Salome HOME
Merge from V6_main_20120808 08Aug12
authorvsr <vsr@opencascade.com>
Thu, 9 Aug 2012 10:03:55 +0000 (10:03 +0000)
committervsr <vsr@opencascade.com>
Thu, 9 Aug 2012 10:03:55 +0000 (10:03 +0000)
1291 files changed:
Makefile.am
SMESH_version.h.in
adm_local/Makefile.am
adm_local/cmake_files/FindSMESH.cmake [new file with mode: 0644]
adm_local/cmake_files/Makefile.am [new file with mode: 0644]
adm_local/unix/Makefile.am
adm_local/unix/config_files/Makefile.am
adm_local/unix/config_files/check_Platform.m4
adm_local/unix/config_files/check_SMESH.m4
adm_local/unix/config_files/check_cgal.m4 [new file with mode: 0644]
adm_local/unix/config_files/check_cgns.m4 [new file with mode: 0644]
adm_local/unix/config_files/check_f77.m4
adm_local/unix/config_files/check_padder.m4 [new file with mode: 0644]
adm_local/unix/config_files/check_qwt.m4 [new file with mode: 0644]
adm_local/unix/make_common_starter.am
bin/Makefile.am
bin/VERSION.in
bin/smesh_setenv.py [new file with mode: 0644]
build_cmake [new file with mode: 0755]
build_cmake.bat [new file with mode: 0644]
build_configure
clean_configure
configure.ac
doc/Makefile.am
doc/docutils/Makefile.am [new file with mode: 0644]
doc/docutils/conf.py.in [new file with mode: 0644]
doc/docutils/docapi.rst [new file with mode: 0644]
doc/docutils/index.rst [new file with mode: 0644]
doc/docutils/overview.rst [new file with mode: 0644]
doc/salome/Makefile.am
doc/salome/gui/Makefile.am
doc/salome/gui/SMESH/Makefile.am
doc/salome/gui/SMESH/doxyfile.in
doc/salome/gui/SMESH/doxyfile_py.in
doc/salome/gui/SMESH/images/2d_from_3d_dlg.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/2d_from_3d_ico.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/2d_from_3d_menu.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/a-arithmetic1d.png
doc/salome/gui/SMESH/images/a-averagelength.png
doc/salome/gui/SMESH/images/a-clipping2.png
doc/salome/gui/SMESH/images/a-creategroup.png
doc/salome/gui/SMESH/images/a-createpolyhedralvolume.png
doc/salome/gui/SMESH/images/a-nbsegments1.png
doc/salome/gui/SMESH/images/a-nbsegments2.png
doc/salome/gui/SMESH/images/a-startendlength.png
doc/salome/gui/SMESH/images/a-transparency.png
doc/salome/gui/SMESH/images/add0delement.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/add_0delement.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/add_ball.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/addball.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/addedge.png
doc/salome/gui/SMESH/images/addhexahedron.png
doc/salome/gui/SMESH/images/addinfo_group.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/addinfo_mesh.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/addinfo_submesh.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/addnode.png
doc/salome/gui/SMESH/images/addnode_notebook.png
doc/salome/gui/SMESH/images/addpolygon.png
doc/salome/gui/SMESH/images/addquadrangle.png
doc/salome/gui/SMESH/images/addtetrahedron.png
doc/salome/gui/SMESH/images/addtriangle.png
doc/salome/gui/SMESH/images/advanced_mesh_infos.png
doc/salome/gui/SMESH/images/aqt.png
doc/salome/gui/SMESH/images/bare_border_faces_smpl.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/bare_border_volumes_smpl.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/blsurf_parameters.png [deleted file]
doc/salome/gui/SMESH/images/blsurf_parameters_advanced.png [deleted file]
doc/salome/gui/SMESH/images/bnd_box.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/bnd_box_preview.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/cartesian3D_hyp.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/cartesian3D_sphere.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/colors_size.png [new file with mode: 0755]
doc/salome/gui/SMESH/images/controls_popup.png [new file with mode: 0755]
doc/salome/gui/SMESH/images/convert.png
doc/salome/gui/SMESH/images/copy_mesh_dlg.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/copy_mesh_icon.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/create_groups_from_geometry.png
doc/salome/gui/SMESH/images/creategroup.png
doc/salome/gui/SMESH/images/creategroup_on_filter.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/custom_point_marker.png [new file with mode: 0755]
doc/salome/gui/SMESH/images/dialog.png
doc/salome/gui/SMESH/images/distributionwithanalyticdensity.png
doc/salome/gui/SMESH/images/distributionwithtabledensity.png
doc/salome/gui/SMESH/images/double_faces.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/double_nodes.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/duplicate01.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/duplicate02.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/duplicate_nodes.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/editgroup.png
doc/salome/gui/SMESH/images/elem_info.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/eleminfo1.png
doc/salome/gui/SMESH/images/eleminfo2.png
doc/salome/gui/SMESH/images/extr_along_wire_after.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/extr_along_wire_before.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/extrusion1.png
doc/salome/gui/SMESH/images/extrusion2.png [deleted file]
doc/salome/gui/SMESH/images/extrusionalongaline1.png
doc/salome/gui/SMESH/images/extrusionalongaline2.png
doc/salome/gui/SMESH/images/findelement1.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/findelement2.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/findelement3.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/formula1.png
doc/salome/gui/SMESH/images/formula2.png
doc/salome/gui/SMESH/images/formula4.png
doc/salome/gui/SMESH/images/formula5.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/free_nodes.png
doc/salome/gui/SMESH/images/ghs3d_parameters_advanced.png [deleted file]
doc/salome/gui/SMESH/images/ghs3d_parameters_basic.png [deleted file]
doc/salome/gui/SMESH/images/head.png [new file with mode: 0755]
doc/salome/gui/SMESH/images/hyp_source_edges.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/hyp_source_faces.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/hypo_fixedpnt_dlg.png [new file with mode: 0755]
doc/salome/gui/SMESH/images/hypo_quad_params_1.png [new file with mode: 0755]
doc/salome/gui/SMESH/images/hypo_quad_params_2.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/hypo_quad_params_dialog.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/hypo_quad_params_res.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/hypo_quad_params_res_2.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/hypo_radquad_dlg.png [new file with mode: 0755]
doc/salome/gui/SMESH/images/hypo_sets.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/image146.png
doc/salome/gui/SMESH/images/image152.png
doc/salome/gui/SMESH/images/image42.png [new file with mode: 0755]
doc/salome/gui/SMESH/images/image43.png [new file with mode: 0755]
doc/salome/gui/SMESH/images/image49.png
doc/salome/gui/SMESH/images/image79.jpg
doc/salome/gui/SMESH/images/image99.gif
doc/salome/gui/SMESH/images/image_octa12.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/max_element_length_2d.png [new file with mode: 0755]
doc/salome/gui/SMESH/images/max_element_length_3d.png [new file with mode: 0755]
doc/salome/gui/SMESH/images/mergeelems.png
doc/salome/gui/SMESH/images/mergeelems_auto.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/mergenodes.png
doc/salome/gui/SMESH/images/mergenodes_auto.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/mesh_evaluation_succeed.png [new file with mode: 0755]
doc/salome/gui/SMESH/images/mesh_fixedpnt.png [new file with mode: 0755]
doc/salome/gui/SMESH/images/mesh_order_123.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/mesh_order_123_res.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/mesh_order_213.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/mesh_order_213_res.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/mesh_order_321.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/mesh_order_321_res.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/mesh_order_no_concurrent.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/mesh_order_preview.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/mesh_radquad_01.png [new file with mode: 0755]
doc/salome/gui/SMESH/images/mesh_radquad_02.png [new file with mode: 0755]
doc/salome/gui/SMESH/images/meshcomputationfail.png
doc/salome/gui/SMESH/images/meshcut_plugin.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/meshtopass.png
doc/salome/gui/SMESH/images/min_distance.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/min_distance_preview.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/moving_nodes1.png
doc/salome/gui/SMESH/images/moving_nodes2.png
doc/salome/gui/SMESH/images/netgen2d.png [deleted file]
doc/salome/gui/SMESH/images/netgen3d_simple.png [deleted file]
doc/salome/gui/SMESH/images/over_constrained_faces.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/over_constrained_volumes.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/pattern2d.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/point_marker_widget1.png [new file with mode: 0755]
doc/salome/gui/SMESH/images/point_marker_widget2.png [new file with mode: 0755]
doc/salome/gui/SMESH/images/pref21.png [new file with mode: 0755]
doc/salome/gui/SMESH/images/pref22.png [new file with mode: 0755]
doc/salome/gui/SMESH/images/pref23.png [new file with mode: 0755]
doc/salome/gui/SMESH/images/pref24.png [new file with mode: 0755]
doc/salome/gui/SMESH/images/projection_1d.png
doc/salome/gui/SMESH/images/projection_2d.png
doc/salome/gui/SMESH/images/projection_3d.png
doc/salome/gui/SMESH/images/remove_nodes_icon.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/remove_orphan_nodes_icon.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/removeorphannodes.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/reorient_2d_face.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/reorient_2d_point.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/reorient_faces_face.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/revolution2.png [deleted file]
doc/salome/gui/SMESH/images/rotation.png
doc/salome/gui/SMESH/images/scalar_bar_dlg.png [new file with mode: 0755]
doc/salome/gui/SMESH/images/scale01.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/scale02.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/scale03.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/scale04.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/scale06.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/scale07.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/scale09.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/scaleinit01.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/scaleinit02.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/scaleres03.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/scaleres04.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/scaleres06.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/scaleres07.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/scaleres09.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/split_into_tetra.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/split_into_tetra_icon.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/std_point_marker.png [new file with mode: 0755]
doc/salome/gui/SMESH/images/symmetry1.png
doc/salome/gui/SMESH/images/symmetry2.png
doc/salome/gui/SMESH/images/symmetry3.png
doc/salome/gui/SMESH/images/translation1.png
doc/salome/gui/SMESH/images/translation2.png
doc/salome/gui/SMESH/images/use_existing_face_sample_mesh.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/using_notebook_smesh.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/viscous_layers_hyp.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/viscous_layers_mesh.png [new file with mode: 0644]
doc/salome/gui/SMESH/input/1d_meshing_hypo.doc
doc/salome/gui/SMESH/input/2d_meshing_hypo.doc
doc/salome/gui/SMESH/input/about_filters.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/about_hypo.doc
doc/salome/gui/SMESH/input/about_meshes.doc
doc/salome/gui/SMESH/input/about_quality_controls.doc
doc/salome/gui/SMESH/input/adding_nodes_and_elements.doc
doc/salome/gui/SMESH/input/adding_quadratic_elements.doc
doc/salome/gui/SMESH/input/additional_hypo.doc
doc/salome/gui/SMESH/input/area.doc
doc/salome/gui/SMESH/input/aspect_ratio.doc
doc/salome/gui/SMESH/input/aspect_ratio_3d.doc
doc/salome/gui/SMESH/input/bare_border_face.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/bare_border_volumes.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/basic_meshing_algos.doc
doc/salome/gui/SMESH/input/blsurf_hypo.doc [deleted file]
doc/salome/gui/SMESH/input/building_compounds.doc
doc/salome/gui/SMESH/input/cartesian_algo.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/changing_orientation_of_elements.doc
doc/salome/gui/SMESH/input/clipping.doc
doc/salome/gui/SMESH/input/colors_size.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/constructing_meshes.doc
doc/salome/gui/SMESH/input/constructing_submeshes.doc
doc/salome/gui/SMESH/input/convert_to_from_quadratic_mesh.doc
doc/salome/gui/SMESH/input/copy_mesh.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/create_groups_from_geometry.doc [new file with mode: 0755]
doc/salome/gui/SMESH/input/creating_groups.doc
doc/salome/gui/SMESH/input/cut_mesh_by_plane.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/deleting_groups.doc
doc/salome/gui/SMESH/input/double_elements_control.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/double_nodes_control.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/double_nodes_page.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/editing_groups.doc
doc/salome/gui/SMESH/input/extrusion.doc
doc/salome/gui/SMESH/input/extrusion_along_path.doc
doc/salome/gui/SMESH/input/find_element_by_point.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/free_faces.doc
doc/salome/gui/SMESH/input/free_nodes.doc
doc/salome/gui/SMESH/input/generate_flat_elements.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/ghs3d_hypo.doc [deleted file]
doc/salome/gui/SMESH/input/ghs3dprl_hypo.doc [deleted file]
doc/salome/gui/SMESH/input/group_of_underlying_elements.doc [new file with mode: 0755]
doc/salome/gui/SMESH/input/grouping_elements.doc
doc/salome/gui/SMESH/input/importing_exporting_meshes.doc
doc/salome/gui/SMESH/input/index.doc
doc/salome/gui/SMESH/input/length_2d.doc
doc/salome/gui/SMESH/input/make_2dmesh_from_3d.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/max_element_length_2d.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/max_element_length_3d.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/measurements.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/merging_elements.doc
doc/salome/gui/SMESH/input/merging_nodes.doc
doc/salome/gui/SMESH/input/mesh_infos.doc
doc/salome/gui/SMESH/input/mesh_preferences.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/mesh_through_point.doc
doc/salome/gui/SMESH/input/minimum_angle.doc
doc/salome/gui/SMESH/input/modifying_meshes.doc
doc/salome/gui/SMESH/input/moving_nodes.doc [deleted file]
doc/salome/gui/SMESH/input/netgen_2d_3d_hypo.doc [deleted file]
doc/salome/gui/SMESH/input/over_constrained_faces.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/over_constrained_volumes.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/pattern_mapping.doc
doc/salome/gui/SMESH/input/point_marker.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/preview_meshes.doc [deleted file]
doc/salome/gui/SMESH/input/prism_3d_algo.doc
doc/salome/gui/SMESH/input/projection_algos.doc
doc/salome/gui/SMESH/input/radial_quadrangle_1D2D_algo.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/removing_nodes_and_elements.doc
doc/salome/gui/SMESH/input/reorient_faces.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/revolution.doc
doc/salome/gui/SMESH/input/rotation.doc
doc/salome/gui/SMESH/input/scalar_bar.doc [new file with mode: 0755]
doc/salome/gui/SMESH/input/scale.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/selection_filter_library.doc
doc/salome/gui/SMESH/input/skew.doc
doc/salome/gui/SMESH/input/smeshpy_interface.doc
doc/salome/gui/SMESH/input/smoothing.doc
doc/salome/gui/SMESH/input/split_to_tetra.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/symmetry.doc
doc/salome/gui/SMESH/input/taper.doc
doc/salome/gui/SMESH/input/translation.doc
doc/salome/gui/SMESH/input/tui_cartesian_algo.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/tui_creating_meshes.doc
doc/salome/gui/SMESH/input/tui_defining_hypotheses.doc
doc/salome/gui/SMESH/input/tui_filters.doc [new file with mode: 0755]
doc/salome/gui/SMESH/input/tui_generate_flat_elements.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/tui_grouping_elements.doc
doc/salome/gui/SMESH/input/tui_measurements.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/tui_modifying_meshes.doc
doc/salome/gui/SMESH/input/tui_notebook_smesh.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/tui_quality_controls.doc
doc/salome/gui/SMESH/input/tui_transforming_meshes.doc
doc/salome/gui/SMESH/input/tui_use_existing_faces.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/tui_viewing_meshes.doc
doc/salome/gui/SMESH/input/tui_work_on_objects_from_gui.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/use_existing_algos.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/using_notebook_smesh_page.doc
doc/salome/gui/SMESH/input/viewing_meshes_overview.doc
doc/salome/gui/SMESH/input/volume.doc
doc/salome/gui/SMESH/input/warping.doc
doc/salome/gui/SMESH/static/doxygen.css
doc/salome/gui/SMESH/static/footer.html
doc/salome/gui/SMESH/static/header.html [deleted file]
doc/salome/gui/SMESH/static/header.html.in [new file with mode: 0755]
doc/salome/gui/SMESH/static/header_py.html.in [new file with mode: 0644]
doc/salome/tui/Makefile.am
doc/salome/tui/doxyfile.in
doc/salome/tui/extra/AddNetgenInSalome2.pdf [deleted file]
doc/salome/tui/extra/AddNetgenInSalome2.ps [deleted file]
doc/salome/tui/extra/AddNetgenInSalome2.sxw [deleted file]
doc/salome/tui/extra/PluginMeshers.html [deleted file]
doc/salome/tui/extra/PluginMeshers.txt [deleted file]
doc/salome/tui/images/head.png [new file with mode: 0755]
doc/salome/tui/images/smeshscreen.png [new file with mode: 0755]
doc/salome/tui/input/index.doc [new file with mode: 0644]
doc/salome/tui/static/doxygen.css
doc/salome/tui/static/footer.html
doc/salome/tui/static/header.html.in [new file with mode: 0755]
doc/salome/tui/static/myheader.html [deleted file]
idl/Makefile.am
idl/SMESH_BasicHypothesis.idl
idl/SMESH_Filter.idl
idl/SMESH_Gen.idl
idl/SMESH_Group.idl
idl/SMESH_Hypothesis.idl
idl/SMESH_Measurements.idl [new file with mode: 0644]
idl/SMESH_Mesh.idl
idl/SMESH_MeshEditor.idl
idl/SMESH_Pattern.idl
resources/Makefile.am
resources/SMESHCatalog.xml.in
resources/SalomeApp.xml [deleted file]
resources/SalomeApp.xml.in [new file with mode: 0644]
resources/StdMeshers.xml
resources/advanced_mesh_info.png
resources/bare_border_face.png [new file with mode: 0644]
resources/bare_border_volume.png [new file with mode: 0644]
resources/copy_mesh.png [new file with mode: 0644]
resources/mesh_2d_from_3d.png [new file with mode: 0644]
resources/mesh_ball.png [new file with mode: 0644]
resources/mesh_biquad_quadrangle.png [new file with mode: 0644]
resources/mesh_bounding_box.png [new file with mode: 0755]
resources/mesh_duplicate_nodes.png [new file with mode: 0644]
resources/mesh_duplicate_nodes_with_elem.png [new file with mode: 0644]
resources/mesh_elem_info.png [new file with mode: 0644]
resources/mesh_equal_edge.png [new file with mode: 0644]
resources/mesh_equal_face.png [new file with mode: 0644]
resources/mesh_equal_node.png [new file with mode: 0644]
resources/mesh_equal_volume.png [new file with mode: 0644]
resources/mesh_find_elem_by_point.png [new file with mode: 0644]
resources/mesh_hypo_viscous_layers.png [new file with mode: 0644]
resources/mesh_max_element_length_2d.png [new file with mode: 0755]
resources/mesh_max_element_length_3d.png [new file with mode: 0755]
resources/mesh_min_dist.png [new file with mode: 0755]
resources/mesh_octahedron.png [new file with mode: 0644]
resources/mesh_pentahedron.png [new file with mode: 0644]
resources/mesh_quadrangle_quadpref.png [new file with mode: 0644]
resources/mesh_quadrangle_quadpref_reversed.png [new file with mode: 0644]
resources/mesh_quadrangle_reduced.png [new file with mode: 0644]
resources/mesh_quadrangle_standard.png [new file with mode: 0644]
resources/mesh_quadrangle_triapref.png [new file with mode: 0644]
resources/mesh_rem_orphan_nodes.png [new file with mode: 0644]
resources/mesh_tree_algo_0D.png [new file with mode: 0644]
resources/mesh_tree_algo_existing_2D.png [new file with mode: 0644]
resources/mesh_tree_algo_prism.png [new file with mode: 0644]
resources/mesh_tree_algo_radial_quadrangle_1D2D.png [new file with mode: 0644]
resources/mesh_tree_group_on_filter.png [new file with mode: 0644]
resources/mesh_tree_hypo_viscous_layers.png [new file with mode: 0644]
resources/mesh_triquad_hexahedron.png [new file with mode: 0644]
resources/over_constrained_face.png [new file with mode: 0644]
resources/over_constrained_volume.png [new file with mode: 0644]
resources/reorient_faces_face.png [new file with mode: 0644]
resources/reorient_faces_point.png [new file with mode: 0644]
resources/scale.png [new file with mode: 0644]
resources/scale_along_axes.png [new file with mode: 0644]
resources/split_into_tetra.png [new file with mode: 0644]
src/Controls/Makefile.am
src/Controls/SMESHControls.cxx
src/Controls/SMESH_Controls.cxx
src/Controls/SMESH_Controls.hxx [deleted file]
src/Controls/SMESH_ControlsDef.hxx
src/Driver/Driver_Document.cxx
src/Driver/Driver_Document.h
src/Driver/Driver_Mesh.cxx
src/Driver/Driver_Mesh.h
src/Driver/Driver_SMDS_Mesh.cxx
src/Driver/Driver_SMDS_Mesh.h
src/Driver/Driver_SMESHDS_Mesh.cxx
src/Driver/Driver_SMESHDS_Mesh.h
src/Driver/Makefile.am
src/DriverCGNS/DriverCGNS_Read.cxx [new file with mode: 0644]
src/DriverCGNS/DriverCGNS_Read.hxx [new file with mode: 0644]
src/DriverCGNS/DriverCGNS_Write.cxx [new file with mode: 0644]
src/DriverCGNS/DriverCGNS_Write.hxx [new file with mode: 0644]
src/DriverCGNS/Makefile.am [new file with mode: 0644]
src/DriverCGNS/SMESH_DriverCGNS.hxx [new file with mode: 0755]
src/DriverDAT/DAT_Test.cxx
src/DriverDAT/DriverDAT_R_SMDS_Mesh.cxx
src/DriverDAT/DriverDAT_R_SMDS_Mesh.h
src/DriverDAT/DriverDAT_R_SMESHDS_Document.cxx [deleted file]
src/DriverDAT/DriverDAT_R_SMESHDS_Document.h [deleted file]
src/DriverDAT/DriverDAT_R_SMESHDS_Mesh.cxx [deleted file]
src/DriverDAT/DriverDAT_R_SMESHDS_Mesh.h [deleted file]
src/DriverDAT/DriverDAT_W_SMDS_Mesh.cxx
src/DriverDAT/DriverDAT_W_SMDS_Mesh.h
src/DriverDAT/DriverDAT_W_SMESHDS_Document.cxx [deleted file]
src/DriverDAT/DriverDAT_W_SMESHDS_Document.h [deleted file]
src/DriverDAT/DriverDAT_W_SMESHDS_Mesh.cxx [deleted file]
src/DriverDAT/DriverDAT_W_SMESHDS_Mesh.h [deleted file]
src/DriverDAT/Makefile.am
src/DriverDAT/SMESH_DriverDAT.hxx
src/DriverMED/DriverMED_Family.cxx
src/DriverMED/DriverMED_Family.h
src/DriverMED/DriverMED_R_SMDS_Mesh.cxx [deleted file]
src/DriverMED/DriverMED_R_SMDS_Mesh.h [deleted file]
src/DriverMED/DriverMED_R_SMESHDS_Document.cxx [deleted file]
src/DriverMED/DriverMED_R_SMESHDS_Document.h [deleted file]
src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx
src/DriverMED/DriverMED_R_SMESHDS_Mesh.h
src/DriverMED/DriverMED_W_SMDS_Mesh.cxx [deleted file]
src/DriverMED/DriverMED_W_SMDS_Mesh.h [deleted file]
src/DriverMED/DriverMED_W_SMESHDS_Document.cxx [deleted file]
src/DriverMED/DriverMED_W_SMESHDS_Document.h [deleted file]
src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx
src/DriverMED/DriverMED_W_SMESHDS_Mesh.h
src/DriverMED/MED_Test.cxx
src/DriverMED/Makefile.am
src/DriverMED/SMESH_DriverMED.hxx
src/DriverSTL/DriverSTL_R_SMDS_Mesh.cxx
src/DriverSTL/DriverSTL_R_SMDS_Mesh.h
src/DriverSTL/DriverSTL_W_SMDS_Mesh.cxx
src/DriverSTL/DriverSTL_W_SMDS_Mesh.h
src/DriverSTL/Makefile.am
src/DriverSTL/SMESH_DriverSTL.hxx
src/DriverSTL/STL_Test.cxx
src/DriverUNV/DriverUNV_R_SMDS_Mesh.cxx
src/DriverUNV/DriverUNV_R_SMDS_Mesh.h
src/DriverUNV/DriverUNV_R_SMESHDS_Document.cxx [deleted file]
src/DriverUNV/DriverUNV_R_SMESHDS_Document.h [deleted file]
src/DriverUNV/DriverUNV_R_SMESHDS_Mesh.cxx [deleted file]
src/DriverUNV/DriverUNV_R_SMESHDS_Mesh.h [deleted file]
src/DriverUNV/DriverUNV_W_SMDS_Mesh.cxx
src/DriverUNV/DriverUNV_W_SMDS_Mesh.h
src/DriverUNV/DriverUNV_W_SMESHDS_Document.cxx [deleted file]
src/DriverUNV/DriverUNV_W_SMESHDS_Document.h [deleted file]
src/DriverUNV/DriverUNV_W_SMESHDS_Mesh.cxx [deleted file]
src/DriverUNV/DriverUNV_W_SMESHDS_Mesh.h [deleted file]
src/DriverUNV/Makefile.am
src/DriverUNV/SMESH_DriverUNV.hxx
src/DriverUNV/UNV164_Structure.cxx [new file with mode: 0644]
src/DriverUNV/UNV164_Structure.hxx [new file with mode: 0644]
src/DriverUNV/UNV2411_Structure.cxx
src/DriverUNV/UNV2411_Structure.hxx
src/DriverUNV/UNV2412_Structure.cxx
src/DriverUNV/UNV2412_Structure.hxx
src/DriverUNV/UNV2417_Structure.cxx
src/DriverUNV/UNV2417_Structure.hxx
src/DriverUNV/UNV2420_Structure.cxx [new file with mode: 0644]
src/DriverUNV/UNV2420_Structure.hxx [new file with mode: 0644]
src/DriverUNV/UNV_Test.cxx
src/DriverUNV/UNV_Utilities.cxx
src/DriverUNV/UNV_Utilities.hxx
src/MEFISTO2/Makefile.am
src/MEFISTO2/Rn.h
src/MEFISTO2/aptrte.cxx
src/MEFISTO2/aptrte.h
src/MEFISTO2/areteideale.f
src/MEFISTO2/trte.f
src/Makefile.am
src/OBJECT/Makefile.am
src/OBJECT/SMESH_Actor.cxx
src/OBJECT/SMESH_Actor.h
src/OBJECT/SMESH_ActorDef.h
src/OBJECT/SMESH_ActorUtils.cxx
src/OBJECT/SMESH_ActorUtils.h
src/OBJECT/SMESH_CellLabelActor.cxx [new file with mode: 0644]
src/OBJECT/SMESH_CellLabelActor.h [new file with mode: 0644]
src/OBJECT/SMESH_DeviceActor.cxx
src/OBJECT/SMESH_DeviceActor.h
src/OBJECT/SMESH_ExtractGeometry.cxx
src/OBJECT/SMESH_ExtractGeometry.h
src/OBJECT/SMESH_FaceOrientationFilter.cxx
src/OBJECT/SMESH_FaceOrientationFilter.h
src/OBJECT/SMESH_NodeLabelActor.cxx [new file with mode: 0644]
src/OBJECT/SMESH_NodeLabelActor.h [new file with mode: 0644]
src/OBJECT/SMESH_Object.cxx
src/OBJECT/SMESH_Object.h
src/OBJECT/SMESH_ObjectDef.h
src/OBJECT/SMESH_PreviewActorsCollection.cxx [new file with mode: 0644]
src/OBJECT/SMESH_PreviewActorsCollection.h [new file with mode: 0644]
src/OBJECT/SMESH_ScalarBarActor.cxx [new file with mode: 0644]
src/OBJECT/SMESH_ScalarBarActor.h [new file with mode: 0644]
src/PluginUtils/GeomSelectionTools.cxx [new file with mode: 0644]
src/PluginUtils/GeomSelectionTools.h [new file with mode: 0644]
src/PluginUtils/Makefile.am [new file with mode: 0644]
src/SMDS/Makefile.am
src/SMDS/Notes [new file with mode: 0644]
src/SMDS/ObjectPool.hxx [new file with mode: 0644]
src/SMDS/SMDSAbs_ElementType.hxx
src/SMDS/SMDS_BallElement.cxx [new file with mode: 0644]
src/SMDS/SMDS_BallElement.hxx [new file with mode: 0644]
src/SMDS/SMDS_Downward.cxx [new file with mode: 0644]
src/SMDS/SMDS_Downward.hxx [new file with mode: 0644]
src/SMDS/SMDS_EdgePosition.cxx
src/SMDS/SMDS_EdgePosition.hxx
src/SMDS/SMDS_ElemIterator.hxx
src/SMDS/SMDS_FaceOfEdges.cxx
src/SMDS/SMDS_FaceOfEdges.hxx
src/SMDS/SMDS_FaceOfNodes.cxx
src/SMDS/SMDS_FaceOfNodes.hxx
src/SMDS/SMDS_FacePosition.cxx
src/SMDS/SMDS_FacePosition.hxx
src/SMDS/SMDS_Iterator.hxx
src/SMDS/SMDS_IteratorOfElements.cxx
src/SMDS/SMDS_IteratorOfElements.hxx
src/SMDS/SMDS_IteratorOnIterators.hxx [new file with mode: 0644]
src/SMDS/SMDS_LinearEdge.cxx [new file with mode: 0644]
src/SMDS/SMDS_LinearEdge.hxx [new file with mode: 0644]
src/SMDS/SMDS_MemoryLimit.cxx
src/SMDS/SMDS_Mesh.cxx
src/SMDS/SMDS_Mesh.hxx
src/SMDS/SMDS_Mesh0DElement.cxx [new file with mode: 0644]
src/SMDS/SMDS_Mesh0DElement.hxx [new file with mode: 0644]
src/SMDS/SMDS_MeshCell.cxx [new file with mode: 0644]
src/SMDS/SMDS_MeshCell.hxx [new file with mode: 0644]
src/SMDS/SMDS_MeshEdge.cxx
src/SMDS/SMDS_MeshEdge.hxx
src/SMDS/SMDS_MeshElement.cxx
src/SMDS/SMDS_MeshElement.hxx
src/SMDS/SMDS_MeshElementIDFactory.cxx
src/SMDS/SMDS_MeshElementIDFactory.hxx
src/SMDS/SMDS_MeshFace.cxx
src/SMDS/SMDS_MeshFace.hxx
src/SMDS/SMDS_MeshGroup.cxx
src/SMDS/SMDS_MeshGroup.hxx
src/SMDS/SMDS_MeshIDFactory.cxx
src/SMDS/SMDS_MeshIDFactory.hxx
src/SMDS/SMDS_MeshInfo.hxx
src/SMDS/SMDS_MeshNode.cxx
src/SMDS/SMDS_MeshNode.hxx
src/SMDS/SMDS_MeshNodeIDFactory.cxx [new file with mode: 0644]
src/SMDS/SMDS_MeshNodeIDFactory.hxx [new file with mode: 0644]
src/SMDS/SMDS_MeshObject.cxx
src/SMDS/SMDS_MeshObject.hxx
src/SMDS/SMDS_MeshVolume.cxx
src/SMDS/SMDS_MeshVolume.hxx
src/SMDS/SMDS_PolygonalFaceOfNodes.cxx
src/SMDS/SMDS_PolygonalFaceOfNodes.hxx
src/SMDS/SMDS_PolyhedralVolumeOfNodes.cxx
src/SMDS/SMDS_PolyhedralVolumeOfNodes.hxx
src/SMDS/SMDS_Position.cxx
src/SMDS/SMDS_Position.hxx
src/SMDS/SMDS_QuadraticEdge.cxx
src/SMDS/SMDS_QuadraticEdge.hxx
src/SMDS/SMDS_QuadraticFaceOfNodes.cxx
src/SMDS/SMDS_QuadraticFaceOfNodes.hxx
src/SMDS/SMDS_QuadraticVolumeOfNodes.cxx
src/SMDS/SMDS_QuadraticVolumeOfNodes.hxx
src/SMDS/SMDS_SetIterator.hxx
src/SMDS/SMDS_SpacePosition.cxx
src/SMDS/SMDS_SpacePosition.hxx
src/SMDS/SMDS_StdIterator.hxx [new file with mode: 0644]
src/SMDS/SMDS_TypeOfPosition.hxx
src/SMDS/SMDS_UnstructuredGrid.cxx [new file with mode: 0644]
src/SMDS/SMDS_UnstructuredGrid.hxx [new file with mode: 0644]
src/SMDS/SMDS_VertexPosition.cxx
src/SMDS/SMDS_VertexPosition.hxx
src/SMDS/SMDS_VolumeOfFaces.cxx
src/SMDS/SMDS_VolumeOfFaces.hxx
src/SMDS/SMDS_VolumeOfNodes.cxx
src/SMDS/SMDS_VolumeOfNodes.hxx
src/SMDS/SMDS_VolumeTool.cxx
src/SMDS/SMDS_VolumeTool.hxx
src/SMDS/SMDS_VtkCellIterator.cxx [new file with mode: 0644]
src/SMDS/SMDS_VtkCellIterator.hxx [new file with mode: 0644]
src/SMDS/SMDS_VtkEdge.cxx [new file with mode: 0644]
src/SMDS/SMDS_VtkEdge.hxx [new file with mode: 0644]
src/SMDS/SMDS_VtkFace.cxx [new file with mode: 0644]
src/SMDS/SMDS_VtkFace.hxx [new file with mode: 0644]
src/SMDS/SMDS_VtkVolume.cxx [new file with mode: 0644]
src/SMDS/SMDS_VtkVolume.hxx [new file with mode: 0644]
src/SMDS/SMESH_SMDS.hxx
src/SMDS/chrono.cxx [new file with mode: 0644]
src/SMDS/chrono.hxx [new file with mode: 0644]
src/SMESH/Makefile.am
src/SMESH/SMESH_0D_Algo.cxx
src/SMESH/SMESH_0D_Algo.hxx
src/SMESH/SMESH_1D_Algo.cxx
src/SMESH/SMESH_1D_Algo.hxx
src/SMESH/SMESH_2D_Algo.cxx
src/SMESH/SMESH_2D_Algo.hxx
src/SMESH/SMESH_3D_Algo.cxx
src/SMESH/SMESH_3D_Algo.hxx
src/SMESH/SMESH_Algo.cxx
src/SMESH/SMESH_Algo.hxx
src/SMESH/SMESH_Block.cxx [deleted file]
src/SMESH/SMESH_Block.hxx [deleted file]
src/SMESH/SMESH_Comment.hxx [deleted file]
src/SMESH/SMESH_ComputeError.hxx [deleted file]
src/SMESH/SMESH_DataMapOfElemPtrSequenceOfElemPtr.hxx [deleted file]
src/SMESH/SMESH_Gen.cxx
src/SMESH/SMESH_Gen.hxx
src/SMESH/SMESH_Group.cxx
src/SMESH/SMESH_Group.hxx
src/SMESH/SMESH_HypoFilter.cxx
src/SMESH/SMESH_HypoFilter.hxx
src/SMESH/SMESH_Hypothesis.cxx
src/SMESH/SMESH_Hypothesis.hxx
src/SMESH/SMESH_IndexedDataMapOfShapeIndexedMapOfShape.hxx [deleted file]
src/SMESH/SMESH_Mesh.cxx
src/SMESH/SMESH_Mesh.hxx
src/SMESH/SMESH_MeshEditor.cxx
src/SMESH/SMESH_MeshEditor.hxx
src/SMESH/SMESH_MesherHelper.cxx
src/SMESH/SMESH_MesherHelper.hxx
src/SMESH/SMESH_Octree.cxx [deleted file]
src/SMESH/SMESH_Octree.hxx [deleted file]
src/SMESH/SMESH_OctreeNode.cxx [deleted file]
src/SMESH/SMESH_OctreeNode.hxx [deleted file]
src/SMESH/SMESH_Pattern.cxx
src/SMESH/SMESH_Pattern.hxx
src/SMESH/SMESH_ProxyMesh.cxx [new file with mode: 0644]
src/SMESH/SMESH_ProxyMesh.hxx [new file with mode: 0644]
src/SMESH/SMESH_SMESH.hxx
src/SMESH/SMESH_SequenceOfElemPtr.hxx [deleted file]
src/SMESH/SMESH_SequenceOfNode.hxx [deleted file]
src/SMESH/SMESH_subMesh.cxx
src/SMESH/SMESH_subMesh.hxx
src/SMESH/SMESH_subMeshEventListener.hxx
src/SMESH/memoire.h [new file with mode: 0644]
src/SMESHClient/Makefile.am
src/SMESHClient/SMESHClientBin.cxx
src/SMESHClient/SMESH_Client.cxx
src/SMESHClient/SMESH_Client.hxx
src/SMESHDS/Makefile.am
src/SMESHDS/SMESHDS_Command.cxx
src/SMESHDS/SMESHDS_Command.hxx
src/SMESHDS/SMESHDS_CommandType.hxx
src/SMESHDS/SMESHDS_DataMapOfShape.hxx
src/SMESHDS/SMESHDS_Document.cxx
src/SMESHDS/SMESHDS_Document.hxx
src/SMESHDS/SMESHDS_Group.cxx
src/SMESHDS/SMESHDS_Group.hxx
src/SMESHDS/SMESHDS_GroupBase.cxx
src/SMESHDS/SMESHDS_GroupBase.hxx
src/SMESHDS/SMESHDS_GroupOnFilter.cxx [new file with mode: 0644]
src/SMESHDS/SMESHDS_GroupOnFilter.hxx [new file with mode: 0644]
src/SMESHDS/SMESHDS_GroupOnGeom.cxx
src/SMESHDS/SMESHDS_GroupOnGeom.hxx
src/SMESHDS/SMESHDS_Hypothesis.cxx
src/SMESHDS/SMESHDS_Hypothesis.hxx
src/SMESHDS/SMESHDS_Mesh.cxx
src/SMESHDS/SMESHDS_Mesh.hxx
src/SMESHDS/SMESHDS_Script.cxx
src/SMESHDS/SMESHDS_Script.hxx
src/SMESHDS/SMESHDS_SubMesh.cxx
src/SMESHDS/SMESHDS_SubMesh.hxx
src/SMESHDS/SMESH_Controls.hxx [new file with mode: 0644]
src/SMESHDS/SMESH_SMESHDS.hxx
src/SMESHFiltersSelection/Makefile.am
src/SMESHFiltersSelection/SMESH_LogicalFilter.cxx
src/SMESHFiltersSelection/SMESH_LogicalFilter.hxx
src/SMESHFiltersSelection/SMESH_NumberFilter.cxx
src/SMESHFiltersSelection/SMESH_NumberFilter.hxx
src/SMESHFiltersSelection/SMESH_Type.h
src/SMESHFiltersSelection/SMESH_TypeFilter.cxx
src/SMESHFiltersSelection/SMESH_TypeFilter.hxx
src/SMESHGUI/Makefile.am
src/SMESHGUI/SMESHGUI.cxx
src/SMESHGUI/SMESHGUI.h
src/SMESHGUI/SMESHGUI_AddMeshElementDlg.cxx
src/SMESHGUI/SMESHGUI_AddMeshElementDlg.h
src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx
src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.h
src/SMESHGUI/SMESHGUI_BuildCompoundDlg.cxx
src/SMESHGUI/SMESHGUI_BuildCompoundDlg.h
src/SMESHGUI/SMESHGUI_ClippingDlg.cxx
src/SMESHGUI/SMESHGUI_ClippingDlg.h
src/SMESHGUI/SMESHGUI_ComputeDlg.cxx
src/SMESHGUI/SMESHGUI_ComputeDlg.h
src/SMESHGUI/SMESHGUI_ConvToQuadDlg.cxx
src/SMESHGUI/SMESHGUI_ConvToQuadDlg.h
src/SMESHGUI/SMESHGUI_ConvToQuadOp.cxx
src/SMESHGUI/SMESHGUI_ConvToQuadOp.h
src/SMESHGUI/SMESHGUI_CopyMeshDlg.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_CopyMeshDlg.h [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_CreatePatternDlg.cxx
src/SMESHGUI/SMESHGUI_CreatePatternDlg.h
src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.cxx
src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.h
src/SMESHGUI/SMESHGUI_DeleteGroupDlg.cxx
src/SMESHGUI/SMESHGUI_DeleteGroupDlg.h
src/SMESHGUI/SMESHGUI_Dialog.cxx
src/SMESHGUI/SMESHGUI_Dialog.h
src/SMESHGUI/SMESHGUI_Displayer.cxx
src/SMESHGUI/SMESHGUI_Displayer.h
src/SMESHGUI/SMESHGUI_DuplicateNodesDlg.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_DuplicateNodesDlg.h [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_EditMeshDlg.cxx [deleted file]
src/SMESHGUI/SMESHGUI_EditMeshDlg.h [deleted file]
src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.cxx
src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.h
src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx
src/SMESHGUI/SMESHGUI_ExtrusionDlg.h
src/SMESHGUI/SMESHGUI_FileInfoDlg.cxx
src/SMESHGUI/SMESHGUI_FileInfoDlg.h
src/SMESHGUI/SMESHGUI_FileValidator.cxx [new file with mode: 0755]
src/SMESHGUI/SMESHGUI_FileValidator.h [new file with mode: 0755]
src/SMESHGUI/SMESHGUI_Filter.cxx
src/SMESHGUI/SMESHGUI_Filter.h
src/SMESHGUI/SMESHGUI_FilterDlg.cxx
src/SMESHGUI/SMESHGUI_FilterDlg.h
src/SMESHGUI/SMESHGUI_FilterLibraryDlg.cxx
src/SMESHGUI/SMESHGUI_FilterLibraryDlg.h
src/SMESHGUI/SMESHGUI_FilterUtils.cxx
src/SMESHGUI/SMESHGUI_FilterUtils.h
src/SMESHGUI/SMESHGUI_FindElemByPointDlg.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_FindElemByPointDlg.h [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_GEOMGenUtils.cxx
src/SMESHGUI/SMESHGUI_GEOMGenUtils.h
src/SMESHGUI/SMESHGUI_GroupDlg.cxx
src/SMESHGUI/SMESHGUI_GroupDlg.h
src/SMESHGUI/SMESHGUI_GroupOnShapeDlg.cxx
src/SMESHGUI/SMESHGUI_GroupOnShapeDlg.h
src/SMESHGUI/SMESHGUI_GroupOpDlg.cxx
src/SMESHGUI/SMESHGUI_GroupOpDlg.h
src/SMESHGUI/SMESHGUI_GroupUtils.cxx
src/SMESHGUI/SMESHGUI_GroupUtils.h
src/SMESHGUI/SMESHGUI_Hypotheses.cxx
src/SMESHGUI/SMESHGUI_Hypotheses.h
src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx
src/SMESHGUI/SMESHGUI_HypothesesUtils.h
src/SMESHGUI/SMESHGUI_IdValidator.h
src/SMESHGUI/SMESHGUI_Make2DFrom3DOp.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_Make2DFrom3DOp.h [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.cxx
src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.h
src/SMESHGUI/SMESHGUI_Measurements.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_Measurements.h [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_MergeDlg.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_MergeDlg.h [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_MeshDlg.cxx
src/SMESHGUI/SMESHGUI_MeshDlg.h
src/SMESHGUI/SMESHGUI_MeshEditPreview.cxx
src/SMESHGUI/SMESHGUI_MeshEditPreview.h
src/SMESHGUI/SMESHGUI_MeshInfo.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_MeshInfo.h [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_MeshInfosBox.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_MeshInfosBox.h [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_MeshInfosDlg.cxx [deleted file]
src/SMESHGUI/SMESHGUI_MeshInfosDlg.h [deleted file]
src/SMESHGUI/SMESHGUI_MeshOp.cxx
src/SMESHGUI/SMESHGUI_MeshOp.h
src/SMESHGUI/SMESHGUI_MeshOrderDlg.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_MeshOrderDlg.h [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_MeshOrderOp.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_MeshOrderOp.h [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_MeshPatternDlg.cxx
src/SMESHGUI/SMESHGUI_MeshPatternDlg.h
src/SMESHGUI/SMESHGUI_MeshUtils.cxx
src/SMESHGUI/SMESHGUI_MeshUtils.h
src/SMESHGUI/SMESHGUI_MoveNodesDlg.cxx [deleted file]
src/SMESHGUI/SMESHGUI_MoveNodesDlg.h [deleted file]
src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx
src/SMESHGUI/SMESHGUI_MultiEditDlg.h
src/SMESHGUI/SMESHGUI_NodesDlg.cxx
src/SMESHGUI/SMESHGUI_NodesDlg.h
src/SMESHGUI/SMESHGUI_Operation.cxx
src/SMESHGUI/SMESHGUI_Operation.h
src/SMESHGUI/SMESHGUI_PatternUtils.cxx
src/SMESHGUI/SMESHGUI_PatternUtils.h
src/SMESHGUI/SMESHGUI_PatternWidget.cxx
src/SMESHGUI/SMESHGUI_PatternWidget.h
src/SMESHGUI/SMESHGUI_Preferences_ColorDlg.cxx
src/SMESHGUI/SMESHGUI_Preferences_ColorDlg.h
src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx
src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.h
src/SMESHGUI/SMESHGUI_PreviewDlg.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_PreviewDlg.h [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx
src/SMESHGUI/SMESHGUI_RemoveElementsDlg.h
src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx
src/SMESHGUI/SMESHGUI_RemoveNodesDlg.h
src/SMESHGUI/SMESHGUI_RenumberingDlg.cxx
src/SMESHGUI/SMESHGUI_RenumberingDlg.h
src/SMESHGUI/SMESHGUI_ReorientFacesDlg.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_ReorientFacesDlg.h [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_RevolutionDlg.cxx
src/SMESHGUI/SMESHGUI_RevolutionDlg.h
src/SMESHGUI/SMESHGUI_RotationDlg.cxx
src/SMESHGUI/SMESHGUI_RotationDlg.h
src/SMESHGUI/SMESHGUI_ScaleDlg.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_ScaleDlg.h [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_Selection.cxx
src/SMESHGUI/SMESHGUI_Selection.h
src/SMESHGUI/SMESHGUI_SelectionOp.cxx
src/SMESHGUI/SMESHGUI_SelectionOp.h
src/SMESHGUI/SMESHGUI_SewingDlg.cxx
src/SMESHGUI/SMESHGUI_SewingDlg.h
src/SMESHGUI/SMESHGUI_ShapeByMeshDlg.cxx
src/SMESHGUI/SMESHGUI_ShapeByMeshDlg.h
src/SMESHGUI/SMESHGUI_SingleEditDlg.cxx
src/SMESHGUI/SMESHGUI_SingleEditDlg.h
src/SMESHGUI/SMESHGUI_SmoothingDlg.cxx
src/SMESHGUI/SMESHGUI_SmoothingDlg.h
src/SMESHGUI/SMESHGUI_SpinBox.cxx
src/SMESHGUI/SMESHGUI_SpinBox.h
src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.cxx [deleted file]
src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.h [deleted file]
src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx
src/SMESHGUI/SMESHGUI_SymmetryDlg.h
src/SMESHGUI/SMESHGUI_TranslationDlg.cxx
src/SMESHGUI/SMESHGUI_TranslationDlg.h
src/SMESHGUI/SMESHGUI_TransparencyDlg.cxx
src/SMESHGUI/SMESHGUI_TransparencyDlg.h
src/SMESHGUI/SMESHGUI_Utils.cxx
src/SMESHGUI/SMESHGUI_Utils.h
src/SMESHGUI/SMESHGUI_VTKUtils.cxx
src/SMESHGUI/SMESHGUI_VTKUtils.h
src/SMESHGUI/SMESHGUI_WhatIsDlg.cxx [deleted file]
src/SMESHGUI/SMESHGUI_WhatIsDlg.h [deleted file]
src/SMESHGUI/SMESHGUI_XmlHandler.cxx
src/SMESHGUI/SMESHGUI_XmlHandler.h
src/SMESHGUI/SMESH_SMESHGUI.hxx
src/SMESHGUI/SMESH_images.ts
src/SMESHGUI/SMESH_msg_en.ts
src/SMESHGUI/SMESH_msg_fr.ts [new file with mode: 0755]
src/SMESHUtils/Makefile.am [new file with mode: 0644]
src/SMESHUtils/SMESH_Block.cxx [new file with mode: 0644]
src/SMESHUtils/SMESH_Block.hxx [new file with mode: 0644]
src/SMESHUtils/SMESH_Comment.hxx [new file with mode: 0644]
src/SMESHUtils/SMESH_ComputeError.hxx [new file with mode: 0644]
src/SMESHUtils/SMESH_File.cxx [new file with mode: 0644]
src/SMESHUtils/SMESH_File.hxx [new file with mode: 0644]
src/SMESHUtils/SMESH_Octree.cxx [new file with mode: 0644]
src/SMESHUtils/SMESH_Octree.hxx [new file with mode: 0644]
src/SMESHUtils/SMESH_OctreeNode.cxx [new file with mode: 0644]
src/SMESHUtils/SMESH_OctreeNode.hxx [new file with mode: 0644]
src/SMESHUtils/SMESH_TypeDefs.hxx [new file with mode: 0644]
src/SMESHUtils/SMESH_Utils.hxx [new file with mode: 0755]
src/SMESH_I/Makefile.am
src/SMESH_I/SMESH.hxx
src/SMESH_I/SMESHEngine.cxx
src/SMESH_I/SMESH_0D_Algo_i.cxx
src/SMESH_I/SMESH_0D_Algo_i.hxx
src/SMESH_I/SMESH_1D_Algo_i.cxx
src/SMESH_I/SMESH_1D_Algo_i.hxx
src/SMESH_I/SMESH_2D_Algo_i.cxx
src/SMESH_I/SMESH_2D_Algo_i.hxx
src/SMESH_I/SMESH_2smeshpy.cxx
src/SMESH_I/SMESH_2smeshpy.hxx
src/SMESH_I/SMESH_3D_Algo_i.cxx
src/SMESH_I/SMESH_3D_Algo_i.hxx
src/SMESH_I/SMESH_Algo_i.cxx
src/SMESH_I/SMESH_Algo_i.hxx
src/SMESH_I/SMESH_DumpPython.cxx
src/SMESH_I/SMESH_Filter_i.cxx
src/SMESH_I/SMESH_Filter_i.hxx
src/SMESH_I/SMESH_Gen_i.cxx
src/SMESH_I/SMESH_Gen_i.hxx
src/SMESH_I/SMESH_Gen_i_1.cxx
src/SMESH_I/SMESH_Group_i.cxx
src/SMESH_I/SMESH_Group_i.hxx
src/SMESH_I/SMESH_Hypothesis_i.cxx
src/SMESH_I/SMESH_Hypothesis_i.hxx
src/SMESH_I/SMESH_MEDFamily_i.cxx
src/SMESH_I/SMESH_MEDFamily_i.hxx
src/SMESH_I/SMESH_MEDMesh_i.cxx
src/SMESH_I/SMESH_MEDMesh_i.hxx
src/SMESH_I/SMESH_MEDSupport_i.cxx
src/SMESH_I/SMESH_MEDSupport_i.hxx
src/SMESH_I/SMESH_Measurements_i.cxx [new file with mode: 0644]
src/SMESH_I/SMESH_Measurements_i.hxx [new file with mode: 0644]
src/SMESH_I/SMESH_MeshEditor_i.cxx
src/SMESH_I/SMESH_MeshEditor_i.hxx
src/SMESH_I/SMESH_Mesh_i.cxx
src/SMESH_I/SMESH_Mesh_i.hxx
src/SMESH_I/SMESH_NoteBook.cxx
src/SMESH_I/SMESH_NoteBook.hxx
src/SMESH_I/SMESH_Pattern_i.cxx
src/SMESH_I/SMESH_Pattern_i.hxx
src/SMESH_I/SMESH_PreMeshInfo.cxx [new file with mode: 0644]
src/SMESH_I/SMESH_PreMeshInfo.hxx [new file with mode: 0644]
src/SMESH_I/SMESH_PythonDump.hxx
src/SMESH_I/SMESH_subMesh_i.cxx
src/SMESH_I/SMESH_subMesh_i.hxx
src/SMESH_I/smeshpy.py
src/SMESH_PY/Makefile.am [new file with mode: 0644]
src/SMESH_PY/__init__.py [new file with mode: 0644]
src/SMESH_PY/smeshstudytools.py [new file with mode: 0644]
src/SMESH_SWIG/Makefile.am
src/SMESH_SWIG/PAL_MESH_041_mesh.py
src/SMESH_SWIG/PAL_MESH_043_2D.py
src/SMESH_SWIG/PAL_MESH_043_3D.py
src/SMESH_SWIG/SMESH_AdvancedEditor.py
src/SMESH_SWIG/SMESH_BelongToGeom.py
src/SMESH_SWIG/SMESH_BuildCompound.py
src/SMESH_SWIG/SMESH_GroupFromGeom.py
src/SMESH_SWIG/SMESH_GroupFromGeom2.py
src/SMESH_SWIG/SMESH_GroupLyingOnGeom.py
src/SMESH_SWIG/SMESH_Nut.py
src/SMESH_SWIG/SMESH_Partition1_tetra.py
src/SMESH_SWIG/SMESH_Sphere.py
src/SMESH_SWIG/SMESH_blocks.py
src/SMESH_SWIG/SMESH_box.py
src/SMESH_SWIG/SMESH_box2_tetra.py
src/SMESH_SWIG/SMESH_box3_tetra.py
src/SMESH_SWIG/SMESH_box_tetra.py
src/SMESH_SWIG/SMESH_controls.py
src/SMESH_SWIG/SMESH_demo_hexa2_upd.py
src/SMESH_SWIG/SMESH_fixation.py
src/SMESH_SWIG/SMESH_fixation_hexa.py
src/SMESH_SWIG/SMESH_fixation_netgen.py
src/SMESH_SWIG/SMESH_fixation_tetra.py
src/SMESH_SWIG/SMESH_flight_skin.py
src/SMESH_SWIG/SMESH_freebord.py
src/SMESH_SWIG/SMESH_hexaedre.py
src/SMESH_SWIG/SMESH_mechanic.py
src/SMESH_SWIG/SMESH_mechanic_editor.py
src/SMESH_SWIG/SMESH_mechanic_netgen.py
src/SMESH_SWIG/SMESH_mechanic_tetra.py
src/SMESH_SWIG/SMESH_reg.py
src/SMESH_SWIG/SMESH_shared_modules.py
src/SMESH_SWIG/SMESH_test.py
src/SMESH_SWIG/SMESH_test0.py
src/SMESH_SWIG/SMESH_test1.py
src/SMESH_SWIG/SMESH_test1_AndDisplay.py
src/SMESH_SWIG/SMESH_test2.py
src/SMESH_SWIG/SMESH_test3.py
src/SMESH_SWIG/SMESH_test4.py
src/SMESH_SWIG/SMESH_test5.py
src/SMESH_SWIG/StdMeshersDC.py [new file with mode: 0644]
src/SMESH_SWIG/batchmode_mefisto.py
src/SMESH_SWIG/batchmode_smesh.py
src/SMESH_SWIG/ex00_all.py
src/SMESH_SWIG/ex01_cube2build.py
src/SMESH_SWIG/ex02_cube2primitive.py
src/SMESH_SWIG/ex03_cube2partition.py
src/SMESH_SWIG/ex04_cube5tetraHexa.py
src/SMESH_SWIG/ex05_hole1build.py
src/SMESH_SWIG/ex06_hole1boolean.py
src/SMESH_SWIG/ex07_hole1partition.py
src/SMESH_SWIG/ex08_hole2build.py
src/SMESH_SWIG/ex09_grid4build.py
src/SMESH_SWIG/ex10_grid4geometry.py
src/SMESH_SWIG/ex11_grid3partition.py
src/SMESH_SWIG/ex12_grid17partition.py
src/SMESH_SWIG/ex13_hole1partial.py
src/SMESH_SWIG/ex14_cyl1holed.py
src/SMESH_SWIG/ex15_cyl2geometry.py
src/SMESH_SWIG/ex16_cyl2complementary.py
src/SMESH_SWIG/ex17_dome1.py
src/SMESH_SWIG/ex18_dome2.py
src/SMESH_SWIG/ex19_sphereINcube.py
src/SMESH_SWIG/ex21_lamp.py
src/SMESH_SWIG/ex24_cylinder.py
src/SMESH_SWIG/ex29_refine.py
src/SMESH_SWIG/ex30_groupsOp.py
src/SMESH_SWIG/ex30_tepal.py
src/SMESH_SWIG/ex31_dimGroup.py
src/SMESH_SWIG/smesh.py
src/SMESH_SWIG/smeshDC.py
src/SMESH_SWIG_WITHIHM/Makefile.am
src/SMESH_SWIG_WITHIHM/libSMESH_Swig.cxx
src/SMESH_SWIG_WITHIHM/libSMESH_Swig.h
src/SMESH_SWIG_WITHIHM/libSMESH_Swig.i
src/StdMeshers/Makefile.am
src/StdMeshers/SMESH_StdMeshers.hxx
src/StdMeshers/StdMeshers_Arithmetic1D.cxx
src/StdMeshers/StdMeshers_Arithmetic1D.hxx
src/StdMeshers/StdMeshers_AutomaticLength.cxx
src/StdMeshers/StdMeshers_AutomaticLength.hxx
src/StdMeshers/StdMeshers_CartesianParameters3D.cxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_CartesianParameters3D.hxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_Cartesian_3D.cxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_Cartesian_3D.hxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_CompositeHexa_3D.cxx
src/StdMeshers/StdMeshers_CompositeHexa_3D.hxx
src/StdMeshers/StdMeshers_CompositeSegment_1D.cxx
src/StdMeshers/StdMeshers_CompositeSegment_1D.hxx
src/StdMeshers/StdMeshers_Deflection1D.cxx
src/StdMeshers/StdMeshers_Deflection1D.hxx
src/StdMeshers/StdMeshers_Distribution.cxx
src/StdMeshers/StdMeshers_Distribution.hxx
src/StdMeshers/StdMeshers_FaceSide.cxx
src/StdMeshers/StdMeshers_FaceSide.hxx
src/StdMeshers/StdMeshers_FixedPoints1D.cxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_FixedPoints1D.hxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_HexaFromSkin_3D.cxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_HexaFromSkin_3D.hxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_Hexa_3D.cxx
src/StdMeshers/StdMeshers_Hexa_3D.hxx
src/StdMeshers/StdMeshers_ImportSource.cxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_ImportSource.hxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_Import_1D.cxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_Import_1D.hxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_Import_1D2D.cxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_Import_1D2D.hxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_LayerDistribution.cxx
src/StdMeshers/StdMeshers_LayerDistribution.hxx
src/StdMeshers/StdMeshers_LayerDistribution2D.cxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_LayerDistribution2D.hxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_LengthFromEdges.cxx
src/StdMeshers/StdMeshers_LengthFromEdges.hxx
src/StdMeshers/StdMeshers_LocalLength.cxx
src/StdMeshers/StdMeshers_LocalLength.hxx
src/StdMeshers/StdMeshers_MEFISTO_2D.cxx
src/StdMeshers/StdMeshers_MEFISTO_2D.hxx
src/StdMeshers/StdMeshers_MaxElementArea.cxx
src/StdMeshers/StdMeshers_MaxElementArea.hxx
src/StdMeshers/StdMeshers_MaxElementVolume.cxx
src/StdMeshers/StdMeshers_MaxElementVolume.hxx
src/StdMeshers/StdMeshers_MaxLength.cxx
src/StdMeshers/StdMeshers_MaxLength.hxx
src/StdMeshers/StdMeshers_NotConformAllowed.cxx
src/StdMeshers/StdMeshers_NotConformAllowed.hxx
src/StdMeshers/StdMeshers_NumberOfLayers.cxx
src/StdMeshers/StdMeshers_NumberOfLayers.hxx
src/StdMeshers/StdMeshers_NumberOfLayers2D.cxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_NumberOfLayers2D.hxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_NumberOfSegments.cxx
src/StdMeshers/StdMeshers_NumberOfSegments.hxx
src/StdMeshers/StdMeshers_Penta_3D.cxx
src/StdMeshers/StdMeshers_Penta_3D.hxx
src/StdMeshers/StdMeshers_Prism_3D.cxx
src/StdMeshers/StdMeshers_Prism_3D.hxx
src/StdMeshers/StdMeshers_ProjectionSource1D.cxx
src/StdMeshers/StdMeshers_ProjectionSource1D.hxx
src/StdMeshers/StdMeshers_ProjectionSource2D.cxx
src/StdMeshers/StdMeshers_ProjectionSource2D.hxx
src/StdMeshers/StdMeshers_ProjectionSource3D.cxx
src/StdMeshers/StdMeshers_ProjectionSource3D.hxx
src/StdMeshers/StdMeshers_ProjectionUtils.cxx
src/StdMeshers/StdMeshers_ProjectionUtils.hxx
src/StdMeshers/StdMeshers_Projection_1D.cxx
src/StdMeshers/StdMeshers_Projection_1D.hxx
src/StdMeshers/StdMeshers_Projection_1D2D.cxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_Projection_1D2D.hxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_Projection_2D.cxx
src/StdMeshers/StdMeshers_Projection_2D.hxx
src/StdMeshers/StdMeshers_Projection_3D.cxx
src/StdMeshers/StdMeshers_Projection_3D.hxx
src/StdMeshers/StdMeshers_Propagation.cxx
src/StdMeshers/StdMeshers_Propagation.hxx
src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx
src/StdMeshers/StdMeshers_QuadToTriaAdaptor.hxx
src/StdMeshers/StdMeshers_QuadrangleParams.cxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_QuadrangleParams.hxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_QuadranglePreference.cxx
src/StdMeshers/StdMeshers_QuadranglePreference.hxx
src/StdMeshers/StdMeshers_Quadrangle_2D.cxx
src/StdMeshers/StdMeshers_Quadrangle_2D.hxx
src/StdMeshers/StdMeshers_QuadraticMesh.cxx
src/StdMeshers/StdMeshers_QuadraticMesh.hxx
src/StdMeshers/StdMeshers_RadialPrism_3D.cxx
src/StdMeshers/StdMeshers_RadialPrism_3D.hxx
src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.hxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_Regular_1D.cxx
src/StdMeshers/StdMeshers_Regular_1D.hxx
src/StdMeshers/StdMeshers_SegmentAroundVertex_0D.cxx
src/StdMeshers/StdMeshers_SegmentAroundVertex_0D.hxx
src/StdMeshers/StdMeshers_SegmentLengthAroundVertex.cxx
src/StdMeshers/StdMeshers_SegmentLengthAroundVertex.hxx
src/StdMeshers/StdMeshers_StartEndLength.cxx
src/StdMeshers/StdMeshers_StartEndLength.hxx
src/StdMeshers/StdMeshers_TrianglePreference.cxx [deleted file]
src/StdMeshers/StdMeshers_TrianglePreference.hxx [deleted file]
src/StdMeshers/StdMeshers_UseExisting_1D2D.cxx
src/StdMeshers/StdMeshers_UseExisting_1D2D.hxx
src/StdMeshers/StdMeshers_ViscousLayers.cxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_ViscousLayers.hxx [new file with mode: 0644]
src/StdMeshersGUI/Makefile.am
src/StdMeshersGUI/SMESH_StdMeshersGUI.hxx
src/StdMeshersGUI/StdMeshersGUI.cxx
src/StdMeshersGUI/StdMeshersGUI_CartesianParamCreator.cxx [new file with mode: 0644]
src/StdMeshersGUI/StdMeshersGUI_CartesianParamCreator.h [new file with mode: 0644]
src/StdMeshersGUI/StdMeshersGUI_DistrPreview.cxx
src/StdMeshersGUI/StdMeshersGUI_DistrPreview.h
src/StdMeshersGUI/StdMeshersGUI_DistrTable.cxx
src/StdMeshersGUI/StdMeshersGUI_DistrTable.h
src/StdMeshersGUI/StdMeshersGUI_FixedPointsParamWdg.cxx [new file with mode: 0644]
src/StdMeshersGUI/StdMeshersGUI_FixedPointsParamWdg.h [new file with mode: 0644]
src/StdMeshersGUI/StdMeshersGUI_LayerDistributionParamWdg.cxx
src/StdMeshersGUI/StdMeshersGUI_LayerDistributionParamWdg.h
src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.cxx
src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.h
src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.cxx
src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.h
src/StdMeshersGUI/StdMeshersGUI_QuadrangleParamWdg.cxx [new file with mode: 0644]
src/StdMeshersGUI/StdMeshersGUI_QuadrangleParamWdg.h [new file with mode: 0644]
src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.cxx
src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.h
src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.cxx [new file with mode: 0644]
src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.h [new file with mode: 0644]
src/StdMeshersGUI/StdMeshers_images.ts
src/StdMeshersGUI/StdMeshers_msg_en.ts
src/StdMeshersGUI/StdMeshers_msg_fr.ts [new file with mode: 0755]
src/StdMeshers_I/Makefile.am
src/StdMeshers_I/SMESH_StdMeshers_I.hxx
src/StdMeshers_I/StdMeshers_Arithmetic1D_i.cxx
src/StdMeshers_I/StdMeshers_Arithmetic1D_i.hxx
src/StdMeshers_I/StdMeshers_AutomaticLength_i.cxx
src/StdMeshers_I/StdMeshers_AutomaticLength_i.hxx
src/StdMeshers_I/StdMeshers_CartesianParameters3D_i.cxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_CartesianParameters3D_i.hxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_Cartesian_3D_i.cxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_Cartesian_3D_i.hxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_CompositeSegment_1D_i.cxx
src/StdMeshers_I/StdMeshers_CompositeSegment_1D_i.hxx
src/StdMeshers_I/StdMeshers_Deflection1D_i.cxx
src/StdMeshers_I/StdMeshers_Deflection1D_i.hxx
src/StdMeshers_I/StdMeshers_FixedPoints1D_i.cxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_FixedPoints1D_i.hxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_Hexa_3D_i.cxx
src/StdMeshers_I/StdMeshers_Hexa_3D_i.hxx
src/StdMeshers_I/StdMeshers_ImportSource1D_i.cxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_ImportSource1D_i.hxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_ImportSource2D_i.cxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_ImportSource2D_i.hxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_Import_1D2D_i.cxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_Import_1D2D_i.hxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_Import_1D_i.cxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_Import_1D_i.hxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_LayerDistribution2D_i.cxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_LayerDistribution2D_i.hxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_LayerDistribution_i.cxx
src/StdMeshers_I/StdMeshers_LayerDistribution_i.hxx
src/StdMeshers_I/StdMeshers_LengthFromEdges_i.cxx
src/StdMeshers_I/StdMeshers_LengthFromEdges_i.hxx
src/StdMeshers_I/StdMeshers_LocalLength_i.cxx
src/StdMeshers_I/StdMeshers_LocalLength_i.hxx
src/StdMeshers_I/StdMeshers_MEFISTO_2D_i.cxx
src/StdMeshers_I/StdMeshers_MEFISTO_2D_i.hxx
src/StdMeshers_I/StdMeshers_MaxElementArea_i.cxx
src/StdMeshers_I/StdMeshers_MaxElementArea_i.hxx
src/StdMeshers_I/StdMeshers_MaxElementVolume_i.cxx
src/StdMeshers_I/StdMeshers_MaxElementVolume_i.hxx
src/StdMeshers_I/StdMeshers_MaxLength_i.cxx
src/StdMeshers_I/StdMeshers_MaxLength_i.hxx
src/StdMeshers_I/StdMeshers_NotConformAllowed_i.cxx
src/StdMeshers_I/StdMeshers_NotConformAllowed_i.hxx
src/StdMeshers_I/StdMeshers_NumberOfLayers2D_i.cxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_NumberOfLayers2D_i.hxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_NumberOfLayers_i.cxx
src/StdMeshers_I/StdMeshers_NumberOfLayers_i.hxx
src/StdMeshers_I/StdMeshers_NumberOfSegments_i.cxx
src/StdMeshers_I/StdMeshers_NumberOfSegments_i.hxx
src/StdMeshers_I/StdMeshers_ObjRefUlils.cxx
src/StdMeshers_I/StdMeshers_ObjRefUlils.hxx
src/StdMeshers_I/StdMeshers_Prism_3D_i.cxx
src/StdMeshers_I/StdMeshers_Prism_3D_i.hxx
src/StdMeshers_I/StdMeshers_ProjectionSource1D_i.cxx
src/StdMeshers_I/StdMeshers_ProjectionSource1D_i.hxx
src/StdMeshers_I/StdMeshers_ProjectionSource2D_i.cxx
src/StdMeshers_I/StdMeshers_ProjectionSource2D_i.hxx
src/StdMeshers_I/StdMeshers_ProjectionSource3D_i.cxx
src/StdMeshers_I/StdMeshers_ProjectionSource3D_i.hxx
src/StdMeshers_I/StdMeshers_Projection_1D_2D_3D_i.cxx
src/StdMeshers_I/StdMeshers_Projection_1D_2D_3D_i.hxx
src/StdMeshers_I/StdMeshers_Propagation_i.cxx
src/StdMeshers_I/StdMeshers_Propagation_i.hxx
src/StdMeshers_I/StdMeshers_QuadrangleParams_i.cxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_QuadrangleParams_i.hxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_QuadranglePreference_i.cxx
src/StdMeshers_I/StdMeshers_QuadranglePreference_i.hxx
src/StdMeshers_I/StdMeshers_Quadrangle_2D_i.cxx
src/StdMeshers_I/StdMeshers_Quadrangle_2D_i.hxx
src/StdMeshers_I/StdMeshers_QuadraticMesh_i.cxx
src/StdMeshers_I/StdMeshers_QuadraticMesh_i.hxx
src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.cxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.hxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_Regular_1D_i.cxx
src/StdMeshers_I/StdMeshers_Regular_1D_i.hxx
src/StdMeshers_I/StdMeshers_SegmentAroundVertex_0D_i.cxx
src/StdMeshers_I/StdMeshers_SegmentAroundVertex_0D_i.hxx
src/StdMeshers_I/StdMeshers_SegmentLengthAroundVertex_i.cxx
src/StdMeshers_I/StdMeshers_SegmentLengthAroundVertex_i.hxx
src/StdMeshers_I/StdMeshers_StartEndLength_i.cxx
src/StdMeshers_I/StdMeshers_StartEndLength_i.hxx
src/StdMeshers_I/StdMeshers_TrianglePreference_i.cxx [deleted file]
src/StdMeshers_I/StdMeshers_TrianglePreference_i.hxx [deleted file]
src/StdMeshers_I/StdMeshers_UseExisting_1D2D_i.cxx
src/StdMeshers_I/StdMeshers_UseExisting_1D2D_i.hxx
src/StdMeshers_I/StdMeshers_ViscousLayers_i.cxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_ViscousLayers_i.hxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_i.cxx
src/Tools/Makefile.am [new file with mode: 0644]
src/Tools/MeshCut/AUTHORS [new file with mode: 0644]
src/Tools/MeshCut/Makefile.am [new file with mode: 0644]
src/Tools/MeshCut/MeshCutDialog.ui [new file with mode: 0644]
src/Tools/MeshCut/MeshCut_Carre.cxx [new file with mode: 0644]
src/Tools/MeshCut/MeshCut_Carre.hxx [new file with mode: 0644]
src/Tools/MeshCut/MeshCut_Cas.cxx [new file with mode: 0644]
src/Tools/MeshCut/MeshCut_Cas.hxx [new file with mode: 0644]
src/Tools/MeshCut/MeshCut_Cube.cxx [new file with mode: 0644]
src/Tools/MeshCut/MeshCut_Cube.hxx [new file with mode: 0644]
src/Tools/MeshCut/MeshCut_DC.cxx [new file with mode: 0644]
src/Tools/MeshCut/MeshCut_Fonctions.cxx [new file with mode: 0644]
src/Tools/MeshCut/MeshCut_Fonctions.hxx [new file with mode: 0644]
src/Tools/MeshCut/MeshCut_Globals.hxx [new file with mode: 0644]
src/Tools/MeshCut/MeshCut_Maillage.cxx [new file with mode: 0644]
src/Tools/MeshCut/MeshCut_Maillage.hxx [new file with mode: 0644]
src/Tools/MeshCut/MeshCut_Utils.cxx [new file with mode: 0644]
src/Tools/MeshCut/MeshCut_Utils.hxx [new file with mode: 0644]
src/Tools/MeshCut/README [new file with mode: 0644]
src/Tools/MeshCut/meshcut_plugin.py [new file with mode: 0644]
src/Tools/padder/Makefile.am [new file with mode: 0644]
src/Tools/padder/README.txt [new file with mode: 0644]
src/Tools/padder/doc/Makefile.am [new file with mode: 0755]
src/Tools/padder/doc/doxyfile.in [new file with mode: 0755]
src/Tools/padder/doc/images/SMESH_spadder_end.png [new file with mode: 0644]
src/Tools/padder/doc/images/SMESH_spadder_inputdialog_concrete.png [new file with mode: 0644]
src/Tools/padder/doc/images/SMESH_spadder_inputdialog_start.png [new file with mode: 0644]
src/Tools/padder/doc/images/SMESH_spadder_inputdialog_steelbar.png [new file with mode: 0644]
src/Tools/padder/doc/images/SMESH_spadder_menu.png [new file with mode: 0644]
src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_finished.png [new file with mode: 0644]
src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_ready.png [new file with mode: 0644]
src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_running.png [new file with mode: 0644]
src/Tools/padder/doc/images/SMESH_spadder_plugindialog_published.png [new file with mode: 0644]
src/Tools/padder/doc/images/SMESH_spadder_plugindialog_start.png [new file with mode: 0644]
src/Tools/padder/doc/images/SMESH_spadder_start.png [new file with mode: 0644]
src/Tools/padder/doc/input/padder_userguide.doc [new file with mode: 0644]
src/Tools/padder/meshjob/Makefile.am [new file with mode: 0644]
src/Tools/padder/meshjob/idl/MESHJOB.idl [new file with mode: 0644]
src/Tools/padder/meshjob/idl/Makefile.am [new file with mode: 0644]
src/Tools/padder/meshjob/idl/SPADDERPluginTest.idl [new file with mode: 0644]
src/Tools/padder/meshjob/impl/Makefile.am [new file with mode: 0644]
src/Tools/padder/meshjob/impl/MeshJobManager_i.cxx [new file with mode: 0644]
src/Tools/padder/meshjob/impl/MeshJobManager_i.hxx [new file with mode: 0644]
src/Tools/padder/meshjob/impl/SPADDERPluginTester_i.cxx [new file with mode: 0644]
src/Tools/padder/meshjob/impl/SPADDERPluginTester_i.hxx [new file with mode: 0644]
src/Tools/padder/meshjob/impl/testhelper.hxx [new file with mode: 0644]
src/Tools/padder/resources/Makefile.am [new file with mode: 0644]
src/Tools/padder/resources/SPADDERCatalog.xml [new file with mode: 0644]
src/Tools/padder/resources/appligen/CatalogResources.xml [new file with mode: 0644]
src/Tools/padder/resources/appligen/Makefile.am [new file with mode: 0644]
src/Tools/padder/resources/appligen/README.txt [new file with mode: 0644]
src/Tools/padder/resources/appligen/SalomeApp.xml [new file with mode: 0644]
src/Tools/padder/resources/appligen/appli-splashscreen.jpg [new file with mode: 0644]
src/Tools/padder/resources/appligen/appligen.sh.in [new file with mode: 0755]
src/Tools/padder/resources/appligen/config_appli.xml.in [new file with mode: 0644]
src/Tools/padder/resources/appligen/genenv.sh [new file with mode: 0755]
src/Tools/padder/resources/padderexe/Makefile.am [new file with mode: 0644]
src/Tools/padder/resources/padderexe/buildparticules.py [new file with mode: 0755]
src/Tools/padder/resources/padderexe/envPadder.sh.in [new file with mode: 0644]
src/Tools/padder/resources/padderexe/med2/REF_FinalEDMesh.med [new file with mode: 0644]
src/Tools/padder/resources/padderexe/med2/REF_spheres.dat.xyz [new file with mode: 0644]
src/Tools/padder/resources/padderexe/med2/concrete.med [new file with mode: 0644]
src/Tools/padder/resources/padderexe/med2/data.txt [new file with mode: 0644]
src/Tools/padder/resources/padderexe/med2/ferraill.med [new file with mode: 0644]
src/Tools/padder/resources/padderexe/med2/ferrtran.med [new file with mode: 0644]
src/Tools/padder/resources/padderexe/med2/padder.exe [new file with mode: 0755]
src/Tools/padder/resources/padderexe/med3/concrete.med [new file with mode: 0644]
src/Tools/padder/resources/padderexe/med3/data.txt [new file with mode: 0644]
src/Tools/padder/resources/padderexe/med3/ferraill.med [new file with mode: 0644]
src/Tools/padder/resources/padderexe/med3/padder.exe [new file with mode: 0755]
src/Tools/padder/resources/padderexe/padder.sh [new file with mode: 0755]
src/Tools/padder/resources/padderexe/particules.png [new file with mode: 0644]
src/Tools/padder/spadderpy/Makefile.am [new file with mode: 0644]
src/Tools/padder/spadderpy/__init__.py [new file with mode: 0644]
src/Tools/padder/spadderpy/configreader.py [new file with mode: 0644]
src/Tools/padder/spadderpy/gui/Makefile.am [new file with mode: 0644]
src/Tools/padder/spadderpy/gui/__init__.py [new file with mode: 0644]
src/Tools/padder/spadderpy/gui/addinput.png [new file with mode: 0644]
src/Tools/padder/spadderpy/gui/clear.png [new file with mode: 0644]
src/Tools/padder/spadderpy/gui/compute.png [new file with mode: 0644]
src/Tools/padder/spadderpy/gui/concrete.png [new file with mode: 0644]
src/Tools/padder/spadderpy/gui/deleteinput.png [new file with mode: 0644]
src/Tools/padder/spadderpy/gui/input.png [new file with mode: 0644]
src/Tools/padder/spadderpy/gui/inputdata.py [new file with mode: 0644]
src/Tools/padder/spadderpy/gui/inputdialog.py [new file with mode: 0644]
src/Tools/padder/spadderpy/gui/inputframe.ui [new file with mode: 0644]
src/Tools/padder/spadderpy/gui/parameters.png [new file with mode: 0644]
src/Tools/padder/spadderpy/gui/plugindialog.py [new file with mode: 0644]
src/Tools/padder/spadderpy/gui/plugindialog.ui [new file with mode: 0644]
src/Tools/padder/spadderpy/gui/publish.png [new file with mode: 0644]
src/Tools/padder/spadderpy/gui/refresh.png [new file with mode: 0644]
src/Tools/padder/spadderpy/gui/select.png [new file with mode: 0644]
src/Tools/padder/spadderpy/gui/steelbar.png [new file with mode: 0644]
src/Tools/padder/spadderpy/padder.cfg.in [new file with mode: 0644]
src/Tools/padder/spadderpy/plugin/Makefile.am [new file with mode: 0644]
src/Tools/padder/spadderpy/plugin/envPlugins.sh.in [new file with mode: 0644]
src/Tools/padder/spadderpy/plugin/spadderPlugin.py [new file with mode: 0644]
src/Tools/padder/unittests/Makefile.am [new file with mode: 0644]
src/Tools/padder/unittests/__init__.py [new file with mode: 0644]
src/Tools/padder/unittests/autotest.sh.in [new file with mode: 0644]
src/Tools/padder/unittests/usecase_meshJobManager.py [new file with mode: 0644]
src/Tools/padder/unittests/usecase_spadderPluginTester.py [new file with mode: 0644]
src/Tools/smesh_plugins.py [new file with mode: 0644]

index 507a6f31257db379c503c265832077b353eba6a0..c887e3f829049290e692033da195daf4c0b1d1b6 100644 (file)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # -* Makefile *- 
 # Author : Patrick GOLDBRONN (CEA)
 # Date : 28/06/2001
@@ -28,8 +26,8 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am
 
 if SMESH_ENABLE_GUI
   ACLOCAL_AMFLAGS = -I adm_local/unix/config_files                     \
-                    -I ${KERNEL_ROOT_DIR}/salome_adm/unix/config_files \
                     -I ${GUI_ROOT_DIR}/adm_local/unix/config_files     \
+                    -I ${KERNEL_ROOT_DIR}/salome_adm/unix/config_files \
                     -I ${MED_ROOT_DIR}/adm_local/unix/config_files     \
                     -I ${GEOM_ROOT_DIR}/adm_local/unix/config_files
 else !SMESH_ENABLE_GUI
@@ -39,17 +37,19 @@ else !SMESH_ENABLE_GUI
                     -I ${GEOM_ROOT_DIR}/adm_local/unix/config_files
 endif
 
-SUBDIRS = idl adm_local resources src doc bin
+SUBDIRS = idl adm_local resources src bin doc
 
-DIST_SUBDIRS = idl adm_local resources src doc bin 
+DIST_SUBDIRS = idl adm_local resources src bin doc
 
-DISTCLEANFILES = a.out aclocal.m4 configure
+DISTCLEANFILES = a.out aclocal.m4 configure local-install.sh hack_libtool
 
 salomeinclude_DATA = SMESH_version.h
 
 EXTRA_DIST +=          \
        build_configure \
        clean_configure \
+       build_cmake     \
+       build_cmake.bat \
        LICENCE
 
 dist-hook:
index d9b835afafb464a50f9b18c72186a74140daf1ea..76a669881fd5d10f1df6b9be2a729a5dbd2551a2 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  File   : SMESH_version.h
 //  Author : Vadim SANDLER
 //  Module : SALOME
@@ -32,5 +33,6 @@
 
 #define SMESH_VERSION_STR "@VERSION@"
 #define SMESH_VERSION     @XVERSION@
+#define SMESH_DEVELOPMENT @VERSION_DEV@
 
 #endif // __SMESH_VERSION_H__
index f35273fac7de52921e587cdc5f9641c7f3116fc3..6d9ac170cb4ecbcbc520e14fdcef90a20c6f8245 100644 (file)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 include $(top_srcdir)/adm_local/unix/make_common_starter.am
 
-SUBDIRS = unix
+SUBDIRS = unix cmake_files
diff --git a/adm_local/cmake_files/FindSMESH.cmake b/adm_local/cmake_files/FindSMESH.cmake
new file mode 100644 (file)
index 0000000..edcba9d
--- /dev/null
@@ -0,0 +1,42 @@
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# 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.com
+#
+
+SET(SMESH_CXXFLAGS -I${SMESH_ROOT_DIR}/include/salome)
+
+FIND_LIBRARY(GeomSelectionTools GeomSelectionTools ${SMESH_ROOT_DIR}/lib/salome)
+FIND_LIBRARY(MEFISTO2D MEFISTO2D ${SMESH_ROOT_DIR}/lib/salome)
+FIND_LIBRARY(MeshDriverDAT MeshDriverDAT ${SMESH_ROOT_DIR}/lib/salome)
+FIND_LIBRARY(MeshDriverMED MeshDriverMED ${SMESH_ROOT_DIR}/lib/salome)
+FIND_LIBRARY(MeshDriver MeshDriver ${SMESH_ROOT_DIR}/lib/salome)
+FIND_LIBRARY(MeshDriverSTL MeshDriverSTL ${SMESH_ROOT_DIR}/lib/salome)
+FIND_LIBRARY(MeshDriverUNV MeshDriverUNV ${SMESH_ROOT_DIR}/lib/salome)
+FIND_LIBRARY(SalomeIDLSMESH SalomeIDLSMESH ${SMESH_ROOT_DIR}/lib/salome)
+FIND_LIBRARY(SMDS SMDS ${SMESH_ROOT_DIR}/lib/salome)
+FIND_LIBRARY(SMESHClient SMESHClient ${SMESH_ROOT_DIR}/lib/salome)
+FIND_LIBRARY(SMESHControls SMESHControls ${SMESH_ROOT_DIR}/lib/salome)
+FIND_LIBRARY(SMESHDS SMESHDS ${SMESH_ROOT_DIR}/lib/salome)
+FIND_LIBRARY(SMESHEngine SMESHEngine ${SMESH_ROOT_DIR}/lib/salome)
+FIND_LIBRARY(SMESHFiltersSelection SMESHFiltersSelection ${SMESH_ROOT_DIR}/lib/salome)
+FIND_LIBRARY(SMESHimpl SMESHimpl ${SMESH_ROOT_DIR}/lib/salome)
+FIND_LIBRARY(SMESHObject SMESHObject ${SMESH_ROOT_DIR}/lib/salome)
+FIND_LIBRARY(SMESH SMESH ${SMESH_ROOT_DIR}/lib/salome)
+FIND_LIBRARY(StdMeshersEngine StdMeshersEngine ${SMESH_ROOT_DIR}/lib/salome)
+FIND_LIBRARY(StdMeshersGUI StdMeshersGUI ${SMESH_ROOT_DIR}/lib/salome)
+FIND_LIBRARY(StdMeshers StdMeshers ${SMESH_ROOT_DIR}/lib/salome)
+FIND_LIBRARY(SMESHUtils SMESHUtils ${SMESH_ROOT_DIR}/lib/salome)
diff --git a/adm_local/cmake_files/Makefile.am b/adm_local/cmake_files/Makefile.am
new file mode 100644 (file)
index 0000000..59484d2
--- /dev/null
@@ -0,0 +1,25 @@
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# 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.com
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+admlocal_cmakedir = $(admlocaldir)/cmake_files
+
+dist_admlocal_cmake_DATA = \
+FindSMESH.cmake
index 5f6d5f7536c72fc43090c511c2a26518cb92af5d..0d5ee76b8ee459c88d1404514f27bade7d926b59 100644 (file)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 include $(top_srcdir)/adm_local/unix/make_common_starter.am
 
 SUBDIRS = config_files
index 0ed70f5f85d80f6eae11a8a1aabd5e3c32f396c8..938083baab23366e68418ae6e9a5f71d854fc060 100644 (file)
@@ -1,27 +1,24 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 include $(top_srcdir)/adm_local/unix/make_common_starter.am
 
 dist_admlocalm4_DATA = \
     check_SMESH.m4     \
-    check_f77.m4       \
-    check_Platform.m4
+    check_Platform.m4   
index ff6606562e82963016b55219b21ede6363059048..93c7267e7cfba358478b2a7ac686bceb63472e51 100755 (executable)
@@ -1,24 +1,25 @@
-dnl  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+dnl Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 dnl
-dnl  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-dnl  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+dnl Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 dnl
-dnl  This library is free software; you can redistribute it and/or
-dnl  modify it under the terms of the GNU Lesser General Public
-dnl  License as published by the Free Software Foundation; either
-dnl  version 2.1 of the License.
+dnl This library is free software; you can redistribute it and/or
+dnl modify it under the terms of the GNU Lesser General Public
+dnl License as published by the Free Software Foundation; either
+dnl version 2.1 of the License.
 dnl
-dnl  This library is distributed in the hope that it will be useful,
-dnl  but WITHOUT ANY WARRANTY; without even the implied warranty of
-dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-dnl  Lesser General Public License for more details.
+dnl This library is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+dnl Lesser General Public License for more details.
 dnl
-dnl  You should have received a copy of the GNU Lesser General Public
-dnl  License along with this library; if not, write to the Free Software
-dnl  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+dnl You should have received a copy of the GNU Lesser General Public
+dnl License along with this library; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 dnl
-dnl  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 dnl
+
 AC_DEFUN([CHECK_PLATFORM],[
 AC_REQUIRE([AC_PROG_CC])dnl
 AC_REQUIRE([AC_PROG_CPP])dnl
index 4c0cdb6e4399e90686bb4b0ba219444859a02928..9096571c19c7b4402fcd2070f22af4b7bf12a7fb 100644 (file)
@@ -1,24 +1,25 @@
-dnl  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+dnl Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 dnl
-dnl  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-dnl  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+dnl Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 dnl
-dnl  This library is free software; you can redistribute it and/or
-dnl  modify it under the terms of the GNU Lesser General Public
-dnl  License as published by the Free Software Foundation; either
-dnl  version 2.1 of the License.
+dnl This library is free software; you can redistribute it and/or
+dnl modify it under the terms of the GNU Lesser General Public
+dnl License as published by the Free Software Foundation; either
+dnl version 2.1 of the License.
 dnl
-dnl  This library is distributed in the hope that it will be useful,
-dnl  but WITHOUT ANY WARRANTY; without even the implied warranty of
-dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-dnl  Lesser General Public License for more details.
+dnl This library is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+dnl Lesser General Public License for more details.
 dnl
-dnl  You should have received a copy of the GNU Lesser General Public
-dnl  License along with this library; if not, write to the Free Software
-dnl  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+dnl You should have received a copy of the GNU Lesser General Public
+dnl License along with this library; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 dnl
-dnl  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 dnl
+
 # Check availability of SMesh binary distribution
 #
 # Author : Nicolas REJNERI (OPEN CASCADE, 2003)
diff --git a/adm_local/unix/config_files/check_cgal.m4 b/adm_local/unix/config_files/check_cgal.m4
new file mode 100644 (file)
index 0000000..2ec4336
--- /dev/null
@@ -0,0 +1,101 @@
+dnl Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+dnl
+dnl Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+dnl
+dnl This library is free software; you can redistribute it and/or
+dnl modify it under the terms of the GNU Lesser General Public
+dnl License as published by the Free Software Foundation; either
+dnl version 2.1 of the License.
+dnl
+dnl This library is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+dnl Lesser General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU Lesser General Public
+dnl License along with this library; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+dnl
+dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+dnl
+
+AC_DEFUN([CHECK_CGAL],[
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_CPP])dnl
+AC_REQUIRE([CHECK_BOOST])
+
+AC_CHECKING(for CGAL)
+
+AC_ARG_WITH(cgal,
+    [  --with-cgal=DIR                 root directory path to CGAL installation ],
+    [CGALHOME="$withval"
+      AC_MSG_RESULT("select $withval as path to CGAL")
+    ])
+
+AC_SUBST(CGAL_INCLUDES)
+AC_SUBST(CGAL_LIBS)
+AC_SUBST(CGALHOME)
+
+CGAL_INCLUDES=""
+CGAL_LIBS=""
+
+cgal_ok=no
+
+LOCAL_INCLUDES=""
+LOCAL_LIBS="-lCGAL"
+
+if test "x$CGALHOME" != "xno"; then
+    if test "x$CGALHOME" == "xyes"; then
+        CGALHOME=""
+    fi
+    if test -z $CGALHOME
+    then
+        AC_MSG_WARN(undefined CGALHOME variable which specify CGAL library installation directory)
+        AC_PATH_PROG(BINDIR, cgal_create_cmake_script)
+        if test "x$BINDIR" != "x" ; then
+            CGALHOME=$BINDIR
+            CGALHOME=`echo ${CGALHOME} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"`
+            CGALHOME=`echo ${CGALHOME} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"`
+        fi
+    fi
+    if test ! -z $CGALHOME
+    then
+        cgal_ok=yes
+        LOCAL_INCLUDES="-I$CGALHOME/include"
+        if test "x$CGALHOME" != "x/usr"; then
+            LOCAL_LIBS="-L$CGALHOME/lib $LOCAL_LIBS"
+        fi
+    fi
+
+dnl check cgallib header
+
+    # CPPFLAGS_old=$CPPFLAGS
+    # CPPFLAGS="$CPPFLAGS $LOCAL_INCLUDES -I$BOOSTDIR/include"
+
+    # AC_CHECK_HEADER(algorithm.h,cgal_ok=yes ,cgal_ok=no)
+
+    # CPPFLAGS=$CPPFLAGS_old
+fi
+
+# if  test "x$cgal_ok" = "xyes"
+# then
+# dnl check cgal library
+#   LIBS_old="$LIBS"
+#   LIBS="$LIBS $LOCAL_LIBS"
+#   AC_CHECK_LIB(cgns,cg_open,cgns_ok=yes,cgns_ok=no)
+#   LIBS="$LIBS_old" 
+# fi
+
+if  test "x$cgal_ok" = "xyes"
+then
+  CGAL_LIBS="$LOCAL_LIBS"
+  CGAL_INCLUDES="$LOCAL_INCLUDES"
+  CPPFLAGS="-DWITH_CGAL $CPPFLAGS"
+fi
+
+AC_MSG_RESULT(for CGAL: $cgal_ok)
+
+AM_CONDITIONAL(WITH_CGAL, [test x"$cgal_ok" = xyes])
+
+])dnl
diff --git a/adm_local/unix/config_files/check_cgns.m4 b/adm_local/unix/config_files/check_cgns.m4
new file mode 100644 (file)
index 0000000..4e25e27
--- /dev/null
@@ -0,0 +1,103 @@
+dnl Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+dnl
+dnl Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+dnl
+dnl This library is free software; you can redistribute it and/or
+dnl modify it under the terms of the GNU Lesser General Public
+dnl License as published by the Free Software Foundation; either
+dnl version 2.1 of the License.
+dnl
+dnl This library is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+dnl Lesser General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU Lesser General Public
+dnl License along with this library; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+dnl
+dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+dnl
+
+AC_DEFUN([CHECK_CGNS],[
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_CPP])dnl
+AC_REQUIRE([CHECK_HDF5])dnl
+
+AC_CHECKING(for CGNS)
+
+AC_ARG_WITH(cgns,
+    [  --with-cgns=DIR                 root directory path to CGNS installation ],
+    [CGNSHOME="$withval"
+      AC_MSG_RESULT("select $withval as path to CGNS")
+    ])
+
+AC_SUBST(CGNS_INCLUDES)
+AC_SUBST(CGNS_LIBS)
+
+CGNS_INCLUDES=""
+CGNS_LIBS=""
+
+cgns_ok=no
+
+LOCAL_INCLUDES=""
+LOCAL_LIBS="-lcgns $HDF5_LIBS"
+
+if test "x$CGNSHOME" != "xno"; then
+    if test "x$CGNSHOME" == "xyes"; then
+        CGNSHOME=""
+    fi
+    if test -z $CGNSHOME
+    then
+        AC_MSG_WARN(undefined CGNSHOME variable which specify CGNS library installation directory)
+        AC_PATH_PROG(BINDIR, cgnsversion)
+        if test "x$BINDIR" != "x" ; then
+            CGNSHOME=$BINDIR
+            CGNSHOME=`echo ${CGNSHOME} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"`
+            CGNSHOME=`echo ${CGNSHOME} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"`
+        fi
+    fi
+    if test ! -z $CGNSHOME
+    then
+        LOCAL_INCLUDES="-I$CGNSHOME/include"
+        if test "x$CGNSHOME" != "x/usr"; then
+            LOCAL_LIBS="-L$CGNSHOME/lib $LOCAL_LIBS"
+        fi
+    fi
+
+dnl check cgnslib header
+
+    CPPFLAGS_old=$CPPFLAGS
+    CPPFLAGS="$CPPFLAGS $LOCAL_INCLUDES"
+
+    AC_CHECK_HEADER(cgnslib.h,cgns_ok=yes ,cgns_ok=no)
+
+    CPPFLAGS=$CPPFLAGS_old
+fi
+
+if  test "x$cgns_ok" = "xyes"
+then
+
+dnl check cgns library
+
+  LIBS_old="$LIBS"
+  LIBS="$LIBS $LOCAL_LIBS"
+  AC_CHECK_LIB(cgns,cg_open,cgns_ok=yes,cgns_ok=no)
+
+  LIBS="$LIBS_old"
+fi
+
+if  test "x$cgns_ok" = "xyes"
+then
+  CGNS_LIBS="$LOCAL_LIBS"
+  CGNS_INCLUDES="$LOCAL_INCLUDES"
+  CPPFLAGS="-DWITH_CGNS $CPPFLAGS"
+fi
+
+AC_MSG_RESULT(for CGNS: $cgns_ok)
+
+AM_CONDITIONAL(WITH_CGNS, [test x"$cgns_ok" = xyes])
+
+])dnl
index e03c6c165359e1f196ee94b8d0ba46391a3c613e..64d3288ab370ed04abec6330a5d90eb4fc6b506d 100644 (file)
@@ -1,23 +1,23 @@
-dnl  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+dnl Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 dnl
-dnl  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-dnl  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+dnl Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 dnl
-dnl  This library is free software; you can redistribute it and/or
-dnl  modify it under the terms of the GNU Lesser General Public
-dnl  License as published by the Free Software Foundation; either
-dnl  version 2.1 of the License.
+dnl This library is free software; you can redistribute it and/or
+dnl modify it under the terms of the GNU Lesser General Public
+dnl License as published by the Free Software Foundation; either
+dnl version 2.1 of the License.
 dnl
-dnl  This library is distributed in the hope that it will be useful,
-dnl  but WITHOUT ANY WARRANTY; without even the implied warranty of
-dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-dnl  Lesser General Public License for more details.
+dnl This library is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+dnl Lesser General Public License for more details.
 dnl
-dnl  You should have received a copy of the GNU Lesser General Public
-dnl  License along with this library; if not, write to the Free Software
-dnl  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+dnl You should have received a copy of the GNU Lesser General Public
+dnl License along with this library; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 dnl
-dnl  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 dnl
 AC_DEFUN([CHECK_F77],[
 
diff --git a/adm_local/unix/config_files/check_padder.m4 b/adm_local/unix/config_files/check_padder.m4
new file mode 100644 (file)
index 0000000..ab30fec
--- /dev/null
@@ -0,0 +1,69 @@
+dnl Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+dnl
+dnl Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+dnl
+dnl This library is free software; you can redistribute it and/or
+dnl modify it under the terms of the GNU Lesser General Public
+dnl License as published by the Free Software Foundation; either
+dnl version 2.1 of the License.
+dnl
+dnl This library is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+dnl Lesser General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU Lesser General Public
+dnl License along with this library; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+dnl
+dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+dnl
+
+AC_DEFUN([CHECK_PADDER],[
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_CPP])dnl
+AC_REQUIRE([CHECK_CGAL])
+
+AC_CHECKING(for PADDER)
+
+padder_ok=no
+
+AC_ARG_WITH(padder,
+    [  --with-padder=DIR                 root directory path to PADDER installation ],
+    [PADDERHOME="$withval"
+      AC_MSG_RESULT("select $withval as path to PADDER")
+    ])
+
+if test "x$PADDERHOME" != "xno"; then
+    if test "x$PADDERHOME" == "xyes"; then
+        PADDERHOME=""
+    fi
+    if test -z $PADDERHOME
+    then
+        AC_MSG_WARN(undefined PADDERHOME variable which specify PADDER installation directory)
+        AC_PATH_PROG(BINDIR, padder.exe)
+        if test "x$BINDIR" != "x" ; then
+            PADDERHOME=$BINDIR
+            PADDERHOME=`echo ${PADDERHOME} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"`
+            PADDERHOME=`echo ${PADDERHOME} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"`
+        fi
+    fi
+    if test ! -z $PADDERHOME
+    then
+        AC_CHECK_FILE($PADDERHOME/padder.env,padder_ok=yes,padder_ok=no)
+    fi
+fi
+
+if  test "x$padder_ok" = "xyes"
+then
+  CPPFLAGS="-DWITH_PADDER $CPPFLAGS"
+fi
+
+AC_SUBST(PADDERHOME)
+
+AC_MSG_RESULT(for PADDER: $padder_ok)
+
+AM_CONDITIONAL(WITH_PADDER, [test x"$padder_ok" = xyes])
+
+])dnl
diff --git a/adm_local/unix/config_files/check_qwt.m4 b/adm_local/unix/config_files/check_qwt.m4
new file mode 100644 (file)
index 0000000..b151420
--- /dev/null
@@ -0,0 +1,187 @@
+dnl Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+dnl
+dnl Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+dnl
+dnl This library is free software; you can redistribute it and/or
+dnl modify it under the terms of the GNU Lesser General Public
+dnl License as published by the Free Software Foundation; either
+dnl version 2.1 of the License.
+dnl
+dnl This library is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+dnl Lesser General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU Lesser General Public
+dnl License along with this library; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+dnl
+dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+dnl
+AC_DEFUN([CHECK_QWT],[
+AC_REQUIRE([CHECK_QT])dnl
+AC_REQUIRE([AC_LINKER_OPTIONS])dnl
+
+AC_CHECKING(for qwt)
+
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+
+qwt_ok=yes
+
+dnl where is qwt ?
+
+AC_ARG_WITH(qwt,
+    [  --with-qwt=DIR     directory path to QWT installation ],
+    [QWTHOME="$withval"
+      AC_MSG_RESULT("select $withval as path to QWT")
+    ])
+
+AC_ARG_WITH(qwt_inc,
+    [  --with-qwt_inc=DIR   directory path to QWT includes ],
+    [QWT_INCDIR="$withval"
+      AC_MSG_RESULT("select $withval as path to QWT includes")
+    ])
+
+libqwt_name=qwt
+if test -z $QWTHOME; then
+  AC_MSG_RESULT(QWTHOME not defined)
+  AC_MSG_NOTICE(Trying native Qwt...)
+  exist_ok=no  
+  if test "x$exist_ok" = "xno"; then
+     for d in /usr /usr/local ; do
+        for extension in qwt-qt4 qwt; do
+           AC_CHECK_FILE(${d}/lib${LIB_LOCATION_SUFFIX}/lib${extension}.so,exist_ok=yes,exist_ok=no)
+           if test "x$exist_ok" = "xyes"; then
+              QWTHOME=$d
+              AC_MSG_RESULT(lib${extension}.so detected in $d/lib)
+              libqwt_name=${extension}
+              dnl  break, libqwt-qt4.so is choosen before libqwt.so since it is surely the Qt4 version.
+              break
+           fi
+        done
+        if test "x$exist_ok" = "xyes"; then
+           break
+        fi
+     done
+  fi
+  if test "x$exist_ok" = "xno"; then
+     for d in `echo $LD_LIBRARY_PATH | sed -e "s/:/ /g"` ; do
+        if test -f $d/libqwt.so ; then
+           AC_MSG_RESULT(libqwt.so detected in $d)
+           QWTHOME=$d
+           QWTHOME=`echo ${QWTHOME} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"`
+           exist_ok=yes
+           break
+        fi
+     done
+  fi
+  if test "x$exist_ok" = "xyes"; then
+     if test -z $QWT_INCDIR; then
+        QWT_INCDIR=$QWTHOME"/include/qwt-qt4"
+        if test ! -f $QWT_INCDIR/qwt.h ; then
+          QWT_INCDIR=/usr/include/qwt
+        fi
+        if test ! -f $QWT_INCDIR/qwt.h ; then
+          QWT_INCDIR=$QWTHOME"/include"
+        fi
+        if test ! -f $QWT_INCDIR/qwt.h ; then
+          QWT_INCDIR=/usr/lib/qt4/include/qwt
+        fi
+        if test ! -f $QWT_INCDIR/qwt.h ; then
+          QWT_INCDIR=/usr/include/qwt-qt4
+        fi
+     fi
+  else
+     qwt_ok=no
+  fi
+else
+  AC_MSG_NOTICE(Trying Qwt from $QWTHOME ...)
+  if test -z $QWT_INCDIR; then
+     QWT_INCDIR="$QWTHOME/include"
+  fi           
+fi
+
+if test "x$qwt_ok" = xno -o ! -d "$QWTHOME" ; then
+  AC_MSG_RESULT(no)
+  AC_MSG_WARN(qwt not found)
+  qwt_ok=no
+else
+  CPPFLAGS_old=$CPPFLAGS
+  CPPFLAGS="$CPPFLAGS $QT_INCLUDES -I$QWT_INCDIR"
+
+  AC_CHECK_HEADER(qwt.h,qwt_ok=yes,qwt_ok=no) 
+  CPPFLAGS=$CPPFLAGS_old
+
+  AC_MSG_CHECKING(include of qwt headers)
+
+  if test "x$qwt_ok" = xno ; then
+    AC_MSG_RESULT(no)
+    AC_MSG_WARN(qwt not found)
+  else
+    AC_MSG_RESULT(yes)
+    QWT_INCLUDES=-I$QWT_INCDIR
+  fi
+
+  #
+  # test Qwt libraries
+  #
+  if test "x$qwt_ok" = "xyes" ; then
+    AC_MSG_CHECKING(linking qwt library)
+
+    LIBS_old=$LIBS
+    LIBS="$LIBS $QT_LIBS"
+    if test "x$QWTHOME" = "x/usr" ; then
+      LIBS="$LIBS -l${libqwt_name}"
+    else
+      LIBS="$LIBS -L$QWTHOME/lib -l${libqwt_name}"
+    fi
+
+    CXXFLAGS_old=$CXXFLAGS
+    CXXFLAGS="$CXXFLAGS $QT_INCLUDES $QWT_INCLUDES"
+
+    AC_CACHE_VAL(salome_cv_lib_qwt,[
+      AC_TRY_LINK(
+#include <QApplication>
+#include <qwt_plot.h>
+,     int n;
+      char **s;
+      QApplication a(n, s);
+      QwtPlot p;
+      p.resize( 600, 400 );
+      p.show();
+      a.exec();,
+      eval "salome_cv_lib_qwt=yes",eval "salome_cv_lib_qwt=no")
+    ])
+    qwt_ok="$salome_cv_lib_qwt"
+
+    if  test "x$qwt_ok" = "xno" ; then
+      AC_MSG_RESULT(unable to link with qwt library)
+      AC_MSG_RESULT(QWTHOME environment variable may be wrong)
+    else
+      AC_MSG_RESULT(yes)
+      if test "x$QWTHOME" = "x/usr" ; then
+        QWT_LIBS=" -l${libqwt_name}"
+      else
+        QWT_LIBS="-L$QWTHOME/lib -l${libqwt_name}"
+      fi
+    fi
+
+    LIBS=$LIBS_old
+    CXXFLAGS=$CXXFLAGS_old
+  fi
+fi
+
+AC_SUBST(QWT_INCLUDES)
+AC_SUBST(QWT_LIBS)
+
+AC_LANG_RESTORE
+
+AC_MSG_RESULT(for qwt: $qwt_ok)
+
+# Save cache
+AC_CACHE_SAVE
+
+])dnl
+dnl
index 36ad8c3a7c7e37c3da0591452c8cc09f24250858..295f19f813747e09386e7c32a4fa9b0e63df04e5 100644 (file)
@@ -1,24 +1,30 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
 #
-#  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+
+# ============================================================
+# The following is to avoid PACKAGE_... env variable
+# redefinition compilation warnings
+# ============================================================
 #
+AM_CXXFLAGS = @KERNEL_CXXFLAGS@ -include SALOMEconfig.h
+AM_CPPFLAGS = @KERNEL_CXXFLAGS@ -include SALOMEconfig.h
+
 # ============================================================
 # This file defines the common definitions used in several
 # Makefile. This file must be included, if needed, by the file
@@ -33,6 +39,12 @@ salomescriptdir    = $(bindir)
 salomepythondir    = $(pythondir)/salome
 salomepyexecdir    = $(pyexecdir)/salome
 
+# Root directory of the python packages of SMESH
+smeshpypkgdir      = $(salomepythondir)/salome/smesh
+
+# Directory for installing SALOME plugins files
+salomepluginsdir    = $(prefix)/share/salome/plugins/@MODULE_NAME@
+
 # Directory for installing idl files
 salomeidldir       = $(prefix)/idl/salome
 
index dc7848fe5070ec32d899a6f77fda7e2c97453633..7e1eea667b021ba653ebb0caf01ab1f4c9c1f49e 100644 (file)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # -* Makefile *- 
 # Author : Guillaume Boulant (CSSI)
 # Module : SMESH
@@ -28,5 +26,9 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am
 # non-distributed files 
 nodist_salomescript_DATA = VERSION
 
+# python files
+dist_salomescript_PYTHON = \
+       smesh_setenv.py
+
 # distributed files
 dist_salomescript_SCRIPTS =
index fa49d303f21e2f54a2b147c34f9fd5f4b9f849a3..de81461c8b7c0fe17398a3b9cd881d2692c3dc34 100755 (executable)
@@ -1 +1,3 @@
-THIS IS SALOME - SMESH VERSION: @VERSION@
+[SALOME SMESH] : @VERSION@
+[DEVELOPMENT]  : @VERSION_DEV@
+[DESCRIPTION]  : SALOME Mesh module
diff --git a/bin/smesh_setenv.py b/bin/smesh_setenv.py
new file mode 100644 (file)
index 0000000..a58406c
--- /dev/null
@@ -0,0 +1,84 @@
+#!/usr/bin/env python
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# 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.com
+#
+
+import os, sys
+from setenv import add_path, get_lib_dir, salome_subdir
+
+# -----------------------------------------------------------------------------
+
+def set_env(args):
+    """Add to the PATH-variables modules specific paths"""
+    psep = os.pathsep
+    python_version="python%d.%d" % sys.version_info[0:2]
+
+
+    if not os.environ.has_key("SALOME_StdMeshersResources"):
+        os.environ["SALOME_StdMeshersResources"] \
+        = os.path.join(os.environ["SMESH_ROOT_DIR"],"share",salome_subdir,"resources","smesh")
+        pass
+
+    # find plugins
+    plugin_list = []
+    resource_path_list = []
+    for env_var in os.environ.keys():
+        value = os.environ[env_var]
+        if env_var[-9:] == "_ROOT_DIR" and value:
+            plugin_root = value
+            plugin = env_var[:-9] # plugin name may have wrong case
+
+            # look for NAMEOFPlugin.xml file among resource files
+            resource_dir = os.path.join(plugin_root,"share",salome_subdir,"resources",plugin.lower())
+            if not os.access( resource_dir, os.F_OK ): continue
+            for resource_file in os.listdir( resource_dir ):
+                if not resource_file.endswith( ".xml") or \
+                   resource_file.lower() != plugin.lower() + ".xml":
+                    continue
+                # use "resources" attribute of "meshers-group" as name of plugin in a right case
+                from xml.dom.minidom import parse
+                xml_doc = parse( os.path.join( resource_dir, resource_file ))
+                meshers_nodes = xml_doc.getElementsByTagName("meshers-group")
+                if not meshers_nodes or not meshers_nodes[0].hasAttribute("resources"): continue
+                plugin = meshers_nodes[0].getAttribute("resources")
+                if plugin in plugin_list: continue
+
+                # add paths of plugin
+               plugin_list.append(plugin)
+                if not os.environ.has_key("SALOME_"+plugin+"Resources"):
+                    resource_path = os.path.join(plugin_root,"share",salome_subdir,"resources",plugin.lower())
+                    os.environ["SALOME_"+plugin+"Resources"] = resource_path
+                    resource_path_list.append( resource_path )
+                    add_path(os.path.join(plugin_root,get_lib_dir(),python_version, "site-packages",salome_subdir), "PYTHONPATH")
+                    add_path(os.path.join(plugin_root,get_lib_dir(),salome_subdir), "PYTHONPATH")
+                    
+                    if sys.platform == "win32":
+                        add_path(os.path.join(plugin_root,get_lib_dir(),salome_subdir), "PATH")
+                        add_path(os.path.join(plugin_root,"bin",salome_subdir), "PYTHONPATH")
+                    else:
+                        add_path(os.path.join(plugin_root,get_lib_dir(),salome_subdir), "LD_LIBRARY_PATH")
+                        add_path(os.path.join(plugin_root,"bin",salome_subdir), "PYTHONPATH")
+                        add_path(os.path.join(plugin_root,"bin",salome_subdir), "PATH")
+                        pass
+                    pass
+                break
+    plugin_list.append("StdMeshers")
+    os.environ["SMESH_MeshersList"] = ":".join(plugin_list)
+    os.environ["SalomeAppConfig"] = os.environ["SalomeAppConfig"] + psep + psep.join(resource_path_list)
+
diff --git a/build_cmake b/build_cmake
new file mode 100755 (executable)
index 0000000..01bb2ac
--- /dev/null
@@ -0,0 +1,27 @@
+#!/bin/sh
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# 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.com
+#
+
+CURRENT_DIR=`pwd`
+CONF_DIR=`echo $0 | sed -e "s,[^/]*$,,;s,/$,,;s,^$,.,"`
+cd ${CONF_DIR}
+python $KERNEL_ROOT_DIR/salome_adm/cmake_files/am2cmake.py --smesh
+status=$?
+cd ${CURRENT_DIR}
+exit $status
diff --git a/build_cmake.bat b/build_cmake.bat
new file mode 100644 (file)
index 0000000..890adcd
--- /dev/null
@@ -0,0 +1,20 @@
+@REM Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+@REM
+@REM This library is free software; you can redistribute it and/or
+@REM modify it under the terms of the GNU Lesser General Public
+@REM License as published by the Free Software Foundation; either
+@REM version 2.1 of the License.
+@REM
+@REM This library is distributed in the hope that it will be useful,
+@REM but WITHOUT ANY WARRANTY; without even the implied warranty of
+@REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+@REM Lesser General Public License for more details.
+@REM
+@REM You should have received a copy of the GNU Lesser General Public
+@REM License along with this library; if not, write to the Free Software
+@REM Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+@REM
+@REM See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+@REM
+
+%PYTHONBIN% %KERNEL_ROOT_DIR%\salome_adm\cmake_files\am2cmake.py --smesh\r
index d135d9e8d027bbddfd5b19fdb2d9c99431a1d9eb..ce47d8056c03ace9f77680f648ab57de826e1eac 100755 (executable)
@@ -1,25 +1,26 @@
 #!/bin/bash
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # Tool for updating list of .in file for the SALOME project 
 # and regenerating configure script
 # Author : Marc Tajchman - CEA
@@ -29,7 +30,6 @@
 #
 ORIG_DIR=`pwd`
 CONF_DIR=`echo $0 | sed -e "s,[^/]*$,,;s,/$,,;s,^$,.,"`
-SMESH_WITH_GUI="yes"
 
 ########################################################################
 # Test if the KERNEL_ROOT_DIR is set correctly
@@ -46,28 +46,6 @@ fi
 #    exit
 #fi
 
-for option
-do
-  case $option in
-      -with-gui | --with-gui)
-          SMESH_WITH_GUI="yes"
-          break;;
-      -without-gui | --without-gui | -with-gui=no | --with-gui=no)
-          SMESH_WITH_GUI="no"
-          break;;
-  esac
-done
-
-########################################################################
-# Test if the GUI_ROOT_DIR is set correctly
-
-if test ${SMESH_WITH_GUI} = yes; then
-    if test ! -d "${GUI_ROOT_DIR}"; then
-        echo "failed : GUI_ROOT_DIR variable is not correct !"
-        exit
-    fi
-fi
-
 ########################################################################
 # Test if the MED_ROOT_DIR is set correctly
 
@@ -89,61 +67,41 @@ cd ${CONF_DIR}
 ABS_CONF_DIR=`pwd`
 
 #######################################################################
-# Update configure.ac script: to set SMESH_WITH_GUI variable
-sed -e s/SMESH_WITH_GUI=[a-z]*/SMESH_WITH_GUI=${SMESH_WITH_GUI}/g configure.ac > configure.tmp
-mv -f configure.tmp configure.ac
-
-mkdir -p salome_adm/unix/config_files
-#cp -f ${KERNEL_ROOT_DIR}/salome_adm/unix/config_files/* salome_adm/unix/config_files
-#cp -f ${KERNEL_ROOT_DIR}/salome_adm/unix/pythonbe.py salome_adm/unix
-
-cp -f ${KERNEL_ROOT_DIR}/salome_adm/unix/SALOMEconfig.h.in salome_adm/unix
-
-#cp -f ${GUI_ROOT_DIR}/adm_local/unix/config_files/* salome_adm/unix/config_files
-#cp -f ${MED_ROOT_DIR}/adm_local/unix/config_files/* salome_adm/unix/config_files
-#cp -f ${GEOM_ROOT_DIR}/adm_local/unix/config_files/* salome_adm/unix/config_files
-
-# remove KERNEL deprecated configure files
-#for deprecated in ac_cc_warnings.m4 ac_cxx_partial_specialization.m4 \
-#  check_mico.m4 config.guess ltmain.sh ac_cxx_bool.m4 ltconfig ac_cxx_typename.m4 \
-#    check_pthreads.m4 config.sub libtool.m4 ac_cxx_mutable.m4 missing
-#    do
-#      rm -f salome_adm/unix/config_files/${deprecated}
-#      done
-      
 
 # ____________________________________________________________________
 # aclocal creates the aclocal.m4 file from the standard macro and the
-# custom macro embedded in the directory salome_adm/unix/config_files
-# and KERNEL config_files directory.
+# custom macro embedded in the directory adm_local/unix/config_files,
+# KERNEL salome_adm/unix/config_files, GEOM and MED adm_local/unix/config_files
+# directories.
 # output:
 #   aclocal.m4
 #   autom4te.cache (directory)
 echo "====================================================== aclocal"
 
-if test ${SMESH_WITH_GUI} = yes; then
+if test -d "${GUI_ROOT_DIR}"; then
   aclocal -I adm_local/unix/config_files \
           -I ${KERNEL_ROOT_DIR}/salome_adm/unix/config_files \
-         -I ${GUI_ROOT_DIR}/adm_local/unix/config_files \
-         -I ${MED_ROOT_DIR}/adm_local/unix/config_files \
-         -I ${GEOM_ROOT_DIR}/adm_local/unix/config_files || exit 1
+          -I ${GUI_ROOT_DIR}/adm_local/unix/config_files \
+          -I ${MED_ROOT_DIR}/adm_local/unix/config_files \
+          -I ${GEOM_ROOT_DIR}/adm_local/unix/config_files || exit 1
 else
   aclocal -I adm_local/unix/config_files \
           -I ${KERNEL_ROOT_DIR}/salome_adm/unix/config_files \
-         -I ${MED_ROOT_DIR}/adm_local/unix/config_files \
-         -I ${GEOM_ROOT_DIR}/adm_local/unix/config_files || exit 1
+          -I ${MED_ROOT_DIR}/adm_local/unix/config_files \
+          -I ${GEOM_ROOT_DIR}/adm_local/unix/config_files || exit 1
 fi
 
+
 # ____________________________________________________________________
 # libtoolize creates some configuration files (ltmain.sh,
 # config.guess and config.sub). It only depends on the libtool
 # version. The files are created in the directory specified with the
 # AC_CONFIG_AUX_DIR(<mydir>) tag (see configure.ac).
 # output:
-#   salome_adm/unix/config_files/config.guess
-#   salome_adm/unix/config_files/config.sub
-#   salome_adm/unix/config_files/ltmain.sh
-#echo "====================================================== libtoolize"
+#   adm_local/unix/config_files/config.guess
+#   adm_local/unix/config_files/config.sub
+#   adm_local/unix/config_files/ltmain.sh
+echo "==================================================== libtoolize"
 
 libtoolize --force --copy --automake || exit 1
 
@@ -163,11 +121,11 @@ autoconf
 # AC_CONFIG_AUX_DIR(<mydir>) tag (see configure.ac). This step also
 # creates the Makefile.in files from the Makefile.am files.
 # output:
-#   salome_adm/unix/config_files/compile
-#   salome_adm/unix/config_files/depcomp
-#   salome_adm/unix/config_files/install-sh
-#   salome_adm/unix/config_files/missing
-#   salome_adm/unix/config_files/py-compile
+#   adm_local/unix/config_files/compile
+#   adm_local/unix/config_files/depcomp
+#   adm_local/unix/config_files/install-sh
+#   adm_local/unix/config_files/missing
+#   adm_local/unix/config_files/py-compile
 #   Makefile.in (from Makefile.am)
 echo "====================================================== automake"
 
index f57f7b3bf98d03cab5f0acc1a75b80d039d61886..09bfbd7bdd7186dcf1dc8529f4e19fd2942dc4b3 100755 (executable)
@@ -1,25 +1,23 @@
 #!/bin/sh
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 rm -rf autom4te.cache aclocal.m4 configure make_config
 find . -name "*~" -print -exec rm {} \;
 find . -name "*.pyc" -print -exec rm {} \;
@@ -30,6 +28,8 @@ find bin -name Makefile.in | xargs rm -f
 find doc -name Makefile.in | xargs rm -f
 find idl -name Makefile.in | xargs rm -f
 find resources -name Makefile.in | xargs rm -f
-find salome_adm -name Makefile.in | xargs rm -f
+find adm_local -name Makefile.in | xargs rm -f
 find src -name Makefile.in | xargs rm -f
 rm -f Makefile.in
+cd adm_local/unix/config_files
+rm -f config.* depcomp install-sh l*.m4 ltmain.sh missing py-compile
index 4aeb847b623b8f813306f0394b9a0c58af862e34..65f1a6852c8515c434dd4dd21953b13fc564ff68 100644 (file)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # Author : Marc Tajchman (CEA)
 # Date : 28/06/2001
 # Modified by : Patrick GOLDBRONN (CEA)
 # Modified by : Alexander BORODIN (OCN) - autotools usage
 # Created from configure.in.base
 #
-AC_INIT([Salome2 Project SMESH module], [5.1.0], [webmaster.salome@opencascade.com], [SalomeSMESH])
-AC_CONFIG_AUX_DIR(salome_adm/unix/config_files)
+AC_INIT([Salome2 Project SMESH module], [6.5.0], [webmaster.salome@opencascade.com], [SalomeSMESH])
+AC_CONFIG_AUX_DIR(adm_local/unix/config_files)
 AC_CANONICAL_HOST
 AC_CANONICAL_TARGET
-AM_INIT_AUTOMAKE
+AM_INIT_AUTOMAKE([-Wno-portability])
 
 XVERSION=`echo $VERSION | awk -F. '{printf("0x%02x%02x%02x",$1,$2,$3)}'`
 AC_SUBST(XVERSION)
+VERSION_DEV=1
+AC_SUBST(VERSION_DEV)
 
 # set up MODULE_NAME variable for dynamic construction of directories (resources, etc.)
 MODULE_NAME=smesh
@@ -81,12 +81,13 @@ echo
 
 AC_PROG_MAKE_SET
 AC_PROG_INSTALL
+AC_LOCAL_INSTALL
 dnl
 dnl libtool macro check for CC, LD, NM, LN_S, RANLIB, STRIP + pour les librairies dynamiques !
 
 echo
 echo ---------------------------------------------
-echo Coniguring production
+echo Configuring production
 echo ---------------------------------------------
 echo
 AC_ENABLE_DEBUG(yes)
@@ -107,7 +108,7 @@ dnl Fix up the INSTALL macro if it s a relative path. We want the
 dnl full-path to the binary instead.
 case "$INSTALL" in
    *install-sh*)
-      INSTALL='\${ROOT_BUILDDIR}'/salome_adm/unix/config_files/install-sh
+      INSTALL='\${ROOT_BUILDDIR}'/adm_local/unix/config_files/install-sh
       ;;
 esac
 
@@ -166,7 +167,15 @@ dnl testing MPICH
 dnl ---------------------------------------------
 dnl
 
-CHECK_MPICH
+dnl CHECK_MPICH
+
+echo
+echo ---------------------------------------------
+echo testing MPI
+echo ---------------------------------------------
+echo
+
+CHECK_MPI
 
 echo
 echo ---------------------------------------------
@@ -212,10 +221,6 @@ echo
 
 ENABLE_PTHREADS
 
-SMESH_WITH_GUI=yes
-
-AM_CONDITIONAL(SMESH_ENABLE_GUI, [test "${SMESH_WITH_GUI}" = "yes"])
-
 if test "x${GUI_DISABLE_CORBA}" != "xyes" ; then
     echo
     echo ---------------------------------------------
@@ -255,8 +260,34 @@ dnl CHECK_MICO
 
 fi
 
+echo
+echo ---------------------------------------------
+echo Testing GUI
+echo ---------------------------------------------
+echo
+
+CHECK_GUI_MODULE
+
+gui_ok=no
+if test "${SalomeGUI_need}" != "no" -a "${FullGUI_ok}" = "yes" ; then 
+  gui_ok=yes
+fi
+
+AM_CONDITIONAL(SMESH_ENABLE_GUI, [test "${gui_ok}" = "yes"])
+
+if test "${SalomeGUI_need}" == "yes"; then
+  if test "${FullGUI_ok}" != "yes"; then
+    AC_MSG_WARN(For configure SMESH module necessary full GUI!)
+  fi
+elif test "${SalomeGUI_need}" == "auto"; then
+  if test "${FullGUI_ok}" != "yes"; then
+    AC_MSG_WARN(Full GUI not found. Build will be done without GUI!)
+  fi
+elif test "${SalomeGUI_need}" == "no"; then
+  echo Build without GUI option has been chosen
+fi
 
-if test "${SMESH_WITH_GUI}" = "yes"; then
+if test "${gui_ok}" = "yes"; then
     echo
     echo ---------------------------------------------
     echo testing openGL
@@ -275,33 +306,37 @@ if test "${SMESH_WITH_GUI}" = "yes"; then
 
     echo
     echo ---------------------------------------------
-    echo testing VTK
+    echo testing sip
     echo ---------------------------------------------
     echo
 
-    CHECK_VTK
+    CHECK_SIP
 
     echo
     echo ---------------------------------------------
-    echo Testing GUI
+    echo testing pyqt
     echo ---------------------------------------------
     echo
 
-    CHECK_SALOME_GUI
+    CHECK_PYQT
 
     echo
     echo ---------------------------------------------
-    echo Testing full GUI
+    echo Testing qwt
     echo ---------------------------------------------
     echo
 
-    CHECK_CORBA_IN_GUI
-    if test "x${CORBA_IN_GUI}" != "xyes"; then
-      echo "failed : For configure SMESH module necessary full GUI !"
-      exit
-    fi
+    CHECK_QWT
 fi
 
+echo
+echo ---------------------------------------------
+echo testing VTK
+echo ---------------------------------------------
+echo
+
+CHECK_VTK
+
 echo
 echo ---------------------------------------------
 echo testing HDF5
@@ -310,6 +345,14 @@ echo
 
 CHECK_HDF5
 
+echo
+echo ---------------------------------------------
+echo testing MED3
+echo ---------------------------------------------
+echo
+
+CHECK_MED3
+
 echo
 echo ---------------------------------------------
 echo BOOST Library
@@ -326,25 +369,28 @@ echo
 
 CHECK_CAS
 
-if test "${SMESH_WITH_GUI}" = "yes"; then
-
 echo
 echo ---------------------------------------------
-echo Testing qwt
+echo Testing html generators
 echo ---------------------------------------------
 echo
 
-CHECK_QWT
-
-fi
+CHECK_HTML_GENERATORS
 
 echo
 echo ---------------------------------------------
-echo Testing html generators
+echo testing sphinx
 echo ---------------------------------------------
 echo
+CHECK_SPHINX
 
-CHECK_HTML_GENERATORS
+echo
+echo ---------------------------------------------
+echo testing libxm
+echo ---------------------------------------------
+echo
+dnl Check the libxml that will be required to use the SALOME launcher
+CHECK_LIBXML
 
 echo
 echo ---------------------------------------------
@@ -372,6 +418,31 @@ CHECK_MED
 
 CHECK_PLATFORM
 
+echo
+echo ---------------------------------------------
+echo Testing CGNS library
+echo ---------------------------------------------
+echo
+
+CHECK_CGNS
+
+echo
+echo ---------------------------------------------
+echo Testing PADDER library
+echo ---------------------------------------------
+echo
+
+CHECK_CGAL
+CHECK_PADDER
+
+echo
+echo ---------------------------------------------
+echo Testing TBB library
+echo ---------------------------------------------
+echo
+
+CHECK_TBB
+
 echo
 echo ---------------------------------------------
 echo Summary
@@ -379,12 +450,13 @@ echo ---------------------------------------------
 echo
 
 echo Configure
-if test "${SMESH_WITH_GUI}" = "yes"; then
-variables="cc_ok fortran_ok boost_ok lex_yacc_ok python_ok swig_ok threads_ok OpenGL_ok qt_ok vtk_ok hdf5_ok omniORB_ok occ_ok doxygen_ok graphviz_ok qwt_ok Kernel_ok Geom_ok Med_ok SalomeGUI_ok"
-fi
 
-if test "${SMESH_WITH_GUI}" = "no"; then
-variables="cc_ok fortran_ok boost_ok lex_yacc_ok python_ok swig_ok threads_ok hdf5_ok omniORB_ok occ_ok doxygen_ok graphviz_ok Kernel_ok Geom_ok Med_ok"
+if test "${gui_ok}" = "yes"; then
+  variables="cc_ok fortran_ok boost_ok lex_yacc_ok python_ok swig_ok threads_ok OpenGL_ok qt_ok vtk_ok hdf5_ok cgns_ok tbb_ok omniORB_ok occ_ok doxygen_ok graphviz_ok sphinx_ok qwt_ok Kernel_ok Geom_ok Med_ok gui_ok"
+elif test "${SalomeGUI_need}" != "no"; then
+  variables="cc_ok fortran_ok boost_ok lex_yacc_ok python_ok swig_ok threads_ok vtk_ok hdf5_ok cgns_ok tbb_ok med3_ok omniORB_ok occ_ok doxygen_ok graphviz_ok sphinx_ok Kernel_ok Geom_ok Med_ok gui_ok"
+else
+  variables="cc_ok fortran_ok boost_ok lex_yacc_ok python_ok swig_ok threads_ok vtk_ok hdf5_ok cgns_ok tbb_ok med3_ok omniORB_ok occ_ok doxygen_ok graphviz_ok sphinx_ok Kernel_ok Geom_ok Med_ok"
 fi
 
 for var in $variables
@@ -397,6 +469,16 @@ echo
 echo "Default ORB   : $DEFAULT_ORB"
 echo
 
+echo "Optionnal products (for plugins):"
+optional_vars="cgal_ok padder_ok"
+for var in $optional_vars
+do
+   printf "   %10s : " `echo \$var | sed -e "s,_ok,,"`
+   eval echo \$$var
+done
+
+
+
 dnl We don t need to say when we re entering directories if we re using
 dnl GNU make becuase make does it for us.
 if test "X$GMAKE" = "Xyes"; then
@@ -414,6 +496,9 @@ dnl AM_CONDITIONAL(ENABLE_OCCVIEWER, [test "$DISABLE_OCCVIEWER" = no])
 dnl AM_CONDITIONAL(ENABLE_VTKVIEWER, [test "$DISABLE_VTKVIEWER" = no])
 dnl AM_CONDITIONAL(ENABLE_SALOMEOBJECT, [test "$DISABLE_SALOMEOBJECT" = no])
 
+dnl Build with SMESH cancel compute feature
+AC_DEFINE(WITH_SMESH_CANCEL_COMPUTE)
+
 echo
 echo ---------------------------------------------
 echo generating Makefiles and configure files
@@ -425,49 +510,91 @@ echo
 #  chmod +x ./bin/salome/*; \
 #])
 
+AC_HACK_LIBTOOL
+AC_CONFIG_COMMANDS([hack_libtool],[
+sed -i "s%^CC=\"\(.*\)\"%hack_libtool (){ \n\
+  $(pwd)/hack_libtool \1 \"\$[@]\" \n\
+}\n\
+CC=\"hack_libtool\"%g" libtool
+sed -i "s%\(\s*\)for searchdir in \$newlib_search_path \$lib_search_path \$sys_lib_search_path \$shlib_search_path; do%\1searchdirs=\"\$newlib_search_path \$lib_search_path \$sys_lib_search_path \$shlib_search_path\"\n\1for searchdir in \$searchdirs; do%g" libtool
+sed -i "s%\(\s*\)searchdirs=\"\$newlib_search_path \$lib_search_path \(.*\)\"%\1searchdirs=\"\$newlib_search_path \$lib_search_path\"\n\1sss_beg=\"\"\n\1sss_end=\"\2\"%g" libtool
+sed -i "s%\(\s*\)\(for searchdir in \$searchdirs; do\)%\1for sss in \$searchdirs; do\n\1  if ! test -d \$sss; then continue; fi\n\1  ssss=\$(cd \$sss; pwd)\n\1  if test \"\$ssss\" != \"\" \&\& test -d \$ssss; then\n\1    case \$ssss in\n\1      /usr/lib | /usr/lib64 ) ;;\n\1      * ) sss_beg=\"\$sss_beg \$ssss\" ;;\n\1    esac\n\1  fi\n\1done\n\1searchdirs=\"\$sss_beg \$sss_end\"\n\1\2%g" libtool
+],[])
+
 # This list is initiated using autoscan and must be updated manually
 # when adding a new file <filename>.in to manage. When you execute
 # autoscan, the Makefile list is generated in the output file configure.scan.
 # This could be helpfull to update de configuration.
 AC_OUTPUT([ \
-  ./salome_adm/unix/SALOMEconfig.h \
-  ./adm_local/Makefile \
-  ./adm_local/unix/Makefile \
-  ./adm_local/unix/config_files/Makefile \
-  ./bin/VERSION \
-  ./bin/Makefile \
-  ./SMESH_version.h \
-  ./doc/Makefile \
-  ./doc/salome/Makefile \
-  ./doc/salome/gui/Makefile \
-  ./doc/salome/gui/SMESH/Makefile \
-  ./doc/salome/gui/SMESH/doxyfile \
-  ./doc/salome/gui/SMESH/doxyfile_py \
-  ./doc/salome/tui/Makefile \
-  ./doc/salome/tui/doxyfile \
-  ./src/Makefile \
-  ./src/Controls/Makefile \
-  ./src/Driver/Makefile \
-  ./src/DriverDAT/Makefile \
-  ./src/DriverMED/Makefile \
-  ./src/DriverSTL/Makefile \
-  ./src/DriverUNV/Makefile \
-  ./src/MEFISTO2/Makefile \
-  ./src/OBJECT/Makefile \
-  ./src/SMDS/Makefile \
-  ./src/SMESH/Makefile \
-  ./src/SMESHClient/Makefile \
-  ./src/SMESHDS/Makefile \
-  ./src/SMESHFiltersSelection/Makefile \
-  ./src/SMESHGUI/Makefile \
-  ./src/SMESH_I/Makefile \
-  ./src/SMESH_SWIG/Makefile \
-  ./src/SMESH_SWIG_WITHIHM/Makefile \
-  ./src/StdMeshers/Makefile \
-  ./src/StdMeshersGUI/Makefile \
-  ./src/StdMeshers_I/Makefile \
-  ./resources/Makefile \
-  ./resources/SMESHCatalog.xml \
-  ./idl/Makefile \
+  adm_local/Makefile \
+  adm_local/cmake_files/Makefile \
+  adm_local/unix/Makefile \
+  adm_local/unix/config_files/Makefile \
+  bin/VERSION \
+  bin/Makefile \
+  SMESH_version.h \
+  doc/Makefile \
+  doc/docutils/Makefile \
+  doc/docutils/conf.py \
+  doc/salome/Makefile \
+  doc/salome/gui/Makefile \
+  doc/salome/gui/SMESH/Makefile \
+  doc/salome/gui/SMESH/doxyfile \
+  doc/salome/gui/SMESH/doxyfile_py \
+  doc/salome/gui/SMESH/static/header.html \
+  doc/salome/gui/SMESH/static/header_py.html \
+  doc/salome/tui/Makefile \
+  doc/salome/tui/doxyfile \
+  doc/salome/tui/static/header.html \
+  src/Makefile \
+  src/Controls/Makefile \
+  src/Driver/Makefile \
+  src/DriverDAT/Makefile \
+  src/DriverMED/Makefile \
+  src/DriverSTL/Makefile \
+  src/DriverUNV/Makefile \
+  src/DriverCGNS/Makefile \
+  src/MEFISTO2/Makefile \
+  src/OBJECT/Makefile \
+  src/PluginUtils/Makefile \
+  src/SMDS/Makefile \
+  src/SMESH/Makefile \
+  src/SMESHUtils/Makefile \
+  src/SMESHClient/Makefile \
+  src/SMESHDS/Makefile \
+  src/SMESHFiltersSelection/Makefile \
+  src/SMESHGUI/Makefile \
+  src/SMESH_I/Makefile \
+  src/SMESH_SWIG/Makefile \
+  src/SMESH_SWIG_WITHIHM/Makefile \
+  src/StdMeshers/Makefile \
+  src/StdMeshersGUI/Makefile \
+  src/StdMeshers_I/Makefile \
+  src/SMESH_PY/Makefile \
+  src/Tools/Makefile \
+  src/Tools/MeshCut/Makefile \
+  src/Tools/padder/Makefile \
+  src/Tools/padder/meshjob/Makefile \
+  src/Tools/padder/meshjob/idl/Makefile \
+  src/Tools/padder/meshjob/impl/Makefile \
+  src/Tools/padder/spadderpy/Makefile \
+  src/Tools/padder/spadderpy/padder.cfg \
+  src/Tools/padder/spadderpy/gui/Makefile \
+  src/Tools/padder/spadderpy/plugin/Makefile \
+  src/Tools/padder/spadderpy/plugin/envPlugins.sh \
+  src/Tools/padder/resources/Makefile \
+  src/Tools/padder/resources/appligen/Makefile \
+  src/Tools/padder/resources/appligen/appligen.sh \
+  src/Tools/padder/resources/appligen/config_appli.xml \
+  src/Tools/padder/resources/padderexe/Makefile \
+  src/Tools/padder/resources/padderexe/envPadder.sh \
+  src/Tools/padder/unittests/Makefile \
+  src/Tools/padder/unittests/autotest.sh \
+  src/Tools/padder/doc/Makefile \
+  src/Tools/padder/doc/doxyfile \
+  resources/Makefile \
+  resources/SMESHCatalog.xml \
+  resources/SalomeApp.xml \
+  idl/Makefile \
   Makefile
 ])
index 1902d9d21933c19777904ac59742905c3fd400d5..6d2dfb20181319a15b9c05ef0ca3ae9bd73086ed 100644 (file)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # -* Makefile *- 
 # Author : Patrick GOLDBRONN (CEA)
 # Date : 30/11/2001
@@ -26,7 +24,8 @@
 # $Header$
 # source path
 #
-SUBDIRS = salome
+SUBDIRS = salome docutils
+#SUBDIRS = salome
 
 usr_docs:
        (cd salome && $(MAKE) $(AM_MAKEFLAGS) usr_docs)
diff --git a/doc/docutils/Makefile.am b/doc/docutils/Makefile.am
new file mode 100644 (file)
index 0000000..1775115
--- /dev/null
@@ -0,0 +1,97 @@
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# Copyright (C) 2003-2007  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.com
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+pydocdir = $(docdir)/tui/SMESH/docutils
+
+RSTFILES = \
+       index.rst \
+       overview.rst \
+       docapi.rst
+
+EXTRA_DIST += $(RSTFILES)
+
+SPHINXOPTS      =
+SOURCEDIR       = $(srcdir)
+SPHINXBUILD     = sphinx-build
+PAPEROPT_a4     = -D latex_paper_size=a4
+ALLSPHINXOPTS   = -d doctrees $(PAPEROPT_a4) $(SPHINXOPTS) $(SOURCEDIR)
+
+if SMESH_ENABLE_GUI
+SPHINX_PYTHONPATH = $(prefix)/lib/python$(PYTHON_VERSION)/site-packages/salome:$(prefix)/lib64/python$(PYTHON_VERSION)/site-packages/salome:$(GUI_ROOT_DIR)/lib/salome:$(GUI_ROOT_DIR)/lib/python$(PYTHON_VERSION)/site-packages/salome:$(GUI_ROOT_DIR)/lib64/python$(PYTHON_VERSION)/site-packages/salome:$(KERNEL_ROOT_DIR)/bin/salome:$(KERNEL_ROOT_DIR)/lib/python$(PYTHON_VERSION)/site-packages/salome:$(KERNEL_ROOT_DIR)/lib64/python$(PYTHON_VERSION)/site-packages/salome:$(OMNIORB_ROOT)/lib/python$(PYTHON_VERSION)/site-packages:$(OMNIORB_ROOT)/lib64/python$(PYTHON_VERSION)/site-packages
+else !SMESH_ENABLE_GUI
+SPHINX_PYTHONPATH = $(prefix)/lib/python$(PYTHON_VERSION)/site-packages/salome:$(prefix)/lib64/python$(PYTHON_VERSION)/site-packages/salome:$(KERNEL_ROOT_DIR)/bin/salome:$(KERNEL_ROOT_DIR)/lib/python$(PYTHON_VERSION)/site-packages/salome:$(KERNEL_ROOT_DIR)/lib64/python$(PYTHON_VERSION)/site-packages/salome:$(OMNIORB_ROOT)/lib/python$(PYTHON_VERSION)/site-packages:$(OMNIORB_ROOT)/lib64/python$(PYTHON_VERSION)/site-packages
+endif
+
+if SMESH_ENABLE_GUI
+SPHINX_LD_LIBRARY_PATH = $(GUI_ROOT_DIR)/lib/salome:$(KERNEL_ROOT_DIR)/lib/salome:$(OMNIORB_ROOT)/lib
+else !SMESH_ENABLE_GUI
+SPHINX_LD_LIBRARY_PATH = $(KERNEL_ROOT_DIR)/lib/salome:$(OMNIORB_ROOT)/lib
+endif
+
+
+.PHONY: latex
+
+if SPHINX_IS_OK
+
+html/index.html:$(RSTFILES)
+       mkdir -p html doctrees
+       PYTHONPATH=$(SPHINX_PYTHONPATH):${PYTHONPATH} \
+       LD_LIBRARY_PATH=$(SPHINX_LD_LIBRARY_PATH):${LD_LIBRARY_PATH} \
+       $(SPHINXBUILD) -c $(top_builddir)/doc/docutils -W -b html $(ALLSPHINXOPTS) html
+       @echo
+       @echo "Build finished. The HTML pages are in html."
+
+else
+
+html/index.html:
+       @echo "Documentation for Python package not built. Sphinx was not present at configure time."
+
+endif
+
+latex:
+       mkdir -p latex doctrees
+       PYTHONPATH=$(SPHINX_PYTHONPATH):${PYTHONPATH} \
+       LD_LIBRARY_PATH=$(SPHINX_LD_LIBRARY_PATH):${LD_LIBRARY_PATH} \
+       $(SPHINXBUILD) -c $(top_builddir)/doc/docutils -W -b latex $(ALLSPHINXOPTS) latex
+       @echo
+       @echo "Build finished; the LaTeX files are in latex."
+       @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
+             "run these through (pdf)latex."
+
+install-data-local: html/index.html
+       test -z $(pydocdir) || mkdir -p $(DESTDIR)$(pydocdir)
+       if test -d "html"; then b=; else b="$(srcdir)/"; fi; \
+       cp -rf $$b"html"/* $(pydocdir) ; \
+       if test -f $$b"latex"/smeshpy.pdf; then cp -f $$b"latex"/smeshpy.pdf $(pydocdir) ; fi;
+
+uninstall-local:
+       -test -d $(pydocdir) && chmod -R +w $(pydocdir) && rm -rf $(pydocdir)/*
+
+clean-local:
+       -rm -rf html latex doctrees
+       if test -d "html"; then rm -rf html ; fi
+
+dist-hook:
+       -test -d html && cp -Rp html $(distdir)
diff --git a/doc/docutils/conf.py.in b/doc/docutils/conf.py.in
new file mode 100644 (file)
index 0000000..1aea4dc
--- /dev/null
@@ -0,0 +1,200 @@
+# -*- coding: iso-8859-1 -*-
+#
+# yacs documentation build configuration file, created by
+# sphinx-quickstart on Fri Aug 29 09:57:25 2008.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# The contents of this file are pickled, so don't put values in the namespace
+# that aren't pickleable (module imports are okay, they're removed automatically).
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If your extensions are in another directory, add it here. If the directory
+# is relative to the documentation root, use os.path.abspath to make it
+# absolute, like shown here.
+#sys.path.append(os.path.abspath('.'))
+
+# General configuration
+# ---------------------
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.autodoc']
+
+# Uncomment the following line to build the links with Python documentation
+# (you might need to set http_proxy environment variable for this to work)
+#extensions += ['sphinx.ext.intersphinx']
+
+# Intersphinx mapping to add links to modules and objects in the Python
+# standard library documentation
+intersphinx_mapping = {'http://docs.python.org': None}
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+source_encoding = 'utf-8'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = 'SMESH python packages'
+copyright = '2010 EDF R&D'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '@VERSION@'
+# The full version, including alpha/beta/rc tags.
+release = '@VERSION@'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+language = 'en'
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of documents that shouldn't be included in the build.
+#unused_docs = []
+
+# List of directories, relative to source directory, that shouldn't be searched
+# for source files.
+exclude_trees = ['.build','ref','images','CVS','.svn']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+
+# Options for HTML output
+# -----------------------
+
+# The theme to use for HTML and HTML Help pages.  Major themes that come with
+# Sphinx are currently 'default' and 'sphinxdoc'.
+html_theme = 'default'
+#html_theme = 'nature'
+#html_theme = 'agogo'
+#html_theme = 'sphinxdoc'
+#html_theme = 'omadoc'
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = ['themes']
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+#html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+html_use_modindex = False
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, the reST sources are included in the HTML build as _sources/<name>.
+html_copy_source = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = ''
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'smeshpydoc'
+
+
+# Options for LaTeX output
+# ------------------------
+
+# The paper size ('letter' or 'a4').
+latex_paper_size = 'a4'
+
+# The font size ('10pt', '11pt' or '12pt').
+latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, document class [howto/manual]).
+latex_documents = [
+  ('index', 'smeshpy.tex', 'Documentation of the SMESH python packages', 'EDF R\&D', 'manual')
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+latex_logo = '@srcdir@/../salome/tui/images/head.png'
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = True
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+latex_use_modindex = False
diff --git a/doc/docutils/docapi.rst b/doc/docutils/docapi.rst
new file mode 100644 (file)
index 0000000..b39c124
--- /dev/null
@@ -0,0 +1,17 @@
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ Documentation of the programming interface (API)
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+This section describes the python packages and modules of the
+``salome.smesh`` python package. The main part is generated from the
+code documentation included in source python files.
+
+:mod:`salome.smesh` -- Package containing the SMESH python utilities
+====================================================================
+
+:mod:`smeshstudytools` -- Tools to access SMESH objects in the study
+--------------------------------------------------------------------
+
+.. automodule:: salome.smesh.smeshstudytools
+   :members:
diff --git a/doc/docutils/index.rst b/doc/docutils/index.rst
new file mode 100644 (file)
index 0000000..4863e82
--- /dev/null
@@ -0,0 +1,10 @@
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ Documentation of the SMESH python package
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+.. toctree::
+   :maxdepth: 3
+
+   overview.rst
+   docapi.rst
diff --git a/doc/docutils/overview.rst b/doc/docutils/overview.rst
new file mode 100644 (file)
index 0000000..ce82cc8
--- /dev/null
@@ -0,0 +1,24 @@
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+General presentation of the SMESH python package
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+The SMESH python package contains (today) helper functions to
+manipulate mesh elements and interact with these elements.
+
+Note that these functions either encapsulate the python programming
+interface of SMESH core (the CORBA or SWIG interface for example) or
+extend existing utilities as the ``smesh.py`` module.
+
+The functions are distributed in the python package
+``salome.smesh``.
+
+The specification of the programming interface of this package is
+detailled in the part :doc:`Documentation of the programming interface
+(API)</docapi>` of this documentation.
+
+.. note::
+   The main package ``salome`` contains other sub-packages that are
+   distributed with the other SALOME modules. For example, the KERNEL
+   module provides the python package ``salome.kernel`` and GEOM the
+   package ``salome.geom``.
index 5a92861e53f2f5283ae565dbba7668f682714577..8bf9f392d938f95a5f3a183a5526b993547d42d4 100644 (file)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # -* Makefile *- 
 # Author : Patrick GOLDBRONN (CEA)
 # Date : 30/11/2001
index 0e41ee5ff42a7bb1fa557a8ba0eca1bee931e84b..9582cd97e7765ffcaa7ec9f87752bdad21b61571 100644 (file)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  File   : Makefile.in
 #  Author : Vasily Rusyaev (Open Cascade NN)
 #  Modified by : Alexander BORODIN (OCN) - autotools usage
index a93b57ccb0eaed84b96225b5f61b1c279c7b6111..cc3ddb25155e64ff5e38d01cbc7aa4b6c3a13495 100755 (executable)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  File   : Makefile.in
 #  Author : Vasily Rusyaev (Open Cascade NN)
 #  Modified by : Alexander BORODIN (OCN) - autotools usage
 #
 include $(top_srcdir)/adm_local/unix/make_common_starter.am
 
-EXTRA_DIST += images input static
+EXTRA_DIST += images input static/footer.html static/doxygen.css
+
+guidocdir = $(docdir)/gui/SMESH
+guidoc_DATA = images/head.png
+
 
 usr_docs: doxyfile_py doxyfile 
-       echo "===========================================" ;            \
-       echo "Generating Python interface documentation";               \
-       echo "===========================================" ;            \
-       $(DOXYGEN) doxyfile_py ;                                        \
-       echo "===========================================" ;            \
-       echo "Replacing smeshDC by smesh" ;                             \
-       echo "===========================================" ;            \
-       files=`find smeshpy_doc -type f` ;                              \
-       for filen in $${files} ; do                                     \
-         sed -e "s/\<smeshDC\>/smesh/g" -e "s/smesh\.smesh/smesh/g"    \
-             -e "s/smesh::smesh/smesh/g" $${filen} > $${filen}_ ;      \
-         mv -f $${filen}_ $${filen} ;                                  \
-       done ;                                                          \
-       echo "===========================================" ;            \
-       echo "Generating GUI documentation" ;                           \
-       echo "===========================================" ;            \
-       $(DOXYGEN) doxyfile ;
+       echo "===========================================" ;                    \
+       echo "Replacing smeshDC by smesh" ;                                     \
+       echo "===========================================" ;                    \
+       awk '/^class Mesh:/ { mesh_found=1 } // { if (mesh_found) {print $$0; next} } /^ +(def|#)/ { match( $$0, /^ +/); print substr( $$0, 1+RLENGTH ); next } /^class smeshDC/ { next } //' \
+         $(top_srcdir)/src/SMESH_SWIG/smeshDC.py > ./smesh.py ;                \
+       echo "===========================================" ;                    \
+       echo "Generating Python interface documentation";                       \
+       echo "===========================================" ;                    \
+       $(DOXYGEN) doxyfile_py ;                                                \
+       echo "===========================================" ;                    \
+       echo "Generating GUI documentation" ;                                   \
+       echo "===========================================" ;                    \
+       $(DOXYGEN) doxyfile ;                                                   \
+       rm -f ./smesh.py
 
 docs: usr_docs
 
 clean-local:
-       @for filen in `find . -maxdepth 1` ; do                         \
+       @for filen in `find . -maxdepth 1` ; do                 \
          case $${filen} in                                     \
            ./Makefile | ./doxyfile | ./doxyfile_py ) ;;        \
-           . | .. ) ;;                                         \
+           . | .. | ./static ) ;;                              \
            *) echo "Removing $${filen}" ; rm -rf $${filen} ;;  \
          esac ;                                                \
        done ;
 
 install-data-local: usr_docs
        $(INSTALL) -d $(DESTDIR)$(docdir)/gui/SMESH
-       @for filen in `find . -maxdepth 1` ; do                                                         \
+       @for filen in `find . -maxdepth 1` ; do                                                 \
          case $${filen} in                                                                     \
            ./Makefile | ./doxyfile | ./doxyfile_py ) ;;                                        \
            ./doxyfile.bak | ./doxyfile_py.bak ) ;;                                             \
-           . | .. ) ;;                                                                         \
+           . | .. | ./static ) ;;                                                              \
            *) echo "Installing $${filen}" ; cp -rp $${filen} $(DESTDIR)$(docdir)/gui/SMESH ;;  \
          esac ;                                                                                \
-       done ;
+       done ;                                                                                  \
+       cp -rp $(srcdir)/images/head.png $(DESTDIR)$(docdir)/gui/SMESH/smeshpy_doc ;
 
 uninstall-local:
        rm -rf $(DESTDIR)$(docdir)/gui/SMESH
index b084396baeda1383b6fc2676be0042f8157beca6..bceb23d558bfcce3546ecb40f5791aaadf5786f7 100755 (executable)
@@ -1,28 +1,29 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #---------------------------------------------------------------------------
 # Project related configuration options
 #---------------------------------------------------------------------------
-PROJECT_NAME      = "Mesh Module Reference Manual v.@VERSION@"
+PROJECT_NAME      = "SALOME Mesh User's Guide"
 OUTPUT_DIRECTORY  = .
 CREATE_SUBDIRS   = NO
 OUTPUT_LANGUAGE   = English
@@ -37,10 +38,10 @@ WARNINGS          = YES
 #---------------------------------------------------------------------------
 #Input related options
 #---------------------------------------------------------------------------
-INPUT             = @srcdir@/input               
+INPUT             = @srcdir@/input @top_srcdir@/src/Tools/padder/doc/input
 FILE_PATTERNS     = *.doc
 EXCLUDE           = 
-IMAGE_PATH        = @srcdir@/images
+IMAGE_PATH        = @srcdir@/images @top_srcdir@/src/Tools/padder/doc/images
 EXAMPLE_PATH      = @top_srcdir@/src/SMESH_SWIG
 
 #---------------------------------------------------------------------------
@@ -48,18 +49,25 @@ EXAMPLE_PATH      = @top_srcdir@/src/SMESH_SWIG
 #---------------------------------------------------------------------------
 GENERATE_HTML     = YES
 HTML_OUTPUT       = .
-HTML_HEADER       = @srcdir@/static/header.html
+HTML_HEADER       = @builddir@/static/header.html
 HTML_FOOTER       = @srcdir@/static/footer.html
-#HTML_STYLESHEET  = @srcdir@/static/doxygen.css
+HTML_STYLESHEET   = @srcdir@/static/doxygen.css
 TOC_EXPAND        = YES
 DISABLE_INDEX     = NO
 GENERATE_TREEVIEW = YES
 TREEVIEW_WIDTH    = 300
 
+#---------------------------------------------------------------------------
+#SORT related options
+#---------------------------------------------------------------------------
+SORT_GROUP_NAMES = NO
+
+
 #---------------------------------------------------------------------------
 #LaTeX related option
 #---------------------------------------------------------------------------
 GENERATE_LATEX    = NO
+EXTRA_PACKAGES    = amsmath
 
 #---------------------------------------------------------------------------
 #RTF related options
@@ -69,4 +77,6 @@ GENERATE_RTF      = NO
 #---------------------------------------------------------------------------
 #External reference options
 #---------------------------------------------------------------------------
-TAGFILES          = smeshpy_doc.tag=smeshpy_doc
+TAGFILES          = smeshpy_doc.tag=../SMESH/smeshpy_doc #rnv: 07.04.2011 Workaround for the doxygen 1.7.3:
+                                                         #because it wrongly defines location of the html files for search.                                                  
+SEARCHENGINE      = YES
index c35d4aaa7ba2fc15b304184d8337488d6d5129a4..19e21b96ec198ad2784ad4a63dad853128e23138 100755 (executable)
@@ -1,28 +1,29 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #---------------------------------------------------------------------------
 # Project related configuration options
 #---------------------------------------------------------------------------
-PROJECT_NAME           = "Mesh Module Reference Manual v.@VERSION@"
+PROJECT_NAME           = "SALOME Mesh User's Guide"
 OUTPUT_DIRECTORY       = .
 CREATE_SUBDIRS        = NO
 OUTPUT_LANGUAGE        = English
@@ -98,8 +99,8 @@ EXAMPLE_RECURSIVE      = NO
 #---------------------------------------------------------------------------
 #Input related options
 #---------------------------------------------------------------------------
-INPUT             = @top_srcdir@/src/SMESH_SWIG
-FILE_PATTERNS     = smeshDC.py
+INPUT             = smesh.py @top_srcdir@/src/SMESH_SWIG/StdMeshersDC.py
+FILE_PATTERNS     = 
 IMAGE_PATH        = @srcdir@/images
 RECURSIVE         = NO
 EXAMPLE_PATH      = @top_srcdir@/src/SMESH_SWIG
@@ -109,11 +110,11 @@ EXAMPLE_PATH      = @top_srcdir@/src/SMESH_SWIG
 #---------------------------------------------------------------------------
 GENERATE_HTML     = YES
 HTML_OUTPUT       = smeshpy_doc
-HTML_HEADER       = @srcdir@/static/header.html
+HTML_HEADER       = @builddir@/static/header_py.html
 HTML_FOOTER       = @srcdir@/static/footer.html
-#HTML_STYLESHEET  = @srcdir@/static/doxygen.css
+HTML_STYLESHEET   = @srcdir@/static/doxygen.css
 TOC_EXPAND        = YES
-DISABLE_INDEX     = YES
+DISABLE_INDEX     = NO
 GENERATE_TREEVIEW = NO
 
 #---------------------------------------------------------------------------
@@ -143,6 +144,7 @@ CALL_GRAPH             = NO
 GRAPHICAL_HIERARCHY    = NO
 DIRECTORY_GRAPH        = NO
 DOT_IMAGE_FORMAT       = jpg
+DOT_FONTNAME           = Arial
 DOT_PATH               = 
 DOTFILE_DIRS           = 
 MAX_DOT_GRAPH_WIDTH    = 1024
@@ -157,3 +159,4 @@ DOT_CLEANUP            = YES
 #External reference options
 #---------------------------------------------------------------------------
 GENERATE_TAGFILE  = smeshpy_doc.tag
+SEARCHENGINE           = YES
diff --git a/doc/salome/gui/SMESH/images/2d_from_3d_dlg.png b/doc/salome/gui/SMESH/images/2d_from_3d_dlg.png
new file mode 100644 (file)
index 0000000..e0c8ca5
Binary files /dev/null and b/doc/salome/gui/SMESH/images/2d_from_3d_dlg.png differ
diff --git a/doc/salome/gui/SMESH/images/2d_from_3d_ico.png b/doc/salome/gui/SMESH/images/2d_from_3d_ico.png
new file mode 100644 (file)
index 0000000..b0842d3
Binary files /dev/null and b/doc/salome/gui/SMESH/images/2d_from_3d_ico.png differ
diff --git a/doc/salome/gui/SMESH/images/2d_from_3d_menu.png b/doc/salome/gui/SMESH/images/2d_from_3d_menu.png
new file mode 100644 (file)
index 0000000..acb7b34
Binary files /dev/null and b/doc/salome/gui/SMESH/images/2d_from_3d_menu.png differ
index d34a5e24cf55507697450e297255e8c99a9c6698..aa43beb5fba8e483c67be55bbec8e90627d6fcd5 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/a-arithmetic1d.png and b/doc/salome/gui/SMESH/images/a-arithmetic1d.png differ
index 70e2afd26dd6ed299365193b2073c28946ed0695..c8ca5ac772651c15214eb8396d322187201641dc 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/a-averagelength.png and b/doc/salome/gui/SMESH/images/a-averagelength.png differ
index bfac4cea53acd9b713925ea20e3e34e0edf45f19..9d1249c68694fb6d24d18e92d9246522b8648574 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/a-clipping2.png and b/doc/salome/gui/SMESH/images/a-clipping2.png differ
index d23ee825da4c9dee936278d595c11ce0bf42a288..ee2b6baa4caad954d7152eddcc330c7016684ecd 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/a-creategroup.png and b/doc/salome/gui/SMESH/images/a-creategroup.png differ
index 26403226c21097c979d38116cc5b062d5d08db2c..6c6bb615d376dc7cb8d47d9d626f38bdb7a3e767 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/a-createpolyhedralvolume.png and b/doc/salome/gui/SMESH/images/a-createpolyhedralvolume.png differ
index 27668505c45da70a23f6f807219bac4ec45b0acd..0cd778fc43dea4d6f45b809c0fa0a550aa319919 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/a-nbsegments1.png and b/doc/salome/gui/SMESH/images/a-nbsegments1.png differ
index 8d4f277d98363844aa5a7d7e8f2f211694ab3753..2a7c9fcaaf93bd47eb44db2cce667775015f5769 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/a-nbsegments2.png and b/doc/salome/gui/SMESH/images/a-nbsegments2.png differ
index 947567d7f8d9172ab6aa8bc73ead4e13fb112f4b..ba29d91dffc017315911b93648a0da8c61e58dd7 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/a-startendlength.png and b/doc/salome/gui/SMESH/images/a-startendlength.png differ
index 370ef3026cf14bdd5fec1ef229855ad278526182..df10f7a987538b68cb0bb3ce4b35d87089283173 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/a-transparency.png and b/doc/salome/gui/SMESH/images/a-transparency.png differ
diff --git a/doc/salome/gui/SMESH/images/add0delement.png b/doc/salome/gui/SMESH/images/add0delement.png
new file mode 100644 (file)
index 0000000..ed27488
Binary files /dev/null and b/doc/salome/gui/SMESH/images/add0delement.png differ
diff --git a/doc/salome/gui/SMESH/images/add_0delement.png b/doc/salome/gui/SMESH/images/add_0delement.png
new file mode 100644 (file)
index 0000000..fa1075b
Binary files /dev/null and b/doc/salome/gui/SMESH/images/add_0delement.png differ
diff --git a/doc/salome/gui/SMESH/images/add_ball.png b/doc/salome/gui/SMESH/images/add_ball.png
new file mode 100644 (file)
index 0000000..1fe4f64
Binary files /dev/null and b/doc/salome/gui/SMESH/images/add_ball.png differ
diff --git a/doc/salome/gui/SMESH/images/addball.png b/doc/salome/gui/SMESH/images/addball.png
new file mode 100644 (file)
index 0000000..c38c9fa
Binary files /dev/null and b/doc/salome/gui/SMESH/images/addball.png differ
index f142dffb26b2e0f6427c8e9e5bac557615728ec3..7a5a030632559926267d32e1f302f4b342d13957 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/addedge.png and b/doc/salome/gui/SMESH/images/addedge.png differ
index 78ea3b50f98248cf9b49a63ef8e785c7b0bd432e..0cf7fe819a0143afd9f65ff03720d0474a76cf75 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/addhexahedron.png and b/doc/salome/gui/SMESH/images/addhexahedron.png differ
diff --git a/doc/salome/gui/SMESH/images/addinfo_group.png b/doc/salome/gui/SMESH/images/addinfo_group.png
new file mode 100644 (file)
index 0000000..9f26c9a
Binary files /dev/null and b/doc/salome/gui/SMESH/images/addinfo_group.png differ
diff --git a/doc/salome/gui/SMESH/images/addinfo_mesh.png b/doc/salome/gui/SMESH/images/addinfo_mesh.png
new file mode 100644 (file)
index 0000000..91fbc38
Binary files /dev/null and b/doc/salome/gui/SMESH/images/addinfo_mesh.png differ
diff --git a/doc/salome/gui/SMESH/images/addinfo_submesh.png b/doc/salome/gui/SMESH/images/addinfo_submesh.png
new file mode 100644 (file)
index 0000000..4811c99
Binary files /dev/null and b/doc/salome/gui/SMESH/images/addinfo_submesh.png differ
index 1f5375b9ae2763c4f6ad0a59235e64223cffdc85..1fd9a9f8a5ec91d375d86951ef6f66327950fb3f 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/addnode.png and b/doc/salome/gui/SMESH/images/addnode.png differ
index 4abab33589ea61a0b79c81146f571f4348eca47f..804f806df5011f49b736e619c55711d05c9d987e 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/addnode_notebook.png and b/doc/salome/gui/SMESH/images/addnode_notebook.png differ
index 5d02dd70dab6ebae6c7d4e9716053f9dffc55591..200999d8da6a349486ef881cff40fc2e9552a102 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/addpolygon.png and b/doc/salome/gui/SMESH/images/addpolygon.png differ
index 3e5c87c42f7507497995eacfd02c3f9cbb604d93..bd2462273021fe124257018aef84aa29ed571bbe 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/addquadrangle.png and b/doc/salome/gui/SMESH/images/addquadrangle.png differ
index 37dc29659045fc2bec3c69edc034517a05a48938..0a6a74084f715a2da8b51b5770ccfc29cbbed5a0 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/addtetrahedron.png and b/doc/salome/gui/SMESH/images/addtetrahedron.png differ
index 52a644e51c44c62c2e859324cfbacf433dffa0a5..67682c8cf6e3000319d0d48daef1c468ae360c40 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/addtriangle.png and b/doc/salome/gui/SMESH/images/addtriangle.png differ
index 2dc9f8f4822514c9b38701078985a9972186f256..ddd305f587eea02b9848081d71b84d483cc3c9f4 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/advanced_mesh_infos.png and b/doc/salome/gui/SMESH/images/advanced_mesh_infos.png differ
index ae8e0d081751435e7c48f3e17d03128a730b6b6f..46ee94dae56e995bb06e2f26bd9265eb3778b3af 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/aqt.png and b/doc/salome/gui/SMESH/images/aqt.png differ
diff --git a/doc/salome/gui/SMESH/images/bare_border_faces_smpl.png b/doc/salome/gui/SMESH/images/bare_border_faces_smpl.png
new file mode 100644 (file)
index 0000000..6b7ead8
Binary files /dev/null and b/doc/salome/gui/SMESH/images/bare_border_faces_smpl.png differ
diff --git a/doc/salome/gui/SMESH/images/bare_border_volumes_smpl.png b/doc/salome/gui/SMESH/images/bare_border_volumes_smpl.png
new file mode 100644 (file)
index 0000000..a1e799a
Binary files /dev/null and b/doc/salome/gui/SMESH/images/bare_border_volumes_smpl.png differ
diff --git a/doc/salome/gui/SMESH/images/blsurf_parameters.png b/doc/salome/gui/SMESH/images/blsurf_parameters.png
deleted file mode 100644 (file)
index 22d038a..0000000
Binary files a/doc/salome/gui/SMESH/images/blsurf_parameters.png and /dev/null differ
diff --git a/doc/salome/gui/SMESH/images/blsurf_parameters_advanced.png b/doc/salome/gui/SMESH/images/blsurf_parameters_advanced.png
deleted file mode 100644 (file)
index 0f2c07d..0000000
Binary files a/doc/salome/gui/SMESH/images/blsurf_parameters_advanced.png and /dev/null differ
diff --git a/doc/salome/gui/SMESH/images/bnd_box.png b/doc/salome/gui/SMESH/images/bnd_box.png
new file mode 100644 (file)
index 0000000..6761a76
Binary files /dev/null and b/doc/salome/gui/SMESH/images/bnd_box.png differ
diff --git a/doc/salome/gui/SMESH/images/bnd_box_preview.png b/doc/salome/gui/SMESH/images/bnd_box_preview.png
new file mode 100644 (file)
index 0000000..902101c
Binary files /dev/null and b/doc/salome/gui/SMESH/images/bnd_box_preview.png differ
diff --git a/doc/salome/gui/SMESH/images/cartesian3D_hyp.png b/doc/salome/gui/SMESH/images/cartesian3D_hyp.png
new file mode 100644 (file)
index 0000000..b8373ed
Binary files /dev/null and b/doc/salome/gui/SMESH/images/cartesian3D_hyp.png differ
diff --git a/doc/salome/gui/SMESH/images/cartesian3D_sphere.png b/doc/salome/gui/SMESH/images/cartesian3D_sphere.png
new file mode 100644 (file)
index 0000000..45bffda
Binary files /dev/null and b/doc/salome/gui/SMESH/images/cartesian3D_sphere.png differ
diff --git a/doc/salome/gui/SMESH/images/colors_size.png b/doc/salome/gui/SMESH/images/colors_size.png
new file mode 100755 (executable)
index 0000000..15060ed
Binary files /dev/null and b/doc/salome/gui/SMESH/images/colors_size.png differ
diff --git a/doc/salome/gui/SMESH/images/controls_popup.png b/doc/salome/gui/SMESH/images/controls_popup.png
new file mode 100755 (executable)
index 0000000..c32f9ea
Binary files /dev/null and b/doc/salome/gui/SMESH/images/controls_popup.png differ
index 4a71cac99697cf6c4437a115396bf008b6b69906..2ebbedc3a08524912321224a89967f2501b3859f 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/convert.png and b/doc/salome/gui/SMESH/images/convert.png differ
diff --git a/doc/salome/gui/SMESH/images/copy_mesh_dlg.png b/doc/salome/gui/SMESH/images/copy_mesh_dlg.png
new file mode 100644 (file)
index 0000000..db9c929
Binary files /dev/null and b/doc/salome/gui/SMESH/images/copy_mesh_dlg.png differ
diff --git a/doc/salome/gui/SMESH/images/copy_mesh_icon.png b/doc/salome/gui/SMESH/images/copy_mesh_icon.png
new file mode 100644 (file)
index 0000000..263479f
Binary files /dev/null and b/doc/salome/gui/SMESH/images/copy_mesh_icon.png differ
index 17d54dec32a0aec35c15704e5cc5b9bf8475419f..f20d4a724a4309b6fd280df05509d2da36e25df2 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/create_groups_from_geometry.png and b/doc/salome/gui/SMESH/images/create_groups_from_geometry.png differ
index 2fb825cc865d820a61def6629daac7a63d338869..ec24a4feda84816946bebe69c6b4f02441fa5c7f 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/creategroup.png and b/doc/salome/gui/SMESH/images/creategroup.png differ
diff --git a/doc/salome/gui/SMESH/images/creategroup_on_filter.png b/doc/salome/gui/SMESH/images/creategroup_on_filter.png
new file mode 100644 (file)
index 0000000..0a494c0
Binary files /dev/null and b/doc/salome/gui/SMESH/images/creategroup_on_filter.png differ
diff --git a/doc/salome/gui/SMESH/images/custom_point_marker.png b/doc/salome/gui/SMESH/images/custom_point_marker.png
new file mode 100755 (executable)
index 0000000..a46e33e
Binary files /dev/null and b/doc/salome/gui/SMESH/images/custom_point_marker.png differ
index 1fa2c42635471fabd424ff507c3283580ff3abbf..c9cc22cab9dc31c410d31e42d77a6e256511261b 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/dialog.png and b/doc/salome/gui/SMESH/images/dialog.png differ
index 7dea248c62f0f07df95e5cc39a1f4186b7f5fd68..83c086b438f0f500646e431a10f0fb4898fe0842 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/distributionwithanalyticdensity.png and b/doc/salome/gui/SMESH/images/distributionwithanalyticdensity.png differ
index 3bd40bc458fa3f23233ee829ee152edadb3e1a7b..60847cde5ffe148afd4d31f4ac30c4125a6d3aa6 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/distributionwithtabledensity.png and b/doc/salome/gui/SMESH/images/distributionwithtabledensity.png differ
diff --git a/doc/salome/gui/SMESH/images/double_faces.png b/doc/salome/gui/SMESH/images/double_faces.png
new file mode 100644 (file)
index 0000000..47bed1f
Binary files /dev/null and b/doc/salome/gui/SMESH/images/double_faces.png differ
diff --git a/doc/salome/gui/SMESH/images/double_nodes.png b/doc/salome/gui/SMESH/images/double_nodes.png
new file mode 100644 (file)
index 0000000..27a209b
Binary files /dev/null and b/doc/salome/gui/SMESH/images/double_nodes.png differ
diff --git a/doc/salome/gui/SMESH/images/duplicate01.png b/doc/salome/gui/SMESH/images/duplicate01.png
new file mode 100644 (file)
index 0000000..80a4a2b
Binary files /dev/null and b/doc/salome/gui/SMESH/images/duplicate01.png differ
diff --git a/doc/salome/gui/SMESH/images/duplicate02.png b/doc/salome/gui/SMESH/images/duplicate02.png
new file mode 100644 (file)
index 0000000..0e50141
Binary files /dev/null and b/doc/salome/gui/SMESH/images/duplicate02.png differ
diff --git a/doc/salome/gui/SMESH/images/duplicate_nodes.png b/doc/salome/gui/SMESH/images/duplicate_nodes.png
new file mode 100644 (file)
index 0000000..61ff32b
Binary files /dev/null and b/doc/salome/gui/SMESH/images/duplicate_nodes.png differ
index ac9e8a2c1e2c176d421a581109e1a6bd41f9b90e..fb102242e2924ca975ee51b365be98b424c56174 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/editgroup.png and b/doc/salome/gui/SMESH/images/editgroup.png differ
diff --git a/doc/salome/gui/SMESH/images/elem_info.png b/doc/salome/gui/SMESH/images/elem_info.png
new file mode 100644 (file)
index 0000000..9937d6d
Binary files /dev/null and b/doc/salome/gui/SMESH/images/elem_info.png differ
index 3aae250c8c7472a4e458aa41b29546c34d1ecdd9..3cd439b76df0733f11f26e61b02a9d9a971e318d 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/eleminfo1.png and b/doc/salome/gui/SMESH/images/eleminfo1.png differ
index 9ead335b823ad79ad2ec0fb962d99fb765c7b13f..54fe12df8603d679a5549f3e4e7f1b5f1fb434c5 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/eleminfo2.png and b/doc/salome/gui/SMESH/images/eleminfo2.png differ
diff --git a/doc/salome/gui/SMESH/images/extr_along_wire_after.png b/doc/salome/gui/SMESH/images/extr_along_wire_after.png
new file mode 100644 (file)
index 0000000..eb39bdd
Binary files /dev/null and b/doc/salome/gui/SMESH/images/extr_along_wire_after.png differ
diff --git a/doc/salome/gui/SMESH/images/extr_along_wire_before.png b/doc/salome/gui/SMESH/images/extr_along_wire_before.png
new file mode 100644 (file)
index 0000000..2f30cee
Binary files /dev/null and b/doc/salome/gui/SMESH/images/extr_along_wire_before.png differ
index 9f34a0febf186ffd09abba1cd3faa7f9d89488b4..540bce24a2cb7a31e0f5e1491eca0a46f3009fcc 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/extrusion1.png and b/doc/salome/gui/SMESH/images/extrusion1.png differ
diff --git a/doc/salome/gui/SMESH/images/extrusion2.png b/doc/salome/gui/SMESH/images/extrusion2.png
deleted file mode 100755 (executable)
index 527b67a..0000000
Binary files a/doc/salome/gui/SMESH/images/extrusion2.png and /dev/null differ
index 76a60bd345e80fe5a9d903e0ce070b27c3e766d9..95a26ca9006e56be549e600d6452d929cc0dfa5c 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/extrusionalongaline1.png and b/doc/salome/gui/SMESH/images/extrusionalongaline1.png differ
index fb04562508b66ae0b3a8ae645907a6d12c4600bd..8c16623966f6e6251bfb19976d5fab41984b63d1 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/extrusionalongaline2.png and b/doc/salome/gui/SMESH/images/extrusionalongaline2.png differ
diff --git a/doc/salome/gui/SMESH/images/findelement1.png b/doc/salome/gui/SMESH/images/findelement1.png
new file mode 100644 (file)
index 0000000..1c11a03
Binary files /dev/null and b/doc/salome/gui/SMESH/images/findelement1.png differ
diff --git a/doc/salome/gui/SMESH/images/findelement2.png b/doc/salome/gui/SMESH/images/findelement2.png
new file mode 100644 (file)
index 0000000..c9898b5
Binary files /dev/null and b/doc/salome/gui/SMESH/images/findelement2.png differ
diff --git a/doc/salome/gui/SMESH/images/findelement3.png b/doc/salome/gui/SMESH/images/findelement3.png
new file mode 100644 (file)
index 0000000..26cfff2
Binary files /dev/null and b/doc/salome/gui/SMESH/images/findelement3.png differ
index 2f8d2f518e7cf3e8bfed0e11f3f662406c22353e..b3468a15abf00b302b1a23e4377f8702e6cd5f60 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/formula1.png and b/doc/salome/gui/SMESH/images/formula1.png differ
index ff189aa8eeb556306ebf54651101baf33c8afdda..dd45fbfb1549dd5e6862c3deac4414d53c9b393f 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/formula2.png and b/doc/salome/gui/SMESH/images/formula2.png differ
index 170f25558f668a433b61840bc4561b20b1c9433c..3a5d31f6f3123076298f41089a8c2c41e24cf46f 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/formula4.png and b/doc/salome/gui/SMESH/images/formula4.png differ
diff --git a/doc/salome/gui/SMESH/images/formula5.png b/doc/salome/gui/SMESH/images/formula5.png
new file mode 100644 (file)
index 0000000..8cd035f
Binary files /dev/null and b/doc/salome/gui/SMESH/images/formula5.png differ
index c1d23c1d371f8724735af9db3606eb570cc4de08..ea043eac3191588efd35ccd46d92e5f15af540b8 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/free_nodes.png and b/doc/salome/gui/SMESH/images/free_nodes.png differ
diff --git a/doc/salome/gui/SMESH/images/ghs3d_parameters_advanced.png b/doc/salome/gui/SMESH/images/ghs3d_parameters_advanced.png
deleted file mode 100644 (file)
index 4f36203..0000000
Binary files a/doc/salome/gui/SMESH/images/ghs3d_parameters_advanced.png and /dev/null differ
diff --git a/doc/salome/gui/SMESH/images/ghs3d_parameters_basic.png b/doc/salome/gui/SMESH/images/ghs3d_parameters_basic.png
deleted file mode 100644 (file)
index 0cce50b..0000000
Binary files a/doc/salome/gui/SMESH/images/ghs3d_parameters_basic.png and /dev/null differ
diff --git a/doc/salome/gui/SMESH/images/head.png b/doc/salome/gui/SMESH/images/head.png
new file mode 100755 (executable)
index 0000000..307d9ef
Binary files /dev/null and b/doc/salome/gui/SMESH/images/head.png differ
diff --git a/doc/salome/gui/SMESH/images/hyp_source_edges.png b/doc/salome/gui/SMESH/images/hyp_source_edges.png
new file mode 100644 (file)
index 0000000..2305e17
Binary files /dev/null and b/doc/salome/gui/SMESH/images/hyp_source_edges.png differ
diff --git a/doc/salome/gui/SMESH/images/hyp_source_faces.png b/doc/salome/gui/SMESH/images/hyp_source_faces.png
new file mode 100644 (file)
index 0000000..fe9e6c6
Binary files /dev/null and b/doc/salome/gui/SMESH/images/hyp_source_faces.png differ
diff --git a/doc/salome/gui/SMESH/images/hypo_fixedpnt_dlg.png b/doc/salome/gui/SMESH/images/hypo_fixedpnt_dlg.png
new file mode 100755 (executable)
index 0000000..74276bd
Binary files /dev/null and b/doc/salome/gui/SMESH/images/hypo_fixedpnt_dlg.png differ
diff --git a/doc/salome/gui/SMESH/images/hypo_quad_params_1.png b/doc/salome/gui/SMESH/images/hypo_quad_params_1.png
new file mode 100755 (executable)
index 0000000..44233b2
Binary files /dev/null and b/doc/salome/gui/SMESH/images/hypo_quad_params_1.png differ
diff --git a/doc/salome/gui/SMESH/images/hypo_quad_params_2.png b/doc/salome/gui/SMESH/images/hypo_quad_params_2.png
new file mode 100644 (file)
index 0000000..9f6fa25
Binary files /dev/null and b/doc/salome/gui/SMESH/images/hypo_quad_params_2.png differ
diff --git a/doc/salome/gui/SMESH/images/hypo_quad_params_dialog.png b/doc/salome/gui/SMESH/images/hypo_quad_params_dialog.png
new file mode 100644 (file)
index 0000000..3cd442a
Binary files /dev/null and b/doc/salome/gui/SMESH/images/hypo_quad_params_dialog.png differ
diff --git a/doc/salome/gui/SMESH/images/hypo_quad_params_res.png b/doc/salome/gui/SMESH/images/hypo_quad_params_res.png
new file mode 100644 (file)
index 0000000..8aae276
Binary files /dev/null and b/doc/salome/gui/SMESH/images/hypo_quad_params_res.png differ
diff --git a/doc/salome/gui/SMESH/images/hypo_quad_params_res_2.png b/doc/salome/gui/SMESH/images/hypo_quad_params_res_2.png
new file mode 100644 (file)
index 0000000..6dc37e2
Binary files /dev/null and b/doc/salome/gui/SMESH/images/hypo_quad_params_res_2.png differ
diff --git a/doc/salome/gui/SMESH/images/hypo_radquad_dlg.png b/doc/salome/gui/SMESH/images/hypo_radquad_dlg.png
new file mode 100755 (executable)
index 0000000..e658a68
Binary files /dev/null and b/doc/salome/gui/SMESH/images/hypo_radquad_dlg.png differ
diff --git a/doc/salome/gui/SMESH/images/hypo_sets.png b/doc/salome/gui/SMESH/images/hypo_sets.png
new file mode 100644 (file)
index 0000000..2a9859d
Binary files /dev/null and b/doc/salome/gui/SMESH/images/hypo_sets.png differ
index 2fb825cc865d820a61def6629daac7a63d338869..a952f5fccfd7ba55a04905a062a33ccd3cc9912e 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/image146.png and b/doc/salome/gui/SMESH/images/image146.png differ
index ef8ef087d955956428be099ee88db0310ceab10b..79e264f628f6dc8cd13fe9d4881db4eb8983657e 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/image152.png and b/doc/salome/gui/SMESH/images/image152.png differ
diff --git a/doc/salome/gui/SMESH/images/image42.png b/doc/salome/gui/SMESH/images/image42.png
new file mode 100755 (executable)
index 0000000..d0120fa
Binary files /dev/null and b/doc/salome/gui/SMESH/images/image42.png differ
diff --git a/doc/salome/gui/SMESH/images/image43.png b/doc/salome/gui/SMESH/images/image43.png
new file mode 100755 (executable)
index 0000000..7b6b895
Binary files /dev/null and b/doc/salome/gui/SMESH/images/image43.png differ
index 74926d24450a3e5b4ca4e9466d88538874a38df9..6e5b3176bc67ae89e0b55398dff8f90a58084dae 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/image49.png and b/doc/salome/gui/SMESH/images/image49.png differ
index 6d164167fb70656b96bdf17c574eb4ed3765009c..0efc736950fdfe0da08551e01812327ecde6a5f0 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/image79.jpg and b/doc/salome/gui/SMESH/images/image79.jpg differ
index 4959ed82548939a522238bb5b9c57adb0d1dfb6d..2672e99f3241466518910e294744154285d7cc9b 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/image99.gif and b/doc/salome/gui/SMESH/images/image99.gif differ
diff --git a/doc/salome/gui/SMESH/images/image_octa12.png b/doc/salome/gui/SMESH/images/image_octa12.png
new file mode 100644 (file)
index 0000000..1a5ed8c
Binary files /dev/null and b/doc/salome/gui/SMESH/images/image_octa12.png differ
diff --git a/doc/salome/gui/SMESH/images/max_element_length_2d.png b/doc/salome/gui/SMESH/images/max_element_length_2d.png
new file mode 100755 (executable)
index 0000000..012d552
Binary files /dev/null and b/doc/salome/gui/SMESH/images/max_element_length_2d.png differ
diff --git a/doc/salome/gui/SMESH/images/max_element_length_3d.png b/doc/salome/gui/SMESH/images/max_element_length_3d.png
new file mode 100755 (executable)
index 0000000..fdf1b76
Binary files /dev/null and b/doc/salome/gui/SMESH/images/max_element_length_3d.png differ
index c5e160884b73adf5f09b59d80c3e6b4b16eb7fba..eaa5a9323dacc7abaa6eeb652288355bcffe0161 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/mergeelems.png and b/doc/salome/gui/SMESH/images/mergeelems.png differ
diff --git a/doc/salome/gui/SMESH/images/mergeelems_auto.png b/doc/salome/gui/SMESH/images/mergeelems_auto.png
new file mode 100644 (file)
index 0000000..f8ef74f
Binary files /dev/null and b/doc/salome/gui/SMESH/images/mergeelems_auto.png differ
index d14620101081839b2a35097703b160574acd66c3..54cb3d17adcd6a78de4edc0cf0eb66aa0ef38886 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/mergenodes.png and b/doc/salome/gui/SMESH/images/mergenodes.png differ
diff --git a/doc/salome/gui/SMESH/images/mergenodes_auto.png b/doc/salome/gui/SMESH/images/mergenodes_auto.png
new file mode 100644 (file)
index 0000000..71511d2
Binary files /dev/null and b/doc/salome/gui/SMESH/images/mergenodes_auto.png differ
diff --git a/doc/salome/gui/SMESH/images/mesh_evaluation_succeed.png b/doc/salome/gui/SMESH/images/mesh_evaluation_succeed.png
new file mode 100755 (executable)
index 0000000..b9aeb52
Binary files /dev/null and b/doc/salome/gui/SMESH/images/mesh_evaluation_succeed.png differ
diff --git a/doc/salome/gui/SMESH/images/mesh_fixedpnt.png b/doc/salome/gui/SMESH/images/mesh_fixedpnt.png
new file mode 100755 (executable)
index 0000000..5d044ab
Binary files /dev/null and b/doc/salome/gui/SMESH/images/mesh_fixedpnt.png differ
diff --git a/doc/salome/gui/SMESH/images/mesh_order_123.png b/doc/salome/gui/SMESH/images/mesh_order_123.png
new file mode 100644 (file)
index 0000000..952f207
Binary files /dev/null and b/doc/salome/gui/SMESH/images/mesh_order_123.png differ
diff --git a/doc/salome/gui/SMESH/images/mesh_order_123_res.png b/doc/salome/gui/SMESH/images/mesh_order_123_res.png
new file mode 100644 (file)
index 0000000..02208a0
Binary files /dev/null and b/doc/salome/gui/SMESH/images/mesh_order_123_res.png differ
diff --git a/doc/salome/gui/SMESH/images/mesh_order_213.png b/doc/salome/gui/SMESH/images/mesh_order_213.png
new file mode 100644 (file)
index 0000000..959ca38
Binary files /dev/null and b/doc/salome/gui/SMESH/images/mesh_order_213.png differ
diff --git a/doc/salome/gui/SMESH/images/mesh_order_213_res.png b/doc/salome/gui/SMESH/images/mesh_order_213_res.png
new file mode 100644 (file)
index 0000000..8706fb4
Binary files /dev/null and b/doc/salome/gui/SMESH/images/mesh_order_213_res.png differ
diff --git a/doc/salome/gui/SMESH/images/mesh_order_321.png b/doc/salome/gui/SMESH/images/mesh_order_321.png
new file mode 100644 (file)
index 0000000..7ad61fa
Binary files /dev/null and b/doc/salome/gui/SMESH/images/mesh_order_321.png differ
diff --git a/doc/salome/gui/SMESH/images/mesh_order_321_res.png b/doc/salome/gui/SMESH/images/mesh_order_321_res.png
new file mode 100644 (file)
index 0000000..7a5f017
Binary files /dev/null and b/doc/salome/gui/SMESH/images/mesh_order_321_res.png differ
diff --git a/doc/salome/gui/SMESH/images/mesh_order_no_concurrent.png b/doc/salome/gui/SMESH/images/mesh_order_no_concurrent.png
new file mode 100644 (file)
index 0000000..6df59a1
Binary files /dev/null and b/doc/salome/gui/SMESH/images/mesh_order_no_concurrent.png differ
diff --git a/doc/salome/gui/SMESH/images/mesh_order_preview.png b/doc/salome/gui/SMESH/images/mesh_order_preview.png
new file mode 100644 (file)
index 0000000..f4b5e3b
Binary files /dev/null and b/doc/salome/gui/SMESH/images/mesh_order_preview.png differ
diff --git a/doc/salome/gui/SMESH/images/mesh_radquad_01.png b/doc/salome/gui/SMESH/images/mesh_radquad_01.png
new file mode 100755 (executable)
index 0000000..dfd8eb5
Binary files /dev/null and b/doc/salome/gui/SMESH/images/mesh_radquad_01.png differ
diff --git a/doc/salome/gui/SMESH/images/mesh_radquad_02.png b/doc/salome/gui/SMESH/images/mesh_radquad_02.png
new file mode 100755 (executable)
index 0000000..63432eb
Binary files /dev/null and b/doc/salome/gui/SMESH/images/mesh_radquad_02.png differ
index 781a59a6418416325c333e6e7da5122e24c7c1ef..61f3a433aea52615f49c56dbc3a78c5106f1d11b 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/meshcomputationfail.png and b/doc/salome/gui/SMESH/images/meshcomputationfail.png differ
diff --git a/doc/salome/gui/SMESH/images/meshcut_plugin.png b/doc/salome/gui/SMESH/images/meshcut_plugin.png
new file mode 100644 (file)
index 0000000..305e920
Binary files /dev/null and b/doc/salome/gui/SMESH/images/meshcut_plugin.png differ
index 9a5c62e245c15881a3195183d3c967a2fc143714..1c426783e94d591b1e8a11f91afa51d28bf623fc 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/meshtopass.png and b/doc/salome/gui/SMESH/images/meshtopass.png differ
diff --git a/doc/salome/gui/SMESH/images/min_distance.png b/doc/salome/gui/SMESH/images/min_distance.png
new file mode 100644 (file)
index 0000000..765522e
Binary files /dev/null and b/doc/salome/gui/SMESH/images/min_distance.png differ
diff --git a/doc/salome/gui/SMESH/images/min_distance_preview.png b/doc/salome/gui/SMESH/images/min_distance_preview.png
new file mode 100644 (file)
index 0000000..c5373d9
Binary files /dev/null and b/doc/salome/gui/SMESH/images/min_distance_preview.png differ
index 2bae388500a0ba1c9b6df9fde542e613f828bd7b..295b3a38fe475350a4df38fd710340e7729e6b85 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/moving_nodes1.png and b/doc/salome/gui/SMESH/images/moving_nodes1.png differ
index b65e57ae97af9cf397aa8493ce51039f5b581ab8..a89e8b36b3bb65119e2dd23cf4db07b52347ad38 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/moving_nodes2.png and b/doc/salome/gui/SMESH/images/moving_nodes2.png differ
diff --git a/doc/salome/gui/SMESH/images/netgen2d.png b/doc/salome/gui/SMESH/images/netgen2d.png
deleted file mode 100644 (file)
index 29e09ef..0000000
Binary files a/doc/salome/gui/SMESH/images/netgen2d.png and /dev/null differ
diff --git a/doc/salome/gui/SMESH/images/netgen3d_simple.png b/doc/salome/gui/SMESH/images/netgen3d_simple.png
deleted file mode 100644 (file)
index 959ec02..0000000
Binary files a/doc/salome/gui/SMESH/images/netgen3d_simple.png and /dev/null differ
diff --git a/doc/salome/gui/SMESH/images/over_constrained_faces.png b/doc/salome/gui/SMESH/images/over_constrained_faces.png
new file mode 100644 (file)
index 0000000..9d584e8
Binary files /dev/null and b/doc/salome/gui/SMESH/images/over_constrained_faces.png differ
diff --git a/doc/salome/gui/SMESH/images/over_constrained_volumes.png b/doc/salome/gui/SMESH/images/over_constrained_volumes.png
new file mode 100644 (file)
index 0000000..7611443
Binary files /dev/null and b/doc/salome/gui/SMESH/images/over_constrained_volumes.png differ
diff --git a/doc/salome/gui/SMESH/images/pattern2d.png b/doc/salome/gui/SMESH/images/pattern2d.png
new file mode 100644 (file)
index 0000000..ff488eb
Binary files /dev/null and b/doc/salome/gui/SMESH/images/pattern2d.png differ
diff --git a/doc/salome/gui/SMESH/images/point_marker_widget1.png b/doc/salome/gui/SMESH/images/point_marker_widget1.png
new file mode 100755 (executable)
index 0000000..13b8e6d
Binary files /dev/null and b/doc/salome/gui/SMESH/images/point_marker_widget1.png differ
diff --git a/doc/salome/gui/SMESH/images/point_marker_widget2.png b/doc/salome/gui/SMESH/images/point_marker_widget2.png
new file mode 100755 (executable)
index 0000000..dbb81b4
Binary files /dev/null and b/doc/salome/gui/SMESH/images/point_marker_widget2.png differ
diff --git a/doc/salome/gui/SMESH/images/pref21.png b/doc/salome/gui/SMESH/images/pref21.png
new file mode 100755 (executable)
index 0000000..d30add4
Binary files /dev/null and b/doc/salome/gui/SMESH/images/pref21.png differ
diff --git a/doc/salome/gui/SMESH/images/pref22.png b/doc/salome/gui/SMESH/images/pref22.png
new file mode 100755 (executable)
index 0000000..b56c4e5
Binary files /dev/null and b/doc/salome/gui/SMESH/images/pref22.png differ
diff --git a/doc/salome/gui/SMESH/images/pref23.png b/doc/salome/gui/SMESH/images/pref23.png
new file mode 100755 (executable)
index 0000000..07858d7
Binary files /dev/null and b/doc/salome/gui/SMESH/images/pref23.png differ
diff --git a/doc/salome/gui/SMESH/images/pref24.png b/doc/salome/gui/SMESH/images/pref24.png
new file mode 100755 (executable)
index 0000000..f1cdcf8
Binary files /dev/null and b/doc/salome/gui/SMESH/images/pref24.png differ
index 5af29afb897b1b50fb8c0392188e8bc3c972aeca..6115327636091f1596defda79b64dc813290bcab 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/projection_1d.png and b/doc/salome/gui/SMESH/images/projection_1d.png differ
index d7380ec1dcf83f298e15999fb6d6a35589b22e0e..e13730994315fc2a3a97603a725cc0467cbfd51c 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/projection_2d.png and b/doc/salome/gui/SMESH/images/projection_2d.png differ
index 5f6b907b849a3764d06b43a0ed922fceaeb23b3d..03eedc3ab94b8ea6784619444fbc287394383cab 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/projection_3d.png and b/doc/salome/gui/SMESH/images/projection_3d.png differ
diff --git a/doc/salome/gui/SMESH/images/remove_nodes_icon.png b/doc/salome/gui/SMESH/images/remove_nodes_icon.png
new file mode 100644 (file)
index 0000000..0818837
Binary files /dev/null and b/doc/salome/gui/SMESH/images/remove_nodes_icon.png differ
diff --git a/doc/salome/gui/SMESH/images/remove_orphan_nodes_icon.png b/doc/salome/gui/SMESH/images/remove_orphan_nodes_icon.png
new file mode 100644 (file)
index 0000000..16df2e5
Binary files /dev/null and b/doc/salome/gui/SMESH/images/remove_orphan_nodes_icon.png differ
diff --git a/doc/salome/gui/SMESH/images/removeorphannodes.png b/doc/salome/gui/SMESH/images/removeorphannodes.png
new file mode 100644 (file)
index 0000000..fdf8395
Binary files /dev/null and b/doc/salome/gui/SMESH/images/removeorphannodes.png differ
diff --git a/doc/salome/gui/SMESH/images/reorient_2d_face.png b/doc/salome/gui/SMESH/images/reorient_2d_face.png
new file mode 100644 (file)
index 0000000..b143ac4
Binary files /dev/null and b/doc/salome/gui/SMESH/images/reorient_2d_face.png differ
diff --git a/doc/salome/gui/SMESH/images/reorient_2d_point.png b/doc/salome/gui/SMESH/images/reorient_2d_point.png
new file mode 100644 (file)
index 0000000..844ac09
Binary files /dev/null and b/doc/salome/gui/SMESH/images/reorient_2d_point.png differ
diff --git a/doc/salome/gui/SMESH/images/reorient_faces_face.png b/doc/salome/gui/SMESH/images/reorient_faces_face.png
new file mode 100644 (file)
index 0000000..23c241f
Binary files /dev/null and b/doc/salome/gui/SMESH/images/reorient_faces_face.png differ
diff --git a/doc/salome/gui/SMESH/images/revolution2.png b/doc/salome/gui/SMESH/images/revolution2.png
deleted file mode 100755 (executable)
index 7d5777c..0000000
Binary files a/doc/salome/gui/SMESH/images/revolution2.png and /dev/null differ
index ae6df4b9f9621d774a36229a8fb6468cf18d600f..c8f11e66be16b71fe228eb1b2aea60ce668c4e9e 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/rotation.png and b/doc/salome/gui/SMESH/images/rotation.png differ
diff --git a/doc/salome/gui/SMESH/images/scalar_bar_dlg.png b/doc/salome/gui/SMESH/images/scalar_bar_dlg.png
new file mode 100755 (executable)
index 0000000..59ca530
Binary files /dev/null and b/doc/salome/gui/SMESH/images/scalar_bar_dlg.png differ
diff --git a/doc/salome/gui/SMESH/images/scale01.png b/doc/salome/gui/SMESH/images/scale01.png
new file mode 100644 (file)
index 0000000..685bbc1
Binary files /dev/null and b/doc/salome/gui/SMESH/images/scale01.png differ
diff --git a/doc/salome/gui/SMESH/images/scale02.png b/doc/salome/gui/SMESH/images/scale02.png
new file mode 100644 (file)
index 0000000..982f468
Binary files /dev/null and b/doc/salome/gui/SMESH/images/scale02.png differ
diff --git a/doc/salome/gui/SMESH/images/scale03.png b/doc/salome/gui/SMESH/images/scale03.png
new file mode 100644 (file)
index 0000000..891ae8d
Binary files /dev/null and b/doc/salome/gui/SMESH/images/scale03.png differ
diff --git a/doc/salome/gui/SMESH/images/scale04.png b/doc/salome/gui/SMESH/images/scale04.png
new file mode 100644 (file)
index 0000000..a042834
Binary files /dev/null and b/doc/salome/gui/SMESH/images/scale04.png differ
diff --git a/doc/salome/gui/SMESH/images/scale06.png b/doc/salome/gui/SMESH/images/scale06.png
new file mode 100644 (file)
index 0000000..2bd8219
Binary files /dev/null and b/doc/salome/gui/SMESH/images/scale06.png differ
diff --git a/doc/salome/gui/SMESH/images/scale07.png b/doc/salome/gui/SMESH/images/scale07.png
new file mode 100644 (file)
index 0000000..8ee0923
Binary files /dev/null and b/doc/salome/gui/SMESH/images/scale07.png differ
diff --git a/doc/salome/gui/SMESH/images/scale09.png b/doc/salome/gui/SMESH/images/scale09.png
new file mode 100644 (file)
index 0000000..2816bac
Binary files /dev/null and b/doc/salome/gui/SMESH/images/scale09.png differ
diff --git a/doc/salome/gui/SMESH/images/scaleinit01.png b/doc/salome/gui/SMESH/images/scaleinit01.png
new file mode 100644 (file)
index 0000000..97990a8
Binary files /dev/null and b/doc/salome/gui/SMESH/images/scaleinit01.png differ
diff --git a/doc/salome/gui/SMESH/images/scaleinit02.png b/doc/salome/gui/SMESH/images/scaleinit02.png
new file mode 100644 (file)
index 0000000..008d2e3
Binary files /dev/null and b/doc/salome/gui/SMESH/images/scaleinit02.png differ
diff --git a/doc/salome/gui/SMESH/images/scaleres03.png b/doc/salome/gui/SMESH/images/scaleres03.png
new file mode 100644 (file)
index 0000000..99b65d7
Binary files /dev/null and b/doc/salome/gui/SMESH/images/scaleres03.png differ
diff --git a/doc/salome/gui/SMESH/images/scaleres04.png b/doc/salome/gui/SMESH/images/scaleres04.png
new file mode 100644 (file)
index 0000000..0880989
Binary files /dev/null and b/doc/salome/gui/SMESH/images/scaleres04.png differ
diff --git a/doc/salome/gui/SMESH/images/scaleres06.png b/doc/salome/gui/SMESH/images/scaleres06.png
new file mode 100644 (file)
index 0000000..059fa97
Binary files /dev/null and b/doc/salome/gui/SMESH/images/scaleres06.png differ
diff --git a/doc/salome/gui/SMESH/images/scaleres07.png b/doc/salome/gui/SMESH/images/scaleres07.png
new file mode 100644 (file)
index 0000000..b75f83c
Binary files /dev/null and b/doc/salome/gui/SMESH/images/scaleres07.png differ
diff --git a/doc/salome/gui/SMESH/images/scaleres09.png b/doc/salome/gui/SMESH/images/scaleres09.png
new file mode 100644 (file)
index 0000000..4708be5
Binary files /dev/null and b/doc/salome/gui/SMESH/images/scaleres09.png differ
diff --git a/doc/salome/gui/SMESH/images/split_into_tetra.png b/doc/salome/gui/SMESH/images/split_into_tetra.png
new file mode 100644 (file)
index 0000000..fce071e
Binary files /dev/null and b/doc/salome/gui/SMESH/images/split_into_tetra.png differ
diff --git a/doc/salome/gui/SMESH/images/split_into_tetra_icon.png b/doc/salome/gui/SMESH/images/split_into_tetra_icon.png
new file mode 100644 (file)
index 0000000..b113c30
Binary files /dev/null and b/doc/salome/gui/SMESH/images/split_into_tetra_icon.png differ
diff --git a/doc/salome/gui/SMESH/images/std_point_marker.png b/doc/salome/gui/SMESH/images/std_point_marker.png
new file mode 100755 (executable)
index 0000000..2a62693
Binary files /dev/null and b/doc/salome/gui/SMESH/images/std_point_marker.png differ
index b37fb0ab1a833a69a8da8db557e09b7950350f42..879a41d9d9b16cabbb85553d943f1ca50d6ace8a 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/symmetry1.png and b/doc/salome/gui/SMESH/images/symmetry1.png differ
index 9304d6734ec5079bfdbecfd509089c72e83f4dd3..83d23382070448231072356d67824bd288cd50e4 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/symmetry2.png and b/doc/salome/gui/SMESH/images/symmetry2.png differ
index f15c5fcaa542d6247610aac9536f4d3a9bdfe6b3..865465993f2e87504ea8cd81e0f332cb426e18ba 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/symmetry3.png and b/doc/salome/gui/SMESH/images/symmetry3.png differ
index b7e811645b68e56f618ddc3f2fd204e1c95bac04..790e365cf9bc948b688cd03520842310094d24b3 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/translation1.png and b/doc/salome/gui/SMESH/images/translation1.png differ
index c0bbad0a59c30efa56650acdc2fed21ed714f904..5df23cc40a3f372021460b8f6d52172a0d577d92 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/translation2.png and b/doc/salome/gui/SMESH/images/translation2.png differ
diff --git a/doc/salome/gui/SMESH/images/use_existing_face_sample_mesh.png b/doc/salome/gui/SMESH/images/use_existing_face_sample_mesh.png
new file mode 100644 (file)
index 0000000..2110540
Binary files /dev/null and b/doc/salome/gui/SMESH/images/use_existing_face_sample_mesh.png differ
diff --git a/doc/salome/gui/SMESH/images/using_notebook_smesh.png b/doc/salome/gui/SMESH/images/using_notebook_smesh.png
new file mode 100644 (file)
index 0000000..0946bff
Binary files /dev/null and b/doc/salome/gui/SMESH/images/using_notebook_smesh.png differ
diff --git a/doc/salome/gui/SMESH/images/viscous_layers_hyp.png b/doc/salome/gui/SMESH/images/viscous_layers_hyp.png
new file mode 100644 (file)
index 0000000..843ff5d
Binary files /dev/null and b/doc/salome/gui/SMESH/images/viscous_layers_hyp.png differ
diff --git a/doc/salome/gui/SMESH/images/viscous_layers_mesh.png b/doc/salome/gui/SMESH/images/viscous_layers_mesh.png
new file mode 100644 (file)
index 0000000..9373a5e
Binary files /dev/null and b/doc/salome/gui/SMESH/images/viscous_layers_mesh.png differ
index 7053546924bfff0525b9728b2dd3ffe029b4a75a..367a0d0b5abe489daf5be5ae49ab5bcd9c5da4cc 100644 (file)
@@ -5,12 +5,13 @@
 <br>
 <ul>
 <li>\ref arithmetic_1d_anchor "Arithmetic 1D"</li>
-<li>\ref average_length_anchor "Average Length"</li>
+<li>\ref average_length_anchor "Local Length"</li>
 <li>\ref max_length_anchor "Max Size"</li>
 <li>\ref deflection_1d_anchor "Deflection 1D"</li>
 <li>\ref number_of_segments_anchor "Number of segments"</li>
 <li>\ref start_and_end_length_anchor "Start and end length"</li>
 <li>\ref automatic_length_anchor "Automatic Length"</li>
+<li>\ref fixed_points_1d_anchor "Fixed points 1D"</li>
 </ul>
 
 <br>
 length that changes in arithmetic progression (Lk = Lk-1 + d)
 beginning from a given starting length and up to a given end length.
 
+The direction of the splitting is defined by the orientation of the underlying geometrical edge. 
+<b>"Reverse Edges"</b> list box allows to specify the edges for which the splitting should be made 
+in the direction opposing to their orientation. This list box is enabled only if the geometry object 
+is selected for the meshing. In this case the user can select edges to be reversed either directly 
+picking them in the 3D viewer or by selecting the edges or groups of edges in the Object browser.
+
 \image html a-arithmetic1d.png
 
 \image html b-ithmetic1d.png "Arithmetic 1D hypothesis - the size of mesh elements gradually increases"
@@ -50,9 +57,9 @@ locations and 1D mesh elements are constructed on segments.
 
 <br>
 \anchor average_length_anchor
-<h2>Average Length hypothesis</h2>
+<h2>Local Length hypothesis</h2>
 
-<b>Average Length</b> hypothesis can be applied for meshing of edges
+<b>Local Length</b> hypothesis can be applied for meshing of edges
 composing your geometrical object. Definition of this hypothesis
 consists of setting the \b length of segments, which will split these
 edges, and the \b precision of rounding. The points on the edges
@@ -72,10 +79,10 @@ integer. Default value is 1e-07.
 
 \image html a-averagelength.png
 
-\image html b-erage_length.png "Average length hypothesis - all 1D mesh elements are roughly equal"
+\image html b-erage_length.png "Local Length hypothesis - all 1D mesh elements are roughly equal"
 
 <b>See Also</b> a sample TUI Script of a 
-\ref tui_average_length "Defining Average Length" hypothesis
+\ref tui_average_length "Defining Local Length" hypothesis
 operation.
 
 <br>\anchor max_length_anchor
@@ -106,6 +113,12 @@ edges generated by these segments will represent nodes of your
 mesh. Later these nodes will be used for meshing of the faces abutting
 to these edges.
 
+The direction of the splitting is defined by the orientation of the underlying geometrical edge. 
+<b>"Reverse Edges"</b> list box allows to specify the edges for which the splitting should be made 
+in the direction opposing to their orientation. This list box is enabled only if the geometry object 
+is selected for the meshing. In this case the user can select edges to be reversed either directly 
+picking them in the 3D viewer or by selecting the edges or groups of edges in the Object browser.
+
 \image html image46.gif
 
 You can set the type of distribution for this hypothesis in the
@@ -144,11 +157,17 @@ operation.
 
 <b>Start and End Length</b> hypothesis allows to divide a geometrical edge
 into segments so that the first and the last segments have a specified
-length. The length medium segments changes with automatically chosen
+length. The length of medium segments changes with automatically chosen
 geometric progression. Then mesh nodes are
 constructed at segment ends location and 1D mesh elements are
 constructed on them.
 
+The direction of the splitting is defined by the orientation of the underlying geometrical edge. 
+<b>"Reverse Edges"</b> list box allows to specify the edges for which the splitting should be made 
+in the direction opposing to their orientation. This list box is enabled only if the geometry object 
+is selected for the meshing. In this case the user can select edges to be reversed either directly 
+picking them in the 3D viewer or by selecting the edges or groups of edges in the Object browser.
+
 \image html a-startendlength.png
 
 \image html b-art_end_length.png "The lengths of the first and the last segment are strictly defined"
@@ -175,4 +194,32 @@ minimum and maximum value of this parameter.
 \image html image147.gif "Example of a very rough mesh. Automatic Length works for 0."
 
 \image html image148.gif "Example of a very fine mesh. Automatic Length works for 1."
+
+<br>
+\anchor fixed_points_1d_anchor
+<h2>Fixed points 1D hypothesis</h2>
+
+<b>Fixed points 1D</b> hypothesis allows splitting edges through a
+set of points parameterized on the edge (from 1 to 0) and a number of segments for each
+interval limited by the points.
+
+\image html hypo_fixedpnt_dlg.png 
+
+It is possible to check in <b>Same Nb. Segments for all intervals</b> 
+option and to define one value for all intervals.
+
+The splitting direction is defined by the orientation of the
+underlying geometrical edge. <b>"Reverse Edges"</b> list box allows to
+specify the edges for which the splitting should be made in the
+direction opposite to their orientation. This list box is enabled only
+if the geometrical object is selected for meshing. In this case it is
+possible to select the edges to be reversed either directly picking them in
+the 3D viewer or selecting the edges or groups of edges in the
+Object browser.
+
+\image html mesh_fixedpnt.png "Example of a submesh on the edge built using Fixed points 1D hypothesis"
+
+<b>See Also</b> a sample TUI Script of a 
+\ref tui_fixed_points "Defining Fixed Points" hypothesis operation.
+
 */
index 6d89e53d57465e4e41653c0e15f696ea7a6a9ea7..d72e4d50459e39613ca3ac0bca641acd810f497a 100644 (file)
@@ -6,8 +6,7 @@
 <ul>
 <li>\ref max_element_area_anchor "Max Element Area"</li>
 <li>\ref length_from_edges_anchor "Length from Edges"</li>
-<li>\ref quadrangle_preference_anchor "Quadrangle Preference"</li>
-<li>\ref triangle_preference_anchor "Triangle Preference"</li>
+<li>\ref hypo_quad_params_anchor "Quadrangle parameters"</li>
 </ul>
 
 <br>
@@ -22,6 +21,8 @@ which will compose the mesh of these 2D faces.
 
 \image html a-maxelarea.png
 
+\n
+
 \image html max_el_area.png "In this example, Max. element area is very small compared to the 1D hypothesis"
 
 <b>See Also</b> a sample TUI Script of a 
@@ -39,24 +40,63 @@ length calculated as an average edge length for a given wire.
 \ref tui_length_from_edges "Length from Edges" hypothesis operation.
 
 <br>
-\anchor quadrangle_preference_anchor
-<h2>Quadrangle Preference</h2>
+\anchor hypo_quad_params_anchor
+<h2>Quadrangle parameters</h2>
 
-This algorithm can be used only together with Quadrangle (Mapping)
-algorithm. It allows to build quadrangular meshes even if the number
-of nodes at the opposite edges of a meshed face is not equal,
-otherwise this mesh will contain some triangular elements.
-<br>
-This hypothesis has one restriction on its work: the total quantity of
-segments on all four sides of the face must be even (divisible by 2).
+\image html hypo_quad_params_dialog.png "Quadrangle parameters creation/edition dialog"
 
-<br>
-\anchor triangle_preference_anchor
-<h2>Triangle Preference</h2>
+<b>Quadrangle parameters</b> is a hypothesis for Quadrangle (Mapping).
+
+<b>Base vertex</b> parameter allows using Quadrangle (Mapping)
+algorithm for meshing of triangular faces. In this case it is
+necessary to select the vertex, which will be used as the fourth edge
+(degenerated).
+
+\image html hypo_quad_params_1.png "A face built from 3 edges"
+
+\image html hypo_quad_params_res.png "The resulting mesh"
+
+This parameter can be also used to mesh a segment of a circular face.
+Please, consider that there is a limitation on the selection of the
+vertex for the faces built with the angle > 180 degrees (see the picture).
+
+\image html hypo_quad_params_2.png "3/4 of a circular face"
+
+In this case, selection of a wrong vertex for the <b>Base vertex</b>
+parameter will generate a wrong mesh. The picture below
+shows the good (left) and the bad (right) results of meshing.
+
+\image html hypo_quad_params_res_2.png "The resulting meshes"
+
+<b>Type</b> parameter is used on faces with a different number of
+segments on opposite sides to define the algorithm of transition
+between them. The following types are available:
+
+<ul>
+<li><b>Standard</b> is the default case, when both triangles and quadrangles
+    are possible in the transition area along the finer meshed sides.</li>
+<li><b>Triangle preference</b> forces building only triangles in the
+    transition area along the finer meshed sides.
+    <i>This type corresponds to <b>Triangle Preference</b> additional
+    hypothesis, which is obsolete now.</i></li>
+<li><b>Quadrangle preference</b> forces building only quadrangles in the
+    transition area along the finer meshed sides. This hypothesis has a
+    restriction: the total quantity of segments on all
+    four sides of the face must be even (divisible by 2).</li>
+    <i>This type corresponds to <b>Quadrangle Preference</b>
+    additional hypothesis, which is obsolete now.</i></li>
+<li><b>Quadrangle preference (reversed)</b> works in the same way and
+with the same restriction as <b>Quadrangle preference</b>, but
+    the transition area is located along the coarser meshed sides.</li>
+<li><b>Reduced</b> type forces building only quadrangles and the transition
+    between the sides is made gradually, layer by layer. This type has
+    a limitation on the number of segments: one pair of opposite sides must have
+    the same number of segments, the other pair must have an even difference
+    between the numbers of segments on the sides.</li>
+</ul>
+
+<b>See Also</b> a sample TUI Script of a 
+\ref tui_quadrangle_parameters "Quadrangle Parameters" hypothesis.
 
-This algorithm can be used only together with Quadrangle (Mapping)
-algorithm. It allows to build triangular mesh faces in the refinement
-area if the number of nodes at the opposite edges of a meshed face is not equal,
-otherwise refinement area will contain some quadrangular elements.
 <br>
 */
diff --git a/doc/salome/gui/SMESH/input/about_filters.doc b/doc/salome/gui/SMESH/input/about_filters.doc
new file mode 100644 (file)
index 0000000..22d8863
--- /dev/null
@@ -0,0 +1,31 @@
+/*!
+
+\page filters_page About filters
+
+\b Filters allow picking only the mesh elements satisfying to a
+specific condition or a set of conditions. Filters can be used to create
+or edit mesh groups, remove elements from the mesh object, control
+mesh quality by different parameters, etc.
+
+Several filters can be combined together by using logical operators \a
+AND and \a OR. In addition, applied filter criterion can be reverted
+using logical operator \a NOT.
+
+Mesh filters use the functionality of \ref quality_page "mesh quality controls"
+to filter mesh nodes / elements by specific characteristic (Area, Length, etc).
+
+The functinality of mesh filters is available in both GUI and TUI
+modes:
+
+- In GUI, filters are available in some dialog boxes via an additional
+"Set Filters" button, clicking on which opens the dialog box
+allowing to specify the list of filter criterions to be applied to the
+current selection. See \subpage selection_filter_library_page page to learn more
+about selection filters and their usage in GUI.
+
+- In Python scripts, filters can be used to choose only some mesh
+  entities (nodes and/or elements) for the operations, which require the
+  list of entities as input parameter (create/modify group, remove
+  nodes/elements, etc). The page \ref tui_filters_page provides
+  examples of the filters usage in Python scripts.
+*/
index 578823bd678e0dcc6ab451c06d55f6a68f90e971..5690ff36c3c88a5473aff669c4d9941a9294b9e5 100644 (file)
@@ -17,7 +17,7 @@ them, you operate numerical values):
 <b>edges</b>):</li>
 <ul>
 <li>\ref arithmetic_1d_anchor "Arithmetic 1D"</li>
-<li>\ref average_length_anchor "Average Length"</li>
+<li>\ref average_length_anchor "Local Length"</li>
 <li>\ref max_length_anchor "Max Size"</li>
 <li>\ref deflection_1d_anchor "Deflection 1D"</li>
 <li>\ref number_of_segments_anchor "Number of segments"</li>
@@ -28,8 +28,7 @@ them, you operate numerical values):
 <ul>
 <li>\ref max_element_area_anchor "Max Element Area"</li>
 <li>\ref length_from_edges_anchor "Length from Edges"</li>
-<li>\ref quadrangle_preference_anchor "Quadrangle Preference"</li>
-<li>\ref triangle_preference_anchor "Triangle Preference"</li>
+<li>\ref hypo_quad_params_anchor "Quadrangle Parameters"</li>
 </ul>
 <li>3D Hypothesis (for meshing of <b>volumes</b>):</li>
 <ul>
@@ -37,22 +36,15 @@ them, you operate numerical values):
 </ul>
 </ul>
 
-Some hypotheses are strictly combined with plug-in
-meshers and thus, work only with definite algorithms.
-<ul>
-<li>\subpage netgen_2d_3d_hypo_page</li> - work with NetGen algorithm.
-<li>\subpage ghs3d_hypo_page</li> - works with GHS3D algorithm.
-<li>\subpage ghs3dprl_hypo_page</li> - works with GHS3DPRL (tepal) algorithm.
-<li>\subpage blsurf_hypo_page</li> - works with BLSURF algorithm.
-</ul>
-
 There also exist  
 \subpage additional_hypo_page "Additional Hypotheses" used together
 with other hypotheses:
 <ul>
-<li>Propagation of 1D Hypothesis on opposite edges</li>
-<li>Non conform mesh allowed</li>
-<li>Quadratic mesh</li>
+<li>\ref propagation_anchor "Propagation of 1D Hypothesis on opposite edges"</li>
+<li>\ref viscous_layers_anchor "Viscous layers"</li>
+<li>\ref quadratic_mesh_anchor "Quadratic mesh"</li>
+<li>\ref non_conform_allowed_anchor "Non conform mesh allowed"</li>
+<li>\ref quadrangle_preference_anchor "Quadrangle preference"</li>
 </ul>
 
 The choice of a hypothesis depends on:
index 61865173b7a29a0d5dcd66adc6861eb1cfd78915..7474e0f62424458d96beff79accac29676926db9 100644 (file)
@@ -5,20 +5,24 @@
 \n \b MESH represents a discretization of a geometrical CAD model into
 a set of entities with a simple topology. 
 
-Meshes are stored in DAT, MED and UNV formats and can be
+Meshes are stored in DAT, MED, UNV, STL, CGNS and SAUVE formats and can be
 \subpage importing_exporting_meshes_page "imported from and exported to"
  the file in these formats.
 
-However, it is possible to \subpage constructing_meshes_page "construct meshes" 
+It is possible to \subpage constructing_meshes_page "construct meshes" 
 on the basis of geometrical shapes produced in the GEOM module.
-It is also possible to \subpage constructing_submeshes_page "create mesh on a part of the geometrical object", 
-for example, a face
+It is also possible to \subpage constructing_submeshes_page "mesh on a part of the geometrical object", 
+for example, a face, with different meshing parameters than the whole mesh.
 
-Several created meshes can be \subpage building_compounds_page "combined into mesh compounds".
+Several created meshes can be \subpage building_compounds_page "combined into another mesh".
 
-All created meshes and submeshes can be \subpage editing_meshes_page "edited".
+The whole mesh or it's part can be \subpage copy_mesh_page "copied" into another mesh.
 
-Meshes can be also using the MESH functions destined for 
+Meshing parameters of meshes and sub-meshes can be 
+\subpage editing_meshes_page "edited", then only a path of mesh
+depending on changed parameters will be re-computed.
+
+Meshes can be edited using the MESH functions destined for 
 \ref modifying_meshes_page "modification" of generated meshes.
 
 The \b topology of a mesh is described by the relationships between its
@@ -26,31 +30,34 @@ entities including:
 
 <ul>
 <li>\b Node &mdash; 0D object of a mesh presented by a point with coordinates (x, y, z).</li>
+<li>\b 0D element &mdash; element of a mesh defined by one node.</li>
 <li>\b Edge &mdash; 1D element of a mesh defined by two nodes.</li>
 <li>\b Face &mdash; 2D element of a mesh defined by three or four edges (closed contour).</li>
 <li>\b Volume &mdash; 3D element of a mesh defined by several faces.</li>
+<li>\b Ball element &mdash; discrete element of a mesh defined by a node and a diameter.</li>
 </ul>
 
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;These entities are
 considered as topological entities and they don't
 imply any geometric representation. Only \b Nodes reference  geometric
 representations of points with definite coordinates. The node entity
-will contain  additional information about its position in the space
+contains  additional information about its position in the space
 and its relations with the meshed CAD model. Its position could be
 described in the following way:
 
 <ul>
-<li><b>2D position</b>. It is a free position defined by only two coordinates x,y.</li>
-<li><b>3D position</b>. It is a free position defined by three coordinates x,y and z. </li>
+<li><b>3D position</b>. It characterizes the position of a node in a
+  solid geometry and is defined by three coordinates x,y and z and a
+  reference to the solid geometrical entity. </li>
 <li><b>Surface position</b>. It characterizes the position of a node on a
-geometric surface and is defined by the u,v position in the parametric
-space of the corresponding surface.</li>
+  geometric surface and is defined by the u,v position in the parametric
+  space of the corresponding surface.</li>
 <li><b>Line position</b>. It characterizes the position of a node on a
-geometric curve and is defined by the u parameter and the
-corresponding curve.</li>
+  geometric curve and is defined by the u parameter and the
+  corresponding curve.</li>
 <li><b>Vertex position</b>. It characterizes the position of a node on a
-geometric point of the meshed CAD model and is defined by the x,y,z
-coordinates of the corresponding vertex.</li>
+  geometric point of the meshed CAD model and is defined by the x,y,z
+  coordinates of the corresponding vertex.</li>
 </ul>
 
 <br><h2>Connections</h2>
index 7f7fa95dbd937ff3a21444f3994bb17712495c3b..1e170e440bd0e15ecf80d7bfdeae228b887845e9 100644 (file)
@@ -13,23 +13,29 @@ the meshing elements and these calculated values is shown with the
 help of a scalar bar, which is displayed near the presentation of your
 mesh.
 
-There are 0D, 1D, 2D and 3D quality controls.
+There are four types of quality controls, corresponding to node, edge,
+face and volume entity type.
 
-0D mesh quality controls:
+Node quality controls:
 <ul>
-<li>\ref free_nodes_page "Free nodes"</li>
+<li>\subpage free_nodes_page "Free nodes"</li>
+<li>\subpage double_nodes_control_page "Double nodes"</li>
 </ul>
 
-1D mesh quality controls:
+Edge quality controls:
 <ul>
+<li>\subpage free_edges_page "Free edges"</li>
 <li>\subpage free_borders_page "Free borders"</li>
-<li>\subpage borders_at_multi_connection_page "Borders at multi-connection"</li>
 <li>\subpage length_page "Length"</li>
+<li>\subpage borders_at_multi_connection_page "Borders at multi-connection"</li>
+<li>\subpage double_elements_page "Double edges"</li>
 </ul>
 
-2D mesh quality controls:
+Face quality controls:
 <ul>
-<li>\subpage free_edges_page "Free edges"</li>
+<li>\subpage free_faces_page "Free faces"</li>
+<li>\subpage bare_border_faces_page "Bare border faces"</li>
+<li>\subpage over_constrained_faces_page "Over-constrained faces"</li>
 <li>\subpage length_2d_page "Length 2D"</li>
 <li>\subpage borders_at_multi_connection_2d_page "Borders at multi-connection 2D"</li>
 <li>\subpage area_page "Area"</li>
@@ -38,13 +44,34 @@ There are 0D, 1D, 2D and 3D quality controls.
 <li>\subpage minimum_angle_page "Minimum angle"</li>
 <li>\subpage warping_page "Warping"</li>
 <li>\subpage skew_page "Skew"</li>
+<li>\subpage max_element_length_2d_page "Element Diameter 2D"</li>
+<li>\ref double_elements_page "Double faces"</li>
 </ul>
 
-3D mesh quality controls:
+Volume quality controls:
 <ul>
 <li>\subpage aspect_ratio_3d_page "Aspect ratio 3D"</li>
 <li>\subpage volume_page "Volume"</li>
-<li>\subpage free_faces_page "Free faces"</li>
+<li>\subpage max_element_length_3d_page "Element Diameter 3D"</li>
+<li>\subpage bare_border_volumes_page "Bare border volumes"</li>
+<li>\subpage over_constrained_volumes_page "Over-constrained volumes"</li>
+<li>\ref double_elements_page "Double volumes"</li>
 </ul>
 
+To manage the quality controls call pop-up in the VTK viewer and select "Controls" sub-menu
+\image html controls_popup.png
+
+<ul>
+<li> <b>Reset</b> switches off quality controls;</li>
+<li> <b>Node Controls</b> provides access to the node quality controls;</li>
+<li> <b>Edge Controls</b> provides access to the edge quality controls;</li>
+<li> <b>Face Controls</b> provides access to the face quality controls;</li>
+<li> <b>Volume Controls</b> provides access to the volume quality controls;</li>
+<li> <b>Scalar Bar Properties</b> allows setting \subpage scalar_bar_dlg;</li>
+<li> <b>Distribution -> Export ...</b> allows saving the distribution of quality control values in the text file;</li>
+<li> <b>Distribution -> Show </b> Shows/Hides the distribution histogram of the quality control values in the VTK Viewer.</li>
+<li> <b>Distribution -> Plot </b> Plots the distribution histogram of the quality control values in the Plot 2D Viewer.</li>
+</ul>
+
+
 */
index 179e7885ab69ba13dff0a32d41ca683237758b1a..a51bbdde45ccb820873ab4457f35723a87a0f0bf 100644 (file)
@@ -6,12 +6,15 @@
 
 <ul>
 <li>\ref adding_nodes_anchor "Nodes"</li>
+<li>\ref adding_0delems_anchor "0D Elements"</li>
+<li>\ref adding_balls_anchor "Ball Elements"</li>
 <li>\ref adding_edges_anchor "Edges"</li>
 <li>\ref adding_triangles_anchor "Triangles"</li>
 <li>\ref adding_quadrangles_anchor "Quadrangles"</li>
 <li>\ref adding_polygons_anchor "Polygons"</li>
 <li>\ref adding_tetrahedrons_anchor "Tetrahedrons"</li>
 <li>\ref adding_hexahedrons_anchor "Hexahedrons"</li>
+<li>\ref adding_octahedrons_anchor "Hexagonal prism"</li>
 <li>\ref adding_polyhedrons_anchor "Polyhedrons"</li>
 </ul>
 
@@ -25,6 +28,25 @@ following associated submenu will appear:</li>
 \image html image146.png
 
 From this submenu select the type of element which you would like to add to your mesh.
+
+\note All dialogs for new node or element adding to the mesh (except for
+the dialog for 0D elements) provide the possibility to automatically add
+a node or element to the specified group or to create the anew using
+<b>Add to group</b> box, that allows choosing an existing group for
+the created node or element or giving the name to a new group. By
+default, the <b>Add to group</b> check box is switched off. If the user
+swiches this check box on, the combo box listing all currently
+existing groups of the corresponding type becomes available. By
+default, no group is selected. In this case, when the user presses
+<b>Apply</b> or <b>Apply & Close</b> button, the warning message box
+informs the user about the necessity to input new group name. The
+combo box lists both \ref standalone_group "standalone groups"
+and \ref group_on_geom "groups on geometry". If the user chooses a
+group on geometry, he is warned and proposed to
+\ref convert_to_standalone "convert this group to standalone".
+If the user rejects conversion operation, it is cancelled and
+a new node/element is not created!
+
 </ol>
 
 <b>See Also</b> sample TUI Scripts of  
@@ -43,10 +65,29 @@ created:
 
 \image html add_node.png
 
-\note You can also use variables defined in the SALOME \b NoteBook
-to specify coordinates of the node:
+<br>
+\anchor adding_0delems_anchor
+<h2>Adding 0D elements</h2>
+
+\image html add0delement.png
+
+In this dialog box specify the node which will form your 0d element by
+selecting it in the 3D viewer and click the \b Apply or
+<b>Apply and Close</b> button. Your 0D element will be created:
+
+\image html add_0delement.png
+
+\anchor adding_balls_anchor
+<h2>Adding ball elements</h2>
 
-\image html addnode_notebook.png
+\image html addball.png
+
+In this dialog box specify the node which will form your ball element
+either by selecting it in the 3D viewer or by manual entering its ID,
+specify a ball diameter and click the \b Apply or <b>Apply and
+Close</b> button. Your ball element will be created:
+
+\image html add_ball.png
 
 <br>
 \anchor adding_edges_anchor
@@ -120,6 +161,16 @@ the \b Apply or <b>Apply and Close</b> button. Your hexahedron will be created:
 
 \image html image71.jpg
 
+<br>
+\anchor adding_octahedrons_anchor
+<h2>Adding hexagonal prism</h2>
+
+In the Add Hexagonal Prism dialog box specify the nodes which will
+form your hexagonal prism by selecting them in the 3D viewer with pressed Shift button and click
+the \b Apply or <b>Apply and Close</b> button. Your hexagonal prism will be created:
+
+\image html image_octa12.png
+
 <br>
 \anchor adding_polyhedrons_anchor
 <h2>Adding polyhedrons</h2>
@@ -142,4 +193,4 @@ button. If you've managed to obtain the necessary result, click the
 
 \image html add_polyhedron.png
 
-*/
\ No newline at end of file
+*/
index afe9b77b51e3ea9458c659b06c9dc51a67d37211..9219486302c70040bb417f7f6afd7e31a2d3d3f5 100644 (file)
@@ -2,7 +2,7 @@
 
 \page adding_quadratic_elements_page Adding Quadratic Elements
 
-\n MESH modules allows you to work with <b>Quadratic Elements</b>.
+\n MESH module allows you to work with <b>Quadratic Elements</b>.
 
 Quadratic Edge is not a straight but a broken line and can be defined
 by three points: first, middle and last. All more complex \b Quadratic
@@ -18,6 +18,25 @@ one of the following:
 
 \image html image152.png
 
+\note All dialogs for quadratic element adding to the mesh
+provide the possibility to automatically add an element
+to the specified group or to create the group anew using
+<b>Add to group</b> box, that allows choosing an existing group for
+the created node or element or giving the name to a new group. By
+default, the <b>Add to group</b> check box is switched off. If the user
+swiches this check box on, the combo box listing all currently
+existing groups of the corresponding type becomes available. By
+default, no group is selected. In this case, when the user presses
+<b>Apply</b> or <b>Apply & Close</b> button, the warning message box
+informs the user about the necessity to input a new group name. The
+combo box lists both \ref standalone_group "standalone groups"
+and \ref group_on_geom "groups on geometry". If the user chooses a
+group on geometry, he is warned and proposed to
+\ref convert_to_standalone "convert this group to standalone".
+If the user rejects conversion operation, it is cancelled and
+a new quadratic element is not created.
+
+
 To create any <b>Quadratic Element</b> specify the nodes which will form your
 triangle by selecting them in the 3D viewer with pressed Shift
 button. Their numbers will appear in the dialog box as <b>Corner Nodes</b>
index 9687bdf2d6f9a5ce1ccc478af9605632d53c219a..61ac4800c1334d0566057e76e651872aed9e965d 100644 (file)
@@ -9,18 +9,21 @@ To define an <b>Additional Hypothesis</b> simply select it in
 <b>Create Mesh</b> menu. These hypotheses are actually changes in the
 rules of mesh creation and as such don't possess adjustable values.
 
+\anchor non_conform_allowed_anchor
 <h2>Non Conform mesh allowed hypothesis</h2>
 
 <b>Non Conform mesh allowed</b> hypothesis allows to generate non-conform
 meshes (that is, meshes having some edges ending on an edge or face of
 adjacent elements).
 
+\anchor quadratic_mesh_anchor
 <h2>Quadratic Mesh</h2>
 
 Quadratic Mesh hypothesis allows to build a quadratic mesh (whose
 edges are not straight but broken lines and can be defined by three
 points: first, middle and last) instead of an ordinary one.
 
+\anchor propagation_anchor
 <h2>Propagation of 1D Hypothesis on opposite edges</h2>
 
 <b>Propagation of 1D Hypothesis on opposite edges</b> allows to propagate a
@@ -28,8 +31,49 @@ hypothesis onto an opposite edge. If a local hypothesis and
 propagation are defined on an edge of a quadrangular face, the
 opposite edge will have the same hypothesis, unless another hypothesis
 has been locally defined on the opposite edge.
-
 <br><b>See Also</b> a sample TUI Script of a 
-\ref tui_propagation "Propagation hypothesis" operation.  
+\ref tui_propagation "Propagation hypothesis" operation
+
+\anchor quadrangle_preference_anchor
+<h2>Quadrangle Preference</h2>
+
+This additional hypothesis can be used together with 2D triangulation algorithms.
+It allows 2D triangulation algorithms to build quadrangular meshes.
+
+When used with "Quadrangle (Mapping)" meshing algorithm, that is obsolete
+ since introducing \ref hypo_quad_params_anchor "Quadrangle parameters" 
+hypothesis, this hypothesis has one restriction on its work: the total quantity of 
+segments on all four sides of the face must be even (divisible by 2).
+
+\anchor viscous_layers_anchor
+<h2>Viscous Layers</h2>
+
+<b>Viscous Layers</b> additional hypothesis can be used together with
+some 3D algorithms, Hexahedron(i,j,k) for example. This
+hypothesis allows creation of layers of highly stretched prisms near
+mesh boundary, which is beneficial for high quality viscous
+computations. The prisms constructed on the quadrangular mesh faces are
+actually the hexahedrons.
+
+
+\image html viscous_layers_hyp.png
+
+<ul>
+<li><b>Name</b> - allows to define the name of the hypothesis.</li>
+<li><b>Total thicknes</b> - gives the total thickness of prism layers.</li>
+<li><b>Number of layers</b> - defines the number of prism layers.</li>
+<li><b>Stretch factor</b> - defines the growth factor of prism height
+from the mesh boundary inwards.</li>
+<li><b>Faces without layers</b> - defines geometrical faces on which
+prism layers should not be constructed. By default the prism layers
+are not constructed on geometrical faces shared by solids.</li>
+</ul>
+
+\image html viscous_layers_mesh.png A group containing viscous layer prisms.
+
+<br><b>See also</b> a sample TUI script of a \ref tui_viscous_layers
+"Viscous layers construction".
+
 
-*/
\ No newline at end of file
+*/
index bef0c0f8aed9748c0b389fa53cef6b42216296dc..f650a3fd65b1b867cd932b75fd99cdbf9560104e 100644 (file)
@@ -11,7 +11,8 @@ quadrangles).
 <ol>
 <li>Display your mesh in the viewer.</li>
 
-<li>Choose <b>Controls > Area</b> or click <em>"Area"</em> button. 
+<li>Choose <b>Controls > Face Controls > Area</b> or click
+<em>"Area"</em> button. 
 
 \image html image35.png
 <center><em>"Area" button</em></center>
index 070d377cc47da6a6a4875dedc2a509d444dc25e8..af1057ddda3e497cf6a422f20bd47a83d29a83cf 100644 (file)
@@ -13,22 +13,23 @@ nodes is calculated by the formula:
 
 \image html formula4.png
 
-- The <b>Aspect Ratio</b> of a \b quadrangle 2D element consisting of
- 4 nodes is the worst (i.e. the greatest) value from all triangles
- which can be built taking three nodes of the quadrangle. There are
- four triangles to consider:
+- The <b>Aspect Ratio</b> of a \b quadrangle 2D element consisting of 4
+nodes is calculated using The Verdict Geometric Quality Library
+available within VTK. The calculation formula is:
 
-\image html image138.gif
+\image html formula5.png
 
 <em>To apply the Aspect Ratio quality criterion to your mesh:</em>
 <ol>
 <li>Display your mesh in the viewer.</li>
 
-<li>Choose <b>Controls > Aspect Ratio</b> or click <em>"Aspect
-Ratio"</em> button in the toolbar.
+<li>Choose <b>Controls > Face Controls > Aspect Ratio</b> or click
+<em>"Aspect Ratio"</em> button in the toolbar.
 
+<center>
 \image html image37.png
-<center><em>"Aspect Ratio" button</em></center>
+<em>"Aspect Ratio" button</em>
+</center>
 
 Your mesh will be displayed in the viewer with its elements colored
 according to the applied mesh quality control criterion:
index 751e411028fe4a3c9fe9d60ef633b7dba312c0a2..2ea62f1f8e60fd14e936662880d93d66711ff7bd 100644 (file)
@@ -7,8 +7,8 @@ parameter as the \ref aspect_ratio_page "Aspect ratio" criterion, but
 it is applied to 3D mesh elements: tetrahedrons, pentahedrons,
 hexahedrons, etc.
 
-- The <b>Aspect Ratio</b> of a \b tetrahedron 3D element is calculated
-by the formula:
+- The <b>Aspect Ratio</b> of a \b tetrahedron 3D element defined by
+vertices {a,b,c,d } is calculated by the formula:
 
 \image html formula1.png
 
@@ -21,8 +21,8 @@ by the formula:
 <ol>
 <li>Display your mesh in the viewer.</li>
 
-<li>Choose <b>Controls > Aspect Ratio 3D</b> or click <em>"Aspect Ratio 3D"</em> 
-button of the toolbar.
+<li>Choose <b>Controls > Volume Controls > Aspect Ratio 3D</b> or click
+<em>"Aspect Ratio 3D"</em> button of the toolbar.
 
 \image html image144.png
 <center><em>"Aspect Ratio 3D" button</em></center>
diff --git a/doc/salome/gui/SMESH/input/bare_border_face.doc b/doc/salome/gui/SMESH/input/bare_border_face.doc
new file mode 100644 (file)
index 0000000..2115d32
--- /dev/null
@@ -0,0 +1,15 @@
+/*!
+
+\page bare_border_faces_page Bare border faces
+
+This mesh quality control highlights the faces having the border not
+shared with other faces (free border) and missing an edge based on
+nodes of the free border. The faces with bare border are shown with a
+color different from the color of shared faces.
+
+\image html bare_border_faces_smpl.png
+
+\sa A sample TUI Script making a group of faces highlighted in the
+picture is \ref tui_bare_border_faces "Bare border faces Control".
+
+*/
diff --git a/doc/salome/gui/SMESH/input/bare_border_volumes.doc b/doc/salome/gui/SMESH/input/bare_border_volumes.doc
new file mode 100644 (file)
index 0000000..d0dd894
--- /dev/null
@@ -0,0 +1,15 @@
+/*!
+
+\page bare_border_volumes_page Bare border volumes
+
+This mesh quality control highlights the volumes having the border not
+shared with other volumes (free border) and missing a face based on
+nodes of the free border. The volumes with bare border are shown with a
+color different from the color of shared volumes.
+
+\image html bare_border_volumes_smpl.png
+
+\sa A sample TUI Script making a group of volumes highlighted in the
+picture is \ref tui_bare_border_volumes "Bare border volumes Control".
+
+*/
index 1fd311d844d410ee903439f8017af74857b7868b..a4ebe1c8a0765b9082683f0dbc38e11c3615cd38 100644 (file)
@@ -21,9 +21,8 @@ shape of a mesh.</li>
 <li>For meshing of 2D entities (<b>faces</b>):</li>
 
 <ul>
-<li>Triangle meshing algorithms (Mefisto, Netgen 1D-2D and BLSUFR ) - Faces
-are split into triangular elements.</li>
-<li>Quadrangle meshing algorithm (Mapping) - Faces are split into
+<li>Triangle meshing algorithms (Mefisto) - Faces are split into triangular elements.</li>
+<li>Quadrangle meshing algorithm (Mapping) - quadrilateral Faces are split into
 quadrangular elements.</li>
 </ul>
 
@@ -34,10 +33,12 @@ quadrangular elements.</li>
 <li>For meshing of 3D entities (<b>volume objects</b>):</li>
 
 <ul>
-<li>Hexahedron meshing algorithm (i,j,k) - Volumes are split into
+<li>Hexahedron meshing algorithm (i,j,k) - 6-sided Volumes are split into
 hexahedral (cubic) elements.</li>
-<li>Tetrahedron (Netgen and GHS3D) meshing algorithms - Volumes are split into
-tetrahedral (pyramidal) elements.</li>
+<li>\subpage cartesian_algo_page</li>
+internal parts of Volumes are split into hexahedral elements forming a
+Cartesian grid; polyhedra and other types of elements are generated
+where the geometrical boundary intersects Cartesian cells.</li>
 </ul>
 
 \image html image125.gif "Example of a tetrahedral 3D mesh"
@@ -45,16 +46,25 @@ tetrahedral (pyramidal) elements.</li>
 \image html image126.gif "Example of a hexahedral 3D mesh"
 </ul>
 
-\Note that BLSURF and GHS3D are commercial meshers and require a
-license to be used within the Mesh module.
+Some of 3D meshing algorithms also can generate 3D meshes from 2D meshes, working without
+geometrical objects. Such algorithms are
+<ul>
+<li>Hexahedron meshing algorithm (i,j,k),</li>
+<!-- <li>GHS3D meshing algorithm (commercial)</li> -->
+</ul>
 
 There is also a number of more specific algorithms:
 <ul>
 <li>\subpage projection_algos_page "for meshing by projection of another mesh"</li>
+<li>\subpage import_algos_page "for meshing by importing elements from another mesh"</li>
 <li>\subpage radial_prism_algo_page "for meshing geometrical objects with cavities"</li>
 <li>\subpage segments_around_vertex_algo_page "for defining the local size of elements around a certain node"</li>
 <li>\subpage prism_3d_algo_page "for meshing prismatic shapes"</li>
+<li>\subpage radial_quadrangle_1D2D_algo_page "for meshing special 2d faces (circles and part of circles)"</li>
 </ul>
+\ref use_existing_anchor "Use existing edges" and 
+\ref use_existing_anchor "Use existing faces" algorithms can be
+used to create an 1D or a 2D mesh in a python script.
 
 \ref constructing_meshes_page "Constructing meshes" page describes in
 detail how to apply meshing algorithms.
@@ -62,4 +72,4 @@ detail how to apply meshing algorithms.
 <br><b>See Also</b> a sample TUI Script of a 
 \ref tui_defining_meshing_algos "Define Meshing Algorithm" operation.  
 
-*/
\ No newline at end of file
+*/
diff --git a/doc/salome/gui/SMESH/input/blsurf_hypo.doc b/doc/salome/gui/SMESH/input/blsurf_hypo.doc
deleted file mode 100644 (file)
index b392f3b..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-/*!
-
-\page blsurf_hypo_page BLSURF Parameters hypothesis
-
-\n BLSURF Parameters hypothesis works only with <b>BLSURF</b> 2d
-algorithm. This algorithm is a commercial software.
-
-\image html blsurf_parameters.png
-
-<ul>
-<li><b>Name</b> - allows defining the name of the hypothesis (BLSURF
-Parameters_n by default).</li>
-
-<li><b>Physical Mesh</b> - if set to "Custom", allows user input in te
-in <b>User size</b>, <b>Max Physical Size</b> and <b>Min Physical
-Size</b> fields.
-</li>
-
-<li><b>User size</b> - defines the size of the generated mesh elements. </li>
-
-<li><b>Max Physical Size</b> - defines the upper limit of mesh element size. </li>
-
-<li><b>Min Physical Size</b> - defines the lower limit of mesh element size. </li>
-
-<li><b>Geometrical mesh</b> - if set to "Custom", allows user input in
- <b>Angle Mesh S</b>, <b>Angle Mesh C</b> and
-<b>Gradation</b> fields. These fields control
-computation of the element size, so called <i>geometrical size</i>, conform to
-the surface geometry considering local curvatures. \n
-If both the <b>User size</b> and the <i>geometrical size</i> are defined, the
- eventual element size correspond to the least of the two. </li>
-
-<li><b>Angle Mesh S</b> - maximum angle between the mesh face and the
-tangent to the geometrical surface at each mesh node, in degrees. </li>
-
-<li><b>Angle Mesh C</b> - maximum angle between the mesh edge and the
-tangent to the geometrical curve at each mesh node, in degrees. </li>
-
-<li><b>Max Geometrical Size</b> - defines the upper limit of the <i>geometrical size</i>.</li>
-
-<li><b>Min Geometrical Size</b> - defines the lower limit of the <i>geometrical size</i>.</li>
-
-<li><b>Gradation</b> - maximum ratio between the lengths of
-two adjacent edges. </li>
-
-<li><b>Allow Quadrangles</b> - if checked, allows the creation of quadrilateral elements.</li>
-
-<li><b>Patch independent</b> - if checked, geometrical
-edges are not respected and all geometrical faces are meshed as one
-hyper-face.</li>
-
-\image html blsurf_parameters_advanced.png
-
-<li><b>Topology</b> - allows creation of a conform mesh on a shell of
-not sewed faces. 
-<ul>
-  <li>"From CAD" means that mesh conformity is assured by conformity
-  of a shape.</li>
-  <li>"Pre-process" and "Pre-process++" allow the BLSURF software to
-  pre-process the geometrical model to eventually produce a conform
-  mesh. </li>
-</ul>
-
-<li><b>Verbosity level</b> - Defines the percentage of "verbosity" of
-BLSURF [0-100].</li>
-
-<li><b>Add option</b> - provides the choice of multiple advanced
-options, which appear, if selected, in a table where it is possible to
-input the value of the option and to edit it later.</li>
-
-<li><b>Clear option</b> - removes the option selected in the table.
-
-</ul>
-
-\n
-The following options are commonly usable. The notion of <i>diag</i>
-used in the descriptions means
-the diagonal of the bounding box of the geometrical object to mesh.
-
-<ul>
-<li><b>topo_eps1</b> (real) - is the tolerance level inside a CAD
-patch. By default is equal to <i>diag</i> Ã— 10-4. This tolerance is used to
-identify nodes to merge within one geometrical face when \b Topology
-option is to pre-process. Default is <i>diag</i>/10.0.</li>
-
-<li><b>topo_eps2</b> (real) - is the tolerance level between two CAD
-patches. By default is equal to <i>diag</i> Ã— 10-4. This tolerance is used to
-identify nodes to merge over different geometrical faces when
-\b Topology option is to pre-process. Default is <i>diag</i>/10.0.</li>
-
-<li>\b LSS (real) - is an abbreviation for "length of sub-segment". It is
-a maximal allowed length of a mesh edge. Default is 0.5.</li>
-
-<li>\b frontal (integer)
-<ul>
-<li> 1 - the mesh generator inserts points with an advancing front method.</li>
-<li> 0 - it inserts them with an algebraic method (on internal edges). This method is
-slightly faster but generates less regular meshes. </li>
-</ul>
-Default is 0.</li>
-
-<li>\b hinterpol_flag (integer) - determines the computation of an
-interpolated value <i>v</i> between two points <i>P1</i> and <i>P2</i> on a
-curve. Let <i>h1</i> be the value at point <i>P1,</i> <i>h2</i> be the value at point
-<i>P2,</i> and <i>t</i> be a parameter varying from 0 to 1 when moving from <i>P1
-to</i> <i>P2</i> . 
-<ul>
-<li>0 - the interpolation is linear: <i>v = h1 + t (h2 - h1 )</i></li>
-<li>1 - the interpolation is geometric: <i>v = h1 * pow( h2/h1, t)</i></li>
-<li>2 - the interpolation is sinusoidal: <i>v = (h1+h2)/2 +
-(h1-h2)/2*cos(PI*t)</i></li>
-</ul>
-Default is 0.</li>
-
-<li>\b hmean_flag (integer) - determines the computation of the average of several
-values:<ul>
-<li>-1 - the minimum is computed.</li>
-<li>0 or 2 - the arithmetic average computed.
-<li>1 - the geometric average is computed.</li>
-</ul>
-Default is 0.</li>
-
-<li>\b CheckAdjacentEdges, \b CheckCloseEdges and \b CheckWellDefined
-(integers) - gives the number of calls of equally named subroutines the
-purpose of which is to improve the mesh of domains having narrow
-parts. At each iteration,\b CheckCloseEdges decreases the sizes of the
-edges when two boundary curves are neighboring,\b CheckAdjacentEdges
-balances the sizes of adjacent edges, and \b CheckWellDefined checks if
-the parametric domain is well defined. Default values are 0.</li>
-
-
-<li>\b CoefRectangle (real)- defines the relative thickness of the rectangles
-used by subroutine \b CheckCloseEdges (see above). Default is 0.25.</li>
-
-<li>\b eps_collapse (real) - if more than 0.0, BLSURF removes
-curves whose lengths are less than \b eps_collapse. To obtain an
-approximate value of the length of a curve, it is arbitrarily
-split into 20 edges. Default is 0.0.</li>
-
-<li>\b eps_ends (real) - is used to detect the curves whose lengths are very
-small, which sometimes constitutes an error. A message is printed
-if<i> fabs(P2-P1) < eps_ends</i>, where <i>P1</i> and <i>P2</i> are the
-extremities of a curve. Default is <i>diag</i>/500.0.</li>
-
-<li>\b prefix (char) - is a prefix of the files generated by
-BLSURF. Default is "x".</li>
-
-<li>\b refs (integer) - reference of a surface, used when exporting
-files. Default is 1.</li>
-</ul>
-
-\n
-The following advanced options are not documented and you can use them
-at your own risk.
-\n\n Interger variables:
-<ul>
-<li>    addsurf_ivertex</li>
-<li>    background     </li>
-<li>    coiter         </li>
-<li>    communication  </li>
-<li>    decim          </li>
-<li>    export_flag    </li>
-<li>    file_h         </li>
-<li>    gridnu         </li>
-<li>    gridnv         </li>
-<li>    intermedfile   </li>
-<li>    memory         </li>
-<li>    normals        </li>
-<li>    optim          </li>
-<li>    pardom_flag    </li>
-<li>    pinch          </li>
-<li>    rigid          </li>
-<li>    surforient     </li>
-<li>    tconf          </li>
-<li>    topo_collapse  </li>
-</ul>
-Real variables:
-<ul>
-<li>    addsurf_angle  </li>
-<li>    addsurf_R      </li>
-<li>    addsurf_H      </li>
-<li>    addsurf_FG     </li>
-<li>    addsurf_r      </li>
-<li>    addsurf_PA     </li>
-<li>    angle_compcurv </li>
-<li>    angle_ridge    </li>
-<li>    eps_pardom     </li>
-</ul>
-String variables:
-<ul>
-<li>    export_format  </li>
-<li>    export_option  </li>
-<li>    import_option  </li>  
-</ul>
-
-
-\n
-Currently BLSURF plugin has the following limitations.
-<ul>
-  <li>The created mesh will contain inverted elements if it is based on a shape,
-      consisting of more than one face (box, cone, torus...) and if
-      the option "Allow Quadrangles (Test)" has been checked before
-      computation.</li>
-
-  <li>SIGFPE exception is raised at the attempt to compute the mesh
-      based on a box when the option "Patch independent" is checked.</li>
-
-  <li>BLSURF algorithm cannot be used as a local algorithm (on
-      sub-meshes) or as a provider of a low-level
-      mesh for some 3D algorithms, because the BLSURF mesher (and
-      consequently plugin) does not provide the information on node
-      parameters on edges (U) and faces (U,V). For example the
-      following combinations of algorithms are impossible:
-      <ul>
-        <li> global MEFISTO or Quadrangle(mapping) + local BLSURF;</li>
-        <li> BLSUFR + Projection 2D from faces meshed by BLSURF;</li>
-        <li> local BLSURF + Extrusion 3D;</li>
-      </ul>
-      </li>
-</ul>
-
-*/
index faf636b824c7dc934b9c31fa9e4f5b1575d09d16..98a20c470fcfc6443d4b45339683f8151287c8ec 100644 (file)
@@ -47,4 +47,6 @@ for this operation.</li>
 
 \image html image160.gif "Example of a compound of two meshed cubes"
 
+<b>See Also</b> a sample 
+\ref tui_building_compound "TUI Example of building compounds."
 */
diff --git a/doc/salome/gui/SMESH/input/cartesian_algo.doc b/doc/salome/gui/SMESH/input/cartesian_algo.doc
new file mode 100644 (file)
index 0000000..3240150
--- /dev/null
@@ -0,0 +1,75 @@
+/*!
+
+\page cartesian_algo_page Body Fitting 3D meshing algorithm
+
+Body Fitting algorithm generates hexahedrons of a Cartesian grid in
+the internal part of geometry and polyhedrons and other types of
+elements at the intersection of Cartesian cells with the geometrical
+boundary.
+
+\image html cartesian3D_sphere.png "A shpere meshed by Body Fitting algorithm"
+
+The meshing algorithm is as follows.
+<ol>
+<li> Lines of a Cartesian structured grid defined by
+\ref cartesian_hyp_anchor "Body Fitting Parameters" hypothesis are
+intersected with the geometry boundary, thus nodes lying on the
+boundary are found. This step also allows finding out for each node of
+the Cartesian grid if it is inside or outside the geometry. </li>
+<li> For each cell of the grid, check how many of its nodes are outside
+of the geometry boundary. Depending on a result of this check
+<ul>
+<li> skip a cell, if all its nodes are outside </li>
+<li> skip a cell, if it is too small according to <b> Size
+    Threshold </b> parameter</li>
+<li> add a hexahedron in the mesh, if all nodes are inside </li>
+<li> add a polyhedron or another cell type in the mesh, if some
+nodes are inside and some outside. </li> 
+</ul>
+</li>
+</ol>
+To apply this algorithm when you define your mesh, select <b>Body
+  Fitting</b> in the list of 3D algorithms and click <em> "Add
+  Hypothesis" </em> button and <em>"Body Fitting Parameters"</em>" menu
+  item. Dialog of <b>Body Fitting Parameters
+  hypothesis</b> will appear.
+
+<br>
+\anchor cartesian_hyp_anchor
+<h2>Body Fitting Parameters hypothesis</h2>
+
+\image html cartesian3D_hyp.png "Body Fitting Parameters hypothesis dialog"
+
+This dialog allows to define
+<ul>
+<li>\b Name of the algorithm </li>
+<li> Minimal size of a cell truncated by the geometry boundary. If the
+  size of a truncated grid cell is \b Threshold times less than a
+  initial cell size, then a mesh element is not created. </li>
+<li> Cartesian structured grid. Each grid axis is defined
+  individually. <b> Definition mode </b> chooses a way of grid
+  definition: <ul> 
+  <li> You can specify the \b Coordinates of grid nodes. \b Insert button
+    inserts a node at distance \b Step (negative or positive) from a
+    selected node. \b Delete button removes a selected node. Double
+    click on a coordinate in the list enables its edition. A grid
+    defined by \b Coordinates should enclose the geometry, else the
+    algorithm will fail. </li>
+  <li> You can define the \b Spacing of a grid as an algebraic formula 
+    <em>f(t)</em> where \a t is a position along a grid axis
+    normalized at [0.0,1.0]. The whole range of geometry can be
+    divided into sub-ranges with their own spacing formulas to apply;
+    \a t varies between 0.0 and 1.0 within each sub-range. \b Insert button
+    divides a selected range into two ones. \b Delete button adds the
+    selected sub-range to the previous one. Double click on a range in
+    the list enables edition of its right boundary. Double click on a
+    function in the list enables its edition. 
+  </li> </ul>
+</li>
+</ul>
+
+<br>
+<b>See Also</b> a sample TUI Script of a 
+\ref tui_cartesian_algo "Usage of Body Fitting algorithm".  
+
+*/
index 410245b04f060344b737fa10bd7d1205254ecfa0..416f9514cfdb44175f947b4271a10525a7dfa39e 100644 (file)
@@ -2,8 +2,7 @@
 
 \page changing_orientation_of_elements_page Changing orientation of elements
 
-\n Orientation of an element is changed by reverting the order of
-nodes of the selected elements.
+\n Orientation of an element is changed by reverting the order of its nodes.
 
 <em>To change orientation of elements:</em>
 <ol>
@@ -11,13 +10,16 @@ nodes of the selected elements.
 <li>In the \b Modification menu select the \b Orientation item or click
 <em>Orientation</em> button in the toolbar.
 
+<center>
 \image html image79.png
-<center><em>"Orientation" button</em></center>
+<em>"Orientation" button</em>
+</center>
 
 The following dialog box will appear:
 
+<center>
 \image html orientaation1.png
-
+</center>
 <ul>
 <li><b>The main list</b> shall contain the elements which will be
 reoriented. You can click on an element in the 3D viewer and it will
index f3b19f3742cd61033b1c20584a5f0a2482270206..2bfa8292bc6ba53c8415e91b4d1dda2c871d8972 100644 (file)
@@ -9,12 +9,20 @@ To start, click on the \em New button.
 
 \image html a-clipping2.png
 
-Now you can define the parameters of your cross-section: \b Orientation
-(X-Y, X-Z or Y-Z); \b Distance between the opposite extremities of the
-object, if it is set to 0.5 the object is split in two halves; and
-\b Rotation (in angle degrees) <b>around X</b> (Y to Z) and <b>around Y</b> (X to
-Z). If the <b>Show preview</b> button is on, you can see the clipping plane
-in the <b>3D Viewer</b>.
+Now you can define the parameters of cross-section: 
+<ul>
+<li> List of <b>meshes, sub-meshes and groups</b> to which the cross-section will be applied.
+/n <b>Select all</b> button allows to select and deselect all available
+objects at once).</li>
+<li> \b Orientation (X-Y, X-Z or Y-Z).</li>
+<li> \b Distance between the opposite extremities of the boundary box
+of selected objects, if it is set
+to 0.5 the boundary box is split in two halves. </li>
+<li> \b Rotation (in angle
+degrees) <b>around X</b> (Y to Z) and <b>around Y</b> (X to Z).</li>
+<li>If the <b>Show preview</b> button is on, you can see the clipping plane
+in the <b>3D Viewer</b>.</li>
+</ul>
 
 \image html image79.jpg "The plane and the cut object"
 
diff --git a/doc/salome/gui/SMESH/input/colors_size.doc b/doc/salome/gui/SMESH/input/colors_size.doc
new file mode 100644 (file)
index 0000000..f953b37
--- /dev/null
@@ -0,0 +1,37 @@
+/*!
+
+\page colors_size_page Properties
+
+\image html colors_size.png
+
+Using this dialog you can define the following set of mesh visualization
+parameters:
+<ul>
+<li><b>Elements</b></li>
+<ul>
+<li><b>Surface color</b> - surface color of elements (seen in Shading mode).</li>
+<li><b>Back surface color</b> - interior surface color of elements. Use slider to select this color 
+generated on base of the <b>Surface color</b> by changing its brightness and saturation.</li>
+<li><b>Outline color</b> - color of element borders.</li>
+<li><b>Wireframe color</b> - color of element borders in wireframe mode.</li>
+<li><b>0D slements</b> - color of 0D elements.</li>
+<li><b>Size of 0D slements</b> - size of 0D elements.</li>
+<li><b>Line width</b> - width of lines (edges and borders of elements).</li>
+<li><b>Shrink coef.</b> - relative space of elements compared to gaps between
+       them in shrink mode.</li>
+</ul>
+<li><b>Nodes</b></li>
+<ul>
+<li><b>Color</b> - color of nodes.</li>
+<li><b>Marker</b> - group of options allowing to change the representation of
+       points (see \subpage point_marker_page "Point Marker" page).</li>
+</ul>
+<li><b>Orientation of faces</b></li>
+<ul>
+<li><b>Color</b> - color of orientation vertors.</li>
+<li><b>Scale</b> - size of orientation vectors.</li>
+<li><b>3D vectors</b> - allows to choose between 2D planar and 3D vectors.</li>
+</ul>
+</ul>
+
+*/
index d62feac7cc5102ef33d3a00a1ae361877ac6e11f..adf63c6a1505385e6c706af72a77c28d58389ddd 100644 (file)
 
 \page constructing_meshes_page Constructing meshes
 
-\n Construction of a mesh consists of:
+\n Construction of a mesh on some geometry consists of:
 <ul>
-<li>Selecting a geometrical object for meshing</li>
-<li>Applying \subpage basic_meshing_algos_page "meshing algorithms" and
-\subpage about_hypo_page "hypotheses" which will be used at computation of
-this mesh.</li>
+  <li> \ref create_mesh_anchor "Creating of a mesh object"</li>
+  <li> \ref evaluate_anchor "Evaluating mesh size"</li>
+  <li> \ref preview_anchor "Previewing the mesh"</li>
+  <li> \ref submesh_order_anchor "Changing submesh priority"</li>
+  <li> \ref compute_anchor "Computing the mesh"</li>
 </ul>
+Mesh can be \ref use_existing_anchor "computed using your own meshing algorithms" 
+written in Python.
 
+
+\anchor create_mesh_anchor
+<h2>Creation of a mesh object</h2>
 <em>To construct a mesh:</em>
 <ol>
-<li>In the \b Mesh menu select <b>Create Mesh</b> or click <em>"Create
-Mesh"</em> button in the toolbar. 
+  <li>Select a geometrical object for meshing.</li>
+  <li>In the \b Mesh menu select <b>Create Mesh</b> or click <em>"Create
+      Mesh"</em> button in the toolbar. 
+
+    \image html image32.png
+    <em>"Create Mesh" button</em>
+
+    The following dialog box will appear: 
+
+    \image html createmesh-inv.png
+    <br>
+  </li>
+  <li>Apply \subpage basic_meshing_algos_page "meshing algorithms" and
+    \subpage about_hypo_page "hypotheses" which will be used at computation of
+    this mesh.
+
+    For example, you need to mesh a 3D object.
+
+    First, type the name for your mesh in the \b Name box, by default,
+    it is "Mesh_1". Then select the geometrical object you wish to
+    mesh in the Object Browser and click "Select" button near \b Geometry
+    field (if name of the object not yet appeared in \b Geometry field).
+
+    \image html image120.png
+    <em>"Select" button</em>
+
+    Now you can define 3D Algorithm and 3D Hypotheses, which will be
+    applied to solids of your geometrical object. Click the <em>"Add
+      Hypothesis"</em>  button to add a hypothesis.
+
+    \image html image121.png
+    <em>"Add Hypothesis" button</em>
+
+    Click the <em>"Edit Hypothesis"</em> button to change values for the
+    current hypothesis.
+
+    \image html image122.png
+    <em>"Edit Hypothesis" button</em>
+
+    Most standard 2D and 3D algorithms can work without hypotheses
+    using some default parameters. The use of additional hypotheses
+    is optional (i.e. you may leave "None" in this box).
+
+    Proceed in the same way with 2D and 1D Algorithms and Hypotheses that
+    will be used to mesh faces and edges of your geometry. (Note
+    that any object has edges, even if their existence is not
+    apparent, for example, a sphere has 4 edges). Note that the
+    choice of hypotheses and of an algorithm of lower dimension depends on
+    the algorithm. 
+
+    Some algorithms generate mesh of several dimensions while others, of
+    only one dimension. In the latter case there must be one Algorithm and zero or several
+    Hypotheses for each dimension of your object, otherwise you will
+    not get any mesh at all. Of course, if you wish to mesh a face,
+    which is a 2D object, you don't need to define 3D Algorithm and
+    Hypotheses.
+
+    In the <b>Object Browser</b> the structure of the new mesh will be
+    displayed as follows:
+
+      \image html image88.jpg
+
+    It contains:
+    <ul>
+      <li>a reference to the geometrical object on the basis of
+        which the mesh has been constructed;</li> 
+      <li><b>Applied hypotheses</b> folder containing the references
+        to the hypotheses applied at the construction of the mesh;</li>
+      <li><b>Applied algorithms</b> folder containing the references
+        to the algorithms applied at the construction of the mesh.</li> 
+    </ul>
+
+    There is an alternative way to assign Algorithms and Hypotheses by
+    clicking <b>Assign a set of hypotheses</b> button and selecting among
+    pre-defined sets of hypotheses. In addition to the standard
+    sets of hypotheses, it is possible to create custom sets by editing
+    CustomMeshers.xml file located in the home directory. CustomMeshers.xml
+    file must describe sets of hypotheses in the
+    same way as ${SMESH_ROOT_DIR}/share/salome/resources/smesh/StdMeshers.xml 
+    file does (sets of hypotheses are enclosed between <hypotheses-set-group>
+      tags).
+
+      \image html hypo_sets.png
+      List of sets of hypotheses: <em>[custom]</em>
+      automatically added to the sets defined by the user
+  </li>
+</ol>
+
+Consider trying a sample script for construction of a mesh from our 
+\ref tui_creating_meshes_page "TUI Scripts" section.
+
+\anchor evaluate_anchor
+<h2>Evaluating mesh size</h2>
+
+After the mesh object is created and all hypotheses are assigned and
+before \ref compute_anchor "Compute" operation, it is possible to
+calculate the eventual mesh size. For this, select the mesh in
+the <b>Object Browser</b> and from the \b Mesh menu select \b
+Evaluate. The result of evaluation will be displayed in the following
+information box: 
+
+\image html mesh_evaluation_succeed.png
+
+\anchor preview_anchor
+<h2>Previewing the mesh</h2>
+
+Before \ref compute_anchor "the mesh computation", it is also possible
+to see the mesh preview.
 
-\image html image32.png
-<center><em>"Create Mesh" button</em></center>
+For this, select the mesh in the Object Browser. From the \b Mesh menu
+select \b Preview or click "Preview" button in the toolbar or activate
+"Preview" item from the pop-up menu.
 
-The following dialog box will appear: 
+\image html mesh_precompute.png
+<em>"Preview" button</em>
 
-\image html createmesh-inv.png
-</li>
-<li>For example, you need to mesh a 3d object.
-\n First, type the name for your mesh in the "Name" box, by default,
-it is "Mesh_1". Then select the object you wish to mesh in the Object
-Browser and click the "Add" button.
+Select <b>1D mesh</b> or <b>2D mesh</b> preview mode in the Preview dialog. 
 
-\image html image120.png
-<center><em>"Add" button</em></center>
+\image html preview_mesh_1D.png "1D mesh preview shows nodes computed on geometry edges"
+<br>
+\image html preview_mesh_2D.png "2D mesh preview shows edge mesh elements, computed on geometry faces"
 
-Now you can define 1d Algorithm and 1d Hypotheses, which will be
-applied to the edges of your object. (Note that any object has edges,
-even if their existence is not apparent, for example, a sphere has 4
-edges). Click the <em>"Add Hypothesis"</em>  button to add a hypothesis.
+<b>Compute</b> button computes the whole mesh.
 
-\image html image121.png
-<center><em>"Add Hypothesis" button</em></center>
+When the Preview dialog is closed, the question about the storage of temporarily
+created mesh elements appers:
 
-Click the <em>"Edit Hypothesis"</em> button to define values for the
-current hypothesis.
+\image html preview_tmp_data.png
 
-\image html image122.png
-<center><em>"Edit Hypothesis" button</em></center>
+These elements can be kept in the mesh.
 
-The use of additional hypotheses is optional (i.e. you may leave
-"None" in this box).
 
-Proceed in the same way with 2d and 3d Algorithms and Hypotheses, note
-that the choice of hypotheses depends on the algorithm. There must be
-one Algorithm and one or several Hypotheses for each dimension of your
-object, otherwise you will not get any mesh at all. Of course, if you
-wish to mesh a face, which is a 2d object, you don't need to define 3d
-Algorithm and Hypotheses.
-\n In the <b>Object Browser</b> the structure of the new mesh will be
-displayed as follows:
+\anchor submesh_order_anchor
+<h2>Changing submesh priority</h2>
 
-\image html image88.jpg
+If the mesh contains concurrent \ref constructing_submeshes_page "submeshes", 
+it is possible to change the priority of their computation, i.e. to
+change the priority of applying algorithms to the shared sub-shapes of
+the Mesh shape.
 
-It contains:
+<em>To change submesh priority:</em>
+
+Choose "Change submesh priority" from the Mesh menu or a pop-up
+menu. The opened dialog shows a list of submeshes in the order of
+their priority. 
+
+There is an example of submesh order modifications of the Mesh created on a Box
+shape. The main Mesh object:
+<ul>
+  <li><i>1D</i> <b>Wire discretisation</b> with <b>Number of Segments</b>=20</li>
+  <li><i>2D</i> <b>Triangle (Mefisto)</b> with Hypothesis<b>Max Element Area</b>
+  </li>
+</ul>
+The first submesh object <b>Submesh_1</b> created on <b>Face_1</b> is:
+<ul>
+  <li><i>1D</i> <b>Wire discretisation</b> with <b>Number of Segments</b>=4</li>
+  <li><i>2D</i> <b>Triangle (Mefisto)</b> with Hypothesis<b>MaxElementArea</b>=1200</li>
+</ul>
+The second submesh object <b>Submesh_2</b> created on <b>Face_2</b> is:
+<ul>
+  <li><i>1D</i> <b>Wire discretisation</b> with <b>Number of Segments</b>=8</li>
+  <li><i>2D</i> <b>Triangle (Mefisto)</b> with Hypothesis<b>MaxElementArea</b>=1200</li>
+</ul>
+
+And the last submesh object <b>Submesh_3</b> created on <b>Face_3</b> is:
 <ul>
-<li>a reference to the geometrical object on the basis of which the mesh has been constructed;</li>
-<li><b>Applied hypotheses</b> folder containing the references to the
-hypotheses applied to the construction of the mesh;</li>
-<li><b>Applied algorithms</b> folder containing the references to the
-algorithms applied to the construction of the mesh.</li>
+  <li><i>1D</i> <b>Wire discretisation</b> with <b>Number of Segments</b>=12</li>
+  <li><i>2D</i> <b>Triangle (Mefisto)</b> with Hypothesis<b>MaxElementArea</b>=1200</li>
 </ul>
 
-There is an alternative way to create a mesh on an object simply by
-clicking <b>Assign a set of hypotheses</b> button and selecting between
-Automatic Tetrahedralization or Hexahedralization.  The program will
-automatically generate a 3D mesh with the most appropriate
-settings. In the same way you can apply this functionality for meshing
-2D objects, in which case 3D algorithms are not applied.</li>
-<li>Now, when everything is ready, select your mesh in the <b>Object
-Browser</b>. From the \b Mesh menu select \b Compute or click "Compute" button of the
-toolbar. 
+The sub-meshes become concurrent if they share sub-shapes that can be
+meshed with different algorithms (or different hypothesises). In the
+example, we have three submeshes with concurrent algorithms, because
+they have different hypotheses.
+
+The first mesh computation is made with:
+<center>
+\image html mesh_order_123.png
+<em>"Mesh order SubMesh_1, SubMesh_2, SubMesh_3"</em></center>
+<center>
+\image html mesh_order_123_res.png
+<em>"Result mesh with order SubMesh_1, SubMesh_2, SubMesh_3 "</em></center>
+
+The next mesh computation is made with:
+<center>
+\image html mesh_order_213.png
+<em>"Mesh order SubMesh_2, SubMesh_1, SubMesh_3"</em></center>
+<center>
+\image html mesh_order_213_res.png
+<em>"Result mesh with order SubMesh_2, SubMesh_1, SubMesh_3 "</em></center>
+
+And the last mesh computation is made with:
+<center>
+\image html mesh_order_321.png
+<em>"Mesh order SubMesh_3, SubMesh_2, SubMesh_1"</em></center>
+<center>\image html mesh_order_321_res.png
+<em>"Result mesh with order SubMesh_3, SubMesh_2, SubMesh_1 "</em></center>
+
+As we can see, each mesh computation has a different number of result
+elements and a different mesh discretisation on the shared edges (the edges 
+that are shared between <b>Face_1</b>, <b>Face_2</b> and <b>Face_3</b>)
+
+Additionally, submesh priority (the order of applied algorithms) can
+be modified not only in a separate dialog box, but also in
+the <b>Preview</b>. This helps to preview different mesh results,
+modifying the order of submeshes. 
+<center>
+\image html mesh_order_preview.png
+<em>"Preview with submesh priority list box"</em></center>
+
+If there are no concurrent submeshes under the Mesh object, the user
+will see the following information.
+<center>
+\image html mesh_order_no_concurrent.png
+<em>"No concurrent submeshes detected"</em></center>
+
+
+\anchor compute_anchor
+<h2>Computing the mesh</h2>
+
+It is equally possible to skip  \ref evaluate_anchor "the Evaluation"
+and \ref preview_anchor "the Preview" and to \b Compute the mesh after
+the hypotheses are assigned. For this, select your mesh in
+the <b>Object Browser</b>. From the \b Mesh menu select \b Compute or
+click "Compute" button of the toolbar.
 
 \image html image28.png
-<center><em>"Compute" button</em></center>
+<em>"Compute" button</em>
 
 The Mesh Computation information box appears.
 
@@ -89,33 +256,58 @@ failure is provided.
 
 \image html meshcomputationfail.png
 
-After you select the error, <b>Show Subshape</b> button allows
-visualizing the geometrical entity that causes it.
+After you select the error, <b>Show Sub-shape</b> button allows
+visualizing in magenta the geometrical entity that causes it.
 
-\image html failed_computation.png "Example of the invalid input mesh"
+\image html failed_computation.png 
+<em>3D algorithm failed to compute mesh on a box shown using <b>Show
+    Sub-shape</b> button</em>
 
-\Note Mesh Computation Information box does not appear if you set
+
+\note Mesh Computation Information box does not appear if you set
 "Mesh computation/Show a computation result notification" preference 
 to the "Never" value. This option gives the possibility to control mesh
 computation reporting. There are the following possibilities: always
 show information box, only if an error occurs or never. 
 By default, the information box is always shown after mesh computation operation.
 
-<b>Publish Subshape</b> button publishes the subshape, whose meshing
+<b>Publish Sub-shape</b> button publishes the sub-shape, whose meshing
 failed, in GEOM component as a child of the mesh geometry, which
 allows analyzing the problem geometry and creating a submesh on it in
 order to locally tune hypotheses.
 
-<b>NOTE</b> It is possible to define a 1D or a 2D mesh in a
-python script and then use such submeshes in the construction of a 3D
-mesh. For this, there exist two algorithms: <b>Use existing edges</b> and <b>Use
-existing faces</b>. They are not entirely usable from the GUI, so a
-mesh created using these algorithms should be exported into a python
-script, edited and then imported into the GUi. 
+If a cause of failure is an invalid input mesh and the algorithm has
+provided information on what mesh entities are bad <b>Show bad Mesh</b> 
+button appears in the dialog. Clicked, it shows bad mesh entities in
+the Viewer in magenta. Sometimes the shown mesh entities are too small
+or/and hidden by other mesh elements, to see them it can be helpful to
+switch the mesh to Wireframe visualization mode or to switch off
+visualization of faces and volumes (if any).
 
-Consider trying a sample script for construction of a mesh from our 
-\ref tui_creating_meshes_page "TUI Scripts" section.
-</li>
-</ol>
+\anchor use_existing_anchor
+<h2>"Use existing edges" and "Use existing faces" algorithms</h2>
+
+It is possible to create an 1D or a 2D mesh in a python script
+(using <em>AddNode, AddEdge</em> and <em>AddFace</em> commands) and
+then use such sub-meshes in the construction of a 2D or a 3D mesh. For
+this, there exist two algorithms: <b>Use existing edges</b> and <b>Use
+  existing faces</b>. Scenario of their usage is following. For
+example, you want to use standard algorithms to generate 1D and 3D
+meshes and to create 2D mesh by your python code. Then you
+<ul>
+  <li> create a mesh object, assign an 1D algorithm,</li>
+  <li> invoke \b Compute command, which computes an 1D mesh,</li>
+  <li> assign <b>Use existing faces</b> and a 3D algorithm,</li>
+  <li> run your python code, which creates a 2D mesh,</li>
+  <li> invoke \b Compute command, which computes a 3D mesh.</li>
+</ul>
+
+Consider trying a sample script demonstrating usage of 
+\ref tui_use_existing_faces "Use existing faces" algorithm for
+construction of a 2D mesh using Python commands.
+
+\image html use_existing_face_sample_mesh.png
+<em> Mesh computed by \ref tui_use_existing_faces "the sample script"
+  shown in a Shrink mode.</em>
 
-*/
\ No newline at end of file
+*/
index a17569f7cb9188541ad3df343491f3b68bc8e27e..f300d6f50e125a426e201beabb7fb09452c6b277 100644 (file)
@@ -1,41 +1,43 @@
 /*!
 
-\page constructing_submeshes_page Constructing submeshes
+\page constructing_submeshes_page Constructing sub-meshes
 
-Submesh is a mesh on a geometrical subobject created with algorithms
+Sub-mesh is a mesh on a geometrical sub-object created with algorithms
 and/or hypotheses other than the algorithms and hypotheses assigned to
 the parent mesh on the parent object.
 <br><br>
-If a geometrical subobject belongs to several geometrical objects
-having different meshes or submeshes, it will be meshed with the
-hypotheses of a submesh of a lower dimension.<br>
-For example, a face of a box is meshed with a submesh using algorithms
+If a geometrical sub-object belongs to several geometrical objects
+having different meshes or sub-meshes, it will be meshed with the
+hypotheses of a sub-mesh of a lower dimension.<br>
+For example, a face of a box is meshed with a sub-mesh using algorithms
 and hypotheses other than the parent mesh on the whole box. The face
 and the box share four edges, which will be meshed with algorithms and
-hypotheses of the submesh on the face, because the face is a 2D object
+hypotheses of the sub-mesh on the face, because the face is a 2D object
 while the box is a 3D object.  <br>
  If the dimensions are the same, an arbitrary algorithm/hypothesis
  will be used. This means that an edge shared by two faces each having
- its own different submesh, will be meshed using algorithms and
- hypotheses of any of the two, chosen randomly. <br>
+ its own different sub-mesh, will be meshed using algorithms and
+ hypotheses of any of the two, chosen randomly. This indeterminacy can
+ be fixed by defining \ref submesh_order_anchor "Sub-mesh priority".
+<br>
 
-\n Construction of a submesh consists of:
+\n Construction of a sub-mesh consists of:
 <ul>
-<li>Selecting a mesh which will encapsulate your submesh</li>
+<li>Selecting a mesh which will encapsulate your sub-mesh</li>
 <li>Selecting a geometrical object for meshing</li>
 <li>Applying one or several previously described 
 \ref about_hypo_page "hypotheses" and 
 \ref basic_meshing_algos_page "meshing algorithms" which will be used
-at computation of this submesh</li>
+at computation of this sub-mesh</li>
 </ul>
 
-<br><em>To construct a submesh:</em>
+<br><em>To construct a sub-mesh:</em>
 \par
-From the \b Mesh menu select <b>Create Submesh</b> or click <em>"Create
+From the \b Mesh menu select <b>Create Sub-mesh</b> or click <em>"Create
 Sum-mesh"</em> button in the toolbar.
 
 \image html image33.gif
-<center><em>"Create Submesh" button</em></center>
+<center><em>"Create Sub-mesh" button</em></center>
 
 \par
 The following dialog box will appear:
@@ -45,11 +47,11 @@ The following dialog box will appear:
 \par
 It allows to define the \b Name, the parent \b Mesh and the \b
 Geometry (e.g. a face if the parent mesh has been built on box) of the
-submesh. You can define algorithms and hypotheses in the same way as
+sub-mesh. You can define algorithms and hypotheses in the same way as
 in \ref constructing_meshes_page "Create mesh" menu.
 
 \par
-In the Object Browser the structure of the new submesh will be
+In the Object Browser the structure of the new sub-mesh will be
 displayed as follows:
 
 \image html image10.jpg
@@ -57,14 +59,14 @@ displayed as follows:
 \par
 It contains:
 <ul>
-<li>a reference to the geometrical object on the basis of which the submesh has been constructed;</li>
+<li>a reference to the geometrical object on the basis of which the sub-mesh has been constructed;</li>
 <li><b>Applied hypotheses</b> folder containing the references to the
-hypotheses applied to the construction of the submesh;</li>
+hypotheses applied to the construction of the sub-mesh;</li>
 <li><b>Applied algorithms</b> folder containing the references to the
-algorithms applied to the construction of the submesh.</li>
+algorithms applied to the construction of the sub-mesh.</li>
 </ul>
 
 <br><b>See Also</b> a sample TUI Script of a 
-\ref tui_construction_submesh "Construct Submesh" operation.
+\ref tui_construction_submesh "Construct Sub-mesh" operation.
 
 */
index 072a91f7a2340e80faad891b883f5d03e52c2e97..66f850664e8625b54b175f16f303844b25d9d7c3 100644 (file)
@@ -2,14 +2,20 @@
 
 \page convert_to_from_quadratic_mesh_page Convert to/from Quadratic Mesh
 
-\n This functionality allows you to transtorm standard meshes to
-quadratic and vice versa. See \ref adding_quadratic_elements_page "Adding quadratic elements" 
+\n This functionality allows transforming standard meshes (or
+sub-meshes) to quadratic and vice versa. 
+See \ref adding_quadratic_elements_page "Adding quadratic elements" 
 for more information about quadratic meshes.
+Note that conversion of a sub-mesh most probably will
+produce a non-conformal mesh. Elements on the boundary between
+quadratic and linear sub-meshes become (or remain) quadratic.
 
 <em>To produce a conversion:</em>
 <ol>
-<li>From the Modification menu choose the Convert to/from Quadratic
-Mesh item, or click <em>"Convert to/from quadratic"</em> button in the
+<li>Select a mesh or a sub-mesh in the Object Browser or in the
+Viewer.</li>
+<li>From the Modification menu choose <b> Convert to/from Quadratic
+Mesh item </b>, or click <em>"Convert to/from quadratic"</em> button in the
 toolbar.
 
 \image html image154.png
@@ -20,11 +26,17 @@ The following dialog box will appear:
 \image html convert.png
 
 </li>
-<li>In this dialog box you should select:
+<li>In this dialog box specify:
 
 <ul>
-<li>if you wish to convert standard mesh to quadratic or quadratic to standard;</li>
-<li>if you wish to place medium nodes of the quadratic mesh on the geometry (meshed object).</li>
+<li>if it is necessary to convert a standard mesh to quadratic or a quadratic
+mesh to standard. Note that the choice is available only if the selected mesh
+(or sub-mesh) contains both quadratic and linear elements, else the
+direction of conversion is selected automatically.</li>
+
+<li>if it is necessary to place medium nodes of the quadratic mesh on the
+geometry (meshed object). This option is relevant for conversion to
+quadratic provided that the mesh is based on a geometry (not imported from file).</li>
 </ul>
 
 \image html image156.gif
@@ -37,4 +49,6 @@ The following dialog box will appear:
 <li>Click the \b Apply or \b OK button.</li>
 </ol>
 
-*/
\ No newline at end of file
+<br><b>See Also</b> a sample TUI Script of a \ref tui_quadratic "Convert to/from quadratic" operation.
+
+*/
diff --git a/doc/salome/gui/SMESH/input/copy_mesh.doc b/doc/salome/gui/SMESH/input/copy_mesh.doc
new file mode 100644 (file)
index 0000000..2c65ab8
--- /dev/null
@@ -0,0 +1,56 @@
+/*!
+
+\page copy_mesh_page Copy Mesh
+
+\n A mesh can be created by copying a part of or the whole other mesh.
+
+<em>To make a copy of a mesh:</em>
+
+\par
+From the \b Mesh menu select <b>Copy Mesh</b> or click <em>"Copy Mesh"</em>
+button in the toolbar.
+
+\image html copy_mesh_icon.png
+<center><em>"Copy Mesh" button</em></center>
+
+\par
+The following dialog box will appear:
+
+\image html copy_mesh_dlg.png
+
+\par
+In the dialog:
+<ul>
+<li>specify the part of mesh to copy:
+
+<ul>
+<li><b>Select the whole mesh, submesh or group</b> by mouse activating
+this checkbox; or</li>
+<li>choose mesh elements with the mouse in the 3D Viewer. It is
+possible to select a whole area with a mouse frame; or</li> 
+<li>input the <b>Source Element IDs</b> directly in this field. The
+selected elements will be highlighted in the viewer; or</li>
+<li>apply Filters. <b>Set filter</b> button allows to apply a filter
+to the selection of elements. See more about filters in the \ref
+selection_filter_library_page "Selection filter library" page.</li>
+</ul>
+</li>
+
+<li>specify the <b>New Mesh Name</b>;</li>
+
+<li>specify the conditions of copying:
+<ul>
+<li>activate <b>Generate groups</b> checkbox to copy the groups of
+elements of the source mesh to the newly created mesh.</li>
+<li>activate <b>Preserve IDs of elements</b> checkbox to keep
+the IDs of new nodes and elements the same as the IDs of source nodes
+and elements.</li>
+</ul>
+</li>
+
+<li>Click \b Apply or <b>Apply and Close</b> button to confirm the operation.</li>
+</ul>
+
+<b>See Also</b> a sample 
+\ref tui_copy_mesh "TUI Example of mesh copying."
+*/
diff --git a/doc/salome/gui/SMESH/input/create_groups_from_geometry.doc b/doc/salome/gui/SMESH/input/create_groups_from_geometry.doc
new file mode 100755 (executable)
index 0000000..a09272c
--- /dev/null
@@ -0,0 +1,17 @@
+/*!
+
+\page create_groups_from_geometry_page Create Groups from Geometry
+
+To use this operation, select in the \b Mesh menu <b>Create Groups from Geometry</b>.
+
+\image html create_groups_from_geometry.png
+
+This operation allows  creating  on a selected geometry several groups consisting of
+elements of all types.
+The group names will be the same as the names of geometrical objects.
+The Type of group of mesh elements is defined automatically by the nature of
+the <b>Geometric object</b>.
+
+
+*/
index 0e89b980d9b7cd49e2e5e645027b40bac75ad677..966e091fe04a83a4fd0970ab76ca81e0447ff651 100644 (file)
@@ -2,12 +2,13 @@
 
 \page creating_groups_page Creating groups
 
-\n In MESH you can create groups of elements of different types. To
-create a group of elements in the \b Mesh menu select <b>Create
-Group</b>.
-\n To create any group you should define the following:
+\n In MESH you can create a group of elements of a certain type. The
+contents of the group can be defined in different ways. To create a group, in the \b
+Mesh menu select <b>Create Group</b> item (also available in the
+context menu of the mesh).<br> 
+To create a group of any type you should define the following: 
 <ul>
-<li><b>Mesh</b> - the name of the mesh whose elements will form your
+<li><b>Mesh</b> - the mesh whose elements will form your
 group. You can select your mesh in the Objet Browser or in the 3D
 viewer.</li>
 <li><b>Elements Type</b> - set of radio buttons allows to select the type of
@@ -19,131 +20,121 @@ elements which will form your group:</li>
 <li><b>Volumes</b></li>
 </ul>
 <li><b>Name</b> field allows to enter the name of your new group.</li>
+<li><b>Color</b> - allows to assign to the group a certain color, for
+example, defining boundary conditions. The chosen color is used to
+display the elements of the group. The color attribute of the group is
+not persistent, it is lost if you save and then load the study from
+the file.</li>
 </ul>
-SALOME Platform distinguishes between the two Group types:
-<b>Standalone Group</b> and <b>Group on Geometry</b>.
+SALOME Platform distinguishes between the three Group types:
+<b>Standalone Group</b>, <b>Group on Geometry</b> and <b>Group on Filter</b>.
 
-<br><h2>Standalone Group</h2>
+\anchor standalone_group <br><h2>"Standalone Group"</h2>
 
-<b>Standalone Group</b> consists of mesh elements, which you can define in
-two possible ways.
+<b>Standalone Group</b> contains a list of mesh elements, which you can define in
+the following ways:
 <ul>
-<li>Choosing them manually with the mouse in the 3D Viewer. You can
-click on an element in the 3D viewer and it will be highlighted. After
-that click the \b Add button and the ID of this element will be added to
-the list.</li>
-<li>Applying Filters. The <b>Set filter</b> button allows to apply a
-definite filter to selection of the elements of your group. See more
-about filters on the
-\ref selection_filter_library_page "Selection filter library" page.</li>
+<li>By adding all entities of the chosen type existing in the
+  mesh. For this, turn on the <b>Select All</b> check box. In this mode
+  all controls, which allow selecting the entities in other ways, are
+  disabled.</li>
+<li>By applying the Filter. The <b>Set filter</b> button allows to
+  define the filter for selection of the elements for your group. See more
+  about filters on the 
+  \ref selection_filter_library_page "Selection filter library" page.<br>
+  If the <b>Enable manual edition</b> check box is turned off, the 
+  filter entirely defines the group contents. In this mode, the filter is
+  applied to all elements of the mesh. If there are no entities
+  corresponding to the filter, the \b Apply button is disabled.<br>
+  If the <b>Enable manual edition</b> check box is turned on, the defined
+  filter can be used to for selection of entities for the group.</li>
+<li>By choosing entities manually with the mouse in the 3D Viewer. For
+  this, turn on the <b>Enable manual edition</b> check box. You can
+  click on an element in the 3D viewer and it will be highlighted. After
+  that click the \b Add button and the ID of this element will be
+  added to the list.</li>
+<li>By adding entities from either a submesh or an existing
+  group.  For this, turn on the <b>Enable manual edition</b> check
+  box. <b>Select from</b> set of fields allows to select a submesh or
+  a group of the appropriate type.</li>
+</ul>
+In the <b>manual edition</b> mode you can
+<ul>
+<li>click the \b Remove button to remove the selected elements from the list</li>
+<li>click the <b>Sort List</b> button to sort the list of IDs of 
+mesh elements.</li>
 </ul>
-To remove a selected element or elements from the list click the
-\b Remove button. The <b>Sort List</b> button allows to sort the list of IDs of
-mesh elements.
-\n <b>Select from</b> set of fields allows to choose a submesh or an existing
-group whose elements of the previously defined type will be added to
-the list of elements which will form your group.
-\n <b>Color</b> - allows to assign to the group a certain color, for
-example, defining boundary conditions. This feature introduces a
-useful element of preprocessing in Mesh module. Note that <b>Color</b> attribute defines
-the colors used for the display of the elements of the group. 
-\n <b>Warning</b> The Med Color group interface may change in future versions of Salome.
-
 
 \image html creategroup.png
 
+
+For example, to create a new group containing all faces of an
+existing group and some other faces selected in the viewer:
+<ul>
+<li> Select the \b Face type of entities and input the name of the new group.</li>
+<li> Check the \b Group checkbox in <b>Select From</b> group.</li>
+<li> Select the existing group of faces in the object browser or in the viewer</li>
+<li> Click \b Add in \b Content group. <b>Id Elements</b> list will be filled
+with IDs of faces belonging to the exising group.</li>
+<li> Select other faces in the viewer.</li>
+<li> Click \b Add in \b Content group.</li>
+<li> Click \b Apply button to create the new group.</li>
+</ul>
+
+Please note that the new group does not have references to the source
+group. It contains only the list of face IDs. So if the source group
+is changed, the new one is not updated accordingly.
+
+
 \image html image130.gif
-<center>In this picture the brown cells belong to a group defined manually.</center>
+<center>In this picture the brown cells belong to a group defined
+  manually.</center> 
 
 \image html image131.gif
-<center>In this picture the brown cells belong to the group defined by the criterion 
-<b>Taper > 0</b>.</center>
+<center>In this picture the brown cells belong to the group defined by
+  the criterion <b>Taper > 0</b>.</center>
 
 <b>See Also</b> a sample TUI Script of a 
 \ref tui_create_standalone_group "Create a Standalone Group"
 operation.  
 
-<br><h2>Group on Geometry</h2>
-
-To create a group on geometry check <b>Group on geometry</b> in the \b Group
-\b type field. <b>Group on geometry</b> contains the elements of a certain type
-belonging to the selected geometrical object. To define a group select
-in the Objet Browser or in the 3D viewer a geometrical object from
-which the elements will be taken. After confirmation of the operation
-a new group of mesh elements will be created.
 
-\image html a-creategroup.png
+\anchor group_on_geom <br><h2>"Group on Geometry"</h2>
 
-<br><br>
-To create multiple groups on geometry of both nodes and elements of
-any type at once, in the \b Mesh menu select <b>Create Groups from
-Geometry</b>.<br>
-Group names are same as those of geometrical objects.
-Type of group of mesh elements is defined automatically by 
-<b>Geometrical object</b> nature.
+To create a group on geometry check <b>Group on geometry</b> in the \b
+Group \b type field. The group on geometry contains the elements
+of a certain type generated on the selected geometrical object. Group
+contents are dynamically updated if the mesh is modified.<br>
+To define a group, select in the Objet Browser or in the 3D viewer a
+geometrical object from which the elements will be taken. After
+confirmation of the operation a new group of mesh elements will be
+created.
 
-\image html create_groups_from_geometry.png
+\image html a-creategroup.png
 
 \image html image132.gif
-<center>In this picture the cells which belong to a certain face are
-selected in green.</center>
+<center>In this picture the cells which belong to a certain
+  geometrical face are selected in green.</center>
 
 <b>See Also</b> a sample TUI Script of a 
 \ref tui_create_group_on_geometry "Create a Group on Geometry"
 operation.
 
-<br><h2>Creation of groups using existing groups and sub-meshes.</h2>
-
-Application provides possibility to create new <b>standalone</b> groups using existing standalone groups, groups on geometry and sub-meshes. This functionality is implemented using "Select from" group box of "Create group" dialog box described above.
-
-This functionality is described on the example of creating new group   from existing standalone groups and groups on geometry.
-
-Imagine there are group G1. It can be standalone group or group on geometry.
 
-To create group G2 containing all entities of group G1 and a faces graphically selected in 3D view following steps can be performed:
-<ul>
-<li>User opens "Create group" dialog box.</li>
-<li>The user specifies "Face" type of entities and "G2" name of group.</li>
-<li>The user checks "Group" check-box of "Select From" group box.</li>
-<li>The user selects G1 group in object browser or 3D view.</li>
-<li>The user presses "Add" push button of "Content" group box. "Id Elements" list-box is filled with identifiers of faces belonging to group G1.</li>
-<li>The user selects other faces in 3D view.</li>
-<li>The user presses "Apply" button. System creates group G2.</li>
-</ul>
-
-Please note that group G2 does not have a references to source group G1. It contains list of faces identifiers only. So if G1 group will be changed group G2 will remain unmodified.
-
-<br>
-\anchor gui_create_dim_group
-<h2>Creating groups of entities from existing groups of superior dimensions</h2>
-
-Application provides possibility for creating groups of entities from existing groups of superior dimensions. For example, it is possible to create group of nodes using list of existing groups of faces.
-
-To create groups of entities from existing groups of superior dimensions, in the \b Mesh menu select <b>Group of underlying entities</b>.<br>
-
-The following dialog box will appear:
-
-\image html dimgroup_dlg.png
+\anchor group_on_filter <br><h2>"Group on Filter"</h2>
 
-In this dialog box you should specify the name of the resulting group, types of entities and set of source groups.
+To create a group on filter check <b>Group on filter</b> in the <b>
+Group type</b> field. The group on filter contains the elements
+of a certain type satisfying the defined filter. Group contents are
+dynamically updated if the mesh is modified.<br> To define a group,
+click the <b>Set filter</b> button and define criteria of the
+filter in the opened dialog. After confirmation of the operation a
+new group of mesh elements will be created. See more about filters on
+the \ref selection_filter_library_page "Selection filter library" page.
 
-For example, we have two source Volume groups illustrated on the figure below 
-
-\image html dimgroup_src.png
-<center>Source groups</center>
-
-In this case we obtain following results for Faces, Edges and Nodes.
-
-\image html dimgroup_2d.png
-<center>Faces</center>
-
-\image html dimgroup_1d.png
-<center>Edges</center>
-
-\image html dimgroup_0d.png
-<center>Nodes</center>
+\image html creategroup_on_filter.png
 
 <b>See Also</b> a sample TUI Script of a 
-\ref tui_create_dim_group "Creating groups of entities from existing groups of superior dimensions"
-operation.
-*/
\ No newline at end of file
+\ref tui_create_group_on_filter "Create a Group on Filter" operation.
+
+*/
diff --git a/doc/salome/gui/SMESH/input/cut_mesh_by_plane.doc b/doc/salome/gui/SMESH/input/cut_mesh_by_plane.doc
new file mode 100644 (file)
index 0000000..9befdbb
--- /dev/null
@@ -0,0 +1,55 @@
+/*!
+
+\page cut_mesh_by_plane_page Cut a tetrahedron mesh by a plane
+
+\n MeshCut works only with MED files and produces MED files, and is a standalone program.
+It can be used either directly from a command shell outside SALOME, or with a GUI interface in SMESH,
+provided in a python plugin that needs to be installed in your SALOME application.
+
+\n MeshCut allows to cut a mesh constituted of linear tetrahedrons by a plane.
+\n The tetrahedrons intersected by the plane are cut and replaced by elements of various types,
+(tetrahedron, pyramid, pentahedron).
+
+<br>
+\anchor meshcut_standalone
+<h2>Using MeshCut as a standalone program, outside SALOME</h2>
+
+\n MeshCut is a standalone program, reading and producing med files.                
+\n                 
+\n Syntax:
+\code
+MeshCut input.med output.med resuMeshName aboveGroup belowGroup nx ny nz px py pz T
+\endcode
+
+\n                 
+\n where:
+\n  input.med    = name of the original mesh file in med format
+\n  output.med   = name of the result mesh file in med format
+\n  resuMeshName = name of the result mesh
+\n  aboveGroup   = name of the group of volumes above the cut plane
+\n  belowGroups  = name of the group of volumes below the cut plane
+\n  nx ny nz     = vector normal to the cut plane
+\n  px py pz     = a point of the cut plane
+\n  T            = 0 < T < 1 : vertices of a tetrahedron are considered as belonging to
+\n                 the cut plane if their distance from the plane is inferior to L*T,
+\n                 where L is the mean edge size of the tetrahedron
+
+<br>
+\anchor meshcut_plugin
+<h2>Using MeshCut inside SALOME</h2>
+
+When the MeshCut plugin is installed, it can be found in the Mesh menu, sub-menu SMESH_plugins.
+\n If the plugin is not installed, the file meshcut_plugin.py is in
+SMESH installation in  subdirectory bin/salome/meshcut_plugin.py.
+
+\n If there are already plugins defined in a smesh_plugins.py file,
+ this file should be added at the end.
+ if not, copied as ${HOME}/Plugins/smesh_plugins.py or ${APPLI}/Plugins/smesh_plugins.py
+ or in ${PLUGINPATH} Directory.
+From the Mesh menu, sub-menu SMESH_plugins, choose "MeshCut" item
+The following dialog box will appear:
+\image html meshcut_plugin.png "MeshCut Plugin dialog box"
+
+See above for the meaning of the parameters. 
+*/
index 21eea88dfbaf64c44bd498d6beef7115a072ca10..86addcf5d8d0257d2d3abad3ad69bc2966900174 100644 (file)
@@ -1,8 +1,8 @@
 /*!
 
-\page deleting_groups_page Deleting Groups
+\page deleting_groups_page Deleting groups with content
 
-\n To delete a group in the <b>Main Menu</b> select <b>Mesh -> Delete Groups</b> and
+\n To delete groups and their content in the <b>Main Menu</b> select <b>Modification -> Remove -> Delete groups with Contents</b> and
 select one or several groups you wish to delete in the 3D viewer or in
 the Object Browser.
 \n The selected groups will be listed in <b>Delete groups with contents</b>
@@ -16,4 +16,4 @@ elements</b>. To delete a group and leave its elements intact, right-click
 on the group in the Object Browser and select \b Delete in the pop-up
 menu or select the group and choose <b>Edit -> Delete</b> in the <b>Main Menu</b>.
 
-*/
\ No newline at end of file
+*/
diff --git a/doc/salome/gui/SMESH/input/double_elements_control.doc b/doc/salome/gui/SMESH/input/double_elements_control.doc
new file mode 100644 (file)
index 0000000..63ee0e7
--- /dev/null
@@ -0,0 +1,14 @@
+/*!
+
+\page double_elements_page Double edge, Double faces and Double volumes
+
+These mesh quality controls highlight the mesh elements basing on the same set of nodes.
+
+\image html double_faces.png
+
+In this picture some faces are coincident after copying all elements
+with translation with subsequent Merge of nodes.
+
+\sa A sample TUI Script of a \ref filter_double_elements "Filters of Double Elements".
+
+*/
diff --git a/doc/salome/gui/SMESH/input/double_nodes_control.doc b/doc/salome/gui/SMESH/input/double_nodes_control.doc
new file mode 100644 (file)
index 0000000..75fd292
--- /dev/null
@@ -0,0 +1,16 @@
+/*!
+
+\page double_nodes_control_page Double nodes
+
+This mesh quality control highlights the nodes which are coincident
+with other nodes (within a given tolerance). Distance at which two
+nodes are considered coincident is defined by "Quality Controls/Double
+nodes tolerance" preference.
+
+\image html double_nodes.png
+
+In this picture some nodes are coincident after copying all elements with translation.
+
+\sa A sample TUI Script of a \ref tui_double_nodes_control "Double Nodes" filter.
+
+*/
diff --git a/doc/salome/gui/SMESH/input/double_nodes_page.doc b/doc/salome/gui/SMESH/input/double_nodes_page.doc
new file mode 100644 (file)
index 0000000..a8a93d1
--- /dev/null
@@ -0,0 +1,72 @@
+/*!
+
+\page double_nodes_page Duplicate Nodes
+
+\n This operation allows to duplicate nodes of your mesh, which can be
+useful to emulate a crack in the model.
+Duplication consists in replacement of an existing mesh element by another one.
+Lower level elements of the duplicated ones are cloned automatically. 
+
+<em>To duplicate nodes:</em>
+<ol>
+<li>From the \b Modification menu choose \b Transformation -> \b Duplicate
+\b Nodes item or click <em>"Duplicate Nodes"</em> button in the toolbar.
+<br>
+\image html duplicate_nodes.png "Duplicate Nodes button"
+</li>
+<li>Check in the dialog box one of two radio buttons corresponding to
+the type of nodes duplication operation you would like to perform.</li>
+<li>Fill the other fields available in the dialog box (depends on the chosen
+ operation mode).</li>
+<li>Click the \b Apply or <b>Apply and Close</b> button to perform the operation of nodes
+ duplication.</li>
+</ol>
+
+\n "Duplicate Nodes" dialog has two working modes:
+<ul>
+<li>\ref mode_without_elem_anchor "Without the duplication of border elements"</li>
+<li>\ref mode_with_elem_anchor "With the duplication of border elements"</li>
+</ul>
+
+<br>
+\anchor mode_without_elem_anchor
+<h2>Without duplication of border elements</h2>
+
+In this mode the dialog looks like:
+
+\image html duplicate01.png
+
+Parameters to be defined in this mode:
+<ul>
+<li><b>Group of nodes to duplicate</b> (<em>mandatory</em>): these nodes will be duplicated.</li>
+<li><b>Group of elements to replace nodes with new ones</b> (<em>optional</em>): the duplicated nodes
+ will be associated with these elements.</li>
+<li><b>Construct group with newly created nodes</b> option (<em>checked by default</em>): 
+ if checked - the group with just created nodes will be built.</li>
+</ul>
+
+<br>
+\anchor mode_with_elem_anchor
+<h2>With duplication of border elements</h2>
+
+In this mode the dialog looks like:
+
+\image html duplicate02.png
+
+Parameters to be defined in this mode:
+<ul>
+<li><b>Group of elements to duplicate</b> (<em>mandatory</em>): these elements will be duplicated.</li>
+<li><b>Group of nodes at not to duplicate</b> (<em>optional</em>): group of nodes at crack bottom
+ which will not be duplicated.</li>
+<li><b>Group of elements to replace nodes with new ones</b> (<em>mandatory</em>): the duplicated nodes
+ will be associated with these elements.</li>
+<li><b>Construct group with newly created elements</b> option (<em>checked by default</em>): 
+ if checked - the group of just created elements will be built.</li>
+<li><b>Construct group with newly created nodes</b> option (<em>checked by default</em>): 
+ if checked - the group of just created nodes will be built.</li>
+</ul>
+
+
+<br><b>See Also</b> a sample TUI Script of a \ref tui_duplicate_nodes "Duplicate nodes" operation.
+
+*/
index b5031468ae0ad0e2387ff0da04a87eaf08439b0a..ca9b7a2228f5d652b2c776b5edaacf972d931582 100644 (file)
@@ -2,7 +2,7 @@
 
 \page editing_groups_page Editing groups
 
-\n <em>To edit an existing group of elements:</em>
+<em>To edit an existing group of elements:</em>
 <ol>
 <li>Select your group in the Object Browser and in the \b Mesh menu click
 the <b>Edit Group</b> item or <em>"Edit Group"</em> button in the toolbar.</li>
@@ -14,28 +14,34 @@ The following dialog box will appear:
 
 \image html editgroup.png
 
-In this dialog box you can modify the name of your group and add or
-remove the elements forming it. For more information see 
+In this dialog box you can modify the name and the color of your group
+despite of its type. You can add or remove the elements forming a
+<em>standalone group</em>. You can change criteria of the filter of
+the <em>group on filter</em>. For more information see
 \ref creating_groups_page "Creating Groups" page.
-<li>Click the \b Apply or <b>Apply and Close</b> button to confirm modification of the
-group.</li>
+
+<li>Click the \b Apply or <b>Apply and Close</b> button to confirm
+modification of the group.</li>
 </ol>
 
-\n <em>To convert an existing group on geometry into standalone group
-of elements and modify:</em>
+\anchor convert_to_standalone
+<em>To convert an existing group on geometry or a group on filer into
+a standalone group of elements and modify:</em>
 <ol>
-<li>Select your group on geometry in the Object Browser and in the \b Mesh menu click
-the <b>Edit Group as Standalone</b> item.</li>
+<li>Select your group on geometry (or your group on filter) in the
+Object Browser and in the \b Mesh menu click the <b>Edit Group as
+Standalone</b> item.</li> 
 
 \image html image74.gif
 <center><em>"Edit Group as Standalone" button</em></center>
 
-The group on geometry will be converted into standalone group and can
-be modified as group of elements
+The selected group will be converted into a standalone group and 
+its contents can be modified.
+
 <li>Click the \b Apply or <b>Apply and Close</b> button to confirm modification of the
 group.</li>
+</ol>
 
-<br><b>See Also</b> a sample TUI Script of an 
-\ref tui_edit_group "Edit Group" operation.  
+\sa A sample TUI Script of an \ref tui_edit_group "Edit Group" operation.  
 
 */
index ea25158f1eff42bdb57cc0b6c082fb091ad16bbb..1b343808493524328d962bb8f1f856a0a017bd18 100644 (file)
@@ -16,38 +16,45 @@ and Hexahedron solids respectively.
 \image html image91.png
 <center><em>"Extrusion" button</em></center>
 
-The following dialog box will appear:
+The following dialog common for line and planar elements will appear:
 
 \image html extrusionalongaline1.png
 
 \image html extrusionalongaline2.png
+
 </li>
 
-<li>In this dialog box you should select:
+<li>In this dialog:
 <ul>
-<li>the type of elements which will be extruded (1D or 2D),</li>
-<li>specify the IDs of the elements which will be extruded by
-selecting them in the 3D viewer or select the whole mesh or
-submesh,
+<li>select the type of elements which will be extruded (0D, 1D or 2D),</li>
+<li>specify the IDs of the elements which will be extruded:
 <ul>
-<li>Check on <b>Select the whole mesh, submesh or group</b> option
-<li>Choosing them manually with the mouse in the 3D Viewer. You can
-click on an element in the 3D viewer and it will be highlighted</li>
-<li>Applying Filters. The <b>Set filter</b> button allows to apply a
-definite filter to selection of the elements. See more
-about filters on the
-\ref selection_filter_library_page "Selection filter library" page.</li>
+<li><b>Select the whole mesh, submesh or group</b> activating this
+checkbox; or</li>
+<li>choose mesh elements with the mouse in the 3D Viewer. It is
+possible to select a whole area with a mouse frame; or</li> 
+<li>input the element IDs directly in <b>ID Elements</b> field. The selected elements will be highlighted in the
+viewer; or</li>
+<li>apply Filters. <b>Set filter</b> button allows to apply a filter to the selection of elements. See more
+about filters in the \ref selection_filter_library_page "Selection filter library" page.</li>
 </ul>
 </li>
+<li>If the <b>Extrude to Distance</b> radio button is selected</li>
+<ul>
 <li>specify the distance at which the elements will be extruded,</li>
-<li>specify the vector along which the elements will be extruded,</li>
-<li>number of steps.</li>
 </ul>
-<li> <b>Generate Groups</b> checkbox allows copying the groups of
+<li>If the <b>Extrude Along Vector</b> radio button is selected</li>
+<ul>
+<li>specify the coordinates of the vector along which the elements will be extruded, or select the face (the normal to the face will define the vector)</li>
+<li>specify the distance of extrusion along the vector,</li>
+</ul>
+<li>specify the number of steps;</li>
+<li>activate  <b>Generate Groups</b> checkbox if it is necessary to copy the groups of
 elements of the source mesh to the newly created one. </li>
 </li>
+</ul>
 
-<li>Click the \b Apply or \b OK button.</li>
+<li>Click \b Apply or <b> Apply and Close</b>  button to confirm the operation.</li>
 </ol>
 
 \image html image77.jpg "The mesh with an edge selected for extrusion"
index d35d233151c133404d8cf5e6e7a1f677d719d4a5..e391111d80f48271bdaa8c6c958780dcc9b9b9bb 100644 (file)
@@ -4,13 +4,14 @@
 
 \n In principle, <b>Extrusion along a path</b> works in the same way
 as \b Extrusion, the main difference is that we define not a vector,
-but a path of extrusion which must be a meshed edge. To get an idea of
-how this algorithm works, examine several examples, starting from the
-most simple case of extrusion along a straight edge. In all examples
-the same mesh will be extruded along different paths and with
-different parameters. This sample 2D mesh has two quadrangle faces and
-seven edges. Look at the picture, where white digits are the node
-numbers and green are the element numbers:
+but a path of extrusion which must be a 1D mesh or 1D sub-mesh. 
+To get an idea of how this algorithm works, examine several examples,
+starting from the most simple case of extrusion along a straight edge.
+In the examples the sample mesh will be extruded along different
+paths and with different parameters.
+This 2D mesh has two quadrangle faces and seven edges. Look
+at the picture, where white digits are the node numbers and green
+are the element numbers:
 
 \image html mesh_for_extr_along_path.png
 
@@ -40,29 +41,17 @@ been selected as <b>Start node</b>.</center>
 \image html curvi_angles_after.png
 <center>The same, but using angles {45, 45, 45, 0, -45, -45, -45}</center>
 
-<br><center><h2>Extrusion along a sub-mesh</h2></center>
+<br><center><h2>Extrusion of a 2D face along a mesh built on a wire</h2></center>
 
-In this example the path mesh has been built on a wire (polyline with
-six edges). The first edge of the wire was used as <b>Shape (edge)</b>, node
-#1 as <b>Start node</b>. The angles have been defined as {10, 10, 10}. The
-middle edge (#4) of the initial mesh has been extruded.
+In this example the path mesh has been built on a wire containing 3
+edges. Node 1 is a start node. Linear angle variation by 180 degrees
+has also been applied.
 
-\image html edge_wire_before.png
+\image html extr_along_wire_before.png
+<center><em>Meshed wire</em></center>
 
-\image html edge_wire_after.png
-
-<br><center><h2>Extrusion of 2d elements along a sub-mesh</h2></center>
-
-This extrusion bases on the same path mesh as in the previous example
-but the third edge of the wire was set as <b>Shape (edge)</b> and node
-#4 as <b>Start node</b>. Please note, that the extrusion has been done
-in direction from node #4 to node #3, i.e. against the wire
-direction. In this example both faces of the initial mesh have been
-extruded.
-
-\image html edge_wire_3d_before.png
-
-\image html edge_wire_3d_after.png
+\image html extr_along_wire_after.png
+<center><em>The resulting extrusion</em></center>
 
 <br><center><h2>Extrusion of 2d elements along a closed path</h2></center>
 
@@ -88,36 +77,36 @@ path</b> item or click <em>"Extrusion along a path"</em> button in the toolbar.
 \image html image101.png
 <center><em>"Extrusion along a path" button</em></center>
 
-The following dialog box will appear:
+The following dialog common for line and planar elements will appear:
 
 \image html extrusion1.png
-
-\image html extrusion2.png
 </li>
 
-<li>In the dialog box you should:
+<li>In this dialog:
 <ul>
 <li>select the type of elements which will be extruded (1D or 2D),</li>
 <li>specify the <b>IDs of the elements</b> which will be extruded
+
 <ul>
-<li>Check on <b>Select the whole mesh, submesh or group</b> option
-<li>Choosing them manually with the mouse in the 3D Viewer. You can
-click on an element in the 3D viewer and it will be highlighted</li>
-<li>Applying Filters. The <b>Set filter</b> button allows to apply a
-definite filter to selection of the elements. See more
-about filters on the
-\ref selection_filter_library_page "Selection filter library" page.</li>
+<li><b>Select the whole mesh, submesh or group</b> activating this
+checkbox; or</li>
+<li>choose mesh elements with the mouse in the 3D Viewer. It is
+possible to select a whole area with a mouse frame; or</li> 
+<li>input the element IDs directly in <b>ID Elements</b> field. The selected elements will be highlighted in the
+viewer; or</li>
+<li>apply Filters. <b>Set filter</b> button allows to apply a filter to the selection of elements. See more
+about filters in the \ref selection_filter_library_page "Selection filter library" page.</li>
 </ul>
+
 </li>
 <li>define the Path along which the elements will be extruded,
 \n Path definition consists of several elements:
 <ul>
-<li>\b Mesh - containing a 1D sub-mesh on the edge, along which proceeds the extrusion</li>
-<li><b>Shape (edge)</b> - as the mesh can be complex, the edge is used to define the sub-mesh for the path</li>
-<li><b>Start node</b> - the first or the last node on the edge. It is used to define the direction of extrusion </li>
+<li><b>Mesh or submesh</b> - 1D mesh or sub-mesh, along which proceeds the extrusion</li>
+<li><b>Start node</b> - the start node. It is used to define the direction of extrusion </li>
 </ul>
 </li>
-<li> <b>Generate Groups</b> checkbox allows copying the groups of
+<li>activate  <b>Generate Groups</b> checkbox if it is necessary to  copy the groups of
 elements of the source mesh to the newly created one. </li>
 </ul>
 </li>
@@ -149,7 +138,9 @@ At each step the shape will be rotated by angle/nb. of steps.
 </ul>
 </li>
 
-<li>Click the \b Apply or \b OK button. Mesh edges will be extruded into
+
+<li>Click \b Apply or <b> Apply and Close</b>  button to confirm the operation.
+Mesh edges will be extruded into
 faces, faces into volumes. The external surface of the resulting 3d
 mesh (if faces have been extruded) is covered with faces, and corners
 with edges. If the path is closed, the resulting mesh can contain
diff --git a/doc/salome/gui/SMESH/input/find_element_by_point.doc b/doc/salome/gui/SMESH/input/find_element_by_point.doc
new file mode 100644 (file)
index 0000000..191aa43
--- /dev/null
@@ -0,0 +1,41 @@
+/*!
+
+\page find_element_by_point_page Find Element by Point
+
+\n This functionality allows you to find all mesh elements to which
+belongs a certain point.
+
+<em>To find the elements:</em>
+<ol>
+<li>Select a mesh or a group</li>
+<li>Select from the Mesh menu or from the context menu the Find
+Element by Point item.
+
+\image html findelement3.png
+<center><em>"Find Element by Point" button</em></center>
+
+The following dialog box will appear:
+
+\image html findelement2.png
+
+</li>
+<li>In this dialog box you should select:
+
+<ul>
+<li>the coordinates of the point;</li>
+<li>the type of elements to be found; it is also possible to find elements
+of all types related to the reference point. Choose type "All" to find
+elements of any type except for nodes and 0D elements.</li>
+</ul>
+
+</li>
+<li>Click the \b Find button.
+</ol>
+
+\image html findelement1.png 
+<center>The reference point and the related elements.</center>
+
+
+<br><b>See Also</b> a sample TUI Script of a \ref tui_find_element_by_point "Find Element by Point" operation.
+
+*/
index 4a87b992ac739a982c9b5d542bced727059b159e..d35caa9ac459eba2d14e68db3ca128462e1f7b44 100644 (file)
@@ -2,16 +2,17 @@
 
 \page free_faces_page Free faces
 
-\n This mesh quality control highlights faces which are connected
-less than to two mesh volume elements. Free faces are shown with a color differs from
-the color of shared faces.
+This mesh quality control highlights the faces connected to
+less than two mesh volume elements. The free faces are shown with a
+color different from the color of shared faces.
 
 \image html free_faces.png
-<center>In this picture some volume mesh element are removed as
-a result some faces become connected only to one
-volume. i.e. become free.
 
-<br><b>See Also</b> a sample TUI Script of a 
-\ref tui_free_faces "Free Faces quality control" operation.  
+In this picture some volume mesh elements have been removed, as
+a result some faces became connected only to one
+volume. i.e. became free.
+
+\sa A sample TUI Script of a \ref tui_free_faces "Free Faces quality control"
+operation.
 
 */
index 13f31430994306e64f949fa205e9448420004ec1..8a06fe3de7cc8b100da3d921af7d89dd8eee9eb1 100644 (file)
@@ -2,15 +2,15 @@
 
 \page free_nodes_page Free nodes
 
-\n This mesh quality control highlights nodes which are not connected
-to any  mesh element. Free nodes are shown with a color differs from
-the color of nodes.
+This mesh quality control highlights the nodes which are not connected
+to any  mesh element. 
 
 \image html free_nodes.png
-<center>In this picture some nodes don't connected to a mesh element as
-a result of deleting elements and adding several isolated nodes.
 
-<br><b>See Also</b> a sample TUI Script of a 
-\ref tui_free_nodes "Free Nodes quality control" operation.  
+In this picture some nodes are not connected to any mesh
+element after deleting some elements and adding several isolated nodes.
+
+\sa A sample TUI Script of a \ref tui_free_nodes "Free Nodes quality control"
+operation.
 
 */
diff --git a/doc/salome/gui/SMESH/input/generate_flat_elements.doc b/doc/salome/gui/SMESH/input/generate_flat_elements.doc
new file mode 100644 (file)
index 0000000..7cfdbf9
--- /dev/null
@@ -0,0 +1,12 @@
+/*!
+
+\page generate_flat_elements_page Generate flat elements on group boundaries or on faces
+
+\n These functionalities, used in some mechanics calculations,
+allow to generate flat volume elements on the boundaries of a list
+of groups of volumes, or on a list of groups of faces.
+\n These functionalities are only available in python scripts.
+
+<br><b>See </b> a sample TUI Script of \ref tui_double_nodes_on_group_boundaries "Generate flat elements" operation.  
+
+*/
diff --git a/doc/salome/gui/SMESH/input/ghs3d_hypo.doc b/doc/salome/gui/SMESH/input/ghs3d_hypo.doc
deleted file mode 100644 (file)
index 414e342..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*!
-
-\page ghs3d_hypo_page GHS3D Parameters hypothesis
-
-\n GHS3D Parameters hypothesis works only with <b>Tetrahedron (GHS3D)</b> 
-algorithm. This algorithm is a commercial software.
-
-\image html ghs3d_parameters_basic.png
-
-<ul>
-<li><b>Name</b> - allows to define the name of the hypothesis (GHS3D 
-Parameters by default).</li>
-
-<li><b>To mesh holes</b> - if checked, the algorithm will 
-create mesh in the holes inside a solid shape, else only the outermost
-shape will be meshed. Volumic elements created within holes are bound
-to the solid.</li>
-
-<li><b>Optimization level</b> - allows choosing the required
-optimization level: none, light, medium or strong. Higher level of
-optimisation provides better mesh, but can be time-consuming.
-</li>
-
-\image html ghs3d_parameters_advanced.png
-
-<li><b>Maximum memory size</b> - launches ghs3d software with
-work space limited to the specified amount of RAM, in Mbytes. If this option is
-checked off, the software will be launched with 7O% of the total RAM space. </li>
-
-<li><b>Initial memory size</b> - starts ghs3d software with
-the specified amount of work space, in Mbytes. If this option is checked off, the
-software will be started with 100 Megabytes of working space. </li>
-
-<li><b>Working directory</b> - allows defining the folder for input and output
-files of ghs3d software, which are the files starting with "GHS3D_" prefix. </li>
-
-<li><b>Keep working files</b> - allows checking input and output files
-of ghs3d software, while usually these files are removed after the
-launch of the mesher.</li>
-
-<li><b>Verbose level</b> - to choose verbosity level in the range from
-0 to 10.
-<ul> <li>0, no standard output,
-</li><li>2, prints the data, quality statistics of the skin and final
-meshes and indicates when the final mesh is being saved. In addition
-the software gives indication regarding the CPU time.
-</li><li>10, same as 2 plus the main steps in the computation, quality
-statistics histogram of the skin mesh, quality statistics histogram
-together with the characteristics of the final mesh.
-</li></ul></li>
-
-<li><b>To create new nodes</b> - if this option is checked off, ghs3d
-tries to create tetrahedrons using only the nodes of the 2D mesh.</li>
-
-<li><b>To use boundary recovery version</b> - enables using a
-boundary recovery module which tries to
-create volume meshes starting from very poor quality surface meshes
-(almost flat triangles on the surface, high density propagation,
-extreme aspect ratios, etc.) which fails with the standard version. The
-resulting volume mesh will however most likely have a very poor
-quality (poor aspect ratio of elements, tetrahedra with a very small
-positive volume).</li>
-
-<li><b>Option as text</b> - allows input of any text as command line
-for ghs3d. This allows the input of advanced options in a free from. </li>
-
-</ul>
-
-*/
\ No newline at end of file
diff --git a/doc/salome/gui/SMESH/input/ghs3dprl_hypo.doc b/doc/salome/gui/SMESH/input/ghs3dprl_hypo.doc
deleted file mode 100644 (file)
index 40ffb91..0000000
+++ /dev/null
@@ -1,392 +0,0 @@
-/*!
-
-\page ghs3dprl_hypo_page GHS3DPRL Parameters hypothesis
-
-\n GHS3DPRL Parameters hypothesis works only with <b>Tetrahedron (Tepal with TetMesh-GHS3D)</b> algorithm.
-\n
-\n This algorithm is a commercial software, its use requires a licence (http://www.distene.com/fr/build/offer.html).
-\n The advantage of Tepal is the possibility to generate (for example) a <em>partitioned</em> 
-200 million tetrahedra mesh on a not-so-big memory computer (2Go RAM) 
-...in something like 50 hours of <em>one</em> CPU (Xeon, 2008). 
-This is an alternative to Pluging GHS3D where you should need something like a not-so-common CPU with 64Go RAM 
-<em>to try</em> to do a one-partitionned 200 million tetrahedra mesh ...in a much less time indeed.
-\n
-\n Notes:
-\n This Plugin <em>doesn't</em> load in Memory the supposed plentiful big resulting meshes. 
-It's user choice: (in GUI Mesh mode) menu File-Import-MED Files.
-\n Beware, to load one 5 millions tetrahedra MED file, GUI Salome needs 2Go RAM.
-\n A new true parallel faster version of Tepal, using MPI, is expected in 2009.
-
-\image html ghs3dprl_parameters_basic.png
-
-<ul>
-<li>
-<b>Name</b> - allows to define the name of the hypothesis (GHS3DPRL Parameters by default).
-</li>
-<li>
-<b>MED_Name</b> - allows to define the path and the basename of the 
-generated resulted MED files ("DOMAIN" by default). 
-Undefined path means environment variable $SALOME_TMP_DIR (or $TMP by default).
-</li>
-<li>
-<b>Nb_Part</b> - allows to define the number of MED files generated, 
-the initial skin (triangles) will be meshed (tetrahedra) and partitioned 
-in Nb_Part by the <i>elementary</i> algorithm implemented in Tepal.<br>
-Beware, the (expected) number of total tetrahedra versus this parameter 
-involves the maximum tepal RAM use.
-</li>
-<li>
-<b>Keep_Files</b> - if this box is checked, input files of Tepal 
-(GHS3DPRL.points and GHS3DPRL.faces) are deleted after use (...if no backgrounding).
-</li>
-<li>
-<b>Tepal_in_Background</b> - if this box is checked, for big meshes, 
-launch Tepal execution and MED file generation in background, 
-allows user exiting of Salome. In this case, beware of the 
-job Tepal is "killSalome.py" <i>independent</i>, sometimes on other host.
-</li>
-<li>
-<b>To_Mesh_Holes</b> - if this box is checked, force parameter component 
-of tetmesh-ghs3d to mesh holes.
-</li>
-
-<h1>Modifying GHS3DPRL Advanced Parameters</h1><br>
-GHS3DPRL Plugin launches standalone binary executable tepal2med which launches binary executable tepal.<br>
-tepal2med launches tepal, wait for the end of computation, and converts resulting output tepal files in expected MED files.<br>
-Some advanced optional parameters are accessibles as arguments.<br>
-If keep_files checked you a posteriori can always re-launch tepal2med in a Terminal as a command with yours parameters.<br>Idem for tepal.<br><br>
-<li>
-<b>Advanced tepal2med Parameters</b> - type "tepal2med --help" in a Terminal. <p>
-
-\verbatim
-myname@myhost > /export/home/myname/salome_5/GHS3DPRLPLUGIN_5/bin/salome/tepal2med --help
-Available options:
-   --help         : produces this help message
-   --casename     : path and name of input tepal2med files which are
-                       - output files of tepal .msg .noboite .faces .points .glo
-                       - output file of GHS3DPRL_Plugin casename_skin.med (optional)
-                         with initial skin and its initial groups
-   --number       : number of partitions
-   --medname      : path and name of output MED files
-   --limitswap    : max size of working cpu memory (Mo) (before swapping on .temp files)
-   --verbose      : trace of execution (0->6)
-   --test         : more tests about joints, before generation of output files
-   --menu         : a GUI menu for option number
-   --launchtepal  : also launch tepal on files casename.faces and casename.points and option number
-   --meshholes    : force parameter component of tetmesh-ghs3d to mesh holes
-   --background   : force background mode from launch tepal and generation of final MED files (big meshes)
-   --deletegroups : regular expression (see QRegExp) which matches unwanted groups in final MED files
-                    (try --deletegroups="(\bAll_Nodes|\bAll_Faces)"
-                    (try --deletegroups="((\bAll_|\bNew_)(N|F|T))"
-example:
-   tepal2med --casename=/tmp/GHS3DPRL --number=2 --medname=DOMAIN --limitswap=1000 
-             --verbose=0 --test=yes --menu=no --launchtepal=no
-
-\endverbatim
-
-</li>
-<li>
-<p>
-<b>Advanced tepal Parameters</b> - type "tepal" in a Terminal. <p>
-
-\verbatim
-myname@myhost > tepal
-    =====================================
-    GHS3D-TEPAL 1.4.2 (Dec, 2006)               10-Dec-2008 AT 12:59:48
-    =====================================
-
- Distene SAS
-         Pole Teratec - BARD-1
-         Domaine du Grand Rue
-         91680 Bruyeres le Chatel
-         FRANCE
- Phone: +33(0)1-69-26-62-10   Fax: +33(0)1-69-26-90-33
- EMail: support@distene.com
-
-  COPYRIGHT (C)2006 DISTENE ALL RIGHTS RESERVED
-
-
-USAGE : tepal options
-
-With options in :
-     --filename name (-f name) :
-          Basename of the input case (MANDATORY)
-
-     --ndom n (-n n) :
-          Number of subdomains to make (MANDATORY)
-
-     --ghs3d ghs3d options (-g ghs3d options) :
-          Run temesh ghs3d on a previously generated subdomain. (ghs3d options must be "quoted")
-
-     --memory m (-m m) :
-          Max amount of memory (megabytes) allowed for ghs in the cutting process. (default is 0 : unlimited)
-
-     --mesh_only  (-Z ) :
-          Only (re)mesh all subdomains and update communications messages
-
-     --mesh_call command (-c command) :
-          Call the user specified command for meshing all the subomains after their skin was generated
-
-     --stats_only  (-S ) :
-          Only compute and show some statistics on subdomains
-
-     --rebuild  (-r ) :
-          Merge final subdomains skins
-
-     --rebuild_tetra  (-R ) :
-          Merge final subdomains skins and tetraedra
-
-     --rebuild_iface  (-i ) :
-          Include interfaces in final subdomains merge
-
-     --rebuild_retag  (-t ) :
-          Tag vertices, faces (and tetra if selected) with their subdomain number in final subdomains merge (keeps the lowest tag for shared elements)
-
-     --rebuild_ensight_parts  (-e ) :
-          Build ensight geom file with parts
-
-     --tetmesh_args str (-G str) :
-          Arguments to pass to Tetmesh during cutting process
-
- ==============================================================================
-                   GHS3D-TEPAL SOFTWARE 1.4.2 (Dec, 2006)
-                                 END OF SESSION
-                COPYRIGHT (C)2006 DISTENE ALL RIGHTS RESERVED
- ==============================================================================
-      ( Distene SAS
-        Phone: +33(0)1-69-26-62-10   Fax: +33(0)1-69-26-90-33
-        EMail: support@distene.com )
-
-\endverbatim
-
-</li>
-<li>
-<p>
-<b>Advanced ghs3d Parameters (through tepal's --tetmesh_args)</b> - type "ghs3d -h" in a Terminal. <p>
-
-\verbatim
-myname@myhost > ghs3d -h
-
-USE
-    /export/home/myname/ghs3d-4.0/DISTENE/Tools/TetMesh-GHS3D4.0/bin/Linux/ghs3dV4.0
-    [-u] [-m memory>] [-M MEMORY] [-f prefix] [-v verbose]
-    [-c component] [-p0] [-C] [-E count] [-t] [-o level]
-    [-I filetype] [-a/-b] [-O n m]
-
-DESCRIPTION
-
- -u (-h)        : prints this message.
-
- -m memory      : launches the software with memory Megabytes of work space.
-                  The default value of this parameter is 64 Megabytes and its
-                  minimum value is 10 Megabytes.
-                  It is also possible to set this parameter with the
-                  environment variable GHS3D_MEMORY by means of an operation
-                  equivalent to:
-                           setenv GHS3D_MEMORY memory,
-                  the value specified in the command line has the priority on
-                  the environment variable.
-
- -M MEMORY      : uses the automatic memory adjustment feature.
-                  If MEMORY is zero, the size of the work space is initially
-                  guessed from the input. If MEMORY is not zero, the
-                  software starts with MEMORY Megabytes of work space.
-                  The software then reallocates more and more memory as
-                  needed.
-                  The starting value when MEMORY equals 0 is 64 Megabytes,
-                  the maximum is given with memory of the -m option if used
-                  and the actual memory available.
-
- -f prefix      : defines the generic prefix of the files.
-
- -v verbose     : sets the output level parameter (the verbose parameter
-                  must be in the range 0 to 10).
-
- -c component   : chooses the meshed component. If component is
-                      0, all components to be meshed
-                      1, only the main (outermost) component to be meshed
-
- -p0            : disables creation of internal points.
-
- -C             : uses alternate boundary recovery version. To be used only
-                  when the boundary recovery of the standard version fails.
-
- -E count       : sets the extended output for error messages. If -E is used,
-                  the error messages found will be printed, up to a maximum
-                  count of errors between 1 and 100.
-
- -t             : generates an error file prefix.Log
-
- -o level       : sets the desired optimisation level.
-                  Valid optimisation levels are:
-                  none, light, medium or standard, strong,
-                  in increasing order of "quality vs speed" ratio.
-
- -I filetype    : defines the input mesh format as follows:
-                    -IP input files are ascii files, named prefix.points
-                     and prefix.faces - this is the default
-                    -IPb input files are binary files, named prefix.pointsb
-                     and prefix.facesb
-                    -IM input file is ascii file, named prefix.mesh
-                  where prefix is given with the -f option
-
- -a/-b          : selects the output file type:
-                    -a for ascii (the default) and
-                    -b for binary.
-
- -On            : saves a NOPO file in addition. NOPO is the mesh data
-                  structure of the Simail and Modulef software packages.
- -Om            : saves a mesh file in addition.
- -Omn           : saves both NOPO and mesh files.
-
- ==============================================================================
-                   TETMESH-GHS3D SOFTWARE 4.0-3 (December, 2006)
-                                 END OF SESSION
-                COPYRIGHT (C)1989-2006 INRIA ALL RIGHTS RESERVED
- ==============================================================================
-      ( Distene SAS
-        Phone: +33(0)1-69-26-62-10   Fax: +33(0)1-69-26-90-33
-        EMail: support@distene.com )
-
-\endverbatim
-
-</li>
-<h1>Saving user's preferred GHS3DPRL Advanced Parameters</h1><br>
-GHS3DPRL Plugin launches standalone binary executable tepal2med.<br>
-you may rename tepal2med as tepal2med.exe for example, and replace tepal2med by a shell script at your convenience to overriding parameters.<br>... or else $PATH modification... .<br>Idem for tepal.<br><br>
-<li>
-<b>Advanced tepal2med Parameters</b> - overriding parameter deletegroups<p>
-
-\code
-#!/bin/bash
-#script tepal2med overriding parameter deletegroups
-#we have renamed binary executable tepal2med as tepal2med.exe
-#echo tepal2med initial parameters are $1 $2 $3 $4 ... or $*
-#$0 is ignored
-
-tepal2med.exe $* --deletegroups="(\bAll_Nodes|\bAll_Faces)"
-
-\endcode
-
-</li>
-<li>
-<p>
-<b>Advanced tepal Parameters</b> - overriding parameter component of ghs3d (to mesh holes). <p>
-
-\code
-#!/bin/bash
-#script tepal overriding parameter component of tetmesh-ghs3d
-#we have renamed binary executable tepal as tepal.exe
-
-#optionnaly we could set licence only for us
-DISTENE_LICENSE_FILE="Use global envvar: DLIM8VAR"
-DLIM8VAR="dlim8 1:1:29030@is142356/0016175ef08c::a1ba1...etc...e19"
-SIMULOGD_LICENSE_FILE=29029@is142356
-
-tepal.exe $* --tetmesh_args "-c 0"
-
-\endcode
-
-</li>
-<li>
-<p>
-<b>Advanced tepal Parameters</b> - overriding launching tepal on other host. <p>
-
-\code
-#!/bin/bash
-#script tepal overriding launching tepal on other host (tepal run 64 bits only)
-#we have renamed binary executable tepal as tepal.exe
-#common file system (same path) otherwise scp... on input or result files
-#ssh -keygen -t rsa done and files id_rsa et id-rsa.pub move in ~/.ssh
-
-#example of typical command
-#tepal -f /home/myname/tmp/GHS3DPRL -n 4 > /home/myname/tmp/tepal.log
-#echo parameters $1 $2 $3 $4 ... or $*
-
-#tepal licence ought to be known on otherhost
-ssh otherhost "tepal.exe $* > /home/myname/tmp/tepal.log"
-
-#or more and more
-#ssh otherhost "tepal.exe $* --tetmesh_args \"-c 0\"" > /home/myname/tmp/tepal.log
-
-\endcode
-
-</li>
-
-<h1>TUI use.</h1><br>
-
-<li>
-<p>
-<b>example ex30_tepal.py.</b><p>
-
-\code
-
-#!/bin/python
-import os
-
-import geompy
-import smesh
-
-# Parameters
-# ----------
-
-results = "/tmp/ZZ"
-
-radius =  50
-height = 200
-
-# Build a cylinder
-# ----------------
-
-base = geompy.MakeVertex(0, 0, 0)
-direction = geompy.MakeVectorDXDYDZ(0, 0, 1)
-
-cylinder = geompy.MakeCylinder(base, direction, radius, height)
-
-geompy.addToStudy(cylinder, "Cylinder")
-
-# Define a mesh on a geometry
-# ---------------------------
-
-m = smesh.Mesh(cylinder)
-
-# 2D mesh with BLSURF
-# -------------------
-
-algo2d = m.Triangle(smesh.BLSURF)
-
-algo2d.SetPhysicalMesh(1)
-algo2d.SetPhySize(5)
-
-algo2d.SetGeometricMesh(0)
-
-# 3D mesh with tepal
-# ------------------
-
-algo3d = m.Tetrahedron(smesh.GHS3DPRL)
-
-algo3d.SetMEDName(results)
-algo3d.SetNbPart(4)
-algo3d.SetBackground(False)
-algo3d.SetKeepFiles(False)
-algo3d.SetToMeshHoles(True)
-
-# Launch meshers
-# --------------
-
-status = m.Compute()
-
-# Test if ok
-# ----------
-
-if os.access(results+".xml", os.F_OK):
-    print "Ok: tepal"
-else:
-    print "KO: tepal"
-\endcode
-
-</li>
-</ul>
-
-
-*/
diff --git a/doc/salome/gui/SMESH/input/group_of_underlying_elements.doc b/doc/salome/gui/SMESH/input/group_of_underlying_elements.doc
new file mode 100755 (executable)
index 0000000..a6a1b91
--- /dev/null
@@ -0,0 +1,34 @@
+/*!
+
+\page group_of_underlying_elements_page Create Group of Underlying Elements
+
+
+To create groups of entities from existing groups of superior dimensions, in the \b Mesh menu select <b>Group of underlying entities</b>.<br>
+
+The following dialog box will appear:
+
+\image html dimgroup_dlg.png
+
+In this dialog box specify the name of the resulting group, types of entities and set of source groups.
+
+In the figure below, there are two source Volume groups:
+
+\image html dimgroup_src.png
+<center>Source groups</center>
+
+In this case the following results for Faces, Edges and Nodes are obtained: 
+
+\image html dimgroup_2d.png
+<center>Faces</center>
+
+\image html dimgroup_1d.png
+<center>Edges</center>
+
+\image html dimgroup_0d.png
+<center>Nodes</center>
+
+<b>See Also</b> a sample TUI Script of a 
+\ref tui_create_dim_group "Creating groups of entities from existing groups of superior dimensions"
+operation.
+
+*/
index 56fe14c0db029ceefc65a64956055a8e2ba24249..9615ad4c39b858009442b9ac7afc3716e174520b 100644 (file)
@@ -2,30 +2,37 @@
 
 \page grouping_elements_page Grouping elements
 
-In Mesh module it is possible to \subpage creating_groups_page "create groups of mesh elements":
-nodes, edges, faces or volumes:
-<ul>
-<li> by selecting the elements of the specified kind by their IDs or
-directly on the presentation in the VTK viewer - <b>Standalone group</b> tab of <b>Create group</b>
-dialog.</li>
-<li> by creating a group of elements of the selected type from all
-such elements of the chosen geometrical object - <b>Group on
-geometry</b> tab of <b>Create group</b> dialog.</li>
-<li> by creating several groups of elements (nodes,
-edges, faces and volumes) from the chosen submesh - using <b>Mesh -> Construct
-Group</b> Menu item. In this case groups of elements are created automatically.</li>
-</ul>
+In Mesh module it is possible to create groups of mesh elements:
+nodes, edges, faces or volumes. One group contains elements of only
+one type. The following ways of creation are possible:
+
+- by selecting the elements using filters and/or directly on the 
+  presentation in the VTK viewer, and/or by using elements of other
+  mesh objects - \ref standalone_group "Standalone group"
+  tab of \ref creating_groups_page "Create group" dialog.
+- by creating a group of elements generated on the chosen geometrical
+  object - \ref group_on_geom "Group on geometry" tab of
+  \subpage creating_groups_page "Create group" dialog and
+  \subpage create_groups_from_geometry_page "Create Groups from Geometry"
+  dialog.
+- by creating a group of elements satisfying to certain criteria -
+  \ref group_on_filter "Group on filter" tab of
+  \subpage creating_groups_page "Create group" dialog.
+- by creating groups of nodes and elements from the chosen submesh
+  (type of elements depends on dimension of submesh geometry) -
+  using <b>Mesh -> Construct Group</b> menu item (available in context
+  menu as well).
+- by creating groups of entities from existing groups of superior
+  dimensions - using \subpage group_of_underlying_elements_page
+  "Create Group of Underlying Elements" dialog.
 
 The created groups can be later:
 
-<ul>
-<li>\subpage editing_groups_page "Edited"</li>
-<li>\subpage using_operations_on_groups_page "Subjected to Boolean operations", or</li>
-<li>\subpage deleting_groups_page "Deleted"</li>
-</ul>
+- \subpage editing_groups_page "Edited"
+- \subpage using_operations_on_groups_page "Subjected to Boolean operations"
+- \subpage deleting_groups_page "Deleted"
 
 An important tool, providing filters for creation of \b Standalone
-groups is  \subpage selection_filter_library_page</li>.
-
+groups is \ref selection_filter_library_page.
 
 */
index dbf96ab89298a8cfff706ead2c62088ddfab3dc4..52ff261e3369b7ab05245de380fa92049d434aa9 100644 (file)
@@ -3,15 +3,15 @@
 \page importing_exporting_meshes_page Importing and exporting meshes
 
 \n In MESH there is a functionality allowing importation/exportation
-of meshes from \b MED, \b UNV (I-DEAS 10), \b DAT (Nastran) and STL
-format files.
+of meshes from/to \b MED, \b UNV (I-DEAS 10), \b DAT (Nastran), \b STL
+and \b CGNS format files. You can also export a group as a whole mesh.
 
 
 <em>To import a mesh:</em>
 
 <ol>
 <li>From the \b File menu choose the \b Import item, from its sub-menu
-select the corresponding format (MED, UNV and DAT) of the file containing
+select the corresponding format (MED, UNV, DAT, STL and CGNS) of the file containing
 your mesh.</li>
 <li>In the standard <b>Search File</b> dialog box find the file for
 importation. It is possible to select multiple files to be imported all at once. </li>
@@ -21,13 +21,13 @@ importation. It is possible to select multiple files to be imported all at once.
 
 \image html meshimportmesh.png
 
-<em>To export a mesh:</em>
+<em>To export a mesh or a group:</em>
 
 <ol>
 <li>Select the object you wish to export.</li>
 <li>From the \b File menu choose the \b Export item, from its sub-menu
-select the format (MED, UNV, DAT and STL) of the file which will contain your
-exported mesh.</li>
+select the format (MED, UNV, DAT, STL and CGNS) of the file which will
+contain your exported mesh.</li>
 <li>In the standard <b>Search File</b> select a location for the
 exported file and enter its name.</li>
 <li>Click the \b OK button.</li>
index 2de722d16115cc472b5c69c44fda05ad969dc302..798237b4b2f77c7eb3ac60587c312fb661b027b4 100644 (file)
@@ -6,22 +6,31 @@
 
 \n \b MESH module of SALOME is destined for:
 <ul>
-<li>\ref importing_exporting_meshes_page "import and export of meshes in MED format";</li>
+<li>\ref importing_exporting_meshes_page "import and export of meshes in different formats";</li>
 <li>\subpage about_meshes_page "meshing geometrical models"
 previously created or imported by the Geometry component; </li>
 <li>\subpage viewing_meshes_overview_page "viewing created meshes" in
 the VTK viewer;</li>
 <li>\subpage grouping_elements_page "creating groups of mesh elements";</li>
-<li>applying to meshes \subpage quality_page "Quality Controls" , 
-allowing to highlight important elements:
+<li>applying to meshes \subpage quality_page "Quality Controls", 
+allowing to highlight important elements;
+<li>filtering sub-sets of mesh entities (nodes elements) using
+\subpage filters_page "Filters" functionality;</li>
 <li>\subpage modifying_meshes_page "modifying meshes" with a vast
-array of dedicated operations.</li> 
-<li>\subpage using_notebook_mesh_page.</li>
+array of dedicated operations;</li> 
+<li>different \subpage measurements_page "measurements" of the mesh objects;
+<li>easily setting parameters via the variables predefined in
+\subpage using_notebook_mesh_page "Salome notebook".</li>
 </ul>
 
+Mesh module preferences are described in the \subpage mesh_preferences_page section of SALOME Mesh Help.
+
 Almost all mesh module functionalities are accessible via
 \subpage smeshpy_interface_page "Mesh module Python interface".
 
+Other functions are available in <a class="el" target="_new" href="../../tui/SMESH/docutils/index.html">salome.smesh python package</a>.
+
+
 \image html image7.jpg "Example of MESH module usage for engineering tasks"
 
 */
index def8afa9585b81a93e9edd949e47991acaed5292..4ed5b69e6a408857ce3e01af34ae6adb0c99f644 100644 (file)
@@ -10,8 +10,8 @@ of your mesh.
 <ol>
 <li>Display your mesh in the viewer. </li>
 
-<li>Choose <b>Controls > Length 2D</b> or click <em>"Length 2D"</em>
-button in the toolbar. 
+<li>Choose <b>Controls > Face Controls > Length 2D</b> or click
+<em>"Length 2D"</em> button in the toolbar. 
 
 \image html image34.png
 <center><em>"Length 2D" button</em></center>
diff --git a/doc/salome/gui/SMESH/input/make_2dmesh_from_3d.doc b/doc/salome/gui/SMESH/input/make_2dmesh_from_3d.doc
new file mode 100644 (file)
index 0000000..a53257e
--- /dev/null
@@ -0,0 +1,52 @@
+/*!
+
+\page make_2dmesh_from_3d_page Generate boundary elements
+
+\n This functionality allows to generate mesh elements on the borders of
+elements of a higher dimension.
+
+<em>To generate border elements:</em>
+<ol>
+<li>Select a mesh or group in the Object Browser or in the 3D Viewer</li>
+<li>From the Modification menu choose "Create boundary elements"
+item, or click "Create boundary elements" button in the toolbar
+
+\image html 2d_from_3d_ico.png "Create boundary elements icon"
+
+The following dialog box will appear:
+\image html 2d_from_3d_dlg.png "Create boundary elements dialog box".
+</li>
+<li>Check in the dialog box one of two radio buttons corresponding to
+the type of operation you would like to perform.</li>
+<li>Fill the other fields available in the dialog box.</li>
+<li>Click the \b Apply or <b>Apply and Close</b> button to perform the operation.</li>
+</ol>
+
+\n "Create boundary elements" dialog allows creation of boundary elements
+of two types.
+<ul>
+<li><b>2D from 3D</b> creates mesh faces on free facets of volume elements</li>
+<li><b>1D from 2D</b> creates mesh edges on free edges of mesh faces</li>
+</ul>
+Here a <em>free facet</em> means a facet shared by only one volume, a <em>free edge</em>
+means an edge shared by only one mesh face.
+
+In this dialog:
+<ul>
+<li>specify the <b>Target</b> mesh, where the boundary elements will
+  be created.
+  <ul>
+  <li><b>This mesh</b> adds elements in the selected mesh.</li>
+  <li><b>New mesh</b> adds elements to a new mesh. The new mesh appears
+  in the Object Browser with the name that you can change in the adjacent box. </li>
+  </ul></li>
+<li>activate <b>Copy source mesh</b> checkbox to copy all elements of
+the selected mesh to the new mesh, else the new mesh will contain only
+boundary elements (old and created by this operation).</li>
+<li>activate <b>Create group</b> checkbox to create a group to which
+  all the boundary elements (old and new) are added. The new group appears
+  in the Object Browser with the name that you can change in the adjacent box. </li>
+</ul>
+<br><b>See Also</b> a sample TUI Script of a \ref tui_make_2dmesh_from_3d "Create boundary elements" operation.  
+
+*/
diff --git a/doc/salome/gui/SMESH/input/max_element_length_2d.doc b/doc/salome/gui/SMESH/input/max_element_length_2d.doc
new file mode 100644 (file)
index 0000000..6ec4f71
--- /dev/null
@@ -0,0 +1,28 @@
+/*!
+
+\page max_element_length_2d_page Element Diameter 2D
+
+\n This quality control criterion consists in calculation of the length of
+edges and diagonals combining 2D mesh elements (triangles and quadrangles).
+
+<em>To apply the Element Diameter 2D quality criterion to your mesh:</em>
+<ol>
+<li>Display your mesh in the viewer. </li>
+
+<li>Choose <b>Controls > Face Controls > Element Diameter 2D</b> or click
+<em>"Element Diameter 2D"</em> button in the toolbar. 
+
+\image html image42.png
+<center><em>"Element Diameter 2D" button</em></center>
+
+Your mesh will be displayed in the viewer with its elements colored according to the
+applied mesh quality control criterion:
+
+\image html max_element_length_2d.png
+</li>
+</ol>
+
+<br><b>See Also</b> a sample TUI Script of a 
+\ref tui_max_element_length_2d "Element Diameter 2D quality control" operation.  
+
+*/
diff --git a/doc/salome/gui/SMESH/input/max_element_length_3d.doc b/doc/salome/gui/SMESH/input/max_element_length_3d.doc
new file mode 100644 (file)
index 0000000..7aa70ad
--- /dev/null
@@ -0,0 +1,29 @@
+/*!
+
+\page max_element_length_3d_page Element Diameter 3D
+
+\n This quality control criterion consists in calculation of the length of
+edges and diagonals combining 3D mesh elements
+(tetrahedrons, pyramids, pentahendrons, hexahedrons and polyhedrons).
+
+<em>To apply the Element Diameter 3D quality criterion to your mesh:</em>
+<ol>
+<li>Display your mesh in the viewer. </li>
+
+<li>Choose <b>Controls > Volume Controls > Element Diameter 3D</b> or click
+<em>"Element Diameter 3D"</em> button in the toolbar. 
+
+\image html image43.png
+<center><em>"Element Diameter 3D" button</em></center>
+
+Your mesh will be displayed in the viewer with its elements colored according to the
+applied mesh quality control criterion:
+
+\image html max_element_length_3d.png
+</li>
+</ol>
+
+<br><b>See Also</b> a sample TUI Script of a 
+\ref tui_max_element_length_3d "Element Diameter 3D quality control" operation.  
+
+*/
diff --git a/doc/salome/gui/SMESH/input/measurements.doc b/doc/salome/gui/SMESH/input/measurements.doc
new file mode 100644 (file)
index 0000000..6514cf2
--- /dev/null
@@ -0,0 +1,70 @@
+/*!
+
+\page measurements_page Measurements
+
+Mesh module provides the possibility to perform different measurements
+of the selected mesh data.
+
+All measurement operations are available via \b Measurements
+top-level menu. Access to the measurements operations is
+implemented via a single dialog box, where each operation is represented
+as a separate tab page.
+
+\section min_distance_anchor Minimum Distance
+
+This operation allows measuring the distance between two objects.
+Currently only node-to-node and node-to-origin operations are
+available, but this operation will be extended in the future to support
+other mesh objects - elements, meshes, sub-meshes and groups.
+
+To start <b>Minimum Distance</b> operation, select <b>Minimum Distance</b>
+item from \b Measurements menu.
+
+\image html min_distance.png
+
+In the dialog box choose the first target and the second target mode by
+switching the corresponding radio buttons, then select the objects the distance
+between which is to be calculated (or input their IDs directly 
+in case of nodes/elements) and press \em Compute button.
+
+The following types of targets are supported:
+- \em Node: single mesh node;
+- \em Element: single mesh element (not available in this version);
+- \em Object: mesh, sub-mesh or group object (not available in this
+version);
+- \em Origin: origin of the global co-ordinate system.
+
+The result will
+be shown in the bottom area of the dialog box. In addition, a simple
+preview will be shown in the 3D viewer.
+
+\image html min_distance_preview.png
+
+\section bounding_box_anchor Bounding Box
+
+This operation allows to calculate the bounding box of the selected
+object(s).
+
+To start <b>Bounding Box</b> operation, select <b>Bounding Box</b>
+item from \b Measurements menu.
+
+\image html bnd_box.png
+
+In the dialog box choose the required type of the object by switching the
+corresponding radio button, select the object(s) and press \em Compute button.
+
+The following types of input are available:
+- \em Objects: select one or several mesh, sub-mesh or group objects;
+- \em Nodes: select a set of mesh nodes;
+- \em Elements: select a set of mesh elements.
+
+The result of calculation will be shown in the bottom area of the
+dialog box. In addition, a simple preview will be shown in the 3D
+viewer.
+
+\image html bnd_box_preview.png
+
+<b>See Also</b> a sample TUI Script of a 
+\ref tui_measurements_page "Measurement operations".
+
+*/
index 821f6f9f28b625d46d9a68e77987bf9cc0404fa3..50513d58fff4173ddeb63cbaaa617bda23712d56 100644 (file)
@@ -5,42 +5,58 @@
 \n This functionality allows to merge coincident elements of a mesh
 selectable in the dialog box.
 
-
 \image html mergeelems_ico.png "Merge elements button"
 
+<ol>
+<li>Choose in the main menu \b Modification -> \b Transformation -> <b>Merge elements</b> item. The following dialog box
+shall appear:</li>
 
-\image html mergeelems.png
+\image html mergeelems_auto.png
+<br>
+<ul>
+<li>\b Name is the name of the mesh whose elements will be merged.</li>
+<li>\b Automatic or \b Manual Mode allows choosing how the elements
+are processed.
+</ul>
+
+<li><b>Automatic mode:</b>
+<ul>
+<li>In the \b Automatic Mode the elements created on the same nodes will be merged.</li>
+</ul>
+</li>
+
+<li>If the \b Manual Mode is selected, additional controls are
+available:
 
+\image html mergeelems.png
+<br>
+<ul>
+<li>\b Detect button generates the list of coincident elements for the given \b Tolerance.</li>
+<li><b>Coincident elements</b> is a list of groups of elements for
+merging. All elements of each group will form one after the operation.
 <ul>
-  <li>\b Name is the name of the mesh whose elements will be merged.</li>
-  <li>\b Tolerance is a maximum distance between elements sufficient for merging.
-    <ul>
-      <li>\b Detect button generates the list of coincident elements for the given \b Tolerance.</li>
-    </ul></li>
-  <li><b>Coincident elements</b> is a list of groupes of elements for
-    merging. All elements of each group will form one after the operation.
-    <ul>
-      <li>\b Remove button deletes the selected group from the list.</li>
-      <li>\b Add button adds to the list a group of elements selected in the
-        viewer with pressed "Shift" key.</li>
-      <li><b>Select all</b> checkbox selects all groups.</li>
-    </ul></li>
-  <li><b>Edit selected group</b> list allows editing the selected group:
-    <br><br>
-    \image html add.png
-    <center>adds to the group the element selected in the viewer.</center>
-    <br>
-    \image html remove.png
-    <center>removes from the group the selected element.</center>
-    <br>
-    \image html sort.png
-    <center>moves the selected element to the first position in the
-    group. This means that all other elements will be merged into this
-    one.</center>
-    <br>
-  </li>
-  <li>To confirm your choice click \b Apply or <b>Apply and Close</b> button.</li>
+<li>\b Remove button deletes the selected group from the list.</li>
+<li>\b Add button adds to the list a group of elements selected in the
+viewer with pressed "Shift" key.</li>
+<li><b>Select all</b> checkbox selects all groups.</li>
+</ul></li>
+<li><b>Edit selected group</b> list allows editing the selected group:
+<br><br>
+\image html add.png
+<center>adds to the group the element selected in the viewer.</center>
+<br>
+\image html remove.png
+<center>removes from the group the selected element.</center>
+<br>
+\image html sort.png
+<center>moves the selected element to the first position in the
+group. This means that all other elements will be merged into this
+one.</center>
+<br>
+</li>
+<li>To confirm your choice click \b Apply or <b>Apply and Close</b> button.</li>
 </ul>
+</ol>
 
 In this picture you see a triangle which coincides with one of the
 elements of the mesh. After we apply <b>Merge Elements</b> functionality, the
index fb88fb89e26492d3ea01eb832f636f5839bcac31..3b1bbeaaf23a4c30b43643a1d69c6bd1584614e3 100644 (file)
@@ -2,29 +2,43 @@
 
 \page merging_nodes_page Merging nodes
 
-\n This functionality allows user to detect groups of coincident nodes
-with desirable tolerance, edit these groups and merge.
+This functionality allows user to detect groups of coincident nodes
+with specified tolerance; each group of the coincident nodes can be
+then converted to the single node.
 
 \image html mergenodes_ico.png "Merge nodes button"
 
 <em>To merge nodes of your mesh:</em>
 <ol>
-<li>From the \b Modification choose \b Transformation and  from its
+<li>From the \b Modification choose \b Transformation and from its
 sub-menu select the <b>Merge nodes</b> item. The following dialog box
-shall appear:
-
-\image html mergenodes.png
-
+shall appear:</li>
+<br>
+\image html mergenodes_auto.png
+<br>
 <ul>
 <li>\b Name is the name of the mesh whose nodes will be merged.</li>
+<li>\b Automatic or \b Manual Mode allows choosing how the nodes are
+processed.
 <li>\b Tolerance is a maximum distance between nodes sufficient for
-merging.
+merging.</li>
+<li><b>Exclude Groups</b> group box allows to ignore the nodes which
+belong to the specified mesh groups.
+</ul>
+
+<li><b>Automatic mode:</b>
+<br>
+<ul>
+<li>In the \b Automatic Mode all Nodes within the indicated tolerance
+will be merged. The nodes which belong to the groups specified in the
+<b>Exclude Groups</b> will be not taken into account.</li>
+</ul>
+</li><br>
+<li>If the \b Manual Mode is selected, additional controls are available:
 <ul>
 <li>\b Detect button generates the list of coincident nodes for the given
 \b Tolerance.</li>
-</ul>
-</li>
-<li><b>Coincident nodes</b> is a list of groupes of nodes for
+<li><b>Coincident nodes</b> is a list of groups of nodes for
 merging. All nodes of each group will form one after the
 operation.
 <ul>
@@ -33,6 +47,10 @@ operation.
 viewer with pressed "Shift" key.</li>
 <li><b>Select all</b> checkbox selects all groups.</li>
 </ul>
+
+<br>
+\image html mergenodes.png
+<br>
 </li>
 <li><b>Edit selected group</b> list allows editing the selected
 group:
@@ -60,4 +78,4 @@ one.</center><br>
 <br><b>See Also</b> a sample TUI Script of a 
 \ref tui_merging_nodes "Merge Nodes" operation.  
 
-*/
\ No newline at end of file
+*/
index 37a3deaf48a66d997bcfaa4391e35a207da8fcaf..06a02d2cc1d90d5d356fe5badf49f6016df7b5a7 100644 (file)
 /*!
 
-\page mesh_infos_page Mesh infos
+\page mesh_infos_page Mesh Information
 
-\n There are three information boxes: <b>Standard Mesh
-Infos</b>, <b>Advanced Mesh Infos</b> and <b> Mesh Element Info</b>.
+The user can obtain information about the selected mesh object
+(mesh, sub-mesh or group) using <b>Mesh Information</b> dialog box.
 
-<br>
-\anchor standard_mesh_infos_anchor
-<h2>Standard Mesh Infos</h2>
-
-The <b>Standard Mesh Infos</b> box gives only the information on the
-number of elements of maximum dimension and the number of nodes in the
-mesh. However, from this Info you can learn about groups selected on
-this mesh.
-\n To view the <b>Standard Mesh Infos</b>, select your mesh or submesh
-in the <b>Object Browser</b> and select <b>Standard Mesh Infos</b>
-from the \b Mesh menu or click <em>"Standard Mesh Infos"</em> button
+To view the <b>Mesh Information</b>, select your mesh, sub-mesh or
+group in the <b>Object Browser</b> and invoke <b>Mesh Information</b>
+item from the \b Mesh menu or click <em>"Mesh Information"</em> button
 in the toolbar. 
 
 \image html image49.png
-<center><em>"Standard Mesh Infos" button</em></center>
+<center><em>"Mesh Information" button</em></center>
+
+The <b>Mesh Information</b> dialog box provides three tab pages:
+- <b>\ref advanced_mesh_infos_anchor "Base Info"</b> - to show base
+information about the selected mesh object
+- <b>\ref mesh_element_info_anchor "Element Info"</b> - to show
+detailed information about the selected mesh node or element.
+- <b>\ref mesh_addition_info_anchor "Additional Info"</b> - to show additional information available
+for the selected mesh, sub-mesh or group object.
 
-The following information will be displayed:
+\anchor advanced_mesh_infos_anchor
+<h2>Base Information</h2>
 
-\image html a-standmeshinfo.png
+The <b>Base Info</b> tab page of the dialog box provides general
+information on the selected object - mesh, sub-mesh or mesh group:
+name, type, total number of nodes and elements separately for each
+type: 0D elements, edges, faces and volumes.
+
+\image html advanced_mesh_infos.png
+<center><em>"Base Info" page</em></center>
 
+\anchor mesh_element_info_anchor
+<h2>Mesh Element Information</h2> 
+
+The <b>Element Info</b> tab page of the dialog box gives basic
+information about the type, coordinates and connectivity of the
+selected mesh node or element.
+
+\image html eleminfo1.png
+<center><em>"Element Info" page, node information</em></center>
 <br>
-\anchor advanced_mesh_infos_anchor
-<h2>Advanced Mesh Infos</h2>
+\image html eleminfo2.png 
+<center><em>"Element Info" page, element information</em></center>
 
-The <b>Advanced Mesh Infos</b> box gives more information about the mesh,
-including the total number of faces and volumes and their geometrical
-types.
-\n To view the <b>Advanced Mesh Infos</b>, select your mesh or submesh
-in the <b>Object Browser</b> and select <b>Advanced Mesh Infos</b>
-from the \b Mesh menu or click <em>"Advanced Mesh Infos"</em> button
-in the toolbar.
+The use can either input the ID of a node or element he wants to
+analyze directly in the dialog box or select the node or element in
+the 3D viewer.
 
-\image html image50.gif
-<center><em>"Advanced Mesh Infos" button</em></center>
+\anchor mesh_addition_info_anchor
+<h2>Additional Information</h2> 
 
-The following information will be displayed:
+The <b>Additional Info</b> tab page of the dialog box provides an
+additional information on the selected object: mesh, sub-mesh or
+group.
 
-\image html advanced_mesh_infos.png
+For a mesh object, the following information is shown:
+- Name
+- Type: based on geomerty, imported, standalone
+- Shape (if mesh is based on geometry)
+- File (if mesh is imported from the file)
+- Groups
+- Sub-meshes
 
-In case you get Mesh Infos via a \ref tui_viewing_mesh_infos "TUI script", 
-the information is displayed in Python Console.
+\image html addinfo_mesh.png
+<center><em>"Additional Info" page, mesh information</em></center>
+<br>
 
-\image html b-mesh_infos.png
+For a sub-mesh object, the following information is shown:
+- Name
+- Parent mesh
+- Shape
 
+\image html addinfo_submesh.png
+<center><em>"Additional Info" page, sub-mesh information</em></center>
 <br>
-\anchor mesh_element_info_anchor
-<h2>Mesh Element Info</h2> 
 
-The <b>Mesh Element Info</b> box gives basic information about the
-type and the coordinates of the selected mesh element.
-\n It is possible to input the Element ID or to select the Element in
-the Viewer.
+For a group object, the following information is shown:
+- Name
+- Parent mesh
+- Type: standalone, group on geometry, group on filter
+- Entity type: node, edge, face, volume
+- Size
+- Color
+- Number of underlying nodes (for non-nodal groups)
+
+\image html addinfo_group.png
+<center><em>"Additional Info" page, group information</em></center>
+<br>
 
-\image html eleminfo1.png
+\note For the performance reasons, the number of underlying nodes is
+computed only by demand. For this, the user should press the "Compute"
+button (see picture). Also, the number of underlying nodes is
+automatically calculated if the size of the group does not exceed
+the "Automatic nodes compute limit" set via the  "Mesh information"
+preferences (zero value means no limit).
 
-\image html eleminfo2.png 
+In case you get <b>Mesh Information</b> via a TUI script, the information is
+displayed in the Python Console. 
+<b>See the</b> \ref tui_viewing_mesh_infos "TUI Example".
 
-*/
\ No newline at end of file
+*/
+       
diff --git a/doc/salome/gui/SMESH/input/mesh_preferences.doc b/doc/salome/gui/SMESH/input/mesh_preferences.doc
new file mode 100644 (file)
index 0000000..1b1b2f9
--- /dev/null
@@ -0,0 +1,203 @@
+/*!
+
+\page mesh_preferences_page Mesh preferences
+
+In the Mesh module you can set mesh preferences, which can be used in
+later sessions with this module.
+
+<h2>General Preferences</h2>
+
+\image html pref21.png
+
+<ul>
+<li><b>Automatic Update</b></li>
+<ul>
+<li>If you toggle <b>Automatic Update</b> checkbox, the model in your
+viewer automatically updated whenever you make changes in it.</li>
+<li><b>Size limit (elements)</b> - allows to specify the maximum
+number of elements in the resulting mesh for which the automatic updating
+of the presentation is performed. This option affects only
+<b>Compute</b> operation. Zero value means "no limit". Default value
+is 500 000 mesh elements.
+</ul>
+<li><b>Quality Controls</b></li>
+<ul>
+<li>If you toggle <b>Display entity</b>, both faces and edges of an
+object will be displayed in the viewer by default.</li>
+<li>If you toggle <b>Use precision</b> checkbox, you can display numbers in
+<b>Quality Control</b> diagrams at the necessary level of precision.</li>
+<li><b>Number of digits after point</b> - defines precision for <b>Quality Controls</b>. By default, numbers in <b>Quality Control</b>
+diagrams are presented as integers.</li>
+<li><b>Double nodes tolerance</b> defines the maximal distance between two
+mesh nodes, at which they are considered coincident by <b>Double nodes</b>
+quality control.
+</ul>
+<li><b>Display mode</b> - allows to set Wireframe, Shading, Nodes or Shrink
+presentation mode as default.</li>
+<li><b>Representation of the 2D quadratic elements</b></li>
+<ul>
+<li><b>Representation of the 2D quadratic elements</b> combobox - allows
+to select lines or arcs for representation of quadratic elements.</li>
+<li><b>Maximum Angle</b> - maximum deviation angle used by the
+application to build arcs. </li>
+</ul>
+<li><b>Mesh export</b></li>
+<ul>
+<li>If you toggle <b>Automatically create groups for MED export</b> checkbox,
+this operation will be carried out automatically.</li>
+<li>If you toggle <b>Automatic renumbering</b> checkbox, the exported
+mesh will be renumbered automatically</li>
+</ul>
+<li><b>Mesh computation</b></li>
+<ul>
+<li><b>Show a computation result notification</b> combobox allows to
+select the notification mode about a mesh computation result.
+There are 3 possible modes:</li>
+<ul>
+<li><b>Never</b> - do not show the result dialog at all;</li>
+<li><b>Errors only</b> - the result dialog will be shown if there were
+some errors during a mesh computation;</li>
+<li><b>Always</b> - show the result dialog after each mesh
+computation. This is a default mode.</li>
+</ul></ul>
+<li><b>Mesh information</b></li>
+<ul>
+<li><b>Mesh element information</b></li> - Change the way mesh element
+information is shown:
+<ul>
+<li><b>Simple</b> - as a plain text</li>
+<li><b>Tree</b> - in a tree-like form</li>
+</ul>
+<li><b>Automatic nodes compute limit</b></li> - allows to define the size limit for the
+mesh groups for which the number of underlying nodes is calculated
+automatically. If the group size exceeds the value set in the preferences,
+the user will have to press \em Compute button explicitly. Zero value
+means "no limit". By default the value is set to 100 000 mesh elements.
+</li></ul>
+<li><b>Automatic Parameters</b></li>
+<ul>
+<li><b>Ratio Bounding Box Diagonal / Max Size</b> - this parameter is
+used for automatic meshing: ratio between the bounding box of the
+meshed object and the Max Size of segments.</li>
+<li><b>Default Number of Segments</b> - allows defining the default
+number of segments on each edge</li>
+</li></ul>
+<li><b>Mesh loading</b></li>
+<ul>
+<li>If <b>No mesh loading from study file at hypothesis modification</b>
+  checkbox is on, the mesh data will not be loaded from the study file
+  when a hypothesis is modified. This allows  saving time by omitting
+  loading data of a large mesh that is planned to be recomputed with other parameters.</li>
+</ul>
+<li><b>Input fields precision</b></li>
+<ul>
+<li><b>Length precision</b> - allows to adjust input precision of coordinates and dimensions.</li>
+<li><b>Angular precision</b> - allows to adjust input precision of angles.</li>
+<li><b>Length tolerance precision</b> - allows to adjust input precision of tolerance of coordinates and dimensions.</li>
+<li><b>Parametric precision</b> - allows to adjust input precision of parametric values.</li>
+<li><b>Area precision</b> - allows to adjust input precision of mesh element area.</li>
+<li><b>Volume precision</b> - allows to adjust input precision of mesh element volume.</li>
+</ul>
+<li><b>Python Dump</b></li>
+<ul>
+<li><b>Historical python dump</b> checkbox allows switching between 
+  \a Historical and \a Snapshot dump mode. In \a
+  Historical mode, Python Dump script includes all commands
+  performed by SMESH engine. In \a Snapshot mode, the commands
+  relating to objects removed from the Study as well as the commands
+  not influencing the current state of meshes are excluded from the script.</li>
+</ul>
+</ul>
+
+<h2>Mesh Preferences</h2>
+
+\image html pref22.png
+
+<ul>
+<li><b>Nodes</b></li>
+<ul>
+<li><b>Color</b> -  allows to select the color of nodes. Click on the
+colored line to access to the <b>Select Color</b> dialog box.</li>
+<li><b>Type of marker</b> - allows to define the shape of nodes.</li>
+<li><b>Scale of marker</b> - allows to define the size of nodes.</li>
+</ul>
+<li><b>Elements</b></li>
+<ul>
+<li><b>Surface color</b>  - allows to select the surface color of elements
+(seen in Shading mode). Click on the colored line to access to the <b>Select Color</b> dialog box.</li>
+<li><b>Back surface color</b> - allows to select the interior surface color
+of elements. Use the slider to select the color generated basing on  
+the <b>Surface color</b> by changing its brightness and saturation.</li>
+<li><b>Outline color</b> - allows to select the color of element
+borders. Click on the colored line to access to the <b>Select Color</b> dialog box.</li>
+<li><b>Wireframe color</b> - allows to select the color of borders of
+elements in the wireframe mode. Click on the colored line to access to the <b>Select Color</b> dialog box.</li>
+<li><b>Width</b> - allows to define the width of lines (edges and borders of elements).</li>
+<li><b>Shrink coef.</b> - allows to define relative space of elements
+compared to gaps between them in shrink mode.</li>
+</ul>
+<li><b>Orientation of Faces</b> - allows to define the behavior of
+<b>Orientation of faces</b> functionality</li>
+<ul>
+<li> \b Color - allows to define the color of orientation vertors;</li>
+<li> \b Scale - allows to define the size of orientation vectors;</li> 
+<li> <b> 3D Vector </b> checkbox allows to choose between 2D planar
+and 3D vectors.</li>
+</ul>
+</ul>
+
+<br><h2>Selection Preferences</h2>
+
+\image html pref23.png
+
+<ul>
+<li><b>Selection</b> - performed with mouse-indexing (preselection)
+and left-clicking on an object, whose appearance changes as defined in
+the <b>Preferences</b>.</li>
+<ul>
+<li><b>Object Color</b> -  allows to select the color of mesh (edges and
+borders of meshes) of the selected entity. Click on the colored line
+to access to the <b>Select Color</b> dialog
+box.</li>
+<li><b>Element color</b> - allows to select the color of surface of selected
+elements (seen in Shading mode). Click on the colored line to access
+to the <b>Select Color</b> dialog box.</li>
+</ul>
+<li><b>Preselection</b> - performed with mouse-indexing on an object,
+whose appearance changes as defined in the <b>Preferences</b>.</li>
+<ul>
+<li><b>Highlight Color</b> -  allows to select the color of mesh (edges and
+borders of meshes) of the entity . Click on the colored line to access
+to the <b>Select Color</b> dialog box.</li>
+</ul>
+<li><b>Precision</b> - in this menu you can set the value of precision
+used for <b>Nodes</b>, <b>Elements</b> and <b>Objects</b>.</li>
+</ul>
+
+<br><h2>Scalar Bar Preferences</h2>
+
+\image html pref24.png
+
+<ul>
+<li><b>Font</b> - in this menu you can set type, face and color for
+the font of <b>Title</b> and <b>Labels</b>.</li>
+<li><b>Colors & Labels</b> - in this menu you can set the <b>number of
+colors</b> and the <b>number of labels</b> in use.</li>
+<li><b>Orientation</b> - here you can choose between vertical and
+horizontal orientation of the <b>Scalar Bar</b></li>.
+<li><b>Origin & Size Vertical & Horizontal</b> - allows to define
+placement (<b>X</b> and <b>Y</b>) and lookout (<b>Width</b> and
+<b>Height</b>) of Scalar Bars</li>
+<ul>
+<li><b>X</b>: abscissa of the point of origin (from the left
+side)</li>
+<li><b>Y</b>: ordinate of the origin of the bar (from the bottom)</li>
+</ul>
+<li><b>Distribution</b> in this menu you can Show/Hide distribution histogram of the values of the <b>Scalar Bar</b> and specify the <b>Coloring Type</b> of the histogram</li>
+<ul>
+<li><b>Multicolor</b> the histogram is colored as <b>Scalar Bar</b></li>
+<li><b>Monocolor</b> the histogram is colored as selected with <b>Distribution color</b> selector</li>
+</ul>
+</ul>
+
+*/
index cd0d68ea9139b02db040ff64b4e9bcbd861b937c..968bfbc0b7c99acde86adb51fce510dccd977a5b 100644 (file)
@@ -1,34 +1,37 @@
 /*!
 
-\page mesh_through_point_page Mesh through point
+\page mesh_through_point_page Moving nodes
 
-\n In mesh you can define a node at a certain point either by creation
-of a new node, by movement of the node closest to the point or by
+\n In mesh you can define a node at a certain point either
+by movement of the node closest to the point or by
 movement of any node to the point.
 
-<em>To create a mesh passing through a point:</em>
+<em>To displace a node:</em>
 <ol>
-<li>From the \b Modification menu choose the <b>Mesh through point</b> item or
-click <em>"Mesh to pass through a point"</em> button in the toolbar.
+<li>From the \b Modification menu choose the <b>Move node</b> item or
+click <em>"Move Node"</em> button in the toolbar.
 
-\image html mesh_node_to_point.png
-<center><em>"Mesh to pass through a point" button</em></center>
+\image html image67.png
+<center><em>"Move Node" button</em></center>
 
 The following dialog box shall appear:
 
 \image html meshtopass.png
 
 </li>
-<li>Enter the coordinates of the point.</li>
-<li>Choose one of several methods: you can either \b Create a new node at
-the indicated point or Move the existing node to the point. In the
-latter case you can check in <b>Automatic search</b> of the closest node or
-select the necessary node manually. \b Preview check-box allows to see
-the results of the operation.</li>
-<li>Click the \b Apply or \b OK button.</li>
+<li>Enter the coordinates of the destination point.</li>
+<li>Check in <b>Find closest to destination</b> option or
+select the necessary node manually (X, Y, Z, dX, dY, dZ fields allow
+to see original coordinates and displacement of the node to move).
+\b Preview check-box allows to see the results of the operation.</li>
+<li>Click the \b Apply or <b>Apply and Close</b> button.</li>
 </ol>
 
+\image html moving_nodes1.png "The initial mesh"
+
+\image html moving_nodes2.png "The modified mesh"
+
 <br><b>See Also</b> a sample TUI Script of a 
-\ref tui_mesh_through_point "Mesh through point" operation.  
+\ref tui_moving_nodes "Moving Nodes" operation.  
 
 */
\ No newline at end of file
index af631b0ec14ce67dd61b2fd36b73e04b9354f134..4236d65627f02a43ba4dc9212643ecf227e1d9ae 100644 (file)
@@ -10,7 +10,8 @@ element (triangle or quadrangle).
 <ol>
 <li>Display your mesh in the viewer.</li>
 
-<li>Choose <b>Controls > Minimum angle</b> or click <em>"Minimum Angle"</em> button.
+<li>Choose <b>Controls > Face Controls > Minimum angle</b> or click
+<em>"Minimum Angle"</em> button.
 
 \image html image38.png
 <center><em>"Minimum Angle" button</em></center>
index d3149b7301eaa0d5a11623772abcfabe9c2dc2e6..36c4e0abbae041ef649ee5bea334385cb76eac68 100644 (file)
@@ -18,24 +18,27 @@ elements of the mesh.</li>
 its elements.</li>
 <li>\subpage rotation_page "Rotate" by the indicated axis and angle
 the mesh or some of its elements.</li>
-<li>Create a \subpage symmetry_page "symmetrical copy" of the mesh
+<li>\subpage scale_page "Scale" the mesh or some of its
+elements.</li>
+<li>\subpage symmetry_page "Mirror" the mesh
 through a point or a vector of symmetry.</li>
+<li>\subpage double_nodes_page "Duplicate nodes" to emulate a crack in the model.</li>
 <li>Unite meshes by \subpage sewing_meshes_page "sewing" free borders,
 conform free borders, border to side or side elements.</li>
-<li>\subpage merging_nodes_page "Merge Notes", considered coincident
+<li>\subpage merging_nodes_page "Merge Nodes", considered coincident
 within the indicated tolerance.</li>
 <li>\subpage merging_elements_page "Merge Elements", considered coincident
 within the indicated tolerance.</li>
-<li>\subpage moving_nodes_page "Move Nodes" to an arbitrary location
+<li>\subpage mesh_through_point_page "Move Nodes" to an arbitrary location
 with consequent transformation of all adjacent elements and edges.</li>
-<li>\subpage mesh_through_point_page "Make node at a point", existing
-or created anew.</li>
 <li>\subpage diagonal_inversion_of_elements_page "Invert an edge" between neighboring triangles.</li>
 <li>\subpage uniting_two_triangles_page "Unite two triangles".</li>
 <li>\subpage uniting_set_of_triangles_page "Unite several adjacent triangles".</li>
 <li>\subpage changing_orientation_of_elements_page "Change orientation"
  of the selected elements.</li>
+<li>\subpage reorient_faces_page "Reorient faces by vector".</li>
 <li>\subpage cutting_quadrangles_page "Cut a quadrangle" into two triangles.</li>
+<li>\subpage split_to_tetra_page "Split" volumic elements into tetrahedra.</li>
 <li>\subpage smoothing_page "Smooth" elements, reducung distortions in
 them by adjusting the locations of element corners.</li>
 <li>Create an \subpage extrusion_page "extrusion" along a vector.</li>
@@ -45,6 +48,12 @@ of the selected node or edge.</li>
 <li>Apply \subpage pattern_mapping_page "pattern mapping".</li>
 <li>\subpage convert_to_from_quadratic_mesh_page "Convert regular mesh to quadratic", 
 or vice versa.</li>
+<li>\subpage make_2dmesh_from_3d_page "Generate boundary elements".</li>
+<li>\subpage generate_flat_elements_page "Generate flat elements on group boundaries or on faces".</li>
+<li>\subpage cut_mesh_by_plane_page "Cut a tetrahedron mesh by a plane".</li>
 </ul>
 
-*/
\ No newline at end of file
+\note It is possible to use the variables defined in the SALOME \b NoteBook
+ to specify the numerical parameters used for modification of any object.
+
+*/
diff --git a/doc/salome/gui/SMESH/input/moving_nodes.doc b/doc/salome/gui/SMESH/input/moving_nodes.doc
deleted file mode 100644 (file)
index d44ddc2..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*!
-
-\page moving_nodes_page Moving nodes
-
-\n In MESH you can change the location of any node of your mesh. In
-this case all adjacent elements (edges) will be also transformed right
-after the displaced node.
-
-<em>To displace a node:</em>
-<ol>
-<li>From the \b Modification menu choose the <b>Move node</b> item or
-click <em>"Move Node"</em> button in the toolbar.
-
-\image html image67.png
-<center><em>"Move Node" button</em></center>
-
-The following dialog box shall appear:
-
-\image html movenodes.png
-
-</li>
-<li>Enter the ID of the required node in the <b>Node ID</b> field or
-select this node in the 3D viewer. The coordinates of your node will
-be automatically displayed in the \b Coordinates set of fields.</li>
-<li>Set new coordinates for your node in the \b Coordinates set of fields.</li>
-<li>Click the \b Apply or <b>Apply and Close</b> button.</li>
-</ol>
-
-\image html moving_nodes1.png "The initial mesh"
-
-\image html moving_nodes2.png "The node has been moved, transforming all adjacent edges"
-
-<br><b>See Also</b> a sample TUI Script of a 
-\ref tui_moving_nodes "Moving Nodes" operation.  
-
-*/
\ No newline at end of file
diff --git a/doc/salome/gui/SMESH/input/netgen_2d_3d_hypo.doc b/doc/salome/gui/SMESH/input/netgen_2d_3d_hypo.doc
deleted file mode 100644 (file)
index f81ed26..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*!
-
-\page netgen_2d_3d_hypo_page Netgen 2D and 3D hypotheses
-
-\n <b>Netgen 2D</b> and <b>Netgen 3D</b> hypotheses work only with <b>Netgen 1D-2D</b> and
-<b>Netgen 1D-2D-3D</b> algorithms. These algorithms do not require
-definition of lower-level  hypotheses and algorithms (2D and 1D for
-meshing 3D objects and 1D for meshing 2D objects). They prove to be
-useful if lower-level meshing is homogeneous for all wires and faces
-of the meshed object.
-
-\image html netgen2d.png
-
-<ul>
-<li><b>Name</b> - allows to define the name for the algorithm (Netgen
-2D (or 3D) Parameters by default).</li>
-<li><b>Max Size</b> - maximum linear dimensions for mesh cells.</li>
-<li><b>Second Order</b> - if this box is checked in, the algorithm will
-create second order nodes on the mesh, which actually will become
-\ref adding_quadratic_elements_page "Quadratic".</li>
-<li><b>Fineness</b> - ranging from Very Coarse to Very Fine allows to set the
-level of meshing detalization using the three parameters below. You
-can select Custom to define them manually.</li>
-<li><b>Growth rate</b> - allows to define how much the linear dimensions of
-two adjacent cells can differ (i.e. 0.3 means 30%).</li>
-<li><b>Nb. Segs per Edge</b> and <b>Nb Segs per Radius</b> - allows to define the
-minimum number of mesh segments in which edges and radiuses will be
-split.</li>
-<li><b>Allow Quadrangles</b> - allows to use quadrangle elements in a
-triangle 2D mesh. This checkbox is not present in Netgen 3D parameters
-because currently building a tetrahedral mesh with quadrangle faces is
-not possible.</li>
-<li><b>Optimize</b> - if this box is checked in, the algorithm will try to
-create regular (possessing even sides) elements.</li>
-</ul>
-
-\image html netgen3d_simple.png
-
-<b>Netgen 2D simple parameters</b> and <b>Netgen 3D simple parameters</b> allow defining the size of elements for each dimension. Note that Netgen algorithm does not strictly follow the input parameters. The actual mesh can be more or less dense than required.<br>
-
-\b 1D group allows defining the size of 1D elements in either of two ways: 
-<ul>
-<li><b>Number of Segments</b> has the same sense as \ref
-number_of_segments_anchor "Number of segments" hypothesis with
-equidistant distribution.</li>
-<li><b>Average Length</b> has the same sense as \ref 
-average_length_anchor "Average Length" hypothesis.</li>
-</ul>
-
-\b 2D group allows defining the size of 2D elements 
-<ul>
-<li><b>Length from edges</b> if checked in, acts like \ref
-length_from_edges_anchor "Length from Edges" hypothesis, else </li>
-<li><b>Max. Element Area</b> defines the maximum element area like \ref
-max_element_area_anchor "Max Element Area" hypothesis. </li>
-</ul>
-
-\b 3D groups allows defining the size of 3D elements.
-<ul>
-<li><b>Length from faces</b> if checked in, the area of sides of
-volumic elements will be equal to an average area of 2D elements, else </li>
-<li><b>Max. Element Volume</b> defines the maximum element volume like
-\ref max_element_volume_hypo_page "Max Element Volume"
-hypothesis.</li>
-<ul>
-
-*/
\ No newline at end of file
diff --git a/doc/salome/gui/SMESH/input/over_constrained_faces.doc b/doc/salome/gui/SMESH/input/over_constrained_faces.doc
new file mode 100644 (file)
index 0000000..6c026f8
--- /dev/null
@@ -0,0 +1,19 @@
+/*!
+
+\page over_constrained_faces_page Over-constrained faces
+
+\n This mesh quality control highlights faces sharing only one border
+with other faces. In other words, the faces having all thier nodes on
+the external border of the mesh are highlighted.
+
+\note The highlighted faces are actually over-constrained only if, at the computation time, 
+the boundary conditions on the borders where the nodes are located are all Dirichlet boundary conditions.
+
+\image html over_constrained_faces.png
+
+In this picture the over-constrained face is displayed in red.
+
+<br><b>See Also</b> a sample TUI Script of a 
+\ref tui_over_constrained_faces "Over-constrained faces" filter.  
+
+*/
diff --git a/doc/salome/gui/SMESH/input/over_constrained_volumes.doc b/doc/salome/gui/SMESH/input/over_constrained_volumes.doc
new file mode 100644 (file)
index 0000000..7f1ba28
--- /dev/null
@@ -0,0 +1,18 @@
+/*!
+
+\page over_constrained_volumes_page Over-constrained volumes
+
+\n This mesh quality control highlights volumes sharing only one border with other volumes.
+In other words, the volumes having all their nodes on the external border of the mesh are highlighted.
+
+\note The highlighted volumes are actually over-constrained only if, at the computation time, 
+the boundary conditions on the borders where the nodes are located are all Dirichlet boundary conditions.
+
+\image html over_constrained_volumes.png
+
+In this picture the over-constrained volume is displayed in red.
+
+<br><b>See Also</b> a sample TUI Script of a 
+\ref tui_over_constrained_volumes "Over-constrained volumes" filter.  
+
+*/
index cf556d51bb714014f79fcf10da665796c6b22092..ef7f8ba66a704be2910dfba199764ad1a3e4665f 100644 (file)
@@ -5,36 +5,87 @@
 <br><h2>About patterns</h2>
 
 The pattern describes a mesh to generate: positions of nodes within a
-geometrical domain and nodal connectivity of elements. As well, a
-pattern specifies the so-called key-points, i.e. nodes that will be
-located at geometrical vertices. Pattern description is stored in
+geometrical domain and nodal connectivity of elements. A
+pattern also specifies the so-called key-points, i.e. the nodes that will be
+located at geometrical vertices. The pattern description is stored in
 \<pattern_name\>.smp file.
 
 The smp file contains 4 sections:
-<ol>
-<li>The first line holds the number of nodes (N).</li>
 
-<li>The next N lines describe nodes coordinates. Each line holds 2
-coordinates of a node.</li>
-
-<li>A key-points line: indices of nodes to be mapped on geometrical
-vertices. An index n refers to a node described on an n-th line of
-section 2. The first node index is zero.</li>
-
-<li>The rest lines describe nodal connectivity of elements, one line
-for an element. A line holds indices of nodes forming an element. An
-index n refers to a node described on an n-th line of the section
-2. The first node index is zero. There must be 3 or 4 indices on a
-line: only 2d elements are allowed.</li>
-</ol>
-
-The 2D pattern must contain at least one element and at least one
-key-point. All key-points must lay on boundaries.
-
-An example of a simple smp file and a preview of a pattern described
-in this file:
-
-\image html image94.gif
+-# The first line indicates the total number of pattern nodes (N).
+-# The next N lines describe nodes coordinates. Each line contains 2
+node coordinates for a 2D pattern or 3 node cordinates for a 3D pattern.
+Note, that node coordinates of a 3D pattern can be defined only by relative values in range [0;1].
+-# The key-points line contains the indices of the nodes to be mapped on geometrical
+vertices (for a 2D pattern only). Index n refers to the node described 
+on the n-th line of section 2. The index of the first node zero. For a 3D pattern the key points are not specified.
+-# The remaining lines describe nodal connectivity of elements, one line
+for each element. Each line holds indices of nodes forming an element.
+Index n refers to the node described on the n-th line of section 2.
+The first node index is zero. There must be 3 or 4 indices on each
+line for a 2D pattern (only 2d elements are allowed) and 4, 5, 6 or 8
+indices for a 3D pattern (only 3d elements are allowed).
+
+A 2D pattern must contain at least one element and at least one
+key-point. All key-points must lie on boundaries.
+
+A 3D pattern must contain at least one element.
+
+An example of a simple 2D pattern smp file:
+
+\code
+!!! SALOME 2D mesh pattern file
+!!!
+!!! Nb of points:
+9
+        200     0       !- 0
+        100     0       !- 1
+          0     0       !- 2
+          0  -100       !- 3
+          0  -200       !- 4
+        100  -200       !- 5
+        200  -200       !- 6
+        200  -100       !- 7
+        100  -100       !- 8
+!!! Indices of 4 key-points
+ 2 0 4 6
+!!! Indices of points of 6 elements
+ 0 1 8
+ 8 5 6 7
+ 2 3 8
+ 8 3 4 5
+ 8 7 0
+ 8 1 2
+\endcode
+
+The image below provides a preview of the above pattern:
+
+\image html pattern2d.png
+
+An example of a simple 3D pattern smp file:
+
+\code
+!!! SALOME 3D mesh pattern file
+!!!
+!!! Nb of points:
+9
+        0        0        0   !- 0
+        1        0        0   !- 1
+        0        1        0   !- 2
+        1        1        0   !- 3
+        0        0        1   !- 4
+        1        0        1   !- 5
+        0        1        1   !- 6
+        1        1        1   !- 7
+      0.5      0.5      0.5   !- 8
+!!! Indices of points of 6 elements:
+ 0 1 5 4 8
+ 7 5 1 3 8
+ 3 2 6 7 8
+ 2 0 4 6 8
+ 0 2 3 1 8
+ 4 5 7 6 8
+\endcode
 
 <br><h2>Application of pattern mapping</h2>
 
@@ -46,90 +97,122 @@ From the \b Modification menu choose the <b>Pattern Mapping</b> item or click
 \image html image98.png
 <center><em>"Pattern mapping" button</em></center>
 
-The following dialog box shall appear:
+The following dialog box will appear:
+
+\n For a <b>2D pattern</b>
 
 \image html patternmapping1.png
 
+In this dialog you should specify:
+
+<ul>
+<li> \b Pattern, which can be loaded from .smp pattern file previously
+created manually or generated automatically from an existing mesh or submesh.</li>
+<li> \b Face with the number of vertices equal to the number of
+     key-points in the pattern; the number of key-points on internal
+     boundaries of the pattern must also be equal to the number of vertices
+     on internal boundaries of the face;</li>
+<li> \b Vertex to which the first key-point should be mapped;</li>
+Alternatively, it is possible to select <b>Refine selected mesh elements</b> 
+checkbox and apply the pattern to
+<li> <b>Mesh Face</b> instead of a geometric Face</li>
+<li> and select \b Node instead of vertex.</li>
+
+Additionally it is possible to:
+<li> <b>Reverse the order of key-points</b> By default, the vertices of
+     a face are ordered counterclockwise.<li>
+<li> Enable to <b> Create polygons near boundary</b> </li>
+<li> and <b>Create polyhedrons near boundary</b><li>  
+</ul>
+
+\n For a <b>3D pattern</b>
+
 \image html patternmapping2.png
 
-To apply a pattern to a geometrical object, you should specify:
+In this dialog you should specify:
 <ul>
-<li>a face having the number of vertices equal to the number of
-key-points in the pattern; the number of key-points on internal
-boundaries of a pattern must also be equal to the number of vertices
-on internal boundaries of a face;</li>
-<li>a vertex to which the first key-point should be mapped;</li>
-<li>reverse or not the order of key-points. (The order of vertices of
-a face is counterclockwise looking from outside).</li>
+<li> \b Pattern, which can be loaded from .smp pattern file previously
+created manually or generated automatically from an existing mesh or submesh.</li>
+   <li> A 3D block (Solid) object;</li>
+   <li> Two vertices that specify the order of nodes in the resulting mesh.</li>
+Alternatively, it is possible to select <b>Refine selected mesh elements</b> 
+checkbox and apply the pattern to
+<li> One or several <b>Mesh volumes</b> instead of a geometric 3D
+object</li>
+<li> and select two /b Nodes instead of vertices.</li> 
+Additionally it is possible to:
+<li> Enable to <b> Create polygons near boundary</b> </li>
+<li> and <b>Create polyhedrons near boundary</b><li>
 </ul>
 
-Then you either load a .smp pattern file previously created manually
-by clicking on the <em>"Load pattern"</em> button, or click on the \b
-New button for automatic generation.
-\n For an automatic generation you just specify a geometrical face
-having a mesh built on it. Mesh nodes lying on face vertices become
-key-points. Additionally, you may choose the way of getting nodes
-coordinates by <b>projecting nodes on the face</b> instead of using
-"positions on face" generated by mesher (if there is any). Faces
-having a seam edge can?t be used for automatic pattern creation.
-
-When creating a pattern from an existing mesh, there are two possible
-cases:
-<ol>
-<li>A sub-mesh on face is selected. A pattern is created from the 2d
-elements bound to a face by mesher. Node coordinates are either
-"positions on face" computed by mesher, or coordinates got by node
-projection on a geometrical surface, according to your choice.</li>
-<li>A mesh where the main shape is a face, is selected. A pattern is
-created from all the 2d elements in a mesh. If all mesh elements are
-build by mesher, the user can select the way of getting nodes
-coordinates, else all nodes are projected on a face surface.</li>
-</ol>
-
-\image html a-patterntype.png
+\n Automatic Generation 
+
+To generate a pattern automatically from an existing mesh or submesh,
+click \b New button.
+
+The following dialog box will appear:
 
 \image html a-patterntype1.png
 
-<br><h2>Mapping algorithm</h2>
+In this dialog you should specify:
 
-The mapping algorithm is as follows:
-<ol>
-<li>Key-points are set in the order that they are encountered when
-walking along a pattern boundary so that elements are on the left. The
-first key-point is preserved.
-</li>
+<ul>
+<li> <b>Mesh or Submesh</b>, which is a meshed geometrical face (for a
+2D pattern) or a meshed solid (for a 3D pattern). Mesh nodes lying on
+the face vertices become key-points of the pattern. </li>
+<li> A custom <b>Pattern Name </b> </li>
+<li>Additionally, for a 2D pattern you may choose to 
+<b>Project nodes on the face</b> to get node coordinates instead of using
+"positions on face" generated by the mesher (if there is any). The faces
+having a seam edge cannot be used for automatic pattern creation.</li>
+</ul>
 
-<li>Find geometrical vertices corresponding to key-points by vertices
-order in a face boundary; here, "Reverse order of key-points" flag is
-taken into account.
+When a pattern is created from an existing mesh, two cases are possible:
 
-\image html image95.gif
-</li>
+- A sub-mesh on a face/solid is selected. The pattern is created from the 2d/3d
+elements bound to the face/solid by the mesher. For a 2D pattern, the node coordinates are either
+"positions on face" computed by the mesher, or coordinates got by node
+projection on a geometrical surface, according to the user choice. For
+a 3D pattern, the node coordinates correspond to the nodes computed by
+the mesher.
+- A mesh, where the main shape is a face/solid, is selected. The pattern is
+created from all 2d/3d elements in a mesh. In addition, if all mesh
+elements of a 2D pattern are built by the mesher, the user can select
+how to get node coordinates, otherwise all nodes are projected on
+a face surface.
 
-<li>Boundary nodes of a pattern are mapped onto edges of a face: a
-node located between certain key-points on a pattern boundary is
-mapped on a geometrical edge limited by corresponding geometrical
-vertices. Node position on an edge reflects its distance from two
-key-points.
 
-\image html image96.gif
-</li>
-
-<li>Coordinates of a non-boundary node in a parametric space of a face
-are defined as following. In a parametric space of a pattern, a node
-lays at the intersection of two iso-lines, each of which intersects a
-pattern boundary at least at two points. Knowing mapped positions of
-boundary nodes, we find where isoline-boundary intersection points are
-mapped to, and hence we can find mapped isolines direction and then,
-two node positions on two mapped isolines. The eventual mapped
-position of a node is found as an average of positions on mapped
-isolines.
+<br><h2>Mapping algorithm</h2>
+
+The mapping algorithm for a 2D case is as follows:
 
+- The key-points are set counterclockwise in the order corresponding
+  to their location on the pattern boundary. The first key-point is preserved.
+- The geometrical vertices corresponding to the key-points are found
+  on face boundary. Here, "Reverse order of key-points" flag is set. 
+\image html image95.gif
+- The boundary nodes of the pattern are mapped onto the edges of the face: a
+  node located between two key-points on the pattern boundary is
+  mapped on the geometrical edge limited by the corresponding geometrical
+  vertices. The node position on the edge depends on its distance from the
+  key-points. 
+\image html image96.gif
+- The cordinates of a non-boundary node in the parametric space of the face
+ are defined in the following way. In the parametric space of the
+  pattern, the  node lies at the intersection of two iso-lines. Both
+  of them intersect the pattern boundary at two
+  points at least. If the mapped positions of boundary nodes are known, it is
+  possible to find, where the points at the intersection of isolines
+  and boundaries are mapped. Then it is possible to find
+  the direction of mapped isolinesection and, filally, the poitions of
+  two nodes on two mapped isolines. The eventual mapped
+ position of the node is found as an average of the positions on mapped
+ isolines. 
 \image html image97.gif
-</li>
-</ol>
 
-<br><b>See Also</b> a sample TUI Script of a 
+The 3D algorithm is similar.
+
+<b>See Also</b> a sample TUI Script of a 
 \ref tui_pattern_mapping "Pattern Mapping" operation.
 
-*/
\ No newline at end of file
+*/
diff --git a/doc/salome/gui/SMESH/input/point_marker.doc b/doc/salome/gui/SMESH/input/point_marker.doc
new file mode 100644 (file)
index 0000000..40c2b93
--- /dev/null
@@ -0,0 +1,53 @@
+/*!
+
+\page point_marker_page Point Marker
+
+\n You can change the representation of points in
+the 3D viewer either by selecting one of the predefined
+shapes or by loading a custom texture from an external file.
+
+- Standard point markers
+
+The Mesh module provides a set of predefined point marker shapes
+which can be used to display points in the 3D viewer.
+Each standard point marker has two attributes: type (defines shape
+form) and scale factor (defines shape size).
+
+\image html point_marker_widget1.png
+
+<br>
+
+\image html std_point_marker.png "Mesh presentation with standard point markers"
+
+- Custom point markers
+
+It is also possible to load a point marker shape from an external file.
+This file should provide a description of the point texture as a set
+of lines; each line is represented as a sequence of "0" and "1" symbols,
+where "1" symbol means an opaque pixel and "0" symbol means a
+transparent pixel. The width of the texture corresponds to the length
+of the longest line in the file, expanded to the nearest byte-aligned
+value. The height of the texture is equal to the number of non-empty
+lines in the file. Note that missing symbols are replaced by "0".
+
+Here is a texture file sample:
+
+<pre>
+00111100
+00111100
+11111111
+11111111
+11111111
+11111111
+00111100
+00111100
+</pre>
+
+\image html point_marker_widget2.png
+
+<br>
+
+\image html custom_point_marker.png "Mesh presentation with custom point markers"
+
+*/
+
diff --git a/doc/salome/gui/SMESH/input/preview_meshes.doc b/doc/salome/gui/SMESH/input/preview_meshes.doc
deleted file mode 100644 (file)
index 92a4cca..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*!
-
-\page preview_meshes_page Preview and Compute meshes
-
-Before whole mesh computation it is allowed to see the mesh preview.
-When mesh object is already created and all hypotheses assigned,
-select your mesh in the <b>Object Browser</b>. From the
-\b Mesh menu select \b Preview or click "Preview" button of the
-toolbar or activate "Preview" item from pop-up menu.
-
-\image html mesh_precompute.png
-<center><em>"Preview" button</em></center>
-
-The Mesh Preview dialog box appears. In this dialog box you can select
-preview mode <b>1D mesh</b> or <b>2D mesh</b> depending on assigned
-hypotheses to mesh. 
-
-The 1D mesh preview shows as nodes computed on geometry edges
-
-\image html preview_mesh_1D.png
-
-The 2D mesh preview shows edge mesh elements, computed on geometry faces
-
-\image html preview_mesh_2D.png
-
-Pressing <b>Compute</b> button leads to whole mesh computation
-process.
-During exit from Preview dialog box, the question about storage temporary
-created mesh elements appers:
-
-\image html preview_tmp_data.png
-
-Note, that computed temporary mesh elements can be reused during next
-mesh computation process.
-
-*/
index 837923ac1ce8afa4432f89c356aa2d5b322a685a..5589ba3a761c8199ea4716deab69ce9cacb9ad88 100644 (file)
@@ -4,9 +4,9 @@
 
 3D extrusion algorithm can be used for meshing prisms, i.e. <b>3D Shapes</b>
 defined by two opposing faces having the same number of vertices and
-edges and meshed using the \ref projection_algos_page "2D Projection"
-algorithm. These two faces should be connected by quadrangle "side"
-faces.
+edges and meshed using, for example,  the \ref projection_algos_page
+"2D Projection" algorithm. These two faces should be connected by
+quadrangle "side" faces.
 
 The opposing faces can be meshed with either quadrangles or triangles,
 while the side faces should be meshed with quadrangles only.
@@ -17,4 +17,8 @@ As you can see, the <b>3D extrusion</b> algorithm permits to build and to
 have in the same 3D mesh such elements as hexahedrons, prisms and
 polyhedrons.
 
-*/
\ No newline at end of file
+\note This algorithm works correctly only if the opposing faces have
+the same (or similar) meshing topography. Otherwise, 3D extrusion
+algorithm can fail to build mesh volumes.
+
+*/
index 422b4099335688c853804394d69380a8f1de0749..dcbae8db4056b95ac68be47f352b383f4e82feb9 100644 (file)
@@ -17,14 +17,18 @@ The following dialog box will appear:
 \image html projection_1d.png
 
 In this menu you can define the \b Name of the algorithm, the already
-meshed source \b Edge and the \b Mesh (optional, use it if there are several
-different meshes on the same edge). It could also be necessary to
-define the orientation of edges, which is done by indicating the
-<b>Source Vertex</b> being the first point of the Source Edge and the 
-<b>Target Vertex</b> being the first point of the created \b Edge. For
-a group of edges, <b>Source</b> and <b>Target</b> vertices should be
-shared by only one edge of the group. If <b>Source</b> and
-<b>Target</b> vertices are specified, the elements of the group must be ajacent.
+meshed source \b Edge and the \b Mesh  (It can be omitted only when 
+projecting a submesh on another one from the same global Mesh). 
+It could also be necessary to define the orientation of edges, 
+which is done by indicating the <b>Source Vertex</b> being the first point 
+of the Source Edge and the <b>Target Vertex</b> being the first point of 
+the created \b Edge. 
+<br>
+For a group of edges, <b>Source</b> and <b>Target</b> vertices should be
+shared by one edge of the group. If <b>Source</b> and <b>Target</b>
+vertices are specified, the elements of the group must be adjacent.
+The source and target groups must contain equal number of edges
+and they must form topologically equal structures.
 
 \n <b>Projection 2D</b> algorithm allows to define the mesh of a face
 (or group of faces) by the
@@ -42,17 +46,26 @@ following dialog box will appear:
 \image html projection_2d.png
 
 In this menu you can define the \b Name of the algorithm, the already
-meshed source \b Face and the \b Mesh (optional, use it if there are several
-different meshes on the same face). It could also be necessary to
-define the orientation of mesh on the face, which is done by
-indicating two <b>Source Vertices</b>, which belong to the same edge of the
-source face, and two <b>Target Vertices</b>, which belong to the same edge of
-the created \b Face.
+meshed source \b Face and the \b Mesh (It can be omitted only when 
+projecting a submesh on another one from the same global Mesh). 
+It could also be necessary to define the orientation of mesh on the
+face, which is done by indicating two <b>Source Vertices</b>, which
+belong to the same edge of the source face, and two <b>Target
+Vertices</b>, which belong to the same edge of the created \b Face.
+For groups of face, they must contain equal number of faces
+and they must form topologically equal structures.
+
+\n <b>Projection 1D-2D</b> algorithm differs from <b>Projection 2D</b>
+algorithm in one aspect: it generates mesh segments on edges of
+the face according to the projected 2D elements; thus it does not
+require the edges to be meshed by any other 1D algorithm; moreover it
+does not allow to mesh edges of the face using another algorithm via
+definition of sub-meshes.
 
 \n <b>Projection 3D</b> algorithm allows to define the mesh of a shape by
 the projection of another already meshed shape.  This algorithm works
-only if all faces and edges of the target face have been meshed as 1D
-Projections of the faces and edges of the source face. Another
+only if all faces and edges of the target shape have been meshed as 1D-2D
+Projections of the faces and edges of the source shape. Another
 limitation is that this algorithm currently works only on boxes.
 
 To apply this algorithm select the solid to be meshed (indicated in
@@ -63,12 +76,15 @@ following dialog box will appear:
 \image html projection_3d.png
 
 In this menu you can define the \b Name of the algorithm, the already
-meshed source <b>3D shape</b> and the \b Mesh (optional, use it if there are
-several different meshes on the same shape). It could also be
-necessary to define the orientation of mesh on the shape, which is
+meshed source <b>3D shape</b> and the \b Mesh (It can be omitted only when 
+projecting a submesh on another one from the same global Mesh). 
+It could also be necessary to define the orientation of mesh on the shape, which is
 done by indicating two <b>Source Vertices</b>, which belong to the same edge
 of the source <b>3D Shape</b>, and two <b>Target Vertices</b>, which belong to the
 same edge of the source <b>3D Shape</b>.
 
+<br><b>See Also</b> a sample TUI Script of a 
+\ref tui_projection "Projection Algorithms".
+
 */
 
diff --git a/doc/salome/gui/SMESH/input/radial_quadrangle_1D2D_algo.doc b/doc/salome/gui/SMESH/input/radial_quadrangle_1D2D_algo.doc
new file mode 100644 (file)
index 0000000..0854941
--- /dev/null
@@ -0,0 +1,29 @@
+/*!
+
+\page radial_quadrangle_1D2D_algo_page Radial Quadrangle 1D2D
+
+\n This algorithm applies to the meshing of 2D shapes under the
+following conditions: the face must be a full circle or a part of circle
+(i.e. the number of edges is less or equal to 3 and one of them is a circle curve).
+The resulting mesh consists of triangles (near the center point) and
+quadrangles.
+
+This algorithm is optionally parametrized by the hypothesis indicating the number
+of mesh layers along the radius. The distribution of layers can be set with any 1D Hypothesis.
+
+If no own hypothesis of the algorithm is assigned, any local or global hypothesis is used 
+by the algorithm to discretize edges. Note that if the geometrical face has two radial edges,
+they must be meshed with equal number of segments.
+
+If no 1D hypothesis is assigned to an edge, "Default Number of Segments" preferences parameter
+is used to discretize the edge.
+
+\image html hypo_radquad_dlg.png
+
+\image html mesh_radquad_01.png "Radial Quadrangle 2D mesh on the top and the bottom faces of a cylinder"
+
+\image html mesh_radquad_02.png "Radial Quadrangle 2D mesh on a part of circle"
+
+\sa A sample \ref tui_radial_quadrangle "TUI Script".
+
+*/
index 6e0f7f804eb404a9360221e45737b5d6f31ccd97..0a48ee65e9f5b3c6d50504e6d41b3e133e98a4d9 100644 (file)
@@ -6,6 +6,7 @@
 
 <ul>
 <li>\ref removing_nodes_anchor "Nodes"</li>
+<li>\ref removing_orphan_nodes_anchor "Orphan Nodes"</li>
 <li>\ref removing_elements_anchor "Elements"</li>
 <li>\ref clear_mesh_anchor "Clear Mesh Data"</li>
 </ul>
 <ol>
 <li>Select your mesh in the Object Browser or in the 3D viewer.</li>
 
-<li>From the Modification menu choose Remove and from the associated
-submenu select the Remove nodes, or just click <em>"Remove nodes"</em>
+<li>From the <em>Modification</em> menu choose <em>Remove</em> and from the associated
+submenu select the <em>Nodes</em>, or just click <em>"Remove nodes"</em>
 button in the toolbar.
 
-\image html image88.gif
+\image html remove_nodes_icon.png
 <center><em>"Remove nodes" button</em></center>
 
 The following dialog box will appear:
 
 \image html removenodes.png
 
-In this dialog box you can specify one or several nodes
+In this dialog box you can specify one or several nodes:
 <ul>
-<li>Choosing them manually with the mouse in the 3D Viewer. You can
-click on a node in the 3D viewer and it will be highlighted</li>
-<li>Applying Filters. The <b>Set filter</b> button allows to apply a
-definite filter to selection of the nodes. See more
-about filters on the
-\ref selection_filter_library_page "Selection filter library" page.</li>
+<li>choose mesh nodes with the mouse in the 3D Viewer. It is
+possible to select a whole area with a mouse frame; or</li> 
+<li>input the node IDs directly in <b>ID Elements</b> field. The selected nodes will be highlighted in the
+viewer; or</li>
+<li>apply Filters. <b>Set filter</b> button allows to apply a filter to the selection of nodes. See more
+about filters in the \ref selection_filter_library_page "Selection filter library" page.</li>
 </ul>
+
+
 </li>
 </ol>
 
 \note Be careful while removing nodes because if you remove a definite
 node of your mesh all adjacent elements will be also deleted.
 
+<br>
+\anchor removing_orphan_nodes_anchor
+<h2>Removing orphan nodes</h2>
+
+There is a quick way to remove all orphan (free) nodes.
+
+<em>To remove orphan nodes:</em>
+<ol>
+<li>Select your mesh in the Object Browser or in the 3D viewer.</li>
+
+<li>From the <em>Modification</em> menu choose <em>Remove</em> and from the associated
+submenu select <em>Orphan Nodes</em>, or just click <em>"Remove orphan nodes"</em>
+button in the toolbar.
+
+\image html remove_orphan_nodes_icon.png
+<center><em>"Remove orphan nodes" button</em></center>
+
+The following Warning message box will appear:
+
+\image html removeorphannodes.png
+
+Confirm nodes removal by pressing "Yes" button.
+</ol>
+
 <br>
 \anchor removing_elements_anchor
 <h2>Removing elements</h2>
@@ -52,8 +79,8 @@ node of your mesh all adjacent elements will be also deleted.
 <ol>
 <li>Select your mesh in the Object Browser or in the 3D viewer.</li>
 
-<li>From the \b Modification menu choose \b Remove and from the
-associated submenu select the Remove elements, or just click
+<li>From the <em>Modification</em> menu choose <em>Remove</em> and from the
+associated submenu select the <em>Elements</em>, or just click
 <em>"Remove elements"</em> button in the toolbar.
 
 \image html remove_elements_icon.png
@@ -65,13 +92,14 @@ The following dialog box will appear:
 
 In this dialog box you can specify one or several elements
 <ul>
-<li>Choosing them manually with the mouse in the 3D Viewer. You can
-click on an element in the 3D viewer and it will be highlighted</li>
-<li>Applying Filters. The <b>Set filter</b> button allows to apply a
-definite filter to selection of the elements. See more
-about filters on the
-\ref selection_filter_library_page "Selection filter library" page.</li>
+<li>choose mesh elements with the mouse in the 3D Viewer. It is
+possible to select a whole area with a mouse frame; or</li> 
+<li>input the element IDs directly in <b>ID Elements</b> field. The selected elements will be highlighted in the
+viewer; or</li>
+<li>apply Filters. <b>Set filter</b> button allows to apply a filter to the selection of elements. See more
+about filters in the \ref selection_filter_library_page "Selection filter library" page.</li>
 </ul>
+
 </li>
 <li>Click \b Apply or <b>Apply and Close</b> to confirm deletion of the specified elements.</li>
 </ol>
@@ -91,7 +119,7 @@ about filters on the
 <li>From the Modification menu choose Remove and from the associated
 submenu select the Clear Mesh Data, or just click <em>"Clear Mesh Data"</em>
 button in the toolbar. You can also right-click on the mesh in the
-Object Browser and select Clear Mesh Data in the pop-up menu.
+Object Browser and select Clear Mesh Data in the pop-up menu.</li>
 </ol>
 
 \image html mesh_clear.png
diff --git a/doc/salome/gui/SMESH/input/reorient_faces.doc b/doc/salome/gui/SMESH/input/reorient_faces.doc
new file mode 100644 (file)
index 0000000..f637aec
--- /dev/null
@@ -0,0 +1,61 @@
+/*!
+
+\page reorient_faces_page Reorient faces by vector
+
+\n This operation allows changing orientation of a set of neighboring
+faces. The desired orientation is defined by a vector. Since direction
+of face normals in the set can be even opposite, it is necessary to
+specify a control face whose normal will be compared with the vector. This
+face can be specified either explicitly or can be found by closeness to
+a given point.
+
+Orientation of a face is changed by reverting the order of its nodes.
+
+<em>To change orientation of faces:</em>
+<ol>
+<li>In the \b Modification menu select the <b>Reorient faces by
+    vector</b> item or click <em>Reorient faces by
+    vector</em> button in the toolbar.
+
+<center>
+\image html reorient_faces_face.png
+<em>"Reorient faces by vector" button</em>
+</center>
+
+The following dialog box will appear:
+
+<center>
+\image html reorient_2d_point.png
+\image html reorient_2d_face.png
+</center>
+
+<li>In this dialog
+<ul>
+<li>Specify a way of selection of the control face: by point or
+  explicitely.</li>
+<li>Select an \b Object containing faces to reorient, either in the Object
+  Browser or in the 3D Viewer; it can be either <ul>
+    <li>group of faces,</li>
+    <li>sub-mesh of faces or</li>
+    <li>mesh.</li>
+    </ul></li>
+<li>Specify either coordinates of a \b Point by which the control face
+  will be found or the control \b Face it-self. You can easy specify the \b
+  Point by either picking a node in the 3D Viewer or by selecting a vertex
+  in the Object Browser. The \b Face can be either picked by mouse in
+  the 3D Viewer or its ID can be entered by typing.</li>
+<li>Set up a \b Direction to be compared with the normal of the
+  control face. You can either pick a node in the 3D Viewer then a \b Direction
+  from the coordinate system origin to the selected node will be set,
+  or you can pick two nodes (holding Shift button) then a \b Direction
+  from the first to the second node will be set.</li>
+</ul>
+</li>
+
+<li>Click the \b Apply or <b>Apply and Close</b> button to confirm the operation.</li>
+</ol>
+
+<br><b>See Also</b> a sample TUI Script of a
+\ref tui_reorient_faces "Reorient faces by vector" operation. 
+
+*/
index 67dfdb374cdb1aea48c01967dbd00b1b7b3715cf..1d13bb23a321e63919dae5b3200cd08ae3c283b2 100644 (file)
@@ -16,31 +16,42 @@ on the revolution axis).
 \image html image92.png
 <center><em>"Revolution" button</em></center>
 
-The following dialog box shall appear:
+The following dialog common for line and planar elements will appear:
 
 \image html revolution1.png
 
-\image html revolution2.png
 </li>
 
 <li>
-In this dialog box you should specify:
+In this dialog you should specify:
 <ul>
 <li>the type of elements which will be extruded (1D or 2D),</li>
-<li>specify the IDs of the elements which will be revolved
+<li>specify the IDs of the elements which will be revolved:
+
+
+<ul>
+<li><b>Select the whole mesh, submesh or group</b> activating this
+checkbox; or</li>
+<li>choose mesh elements with the mouse in the 3D Viewer. It is
+possible to select a whole area with a mouse frame; or</li> 
+<li>input the element IDs directly in <b>ID Elements</b> field. The selected elements will be highlighted in the
+viewer; or</li>
+<li>apply Filters. <b>Set filter</b> button allows to apply a filter to the selection of elements. See more
+about filters in the \ref selection_filter_library_page "Selection filter library" page.</li>
+</ul>
+</li>
+
+<li>specify the axis of revolution:
 <ul>
-<li>Check on <b>Select the whole mesh, submesh or group</b> option
-<li>Choosing them manually with the mouse in the 3D Viewer. You can
-click on an element in the 3D viewer and it will be highlighted</li>
-<li>Applying Filters. The <b>Set filter</b> button allows to apply a
-definite filter to selection of the elements. See more
-about filters on the
-\ref selection_filter_library_page "Selection filter library" page.</li>
+<li>specify the cooordinates of the start \b Point of the vector of revolution;</li>
+<li>specify the \b Vector of revolution through the coordinates of its
+end point with respect to the coordinates of the start
+point. Alternatively, it is possible to specify the vector through the
+normal to the selected face.</li>
 </ul>
 </li>
-<li>specify the axis (point and vector) around which the elements will
-be revolved,</li>
-<li>angle of rotation and number of steps,</li>
+
+<li>specify the angle of revolution and the number of revolution steps,</li>
 <ul> <li> Angle by Step - the elements are extruded by the specified angle at each step (i.e. for Angle=30 and Number of Steps=2, the elements will be extruded 
  by 30 degrees twice for a total of 30*2=60)</li>
 
@@ -52,15 +63,18 @@ be revolved,</li>
 \image html revolutionsn1.png "Example of Revolution with Total Angle"
 
 </ul>
-<li>tolerance of rotation</li>
-</ul>
+</li>
 
-<li> <b>Preview</b> checkbox allows showing the results of parameter-setting in the viewer </li>
-<li> <b>Generate Groups</b> checkbox allows copying the groups of
+<li>specify the tolerance for the operation</li>
+
+<li>activate  <b>Preview</b> checkbox to show the  parameter-setting in the viewer </li>
+<li>activate  <b>Generate Groups</b> checkbox to copy the groups of
 elements of the source mesh to the newly created one. </li>
 </li>
+</ul>
 
-<li>Click the \b Apply or \b OK button.</li>
+<li>Click \b Apply or <b> Apply and Close</b> button to confirm the
+operation.</li>
 </ol>
 
 
index e643572764b847143884c85c6aa92c334c2af3b9..cb46359fd43728747ddd076b71c8c4378e271ce8 100644 (file)
@@ -2,41 +2,70 @@
 
 \page rotation_page Rotation
 
-\n This operation allows to rotate in space your mesh or
+\n This operation allows to rotate in space the mesh or
 some of its elements.
 
+<em>To rotate the mesh:</em>
+
+<ol>
+<li>From the \b Modification menu choose \b Transformation -> \b Rotation item  or click
+<em>"Rotation"</em> button in the toolbar.
 \image html rotation_ico.png "Rotation button"
 
-<em>To rotate your mesh:</em>
-\par
-From the \b Modification choose \b Transformation and  from its sub-menu
-select the \b Rotation item. The following dialog box shall appear:
+The following dialog will appear:
 
 \image html rotation.png
-\par 
-In this dialog box you can specify the elements which should be
-rotated
+
+</li>
+
+<li>
+In this dialog:
+<ul>
+<li>specify the IDs of the elements which will be rotated:
+
 <ul>
-<li>Check on <b>Select the whole mesh, submesh or group</b> option
-<li>Choosing them manually with the mouse in the 3D Viewer. You can
-click on an element in the 3D viewer and it will be highlighted</li>
-<li>Applying Filters. The <b>Set filter</b> button allows to apply a
-definite filter to selection of the elements. See more
-about filters on the
-\ref selection_filter_library_page "Selection filter library" page.</li>
+<li><b>Select the whole mesh, submesh or group</b> activating this
+checkbox; or</li>
+<li>choose mesh elements with the mouse in the 3D Viewer. It is
+possible to select a whole area with a mouse frame; or</li> 
+<li>input the element IDs directly in <b>ID Elements</b> field. The selected elements will be highlighted in the
+viewer; or</li>
+<li>apply Filters. <b>Set filter</b> button allows to apply a filter to the selection of elements. See more
+about filters in the \ref selection_filter_library_page "Selection filter library" page.</li>
 </ul>
- and the rotation parameters:
+</li>
+
+<li>specify the axis of rotation:
 <ul>
-<li>\b Axis: point and vector</li>
-<li>\b Angle of rotation</li>
+<li>specify the cooordinates of the start \b Point of the vector of rotation;</li>
+<li>specify the \b Vector of rotation through the coordinates of its
+end point with respect to the coordinates of the start point;</li>
 </ul>
+</li>
+<li>specify the \b Angle of rotation </li>
 
-\n Toggle the corresponding checkbox to <b> Select whole mesh, submesh or group.</b>  
-\n When <b>Move elements</b> radio button is selected, the source mesh (or elements) is created at the new location and erased from its previous location
-\n When <b>Copy elements</b> radio button is selected,the source mesh (or elements) is created at the new location, but it also remains at its previous location and is considered one and single mesh with the result of the rotation.
-\n When <b>Create as new mesh</b> radio button is selected, the source mesh (or elements) remains at its previous location and a new mesh is created at the new location and appears in the Object Browser with the default name MeshName_rotated (you can change this name in the adjacent box).
-\n <b> Copy groups </b> checkbox allows copying the groups of elements of the source mesh to the newly created one.
-\par
+<li>specify the conditions of rotation:
+<ul>
+<li>activate <b>Move elements</b> radio button to create  the source
+mesh (or elements) at the new location and erase it from the previous location;</li>
+<li>activate <b>Copy elements</b> radio button to create the source
+mesh (or elements) at the new location, but leave it at the previous
+location, the source mesh will be considered one and single mesh with the result of the rotation;</li>
+<li>activate <b>Create as new mesh</b> radio button to leave the
+source mesh (or elements) at its previous location and create a new
+mesh at the new location, the new mesh appears in the Object Browser
+with the default name MeshName_rotated (it is possible to change this
+name in the adjacent box);</li>
+<li>activate <b> Copy groups </b> checkbox to copy the groups of elements of the source mesh to the newly created mesh.</li>
+</ul>
+</li>
+
+<li>activate <b>Preview</b> checkbox to show the result of transformation in the viewer </li>
+<li>click \b Apply or <b> Apply and Close</b> button to confirm the
+operation.</li>
+</ul>
+</ol>
 
 
 \image html rotation1.png "The initial mesh"
diff --git a/doc/salome/gui/SMESH/input/scalar_bar.doc b/doc/salome/gui/SMESH/input/scalar_bar.doc
new file mode 100755 (executable)
index 0000000..146a7fa
--- /dev/null
@@ -0,0 +1,40 @@
+/*!
+
+\page scalar_bar_dlg Scalar Bar properties
+
+In this dialog you can specify the properties of the scalar bar
+
+\image html scalar_bar_dlg.png
+
+<ul>
+<li><b>Scalar Range</b> in this menu you can specify 
+<b>Min value</b> and <b>Max value</b> of the <b>Scalar Bar</b> </li>
+
+<li><b>Font</b> - in this menu you can set type, face and color for
+the font of <b>Title</b> and <b>Labels</b> of the <b>Scalar
+Bar</b></li>
+
+<li><b>Colors & Labels</b> - in this menu you can set the <b>number of
+colors</b> and the <b>number of labels</b> of the <b>Scalar
+Bar</b></li>
+
+<li><b>Orientation</b> - allows choosing between vertical and
+horizontal orientation of the <b>Scalar Bar</b></li>.
+
+<li><b>Origin & Size Vertical & Horizontal</b> - allows defining the
+location (<b>X</b> and <b>Y</b>) and size (<b>Width</b> and
+<b>Height</b>) of <b>Scalar Bar</b></li>
+<ul>
+<li><b>X</b>: abscissa of the origin (from the left
+side)</li>
+<li><b>Y</b>: ordinate of the origin (from the bottom)</li>
+</ul>
+<li><b>Distribution</b> in this menu you can Show/Hide distribution histogram of the values of the <b>Scalar Bar</b> and specify histogram properties</li>
+<ul>
+<li><b>Multicolor</b> the histogram is colored as <b>Scalar Bar</b></li>
+<li><b>Monocolor</b> the histogram is colored as selected with <b>Distribution color</b> selector</li>
+</ul>
+</ul>
+
+
+*/
diff --git a/doc/salome/gui/SMESH/input/scale.doc b/doc/salome/gui/SMESH/input/scale.doc
new file mode 100644 (file)
index 0000000..57626fd
--- /dev/null
@@ -0,0 +1,134 @@
+/*!
+
+\page scale_page Scale
+
+\n This geometrical operation allows to scale in space your mesh
+or some of its elements.
+
+<em>To scale a mesh:</em>
+
+<ol>
+<li>From the \b Modification menu choose \b Transformation -> \b Scale
+\b Transform item.
+
+One of the following dialogs will appear:
+
+With one scale factor:
+\image html scale01.png
+
+Or with different scale factors for axes:
+\image html scale02.png
+
+</li>
+
+<li>
+In the dialog:
+<ul>
+<li>specify the IDs of the translated elements:
+
+<ul>
+<li><b>Select the whole mesh, submesh or group</b> activating this
+checkbox; or</li>
+<li>choose mesh elements with the mouse in the 3D Viewer. It is
+possible to select a whole area with a mouse frame; or</li> 
+<li>input the element IDs directly in <b>ID Elements</b> field. The selected elements will be highlighted in the
+viewer; or</li>
+<li>apply Filters. <b>Set filter</b> button allows to apply a filter to the selection of elements. See more
+about filters in the \ref selection_filter_library_page "Selection filter library" page.</li>
+</ul>
+</li>
+
+<li>specify the base point for scale</li>
+
+<li>specify the scale factor</li>
+
+<li>specify the conditions of scale:
+<ul>
+<li>activate <b>Move elements</b> radio button to scale the selected
+mesh (or elements) without creating a copy;</li>
+<li>activate <b>Copy elements</b> radio button to duplicate the selected
+mesh (or elements) and to apply scaling to the copy within the same mesh;</li>
+<li>activate <b>Create as new mesh</b> radio button to leave the
+selected mesh (or elements) at its previous location and create a new
+mesh of the scaled copy of the selected elements; the new mesh appears in the Object Browser
+with the default name MeshName_scaled (it is possible to change this
+name in the adjacent box);</li>
+<li>activate <b> Copy groups </b> checkbox to copy the groups of
+elements existing in the source mesh to the newly created mesh.</li>
+</ul>
+</li>
+
+</li>
+
+<li>activate <b>Preview</b> checkbox to show the result of transformation in the viewer </li>
+<li>click \b Apply or <b> Apply and Close</b> button to confirm the operation.</li>
+</ul>
+</ol>
+
+
+
+<b>Example of using:</b>
+
+1. Create quandrangle mesh 3x3 on a simple planar face (200x200)
+
+\image html scaleinit01.png
+
+and union 3 faces (along axis Z) to group "gr_faces"
+
+\image html scaleinit02.png
+
+
+
+2. Perform scale operation for the whole mesh and create a new mesh:
+
+\image html scale03.png
+
+result after operation:
+
+\image html scaleres03.png
+
+
+
+3. Perform scale operation for the whole mesh and copy elements:
+
+\image html scale04.png
+
+result after operation:
+
+\image html scaleres04.png
+
+
+
+4. Perform scale operation for a group of faces and copy elements:
+
+\image html scale06.png
+
+result after operation:
+
+\image html scaleres06.png
+
+
+
+5. Perform scale operation for two edges and move elements:
+
+\image html scale07.png
+
+result after operation:
+
+\image html scaleres07.png
+
+
+
+6. Perform scale operation for one face and move elements:
+
+\image html scale09.png
+
+result after operation:
+
+\image html scaleres09.png
+
+
+<br><b>See Also</b> a sample TUI Script of a \ref tui_scale "Scale" operation.  
+
+
+*/
index 66c72a0e848286f681124fc3d8775ff22da41d83..4e58dcee09fefe4ee60d516553e7508f5f582372 100644 (file)
@@ -9,8 +9,8 @@ via <b>Tools / Selection filter library</b>.
 \image html selectionfilterlibrary.png
 
 <b>Library file name</b> shows the path and the file name where your
-filters will be stored. By clicking the <em>Browse</em> button you can load an
-existing filter library.
+filters will be stored. By clicking the <em>Browse</em> button you can
+load an existing filter library.
 \n <b>Names of filters</b> lists the filters created or uploaded for
 the current study. You can \b Add or \b Delete filters.
 \n In <b>Filter name</b> box you can specify the name for your
@@ -31,18 +31,28 @@ specify logical relations between criteria using \b Binary operators
 Or and And.
 \n Some criteria should have the additional parameter of \b Tolerance.
 
-When we create a <b>Standalone Group</b> using filters (for this click
-<b>Set Filters</b> button in the <b>Create Group</b> menu), the menu
-for setting filters looks a bit differently. Toggling <b>Insert filter
-in viewer</b> checkbox enables to preview the group selected with your
-current filter in the viewer.
-\n In the \b Source field you choose if the filter will be applied to
-the whole \b Mesh, the <b>Initial Selection</b> or the <b>Current Group</b>. 
-\n <b>Copy from...</b> button gives you a possibility to load an
+When we create a group using filters (for this click
+<b>Set Filters</b> button in the <b>Create Group</b> dialog), the menu
+for setting filters looks a bit differently (see below). Switching
+on <b>Insert filter in viewer</b> checkbox limits selection of elements
+in the Viewer using your current filter.
+<br>
+In the \b Source field you choose if the filter will be applied to
+the whole \b Mesh, the <b>Initial Selection</b> or the <b>Current
+Group</b>. If \b Mesh is chosen, the elements satisfying the filter
+will be selected in the 3D Viewer. If <b> Initial Selection</b> is
+chosen, the filter will be applied to the selected elements and the
+elements rejected by the filter will be deseleced. If <b>Current
+Group</b> is chosen, the filter will be applied to the list of
+elements in the <em>Greate Croup</em> dialog and the elements rejected
+by the filter will be removed from the list.
+<br>
+<b>Copy from...</b> button gives you a possibility to load an
 existing filter from <b>Selection filter library</b> and <b>Add
 to...</b> button gives you a possibility to save your current filter
 in the Library.
-\n <b>Note:</b> If the button <b>Apply and Close</b> is disabled, there
+<br>
+<b>Note:</b> If the button <b>Apply and Close</b> is disabled, there
 is no selected mesh in the Object Browser and the filter can not be
 created. You have to select the mesh and the button will be enabled.
 
@@ -66,20 +76,19 @@ shape, the algorithm works slower.
 IDs. 
 <b>Threshold Value</b> can be, for example: "1,2,3,50-60,63,67,70-78"
 </li><li>
-<b>Color of Group</b> allows selection of entities belonging to Group with
-specified color defined by the <b>Threshold Value</b>.
+<b>Color of Group</b> allows selection of entities belonging to the Group with
+the color defined by the <b>Threshold Value</b>.
 </li>
 </ul>
 
-Some criteria are applicable to all <b>Entity types</b>: except for
+Some criteria are applicable to all <b>Entity types</b>, except for
 <b>Nodes</b>
 <ul><li>
-<b>Linear</b> allows selection of Linear or Quadratic (in case of
-Unary set to "Not" state)
+<b>Linear</b> allows selection of Linear or Quadratic elements (if Unary is set to "Not")
 </li><li>
 <b>Geometry type</b> allows selection of elements by their geometric type
 defined by the <b>Threshold Value</b>. The list of available geometric
-types depends on element entity type defined by the <b>Threshold Value</b>.
+types depends on the element entity type defined by the <b>Threshold Value</b>.
 </li>
 </ul>
 
@@ -97,12 +106,25 @@ specified arbitrary surface within a given <b>Tolerance</b>.
 </li>
 </ul>
 
-Additional criteria to select mesh <b>Edges</b> are the following:
+The following criteria allow selecting mesh <b>Nodes</b>:
+<ul><li>
+<b>Free nodes</b> selects nodes not belonging to any mesh element.
+</li><li>
+<b>Double nodes</b> selects a node coincident with other nodes 
+(within a given <b>Tolerance</b>). 
+See also \ref tui_double_nodes_control "Double Nodes quality control".
+</li>
+</ul>
+
+The following criteria allow selecting mesh <b>Edges</b>:
 <ul><li>
 <b>Free Borders</b> selects free 1D mesh elements, i.e. edges belonging to 
 one face only. See also a
 \ref free_borders_page "Free Borders quality control".
 </li><li>
+<b>Double edges</b> selects 1D mesh elements basing on the same set of nodes.
+See also \ref filter_double_elements "Double Elements quality control".
+</li><li>
 <b>Borders at Multi-Connections</b> selects edges belonging to several faces.
 The number of faces should be more, less or equal (within a given <b>Tolerance</b>)
 to the predefined <b>Threshold Value</b>. See also a
@@ -115,7 +137,7 @@ See also a
 </li>
 </ul>
 
-Additional criteria to select mesh <b>Faces</b> are the following:
+The following criteria allow selecting mesh <b>Faces</b>:
 <ul><li>
 <b>Aspect ratio</b> selects 2D mesh elements with an aspect ratio (see also an
 \ref aspect_ratio_page "Aspect Ratio quality control"), which is more, less or equal
@@ -145,8 +167,17 @@ Additional criteria to select mesh <b>Faces</b> are the following:
 one element of mesh only. See also a
 \ref free_edges_page "Free Edges quality control".
 </li><li>
-<b>Free faces</b> selects 3D mesh elements wich belong less than to
-two volumes.
+<b>Free faces</b> selects 2D mesh elements wich belong to less than two volumes.
+</li><li>
+<b>Double faces</b> selects 2D mesh elements basing on the same set of nodes.
+See also \ref filter_double_elements "Double Elements quality control".
+</li><li>
+<b>Faces with bare border</b> selects 2D mesh elements having a free border without an edge on it.
+See also \ref bare_border_faces_page "Bare border faces quality control".
+</li><li>
+<b>Over-constrained faces</b> selects 2D mesh elements having only one border shared 
+with other 2D elements.
+See also \ref over_constrained_faces_page "Over-constrained faces quality control".
 </li><li>
 <b>Borders at Multi-Connections 2D</b> selects cells consisting of edges belonging to
 several elements of mesh. The number of mesh elements should be more, less or equal
@@ -158,10 +189,21 @@ See also a
 length, which is more, less or equal (within a given <b>Tolerance</b>) to the predefined
 <b>Threshold Value</b>. See also a
 \ref length_2d_page "Length 2D quality control".
+</li><li>
+<b>Coplanar faces</b> selects mesh faces neighboring the one selected
+by ID in <b>Threshold Value</b> field, if the angle between the
+normal to the neighboring face and the normal to the selected face is less then the
+angular tolerance (defined in degrees). Selection continues among all neighbor faces of already 
+selected ones.<br>
+</li><li>
+<b>Element Diameter 2D</b> selects triangles and quadrangles composed of the edges and
+diagonals with a value of length, which is more, less or equal
+(within a given <b>Tolerance</b>) to the predefined <b>Threshold Value</b>. See also a
+\ref max_element_length_2d_page "Element Diameter 2D quality control".
 </li>
 </ul>
 
-Additional criteria to select mesh <b>Volumes</b> are the following:
+The following criteria allow selecting  mesh <b>Volumes</b>:
 <ul><li>
 <b>Aspect ratio 3D</b> selects 3D mesh elements with an aspect ratio (see also an
 \ref aspect_ratio_3d_page "Aspect Ratio 3D quality control"), which is more, less or equal
@@ -171,8 +213,23 @@ Additional criteria to select mesh <b>Volumes</b> are the following:
 \ref volume_page "Volume quality control"), which is more, less or equal (within a given
 <b>Tolerance</b>) to the predefined <b>Threshold Value</b>.
 </li><li>
+<b>Element Diameter 3D</b> selects 3D mesh elements composed of the edges and
+diagonals with a value of length, which is more, less or equal
+(within a given <b>Tolerance</b>) to the predefined <b>Threshold Value</b>. See also a
+\ref max_element_length_3d_page "Element Diameter 3D quality control".
+</li><li>
+<b>Double volumes</b> selects 3D mesh elements basing on the same set of nodes.
+See also \ref filter_double_elements "Double Elements quality control".
+</li><li>
 <b>Bad oriented volume</b> selects mesh volumes, which are incorrectly oriented from
 the point of view of MED convention.
+</li><li>
+<b>Over-constrained volumes</b> selects mesh volumes having only one border shared 
+with other volumes.
+See also \ref over_constrained_volumes_page "Over-constrained volumes quality control".
+</li><li>
+<b>Volumes with bare border</b> selects 3D mesh elements having a free border without a face on it.
+See also \ref bare_border_volumes_page "Bare border volumes quality control".
 </li>
 </ul>
 
index 5235b4dddeb00c88b2bb7a9562d3e317f84c244e..036c70d83aaf7e9a655c1f646e0c97286e16cd28 100644 (file)
@@ -14,7 +14,8 @@ criterion can be applied to elements composed of 4 and 3 nodes
 <ol>
 <li>Display your mesh in the viewer.</li>
 
-<li>Choose <b>Controls > Skew</b> or click <em>"Skew"</em> button of the toolbar.
+<li>Choose <b>Controls > Face Controls > Skew</b> or click
+<em>"Skew"</em> button of the toolbar.
 
 \image html image40.png
 <center><em>"Skew" button </em></center>
index 17255212cd841c7ae21b152f24ace185123836b6..e725ef99cf237c4d8d012ac6cd3f0752efb768f4 100644 (file)
 
 \page smeshpy_interface_page Python interface
 
-\n Python package smesh defines several classes, destined for easy and
+Python package smesh defines several classes, destined for easy and
 clear mesh creation and edition.
 
-\n Documentation for smesh package is available in two forms:
-
-\n The <a href="smeshpy_doc/modules.html"> structured
-   documentation for smesh package</a>, where all methods and
-   classes are grouped by their functionality, like it is done in the GUI documentation
-\n and the \ref smeshDC "linear documentation for smesh package"
-   grouped only by classes, declared in the smesh.py file.
-
-\n The main page of the \ref smeshDC "linear documentation for smesh package"
-   contains a list of data structures and a list of
-   functions, provided by the package smesh.py. The first item in
-   the list of data structures (\ref smeshDC::smeshDC "class smesh")
-   also represents documentation for the methods of the package smesh.py itself.
-
-\n The package smesh.py provides an interface to create and handle
-   meshes. Use it to create an empty mesh or to import it from the data file.
-
-\n Once a mesh has been created, it is possible to  manage it via its own
-   methods, described at \ref smeshDC::Mesh "class Mesh" documentation
-   (it is also accessible by the second item "class Mesh" in the list of data structures).
-
-\n Class Mesh allows assigning algorithms to a mesh.
-\n Please note, that some algorithms,
-   included in the standard Salome installation are always available:
-      - REGULAR(1D), COMPOSITE(1D), MEFISTO(2D), Quadrangle(2D), Hexa(3D), etc.
-
-\n There are also some algorithms, which can be installed optionally,
-\n some of them are based on open-source meshers:
-         - NETGEN(1D-2D,2D,1D-2D-3D,3D),
-
-\n others are based on commercial meshers:
-         - GHS3D(3D), BLSURF(2D).
-
-\n    To add hypotheses, use the interfaces, provided by the assigned
+Documentation for smesh package is available in two forms:
+
+The <a href="smeshpy_doc/modules.html"> structured
+documentation for smesh package</a>, where all methods and
+classes are grouped by their functionality, like it is done in the GUI documentation
+and the \ref smeshDC "linear documentation for smesh package"
+grouped only by classes, declared in the smesh.py file.
+
+The main page of the \ref smeshDC "linear documentation for smesh package"
+contains a list of data structures and a list of
+functions, provided by the package smesh.py. The first item in
+the list of data structures (\ref smeshDC::smeshDC "class smesh")
+also represents documentation for the methods of the package smesh.py itself.
+
+The package smesh.py provides an interface to create and handle
+meshes. Use it to create an empty mesh or to import it from the data file.
+
+Once a mesh has been created, it is possible to  manage it via its own
+methods, described at \ref smeshDC::Mesh "class Mesh" documentation
+(it is also accessible by the second item "class Mesh" in the list of data structures).
+
+Class \b Mesh allows assigning algorithms to a mesh.
+Please note, that some algorithms, included in the standard SALOME
+distribution are always available:
+- REGULAR (1D)
+- COMPOSITE (1D)
+- MEFISTO (2D)
+- Quadrangle (2D)
+- Hexa(3D)
+- etc...
+
+To add hypotheses, use the interfaces, provided by the assigned
 algorithms.
 
-\n Below you can see an example of usage of the package smesh for 3d mesh generation. 
+Below you can see an example of usage of the package smesh for 3d mesh generation. 
 
-<h2>Example of 3d mesh generation with NETGEN:</h2>
+\anchor example_3d_mesh
+<h2>Example of 3d mesh generation:</h2>
 
-\n from geompy import * 
-\n import smesh 
+\code
+from geompy import * 
+import smesh 
 
-<b># Geometry</b>
-\n <b># an assembly of a box, a cylinder and a truncated cone meshed with tetrahedral</b>. 
+###
+# Geometry: an assembly of a box, a cylinder and a truncated cone
+# meshed with tetrahedral 
+###
 
-<b># Define values</b>
-\n name = "ex21_lamp" 
-\n cote = 60 
-\n section = 20 
-\n size = 200 
-\n radius_1 = 80 
-\n radius_2 = 40 
-\n height = 100 
+# Define values
+name = "ex21_lamp" 
+cote = 60 
+section = 20 
+size = 200 
+radius_1 = 80 
+radius_2 = 40 
+height = 100 
 
-<b># Build a box</b>
-\n box = MakeBox(-cote, -cote, -cote, +cote, +cote, +cote) 
+# Build a box
+box = MakeBox(-cote, -cote, -cote, +cote, +cote, +cote) 
 
-<b># Build a cylinder</b>
-\n pt1 = MakeVertex(0, 0, cote/3) 
-\n di1 = MakeVectorDXDYDZ(0, 0, 1) 
-\n cyl = MakeCylinder(pt1, di1, section, size) 
+# Build a cylinder
+pt1 = MakeVertex(0, 0, cote/3) 
+di1 = MakeVectorDXDYDZ(0, 0, 1) 
+cyl = MakeCylinder(pt1, di1, section, size) 
 
-<b># Build a truncated cone</b>
-\n pt2 = MakeVertex(0, 0, size) 
-\n cone = MakeCone(pt2, di1, radius_1, radius_2, height) 
+# Build a truncated cone
+pt2 = MakeVertex(0, 0, size) 
+cone = MakeCone(pt2, di1, radius_1, radius_2, height) 
 
-<b># Fuse </b>
-\n box_cyl = MakeFuse(box, cyl) 
-\n piece = MakeFuse(box_cyl, cone) 
+# Fuse
+box_cyl = MakeFuse(box, cyl) 
+piece = MakeFuse(box_cyl, cone) 
 
-<b># Add in study</b>
-\n addToStudy(piece, name) 
+# Add to the study
+addToStudy(piece, name) 
 
-<b># Create a group of faces</b>
-\n group = CreateGroup(piece, ShapeType["FACE"]) 
-\n group_name = name + "_grp" 
-\n addToStudy(group, group_name) 
-\n group.SetName(group_name) 
+# Create a group of faces
+group = CreateGroup(piece, ShapeType["FACE"]) 
+group_name = name + "_grp" 
+addToStudy(group, group_name) 
+group.SetName(group_name) 
 
-<b># Add faces in the group</b>
-\n faces = SubShapeAllIDs(piece, ShapeType["FACE"]) 
-\n UnionIDs(group, faces) 
+# Add faces to the group
+faces = SubShapeAllIDs(piece, ShapeType["FACE"]) 
+UnionIDs(group, faces) 
 
-<b># Create a mesh</b>
+###
+# Create a mesh
+###
 
-<b># Define a mesh on a geometry</b>
-\n tetra = smesh.Mesh(piece, name) 
+# Define a mesh on a geometry
+tetra = smesh.Mesh(piece, name) 
 
-<b># Define 1D hypothesis</b>
-\n algo1d = tetra.Segment() 
-\n algo1d.LocalLength(10) 
+# Define 1D hypothesis
+algo1d = tetra.Segment() 
+algo1d.LocalLength(10) 
 
-<b># Define 2D hypothesis</b>
-\n algo2d = tetra.Triangle() 
-\n algo2d.LengthFromEdges() 
+# Define 2D hypothesis
+algo2d = tetra.Triangle() 
+algo2d.LengthFromEdges() 
 
-<b># Define 3D hypothesis</b>
-\n algo3d = tetra.Tetrahedron(smesh.NETGEN) 
-\n algo3d.MaxElementVolume(100) 
+# Define 3D hypothesis
+algo3d = tetra.Tetrahedron()
+algo3d.MaxElementVolume(100) 
 
-<b># Compute the mesh</b>
-\n tetra.Compute() 
+# Compute the mesh
+tetra.Compute() 
 
-<b># Create a groupe of faces</b>
-\n tetra.Group(group)
+# Create a groupe of faces
+tetra.Group(group)
 
-\n Examples of Python scripts for all Mesh operations are available by
-the following links:
+\endcode
 
-<ul>
-<li>\subpage tui_creating_meshes_page</li>
-<li>\subpage tui_viewing_meshes_page</li>
-<li>\subpage tui_defining_hypotheses_page</li>
-<li>\subpage tui_quality_controls_page</li>
-<li>\subpage tui_grouping_elements_page</li>
-<li>\subpage tui_modifying_meshes_page</li>
-<li>\subpage tui_transforming_meshes_page</li>
-</ul>
+Examples of Python scripts for all Mesh operations are available by
+the following links:
 
+- \subpage tui_creating_meshes_page
+- \subpage tui_cartesian_algo
+- \subpage tui_viewing_meshes_page
+- \subpage tui_defining_hypotheses_page
+- \subpage tui_quality_controls_page
+- \subpage tui_filters_page
+- \subpage tui_grouping_elements_page
+- \subpage tui_modifying_meshes_page
+- \subpage tui_transforming_meshes_page
+- \subpage tui_notebook_smesh_page
+- \subpage tui_measurements_page
+- \subpage tui_generate_flat_elements_page
+- \subpage tui_work_on_objects_from_gui
 
 */
index 77a59f880e8b57e9f5d148ff6dfc9fced588d06f..dc15270a8e460109cfb6310c3f97df9fc8ad15b5 100644 (file)
@@ -7,38 +7,40 @@
 
 <em>To apply smoothing to the elements of your mesh:</em>
 <ol>
-<li>Display a mesh or a submesh in the 3D viewer.</li>
+
 <li>In the \b Modification menu select the \b Smoothing item or click
 <em>"Smoothing"</em> button in the toolbar.
 
 \image html image84.png
 <center><em>"Smoothing" button</em></center>
 
-The dialog box contains the following fields which should be
-specified:
+The following dialog will appear:
 
 \image html smoothing.png
+</li>
+<li>In this dialog:
 
 <ul>
-<li><b>Id Elements</b> field allows to specify the elements which
-should be smoothed
+<li>specify the IDs of the elements which will be smoothed:
 <ul>
-<li>Check on <b>Select the whole mesh, submesh or group</b> option
-<li>Choosing them manually with the mouse in the 3D Viewer. You can
-click on an element in the 3D viewer and it will be highlighted</li>
-<li>Applying Filters. The <b>Set filter</b> button allows to apply a
-definite filter to selection of the elements. See more
-about filters on the
-\ref selection_filter_library_page "Selection filter library" page.</li>
+<li><b>Select the whole mesh, submesh or group</b> activating this
+checkbox; or</li>
+<li>choose mesh elements with the mouse in the 3D Viewer. It is
+possible to select a whole area with a mouse frame; or</li> 
+<li>input the element IDs directly in <b>ID Elements</b> field. The selected elements will be highlighted in the
+viewer; or</li>
+<li>apply Filters. <b>Set filter</b> button allows to apply a filter to the selection of elements. See more
+about filters in the \ref selection_filter_library_page "Selection filter library" page.</li>
 </ul>
 </li>
-<b>Fixed nodes ids:</b> some nodes keep their location during
-smoothing. If a mesh is built on a geometry shape, the nodes built on
-geometrical edges are always fixed. If smoothing is applied to a part
-of a mesh then the boundary nodes of an elements set are also
-fixed. Any other nodes may be additionally fixed. Fixed nodes can be
-selected manually or by filters too.</li>
-<li><b>Smoothing Method:</b>
+
+<li>define the <b>Fixed nodes ids</b> that should remain at their location during
+smoothing. If a mesh is built on a shape, the nodes built on its
+geometric edges are always fixed. If the smoothing is applied to a part
+of the mesh, the nodes of boundary elements are also
+fixed. It is possible to additionally fix any other nodes. The fixed nodes can be
+selected manually or by filters, just as the smoothed elements.</li>
+<li>choose the <b>Smoothing Method:</b>
 <ul>
 <li>\b Laplacian smoothing pulls a node toward the center of
 surrounding nodes directly connected to that node along an element
@@ -47,32 +49,29 @@ edge.
 element-area-weighted centroid of the surrounding elements. </li>
 
 Typically, the  Laplacian method will produce the mesh with the least element
-distortion. It is also the faster method.Centroidal smoothing usually
-produces  a mesh that has more uniform element sizes. Both methods
+distortion. It is also the fastest method. Centroidal smoothing usually
+produces  a mesh with more uniform element sizes. Both methods
 produce good results with "free" meshes.</li>
 </ul>
 
 \image html image83.gif
 
 </li>
-<li><b>Iteration limit:</b> both of the smoothing methods use an
-iterative procedure to converge toward a smoothed mesh. All nodes are
-smoothed according to one of the techniques shown above. Then the
-smoothing is reevaluated with the updated nodal locations. This
-process continues until the maximum number of iterations has been
-exceeded, or all elements has aspect ratio less or equal than the
+<li>specify the <b>Iteration limit</b>. Both smoothing methods
+iterate through a number of steps to produce the resulting smoothed
+mesh. At each new step the smoothing is reevaluated with the updated nodal locations. This
+process continues till the limit of iterations has been
+exceeded, or till the aspect ratio of all element is less than or equal to the
 specified one.</li>
-<li><b>Max. aspect ratio</b> allows to define the quality at which the
-smoothing algorithm should stop the iterations as the target of the
-operation has been reached.</li>
-<li>When <b>in parametric space</b> radio button is checked, the
-algorithm tries to improve the shape of faces in the parametric space
+<li>specify the  <b>Max. aspect ratio</b> - the target mesh quality at which the
+smoothing algorithm should stop the iterations.</li>
+<li>activate <b>in parametric space</b> checkbox if it is necessary to
+to improve the shape of faces in the parametric space
 of geometrical surfaces on which they are generated, else the shape of
 faces in the 3D space is improved. </li>   
 </ul>
-
 </li>
-<li>Click the \b Apply or \b OK button to confirm the operation.</li>
+<li>Click \b Apply or <b> Apply and Close</b> button to confirm the operation.</li>
 </ol>
 
 \image html smoothing1.png "The initial mesh"
diff --git a/doc/salome/gui/SMESH/input/split_to_tetra.doc b/doc/salome/gui/SMESH/input/split_to_tetra.doc
new file mode 100644 (file)
index 0000000..325c30c
--- /dev/null
@@ -0,0 +1,55 @@
+/*!
+
+\page split_to_tetra_page Splitting volumes into tetrahedra
+
+\n This operation allows to split volumic elements into tetrahedra. 
+2D mesh is modified accordingly.
+
+<em>To split volumes:</em>
+<ol>
+<li>Display a mesh or a submesh in the 3D viewer.</li>
+<li>In the \b Modification menu select the <b>Split into Tetrahedra</b> item or
+click <em>"Split into Tetrahedra"</em> button in the toolbar.
+
+\image html split_into_tetra_icon.png
+<center><em>"Split into Tetrahedra" button</em></center>
+
+The following dialog box will appear:
+
+\image html split_into_tetra.png
+
+\par
+<ul>
+<li>The main list contains the list of volumes. You can click on
+a volume in the 3D viewer and it will be highlighted (lock Shift
+keyboard button to select several volumes). Click \b Add button and
+the ID of this volume will be added to the list. To remove the
+selected element or elements from the list click \b Remove button. <b>Sort
+list</b> button allows to sort the list of IDs. \b Filter button allows to
+apply a definite filter to the selection of volumes.
+<br><b>Note:</b> If you split not all adjacent non-tetrahedral volumes, your mesh becomes 
+non-conform.</li>
+<li><b>Apply to all</b> radio button allows to split all
+volumes of the currently displayed mesh or submesh.</li>
+</ul>
+
+<ul>
+<li>\b Split hexahedron
+
+<ul>
+<li><b>Into 5 tetrahedra</b>, <b>Into 6 tetrahedra</b> and <b>Into 24 tetrahedra</b> allows to
+specify the number of tetrahedra a hexahedron will be split into. If the specified method does
+not allow to get a conform mesh, a generic solution is applied: an additional node 
+is created at the gravity center of a hexahedron, serving an apex of tetrahedra, all quadrangle sides of the hexahedron are split into two triangles each serving a base of a new tetrahedron.</li>
+</ul>
+
+</li>
+
+<li><b>Select from</b> a set of fields allows to choose a submesh or an
+existing group whose elements will be automatically added to the
+list.</li>
+</ul>
+
+<li>Click the \b Apply or <b>Apply and Close</b> button to confirm the operation.</li>
+</ol>
+*/
index 67068e98145524221c5d331a9c34c66998ac4326..924e4eeb0e2e8d79c9a3880b00f55aaf4404fad7 100644 (file)
@@ -5,48 +5,81 @@
 \n This geometrical operation allows to perform a symmetrical copy of
 your mesh or some of its elements.
 
+<em>To create a symmetrical copy of the mesh:</em>
+
+<ol>
+<li>From the \b Modification menu choose \b Transformation -> \b Symmetry item  or click
+<em>"Symmetry"</em> button in the toolbar.
+
 \image html symmetry.png "Symmetry button"
 
-<em>To apply symmetry to your mesh:</em>
-\par
-From the \b Modification choose \b Transformation and  from its
-sub-menu select the \b Symmetry item. The following dialog box shall
-appear:
+One of the following dialogs will appear:
 
-\image html symmetry1.png
+It is possible to mirror a mesh or some of its elements through:
+\image html symmetry1.png "a point (defined by a point and a vector)"
+\image html symmetry2.png "an axis"
+\image html symmetry3.png "a plane (defined by a point and a normal to the plane)"
 
-\image html symmetry2.png
+</li>
 
-\image html symmetry3.png
+<li>In the dialog:
+<ul>
+<li>specify the IDs of the elements for the symmetry operation:
+
+<ul>
+<li><b>Select the whole mesh, submesh or group</b> activating this
+checkbox; or</li>
+<li>choose mesh elements with the mouse in the 3D Viewer. It is
+possible to select a whole area with a mouse frame; or</li> 
+<li>input the element IDs directly in <b>ID Elements</b> field. The selected elements will be highlighted in the
+viewer; or</li>
+<li>apply Filters. <b>Set filter</b> button allows to apply a filter to the selection of elements. See more
+about filters in the \ref selection_filter_library_page "Selection filter library" page.</li>
+</ul>
+</li>
 
-\par
-This operation has three options, you can symmetrically copy your mesh
-or some of its elements specifying:
+<li>depending on the nature of the mirror object: 
+<ul>
+<li>if the mesh is mirrored through a point, specify the coordinates
+of the point</li>
+<li>if the mesh is mirrored through an axis: 
 <ul>
-<li>one point</li>
-<li>one axis (point and vector)</li>
-<li>one plane (point and normal)</li>
+<li>specify the cooordinates of the start \b Point of the axis vector;</li>
+<li>specify the axis \b Vector through the coordinates of its
+end point with respect to the coordinates of the start point;</li>
 </ul>
+</li>
 
+<li>if the mesh is mirrored through a plane:
 <ul>
-<li>Select elements for the symmetry operation
+<li>specify the cooordinates of the \b Point lying on the plane;</li>
+<li>specify the axis \b Vector through the coordinates of its
+end point with respect to the coordinates of the start point.</li>
+</ul>
+</li>
+
+<li>specify the conditions of symmetry operation:
 <ul>
-<li>Check on <b>Select the whole mesh, submesh or group</b> option
-<li>Choosing them manually with the mouse in the 3D Viewer. You can
-click on an element in the 3D viewer and it will be highlighted</li>
-<li>Applying Filters. The <b>Set filter</b> button allows to apply a
-definite filter to selection of the elements. See more
-about filters on the
-\ref selection_filter_library_page "Selection filter library" page.</li>
+<li>activate <b>Move elements</b> radio button to create  the source
+mesh (or elements) at the new location and erase it from the previous location;</li>
+<li>activate <b>Copy elements</b> radio button to create the source
+mesh (or elements) at the new location, but leave it at the previous
+location, the source mesh will be considered one and single mesh with the result of the rotation;</li>
+<li>activate <b>Create as new mesh</b> radio button to leave the
+source mesh (or elements) at its previous location and create a new
+mesh at the new location, the new mesh appears in the Object Browser
+with the default name MeshName_rotated (it is possible to change this
+name in the adjacent box);</li>
+<li>activate <b> Copy groups </b> checkbox to copy the groups of elements of the source mesh to the newly created mesh.</li>
 </ul>
 </li>
-<li>When <b>Move elements</b> radio button is selected, the source mesh (or elements) is created at the new location and erased from its previous location</li>
-<li>When <b>Copy elements</b> radio button is selected,the source mesh (or elements) is created at the new location, but it also remains at its previous location and is considered one and single mesh with the result of the translation.</li>
-<li>When <b>Create as new mesh</b> radio button is selected, the source mesh (or elements) remains at its previous location and a new mesh is created at the new location and appears in the Object Browser with the default name MeshName_mirrored (you can change this name in the adjacent box).</li>
-<li><b> Copy groups </b> checkbox allows copying the groups of elements of the source mesh to the newly created one.</li>
+</ul>
+<li>activate <b>Preview</b> checkbox to show the result of transformation in the viewer </li>
+<li>click \b Apply or <b> Apply and Close</b> button to confirm the
+operation.</li>
 </ul>
 
-\par
+</ol>
 
 <br><b>See Also</b> a sample TUI Script of a 
 \ref tui_symmetry "Symmetry" operation.  
index d2c4dd2b4358cd407db279825c5bcfcb15f63c8b..86472eabe82c537b2f40a3a9c72245ea1060e1c8 100644 (file)
@@ -13,8 +13,8 @@ for elements consisting of 4 nodes.
 <ol>
 <li>Display your mesh in the viewer.</li>
 
-<li>Choose <b>Controls > Taper</b> or click <em>"Taper"</em> button in
-the toolbar.
+<li>Choose <b>Controls > Face Controls > Taper</b> or click
+<em>"Taper"</em> button in the toolbar.
 
 \image html image36.png
 <center><em>"Taper" button</em></center>
index 45565acaa6f8a29491df96acd3149893782d76ee..56c1dfb05abd4cf6e9418f0595582db76c6957ff 100644 (file)
@@ -5,45 +5,70 @@
 \n This geometrical operation allows to translate in space your mesh
 or some of its elements.
 
+<em>To translate a mesh:</em>
+
+<ol>
+<li>From the \b Modification menu choose \b Transformation -> \b Translation item  or click
+<em>"Translation"</em> button in the toolbar.
+
 \image html translation.png "Translation button"
 
-<em>To translate your mesh:</em>
-\par
-From the \b Modification choose \b Transformation and from its
-sub-menu select the \b Translation item. The following dialog box
-shall appear:
+One of the following dialogs will appear:
+
+It is possible to define the vector of thanslation:
+\image html translation1.png "by two points"
 
-\image html translation1.png
+\image html translation2.png "by the vector from the origin of coordinates" 
 
-\image html translation2.png
+</li>
+
+<li>
+In the dialog:
+<ul>
+<li>specify the IDs of the translated elements:
 
-\par
-This operation has two options, you can translate in space your mesh
-or some of its elements specifying:
 <ul>
-<li>two points (starting and ending)</li>
-<li>one vector</li>
+<li><b>Select the whole mesh, submesh or group</b> activating this
+checkbox; or</li>
+<li>choose mesh elements with the mouse in the 3D Viewer. It is
+possible to select a whole area with a mouse frame; or</li> 
+<li>input the element IDs directly in <b>ID Elements</b> field. The selected elements will be highlighted in the
+viewer; or</li>
+<li>apply Filters. <b>Set filter</b> button allows to apply a filter to the selection of elements. See more
+about filters in the \ref selection_filter_library_page "Selection filter library" page.</li>
 </ul>
+</li>
 
+<li>specify the vector of translation:
 <ul>
-<li>Select elements for the translation operation
+<li>specify the cooordinates of the start and end \b Points of the
+vector of translation; or</li>
+<li>specify the end point of the \b Vector of rotation starting at the
+origin of coordinates.</li>
+</ul>
+</li>
+
+<li>specify the conditions of translation:
 <ul>
-<li>Check on <b>Select the whole mesh, submesh or group</b> option
-<li>Choosing them manually with the mouse in the 3D Viewer. You can
-click on an element in the 3D viewer and it will be highlighted</li>
-<li>Applying Filters. The <b>Set filter</b> button allows to apply a
-definite filter to selection of the elements. See more
-about filters on the
-\ref selection_filter_library_page "Selection filter library" page.</li>
+<li>activate <b>Move elements</b> radio button to create  the source
+mesh (or elements) at the new location and erase it from the previous location;</li>
+<li>activate <b>Copy elements</b> radio button to create the source
+mesh (or elements) at the new location, but leave it at the previous
+location, the source mesh will be considered one and single mesh with the result of the rotation;</li>
+<li>activate <b>Create as new mesh</b> radio button to leave the
+source mesh (or elements) at its previous location and create a new
+mesh at the new location, the new mesh appears in the Object Browser
+with the default name MeshName_rotated (it is possible to change this
+name in the adjacent box);</li>
+<li>activate <b> Copy groups </b> checkbox to copy the groups of elements of the source mesh to the newly created mesh.</li>
 </ul>
 </li>
-<li>When <b>Move elements</b> radio button is selected, the source mesh (or elements) is created at the new location and erased from its previous location</li>
-<li>When <b>Copy elements</b> radio button is selected,the source mesh (or elements) is created at the new location, but it also remains at its previous location and is considered one and single mesh with the result of the translation.</li>
-<li>When <b>Create as new mesh</b> radio button is selected, the source mesh (or elements) remains at its previous location and a new mesh is created at the new location and appears in the Object Browser with the default name MeshName_translated (you can change this name in the adjacent box).</li>
-<li><b> Copy groups </b> checkbox allows copying the groups of elements of the source mesh to the newly created one.</li>
+
+<li>activate <b>Preview</b> checkbox to show the result of transformation in the viewer </li>
+<li>click \b Apply or <b> Apply and Close</b> button to confirm the operation.</li>
 </ul>
+</ol>
 
-<br><b>See Also</b> a sample TUI Script of a 
-\ref tui_translation "Translation" operation.  
+<br><b>See Also</b> a sample TUI Script of a \ref tui_translation "Translation" operation.  
 
 */
diff --git a/doc/salome/gui/SMESH/input/tui_cartesian_algo.doc b/doc/salome/gui/SMESH/input/tui_cartesian_algo.doc
new file mode 100644 (file)
index 0000000..f121843
--- /dev/null
@@ -0,0 +1,49 @@
+/*!
+
+\page tui_cartesian_algo Usage of Body Fitting algorithm
+
+\code
+from smesh import *
+SetCurrentStudy(salome.myStudy)
+
+# create a sphere
+sphere = geompy.MakeSphereR( 50 )
+geompy.addToStudy( sphere, "sphere" )
+
+# create a mesh and assign a "Body Fitting" algo
+mesh = Mesh( sphere )
+cartAlgo = mesh.BodyFitted()
+
+# define a cartesian grid using Coordinates
+coords = range(-100,100,10)
+cartHyp = cartAlgo.SetGrid( coords,coords,coords, 1000000)
+
+# compute the mesh
+mesh.Compute()
+print "nb hexahedra",mesh.NbHexas()
+print "nb tetrahedra",mesh.NbTetras()
+print "nb polyhedra",mesh.NbPolyhedrons()
+print
+
+# define the grid by sitting constant spacing
+cartHyp = cartAlgo.SetGrid( "10","10","10", 1000000)
+
+mesh.Compute()
+print "nb hexahedra",mesh.NbHexas()
+print "nb tetrahedra",mesh.NbTetras()
+print "nb polyhedra",mesh.NbPolyhedrons()
+
+
+# define the grid by sitting different spacing in 2 sub-ranges of geometry
+spaceFuns = ["5","10+10*t"]
+cartAlgo.SetGrid( [spaceFuns, [0.5]], [spaceFuns, [0.5]], [spaceFuns, [0.25]], 2 )
+
+mesh.Compute()
+print "nb hexahedra",mesh.NbHexas()
+print "nb tetrahedra",mesh.NbTetras()
+print "nb polyhedra",mesh.NbPolyhedrons()
+print
+
+\endcode
+
+*/
index 9048afef17fe0fde4852801fdd7e8f45a29ae8bc..24161d483df084fb02a673ffa9d7d38b647bad91 100644 (file)
@@ -2,7 +2,7 @@
 
 \page tui_creating_meshes_page Creating Meshes
 
-\n First of all see \ref introduction_to_mesh_python_page "Example of 3d mesh generation",
+\n First of all see \ref example_3d_mesh "Example of 3d mesh generation",
  which is an example of good python script style for Mesh module.
 
 <br>
@@ -25,7 +25,7 @@ algo1D.NumberOfSegments(7)
 algo2D = tetra.Triangle()
 algo2D.MaxElementArea(800.)
 
-algo3D = tetra.Tetrahedron(smesh.NETGEN)
+algo3D = tetra.Tetrahedron()
 algo3D.MaxElementVolume(900.)
 
 # compute the mesh
@@ -82,6 +82,68 @@ quadra.Compute()
 
 \endcode
 
+<br>
+<h2>Change priority of submeshes in Mesh</h2>
+
+\code
+import salome
+import geompy
+import smesh
+import SMESH
+
+Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
+[Face_1,Face_2,Face_3,Face_4,Face_5,Face_6] = geompy.SubShapeAllSorted(Box_1, geompy.ShapeType["FACE"])
+
+# create Mesh object on Box shape
+Mesh_1 = smesh.Mesh(Box_1)
+
+# assign mesh algorithms
+Regular_1D = Mesh_1.Segment()
+Nb_Segments_1 = Regular_1D.NumberOfSegments(20)
+Nb_Segments_1.SetDistrType( 0 )
+MEFISTO_2D = Mesh_1.Triangle()
+Max_Element_Area_1 = MEFISTO_2D.MaxElementArea(1200)
+Tetrahedron = Mesh_1.Tetrahedron()
+Max_Element_Volume_1 = Tetrahedron.MaxElementVolume(40000)
+
+# create submesh and assign algorithms on Face_1
+Regular_1D_1 = Mesh_1.Segment(geom=Face_1)
+Nb_Segments_2 = Regular_1D_1.NumberOfSegments(4)
+Nb_Segments_2.SetDistrType( 0 )
+MEFISTO_2D_1 = Mesh_1.Triangle(algo=smesh.MEFISTO,geom=Face_1)
+Length_From_Edges_2D = MEFISTO_2D_1.LengthFromEdges()
+SubMesh_1 = MEFISTO_2D_1.GetSubMesh()
+
+# create submesh and assign algorithms on Face_2
+Regular_1D_2 = Mesh_1.Segment(geom=Face_2)
+Nb_Segments_3 = Regular_1D_2.NumberOfSegments(8)
+Nb_Segments_3.SetDistrType( 0 )
+MEFISTO_2D_2 = Mesh_1.Triangle(algo=smesh.MEFISTO,geom=Face_2)
+Length_From_Edges_2D_1 = MEFISTO_2D_2.LengthFromEdges()
+SubMesh_2 = MEFISTO_2D_2.GetSubMesh()
+
+# create submesh and assign algorithms on Face_3
+Regular_1D_3 = Mesh_1.Segment(geom=Face_3)
+Nb_Segments_4 = Regular_1D_3.NumberOfSegments(12)
+Nb_Segments_4.SetDistrType( 0 )
+MEFISTO_2D_3 = Mesh_1.Triangle(algo=smesh.MEFISTO,geom=Face_3)
+Length_From_Edges_2D_2 = MEFISTO_2D_3.LengthFromEdges()
+SubMesh_3 = MEFISTO_2D_3.GetSubMesh()
+
+# check exisiting submesh priority order
+[ [ SubMesh_1, SubMesh_3, SubMesh_2 ] ] = Mesh_1.GetMeshOrder()
+# set new submesh order
+isDone = Mesh_1.SetMeshOrder( [ [ SubMesh_1, SubMesh_2, SubMesh_3 ] ])
+# compute mesh
+isDone = Mesh_1.Compute()
+
+# clear mesh result and compute with other submesh order
+Mesh_1.Clear()
+isDone = Mesh_1.SetMeshOrder( [ [ SubMesh_2, SubMesh_1, SubMesh_3 ] ])
+isDone = Mesh_1.Compute()
+
+\endcode
+
 <br>
 \anchor tui_editing_mesh
 <h2>Editing of a mesh</h2>
@@ -162,7 +224,7 @@ algo1D.NumberOfSegments(7)
 algo2D = tetra.Triangle()
 algo2D.MaxElementArea(800.)
 
-algo3D = tetra.Tetrahedron(smesh.NETGEN)
+algo3D = tetra.Tetrahedron()
 algo3D.MaxElementVolume(900.)
 
 # compute the mesh
@@ -170,6 +232,11 @@ tetra.Compute()
 
 # export the mesh in a MED file
 tetra.ExportMED("/tmp/meshMED.med", 0)
+
+# export a group in a MED file
+face = geompy.SubShapeAll( box, geompy.ShapeType["FACE"])[0] # a box side
+group = tetra.GroupOnGeom( face, "face group" ) # group of 2D elements on the <face>
+tetra.ExportMED("/tmp/groupMED.med", meshPart=group)
 \endcode
 
 <br>
@@ -188,4 +255,48 @@ demonstrating the resulting mesh.
 \skipline import geompy
 \until #end
 
+<br>
+\anchor tui_copy_mesh
+<h2>Mesh Copying</h2>
+\code
+from smesh import *
+SetCurrentStudy(salome.myStudy)
+
+# make geometry of a box
+box = geompy.MakeBoxDXDYDZ(100,100,100)
+face = geompy.SubShapeAllSorted(box, geompy.ShapeType["FACE"])[0]
+
+# generate 3D mesh
+mesh = Mesh(box)
+localAlgo = mesh.Triangle(face)
+mesh.AutomaticHexahedralization()
+
+# objects to copy
+fGroup = mesh.GroupOnGeom( face, "2D on face")
+nGroup = mesh.GroupOnGeom( face, "nodes on face", NODE)
+subMesh = localAlgo.GetSubMesh()
+
+# make a new mesh by copying different parts of the mesh
+
+# 1. copy the whole mesh
+newMesh = CopyMesh( mesh, "whole mesh copy")
+
+# 2. copy a group of 2D elements along with groups
+newMesh = CopyMesh( fGroup,  "face group copy with groups",toCopyGroups=True)
+
+# 3. copy a group of nodes with preseving their ids
+newMesh = CopyMesh( nGroup, "node group copy", toKeepIDs=True)
+
+# 4. copy some faces
+faceIds = fGroup.GetIDs()[-10:]
+newMesh = CopyMesh( mesh.GetIDSource( faceIds, FACE ), "some faces copy")
+
+# 5. copy some nodes
+nodeIds = nGroup.GetIDs()[-10:]
+newMesh = CopyMesh( mesh.GetIDSource( nodeIds, NODE), "some nodes copy")
+
+# 6. copy a sub-mesh
+newMesh = CopyMesh( subMesh, "submesh copy" )
+\endcode
+
 */
index bd9fbbb10f3543ffc1845703e488d6ae8bf277d9..e98eca6b4ec10dc5f73f9c9a1b48328b6a19db08 100644 (file)
@@ -22,8 +22,12 @@ hexa = smesh.Mesh(box, "Box : hexahedrical mesh")
 # create a Regular 1D algorithm for edges
 algo1D = hexa.Segment()
 
+# optionally reverse node distribution on certain edges
+allEdges = geompy.SubShapeAllSortedIDs( box, geompy.ShapeType["EDGE"])
+reversedEdges = [ allEdges[0], allEdges[4] ]
+
 # define "Arithmetic1D" hypothesis to cut all edges in several segments with increasing arithmetic length 
-algo1D.Arithmetic1D(1, 4)
+algo1D.Arithmetic1D(1, 4, reversedEdges)
 
 # create a quadrangle 2D algorithm for faces
 hexa.Quadrangle()
@@ -124,7 +128,7 @@ hexa.Compute()
 
 <br>
 \anchor tui_average_length
-<h3>Average Length</h3>
+<h3>Local Length</h3>
 
 \code
 from geompy import *
@@ -227,7 +231,7 @@ tetra = smesh.Mesh(cyl, "Cylinder : tetrahedrical mesh")
 # assign algorithms
 algo1D = tetra.Segment()
 algo2D = tetra.Triangle()
-algo3D = tetra.Tetrahedron(smesh.NETGEN)
+algo3D = tetra.Tetrahedron()
 
 # assign 1D and 2D hypotheses
 algo1D.NumberOfSegments(7)
@@ -359,8 +363,8 @@ algo1D = tetra.Segment()
 # create a Mefisto 2D algorithm for faces
 algo2D = tetra.Triangle()
 
-# create a Netgen 3D algorithm for solids
-algo3D = tetra.Tetrahedron(smesh.NETGEN)
+# create a 3D algorithm for solids
+algo3D = tetra.Tetrahedron()
 
 # define hypotheses
 algo1D.Arithmetic1D(1, 4)
@@ -369,17 +373,338 @@ algo2D.LengthFromEdges()
 # compute the mesh
 tetra.Compute()
 
-# 3. Create a tetrahedral mesh on the box with NETGEN_2D3D algorithm
-tetraN = smesh.Mesh(box, "Box : tetrahedrical mesh by NETGEN_2D3D")
+\endcode
 
-# create a Netgen_2D3D algorithm for solids
-algo3D = tetraN.Tetrahedron(smesh.FULL_NETGEN) 
+<br>
+\anchor tui_projection
+<h3>Projection Algorithms</h3>
 
-# define hypotheses
-n23_params = algo3D.Parameters()
+\code
+# Project prisms from one meshed box to another mesh on the same box
+
+from smesh import *
+
+# Prepare geometry
+
+# Create a parallelepiped
+box = geompy.MakeBoxDXDYDZ(200, 100, 70)
+geompy.addToStudy( box, "box" )
+
+# Get geom faces to mesh with triangles in the 1ts and 2nd meshes
+faces = geompy.SubShapeAll(box, geompy.ShapeType["FACE"])
+# 2 adjacent faces of the box
+f1 = faces[2]
+f2 = faces[0]
+# face opposite to f2
+f2opp = faces[1]
+
+# Get vertices used to specify how to associate sides of faces at projection
+[v1F1, v2F1] = geompy.SubShapeAll(f1, geompy.ShapeType["VERTEX"])[:2]
+[v1F2, v2F2] = geompy.SubShapeAll(f2, geompy.ShapeType["VERTEX"])[:2]
+geompy.addToStudyInFather( box, v1F1, "v1F1" )
+geompy.addToStudyInFather( box, v2F1, "v2F1" )
+geompy.addToStudyInFather( box, v1F2, "v1F2" )
+geompy.addToStudyInFather( box, v2F2, "v2F2" )
+
+# Make group of 3 edges of f1 and f2
+edgesF1 = geompy.CreateGroup(f1, geompy.ShapeType["EDGE"])
+geompy.UnionList( edgesF1, geompy.SubShapeAll(f1, geompy.ShapeType["EDGE"])[:3])
+edgesF2 = geompy.CreateGroup(f2, geompy.ShapeType["EDGE"])
+geompy.UnionList( edgesF2, geompy.SubShapeAll(f2, geompy.ShapeType["EDGE"])[:3])
+geompy.addToStudyInFather( box, edgesF1, "edgesF1" )
+geompy.addToStudyInFather( box, edgesF2, "edgesF2" )
+
+
+# Make the source mesh with prisms
+src_mesh = Mesh(box, "Source mesh")
+src_mesh.Segment().NumberOfSegments(9,10)
+src_mesh.Quadrangle()
+src_mesh.Hexahedron()
+src_mesh.Triangle(f1) # triangular sumbesh 
+src_mesh.Compute()
+
+
+# Mesh the box using projection algoritms
+
+# Define the same global 1D and 2D hypotheses
+tgt_mesh = Mesh(box, "Target mesh")
+tgt_mesh.Segment().NumberOfSegments(9,10,UseExisting=True)
+tgt_mesh.Quadrangle()
+
+# Define Projection 1D algorithm to project 1d mesh elements from group edgesF2 to edgesF1
+# It is actually not needed, just a demonstration
+proj1D = tgt_mesh.Projection1D( edgesF1 )
+# each vertex must be at the end of a connected group of edges (or a sole edge)
+proj1D.SourceEdge( edgesF2, src_mesh, v2F1, v2F2 )
+
+# Define 2D hypotheses to project triangles from f1 face of the source mesh to
+# f2 face in the target mesh. Vertices specify how to associate sides of faces
+proj2D = tgt_mesh.Projection2D( f2 )
+proj2D.SourceFace( f1, src_mesh, v1F1, v1F2, v2F1, v2F2 )
+
+# 2D hypotheses to project triangles from f2 of target mesh to the face opposite to f2.
+# Association of face sides is default
+proj2D = tgt_mesh.Projection2D( f2opp )
+proj2D.SourceFace( f2 )
+
+# 3D hypotheses to project prisms from the source to the target mesh
+proj3D = tgt_mesh.Projection3D()
+proj3D.SourceShape3D( box, src_mesh, v1F1, v1F2, v2F1, v2F2 )
+tgt_mesh.Compute()
+
+# Move the source mesh to visualy compare the two meshes
+src_mesh.TranslateObject( src_mesh, MakeDirStruct( 210, 0, 0 ), Copy=False)
+
+\endcode
+
+<br>
+
+\anchor tui_fixed_points
+
+<h2>1D Mesh with Fixed Points example</h2>
+
+\code
+import salome
+import geompy
+import smesh
+import StdMeshers
+
+# Create face and explode it on edges
+face = geompy.MakeFaceHW(100, 100, 1)
+edges = geompy.SubShapeAllSorted(face, geompy.ShapeType["EDGE"])
+geompy.addToStudy( face, "Face" )
+
+# get the first edge from exploded result
+edge1 = geompy.GetSubShapeID(face, edges[0])
+
+# Define Mesh on previously created face
+Mesh_1 = smesh.Mesh(face)
+
+# Create Fixed Point 1D hypothesis and define parameters.
+# Note: values greater than 1.0 and less than 0.0 are not taken into account;
+# duplicated values are removed. Also, if not specified explicitly, values 0.0 and 1.0
+# add added automatically.
+# The number of segments should correspond to the number of points (NbSeg = NbPnt-1);
+# extra values of segments splitting parameter are not taken into account,
+# while missing values are considered to be equal to 1.
+Fixed_points_1D_1 = smesh.CreateHypothesis('FixedPoints1D')
+Fixed_points_1D_1.SetPoints( [ 1.1, 0.9, 0.5, 0.0, 0.5, -0.3 ] )
+Fixed_points_1D_1.SetNbSegments( [ 3, 1, 2 ] )
+Fixed_points_1D_1.SetReversedEdges( [edge1] )
+
+# Add hypothesis to mesh and define 2D parameters
+Mesh_1.AddHypothesis(Fixed_points_1D_1)
+Regular_1D = Mesh_1.Segment()
+Quadrangle_2D = Mesh_1.Quadrangle()
+# Compute mesh
+Mesh_1.Compute()
+\endcode
+
+\anchor tui_radial_quadrangle
+<h2> Radial Quadrangle 1D2D example </h2>
+\code
+from smesh import *
+
+SetCurrentStudy(salome.myStudy)
+
+# Create face from the wire and add to study
+Face = geompy.MakeSketcher("Sketcher:F 0 0:TT 20 0:R 90:C 20 90:WF", [0, 0, 0, 1, 0, 0, 0, 0, 1])
+geompy.addToStudy(Face,"Face")
+edges = geompy.SubShapeAllSorted(Face, geompy.ShapeType["EDGE"])
+circle, radius1, radius2 = edges
+geompy.addToStudyInFather(Face, radius1,"radius1")
+geompy.addToStudyInFather(Face, radius2,"radius2")
+geompy.addToStudyInFather(Face, circle,"circle")
+
+
+# Define geometry for mesh, and Radial Quadrange algorithm
+mesh = smesh.Mesh(Face)
+radial_Quad_algo = mesh.Quadrangle(algo=RADIAL_QUAD)
+
+# The Radial Quadrange algorithm can work without any hypothesis
+# In this case it uses "Default Nb of Segments" preferences parameter to discretize edges
+mesh.Compute()
+
+# The Radial Quadrange uses global or local 1d hypotheses if it does
+# not have its own hypotheses.
+# Define global hypotheses to discretize radial edges and a local one for circular edge
+global_Nb_Segments = mesh.Segment().NumberOfSegments(5)
+local_Nb_Segments  = mesh.Segment(circle).NumberOfSegments(10)
+mesh.Compute()
+
+# Define own parameters of Radial Quadrange algorithm
+radial_Quad_algo.NumberOfLayers( 4 )
+mesh.Compute()
+\endcode
+
+\anchor tui_quadrangle_parameters
+<h2>Quadrangle Parameters example 1 (meshing a face with 3 edges) </h2>
+\code
+from smesh import *
+SetCurrentStudy(salome.myStudy)
+
+# Get 1/4 part from the disk face.
+Box_1 = geompy.MakeBoxDXDYDZ(100, 100, 100)
+Disk_1 = geompy.MakeDiskR(100, 1)
+Common_1 = geompy.MakeCommon(Disk_1, Box_1)
+geompy.addToStudy( Disk_1, "Disk_1" )
+geompy.addToStudy( Box_1, "Box_1" )
+geompy.addToStudy( Common_1, "Common_1" )
+
+# Set the Geometry for meshing
+Mesh_1 = smesh.Mesh(Common_1)
+
+
+# Define 1D hypothesis and compute the mesh
+Regular_1D = Mesh_1.Segment()
+Nb_Segments_1 = Regular_1D.NumberOfSegments(10)
+Nb_Segments_1.SetDistrType( 0 )
+
+# Create Quadrangle parameters and define the Base Vertex.
+Quadrangle_2D = Mesh_1.Quadrangle().TriangleVertex( 8 )
+
+Mesh_1.Compute()
+\endcode
+
+<h2>Quadrangle Parameters example 2 (using different types) </h2>
+\code
+import geompy
+import smesh
+import StdMeshers
+
+# Make quadrangle face and explode it on edges.
+Vertex_1 = geompy.MakeVertex(0, 0, 0)
+Vertex_2 = geompy.MakeVertex(40, 0, 0)
+Vertex_3 = geompy.MakeVertex(40, 30, 0)
+Vertex_4 = geompy.MakeVertex(0, 30, 0)
+Quadrangle_Face_1 = geompy.MakeQuad4Vertices(Vertex_1, Vertex_4, Vertex_3, Vertex_2)
+[Edge_1,Edge_2,Edge_3,Edge_4] = geompy.SubShapeAllSorted(Quadrangle_Face_1, geompy.ShapeType["EDGE"])
+geompy.addToStudy( Vertex_1, "Vertex_1" )
+geompy.addToStudy( Vertex_2, "Vertex_2" )
+geompy.addToStudy( Vertex_3, "Vertex_3" )
+geompy.addToStudy( Vertex_4, "Vertex_4" )
+geompy.addToStudy( Quadrangle_Face_1, "Quadrangle Face_1" )
+geompy.addToStudyInFather( Quadrangle_Face_1, Edge_2, "Edge_2" )
+
+# Set the Geometry for meshing
+Mesh_1 = smesh.Mesh(Quadrangle_Face_1)
+
+# Create Quadrangle parameters and
+# define the Type as Quadrangle Preference
+Quadrangle_Parameters_1 = smesh.CreateHypothesis('QuadrangleParams')
+Quadrangle_Parameters_1.SetQuadType( StdMeshers.QUAD_QUADRANGLE_PREF )
+
+# Define other hypotheses and algorithms
+Regular_1D = Mesh_1.Segment()
+Nb_Segments_1 = Regular_1D.NumberOfSegments(4)
+Nb_Segments_1.SetDistrType( 0 )
+status = Mesh_1.AddHypothesis(Quadrangle_Parameters_1)
+Quadrangle_2D = Mesh_1.Quadrangle()
+
+# Define submesh on one edge to provide different number of segments
+Regular_1D_1 = Mesh_1.Segment(geom=Edge_2)
+Nb_Segments_2 = Regular_1D_1.NumberOfSegments(10)
+Nb_Segments_2.SetDistrType( 0 )
+SubMesh_1 = Regular_1D_1.GetSubMesh()
+
+# Compute mesh (with Quadrangle Preference type)
+isDone = Mesh_1.Compute()
+
+# Change type to Reduced and compute again
+Quadrangle_Parameters_1.SetQuadType( StdMeshers.QUAD_REDUCED )
+isDone = Mesh_1.Compute()
+\endcode
+
+\anchor tui_import
+<h2>"Use Existing Elements" example </h2>
+\code
+
+from smesh import *
+SetCurrentStudy(salome.myStudy)
+
+# Make a patritioned box
+
+box = geompy.MakeBoxDXDYDZ(100,100,100)
+
+N = geompy.MakeVectorDXDYDZ( 1,0,0 )
+O = geompy.MakeVertex( 50,0,0 )
+plane = geompy.MakePlane( O, N, 200 ) # plane YOZ
+
+shape2boxes = geompy.MakeHalfPartition( box, plane )
+boxes = geompy.SubShapeAllSorted(shape2boxes, geompy.ShapeType["SOLID"])
+
+geompy.addToStudy( boxes[0], "boxes[0]")
+geompy.addToStudy( boxes[1], "boxes[1]")
+midFace0 = geompy.SubShapeAllSorted(boxes[0], geompy.ShapeType["FACE"])[5]
+geompy.addToStudyInFather( boxes[0], midFace0, "middle Face")
+midFace1 = geompy.SubShapeAllSorted(boxes[1], geompy.ShapeType["FACE"])[0]
+geompy.addToStudyInFather( boxes[1], midFace1, "middle Face")
+
+# Mesh one of boxes with quadrangles. It is a source mesh
+
+srcMesh = Mesh(boxes[0], "source mesh") # box coloser to CS origin
+nSeg1 = srcMesh.Segment().NumberOfSegments(4)
+srcMesh.Quadrangle()
+srcMesh.Compute()
+srcFaceGroup = srcMesh.GroupOnGeom( midFace0, "src faces", FACE )
+
+# Import faces from midFace0 to the target mesh
+
+tgtMesh = Mesh(boxes[1], "target mesh")
+importAlgo = tgtMesh.UseExisting2DElements(midFace1)
+import2hyp = importAlgo.SourceFaces( [srcFaceGroup] )
+tgtMesh.Segment().NumberOfSegments(3)
+tgtMesh.Quadrangle()
+tgtMesh.Compute()
+
+# Import the whole source mesh with groups
+import2hyp.SetCopySourceMesh(True,True)
+tgtMesh.Compute()
+\endcode
+
+\anchor tui_viscous_layers
+<h2>Viscous layers construction</h2>
+
+\code
+from smesh import *
+SetCurrentStudy(salome.myStudy)
+
+X = geompy.MakeVectorDXDYDZ( 1,0,0 )
+O = geompy.MakeVertex( 100,50,50 )
+plane = geompy.MakePlane( O, X, 200 ) # plane YZ
+
+box = geompy.MakeBoxDXDYDZ(200,100,100)
+
+shape = geompy.MakeHalfPartition( box, plane )
+
+faces = geompy.SubShapeAllSorted(shape, geompy.ShapeType["FACE"])
+face1 = faces[1]
+ignoreFaces = [ faces[0], faces[-1]]
+
+geompy.addToStudy( shape, "shape" )
+geompy.addToStudyInFather( shape, face1, "face1")
+
+
+mesh = Mesh(shape, "CFD")
+
+mesh.Segment().NumberOfSegments( 4 )
+
+mesh.Triangle()
+mesh.Quadrangle(face1)
+mesh.Compute()
+algo3D = mesh.Tetrahedron()
+
+thickness = 20
+numberOfLayers = 10
+stretchFactor = 1.5
+layersHyp = algo3D.ViscousLayers(thickness,numberOfLayers,stretchFactor,ignoreFaces)
+
+mesh.Compute()
+
+mesh.MakeGroup("Tetras",VOLUME,FT_ElemGeomType,"=",Geom_TETRA)
+mesh.MakeGroup("Pyras",VOLUME,FT_ElemGeomType,"=",Geom_PYRAMID)
+mesh.MakeGroup("Prims",VOLUME,FT_ElemGeomType,"=",Geom_PENTA)
 
-# compute the mesh
-tetraN.Compute()
 \endcode
 
-*/
\ No newline at end of file
+*/
diff --git a/doc/salome/gui/SMESH/input/tui_filters.doc b/doc/salome/gui/SMESH/input/tui_filters.doc
new file mode 100755 (executable)
index 0000000..0eb41dd
--- /dev/null
@@ -0,0 +1,770 @@
+/*!
+
+\page tui_filters_page Filters usage
+
+Filters allow picking only the mesh elements satisfying to a
+specific condition or a set of conditions. Filters can be used to create
+or edit mesh groups, remove elements from the mesh object, control
+mesh quality by different parameters, etc.
+
+Several filters can be combined together by using logical operators \a
+AND and \a OR. In addition, applied filter criterion can be reverted
+using logical operator \a NOT.
+
+Mesh filters use the functionality of mesh quality controls to filter
+mesh nodes / elements by a specific characteristic (Area, Length, etc).
+
+This page provides a short description of the existing mesh filters,
+describes required parameters and gives simple examples of usage in
+Python scripts.
+
+\sa \ref tui_quality_controls_page
+
+\section filter_aspect_ratio Aspect ratio
+
+Filter 2D mesh elements (faces) according to the aspect ratio value:
+- element type should be \a smesh.FACE
+- functor type should be \a smesh.FT_AspectRatio
+- threshold is floating point value (aspect ratio)
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# get faces with aspect ratio > 6.5
+filter = smesh.GetFilter(smesh.FACE, smesh.FT_AspectRatio, smesh.FT_MoreThan, 6.5)
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of faces with aspect ratio > 6.5:", len(ids)
+\endcode
+
+\sa \ref tui_aspect_ratio
+
+\section filter_aspect_ratio_3d Aspect ratio 3D
+
+Filter 3D mesh elements (volumes) according to the aspect ratio value:
+- element type is \a smesh.VOLUME
+- functor type is \a smesh.FT_AspectRatio3D
+- threshold is floating point value (aspect ratio)
+
+\code
+# create mesh with volumes
+from SMESH_mechanic import *
+mesh.Tetrahedron()
+mesh.Compute()
+# get volumes with aspect ratio < 2.0
+filter = smesh.GetFilter(smesh.VOLUME, smesh.FT_AspectRatio3D, smesh.FT_LessThan, 2.0)
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of volumes with aspect ratio < 2.0:", len(ids)
+\endcode
+
+\sa \ref tui_aspect_ratio_3d
+
+\section filter_warping_angle Warping angle
+
+Filter 2D mesh elements (faces) according to the warping angle value:
+- element type is \a smesh.FACE
+- functor type is \a smesh.FT_Warping
+- threshold is floating point value (warping angle)
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# get faces with warping angle = 2.0e-13 with tolerance 5.0e-14
+criterion = smesh.GetCriterion(smesh.FACE, smesh.FT_Warping, smesh.FT_EqualTo, 2.0e-13)
+criterion.Tolerance = 5.0e-14
+filter = smesh.CreateFilterManager().CreateFilter()
+filter.SetCriteria([criterion])
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of faces with warping angle = 2.0e-13 (tolerance 5.0e-14):", len(ids)
+\endcode
+
+\sa \ref tui_warping
+
+\section filter_minimum_angle Minimum angle
+
+Filter 2D mesh elements (faces) according to the minimum angle value:
+- element type is \a smesh.FACE
+- functor type is \a smesh.FT_MinimumAngle
+- threshold is floating point value (minimum angle)
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# get faces with minimum angle > 75
+filter = smesh.GetFilter(smesh.FACE, smesh.FT_MinimumAngle,">", 75)
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of faces with minimum angle > 75:", len(ids)
+\endcode
+
+\sa \ref tui_minimum_angle
+
+\section filter_taper Taper
+
+Filter 2D mesh elements (faces) according to the taper value:
+- element type is \a smesh.FACE
+- functor type is \a smesh.FT_Taper
+- threshold is floating point value (taper)
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# get faces with taper < 1.e-15
+filter = smesh.GetFilter(smesh.FACE, smesh.FT_Taper, smesh.FT_LessThan, 1.e-15)
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of faces with taper < 1.e-15:", len(ids)
+\endcode
+
+\sa \ref tui_taper
+
+\section filter_skew Skew
+
+Filter 2D mesh elements (faces) according to the skew value:
+- element type is \a smesh.FACE
+- functor type is \a smesh.FT_Skew
+- threshold is floating point value (skew)
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# get faces with skew > 50
+filter = smesh.GetFilter(smesh.FACE, smesh.FT_Skew, smesh.FT_MoreThan, 50)
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of faces with skew > 50:", len(ids)
+\endcode
+
+\sa \ref tui_skew
+
+\section filter_area Area
+
+Filter 2D mesh elements (faces) according to the area value:
+- element type is \a smesh.FACE
+- functor type is \a smesh.FT_Area
+- threshold is floating point value (area)
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# get faces with area > 60 and < 90
+criterion1 = smesh.GetCriterion(smesh.FACE, smesh.FT_Area, smesh.FT_MoreThan, 60,\
+                                smesh.FT_Undefined, smesh.FT_LogicalAND)
+criterion2 = smesh.GetCriterion(smesh.FACE, smesh.FT_Area, smesh.FT_LessThan, 90)
+filter = smesh.CreateFilterManager().CreateFilter()
+filter.SetCriteria([criterion1,criterion2])
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of faces with area in range (60,90):", len(ids)
+\endcode
+
+\sa \ref tui_area
+
+\section filter_volume Volume
+
+Filter 3D mesh elements (volumes) according to the volume value:
+- element type is \a smesh.VOLUME
+- functor type is \a smesh.FT_Volume3D
+- threshold is floating point value (volume)
+
+\code
+# create mesh with volumes
+from SMESH_mechanic import *
+mesh.Tetrahedron()
+mesh.Compute()
+# get volumes faces with volume > 100
+filter = smesh.GetFilter(smesh.VOLUME, smesh.FT_Volume3D, smesh.FT_MoreThan, 100)
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of volumes with volume > 100:", len(ids)
+\endcode
+
+\sa \ref tui_volume
+
+\section filter_free_borders Free borders
+
+Filter 1D mesh elements (edges) which represent free borders of a mesh:
+- element type is \a smesh.EDGE
+- functor type is \a smesh.FT_FreeBorders
+- threshold value is not required
+
+\code
+# create mesh
+import geompy, smesh, StdMeshers
+face = geompy.MakeFaceHW(100, 100, 1)
+geompy.addToStudy( face, "quadrangle" )
+mesh = smesh.Mesh(face)
+mesh.Segment().NumberOfSegments(10)
+mesh.Triangle().MaxElementArea(25)
+mesh.Compute()
+# get all free borders
+filter = smesh.GetFilter(smesh.EDGE, smesh.FT_FreeBorders)
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of edges on free borders:", len(ids)
+\endcode
+
+\sa \ref tui_free_borders
+
+\section filter_free_edges Free edges
+
+Filter 2D mesh elements (faces) consisting of edges belonging to one
+element of mesh only:
+- element type is \a smesh.FACE
+- functor type is \a smesh.FT_FreeEdges
+- threshold value is not required
+
+\code
+# create mesh
+import geompy, smesh, StdMeshers
+face = geompy.MakeFaceHW(100, 100, 1)
+geompy.addToStudy( face, "quadrangle" )
+mesh = smesh.Mesh(face)
+mesh.Segment().NumberOfSegments(10)
+mesh.Triangle().MaxElementArea(25)
+mesh.Compute()
+# get all faces with free edges
+filter = smesh.GetFilter(smesh.FACE, smesh.FT_FreeEdges)
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of faces with free edges:", len(ids)
+\endcode
+
+\sa \ref tui_free_edges
+
+\section filter_free_nodes Free nodes
+
+Filter free nodes:
+- element type is \a smesh.NODE
+- functor type is \a smesh.FT_FreeNodes
+- threshold value is not required
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# add node
+mesh.AddNode(0,0,0)
+# get all free nodes
+filter = smesh.GetFilter(smesh.NODE, smesh.FT_FreeNodes)
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of free nodes:", len(ids)
+\endcode
+
+\sa \ref tui_free_nodes
+
+\section filter_free_faces Free faces
+
+Filter free faces:
+- element type is \a smesh.FACE
+- functor type is \a smesh.FT_FreeFaces
+- threshold value is not required
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# get all free faces
+filter = smesh.GetFilter(smesh.FACE, smesh.FT_FreeFaces)
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of free faces:", len(ids)
+\endcode
+
+\sa \ref tui_free_faces
+
+\section filter_bare_border_faces Bare border faces
+
+Filter faces with bare borders:
+- element type is \a smesh.FACE
+- functor type is \a smesh.FT_BareBorderFace
+- threshold value is not required
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# remove some faces to have faces with bare borders
+mesh.RemoveElements( mesh.GetElementsByType(FACE)[0:5] )
+# get all faces bare borders
+filter = smesh.GetFilter(smesh.FACE, smesh.FT_BareBorderFace)
+ids = mesh.GetIdsFromFilter(filter)
+print "Faces with bare borders:", ids
+\endcode
+
+\sa \ref tui_bare_border_faces
+
+\section filter_coplanar_faces Coplanar faces
+
+Filter faces with bare borders:
+- element type is \a smesh.FACE
+- functor type is \a smesh.FT_CoplanarFaces
+- threshold value is the face ID
+- tolerance is in degrees
+
+\code
+# create mesh
+from SMESH_mechanic import *
+faceID = mesh.GetElementsByType(FACE)[0]
+# get all faces co-planar to the first face with tolerance 5 degrees
+filter = smesh.GetFilter(smesh.FACE, smesh.FT_CoplanarFaces,faceID,Tolerance=5.0)
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of faces coplanar with the first one:", len(ids)
+\endcode
+
+\section filter_over_constrained_faces Over-constrained faces
+
+Filter over-constrained faces:
+- element type is \a smesh.FACE
+- functor type is \a smesh.FT_OverConstrainedFace
+- threshold value is not required
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# get all over-constrained faces
+filter = smesh.GetFilter(smesh.FACE, smesh.FT_OverConstrainedFace)
+ids = mesh.GetIdsFromFilter(filter)
+print "Over-constrained faces:", ids
+\endcode
+
+\sa \ref tui_over_constrained_faces
+
+\section filter_double_elements Double edges, Double faces, Double volumes
+
+filter mesh elements basing on the same set of nodes:
+- element type is either \a smesh.EGDE, \a smesh.FACE or \a smesh.VOLUME
+- functor type is either \a smesh.FT_EqualEdges, \a
+          smesh.FT_EqualFaces or \a smesh.FT_EqualVolumes, 
+- threshold value is not required
+
+\code
+from smesh import *
+# make a mesh on a box
+box = geompy.MakeBoxDXDYDZ(100,100,100)
+mesh = Mesh( box, "Box" )
+mesh.Segment().NumberOfSegments(10)
+mesh.Quadrangle()
+mesh.Hexahedron()
+mesh.Compute()
+# copy all elements with translation and Merge nodes
+mesh.TranslateObject( mesh, MakeDirStruct( 10,0,0), Copy=True )
+mesh.MergeNodes( mesh.FindCoincidentNodes(1e-7) )
+# create filters to find equal elements
+equalEdgesFilter   = GetFilter(SMESH.EDGE, FT_EqualEdges)
+equalFacesFilter   = GetFilter(SMESH.FACE, FT_EqualFaces)
+equalVolumesFilter = GetFilter(SMESH.VOLUME, FT_EqualVolumes)
+# get equal elements
+print "Number of equal edges:",   len( mesh.GetIdsFromFilter( equalEdgesFilter ))
+print "Number of equal faces:",   len( mesh.GetIdsFromFilter( equalFacesFilter ))
+print "Number of equal volumes:", len( mesh.GetIdsFromFilter( equalVolumesFilter ))
+\endcode
+
+
+\section tui_double_nodes_control Double nodes
+
+filters mesh nodes which are coincident with other nodes (within a given tolerance):
+- element type is \a smesh.NODE
+- functor type is \a smesh.FT_EqualNodes
+- threshold value is not required
+- default tolerance is 1.0e-7
+
+\code
+from smesh import *
+# make a mesh on a box
+box = geompy.MakeBoxDXDYDZ(100,100,100)
+mesh = Mesh( box, "Box" )
+mesh.Segment().NumberOfSegments(10)
+mesh.Quadrangle()
+mesh.Hexahedron()
+mesh.Compute()
+# copy all elements with translation
+mesh.TranslateObject( mesh, MakeDirStruct( 10,0,0), Copy=True )
+# create filters to find nodes equal within tolerance of 1e-5
+filter = GetFilter(SMESH.NODE, FT_EqualNodes, Tolerance=1e-5)
+# get equal nodes
+print "Number of equal nodes:", len( mesh.GetIdsFromFilter( filter ))
+\endcode
+
+
+\section filter_borders_multiconnection Borders at multi-connection
+
+Filter border 1D mesh elements (edges) according to the specified number of
+connections (faces belonging the border edges)
+- element type is \a smesh.EDGE
+- functor type is \a smesh.FT_MultiConnection
+- threshold is integer value (number of connections)
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# get border edges with number of connected faces = 5
+filter = smesh.GetFilter(smesh.EDGE, smesh.FT_MultiConnection, 5)
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of border edges with 5 faces connected:", len(ids)
+\endcode
+
+\sa \ref tui_borders_at_multiconnection
+
+\section filter_borders_multiconnection_2d Borders at multi-connection 2D
+
+Filter 2D mesh elements (faces) which consist of edges belonging
+to the specified number of mesh elements
+- element type is \a smesh.FACE
+- functor type is \a smesh.FT_MultiConnection2D
+- threshold is integer value (number of connections)
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# get faces which consist of edges belonging to 2 mesh elements
+filter = smesh.GetFilter(smesh.FACE, smesh.FT_MultiConnection2D, 2)
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of faces consisting of edges belonging to 2 faces:", len(ids)
+\endcode
+
+\sa \ref tui_borders_at_multiconnection_2d
+
+\section filter_length Length
+
+Filter 1D mesh elements (edges) according to the edge length value:
+- element type should be \a smesh.EDGE
+- functor type should be \a smesh.FT_Length
+- threshold is floating point value (length)
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# get edges with length > 14
+filter = smesh.GetFilter(smesh.EDGE, smesh.FT_Length, smesh.FT_MoreThan, 14)
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of edges with length > 14:", len(ids)
+\endcode
+
+\sa \ref tui_length_1d
+
+\section filter_length_2d Length 2D
+
+Filter 2D mesh elements (faces) corresponding to the maximum length.
+value of its edges:
+- element type should be \a smesh.FACE
+- functor type should be \a smesh.FT_Length2D
+- threshold is floating point value (edge length)
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# get all faces that have edges with length > 14
+filter = smesh.GetFilter(smesh.FACE, smesh.FT_Length2D, smesh.FT_MoreThan, 14)
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of faces with maximum edge length > 14:", len(ids)
+\endcode
+
+\sa \ref tui_length_2d
+
+\section filter_max_element_length_2d Element Diameter 2D
+
+Filter 2D mesh elements (faces) corresponding to the maximum length
+value of its edges and diagonals:
+- element type should be \a smesh.FACE
+- functor type should be \a smesh.FT_MaxElementLength2D
+- threshold is floating point value (edge/diagonal length)
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# get all faces that have elements with length > 10
+filter = smesh.GetFilter(smesh.FACE, smesh.FT_MaxElementLength2D, smesh.FT_MoreThan, 10)
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of faces with maximum element length > 10:", len(ids)
+\endcode
+
+\sa \ref tui_max_element_length_2d
+
+\section filter_max_element_length_3d Element Diameter 3D
+
+Filter 3D mesh elements (volumes) corresponding to the maximum length
+value of its edges and diagonals:
+- element type should be \a smesh.VOLUME
+- functor type should be \a smesh.FT_MaxElementLength3D
+- threshold is floating point value (edge/diagonal length)
+
+\code
+# create mesh with volumes
+from SMESH_mechanic import *
+mesh.Tetrahedron()
+mesh.Compute()
+# get all volumes that have elements with length > 10
+filter = smesh.GetFilter(smesh.VOLUME, smesh.FT_MaxElementLength3D, smesh.FT_MoreThan, 10)
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of volumes with maximum element length > 10:", len(ids)
+\endcode
+
+\sa \ref tui_max_element_length_3d
+
+\section filter_bare_border_volumes Bare border volumes
+
+Filter 3D mesh elements with bare borders:
+- element type is \a smesh.VOLUME
+- functor type is \a smesh.FT_BareBorderVolume
+- threshold value is not required
+
+\code
+# create mesh
+from SMESH_mechanic import *
+mesh.Tetrahedron()
+mesh.Compute()
+# remove some volumes to have volumes with bare borders
+mesh.RemoveElements( mesh.GetElementsByType(VOLUME)[0:5] )
+# get all volumes with bare borders
+filter = smesh.GetFilter(smesh.VOLUME, smesh.FT_BareBorderVolume)
+ids = mesh.GetIdsFromFilter(filter)
+print "Volumes with bare borders:", ids
+\endcode
+
+\sa \ref tui_bare_border_volumes
+
+\section filter_over_constrained_volumes Over-constrained volumes
+
+Filter over-constrained volumes:
+- element type is \a smesh.VOLUME
+- functor type is \a smesh.FT_OverConstrainedVolume
+- threshold value is not required
+
+\code
+# create mesh
+from SMESH_mechanic import *
+mesh.Tetrahedron()
+mesh.Compute()
+# get all over-constrained volumes
+filter = smesh.GetFilter(smesh.VOLUME, smesh.FT_OverConstrainedVolume)
+ids = mesh.GetIdsFromFilter(filter)
+print "Over-constrained volumes:", ids
+\endcode
+
+\sa \ref tui_over_constrained_faces
+
+\section filter_belong_to_geom Belong to Geom
+
+Filter mesh entities (nodes or elements) which all nodes lie on the
+shape defined by threshold value:
+- element type can be any entity type, from \a smesh.NODE to \a smesh.VOLUME
+- functor type should be \a smesh.FT_BelongToGeom
+- threshold is geometrical object
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# get all faces which nodes lie on the face sub_face3
+filter = smesh.GetFilter(smesh.FACE, smesh.FT_BelongToGeom, sub_face3)
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of faces which nodes lie on sub_face3:", len(ids)
+\endcode
+
+\section filter_lying_on_geom Lying on Geom
+
+Filter mesh entities (nodes or elements) at least one node of which lies on the
+shape defined by threshold value:
+- element type can be any entity type, from \a smesh.NODE to \a smesh.VOLUME
+- functor type should be \a smesh.FT_LyingOnGeom
+- threshold is geometrical object
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# get all faces at least one node of each lies on the face sub_face3
+filter = smesh.GetFilter(smesh.FACE, smesh.FT_LyingOnGeom, sub_face3)
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of faces at least one node of each lies on sub_face3:", len(ids)
+\endcode
+
+\section filter_belong_to_plane Belong to Plane
+
+Filter mesh entities (nodes or elements) which all nodes belong to the
+plane defined by threshold value with the given tolerance:
+- element type can be: \a smesh.NODE, \a smesh.EDGE, \a smesh.FACE
+- functor type should be \a smesh.FT_BelongToPlane
+- threshold is geometrical object (plane)
+- default tolerance is 1.0e-7
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# create plane
+import geompy
+plane_1 = geompy.MakePlane(p3,seg1,2000)
+geompy.addToStudy(plane_1, "plane_1")
+# get all nodes which lie on the plane \a plane_1
+filter = smesh.GetFilter(smesh.NODE, smesh.FT_BelongToPlane, plane_1)
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of nodes which lie on the plane plane_1:", len(ids)
+\endcode
+
+\section filter_belong_to_cylinder Belong to Cylinder
+
+Filter mesh entities (nodes or elements) which all nodes belong to the
+cylindrical face defined by threshold value with the given tolerance:
+- element type can be: \a smesh.NODE, \a smesh.EDGE, \a smesh.FACE
+- functor type should be \a smesh.FT_BelongToCylinder
+- threshold is geometrical object (cylindrical face)
+- default tolerance is 1.0e-7
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# get all faces which lie on the cylindrical face \a sub_face1
+filter = smesh.GetFilter(smesh.FACE, smesh.FT_BelongToCylinder, sub_face1)
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of faces which lie on the cylindrical surface sub_face1:", len(ids)
+\endcode
+
+\section filter_belong_to_surface Belong to Surface
+
+Filter mesh entities (nodes or elements) which all nodes belong to the
+arbitrary surface defined by threshold value with the given tolerance:
+- element type can be: \a smesh.NODE, \a smesh.EDGE, \a smesh.FACE
+- functor type should be \a smesh.FT_BelongToGenSurface
+- threshold is geometrical object (arbitrary surface)
+- default tolerance is 1.0e-7
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# create b-spline
+spline_1 = geompy.MakeInterpol([p4,p6,p3,p1])
+surface_1 = geompy.MakePrismVecH( spline_1, vz, 70.0 )
+geompy.addToStudy(surface_1, "surface_1")
+# get all nodes which lie on the surface \a surface_1
+filter = smesh.GetFilter(smesh.NODE, smesh.FT_BelongToGenSurface, surface_1)
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of nodes which lie on the surface surface_1:", len(ids)
+\endcode
+
+\section filter_range_of_ids Range of IDs
+
+Filter mesh entities elements (nodes or elements) according to the
+specified identifiers range:
+- element type can be any entity type, from \a smesh.NODE to \a smesh.VOLUME
+- functor type is \a smesh.FT_RangeOfIds
+- threshold is string listing required IDs and/or ranges of IDs, e.g."1,2,3,50-60,63,67,70-78" 
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# get nodes with identifiers [5-10] and [15-30]
+criterion1 = smesh.GetCriterion(smesh.NODE, smesh.FT_RangeOfIds, Treshold="5-10",\
+                                BinaryOp=smesh.FT_LogicalOR)
+criterion2 = smesh.GetCriterion(smesh.NODE, smesh.FT_RangeOfIds, Treshold="15-30")
+filter = smesh.CreateFilterManager().CreateFilter()
+filter.SetCriteria([criterion1,criterion2])
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of nodes in ranges [5-10] and [15-30]:", len(ids)
+\endcode
+
+\section filter_bad_oriented_volume Badly oriented volume
+
+Filter 3D mesh elements (volumes), which are incorrectly oriented from
+the point of view of MED convention. 
+- element type should be \a smesh.VOLUME
+- functor type is \a smesh.FT_BadOrientedVolume
+- threshold is not required
+
+\code
+# create mesh with volumes
+from SMESH_mechanic import *
+mesh.Tetrahedron()
+mesh.Compute()
+# get all badly oriented volumes
+filter = smesh.GetFilter(smesh.VOLUME, smesh.FT_BadOrientedVolume)
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of badly oriented volumes:", len(ids)
+\endcode
+
+\section filter_linear_or_quadratic Linear / quadratic
+
+Filter linear / quadratic mesh elements:
+- element type should be any element type, e.g.: \a smesh.EDGE, \a smesh.FACE, \a smesh.VOLUME
+- functor type is \a smesh.FT_LinearOrQuadratic
+- threshold is not required
+- if unary operator is set to smesh.FT_LogicalNOT, the quadratic
+elements are selected, otherwise (by default) linear elements are selected
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# get number of linear and quadratic edges
+filter_linear = smesh.GetFilter(smesh.EDGE, smesh.FT_LinearOrQuadratic)
+filter_quadratic = smesh.GetFilter(smesh.EDGE, smesh.FT_LinearOrQuadratic, smesh.FT_LogicalNOT)
+ids_linear = mesh.GetIdsFromFilter(filter_linear)
+ids_quadratic = mesh.GetIdsFromFilter(filter_quadratic)
+print "Number of linear edges:", len(ids_linear), "; number of quadratic edges:", len(ids_quadratic)
+# convert mesh to quadratic
+print "Convert to quadratic..."
+mesh.ConvertToQuadratic(True)
+# get number of linear and quadratic edges
+ids_linear = mesh.GetIdsFromFilter(filter_linear)
+ids_quadratic = mesh.GetIdsFromFilter(filter_quadratic)
+print "Number of linear edges:", len(ids_linear), "; number of quadratic edges:", len(ids_quadratic)
+\endcode
+
+\section filter_group_color Group color
+
+Filter mesh entities, belonging to the group with the color defined by the threshold value.
+- element type can be any entity type, from \a smesh.NODE to \a smesh.VOLUME
+- functor type is \a smesh.FT_GroupColor
+- threshold should be of SALOMEDS.Color type
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# create group of edges
+all_edges = mesh.GetElementsByType(smesh.EDGE)
+grp = mesh.MakeGroupByIds("edges group", smesh.EDGE, all_edges[:len(all_edges)/4])
+import SALOMEDS
+c = SALOMEDS.Color(0.1, 0.5, 1.0)
+grp.SetColor(c)
+# get number of the edges not belonging to the group with the given color
+filter = smesh.GetFilter(smesh.EDGE, smesh.FT_GroupColor, c, smesh.FT_LogicalNOT)
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of edges not beloging to the group with color (0.1, 0.5, 1.0):", len(ids)
+\endcode
+
+\section filter_geom_type Geometry type
+
+Filter mesh elements by the geometric type defined with the threshold
+value. The list of available geometric types depends on the element
+entity type.
+- element type should be any element type, e.g.: \a smesh.EDGE, \a smesh.FACE, \a smesh.VOLUME
+- functor type should be \a smesh.FT_ElemGeomType
+- threshold is of smesh.GeometryType value
+
+\code
+# create mesh with volumes
+from SMESH_mechanic import *
+mesh.Tetrahedron()
+mesh.Compute()
+# get all triangles, quadrangles, tetrahedrons, pyramids
+filter_tri = smesh.GetFilter(smesh.FACE, smesh.FT_ElemGeomType, smesh.Geom_TRIANGLE)
+filter_qua = smesh.GetFilter(smesh.FACE, smesh.FT_ElemGeomType, smesh.Geom_QUADRANGLE)
+filter_tet = smesh.GetFilter(smesh.VOLUME, smesh.FT_ElemGeomType, smesh.Geom_TETRA)
+filter_pyr = smesh.GetFilter(smesh.VOLUME, smesh.FT_ElemGeomType, smesh.Geom_PYRAMID)
+ids_tri = mesh.GetIdsFromFilter(filter_tri)
+ids_qua = mesh.GetIdsFromFilter(filter_qua)
+ids_tet = mesh.GetIdsFromFilter(filter_tet)
+ids_pyr = mesh.GetIdsFromFilter(filter_pyr)
+print "Number of triangles:", len(ids_tri)
+print "Number of quadrangles:", len(ids_qua)
+print "Number of tetrahedrons:", len(ids_tet)
+print "Number of pyramids:", len(ids_pyr)
+\endcode
+
+\section combining_filters How to combine filters with Criterion structures?
+
+Filters can be combined by making use of "criteria".
+
+Example :
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# get all the quadrangle faces ...
+criterion1 = smesh.GetCriterion(smesh.FACE, smesh.FT_ElemGeomType, smesh.Geom_QUADRANGLE, smesh.FT_LogicalAND)
+# ... AND do NOT get those from sub_face3
+criterion2 = smesh.GetCriterion(smesh.FACE, smesh.FT_BelongToGeom, sub_face3, smesh.FT_LogicalNOT)
+filter = smesh.CreateFilterManager().CreateFilter()
+filter.SetCriteria([criterion1,criterion2])
+ids = mesh.GetIdsFromFilter(filter)
+
+myGroup = mesh.MakeGroupByIds("Quads_on_cylindrical_faces",smesh.FACE,ids)
+\endcode
+
+
+*/
diff --git a/doc/salome/gui/SMESH/input/tui_generate_flat_elements.doc b/doc/salome/gui/SMESH/input/tui_generate_flat_elements.doc
new file mode 100644 (file)
index 0000000..eaf5445
--- /dev/null
@@ -0,0 +1,82 @@
+/*!
+
+\page tui_generate_flat_elements_page Generate flat elements
+
+<br>
+\anchor tui_double_nodes_on_group_boundaries
+<h2>Double nodes on groups boundaries</h2>
+
+\n Double nodes on shared faces between groups of volumes and create flat elements on demand.
+\n The list of groups must describe a partition of the mesh volumes. The nodes of the internal
+faces at the boundaries of the groups are doubled. Optionally, the internal faces are replaced
+by flat elements.
+\n Triangles are transformed into prisms, and quadrangles into hexahedrons.
+\n The flat elements are stored in groups of volumes.
+
+\n
+\n This example represents an iron cable (a thin cylinder) in a concrete bloc (a big cylinder).
+The big cylinder is defined by two geometric volumes.
+
+\code
+import geompy
+import smesh
+import SMESH
+# geometry 
+
+O = geompy.MakeVertex(0, 0, 0)
+OX = geompy.MakeVectorDXDYDZ(1, 0, 0)
+OY = geompy.MakeVectorDXDYDZ(0, 1, 0)
+OZ = geompy.MakeVectorDXDYDZ(0, 0, 1)
+Vertex_1 = geompy.MakeVertex(50, 0, 0)
+Cylinder_1 = geompy.MakeCylinder(O, OX, 10, 500)
+Cylinder_2 = geompy.MakeCylinder(Vertex_1, OX, 100, 400)
+Vertex_2 = geompy.MakeVertex(-200, -200, -200)
+Vertex_3 = geompy.MakeVertex(250, 200, 200)
+Box_1 = geompy.MakeBoxTwoPnt(Vertex_2, Vertex_3)
+Fuse_1 = geompy.MakeFuse(Cylinder_1, Cylinder_2)
+Partition_1 = geompy.MakePartition([Fuse_1], [Cylinder_1, Box_1], [], [], geompy.ShapeType["SOLID"], 0, [], 0)
+[Solid_1,Solid_2] = geompy.GetShapesOnShape(Cylinder_1, Partition_1, geompy.ShapeType["SOLID"], geompy.GEOM.ST_IN)
+[Solid_3,Solid_4] = geompy.GetShapesOnShape(Cylinder_2, Partition_1, geompy.ShapeType["SOLID"], geompy.GEOM.ST_IN)
+Vertex_4 = geompy.MakeVertex(450, 0, 0)
+Vertex_5 = geompy.MakeVertex(500, 0, 0)
+Vertex_6 = geompy.MakeVertex(550, 0, 0)
+vec1 = geompy.MakeVector(Vertex_4, Vertex_5)
+vec2 = geompy.MakeVector(Vertex_5, Vertex_6)
+[Face_1] = geompy.GetShapesOnPlane(Partition_1, geompy.ShapeType["FACE"], vec1, geompy.GEOM.ST_ON)
+[Face_2] = geompy.GetShapesOnPlane(Partition_1, geompy.ShapeType["FACE"], vec2, geompy.GEOM.ST_ON)
+
+# meshing (we have linear tetrahedrons here, but other elements are OK)
+
+Mesh_1 = smesh.Mesh(Partition_1)
+Regular_1D = Mesh_1.Segment()
+Nb_Segments_1 = Regular_1D.NumberOfSegments(15)
+MEFISTO_2D = Mesh_1.Triangle(algo=smesh.MEFISTO)
+Length_From_Edges_2D = MEFISTO_2D.LengthFromEdges()
+ALGO3D = Mesh_1.Tetrahedron()
+isDone = Mesh_1.Compute()
+
+# relevant groups of volumes and faces
+
+Solid_1_1 = Mesh_1.GroupOnGeom(Solid_1,'Solid_1',SMESH.VOLUME)
+Solid_2_1 = Mesh_1.GroupOnGeom(Solid_2,'Solid_2',SMESH.VOLUME)
+Solid_3_1 = Mesh_1.GroupOnGeom(Solid_3,'Solid_3',SMESH.VOLUME)
+Solid_4_1 = Mesh_1.GroupOnGeom(Solid_4,'Solid_4',SMESH.VOLUME)
+Face_1_1 = Mesh_1.GroupOnGeom(Face_1,'Face_1',SMESH.FACE)
+Face_2_1 = Mesh_1.GroupOnGeom(Face_2,'Face_2',SMESH.FACE)
+
+\endcode
+
+\n Here, the 4 groups of volumes [Solid_1_1, Solid_2_1, Solid_3_1, Solid_4_1] constitute a partition of the mesh.
+The flat elements on group boundaries and on faces are built with the following code.
+\n If the last argument (Boolean) in DoubleNodesOnGroupBoundaries is set to 1,
+the flat elements are built, otherwise, there is only a duplication of the nodes.
+
+\code
+Mesh_1.DoubleNodesOnGroupBoundaries([Solid_1_1, Solid_2_1, Solid_3_1, Solid_4_1], 1)
+
+Mesh_1.CreateFlatElementsOnFacesGroups([Face_1_1, Face_2_1])
+\endcode
+
+\n To observe flat element groups, save the resulting mesh on a MED file and reload it.
+
+*/
index e03433f1c7a02337adc5db6c5adfdcd2909d6037..a163d13f5891cd4f35f334b09c3c447d35c7e665 100644 (file)
@@ -19,7 +19,11 @@ aFilter = smesh.GetFilter(smesh.FACE, smesh.FT_Area, smesh.FT_MoreThan, 100.)
 anIds = mesh.GetIdsFromFilter(aFilter) 
 
 # create a group consisting of faces with area > 100
-aGroup = mesh.MakeGroupByIds("Area > 100", smesh.FACE, anIds)
+aGroup1 = mesh.MakeGroupByIds("Area > 100", smesh.FACE, anIds)
+
+# create a group that contains all nodes from the mesh
+aGroup2 = mesh.CreateEmptyGroup(smesh.NODE, "all nodes")
+aGroup2.AddFrom(mesh.mesh)
 
 salome.sg.updateObjBrowser(1)
 \endcode
@@ -70,6 +74,51 @@ aSmeshGroup2 = quadra.GroupOnGeom(aGeomGroupE)
 salome.sg.updateObjBrowser(1)
 \endcode
 
+<br>
+\anchor tui_create_group_on_filter
+
+<h2>Create a Group on Filter</h2>
+
+\code
+from smesh import *
+SetCurrentStudy(salome.myStudy)
+
+box = geompy.MakeBoxDXDYDZ(10,10,10)
+
+# make a mesh with quadrangles of different area in range [1,16]
+mesh = Mesh(box,"Quad mesh")
+hyp1D = mesh.Segment().StartEndLength( 1, 4 )
+mesh.Quadrangle()
+mesh.Compute()
+
+# create a group on filter selecting faces of medium size
+critaria = [ \
+    GetCriterion(FACE, FT_Area, ">", 1.1, BinaryOp=FT_LogicalAND ),
+    GetCriterion(FACE, FT_Area, "<", 15.0 )
+    ]
+filt = GetFilterFromCriteria( critaria )
+filtGroup = mesh.GroupOnFilter( FACE, "group on filter", filt )
+print "Group on filter conatains %s elemens" % filtGroup.Size()
+
+# group on filter is updated if the mesh is modified
+hyp1D.SetStartLength( 2.5 )
+hyp1D.SetEndLength( 2.5 )
+mesh.Compute()
+print "After mesh change, group on filter conatains %s elemens" % filtGroup.Size()
+
+# set a new filter defining the group
+filt2 = GetFilter( FACE, FT_RangeOfIds, "1-50" )
+filtGroup.SetFilter( filt2 )
+print "With a new filter, group on filter conatains %s elemens" % filtGroup.Size()
+
+# group is updated at modification of the filter
+filt2.SetCriteria( [ GetCriterion( FACE, FT_RangeOfIds, "1-70" )])
+filtIDs3 = filtGroup.GetIDs()
+print "After filter modification, group on filter conatains %s elemens" % filtGroup.Size()
+
+salome.sg.updateObjBrowser(1)
+\endcode
+
 <br>
 \anchor tui_edit_group
 <h2>Edit a Group</h2>
@@ -318,13 +367,13 @@ salome.sg.updateObjBrowser(1)
 \endcode
 
 \image html dimgroup_tui1.png
-<center>Source groups of faces<\center>
+<center>Source groups of faces</center>
 
 \image html dimgroup_tui2.png
-<center>Result groups of edges and nodes<\center>
+<center>Result groups of edges and nodes</center>
 
 
 
 
 
-*/
\ No newline at end of file
+*/
diff --git a/doc/salome/gui/SMESH/input/tui_measurements.doc b/doc/salome/gui/SMESH/input/tui_measurements.doc
new file mode 100644 (file)
index 0000000..aabf0b3
--- /dev/null
@@ -0,0 +1,84 @@
+/*!
+
+\page tui_measurements_page Measurements
+
+\section tui_min_distance Minimum Distance
+
+\code
+
+import smesh
+from SMESH_mechanic import mesh as mesh1
+from SMESH_test1 import mesh as mesh2
+
+mesh1.Compute()
+mesh2.Compute()
+
+# compute min distance from mesh1 to the origin (not available yet)
+smesh.MinDistance(mesh1)
+
+# compute min distance from node 10 of mesh1 to the origin
+smesh.MinDistance(mesh1, id1=10)
+# ... or
+mesh1.MinDistance(10)
+
+# compute min distance between nodes 10 and 20 of mesh1
+smesh.MinDistance(mesh1, id1=10, id2=20)
+# ... or
+mesh1.MinDistance(10, 20)
+
+# compute min distance from element 100 of mesh1 to the origin (not available yet)
+smesh.MinDistance(mesh1, id1=100, isElem1=True)
+# ... or
+mesh1.MinDistance(100, isElem1=True)
+
+# compute min distance between elements 100 and 200 of mesh1 (not available yet)
+smesh.MinDistance(mesh1, id1=100, id2=200, isElem1=True, isElem2=True)
+# ... or
+mesh1.MinDistance(100, 200, True, True)
+
+# compute min distance from element 100 to node 20 of mesh1 (not available yet)
+smesh.MinDistance(mesh1, id1=100, id2=20, isElem1=True)
+# ... or
+mesh1.MinDistance(100, 20, True)
+
+# compute min distance from mesh1 to mesh2 (not available yet)
+smesh.MinDistance(mesh1, mesh2)
+
+# compute min distance from node 10 of mesh1 to node 20 of mesh2
+smesh.MinDistance(mesh1, mesh2, 10, 20)
+
+# compute min distance from node 10 of mesh1 to element 200 of mesh2 (not available yet)
+smesh.MinDistance(mesh1, mesh2, 10, 200, isElem2=True)
+
+# etc...
+
+\endcode
+
+\section tui_bounding_box Bounding Box
+
+\code
+
+import smesh
+from SMESH_mechanic import mesh as mesh1
+from SMESH_test1 import mesh as mesh2
+
+mesh1.Compute()
+mesh2.Compute()
+
+# compute bounding box for mesh1
+mesh1.BoundingBox()
+
+# compute bounding box for list of nodes of mesh1
+mesh1.BoundingBox([363, 364, 370, 371, 372, 373, 379, 380, 381])
+
+# compute bounding box for list of elements of mesh1
+mesh1.BoundingBox([363, 364, 370, 371, 372, 373, 379, 380, 381], isElem=True)
+
+# compute common bounding box of mesh1 and mesh2
+smesh.BoundingBox([mesh1, mesh2])
+
+# etc...
+
+\endcode
+
+*/
index bc7b78c89e2da15d8db4ccdb8f1259e74a28f274..922d15969d2d931342831cde4f76cf5f9b998948 100644 (file)
@@ -22,6 +22,26 @@ if new_id == 0: print "KO node addition."
 else:           print "New Node has been added with ID ", new_id
 \endcode
 
+<br>
+\anchor tui_add_0DElement
+<h3>Add 0D Element</h3>
+
+\code
+import SMESH_mechanic
+
+mesh = SMESH_mechanic.mesh
+
+# add node
+node_id = mesh.AddNode(50, 10, 0)
+
+# add 0D Element
+new_id = mesh.Add0DElement(node_id)
+
+print ""
+if new_id == 0: print "KO node addition."
+else:           print "New 0D Element has been added with ID ", new_id
+\endcode
+
 <br>
 \anchor tui_add_edge
 <h3>Add Edge</h3>
@@ -262,35 +282,40 @@ else:        print "KO Elements removing."
 \endcode
 
 <br>
-\anchor tui_renumbering_nodes_and_elements
-<h2>Renumbering Nodes and Elements</h2>
+\anchor tui_removing_orphan_nodes
+<h3>Removing Orphan Nodes</h3>
 
 \code
 import SMESH_mechanic
 
 mesh = SMESH_mechanic.mesh
 
-mesh.RenumberNodes()
-
-mesh.RenumberElements()
+# add orphan nodes
+mesh.AddNode(0,0,0)
+mesh.AddNode(1,1,1)
+# remove just created orphan nodes
+res = mesh.RemoveOrphanNodes()
+if res == 1: print "Removed %d nodes!" % res
+else:        print "KO nodes removing."
 \endcode
 
 <br>
-\anchor tui_moving_nodes
-<h2>Moving Nodes</h2>
+\anchor tui_renumbering_nodes_and_elements
+<h2>Renumbering Nodes and Elements</h2>
 
 \code
 import SMESH_mechanic
 
 mesh = SMESH_mechanic.mesh
 
-# move node #38
-mesh.MoveNode(38, 20., 10., 0.)
+mesh.RenumberNodes()
+
+mesh.RenumberElements()
 \endcode
 
 <br>
-\anchor tui_mesh_through_point
-<h2>Mesh through point</h2>
+\anchor tui_moving_nodes
+<h2>Moving Nodes</h2>
 
 \code
 from geompy import *
@@ -324,16 +349,11 @@ n = mesh.FindNodeClosestTo( -1,-1,-1 )
 if not n == node000:
     raise "FindNodeClosestTo() returns " + str( n ) + " != " + str( node000 )
 
-# check if any node will be found for a point inside a box
-n = mesh.FindNodeClosestTo( 100, 100, 100 )
-if not n > 0:
-    raise "FindNodeClosestTo( 100, 100, 100 ) fails"
-
 # move node000 to a new location
 x,y,z = -10, -10, -10
-n = mesh.MeshToPassThroughAPoint( x,y,z )
-if not n == node000:
-    raise "FindNodeClosestTo() returns " + str( n ) + " != " + str( node000 )
+n = mesh.MoveNode( n,x,y,z )
+if not n:
+    raise "MoveNode() returns " + n
 
 # check the coordinates of the node000
 xyz = mesh.GetNodeXYZ( node000 )
@@ -768,7 +788,6 @@ mesh.RotationSweepObject(GroupRotate, axisXYZ, angle45, 4, 1e-5)
 
 \code
 import geompy
-
 import smesh
 
 # define the geometry
@@ -802,17 +821,151 @@ algo2D.MaxElementArea(240)
 isDone = Mesh_2.Compute()
 if not isDone: print 'Mesh Mesh_2 : computation failed'
 
-# create a pattern
+# create a 2d pattern
 pattern = smesh.GetPattern()
 
 isDone = pattern.LoadFromFace(Mesh_2.GetMesh(), Face_2, 0)
 if (isDone != 1): print 'LoadFromFace :', pattern.GetErrorCode()
 
 # apply the pattern to a face of the first mesh
-pattern.ApplyToMeshFaces(Mesh_1.GetMesh(), [17], 0, 0)
-
+facesToSplit = Mesh_1.GetElementsByType(smesh.SMESH.FACE)
+print "Splitting %d rectangular face(s) to %d triangles..."%(len(facesToSplit), 2*len(facesToSplit))
+pattern.ApplyToMeshFaces(Mesh_1.GetMesh(), facesToSplit, 0, 0)
 isDone = pattern.MakeMesh(Mesh_1.GetMesh(), 0, 0)
 if (isDone != 1): print 'MakeMesh :', pattern.GetErrorCode()  
+
+# create quadrangle mesh
+Mesh_3 = smesh.Mesh(Box_1)
+Mesh_3.Segment().NumberOfSegments(1)
+Mesh_3.Quadrangle()
+Mesh_3.Hexahedron()
+isDone = Mesh_3.Compute()
+if not isDone: print 'Mesh Mesh_3 : computation failed'
+
+# create a 3d pattern (hexahedrons)
+pattern_hexa = smesh.GetPattern()
+
+smp_hexa = """!!! Nb of points:
+15
+      0        0        0   !- 0
+      1        0        0   !- 1
+      0        1        0   !- 2
+      1        1        0   !- 3
+      0        0        1   !- 4
+      1        0        1   !- 5
+      0        1        1   !- 6
+      1        1        1   !- 7
+    0.5        0      0.5   !- 8
+    0.5        0        1   !- 9
+    0.5      0.5      0.5   !- 10
+    0.5      0.5        1   !- 11
+      1        0      0.5   !- 12
+      1      0.5      0.5   !- 13
+      1      0.5        1   !- 14
+  !!! Indices of points of 4 elements:
+  8 12 5 9 10 13 14 11
+  0 8 9 4 2 10 11 6
+  2 10 11 6 3 13 14 7
+  0 1 12 8 2 3 13 10"""
+
+pattern_hexa.LoadFromFile(smp_hexa)
+
+# apply the pattern to a mesh
+volsToSplit = Mesh_3.GetElementsByType(smesh.SMESH.VOLUME)
+print "Splitting %d hexa volume(s) to %d hexas..."%(len(volsToSplit), 4*len(volsToSplit))
+pattern_hexa.ApplyToHexahedrons(Mesh_3.GetMesh(), volsToSplit,0,3)
+isDone = pattern_hexa.MakeMesh(Mesh_3.GetMesh(), True, True)
+if (isDone != 1): print 'MakeMesh :', pattern_hexa.GetErrorCode()  
+
+# create one more quadrangle mesh
+Mesh_4 = smesh.Mesh(Box_1)
+Mesh_4.Segment().NumberOfSegments(1)
+Mesh_4.Quadrangle()
+Mesh_4.Hexahedron()
+isDone = Mesh_4.Compute()
+if not isDone: print 'Mesh Mesh_4 : computation failed'
+
+# create another 3d pattern (pyramids)
+pattern_pyra = smesh.GetPattern()
+
+smp_pyra = """!!! Nb of points:
+9
+        0        0        0   !- 0
+        1        0        0   !- 1
+        0        1        0   !- 2
+        1        1        0   !- 3
+        0        0        1   !- 4
+        1        0        1   !- 5
+        0        1        1   !- 6
+        1        1        1   !- 7
+      0.5      0.5      0.5   !- 8
+  !!! Indices of points of 6 elements:
+  0 1 5 4 8
+  7 5 1 3 8
+  3 2 6 7 8
+  2 0 4 6 8
+  0 2 3 1 8
+  4 5 7 6 8"""
+
+pattern_pyra.LoadFromFile(smp_pyra)
+
+# apply the pattern to a face mesh
+volsToSplit = Mesh_4.GetElementsByType(smesh.SMESH.VOLUME)
+print "Splitting %d hexa volume(s) to %d hexas..."%(len(volsToSplit), 6*len(volsToSplit))
+pattern_pyra.ApplyToHexahedrons(Mesh_4.GetMesh(), volsToSplit,1,0)
+isDone = pattern_pyra.MakeMesh(Mesh_4.GetMesh(), True, True)
+if (isDone != 1): print 'MakeMesh :', pattern_pyra.GetErrorCode()  
+\endcode
+
+<br>
+\anchor tui_quadratic
+<h2>Convert mesh to/from quadratic</h2>
+
+\code
+import geompy
+import smesh
+
+# create sphere of radius 100
+
+Sphere = geompy.MakeSphereR( 100 )
+geompy.addToStudy( Sphere, "Sphere" )
+
+# create simple trihedral mesh
+
+Mesh = smesh.Mesh(Sphere)
+Regular_1D = Mesh.Segment()
+Nb_Segments = Regular_1D.NumberOfSegments(5)
+MEFISTO_2D = Mesh.Triangle()
+Tetrahedron = Mesh.Tetrahedron()
+
+# compute mesh
+
+isDone = Mesh.Compute()
+
+# convert to quadratic
+# theForce3d = 1; this results in the medium node lying at the
+# middle of the line segments connecting start and end node of a mesh
+# element
+
+Mesh.ConvertToQuadratic( theForce3d=1 )
+
+# revert back to the non-quadratic mesh
+
+Mesh.ConvertFromQuadratic()
+
+# convert to quadratic
+# theForce3d = 0; this results in the medium node lying at the
+# geometrical edge from which the mesh element is built
+
+Mesh.ConvertToQuadratic( theForce3d=0 )
+
+# to convert not the whole mesh but a sub-mesh, provide it as 
+# an additional argument to the functions:
+# Mesh.ConvertToQuadratic( 0, subMesh )
+# Mesh.ConvertFromQuadratic( subMesh )
+#
+# Note that the mesh becomes non-conformal at conversion of sub-mesh.
+
 \endcode
 
-*/
\ No newline at end of file
+*/
diff --git a/doc/salome/gui/SMESH/input/tui_notebook_smesh.doc b/doc/salome/gui/SMESH/input/tui_notebook_smesh.doc
new file mode 100644 (file)
index 0000000..a300ee6
--- /dev/null
@@ -0,0 +1,47 @@
+/*!
+
+\page tui_notebook_smesh_page Using SALOME NoteBook
+
+\anchor tui_notebook_smesh
+
+\code
+import geompy
+import smesh
+import salome_notebook
+
+# set variables
+notebook = salome_notebook.notebook
+notebook.set("Length", 100)
+notebook.set("Width", 200)
+notebook.set("Offset", 50)
+
+notebook.set("NbSegments", 7)
+notebook.set("MaxElementArea", 800)
+notebook.set("MaxElementVolume", 900)
+
+# create a box
+box = geompy.MakeBoxDXDYDZ("Length", "Width", 300)
+idbox = geompy.addToStudy(box, "Box")
+
+# create a mesh
+tetra = smesh.Mesh(box, "MeshBox")
+
+algo1D = tetra.Segment()
+algo1D.NumberOfSegments("NbSegments")
+
+algo2D = tetra.Triangle()
+algo2D.MaxElementArea("MaxElementArea")
+
+algo3D = tetra.Tetrahedron()
+algo3D.MaxElementVolume("MaxElementVolume")
+
+# compute the mesh
+ret = tetra.Compute()
+
+# translate the mesh
+point = smesh.PointStruct("Offset", 0., 0.)
+vector = smesh.DirStruct(point) 
+tetra.TranslateObject(tetra, vector, 0)
+\endcode
+
+*/
index 57d52c69e7a3d04c657d9ade576a4986dc7f72a5..bc99172aaec77fceb5ec25b114f2eb7d1caf1939 100644 (file)
@@ -2,9 +2,7 @@
 
 \page tui_quality_controls_page Quality Controls
 
-<br>
-\anchor tui_free_borders
-<h2>Free Borders</h2>
+\section tui_free_borders Free Borders
 
 \code
 import salome
@@ -48,9 +46,7 @@ aGroup.Add(anIds)
 salome.sg.updateObjBrowser(1)
 \endcode
 
-<br>
-\anchor tui_borders_at_multiconnection
-<h2>Borders at Multiconnection</h2>
+\section tui_borders_at_multiconnection Borders at Multiconnection
 
 \code
 import salome
@@ -97,9 +93,7 @@ aGroup.Add(anIds)
 salome.sg.updateObjBrowser(1)
 \endcode
 
-<br>
-\anchor tui_length_1d
-<h2>Length 1D</h2>
+\section tui_length_1d Length 1D
 
 \code
 import salome
@@ -145,9 +139,7 @@ aGroup.Add(anIds)
 salome.sg.updateObjBrowser(1)
 \endcode
 
-<br>
-\anchor tui_free_edges
-<h2>Free Edges</h2>
+\section tui_free_edges Free Edges
 
 \code
 import SMESH_mechanic
@@ -189,9 +181,7 @@ for i in range(len(aBorders)):
 salome.sg.updateObjBrowser(1)
 \endcode
 
-<br>
-\anchor tui_free_nodes
-<h2>Free Nodes</h2>
+\section tui_free_nodes Free Nodes
 
 \code
 import salome
@@ -242,10 +232,7 @@ print ""
 salome.sg.updateObjBrowser(1)
 \endcode
 
-
-<br>
-\anchor tui_free_faces
-<h2>Free Faces</h2>
+\section tui_free_faces Free Faces
 
 \code
 import salome
@@ -281,13 +268,12 @@ geompy.addToStudy( Plane_2, "Plane_2" )
 import smesh
 
 import StdMeshers
-import NETGENPlugin
 
 Mesh_1 = smesh.Mesh(Partition_1)
 Regular_1D = Mesh_1.Segment()
 Max_Size_1 = Regular_1D.MaxSize(34.641)
 MEFISTO_2D = Mesh_1.Triangle()
-Tetrahedron_Netgen = Mesh_1.Tetrahedron(algo=smesh.NETGEN)
+Tetrahedronn = Mesh_1.Tetrahedron()
 isDone = Mesh_1.Compute()
 
 # create a group of free faces
@@ -298,11 +284,11 @@ aGroup = Mesh_1.CreateEmptyGroup(smesh.FACE, "Free_faces")
 aGroup.Add(aFaceIds)
 
 # print the result
-print "Criterion: Free nodes Nb = ", len(anNodeIds)
+print "Criterion: Free faces Nb = ", len(aFaceIds)
 j = 1
 for i in range(len(aFaceIds)):
   if j > 20: j = 1; print ""
-  print anNodeIds[i],
+  print aFaceIds[i],
   j = j + 1
   pass
 print ""
@@ -322,10 +308,91 @@ aGroup.Add(aFaceIds)
 salome.sg.updateObjBrowser(1)
 \endcode
 
+\section tui_bare_border_faces Bare border faces
+
+\code
+from smesh import *
+SetCurrentStudy(salome.myStudy)
+
+box = geompy.MakeBoxDXDYDZ(100, 100, 100)
+geompy.addToStudy( box, "box" )
+
+mesh = smesh.Mesh(box)
+mesh.Segment().NumberOfSegments(3)
+mesh.Quadrangle()
+mesh.Compute()
+
+# remove 2 faces
+allFaces = mesh.GetElementsByType(FACE)
+mesh.RemoveElements( allFaces[0:2])
+
+bareGroup = mesh.MakeGroup("bare faces", FACE, FT_BareBorderFace)
+assert(bareGroup.Size() == 3)
+\endcode
+
+\section tui_bare_border_volumes Bare border volumes
+
+\code
+from smesh import *
+SetCurrentStudy(salome.myStudy)
+
+box = geompy.MakeBoxDXDYDZ(100, 30, 10)
+# the smallest face of the box
+face = geompy.SubShapeAllSorted( box, geompy.ShapeType["FACE"])[0]
+
+geompy.addToStudy( box, "box" )
+geompy.addToStudyInFather( box, face, "face" )
+
+mesh = Mesh(box)
+mesh.AutomaticHexahedralization();
+
+# remove half of mesh faces from the smallest face
+faceFaces = mesh.GetSubMeshElementsId(face)
+faceToRemove = faceFaces[: len(faceFaces)/2]
+mesh.RemoveElements( faceToRemove )
+
+# make a group of volumes missing the removed faces
+bareGroup = mesh.MakeGroup("bare volumes", VOLUME, FT_BareBorderVolume)
+assert(bareGroup.Size() == len( faceToRemove))
+\endcode
+
+\section tui_over_constrained_faces Over-constrained faces
+\code
+from smesh import *
+SetCurrentStudy(salome.myStudy)
+
+mesh = Mesh()
+faceFilter = GetFilter(FACE,FT_OverConstrainedFace)
+
+#make an edge
+n1 = mesh.AddNode(0,0,0)
+n2 = mesh.AddNode(10,0,0)
+edge = mesh.AddEdge([n1,n2])
+assert( not mesh.GetIdsFromFilter( faceFilter ))
 
-<br>
-\anchor tui_length_2d
-<h2>Length 2D</h2>
+# make faces 
+mesh.ExtrusionSweep([edge], MakeDirStruct(0,7,0), 5)
+assert( 2 == len( mesh.GetIdsFromFilter( faceFilter )))
+\endcode
+
+\section tui_over_constrained_volumes Over-constrained volumes
+\code
+from smesh import *
+SetCurrentStudy(salome.myStudy)
+
+mesh = Mesh()
+volumeFilter = GetFilter(VOLUME,FT_OverConstrainedVolume)
+
+# make volumes by extrusion of one face
+n1 = mesh.AddNode(0,0,0)
+n2 = mesh.AddNode(10,0,0)
+edge = mesh.AddEdge([n1,n2])
+mesh.ExtrusionSweep([edge], MakeDirStruct(0,7,0), 1)
+mesh.ExtrusionSweep( mesh.GetElementsByType(FACE), MakeDirStruct(0,0,5), 7)
+assert( 2 == len( mesh.GetIdsFromFilter( volumeFilter )))
+\endcode
+
+\section tui_length_2d Length 2D
 
 \code
 import salome
@@ -372,9 +439,7 @@ aGroup.Add(anIds)
 salome.sg.updateObjBrowser(1)
 \endcode
 
-<br>
-\anchor tui_borders_at_multiconnection_2d
-<h2>Borders at Multiconnection 2D</h2>
+\section tui_borders_at_multiconnection_2d Borders at Multiconnection 2D
 
 \code
 import salome
@@ -421,9 +486,7 @@ aGroup.Add(anIds)
 salome.sg.updateObjBrowser(1)
 \endcode
 
-<br>
-\anchor tui_area
-<h2>Area</h2>
+\section tui_area Area
 
 \code
 import SMESH_mechanic
@@ -456,9 +519,7 @@ aGroup.Add(anIds)
 salome.sg.updateObjBrowser(1)  
 \endcode
 
-<br>
-\anchor tui_taper
-<h2>Taper</h2>
+\section tui_taper Taper
 
 \code
 import SMESH_mechanic
@@ -491,9 +552,7 @@ aGroup.Add(anIds)
 salome.sg.updateObjBrowser(1)
 \endcode
 
-<br>
-\anchor tui_aspect_ratio
-<h2>Aspect Ratio</h2>
+\section tui_aspect_ratio Aspect Ratio
 
 \code
 import SMESH_mechanic
@@ -526,9 +585,7 @@ aGroup.Add(anIds)
 salome.sg.updateObjBrowser(1)
 \endcode
 
-<br>
-\anchor tui_minimum_angle
-<h2>Minimum Angle</h2>
+\section tui_minimum_angle Minimum Angle
 
 \code
 import SMESH_mechanic
@@ -562,9 +619,7 @@ aGroup.Add(anIds)
 salome.sg.updateObjBrowser(1)
 \endcode
 
-<br>
-\anchor tui_warping
-<h2>Warping</h2>
+\section tui_warping Warping
 
 \code
 import SMESH_mechanic
@@ -598,9 +653,7 @@ aGroup.Add(anIds)
 salome.sg.updateObjBrowser(1) 
 \endcode
 
-<br>
-\anchor tui_skew
-<h2>Skew</h2>
+\section tui_skew Skew
 
 \code
 import SMESH_mechanic
@@ -633,9 +686,40 @@ aGroup.Add(anIds)
 salome.sg.updateObjBrowser(1)
 \endcode
 
-<br>
-\anchor tui_aspect_ratio_3d
-<h2>Aspect Ratio 3D</h2>
+\section tui_max_element_length_2d Element Diameter 2D
+
+\code
+import SMESH_mechanic
+
+smesh  = SMESH_mechanic.smesh
+mesh   = SMESH_mechanic.mesh
+salome = SMESH_mechanic.salome
+
+# Criterion : ELEMENT DIAMETER 2D > 10
+mel_2d_margin = 10
+
+aFilter = smesh.GetFilter(smesh.FACE, smesh.FT_MaxElementLength2D, smesh.FT_MoreThan, mel_2d_margin)
+
+anIds = mesh.GetIdsFromFilter(aFilter) 
+
+# print the result
+print "Criterion: Element Diameter 2D Ratio > ", mel_2d_margin, " Nb = ", len(anIds)
+j = 1
+for i in range(len(anIds)):
+  if j > 20: j = 1; print ""
+  print anIds[i],
+  j = j + 1
+  pass
+print ""
+
+# create a group
+aGroup = mesh.CreateEmptyGroup(smesh.FACE, "Element Diameter 2D > " + `mel_2d_margin`)
+aGroup.Add(anIds)
+
+salome.sg.updateObjBrowser(1)
+\endcode
+
+\section tui_aspect_ratio_3d Aspect Ratio 3D
 
 \code
 import SMESH_mechanic_tetra 
@@ -669,9 +753,7 @@ aGroup.Add(anIds)
 salome.sg.updateObjBrowser(1)
 \endcode
 
-<br>
-\anchor tui_volume
-<h2>Volume</h2>
+\section tui_volume Volume
 
 \code
 import SMESH_mechanic_tetra
@@ -706,4 +788,37 @@ aGroup.Add(anIds)
 salome.sg.updateObjBrowser(1) 
 \endcode
 
+\section tui_max_element_length_3d Element Diameter 3D
+
+\code
+import SMESH_mechanic_tetra
+
+smesh  = SMESH_mechanic_tetra.smesh
+mesh   = SMESH_mechanic_tetra.mesh
+salome = SMESH_mechanic_tetra.salome
+
+# Criterion : ELEMENT DIAMETER 3D > 10
+mel_3d_margin = 10
+
+aFilter = smesh.GetFilter(smesh.FACE, smesh.FT_MaxElementLength3D, smesh.FT_MoreThan, mel_3d_margin)
+
+anIds = mesh.GetIdsFromFilter(aFilter) 
+
+# print the result
+print "Criterion: Element Diameter 3D Ratio > ", mel_3d_margin, " Nb = ", len(anIds)
+j = 1
+for i in range(len(anIds)):
+  if j > 20: j = 1; print ""
+  print anIds[i],
+  j = j + 1
+  pass
+print ""
+
+# create a group
+aGroup = mesh.CreateEmptyGroup(smesh.FACE, "Element Diameter 3D > " + `mel_3d_margin`)
+aGroup.Add(anIds)
+
+salome.sg.updateObjBrowser(1)
+\endcode
+
 */
index 163afe0e49f2bae1c8cb0b404add6cbaab50b21b..a4c6df87d60af179feaab31896d06b7ca6d40661 100644 (file)
@@ -44,6 +44,37 @@ angle270 = 1.5 * math.pi
 mesh.Rotate([], axisXYZ, angle270, 1)  
 \endcode
 
+<br>
+\anchor tui_scale
+<h3>Scale</h3>
+
+\code
+import geompy
+Box = geompy.MakeBoxDXDYDZ(200, 200, 200)
+f = geompy.SubShapeAllSorted(Box, geompy.ShapeType["FACE"])
+
+import smesh,SMESH
+import StdMeshers
+Mesh1 = smesh.Mesh(f[0])
+Regular_1D = Mesh1.Segment()
+Nb_Segments_1 = Regular_1D.NumberOfSegments(3)
+Nb_Segments_1.SetDistrType( 0 )
+Quadrangle_2D = Mesh1.Quadrangle()
+isDone = Mesh1.Compute()
+
+#Perform scale opration for the whole mesh and creation of a new mesh
+newMesh = Mesh1.ScaleMakeMesh(Mesh1,SMESH.PointStruct(100,100,200),[0.5,0.3,0.7],True,"ScaledMesh")
+
+#Perform scale operation for the whole mesh and copy elements
+Mesh1.Scale(Mesh1,SMESH.PointStruct(200,100,100),[0.5,0.5,0.5],True,True)
+
+#Perform scale opration for two edges and move elements
+Mesh1.Scale([1,2],SMESH.PointStruct(-100,100,100),[0.8,1.0,0.7],False)
+
+#Perform scale opration for one face and move elements
+Mesh1.Scale([21],SMESH.PointStruct(0,200,200),[0.7,0.7,0.7],False)
+\endcode
+
 <br>
 \anchor tui_symmetry
 <h3>Symmetry</h3>
@@ -319,4 +350,237 @@ mesh.Compute()
 mesh.SewSideElements([69, 70, 71, 72], [91, 92, 89, 90], 8, 38, 23, 58)
 \endcode
 
-*/
\ No newline at end of file
+<br>
+\anchor tui_duplicate_nodes
+<h3>Duplicate nodes</h3>
+
+\code
+import salome
+import smesh
+import SMESH_test1
+
+mesh = SMESH_test1.mesh
+
+# Compute mesh
+mesh.Compute()
+
+# Without the duplication of border elements
+
+# Nodes to duplicate
+nodes1 = mesh.CreateEmptyGroup( smesh.NODE, 'nodes1' )
+nodes1.Add( [ 289, 278, 302, 285 ] )
+
+# Group of faces to replace nodes with new ones 
+faces1 = mesh.CreateEmptyGroup( smesh.FACE, 'faces1' )
+faces1.Add( [ 519, 556, 557 ] )
+
+# Duplicate nodes
+print "\nMesh before the first nodes duplication:"
+print "Nodes      : ", mesh.NbNodes()
+print "Edges      : ", mesh.NbEdges()
+print "Triangles  : ", mesh.NbTriangles()
+
+groupOfCreatedNodes = mesh.DoubleNodeGroup(nodes1, faces1, theMakeGroup=True)
+print "New nodes:", groupOfCreatedNodes.GetIDs()
+
+print "\nMesh after the first nodes duplication:"
+print "Nodes      : ", mesh.NbNodes()
+print "Edges      : ", mesh.NbEdges()
+print "Triangles  : ", mesh.NbTriangles()
+
+# With the duplication of border elements
+
+# Edges to duplicate
+edges = mesh.CreateEmptyGroup( smesh.EDGE, 'edges' )
+edges.Add( [ 29, 30, 31 ] )
+
+# Nodes not to duplicate
+nodes2 = mesh.CreateEmptyGroup( smesh.NODE, 'nodes2' )
+nodes2.Add( [ 32, 5 ] )
+
+# Group of faces to replace nodes with new ones 
+faces2 = mesh.CreateEmptyGroup( smesh.FACE, 'faces2' )
+faces2.Add( [ 576, 578, 580 ] )
+
+# Duplicate nodes
+print "\nMesh before the second nodes duplication:"
+print "Nodes      : ", mesh.NbNodes()
+print "Edges      : ", mesh.NbEdges()
+print "Triangles  : ", mesh.NbTriangles()
+
+groupOfNewEdges = mesh.DoubleNodeElemGroup( edges, nodes2, faces2, theMakeGroup=True )
+print "New edges:", groupOfNewEdges.GetIDs()
+
+print "\nMesh after the second nodes duplication:"
+print "Nodes      : ", mesh.NbNodes()
+print "Edges      : ", mesh.NbEdges()
+print "Triangles  : ", mesh.NbTriangles()
+
+# Update object browser
+if salome.sg.hasDesktop():
+    salome.sg.updateObjBrowser(0)
+\endcode
+
+<br>
+\anchor tui_make_2dmesh_from_3d
+<h3>Create boundary elements</h3>
+
+\code
+from smesh import *
+SetCurrentStudy(salome.myStudy)
+
+box = geompy.MakeBoxDXDYDZ(100, 100, 100)
+gFaces = geompy.SubShapeAllSorted(box, geompy.ShapeType["FACE"])
+f1,f2 = gFaces[0],gFaces[1]
+geompy.addToStudy(box,"box")
+geompy.addToStudyInFather(box,f1,"face1")
+geompy.addToStudyInFather(box,f2,"face2")
+
+twoFaces = geompy.MakeCompound([f1,f2])
+
+## -----------
+##
+## 2D from 3D
+##
+## -----------
+dim = SMESH.BND_2DFROM3D
+
+init_mesh = Mesh(box, "box")
+init_mesh.AutomaticHexahedralization() # it makes 3 x 3 x 3 hexahedrons
+
+# remove some faces
+faces = init_mesh.GetElementsByType( SMESH.FACE )
+nb_faces = len( faces )
+rm_face = faces[ : nb_faces/2]
+init_mesh.RemoveElements( rm_face )
+
+# restore boundary in this mesh
+mesh = CopyMesh( init_mesh, "2D from 3D")
+groupName = "bnd 2D"
+nb, new_mesh, new_group = mesh.MakeBoundaryElements(dim, groupName)
+
+# restore boundary (only) in other mesh
+meshName = "2D boundary of " + init_mesh.GetName()
+nb, new_mesh, new_group = init_mesh.MakeBoundaryElements(dim, groupName, meshName)
+
+# restore boundary in mesh copy
+meshName = init_mesh.GetName() + " + boundary"
+nb, new_mesh, new_group = init_mesh.MakeBoundaryElements(dim, groupName, meshName, toCopyAll=True)
+
+
+## -----------
+##
+## 1D from 2D
+##
+## -----------
+dim = SMESH.BND_1DFROM2D
+
+init_mesh = Mesh(f1, "2D mesh")
+init_mesh.AutomaticHexahedralization()
+
+# remove some edges
+edges = init_mesh.GetElementsByType( SMESH.EDGE )
+nb_edges = len( edges )
+rm_edge = edges[ : nb_edges/2]
+init_mesh.RemoveElements( rm_edge )
+
+
+# restore boundary edges in this mesh
+mesh = CopyMesh( init_mesh, "1D from 2D")
+groupName = "bnd 1D"
+nb, new_mesh, new_group = mesh.MakeBoundaryElements(dim, groupName)
+
+# restore boundary edges (only) in other mesh
+meshName = "1D boundary of " + init_mesh.GetName()
+nb, new_mesh, new_group = init_mesh.MakeBoundaryElements(dim, groupName, meshName)
+
+# restore boundary edges in mesh copy
+meshName = init_mesh.GetName() + " + boundary"
+nb, new_mesh, new_group = init_mesh.MakeBoundaryElements(dim, groupName, meshName, toCopyAll=True)
+
+
+
+## ------------------
+##
+## 1D from 2D GROUPS
+##
+## ------------------
+dim = SMESH.BND_1DFROM3D
+
+init_mesh = Mesh(box, "box")
+init_mesh.AutomaticHexahedralization() # it makes 3 x 3 x 3 hexahedrons
+# remove all edges
+rm_edges = init_mesh.GetElementsByType( SMESH.EDGE )
+init_mesh.RemoveElements( rm_edges )
+
+# make groups of faces
+fGroup1 = init_mesh.Group( f1, "f1" )
+fGroup2 = init_mesh.Group( f2, "f2" )
+
+# make 1D boundary around groups in this mesh
+mesh = CopyMesh( init_mesh, "1D from 2D groups", toCopyGroups=True)
+groups = mesh.GetGroups()
+nb, new_mesh, new_group = mesh.MakeBoundaryElements(dim, groupName,groups=groups)
+
+# make 1D boundary (only) in other mesh
+meshName =  "boundary from groups of " + init_mesh.GetName()
+groups = init_mesh.GetGroups()
+nb, new_mesh, new_group = init_mesh.MakeBoundaryElements(dim, groupName, meshName,groups=groups)
+
+# make 1D boundary in mesh copy
+meshName = init_mesh.GetName() + " + boundary from groups"
+nb, new_mesh, new_group = init_mesh.MakeBoundaryElements(dim, groupName, meshName,
+                                                         groups=groups, toCopyAll=True)
+
+\endcode
+
+<br>
+\anchor tui_reorient_faces
+<h3>Reorient faces by vector</h3>
+
+\code
+import smesh, geompy, SMESH
+
+# create a geometry consisting of two faces
+box = geompy.MakeBoxDXDYDZ( 10, 10, 10 )
+faces = geompy.SubShapeAllSorted( box, geompy.ShapeType["FACE"])
+
+shape = geompy.MakeCompound( faces[:2] )
+faces = geompy.SubShapeAll( shape, geompy.ShapeType["FACE"] )
+geompy.addToStudy( shape, "shape")
+geompy.addToStudyInFather( shape, faces[0], "faces[0]")
+geompy.addToStudyInFather( shape, faces[1], "faces[1]")
+
+# create a 2D mesh
+mesh = smesh.Mesh( shape, "test_Reorient2D")
+mesh.AutomaticHexahedralization(0.5)
+localAlgo = mesh.Segment(faces[0])
+localAlgo.NumberOfSegments( 11 )
+mesh.Compute()
+group = mesh.Group( faces[1] )
+
+vec = geompy.MakeVectorDXDYDZ( 1, 1, 1 )
+
+# Each of arguments of Reorient2D() function can be of different types:
+#
+# 2DObject    - the whole mesh
+# Direction   - a GEOM object (vector)
+# FaceOrPoint - an ID of face
+mesh.Reorient2D( mesh, vec, mesh.NbElements() )
+#
+# 2DObject    - a sub-mesh
+# Direction   - components of a vector
+# FaceOrPoint - a GEOM object (vertex)
+mesh.Reorient2D( localAlgo.GetSubMesh(), [ 1, -1, 1 ], geompy.GetFirstVertex( vec ))
+#
+# 2DObject    - a group of faces
+# Direction   - a SMESH.DirStruct structure
+# FaceOrPoint - coordinates of a point
+mesh.Reorient2D( group, smesh.MakeDirStruct( -10, 1, 10 ), [0,0,0])
+#
+# FaceOrPoint - a SMESH.PointStruct structure
+mesh.Reorient2D( localAlgo.GetSubMesh().GetIDs(), [10,1,0], SMESH.PointStruct(0,0,0))
+
+\endcode
+
+*/
diff --git a/doc/salome/gui/SMESH/input/tui_use_existing_faces.doc b/doc/salome/gui/SMESH/input/tui_use_existing_faces.doc
new file mode 100644 (file)
index 0000000..8b9c732
--- /dev/null
@@ -0,0 +1,124 @@
+/*!
+
+\page tui_use_existing_faces Use existing faces
+
+This sample demonstrates how to use <b>Use existing faces</b> algorithm,
+which is actulally just a stub allowing to use your own 2D algoritm
+implemented in Python.
+
+
+\code
+import smesh, geompy
+import numpy as np
+
+# define my 2D algorithm
+def my2DMeshing( geomFace ):
+
+    # find gravity center of geomFace
+    gcXYZ = geompy.PointCoordinates( geompy.MakeCDG( geomFace ))
+
+    # define order and orientation of edges
+    sortedEdges = []
+    geomEdges = geompy.SubShapeAll( geomFace, geompy.ShapeType["EDGE"])
+    sortedEdges.append(( geomEdges.pop(0), True ))
+    while geomEdges:
+        prevEdge_rev = sortedEdges[ -1 ]
+        prevVV = geompy.SubShapeAll( prevEdge_rev[0], geompy.ShapeType["VERTEX"])
+        prevV2 = prevVV[ prevEdge_rev[1] ]
+        found = False
+        for iE in range( len( geomEdges )):
+            v1,v2 = geompy.SubShapeAll( geomEdges[ iE ], geompy.ShapeType["VERTEX"])
+            same1,same2 = [( geompy.MinDistance( prevV2, v ) < 1e-7 ) for v in [v1,v2] ]
+            if not same1 and not same2: continue
+            sortedEdges.append(( geomEdges.pop( iE ), same1 ))
+            found = True
+            break
+        assert found
+    sortedEdges.reverse()
+
+    # put nodes on edges in a right order
+    nodes = []
+    for edge, isForward in sortedEdges:
+        v1,v2 = geompy.SubShapeAll( edge, geompy.ShapeType["VERTEX"])
+        edgeNodes = mesh.GetSubMeshNodesId( v2,   all=False ) + \
+                    mesh.GetSubMeshNodesId( edge, all=False ) + \
+                    mesh.GetSubMeshNodesId( v1,   all=False )
+        if not isForward: edgeNodes.reverse()
+        nodes.extend( edgeNodes[:-1] )
+
+    # create nodes inside the geomFace
+    r1 = 0.6
+    r2 = 1 - r1
+    nodesInside = []
+    for n in nodes:
+        nXYZ = mesh.GetNodeXYZ( n )
+        newXYZ = np.add( np.multiply( r1, gcXYZ ), np.multiply( r2, nXYZ ))
+        nodesInside.append( mesh.AddNode( newXYZ[0], newXYZ[1], newXYZ[2] ))
+        mesh.SetNodeOnFace( nodesInside[-1], geomFace, 0, 0 )
+
+    # find out orientation of faces to create
+    #    geomFace normal
+    faceNorm = geompy.GetNormal( geomFace )
+    v1,v2 = [ geompy.PointCoordinates( v ) \
+              for v in geompy.SubShapeAll( faceNorm, geompy.ShapeType["VERTEX"]) ]
+    faceNormXYZ = np.subtract( v2, v1 )
+    outDirXYZ   = np.subtract( v1, [ 50, 50, 50 ] )
+    if np.dot( faceNormXYZ, outDirXYZ ) < 0: # reversed face
+        faceNormXYZ = np.multiply( -1., faceNormXYZ )
+    #   mesh face normal
+    e1 = np.subtract( mesh.GetNodeXYZ( nodes[0] ), mesh.GetNodeXYZ( nodes[1] ))
+    e2 = np.subtract( mesh.GetNodeXYZ( nodes[0] ), mesh.GetNodeXYZ( nodesInside[0] ))
+    meshNorm = np.cross( e1, e2 )
+    #   faces orientation
+    reverse = ( np.dot( faceNormXYZ, meshNorm ) < 0 )
+
+    # create mesh faces
+    iN = len( nodes )
+    while iN:
+        n1, n2, n3, n4 = nodes[iN-1], nodes[iN-2], nodesInside[iN-2], nodesInside[iN-1]
+        iN -= 1
+        if reverse:
+            f = mesh.AddFace( [n1, n2, n3, n4] )
+        else:
+            f = mesh.AddFace( [n4, n3, n2, n1] )
+        # new faces must be assigned to geometry to allow 3D algorithm finding them
+        mesh.SetMeshElementOnShape( f, geomFace )
+
+    if reverse:
+        nodesInside.reverse()
+    polygon = mesh.AddPolygonalFace( nodesInside )
+    mesh.SetMeshElementOnShape( polygon, geomFace )
+
+    return
+
+# create geometry and get faces to mesh with my2DMeshing()
+box = geompy.MakeBoxDXDYDZ( 100, 100, 100 )
+f1 = geompy.SubShapeAll( box, geompy.ShapeType["FACE"])[0]
+f2 = geompy.GetOppositeFace( box, f1 )
+geompy.addToStudy( box, "box" )
+geompy.addToStudy( f1, "f1" )
+geompy.addToStudy( f2, "f2" )
+
+# compute 1D mesh
+mesh = smesh.Mesh( box )
+mesh.Segment().NumberOfSegments( 5 )
+mesh.Compute()
+
+# compute 2D mesh
+mesh.Quadrangle()
+mesh.UseExistingFaces(f1) # UseExistingFaces() allows using my2DMeshing()
+mesh.UseExistingFaces(f2)
+my2DMeshing( f1 )
+my2DMeshing( f2 )
+assert mesh.Compute()
+
+# compute 3D mesh
+mesh.Prism()
+assert mesh.Compute()
+
+\endcode
+
+Resulting mesh:
+\image html use_existing_face_sample_mesh.png
+
+*/
index 59681c16b856af4458426206528e721d88eb313e..fc0094e4b5f440348035387c3b9a8e8d9be70f13 100644 (file)
@@ -9,10 +9,12 @@
 \code
 import geompy
 import smesh
+import SMESH
 
 # create a box
 box = geompy.MakeBox(0., 0., 0., 20., 20., 20.)
 geompy.addToStudy(box, "box")
+[Face_1,Face_2,Face_3,Face_4,Face_5,Face_5] = geompy.SubShapeAll(box, geompy.ShapeType["FACE"])
 
 # create a mesh
 tetra = smesh.Mesh(box, "MeshBox")
@@ -23,13 +25,25 @@ algo1D.NumberOfSegments(3)
 algo2D = tetra.Triangle()
 algo2D.MaxElementArea(10.)
 
-algo3D = tetra.Tetrahedron(smesh.NETGEN)
+algo3D = tetra.Tetrahedron()
 algo3D.MaxElementVolume(900.)
 
+# Creation of SubMesh
+Regular_1D_1_1 = tetra.Segment(geom=Face_1)
+Nb_Segments_1 = Regular_1D_1_1.NumberOfSegments(5)
+Nb_Segments_1.SetDistrType( 0 )
+Quadrangle_2D = tetra.Quadrangle(geom=Face_1)
+isDone = tetra.Compute()
+submesh = Regular_1D_1_1.GetSubMesh()
+
 # compute the mesh
 tetra.Compute()
 
-# print information about the mesh
+# Creation of group
+group = tetra.CreateEmptyGroup( SMESH.FACE, 'Group' )
+nbAdd = group.Add( [ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76 ] )
+
+# Print information about the mesh
 print "Information about mesh:" 
 print "Number of nodes       : ", tetra.NbNodes()
 print "Number of edges       : ", tetra.NbEdges()
@@ -43,5 +57,83 @@ print "          hexahedrons : ", tetra.NbHexas()
 print "          prisms      : ", tetra.NbPrisms()
 print "          pyramids    : ", tetra.NbPyramids()
 print "          polyhedrons : ", tetra.NbPolyhedrons() 
+
+# Get Information About Mesh by GetMeshInfo
+print "\nInformation about mesh by GetMeshInfo:"
+info = smesh.GetMeshInfo(tetra)
+keys = info.keys(); keys.sort()
+for i in keys:
+  print "  %s   :  %d" % ( i, info[i] )
+  pass
+
+# Get Information About Group by GetMeshInfo
+print "\nInformation about group by GetMeshInfo:"
+info = smesh.GetMeshInfo(group)
+keys = info.keys(); keys.sort()
+for i in keys:
+  print "  %s  :  %d" % ( i, info[i] )
+  pass
+
+# Get Information About SubMesh by GetMeshInfo
+print "\nInformation about Submesh by GetMeshInfo:"
+info = smesh.GetMeshInfo(submesh)
+keys = info.keys(); keys.sort()
+for i in keys:
+  print "  %s  :  %d" % ( i, info[i] )
+  pass
+\endcode
+
+
+
+<br>
+\anchor tui_find_element_by_point
+<h2>Find Element by Point</h2>
+
+\code
+import geompy
+import smesh
+import SMESH
+
+# Create a geometry to mesh
+box = geompy.MakeBoxDXDYDZ(100,100,100)
+
+# Create a mesh
+mesh = Mesh(box,"Mesh")
+mesh.AutomaticHexahedralization()
+mesh.Compute()
+
+# Create a point
+x,y,z = 0, 0, 1
+
+# Find all elements (except 0D ones) located at the point
+all_elems_except_0D = mesh.FindElementsByPoint(x,y,z)
+assert( len(all_elems_except_0D) == 4)
+
+# Find nodes at the point
+nodes = mesh.FindElementsByPoint(x,y,z, SMESH.NODE )
+assert( len(nodes) == 0)
+assert( len( mesh.FindElementsByPoint(x,y,0, SMESH.NODE)) == 1)
+
+# Find an edge at the point
+edges = mesh.FindElementsByPoint(x,y,z, SMESH.EDGE )
+assert( len(edges) == 1)
+
+# Find faces at the point
+edges = mesh.FindElementsByPoint(x,y,z, SMESH.FACE )
+assert( len(edges) == 2)
+
+# Find a volume at the point
+vols = mesh.FindElementsByPoint(x,y,z, SMESH.VOLUME )
+assert( len(vols) == 1)
+
+# Find 0D elements at the point
+elems0d = mesh.FindElementsByPoint(x,y,z, SMESH.ELEM0D )
+assert( len(elems0d) == 0)
+
+# Find edges within a group
+group1D = mesh.MakeGroupByIds("1D", SMESH.EDGE, [1,2] )
+edges = mesh.FindElementsByPoint(x,y,z, SMESH.EDGE, group1D )
+
 \endcode
-*/
\ No newline at end of file
+
+*/
diff --git a/doc/salome/gui/SMESH/input/tui_work_on_objects_from_gui.doc b/doc/salome/gui/SMESH/input/tui_work_on_objects_from_gui.doc
new file mode 100644 (file)
index 0000000..abc51d9
--- /dev/null
@@ -0,0 +1,27 @@
+/*!
+
+\page tui_work_on_objects_from_gui How to work with objects from the GUI ?
+
+It is sometimes useful to work alternatively in the GUI of SALOME and in the Python Console. To fetch an object from the TUI simply type:
+
+\code
+myMesh_ref = salome.IDToObject("ID")  
+// were ID is the number that appears in the object browser in the Entry column 
+// ( If hidden show it by right clicking and checking the checkbox Entry)
+myMesh = smesh.Mesh(myMesh_ref)
+\endcode
+or 
+\code
+myMesh_ref = salome.myStudy.FindObjectByPath("/Mesh/myMesh").GetObject() 
+// "/Mesh/myMesh" is the path to the desired object in the object browser
+myMesh = smesh.Mesh(myMesh_ref)
+\endcode
+
+All the methods documented in these pages can then be used on myMesh
+
+\note The first statement only gives you access to a reference to the object created via the GUI. 
+\n But the methods available on this reference are not exactly the same as those documented in these help pages. 
+This Python API is meant to be used on smesh.Mesh instances. 
+\n That's why you'll have to create such an instance with the second statement. 
+
+*/
diff --git a/doc/salome/gui/SMESH/input/use_existing_algos.doc b/doc/salome/gui/SMESH/input/use_existing_algos.doc
new file mode 100644 (file)
index 0000000..3634ccf
--- /dev/null
@@ -0,0 +1,66 @@
+/*!
+
+\page import_algos_page Use Existing Elements Algorithms
+
+\n <em>Use Existing Elements </em>algorithms allow to define the mesh of a geometrical
+object by importing suitably located mesh elements from another
+mesh. The mesh elements to import from the other mesh should be contained in
+groups. If several groups are used to mesh the same geometry, validity of
+nodal connectivity of result mesh must be assured by connectivity of
+the source mesh; no geometrical checks are performed to merge
+different nodes at same locations.
+<br> The source elements must totally cover the meshed geometry.
+The source elements lying partially over the geometry will not be used.
+<br>
+These algorithms can be used to mesh a very complex geometry part by
+part, by storing meshes of parts in files and then fusing them
+together using these algorithms.
+<br>
+
+<b>Use Existing 1D Elements</b> algorithm allows to define the mesh of
+a geometrical edge (or group of edges)
+by importing mesh edges contained in a group (or groups) from another mesh.
+\n To apply this algorithm select the edge to be meshed (indicated in
+the field \b Geometry of <b>Create mesh</b> dialog box),
+<b>Use existing 1D elements</b> in the list of 1D algorithms and click the
+<em>"Add Hypothesis"</em> button.
+The following dialog box will appear:
+
+\image html hyp_source_edges.png
+
+In this dialog box you can define 
+<ul>
+<li>The \b Name of the algorithm. </li>
+<li>The <b>Groups of Edges</b> to import 1D elements from.
+<li><b>To copy mesh</b> checkbox allows to import not only the edges of
+the selected <b>Groups of Edges</b>, but the whole source
+mesh. In this case <b>To copy groups</b> checkbox allows to create
+the same groups as in the imported source mesh.</li>
+</ul>
+
+<b>Use Existing 2D Elements</b> algorithm allows to define the mesh of
+a geometrical face (or group of faces)
+by importing mesh faces contained in a group (or groups) from another mesh.
+\n To apply this algorithm select the geometrical face to be meshed (indicated in
+the field \b Geometry of <b>Create mesh</b> dialog box),
+<b>Use existing 2D elements</b> in the list of 2D algorithms and click the
+<em>"Add Hypothesis"</em> button.
+The following dialog box will appear:
+
+\image html hyp_source_faces.png
+
+In this dialog box you can define 
+<ul>
+<li>The \b Name of the algorithm. </li>
+<li>The <b>Groups of Edges</b> to import 1D elements from.
+<li><b>To copy mesh</b> checkbox allows to import not only the edges of
+the selected <b>Groups of Edges</b>, but the whole source
+mesh. In this case <b>To copy groups</b> checkbox allows to create
+the same groups as in the imported source mesh.</li>
+</ul>
+
+<br><b>See Also</b> a sample TUI Script of a 
+\ref tui_import "Use Existing Elements Algorithms".
+
+*/
+
index 2968a27be006feb5717247ac3194995430d4a9ea..aac0c9052fb9945a32d1a740c8a1a2136537c1de 100644 (file)
@@ -2,9 +2,14 @@
 
 \page using_notebook_mesh_page Using SALOME NoteBook
 
-It is possible to use variables defined through <b>SALOME NoteBook</b> for
-creation and modification of objects in the MESH module with the following
-limitations:
+<b>SALOME NoteBook</b> allows defining variables to be used for
+creation and modification of objects.
+
+\image html using_notebook_smesh.png "Setting of variables in SALOME NoteBook"
+
+\image html addnode_notebook.png "Use of variables to add a node in MESH module"
+
+The following limitations on the use of variables still exist:
 
 <ul>
 <li> \ref radial_prism_algo_page "Distribution of Layers" hypothesis -
@@ -28,6 +33,10 @@ limitations:
      values (indices of nodes) are correctly applied, but they are not restored
      after "Update study" operation.
 <li> \ref clipping_page "Clipping" dialog box.
-<li> <b>Colors / Size</b> dialog box.
+<li> <b>Properties</b> dialog box.
 </ul>
+
+Our <b>TUI Scripts</b> provide you with useful examples of 
+\ref tui_notebook_smesh "Using SALOME NoteBook".
+
 */
index 01a272de29177ca66451801681b6c9135ac3b673..376da99b0e5ad10f745582d6a7f667171db2808f 100644 (file)
@@ -17,13 +17,16 @@ right-clicking on the selected mesh.
 \image html dialog.png
 
 <ul>
+<li><b>Rename</b> - allows to rename the object in the Object browser.</li>
 <li><b>Hide all</b> - allows to hide all objects in the viewer.</li>
 <li><b>Update</b> - refreshes the presentation of your mesh in the
 Object Browser, applying all recent changes. </li>
-<li>\subpage mesh_infos_page "Mesh Infos" -  provides
+<li>\subpage mesh_infos_page "Mesh Information" -  provides
 information about the mesh.</li>
-<li>\ref mesh_element_info_anchor "Mesh Element Info" - provides basic
-information about the selected element of the mesh. </li>
+<li>\subpage find_element_by_point_page "Find Element by Point" -
+allows to find all mesh elements, to which belongs a point with the
+given coordinates.</li>
+<li><b>Auto Color</b> - switch on / off auto-assigning colors for the groups.</li>
 <li>\subpage numbering_page "Numbering"  - allows to display the ID
 numbers of all meshing elements or nodes composing your mesh in the
 viewer.</li>
@@ -31,19 +34,27 @@ viewer.</li>
 Wireframe, Shading and Nodes presentation.</li>
 <li>\subpage display_entity_page "Display Entity" - allows to display
 Faces, Edges or both.</li>
+<li><b>2D Quadratic</b> - allows to select between the representation
+of quadratic edges as broken <b>lines</b> or as <b>arcs</b></li>
 <li><b>Orientation of faces</b> - shows vectors of orientation of
-faces of the selected mesh</li> 
-<li><b>Colors / Size</b> - allows to select color and size of
-meshes.</li>
+faces of the selected mesh. The orientation vector is shown for each 2D mesh element 
+and for each free face of a 3D mesh element. the vector direction is calculated by 
+the first three nodes of the face produced by vectors n1-n2 and n1-n3.</li> 
+<li>\subpage colors_size_page "Properties" - allows to define several properties, including color of elements, shrink size, ....</li>
 <li>\subpage transparency_page "Transparency" - allows to change the
 transparency of mesh elements.</li>
-<li>\subpage clipping_page "Clipping" - allows to create cross-sections of the selected objects.</li>
-<li>\ref about_quality_controls_page "Controls" - graphically
+<li>\ref quality_page "Controls" - graphically
 presents various information about meshes.</li>
 <li><b>Hide</b> - allows to hide the selected mesh from the viewer.</li>
 <li><b>Show Only</b> -allows to display only the selected mesh, hiding all other from the viewer.</li>
+<li>\subpage clipping_page "Clipping" - allows to create cross-sections of the selected objects.</li>
 <li><b>Dump view</b> - exports an object from the viewer in bmp, png, jpg or jpeg image format.</li>
-<li><b>Change background</b> - allows to redefine the background color. By default it is black.</li>
+<li><b>Change background</b> - allows to redefine the background
+color. By default it is black.</li>
+<li><b>View Operations</b> checkbox - allows to show/hide the
+visualization toolbar in the viewer window.</li>
+<li><b>Recording Operations</b> - allows to show/hide the recording
+toolbar in the viewer window.</li>
 </ul>
 
 */
index ba99c193ebc3b9bd3528f7f73894ef1c2149e551..4d74fcbf02efd33341a2dce73e33b22aa8685902 100644 (file)
@@ -9,8 +9,8 @@
 <ol>
 <li>Display your mesh in the viewer.</li>
 
-<li>Choose <b>Controls > Volume</b> or click <em>"Volume"</em> button
-in the toolbar.
+<li>Choose <b>Controls > Volume Controls > Volume</b> or click
+<em>"Volume"</em> button in the toolbar.
 
 \image html image145.png
 <center><em>"Volume" button</em></center>
index 83bfaa3ac638c4d11b7cd188669af966a62d8b5d..86ba0c9055e1bf0ed2426c77b468ae740a5602ca 100644 (file)
@@ -24,8 +24,8 @@ projection height ?h? to the half edge length ?l?.
 <ol>
 <li>Display your mesh in the viewer.</li>
 
-<li>Choose <b>Controls > Warping Angle</b> or click <em>"Warping angle"</em>
-button of the toolbar.
+<li>Choose <b>Controls > Face Controls > Warping Angle</b> or click
+<em>"Warping angle"</em> button of the toolbar.
 
 \image html image39.png
 <center><em>"Warping angle" button</em></center>
index 88e613d2392388224ab7c6ba85e7aafb73185dac..7a2dcbde8e1abe74a42ba5554635bdfa6473a572 100755 (executable)
-H1 { 
-   text-align: center; 
+/* The standard CSS for doxygen */
+
+body, table, div, p, dl {
+       font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif;
+       font-size: 12px;
+}
+
+/* @group Heading Levels */
+
+h1 {
+       font-size: 150%;
+}
+
+h2 {
+       font-size: 120%;
+}
+
+h3 {
+       font-size: 100%;
+}
+
+dt {
+       font-weight: bold;
+}
+
+div.multicol {
+       -moz-column-gap: 1em;
+       -webkit-column-gap: 1em;
+       -moz-column-count: 3;
+       -webkit-column-count: 3;
+}
+
+p.startli, p.startdd, p.starttd {
+       margin-top: 2px;
+}
+
+p.endli {
+       margin-bottom: 0px;
+}
+
+p.enddd {
+       margin-bottom: 4px;
+}
+
+p.endtd {
+       margin-bottom: 2px;
+}
+
+/* @end */
+
+caption {
+       font-weight: bold;
+}
+
+span.legend {
+        font-size: 70%;
+        text-align: center;
+}
+
+h3.version {
+        font-size: 90%;
+        text-align: center;
+}
+
+div.qindex, div.navtab{
+       background-color: #EBEFF6;
+       border: 1px solid #A3B4D7;
+       text-align: center;
+       margin: 2px;
+       padding: 2px;
+}
+
+div.qindex, div.navpath {
+       width: 100%;
+       line-height: 140%;
+}
+
+div.navtab {
+       margin-right: 15px;
+}
+
+/* @group Link Styling */
+
+a {
+       color: #3D578C;
+       font-weight: normal;
+       text-decoration: none;
+}
+
+.contents a:visited {
+       color: #4665A2;
+}
+
+a:hover {
+       text-decoration: underline;
+}
+
+a.qindex {
+       font-weight: bold;
+}
+
+a.qindexHL {
+       font-weight: bold;
+       background-color: #9CAFD4;
+       color: #ffffff;
+       border: 1px double #869DCA;
+}
+
+.contents a.qindexHL:visited {
+        color: #ffffff;
+}
+
+a.el {
+       font-weight: bold;
+}
+
+a.elRef {
+}
+
+a.code {
+       color: #4665A2;
+}
+
+a.codeRef {
+       color: #4665A2;
+}
+
+/* @end */
+
+dl.el {
+       margin-left: -1cm;
+}
+
+.fragment {
+       font-family: monospace, fixed;
+       font-size: 105%;
+}
+
+pre.fragment {
+       border: 1px solid #C4CFE5;
+       background-color: #FBFCFD;
+       padding: 4px 6px;
+       margin: 4px 8px 4px 2px;
+       overflow: auto;
+       word-wrap: break-word;
+       font-size:  9pt;
+       line-height: 125%;
+}
+
+div.ah {
+       background-color: black;
+       font-weight: bold;
+       color: #ffffff;
+       margin-bottom: 3px;
+       margin-top: 3px;
+       padding: 0.2em;
+       border: solid thin #333;
+       border-radius: 0.5em;
+       -webkit-border-radius: .5em;
+       -moz-border-radius: .5em;
+       box-shadow: 2px 2px 3px #999;
+       -webkit-box-shadow: 2px 2px 3px #999;
+       -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
+       background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444));
+       background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000);
+}
+
+div.groupHeader {
+       margin-left: 16px;
+       margin-top: 12px;
+       font-weight: bold;
+}
+
+div.version {
+       border:1px solid #0000FF;
+        color: #CCCCCC;
+       font-family: Arial, Helvetica, sans-serif;
+       font-size: 9pt;
+       text-align: center;
+       width:100px;
+       -moz-border-radius: 8px;
+       margin: 5px;
+}
+                    
+div.footer1 {
+    background-color: #DFE5F1;
+    border: 1px solid #AAAAAA;
+    font-family: Arial, Helvetica, sans-serif;
+    font-size: 11px;
+    padding: 10px;
+    margin-top: 15px;
+}
+           
+
+div.groupText {
+       margin-left: 16px;
+       font-style: italic;
+}
+
+body {
+       background: white;
+       color: black;
+        margin: 0;
+}
+
+div.contents {
+       margin-top: 10px;
+       margin-left: 10px;
+       margin-right: 10px;
+}
+
+td.indexkey {
+       background-color: #EBEFF6;
+       font-weight: bold;
+       border: 1px solid #C4CFE5;
+       margin: 2px 0px 2px 0;
+       padding: 2px 10px;
+}
+
+td.indexvalue {
+       background-color: #EBEFF6;
+       border: 1px solid #C4CFE5;
+       padding: 2px 10px;
+       margin: 2px 0px;
+}
+
+tr.memlist {
+       background-color: #EEF1F7;
+}
+
+p.formulaDsp {
+       text-align: center;
+}
+
+img.formulaDsp {
+       
+}
+
+img.formulaInl {
+       vertical-align: middle;
+}
+
+div.center {
+       text-align: center;
+        margin-top: 0px;
+        margin-bottom: 0px;
+        padding: 0px;
+}
+
+div.center img {
+       border: 0px;
+}
+
+address.footer {
+       text-align: right;
+       padding-right: 12px;
+}
+
+img.footer {
+       border: 0px;
+       vertical-align: middle;
+}
+
+/* @group Code Colorization */
+
+span.keyword {
+       color: #008000
+}
+
+span.keywordtype {
+       color: #604020
+}
+
+span.keywordflow {
+       color: #e08000
+}
+
+span.comment {
+       color: #800000
+}
+
+span.preprocessor {
+       color: #806020
+}
+
+span.stringliteral {
+       color: #002080
+}
+
+span.charliteral {
+       color: #008080
+}
+
+span.vhdldigit { 
+       color: #ff00ff 
+}
+
+span.vhdlchar { 
+       color: #000000 
+}
+
+span.vhdlkeyword { 
+       color: #700070 
+}
+
+span.vhdllogic { 
+       color: #ff0000 
+}
+
+/* @end */
+
+/*
+.search {
+       color: #003399;
+       font-weight: bold;
+}
+
+form.search {
+       margin-bottom: 0px;
+       margin-top: 0px;
+}
+
+input.search {
+       font-size: 75%;
+       color: #000080;
+       font-weight: normal;
+       background-color: #e8eef2;
+}
+*/
+
+td.tiny {
+       font-size: 75%;
+}
+
+.dirtab {
+       padding: 4px;
+       border-collapse: collapse;
+       border: 1px solid #A3B4D7;
+}
+
+th.dirtab {
+       background: #EBEFF6;
+       font-weight: bold;
+}
+
+hr {
+       height: 0px;
+       border: none;
+       border-top: 1px solid #4A6AAA;
+}
+
+hr.footer {
+       height: 1px;
+}
+
+/* @group Member Descriptions */
+
+table.memberdecls {
+       border-spacing: 0px;
+       padding: 0px;
+}
+
+.mdescLeft, .mdescRight,
+.memItemLeft, .memItemRight,
+.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
+       background-color: #F9FAFC;
+       border: none;
+       margin: 4px;
+       padding: 1px 0 0 8px;
+}
+
+.mdescLeft, .mdescRight {
+       padding: 0px 8px 4px 8px;
+       color: #555;
+}
+
+.memItemLeft, .memItemRight, .memTemplParams {
+       border-top: 1px solid #C4CFE5;
+}
+
+.memItemLeft, .memTemplItemLeft {
+        white-space: nowrap;
+}
+
+.memTemplParams {
+       color: #4665A2;
+        white-space: nowrap;
+}
+
+/* @end */
+
+/* @group Member Details */
+
+/* Styles for detailed member documentation */
+
+.memtemplate {
+       font-size: 80%;
+       color: #4665A2;
+       font-weight: normal;
+       margin-left: 9px;
+}
+
+.memnav {
+       background-color: #EBEFF6;
+       border: 1px solid #A3B4D7;
+       text-align: center;
+       margin: 2px;
+       margin-right: 15px;
+       padding: 2px;
+}
+
+.memitem {
+       padding: 0;
+       margin-bottom: 10px;
+}
+
+.memname {
+        white-space: nowrap;
+        font-weight: bold;
+        margin-left: 6px;
+}
+
+.memproto {
+        border-top: 1px solid #A8B8D9;
+        border-left: 1px solid #A8B8D9;
+        border-right: 1px solid #A8B8D9;
+        padding: 6px 0px 6px 0px;
+        color: #253555;
+        font-weight: bold;
+        text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+        /* opera specific markup */
+        box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+        border-top-right-radius: 8px;
+        border-top-left-radius: 8px;
+        /* firefox specific markup */
+        -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+        -moz-border-radius-topright: 8px;
+        -moz-border-radius-topleft: 8px;
+        /* webkit specific markup */
+        -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+        -webkit-border-top-right-radius: 8px;
+        -webkit-border-top-left-radius: 8px;
+        background-image:url('nav_f.png');
+        background-repeat:repeat-x;
+        background-color: #E2E8F2;
+
+}
+
+.memdoc {
+        border-bottom: 1px solid #A8B8D9;      
+        border-left: 1px solid #A8B8D9;      
+        border-right: 1px solid #A8B8D9; 
+        padding: 2px 5px;
+        background-color: #FBFCFD;
+        border-top-width: 0;
+        /* opera specific markup */
+        border-bottom-left-radius: 8px;
+        border-bottom-right-radius: 8px;
+        box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+        /* firefox specific markup */
+        -moz-border-radius-bottomleft: 8px;
+        -moz-border-radius-bottomright: 8px;
+        -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+        background-image: -moz-linear-gradient(center top, #FFFFFF 0%, #FFFFFF 60%, #F7F8FB 95%, #EEF1F7);
+        /* webkit specific markup */
+        -webkit-border-bottom-left-radius: 8px;
+        -webkit-border-bottom-right-radius: 8px;
+        -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+        background-image: -webkit-gradient(linear,center top,center bottom,from(#FFFFFF), color-stop(0.6,#FFFFFF), color-stop(0.60,#FFFFFF), color-stop(0.95,#F7F8FB), to(#EEF1F7));
+}
+
+.paramkey {
+       text-align: right;
+}
+
+.paramtype {
+       white-space: nowrap;
 }
 
-CAPTION { 
-   font-weight: bold 
+.paramname {
+       color: #602020;
+       white-space: nowrap;
 }
+.paramname em {
+       font-style: normal;
+}
+
+.params, .retval, .exception, .tparams {
+        border-spacing: 6px 2px;
+}       
+
+.params .paramname, .retval .paramname {
+        font-weight: bold;
+        vertical-align: top;
+}
+        
+.params .paramtype {
+        font-style: italic;
+        vertical-align: top;
+}       
+        
+.params .paramdir {
+        font-family: "courier new",courier,monospace;
+        vertical-align: top;
+}
+
+
+
 
-/* Link in the top navbar */
-A.qindex {}
+/* @end */
 
-A.qindexRef {}
+/* @group Directory (tree) */
 
-/* Link to any cross-referenced Doxygen element */
-A.el { 
-   text-decoration: none; 
-   font-weight: bold 
+/* for the tree view */
+
+.ftvtree {
+       font-family: sans-serif;
+       margin: 0px;
+}
+
+/* these are for tree view when used as main index */
+
+.directory {
+       font-size: 9pt;
+       font-weight: bold;
+       margin: 5px;
 }
 
-A.elRef { 
-   font-weight: bold 
+.directory h3 {
+       margin: 0px;
+       margin-top: 1em;
+       font-size: 11pt;
 }
 
-/* Link to any cross-referenced Doxygen element inside a code section 
-   (ex: header)
+/*
+The following two styles can be used to replace the root node title
+with an image of your choice.  Simply uncomment the next two styles,
+specify the name of your image and be sure to set 'height' to the
+proper pixel height of your image.
+*/
+
+/*
+.directory h3.swap {
+       height: 61px;
+       background-repeat: no-repeat;
+       background-image: url("yourimage.gif");
+}
+.directory h3.swap span {
+       display: none;
+}
 */
-A.code { 
-   text-decoration: none; 
-   font-weight: normal; 
-   color: #4444ee 
+
+.directory > h3 {
+       margin-top: 0;
+}
+
+.directory p {
+       margin: 0px;
+       white-space: nowrap;
+}
+
+.directory div {
+       display: none;
+       margin: 0px;
+}
+
+.directory img {
+       vertical-align: -30%;
+}
+
+/* these are for tree view when not used as main index */
+
+.directory-alt {
+       font-size: 100%;
+       font-weight: bold;
+}
+
+.directory-alt h3 {
+       margin: 0px;
+       margin-top: 1em;
+       font-size: 11pt;
+}
+
+.directory-alt > h3 {
+       margin-top: 0;
+}
+
+.directory-alt p {
+       margin: 0px;
+       white-space: nowrap;
+}
+
+.directory-alt div {
+       display: none;
+       margin: 0px;
+}
+
+.directory-alt img {
+       vertical-align: -30%;
+}
+
+/* @end */
+
+div.dynheader {
+        margin-top: 8px;
+}
+
+address {
+       font-style: normal;
+       color: #2A3D61;
+}
+
+table.doxtable {
+       border-collapse:collapse;
+}
+
+table.doxtable td, table.doxtable th {
+       border: 1px solid #2D4068;
+       padding: 3px 7px 2px;
+}
+
+table.doxtable th {
+       background-color: #374F7F;
+       color: #FFFFFF;
+       font-size: 110%;
+       padding-bottom: 4px;
+       padding-top: 5px;
+       text-align:left;
+}
+
+.tabsearch {
+       top: 0px;
+       left: 10px;
+       height: 36px;
+       background-image: url('tab_b.png');
+       z-index: 101;
+       overflow: hidden;
+       font-size: 13px;
+}
+
+.navpath ul
+{
+       font-size: 11px;
+       background-image:url('tab_b.png');
+       background-repeat:repeat-x;
+       height:30px;
+       line-height:30px;
+       color:#8AA0CC;
+       border:solid 1px #C2CDE4;
+       overflow:hidden;
+       margin:0px;
+       padding:0px;
+}
+
+.navpath li
+{
+       list-style-type:none;
+       float:left;
+       padding-left:10px;
+       padding-right:15px;
+       background-image:url('bc_s.png');
+       background-repeat:no-repeat;
+       background-position:right;
+       color:#364D7C;
+}
+
+.navpath li.navelem a
+{
+       height:32px;
+       display:block;
+       text-decoration: none;
+       outline: none;
+}
+
+.navpath li.navelem a:hover
+{
+       color:#6884BD;
+}
+
+.navpath li.footer
+{
+        list-style-type:none;
+        float:right;
+        padding-left:10px;
+        padding-right:15px;
+        background-image:none;
+        background-repeat:no-repeat;
+        background-position:right;
+        color:#364D7C;
+        font-size: 8pt;
+}
+
+
+div.summary
+{
+       float: right;
+       font-size: 8pt;
+       padding-right: 5px;
+       width: 50%;
+       text-align: right;
+}       
+
+div.summary a
+{
+       white-space: nowrap;
+}
+
+div.ingroups
+{
+       font-size: 8pt;
+       padding-left: 5px;
+       width: 50%;
+       text-align: left;
+}
+
+div.ingroups a
+{
+       white-space: nowrap;
+}
+
+div.header
+{
+        background-image:url('nav_h.png');
+        background-repeat:repeat-x;
+       background-color: #F9FAFC;
+       margin:  0px;
+       border-bottom: 1px solid #C4CFE5;
+}
+
+div.headertitle
+{
+       padding: 5px 5px 5px 10px;
+}
+
+.title {
+        font-size: 150%;
+        font-weight: bold;
+        margin: 10px 2px;
+}
+
+dl
+{
+        padding: 0 0 0 10px;
+}
+
+dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug
+{
+        border-left:4px solid;
+        padding: 0 0 0 6px;
+}
+
+dl.note
+{
+        border-color: #D0D000;
+}
+
+dl.warning, dl.attention
+{
+        border-color: #FF0000;
+}
+
+dl.pre, dl.post, dl.invariant
+{
+        border-color: #00D000;
+}
+
+dl.deprecated
+{
+        border-color: #505050;
 }
 
-A.codeRef { 
-   font-weight: normal; 
-   color: #4444ee 
+dl.todo
+{
+        border-color: #00C0E0;
 }
 
-A:hover { 
-   text-decoration: none; 
-   background-color: lightblue 
+dl.test
+{
+        border-color: #3030E0;
 }
 
-DL.el { 
-   margin-left: -1cm 
+dl.bug
+{
+        border-color: #C08050;
 }
 
-/* A code fragment (ex: header) */
-DIV.fragment { 
-   width: 100%; 
-   border: none; 
-   background-color: #CCCCCC 
+#projectlogo
+{
+       text-align: center;
+       vertical-align: bottom;
+       border-collapse: separate;
+}
+#projectlogo img
+{ 
+       border: 0px none;
+}
+#projectname
+{
+        background-color: #175783;
+        border: 1px solid;
+        height: 80px;
+       background-repeat: no-repeat;
+/*     font: 300% arial,sans-serif;*/
+       margin: 0px;
+       padding: 0px;
+}
+    
+#projectbrief
+{
+       font: 120% arial,sans-serif;
+       margin: 0px;
+       padding: 0px;
 }
 
-/* In the alpha list (coumpound index), style of an alphabetical index letter */
-DIV.ah { 
-   background-color: #CCCCCC; 
-   font-weight: bold; 
-   color: #ffffff; 
-   margin-bottom: 3px; 
-   margin-top: 3px 
+#projectnumber
+{
+       font: 50% arial,sans-serif;
+       margin: 0px;
+       padding: 0px;
 }
 
-/* Method name (+ type) */
-TD.md { 
-   background-color: lightblue; 
-   font-weight: bold; 
+#titlearea
+{
+        background: url("head.png");
+        background-color: #175783;
+        border: 1px solid;
+        height: 80px;
+        background-repeat: no-repeat;
+       padding: 0px;
+       margin: 0px;
+       width: 100%;
+       border-bottom: 1px solid #5373B4;
 }
 
-/* Method parameter (some of them) */
-TD.mdname1 { 
-   background-color: lightblue; 
-   font-weight: bold; color: #602020; 
-}
-
-/* Method parameter (some of them) */
-TD.mdname { 
-   background-color: lightblue; 
-   font-weight: bold; 
-   color: #602020; 
-   width: 600px; 
-}
-
-/* Separator between methods group (usually empty, seems not supported by IE) */
-DIV.groupHeader { 
-   margin-left: 16px; 
-   margin-top: 12px; 
-   margin-bottom: 6px; 
-   font-weight: bold 
-}
-
-DIV.groupText { 
-   margin-left: 16px; 
-   font-style: italic; 
-   font-size: smaller 
-}
-
-BODY { 
-   background: #FFFFFF;
-}
-
-/*div.div-page { 
-  background-color: #FFFFFF; 
-  margin-left: 1em;
-  margin-right: 1em;
-  margin-top: 1em;
-  margin-bottom: 0.1em;
-
-  padding-left: 1em;
-  padding-right: 1em;
-  padding-top: 0.5em;
-  padding-bottom: 0.5em;
-
-  border: 2px solid #0D299A; 
-  border-width: 2px;
-  border-color: #0D299A; 
-}*/
-
-div.tabs { 
-  text-align: justify; 
-  margin-left    : 2px;         
-  margin-right   : 2px;  
-  margin-top     : 2px; 
-  margin-bottom  : 2px
-  font-weight: bold;
-  color: #FFFFFF;
-}
-
-DIV.div-footer { 
-  margin-left: 1em;
-  margin-right: 1em;
-  margin-bottom: 0.2em;
-  text-align: right;
-  font-size: 9pt; 
-}
-
-/* In File List, Coumpound List, etc, 1st column of the index */
-TD.indexkey { 
-   background-color: #CCCCCC; 
-   font-weight: bold; 
-   padding-right  : 10px; 
-   padding-top    : 2px; 
-   padding-left   : 10px; 
-   padding-bottom : 2px; 
-   margin-left    : 0px; 
-   margin-right   : 0px; 
-   margin-top     : 2px; 
-   margin-bottom  : 2px  
-}
-
-/* In File List, Coumpound List, etc, 2nd column of the index */
-TD.indexvalue { 
-   background-color: #CCCCCC; 
-   font-style: italic; 
-   padding-right  : 10px; 
-   padding-top    : 2px; 
-   padding-left   : 10px; 
-   padding-bottom : 2px; 
-   margin-left    : 0px; 
-   margin-right   : 0px; 
-   margin-top     : 2px; 
-   margin-bottom  : 2px  
-}
-
-span.keyword       { color: #008000 }
-span.keywordtype   { color: #604020 }
-span.keywordflow   { color: #e08000 }
-span.comment       { color: #800000 }
-span.preprocessor  { color: #806020 }
-span.stringliteral { color: #002080 }
-span.charliteral   { color: #008080 }
index 9211d570fa977e8749aadf7eed6497d7bad3e1f8..4c89a2ba1ed1150de49b5f1bc72ca9975f411550 100755 (executable)
@@ -1,10 +1,12 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-</head>
-<body>
-<hr style="width: 100%; height: 2px;">
-<div style="text-align: center;">Copyright &copy; 2003-2009 CEA, EDF<br>
-</div>
+    <li class="footer"></li>
+   </ul>
+ </div>
+ <div class="footer1">
+ <div style="text-align: center;">
+ Copyright &copy; 2007-2012  CEA/DEN, EDF R&amp;D, OPEN CASCADE<br>
+ Copyright &copy; 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&amp;D, LEG, PRINCIPIA R&amp;D, BUREAU VERITAS<br>
+ </div>
+ </div>
 </body>
 </html>
+               
\ No newline at end of file
diff --git a/doc/salome/gui/SMESH/static/header.html b/doc/salome/gui/SMESH/static/header.html
deleted file mode 100755 (executable)
index a70a95e..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-   <title>$title</title>
-   <link href="doxygen.css" rel="stylesheet" type="text/css">
-</head>
-<hr>
-<center>
-SALOME documentation central
-</center>
-<hr>
diff --git a/doc/salome/gui/SMESH/static/header.html.in b/doc/salome/gui/SMESH/static/header.html.in
new file mode 100755 (executable)
index 0000000..4571b43
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<title>$title</title>
+<link href="$relpath$tabs.css" rel="stylesheet" type="text/css"/>
+$treeview
+$search
+$mathjax
+<script type="text/javascript">
+$(document).ready(initResizable);
+</script>
+<link href="$relpath$doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body onload='searchBox.OnSelectItem(0);'>
+<div id="top"><!-- do not remove this div! -->
+<div id="titlearea"><div align="right"><div class="version">Version: @VERSION@</div></div></div>
+
+</div>
diff --git a/doc/salome/gui/SMESH/static/header_py.html.in b/doc/salome/gui/SMESH/static/header_py.html.in
new file mode 100644 (file)
index 0000000..61414bb
--- /dev/null
@@ -0,0 +1,21 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<title>$title</title>
+<link href="$relpath$tabs.css" rel="stylesheet" type="text/css"/>
+$treeview
+$search
+$mathjax
+<script type="text/javascript">
+$(document).ready(initResizable);
+</script>
+<link href="$relpath$doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body onload='searchBox.OnSelectItem(0);'>
+<div id="top"><!-- do not remove this div! -->
+<div id="titlearea"><div align="right"><div class="version">Version: @VERSION@</div></div></div>
+<div align="bottom-left"><a href=../index.html>Home</a></div>
+
+</div>
index b8cd5eee5a651a9200cd2e499cf9a059969d015c..987d26a43615ea2d85187e6e40b642ac3c4f5c64 100644 (file)
@@ -1,39 +1,32 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  File   : Makefile.in
 #  Author : Vasily Rusyaev (Open Cascade NN)
 #  Module : doc
 #
 include $(top_srcdir)/adm_local/unix/make_common_starter.am
 
-EXTRA_DIST += images static
-
-dist_doc_DATA = \
-       extra/AddNetgenInSalome2.pdf    \
-       extra/AddNetgenInSalome2.ps     \
-       extra/AddNetgenInSalome2.sxw    \
-       extra/PluginMeshers.html
+EXTRA_DIST += input images static/doxygen.css static/footer.html
 
-EXTRA_DIST += extra/PluginMeshers.txt
+tuidocdir = $(docdir)/tui/SMESH
+tuidoc_DATA = images/head.png images/smeshscreen.png
 
 dev_docs: doxyfile
        echo "Running doxygen in directory: "`pwd`; \
@@ -49,4 +42,13 @@ install-data-local:
        fi;
 
 uninstall-local:
-       rm -rf $(DESTDIR)$(docdir)/tui/SMESH
+       @test -d $(DESTDIR)$(tuidocdir) && chmod -R +w $(DESTDIR)$(tuidocdir) ; \
+       for filen in `find $(DESTDIR)$(tuidocdir) -mindepth 1 -maxdepth 1` dummy ; do \
+         case $${filen} in \
+           dummy ) ;; \
+           $(DESTDIR)$(tuidocdir)/docutils ) ;; \
+           $(DESTDIR)$(tuidocdir)/head.png ) ;; \
+           $(DESTDIR)$(tuidocdir)/smeshscreen.png ) ;; \
+           * ) echo "removing $${filen}" && rm -rf $${filen} ;; \
+         esac ; \
+       done
index bd927280e17f0cc87e84de257c808e0a78496cd8..a4143bfee410f5b29192269677fa0247a8b1f1de 100755 (executable)
@@ -1,37 +1,36 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
-# Doxyfile 1.4.6
 
 #---------------------------------------------------------------------------
 # Project related configuration options
 #---------------------------------------------------------------------------
-PROJECT_NAME           = "Mesh Module Programming Guide v.@VERSION@"
+PROJECT_NAME           = "SALOME Mesh Module Developer"
 PROJECT_NUMBER         = 
 OUTPUT_DIRECTORY       = SMESH
 CREATE_SUBDIRS         = NO
 OUTPUT_LANGUAGE        = English
 USE_WINDOWS_ENCODING   = NO
 BRIEF_MEMBER_DESC      = YES
-REPEAT_BRIEF           = NO
+REPEAT_BRIEF           = YES
 ABBREVIATE_BRIEF       = 
 ALWAYS_DETAILED_SEC    = YES
 INLINE_INHERITED_MEMB  = YES
@@ -40,6 +39,7 @@ STRIP_FROM_PATH        = @top_srcdir@ @top_builddir@
 STRIP_FROM_INC_PATH    = 
 SHORT_NAMES            = NO
 JAVADOC_AUTOBRIEF      = YES
+QT_AUTOBRIEF           = YES
 MULTILINE_CPP_IS_BRIEF = NO
 DETAILS_AT_TOP         = NO
 INHERIT_DOCS           = YES
@@ -69,7 +69,7 @@ CASE_SENSE_NAMES       = YES
 HIDE_SCOPE_NAMES       = NO
 SHOW_INCLUDE_FILES     = YES
 INLINE_INFO            = YES
-SORT_MEMBER_DOCS       = NO
+SORT_MEMBER_DOCS       = YES
 SORT_BRIEF_DOCS        = NO
 SORT_BY_SCOPE_NAME     = NO
 GENERATE_TODOLIST      = YES
@@ -91,7 +91,7 @@ WARN_IF_UNDOCUMENTED   = YES
 WARN_IF_DOC_ERROR      = YES
 WARN_NO_PARAMDOC       = NO
 WARN_FORMAT            = "$file:$line: $text"
-WARN_LOGFILE           =
+WARN_LOGFILE           = log.txt
 
 #---------------------------------------------------------------------------
 # configuration options related to the input files
@@ -99,8 +99,9 @@ WARN_LOGFILE           =
 INPUT                  = @top_srcdir@/src \
                         @top_srcdir@/bin \
                         @top_srcdir@/idl \
-                        @top_builddir@/bin
-FILE_PATTERNS          = *.idl *.hxx *.cxx *.h *.c *.hh *.cc @DOXYGEN_PYTHON_EXTENSION@
+                        @top_builddir@/bin \
+                        @srcdir@/input
+FILE_PATTERNS          = *.idl *.hxx *.cxx *.h *.c *.hh *.cc @DOXYGEN_PYTHON_EXTENSION@ *.doc
 RECURSIVE              = YES
 EXCLUDE                = 
 EXCLUDE_SYMLINKS       = NO
@@ -116,19 +117,19 @@ FILTER_SOURCE_FILES    = YES
 #---------------------------------------------------------------------------
 # configuration options related to source browsing
 #---------------------------------------------------------------------------
-SOURCE_BROWSER         = NO
-INLINE_SOURCES         = NO
+SOURCE_BROWSER         = YES
+INLINE_SOURCES         = YES
 STRIP_CODE_COMMENTS    = YES
-REFERENCED_BY_RELATION = NO
+REFERENCED_BY_RELATION = YES
 REFERENCES_RELATION    = YES
-USE_HTAGS              = NO
+#USE_HTAGS              = NO
 VERBATIM_HEADERS       = YES
 
 #---------------------------------------------------------------------------
 # configuration options related to the alphabetical class index
 #---------------------------------------------------------------------------
 ALPHABETICAL_INDEX     = YES
-COLS_IN_ALPHA_INDEX    = 3
+COLS_IN_ALPHA_INDEX    = 2
 IGNORE_PREFIX          = 
 
 #---------------------------------------------------------------------------
@@ -137,7 +138,7 @@ IGNORE_PREFIX          =
 GENERATE_HTML          = YES
 HTML_OUTPUT            = .
 HTML_FILE_EXTENSION    = .html
-HTML_HEADER            = @srcdir@/static/myheader.html
+HTML_HEADER            = @builddir@/static/header.html
 HTML_FOOTER            = @srcdir@/static/footer.html
 HTML_STYLESHEET        = @srcdir@/static/doxygen.css
 HTML_ALIGN_MEMBERS     = YES
@@ -145,8 +146,8 @@ GENERATE_HTMLHELP      = NO
 CHM_FILE               = 
 HHC_LOCATION           = 
 GENERATE_CHI           = NO
-BINARY_TOC             = YES
-TOC_EXPAND             = YES
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
 DISABLE_INDEX          = NO
 ENUM_VALUES_PER_LINE   = 4
 GENERATE_TREEVIEW      = NO
@@ -212,14 +213,14 @@ PERLMOD_MAKEVAR_PREFIX =
 # Configuration options related to the preprocessor   
 #---------------------------------------------------------------------------
 ENABLE_PREPROCESSING   = YES
-MACRO_EXPANSION        = NO
+MACRO_EXPANSION        = YES
 EXPAND_ONLY_PREDEF     = NO
 SEARCH_INCLUDES        = YES
 INCLUDE_PATH           = 
 INCLUDE_FILE_PATTERNS  = 
 PREDEFINED             = 
 EXPAND_AS_DEFINED      = 
-SKIP_FUNCTION_MACROS   = NO
+SKIP_FUNCTION_MACROS   = YES
 
 #---------------------------------------------------------------------------
 # Configuration::additions related to external references   
@@ -238,26 +239,29 @@ HIDE_UNDOC_RELATIONS   = NO
 HAVE_DOT               = YES
 CLASS_GRAPH            = YES
 COLLABORATION_GRAPH    = NO
-GROUP_GRAPHS           = NO
+GROUP_GRAPHS           = YES
 UML_LOOK               = NO
 TEMPLATE_RELATIONS     = YES
 INCLUDE_GRAPH          = YES
-INCLUDED_BY_GRAPH      = NO
+INCLUDED_BY_GRAPH      = YES
 CALL_GRAPH             = NO
 GRAPHICAL_HIERARCHY    = YES
 DIRECTORY_GRAPH        = YES
-DOT_IMAGE_FORMAT       = jpg
+DOT_IMAGE_FORMAT       = png
+DOT_FONTNAME           = Arial
 DOT_PATH               = 
 DOTFILE_DIRS           = 
 MAX_DOT_GRAPH_WIDTH    = 1024
-MAX_DOT_GRAPH_HEIGHT   = 1200
-MAX_DOT_GRAPH_DEPTH    = 0
+MAX_DOT_GRAPH_HEIGHT   = 1024
+MAX_DOT_GRAPH_DEPTH    = 1000
 DOT_TRANSPARENT        = NO
 DOT_MULTI_TARGETS      = NO
-GENERATE_LEGEND        = NO
+GENERATE_LEGEND        = YES
 DOT_CLEANUP            = YES
 
 #---------------------------------------------------------------------------
 # Configuration::additions related to the search engine   
 #---------------------------------------------------------------------------
 SEARCHENGINE           = NO
+
+
diff --git a/doc/salome/tui/extra/AddNetgenInSalome2.pdf b/doc/salome/tui/extra/AddNetgenInSalome2.pdf
deleted file mode 100644 (file)
index d736a6d..0000000
Binary files a/doc/salome/tui/extra/AddNetgenInSalome2.pdf and /dev/null differ
diff --git a/doc/salome/tui/extra/AddNetgenInSalome2.ps b/doc/salome/tui/extra/AddNetgenInSalome2.ps
deleted file mode 100644 (file)
index a81aa96..0000000
+++ /dev/null
@@ -1,13935 +0,0 @@
-%!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
-<</PageSize [595 842] /ImagingBBox null>> 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
-<B7>
-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
-<EA747265>
-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
-<B7>
-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
-<B7>
-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
-<B7>
-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
-<B7>
-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
-<EA747265>
-show
-1648 2031 moveto
-<636F6E73747275697465>
-show
-1868 2031 moveto
-<E0>
-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
-<B7>
-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
-<B7>
-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
-<E971756976616C656E74>
-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
-<B7>
-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
-<B7>
-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
-<B7>
-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
-<B7>
-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
-<B7>
-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
-<B7>
-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
-<B7>
-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
-<E971756976616C656E74>
-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
-<B7>
-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
-<B7>
-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
-<E0>
-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
-<B7>
-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
-<B7>
-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/tui/extra/AddNetgenInSalome2.sxw b/doc/salome/tui/extra/AddNetgenInSalome2.sxw
deleted file mode 100644 (file)
index 1538190..0000000
Binary files a/doc/salome/tui/extra/AddNetgenInSalome2.sxw and /dev/null differ
diff --git a/doc/salome/tui/extra/PluginMeshers.html b/doc/salome/tui/extra/PluginMeshers.html
deleted file mode 100755 (executable)
index 64c3688..0000000
+++ /dev/null
@@ -1,344 +0,0 @@
-<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
-<html>
-<head>
-    
-  <meta http-equiv="Content-Type"
- content="text/html; charset=iso-8859-1">
-    
-  <meta name="GENERATOR"
- content="Mozilla/4.79 [en] (X11; U; SunOS 5.6 sun4u) [Netscape]">
-  <title>Main Page</title>
-     
-  <link href="doxygen.css" rel="stylesheet" type="text/css">
-</head>
-  <body>
- &nbsp; 
-<center>
-<table width="96%">
- <tbody>
-    <tr>
- <td> 
-      <h1> <a href="http://www.opencascade.com"><img
- src="sources/logocorp.gif" border="0" height="46" width="122"
- align="left">
-      </a></h1>
- </td>
-  <td> 
-      <div align="right"><a href="http://www.opencascade.org/SALOME/"><img
- src="sources/application.gif" border="0" height="46" width="108"
- align="right">
-      </a></div>
- </td>
- </tr>
-  </tbody>
-</table>
-</center>
-  
-<center> 
-<h1> <a name="page2"></a>How to add your own mesher</h1>
-</center>
-  
-<center> 
-<h1> (as a set of hypotheses and algorithms)</h1>
-</center>
-  
-<center> 
-<h1> to the application.</h1>
-</center>
-  
-<h2> <a name="cont"></a>Table of contents</h2>
-  
-<ul>
- <li> <b><i><a href="#1">1. Introduction</a></i></b></li>
-  <li> <b><i><a href="#2">2. Implementation steps</a></i></b></li>
-  
-  <ul>
- <li> <b><i><a href="#2_1">2.1. Mesher plugin package</a></i></b></li>
-    <li>     <b><i><a href="#2_2">2.2. List of available hypotheses and algorithms</a></i></b></li>
-  <li> <b><i><a href="#2_3">2.3. Build server plugin library</a></i></b></li>
-  
-    <ul>
- <li> <b><i><a href="#2_3_1">2.3.1. Define interface to your hypotheses and
-algorithms</a></i></b></li>
-  <li> <b><i><a href="#2_3_2">2.3.2. Implement functionality of your hypotheses 
-and algorithms</a></i></b></li>
-  <li> <b><i><a href="#2_3_3">2.3.3. Implement interface to your hypotheses
-and algorithms</a></i></b></li>
-  <li> <b><i><a href="#2_3_4">2.3.4. Implement being exported method</a></i></b></li>
-    </ul>
-  <li> <b><i><a href="#2_4">2.4. Build client (GUI) plugin library</a></i></b></li>
-  
-    <ul>
- <li> <b><i><a href="#2_4_1">2.4.1. Implement the required GUI</a></i></b></li>
-  <li> <b><i><a href="#2_4_2">2.4.2. Provide icons and messages for your
-GUI</a></i></b></li>
-  <li> <b><i><a href="#2_4_3">2.4.3. Implement your hypotheses creator and
-being exported method</a></i></b></li>
-    </ul>
-  <li> <b><i><a href="#2_5">2.5. Provide icons for Object Browser</a></i></b></li>
-    <li> <b><i><a href="#2_6">2.6. Setup SALOME environment</a></i></b></li>
-    <ul type="square">
-      <li><b><i><a href="#2_6_1">2.6.1. Set LD_LIBRARY_PATH, PYTHONPATH,
-PATH environment variables</a></i></b></li>
-      <li><b><i><a href="#2_6_2">2.6.2. Set mesher plugin resources environment
-variable</a><br>
-        </i></b></li>
-    </ul>
-  </ul>
-</ul>
-  
-<h2> <a name="1"></a>1. Introduction</h2>
- All hypotheses and algorithms are available in SMESH module via plugin mechanism.
-Such approach allows easily to introduce new hypotheses and algorithms types
-to the application. Also, it makes possible the customization of available
-hypotheses and algorithms list for different users without recompilation
-of sources.<br>
-The goal of this document is to describe the process of creation external
-mesher plugins. 
-<p><i><a href="#cont">Back to the contents</a></i> </p>
-<h2> <a name="2"></a>2. Implementation steps</h2>
-  
-<h3> 
-<h3> <a name="2_1"></a>2.1. <small>Mesher plugin package</small></h3>
-</h3>
-Create your mesher plugin package which will contain the sources files, e.g.
-&nbsp;MyMesherPlugin.<br>
-<br>
-<i><a
- href="file:///home/vsr-local/work/SALOME/SALOME2/SMESH_SRC/doc/salome/tui/SMESH/sources/static/PluginMeshers.html#cont">Back
-to the contents</a></i><br>
-<h3><a name="2_2"></a>2.2. List of available hypotheses and algorithms</h3>
-Create XML file to describe all algorithms and hypotheses, provided by your
-plugin package (see SMESH_SRC/resources/SMESH_Meshers.xml for example).<br>
-<blockquote><small><tt><big>&lt;meshers-group name="MyName"<br>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;resources="MyResourceKey"<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-server-lib="libMyServerLib.so"<br>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;gui-lib="libMyClientLib.so"&gt;<br>
-&nbsp; &nbsp; &nbsp;&lt;hypotheses&gt;<br>
-&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&lt;hypothesis type="MyHypType1"<br>
-&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp;
-&nbsp;&nbsp;&nbsp; label-id="My beautiful hypothesis name"<br>
-&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
-&nbsp;&nbsp; icon-id="my_hypo_1_icon.png"/&gt;<br>
-&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &lt;/hypotheses&gt;<br>
-&nbsp;&nbsp;&nbsp;&nbsp; &lt;algorithms&gt;<br>
-&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &lt;algorithm type="MyAlgType1"<br>
-&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
-&nbsp;&nbsp;&nbsp; &nbsp;label-id="My beautiful algorithm name"<br>
-&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;
-&nbsp;&nbsp;&nbsp; icon-id="my_algo_1_icon.png"/&gt;<br>
-&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &lt;/algorithms&gt;<br>
-&lt;/meshers-group&gt;<br>
-  </big></tt></small><br>
-  <ul>
-    <li>Attributes of &lt;meshers-group&gt; tag:</li>
-  </ul>
-  <blockquote>
-    <ul type="circle">
-      <li>value of &lt;name&gt; attribute is used to collect hypotheses/algoritms
-in groups; you can also use this attribute for short description of your
-mesher plugin.</li>
-      <li>value of &lt;resources&gt; attribute (MyResourceKey) is used to
-access resources (messages and icons) from GUI (see paragraphs <a
- href="#2_4_2">2.4.2</a> and <a href="#2_5">2.5</a>); in the current implementation
-it should coincide with the name of plugin package; this limitation will
-be eliminated in the further development.</li>
-      <li>value of &lt;server-lib&gt; attribute describes the name of your
-mesher's server plugin library (See paragraph <a href="#2_3">2.3</a>)</li>
-      <li>value of &lt;gui-lib&gt; attribute describes the name of your mesher's
-client plugin library (See paragraph <a href="#2_4">2.4</a>)</li>
-    </ul>
-  </blockquote>
-  <ul>
-    <li>Attributes of &lt;hypothesis/algorithm&gt; tag:</li>
-  </ul>
-  <blockquote>
-    <ul type="circle">
-      <li>value of &lt;type&gt; attribute is an unique name of the hypothesis/algorithm</li>
-    </ul>
-    <ul type="circle">
-      <ul type="square">
-        <li>It is a value of _name field of your hypothesis class (see paragraph
-          <a href="#2_3">2.3</a>, implementation of constructor of StdMeshers_LocalLength
-class: _name = "LocalLength")</li>
-        <li>It is a key to each certain hypothesis class (see paragraph <a
- href="#2_3">2.3</a>, implementation of "GetHypothesisCreator()" method in
-StdMeshers_i.cxx)</li>
-        <li>It is a key to each certain hypothesis GUI (see paragraph <a
- href="#2_4">2.4</a>, implementation of "StdMeshersGUI_HypothesisCreator::CreateHypothesis()"
-and "StdMeshersGUI_HypothesisCreator::EditHypothesis()" methods in StdMeshersGUI.cxx)</li>
-        <li>It is a key to each certain hypothesis icon in Object Browser
-(see paragraph <a href="#2_4_2_1">2.4.2.1</a>)</li>
-      </ul>
-    </ul>
-  </blockquote>
-  <blockquote>
-    <ul type="circle">
-      <li>value of &lt;label-id&gt; attribute is displayed in the GUI in
-the list of available hypotheses/algorithms ("Create Hypothesis/Algorithm"
-dialog)</li>
-      <li>value of &lt;icon-id&gt; attribute is a name of icon file, which
-is displayed in GUI in the list of available hypotheses/algorithms ("Create
-Hypothesis/Algorithm" dialog)</li>
-    </ul>
-  </blockquote>
-Note: All attributes values are accessible in your GUI via HypothesisData
-class (see paragraph <a href="#2_4_1">2.4.1</a>)<br>
-  <br>
-Note: The environment variable SMESH_MeshersList contains the list of plugins
-names, separated by colon (":") symbol, e.g.:<br>
-  <br>
-  <tt>&nbsp;&nbsp;&nbsp; setenv SMESH_MeshersList StdMeshers:NETGENPlugin</tt><br>
-  <br>
-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.<br>
-  <br>
-The SALOME automatically locates XML files, searching them in the following
-directories:<br>
-  <tt><br>
-&nbsp;&nbsp;&nbsp; ${&lt;PLUGINNAME&gt;_ROOT_DIR}/share/salome/resources/&lt;pluginname&gt;<br>
-&nbsp;&nbsp;&nbsp; ${SALOME_&lt;PluginName&gt;Resources}<br>
-&nbsp;&nbsp;&nbsp; ${HOME}/.salome/resources<br>
-&nbsp;&nbsp;&nbsp; ${KERNEL_ROOT_DIR}/share/salome/resources/kernel</tt><br>
-  <br>
-where &lt;PluginName&gt; is a name of each mesher plugin package<br>
-</blockquote>
-<i><a href="#cont">Back to the contents</a></i> 
-<h3> <a name="2_3"></a>2.3. Build server plugin library &lt;libMyServerLib.so&gt;.</h3>
-  
-<h4> <a name="2_3_1"></a>2.3.1. Define interface to your hypotheses and algorithms.</h4>
-  
-<blockquote><tt>Example: SMESH_SRC/idl/SMESH_BasicHypothesis.idl<br>
-&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NETGENPLUGIN_SRC/src/NETGENPlugin_Algorithm.idl<br>
-  </tt><tt></tt></blockquote>
-  
-<h4> <a name="2_3_2"></a>2.3.2. Implement functionality of your hypotheses
-and algorithms.</h4>
-  
-<blockquote>Inherit corresponding classes from SMESH. 
-  <p><tt>Example: SMESH_SRC/src/StdMeshers/StdMeshers_*<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NETGENPLUGIN_SRC/src/NETGENPlugin_NETGEN_3D<br>
-  </tt><tt></tt></p>
-</blockquote>
-  
-<h4> <a name="2_3_3"></a>2.3.3.Implement interface to your hypotheses and
-algorithms.</h4>
-  
-<blockquote><tt>Inherit corresponding classes from SMESH_I.</tt> 
-  <p><tt>Example: SMESH_SRC/src/StdMeshers_I/SMESH_*_i<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NETGENPLUGIN_SRC/src/NETGENPlugin_NETGEN_3D_i<br>
-  </tt><tt></tt></p>
-</blockquote>
-  
-<h4> <a name="2_3_4"></a>2.3.4. Implement being exported method.</h4>
-  
-<blockquote><tt>GenericHypothesisCreator_i* GetHypothesisCreator (const char*
-aHypType)</tt> 
-  <p>&lt;aHypType&gt; is a value of &lt;type&gt; attribute in the XML-description
-file</p>
-</blockquote>
-  
-<blockquote><tt>Example: SMESH_SRC/src/StdMeshers_I/StdMeshers_i.cxx<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NETGENPLUGIN_SRC/src/NETGENPlugin_i.cxx<br>
-  </tt><tt></tt></blockquote>
- <i><a href="#cont">Back to the contents</a></i> 
-<h3> <a name="2_4"></a>2.4. Build client (GUI) plugin library &lt;libMyClientLib.so&gt;.</h3>
-  
-<blockquote>This step is required only if your hypotheses/algorithms need 
-specific GUI for their construction.</blockquote>
-  
-<h4> <a name="2_4_1"></a>2.4.1. Implement the required GUI (e.g. construction
-dialog boxes).</h4>
-  
-<blockquote><tt>Example: SMESH_SRC/src/StdMeshersGUI/StdMeshersGUI_*Dlg</tt> 
-  <p>Note: all data from XML-description files is accessible in your GUI
-via HypothesisData class&nbsp; (mySMESHGUI-&gt;GetHypothesisData (aHypType),
-see SMESHGUI_Hypotheses.h for HypothesisData definition)</p>
-</blockquote>
-  
-<h4> <a name="2_4_2"></a>2.4.2. Provide icons and messages for your GUI.</h4>
-  
-<h5> <a name="2_4_2_1"></a>2.4.2.1. Implement resource files</h5>
-  
-<blockquote><tt>MyResourceKey_icons.po and MyResourceKey_msg_en.po</tt> 
-  <p><tt>Example: SMESH_SRC/src/StdMeshersGUI/StdMeshers_*.po<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NETGENPLUGIN_SRC/src/NETGENPlugin_icons.po<br>
-  </tt><br>
-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".<br>
-See paragraph 2 for definition of MyResourceKey, MyHypType1, MyAlgType1.<tt><br>
-  </tt></p>
-</blockquote>
-  
-<h5> <a name="2_4_2_2"></a>2.4.2.2. Define environment variable SALOME_&lt;MyResourceKey&gt;Resources</h5>
-<blockquote>It should point to the directory where resources are situated.</blockquote>
-  
-<blockquote><tt>Example: setenv SALOME_StdMeshersResources ${SMESH_ROOT_DIR}/share/salome/resources/smesh</tt></blockquote>
-  
-<h4> <a name="2_4_3"></a>2.4.3. Implement your Hypothesis Creator and being
-exported method</h4>
-  
-<blockquote><tt>SMESHGUI_GenericHypothesisCreator* GetHypothesisCreator</tt> 
-  <br>
-  <tt>&nbsp; (QString aHypType, QString aServerLibName, SMESHGUI* aSMESHGUI)</tt> 
-  <p>&lt;aHypType&gt; is to pass a value of &lt;type&gt; attribute in XML-description
-file;<br>
-&lt;aServerLibName&gt; is to pass a value of &lt;server-lib&gt; attribute
-in XML-description file. </p>
-  <p><tt>Example: SMESH_SRC/src/StdMeshersGUI/StdMeshersGUI.cxx</tt></p>
-</blockquote>
- <i><a href="#cont">Back to the contents</a></i> 
-<h3> <a name="2_5"></a>2.5. Provide icons for object browser.</h3>
-  
-<blockquote>If your hypotheses/algorithms do not need specific GUI, but you
-want to provide icons for object browser, see <a href="#2_4_2">2.4.2</a> paragrath.<br>
-</blockquote>
-<div align="left">
-<p><i><a
- href="file:///home/vsr-local/work/SALOME/SALOME2/SMESH_SRC/doc/salome/tui/SMESH/sources/static/PluginMeshers.html#cont">Back
-to the contents</a></i> </p>
-</div>
-<h3> <a name="2_6"></a>2.6. Setup your SALOME environment.</h3>
-  
-<h4> <a name="2_6_1"></a>2.6.1.&nbsp; Add your plugin to the LD_LIBRARY_PATH,
-PYTHONPATH (and maybe PATH) environment variables.<br>
-</h4>
-<blockquote><tt>setenv PATH &lt;path-to-my-plugin&gt;/bin/salome:${PATH}<br>
-setenv LD_LIBRARY_PATH &lt;path-to-my-plugin&gt;/lib/salome:${LD_LIBRARY_PATH}<br>
-Setenv PYTHONPATH &lt;path-to-my-plugin&gt;/lib/python2.2/site-packages/salome:${PYTHONPATH}<br>
-  </tt>&nbsp;&nbsp; <br>
-</blockquote>
-<h4> <a name="2_6_2"></a>2.6.2.&nbsp; Set mesher plugin resources environment
-variable</h4>
-<blockquote>&nbsp;This enviroment variable is used to set meshers plugins
-which should be loaded by SMESH module (see <a href="#2_4_2_2">2.4.2.2</a>
-paragraph). Add your plugin to this variable. All plugins are separated by
-colon (":") symbol.<br>
-  <br>
-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 &lt;plugin&gt; section to your ${HOME}/.salome/salome.launch
-file for SMESH module section:<br>
-  <tt><br>
-...<br>
-&lt;modules-list&gt;<br>
-&nbsp;&nbsp;&nbsp; ...<br>
-&nbsp;&nbsp;&nbsp; &lt;module name="SMESH"&gt;<br>
-&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;plugin name="MyMesher"/&gt;<br>
-&nbsp;&nbsp;&nbsp; &lt;/module&gt;<br>
-&nbsp;&nbsp;&nbsp; ...<br>
-&lt;/modules-list&gt;<br>
-...</tt><br>
-</blockquote>
-<i><a href="#cont">Back to the contents</a></i> <br>
-&nbsp; <br>
-</body>
-</html>
diff --git a/doc/salome/tui/extra/PluginMeshers.txt b/doc/salome/tui/extra/PluginMeshers.txt
deleted file mode 100644 (file)
index 71e58b2..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-#######################################################################################
-# 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).
-
-   <meshers-group name="MyName"
-                  resources="MyResourceKey"
-                  server-lib="libMyServerLib.so"
-                 gui-lib="libMyClientLib.so">
-     <hypotheses>
-       <hypothesis type="MyHypType1"
-                  label-id="My beautiful hypothesis name"
-                  icon-id="my_hypo_1_icon.png"/>
-     </hypotheses>
-     <algorithms>
-       <algorithm type="MyAlgType1"
-                 label-id="My beautiful algorithm name"
-                 icon-id="my_algo_1_icon.png"/>
-     </algorithms>
-   </meshers-group>
-
-   Attributes of <meshers-group> tag:
-
-        - value of <name> attribute is used to collect hypotheses/algoritms in groups;
-          you can also use this attribute for short description of your mesher plugin
-
-        - value of <resources> 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 <server-lib> attribute describes the name of your mesher's
-          server plugin library (See paragraph 3)
-
-        - value of <gui-lib> attribute describes the name of your mesher's
-          client plugin library (See paragraph 4)
-
-   Attributes of <hypothesis/algorithm> tag:
-
-        - value of <type> 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 <label-id> attribute is displayed in the GUI in the list
-          of available hypotheses/algorithms ("Create Hypothesis/Algorithm" dialog)
-
-        - value of <icon-id> 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:
-
-         ${<PLUGINNAME>_ROOT_DIR}/share/salome/resources/<plugin>
-         ${SALOME_<PluginName>Resources}
-         ${HOME}/.salome/resources
-         ${KERNEL_ROOT_DIR}/share/salome/resources/kernel
-
-        where <PluginName> is a name of each mesher plugin package
-
-3. Build server plugin library <libMyServerLib.so>.
-
-   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)
-
-       <aHypType> is a value of <type> 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 <libMyClientLib.so>.
-   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_<MyResourceKey>Resources to point to the 
-               directory where resources are situated.
-
-               Example: setenv SALOME_StdMeshersResources ${SMESH_ROOT_DIR}/share/salome/resources/smesh
-
-   4.3. Implement your Hypothesis Creator and being exported method
-
-        SMESHGUI_GenericHypothesisCreator* GetHypothesisCreator
-          (QString aHypType, QString aServerLibName, SMESHGUI* aSMESHGUI)
-
-       <aHypType> is to pass a value of <type> attribute in XML-description file;
-       <aServerLibName> is to pass a value of <server-lib> 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 <path-to-my-plugin>/bin/salome:${PATH}
-      setenv LD_LIBRARY_PATH <path-to-my-plugin>/lib/salome:${LD_LIBRARY_PATH}
-      setenv PYTHONPATH <path-to-my-plugin>/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 <plugin> section to your ${HOME}/.salome/salome.launch file for SMESH module section:
-
-      ...
-      <modules-list>
-          ...
-         <module name="SMESH">
-              <plugin name="MyMesher"/>
-          </module>
-          ...
-      </modules-list>
-      ...
diff --git a/doc/salome/tui/images/head.png b/doc/salome/tui/images/head.png
new file mode 100755 (executable)
index 0000000..307d9ef
Binary files /dev/null and b/doc/salome/tui/images/head.png differ
diff --git a/doc/salome/tui/images/smeshscreen.png b/doc/salome/tui/images/smeshscreen.png
new file mode 100755 (executable)
index 0000000..638870e
Binary files /dev/null and b/doc/salome/tui/images/smeshscreen.png differ
diff --git a/doc/salome/tui/input/index.doc b/doc/salome/tui/input/index.doc
new file mode 100644 (file)
index 0000000..d0ef893
--- /dev/null
@@ -0,0 +1,13 @@
+/*! \mainpage
+
+\image html smeshscreen.png
+
+To browse the \b SALOME Mesh module Developer Documentation, follow the links below or use navigation menu at the top of the page:
+<ul>
+<li> <a href="modules.html">Modules</a> - documentation of TUI functionality.</li>
+<li> <a href="namespaces.html">Name Spaces</a> - list of TUI packages and scripts.</li>
+<li> <a href="annotated.html">Data Structures</a> - list of all data structures and classes with brief descriptions.</li>
+<li> <a href="files.html">Files</a> - list of all files with brief descriptions.</li>
+</ul>
+
+*/
\ No newline at end of file
index 389449d8746fde543d6fea6e87c8bd6955370b38..7a2dcbde8e1abe74a42ba5554635bdfa6473a572 100755 (executable)
-H1 { 
-   text-align: center; 
+/* The standard CSS for doxygen */
+
+body, table, div, p, dl {
+       font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif;
+       font-size: 12px;
+}
+
+/* @group Heading Levels */
+
+h1 {
+       font-size: 150%;
+}
+
+h2 {
+       font-size: 120%;
+}
+
+h3 {
+       font-size: 100%;
 }
 
-CAPTION { 
-   font-weight: bold 
+dt {
+       font-weight: bold;
 }
 
-/* Link in the top navbar */
-A.qindex {}
+div.multicol {
+       -moz-column-gap: 1em;
+       -webkit-column-gap: 1em;
+       -moz-column-count: 3;
+       -webkit-column-count: 3;
+}
+
+p.startli, p.startdd, p.starttd {
+       margin-top: 2px;
+}
+
+p.endli {
+       margin-bottom: 0px;
+}
 
-A.qindexRef {}
+p.enddd {
+       margin-bottom: 4px;
+}
 
-/* Link to any cross-referenced Doxygen element */
-A.el { 
-   text-decoration: none; 
-   font-weight: bold 
+p.endtd {
+       margin-bottom: 2px;
 }
 
-A.elRef { 
-   font-weight: bold 
+/* @end */
+
+caption {
+       font-weight: bold;
 }
 
-/* Link to any cross-referenced Doxygen element inside a code section 
-   (ex: header)
+span.legend {
+        font-size: 70%;
+        text-align: center;
+}
+
+h3.version {
+        font-size: 90%;
+        text-align: center;
+}
+
+div.qindex, div.navtab{
+       background-color: #EBEFF6;
+       border: 1px solid #A3B4D7;
+       text-align: center;
+       margin: 2px;
+       padding: 2px;
+}
+
+div.qindex, div.navpath {
+       width: 100%;
+       line-height: 140%;
+}
+
+div.navtab {
+       margin-right: 15px;
+}
+
+/* @group Link Styling */
+
+a {
+       color: #3D578C;
+       font-weight: normal;
+       text-decoration: none;
+}
+
+.contents a:visited {
+       color: #4665A2;
+}
+
+a:hover {
+       text-decoration: underline;
+}
+
+a.qindex {
+       font-weight: bold;
+}
+
+a.qindexHL {
+       font-weight: bold;
+       background-color: #9CAFD4;
+       color: #ffffff;
+       border: 1px double #869DCA;
+}
+
+.contents a.qindexHL:visited {
+        color: #ffffff;
+}
+
+a.el {
+       font-weight: bold;
+}
+
+a.elRef {
+}
+
+a.code {
+       color: #4665A2;
+}
+
+a.codeRef {
+       color: #4665A2;
+}
+
+/* @end */
+
+dl.el {
+       margin-left: -1cm;
+}
+
+.fragment {
+       font-family: monospace, fixed;
+       font-size: 105%;
+}
+
+pre.fragment {
+       border: 1px solid #C4CFE5;
+       background-color: #FBFCFD;
+       padding: 4px 6px;
+       margin: 4px 8px 4px 2px;
+       overflow: auto;
+       word-wrap: break-word;
+       font-size:  9pt;
+       line-height: 125%;
+}
+
+div.ah {
+       background-color: black;
+       font-weight: bold;
+       color: #ffffff;
+       margin-bottom: 3px;
+       margin-top: 3px;
+       padding: 0.2em;
+       border: solid thin #333;
+       border-radius: 0.5em;
+       -webkit-border-radius: .5em;
+       -moz-border-radius: .5em;
+       box-shadow: 2px 2px 3px #999;
+       -webkit-box-shadow: 2px 2px 3px #999;
+       -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
+       background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444));
+       background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000);
+}
+
+div.groupHeader {
+       margin-left: 16px;
+       margin-top: 12px;
+       font-weight: bold;
+}
+
+div.version {
+       border:1px solid #0000FF;
+        color: #CCCCCC;
+       font-family: Arial, Helvetica, sans-serif;
+       font-size: 9pt;
+       text-align: center;
+       width:100px;
+       -moz-border-radius: 8px;
+       margin: 5px;
+}
+                    
+div.footer1 {
+    background-color: #DFE5F1;
+    border: 1px solid #AAAAAA;
+    font-family: Arial, Helvetica, sans-serif;
+    font-size: 11px;
+    padding: 10px;
+    margin-top: 15px;
+}
+           
+
+div.groupText {
+       margin-left: 16px;
+       font-style: italic;
+}
+
+body {
+       background: white;
+       color: black;
+        margin: 0;
+}
+
+div.contents {
+       margin-top: 10px;
+       margin-left: 10px;
+       margin-right: 10px;
+}
+
+td.indexkey {
+       background-color: #EBEFF6;
+       font-weight: bold;
+       border: 1px solid #C4CFE5;
+       margin: 2px 0px 2px 0;
+       padding: 2px 10px;
+}
+
+td.indexvalue {
+       background-color: #EBEFF6;
+       border: 1px solid #C4CFE5;
+       padding: 2px 10px;
+       margin: 2px 0px;
+}
+
+tr.memlist {
+       background-color: #EEF1F7;
+}
+
+p.formulaDsp {
+       text-align: center;
+}
+
+img.formulaDsp {
+       
+}
+
+img.formulaInl {
+       vertical-align: middle;
+}
+
+div.center {
+       text-align: center;
+        margin-top: 0px;
+        margin-bottom: 0px;
+        padding: 0px;
+}
+
+div.center img {
+       border: 0px;
+}
+
+address.footer {
+       text-align: right;
+       padding-right: 12px;
+}
+
+img.footer {
+       border: 0px;
+       vertical-align: middle;
+}
+
+/* @group Code Colorization */
+
+span.keyword {
+       color: #008000
+}
+
+span.keywordtype {
+       color: #604020
+}
+
+span.keywordflow {
+       color: #e08000
+}
+
+span.comment {
+       color: #800000
+}
+
+span.preprocessor {
+       color: #806020
+}
+
+span.stringliteral {
+       color: #002080
+}
+
+span.charliteral {
+       color: #008080
+}
+
+span.vhdldigit { 
+       color: #ff00ff 
+}
+
+span.vhdlchar { 
+       color: #000000 
+}
+
+span.vhdlkeyword { 
+       color: #700070 
+}
+
+span.vhdllogic { 
+       color: #ff0000 
+}
+
+/* @end */
+
+/*
+.search {
+       color: #003399;
+       font-weight: bold;
+}
+
+form.search {
+       margin-bottom: 0px;
+       margin-top: 0px;
+}
+
+input.search {
+       font-size: 75%;
+       color: #000080;
+       font-weight: normal;
+       background-color: #e8eef2;
+}
 */
-A.code { 
-   text-decoration: none; 
-   font-weight: normal; 
-   color: #4444ee 
+
+td.tiny {
+       font-size: 75%;
 }
 
-A.codeRef { 
-   font-weight: normal; 
-   color: #4444ee 
+.dirtab {
+       padding: 4px;
+       border-collapse: collapse;
+       border: 1px solid #A3B4D7;
 }
 
-A:hover { 
-   text-decoration: none; 
-   background-color: lightblue 
+th.dirtab {
+       background: #EBEFF6;
+       font-weight: bold;
 }
 
-DL.el { 
-   margin-left: -1cm 
+hr {
+       height: 0px;
+       border: none;
+       border-top: 1px solid #4A6AAA;
 }
 
-/* A code fragment (ex: header) */
-DIV.fragment { 
-   width: 100%; 
-   border: none; 
-   background-color: #CCCCCC 
+hr.footer {
+       height: 1px;
 }
 
-/* In the alpha list (coumpound index), style of an alphabetical index letter */
-DIV.ah { 
-   background-color: #CCCCCC; 
-   font-weight: bold; 
-   color: #ffffff; 
-   margin-bottom: 3px; 
-   margin-top: 3px 
+/* @group Member Descriptions */
+
+table.memberdecls {
+       border-spacing: 0px;
+       padding: 0px;
 }
 
-/* Method name (+ type) */
-TD.md { 
-   background-color: lightblue; 
-   font-weight: bold; 
+.mdescLeft, .mdescRight,
+.memItemLeft, .memItemRight,
+.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
+       background-color: #F9FAFC;
+       border: none;
+       margin: 4px;
+       padding: 1px 0 0 8px;
 }
 
-/* Method parameter (some of them) */
-TD.mdname1 { 
-   background-color: lightblue; 
-   font-weight: bold; color: #602020; 
+.mdescLeft, .mdescRight {
+       padding: 0px 8px 4px 8px;
+       color: #555;
 }
 
-/* Method parameter (some of them) */
-TD.mdname { 
-   background-color: lightblue; 
-   font-weight: bold; 
-   color: #602020; 
-   width: 600px; 
+.memItemLeft, .memItemRight, .memTemplParams {
+       border-top: 1px solid #C4CFE5;
 }
 
-/* Separator between methods group (usually empty, seems not supported by IE) */
-DIV.groupHeader { 
-   margin-left: 16px; 
-   margin-top: 12px; 
-   margin-bottom: 6px; 
-   font-weight: bold 
+.memItemLeft, .memTemplItemLeft {
+        white-space: nowrap;
 }
 
-DIV.groupText { 
-   margin-left: 16px; 
-   font-style: italic; 
-   font-size: smaller 
+.memTemplParams {
+       color: #4665A2;
+        white-space: nowrap;
 }
 
-BODY { 
-   background: #FFFFFF;
+/* @end */
+
+/* @group Member Details */
+
+/* Styles for detailed member documentation */
+
+.memtemplate {
+       font-size: 80%;
+       color: #4665A2;
+       font-weight: normal;
+       margin-left: 9px;
 }
 
-/*div.div-page { 
-  background-color: #FFFFFF; 
-  margin-left: 1em;
-  margin-right: 1em;
-  margin-top: 1em;
-  margin-bottom: 0.1em;
+.memnav {
+       background-color: #EBEFF6;
+       border: 1px solid #A3B4D7;
+       text-align: center;
+       margin: 2px;
+       margin-right: 15px;
+       padding: 2px;
+}
 
-  padding-left: 1em;
-  padding-right: 1em;
-  padding-top: 0.5em;
-  padding-bottom: 0.5em;
+.memitem {
+       padding: 0;
+       margin-bottom: 10px;
+}
+
+.memname {
+        white-space: nowrap;
+        font-weight: bold;
+        margin-left: 6px;
+}
+
+.memproto {
+        border-top: 1px solid #A8B8D9;
+        border-left: 1px solid #A8B8D9;
+        border-right: 1px solid #A8B8D9;
+        padding: 6px 0px 6px 0px;
+        color: #253555;
+        font-weight: bold;
+        text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+        /* opera specific markup */
+        box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+        border-top-right-radius: 8px;
+        border-top-left-radius: 8px;
+        /* firefox specific markup */
+        -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+        -moz-border-radius-topright: 8px;
+        -moz-border-radius-topleft: 8px;
+        /* webkit specific markup */
+        -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+        -webkit-border-top-right-radius: 8px;
+        -webkit-border-top-left-radius: 8px;
+        background-image:url('nav_f.png');
+        background-repeat:repeat-x;
+        background-color: #E2E8F2;
+
+}
+
+.memdoc {
+        border-bottom: 1px solid #A8B8D9;      
+        border-left: 1px solid #A8B8D9;      
+        border-right: 1px solid #A8B8D9; 
+        padding: 2px 5px;
+        background-color: #FBFCFD;
+        border-top-width: 0;
+        /* opera specific markup */
+        border-bottom-left-radius: 8px;
+        border-bottom-right-radius: 8px;
+        box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+        /* firefox specific markup */
+        -moz-border-radius-bottomleft: 8px;
+        -moz-border-radius-bottomright: 8px;
+        -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+        background-image: -moz-linear-gradient(center top, #FFFFFF 0%, #FFFFFF 60%, #F7F8FB 95%, #EEF1F7);
+        /* webkit specific markup */
+        -webkit-border-bottom-left-radius: 8px;
+        -webkit-border-bottom-right-radius: 8px;
+        -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+        background-image: -webkit-gradient(linear,center top,center bottom,from(#FFFFFF), color-stop(0.6,#FFFFFF), color-stop(0.60,#FFFFFF), color-stop(0.95,#F7F8FB), to(#EEF1F7));
+}
+
+.paramkey {
+       text-align: right;
+}
+
+.paramtype {
+       white-space: nowrap;
+}
+
+.paramname {
+       color: #602020;
+       white-space: nowrap;
+}
+.paramname em {
+       font-style: normal;
+}
+
+.params, .retval, .exception, .tparams {
+        border-spacing: 6px 2px;
+}       
+
+.params .paramname, .retval .paramname {
+        font-weight: bold;
+        vertical-align: top;
+}
+        
+.params .paramtype {
+        font-style: italic;
+        vertical-align: top;
+}       
+        
+.params .paramdir {
+        font-family: "courier new",courier,monospace;
+        vertical-align: top;
+}
+
+
+
+
+/* @end */
+
+/* @group Directory (tree) */
+
+/* for the tree view */
+
+.ftvtree {
+       font-family: sans-serif;
+       margin: 0px;
+}
+
+/* these are for tree view when used as main index */
+
+.directory {
+       font-size: 9pt;
+       font-weight: bold;
+       margin: 5px;
+}
+
+.directory h3 {
+       margin: 0px;
+       margin-top: 1em;
+       font-size: 11pt;
+}
+
+/*
+The following two styles can be used to replace the root node title
+with an image of your choice.  Simply uncomment the next two styles,
+specify the name of your image and be sure to set 'height' to the
+proper pixel height of your image.
+*/
+
+/*
+.directory h3.swap {
+       height: 61px;
+       background-repeat: no-repeat;
+       background-image: url("yourimage.gif");
+}
+.directory h3.swap span {
+       display: none;
+}
+*/
+
+.directory > h3 {
+       margin-top: 0;
+}
+
+.directory p {
+       margin: 0px;
+       white-space: nowrap;
+}
+
+.directory div {
+       display: none;
+       margin: 0px;
+}
+
+.directory img {
+       vertical-align: -30%;
+}
+
+/* these are for tree view when not used as main index */
+
+.directory-alt {
+       font-size: 100%;
+       font-weight: bold;
+}
+
+.directory-alt h3 {
+       margin: 0px;
+       margin-top: 1em;
+       font-size: 11pt;
+}
+
+.directory-alt > h3 {
+       margin-top: 0;
+}
+
+.directory-alt p {
+       margin: 0px;
+       white-space: nowrap;
+}
+
+.directory-alt div {
+       display: none;
+       margin: 0px;
+}
+
+.directory-alt img {
+       vertical-align: -30%;
+}
+
+/* @end */
 
-  border: 2px solid #0D299A; 
-  border-width: 2px;
-  border-color: #0D299A; 
-}*/
+div.dynheader {
+        margin-top: 8px;
+}
+
+address {
+       font-style: normal;
+       color: #2A3D61;
+}
+
+table.doxtable {
+       border-collapse:collapse;
+}
+
+table.doxtable td, table.doxtable th {
+       border: 1px solid #2D4068;
+       padding: 3px 7px 2px;
+}
+
+table.doxtable th {
+       background-color: #374F7F;
+       color: #FFFFFF;
+       font-size: 110%;
+       padding-bottom: 4px;
+       padding-top: 5px;
+       text-align:left;
+}
+
+.tabsearch {
+       top: 0px;
+       left: 10px;
+       height: 36px;
+       background-image: url('tab_b.png');
+       z-index: 101;
+       overflow: hidden;
+       font-size: 13px;
+}
+
+.navpath ul
+{
+       font-size: 11px;
+       background-image:url('tab_b.png');
+       background-repeat:repeat-x;
+       height:30px;
+       line-height:30px;
+       color:#8AA0CC;
+       border:solid 1px #C2CDE4;
+       overflow:hidden;
+       margin:0px;
+       padding:0px;
+}
+
+.navpath li
+{
+       list-style-type:none;
+       float:left;
+       padding-left:10px;
+       padding-right:15px;
+       background-image:url('bc_s.png');
+       background-repeat:no-repeat;
+       background-position:right;
+       color:#364D7C;
+}
+
+.navpath li.navelem a
+{
+       height:32px;
+       display:block;
+       text-decoration: none;
+       outline: none;
+}
+
+.navpath li.navelem a:hover
+{
+       color:#6884BD;
+}
+
+.navpath li.footer
+{
+        list-style-type:none;
+        float:right;
+        padding-left:10px;
+        padding-right:15px;
+        background-image:none;
+        background-repeat:no-repeat;
+        background-position:right;
+        color:#364D7C;
+        font-size: 8pt;
+}
+
+
+div.summary
+{
+       float: right;
+       font-size: 8pt;
+       padding-right: 5px;
+       width: 50%;
+       text-align: right;
+}       
+
+div.summary a
+{
+       white-space: nowrap;
+}
+
+div.ingroups
+{
+       font-size: 8pt;
+       padding-left: 5px;
+       width: 50%;
+       text-align: left;
+}
+
+div.ingroups a
+{
+       white-space: nowrap;
+}
+
+div.header
+{
+        background-image:url('nav_h.png');
+        background-repeat:repeat-x;
+       background-color: #F9FAFC;
+       margin:  0px;
+       border-bottom: 1px solid #C4CFE5;
+}
+
+div.headertitle
+{
+       padding: 5px 5px 5px 10px;
+}
+
+.title {
+        font-size: 150%;
+        font-weight: bold;
+        margin: 10px 2px;
+}
+
+dl
+{
+        padding: 0 0 0 10px;
+}
+
+dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug
+{
+        border-left:4px solid;
+        padding: 0 0 0 6px;
+}
+
+dl.note
+{
+        border-color: #D0D000;
+}
+
+dl.warning, dl.attention
+{
+        border-color: #FF0000;
+}
+
+dl.pre, dl.post, dl.invariant
+{
+        border-color: #00D000;
+}
+
+dl.deprecated
+{
+        border-color: #505050;
+}
+
+dl.todo
+{
+        border-color: #00C0E0;
+}
+
+dl.test
+{
+        border-color: #3030E0;
+}
+
+dl.bug
+{
+        border-color: #C08050;
+}
+
+#projectlogo
+{
+       text-align: center;
+       vertical-align: bottom;
+       border-collapse: separate;
+}
+#projectlogo img
+{ 
+       border: 0px none;
+}
+#projectname
+{
+        background-color: #175783;
+        border: 1px solid;
+        height: 80px;
+       background-repeat: no-repeat;
+/*     font: 300% arial,sans-serif;*/
+       margin: 0px;
+       padding: 0px;
+}
+    
+#projectbrief
+{
+       font: 120% arial,sans-serif;
+       margin: 0px;
+       padding: 0px;
+}
+
+#projectnumber
+{
+       font: 50% arial,sans-serif;
+       margin: 0px;
+       padding: 0px;
+}
 
-DIV.div-footer { 
-  margin-left: 1em;
-  margin-right: 1em;
-  margin-bottom: 0.2em;
-  text-align: right;
-  font-size: 9pt; 
+#titlearea
+{
+        background: url("head.png");
+        background-color: #175783;
+        border: 1px solid;
+        height: 80px;
+        background-repeat: no-repeat;
+       padding: 0px;
+       margin: 0px;
+       width: 100%;
+       border-bottom: 1px solid #5373B4;
 }
 
-/* In File List, Coumpound List, etc, 1st column of the index */
-TD.indexkey { 
-   background-color: #CCCCCC; 
-   font-weight: bold; 
-   padding-right  : 10px; 
-   padding-top    : 2px; 
-   padding-left   : 10px; 
-   padding-bottom : 2px; 
-   margin-left    : 0px; 
-   margin-right   : 0px; 
-   margin-top     : 2px; 
-   margin-bottom  : 2px  
-}
-
-/* In File List, Coumpound List, etc, 2nd column of the index */
-TD.indexvalue { 
-   background-color: #CCCCCC; 
-   font-style: italic; 
-   padding-right  : 10px; 
-   padding-top    : 2px; 
-   padding-left   : 10px; 
-   padding-bottom : 2px; 
-   margin-left    : 0px; 
-   margin-right   : 0px; 
-   margin-top     : 2px; 
-   margin-bottom  : 2px  
-}
-
-span.keyword       { color: #008000 }
-span.keywordtype   { color: #604020 }
-span.keywordflow   { color: #e08000 }
-span.comment       { color: #800000 }
-span.preprocessor  { color: #806020 }
-span.stringliteral { color: #002080 }
-span.charliteral   { color: #008080 }
index cb55f397acf510370ed145be8d3c5d7cb09d4f43..5b030c0214278fc821e3965b3c7d23de85f9c743 100755 (executable)
@@ -1,5 +1,14 @@
-</DIV>
-<DIV class="div-footer">
-Generated on $datetime for $projectname by&nbsp;<A href="http://www.doxygen.org/index.html"><img src="doxygen.png" alt="doxygen" align="middle" border="0"></A> $doxygenversion</DIV>
-</BODY>
-</HTML>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+</head>
+<body>
+<div class="footer1">
+<!--hr style="width: 100%; height: 2px;"-->
+<div style="text-align: center;">
+Copyright &copy; 2007-2012  CEA/DEN, EDF R&amp;D, OPEN CASCADE<br>
+Copyright &copy; 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&amp;D, LEG, PRINCIPIA R&amp;D, BUREAU VERITAS<br>
+</div>
+</div>
+</body>
+</html>
diff --git a/doc/salome/tui/static/header.html.in b/doc/salome/tui/static/header.html.in
new file mode 100755 (executable)
index 0000000..4571b43
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<title>$title</title>
+<link href="$relpath$tabs.css" rel="stylesheet" type="text/css"/>
+$treeview
+$search
+$mathjax
+<script type="text/javascript">
+$(document).ready(initResizable);
+</script>
+<link href="$relpath$doxygen.css" rel="stylesheet" type="text/css"/>
+</head>
+<body onload='searchBox.OnSelectItem(0);'>
+<div id="top"><!-- do not remove this div! -->
+<div id="titlearea"><div align="right"><div class="version">Version: @VERSION@</div></div></div>
+
+</div>
diff --git a/doc/salome/tui/static/myheader.html b/doc/salome/tui/static/myheader.html
deleted file mode 100755 (executable)
index d2efb75..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-   <meta name="GENERATOR" content="Mozilla/4.73 [en] (WinNT; I) [Netscape]">
-   <title>Main Page</title>
-<link href="doxygen.css" rel="stylesheet" type="text/css">
-<link href="tabs.css" rel="stylesheet" type="text/css">
-</head>
-<body>
-&nbsp;
-</body>
-</html>
index a1d468cb5e0d95ea24c0c9b72250a3369086edbe..c43e554d320152261567f789ab048e7e5656cad0 100644 (file)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # This Makefile is responsible of generating the client and server
 # implementation of IDL interfaces for both C++ and python usage.
 # The building process of the C++ files is in charge of each source
@@ -34,7 +32,10 @@ BASEIDL_FILES = \
        SMESH_Filter.idl \
        SMESH_Group.idl \
        SMESH_Pattern.idl \
-       SMESH_MeshEditor.idl
+       SMESH_MeshEditor.idl \
+       SMESH_Measurements.idl
+
+BASEIDL_FILES_PY=$(BASEIDL_FILES:%.idl=%_idl.py)
 
 # This variable defines the files to be installed
 dist_salomeidl_DATA = $(BASEIDL_FILES)
@@ -51,13 +52,16 @@ nodist_libSalomeIDLSMESH_la_SOURCES = \
        SMESH_FilterSK.cc \
        SMESH_GroupSK.cc \
        SMESH_PatternSK.cc \
-       SMESH_MeshEditorSK.cc
+       SMESH_MeshEditorSK.cc \
+       SMESH_MeasurementsSK.cc
+
+# to be done at first, to avoid parallel compilation problems
+BUILT_SOURCES = $(nodist_libSalomeIDLSMESH_la_SOURCES)
 
 # header files must be exported: other modules have to use this library
 nodist_salomeinclude_HEADERS = $(BASEIDL_FILES:%.idl=%.hh)
 
 libSalomeIDLSMESH_la_CPPFLAGS =                        \
-       -I$(top_builddir)/salome_adm/unix       \
        -I$(top_builddir)/idl                   \
        $(CORBA_CXXFLAGS) $(CORBA_INCLUDES)     \
        $(KERNEL_CXXFLAGS) $(MED_CXXFLAGS)      \
@@ -85,8 +89,7 @@ IDLCXXFLAGS = \
        -I$(top_builddir)/idl/salome \
        -I$(KERNEL_ROOT_DIR)/idl/salome \
        -I$(MED_ROOT_DIR)/idl/salome \
-       -I$(GEOM_ROOT_DIR)/idl/salome \
-       -I$(top_builddir)/salome_adm/unix
+       -I$(GEOM_ROOT_DIR)/idl/salome
 
 IDLPYFLAGS  = \
        @IDLPYFLAGS@ \
@@ -107,9 +110,15 @@ install-exec-local: $(BASEIDL_FILES:%=$(top_srcdir)/idl/%)
          $(OMNIORB_IDL) $(IDLPYFLAGS) -C$(DESTDIR)$(salomepythondir) $$file ; \
        done
 
-# uninstall-local removes too much, but it works in distcheck
+# we want to remove only staff generated for IDL files and nothing more
 uninstall-local:
-       rm -rf $(DESTDIR)$(salomepythondir)/*
+       @for modulen in SMESH StdMeshers ; do \
+         test -d $(DESTDIR)$(salomepythondir)/$${modulen} && echo "Removing $(DESTDIR)$(salomepythondir)/$${modulen}" && rm -rf $(DESTDIR)$(salomepythondir)/$${modulen} ; \
+         test -d $(DESTDIR)$(salomepythondir)/$${modulen}__POA && echo "Removing $(DESTDIR)$(salomepythondir)/$${modulen}__POA" && rm -rf $(DESTDIR)$(salomepythondir)/$${modulen}__POA ; \
+       done ; \
+       for filen in $(BASEIDL_FILES_PY) ; do \
+         echo "Removing $(DESTDIR)$(salomepythondir)/$${filen}" && rm -f $(DESTDIR)$(salomepythondir)/$${filen}* ; \
+       done
 
 mostlyclean-local:
        -rm -f *.hh *.cc .depidl
index 9c428ba145934922c7e2515b42cd2846d847fbb8..5ec9ebbf0273e389a3dc267098a03f6c1f67ff35 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  File   : SMESH_BasicHypothesis.idl
 //  Author : Paul RASCLE, EDF
 //
@@ -29,7 +30,6 @@
 #include "SMESH_Hypothesis.idl"
 #include "SMESH_Mesh.idl"
 
-
 /*!
  * StdMeshers: interfaces to standard hypotheses and algorithms
  */
@@ -209,6 +209,26 @@ module StdMeshers
      */
     long ConversionMode()
       raises (SALOME::SALOME_Exception);
+
+    /*!
+     * Set list of edges to reverse
+     */
+    void SetReversedEdges( in SMESH::long_array list );
+    
+    /*!
+     * Returns list of edges to reverse
+     */
+    SMESH::long_array GetReversedEdges();
+    
+    /*!
+     * Set entry of the main object
+     */
+    void SetObjectEntry( in string entry );
+    
+    /*!
+     * Get the entry of the main object
+     */
+    string GetObjectEntry();
   };
 
   /*!
@@ -218,14 +238,48 @@ module StdMeshers
   {
     /*!
      * Sets <start segment length> or <end segment length> parameter value
+     * * OBSOLETE *. Avoid such a way of interface design
+     * * It is recommended to dedicate a method to each parameter.
      */
     void SetLength(in double length, in boolean isStartLength) 
       raises (SALOME::SALOME_Exception);
 
+    /*!
+     * Sets <start segment length> parameter value
+     */
+    void SetStartLength(in double length) 
+      raises (SALOME::SALOME_Exception);
+
+    /*!
+     * Sets <end segment length> parameter value
+     */
+    void SetEndLength(in double length)
+      raises (SALOME::SALOME_Exception);
+
     /*!
      * Returns <start segment length> or <end segment length> parameter value
      */
     double GetLength(in boolean isStartLength);
+    
+    /*!
+     * Set list of edges to reverse
+     */
+    void SetReversedEdges( in SMESH::long_array list );
+    
+    /*!
+     * Returns list of edges to reverse
+     */
+    SMESH::long_array GetReversedEdges();
+    
+    /*!
+     * Set entry of the main object
+     */
+    void SetObjectEntry( in string entry );
+    
+    /*!
+     * Get the entry of the main object
+     */
+    string GetObjectEntry();
   };
 
   /*!
@@ -269,14 +323,48 @@ module StdMeshers
   {
     /*!
      * Sets <start segment length> or <end segment length> parameter value
+     * * OBSOLETE *. Avoid such a way of interface design.
+     * * It is recommended to dedicate a method to each parameter.
      */
     void SetLength(in double length, in boolean isStartLength) 
       raises (SALOME::SALOME_Exception);
 
+    /*!
+     * Sets <start segment length> parameter value
+     */
+    void SetStartLength(in double length) 
+      raises (SALOME::SALOME_Exception);
+
+    /*!
+     * Sets <end segment length> parameter value
+     */
+    void SetEndLength(in double length)
+      raises (SALOME::SALOME_Exception);
+
     /*!
      * Returns <start segment length> or <end segment length> parameter value
      */
     double GetLength(in boolean isStartLength);
+
+    /*!
+     * Set list of edges to reverse
+     */
+    void SetReversedEdges( in SMESH::long_array list );
+    
+    /*!
+     * Returns list of edges to reverse
+     */
+    SMESH::long_array GetReversedEdges();
+    
+    /*!
+     * Set entry of the main object
+     */
+    void SetObjectEntry( in string entry );
+    
+    /*!
+     * Get the entry of the main object
+     */
+    string GetObjectEntry();
   };
 
 
@@ -298,6 +386,54 @@ module StdMeshers
   };
 
 
+  /*!
+   * StdMeshers_FixedPoints1D: interface of "Fixed points 1D" hypothesis
+   */
+  interface StdMeshers_FixedPoints1D : SMESH::SMESH_Hypothesis
+  {
+    /*!
+     * Sets some points on edge using parameter on curve from 0 to 1
+     * (additionally it is neecessary to check orientation of edges and
+     * create list of reversed edges if it is needed) and sets numbers
+     * of segments between given points (default values are equals 1)
+     */
+    void SetPoints(in SMESH::double_array listParams) 
+      raises (SALOME::SALOME_Exception);
+    void SetNbSegments(in SMESH::long_array listNbSeg) 
+      raises (SALOME::SALOME_Exception);
+
+    /*!
+     * Returns list of point's parameters
+     */
+    SMESH::double_array GetPoints();
+    
+    /*!
+     * Returns list of numbers of segments
+     */
+    SMESH::long_array GetNbSegments();
+    
+    /*!
+     * Set list of edges to reverse
+     */
+    void SetReversedEdges( in SMESH::long_array list );
+    
+    /*!
+     * Returns list of edges to reverse
+     */
+    SMESH::long_array GetReversedEdges();
+    
+    /*!
+     * Set entry of the main object
+     */
+    void SetObjectEntry( in string entry );
+    
+    /*!
+     * Get the entry of the main object
+     */
+    string GetObjectEntry();
+  };
+
+
   /*!
    * StdMeshers_MaxElementVolume: interface of "Max. Hexahedron or Tetrahedron Volume" hypothesis
    */
@@ -344,16 +480,6 @@ module StdMeshers
   {
   };
 
-  /*!
-   * StdMeshers_TrianglePreference: interface of "TrianglePreference" hypothesis.
-   * This hypothesis is used by StdMeshers_Quadrangle_2D algorithm.
-   * Presence of this hypothesis forces construction of triangles in the refinement 
-   * area if the number of nodes on opposite edges is not the same.
-   */
-  interface StdMeshers_TrianglePreference : SMESH::SMESH_Hypothesis
-  {
-  };
-
   /*!
    * StdMeshers_QuadraticMesh: interface of "QuadraticMesh" hypothesis.
    * This is an auxiliary 1D hypothesis whose presence forces construction 
@@ -411,6 +537,26 @@ module StdMeshers
 
   };
 
+  /*!
+   * StdMeshers_NumberOfLayers2D: interface of "Nb. Layers" hypothesis.
+   * This hypothesis is used by "Radial quadrangle" algorithm.
+   * It specifies number of segments between the internal 
+   * and the external surfaces.
+   */
+  interface StdMeshers_NumberOfLayers2D : StdMeshers_NumberOfLayers
+  {
+  };
+
+  /*!
+   * StdMeshers_LayerDistribution2D: interface of "Distribution of Layers" hypothesis.
+   * This hypothesis is used by "Radial quadrangle" algorithm.
+   * It specifies 1D hypothesis defining distribution of segments between the internal 
+   * and the external surfaces.
+   */
+  interface StdMeshers_LayerDistribution2D : StdMeshers_LayerDistribution
+  {
+  };
+
   /*!
    * interface of "ProjectionSource1D" hypothesis.
    * This hypothesis specifies a meshed edge to take a mesh pattern from
@@ -594,6 +740,189 @@ module StdMeshers
     double GetLength();
   };
 
+  /*!
+   * StdMeshers_QuadrangleParams: interface of "Quadrangle Params" hypothesis
+   */
+  enum QuadType
+  {
+    QUAD_STANDARD,
+    QUAD_TRIANGLE_PREF,
+    QUAD_QUADRANGLE_PREF,
+    QUAD_QUADRANGLE_PREF_REVERSED,
+    QUAD_REDUCED,
+    QUAD_NB_TYPES /* this is not a type of quadrangulation */
+  };
+
+  interface StdMeshers_QuadrangleParams : SMESH::SMESH_Hypothesis
+  {
+    /*!
+     * Set base vertex for triangles
+     */
+    void SetTriaVertex( in long vertID );
+    
+    /*!
+     * Returns base vertex for triangles
+     */
+    long GetTriaVertex();
+    
+    /*!
+     * Set entry of the main object
+     */
+    void SetObjectEntry( in string entry );
+    
+    /*!
+     * Get the entry of the main object
+     */
+    string GetObjectEntry();
+    
+    /*!
+     * Set the type of quadrangulation
+     */
+    void SetQuadType( in QuadType type );
+
+    /*!
+     * Get the type of quadrangulation
+     */
+    QuadType GetQuadType();
+  };
+
+  /*!
+   * interface of "Source edges" hypothesis.
+   * This hypothesis specifies groups of edges of other mesh to be imported
+   * in this mesh
+   */
+  interface StdMeshers_ImportSource1D : SMESH::SMESH_Hypothesis
+  {
+    /*!
+     * Set edges to import from other mesh
+     */
+    void SetSourceEdges(in SMESH::ListOfGroups groups);
+    SMESH::string_array GetSourceEdges();
+
+    /*!
+     * Set to import the whole other mesh or not, and if yes, to
+     * copy groups of not. By default the mesh is not copied.
+     */
+    void SetCopySourceMesh(in boolean toCopyMesh, in boolean toCopyGroups);
+    void GetCopySourceMesh(out boolean toCopyMesh,out boolean toCopyGroups);
+  };
+
+  /*!
+   * interface of "Source faces" hypothesis.
+   * This hypothesis specifies groups of faces of other mesh to be imported
+   * in this mesh
+   */
+  interface StdMeshers_ImportSource2D : SMESH::SMESH_Hypothesis
+  {
+    /*!
+     * Set faces to import from other mesh
+     */
+    void SetSourceFaces(in SMESH::ListOfGroups groups);
+    SMESH::string_array GetSourceFaces();
+
+    /*!
+     * Set to import the whole other mesh or not, and if yes, to
+     * copy groups of not. By default the mesh is not copied.
+     */
+    void SetCopySourceMesh(in boolean toCopyMesh,in boolean toCopyGroups);
+    void GetCopySourceMesh(out boolean toCopyMesh,out boolean toCopyGroups);
+  };
+
+  /*!
+   * interface of "Viscous Layers" hypothesis.
+   * This hypothesis specifies parameters of layers of prisms to build
+   * near mesh boundary. This hypothesis can be used by several 3D algorithms:
+   * NETGEN 3D, GHS3D, Hexahedron(i,j,k)
+   */
+  interface StdMeshers_ViscousLayers : SMESH::SMESH_Hypothesis
+  {
+    /*!
+     * Set faces to exclude from treatment
+     */
+    void SetIgnoreFaces(in SMESH::long_array faceIDs) raises (SALOME::SALOME_Exception);
+    SMESH::long_array GetIgnoreFaces();
+
+    /*!
+     * Set total thickness of layers of prisms
+     */
+    void SetTotalThickness(in double thickness) raises (SALOME::SALOME_Exception);
+    double GetTotalThickness();
+
+    /*!
+     * Set number of layers of prisms
+     */
+    void SetNumberLayers(in short nb) raises (SALOME::SALOME_Exception);
+    short GetNumberLayers();
+
+    /*!
+     * Set factor (>1.0) of growth of layer thickness towards inside of mesh
+     */
+    void SetStretchFactor(in double factor) raises (SALOME::SALOME_Exception);
+    double GetStretchFactor();
+  };
+
+  /*!
+   * interface of "Body fitting Parameters" hypothesis.
+   * This hypothesis specifies 
+   * - Definition of the Cartesian grid
+   * - Size threshold
+   */
+  interface StdMeshers_CartesianParameters3D : SMESH::SMESH_Hypothesis
+  {
+    /*!
+     * Set size threshold. A polyhedral cell got by cutting an initial
+     * hexahedron by geometry boundary is considered small and is removed if
+     * it's size is \athreshold times less than the size of the initial hexahedron. 
+     * threshold must be > 1.0
+     */
+    void SetSizeThreshold(in double threshold) raises (SALOME::SALOME_Exception);
+    double GetSizeThreshold();
+
+    /*!
+     * \brief Return true if the grid is defined by spacing functions and 
+     *        not by node coordinates in given direction (X==0,...)
+     */
+    boolean IsGridBySpacing(in short axis);
+
+    /*!
+     * Set coordinates of nodes along an axis (counterd from zero)
+     */
+    void SetGrid(in SMESH::double_array coords,
+                 in short               axis) raises (SALOME::SALOME_Exception);
+    SMESH::double_array GetGrid(in short axis) raises (SALOME::SALOME_Exception);
+
+    /*!
+     * \brief Set grid spacing along an axis
+     *  \param spaceFunctions - functions defining spacing values at given point on axis
+     *  \param internalPoints - points dividing a grid into parts along an axis
+     *  \param axis - index of an axis counterd from zero, i.e. 0==X, 1==Y, 2==Z
+     *
+     * Parameter t of spaceFunction f(t) is a position [0,1] withing bounding box of
+     * the shape to mesh or withing an interval defined by internal points
+     */
+    void SetGridSpacing(in SMESH::string_array spaceFunctions,
+                        in SMESH::double_array internalPoints,
+                        in short               axis) raises (SALOME::SALOME_Exception);
+
+    void GetGridSpacing(out SMESH::string_array spaceFunctions,
+                        out SMESH::double_array internalPoints,
+                        in short                axis) raises (SALOME::SALOME_Exception);
+
+    /*!
+     * \brief Computes node coordinates by spacing functions
+     *  \param x0 - lower coordinate
+     *  \param x1 - upper coordinate
+     *  \param spaceFuns - space functions
+     *  \param points - internal points
+     *  \param coords - the computed coordinates
+     */
+    SMESH::double_array ComputeCoordinates(in double              x0,
+                                           in double              x1,
+                                           in SMESH::string_array spaceFuns,
+                                           in SMESH::double_array points,
+                                           in string              axisName ) raises (SALOME::SALOME_Exception);
+  };
+
   /*!
    * StdMeshers_SegmentAroundVertex_0D: interface of "SegmentAroundVertex" algorithm
    */
@@ -664,6 +993,13 @@ module StdMeshers
   {
   };
 
+  /*!
+   * StdMeshers_Projection_1D2D: interface of "Projection 1D-2D" algorithm
+   */
+  interface StdMeshers_Projection_1D2D : SMESH::SMESH_2D_Algo
+  {
+  };
+
   /*!
    * StdMeshers_Projection_1D: interface of "Projection 1D" algorithm
    */
@@ -687,6 +1023,32 @@ module StdMeshers
   {
   };
 
+  /*!
+   * StdMeshers_RadialQuadrangle_1D2D: interface of "Radial quadrangle" algorithm
+   */
+  interface StdMeshers_RadialQuadrangle_1D2D : SMESH::SMESH_2D_Algo
+  {
+  };
+
+  /*!
+   * StdMeshers_Import_1D2D: interface of "Use existing 2D elements" algorithm
+   */
+  interface StdMeshers_Import_1D2D : SMESH::SMESH_2D_Algo
+  {
+  };
+  /*!
+   * StdMeshers_Import_1D: interface of "Use existing 1D elements" algorithm
+   */
+  interface StdMeshers_Import_1D : SMESH::SMESH_1D_Algo
+  {
+  };
+  /*!
+   * StdMeshers_Cartesian_3D: interface of "Body fitting" algorithm
+   */
+  interface StdMeshers_Cartesian_3D : SMESH::SMESH_3D_Algo
+  {
+  };
+
 };
 
 #endif
index 83c1d43d21136b9d98efee561c8e8f64597fcd0a..8cc7bc8645724e8201e5d8c7bb0997d99e57d7bb 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  File   : SMESH_Filter.idl
 //  Author : Alexey Petrov, OCC
 //
@@ -46,10 +47,16 @@ module SMESH
     FT_Skew,         
     FT_Area,          
     FT_Volume3D,          
+    FT_MaxElementLength2D,
+    FT_MaxElementLength3D,
     FT_FreeBorders,
     FT_FreeEdges,
     FT_FreeNodes,
     FT_FreeFaces,
+    FT_EqualNodes,  // IMPORTANT: when a new item is added, please
+    FT_EqualEdges,  // 1) update getFunctNames() in SMESH_Filter_i.cxx: line 3910
+    FT_EqualFaces,  // 2) update fixFunctorType() in SMESH_2smeshpy.cxx: line 234
+    FT_EqualVolumes,
     FT_MultiConnection,
     FT_MultiConnection2D,
     FT_Length,
@@ -61,9 +68,15 @@ module SMESH
     FT_LyingOnGeom,
     FT_RangeOfIds,
     FT_BadOrientedVolume,
+    FT_BareBorderVolume,
+    FT_BareBorderFace,
+    FT_OverConstrainedVolume,
+    FT_OverConstrainedFace,
     FT_LinearOrQuadratic,
     FT_GroupColor,
     FT_ElemGeomType,
+    FT_CoplanarFaces,
+    FT_BallDiameter,
     FT_LessThan,
     FT_MoreThan,
     FT_EqualTo,
@@ -73,6 +86,18 @@ module SMESH
     FT_Undefined
   };
 
+  /*!
+  * Parameters of a reclangle of histogram
+  */
+  struct HistogramRectangle
+  {
+    long nbEvents;
+    double min;
+    double max;
+  };
+  typedef sequence<HistogramRectangle> Histogram;
+
+
   /*!
   * Base interface for all functors ( i.e. numerical functors and predicates )
   */
@@ -83,8 +108,6 @@ module SMESH
     ElementType     GetElementType();
   };
 
-
-
   /*!
   * Numerical functors are intended for calculating value by Id of mesh entity
   */
@@ -92,6 +115,8 @@ module SMESH
   {
     double GetValue( in long theElementId );
 
+    Histogram GetHistogram( in short nbIntervals );
+
     /*!
     * Set precision for calculation. It is a position after point which is
     * used to functor value after calculation.
@@ -107,6 +132,8 @@ module SMESH
   interface Skew            : NumericalFunctor{};
   interface Area            : NumericalFunctor{};
   interface Volume3D        : NumericalFunctor{};
+  interface MaxElementLength2D : NumericalFunctor{};
+  interface MaxElementLength3D : NumericalFunctor{};
   interface Length          : NumericalFunctor{};
   interface Length2D        : NumericalFunctor
   {
@@ -130,7 +157,9 @@ module SMESH
     typedef sequence<Value> Values;
     Values GetValues();
   };
+  interface BallDiameter    : NumericalFunctor{};
   
+
   /*!
   * Predicates are intended for verification of criteria,
   *            must return bool value by mesh id
@@ -147,6 +176,54 @@ module SMESH
    */
   interface BadOrientedVolume: Predicate {};
 
+  /*!
+   * Logical functor (predicate) "Volumes with bare border".
+   * Verify whether a mesh volume has a free facet without a mesh face on it
+   */
+  interface BareBorderVolume: Predicate {};
+  /*!
+   * Logical functor (predicate) "Faces with bare border".
+   * Verify whether a mesh face has a side not shared with another face
+   * and without a mesh edge on it
+   */
+  interface BareBorderFace: Predicate {};
+
+  /*!
+   * Logical functor (predicate) "Over-constrained Volume"
+   * Verify whether a mesh volume has only one facet shared with other volumes
+   */
+  interface OverConstrainedVolume: Predicate {};
+  /*!
+   * Logical functor (predicate) "Over-constrained Face".
+   * Verify whether a mesh face has only one border shared with other faces
+   */
+  interface OverConstrainedFace: Predicate {};
+
+  /*!
+   * Logical functor (predicate) "Equal Nodes".
+   * Verify whether there is another mesh node with same coordinates
+   */
+  interface EqualNodes: Predicate 
+  {
+    void    SetTolerance( in double theToler );
+    double  GetTolerance();
+  };
+  /*!
+   * Logical functor (predicate) "Equal Edges".
+   * Verify whether there is another mesh edge basing on the same nodes
+   */
+  interface EqualEdges: Predicate {};
+  /*!
+   * Logical functor (predicate) "Equal Faces".
+   * Verify whether there is another mesh face basing on the same nodes
+   */
+  interface EqualFaces: Predicate {};
+  /*!
+   * Logical functor (predicate) "Equal Volumes".
+   * Verify whether there is another mesh volumes basing on the same nodes
+   */
+  interface EqualVolumes: Predicate {};
+
   /*!
    * Logical functor (predicate) "Belong To Geometry".
    * Verify whether mesh element or node belong to pointed Geom Object
@@ -345,6 +422,16 @@ module SMESH
     void            SetGeometryType( in GeometryType theType );
   };
 
+  /*!
+  * Functor "Coplanar faces"
+  * Returns true if a mesh face is a coplanar neighbour to a given one. It checks
+  * if normal of a face has angle with the threshold face less than a tolerance.
+  */
+  interface CoplanarFaces : Predicate{
+    void            SetFace ( in long theFaceID );
+    void            SetTolerance( in double theToler );
+  };
+
   /*!
   *  Filter
   */
@@ -359,13 +446,13 @@ module SMESH
     *   BinaryOp      - binary logical operation FT_LogicalAND, FT_LogicalOR or
     *                   (FT_Undefined must be for the last criterion)
     *   ThresholdStr  - Threshold value defined as string. Used for:
-    *                   1. Diaposon of identifiers. Example: "1,2,3,5-10,12,27-29"
+    *                   1. Diapason of identifiers. Example: "1,2,3,5-10,12,27-29"
     *                   2. BelongToGeom predicate for storing name of shape
     *                   3. GroupColor predicate for storing group color "0.2;0;0.5"
     *   ThresholdID   - One more threshold value defined as string. Used for:
     *                   1. BelongToGeom predicate for storing id of shape
     *   Tolerance     - Tolerance is used for comparators (EqualTo comparision) and for
-    *                   "Belong to plane" and "Belong to cylinder" predicates
+    *                   "Belong to plane", "Belong to cylinder" etc predicates
     *   TypeOfElement - type of element SMESH::NODE, SMESH::FACE (used by BelongToGeom predicate only)
     *   Precision     - Precision of numerical functors
     */
@@ -449,10 +536,13 @@ module SMESH
     Skew              CreateSkew();
     Area              CreateArea();
     Volume3D          CreateVolume3D();
+    MaxElementLength2D CreateMaxElementLength2D();
+    MaxElementLength3D CreateMaxElementLength3D();
     Length            CreateLength();
     Length2D          CreateLength2D();
     MultiConnection   CreateMultiConnection();
     MultiConnection2D CreateMultiConnection2D();
+    BallDiameter      CreateBallDiameter();
 
     /*!
     *  Create logical functors ( predicates )
@@ -469,13 +559,23 @@ module SMESH
     FreeNodes         CreateFreeNodes();
     FreeFaces         CreateFreeFaces();
 
+    EqualNodes        CreateEqualNodes();
+    EqualEdges        CreateEqualEdges();
+    EqualFaces        CreateEqualFaces();
+    EqualVolumes      CreateEqualVolumes();
+
     RangeOfIds        CreateRangeOfIds();
 
     BadOrientedVolume CreateBadOrientedVolume();
+    BareBorderVolume  CreateBareBorderVolume();
+    BareBorderFace    CreateBareBorderFace();
+    OverConstrainedVolume CreateOverConstrainedVolume();
+    OverConstrainedFace   CreateOverConstrainedFace();
     LinearOrQuadratic CreateLinearOrQuadratic();
 
     GroupColor        CreateGroupColor();
     ElemGeomType      CreateElemGeomType();
+    CoplanarFaces     CreateCoplanarFaces();
 
     /*!
     *  Create comparators ( predicates )
index 7cc93177b00784f00da161877c512d8c8a46051a..f6e9f89adb4a842a1e94907e9249353c52121fd9 100644 (file)
@@ -1,23 +1,23 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 //  File   : SMESH_Gen.idl
 //  Author : Paul RASCLE, EDF
@@ -41,6 +41,7 @@ module SMESH
 
   interface FilterManager;
   interface SMESH_Pattern;
+  interface Measurements;
 
   /*!
    * Tags definition
@@ -69,12 +70,14 @@ module SMESH
   const long Tag_EdgeGroups             = 12;
   const long Tag_FaceGroups             = 13;
   const long Tag_VolumeGroups           = 14;
-  const long Tag_LastGroup              = 14;
+  const long Tag_0DElementsGroups       = 15;
+  const long Tag_BallElementsGroups     = 16;
+  const long Tag_LastGroup              = 16;
 
   /*!
    * Hypothesis definintion error
    */
-  struct AlgoStateError 
+  struct AlgoStateError
   {
     Hypothesis_Status  state;
     string             algoName;
@@ -96,20 +99,22 @@ module SMESH
     COMPERR_EXCEPTION     ,  // other exception raised
     COMPERR_MEMORY_PB     ,  // memory allocation problem
     COMPERR_ALGO_FAILED   ,  // computation failed
-    COMPERR_BAD_SHAPE        // bad geometry
+    COMPERR_BAD_SHAPE     ,  // bad geometry
+    COMPERR_WARNING       ,  // algo reports error but sub-mesh is computed anyway
+    COMPERR_CANCELED         // compute canceled
   };
   struct ComputeError
   {
     short   code;       // ComputeErrorName or, if negative, algo specific code
     string  comment;    // textual problem description
     string  algoName;
-    short   subShapeID; // id of subshape of a shape to mesh
+    short   subShapeID; // id of sub-shape of a shape to mesh
     boolean hasBadMesh; // there are elements preventing computation available for visualization
   };
   typedef sequence<ComputeError> compute_error_array;
 
 
-  interface SMESH_Gen : Engines::Component, SALOMEDS::Driver
+  interface SMESH_Gen : Engines::EngineComponent, SALOMEDS::Driver
   {
     //GEOM::GEOM_Gen SetGeomEngine( in string containerLoc );
     void SetGeomEngine( in GEOM::GEOM_Gen geomcompo );
@@ -118,6 +123,8 @@ module SMESH
 
     SMESH_Pattern GetPattern();
 
+    Measurements  CreateMeasurements();
+
     /*!
       Set the current mode
      */
@@ -146,7 +153,7 @@ module SMESH
      * Algorithms are 1D, 2D or 3D.
      */
     SMESH_Hypothesis CreateHypothesis( in string theHypName,
-                                      in string theLibName )
+                                       in string theLibName )
       raises ( SALOME::SALOME_Exception );
 
     /*!
@@ -177,7 +184,7 @@ module SMESH
      * Set the object name
      */
     void SetName( in string theObjectIOR,
-                 in string theObjectName )
+                  in string theObjectName )
       raises ( SALOME::SALOME_Exception );
 
     /*!
@@ -189,13 +196,13 @@ module SMESH
      */
     SMESH_Mesh CreateMesh( in GEOM::GEOM_Object theObject )
       raises ( SALOME::SALOME_Exception );
-    
+
     /*!
      * Create an empty mesh object
      */
     SMESH_Mesh CreateEmptyMesh()
       raises ( SALOME::SALOME_Exception );
-    
+
     /*!
      * Create Mesh object importing data from given UNV file
      * (UNV supported version is I-DEAS 10)
@@ -207,7 +214,14 @@ module SMESH
      * Create Mesh object(s) importing data from given MED file
      */
      mesh_array CreateMeshesFromMED( in string theFileName,
-                                    out SMESH::DriverMED_ReadStatus theStatus )
+                                     out SMESH::DriverMED_ReadStatus theStatus )
+       raises ( SALOME::SALOME_Exception );
+
+    /*!
+     * Create Mesh object(s) importing data from given MED file
+     */
+     mesh_array CreateMeshesFromSAUV( in string theFileName,
+                                     out SMESH::DriverMED_ReadStatus theStatus )
        raises ( SALOME::SALOME_Exception );
 
     /*!
@@ -217,43 +231,98 @@ module SMESH
       raises ( SALOME::SALOME_Exception );
 
     /*!
-     * Create a Mesh object, without a geometry shape reference
+     * Create Mesh object(s) importing data from given CGNS file
+     */
+    mesh_array CreateMeshesFromCGNS( in string theFileName,
+                                     out SMESH::DriverMED_ReadStatus theStatus )
+      raises ( SALOME::SALOME_Exception );
+
+    /*!
+     * Create a mesh by copying a part of another mesh
+     *  \param meshPart - a part of mesh to copy
+     *  \param meshName - a name of the new mesh
+     *  \param toCopyGroups - to create in the new mesh groups
+     *                        the copied elements belongs to
+     *  \param toKeepIDs - to preserve IDs of the copied elements or not
+     */
+    SMESH_Mesh CopyMesh(in SMESH_IDSource meshPart,
+                        in string         meshName,
+                        in boolean        toCopyGroups,
+                        in boolean        toKeepIDs)
+      raises ( SALOME::SALOME_Exception );
+
+    /*!
+     * Concatenate the given meshes into one mesh.
+     * Union groups with the same name and type if
+     * theUniteIdenticalGroups flag is true.
+     * Merge coincident nodes and elements if
+     * theMergeNodesAndElements flag is true.
+     */
+    SMESH_Mesh Concatenate(in mesh_array theMeshesArray,
+                           in boolean    theUniteIdenticalGroups,
+                           in boolean    theMergeNodesAndElements,
+                           in double     theMergeTolerance)
+      raises ( SALOME::SALOME_Exception );
+
+    /*!
+     * Concatenate the given meshes into one mesh.
+     * Union groups with the same name and type if
+     * theUniteIdenticalGroups flag is true.
+     * Merge coincident nodes and elements if
+     * theMergeNodesAndElements flag is true.
+     * Create the groups of all elements from initial meshes.
      */
-//      SMESH_Mesh NewEmpty()
-//        raises ( SALOME::SALOME_Exception );
+    SMESH_Mesh ConcatenateWithGroups(in mesh_array theMeshesArray,
+                                     in boolean    theUniteIdenticalGroups,
+                                     in boolean    theMergeNodesAndElements,
+                                     in double     theMergeTolerance)
+      raises ( SALOME::SALOME_Exception );
 
     /*!
-     * Mesh a subShape. 
-     * First, verify list of hypothesis associated with the subShape,
+     * Mesh a subShape.
+     * First, verify list of hypothesis associated with the Sub-shape,
      * return NOK if hypothesis are not sufficient
      */
-    boolean Compute( in SMESH_Mesh        theMesh, 
-                    in GEOM::GEOM_Object theSubObject )
+    boolean Compute( in SMESH_Mesh        theMesh,
+                     in GEOM::GEOM_Object theSubObject )
       raises ( SALOME::SALOME_Exception );
 
+    /*!
+     * Cancel a computation.
+     */
+    void CancelCompute( in SMESH_Mesh        theMesh,
+                       in GEOM::GEOM_Object theSubObject );
+
     /*!
      * Return true if hypotheses are defined well
      */
-    boolean IsReadyToCompute( in SMESH_Mesh        theMesh, 
-                             in GEOM::GEOM_Object theSubObject )
+    boolean IsReadyToCompute( in SMESH_Mesh        theMesh,
+                              in GEOM::GEOM_Object theSubObject )
+      raises ( SALOME::SALOME_Exception );
+
+    /*!
+     * Evaluates size of prospective mesh on a shape
+     */
+    long_array  Evaluate(in SMESH_Mesh        theMesh,
+                         in GEOM::GEOM_Object theSubObject)
       raises ( SALOME::SALOME_Exception );
 
     /*!
      * Calculate Mesh as preview till indicated dimension
-     * First, verify list of hypothesis associated with the subShape.
+     * First, verify list of hypothesis associated with the Sub-shape.
      * Return mesh preview structure
      */
-    MeshPreviewStruct Precompute( in SMESH_Mesh        theMesh, 
-                                 in GEOM::GEOM_Object theSubObject,
-                                 in Dimension         theDimension,
-                                 inout long_array    theShapesId )
+    MeshPreviewStruct Precompute( in SMESH_Mesh        theMesh,
+                                  in GEOM::GEOM_Object theSubObject,
+                                  in Dimension         theDimension,
+                                  inout long_array    theShapesId )
       raises ( SALOME::SALOME_Exception );
 
     /*!
      * Return errors of hypotheses definintion
      * algo_error_array is empty if everything is OK
      */
-    algo_error_array GetAlgoState( in SMESH_Mesh        theMesh, 
+    algo_error_array GetAlgoState( in SMESH_Mesh        theMesh,
                                    in GEOM::GEOM_Object theSubObject )
       raises ( SALOME::SALOME_Exception );
 
@@ -261,19 +330,19 @@ module SMESH
      * Return errors of mesh computation
      * compute_error_array is empty if everything is OK
      */
-    compute_error_array GetComputeErrors( in SMESH_Mesh        theMesh, 
+    compute_error_array GetComputeErrors( in SMESH_Mesh        theMesh,
                                           in GEOM::GEOM_Object theSubObject )
       raises ( SALOME::SALOME_Exception );
 
     /*!
-     * Return mesh elements preventing computation of a subshape
+     * Return mesh elements preventing computation of a sub-shape
      */
     MeshPreviewStruct GetBadInputElements( in SMESH_Mesh theMesh,
                                            in short      theSubShapeID )
       raises ( SALOME::SALOME_Exception );
 
     /*!
-     * Return indeces of faces, edges and vertices of given subshapes
+     * Return indeces of faces, edges and vertices of given sub-shapes
      * within theMainObject
      */
     long_array GetSubShapesId( in GEOM::GEOM_Object theMainObject,
@@ -282,7 +351,7 @@ module SMESH
 
     /*!
      * Return geometrical object the given element is built on.
-     * The returned geometrical object, if not nil, is either found in the 
+     * The returned geometrical object, if not nil, is either found in the
      * study or is published by this method with the given name
      */
     GEOM::GEOM_Object GetGeometryByMeshElement( in SMESH_Mesh  theMesh,
@@ -295,42 +364,25 @@ module SMESH
      * The returned geometrical object not published in study by this method.
      */
     GEOM::GEOM_Object FindGeometryByMeshElement( in SMESH_Mesh  theMesh,
-                                                in long        theElementID)
+                                                 in long        theElementID)
       raises ( SALOME::SALOME_Exception );
 
     /*!
-     * Concatenate the given meshes into one mesh.
-     * Union groups with the same name and type if
-     * theUniteIdenticalGroups flag is true.
-     * Merge coincident nodes and elements if 
-     * theMergeNodesAndElements flag is true.
+     * \brief Return id of object, registered in current study context
+     *
+     * Can be used to check if the object was created in the same container, as this engine.
      */
-    SMESH_Mesh Concatenate(in mesh_array theMeshesArray, 
-                          in boolean    theUniteIdenticalGroups, 
-                          in boolean    theMergeNodesAndElements, 
-                          in double     theMergeTolerance)
-      raises ( SALOME::SALOME_Exception );
+    long GetObjectId(in Object theObject);
 
     /*!
-     * Concatenate the given meshes into one mesh.
-     * Union groups with the same name and type if
-     * theUniteIdenticalGroups flag is true.
-     * Merge coincident nodes and elements if 
-     * theMergeNodesAndElements flag is true.
-     * Create the groups of all elements from initial meshes.
+     * \brief Get MED version of the file by its name.
      */
-    SMESH_Mesh ConcatenateWithGroups(in mesh_array theMeshesArray, 
-                                    in boolean    theUniteIdenticalGroups, 
-                                     in boolean    theMergeNodesAndElements, 
-                                     in double     theMergeTolerance)
-      raises ( SALOME::SALOME_Exception );
+    boolean GetMEDVersion(in string theFileName, out MED_VERSION theVersion);
 
     /*!
-     * \brief Return id of object, registered in current study context
-     *
-     * Can be used to check if the object was created in the same container, as this engine.
+     * \brief Get names of meshes defined in file with the specified name.
      */
-    long GetObjectId(in Object theObject);
+    string_array GetMeshNames(in string theFileName);
   };
 
 };
index aa9cee1252b48e8f90d82f2e8083e9417de7effd..d00fe0e9d4296b8b1101cf641ff4bc48b2eb852b 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  File   : SMESH_Group.idl
 //  Author : Sergey ANIKIN, OCC
 //  $Header$
@@ -35,6 +36,7 @@
 module SMESH
 {
   interface Predicate;
+  interface Filter;
 
   /*!
    * SMESH_Group: base interface of group object
@@ -82,9 +84,21 @@ module SMESH
     long_array GetListOfID();
 
     /*!
-     * Returns the mesh object this group belongs to
+     * Get the number of nodes of cells included to the group
+     * For a nodal group returns the same value as Size() function
+     */
+    long GetNumberOfNodes();
+
+    /*!
+     * Get IDs of nodes of cells included to the group
+     * For a nodal group returns result of GetListOfID() function
+     */
+    long_array GetNodeIDs();
+
+    /*!
+     * Return true if GetNumberOfNodes() won't take a long time for computation
      */
-    SMESH_Mesh GetMesh();
+    boolean IsNodeInfoAvailable();
 
     /*!
      * Sets group color
@@ -110,7 +124,7 @@ module SMESH
   }; 
 
   /*!
-   * SMESH_Group: interface of group object
+   * SMESH_Group: interface of a standalone group object
    */
   interface SMESH_Group : SMESH_GroupBase
   {
@@ -120,26 +134,46 @@ module SMESH
     void Clear();
 
     /*!
-     * Adds elements to the group
+     * Adds elements or nodes with specified identifiers to the group
      */
     long Add( in long_array elem_ids );
+    /*!
+     * Adds elements or nodes that match specified predicate to the group
+     */
     long AddByPredicate( in Predicate thePredicate );
+    /*!
+     * Add all elements or nodes from the specified source to the group
+     */
+    long AddFrom( in SMESH_IDSource theSource );
 
     /*!
-     * Removes elements from the group
+     * Removes elements or nodes with specified identifiers from the group
      */
     long Remove( in long_array elem_ids );
+    /*!
+     * Removes elements or nodes that match specified predicate from the group
+     */
     long RemoveByPredicate( in Predicate thePredicate );
 
   };
+
   /*!
-   * SMESH_Group: interface of group object linked to geometry
+   * SMESH_GroupOnGeom: interface of a group object linked to geometry
    */
   interface SMESH_GroupOnGeom : SMESH_GroupBase
   {
     GEOM::GEOM_Object GetShape();
   };
 
+  /*!
+   * SMESH_GroupOnFilter: interface of a group object defined by filter
+   */
+  interface SMESH_GroupOnFilter : SMESH_GroupBase
+  {
+    void   SetFilter( in Filter theFilter); 
+    Filter GetFilter();
+  };
+
 };
 
 
index 56ae48b0cfed28db8767c589560f11ab2949c2ba..8d18789baea37cc21e49dca776d1bae6fbc2b69d 100644 (file)
@@ -1,27 +1,27 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  File   : SMESH_Hypothesis.idl
 //  Author : Paul RASCLE, EDF
-//  $Header$
 //
 #ifndef _SMESH_HYPOTHESIS_IDL_
 #define _SMESH_HYPOTHESIS_IDL_
@@ -59,6 +59,22 @@ module SMESH
      */
     long GetId();
 
+    /*!
+     *  Set the variable parameter
+     *  \param parameter is a string containing the notebook variable
+     *         used for Hypothesis creation
+     *  \param method is a name of Hypothesis method setting this parameter
+     *
+     *  This method must be called before calling method()
+     */
+    void SetVarParameter (in string parameter, in string method);
+
+    /*!
+     *  Return the variable parameter used for Hypothesis creation by name of method
+     *  setting this parameter
+     */
+    string GetVarParameter (in string methodName);
+
     /*!
      *  Set list of parameters
      *  \param theParameters is a string containing the notebook variables separated by ":" symbol,
diff --git a/idl/SMESH_Measurements.idl b/idl/SMESH_Measurements.idl
new file mode 100644 (file)
index 0000000..6d8d7f5
--- /dev/null
@@ -0,0 +1,61 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+//  File   : SMESH_Measurements.idl
+//  Author : Pavel Telkov, OCC
+//
+#ifndef _SMESH_MEASUREMENTS_IDL_
+#define _SMESH_MEASUREMENTS_IDL_
+
+#include "SALOME_GenericObj.idl"
+#include "SMESH_Mesh.idl"
+
+module SMESH
+{
+
+  /*
+   * Measure component
+   */
+  struct Measure {
+    double minX, minY, minZ;
+    double maxX, maxY, maxZ;
+    long node1, node2;
+    long elem1, elem2;
+    double value;
+  };
+
+  interface Measurements: SALOME::GenericObj
+  {
+    /*!
+     * minimal distance between two entities
+     */
+    Measure MinDistance(in SMESH_IDSource source1,
+                        in SMESH_IDSource source2);
+
+    /*!
+     * common bounding box of entities
+     */
+    Measure BoundingBox(in ListOfIDSources sources);
+  };
+};    
+
+#endif
index fa5180a24d6f52d690eef70b88f991b70142ef36..409bb4e6ec4ac3ded80a66a86a00e08a1152545f 100644 (file)
@@ -1,28 +1,28 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  File   : SMESH_Mesh.idl
 //  Author : Paul RASCLE, EDF
 //
-
 #ifndef _SMESH_MESH_IDL_
 #define _SMESH_MESH_IDL_
 
@@ -37,6 +37,8 @@ module SMESH
   typedef sequence<SMESH_Hypothesis> ListOfHypothesis;
   interface SMESH_GroupBase;
   typedef sequence<SMESH_GroupBase> ListOfGroups;
+  interface SMESH_IDSource;
+  typedef sequence<SMESH_IDSource> ListOfIDSources;
 
   typedef sequence<double    > double_array ;
   typedef sequence<long      > long_array ;
@@ -68,7 +70,12 @@ module SMESH
       ADD_QUADTETRAHEDRON,
       ADD_QUADPYRAMID,
       ADD_QUADPENTAHEDRON,
-      ADD_QUADHEXAHEDRON
+      ADD_QUADHEXAHEDRON,
+      ADD_ELEM0D,
+      ADD_BIQUAD_QUADRANGLE,
+      ADD_TRIQUAD_HEXA,
+      ADD_HEXAGONAL_PRISM,
+      ADD_BALL
     };
 
   struct log_block
@@ -112,8 +119,11 @@ module SMESH
     NODE,
     EDGE,
     FACE,
-    VOLUME
+    VOLUME,
+    ELEM0D,
+    BALL
   };
+  typedef sequence<ElementType> array_of_ElementType ;
 
   /*!
    * Enumeration for element geometry type, like in SMDS
@@ -123,13 +133,15 @@ module SMESH
     Geom_POINT,
     Geom_EDGE,
     Geom_TRIANGLE,
-    Geom_QUADRANGLE,
-    Geom_POLYGON,
+    Geom_QUADRANGLE, // when a new GeometryType is added, please
+    Geom_POLYGON,    // update a corresponding list in SMESH_2smeshpy.cxx, ln 665
     Geom_TETRA,
     Geom_PYRAMID,
     Geom_HEXA,
     Geom_PENTA,
-    Geom_POLYHEDRA
+    Geom_HEXAGONAL_PRISM,
+    Geom_POLYHEDRA,
+    Geom_BALL
   };
   
   /*!
@@ -141,6 +153,41 @@ module SMESH
     ORDER_QUADRATIC     /*! entities of 2nd order */
   };
 
+
+  /*!
+   * Enumeration of entity type used in mesh info array,
+   * it should be synchronised with enum SMDSAbs_EntityType
+   */
+  enum EntityType
+  {
+    Entity_Node,
+    Entity_0D,
+    Entity_Edge,
+    Entity_Quad_Edge,
+    Entity_Triangle,
+    Entity_Quad_Triangle,
+    Entity_Quadrangle,
+    Entity_Quad_Quadrangle,
+    Entity_BiQuad_Quadrangle,
+    Entity_Polygon,
+    Entity_Quad_Polygon,
+    Entity_Tetra,
+    Entity_Quad_Tetra,
+    Entity_Pyramid,
+    Entity_Quad_Pyramid,
+    Entity_Hexa,
+    Entity_Quad_Hexa,
+    Entity_TriQuad_Hexa,
+    Entity_Penta,
+    Entity_Quad_Penta,
+    Entity_Hexagonal_Prism,
+    Entity_Polyhedra,
+    Entity_Quad_Polyhedra,
+    Entity_Ball,
+    Entity_Last
+  };
+
+
   /*!
    * Enumeration for hypothesis status (used by AddHypothesis() and RemoveHypothesis() methods)
    */
@@ -158,7 +205,7 @@ module SMESH
     HYP_NOTCONFORM,   // not conform mesh is produced appling a hypothesis
     HYP_ALREADY_EXIST,// such hypothesis already exist
     HYP_BAD_DIM,      // bad dimension
-    HYP_BAD_SUBSHAPE, // shape is neither the main one, nor its subshape, nor a group
+    HYP_BAD_SUBSHAPE, // shape is neither the main one, nor its sub-shape, nor a group
     HYP_BAD_GEOMETRY, // geometry mismatches algorithm's expectation
     HYP_NEED_SHAPE    // algorithm can work on shape only
   };
@@ -212,18 +259,49 @@ module SMESH
                              long_array  elementConnectivities;
                              types_array elementTypes; };
 
+  interface SMESH_Mesh;
+
   interface SMESH_IDSource
   {
     /*!
      * Returns a sequence of all element IDs
      */
     long_array GetIDs();
+
+    /*!
+     * Returns statistic of mesh elements
+     * @return array of number enityties by index of EntityType
+     */
+    long_array GetMeshInfo();
+
+    /*!
+     * Returns types of elements it contains.
+     * It's empty if the SMESH_IDSource contains no IDs
+     */
+    array_of_ElementType GetTypes();
+
+    /*!
+     * Returns the mesh
+     */
+    SMESH_Mesh GetMesh();
+
+    /*!
+     * Returns false if GetMeshInfo() returns incorrect information that may
+     * happen if mesh data is not yet fully loaded from the file of study.
+     */
+    boolean IsMeshInfoCorrect();
   };
 
   interface SMESH_Group;
   interface SMESH_GroupOnGeom;
+  interface Filter;
+  interface SMESH_GroupOnFilter;
   interface SMESH_subMesh;
   interface SMESH_MeshEditor;
+
+  typedef sequence<SMESH_subMesh>     submesh_array;
+  typedef sequence<submesh_array>     submesh_array_array;
+
   interface SMESH_Mesh : SALOME::GenericObj, SMESH_IDSource
   {
     /*!
@@ -239,12 +317,30 @@ module SMESH
     GEOM::GEOM_Object GetShapeToMesh()
       raises (SALOME::SALOME_Exception);
 
+    /*!
+     * Return false if the mesh is not yet fully loaded from the study file
+     */
+    boolean IsLoaded()
+      raises (SALOME::SALOME_Exception);
+
+    /*!
+     * Load full mesh data from the study file
+     */
+    void Load()
+      raises (SALOME::SALOME_Exception);
+
     /*!
      * Remove all nodes and elements
      */
     void Clear()
       raises (SALOME::SALOME_Exception);
 
+    /*!
+     *  Get the list of sub-meshes existing in the mesh
+     */
+    submesh_array GetSubMeshes()
+      raises (SALOME::SALOME_Exception);
+
     /*!
      * Remove all nodes and elements of submesh
      */
@@ -252,9 +348,9 @@ module SMESH
       raises (SALOME::SALOME_Exception);
 
     /*!
-     * Get the subMesh object associated to a subShape. The subMesh object
+     * Get the subMesh object associated to a Sub-shape. The subMesh object
      * gives access to nodes and elements IDs.
-     * SubMesh will be used instead of SubShape in a next idl version to
+     * SubMesh will be used instead of Sub-shape in a next idl version to
      * adress a specific subMesh...
      */
     SMESH_subMesh GetSubMesh(in GEOM::GEOM_Object aSubObject, in string name)
@@ -271,15 +367,23 @@ module SMESH
      * Create a group
      */
     SMESH_Group CreateGroup( in ElementType elem_type,
-                            in string name )
+                            in string      name )
+      raises (SALOME::SALOME_Exception);
+
+    /*!
+     * Create a group from geometry
+     */
+    SMESH_GroupOnGeom CreateGroupFromGEOM( in ElementType       elemType,
+                                           in string            name,
+                                           in GEOM::GEOM_Object geomObject )
       raises (SALOME::SALOME_Exception);
 
     /*!
-     * Create a group from geometry group
+     * Create a group from filter
      */
-    SMESH_GroupOnGeom CreateGroupFromGEOM( in ElementType elem_type,
-                                          in string name,
-                                          in GEOM::GEOM_Object theGeomObject )
+    SMESH_GroupOnFilter CreateGroupFromFilter( in ElementType   elemType,
+                                               in string        name,
+                                               in SMESH::Filter filter )
       raises (SALOME::SALOME_Exception);
 
     /*!
@@ -376,26 +480,26 @@ module SMESH
       raises (SALOME::SALOME_Exception);
 
     /*!
-     * Convert group on geometry into standalone group
+     * Convert group on geometry or on filter into standalone group
      */
-    SMESH_Group ConvertToStandalone( in SMESH_GroupOnGeom theGeomGroup )
+    SMESH_Group ConvertToStandalone( in SMESH_GroupBase theGroupOn )
       raises (SALOME::SALOME_Exception);
 
     /*!
-     * Add hypothesis to the mesh, under a particular subShape
+     * Add hypothesis to the mesh, under a particular Sub-shape
      * (or the main shape itself)
      * The Add method is only used to prepare the build of the mesh and store
      * the algorithms and associated parameters.
      * Actual job of mesh the shape is done by MESH_Gen.
      * @params
-     * - aSubShape : subShape obtained by a shape explode in GEOM
+     * - aSubShape : sub-shape obtained by a shape explode in GEOM
      *   (or main shape)
      * - anHyp : hypothesis object
      * @return
-     * - OK if the hypothesis is compatible with the subShape
-     *   (and all previous hypothesis on the subShape)
-     * - NOK if the hypothesis is not compatible with the subShape
-     *   (or one previous hypothesis on the subShape)
+     * - OK if the hypothesis is compatible with the sub-shape
+     *   (and all previous hypothesis on the sub-shape)
+     * - NOK if the hypothesis is not compatible with the sub-shape
+     *   (or one previous hypothesis on the sub-shape)
      * raises exception if hypothesis has not been created
      */
     Hypothesis_Status AddHypothesis(in GEOM::GEOM_Object aSubObject,
@@ -415,7 +519,7 @@ module SMESH
 //       raises (SALOME::SALOME_Exception);
 
     /*!
-     * Get the list of hypothesis added on a subShape
+     * Get the list of hypothesis added on a sub-shape
      */
     ListOfHypothesis GetHypothesisList(in GEOM::GEOM_Object aSubObject)
       raises (SALOME::SALOME_Exception);
@@ -477,6 +581,13 @@ module SMESH
     SMESH_MeshEditor GetMeshEditPreviewer()
       raises (SALOME::SALOME_Exception);
 
+    /*!
+     * Return true if the mesh has been edited since a total re-compute
+     * and those modifications may prevent successful partial re-compute
+     */
+    boolean HasModificationsToDiscard()
+      raises (SALOME::SALOME_Exception);
+
     /*! Check group names for duplications.
      *  Consider maximum group name length stored in MED file.
      */
@@ -485,22 +596,56 @@ module SMESH
     /*!
      * Export Mesh to different MED Formats
      * @params
+     * - file : name of the MED file
      * - auto_groups : boolean parameter for creating/not creating
      *   the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
      *   the typical use is auto_groups=false.
-     * - theVersion : define the version of format of MED file, that will be created
+     * - version : define the version of format of MED file, that will be created
+     * - overwrite : boolean parameter for overwriting/not overwriting the file, if it exists
+     */
+    void ExportToMEDX( in string      file, 
+                       in boolean     auto_groups, 
+                       in MED_VERSION version, 
+                       in boolean     overwrite ) raises (SALOME::SALOME_Exception);
+
+    /*!
+     * Export a part of Mesh into a MED file
+     * @params
+     * - meshPart : a part of mesh to store
+     * - file : name of the MED file
+     * - version : define the version of format of MED file, that will be created
+     * - overwrite : boolean parameter for overwriting/not overwriting the file, if it exists
+     */
+    void ExportPartToMED( in SMESH_IDSource meshPart, 
+                          in string         file, 
+                          in boolean        auto_groups,
+                          in MED_VERSION    version,
+                          in boolean        overwrite ) raises (SALOME::SALOME_Exception);
+
+    /*!
+     * Export Mesh to different MED Formats
+     * Works, just the same as ExportToMEDX, with overwrite parameter equal to true.
+     * The method is kept in order to support old functionality
      */
     void ExportToMED( in string file, in boolean auto_groups, in MED_VERSION theVersion )
       raises (SALOME::SALOME_Exception);
 
     /*!
      * Export Mesh to MED_V2_1 MED format
-     * Works, just the same as ExportToMED, with MED_VERSION parameter equal to MED_V2_1.
+     * Works, just the same as ExportToMEDX with MED_VERSION parameter equal to MED_V2_1
+     * and overwrite parameter equal to true
      * The method is kept in order to support old functionality
      */
     void ExportMED( in string file, in boolean auto_groups )
       raises (SALOME::SALOME_Exception);
 
+    /*!
+     * Export Mesh to SAUV formatted file
+     * Write a temporary med file and use med2sauv
+     */
+    void ExportSAUV( in string file, in boolean auto_groups )
+      raises (SALOME::SALOME_Exception);
+
     /*!
      * Return string representation of a MED file version comprising nbDigits
      */
@@ -510,12 +655,20 @@ module SMESH
      * Export Mesh to DAT, UNV and STL Formats
      * (UNV supported version is I-DEAS 10)
      */
-    void ExportDAT( in string file )
-      raises (SALOME::SALOME_Exception);
-    void ExportUNV( in string file )
-      raises (SALOME::SALOME_Exception);
-    void ExportSTL( in string file, in boolean isascii )
-      raises (SALOME::SALOME_Exception);
+    void ExportDAT( in string file ) raises (SALOME::SALOME_Exception);
+    void ExportUNV( in string file ) raises (SALOME::SALOME_Exception);
+    void ExportSTL( in string  file,
+                    in boolean isascii ) raises (SALOME::SALOME_Exception);
+    void ExportCGNS( in SMESH_IDSource meshPart, 
+                     in string         file,
+                     in boolean        overwrite ) raises (SALOME::SALOME_Exception);
+    void ExportPartToDAT( in SMESH_IDSource meshPart, 
+                          in string         file ) raises (SALOME::SALOME_Exception);
+    void ExportPartToUNV( in SMESH_IDSource meshPart, 
+                          in string         file ) raises (SALOME::SALOME_Exception);
+    void ExportPartToSTL( in SMESH_IDSource meshPart,
+                          in string         file,
+                          in boolean        isascii ) raises (SALOME::SALOME_Exception);
 
     /*!
      * Get MED Mesh
@@ -532,6 +685,12 @@ module SMESH
     long NbElements()
       raises (SALOME::SALOME_Exception);
 
+    long Nb0DElements()
+      raises (SALOME::SALOME_Exception);
+
+    long NbBalls()
+      raises (SALOME::SALOME_Exception);
+
     long NbEdges()
       raises (SALOME::SALOME_Exception);
 
@@ -556,6 +715,9 @@ module SMESH
     long NbQuadranglesOfOrder(in ElementOrder order)
       raises (SALOME::SALOME_Exception);
 
+    long NbBiQuadQuadrangles()
+      raises (SALOME::SALOME_Exception);
+
     long NbPolygons()
       raises (SALOME::SALOME_Exception);
 
@@ -577,6 +739,9 @@ module SMESH
     long NbHexasOfOrder(in ElementOrder order)
       raises (SALOME::SALOME_Exception);
 
+    long NbTriQuadraticHexas()
+      raises (SALOME::SALOME_Exception);
+
     long NbPyramids()
       raises (SALOME::SALOME_Exception);
 
@@ -589,6 +754,9 @@ module SMESH
     long NbPrismsOfOrder(in ElementOrder order)
       raises (SALOME::SALOME_Exception);
 
+    long NbHexagonalPrisms()
+      raises (SALOME::SALOME_Exception);
+
     long NbPolyhedrons()
       raises (SALOME::SALOME_Exception);
 
@@ -610,6 +778,9 @@ module SMESH
     ElementType GetElementType( in long id, in boolean iselem )
       raises (SALOME::SALOME_Exception);
 
+    EntityType GetElementGeomType( in long id )
+      raises (SALOME::SALOME_Exception);
+
     long_array GetSubMeshElementsId(in long ShapeID)
       raises (SALOME::SALOME_Exception);
 
@@ -619,6 +790,22 @@ module SMESH
     ElementType GetSubMeshElementType(in long ShapeID)
       raises (SALOME::SALOME_Exception);
 
+
+    /*!
+     * Methods to set meshing order of submeshes
+     */
+
+    /*!
+     * \brief Return submesh objects list in meshing order
+     */
+    submesh_array_array GetMeshOrder();
+
+    /*!
+     * \brief Set submesh object order
+     */
+    boolean SetMeshOrder(in submesh_array_array theSubMeshArray);
+
+
     /*!
      * Get mesh description
      */
@@ -699,6 +886,16 @@ module SMESH
      */
     long ElemNbFaces(in long id);
 
+    /*!
+     * Returns nodes of given face (counted from zero) for given volumic element.
+     */
+    long_array GetElemFaceNodes(in long elemId, in short faceIndex);
+
+    /*!
+     * Returns an element based on all given nodes.
+     */
+    long FindElementByNodes(in long_array nodes);
+
     /*!
      * Returns true if given element is polygon
      */
@@ -709,6 +906,11 @@ module SMESH
      */
     boolean IsQuadratic(in long id);
 
+    /*!
+     * Returns diameter of a ball discrete element or zero in case of an invalid \a id
+     */
+    double GetBallDiameter(in long id);
+
     /*!
      * Returns XYZ coordinates of bary center for given element
      * as list of double
index 0a4b5b7cd4e8e464114a8fc22cd669b52f632227..561c5b8841b4945d60160daafac2eceaa1eba64a 100644 (file)
@@ -1,26 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 //  File   : SMESH_MeshEditor.idl
-//
 
 #ifndef _SMESH_MESHEDITOR_IDL_
 #define _SMESH_MESHEDITOR_IDL_
 
 module SMESH
 {
+  enum Bnd_Dimension { BND_2DFROM3D, BND_1DFROM3D, BND_1DFROM2D };
+
   /*!
    * This interface makes modifications on the Mesh - removing elements and nodes etc.
    */
   interface NumericalFunctor;
   interface SMESH_MeshEditor
   {
+    /*!
+     * \brief Wrap a sequence of ids in a SMESH_IDSource
+     * \param IDsOfElements list of mesh elements identifiers
+     * \return new ID source object
+     */
+    SMESH_IDSource MakeIDSource(in long_array IDsOfElements, in ElementType type);
+
+    /*!
+     * \brief Remove mesh elements specified by their identifiers.
+     * \param IDsOfElements list of mesh elements identifiers
+     * \return \c true if elements are correctly removed or \c false otherwise
+     */
     boolean RemoveElements(in long_array IDsOfElements);
 
+    /*!
+     * \brief Remove mesh nodes specified by their identifiers.
+     * \param IDsOfNodes list of mesh nodes identifiers
+     * \return \c true if nodes are correctly removed or \c false otherwise
+     */
     boolean RemoveNodes(in long_array IDsOfNodes);
 
+    /*!
+     * \brief Remove all orphan nodes.
+     * \return number of removed nodes
+     */
+    long RemoveOrphanNodes();
+
+    /*!
+     * \brief Add a new node.
+     * \param x X coordinate of new node
+     * \param y Y coordinate of new node
+     * \param z Z coordinate of new node
+     * \return integer identifier of new node
+     */
     long AddNode(in double x, in double y, in double z);
 
     /*!
-     *  Create edge, either linear and quadratic (this is determed
-     *  by number of given nodes).
+     *  Create a 0D element on the given node.
+     *  \param IdOfNode Node IDs for creation of element.
+     */
+    long Add0DElement(in long IDOfNode);
+
+    /*!
+     *  Create a ball element on the given node.
+     *  \param IdOfNode Node IDs for creation of element.
+     */
+    long AddBall(in long IDOfNode, in double diameter);
+
+    /*!
+     *  Create an edge, either linear and quadratic (this is determed
+     *  by number of given nodes, two or three).
      *  \param IdsOfNodes List of node IDs for creation of element.
      *  Needed order of nodes in this list corresponds to description
      *  of MED. This description is located by the following link:
@@ -139,6 +182,19 @@ module SMESH
     boolean Reorient(in long_array IDsOfElements);
 
     boolean ReorientObject(in SMESH_IDSource theObject);
+    /*!
+     * \brief Reorient faces contained in \a the2Dgroup.
+     * \param the2Dgroup - the mesh or its part to reorient
+     * \param theDirection - desired direction of normal of \a theFace
+     * \param theFace - ID of face whose orientation is checked.
+     *        It can be < 1 then \a thePoint is used to find a face.
+     * \param thePoint - is used to find a face if \a theFace < 1.
+     * \return number of reoriented elements.
+     */
+    long Reorient2D(in SMESH_IDSource the2Dgroup,
+                    in DirStruct      theDirection,
+                    in long           theFace,
+                    in PointStruct    thePoint) raises (SALOME::SALOME_Exception);
 
     /*!
      * \brief Fuse neighbour triangles into quadrangles.
@@ -149,8 +205,8 @@ module SMESH
      * \return TRUE in case of success, FALSE otherwise.
      */
     boolean TriToQuad (in long_array       IDsOfElements,
-                      in NumericalFunctor Criterion,
-                      in double           MaxAngle);
+                       in NumericalFunctor Criterion,
+                       in double           MaxAngle);
 
     /*!
      * \brief Fuse neighbour triangles into quadrangles.
@@ -158,8 +214,8 @@ module SMESH
      * Behaves like the above method, taking list of elements from \a theObject
      */
     boolean TriToQuadObject (in SMESH_IDSource   theObject,
-                            in NumericalFunctor Criterion,
-                            in double           MaxAngle);
+                             in NumericalFunctor Criterion,
+                             in double           MaxAngle);
 
     /*!
      * \brief Split quadrangles into triangles.
@@ -168,7 +224,7 @@ module SMESH
      * \return TRUE in case of success, FALSE otherwise.
      */
     boolean QuadToTri (in long_array       IDsOfElements,
-                      in NumericalFunctor Criterion);
+                       in NumericalFunctor Criterion);
 
     /*!
      * \brief Split quadrangles into triangles.
@@ -176,7 +232,7 @@ module SMESH
      * Behaves like the above method, taking list of elements from \a theObject
      */
     boolean QuadToTriObject (in SMESH_IDSource   theObject,
-                            in NumericalFunctor Criterion);
+                             in NumericalFunctor Criterion);
 
     /*!
      * \brief Split quadrangles into triangles.
@@ -185,7 +241,7 @@ module SMESH
      * \return TRUE in case of success, FALSE otherwise.
      */
     boolean SplitQuad (in long_array IDsOfElements,
-                      in boolean    Diag13);
+                       in boolean    Diag13);
 
     /*!
      * \brief Split quadrangles into triangles.
@@ -193,7 +249,7 @@ module SMESH
      * Behaves like the above method, taking list of elements from \a theObject
      */
     boolean SplitQuadObject (in SMESH_IDSource theObject,
-                            in boolean        Diag13);
+                             in boolean        Diag13);
 
     /*!
      *  Find better splitting of the given quadrangle.
@@ -203,7 +259,19 @@ module SMESH
      *          diagonal is better, 0 if error occurs.
      */
     long BestSplit (in long             IDOfQuad,
-                   in NumericalFunctor Criterion);
+                    in NumericalFunctor Criterion);
+
+    /*!
+     * \brief Split volumic elements into tetrahedrons
+     *  \param elems - elements to split
+     *  \param methodFlags - flags passing splitting method:
+     *         1 - split the hexahedron into 5 tetrahedrons
+     *         2 - split the hexahedron into 6 tetrahedrons
+     *         3 - split the hexahedron into 24 tetrahedrons
+     */
+    void SplitVolumesIntoTetra(in SMESH_IDSource elems, in short methodFlags)
+      raises (SALOME::SALOME_Exception);
+
 
     enum Smooth_Method { LAPLACIAN_SMOOTH, CENTROIDAL_SMOOTH };
 
@@ -214,10 +282,10 @@ module SMESH
                    in Smooth_Method Method);
 
     boolean SmoothObject(in SMESH_IDSource  theObject,
-                        in long_array      IDsOfFixedNodes,
-                        in long            MaxNbOfIterations,
-                        in double          MaxAspectRatio,
-                        in Smooth_Method   Method);
+                         in long_array      IDsOfFixedNodes,
+                         in long            MaxNbOfIterations,
+                         in double          MaxAspectRatio,
+                         in Smooth_Method   Method);
 
     boolean SmoothParametric(in long_array    IDsOfElements,
                              in long_array    IDsOfFixedNodes,
@@ -235,6 +303,13 @@ module SMESH
 
     boolean ConvertFromQuadratic();
 
+    void ConvertToQuadraticObject(in boolean        theForce3d, 
+                                  in SMESH_IDSource theObject) 
+      raises (SALOME::SALOME_Exception);
+
+    void ConvertFromQuadraticObject(in SMESH_IDSource theObject)
+      raises (SALOME::SALOME_Exception);
+
     void RenumberNodes();
 
     void RenumberElements();
@@ -268,10 +343,10 @@ module SMESH
      * \param NbOfSteps - number of elements to generate from one element
      */
     void RotationSweepObject(in SMESH_IDSource  theObject,
-                            in AxisStruct      Axix,
-                            in double          AngleInRadians,
-                            in long            NbOfSteps,
-                            in double          Tolerance);
+                             in AxisStruct      Axix,
+                             in double          AngleInRadians,
+                             in long            NbOfSteps,
+                             in double          Tolerance);
     /*!
      * \brief Same as previous but additionally create groups of elements
      *  generated from elements belonging to preexisting groups
@@ -289,19 +364,19 @@ module SMESH
      * \param NbOfSteps - number of elements to generate from one element
      */
     void RotationSweepObject1D(in SMESH_IDSource  theObject,
-                              in AxisStruct      Axix,
-                              in double          AngleInRadians,
-                              in long            NbOfSteps,
-                              in double          Tolerance);
+                               in AxisStruct      Axix,
+                               in double          AngleInRadians,
+                               in long            NbOfSteps,
+                               in double          Tolerance);
     /*!
      * \brief Same as previous but additionally create groups of elements
      *  generated from elements belonging to preexisting groups
      */
     ListOfGroups RotationSweepObject1DMakeGroups(in SMESH_IDSource  theObject,
-                                                in AxisStruct      Axix,
-                                                in double          AngleInRadians,
-                                                in long            NbOfSteps,
-                                                in double          Tolerance);
+                                                 in AxisStruct      Axix,
+                                                 in double          AngleInRadians,
+                                                 in long            NbOfSteps,
+                                                 in double          Tolerance);
     /*!
      * \brief Genarate dim+1 elements by rotation of the object around axis
      * \param theObject - object containing elements to ratate
@@ -310,19 +385,19 @@ module SMESH
      * \param NbOfSteps - number of elements to generate from one element
      */
     void RotationSweepObject2D(in SMESH_IDSource  theObject,
-                              in AxisStruct      Axix,
-                              in double          AngleInRadians,
-                              in long            NbOfSteps,
-                              in double          Tolerance);
+                               in AxisStruct      Axix,
+                               in double          AngleInRadians,
+                               in long            NbOfSteps,
+                               in double          Tolerance);
     /*!
      * \brief Same as previous but additionally create groups of elements
      *  generated from elements belonging to preexisting groups
      */
     ListOfGroups RotationSweepObject2DMakeGroups(in SMESH_IDSource  theObject,
-                                                in AxisStruct      Axix,
-                                                in double          AngleInRadians,
-                                                in long            NbOfSteps,
-                                                in double          Tolerance);
+                                                 in AxisStruct      Axix,
+                                                 in double          AngleInRadians,
+                                                 in long            NbOfSteps,
+                                                 in double          Tolerance);
     /*!
      * \brief Genarate dim+1 elements by extrusion of elements along vector
      * \param IDsOfElements - elements to sweep
@@ -332,6 +407,15 @@ module SMESH
     void ExtrusionSweep(in long_array      IDsOfElements,
                         in DirStruct       StepVector,
                         in long            NbOfSteps);
+    /*!
+     * \brief Genarate dim+1 elements by extrusion of elements along vector
+     * \param IDsOfElements - elements to sweep
+     * \param StepVector - vector giving direction and distance of an extrusion step
+     * \param NbOfSteps - number of elements to generate from one element
+     */
+    void ExtrusionSweep0D(in long_array    IDsOfElements,
+                        in DirStruct       StepVector,
+                        in long            NbOfSteps);
     /*!
      * \brief Same as previous but additionally create groups of elements
      *  generated from elements belonging to preexisting groups
@@ -340,7 +424,13 @@ module SMESH
                                           in DirStruct       StepVector,
                                           in long            NbOfSteps);
    /*!
-    * Generate new elements by extrusion of theElements 
+     * \brief Same as previous but elements are nodes
+     */
+    ListOfGroups ExtrusionSweepMakeGroups0D(in long_array      IDsOfElements,
+                                          in DirStruct       StepVector,
+                                          in long            NbOfSteps);
+   /*!
+    * Generate new elements by extrusion of theElements
     * by StepVector by NbOfSteps
     * param ExtrFlags set flags for performing extrusion
     * param SewTolerance - uses for comparing locations of nodes if flag
@@ -349,8 +439,8 @@ module SMESH
     void AdvancedExtrusion(in long_array      IDsOfElements,
                            in DirStruct       StepVector,
                            in long            NbOfSteps,
-                          in long            ExtrFlags,
-                          in double          SewTolerance);
+                           in long            ExtrFlags,
+                           in double          SewTolerance);
     /*!
      * \brief Same as previous but additionally create groups of elements
      *  generated from elements belonging to preexisting groups
@@ -362,22 +452,29 @@ module SMESH
                                              in double          SewTolerance);
 
     void ExtrusionSweepObject(in SMESH_IDSource  theObject,
-                             in DirStruct       StepVector,
-                             in long            NbOfSteps);
+                              in DirStruct       StepVector,
+                              in long            NbOfSteps);
     ListOfGroups ExtrusionSweepObjectMakeGroups(in SMESH_IDSource  theObject,
                                                 in DirStruct       StepVector,
                                                 in long            NbOfSteps);
 
+    void ExtrusionSweepObject0D(in SMESH_IDSource theObject,
+                                in DirStruct      StepVector,
+                                in long           NbOfSteps);
+    ListOfGroups ExtrusionSweepObject0DMakeGroups(in SMESH_IDSource theObject,
+                                                  in DirStruct      StepVector,
+                                                  in long           NbOfSteps);
+
     void ExtrusionSweepObject1D(in SMESH_IDSource theObject,
-                               in DirStruct      StepVector,
-                               in long           NbOfSteps);
+                                in DirStruct      StepVector,
+                                in long           NbOfSteps);
     ListOfGroups ExtrusionSweepObject1DMakeGroups(in SMESH_IDSource theObject,
                                                   in DirStruct      StepVector,
                                                   in long           NbOfSteps);
 
     void ExtrusionSweepObject2D(in SMESH_IDSource theObject,
-                               in DirStruct      StepVector,
-                               in long           NbOfSteps);
+                                in DirStruct      StepVector,
+                                in long           NbOfSteps);
     ListOfGroups ExtrusionSweepObject2DMakeGroups(in SMESH_IDSource theObject,
                                                   in DirStruct      StepVector,
                                                   in long           NbOfSteps);
@@ -392,14 +489,38 @@ module SMESH
       EXTR_CANT_GET_TANGENT
       };
 
+    ListOfGroups ExtrusionAlongPathX(in long_array        IDsOfElements,
+                                     in SMESH_IDSource    Path,
+                                     in long              NodeStart,
+                                     in boolean           HasAngles,
+                                     in double_array      Angles,
+                                     in boolean           LinearVariation,
+                                     in boolean           HasRefPoint,
+                                     in PointStruct       RefPoint,
+                                     in boolean           MakeGroups,
+                                     in ElementType       ElemType,
+                                     out Extrusion_Error  Error);
+
+    ListOfGroups ExtrusionAlongPathObjX(in SMESH_IDSource    theObject,
+                                        in SMESH_IDSource    Path,
+                                        in long              NodeStart,
+                                        in boolean           HasAngles,
+                                        in double_array      Angles,
+                                        in boolean           LinearVariation,
+                                        in boolean           HasRefPoint,
+                                        in PointStruct       RefPoint,
+                                        in boolean           MakeGroups,
+                                        in ElementType       ElemType,
+                                        out Extrusion_Error  Error);
+
     Extrusion_Error ExtrusionAlongPath(in long_array        IDsOfElements,
-                                      in SMESH_Mesh        PathMesh,
-                                      in GEOM::GEOM_Object PathShape,
-                                      in long              NodeStart,
-                                      in boolean           HasAngles,
-                                      in double_array      Angles,
-                                      in boolean           HasRefPoint,
-                                      in PointStruct       RefPoint);
+                                       in SMESH_Mesh        PathMesh,
+                                       in GEOM::GEOM_Object PathShape,
+                                       in long              NodeStart,
+                                       in boolean           HasAngles,
+                                       in double_array      Angles,
+                                       in boolean           HasRefPoint,
+                                       in PointStruct       RefPoint);
     ListOfGroups ExtrusionAlongPathMakeGroups(in long_array        IDsOfElements,
                                               in SMESH_Mesh        PathMesh,
                                               in GEOM::GEOM_Object PathShape,
@@ -411,13 +532,13 @@ module SMESH
                                               out Extrusion_Error  Error);
 
     Extrusion_Error ExtrusionAlongPathObject(in SMESH_IDSource    theObject,
-                                            in SMESH_Mesh        PathMesh,
-                                            in GEOM::GEOM_Object PathShape,
-                                            in long              NodeStart,
-                                            in boolean           HasAngles,
-                                            in double_array      Angles,
-                                            in boolean           HasRefPoint,
-                                            in PointStruct       RefPoint);
+                                             in SMESH_Mesh        PathMesh,
+                                             in GEOM::GEOM_Object PathShape,
+                                             in long              NodeStart,
+                                             in boolean           HasAngles,
+                                             in double_array      Angles,
+                                             in boolean           HasRefPoint,
+                                             in PointStruct       RefPoint);
     ListOfGroups ExtrusionAlongPathObjectMakeGroups(in SMESH_IDSource    theObject,
                                                     in SMESH_Mesh        PathMesh,
                                                     in GEOM::GEOM_Object PathShape,
@@ -429,47 +550,47 @@ module SMESH
                                                     out Extrusion_Error  Error);
 
     Extrusion_Error ExtrusionAlongPathObject1D(in SMESH_IDSource    theObject,
-                                              in SMESH_Mesh        PathMesh,
-                                              in GEOM::GEOM_Object PathShape,
-                                              in long              NodeStart,
-                                              in boolean           HasAngles,
-                                              in double_array      Angles,
-                                              in boolean           HasRefPoint,
-                                              in PointStruct       RefPoint);
+                                               in SMESH_Mesh        PathMesh,
+                                               in GEOM::GEOM_Object PathShape,
+                                               in long              NodeStart,
+                                               in boolean           HasAngles,
+                                               in double_array      Angles,
+                                               in boolean           HasRefPoint,
+                                               in PointStruct       RefPoint);
     ListOfGroups ExtrusionAlongPathObject1DMakeGroups(in SMESH_IDSource    theObject,
-                                                     in SMESH_Mesh        PathMesh,
-                                                     in GEOM::GEOM_Object PathShape,
-                                                     in long              NodeStart,
-                                                     in boolean           HasAngles,
-                                                     in double_array      Angles,
-                                                     in boolean           HasRefPoint,
-                                                     in PointStruct       RefPoint,
-                                                     out Extrusion_Error  Error);
+                                                      in SMESH_Mesh        PathMesh,
+                                                      in GEOM::GEOM_Object PathShape,
+                                                      in long              NodeStart,
+                                                      in boolean           HasAngles,
+                                                      in double_array      Angles,
+                                                      in boolean           HasRefPoint,
+                                                      in PointStruct       RefPoint,
+                                                      out Extrusion_Error  Error);
 
     Extrusion_Error ExtrusionAlongPathObject2D(in SMESH_IDSource    theObject,
-                                              in SMESH_Mesh        PathMesh,
-                                              in GEOM::GEOM_Object PathShape,
-                                              in long              NodeStart,
-                                              in boolean           HasAngles,
-                                              in double_array      Angles,
-                                              in boolean           HasRefPoint,
-                                              in PointStruct       RefPoint);
+                                               in SMESH_Mesh        PathMesh,
+                                               in GEOM::GEOM_Object PathShape,
+                                               in long              NodeStart,
+                                               in boolean           HasAngles,
+                                               in double_array      Angles,
+                                               in boolean           HasRefPoint,
+                                               in PointStruct       RefPoint);
     ListOfGroups ExtrusionAlongPathObject2DMakeGroups(in SMESH_IDSource    theObject,
-                                                     in SMESH_Mesh        PathMesh,
-                                                     in GEOM::GEOM_Object PathShape,
-                                                     in long              NodeStart,
-                                                     in boolean           HasAngles,
-                                                     in double_array      Angles,
-                                                     in boolean           HasRefPoint,
-                                                     in PointStruct       RefPoint,
-                                                     out Extrusion_Error  Error);
+                                                      in SMESH_Mesh        PathMesh,
+                                                      in GEOM::GEOM_Object PathShape,
+                                                      in long              NodeStart,
+                                                      in boolean           HasAngles,
+                                                      in double_array      Angles,
+                                                      in boolean           HasRefPoint,
+                                                      in PointStruct       RefPoint,
+                                                      out Extrusion_Error  Error);
 
    /*!
     * Compute rotation angles for ExtrusionAlongPath as linear variation
     * of given angles along path steps
-    * param PathMesh mesh containing a 1D sub-mesh on the edge, along 
+    * param PathMesh mesh containing a 1D sub-mesh on the edge, along
     *                which proceeds the extrusion
-    * param PathShape is shape(edge); as the mesh can be complex, the edge 
+    * param PathShape is shape(edge); as the mesh can be complex, the edge
     *                 is used to define the sub-mesh for the path
     */
     double_array LinearAnglesVariation(in SMESH_Mesh        PathMesh,
@@ -492,9 +613,9 @@ module SMESH
                                in string     MeshName);
 
     void MirrorObject (in SMESH_IDSource theObject,
-                      in AxisStruct     Mirror,
-                      in MirrorType     Type,
-                      in boolean        Copy);
+                       in AxisStruct     Mirror,
+                       in MirrorType     Type,
+                       in boolean        Copy);
     ListOfGroups MirrorObjectMakeGroups (in SMESH_IDSource theObject,
                                          in AxisStruct     Mirror,
                                          in MirrorType     Type);
@@ -515,8 +636,8 @@ module SMESH
                                   in string     MeshName);
 
     void TranslateObject (in SMESH_IDSource theObject,
-                         in DirStruct      Vector,
-                         in boolean        Copy);
+                          in DirStruct      Vector,
+                          in boolean        Copy);
     ListOfGroups TranslateObjectMakeGroups (in SMESH_IDSource theObject,
                                             in DirStruct      Vector);
     SMESH_Mesh TranslateObjectMakeMesh (in SMESH_IDSource theObject,
@@ -524,6 +645,19 @@ module SMESH
                                         in boolean        CopyGroups,
                                         in string         MeshName);
 
+    void Scale (in SMESH_IDSource theObject,
+                in PointStruct    thePoint,
+                in double_array   theScaleFact,
+                in boolean        Copy);
+    ListOfGroups ScaleMakeGroups (in SMESH_IDSource theObject,
+                                  in PointStruct    thePoint,
+                                  in double_array   theScaleFact);
+    SMESH_Mesh ScaleMakeMesh (in SMESH_IDSource theObject,
+                              in PointStruct    thePoint,
+                              in double_array   theScaleFact,
+                              in boolean        CopyGroups,
+                              in string         MeshName);
+
     void Rotate (in long_array IDsOfElements,
                  in AxisStruct Axis,
                  in double     AngleInRadians,
@@ -538,9 +672,9 @@ module SMESH
                                in string     MeshName);
 
     void RotateObject (in SMESH_IDSource theObject,
-                      in AxisStruct     Axis,
-                      in double         AngleInRadians,
-                      in boolean        Copy);
+                       in AxisStruct     Axis,
+                       in double         AngleInRadians,
+                       in boolean        Copy);
     ListOfGroups RotateObjectMakeGroups (in SMESH_IDSource theObject,
                                          in AxisStruct     Axis,
                                          in double         AngleInRadians);
@@ -554,8 +688,13 @@ module SMESH
                               out array_of_long_array GroupsOfNodes);
 
     void FindCoincidentNodesOnPart (in  SMESH_IDSource      SubMeshOrGroup,
-                                   in  double              Tolerance,
-                                   out array_of_long_array GroupsOfNodes);
+                                    in  double              Tolerance,
+                                    out array_of_long_array GroupsOfNodes);
+
+    void FindCoincidentNodesOnPartBut (in  SMESH_IDSource      SubMeshOrGroup,
+                                       in  double              Tolerance,
+                                       out array_of_long_array GroupsOfNodes,
+                                       in  ListOfIDSources     ExceptSubMeshOrGroups);
 
     void MergeNodes (in array_of_long_array GroupsOfNodes);
 
@@ -565,7 +704,7 @@ module SMESH
      * \return List of groups of equal elements.
      */
     void FindEqualElements (in  SMESH_IDSource      MeshOrSubMeshOrGroup,
-                           out array_of_long_array GroupsOfElementsID);
+                            out array_of_long_array GroupsOfElementsID);
 
     /*!
      * \brief Merge elements in each given group.
@@ -577,13 +716,41 @@ module SMESH
      * \brief Merge equal elements in the whole mesh.
      */
     void MergeEqualElements();
-    
+
     /*!
      * If the given ID is a valid node ID (nodeID > 0), just move this node, else
      * move the node closest to the point to point's location and return ID of the node
      */
     long MoveClosestNodeToPoint(in double x, in double y, in double z, in long nodeID);
 
+    /*!
+     * Return ID of node closest to a given point
+     */
+    long FindNodeClosestTo(in double x, in double y, in double z);
+
+    /*!
+     * Return elements of given type where the given point is IN or ON.
+     *
+     * 'ALL' type means elements of any type excluding nodes and 0D elements
+     */
+    long_array FindElementsByPoint(in double x, in double y, in double z, in ElementType type);
+
+    /*!
+     * Searching among the given elements, return elements of given type 
+     * where the given point is IN or ON.
+     *
+     * 'ALL' type means elements of any type excluding nodes and 0D elements
+     */
+    long_array FindAmongElementsByPoint(in SMESH_IDSource elements,
+                                        in double x, in double y, in double z, 
+                                        in ElementType type);
+
+    /*!
+     * Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
+     * TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
+     */
+    short GetPointState(in double x, in double y, in double z);
+
     enum Sew_Error {
       SEW_OK,
       SEW_BORDER1_NOT_FOUND,
@@ -604,8 +771,8 @@ module SMESH
                               in long FirstNodeID2,
                               in long SecondNodeID2,
                               in long LastNodeID2,
-                             in boolean CreatePolygons,
-                             in boolean CreatePolyedrs);
+                              in boolean CreatePolygons,
+                              in boolean CreatePolyedrs);
 
     Sew_Error SewConformFreeBorders (in long FirstNodeID1,
                                      in long SecondNodeID1,
@@ -618,8 +785,8 @@ module SMESH
                                in long LastNodeIDOnFreeBorder,
                                in long FirstNodeIDOnSide,
                                in long LastNodeIDOnSide,
-                              in boolean CreatePolygons,
-                              in boolean CreatePolyedrs);
+                               in boolean CreatePolygons,
+                               in boolean CreatePolyedrs);
 
     Sew_Error SewSideElements (in long_array IDsOfSide1Elements,
                                in long_array IDsOfSide2Elements,
@@ -636,7 +803,7 @@ module SMESH
     boolean ChangeElemNodes(in long ide, in long_array newIDs);
 
    /*!
-    * Return data of mesh edition preview which is computed provided 
+    * Return data of mesh edition preview which is computed provided
     * that the editor was obtained trough SMESH_Mesh::GetMeshEditPreviewer()
     */
     MeshPreviewStruct GetPreviewData();
@@ -654,50 +821,302 @@ module SMESH
     * not creared - returns empty list
     */
     long_array GetLastCreatedElems();
-    
+
     /*!
      * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
      * \param theNodes - identifiers of nodes to be doubled
-     * \param theModifiedElems - identifiers of elements to be updated by the new (doubled) 
-     *        nodes. If list of element identifiers is empty then nodes are doubled but 
+     * \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
+     *        nodes. If list of element identifiers is empty then nodes are doubled but
      *        they not assigned to elements
      *        \return TRUE if operation has been completed successfully, FALSE otherwise
      * \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
-    */
-    boolean DoubleNodes( in long_array theNodes, in long_array theModifiedElems ); 
+     */
+    boolean DoubleNodes( in long_array theNodes, in long_array theModifiedElems );
 
     /*!
-    * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
-    * This method provided for convenience works as DoubleNodes() described above.
-    * \param theNodeId - identifier of node to be doubled.
-    * \param theModifiedElems - identifiers of elements to be updated.
-    * \return TRUE if operation has been completed successfully, FALSE otherwise
-    * \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
-    */
-    boolean DoubleNode( in long theNodeId, in long_array theModifiedElems ); 
+     * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+     * This method provided for convenience works as DoubleNodes() described above.
+     * \param theNodeId - identifier of node to be doubled.
+     * \param theModifiedElems - identifiers of elements to be updated.
+     * \return TRUE if operation has been completed successfully, FALSE otherwise
+     * \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
+     */
+    boolean DoubleNode( in long theNodeId, in long_array theModifiedElems );
 
     /*!
-    * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
-    * This method provided for convenience works as DoubleNodes() described above.
-    * \param theNodes - group of nodes to be doubled.
-    * \param theModifiedElems - group of elements to be updated.
-    * \return TRUE if operation has been completed successfully, FALSE otherwise
-    * \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
-    */
-    boolean DoubleNodeGroup( in SMESH_GroupBase theNodes, 
+     * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+     * This method provided for convenience works as DoubleNodes() described above.
+     * \param theNodes - group of nodes to be doubled.
+     * \param theModifiedElems - group of elements to be updated.
+     * \return TRUE if operation has been completed successfully, FALSE otherwise
+     * \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups(), DoubleNodeGroupNew()
+     */
+    boolean DoubleNodeGroup( in SMESH_GroupBase theNodes,
                              in SMESH_GroupBase theModifiedElems );
+    /*!
+     * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
+     * Works as DoubleNodeGroup() described above, but returns a new group with
+     * newly created nodes.
+     * \param theNodes - group of nodes to be doubled.
+     * \param theModifiedElems - group of elements to be updated.
+     * \return a new group with newly created nodes
+     * \sa DoubleNodeGroup()
+     */
+    SMESH_Group DoubleNodeGroupNew( in SMESH_GroupBase theNodes,
+                                    in SMESH_GroupBase theModifiedElems );
 
     /*!
-    \brief Creates a hole in a mesh by doubling the nodes of some particular elements
-    This method provided for convenience works as DoubleNodes() described above.
-    \param theNodes - list of groups of nodes to be doubled
-    \param theModifiedElems - list of groups of elements to be updated.
-    \return TRUE if operation has been completed successfully, FALSE otherwise
-    \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
-    */
-    boolean DoubleNodeGroups( in ListOfGroups theNodes, 
+     * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+     * This method provided for convenience works as DoubleNodes() described above.
+     * \param theNodes - list of groups of nodes to be doubled
+     * \param theModifiedElems - list of groups of elements to be updated.
+     * \return TRUE if operation has been completed successfully, FALSE otherwise
+     * \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
+     */
+    boolean DoubleNodeGroups( in ListOfGroups theNodes,
                               in ListOfGroups theModifiedElems );
+    /*!
+     * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+     * Works as DoubleNodeGroups() described above, but returns a new group with
+     * newly created nodes.
+     * \param theNodes - list of groups of nodes to be doubled
+     * \param theModifiedElems - list of groups of elements to be updated.
+     * \return a new group with newly created nodes
+     * \sa DoubleNodeGroups()
+     */
+    SMESH_Group DoubleNodeGroupsNew( in ListOfGroups theNodes,
+                                    in ListOfGroups theModifiedElems );
+
+    /*!
+     * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+     * \param theElems - the list of elements (edges or faces) to be replicated
+     *        The nodes for duplication could be found from these elements
+     * \param theNodesNot - list of nodes to NOT replicate
+     * \param theAffectedElems - the list of elements (cells and edges) to which the
+     *        replicated nodes should be associated to.
+     * \return TRUE if operation has been completed successfully, FALSE otherwise
+     * \sa DoubleNodeGroup(), DoubleNodeGroups()
+     */
+    boolean DoubleNodeElem( in long_array theElems,
+                            in long_array theNodesNot,
+                            in long_array theAffectedElems );
+
+    /*!
+     * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+     * \param theElems - the list of elements (edges or faces) to be replicated
+     *        The nodes for duplication could be found from these elements
+     * \param theNodesNot - list of nodes to NOT replicate
+     * \param theShape - shape to detect affected elements (element which geometric center
+     *        located on or inside shape).
+     *        The replicated nodes should be associated to affected elements.
+     * \return TRUE if operation has been completed successfully, FALSE otherwise
+     * \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
+     */
+    boolean DoubleNodeElemInRegion( in long_array theElems,
+                                    in long_array theNodesNot,
+                                    in GEOM::GEOM_Object theShape );
+
+    /*!
+     * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+     * This method provided for convenience works as DoubleNodes() described above.
+     * \param theElems - group of of elements (edges or faces) to be replicated
+     * \param theNodesNot - group of nodes not to replicated
+     * \param theAffectedElems - group of elements to which the replicated nodes
+     *        should be associated to.
+     * \return TRUE if operation has been completed successfully, FALSE otherwise
+     * \sa DoubleNodes(), DoubleNodeGroups(), DoubleNodeElemGroupNew()
+     */
+    boolean DoubleNodeElemGroup( in SMESH_GroupBase theElems,
+                                 in SMESH_GroupBase theNodesNot,
+                                 in SMESH_GroupBase theAffectedElems );
+    /*!
+     * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
+     * Works as DoubleNodeElemGroup() described above, but returns a new group with
+     * newly created elements.
+     * \param theElems - group of of elements (edges or faces) to be replicated
+     * \param theNodesNot - group of nodes not to replicated
+     * \param theAffectedElems - group of elements to which the replicated nodes
+     *        should be associated to.
+     * \return a new group with newly created elements
+     * \sa DoubleNodeElemGroup()
+     */
+    SMESH_Group DoubleNodeElemGroupNew( in SMESH_GroupBase theElems,
+                                        in SMESH_GroupBase theNodesNot,
+                                        in SMESH_GroupBase theAffectedElems );
+    /*!
+     * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
+     * Works as DoubleNodeElemGroup() described above, but returns two new groups:
+     * a group of newly created elements and a group of newly created nodes
+     * \param theElems - group of of elements (edges or faces) to be replicated
+     * \param theNodesNot - group of nodes not to replicated
+     * \param theAffectedElems - group of elements to which the replicated nodes
+     *        should be associated to.
+     * \param theElemGroupNeeded - to create group of new elements or not
+     * \param theNodeGroupNeeded - to create group of new nodes or not
+     * \return two new groups of newly created elements (1st) and nodes (2nd)
+     * \sa DoubleNodeElemGroup()
+     */
+    ListOfGroups DoubleNodeElemGroup2New( in SMESH_GroupBase theElems,
+                                          in SMESH_GroupBase theNodesNot,
+                                          in SMESH_GroupBase theAffectedElems,
+                                          in boolean         theElemGroupNeeded,
+                                          in boolean         theNodeGroupNeeded);
 
+    /*!
+     * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+     * This method provided for convenience works as DoubleNodes() described above.
+     * \param theElems - group of elements (edges or faces) to be replicated
+     * \param theNodesNot - group of nodes not to replicated
+     * \param theShape - shape to detect affected elements (element which geometric center
+     *        located on or inside shape).
+     *        The replicated nodes should be associated to affected elements.
+     * \return TRUE if operation has been completed successfully, FALSE otherwise
+     * \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
+     */
+    boolean DoubleNodeElemGroupInRegion( in SMESH_GroupBase theElems,
+                                         in SMESH_GroupBase theNodesNot,
+                                         in GEOM::GEOM_Object theShape );
+
+    /*!
+     * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+     * This method provided for convenience works as DoubleNodes() described above.
+     * \param theElems - list of groups of elements (edges or faces) to be replicated
+     * \param theNodesNot - list of groups of nodes not to replicated
+     * \param theAffectedElems - group of elements to which the replicated nodes
+     *        should be associated to.
+     * \return TRUE if operation has been completed successfully, FALSE otherwise
+     * \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
+     */
+    boolean DoubleNodeElemGroups( in ListOfGroups theElems,
+                                  in ListOfGroups theNodesNot,
+                                  in ListOfGroups theAffectedElems );
+    /*!
+     * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
+     * Works as DoubleNodeElemGroups() described above, but returns a new group with
+     * newly created elements.
+     * \param theElems - list of groups of elements (edges or faces) to be replicated
+     * \param theNodesNot - list of groups of nodes not to replicated
+     * \param theAffectedElems - group of elements to which the replicated nodes
+     *        should be associated to.
+     * \return a new group with newly created elements
+     * \sa DoubleNodeElemGroups()
+     */
+    SMESH_Group DoubleNodeElemGroupsNew( in ListOfGroups theElems,
+                                         in ListOfGroups theNodesNot,
+                                         in ListOfGroups theAffectedElems );
+    /*!
+     * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
+     * Works as DoubleNodeElemGroups() described above, but returns two new groups:
+     * a group of newly created elements and a group of newly created nodes.
+     * \param theElems - list of groups of elements (edges or faces) to be replicated
+     * \param theNodesNot - list of groups of nodes not to replicated
+     * \param theAffectedElems - group of elements to which the replicated nodes
+     *        should be associated to.
+     * \param theElemGroupNeeded - to create group of new elements or not
+     * \param theNodeGroupNeeded - to create group of new nodes or not
+     * \return two new groups of newly created elements (1st) and nodes (2nd)
+     * \sa DoubleNodeElemGroups()
+     */
+    ListOfGroups DoubleNodeElemGroups2New( in ListOfGroups theElems,
+                                           in ListOfGroups theNodesNot,
+                                           in ListOfGroups theAffectedElems,
+                                           in boolean         theElemGroupNeeded,
+                                           in boolean         theNodeGroupNeeded );
+
+    /*!
+     * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+     * This method provided for convenience works as DoubleNodes() described above.
+     * \param theElems - list of groups of elements (edges or faces) to be replicated
+     * \param theNodesNot - list of groups of nodes not to replicated
+     * \param theShape - shape to detect affected elements (element which geometric center
+     *        located on or inside shape).
+     *        The replicated nodes should be associated to affected elements.
+     * \return TRUE if operation has been completed successfully, FALSE otherwise
+     * \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
+     */
+    boolean DoubleNodeElemGroupsInRegion( in ListOfGroups theElems,
+                                          in ListOfGroups theNodesNot,
+                                          in GEOM::GEOM_Object theShape );
+
+    /*!
+     * \brief Generates skin mesh (containing 2D cells) from 3D mesh
+     * The created 2D mesh elements based on nodes of free faces of boundary volumes
+     * \return TRUE if operation has been completed successfully, FALSE otherwise
+     */
+    boolean Make2DMeshFrom3D();
+
+    /*!
+     * \brief Creates missing boundary elements
+     *  \param elements - elements whose boundary is to be checked
+     *  \param dimension - defines type of boundary elements to create
+     *    BND_1DFROM3D creates mesh edges on all borders of free facets of 3D elements.
+     *  \param groupName - a name of group to store created boundary elements in,
+     *                     "" means not to create the group
+     *  \param meshName - a name of new mesh to store created boundary elements in,
+     *                     "" means not to create the new mesh
+     *  \param toCopyElements - if true, the checked elements will be copied into the new mesh
+     *                          else only boundary elements will be copied into the new mesh
+     *  \param toCopyExistingBondary - if true, not only new but also pre-existing
+     *                                boundary elements will be copied into the new mesh
+     *  \param group - returns the create group, if any
+     *  \retval SMESH::SMESH_Mesh - the mesh where elements were added to
+     */
+    SMESH_Mesh MakeBoundaryMesh(in SMESH_IDSource elements,
+                                in Bnd_Dimension  dimension,
+                                in string         groupName,
+                                in string         meshName,
+                                in boolean        toCopyElements,
+                                in boolean        toCopyExistingBondary,
+                                out SMESH_Group   group);
+    /*!
+     * \brief Creates missing boundary elements around either the whole mesh or 
+     *    groups of 2D elements
+     *  \param dimension - defines type of boundary elements to create
+     *  \param groupName - a name of group to store all boundary elements in,
+     *    "" means not to create the group
+     *  \param meshName - a name of a new mesh, which is a copy of the initial 
+     *    mesh + created boundary elements; "" means not to create the new mesh
+     *  \param toCopyAll - if true, the whole initial mesh will be copied into
+     *    the new mesh else only boundary elements will be copied into the new mesh
+     *  \param groups - optional groups of 2D elements to make boundary around
+     *  \param mesh - returns the mesh where elements were added to
+     *  \param group - returns the created group, if any
+     *  \retval long - number of added boundary elements
+     */
+    long MakeBoundaryElements(in Bnd_Dimension   dimension,
+                              in string          groupName,
+                              in string          meshName,
+                              in boolean         toCopyAll,
+                              in ListOfIDSources groups,
+                              out SMESH_Mesh     mesh,
+                              out SMESH_Group    group) raises (SALOME::SALOME_Exception);
+
+    /*!
+     * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
+     * Flat elements are mainly used by some types of mechanic calculations.
+     *
+     * The list of groups must describe a partition of the mesh volumes.
+     * The nodes of the internal faces at the boundaries of the groups are doubled.
+     * In option, the internal faces are replaced by flat elements.
+     * Triangles are transformed in prisms, and quadrangles in hexahedrons.
+     * \param theDomains - list of groups of volumes
+     * \param createJointElems - if TRUE, create the elements
+     * \return TRUE if operation has been completed successfully, FALSE otherwise
+     */
+    boolean DoubleNodesOnGroupBoundaries( in ListOfGroups theDomains,
+                                          in boolean createJointElems ) 
+      raises (SALOME::SALOME_Exception);
+
+    /*!
+     * \brief Double nodes on some external faces and create flat elements.
+     * Flat elements are mainly used by some types of mechanic calculations.
+     *
+     * Each group of the list must be constituted of faces.
+     * Triangles are transformed in prisms, and quadrangles in hexahedrons.
+     * \param theGroupsOfFaces - list of groups of faces
+     * \return TRUE if operation has been completed successfully, FALSE otherwise
+     */
+    boolean CreateFlatElementsOnFacesGroups( in ListOfGroups theGroupsOfFaces ); 
   };
 };
 
index 4f0bcfaa6e44994c383cd063eac85874c7d87eae..85b842f8374f1053913e96a2deb8e9f9ece4f7ed 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File    : SMESH_Pattern.idl
 // Created : Mon Aug  2 10:48:36 2004
 // Author  : Edward AGAPOV (eap)
index 2ebd83edff16cbd8faf46130d2563fa68c137103..dcbb70ebc7d86a72011d7119e9b72f5c4e1937d9 100644 (file)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # -* Makefile *- 
 # Author : Patrick GOLDBRONN (CEA)
 # Date : 28/06/2001
@@ -38,6 +36,7 @@ dist_salomeres_DATA = \
        mesh_area.png \
        mesh_aspect.png \
        mesh_aspect_3d.png \
+       mesh_biquad_quadrangle.png \
        mesh_clear.png \
        mesh_compute.png \
        mesh_diagonal.png \
@@ -51,18 +50,27 @@ dist_salomeres_DATA = \
        mesh_info.png \
        advanced_mesh_info.png \
        standard_mesh_info.png \
+       mesh_elem_info.png \
+       mesh_equal_edge.png \
+       mesh_equal_face.png \
+       mesh_equal_node.png \
+       mesh_equal_volume.png \
        mesh_whatis.png \
        mesh_init.png \
        mesh_length.png \
        mesh_length_2d.png \
+       mesh_find_elem_by_point.png \
        mesh_free_edges.png \
        mesh_free_edges_2d.png \
        mesh_free_nodes.png \
+       mesh_max_element_length_2d.png \
+       mesh_max_element_length_3d.png \
        mesh_multi_edges.png \
        mesh_multi_edges_2d.png \
        mesh_line_n.png \
        mesh_line.png \
        mesh_move_node.png \
+       mesh_octahedron.png \
        mesh_orientation.png \
        mesh.png \
        mesh_polygon.png \
@@ -71,8 +79,14 @@ dist_salomeres_DATA = \
        mesh_pyramid.png \
        mesh_quad_n.png \
        mesh_quad.png \
+       mesh_quadrangle_quadpref.png \
+       mesh_quadrangle_quadpref_reversed.png \
+       mesh_quadrangle_reduced.png \
+       mesh_quadrangle_standard.png \
+       mesh_quadrangle_triapref.png \
        mesh_rem_element.png \
        mesh_rem_node.png \
+       mesh_rem_orphan_nodes.png \
        mesh_shading.png \
        mesh_shrink.png \
        mesh_skew.png \
@@ -81,6 +95,7 @@ dist_salomeres_DATA = \
        mesh_tree_algo_hexa.png \
        mesh_tree_algo_mefisto.png \
        mesh_tree_algo.png \
+       mesh_tree_algo_0D.png \
        mesh_tree_algo_quad.png \
        mesh_tree_algo_regular.png \
        mesh_tree_algo_tetra.png \
@@ -93,16 +108,22 @@ dist_salomeres_DATA = \
        mesh_tree_importedmesh.png \
        mesh_tree_mesh_warn.png \
        mesh_triangle_n.png \
+       mesh_triquad_hexahedron.png \
        mesh_triangle.png \
        mesh_update.png \
        mesh_vertex_n.png \
        mesh_vertex.png \
        mesh_volume_3d.png \
+       bare_border_volume.png \
+       bare_border_face.png \
+       over_constrained_volume.png \
+       over_constrained_face.png \
        mesh_wireframe.png \
        mesh_points.png \
        mesh_wrap.png \
        mesh_group.png \
        mesh_tree_group.png \
+       mesh_tree_group_on_filter.png \
        mesh_edit_group.png \
        mesh_make_group.png \
        mesh_groups_from_gemetry.png \
@@ -134,8 +155,8 @@ dist_salomeres_DATA = \
        mesh_merge_elements.png \
        select1.png \
        StdMeshers.xml \
-       SalomeApp.xml \
        mesh_pattern.png \
+       mesh_pentahedron.png \
        pattern_sample_2d.png \
        pattern_sample_3D.png \
        mesh_add.png \
@@ -150,6 +171,9 @@ dist_salomeres_DATA = \
        mesh_conv_to_quad.png \
        mesh_tree_hypo_layers_distribution.png \
        mesh_tree_algo_radial_prism.png \
+       mesh_tree_algo_radial_quadrangle_1D2D.png \
+       mesh_tree_algo_existing_2D.png \
+       mesh_tree_algo_prism.png \
        mesh_tree_algo_projection_2d.png \
        mesh_hypo_source_edge.png \
        mesh_hypo_source_3d.png \
@@ -161,11 +185,25 @@ dist_salomeres_DATA = \
        mesh_tree_hypo_projection_3d.png \
        mesh_tree_hypo_projection_2d.png \
        mesh_build_compound.png \
+       copy_mesh.png \
        mesh_node_to_point.png \
        mesh_tree_mesh_partial.png \
        mesh_extractGroup.png \
        mesh_precompute.png \
-        mesh_free_faces.png
+       mesh_2d_from_3d.png \
+        mesh_free_faces.png \
+        scale.png \
+        scale_along_axes.png \
+       split_into_tetra.png \
+       mesh_duplicate_nodes.png \
+       mesh_duplicate_nodes_with_elem.png \
+       mesh_bounding_box.png \
+       mesh_hypo_viscous_layers.png \
+       mesh_tree_hypo_viscous_layers.png \
+       mesh_min_dist.png \
+       reorient_faces_point.png \
+       reorient_faces_face.png \
+       mesh_ball.png
 
 # VSR: little trick to avoid putting if SMESHCatalog.xml to the distribution archive
-nodist_salomeres_SCRIPTS = SMESHCatalog.xml
+nodist_salomeres_SCRIPTS = SMESHCatalog.xml SalomeApp.xml
index 200d232973684bf574d7a256f6622c72b6dea3bb..f658219171aef5bcd7853170045d2d9b3d779d6d 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version='1.0' encoding='us-ascii' ?>
 <!--
-  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+  Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 
   Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
   CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -32,7 +32,7 @@
 </path-prefix-list>
 
 <type-list>
-  <objref name="SMESH_Mesh" id="IDL:Mesh/SMESH_Mesh:1.0"/>
+  <objref name="SMESH_Mesh" id="IDL:SMESH/SMESH_Mesh:1.0"/>
   <objref name="SMESH_Hypothesis" id="IDL:SMESH/SMESH_Hypothesis:1.0"/>
 </type-list>
 
diff --git a/resources/SalomeApp.xml b/resources/SalomeApp.xml
deleted file mode 100644 (file)
index e30cd2a..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-<!--
-  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-
-  Copyright (C) 2003-2007  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.com
-
--->
-<document>
-  <section name="SMESH">
-    <!-- Major module parameters -->
-    <parameter name="name" value="Mesh"/>
-    <parameter name="icon" value="ModuleMesh.png"/>
-    <!-- Other module preferences -->
-    <parameter name="node_color"                   value="255, 0,   0"/>
-    <parameter name="fill_color"                   value="0, 170, 255"/>
-    <parameter name="outline_color"                value="0, 170, 255"/>
-    <parameter name="backface_color"               value="0, 0,   255"/>
-    <parameter name="highlight_color"              value="0, 255, 255"/>
-    <parameter name="node_size"                    value="3" />
-    <parameter name="element_width"                value="1" />
-    <parameter name="shrink_coeff"                 value="75"/>
-    <parameter name="orientation_color"            value="255, 255, 255"/>
-    <parameter name="orientation_scale"            value="0.1"/>
-    <parameter name="orientation_3d_vectors"       value="false"/>
-    <parameter name="selection_element_color"      value="255, 255,   0"/>
-    <parameter name="selection_object_color"       value="255, 255, 255"/>
-    <parameter name="selection_precision_element"  value="0.005"/>
-    <parameter name="selection_precision_node"     value="0.005"/>
-    <parameter name="selection_precision_object"   value="0.005"/>
-    <parameter name="selection_width"              value="5"/>
-    <parameter name="highlight_width"              value="5"/>
-    <parameter name="controls_precision"           value="0"/>
-    <parameter name="scalar_bar_horizontal_height" value="0.08"/>
-    <parameter name="scalar_bar_horizontal_width"  value="0.8" />
-    <parameter name="scalar_bar_horizontal_x"      value="0.1"/>
-    <parameter name="scalar_bar_horizontal_y"      value="0.01"/>
-    <parameter name="scalar_bar_label_color"       value="255, 255, 255"/>
-    <parameter name="scalar_bar_label_font"        value="Arial,12"     />
-    <parameter name="scalar_bar_num_colors"        value="64"/>
-    <parameter name="scalar_bar_num_labels"        value="5" />
-    <parameter name="scalar_bar_orientation"       value="0" />
-    <parameter name="scalar_bar_title_color"       value="255, 255, 255"/>
-    <parameter name="scalar_bar_title_font"        value="Arial,12"     />
-    <parameter name="scalar_bar_vertical_height"   value="0.8"  />
-    <parameter name="scalar_bar_vertical_width"    value="0.08" />
-    <parameter name="scalar_bar_vertical_x"        value="0.01" />
-    <parameter name="scalar_bar_vertical_y"        value="0.1" />
-    <parameter name="DisplayMode"                  value="true" />
-    <parameter name="auto_update"                  value="true" />
-    <parameter name="display_mode"                 value="1"    />
-    <parameter name="auto_groups"                  value="false"/>
-    <parameter name="show_result_notification"     value="2"/>
-    <parameter name="segmentation"                 value="10"/>
-    <parameter name="nb_segments_per_edge"         value="15"/>
-  </section>
-  <section name="resources">
-    <!-- Module resources -->
-    <parameter name="SMESH"        value="${SMESH_ROOT_DIR}/share/salome/resources/smesh"/>
-    <parameter name="StdMeshers"   value="${SMESH_ROOT_DIR}/share/salome/resources/smesh"/>
-    <!-- NETGENPlugin and GHS3DPlugin -->
-    <!-- Here the environment variables are used as case-sensitive, -->
-    <!-- In GUI/src/SalomeApp/resources/SalomeApp.xml upper-case notation is used. -->
-    <!-- As a result, both variants are acceptable. -->
-    <parameter name="NETGENPlugin" value="${NETGENPlugin_ROOT_DIR}/share/salome/resources/netgenplugin"/>
-    <parameter name="GHS3DPlugin"  value="${GHS3DPlugin_ROOT_DIR}/share/salome/resources/ghs3dplugin"/>
-    <parameter name="BLSURFPlugin" value="${BLSURFPlugin_ROOT_DIR}/share/salome/resources"/>
-    <parameter name="HexoticPLUGIN" value="${HexoticPlugin_ROOT_DIR}/share/salome/resources"/>
-    <parameter name="GHS3DPRLPlugin" value="${GHS3DPRLPLUGIN_ROOT_DIR}/share/salome/resources"/>
-  </section>
-</document>
diff --git a/resources/SalomeApp.xml.in b/resources/SalomeApp.xml.in
new file mode 100644 (file)
index 0000000..0dbcc2e
--- /dev/null
@@ -0,0 +1,109 @@
+<!--
+  Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+
+  Copyright (C) 2003-2007  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.com
+
+-->
+<document>
+  <section name="SMESH">
+    <!-- Major module parameters -->
+    <parameter name="name" value="Mesh"/>
+    <parameter name="icon" value="ModuleMesh.png"/>
+    <parameter name="version" value="@VERSION@"/>
+    <!-- Other module preferences -->
+    <parameter name="node_color"                   value="255, 0,   0"/>
+    <parameter name="fill_color"                   value="0, 170, 255|-100"/>
+    <parameter name="wireframe_color"              value="0, 170, 255"/>
+    <parameter name="outline_color"                value="0,  70,   0"/>
+    <parameter name="elem0d_color"                 value="0, 255,   0"/>
+    <parameter name="ball_elem_color"              value="100, 255,   0"/>
+    <parameter name="highlight_color"              value="0, 255, 255"/>
+    <parameter name="group_name_color"             value="255, 255, 255"/>
+    <parameter name="type_of_marker"               value="1"  />
+    <parameter name="marker_scale"                 value="9"  />
+    <parameter name="elem0d_size"                  value="5" />
+    <parameter name="ball_elem_size"               value="10" />
+    <parameter name="element_width"                value="1" />
+    <parameter name="shrink_coeff"                 value="75"/>
+    <parameter name="orientation_color"            value="255, 255, 255"/>
+    <parameter name="orientation_scale"            value="0.1"/>
+    <parameter name="orientation_3d_vectors"       value="false"/>
+    <parameter name="selection_element_color"      value="255, 255,   0"/>
+    <parameter name="selection_object_color"       value="255, 255, 255"/>
+    <parameter name="selection_precision_element"  value="0.005"/>
+    <parameter name="selection_precision_node"     value="0.005"/>
+    <parameter name="selection_precision_object"   value="0.005"/>
+    <parameter name="controls_precision"           value="0"/>
+    <parameter name="equal_nodes_tolerance"        value="1e-7"/>
+    <parameter name="scalar_bar_horizontal_height" value="0.08"/>
+    <parameter name="scalar_bar_horizontal_width"  value="0.8" />
+    <parameter name="scalar_bar_horizontal_x"      value="0.1"/>
+    <parameter name="scalar_bar_horizontal_y"      value="0.01"/>
+    <parameter name="scalar_bar_label_color"       value="255, 255, 255"/>
+    <parameter name="scalar_bar_label_font"        value="Arial,12"     />
+    <parameter name="scalar_bar_num_colors"        value="64"/>
+    <parameter name="scalar_bar_num_labels"        value="5" />
+    <parameter name="scalar_bar_orientation"       value="1" />
+    <parameter name="scalar_bar_title_color"       value="255, 255, 255"/>
+    <parameter name="scalar_bar_title_font"        value="Arial,12"     />
+    <parameter name="scalar_bar_vertical_height"   value="0.8"  />
+    <parameter name="scalar_bar_vertical_width"    value="0.08" />
+    <parameter name="scalar_bar_vertical_x"        value="0.01" />
+    <parameter name="scalar_bar_vertical_y"        value="0.1" />
+    <parameter name="distribution_visibility"      value="false" />
+    <parameter name="distribution_coloring_type"   value="0" />
+    <parameter name="distribution_color"           value="0, 85, 0" />
+    <parameter name="DisplayMode"                  value="true" />
+    <parameter name="auto_update"                  value="true" />
+    <parameter name="update_limit"                 value="500000" />
+    <parameter name="display_entity"               value="true" />
+    <parameter name="display_mode"                 value="1"    />
+    <parameter name="auto_groups"                  value="false"/>
+    <parameter name="show_result_notification"     value="2"/>
+    <parameter name="mesh_elem_info"               value="1"/>
+    <parameter name="info_groups_nodes_limit"      value="100000"/>
+    <parameter name="segmentation"                 value="10"/>
+    <parameter name="nb_segments_per_edge"         value="15"/>
+    <parameter name="forget_mesh_on_hyp_modif"     value="false"/>
+    <parameter name="quadratic_mode"               value="0"/>
+    <parameter name="max_angle"                    value="2"/>
+    <parameter name="documentation"                value="smesh_help"/>
+    <parameter name="preview_actor_chunk_size"     value="100" />
+    <parameter name="historical_python_dump"       value="true" />
+    <!-- Input field precisions -->
+    <parameter name="def_precision"                value="3"  />
+    <parameter name="length_precision"             value="-6"  />
+    <parameter name="angle_precision"              value="-3"  />
+    <parameter name="len_tol_precision"            value="-7"  />
+    <parameter name="parametric_precision"         value="-6"  />
+    <parameter name="area_precision"               value="-6"  />
+    <parameter name="vol_precision"                value="-6"  />
+  </section>
+  <section name="smesh_help" >
+    <parameter name="sub_menu"          value="%1 module"/>
+    <parameter name="User's Guide"      value="%SMESH_ROOT_DIR%/share/doc/salome/gui/SMESH/index.html"/>
+    <parameter name="Developer's Guide" value="%SMESH_ROOT_DIR%/share/doc/salome/tui/SMESH/index.html"/>
+  </section>
+  <section name="resources">
+    <!-- Module resources -->
+    <parameter name="SMESH"        value="%SMESH_ROOT_DIR%/share/salome/resources/smesh"/>
+    <parameter name="StdMeshers"   value="%SMESH_ROOT_DIR%/share/salome/resources/smesh"/>
+  </section>
+</document>
index 4adf93e83eb002565033a74f26dd1a0636b3c7e6..0d519fc574f21a5ca809d7ec8e1490c937bdd598 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version='1.0' encoding='us-ascii'?>
 <!DOCTYPE meshers PUBLIC "" "desktop.dtd">
 <!--
-  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+  Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 
   Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
   CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -40,7 +40,7 @@
                 dim="0"/>
 
     <hypothesis type="LocalLength"
-                label-id="Average length"
+                label-id="Local Length"
                 icon-id="mesh_hypo_length.png"
                 dim="1"/>
 
                 icon-id="mesh_hypo_length.png"
                 dim="1"/>
 
+    <hypothesis type="FixedPoints1D"
+                label-id="Fixed points 1D"
+                icon-id="mesh_hypo_length.png"
+                dim="1"/>
+
     <hypothesis type="StartEndLength"
                 label-id="Start and End Length"
                 icon-id="mesh_hypo_length.png"
                 auxiliary="true"
                 dim="2"/>
 
-    <hypothesis        type="TrianglePreference"
-               label-id="Triangle Preference"
-                icon-id="mesh_algo_mefisto.png"
-               auxiliary="true"
-               dim="2"/>
-               
     <hypothesis type="QuadraticMesh"
                 label-id="Quadratic Mesh"
                 icon-id="mesh_algo_quad.png"
     <hypothesis type="MaxElementVolume"
                 label-id="Max. Element Volume"
                 icon-id="mesh_hypo_volume.png"
-               need-geom = "false"
                 dim="3"/>
 
     <hypothesis type="ProjectionSource3D"
                 icon-id="mesh_hypo_length.png"
                 dim="1"/>
 
+    <hypothesis type="ImportSource2D"
+                label-id="Source Faces"
+                icon-id="mesh_hypo_area.png"
+                dim="2"/>
+
+    <hypothesis type="ImportSource1D"
+                label-id="Source Edges"
+                icon-id="mesh_hypo_length.png"
+                dim="1"/>
+
     <hypothesis type="NumberOfLayers"
                 label-id="Number of Layers"
                 icon-id="mesh_hypo_length.png"
                 label-id="Distribution of Layers"
                 icon-id="mesh_hypo_length.png"
                 dim="3"/>
+
+    <hypothesis type="ViscousLayers"
+                label-id="Viscous Layers"
+                icon-id="mesh_algo_quad.png"
+                auxiliary="true"
+                dim="3"/>
+
+    <hypothesis type="NumberOfLayers2D"
+                label-id="Number of Layers"
+                icon-id="mesh_hypo_length.png"
+                dim="2"/>
+
+    <hypothesis type="LayerDistribution2D"
+                label-id="Distribution of Layers"
+                icon-id="mesh_hypo_length.png"
+                dim="2"/>
+
+    <hypothesis type="QuadrangleParams"
+                label-id="Quadrangle Parameters"
+                icon-id="mesh_hypo_length.png"
+                dim="2"/>
+
+    <hypothesis type="CartesianParameters3D"
+                label-id="Body Fitting Parameters"
+                icon-id="mesh_hypo_length.png"
+                dim="3"/>
+
   </hypotheses>
 
   <algorithms>
     <algorithm type="Regular_1D"
               label-id="Wire discretisation"
               icon-id="mesh_algo_regular.png"
-               hypos="LocalLength,MaxLength,Arithmetic1D,StartEndLength,NumberOfSegments,Deflection1D,AutomaticLength"
+               hypos="LocalLength,MaxLength,Arithmetic1D,StartEndLength,NumberOfSegments,Deflection1D,AutomaticLength,FixedPoints1D"
                opt-hypos="Propagation,QuadraticMesh"
                input="VERTEX"
                output="EDGE"
-               dim="1"/>
+               dim="1">
+      <python-wrap>
+        <algo>Regular_1D=Segment()</algo>
+        <hypo>LocalLength=LocalLength(SetLength(1),,SetPrecision(1))</hypo>
+        <hypo>MaxLength=MaxSize(SetLength(1))</hypo>
+        <hypo>Arithmetic1D=Arithmetic1D(SetStartLength(),SetEndLength(),SetReversedEdges())</hypo>
+        <hypo>StartEndLength=StartEndLength(SetStartLength(),SetEndLength(),SetReversedEdges())</hypo>
+        <hypo>Deflection1D=Deflection1D(SetDeflection())</hypo>
+        <hypo>AutomaticLength=AutomaticLength(SetFineness())</hypo>
+        <hypo>FixedPoints1D=FixedPoints1D(SetPoints(),SetNbSegments(),SetReversedEdges())</hypo>
+        <hypo>Propagation=Propagation()</hypo>
+        <hypo>QuadraticMesh=QuadraticMesh()</hypo>
+      </python-wrap>
+    </algorithm>
 
     <algorithm type="CompositeSegment_1D"
               label-id="Composite side discretisation"
               icon-id="mesh_algo_regular.png"
-               hypos="LocalLength,MaxLength,Arithmetic1D,StartEndLength,NumberOfSegments,Deflection1D,AutomaticLength"
+               hypos="LocalLength,MaxLength,Arithmetic1D,StartEndLength,NumberOfSegments,Deflection1D,AutomaticLength,FixedPoints1D"
                opt-hypos="Propagation,QuadraticMesh"
                input="VERTEX"
                output="EDGE"
-               dim="1"/>
+               dim="1">
+      <python-wrap>
+        <algo>CompositeSegment_1D=Segment(algo=smesh.COMPOSITE)</algo>
+        <hypo>LocalLength=LocalLength(SetLength(), ,SetPrecision())</hypo>
+        <hypo>MaxLength=MaxSize(SetLength())</hypo>
+        <hypo>Arithmetic1D=Arithmetic1D(SetStartLength(),SetEndLength(),SetReversedEdges())</hypo>
+        <hypo>StartEndLength=StartEndLength(SetStartLength(),SetEndLength(),SetReversedEdges())</hypo>
+        <hypo>Deflection1D=Deflection1D(SetDeflection())</hypo>
+        <hypo>AutomaticLength=AutomaticLength(SetFineness())</hypo>
+        <hypo>FixedPoints1D=FixedPoints1D(SetPoints(),SetNbSegments(),SetReversedEdges())</hypo>
+        <hypo>Propagation=Propagation()</hypo>
+        <hypo>QuadraticMesh=QuadraticMesh()</hypo>
+      </python-wrap>
+    </algorithm>
+
+    <algorithm type="Python_1D"
+               output="EDGE"
+               dim="1">
+      <python-wrap>
+        <algo>Python_1D=Segment(algo=smesh.PYTHON)</algo>
+        <hypo>PythonSplit1D=PythonSplit1D(SetNumberOfSegments(),SetPythonLog10RatioFunction())</hypo>
+      </python-wrap>
+    </algorithm>
 
     <algorithm type="MEFISTO_2D"
               label-id="Triangle (Mefisto)"
                hypos="LengthFromEdges,MaxElementArea"
                input="EDGE"
                output="TRIA"
-               dim="2"/>
+               dim="2">
+      <python-wrap>
+        <algo>MEFISTO_2D=Triangle(algo=smesh.MEFISTO)</algo>
+        <hypo>LengthFromEdges=LengthFromEdges()</hypo>
+        <hypo>MaxElementArea=MaxElementArea(SetMaxElementArea())</hypo>
+      </python-wrap>
+    </algorithm>
 
     <algorithm type="Quadrangle_2D"
                label-id="Quadrangle (Mapping)"
                icon-id="mesh_algo_quad.png"
-               opt-hypos="QuadranglePreference,TrianglePreference"
+               hypos="QuadrangleParams"
                input="EDGE"
                output="QUAD"
-               dim="2"/>
+               dim="2">
+      <python-wrap>
+        <algo>Quadrangle_2D=Quadrangle(algo=smesh.QUADRANGLE)</algo>
+        <hypo>QuadrangleParams=QuadrangleParameters(SetQuadType(),SetTriaVertex())</hypo>
+      </python-wrap>
+    </algorithm>
 
     <algorithm type="Hexa_3D"
                label-id="Hexahedron (i,j,k)"
                icon-id="mesh_algo_hexa.png"
                input="QUAD"
-               dim="3"/>
+              need-geom="false"
+               opt-hypos="ViscousLayers"
+               dim="3">
+      <python-wrap>
+        <algo>Hexa_3D=Hexahedron(algo=smesh.Hexa)</algo>
+        <hypo>ViscousLayers=ViscousLayers(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetIgnoreFaces())</hypo>
+      </python-wrap>
+    </algorithm>
 
     <algorithm type="Projection_1D"
                label-id="Projection 1D"
                icon-id="mesh_algo_regular.png"
                hypos="ProjectionSource1D"
                output="EDGE"
-               dim="1"/>
+               dim="1">
+      <python-wrap>
+        <algo>Projection_1D=Projection1D()</algo>
+        <hypo>ProjectionSource1D=SourceEdge(SetSourceEdge(),SetSourceMesh(),SetVertexAssociation(1),SetVertexAssociation(2))</hypo>
+      </python-wrap>
+    </algorithm>
 
     <algorithm type="Projection_2D"
                label-id="Projection 2D"
                input="EDGE"
                hypos="ProjectionSource2D"
                output="QUAD,TRIA"
-               dim="2"/>
+               dim="2">
+      <python-wrap>
+        <algo>Projection_2D=Projection2D()</algo>
+        <hypo>ProjectionSource2D=SourceFace(SetSourceFace(),SetSourceMesh(),SetVertexAssociation(1),SetVertexAssociation(2),SetVertexAssociation(3),SetVertexAssociation(4))</hypo>
+      </python-wrap>
+    </algorithm>
+
+    <algorithm type="Projection_1D2D"
+               label-id="Projection 1D-2D"
+               icon-id="mesh_algo_quad.png"
+               input=""
+               hypos="ProjectionSource2D"
+               output="QUAD,TRIA"
+               dim="2">
+      <python-wrap>
+        <algo>Projection_1D2D=Projection1D2D()</algo>
+        <hypo>ProjectionSource2D=SourceFace(SetSourceFace(),SetSourceMesh(),SetVertexAssociation(1),SetVertexAssociation(2),SetVertexAssociation(3),SetVertexAssociation(4))</hypo>
+      </python-wrap>
+    </algorithm>
 
     <algorithm type="Projection_3D"
                label-id="Projection 3D"
                icon-id="mesh_algo_hexa.png"
                hypos="ProjectionSource3D"
                input="QUAD,TRIA"
-               dim="3"/>
+               dim="3">
+      <python-wrap>
+        <algo>Projection_3D=Projection3D()</algo>
+        <hypo>ProjectionSource3D=SourceShape3D(SetSource3DShape(),SetSourceMesh(),SetVertexAssociation(1),SetVertexAssociation(2),SetVertexAssociation(3),SetVertexAssociation(4))</hypo>
+      </python-wrap>
+    </algorithm>
+
+    <algorithm type="Import_1D"
+               label-id="Use existing 1D elements"
+               icon-id="mesh_algo_regular.png"
+               hypos="ImportSource1D"
+               output="EDGE"
+               dim="1">
+      <python-wrap>
+        <algo>Import_1D=UseExisting1DElements()</algo>
+        <hypo>ImportSource1D=SourceEdges(SetSourceEdges(),SetCopySourceMesh(1),SetCopySourceMesh(2))</hypo>
+      </python-wrap>
+    </algorithm>
+
+    <algorithm type="Import_1D2D"
+               label-id="Use existing 2D elements"
+               icon-id="mesh_algo_quad.png"
+               hypos="ImportSource2D"
+               output="QUAD,TRIA"
+               support-submeshes="false"
+               dim="2">
+      <python-wrap>
+        <algo>Import_1D2D=UseExisting2DElements()</algo>
+        <hypo>ImportSource2D=SourceFaces(SetSourceFaces(),SetCopySourceMesh(1),SetCopySourceMesh(2))</hypo>
+      </python-wrap>
+    </algorithm>
 
     <algorithm type="Prism_3D"
                label-id="3D extrusion"
                icon-id="mesh_algo_hexa.png"
                input="QUAD,TRIA"
-               dim="3"/>
+               dim="3">
+      <python-wrap>
+        <algo>Prism_3D=Prism()</algo>
+      </python-wrap>
+    </algorithm>
 
     <algorithm type="RadialPrism_3D"
                label-id="Radial Prism 3D"
                icon-id="mesh_algo_hexa.png"
                hypos="NumberOfLayers, LayerDistribution"
                input="QUAD,TRIA"
-               dim="3"/>
+               dim="3">
+      <python-wrap>
+        <algo>RadialPrism_3D=Prism('RadialPrism_3D')</algo>
+        <hypo>NumberOfLayers=NumberOfLayers(SetNumberOfLayers())</hypo>
+      </python-wrap>
+    </algorithm>
 
     <algorithm type="UseExisting_1D"
                label-id="Use existing edges"
                icon-id="mesh_algo_regular.png"
                input="VERTEX"
                output="EDGE"
-               dim="1"/>
+               dim="1">
+      <python-wrap>
+        <algo>UseExisting_1D=UseExistingSegments()</algo>
+      </python-wrap>
+    </algorithm>
 
     <algorithm type="UseExisting_2D"
                label-id="Use existing faces"
                icon-id="mesh_algo_quad.png"
                input="EDGE"
                output="QUAD,TRIA"
-               dim="2"/>
+               dim="2">
+      <python-wrap>
+        <algo>UseExisting_2D=UseExistingFaces()</algo>
+      </python-wrap>
+    </algorithm>
+
+    <algorithm type="RadialQuadrangle_1D2D"
+               label-id="Radial quadrangle 1D2D"
+               icon-id="mesh_algo_quad.png"
+               hypos="NumberOfLayers2D, LayerDistribution2D"
+               input="EDGE"
+               output="QUAD,TRIA"
+               dim="2">
+      <python-wrap>
+        <algo>RadialQuadrangle_1D2D=Quadrangle(algo=smesh.RADIAL_QUAD)</algo>
+        <hypo>NumberOfLayers2D=NumberOfLayers(SetNumberOfLayers())</hypo>
+      </python-wrap>
+    </algorithm>
+
+    <algorithm type="Cartesian_3D"
+               label-id="Body Fitting"
+               icon-id="mesh_algo_hexa.png"
+               hypos="CartesianParameters3D"
+               support-submeshes="false"
+               dim="3">
+      <python-wrap>
+        <algo>Cartesian_3D=BodyFitted()</algo>
+      </python-wrap>
+    </algorithm>
 
   </algorithms>
 </meshers-group>
                     hypos="NumberOfSegments"
                     algos="Regular_1D, Quadrangle_2D, Hexa_3D"/>
 
+    <hypotheses-set name="Automatic Triangulation"
+                    hypos="MaxLength"
+                    algos="Regular_1D, MEFISTO_2D"/>
+
+    <hypotheses-set name="Automatic Quadrangulation"
+                    hypos="NumberOfSegments"
+                    algos="Regular_1D, Quadrangle_2D"/>
+
 </hypotheses-set-group>
 
 </meshers>
index 44ce337d960d7c1474218cf22ffb4cc0a269e543..6e5b3176bc67ae89e0b55398dff8f90a58084dae 100644 (file)
Binary files a/resources/advanced_mesh_info.png and b/resources/advanced_mesh_info.png differ
diff --git a/resources/bare_border_face.png b/resources/bare_border_face.png
new file mode 100644 (file)
index 0000000..1993f20
Binary files /dev/null and b/resources/bare_border_face.png differ
diff --git a/resources/bare_border_volume.png b/resources/bare_border_volume.png
new file mode 100644 (file)
index 0000000..3ef6e6a
Binary files /dev/null and b/resources/bare_border_volume.png differ
diff --git a/resources/copy_mesh.png b/resources/copy_mesh.png
new file mode 100644 (file)
index 0000000..263479f
Binary files /dev/null and b/resources/copy_mesh.png differ
diff --git a/resources/mesh_2d_from_3d.png b/resources/mesh_2d_from_3d.png
new file mode 100644 (file)
index 0000000..b0842d3
Binary files /dev/null and b/resources/mesh_2d_from_3d.png differ
diff --git a/resources/mesh_ball.png b/resources/mesh_ball.png
new file mode 100644 (file)
index 0000000..ad6c92d
Binary files /dev/null and b/resources/mesh_ball.png differ
diff --git a/resources/mesh_biquad_quadrangle.png b/resources/mesh_biquad_quadrangle.png
new file mode 100644 (file)
index 0000000..9d66e0a
Binary files /dev/null and b/resources/mesh_biquad_quadrangle.png differ
diff --git a/resources/mesh_bounding_box.png b/resources/mesh_bounding_box.png
new file mode 100755 (executable)
index 0000000..f01bae8
Binary files /dev/null and b/resources/mesh_bounding_box.png differ
diff --git a/resources/mesh_duplicate_nodes.png b/resources/mesh_duplicate_nodes.png
new file mode 100644 (file)
index 0000000..0f800f7
Binary files /dev/null and b/resources/mesh_duplicate_nodes.png differ
diff --git a/resources/mesh_duplicate_nodes_with_elem.png b/resources/mesh_duplicate_nodes_with_elem.png
new file mode 100644 (file)
index 0000000..7a313aa
Binary files /dev/null and b/resources/mesh_duplicate_nodes_with_elem.png differ
diff --git a/resources/mesh_elem_info.png b/resources/mesh_elem_info.png
new file mode 100644 (file)
index 0000000..9937d6d
Binary files /dev/null and b/resources/mesh_elem_info.png differ
diff --git a/resources/mesh_equal_edge.png b/resources/mesh_equal_edge.png
new file mode 100644 (file)
index 0000000..027fad2
Binary files /dev/null and b/resources/mesh_equal_edge.png differ
diff --git a/resources/mesh_equal_face.png b/resources/mesh_equal_face.png
new file mode 100644 (file)
index 0000000..e2a5983
Binary files /dev/null and b/resources/mesh_equal_face.png differ
diff --git a/resources/mesh_equal_node.png b/resources/mesh_equal_node.png
new file mode 100644 (file)
index 0000000..1ca5b65
Binary files /dev/null and b/resources/mesh_equal_node.png differ
diff --git a/resources/mesh_equal_volume.png b/resources/mesh_equal_volume.png
new file mode 100644 (file)
index 0000000..e0a0bac
Binary files /dev/null and b/resources/mesh_equal_volume.png differ
diff --git a/resources/mesh_find_elem_by_point.png b/resources/mesh_find_elem_by_point.png
new file mode 100644 (file)
index 0000000..d4d1784
Binary files /dev/null and b/resources/mesh_find_elem_by_point.png differ
diff --git a/resources/mesh_hypo_viscous_layers.png b/resources/mesh_hypo_viscous_layers.png
new file mode 100644 (file)
index 0000000..9223c61
Binary files /dev/null and b/resources/mesh_hypo_viscous_layers.png differ
diff --git a/resources/mesh_max_element_length_2d.png b/resources/mesh_max_element_length_2d.png
new file mode 100755 (executable)
index 0000000..d0120fa
Binary files /dev/null and b/resources/mesh_max_element_length_2d.png differ
diff --git a/resources/mesh_max_element_length_3d.png b/resources/mesh_max_element_length_3d.png
new file mode 100755 (executable)
index 0000000..7b6b895
Binary files /dev/null and b/resources/mesh_max_element_length_3d.png differ
diff --git a/resources/mesh_min_dist.png b/resources/mesh_min_dist.png
new file mode 100755 (executable)
index 0000000..6713caf
Binary files /dev/null and b/resources/mesh_min_dist.png differ
diff --git a/resources/mesh_octahedron.png b/resources/mesh_octahedron.png
new file mode 100644 (file)
index 0000000..23ff0fd
Binary files /dev/null and b/resources/mesh_octahedron.png differ
diff --git a/resources/mesh_pentahedron.png b/resources/mesh_pentahedron.png
new file mode 100644 (file)
index 0000000..78f40c9
Binary files /dev/null and b/resources/mesh_pentahedron.png differ
diff --git a/resources/mesh_quadrangle_quadpref.png b/resources/mesh_quadrangle_quadpref.png
new file mode 100644 (file)
index 0000000..429a610
Binary files /dev/null and b/resources/mesh_quadrangle_quadpref.png differ
diff --git a/resources/mesh_quadrangle_quadpref_reversed.png b/resources/mesh_quadrangle_quadpref_reversed.png
new file mode 100644 (file)
index 0000000..fb530ea
Binary files /dev/null and b/resources/mesh_quadrangle_quadpref_reversed.png differ
diff --git a/resources/mesh_quadrangle_reduced.png b/resources/mesh_quadrangle_reduced.png
new file mode 100644 (file)
index 0000000..985c236
Binary files /dev/null and b/resources/mesh_quadrangle_reduced.png differ
diff --git a/resources/mesh_quadrangle_standard.png b/resources/mesh_quadrangle_standard.png
new file mode 100644 (file)
index 0000000..957a0f2
Binary files /dev/null and b/resources/mesh_quadrangle_standard.png differ
diff --git a/resources/mesh_quadrangle_triapref.png b/resources/mesh_quadrangle_triapref.png
new file mode 100644 (file)
index 0000000..d14440d
Binary files /dev/null and b/resources/mesh_quadrangle_triapref.png differ
diff --git a/resources/mesh_rem_orphan_nodes.png b/resources/mesh_rem_orphan_nodes.png
new file mode 100644 (file)
index 0000000..16df2e5
Binary files /dev/null and b/resources/mesh_rem_orphan_nodes.png differ
diff --git a/resources/mesh_tree_algo_0D.png b/resources/mesh_tree_algo_0D.png
new file mode 100644 (file)
index 0000000..5725a17
Binary files /dev/null and b/resources/mesh_tree_algo_0D.png differ
diff --git a/resources/mesh_tree_algo_existing_2D.png b/resources/mesh_tree_algo_existing_2D.png
new file mode 100644 (file)
index 0000000..db0de78
Binary files /dev/null and b/resources/mesh_tree_algo_existing_2D.png differ
diff --git a/resources/mesh_tree_algo_prism.png b/resources/mesh_tree_algo_prism.png
new file mode 100644 (file)
index 0000000..0025d48
Binary files /dev/null and b/resources/mesh_tree_algo_prism.png differ
diff --git a/resources/mesh_tree_algo_radial_quadrangle_1D2D.png b/resources/mesh_tree_algo_radial_quadrangle_1D2D.png
new file mode 100644 (file)
index 0000000..234ed30
Binary files /dev/null and b/resources/mesh_tree_algo_radial_quadrangle_1D2D.png differ
diff --git a/resources/mesh_tree_group_on_filter.png b/resources/mesh_tree_group_on_filter.png
new file mode 100644 (file)
index 0000000..0d76d82
Binary files /dev/null and b/resources/mesh_tree_group_on_filter.png differ
diff --git a/resources/mesh_tree_hypo_viscous_layers.png b/resources/mesh_tree_hypo_viscous_layers.png
new file mode 100644 (file)
index 0000000..694a4aa
Binary files /dev/null and b/resources/mesh_tree_hypo_viscous_layers.png differ
diff --git a/resources/mesh_triquad_hexahedron.png b/resources/mesh_triquad_hexahedron.png
new file mode 100644 (file)
index 0000000..06e18a6
Binary files /dev/null and b/resources/mesh_triquad_hexahedron.png differ
diff --git a/resources/over_constrained_face.png b/resources/over_constrained_face.png
new file mode 100644 (file)
index 0000000..22b61bb
Binary files /dev/null and b/resources/over_constrained_face.png differ
diff --git a/resources/over_constrained_volume.png b/resources/over_constrained_volume.png
new file mode 100644 (file)
index 0000000..0e2da26
Binary files /dev/null and b/resources/over_constrained_volume.png differ
diff --git a/resources/reorient_faces_face.png b/resources/reorient_faces_face.png
new file mode 100644 (file)
index 0000000..23c241f
Binary files /dev/null and b/resources/reorient_faces_face.png differ
diff --git a/resources/reorient_faces_point.png b/resources/reorient_faces_point.png
new file mode 100644 (file)
index 0000000..63fae72
Binary files /dev/null and b/resources/reorient_faces_point.png differ
diff --git a/resources/scale.png b/resources/scale.png
new file mode 100644 (file)
index 0000000..d838d9f
Binary files /dev/null and b/resources/scale.png differ
diff --git a/resources/scale_along_axes.png b/resources/scale_along_axes.png
new file mode 100644 (file)
index 0000000..04a4ae0
Binary files /dev/null and b/resources/scale_along_axes.png differ
diff --git a/resources/split_into_tetra.png b/resources/split_into_tetra.png
new file mode 100644 (file)
index 0000000..b113c30
Binary files /dev/null and b/resources/split_into_tetra.png differ
index 0dd516e946bdda88f5cf355c50054aab1f0674b0..ea7904a61283431c9950adb06083fc84d3668ac4 100644 (file)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  File   : Makefile.in
 #  Author : Patrick GOLDBRONN (CEA)
 #  Modified by : Alexander BORODIN (OCN) - autotools usage
@@ -28,7 +26,6 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am
 
 # header files 
 salomeinclude_HEADERS = \
-       SMESH_Controls.hxx \
        SMESH_ControlsDef.hxx
 
 # Libraries targets
@@ -45,15 +42,19 @@ dist_SMESHControls_SOURCES = \
 # additionnal information to compil and link file
 libSMESHControls_la_CPPFLAGS = \
        $(CAS_CPPFLAGS) \
+        $(VTK_INCLUDES) \
        $(BOOST_CPPFLAGS) \
        $(KERNEL_CXXFLAGS) \
        -I$(srcdir)/../SMDS \
-       -I$(srcdir)/../SMESHDS
+       -I$(srcdir)/../SMESHDS \
+       -I$(srcdir)/../SMESHUtils
 
 libSMESHControls_la_LDFLAGS = \
        ../SMDS/libSMDS.la \
        ../SMESHDS/libSMESHDS.la \
-       $(CAS_LDPATH) -lTKernel -lTKBRep -lTKG3d
+       ../SMESHUtils/libSMESHUtils.la \
+       $(CAS_LDPATH) -lTKernel -lTKBRep -lTKG3d -lTKTopAlgo -lTKGeomBase -lTKGeomAlgo \
+       $(VTK_LIBS)
 
 SMESHControls_CPPFLAGS = \
        $(libSMESHControls_la_CPPFLAGS)
index e12427015a0b244aee2099ac659aef5815ade6c4..a1fb1f92f47c3162ccf1a057ab5e5b06779ef0d2 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #include "SMESH_ControlsDef.hxx"
 
 int main(int argc, char** argv)
@@ -30,6 +31,8 @@ int main(int argc, char** argv)
   new Taper();
   new Skew();
   new Area();
+  new MaxElementLength2D();
+  new MaxElementLength3D();
   new Length();
   //  new Length2D();
   new MultiConnection();
index 8ba13a8f1f4e0727d548282be267cb69b4fbe571..f9540e0046d526846c6e05291de07438572c5509 100644 (file)
@@ -1,50 +1,57 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #include "SMESH_ControlsDef.hxx"
 
-#include <set>
+#include "SMDS_BallElement.hxx"
+#include "SMDS_Iterator.hxx"
+#include "SMDS_Mesh.hxx"
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_QuadraticEdge.hxx"
+#include "SMDS_QuadraticFaceOfNodes.hxx"
+#include "SMDS_VolumeTool.hxx"
+#include "SMESHDS_GroupBase.hxx"
+#include "SMESHDS_Mesh.hxx"
+#include "SMESH_OctreeNode.hxx"
 
 #include <BRepAdaptor_Surface.hxx>
 #include <BRepClass_FaceClassifier.hxx>
 #include <BRep_Tool.hxx>
-
-#include <TopAbs.hxx>
-#include <TopoDS.hxx>
-#include <TopoDS_Edge.hxx>
-#include <TopoDS_Face.hxx>
-#include <TopoDS_Shape.hxx>
-#include <TopoDS_Vertex.hxx>
-#include <TopoDS_Iterator.hxx>
-
 #include <Geom_CylindricalSurface.hxx>
 #include <Geom_Plane.hxx>
 #include <Geom_Surface.hxx>
-
 #include <Precision.hxx>
 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
 #include <TColStd_MapOfInteger.hxx>
 #include <TColStd_SequenceOfAsciiString.hxx>
 #include <TColgp_Array1OfXYZ.hxx>
-
+#include <TopAbs.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopoDS_Vertex.hxx>
 #include <gp_Ax3.hxx>
 #include <gp_Cylinder.hxx>
 #include <gp_Dir.hxx>
 #include <gp_Vec.hxx>
 #include <gp_XYZ.hxx>
 
-#include "SMDS_Mesh.hxx"
-#include "SMDS_Iterator.hxx"
-#include "SMDS_MeshElement.hxx"
-#include "SMDS_MeshNode.hxx"
-#include "SMDS_VolumeTool.hxx"
-#include "SMDS_QuadraticFaceOfNodes.hxx"
-#include "SMDS_QuadraticEdge.hxx"
+#include <vtkMeshQuality.h>
+
+#include <set>
+#include <limits>
 
-#include "SMESHDS_Mesh.hxx"
-#include "SMESHDS_GroupBase.hxx"
 
 /*
                             AUXILIARY METHODS
 */
 
 namespace{
+
+  inline gp_XYZ gpXYZ(const SMDS_MeshNode* aNode )
+  {
+    return gp_XYZ(aNode->X(), aNode->Y(), aNode->Z() );
+  }
+
   inline double getAngle( const gp_XYZ& P1, const gp_XYZ& P2, const gp_XYZ& P3 )
   {
     gp_Vec v1( P1 - P2 ), v2( P3 - P2 );
@@ -149,27 +157,47 @@ namespace{
 //     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++;
-//       }
-//     }
+//      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;
   }
 
+  gp_XYZ getNormale( const SMDS_MeshFace* theFace, bool* ok=0 )
+  {
+    int aNbNode = theFace->NbNodes();
+
+    gp_XYZ q1 = gpXYZ( theFace->GetNode(1)) - gpXYZ( theFace->GetNode(0));
+    gp_XYZ q2 = gpXYZ( theFace->GetNode(2)) - gpXYZ( theFace->GetNode(0));
+    gp_XYZ n  = q1 ^ q2;
+    if ( aNbNode > 3 ) {
+      gp_XYZ q3 = gpXYZ( theFace->GetNode(3)) - gpXYZ( theFace->GetNode(0));
+      n += q2 ^ q3;
+    }
+    double len = n.Modulus();
+    bool zeroLen = ( len <= numeric_limits<double>::min());
+    if ( !zeroLen )
+      n /= len;
+
+    if (ok) *ok = !zeroLen;
+
+    return n;
+  }
 }
 
 
@@ -177,8 +205,8 @@ namespace{
 using namespace SMESH::Controls;
 
 /*
-                                FUNCTORS
-*/
*                               FUNCTORS
+ */
 
 /*
   Class       : NumericalFunctor
@@ -222,11 +250,11 @@ bool NumericalFunctor::GetPoints(const SMDS_MeshElement* anElem,
   if ( anElem->IsQuadratic() ) {
     switch ( anElem->GetType() ) {
     case SMDSAbs_Edge:
-      anIter = static_cast<const SMDS_QuadraticEdge*>
+      anIter = dynamic_cast<const SMDS_VtkEdge*>
         (anElem)->interlacedNodesElemIterator();
       break;
     case SMDSAbs_Face:
-      anIter = static_cast<const SMDS_QuadraticFaceOfNodes*>
+      anIter = dynamic_cast<const SMDS_VtkFace*>
         (anElem)->interlacedNodesElemIterator();
       break;
     default:
@@ -256,24 +284,109 @@ long  NumericalFunctor::GetPrecision() const
 void  NumericalFunctor::SetPrecision( const long thePrecision )
 {
   myPrecision = thePrecision;
+  myPrecisionValue = pow( 10., (double)( myPrecision ) );
 }
 
 double NumericalFunctor::GetValue( long theId )
 {
+  double aVal = 0;
+
   myCurrElement = myMesh->FindElement( theId );
+
   TSequenceOfXYZ P;
   if ( GetPoints( theId, P ))
+    aVal = Round( GetValue( P ));
+
+  return aVal;
+}
+
+double NumericalFunctor::Round( const double & aVal )
+{
+  return ( myPrecision >= 0 ) ? floor( aVal * myPrecisionValue + 0.5 ) / myPrecisionValue : aVal;
+}
+
+//================================================================================
+/*!
+ * \brief Return histogram of functor values
+ *  \param nbIntervals - number of intervals
+ *  \param nbEvents - number of mesh elements having values within i-th interval
+ *  \param funValues - boundaries of intervals
+ *  \param elements - elements to check vulue of; empty list means "of all"
+ *  \param minmax - boundaries of diapason of values to divide into intervals
+ */
+//================================================================================
+
+void NumericalFunctor::GetHistogram(int                  nbIntervals,
+                                    std::vector<int>&    nbEvents,
+                                    std::vector<double>& funValues,
+                                    const vector<int>&   elements,
+                                    const double*        minmax)
+{
+  if ( nbIntervals < 1 ||
+       !myMesh ||
+       !myMesh->GetMeshInfo().NbElements( GetType() ))
+    return;
+  nbEvents.resize( nbIntervals, 0 );
+  funValues.resize( nbIntervals+1 );
+
+  // get all values sorted
+  std::multiset< double > values;
+  if ( elements.empty() )
   {
-    double aVal = GetValue( P );
-    if ( myPrecision >= 0 )
+    SMDS_ElemIteratorPtr elemIt = myMesh->elementsIterator(GetType());
+    while ( elemIt->more() )
+      values.insert( GetValue( elemIt->next()->GetID() ));
+  }
+  else
+  {
+    vector<int>::const_iterator id = elements.begin();
+    for ( ; id != elements.end(); ++id )
+      values.insert( GetValue( *id ));
+  }
+
+  if ( minmax )
+  {
+    funValues[0] = minmax[0];
+    funValues[nbIntervals] = minmax[1];
+  }
+  else
+  {
+    funValues[0] = *values.begin();
+    funValues[nbIntervals] = *values.rbegin();
+  }
+  // case nbIntervals == 1
+  if ( nbIntervals == 1 )
+  {
+    nbEvents[0] = values.size();
+    return;
+  }
+  // case of 1 value
+  if (funValues.front() == funValues.back())
+  {
+    nbEvents.resize( 1 );
+    nbEvents[0] = values.size();
+    funValues[1] = funValues.back();
+    funValues.resize( 2 );
+  }
+  // generic case
+  std::multiset< double >::iterator min = values.begin(), max;
+  for ( int i = 0; i < nbIntervals; ++i )
+  {
+    // find end value of i-th interval
+    double r = (i+1) / double( nbIntervals );
+    funValues[i+1] = funValues.front() * (1-r) + funValues.back() * r;
+
+    // count values in the i-th interval if there are any
+    if ( min != values.end() && *min <= funValues[i+1] )
     {
-      double prec = pow( 10., (double)( myPrecision ) );
-      aVal = floor( aVal * prec + 0.5 ) / prec;
+      // find the first value out of the interval
+      max = values.upper_bound( funValues[i+1] ); // max is greater than funValues[i+1], or end()
+      nbEvents[i] = std::distance( min, max );
+      min = max;
     }
-    return aVal;
   }
-
-  return 0.;
+  // add values larger than minmax[1]
+  nbEvents.back() += std::distance( min, values.end() );
 }
 
 //=======================================================================
@@ -312,6 +425,252 @@ SMDSAbs_ElementType Volume::GetType() const
 }
 
 
+/*
+  Class       : MaxElementLength2D
+  Description : Functor calculating maximum length of 2D element
+*/
+
+double MaxElementLength2D::GetValue( long theElementId )
+{
+  TSequenceOfXYZ P;
+  if( GetPoints( theElementId, P ) ) {
+    double aVal = 0;
+    const SMDS_MeshElement* aElem = myMesh->FindElement( theElementId );
+    SMDSAbs_ElementType aType = aElem->GetType();
+    int len = P.size();
+    switch( aType ) {
+    case SMDSAbs_Face:
+      if( len == 3 ) { // triangles
+        double L1 = getDistance(P( 1 ),P( 2 ));
+        double L2 = getDistance(P( 2 ),P( 3 ));
+        double L3 = getDistance(P( 3 ),P( 1 ));
+        aVal = Max(L1,Max(L2,L3));
+        break;
+      }
+      else if( len == 4 ) { // quadrangles
+        double L1 = getDistance(P( 1 ),P( 2 ));
+        double L2 = getDistance(P( 2 ),P( 3 ));
+        double L3 = getDistance(P( 3 ),P( 4 ));
+        double L4 = getDistance(P( 4 ),P( 1 ));
+        double D1 = getDistance(P( 1 ),P( 3 ));
+        double D2 = getDistance(P( 2 ),P( 4 ));
+        aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(D1,D2));
+        break;
+      }
+      else if( len == 6 ) { // quadratic triangles
+        double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 ));
+        double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 ));
+        double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 1 ));
+        aVal = Max(L1,Max(L2,L3));
+        break;
+      }
+      else if( len == 8 || len == 9 ) { // quadratic quadrangles
+        double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 ));
+        double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 ));
+        double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 7 ));
+        double L4 = getDistance(P( 7 ),P( 8 )) + getDistance(P( 8 ),P( 1 ));
+        double D1 = getDistance(P( 1 ),P( 5 ));
+        double D2 = getDistance(P( 3 ),P( 7 ));
+        aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(D1,D2));
+        break;
+      }
+    }
+
+    if( myPrecision >= 0 )
+    {
+      double prec = pow( 10., (double)myPrecision );
+      aVal = floor( aVal * prec + 0.5 ) / prec;
+    }
+    return aVal;
+  }
+  return 0.;
+}
+
+double MaxElementLength2D::GetBadRate( double Value, int /*nbNodes*/ ) const
+{
+  return Value;
+}
+
+SMDSAbs_ElementType MaxElementLength2D::GetType() const
+{
+  return SMDSAbs_Face;
+}
+
+/*
+  Class       : MaxElementLength3D
+  Description : Functor calculating maximum length of 3D element
+*/
+
+double MaxElementLength3D::GetValue( long theElementId )
+{
+  TSequenceOfXYZ P;
+  if( GetPoints( theElementId, P ) ) {
+    double aVal = 0;
+    const SMDS_MeshElement* aElem = myMesh->FindElement( theElementId );
+    SMDSAbs_ElementType aType = aElem->GetType();
+    int len = P.size();
+    switch( aType ) {
+    case SMDSAbs_Volume:
+      if( len == 4 ) { // tetras
+        double L1 = getDistance(P( 1 ),P( 2 ));
+        double L2 = getDistance(P( 2 ),P( 3 ));
+        double L3 = getDistance(P( 3 ),P( 1 ));
+        double L4 = getDistance(P( 1 ),P( 4 ));
+        double L5 = getDistance(P( 2 ),P( 4 ));
+        double L6 = getDistance(P( 3 ),P( 4 ));
+        aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+        break;
+      }
+      else if( len == 5 ) { // pyramids
+        double L1 = getDistance(P( 1 ),P( 2 ));
+        double L2 = getDistance(P( 2 ),P( 3 ));
+        double L3 = getDistance(P( 3 ),P( 4 ));
+        double L4 = getDistance(P( 4 ),P( 1 ));
+        double L5 = getDistance(P( 1 ),P( 5 ));
+        double L6 = getDistance(P( 2 ),P( 5 ));
+        double L7 = getDistance(P( 3 ),P( 5 ));
+        double L8 = getDistance(P( 4 ),P( 5 ));
+        aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+        aVal = Max(aVal,Max(L7,L8));
+        break;
+      }
+      else if( len == 6 ) { // pentas
+        double L1 = getDistance(P( 1 ),P( 2 ));
+        double L2 = getDistance(P( 2 ),P( 3 ));
+        double L3 = getDistance(P( 3 ),P( 1 ));
+        double L4 = getDistance(P( 4 ),P( 5 ));
+        double L5 = getDistance(P( 5 ),P( 6 ));
+        double L6 = getDistance(P( 6 ),P( 4 ));
+        double L7 = getDistance(P( 1 ),P( 4 ));
+        double L8 = getDistance(P( 2 ),P( 5 ));
+        double L9 = getDistance(P( 3 ),P( 6 ));
+        aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+        aVal = Max(aVal,Max(Max(L7,L8),L9));
+        break;
+      }
+      else if( len == 8 ) { // hexas
+        double L1 = getDistance(P( 1 ),P( 2 ));
+        double L2 = getDistance(P( 2 ),P( 3 ));
+        double L3 = getDistance(P( 3 ),P( 4 ));
+        double L4 = getDistance(P( 4 ),P( 1 ));
+        double L5 = getDistance(P( 5 ),P( 6 ));
+        double L6 = getDistance(P( 6 ),P( 7 ));
+        double L7 = getDistance(P( 7 ),P( 8 ));
+        double L8 = getDistance(P( 8 ),P( 5 ));
+        double L9 = getDistance(P( 1 ),P( 5 ));
+        double L10= getDistance(P( 2 ),P( 6 ));
+        double L11= getDistance(P( 3 ),P( 7 ));
+        double L12= getDistance(P( 4 ),P( 8 ));
+        double D1 = getDistance(P( 1 ),P( 7 ));
+        double D2 = getDistance(P( 2 ),P( 8 ));
+        double D3 = getDistance(P( 3 ),P( 5 ));
+        double D4 = getDistance(P( 4 ),P( 6 ));
+        aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+        aVal = Max(aVal,Max(Max(L7,L8),Max(L9,L10)));
+        aVal = Max(aVal,Max(L11,L12));
+        aVal = Max(aVal,Max(Max(D1,D2),Max(D3,D4)));
+        break;
+      }
+      else if( len == 12 ) { // hexagonal prism
+        for ( int i1 = 1; i1 < 12; ++i1 )
+          for ( int i2 = i1+1; i1 <= 12; ++i1 )
+            aVal = Max( aVal, getDistance(P( i1 ),P( i2 )));
+        break;
+      }
+      else if( len == 10 ) { // quadratic tetras
+        double L1 = getDistance(P( 1 ),P( 5 )) + getDistance(P( 5 ),P( 2 ));
+        double L2 = getDistance(P( 2 ),P( 6 )) + getDistance(P( 6 ),P( 3 ));
+        double L3 = getDistance(P( 3 ),P( 7 )) + getDistance(P( 7 ),P( 1 ));
+        double L4 = getDistance(P( 1 ),P( 8 )) + getDistance(P( 8 ),P( 4 ));
+        double L5 = getDistance(P( 2 ),P( 9 )) + getDistance(P( 9 ),P( 4 ));
+        double L6 = getDistance(P( 3 ),P( 10 )) + getDistance(P( 10 ),P( 4 ));
+        aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+        break;
+      }
+      else if( len == 13 ) { // quadratic pyramids
+        double L1 = getDistance(P( 1 ),P( 6 )) + getDistance(P( 6 ),P( 2 ));
+        double L2 = getDistance(P( 2 ),P( 7 )) + getDistance(P( 7 ),P( 3 ));
+        double L3 = getDistance(P( 3 ),P( 8 )) + getDistance(P( 8 ),P( 4 ));
+        double L4 = getDistance(P( 4 ),P( 9 )) + getDistance(P( 9 ),P( 1 ));
+        double L5 = getDistance(P( 1 ),P( 10 )) + getDistance(P( 10 ),P( 5 ));
+        double L6 = getDistance(P( 2 ),P( 11 )) + getDistance(P( 11 ),P( 5 ));
+        double L7 = getDistance(P( 3 ),P( 12 )) + getDistance(P( 12 ),P( 5 ));
+        double L8 = getDistance(P( 4 ),P( 13 )) + getDistance(P( 13 ),P( 5 ));
+        aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+        aVal = Max(aVal,Max(L7,L8));
+        break;
+      }
+      else if( len == 15 ) { // quadratic pentas
+        double L1 = getDistance(P( 1 ),P( 7 )) + getDistance(P( 7 ),P( 2 ));
+        double L2 = getDistance(P( 2 ),P( 8 )) + getDistance(P( 8 ),P( 3 ));
+        double L3 = getDistance(P( 3 ),P( 9 )) + getDistance(P( 9 ),P( 1 ));
+        double L4 = getDistance(P( 4 ),P( 10 )) + getDistance(P( 10 ),P( 5 ));
+        double L5 = getDistance(P( 5 ),P( 11 )) + getDistance(P( 11 ),P( 6 ));
+        double L6 = getDistance(P( 6 ),P( 12 )) + getDistance(P( 12 ),P( 4 ));
+        double L7 = getDistance(P( 1 ),P( 13 )) + getDistance(P( 13 ),P( 4 ));
+        double L8 = getDistance(P( 2 ),P( 14 )) + getDistance(P( 14 ),P( 5 ));
+        double L9 = getDistance(P( 3 ),P( 15 )) + getDistance(P( 15 ),P( 6 ));
+        aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+        aVal = Max(aVal,Max(Max(L7,L8),L9));
+        break;
+      }
+      else if( len == 20 || len == 27 ) { // quadratic hexas
+        double L1 = getDistance(P( 1 ),P( 9 )) + getDistance(P( 9 ),P( 2 ));
+        double L2 = getDistance(P( 2 ),P( 10 )) + getDistance(P( 10 ),P( 3 ));
+        double L3 = getDistance(P( 3 ),P( 11 )) + getDistance(P( 11 ),P( 4 ));
+        double L4 = getDistance(P( 4 ),P( 12 )) + getDistance(P( 12 ),P( 1 ));
+        double L5 = getDistance(P( 5 ),P( 13 )) + getDistance(P( 13 ),P( 6 ));
+        double L6 = getDistance(P( 6 ),P( 14 )) + getDistance(P( 14 ),P( 7 ));
+        double L7 = getDistance(P( 7 ),P( 15 )) + getDistance(P( 15 ),P( 8 ));
+        double L8 = getDistance(P( 8 ),P( 16 )) + getDistance(P( 16 ),P( 5 ));
+        double L9 = getDistance(P( 1 ),P( 17 )) + getDistance(P( 17 ),P( 5 ));
+        double L10= getDistance(P( 2 ),P( 18 )) + getDistance(P( 18 ),P( 6 ));
+        double L11= getDistance(P( 3 ),P( 19 )) + getDistance(P( 19 ),P( 7 ));
+        double L12= getDistance(P( 4 ),P( 20 )) + getDistance(P( 20 ),P( 8 ));
+        double D1 = getDistance(P( 1 ),P( 7 ));
+        double D2 = getDistance(P( 2 ),P( 8 ));
+        double D3 = getDistance(P( 3 ),P( 5 ));
+        double D4 = getDistance(P( 4 ),P( 6 ));
+        aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+        aVal = Max(aVal,Max(Max(L7,L8),Max(L9,L10)));
+        aVal = Max(aVal,Max(L11,L12));
+        aVal = Max(aVal,Max(Max(D1,D2),Max(D3,D4)));
+        break;
+      }
+      else if( len > 1 && aElem->IsPoly() ) { // polys
+        // get the maximum distance between all pairs of nodes
+        for( int i = 1; i <= len; i++ ) {
+          for( int j = 1; j <= len; j++ ) {
+            if( j > i ) { // optimization of the loop
+              double D = getDistance( P(i), P(j) );
+              aVal = Max( aVal, D );
+            }
+          }
+        }
+      }
+    }
+
+    if( myPrecision >= 0 )
+    {
+      double prec = pow( 10., (double)myPrecision );
+      aVal = floor( aVal * prec + 0.5 ) / prec;
+    }
+    return aVal;
+  }
+  return 0.;
+}
+
+double MaxElementLength3D::GetBadRate( double Value, int /*nbNodes*/ ) const
+{
+  return Value;
+}
+
+SMDSAbs_ElementType MaxElementLength3D::GetType() const
+{
+  return SMDSAbs_Volume;
+}
+
+
 /*
   Class       : MinimumAngle
   Description : Functor for calculation of minimum angle
@@ -332,7 +691,7 @@ double MinimumAngle::GetValue( const TSequenceOfXYZ& P )
     aMin = Min(aMin,A0);
   }
 
-  return aMin * 180.0 / PI;
+  return aMin * 180.0 / M_PI;
 }
 
 double MinimumAngle::GetBadRate( double Value, int nbNodes ) const
@@ -352,6 +711,26 @@ SMDSAbs_ElementType MinimumAngle::GetType() const
   Class       : AspectRatio
   Description : Functor for calculating aspect ratio
 */
+double AspectRatio::GetValue( long theId )
+{
+  double aVal = 0;
+  myCurrElement = myMesh->FindElement( theId );
+  if ( myCurrElement && myCurrElement->GetVtkType() == VTK_QUAD )
+  {
+    // issue 21723
+    vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myCurrElement->getMeshId()]->getGrid();
+    if ( vtkCell* avtkCell = grid->GetCell( myCurrElement->getVtkId() ))
+      aVal = Round( vtkMeshQuality::QuadAspectRatio( avtkCell ));
+  }
+  else
+  {
+    TSequenceOfXYZ P;
+    if ( GetPoints( myCurrElement, P ))
+      aVal = Round( GetValue( P ));
+  }
+  return aVal;
+}
+
 double AspectRatio::GetValue( const TSequenceOfXYZ& P )
 {
   // According to "Mesh quality control" by Nadir Bouhamau referring to
@@ -407,55 +786,103 @@ double AspectRatio::GetValue( const TSequenceOfXYZ& P )
     return alfa * maxLen * half_perimeter / anArea;
   }
   else if( nbNodes == 4 ) { // quadrangle
-    // return aspect ratio of the worst triange which can be built
+    // Compute lengths of the sides
+    std::vector< double > aLen (4);
+    aLen[0] = getDistance( P(1), P(2) );
+    aLen[1] = getDistance( P(2), P(3) );
+    aLen[2] = getDistance( P(3), P(4) );
+    aLen[3] = getDistance( P(4), P(1) );
+    // Compute lengths of the diagonals
+    std::vector< double > aDia (2);
+    aDia[0] = getDistance( P(1), P(3) );
+    aDia[1] = getDistance( P(2), P(4) );
+    // Compute areas of all triangles which can be built
     // taking three nodes of the quadrangle
-    TSequenceOfXYZ triaPnts(3);
-    // triangle on nodes 1 3 2
-    triaPnts(1) = P(1);
-    triaPnts(2) = P(3);
-    triaPnts(3) = P(2);
-    double ar = GetValue( triaPnts );
-    // triangle on nodes 1 3 4
-    triaPnts(3) = P(4);
-    ar = Max ( ar, GetValue( triaPnts ));
-    // triangle on nodes 1 2 4
-    triaPnts(2) = P(2);
-    ar = Max ( ar, GetValue( triaPnts ));
-    // triangle on nodes 3 2 4
-    triaPnts(1) = P(3);
-    ar = Max ( ar, GetValue( triaPnts ));
-
-    return ar;
-  }
-  else { // nbNodes==8 - quadratic quadrangle
-    // return aspect ratio of the worst triange which can be built
+    std::vector< double > anArea (4);
+    anArea[0] = getArea( P(1), P(2), P(3) );
+    anArea[1] = getArea( P(1), P(2), P(4) );
+    anArea[2] = getArea( P(1), P(3), P(4) );
+    anArea[3] = getArea( P(2), P(3), P(4) );
+    // Q = alpha * L * C1 / C2, where
+    //
+    // alpha = sqrt( 1/32 )
+    // L = max( L1, L2, L3, L4, D1, D2 )
+    // C1 = sqrt( ( L1^2 + L1^2 + L1^2 + L1^2 ) / 4 )
+    // C2 = min( S1, S2, S3, S4 )
+    // Li - lengths of the edges
+    // Di - lengths of the diagonals
+    // Si - areas of the triangles
+    const double alpha = sqrt( 1 / 32. );
+    double L = Max( aLen[ 0 ],
+                 Max( aLen[ 1 ],
+                   Max( aLen[ 2 ],
+                     Max( aLen[ 3 ],
+                       Max( aDia[ 0 ], aDia[ 1 ] ) ) ) ) );
+    double C1 = sqrt( ( aLen[0] * aLen[0] +
+                        aLen[1] * aLen[1] +
+                        aLen[2] * aLen[2] +
+                        aLen[3] * aLen[3] ) / 4. );
+    double C2 = Min( anArea[ 0 ],
+                  Min( anArea[ 1 ],
+                    Min( anArea[ 2 ], anArea[ 3 ] ) ) );
+    if ( C2 <= Precision::Confusion() )
+      return 0.;
+    return alpha * L * C1 / C2;
+  }
+  else if( nbNodes == 8 || nbNodes == 9 ) { // nbNodes==8 - quadratic quadrangle
+    // Compute lengths of the sides
+    std::vector< double > aLen (4);
+    aLen[0] = getDistance( P(1), P(3) );
+    aLen[1] = getDistance( P(3), P(5) );
+    aLen[2] = getDistance( P(5), P(7) );
+    aLen[3] = getDistance( P(7), P(1) );
+    // Compute lengths of the diagonals
+    std::vector< double > aDia (2);
+    aDia[0] = getDistance( P(1), P(5) );
+    aDia[1] = getDistance( P(3), P(7) );
+    // Compute areas of all triangles which can be built
     // taking three nodes of the quadrangle
-    TSequenceOfXYZ triaPnts(3);
-    // triangle on nodes 1 3 2
-    triaPnts(1) = P(1);
-    triaPnts(2) = P(5);
-    triaPnts(3) = P(3);
-    double ar = GetValue( triaPnts );
-    // triangle on nodes 1 3 4
-    triaPnts(3) = P(7);
-    ar = Max ( ar, GetValue( triaPnts ));
-    // triangle on nodes 1 2 4
-    triaPnts(2) = P(3);
-    ar = Max ( ar, GetValue( triaPnts ));
-    // triangle on nodes 3 2 4
-    triaPnts(1) = P(5);
-    ar = Max ( ar, GetValue( triaPnts ));
-
-    return ar;
+    std::vector< double > anArea (4);
+    anArea[0] = getArea( P(1), P(3), P(5) );
+    anArea[1] = getArea( P(1), P(3), P(7) );
+    anArea[2] = getArea( P(1), P(5), P(7) );
+    anArea[3] = getArea( P(3), P(5), P(7) );
+    // Q = alpha * L * C1 / C2, where
+    //
+    // alpha = sqrt( 1/32 )
+    // L = max( L1, L2, L3, L4, D1, D2 )
+    // C1 = sqrt( ( L1^2 + L1^2 + L1^2 + L1^2 ) / 4 )
+    // C2 = min( S1, S2, S3, S4 )
+    // Li - lengths of the edges
+    // Di - lengths of the diagonals
+    // Si - areas of the triangles
+    const double alpha = sqrt( 1 / 32. );
+    double L = Max( aLen[ 0 ],
+                 Max( aLen[ 1 ],
+                   Max( aLen[ 2 ],
+                     Max( aLen[ 3 ],
+                       Max( aDia[ 0 ], aDia[ 1 ] ) ) ) ) );
+    double C1 = sqrt( ( aLen[0] * aLen[0] +
+                        aLen[1] * aLen[1] +
+                        aLen[2] * aLen[2] +
+                        aLen[3] * aLen[3] ) / 4. );
+    double C2 = Min( anArea[ 0 ],
+                  Min( anArea[ 1 ],
+                    Min( anArea[ 2 ], anArea[ 3 ] ) ) );
+    if ( C2 <= Precision::Confusion() )
+      return 0.;
+    return alpha * L * C1 / C2;
   }
+  return 0;
 }
 
 double AspectRatio::GetBadRate( double Value, int /*nbNodes*/ ) const
 {
   // the aspect ratio is in the range [1.0,infinity]
+  // < 1.0 = very bad, zero area
   // 1.0 = good
   // infinity = bad
-  return Value / 1000.;
+  return ( Value < 0.9 ) ? 1000 : Value / 1000.;
 }
 
 SMDSAbs_ElementType AspectRatio::GetType() const
@@ -476,9 +903,9 @@ namespace{
 
   inline double getArea(double theHalfPerim, double theTria[3]){
     return sqrt(theHalfPerim*
-               (theHalfPerim-theTria[0])*
-               (theHalfPerim-theTria[1])*
-               (theHalfPerim-theTria[2]));
+                (theHalfPerim-theTria[0])*
+                (theHalfPerim-theTria[1])*
+                (theHalfPerim-theTria[2]));
   }
 
   inline double getVolume(double theLen[6]){
@@ -530,6 +957,28 @@ namespace{
 
 }
 
+double AspectRatio3D::GetValue( long theId )
+{
+  double aVal = 0;
+  myCurrElement = myMesh->FindElement( theId );
+  if ( myCurrElement && myCurrElement->GetVtkType() == VTK_TETRA )
+  {
+    // Action from CoTech | ACTION 31.3:
+    // EURIWARE BO: Homogenize the formulas used to calculate the Controls in SMESH to fit with
+    // those of ParaView. The library used by ParaView for those calculations can be reused in SMESH.
+    vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myCurrElement->getMeshId()]->getGrid();
+    if ( vtkCell* avtkCell = grid->GetCell( myCurrElement->getVtkId() ))
+      aVal = Round( vtkMeshQuality::TetAspectRatio( avtkCell ));
+  }
+  else
+  {
+    TSequenceOfXYZ P;
+    if ( GetPoints( myCurrElement, P ))
+      aVal = Round( GetValue( P ));
+  }
+  return aVal;
+}
+
 double AspectRatio3D::GetValue( const TSequenceOfXYZ& P )
 {
   double aQuality = 0.0;
@@ -542,10 +991,11 @@ double AspectRatio3D::GetValue( const TSequenceOfXYZ& P )
     else if(nbNodes==13) nbNodes=5; // quadratic pyramid
     else if(nbNodes==15) nbNodes=6; // quadratic pentahedron
     else if(nbNodes==20) nbNodes=8; // quadratic hexahedron
+    else if(nbNodes==27) nbNodes=8; // quadratic hexahedron
     else return aQuality;
   }
 
-  switch(nbNodes){
+  switch(nbNodes) {
   case 4:{
     double aLen[6] = {
       getDistance(P( 1 ),P( 2 )), // a
@@ -763,7 +1213,22 @@ double AspectRatio3D::GetValue( const TSequenceOfXYZ& P )
     }
     break;
   }
-  }
+  case 12:
+    {
+      gp_XYZ aXYZ[8] = {P( 1 ),P( 2 ),P( 4 ),P( 5 ),P( 7 ),P( 8 ),P( 10 ),P( 11 )};
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[8])),aQuality);
+    }
+    {
+      gp_XYZ aXYZ[8] = {P( 2 ),P( 3 ),P( 5 ),P( 6 ),P( 8 ),P( 9 ),P( 11 ),P( 12 )};
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[8])),aQuality);
+    }
+    {
+      gp_XYZ aXYZ[8] = {P( 3 ),P( 4 ),P( 6 ),P( 1 ),P( 9 ),P( 10 ),P( 12 ),P( 7 )};
+      aQuality = std::max(GetValue(TSequenceOfXYZ(&aXYZ[0],&aXYZ[8])),aQuality);
+    }
+    break;
+  } // switch(nbNodes)
+
   if ( nbNodes > 4 ) {
     // avaluate aspect ratio of quadranle faces
     AspectRatio aspect2D;
@@ -831,12 +1296,12 @@ double Warping::ComputeA( const gp_XYZ& thePnt1,
   gp_XYZ N  = GI.Crossed( GJ );
 
   if ( N.Modulus() < gp::Resolution() )
-    return PI / 2;
+    return M_PI / 2;
 
   N.Normalize();
 
   double H = ( thePnt2 - theG ).Dot( N );
-  return asin( fabs( H / L ) ) * 180. / PI;
+  return asin( fabs( H / L ) ) * 180. / M_PI;
 }
 
 double Warping::GetBadRate( double Value, int /*nbNodes*/ ) const
@@ -915,14 +1380,14 @@ double Skew::GetValue( const TSequenceOfXYZ& P )
     return 0.;
 
   // Compute skew
-  static double PI2 = PI / 2.;
+  static double PI2 = M_PI / 2.;
   if ( P.size() == 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;
+    return Max( A0, Max( A1, A2 ) ) * 180. / M_PI;
   }
   else
   {
@@ -939,7 +1404,7 @@ double Skew::GetValue( const TSequenceOfXYZ& P )
     if ( A < Precision::Angular() )
       return 0.;
 
-    return A * 180. / PI;
+    return A * 180. / M_PI;
   }
 }
 
@@ -963,16 +1428,20 @@ SMDSAbs_ElementType Skew::GetType() const
 */
 double Area::GetValue( const TSequenceOfXYZ& P )
 {
-  gp_Vec aVec1( P(2) - P(1) );
-  gp_Vec aVec2( P(3) - P(1) );
-  gp_Vec SumVec = aVec1 ^ aVec2;
-  for (int i=4; i<=P.size(); i++) {
-    gp_Vec aVec1( P(i-1) - P(1) );
-    gp_Vec aVec2( P(i) - P(1) );
-    gp_Vec tmp = aVec1 ^ aVec2;
-    SumVec.Add(tmp);
+  double val = 0.0;
+  if ( P.size() > 2 ) {
+    gp_Vec aVec1( P(2) - P(1) );
+    gp_Vec aVec2( P(3) - P(1) );
+    gp_Vec SumVec = aVec1 ^ aVec2;
+    for (int i=4; i<=P.size(); i++) {
+      gp_Vec aVec1( P(i-1) - P(1) );
+      gp_Vec aVec2( P(i) - P(1) );
+      gp_Vec tmp = aVec1 ^ aVec2;
+      SumVec.Add(tmp);
+    }
+    val = SumVec.Magnitude() * 0.5;
   }
-  return SumVec.Magnitude() * 0.5;
+  return val;
 }
 
 double Area::GetBadRate( double Value, int /*nbNodes*/ ) const
@@ -989,7 +1458,7 @@ SMDSAbs_ElementType Area::GetType() const
 
 /*
   Class       : Length
-  Description : Functor for calculating length off edge
+  Description : Functor for calculating length of edge
 */
 double Length::GetValue( const TSequenceOfXYZ& P )
 {
@@ -1036,160 +1505,160 @@ double Length2D::GetValue( long theElementId)
     case SMDSAbs_Node:
     case SMDSAbs_Edge:
       if (len == 2){
-       aVal = getDistance( P( 1 ), P( 2 ) );
+        aVal = getDistance( P( 1 ), P( 2 ) );
         break;
       }
       else if (len == 3){ // quadratic edge
-       aVal = getDistance(P( 1 ),P( 3 )) + getDistance(P( 3 ),P( 2 ));
+        aVal = getDistance(P( 1 ),P( 3 )) + getDistance(P( 3 ),P( 2 ));
         break;
       }
     case SMDSAbs_Face:
       if (len == 3){ // triangles
-       double L1 = getDistance(P( 1 ),P( 2 ));
-       double L2 = getDistance(P( 2 ),P( 3 ));
-       double L3 = getDistance(P( 3 ),P( 1 ));
-       aVal = Max(L1,Max(L2,L3));
-       break;
+        double L1 = getDistance(P( 1 ),P( 2 ));
+        double L2 = getDistance(P( 2 ),P( 3 ));
+        double L3 = getDistance(P( 3 ),P( 1 ));
+        aVal = Max(L1,Max(L2,L3));
+        break;
       }
       else if (len == 4){ // quadrangles
-       double L1 = getDistance(P( 1 ),P( 2 ));
-       double L2 = getDistance(P( 2 ),P( 3 ));
-       double L3 = getDistance(P( 3 ),P( 4 ));
-       double L4 = getDistance(P( 4 ),P( 1 ));
-       aVal = Max(Max(L1,L2),Max(L3,L4));
-       break;
+        double L1 = getDistance(P( 1 ),P( 2 ));
+        double L2 = getDistance(P( 2 ),P( 3 ));
+        double L3 = getDistance(P( 3 ),P( 4 ));
+        double L4 = getDistance(P( 4 ),P( 1 ));
+        aVal = Max(Max(L1,L2),Max(L3,L4));
+        break;
       }
       if (len == 6){ // quadratic triangles
-       double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 ));
-       double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 ));
-       double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 1 ));
-       aVal = Max(L1,Max(L2,L3));
+        double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 ));
+        double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 ));
+        double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 1 ));
+        aVal = Max(L1,Max(L2,L3));
         //cout<<"L1="<<L1<<" L2="<<L2<<"L3="<<L3<<" aVal="<<aVal<<endl;
-       break;
+        break;
       }
       else if (len == 8){ // quadratic quadrangles
-       double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 ));
-       double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 ));
-       double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 7 ));
-       double L4 = getDistance(P( 7 ),P( 8 )) + getDistance(P( 8 ),P( 1 ));
-       aVal = Max(Max(L1,L2),Max(L3,L4));
-       break;
+        double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 ));
+        double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 ));
+        double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 7 ));
+        double L4 = getDistance(P( 7 ),P( 8 )) + getDistance(P( 8 ),P( 1 ));
+        aVal = Max(Max(L1,L2),Max(L3,L4));
+        break;
       }
     case SMDSAbs_Volume:
       if (len == 4){ // tetraidrs
-       double L1 = getDistance(P( 1 ),P( 2 ));
-       double L2 = getDistance(P( 2 ),P( 3 ));
-       double L3 = getDistance(P( 3 ),P( 1 ));
-       double L4 = getDistance(P( 1 ),P( 4 ));
-       double L5 = getDistance(P( 2 ),P( 4 ));
-       double L6 = getDistance(P( 3 ),P( 4 ));
-       aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
-       break;
+        double L1 = getDistance(P( 1 ),P( 2 ));
+        double L2 = getDistance(P( 2 ),P( 3 ));
+        double L3 = getDistance(P( 3 ),P( 1 ));
+        double L4 = getDistance(P( 1 ),P( 4 ));
+        double L5 = getDistance(P( 2 ),P( 4 ));
+        double L6 = getDistance(P( 3 ),P( 4 ));
+        aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+        break;
       }
       else if (len == 5){ // piramids
-       double L1 = getDistance(P( 1 ),P( 2 ));
-       double L2 = getDistance(P( 2 ),P( 3 ));
-       double L3 = getDistance(P( 3 ),P( 1 ));
-       double L4 = getDistance(P( 4 ),P( 1 ));
-       double L5 = getDistance(P( 1 ),P( 5 ));
-       double L6 = getDistance(P( 2 ),P( 5 ));
-       double L7 = getDistance(P( 3 ),P( 5 ));
-       double L8 = getDistance(P( 4 ),P( 5 ));
-
-       aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
-       aVal = Max(aVal,Max(L7,L8));
-       break;
+        double L1 = getDistance(P( 1 ),P( 2 ));
+        double L2 = getDistance(P( 2 ),P( 3 ));
+        double L3 = getDistance(P( 3 ),P( 4 ));
+        double L4 = getDistance(P( 4 ),P( 1 ));
+        double L5 = getDistance(P( 1 ),P( 5 ));
+        double L6 = getDistance(P( 2 ),P( 5 ));
+        double L7 = getDistance(P( 3 ),P( 5 ));
+        double L8 = getDistance(P( 4 ),P( 5 ));
+
+        aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+        aVal = Max(aVal,Max(L7,L8));
+        break;
       }
       else if (len == 6){ // pentaidres
-       double L1 = getDistance(P( 1 ),P( 2 ));
-       double L2 = getDistance(P( 2 ),P( 3 ));
-       double L3 = getDistance(P( 3 ),P( 1 ));
-       double L4 = getDistance(P( 4 ),P( 5 ));
-       double L5 = getDistance(P( 5 ),P( 6 ));
-       double L6 = getDistance(P( 6 ),P( 4 ));
-       double L7 = getDistance(P( 1 ),P( 4 ));
-       double L8 = getDistance(P( 2 ),P( 5 ));
-       double L9 = getDistance(P( 3 ),P( 6 ));
-
-       aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
-       aVal = Max(aVal,Max(Max(L7,L8),L9));
-       break;
+        double L1 = getDistance(P( 1 ),P( 2 ));
+        double L2 = getDistance(P( 2 ),P( 3 ));
+        double L3 = getDistance(P( 3 ),P( 1 ));
+        double L4 = getDistance(P( 4 ),P( 5 ));
+        double L5 = getDistance(P( 5 ),P( 6 ));
+        double L6 = getDistance(P( 6 ),P( 4 ));
+        double L7 = getDistance(P( 1 ),P( 4 ));
+        double L8 = getDistance(P( 2 ),P( 5 ));
+        double L9 = getDistance(P( 3 ),P( 6 ));
+
+        aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+        aVal = Max(aVal,Max(Max(L7,L8),L9));
+        break;
       }
       else if (len == 8){ // hexaider
-       double L1 = getDistance(P( 1 ),P( 2 ));
-       double L2 = getDistance(P( 2 ),P( 3 ));
-       double L3 = getDistance(P( 3 ),P( 4 ));
-       double L4 = getDistance(P( 4 ),P( 1 ));
-       double L5 = getDistance(P( 5 ),P( 6 ));
-       double L6 = getDistance(P( 6 ),P( 7 ));
-       double L7 = getDistance(P( 7 ),P( 8 ));
-       double L8 = getDistance(P( 8 ),P( 5 ));
-       double L9 = getDistance(P( 1 ),P( 5 ));
-       double L10= getDistance(P( 2 ),P( 6 ));
-       double L11= getDistance(P( 3 ),P( 7 ));
-       double L12= getDistance(P( 4 ),P( 8 ));
-
-       aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
-       aVal = Max(aVal,Max(Max(L7,L8),Max(L9,L10)));
-       aVal = Max(aVal,Max(L11,L12));
-       break;
+        double L1 = getDistance(P( 1 ),P( 2 ));
+        double L2 = getDistance(P( 2 ),P( 3 ));
+        double L3 = getDistance(P( 3 ),P( 4 ));
+        double L4 = getDistance(P( 4 ),P( 1 ));
+        double L5 = getDistance(P( 5 ),P( 6 ));
+        double L6 = getDistance(P( 6 ),P( 7 ));
+        double L7 = getDistance(P( 7 ),P( 8 ));
+        double L8 = getDistance(P( 8 ),P( 5 ));
+        double L9 = getDistance(P( 1 ),P( 5 ));
+        double L10= getDistance(P( 2 ),P( 6 ));
+        double L11= getDistance(P( 3 ),P( 7 ));
+        double L12= getDistance(P( 4 ),P( 8 ));
+
+        aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+        aVal = Max(aVal,Max(Max(L7,L8),Max(L9,L10)));
+        aVal = Max(aVal,Max(L11,L12));
+        break;
 
       }
 
       if (len == 10){ // quadratic tetraidrs
-       double L1 = getDistance(P( 1 ),P( 5 )) + getDistance(P( 5 ),P( 2 ));
-       double L2 = getDistance(P( 2 ),P( 6 )) + getDistance(P( 6 ),P( 3 ));
-       double L3 = getDistance(P( 3 ),P( 7 )) + getDistance(P( 7 ),P( 1 ));
-       double L4 = getDistance(P( 1 ),P( 8 )) + getDistance(P( 8 ),P( 4 ));
-       double L5 = getDistance(P( 2 ),P( 9 )) + getDistance(P( 9 ),P( 4 ));
-       double L6 = getDistance(P( 3 ),P( 10 )) + getDistance(P( 10 ),P( 4 ));
-       aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
-       break;
+        double L1 = getDistance(P( 1 ),P( 5 )) + getDistance(P( 5 ),P( 2 ));
+        double L2 = getDistance(P( 2 ),P( 6 )) + getDistance(P( 6 ),P( 3 ));
+        double L3 = getDistance(P( 3 ),P( 7 )) + getDistance(P( 7 ),P( 1 ));
+        double L4 = getDistance(P( 1 ),P( 8 )) + getDistance(P( 8 ),P( 4 ));
+        double L5 = getDistance(P( 2 ),P( 9 )) + getDistance(P( 9 ),P( 4 ));
+        double L6 = getDistance(P( 3 ),P( 10 )) + getDistance(P( 10 ),P( 4 ));
+        aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+        break;
       }
       else if (len == 13){ // quadratic piramids
-       double L1 = getDistance(P( 1 ),P( 6 )) + getDistance(P( 6 ),P( 2 ));
-       double L2 = getDistance(P( 2 ),P( 7 )) + getDistance(P( 7 ),P( 3 ));
-       double L3 = getDistance(P( 3 ),P( 8 )) + getDistance(P( 8 ),P( 1 ));
-       double L4 = getDistance(P( 4 ),P( 9 )) + getDistance(P( 9 ),P( 1 ));
-       double L5 = getDistance(P( 1 ),P( 10 )) + getDistance(P( 10 ),P( 5 ));
-       double L6 = getDistance(P( 2 ),P( 11 )) + getDistance(P( 11 ),P( 5 ));
-       double L7 = getDistance(P( 3 ),P( 12 )) + getDistance(P( 12 ),P( 5 ));
-       double L8 = getDistance(P( 4 ),P( 13 )) + getDistance(P( 13 ),P( 5 ));
-       aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
-       aVal = Max(aVal,Max(L7,L8));
-       break;
+        double L1 = getDistance(P( 1 ),P( 6 )) + getDistance(P( 6 ),P( 2 ));
+        double L2 = getDistance(P( 2 ),P( 7 )) + getDistance(P( 7 ),P( 3 ));
+        double L3 = getDistance(P( 3 ),P( 8 )) + getDistance(P( 8 ),P( 4 ));
+        double L4 = getDistance(P( 4 ),P( 9 )) + getDistance(P( 9 ),P( 1 ));
+        double L5 = getDistance(P( 1 ),P( 10 )) + getDistance(P( 10 ),P( 5 ));
+        double L6 = getDistance(P( 2 ),P( 11 )) + getDistance(P( 11 ),P( 5 ));
+        double L7 = getDistance(P( 3 ),P( 12 )) + getDistance(P( 12 ),P( 5 ));
+        double L8 = getDistance(P( 4 ),P( 13 )) + getDistance(P( 13 ),P( 5 ));
+        aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+        aVal = Max(aVal,Max(L7,L8));
+        break;
       }
       else if (len == 15){ // quadratic pentaidres
-       double L1 = getDistance(P( 1 ),P( 7 )) + getDistance(P( 7 ),P( 2 ));
-       double L2 = getDistance(P( 2 ),P( 8 )) + getDistance(P( 8 ),P( 3 ));
-       double L3 = getDistance(P( 3 ),P( 9 )) + getDistance(P( 9 ),P( 1 ));
-       double L4 = getDistance(P( 4 ),P( 10 )) + getDistance(P( 10 ),P( 5 ));
-       double L5 = getDistance(P( 5 ),P( 11 )) + getDistance(P( 11 ),P( 6 ));
-       double L6 = getDistance(P( 6 ),P( 12 )) + getDistance(P( 12 ),P( 4 ));
-       double L7 = getDistance(P( 1 ),P( 13 )) + getDistance(P( 13 ),P( 4 ));
-       double L8 = getDistance(P( 2 ),P( 14 )) + getDistance(P( 14 ),P( 5 ));
-       double L9 = getDistance(P( 3 ),P( 15 )) + getDistance(P( 15 ),P( 6 ));
-       aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
-       aVal = Max(aVal,Max(Max(L7,L8),L9));
-       break;
+        double L1 = getDistance(P( 1 ),P( 7 )) + getDistance(P( 7 ),P( 2 ));
+        double L2 = getDistance(P( 2 ),P( 8 )) + getDistance(P( 8 ),P( 3 ));
+        double L3 = getDistance(P( 3 ),P( 9 )) + getDistance(P( 9 ),P( 1 ));
+        double L4 = getDistance(P( 4 ),P( 10 )) + getDistance(P( 10 ),P( 5 ));
+        double L5 = getDistance(P( 5 ),P( 11 )) + getDistance(P( 11 ),P( 6 ));
+        double L6 = getDistance(P( 6 ),P( 12 )) + getDistance(P( 12 ),P( 4 ));
+        double L7 = getDistance(P( 1 ),P( 13 )) + getDistance(P( 13 ),P( 4 ));
+        double L8 = getDistance(P( 2 ),P( 14 )) + getDistance(P( 14 ),P( 5 ));
+        double L9 = getDistance(P( 3 ),P( 15 )) + getDistance(P( 15 ),P( 6 ));
+        aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+        aVal = Max(aVal,Max(Max(L7,L8),L9));
+        break;
       }
       else if (len == 20){ // quadratic hexaider
-       double L1 = getDistance(P( 1 ),P( 9 )) + getDistance(P( 9 ),P( 2 ));
-       double L2 = getDistance(P( 2 ),P( 10 )) + getDistance(P( 10 ),P( 3 ));
-       double L3 = getDistance(P( 3 ),P( 11 )) + getDistance(P( 11 ),P( 4 ));
-       double L4 = getDistance(P( 4 ),P( 12 )) + getDistance(P( 12 ),P( 1 ));
-       double L5 = getDistance(P( 5 ),P( 13 )) + getDistance(P( 13 ),P( 6 ));
-       double L6 = getDistance(P( 6 ),P( 14 )) + getDistance(P( 14 ),P( 7 ));
-       double L7 = getDistance(P( 7 ),P( 15 )) + getDistance(P( 15 ),P( 8 ));
-       double L8 = getDistance(P( 8 ),P( 16 )) + getDistance(P( 16 ),P( 5 ));
-       double L9 = getDistance(P( 1 ),P( 17 )) + getDistance(P( 17 ),P( 5 ));
-       double L10= getDistance(P( 2 ),P( 18 )) + getDistance(P( 18 ),P( 6 ));
-       double L11= getDistance(P( 3 ),P( 19 )) + getDistance(P( 19 ),P( 7 ));
-       double L12= getDistance(P( 4 ),P( 20 )) + getDistance(P( 20 ),P( 8 ));
-       aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
-       aVal = Max(aVal,Max(Max(L7,L8),Max(L9,L10)));
-       aVal = Max(aVal,Max(L11,L12));
-       break;
+        double L1 = getDistance(P( 1 ),P( 9 )) + getDistance(P( 9 ),P( 2 ));
+        double L2 = getDistance(P( 2 ),P( 10 )) + getDistance(P( 10 ),P( 3 ));
+        double L3 = getDistance(P( 3 ),P( 11 )) + getDistance(P( 11 ),P( 4 ));
+        double L4 = getDistance(P( 4 ),P( 12 )) + getDistance(P( 12 ),P( 1 ));
+        double L5 = getDistance(P( 5 ),P( 13 )) + getDistance(P( 13 ),P( 6 ));
+        double L6 = getDistance(P( 6 ),P( 14 )) + getDistance(P( 14 ),P( 7 ));
+        double L7 = getDistance(P( 7 ),P( 15 )) + getDistance(P( 15 ),P( 8 ));
+        double L8 = getDistance(P( 8 ),P( 16 )) + getDistance(P( 16 ),P( 5 ));
+        double L9 = getDistance(P( 1 ),P( 17 )) + getDistance(P( 17 ),P( 5 ));
+        double L10= getDistance(P( 2 ),P( 18 )) + getDistance(P( 18 ),P( 6 ));
+        double L11= getDistance(P( 3 ),P( 19 )) + getDistance(P( 19 ),P( 7 ));
+        double L12= getDistance(P( 4 ),P( 20 )) + getDistance(P( 20 ),P( 8 ));
+        aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+        aVal = Max(aVal,Max(Max(L7,L8),Max(L9,L10)));
+        aVal = Max(aVal,Max(L11,L12));
+        break;
 
       }
 
@@ -1246,10 +1715,10 @@ void Length2D::GetValues(TValues& theValues){
     const SMDS_MeshFace* anElem = anIter->next();
 
     if(anElem->IsQuadratic()) {
-      const SMDS_QuadraticFaceOfNodes* F =
-        static_cast<const SMDS_QuadraticFaceOfNodes*>(anElem);
+      const SMDS_VtkFace* F =
+        dynamic_cast<const SMDS_VtkFace*>(anElem);
       // use special nodes iterator
-      SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+      SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator();
       long aNodeId[4];
       gp_Pnt P[4];
 
@@ -1443,7 +1912,7 @@ void MultiConnection2D::GetValues(MValues& theValues){
     const SMDS_MeshFace* anElem = anIter->next();
     SMDS_ElemIteratorPtr aNodesIter;
     if ( anElem->IsQuadratic() )
-      aNodesIter = static_cast<const SMDS_QuadraticFaceOfNodes*>
+      aNodesIter = dynamic_cast<const SMDS_VtkFace*>
         (anElem)->interlacedNodesElemIterator();
     else
       aNodesIter = anElem->nodesIterator();
@@ -1467,12 +1936,12 @@ void MultiConnection2D::GetValues(MValues& theValues){
       Value aValue(aNodeId[1],aNodeId[2]);
       MValues::iterator aItr = theValues.find(aValue);
       if (aItr != theValues.end()){
-       aItr->second += 1;
-       //aNbConnects = nb;
+        aItr->second += 1;
+        //aNbConnects = nb;
       }
       else {
-       theValues[aValue] = 1;
-       //aNbConnects = 1;
+        theValues[aValue] = 1;
+        //aNbConnects = 1;
       }
       //cout << "NodeIds: "<<aNodeId[1]<<","<<aNodeId[2]<<" nbconn="<<aNbConnects<<endl;
       aNodeId[1] = aNodeId[2];
@@ -1493,6 +1962,34 @@ void MultiConnection2D::GetValues(MValues& theValues){
 
 }
 
+/*
+  Class       : BallDiameter
+  Description : Functor returning diameter of a ball element
+*/
+double BallDiameter::GetValue( long theId )
+{
+  double diameter = 0;
+
+  if ( const SMDS_BallElement* ball =
+       dynamic_cast<const SMDS_BallElement*>( myMesh->FindElement( theId )))
+  {
+    diameter = ball->GetDiameter();
+  }
+  return diameter;
+}
+
+double BallDiameter::GetBadRate( double Value, int /*nbNodes*/ ) const
+{
+  // meaningless as it is not a quality control functor
+  return Value;
+}
+
+SMDSAbs_ElementType BallDiameter::GetType() const
+{
+  return SMDSAbs_Ball;
+}
+
+
 /*
                             PREDICATES
 */
@@ -1526,6 +2023,218 @@ SMDSAbs_ElementType BadOrientedVolume::GetType() const
   return SMDSAbs_Volume;
 }
 
+/*
+  Class       : BareBorderVolume
+*/
+
+bool BareBorderVolume::IsSatisfy(long theElementId )
+{
+  SMDS_VolumeTool  myTool;
+  if ( myTool.Set( myMesh->FindElement(theElementId)))
+  {
+    for ( int iF = 0; iF < myTool.NbFaces(); ++iF )
+      if ( myTool.IsFreeFace( iF ))
+      {
+        const SMDS_MeshNode** n = myTool.GetFaceNodes(iF);
+        vector< const SMDS_MeshNode*> nodes( n, n+myTool.NbFaceNodes(iF));
+        if ( !myMesh->FindElement( nodes, SMDSAbs_Face, /*Nomedium=*/false))
+          return true;
+      }
+  }
+  return false;
+}
+
+/*
+  Class       : BareBorderFace
+*/
+
+bool BareBorderFace::IsSatisfy(long theElementId )
+{
+  bool ok = false;
+  if ( const SMDS_MeshElement* face = myMesh->FindElement(theElementId))
+  {
+    if ( face->GetType() == SMDSAbs_Face )
+    {
+      int nbN = face->NbCornerNodes();
+      for ( int i = 0; i < nbN && !ok; ++i )
+      {
+        // check if a link is shared by another face
+        const SMDS_MeshNode* n1 = face->GetNode( i );
+        const SMDS_MeshNode* n2 = face->GetNode( (i+1)%nbN );
+        SMDS_ElemIteratorPtr fIt = n1->GetInverseElementIterator( SMDSAbs_Face );
+        bool isShared = false;
+        while ( !isShared && fIt->more() )
+        {
+          const SMDS_MeshElement* f = fIt->next();
+          isShared = ( f != face && f->GetNodeIndex(n2) != -1 );
+        }
+        if ( !isShared )
+        {
+          const int iQuad = face->IsQuadratic();
+          myLinkNodes.resize( 2 + iQuad);
+          myLinkNodes[0] = n1;
+          myLinkNodes[1] = n2;
+          if ( iQuad )
+            myLinkNodes[2] = face->GetNode( i+nbN );
+          ok = !myMesh->FindElement( myLinkNodes, SMDSAbs_Edge, /*noMedium=*/false);
+        }
+      }
+    }
+  }
+  return ok;
+}
+
+/*
+  Class       : OverConstrainedVolume
+*/
+
+bool OverConstrainedVolume::IsSatisfy(long theElementId )
+{
+  // An element is over-constrained if it has N-1 free borders where
+  // N is the number of edges/faces for a 2D/3D element.
+  SMDS_VolumeTool  myTool;
+  if ( myTool.Set( myMesh->FindElement(theElementId)))
+  {
+    int nbSharedFaces = 0;
+    for ( int iF = 0; iF < myTool.NbFaces(); ++iF )
+      if ( !myTool.IsFreeFace( iF ) && ++nbSharedFaces > 1 )
+        break;
+    return ( nbSharedFaces == 1 );
+  }
+  return false;
+}
+
+/*
+  Class       : OverConstrainedFace
+*/
+
+bool OverConstrainedFace::IsSatisfy(long theElementId )
+{
+  // An element is over-constrained if it has N-1 free borders where
+  // N is the number of edges/faces for a 2D/3D element.
+  if ( const SMDS_MeshElement* face = myMesh->FindElement(theElementId))
+    if ( face->GetType() == SMDSAbs_Face )
+    {
+      int nbSharedBorders = 0;
+      int nbN = face->NbCornerNodes();
+      for ( int i = 0; i < nbN; ++i )
+      {
+        // check if a link is shared by another face
+        const SMDS_MeshNode* n1 = face->GetNode( i );
+        const SMDS_MeshNode* n2 = face->GetNode( (i+1)%nbN );
+        SMDS_ElemIteratorPtr fIt = n1->GetInverseElementIterator( SMDSAbs_Face );
+        bool isShared = false;
+        while ( !isShared && fIt->more() )
+        {
+          const SMDS_MeshElement* f = fIt->next();
+          isShared = ( f != face && f->GetNodeIndex(n2) != -1 );
+        }
+        if ( isShared && ++nbSharedBorders > 1 )
+          break;
+      }
+      return ( nbSharedBorders == 1 );
+    }
+  return false;
+}
+
+/*
+  Class       : CoincidentNodes
+  Description : Predicate of Coincident nodes
+*/
+
+CoincidentNodes::CoincidentNodes()
+{
+  myToler = 1e-5;
+}
+
+bool CoincidentNodes::IsSatisfy( long theElementId )
+{
+  return myCoincidentIDs.Contains( theElementId );
+}
+
+SMDSAbs_ElementType CoincidentNodes::GetType() const
+{
+  return SMDSAbs_Node;
+}
+
+void CoincidentNodes::SetMesh( const SMDS_Mesh* theMesh )
+{
+  myMeshModifTracer.SetMesh( theMesh );
+  if ( myMeshModifTracer.IsMeshModified() )
+  {
+    TIDSortedNodeSet nodesToCheck;
+    SMDS_NodeIteratorPtr nIt = theMesh->nodesIterator(/*idInceasingOrder=*/true);
+    while ( nIt->more() )
+      nodesToCheck.insert( nodesToCheck.end(), nIt->next() );
+
+    list< list< const SMDS_MeshNode*> > nodeGroups;
+    SMESH_OctreeNode::FindCoincidentNodes ( nodesToCheck, &nodeGroups, myToler );
+
+    myCoincidentIDs.Clear();
+    list< list< const SMDS_MeshNode*> >::iterator groupIt = nodeGroups.begin();
+    for ( ; groupIt != nodeGroups.end(); ++groupIt )
+    {
+      list< const SMDS_MeshNode*>& coincNodes = *groupIt;
+      list< const SMDS_MeshNode*>::iterator n = coincNodes.begin();
+      for ( ; n != coincNodes.end(); ++n )
+        myCoincidentIDs.Add( (*n)->GetID() );
+    }
+  }
+}
+
+/*
+  Class       : CoincidentElements
+  Description : Predicate of Coincident Elements
+  Note        : This class is suitable only for visualization of Coincident Elements
+*/
+
+CoincidentElements::CoincidentElements()
+{
+  myMesh = 0;
+}
+
+void CoincidentElements::SetMesh( const SMDS_Mesh* theMesh )
+{
+  myMesh = theMesh;
+}
+
+bool CoincidentElements::IsSatisfy( long theElementId )
+{
+  if ( !myMesh ) return false;
+
+  if ( const SMDS_MeshElement* e = myMesh->FindElement( theElementId ))
+  {
+    if ( e->GetType() != GetType() ) return false;
+    set< const SMDS_MeshNode* > elemNodes( e->begin_nodes(), e->end_nodes() );
+    const int nbNodes = e->NbNodes();
+    SMDS_ElemIteratorPtr invIt = (*elemNodes.begin())->GetInverseElementIterator( GetType() );
+    while ( invIt->more() )
+    {
+      const SMDS_MeshElement* e2 = invIt->next();
+      if ( e2 == e || e2->NbNodes() != nbNodes ) continue;
+
+      bool sameNodes = true;
+      for ( size_t i = 0; i < elemNodes.size() && sameNodes; ++i )
+        sameNodes = ( elemNodes.count( e2->GetNode( i )));
+      if ( sameNodes )
+        return true;
+    }
+  }
+  return false;
+}
+
+SMDSAbs_ElementType CoincidentElements1D::GetType() const
+{
+  return SMDSAbs_Edge;
+}
+SMDSAbs_ElementType CoincidentElements2D::GetType() const
+{
+  return SMDSAbs_Face;
+}
+SMDSAbs_ElementType CoincidentElements3D::GetType() const
+{
+  return SMDSAbs_Volume;
+}
 
 
 /*
@@ -1573,17 +2282,13 @@ bool FreeEdges::IsFreeEdge( const SMDS_MeshNode** theNodes, const int theFaceId
   TColStd_MapOfInteger aMap;
   for ( int i = 0; i < 2; i++ )
   {
-    SMDS_ElemIteratorPtr anElemIter = theNodes[ i ]->GetInverseElementIterator();
+    SMDS_ElemIteratorPtr anElemIter = theNodes[ i ]->GetInverseElementIterator(SMDSAbs_Face);
     while( anElemIter->more() )
     {
-      const SMDS_MeshElement* anElem = anElemIter->next();
-      if ( anElem != 0 && anElem->GetType() == SMDSAbs_Face )
+      if ( const SMDS_MeshElement* anElem = anElemIter->next())
       {
-        int anId = anElem->GetID();
-
-        if ( i == 0 )
-          aMap.Add( anId );
-        else if ( aMap.Contains( anId ) && anId != theFaceId )
+        const int anId = anElem->GetID();
+        if ( anId != theFaceId && !aMap.Add( anId ))
           return false;
       }
     }
@@ -1602,13 +2307,13 @@ bool FreeEdges::IsSatisfy( long theId )
 
   SMDS_ElemIteratorPtr anIter;
   if ( aFace->IsQuadratic() ) {
-    anIter = static_cast<const SMDS_QuadraticFaceOfNodes*>
+    anIter = dynamic_cast<const SMDS_VtkFace*>
       (aFace)->interlacedNodesElemIterator();
   }
   else {
     anIter = aFace->nodesIterator();
   }
-  if ( anIter == 0 )
+  if ( !anIter )
     return false;
 
   int i = 0, nbNodes = aFace->NbNodes();
@@ -1651,8 +2356,8 @@ bool FreeEdges::Border::operator<(const FreeEdges::Border& x) const{
 }
 
 inline void UpdateBorders(const FreeEdges::Border& theBorder,
-                         FreeEdges::TBorders& theRegistry,
-                         FreeEdges::TBorders& theContainer)
+                          FreeEdges::TBorders& theRegistry,
+                          FreeEdges::TBorders& theContainer)
 {
   if(theRegistry.find(theBorder) == theRegistry.end()){
     theRegistry.insert(theBorder);
@@ -1671,7 +2376,7 @@ void FreeEdges::GetBoreders(TBorders& theBorders)
     long anElemId = anElem->GetID();
     SMDS_ElemIteratorPtr aNodesIter;
     if ( anElem->IsQuadratic() )
-      aNodesIter = static_cast<const SMDS_QuadraticFaceOfNodes*>(anElem)->
+      aNodesIter = static_cast<const SMDS_VtkFace*>(anElem)->
         interlacedNodesElemIterator();
     else
       aNodesIter = anElem->nodesIterator();
@@ -1686,14 +2391,11 @@ void FreeEdges::GetBoreders(TBorders& theBorders)
       long anId = aNode->GetID();
       Border aBorder(anElemId,aNodeId[1],anId);
       aNodeId[1] = anId;
-      //std::cout<<aBorder.myPntId[0]<<"; "<<aBorder.myPntId[1]<<"; "<<aBorder.myElemId<<endl;
       UpdateBorders(aBorder,aRegistry,theBorders);
     }
     Border aBorder(anElemId,aNodeId[0],aNodeId[1]);
-    //std::cout<<aBorder.myPntId[0]<<"; "<<aBorder.myPntId[1]<<"; "<<aBorder.myElemId<<endl;
     UpdateBorders(aBorder,aRegistry,theBorders);
   }
-  //std::cout<<"theBorders.size() = "<<theBorders.size()<<endl;
 }
 
 
@@ -1938,8 +2640,10 @@ bool ElemGeomType::IsSatisfy( long theId )
 {
   if (!myMesh) return false;
   const SMDS_MeshElement* anElem = myMesh->FindElement( theId );
+  if ( !anElem )
+    return false;
   const SMDSAbs_ElementType anElemType = anElem->GetType();
-  if ( !anElem || (myType != SMDSAbs_All && anElemType != myType) )
+  if ( myType != SMDSAbs_All && anElemType != myType )
     return false;
   const int aNbNode = anElem->NbNodes();
   bool isOk = false;
@@ -1955,22 +2659,24 @@ bool ElemGeomType::IsSatisfy( long theId )
 
   case SMDSAbs_Face:
     if ( myGeomType == SMDSGeom_TRIANGLE )
-      isOk = (!anElem->IsPoly() && aNbNode == 3);
+      isOk = (!anElem->IsPoly() && (anElem->IsQuadratic() ? aNbNode == 6 : aNbNode == 3));
     else if ( myGeomType == SMDSGeom_QUADRANGLE )
-      isOk = (!anElem->IsPoly() && aNbNode == 4);
+      isOk = (!anElem->IsPoly() && (anElem->IsQuadratic() ? ( aNbNode == 8 || aNbNode == 9 ) : aNbNode == 4));
     else if ( myGeomType == SMDSGeom_POLYGON )
       isOk = anElem->IsPoly();
     break;
 
   case SMDSAbs_Volume:
     if ( myGeomType == SMDSGeom_TETRA )
-      isOk = (!anElem->IsPoly() && aNbNode == 4);
+      isOk = (!anElem->IsPoly() && (anElem->IsQuadratic() ? aNbNode == 10 : aNbNode == 4));
     else if ( myGeomType == SMDSGeom_PYRAMID )
-      isOk = (!anElem->IsPoly() && aNbNode == 5);
+      isOk = (!anElem->IsPoly() && (anElem->IsQuadratic() ? aNbNode == 13 : aNbNode == 5));
     else if ( myGeomType == SMDSGeom_PENTA )
-      isOk = (!anElem->IsPoly() && aNbNode == 6);
+      isOk = (!anElem->IsPoly() && (anElem->IsQuadratic() ? aNbNode == 15 : aNbNode == 6));
     else if ( myGeomType == SMDSGeom_HEXA )
-      isOk = (!anElem->IsPoly() && aNbNode == 8);
+      isOk = (!anElem->IsPoly() && (anElem->IsQuadratic() ? ( aNbNode == 20 || aNbNode == 27 ): aNbNode == 8));
+    else if ( myGeomType == SMDSGeom_HEXAGONAL_PRISM )
+      isOk = (anElem->GetEntityType() == SMDSEntity_Hexagonal_Prism );
      else if ( myGeomType == SMDSGeom_POLYHEDRA )
       isOk = anElem->IsPoly();
     break;
@@ -1999,13 +2705,77 @@ SMDSAbs_GeometryType ElemGeomType::GetGeomType() const
   return myGeomType;
 }
 
+//================================================================================
+/*!
+ * \brief Class CoplanarFaces
+ */
+//================================================================================
+
+CoplanarFaces::CoplanarFaces()
+  : myFaceID(0), myToler(0)
+{
+}
+void CoplanarFaces::SetMesh( const SMDS_Mesh* theMesh )
+{
+  myMeshModifTracer.SetMesh( theMesh );
+  if ( myMeshModifTracer.IsMeshModified() )
+  {
+    // Build a set of coplanar face ids
+
+    myCoplanarIDs.clear();
+
+    if ( !myMeshModifTracer.GetMesh() || !myFaceID || !myToler )
+      return;
+
+    const SMDS_MeshElement* face = myMeshModifTracer.GetMesh()->FindElement( myFaceID );
+    if ( !face || face->GetType() != SMDSAbs_Face )
+      return;
+
+    bool normOK;
+    gp_Vec myNorm = getNormale( static_cast<const SMDS_MeshFace*>(face), &normOK );
+    if (!normOK)
+      return;
+
+    const double radianTol = myToler * M_PI / 180.;
+    typedef SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > TFaceIt;
+    std::set<const SMDS_MeshElement*> checkedFaces, checkedNodes;
+    std::list<const SMDS_MeshElement*> faceQueue( 1, face );
+    while ( !faceQueue.empty() )
+    {
+      face = faceQueue.front();
+      if ( checkedFaces.insert( face ).second )
+      {
+        gp_Vec norm = getNormale( static_cast<const SMDS_MeshFace*>(face), &normOK );
+        if (!normOK || myNorm.Angle( norm ) <= radianTol)
+        {
+          myCoplanarIDs.insert( face->GetID() );
+          std::set<const SMDS_MeshElement*> neighborFaces;
+          for ( int i = 0; i < face->NbCornerNodes(); ++i )
+          {
+            const SMDS_MeshNode* n = face->GetNode( i );
+            if ( checkedNodes.insert( n ).second )
+              neighborFaces.insert( TFaceIt( n->GetInverseElementIterator(SMDSAbs_Face)),
+                                    TFaceIt());
+          }
+          faceQueue.insert( faceQueue.end(), neighborFaces.begin(), neighborFaces.end() );
+        }
+      }
+      faceQueue.pop_front();
+    }
+  }
+}
+bool CoplanarFaces::IsSatisfy( long theElementId )
+{
+  return myCoplanarIDs.count( theElementId );
+}
+
 /*
-  Class       : RangeOfIds
-  Description : Predicate for Range of Ids.
-                Range may be specified with two ways.
-                1. Using AddToRange method
-                2. With SetRangeStr method. Parameter of this method is a string
-                   like as "1,2,3,50-60,63,67,70-"
+  *Class       : RangeOfIds
+  *Description : Predicate for Range of Ids.
+  *              Range may be specified with two ways.
+  *              1. Using AddToRange method
+  *              2. With SetRangeStr method. Parameter of this method is a string
+  *                 like as "1,2,3,50-60,63,67,70-"
 */
 
 //=======================================================================
@@ -2152,8 +2922,8 @@ bool RangeOfIds::SetRangeStr( const TCollection_AsciiString& theStr )
       while ( aMinStr.Search( "-" ) != -1 ) aMinStr.RemoveAll( '-' );
       while ( aMaxStr.Search( "-" ) != -1 ) aMaxStr.RemoveAll( '-' );
 
-      if ( !aMinStr.IsEmpty() && !aMinStr.IsIntegerValue() ||
-           !aMaxStr.IsEmpty() && !aMaxStr.IsIntegerValue() )
+      if ( (!aMinStr.IsEmpty() && !aMinStr.IsIntegerValue()) ||
+           (!aMaxStr.IsEmpty() && !aMaxStr.IsIntegerValue()) )
         return false;
 
       myMin.Append( aMinStr.IsEmpty() ? IntegerFirst() : aMinStr.IntegerValue() );
@@ -2199,7 +2969,7 @@ bool RangeOfIds::IsSatisfy( long theId )
   else
   {
     const SMDS_MeshElement* anElem = myMesh->FindElement( theId );
-    if ( anElem == 0 || myType != anElem->GetType() && myType != SMDSAbs_All )
+    if ( anElem == 0 || (myType != anElem->GetType() && myType != SMDSAbs_All ))
       return false;
   }
 
@@ -2390,8 +3160,8 @@ bool LogicalOR::IsSatisfy( long theId )
   return
     myPredicate1 &&
     myPredicate2 &&
-    myPredicate1->IsSatisfy( theId ) ||
-    myPredicate2->IsSatisfy( theId );
+    (myPredicate1->IsSatisfy( theId ) ||
+    myPredicate2->IsSatisfy( theId ));
 }
 
 
@@ -2410,26 +3180,9 @@ void Filter::SetPredicate( PredicatePtr thePredicate )
   myPredicate = thePredicate;
 }
 
-template<class TElement, class TIterator, class TPredicate>
-inline void FillSequence(const TIterator& theIterator,
-                        TPredicate& thePredicate,
-                        Filter::TIdSequence& theSequence)
-{
-  if ( theIterator ) {
-    while( theIterator->more() ) {
-      TElement anElem = theIterator->next();
-      long anId = anElem->GetID();
-      if ( thePredicate->IsSatisfy( anId ) )
-       theSequence.push_back( anId );
-    }
-  }
-}
-
-void
-Filter::
-GetElementsId( const SMDS_Mesh* theMesh,
-              PredicatePtr thePredicate,
-              TIdSequence& theSequence )
+void Filter::GetElementsId( const SMDS_Mesh* theMesh,
+                            PredicatePtr     thePredicate,
+                            TIdSequence&     theSequence )
 {
   theSequence.clear();
 
@@ -2438,31 +3191,19 @@ GetElementsId( const SMDS_Mesh* theMesh,
 
   thePredicate->SetMesh( theMesh );
 
-  SMDSAbs_ElementType aType = thePredicate->GetType();
-  switch(aType){
-  case SMDSAbs_Node:
-    FillSequence<const SMDS_MeshNode*>(theMesh->nodesIterator(),thePredicate,theSequence);
-    break;
-  case SMDSAbs_Edge:
-    FillSequence<const SMDS_MeshElement*>(theMesh->edgesIterator(),thePredicate,theSequence);
-    break;
-  case SMDSAbs_Face:
-    FillSequence<const SMDS_MeshElement*>(theMesh->facesIterator(),thePredicate,theSequence);
-    break;
-  case SMDSAbs_Volume:
-    FillSequence<const SMDS_MeshElement*>(theMesh->volumesIterator(),thePredicate,theSequence);
-    break;
-  case SMDSAbs_All:
-    FillSequence<const SMDS_MeshElement*>(theMesh->edgesIterator(),thePredicate,theSequence);
-    FillSequence<const SMDS_MeshElement*>(theMesh->facesIterator(),thePredicate,theSequence);
-    FillSequence<const SMDS_MeshElement*>(theMesh->volumesIterator(),thePredicate,theSequence);
-    break;
+  SMDS_ElemIteratorPtr elemIt = theMesh->elementsIterator( thePredicate->GetType() );
+  if ( elemIt ) {
+    while ( elemIt->more() ) {
+      const SMDS_MeshElement* anElem = elemIt->next();
+      long anId = anElem->GetID();
+      if ( thePredicate->IsSatisfy( anId ) )
+        theSequence.push_back( anId );
+    }
   }
 }
 
-void
-Filter::GetElementsId( const SMDS_Mesh* theMesh,
-                      Filter::TIdSequence& theSequence )
+void Filter::GetElementsId( const SMDS_Mesh*     theMesh,
+                            Filter::TIdSequence& theSequence )
 {
   GetElementsId(theMesh,myPredicate,theSequence);
 }
@@ -2635,32 +3376,6 @@ static void getLinks( const SMDS_MeshFace* theFace,
   }
 }
 
-static gp_XYZ getNormale( const SMDS_MeshFace* theFace )
-{
-  gp_XYZ n;
-  int aNbNode = theFace->NbNodes();
-  TColgp_Array1OfXYZ anArrOfXYZ(1,4);
-  SMDS_ElemIteratorPtr aNodeItr = theFace->nodesIterator();
-  int i = 1;
-  for ( ; aNodeItr->more() && i <= 4; i++ ) {
-    SMDS_MeshNode* aNode = (SMDS_MeshNode*)aNodeItr->next();
-    anArrOfXYZ.SetValue(i, gp_XYZ( aNode->X(), aNode->Y(), aNode->Z() ) );
-  }
-
-  gp_XYZ q1 = anArrOfXYZ.Value(2) - anArrOfXYZ.Value(1);
-  gp_XYZ q2 = anArrOfXYZ.Value(3) - anArrOfXYZ.Value(1);
-  n  = q1 ^ q2;
-  if ( aNbNode > 3 ) {
-    gp_XYZ q3 = anArrOfXYZ.Value(4) - anArrOfXYZ.Value(1);
-    n += q2 ^ q3;
-  }
-  double len = n.Modulus();
-  if ( len > 0 )
-    n /= len;
-
-  return n;
-}
-
 bool ManifoldPart::findConnected
                  ( const ManifoldPart::TDataMapFacePtrInt& theAllFacePtrInt,
                   SMDS_MeshFace*                           theStartFace,
@@ -2815,7 +3530,7 @@ void ManifoldPart::expandBoundary
 void ManifoldPart::getFacesByLink( const ManifoldPart::Link& theLink,
                                    ManifoldPart::TVectorOfFacePtr& theFaces ) const
 {
-  SMDS_Mesh::SetOfFaces aSetOfFaces;
+  std::set<SMDS_MeshCell *> aSetOfFaces;
   // take all faces that shared first node
   SMDS_ElemIteratorPtr anItr = theLink.myNode1->facesIterator();
   for ( ; anItr->more(); )
@@ -2823,7 +3538,7 @@ void ManifoldPart::getFacesByLink( const ManifoldPart::Link& theLink,
     SMDS_MeshFace* aFace = (SMDS_MeshFace*)anItr->next();
     if ( !aFace )
       continue;
-    aSetOfFaces.Add( aFace );
+    aSetOfFaces.insert( aFace );
   }
   // take all faces that shared second node
   anItr = theLink.myNode2->facesIterator();
@@ -2831,7 +3546,7 @@ void ManifoldPart::getFacesByLink( const ManifoldPart::Link& theLink,
   for ( ; anItr->more(); )
   {
     SMDS_MeshFace* aFace = (SMDS_MeshFace*)anItr->next();
-    if ( aSetOfFaces.Contains( aFace ) )
+    if ( aSetOfFaces.count( aFace ) )
       theFaces.push_back( aFace );
   }
 }
@@ -2999,7 +3714,7 @@ bool ElementsOnSurface::isOnSurface( const SMDS_MeshNode* theNode )
 */
 
 ElementsOnShape::ElementsOnShape()
-  : myMesh(0),
+  : //myMesh(0),
     myType(SMDSAbs_All),
     myToler(Precision::Confusion()),
     myAllNodesFlag(false)
@@ -3013,10 +3728,9 @@ ElementsOnShape::~ElementsOnShape()
 
 void ElementsOnShape::SetMesh (const SMDS_Mesh* theMesh)
 {
-  if (myMesh != theMesh) {
-    myMesh = theMesh;
+  myMeshModifTracer.SetMesh( theMesh );
+  if ( myMeshModifTracer.IsMeshModified())
     SetShape(myShape, myType);
-  }
 }
 
 bool ElementsOnShape::IsSatisfy (long theElementId)
@@ -3057,7 +3771,9 @@ void ElementsOnShape::SetShape (const TopoDS_Shape&       theShape,
   myShape = theShape;
   myIds.Clear();
 
-  if (myMesh == 0) return;
+  const SMDS_Mesh* myMesh = myMeshModifTracer.GetMesh();
+  
+  if ( !myMesh ) return;
 
   switch (myType)
   {
@@ -3086,7 +3802,7 @@ void ElementsOnShape::SetShape (const TopoDS_Shape&       theShape,
 
 void ElementsOnShape::addShape (const TopoDS_Shape& theShape)
 {
-  if (theShape.IsNull() || myMesh == 0)
+  if (theShape.IsNull() || myMeshModifTracer.GetMesh() == 0)
     return;
 
   if (!myShapesMap.Add(theShape)) return;
@@ -3147,39 +3863,13 @@ void ElementsOnShape::addShape (const TopoDS_Shape& theShape)
 
 void ElementsOnShape::process()
 {
+  const SMDS_Mesh* myMesh = myMeshModifTracer.GetMesh();
   if (myShape.IsNull() || myMesh == 0)
     return;
 
-  if (myType == SMDSAbs_Node)
-  {
-    SMDS_NodeIteratorPtr anIter = myMesh->nodesIterator();
-    while (anIter->more())
-      process(anIter->next());
-  }
-  else
-  {
-    if (myType == SMDSAbs_Edge || myType == SMDSAbs_All)
-    {
-      SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
-      while (anIter->more())
-        process(anIter->next());
-    }
-
-    if (myType == SMDSAbs_Face || myType == SMDSAbs_All)
-    {
-      SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
-      while (anIter->more()) {
-        process(anIter->next());
-      }
-    }
-
-    if (myType == SMDSAbs_Volume || myType == SMDSAbs_All)
-    {
-      SMDS_VolumeIteratorPtr anIter = myMesh->volumesIterator();
-      while (anIter->more())
-        process(anIter->next());
-    }
-  }
+  SMDS_ElemIteratorPtr anIter = myMesh->elementsIterator(myType);
+  while (anIter->more())
+    process(anIter->next());
 }
 
 void ElementsOnShape::process (const SMDS_MeshElement* theElemPtr)
@@ -3190,10 +3880,12 @@ void ElementsOnShape::process (const SMDS_MeshElement* theElemPtr)
   SMDS_ElemIteratorPtr aNodeItr = theElemPtr->nodesIterator();
   bool isSatisfy = myAllNodesFlag;
 
+  gp_XYZ centerXYZ (0, 0, 0);
+
   while (aNodeItr->more() && (isSatisfy == myAllNodesFlag))
   {
-    SMDS_MeshNode* aNode = (SMDS_MeshNode*)aNodeItr->next();
-    gp_Pnt aPnt (aNode->X(), aNode->Y(), aNode->Z());
+    SMESH_TNodeXYZ aPnt ( aNodeItr->next() );
+    centerXYZ += aPnt;
 
     switch (myCurShapeType)
     {
@@ -3226,7 +3918,7 @@ void ElementsOnShape::process (const SMDS_MeshElement* theElemPtr)
       break;
     case TopAbs_VERTEX:
       {
-        isSatisfy = (aPnt.Distance(myCurPnt) <= myToler);
+        isSatisfy = (myCurPnt.Distance(aPnt) <= myToler);
       }
       break;
     default:
@@ -3236,6 +3928,90 @@ void ElementsOnShape::process (const SMDS_MeshElement* theElemPtr)
     }
   }
 
+  if (isSatisfy && myCurShapeType == TopAbs_SOLID) { // Check the center point for volumes MantisBug 0020168
+    centerXYZ /= theElemPtr->NbNodes();
+    gp_Pnt aCenterPnt (centerXYZ);
+    myCurSC.Perform(aCenterPnt, myToler);
+    if ( !(myCurSC.State() == TopAbs_IN || myCurSC.State() == TopAbs_ON))
+      isSatisfy = false;
+  }
+
   if (isSatisfy)
     myIds.Add(theElemPtr->GetID());
 }
+
+TSequenceOfXYZ::TSequenceOfXYZ()
+{}
+
+TSequenceOfXYZ::TSequenceOfXYZ(size_type n) : myArray(n)
+{}
+
+TSequenceOfXYZ::TSequenceOfXYZ(size_type n, const gp_XYZ& t) : myArray(n,t)
+{}
+
+TSequenceOfXYZ::TSequenceOfXYZ(const TSequenceOfXYZ& theSequenceOfXYZ) : myArray(theSequenceOfXYZ.myArray)
+{}
+
+template <class InputIterator>
+TSequenceOfXYZ::TSequenceOfXYZ(InputIterator theBegin, InputIterator theEnd): myArray(theBegin,theEnd)
+{}
+
+TSequenceOfXYZ::~TSequenceOfXYZ()
+{}
+
+TSequenceOfXYZ& TSequenceOfXYZ::operator=(const TSequenceOfXYZ& theSequenceOfXYZ)
+{
+  myArray = theSequenceOfXYZ.myArray;
+  return *this;
+}
+
+gp_XYZ& TSequenceOfXYZ::operator()(size_type n)
+{
+  return myArray[n-1];
+}
+
+const gp_XYZ& TSequenceOfXYZ::operator()(size_type n) const
+{
+  return myArray[n-1];
+}
+
+void TSequenceOfXYZ::clear()
+{
+  myArray.clear();
+}
+
+void TSequenceOfXYZ::reserve(size_type n)
+{
+  myArray.reserve(n);
+}
+
+void TSequenceOfXYZ::push_back(const gp_XYZ& v)
+{
+  myArray.push_back(v);
+}
+
+TSequenceOfXYZ::size_type TSequenceOfXYZ::size() const
+{
+  return myArray.size();
+}
+
+TMeshModifTracer::TMeshModifTracer():
+  myMeshModifTime(0), myMesh(0)
+{
+}
+void TMeshModifTracer::SetMesh( const SMDS_Mesh* theMesh )
+{
+  if ( theMesh != myMesh )
+    myMeshModifTime = 0;
+  myMesh = theMesh;
+}
+bool TMeshModifTracer::IsMeshModified()
+{
+  bool modified = false;
+  if ( myMesh )
+  {
+    modified = ( myMeshModifTime != myMesh->GetMTime() );
+    myMeshModifTime = myMesh->GetMTime();
+  }
+  return modified;
+}
diff --git a/src/Controls/SMESH_Controls.hxx b/src/Controls/SMESH_Controls.hxx
deleted file mode 100644 (file)
index 3bab160..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-#ifndef _SMESH_CONTROLS_HXX_
-#define _SMESH_CONTROLS_HXX_
-
-#include <boost/shared_ptr.hpp>
-
-namespace SMESH{
-  namespace Controls{
-
-    class Functor;
-    typedef boost::shared_ptr<Functor> FunctorPtr;
-
-
-    class NumericalFunctor;
-    typedef boost::shared_ptr<NumericalFunctor> NumericalFunctorPtr;
-  
-  
-    class Predicate;
-    typedef boost::shared_ptr<Predicate> PredicatePtr;
-
-  }
-}
-
-
-#endif
index d692a6e5dc8e3939756d759760fa5bb81766ba02..0609c99e79595753e5b3109d572b155b2a5aa9ae 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #ifndef _SMESH_CONTROLSDEF_HXX_
 #define _SMESH_CONTROLSDEF_HXX_
 
 
 #include "SMDSAbs_ElementType.hxx"
 #include "SMDS_MeshNode.hxx"
+#include "SMESH_TypeDefs.hxx"
 
 #include "SMESH_Controls.hxx"
 
-#ifdef WNT
- #if defined SMESHCONTROLS_EXPORTS
-  #define SMESHCONTROLS_EXPORT __declspec( dllexport )
- #else
-  #define SMESHCONTROLS_EXPORT __declspec( dllimport )
- #endif
-#else
- #define SMESHCONTROLS_EXPORT
-#endif
-
 class SMDS_MeshElement;
 class SMDS_MeshFace;
 class SMDS_MeshNode;
@@ -68,59 +60,55 @@ class gp_Pnt;
 namespace SMESH{
   namespace Controls{
 
-    class SMESHCONTROLS_EXPORT TSequenceOfXYZ: public std::vector<gp_XYZ>
+    class SMESHCONTROLS_EXPORT TSequenceOfXYZ
     {
+      typedef std::vector<gp_XYZ>::size_type size_type;
+
     public:
-      typedef std::vector<gp_XYZ> TSuperClass;
-      TSequenceOfXYZ()
-      {}
+      TSequenceOfXYZ();
 
-      TSequenceOfXYZ(size_type n):
-       TSuperClass(n)
-      {}
+      TSequenceOfXYZ(size_type n);
 
-      TSequenceOfXYZ(size_type n, const value_type& t):
-       TSuperClass(n,t)
-      {}
+      TSequenceOfXYZ(size_type n, const gp_XYZ& t);
 
-      TSequenceOfXYZ(const TSequenceOfXYZ& theSequenceOfXYZ):
-       TSuperClass(theSequenceOfXYZ)
-      {}
+      TSequenceOfXYZ(const TSequenceOfXYZ& theSequenceOfXYZ);
 
       template <class InputIterator>
-      TSequenceOfXYZ(InputIterator theBegin, InputIterator theEnd):
-       TSuperClass(theBegin,theEnd)
-      {}
+      TSequenceOfXYZ(InputIterator theBegin, InputIterator theEnd);
 
-      TSequenceOfXYZ& operator=(const TSequenceOfXYZ& theSequenceOfXYZ){
-       TSuperClass::operator=(theSequenceOfXYZ);
-       return *this;
-      }
+      ~TSequenceOfXYZ();
 
-      reference operator()(size_type n){
-       return TSuperClass::operator[](n-1);
-      }
+      TSequenceOfXYZ& operator=(const TSequenceOfXYZ& theSequenceOfXYZ);
 
-      const_reference operator()(size_type n) const{
-       return TSuperClass::operator[](n-1);
-      }
+      gp_XYZ& operator()(size_type n);
 
-    private:
-      reference operator[](size_type n);
+      const gp_XYZ& operator()(size_type n) const;
+
+      void clear();
+
+      void reserve(size_type n);
+
+      void push_back(const gp_XYZ& v);
+
+      size_type size() const;
 
-      const_reference operator[](size_type n) const;
+    private:
+      std::vector<gp_XYZ> myArray;
     };
 
-    /*
-      Class       : Functor
-      Description : Root of all Functors
-    */
-    class SMESHCONTROLS_EXPORT Functor
+    /*!
+     * \brief Class used to detect mesh modification: IsMeshModified() returns
+     * true if a mesh has changed since last calling IsMeshModified()
+     */
+    class SMESHCONTROLS_EXPORT TMeshModifTracer
     {
+      unsigned long    myMeshModifTime;
+      const SMDS_Mesh* myMesh;
     public:
-      ~Functor(){}
-      virtual void SetMesh( const SMDS_Mesh* theMesh ) = 0;
-      virtual SMDSAbs_ElementType GetType() const = 0;
+      TMeshModifTracer();
+      void SetMesh( const SMDS_Mesh* theMesh );
+      const SMDS_Mesh* GetMesh() const { return myMesh; }
+      bool IsMeshModified();
     };
 
     /*
@@ -133,19 +121,24 @@ namespace SMESH{
       virtual void SetMesh( const SMDS_Mesh* theMesh );
       virtual double GetValue( long theElementId );
       virtual double GetValue(const TSequenceOfXYZ& thePoints) { return -1.0;};
+      void GetHistogram(int                     nbIntervals,
+                        std::vector<int>&       nbEvents,
+                        std::vector<double>&    funValues,
+                        const std::vector<int>& elements,
+                        const double*           minmax=0);
       virtual SMDSAbs_ElementType GetType() const = 0;
       virtual double GetBadRate( double Value, int nbNodes ) const = 0;
       long  GetPrecision() const;
       void  SetPrecision( const long thePrecision );
+      double Round( const double & value );
       
-      bool GetPoints(const int theId,
-                    TSequenceOfXYZ& theRes) const;
-      static bool GetPoints(const SMDS_MeshElement* theElem,
-                           TSequenceOfXYZ& theRes);
+      bool GetPoints(const int theId, TSequenceOfXYZ& theRes) const;
+      static bool GetPoints(const SMDS_MeshElement* theElem, TSequenceOfXYZ& theRes);
     protected:
-      const SMDS_Mesh* myMesh;
+      const SMDS_Mesh*        myMesh;
       const SMDS_MeshElement* myCurrElement;
-      long       myPrecision;
+      long                    myPrecision;
+      double                  myPrecisionValue;
     };
 
 
@@ -162,6 +155,30 @@ namespace SMESH{
     };
   
   
+    /*
+      Class       : MaxElementLength2D
+      Description : Functor calculating maximum length of 2D element
+    */
+    class SMESHCONTROLS_EXPORT MaxElementLength2D: public virtual NumericalFunctor{
+    public:
+      virtual double GetValue( long theElementId );
+      virtual double GetBadRate( double Value, int nbNodes ) const;
+      virtual SMDSAbs_ElementType GetType() const;
+    };
+  
+  
+    /*
+      Class       : MaxElementLength3D
+      Description : Functor calculating maximum length of 3D element
+    */
+    class SMESHCONTROLS_EXPORT MaxElementLength3D: public virtual NumericalFunctor{
+    public:
+      virtual double GetValue( long theElementId );
+      virtual double GetBadRate( double Value, int nbNodes ) const;
+      virtual SMDSAbs_ElementType GetType() const;
+    };
+  
+  
     /*
       Class       : SMESH_MinimumAngle
       Description : Functor for calculation of minimum angle
@@ -180,6 +197,7 @@ namespace SMESH{
     */
     class SMESHCONTROLS_EXPORT AspectRatio: public virtual NumericalFunctor{
     public:
+      virtual double GetValue( long theElementId );
       virtual double GetValue( const TSequenceOfXYZ& thePoints );
       virtual double GetBadRate( double Value, int nbNodes ) const;
       virtual SMDSAbs_ElementType GetType() const;
@@ -192,6 +210,7 @@ namespace SMESH{
     */
     class SMESHCONTROLS_EXPORT AspectRatio3D: public virtual NumericalFunctor{
     public:
+      virtual double GetValue( long theElementId );
       virtual double GetValue( const TSequenceOfXYZ& thePoints );
       virtual double GetBadRate( double Value, int nbNodes ) const;
       virtual SMDSAbs_ElementType GetType() const;
@@ -270,10 +289,10 @@ namespace SMESH{
       virtual double GetBadRate( double Value, int nbNodes ) const;
       virtual SMDSAbs_ElementType GetType() const;
       struct Value{
-       double myLength;
-       long myPntId[2];
-       Value(double theLength, long thePntId1, long thePntId2);
-       bool operator<(const Value& x) const;
+        double myLength;
+        long myPntId[2];
+        Value(double theLength, long thePntId1, long thePntId2);
+        bool operator<(const Value& x) const;
       };
       typedef std::set<Value> TValues;
       void GetValues(TValues& theValues);
@@ -303,29 +322,80 @@ namespace SMESH{
       virtual double GetBadRate( double Value, int nbNodes ) const;
       virtual SMDSAbs_ElementType GetType() const;
       struct Value{
-       long myPntId[2];
-       Value(long thePntId1, long thePntId2);
-       bool operator<(const Value& x) const;
+        long myPntId[2];
+        Value(long thePntId1, long thePntId2);
+        bool operator<(const Value& x) const;
       };
       typedef std::map<Value,int> MValues;
 
       void GetValues(MValues& theValues);
     };
     typedef boost::shared_ptr<MultiConnection2D> MultiConnection2DPtr;
+
+    /*
+      Class       : BallDiameter
+      Description : Functor returning diameter of a ball element
+    */
+    class SMESHCONTROLS_EXPORT BallDiameter: public virtual NumericalFunctor{
+    public:
+      virtual double GetValue( long theElementId );
+      virtual double GetBadRate( double Value, int nbNodes ) const;
+      virtual SMDSAbs_ElementType GetType() const;
+    };
+    
+
     /*
       PREDICATES
     */
     /*
-      Class       : Predicate
-      Description : Base class for all predicates
+      Class       : CoincidentNodes
+      Description : Predicate of Coincident Nodes
+      Note        : This class is suitable only for visualization of Coincident Nodes
     */
-    class SMESHCONTROLS_EXPORT Predicate: public virtual Functor{
+    class SMESHCONTROLS_EXPORT CoincidentNodes: public Predicate {
     public:
-      virtual bool IsSatisfy( long theElementId ) = 0;
-      virtual SMDSAbs_ElementType GetType() const = 0;
+      CoincidentNodes();
+      virtual void SetMesh( const SMDS_Mesh* theMesh );
+      virtual bool IsSatisfy( long theElementId );
+      virtual SMDSAbs_ElementType GetType() const;
+
+      void SetTolerance (const double theToler)  { myToler = theToler; }
+      double GetTolerance () const { return myToler; }
+
+    private:
+      double               myToler;
+      TColStd_MapOfInteger myCoincidentIDs;
+      TMeshModifTracer     myMeshModifTracer;
     };
-  
-  
+    typedef boost::shared_ptr<CoincidentNodes> CoincidentNodesPtr;
+   
+    /*
+      Class       : CoincidentElements
+      Description : Predicate of Coincident Elements
+      Note        : This class is suitable only for visualization of Coincident Elements
+    */
+    class SMESHCONTROLS_EXPORT CoincidentElements: public Predicate {
+    public:
+      CoincidentElements();
+      virtual void SetMesh( const SMDS_Mesh* theMesh );
+      virtual bool IsSatisfy( long theElementId );
+
+    private:
+      const SMDS_Mesh* myMesh;
+    };
+    class SMESHCONTROLS_EXPORT CoincidentElements1D: public CoincidentElements {
+    public:
+      virtual SMDSAbs_ElementType GetType() const;
+    };
+    class SMESHCONTROLS_EXPORT CoincidentElements2D: public CoincidentElements {
+    public:
+      virtual SMDSAbs_ElementType GetType() const;
+    };
+    class SMESHCONTROLS_EXPORT CoincidentElements3D: public CoincidentElements {
+    public:
+      virtual SMDSAbs_ElementType GetType() const;
+    };
+
     /*
       Class       : FreeBorders
       Description : Predicate for free borders
@@ -352,11 +422,71 @@ namespace SMESH{
       virtual void SetMesh( const SMDS_Mesh* theMesh );
       virtual bool IsSatisfy( long theElementId );
       virtual SMDSAbs_ElementType GetType() const;
-            
+
     protected:
       const SMDS_Mesh* myMesh;
     };
-   
+
+    /*
+      BareBorderVolume
+    */
+    class SMESHCONTROLS_EXPORT BareBorderVolume: public Predicate
+    {
+    public:
+      BareBorderVolume():myMesh(0) {}
+      virtual void SetMesh( const SMDS_Mesh* theMesh ) { myMesh = theMesh; }
+      virtual SMDSAbs_ElementType GetType() const      { return SMDSAbs_Volume; }
+      virtual bool IsSatisfy( long theElementId );
+    protected:
+      const SMDS_Mesh* myMesh;
+    };
+    typedef boost::shared_ptr<BareBorderVolume> BareBorderVolumePtr;
+
+    /*
+      BareBorderFace
+    */
+    class SMESHCONTROLS_EXPORT BareBorderFace: public Predicate
+    {
+    public:
+      BareBorderFace():myMesh(0) {}
+      virtual void SetMesh( const SMDS_Mesh* theMesh ) { myMesh = theMesh; }
+      virtual SMDSAbs_ElementType GetType() const      { return SMDSAbs_Face; }
+      virtual bool IsSatisfy( long theElementId );
+    protected:
+      const SMDS_Mesh* myMesh;
+      std::vector< const SMDS_MeshNode* > myLinkNodes;
+    };
+    typedef boost::shared_ptr<BareBorderFace> BareBorderFacePtr;
+
+    /*
+      OverConstrainedVolume
+    */
+    class SMESHCONTROLS_EXPORT OverConstrainedVolume: public Predicate
+    {
+    public:
+      OverConstrainedVolume():myMesh(0) {}
+      virtual void SetMesh( const SMDS_Mesh* theMesh ) { myMesh = theMesh; }
+      virtual SMDSAbs_ElementType GetType() const      { return SMDSAbs_Volume; }
+      virtual bool IsSatisfy( long theElementId );
+    protected:
+      const SMDS_Mesh* myMesh;
+    };
+    typedef boost::shared_ptr<OverConstrainedVolume> OverConstrainedVolumePtr;
+
+    /*
+      OverConstrainedFace
+    */
+    class SMESHCONTROLS_EXPORT OverConstrainedFace: public Predicate
+    {
+    public:
+      OverConstrainedFace():myMesh(0) {}
+      virtual void SetMesh( const SMDS_Mesh* theMesh ) { myMesh = theMesh; }
+      virtual SMDSAbs_ElementType GetType() const      { return SMDSAbs_Face; }
+      virtual bool IsSatisfy( long theElementId );
+    protected:
+      const SMDS_Mesh* myMesh;
+    };
+    typedef boost::shared_ptr<OverConstrainedFace> OverConstrainedFacePtr;
 
     /*
       Class       : FreeEdges
@@ -371,14 +501,14 @@ namespace SMESH{
       static bool IsFreeEdge( const SMDS_MeshNode** theNodes, const int theFaceId  );
       typedef long TElemId;
       struct Border{
-       TElemId myElemId;
-       TElemId myPntId[2];
-       Border(long theElemId, long thePntId1, long thePntId2);
-       bool operator<(const Border& x) const;
+        TElemId myElemId;
+        TElemId myPntId[2];
+        Border(long theElemId, long thePntId1, long thePntId2);
+        bool operator<(const Border& x) const;
       };
       typedef std::set<Border> TBorders;
       void GetBoreders(TBorders& theBorders);
-      
+
     protected:
       const SMDS_Mesh* myMesh;
     };
@@ -694,7 +824,7 @@ namespace SMESH{
       void    process (const SMDS_MeshElement* theElem);
 
     private:
-      const SMDS_Mesh*      myMesh;
+      TMeshModifTracer      myMeshModifTracer;
       TColStd_MapOfInteger  myIds;
       SMDSAbs_ElementType   myType;
       TopoDS_Shape          myShape;
@@ -776,11 +906,11 @@ namespace SMESH{
     class SMESHCONTROLS_EXPORT ElemGeomType: public virtual Predicate{
     public:
       ElemGeomType();
-      virtual void        SetMesh( const SMDS_Mesh* theMesh );
-      virtual bool        IsSatisfy( long theElementId );
-      void                SetType( SMDSAbs_ElementType theType );
-      virtual             SMDSAbs_ElementType GetType() const;
-      void                SetGeomType( SMDSAbs_GeometryType theType );
+      virtual void         SetMesh( const SMDS_Mesh* theMesh );
+      virtual bool         IsSatisfy( long theElementId );
+      void                 SetType( SMDSAbs_ElementType theType );
+      virtual              SMDSAbs_ElementType GetType() const;
+      void                 SetGeomType( SMDSAbs_GeometryType theType );
       virtual SMDSAbs_GeometryType GetGeomType() const;
 
     private:
@@ -790,6 +920,31 @@ namespace SMESH{
     };
     typedef boost::shared_ptr<ElemGeomType> ElemGeomTypePtr;
 
+    /*
+      Class       : CoplanarFaces
+      Description : Predicate to check angle between faces
+    */
+    class SMESHCONTROLS_EXPORT CoplanarFaces: public virtual Predicate
+    {
+    public:
+      CoplanarFaces();
+      void                 SetFace( long theID )                   { myFaceID = theID; }
+      long                 GetFace() const                         { return myFaceID; }
+      void                 SetTolerance (const double theToler)    { myToler = theToler; }
+      double               GetTolerance () const                   { return myToler; }
+      virtual              SMDSAbs_ElementType GetType() const     { return SMDSAbs_Face; }
+
+      virtual void         SetMesh( const SMDS_Mesh* theMesh );
+      virtual bool         IsSatisfy( long theElementId );
+
+    private:
+      TMeshModifTracer     myMeshModifTracer;
+      long                 myFaceID;
+      double               myToler;
+      std::set< long >     myCoplanarIDs;
+    };
+    typedef boost::shared_ptr<CoplanarFaces> CoplanarFacesPtr;
+
     /*
       FILTER
     */
@@ -804,13 +959,13 @@ namespace SMESH{
       virtual
       void
       GetElementsId( const SMDS_Mesh* theMesh,
-                    TIdSequence& theSequence );
+                     TIdSequence& theSequence );
 
       static
       void
       GetElementsId( const SMDS_Mesh* theMesh,
-                    PredicatePtr thePredicate,
-                    TIdSequence& theSequence );
+                     PredicatePtr thePredicate,
+                     TIdSequence& theSequence );
       
     protected:
       PredicatePtr myPredicate;
index 77b99b8bbc2e84ab50272a4307f400e5cc528b41..a47997532997e21c3a86e88e5c1c8600bc2d1a1d 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #include "Driver_Document.h"
 
 Driver_Document::Driver_Document():
index d8779719d6405ec3ae31ff72c30396e30d786c2f..7fc8e60d6537298f4533191f8b4cd73de0af021c 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #ifndef _INCLUDE_DRIVER_DOCUMENT
 #define _INCLUDE_DRIVER_DOCUMENT
 
index 0f4b51a85072b1ffe690bff6d5eac332793a50ab..73895176fe7faa33672b36a5a1c9221a762de713 100644 (file)
@@ -1,30 +1,33 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-//  SMESH Driver : implementaion of driver for reading and writing     
+
+//  SMESH Driver : implementaion of driver for reading and writing      
 //  File   : Mesh_Reader.cxx
 //  Module : SMESH
 //
 #include "Driver_Mesh.h"
 
+#include <utilities.h>
+
 using namespace std;
 
 Driver_Mesh::Driver_Mesh():
@@ -38,8 +41,42 @@ void Driver_Mesh::SetMeshId(int theMeshId)
   myMeshId = theMeshId;
 }
 
+void Driver_Mesh::SetMeshName(const std::string& theMeshName)
+{
+  myMeshName = theMeshName;
+}
+
+std::string Driver_Mesh::GetMeshName() const
+{
+  return myMeshName;
+}
+
 
 void Driver_Mesh::SetFile(const std::string& theFileName)
 {
   myFile = theFileName;
 }
+
+
+//================================================================================
+/*!
+ * \brief Stores an error message
+ *
+ * We consider an error fatal if none mesh can be read
+ */
+//================================================================================
+
+Driver_Mesh::Status Driver_Mesh::addMessage(const std::string& msg,
+                                            const bool         isFatal/*=false*/)
+{
+  if ( isFatal )
+    myErrorMessages.clear(); // warnings are useless if a fatal error encounters
+
+  myErrorMessages.push_back( msg );
+
+  MESSAGE(msg);
+#ifdef _DEBUG_
+  cout << msg << endl;
+#endif
+  return isFatal ? DRS_FAIL : DRS_WARN_SKIP_ELEM;
+}
index 9840ed034635bcb9f3af05ac8cc9f64f7778e3d9..45861a82a784b15b22d4467fb4f373721894d346 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH Driver : implementaion of driver for reading and writing  
 //  File   : Mesh_Reader.h
 //  Module : SMESH
 #define _INCLUDE_DRIVER_MESH
 
 #include <string>
+#include <vector>
 
 #ifdef WNT
- #if defined MESHDRIVER_EXPORTS
+ #if defined MESHDRIVER_EXPORTS || defined MeshDriver_EXPORTS
   #define MESHDRIVER_EXPORT __declspec( dllexport )
  #else
   #define MESHDRIVER_EXPORT __declspec( dllimport )
@@ -56,11 +58,16 @@ class MESHDRIVER_EXPORT Driver_Mesh
   virtual Status Perform() = 0;
   void SetMeshId(int theMeshId);
   void SetFile(const std::string& theFileName);
+  virtual void SetMeshName(const std::string& theMeshName);
+  virtual std::string GetMeshName() const;
 
  protected:
   std::string myFile;
+  std::string myMeshName;
   int myMeshId;
 
+  Status addMessage(const std::string& msg, const bool isFatal=false);
+  std::vector< std::string > myErrorMessages;
 };
 
 #endif
index b723c5c7b8cbb8ace9870e49e174ebd78b43c256..398d422914f946269b6804d74001d783b0b0ddd2 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #include "Driver_SMDS_Mesh.h"
 
 using namespace std;
index 6391a009b99488264dd67d179c92825cb3d88493..bb47cb5f1f118e3c79ed2aee6c19982d84b5929f 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #ifndef _INCLUDE_DRIVER_SMDS_MESH
 #define _INCLUDE_DRIVER_SMDS_MESH
 
index bb0b75de49008f6d5668ca40f6c5be5704adaadc..5cebe47ead766f5636a51b52d568d15bd3744c4c 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #include "Driver_SMESHDS_Mesh.h"
 
 using namespace std;
index 4ea15e0ad12a5577e168f66834f3ae4ac302aec0..4e21098ff6d267d76e5bfa6ff5270a558527c064 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #ifndef _INCLUDE_DRIVER_SMESHDS_MESH
 #define _INCLUDE_DRIVER_SMESHDS_MESH
 
index 0534f2a573df9cf2ada916cfbca25b89d32748f9..0062ee7744cec38f8eaee42768e7ba2f1626dd9a 100644 (file)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  SMESH Driver : implementaion of driver for reading and writing      
 #  File   : Makefile.in
 #  Author : Marc Tajchman (CEA)
@@ -53,4 +51,4 @@ libMeshDriver_la_CPPFLAGS = \
 libMeshDriver_la_LDFLAGS  = \
        ../SMESHDS/libSMESHDS.la \
        $(KERNEL_LDFLAGS) -lOpUtil \
-       $(CAS_LDPATH) -TKernel -lTKTopAlgo
+       $(CAS_LDPATH) -lTKernel -lTKTopAlgo
diff --git a/src/DriverCGNS/DriverCGNS_Read.cxx b/src/DriverCGNS/DriverCGNS_Read.cxx
new file mode 100644 (file)
index 0000000..97fafe3
--- /dev/null
@@ -0,0 +1,1195 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+// File      : DriverCGNS_Read.cxx
+// Created   : Thu Jun 30 10:33:31 2011
+// Author    : Edward AGAPOV (eap)
+
+#include "DriverCGNS_Read.hxx"
+
+#include "SMDS_MeshNode.hxx"
+#include "SMESHDS_Group.hxx"
+#include "SMESHDS_Mesh.hxx"
+#include "SMESH_Comment.hxx"
+
+#include <gp_XYZ.hxx>
+
+#include <cgnslib.h>
+
+#include <map>
+
+#if CGNS_VERSION < 3100
+# define cgsize_t int
+#endif
+
+#define NB_ZONE_SIZE_VAL 9
+#define CGNS_NAME_SIZE 33
+#define CGNS_STRUCT_RANGE_SZ 6
+
+using namespace std;
+
+namespace
+{
+  //================================================================================
+  /*!
+   * \brief Data of a zone
+   */
+  struct TZoneData
+  {
+    int                    _id;
+    int                    _nodeIdShift; // nb nodes in previously read zones
+    int                    _elemIdShift; // nb faces in previously read zones
+    int                    _nbNodes, _nbElems;
+    int                    _meshDim;
+    int                    _sizeX, _sizeY, _sizeZ, _nbCells; // structured
+    cgsize_t               _sizes[NB_ZONE_SIZE_VAL];
+    CGNS_ENUMT(ZoneType_t) _type;
+    map< int, int >        _nodeReplacementMap;/* key:   id of node to replace (in this zone),
+                                                  value: id of node to replace by (in another zone)
+                                                  id values include _nodeIdShift of the zones */
+    void SetSizeAndDim( cgsize_t* sizes, int meshDim )
+    {
+      _meshDim = meshDim;
+      memcpy( _sizes, sizes, NB_ZONE_SIZE_VAL*sizeof(cgsize_t));
+      _sizeX = _sizes[0];
+      _sizeY = _meshDim > 1 ? _sizes[1] : 0;
+      _sizeZ = _meshDim > 2 ? _sizes[2] : 0;
+      _nbCells = (_sizeX - 1) * ( _meshDim > 1 ? _sizeY : 1 ) * ( _meshDim > 2 ? _sizeZ : 1 );
+    }
+    bool IsStructured() const { return ( _type == CGNS_ENUMV( Structured )); }
+    int IndexSize() const { return IsStructured() ? _meshDim : 1; }
+    string ReadZonesConnection(int file, int base, const map< string, TZoneData >& zonesByName);
+    void ReplaceNodes( cgsize_t* ids, int nbIds, int idShift = 0 ) const;
+
+    // Methods for a structured zone
+
+    int NodeID( int i, int j, int k = 1 ) const
+    {
+      return _nodeIdShift + (k-1)*_sizeX*_sizeY + (j-1)*_sizeX + i;
+    }
+    int NodeID( const gp_XYZ& ijk ) const
+    {
+      return NodeID( int(ijk.X()), int(ijk.Y()), int(ijk.Z()));
+    }
+    void CellNodes( int i, int j, int k, cgsize_t* ids ) const
+    {
+      ids[0] = NodeID( i  , j  , k  );
+      ids[1] = NodeID( i  , j+1, k  );
+      ids[2] = NodeID( i+1, j+1, k  );
+      ids[3] = NodeID( i+1, j  , k  );
+      ids[4] = NodeID( i  , j  , k+1);
+      ids[5] = NodeID( i  , j+1, k+1);
+      ids[6] = NodeID( i+1, j+1, k+1);
+      ids[7] = NodeID( i+1, j  , k+1);
+    }
+    void CellNodes( int i, int j, cgsize_t* ids ) const
+    {
+      ids[0] = NodeID( i  , j   );
+      ids[1] = NodeID( i  , j+1 );
+      ids[2] = NodeID( i+1, j+1 );
+      ids[3] = NodeID( i+1, j   );
+    }
+    void IFaceNodes( int i, int j, int k, cgsize_t* ids ) const // face perpendiculaire to X (3D)
+    {
+      ids[0] = NodeID( i, j, k );
+      ids[1] = ids[0] + _sizeX*( i==_sizeX ? 1 : _sizeY );
+      ids[2] = ids[0] + _sizeX*( _sizeY + 1 );
+      ids[3] = ids[0] + _sizeX*( i==_sizeX ? _sizeY : 1 );
+    }
+    void JFaceNodes( int i, int j, int k, cgsize_t* ids ) const
+    {
+      ids[0] = NodeID( i, j, k );
+      ids[1] = ids[0] + ( j==_sizeY ? _sizeX*_sizeY : 1);
+      ids[2] = ids[0] + _sizeX*_sizeY + 1;
+      ids[3] = ids[0] + ( j==_sizeY ? 1 : _sizeX*_sizeY);
+    }
+    void KFaceNodes( int i, int j, int k, cgsize_t* ids ) const
+    {
+      ids[0] = NodeID( i, j, k );
+      ids[1] = ids[0] + ( k==_sizeZ ? 1 : _sizeX);
+      ids[2] = ids[0] + _sizeX + 1;
+      ids[3] = ids[0] + ( k==_sizeZ ? _sizeX : 1);
+    }
+    void IEdgeNodes( int i, int j, int k, cgsize_t* ids ) const // edge perpendiculaire to X (2D)
+    {
+      ids[0] = NodeID( i, j, 0 );
+      ids[1] = ids[0] + _sizeX;
+    }
+    void JEdgeNodes( int i, int j, int k, cgsize_t* ids ) const
+    {
+      ids[0] = NodeID( i, j, 0 );
+      ids[1] = ids[0] + 1;
+    }
+#define gpXYZ2IJK(METHOD)                                     \
+    void METHOD( const gp_XYZ& ijk, cgsize_t* ids ) const {        \
+      METHOD( int(ijk.X()), int(ijk.Y()), int(ijk.Z()), ids); \
+    }
+    gpXYZ2IJK( IFaceNodes )
+    gpXYZ2IJK( JFaceNodes )
+    gpXYZ2IJK( KFaceNodes )
+    gpXYZ2IJK( IEdgeNodes )
+    gpXYZ2IJK( JEdgeNodes )
+  };
+
+  //================================================================================
+  /*!
+   * \brief Iterator over nodes of the structired grid using FORTRAN multidimensional
+   * array ordering.
+   */
+  class TPointRangeIterator
+  {
+    int _beg[3], _end[3], _cur[3], _dir[3], _dim;
+    bool _more;
+  public:
+    TPointRangeIterator( const cgsize_t* range, int dim ):_dim(dim)
+    {
+      _more = false;
+      for ( int i = 0; i < dim; ++i )
+      {
+        _beg[i] = range[i];
+        _end[i] = range[i+dim];
+        _dir[i] = _end[i] < _beg[i] ? -1 : 1;
+        _end[i] += _dir[i];
+        _cur[i] = _beg[i];
+        if ( _end[i] - _beg[i] )
+          _more = true;
+      }
+//       for ( int i = dim; i < 3; ++i )
+//         _cur[i] = _beg[i] = _end[i] = _dir[i] = 0;
+    }
+    bool More() const
+    {
+      return _more;
+    }
+    gp_XYZ Next()
+    {
+      gp_XYZ res( _cur[0], _cur[1], _cur[2] );
+      for ( int i = 0; i < _dim; ++i )
+      {
+        _cur[i] += _dir[i];
+        if ( _cur[i]*_dir[i] < _end[i]*_dir[i] )
+          break;
+        if ( i+1 < _dim )
+          _cur[i] = _beg[i];
+        else
+          _more = false;
+      }
+      return res;
+    }
+    size_t Size()  const
+    {
+      size_t size = 1;
+      for ( int i = 0; i < _dim; ++i )
+        size *= _dir[i]*(_end[i]-_beg[i]);
+      return size;
+    }
+    gp_XYZ Begin() const { return gp_XYZ( _beg[0], _beg[1], _beg[2] ); }
+    //gp_XYZ End() const { return gp_XYZ( _end[0]-1, _end[1]-1, _end[2]-1 ); }
+  };
+
+  //================================================================================
+  /*!
+   * \brief Reads zone interface connectivity
+   *  \param file - file to read
+   *  \param base - base to read
+   *  \param zone - zone to replace nodes in
+   *  \param zonesByName - TZoneData by name
+   *  \retval string - warning message
+   *
+   * see // http://www.grc.nasa.gov/WWW/cgns/CGNS_docs_current/sids/cnct.html
+   */
+  //================================================================================
+
+  string TZoneData::ReadZonesConnection( int                             file,
+                                         int                             base,
+                                         const map< string, TZoneData >& zonesByName)
+  {
+    string error;
+
+    char connectName[ CGNS_NAME_SIZE ], donorName [ CGNS_NAME_SIZE ];
+
+    // ----------------------------
+    // read zone 1 to 1 interfaces
+    // ----------------------------
+    if ( IsStructured() )
+    {
+      int nb1to1 = 0;
+      if ( cg_n1to1 ( file, base, _id, &nb1to1) == CG_OK )
+      {
+        cgsize_t range[CGNS_STRUCT_RANGE_SZ], donorRange[CGNS_STRUCT_RANGE_SZ];
+        int transform[3] = {0,0,0};
+
+        for ( int I = 1; I <= nb1to1; ++I )
+        {
+          if ( cg_1to1_read(file, base, _id, I, connectName,
+                            donorName, range, donorRange, transform) == CG_OK )
+          {
+            map< string, TZoneData>::const_iterator n_z = zonesByName.find( donorName );
+            if ( n_z == zonesByName.end() )
+              continue; // donor zone not yet read
+            const TZoneData& zone2 = n_z->second;
+
+            // set up matrix to transform ijk of the zone to ijk of the zone2
+            gp_Mat T;
+            for ( int i = 0; i < _meshDim; ++i )
+              if ( transform[i] )
+              {
+                int row = Abs(transform[i]);
+                int col = i+1;
+                int val = transform[i] > 0 ? +1 : -1;
+                T( row, col ) = val;
+              }
+
+            // fill nodeReplacementMap
+            TPointRangeIterator rangeIt1( range, _meshDim );
+            TPointRangeIterator rangeIt2( donorRange, _meshDim );
+            gp_XYZ begin1 = rangeIt1.Begin(), begin2 = rangeIt2.Begin(), index1, index2;
+            if ( &zone2 == this )
+            {
+              // not to read twice the same interface with self
+              TPointRangeIterator rangeIt1bis( range, _meshDim );
+              if ( rangeIt1bis.More() )
+              {
+                index1 = rangeIt1bis.Next();
+                index2 = T * ( index1 - begin1 ) + begin2;
+                int node1 = NodeID( index1 );
+                int node2 = zone2.NodeID( index2 );
+                if ( _nodeReplacementMap.count( node2 ) &&
+                     _nodeReplacementMap[ node2 ] == node1 )
+                  continue; // this interface already read
+              }
+            }
+            while ( rangeIt1.More() )
+            {
+              index1 = rangeIt1.Next();
+              index2 = T * ( index1 - begin1 ) + begin2;
+              int node1 = NodeID( index1 );
+              int node2 = zone2.NodeID( index2 );
+              _nodeReplacementMap.insert( make_pair( node1, node2 ));
+            }
+          }
+          else
+          {
+            error = cg_get_error();
+          }
+        }
+      }
+      else
+      {
+        error = cg_get_error();
+      }
+    }
+
+    // ---------------------------------
+    // read general zone connectivities
+    // ---------------------------------
+    int nbConn = 0;
+    if ( cg_nconns( file, base, _id, &nbConn) == CG_OK )
+    {
+      cgsize_t nb, donorNb;
+      CGNS_ENUMT(GridLocation_t) location;
+      CGNS_ENUMT(GridConnectivityType_t) connectType;
+      CGNS_ENUMT(PointSetType_t) ptype, donorPtype;
+      CGNS_ENUMT(ZoneType_t) donorZonetype;
+      CGNS_ENUMT(DataType_t) donorDatatype;
+
+      for ( int I = 1; I <= nbConn; ++I )
+      {
+        if ( cg_conn_info(file, base, _id, I, connectName, &location, &connectType,
+                          &ptype, &nb, donorName, &donorZonetype, &donorPtype,
+                          &donorDatatype, &donorNb ) == CG_OK )
+        {
+          if ( location != CGNS_ENUMV( Vertex ))
+            continue; // we do not support cell-to-cell connectivity
+          if ( ptype != CGNS_ENUMV( PointList ) &&
+               ptype != CGNS_ENUMV( PointRange ))
+            continue;
+          if ( donorPtype != CGNS_ENUMV( PointList ) &&
+               donorPtype != CGNS_ENUMV( PointRange ))
+            continue;
+          
+          map< string, TZoneData>::const_iterator n_z = zonesByName.find( donorName );
+          if ( n_z == zonesByName.end() )
+            continue; // donor zone not yet read
+          const TZoneData& zone2 = n_z->second;
+
+          vector< cgsize_t > ids( nb * IndexSize() );
+          vector< cgsize_t > donorIds( donorNb * zone2.IndexSize() );
+          if (cg_conn_read ( file, base, _id, I,
+                             &ids[0], CGNS_ENUMV(Integer), &donorIds[0]) == CG_OK )
+          {
+            for ( int isThisZone = 0; isThisZone < 2; ++isThisZone )
+            {
+              const TZoneData&            zone = isThisZone ? *this : zone2;
+              CGNS_ENUMT(PointSetType_t) type = isThisZone ? ptype : donorPtype;
+              vector< cgsize_t >&      points = isThisZone ? ids : donorIds;
+              if ( type == CGNS_ENUMV( PointRange ))
+              {
+                TPointRangeIterator rangeIt( &points[0], zone._meshDim );
+                points.clear();
+                while ( rangeIt.More() )
+                  points.push_back ( NodeID( rangeIt.Next() ));
+              }
+              else if ( zone.IsStructured() )
+              {
+                vector< cgsize_t > resIDs; resIDs.reserve( points.size() / IndexSize() );
+                for ( size_t i = 0; i < points.size(); i += IndexSize() )
+                  resIDs.push_back( zone.NodeID( points[i+0], points[i+1], points[i+2] ));
+                resIDs.swap( points );
+              }
+              else if ( zone._nodeIdShift > 0 )
+              {
+                for ( size_t i = 0; i < points.size(); ++i )
+                  points[i] += zone._nodeIdShift;
+              }
+            }
+            for ( size_t i = 0; i < ids.size() && i < donorIds.size(); ++i )
+              _nodeReplacementMap.insert( make_pair( ids[i], donorIds[i] ));
+          }
+          else
+          {
+            error = cg_get_error();
+          }
+        }
+        else
+        {
+          error = cg_get_error();
+        }
+      }
+    }
+    else
+    {
+      error = cg_get_error();
+    }
+    return error;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Replaces node ids according to nodeReplacementMap to take into account
+   *        connection of zones
+   */
+  //================================================================================
+
+  void TZoneData::ReplaceNodes( cgsize_t* ids, int nbIds, int idShift/* = 0*/ ) const
+  {
+    if ( !_nodeReplacementMap.empty() )
+    {
+      map< int, int >::const_iterator it, end = _nodeReplacementMap.end();
+      for ( size_t i = 0; i < nbIds; ++i )
+        if (( it = _nodeReplacementMap.find( ids[i] + idShift)) != end )
+          ids[i] = it->second;
+        else
+          ids[i] += idShift;
+    }
+    else if ( idShift )
+    {
+      for ( size_t i = 0; i < nbIds; ++i )
+        ids[i] += idShift;
+    }
+  }
+  //================================================================================
+  /*!
+   * \brief functions adding an element of a particular type
+   */
+  SMDS_MeshElement* add_0D(cgsize_t* ids, SMESHDS_Mesh* mesh, int ID)
+  {
+    return mesh->Add0DElementWithID( ids[0], ID );
+  }
+  SMDS_MeshElement* add_BAR_2(cgsize_t* ids, SMESHDS_Mesh* mesh, int ID)
+  {
+    return mesh->AddEdgeWithID( ids[0], ids[1], ID );
+  }
+  SMDS_MeshElement* add_BAR_3(cgsize_t* ids, SMESHDS_Mesh* mesh, int ID)
+  {
+    return mesh->AddEdgeWithID( ids[0], ids[1], ids[2], ID );
+  }
+  SMDS_MeshElement* add_TRI_3(cgsize_t* ids, SMESHDS_Mesh* mesh, int ID)
+  {
+    return mesh->AddFaceWithID( ids[0], ids[2], ids[1], ID );
+  }
+  SMDS_MeshElement* add_TRI_6(cgsize_t* ids, SMESHDS_Mesh* mesh, int ID)
+  {
+    return mesh->AddFaceWithID( ids[0], ids[2], ids[1], ids[5], ids[4], ids[3], ID );
+  }
+  SMDS_MeshElement* add_QUAD_4(cgsize_t* ids, SMESHDS_Mesh* mesh, int ID)
+  {
+    return mesh->AddFaceWithID( ids[0], ids[3], ids[2], ids[1], ID );
+  }
+  SMDS_MeshElement* add_QUAD_8(cgsize_t* ids, SMESHDS_Mesh* mesh, int ID)
+  {
+    return mesh->AddFaceWithID( ids[0],ids[3],ids[2],ids[1],ids[7],ids[6],ids[5],ids[4], ID );
+  }
+  SMDS_MeshElement* add_QUAD_9(cgsize_t* ids, SMESHDS_Mesh* mesh, int ID)
+  {
+    return mesh->AddFaceWithID( ids[0],ids[3],ids[2],ids[1],ids[7],ids[6],ids[5],ids[4],ids[8], ID);
+  }
+  SMDS_MeshElement* add_TETRA_4(cgsize_t* ids, SMESHDS_Mesh* mesh, int ID)
+  {
+    return mesh->AddVolumeWithID( ids[0], ids[2], ids[1], ids[3], ID );
+  }
+  SMDS_MeshElement* add_TETRA_10(cgsize_t* ids, SMESHDS_Mesh* mesh, int ID)
+  {
+    return mesh->AddVolumeWithID( ids[0],ids[2],ids[1],ids[3],ids[6],
+                                  ids[5],ids[4],ids[7],ids[9],ids[8], ID );
+  }
+  SMDS_MeshElement* add_PYRA_5(cgsize_t* ids, SMESHDS_Mesh* mesh, int ID)
+  {
+    return mesh->AddVolumeWithID( ids[0],ids[3],ids[2],ids[1],ids[4],ID );
+  }
+  SMDS_MeshElement* add_PYRA_13(cgsize_t* ids, SMESHDS_Mesh* mesh, int ID)
+  {
+    return mesh->AddVolumeWithID( ids[0],ids[3],ids[2],ids[1],ids[4],ids[8],ids[7],
+                                  ids[6],ids[5],ids[9],ids[12],ids[11],ids[10], ID );
+  }
+  SMDS_MeshElement* add_PENTA_6(cgsize_t* ids, SMESHDS_Mesh* mesh, int ID)
+  {
+    return mesh->AddVolumeWithID( ids[0],ids[2],ids[1],ids[3],ids[5],ids[4], ID );
+  }
+  SMDS_MeshElement* add_PENTA_15(cgsize_t* ids, SMESHDS_Mesh* mesh, int ID)
+  {
+    return mesh->AddVolumeWithID( ids[0],ids[2],ids[1],ids[3],ids[5],ids[4],ids[8],ids[7],
+                                  ids[6],ids[9],ids[11],ids[10],ids[14],ids[13],ids[12], ID );
+  }
+  SMDS_MeshElement* add_HEXA_8(cgsize_t* ids, SMESHDS_Mesh* mesh, int ID)
+  {
+    return mesh->AddVolumeWithID( ids[0],ids[3],ids[2],ids[1],ids[4],ids[7],ids[6],ids[5], ID );
+  }
+  SMDS_MeshElement* add_HEXA_20(cgsize_t* ids, SMESHDS_Mesh* mesh, int ID)
+  {
+    return mesh->AddVolumeWithID( ids[0],ids[3],ids[2],ids[1],ids[4],ids[7],ids[6],
+                                  ids[5],ids[11],ids[10],ids[9],ids[8],ids[12],ids[15],
+                                  ids[14],ids[13],ids[19],ids[18],ids[17],ids[16], ID );
+  }
+  SMDS_MeshElement* add_HEXA_27(cgsize_t* ids, SMESHDS_Mesh* mesh, int ID)
+  {
+    return mesh->AddVolumeWithID( ids[0],ids[3],ids[2],ids[1],ids[4],ids[7],ids[6],
+                                  ids[5],ids[11],ids[10],ids[9],ids[8],ids[12],ids[15],
+                                  ids[14],ids[13],ids[19],ids[18],ids[17],ids[16],
+                                  ids[20],ids[24],ids[23],ids[22],ids[21],ids[25],ids[26], ID );
+  }
+  SMDS_MeshElement* add_NGON(cgsize_t* ids, SMESHDS_Mesh* mesh, int ID)
+  {
+    vector<int> idVec( ids[0] );
+    for ( int i = 0; i < ids[0]; ++i )
+      idVec[ i ] = (int) ids[ i + 1];
+    return mesh->AddPolygonalFaceWithID( idVec, ID );
+  }
+
+  typedef SMDS_MeshElement* (* PAddElemFun) (cgsize_t* ids, SMESHDS_Mesh* mesh, int ID);
+  
+  //================================================================================
+  /*!
+   * \brief Return an array of functions each adding an element of a particular type
+   */
+  //================================================================================
+
+  PAddElemFun* getAddElemFunTable()
+  {
+    static vector< PAddElemFun > funVec;
+    if ( funVec.empty() )
+    {
+      funVec.resize( NofValidElementTypes, (PAddElemFun)0 );
+      funVec[ CGNS_ENUMV( NODE     )] = add_0D      ;
+      funVec[ CGNS_ENUMV( BAR_2    )] = add_BAR_2   ;
+      funVec[ CGNS_ENUMV( BAR_3    )] = add_BAR_3   ;
+      funVec[ CGNS_ENUMV( TRI_3    )] = add_TRI_3   ;
+      funVec[ CGNS_ENUMV( TRI_6    )] = add_TRI_6   ;
+      funVec[ CGNS_ENUMV( QUAD_4   )] = add_QUAD_4  ;
+      funVec[ CGNS_ENUMV( QUAD_8   )] = add_QUAD_8  ;
+      funVec[ CGNS_ENUMV( QUAD_9   )] = add_QUAD_9  ;
+      funVec[ CGNS_ENUMV( TETRA_4  )] = add_TETRA_4 ;
+      funVec[ CGNS_ENUMV( TETRA_10 )] = add_TETRA_10;
+      funVec[ CGNS_ENUMV( PYRA_5   )] = add_PYRA_5  ;
+      funVec[ CGNS_ENUMV( PYRA_13  )] = add_PYRA_13 ;
+      funVec[ CGNS_ENUMV( PYRA_14  )] = add_PYRA_13 ;
+      funVec[ CGNS_ENUMV( PENTA_6  )] = add_PENTA_6 ;
+      funVec[ CGNS_ENUMV( PENTA_15 )] = add_PENTA_15;
+      funVec[ CGNS_ENUMV( PENTA_18 )] = add_PENTA_15;
+      funVec[ CGNS_ENUMV( HEXA_8   )] = add_HEXA_8  ;
+      funVec[ CGNS_ENUMV( HEXA_20  )] = add_HEXA_20 ;
+      funVec[ CGNS_ENUMV( HEXA_27  )] = add_HEXA_27 ;
+      funVec[ CGNS_ENUMV( NGON_n   )] = add_NGON    ;
+    }
+    return &funVec[0];
+  }
+
+  //================================================================================
+  /*!
+   * \brief Finds an existing boundary element
+   */
+  //================================================================================
+
+  const SMDS_MeshElement* findElement(const cgsize_t*     nodeIDs,
+                                      const int           nbNodes,
+                                      const SMESHDS_Mesh* mesh)
+  {
+    const SMDS_MeshNode* nn[4]; // look for quad4 or seg2
+    if (( nn[0] = mesh->FindNode( nodeIDs[0] )))
+    {
+      SMDSAbs_ElementType eType = nbNodes==4 ? SMDSAbs_Face : SMDSAbs_Edge;
+      SMDS_ElemIteratorPtr eIt = nn[0]->GetInverseElementIterator( eType );
+      if ( eIt->more() )
+        for ( int i = 1; i < nbNodes; ++i )
+          nn[i] = mesh->FindNode( nodeIDs[i] );
+      while ( eIt->more() )
+      {
+        const SMDS_MeshElement* e = eIt->next();
+        if ( e->NbNodes() == nbNodes )
+        {
+          bool elemOK = true;
+          for ( int i = 1; i < nbNodes && elemOK; ++i )
+            elemOK = ( e->GetNodeIndex( nn[i] ) >= 0 );
+          if ( elemOK )
+            return e;
+        }
+      } 
+    }
+    return 0;
+  }
+
+} // namespace
+
+//================================================================================
+/*!
+ * \brief Perform reading a myMeshId-th mesh
+ */
+//================================================================================
+
+Driver_Mesh::Status DriverCGNS_Read::Perform()
+{
+  myErrorMessages.clear();
+
+  Status aResult;
+  if (( aResult = open() ) != DRS_OK )
+    return aResult;
+
+  // read nb of meshes (CGNSBase_t)
+  if ( myMeshId < 0 || myMeshId >= GetNbMeshes(aResult))
+    return addMessage( SMESH_Comment("Invalid mesh index :") << myMeshId );
+
+  // read a name and a dimension of the mesh
+  const int cgnsBase = myMeshId + 1;
+  char meshName[CGNS_NAME_SIZE];
+  int meshDim, spaceDim;
+  if ( cg_base_read( _fn, cgnsBase, meshName, &meshDim, &spaceDim) != CG_OK )
+    return addMessage( cg_get_error() );
+
+  if ( spaceDim < 1 || spaceDim > 3 )
+    return addMessage( SMESH_Comment("Invalid space dimension: ") << spaceDim
+                       << " in mesh '" << meshName << "'");
+
+  myMeshName = meshName;
+
+  // read nb of domains (Zone_t) in the mesh
+  int nbZones = 0;
+  if ( cg_nzones (_fn, cgnsBase, &nbZones) != CG_OK )
+    return addMessage( cg_get_error() );
+
+  if ( nbZones < 1 )
+    return addMessage( SMESH_Comment("Empty mesh: '") << meshName << "'");
+
+  // read the domains (zones)
+  // ------------------------
+  map< string, TZoneData > zonesByName;
+  char name[CGNS_NAME_SIZE];
+  cgsize_t sizes[NB_ZONE_SIZE_VAL];
+  memset(sizes, 0, NB_ZONE_SIZE_VAL * sizeof(cgsize_t));
+
+  const SMDS_MeshInfo& meshInfo = myMesh->GetMeshInfo();
+  int groupID = myMesh->GetGroups().size();
+
+  for ( int iZone = 1; iZone <= nbZones; ++iZone )
+  {
+    // size and name of a zone
+    if ( cg_zone_read( _fn, cgnsBase, iZone, name, sizes) != CG_OK) {
+      addMessage( cg_get_error() );
+      continue;
+    }
+    TZoneData& zone = zonesByName[ name ];
+    zone._id          = iZone;
+    zone._nodeIdShift = meshInfo.NbNodes();
+    zone._elemIdShift = meshInfo.NbElements();
+    zone.SetSizeAndDim( sizes, meshDim );
+
+    // mesh type of the zone
+    if ( cg_zone_type ( _fn, cgnsBase, iZone, &zone._type) != CG_OK) {
+      addMessage( cg_get_error() );
+      continue;
+    }
+
+    switch ( zone._type )
+    {
+    case CGNS_ENUMV( Unstructured ):
+    case CGNS_ENUMV( Structured ):
+      break;
+    case CGNS_ENUMV( ZoneTypeNull ):
+      addMessage( "Meshes with ZoneTypeNull are not supported");
+      continue;
+    case CGNS_ENUMV( ZoneTypeUserDefined ):
+      addMessage( "Meshes with ZoneTypeUserDefined are not supported");
+      continue;
+    default:
+      addMessage( "Unknown ZoneType_t");
+      continue;
+    }
+
+    // -----------
+    // Read nodes
+    // -----------
+
+    if ( cg_ncoords( _fn, cgnsBase, iZone, &spaceDim) != CG_OK ) {
+      addMessage( cg_get_error() );
+      continue;
+    }
+    if ( spaceDim < 1 ) {
+      addMessage( SMESH_Comment("No coordinates defined in zone ")
+                  << iZone << " of Mesh " << myMeshId );
+      continue;
+    }
+    // read coordinates
+
+    cgsize_t rmin[3] = {1,1,1}; // range of nodes to read
+    cgsize_t rmax[3] = {1,1,1};
+    int nbNodes = rmax[0] = zone._sizes[0];
+    if ( zone.IsStructured())
+      for ( int i = 1; i < meshDim; ++i )
+        nbNodes *= rmax[i] = zone._sizes[i];
+
+    vector<double> coords[3];
+    for ( int c = 1; c <= spaceDim; ++c)
+    {
+      coords[c-1].resize( nbNodes );
+
+      CGNS_ENUMV( DataType_t ) type;
+      if ( cg_coord_info( _fn, cgnsBase, iZone, c, &type, name) != CG_OK ||
+           cg_coord_read( _fn, cgnsBase, iZone, name, CGNS_ENUMV(RealDouble),
+                          rmin, rmax, (void*)&(coords[c-1][0])) != CG_OK)
+      {
+        addMessage( cg_get_error() );
+        coords[c-1].clear();
+        break;
+      }
+    }
+    if ( coords[ spaceDim-1 ].empty() )
+      continue; // there was an error while reading coordinates 
+
+    // fill coords with zero if spaceDim < 3
+    for ( int c = 2; c <= 3; ++c)
+      if ( coords[ c-1 ].empty() )
+        coords[ c-1 ].resize( nbNodes, 0.0 );
+
+    // create nodes
+    try {
+      for ( int i = 0; i < nbNodes; ++i )
+        myMesh->AddNodeWithID( coords[0][i], coords[1][i], coords[2][i], i+1+zone._nodeIdShift );
+    }
+    catch ( std::exception& exc ) // expect std::bad_alloc
+    {
+      addMessage( exc.what() );
+      break;
+    }
+
+    // Read connectivity between zones. Nodes of the zone interface will be
+    // replaced withing the zones read later
+    string err = zone.ReadZonesConnection( _fn, cgnsBase, zonesByName );
+    if ( !err.empty() )
+      addMessage( err );
+
+    // --------------
+    // Read elements
+    // --------------
+    if ( zone.IsStructured())
+    {
+      int nbI = zone._sizeX - 1, nbJ = zone._sizeY - 1, nbK = zone._sizeZ - 1;
+      cgsize_t nID[8];
+      if ( meshDim > 2 && nbK > 0 )
+      {
+        for ( int k = 1; k <= nbK; ++k )
+          for ( int j = 1; j <= nbJ; ++j )
+            for ( int i = 1; i <= nbI; ++i )
+            {
+              zone.CellNodes( i, j, k, nID );
+              zone.ReplaceNodes( nID, 8 );
+              myMesh->AddVolumeWithID(nID[0],nID[1],nID[2],nID[3],nID[4],nID[5],nID[6],nID[7],
+                                      meshInfo.NbElements()+1);
+            }
+      }
+      else if ( meshDim > 1 && nbJ > 0 )
+      {
+        for ( int j = 1; j <= nbJ; ++j )
+          for ( int i = 1; i <= nbI; ++i )
+          {
+            zone.CellNodes( i, j, nID );
+            zone.ReplaceNodes( nID, 4 );
+            myMesh->AddFaceWithID(nID[0],nID[1],nID[2],nID[3], meshInfo.NbElements()+1);
+          }
+      }
+      else if ( meshDim > 0 && nbI > 0 )
+      {
+        nID[0] = zone.NodeID( 1, 0, 0 );
+        for ( int i = 1; i <= nbI; ++i, ++nID[0] )
+        {
+          nID[1] = nID[0]+1;
+          zone.ReplaceNodes( nID, 2 );
+          myMesh->AddEdgeWithID(nID[0],nID[1], meshInfo.NbElements()+1);
+        }
+      }
+    }
+    else
+    {
+      // elements can be stored in different sections each dedicated to one element type
+      int nbSections = 0;
+      if ( cg_nsections( _fn, cgnsBase, iZone, &nbSections) != CG_OK)
+      {
+        addMessage( cg_get_error() );
+        continue;
+      }
+      PAddElemFun* addElemFuns = getAddElemFunTable(), curAddElemFun = 0;
+      int nbNotSuppElem = 0; // nb elements of not supported types
+      bool polyhedError = false; // error at polyhedron creation
+
+      // read element data
+
+      CGNS_ENUMT( ElementType_t ) elemType;
+      cgsize_t start, end; // range of ids of elements of a zone
+      cgsize_t eDataSize = 0;
+      int nbBnd, parent_flag;
+      for ( int iSec = 1; iSec <= nbSections; ++iSec )
+      {
+        if ( cg_section_read( _fn, cgnsBase, iZone, iSec, name, &elemType,
+                              &start, &end, &nbBnd, &parent_flag) != CG_OK ||
+             cg_ElementDataSize( _fn, cgnsBase, iZone, iSec, &eDataSize ) != CG_OK )
+        {
+          addMessage( cg_get_error() );
+          continue;
+        }
+        vector< cgsize_t > elemData( eDataSize );
+        if ( cg_elements_read( _fn, cgnsBase, iZone, iSec, &elemData[0], NULL ) != CG_OK )
+        {
+          addMessage( cg_get_error() );
+          continue;
+        }
+        // store elements
+
+        int pos = 0, cgnsNbNodes = 0, elemID = start + zone._elemIdShift;
+        cg_npe( elemType, &cgnsNbNodes ); // get nb nodes by element type
+        curAddElemFun = addElemFuns[ elemType ];
+        SMDS_MeshElement* newElem = 0;
+        const SMDS_MeshElement* face;
+
+        while ( pos < eDataSize )
+        {
+          CGNS_ENUMT( ElementType_t ) currentType = elemType;
+          if ( currentType == CGNS_ENUMV( MIXED )) {
+            //ElementConnectivity = Etype1, Node11, Node21, ... NodeN1,
+            //                      Etype2, Node12, Node22, ... NodeN2,
+            //                      ...
+            //                      EtypeM, Node1M, Node2M, ... NodeNM
+            currentType = (CGNS_ENUMT(ElementType_t)) elemData[ pos++ ];
+            cg_npe( currentType, &cgnsNbNodes );
+            curAddElemFun = addElemFuns[ currentType ];
+          }
+          if ( cgnsNbNodes < 1 ) // poly elements
+          {
+            if ( currentType == CGNS_ENUMV( NFACE_n )) // polyhedron
+            {
+              //ElementConnectivity = Nfaces1, Face11, Face21, ... FaceN1,
+              //                      Nfaces2, Face12, Face22, ... FaceN2,
+              //                      ...
+              //                      NfacesM, Face1M, Face2M, ... FaceNM
+              const int nbFaces = elemData[ pos++ ];
+              vector<int> quantities( nbFaces );
+              vector<const SMDS_MeshNode*> nodes, faceNodes;
+              nodes.reserve( nbFaces * 4 );
+              for ( int iF = 0; iF < nbFaces; ++iF )
+              {
+                const int faceID = std::abs( elemData[ pos++ ]) + zone._elemIdShift; 
+                if (( face = myMesh->FindElement( faceID )) && face->GetType() == SMDSAbs_Face )
+                {
+                  const bool reverse = ( elemData[ pos-1 ] < 0 );
+                  const int    iQuad = face->IsQuadratic() ? 1 : 0;
+                  SMDS_ElemIteratorPtr nIter = face->interlacedNodesElemIterator();
+                  faceNodes.assign( SMDS_MeshElement::iterator( nIter ),
+                                    SMDS_MeshElement::iterator());
+                  if ( iQuad && reverse )
+                    nodes.push_back( faceNodes[0] );
+                  if ( reverse )
+                    nodes.insert( nodes.end(), faceNodes.rbegin(), faceNodes.rend() - iQuad );
+                  else
+                    nodes.insert( nodes.end(), faceNodes.begin(), faceNodes.end() );
+
+                  quantities[ iF ] = face->NbNodes();
+                }
+                else {
+                  polyhedError = true;
+                  break;
+                }
+              }
+              if ( quantities.back() )
+              {
+                myMesh->AddPolyhedralVolumeWithID( nodes, quantities, elemID );
+              }
+            }
+            else if ( currentType == CGNS_ENUMV( NGON_n )) // polygon
+            {
+              // ElementConnectivity = Nnodes1, Node11, Node21, ... NodeN1,
+              //                       Nnodes2, Node12, Node22, ... NodeN2,
+              //                       ...
+              //                       NnodesM, Node1M, Node2M, ... NodeNM
+              const int nbNodes = elemData[ pos ];
+              zone.ReplaceNodes( &elemData[pos+1], nbNodes, zone._nodeIdShift );
+              newElem = add_NGON( &elemData[pos  ], myMesh, elemID );
+              pos += nbNodes + 1;
+            }
+          }
+          else // standard elements
+          {
+            zone.ReplaceNodes( &elemData[pos], cgnsNbNodes, zone._nodeIdShift );
+            newElem = curAddElemFun( &elemData[pos], myMesh, elemID );
+            pos += cgnsNbNodes;
+            nbNotSuppElem += int( newElem && newElem->NbNodes() != cgnsNbNodes );
+          }
+          elemID++;
+
+        } // loop on elemData
+      } // loop on cgns sections
+
+      if ( nbNotSuppElem > 0 )
+        addMessage( SMESH_Comment(nbNotSuppElem) << " elements of not supported types"
+                    << " have beem converted to close types");
+      if ( polyhedError )
+        addMessage( "Some polyhedral elements have been skipped due to internal(?) errors" );
+
+    } // reading unstructured elements
+
+    zone._nbNodes = meshInfo.NbNodes() - zone._nodeIdShift;
+    zone._nbElems = meshInfo.NbElements() - zone._elemIdShift;
+
+    // -------------------------------------------
+    // Read Boundary Conditions into SMESH groups
+    // -------------------------------------------
+    int nbBC = 0;
+    if ( cg_nbocos( _fn, cgnsBase, iZone, &nbBC) == CG_OK )
+    {
+      CGNS_ENUMT( BCType_t ) bcType;
+      CGNS_ENUMT( PointSetType_t ) psType;
+      CGNS_ENUMT( DataType_t ) normDataType;
+      cgsize_t nbPnt, normFlag;
+      int normIndex[3], nbDS;
+      for ( int iBC = 1; iBC <= nbBC; ++iBC )
+      {
+        if ( cg_boco_info( _fn, cgnsBase, iZone, iBC, name, &bcType, &psType,
+                           &nbPnt, normIndex, &normFlag, &normDataType, &nbDS ) != CG_OK )
+        {
+          addMessage( cg_get_error() );
+          continue;
+        }
+        vector< cgsize_t > ids( nbPnt * zone.IndexSize() );
+        CGNS_ENUMT( GridLocation_t ) location;
+        if ( cg_boco_read( _fn, cgnsBase, iZone, iBC, &ids[0], NULL ) != CG_OK ||
+             cg_boco_gridlocation_read( _fn, cgnsBase, iZone, iBC, &location) != CG_OK )
+        {
+          addMessage( cg_get_error() );
+          continue;
+        }
+        SMDSAbs_ElementType elemType = SMDSAbs_All;
+        switch ( location ) {
+        case CGNS_ENUMV( Vertex      ): elemType = SMDSAbs_Node; break;
+        case CGNS_ENUMV( FaceCenter  ): elemType = SMDSAbs_Face; break;
+        case CGNS_ENUMV( IFaceCenter ): elemType = SMDSAbs_Face; break;
+        case CGNS_ENUMV( JFaceCenter ): elemType = SMDSAbs_Face; break;
+        case CGNS_ENUMV( KFaceCenter ): elemType = SMDSAbs_Face; break;
+        case CGNS_ENUMV( EdgeCenter  ): elemType = SMDSAbs_Edge; break;
+        default:;
+        }
+        SMESHDS_Group* group = new SMESHDS_Group ( groupID++, myMesh, elemType );
+        myMesh->AddGroup( group );
+        SMESH_Comment groupName( name ); groupName << " " << cg_BCTypeName( bcType );
+        group->SetStoreName( groupName.c_str() );
+        SMDS_MeshGroup& groupDS = group->SMDSGroup();
+
+        if ( elemType == SMDSAbs_Node )
+        {
+          if ( zone.IsStructured() )
+          {
+            vector< cgsize_t > nodeIds;
+            if ( psType == CGNS_ENUMV( PointRange ))
+            {
+              // nodes are given as (ijkMin, ijkMax)
+              TPointRangeIterator idIt( & ids[0], meshDim );
+              nodeIds.reserve( idIt.Size() );
+              while ( idIt.More() )
+                nodeIds.push_back( zone.NodeID( idIt.Next() ));
+            }
+            else
+            {
+              // nodes are given as (ijk1, ijk2, ..., ijkN)
+              nodeIds.reserve( ids.size() / meshDim );
+              for ( size_t i = 0; i < ids.size(); i += meshDim )
+                nodeIds.push_back( zone.NodeID( ids[i], ids[i+1], ids[i+2] ));
+            }
+            ids.swap( nodeIds );
+          }
+          else if ( zone._nodeIdShift )
+          {
+            for ( size_t i = 0; i < ids.size(); ++i )
+              ids[i] += zone._nodeIdShift;
+          }
+          zone.ReplaceNodes( &ids[0], ids.size() );
+
+          for ( size_t i = 0; i < ids.size(); ++i )
+            if ( const SMDS_MeshNode* n = myMesh->FindNode( ids[i] ))
+              groupDS.Add( n );
+        }
+        else // BC applied to elements
+        {
+          if ( zone.IsStructured() )
+          {
+            int axis = 0; // axis perpendiculaire to which boundary elements are oriented
+            if ( ids.size() >= meshDim * 2 )
+            {
+              for ( ; axis < meshDim; ++axis )
+                if ( ids[axis] - ids[axis+meshDim] == 0 )
+                  break;
+            }
+            else
+            {
+              for ( ; axis < meshDim; ++axis )
+                if ( normIndex[axis] != 0 )
+                  break;
+            }
+            if ( axis == meshDim )
+            {
+              addMessage( SMESH_Comment("Invalid NormalIndex in BC ") << name );
+              continue;
+            }
+            const int nbElemNodesByDim[] = { 1, 2, 4, 8 };
+            const int nbElemNodes = nbElemNodesByDim[ meshDim ];
+
+            if ( psType == CGNS_ENUMV( PointRange ) ||
+                 psType == CGNS_ENUMV( ElementRange ))
+            {
+              // elements are given as (ijkMin, ijkMax)
+              typedef void (TZoneData::*PGetNodesFun)( const gp_XYZ& ijk, cgsize_t* ids ) const;
+              PGetNodesFun getNodesFun = 0;
+              if ( elemType == SMDSAbs_Face  && meshDim == 3 )
+                switch ( axis ) {
+                case 0: getNodesFun = & TZoneData::IFaceNodes;
+                case 1: getNodesFun = & TZoneData::JFaceNodes;
+                case 2: getNodesFun = & TZoneData::KFaceNodes;
+                }
+              else if ( elemType == SMDSAbs_Edge && meshDim == 2 )
+                switch ( axis ) {
+                case 0: getNodesFun = & TZoneData::IEdgeNodes;
+                case 1: getNodesFun = & TZoneData::JEdgeNodes;
+                }
+              if ( !getNodesFun )
+              {
+                addMessage( SMESH_Comment("Unsupported BC location in BC ") << name
+                            << " " << cg_GridLocationName( location )
+                            << " in " << meshDim << " mesh");
+                continue;
+              }
+              TPointRangeIterator rangeIt( & ids[0], meshDim );
+              vector< cgsize_t > elemNodeIds( rangeIt.Size() * nbElemNodes );
+              for ( int i = 0; rangeIt.More(); i+= nbElemNodes )
+                (zone.*getNodesFun)( rangeIt.Next(), &elemNodeIds[i] );
+
+              ids.swap( elemNodeIds );
+            }
+            else
+            {
+              // elements are given as (ijk1, ijk2, ..., ijkN)
+              typedef void (TZoneData::*PGetNodesFun)( int i, int j, int k, cgsize_t* ids ) const;
+              PGetNodesFun getNodesFun = 0;
+              if ( elemType == SMDSAbs_Face )
+                switch ( axis ) {
+                case 0: getNodesFun = & TZoneData::IFaceNodes;
+                case 1: getNodesFun = & TZoneData::JFaceNodes;
+                case 2: getNodesFun = & TZoneData::KFaceNodes;
+                }
+              else if ( elemType == SMDSAbs_Edge && meshDim == 2 )
+                switch ( axis ) {
+                case 0: getNodesFun = & TZoneData::IEdgeNodes;
+                case 1: getNodesFun = & TZoneData::JEdgeNodes;
+                }
+              if ( !getNodesFun )
+              {
+                addMessage( SMESH_Comment("Unsupported BC location in BC ") << name
+                            << " " << cg_GridLocationName( location )
+                            << " in " << meshDim << " mesh");
+                continue;
+              }
+              vector< cgsize_t > elemNodeIds( ids.size()/meshDim * nbElemNodes );
+              for ( size_t i = 0, j = 0; i < ids.size(); i += meshDim, j += nbElemNodes )
+                (zone.*getNodesFun)( ids[i], ids[i+1], ids[i+2], &elemNodeIds[j] );
+
+              ids.swap( elemNodeIds );
+            }
+            zone.ReplaceNodes( &ids[0], ids.size() );
+
+            PAddElemFun addElemFun = 0;
+            switch ( meshDim ) {
+            case 1: addElemFun = & add_BAR_2;
+            case 2: addElemFun = & add_QUAD_4;
+            case 3: addElemFun = & add_HEXA_8;
+            }
+            int elemID = meshInfo.NbElements();
+            const SMDS_MeshElement* elem = 0;
+            for ( size_t i = 0; i < ids.size(); i += nbElemNodes )
+            {
+              if ( iZone == 1 || !( elem = findElement( &ids[i], nbElemNodes, myMesh )))
+                elem = addElemFun( &ids[i], myMesh, ++elemID );
+              groupDS.Add( elem );
+            }
+          }
+          else // unstructured zone
+          {
+            if ( zone._elemIdShift )
+              for ( size_t i = 0; i < ids.size(); ++i )
+                ids[i] += zone._elemIdShift;
+
+            if ( psType == CGNS_ENUMV( PointRange ) && ids.size() == 2 )
+            {
+              for ( size_t i = ids[0]; i <= ids[1]; ++i )
+                if ( const SMDS_MeshElement* e = myMesh->FindElement( i ))
+                  groupDS.Add( e );
+            }
+            else
+            {
+              for ( size_t i = 0; i < ids.size(); ++i )
+                if ( const SMDS_MeshElement* e = myMesh->FindElement( ids[i] ))
+                  groupDS.Add( e );
+            }
+          }
+        } // end "BC applied to elements"
+
+        // to have group type according to a real elem type
+        group->SetType( groupDS.GetType() );
+
+      } // loop on BCs of the zone
+    }
+    else
+    {
+      addMessage( cg_get_error() );
+    }
+  } // loop on the zones of a mesh
+
+
+  // ------------------------------------------------------------------------
+  // Make groups for multiple zones and remove free nodes at zone interfaces
+  // ------------------------------------------------------------------------
+  map< string, TZoneData >::iterator nameZoneIt = zonesByName.begin();
+  for ( ; nameZoneIt != zonesByName.end(); ++nameZoneIt )
+  {
+    TZoneData& zone = nameZoneIt->second;
+    if ( zone._nbElems == 0 ) continue;
+    if ( zone._nbElems == meshInfo.NbElements() ) break; // there is only one non-empty zone
+
+    // make a group
+    SMDSAbs_ElementType elemType = myMesh->GetElementType( zone._elemIdShift + 1,
+                                                           /*iselem=*/true );
+    SMESHDS_Group* group = new SMESHDS_Group ( groupID++, myMesh, elemType );
+    myMesh->AddGroup( group );
+    group->SetStoreName( nameZoneIt->first.c_str() );
+    SMDS_MeshGroup& groupDS = group->SMDSGroup();
+
+    for ( int i = 1; i <= zone._nbElems; ++i )
+      if ( const SMDS_MeshElement* e = myMesh->FindElement( i + zone._elemIdShift ))
+        groupDS.Add( e );
+
+    // remove free nodes
+    map< int, int >::iterator nnRmKeepIt = zone._nodeReplacementMap.begin();
+    for ( ; nnRmKeepIt != zone._nodeReplacementMap.end(); ++nnRmKeepIt )
+      if ( const SMDS_MeshNode* n = myMesh->FindNode( nnRmKeepIt->first ))
+        if ( n->NbInverseElements() == 0 )
+          myMesh->RemoveFreeNode( n, (SMESHDS_SubMesh *)0, /*fromGroups=*/false );
+  }
+
+  aResult = myErrorMessages.empty() ? DRS_OK : DRS_WARN_SKIP_ELEM;
+
+  return aResult;
+}
+
+//================================================================================
+/*!
+ * \brief Constructor
+ */
+//================================================================================
+
+DriverCGNS_Read::DriverCGNS_Read()
+{
+  _fn = -1;
+}
+//================================================================================
+/*!
+ * \brief Close the cgns file at destruction
+ */
+//================================================================================
+
+DriverCGNS_Read::~DriverCGNS_Read()
+{
+  if ( _fn > 0 )
+    cg_close( _fn );
+}
+
+//================================================================================
+/*!
+ * \brief Opens myFile
+ */
+//================================================================================
+
+Driver_Mesh::Status DriverCGNS_Read::open()
+{
+  if ( _fn < 0 )
+  {
+    
+#ifdef CG_MODE_READ
+    int res = cg_open(myFile.c_str(), CG_MODE_READ, &_fn);
+#else
+    int res = cg_open(myFile.c_str(), MODE_READ, &_fn);
+#endif
+    if ( res != CG_OK)
+    {
+      addMessage( cg_get_error(), /*fatal = */true );
+    }
+  }
+  return _fn >= 0 ? DRS_OK : DRS_FAIL;
+}
+
+//================================================================================
+/*!
+ * \brief Reads nb of meshes in myFile
+ */
+//================================================================================
+
+int DriverCGNS_Read::GetNbMeshes(Status& theStatus)
+{
+  if (( theStatus = open()) != DRS_OK )
+    return 0;
+
+  int nbases = 0;
+  if(cg_nbases( _fn, &nbases) != CG_OK)
+    theStatus = addMessage( cg_get_error(), /*fatal = */true );
+
+  return nbases;
+}
diff --git a/src/DriverCGNS/DriverCGNS_Read.hxx b/src/DriverCGNS/DriverCGNS_Read.hxx
new file mode 100644 (file)
index 0000000..6460590
--- /dev/null
@@ -0,0 +1,59 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+// File      : DriverCGNS_Read.hxx
+// Created   : Thu Jun 30 10:25:09 2011
+// Author    : Edward AGAPOV (eap)
+
+#ifndef __DriverCGNS_Read_HXX__
+#define __DriverCGNS_Read_HXX__
+
+#include "SMESH_DriverCGNS.hxx"
+
+#include "Driver_SMESHDS_Mesh.h"
+
+#include <vector>
+#include <string>
+
+/*!
+ * \brief Driver reading a mesh from the CGNS file. The mesh to read is selected by 
+ *  an index (counted form 0) set via SetMeshId()
+ */
+class MESHDriverCGNS_EXPORT DriverCGNS_Read : public Driver_SMESHDS_Mesh
+{
+public:
+
+  DriverCGNS_Read();
+  ~DriverCGNS_Read();
+
+  virtual Status Perform();
+
+  int GetNbMeshes(Status& theStatus);
+
+
+private:
+
+  Status open();
+
+  int _fn; //!< file index
+};
+
+#endif
diff --git a/src/DriverCGNS/DriverCGNS_Write.cxx b/src/DriverCGNS/DriverCGNS_Write.cxx
new file mode 100644 (file)
index 0000000..517a56f
--- /dev/null
@@ -0,0 +1,585 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+// File      : DriverCGNS_Write.cxx
+// Created   : Fri Aug  5 17:43:54 2011
+// Author    : Edward AGAPOV (eap)
+
+#include "DriverCGNS_Write.hxx"
+
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_VolumeTool.hxx"
+#include "SMESHDS_GroupBase.hxx"
+#include "SMESHDS_Mesh.hxx"
+#include "SMESH_Comment.hxx"
+
+#include <limits>
+#include <cgnslib.h>
+
+#if CGNS_VERSION < 3100
+# define cgsize_t int
+#endif
+
+using namespace std;
+
+namespace
+{
+  //================================================================================
+  /*!
+   * \brief Return interlace and type of CGNS element for the given SMDSAbs_EntityType
+   */
+  //================================================================================
+
+  const int* getInterlaceAndType( const SMDSAbs_EntityType      smType,
+                                  CGNS_ENUMT( ElementType_t ) & cgType )
+  {
+    static vector< const int* >                 interlaces;
+    static vector< CGNS_ENUMT( ElementType_t )> cgTypes; 
+    if ( interlaces.empty() )
+    {
+      interlaces.resize( SMDSEntity_Last, 0 );
+      cgTypes.resize( SMDSEntity_Last, CGNS_ENUMV( ElementTypeNull ));
+      {
+        static int ids[] = {0};
+        interlaces[SMDSEntity_0D] = ids;
+        cgTypes   [SMDSEntity_0D] = CGNS_ENUMV( NODE );
+      }
+      {
+        static int ids[] = { 0, 1 };
+        interlaces[SMDSEntity_Edge] = ids;
+        cgTypes   [SMDSEntity_Edge] = CGNS_ENUMV( BAR_2 );
+      }
+      {
+        static int ids[] = { 0, 1, 2 };
+        interlaces[SMDSEntity_Quad_Edge] = ids;
+        cgTypes   [SMDSEntity_Quad_Edge] = CGNS_ENUMV( BAR_3 );
+      }
+      {
+        static int ids[] = { 0, 2, 1 };
+        interlaces[SMDSEntity_Triangle] = ids;
+        cgTypes   [SMDSEntity_Triangle] = CGNS_ENUMV( TRI_3 );
+      }
+      {
+        static int ids[] = { 0, 2, 1, 5, 4, 3 };
+        interlaces[SMDSEntity_Quad_Triangle] = ids;
+        cgTypes   [SMDSEntity_Quad_Triangle] = CGNS_ENUMV( TRI_6 );
+      }
+      {
+        static int ids[] = { 0, 3, 2, 1 };
+        interlaces[SMDSEntity_Quadrangle] = ids;
+        cgTypes   [SMDSEntity_Quadrangle] = CGNS_ENUMV( QUAD_4 );
+      }
+      {
+        static int ids[] = { 0,3,2,1,7,6,5,4 };
+        interlaces[SMDSEntity_Quad_Quadrangle] = ids;
+        cgTypes   [SMDSEntity_Quad_Quadrangle] = CGNS_ENUMV( QUAD_8 );
+      }
+      {
+        static int ids[] = { 0,3,2,1,7,6,5,4,8 };
+        interlaces[SMDSEntity_BiQuad_Quadrangle] = ids;
+        cgTypes   [SMDSEntity_BiQuad_Quadrangle] = CGNS_ENUMV( QUAD_9 );
+      }
+      {
+        static int ids[] = { 0, 2, 1, 3 };
+        interlaces[SMDSEntity_Tetra] = ids;
+        cgTypes   [SMDSEntity_Tetra] = CGNS_ENUMV( TETRA_4 );
+      }
+      {
+        static int ids[] = { 0,2,1,3,6,5,4,7,9,8 };
+        interlaces[SMDSEntity_Quad_Tetra] = ids;
+        cgTypes   [SMDSEntity_Quad_Tetra] = CGNS_ENUMV( TETRA_10 );
+      }
+      {
+        static int ids[] = { 0,3,2,1,4 };
+        interlaces[SMDSEntity_Pyramid] = ids;
+        cgTypes   [SMDSEntity_Pyramid] = CGNS_ENUMV( PYRA_5 );
+      }
+      {
+        static int ids[] = { 0,3,2,1,4,8,7,6,5,9,12,11,10 };
+        interlaces[SMDSEntity_Quad_Pyramid] = ids;
+        cgTypes   [SMDSEntity_Quad_Pyramid] = CGNS_ENUMV( PYRA_13 );
+      }
+      {
+        static int ids[] = { 0,2,1,3,5,4 };
+        interlaces[SMDSEntity_Penta] = ids;
+        cgTypes   [SMDSEntity_Penta] = CGNS_ENUMV( PENTA_6 );
+      }
+      {
+        static int ids[] = { 0,2,1,3,5,4,8,7,6,9,11,10,14,13,12 };
+        interlaces[SMDSEntity_Quad_Penta] = ids;
+        cgTypes   [SMDSEntity_Quad_Penta] = CGNS_ENUMV( PENTA_15 );
+      }
+      {
+        static int ids[] = { 0,3,2,1,4,7,6,5 };
+        interlaces[SMDSEntity_Hexa] = ids;
+        cgTypes   [SMDSEntity_Hexa] = CGNS_ENUMV( HEXA_8 );
+      }
+      {
+        static int ids[] = { 0,3,2,1,4,7,6,5,11,10,9,8,12,15,14,13,19,18,17,16 };
+        interlaces[SMDSEntity_Quad_Hexa] = ids;
+        cgTypes   [SMDSEntity_Quad_Hexa] = CGNS_ENUMV( HEXA_20 );
+      }
+      {
+        static int ids[] = { 0,3,2,1,4,7,6,5,11,10,9,8,12,15,14,13,19,18,17,16,
+                             20, 24,23,22,21, 25};
+        interlaces[SMDSEntity_TriQuad_Hexa] = ids;
+        cgTypes   [SMDSEntity_TriQuad_Hexa] = CGNS_ENUMV( HEXA_27 );
+      }
+      {
+        cgTypes[SMDSEntity_Polygon]         = CGNS_ENUMV( NGON_n );
+        cgTypes[SMDSEntity_Polyhedra]       = CGNS_ENUMV( NFACE_n );
+        cgTypes[SMDSEntity_Hexagonal_Prism] = CGNS_ENUMV( NFACE_n );
+      }
+    }
+    cgType  = cgTypes[ smType ];
+    return interlaces[ smType ];
+  }
+
+  //================================================================================
+  /*!
+   * \brief Cut off type of boundary condition from the group name
+   */
+  //================================================================================
+
+  CGNS_ENUMT( BCType_t ) getBCType( string& groupName )
+  {
+    CGNS_ENUMT( BCType_t ) bcType = CGNS_ENUMV( BCGeneral ); // default type
+
+    // boundary condition type starts from "BC"
+    size_t bcBeg = groupName.find("BC");
+    if ( bcBeg != string::npos )
+    {
+      for ( int t = 0; t < NofValidBCTypes; ++t )
+      {
+        CGNS_ENUMT( BCType_t ) type = CGNS_ENUMT( BCType_t)( t );
+        string typeName = cg_BCTypeName( type );
+        if ( typeName == &groupName[0] + bcBeg )
+        {
+          bcType = type;
+          while ( bcBeg > 0 && isspace( bcBeg-1 ))
+            --bcBeg;
+          if ( bcBeg == 0 )
+            groupName = "Group";
+          else
+            groupName = groupName.substr( 0, bcBeg-1 );
+        }
+      }
+    }
+    return bcType;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Sortable face of a polyhedron
+   */
+  struct TPolyhedFace
+  {
+    int _id; // id of NGON_n
+    vector< int > _nodes; // lowest node IDs used for sorting
+
+    TPolyhedFace( const SMDS_MeshNode** nodes, const int nbNodes, int ID):_id(ID)
+    {
+      set< int > ids;
+      for ( int i = 0; i < nbNodes; ++i )
+        ids.insert( nodes[i]->GetID() );
+
+      _nodes.resize( 3 ); // std::min( nbNodes, 4 )); hope 3 nodes is enough
+      set< int >::iterator idIt = ids.begin();
+      for ( size_t j = 0; j < _nodes.size(); ++j, ++idIt )
+        _nodes[j] = *idIt;
+    }
+    bool operator< (const TPolyhedFace& o ) const
+    {
+      return _nodes < o._nodes;
+    }
+  };
+  //================================================================================
+  /*!
+   * \brief Return CGNS id of an element
+   */
+  //================================================================================
+
+  cgsize_t cgnsID( const SMDS_MeshElement*                         elem,
+                   const map< const SMDS_MeshElement*, cgsize_t >& elem2cgID )
+  {
+    map< const SMDS_MeshElement*, cgsize_t >::const_iterator e2id = elem2cgID.find( elem );
+    return ( e2id == elem2cgID.end() ? elem->GetID() : e2id->second );
+  }
+
+} // namespace
+
+//================================================================================
+/*!
+ * \brief Write the mesh into the CGNS file
+ */
+//================================================================================
+
+Driver_Mesh::Status DriverCGNS_Write::Perform()
+{
+  myErrorMessages.clear();
+
+  if ( !myMesh || myMesh->GetMeshInfo().NbElements() < 1 )
+    return addMessage( !myMesh ? "NULL mesh" : "Empty mesh (no elements)", /*fatal = */true );
+
+  // open the file
+  if ( cg_open(myFile.c_str(), CG_MODE_MODIFY, &_fn) != CG_OK &&
+       cg_open(myFile.c_str(), CG_MODE_WRITE,  &_fn) != CG_OK )
+    return addMessage( cg_get_error(), /*fatal = */true );
+
+  // create a Base
+  // --------------
+
+  const int spaceDim = 3;
+  int meshDim = 1;
+  if ( myMesh->NbFaces() > 0 ) meshDim = 2;
+  if ( myMesh->NbVolumes() > 0 ) meshDim = 3;
+
+  if ( myMeshName.empty() )
+  {
+    int nbases = 0;
+    if ( cg_nbases( _fn, &nbases) == CG_OK)
+      myMeshName = ( SMESH_Comment("Base_") << nbases+1 );
+    else
+      myMeshName = "Base_0";
+  }
+  int iBase;
+  if ( cg_base_write( _fn, myMeshName.c_str(), meshDim, spaceDim, &iBase))
+    return addMessage( cg_get_error(), /*fatal = */true );
+
+  // create a Zone
+  // --------------
+
+  int nbCells = myMesh->NbEdges();
+  if ( meshDim == 3 )
+    nbCells = myMesh->NbVolumes();
+  else if ( meshDim == 2 )
+    nbCells = myMesh->NbFaces();
+
+  cgsize_t size[9] = { myMesh->NbNodes(), nbCells, /*NBoundVertex=*/0, 0,0,0,0,0,0 };
+  int iZone;
+  if ( cg_zone_write( _fn, iBase, "SMESH_Mesh", size,
+                      CGNS_ENUMV( Unstructured ), &iZone) != CG_OK )
+    return addMessage( cg_get_error(), /*fatal = */true );
+
+  // Map to store only elements whose an SMDS ID differs from a CGNS one
+  typedef map< const SMDS_MeshElement*, cgsize_t > TElem2cgIDMap;
+  vector< TElem2cgIDMap > elem2cgIDByEntity( SMDSEntity_Last );
+  TElem2cgIDMap::iterator elem2cgIDIter;
+
+  TElem2cgIDMap & n2cgID = elem2cgIDByEntity[ SMDSEntity_Node ];
+
+  // Write nodes
+  // ------------
+  {
+    vector< double > coords( myMesh->NbNodes() );
+    int iC;
+    // X
+    SMDS_NodeIteratorPtr nIt = myMesh->nodesIterator( /*idInceasingOrder=*/true );
+    for ( int i = 0; nIt->more(); ++i ) coords[i] = nIt->next()->X();
+    if ( cg_coord_write( _fn, iBase, iZone, CGNS_ENUMV(RealDouble),
+                          "CoordinateX", &coords[0], &iC) != CG_OK )
+      return addMessage( cg_get_error(), /*fatal = */true );
+    // Y
+    nIt = myMesh->nodesIterator( /*idInceasingOrder=*/true );
+    for ( int i = 0; nIt->more(); ++i ) coords[i] = nIt->next()->Y();
+    if ( cg_coord_write( _fn, iBase, iZone, CGNS_ENUMV(RealDouble),
+                          "CoordinateY", &coords[0], &iC) != CG_OK )
+      return addMessage( cg_get_error(), /*fatal = */true );
+    // Z
+    nIt = myMesh->nodesIterator( /*idInceasingOrder=*/true );
+    for ( int i = 0; nIt->more(); ++i ) coords[i] = nIt->next()->Z();
+    if ( cg_coord_write( _fn, iBase, iZone, CGNS_ENUMV(RealDouble),
+                          "CoordinateZ", &coords[0], &iC) != CG_OK )
+      return addMessage( cg_get_error(), /*fatal = */true );
+
+    // store CGNS ids of nodes
+    nIt = myMesh->nodesIterator( /*idInceasingOrder=*/true );
+    for ( int i = 0; nIt->more(); ++i )
+    {
+      const SMDS_MeshElement* n = nIt->next();
+      if ( n->GetID() != i+1 )
+        n2cgID.insert( n2cgID.end(), make_pair( n, i+1 ));
+    }
+  }
+  // Write elements
+  // ---------------
+  
+  cgsize_t cgID = 1, startID;
+
+  // write into a section all successive elements of one geom type
+  int iSec;
+  vector< cgsize_t > elemData;
+  SMDS_ElemIteratorPtr elemIt = myMesh->elementsIterator();
+  const SMDS_MeshElement* elem = elemIt->next();
+  while ( elem )
+  {
+    const SMDSAbs_EntityType elemType = elem->GetEntityType();
+    CGNS_ENUMT( ElementType_t ) cgType;
+    const int* interlace = getInterlaceAndType( elemType, cgType );
+
+    TElem2cgIDMap & elem2cgID = elem2cgIDByEntity[ elemType ];
+
+    elemData.clear();
+    startID = cgID;
+
+    if ( interlace ) // STANDARD elements
+      do
+      {
+        for ( int i = 0, nb = elem->NbNodes(); i < nb; ++i )
+          elemData.push_back( cgnsID( elem->GetNode( interlace[i] ), n2cgID ));
+        if ( elem->GetID() != cgID )
+          elem2cgID.insert( elem2cgID.end(), make_pair( elem, cgID ));
+        ++cgID;
+        elem = elemIt->more() ? elemIt->next() : 0;
+      }
+      while ( elem && elem->GetEntityType() == elemType );
+
+    else if ( elemType == SMDSEntity_Polygon ) // POLYGONS
+      do
+      {
+        elemData.push_back( elem->NbNodes() );
+        for ( int i = 0, nb = elem->NbNodes(); i < nb; ++i )
+          elemData.push_back( cgnsID( elem->GetNode(i), n2cgID ));
+        if ( elem->GetID() != cgID )
+          elem2cgID.insert( elem2cgID.end(), make_pair( elem, cgID ));
+        ++cgID;
+        elem = elemIt->more() ? elemIt->next() : 0;
+      }
+      while ( elem && elem->GetEntityType() == elemType );
+
+    else if ( elemType == SMDSEntity_Polyhedra ||
+              elemType == SMDSEntity_Hexagonal_Prism) // POLYHEDRA
+    {
+      // to save polyhedrons after all
+      const SMDS_MeshInfo& meshInfo = myMesh->GetMeshInfo();
+      if ( meshInfo.NbPolyhedrons() == meshInfo.NbElements() - cgID + 1 )
+        break; // only polyhedrons remain
+      while ( elem && elem->GetEntityType() == elemType )
+        elem = elemIt->more() ? elemIt->next() : 0;
+      continue;
+    }
+
+    SMESH_Comment sectionName( cg_ElementTypeName( cgType ));
+    sectionName << " " << startID << " - " << cgID-1;
+
+    if ( cg_section_write(_fn, iBase, iZone, sectionName.c_str(), cgType, startID,
+                          cgID-1, /*nbndry=*/0, &elemData[0], &iSec) != CG_OK )
+      return addMessage( cg_get_error(), /*fatal = */true );
+  }
+  // Write polyhedral volumes
+  // -------------------------
+
+  if ( myMesh->GetMeshInfo().NbElements() > cgID-1 ) // polyhedra or hexagonal prisms remain
+  {
+    // the polyhedron (NFACE_n) is described as a set of signed face IDs,
+    // so first we are to write all polygones (NGON_n) bounding polyhedrons
+
+    vector< cgsize_t > faceData;
+    set< TPolyhedFace > faces;
+    set< TPolyhedFace >::iterator faceInSet;
+    vector<const SMDS_MeshNode *> faceNodesVec;
+    int nbPolygones = 0, faceID;
+
+    SMDS_VolumeTool vol;
+
+    elemData.clear();
+
+    int nbPolyhTreated = 0;
+
+    TElem2cgIDMap * elem2cgID = 0;
+    TElem2cgIDMap & n2cgID    = elem2cgIDByEntity[ SMDSEntity_Node ];
+
+    SMDS_ElemIteratorPtr elemIt = myMesh->elementsIterator();
+    while ( elemIt->more() )
+    {
+      elem = elemIt->next();
+      SMDSAbs_EntityType type = elem->GetEntityType();
+      if ( type == SMDSEntity_Polyhedra ||
+           type == SMDSEntity_Hexagonal_Prism )
+      {
+        ++nbPolyhTreated;
+        vol.Set( elem );
+        vol.SetExternalNormal();
+        const int nbFaces = vol.NbFaces();
+        elemData.push_back( nbFaces );
+        for ( int iF = 0; iF < nbFaces; ++iF )
+        {
+          const int nbNodes = vol.NbFaceNodes( iF );
+          const SMDS_MeshNode** faceNodes = vol.GetFaceNodes( iF );
+          faceNodesVec.assign( faceNodes, faceNodes + nbNodes );
+          if (( elem = myMesh->FindElement( faceNodesVec, SMDSAbs_Face, /*noMedium=*/false)))
+          {
+            // a face of the polyhedron is present in the mesh
+            faceID = cgnsID( elem, elem2cgIDByEntity[ elem->GetEntityType() ]);
+          }
+          else if ( vol.IsFreeFace( iF ))
+          {
+            // the face is not shared by volumes
+            faceID = cgID++;
+            ++nbPolygones;
+            faceData.push_back( nbNodes );
+            for ( int i = 0; i < nbNodes; ++i )
+              faceData.push_back( cgnsID( faceNodes[i], n2cgID ));
+          }
+          else
+          {
+            TPolyhedFace face( faceNodes, nbNodes, cgID );
+            faceInSet = faces.insert( faces.end(), face );
+            if ( faceInSet->_id == cgID ) // the face encounters for the 1st time
+            {
+              faceID = cgID++;
+              ++nbPolygones;
+              faceData.push_back( nbNodes );
+              for ( int i = 0; i < nbNodes; ++i )
+                faceData.push_back( cgnsID( faceNodes[i], n2cgID ));
+            }
+            else
+            {
+              // the face encounters for the 2nd time; we hope it won't encounter once more,
+              // for that we can erase it from the set of faces
+              faceID = -faceInSet->_id;
+              faces.erase( faceInSet );
+            }
+          }
+          elemData.push_back( faceID );
+        }
+      }
+    }
+
+    if ( nbPolygones > 0 )
+    {
+      if ( cg_section_write(_fn, iBase, iZone, "Faces of Polyhedrons",
+                             CGNS_ENUMV( NGON_n ), cgID - nbPolygones, cgID-1,
+                             /*nbndry=*/0, &faceData[0], &iSec) != CG_OK )
+        return addMessage( cg_get_error(), /*fatal = */true );
+    }
+    
+    if ( cg_section_write(_fn, iBase, iZone, "Polyhedrons", 
+                             CGNS_ENUMV( NFACE_n ), cgID, cgID+nbPolyhTreated-1,
+                           /*nbndry=*/0, &elemData[0], &iSec) != CG_OK )
+      return addMessage( cg_get_error(), /*fatal = */true );
+
+    if ( !myMesh->GetGroups().empty() )
+    {
+      // store CGNS ids of polyhedrons
+      elem2cgID = &elem2cgIDByEntity[ SMDSEntity_Polyhedra ];
+      elemIt = myMesh->elementsIterator();
+      while ( elemIt->more() )
+      {
+        elem = elemIt->next();
+        if ( elem->GetEntityType() == SMDSEntity_Polyhedra )
+        {
+          if ( elem->GetID() != cgID )
+            elem2cgID->insert( elem2cgID->end(), make_pair( elem, cgID ));
+          ++cgID;
+        }
+      }
+    }
+  } // write polyhedral volumes
+
+
+  // Write groups as boundary conditions
+  // ------------------------------------
+
+  const set<SMESHDS_GroupBase*>& groups = myMesh->GetGroups();
+  set<SMESHDS_GroupBase*>::const_iterator grpIt = groups.begin();
+  set< string > groupNames; groupNames.insert(""); // to avoid duplicated and empty names
+  for ( ; grpIt != groups.end(); ++grpIt )
+  {
+    const SMESHDS_GroupBase* group = *grpIt;
+
+    // write BC location (default is Vertex)
+    CGNS_ENUMT( GridLocation_t ) location = CGNS_ENUMV( Vertex );
+    if ( group->GetType() != SMDSAbs_Node )
+    {
+      switch ( meshDim ) {
+      case 3:
+        switch ( group->GetType() ) {
+        case SMDSAbs_Volume: location = CGNS_ENUMV( FaceCenter ); break; // !!!
+        case SMDSAbs_Face:   location = CGNS_ENUMV( FaceCenter ); break; // OK
+        case SMDSAbs_Edge:   location = CGNS_ENUMV( EdgeCenter ); break; // OK
+        default:;
+        }
+        break;
+      case 2:
+        switch ( group->GetType() ) {
+        case SMDSAbs_Face: location = CGNS_ENUMV( FaceCenter ); break; // ???
+        case SMDSAbs_Edge: location = CGNS_ENUMV( EdgeCenter ); break; // OK
+        default:;
+        }
+        break;
+      case 1:
+        location = CGNS_ENUMV( EdgeCenter ); break; // ???
+        break;
+      }
+    }
+
+    // try to extract type of boundary condition from the group name
+    string name = group->GetStoreName();
+    CGNS_ENUMT( BCType_t ) bcType = getBCType( name );
+    while ( !groupNames.insert( name ).second )
+      name = (SMESH_Comment( "Group_") << groupNames.size());
+
+    // write IDs of elements
+    vector< cgsize_t > pnts;
+    pnts.reserve( group->Extent() );
+    SMDS_ElemIteratorPtr elemIt = group->GetElements();
+    while ( elemIt->more() )
+    {
+      const SMDS_MeshElement* elem = elemIt->next();
+      pnts.push_back( cgnsID( elem, elem2cgIDByEntity[ elem->GetEntityType() ]));
+    }
+    int iBC;
+    if ( cg_boco_write( _fn, iBase, iZone, name.c_str(), bcType,
+                        CGNS_ENUMV( PointList ), pnts.size(), &pnts[0], &iBC) != CG_OK )
+      return addMessage( cg_get_error(), /*fatal = */true);
+
+    // write BC location
+    if ( location != CGNS_ENUMV( Vertex ))
+    {
+      if ( cg_boco_gridlocation_write( _fn, iBase, iZone, iBC, location) != CG_OK )
+        return addMessage( cg_get_error(), /*fatal = */false);
+    }
+  }
+  return DRS_OK;
+}
+
+//================================================================================
+/*!
+ * \brief Constructor
+ */
+//================================================================================
+
+DriverCGNS_Write::DriverCGNS_Write(): _fn(0)
+{
+}
+
+//================================================================================
+/*!
+ * \brief Close the cgns file at destruction
+ */
+//================================================================================
+
+DriverCGNS_Write::~DriverCGNS_Write()
+{
+  if ( _fn > 0 )
+    cg_close( _fn );
+}
diff --git a/src/DriverCGNS/DriverCGNS_Write.hxx b/src/DriverCGNS/DriverCGNS_Write.hxx
new file mode 100644 (file)
index 0000000..65496ab
--- /dev/null
@@ -0,0 +1,53 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+// File      : DriverCGNS_Write.hxx
+// Created   : Thu Jun 30 10:25:09 2011
+// Author    : Edward AGAPOV (eap)
+
+#ifndef __DriverCGNS_Write_HXX__
+#define __DriverCGNS_Write_HXX__
+
+#include "SMESH_DriverCGNS.hxx"
+
+#include "Driver_SMESHDS_Mesh.h"
+
+#include <vector>
+#include <string>
+
+/*!
+ * \brief Driver writinging a mesh into the CGNS file.
+ */
+class MESHDriverCGNS_EXPORT DriverCGNS_Write : public Driver_SMESHDS_Mesh
+{
+public:
+
+  DriverCGNS_Write();
+  ~DriverCGNS_Write();
+
+  virtual Status Perform();
+
+private:
+
+  int _fn; //!< file index
+};
+
+#endif
diff --git a/src/DriverCGNS/Makefile.am b/src/DriverCGNS/Makefile.am
new file mode 100644 (file)
index 0000000..37f1f5d
--- /dev/null
@@ -0,0 +1,50 @@
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# 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.com
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+# header files 
+salomeinclude_HEADERS = \
+       DriverCGNS_Read.hxx \
+       DriverCGNS_Write.hxx \
+       SMESH_DriverCGNS.hxx
+
+# Libraries targets
+lib_LTLIBRARIES = libMeshDriverCGNS.la
+dist_libMeshDriverCGNS_la_SOURCES = \
+       DriverCGNS_Read.cxx \
+       DriverCGNS_Write.cxx
+
+# additionnal information to compil and link file
+libMeshDriverCGNS_la_CPPFLAGS = \
+       $(KERNEL_CXXFLAGS) \
+       $(CAS_CPPFLAGS) \
+       $(CGNS_INCLUDES) \
+        $(VTK_INCLUDES) \
+       $(BOOST_CPPFLAGS) \
+       -I$(srcdir)/../Driver \
+       -I$(srcdir)/../SMESHUtils \
+       -I$(srcdir)/../SMDS \
+       -I$(srcdir)/../SMESHDS
+
+libMeshDriverCGNS_la_LDFLAGS  = \
+       $(BOOST_LIBS) \
+       $(CGNS_LIBS) \
+       ../Driver/libMeshDriver.la \
+       ../SMESHUtils/libSMESHUtils.la
diff --git a/src/DriverCGNS/SMESH_DriverCGNS.hxx b/src/DriverCGNS/SMESH_DriverCGNS.hxx
new file mode 100755 (executable)
index 0000000..365007b
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+//  File   : SMESH_DriverCGNS.hxx
+//  Author : Alexander A. BORODIN
+//  Module : SMESH
+//
+#ifndef _SMESH_DriverCGNS_HXX_
+#define _SMESH_DriverCGNS_HXX_
+
+#ifdef WNT
+ #if defined MESHDriverCGNS_EXPORTS || defined MeshDriverCGNS_EXPORTS
+  #define MESHDriverCGNS_EXPORT __declspec( dllexport )
+ #else
+  #define MESHDriverCGNS_EXPORT __declspec( dllimport )
+ #endif
+#else
+ #define MESHDriverCGNS_EXPORT
+#endif
+
+#endif
index 799dff4620b6bda24ab64a98b8605cae01395855..4810067ce9916d13fab85f755c17f90dd34b88f2 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #include "DriverDAT_R_SMDS_Mesh.h"
 #include "DriverDAT_W_SMDS_Mesh.h"
 
index 6c0abb7303d5a80aa483e4b987456412cfe8db41..d44951e8689d9f90d59042fea28eef73a00485fe 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #include <stdio.h>
 
 #include "DriverDAT_R_SMDS_Mesh.h"
 
 #include "utilities.h"
 
+#include <Basics_Utils.hxx>
+
 using namespace std;
 
 Driver_Mesh::Status DriverDAT_R_SMDS_Mesh::Perform()
 {
+  Kernel_Utils::Localizer loc;
   Status aResult = DRS_OK;
 
   int i, j;
@@ -40,12 +44,9 @@ Driver_Mesh::Status DriverDAT_R_SMDS_Mesh::Perform()
   
   int intNumMaille, Degre;
   int ValElement;
-  int ValDegre;
   int NoeudsMaille[20];
   int NoeudMaille;
   
-  bool ok;
-  
   MESSAGE("in DriverDAT_R_SMDS_Mesh::Read()");
   /****************************************************************************
    *                      OUVERTURE DU FICHIER EN LECTURE                      *
@@ -68,7 +69,7 @@ Driver_Mesh::Status DriverDAT_R_SMDS_Mesh::Perform()
   
   for (i = 0; i < nbNodes; i++){
     fscanf(aFileId, "%d %e %e %e\n", &intNumPoint, &coordX, &coordY, &coordZ);
-    ok = myMesh->AddNodeWithID(coordX, coordY, coordZ, intNumPoint);
+    myMesh->AddNodeWithID(coordX, coordY, coordZ, intNumPoint);
   }
   
   fprintf(stdout, "%d noeuds\n", myMesh->NbNodes());
@@ -96,72 +97,66 @@ Driver_Mesh::Status DriverDAT_R_SMDS_Mesh::Perform()
     switch (ValElement) {
     case 102:
     case 103:
-      ValDegre = 3;
       nbNoeuds = 2;
-      ok = myMesh->AddEdgeWithID(NoeudsMaille[0], NoeudsMaille[1], 
-                                intNumMaille);
+      myMesh->AddEdgeWithID(NoeudsMaille[0], NoeudsMaille[1], 
+                                 intNumMaille);
       break;
     case 204:
     case 208:
-      ValDegre = 9;
       nbNoeuds = 4;
-      ok = myMesh->AddFaceWithID(NoeudsMaille[0], NoeudsMaille[1],
-                                NoeudsMaille[2], NoeudsMaille[3], 
-                                intNumMaille);
+      myMesh->AddFaceWithID(NoeudsMaille[0], NoeudsMaille[1],
+                                 NoeudsMaille[2], NoeudsMaille[3], 
+                                 intNumMaille);
       break;
     case 203:
     case 206:
-      ValDegre = 5;
       nbNoeuds = 3;
-      ok = myMesh->AddFaceWithID(NoeudsMaille[0], NoeudsMaille[1],
-                                NoeudsMaille[2], intNumMaille);
+      myMesh->AddFaceWithID(NoeudsMaille[0], NoeudsMaille[1],
+                                 NoeudsMaille[2], intNumMaille);
       break;
     case 308:
     case 320:
-      ValDegre = 12;
       nbNoeuds = 8;
       if (ValElement == 320){
-       //A voir, correspondance VTK
-       NoeudsMaille[4] = NoeudsMaille[8];
-       NoeudsMaille[5] = NoeudsMaille[9];
-       NoeudsMaille[6] = NoeudsMaille[10];
-       NoeudsMaille[7] = NoeudsMaille[11];
+        //A voir, correspondance VTK
+        NoeudsMaille[4] = NoeudsMaille[8];
+        NoeudsMaille[5] = NoeudsMaille[9];
+        NoeudsMaille[6] = NoeudsMaille[10];
+        NoeudsMaille[7] = NoeudsMaille[11];
       }
-      ok = myMesh->AddVolumeWithID(NoeudsMaille[0], NoeudsMaille[1],
-                                  NoeudsMaille[2], NoeudsMaille[3], 
-                                  NoeudsMaille[4], NoeudsMaille[5], 
-                                  NoeudsMaille[6], NoeudsMaille[7],
-                                  intNumMaille);
+      myMesh->AddVolumeWithID(NoeudsMaille[0], NoeudsMaille[1],
+                                   NoeudsMaille[2], NoeudsMaille[3], 
+                                   NoeudsMaille[4], NoeudsMaille[5], 
+                                   NoeudsMaille[6], NoeudsMaille[7],
+                                   intNumMaille);
       break;
     case 304:
     case 310:
-      ValDegre = 10;
       nbNoeuds = 4;
       if (ValElement == 310)
-       NoeudsMaille[3] = NoeudsMaille[6];
-      ok = myMesh->AddVolumeWithID(NoeudsMaille[0], NoeudsMaille[1],
-                                  NoeudsMaille[2], NoeudsMaille[3], 
-                                  intNumMaille);
+        NoeudsMaille[3] = NoeudsMaille[6];
+      myMesh->AddVolumeWithID(NoeudsMaille[0], NoeudsMaille[1],
+                                   NoeudsMaille[2], NoeudsMaille[3], 
+                                   intNumMaille);
       break;
     case 306:
     case 315:
-      ValDegre = 12;
       nbNoeuds = 8;
       if (ValElement == 315) {
-       NoeudsMaille[3] = NoeudsMaille[6];
-       NoeudsMaille[4] = NoeudsMaille[7];
-       NoeudsMaille[5] = NoeudsMaille[8];
+        NoeudsMaille[3] = NoeudsMaille[6];
+        NoeudsMaille[4] = NoeudsMaille[7];
+        NoeudsMaille[5] = NoeudsMaille[8];
       }
       NoeudsMaille[7] = NoeudsMaille[5];
       NoeudsMaille[6] = NoeudsMaille[5];
       NoeudsMaille[5] = NoeudsMaille[4];
       NoeudsMaille[4] = NoeudsMaille[3];
       NoeudsMaille[3] = NoeudsMaille[2];
-      ok = myMesh->AddVolumeWithID(NoeudsMaille[0], NoeudsMaille[1],
-                                  NoeudsMaille[2], NoeudsMaille[3], 
-                                  NoeudsMaille[4], NoeudsMaille[5], 
-                                  intNumMaille);
-                               break;
+      myMesh->AddVolumeWithID(NoeudsMaille[0], NoeudsMaille[1],
+                                   NoeudsMaille[2], NoeudsMaille[3], 
+                                   NoeudsMaille[4], NoeudsMaille[5], 
+                                   intNumMaille);
+                                break;
     }
   }
   /****************************************************************************
index 1918963fb838f7fcfdabd9f97cb2667f18c30aac..73169a273c5ed71e20704214dc3b472a74b675c4 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #ifndef _INCLUDE_DRIVERDAT_R_SMDS_MESH
 #define _INCLUDE_DRIVERDAT_R_SMDS_MESH
 
diff --git a/src/DriverDAT/DriverDAT_R_SMESHDS_Document.cxx b/src/DriverDAT/DriverDAT_R_SMESHDS_Document.cxx
deleted file mode 100644 (file)
index 6418e4c..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-#include "DriverDAT_R_SMESHDS_Document.h"
diff --git a/src/DriverDAT/DriverDAT_R_SMESHDS_Document.h b/src/DriverDAT/DriverDAT_R_SMESHDS_Document.h
deleted file mode 100644 (file)
index 7a6bd7e..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-#ifndef _INCLUDE_DRIVERDAT_R_SMESHDS_DOCUMENT
-#define _INCLUDE_DRIVERDAT_R_SMESHDS_DOCUMENT
-
-#include "SMESH_DriverDAT.hxx"
-
-#include "Driver_Document.h"
-
-class MESHDRIVERDAT_EXPORT DriverDAT_R_SMESHDS_Document : public Driver_Document 
-{};
-
-#endif
diff --git a/src/DriverDAT/DriverDAT_R_SMESHDS_Mesh.cxx b/src/DriverDAT/DriverDAT_R_SMESHDS_Mesh.cxx
deleted file mode 100644 (file)
index 5a7f445..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-#include "DriverDAT_R_SMESHDS_Mesh.h"
diff --git a/src/DriverDAT/DriverDAT_R_SMESHDS_Mesh.h b/src/DriverDAT/DriverDAT_R_SMESHDS_Mesh.h
deleted file mode 100644 (file)
index 5229e7f..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-#ifndef _INCLUDE_DRIVERDAT_R_SMESHDS_MESH
-#define _INCLUDE_DRIVERDAT_R_SMESHDS_MESH
-
-#include "SMESH_DriverDAT.hxx"
-
-#include "Driver_SMESHDS_Mesh.h"
-
-class MESHDRIVERDAT_EXPORT DriverDAT_R_SMESHDS_Mesh: public Driver_SMESHDS_Mesh
-{};
-
-#endif
index 91b06d6b1d895edc3bdd3adc1aec9214b6d3d2da..7bdee747b818c6a6d61d4dd4df44f09d1d289ee7 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #include <stdio.h>
 
 #include "DriverDAT_W_SMDS_Mesh.h"
 
 #include "utilities.h"
 
+#include <Basics_Utils.hxx>
+
 using namespace std;
 
 Driver_Mesh::Status DriverDAT_W_SMDS_Mesh::Perform()
 {
+  Kernel_Utils::Localizer loc;
   Status aResult = DRS_OK;
 
   int nbNodes, nbCells;
@@ -74,11 +78,11 @@ Driver_Mesh::Status DriverDAT_W_SMDS_Mesh::Perform()
   fprintf(stdout, "(************************)\n");
   
   SMDS_NodeIteratorPtr itNodes=myMesh->nodesIterator();
-  while(itNodes->more()){              
+  while(itNodes->more()){               
     const SMDS_MeshNode * node = itNodes->next();
     fprintf(aFileId, "%d %e %e %e\n", node->GetID(), node->X(), node->Y(), node->Z());
   }
-       
+        
   /****************************************************************************
    *                       ECRITURE DES ELEMENTS                                *
    ****************************************************************************/
index 9afbefc8fd871c0697371d22ceb7d0db3f4a46b3..66b726b1367f43277a81b312331e154e5b90c851 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH DriverDAT : driver to read and write 'dat' files
 //  File   : DriverDAT_W_SMDS_Mesh.h
 //  Module : SMESH
diff --git a/src/DriverDAT/DriverDAT_W_SMESHDS_Document.cxx b/src/DriverDAT/DriverDAT_W_SMESHDS_Document.cxx
deleted file mode 100644 (file)
index c6555a8..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-#include "DriverDAT_W_SMESHDS_Document.h"
diff --git a/src/DriverDAT/DriverDAT_W_SMESHDS_Document.h b/src/DriverDAT/DriverDAT_W_SMESHDS_Document.h
deleted file mode 100644 (file)
index 09bb0c8..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-#ifndef _INCLUDE_DRIVERDAT_W_SMESHDS_DOCUMENT
-#define _INCLUDE_DRIVERDAT_W_SMESHDS_DOCUMENT
-
-#include "SMESH_DriverDAT.hxx"
-
-#include "Driver_Document.h"
-
-class MESHDRIVERDAT_EXPORT DriverDAT_W_SMESHDS_Document: public Driver_Document 
-{};
-
-#endif
diff --git a/src/DriverDAT/DriverDAT_W_SMESHDS_Mesh.cxx b/src/DriverDAT/DriverDAT_W_SMESHDS_Mesh.cxx
deleted file mode 100644 (file)
index bbef027..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-#include "DriverDAT_W_SMESHDS_Mesh.h"
diff --git a/src/DriverDAT/DriverDAT_W_SMESHDS_Mesh.h b/src/DriverDAT/DriverDAT_W_SMESHDS_Mesh.h
deleted file mode 100644 (file)
index dffea1b..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-//  SMESH DriverDAT : driver to read and write 'dat' files
-//  File   : DriverDAT_W_SMESHDS_Mesh.h
-//  Module : SMESH
-//
-#ifndef _INCLUDE_DRIVERDAT_W_SMESHDS_MESH
-#define _INCLUDE_DRIVERDAT_W_SMESHDS_MESH
-
-#include "SMESH_DriverDAT.hxx"
-
-#include "Driver_SMESHDS_Mesh.h"
-
-class MESHDRIVERDAT_EXPORT DriverDAT_W_SMESHDS_Mesh: public Driver_SMESHDS_Mesh
-{};
-
-#endif
index 2a9973796d68a1966fe53aa48c9069f94f4aeda7..338bc1d17e5bcdc0c75cad22901a109fc9f3071b 100644 (file)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  SMESH DriverDAT : driver to read and write 'dat' files
 #  File   : Makefile.in
 #  Author : Marc Tajchman (CEA)
@@ -31,11 +29,7 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am
 # header files 
 salomeinclude_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 \
        SMESH_DriverDAT.hxx
 
 # Libraries targets
@@ -43,11 +37,7 @@ lib_LTLIBRARIES = libMeshDriverDAT.la
 
 dist_libMeshDriverDAT_la_SOURCES = \
        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
+       DriverDAT_W_SMDS_Mesh.cxx
 
 # Executables targets
 bin_PROGRAMS = DAT_Test
@@ -58,6 +48,7 @@ dist_DAT_Test_SOURCES = \
 libMeshDriverDAT_la_CPPFLAGS = \
        $(KERNEL_CXXFLAGS) \
        $(CAS_CPPFLAGS) \
+        $(VTK_INCLUDES) \
        $(BOOST_CPPFLAGS) \
        -I$(srcdir)/../Driver \
        -I$(srcdir)/../SMDS \
@@ -65,6 +56,7 @@ libMeshDriverDAT_la_CPPFLAGS = \
 
 libMeshDriverDAT_la_LDFLAGS  = \
        ../Driver/libMeshDriver.la \
+       $(KERNEL_LDFLAGS) -lSALOMEBasics \
        $(CAS_KERNEL)
 
 DAT_Test_CPPFLAGS = \
index 9020c6fc1b7e8db3bd78c5ad7e418291ce67f8a6..de4d07ce2c799ea04623be3be52db70379d11ccc 100755 (executable)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  File   : SMESH_DriverDAT.hxx
 //  Author : Alexander A. BORODIN
 //  Module : SMESH
@@ -27,7 +28,7 @@
 #define _SMESH_DriverDAT_HXX_
 
 #ifdef WNT
- #if defined MESHDRIVERDAT_EXPORTS
+ #if defined MESHDRIVERDAT_EXPORTS || defined MeshDriverDAT_EXPORTS
   #define MESHDRIVERDAT_EXPORT __declspec( dllexport )
  #else
   #define MESHDRIVERDAT_EXPORT __declspec( dllimport )
index 84fbf8937ec2daec1931360e1309ad1e11b0188b..c284b0b3ca8f3e7315eaa5eb97360d222c57931c 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH DriverMED : tool to split groups on families
 //  File   : DriverMED_Family.cxx
 //  Author : Julia DOROVSKIKH
@@ -28,7 +29,7 @@
 #include "DriverMED_Family.h"
 #include "MED_Factory.hxx"
 
-#include <sstream>     
+#include <sstream>      
 
 using namespace std;
 
@@ -83,7 +84,7 @@ void
 DriverMED_Family
 ::SetType(const SMDSAbs_ElementType theType) 
 { 
-  myType = theType; 
+  myTypes.insert( myType = theType );
 }
 
 SMDSAbs_ElementType
@@ -93,6 +94,13 @@ DriverMED_Family
   return myType; 
 }
 
+const std::set< SMDSAbs_ElementType >&
+DriverMED_Family
+::GetTypes() const
+{
+  return myTypes;
+}
+
 bool
 DriverMED_Family
 ::MemberOf(std::string theGroupName) const
@@ -139,21 +147,25 @@ DriverMED_Family
 DriverMED_FamilyPtrList 
 DriverMED_Family
 ::MakeFamilies(const SMESHDS_SubMeshPtrMap& theSubMeshes,
-              const SMESHDS_GroupBasePtrList& theGroups,
-              const bool doGroupOfNodes,
-              const bool doGroupOfEdges,
-              const bool doGroupOfFaces,
-              const bool doGroupOfVolumes)
+               const SMESHDS_GroupBasePtrList& theGroups,
+               const bool doGroupOfNodes,
+               const bool doGroupOfEdges,
+               const bool doGroupOfFaces,
+               const bool doGroupOfVolumes,
+               const bool doGroupOf0DElems,
+               const bool doGroupOfBalls)
 {
   DriverMED_FamilyPtrList aFamilies;
 
-  string anAllNodesGroupName = "Group_Of_All_Nodes";
-  string anAllEdgesGroupName = "Group_Of_All_Edges";
-  string anAllFacesGroupName = "Group_Of_All_Faces";
+  string anAllNodesGroupName   = "Group_Of_All_Nodes";
+  string anAllEdgesGroupName   = "Group_Of_All_Edges";
+  string anAllFacesGroupName   = "Group_Of_All_Faces";
   string anAllVolumesGroupName = "Group_Of_All_Volumes";
+  string anAll0DElemsGroupName = "Group_Of_All_0DElems";
+  string anAllBallsGroupName   = "Group_Of_All_Balls";
 
-  // Reserve four ids for families of free elements
-  // (1 - nodes, -1 - edges, -2 - faces, -3 - volumes).
+  // Reserve 6 ids for families of free elements
+  // (1 - nodes, -1 - edges, -2 - faces, -3 - volumes, -4 - 0D, -5 - balls).
   // 'Free' means here not belonging to any group.
   int aNodeFamId = FIRST_NODE_FAMILY;
   int aElemFamId = FIRST_ELEM_FAMILY;
@@ -189,7 +201,7 @@ DriverMED_Family
             aFamilies.erase(aCurrIter);
           }
           if (aFam2->IsEmpty()) 
-           break;
+            break;
         }
       }
       // The rest elements of family
@@ -218,7 +230,7 @@ DriverMED_Family
         aFam1->Split(aFam2, aCommon);
         if (!aCommon->IsEmpty())
         {
-         aCommon->SetGroupAttributVal(0);
+          aCommon->SetGroupAttributVal(0);
           aFamilies.push_back(aCommon);
         }
         if (aFam1->IsEmpty())
@@ -226,7 +238,7 @@ DriverMED_Family
           aFamilies.erase(aCurrIter);
         }
         if (aFam2->IsEmpty()) 
-         break;
+          break;
       }
     }
     // The rest elements of group
@@ -255,6 +267,12 @@ DriverMED_Family
       else if (aFam->myType == SMDSAbs_Volume) {
         if (doGroupOfVolumes) aFam->myGroupNames.insert(anAllVolumesGroupName);
       }
+      else if (aFam->myType == SMDSAbs_0DElement) {
+        if (doGroupOfVolumes) aFam->myGroupNames.insert(anAll0DElemsGroupName);
+      }
+      else if (aFam->myType == SMDSAbs_Ball) {
+        if (doGroupOfVolumes) aFam->myGroupNames.insert(anAllBallsGroupName);
+      }
     }
   }
 
@@ -295,6 +313,24 @@ DriverMED_Family
     aFamilies.push_back(aFreeVolumesFam);
   }
 
+  if (doGroupOf0DElems)
+  {
+    DriverMED_FamilyPtr aFree0DFam (new DriverMED_Family);
+    aFree0DFam->SetId(REST_0DELEM_FAMILY);
+    aFree0DFam->myType = SMDSAbs_0DElement;
+    aFree0DFam->myGroupNames.insert(anAll0DElemsGroupName);
+    aFamilies.push_back(aFree0DFam);
+  }
+
+  if (doGroupOfBalls)
+  {
+    DriverMED_FamilyPtr aFreeBallsFam (new DriverMED_Family);
+    aFreeBallsFam->SetId(REST_BALL_FAMILY);
+    aFreeBallsFam->myType = SMDSAbs_Ball;
+    aFreeBallsFam->myGroupNames.insert(anAllBallsGroupName);
+    aFamilies.push_back(aFreeBallsFam);
+  }
+
   DriverMED_FamilyPtr aNullFam (new DriverMED_Family);
   aNullFam->SetId(0);
   aNullFam->myType = SMDSAbs_All;
@@ -310,7 +346,7 @@ DriverMED_Family
 //=============================================================================
 MED::PFamilyInfo 
 DriverMED_Family::GetFamilyInfo(const MED::PWrapper& theWrapper, 
-                               const MED::PMeshInfo& theMeshInfo) const
+                                const MED::PMeshInfo& theMeshInfo) const
 {
   ostringstream aStr;
   aStr << "FAM_" << myId;
@@ -332,20 +368,20 @@ DriverMED_Family::GetFamilyInfo(const MED::PWrapper& theWrapper,
   MED::PFamilyInfo anInfo;
   if(myId == 0 || myGroupAttributVal == 0){
     anInfo = theWrapper->CrFamilyInfo(theMeshInfo,
-                                     aValue,
-                                     myId,
-                                     myGroupNames);
+                                      aValue,
+                                      myId,
+                                      myGroupNames);
   }else{
     MED::TStringVector anAttrDescs (1, "");  // 1 attribute with empty description,
     MED::TIntVector anAttrIds (1, myId);        // Id=0,
     MED::TIntVector anAttrVals (1, myGroupAttributVal);
     anInfo = theWrapper->CrFamilyInfo(theMeshInfo,
-                                     aValue,
-                                     myId,
-                                     myGroupNames,
-                                     anAttrDescs,
-                                     anAttrIds,
-                                     anAttrVals);
+                                      aValue,
+                                      myId,
+                                      myGroupNames,
+                                      anAttrDescs,
+                                      anAttrIds,
+                                      anAttrVals);
   }
 
 //  cout << endl;
@@ -391,9 +427,9 @@ void DriverMED_Family::Init (SMESHDS_GroupBase* theGroup)
   myGroupNames.insert(string(theGroup->GetStoreName()));
 
   Quantity_Color aColor = theGroup->GetColor();
-  double aRed = aColor.Red();
+  double aRed   = aColor.Red();
   double aGreen = aColor.Green();
-  double aBlue = aColor.Blue();
+  double aBlue  = aColor.Blue();
   int aR = int( aRed*255   );
   int aG = int( aGreen*255 );
   int aB = int( aBlue*255  );
@@ -413,13 +449,15 @@ void DriverMED_Family::Init (SMESHDS_GroupBase* theGroup)
 DriverMED_FamilyPtrList 
 DriverMED_Family
 ::SplitByType (SMESHDS_SubMesh* theSubMesh,
-              const int        theId)
+               const int        theId)
 {
   DriverMED_FamilyPtrList 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);
+  // DriverMED_FamilyPtr a0DElemsFamily (new DriverMED_Family);
+  // DriverMED_FamilyPtr aBallsFamily   (new DriverMED_Family);
 
   char submeshGrpName[ 30 ];
   sprintf( submeshGrpName, "SubMesh %d", theId );
@@ -486,13 +524,14 @@ void DriverMED_Family::Split (DriverMED_FamilyPtr by,
                               DriverMED_FamilyPtr common)
 {
   // Elements
-  ElementsSet::iterator anIter = by->myElements.begin();
+  ElementsSet::iterator anIter = by->myElements.begin(), elemInMe;
   while ( anIter != by->myElements.end())
   {
-    if (myElements.find(*anIter) != myElements.end())
+    elemInMe = myElements.find(*anIter);
+    if (elemInMe != myElements.end())
     {
       common->myElements.insert(*anIter);
-      myElements.erase(*anIter);
+      myElements.erase(elemInMe);
       by->myElements.erase(anIter++);
     }
     else
@@ -503,11 +542,7 @@ void DriverMED_Family::Split (DriverMED_FamilyPtr by,
   {
     // Groups list
     common->myGroupNames = myGroupNames;
-    MED::TStringSet::iterator aGrNamesIter = by->myGroupNames.begin();
-    for (; aGrNamesIter != by->myGroupNames.end(); aGrNamesIter++)
-    {
-      common->myGroupNames.insert(*aGrNamesIter);
-    }
+    common->myGroupNames.insert( by->myGroupNames.begin(), by->myGroupNames.end() );
 
     // Type
     common->myType = myType;
index 6ec769bbad86aa3de32e0a958a9ebceb38579bd1..1e159539cc9bc7dc77a0698c0697386269805976 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH DriverMED : tool to split groups on families
 //  File   : DriverMED_Family.hxx
 //  Author : Julia DOROVSKIKH
 #include <set>
 
 #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
+
+#define REST_EDGES_FAMILY   -1
+#define REST_FACES_FAMILY   -2
+#define REST_VOLUMES_FAMILY -3
+#define REST_0DELEM_FAMILY  -4
+#define REST_BALL_FAMILY    -5
+#define FIRST_ELEM_FAMILY   -6
 
 class DriverMED_Family;
 typedef boost::shared_ptr<DriverMED_Family> DriverMED_FamilyPtr;
-typedef std::list<DriverMED_FamilyPtr> DriverMED_FamilyPtrList;
-typedef std::map<int,SMESHDS_SubMesh*> SMESHDS_SubMeshPtrMap;
-typedef std::list<SMESHDS_GroupBase*> SMESHDS_GroupBasePtrList;
-typedef std::set<const SMDS_MeshElement*> ElementsSet;
+typedef std::list<DriverMED_FamilyPtr     > DriverMED_FamilyPtrList;
+typedef std::map<int,SMESHDS_SubMesh*     > SMESHDS_SubMeshPtrMap;
+typedef std::list<SMESHDS_GroupBase*      > SMESHDS_GroupBasePtrList;
+typedef std::set<const SMDS_MeshElement*  > ElementsSet;
 
 class MESHDRIVERMED_EXPORT DriverMED_Family
 {
@@ -68,16 +72,18 @@ class MESHDRIVERMED_EXPORT DriverMED_Family
   static 
   DriverMED_FamilyPtrList
   MakeFamilies (const SMESHDS_SubMeshPtrMap& theSubMeshes,
-               const SMESHDS_GroupBasePtrList& theGroups,
-               const bool doGroupOfNodes,
-               const bool doGroupOfEdges,
-               const bool doGroupOfFaces,
-               const bool doGroupOfVolumes);
+                const SMESHDS_GroupBasePtrList& theGroups,
+                const bool doGroupOfNodes,
+                const bool doGroupOfEdges,
+                const bool doGroupOfFaces,
+                const bool doGroupOfVolumes,
+                const bool doGroupOf0DElems,
+                const bool doGroupOfBalls);
 
   //! Create TFamilyInfo for this family
   MED::PFamilyInfo 
   GetFamilyInfo (const MED::PWrapper& theWrapper, 
-                const MED::PMeshInfo& theMeshInfo) const;
+                 const MED::PMeshInfo& theMeshInfo) const;
 
   //! Returns elements of this family
   const ElementsSet& GetElements () const;
@@ -99,6 +105,7 @@ class MESHDRIVERMED_EXPORT DriverMED_Family
 
   void SetType(const SMDSAbs_ElementType theType);
   SMDSAbs_ElementType GetType();
+  const std::set< SMDSAbs_ElementType >& GetTypes() const;
 
   bool MemberOf(std::string theGroupName) const;
 
@@ -113,7 +120,7 @@ class MESHDRIVERMED_EXPORT DriverMED_Family
   static
   DriverMED_FamilyPtrList 
   SplitByType(SMESHDS_SubMesh* theSubMesh,
-             const int        theId);
+              const int        theId);
 
 
   /*! Remove from <Elements> elements, common with <by>,
@@ -121,7 +128,7 @@ class MESHDRIVERMED_EXPORT DriverMED_Family
     Create family <common> from common elements, with combined groups list.
   */
   void Split (DriverMED_FamilyPtr by,
-             DriverMED_FamilyPtr common);
+              DriverMED_FamilyPtr common);
 
   //! Check, if this family has empty list of elements
   bool IsEmpty () const;
@@ -133,6 +140,7 @@ class MESHDRIVERMED_EXPORT DriverMED_Family
   ElementsSet                   myElements;
   MED::TStringSet               myGroupNames;
   int                           myGroupAttributVal;
+  std::set<SMDSAbs_ElementType> myTypes; // Issue 0020576
 };
 
 #endif
diff --git a/src/DriverMED/DriverMED_R_SMDS_Mesh.cxx b/src/DriverMED/DriverMED_R_SMDS_Mesh.cxx
deleted file mode 100644 (file)
index baf81ed..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-#include "DriverMED_R_SMDS_Mesh.h"
diff --git a/src/DriverMED/DriverMED_R_SMDS_Mesh.h b/src/DriverMED/DriverMED_R_SMDS_Mesh.h
deleted file mode 100644 (file)
index e7373c3..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-#ifndef _INCLUDE_DRIVERMED_R_SMDS_MESH
-#define _INCLUDE_DRIVERMED_R_SMDS_MESH
-
-#include "SMESH_DriverMED.hxx"
-
-#include "Driver_SMDS_Mesh.h"
-
-class MESHDRIVERMED_EXPORT DriverMED_R_SMDS_Mesh: public Driver_SMDS_Mesh
-{};
-
-#endif
diff --git a/src/DriverMED/DriverMED_R_SMESHDS_Document.cxx b/src/DriverMED/DriverMED_R_SMESHDS_Document.cxx
deleted file mode 100644 (file)
index 0c97ede..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-#include "DriverMED_R_SMESHDS_Document.h"
diff --git a/src/DriverMED/DriverMED_R_SMESHDS_Document.h b/src/DriverMED/DriverMED_R_SMESHDS_Document.h
deleted file mode 100644 (file)
index 640ea67..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-#ifndef _INCLUDE_DRIVERMED_R_SMESHDS_DOCUMENT
-#define _INCLUDE_DRIVERMED_R_SMESHDS_DOCUMENT
-
-#include "SMESH_DriverMED.hxx"
-
-#include "Driver_Document.h"
-
-class MESHDRIVERMED_EXPORT DriverMED_R_SMESHDS_Document : public Driver_Document 
-{};
-
-#endif
index 99f892d14e1ab10815817b5400f50d0f2a88d412..a60b77ca9e33cde6123d5eb35e4c5c0f5d6a133b 100644 (file)
@@ -1,30 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH DriverMED : driver to read and write 'med' files
 //  File   : DriverMED_R_SMESHDS_Mesh.cxx
 //  Module : SMESH
 //
 #include "DriverMED_R_SMESHDS_Mesh.h"
-#include "DriverMED_R_SMDS_Mesh.h"
 #include "SMESHDS_Mesh.hxx"
 #include "utilities.h"
 
@@ -39,7 +39,7 @@
 #include <stdlib.h>
 
 #ifdef _DEBUG_
-static int MYDEBUG = 0;
+static int MYDEBUG = 1;
 //#define _DEXCEPT_
 #else
 static int MYDEBUG = 0;
@@ -48,19 +48,21 @@ static int MYDEBUG = 0;
 #define _EDF_NODE_IDS_
 
 using namespace MED;
+using namespace std;
 
 void
 DriverMED_R_SMESHDS_Mesh
-::SetMeshName(std::string theMeshName)
+::SetMeshName(string theMeshName)
 {
   myMeshName = theMeshName;
 }
 
 static const SMDS_MeshNode* 
-FindNode(const SMDS_Mesh* theMesh, TInt theId){
+FindNode(const SMDS_Mesh* theMesh, TInt theId)
+{
   const SMDS_MeshNode* aNode = theMesh->FindNode(theId);
   if(aNode) return aNode;
-  EXCEPTION(std::runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<<theId);
+  EXCEPTION(runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<<theId);
 }
 
 
@@ -79,91 +81,88 @@ DriverMED_R_SMESHDS_Mesh
     aResult = DRS_EMPTY;
     if(TInt aNbMeshes = aMed->GetNbMeshes()){
       for(int iMesh = 0; iMesh < aNbMeshes; iMesh++){
-       // Reading the MED mesh
-       //---------------------
-       PMeshInfo aMeshInfo = aMed->GetPMeshInfo(iMesh+1);
+        // Reading the MED mesh
+        //---------------------
+        PMeshInfo aMeshInfo = aMed->GetPMeshInfo(iMesh+1);
 
-        std::string aMeshName;
+        string aMeshName;
         if (myMeshId != -1) {
-          std::ostringstream aMeshNameStr;
+          ostringstream aMeshNameStr;
           aMeshNameStr<<myMeshId;
           aMeshName = aMeshNameStr.str();
         } else {
           aMeshName = myMeshName;
         }
-       if(MYDEBUG) MESSAGE("Perform - aMeshName : "<<aMeshName<<"; "<<aMeshInfo->GetName());
-       if(aMeshName != aMeshInfo->GetName()) continue;
+        if(MYDEBUG) MESSAGE("Perform - aMeshName : "<<aMeshName<<"; "<<aMeshInfo->GetName());
+        if(aMeshName != aMeshInfo->GetName()) continue;
         aResult = DRS_OK;
 
-       //TInt aMeshDim = aMeshInfo->GetDim();
-       
         // Reading MED families to the temporary structure
-       //------------------------------------------------
-       TErr anErr;
-       TInt aNbFams = aMed->GetNbFamilies(aMeshInfo);
+        //------------------------------------------------
+        TErr anErr;
+        TInt aNbFams = aMed->GetNbFamilies(aMeshInfo);
         if(MYDEBUG) MESSAGE("Read " << aNbFams << " families");
         for (TInt iFam = 0; iFam < aNbFams; iFam++) {
-         PFamilyInfo aFamilyInfo = aMed->GetPFamilyInfo(aMeshInfo,iFam+1,&anErr);
-         if(anErr >= 0){
-           TInt aFamId = aFamilyInfo->GetId();
-           if(MYDEBUG) MESSAGE("Family " << aFamId << " :");
-           
+          PFamilyInfo aFamilyInfo = aMed->GetPFamilyInfo(aMeshInfo,iFam+1,&anErr);
+          if(anErr >= 0){
+            TInt aFamId = aFamilyInfo->GetId();
+            if(MYDEBUG) MESSAGE("Family " << aFamId << " :");
+            
             DriverMED_FamilyPtr aFamily (new DriverMED_Family);
-           
+            
             TInt aNbGrp = aFamilyInfo->GetNbGroup();
             if(MYDEBUG) MESSAGE("belong to " << aNbGrp << " groups");
-           bool isAttrOk = false;
-           if(aFamilyInfo->GetNbAttr() == aNbGrp)
-             isAttrOk = true;
+            bool isAttrOk = false;
+            if(aFamilyInfo->GetNbAttr() == aNbGrp)
+              isAttrOk = true;
             for (TInt iGr = 0; iGr < aNbGrp; iGr++) {
-              std::string aGroupName = aFamilyInfo->GetGroupName(iGr);
+              string aGroupName = aFamilyInfo->GetGroupName(iGr);
               if(isAttrOk){
-               TInt anAttrVal = aFamilyInfo->GetAttrVal(iGr);
-               aFamily->SetGroupAttributVal(anAttrVal);
-             }
-             
+                TInt anAttrVal = aFamilyInfo->GetAttrVal(iGr);
+                aFamily->SetGroupAttributVal(anAttrVal);
+              }
+              
               if(MYDEBUG) MESSAGE(aGroupName);
               aFamily->AddGroupName(aGroupName);
-             
+              
             }
             aFamily->SetId( aFamId );
             myFamilies[aFamId] = aFamily;
-         }
+          }
         }
 
-       if (aMeshInfo->GetType() == MED::eSTRUCTURE){
-         /*bool aRes = */buildMeshGrille(aMed,aMeshInfo);
-         continue;
-       }
+        if (aMeshInfo->GetType() == MED::eSTRUCTURE){
+          /*bool aRes = */buildMeshGrille(aMed,aMeshInfo);
+          continue;
+        }
 
         // Reading MED nodes to the corresponding SMDS structure
-       //------------------------------------------------------
+        //------------------------------------------------------
         PNodeInfo aNodeInfo = aMed->GetPNodeInfo(aMeshInfo);
-       if (!aNodeInfo) {
+        if (!aNodeInfo) {
           aResult = DRS_FAIL;
-         continue;
+          continue;
         }
+        aMeshInfo->myDim=aMeshInfo->mySpaceDim;// ignore meshdim in MEDFile because it can be false
+        PCoordHelper aCoordHelper = GetCoordHelper(aNodeInfo);
 
-       PCoordHelper aCoordHelper = GetCoordHelper(aNodeInfo);
-
-       EBooleen anIsNodeNum = aNodeInfo->IsElemNum();
-       TInt aNbElems = aNodeInfo->GetNbElem();
-       if(MYDEBUG) MESSAGE("Perform - aNodeInfo->GetNbElem() = "<<aNbElems<<"; anIsNodeNum = "<<anIsNodeNum);
+        EBooleen anIsNodeNum = aNodeInfo->IsElemNum();
+        TInt aNbElems = aNodeInfo->GetNbElem();
+        if(MYDEBUG) MESSAGE("Perform - aNodeInfo->GetNbElem() = "<<aNbElems<<"; anIsNodeNum = "<<anIsNodeNum);
         DriverMED_FamilyPtr aFamily;
         for(TInt iElem = 0; iElem < aNbElems; iElem++){
-         TCCoordSlice aCoordSlice = aNodeInfo->GetCoordSlice(iElem);
+          TCCoordSlice aCoordSlice = aNodeInfo->GetCoordSlice(iElem);
           double aCoords[3] = {0.0, 0.0, 0.0};
           for(TInt iDim = 0; iDim < 3; iDim++)
             aCoords[iDim] = aCoordHelper->GetCoord(aCoordSlice,iDim);
           const SMDS_MeshNode* aNode;
           if(anIsNodeNum) {
-           aNode = myMesh->AddNodeWithID
+            aNode = myMesh->AddNodeWithID
               (aCoords[0],aCoords[1],aCoords[2],aNodeInfo->GetElemNum(iElem));
           } else {
-           aNode = myMesh->AddNode
-              (aCoords[0],aCoords[1],aCoords[2]);
+            aNode = myMesh->AddNodeWithID
+              (aCoords[0],aCoords[1],aCoords[2], iElem+1);
           }
-          //cout<<aNode->GetID()<<": "<<aNode->X()<<", "<<aNode->Y()<<", "<<aNode->Z()<<endl;
 
           // Save reference to this node from its family
           TInt aFamNum = aNodeInfo->GetFamNum(iElem);
@@ -174,44 +173,108 @@ DriverMED_R_SMESHDS_Mesh
           }
         }
 
-       // Reading pre information about all MED cells
-       //--------------------------------------------
-       typedef MED::TVector<int> TNodeIds;
+        // Reading pre information about all MED cells
+        //--------------------------------------------
+        typedef MED::TVector<int> TNodeIds;
         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 EEntiteMaillage& anEntity = anEntityIter->first;
-         if(anEntity == eNOEUD) continue;
-         // Reading MED cells to the corresponding SMDS structure
-         //------------------------------------------------------
-         const MED::TGeom2Size& aGeom2Size = anEntityIter->second;
-         MED::TGeom2Size::const_iterator aGeom2SizeIter = aGeom2Size.begin();
-         for(; aGeom2SizeIter != aGeom2Size.end(); aGeom2SizeIter++){
-           const EGeometrieElement& aGeom = aGeom2SizeIter->first;
-
-           switch(aGeom) {
-//         case ePOINT1: ## PAL16410
-//           break;
-           case ePOLYGONE: {
+        MED::TEntityInfo aEntityInfo = aMed->GetEntityInfo(aMeshInfo);
+        MED::TEntityInfo::iterator anEntityIter = aEntityInfo.begin();
+        for(; anEntityIter != aEntityInfo.end(); anEntityIter++){
+          const EEntiteMaillage& anEntity = anEntityIter->first;
+          if(anEntity == eNOEUD) continue;
+          // Reading MED cells to the corresponding SMDS structure
+          //------------------------------------------------------
+          const MED::TGeom2Size& aGeom2Size = anEntityIter->second;
+          MED::TGeom2Size::const_iterator aGeom2SizeIter = aGeom2Size.begin();
+          for(; aGeom2SizeIter != aGeom2Size.end(); aGeom2SizeIter++){
+            const EGeometrieElement& aGeom = aGeom2SizeIter->first;
+
+            if ( anEntity == eSTRUCT_ELEMENT ) // MED_BALL (issue 0021459)
+            {
+              PBallInfo aBallInfo = aMed->GetPBallInfo(aMeshInfo);
+              TInt      aNbBalls  = aBallInfo->GetNbElem();
+
+              EBooleen anIsElemNum = takeNumbers ? aBallInfo->IsElemNum() : eFAUX;
+              if ( anIsElemNum && aBallInfo->myElemNum->empty() )
+                anIsElemNum = eFAUX;
+
+              // get supporting nodes
+              TNodeIds aNodeIds;
+#ifdef _EDF_NODE_IDS_
+              if(anIsNodeNum) {
+                aNodeIds.resize( aNbBalls );
+                for(TInt iBall = 0; iBall < aNbBalls && anIsNodeNum; iBall++)
+                {
+                  aNodeIds[iBall] = aNodeInfo->GetElemNum(iBall);
+                  anIsNodeNum = myMesh->FindNode( aNodeIds[iBall] ) ? eVRAI : eFAUX;
+                }
+              }
+#endif
+              if ( !anIsNodeNum )
+                aNodeIds.swap( *(aBallInfo->myConn ));
+
+              // allocate array of diameters
+              vtkIdType maxID = myMesh->MaxElementID() + aNbBalls;
+              if ( anIsElemNum && !aBallInfo->myElemNum->empty() )
+                maxID = *std::max_element( aBallInfo->myElemNum->begin(),
+                                           aBallInfo->myElemNum->end() );
+              myMesh->getGrid()->AllocateDiameters( maxID ); // performance optimization
+
+              // create balls
+              SMDS_MeshElement* anElement;
+              DriverMED_FamilyPtr aFamily;
+              for ( TInt iBall = 0; iBall < aNbBalls; iBall++)
+              {
+                anElement = 0;
+                if ( anIsElemNum ) {
+                  if (!(anElement = myMesh->AddBallWithID( aNodeIds[iBall],
+                                                           aBallInfo->myDiameters[iBall],
+                                                           aBallInfo->GetElemNum(iBall))))
+                    anIsElemNum = eFAUX;
+                }
+                if ( !anElement )
+                  myMesh->AddBall( myMesh->FindNode( aNodeIds[iBall]),
+                                   aBallInfo->myDiameters[iBall] );
+
+                // Save reference to this element from its family
+                TInt aFamNum = aBallInfo->GetFamNum(iBall);
+                if ( checkFamilyID ( aFamily, aFamNum ))
+                {
+                  aFamily->AddElement(anElement);
+                  aFamily->SetType( SMDSAbs_Ball );
+                }
+              }
+
+              if ( !anIsElemNum &&
+                   ( takeNumbers && aBallInfo->IsElemNum() && !aBallInfo->myElemNum->empty() ))
+                if ( aResult < DRS_WARN_RENUMBER )
+                  aResult = DRS_WARN_RENUMBER;
+
+              continue;
+            } // MED_BALL
+
+            switch(aGeom) {
+//          case ePOINT1: ## PAL16410
+//            break;
+            case ePOLYGONE: {
               PPolygoneInfo aPolygoneInfo = aMed->GetPPolygoneInfo(aMeshInfo,anEntity,aGeom);
               EBooleen anIsElemNum = takeNumbers ? aPolygoneInfo->IsElemNum() : eFAUX;
-             
-             TInt aNbElem = aPolygoneInfo->GetNbElem();
-             for(TInt iElem = 0; iElem < aNbElem; iElem++){
-               MED::TCConnSlice aConnSlice = aPolygoneInfo->GetConnSlice(iElem);
-               TInt aNbConn = aPolygoneInfo->GetNbConn(iElem);
-               TNodeIds aNodeIds(aNbConn);
+              
+              TInt aNbElem = aPolygoneInfo->GetNbElem();
+              for(TInt iElem = 0; iElem < aNbElem; iElem++){
+                MED::TCConnSlice aConnSlice = aPolygoneInfo->GetConnSlice(iElem);
+                TInt aNbConn = aPolygoneInfo->GetNbConn(iElem);
+                TNodeIds aNodeIds(aNbConn);
 #ifdef _EDF_NODE_IDS_
-               if(anIsNodeNum)
-                 for(TInt iConn = 0; iConn < aNbConn; iConn++)
-                   aNodeIds[iConn] = aNodeInfo->GetElemNum(aConnSlice[iConn] - 1);
-               else
-                 for(TInt iConn = 0; iConn < aNbConn; iConn++)
-                   aNodeIds[iConn] = aConnSlice[iConn];
+                if(anIsNodeNum)
+                  for(TInt iConn = 0; iConn < aNbConn; iConn++)
+                    aNodeIds[iConn] = aNodeInfo->GetElemNum(aConnSlice[iConn] - 1);
+                else
+                  for(TInt iConn = 0; iConn < aNbConn; iConn++)
+                    aNodeIds[iConn] = aConnSlice[iConn];
 #else
-               for(TInt iConn = 0; iConn < aNbConn; iConn++)
-                 aNodeIds[iConn] = aConnSlice[iConn];
+                for(TInt iConn = 0; iConn < aNbConn; iConn++)
+                  aNodeIds[iConn] = aConnSlice[iConn];
 #endif
                 bool isRenum = false;
                 SMDS_MeshElement* anElement = NULL;
@@ -221,12 +284,12 @@ DriverMED_R_SMESHDS_Mesh
                 try{
 #endif
                   if(anIsElemNum){
-                   TInt anElemId = aPolygoneInfo->GetElemNum(iElem);
+                    TInt anElemId = aPolygoneInfo->GetElemNum(iElem);
                     anElement = myMesh->AddPolygonalFaceWithID(aNodeIds,anElemId);
-                 }
+                  }
                   if(!anElement){
-                    std::vector<const SMDS_MeshNode*> aNodes(aNbConn);
-                   for(TInt iConn = 0; iConn < aNbConn; iConn++)
+                    vector<const SMDS_MeshNode*> aNodes(aNbConn);
+                    for(TInt iConn = 0; iConn < aNbConn; iConn++)
                       aNodes[iConn] = FindNode(myMesh,aNodeIds[iConn]);
                     anElement = myMesh->AddPolygonalFace(aNodes);
                     isRenum = anIsElemNum;
@@ -256,107 +319,117 @@ DriverMED_R_SMESHDS_Mesh
                 }
               }
               break;
-           }
-           case ePOLYEDRE: {
+            }
+            case ePOLYEDRE: {
               PPolyedreInfo aPolyedreInfo = aMed->GetPPolyedreInfo(aMeshInfo,anEntity,aGeom);
               EBooleen anIsElemNum = takeNumbers ? aPolyedreInfo->IsElemNum() : eFAUX;
 
-             TInt aNbElem = aPolyedreInfo->GetNbElem();
-             for(TInt iElem = 0; iElem < aNbElem; iElem++){
-               MED::TCConnSliceArr aConnSliceArr = aPolyedreInfo->GetConnSliceArr(iElem);
-               TInt aNbFaces = aConnSliceArr.size();
+              TInt aNbElem = aPolyedreInfo->GetNbElem();
+              for(TInt iElem = 0; iElem < aNbElem; iElem++){
+                MED::TCConnSliceArr aConnSliceArr = aPolyedreInfo->GetConnSliceArr(iElem);
+                TInt aNbFaces = aConnSliceArr.size();
                 typedef MED::TVector<int> TQuantities;
-               TQuantities aQuantities(aNbFaces);
-               TInt aNbNodes = aPolyedreInfo->GetNbNodes(iElem);
-               TNodeIds aNodeIds(aNbNodes);
-               for(TInt iFace = 0, iNode = 0; iFace < aNbFaces; iFace++){
-                 MED::TCConnSlice aConnSlice = aConnSliceArr[iFace];
-                 TInt aNbConn = aConnSlice.size();
+                TQuantities aQuantities(aNbFaces);
+                TInt aNbNodes = aPolyedreInfo->GetNbNodes(iElem);
+                TNodeIds aNodeIds(aNbNodes);
+                for(TInt iFace = 0, iNode = 0; iFace < aNbFaces; iFace++){
+                  MED::TCConnSlice aConnSlice = aConnSliceArr[iFace];
+                  TInt aNbConn = aConnSlice.size();
                   aQuantities[iFace] = aNbConn;
 #ifdef _EDF_NODE_IDS_
-                 if(anIsNodeNum)
-                   for(TInt iConn = 0; iConn < aNbConn; iConn++)
-                     aNodeIds[iNode++] = aNodeInfo->GetElemNum(aConnSlice[iConn] - 1);
-                 else
-                   for(TInt iConn = 0; iConn < aNbConn; iConn++)
-                     aNodeIds[iNode++] = aConnSlice[iConn];
+                  if(anIsNodeNum)
+                    for(TInt iConn = 0; iConn < aNbConn; iConn++)
+                      {
+                      aNodeIds[iNode] = aNodeInfo->GetElemNum(aConnSlice[iConn] - 1);
+                      iNode++;
+                      }
+                  else
+                    for(TInt iConn = 0; iConn < aNbConn; iConn++)
+                      {
+                      aNodeIds[iNode++] = aConnSlice[iConn];
+                      }
 #else
-                 for(TInt iConn = 0; iConn < aNbConn; iConn++)
-                   aNodeIds[iNode++] = aConnSlice[iConn];
-#endif         
-               }
-
-               bool isRenum = false;
-               SMDS_MeshElement* anElement = NULL;
-               TInt aFamNum = aPolyedreInfo->GetFamNum(iElem);
-               
+                  for(TInt iConn = 0; iConn < aNbConn; iConn++)
+                    {
+                    aNodeIds[iNode++] = aConnSlice[iConn];
+                    }
+#endif          
+                }
+
+                bool isRenum = false;
+                SMDS_MeshElement* anElement = NULL;
+                TInt aFamNum = aPolyedreInfo->GetFamNum(iElem);
+                
 #ifndef _DEXCEPT_
-               try{
+                try{
 #endif
-                 if(anIsElemNum){
-                   TInt anElemId = aPolyedreInfo->GetElemNum(iElem);
-                   anElement = myMesh->AddPolyhedralVolumeWithID(aNodeIds,aQuantities,anElemId);
-                 }
-                 if(!anElement){
-                   std::vector<const SMDS_MeshNode*> aNodes(aNbNodes);
-                   for(TInt iConn = 0; iConn < aNbNodes; iConn++)
-                     aNodes[iConn] = FindNode(myMesh,aNodeIds[iConn]);
-                   anElement = myMesh->AddPolyhedralVolume(aNodes,aQuantities);
-                   isRenum = anIsElemNum;
-                 }
+                  if(anIsElemNum){
+                    TInt anElemId = aPolyedreInfo->GetElemNum(iElem);
+                    anElement = myMesh->AddPolyhedralVolumeWithID(aNodeIds,aQuantities,anElemId);
+                  }
+                  if(!anElement){
+                    vector<const SMDS_MeshNode*> aNodes(aNbNodes);
+                    for(TInt iConn = 0; iConn < aNbNodes; iConn++)
+                      aNodes[iConn] = FindNode(myMesh,aNodeIds[iConn]);
+                    anElement = myMesh->AddPolyhedralVolume(aNodes,aQuantities);
+                    isRenum = anIsElemNum;
+                  }
 #ifndef _DEXCEPT_
-               }catch(const std::exception& exc){
-                 aResult = DRS_FAIL;
-               }catch(...){
-                 aResult = DRS_FAIL;
-               }
-#endif         
-               if(!anElement){
-                 aResult = DRS_WARN_SKIP_ELEM;
-               }else{
-                 if(isRenum){
-                   anIsElemNum = eFAUX;
-                   takeNumbers = false;
-                   if (aResult < DRS_WARN_RENUMBER)
-                     aResult = DRS_WARN_RENUMBER;
-                 }
-                 if ( checkFamilyID ( aFamily, aFamNum )) {
-                   // Save reference to this element from its family
-                   aFamily->AddElement(anElement);
-                   aFamily->SetType(anElement->GetType());
-                 }
-               }
-             }
+                }catch(const std::exception& exc){
+                  aResult = DRS_FAIL;
+                }catch(...){
+                  aResult = DRS_FAIL;
+                }
+#endif          
+                if(!anElement){
+                  aResult = DRS_WARN_SKIP_ELEM;
+                }else{
+                  if(isRenum){
+                    anIsElemNum = eFAUX;
+                    takeNumbers = false;
+                    if (aResult < DRS_WARN_RENUMBER)
+                      aResult = DRS_WARN_RENUMBER;
+                  }
+                  if ( checkFamilyID ( aFamily, aFamNum )) {
+                    // Save reference to this element from its family
+                    aFamily->AddElement(anElement);
+                    aFamily->SetType(anElement->GetType());
+                  }
+                }
+              }
               break;
             }
-           default: {
+            default: {
               PCellInfo aCellInfo = aMed->GetPCellInfo(aMeshInfo,anEntity,aGeom);
               EBooleen anIsElemNum = takeNumbers ? aCellInfo->IsElemNum() : eFAUX;
               TInt aNbElems = aCellInfo->GetNbElem();
               if(MYDEBUG) MESSAGE("Perform - anEntity = "<<anEntity<<"; anIsElemNum = "<<anIsElemNum);
               if(MYDEBUG) MESSAGE("Perform - aGeom = "<<aGeom<<"; aNbElems = "<<aNbElems);
 
+              TInt aNbNodes = -1;
+              switch(aGeom){
+              case eSEG2:    aNbNodes = 2;  break;
+              case eSEG3:    aNbNodes = 3;  break;
+              case eTRIA3:   aNbNodes = 3;  break;
+              case eTRIA6:   aNbNodes = 6;  break;
+              case eQUAD4:   aNbNodes = 4;  break;
+              case eQUAD8:   aNbNodes = 8;  break;
+              case eQUAD9:   aNbNodes = 9;  break;
+              case eTETRA4:  aNbNodes = 4;  break;
+              case eTETRA10: aNbNodes = 10; break;
+              case ePYRA5:   aNbNodes = 5;  break;
+              case ePYRA13:  aNbNodes = 13; break;
+              case ePENTA6:  aNbNodes = 6;  break;
+              case ePENTA15: aNbNodes = 15; break;
+              case eHEXA8:   aNbNodes = 8;  break;
+              case eHEXA20:  aNbNodes = 20; break;
+              case eHEXA27:  aNbNodes = 27; break;
+              case eOCTA12:  aNbNodes = 12; break;
+              case ePOINT1:  aNbNodes = 1;  break;
+              default:;
+              }
+              vector<TInt> aNodeIds(aNbNodes);
               for(int iElem = 0; iElem < aNbElems; iElem++){
-                TInt aNbNodes = -1;
-                switch(aGeom){
-                case eSEG2:    aNbNodes = 2;  break;
-                case eSEG3:    aNbNodes = 3;  break;
-                case eTRIA3:   aNbNodes = 3;  break;
-                case eTRIA6:   aNbNodes = 6;  break;
-                case eQUAD4:   aNbNodes = 4;  break;
-                case eQUAD8:   aNbNodes = 8;  break;
-                case eTETRA4:  aNbNodes = 4;  break;
-                case eTETRA10: aNbNodes = 10; break;
-                case ePYRA5:   aNbNodes = 5;  break;
-                case ePYRA13:  aNbNodes = 13; break;
-                case ePENTA6:  aNbNodes = 6;  break;
-                case ePENTA15: aNbNodes = 15; break;
-                case eHEXA8:   aNbNodes = 8;  break;
-                case eHEXA20:  aNbNodes = 20; break;
-                case ePOINT1:  aNbNodes = 1;  break;
-                default:;
-                }
-                std::vector<TInt> aNodeIds(aNbNodes);
                 bool anIsValidConnect = false;
                 TCConnSlice aConnSlice = aCellInfo->GetConnSlice(iElem);
 #ifndef _DEXCEPT_
@@ -376,10 +449,10 @@ DriverMED_R_SMESHDS_Mesh
                   anIsValidConnect = true;
 #ifndef _DEXCEPT_
                 }catch(const std::exception& exc){
-                  //INFOS("Follow exception was cought:\n\t"<<exc.what());
+                  INFOS("Following exception was caught:\n\t"<<exc.what());
                   aResult = DRS_FAIL;
                 }catch(...){
-                  //INFOS("Unknown exception was cought !!!");
+                  INFOS("Unknown exception was caught !!!");
                   aResult = DRS_FAIL;
                 }
 #endif          
@@ -395,6 +468,16 @@ DriverMED_R_SMESHDS_Mesh
                   //MESSAGE("Try to create element # " << iElem << " with id = "
                   //        << aCellInfo->GetElemNum(iElem));
                   switch(aGeom) {
+                  case ePOINT1:
+                    //anElement = FindNode(myMesh,aNodeIds[0]);
+                    if(anIsElemNum)
+                      anElement = myMesh->Add0DElementWithID
+                        (aNodeIds[0], aCellInfo->GetElemNum(iElem));
+                    if (!anElement) {
+                      anElement = myMesh->Add0DElement(FindNode(myMesh,aNodeIds[0]));
+                      isRenum = anIsElemNum;
+                    }
+                    break;
                   case eSEG2:
                     if(anIsElemNum)
                       anElement = myMesh->AddEdgeWithID(aNodeIds[0],
@@ -484,6 +567,27 @@ DriverMED_R_SMESHDS_Mesh
                       isRenum = anIsElemNum;
                     }
                     break;
+                  case eQUAD9:
+                    aNbNodes = 9;
+                    if(anIsElemNum)
+                      anElement = myMesh->AddFaceWithID(aNodeIds[0], aNodeIds[1],
+                                                        aNodeIds[2], aNodeIds[3],
+                                                        aNodeIds[4], aNodeIds[5],
+                                                        aNodeIds[6], aNodeIds[7], aNodeIds[8],
+                                                        aCellInfo->GetElemNum(iElem));
+                    if (!anElement) {
+                      anElement = myMesh->AddFace(FindNode(myMesh,aNodeIds[0]),
+                                                  FindNode(myMesh,aNodeIds[1]),
+                                                  FindNode(myMesh,aNodeIds[2]),
+                                                  FindNode(myMesh,aNodeIds[3]),
+                                                  FindNode(myMesh,aNodeIds[4]),
+                                                  FindNode(myMesh,aNodeIds[5]),
+                                                  FindNode(myMesh,aNodeIds[6]),
+                                                  FindNode(myMesh,aNodeIds[7]),
+                                                  FindNode(myMesh,aNodeIds[8]));
+                      isRenum = anIsElemNum;
+                    }
+                    break;
                   case eTETRA4:
                     aNbNodes = 4;
                     if(anIsElemNum)
@@ -523,7 +627,6 @@ DriverMED_R_SMESHDS_Mesh
                     break;
                   case ePYRA5:
                     aNbNodes = 5;
-                    // There is some differnce between SMDS and MED
                     if(anIsElemNum)
                       anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
                                                           aNodeIds[2], aNodeIds[3],
@@ -540,7 +643,6 @@ DriverMED_R_SMESHDS_Mesh
                     break;
                   case ePYRA13:
                     aNbNodes = 13;
-                    // There is some differnce between SMDS and MED
                     if(anIsElemNum)
                       anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
                                                           aNodeIds[2], aNodeIds[3],
@@ -642,6 +744,7 @@ DriverMED_R_SMESHDS_Mesh
                       isRenum = anIsElemNum;
                     }
                     break;
+
                   case eHEXA20:
                     aNbNodes = 20;
                     if(anIsElemNum)
@@ -681,16 +784,91 @@ DriverMED_R_SMESHDS_Mesh
                     }
                     break;
 
-                  case ePOINT1:
-                    anElement = FindNode(myMesh,aNodeIds[0]);
+                  case eHEXA27:
+                    aNbNodes = 27;
+                    if(anIsElemNum)
+                      anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
+                                                          aNodeIds[2], aNodeIds[3],
+                                                          aNodeIds[4], aNodeIds[5],
+                                                          aNodeIds[6], aNodeIds[7],
+                                                          aNodeIds[8], aNodeIds[9],
+                                                          aNodeIds[10], aNodeIds[11],
+                                                          aNodeIds[12], aNodeIds[13],
+                                                          aNodeIds[14], aNodeIds[15],
+                                                          aNodeIds[16], aNodeIds[17],
+                                                          aNodeIds[18], aNodeIds[19],
+                                                          aNodeIds[20], aNodeIds[21],
+                                                          aNodeIds[22], aNodeIds[23],
+                                                          aNodeIds[24], aNodeIds[25],
+                                                          aNodeIds[26],
+                                                          aCellInfo->GetElemNum(iElem));
+                    if (!anElement) {
+                      anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
+                                                    FindNode(myMesh,aNodeIds[1]),
+                                                    FindNode(myMesh,aNodeIds[2]),
+                                                    FindNode(myMesh,aNodeIds[3]),
+                                                    FindNode(myMesh,aNodeIds[4]),
+                                                    FindNode(myMesh,aNodeIds[5]),
+                                                    FindNode(myMesh,aNodeIds[6]),
+                                                    FindNode(myMesh,aNodeIds[7]),
+                                                    FindNode(myMesh,aNodeIds[8]),
+                                                    FindNode(myMesh,aNodeIds[9]),
+                                                    FindNode(myMesh,aNodeIds[10]),
+                                                    FindNode(myMesh,aNodeIds[11]),
+                                                    FindNode(myMesh,aNodeIds[12]),
+                                                    FindNode(myMesh,aNodeIds[13]),
+                                                    FindNode(myMesh,aNodeIds[14]),
+                                                    FindNode(myMesh,aNodeIds[15]),
+                                                    FindNode(myMesh,aNodeIds[16]),
+                                                    FindNode(myMesh,aNodeIds[17]),
+                                                    FindNode(myMesh,aNodeIds[18]),
+                                                    FindNode(myMesh,aNodeIds[19]),
+                                                    FindNode(myMesh,aNodeIds[20]),
+                                                    FindNode(myMesh,aNodeIds[21]),
+                                                    FindNode(myMesh,aNodeIds[22]),
+                                                    FindNode(myMesh,aNodeIds[23]),
+                                                    FindNode(myMesh,aNodeIds[24]),
+                                                    FindNode(myMesh,aNodeIds[25]),
+                                                    FindNode(myMesh,aNodeIds[26]));
+                      isRenum = anIsElemNum;
+                    }
                     break;
-                  }
+
+                  case eOCTA12:
+                    aNbNodes = 12;
+                    if(anIsElemNum)
+                      anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
+                                                          aNodeIds[2], aNodeIds[3],
+                                                          aNodeIds[4], aNodeIds[5],
+                                                          aNodeIds[6], aNodeIds[7],
+                                                          aNodeIds[8], aNodeIds[9],
+                                                          aNodeIds[10], aNodeIds[11],
+                                                          aCellInfo->GetElemNum(iElem));
+                    if (!anElement) {
+                      anElement = myMesh->AddVolume(FindNode(myMesh,aNodeIds[0]),
+                                                    FindNode(myMesh,aNodeIds[1]),
+                                                    FindNode(myMesh,aNodeIds[2]),
+                                                    FindNode(myMesh,aNodeIds[3]),
+                                                    FindNode(myMesh,aNodeIds[4]),
+                                                    FindNode(myMesh,aNodeIds[5]),
+                                                    FindNode(myMesh,aNodeIds[6]),
+                                                    FindNode(myMesh,aNodeIds[7]),
+                                                    FindNode(myMesh,aNodeIds[8]),
+                                                    FindNode(myMesh,aNodeIds[9]),
+                                                    FindNode(myMesh,aNodeIds[10]),
+                                                    FindNode(myMesh,aNodeIds[11]));
+                      isRenum = anIsElemNum;
+                    }
+                    break;
+
+                  } // switch(aGeom)
+
 #ifndef _DEXCEPT_
                 }catch(const std::exception& exc){
-                  //INFOS("Follow exception was cought:\n\t"<<exc.what());
+                  INFOS("The following exception was caught:\n\t"<<exc.what());
                   aResult = DRS_FAIL;
                 }catch(...){
-                  //INFOS("Unknown exception was cought !!!");
+                  INFOS("Unknown exception was caught !!!");
                   aResult = DRS_FAIL;
                 }
 #endif          
@@ -718,20 +896,22 @@ DriverMED_R_SMESHDS_Mesh
     }
 #ifndef _DEXCEPT_
   }catch(const std::exception& exc){
-    INFOS("Follow exception was cought:\n\t"<<exc.what());
+    INFOS("The following exception was caught:\n\t"<<exc.what());
     aResult = DRS_FAIL;
   }catch(...){
-    INFOS("Unknown exception was cought !!!");
+    INFOS("Unknown exception was caught !!!");
     aResult = DRS_FAIL;
   }
 #endif
+  if (myMesh)
+    myMesh->compactMesh();
   if(MYDEBUG) MESSAGE("Perform - aResult status = "<<aResult);
   return aResult;
 }
 
-std::list<std::string> DriverMED_R_SMESHDS_Mesh::GetMeshNames(Status& theStatus)
+list<string> DriverMED_R_SMESHDS_Mesh::GetMeshNames(Status& theStatus)
 {
-  std::list<std::string> aMeshNames;
+  list<string> aMeshNames;
 
   try {
     if(MYDEBUG) MESSAGE("GetMeshNames - myFile : " << myFile);
@@ -740,43 +920,45 @@ std::list<std::string> DriverMED_R_SMESHDS_Mesh::GetMeshNames(Status& theStatus)
 
     if (TInt aNbMeshes = aMed->GetNbMeshes()) {
       for (int iMesh = 0; iMesh < aNbMeshes; iMesh++) {
-       // Reading the MED mesh
-       //---------------------
-       PMeshInfo aMeshInfo = aMed->GetPMeshInfo(iMesh+1);
-       aMeshNames.push_back(aMeshInfo->GetName());
+        // Reading the MED mesh
+        //---------------------
+        PMeshInfo aMeshInfo = aMed->GetPMeshInfo(iMesh+1);
+        aMeshNames.push_back(aMeshInfo->GetName());
       }
     }
   }catch(const std::exception& exc){
-    INFOS("Follow exception was cought:\n\t"<<exc.what());
+    INFOS("Following exception was caught:\n\t"<<exc.what());
     theStatus = DRS_FAIL;
   }catch(...){
-    INFOS("Unknown exception was cought !!!");
+    INFOS("Unknown exception was caught !!!");
     theStatus = DRS_FAIL;
   }
 
   return aMeshNames;
 }
 
-std::list<TNameAndType> DriverMED_R_SMESHDS_Mesh::GetGroupNamesAndTypes()
+list<TNameAndType> DriverMED_R_SMESHDS_Mesh::GetGroupNamesAndTypes()
 {
-  std::list<TNameAndType> aResult;
-  std::set<TNameAndType> aResGroupNames;
+  list<TNameAndType> aResult;
+  set<TNameAndType> aResGroupNames;
 
-  std::map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
+  map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
   for (; aFamsIter != myFamilies.end(); aFamsIter++)
   {
     DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
     const MED::TStringSet& aGroupNames = aFamily->GetGroupNames();
-    std::set<std::string>::const_iterator aGrNamesIter = aGroupNames.begin();
+    set<string>::const_iterator aGrNamesIter = aGroupNames.begin();
     for (; aGrNamesIter != aGroupNames.end(); aGrNamesIter++)
     {
-      TNameAndType aNameAndType = make_pair( *aGrNamesIter, aFamily->GetType() );
-      // Check, if this is a Group or SubMesh name
-//if (aName.substr(0, 5) == string("Group")) {
+      const set< SMDSAbs_ElementType >& types = aFamily->GetTypes();
+      set< SMDSAbs_ElementType >::const_iterator type = types.begin();
+      for ( ; type != types.end(); ++type )
+      {
+        TNameAndType aNameAndType = make_pair( *aGrNamesIter, *type );
         if ( aResGroupNames.insert( aNameAndType ).second ) {
           aResult.push_back( aNameAndType );
         }
-//    }
+      }
     }
   }
 
@@ -785,28 +967,28 @@ std::list<TNameAndType> DriverMED_R_SMESHDS_Mesh::GetGroupNamesAndTypes()
 
 void DriverMED_R_SMESHDS_Mesh::GetGroup(SMESHDS_Group* theGroup)
 {
-  std::string aGroupName (theGroup->GetStoreName());
+  string aGroupName (theGroup->GetStoreName());
   if(MYDEBUG) MESSAGE("Get Group " << aGroupName);
 
-  std::map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
+  map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
   for (; aFamsIter != myFamilies.end(); aFamsIter++)
   {
     DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
-    if (aFamily->GetType() == theGroup->GetType() && aFamily->MemberOf(aGroupName))
+    if (aFamily->GetTypes().count( theGroup->GetType() ) && aFamily->MemberOf(aGroupName))
     {
-      const std::set<const SMDS_MeshElement *>& anElements = aFamily->GetElements();
-      std::set<const SMDS_MeshElement *>::const_iterator anElemsIter = anElements.begin();
-      const SMDS_MeshElement * element = 0;
+      const set<const SMDS_MeshElement *>& anElements = aFamily->GetElements();
+      set<const SMDS_MeshElement *>::const_iterator anElemsIter = anElements.begin();
       for (; anElemsIter != anElements.end(); anElemsIter++)
       {
-        element = *anElemsIter;
-       theGroup->SMDSGroup().Add(element);
-       int aGroupAttrVal = aFamily->GetGroupAttributVal();
-       if( aGroupAttrVal != 0)
-         theGroup->SetColorGroup(aGroupAttrVal);
+        const SMDS_MeshElement * element = *anElemsIter;
+        if ( element->GetType() == theGroup->GetType() ) // Issue 0020576
+          theGroup->SMDSGroup().Add(element);
       }
-      if ( element )
-        theGroup->SetType( theGroup->SMDSGroup().GetType() );
+      int aGroupAttrVal = aFamily->GetGroupAttributVal();
+      if( aGroupAttrVal != 0)
+        theGroup->SetColorGroup(aGroupAttrVal);
+//       if ( element ) -- Issue 0020576
+//         theGroup->SetType( theGroup->SMDSGroup().GetType() );
     }
   }
 }
@@ -816,15 +998,15 @@ void DriverMED_R_SMESHDS_Mesh::GetSubMesh (SMESHDS_SubMesh* theSubMesh,
 {
   char submeshGrpName[ 30 ];
   sprintf( submeshGrpName, "SubMesh %d", theId );
-  std::string aName (submeshGrpName);
-  std::map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
+  string aName (submeshGrpName);
+  map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
   for (; aFamsIter != myFamilies.end(); aFamsIter++)
   {
     DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
     if (aFamily->MemberOf(aName))
     {
-      const std::set<const SMDS_MeshElement *>& anElements = aFamily->GetElements();
-      std::set<const SMDS_MeshElement *>::const_iterator anElemsIter = anElements.begin();
+      const set<const SMDS_MeshElement *>& anElements = aFamily->GetElements();
+      set<const SMDS_MeshElement *>::const_iterator anElemsIter = anElements.begin();
       if (aFamily->GetType() == SMDSAbs_Node)
       {
         for (; anElemsIter != anElements.end(); anElemsIter++)
@@ -846,21 +1028,21 @@ void DriverMED_R_SMESHDS_Mesh::GetSubMesh (SMESHDS_SubMesh* theSubMesh,
 
 void DriverMED_R_SMESHDS_Mesh::CreateAllSubMeshes ()
 {
-  std::map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
+  map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
   for (; aFamsIter != myFamilies.end(); aFamsIter++)
   {
     DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
     MED::TStringSet aGroupNames = aFamily->GetGroupNames();
-    std::set<std::string>::iterator aGrNamesIter = aGroupNames.begin();
+    set<string>::iterator aGrNamesIter = aGroupNames.begin();
     for (; aGrNamesIter != aGroupNames.end(); aGrNamesIter++)
     {
-      std::string aName = *aGrNamesIter;
+      string aName = *aGrNamesIter;
       // Check, if this is a Group or SubMesh name
-      if (aName.substr(0, 7) == std::string("SubMesh"))
+      if (aName.substr(0, 7) == string("SubMesh"))
       {
-        int Id = atoi(std::string(aName).substr(7).c_str());
-        std::set<const SMDS_MeshElement *> anElements = aFamily->GetElements();
-        std::set<const SMDS_MeshElement *>::iterator anElemsIter = anElements.begin();
+        int Id = atoi(string(aName).substr(7).c_str());
+        set<const SMDS_MeshElement *> anElements = aFamily->GetElements();
+        set<const SMDS_MeshElement *>::iterator anElemsIter = anElements.begin();
         if (aFamily->GetType() == SMDSAbs_Node)
         {
           for (; anElemsIter != anElements.end(); anElemsIter++)
@@ -902,7 +1084,7 @@ void DriverMED_R_SMESHDS_Mesh::CreateAllSubMeshes ()
 bool DriverMED_R_SMESHDS_Mesh::checkFamilyID(DriverMED_FamilyPtr & aFamily, int anID) const
 {
   if ( !aFamily || aFamily->GetId() != anID ) {
-    std::map<int, DriverMED_FamilyPtr>::const_iterator i_fam = myFamilies.find(anID);
+    map<int, DriverMED_FamilyPtr>::const_iterator i_fam = myFamilies.find(anID);
     if ( i_fam == myFamilies.end() )
       return false;
     aFamily = i_fam->second;
@@ -917,7 +1099,7 @@ bool DriverMED_R_SMESHDS_Mesh::checkFamilyID(DriverMED_FamilyPtr & aFamily, int
  * \return TRUE, if successfully. Else FALSE
  */
 bool DriverMED_R_SMESHDS_Mesh::buildMeshGrille(const MED::PWrapper& theWrapper,
-                                              const MED::PMeshInfo& theMeshInfo)
+                                               const MED::PMeshInfo& theMeshInfo)
 {
   bool res = true;
 
@@ -932,15 +1114,18 @@ bool DriverMED_R_SMESHDS_Mesh::buildMeshGrille(const MED::PWrapper& theWrapper,
     MED::TNodeCoord aMEDNodeCoord = aGrilleInfo->GetCoord(iNode);
     for(MED::TInt iDim=0;iDim<aMeshDim;iDim++)
       aCoords[(int)iDim] = aMEDNodeCoord[(int)iDim];
-    aNode = myMesh->AddNodeWithID(aCoords[0],aCoords[1],aCoords[2],(int)iNode);
+    aNode = myMesh->AddNodeWithID(aCoords[0],aCoords[1],aCoords[2],iNode+1);
+    if (!aNode) {
+      EXCEPTION(runtime_error,"buildMeshGrille Error. Node not created! "<<(int)iNode);
+    }
 
     if((aGrilleInfo->myFamNumNode).size() > 0){
       TInt aFamNum = aGrilleInfo->GetFamNumNode(iNode);
       if ( checkFamilyID ( aFamily, aFamNum ))
-       {
-         aFamily->AddElement(aNode);
-         aFamily->SetType(SMDSAbs_Node);
-       }
+        {
+          aFamily->AddElement(aNode);
+          aFamily->SetType(SMDSAbs_Node);
+        }
     }
     
   }
@@ -952,48 +1137,50 @@ bool DriverMED_R_SMESHDS_Mesh::buildMeshGrille(const MED::PWrapper& theWrapper,
     switch(aGrilleInfo->GetGeom()){
     case MED::eSEG2:
       if(aNodeIds.size() != 2){
-       res = false;
-       EXCEPTION(std::runtime_error,"buildMeshGrille Error. Incorrect size of ids 2!="<<aNodeIds.size());
+        res = false;
+        EXCEPTION(runtime_error,"buildMeshGrille Error. Incorrect size of ids 2!="<<aNodeIds.size());
       }
-      anElement = myMesh->AddEdgeWithID(aNodeIds[0],
-                                       aNodeIds[1],
-                                       iCell);
+      anElement = myMesh->AddEdgeWithID(aNodeIds[0]+1,
+                                        aNodeIds[1]+1,
+                                        iCell+1);
       break;
     case MED::eQUAD4:
       if(aNodeIds.size() != 4){
-       res = false;
-       EXCEPTION(std::runtime_error,"buildMeshGrille Error. Incorrect size of ids 4!="<<aNodeIds.size());
+        res = false;
+        EXCEPTION(runtime_error,"buildMeshGrille Error. Incorrect size of ids 4!="<<aNodeIds.size());
       }
-      anElement = myMesh->AddFaceWithID(aNodeIds[0],
-                                       aNodeIds[2],
-                                       aNodeIds[3],
-                                       aNodeIds[1],
-                                       iCell);
+      anElement = myMesh->AddFaceWithID(aNodeIds[0]+1,
+                                        aNodeIds[2]+1,
+                                        aNodeIds[3]+1,
+                                        aNodeIds[1]+1,
+                                        iCell+1);
       break;
     case MED::eHEXA8:
       if(aNodeIds.size() != 8){
-       res = false;
-       EXCEPTION(std::runtime_error,"buildMeshGrille Error. Incorrect size of ids 8!="<<aNodeIds.size());
+        res = false;
+        EXCEPTION(runtime_error,"buildMeshGrille Error. Incorrect size of ids 8!="<<aNodeIds.size());
       }
-      anElement = myMesh->AddVolumeWithID(aNodeIds[0],
-                                         aNodeIds[2],
-                                         aNodeIds[3],
-                                         aNodeIds[1],
-                                         aNodeIds[4],
-                                         aNodeIds[6],
-                                         aNodeIds[7],
-                                         aNodeIds[5],
-                                         iCell);
+      anElement = myMesh->AddVolumeWithID(aNodeIds[0]+1,
+                                          aNodeIds[2]+1,
+                                          aNodeIds[3]+1,
+                                          aNodeIds[1]+1,
+                                          aNodeIds[4]+1,
+                                          aNodeIds[6]+1,
+                                          aNodeIds[7]+1,
+                                          aNodeIds[5]+1,
+                                          iCell+1);
       break;
     default:
       break;
     }
-    
+    if (!anElement) {
+      EXCEPTION(runtime_error,"buildMeshGrille Error. Element not created! "<<iCell);
+    }
     if((aGrilleInfo->myFamNum).size() > 0){
       TInt aFamNum = aGrilleInfo->GetFamNum(iCell);
       if ( checkFamilyID ( aFamily, aFamNum )){
-       aFamily->AddElement(anElement);
-       aFamily->SetType(anElement->GetType());
+        aFamily->AddElement(anElement);
+        aFamily->SetType(anElement->GetType());
       }
     }
   }
index 2ccaa3f3d7625b8188a5d8f6f82bc5e8c4e20321..9d27ae20db6e38c85a7ba205f6a6f0135964ab18 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH DriverMED : driver to read and write 'med' files
 //  File   : DriverMED_R_SMESHDS_Mesh.h
 //  Module : SMESH
@@ -62,7 +63,7 @@ class MESHDRIVERMED_EXPORT DriverMED_R_SMESHDS_Mesh: public Driver_SMESHDS_Mesh
   bool checkFamilyID(DriverMED_FamilyPtr & aFamily, int anID) const;
 
   bool buildMeshGrille(const MED::PWrapper& theWrapper,
-                      const MED::PMeshInfo& theMeshInfo);
+                       const MED::PMeshInfo& theMeshInfo);
 
  private:
   std::string myMeshName;
diff --git a/src/DriverMED/DriverMED_W_SMDS_Mesh.cxx b/src/DriverMED/DriverMED_W_SMDS_Mesh.cxx
deleted file mode 100644 (file)
index 4669cf0..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-#include "DriverMED_W_SMDS_Mesh.h"
diff --git a/src/DriverMED/DriverMED_W_SMDS_Mesh.h b/src/DriverMED/DriverMED_W_SMDS_Mesh.h
deleted file mode 100644 (file)
index da1f9b3..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-#ifndef _INCLUDE_DRIVERMED_W_SMDS_MESH
-#define _INCLUDE_DRIVERMED_W_SMDS_MESH
-
-#include "SMESH_DriverMED.hxx"
-
-#include "Driver_SMDS_Mesh.h"
-
-class MESHDRIVERMED_EXPORT DriverMED_W_SMDS_Mesh: public Driver_SMDS_Mesh
-{};
-
-#endif
diff --git a/src/DriverMED/DriverMED_W_SMESHDS_Document.cxx b/src/DriverMED/DriverMED_W_SMESHDS_Document.cxx
deleted file mode 100644 (file)
index ac4ba94..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-//  SMESH DriverMED : driver to read and write 'med' files
-//  File   : DriverMED_W_SMESHDS_Document.cxx
-//  Module : SMESH
-//
-#include "DriverMED_W_SMESHDS_Document.h"
diff --git a/src/DriverMED/DriverMED_W_SMESHDS_Document.h b/src/DriverMED/DriverMED_W_SMESHDS_Document.h
deleted file mode 100644 (file)
index 95764fd..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-#ifndef _INCLUDE_DRIVERMED_W_SMESHDS_DOCUMENT
-#define _INCLUDE_DRIVERMED_W_SMESHDS_DOCUMENT
-
-#include "SMESH_DriverMED.hxx"
-
-#include "Driver_Document.h"
-
-class MESHDRIVERMED_EXPORT DriverMED_W_SMESHDS_Document : public Driver_Document 
-{};
-
-#endif
index 9f8e9c06cee7d341826425543431413b1133869b..39b03f2d619cd4435c71d253ee0d0967f0ebc71f 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH DriverMED : driver to read and write 'med' files
 //  File   : DriverMED_W_SMESHDS_Mesh.cxx
 //  Module : SMESH
@@ -26,7 +27,6 @@
 #include <sstream>
 
 #include "DriverMED_W_SMESHDS_Mesh.h"
-#include "DriverMED_W_SMDS_Mesh.h"
 #include "DriverMED_Family.h"
 
 #include "SMESHDS_Mesh.hxx"
@@ -54,7 +54,7 @@ DriverMED_W_SMESHDS_Mesh::DriverMED_W_SMESHDS_Mesh():
 {}
 
 void DriverMED_W_SMESHDS_Mesh::SetFile(const std::string& theFileName, 
-                                      MED::EVersion theId)
+                                       MED::EVersion theId)
 {
   myMed = CrWrapper(theFileName,theId);
   Driver_SMESHDS_Mesh::SetFile(theFileName);
@@ -69,9 +69,9 @@ string DriverMED_W_SMESHDS_Mesh::GetVersionString(const MED::EVersion theVersion
 {
   TInt majeur, mineur, release;
   majeur =  mineur = release = 0;
-  if ( theVersion == eV2_1 )
-    MED::GetVersionRelease<eV2_1>(majeur, mineur, release);
-  else
+//   if ( theVersion == eV2_1 )
+//     MED::GetVersionRelease<eV2_1>(majeur, mineur, release);
+//   else
     MED::GetVersionRelease<eV2_2>(majeur, mineur, release);
   ostringstream name;
   if ( theNbDigits > 0 )
@@ -83,11 +83,6 @@ string DriverMED_W_SMESHDS_Mesh::GetVersionString(const MED::EVersion theVersion
   return name.str();
 }
 
-void DriverMED_W_SMESHDS_Mesh::SetMeshName(const std::string& theMeshName)
-{
-  myMeshName = theMeshName;
-}
-
 void DriverMED_W_SMESHDS_Mesh::AddGroup(SMESHDS_GroupBase* theGroup)
 {
   myGroups.push_back(theGroup);
@@ -189,9 +184,9 @@ namespace{
     TUnit* myUnit;
   public:
     TCoordHelper(const SMDS_NodeIteratorPtr& theNodeIter,
-                TGetCoord* theGetCoord,
-                TName* theName,
-                TUnit* theUnit = aUnit):
+                 TGetCoord* theGetCoord,
+                 TName* theName,
+                 TUnit* theUnit = aUnit):
       myNodeIter(theNodeIter),
       myGetCoord(theGetCoord),
       myName(theName),
@@ -200,7 +195,7 @@ namespace{
     virtual ~TCoordHelper(){}
     bool Next(){ 
       return myNodeIter->more() && 
-       (myCurrentNode = myNodeIter->next());
+        (myCurrentNode = myNodeIter->next());
     }
     const SMDS_MeshNode* GetNode(){
       return myCurrentNode;
@@ -220,34 +215,6 @@ namespace{
   };
   typedef boost::shared_ptr<TCoordHelper> TCoordHelperPtr;
 
-
-  //-------------------------------------------------------
-  /*!
-   * \brief Class helping to use either SMDS_EdgeIterator, SMDS_FaceIterator
-   * or SMDS_VolumeIterator in the same code
-   */
-  //-------------------------------------------------------
-  struct TElemIterator
-  {
-    virtual const SMDS_MeshElement* next() = 0;
-    virtual ~TElemIterator() {}
-  };
-  typedef boost::shared_ptr<TElemIterator> PElemIterator;
-
-  template< class SMDSIteratorPtr > class TypedElemIterator: public TElemIterator
-  {
-    SMDSIteratorPtr myItPtr;
-  public:
-    TypedElemIterator(SMDSIteratorPtr it): myItPtr(it) {}
-    virtual const SMDS_MeshElement* next() {
-      if ( myItPtr->more() ) return myItPtr->next();
-      else                   return 0;
-    }
-  };
-  typedef TypedElemIterator< SMDS_EdgeIteratorPtr > TEdgeIterator;
-  typedef TypedElemIterator< SMDS_FaceIteratorPtr > TFaceIterator;
-  typedef TypedElemIterator< SMDS_VolumeIteratorPtr > TVolumeIterator;
-
   //-------------------------------------------------------
   /*!
    * \brief Structure describing element type
@@ -266,7 +233,6 @@ namespace{
 
 
   typedef NCollection_DataMap< Standard_Address, int > TElemFamilyMap;
-  //typedef map<const SMDS_MeshElement *, int> TElemFamilyMap;
 
   //================================================================================
   /*!
@@ -343,100 +309,109 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
     }
 
     // Mesh dimension definition
-    TInt aMeshDimension;
+    TInt aSpaceDimension;
     TCoordHelperPtr aCoordHelperPtr;
-    {  
+    {
       bool anIsXDimension = false;
       bool anIsYDimension = false;
       bool anIsZDimension = false;
       {
-       SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator();
-       double aBounds[6];
-       if(aNodesIter->more()){
-         const SMDS_MeshNode* aNode = aNodesIter->next();
-         aBounds[0] = aBounds[1] = aNode->X();
-         aBounds[2] = aBounds[3] = aNode->Y();
-         aBounds[4] = aBounds[5] = aNode->Z();
-       }
-       while(aNodesIter->more()){
-         const SMDS_MeshNode* aNode = aNodesIter->next();
-         aBounds[0] = min(aBounds[0],aNode->X());
-         aBounds[1] = max(aBounds[1],aNode->X());
-         
-         aBounds[2] = min(aBounds[2],aNode->Y());
-         aBounds[3] = max(aBounds[3],aNode->Y());
-         
-         aBounds[4] = min(aBounds[4],aNode->Z());
-         aBounds[5] = max(aBounds[5],aNode->Z());
-       }
-
-       double EPS = 1.0E-7;
-       anIsXDimension = (aBounds[1] - aBounds[0]) + abs(aBounds[1]) + abs(aBounds[0]) > EPS;
-       anIsYDimension = (aBounds[3] - aBounds[2]) + abs(aBounds[3]) + abs(aBounds[2]) > EPS;
-       anIsZDimension = (aBounds[5] - aBounds[4]) + abs(aBounds[5]) + abs(aBounds[4]) > EPS;
-       aMeshDimension = anIsXDimension + anIsYDimension + anIsZDimension;
-       if(!aMeshDimension)
-         aMeshDimension = 3;
+        SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator();
+        double aBounds[6];
+        if(aNodesIter->more()){
+          const SMDS_MeshNode* aNode = aNodesIter->next();
+          aBounds[0] = aBounds[1] = aNode->X();
+          aBounds[2] = aBounds[3] = aNode->Y();
+          aBounds[4] = aBounds[5] = aNode->Z();
+        }
+        while(aNodesIter->more()){
+          const SMDS_MeshNode* aNode = aNodesIter->next();
+          aBounds[0] = min(aBounds[0],aNode->X());
+          aBounds[1] = max(aBounds[1],aNode->X());
+          
+          aBounds[2] = min(aBounds[2],aNode->Y());
+          aBounds[3] = max(aBounds[3],aNode->Y());
+          
+          aBounds[4] = min(aBounds[4],aNode->Z());
+          aBounds[5] = max(aBounds[5],aNode->Z());
+        }
+
+        double EPS = 1.0E-7;
+        anIsXDimension = (aBounds[1] - aBounds[0]) + abs(aBounds[1]) + abs(aBounds[0]) > EPS;
+        anIsYDimension = (aBounds[3] - aBounds[2]) + abs(aBounds[3]) + abs(aBounds[2]) > EPS;
+        anIsZDimension = (aBounds[5] - aBounds[4]) + abs(aBounds[5]) + abs(aBounds[4]) > EPS;
+        aSpaceDimension = anIsXDimension + anIsYDimension + anIsZDimension;
+        if(!aSpaceDimension)
+          aSpaceDimension = 3;
         // PAL16857(SMESH not conform to the MED convention):
-        if ( aMeshDimension == 2 && anIsZDimension ) // 2D only if mesh is in XOY plane
-          aMeshDimension = 3;
+        if ( aSpaceDimension == 2 && anIsZDimension ) // 2D only if mesh is in XOY plane
+          aSpaceDimension = 3;
         // PAL18941(a saved study with a mesh belong Z is opened and the mesh is belong X)
-        if ( aMeshDimension == 1 && !anIsXDimension ) // 1D only if mesh is along OX
+        if ( aSpaceDimension == 1 && !anIsXDimension ) {// 1D only if mesh is along OX
           if ( anIsYDimension ) {
-            aMeshDimension = 2;
+            aSpaceDimension = 2;
             anIsXDimension = true;
           } else {
-            aMeshDimension = 3;
+            aSpaceDimension = 3;
           }
+        }
       }
 
-      SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator();
-      switch(aMeshDimension){
+      SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator(/*idInceasingOrder=*/true);
+      switch(aSpaceDimension){
       case 3:
-       aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXYZGetCoord,aXYZName));
-       break;
+        aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXYZGetCoord,aXYZName));
+        break;
       case 2:
-       if(anIsXDimension && anIsYDimension)
-         aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXYGetCoord,aXYName));
-       if(anIsYDimension && anIsZDimension)
-         aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aYZGetCoord,aYZName));
-       if(anIsXDimension && anIsZDimension)
-         aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXZGetCoord,aXZName));
-       break;
+        if(anIsXDimension && anIsYDimension)
+          aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXYGetCoord,aXYName));
+        if(anIsYDimension && anIsZDimension)
+          aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aYZGetCoord,aYZName));
+        if(anIsXDimension && anIsZDimension)
+          aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXZGetCoord,aXZName));
+        break;
       case 1:
-       if(anIsXDimension)
-         aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXGetCoord,aXName));
-       if(anIsYDimension)
-         aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aYGetCoord,aYName));
-       if(anIsZDimension)
-         aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aZGetCoord,aZName));
-       break;
+        if(anIsXDimension)
+          aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXGetCoord,aXName));
+        if(anIsYDimension)
+          aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aYGetCoord,aYName));
+        if(anIsZDimension)
+          aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aZGetCoord,aZName));
+        break;
       }
     }
-
+    TInt aMeshDimension = 0;
+    if ( myMesh->NbEdges() > 0 )
+      aMeshDimension = 1;
+    if ( myMesh->NbFaces() > 0 )
+      aMeshDimension = 2;
+    if ( myMesh->NbVolumes() > 0 )
+      aMeshDimension = 3;
     
-    PMeshInfo aMeshInfo = myMed->CrMeshInfo(aMeshDimension,aMeshName);
+    PMeshInfo aMeshInfo = myMed->CrMeshInfo(aMeshDimension,aSpaceDimension,aMeshName);
     MESSAGE("Add - aMeshName : "<<aMeshName<<"; "<<aMeshInfo->GetName());
     myMed->SetMeshInfo(aMeshInfo);
 
     // Storing SMDS groups and sub-meshes as med families
     //----------------------------------------------------
-    int myNodesDefaultFamilyId   = 0;
-    int myEdgesDefaultFamilyId   = 0;
-    int myFacesDefaultFamilyId   = 0;
-    int myVolumesDefaultFamilyId = 0;
-    int nbNodes   = myMesh->NbNodes();
-    int nbEdges   = myMesh->NbEdges();
-    int nbFaces   = myMesh->NbFaces();
-    int nbVolumes = myMesh->NbVolumes();
-    if (myDoGroupOfNodes && nbNodes)
-      myNodesDefaultFamilyId = REST_NODES_FAMILY;
-    if (myDoGroupOfEdges && nbEdges)
-      myEdgesDefaultFamilyId = REST_EDGES_FAMILY;
-    if (myDoGroupOfFaces && nbFaces)
-      myFacesDefaultFamilyId = REST_FACES_FAMILY;
-    if (myDoGroupOfVolumes && nbVolumes)
-      myVolumesDefaultFamilyId = REST_VOLUMES_FAMILY;
+    int myNodesDefaultFamilyId      = 0;
+    int my0DElementsDefaultFamilyId = 0;
+    int myBallsDefaultFamilyId      = 0;
+    int myEdgesDefaultFamilyId      = 0;
+    int myFacesDefaultFamilyId      = 0;
+    int myVolumesDefaultFamilyId    = 0;
+    int nbNodes      = myMesh->NbNodes();
+    int nb0DElements = myMesh->Nb0DElements();
+    int nbBalls      = myMesh->NbBalls();
+    int nbEdges      = myMesh->NbEdges();
+    int nbFaces      = myMesh->NbFaces();
+    int nbVolumes    = myMesh->NbVolumes();
+    if (myDoGroupOfNodes && nbNodes) myNodesDefaultFamilyId = REST_NODES_FAMILY;
+    if (myDoGroupOfEdges && nbEdges) myEdgesDefaultFamilyId = REST_EDGES_FAMILY;
+    if (myDoGroupOfFaces && nbFaces) myFacesDefaultFamilyId = REST_FACES_FAMILY;
+    if (myDoGroupOfVolumes && nbVolumes) myVolumesDefaultFamilyId = REST_VOLUMES_FAMILY;
+    if (myDoGroupOf0DElems && nb0DElements) my0DElementsDefaultFamilyId = REST_0DELEM_FAMILY;
+    if (myDoGroupOfVolumes && nbVolumes) myBallsDefaultFamilyId = REST_BALL_FAMILY;
 
     MESSAGE("Perform - aFamilyInfo");
     //cout << " DriverMED_Family::MakeFamilies() " << endl;
@@ -447,14 +422,18 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
          myDoGroupOfNodes   && nbNodes,
          myDoGroupOfEdges   && nbEdges,
          myDoGroupOfFaces   && nbFaces,
-         myDoGroupOfVolumes && nbVolumes);
+         myDoGroupOfVolumes && nbVolumes,
+         myDoGroupOf0DElems && nb0DElements,
+         myDoGroupOfBalls   && nbBalls);
     } else {
       aFamilies = DriverMED_Family::MakeFamilies
         (mySubMeshes, myGroups,
          myDoGroupOfNodes   && nbNodes,
          myDoGroupOfEdges   && nbEdges,
          myDoGroupOfFaces   && nbFaces,
-         myDoGroupOfVolumes && nbVolumes);
+         myDoGroupOfVolumes && nbVolumes,
+         myDoGroupOf0DElems && nb0DElements,
+         myDoGroupOfBalls   && nbBalls);
     }
     //cout << " myMed->SetFamilyInfo() " << endl;
     list<DriverMED_FamilyPtr>::iterator aFamsIter;
@@ -490,8 +469,8 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
     {
       // coordinates
       TCoordSlice aTCoordSlice = aNodeInfo->GetCoordSlice( iNode );
-      for(TInt iCoord = 0; iCoord < aMeshDimension; iCoord++){
-       aTCoordSlice[iCoord] = aCoordHelperPtr->GetCoord(iCoord);
+      for(TInt iCoord = 0; iCoord < aSpaceDimension; iCoord++){
+        aTCoordSlice[iCoord] = aCoordHelperPtr->GetCoord(iCoord);
       }
       // node number
       int aNodeID = aCoordHelperPtr->GetID();
@@ -507,7 +486,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
     anElemFamMap.Clear();
 
     // coordinate names and units
-    for (TInt iCoord = 0; iCoord < aMeshDimension; iCoord++) {
+    for (TInt iCoord = 0; iCoord < aSpaceDimension; iCoord++) {
       aNodeInfo->SetCoordName( iCoord, aCoordHelperPtr->GetName(iCoord));
       aNodeInfo->SetCoordUnit( iCoord, aCoordHelperPtr->GetUnit(iCoord));
     }
@@ -533,6 +512,20 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
     list< TElemTypeData > aTElemTypeDatas;
 
     EEntiteMaillage anEntity = eMAILLE;
+#ifdef _ELEMENTS_BY_DIM_
+    anEntity = eNOEUD_ELEMENT;
+#endif
+    aTElemTypeDatas.push_back(TElemTypeData(anEntity,
+                                            ePOINT1,
+                                            nbElemInfo.Nb0DElements(),
+                                            SMDSAbs_0DElement));
+#ifdef _ELEMENTS_BY_DIM_
+    anEntity = eSTRUCT_ELEMENT;
+#endif
+    aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+                                             eBALL,
+                                             nbElemInfo.NbBalls(),
+                                             SMDSAbs_Ball));
 #ifdef _ELEMENTS_BY_DIM_
     anEntity = eARETE;
 #endif
@@ -560,9 +553,14 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
                                             nbElemInfo.NbQuadrangles( ORDER_LINEAR ),
                                             SMDSAbs_Face));
     aTElemTypeDatas.push_back( TElemTypeData(anEntity,
-                                            eQUAD8,
-                                            nbElemInfo.NbQuadrangles( ORDER_QUADRATIC ),
-                                            SMDSAbs_Face));
+                                             eQUAD8,
+                                             nbElemInfo.NbQuadrangles( ORDER_QUADRATIC ) -
+                                             nbElemInfo.NbBiQuadQuadrangles(),
+                                             SMDSAbs_Face));
+    aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+                                             eQUAD9,
+                                             nbElemInfo.NbBiQuadQuadrangles(),
+                                             SMDSAbs_Face));
     if ( polyTypesSupported ) {
       aTElemTypeDatas.push_back( TElemTypeData(anEntity,
                                                ePOLYGONE,
@@ -607,7 +605,16 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
                                              SMDSAbs_Volume));
     aTElemTypeDatas.push_back( TElemTypeData(anEntity,
                                              eHEXA20,
-                                             nbElemInfo.NbHexas( ORDER_QUADRATIC ),
+                                             nbElemInfo.NbHexas( ORDER_QUADRATIC )-
+                                             nbElemInfo.NbTriQuadHexas(),
+                                             SMDSAbs_Volume));
+    aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+                                             eHEXA27,
+                                             nbElemInfo.NbTriQuadHexas(),
+                                             SMDSAbs_Volume));
+    aTElemTypeDatas.push_back( TElemTypeData(anEntity,
+                                             eOCTA12,
+                                             nbElemInfo.NbHexPrisms(),
                                              SMDSAbs_Volume));
     if ( polyTypesSupported ) {
       aTElemTypeDatas.push_back( TElemTypeData(anEntity,
@@ -631,40 +638,43 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
       if ( aElemTypeData->_nbElems == 0 )
         continue;
 
-      // iterator on elements of a current type
-      PElemIterator elemIterator;
       int defaultFamilyId = 0;
       switch ( aElemTypeData->_smdsType ) {
+      case SMDSAbs_0DElement:
+        defaultFamilyId = my0DElementsDefaultFamilyId;
+        break;
+      case SMDSAbs_Ball:
+        defaultFamilyId = myBallsDefaultFamilyId;
+        break;
       case SMDSAbs_Edge:
-        elemIterator = PElemIterator( new TEdgeIterator( myMesh->edgesIterator() ));
         defaultFamilyId = myEdgesDefaultFamilyId;
         break;
       case SMDSAbs_Face:
-        elemIterator = PElemIterator( new TFaceIterator( myMesh->facesIterator() ));
         defaultFamilyId = myFacesDefaultFamilyId;
         break;
       case SMDSAbs_Volume:
-        elemIterator = PElemIterator( new TVolumeIterator( myMesh->volumesIterator() ));
         defaultFamilyId = myVolumesDefaultFamilyId;
         break;
       default:
         continue;
       }
+
+      // iterator on elements of a current type
+      SMDS_ElemIteratorPtr elemIterator;
       int iElem = 0;
 
-      //cout << " Treat type " << aElemTypeData->_geomType << " nb = " <<aElemTypeData->_nbElems<< endl;
       // Treat POLYGONs
       // ---------------
       if ( aElemTypeData->_geomType == ePOLYGONE )
       {
+        elemIterator = myMesh->elementGeomIterator( SMDSGeom_POLYGON );
         if ( nbPolygonNodes == 0 ) {
           // Count nb of nodes
-          while ( const SMDS_MeshElement* anElem = elemIterator->next() ) {
-            if ( anElem->IsPoly() ) {
-              nbPolygonNodes += anElem->NbNodes();
-              if ( ++iElem == aElemTypeData->_nbElems )
-                break;
-            }
+          while ( elemIterator->more() ) {
+            const SMDS_MeshElement* anElem = elemIterator->next();
+            nbPolygonNodes += anElem->NbNodes();
+            if ( ++iElem == aElemTypeData->_nbElems )
+              break;
           }
         }
         else {
@@ -679,11 +689,9 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
           TElemNum & index = *(aPolygoneInfo->myIndex.get());
           index[0] = 1;
 
-          while ( const SMDS_MeshElement* anElem = elemIterator->next() )
+          while ( elemIterator->more() )
           {
-            if ( !anElem->IsPoly() )
-              continue;
-
+            const SMDS_MeshElement* anElem = elemIterator->next();
             // index
             TInt aNbNodes = anElem->NbNodes();
             index[ iElem+1 ] = index[ iElem ] + aNbNodes;
@@ -708,11 +716,6 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
             if ( ++iElem == aPolygoneInfo->GetNbElem() )
               break;
           }
-          //       if(TInt aNbElems = aPolygoneElemNums.size())
-          //         // add one element in connectivities,
-          //         // referenced by the last element in indices
-          //         aPolygoneConn.push_back(0);
-          //cout << " SetPolygoneInfo(aPolygoneInfo)" << endl;
           myMed->SetPolygoneInfo(aPolygoneInfo);
         }
 
@@ -722,17 +725,18 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
       // ----------------
       else if (aElemTypeData->_geomType == ePOLYEDRE )
       {
+        elemIterator = myMesh->elementGeomIterator( SMDSGeom_POLYHEDRA );
+        
         if ( nbPolyhedronNodes == 0 ) {
           // Count nb of nodes
-          while ( const SMDS_MeshElement* anElem = elemIterator->next() ) {
-            const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
-              dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>( anElem );
-            if ( aPolyedre ) {
-              nbPolyhedronNodes += aPolyedre->NbNodes();
-              nbPolyhedronFaces += aPolyedre->NbFaces();
-              if ( ++iElem == aElemTypeData->_nbElems )
-                break;
-            }
+          while ( elemIterator->more() ) {
+            const SMDS_MeshElement* anElem = elemIterator->next();
+            const SMDS_VtkVolume *aPolyedre = dynamic_cast<const SMDS_VtkVolume*>(anElem);
+            if ( !aPolyedre ) continue;
+            nbPolyhedronNodes += aPolyedre->NbNodes();
+            nbPolyhedronFaces += aPolyedre->NbFaces();
+            if ( ++iElem == aElemTypeData->_nbElems )
+              break;
           }
         }
         else {
@@ -753,13 +757,11 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
           faces[0] = 1;
 
           TInt iFace = 0, iNode = 0;
-          while ( const SMDS_MeshElement* anElem = elemIterator->next() )
+          while ( elemIterator->more() )
           {
-            const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
-              dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>( anElem );
-            if ( !aPolyedre )
-              continue;
-
+            const SMDS_MeshElement* anElem = elemIterator->next();
+            const SMDS_VtkVolume *aPolyedre = dynamic_cast<const SMDS_VtkVolume*>(anElem);
+            if ( !aPolyedre ) continue;
             // index
             TInt aNbFaces = aPolyedre->NbFaces();
             index[ iElem+1 ] = index[ iElem ] + aNbFaces;
@@ -790,11 +792,52 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
             if ( ++iElem == aPolyhInfo->GetNbElem() )
               break;
           }
-          //cout << " SetPolyedreInfo(aPolyhInfo )" << endl;
           myMed->SetPolyedreInfo(aPolyhInfo);
         }
       } // if (aElemTypeData->_geomType == ePOLYEDRE )
 
+      // Treat BALLs
+      // ----------------
+      else if (aElemTypeData->_geomType == eBALL )
+      {
+        // allocate data arrays
+        PBallInfo aBallInfo = myMed->CrBallInfo( aMeshInfo,
+                                                 aElemTypeData->_nbElems );
+
+        // build map of family numbers for this type
+        if ( !isElemFamMapBuilt[ aElemTypeData->_smdsType ])
+        {
+          fillElemFamilyMap( anElemFamMap, aFamilies, aElemTypeData->_smdsType );
+          isElemFamMapBuilt[ aElemTypeData->_smdsType ] = true;
+        }
+
+        elemIterator = myMesh->elementsIterator( SMDSAbs_Ball );
+        while ( elemIterator->more() )
+        {
+          const SMDS_MeshElement* anElem = elemIterator->next();
+          // connectivity
+          const SMDS_MeshElement* aNode = anElem->GetNode( 0 );
+#ifdef _EDF_NODE_IDS_
+          (*aBallInfo->myConn)[ iElem ] = aNodeIdMap[aNode->GetID()];
+#else
+          (*aBallInfo->myConn)[ iElem ] = aNode->GetID();
+#endif
+          // element number
+          aBallInfo->SetElemNum( iElem, anElem->GetID() );
+
+          // diameter
+          aBallInfo->myDiameters[ iElem ] =
+            static_cast<const SMDS_BallElement*>( anElem )->GetDiameter();
+
+          // family number
+          int famNum = getFamilyId( anElemFamMap, anElem, defaultFamilyId );
+          aBallInfo->SetFamNum( iElem, famNum );
+          ++iElem;
+        }
+        // store data in a file
+        myMed->SetBallInfo(aBallInfo);
+      }
+
       else
       {
         // Treat standard types
@@ -817,8 +860,10 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
         }
 
         TInt aNbNodes = MED::GetNbNodes(aElemTypeData->_geomType);
-        while ( const SMDS_MeshElement* anElem = elemIterator->next() )
+        elemIterator = myMesh->elementsIterator( aElemTypeData->_smdsType );
+        while ( elemIterator->more() )
         {
+          const SMDS_MeshElement* anElem = elemIterator->next();
           if ( anElem->NbNodes() != aNbNodes || anElem->IsPoly() )
             continue; // other geometry
 
@@ -843,7 +888,6 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
             break;
         }
         // store data in a file
-        //cout << " SetCellInfo(aCellInfo)" << endl;
         myMed->SetCellInfo(aCellInfo);
       }
 
@@ -852,11 +896,11 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
 
   }
   catch(const std::exception& exc) {
-    INFOS("Follow exception was cought:\n\t"<<exc.what());
+    INFOS("The following exception was caught:\n\t"<<exc.what());
     throw;
   }
   catch(...) {
-    INFOS("Unknown exception was cought !!!");
+    INFOS("Unknown exception was caught !!!");
     throw;
   }
 
index 5b8287ef2bd3f5d9471a40336cd31661cdb10dc7..6b0f03138c3e44aa7edd1dc6e1bdc46a849b402f 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH DriverMED : driver to read and write 'med' files
 //  File   : DriverMED_W_SMESHDS_Mesh.h
 //  Module : SMESH
@@ -55,10 +56,11 @@ class MESHDRIVERMED_EXPORT DriverMED_W_SMESHDS_Mesh: public Driver_SMESHDS_Mesh
   void AddGroupOfEdges();
   void AddGroupOfFaces();
   void AddGroupOfVolumes();
+  void AddGroupOf0DElems();
+  void AddGroupOfBalls();
 
   /*! functions to prepare adding one mesh
    */
-  void SetMeshName(const std::string& theMeshName);
   void AddGroup(SMESHDS_GroupBase * theGroup);
   void AddAllSubMeshes();
   void AddSubMesh(SMESHDS_SubMesh* theSubMesh, int theID);
@@ -70,7 +72,6 @@ class MESHDRIVERMED_EXPORT DriverMED_W_SMESHDS_Mesh: public Driver_SMESHDS_Mesh
  private:
 
   MED::PWrapper myMed;
-  std::string myMeshName;
   std::list<SMESHDS_GroupBase*> myGroups;
   bool myAllSubMeshes;
   std::map<int,SMESHDS_SubMesh*> mySubMeshes;
@@ -78,6 +79,8 @@ class MESHDRIVERMED_EXPORT DriverMED_W_SMESHDS_Mesh: public Driver_SMESHDS_Mesh
   bool myDoGroupOfEdges;
   bool myDoGroupOfFaces;
   bool myDoGroupOfVolumes;
+  bool myDoGroupOf0DElems;
+  bool myDoGroupOfBalls;
 };
 
 
index edd86c556cfe8db2d0c922b94084047a05decb54..f94c0c027ac3456279ef5f77e257ced7a82a98c9 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #include "DriverMED_R_SMESHDS_Mesh.h"
 #include "DriverMED_W_SMESHDS_Mesh.h"
 
index 3207132f87c5308cfb3828cd56b7f184e66e7c99..898952af77ff2948b7bfdc21933b42eb1f692ac8 100644 (file)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  SMESH DriverMED : driver to read and write 'med' files
 #  File   : Makefile.in
 #  Author : Marc Tajchman (CEA)
@@ -30,23 +28,15 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am
 
 # header files 
 salomeinclude_HEADERS = \
-       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 \
        SMESH_DriverMED.hxx
 
 # Libraries targets
 lib_LTLIBRARIES = libMeshDriverMED.la
 dist_libMeshDriverMED_la_SOURCES = \
-       DriverMED_R_SMDS_Mesh.cxx \
        DriverMED_R_SMESHDS_Mesh.cxx \
-       DriverMED_R_SMESHDS_Document.cxx \
-       DriverMED_W_SMDS_Mesh.cxx \
-       DriverMED_W_SMESHDS_Document.cxx \
        DriverMED_W_SMESHDS_Mesh.cxx \
        DriverMED_Family.cxx
 
@@ -63,15 +53,16 @@ libMeshDriverMED_la_CPPFLAGS = \
        @HDF5_INCLUDES@ \
        $(KERNEL_CXXFLAGS) \
        $(CAS_CPPFLAGS) \
+        $(VTK_INCLUDES) \
        $(BOOST_CPPFLAGS) \
        -I$(srcdir)/../Driver \
        -I$(srcdir)/../SMDS \
-       -I$(srcdir)/../SMESHDS \
-       -I$(top_builddir)/salome_adm/unix
+       -I$(srcdir)/../SMESHDS
 
 libMeshDriverMED_la_LDFLAGS  = \
+       $(BOOST_LIBS) \
        ../Driver/libMeshDriver.la \
-       $(MED_LDFLAGS) -lMEDWrapper
+       $(MED_LDFLAGS) -lMEDWrapper -lMEDWrapperBase -lMEDWrapper_V2_2 -lMEDWrapper_V2_1
 
 
 MED_Test_CPPFLAGS = \
@@ -89,7 +80,6 @@ MED_Test_LDADD = \
        $(MED_LDFLAGS) \
        -lMEDWrapper \
        -lMEDWrapperBase \
-       -lMEDWrapper_V2_1 \
-       -lmed_V2_1 \
-       -lMEDWrapper_V2_2
+       -lMEDWrapper_V2_2 \
+       -lMEDWrapper_V2_1 
 
index 0042f9366de15d819dd2a85780f56bd99bd65ffa..92aed5cf5e4e8fa182cb6abf068990f12b95751d 100755 (executable)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  File   : SMESH_DriverMED.hxx
 //  Author : Alexander A. BORODIN
 //  Module : SMESH
@@ -27,7 +28,7 @@
 #define _SMESH_DriverMED_HXX_
 
 #ifdef WNT
- #if defined MESHDRIVERMED_EXPORTS
+ #if defined MESHDRIVERMED_EXPORTS || defined MeshDriverMED_EXPORTS
   #define MESHDRIVERMED_EXPORT __declspec( dllexport )
  #else
   #define MESHDRIVERMED_EXPORT __declspec( dllimport )
index bd01c08bf759c7296c8043b350ae74106ba79333..2687363db2af85b6a697870f5dbec728d56e99d0 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #include <stdio.h>
 #include <gp_Pnt.hxx>
 //=======================================================================
index c541daf1bd3eb15ebf35891927a719b7402f1a4e..86e5eaec6c3f7ec42d535c975d00d1bca9f9b840 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #ifndef _INCLUDE_DRIVERSTL_R_SMDS_MESH
 #define _INCLUDE_DRIVERSTL_R_SMDS_MESH
 
index 0f68b7583a11f47916976d69e59d58a451a5b764..e4e27004259164bd0051490ab9138ac52c490eed 100644 (file)
@@ -1,44 +1,49 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #include <stdio.h>
+#include <limits>
 
 #include "DriverSTL_W_SMDS_Mesh.h"
 
+#include "SMDS_FaceOfNodes.hxx"
+#include "SMDS_IteratorOnIterators.hxx"
 #include "SMDS_Mesh.hxx"
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
-#include <gp_XYZ.hxx>
-#include <OSD_Path.hxx>
+#include "SMDS_SetIterator.hxx"
+#include "SMDS_VolumeTool.hxx"
+#include "SMESH_TypeDefs.hxx"
+
 #include <OSD_File.hxx>
-#include <OSD_FromWhere.hxx>
+//#include <OSD_FromWhere.hxx>
+#include <OSD_Path.hxx>
 #include <OSD_Protection.hxx>
-#include <OSD_SingleProtection.hxx>
+//#include <OSD_SingleProtection.hxx>
 #include <TCollection_AsciiString.hxx>
-#include <TColgp_Array1OfXYZ.hxx>
+#include <gp_XYZ.hxx>
 
 #include "utilities.h"
 
-//using namespace std;
-
 // definition des constantes 
 static const int LABEL_SIZE = 80;
 
@@ -60,6 +65,7 @@ Driver_Mesh::Status DriverSTL_W_SMDS_Mesh::Perform()
     fprintf(stderr, ">> ERROR : Mesh is null \n");
     return DRS_FAIL;
   }
+  findVolumeTriangles();
   if ( myIsAscii )
     aResult = writeAscii();
   else
@@ -67,11 +73,73 @@ Driver_Mesh::Status DriverSTL_W_SMDS_Mesh::Perform()
 
   return aResult;
 }
+//================================================================================
+/*!
+ * \brief Destructor deletes temporary faces
+ */
+//================================================================================
+
+DriverSTL_W_SMDS_Mesh::~DriverSTL_W_SMDS_Mesh()
+{
+  for ( unsigned i = 0; i < myVolumeTrias.size(); ++i )
+    delete myVolumeTrias[i];
+}
+
+//================================================================================
+/*!
+ * \brief Finds free facets of volumes for which faces are missing in the mesh
+ */
+//================================================================================
+
+void DriverSTL_W_SMDS_Mesh::findVolumeTriangles()
+{
+  SMDS_VolumeTool myTool;
+  SMDS_VolumeIteratorPtr vIt = myMesh->volumesIterator();
+  while ( vIt->more() )
+  {
+    myTool.Set( vIt->next() );
+    for ( int iF = 0; iF < myTool.NbFaces(); ++iF )
+      if ( myTool.IsFreeFace( iF ))
+      {
+        const SMDS_MeshNode** n = myTool.GetFaceNodes(iF);
+        int                 nbN = myTool.NbFaceNodes(iF);
+        std::vector< const SMDS_MeshNode*> nodes( n, n+nbN );
+        if ( !myMesh->FindElement( nodes, SMDSAbs_Face, /*Nomedium=*/false))
+        {
+          int nbTria = nbN - 2;
+          for ( int iT = 0; iT < nbTria; ++iT )
+          {
+            myVolumeTrias.push_back( new SMDS_FaceOfNodes( n[0], n[1+iT], n[2+iT] ));
+          }
+        }
+      }
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Return iterator on both faces in the mesh and on temporary faces
+ */
+//================================================================================
+
+SMDS_ElemIteratorPtr DriverSTL_W_SMDS_Mesh::getFaces() const
+{
+  SMDS_ElemIteratorPtr facesIter = myMesh->elementsIterator(SMDSAbs_Face);
+  SMDS_ElemIteratorPtr tmpTriaIter( new SMDS_ElementVectorIterator( myVolumeTrias.begin(),
+                                                                    myVolumeTrias.end()));
+  typedef std::vector< SMDS_ElemIteratorPtr > TElemIterVector;
+  TElemIterVector iters(2);
+  iters[0] = facesIter;
+  iters[1] = tmpTriaIter;
+  
+  typedef SMDS_IteratorOnIterators<const SMDS_MeshElement *, TElemIterVector> TItersIter;
+  return SMDS_ElemIteratorPtr( new TItersIter( iters ));
+}
 
 // static methods
 
 static void writeInteger( const Standard_Integer& theVal,
-                        OSD_File& ofile )
+                         OSD_File& ofile )
 {
   union {
     Standard_Integer i;
@@ -90,7 +158,7 @@ static void writeInteger( const Standard_Integer& theVal,
 }
 
 static void writeFloat  ( const Standard_ShortReal& theVal,
-                        OSD_File& ofile)
+                         OSD_File& ofile)
 {
   union {
     Standard_ShortReal f;
@@ -109,35 +177,45 @@ static void writeFloat  ( const Standard_ShortReal& theVal,
   ofile.Write((char *)&entier,sizeof(u.c));
 }
 
-static gp_XYZ getNormale( const SMDS_MeshFace* theFace )
+static gp_XYZ getNormale( const SMDS_MeshNode* n1,
+                          const SMDS_MeshNode* n2,
+                          const SMDS_MeshNode* n3)
 {
-  gp_XYZ n;
-  int aNbNode = theFace->NbNodes();
-  TColgp_Array1OfXYZ anArrOfXYZ(1,4);
-  gp_XYZ p1, p2, p3, p4;
-  SMDS_ElemIteratorPtr aNodeItr = theFace->nodesIterator();
-  int i = 1;
-  for ( ; aNodeItr->more() && i <= 4; i++ )
-  {
-    SMDS_MeshNode* aNode = (SMDS_MeshNode*)aNodeItr->next();
-    anArrOfXYZ.SetValue(i, gp_XYZ( aNode->X(), aNode->Y(), aNode->Z() ) );
-  }
-  
-  gp_XYZ q1 = anArrOfXYZ.Value(2) - anArrOfXYZ.Value(1);
-  gp_XYZ q2 = anArrOfXYZ.Value(3) - anArrOfXYZ.Value(1);
-  n  = q1 ^ q2;
-  if ( aNbNode > 3 )
-  {
-    gp_XYZ q3 = anArrOfXYZ.Value(4) - anArrOfXYZ.Value(1);
-    n += q2 ^ q3;
-  }
+  SMESH_TNodeXYZ xyz1( n1 );
+  SMESH_TNodeXYZ xyz2( n2 );
+  SMESH_TNodeXYZ xyz3( n3 );
+  gp_XYZ q1 = xyz2 - xyz1;
+  gp_XYZ q2 = xyz3 - xyz1;
+  gp_XYZ n  = q1 ^ q2;
   double len = n.Modulus();
-  if ( len > 0 )
+  if ( len > std::numeric_limits<double>::min() )
     n /= len;
 
   return n;
 }
 
+//================================================================================
+/*!
+ * \brief Decompose a mesh face into triangles
+ *  \retval int - number of triangles
+ */
+//================================================================================
+
+static int getTriangles( const SMDS_MeshElement* face,
+                         const SMDS_MeshNode**   nodes)
+{
+  // WARNING: implementation must be coherent with counting triangles in writeBinary()
+  int nbN = face->NbCornerNodes();
+  const int nbTria = nbN-2;
+  for ( int i = 0; nbN > 1; --nbN )
+  {
+    nodes[ i++ ] = face->GetNode( 0 );
+    nodes[ i++ ] = face->GetNode( nbN-2 );
+    nodes[ i++ ] = face->GetNode( nbN-1 );
+  }
+  return nbTria;
+}
+
 // private methods
 
 Driver_Mesh::Status DriverSTL_W_SMDS_Mesh::writeAscii() const
@@ -151,17 +229,24 @@ Driver_Mesh::Status DriverSTL_W_SMDS_Mesh::writeAscii() const
 
   OSD_File aFile = OSD_File(OSD_Path(aFileName));
   aFile.Build(OSD_WriteOnly,OSD_Protection());
+
+  char sval[16];
   TCollection_AsciiString buf = TCollection_AsciiString ("solid\n");
   aFile.Write (buf,buf.Length());buf.Clear();
-  char sval[16];
 
-  SMDS_FaceIteratorPtr itFaces = myMesh->facesIterator();
-  
-  for (; itFaces->more() ;) {
-    SMDS_MeshFace* aFace = (SMDS_MeshFace*)itFaces->next();
+  const SMDS_MeshNode* triaNodes[2048];
+
+  SMDS_ElemIteratorPtr itFaces = getFaces();
+  while ( itFaces->more() )
+  {
+    const SMDS_MeshElement* aFace = itFaces->next();
+    int nbTria = getTriangles( aFace, triaNodes );
     
-    if (aFace->NbNodes() == 3) {
-      gp_XYZ normale = getNormale( aFace );
+    for ( int iT = 0, iN = 0; iT < nbTria; ++iT )
+    {
+      gp_XYZ normale = getNormale( triaNodes[iN],
+                                   triaNodes[iN+1],
+                                   triaNodes[iN+2] );
 
       buf += " facet normal "; 
       sprintf (sval,"% 12e",normale.X());
@@ -177,9 +262,8 @@ Driver_Mesh::Status DriverSTL_W_SMDS_Mesh::writeAscii() const
       buf += "   outer loop\n"; 
       aFile.Write (buf,buf.Length());buf.Clear();
       
-      SMDS_ElemIteratorPtr aNodeIter = aFace->nodesIterator();
-      for (; aNodeIter->more(); ) {
-       SMDS_MeshNode* node = (SMDS_MeshNode*)aNodeIter->next();
+      for ( int jN = 0; jN < 3; ++jN, ++iN ) {
+        const SMDS_MeshNode* node = triaNodes[iN];
         buf += "     vertex "; 
         sprintf (sval,"% 12e",node->X());
         buf += sval;
@@ -218,41 +302,58 @@ Driver_Mesh::Status DriverSTL_W_SMDS_Mesh::writeBinary() const
   OSD_File aFile = OSD_File(OSD_Path(aFileName));
   aFile.Build(OSD_WriteOnly,OSD_Protection());
 
-  char sval[80];
-  Standard_Integer nbTri = 0;
-  SMDS_FaceIteratorPtr itFaces = myMesh->facesIterator();
-
   // we first count the number of triangles
-  for (;itFaces->more();) {
-    SMDS_MeshFace* aFace = (SMDS_MeshFace*)itFaces->next();
-    if (aFace->NbNodes() == 3)
-      nbTri++;
+  // WARNING: counting triangles must be coherent with getTriangles()
+  int nbTri = 0;
+  const SMDS_MeshInfo& info = myMesh->GetMeshInfo();
+  nbTri += info.NbTriangles();
+  nbTri += info.NbQuadrangles() * 2;
+  nbTri += myVolumeTrias.size();
+  if ( info.NbPolygons() > 0 )
+  {
+    SMDS_FaceIteratorPtr itFaces = myMesh->facesIterator();
+    while ( itFaces->more() )
+    {
+      const SMDS_MeshElement* aFace = itFaces->next();
+      if ( aFace->IsPoly() )
+        nbTri += aFace->NbNodes() - 2;
+    }
   }
 
+  // char sval[80]; -- avoid writing not initialized memory
+  TCollection_AsciiString sval(LABEL_SIZE-1,' ');
+  aFile.Write((Standard_Address)sval.ToCString(),LABEL_SIZE);
+
   // write number of triangles
-  //unsigned int NBT = nbTri;
-  aFile.Write((Standard_Address)sval,LABEL_SIZE);
   writeInteger(nbTri,aFile);  
 
-  // loop writing nodes. take face iterator again
+  // Loop writing nodes
+
   int dum=0;
-  itFaces = myMesh->facesIterator();
-  
-  for (;itFaces->more();) {
-    SMDS_MeshFace* aFace = (SMDS_MeshFace*)itFaces->next();
+
+  const SMDS_MeshNode* triaNodes[2048];
+
+  SMDS_ElemIteratorPtr itFaces = getFaces();
+  while ( itFaces->more() )
+  {
+    const SMDS_MeshElement* aFace = itFaces->next();
+    int nbTria = getTriangles( aFace, triaNodes );
     
-    if (aFace->NbNodes() == 3) {
-      gp_XYZ aNorm = getNormale( aFace );
-      writeFloat(aNorm.X(),aFile);
-      writeFloat(aNorm.Y(),aFile);
-      writeFloat(aNorm.Z(),aFile);
-
-      SMDS_ElemIteratorPtr aNodeIter = aFace->nodesIterator();
-      for (; aNodeIter->more(); ) {
-       SMDS_MeshNode* node = (SMDS_MeshNode*)aNodeIter->next();
-       writeFloat(node->X(),aFile);
-       writeFloat(node->Y(),aFile);
-       writeFloat(node->Z(),aFile);
+    for ( int iT = 0, iN = 0; iT < nbTria; ++iT )
+    {
+      gp_XYZ normale = getNormale( triaNodes[iN],
+                                   triaNodes[iN+1],
+                                   triaNodes[iN+2] );
+      writeFloat(normale.X(),aFile);
+      writeFloat(normale.Y(),aFile);
+      writeFloat(normale.Z(),aFile);
+
+      for ( int jN = 0; jN < 3; ++jN, ++iN )
+      {
+        const SMDS_MeshNode* node = triaNodes[iN];
+        writeFloat(node->X(),aFile);
+        writeFloat(node->Y(),aFile);
+        writeFloat(node->Z(),aFile);
       }
       aFile.Write (&dum,2);
     } 
index 04979d4fcd945ebf5b42196d8466a25cdd0feec7..f83284ee547580be674eab7a7ae2469234282e95 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH DriverSTL : driver to read and write 'stl' files
 //  File   : DriverSTL_W_SMDS_Mesh.h
 //  Module : SMESH
 #include "SMESH_DriverSTL.hxx"
 
 #include "Driver_SMDS_Mesh.h"
-#include <Standard_TypeDef.hxx>
+#include "SMDS_ElemIterator.hxx"
+
+#include <vector>
 
 class MESHDRIVERSTL_EXPORT DriverSTL_W_SMDS_Mesh: public Driver_SMDS_Mesh
 {
  public:
   
   DriverSTL_W_SMDS_Mesh();
+  ~DriverSTL_W_SMDS_Mesh();
   virtual Status Perform();
   void    SetIsAscii( const bool theIsAscii = false );
 
@@ -43,10 +47,14 @@ class MESHDRIVERSTL_EXPORT DriverSTL_W_SMDS_Mesh: public Driver_SMDS_Mesh
   // PRIVATE METHODS
   Status  writeAscii  () const;
   Status  writeBinary () const;
+  void    findVolumeTriangles();
+
+  SMDS_ElemIteratorPtr getFaces() const;
 
  private:
   // PRIVATE FIELDS
   bool myIsAscii;
+  std::vector<const SMDS_MeshElement*> myVolumeTrias; // tmp triangles
 };
 
 #endif
index aa49c013c29943258c59b23869c6ff314ffbc6bd..426538639b1ec091582033a0c2c2d3cb72b6b937 100644 (file)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  SMESH DriverSTL : driver to read and write 'stl' files
 #  File   : Makefile.in
 #  Author : Marc Tajchman (CEA)
@@ -52,8 +50,11 @@ dist_STL_Test_SOURCES = \
 libMeshDriverSTL_la_CPPFLAGS = \
        $(KERNEL_CXXFLAGS) \
        $(CAS_CPPFLAGS) \
+        $(VTK_INCLUDES) \
        $(BOOST_CPPFLAGS) \
        -I$(srcdir)/../Driver \
+       -I$(srcdir)/../SMESH \
+       -I$(srcdir)/../SMESHUtils \
        -I$(srcdir)/../SMDS
 
 libMeshDriverSTL_la_LDFLAGS  = \
index 4246d18adb2ea017a5a1b09b3654aacf81d4ef99..c2ecd37ea8e48707c98b0b8367f5f4793f5706cb 100755 (executable)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  File   : SMESH_DriverSTL.hxx
 //  Author : Alexander A. BORODIN
 //  Module : SMESH
@@ -27,7 +28,7 @@
 #define _SMESH_DriverSTL_HXX_
 
 #ifdef WNT
- #if defined MESHDRIVERSTL_EXPORTS
+ #if defined MESHDRIVERSTL_EXPORTS || defined MeshDriverSTL_EXPORTS
   #define MESHDRIVERSTL_EXPORT __declspec( dllexport )
  #else
   #define MESHDRIVERSTL_EXPORT __declspec( dllimport )
index 1acfd97895e998bd0ad8e3b5737d09be2b52abfa..c060fb49e3f788600bd86bdcdbad293ec1ce7342 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //#include "DriverSTL_R_SMDS_Mesh.h"
 //
 #include "DriverSTL_W_SMDS_Mesh.h"
index c438fa334639dc62cffd0ff3696250611e8b10b5..0ad1f8beec51033887f87d5f8d3aad78c21288ea 100644 (file)
@@ -1,44 +1,95 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #include "DriverUNV_R_SMDS_Mesh.h"
 #include "SMDS_Mesh.hxx"
 #include "SMDS_MeshGroup.hxx"
 
 #include "utilities.h"
 
+#include "UNV164_Structure.hxx"
 #include "UNV2411_Structure.hxx"
 #include "UNV2412_Structure.hxx"
 #include "UNV2417_Structure.hxx"
+#include "UNV2420_Structure.hxx"
 #include "UNV_Utilities.hxx"
 
+#include <Basics_Utils.hxx>
+
 using namespace std;
 
 
 #ifdef _DEBUG_
-static int MYDEBUG = 0;
+static int MYDEBUG = 1;
 #else
 static int MYDEBUG = 0;
 #endif
 
+namespace
+{
+  /*!
+   * \brief Move node coordinates to the global Cartesian CS
+   */
+  void transformNodes( UNV2411::TDataSet::const_iterator fromNode,
+                       UNV2411::TDataSet::const_iterator endNode,
+                       const UNV2420::TRecord &          csRecord )
+  {
+    const int csLabel = fromNode->exp_coord_sys_num;
+
+    UNV2411::TDataSet::const_iterator nodeIt;
+
+    // apply Transformation Matrix
+    if ( !csRecord.isIdentityMatrix() )
+    {
+      for ( nodeIt = fromNode; nodeIt != endNode; ++nodeIt )
+      {
+        const UNV2411::TRecord& nodeRec = *nodeIt;
+        if ( nodeRec.exp_coord_sys_num == csLabel )
+          csRecord.ApplyMatrix( (double*) nodeRec.coord );
+      }
+    }
+
+    // transform from Cylindrical CS
+    if ( csRecord.coord_sys_type == UNV2420::Cylindrical )
+    {
+      for ( nodeIt = fromNode; nodeIt != endNode; ++nodeIt )
+      {
+        const UNV2411::TRecord& nodeRec = *nodeIt;
+        if ( nodeRec.exp_coord_sys_num == csLabel )
+          csRecord.FromCylindricalCS( (double*) nodeRec.coord );
+      }
+    }
+    // transform from Spherical CS
+    else if ( csRecord.coord_sys_type == UNV2420::Spherical )
+    {
+      for ( nodeIt = fromNode; nodeIt != endNode; ++nodeIt )
+      {
+        const UNV2411::TRecord& nodeRec = *nodeIt;
+        if ( nodeRec.exp_coord_sys_num == csLabel )
+          csRecord.FromSphericalCS( (double*) nodeRec.coord );
+      }
+    }
+  }
+}
 
 DriverUNV_R_SMDS_Mesh::~DriverUNV_R_SMDS_Mesh()
 {
@@ -49,309 +100,367 @@ DriverUNV_R_SMDS_Mesh::~DriverUNV_R_SMDS_Mesh()
 
 Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform()
 {
+  Kernel_Utils::Localizer loc;
   Status aResult = DRS_OK;
   std::ifstream in_stream(myFile.c_str());
-  try{
+  try
+  {
     {
+      // Read Units
+      UNV164::TRecord aUnitsRecord;
+      UNV164::Read( in_stream, aUnitsRecord );
+
+      // Read Coordinate systems
+      UNV2420::TDataSet aCoordSysDataSet;
+      UNV2420::Read(in_stream, myMeshName, aCoordSysDataSet);
+
+      // Read nodes
       using namespace UNV2411;
       TDataSet aDataSet2411;
       UNV2411::Read(in_stream,aDataSet2411);
       if(MYDEBUG) MESSAGE("Perform - aDataSet2411.size() = "<<aDataSet2411.size());
+
+      // Move nodes in a global CS
+      if ( !aCoordSysDataSet.empty() )
+      {
+        UNV2420::TDataSet::const_iterator csIter = aCoordSysDataSet.begin();
+        for ( ; csIter != aCoordSysDataSet.end(); ++csIter )
+        {
+          // find any node in this CS
+          TDataSet::const_iterator nodeIter = aDataSet2411.begin();
+          for (; nodeIter != aDataSet2411.end(); nodeIter++)
+            if ( nodeIter->exp_coord_sys_num == csIter->coord_sys_label )
+            {
+              transformNodes( nodeIter, aDataSet2411.end(), *csIter );
+              break;
+            }
+        }
+      }
+      // Move nodes to SI unit system
+      const double lenFactor = aUnitsRecord.factors[ UNV164::LENGTH_FACTOR ]; 
+      if ( lenFactor != 1. )
+      {
+        TDataSet::iterator nodeIter = aDataSet2411.begin(), nodeEnd;
+        for ( nodeEnd = aDataSet2411.end(); nodeIter != nodeEnd; nodeIter++)
+        {
+          UNV2411::TRecord& nodeRec = *nodeIter;
+          nodeRec.coord[0] *= lenFactor;
+          nodeRec.coord[1] *= lenFactor;
+          nodeRec.coord[2] *= lenFactor;
+        }
+      }
+
+      // Create nodes in the mesh
       TDataSet::const_iterator anIter = aDataSet2411.begin();
-      for(; anIter != aDataSet2411.end(); anIter++){
-       const TNodeLab& aLabel = anIter->first;
-       const TRecord& aRec = anIter->second;
-       myMesh->AddNodeWithID(aRec.coord[0],aRec.coord[1],aRec.coord[2],aLabel);
+      for(; anIter != aDataSet2411.end(); anIter++)
+      {
+        const TRecord& aRec = *anIter;
+        myMesh->AddNodeWithID(aRec.coord[0],aRec.coord[1],aRec.coord[2],aRec.label);
       }
     }
     {
       using namespace UNV2412;
-      in_stream.seekg(0);
       TDataSet aDataSet2412;
       UNV2412::Read(in_stream,aDataSet2412);
       TDataSet::const_iterator anIter = aDataSet2412.begin();
       if(MYDEBUG) MESSAGE("Perform - aDataSet2412.size() = "<<aDataSet2412.size());
-      for(; anIter != aDataSet2412.end(); anIter++){
-       SMDS_MeshElement* anElement = NULL;
-       const TElementLab& aLabel = anIter->first;
-       const TRecord& aRec = anIter->second;
-       if(IsBeam(aRec.fe_descriptor_id)) {
+      for(; anIter != aDataSet2412.end(); anIter++)
+      {
+        SMDS_MeshElement* anElement = NULL;
+        const TRecord& aRec = *anIter;
+        if(IsBeam(aRec.fe_descriptor_id)) {
           switch ( aRec.node_labels.size() ) {
           case 2: // edge with two nodes
+            //MESSAGE("add edge " << aLabel << " " << aRec.node_labels[0] << " " << aRec.node_labels[1]);
             anElement = myMesh->AddEdgeWithID(aRec.node_labels[0],
                                               aRec.node_labels[1],
-                                              aLabel);
+                                              aRec.label);
             break;
           case 3: // quadratic edge (with 3 nodes)
+            //MESSAGE("add edge " << aRec.label << " " << aRec.node_labels[0] << " " << aRec.node_labels[1] << " " << aRec.node_labels[2]);
             anElement = myMesh->AddEdgeWithID(aRec.node_labels[0],
                                               aRec.node_labels[2],
                                               aRec.node_labels[1],
-                                              aLabel);
+                                              aRec.label);
           }
-       }
+        }
         else if(IsFace(aRec.fe_descriptor_id)) {
-         switch(aRec.fe_descriptor_id){
-         case 71: // TRI3
-         case 72:
-         case 74:
-           
-         case 41: // Plane Stress Linear Triangle - TRI3
-         case 91: // Thin Shell Linear Triangle - TRI3
-           anElement = myMesh->AddFaceWithID(aRec.node_labels[0],
-                                             aRec.node_labels[1],
-                                             aRec.node_labels[2],
-                                             aLabel);
-           break;
-           
-         case 42: // Plane Stress Quadratic Triangle - TRI6
-         case 92: // Thin Shell Quadratic Triangle - TRI6
-           anElement = myMesh->AddFaceWithID(aRec.node_labels[0],
-                                             aRec.node_labels[2],
-                                             aRec.node_labels[4],
-                                             aRec.node_labels[1],
-                                             aRec.node_labels[3],
-                                             aRec.node_labels[5],
-                                             aLabel);
-           break;
-           
-         case 44: // Plane Stress Linear Quadrilateral - QUAD4
-         case 94: // Thin Shell   Linear Quadrilateral -  QUAD4
-           anElement = myMesh->AddFaceWithID(aRec.node_labels[0],
-                                             aRec.node_labels[1],
-                                             aRec.node_labels[2],
-                                             aRec.node_labels[3],
-                                             aLabel);
-           break;
-           
-         case 45: // Plane Stress Quadratic Quadrilateral - QUAD8
-         case 95: // Thin Shell   Quadratic Quadrilateral - QUAD8
-           anElement = myMesh->AddFaceWithID(aRec.node_labels[0],
-                                             aRec.node_labels[2],
-                                             aRec.node_labels[4],
-                                             aRec.node_labels[6],
-                                             aRec.node_labels[1],
-                                             aRec.node_labels[3],
-                                             aRec.node_labels[5],
-                                             aRec.node_labels[7],
-                                             aLabel);
-           break;
-         }
-       }
+          //MESSAGE("add face " << aRec.label);
+          switch(aRec.fe_descriptor_id){
+          case 41: // Plane Stress Linear Triangle      
+          case 51: // Plane Strain Linear Triangle      
+          case 61: // Plate Linear Triangle             
+          case 74: // Membrane Linear Triangle          
+          case 81: // Axisymetric Solid Linear Triangle 
+          case 91: // Thin Shell Linear Triangle        
+            anElement = myMesh->AddFaceWithID(aRec.node_labels[0],
+                                              aRec.node_labels[1],
+                                              aRec.node_labels[2],
+                                              aRec.label);
+            break;
+            
+          case 42: //  Plane Stress Parabolic Triangle       
+          case 52: //  Plane Strain Parabolic Triangle       
+          case 62: //  Plate Parabolic Triangle              
+          case 72: //  Membrane Parabolic Triangle           
+          case 82: //  Axisymetric Solid Parabolic Triangle  
+          case 92: //  Thin Shell Parabolic Triangle         
+            //MESSAGE("add face " << aRec.label << " " << aRec.node_labels[0] << " " << aRec.node_labels[1] << " " << aRec.node_labels[2] << " " << aRec.node_labels[3] << " " << aRec.node_labels[4] << " " << aRec.node_labels[5]);
+            anElement = myMesh->AddFaceWithID(aRec.node_labels[0],
+                                              aRec.node_labels[2],
+                                              aRec.node_labels[4],
+                                              aRec.node_labels[1],
+                                              aRec.node_labels[3],
+                                              aRec.node_labels[5],
+                                              aRec.label);
+            break;
+            
+          case 44: // Plane Stress Linear Quadrilateral     
+          case 54: // Plane Strain Linear Quadrilateral     
+          case 64: // Plate Linear Quadrilateral            
+          case 71: // Membrane Linear Quadrilateral         
+          case 84: // Axisymetric Solid Linear Quadrilateral
+          case 94: // Thin Shell Linear Quadrilateral       
+            anElement = myMesh->AddFaceWithID(aRec.node_labels[0],
+                                              aRec.node_labels[1],
+                                              aRec.node_labels[2],
+                                              aRec.node_labels[3],
+                                              aRec.label);
+            break;
+            
+          case 45: // Plane Stress Parabolic Quadrilateral      
+          case 55: // Plane Strain Parabolic Quadrilateral      
+          case 65: // Plate Parabolic Quadrilateral             
+          case 75: // Membrane Parabolic Quadrilateral          
+          case 85: // Axisymetric Solid Parabolic Quadrilateral 
+          case 95: // Thin Shell Parabolic Quadrilateral        
+            anElement = myMesh->AddFaceWithID(aRec.node_labels[0],
+                                              aRec.node_labels[2],
+                                              aRec.node_labels[4],
+                                              aRec.node_labels[6],
+                                              aRec.node_labels[1],
+                                              aRec.node_labels[3],
+                                              aRec.node_labels[5],
+                                              aRec.node_labels[7],
+                                              aRec.label);
+            break;
+          }
+        }
         else if(IsVolume(aRec.fe_descriptor_id)){
-         switch(aRec.fe_descriptor_id){
-           
-         case 111: // Solid Linear Tetrahedron - TET4
-           anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
-                                               aRec.node_labels[2],
-                                               aRec.node_labels[1],
-                                               aRec.node_labels[3],
-                                               aLabel);
-           break;
-
-         case 118: // Solid Quadratic Tetrahedron - TET10
-           anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
-                                               aRec.node_labels[4],
-                                               aRec.node_labels[2],
-
-                                               aRec.node_labels[9],
-
-                                               aRec.node_labels[5],
-                                               aRec.node_labels[3],
+          //MESSAGE("add volume " << aRec.label);
+          switch(aRec.fe_descriptor_id){
+            
+          case 111: // Solid Linear Tetrahedron - TET4
+            anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
+                                                aRec.node_labels[2],
+                                                aRec.node_labels[1],
+                                                aRec.node_labels[3],
+                                                aRec.label);
+            break;
+
+          case 118: // Solid Quadratic Tetrahedron - TET10
+            anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
+                                                aRec.node_labels[4],
+                                                aRec.node_labels[2],
+
+                                                aRec.node_labels[9],
+
+                                                aRec.node_labels[5],
+                                                aRec.node_labels[3],
                                                 aRec.node_labels[1],
 
                                                 aRec.node_labels[6],
-                                               aRec.node_labels[8],
-                                               aRec.node_labels[7],
-                                               aLabel);
-           break;
-           
-         case 112: // Solid Linear Prism - PRISM6
-           anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
-                                               aRec.node_labels[2],
-                                               aRec.node_labels[1],
-                                               aRec.node_labels[3],
-                                               aRec.node_labels[5],
-                                               aRec.node_labels[4],
-                                               aLabel);
-           break;
-           
-         case 113: // Solid Quadratic Prism - PRISM15
-           anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
-                                               aRec.node_labels[4],
-                                               aRec.node_labels[2],
-
-                                               aRec.node_labels[9],
-                                               aRec.node_labels[13],
-                                               aRec.node_labels[11],
-
-                                               aRec.node_labels[5],
-                                               aRec.node_labels[3],
+                                                aRec.node_labels[8],
+                                                aRec.node_labels[7],
+                                                aRec.label);
+            break;
+            
+          case 112: // Solid Linear Prism - PRISM6
+            anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
+                                                aRec.node_labels[2],
+                                                aRec.node_labels[1],
+                                                aRec.node_labels[3],
+                                                aRec.node_labels[5],
+                                                aRec.node_labels[4],
+                                                aRec.label);
+            break;
+            
+          case 113: // Solid Quadratic Prism - PRISM15
+            anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
+                                                aRec.node_labels[4],
+                                                aRec.node_labels[2],
+
+                                                aRec.node_labels[9],
+                                                aRec.node_labels[13],
+                                                aRec.node_labels[11],
+
+                                                aRec.node_labels[5],
+                                                aRec.node_labels[3],
                                                 aRec.node_labels[1],
 
-                                               aRec.node_labels[14],
-                                               aRec.node_labels[12],
+                                                aRec.node_labels[14],
+                                                aRec.node_labels[12],
                                                 aRec.node_labels[10],
 
                                                 aRec.node_labels[6],
-                                               aRec.node_labels[8],
-                                               aRec.node_labels[7],
-                                               aLabel);
-           break;
-           
-         case 115: // Solid Linear Brick - HEX8
-           anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
-                                               aRec.node_labels[3],
-                                               aRec.node_labels[2],
-                                               aRec.node_labels[1],
-                                               aRec.node_labels[4],
-                                               aRec.node_labels[7],
-                                               aRec.node_labels[6],
-                                               aRec.node_labels[5],
-                                               aLabel);
-           break;
-
-         case 116: // Solid Quadratic Brick - HEX20
-           anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
-                                               aRec.node_labels[6],
-                                               aRec.node_labels[4],
-                                               aRec.node_labels[2],
-
-                                               aRec.node_labels[12],
-                                               aRec.node_labels[18],
-                                               aRec.node_labels[16],
-                                               aRec.node_labels[14],
-
-                                               aRec.node_labels[7],
-                                               aRec.node_labels[5],
-                                               aRec.node_labels[3],
-                                               aRec.node_labels[1],
-
-                                               aRec.node_labels[19],
-                                               aRec.node_labels[17],
-                                               aRec.node_labels[15],
+                                                aRec.node_labels[8],
+                                                aRec.node_labels[7],
+                                                aRec.label);
+            break;
+            
+          case 115: // Solid Linear Brick - HEX8
+            anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
+                                                aRec.node_labels[3],
+                                                aRec.node_labels[2],
+                                                aRec.node_labels[1],
+                                                aRec.node_labels[4],
+                                                aRec.node_labels[7],
+                                                aRec.node_labels[6],
+                                                aRec.node_labels[5],
+                                                aRec.label);
+            break;
+
+          case 116: // Solid Quadratic Brick - HEX20
+            anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
+                                                aRec.node_labels[6],
+                                                aRec.node_labels[4],
+                                                aRec.node_labels[2],
+
+                                                aRec.node_labels[12],
+                                                aRec.node_labels[18],
+                                                aRec.node_labels[16],
+                                                aRec.node_labels[14],
+
+                                                aRec.node_labels[7],
+                                                aRec.node_labels[5],
+                                                aRec.node_labels[3],
+                                                aRec.node_labels[1],
+
+                                                aRec.node_labels[19],
+                                                aRec.node_labels[17],
+                                                aRec.node_labels[15],
                                                 aRec.node_labels[13],
 
                                                 aRec.node_labels[8],
-                                               aRec.node_labels[11],
-                                               aRec.node_labels[10],
-                                               aRec.node_labels[9],
-                                               aLabel);
-           break;
-
-         case 114: // pyramid of 13 nodes (quadratic) - PIRA13
-           anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
-                                               aRec.node_labels[6],
-                                               aRec.node_labels[4],
-                                               aRec.node_labels[2],
-                                               aRec.node_labels[7],
-                                               aRec.node_labels[5],
-                                               aRec.node_labels[3],
-                                               aRec.node_labels[1],
-
-                                               aRec.node_labels[8],
-                                               aRec.node_labels[11],
-                                               aRec.node_labels[10],
-                                               aRec.node_labels[9],
-                                               aRec.node_labels[12],
-                                               aLabel);
-           break;
-
-         }
-       }
-       //      if(!anElement)
-       //        MESSAGE("DriverUNV_R_SMDS_Mesh::Perform - can not add element with ID = "<<aLabel<<" and type = "<<aRec.fe_descriptor_id);
+                                                aRec.node_labels[11],
+                                                aRec.node_labels[10],
+                                                aRec.node_labels[9],
+                                                aRec.label);
+            break;
+
+          case 114: // pyramid of 13 nodes (quadratic) - PIRA13
+            anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
+                                                aRec.node_labels[6],
+                                                aRec.node_labels[4],
+                                                aRec.node_labels[2],
+                                                aRec.node_labels[7],
+                                                aRec.node_labels[5],
+                                                aRec.node_labels[3],
+                                                aRec.node_labels[1],
+
+                                                aRec.node_labels[8],
+                                                aRec.node_labels[11],
+                                                aRec.node_labels[10],
+                                                aRec.node_labels[9],
+                                                aRec.node_labels[12],
+                                                aRec.label);
+            break;
+
+          }
+        }
+        if(!anElement)
+          MESSAGE("DriverUNV_R_SMDS_Mesh::Perform - can not add element with ID = "<<aRec.label<<" and type = "<<aRec.fe_descriptor_id);
       }
     }
     {
       using namespace UNV2417;      
-      in_stream.seekg(0);
       TDataSet aDataSet2417;
       UNV2417::Read(in_stream,aDataSet2417);
       if(MYDEBUG) MESSAGE("Perform - aDataSet2417.size() = "<<aDataSet2417.size());
       if  (aDataSet2417.size() > 0) {
-       myGroup = new SMDS_MeshGroup(myMesh);
-       TDataSet::const_iterator anIter = aDataSet2417.begin();
-       for(; anIter != aDataSet2417.end(); anIter++){
-         const TGroupId& aLabel = anIter->first;
-         const TRecord& aRec = anIter->second;
-
-         int aNodesNb = aRec.NodeList.size();
-         int aElementsNb = aRec.ElementList.size();
-
-         bool useSuffix = ((aNodesNb > 0) && (aElementsNb > 0));
-         int i;
-         if (aNodesNb > 0) {
-           SMDS_MeshGroup* aNodesGroup = (SMDS_MeshGroup*) myGroup->AddSubGroup(SMDSAbs_Node);
-           std::string aGrName = (useSuffix) ? aRec.GroupName + "_Nodes" : aRec.GroupName;
-           int i = aGrName.find( "\r" );
-           if (i > 0)
-             aGrName.erase (i, 2);
-           myGroupNames.insert(TGroupNamesMap::value_type(aNodesGroup, aGrName));
-           myGroupId.insert(TGroupIdMap::value_type(aNodesGroup, aLabel));
-
-           for (i = 0; i < aNodesNb; i++) {
-             const SMDS_MeshNode* aNode = myMesh->FindNode(aRec.NodeList[i]);
-             if (aNode)
-               aNodesGroup->Add(aNode);
-           }
-         }
-         if (aElementsNb > 0){
-           SMDS_MeshGroup* aEdgesGroup = 0;
-           SMDS_MeshGroup* aFacesGroup = 0;
-           SMDS_MeshGroup* aVolumeGroup = 0;
-           bool createdGroup = false;
-
-           for (i = 0; i < aElementsNb; i++) {
-             const SMDS_MeshElement* aElement = myMesh->FindElement(aRec.ElementList[i]);
-             if (aElement) {
-               switch (aElement->GetType()) {
-               case SMDSAbs_Edge:
-                 if (!aEdgesGroup) {
-                   aEdgesGroup = (SMDS_MeshGroup*) myGroup->AddSubGroup(SMDSAbs_Edge);
-                   if (!useSuffix && createdGroup) useSuffix = true;
-                   std::string aEdgesGrName = (useSuffix) ? aRec.GroupName + "_Edges" : aRec.GroupName;
-                   int i = aEdgesGrName.find( "\r" );
-                   if (i > 0)
-                     aEdgesGrName.erase (i, 2);
-                   myGroupNames.insert(TGroupNamesMap::value_type(aEdgesGroup, aEdgesGrName));
-                   myGroupId.insert(TGroupIdMap::value_type(aEdgesGroup, aLabel));
-                   createdGroup = true;
-                 }
-                 aEdgesGroup->Add(aElement);
-                 break;
-               case SMDSAbs_Face:
-                 if (!aFacesGroup) {
-                   aFacesGroup = (SMDS_MeshGroup*) myGroup->AddSubGroup(SMDSAbs_Face);
-                   if (!useSuffix && createdGroup) useSuffix = true;
-                   std::string aFacesGrName = (useSuffix) ? aRec.GroupName + "_Faces" : aRec.GroupName;
-                   int i = aFacesGrName.find( "\r" );
-                   if (i > 0)
-                     aFacesGrName.erase (i, 2);
-                   myGroupNames.insert(TGroupNamesMap::value_type(aFacesGroup, aFacesGrName));
-                   myGroupId.insert(TGroupIdMap::value_type(aFacesGroup, aLabel));
-                   createdGroup = true;
-                 }
-                 aFacesGroup->Add(aElement);
-                 break;
-               case SMDSAbs_Volume:
-                 if (!aVolumeGroup) {
-                   aVolumeGroup = (SMDS_MeshGroup*) myGroup->AddSubGroup(SMDSAbs_Volume);
-                   if (!useSuffix && createdGroup) useSuffix = true;
-                   std::string aVolumeGrName = (useSuffix) ? aRec.GroupName + "_Volumes" : aRec.GroupName;
-                   int i = aVolumeGrName.find( "\r" );
-                   if (i > 0)
-                     aVolumeGrName.erase (i, 2);
-                   myGroupNames.insert(TGroupNamesMap::value_type(aVolumeGroup, aVolumeGrName));
-                   myGroupId.insert(TGroupIdMap::value_type(aVolumeGroup, aLabel));
-                   createdGroup = true;
-                 }
-                 aVolumeGroup->Add(aElement);
-                 break;
-               }
-             } 
-           }
-         }
-       }
+        myGroup = new SMDS_MeshGroup(myMesh);
+        TDataSet::const_iterator anIter = aDataSet2417.begin();
+        for(; anIter != aDataSet2417.end(); anIter++){
+          const TGroupId& aLabel = anIter->first;
+          const TRecord& aRec = anIter->second;
+
+          int aNodesNb = aRec.NodeList.size();
+          int aElementsNb = aRec.ElementList.size();
+
+          bool useSuffix = ((aNodesNb > 0) && (aElementsNb > 0));
+          int i;
+          if (aNodesNb > 0) {
+            SMDS_MeshGroup* aNodesGroup = (SMDS_MeshGroup*) myGroup->AddSubGroup(SMDSAbs_Node);
+            std::string aGrName = (useSuffix) ? aRec.GroupName + "_Nodes" : aRec.GroupName;
+            int i = aGrName.find( "\r" );
+            if (i > 0)
+              aGrName.erase (i, 2);
+            myGroupNames.insert(TGroupNamesMap::value_type(aNodesGroup, aGrName));
+            myGroupId.insert(TGroupIdMap::value_type(aNodesGroup, aLabel));
+
+            for (i = 0; i < aNodesNb; i++) {
+              const SMDS_MeshNode* aNode = myMesh->FindNode(aRec.NodeList[i]);
+              if (aNode)
+                aNodesGroup->Add(aNode);
+            }
+          }
+          if (aElementsNb > 0){
+            SMDS_MeshGroup* aEdgesGroup = 0;
+            SMDS_MeshGroup* aFacesGroup = 0;
+            SMDS_MeshGroup* aVolumeGroup = 0;
+            bool createdGroup = false;
+
+            for (i = 0; i < aElementsNb; i++) {
+              const SMDS_MeshElement* aElement = myMesh->FindElement(aRec.ElementList[i]);
+              if (aElement) {
+                switch (aElement->GetType()) {
+                case SMDSAbs_Edge:
+                  if (!aEdgesGroup) {
+                    aEdgesGroup = (SMDS_MeshGroup*) myGroup->AddSubGroup(SMDSAbs_Edge);
+                    if (!useSuffix && createdGroup) useSuffix = true;
+                    std::string aEdgesGrName = (useSuffix) ? aRec.GroupName + "_Edges" : aRec.GroupName;
+                    int i = aEdgesGrName.find( "\r" );
+                    if (i > 0)
+                      aEdgesGrName.erase (i, 2);
+                    myGroupNames.insert(TGroupNamesMap::value_type(aEdgesGroup, aEdgesGrName));
+                    myGroupId.insert(TGroupIdMap::value_type(aEdgesGroup, aLabel));
+                    createdGroup = true;
+                  }
+                  aEdgesGroup->Add(aElement);
+                  break;
+                case SMDSAbs_Face:
+                  if (!aFacesGroup) {
+                    aFacesGroup = (SMDS_MeshGroup*) myGroup->AddSubGroup(SMDSAbs_Face);
+                    if (!useSuffix && createdGroup) useSuffix = true;
+                    std::string aFacesGrName = (useSuffix) ? aRec.GroupName + "_Faces" : aRec.GroupName;
+                    int i = aFacesGrName.find( "\r" );
+                    if (i > 0)
+                      aFacesGrName.erase (i, 2);
+                    myGroupNames.insert(TGroupNamesMap::value_type(aFacesGroup, aFacesGrName));
+                    myGroupId.insert(TGroupIdMap::value_type(aFacesGroup, aLabel));
+                    createdGroup = true;
+                  }
+                  aFacesGroup->Add(aElement);
+                  break;
+                case SMDSAbs_Volume:
+                  if (!aVolumeGroup) {
+                    aVolumeGroup = (SMDS_MeshGroup*) myGroup->AddSubGroup(SMDSAbs_Volume);
+                    if (!useSuffix && createdGroup) useSuffix = true;
+                    std::string aVolumeGrName = (useSuffix) ? aRec.GroupName + "_Volumes" : aRec.GroupName;
+                    int i = aVolumeGrName.find( "\r" );
+                    if (i > 0)
+                      aVolumeGrName.erase (i, 2);
+                    myGroupNames.insert(TGroupNamesMap::value_type(aVolumeGroup, aVolumeGrName));
+                    myGroupId.insert(TGroupIdMap::value_type(aVolumeGroup, aLabel));
+                    createdGroup = true;
+                  }
+                  aVolumeGroup->Add(aElement);
+                  break;
+                }
+              
+            }
+          }
+        }
       }
     } 
   }
@@ -361,5 +470,7 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform()
   catch(...){
     INFOS("Unknown exception was cought !!!");
   }
+  if (myMesh)
+    myMesh->compactMesh();
   return aResult;
 }
index d385dac32ab5ffa6c952d3f6f032d8b224af8484..f9545a33cb5ea2868403efacd64b694ae34e3edc 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #ifndef _INCLUDE_DRIVERUNV_R_SMDS_MESH
 #define _INCLUDE_DRIVERUNV_R_SMDS_MESH
 
diff --git a/src/DriverUNV/DriverUNV_R_SMESHDS_Document.cxx b/src/DriverUNV/DriverUNV_R_SMESHDS_Document.cxx
deleted file mode 100644 (file)
index ff81904..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-#include "DriverUNV_R_SMESHDS_Document.h"
diff --git a/src/DriverUNV/DriverUNV_R_SMESHDS_Document.h b/src/DriverUNV/DriverUNV_R_SMESHDS_Document.h
deleted file mode 100644 (file)
index bf40922..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-#ifndef _INCLUDE_DRIVERUNV_R_SMESHDS_DOCUMENT
-#define _INCLUDE_DRIVERUNV_R_SMESHDS_DOCUMENT
-
-#include "SMESH_DriverUNV.hxx"
-
-#include "Driver_Document.h"
-
-class MESHDRIVERUNV_EXPORT DriverUNV_R_SMESHDS_Document: public Driver_Document
-{};
-
-#endif
diff --git a/src/DriverUNV/DriverUNV_R_SMESHDS_Mesh.cxx b/src/DriverUNV/DriverUNV_R_SMESHDS_Mesh.cxx
deleted file mode 100644 (file)
index ee4f2cf..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-#include "DriverUNV_R_SMESHDS_Mesh.h"
diff --git a/src/DriverUNV/DriverUNV_R_SMESHDS_Mesh.h b/src/DriverUNV/DriverUNV_R_SMESHDS_Mesh.h
deleted file mode 100644 (file)
index 074faeb..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-#ifndef _INCLUDE_DRIVERUNV_R_SMESHDS_MESH
-#define _INCLUDE_DRIVERUNV_R_SMESHDS_MESH
-
-#include "SMESH_DriverUNV.hxx"
-
-#include "Driver_SMESHDS_Mesh.h"
-
-class MESHDRIVERUNV_EXPORT DriverUNV_R_SMESHDS_Mesh: public Driver_SMESHDS_Mesh
-{};
-
-#endif
index 57688633245572717bc03d3d188faa8506028583..a33d10b3886a00cf8f056aaedd05632c1932f294 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #include <algorithm>
 
 #include "DriverUNV_W_SMDS_Mesh.h"
 
 #include "utilities.h"
 
+#include "UNV164_Structure.hxx"
 #include "UNV2411_Structure.hxx"
 #include "UNV2412_Structure.hxx"
 #include "UNV2417_Structure.hxx"
+#include "UNV2420_Structure.hxx"
 #include "UNV_Utilities.hxx"
 
+#include <Basics_Utils.hxx>
+
 using namespace std;
 using namespace UNV;
 
@@ -43,7 +48,7 @@ namespace{
   typedef std::vector<size_t> TConnect;
 
   int GetConnect(const SMDS_ElemIteratorPtr& theNodesIter, 
-                TConnect& theConnect)
+                 TConnect& theConnect)
   {
     theConnect.clear();
     for(; theNodesIter->more();){
@@ -57,9 +62,14 @@ namespace{
 
 Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform()
 {
+  Kernel_Utils::Localizer loc;
   Status aResult = DRS_OK;
   std::ofstream out_stream(myFile.c_str());
   try{
+
+    UNV164::Write( out_stream ); // unit system
+    UNV2420::Write( out_stream, myMeshName ); // Coordinate system
+
     {
       using namespace UNV2411;
       TDataSet aDataSet2411;
@@ -67,14 +77,15 @@ Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform()
       //-----------------------------------
       MESSAGE("Perform - myMesh->NbNodes() = "<<myMesh->NbNodes());
       SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator();
-      for(; aNodesIter->more();){
-       const SMDS_MeshNode* aNode = aNodesIter->next();
-       TRecord aRec;
-       aRec.coord[0] = aNode->X();
-       aRec.coord[1] = aNode->Y();
-       aRec.coord[2] = aNode->Z();
-       const TNodeLab& aLabel = aNode->GetID();
-       aDataSet2411.insert(TDataSet::value_type(aLabel,aRec));
+      TRecord aRec;
+      while ( aNodesIter->more() )
+      {
+        const SMDS_MeshNode* aNode = aNodesIter->next();
+        aRec.label    = aNode->GetID();
+        aRec.coord[0] = aNode->X();
+        aRec.coord[1] = aNode->Y();
+        aRec.coord[2] = aNode->Z();
+        aDataSet2411.push_back( aRec );
       }
       MESSAGE("Perform - aDataSet2411.size() = "<<aDataSet2411.size());
       UNV2411::Write(out_stream,aDataSet2411);
@@ -87,218 +98,183 @@ Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform()
       // Storing SMDS Edges
       MESSAGE("Perform - myMesh->NbEdges() = "<<myMesh->NbEdges());
       if(myMesh->NbEdges()){
-       SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
-       for(; anIter->more();){
-         const SMDS_MeshEdge* anElem = anIter->next();
-         TElementLab aLabel = anElem->GetID();
-         int aNbNodes = anElem->NbNodes();
-         TRecord aRec;
-         aRec.node_labels.reserve(aNbNodes);
-         SMDS_ElemIteratorPtr aNodesIter;
+        SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
+        while( anIter->more() )
+        {
+          const SMDS_MeshEdge* anElem = anIter->next();
+          int aNbNodes = anElem->NbNodes();
+          TRecord aRec;
+          aRec.label = anElem->GetID();
+          aRec.node_labels.reserve(aNbNodes);
+          SMDS_ElemIteratorPtr aNodesIter;
+          aNodesIter = anElem->nodesIteratorToUNV();
           if( anElem->IsQuadratic() ) {
-            aNodesIter = static_cast<const SMDS_QuadraticEdge* >
-              ( anElem )->interlacedNodesElemIterator();
             aRec.fe_descriptor_id = 22;
           } else {
-            aNodesIter = anElem->nodesIterator();
             aRec.fe_descriptor_id = 11;
           }
-         for(; aNodesIter->more();){
-           const SMDS_MeshElement* aNode = aNodesIter->next();
-           aRec.node_labels.push_back(aNode->GetID());
-         }
-         aDataSet2412.insert(TDataSet::value_type(aLabel,aRec));
-       }
-       MESSAGE("Perform - aDataSet2412.size() = "<<aDataSet2412.size());
+          while( aNodesIter->more())
+          {
+            const SMDS_MeshElement* aNode = aNodesIter->next();
+            aRec.node_labels.push_back(aNode->GetID());
+          }
+          aDataSet2412.push_back(aRec);
+        }
+        MESSAGE("Perform - aDataSet2412.size() = "<<aDataSet2412.size());
       }
 
       MESSAGE("Perform - myMesh->NbFaces() = "<<myMesh->NbFaces());
-      if(myMesh->NbFaces()){
-       SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
-       for(; anIter->more();){
-         const SMDS_MeshFace* anElem = anIter->next();
-         TElementLab aLabel = anElem->GetID();
-         int aNbNodes = anElem->NbNodes();
-         TRecord aRec;
-         aRec.node_labels.reserve(aNbNodes);
-         SMDS_ElemIteratorPtr aNodesIter;
-          if( anElem->IsQuadratic() )
-            aNodesIter = static_cast<const SMDS_QuadraticFaceOfNodes* >
-              ( anElem )->interlacedNodesElemIterator();
-          else
-            aNodesIter = anElem->nodesIterator();
-         for(; aNodesIter->more();){
-           const SMDS_MeshElement* aNode = aNodesIter->next();
-           aRec.node_labels.push_back(aNode->GetID());
-         }
-         switch(aNbNodes){
-         case 3:
-           aRec.fe_descriptor_id = 41;
-           break;
-         case 4:
-           aRec.fe_descriptor_id = 44;
-           break;
-         case 6:
-           aRec.fe_descriptor_id = 42;
-           break;
-         case 8:
-           aRec.fe_descriptor_id = 45;
-           break;
-         default:
-           continue;
-         }
-         aDataSet2412.insert(TDataSet::value_type(aLabel,aRec));
-       }
-       MESSAGE("Perform - aDataSet2412.size() = "<<aDataSet2412.size());
+      if ( myMesh->NbFaces() )
+      {
+        SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
+        while ( anIter->more())
+        {
+          const SMDS_MeshFace* anElem = anIter->next();
+          if ( anElem->IsPoly() ) continue;
+          int aNbNodes = anElem->NbNodes();
+          TRecord aRec;
+          aRec.label = anElem->GetID();
+          aRec.node_labels.reserve(aNbNodes);
+          SMDS_ElemIteratorPtr aNodesIter;
+          aNodesIter = anElem->nodesIteratorToUNV();
+          for(; aNodesIter->more();){
+            const SMDS_MeshElement* aNode = aNodesIter->next();
+            aRec.node_labels.push_back(aNode->GetID());
+          }
+          switch(aNbNodes){
+          case 3:
+            aRec.fe_descriptor_id = 41;
+            break;
+          case 4:
+            aRec.fe_descriptor_id = 44;
+            break;
+          case 6:
+            aRec.fe_descriptor_id = 42;
+            break;
+          case 8:
+            aRec.fe_descriptor_id = 45;
+            break;
+          case 9:
+            aRec.fe_descriptor_id = 45;
+            aRec.node_labels.resize( 8 );
+            break;
+          default:
+            continue;
+          }
+          aDataSet2412.push_back(aRec);
+        }
+        MESSAGE("Perform - aDataSet2412.size() = "<<aDataSet2412.size());
       }
 
       MESSAGE("Perform - myMesh->NbVolumes() = "<<myMesh->NbVolumes());
-      if(myMesh->NbVolumes()){
-       SMDS_VolumeIteratorPtr anIter = myMesh->volumesIterator();
-       for(; anIter->more();){
-         const SMDS_MeshVolume* anElem = anIter->next();
-         TElementLab aLabel = anElem->GetID();
-
-         int aNbNodes = anElem->NbNodes();
-         SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
+      if ( myMesh->NbVolumes() )
+      {
+        SMDS_VolumeIteratorPtr anIter = myMesh->volumesIterator();
+        while ( anIter->more())
+        {
+          const SMDS_MeshVolume* anElem = anIter->next();
+          int aNbNodes = anElem->NbNodes();
+          SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIteratorToUNV();
           if ( anElem->IsPoly() ) {
-            if ( const SMDS_PolyhedralVolumeOfNodes* ph =
-                 dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem))
+            continue;
+          }
+          int anId = -1;
+          switch(aNbNodes) {
+          case 4:  anId = 111; break;
+          case 6:  anId = 112; break;
+          case 8:  anId = 115; break;
+          case 10: anId = 118; break;
+          case 13: anId = 114; break;
+          case 15: anId = 113; break;
+          case 20:
+          case 27: anId = 116; aNbNodes = 20; break;
+          default:
+            continue;
+          }
+          if(anId>0){
+            TRecord aRec;
+            aRec.label = anElem->GetID();
+            aRec.fe_descriptor_id = anId;
+            aRec.node_labels.reserve(aNbNodes);
+            while ( aNodesIter->more() && aRec.node_labels.size() < aNbNodes )
             {
-              aNbNodes = ph->NbUniqueNodes();
-              aNodesIter = ph->uniqueNodesIterator();
+              const SMDS_MeshElement* aNode = aNodesIter->next();
+              aRec.node_labels.push_back(aNode->GetID());
             }
+            aDataSet2412.push_back(aRec);
           }
-         aConnect.resize(aNbNodes);
-         GetConnect(aNodesIter,aConnect);
-
-         int anId = -1;
-         int* aConn = NULL;
-         switch(aNbNodes){
-         case 4: {
-           static int anIds[] = {0,2,1,3};
-           aConn = anIds;
-           anId = 111;
-           break;
-         }
-         case 6: {
-           static int anIds[] = {0,2,1,3,5,4};
-           aConn = anIds;
-           anId = 112;
-           break;
-         }
-         case 8: {
-           static int anIds[] = {0,3,2,1,4,7,6,5};
-           aConn = anIds;
-           anId = 115;
-           break;
-         }
-         case 10: {
-           static int anIds[] = {0,4,2,9,5,3, 1,6,8, 7};
-           aConn = anIds;
-           anId = 118;
-           break;
-         }
-         case 13: {
-           static int anIds[] = {0,6,4,2,7,5,3,1,8,11,10,9,12};
-           aConn = anIds;
-           anId = 114;
-           break;
-         }
-         case 15: {
-           static int anIds[] = {0,4,2,9,13,11,5,3,1,14,12,10,6,8,7};
-           aConn = anIds;
-           anId = 113;
-           break;
-         }
-         case 20: {
-           static int anIds[] = {0,6, 4,2, 12,18,16,14,7, 5, 3, 1, 19,17,15,13,8, 11,10,9};
-           aConn = anIds;
-           anId = 116;
-           break;
-         }
-         default:
-           continue;
-         }
-         if(aConn){
-           TRecord aRec;
-           aRec.fe_descriptor_id = anId;
-           aRec.node_labels.resize(aNbNodes);
-           for(int aNodeId = 0; aNodeId < aNbNodes; aNodeId++){
-             aRec.node_labels[aConn[aNodeId]] = aConnect[aNodeId];
-           }
-           aDataSet2412.insert(TDataSet::value_type(aLabel,aRec));
-         }
-       }
-       MESSAGE("Perform - aDataSet2412.size() = "<<aDataSet2412.size());
+        }
+        MESSAGE("Perform - aDataSet2412.size() = "<<aDataSet2412.size());
       }
       UNV2412::Write(out_stream,aDataSet2412);
     }
     {
       using namespace UNV2417;
       if (myGroups.size() > 0) {
-       TDataSet aDataSet2417;
-       TGroupList::const_iterator aIter = myGroups.begin();
-       for (; aIter != myGroups.end(); aIter++) {
-         SMESHDS_GroupBase* aGroupDS = *aIter;
-         TRecord aRec;
-         aRec.GroupName = aGroupDS->GetStoreName();
+        TDataSet aDataSet2417;
+        TGroupList::const_iterator aIter = myGroups.begin();
+        for (; aIter != myGroups.end(); aIter++) {
+          SMESHDS_GroupBase* aGroupDS = *aIter;
+          TRecord aRec;
+          aRec.GroupName = aGroupDS->GetStoreName();
 
-         int i;
-         SMDS_ElemIteratorPtr aIter = aGroupDS->GetElements();
-         if (aGroupDS->GetType() == SMDSAbs_Node) {
-           aRec.NodeList.resize(aGroupDS->Extent());
-           i = 0;
-           while (aIter->more()) {
-             const SMDS_MeshElement* aElem = aIter->next();
-             aRec.NodeList[i] = aElem->GetID(); 
-             i++;
-           }
-         } else {
-           aRec.ElementList.resize(aGroupDS->Extent());
-           i = 0;
-           while (aIter->more()) {
-             const SMDS_MeshElement* aElem = aIter->next();
-             aRec.ElementList[i] = aElem->GetID(); 
-             i++;
-           }
-         }
-         aDataSet2417.insert(TDataSet::value_type(aGroupDS->GetID(), aRec));
-       }
-       UNV2417::Write(out_stream,aDataSet2417);
-       myGroups.clear();
+          int i;
+          SMDS_ElemIteratorPtr aIter = aGroupDS->GetElements();
+          if (aGroupDS->GetType() == SMDSAbs_Node) {
+            aRec.NodeList.resize(aGroupDS->Extent());
+            i = 0;
+            while (aIter->more()) {
+              const SMDS_MeshElement* aElem = aIter->next();
+              aRec.NodeList[i] = aElem->GetID(); 
+              i++;
+            }
+          } else {
+            aRec.ElementList.resize(aGroupDS->Extent());
+            i = 0;
+            while (aIter->more()) {
+              const SMDS_MeshElement* aElem = aIter->next();
+              aRec.ElementList[i] = aElem->GetID(); 
+              i++;
+            }
+          }
+          // 0019936: EDF 794 SMESH : Export UNV : Node color and group id
+          //aDataSet2417.insert(TDataSet::value_type(aGroupDS->GetID(), aRec));
+          aDataSet2417.insert(TDataSet::value_type(aGroupDS->GetID()+1, aRec));
+        }
+        UNV2417::Write(out_stream,aDataSet2417);
+        myGroups.clear();
       }
     }
     /*    {
       using namespace UNV2417;
       TDataSet aDataSet2417;
       for ( TGroupsMap::iterator it = myGroupsMap.begin(); it != myGroupsMap.end(); it++ ) {
-       SMESH_Group*       aGroup   = it->second;
-       SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS();
-       if ( aGroupDS ) {
-         TRecord aRec;
-         aRec.GroupName = aGroup->GetName();
-         int i;
-         SMDS_ElemIteratorPtr aIter = aGroupDS->GetElements();
-         if (aGroupDS->GetType() == SMDSAbs_Node) {
-           aRec.NodeList.resize(aGroupDS->Extent());
-           i = 0;
-           while (aIter->more()) {
-             const SMDS_MeshElement* aElem = aIter->next();
-             aRec.NodeList[i] = aElem->GetID(); 
-             i++;
-           }
-         } else {
-           aRec.ElementList.resize(aGroupDS->Extent());
-           i = 0;
-           while (aIter->more()) {
-             const SMDS_MeshElement* aElem = aIter->next();
-             aRec.ElementList[i] = aElem->GetID(); 
-             i++;
-           }
-         }
-         aDataSet2417.insert(TDataSet::value_type(aGroupDS->GetID(), aRec));
-       }
+        SMESH_Group*       aGroup   = it->second;
+        SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS();
+        if ( aGroupDS ) {
+          TRecord aRec;
+          aRec.GroupName = aGroup->GetName();
+          int i;
+          SMDS_ElemIteratorPtr aIter = aGroupDS->GetElements();
+          if (aGroupDS->GetType() == SMDSAbs_Node) {
+            aRec.NodeList.resize(aGroupDS->Extent());
+            i = 0;
+            while (aIter->more()) {
+              const SMDS_MeshElement* aElem = aIter->next();
+              aRec.NodeList[i] = aElem->GetID(); 
+              i++;
+            }
+          } else {
+            aRec.ElementList.resize(aGroupDS->Extent());
+            i = 0;
+            while (aIter->more()) {
+              const SMDS_MeshElement* aElem = aIter->next();
+              aRec.ElementList[i] = aElem->GetID(); 
+              i++;
+            }
+          }
+          aDataSet2417.insert(TDataSet::value_type(aGroupDS->GetID(), aRec));
+        }
       }
       UNV2417::Write(out_stream,aDataSet2417);
       }*/
index 6a76da655c0e778c10ba0ad9c9d783742b40a1cb..304af56cb5512908bb85858c7d0bd45a2b8f371c 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #ifndef _INCLUDE_DRIVERUNV_W_SMDS_MESH
 #define _INCLUDE_DRIVERUNV_W_SMDS_MESH
 
diff --git a/src/DriverUNV/DriverUNV_W_SMESHDS_Document.cxx b/src/DriverUNV/DriverUNV_W_SMESHDS_Document.cxx
deleted file mode 100644 (file)
index d01c261..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-#include "DriverUNV_W_SMESHDS_Document.h"
diff --git a/src/DriverUNV/DriverUNV_W_SMESHDS_Document.h b/src/DriverUNV/DriverUNV_W_SMESHDS_Document.h
deleted file mode 100644 (file)
index 8fa6bb0..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-#ifndef _INCLUDE_DRIVERUNV_W_SMESHDS_DOCUMENT
-#define _INCLUDE_DRIVERUNV_W_SMESHDS_DOCUMENT
-
-#include "SMESH_DriverUNV.hxx"
-
-#include "Driver_Document.h"
-
-class MESHDRIVERUNV_EXPORT DriverUNV_W_SMESHDS_Document : public Driver_Document 
-{};
-
-#endif
diff --git a/src/DriverUNV/DriverUNV_W_SMESHDS_Mesh.cxx b/src/DriverUNV/DriverUNV_W_SMESHDS_Mesh.cxx
deleted file mode 100644 (file)
index baf916e..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-#include "DriverUNV_W_SMESHDS_Mesh.h"
diff --git a/src/DriverUNV/DriverUNV_W_SMESHDS_Mesh.h b/src/DriverUNV/DriverUNV_W_SMESHDS_Mesh.h
deleted file mode 100644 (file)
index 260f08d..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-#ifndef _INCLUDE_DRIVERUNV_W_SMESHDS_MESH
-#define _INCLUDE_DRIVERUNV_W_SMESHDS_MESH
-
-#include "SMESH_DriverUNV.hxx"
-
-#include "Driver_SMESHDS_Mesh.h"
-
-class MESHDRIVERUNV_EXPORT DriverUNV_W_SMESHDS_Mesh: public Driver_SMESHDS_Mesh
-{};
-
-#endif
index 5b5775f6d1646e1d1df7979f52299581b13b7d15..0e05ad76112e69364e0e7129a873f35d5337cdb2 100644 (file)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  SMESH DriverUNV : driver to read and write 'unv' files
 #  File   : Makefile.in
 #  Author : Marc Tajchman (CEA)
@@ -31,32 +29,28 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am
 # header files 
 salomeinclude_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 \
        SMESH_DriverUNV.hxx
 
 # not-exported (internal) files
 EXTRA_DIST += \
+       UNV164_Structure.hxx \
        UNV2411_Structure.hxx \
        UNV2412_Structure.hxx \
        UNV2417_Structure.hxx \
+       UNV2420_Structure.hxx \
        UNV_Utilities.hxx
 
 # Libraries targets
 lib_LTLIBRARIES = libMeshDriverUNV.la
 dist_libMeshDriverUNV_la_SOURCES = \
        DriverUNV_R_SMDS_Mesh.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 \
        UNV_Utilities.cxx \
+       UNV164_Structure.cxx \
        UNV2411_Structure.cxx \
        UNV2412_Structure.cxx \
+       UNV2420_Structure.cxx \
        UNV2417_Structure.cxx
 
 # Executables targets
@@ -69,8 +63,7 @@ UNV_Test_SOURCES = \
 libMeshDriverUNV_la_CPPFLAGS = \
        $(KERNEL_CXXFLAGS) \
        $(CAS_CPPFLAGS) \
-       $(CORBA_CXXFLAGS) \
-        $(CORBA_INCLUDES) \
+        $(VTK_INCLUDES) \
        $(BOOST_CPPFLAGS) \
        -I$(srcdir)/../Driver \
        -I$(srcdir)/../SMDS \
@@ -78,6 +71,7 @@ libMeshDriverUNV_la_CPPFLAGS = \
 
 libMeshDriverUNV_la_LDFLAGS  = \
        ../Driver/libMeshDriver.la \
+       $(KERNEL_LDFLAGS) -lSALOMEBasics \
        $(CAS_KERNEL)
 
 UNV_Test_CPPFLAGS = \
index 106b6e93903d7875534148cbd03193368204da18..de65e4c3cdbd647ed1a1d59001833e75496e2b23 100755 (executable)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  File   : SMESH_DriverUNV.hxx
 //  Author : Alexander A. BORODIN
 //  Module : SMESH
@@ -27,7 +28,7 @@
 #define _SMESH_DriverUNV_HXX_
 
 #ifdef WNT
- #if defined MESHDRIVERUNV_EXPORTS
+ #if defined MESHDRIVERUNV_EXPORTS || defined MeshDriverUNV_EXPORTS
   #define MESHDRIVERUNV_EXPORT __declspec( dllexport )
  #else
   #define MESHDRIVERUNV_EXPORT __declspec( dllimport )
diff --git a/src/DriverUNV/UNV164_Structure.cxx b/src/DriverUNV/UNV164_Structure.cxx
new file mode 100644 (file)
index 0000000..0fff1bd
--- /dev/null
@@ -0,0 +1,83 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+#include "UNV164_Structure.hxx"
+#include "UNV_Utilities.hxx"
+
+#include <fstream>
+#include <cstdio>
+#include <cmath>
+
+using namespace std;
+using namespace UNV;
+using namespace UNV164;
+
+static string _label_dataset = "164";
+
+void UNV164::Read(std::ifstream& in_stream, TRecord& theUnitsRecord )
+{
+  if(!in_stream.good())
+    EXCEPTION(runtime_error,"ERROR: Input file not good.");
+
+  if(!beginning_of_dataset(in_stream,_label_dataset))
+    return;
+
+  string num_buf;
+  char line[theMaxLineLen];
+
+  in_stream >> theUnitsRecord.units_code;
+  in_stream.readsome( line, 20 );
+  theUnitsRecord.units_description = line;
+  in_stream >> theUnitsRecord.temp_mode;
+
+  for ( int i = 0; i < 4; i++ )
+  {
+    in_stream >> num_buf;
+    theUnitsRecord.factors[i] = D_to_e(num_buf);
+  }
+}
+
+void UNV164::Write(std::ofstream& out_stream)
+{
+  if(!out_stream.good())
+    EXCEPTION(runtime_error,"ERROR: Output file not good.");
+  
+  out_stream<<"    -1" << endl;
+  out_stream<<"  "<<_label_dataset << endl;
+
+  out_stream<<"         1  SI: Meter (newton)         2"                                    << endl;
+  out_stream<<"    1.0000000000000000E+0    1.0000000000000000E+0    1.0000000000000000E+0" << endl;
+  out_stream<<"    2.7314999999999998E+2"                                                   << endl;
+
+  out_stream<<"    -1"  << endl;
+}
+
+UNV164::TRecord::TRecord()
+{
+  units_code        = 1;
+  units_description = "SI: Meter (newton)";
+  temp_mode         = 2;
+  factors[0]        = 1.0;
+  factors[1]        = 1.0;
+  factors[2]        = 1.0;
+  factors[3]        = 273.15;
+}
diff --git a/src/DriverUNV/UNV164_Structure.hxx b/src/DriverUNV/UNV164_Structure.hxx
new file mode 100644 (file)
index 0000000..e01a6e3
--- /dev/null
@@ -0,0 +1,94 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+#ifndef UNV164_Structure_HeaderFile
+#define UNV164_Structure_HeaderFile
+
+// Universal Dataset Number: 164
+// Name:   Units
+// Status: Current
+// Owner:  General
+// Revision Date: 19-AUG-1987
+// -----------------------------------------------------------------------
+
+// Record 1:       FORMAT(I10,20A1,I10)
+//                 Field 1      -- units code
+//                                 = 1 - SI: Meter (newton)
+//                                 = 2 - BG: Foot (pound f)
+//                                 = 3 - MG: Meter (kilogram f)
+//                                 = 4 - BA: Foot (poundal)
+//                                 = 5 - MM: mm (milli newton)
+//                                 = 6 - CM: cm (centi newton)
+//                                 = 7 - IN: Inch (pound f)
+//                                 = 8 - GM: mm (kilogram f)
+//                                 = 9 - US: USER_DEFINED
+//                                 = 10- MN: mm (newton)
+//                 Field 2      -- units description (used for
+//                                 documentation only)
+//                 Field 3      -- temperature mode
+//                                 = 1 - absolute
+//                                 = 2 - relative
+// Record 2:       FORMAT(3D25.17)
+//                 Unit factors for converting universal file units to SI.
+//                 To convert from universal file units to SI divide by
+//                 the appropriate factor listed below.
+//                 Field 1      -- length
+//                 Field 2      -- force
+//                 Field 3      -- temperature
+//                 Field 4      -- temperature offset
+
+// Example:
+
+//     -1
+//    164
+//          2Foot (pound f)               2
+//   3.28083989501312334D+00  2.24808943099710480D-01  1.79999999999999999D+00
+//   4.59670000000000002D+02
+//     -1
+
+#include "SMESH_DriverUNV.hxx"
+
+#include <string>
+
+namespace UNV164
+{
+  enum { LENGTH_FACTOR, FORCE_FACTOR, TEMP_FACTOR, TEMP_OFFSET };
+
+  struct MESHDRIVERUNV_EXPORT TRecord
+  {
+    int         units_code;
+    std::string units_description;
+    int         temp_mode;
+    double      factors[4];
+    TRecord();
+  };
+  
+  MESHDRIVERUNV_EXPORT void
+  Read(std::ifstream& in_stream, TRecord& theUnitsRecord);
+
+  MESHDRIVERUNV_EXPORT void
+  Write(std::ofstream& out_stream );
+
+};
+
+
+#endif
index 1d3707c6e5278d1ad0abc42dcf64a66399d3d216..13bcecdbcfbc240e79398d81ddcfa73eabaf9196 100644 (file)
@@ -1,26 +1,27 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-#include <fstream>     
-#include <stdio.h>     
+
+#include <fstream>      
+#include <stdio.h>      
 
 #include "UNV2411_Structure.hxx"
 #include "UNV_Utilities.hxx"
@@ -29,18 +30,12 @@ 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)
+  exp_coord_sys_num(1),
+  disp_coord_sys_num(1),
+  color(11)//(0) -  0019936: EDF 794 SMESH : Export UNV : Node color and group id
 {}
 
 void UNV2411::Read(std::ifstream& in_stream, TDataSet& theDataSet)
@@ -59,16 +54,16 @@ void UNV2411::Read(std::ifstream& in_stream, TDataSet& theDataSet)
    * 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){
+  while ( !in_stream.eof() )
+  {
+    TRecord aRec;
+    in_stream >> aRec.label ;
+    if ( aRec.label == -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;
@@ -82,7 +77,7 @@ void UNV2411::Read(std::ifstream& in_stream, TDataSet& theDataSet)
       aRec.coord[d] = D_to_e(num_buf);
     }
 
-    theDataSet.insert(TDataSet::value_type(aLabel,aRec));
+    theDataSet.push_back(aRec);
   }
 }
 
@@ -99,22 +94,22 @@ void UNV2411::Write(std::ofstream& out_stream, const TDataSet& theDataSet)
   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;
+  for(; anIter != theDataSet.end(); anIter++)
+  {
+    const TRecord& aRec = *anIter;
     char buf[78];
     sprintf(buf, "%10d%10d%10d%10d\n", 
-           aLabel,
-           aRec.exp_coord_sys_num,
-           aRec.disp_coord_sys_num,
-           aRec.color);
+            aRec.label,
+            aRec.exp_coord_sys_num,
+            aRec.disp_coord_sys_num,
+            aRec.color);
     out_stream<<buf;
 
     // the coordinates
     sprintf(buf, "%25.16E%25.16E%25.16E\n", 
-           aRec.coord[0],
-           aRec.coord[1],
-           aRec.coord[2]);
+            aRec.coord[0],
+            aRec.coord[1],
+            aRec.coord[2]);
     out_stream<<buf;
   }
   
index 07195860ea1651a77c885a57c5d645e258e81181..99908b4b12f279e3997963e5d1e6a6b2e5d39f4f 100644 (file)
@@ -1,44 +1,47 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #ifndef UNV2411_Structure_HeaderFile
 #define UNV2411_Structure_HeaderFile
 
 #include "SMESH_DriverUNV.hxx"
 
-#include <map>
-#include <fstream>     
+#include <vector>
+#include <fstream>      
 
 namespace UNV2411{
   
+  typedef int TNodeLab; // type of node label
+
   struct MESHDRIVERUNV_EXPORT TRecord{
     TRecord();
+    TNodeLab label;
     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<TNodeLab,TRecord> TDataSet;
+  typedef std::vector<TRecord> TDataSet;
 
   MESHDRIVERUNV_EXPORT void
     Read(std::ifstream& in_stream, TDataSet& theDataSet);
index a522ecbc1d5c97ec7436be68ece031a6891d145c..0b4d2dfa34f7ace653db340c0277165687e207d8 100644 (file)
@@ -1,25 +1,26 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-#include <fstream>     
+
+#include <fstream>      
 #include <iomanip>
 
 #include "UNV2412_Structure.hxx"
@@ -29,21 +30,167 @@ using namespace std;
 using namespace UNV;
 using namespace UNV2412;
 
-#ifdef _DEBUG_
-static int MYDEBUG = 1;
-#else
-static int MYDEBUG = 0;
-#endif
+// Universal Dataset Number 2412
+
+// Name:   Elements
+// Status: Current
+// Owner:  Simulation
+// Revision Date: 14-AUG-1992
+// -----------------------------------------------------------------------
+// Record 1:        FORMAT(6I10)
+//                  Field 1       -- element label
+//                  Field 2       -- fe descriptor id
+//                  Field 3       -- physical property table number
+//                  Field 4       -- material property table number
+//                  Field 5       -- color
+//                  Field 6       -- number of nodes on element
+// Record 2:  *** FOR NON-BEAM ELEMENTS ***
+//                  FORMAT(8I10)
+//                  Fields 1-n    -- node labels defining element
+// Record 2:  *** FOR BEAM ELEMENTS ONLY ***
+//                  FORMAT(3I10)
+//                  Field 1       -- beam orientation node number
+//                  Field 2       -- beam fore-end cross section number
+//                  Field 3       -- beam  aft-end cross section number
+// Record 3:  *** FOR BEAM ELEMENTS ONLY ***
+//                  FORMAT(8I10)
+//                  Fields 1-n    -- node labels defining element
+// Records 1 and 2 are repeated for each non-beam element in the model.
+// Records 1 - 3 are repeated for each beam element in the model.
+// Example:
+//     -1
+//   2412
+//          1        11         1      5380         7         2
+//          0         1         1
+//          1         2
+//          2        21         2      5380         7         2
+//          0         1         1
+//          3         4
+//          3        22         3      5380         7         2
+//          0         1         2
+//          5         6
+//          6        91         6      5380         7         3
+//         11        18        12
+//          9        95         6      5380         7         8
+//         22        25        29        30        31        26        24        23
+//         14       136         8         0         7         2
+//         53        54
+//         36       116        16      5380         7        20
+//        152       159       168       167       166       158       150       151
+//        154       170       169       153       157       161       173       172
+//        171       160       155       156
+//     -1
+
+// FE Descriptor Id definitions
+// ____________________________
+
+//    11  Rod
+//    21  Linear beam
+//    22  Tapered beam
+//    23  Curved beam
+//    24  Parabolic beam
+//    31  Straight pipe
+//    32  Curved pipe
+//    41  Plane Stress Linear Triangle
+//    42  Plane Stress Parabolic Triangle
+//    43  Plane Stress Cubic Triangle
+//    44  Plane Stress Linear Quadrilateral
+//    45  Plane Stress Parabolic Quadrilateral
+//    46  Plane Strain Cubic Quadrilateral
+//    51  Plane Strain Linear Triangle
+//    52  Plane Strain Parabolic Triangle
+//    53  Plane Strain Cubic Triangle
+//    54  Plane Strain Linear Quadrilateral
+//    55  Plane Strain Parabolic Quadrilateral
+//    56  Plane Strain Cubic Quadrilateral
+//    61  Plate Linear Triangle
+//    62  Plate Parabolic Triangle
+//    63  Plate Cubic Triangle
+//    64  Plate Linear Quadrilateral
+//    65  Plate Parabolic Quadrilateral
+//    66  Plate Cubic Quadrilateral
+//    71  Membrane Linear Quadrilateral
+//    72  Membrane Parabolic Triangle
+//    73  Membrane Cubic Triangle
+//    74  Membrane Linear Triangle
+//    75  Membrane Parabolic Quadrilateral
+//    76  Membrane Cubic Quadrilateral
+//    81  Axisymetric Solid Linear Triangle
+//    82  Axisymetric Solid Parabolic Triangle
+//    84  Axisymetric Solid Linear Quadrilateral
+//    85  Axisymetric Solid Parabolic Quadrilateral
+//    91  Thin Shell Linear Triangle
+//    92  Thin Shell Parabolic Triangle
+//    93  Thin Shell Cubic Triangle
+//    94  Thin Shell Linear Quadrilateral
+//    95  Thin Shell Parabolic Quadrilateral
+//    96  Thin Shell Cubic Quadrilateral
+//    101 Thick Shell Linear Wedge
+//    102 Thick Shell Parabolic Wedge
+//    103 Thick Shell Cubic Wedge
+//    104 Thick Shell Linear Brick
+//    105 Thick Shell Parabolic Brick
+//    106 Thick Shell Cubic Brick
+//    111 Solid Linear Tetrahedron
+//    112 Solid Linear Wedge
+//    113 Solid Parabolic Wedge
+//    114 Solid Cubic Wedge
+//    115 Solid Linear Brick
+//    116 Solid Parabolic Brick
+//    117 Solid Cubic Brick
+//    118 Solid Parabolic Tetrahedron
+//    121 Rigid Bar
+//    122 Rigid Element
+//    136 Node To Node Translational Spring
+//    137 Node To Node Rotational Spring
+//    138 Node To Ground Translational Spring
+//    139 Node To Ground Rotational Spring
+//    141 Node To Node Damper
+//    142 Node To Gound Damper
+//    151 Node To Node Gap
+//    152 Node To Ground Gap
+//    161 Lumped Mass
+//    171 Axisymetric Linear Shell
+//    172 Axisymetric Parabolic Shell
+//    181 Constraint
+//    191 Plastic Cold Runner
+//    192 Plastic Hot Runner
+//    193 Plastic Water Line
+//    194 Plastic Fountain
+//    195 Plastic Baffle
+//    196 Plastic Rod Heater
+//    201 Linear node-to-node interface
+//    202 Linear edge-to-edge interface
+//    203 Parabolic edge-to-edge interface
+//    204 Linear face-to-face interface
+//    208 Parabolic face-to-face interface
+//    212 Linear axisymmetric interface
+//    213 Parabolic axisymmetric interface
+//    221 Linear rigid surface
+//    222 Parabolic rigin surface
+//    231 Axisymetric linear rigid surface
+//    232 Axisymentric parabolic rigid surface
+
+
 
 static string _label_dataset = "2412";
 
 UNV2412::TRecord::TRecord():
+  label(-1),
+  fe_descriptor_id(-1),
   phys_prop_tab_num(2),
   mat_prop_tab_num(1),
   color(7),
   beam_orientation(0),
-  beam_fore_end(0),
-  beam_aft_end(0)
+  beam_fore_end(1), // default values
+  beam_aft_end(1) // default values
 {}
 
 void UNV2412::Read(std::ifstream& in_stream, TDataSet& theDataSet)
@@ -58,16 +205,15 @@ void UNV2412::Read(std::ifstream& in_stream, TDataSet& theDataSet)
   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){
+  TRecord aRec;
+  while( !in_stream.eof())
+  {
+    in_stream >> aRec.label ;
+    if (aRec.label == -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;
@@ -81,12 +227,11 @@ void UNV2412::Read(std::ifstream& in_stream, TDataSet& theDataSet)
     }
 
     aRec.node_labels.resize(n_nodes);
-    for(int j=0; j < n_nodes; j++){
+    for(int j=0; j < n_nodes; j++)
       // read node labels
       in_stream>>aRec.node_labels[j];             
-    }
 
-    theDataSet.insert(TDataSet::value_type(aLabel,aRec));
+    theDataSet.push_back(aRec);
   }
 
 }
@@ -104,17 +249,18 @@ void UNV2412::Write(std::ofstream& out_stream, const TDataSet& theDataSet)
   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<<std::setw(10)<<aLabel;  /* element ID */
+  for(; anIter != theDataSet.end(); anIter++)
+  {
+    const TRecord& aRec = *anIter;
+    out_stream<<std::setw(10)<<aRec.label;  /* element ID */
     out_stream<<std::setw(10)<<aRec.fe_descriptor_id;  /* type of element */
     out_stream<<std::setw(10)<<aRec.phys_prop_tab_num;
     out_stream<<std::setw(10)<<aRec.mat_prop_tab_num;
     out_stream<<std::setw(10)<<aRec.color;
     out_stream<<std::setw(10)<<aRec.node_labels.size()<<std::endl;  /* No. of nodes per element */
 
-    if(IsBeam(aRec.fe_descriptor_id)){
+    if(IsBeam(aRec.fe_descriptor_id))
+    {
       out_stream<<std::setw(10)<<aRec.beam_orientation;
       out_stream<<std::setw(10)<<aRec.beam_fore_end;
       out_stream<<std::setw(10)<<aRec.beam_aft_end<<std::endl;
@@ -125,11 +271,11 @@ void UNV2412::Write(std::ofstream& out_stream, const TDataSet& theDataSet)
     for(int i = 0, k = 0; i < iEnd; i++){
       int jEnd = n_nodes - 8*(i+1);
       if(jEnd < 0) 
-       jEnd = 8 + jEnd;
+        jEnd = 8 + jEnd;
       else
-       jEnd = 8;
+        jEnd = 8;
       for(int j = 0; j < jEnd ; k++, j++){
-       out_stream<<std::setw(10)<<aRec.node_labels[k];
+        out_stream<<std::setw(10)<<aRec.node_labels[k];
       }
       out_stream<<std::endl;
     }
@@ -157,31 +303,34 @@ bool UNV2412::IsBeam(int theFeDescriptorId){
 
 
 bool UNV2412::IsFace(int theFeDescriptorId){
-  switch (theFeDescriptorId){
+  return ( 41 <= theFeDescriptorId && theFeDescriptorId <= 96 );
+//   switch (theFeDescriptorId){
     
-  case 71: // TRI3
-  case 72:
-  case 74:
+//   case 71: // TRI3
+//   case 72:
+//   case 74:
 
-  case 41: // Plane Stress Linear Triangle - TRI3
-  case 91: // Thin Shell Linear Triangle - TRI3
+//   case 41: // Plane Stress Linear Triangle - TRI3
+//   case 51: // Plane Strain Linear Triangle
+//   case 91: // Thin Shell Linear Triangle - TRI3
 
-  case 42: // Plane Stress Quadratic Triangle - TRI6
-  case 92: // Thin Shell Quadratic Triangle - TRI6
+//   case 42: // Plane Stress Quadratic Triangle - TRI6
+//   case 52: // Plane Strain Parabolic Triangle
+//   case 92: // Thin Shell Quadratic Triangle - TRI6
 
-  case 43: // Plane Stress Cubic Triangle
+//   case 43: // Plane Stress Cubic Triangle
 
-  case 44: // Plane Stress Linear Quadrilateral - QUAD4
-  case 94: // Thin Shell   Linear Quadrilateral -  QUAD4
+//   case 44: // Plane Stress Linear Quadrilateral - QUAD4
+//   case 94: // Thin Shell   Linear Quadrilateral -  QUAD4
 
-  case 45: // Plane Stress Quadratic Quadrilateral - QUAD8
-  case 95: // Thin Shell   Quadratic Quadrilateral - QUAD8
+//   case 45: // Plane Stress Quadratic Quadrilateral - QUAD8
+//   case 95: // Thin Shell   Quadratic Quadrilateral - QUAD8
 
-  case 46: // Plane Stress Cubic Quadrilateral
+//   case 46: // Plane Stress Cubic Quadrilateral
 
-    return true;
-  }
-  return false;
+//     return true;
+//   }
+//  return false;
 }
 
 
index 5c6a532f1aa6429e0cbfb2cae1abb6b84d9383ac..ce15c79bf3964def542f170852a603309ed0855b 100644 (file)
@@ -1,41 +1,43 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #ifndef UNV2412_Structure_HeaderFile
 #define UNV2412_Structure_HeaderFile
 
 #include "SMESH_DriverUNV.hxx"
 
-#include <map>
 #include <vector>
-#include <fstream>     
-
+#include <fstream>
 
 namespace UNV2412{
   
   typedef std::vector<int> TNodeLabels; // Nodal connectivities
+  typedef int TElementLab; // type of element label
 
-  struct MESHDRIVERUNV_EXPORT TRecord{
+  struct MESHDRIVERUNV_EXPORT TRecord
+  {
     TRecord();
 
+    TElementLab label;
     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
@@ -48,8 +50,7 @@ namespace UNV2412{
     int beam_aft_end;  // beam  aft-end cross section number
   };
   
-  typedef int TElementLab; // type of element label
-  typedef std::map<TElementLab,TRecord> TDataSet;
+  typedef std::vector<TRecord> TDataSet;
 
   MESHDRIVERUNV_EXPORT void
     Read(std::ifstream& in_stream, TDataSet& theDataSet);
index 0e836f755a7e9afd84a66b1bf79cec964d3b3c25..781d5991407c525716c7055305b7116f32060886 100644 (file)
@@ -1,43 +1,37 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #include "UNV2417_Structure.hxx"
 #include "UNV_Utilities.hxx"
 
-#include <fstream>     
+#include <fstream>      
 #include <iomanip>
 
 using namespace std;
 using namespace UNV;
 using namespace UNV2417;
 
-#ifdef _DEBUG_
-static int MYDEBUG = 0;
-#else
-static int MYDEBUG = 0;
-#endif
-
-
 static string _group_labels[] = {"2417", "2429", "2430", "2432",
-                                "2435", "2452", "2467", "2477"};
+                                 "2435", "2452", "2467", "2477"};
 #define NBGROUP 8
 
 static string _label_dataset = "2467";
@@ -55,7 +49,7 @@ void UNV2417::Read(std::ifstream& in_stream, TDataSet& theDataSet)
      * 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_stream.eof() ){    
+    while( ((olds != "-1") || (news == "-1") ) && !in_stream.eof() ){     
       olds = news;
       in_stream >> news;
     }
@@ -63,7 +57,7 @@ void UNV2417::Read(std::ifstream& in_stream, TDataSet& theDataSet)
       return;
     for (int i = 0; i < NBGROUP; i++) {
       if (news == _group_labels[i]) {
-       ReadGroup(news, in_stream, theDataSet);
+        ReadGroup(news, in_stream, theDataSet);
       }
     }
   }
@@ -102,23 +96,23 @@ void UNV2417::ReadGroup(const std::string& myGroupLabel, std::ifstream& in_strea
       in_stream>>aElType;
       in_stream>>aElId;
       if ((myGroupLabel.compare("2435") == 0) ||
-         (myGroupLabel.compare("2452") == 0) ||
-         (myGroupLabel.compare("2467") == 0) ||
-         (myGroupLabel.compare("2477") == 0)) {
-       in_stream>>aTmp;
-       in_stream>>aTmp;
+          (myGroupLabel.compare("2452") == 0) ||
+          (myGroupLabel.compare("2467") == 0) ||
+          (myGroupLabel.compare("2477") == 0)) {
+        in_stream>>aTmp;
+        in_stream>>aTmp;
       }
       switch (aElType) {
       case 7: // Nodes
-       aNum = aRec.NodeList.size();
-       aRec.NodeList.resize(aNum + 1);
-       aRec.NodeList[aNum] = aElId;
-       break;
+        aNum = aRec.NodeList.size();
+        aRec.NodeList.resize(aNum + 1);
+        aRec.NodeList[aNum] = aElId;
+        break;
       case 8: // Elements
-       aNum = aRec.ElementList.size();
-       aRec.ElementList.resize(aNum + 1);
-       aRec.ElementList[aNum] = aElId;
-       break;
+        aNum = aRec.ElementList.size();
+        aRec.ElementList.resize(aNum + 1);
+        aRec.ElementList[aNum] = aElId;
+        break;
       }
     }
     theDataSet.insert(TDataSet::value_type(aId,aRec));
@@ -160,8 +154,8 @@ void UNV2417::Write(std::ofstream& out_stream, const TDataSet& theDataSet)
     int i;
     for (i = 0; i < aNbNodes; i++) {
       if (aRow == 2) {
-       out_stream<<std::endl; 
-       aRow = 0;
+        out_stream<<std::endl; 
+        aRow = 0;
       }
       out_stream<<std::setw(10)<<7;
       out_stream<<std::setw(10)<<aRec.NodeList[i];
@@ -171,8 +165,8 @@ void UNV2417::Write(std::ofstream& out_stream, const TDataSet& theDataSet)
     }
     for (i = 0; i < aNbElements; i++) {
       if (aRow == 2) {
-       out_stream<<std::endl; 
-       aRow = 0;
+        out_stream<<std::endl; 
+        aRow = 0;
       }
       out_stream<<std::setw(10)<<8;
       out_stream<<std::setw(10)<<aRec.ElementList[i];
index 2f7999012504374258fbe50bfbde5ad9166e8875..7548846ab66c21bf727e76c8413d1b7322914c9e 100644 (file)
@@ -1,31 +1,32 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #ifndef UNV2417_Structure_HeaderFile
 #define UNV2417_Structure_HeaderFile
 
 #include <map>
 #include <vector>
-#include <fstream>     
-#include <string>      
+#include <fstream>      
+#include <string>       
 
 
 namespace UNV2417{
diff --git a/src/DriverUNV/UNV2420_Structure.cxx b/src/DriverUNV/UNV2420_Structure.cxx
new file mode 100644 (file)
index 0000000..7d9bb67
--- /dev/null
@@ -0,0 +1,152 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+#include "UNV2420_Structure.hxx"
+#include "UNV_Utilities.hxx"
+
+#include <fstream>
+#include <cstdio>
+#include <cmath>
+
+using namespace std;
+using namespace UNV;
+using namespace UNV2420;
+
+static string _label_dataset = "2420";
+
+void UNV2420::Read(std::ifstream& in_stream,
+                   std::string&   part_name, // can re-store a mesh name
+                   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))
+    return;
+
+  string num_buf;
+  int part_uid;
+
+  in_stream >> part_uid; // Record 1
+  part_name = read_line( in_stream );  // Record 2
+
+  while ( !in_stream.eof() )
+  {
+    TRecord aRec;
+
+    // Record 3
+    in_stream >> aRec.coord_sys_label;
+    if ( aRec.coord_sys_label == -1 ) // end of dataset is reached
+      break;
+    in_stream >> aRec.coord_sys_type;
+    in_stream >> aRec.coord_sys_color;
+
+    aRec.coord_sys_name = read_line( in_stream ); // Record 4
+
+    // Records 5-8: rows of Transformation Matrix
+    for ( int row = 0; row < 4; ++row )
+      for ( int i = 0; i < 3; i++ )
+      {
+        in_stream >> num_buf;
+        aRec.matrix[row][i] = D_to_e(num_buf);
+      }
+    // Store a CS data only if it requires conversion into the global Cartesian CS
+    if ( aRec.coord_sys_type != 0 || !aRec.isIdentityMatrix() ) // 0 - Cartesian CS
+      theDataSet.push_back( aRec );
+  }
+}
+
+
+void UNV2420::Write(std::ofstream&     out_stream,
+                    const std::string& part_name)
+//                    const TDataSet& theDataSet)
+{
+  if(!out_stream.good())
+    EXCEPTION(runtime_error,"ERROR: Output file not good.");
+  
+  out_stream<<"    -1"  << endl;
+  out_stream<<"  "<<_label_dataset << endl;
+
+  out_stream<<"         1"                     << endl; // R1: Part UID
+  if ( part_name.empty() )
+    out_stream<<"SMESH_Mesh"                   << endl; // R2: Part Name
+  else
+    out_stream<< part_name                     << endl;
+  out_stream<<"         1         0         0" << endl; // R3: Label, Type, Color
+
+  out_stream<<"Global Cartesian Coordinate System" << endl; // R4: Name
+  out_stream<<"    1.0000000000000000E+0    0.0000000000000000E+0    0.0000000000000000E+0" << endl;
+  out_stream<<"    0.0000000000000000E+0    1.0000000000000000E+0    0.0000000000000000E+0" << endl;
+  out_stream<<"    0.0000000000000000E+0    0.0000000000000000E+0    1.0000000000000000E+0" << endl;
+  out_stream<<"    0.0000000000000000E+0    0.0000000000000000E+0    0.0000000000000000E+0" << endl;
+
+  out_stream<<"    -1"  << endl;
+}
+
+
+bool UNV2420::TRecord::isIdentityMatrix() const
+{
+  bool isIdentity = true;
+  for ( int row = 0; row < 4 && isIdentity; ++row )
+    for ( int i = 0; i < 3; i++ )
+    {
+      if ( matrix[row][i] != ( row==i ? 1. : 0. ))
+      {
+        isIdentity = false;
+        break;
+      }
+    }
+  return isIdentity;
+}
+
+void UNV2420::TRecord::ApplyMatrix( double* c ) const
+{
+  const double x = matrix[0][0] * c[0] + matrix[0][1] * c[1] + matrix[0][2] * c[2];
+  const double y = matrix[1][0] * c[0] + matrix[1][1] * c[1] + matrix[1][2] * c[2];
+  const double z = matrix[2][0] * c[0] + matrix[2][1] * c[1] + matrix[2][2] * c[2];
+  c[0] = x + matrix[3][0];
+  c[1] = y + matrix[3][1];
+  c[2] = z + matrix[3][2];
+}
+
+void UNV2420::TRecord::FromCylindricalCS( double* coords )
+{
+  const double x = coords[0] * cos( coords[1] );
+  const double y = coords[0] * sin( coords[1] );
+  coords[0] = x;
+  coords[1] = y;
+}
+
+void UNV2420::TRecord::FromSphericalCS  ( double* coords )
+{
+  const double sin2 = sin( coords[2] );
+  const double x = coords[0] * cos( coords[1] ) * sin2;
+  const double y = coords[0] * sin( coords[1] ) * sin2;
+  const double z = coords[0] * cos( coords[2] );
+  coords[0] = x;
+  coords[1] = y;
+  coords[2] = z;
+}
diff --git a/src/DriverUNV/UNV2420_Structure.hxx b/src/DriverUNV/UNV2420_Structure.hxx
new file mode 100644 (file)
index 0000000..491c17a
--- /dev/null
@@ -0,0 +1,119 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+#ifndef UNV2420_Structure_HeaderFile
+#define UNV2420_Structure_HeaderFile
+
+// Name:   Coordinate Systems
+// -----------------------------------------------------------------------
+
+// Record 1:        FORMAT (1I10)
+//                  Field 1       -- Part UID
+
+// Record 2:        FORMAT (40A2)
+//                  Field 1       -- Part Name
+
+// Record 3:        FORMAT (3I10)
+//                  Field 1       -- Coordinate System Label
+//                  Field 2       -- Coordinate System Type
+//                                   = 0, Cartesian
+//                                   = 1, Cylindrical
+//                                   = 2, Spherical
+//                  Field 3       -- Coordinate System Color
+
+// Record 4:        FORMAT (40A2)
+//                  Field 1       -- Coordinate System Name
+
+// Record 5:        FORMAT (1P3D25.16)
+//                  Field 1-3     -- Transformation Matrix Row 1
+
+// Record 6:        FORMAT (1P3D25.16)
+//                  Field 1-3     -- Transformation Matrix Row 2
+
+// Record 7:        FORMAT (1P3D25.16)
+//                  Field 1-3     -- Transformation Matrix Row 3
+
+// Record 8:        FORMAT (1P3D25.16)
+//                  Field 1-3     -- Transformation Matrix Row 4
+
+// Records 3 thru 8 are repeated for each Coordinate System in the Part.
+
+// Example:
+//     -1
+//   2420
+//        100
+// Untitled
+//          6         1        15
+// FEMAP Global Cylindrical (6)
+//     1.0000000000000000E+0    0.0000000000000000E+0    0.0000000000000000E+0
+//     0.0000000000000000E+0    1.0000000000000000E+0    0.0000000000000000E+0
+//     0.0000000000000000E+0    0.0000000000000000E+0    1.0000000000000000E+0
+//     0.0000000000000000E+0    0.0000000000000000E+0    0.0000000000000000E+0
+//          7         2        15
+// Coordinate System 4
+//     1.0000000000000000E+0    0.0000000000000000E+0    0.0000000000000000E+0
+//     0.0000000000000000E+0    1.0000000000000000E+0    0.0000000000000000E+0
+//     0.0000000000000000E+0    0.0000000000000000E+0    1.0000000000000000E+0
+//     0.0000000000000000E+0    0.0000000000000000E+0    0.0000000000000000E+0
+//     -1
+
+#include "SMESH_DriverUNV.hxx"
+
+#include <string>
+#include <vector>
+
+namespace UNV2420
+{
+  enum { Cartesian=0, Cylindrical, Spherical };
+
+  typedef int TCSLabel; // type of coord system label
+
+  struct MESHDRIVERUNV_EXPORT TRecord
+  {
+    TCSLabel    coord_sys_label; 
+    int         coord_sys_type;  // { Cartesian=0, Cylindrical, Spherical }
+    int         coord_sys_color;
+    std::string coord_sys_name;
+    double      matrix[4][3];
+
+    bool        isIdentityMatrix() const;
+    void        ApplyMatrix      ( double* coords ) const;
+    static void FromCylindricalCS( double* coords );
+    static void FromSphericalCS  ( double* coords );
+  };
+  
+  typedef std::vector<TRecord> TDataSet;
+
+  MESHDRIVERUNV_EXPORT void
+  Read(std::ifstream& in_stream,
+       std::string&   part_name, // can re-store a mesh name
+       TDataSet&      theDataSet);
+
+  MESHDRIVERUNV_EXPORT void
+  Write(std::ofstream&     out_stream,
+        const std::string& part_name); // can store a mesh name
+  //    const TDataSet&    theDataSet);
+
+};
+
+
+#endif
index 0e274fd2358656ee1dd2f47a79bdb38db0f536e8..281ccacd9ea625dc9a055c5a9c85ae2dfc27002c 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #include "UNV2411_Structure.hxx"
 #include "UNV2412_Structure.hxx"
 #include "UNV_Utilities.hxx"
 
 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);
 
index 2928bd1003f8b2b567f3c278b50136b1b4189624..50bc99a8fd3bae27844d6cd81d36ef1290c3acef 100644 (file)
@@ -1,34 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #include "UNV_Utilities.hxx"
 
 using namespace std;
 
-#ifdef _DEBUG_
-static int MYDEBUG = 1;
-#else
-static int MYDEBUG = 0;
-#endif
-
 
 int UNV::PrefixPrinter::myCounter = 0;
 
index e53f75d95da120a9dd3cff3c5cb87e9117a0e313..96a418716419d151d72f722a568f02a2e77609d2 100644 (file)
@@ -1,31 +1,32 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #ifndef MED_Utilities_HeaderFile
 #define MED_Utilities_HeaderFile
 
 #include "SMESH_DriverUNV.hxx"
 
-#include <iostream>    
-#include <sstream>     
+#include <iostream>     
+#include <sstream>      
 #include <fstream>
 #include <string>
 #include <stdexcept>
@@ -35,6 +36,8 @@
 namespace UNV{
   using namespace std;
 
+  const size_t theMaxLineLen = 80;
+
   class MESHDRIVERUNV_EXPORT PrefixPrinter{
     static int myCounter;
   public:
@@ -56,20 +59,24 @@ namespace UNV{
     
     std::string olds, news;
     
+    in_file.seekg(0);
     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;
+      while( ((olds != "-1") || (news == "-1") ) && !in_file.eof() ){     
+        olds = news;
+        in_file >> news;
       }
       if(in_file.eof())
-       return false;
+      {
+        in_file.clear();
+        return false;
+      }
       if (news == ds_name)
-       return true;
+        return true;
     }
     // should never end up here
     return false;
@@ -112,6 +119,25 @@ namespace UNV{
     return (olds == "    -1");
   }
 
+  /*!
+   * \brief reads a whole line
+   *  \param in_stream - source stream
+   *  \param next - if true, first reads the current line up to the end
+   *  which is necessary after reading using >> operator
+   *  \retval std::string - the result line
+   */
+  inline std::string read_line(std::ifstream& in_stream, const bool next=true)
+  {
+    char line[theMaxLineLen];
+    in_stream.getline( line, theMaxLineLen );
+    if ( next )
+      in_stream.getline( line, theMaxLineLen );
+
+    std::string resLine = line;
+    if ( resLine.size() > 0 && resLine[ resLine.size()-1 ] == '\r' )
+      resLine.resize( resLine.size()-1 );
+    return line;
+  }
 };
 
 
index 1f0e496964a609a82b6c53cee90899ba52f41f17..51b458db3f8b48bf6af6e13c6d49c0da2348f9db 100644 (file)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  File   : Makefile.in
 #  Author : 
 #  Modified by : Alexander BORODIN (OCN) - autotools usage
@@ -43,6 +41,7 @@ libMEFISTO2D_la_CPPFLAGS = \
        @PLATFORM_INCLUDES@
 
 libMEFISTO2D_la_LDFLAGS = \
+       $(CAS_LDFLAGS) -lTKernel -lTKMath \
        $(KERNEL_LDFLAGS) -lSALOMELocalTrace \
        $(FCLIBS)
 
@@ -52,3 +51,6 @@ libMEFISTO2D_la_LDFLAGS = \
 #libMEFISTO2D_la_LDFLAGS += -lg2c
 #endif
 
+OBSOLETE_FILES = areteideale.f
+
+EXTRA_DIST += $(OBSOLETE_FILES)
index 63c6ec26640f6493d403fe2a6daac90852c03eb4..227d833cfeb050e1368883b085dea7b7af056cd4 100755 (executable)
@@ -1,24 +1,22 @@
 //  MEFISTO :  library to compute 2D triangulation from segmented boundaries
 //
-//  Copyright (C) 2006  Laboratoire J.-L. Lions UPMC Paris
-// 
-//  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.ann.jussieu.fr/~perronne or email Perronnet@ann.jussieu.fr
-//                                          or email Hecht@ann.jussieu.fr
+// Copyright (C) 2006-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
+// 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.com
 //
 //  File   : Rn.h
 //  Module : SMESH
@@ -172,8 +170,8 @@ public:
 
   bool  DansPave( R3 & xyzMin, R3 & xyzMax )
     { return xyzMin.x<=x && x<=xyzMax.x &&
-            xyzMin.y<=y && y<=xyzMax.y &&
-            xyzMin.z<=z && z<=xyzMax.z; }
+             xyzMin.y<=y && y<=xyzMax.y &&
+             xyzMin.z<=z && z<=xyzMax.z; }
 };
 
 //la classe R4
index b2559e323898bd711f688647e102fd96e7eaa46e..619a3ebcbd312b7fc11d32a0c93767e1fd205ccd 100755 (executable)
@@ -1,23 +1,23 @@
 //  MEFISTO2: a library to compute 2D triangulation from segmented boundaries
 //
 //
-//  Copyright (C) 2006  Laboratoire J.-L. Lions UPMC Paris
+// Copyright (C) 2006-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  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 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.
+// 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
+// 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.ann.jussieu.fr/~perronne or email Perronnet@ann.jussieu.fr
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 //  File   : aptrte.cxx   le C++ de l'appel du trianguleur plan
 //  Module : SMESH
@@ -36,7 +36,10 @@ extern "C"
   MEFISTO2D_EXPORT   
     R
   #ifdef WIN32
+  #ifdef F2C_BUILD
+  #else
       __stdcall
+  #endif
   #endif
       areteideale()//( R3 xyz, R3 direction )
   {
@@ -50,7 +53,14 @@ extern "C"
 
 static double cpunew, cpuold=0;
 
-void tempscpu_( double & tempsec )
+void
+#ifdef WIN32
+#ifdef F2C_BUILD
+#else
+              __stdcall
+#endif
+#endif
+tempscpu_( double & tempsec )
 //Retourne le temps CPU utilise en secondes
 {  
   tempsec = ( (double) clock() ) / CLOCKS_PER_SEC;
@@ -58,7 +68,14 @@ void tempscpu_( double & tempsec )
 }
 
 
-void deltacpu_( R & dtcpu )
+void
+#ifdef WIN32
+#ifdef F2C_BUILD
+#else
+              __stdcall
+#endif
+#endif
+deltacpu_( R & dtcpu )
 //Retourne le temps CPU utilise en secondes depuis le precedent appel
 {
   tempscpu_( cpunew );
@@ -70,11 +87,11 @@ void deltacpu_( R & dtcpu )
 
 
 void  aptrte( Z   nutysu, R      aretmx,
-             Z   nblf,   Z  *   nudslf,  R2 * uvslf,
-             Z   nbpti,  R2 *   uvpti,
-             Z & nbst,   R2 * & uvst,
-             Z & nbt,    Z  * & nust,
-             Z & ierr )
+              Z   nblf,   Z  *   nudslf,  R2 * uvslf,
+              Z   nbpti,  R2 *   uvpti,
+              Z & nbst,   R2 * & uvst,
+              Z & nbt,    Z  * & nust,
+              Z & ierr )
 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 // but : appel de la triangulation par un arbre-4 recouvrant
 // ----- de triangles equilateraux
@@ -124,7 +141,7 @@ void  aptrte( Z   nutysu, R      aretmx,
                  //no st1, st2, st3, 0 (non quadrangle)
 
   R  d, tcpu=0;
-  R3 direction=R3(0,0,0);  //direction pour areteideale() inactive ici!
+//  R3 direction=R3(0,0,0);  //direction pour areteideale() inactive ici!
   Z  nbarfr=nudslf[nblf];  //nombre total d'aretes des lignes fermees
   Z  mxtrou = Max( 1024, nblf );  //nombre maximal de trous dans la surface
 
@@ -167,7 +184,7 @@ void  aptrte( Z   nutysu, R      aretmx,
   mxsomm = Max( 20000, 64*nbpti+i*i );
   MESSAGE( "APTRTE: Debut de la triangulation plane avec " );
   MESSAGE( "nutysu=" << nutysu << "  aretmx=" << aretmx
-          << "  mxsomm=" << mxsomm );
+           << "  mxsomm=" << mxsomm );
   MESSAGE( nbarfr << " sommets sur la frontiere et " << nbpti << " points internes");
 
  NEWDEPART:
@@ -230,7 +247,7 @@ void  aptrte( Z   nutysu, R      aretmx,
     mnpxyd[ns0].y = uvslf[ns0].y;
     mnpxyd[ns0].z = areteideale();//( mnpxyd[ns0], direction );
 //     MESSAGE("Sommet " << ns0 << ": " << mnpxyd[ns0].x
-//      << " " << mnpxyd[ns0].y << " longueur arete=" << mnpxyd[ns0].z);
+//       << " " << mnpxyd[ns0].y << " longueur arete=" << mnpxyd[ns0].z);
 
     //carre de la longueur de l'arete 1 de la ligne fermee n
     d = pow( uvslf[ns0+1].x - uvslf[ns0].x, 2 ) 
@@ -251,8 +268,8 @@ void  aptrte( Z   nutysu, R      aretmx,
      //le numero n de la ligne du sommet et son numero ns1 dans la ligne
     mnslig[ns0-1] = 1000000 * n + ns1-nudslf[n-1];
     fasoar( ns1, ns2, moins1, moins1, n,
-            mosoar, mxsoar, n1soar, mnsoar, mnarst,
-            noar0,  ierr );
+             mosoar, mxsoar, n1soar, mnsoar, mnarst,
+             noar0,  ierr );
     //pas de test sur ierr car pas de saturation possible a ce niveau
 
     //le pointeur dans le hachage sur la premiere arete de la ligne fermee n
@@ -269,11 +286,11 @@ void  aptrte( Z   nutysu, R      aretmx,
     {
       ns1 = ns2; //le numero de l'arete et le numero du premier sommet de l'arete
       if( i < nbarli )
-       //nbs+1 est le 2-eme sommet de l'arete i de la ligne fermee n
-       ns2 = ns1+1;
+        //nbs+1 est le 2-eme sommet de l'arete i de la ligne fermee n
+        ns2 = ns1+1;
       else
-       //le 2-eme sommet de la derniere arete est le premier sommet de la ligne
-       ns2 = ns0;
+        //le 2-eme sommet de la derniere arete est le premier sommet de la ligne
+        ns2 = ns0;
 
       //l'arete precedente est dotee de sa suivante:celle cree ensuite
       //les 2 coordonnees du sommet ns2 de la ligne
@@ -285,7 +302,7 @@ void  aptrte( Z   nutysu, R      aretmx,
       mnpxyd[ns].y = uvslf[ns].y;
       mnpxyd[ns].z = areteideale();//( mnpxyd[ns], direction );
 //       MESSAGE("Sommet " << ns << ": " << mnpxyd[ns].x
-//        << " " << mnpxyd[ns].y << " longueur arete=" << mnpxyd[ns].z);
+//         << " " << mnpxyd[ns].y << " longueur arete=" << mnpxyd[ns].z);
 
       //carre de la longueur de l'arete
       d = pow( uvslf[ns2-1].x - uvslf[ns1-1].x, 2) 
@@ -306,8 +323,8 @@ void  aptrte( Z   nutysu, R      aretmx,
 
       //ajout de l'arete dans la liste
       fasoar( ns1, ns2, moins1, moins1, n,
-              mosoar, mxsoar, n1soar, mnsoar,
-              mnarst, noar, ierr );
+               mosoar, mxsoar, n1soar, mnsoar,
+               mnarst, noar, ierr );
       //pas de test sur ierr car pas de saturation possible a ce niveau
 
       //chainage des aretes frontalieres en position 6 du tableau mnsoar
@@ -351,7 +368,7 @@ void  aptrte( Z   nutysu, R      aretmx,
 
   MESSAGE("Sur  le  bord: arete min=" << aremin << " arete max=" << aremax );
   MESSAGE("Triangulation: arete mx=" << aretmx
-         << " triangle aire mx=" << airemx );
+          << " triangle aire mx=" << airemx );
 
   //chainage des aretes frontalieres : la derniere arete frontaliere
   mnsoar[ mosoar * noar - mosoar + 5 ] = 0;
@@ -398,6 +415,8 @@ void  aptrte( Z   nutysu, R      aretmx,
   if( mntree==NULL ) goto ERREUR;
 
   //initialisation du tableau letree et ajout dans letree des sommets 1 a nbsomm
+  comxmi[0].x = comxmi[1].x = uvslf[0].x;
+  comxmi[0].y = comxmi[1].y = uvslf[0].y;
   teajte( mxsomm, nbsomm, mnpxyd, comxmi, aretmx, mxtree, mntree, ierr );
   comxmi[0].z=0;
   comxmi[1].z=0;
@@ -427,9 +446,9 @@ void  aptrte( Z   nutysu, R      aretmx,
   if( mnqueu==NULL) goto ERREUR;
 
   tehote( nutysu, nbarpi, mxsomm, nbsomm, mnpxyd,
-          comxmi, aretmx,
-          mntree, mxqueu, mnqueu,
-          ierr );
+           comxmi, aretmx,
+           mntree, mxqueu, mnqueu,
+           ierr );
 
   deltacpu_( d );
   tcpu += d;
@@ -454,9 +473,9 @@ void  aptrte( Z   nutysu, R      aretmx,
   // et des points de la frontiere, des points internes imposes interieurs
   // ==========================================================================
   tetrte( comxmi, aretmx, nbarpi, mxsomm, mnpxyd,
-          mxqueu, mnqueu, mntree, mosoar, mxsoar, n1soar, mnsoar,
-          moartr, mxartr, n1artr, mnartr, mnarst,
-          ierr );
+           mxqueu, mnqueu, mntree, mosoar, mxsoar, n1soar, mnsoar,
+           moartr, mxartr, n1artr, mnartr, mnarst,
+           ierr );
 
   // destruction de la queue et de l'arbre devenus inutiles
   delete [] mnqueu;  mnqueu=NULL;
@@ -476,7 +495,7 @@ void  aptrte( Z   nutysu, R      aretmx,
 
   //qualites de la triangulation actuelle
   qualitetrte( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
-               nbt, quamoy, quamin );
+                nbt, quamoy, quamin );
 
   // boucle sur les aretes internes (non sur une ligne de la frontiere)
   // avec echange des 2 diagonales afin de rendre la triangulation delaunay
@@ -484,8 +503,8 @@ void  aptrte( Z   nutysu, R      aretmx,
   // formation du chainage 6 des aretes internes a echanger eventuellement
   aisoar( mosoar, mxsoar, mnsoar, na );
   tedela( mnpxyd, mnarst,
-          mosoar, mxsoar, n1soar, mnsoar, na,
-          moartr, mxartr, n1artr, mnartr, n );
+           mosoar, mxsoar, n1soar, mnsoar, na,
+           moartr, mxartr, n1artr, mnartr, n );
 
   MESSAGE( "Nombre d'echanges des diagonales de 2 triangles=" << n );
   deltacpu_( d );
@@ -495,7 +514,7 @@ void  aptrte( Z   nutysu, R      aretmx,
 
   //qualites de la triangulation actuelle
   qualitetrte( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
-               nbt, quamoy, quamin );
+                nbt, quamoy, quamin );
 
   // detection des aretes frontalieres initiales perdues
   // triangulation frontale pour les restaurer
@@ -515,10 +534,10 @@ void  aptrte( Z   nutysu, R      aretmx,
   if( mnarcf2 == NULL ) goto ERREUR;
 
   terefr( nbarpi, mnpxyd,
-          mosoar, mxsoar, n1soar, mnsoar,
-          moartr, mxartr, n1artr, mnartr, mnarst,
-          mxarcf, mn1arcf, mnarcf, mnarcf1, mnarcf2,
-          n, ierr );
+           mosoar, mxsoar, n1soar, mnsoar,
+           moartr, mxartr, n1artr, mnartr, mnarst,
+           mxarcf, mn1arcf, mnarcf, mnarcf1, mnarcf2,
+           n, ierr );
 
   MESSAGE( "Restauration de " << n << " aretes perdues de la frontiere  ierr=" << ierr );
   deltacpu_( d );
@@ -530,7 +549,7 @@ void  aptrte( Z   nutysu, R      aretmx,
 
   //qualites de la triangulation actuelle
   qualitetrte( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
-               nbt, quamoy, quamin );
+                nbt, quamoy, quamin );
 
   // fin de la triangulation avec respect des aretes initiales frontalieres
 
@@ -556,10 +575,10 @@ void  aptrte( Z   nutysu, R      aretmx,
     mnlftr[n] = n+1;
 
   tesuex( nblf,   mnlftr,
-          ndtri0, nbsomm, mnpxyd, mnslig,
-          mosoar, mxsoar, mnsoar,
-          moartr, mxartr, n1artr, mnartr, mnarst,
-          nbt, mntrsu, ierr );
+           ndtri0, nbsomm, mnpxyd, mnslig,
+           mosoar, mxsoar, mnsoar,
+           moartr, mxartr, n1artr, mnartr, mnarst,
+           nbt, mntrsu, ierr );
 
   delete [] mnlftr; mnlftr=NULL;
   delete [] mntrsu; mntrsu=NULL;
@@ -571,7 +590,7 @@ void  aptrte( Z   nutysu, R      aretmx,
 
   //qualites de la triangulation actuelle
   qualitetrte( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
-               nbt, quamoy, quamin );
+                nbt, quamoy, quamin );
 
   // amelioration de la qualite de la triangulation par
   // barycentrage des sommets internes a la triangulation
@@ -586,12 +605,12 @@ void  aptrte( Z   nutysu, R      aretmx,
     goto ERREUR;
   }
   teamqt( nutysu,  aretmx,  airemx,
-          mnarst,  mosoar,  mxsoar, n1soar, mnsoar,
-          moartr,  mxartr,  n1artr, mnartr,
-          mxarcf,  mnarcf2, mnarcf3,
-          mn1arcf, mnarcf,  mnarcf1,
-          nbarpi,  nbsomm, mxsomm, mnpxyd, mnslig,
-          ierr );
+           mnarst,  mosoar,  mxsoar, n1soar, mnsoar,
+           moartr,  mxartr,  n1artr, mnartr,
+           mxarcf,  mnarcf2, mnarcf3,
+           mn1arcf, mnarcf,  mnarcf1,
+           nbarpi,  nbsomm, mxsomm, mnpxyd, mnslig,
+           ierr );
   if( mnarcf3 != NULL ) {delete [] mnarcf3; mnarcf3=NULL;}
   if( mn1arcf != NULL ) {delete [] mn1arcf; mn1arcf=NULL;}
   if( mnarcf  != NULL ) {delete [] mnarcf;  mnarcf =NULL;}
@@ -606,7 +625,7 @@ void  aptrte( Z   nutysu, R      aretmx,
 
   //qualites de la triangulation finale
   qualitetrte( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
-               nbt, quamoy, quamin );
+                nbt, quamoy, quamin );
 
   // renumerotation des sommets internes: mnarst(i)=numero final du sommet
   // ===================================
@@ -652,22 +671,22 @@ void  aptrte( Z   nutysu, R      aretmx,
       n = mnslig[i];
       if( n > 0 )
       {
-       if( n >= 1000000 )
-       {
-         //sommet d'une ligne
-         //retour aux coordonnees initiales dans uvslf
-         l = n / 1000000;
-         n = n - 1000000 * l + nudslf[l-1] - 1;
-         uvst[nbst].x = uvslf[n].x;
-         uvst[nbst].y = uvslf[n].y;
-       }
-       else
-       {
-         //point utilisateur n interne impose
-         //retour aux coordonnees initiales dans uvpti
-         uvst[nbst].x = uvpti[n-1].x;
-         uvst[nbst].y = uvpti[n-1].y;
-       }
+        if( n >= 1000000 )
+        {
+          //sommet d'une ligne
+          //retour aux coordonnees initiales dans uvslf
+          l = n / 1000000;
+          n = n - 1000000 * l + nudslf[l-1] - 1;
+          uvst[nbst].x = uvslf[n].x;
+          uvst[nbst].y = uvslf[n].y;
+        }
+        else
+        {
+          //point utilisateur n interne impose
+          //retour aux coordonnees initiales dans uvpti
+          uvst[nbst].x = uvpti[n-1].x;
+          uvst[nbst].y = uvpti[n-1].y;
+        }
       }
     }
   }
@@ -695,7 +714,7 @@ void  aptrte( Z   nutysu, R      aretmx,
   }
   nbt /= nbsttria;  //le nombre final de triangles de la surface
   MESSAGE( "APTRTE: Fin de la triangulation plane avec "<<nbst<<" sommets et "
-          << nbt << " triangles" );
+           << nbt << " triangles" );
   deltacpu_( d );
   tcpu += d;
   MESSAGE( "APTRTE: Temps total de la triangulation plane=" << tcpu << " secondes" );
@@ -736,12 +755,15 @@ void  aptrte( Z   nutysu, R      aretmx,
 }
 void
 #ifdef WIN32
+#ifdef F2C_BUILD
+#else
               __stdcall
+#endif
 #endif
  qualitetrte( R3 *mnpxyd,
-                  Z & mosoar, Z & mxsoar, Z *mnsoar,
-                  Z & moartr, Z & mxartr, Z *mnartr,
-                  Z & nbtria, R & quamoy, R & quamin )
+                   Z & mosoar, Z & mxsoar, Z *mnsoar,
+                   Z & moartr, Z & mxartr, Z *mnartr,
+                   Z & nbtria, R & quamoy, R & quamin )
 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 // but :    calculer la qualite moyenne et minimale de la triangulation
 // -----    actuelle definie par les tableaux mnsoar et mnartr
@@ -795,7 +817,7 @@ void
 
       //la qualite du triangle ns1 ns2 ns3
       qutr2d( mnpxyd[nosotr[0]-1], mnpxyd[nosotr[1]-1], mnpxyd[nosotr[2]-1],
-              qualite );
+               qualite );
 
       //la qualite moyenne
       quamoy += qualite;
@@ -811,11 +833,11 @@ void
       d = surtd2( mnpxyd[nosotr[0]-1], mnpxyd[nosotr[1]-1], mnpxyd[nosotr[2]-1] );
       if( d<0 )
       {
-       //un triangle d'aire negative de plus
-       nbtrianeg++;
-       MESSAGE("ATTENTION: le triangle " << nt << " de sommets:"
-            << nosotr[0] << " " << nosotr[1] << " " << nosotr[2]
-            << " a une aire " << d <<"<=0");
+        //un triangle d'aire negative de plus
+        nbtrianeg++;
+        MESSAGE("ATTENTION: le triangle " << nt << " de sommets:"
+             << nosotr[0] << " " << nosotr[1] << " " << nosotr[2]
+             << " a une aire " << d <<"<=0");
       }
 
       //aire des triangles actuels
@@ -838,7 +860,7 @@ void
             <<nosotr[0]<<" "<<nosotr[1]<<" "<<nosotr[2]<<" ");
     for (int i=0;i<3;i++)
       MESSAGE("Sommet "<<nosotr[i]<<": x="<< mnpxyd[nosotr[i]-1].x
-             <<" y="<< mnpxyd[nosotr[i]-1].y);
+              <<" y="<< mnpxyd[nosotr[i]-1].y);
   }
 
   if( nbtrianeg>0 )
index 68fb0e63ac414a1e6681d4953592a658fbe459e4..da60fbab500f64016a5169c1924873820420715d 100755 (executable)
@@ -1,24 +1,22 @@
 //  SMESH MEFISTO2 : algorithm for meshing
 //
-//  Copyright (C) 2006  Laboratoire J.-L. Lions UPMC Paris
+// Copyright (C) 2006-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  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 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.ann.jussieu.fr/~perronne or email Perronnet@ann.jussieu.fr
+// 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.com
 //
 //  File   : aptrte.h
 //  Author : Alain PERRONNET
 
 MEFISTO2D_EXPORT
   void  aptrte( Z nutysu, R aretmx,
-             Z nblf,   Z *nudslf, R2 *uvslf,
-             Z nbpti,  R2 *uvpti,
-             Z & nbst, R2 * & uvst, Z & nbt, Z * & nust,
-             Z & ierr );
+              Z nblf,   Z *nudslf, R2 *uvslf,
+              Z nbpti,  R2 *uvpti,
+              Z & nbst, R2 * & uvst, Z & nbt, Z * & nust,
+              Z & ierr );
 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 // but : appel de la triangulation par un arbre-4 recouvrant
 // ----- de triangles equilateraux
@@ -126,7 +124,7 @@ MEFISTO2D_EXPORT
   #define nusotr   NUSOTR
   #define qutr2d   QUTR2D
   #define surtd2   SURTD2
-  #define qualitetrte  QUALITETRTE
+  #define qualitetrte   QUALITETRTE
   
   #define areteideale ARETEIDEALE
   
@@ -156,12 +154,15 @@ MEFISTO2D_EXPORT
 
 extern "C" { void
 #ifdef WIN32
+#ifdef F2C_BUILD
+#else
               __stdcall
+#endif
 #endif
    qualitetrte( R3 *mnpxyd,
-                  Z & mosoar, Z & mxsoar, Z *mnsoar,
-                  Z & moartr, Z & mxartr, Z *mnartr,
-                  Z & nbtria, R & quamoy, R & quamin ); }
+                   Z & mosoar, Z & mxsoar, Z *mnsoar,
+                   Z & moartr, Z & mxartr, Z *mnartr,
+                   Z & nbtria, R & quamoy, R & quamin ); }
 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 // but :    calculer la qualite moyenne et minimale de la triangulation
 // -----    actuelle definie par les tableaux nosoar et noartr
@@ -193,7 +194,10 @@ extern "C" { void
 
 extern "C" {  void
 #ifdef WIN32
+#ifdef F2C_BUILD
+#else
               __stdcall
+#endif
 #endif
   tempscpu( double & tempsec );
 }
@@ -202,7 +206,10 @@ extern "C" {  void
 
 extern "C" { void
 #ifdef WIN32
+#ifdef F2C_BUILD
+#else
               __stdcall
+#endif
 #endif
   deltacpu( R & dtcpu );
 }
@@ -212,7 +219,10 @@ extern "C" { void
 //initialiser le tableau mnsoar pour le hachage des aretes
 extern "C" {void
 #ifdef WIN32
+#ifdef F2C_BUILD
+#else
               __stdcall
+#endif
 #endif
   insoar( Z & mxsomm, Z & mosoar, Z & mxsoar, Z & n1soar, Z * mnsoar );
 }
@@ -220,18 +230,24 @@ extern "C" {void
 //mettre a zero les nb entiers de tab
 extern "C" {void
 #ifdef WIN32
+#ifdef F2C_BUILD
+#else
               __stdcall
+#endif
 #endif
   azeroi( Z & nb, Z * tab );
 }
 
 extern "C" {void
 #ifdef WIN32
+#ifdef F2C_BUILD
+#else
               __stdcall
+#endif
 #endif
   fasoar( Z & ns1, Z & ns2, Z & nt1, Z & nt2, Z & nolign,
-                         Z & mosoar,  Z & mxsoar,  Z & n1soar,  Z * mnsoar,  Z * mnarst,
-                         Z & noar, Z & ierr );
+                          Z & mosoar,  Z & mxsoar,  Z & n1soar,  Z * mnsoar,  Z * mnarst,
+                          Z & noar, Z & ierr );
 }
 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 // but :    former l'arete de sommet ns1-ns2 dans le hachage du tableau
@@ -279,41 +295,53 @@ extern "C" {void
 //initialisation du tableau letree et ajout dans letree des sommets 1 a nbsomm
 extern "C" {void
 #ifdef WIN32
+#ifdef F2C_BUILD
+#else
               __stdcall
+#endif
 #endif
   teajte( Z & mxsomm, Z &  nbsomm, R3 * mnpxyd,  R3 * comxmi,
-                           R & aretmx,  Z & mxtree, Z * letree,
-                           Z & ierr );
+                            R & aretmx,  Z & mxtree, Z * letree,
+                            Z & ierr );
 }
 
 extern "C" {void
 #ifdef WIN32
+#ifdef F2C_BUILD
+#else
               __stdcall
+#endif
 #endif
   tehote( Z & nutysu, Z & nbarpi, Z &  mxsomm, Z &  nbsomm, R3 * mnpxyd,
-                           R3 * comxmi, R & aretmx,
-                           Z * letree, Z & mxqueu, Z * mnqueu,
-                           Z & ierr );
+                            R3 * comxmi, R & aretmx,
+                            Z * letree, Z & mxqueu, Z * mnqueu,
+                            Z & ierr );
 }
 // homogeneisation de l'arbre des te a un saut de taille au plus
 // prise en compte des tailles d'aretes souhaitees autour des sommets initiaux
 
 extern "C" {void
 #ifdef WIN32
+#ifdef F2C_BUILD
+#else
               __stdcall
+#endif
 #endif
   tetrte( R3 * comxmi, R & aretmx, Z & nbarpi, Z & mxsomm, R3 * mnpxyd,
-                           Z & mxqueu,  Z * mnqueu,  Z * mntree,
-                           Z & mosoar,  Z & mxsoar,  Z & n1soar, Z * mnsoar,
-                           Z & moartr, Z &  mxartr,  Z & n1artr,  Z * mnartr,  Z * mnarst,
-                           Z & ierr );
+                            Z & mxqueu,  Z * mnqueu,  Z * mntree,
+                            Z & mosoar,  Z & mxsoar,  Z & n1soar, Z * mnsoar,
+                            Z & moartr, Z &  mxartr,  Z & n1artr,  Z * mnartr,  Z * mnarst,
+                            Z & ierr );
 }
 // trianguler les triangles equilateraux feuilles a partir de leurs 3 sommets
 // et des points de la frontiere, des points internes imposes interieurs
 
 extern "C" {void
 #ifdef WIN32
+#ifdef F2C_BUILD
+#else
               __stdcall
+#endif
 #endif
   aisoar( Z & mosoar, Z & mxsoar, Z * mnsoar, Z & na );
 }
@@ -321,53 +349,65 @@ extern "C" {void
 
 extern "C" {void
 #ifdef WIN32
+#ifdef F2C_BUILD
+#else
               __stdcall
+#endif
 #endif
   tedela( R3 * mnpxyd, Z * mnarst,
-                           Z & mosoar, Z & mxsoar, Z & n1soar, Z * mnsoar, Z & na,
-                           Z & moartr, Z & mxartr, Z & n1artr, Z * mnartr, Z & n );
+                            Z & mosoar, Z & mxsoar, Z & n1soar, Z * mnsoar, Z & na,
+                            Z & moartr, Z & mxartr, Z & n1artr, Z * mnartr, Z & n );
 }
 // boucle sur les aretes internes (non sur une ligne de la frontiere)
 // avec echange des 2 diagonales afin de rendre la triangulation delaunay
  
 extern "C" {void
 #ifdef WIN32
+#ifdef F2C_BUILD
+#else
               __stdcall
+#endif
 #endif
   terefr( Z & nbarpi, R3 * mnpxyd,
-                           Z & mosoar, Z & mxsoar, Z & n1soar, Z * mnsoar,
-                           Z & moartr, Z & mxartr, Z & n1artr, Z * mnartr, Z * mnarst,
-                           Z & mxarcf, Z * mnarc1, Z * mnarc2,
-                           Z * mnarc3, Z * mnarc4,
-                           Z & n, Z & ierr );
+                            Z & mosoar, Z & mxsoar, Z & n1soar, Z * mnsoar,
+                            Z & moartr, Z & mxartr, Z & n1artr, Z * mnartr, Z * mnarst,
+                            Z & mxarcf, Z * mnarc1, Z * mnarc2,
+                            Z * mnarc3, Z * mnarc4,
+                            Z & n, Z & ierr );
 }
 // detection des aretes frontalieres initiales perdues
 // triangulation frontale pour les restaurer
 
 extern "C" {void
 #ifdef WIN32
+#ifdef F2C_BUILD
+#else
               __stdcall
+#endif
 #endif
   tesuex( Z & nblf, Z * nulftr,
-                           Z & ndtri0, Z & nbsomm, R3 * mnpxyd, Z * mnslig,
-                           Z & mosoar, Z & mxsoar, Z * mnsoar,
-                           Z & moartr, Z & mxartr, Z & n1artr, Z * mnartr, Z * mnarst,
-                           Z & nbtria, Z * mntrsu, Z & ierr );
+                            Z & ndtri0, Z & nbsomm, R3 * mnpxyd, Z * mnslig,
+                            Z & mosoar, Z & mxsoar, Z * mnsoar,
+                            Z & moartr, Z & mxartr, Z & n1artr, Z * mnartr, Z * mnarst,
+                            Z & nbtria, Z * mntrsu, Z & ierr );
 }
 // suppression des triangles externes a la surface
 
 extern "C" {void
 #ifdef WIN32
+#ifdef F2C_BUILD
+#else
               __stdcall
+#endif
 #endif
   teamqt( Z & nutysu, R & aretmx, R & airemx,
-                           Z * mnarst, Z & mosoar, Z & mxsoar, Z & n1soar, Z * mnsoar,
-                           Z & moartr, Z & mxartr, Z & n1artr, Z * mnartr,
-                           Z & mxarcf, Z * mntrcf, Z * mnstbo,
-                           Z * n1arcf, Z * mnarcf, Z * mnarc1,
-                           Z & nbarpi, Z & nbsomm, Z & mxsomm,
-                           R3 * mnpxyd, Z * mnslig,
-                           Z & ierr );
+                            Z * mnarst, Z & mosoar, Z & mxsoar, Z & n1soar, Z * mnsoar,
+                            Z & moartr, Z & mxartr, Z & n1artr, Z * mnartr,
+                            Z & mxarcf, Z * mntrcf, Z * mnstbo,
+                            Z * n1arcf, Z * mnarcf, Z * mnarc1,
+                            Z & nbarpi, Z & nbsomm, Z & mxsomm,
+                            R3 * mnpxyd, Z * mnslig,
+                            Z & ierr );
 }
 // amelioration de la qualite de la triangulation par
 // barycentrage des sommets internes a la triangulation
@@ -377,7 +417,10 @@ extern "C" {void
  
 extern "C" {void
 #ifdef WIN32
+#ifdef F2C_BUILD
+#else
               __stdcall
+#endif
 #endif
   nusotr( Z & nt, Z & mosoar, Z * mnsoar, Z & moartr, Z * mnartr,Z * nosotr );
 }
@@ -385,7 +428,10 @@ extern "C" {void
 
 extern "C" {void
 #ifdef WIN32
+#ifdef F2C_BUILD
+#else
               __stdcall
+#endif
 #endif
   qutr2d( R3 & p1, R3 & p2, R3 & p3, R & qualite );
 }
@@ -393,7 +439,10 @@ extern "C" {void
 
 extern "C" { R
 #ifdef WIN32
+#ifdef F2C_BUILD
+#else
               __stdcall
+#endif
 #endif
   surtd2( R3 & p1, R3 & p2, R3 & p3 );
 }
index 8ee61fadc43a685c62b645303831ec6b0e15c68f..d50804995af60b7ec54256758a640616088042c3 100755 (executable)
@@ -1,23 +1,22 @@
 c  MEFISTO : library to compute 2D triangulation from segmented boundaries
 c
-c  Copyright (C) 2006  Laboratoire J.-L. Lions UPMC Paris
+c Copyright (C) 2006-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 c
-c  This library is free software; you can redistribute it and/or
-c  modify it under the terms of the GNU Lesser General Public
-c  License as published by the Free Software Foundation; either
-c  version 2.1 of the License.
+c This library is free software; you can redistribute it and/or
+c modify it under the terms of the GNU Lesser General Public
+c License as published by the Free Software Foundation; either
+c version 2.1 of the License.
 c
-c  This library is distributed in the hope that it will be useful,
-c  but WITHOUT ANY WARRANTY; without even the implied warranty of
-c  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-c  Lesser General Public License for more details.
+c This library is distributed in the hope that it will be useful,
+c but WITHOUT ANY WARRANTY; without even the implied warranty of
+c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+c Lesser General Public License for more details.
 c
-c  You should have received a copy of the GNU Lesser General Public
-c  License along with this library; if not, write to the Free Software
-c  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-c
-c  See http://www.ann.jussieu.fr/~perronne or email Perronnet@ann.jussieu.fr
+c You should have received a copy of the GNU Lesser General Public
+c License along with this library; if not, write to the Free Software
+c Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 c
+c See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 c
 c  File   : areteideale.f
 c  Module : SMESH
index 273569def1c20288d24bbaea4f7f0567688b56b4..e15ebc2667a6d26b30673ce7d7faca3742e19308 100755 (executable)
@@ -1,22 +1,22 @@
 c  MEFISTO2: a library to compute 2D triangulation from segmented boundaries
 c
-c  Copyright (C) 2006  Laboratoire J.-L. Lions UPMC Paris
+c Copyright (C) 2006-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 c
-c  This library is free software; you can redistribute it and/or
-c  modify it under the terms of the GNU Lesser General Public
-c  License as published by the Free Software Foundation; either
-c  version 2.1 of the License.
+c This library is free software; you can redistribute it and/or
+c modify it under the terms of the GNU Lesser General Public
+c License as published by the Free Software Foundation; either
+c version 2.1 of the License.
 c
-c  This library is distributed in the hope that it will be useful,
-c  but WITHOUT ANY WARRANTY; without even the implied warranty of
-c  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-c  Lesser General Public License for more details.
+c This library is distributed in the hope that it will be useful,
+c but WITHOUT ANY WARRANTY; without even the implied warranty of
+c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+c Lesser General Public License for more details.
 c
-c  You should have received a copy of the GNU Lesser General Public
-c  License along with this library; if not, write to the Free Software
-c  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+c You should have received a copy of the GNU Lesser General Public
+c License along with this library; if not, write to the Free Software
+c Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 c
-c  See http://www.ann.jussieu.fr/~perronnet or email perronnet@ann.jussieu.fr
+c See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 c
 c  File   : trte.f    le Fortran du trianguleur plan
 c  Module : SMESH
@@ -1294,7 +1294,7 @@ c        la direction pour le calcul de la longueur (inactif ici!)
          xyzd(2) = 0d0
          xyzd(3) = 0d0
 
-         longai = areteideale()
+         longai = areteideale(xyz,xyzd)
 c         (xyz,xyzd)
          if( longai .lt. 0d0 ) then
             write(imprim,10000) xyz
index 51c76c599a6f482533b640ff1a722ed197ae46c9..b969674a181e6e8f3953ac794aa908348ae1e059 100644 (file)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  File   : Makefile.in
 #  Author : Patrick GOLDBRONN (CEA)
 #  Modified by : Alexander BORODIN (OCN) - autotools usage
 #
 include $(top_srcdir)/adm_local/unix/make_common_starter.am
 
+if WITH_CGNS
+  DriverCGNS_SUDIR = DriverCGNS
+endif
+
 SUBDIRS = \
        SMDS \
        SMESHDS \
+       SMESHUtils \
        Controls \
        Driver \
        DriverMED \
        DriverDAT \
        DriverUNV \
        DriverSTL \
+       $(DriverCGNS_SUDIR) \
        SMESH \
        SMESH_I \
        SMESHClient \
        SMESH_SWIG \
        MEFISTO2 \
        StdMeshers \
-       StdMeshers_I
+       StdMeshers_I \
+       SMESH_PY \
+       Tools
 
 if SMESH_ENABLE_GUI
   SUBDIRS += \
        OBJECT \
        SMESHFiltersSelection \
        SMESHGUI \
+       PluginUtils \
        SMESH_SWIG_WITHIHM \
        StdMeshersGUI
 endif
 
-DIST_SUBDIRS =         SMDS SMESHDS Controls Driver DriverMED DriverDAT DriverUNV DriverSTL SMESH      \
-               SMESH_I SMESHClient SMESH_SWIG MEFISTO2 StdMeshers StdMeshers_I OBJECT          \
-               SMESHFiltersSelection SMESHGUI SMESH_SWIG_WITHIHM StdMeshersGUI
+DIST_SUBDIRS =         SMDS SMESHDS Controls Driver DriverMED DriverDAT DriverUNV DriverSTL DriverCGNS \
+               SMESHUtils SMESH SMESH_I SMESHClient SMESH_SWIG MEFISTO2 StdMeshers StdMeshers_I OBJECT         \
+               SMESHFiltersSelection SMESHGUI PluginUtils SMESH_SWIG_WITHIHM StdMeshersGUI SMESH_PY Tools
index 3bc3907c9ce4da80e83fe12df4a98db9dcb0c8e6..31cb50d27f5889b295cf2979181de257d1be387d 100644 (file)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  SMESH OBJECT : interactive object for SMESH visualization
 #  File   : Makefile.in
 #  Modified by : Alexander BORODIN (OCN) - autotools usage
@@ -34,9 +32,12 @@ salomeinclude_HEADERS = \
        SMESH_ActorUtils.h \
        SMESH_ActorDef.h \
        SMESH_DeviceActor.h \
+       SMESH_PreviewActorsCollection.h \
        SMESH_ExtractGeometry.h \
-       SMESH_ActorUtils.h \
-       SMESH_FaceOrientationFilter.h
+       SMESH_FaceOrientationFilter.h \
+       SMESH_ScalarBarActor.h \
+       SMESH_NodeLabelActor.h \
+       SMESH_CellLabelActor.h
 
 # Libraries targets
 
@@ -45,18 +46,25 @@ dist_libSMESHObject_la_SOURCES = \
        SMESH_Object.cxx \
        SMESH_DeviceActor.cxx \
        SMESH_Actor.cxx \
+       SMESH_PreviewActorsCollection.cxx \
        SMESH_ExtractGeometry.cxx \
        SMESH_ActorUtils.cxx \
-       SMESH_FaceOrientationFilter.cxx
+       SMESH_FaceOrientationFilter.cxx \
+       SMESH_ScalarBarActor.cxx \
+       SMESH_NodeLabelActor.cxx \
+       SMESH_CellLabelActor.cxx 
 
 libSMESHObject_la_CPPFLAGS = \
+        $(QT_INCLUDES) \
         $(KERNEL_CXXFLAGS) \
         $(GUI_CXXFLAGS) \
        $(MED_CXXFLAGS) \
+       $(QWT_INCLUDES) \
        $(GEOM_CXXFLAGS) \
        $(CAS_CPPFLAGS) \
         $(VTK_INCLUDES) \
        $(CORBA_INCLUDES) \
+       $(CORBA_CXXFLAGS) \
         $(BOOST_CPPFLAGS) \
         $(QT_INCLUDES) \
        -I$(srcdir)/../Controls \
@@ -66,13 +74,16 @@ libSMESHObject_la_CPPFLAGS = \
        -I$(srcdir)/../DriverMED \
        -I$(srcdir)/../SMESH \
        -I$(srcdir)/../SMESHClient \
-       -I$(top_builddir)/idl \
-       -I$(top_builddir)/salome_adm/unix
+       -I$(srcdir)/../SMESHUtils \
+       -I$(top_builddir)/idl
 
 libSMESHObject_la_LDFLAGS  = \
         ../SMESHClient/libSMESHClient.la \
         ../SMDS/libSMDS.la \
         ../Controls/libSMESHControls.la \
-        $(GUI_LDFLAGS) -lSalomeApp lSalomeObject \
+        $(GUI_LDFLAGS) -lSalomeApp -lSalomeObject -lSVTK -lVTKViewer -lqtx -lsuit -lstd \
+       -lPlot2d \
+       -lSPlot2d \
+       $(GEOM_LDFLAGS) -lGEOMObject \
        $(CAS_KERNEL) \
-        $(VTK_LIBS)
+        $(VTK_LIBS) $(QT_MT_LIBS)
index 49d838bac3d47d7efb04ad0f9d7404b28692f3af..4daba11f8575cdb82ec8ed052654fa09dfb902c5 100644 (file)
@@ -1,40 +1,52 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH OBJECT : interactive object for SMESH visualization
 //  File   : SMESH_Actor.cxx
 //  Author : Nicolas REJNERI
 //  Module : SMESH
-
-
+//
 #include "SMESH_ActorDef.h"
 #include "SMESH_ActorUtils.h"
 #include "SMESH_DeviceActor.h"
+#include "SMESH_NodeLabelActor.h"
+#include "SMESH_CellLabelActor.h"
+#include "SMESH_ObjectDef.h"
 #include "SMESH_ControlsDef.hxx"
+#include "SMDS_UnstructuredGrid.hxx"
+#include "SMESH_ScalarBarActor.h"
 #include "VTKViewer_ExtractUnstructuredGrid.h"
+#include "VTKViewer_FramedTextActor.h"
 #include "SALOME_InteractiveObject.hxx"
 
 #include "SUIT_Session.h"
 #include "SUIT_ResourceMgr.h"
 
+#include <Qtx.h>
+
+#ifndef DISABLE_PLOT2DVIEWER
+#include <SPlot2d_Histogram.h>
+#endif
+
 #include <vtkProperty.h>
 #include <vtkTimeStamp.h>
 #include <vtkObjectFactory.h>
 #include <vtkActor2D.h>
 #include <vtkProperty2D.h>
 #include <vtkPolyData.h>
-#include <vtkMaskPoints.h>
-#include <vtkCellCenters.h>
 #include <vtkTextProperty.h>
-#include <vtkLabeledDataMapper.h>
-#include <vtkSelectVisiblePoints.h>
 
-#include <vtkScalarBarActor.h>
 #include <vtkLookupTable.h>
 
 #include <vtkMath.h>
 #include <vtkImplicitBoolean.h>
 #include <vtkImplicitFunctionCollection.h>
 
+#include <vtkConfigure.h>
+#if !defined(VTK_XVERSION)
+#define VTK_XVERSION (VTK_MAJOR_VERSION<<16)+(VTK_MINOR_VERSION<<8)+(VTK_BUILD_VERSION)
+#endif
+
 #include "utilities.h"
 
 #ifdef _DEBUG_
 static int MYDEBUG = 1;
 #else
-static int MYDEBUG = 0;
+static int MYDEBUG = 1;
 #endif
 
 static int aLineWidthInc = 2;
-static int aPointSizeInc = 2;
 
 
 SMESH_ActorDef* SMESH_ActorDef::New(){
@@ -88,28 +99,33 @@ SMESH_ActorDef* SMESH_ActorDef::New(){
 
 
 SMESH_Actor* SMESH_Actor::New(TVisualObjPtr theVisualObj, 
-                             const char* theEntry, 
-                             const char* theName,
-                             int theIsClear)
+                              const char* theEntry, 
+                              const char* theName,
+                              int theIsClear)
 {
-  SMESH_ActorDef* anActor = SMESH_ActorDef::New();
-  if(!anActor->Init(theVisualObj,theEntry,theName,theIsClear)){
-    anActor->Delete();
-    anActor = NULL;
+  SMESH_ActorDef* anActor = NULL;
+  if(theVisualObj->IsValid() ) {
+    anActor = SMESH_ActorDef::New();
+    if(!anActor->Init(theVisualObj,theEntry,theName,theIsClear)){
+      anActor->Delete();
+      anActor = NULL;
+    }
+    if( anActor )
+      anActor->UpdateScalarBar();
   }
-  if( anActor )
-    anActor->UpdateScalarBar();
   return anActor;
 }
 
 
 SMESH_ActorDef::SMESH_ActorDef()
 {
-  if(MYDEBUG) MESSAGE("SMESH_ActorDef - "<<this);
+  if(MYDEBUG) MESSAGE("SMESH_ActorDef - "<<this);  
+  myBaseActor = SMESH_DeviceActor::New();
 
   myTimeStamp = vtkTimeStamp::New();
 
   myIsPointsVisible = false;
+  myIsEntityModeCache = false;
 
   myIsShrinkable = false;
   myIsShrunk = false;
@@ -118,28 +134,33 @@ SMESH_ActorDef::SMESH_ActorDef()
 
   myControlsPrecision = -1;
   SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr();
-  
+
   if ( mgr && mgr->booleanValue( "SMESH", "use_precision", false ) )
     myControlsPrecision = mgr->integerValue( "SMESH", "controls_precision", -1);
 
-  vtkFloatingPointType aPointSize = SMESH::GetFloat("SMESH:node_size",3);
-  vtkFloatingPointType aLineWidth = SMESH::GetFloat("SMESH:element_width",1);
+  vtkFloatingPointType aElem0DSize   = SMESH::GetFloat("SMESH:elem0d_size",5);
+  vtkFloatingPointType aBallElemSize = SMESH::GetFloat("SMESH:ball_elem_size",10);
+  vtkFloatingPointType aLineWidth    = SMESH::GetFloat("SMESH:element_width",1);
 
   vtkMatrix4x4 *aMatrix = vtkMatrix4x4::New();
   VTKViewer_ExtractUnstructuredGrid* aFilter = NULL;
 
-  //Definition 2D and 3D divices of the actor
+  //Definition 2D and 3D devices of the actor
   //-----------------------------------------
   vtkFloatingPointType anRGB[3] = {1,1,1};
   mySurfaceProp = vtkProperty::New();
-  SMESH::GetColor( "SMESH", "fill_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 170, 255 ) );
-  mySurfaceProp->SetColor( anRGB[0], anRGB[1], anRGB[2] );
+  QColor ffc, bfc;
+  int delta;
+  SMESH::GetColor( "SMESH", "fill_color", ffc, delta, "0,170,255|-100" ) ;
+  mySurfaceProp->SetColor( ffc.red() / 255. , ffc.green() / 255. , ffc.blue() / 255. );
+  myDeltaBrightness = delta;
 
   myBackSurfaceProp = vtkProperty::New();
-  SMESH::GetColor( "SMESH", "backface_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 0, 255 ) );
-  myBackSurfaceProp->SetColor( anRGB[0], anRGB[1], anRGB[2] );
+  bfc = Qtx::mainColorToSecondary(ffc, delta);
+  myBackSurfaceProp->SetColor( bfc.red() / 255. , bfc.green() / 255. , bfc.blue() / 255. );
 
-  my2DActor = SMESH_DeviceActor::New();
+  my2DActor = SMESH_CellLabelActor::New();
+  my2DActor->SetStoreGemetryMapping(true);
   my2DActor->SetUserMatrix(aMatrix);
   my2DActor->PickableOff();
   my2DActor->SetProperty(mySurfaceProp);
@@ -152,6 +173,7 @@ SMESH_ActorDef::SMESH_ActorDef()
   aFilter->RegisterCellsWithType(VTK_QUAD);
   aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE);
   aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD);
+  aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUAD);
 
   my2DExtProp = vtkProperty::New();
   my2DExtProp->DeepCopy(mySurfaceProp);
@@ -173,13 +195,16 @@ SMESH_ActorDef::SMESH_ActorDef()
   aFilter->RegisterCellsWithType(VTK_QUAD);
   aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE);
   aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD);
+  aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUAD);
 
-  my3DActor = SMESH_DeviceActor::New();
+  my3DActor = SMESH_CellLabelActor::New();
+  my3DActor->SetStoreGemetryMapping(true);
   my3DActor->SetUserMatrix(aMatrix);
   my3DActor->PickableOff();
   my3DActor->SetProperty(mySurfaceProp);
   my3DActor->SetBackfaceProperty(myBackSurfaceProp);
   my3DActor->SetRepresentation(SMESH_DeviceActor::eSurface);
+  my3DActor->SetCoincident3DAllowed(true);
   aFilter = my3DActor->GetExtractUnstructuredGrid();
   aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
   aFilter->RegisterCellsWithType(VTK_TETRA);
@@ -187,22 +212,53 @@ SMESH_ActorDef::SMESH_ActorDef()
   aFilter->RegisterCellsWithType(VTK_HEXAHEDRON);
   aFilter->RegisterCellsWithType(VTK_WEDGE);
   aFilter->RegisterCellsWithType(VTK_PYRAMID);
+  aFilter->RegisterCellsWithType(VTK_HEXAGONAL_PRISM);
+  aFilter->RegisterCellsWithType(VTK_QUADRATIC_TETRA);
+  aFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON);
+  aFilter->RegisterCellsWithType(VTK_TRIQUADRATIC_HEXAHEDRON);
+  aFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE);
+  aFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID);
+  aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
+//#ifdef VTK_HAVE_POLYHEDRON
+  MESSAGE("RegisterCellsWithType(VTK_POLYHEDRON)");
+  aFilter->RegisterCellsWithType(VTK_POLYHEDRON);
+//#endif
+
+  my3DExtActor = SMESH_DeviceActor::New();
+  my3DExtActor->SetUserMatrix(aMatrix);
+  my3DExtActor->PickableOff();
+  my3DExtActor->SetProperty(my2DExtProp);
+  my3DExtActor->SetBackfaceProperty(my2DExtProp);
+  my3DExtActor->SetRepresentation(SMESH_DeviceActor::eSurface);
+  my3DExtActor->SetCoincident3DAllowed(true);
+  aFilter = my3DExtActor->GetExtractUnstructuredGrid();
+  aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
+  aFilter->RegisterCellsWithType(VTK_TETRA);
+  aFilter->RegisterCellsWithType(VTK_VOXEL);
+  aFilter->RegisterCellsWithType(VTK_HEXAHEDRON);
+  aFilter->RegisterCellsWithType(VTK_WEDGE);
+  aFilter->RegisterCellsWithType(VTK_PYRAMID);
+  aFilter->RegisterCellsWithType(VTK_HEXAGONAL_PRISM);
   aFilter->RegisterCellsWithType(VTK_QUADRATIC_TETRA);
   aFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON);
+  aFilter->RegisterCellsWithType(VTK_TRIQUADRATIC_HEXAHEDRON);
   aFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE);
+  aFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID);
   aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
+  aFilter->RegisterCellsWithType(VTK_POLYHEDRON);
 
-  //Definition 1D divice of the actor
+  //Definition 1D device of the actor
   //---------------------------------
   myEdgeProp = vtkProperty::New();
   myEdgeProp->SetAmbient(1.0);
   myEdgeProp->SetDiffuse(0.0);
   myEdgeProp->SetSpecular(0.0);
-  SMESH::GetColor( "SMESH", "outline_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 170, 255 ) );
+  SMESH::GetColor( "SMESH", "wireframe_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 170, 255 ) );
   myEdgeProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
   myEdgeProp->SetLineWidth(aLineWidth);
 
-  my1DActor = SMESH_DeviceActor::New();
+  my1DActor = SMESH_CellLabelActor::New();
+  my1DActor->SetStoreGemetryMapping(true);
   my1DActor->SetUserMatrix(aMatrix);
   my1DActor->PickableOff();
   my1DActor->SetHighlited(true);
@@ -216,7 +272,7 @@ SMESH_ActorDef::SMESH_ActorDef()
   my1DProp = vtkProperty::New();
   my1DProp->DeepCopy(myEdgeProp);
   my1DProp->SetLineWidth(aLineWidth + aLineWidthInc);
-  my1DProp->SetPointSize(aPointSize);
+  my1DProp->SetPointSize(aElem0DSize);
   
   my1DExtProp = vtkProperty::New();
   my1DExtProp->DeepCopy(myEdgeProp);
@@ -225,7 +281,7 @@ SMESH_ActorDef::SMESH_ActorDef()
   anRGB[2] = 1 - anRGB[2];
   my1DExtProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
   my1DExtProp->SetLineWidth(aLineWidth + aLineWidthInc);
-  my1DExtProp->SetPointSize(aPointSize + aPointSizeInc);
+  my1DExtProp->SetPointSize(aElem0DSize);
 
   my1DExtActor = SMESH_DeviceActor::New();
   my1DExtActor->SetUserMatrix(aMatrix);
@@ -240,14 +296,74 @@ SMESH_ActorDef::SMESH_ActorDef()
   aFilter->RegisterCellsWithType(VTK_QUADRATIC_EDGE);
 
 
-  //Definition 0D divice of the actor
-  //---------------------------------
+  //Definition 0D device of the actor (0d elements)
+  //-----------------------------------------------
+  my0DProp = vtkProperty::New();
+  SMESH::GetColor( "SMESH", "elem0d_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 255, 0 ) );
+  my0DProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
+  my0DProp->SetPointSize(aElem0DSize);
+
+  my0DActor = SMESH_CellLabelActor::New();
+  my0DActor->SetUserMatrix(aMatrix);
+  my0DActor->SetStoreGemetryMapping(true);
+  my0DActor->PickableOff();
+  my0DActor->SetVisibility(false);
+  my0DActor->SetProperty(my0DProp);
+  my0DActor->SetRepresentation(SMESH_DeviceActor::eSurface);
+  aFilter = my0DActor->GetExtractUnstructuredGrid();
+  //aFilter->SetModeOfExtraction(VTKViewer_ExtractUnstructuredGrid::ePoints);
+  aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
+  aFilter->RegisterCellsWithType(VTK_VERTEX);
+  
+  //Definition 0D device of the actor (ball elements)
+  //-----------------------------------------------
+  myBallProp = vtkProperty::New();
+  SMESH::GetColor( "SMESH", "ball_elem_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 255, 0 ) );
+  myBallProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
+  myBallProp->SetPointSize(aBallElemSize);
+
+  myBallActor = SMESH_CellLabelActor::New();
+  myBallActor->SetUserMatrix(aMatrix);
+  myBallActor->SetStoreGemetryMapping(true);
+  myBallActor->PickableOff();
+  myBallActor->SetVisibility(false);
+  myBallActor->SetProperty(myBallProp);
+  myBallActor->SetRepresentation(SMESH_DeviceActor::eSurface);
+  aFilter = myBallActor->GetExtractUnstructuredGrid();
+  //aFilter->SetModeOfExtraction(VTKViewer_ExtractUnstructuredGrid::ePoints);
+  aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
+  aFilter->RegisterCellsWithType(VTK_VERTEX);
+  aFilter->RegisterCellsWithType(VTK_POLY_VERTEX);
+  
+  //my0DExtProp = vtkProperty::New();
+  //my0DExtProp->DeepCopy(my0DProp);
+  //anRGB[0] = 1 - anRGB[0];
+  //anRGB[1] = 1 - anRGB[1];
+  //anRGB[2] = 1 - anRGB[2];
+  //my0DExtProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
+  //my0DExtProp->SetPointSize(aElem0DSize);
+  //
+  //my0DExtActor = SMESH_DeviceActor::New();
+  //my0DExtActor->SetUserMatrix(aMatrix);
+  //my0DExtActor->SetStoreClippingMapping(true);
+  //my0DExtActor->PickableOff();
+  //my0DExtActor->SetHighlited(true);
+  //my0DExtActor->SetVisibility(false);
+  //my0DExtActor->SetProperty(my0DExtProp);
+  //my0DExtActor->SetRepresentation(SMESH_DeviceActor::eInsideframe);
+  //aFilter = my0DExtActor->GetExtractUnstructuredGrid();
+  ////aFilter->SetModeOfExtraction(VTKViewer_ExtractUnstructuredGrid::ePoints);
+  //aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
+  //aFilter->RegisterCellsWithType(VTK_VERTEX);
+
+
+  //Definition 0D device of the actor (nodes)
+  //-----------------------------------------
   myNodeProp = vtkProperty::New();
   SMESH::GetColor( "SMESH", "node_color", anRGB[0], anRGB[1], anRGB[2], QColor( 255, 0, 0 ) );
   myNodeProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
-  myNodeProp->SetPointSize(aPointSize);
 
-  myNodeActor = SMESH_DeviceActor::New();
+  myNodeActor = SMESH_NodeLabelActor::New();
   myNodeActor->SetUserMatrix(aMatrix);
   myNodeActor->SetStoreClippingMapping(true);
   myNodeActor->PickableOff();
@@ -263,7 +379,6 @@ SMESH_ActorDef::SMESH_ActorDef()
   anRGB[1] = 1 - anRGB[1];
   anRGB[2] = 1 - anRGB[2];
   myNodeExtProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
-  myNodeExtProp->SetPointSize(aPointSize);
 
   myNodeExtActor = SMESH_DeviceActor::New();
   myNodeExtActor->SetUserMatrix(aMatrix);
@@ -280,11 +395,9 @@ SMESH_ActorDef::SMESH_ActorDef()
   //Definition of Pickable and Highlitable engines
   //----------------------------------------------
 
-  myBaseActor = SMESH_DeviceActor::New();
   myBaseActor->SetUserMatrix(aMatrix);
   myBaseActor->SetStoreGemetryMapping(true);
   myBaseActor->GetProperty()->SetOpacity(0.0);
-
   myPickableActor = myBaseActor;
   
   myHighlightProp = vtkProperty::New();
@@ -293,22 +406,37 @@ SMESH_ActorDef::SMESH_ActorDef()
   myHighlightProp->SetSpecular(0.0);
   SMESH::GetColor( "SMESH", "selection_object_color", anRGB[0], anRGB[1], anRGB[2], QColor( 255, 255, 255 ) );
   myHighlightProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
-  myHighlightProp->SetPointSize(aPointSize);
+  myHighlightProp->SetPointSize(aElem0DSize); // ??
+  myHighlightProp->SetLineWidth(aLineWidth);
   myHighlightProp->SetRepresentation(1);
+
+  myOutLineProp = vtkProperty::New();
+  myOutLineProp->SetAmbient(1.0);
+  myOutLineProp->SetDiffuse(0.0);
+  myOutLineProp->SetSpecular(0.0);
+  SMESH::GetColor( "SMESH", "outline_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 70, 0 ) );
+  myOutLineProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
+  myOutLineProp->SetPointSize(aElem0DSize); // ??
+  myOutLineProp->SetLineWidth(aLineWidth);
+  myOutLineProp->SetRepresentation(1);
+
   myPreselectProp = vtkProperty::New();
   myPreselectProp->SetAmbient(1.0);
   myPreselectProp->SetDiffuse(0.0);
   myPreselectProp->SetSpecular(0.0);
   SMESH::GetColor( "SMESH", "highlight_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 255, 255 ) );
   myPreselectProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
-  myPreselectProp->SetPointSize(aPointSize);
+  myPreselectProp->SetPointSize(aElem0DSize); // ??
+  myPreselectProp->SetLineWidth(aLineWidth);
   myPreselectProp->SetRepresentation(1);
 
   myHighlitableActor = SMESH_DeviceActor::New();
   myHighlitableActor->SetUserMatrix(aMatrix);
   myHighlitableActor->PickableOff();
   myHighlitableActor->SetRepresentation(SMESH_DeviceActor::eWireframe);
+  myHighlitableActor->SetCoincident3DAllowed(true);
+
+  aMatrix->Delete();
 
   myName = "";
   myIO = NULL;
@@ -323,7 +451,7 @@ SMESH_ActorDef::SMESH_ActorDef()
   //Controls - Aspect Ratio: incorrect colors of the best and worst values
   myLookupTable->SetHueRange(0.667,0.0);
 
-  myScalarBarActor = vtkScalarBarActor::New();
+  myScalarBarActor = SMESH_ScalarBarActor::New();
   myScalarBarActor->SetVisibility(false);
   myScalarBarActor->SetLookupTable(myLookupTable);
 
@@ -336,85 +464,41 @@ SMESH_ActorDef::SMESH_ActorDef()
   if( !mgr )
     return;
 
-  //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();
-  
   myEntityMode = eAllEntity;
-
-  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);
-
-  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);
-
+  myEntityModeCache = eAllEntity;
+  
   // Clipping planes
   myImplicitBoolean = vtkImplicitBoolean::New();
   myImplicitBoolean->SetOperationTypeToIntersection();
+  
+  //Quadratic 2D elements representation
+  //-----------------------------------------------------------------------------
+  int aQuadratic2DMode = mgr->integerValue( "SMESH", "quadratic_mode", 0);
+  if(aQuadratic2DMode == 0){
+    myHighlitableActor->SetQuadraticArcMode(false);
+    my2DActor->SetQuadraticArcMode(false);
+    my1DActor->SetQuadraticArcMode(false);
+  }
+  else if(aQuadratic2DMode == 1){
+    myHighlitableActor->SetQuadraticArcMode(true);
+    my2DActor->SetQuadraticArcMode(true);
+    my1DActor->SetQuadraticArcMode(true);
+  }
+  
+  int aQuadraticAngle = mgr->integerValue( "SMESH", "max_angle", 2);
+  myHighlitableActor->SetQuadraticArcAngle(aQuadraticAngle);
+  my2DActor->SetQuadraticArcAngle(aQuadraticAngle);
+  
+  // Set colors of the name actor
+  SMESH::GetColor( "SMESH", "fill_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 170, 255 ) );
+  myNameActor->SetBackgroundColor(anRGB[0], anRGB[1], anRGB[2]);
+  SMESH::GetColor( "SMESH", "group_name_color", anRGB[0], anRGB[1], anRGB[2], QColor( 255, 255, 255 ) );
+  myNameActor->SetForegroundColor(anRGB[0], anRGB[1], anRGB[2]);
+
+#ifndef DISABLE_PLOT2DVIEWER
+  my2dHistogram = 0;
+#endif
+
 }
 
 
@@ -422,11 +506,19 @@ SMESH_ActorDef::~SMESH_ActorDef()
 {
   if(MYDEBUG) MESSAGE("~SMESH_ActorDef - "<<this);
 
+#ifndef DISABLE_PLOT2DVIEWER
+  if(my2dHistogram) {
+    SMESH::ProcessIn2DViewers(this,SMESH::RemoveFrom2dViewer);
+    delete my2dHistogram;
+  }
+#endif
+
   myScalarBarActor->Delete();
   myLookupTable->Delete();
 
   mySurfaceProp->Delete();
   myBackSurfaceProp->Delete();
+  myOutLineProp->Delete();
 
   myEdgeProp->Delete();
   myHighlightProp->Delete();
@@ -435,6 +527,13 @@ SMESH_ActorDef::~SMESH_ActorDef()
   myNodeProp->Delete();
   myNodeExtProp->Delete();
  
+  my0DProp->Delete();
+  my0DActor->Delete();
+  myBallActor->Delete();
+
+  //my0DExtProp->Delete();
+  //my0DExtActor->Delete();
   my1DProp->Delete();
   my1DActor->Delete();
 
@@ -445,116 +544,83 @@ SMESH_ActorDef::~SMESH_ActorDef()
   my2DExtProp->Delete();
   my2DExtActor->Delete();
   my3DActor->Delete();
+  my3DExtActor->Delete();
 
   myNodeActor->Delete();
   myBaseActor->Delete();
 
-  myNodeExtActor->Delete();
-  
+  myNodeExtActor->Delete();  
   myHighlitableActor->Delete();
 
-  //Deleting of pints numbering pipeline
-  //---------------------------------------
-  myPointsNumDataSet->Delete();
-
-  // commented: porting to vtk 5.0
-  //  myPtsLabeledDataMapper->RemoveAllInputs();
-  myPtsLabeledDataMapper->Delete();
-
-  // commented: porting to vtk 5.0
-  //  myPtsSelectVisiblePoints->UnRegisterAllOutputs();
-  myPtsSelectVisiblePoints->Delete();
+  myImplicitBoolean->Delete();
 
-  // commented: porting to vtk 5.0
-  //  myPtsMaskPoints->UnRegisterAllOutputs();
-  myPtsMaskPoints->Delete();
+  myTimeStamp->Delete();
+}
 
-  myPointLabels->Delete();
+void SMESH_ActorDef::Delete()
+{
+  // This is just to guarantee that the DeleteActorEvent (which was previously invoked
+  // from the actor's destructor) will be thrown before removing the actor's observers,
+  // that is done inside the Superclass::Delete() method but before the destructor itself
+  // (see the issue 0021562: EDF SMESH: clipping and delete mesh clipped leads to crash).
+  // The event is caught by SMESHGUI::ProcessEvents() static method.
+  this->InvokeEvent( SMESH::DeleteActorEvent, NULL );
 
+  Superclass::Delete();
+}
 
-  //Deleting of cells numbering pipeline
-  //---------------------------------------
-  myCellsNumDataSet->Delete();
+void SMESH_ActorDef::SetPointsLabeled( bool theIsPointsLabeled )
+{    
+  if(myNodeActor) {
+    myNodeActor->SetPointsLabeled(theIsPointsLabeled);
+    SetRepresentation(GetRepresentation());
+    myTimeStamp->Modified();
+  }
+}
 
-  myClsLabeledDataMapper->RemoveAllInputs();
-  myClsLabeledDataMapper->Delete();
+bool SMESH_ActorDef::GetPointsLabeled() {
+  return myNodeActor && myNodeActor->GetPointsLabeled();
+}
 
-  // commented: porting to vtk 5.0
-  //  myClsSelectVisiblePoints->UnRegisterAllOutputs();
-  myClsSelectVisiblePoints->Delete();
+void SMESH_ActorDef::SetCellsLabeled(bool theIsCellsLabeled)
+{
+  if(my3DActor)
+    my3DActor->SetCellsLabeled(theIsCellsLabeled);
 
-  // commented: porting to vtk 5.0
-  //  myClsMaskPoints->UnRegisterAllOutputs();
-  myClsMaskPoints->Delete();
+  if(my2DActor)
+    my2DActor->SetCellsLabeled(theIsCellsLabeled);
 
-  // commented: porting to vtk 5.0
-  //  myCellCenters->UnRegisterAllOutputs();
-  myCellCenters->Delete();
+  if(my1DActor)
+    my1DActor->SetCellsLabeled(theIsCellsLabeled);
 
-  myCellsLabels->Delete();
+  if(my0DActor)
+    my0DActor->SetCellsLabeled(theIsCellsLabeled);
+  
+  if(myBallActor)
+    myBallActor->SetCellsLabeled(theIsCellsLabeled);
+  
+  myTimeStamp->Modified();
+}
 
-  myImplicitBoolean->Delete();
 
-  myTimeStamp->Delete();
-}
+bool SMESH_ActorDef::GetCellsLabeled() {
+  bool result = false;
+  if(my3DActor)
+    result = result || my3DActor->GetCellsLabeled();
 
+  if(my2DActor)
+    result = result || my2DActor->GetCellsLabeled();
 
-void SMESH_ActorDef::SetPointsLabeled( bool theIsPointsLabeled )
-{
-  vtkUnstructuredGrid* aGrid = GetUnstructuredGrid();
-  myIsPointsLabeled = theIsPointsLabeled && aGrid->GetNumberOfPoints();
+  if(my1DActor)
+    result = result || my1DActor->GetCellsLabeled();
 
-  if ( myIsPointsLabeled )
-  {
-    myPointsNumDataSet->ShallowCopy(aGrid);
-    vtkDataSet *aDataSet = myPointsNumDataSet;
-    
-    int aNbElem = aDataSet->GetNumberOfPoints();
-    
-    vtkIntArray *anArray = vtkIntArray::New();
-    anArray->SetNumberOfValues( aNbElem );
-    
-    for ( int anId = 0; anId < aNbElem; anId++ )
-    {
-      int aSMDSId = myVisualObj->GetNodeObjId( anId );
-      anArray->SetValue( anId, aSMDSId );
-    }
-    
-    aDataSet->GetPointData()->SetScalars( anArray );
-    anArray->Delete();
-    myPtsMaskPoints->SetInput( aDataSet );
-    myPointLabels->SetVisibility( GetVisibility() );
-  }
-  else
-  {
-    myPointLabels->SetVisibility( false );
-  }
-  SetRepresentation(GetRepresentation());
-  myTimeStamp->Modified();
-}
+  if(my0DActor)
+    result = result || my0DActor->GetCellsLabeled();
 
+  if(myBallActor)
+    result = result || myBallActor->GetCellsLabeled();
 
-void SMESH_ActorDef::SetCellsLabeled(bool theIsCellsLabeled)
-{
-  vtkUnstructuredGrid* aGrid = GetUnstructuredGrid();
-  myIsCellsLabeled = theIsCellsLabeled && aGrid->GetNumberOfPoints();
-  if(myIsCellsLabeled){
-    myCellsNumDataSet->ShallowCopy(aGrid);
-    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);
-    }
-    aDataSet->GetCellData()->SetScalars(anArray);
-    myCellCenters->SetInput(aDataSet);
-    myCellsLabels->SetVisibility(GetVisibility());
-  }else{
-    myCellsLabels->SetVisibility(false);
-  }
-  myTimeStamp->Modified();
+  return result;
 }
 
 
@@ -573,6 +639,39 @@ bool SMESH_ActorDef::GetFacesOriented()
   return myIsFacesOriented;
 }
 
+void SMESH_ActorDef::SetFacesOrientationColor(vtkFloatingPointType theColor[3])
+{
+  my2DActor->SetFacesOrientationColor( theColor );
+  my3DActor->SetFacesOrientationColor( theColor );
+}
+
+void SMESH_ActorDef::GetFacesOrientationColor(vtkFloatingPointType theColor[3])
+{
+  my3DActor->GetFacesOrientationColor( theColor );
+}
+
+void SMESH_ActorDef::SetFacesOrientationScale(vtkFloatingPointType theScale)
+{
+  my2DActor->SetFacesOrientationScale( theScale );
+  my3DActor->SetFacesOrientationScale( theScale );
+}
+
+vtkFloatingPointType SMESH_ActorDef::GetFacesOrientationScale()
+{
+  return my3DActor->GetFacesOrientationScale();
+}
+
+void SMESH_ActorDef::SetFacesOrientation3DVectors(bool theState)
+{
+  my2DActor->SetFacesOrientation3DVectors( theState );
+  my3DActor->SetFacesOrientation3DVectors( theState );
+}
+
+bool SMESH_ActorDef::GetFacesOrientation3DVectors()
+{
+  return my3DActor->GetFacesOrientation3DVectors();
+}
+
 
 void 
 SMESH_ActorDef::
@@ -585,7 +684,7 @@ SetControlMode(eControl theMode)
 void 
 SMESH_ActorDef::
 SetControlMode(eControl theMode,
-              bool theCheckEntityMode)
+               bool theCheckEntityMode)
 {
   SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr();  
   if( !mgr )
@@ -594,59 +693,89 @@ SetControlMode(eControl theMode,
   myControlMode = eNone;
   theCheckEntityMode &= mgr->booleanValue( "SMESH", "display_entity", false );
 
+  my0DActor->GetMapper()->SetScalarVisibility(false);
   my1DActor->GetMapper()->SetScalarVisibility(false);
   my2DActor->GetMapper()->SetScalarVisibility(false);
   my3DActor->GetMapper()->SetScalarVisibility(false);
+  myBallActor->GetMapper()->SetScalarVisibility(false);
   myScalarBarActor->SetVisibility(false);
 
   bool anIsScalarVisible = theMode > eNone;
 
-  if(anIsScalarVisible){
-    SMESH::Controls::FunctorPtr aFunctor;
-    switch(theMode){
+  if(anIsScalarVisible) {
+    switch(theMode) {
     case eLength:
     {
       SMESH::Controls::Length* aControl = new SMESH::Controls::Length();
       aControl->SetPrecision( myControlsPrecision );
-      aFunctor.reset( aControl );
+      myFunctor.reset( aControl );
       myControlActor = my1DActor;
       break;
     }
     case eLength2D:
     {
-      aFunctor.reset(new SMESH::Controls::Length2D());
+      myFunctor.reset(new SMESH::Controls::Length2D());
       myControlActor = my2DActor;
       break;
     }
     case eFreeBorders:
-      aFunctor.reset(new SMESH::Controls::FreeBorders());
+      myFunctor.reset(new SMESH::Controls::FreeBorders());
       myControlActor = my1DActor;
       break;
     case eFreeEdges:
-      aFunctor.reset(new SMESH::Controls::FreeEdges());
+      myFunctor.reset(new SMESH::Controls::FreeEdges());
       myControlActor = my2DActor;
       break;
     case eFreeNodes:
-      aFunctor.reset(new SMESH::Controls::FreeNodes());
+      myFunctor.reset(new SMESH::Controls::FreeNodes());
       myControlActor = myNodeActor;
       break;
     case eFreeFaces:
-      aFunctor.reset(new SMESH::Controls::FreeFaces());
+      myFunctor.reset(new SMESH::Controls::FreeFaces());
+      myControlActor = my2DActor;
+      break;
+    case eCoincidentNodes:
+      {
+        SMESH::Controls::CoincidentNodes* cn = new SMESH::Controls::CoincidentNodes();
+        double tol = mgr->doubleValue( "SMESH", "equal_nodes_tolerance", 1e-7 );
+        cn->SetTolerance( tol );
+        myFunctor.reset(cn);
+        myControlActor = myNodeActor;
+        break;
+      }
+    case eCoincidentElems1D:
+      myFunctor.reset(new SMESH::Controls::CoincidentElements1D());
+      myControlActor = my1DActor;
+      break;
+    case eCoincidentElems2D:
+      myFunctor.reset(new SMESH::Controls::CoincidentElements2D());
+      myControlActor = my2DActor;
+      break;
+    case eCoincidentElems3D:
+      myFunctor.reset(new SMESH::Controls::CoincidentElements3D());
+      myControlActor = my3DActor;
+      break;
+    case eBareBorderFace:
+      myFunctor.reset(new SMESH::Controls::BareBorderFace());
+      myControlActor = my2DActor;
+      break;
+    case eOverConstrainedFace:
+      myFunctor.reset(new SMESH::Controls::OverConstrainedFace());
       myControlActor = my2DActor;
       break;
     case eMultiConnection:
-      aFunctor.reset(new SMESH::Controls::MultiConnection());
+      myFunctor.reset(new SMESH::Controls::MultiConnection());
       myControlActor = my1DActor;
       break;
     case eMultiConnection2D:
-      aFunctor.reset(new SMESH::Controls::MultiConnection2D());
+      myFunctor.reset(new SMESH::Controls::MultiConnection2D());
       myControlActor = my2DActor;
       break;
     case eArea:
     {
       SMESH::Controls::Area* aControl = new SMESH::Controls::Area();
       aControl->SetPrecision( myControlsPrecision );
-      aFunctor.reset( aControl );
+      myFunctor.reset( aControl );
       myControlActor = my2DActor;
       break;
     }
@@ -654,7 +783,7 @@ SetControlMode(eControl theMode,
     {
       SMESH::Controls::Taper* aControl = new SMESH::Controls::Taper();
       aControl->SetPrecision( myControlsPrecision );
-      aFunctor.reset( aControl );
+      myFunctor.reset( aControl );
       myControlActor = my2DActor;
       break;
     }
@@ -662,7 +791,7 @@ SetControlMode(eControl theMode,
     {
       SMESH::Controls::AspectRatio* aControl = new SMESH::Controls::AspectRatio();
       aControl->SetPrecision( myControlsPrecision );
-      aFunctor.reset( aControl );
+      myFunctor.reset( aControl );
       myControlActor = my2DActor;
       break;
     }
@@ -670,7 +799,7 @@ SetControlMode(eControl theMode,
     {
       SMESH::Controls::AspectRatio3D* aControl = new SMESH::Controls::AspectRatio3D();
       aControl->SetPrecision( myControlsPrecision );
-      aFunctor.reset( aControl );
+      myFunctor.reset( aControl );
       myControlActor = my3DActor;
       break;
     }
@@ -678,7 +807,35 @@ SetControlMode(eControl theMode,
     {
       SMESH::Controls::Volume* aControl = new SMESH::Controls::Volume();
       aControl->SetPrecision( myControlsPrecision );
-      aFunctor.reset( aControl );
+      myFunctor.reset( aControl );
+      myControlActor = my3DActor;
+      break;
+    }
+    case eMaxElementLength2D:
+    {
+      SMESH::Controls::MaxElementLength2D* aControl = new SMESH::Controls::MaxElementLength2D();
+      aControl->SetPrecision( myControlsPrecision );
+      myFunctor.reset( aControl );
+      myControlActor = my2DActor;
+      break;
+    }
+    case eMaxElementLength3D:
+    {
+      SMESH::Controls::MaxElementLength3D* aControl = new SMESH::Controls::MaxElementLength3D();
+      aControl->SetPrecision( myControlsPrecision );
+      myFunctor.reset( aControl );
+      myControlActor = my3DActor;
+      break;
+    }
+    case eBareBorderVolume:
+    {
+      myFunctor.reset(new SMESH::Controls::BareBorderVolume());
+      myControlActor = my3DActor;
+      break;
+    }
+    case eOverConstrainedVolume:
+    {
+      myFunctor.reset(new SMESH::Controls::OverConstrainedVolume());
       myControlActor = my3DActor;
       break;
     }
@@ -686,7 +843,7 @@ SetControlMode(eControl theMode,
     {
       SMESH::Controls::MinimumAngle* aControl = new SMESH::Controls::MinimumAngle();
       aControl->SetPrecision( myControlsPrecision );
-      aFunctor.reset( aControl );
+      myFunctor.reset( aControl );
       myControlActor = my2DActor;
       break;
     }
@@ -694,7 +851,7 @@ SetControlMode(eControl theMode,
     {
       SMESH::Controls::Warping* aControl = new SMESH::Controls::Warping();
       aControl->SetPrecision( myControlsPrecision );
-      aFunctor.reset( aControl );
+      myFunctor.reset( aControl );
       myControlActor = my2DActor;
       break;
     }
@@ -702,7 +859,7 @@ SetControlMode(eControl theMode,
     {
       SMESH::Controls::Skew* aControl = new SMESH::Controls::Skew();
       aControl->SetPrecision( myControlsPrecision );
-      aFunctor.reset( aControl );
+      myFunctor.reset( aControl );
       myControlActor = my2DActor;
       break;
     }
@@ -716,107 +873,143 @@ SetControlMode(eControl theMode,
       myControlMode = theMode;
       switch(myControlMode){
       case eFreeNodes:
-       myNodeExtActor->SetExtControlMode(aFunctor);
-       break;
+      case eCoincidentNodes:
+        myNodeExtActor->SetExtControlMode(myFunctor);
+        break;
       case eFreeEdges:
       case eFreeBorders:
-       my1DExtActor->SetExtControlMode(aFunctor);
-       break;
+      case eCoincidentElems1D:
+        my1DExtActor->SetExtControlMode(myFunctor);
+        break;
       case eFreeFaces:
-       my2DExtActor->SetExtControlMode(aFunctor);
-       break;
+      case eBareBorderFace:
+      case eOverConstrainedFace:
+      case eCoincidentElems2D:
+        my2DExtActor->SetExtControlMode(myFunctor);
+        break;
+      case eBareBorderVolume:
+      case eOverConstrainedVolume:
+      case eCoincidentElems3D:
+        my3DExtActor->SetExtControlMode(myFunctor);
+        break;
       case eLength2D:
       case eMultiConnection2D:
-       my1DExtActor->SetExtControlMode(aFunctor,myScalarBarActor,myLookupTable);
-       break;
+        my1DExtActor->SetExtControlMode(myFunctor,myScalarBarActor,myLookupTable);
+        UpdateDistribution();
+        break;
       default:
-       myControlActor->SetControlMode(aFunctor,myScalarBarActor,myLookupTable);
+        myControlActor->SetControlMode(myFunctor,myScalarBarActor,myLookupTable);
+        UpdateDistribution();
       }
     }
 
-    if(theCheckEntityMode){
-      if(myControlActor == my1DActor)
-       SetEntityMode(eEdges);
-      else if(myControlActor == my2DActor){
-       switch(myControlMode){
-       case eLength2D:
-       case eFreeEdges:
-       case eFreeFaces:
-       case eMultiConnection2D:
-         //SetEntityMode(eEdges);
-         SetEntityMode(eFaces);
-         break;
-       default:
-         SetEntityMode(eFaces);
-       }
-      }else if(myControlActor == my3DActor)
-       SetEntityMode(eVolumes);
+    if(theCheckEntityMode) {
+      if(myControlActor == my1DActor) {
+        if (!myIsEntityModeCache){
+          myEntityModeCache = GetEntityMode();
+          myIsEntityModeCache=true;
+        } 
+        SetEntityMode(eEdges);
+      }
+      else if(myControlActor == my2DActor) {
+        switch(myControlMode) {
+        case eLength2D:
+        case eFreeEdges:
+        case eFreeFaces:
+        case eMultiConnection2D:
+          if (!myIsEntityModeCache){
+            myEntityModeCache = GetEntityMode();
+            myIsEntityModeCache=true;
+          } 
+          SetEntityMode(eFaces);
+          break;
+        default:
+          if (!myIsEntityModeCache){
+            myEntityModeCache = GetEntityMode();
+            myIsEntityModeCache=true;
+          }
+          SetEntityMode(eFaces);
+        }
+      }else if(myControlActor == my3DActor) {
+        if (!myIsEntityModeCache){
+            myEntityModeCache = GetEntityMode();
+            myIsEntityModeCache=true;
+        } 
+        SetEntityMode(eVolumes);
+    }
     }
 
-  }else if(theCheckEntityMode){
-    myEntityMode = eAllEntity;
+  }
+  else {
+    if(theCheckEntityMode){
+      myEntityMode = myEntityModeCache;
+      myIsEntityModeCache = false;
+    }
+    myFunctor.reset();
   }
 
   SetRepresentation(GetRepresentation());
 
   myTimeStamp->Modified();
   Modified();
+  Update();
 }
 
 
 void SMESH_ActorDef::AddToRender(vtkRenderer* theRenderer){
-  SALOME_Actor::AddToRender(theRenderer);
-
-  theRenderer->AddActor(myNodeActor);
-  theRenderer->AddActor(myBaseActor);
-  
+  theRenderer->AddActor(myBaseActor);  
   theRenderer->AddActor(myNodeExtActor);
+  theRenderer->AddActor(my1DExtActor);
 
-  my3DActor->AddToRender(theRenderer);
-  my2DActor->AddToRender(theRenderer);
+  my3DActor   ->AddToRender(theRenderer);
+  my3DExtActor->AddToRender(theRenderer);
+  my2DActor   ->AddToRender(theRenderer);
   my2DExtActor->AddToRender(theRenderer);
-
-  theRenderer->AddActor(my1DActor);
-  theRenderer->AddActor(my1DExtActor);
+  myNodeActor ->AddToRender(theRenderer);
+  my1DActor   ->AddToRender(theRenderer);
+  my0DActor   ->AddToRender(theRenderer);
+  myBallActor ->AddToRender(theRenderer);
+  //theRenderer->AddActor(my0DExtActor);
 
   theRenderer->AddActor(myHighlitableActor);
   
   theRenderer->AddActor2D(myScalarBarActor);
 
-  myPtsSelectVisiblePoints->SetRenderer(theRenderer);
-  myClsSelectVisiblePoints->SetRenderer(theRenderer);
-
-  theRenderer->AddActor2D(myPointLabels);
-  theRenderer->AddActor2D(myCellsLabels);
+  // the superclass' method should be called at the end
+  // (in particular, for correct work of selection)
+  SALOME_Actor::AddToRender(theRenderer);
 }
 
 void SMESH_ActorDef::RemoveFromRender(vtkRenderer* theRenderer){
   SALOME_Actor::RemoveFromRender(theRenderer);
 
-  theRenderer->RemoveActor(myNodeActor);
   theRenderer->RemoveActor(myBaseActor);
 
   theRenderer->RemoveActor(myNodeExtActor);
 
   theRenderer->RemoveActor(myHighlitableActor);
 
-  theRenderer->RemoveActor(my1DActor);
+  //theRenderer->RemoveActor(my0DExtActor);
+
   theRenderer->RemoveActor(my1DExtActor);
 
   my2DActor->RemoveFromRender(theRenderer);
   my2DExtActor->RemoveFromRender(theRenderer);
   my3DActor->RemoveFromRender(theRenderer);
+  my3DExtActor->RemoveFromRender(theRenderer);
+  myNodeActor->RemoveFromRender(theRenderer);
+  my0DActor->RemoveFromRender(theRenderer);
+  myBallActor->RemoveFromRender(theRenderer);
+  my1DActor->RemoveFromRender(theRenderer);
 
   theRenderer->RemoveActor(myScalarBarActor);
-  theRenderer->RemoveActor(myPointLabels);
-  theRenderer->RemoveActor(myCellsLabels);
 }
 
 
 bool SMESH_ActorDef::Init(TVisualObjPtr theVisualObj, 
-                         const char* theEntry, 
-                         const char* theName,
-                         int theIsClear)
+                          const char* theEntry, 
+                          const char* theName,
+                          int theIsClear)
 {
   Handle(SALOME_InteractiveObject) anIO = new SALOME_InteractiveObject(theEntry,"SMESH",theName);
   setIO(anIO);
@@ -832,12 +1025,21 @@ bool SMESH_ActorDef::Init(TVisualObjPtr theVisualObj,
 
   myNodeExtActor->Init(myVisualObj,myImplicitBoolean);
   
+  my0DActor->Init(myVisualObj,myImplicitBoolean);
+  myBallActor->Init(myVisualObj,myImplicitBoolean);
+  //my0DExtActor->Init(myVisualObj,myImplicitBoolean);
+  
   my1DActor->Init(myVisualObj,myImplicitBoolean);
   my1DExtActor->Init(myVisualObj,myImplicitBoolean);
   
   my2DActor->Init(myVisualObj,myImplicitBoolean);
   my2DExtActor->Init(myVisualObj,myImplicitBoolean);
   my3DActor->Init(myVisualObj,myImplicitBoolean);
+  my3DExtActor->Init(myVisualObj,myImplicitBoolean);
+  
+  my0DActor->GetMapper()->SetLookupTable(myLookupTable);
+  myBallActor->GetMapper()->SetLookupTable(myLookupTable);
+  //my0DExtActor->GetMapper()->SetLookupTable(myLookupTable);
   
   my1DActor->GetMapper()->SetLookupTable(myLookupTable);
   my1DExtActor->GetMapper()->SetLookupTable(myLookupTable);
@@ -845,6 +1047,7 @@ bool SMESH_ActorDef::Init(TVisualObjPtr theVisualObj,
   my2DActor->GetMapper()->SetLookupTable(myLookupTable);
   my2DExtActor->GetMapper()->SetLookupTable(myLookupTable);
   my3DActor->GetMapper()->SetLookupTable(myLookupTable);
+  my3DExtActor->GetMapper()->SetLookupTable(myLookupTable);
     
   vtkFloatingPointType aFactor, aUnits;
   my2DActor->GetPolygonOffsetParameters(aFactor,aUnits);
@@ -875,6 +1078,13 @@ bool SMESH_ActorDef::Init(TVisualObjPtr theVisualObj,
     SetShrink();
   }
 
+  if( dynamic_cast<SMESH_GroupObj*>( myVisualObj.get() ) )
+    SetIsDisplayNameActor( true );
+
+  int aMarkerType = mgr->integerValue( "SMESH", "type_of_marker", 1 ); // dot
+  int aMarkerScale = mgr->integerValue( "SMESH", "marker_scale", 9 );  // 5 pixels
+  SetMarkerStd( (VTK::MarkerType)aMarkerType, (VTK::MarkerScale)aMarkerScale );
+
   myTimeStamp->Modified();
   Modified();
   return true;
@@ -901,12 +1111,17 @@ void SMESH_ActorDef::SetTransform(VTKViewer_Transform* theTransform){
 
   myNodeExtActor->SetTransform(theTransform);
 
+  my0DActor->SetTransform(theTransform);
+  myBallActor->SetTransform(theTransform);
+  //my0DExtActor->SetTransform(theTransform);
+
   my1DActor->SetTransform(theTransform);
   my1DExtActor->SetTransform(theTransform);
 
   my2DActor->SetTransform(theTransform);
   my2DExtActor->SetTransform(theTransform);
   my3DActor->SetTransform(theTransform);
+  my3DExtActor->SetTransform(theTransform);
 
   Modified();
 }
@@ -936,8 +1151,8 @@ bool SMESH_ActorDef::IsInfinitive(){
   vtkDataSet *aDataSet = myPickableActor->GetUnstructuredGrid();
   aDataSet->Update();
   myIsInfinite = aDataSet->GetNumberOfCells() == 0 ||
-    aDataSet->GetNumberOfCells() == 1 && 
-    aDataSet->GetCell(0)->GetCellType() == VTK_VERTEX;
+    aDataSet->GetNumberOfCells() == 1 && 
+    aDataSet->GetCell(0)->GetCellType() == VTK_VERTEX );
   return SALOME_Actor::IsInfinitive();
 }
 
@@ -962,6 +1177,9 @@ void SMESH_ActorDef::SetShrinkFactor(vtkFloatingPointType theValue){
   my2DActor->SetShrinkFactor(theValue);
   my2DExtActor->SetShrinkFactor(theValue);
   my3DActor->SetShrinkFactor(theValue);
+  my3DExtActor->SetShrinkFactor(theValue);
+  my3DExtActor->SetShrinkFactor(theValue);
+  myHighlitableActor->SetShrinkFactor(theValue);
 
   Modified();
 }
@@ -977,6 +1195,8 @@ void SMESH_ActorDef::SetShrink(){
   my2DActor->SetShrink();
   my2DExtActor->SetShrink();
   my3DActor->SetShrink();
+  my3DExtActor->SetShrink();
+  myHighlitableActor->SetShrink();
 
   myIsShrunk = true;
   Modified();
@@ -993,6 +1213,8 @@ void SMESH_ActorDef::UnShrink(){
   my2DActor->UnShrink();
   my2DExtActor->UnShrink();
   my3DActor->UnShrink();
+  my3DExtActor->UnShrink();
+  myHighlitableActor->UnShrink();
 
   myIsShrunk = false;
   Modified();
@@ -1030,16 +1252,19 @@ void SMESH_ActorDef::SetVisibility(int theMode, bool theIsUpdateRepersentation){
   
   myNodeExtActor->VisibilityOff();
 
+  my0DActor->VisibilityOff();
+  myBallActor->VisibilityOff();
+  //my0DExtActor->VisibilityOff();
+
   my1DActor->VisibilityOff();
   my1DExtActor->VisibilityOff();
   
   my2DActor->VisibilityOff();
   my2DExtActor->VisibilityOff();
   my3DActor->VisibilityOff();
+  my3DExtActor->VisibilityOff();
   
   myScalarBarActor->VisibilityOff();
-  myPointLabels->VisibilityOff();
-  myCellsLabels->VisibilityOff();
   
   if(GetVisibility()){
     if(theIsUpdateRepersentation)
@@ -1048,21 +1273,31 @@ void SMESH_ActorDef::SetVisibility(int theMode, bool theIsUpdateRepersentation){
     if(myControlMode != eNone){
       switch(myControlMode){
       case eFreeNodes:
-       myNodeExtActor->VisibilityOn();
-       break;
+      case eCoincidentNodes:
+        myNodeExtActor->VisibilityOn();
+        break;
       case eFreeEdges:
       case eFreeBorders:
-       my1DExtActor->VisibilityOn();
-       break;
+      case eCoincidentElems1D:
+        my1DExtActor->VisibilityOn();
+        break;
       case eFreeFaces:
-       my2DExtActor->VisibilityOn();
-       break;
+      case eBareBorderFace:
+      case eOverConstrainedFace:
+      case eCoincidentElems2D:
+        my2DExtActor->VisibilityOn();
+        break;
+      case eBareBorderVolume:
+      case eOverConstrainedVolume:
+      case eCoincidentElems3D:
+        my3DExtActor->VisibilityOn();
+        break;
       case eLength2D:
       case eMultiConnection2D:
-       my1DExtActor->VisibilityOn();
+        my1DExtActor->VisibilityOn();
       default:
-       if(myControlActor->GetUnstructuredGrid()->GetNumberOfCells())
-         myScalarBarActor->VisibilityOn();
+        if(myControlActor->GetUnstructuredGrid()->GetNumberOfCells())
+          myScalarBarActor->VisibilityOn();
       }
     }
 
@@ -1072,50 +1307,89 @@ void SMESH_ActorDef::SetVisibility(int theMode, bool theIsUpdateRepersentation){
       myNodeActor->VisibilityOn();
     }
 
-    if(myEntityMode & eEdges){
+    if(myEntityMode & e0DElements){
+      my0DActor->VisibilityOn();
+    }
+    if(myEntityMode & eBallElem){
+      myBallActor->VisibilityOn();
+    }
+
+    if(myEntityMode & eEdges && GetRepresentation() != ePoint){
       my1DActor->VisibilityOn();
     }
     
-    if(myEntityMode & eFaces){
+    if(myEntityMode & eFaces && GetRepresentation() != ePoint){
       my2DActor->VisibilityOn();
     }
     
-    if(myEntityMode & eVolumes){
+    if(myEntityMode & eVolumes && GetRepresentation() != ePoint){
       my3DActor->VisibilityOn();
     }
     
-    if(myIsPointsLabeled){ 
-      myPointLabels->VisibilityOn();
+    if(myNodeActor->GetPointsLabeled()){ 
       myNodeActor->VisibilityOn();
     }
 
-    if(myIsCellsLabeled) 
-      myCellsLabels->VisibilityOn();
-  }
+    if(my0DActor)
+      my0DActor->UpdateLabels();
+    
+    if(myBallActor)
+      myBallActor->UpdateLabels();
+    
+    if(my1DActor)
+      my1DActor->UpdateLabels();
+    
+    if(my2DActor)
+      my2DActor->UpdateLabels();
+    
+    if(my3DActor)
+      my3DActor->UpdateLabels();    
+  } 
+#ifndef DISABLE_PLOT2DVIEWER
+  else
+    SMESH::ProcessIn2DViewers(this,SMESH::RemoveFrom2dViewer);
+#endif
   UpdateHighlight();
   Modified();
 }
 
 
-void SMESH_ActorDef::SetEntityMode(unsigned int theMode){
+void SMESH_ActorDef::SetEntityMode(unsigned int theMode)
+{
   myEntityState = eAllEntity;
 
-  if(!myVisualObj->GetNbEntities(SMDSAbs_Edge)){
+  if(!myVisualObj->GetNbEntities(SMDSAbs_0DElement)) {
+    myEntityState &= ~e0DElements;
+    theMode &= ~e0DElements;
+  }
+
+  if(!myVisualObj->GetNbEntities(SMDSAbs_Ball)) {
+    myEntityState &= ~eBallElem;
+    theMode &= ~eBallElem;
+  }
+
+  if(!myVisualObj->GetNbEntities(SMDSAbs_Edge)) {
     myEntityState &= ~eEdges;
     theMode &= ~eEdges;
   }
 
-  if(!myVisualObj->GetNbEntities(SMDSAbs_Face)){
+  if(!myVisualObj->GetNbEntities(SMDSAbs_Face)) {
     myEntityState &= ~eFaces;
     theMode &= ~eFaces;
   }
 
-  if(!myVisualObj->GetNbEntities(SMDSAbs_Volume)){
+  if(!myVisualObj->GetNbEntities(SMDSAbs_Volume)) {
     myEntityState &= ~eVolumes;
     theMode &= ~eVolumes;
   }
 
-  if(!theMode){
+  if (!theMode) {
+    if(myVisualObj->GetNbEntities(SMDSAbs_0DElement))
+      theMode |= e0DElements;
+
+    if(myVisualObj->GetNbEntities(SMDSAbs_Ball))
+      theMode |= eBallElem;
+
     if(myVisualObj->GetNbEntities(SMDSAbs_Edge))
       theMode |= eEdges;
 
@@ -1133,70 +1407,119 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode){
   aFilter = myBaseActor->GetExtractUnstructuredGrid();
   aFilter->ClearRegisteredCellsWithType();
   aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
-  
-  if(myEntityMode & eEdges){
+
+  VTKViewer_ExtractUnstructuredGrid* aHightFilter = myHighlitableActor->GetExtractUnstructuredGrid();
+  aHightFilter->ClearRegisteredCellsWithType();
+  aHightFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
+
+  if (myEntityMode & e0DElements) {
+    if (MYDEBUG) MESSAGE("0D ELEMENTS");
+    aFilter->RegisterCellsWithType(VTK_VERTEX);
+    aHightFilter->RegisterCellsWithType(VTK_VERTEX);
+  }
+
+  if (myEntityMode & eBallElem) {
+    aFilter->RegisterCellsWithType(VTK_POLY_VERTEX);
+    aHightFilter->RegisterCellsWithType(VTK_POLY_VERTEX);
+  }
+
+  if (myEntityMode & eEdges) {
     if (MYDEBUG) MESSAGE("EDGES");
     aFilter->RegisterCellsWithType(VTK_LINE);
     aFilter->RegisterCellsWithType(VTK_QUADRATIC_EDGE);
+
+    aHightFilter->RegisterCellsWithType(VTK_LINE);
+    aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_EDGE);
   }
 
-  if(myEntityMode & eFaces){
+  if (myEntityMode & eFaces) {
     if (MYDEBUG) MESSAGE("FACES");
     aFilter->RegisterCellsWithType(VTK_TRIANGLE);
     aFilter->RegisterCellsWithType(VTK_POLYGON);
     aFilter->RegisterCellsWithType(VTK_QUAD);
     aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE);
     aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD);
+    aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUAD);
+
+    aHightFilter->RegisterCellsWithType(VTK_TRIANGLE);
+    aHightFilter->RegisterCellsWithType(VTK_POLYGON);
+    aHightFilter->RegisterCellsWithType(VTK_QUAD);
+    aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE);
+    aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD);
+    aHightFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUAD);
   }
 
-  if(myEntityMode & eVolumes){
+  if (myEntityMode & eVolumes) {
     if (MYDEBUG) MESSAGE("VOLUMES");
     aFilter->RegisterCellsWithType(VTK_TETRA);
     aFilter->RegisterCellsWithType(VTK_VOXEL);
     aFilter->RegisterCellsWithType(VTK_HEXAHEDRON);
     aFilter->RegisterCellsWithType(VTK_WEDGE);
     aFilter->RegisterCellsWithType(VTK_PYRAMID);
+    aFilter->RegisterCellsWithType(VTK_HEXAGONAL_PRISM);
     aFilter->RegisterCellsWithType(VTK_QUADRATIC_TETRA);
     aFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON);
+    aFilter->RegisterCellsWithType(VTK_TRIQUADRATIC_HEXAHEDRON);
     aFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE);
     aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
+//#ifdef VTK_HAVE_POLYHEDRON
+    aFilter->RegisterCellsWithType(VTK_POLYHEDRON);
+//#endif
+    
+    aHightFilter->RegisterCellsWithType(VTK_TETRA);
+    aHightFilter->RegisterCellsWithType(VTK_VOXEL);
+    aHightFilter->RegisterCellsWithType(VTK_HEXAHEDRON);
+    aHightFilter->RegisterCellsWithType(VTK_WEDGE);
+    aHightFilter->RegisterCellsWithType(VTK_PYRAMID);
+    aHightFilter->RegisterCellsWithType(VTK_HEXAGONAL_PRISM);
+    aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_TETRA);
+    aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON);
+    aHightFilter->RegisterCellsWithType(VTK_TRIQUADRATIC_HEXAHEDRON);
+    aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE);
+    aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID);
+    aHightFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
+//#ifdef VTK_HAVE_POLYHEDRON
+    aHightFilter->RegisterCellsWithType(VTK_POLYHEDRON);
+//#endif
   }
   aFilter->Update();
   if (MYDEBUG) MESSAGE(aFilter->GetOutput()->GetNumberOfCells());
   SetVisibility(GetVisibility(),false);
 }
 
-void SMESH_ActorDef::SetRepresentation(int theMode){ 
+void SMESH_ActorDef::SetRepresentation (int theMode)
+{ 
   int aNbEdges = myVisualObj->GetNbEntities(SMDSAbs_Edge);
   int aNbFaces = myVisualObj->GetNbEntities(SMDSAbs_Face);
   int aNbVolumes = myVisualObj->GetNbEntities(SMDSAbs_Volume);
-  if(theMode < 0){
+
+  if (theMode < 0) {
     myRepresentation = eSurface;
-    if(!aNbFaces && !aNbVolumes && aNbEdges){
+    if (!aNbFaces && !aNbVolumes && aNbEdges) {
       myRepresentation = eEdge;
-    }else if(!aNbFaces && !aNbVolumes && !aNbEdges){
+    } else if (!aNbFaces && !aNbVolumes && !aNbEdges) {
       myRepresentation = ePoint;
     }
-  }else{
-    switch(theMode){
+  } else {
+    switch (theMode) {
     case eEdge:
-      if(!aNbFaces && !aNbVolumes && !aNbEdges) return;
+      if (!aNbFaces && !aNbVolumes && !aNbEdges) return;
       break;
     case eSurface:
-      if(!aNbFaces && !aNbVolumes) return;
+      if (!aNbFaces && !aNbVolumes) return;
       break;
     }    
     myRepresentation = theMode;
   }
 
-  if(!GetUnstructuredGrid()->GetNumberOfCells())
+  if (!GetUnstructuredGrid()->GetNumberOfCells())
     myRepresentation = ePoint;
 
-  if(myIsShrunk){
-    if(myRepresentation == ePoint){
+  if (myIsShrunk) {
+    if (myRepresentation == ePoint) {
       UnShrink();
       myIsShrunk = true;
-    }else{
+    } else {
       SetShrink();
     }      
   }
@@ -1206,11 +1529,12 @@ void SMESH_ActorDef::SetRepresentation(int theMode){
   myNodeExtActor->SetVisibility(false);
   vtkProperty *aProp = NULL, *aBackProp = NULL;
   SMESH_DeviceActor::EReperesent aReperesent = SMESH_DeviceActor::EReperesent(-1);
-  switch(myRepresentation){
+  SMESH_Actor::EQuadratic2DRepresentation aQuadraticMode = GetQuadratic2DRepresentation();
+  switch (myRepresentation) {
   case ePoint:
     myPickableActor = myNodeActor;
     myNodeActor->SetVisibility(true);
-    
+    aQuadraticMode = SMESH_Actor::eLines;
     aProp = aBackProp = myNodeProp;
     aReperesent = SMESH_DeviceActor::ePoint;
     break;
@@ -1223,20 +1547,34 @@ void SMESH_ActorDef::SetRepresentation(int theMode){
     aBackProp = myBackSurfaceProp;
     aReperesent = SMESH_DeviceActor::eSurface;
     break;
-  }    
+  }
 
   my2DActor->SetProperty(aProp);
   my2DActor->SetBackfaceProperty(aBackProp);
   my2DActor->SetRepresentation(aReperesent);
 
+  if(aQuadraticMode == SMESH_Actor::eLines)
+    my2DActor->SetQuadraticArcMode(false);
+  else if(aQuadraticMode == SMESH_Actor::eArcs)
+    my2DActor->SetQuadraticArcMode(true);
+
   my2DExtActor->SetRepresentation(aReperesent);
   
   my3DActor->SetProperty(aProp);
   my3DActor->SetBackfaceProperty(aBackProp);
   my3DActor->SetRepresentation(aReperesent);
 
+  //my0DExtActor->SetVisibility(false);
   my1DExtActor->SetVisibility(false);
   my2DExtActor->SetVisibility(false);
+  my3DExtActor->SetVisibility(false);
+
+  // ???
+  //my0DActor->SetProperty(aProp);
+  //my0DActor->SetBackfaceProperty(aBackProp);
+  my0DActor->SetRepresentation(aReperesent);
+  myBallActor->SetRepresentation(aReperesent);
+  //my0DExtActor->SetRepresentation(aReperesent);
 
   switch(myControlMode){
   case eLength:
@@ -1247,12 +1585,17 @@ void SMESH_ActorDef::SetRepresentation(int theMode){
     break;
   }
   
+  if(aQuadraticMode == SMESH_Actor::eLines)
+    my1DActor->SetQuadraticArcMode(false);
+  else if(aQuadraticMode == SMESH_Actor::eArcs)
+    my1DActor->SetQuadraticArcMode(true);
+
   my1DActor->SetProperty(aProp);
   my1DActor->SetBackfaceProperty(aBackProp);
   my1DActor->SetRepresentation(aReperesent);
 
   my1DExtActor->SetRepresentation(aReperesent);
-  
+
   if(myIsPointsVisible)
     myPickableActor = myNodeActor;
   if(GetPointRepresentation())
@@ -1274,35 +1617,49 @@ void SMESH_ActorDef::SetPointRepresentation(bool theIsPointsVisible){
 }
 
 bool SMESH_ActorDef::GetPointRepresentation(){ 
-  return myIsPointsVisible || myIsPointsLabeled;
+  return myIsPointsVisible || myNodeActor->GetPointsLabeled();
 }
 
 
 void SMESH_ActorDef::UpdateHighlight(){
-  myHighlitableActor->SetVisibility(false);
   myHighlitableActor->SetHighlited(false);
-
-  if(myIsHighlighted){
-    myHighlitableActor->SetProperty(myHighlightProp);
-  }else if(myIsPreselected){
-    myHighlitableActor->SetProperty(myPreselectProp);
-  }
+  myHighlitableActor->SetVisibility(false);
 
   bool anIsVisible = GetVisibility();
 
-  if(myIsHighlighted || myIsPreselected){
-    if(GetUnstructuredGrid()->GetNumberOfCells()){
-      myHighlitableActor->SetHighlited(anIsVisible);
-      myHighlitableActor->SetVisibility(anIsVisible);
-      myHighlitableActor->GetExtractUnstructuredGrid()->
-       SetModeOfExtraction(VTKViewer_ExtractUnstructuredGrid::eCells);
-      myHighlitableActor->SetRepresentation(SMESH_DeviceActor::eWireframe);
-    }else if(myRepresentation == ePoint || GetPointRepresentation()){
-      myHighlitableActor->SetHighlited(anIsVisible);
-      myHighlitableActor->GetExtractUnstructuredGrid()->
-       SetModeOfExtraction(VTKViewer_ExtractUnstructuredGrid::ePoints);
+  switch(myRepresentation){
+  case SMESH_DeviceActor::eSurface:
+  case SMESH_DeviceActor::eWireframe:
+    {
+      if(myIsHighlighted) {
+        myHighlitableActor->SetProperty(myHighlightProp);
+      }else if(myIsPreselected){
+        myHighlitableActor->SetProperty(myPreselectProp);
+      } else if(anIsVisible){
+        (myRepresentation == eSurface) ? 
+          myHighlitableActor->SetProperty(myOutLineProp) : myHighlitableActor->SetProperty(myEdgeProp);
+      }
+      if(GetUnstructuredGrid()->GetNumberOfCells()) {
+        myHighlitableActor->SetHighlited(anIsVisible);
+        myHighlitableActor->GetExtractUnstructuredGrid()->
+          SetModeOfExtraction(VTKViewer_ExtractUnstructuredGrid::eCells);
+        myHighlitableActor->SetRepresentation(SMESH_DeviceActor::eWireframe);
+      }
       myHighlitableActor->SetVisibility(anIsVisible);
-      myHighlitableActor->SetRepresentation(SMESH_DeviceActor::ePoint);
+      break;
+    }
+  case SMESH_DeviceActor::ePoint:
+    {
+      if(myIsHighlighted) {
+        myNodeActor->SetProperty(myHighlightProp);
+      }else if(myIsPreselected) {
+        myNodeActor->SetProperty(myPreselectProp);
+      } else if(anIsVisible) {
+        myNodeActor->SetProperty(myNodeProp);
+      }
+      myNodeActor->SetRepresentation(SMESH_DeviceActor::ePoint);
+      myNodeActor->GetExtractUnstructuredGrid()->SetModeOfExtraction(VTKViewer_ExtractUnstructuredGrid::ePoints);
+      break;
     }
   }
 }
@@ -1367,15 +1724,33 @@ void SMESH_ActorDef::Update(){
     if (anObjTime > aTime)
       SetControlMode(GetControlMode(),false);
   }
-  if(myIsPointsLabeled){
-    SetPointsLabeled(myIsPointsLabeled);
-  }
-  if(myIsCellsLabeled){
-    SetCellsLabeled(myIsCellsLabeled);
-  }
+
+  if(myNodeActor)
+    myNodeActor->UpdateLabels();
+
+  if(my0DActor)
+    my0DActor->UpdateLabels();
+  
+  if(myBallActor)
+    myBallActor->UpdateLabels();
+  
+  if(my1DActor)
+    my1DActor->UpdateLabels();
+  
+  if(my2DActor)
+    my2DActor->UpdateLabels();
+
+  if(my3DActor)
+    my3DActor->UpdateLabels();
+  
   if(myIsFacesOriented){
     SetFacesOriented(myIsFacesOriented);
   }
+    
+  if(myVisualObj->GetEntitiesFlag()) {
+    myEntityMode |= myVisualObj->GetEntitiesState();
+  }
+  
   SetEntityMode(GetEntityMode());
   SetVisibility(GetVisibility());
   
@@ -1414,29 +1789,32 @@ vtkFloatingPointType SMESH_ActorDef::GetOpacity(){
 }
 
 
-void SMESH_ActorDef::SetSufaceColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b){
+void SMESH_ActorDef::SetSufaceColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b, int delta){
   mySurfaceProp->SetColor(r,g,b);
+  if( SMESH_GroupObj* aGroupObj = dynamic_cast<SMESH_GroupObj*>( myVisualObj.get() ) )
+    if( aGroupObj->GetElementType() == SMDSAbs_Face ||
+        aGroupObj->GetElementType() == SMDSAbs_Volume )
+      myNameActor->SetBackgroundColor(r,g,b);
+  
+  myDeltaBrightness = delta;
+  QColor bfc = Qtx::mainColorToSecondary(QColor(int(r*255),int(g*255),int(b*255)), delta);
+  myBackSurfaceProp->SetColor( bfc.red() / 255. , bfc.green() / 255. , bfc.blue() / 255. );
   Modified();
 }
 
-void SMESH_ActorDef::GetSufaceColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b){
+void SMESH_ActorDef::GetSufaceColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b, int& delta){
   ::GetColor(mySurfaceProp,r,g,b);
   my2DExtProp->SetColor(1.0-r,1.0-g,1.0-b);
-}
-
-void SMESH_ActorDef::SetBackSufaceColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b){
-  myBackSurfaceProp->SetColor(r,g,b);
-  Modified();
-}
-
-void SMESH_ActorDef::GetBackSufaceColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b){
-  ::GetColor(myBackSurfaceProp,r,g,b);
+  delta = myDeltaBrightness;
 }
 
 void SMESH_ActorDef::SetEdgeColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b){
   myEdgeProp->SetColor(r,g,b);
   my1DProp->SetColor(r,g,b);
   my1DExtProp->SetColor(1.0-r,1.0-g,1.0-b);
+  if( SMESH_GroupObj* aGroupObj = dynamic_cast<SMESH_GroupObj*>( myVisualObj.get() ) )
+    if( aGroupObj->GetElementType() == SMDSAbs_Edge )
+      myNameActor->SetBackgroundColor(r,g,b);
   Modified();
 }
 
@@ -1444,9 +1822,22 @@ void SMESH_ActorDef::GetEdgeColor(vtkFloatingPointType& r,vtkFloatingPointType&
   ::GetColor(myEdgeProp,r,g,b);
 }
 
+void SMESH_ActorDef::SetOutlineColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b){
+  myOutLineProp->SetColor(r,g,b);
+  Modified();
+}
+
+void SMESH_ActorDef::GetOutlineColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b){
+  ::GetColor(myOutLineProp,r,g,b);
+}
+
+
 void SMESH_ActorDef::SetNodeColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b){ 
   myNodeProp->SetColor(r,g,b);
   myNodeExtProp->SetColor(1.0-r,1.0-g,1.0-b);
+  if( SMESH_GroupObj* aGroupObj = dynamic_cast<SMESH_GroupObj*>( myVisualObj.get() ) )
+    if( aGroupObj->GetElementType() == SMDSAbs_Node )
+      myNameActor->SetBackgroundColor(r,g,b);
   Modified();
 }
 
@@ -1454,6 +1845,30 @@ void SMESH_ActorDef::GetNodeColor(vtkFloatingPointType& r,vtkFloatingPointType&
   ::GetColor(myNodeProp,r,g,b);
 }
 
+void SMESH_ActorDef::Set0DColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b){ 
+  my0DProp->SetColor(r,g,b);
+  if( SMESH_GroupObj* aGroupObj = dynamic_cast<SMESH_GroupObj*>( myVisualObj.get() ) )
+    if( aGroupObj->GetElementType() == SMDSAbs_0DElement )
+      myNameActor->SetBackgroundColor(r,g,b);
+  Modified();
+}
+
+void SMESH_ActorDef::Get0DColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b){ 
+  ::GetColor(my0DProp,r,g,b);
+}
+
+void SMESH_ActorDef::SetBallColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b){ 
+  myBallProp->SetColor(r,g,b);
+  if( SMESH_GroupObj* aGroupObj = dynamic_cast<SMESH_GroupObj*>( myVisualObj.get() ) )
+    if( aGroupObj->GetElementType() == SMDSAbs_Ball )
+      myNameActor->SetBackgroundColor(r,g,b);
+  Modified();
+}
+
+void SMESH_ActorDef::GetBallColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b){ 
+  ::GetColor(myBallProp,r,g,b);
+}
+
 void SMESH_ActorDef::SetHighlightColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b){ 
   myHighlightProp->SetColor(r,g,b);
   Modified();
@@ -1482,26 +1897,31 @@ void SMESH_ActorDef::SetLineWidth(vtkFloatingPointType theVal){
   myEdgeProp->SetLineWidth(theVal);
 
   my1DProp->SetLineWidth(theVal + aLineWidthInc);
-  my1DExtProp->SetLineWidth(theVal + aLineWidthInc);
-
+  my1DExtProp->SetLineWidth(theVal + aLineWidthInc);    
+  my2DExtProp->SetLineWidth(theVal + aLineWidthInc);
+  myOutLineProp->SetLineWidth(theVal);
+  myHighlightProp->SetLineWidth(theVal);
+  myPreselectProp->SetLineWidth(theVal);
   Modified();
 }
 
 
-void SMESH_ActorDef::SetNodeSize(vtkFloatingPointType theVal){
-  myNodeProp->SetPointSize(theVal);
-  myNodeExtProp->SetPointSize(theVal);
-  myHighlightProp->SetPointSize(theVal);
-  myPreselectProp->SetPointSize(theVal);
+void SMESH_ActorDef::Set0DSize(vtkFloatingPointType theVal){
+  my0DProp->SetPointSize(theVal);
+  Modified();
+}
 
-  my1DProp->SetPointSize(theVal + aPointSizeInc);
-  my1DExtProp->SetPointSize(theVal + aPointSizeInc);
+vtkFloatingPointType SMESH_ActorDef::Get0DSize(){
+  return my0DProp->GetPointSize();
+}
 
+void SMESH_ActorDef::SetBallSize(vtkFloatingPointType theVal){
+  myBallProp->SetPointSize(theVal);
   Modified();
 }
 
-vtkFloatingPointType SMESH_ActorDef::GetNodeSize(){
-  return myNodeProp->GetPointSize();
+vtkFloatingPointType SMESH_ActorDef::GetBallSize(){
+  return myBallProp->GetPointSize();
 }
 
 int SMESH_ActorDef::GetObjDimension( const int theObjId )
@@ -1517,33 +1937,37 @@ IsImplicitFunctionUsed() const
 }
 
 void
-SMESH_ActorDef::
-SetImplicitFunctionUsed(bool theIsImplicitFunctionUsed)
+SMESH_ActorDef::SetImplicitFunctionUsed(bool theIsImplicitFunctionUsed)
 {
   myNodeActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
   myBaseActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
-  
+
   myHighlitableActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
 
   myNodeExtActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
-  
+
+  my0DActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
+  myBallActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
+  //my0DExtActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
+
   my1DActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
   my1DExtActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
-  
+
   my2DActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
   my2DExtActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
   my3DActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
+  my3DExtActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
 }
 
 vtkIdType 
-SMESH_ActorDef::
-AddClippingPlane(vtkPlane* thePlane)
+SMESH_ActorDef::AddClippingPlane(vtkPlane* thePlane)
 {
   if(thePlane){
     myImplicitBoolean->GetFunction()->AddItem(thePlane);
     myCippingPlaneCont.push_back(thePlane);
     if(!IsImplicitFunctionUsed())
       SetImplicitFunctionUsed(true);
+    myNodeActor->UpdateLabels();
   }
   return myCippingPlaneCont.size();
 }
@@ -1556,6 +1980,7 @@ RemoveAllClippingPlanes()
   myImplicitBoolean->GetFunction()->Modified(); // VTK bug
   myCippingPlaneCont.clear();
   SetImplicitFunctionUsed(false);
+  myNodeActor->UpdateLabels();
 }
 
 vtkIdType
@@ -1574,92 +1999,6 @@ GetClippingPlane(vtkIdType theID)
   return myCippingPlaneCont[theID].Get();
 }
 
-
-static void ComputeBoundsParam(vtkDataSet* theDataSet,
-                              vtkFloatingPointType theDirection[3], vtkFloatingPointType theMinPnt[3],
-                              vtkFloatingPointType& theMaxBoundPrj, vtkFloatingPointType& theMinBoundPrj)
-{
-  vtkFloatingPointType aBounds[6];
-  theDataSet->GetBounds(aBounds);
-
-  //Enlarge bounds in order to avoid conflicts of precision
-  for(int i = 0; i < 6; i += 2){
-    static double EPS = 1.0E-3;
-    vtkFloatingPointType aDelta = (aBounds[i+1] - aBounds[i])*EPS;
-    aBounds[i] -= aDelta;
-    aBounds[i+1] += aDelta;
-  }
-
-  vtkFloatingPointType aBoundPoints[8][3] = { {aBounds[0],aBounds[2],aBounds[4]},
-                              {aBounds[1],aBounds[2],aBounds[4]},
-                              {aBounds[0],aBounds[3],aBounds[4]},
-                              {aBounds[1],aBounds[3],aBounds[4]},
-                              {aBounds[0],aBounds[2],aBounds[5]},
-                              {aBounds[1],aBounds[2],aBounds[5]}, 
-                              {aBounds[0],aBounds[3],aBounds[5]}, 
-                              {aBounds[1],aBounds[3],aBounds[5]}};
-
-  int aMaxId = 0, aMinId = aMaxId;
-  theMaxBoundPrj = vtkMath::Dot(theDirection,aBoundPoints[aMaxId]);
-  theMinBoundPrj = theMaxBoundPrj;
-  for(int i = 1; i < 8; i++){
-    vtkFloatingPointType aTmp = vtkMath::Dot(theDirection,aBoundPoints[i]);
-    if(theMaxBoundPrj < aTmp){
-      theMaxBoundPrj = aTmp;
-      aMaxId = i;
-    }
-    if(theMinBoundPrj > aTmp){
-      theMinBoundPrj = aTmp;
-      aMinId = i;
-    }
-  }
-  vtkFloatingPointType *aMinPnt = aBoundPoints[aMaxId];
-  theMinPnt[0] = aMinPnt[0];
-  theMinPnt[1] = aMinPnt[1];
-  theMinPnt[2] = aMinPnt[2];
-}
-
-
-static void DistanceToPosition(vtkDataSet* theDataSet,
-                              vtkFloatingPointType theDirection[3], vtkFloatingPointType theDist, vtkFloatingPointType thePos[3])
-{
-  vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
-  ComputeBoundsParam(theDataSet,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
-  vtkFloatingPointType aLength = (aMaxBoundPrj-aMinBoundPrj)*theDist;
-  thePos[0] = aMinPnt[0]-theDirection[0]*aLength;
-  thePos[1] = aMinPnt[1]-theDirection[1]*aLength;
-  thePos[2] = aMinPnt[2]-theDirection[2]*aLength;
-}
-
-
-static void PositionToDistance(vtkDataSet* theDataSet, 
-                              vtkFloatingPointType theDirection[3], vtkFloatingPointType thePos[3], vtkFloatingPointType& theDist)
-{
-  vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
-  ComputeBoundsParam(theDataSet,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
-  vtkFloatingPointType aPrj = vtkMath::Dot(theDirection,thePos);
-  theDist = (aPrj-aMinBoundPrj)/(aMaxBoundPrj-aMinBoundPrj);
-}
-
-
-void SMESH_ActorDef::SetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType theDist, vtkPlane* thePlane)
-{
-  thePlane->SetNormal(theDir);
-  vtkFloatingPointType anOrigin[3];
-  ::DistanceToPosition(GetUnstructuredGrid(),theDir,theDist,anOrigin);
-  thePlane->SetOrigin(anOrigin);
-}
-
-
-void SMESH_ActorDef::GetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType& theDist, vtkPlane* thePlane)
-{
-  thePlane->GetNormal(theDir);
-
-  vtkFloatingPointType anOrigin[3];
-  thePlane->GetOrigin(anOrigin);
-  ::PositionToDistance(GetUnstructuredGrid(),theDir,anOrigin,theDist);
-}
-
 void SMESH_ActorDef::UpdateScalarBar()
 {
   SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr();
@@ -1773,5 +2112,139 @@ void SMESH_ActorDef::UpdateScalarBar()
   if( mgr->hasValue( "SMESH", "scalar_bar_num_colors" ) )
     anIntVal = mgr->integerValue( "SMESH", "scalar_bar_num_colors", anIntVal );
   myScalarBarActor->SetMaximumNumberOfColors( anIntVal == 0 ? 64 : anIntVal );
+
+  bool distributionVisibility = mgr->booleanValue("SMESH","distribution_visibility");
+  myScalarBarActor->SetDistributionVisibility(distributionVisibility);
+
+  int coloringType = mgr->integerValue("SMESH", "distribution_coloring_type", 0);
+  myScalarBarActor->SetDistributionColoringType(coloringType);
   
+  QColor distributionColor = mgr->colorValue("SMESH", "distribution_color",
+                                             QColor(255, 255, 255));
+  double rgb[3];
+  rgb[0]= distributionColor.red()/255.;
+  rgb[1]= distributionColor.green()/255.;
+  rgb[2]= distributionColor.blue()/255.;
+  myScalarBarActor->SetDistributionColor(rgb);
+
+  
+}
+
+void SMESH_ActorDef::UpdateDistribution()
+{
+  if(SMESH::Controls::NumericalFunctor* fun =
+     dynamic_cast<SMESH::Controls::NumericalFunctor*>(myFunctor.get()))
+  {
+    int nbIntervals = myScalarBarActor->GetMaximumNumberOfColors();
+    std::vector<int> nbEvents;
+    std::vector<double> funValues;
+    SMESH_VisualObjDef::TEntityList elems;
+    if ( ! dynamic_cast<SMESH_MeshObj*>(myVisualObj.get()))
+      dynamic_cast<SMESH_VisualObjDef*>(myVisualObj.get())->GetEntities( fun->GetType(), elems );
+    std::vector<int> elemIds;
+    for ( SMESH_VisualObjDef::TEntityList::iterator e = elems.begin(); e != elems.end(); ++e)
+      elemIds.push_back( (*e)->GetID());
+    vtkLookupTable* lookupTable = static_cast<vtkLookupTable*>(myScalarBarActor->GetLookupTable());
+    double * range = lookupTable->GetRange();
+    fun->GetHistogram(nbIntervals, nbEvents, funValues, elemIds, range);
+    myScalarBarActor->SetDistribution(nbEvents);
+  }
+}
+
+void SMESH_ActorDef::SetQuadratic2DRepresentation(EQuadratic2DRepresentation theMode)
+{
+  switch(theMode) {
+  case SMESH_Actor::eLines :
+    myHighlitableActor->SetQuadraticArcMode(false);
+    my2DActor->SetQuadraticArcMode(false);
+    my1DActor->SetQuadraticArcMode(false);
+    break;
+  case SMESH_Actor::eArcs :
+    myHighlitableActor->SetQuadraticArcMode(true);
+    if(GetRepresentation() != SMESH_Actor::ePoint) {
+      my2DActor->SetQuadraticArcMode(true);
+      my1DActor->SetQuadraticArcMode(true);
+    }
+    break;
+  default:
+    break;
+  }
+}
+
+
+SMESH_Actor::EQuadratic2DRepresentation SMESH_ActorDef::GetQuadratic2DRepresentation()
+{
+  if(myHighlitableActor->GetQuadraticArcMode())
+    return SMESH_Actor::eArcs;
+  else
+    return SMESH_Actor::eLines;
+}
+
+void SMESH_ActorDef::SetMarkerStd( VTK::MarkerType theMarkerType, VTK::MarkerScale theMarkerScale )
+{
+  SALOME_Actor::SetMarkerStd( theMarkerType, theMarkerScale );
+  myNodeActor->SetMarkerStd( theMarkerType, theMarkerScale );
+  myNodeExtActor->SetMarkerStd( theMarkerType, theMarkerScale );
 }
+
+void SMESH_ActorDef::SetMarkerTexture( int theMarkerId, VTK::MarkerTexture theMarkerTexture )
+{
+  SALOME_Actor::SetMarkerTexture( theMarkerId, theMarkerTexture );
+  myNodeActor->SetMarkerTexture( theMarkerId, theMarkerTexture );
+  myNodeExtActor->SetMarkerTexture( theMarkerId, theMarkerTexture );
+  myMarkerTexture = theMarkerTexture; // for deferred update of myHighlightActor
+}
+
+#ifndef DISABLE_PLOT2DVIEWER
+SPlot2d_Histogram* SMESH_ActorDef::UpdatePlot2Histogram() {
+
+  if(my2dHistogram)
+    my2dHistogram->clearAllPoints();
+  
+  if(SMESH::Controls::NumericalFunctor* fun =
+     dynamic_cast<SMESH::Controls::NumericalFunctor*>(myFunctor.get()))
+  {
+    
+    if(!my2dHistogram) {
+      my2dHistogram = new SPlot2d_Histogram();
+      Handle(SALOME_InteractiveObject) anIO = new SALOME_InteractiveObject(getIO()->getEntry(),"SMESH",getName());
+      my2dHistogram->setIO(anIO);
+    }
+    
+    int nbIntervals = myScalarBarActor->GetMaximumNumberOfColors();
+    std::vector<int> nbEvents;
+    std::vector<double> funValues;
+    SMESH_VisualObjDef::TEntityList elems;
+    if ( ! dynamic_cast<SMESH_MeshObj*>(myVisualObj.get()))
+      dynamic_cast<SMESH_VisualObjDef*>(myVisualObj.get())->GetEntities( fun->GetType(), elems );
+    std::vector<int> elemIds;
+    
+    for ( SMESH_VisualObjDef::TEntityList::iterator e = elems.begin(); e != elems.end(); ++e)
+      elemIds.push_back( (*e)->GetID());
+
+    vtkLookupTable* lookupTable = static_cast<vtkLookupTable*>(myScalarBarActor->GetLookupTable());
+    double * range = lookupTable->GetRange();
+    fun->GetHistogram(nbIntervals, nbEvents, funValues, elemIds, range);
+
+    for ( int i = 0; i < std::min( nbEvents.size(), funValues.size() -1 ); i++ ) 
+      my2dHistogram->addPoint(funValues[i] + (funValues[i+1] - funValues[i])/2.0, static_cast<double>(nbEvents[i]));
+
+    if(funValues.size() >= 2)
+      my2dHistogram->setWidth((funValues[1] - funValues[0]) * 0.8) ;
+
+  }
+  
+  //Color of the histogram
+  if(myScalarBarActor->GetDistributionColoringType() == SMESH_MULTICOLOR_TYPE)
+    my2dHistogram->setAutoAssign(true);
+  else {
+    double rgb[3];
+    myScalarBarActor->GetDistributionColor(rgb);
+    QColor aColor = QColor( (int)( rgb[0]*255 ), (int)( rgb[1]*255 ), (int)( rgb[2]*255 ) );
+    my2dHistogram->setColor(aColor);
+
+  }
+      
+  return my2dHistogram;
+}
+#endif
index df02e86e4cbc29efb6decab87ea841ad233a6e82..4e04546f42237bb77bfd10fb74bfb149a8d9c2dd 100644 (file)
@@ -1,42 +1,55 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH OBJECT : interactive object for SMESH visualization
 //  File   : SMESH_Actor.h
 //  Author : Nicolas REJNERI
 //  Module : SMESH
-
+//
 #ifndef SMESH_ACTOR_H
 #define SMESH_ACTOR_H
 
+#include <SALOMEconfig.h> // To fix some redefinition
 #include <SALOME_Actor.h>
 #include "SMESH_Object.h"
 
+#include <vtkCommand.h>
+
 class vtkUnstructuredGrid;
 
-class vtkScalarBarActor;
+class SMESH_ScalarBarActor;
 
 class vtkPlane;
 class vtkImplicitBoolean;
 
+#ifndef DISABLE_PLOT2DVIEWER
+class SPlot2d_Histogram;
+#endif
+
+namespace SMESH
+{
+  const vtkIdType DeleteActorEvent = vtkCommand::UserEvent + 100;
+}
+
 class SMESHOBJECT_EXPORT SMESH_Actor: public SALOME_Actor
 {
   static SMESH_Actor* New() { return NULL;}
@@ -44,21 +57,27 @@ class SMESHOBJECT_EXPORT SMESH_Actor: public SALOME_Actor
  public:
   vtkTypeMacro(SMESH_Actor,SALOME_Actor);
   static SMESH_Actor* New(TVisualObjPtr theVisualObj, 
-                         const char* theEntry, 
-                         const char* theName,
-                         int theIsClear);
-  
-  virtual void SetSufaceColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b) = 0;
-  virtual void GetSufaceColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b) = 0;
-  
-  virtual void SetBackSufaceColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b) = 0;
-  virtual void GetBackSufaceColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b) = 0;
+                          const char* theEntry, 
+                          const char* theName,
+                          int theIsClear);
   
+  virtual void SetSufaceColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b, int delta ) = 0;
+  virtual void GetSufaceColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b, int& delta ) = 0;
+    
   virtual void SetEdgeColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b) = 0;
   virtual void GetEdgeColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b) = 0;
 
   virtual void SetNodeColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b) = 0;
   virtual void GetNodeColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b) = 0;
+  
+  virtual void SetOutlineColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b) = 0;
+  virtual void GetOutlineColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b) = 0;  
+
+  virtual void Set0DColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b) = 0;
+  virtual void Get0DColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b) = 0;
+
+  virtual void SetBallColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b) = 0;
+  virtual void GetBallColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b) = 0;
 
   virtual void SetHighlightColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b) = 0;
   virtual void GetHighlightColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b) = 0;
@@ -69,15 +88,24 @@ class SMESHOBJECT_EXPORT SMESH_Actor: public SALOME_Actor
   virtual vtkFloatingPointType GetLineWidth() = 0;
   virtual void SetLineWidth(vtkFloatingPointType theVal) = 0;
 
-  virtual void SetNodeSize(vtkFloatingPointType size) = 0;
-  virtual vtkFloatingPointType GetNodeSize() = 0;
+  virtual void Set0DSize(vtkFloatingPointType size) = 0;
+  virtual vtkFloatingPointType Get0DSize() = 0;
+
+  virtual void SetBallSize(vtkFloatingPointType size) = 0;
+  virtual vtkFloatingPointType GetBallSize() = 0;
 
   enum EReperesent { ePoint, eEdge, eSurface};
   
-  enum EEntityMode { eEdges = 0x01, eFaces = 0x02, eVolumes = 0x04, eAllEntity = 0x07};
+  enum EEntityMode { e0DElements = 0x01, eEdges = 0x02, eFaces = 0x04, eVolumes = 0x08, eBallElem = 0x10, eAllEntity = 0x1f};
+
+  enum EQuadratic2DRepresentation { eLines = 0x01, eArcs = 0x02 };
+
   virtual void SetEntityMode(unsigned int theMode) = 0;
   virtual unsigned int GetEntityMode() const = 0;
 
+  virtual void SetQuadratic2DRepresentation(EQuadratic2DRepresentation) = 0;
+  virtual EQuadratic2DRepresentation GetQuadratic2DRepresentation() = 0;
+
   virtual void SetPointRepresentation(bool theIsPointsVisible) = 0;
   virtual bool GetPointRepresentation() = 0;
 
@@ -94,16 +122,26 @@ class SMESHOBJECT_EXPORT SMESH_Actor: public SALOME_Actor
   virtual void SetFacesOriented(bool theIsFacesOriented) = 0;
   virtual bool GetFacesOriented() = 0;
 
+  virtual void SetFacesOrientationColor(vtkFloatingPointType theColor[3]) = 0;
+  virtual void GetFacesOrientationColor(vtkFloatingPointType theColor[3]) = 0;
+
+  virtual void SetFacesOrientationScale(vtkFloatingPointType theScale) = 0;
+  virtual vtkFloatingPointType GetFacesOrientationScale() = 0;
+
+  virtual void SetFacesOrientation3DVectors(bool theState) = 0;
+  virtual bool GetFacesOrientation3DVectors() = 0;
+
   enum eControl{eNone, eLength, eLength2D, eFreeBorders, eFreeEdges, eFreeNodes,
                 eFreeFaces, eMultiConnection, eArea, eTaper, eAspectRatio,
-                eMinimumAngle, eWarping, eSkew,        eAspectRatio3D, eMultiConnection2D, eVolume3D};
+                eMinimumAngle, eWarping, eSkew, eAspectRatio3D, eMultiConnection2D, eVolume3D,
+                eMaxElementLength2D, eMaxElementLength3D, eBareBorderFace, eBareBorderVolume,
+                eOverConstrainedFace, eOverConstrainedVolume, eCoincidentNodes,
+                eCoincidentElems1D, eCoincidentElems2D, eCoincidentElems3D };
   virtual void SetControlMode(eControl theMode) = 0;
   virtual eControl GetControlMode() = 0;
+  virtual SMESH::Controls::FunctorPtr GetFunctor() = 0;
 
-  virtual vtkScalarBarActor* GetScalarBarActor() = 0;
-
-  virtual void SetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType theDist, vtkPlane* thePlane) = 0;
-  virtual void GetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType& theDist, vtkPlane* thePlane) = 0;
+  virtual SMESH_ScalarBarActor* GetScalarBarActor() = 0;
 
   virtual void RemoveAllClippingPlanes() = 0; 
   virtual vtkIdType GetNumberOfClippingPlanes() = 0; 
@@ -116,6 +154,12 @@ class SMESHOBJECT_EXPORT SMESH_Actor: public SALOME_Actor
   virtual long GetControlsPrecision() const = 0;
 
   virtual void UpdateScalarBar() = 0;
+  virtual void UpdateDistribution() = 0;
+
+#ifndef DISABLE_PLOT2DVIEWER
+  virtual SPlot2d_Histogram* GetPlot2Histogram() = 0;
+  virtual SPlot2d_Histogram* UpdatePlot2Histogram() = 0;
+#endif
 };
 
 
index 619f0096a7f8dc60fbaf999ae4e062cdcf645398..b346e68b467d50648abb1cbdf18b952d137e12b2 100644 (file)
@@ -1,30 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH OBJECT : interactive object for SMESH visualization
 //  File   : SMESH_ActorDef.h
 //  Author : Nicolas REJNERI
 //  Module : SMESH
 //
-
 #ifndef SMESH_ACTORDEF_H
 #define SMESH_ACTORDEF_H
 
@@ -59,23 +59,21 @@ class vtkPolyDataMapper;
 class vtkUnstructuredGrid;
 class vtkMergeFilter;
 class vtkPolyData;
-
 class vtkMapper;
 class vtkActor2D;
-class vtkMaskPoints;
-class vtkCellCenters;
-class vtkLabeledDataMapper;
-class vtkSelectVisiblePoints;
-
-class vtkScalarBarActor;
 class vtkLookupTable;
-
 class vtkPlane;
 class vtkImplicitBoolean;
-
 class vtkTimeStamp;
 
 class SMESH_DeviceActor;
+class SMESH_NodeLabelActor;
+class SMESH_CellLabelActor;
+class SMESH_ScalarBarActor;
+
+#ifndef DISABLE_PLOT2DVIEWER
+class SPlot2d_Histogram;
+#endif
 
 
 class SMESH_ActorDef : public SMESH_Actor
@@ -86,6 +84,8 @@ class SMESH_ActorDef : public SMESH_Actor
  public:
   vtkTypeMacro(SMESH_ActorDef,SMESH_Actor);
   
+  virtual void Delete();
+
   virtual void ReleaseGraphicsResources(vtkWindow *renWin);
   virtual int RenderOpaqueGeometry(vtkViewport *viewport);
   virtual int RenderTranslucentGeometry(vtkViewport *viewport);
@@ -103,18 +103,25 @@ class SMESH_ActorDef : public SMESH_Actor
   virtual void SetOpacity(vtkFloatingPointType theValue);
   virtual vtkFloatingPointType GetOpacity();
 
-  virtual void SetSufaceColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b);
-  virtual void GetSufaceColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b);
-
-  virtual void SetBackSufaceColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b);
-  virtual void GetBackSufaceColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b);
+  virtual void SetSufaceColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b, int delta );
+  virtual void GetSufaceColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b, int& delta);
 
   virtual void SetEdgeColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b);
   virtual void GetEdgeColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b);
 
+  virtual void SetOutlineColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b);
+  virtual void GetOutlineColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b);
+
+
   virtual void SetNodeColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b);
   virtual void GetNodeColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b);
 
+  virtual void Set0DColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b);
+  virtual void Get0DColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b);
+
+  virtual void SetBallColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b);
+  virtual void GetBallColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b);
+
   virtual void SetHighlightColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b);
   virtual void GetHighlightColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b);
 
@@ -124,8 +131,11 @@ class SMESH_ActorDef : public SMESH_Actor
   virtual vtkFloatingPointType GetLineWidth();
   virtual void SetLineWidth(vtkFloatingPointType theVal);
 
-  virtual void SetNodeSize(vtkFloatingPointType size) ;
-  virtual vtkFloatingPointType GetNodeSize() ;
+  virtual void Set0DSize(vtkFloatingPointType size);
+  virtual vtkFloatingPointType Get0DSize();
+
+  virtual void SetBallSize(vtkFloatingPointType size);
+  virtual vtkFloatingPointType GetBallSize();
 
   virtual int GetNodeObjId(int theVtkID);
   virtual vtkFloatingPointType* GetNodeCoord(int theObjID);
@@ -162,21 +172,28 @@ class SMESH_ActorDef : public SMESH_Actor
   virtual void UnShrink(); 
 
   virtual void SetPointsLabeled(bool theIsPointsLabeled);
-  virtual bool GetPointsLabeled(){ return myIsPointsLabeled;}
+  virtual bool GetPointsLabeled();
 
   virtual void SetCellsLabeled(bool theIsCellsLabeled);
-  virtual bool GetCellsLabeled(){ return myIsCellsLabeled;}
+  virtual bool GetCellsLabeled();
 
   virtual void SetFacesOriented(bool theIsFacesOriented);
   virtual bool GetFacesOriented();
 
+  virtual void SetFacesOrientationColor(vtkFloatingPointType theColor[3]);
+  virtual void GetFacesOrientationColor(vtkFloatingPointType theColor[3]);
+
+  virtual void SetFacesOrientationScale(vtkFloatingPointType theScale);
+  virtual vtkFloatingPointType GetFacesOrientationScale();
+
+  virtual void SetFacesOrientation3DVectors(bool theState);
+  virtual bool GetFacesOrientation3DVectors();
+
   virtual void SetControlMode(eControl theMode);
   virtual eControl GetControlMode(){ return myControlMode;}
+  virtual SMESH::Controls::FunctorPtr GetFunctor() { return myFunctor; }
 
-  virtual vtkScalarBarActor* GetScalarBarActor(){ return myScalarBarActor;}
-
-  virtual void SetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType theDist, vtkPlane* thePlane);
-  virtual void GetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType& theDist, vtkPlane* thePlane);
+  virtual SMESH_ScalarBarActor* GetScalarBarActor(){ return myScalarBarActor;}
 
   virtual void RemoveAllClippingPlanes();
   virtual vtkIdType GetNumberOfClippingPlanes();
@@ -189,7 +206,20 @@ class SMESH_ActorDef : public SMESH_Actor
   virtual long GetControlsPrecision() const { return myControlsPrecision; }
 
   virtual void UpdateScalarBar();
+  virtual void UpdateDistribution();
+
+#ifndef DISABLE_PLOT2DVIEWER
+  virtual SPlot2d_Histogram* GetPlot2Histogram() { return my2dHistogram; }
+  virtual SPlot2d_Histogram* UpdatePlot2Histogram();
+#endif
+
+
+  virtual void SetQuadratic2DRepresentation(EQuadratic2DRepresentation);
+  virtual EQuadratic2DRepresentation GetQuadratic2DRepresentation();
   
+  virtual void SetMarkerStd( VTK::MarkerType, VTK::MarkerScale );
+  virtual void SetMarkerTexture( int, VTK::MarkerTexture );
+
  protected:
   void SetControlMode(eControl theMode, bool theCheckEntityMode);
   void SetImplicitFunctionUsed(bool theIsImplicitFunctionUsed);
@@ -198,7 +228,7 @@ class SMESH_ActorDef : public SMESH_Actor
   TVisualObjPtr myVisualObj;
   vtkTimeStamp* myTimeStamp;
 
-  vtkScalarBarActor* myScalarBarActor;
+  SMESH_ScalarBarActor* myScalarBarActor;
   vtkLookupTable* myLookupTable;
 
   vtkProperty* mySurfaceProp;
@@ -207,65 +237,71 @@ class SMESH_ActorDef : public SMESH_Actor
   vtkProperty* myNodeProp;
 
   SMESH_DeviceActor* myBaseActor;
-  SMESH_DeviceActor* myNodeActor;
+  SMESH_NodeLabelActor* myNodeActor;
   SMESH_DeviceActor* myPickableActor;
 
   vtkProperty* myHighlightProp;
+  vtkProperty* myOutLineProp;
   vtkProperty* myPreselectProp;
+          
   SMESH_DeviceActor* myHighlitableActor;
 
   eControl myControlMode;
+  SMESH::Controls::FunctorPtr myFunctor;
   vtkProperty* my2DExtProp;
-  SMESH_DeviceActor* my2DActor;
+  SMESH_CellLabelActor* my2DActor;
   SMESH_DeviceActor* my2DExtActor;
-  SMESH_DeviceActor* my3DActor;
+  SMESH_CellLabelActor* my3DActor;
+  SMESH_DeviceActor* my3DExtActor;
   SMESH_DeviceActor* myControlActor;
 
   vtkProperty* myNodeExtProp;
   SMESH_DeviceActor* myNodeExtActor;
 
   vtkProperty* my1DProp;
-  SMESH_DeviceActor* my1DActor;
+  SMESH_CellLabelActor* my1DActor;
   vtkProperty* my1DExtProp;
   SMESH_DeviceActor* my1DExtActor;
 
+  vtkProperty* my0DProp;
+  SMESH_CellLabelActor* my0DActor;
+  vtkProperty* myBallProp;
+  SMESH_CellLabelActor* myBallActor;
+  vtkProperty* my0DExtProp;
+  SMESH_DeviceActor* my0DExtActor;
+
   unsigned int myEntityMode;
   unsigned int myEntityState;
+  unsigned int myEntityModeCache;
+  bool myIsEntityModeCache;
   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;
-
   vtkImplicitBoolean* myImplicitBoolean;
   typedef TVTKSmartPtr<vtkPlane> TPlanePtr;
   typedef std::vector<TPlanePtr> TCippingPlaneCont;
   TCippingPlaneCont myCippingPlaneCont;
   long myControlsPrecision;
 
+#ifndef DISABLE_PLOT2DVIEWER
+  SPlot2d_Histogram* my2dHistogram;
+#endif
+
   bool myIsFacesOriented;
+  
+  int myDeltaBrightness;
+
+  VTK::MarkerTexture myMarkerTexture;
 
   SMESH_ActorDef();
   ~SMESH_ActorDef();
 
   bool Init(TVisualObjPtr theVisualObj, 
-           const char* theEntry, 
-           const char* theName,
-           int theIsClear);
+            const char* theEntry, 
+            const char* theName,
+            int theIsClear);
 
   void SetIsShrunkable(bool theShrunkable);
   void UpdateHighlight();
index c8fcbfe2489d97497adda170b64a6455c4a5cdf0..bb9fd64b185324fea24f498371bd67a37bedc711 100644 (file)
@@ -1,47 +1,63 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #include "SMESH_ActorUtils.h"
+#include "SMESH_Actor.h"
 
 #include "SUIT_Tools.h"
 #include "SUIT_Session.h"
 #include "SUIT_ResourceMgr.h"
+#include <SALOMEconfig.h> // To fix some redefinition
+#include "SalomeApp_Application.h"
+
+#ifndef DISABLE_PLOT2DVIEWER
+#include <SPlot2d_ViewModel.h>
+#include <SPlot2d_Histogram.h>
+#include <Plot2d_ViewManager.h>
+#endif
+
+#include <Qtx.h>
+
 
 #include "utilities.h"
 
 #include <vtkUnstructuredGrid.h>
+#include <vtkCellType.h>
+#include <vtkXMLUnstructuredGridWriter.h>
 #include <vtkUnstructuredGridWriter.h>
+#include <vtkUnsignedCharArray.h>
 
-#ifdef _DEBUG_
-static int MYDEBUG = 1;
-#else
-static int MYDEBUG = 0;
-#endif
+//#ifdef _DEBUG_
+//static int MYDEBUG = 1;
+//#else
+//static int MYDEBUG = 0;
+//#endif
 
 namespace SMESH
 {
 
   vtkFloatingPointType
   GetFloat( const QString& theValue, 
-           vtkFloatingPointType theDefault )
+            vtkFloatingPointType theDefault )
   {
     int pos = theValue.indexOf( ":" );
     vtkFloatingPointType val = theDefault;
@@ -50,15 +66,15 @@ namespace SMESH
       QString name = theValue.right( theValue.length()-pos-1 ),
               sect = theValue.left( pos );
       if( !name.isEmpty() && !sect.isEmpty() )
-       val = GetFloat( name, sect, theDefault );
+        val = GetFloat( name, sect, theDefault );
     }
     return val;
   }
 
   vtkFloatingPointType
   GetFloat( const QString& theValue, 
-           const QString& theSection, 
-           vtkFloatingPointType theDefault )
+            const QString& theSection, 
+            vtkFloatingPointType theDefault )
   {
     vtkFloatingPointType val = theDefault;
     SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr();
@@ -70,11 +86,12 @@ namespace SMESH
 
   void
   WriteUnstructuredGrid(vtkUnstructuredGrid* theGrid, 
-                       const char* theFileName)
+                        const char* theFileName)
   {
-    vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
+    vtkXMLUnstructuredGridWriter* aWriter = vtkXMLUnstructuredGridWriter::New();
     aWriter->SetFileName(theFileName);
     aWriter->SetInput(theGrid);
+    aWriter->SetDataModeToAscii();
     if(theGrid->GetNumberOfCells()){
       aWriter->Write();
     }
@@ -83,8 +100,8 @@ namespace SMESH
 
   QColor
   GetColor( const QString& theSect, 
-           const QString& theName, 
-           const QColor& def )
+            const QString& theName, 
+            const QColor& def )
   {
     QColor c = def;
     SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr();
@@ -95,11 +112,11 @@ namespace SMESH
 
   void
   GetColor( const QString& theSect, 
-           const QString& theName, 
-           int& r, 
-           int& g, 
-           int& b, 
-           const QColor& def )
+            const QString& theName, 
+            int& r, 
+            int& g, 
+            int& b, 
+            const QColor& def )
   {
     QColor c = def;
     SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr();
@@ -111,11 +128,11 @@ namespace SMESH
 
   void
   GetColor( const QString& theSect, 
-           const QString& theName, 
-           vtkFloatingPointType& r, 
-           vtkFloatingPointType& g, 
-           vtkFloatingPointType& b, 
-           const QColor& def )
+            const QString& theName, 
+            vtkFloatingPointType& r, 
+            vtkFloatingPointType& g, 
+            vtkFloatingPointType& b, 
+            const QColor& def )
   {
     int ir( 0 ), ig( 0 ), ib( 0 );
     GetColor( theSect, theName, ir, ig, ib, def );
@@ -123,4 +140,82 @@ namespace SMESH
     g = ig / 255.;
     b = ib / 255.;
   }
+
+
+  void
+  GetColor(  const QString& theSect, 
+            const QString& theName, 
+            QColor& color,
+            int& delta,
+            QString def) 
+  {
+    
+    SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr();
+    if ( mgr ) {
+      QString str = mgr->stringValue( theSect, theName, def );
+      Qtx::stringToBiColor(str,color,delta);
+    }
+  }
+
+  std::map<SMDSAbs_ElementType,int> GetEntitiesFromObject(SMESH_VisualObj *theObject) {
+    std::map<SMDSAbs_ElementType,int> entities;
+    entities.insert(std::pair<SMDSAbs_ElementType,int>(SMDSAbs_0DElement,
+               theObject ? theObject->GetNbEntities(SMDSAbs_0DElement) : 0));
+    entities.insert(std::pair<SMDSAbs_ElementType,int>(SMDSAbs_Ball,
+               theObject ? theObject->GetNbEntities(SMDSAbs_Ball) : 0));
+    entities.insert(std::pair<SMDSAbs_ElementType,int>(SMDSAbs_Edge,
+               theObject ? theObject->GetNbEntities(SMDSAbs_Edge) : 0));
+    entities.insert(std::pair<SMDSAbs_ElementType,int>(SMDSAbs_Face,
+               theObject ? theObject->GetNbEntities(SMDSAbs_Face) : 0));
+    entities.insert(std::pair<SMDSAbs_ElementType,int>(SMDSAbs_Volume,
+               theObject ? theObject->GetNbEntities(SMDSAbs_Volume) : 0));
+    return entities;
+  }
+  
+
+
+#ifndef DISABLE_PLOT2DVIEWER
+  //=======================================================================
+  /**
+     Get histogram from the input actor
+     Repaint/Remove the histogram in/from each opened Plot2D Viewer 
+  */
+  //=======================================================================
+  void ProcessIn2DViewers( SMESH_Actor *theActor, Viewer2dActionType aType ) {
+    SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>(SUIT_Session::session()->activeApplication());
+    
+    if(!anApp || !theActor)
+      return;
+    
+    SPlot2d_Histogram* aHistogram = 0;
+    
+    if(theActor->GetPlot2Histogram())
+      if(aType == UpdateIn2dViewer)
+        aHistogram = theActor->UpdatePlot2Histogram();
+      else
+        aHistogram = theActor->GetPlot2Histogram();
+    else 
+      return;
+    
+    ViewManagerList aViewManagerList;
+    anApp->viewManagers(SPlot2d_Viewer::Type(), aViewManagerList);
+    
+    aType = aHistogram->getPointList().empty() ? RemoveFrom2dViewer : aType;
+    
+    SUIT_ViewManager* aViewManager;
+    foreach( aViewManager, aViewManagerList ) {
+      if (Plot2d_ViewManager* aManager = dynamic_cast<Plot2d_ViewManager*>(aViewManager)) {
+        if (SPlot2d_Viewer* aViewer = dynamic_cast<SPlot2d_Viewer*>(aManager->getViewModel())) {
+          if (Plot2d_ViewFrame* aViewFrame = aViewer->getActiveViewFrame()) {
+            if(aType == UpdateIn2dViewer )
+              aViewFrame->displayObject(aHistogram, true);
+            else if (aType == RemoveFrom2dViewer)
+              aViewFrame->eraseObject(aHistogram, true);
+          }
+        }
+      }
+    }
+  }
+#endif //DISABLE_PLOT2DVIEWER
+  
 }
index a494f743b5d317b7486e5f846031cca3bed8a10e..3a15c40adcb9c97ec7f4524c8b7a754478a8573a 100644 (file)
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #ifndef SMESH_ACTORUTILS_H
 #define SMESH_ACTORUTILS_H
 
 #include "SMESH_Object.h"
+#include <map>
 
 #include <QColor>
 
 class vtkUnstructuredGrid;
+class SMESH_Actor;
 
 namespace SMESH
 {
 SMESHOBJECT_EXPORT  
   vtkFloatingPointType 
   GetFloat( const QString& theValue, 
-           vtkFloatingPointType theDefault = 0 );
+            vtkFloatingPointType theDefault = 0 );
 
 SMESHOBJECT_EXPORT
   vtkFloatingPointType 
   GetFloat( const QString& theName, 
-           const QString& theSection, 
-           vtkFloatingPointType theDefault = 0 );
+            const QString& theSection, 
+            vtkFloatingPointType theDefault = 0 );
 
 SMESHOBJECT_EXPORT
   QColor 
   GetColor( const QString& theSect, 
-           const QString& theName, 
-           const QColor& = QColor() );
+            const QString& theName, 
+            const QColor& = QColor() );
 
 SMESHOBJECT_EXPORT
   void
   GetColor( const QString& theSect, 
-           const QString& theName, 
-           int&, 
-           int&, 
-           int&, 
-           const QColor& = QColor() );
+            const QString& theName, 
+            int&, 
+            int&, 
+            int&, 
+            const QColor& = QColor() );
 
 SMESHOBJECT_EXPORT
   void
   GetColor( const QString& theSect, 
-           const QString& theName, 
-           vtkFloatingPointType&, 
-           vtkFloatingPointType&, 
-           vtkFloatingPointType&, 
-           const QColor& = QColor() );
+            const QString& theName, 
+            vtkFloatingPointType&, 
+            vtkFloatingPointType&, 
+            vtkFloatingPointType&, 
+            const QColor& = QColor() );
 
+ SMESHOBJECT_EXPORT
+   void
+   GetColor(  const QString& theSect, 
+             const QString& theName, 
+             QColor& color,
+             int& delta,
+             QString def);
+   
+ SMESHOBJECT_EXPORT
+   std::map<SMDSAbs_ElementType,int>
+   GetEntitiesFromObject(SMESH_VisualObj *theObject);
+   
 SMESHOBJECT_EXPORT
   void 
   WriteUnstructuredGrid(vtkUnstructuredGrid* theGrid, 
-                       const char* theFileName);
+                        const char* theFileName);
+
+
+#ifndef DISABLE_PLOT2DVIEWER
+ typedef enum {UpdateIn2dViewer = 0, RemoveFrom2dViewer } Viewer2dActionType;
+ SMESHOBJECT_EXPORT
+   void ProcessIn2DViewers( SMESH_Actor* theActor, Viewer2dActionType = UpdateIn2dViewer );
+#endif
+
 
 }
 
diff --git a/src/OBJECT/SMESH_CellLabelActor.cxx b/src/OBJECT/SMESH_CellLabelActor.cxx
new file mode 100644 (file)
index 0000000..3e117de
--- /dev/null
@@ -0,0 +1,185 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+//  File   : SMESH_CellLabelActor.cxx
+//  Author : Roman NIKOLAEV
+//  Module : SMESH
+//
+#include "SMESH_CellLabelActor.h"
+
+#include <VTKViewer_TransformFilter.h>
+#include <VTKViewer_CellCenters.h>
+
+#include <vtkObjectFactory.h>
+#include <vtkCallbackCommand.h>
+#include <vtkMaskPoints.h>
+#include <vtkSelectVisiblePoints.h>
+#include <vtkLabeledDataMapper.h>
+#include <vtkActor2D.h>
+#include <vtkTextProperty.h>
+#include <vtkPointData.h>
+#include <vtkProperty2D.h>
+#include <vtkRenderer.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkCellData.h>
+
+vtkStandardNewMacro(SMESH_CellLabelActor);
+
+/*!
+  Constructor.
+*/
+SMESH_CellLabelActor::SMESH_CellLabelActor() {
+    //Definition of cells numbering pipeline
+  //---------------------------------------
+  myCellsNumDataSet = vtkUnstructuredGrid::New();
+
+  myCellCenters = VTKViewer_CellCenters::New();
+  myCellCenters->SetInput(myCellsNumDataSet);
+
+  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("%d");
+  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);
+
+  vtkCallbackCommand* callBackCommand = vtkCallbackCommand::New();
+  callBackCommand->SetClientData(this);
+  callBackCommand->SetCallback(SMESH_CellLabelActor::ProcessEvents);
+
+  myTransformFilter->AddObserver("VTKViewer_TransformFilter::TransformationFinished",
+                                callBackCommand);
+  callBackCommand->Delete();
+}
+
+
+/*!
+  Destructor.
+*/
+SMESH_CellLabelActor::~SMESH_CellLabelActor() {
+  //Deleting of cells numbering pipeline
+  //---------------------------------------
+  myCellsNumDataSet->Delete();
+
+  myClsLabeledDataMapper->RemoveAllInputs();
+  myClsLabeledDataMapper->Delete();
+  
+  // commented: porting to vtk 5.0
+  //  myClsSelectVisiblePoints->UnRegisterAllOutputs();
+  myClsSelectVisiblePoints->Delete();
+  
+  // commented: porting to vtk 5.0
+  //  myClsMaskPoints->UnRegisterAllOutputs();
+  myClsMaskPoints->Delete();
+  
+  // commented: porting to vtk 5.0
+  //  myCellCenters->UnRegisterAllOutputs();
+  myCellCenters->Delete();
+  
+  myCellsLabels->Delete();
+}
+
+
+void SMESH_CellLabelActor::SetCellsLabeled(bool theIsCellsLabeled) {
+  myTransformFilter->Update();
+  vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::SafeDownCast(myTransformFilter->GetOutput());
+  if(!aGrid)
+    return;
+
+  myIsCellsLabeled = theIsCellsLabeled && aGrid->GetNumberOfPoints();
+  if(myIsCellsLabeled){
+    myCellsNumDataSet->ShallowCopy(aGrid);
+    vtkUnstructuredGrid *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);
+    }
+    aDataSet->GetCellData()->SetScalars(anArray);
+    myCellCenters->SetInput(aDataSet);
+    myCellsLabels->SetVisibility(GetVisibility());
+  }else{
+    myCellsLabels->SetVisibility(false);
+  }
+}
+
+void SMESH_CellLabelActor::SetVisibility(int theMode)
+{
+  SMESH_DeviceActor::SetVisibility(theMode);
+  myCellsLabels->VisibilityOff();
+  if(myIsCellsLabeled && theMode)
+    myCellsLabels->VisibilityOn();
+}
+
+void SMESH_CellLabelActor::AddToRender(vtkRenderer* theRenderer)
+{
+  SMESH_DeviceActor::AddToRender(theRenderer);
+  myClsSelectVisiblePoints->SetRenderer(theRenderer);
+  theRenderer->AddActor2D(myCellsLabels);
+}
+
+void SMESH_CellLabelActor::RemoveFromRender(vtkRenderer* theRenderer)
+{
+  theRenderer->RemoveActor(myCellsLabels);
+  SMESH_DeviceActor::RemoveFromRender(theRenderer);
+}
+
+void SMESH_CellLabelActor::UpdateLabels() {
+  if(myIsCellsLabeled)
+    SetCellsLabeled(myIsCellsLabeled);
+}
+
+
+void SMESH_CellLabelActor::ProcessEvents(vtkObject* vtkNotUsed(theObject),
+                                        unsigned long theEvent,
+                                        void* theClientData,
+                                        void* vtkNotUsed(theCallData)) {
+  SMESH_CellLabelActor* self = reinterpret_cast<SMESH_CellLabelActor*>(theClientData);
+  if(self)
+    self->UpdateLabels();
+}
diff --git a/src/OBJECT/SMESH_CellLabelActor.h b/src/OBJECT/SMESH_CellLabelActor.h
new file mode 100644 (file)
index 0000000..988a0dc
--- /dev/null
@@ -0,0 +1,82 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+//  File   : SMESH_CellLabelActor.h
+//  Author : Roman NIKOLAEV
+//  Module : SMESH
+//
+#ifndef SMESH_CELL_LABEL_ACTOR_H
+#define SMESH_CELL_LABEL_ACTOR_H
+
+#include "SMESH_DeviceActor.h"
+
+class vtkSelectVisiblePoints;
+class vtkLabeledDataMapper;
+class vtkActor2D;
+class vtkMaskPoints;
+class vtkUnstructuredGrid;
+
+class VTKViewer_CellCenters;
+
+
+class SMESHOBJECT_EXPORT SMESH_CellLabelActor : public SMESH_DeviceActor {
+public:
+  static SMESH_CellLabelActor* New();
+
+  static void ProcessEvents(vtkObject* theObject,
+                           unsigned long theEvent,
+                           void* theClientData,
+                           void* theCallData);
+
+
+  vtkTypeMacro(SMESH_CellLabelActor, SMESH_DeviceActor);
+
+
+  virtual void SetCellsLabeled(bool theIsCellsLabeled);
+  virtual bool GetCellsLabeled(){ return myIsCellsLabeled;}
+
+  virtual void SetVisibility(int theMode);
+
+  virtual void AddToRender(vtkRenderer* theRenderer);
+  virtual void RemoveFromRender(vtkRenderer* theRenderer);
+
+  void UpdateLabels();
+  
+protected:
+  SMESH_CellLabelActor();
+  ~SMESH_CellLabelActor();
+
+  bool myIsCellsLabeled;
+  vtkUnstructuredGrid* myCellsNumDataSet;
+  vtkActor2D *myCellsLabels;
+  vtkMaskPoints* myClsMaskPoints;
+  VTKViewer_CellCenters* myCellCenters;
+  vtkLabeledDataMapper* myClsLabeledDataMapper;
+  vtkSelectVisiblePoints* myClsSelectVisiblePoints;  
+  SMESH_DeviceActor* myBaseActor; //Pointer to the base actor
+
+protected:
+  // Not implemented.
+  SMESH_CellLabelActor(const SMESH_CellLabelActor&);
+  void operator=(const SMESH_CellLabelActor&);
+};
+
+#endif //SMESH_NODE_LABEL_ACTOR_H
index c24f10bfc8918f2849ed71400387b7c42a8d435c..7a88f701b6751579b33bba7b74e96f3924701c0b 100644 (file)
@@ -1,36 +1,38 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH OBJECT : interactive object for SMESH visualization
 //  File   : SMESH_DeviceActor.cxx
 //  Author : 
 //  Module : SMESH
 //
-
 #include "SMESH_DeviceActor.h"
+#include "SMESH_ScalarBarActor.h"
 #include "SMESH_ExtractGeometry.h"
 #include "SMESH_ControlsDef.hxx"
 #include "SMESH_ActorUtils.h"
 #include "SMESH_FaceOrientationFilter.h"
 #include "VTKViewer_CellLocationsArray.h"
+#include "VTKViewer_PolyDataMapper.h"
 
 #include <VTKViewer_Transform.h>
 #include <VTKViewer_TransformFilter.h>
@@ -47,7 +49,6 @@
 #include <vtkPolyDataMapper.h>
 #include <vtkUnstructuredGrid.h>
 
-#include <vtkScalarBarActor.h>
 #include <vtkLookupTable.h>
 #include <vtkDoubleArray.h>
 #include <vtkCellData.h>
@@ -88,10 +89,10 @@ SMESH_DeviceActor
   myRepresentation = eSurface;
 
   myProperty = vtkProperty::New();
-  myMapper = vtkPolyDataMapper::New();
+  myMapper = VTKViewer_PolyDataMapper::New();
 
   vtkMapper::GetResolveCoincidentTopologyPolygonOffsetParameters(myPolygonOffsetFactor,
-                                                                myPolygonOffsetUnits);
+                                                                 myPolygonOffsetUnits);
 
   myMapper->UseLookupTableScalarRangeOn();
   myMapper->SetColorModeToMapScalars();
@@ -239,17 +240,17 @@ SMESH_DeviceActor
     myPassFilter[ anId + 1]->SetInput( myPassFilter[ anId ]->GetOutput() );
     
     anId++; // 1
-    myGeomFilter->SetInput( myPassFilter[ anId ]->GetOutput() );
+    myTransformFilter->SetInput( myPassFilter[ anId ]->GetOutput() );
 
     anId++; // 2
-    myPassFilter[ anId ]->SetInput( myGeomFilter->GetOutput() ); 
+    myPassFilter[ anId ]->SetInput( myTransformFilter->GetOutput() );
     myPassFilter[ anId + 1 ]->SetInput( myPassFilter[ anId ]->GetOutput() );
 
     anId++; // 3
-    myTransformFilter->SetInput( myPassFilter[ anId ]->GetPolyDataOutput() );
+    myGeomFilter->SetInput( myPassFilter[ anId ]->GetOutput() );
 
     anId++; // 4
-    myPassFilter[ anId ]->SetInput( myTransformFilter->GetOutput() );
+    myPassFilter[ anId ]->SetInput( myGeomFilter->GetOutput() ); 
     myPassFilter[ anId + 1 ]->SetInput( myPassFilter[ anId ]->GetOutput() );
 
     anId++; // 5
@@ -281,8 +282,8 @@ SMESH_DeviceActor
 void
 SMESH_DeviceActor
 ::SetControlMode(SMESH::Controls::FunctorPtr theFunctor,
-                vtkScalarBarActor* theScalarBarActor,
-                vtkLookupTable* theLookupTable)
+                 SMESH_ScalarBarActor* theScalarBarActor,
+                 vtkLookupTable* theLookupTable)
 {
   bool anIsInitialized = theFunctor;
   if(anIsInitialized){
@@ -304,23 +305,23 @@ SMESH_DeviceActor
     using namespace SMESH::Controls;
     if(NumericalFunctor* aNumericalFunctor = dynamic_cast<NumericalFunctor*>(theFunctor.get())){
       for(vtkIdType i = 0; i < aNbCells; i++){
-       vtkIdType anId = myExtractUnstructuredGrid->GetInputId(i);
-       vtkIdType anObjId = myVisualObj->GetElemObjId(anId);
-       double aValue = aNumericalFunctor->GetValue(anObjId);
-       aScalars->SetValue(i,aValue);
+        vtkIdType anId = myExtractUnstructuredGrid->GetInputId(i);
+        vtkIdType anObjId = myVisualObj->GetElemObjId(anId);
+        double aValue = aNumericalFunctor->GetValue(anObjId);
+        aScalars->SetValue(i,aValue);
       }
     }else if(Predicate* aPredicate = dynamic_cast<Predicate*>(theFunctor.get())){
       for(vtkIdType i = 0; i < aNbCells; i++){
-       vtkIdType anId = myExtractUnstructuredGrid->GetInputId(i);
-       vtkIdType anObjId = myVisualObj->GetElemObjId(anId);
-       bool aValue = aPredicate->IsSatisfy(anObjId);
-       aScalars->SetValue(i,aValue);
+        vtkIdType anId = myExtractUnstructuredGrid->GetInputId(i);
+        vtkIdType anObjId = myVisualObj->GetElemObjId(anId);
+        bool aValue = aPredicate->IsSatisfy(anObjId);
+        aScalars->SetValue(i,aValue);
       }
     }
 
     aDataSet->GetCellData()->SetScalars(aScalars);
     aScalars->Delete();
-       
+        
     theLookupTable->SetRange(aScalars->GetRange());
     theLookupTable->SetNumberOfTableValues(theScalarBarActor->GetMaximumNumberOfColors());
     theLookupTable->Build();
@@ -335,8 +336,8 @@ SMESH_DeviceActor
 void
 SMESH_DeviceActor
 ::SetExtControlMode(SMESH::Controls::FunctorPtr theFunctor,
-                   vtkScalarBarActor* theScalarBarActor,
-                   vtkLookupTable* theLookupTable)
+                    SMESH_ScalarBarActor* theScalarBarActor,
+                    vtkLookupTable* theLookupTable)
 {
   bool anIsInitialized = theFunctor;
   myExtractUnstructuredGrid->ClearRegisteredCells();
@@ -374,18 +375,18 @@ SMESH_DeviceActor
       
       Length2D::TValues::const_iterator anIter = aValues.begin();
       for(vtkIdType aVtkId = 0; anIter != aValues.end(); anIter++,aVtkId++){
-       const Length2D::Value& aValue = *anIter;
-       int aNode[2] = {
-         myVisualObj->GetNodeVTKId(aValue.myPntId[0]),
-         myVisualObj->GetNodeVTKId(aValue.myPntId[1])
-       };
-       if(aNode[0] >= 0 && aNode[1] >= 0){
-         anIdList->SetId( 0, aNode[0] );
-         anIdList->SetId( 1, aNode[1] );
-         aConnectivity->InsertNextCell( anIdList );
-         aCellTypesArray->InsertNextValue( VTK_LINE );
-         aScalars->SetValue(aVtkId,aValue.myLength);
-       }
+        const Length2D::Value& aValue = *anIter;
+        int aNode[2] = {
+          myVisualObj->GetNodeVTKId(aValue.myPntId[0]),
+          myVisualObj->GetNodeVTKId(aValue.myPntId[1])
+        };
+        if(aNode[0] >= 0 && aNode[1] >= 0){
+          anIdList->SetId( 0, aNode[0] );
+          anIdList->SetId( 1, aNode[1] );
+          aConnectivity->InsertNextCell( anIdList );
+          aCellTypesArray->InsertNextValue( VTK_LINE );
+          aScalars->SetValue(aVtkId,aValue.myLength);
+        }
       }
       
       VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
@@ -394,7 +395,7 @@ SMESH_DeviceActor
       
       aConnectivity->InitTraversal();
       for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
-       aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
+        aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
       
       aDataSet->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
       SetUnstructuredGrid(aDataSet);
@@ -434,18 +435,18 @@ SMESH_DeviceActor
       
       MultiConnection2D::MValues::const_iterator anIter = aValues.begin();
       for(vtkIdType aVtkId = 0; anIter != aValues.end(); anIter++,aVtkId++){
-       const MultiConnection2D::Value& aValue = (*anIter).first;
-       int aNode[2] = {
-         myVisualObj->GetNodeVTKId(aValue.myPntId[0]),
-         myVisualObj->GetNodeVTKId(aValue.myPntId[1])
-       };
-       if(aNode[0] >= 0 && aNode[1] >= 0){
-         anIdList->SetId( 0, aNode[0] );
-         anIdList->SetId( 1, aNode[1] );
-         aConnectivity->InsertNextCell( anIdList );
-         aCellTypesArray->InsertNextValue( VTK_LINE );
-         aScalars->SetValue(aVtkId,(*anIter).second);
-       }
+        const MultiConnection2D::Value& aValue = (*anIter).first;
+        int aNode[2] = {
+          myVisualObj->GetNodeVTKId(aValue.myPntId[0]),
+          myVisualObj->GetNodeVTKId(aValue.myPntId[1])
+        };
+        if(aNode[0] >= 0 && aNode[1] >= 0){
+          anIdList->SetId( 0, aNode[0] );
+          anIdList->SetId( 1, aNode[1] );
+          aConnectivity->InsertNextCell( anIdList );
+          aCellTypesArray->InsertNextValue( VTK_LINE );
+          aScalars->SetValue(aVtkId,(*anIter).second);
+        }
       }
       
       VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
@@ -454,7 +455,7 @@ SMESH_DeviceActor
       
       aConnectivity->InitTraversal();
       for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
-       aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
+        aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
       
       aDataSet->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
       SetUnstructuredGrid(aDataSet);
@@ -483,21 +484,31 @@ SMESH_DeviceActor
   myVisualObj->UpdateFunctor(theFunctor);
 
   using namespace SMESH::Controls;
-  if ( dynamic_cast<FreeBorders*>(theFunctor.get()) ||
-       dynamic_cast<FreeFaces*>(theFunctor.get()) ) {
-    Predicate* aFreePredicate = dynamic_cast<Predicate*>(theFunctor.get());
+  if ( dynamic_cast<FreeBorders          *>(theFunctor.get()) ||
+       dynamic_cast<FreeFaces            *>(theFunctor.get()) ||
+       dynamic_cast<BareBorderVolume     *>(theFunctor.get()) ||
+       dynamic_cast<BareBorderFace       *>(theFunctor.get()) ||
+       dynamic_cast<OverConstrainedVolume*>(theFunctor.get()) ||
+       dynamic_cast<CoincidentElements1D *>(theFunctor.get()) ||
+       dynamic_cast<CoincidentElements2D *>(theFunctor.get()) ||
+       dynamic_cast<CoincidentElements3D *>(theFunctor.get()) ||
+       dynamic_cast<OverConstrainedFace  *>(theFunctor.get()))
+  {
+    Predicate* aPredicate = dynamic_cast<Predicate*>(theFunctor.get());
     myExtractUnstructuredGrid->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
     vtkUnstructuredGrid* aGrid = myVisualObj->GetUnstructuredGrid();
     vtkIdType aNbCells = aGrid->GetNumberOfCells();
     for( vtkIdType i = 0; i < aNbCells; i++ ){
       vtkIdType anObjId = myVisualObj->GetElemObjId(i);
-      if(aFreePredicate->IsSatisfy(anObjId))
-       myExtractUnstructuredGrid->RegisterCell(i);
+      if(aPredicate->IsSatisfy(anObjId))
+        myExtractUnstructuredGrid->RegisterCell(i);
     }
     if(!myExtractUnstructuredGrid->IsCellsRegistered())
       myExtractUnstructuredGrid->RegisterCell(-1);
     SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid());
-  }else if(FreeEdges* aFreeEdges = dynamic_cast<FreeEdges*>(theFunctor.get())){
+  }
+  else if(FreeEdges* aFreeEdges = dynamic_cast<FreeEdges*>(theFunctor.get()))
+  {
     SMESH::Controls::FreeEdges::TBorders aBorders;
     aFreeEdges->GetBoreders(aBorders);
     vtkUnstructuredGrid* aDataSet = vtkUnstructuredGrid::New();
@@ -520,15 +531,15 @@ SMESH_DeviceActor
     for(; anIter != aBorders.end(); anIter++){
       const FreeEdges::Border& aBorder = *anIter;
       int aNode[2] = {
-       myVisualObj->GetNodeVTKId(aBorder.myPntId[0]),
-       myVisualObj->GetNodeVTKId(aBorder.myPntId[1])
+        myVisualObj->GetNodeVTKId(aBorder.myPntId[0]),
+        myVisualObj->GetNodeVTKId(aBorder.myPntId[1])
       };
       //cout<<"aNode = "<<aBorder.myPntId[0]<<"; "<<aBorder.myPntId[1]<<endl;
       if(aNode[0] >= 0 && aNode[1] >= 0){
-       anIdList->SetId( 0, aNode[0] );
-       anIdList->SetId( 1, aNode[1] );
-       aConnectivity->InsertNextCell( anIdList );
-       aCellTypesArray->InsertNextValue( VTK_LINE );
+        anIdList->SetId( 0, aNode[0] );
+        anIdList->SetId( 1, aNode[1] );
+        aConnectivity->InsertNextCell( anIdList );
+        aCellTypesArray->InsertNextValue( VTK_LINE );
       }
     }
     
@@ -544,14 +555,17 @@ SMESH_DeviceActor
 
     SetUnstructuredGrid(aDataSet);
     aDataSet->Delete();
-  }else if(FreeNodes* aFreeNodes = dynamic_cast<FreeNodes*>(theFunctor.get())){
+  }
+  else if(dynamic_cast<FreeNodes      *>(theFunctor.get()) ||
+          dynamic_cast<CoincidentNodes*>(theFunctor.get()))
+  {
+    Predicate* aPredicate = dynamic_cast<Predicate*>(theFunctor.get());
     myExtractUnstructuredGrid->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
-    vtkUnstructuredGrid* aGrid = myVisualObj->GetUnstructuredGrid();
-    vtkIdType aNbCells = aGrid->GetNumberOfCells();
-    for( vtkIdType i = 0; i < aNbCells; i++ ){
+    vtkIdType aNbNodes = myVisualObj->GetNbEntities(SMDSAbs_Node);
+    for( vtkIdType i = 0; i < aNbNodes; i++ ){
       vtkIdType anObjId = myVisualObj->GetNodeObjId(i);
-      if(aFreeNodes->IsSatisfy(anObjId))
-       myExtractUnstructuredGrid->RegisterCell(i);
+      if(aPredicate->IsSatisfy(anObjId))
+        myExtractUnstructuredGrid->RegisterCell(i);
     }
     if(!myExtractUnstructuredGrid->IsCellsRegistered())
       myExtractUnstructuredGrid->RegisterCell(-1);
@@ -617,7 +631,7 @@ void
 SMESH_DeviceActor
 ::SetFacesOriented(bool theIsFacesOriented) 
 {
-  if ( vtkDataSet* aDataSet = myPassFilter[ 1 ]->GetOutput() )
+  if ( vtkDataSet* aDataSet = myTransformFilter->GetOutput() )
   {
     myIsFacesOriented = theIsFacesOriented;
     if( theIsFacesOriented )
@@ -626,6 +640,48 @@ SMESH_DeviceActor
   }
 }
 
+void
+SMESH_DeviceActor
+::SetFacesOrientationColor(vtkFloatingPointType theColor[3])
+{
+  myFaceOrientation->GetProperty()->SetColor( theColor );
+}
+
+void
+SMESH_DeviceActor
+::GetFacesOrientationColor(vtkFloatingPointType theColor[3])
+{
+  myFaceOrientation->GetProperty()->GetColor( theColor );
+}
+
+void
+SMESH_DeviceActor
+::SetFacesOrientationScale(vtkFloatingPointType theScale)
+{
+  myFaceOrientationFilter->SetOrientationScale( theScale );
+}
+
+vtkFloatingPointType
+SMESH_DeviceActor
+::GetFacesOrientationScale()
+{
+  return myFaceOrientationFilter->GetOrientationScale();
+}
+
+void
+SMESH_DeviceActor
+::SetFacesOrientation3DVectors(bool theState)
+{
+  myFaceOrientationFilter->Set3dVectors( theState );
+}
+
+bool
+SMESH_DeviceActor
+::GetFacesOrientation3DVectors()
+{
+  return myFaceOrientationFilter->Get3dVectors();
+}
+
 void
 SMESH_DeviceActor
 ::UpdateFaceOrientation()
@@ -662,6 +718,7 @@ SMESH_DeviceActor
     myGeomFilter->SetWireframeMode(false);
     GetProperty()->SetRepresentation(theMode);
   }
+  SetMarkerEnabled(theMode == ePoint);
   myRepresentation = theMode;
   UpdateFaceOrientation();
   GetProperty()->Modified();
@@ -828,9 +885,98 @@ SMESH_DeviceActor
 void
 SMESH_DeviceActor
 ::SetPolygonOffsetParameters(vtkFloatingPointType factor, 
-                            vtkFloatingPointType units)
+                             vtkFloatingPointType units)
 {
   myPolygonOffsetFactor = factor;
   myPolygonOffsetUnits = units;
 }
 
+/*!
+ * On/Off representation 2D quadratic element as arked polygon
+ */
+void SMESH_DeviceActor::SetQuadraticArcMode(bool theFlag){
+  myGeomFilter->SetQuadraticArcMode(theFlag);
+}
+
+/*!
+ * Return true if 2D quadratic element displayed as arked polygon
+ */
+bool SMESH_DeviceActor::GetQuadraticArcMode(){
+  return myGeomFilter->GetQuadraticArcMode();
+}
+/*!
+ * Set Max angle for representation 2D quadratic element as arked polygon
+ */
+void SMESH_DeviceActor::SetQuadraticArcAngle(vtkFloatingPointType theMaxAngle){
+  myGeomFilter->SetQuadraticArcAngle(theMaxAngle);
+}
+
+/*!
+ * Return Max angle of the representation 2D quadratic element as arked polygon
+ */
+vtkFloatingPointType SMESH_DeviceActor::GetQuadraticArcAngle(){
+  return myGeomFilter->GetQuadraticArcAngle();
+}
+
+/*!
+ * Set point marker enabled
+ * \param theMarkerEnabled flag to enable/disable point marker
+ */
+void SMESH_DeviceActor::SetMarkerEnabled( bool theMarkerEnabled )
+{
+  myMapper->SetMarkerEnabled( theMarkerEnabled );
+}
+
+/*!
+ * Set standard point marker
+ * \param theMarkerType type of the marker
+ */
+void SMESH_DeviceActor::SetMarkerStd( VTK::MarkerType theMarkerType, VTK::MarkerScale theMarkerScale )
+{
+  myMapper->SetMarkerStd( theMarkerType, theMarkerScale );
+}
+
+/*!
+ * Set custom point marker
+ * \param theMarkerId id of the marker texture
+ * \param theMarkerTexture marker texture
+ */
+void SMESH_DeviceActor::SetMarkerTexture( int theMarkerId, VTK::MarkerTexture theMarkerTexture )
+{
+  myMapper->SetMarkerTexture( theMarkerId, theMarkerTexture );
+}
+
+/*!
+ * Get type of the point marker
+ * \return type of the point marker
+ */
+VTK::MarkerType SMESH_DeviceActor::GetMarkerType()
+{
+  return myMapper->GetMarkerType();
+}
+
+/*!
+  Get scale of the point marker
+  \return scale of the point marker
+*/
+VTK::MarkerScale SMESH_DeviceActor::GetMarkerScale()
+{
+  return myMapper->GetMarkerScale();
+}
+
+/*!
+ * Get texture identifier of the point marker
+ * \return texture identifier of the point marker
+ */
+int SMESH_DeviceActor::GetMarkerTexture()
+{
+  return myMapper->GetMarkerTexture();
+}
+
+void SMESH_DeviceActor::SetCoincident3DAllowed(bool theFlag) {
+  myGeomFilter->SetAppendCoincident3D(theFlag);
+}
+
+bool SMESH_DeviceActor::IsCoincident3DAllowed() const {
+  return myGeomFilter->GetAppendCoincident3D();
+}
index 5a6169a95f3bb0f03c4c19cf7101fde21fa2f4bc..8c3abb7ae87f956077a9cf2e02171513a8ab01b1 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH OBJECT : interactive object for SMESH visualization
 //  File   : SMESH_DeviceActor.h
 //  Author : Nicolas REJNERI
@@ -29,6 +30,7 @@
 #define SMESH_DEVICE_ACTOR_H
 
 #include <VTKViewer_GeometryFilter.h>
+#include <VTKViewer_MarkerDef.h>
 #include "SMESH_Controls.hxx"
 #include "SMESH_Object.h"
 
@@ -39,9 +41,7 @@ class vtkCell;
 class vtkProperty;
 class vtkMergeFilter;
 class vtkShrinkFilter;
-class vtkPolyDataMapper;
 class vtkUnstructuredGrid;
-class vtkScalarBarActor;
 class vtkLookupTable;
 class vtkImplicitBoolean;
 class vtkPassThroughFilter;
@@ -49,9 +49,11 @@ class vtkPassThroughFilter;
 class VTKViewer_Transform;
 class VTKViewer_TransformFilter;
 class VTKViewer_ExtractUnstructuredGrid;
+class VTKViewer_PolyDataMapper;
 
 class SMESH_ExtractGeometry;
 class SMESH_FaceOrientationFilter;
+class SMESH_ScalarBarActor;
 
 
 class SMESHOBJECT_EXPORT SMESH_DeviceActor: public vtkLODActor{
@@ -77,6 +79,23 @@ class SMESHOBJECT_EXPORT SMESH_DeviceActor: public vtkLODActor{
   virtual void SetFacesOriented(bool theIsFacesOriented);
   virtual bool GetFacesOriented() { return myIsFacesOriented; }
 
+  virtual void SetFacesOrientationColor(vtkFloatingPointType theColor[3]);
+  virtual void GetFacesOrientationColor(vtkFloatingPointType theColor[3]);
+
+  virtual void SetFacesOrientationScale(vtkFloatingPointType theScale);
+  virtual vtkFloatingPointType GetFacesOrientationScale();
+
+  virtual void SetFacesOrientation3DVectors(bool theState);
+  virtual bool GetFacesOrientation3DVectors();
+
+  //----------------------------------------------------------------------------
+  //! Setting for displaying quadratic elements
+  virtual void SetQuadraticArcMode(bool theFlag);
+  virtual bool GetQuadraticArcMode();
+  
+  virtual void SetQuadraticArcAngle(vtkFloatingPointType theMaxAngle);
+  virtual vtkFloatingPointType GetQuadraticArcAngle();
+  
   void UpdateFaceOrientation();
 
   vtkFloatingPointType GetShrinkFactor();
@@ -101,26 +120,41 @@ class SMESHOBJECT_EXPORT SMESH_DeviceActor: public vtkLODActor{
   vtkUnstructuredGrid* GetUnstructuredGrid();
 
   void SetControlMode(SMESH::Controls::FunctorPtr theFunctor,
-                     vtkScalarBarActor* theScalarBarActor,
-                     vtkLookupTable* theLookupTable);
+                      SMESH_ScalarBarActor* theScalarBarActor,
+                      vtkLookupTable* theLookupTable);
   void SetExtControlMode(SMESH::Controls::FunctorPtr theFunctor,
-                        vtkScalarBarActor* theScalarBarActor,
-                        vtkLookupTable* theLookupTable);
+                         SMESH_ScalarBarActor* theScalarBarActor,
+                         vtkLookupTable* theLookupTable);
   void SetExtControlMode(SMESH::Controls::FunctorPtr theFunctor);
 
   bool IsHighlited() { return myIsHighlited;}
   void SetHighlited(bool theIsHighlited);
 
+  virtual
+  void
+  SetCoincident3DAllowed(bool theIsFeatureEdgesAllowed);
+
+  virtual
+  bool 
+  IsCoincident3DAllowed() const;
+
   virtual void Render(vtkRenderer *, vtkMapper *);
 
   void SetImplicitFunctionUsed(bool theIsImplicitFunctionUsed);
   bool IsImplicitFunctionUsed() const{ return myIsImplicitFunctionUsed;}
 
+  void SetMarkerEnabled( bool );
+  void SetMarkerStd( VTK::MarkerType, VTK::MarkerScale );
+  void SetMarkerTexture( int, VTK::MarkerTexture );
+  VTK::MarkerType GetMarkerType();
+  VTK::MarkerScale GetMarkerScale();
+  int GetMarkerTexture();
+
  protected:
   void Init(TVisualObjPtr theVisualObj, vtkImplicitBoolean* theImplicitBoolean);
   void SetUnstructuredGrid(vtkUnstructuredGrid* theGrid);
 
-  vtkPolyDataMapper *myMapper;
+  VTKViewer_PolyDataMapper *myMapper;
   TVisualObjPtr myVisualObj;
 
   vtkProperty *myProperty;
@@ -153,11 +187,11 @@ class SMESHOBJECT_EXPORT SMESH_DeviceActor: public vtkLODActor{
 
   void
   SetPolygonOffsetParameters(vtkFloatingPointType factor, 
-                            vtkFloatingPointType units);
+                             vtkFloatingPointType units);
 
   void
   GetPolygonOffsetParameters(vtkFloatingPointType& factor, 
-                            vtkFloatingPointType& units)
+                             vtkFloatingPointType& units)
   {
     factor = myPolygonOffsetFactor;
     units = myPolygonOffsetUnits;
index cebedd549c76b0f6a80f802caeabd106b246fd06..aad9a64474a7110208f147593c3105f36eea43ae 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #include "SMESH_ExtractGeometry.h"
 
 #include <vtkCell.h>
 
 using namespace std;
 
-#ifdef _DEBUG_
-static int MYDEBUG = 0;
-#else
-static int MYDEBUG = 0;
-#endif
+//#ifdef _DEBUG_
+//static int MYDEBUG = 0;
+//#else
+//static int MYDEBUG = 0;
+//#endif
 
 #if defined __GNUC__
   #if __GNUC__ == 2
@@ -58,22 +59,14 @@ SMESH_ExtractGeometry::~SMESH_ExtractGeometry(){}
 
 
 vtkIdType SMESH_ExtractGeometry::GetElemObjId(int theVtkID){
-  if(myElemVTK2ObjIds.empty() || theVtkID > myElemVTK2ObjIds.size()) return -1;
-#if defined __GNUC_2__
+  if( theVtkID < 0 || theVtkID >= myElemVTK2ObjIds.size()) return -1;
   return myElemVTK2ObjIds[theVtkID];
-#else
-  return myElemVTK2ObjIds.at(theVtkID);
-#endif
 }
 
 
 vtkIdType SMESH_ExtractGeometry::GetNodeObjId(int theVtkID){
-  if(myNodeVTK2ObjIds.empty() || theVtkID > myNodeVTK2ObjIds.size()) return -1;
-#if defined __GNUC_2__
+  if ( theVtkID < 0 || theVtkID >= myNodeVTK2ObjIds.size()) return -1;
   return myNodeVTK2ObjIds[theVtkID];
-#else
-  return myNodeVTK2ObjIds.at(theVtkID);
-#endif
 }
 
 
@@ -160,7 +153,7 @@ int SMESH_ExtractGeometry::RequestData(
         {
         newId = newPts->InsertNextPoint(x);
         pointMap[ptId] = newId;
-       myNodeVTK2ObjIds.push_back(ptId);
+        myNodeVTK2ObjIds.push_back(ptId);
         outputPD->CopyData(pd,ptId,newId);
         }
       }
@@ -183,7 +176,7 @@ int SMESH_ExtractGeometry::RequestData(
           {
           newId = newPts->InsertNextPoint(x);
           pointMap[ptId] = newId;
-         myNodeVTK2ObjIds.push_back(ptId);
+          myNodeVTK2ObjIds.push_back(ptId);
           outputPD->CopyData(pd,ptId,newId);
           }
         }
@@ -236,7 +229,7 @@ int SMESH_ExtractGeometry::RequestData(
             x = input->GetPoint(ptId);
             newId = newPts->InsertNextPoint(x);
             pointMap[ptId] = newId;
-           myNodeVTK2ObjIds.push_back(ptId);
+            myNodeVTK2ObjIds.push_back(ptId);
             outputPD->CopyData(pd,ptId,newId);
             }
           newCellPts->InsertId(i,pointMap[ptId]);
@@ -246,9 +239,14 @@ int SMESH_ExtractGeometry::RequestData(
       
     if ( npts >= numCellPts || (this->ExtractBoundaryCells && npts > 0) )
       {
-      newCellId = output->InsertNextCell(cell->GetCellType(),newCellPts);
-      myElemVTK2ObjIds.push_back(cellId);
-      outputCD->CopyData(cd,cellId,newCellId);
+        if(cell->GetCellType() == VTK_POLYHEDRON) {
+          newCellPts->Reset();
+          vtkUnstructuredGrid::SafeDownCast(input)->GetFaceStream( cellId ,newCellPts );        
+          vtkUnstructuredGrid::ConvertFaceStreamPointIds(newCellPts, pointMap);
+        }
+          newCellId = output->InsertNextCell(cell->GetCellType(),newCellPts);
+          myElemVTK2ObjIds.push_back(cellId);
+          outputCD->CopyData(cd,cellId,newCellId);
       }
     }//for all cells
 
index f1796b098a24e3287d37e26168cc6d55f3b8bdbb..97a6a012b04898c2d0598a74d68447d1eda7f749 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #ifndef SALOME_ExtractGeometry_HeaderFile
 #define SALOME_ExtractGeometry_HeaderFile
 
index a7f5d1d944da3eed8a299886c1d8c7d0cd647071..da38ecf2f11f532fc315375ce4cae7813f5abfeb 100644 (file)
@@ -1,30 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  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 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.
 //
-//  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
 //
-//  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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #include "SMESH_FaceOrientationFilter.h"
 #include "SMESH_ActorUtils.h"
 
 #include "SUIT_Session.h"
 #include "SUIT_ResourceMgr.h"
 
+#include <VTKViewer_CellCenters.h>
+
 #include <vtkCellData.h>
 #include <vtkDataSet.h>
 #include <vtkPolyData.h>
@@ -35,7 +35,6 @@
 #include <vtkFloatArray.h>
 #include <vtkCellArray.h>
 #include <vtkMaskPoints.h>
-#include <vtkCellCenters.h>
 #include <vtkGlyph3D.h>
 #include <vtkGlyphSource2D.h>
 
@@ -61,7 +60,7 @@ SMESH_FaceOrientationFilter::SMESH_FaceOrientationFilter()
 
   myFacePolyData = vtkPolyData::New();
 
-  myFaceCenters = vtkCellCenters::New();
+  myFaceCenters = VTKViewer_CellCenters::New();
   myFaceCenters->SetInput(myFacePolyData);
 
   myFaceMaskPoints = vtkMaskPoints::New();
@@ -91,6 +90,19 @@ SMESH_FaceOrientationFilter::~SMESH_FaceOrientationFilter()
   myBaseGlyph->Delete();
 }
 
+void SMESH_FaceOrientationFilter::SetOrientationScale( vtkFloatingPointType theScale )
+{
+  myOrientationScale = theScale;
+  Modified();
+}
+
+void SMESH_FaceOrientationFilter::Set3dVectors( bool theState )
+{
+  my3dVectors = theState;
+  myBaseGlyph->SetSource(my3dVectors ? myArrowPolyData : myGlyphSource->GetOutput());
+  Modified();
+}
+
 vtkPolyData* SMESH_FaceOrientationFilter::CreateArrowPolyData()
 {
   vtkPoints* points = vtkPoints::New();
@@ -209,8 +221,8 @@ void GetFaceParams( vtkCell* theFace, double theNormal[3], double& theSize )
 
   double* aBounds = theFace->GetBounds();
   theSize = pow( pow( aBounds[1] - aBounds[0], 2 ) +
-                pow( aBounds[3] - aBounds[2], 2 ) +
-                pow( aBounds[5] - aBounds[4], 2 ), 0.5 );
+                 pow( aBounds[3] - aBounds[2], 2 ) +
+                 pow( aBounds[5] - aBounds[4], 2 ), 0.5 );
 }
 
 /*!
@@ -268,7 +280,7 @@ int SMESH_FaceOrientationFilter::RequestData(
 
       input->GetCellNeighbors( aCellId, aFace->PointIds, aNeighborIds );
       if( aNeighborIds->GetNumberOfIds() > 0 )
-       continue;
+        continue;
 
       double aSize, aNormal[3];
       GetFaceParams( aFace, aNormal, aSize );
index d51b06b568cad684b42c9dc76a065af68ff4b01d..dcd4c33d596cfa6e09bc2f08883c8f2f5aa99672 100644 (file)
@@ -1,24 +1,22 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  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 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.
 //
-//  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
 //
-//  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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #ifndef SMESH_FACEORIENTATIONFILTER_H
 #define SMESH_FACEORIENTATIONFILTER_H
 
 
 #include <vtkPolyDataAlgorithm.h>
 
-class vtkCellCenters;
 class vtkGlyph3D;
 class vtkGlyphSource2D;
 class vtkMaskPoints;
 
+class VTKViewer_CellCenters;
+
 class SMESHOBJECT_EXPORT SMESH_FaceOrientationFilter : public vtkPolyDataAlgorithm
 {
 public:
@@ -39,6 +38,12 @@ public:
   /*!Create a new SMESH_FaceOrientationFilter.*/
   static SMESH_FaceOrientationFilter *New();
 
+  void SetOrientationScale( vtkFloatingPointType );
+  vtkFloatingPointType GetOrientationScale() const { return myOrientationScale; }
+
+  void Set3dVectors( bool );
+  bool Get3dVectors() const { return my3dVectors; }
+
 protected:
   SMESH_FaceOrientationFilter();
   virtual ~SMESH_FaceOrientationFilter();
@@ -59,7 +64,7 @@ private:
   vtkFloatingPointType myOrientationScale;
   vtkPolyData* myArrowPolyData;
   vtkPolyData* myFacePolyData;
-  vtkCellCenters* myFaceCenters;
+  VTKViewer_CellCenters* myFaceCenters;
   vtkMaskPoints* myFaceMaskPoints;
   vtkGlyphSource2D* myGlyphSource;
   vtkGlyph3D* myBaseGlyph;
diff --git a/src/OBJECT/SMESH_NodeLabelActor.cxx b/src/OBJECT/SMESH_NodeLabelActor.cxx
new file mode 100644 (file)
index 0000000..5d7b335
--- /dev/null
@@ -0,0 +1,187 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+//  File   : SMESH_NodeLabelActor.cxx
+//  Author : Roman NIKOLAEV
+//  Module : SMESH
+//
+#include "SMESH_NodeLabelActor.h"
+
+#include <VTKViewer_TransformFilter.h>
+
+#include <vtkObjectFactory.h>
+#include <vtkCallbackCommand.h>
+#include <vtkMaskPoints.h>
+#include <vtkSelectVisiblePoints.h>
+#include <vtkLabeledDataMapper.h>
+#include <vtkActor2D.h>
+#include <vtkTextProperty.h>
+#include <vtkPointData.h>
+#include <vtkProperty2D.h>
+#include <vtkRenderer.h>
+#include <vtkUnstructuredGrid.h>
+
+vtkStandardNewMacro(SMESH_NodeLabelActor);
+
+/*!
+  Constructor.
+*/
+SMESH_NodeLabelActor::SMESH_NodeLabelActor() {
+  //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("%d");
+  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);
+
+  vtkCallbackCommand* callBackCommand = vtkCallbackCommand::New();
+  callBackCommand->SetClientData(this);
+  callBackCommand->SetCallback(SMESH_NodeLabelActor::ProcessEvents);
+
+  myTransformFilter->AddObserver("VTKViewer_TransformFilter::TransformationFinished",
+                                callBackCommand);
+  callBackCommand->Delete();
+}
+
+/*!
+  Destructor
+*/
+SMESH_NodeLabelActor::~SMESH_NodeLabelActor() {
+  //Deleting of points numbering pipeline
+  //---------------------------------------
+  myPointsNumDataSet->Delete();
+  
+  // commented: porting to vtk 5.0
+  //  myPtsLabeledDataMapper->RemoveAllInputs();
+  myPtsLabeledDataMapper->Delete();
+  
+  // commented: porting to vtk 5.0
+  //  myPtsSelectVisiblePoints->UnRegisterAllOutputs();
+  myPtsSelectVisiblePoints->Delete();
+  
+  // commented: porting to vtk 5.0
+  //  myPtsMaskPoints->UnRegisterAllOutputs();
+  myPtsMaskPoints->Delete();
+  myPointLabels->Delete();
+
+}
+
+void SMESH_NodeLabelActor::SetPointsLabeled(bool theIsPointsLabeled) {
+  myTransformFilter->Update();
+  vtkDataSet* aGrid = vtkUnstructuredGrid::SafeDownCast(myTransformFilter->GetOutput());
+
+  if(!aGrid)
+    return;
+    
+  myIsPointsLabeled = theIsPointsLabeled && aGrid->GetNumberOfPoints();
+
+  if ( myIsPointsLabeled )
+  {
+    myPointsNumDataSet->ShallowCopy(aGrid);
+    vtkUnstructuredGrid *aDataSet = myPointsNumDataSet;
+    
+    int aNbElem = aDataSet->GetNumberOfPoints();
+    
+    vtkIntArray *anArray = vtkIntArray::New();
+    anArray->SetNumberOfValues( aNbElem );
+    
+    for ( vtkIdType anId = 0; anId < aNbElem; anId++ )
+    {
+      int aSMDSId = myVisualObj->GetNodeObjId( anId );
+      anArray->SetValue( anId, aSMDSId );
+    }
+    
+    aDataSet->GetPointData()->SetScalars( anArray );
+    myPtsMaskPoints->SetInput( aDataSet );
+    myPointLabels->SetVisibility( GetVisibility() );
+    anArray->Delete();
+  }
+  else
+  {
+    myPointLabels->SetVisibility( false );
+  } 
+}
+
+
+void SMESH_NodeLabelActor::SetVisibility(int theMode)
+{
+  SMESH_DeviceActor::SetVisibility(theMode);
+  myPointLabels->VisibilityOff();
+  if(myIsPointsLabeled && theMode)
+    myPointLabels->VisibilityOn();
+}
+
+
+void SMESH_NodeLabelActor::AddToRender(vtkRenderer* theRenderer)
+{
+  SMESH_DeviceActor::AddToRender(theRenderer);
+  myPtsSelectVisiblePoints->SetRenderer(theRenderer);
+  theRenderer->AddActor2D(myPointLabels);
+}
+
+void SMESH_NodeLabelActor::RemoveFromRender(vtkRenderer* theRenderer)
+{
+  theRenderer->RemoveActor(myPointLabels);
+  SMESH_DeviceActor::RemoveFromRender(theRenderer);
+}
+
+void SMESH_NodeLabelActor::UpdateLabels() {
+  if(myIsPointsLabeled)
+    SetPointsLabeled(myIsPointsLabeled);
+}
+
+
+void SMESH_NodeLabelActor::ProcessEvents(vtkObject* vtkNotUsed(theObject),
+                                        unsigned long theEvent,
+                                        void* theClientData,
+                                        void* vtkNotUsed(theCallData)) {
+  SMESH_NodeLabelActor* self = reinterpret_cast<SMESH_NodeLabelActor*>(theClientData);    
+  if(self)
+    self->UpdateLabels();
+}
diff --git a/src/OBJECT/SMESH_NodeLabelActor.h b/src/OBJECT/SMESH_NodeLabelActor.h
new file mode 100644 (file)
index 0000000..a15a233
--- /dev/null
@@ -0,0 +1,78 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+//  File   : SMESH_NodeLabelActor.h
+//  Author : Roman NIKOLAEV
+//  Module : SMESH
+//
+#ifndef SMESH_NODE_LABEL_ACTOR_H
+#define SMESH_NODE_LABEL_ACTOR_H
+
+#include "SMESH_DeviceActor.h"
+
+class vtkSelectVisiblePoints;
+class vtkLabeledDataMapper;
+class vtkActor2D;
+class vtkMaskPoints;
+class vtkUnstructuredGrid;
+
+
+class SMESHOBJECT_EXPORT SMESH_NodeLabelActor : public SMESH_DeviceActor {
+public:
+  static SMESH_NodeLabelActor* New();
+
+  static void ProcessEvents(vtkObject* theObject,
+                           unsigned long theEvent,
+                           void* theClientData,
+                           void* theCallData);
+
+
+  vtkTypeMacro(SMESH_NodeLabelActor, SMESH_DeviceActor);
+
+
+  virtual void SetPointsLabeled(bool theIsPointsLabeled);
+  virtual bool GetPointsLabeled(){ return myIsPointsLabeled;}  
+
+  virtual void SetVisibility(int theMode);  
+
+  virtual void AddToRender(vtkRenderer* theRenderer); 
+  virtual void RemoveFromRender(vtkRenderer* theRenderer);
+
+  void UpdateLabels();
+  
+protected:
+  SMESH_NodeLabelActor();
+  ~SMESH_NodeLabelActor();
+  
+  bool myIsPointsLabeled;
+  vtkUnstructuredGrid* myPointsNumDataSet;
+  vtkActor2D *myPointLabels;
+  vtkMaskPoints* myPtsMaskPoints;
+  vtkLabeledDataMapper* myPtsLabeledDataMapper;
+  vtkSelectVisiblePoints* myPtsSelectVisiblePoints;
+
+protected:
+  // Not implemented.
+  SMESH_NodeLabelActor(const SMESH_NodeLabelActor&);
+  void operator=(const SMESH_NodeLabelActor&);
+};
+
+#endif //SMESH_NODE_LABEL_ACTOR_H
index a885c49b9fc54837b52778d1329f3984ae9d6b31..e137a1c6d202d47ec858db715030421bd8653246 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH OBJECT : interactive object for SMESH visualization
 //  File   : SMESH_Grid.cxx
 //  Author : Nicolas REJNERI
@@ -46,7 +47,7 @@
 #include <vtkUnstructuredGrid.h>
 
 #include <memory>
-#include <sstream>     
+#include <sstream>      
 #include <stdexcept>
 #include <set>
 
@@ -63,8 +64,8 @@ using namespace std;
 #endif
 
 #ifdef _DEBUG_
-static int MYDEBUG = 0;
-static int MYDEBUGWITHFILES = 0;
+static int MYDEBUG = 1;
+static int MYDEBUGWITHFILES = 0;//1;
 #else
 static int MYDEBUG = 0;
 static int MYDEBUGWITHFILES = 0;
@@ -81,11 +82,15 @@ static int MYDEBUGWITHFILES = 0;
 // purpose  : Get type of VTK cell
 //=================================================================================
 static inline vtkIdType getCellType( const SMDSAbs_ElementType theType,
-                                    const bool thePoly,
+                                     const bool thePoly,
                                      const int theNbNodes )
 {
   switch( theType )
   {
+    case SMDSAbs_0DElement:         return VTK_VERTEX;
+
+    case SMDSAbs_Ball:   return VTK_POLY_VERTEX;
+
     case SMDSAbs_Edge: 
       if( theNbNodes == 2 )         return VTK_LINE;
       else if ( theNbNodes == 3 )   return VTK_QUADRATIC_EDGE;
@@ -97,26 +102,21 @@ static inline vtkIdType getCellType( const SMDSAbs_ElementType theType,
       else if ( theNbNodes == 4 )   return VTK_QUAD;
       else if ( theNbNodes == 6 )   return VTK_QUADRATIC_TRIANGLE;
       else if ( theNbNodes == 8 )   return VTK_QUADRATIC_QUAD;
+      else if ( theNbNodes == 9 )   return VTK_BIQUADRATIC_QUAD;
       else return VTK_EMPTY_CELL;
       
     case SMDSAbs_Volume:
-      if (thePoly && theNbNodes>3 ) return VTK_CONVEX_POINT_SET;
+      if (thePoly && theNbNodes>3 ) return VTK_POLYHEDRON; //VTK_CONVEX_POINT_SET;
       else if ( theNbNodes == 4 )   return VTK_TETRA;
       else if ( theNbNodes == 5 )   return VTK_PYRAMID;
       else if ( theNbNodes == 6 )   return VTK_WEDGE;
       else if ( theNbNodes == 8 )   return VTK_HEXAHEDRON;
-      else if ( theNbNodes == 10 )  {
-        return VTK_QUADRATIC_TETRA;
-      }
-      else if ( theNbNodes == 20 )  {
-        return VTK_QUADRATIC_HEXAHEDRON;
-      }
-      else if ( theNbNodes == 15 )  {
-        return VTK_QUADRATIC_WEDGE;
-      }
-      else if ( theNbNodes==13 )  {
-        return VTK_CONVEX_POINT_SET;
-      }
+      else if ( theNbNodes == 12 )  return VTK_HEXAGONAL_PRISM;
+      else if ( theNbNodes == 10 )  return VTK_QUADRATIC_TETRA;
+      else if ( theNbNodes == 20 )  return VTK_QUADRATIC_HEXAHEDRON;
+      else if ( theNbNodes == 27 )  return VTK_TRIQUADRATIC_HEXAHEDRON;
+      else if ( theNbNodes == 15 )  return VTK_QUADRATIC_WEDGE;
+      else if ( theNbNodes == 13 )  return VTK_QUADRATIC_PYRAMID; //VTK_CONVEX_POINT_SET;
       else return VTK_EMPTY_CELL;
 
     default: return VTK_EMPTY_CELL;
@@ -129,11 +129,16 @@ static inline vtkIdType getCellType( const SMDSAbs_ElementType theType,
 //=================================================================================
 SMESH_VisualObjDef::SMESH_VisualObjDef()
 {
+  MESSAGE("---------------------------------------------SMESH_VisualObjDef::SMESH_VisualObjDef");
   myGrid = vtkUnstructuredGrid::New();
+  myLocalGrid = false;
+  ClearEntitiesFlags();
+  SMESH::GetEntitiesFromObject(NULL);
 }
 SMESH_VisualObjDef::~SMESH_VisualObjDef()
 {
-  if ( MYDEBUG )
+  MESSAGE("---------------------------------------------SMESH_VisualObjDef::~SMESH_VisualObjDef");
+  //if ( MYDEBUG )
     MESSAGE( "~SMESH_MeshObj - myGrid->GetReferenceCount() = " << myGrid->GetReferenceCount() );
   myGrid->Delete();
 }
@@ -144,28 +149,58 @@ SMESH_VisualObjDef::~SMESH_VisualObjDef()
 //=================================================================================
 vtkIdType SMESH_VisualObjDef::GetNodeObjId( int theVTKID )
 {
-  return myVTK2SMDSNodes.find(theVTKID) == myVTK2SMDSNodes.end() ? -1 : myVTK2SMDSNodes[theVTKID];
+        if (myLocalGrid)
+        {
+                TMapOfIds::const_iterator i = myVTK2SMDSNodes.find(theVTKID);
+                return i == myVTK2SMDSNodes.end() ? -1 : i->second;
+        }
+  return this->GetMesh()->FindNodeVtk(theVTKID)->GetID();
 }
 
 vtkIdType SMESH_VisualObjDef::GetNodeVTKId( int theObjID )
 {
-  return mySMDS2VTKNodes.find(theObjID) == mySMDS2VTKNodes.end() ? -1 : mySMDS2VTKNodes[theObjID];
+        if (myLocalGrid)
+        {
+                TMapOfIds::const_iterator i = mySMDS2VTKNodes.find(theObjID);
+    return i == mySMDS2VTKNodes.end() ? -1 : i->second;
+        }
+
+        const SMDS_MeshNode* aNode = 0;
+        if( this->GetMesh() ) {
+          aNode = this->GetMesh()->FindNode(theObjID);
+        }
+        return aNode ? aNode->getVtkId() : -1;
 }
 
 vtkIdType SMESH_VisualObjDef::GetElemObjId( int theVTKID )
 {
-  return myVTK2SMDSElems.find(theVTKID) == myVTK2SMDSElems.end() ? -1 : myVTK2SMDSElems[theVTKID];
+        if (myLocalGrid)
+        {
+                TMapOfIds::const_iterator i = myVTK2SMDSElems.find(theVTKID);
+                return i == myVTK2SMDSElems.end() ? -1 : i->second;
+        }
+  return this->GetMesh()->fromVtkToSmds(theVTKID);
 }
 
 vtkIdType SMESH_VisualObjDef::GetElemVTKId( int theObjID )
 {
-  return mySMDS2VTKElems.find(theObjID) == mySMDS2VTKElems.end() ? -1 : mySMDS2VTKElems[theObjID];
+        if (myLocalGrid)
+        {
+                TMapOfIds::const_iterator i = mySMDS2VTKElems.find(theObjID);
+                return i == mySMDS2VTKElems.end() ? -1 : i->second;
+        }
+  return this->GetMesh()->FindElement(theObjID)->getVtkId();
+  //return this->GetMesh()->fromSmdsToVtk(theObjID);
 }
 
 //=================================================================================
 // function : SMESH_VisualObjDef::createPoints
 // purpose  : Create points from nodes
 //=================================================================================
+/*! fills a vtkPoints structure for a submesh.
+ *  fills a std::list of SMDS_MeshElements*, then extract the points.
+ *  fills also conversion id maps between SMDS and VTK.
+ */
 void SMESH_VisualObjDef::createPoints( vtkPoints* thePoints )
 {
   if ( thePoints == 0 )
@@ -174,7 +209,7 @@ void SMESH_VisualObjDef::createPoints( vtkPoints* thePoints )
   TEntityList aNodes;
   vtkIdType nbNodes = GetEntities( SMDSAbs_Node, aNodes );
   thePoints->SetNumberOfPoints( nbNodes );
-  
+
   int nbPoints = 0;
 
   TEntityList::const_iterator anIter;
@@ -199,40 +234,59 @@ void SMESH_VisualObjDef::createPoints( vtkPoints* thePoints )
 // function : buildPrs
 // purpose  : create VTK cells( fill unstructured grid )
 //=================================================================================
-void SMESH_VisualObjDef::buildPrs()
+void SMESH_VisualObjDef::buildPrs(bool buildGrid)
 {
-  try 
+  MESSAGE("----------------------------------------------------------SMESH_VisualObjDef::buildPrs " << buildGrid);
+  if (buildGrid)
   {
-    mySMDS2VTKNodes.clear();
-    myVTK2SMDSNodes.clear();
-    mySMDS2VTKElems.clear();
-    myVTK2SMDSElems.clear();
-    
-    if ( IsNodePrs() )
-      buildNodePrs();
-    else
-      buildElemPrs();
+        myLocalGrid = true;
+        try
+        {
+                mySMDS2VTKNodes.clear();
+                myVTK2SMDSNodes.clear();
+                mySMDS2VTKElems.clear();
+                myVTK2SMDSElems.clear();
+
+                if ( IsNodePrs() )
+                        buildNodePrs();
+                else
+                        buildElemPrs();
+        }
+        catch(...)
+        {
+                mySMDS2VTKNodes.clear();
+                myVTK2SMDSNodes.clear();
+                mySMDS2VTKElems.clear();
+                myVTK2SMDSElems.clear();
+
+                myGrid->SetPoints( 0 );
+                myGrid->SetCells( 0, 0, 0, 0, 0 );
+                throw;
+        }
   }
-  catch(...)
+  else
   {
-    mySMDS2VTKNodes.clear();
-    myVTK2SMDSNodes.clear();
-    mySMDS2VTKElems.clear();
-    myVTK2SMDSElems.clear();
-
-    myGrid->SetPoints( 0 );
-    myGrid->SetCells( 0, 0, 0 );
-    throw;
+        myLocalGrid = false;
+        if (!GetMesh()->isCompacted())
+          {
+            MESSAGE("*** buildPrs ==> compactMesh!");
+            GetMesh()->compactMesh();
+          }
+        vtkUnstructuredGrid *theGrid = GetMesh()->getGrid();
+        updateEntitiesFlags();
+        myGrid->ShallowCopy(theGrid);
+        //MESSAGE(myGrid->GetReferenceCount());
+        //MESSAGE( "Update - myGrid->GetNumberOfCells() = "<<myGrid->GetNumberOfCells() );
+        //MESSAGE( "Update - myGrid->GetNumberOfPoints() = "<<myGrid->GetNumberOfPoints() );
+        if( MYDEBUGWITHFILES ) SMESH::WriteUnstructuredGrid( myGrid,"buildPrs.vtu" );
   }
-  
-  if( MYDEBUG ) MESSAGE( "Update - myGrid->GetNumberOfCells() = "<<myGrid->GetNumberOfCells() );
-  if( MYDEBUGWITHFILES ) SMESH::WriteUnstructuredGrid( myGrid,"/tmp/buildPrs" );
 }
 
 //=================================================================================
 // function : buildNodePrs
 // purpose  : create VTK cells for nodes
 //=================================================================================
+
 void SMESH_VisualObjDef::buildNodePrs()
 {
   // PAL16631: without swap, bad_alloc is not thrown but hung up and crash instead,
@@ -244,7 +298,7 @@ void SMESH_VisualObjDef::buildNodePrs()
   myGrid->SetPoints( aPoints );
   aPoints->Delete();
 
-  myGrid->SetCells( 0, 0, 0 );
+  myGrid->SetCells( 0, 0, 0, 0, 0 );
 }
 
 //=================================================================================
@@ -256,7 +310,7 @@ namespace{
   typedef std::vector<const SMDS_MeshElement*> TConnect;
 
   int GetConnect(const SMDS_ElemIteratorPtr& theNodesIter, 
-                TConnect& theConnect)
+                 TConnect& theConnect)
   {
     theConnect.clear();
     for(; theNodesIter->more();)
@@ -266,10 +320,10 @@ namespace{
   
   inline 
   void SetId(vtkIdList *theIdList, 
-            const SMESH_VisualObjDef::TMapOfIds& theSMDS2VTKNodes, 
-            const TConnect& theConnect, 
-            int thePosition,
-            int theId)
+             const SMESH_VisualObjDef::TMapOfIds& theSMDS2VTKNodes, 
+             const TConnect& theConnect, 
+             int thePosition,
+             int theId)
   {
     theIdList->SetId(thePosition,theSMDS2VTKNodes.find(theConnect[theId]->GetID())->second);
   }
@@ -280,59 +334,79 @@ namespace{
 void SMESH_VisualObjDef::buildElemPrs()
 {
   // Create points
-  
+
   vtkPoints* aPoints = vtkPoints::New();
   createPoints( aPoints );
   myGrid->SetPoints( aPoints );
   aPoints->Delete();
-    
+
   if ( MYDEBUG )
     MESSAGE("Update - myGrid->GetNumberOfPoints() = "<<myGrid->GetNumberOfPoints());
 
   // Calculate cells size
 
-  static SMDSAbs_ElementType aTypes[ 3 ] = { SMDSAbs_Edge, SMDSAbs_Face, SMDSAbs_Volume };
+  static SMDSAbs_ElementType aTypes[ 5 ] =
+    { SMDSAbs_Ball, SMDSAbs_0DElement, SMDSAbs_Edge, SMDSAbs_Face, SMDSAbs_Volume };
 
   // get entity data
   map<SMDSAbs_ElementType,int> nbEnts;
   map<SMDSAbs_ElementType,TEntityList> anEnts;
 
-  for ( int i = 0; i <= 2; i++ )
+  for ( int i = 0; i <= 3; i++ )
     nbEnts[ aTypes[ i ] ] = GetEntities( aTypes[ i ], anEnts[ aTypes[ i ] ] );
 
   // PAL16631: without swap, bad_alloc is not thrown but hung up and crash instead,
   // so check remaining memory size for safety
   SMDS_Mesh::CheckMemory(); // PAL16631
 
-  vtkIdType aCellsSize =  3 * nbEnts[ SMDSAbs_Edge ];
+  vtkIdType aCellsSize =  2 * nbEnts[ SMDSAbs_0DElement ] + 3 * nbEnts[ SMDSAbs_Edge ];
+  aCellsSize += 2 * nbEnts[ SMDSAbs_Ball ];
 
-  for ( int i = 1; i <= 2; i++ ) // iterate through faces and volumes
+  for ( int i = 2; i <= 3; 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;
+      for ( anIter = aList.begin(); anIter != aList.end(); ++anIter ) {
+        if((*anIter)->GetEntityType() != SMDSEntity_Polyhedra &&
+           (*anIter)->GetEntityType() != SMDSEntity_Quad_Polyhedra) {
+          aCellsSize += (*anIter)->NbNodes() + 1;
+        } 
+        // Special case for the VTK_POLYHEDRON:
+        // itsinput cellArray is of special format.
+        //  [nCellFaces, nFace0Pts, i, j, k, nFace1Pts, i, j, k, ...]   
+        else {
+          if( const SMDS_VtkVolume* ph = dynamic_cast<const SMDS_VtkVolume*>(*anIter) ) {
+            int nbFaces = ph->NbFaces();
+            aCellsSize += (1 + ph->NbFaces());
+            for( int i = 1; i <= nbFaces; i++ ) {
+              aCellsSize += ph->NbFaceNodes(i);
+            }
+          }
+        }
+      }
     }
   }
-
-  vtkIdType aNbCells = nbEnts[ SMDSAbs_Edge ] + nbEnts[ SMDSAbs_Face ] + nbEnts[ SMDSAbs_Volume ];
   
+  vtkIdType aNbCells =
+    nbEnts[ SMDSAbs_0DElement ] + nbEnts[ SMDSAbs_Ball ] + nbEnts[ SMDSAbs_Edge ] +
+    nbEnts[ SMDSAbs_Face ] + nbEnts[ SMDSAbs_Volume ];
+
   if ( MYDEBUG )
     MESSAGE( "Update - aNbCells = "<<aNbCells<<"; aCellsSize = "<<aCellsSize );
 
   // Create cells
-  
+
   vtkCellArray* aConnectivity = vtkCellArray::New();
   aConnectivity->Allocate( aCellsSize, 0 );
-  
+
   SMDS_Mesh::CheckMemory(); // PAL16631
 
   vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
   aCellTypesArray->SetNumberOfComponents( 1 );
   aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
-  
+
   SMDS_Mesh::CheckMemory(); // PAL16631
 
   vtkIdList *anIdList = vtkIdList::New();
@@ -343,10 +417,10 @@ void SMESH_VisualObjDef::buildElemPrs()
 
   SMDS_Mesh::CheckMemory(); // PAL16631
 
-  for ( int i = 0; i <= 2; i++ ) // iterate through edges, faces and volumes
+  for ( int i = 0; i <= 3; i++ ) // iterate through 0d elements, edges, faces and volumes
   {
-    if( nbEnts[ aTypes[ i ] ] > 0 )
-    {
+    if ( nbEnts[ aTypes[ i ] ] > 0 ) {
+      
       const SMDSAbs_ElementType& aType = aTypes[ i ];
       const TEntityList& aList = anEnts[ aType ];
       TEntityList::const_iterator anIter;
@@ -356,90 +430,52 @@ void SMESH_VisualObjDef::buildElemPrs()
         
         vtkIdType aNbNodes = anElem->NbNodes();
         anIdList->SetNumberOfIds( aNbNodes );
-
+        const vtkIdType vtkElemType = getCellType( aType, anElem->IsPoly(), aNbNodes );
+        
         int anId = anElem->GetID();
-
+        
         mySMDS2VTKElems.insert( TMapOfIds::value_type( anId, iElem ) );
         myVTK2SMDSElems.insert( TMapOfIds::value_type( iElem, anId ) );
-
+        
         SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
-       switch(aType){
-       case SMDSAbs_Volume:{
-          aConnect.clear();
-         std::vector<int> aConnectivities;
-         // Convertions connectivities from SMDS to VTK
-         if (anElem->IsPoly() && aNbNodes > 3) { // POLYEDRE
-
-            if ( const SMDS_PolyhedralVolumeOfNodes* ph =
-                 dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem))
-            {
-              aNbNodes = GetConnect(ph->uniqueNodesIterator(),aConnect);
-              anIdList->SetNumberOfIds( aNbNodes );
+        {
+          // Convertions connectivities from SMDS to VTK
+
+          if (aType == SMDSAbs_Volume && anElem->IsPoly() && aNbNodes > 3) { // POLYEDRE
+            anIdList->Reset();
+            if ( const SMDS_VtkVolume* ph = dynamic_cast<const SMDS_VtkVolume*>(anElem) ) {
+              int nbFaces = ph->NbFaces();
+              anIdList->InsertNextId(nbFaces);
+              for( int i = 1; i <= nbFaces; i++ ) {
+                anIdList->InsertNextId(ph->NbFaceNodes(i));
+                for(int j = 1; j <= ph->NbFaceNodes(i); j++) {
+                  const SMDS_MeshNode* n = ph->GetFaceNode(i,j);
+                  if(n) {
+                    anIdList->InsertNextId(mySMDS2VTKNodes[n->GetID()]);
+                  }
+                }
+              }
             }
-           for (int k = 0; k < aNbNodes; k++)
-             aConnectivities.push_back(k);
-
-          } else if (aNbNodes == 4) {
-           static int anIds[] = {0,2,1,3};
-           for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
-
-         } else if (aNbNodes == 5) {
-           static int anIds[] = {0,3,2,1,4};
-           for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
-
-         } else if (aNbNodes == 6) {
-           static int anIds[] = {0,1,2,3,4,5};
-           for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
-
-         }
-          else if (aNbNodes == 8) {
-           static int anIds[] = {0,3,2,1,4,7,6,5};
-           for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
-
-         }
-          else if (aNbNodes == 10) {
-           static int anIds[] = {0,2,1,3,6,5,4,7,9,8};
-           for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
-         }
-          else if (aNbNodes == 13) {
-           static int anIds[] = {0,3,2,1,4,8,7,6,5,9,12,11,10};
-           for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
-         }
-          else if (aNbNodes == 15) {
-            //static int anIds[] = {0,2,1,3,5,4,8,7,6,11,10,9,12,14,13};
-            static int anIds[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14};
-           for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
-           //for (int k = 0; k < aNbNodes; k++) {
-            //  int nn = aConnectivities[k];
-            //  const SMDS_MeshNode* N = static_cast<const SMDS_MeshNode*> (aConnect[nn]);
-            //  cout<<"k="<<k<<"  N("<<N->X()<<","<<N->Y()<<","<<N->Z()<<")"<<endl;
-            //}
-         }
-          else if (aNbNodes == 20) {
-           static int anIds[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17};
-           for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
-         }
+          }
           else {
+            const std::vector<int>& aConnectivities =
+              SMDS_MeshCell::toVtkOrder( VTKCellType( vtkElemType ));
+            if (aConnectivities.size() > 0) {
+              aConnect.clear();
+              GetConnect(aNodesIter,aConnect);
+              for (vtkIdType aNodeId = 0; aNodeId < aNbNodes; aNodeId++)
+                SetId(anIdList,mySMDS2VTKNodes,aConnect,aNodeId,aConnectivities[aNodeId]);
+            }
+            else {
+              for( vtkIdType aNodeId = 0; aNodesIter->more(); aNodeId++ ){
+                const SMDS_MeshElement* aNode = aNodesIter->next();
+                anIdList->SetId( aNodeId, mySMDS2VTKNodes[aNode->GetID()] );
+              }
+            }
           }
-
-          if ( aConnect.empty() )
-            GetConnect(aNodesIter,aConnect);
-
-         if (aConnectivities.size() > 0) {
-           for (vtkIdType aNodeId = 0; aNodeId < aNbNodes; aNodeId++)
-             SetId(anIdList,mySMDS2VTKNodes,aConnect,aNodeId,aConnectivities[aNodeId]);
-         }
-         break;
-       }
-       default:
-         for( vtkIdType aNodeId = 0; aNodesIter->more(); aNodeId++ ){
-           const SMDS_MeshElement* aNode = aNodesIter->next();
-           anIdList->SetId( aNodeId, mySMDS2VTKNodes[aNode->GetID()] );
-         }
-       }
-
+        }
         aConnectivity->InsertNextCell( anIdList );
-        aCellTypesArray->InsertNextValue( getCellType( aType, anElem->IsPoly(), aNbNodes ) );
+        aCellTypesArray->InsertNextValue( vtkElemType );
 
         iElem++;
       }
@@ -448,11 +484,11 @@ void SMESH_VisualObjDef::buildElemPrs()
   }
 
   // Insert cells in grid
-  
+
   VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
   aCellLocationsArray->SetNumberOfComponents( 1 );
   aCellLocationsArray->SetNumberOfTuples( aNbCells );
-  
+
   SMDS_Mesh::CheckMemory(); // PAL16631
 
   aConnectivity->InitTraversal();
@@ -460,7 +496,7 @@ void SMESH_VisualObjDef::buildElemPrs()
     aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
 
   myGrid->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
-  
+
   aCellLocationsArray->Delete();
   aCellTypesArray->Delete();
   aConnectivity->Delete();
@@ -474,9 +510,9 @@ void SMESH_VisualObjDef::buildElemPrs()
 // purpose  : Retrieve ids of nodes from edge of elements ( edge is numbered from 1 )
 //=================================================================================
 bool SMESH_VisualObjDef::GetEdgeNodes( const int theElemId,
-                                      const int theEdgeNum,
-                                      int&      theNodeId1,
-                                      int&      theNodeId2 ) const
+                                       const int theEdgeNum,
+                                       int&      theNodeId1,
+                                       int&      theNodeId2 ) const
 {
   const SMDS_Mesh* aMesh = GetMesh();
   if ( aMesh == 0 )
@@ -488,7 +524,7 @@ bool SMESH_VisualObjDef::GetEdgeNodes( const int theElemId,
     
   int nbNodes = anElem->NbNodes();
 
-  if ( theEdgeNum < 0 || theEdgeNum > 3 || nbNodes != 3 && nbNodes != 4 || theEdgeNum > nbNodes )
+  if ( theEdgeNum < 0 || theEdgeNum > 3 || (nbNodes != 3 && nbNodes != 4) || theEdgeNum > nbNodes )
     return false;
 
   vector<int> anIds( nbNodes );
@@ -511,6 +547,93 @@ bool SMESH_VisualObjDef::GetEdgeNodes( const int theElemId,
   return true;
 }
 
+vtkUnstructuredGrid* SMESH_VisualObjDef::GetUnstructuredGrid()
+{
+  if ( !myLocalGrid && !GetMesh()->isCompacted() )
+  {
+    GetMesh()->compactMesh();
+        updateEntitiesFlags();
+    vtkUnstructuredGrid *theGrid = GetMesh()->getGrid();
+    myGrid->ShallowCopy(theGrid);
+  }
+  return myGrid;
+}
+
+
+//=================================================================================
+// function : IsValid
+// purpose  : Return true if there are some entities
+//=================================================================================
+bool SMESH_VisualObjDef::IsValid() const
+{
+        //MESSAGE("SMESH_VisualObjDef::IsValid");
+  return GetNbEntities(SMDSAbs_Node) > 0      || 
+         GetNbEntities(SMDSAbs_0DElement) > 0 || 
+         GetNbEntities(SMDSAbs_Ball) > 0 || 
+         GetNbEntities(SMDSAbs_Edge) > 0      || 
+         GetNbEntities(SMDSAbs_Face) > 0      ||
+         GetNbEntities(SMDSAbs_Volume) > 0 ;
+}
+
+//=================================================================================
+// function : updateEntitiesFlags
+// purpose  : Update entities flags
+//=================================================================================
+void SMESH_VisualObjDef::updateEntitiesFlags() {
+
+        unsigned int tmp = myEntitiesState;
+        ClearEntitiesFlags();
+
+        map<SMDSAbs_ElementType,int> entities = SMESH::GetEntitiesFromObject(this);
+        
+
+        if( myEntitiesCache[SMDSAbs_0DElement] != 0 ||  myEntitiesCache[SMDSAbs_0DElement] >= entities[SMDSAbs_0DElement] )
+                myEntitiesState &= ~SMESH_Actor::e0DElements;
+
+        if( myEntitiesCache[SMDSAbs_Ball] != 0 ||  myEntitiesCache[SMDSAbs_Ball] >= entities[SMDSAbs_Ball] )
+                myEntitiesState &= ~SMESH_Actor::eBallElem;
+
+        if( myEntitiesCache[SMDSAbs_Edge] != 0 || myEntitiesCache[SMDSAbs_Edge] >= entities[SMDSAbs_Edge] )
+                myEntitiesState &= ~SMESH_Actor::eEdges; 
+
+        if( myEntitiesCache[SMDSAbs_Face] != 0 || myEntitiesCache[SMDSAbs_Face] >= entities[SMDSAbs_Face] )
+                myEntitiesState &= ~SMESH_Actor::eFaces; 
+
+        if( myEntitiesCache[SMDSAbs_Volume] != 0 || myEntitiesCache[SMDSAbs_Volume] >= entities[SMDSAbs_Volume] )
+                myEntitiesState &= ~SMESH_Actor::eVolumes;
+
+        if( tmp != myEntitiesState ) {
+                myEntitiesFlag = true;
+        }
+        
+        myEntitiesCache = entities;
+}
+
+//=================================================================================
+// function : ClearEntitiesFlags
+// purpose  : Clear the entities flags
+//=================================================================================
+void SMESH_VisualObjDef::ClearEntitiesFlags() {
+        myEntitiesState = SMESH_Actor::eAllEntity;
+        myEntitiesFlag = false;
+}
+
+//=================================================================================
+// function : GetEntitiesFlag
+// purpose  : Return the entities flag
+//=================================================================================
+bool SMESH_VisualObjDef::GetEntitiesFlag() {
+        return myEntitiesFlag;
+}
+
+//=================================================================================
+// function : GetEntitiesState
+// purpose  : Return the entities state
+//=================================================================================
+unsigned int SMESH_VisualObjDef::GetEntitiesState() {
+        return myEntitiesState;
+}
+
 /*
   Class       : SMESH_MeshObj
   Description : Class for visualisation of mesh
@@ -523,6 +646,7 @@ bool SMESH_VisualObjDef::GetEdgeNodes( const int theElemId,
 SMESH_MeshObj::SMESH_MeshObj(SMESH::SMESH_Mesh_ptr theMesh):
   myClient(SalomeApp_Application::orb(),theMesh)
 {
+        myEmptyGrid = 0;
   if ( MYDEBUG ) 
     MESSAGE("SMESH_MeshObj - this = "<<this<<"; theMesh->_is_nil() = "<<theMesh->_is_nil());
 }
@@ -544,13 +668,32 @@ SMESH_MeshObj::~SMESH_MeshObj()
 bool SMESH_MeshObj::Update( int theIsClear )
 {
   // Update SMDS_Mesh on client part
+  MESSAGE("SMESH_MeshObj::Update " << this);
   if ( myClient.Update(theIsClear) || GetUnstructuredGrid()->GetNumberOfPoints()==0) {
+    MESSAGE("buildPrs");
     buildPrs();  // Fill unstructured grid
     return true;
   }
   return false;
 }
 
+bool SMESH_MeshObj::NulData()
+{
+        MESSAGE ("SMESH_MeshObj::NulData() ==================================================================================");
+        if (!myEmptyGrid)
+        {
+          myEmptyGrid = SMDS_UnstructuredGrid::New();
+          myEmptyGrid->Initialize();
+          myEmptyGrid->Allocate();
+          vtkPoints* points = vtkPoints::New();
+          points->SetNumberOfPoints(0);
+          myEmptyGrid->SetPoints( points );
+          points->Delete();
+          myEmptyGrid->BuildLinks();
+        }
+        myGrid->ShallowCopy(myEmptyGrid);
+        return true;
+}
 //=================================================================================
 // function : GetElemDimension
 // purpose  : Get dimension of element
@@ -564,6 +707,8 @@ int SMESH_MeshObj::GetElemDimension( const int theObjId )
   int aType = anElem->GetType();
   switch ( aType )
   {
+    case SMDSAbs_0DElement : return 0;
+    case SMDSAbs_Ball : return 0;
     case SMDSAbs_Edge  : return 1;
     case SMDSAbs_Face  : return 2;
     case SMDSAbs_Volume: return 3;
@@ -584,6 +729,15 @@ int SMESH_MeshObj::GetNbEntities( const SMDSAbs_ElementType theType) const
       return myClient->NbNodes();
     }
     break;
+    case SMDSAbs_0DElement:
+    {
+      return myClient->Nb0DElements();
+    }
+    case SMDSAbs_Ball:
+    {
+      return myClient->NbBalls();
+    }
+    break;
     case SMDSAbs_Edge:
     {
       return myClient->NbEdges();
@@ -617,6 +771,18 @@ int SMESH_MeshObj::GetEntities( const SMDSAbs_ElementType theType, TEntityList&
       while ( anIter->more() ) theObjs.push_back( anIter->next() );
     }
     break;
+    case SMDSAbs_0DElement:
+    {
+      SMDS_ElemIteratorPtr anIter = myClient->elementsIterator(SMDSAbs_0DElement);
+      while ( anIter->more() ) theObjs.push_back( anIter->next() );
+    }
+    break;
+    case SMDSAbs_Ball:
+    {
+      SMDS_ElemIteratorPtr anIter = myClient->elementGeomIterator(SMDSGeom_BALL);
+      while ( anIter->more() ) theObjs.push_back( anIter->next() );
+    }
+    break;
     case SMDSAbs_Edge:
     {
       SMDS_EdgeIteratorPtr anIter = myClient->edgesIterator();
@@ -657,7 +823,7 @@ void SMESH_MeshObj::UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor
 //=================================================================================
 bool SMESH_MeshObj::IsNodePrs() const
 {
-  return myClient->NbEdges() == 0 &&myClient->NbFaces() == 0 && myClient->NbVolumes() == 0 ;
+  return myClient->Nb0DElements() + myClient->NbEdges() + myClient->NbFaces() + myClient->NbVolumes() + myClient->NbBalls() == 0 ;
 }
 
 
@@ -694,6 +860,7 @@ int SMESH_SubMeshObj::GetElemDimension( const int theObjId )
 // function : UpdateFunctor
 // purpose  : Update functor in accordance with current mesh
 //=================================================================================
+
 void SMESH_SubMeshObj::UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor )
 {
   theFunctor->SetMesh( myMeshObj->GetMesh() );
@@ -705,8 +872,9 @@ void SMESH_SubMeshObj::UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunc
 //=================================================================================
 bool SMESH_SubMeshObj::Update( int theIsClear )
 {
+  MESSAGE("SMESH_SubMeshObj::Update " << this)
   bool changed = myMeshObj->Update( theIsClear );
-  buildPrs();
+  buildPrs(true);
   return changed;
 }
 
@@ -732,7 +900,7 @@ SMESH_GroupObj::SMESH_GroupObj( SMESH::SMESH_GroupBase_ptr theGroup,
 SMESH_GroupObj::~SMESH_GroupObj()
 {
   if ( MYDEBUG ) MESSAGE("~SMESH_GroupObj");
-  myGroupServer->Destroy();
+  myGroupServer->UnRegister();
 }
 
 //=================================================================================
@@ -744,6 +912,15 @@ bool SMESH_GroupObj::IsNodePrs() const
   return myGroupServer->GetType() == SMESH::NODE;
 }
 
+//=================================================================================
+// function : GetElementType
+// purpose  : Return type of elements of group
+//=================================================================================
+SMDSAbs_ElementType SMESH_GroupObj::GetElementType() const
+{
+  return SMDSAbs_ElementType(myGroupServer->GetType());
+}
+
 //=================================================================================
 // function : getNodesFromElems
 // purpose  : Retrieve nodes from elements
@@ -804,9 +981,12 @@ static int getPointers( const SMDSAbs_ElementType            theRequestType,
 //=================================================================================
 int SMESH_GroupObj::GetNbEntities( const SMDSAbs_ElementType theType) const
 {
-  if(SMDSAbs_ElementType(myGroupServer->GetType()) == theType){
+  if(SMDSAbs_ElementType(myGroupServer->GetType()) == theType) {
     return myGroupServer->Size();
   }
+  if ( theType == SMDSAbs_Node ) {
+    return myGroupServer->GetNumberOfNodes();
+  }
   return 0;
 }
 
@@ -853,7 +1033,7 @@ SMESH_subMeshObj::SMESH_subMeshObj( SMESH::SMESH_subMesh_ptr theSubMesh,
 SMESH_subMeshObj::~SMESH_subMeshObj()
 {
   if ( MYDEBUG ) MESSAGE( "~SMESH_subMeshObj" );
-  mySubMeshServer->Destroy();
+  mySubMeshServer->UnRegister();
 }
 
 //=================================================================================
@@ -866,15 +1046,17 @@ int SMESH_subMeshObj::GetNbEntities( const SMDSAbs_ElementType theType) const
   {
     case SMDSAbs_Node:
     {
-      return mySubMeshServer->GetNumberOfNodes( false );
+      return mySubMeshServer->GetNumberOfNodes( /*all=*/true );
     }
     break;
+    case SMDSAbs_Ball:
+    case SMDSAbs_0DElement:
     case SMDSAbs_Edge:
     case SMDSAbs_Face:
     case SMDSAbs_Volume:
     {
       SMESH::long_array_var anIds = 
-       mySubMeshServer->GetElementsByType( SMESH::ElementType(theType) );
+        mySubMeshServer->GetElementsByType( SMESH::ElementType(theType) );
       return anIds->length();
     }
     default:
@@ -911,7 +1093,7 @@ int SMESH_subMeshObj::GetEntities( const SMDSAbs_ElementType theType, TEntityLis
     else
     {
       SMESH::long_array_var anIds = 
-       mySubMeshServer->GetElementsByType( SMESH::ElementType(theType) );
+        mySubMeshServer->GetElementsByType( SMESH::ElementType(theType) );
       return getPointers( theType, anIds, aMesh, theResList );
     }
   }
index 638155200f484c973e74f76b0089f0d6c3389760..5ce10b850076b6a3e73507336d4e6e188b0cdd0f 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH OBJECT : interactive object for SMESH visualization
 //  File   : SMESH_Object.h
 //  Author : Nicolas REJNERI
@@ -29,7 +30,7 @@
 #define SMESH_OBJECT_H
 
 #ifdef WNT
- #if defined SMESHOBJECT_EXPORTS
+ #if defined SMESHOBJECT_EXPORTS || defined SMESHObject_EXPORTS
   #define SMESHOBJECT_EXPORT __declspec( dllexport )
  #else
   #define SMESHOBJECT_EXPORT __declspec( dllimport )
@@ -55,6 +56,7 @@ class SMESHOBJECT_EXPORT SMESH_VisualObj
 {
 public:
   virtual bool Update( int theIsClear = true ) = 0;
+  virtual bool NulData() = 0;
   virtual void UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor ) = 0;
   virtual int GetElemDimension( const int theObjId ) = 0;
 
@@ -62,9 +64,10 @@ public:
   virtual SMDS_Mesh* GetMesh() const = 0;
 
   virtual bool GetEdgeNodes( const int theElemId,
-                            const int theEdgeNum,
-                            int&      theNodeId1,
-                            int&      theNodeId2 ) const = 0;
+                             const int theEdgeNum,
+                             int&      theNodeId1,
+                             int&      theNodeId2 ) const = 0;
+  virtual bool              IsValid() const = 0;
   
   virtual vtkUnstructuredGrid* GetUnstructuredGrid() = 0;
   
@@ -72,6 +75,9 @@ public:
   virtual vtkIdType GetNodeVTKId( int theObjID ) = 0;
   virtual vtkIdType GetElemObjId( int theVTKID ) = 0;
   virtual vtkIdType GetElemVTKId( int theObjID ) = 0;
+  virtual void              ClearEntitiesFlags() = 0;
+  virtual bool              GetEntitiesFlag() = 0;
+  virtual unsigned int      GetEntitiesState() = 0;
 };
 
 typedef boost::shared_ptr<SMESH_VisualObj> TVisualObjPtr;
index e472a2121c2882208f7c0194d80ffbaf9a486f33..4532a019744afe2d85f07320114755601a7bd19b 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH OBJECT : interactive object for SMESH visualization
 //  File   : SMESH_Object.h
 //  Author : Nicolas REJNERI
@@ -31,6 +32,7 @@
 #include "SMESH_Controls.hxx"
 #include "SMESH_Object.h"
 #include "SMESH_Client.hxx"
+#include "SMESH_Actor.h"
 
 // IDL Headers
 #include <SALOMEconfig.h>
@@ -43,7 +45,6 @@
 class vtkPoints;
 class SALOME_ExtractUnstructuredGrid;
 
-class SMESH_Actor;
 class SMDS_MeshNode;
 class SMDS_MeshElement;
 
@@ -61,6 +62,7 @@ public:
   virtual                   ~SMESH_VisualObjDef();
   
   virtual bool              Update( int theIsClear = true ) = 0;
+  virtual bool              NulData() {return 0; };
   virtual void              UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor ) = 0;
   virtual int               GetElemDimension( const int theObjId ) = 0;
 
@@ -69,33 +71,44 @@ public:
   virtual bool              IsNodePrs() const = 0;
   virtual SMDS_Mesh*        GetMesh() const = 0;
 
+  virtual bool              IsValid() const;
+
   virtual bool              GetEdgeNodes( const int theElemId,
                                           const int theEdgeNum,
                                           int&      theNodeId1,
                                           int&      theNodeId2 ) const;
 
-  virtual vtkUnstructuredGrid* GetUnstructuredGrid() { return myGrid; }
+  virtual vtkUnstructuredGrid* GetUnstructuredGrid();
   
   virtual vtkIdType         GetNodeObjId( int theVTKID );
   virtual vtkIdType         GetNodeVTKId( int theObjID );
   virtual vtkIdType         GetElemObjId( int theVTKID );
   virtual vtkIdType         GetElemVTKId( int theObjID );
   
+  virtual void              ClearEntitiesFlags();
+  virtual bool              GetEntitiesFlag();
+  virtual unsigned int      GetEntitiesState();
+  
 protected:
 
   void                      createPoints( vtkPoints* );
-  void                      buildPrs();
+  void                      buildPrs(bool buildGrid = false);
   void                      buildNodePrs();
   void                      buildElemPrs();
-  
-private:                                   
+  void                      updateEntitiesFlags();
+//private:
 
   TMapOfIds                 mySMDS2VTKNodes;
   TMapOfIds                 myVTK2SMDSNodes;
   TMapOfIds                 mySMDS2VTKElems;
   TMapOfIds                 myVTK2SMDSElems;
+  bool                      myLocalGrid;
+
+  bool                      myEntitiesFlag;
+  unsigned int              myEntitiesState;
 
   vtkUnstructuredGrid*      myGrid;
+  std::map<SMDSAbs_ElementType,int> myEntitiesCache;
 };
 
 
@@ -112,6 +125,7 @@ public:
   virtual                   ~SMESH_MeshObj();
   
   virtual bool              Update( int theIsClear = true );
+  virtual bool              NulData();
   
   virtual int               GetNbEntities( const SMDSAbs_ElementType) const;
   virtual int               GetEntities( const SMDSAbs_ElementType, TEntityList& ) const;
@@ -126,6 +140,7 @@ public:
 
 protected:
   SMESH_Client              myClient;
+  vtkUnstructuredGrid*      myEmptyGrid;
 };
 
 
@@ -168,6 +183,8 @@ public:
   virtual int               GetEntities( const SMDSAbs_ElementType, TEntityList& ) const;
   virtual bool              IsNodePrs() const;
 
+  virtual SMDSAbs_ElementType GetElementType() const;
+
 private:
 
   SMESH::SMESH_GroupBase_var    myGroupServer;
diff --git a/src/OBJECT/SMESH_PreviewActorsCollection.cxx b/src/OBJECT/SMESH_PreviewActorsCollection.cxx
new file mode 100644 (file)
index 0000000..b5e145c
--- /dev/null
@@ -0,0 +1,247 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+#include "SMESH_PreviewActorsCollection.h"
+
+#include <utilities.h>
+
+// OCC includes
+#include <TopoDS.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+
+// VTK includes
+#include <vtkUnstructuredGrid.h>
+#include <vtkPlane.h>
+#include <vtkRenderer.h>
+#include <vtkProperty.h>
+
+#include <QSet>
+
+// GEOM includes
+#include <GEOM_Actor.h>
+
+// GUI includes
+#include <VTKViewer_Actor.h>
+#include <SVTK_DeviceActor.h>
+#include <SALOME_InteractiveObject.hxx>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_Session.h>
+
+#ifdef _DEBUG_
+static int MYDEBUG = 0;
+#else
+static int MYDEBUG = 0;
+#endif
+
+
+SMESH_PreviewActorsCollection::SMESH_PreviewActorsCollection() :
+  mySelector( 0 ), myRenderer( 0 ), myCurrentChunk( 0 ), myChunkSize( 0 ), myIsShown( true )
+{
+  if(MYDEBUG) MESSAGE("SMESH_PreviewActorsCollection - "<<this);
+}
+
+
+SMESH_PreviewActorsCollection::~SMESH_PreviewActorsCollection()
+{
+  if(MYDEBUG) MESSAGE("~SMESH_PreviewActorsCollection - "<<this);
+  clearActors();
+}
+
+bool SMESH_PreviewActorsCollection::Init( const TopoDS_Shape& theShape,
+                                         TopAbs_ShapeEnum theType,
+                                         const QString& theEntry )
+{
+  SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr();
+
+  myType =  theType;
+  myEntry = theEntry;
+  myMainShape = theShape;
+  myMapOfActors.clear();
+  myMapOfShapes.Clear();
+  myIndices.clear();
+  myCurrentChunk = 0;
+  myChunkSize = mgr->integerValue( "SMESH", "preview_actor_chunk_size", 100 );
+
+  if ( theShape.IsNull() )
+    return false;
+
+  Handle( SALOME_InteractiveObject ) anIO = new SALOME_InteractiveObject();
+  anIO->setEntry( theEntry.toLatin1().constData() );
+  
+  // get indexes of seleted elements
+  TopExp::MapShapes( theShape, myMapOfShapes );
+  TopExp_Explorer exp( theShape, theType );
+  QSet<int> indices;
+  for ( ; exp.More(); exp.Next() )
+    indices << myMapOfShapes.FindIndex( exp.Current() );
+  myIndices = indices.toList();
+  qSort(myIndices);
+
+  // show current chunk
+  showCurrentChunk();
+
+  return count() > 0;
+}
+
+GEOM_Actor* SMESH_PreviewActorsCollection::createActor(const TopoDS_Shape& shape)
+{
+  GEOM_Actor* actor = GEOM_Actor::New();
+  actor->SetShape( shape, 0, 0 );
+  return actor;
+}
+
+GEOM_Actor* SMESH_PreviewActorsCollection::GetActorByIndex(int index)
+{
+  return myMapOfActors.value( index );
+}
+
+int SMESH_PreviewActorsCollection::GetIndexByShape( const TopoDS_Shape& theShape )
+{
+  return myMapOfShapes.FindIndex( theShape );
+}
+
+void SMESH_PreviewActorsCollection::AddToRender(vtkRenderer* theRenderer)
+{
+  myRenderer = theRenderer;
+
+  QMap<int, GEOM_Actor*>::iterator iter = myMapOfActors.begin();
+  for ( ; iter != myMapOfActors.end(); ++iter ) {
+    iter.value()->SetVisibility( myIsShown );
+    iter.value()->AddToRender( theRenderer );
+  }
+}
+
+void SMESH_PreviewActorsCollection::RemoveFromRender(vtkRenderer* theRenderer)
+{
+  QMap<int, GEOM_Actor*>::iterator iter = myMapOfActors.begin();
+  for ( ; iter != myMapOfActors.end(); ++iter )
+    iter.value()->RemoveFromRender( theRenderer );
+}
+
+void SMESH_PreviewActorsCollection::SetSelector(SVTK_Selector* theSelector)
+{
+  mySelector = theSelector;
+}
+
+void SMESH_PreviewActorsCollection::HighlightAll( bool theHighlight )
+{
+  QMap<int, GEOM_Actor*>::iterator iter = myMapOfActors.begin();
+  for ( ; iter != myMapOfActors.end(); ++iter )
+    iter.value()->Highlight( theHighlight );
+}
+
+void SMESH_PreviewActorsCollection::HighlightID( int index )
+{
+  GEOM_Actor* anActor = GetActorByIndex( index );
+  if ( anActor && !anActor->isHighlighted() )
+    anActor->Highlight( true );
+}
+
+void SMESH_PreviewActorsCollection::SetShown( bool shown )
+{
+  myIsShown = shown;
+  QMap<int, GEOM_Actor*>::iterator iter = myMapOfActors.begin();
+  for ( ; iter != myMapOfActors.end(); ++iter )
+    iter.value()->SetVisibility( shown );
+}
+
+int SMESH_PreviewActorsCollection::count() const
+{
+  return myIndices.count();
+}
+
+int SMESH_PreviewActorsCollection::chunkSize() const
+{
+  return myChunkSize;
+}
+
+int SMESH_PreviewActorsCollection::currentChunk() const
+{
+  return myCurrentChunk;
+}
+
+bool SMESH_PreviewActorsCollection::hasPrevious() const
+{
+  return chunkSize() > 0 && currentChunk() > 0;
+}
+
+bool SMESH_PreviewActorsCollection::hasNext() const
+{
+  return chunkSize() > 0 && (currentChunk()+1)*chunkSize() < count();
+}
+
+void SMESH_PreviewActorsCollection::previous()
+{
+  if ( !hasPrevious() ) return;
+  myCurrentChunk--;
+  showCurrentChunk();
+}
+
+void SMESH_PreviewActorsCollection::next()
+{
+  if ( !hasNext() ) return;
+  myCurrentChunk++;
+  showCurrentChunk();
+}
+
+void SMESH_PreviewActorsCollection::showCurrentChunk()
+{
+  clearActors();
+  int imin = currentChunk() * chunkSize();
+  int imax = std::min( (currentChunk()+1) * chunkSize(), count() );
+  for ( int i = imin; i < imax; i++ ) {
+    int index = myIndices[i];
+    if ( !index || myMapOfActors.contains( index ) ) continue;
+    TopoDS_Shape s = myMapOfShapes.FindKey( index );
+    if ( s.IsNull() ) continue;
+    // create actor if the index is present
+    if ( GEOM_Actor* anActor = createActor( s.Oriented(TopAbs_FORWARD))) {
+      // Create new entry for actor
+      QString entry = QString( "%1_%2" ).arg( myEntry ).arg( index );
+      // Create interactive object
+      Handle( SALOME_InteractiveObject ) anIO = new SALOME_InteractiveObject();
+      anIO->setEntry( entry.toLatin1().constData() );
+      // Init Actor
+      anActor->SetVectorMode( myType==TopAbs_EDGE );
+      anActor->setIO( anIO );
+      anActor->SetSelector( mySelector );
+      anActor->SetPickable( true );
+      anActor->SetResolveCoincidentTopology( true );
+
+      // Add Actor to the Actors Map
+      myMapOfActors.insert(index, anActor);
+    }
+  }
+  mySelector->ClearIObjects();
+  if ( myRenderer )
+    AddToRender( myRenderer );
+}
+
+void SMESH_PreviewActorsCollection::clearActors()
+{
+  if (myRenderer)
+    RemoveFromRender(myRenderer);
+
+  QMap<int, GEOM_Actor*>::iterator iter = myMapOfActors.begin();
+  for ( ; iter != myMapOfActors.end(); ++iter )
+    if ( GEOM_Actor* anActor = iter.value() )
+      anActor->Delete();
+  myMapOfActors.clear();
+}
diff --git a/src/OBJECT/SMESH_PreviewActorsCollection.h b/src/OBJECT/SMESH_PreviewActorsCollection.h
new file mode 100644 (file)
index 0000000..7c13ae3
--- /dev/null
@@ -0,0 +1,92 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+//  SMESH OBJECT : interactive object for SMESH visualization
+//  File   : SMESH_PreviewActorsCollection.h
+//  Author : OCN
+//  Module : SMESH
+//  $Header: /home/server/cvs/SMESH/SMESH_SRC/src/OBJECT/SMESH_PreviewActorsCollection.h,v 1
+//
+#ifndef SMESH_PREVIEW_ACTOR_COLLECTION_H
+#define SMESH_PREVIEW_ACTOR_COLLECTION_H
+
+#include "SMESH_Object.h"
+
+#include <TopoDS_Shape.hxx>
+#include <TopAbs_ShapeEnum.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <QList>
+#include <QMap>
+#include <QString>
+
+class vtkRenderer;
+class GEOM_Actor;
+class SVTK_Selector;
+
+class SMESHOBJECT_EXPORT SMESH_PreviewActorsCollection
+{
+public:
+  SMESH_PreviewActorsCollection();
+  ~SMESH_PreviewActorsCollection();
+
+  virtual void    AddToRender(vtkRenderer* theRenderer);
+  virtual void    RemoveFromRender(vtkRenderer* theRenderer);
+
+  bool            Init( const TopoDS_Shape& theShape, TopAbs_ShapeEnum subShapeType = TopAbs_EDGE, const QString& = QString("") );
+
+  void            SetSelector( SVTK_Selector* );
+
+  void            HighlightAll( bool );
+  void            HighlightID( int );
+
+  GEOM_Actor*     GetActorByIndex( int );
+
+  int             GetIndexByShape( const TopoDS_Shape& );
+
+  void            SetShown( bool );
+
+  int             count() const;
+  int             chunkSize() const;
+  int             currentChunk() const;
+  bool            hasPrevious() const;
+  bool            hasNext() const;
+  void            previous();
+  void            next();
+  
+protected:
+  GEOM_Actor*    createActor( const TopoDS_Shape& );
+  void           showCurrentChunk();
+  void           clearActors();
+   
+protected:
+  TopAbs_ShapeEnum             myType;
+  QString                      myEntry;
+  TopoDS_Shape                 myMainShape;
+  SVTK_Selector*               mySelector;
+  vtkRenderer*                 myRenderer;
+  TopTools_IndexedMapOfShape   myMapOfShapes;
+  QMap<int, GEOM_Actor*>       myMapOfActors;
+  QList<int>                   myIndices;
+  int                          myCurrentChunk;
+  int                          myChunkSize;
+  bool                         myIsShown;
+};
+
+
+#endif //SMESH_DEVICE_ACTOR_COLLECTION_H
diff --git a/src/OBJECT/SMESH_ScalarBarActor.cxx b/src/OBJECT/SMESH_ScalarBarActor.cxx
new file mode 100644 (file)
index 0000000..a305712
--- /dev/null
@@ -0,0 +1,923 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+//  File   : SMESH_ScalarBarActor.cxx
+//  Author : Roman NIKOLAEV
+//  Module : SMESH
+//
+
+#include "SMESH_ScalarBarActor.h"
+
+#include <vtkCellArray.h>
+#include <vtkCellData.h>
+#include <vtkObjectFactory.h>
+#include <vtkPolyData.h>
+#include <vtkPolyDataMapper2D.h>
+#include <vtkScalarsToColors.h>
+#include <vtkTextMapper.h>
+#include <vtkTextProperty.h>
+#include <vtkViewport.h>
+#include <vtkWindow.h>
+#include <vtkLookupTable.h>
+#include <vtkProperty2D.h>
+
+#define SHRINK_COEF 0.08;
+
+vtkStandardNewMacro(SMESH_ScalarBarActor);
+
+vtkCxxSetObjectMacro(SMESH_ScalarBarActor,LookupTable,vtkScalarsToColors);
+vtkCxxSetObjectMacro(SMESH_ScalarBarActor,LabelTextProperty,vtkTextProperty);
+vtkCxxSetObjectMacro(SMESH_ScalarBarActor,TitleTextProperty,vtkTextProperty);
+
+//----------------------------------------------------------------------------
+// Instantiate object with 64 maximum colors; 5 labels; %%-#6.3g label
+// format, no title, and vertical orientation. The initial scalar bar
+// size is (0.05 x 0.8) of the viewport size.
+SMESH_ScalarBarActor::SMESH_ScalarBarActor() {
+  this->LookupTable = NULL;
+  this->Position2Coordinate->SetValue(0.17, 0.8);
+  
+  this->PositionCoordinate->SetCoordinateSystemToNormalizedViewport();
+  this->PositionCoordinate->SetValue(0.82,0.1);
+  
+  this->MaximumNumberOfColors = 64;
+  this->NumberOfLabels = 5;
+  this->NumberOfLabelsBuilt = 0;
+  this->Orientation = VTK_ORIENT_VERTICAL;
+  this->Title = NULL;
+
+  this->LabelTextProperty = vtkTextProperty::New();
+  this->LabelTextProperty->SetFontSize(12);
+  this->LabelTextProperty->SetBold(1);
+  this->LabelTextProperty->SetItalic(1);
+  this->LabelTextProperty->SetShadow(1);
+  this->LabelTextProperty->SetFontFamilyToArial();
+
+  this->TitleTextProperty = vtkTextProperty::New();
+  this->TitleTextProperty->ShallowCopy(this->LabelTextProperty);
+
+  this->LabelFormat = new char[8]; 
+  sprintf(this->LabelFormat,"%s","%-#6.3g");
+
+  this->TitleMapper = vtkTextMapper::New();
+  this->TitleActor = vtkActor2D::New();
+  this->TitleActor->SetMapper(this->TitleMapper);
+  this->TitleActor->GetPositionCoordinate()->
+    SetReferenceCoordinate(this->PositionCoordinate);
+  
+  this->TextMappers = NULL;
+  this->TextActors = NULL;
+
+  this->ScalarBar = vtkPolyData::New();
+  this->ScalarBarMapper = vtkPolyDataMapper2D::New();
+  this->ScalarBarMapper->SetInput(this->ScalarBar);
+  this->ScalarBarActor = vtkActor2D::New();
+  this->ScalarBarActor->SetMapper(this->ScalarBarMapper);
+  this->ScalarBarActor->GetPositionCoordinate()->
+    SetReferenceCoordinate(this->PositionCoordinate);
+  this->LastOrigin[0] = 0;
+  this->LastOrigin[1] = 0;
+  this->LastSize[0] = 0;
+  this->LastSize[1] = 0;
+
+
+  // rnv begin
+  // Customization of the vtkScalarBarActor to show distribution histogram.
+  myDistribution = vtkPolyData::New();
+  myDistributionMapper = vtkPolyDataMapper2D::New();
+  myDistributionMapper->SetInput(this->myDistribution);
+  
+  myDistributionActor = vtkActor2D::New();
+  myDistributionActor->SetMapper(this->myDistributionMapper);
+  myDistributionActor->GetPositionCoordinate()->
+    SetReferenceCoordinate(this->PositionCoordinate);
+
+  // By default distribution histogram is invisible
+  myDistributionActor->SetVisibility(0);
+
+  // By default monocolor
+  myDistributionColoringType = SMESH_MONOCOLOR_TYPE;
+  // rnv end
+}
+
+//----------------------------------------------------------------------------
+// Release any graphics resources that are being consumed by this actor.
+// The parameter window could be used to determine which graphic
+// resources to release.
+void SMESH_ScalarBarActor::ReleaseGraphicsResources(vtkWindow *win)
+{
+  this->TitleActor->ReleaseGraphicsResources(win);
+  if (this->TextMappers != NULL )
+    {
+    for (int i=0; i < this->NumberOfLabelsBuilt; i++)
+      {
+      this->TextActors[i]->ReleaseGraphicsResources(win);
+      }
+    }
+  this->ScalarBarActor->ReleaseGraphicsResources(win);
+  // rnv begin
+  // Customization of the vtkScalarBarActor to show distribution histogram.
+  myDistributionActor->ReleaseGraphicsResources(win);
+}
+
+
+/*--------------------------------------------------------------------------*/
+SMESH_ScalarBarActor::~SMESH_ScalarBarActor() {
+  if (this->LabelFormat) 
+    {
+    delete [] this->LabelFormat;
+    this->LabelFormat = NULL;
+    }
+
+  this->TitleMapper->Delete();
+  this->TitleActor->Delete();
+
+  if (this->TextMappers != NULL )
+    {
+    for (int i=0; i < this->NumberOfLabelsBuilt; i++)
+      {
+      this->TextMappers[i]->Delete();
+      this->TextActors[i]->Delete();
+      }
+    delete [] this->TextMappers;
+    delete [] this->TextActors;
+    }
+
+  this->ScalarBar->Delete();
+  this->ScalarBarMapper->Delete();
+  this->ScalarBarActor->Delete();
+
+  if (this->Title)
+    {
+    delete [] this->Title;
+    this->Title = NULL;
+    }
+  
+  this->SetLookupTable(NULL);
+  this->SetLabelTextProperty(NULL);
+  this->SetTitleTextProperty(NULL);
+  
+  // rnv begin
+  // Customization of the vtkScalarBarActor to show distribution histogram:
+  myDistribution->Delete();
+  myDistributionMapper->Delete();
+  myDistributionActor->Delete();
+  // rnv end
+}
+
+//----------------------------------------------------------------------------
+int SMESH_ScalarBarActor::RenderOverlay(vtkViewport *viewport)
+{
+  int renderedSomething = 0;
+  int i;
+  
+  // Everything is built, just have to render
+  if (this->Title != NULL)
+    {
+    renderedSomething += this->TitleActor->RenderOverlay(viewport);
+    }
+  this->ScalarBarActor->RenderOverlay(viewport);
+  this->myDistributionActor->RenderOverlay(viewport);
+  if( this->TextActors == NULL)
+    {
+     vtkWarningMacro(<<"Need a mapper to render a scalar bar");
+     return renderedSomething;
+    }
+  
+  for (i=0; i<this->NumberOfLabels; i++)
+    {
+    renderedSomething += this->TextActors[i]->RenderOverlay(viewport);
+    }
+
+  renderedSomething = (renderedSomething > 0)?(1):(0);
+
+  return renderedSomething;
+}
+
+
+//----------------------------------------------------------------------------
+int SMESH_ScalarBarActor::RenderOpaqueGeometry(vtkViewport *viewport)
+{
+  int renderedSomething = 0;
+  int i;
+  int size[2];
+  
+  if (!this->LookupTable)
+    {
+    vtkWarningMacro(<<"Need a mapper to render a scalar bar");
+    return 0;
+    }
+
+  if (!this->TitleTextProperty)
+    {
+    vtkErrorMacro(<<"Need title text property to render a scalar bar");
+    return 0;
+    }
+
+  if (!this->LabelTextProperty)
+    {
+    vtkErrorMacro(<<"Need label text property to render a scalar bar");
+    return 0;
+    }
+
+  // Check to see whether we have to rebuild everything
+  int positionsHaveChanged = 0;
+  if (viewport->GetMTime() > this->BuildTime || 
+      (viewport->GetVTKWindow() && 
+       viewport->GetVTKWindow()->GetMTime() > this->BuildTime))
+    {
+    // if the viewport has changed we may - or may not need
+    // to rebuild, it depends on if the projected coords chage
+    int *barOrigin;
+    barOrigin = this->PositionCoordinate->GetComputedViewportValue(viewport);
+    size[0] = 
+      this->Position2Coordinate->GetComputedViewportValue(viewport)[0] -
+      barOrigin[0];
+    size[1] = 
+      this->Position2Coordinate->GetComputedViewportValue(viewport)[1] -
+      barOrigin[1];
+    if (this->LastSize[0] != size[0] || 
+        this->LastSize[1] != size[1] ||
+        this->LastOrigin[0] != barOrigin[0] || 
+        this->LastOrigin[1] != barOrigin[1])
+      {
+      positionsHaveChanged = 1;
+      }
+    }
+  
+  // Check to see whether we have to rebuild everything
+  if (positionsHaveChanged ||
+      this->GetMTime() > this->BuildTime || 
+      this->LookupTable->GetMTime() > this->BuildTime ||
+      this->LabelTextProperty->GetMTime() > this->BuildTime ||
+      this->TitleTextProperty->GetMTime() > this->BuildTime)
+    {
+    vtkDebugMacro(<<"Rebuilding subobjects");
+
+    // Delete previously constructed objects
+    //
+    if (this->TextMappers != NULL )
+      {
+      for (i=0; i < this->NumberOfLabelsBuilt; i++)
+        {
+        this->TextMappers[i]->Delete();
+        this->TextActors[i]->Delete();
+        }
+      delete [] this->TextMappers;
+      delete [] this->TextActors;
+      }
+
+    // Build scalar bar object; determine its type
+    //
+    // is this a vtkLookupTable or a subclass of vtkLookupTable 
+    // with its scale set to log
+    // NOTE: it's possible we could to without the 'lut' variable
+    // later in the code, but if the vtkLookupTableSafeDownCast operation
+    // fails for some reason, this code will break in new ways. So, the 'LUT'
+    // variable is used for this operation only
+    vtkLookupTable *LUT = vtkLookupTable::SafeDownCast( this->LookupTable );
+    int isLogTable = 0;
+    if ( LUT )
+      {
+      if ( LUT->GetScale() == VTK_SCALE_LOG10 )
+        {
+        isLogTable = 1; 
+        }
+      }
+    
+    // we hard code how many steps to display
+    vtkScalarsToColors *lut = this->LookupTable;
+    int numColors = this->MaximumNumberOfColors;
+    double *range = lut->GetRange();
+
+    int numPts = 2*(numColors + 1);
+    vtkPoints *pts = vtkPoints::New();
+    pts->SetNumberOfPoints(numPts);
+    vtkCellArray *polys = vtkCellArray::New();
+    polys->Allocate(polys->EstimateSize(numColors,4));
+    vtkUnsignedCharArray *colors = vtkUnsignedCharArray::New();
+    colors->SetNumberOfComponents(3);
+    colors->SetNumberOfTuples(numColors);
+
+
+    // rnv begin
+    // Customization of the vtkScalarBarActor to show distribution histogram.
+    bool distrVisibility =  (numColors == this->myNbValues.size());
+    vtkPoints *distrPts;
+    vtkCellArray *distrPolys;
+    vtkUnsignedCharArray *distColors = 0;
+    int numDistrPts = 0, numPositiveVal=0, maxValue=0;
+    if(!distrVisibility)
+      vtkDebugMacro(<<" Distribution invisible, because numColors == this->myNbValues.size()");
+
+    if (distrVisibility && GetDistributionVisibility()) {
+      for( i=0 ;i<myNbValues.size();i++ ) {
+        if(myNbValues[i]) {
+          numPositiveVal++;
+          maxValue = std::max(maxValue,myNbValues[i]);
+        } 
+      }
+      numDistrPts = 4*(numPositiveVal);
+      distrPts = vtkPoints::New();
+      distrPolys = vtkCellArray::New();
+      distrPts->SetNumberOfPoints(numDistrPts);
+      distrPolys->Allocate(distrPolys->EstimateSize(numPositiveVal,4));
+      this->myDistribution->Initialize();
+      this->myDistribution->SetPoints(distrPts);
+      this->myDistribution->SetPolys(distrPolys);
+      distrPts->Delete();
+      distrPolys->Delete();
+      if ( myDistributionColoringType == SMESH_MULTICOLOR_TYPE ) {
+        distColors = vtkUnsignedCharArray::New();
+        distColors->SetNumberOfComponents(3);
+        distColors->SetNumberOfTuples(numPositiveVal);
+        this->myDistribution->GetCellData()->SetScalars(distColors);
+        distColors->Delete();
+      } else if( myDistributionColoringType == SMESH_MONOCOLOR_TYPE ){
+        this->myDistribution->GetCellData()->SetScalars(NULL);
+      }
+    } else {
+      myDistribution->Reset();
+    }
+    // rnv end
+
+    this->ScalarBarActor->SetProperty(this->GetProperty());
+    this->ScalarBar->Initialize();
+    this->ScalarBar->SetPoints(pts);
+    this->ScalarBar->SetPolys(polys);
+    this->ScalarBar->GetCellData()->SetScalars(colors);
+    pts->Delete(); polys->Delete(); colors->Delete();
+
+    // get the viewport size in display coordinates
+    int *barOrigin, barWidth, barHeight, distrHeight;
+    barOrigin = this->PositionCoordinate->GetComputedViewportValue(viewport);
+    size[0] = 
+      this->Position2Coordinate->GetComputedViewportValue(viewport)[0] -
+      barOrigin[0];
+    size[1] = 
+      this->Position2Coordinate->GetComputedViewportValue(viewport)[1] -
+      barOrigin[1];
+    this->LastOrigin[0] = barOrigin[0];
+    this->LastOrigin[1] = barOrigin[1];
+    this->LastSize[0] = size[0];
+    this->LastSize[1] = size[1];
+    
+    // Update all the composing objects
+    this->TitleActor->SetProperty(this->GetProperty());
+    this->TitleMapper->SetInput(this->Title);
+    if (this->TitleTextProperty->GetMTime() > this->BuildTime)
+      {
+      // Shallow copy here so that the size of the title prop is not affected
+      // by the automatic adjustment of its text mapper's size (i.e. its
+      // mapper's text property is identical except for the font size
+      // which will be modified later). This allows text actors to
+      // share the same text property, and in that case specifically allows
+      // the title and label text prop to be the same.
+      this->TitleMapper->GetTextProperty()->ShallowCopy(this->TitleTextProperty);
+      this->TitleMapper->GetTextProperty()->SetJustificationToCentered();
+      }
+    
+    // find the best size for the title font
+    int titleSize[2];
+    this->SizeTitle(titleSize, size, viewport);
+    
+    // find the best size for the ticks
+    int labelSize[2];
+    this->AllocateAndSizeLabels(labelSize, size, viewport,range);
+    this->NumberOfLabelsBuilt = this->NumberOfLabels;
+    
+    // generate points
+    double x[3]; x[2] = 0.0;
+    double delta, itemH, shrink;
+    if ( this->Orientation == VTK_ORIENT_VERTICAL ) {
+      // rnv begin
+      // Customization of the vtkScalarBarActor to show distribution histogram.
+      double delimeter=0.0;
+      if(GetDistributionVisibility() && distrVisibility) {
+        delimeter=0.01*size[0]; //1 % from horizontal size of the full presentation size.
+        barWidth = size[0] - 4 - labelSize[0];
+        distrHeight = barWidth/2;
+      } else {
+        barWidth = size[0] - 4 - labelSize[0];
+        distrHeight = 0;
+      }
+
+      barHeight = (int)(0.86*size[1]);
+      delta=(double)barHeight/numColors;
+      
+      for ( i=0; i<numPts/2; i++ ) {
+        x[0] = distrHeight+delimeter/2.0;
+        x[1] = i*delta;
+        pts->SetPoint(2*i,x);
+        x[0] = barWidth;
+        pts->SetPoint(2*i+1,x);
+      }
+
+      if(GetDistributionVisibility() && distrVisibility) {
+        // Distribution points 
+        shrink = delta*SHRINK_COEF;
+        vtkIdType distPtsId=0;
+        vtkIdType distPtsIds[4];
+        for(i=0; i<numColors; i++) {
+          if(myNbValues[i]) {
+            itemH = distrHeight*((double)myNbValues[i]/maxValue);
+            
+            if(distrHeight == itemH) 
+              itemH = itemH - delimeter/2;
+
+            x[1] = i*delta+shrink;
+
+            // first point of polygon (quadrangle)
+            x[0] = 0; 
+            distPtsIds[0] = distPtsId;
+            distrPts->SetPoint(distPtsId++,x);
+
+            // second point of polygon (quadrangle)
+            x[0] = itemH;
+            distPtsIds[1] = distPtsId;
+            distrPts->SetPoint(distPtsId++,x);
+
+            x[1] = i*delta+delta-shrink;
+
+            // third point of polygon (quadrangle)
+            x[0] = 0; 
+            distPtsIds[3] = distPtsId;
+            distrPts->SetPoint(distPtsId++,x);
+
+            // fourth point of polygon (quadrangle)
+            x[0] = itemH;
+            distPtsIds[2] = distPtsId;
+            distrPts->SetPoint(distPtsId++,x);
+
+            //Inser Quadrangle
+            distrPolys->InsertNextCell(4,distPtsIds);
+          }
+        }
+      }    
+    }
+    // rnv end
+    else {
+      barWidth = size[0];
+      
+      // rnv begin
+      // Customization of the vtkScalarBarActor to show distribution histogram.
+      double coef1, delimeter=0.0;
+      if(GetDistributionVisibility() && distrVisibility) {
+        coef1=0.62;
+        distrHeight = (int)((coef1/2)*size[1]);
+        //delimeter between distribution diagram and scalar bar 
+        delimeter=0.02*size[1];
+      }
+      else {
+        coef1=0.4;
+        barHeight = (int)(coef1*size[1]);
+        distrHeight = 0;
+      }
+      
+      barHeight = (int)(coef1*size[1]);
+      
+      delta=(double)barWidth/numColors;
+      for (i=0; i<numPts/2; i++) {
+        x[0] = i*delta;
+        x[1] = barHeight;
+        pts->SetPoint(2*i,x);                        
+        x[1] = distrHeight + delimeter;
+        pts->SetPoint(2*i+1,x);
+      }
+      
+      if(GetDistributionVisibility() && distrVisibility) {
+        // Distribution points 
+        shrink = delta*SHRINK_COEF;
+        vtkIdType distPtsId=0;
+        vtkIdType distPtsIds[4];
+        for(i=0; i<numColors; i++) {
+          if(myNbValues[i]) {
+            itemH = distrHeight*((double)myNbValues[i]/maxValue);
+            
+            // first point of polygon (quadrangle)
+            x[0] = i*delta+shrink; 
+            x[1] = 0;
+            distPtsIds[0] = distPtsId;
+            distrPts->SetPoint(distPtsId++,x);
+            
+            // second point of polygon (quadrangle)
+            x[0] = i*delta+shrink; 
+            x[1] = itemH;
+            distPtsIds[3] = distPtsId;
+            distrPts->SetPoint(distPtsId++,x);
+            
+            // third point of polygon (quadrangle)
+            x[0] = i*delta+delta-shrink; 
+            x[1] = 0;
+            distPtsIds[1] = distPtsId;
+            distrPts->SetPoint(distPtsId++,x);
+            
+            // fourth point of polygon (quadrangle)
+            x[0] = i*delta+delta-shrink; 
+            x[1] = itemH;
+            distPtsIds[2] = distPtsId;
+            distrPts->SetPoint(distPtsId++,x);
+            
+            // Add polygon into poly data
+            distrPolys->InsertNextCell(4,distPtsIds);
+          }
+        } 
+      }
+      // rnv end
+    }
+    
+    //polygons & cell colors
+    unsigned char *rgba, *rgb;
+    vtkIdType ptIds[4], dcCount=0;
+    for (i=0; i<numColors; i++)
+      {
+      ptIds[0] = 2*i;
+      ptIds[1] = ptIds[0] + 1;
+      ptIds[2] = ptIds[1] + 2;
+      ptIds[3] = ptIds[0] + 2;
+      polys->InsertNextCell(4,ptIds);
+
+      if ( isLogTable )
+        {
+        double rgbval = log10(range[0]) + 
+          i*(log10(range[1])-log10(range[0]))/(numColors -1);
+        rgba = lut->MapValue(pow(10.0,rgbval));
+        }
+      else
+        {
+        rgba = lut->MapValue(range[0] + (range[1] - range[0])*
+                             ((double)i /(numColors-1.0)));
+        }
+
+      rgb = colors->GetPointer(3*i); //write into array directly
+      rgb[0] = rgba[0];
+      rgb[1] = rgba[1];
+      rgb[2] = rgba[2];
+      
+      // rnv begin
+      // Customization of the vtkScalarBarActor to show distribution histogram.
+      if(myNbValues[i] && myDistributionColoringType == SMESH_MULTICOLOR_TYPE && GetDistributionVisibility() && distrVisibility)
+        {
+          rgb = distColors->GetPointer(3*dcCount); //write into array directly
+          rgb[0] = rgba[0];
+          rgb[1] = rgba[1];
+          rgb[2] = rgba[2];
+          dcCount++;
+        }
+      }
+
+    // Now position everything properly
+    //
+    double val;
+    if (this->Orientation == VTK_ORIENT_VERTICAL)
+      {
+      int sizeTextData[2];
+      
+      // center the title
+      this->TitleActor->SetPosition(size[0]/2, 0.9*size[1]);
+      
+      for (i=0; i < this->NumberOfLabels; i++)
+        {
+        if (this->NumberOfLabels > 1)
+          {
+          val = (double)i/(this->NumberOfLabels-1) *barHeight;
+          }
+        else 
+          {
+          val = 0.5*barHeight;
+          }
+        this->TextMappers[i]->GetSize(viewport,sizeTextData);
+        this->TextMappers[i]->GetTextProperty()->SetJustificationToLeft();
+        this->TextActors[i]->SetPosition(barWidth+3,
+                                         val - sizeTextData[1]/2);
+        }
+      }
+    else
+      {
+      this->TitleActor->SetPosition(size[0]/2, 
+                                    barHeight + labelSize[1] + 0.1*size[1]);
+      for (i=0; i < this->NumberOfLabels; i++)
+        {
+        this->TextMappers[i]->GetTextProperty()->SetJustificationToCentered();
+        if (this->NumberOfLabels > 1)
+          {
+          val = (double)i/(this->NumberOfLabels-1) * barWidth;
+          }
+        else
+          {
+          val = 0.5*barWidth;
+          }
+        this->TextActors[i]->SetPosition(val, barHeight + 0.05*size[1]);
+        }
+      }
+
+    this->BuildTime.Modified();
+    }
+
+  // Everything is built, just have to render
+  if (this->Title != NULL)
+    {
+    renderedSomething += this->TitleActor->RenderOpaqueGeometry(viewport);
+    }
+  this->ScalarBarActor->RenderOpaqueGeometry(viewport);
+  this->myDistributionActor->RenderOpaqueGeometry(viewport);
+  for (i=0; i<this->NumberOfLabels; i++)
+    {
+    renderedSomething += this->TextActors[i]->RenderOpaqueGeometry(viewport);
+    }
+
+  renderedSomething = (renderedSomething > 0)?(1):(0);
+
+  return renderedSomething;
+}
+
+//----------------------------------------------------------------------------
+void SMESH_ScalarBarActor::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os,indent);
+
+  if ( this->LookupTable )
+    {
+    os << indent << "Lookup Table:\n";
+    this->LookupTable->PrintSelf(os,indent.GetNextIndent());
+    }
+  else
+    {
+    os << indent << "Lookup Table: (none)\n";
+    }
+
+  if (this->TitleTextProperty)
+    {
+    os << indent << "Title Text Property:\n";
+    this->TitleTextProperty->PrintSelf(os,indent.GetNextIndent());
+    }
+  else
+    {
+    os << indent << "Title Text Property: (none)\n";
+    }
+
+  if (this->LabelTextProperty)
+    {
+    os << indent << "Label Text Property:\n";
+    this->LabelTextProperty->PrintSelf(os,indent.GetNextIndent());
+    }
+  else
+    {
+    os << indent << "Label Text Property: (none)\n";
+    }
+
+  os << indent << "Title: " << (this->Title ? this->Title : "(none)") << "\n";
+  os << indent << "Maximum Number Of Colors: " 
+     << this->MaximumNumberOfColors << "\n";
+  os << indent << "Number Of Labels: " << this->NumberOfLabels << "\n";
+  os << indent << "Number Of Labels Built: " << this->NumberOfLabelsBuilt << "\n";
+
+  os << indent << "Orientation: ";
+  if ( this->Orientation == VTK_ORIENT_HORIZONTAL )
+    {
+    os << "Horizontal\n";
+    }
+  else
+    {
+    os << "Vertical\n";
+    }
+
+  os << indent << "Label Format: " << this->LabelFormat << "\n";
+}
+
+//----------------------------------------------------------------------------
+void SMESH_ScalarBarActor::ShallowCopy(vtkProp *prop)
+{
+  SMESH_ScalarBarActor *a = SMESH_ScalarBarActor::SafeDownCast(prop);
+  if ( a != NULL )
+    {
+    this->SetPosition2(a->GetPosition2());
+    this->SetLookupTable(a->GetLookupTable());
+    this->SetMaximumNumberOfColors(a->GetMaximumNumberOfColors());
+    this->SetOrientation(a->GetOrientation());
+    this->SetLabelTextProperty(a->GetLabelTextProperty());
+    this->SetTitleTextProperty(a->GetTitleTextProperty());
+    this->SetLabelFormat(a->GetLabelFormat());
+    this->SetTitle(a->GetTitle());
+    this->GetPositionCoordinate()->SetCoordinateSystem(
+      a->GetPositionCoordinate()->GetCoordinateSystem());    
+    this->GetPositionCoordinate()->SetValue(
+      a->GetPositionCoordinate()->GetValue());
+    this->GetPosition2Coordinate()->SetCoordinateSystem(
+      a->GetPosition2Coordinate()->GetCoordinateSystem());    
+    this->GetPosition2Coordinate()->SetValue(
+      a->GetPosition2Coordinate()->GetValue());
+    }
+
+  // Now do superclass
+  this->vtkActor2D::ShallowCopy(prop);
+}
+
+//----------------------------------------------------------------------------
+void SMESH_ScalarBarActor::AllocateAndSizeLabels(int *labelSize, 
+                                              int *size,
+                                              vtkViewport *viewport,
+                                              double *range)
+{
+  labelSize[0] = labelSize[1] = 0;
+
+  this->TextMappers = new vtkTextMapper * [this->NumberOfLabels];
+  this->TextActors = new vtkActor2D * [this->NumberOfLabels];
+
+  char string[512];
+
+  double val;
+  int i;
+  
+  // TODO: this should be optimized, maybe by keeping a list of
+  // allocated mappers, in order to avoid creation/destruction of
+  // their underlying text properties (i.e. each time a mapper is
+  // created, text properties are created and shallow-assigned a font size
+  // which value might be "far" from the target font size).
+
+  // is this a vtkLookupTable or a subclass of vtkLookupTable 
+  // with its scale set to log
+  vtkLookupTable *LUT = vtkLookupTable::SafeDownCast( this->LookupTable );
+  int isLogTable = 0;
+  if ( LUT )
+    {
+    if ( LUT->GetScale() == VTK_SCALE_LOG10 )
+      {
+      isLogTable = 1; 
+      }
+    }
+
+  for (i=0; i < this->NumberOfLabels; i++)
+    {
+    this->TextMappers[i] = vtkTextMapper::New();
+
+    if ( isLogTable )
+      {
+      double lval;
+      if (this->NumberOfLabels > 1)
+        {
+        lval = log10(range[0]) + (double)i/(this->NumberOfLabels-1) *
+          (log10(range[1])-log10(range[0]));
+        }
+      else
+        {
+        lval = log10(range[0]) + 0.5*(log10(range[1])-log10(range[0]));
+        }
+      val = pow(10.0,lval);
+      }
+    else
+      {
+      if (this->NumberOfLabels > 1)
+        {
+        val = range[0] + 
+          (double)i/(this->NumberOfLabels-1) * (range[1]-range[0]);
+        }
+      else
+        {
+        val = range[0] + 0.5*(range[1]-range[0]);
+        }
+      }
+
+    sprintf(string, this->LabelFormat, val);
+    this->TextMappers[i]->SetInput(string);
+
+    // Shallow copy here so that the size of the label prop is not affected
+    // by the automatic adjustment of its text mapper's size (i.e. its
+    // mapper's text property is identical except for the font size
+    // which will be modified later). This allows text actors to
+    // share the same text property, and in that case specifically allows
+    // the title and label text prop to be the same.
+    this->TextMappers[i]->GetTextProperty()->ShallowCopy(
+      this->LabelTextProperty);
+
+    this->TextActors[i] = vtkActor2D::New();
+    this->TextActors[i]->SetMapper(this->TextMappers[i]);
+    this->TextActors[i]->SetProperty(this->GetProperty());
+    this->TextActors[i]->GetPositionCoordinate()->
+      SetReferenceCoordinate(this->PositionCoordinate);
+    }
+
+  if (this->NumberOfLabels)
+    {
+    int targetWidth, targetHeight;
+    // rnv begin
+    // Customization of the vtkScalarBarActor to show distribution histogram.
+    bool distrVisibility = this->MaximumNumberOfColors == this->myNbValues.size();
+    double coef;
+    if( GetDistributionVisibility() && distrVisibility )
+      if(this->Orientation == VTK_ORIENT_VERTICAL)
+        coef = 0.4;
+      else 
+        coef = 0.18;
+    else 
+      if(this->Orientation == VTK_ORIENT_VERTICAL)
+        coef = 0.6;
+      else 
+        coef=0.25;
+
+
+    if ( this->Orientation == VTK_ORIENT_VERTICAL )
+      {
+      targetWidth = (int)(coef*size[0]);
+      targetHeight = (int)(0.86*size[1]/this->NumberOfLabels);
+      }
+    else
+      {
+      targetWidth = (int)(size[0]*0.8/this->NumberOfLabels);
+      targetHeight = (int)(coef*size[1]);
+      }
+    // rnv end
+    
+    vtkTextMapper::SetMultipleConstrainedFontSize(viewport, 
+                                                  targetWidth, 
+                                                  targetHeight,
+                                                  this->TextMappers,
+                                                  this->NumberOfLabels,
+                                                  labelSize);
+    }
+}
+
+//----------------------------------------------------------------------------
+void SMESH_ScalarBarActor::SizeTitle(int *titleSize, 
+                                  int *size, 
+                                  vtkViewport *viewport)
+{
+  titleSize[0] = titleSize[1] = 0;
+
+  if (this->Title == NULL || !strlen(this->Title))
+    {
+    return;
+    }
+
+  int targetWidth, targetHeight;
+  
+  targetWidth = size[0];
+  // rnv begin
+  // Customization of the vtkScalarBarActor to show distribution histogram.
+  bool distrVisibility =  this->MaximumNumberOfColors == this->myNbValues.size();
+  double coef;
+  if( GetDistributionVisibility() && distrVisibility ) 
+    coef=0.18;
+  else 
+    coef=0.25;
+
+  if ( this->Orientation == VTK_ORIENT_VERTICAL )
+    {
+      targetHeight = (int)(0.1*size[1]);
+    }
+  else
+    {
+      targetHeight = (int)(coef*size[1]);
+    }
+
+  this->TitleMapper->SetConstrainedFontSize(
+    viewport, targetWidth, targetHeight);
+
+  this->TitleMapper->GetSize(viewport, titleSize);
+}
+
+
+/*--------------------------------------------------------------------------*/
+void SMESH_ScalarBarActor::SetDistributionVisibility(int flag) {
+  myDistributionActor->SetVisibility(flag);
+  Modified();
+}
+
+
+/*--------------------------------------------------------------------------*/
+int SMESH_ScalarBarActor::GetDistributionVisibility() {
+  return myDistributionActor->GetVisibility();
+}
+
+
+void SMESH_ScalarBarActor::SetDistribution(std::vector<int> theNbValues) {
+  myNbValues = theNbValues;
+} 
+
+
+void SMESH_ScalarBarActor::SetDistributionColor (double rgb[3]) {
+  myDistributionActor->GetProperty()->SetColor(rgb);
+  Modified();
+}
+
+void SMESH_ScalarBarActor::GetDistributionColor (double rgb[3]) {
+  myDistributionActor->GetProperty()->GetColor(rgb);
+}
diff --git a/src/OBJECT/SMESH_ScalarBarActor.h b/src/OBJECT/SMESH_ScalarBarActor.h
new file mode 100644 (file)
index 0000000..f110c5d
--- /dev/null
@@ -0,0 +1,246 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+//  SMESH SCALAR BAR : 2D Actor for the visualization scalar bar with the distribution diagram
+//                     it is customized vtkScalarBarActor.
+//  File   : SMESH_ScalarBarActor.h
+//  Author : Roman NIKOLAEV
+//  Module : SMESH
+
+
+// .NAME vtkScalarBarActor - Create a scalar bar with labels 
+// .SECTION Description
+// vtkScalarBarActor creates a scalar bar with annotation text. A scalar
+// bar is a legend that indicates to the viewer the correspondence between
+// color value and data value. The legend consists of a rectangular bar 
+// made of rectangular pieces each colored a constant value. Since 
+// vtkScalarBarActor is a subclass of vtkActor2D, it is drawn in the image 
+// plane (i.e., in the renderer's viewport) on top of the 3D graphics window.
+//
+// To use vtkScalarBarActor you must associate a vtkScalarsToColors (or
+// subclass) with it. The lookup table defines the colors and the
+// range of scalar values used to map scalar data.  Typically, the
+// number of colors shown in the scalar bar is not equal to the number
+// of colors in the lookup table, in which case sampling of
+// the lookup table is performed. 
+//
+// Other optional capabilities include specifying the fraction of the
+// viewport size (both x and y directions) which will control the size
+// of the scalar bar and the number of annotation labels. The actual position
+// of the scalar bar on the screen is controlled by using the
+// vtkActor2D::SetPosition() method (by default the scalar bar is
+// centered in the viewport).  Other features include the ability to
+// orient the scalar bar horizontally of vertically and controlling
+// the format (printf style) with which to print the labels on the
+// scalar bar. Also, the vtkScalarBarActor's property is applied to
+// the scalar bar and annotation (including layer, and
+// compositing operator).
+//
+// Set the text property/attributes of the title and the labels through the 
+// vtkTextProperty objects associated to this actor.
+//
+// .SECTION Caveats
+// If a vtkLogLookupTable is specified as the lookup table to use, then the
+// labels are created using a logarithmic scale.
+//
+// .SECTION See Also
+// vtkActor2D vtkTextProperty vtkTextMapper vtkPolyDataMapper2D
+
+#ifndef SMESH_SCALAR_BAR_ACTOR_H
+#define SMESH_SCALAR_BAR_ACTOR_H
+
+#include <vtkActor2D.h>
+
+#include "SMESH_Object.h"
+
+#include <vector>
+
+class vtkPolyData;
+class vtkPolyDataMapper2D;
+class vtkScalarsToColors;
+class vtkTextMapper;
+class vtkTextProperty;
+
+#define VTK_ORIENT_HORIZONTAL 0
+#define VTK_ORIENT_VERTICAL 1
+
+#define SMESH_MONOCOLOR_TYPE 0
+#define SMESH_MULTICOLOR_TYPE 1
+
+
+class SMESHOBJECT_EXPORT SMESH_ScalarBarActor: public vtkActor2D {
+ public:
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  vtkTypeMacro(SMESH_ScalarBarActor,vtkActor2D);
+
+  // Description:
+  // Instantiate object with 64 maximum colors; 5 labels; %%-#6.3g label
+  // format, no title, and vertical orientation. The initial scalar bar
+  // size is (0.05 x 0.8) of the viewport size.
+  static SMESH_ScalarBarActor *New();
+
+  // Description:
+  // Draw the scalar bar and annotation text to the screen.
+  int RenderOpaqueGeometry(vtkViewport* viewport);
+  int RenderTranslucentGeometry(vtkViewport*) { return 0; };
+  int RenderOverlay(vtkViewport* viewport);
+
+  // Description:
+  // Release any graphics resources that are being consumed by this actor.
+  // The parameter window could be used to determine which graphic
+  // resources to release.
+  virtual void ReleaseGraphicsResources(vtkWindow *);
+
+  // Description:
+  // Set/Get the vtkLookupTable to use. The lookup table specifies the number
+  // of colors to use in the table (if not overridden), as well as the scalar
+  // range.
+  virtual void SetLookupTable(vtkScalarsToColors*);
+  vtkGetObjectMacro(LookupTable,vtkScalarsToColors);
+
+  // Description:
+  // Set/Get the maximum number of scalar bar segments to show. This may
+  // differ from the number of colors in the lookup table, in which case
+  // the colors are samples from the lookup table.
+  vtkSetClampMacro(MaximumNumberOfColors, int, 2, VTK_LARGE_INTEGER);
+  vtkGetMacro(MaximumNumberOfColors, int);
+  
+  // Description:
+  // Set/Get the number of annotation labels to show.
+  vtkSetClampMacro(NumberOfLabels, int, 0, 64);
+  vtkGetMacro(NumberOfLabels, int);
+  
+  // Description:
+  // Control the orientation of the scalar bar.
+  vtkSetClampMacro(Orientation,int,VTK_ORIENT_HORIZONTAL, VTK_ORIENT_VERTICAL);
+  vtkGetMacro(Orientation, int);
+  void SetOrientationToHorizontal()
+       {this->SetOrientation(VTK_ORIENT_HORIZONTAL);};
+  void SetOrientationToVertical() {this->SetOrientation(VTK_ORIENT_VERTICAL);};
+
+  // Description:
+  // Set/Get the title text property.
+  virtual void SetTitleTextProperty(vtkTextProperty *p);
+  vtkGetObjectMacro(TitleTextProperty,vtkTextProperty);
+  
+  // Description:
+  // Set/Get the labels text property.
+  virtual void SetLabelTextProperty(vtkTextProperty *p);
+  vtkGetObjectMacro(LabelTextProperty,vtkTextProperty);
+    
+  // Description:
+  // Set/Get the format with which to print the labels on the scalar
+  // bar.
+  vtkSetStringMacro(LabelFormat);
+  vtkGetStringMacro(LabelFormat);
+
+  // Description:
+  // Set/Get the title of the scalar bar actor,
+  vtkSetStringMacro(Title);
+  vtkGetStringMacro(Title);
+
+  // Description:
+  // Shallow copy of a scalar bar actor. Overloads the virtual vtkProp method.
+  void ShallowCopy(vtkProp *prop);
+
+  // Description:
+  // Set visibility of the distribution histogram
+  // rnv: Customization of the vtkScalarBarActor to show distribution histogram:
+  virtual void SetDistributionVisibility(int flag);
+
+  // Description:
+  // Set visibility of the distribution histogram
+  // rnv: Customization of the vtkScalarBarActor to show distribution histogram:
+  virtual int GetDistributionVisibility();
+  // Description:
+  // Set distribution
+  virtual void SetDistribution(std::vector<int> theNbValues);
+  
+  // Description: 
+  // Set distribution coloring type (SMESH_MONOCOLOR_TYPE or SMESH_MULTICOLOR_TYPE)
+  void SetDistributionColoringType(int theDistributionColoringType) {myDistributionColoringType = theDistributionColoringType;Modified();}
+
+  // Description: 
+  // Get distribution coloring type ((SMESH_MONOCOLOR_TYPE or SMESH_MULTICOLOR_TYPE))  
+  int GetDistributionColoringType() {return myDistributionColoringType;}
+
+  // Description:
+  // Set Distribution Color
+  void SetDistributionColor (double rgb[3]);
+
+  // Description:
+  // Get Distribution Color
+  void GetDistributionColor (double rgb[3]);
+  
+
+
+ protected:
+  SMESH_ScalarBarActor();
+  ~SMESH_ScalarBarActor();
+  
+  vtkScalarsToColors *LookupTable;
+  vtkTextProperty *TitleTextProperty;
+  vtkTextProperty *LabelTextProperty;
+  
+  int   MaximumNumberOfColors;
+  int   NumberOfLabels;
+  int   NumberOfLabelsBuilt;
+  int   Orientation;
+  char  *Title;
+  char  *LabelFormat;
+
+  vtkTextMapper **TextMappers;
+  virtual void AllocateAndSizeLabels(int *labelSize, int *size,
+                                     vtkViewport *viewport, double *range);
+
+  
+  
+ private:
+  vtkTextMapper *TitleMapper;
+  vtkActor2D    *TitleActor;
+
+  vtkActor2D    **TextActors;
+
+  vtkPolyData         *ScalarBar;
+  vtkPolyDataMapper2D *ScalarBarMapper;
+  vtkActor2D          *ScalarBarActor;
+
+  vtkTimeStamp  BuildTime;
+  int LastSize[2];
+  int LastOrigin[2];
+
+  void SizeTitle(int *titleSize, int *size, vtkViewport *viewport);
+  
+  // rnv: Customization of the vtkScalarBarActor to show distribution histogram:
+  vtkPolyData*           myDistribution;             //Distribution polygonal data
+  vtkActor2D*            myDistributionActor;        //Distribution actor
+  vtkPolyDataMapper2D*   myDistributionMapper;       //Distribution mapper
+  std::vector<int>       myNbValues;                 //Nb values for the range
+  int                    myDistributionColoringType; //Distribution color type (monocolor or multicolor)
+  
+ private:
+  SMESH_ScalarBarActor(const SMESH_ScalarBarActor&);  // Not implemented.
+  void operator=(const SMESH_ScalarBarActor&);  // Not implemented.
+};
+
+#endif //SMESH_SCALAR_BAR_ACTOR_H
diff --git a/src/PluginUtils/GeomSelectionTools.cxx b/src/PluginUtils/GeomSelectionTools.cxx
new file mode 100644 (file)
index 0000000..07c7f08
--- /dev/null
@@ -0,0 +1,342 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+// ---
+// File    : GeomSelectionTools.cxx
+// Authors : Nicolas GEIMER (OCC)
+// ---
+
+#include "GeomSelectionTools.h"
+
+#include <LightApp_SelectionMgr.h>
+#include <SalomeApp_Application.h>
+#include <SUIT_Session.h>
+
+#include <SALOME_ListIteratorOfListIO.hxx>
+#include <GEOM_Client.hxx>
+#include <SMESHGUI_Utils.h>
+#include <boost/shared_ptr.hpp>
+#include <GEOMImpl_Types.hxx>
+
+#include <TopoDS.hxx>
+#include <BRep_Tool.hxx>
+#include <Handle_Geom_Surface.hxx>
+#include <BRepAdaptor_Surface.hxx>
+
+#include "utilities.h"
+
+#include "SALOME_LifeCycleCORBA.hxx"
+#include <sstream>
+
+/*!
+ * Constructor
+ * @param aStudy pointer to the Study
+ *
+ */
+GeomSelectionTools::GeomSelectionTools(_PTR(Study) aStudy)
+{
+  myStudy = aStudy;
+}
+
+/*!
+ * Accessor to the Study used by this GeomSelectionTools object
+ * @return The study used by the GeomSelectionTools class
+ */
+_PTR(Study) GeomSelectionTools::getMyStudy()
+{
+    return myStudy;
+}
+
+/*!
+ * Allows to get the Salome Application
+ * @return A LightApp_SelectionMgr Pointer or 0 if it can't get it.
+ */
+SalomeApp_Application*  GeomSelectionTools::GetSalomeApplication()
+{
+  SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
+  if (anApp)
+    return anApp;
+  else
+    return 0;
+}
+
+/*!
+ * Allows to get the selection manager from LightApp
+ * @return A LightApp_SelectionMgr Pointer or 0 if it can't get it.
+ */
+LightApp_SelectionMgr*  GeomSelectionTools::selectionMgr()
+{
+   SalomeApp_Application* anApp = GetSalomeApplication();
+   if (anApp)
+     return dynamic_cast<LightApp_SelectionMgr*>( anApp->selectionMgr() );
+   else
+     return 0;
+}
+
+/*!
+ * Return the list of the selected Salome Interactive Object (SALOME_ListIO*)
+ * @return the list of the selected Salome Interactive Object
+ */
+SALOME_ListIO* GeomSelectionTools::getSelectedSalomeObjects()
+{
+  SALOME_ListIO* selected;
+  LightApp_SelectionMgr* aSel = selectionMgr();
+  aSel->selectedObjects( *selected, NULL, false );
+  return selected;
+}
+
+/*!
+ * Return the first selected Salome Interactive Object (Handle(Salome_InteractiveObject))
+ * @return the first selected Salome Interactive Object
+ */
+Handle(SALOME_InteractiveObject) GeomSelectionTools::getFirstSelectedSalomeObject()
+{
+  SALOME_ListIO selected;
+  LightApp_SelectionMgr* aSel = selectionMgr();
+  aSel->selectedObjects( selected, NULL, false );
+  if (!selected.IsEmpty()){
+    SALOME_ListIteratorOfListIO anIt(selected);
+    Handle(SALOME_InteractiveObject) anIO;
+    anIO = anIt.Value();
+    return anIO;
+  }
+  return NULL;
+}
+
+/*!
+ * Return the entry of the first selected Object
+ * @return the entry of the first selected Object
+ */
+std::string GeomSelectionTools::getFirstSelectedEntry()
+{
+  Handle(SALOME_InteractiveObject) anIO;
+  std::string entry="";
+  anIO=GeomSelectionTools::getFirstSelectedSalomeObject();
+  return GeomSelectionTools::getEntryOfObject(anIO);
+}
+
+/*!
+ * Return the entry of a Salome Interactive Object
+ * @param anIO the Handle of the Salome Interactive Object
+ * @return the entry of the Salome Interactive Object
+ */
+std::string GeomSelectionTools::getEntryOfObject(Handle(SALOME_InteractiveObject) anIO){
+  std::string entry="";
+  _PTR(SObject) aSO = myStudy->FindObjectID(anIO->getEntry());
+  if (aSO){
+    _PTR(SObject) aRefSObj;
+    // If selected object is a reference
+    if ( aSO->ReferencedObject( aRefSObj ))
+      entry = aRefSObj->GetID();
+    // If selected object is a reference is not a reference
+    else
+      entry= anIO->getEntry();
+  }
+  return entry;
+}
+
+/*!
+ * Retrieve the name from the entry of the object
+ * @param entry the entry of the object
+ * @return the name of the object
+ */
+std::string GeomSelectionTools::getNameFromEntry(std::string entry){
+  std::string name = "";
+  _PTR(SObject) aSO = myStudy->FindObjectID(entry);
+  if (aSO){
+    _PTR(SObject) aRefSObj;
+    // If selected object is a reference
+    if ( aSO->ReferencedObject( aRefSObj ))
+      name = aRefSObj->GetName();
+    // If selected object is a reference is not a reference
+    else
+      name = aSO->GetName();
+   }
+  return name;
+}
+
+
+/*!
+ * Retrieve the component type of the first selected object, it manages successfully references.
+ * @return the component type of the first selected object
+ */
+std::string GeomSelectionTools::getFirstSelectedComponentDataType()
+{
+  Handle(SALOME_InteractiveObject) anIO;
+  std::string DataType="";
+  anIO=GeomSelectionTools::getFirstSelectedSalomeObject();
+  _PTR(SObject) aSO = myStudy->FindObjectID(anIO->getEntry());
+  if (aSO){
+    _PTR(SObject) aRefSObj;
+    // If selected object is a reference
+    if ( aSO->ReferencedObject( aRefSObj ))
+      DataType= aRefSObj->GetFatherComponent()->ComponentDataType();
+    // If selected object is a reference is not a reference
+    else
+      DataType=anIO->getComponentDataType();
+ }
+ return DataType;
+}
+
+/*!
+ * Retrieve the shape type from the entry
+ * @return the shape type from the entry, return TopAbs_SHAPE if the object does not define a shape or a group.
+ */
+TopAbs_ShapeEnum GeomSelectionTools::entryToShapeType(std::string entry){
+//   MESSAGE("GeomSelectionTools::entryToShapeType"<<entry );
+  TopoDS_Shape S = TopoDS_Shape();
+  TopAbs_ShapeEnum ShapeType = TopAbs_SHAPE;
+   _PTR(SObject) aSO = myStudy->FindObjectID(entry);
+  if (aSO){
+    _PTR(SObject) aRefSObj;
+    GEOM::GEOM_Object_var aShape;
+    // MESSAGE("Got a SO");
+    // If selected object is a reference
+    if ( aSO->ReferencedObject( aRefSObj ))
+      aSO = aRefSObj;
+    // MESSAGE("aSO->GetFatherComponent()->ComponentDataType(): " << aSO->GetFatherComponent()->ComponentDataType());
+    if (  strcmp(aSO->GetFatherComponent()->ComponentDataType().c_str(),"GEOM") == 0)
+      aShape = SMESH::SObjectToInterface<GEOM::GEOM_Object>(aSO);
+    if ( !aShape->_is_nil() ){
+      // MESSAGE("Got the Geom Object ");
+      // MESSAGE("Geom Object Type "<< aShape->GetType());
+      SalomeApp_Application* anApp = GetSalomeApplication();
+      if (anApp) {
+//         MESSAGE("Got Application");
+        Engines::EngineComponent_var component = anApp->lcc()->FindOrLoad_Component( "FactoryServer","GEOM" );
+        GEOM::GEOM_Gen_var _geomEngine = GEOM::GEOM_Gen::_narrow(component);
+//         MESSAGE("Got GEOM engine");
+        // if the Geom Object is a group
+        if (aShape->GetType() == GEOM_GROUP){
+//           MESSAGE("It's a group");
+          GEOM::GEOM_IGroupOperations_var aGroupOp = _geomEngine->GetIGroupOperations(myStudy->StudyId());
+          ShapeType= (TopAbs_ShapeEnum)aGroupOp->GetType(aShape);
+        }
+        // if not
+        else {
+          GEOM_Client* aClient = new GEOM_Client();
+          if ( aClient && !_geomEngine->_is_nil() ) {
+//             MESSAGE("GEOM client is OK and GEOM engine is not null");
+            S = aClient->GetShape( _geomEngine, aShape );
+            ShapeType=S.ShapeType();
+          }
+        }
+      }
+    }
+  }
+//   MESSAGE("ShapeType returned is " << ShapeType);
+  return ShapeType;
+}
+
+/*!
+ * Gives the ShapeType of the first Selected Object, return TopAbs_SHAPE if the first selected object does not define a shape.
+ * @return the ShapeType of the first Selected Object, return TopAbs_SHAPE if the first selected object does not define a shape.
+ */
+TopAbs_ShapeEnum GeomSelectionTools:: getFirstSelectedShapeType()
+{
+ Handle(SALOME_InteractiveObject) anIO;
+ anIO=GeomSelectionTools::getFirstSelectedSalomeObject();
+ return entryToShapeType(anIO->getEntry());
+}
+
+/*!
+ *  Print information to std output of the face
+ *  and return the OCC type of face: Plane, Cylinder,Cone, Sphere, Torus, BezierSurface,BSplineSurface, SurfaceOfRevolution,SurfaceOfExtrusion, OtherSurface
+ *  @param TopoDS_Shape S Face we want information about.
+ *  @return the OCC type of face: Plane, Cylinder,Cone, Sphere, Torus, BezierSurface,BSplineSurface, SurfaceOfRevolution,SurfaceOfExtrusion, OtherSurface
+ *  return Other_Surface if the selected face is not a face.
+ *  Information printed is :
+ *  U and V degrees
+ *  U and V number of poles
+ *  U and V number of knots
+ *  U or V is Rational ?
+ *
+ */
+GeomAbs_SurfaceType GeomSelectionTools::getFaceInformation(TopoDS_Shape S)
+{
+  GeomAbs_SurfaceType surf_type=GeomAbs_OtherSurface ;
+  if (!S.IsNull() &&  S.ShapeType()==TopAbs_FACE){
+    TopoDS_Face f=TopoDS::Face(S);
+    Handle(Geom_Surface) surf = BRep_Tool::Surface(f);
+    BRepAdaptor_Surface surf_adap(f);
+
+    /* Global Information */
+    std::cout << "GLOBAL INFORMATION" << std::endl;
+    std::cout << "******************" << std::endl;
+    std::stringstream buffer;
+    buffer << "Degre U : " <<  surf_adap.UDegree();
+   //conversion nécessaire pour affichage
+    std::cout << buffer.str() << std::endl;
+    std::cout <<  " Degre V : " <<  surf_adap.VDegree() << std::endl;
+    std::cout <<  " Nb Poles U : " <<  surf_adap.NbUPoles() << std::endl;
+    std::cout <<  " Nb Poles V : " <<  surf_adap.NbVPoles() << std::endl;
+    std::cout <<  " Nb Noeuds U : " <<  surf_adap.NbUKnots() << std::endl;
+    std::cout <<  " Nb Noeuds V : " <<  surf_adap.NbVKnots() << std::endl;
+    std::cout <<  " U Rationnel ? " <<  surf_adap.IsURational() << std::endl;
+    std::cout <<  " V Rationnel ? " <<  surf_adap.IsVRational() << std::endl;
+
+    surf_type=surf_adap.GetType();
+  }
+  return surf_type;
+}
+
+
+//////////////////////////////////////////
+// Utility functions
+//////////////////////////////////////////
+#include <QLocale>
+#include <QRegExp>
+
+QString PluginUtils::PrintDoubleValue( double theValue, int thePrecision )
+{
+  const double prec = 1e-12;
+
+  if ( qAbs(theValue) < prec )
+    return "0";
+
+  QString aRes = QLocale().toString( theValue, thePrecision >= 0 ? 'f' : 'g', qAbs( thePrecision ) );
+
+  if ( prec > 0 ) {
+    int p = 0;
+    while ( p < thePrecision ) {
+      QString aRes = QLocale().toString( theValue, thePrecision >= 0 ? 'f' : 'g', qAbs( p++ ) );
+      double v = aRes.toDouble();
+      double err = qAbs( theValue - v );
+      if ( err > 0 && err <= prec )
+        break;
+    }
+  }
+
+  // remove trailing zeroes
+
+  QRegExp expre( QString( "(%1|%2)[+-]?[0-9]+$" ).arg( QLocale().exponential().toLower(),
+                               QLocale().exponential().toUpper() ) );
+
+  int idx = aRes.indexOf( expre );
+  QString aResExp = "";
+  if ( idx >= 0 ) {
+    aResExp = aRes.mid( idx );
+    aRes = aRes.left( idx );
+  }
+
+  if ( aRes.contains( QLocale().decimalPoint() ) )
+    aRes.remove( QRegExp( QString( "(\\%1|0)0*$" ).arg( QLocale().decimalPoint() ) ) );
+
+  return aRes == "-0" ? QString( "0" ) : aRes + aResExp;
+}
diff --git a/src/PluginUtils/GeomSelectionTools.h b/src/PluginUtils/GeomSelectionTools.h
new file mode 100644 (file)
index 0000000..3704861
--- /dev/null
@@ -0,0 +1,91 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+// ---
+// File    : GeomSelectionTools.h
+// Authors : Nicolas GEIMER (OCC)
+// ---
+
+#ifndef _GEOMSELECTIONTOOLS_H_
+#define _GEOMSELECTIONTOOLS_H_
+
+#ifdef WIN32
+#  ifdef GeomSelectionTools_EXPORTS
+#    define GEOMSELECTIONTOOLS_EXPORT __declspec( dllexport )
+#  else
+#    define GEOMSELECTIONTOOLS_EXPORT __declspec( dllimport )
+#  endif
+#else
+#  define GEOMSELECTIONTOOLS_EXPORT
+#endif
+
+#include "SALOMEDSClient.hxx"
+#include "SALOME_InteractiveObject.hxx"
+#include <SALOME_ListIO.hxx>
+#include <SalomeApp_Application.h>
+
+#include <TopoDS_Shape.hxx>
+#include <GeomAbs_SurfaceType.hxx>
+
+class LightApp_SelectionMgr;
+
+
+/*!
+ * The GeomSelectionTools class gives high level tools to select Geom (and other objects)
+ * A specific attention has been given to analyze selected GEOM objects.
+ *
+ * @param myStudy This class is specific to the study !
+ *
+ */
+
+class GEOMSELECTIONTOOLS_EXPORT GeomSelectionTools
+{
+
+private:
+
+  _PTR(Study) myStudy;
+
+public:
+
+  GeomSelectionTools(_PTR(Study));
+  static SalomeApp_Application*  GetSalomeApplication();
+  static LightApp_SelectionMgr* selectionMgr();
+  SALOME_ListIO* getSelectedSalomeObjects();
+  Handle(SALOME_InteractiveObject) getFirstSelectedSalomeObject();
+  std::string getFirstSelectedEntry();
+  std::string getEntryOfObject(Handle(SALOME_InteractiveObject));
+  std::string getNameFromEntry(std::string);
+  std::string getFirstSelectedComponentDataType();
+  TopAbs_ShapeEnum getFirstSelectedShapeType();
+  TopAbs_ShapeEnum entryToShapeType(std::string );
+  GeomAbs_SurfaceType getFaceInformation(TopoDS_Shape);
+  _PTR(Study) getMyStudy();
+};
+
+//////////////////////////////////////////
+// Utility functions
+//////////////////////////////////////////
+
+namespace PluginUtils
+{
+  GEOMSELECTIONTOOLS_EXPORT QString PrintDoubleValue( double, int = 16 );
+};
+
+#endif // _GEOMSELECTIONTOOLS_H_
+
diff --git a/src/PluginUtils/Makefile.am b/src/PluginUtils/Makefile.am
new file mode 100644 (file)
index 0000000..09c1e13
--- /dev/null
@@ -0,0 +1,61 @@
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# 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.com
+#
+
+# ---
+# File   : Makefile.am
+# Author : Nicolas GEIMER (OCC)
+# ---
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+# header files 
+salomeinclude_HEADERS = \
+       GeomSelectionTools.h
+
+# Libraries targets
+lib_LTLIBRARIES = libGeomSelectionTools.la
+
+dist_libGeomSelectionTools_la_SOURCES =                \
+       GeomSelectionTools.h                    \
+       GeomSelectionTools.cxx
+
+# additionnal information to compil and link file
+libGeomSelectionTools_la_CPPFLAGS =    \
+       $(QT_INCLUDES)                  \
+       $(CAS_CPPFLAGS)                 \
+       $(PYTHON_INCLUDES)              \
+       $(KERNEL_CXXFLAGS)              \
+       $(GUI_CXXFLAGS)                 \
+       $(GEOM_CXXFLAGS)                \
+       $(MED_CXXFLAGS)                 \
+       $(BOOST_CPPFLAGS)               \
+       $(CORBA_CXXFLAGS)               \
+       $(CORBA_INCLUDES)               \
+       -I$(srcdir)/../SMESHGUI         \
+       -I$(top_builddir)/idl
+
+libGeomSelectionTools_la_LDFLAGS =             \
+       ../../idl/libSalomeIDLSMESH.la \
+       ../SMESHGUI/libSMESH.la \
+       $(QT_LIBS) \
+       $(CORBA_LIBS) \
+       $(KERNEL_LDFLAGS) -lSalomeIDLKernel -lSALOMELocalTrace -lSalomeLifeCycleCORBA \
+       $(GUI_LDFLAGS) -lSalomeObject -lsuit -lLightApp -lSalomeApp \
+       $(GEOM_LDFLAGS) -lSalomeIDLGEOM -lGEOMClient \
+       $(CAS_KERNEL) -lTKBRep -lTKG3d
index 9e945244719cbb85a9c0229f6698d678efa3a14f..9afd8d83b9ca1ebfba99383f5257c229c566b5f7 100644 (file)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  SMESH SMDS : implementaion of Salome mesh data structure
 #  File   : Makefile.in
 #  Author : Patrick GOLDBRONN (CEA)
@@ -29,19 +27,26 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am
 
 # header files 
 salomeinclude_HEADERS = \
+    chrono.hxx \
+       ObjectPool.hxx \
        SMDS_TypeOfPosition.hxx \
        SMDSAbs_ElementType.hxx \
        SMDS_EdgePosition.hxx \
        SMDS_ElemIterator.hxx \
        SMDS_FacePosition.hxx \
        SMDS_Mesh.hxx \
+       SMDS_Mesh0DElement.hxx \
+       SMDS_LinearEdge.hxx \
        SMDS_MeshEdge.hxx \
        SMDS_MeshElement.hxx \
+       SMDS_MeshElement.cxx \
        SMDS_MeshElementIDFactory.hxx \
+       SMDS_MeshCell.hxx \
        SMDS_MeshFace.hxx \
        SMDS_MeshGroup.hxx \
        SMDS_MeshIDFactory.hxx \
        SMDS_MeshNode.hxx \
+       SMDS_MeshNodeIDFactory.hxx \
        SMDS_MeshObject.hxx \
        SMDS_MeshVolume.hxx \
        SMDS_Position.hxx \
@@ -51,6 +56,10 @@ salomeinclude_HEADERS = \
        SMDS_IteratorOfElements.hxx \
        SMDS_VolumeOfFaces.hxx \
        SMDS_VolumeOfNodes.hxx \
+       SMDS_VtkEdge.hxx \
+       SMDS_VtkFace.hxx \
+       SMDS_VtkVolume.hxx \
+       SMDS_VtkCellIterator.hxx \
        SMDS_PolyhedralVolumeOfNodes.hxx \
        SMDS_FaceOfEdges.hxx \
        SMDS_FaceOfNodes.hxx \
@@ -61,24 +70,34 @@ salomeinclude_HEADERS = \
        SMDS_QuadraticVolumeOfNodes.hxx \
        SMDS_SetIterator.hxx \
        SMESH_SMDS.hxx \
-       SMDS_MeshInfo.hxx
+       SMDS_MeshInfo.hxx \
+       SMDS_UnstructuredGrid.hxx \
+       SMDS_Downward.hxx \
+       SMDS_StdIterator.hxx \
+       SMDS_IteratorOnIterators.hxx \
+       SMDS_BallElement.hxx
 
 
 # Libraries targets
 
 lib_LTLIBRARIES = libSMDS.la
 dist_libSMDS_la_SOURCES = \
+       chrono.cxx \
        SMDS_MeshObject.cxx \
        SMDS_MeshElement.cxx \
+       SMDS_MeshCell.cxx \
        SMDS_Position.cxx \
        SMDS_EdgePosition.cxx \
        SMDS_FacePosition.cxx \
        SMDS_SpacePosition.cxx \
        SMDS_VertexPosition.cxx \
        SMDS_MeshNode.cxx \
+       SMDS_Mesh0DElement.cxx \
+       SMDS_LinearEdge.cxx \
        SMDS_MeshEdge.cxx \
        SMDS_MeshFace.cxx \
        SMDS_MeshVolume.cxx \
+       SMDS_MeshNodeIDFactory.cxx \
        SMDS_MeshElementIDFactory.cxx \
        SMDS_MeshGroup.cxx \
        SMDS_MeshIDFactory.cxx \
@@ -86,6 +105,10 @@ dist_libSMDS_la_SOURCES = \
        SMDS_IteratorOfElements.cxx \
        SMDS_VolumeOfFaces.cxx \
        SMDS_VolumeOfNodes.cxx \
+       SMDS_VtkEdge.cxx \
+       SMDS_VtkFace.cxx \
+       SMDS_VtkVolume.cxx \
+       SMDS_VtkCellIterator.cxx \
        SMDS_PolyhedralVolumeOfNodes.cxx \
        SMDS_FaceOfEdges.cxx \
        SMDS_FaceOfNodes.cxx \
@@ -93,22 +116,22 @@ dist_libSMDS_la_SOURCES = \
        SMDS_VolumeTool.cxx \
        SMDS_QuadraticEdge.cxx \
        SMDS_QuadraticFaceOfNodes.cxx \
-       SMDS_QuadraticVolumeOfNodes.cxx
+       SMDS_QuadraticVolumeOfNodes.cxx \
+       SMDS_UnstructuredGrid.cxx \
+       SMDS_Downward.cxx \
+       SMDS_BallElement.cxx
 
 # additionnal information to compil and link file
 libSMDS_la_CPPFLAGS = \
        $(KERNEL_CXXFLAGS) \
-       $(CAS_CPPFLAGS) \
+        $(VTK_INCLUDES) \
        $(BOOST_CPPFLAGS)
 
 libSMDS_la_LDFLAGS  = \
-       $(KERNEL_LDFLAGS) -lSALOMELocalTrace \
-       $(CAS_KERNEL)
+       $(VTK_LIBS) \
+       $(KERNEL_LDFLAGS) -lSALOMELocalTrace -lOpUtil
 
 # Executables targets
 bin_PROGRAMS = SMDS_MemoryLimit
 dist_SMDS_MemoryLimit_SOURCES = \
        SMDS_MemoryLimit.cxx
-
-SMDS_MemoryLimit_LDADD = \
-       $(KERNEL_LDFLAGS) -lSALOMELocalTrace
diff --git a/src/SMDS/Notes b/src/SMDS/Notes
new file mode 100644 (file)
index 0000000..830ffb5
--- /dev/null
@@ -0,0 +1,235 @@
+--> Branche V6_main
+
+Problemes en cours
+==================
+- a faire
++ en cours, OK mais perfectible
+* OK
+
++ visualisation de groupe (type d'element): on voit tout le maillage, mais le groupe est OK
+  creation d'une structure vtkUnstructuredGrid locale : iteration un peu lourde, et pas de partage avec la structure du maillage (pas evident)
+- inversion d'un volume (tetra): exception
+- script de creation de noeuds et d'elements: OK, mais pas compatible avec version precedente (numerotation noeuds differente)
++ affichage numeros noeuds: numeros en trop sur (O,0,0) pas systematique, trouver la condition (enlever dans vtkUnstructuredGrid ?)
+  ==> purge systematique noeuds et cellules en trop dans compactage grid.
++ gestion du mode embedded mal faite lors d'un script python : journal commandes intempestif
+- affichage des noeuds apres changement lineaire <--> quadratique Ã  l'IHM : pas pris en compte, alors que maillage OK,
+  mais script OK
+  ==> cassé apres mode embedded ou elimination noeuds en trop ?
+- extrusion elements 2D along a path : affichage apres calcul pas toujours OK (filaire)
+- branche git a ouvrir pour merge avec V5_1_4_BR tag V5_1_4rc1
+
+A tester, non pris en compte
+============================
+- engine standalone
+- polyedres (attendre vtk)
+
+
+=============================== Hypothese de refonte de l'API de SMDS
+
+n'utiliser que vtkUnstructuredGrid, ne pas avor d'objets SMDS_MeshElement mais seulement des index de vtkUnstructuredGrid.
+2987 usages de SMDS_MeshNodes
+810            SMDS_MeshElement
+...
+==> en dernier ressort, lourd
+================================================================================
+
+Essai a API SMDS a peu pres constante
+=====================================
+
+SMDS_Mesh
+  static vector<SMDS_Mesh*> _meshList;     --> retrouver un SMDS_Mesh
+  vtkUnstructuredGrid*      myGrid;
+
+  vector<SMDS_MeshNode *>   myNodes;       --> meme index que dans le pointSet de myGrid
+  vector<SMDS_MeshCell *>   myCells;       --> index = ID client, pas le meme index que dans le cellTypes de myGrid (ID vtk)
+
+
+
+SMDS_MeshElement
+  int myID;                                --> index dans la structure geree par SMDS_Mesh
+  int myMeshId;                            --> pour retrouver SMDS_Mesh* dans _meshList
+  int myShapeId;                           --> pour retrouver la subShape
+                                                         
+
+SMDS_MeshNode: SMDS_MeshElement
+  SMDS_PositionPtr myPosition;             -->  A REVOIR : objet position dans la shape geom
+  ##vector<int> myInverseElements;         -->  SUPPRIME : pour retrouver les elements, vtkCellLinks
+
+
+SMDS_MeshCell: SMDS_MeshElement            --> generique pour tous les elements (cells)
+  int myVtkID                              --> A SUPPRIMER
+
+SMDS_MeshVolume: SMDS_MeshCell
+
+SMDS_VolumeOfNodes: SMDS_MeshVolume        --> Garder temporairement, utilisation dans StdMesher et SMDS_VolumeTool
+  const SMDS_MeshNode **myNodes;           --> Couteux
+  int                 myNbNodes;           -->  ""
+
+SMDS_VolumeVtkNodes: SMDS_MeshVolume       --> Utiliser systematiquement dans SMDS,
+                                           --> IMPLEMENTER.
+
+
+SMDS_MeshElementIDFactory: SMDS_MeshNodeIDFactory
+  vector<int> myIDElements; // index = ID client, value = ID vtk  --> A SUPPRIMER, ne sert que dans SMDS_MeshElementIDFactory
+  vector<int> myVtkIndex;   // index = ID vtk, value = ID client  --> A REPORTER dans SMDS_Mesh
+
+
+
+
+========= TODO ============
+
+enlever vtkId de SMDS_MeshCell, utiliser SMDS_MeshElementIDFactory.
+
+ajouter ID dans SMDS_Mesh::createTriangle 
+verifier ID dans SMDS_Mesh::Find*OrCreate
+
+===================================================
+occupation memoire cube 100*100*100 sans affichage
+NOTES:
+- sur Debian Sarge 64 bits, les mesures malloc_stat() semblent coherentes
+  avec une mesure externe globale(recherche du passage en swap du process).
+- sur Ubuntu 9.10 64 bits, les mesures malloc_stat() donnent des resultats bizarres (surestimation ?),
+  mais la mesure avec l'outil KDE de surveillance systeme est OK avec la recherche du swap.
+
+
+Reference : V513 Debian Sarge 64 bits: --> 463 - 33 = 430 Mo
+-------------------------------------
+Total (incl. mmap):
+system bytes     =   43757568
+in use bytes     =   32909584 = 33M
+max mmap regions =         41
+max mmap bytes   =   16371712
+----
+Total (incl. mmap):
+system bytes     =  464670720
+in use bytes     =  463105120 = 463M
+max mmap regions =         47
+max mmap bytes   =   28188672
+
+Debian Sarge 64 bits, vtkUnstructuredGrid nodes et hexa, 4 janvier 2010 --> 512 - 41 = 471M
+-----------------------------------
+
+Total (incl. mmap):
+system bytes     =   52133888
+in use bytes     =   41340320 : 41M
+max mmap regions =         72
+max mmap bytes   =   24625152
+----
+Total (incl. mmap):
+system bytes     =  520560640
+in use bytes     =  518735584 : 512M
+max mmap regions =         88
+max mmap bytes   =  198385664
+
+idem avec pool SMDS_MeshNodes --> 483 -33 = 450M
+-----------------------------
+Total (incl. mmap):
+system bytes     =   43696128
+in use bytes     =   32915184 : 33M 
+max mmap regions =         41
+max mmap bytes   =   16371712
+----
+Total (incl. mmap):
+system bytes     =  484806656
+in use bytes     =  482980992 : 483M
+max mmap regions =         58
+max mmap bytes   =  184557568
+
+idem ci-dessus + pool SMDS_VolumeVtkNodes --> 475 -33 = 442M (git: add ObjectPool.hxx)
+-----------------------------------------
+
+Total (incl. mmap):
+system bytes     =   43200512
+in use bytes     =   32908576 : 33M
+max mmap regions =         41
+max mmap bytes   =   16371712
+----
+Total (incl. mmap):
+system bytes     =  478068736
+in use bytes     =  475144400 : 475M
+max mmap regions =         59
+max mmap bytes   =  184692736
+
+remplacement SMDS_PositionPtr: (boost::shared_ptr<SMDS_Position> --> SMDS_Position*) --> 436 - 35 = 401M (git SMDS_Position)
+------------------------------------------------------------------------------------
+Total (incl. mmap):
+system bytes     =   45408256
+in use bytes     =   35097680 : 35M
+max mmap regions =         47
+max mmap bytes   =   18116608
+----
+Total (incl. mmap):
+system bytes     =  438935552
+in use bytes     =  436116560 : 436M
+max mmap regions =         65
+max mmap bytes   =  186437632
+
+simplification SMDS_SpacePosition (pas de double[3]) --> 418 -33 = 385M (git SMDS_SpacePosition)
+----------------------------------------------------
+Total (incl. mmap):
+system bytes     =   42582016
+in use bytes     =   32883552 : 33M
+max mmap regions =         41
+max mmap bytes   =   16371712
+----
+Total (incl. mmap):
+system bytes     =  421728256
+in use bytes     =  418378000 : 418M
+max mmap regions =         58
+max mmap bytes   =  183640064
+
+sizeof(SMDS_MeshElement) 16
+sizeof(SMDS_MeshNode) 24
+sizeof(SMDS_MeshCell) 24
+sizeof(SMDS_VolumeVtkNodes) 24
+sizeof(SMDS_Position) 16
+sizeof(SMDS_SpacePosition) 16
+
+impact d'un int en plus dans SMDS_MeshElement --> 426 - 33 = 393M
+---------------------------------------------
+
+sizeof(SMDS_MeshElement) 24
+sizeof(SMDS_MeshNode) 32       --> on retrouve bien les 8M
+sizeof(SMDS_MeshCell) 24
+sizeof(SMDS_VolumeVtkNodes) 24
+sizeof(SMDS_Position) 16
+sizeof(SMDS_SpacePosition) 16
+
+Total (incl. mmap):
+system bytes     =   43192320
+in use bytes     =   32681088 : 33M
+max mmap regions =         41
+max mmap bytes   =   16371712
+----
+Total (incl. mmap):
+system bytes     =  429334528
+in use bytes     =  426424576 : 426M
+max mmap regions =         59
+max mmap bytes   =  184692736
+
+remplacement std::set par std::vector dans SMESHDS_SubMesh --> 347 - 35 = 312M
+----------------------------------------------------------
+sizeof(SMDS_MeshElement) 24
+sizeof(SMDS_MeshNode) 32
+sizeof(SMDS_MeshCell) 24
+sizeof(SMDS_VolumeVtkNodes) 24
+sizeof(SMDS_Position) 16
+sizeof(SMDS_SpacePosition) 16
+
+Total (incl. mmap):
+system bytes     =   45404160
+in use bytes     =   35132160 --> 35M
+max mmap regions =         49
+max mmap bytes   =   17723392
+----
+Total (incl. mmap):
+system bytes     =  349831168
+in use bytes     =  346885424 --> 347M
+max mmap regions =         73
+max mmap bytes   =  204148736
+
+Ce resultat est coherent avec une recherche de swap sur une machine a 8Go de memoire:
+Cube a 270**3 mailles (~20M mailles) --> 6.2 Go (idem Debian Sarge et Ubuntu 9.10, 64 bits)
+Le meme avec V5.1.3 --> 14 Go (swap)
+
diff --git a/src/SMDS/ObjectPool.hxx b/src/SMDS/ObjectPool.hxx
new file mode 100644 (file)
index 0000000..1ee3710
--- /dev/null
@@ -0,0 +1,134 @@
+// Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+#ifndef _OBJECTPOOL_HXX_
+#define _OBJECTPOOL_HXX_
+
+#include <vector>
+#include <stack>
+#include <iostream>
+
+template<class X> class ObjectPool
+{
+
+private:
+  std::vector<X*> _chunkList;
+  std::vector<bool> _freeList;
+  int _nextFree;
+  int _maxAvail;
+  int _chunkSize;
+
+  int getNextFree()
+  {
+    for (int i = _nextFree; i < _maxAvail; i++)
+      if (_freeList[i] == true)
+        {
+          return i;
+          break;
+        }
+    return _maxAvail;
+  }
+
+  void checkDelete(int chunkId)
+  {
+    int i0 = _chunkSize * chunkId;
+    int i1 = _chunkSize * (chunkId + 1);
+    for (int i = i0; i < i1; i++)
+      if (_freeList[i] == false)
+        return;
+    std::cerr << "a chunk to delete" << std::endl;
+    // compactage des vecteurs un peu lourd, pas necessaire
+    //X* chunk = _chunkList[chunkId];
+    //delete [] chunk;
+  }
+
+public:
+  ObjectPool(int nblk)
+  {
+    _chunkSize = nblk;
+    _nextFree = 0;
+    _maxAvail = 0;
+    _chunkList.clear();
+    _freeList.clear();
+  }
+
+  virtual ~ObjectPool()
+  {
+    for (int i = 0; i < _chunkList.size(); i++)
+      delete[] _chunkList[i];
+  }
+
+  X* getNew()
+  {
+    X *obj = 0;
+    _nextFree = getNextFree();
+    if (_nextFree == _maxAvail)
+      {
+        X* newChunk = new X[_chunkSize];
+        _chunkList.push_back(newChunk);
+        _freeList.insert(_freeList.end(), _chunkSize, true);
+        _maxAvail += _chunkSize;
+        _freeList[_nextFree] = false;
+        obj = newChunk; // &newChunk[0];
+      }
+    else
+      {
+        int chunkId = _nextFree / _chunkSize;
+        int rank = _nextFree - chunkId * _chunkSize;
+        _freeList[_nextFree] = false;
+        obj = _chunkList[chunkId] + rank; // &_chunkList[chunkId][rank];
+      }
+    //obj->init();
+    return obj;
+  }
+
+  void destroy(X* obj)
+  {
+    long adrobj = (long) (obj);
+    for (int i = 0; i < _chunkList.size(); i++)
+      {
+        X* chunk = _chunkList[i];
+        long adrmin = (long) (chunk);
+        if (adrobj < adrmin)
+          continue;
+        long adrmax = (long) (chunk + _chunkSize);
+        if (adrobj >= adrmax)
+          continue;
+        int rank = (adrobj - adrmin) / sizeof(X);
+        int toFree = i * _chunkSize + rank;
+        _freeList[toFree] = true;
+        if (toFree < _nextFree)
+          _nextFree = toFree;
+        //obj->clean();
+        //checkDelete(i); compactage non fait
+        break;
+      }
+  }
+
+  //  void destroy(int toFree)
+  //  {
+  //    // no control 0<= toFree < _freeList.size()
+  //    _freeList[toFree] = true;
+  //    if (toFree < _nextFree)
+  //      _nextFree = toFree;
+  //  }
+
+};
+
+#endif
index a76772e3f05b483433ba6b233be2013dd2a0fd89..e66bbff09497b844b1ab2051919bd74f67f056df 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDSAbs_ElementType.hxx
 //  Module : SMESH
 /// Type (node, edge, face or volume) of elements
 ///////////////////////////////////////////////////////////////////////////////
 enum SMDSAbs_ElementType
-{
-       SMDSAbs_All,
-       SMDSAbs_Node,
-       SMDSAbs_Edge,
-       SMDSAbs_Face,
-       SMDSAbs_Volume,
-        SMDSAbs_NbElementTypes
-};
+  {
+    SMDSAbs_All,
+    SMDSAbs_Node,
+    SMDSAbs_Edge,
+    SMDSAbs_Face,
+    SMDSAbs_Volume,
+    SMDSAbs_0DElement,
+    SMDSAbs_Ball,
+    SMDSAbs_NbElementTypes
+  };
 
 /*! enumeration for element geometry type */
 enum SMDSAbs_GeometryType
-{
-  // 0D element
-  SMDSGeom_POINT,
-  // 1D element
-  SMDSGeom_EDGE,
-  // 2D element
-  SMDSGeom_TRIANGLE,
-  SMDSGeom_QUADRANGLE,
-  SMDSGeom_POLYGON,
-  // 3D element
-  SMDSGeom_TETRA,
-  SMDSGeom_PYRAMID,
-  SMDSGeom_PENTA,
-  SMDSGeom_HEXA,
-  SMDSGeom_POLYHEDRA,
-};
+  {
+    // 0D element
+    SMDSGeom_POINT,
+    // 1D element
+    SMDSGeom_EDGE,
+    // 2D element
+    SMDSGeom_TRIANGLE,
+    SMDSGeom_QUADRANGLE,
+    SMDSGeom_POLYGON,
+    // 3D element
+    SMDSGeom_TETRA,
+    SMDSGeom_PYRAMID,
+    SMDSGeom_HEXA,
+    SMDSGeom_PENTA,
+    SMDSGeom_HEXAGONAL_PRISM,
+    SMDSGeom_POLYHEDRA,
+    // Discrete elements
+    SMDSGeom_BALL,
+    //
+    SMDSGeom_NONE
+  };
 
 
 enum SMDSAbs_ElementOrder {
@@ -65,4 +73,36 @@ enum SMDSAbs_ElementOrder {
   ORDER_QUADRATIC     /*! entities of 2nd order */
 };
 
+/*!
+ * Enumeration of entity type uses in mesh info array,
+ *  and should be synchronised with enum in SMDS  
+ */
+enum SMDSAbs_EntityType {
+  SMDSEntity_Node,
+  SMDSEntity_0D,
+  SMDSEntity_Edge,
+  SMDSEntity_Quad_Edge,
+  SMDSEntity_Triangle,
+  SMDSEntity_Quad_Triangle,
+  SMDSEntity_Quadrangle,
+  SMDSEntity_Quad_Quadrangle,
+  SMDSEntity_BiQuad_Quadrangle,
+  SMDSEntity_Polygon,
+  SMDSEntity_Quad_Polygon,
+  SMDSEntity_Tetra,
+  SMDSEntity_Quad_Tetra,
+  SMDSEntity_Pyramid,
+  SMDSEntity_Quad_Pyramid,
+  SMDSEntity_Hexa,
+  SMDSEntity_Quad_Hexa,
+  SMDSEntity_TriQuad_Hexa,
+  SMDSEntity_Penta,
+  SMDSEntity_Quad_Penta,
+  SMDSEntity_Hexagonal_Prism,
+  SMDSEntity_Polyhedra,
+  SMDSEntity_Quad_Polyhedra,
+  SMDSEntity_Ball,
+  SMDSEntity_Last
+};
+
 #endif
diff --git a/src/SMDS/SMDS_BallElement.cxx b/src/SMDS/SMDS_BallElement.cxx
new file mode 100644 (file)
index 0000000..9595e98
--- /dev/null
@@ -0,0 +1,102 @@
+// Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+//  SMESH SMDS : implementaion of Salome mesh data structure
+//  Module     : SMESH
+//  File       : SMDS_BallElement.cxx
+//  Author     : Edward AGAPOV (eap)
+
+#include "SMDS_BallElement.hxx"
+
+#include "SMDS_ElemIterator.hxx"
+#include "SMDS_Mesh.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_VtkCellIterator.hxx"
+
+SMDS_BallElement::SMDS_BallElement()
+{
+  SMDS_MeshCell::init();
+}
+
+SMDS_BallElement::SMDS_BallElement (const SMDS_MeshNode * node, double diameter)
+{
+  init( node->getVtkId(), diameter, SMDS_Mesh::_meshList[ node->getMeshId() ] );
+}
+
+SMDS_BallElement::SMDS_BallElement(vtkIdType nodeId, double diameter, SMDS_Mesh* mesh)
+{
+  init( nodeId, diameter, mesh );
+}
+
+void SMDS_BallElement::init(vtkIdType nodeId, double diameter, SMDS_Mesh* mesh)
+{
+  SMDS_MeshCell::init();
+  SMDS_UnstructuredGrid* grid = mesh->getGrid();
+  myVtkID = grid->InsertNextLinkedCell( GetVtkType(), 1, &nodeId );
+  myMeshId = mesh->getMeshId();
+  grid->SetBallDiameter( myVtkID, diameter );
+  mesh->setMyModified();
+}
+
+double SMDS_BallElement::GetDiameter() const
+{
+  return SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetBallDiameter( myVtkID );
+}
+
+void SMDS_BallElement::SetDiameter(double diameter)
+{
+  SMDS_Mesh::_meshList[myMeshId]->getGrid()->SetBallDiameter( myVtkID, diameter );
+}
+
+bool SMDS_BallElement::ChangeNode (const SMDS_MeshNode * node)
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType npts = 0;
+  vtkIdType* pts = 0;
+  grid->GetCellPoints(myVtkID, npts, pts);
+  pts[0] = node->getVtkId();
+  SMDS_Mesh::_meshList[myMeshId]->setMyModified();
+  return true;
+}
+
+void SMDS_BallElement::Print (std::ostream & OS) const
+{
+  OS << "ball<" << GetID() << "> : ";
+}
+
+const SMDS_MeshNode* SMDS_BallElement::GetNode (const int ind) const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType npts, *pts;
+  grid->GetCellPoints( myVtkID, npts, pts );
+  return SMDS_Mesh::_meshList[myMeshId]->FindNodeVtk( pts[ 0 ]);
+}
+
+SMDS_ElemIteratorPtr SMDS_BallElement::elementsIterator (SMDSAbs_ElementType type) const
+{
+  switch (type)
+  {
+    case SMDSAbs_Node:
+      return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
+    default:
+      ;
+      return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL);
+  }
+}
+
diff --git a/src/SMDS/SMDS_BallElement.hxx b/src/SMDS/SMDS_BallElement.hxx
new file mode 100644 (file)
index 0000000..c8ead2a
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+//  SMESH SMDS : implementaion of Salome mesh data structure
+//  File   : SMDS_BallElement.hxx
+//  Module : SMESH
+//
+#ifndef _SMDS_BallElement_HeaderFile
+#define _SMDS_BallElement_HeaderFile
+
+#include "SMESH_SMDS.hxx"
+#include "SMDS_MeshCell.hxx"
+
+#include <iostream>
+
+class SMDS_EXPORT SMDS_BallElement: public SMDS_MeshCell
+{
+ public:
+  SMDS_BallElement();
+  SMDS_BallElement (const SMDS_MeshNode * node, double diameter);
+  SMDS_BallElement(vtkIdType nodeId, double diameter, SMDS_Mesh* mesh);
+  void init(vtkIdType nodeId, double diameter, SMDS_Mesh* mesh);
+  double GetDiameter() const;
+  void SetDiameter(double diameter);
+  bool ChangeNode (const SMDS_MeshNode * node);
+
+  virtual bool ChangeNodes(const SMDS_MeshNode* nodes[],
+                           const int            nbNodes) { return ChangeNode( nodes[0] ); }
+  virtual void Print (std::ostream & OS) const;
+
+  virtual SMDSAbs_ElementType  GetType()       const { return SMDSAbs_Ball; }
+  virtual vtkIdType            GetVtkType()    const { return VTK_POLY_VERTEX; }
+  virtual SMDSAbs_EntityType   GetEntityType() const { return SMDSEntity_Ball; }
+  virtual SMDSAbs_GeometryType GetGeomType()   const { return SMDSGeom_BALL; }
+  virtual int NbNodes() const { return 1; }
+  virtual int NbEdges() const { return 0; }
+  virtual int NbFaces() const { return 0; }
+  virtual const SMDS_MeshNode* GetNode (const int ind) const;
+
+ protected:
+  SMDS_ElemIteratorPtr elementsIterator (SMDSAbs_ElementType type) const;
+};
+
+#endif
diff --git a/src/SMDS/SMDS_Downward.cxx b/src/SMDS/SMDS_Downward.cxx
new file mode 100644 (file)
index 0000000..67ff05f
--- /dev/null
@@ -0,0 +1,2235 @@
+// Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+// File: SMDS_Downward.cxx
+// Created: Jun 3, 2010
+// Author: prascle
+
+#include "SMDS_Downward.hxx"
+#include "SMDS_Mesh.hxx"
+#include "utilities.h"
+
+#include <vtkCellType.h>
+#include <vtkCellLinks.h>
+
+#include <map>
+
+using namespace std;
+
+// ---------------------------------------------------------------------------
+
+vector<int> SMDS_Downward::_cellDimension;
+
+/*! get the dimension of a cell (1,2,3 for 1D, 2D 3D) given the vtk cell type
+ *
+ * @param cellType vtk cell type @see vtkCellType.h
+ * @return 1,2 or 3
+ */
+int SMDS_Downward::getCellDimension(unsigned char cellType)
+{
+  if (_cellDimension.empty())
+    {
+      _cellDimension.resize(VTK_MAXTYPE + 1, 0);
+      _cellDimension[VTK_LINE] = 1;
+      _cellDimension[VTK_QUADRATIC_EDGE] = 1;
+      _cellDimension[VTK_TRIANGLE] = 2;
+      _cellDimension[VTK_QUADRATIC_TRIANGLE] = 2;
+      _cellDimension[VTK_QUAD] = 2;
+      _cellDimension[VTK_QUADRATIC_QUAD] = 2;
+      _cellDimension[VTK_BIQUADRATIC_QUAD] = 2;
+      _cellDimension[VTK_TETRA] = 3;
+      _cellDimension[VTK_QUADRATIC_TETRA] = 3;
+      _cellDimension[VTK_HEXAHEDRON] = 3;
+      _cellDimension[VTK_QUADRATIC_HEXAHEDRON] = 3;
+      _cellDimension[VTK_TRIQUADRATIC_HEXAHEDRON] = 3;
+      _cellDimension[VTK_WEDGE] = 3;
+      _cellDimension[VTK_QUADRATIC_WEDGE] = 3;
+      _cellDimension[VTK_PYRAMID] = 3;
+      _cellDimension[VTK_QUADRATIC_PYRAMID] = 3;
+      _cellDimension[VTK_HEXAGONAL_PRISM] = 3;
+    }
+  return _cellDimension[cellType];
+}
+
+// ---------------------------------------------------------------------------
+
+/*! Generic constructor for all the downward connectivity structures (one per vtk cell type).
+ *  The static structure for cell dimension is set only once.
+ * @param grid unstructured grid associated to the mesh.
+ * @param nbDownCells number of downward entities associated to this vtk type of cell.
+ * @return
+ */
+SMDS_Downward::SMDS_Downward(SMDS_UnstructuredGrid *grid, int nbDownCells) :
+  _grid(grid), _nbDownCells(nbDownCells)
+{
+  this->_maxId = 0;
+  this->_cellIds.clear();
+  this->_cellTypes.clear();
+  if (_cellDimension.empty())
+    getCellDimension( VTK_LINE );
+}
+
+SMDS_Downward::~SMDS_Downward()
+{
+}
+
+/*! Give or create an entry for downward connectivity structure relative to a cell.
+ * If the entry already exists, just return its id, otherwise, create it.
+ * The internal storage memory is allocated if needed.
+ * The SMDS_UnstructuredGrid::_cellIdToDownId vector is completed for vtkUnstructuredGrid cells.
+ * @param vtkId for a vtkUnstructuredGrid cell  or -1 (default) for a created downward cell.
+ * @return the rank in downward[vtkType] structure.
+ */
+int SMDS_Downward::addCell(int vtkId)
+{
+  int localId = -1;
+  if (vtkId >= 0)
+    localId = _grid->CellIdToDownId(vtkId);
+  if (localId >= 0)
+    return localId;
+
+  localId = this->_maxId;
+  this->_maxId++;
+  this->allocate(_maxId);
+  if (vtkId >= 0)
+    {
+      this->_vtkCellIds[localId] = vtkId;
+      _grid->setCellIdToDownId(vtkId, localId);
+    }
+  this->initCell(localId);
+  return localId;
+}
+
+/*! generic method do nothing. see derived methods
+ *
+ * @param cellId
+ */
+void SMDS_Downward::initCell(int cellId)
+{
+}
+
+/*! Get the number of downward entities associated to a cell (always the same for a given vtk type of cell)
+ *
+ * @param cellId not used here.
+ * @return
+ */
+int SMDS_Downward::getNumberOfDownCells(int cellId)
+{
+  return _nbDownCells;
+}
+
+/*! get a pointer on the downward entities id's associated to a cell.
+ * @see SMDS_Downward::getNumberOfDownCells for the number of downward entities.
+ * @see SMDS_Downward::getDownTypes for the vtk cell types associated to the downward entities.
+ * @param cellId index of the cell in the downward structure relative to a given vtk cell type.
+ * @return table of downward entities id's.
+ */
+const int* SMDS_Downward::getDownCells(int cellId)
+{
+  //ASSERT((cellId >=0) && (cellId < _maxId));
+  return &_cellIds[_nbDownCells * cellId];
+}
+
+/*! get a list of vtk cell types associated to downward entities of a given cell, in the same order
+ * than the downward entities id's list (@see SMDS_Downward::getDownCells).
+ *
+ * @param cellId index of the cell in the downward structure relative to a vtk cell type.
+ * @return table of downward entities types.
+ */
+const unsigned char* SMDS_Downward::getDownTypes(int cellId)
+{
+  return &_cellTypes[0];
+}
+
+/*! add a downward entity of dimension n-1 (cell or node) to a given cell.
+ * Actual implementation is done in derived methods.
+ * @param cellId index of the parent cell (dimension n) in the downward structure relative to a vtk cell type.
+ * @param lowCellId index of the children cell to add (dimension n-1)
+ * @param aType vtk cell type of the cell to add (needed to find the SMDS_Downward structure containing the cell to add).
+ */
+void SMDS_Downward::addDownCell(int cellId, int lowCellId, unsigned char aType)
+{
+  ASSERT(0); // must be re-implemented in derived class
+}
+
+/*! add a downward entity of dimension n+1 to a given cell.
+ * Actual implementation is done in derived methods.
+ * @param cellId index of the children cell (dimension n) in the downward structure relative to a vtk cell type.
+ * @param upCellId index of the parent cell to add (dimension n+1)
+ * @param aType vtk cell type of the cell to add (needed to find the SMDS_Downward structure containing the cell to add).
+ */
+void SMDS_Downward::addUpCell(int cellId, int upCellId, unsigned char aType)
+{
+  ASSERT(0); // must be re-implemented in derived class
+}
+
+int SMDS_Downward::getNodeSet(int cellId, int* nodeSet)
+{
+  return 0;
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_Down1D::SMDS_Down1D(SMDS_UnstructuredGrid *grid, int nbDownCells) :
+  SMDS_Downward(grid, nbDownCells)
+{
+  _upCellIdsVector.clear();
+  _upCellTypesVector.clear();
+  _upCellIds.clear();
+  _upCellTypes.clear();
+  _upCellIndex.clear();
+}
+
+SMDS_Down1D::~SMDS_Down1D()
+{
+}
+
+/*! clear vectors used to reference 2D cells containing the edge
+ *
+ * @param cellId
+ */
+void SMDS_Down1D::initCell(int cellId)
+{
+  _upCellIdsVector[cellId].clear();
+  _upCellTypesVector[cellId].clear();
+}
+
+/*! Resize the downward connectivity storage vector if needed.
+ *
+ * @param nbElems total number of elements of the same type required
+ */
+void SMDS_Down1D::allocate(int nbElems)
+{
+  if (nbElems >= _vtkCellIds.size())
+    {
+      _vtkCellIds.resize(nbElems + SMDS_Mesh::chunkSize, -1);
+      _cellIds.resize(_nbDownCells * (nbElems + SMDS_Mesh::chunkSize), -1);
+      _upCellIdsVector.resize(nbElems + SMDS_Mesh::chunkSize);
+      _upCellTypesVector.resize(nbElems + SMDS_Mesh::chunkSize);
+    }
+}
+
+void SMDS_Down1D::compactStorage()
+{
+  _cellIds.resize(_nbDownCells * _maxId);
+  _vtkCellIds.resize(_maxId);
+
+  int sizeUpCells = 0;
+  for (int i = 0; i < _maxId; i++)
+    sizeUpCells += _upCellIdsVector[i].size();
+  _upCellIds.resize(sizeUpCells, -1);
+  _upCellTypes.resize(sizeUpCells);
+  _upCellIndex.resize(_maxId + 1, -1); // id and types of rank i correspond to [ _upCellIndex[i], _upCellIndex[i+1] [
+  int current = 0;
+  for (int i = 0; i < _maxId; i++)
+    {
+      _upCellIndex[i] = current;
+      for (int j = 0; j < _upCellIdsVector[i].size(); j++)
+        {
+          _upCellIds[current] = _upCellIdsVector[i][j];
+          _upCellTypes[current] = _upCellTypesVector[i][j];
+          current++;
+        }
+    }
+  _upCellIndex[_maxId] = current;
+
+  _upCellIdsVector.clear();
+  _upCellTypesVector.clear();
+}
+
+void SMDS_Down1D::addUpCell(int cellId, int upCellId, unsigned char aType)
+{
+  //ASSERT((cellId >=0) && (cellId < _maxId));
+  int nbFaces = _upCellIdsVector[cellId].size();
+  for (int i = 0; i < nbFaces; i++)
+    {
+      if ((_upCellIdsVector[cellId][i] == upCellId) && (_upCellTypesVector[cellId][i] == aType))
+        {
+          return; // already done
+        }
+    }
+  _upCellIdsVector[cellId].push_back(upCellId);
+  _upCellTypesVector[cellId].push_back(aType);
+}
+
+int SMDS_Down1D::getNumberOfUpCells(int cellId)
+{
+  //ASSERT((cellId >=0) && (cellId < _maxId));
+  return _upCellIndex[cellId + 1] - _upCellIndex[cellId];
+}
+
+const int* SMDS_Down1D::getUpCells(int cellId)
+{
+  //ASSERT((cellId >=0) && (cellId < _maxId));
+  return &_upCellIds[_upCellIndex[cellId]];
+}
+
+const unsigned char* SMDS_Down1D::getUpTypes(int cellId)
+{
+  //ASSERT((cellId >=0) && (cellId < _maxId));
+  return &_upCellTypes[_upCellIndex[cellId]];
+}
+
+void SMDS_Down1D::getNodeIds(int cellId, std::set<int>& nodeSet)
+{
+  for (int i = 0; i < _nbDownCells; i++)
+    nodeSet.insert(_cellIds[_nbDownCells * cellId + i]);
+}
+
+int SMDS_Down1D::getNodeSet(int cellId, int* nodeSet)
+{
+  for (int i = 0; i < _nbDownCells; i++)
+    nodeSet[i] = _cellIds[_nbDownCells * cellId + i];
+  return _nbDownCells;
+}
+
+void SMDS_Down1D::setNodes(int cellId, int vtkId)
+{
+  vtkIdType npts = 0;
+  vtkIdType *pts; // will refer to the point id's of the face
+  _grid->GetCellPoints(vtkId, npts, pts);
+  // MESSAGE(vtkId << " " << npts << "  " << _nbDownCells);
+  //ASSERT(npts == _nbDownCells);
+  for (int i = 0; i < npts; i++)
+    {
+      _cellIds[_nbDownCells * cellId + i] = pts[i];
+    }
+}
+
+void SMDS_Down1D::setNodes(int cellId, const int* nodeIds)
+{
+  //ASSERT(nodeIds.size() == _nbDownCells);
+  for (int i = 0; i < _nbDownCells; i++)
+    {
+      _cellIds[_nbDownCells * cellId + i] = nodeIds[i];
+    }
+}
+
+/*! Build the list of vtkUnstructuredGrid cells containing the edge.
+ * We keep in the list the cells that contains all the nodes, we keep only volumes and faces.
+ * @param cellId id of the edge in the downward structure
+ * @param vtkIds vector of vtk id's
+ * @return number of vtk cells (size of vector)
+ */
+int SMDS_Down1D::computeVtkCells(int cellId, std::vector<int>& vtkIds)
+{
+  vtkIds.clear();
+
+  // --- find all the cells the points belong to, and how many of the points belong to a given cell
+
+  int *pts = &_cellIds[_nbDownCells * cellId];
+  int ncells = this->computeVtkCells(pts, vtkIds);
+  return ncells;
+}
+
+/*! Build the list of vtkUnstructuredGrid cells containing the edge.
+ *
+ * @param pts list of points id's defining an edge
+ * @param vtkIds vector of vtk id's
+ * @return number of vtk cells (size of vector)
+ */
+int SMDS_Down1D::computeVtkCells(int *pts, std::vector<int>& vtkIds)
+{
+
+  // --- find all the cells the points belong to, and how many of the points belong to a given cell
+
+  int cellIds[1000];
+  int cellCnt[1000];
+  int cnt = 0;
+  for (int i = 0; i < _nbDownCells; i++)
+    {
+      vtkIdType point = pts[i];
+      int numCells = _grid->GetLinks()->GetNcells(point);
+      vtkIdType *cells = _grid->GetLinks()->GetCells(point);
+      for (int j = 0; j < numCells; j++)
+        {
+          int vtkCellId = cells[j];
+          bool found = false;
+          for (int k = 0; k < cnt; k++)
+            {
+              if (cellIds[k] == vtkCellId)
+                {
+                  cellCnt[k] += 1;
+                  found = true;
+                  break;
+                }
+            }
+          if (!found)
+            {
+              cellIds[cnt] = vtkCellId;
+              cellCnt[cnt] = 1;
+              // TODO ASSERT(cnt<1000);
+              cnt++;
+            }
+        }
+    }
+
+  // --- find the face and volume cells: they contains all the points and are of type volume or face
+
+  int ncells = 0;
+  for (int i = 0; i < cnt; i++)
+    {
+      if (cellCnt[i] == _nbDownCells)
+        {
+          int vtkElemId = cellIds[i];
+          int vtkType = _grid->GetCellType(vtkElemId);
+          if (SMDS_Downward::getCellDimension(vtkType) > 1)
+            {
+              vtkIds.push_back(vtkElemId);
+              ncells++;
+            }
+        }
+    }
+
+  return ncells;
+}
+
+/*! Build the list of downward faces from a list of vtk cells.
+ *
+ * @param cellId id of the edge in the downward structure
+ * @param vtkIds vector of vtk id's
+ * @param downFaces vector of face id's in downward structures
+ * @param downTypes vector of face types
+ * @return number of downward faces
+ */
+int SMDS_Down1D::computeFaces(int cellId, int* vtkIds, int nbcells, int* downFaces, unsigned char* downTypes)
+{
+  int *pts = &_cellIds[_nbDownCells * cellId];
+  int nbFaces = this->computeFaces(pts, vtkIds, nbcells, downFaces, downTypes);
+  return nbFaces;
+}
+
+/*! Build the list of downward faces from a list of vtk cells.
+ *
+ * @param pts list of points id's defining an edge
+ * @param vtkIds vector of vtk id's
+ * @param downFaces vector of face id's in downward structures
+ * @param downTypes vector of face types
+ * @return number of downward faces
+ */
+int SMDS_Down1D::computeFaces(int* pts, int* vtkIds, int nbcells, int* downFaces, unsigned char* downTypes)
+{
+  int cnt = 0;
+  for (int i = 0; i < nbcells; i++)
+    {
+      int vtkId = vtkIds[i];
+      int vtkType = _grid->GetCellType(vtkId);
+      if (SMDS_Downward::getCellDimension(vtkType) == 2)
+        {
+          int faceId = _grid->CellIdToDownId(vtkId);
+          downFaces[cnt] = faceId;
+          downTypes[cnt] = vtkType;
+          cnt++;
+        }
+      else if (SMDS_Downward::getCellDimension(vtkType) == 3)
+        {
+          int volId = _grid->CellIdToDownId(vtkId);
+          SMDS_Downward * downvol = _grid->getDownArray(vtkType);
+          //const int *downIds = downvol->getDownCells(volId);
+          const unsigned char* downTypesVol = downvol->getDownTypes(volId);
+          int nbFaces = downvol->getNumberOfDownCells(volId);
+          const int* faceIds = downvol->getDownCells(volId);
+          for (int n = 0; n < nbFaces; n++)
+            {
+              SMDS_Down2D *downFace = static_cast<SMDS_Down2D*> (_grid->getDownArray(downTypesVol[n]));
+              bool isInFace = downFace->isInFace(faceIds[n], pts, _nbDownCells);
+              if (isInFace)
+                {
+                  bool alreadySet = false;
+                  for (int k = 0; k < cnt; k++)
+                    if (faceIds[n] == downFaces[k])
+                      {
+                        alreadySet = true;
+                        break;
+                      }
+                  if (!alreadySet)
+                    {
+                      downFaces[cnt] = faceIds[n];
+                      downTypes[cnt] = downTypesVol[n];
+                      cnt++;
+                    }
+                }
+            }
+        }
+    }
+  return cnt;
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_Down2D::SMDS_Down2D(SMDS_UnstructuredGrid *grid, int nbDownCells) :
+  SMDS_Downward(grid, nbDownCells)
+{
+  _upCellIds.clear();
+  _upCellTypes.clear();
+  _tempNodes.clear();
+  _nbNodes = 0;
+}
+
+SMDS_Down2D::~SMDS_Down2D()
+{
+}
+
+int SMDS_Down2D::getNumberOfUpCells(int cellId)
+{
+  int nbup = 0;
+  if (_upCellIds[2 * cellId] >= 0)
+    nbup++;
+  if (_upCellIds[2 * cellId + 1] >= 0)
+    nbup++;
+  return nbup;
+}
+
+const int* SMDS_Down2D::getUpCells(int cellId)
+{
+  //ASSERT((cellId >=0) && (cellId < _maxId));
+  return &_upCellIds[2 * cellId];
+}
+
+const unsigned char* SMDS_Down2D::getUpTypes(int cellId)
+{
+  //ASSERT((cellId >=0) && (cellId < _maxId));
+  return &_upCellTypes[2 * cellId];
+}
+
+void SMDS_Down2D::getNodeIds(int cellId, std::set<int>& nodeSet)
+{
+  for (int i = 0; i < _nbDownCells; i++)
+    {
+      int downCellId = _cellIds[_nbDownCells * cellId + i];
+      unsigned char cellType = _cellTypes[i];
+      this->_grid->getDownArray(cellType)->getNodeIds(downCellId, nodeSet);
+    }
+}
+
+/*! Find in vtkUnstructuredGrid the volumes containing a face already stored in vtkUnstructuredGrid.
+ * Search the volumes containing a face, to store the info in SMDS_Down2D for later uses
+ * with SMDS_Down2D::getUpCells and SMDS_Down2D::getUpTypes.
+ * A face belongs to 0, 1 or 2 volumes, identified by their id in vtkUnstructuredGrid.
+ * @param cellId the face cell id in vkUnstructuredGrid
+ * @param ids a couple of vtkId, initialized at -1 (no parent volume)
+ * @return number of volumes (0, 1 or 2)
+ */
+int SMDS_Down2D::computeVolumeIds(int cellId, int* ids)
+{
+  // --- find point id's of the face
+
+  vtkIdType npts = 0;
+  vtkIdType *pts; // will refer to the point id's of the face
+  _grid->GetCellPoints(cellId, npts, pts);
+  vector<int> nodes;
+  for (int i = 0; i < npts; i++)
+    nodes.push_back(pts[i]);
+  int nvol = this->computeVolumeIdsFromNodesFace(&nodes[0], npts, ids);
+  return nvol;
+}
+
+/*! Find in vtkUnstructuredGrid the volumes containing a face described by it's nodes
+ * Search the volumes containing a face, to store the info in SMDS_Down2D for later uses
+ * with SMDS_Down2D::getUpCells and SMDS_Down2D::getUpTypes.
+ * A face belongs to 0, 1 or 2 volumes, identified by their id in vtkUnstructuredGrid.
+ * @param faceByNodes
+ * @param ids a couple of vtkId, initialized at -1 (no parent volume)
+ * @return number of volumes (0, 1 or 2)
+ */
+int SMDS_Down2D::computeVolumeIds(ElemByNodesType& faceByNodes, int* ids)
+{
+  int nvol = this->computeVolumeIdsFromNodesFace(&faceByNodes.nodeIds[0], faceByNodes.nbNodes, ids);
+  return nvol;
+}
+
+/*! Find in vtkUnstructuredGrid the volumes containing a face described by it's nodes
+ * Search the volumes containing a face, to store the info in SMDS_Down2D for later uses
+ * with SMDS_Down2D::getUpCells and SMDS_Down2D::getUpTypes.
+ * A face belongs to 0, 1 or 2 volumes, identified by their id in vtkUnstructuredGrid.
+ * @param pts array of vtk node id's
+ * @param npts number of nodes
+ * @param ids
+ * @return number of volumes (0, 1 or 2)
+ */
+int SMDS_Down2D::computeVolumeIdsFromNodesFace(int* pts, int npts, int* ids)
+{
+
+  // --- find all the cells the points belong to, and how many of the points belong to a given cell
+
+  int cellIds[1000];
+  int cellCnt[1000];
+  int cnt = 0;
+  for (int i = 0; i < npts; i++)
+    {
+      vtkIdType point = pts[i];
+      int numCells = _grid->GetLinks()->GetNcells(point);
+      //MESSAGE("cells pour " << i << " " << numCells);
+      vtkIdType *cells = _grid->GetLinks()->GetCells(point);
+      for (int j = 0; j < numCells; j++)
+        {
+          int vtkCellId = cells[j];
+          bool found = false;
+          for (int k = 0; k < cnt; k++)
+            {
+              if (cellIds[k] == vtkCellId)
+                {
+                  cellCnt[k] += 1;
+                  found = true;
+                  break;
+                }
+            }
+          if (!found)
+            {
+              cellIds[cnt] = vtkCellId;
+              cellCnt[cnt] = 1;
+              // TODO ASSERT(cnt<1000);
+              cnt++;
+            }
+        }
+    }
+
+  // --- find the volume cells: they contains all the points and are of type volume
+
+  int nvol = 0;
+  for (int i = 0; i < cnt; i++)
+    {
+      //MESSAGE("cell " << cellIds[i] << " points " << cellCnt[i]);
+      if (cellCnt[i] == npts)
+        {
+          int vtkElemId = cellIds[i];
+          int vtkType = _grid->GetCellType(vtkElemId);
+          if (SMDS_Downward::getCellDimension(vtkType) == 3)
+            {
+              ids[nvol] = vtkElemId; // store the volume id in given vector
+              nvol++;
+            }
+        }
+      if (nvol == 2)
+        break;
+    }
+
+  return nvol;
+}
+
+void SMDS_Down2D::setTempNodes(int cellId, int vtkId)
+{
+  vtkIdType npts = 0;
+  vtkIdType *pts; // will refer to the point id's of the face
+  _grid->GetCellPoints(vtkId, npts, pts);
+  // MESSAGE(vtkId << " " << npts << "  " << _nbNodes);
+  //ASSERT(npts == _nbNodes);
+  for (int i = 0; i < npts; i++)
+    {
+      _tempNodes[_nbNodes * cellId + i] = pts[i];
+    }
+}
+
+void SMDS_Down2D::setTempNodes(int cellId, ElemByNodesType& faceByNodes)
+{
+  for (int i = 0; i < faceByNodes.nbNodes; i++)
+    _tempNodes[_nbNodes * cellId + i] = faceByNodes.nodeIds[i];
+}
+
+/*! Find if all the nodes belongs to the face.
+ *
+ * @param cellId the face cell Id
+ * @param nodeSet set of node id's to be found in the face list of nodes
+ * @return
+ */
+bool SMDS_Down2D::isInFace(int cellId, int *pts, int npts)
+{
+  int nbFound = 0;
+  int *nodes = &_tempNodes[_nbNodes * cellId];
+  for (int j = 0; j < npts; j++)
+    {
+      int point = pts[j];
+      for (int i = 0; i < _nbNodes; i++)
+        {
+          if (nodes[i] == point)
+            {
+              nbFound++;
+              break;
+            }
+        }
+    }
+  return (nbFound == npts);
+}
+
+/*! Resize the downward connectivity storage vector if needed.
+ *
+ * @param nbElems total number of elements of the same type required
+ */
+void SMDS_Down2D::allocate(int nbElems)
+{
+  if (nbElems >= _vtkCellIds.size())
+    {
+      _cellIds.resize(_nbDownCells * (nbElems + SMDS_Mesh::chunkSize), -1);
+      _vtkCellIds.resize(nbElems + SMDS_Mesh::chunkSize, -1);
+      _upCellIds.resize(2 * (nbElems + SMDS_Mesh::chunkSize), -1);
+      _upCellTypes.resize(2 * (nbElems + SMDS_Mesh::chunkSize), -1);
+      _tempNodes.resize(_nbNodes * (nbElems + SMDS_Mesh::chunkSize), -1);
+    }
+}
+
+void SMDS_Down2D::compactStorage()
+{
+  _cellIds.resize(_nbDownCells * _maxId);
+  _upCellIds.resize(2 * _maxId);
+  _upCellTypes.resize(2 * _maxId);
+  _vtkCellIds.resize(_maxId);
+  _tempNodes.clear();
+}
+
+void SMDS_Down2D::addUpCell(int cellId, int upCellId, unsigned char aType)
+{
+  //ASSERT((cellId >=0)&& (cellId < _maxId));
+  int *vols = &_upCellIds[2 * cellId];
+  unsigned char *types = &_upCellTypes[2 * cellId];
+  for (int i = 0; i < 2; i++)
+    {
+      if (vols[i] < 0)
+        {
+          vols[i] = upCellId; // use non affected volume
+          types[i] = aType;
+          return;
+        }
+      if ((vols[i] == upCellId) && (types[i] == aType)) // already done
+        return;
+    }
+  ASSERT(0);
+}
+
+int SMDS_Down2D::getNodeSet(int cellId, int* nodeSet)
+{
+  for (int i = 0; i < _nbNodes; i++)
+    nodeSet[i] = _tempNodes[_nbNodes * cellId + i];
+  return _nbNodes;
+}
+
+int SMDS_Down2D::FindEdgeByNodes(int cellId, ElemByNodesType& edgeByNodes)
+{
+  int *edges = &_cellIds[_nbDownCells * cellId];
+  for (int i = 0; i < _nbDownCells; i++)
+    {
+      if ((edges[i] >= 0) && (edgeByNodes.vtkType == _cellTypes[i]))
+        {
+          int nodeSet[3];
+          int npts = this->_grid->getDownArray(edgeByNodes.vtkType)->getNodeSet(edges[i], nodeSet);
+          bool found = false;
+          for (int j = 0; j < npts; j++)
+            {
+              int point = edgeByNodes.nodeIds[j];
+              found = false;
+              for (int k = 0; k < npts; k++)
+                {
+                  if (nodeSet[k] == point)
+                    {
+                      found = true;
+                      break;
+                    }
+                }
+              if (!found)
+                break;
+            }
+          if (found)
+            return edges[i];
+        }
+    }
+  return -1;
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_Down3D::SMDS_Down3D(SMDS_UnstructuredGrid *grid, int nbDownCells) :
+  SMDS_Downward(grid, nbDownCells)
+{
+}
+
+SMDS_Down3D::~SMDS_Down3D()
+{
+}
+
+void SMDS_Down3D::allocate(int nbElems)
+{
+  if (nbElems >= _vtkCellIds.size())
+    {
+      _cellIds.resize(_nbDownCells * (nbElems + SMDS_Mesh::chunkSize), -1);
+      _vtkCellIds.resize(nbElems + SMDS_Mesh::chunkSize, -1);
+    }
+}
+
+void SMDS_Down3D::compactStorage()
+{
+  // nothing to do, size was known before
+}
+
+int SMDS_Down3D::getNumberOfUpCells(int cellId)
+{
+  return 0;
+}
+
+const int* SMDS_Down3D::getUpCells(int cellId)
+{
+  return 0;
+}
+
+const unsigned char* SMDS_Down3D::getUpTypes(int cellId)
+{
+  return 0;
+}
+
+void SMDS_Down3D::getNodeIds(int cellId, std::set<int>& nodeSet)
+{
+  int vtkId = this->_vtkCellIds[cellId];
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(vtkId, npts, nodes);
+  for (int i = 0; i < npts; i++)
+    nodeSet.insert(nodes[i]);
+}
+
+int SMDS_Down3D::FindFaceByNodes(int cellId, ElemByNodesType& faceByNodes)
+{
+  int *faces = &_cellIds[_nbDownCells * cellId];
+  int npoints = 0;
+
+  for (int i = 0; i < _nbDownCells; i++)
+    {
+      if ((faces[i] >= 0) && (faceByNodes.vtkType == _cellTypes[i]))
+        {
+          if (npoints == 0)
+            npoints = faceByNodes.nbNodes;
+
+          int nodeSet[10];
+          int npts = this->_grid->getDownArray(faceByNodes.vtkType)->getNodeSet(faces[i], nodeSet);
+          if (npts != npoints)
+            continue; // skip this face
+          bool found = false;
+          for (int j = 0; j < npts; j++)
+            {
+              int point = faceByNodes.nodeIds[j];
+              found = false;
+              for (int k = 0; k < npts; k++)
+                {
+                  if (nodeSet[k] == point)
+                    {
+                      found = true;
+                      break; // point j is in the 2 faces, skip remaining k values
+                    }
+                }
+              if (!found)
+                break; // point j is not in the 2 faces, skip the remaining tests
+            }
+          if (found)
+            return faces[i];
+        }
+    }
+  return -1;
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_DownEdge::SMDS_DownEdge(SMDS_UnstructuredGrid *grid) :
+  SMDS_Down1D(grid, 2)
+{
+  _cellTypes.push_back(VTK_VERTEX);
+  _cellTypes.push_back(VTK_VERTEX);
+}
+
+SMDS_DownEdge::~SMDS_DownEdge()
+{
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_DownQuadEdge::SMDS_DownQuadEdge(SMDS_UnstructuredGrid *grid) :
+  SMDS_Down1D(grid, 3)
+{
+  _cellTypes.push_back(VTK_VERTEX);
+  _cellTypes.push_back(VTK_VERTEX);
+  _cellTypes.push_back(VTK_VERTEX);
+}
+
+SMDS_DownQuadEdge::~SMDS_DownQuadEdge()
+{
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_DownTriangle::SMDS_DownTriangle(SMDS_UnstructuredGrid *grid) :
+  SMDS_Down2D(grid, 3)
+{
+  _cellTypes.push_back(VTK_LINE);
+  _cellTypes.push_back(VTK_LINE);
+  _cellTypes.push_back(VTK_LINE);
+  _nbNodes = 3;
+}
+
+SMDS_DownTriangle::~SMDS_DownTriangle()
+{
+}
+
+void SMDS_DownTriangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes)
+{
+  int *nodes = &_tempNodes[_nbNodes * cellId];
+  edgesWithNodes.nbElems = 3;
+
+  edgesWithNodes.elems[0].nodeIds[0] = nodes[0];
+  edgesWithNodes.elems[0].nodeIds[1] = nodes[1];
+  edgesWithNodes.elems[0].nbNodes = 2;
+  edgesWithNodes.elems[0].vtkType = VTK_LINE;
+
+  edgesWithNodes.elems[1].nodeIds[0] = nodes[1];
+  edgesWithNodes.elems[1].nodeIds[1] = nodes[2];
+  edgesWithNodes.elems[1].nbNodes = 2;
+  edgesWithNodes.elems[1].vtkType = VTK_LINE;
+
+  edgesWithNodes.elems[2].nodeIds[0] = nodes[2];
+  edgesWithNodes.elems[2].nodeIds[1] = nodes[0];
+  edgesWithNodes.elems[2].nbNodes = 2;
+  edgesWithNodes.elems[2].vtkType = VTK_LINE;
+}
+
+void SMDS_DownTriangle::addDownCell(int cellId, int lowCellId, unsigned char aType)
+{
+  //ASSERT((cellId >=0)&& (cellId < _maxId));
+  //ASSERT(aType == VTK_LINE);
+  int *faces = &_cellIds[_nbDownCells * cellId];
+  for (int i = 0; i < _nbDownCells; i++)
+    {
+      if (faces[i] < 0)
+        {
+          faces[i] = lowCellId;
+          return;
+        }
+      if (faces[i] == lowCellId)
+        return;
+    }
+  ASSERT(0);
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_DownQuadTriangle::SMDS_DownQuadTriangle(SMDS_UnstructuredGrid *grid) :
+  SMDS_Down2D(grid, 3)
+{
+  _cellTypes.push_back(VTK_QUADRATIC_EDGE);
+  _cellTypes.push_back(VTK_QUADRATIC_EDGE);
+  _cellTypes.push_back(VTK_QUADRATIC_EDGE);
+  _nbNodes = 6;
+}
+
+SMDS_DownQuadTriangle::~SMDS_DownQuadTriangle()
+{
+}
+
+void SMDS_DownQuadTriangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes)
+{
+  int *nodes = &_tempNodes[_nbNodes * cellId];
+  edgesWithNodes.nbElems = 3;
+
+  edgesWithNodes.elems[0].nodeIds[0] = nodes[0];
+  edgesWithNodes.elems[0].nodeIds[1] = nodes[1];
+  edgesWithNodes.elems[0].nodeIds[2] = nodes[3];
+  edgesWithNodes.elems[0].nbNodes = 3;
+  edgesWithNodes.elems[0].vtkType = VTK_QUADRATIC_EDGE;
+
+  edgesWithNodes.elems[1].nodeIds[0] = nodes[1];
+  edgesWithNodes.elems[1].nodeIds[1] = nodes[2];
+  edgesWithNodes.elems[1].nodeIds[2] = nodes[4];
+  edgesWithNodes.elems[1].nbNodes = 3;
+  edgesWithNodes.elems[1].vtkType = VTK_QUADRATIC_EDGE;
+
+  edgesWithNodes.elems[2].nodeIds[0] = nodes[2];
+  edgesWithNodes.elems[2].nodeIds[1] = nodes[0];
+  edgesWithNodes.elems[2].nodeIds[2] = nodes[5];
+  edgesWithNodes.elems[2].nbNodes = 3;
+  edgesWithNodes.elems[2].vtkType = VTK_QUADRATIC_EDGE;
+}
+
+void SMDS_DownQuadTriangle::addDownCell(int cellId, int lowCellId, unsigned char aType)
+{
+  //ASSERT((cellId >=0)&& (cellId < _maxId));
+  //ASSERT(aType == VTK_QUADRATIC_EDGE);
+  int *edges = &_cellIds[_nbDownCells * cellId];
+  for (int i = 0; i < _nbDownCells; i++)
+    {
+      if (edges[i] < 0)
+        {
+          edges[i] = lowCellId;
+          return;
+        }
+      if (edges[i] == lowCellId)
+        return;
+    }
+  ASSERT(0);
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_DownQuadrangle::SMDS_DownQuadrangle(SMDS_UnstructuredGrid *grid) :
+  SMDS_Down2D(grid, 4)
+{
+  _cellTypes.push_back(VTK_LINE);
+  _cellTypes.push_back(VTK_LINE);
+  _cellTypes.push_back(VTK_LINE);
+  _cellTypes.push_back(VTK_LINE);
+  _nbNodes = 4;
+}
+
+SMDS_DownQuadrangle::~SMDS_DownQuadrangle()
+{
+}
+
+void SMDS_DownQuadrangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes)
+{
+  int *nodes = &_tempNodes[_nbNodes * cellId];
+  edgesWithNodes.nbElems = 4;
+
+  edgesWithNodes.elems[0].nodeIds[0] = nodes[0];
+  edgesWithNodes.elems[0].nodeIds[1] = nodes[1];
+  edgesWithNodes.elems[0].nbNodes = 2;
+  edgesWithNodes.elems[0].vtkType = VTK_LINE;
+
+  edgesWithNodes.elems[1].nodeIds[0] = nodes[1];
+  edgesWithNodes.elems[1].nodeIds[1] = nodes[2];
+  edgesWithNodes.elems[1].nbNodes = 2;
+  edgesWithNodes.elems[1].vtkType = VTK_LINE;
+
+  edgesWithNodes.elems[2].nodeIds[0] = nodes[2];
+  edgesWithNodes.elems[2].nodeIds[1] = nodes[3];
+  edgesWithNodes.elems[2].nbNodes = 2;
+  edgesWithNodes.elems[2].vtkType = VTK_LINE;
+
+  edgesWithNodes.elems[3].nodeIds[0] = nodes[3];
+  edgesWithNodes.elems[3].nodeIds[1] = nodes[0];
+  edgesWithNodes.elems[3].nbNodes = 2;
+  edgesWithNodes.elems[3].vtkType = VTK_LINE;
+}
+
+void SMDS_DownQuadrangle::addDownCell(int cellId, int lowCellId, unsigned char aType)
+{
+  //ASSERT((cellId >=0)&& (cellId < _maxId));
+  //ASSERT(aType == VTK_LINE);
+  int *faces = &_cellIds[_nbDownCells * cellId];
+  for (int i = 0; i < _nbDownCells; i++)
+    {
+      if (faces[i] < 0)
+        {
+          faces[i] = lowCellId;
+          return;
+        }
+      if (faces[i] == lowCellId)
+        return;
+    }
+  ASSERT(0);
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_DownQuadQuadrangle::SMDS_DownQuadQuadrangle(SMDS_UnstructuredGrid *grid) :
+  SMDS_Down2D(grid, 4)
+{
+  _cellTypes.push_back(VTK_QUADRATIC_EDGE);
+  _cellTypes.push_back(VTK_QUADRATIC_EDGE);
+  _cellTypes.push_back(VTK_QUADRATIC_EDGE);
+  _cellTypes.push_back(VTK_QUADRATIC_EDGE);
+  _nbNodes = 8;
+}
+
+SMDS_DownQuadQuadrangle::~SMDS_DownQuadQuadrangle()
+{
+}
+
+void SMDS_DownQuadQuadrangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes)
+{
+  int *nodes = &_tempNodes[_nbNodes * cellId];
+  edgesWithNodes.nbElems = 4;
+
+  edgesWithNodes.elems[0].nodeIds[0] = nodes[0];
+  edgesWithNodes.elems[0].nodeIds[1] = nodes[1];
+  edgesWithNodes.elems[0].nodeIds[2] = nodes[4];
+  edgesWithNodes.elems[0].nbNodes = 3;
+  edgesWithNodes.elems[0].vtkType = VTK_QUADRATIC_EDGE;
+
+  edgesWithNodes.elems[1].nodeIds[0] = nodes[1];
+  edgesWithNodes.elems[1].nodeIds[1] = nodes[2];
+  edgesWithNodes.elems[1].nodeIds[2] = nodes[5];
+  edgesWithNodes.elems[1].nbNodes = 3;
+  edgesWithNodes.elems[1].vtkType = VTK_QUADRATIC_EDGE;
+
+  edgesWithNodes.elems[2].nodeIds[0] = nodes[2];
+  edgesWithNodes.elems[2].nodeIds[1] = nodes[3];
+  edgesWithNodes.elems[2].nodeIds[2] = nodes[6];
+  edgesWithNodes.elems[2].nbNodes = 3;
+  edgesWithNodes.elems[2].vtkType = VTK_QUADRATIC_EDGE;
+
+  edgesWithNodes.elems[3].nodeIds[0] = nodes[3];
+  edgesWithNodes.elems[3].nodeIds[1] = nodes[0];
+  edgesWithNodes.elems[3].nodeIds[2] = nodes[7];
+  edgesWithNodes.elems[3].nbNodes = 3;
+  edgesWithNodes.elems[3].vtkType = VTK_QUADRATIC_EDGE;
+}
+
+void SMDS_DownQuadQuadrangle::addDownCell(int cellId, int lowCellId, unsigned char aType)
+{
+  //ASSERT((cellId >=0)&& (cellId < _maxId));
+  //ASSERT(aType == VTK_QUADRATIC_EDGE);
+  int *faces = &_cellIds[_nbDownCells * cellId];
+  for (int i = 0; i < _nbDownCells; i++)
+    {
+      if (faces[i] < 0)
+        {
+          faces[i] = lowCellId;
+          return;
+        }
+      if (faces[i] == lowCellId)
+        return;
+    }
+  ASSERT(0);
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_DownTetra::SMDS_DownTetra(SMDS_UnstructuredGrid *grid) :
+  SMDS_Down3D(grid, 4)
+{
+  _cellTypes.push_back(VTK_TRIANGLE);
+  _cellTypes.push_back(VTK_TRIANGLE);
+  _cellTypes.push_back(VTK_TRIANGLE);
+  _cellTypes.push_back(VTK_TRIANGLE);
+}
+
+SMDS_DownTetra::~SMDS_DownTetra()
+{
+}
+
+void SMDS_DownTetra::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
+{
+  set<int> setNodes;
+  setNodes.clear();
+  for (int i = 0; i < orderedNodes.size(); i++)
+    setNodes.insert(orderedNodes[i]);
+  //MESSAGE("cellId = " << cellId);
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
+
+  set<int> tofind;
+  int ids[12] = { 0, 1, 2,  0, 3, 1,  2, 3, 0,   1, 3, 2 };
+//int ids[12] = { 2, 1, 0,  1, 3, 0,  0, 3, 2,   2, 3, 1 };
+  for (int k = 0; k < 4; k++)
+    {
+      tofind.clear();
+      for (int i = 0; i < 3; i++)
+        tofind.insert(nodes[ids[3 * k + i]]);
+      if (setNodes == tofind)
+        {
+          for (int i = 0; i < 3; i++)
+            orderedNodes[i] = nodes[ids[3 * k + i]];
+          return;
+        }
+    }
+  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
+  MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
+  MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
+}
+
+void SMDS_DownTetra::addDownCell(int cellId, int lowCellId, unsigned char aType)
+{
+  //ASSERT((cellId >=0)&& (cellId < _maxId));
+  //ASSERT(aType == VTK_TRIANGLE);
+  int *faces = &_cellIds[_nbDownCells * cellId];
+  for (int i = 0; i < _nbDownCells; i++)
+    {
+      if (faces[i] < 0)
+        {
+          faces[i] = lowCellId;
+          return;
+        }
+      if (faces[i] == lowCellId)
+        return;
+    }
+  ASSERT(0);
+}
+
+/*! Create a list of faces described by a vtk Type and  an ordered set of Node Id's
+ * The linear tetrahedron is defined by four points.
+ * @see vtkTetra.h in Filtering.
+ * @param cellId volumeId in vtkUnstructuredGrid
+ * @param facesWithNodes vector of face descriptors to be filled
+ */
+void SMDS_DownTetra::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
+{
+  // --- find point id's of the volume
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(cellId, npts, nodes);
+
+  // --- create all the ordered list of node id's for each face
+
+  facesWithNodes.nbElems = 4;
+
+  facesWithNodes.elems[0].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[0].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[0].nodeIds[2] = nodes[2];
+  facesWithNodes.elems[0].nbNodes = 3;
+  facesWithNodes.elems[0].vtkType = VTK_TRIANGLE;
+
+  facesWithNodes.elems[1].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[1].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[1].nodeIds[2] = nodes[3];
+  facesWithNodes.elems[1].nbNodes = 3;
+  facesWithNodes.elems[1].vtkType = VTK_TRIANGLE;
+
+  facesWithNodes.elems[2].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[2].nodeIds[1] = nodes[2];
+  facesWithNodes.elems[2].nodeIds[2] = nodes[3];
+  facesWithNodes.elems[2].nbNodes = 3;
+  facesWithNodes.elems[2].vtkType = VTK_TRIANGLE;
+
+  facesWithNodes.elems[3].nodeIds[0] = nodes[1];
+  facesWithNodes.elems[3].nodeIds[1] = nodes[2];
+  facesWithNodes.elems[3].nodeIds[2] = nodes[3];
+  facesWithNodes.elems[3].nbNodes = 3;
+  facesWithNodes.elems[3].vtkType = VTK_TRIANGLE;
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_DownQuadTetra::SMDS_DownQuadTetra(SMDS_UnstructuredGrid *grid) :
+  SMDS_Down3D(grid, 4)
+{
+  _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
+  _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
+  _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
+  _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
+}
+
+SMDS_DownQuadTetra::~SMDS_DownQuadTetra()
+{
+}
+
+void SMDS_DownQuadTetra::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
+{
+  set<int> setNodes;
+  setNodes.clear();
+  for (int i = 0; i < orderedNodes.size(); i++)
+    setNodes.insert(orderedNodes[i]);
+  //MESSAGE("cellId = " << cellId);
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
+
+  set<int> tofind;
+  int ids[24] = { 0, 1, 2, 4, 5, 6,  0, 3, 1, 7, 8, 4,  2, 3, 0, 9, 7, 6,  1, 3, 2, 8, 9, 5 };
+//int ids[24] = { 2, 1, 0, 5, 4, 6,  1, 3, 0, 8, 7, 4,  0, 3, 2, 7, 9, 6,  2, 3, 1, 9, 8, 5 };
+  for (int k = 0; k < 4; k++)
+    {
+      tofind.clear();
+      for (int i = 0; i < 6; i++)
+        tofind.insert(nodes[ids[6 * k + i]]);
+      if (setNodes == tofind)
+        {
+          for (int i = 0; i < 6; i++)
+            orderedNodes[i] = nodes[ids[6 * k + i]];
+          return;
+        }
+    }
+  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
+  MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
+  MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
+}
+
+void SMDS_DownQuadTetra::addDownCell(int cellId, int lowCellId, unsigned char aType)
+{
+  //ASSERT((cellId >=0)&& (cellId < _maxId));
+  //ASSERT(aType == VTK_QUADRATIC_TRIANGLE);
+  int *faces = &_cellIds[_nbDownCells * cellId];
+  for (int i = 0; i < _nbDownCells; i++)
+    {
+      if (faces[i] < 0)
+        {
+          faces[i] = lowCellId;
+          return;
+        }
+      if (faces[i] == lowCellId)
+        return;
+    }
+  ASSERT(0);
+}
+
+/*! Create a list of faces described by a vtk Type and  an ordered set of Node Id's
+ * The ordering of the ten points defining the quadratic tetrahedron cell is point id's (0-3,4-9)
+ * where id's 0-3 are the four tetrahedron vertices;
+ * and point id's 4-9 are the mid-edge nodes between (0,1), (1,2), (2,0), (0,3), (1,3), and (2,3).
+ * @see vtkQuadraticTetra.h in Filtering.
+ * @param cellId volumeId in vtkUnstructuredGrid
+ * @param facesWithNodes vector of face descriptors to be filled
+ */
+void SMDS_DownQuadTetra::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
+{
+  // --- find point id's of the volume
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(cellId, npts, nodes);
+
+  // --- create all the ordered list of node id's for each face
+
+  facesWithNodes.nbElems = 4;
+
+  facesWithNodes.elems[0].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[0].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[0].nodeIds[2] = nodes[2];
+  facesWithNodes.elems[0].nodeIds[3] = nodes[4];
+  facesWithNodes.elems[0].nodeIds[4] = nodes[5];
+  facesWithNodes.elems[0].nodeIds[5] = nodes[6];
+  facesWithNodes.elems[0].nbNodes = 6;
+  facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_TRIANGLE;
+
+  facesWithNodes.elems[1].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[1].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[1].nodeIds[2] = nodes[3];
+  facesWithNodes.elems[1].nodeIds[3] = nodes[4];
+  facesWithNodes.elems[1].nodeIds[4] = nodes[8];
+  facesWithNodes.elems[1].nodeIds[5] = nodes[7];
+  facesWithNodes.elems[1].nbNodes = 6;
+  facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_TRIANGLE;
+
+  facesWithNodes.elems[2].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[2].nodeIds[1] = nodes[2];
+  facesWithNodes.elems[2].nodeIds[2] = nodes[3];
+  facesWithNodes.elems[2].nodeIds[3] = nodes[6];
+  facesWithNodes.elems[2].nodeIds[4] = nodes[9];
+  facesWithNodes.elems[2].nodeIds[5] = nodes[7];
+  facesWithNodes.elems[2].nbNodes = 6;
+  facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_TRIANGLE;
+
+  facesWithNodes.elems[3].nodeIds[0] = nodes[1];
+  facesWithNodes.elems[3].nodeIds[1] = nodes[2];
+  facesWithNodes.elems[3].nodeIds[2] = nodes[3];
+  facesWithNodes.elems[3].nodeIds[3] = nodes[5];
+  facesWithNodes.elems[3].nodeIds[4] = nodes[9];
+  facesWithNodes.elems[3].nodeIds[5] = nodes[8];
+  facesWithNodes.elems[3].nbNodes = 6;
+  facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_TRIANGLE;
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_DownPyramid::SMDS_DownPyramid(SMDS_UnstructuredGrid *grid) :
+  SMDS_Down3D(grid, 5)
+{
+  _cellTypes.push_back(VTK_QUAD);
+  _cellTypes.push_back(VTK_TRIANGLE);
+  _cellTypes.push_back(VTK_TRIANGLE);
+  _cellTypes.push_back(VTK_TRIANGLE);
+  _cellTypes.push_back(VTK_TRIANGLE);
+}
+
+SMDS_DownPyramid::~SMDS_DownPyramid()
+{
+}
+
+void SMDS_DownPyramid::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
+{
+  set<int> setNodes;
+  setNodes.clear();
+  for (int i = 0; i < orderedNodes.size(); i++)
+    setNodes.insert(orderedNodes[i]);
+  //MESSAGE("cellId = " << cellId);
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
+
+  set<int> tofind;
+  int ids[16] = { 0, 1, 2, 3,   0, 3, 4,   3, 2, 4,   2, 1, 4,   1, 0, 4 };
+
+  tofind.clear();
+  for (int i = 0; i < 4; i++)
+    tofind.insert(nodes[ids[i]]);
+  if (setNodes == tofind)
+    {
+      for (int i = 0; i < 4; i++)
+        orderedNodes[i] = nodes[ids[i]];
+      return;
+    }
+  for (int k = 0; k < 4; k++)
+    {
+      tofind.clear();
+      for (int i = 0; i < 3; i++)
+        tofind.insert(nodes[ids[4 + 3 * k + i]]);
+      if (setNodes == tofind)
+        {
+          for (int i = 0; i < 3; i++)
+            orderedNodes[i] = nodes[ids[4 + 3 * k + i]];
+          return;
+        }
+    }
+  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
+  MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
+  MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
+}
+
+void SMDS_DownPyramid::addDownCell(int cellId, int lowCellId, unsigned char aType)
+{
+  //ASSERT((cellId >=0) && (cellId < _maxId));
+  int *faces = &_cellIds[_nbDownCells * cellId];
+  if (aType == VTK_QUAD)
+    {
+      if (faces[0] < 0)
+        {
+          faces[0] = lowCellId;
+          return;
+        }
+      if (faces[0] == lowCellId)
+        return;
+    }
+  else
+    {
+      //ASSERT(aType == VTK_TRIANGLE);
+      for (int i = 1; i < _nbDownCells; i++)
+        {
+          if (faces[i] < 0)
+            {
+              faces[i] = lowCellId;
+              return;
+            }
+          if (faces[i] == lowCellId)
+            return;
+        }
+    }
+  ASSERT(0);
+}
+
+/*! Create a list of faces described by a vtk Type and  an ordered set of Node Id's
+ * The pyramid is defined by the five points (0-4) where (0,1,2,3) is the base of the pyramid which,
+ * using the right hand rule, forms a quadrilateral whose normal points in the direction of the
+ * pyramid apex at vertex #4.
+ * @see vtkPyramid.h in Filtering.
+ * @param cellId volumeId in vtkUnstructuredGrid
+ * @param facesWithNodes vector of face descriptors to be filled
+ */
+void SMDS_DownPyramid::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
+{
+  // --- find point id's of the volume
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(cellId, npts, nodes);
+
+  // --- create all the ordered list of node id's for each face
+
+  facesWithNodes.nbElems = 5;
+
+  facesWithNodes.elems[0].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[0].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[0].nodeIds[2] = nodes[2];
+  facesWithNodes.elems[0].nodeIds[3] = nodes[3];
+  facesWithNodes.elems[0].nbNodes = 4;
+  facesWithNodes.elems[0].vtkType = VTK_QUAD;
+
+  facesWithNodes.elems[1].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[1].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[1].nodeIds[2] = nodes[4];
+  facesWithNodes.elems[1].nbNodes = 3;
+  facesWithNodes.elems[1].vtkType = VTK_TRIANGLE;
+
+  facesWithNodes.elems[2].nodeIds[0] = nodes[1];
+  facesWithNodes.elems[2].nodeIds[1] = nodes[2];
+  facesWithNodes.elems[2].nodeIds[2] = nodes[4];
+  facesWithNodes.elems[2].nbNodes = 3;
+  facesWithNodes.elems[2].vtkType = VTK_TRIANGLE;
+
+  facesWithNodes.elems[3].nodeIds[0] = nodes[2];
+  facesWithNodes.elems[3].nodeIds[1] = nodes[3];
+  facesWithNodes.elems[3].nodeIds[2] = nodes[4];
+  facesWithNodes.elems[3].nbNodes = 3;
+  facesWithNodes.elems[3].vtkType = VTK_TRIANGLE;
+
+  facesWithNodes.elems[4].nodeIds[0] = nodes[3];
+  facesWithNodes.elems[4].nodeIds[1] = nodes[0];
+  facesWithNodes.elems[4].nodeIds[2] = nodes[4];
+  facesWithNodes.elems[4].nbNodes = 3;
+  facesWithNodes.elems[4].vtkType = VTK_TRIANGLE;
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_DownQuadPyramid::SMDS_DownQuadPyramid(SMDS_UnstructuredGrid *grid) :
+  SMDS_Down3D(grid, 5)
+{
+  _cellTypes.push_back(VTK_QUADRATIC_QUAD);
+  _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
+  _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
+  _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
+  _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
+}
+
+SMDS_DownQuadPyramid::~SMDS_DownQuadPyramid()
+{
+}
+
+void SMDS_DownQuadPyramid::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
+{
+  set<int> setNodes;
+  setNodes.clear();
+  for (int i = 0; i < orderedNodes.size(); i++)
+    setNodes.insert(orderedNodes[i]);
+  //MESSAGE("cellId = " << cellId);
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
+
+  set<int> tofind;
+  int ids[32] = { 0, 1, 2, 3, 5, 6, 7, 8,
+                  0, 3, 4, 8, 12, 9,   3, 2, 4, 7 , 11, 12,   2, 1, 4, 6, 10, 11,   1, 0, 4, 5, 9, 10 };
+
+  tofind.clear();
+  for (int i = 0; i < 4; i++)
+    tofind.insert(nodes[ids[i]]);
+  if (setNodes == tofind)
+    {
+      for (int i = 0; i < 8; i++)
+        orderedNodes[i] = nodes[ids[i]];
+      return;
+    }
+  for (int k = 0; k < 4; k++)
+    {
+      tofind.clear();
+      for (int i = 0; i < 6; i++)
+        tofind.insert(nodes[ids[8 + 6 * k + i]]);
+      if (setNodes == tofind)
+        {
+          for (int i = 0; i < 6; i++)
+            orderedNodes[i] = nodes[ids[8 + 6 * k + i]];
+          return;
+        }
+    }
+  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
+  MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
+  MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
+}
+
+void SMDS_DownQuadPyramid::addDownCell(int cellId, int lowCellId, unsigned char aType)
+{
+  //ASSERT((cellId >=0) && (cellId < _maxId));
+  int *faces = &_cellIds[_nbDownCells * cellId];
+  if (aType == VTK_QUADRATIC_QUAD)
+    {
+      if (faces[0] < 0)
+        {
+          faces[0] = lowCellId;
+          return;
+        }
+      if (faces[0] == lowCellId)
+        return;
+    }
+  else
+    {
+      //ASSERT(aType == VTK_QUADRATIC_TRIANGLE);
+      for (int i = 1; i < _nbDownCells; i++)
+        {
+          if (faces[i] < 0)
+            {
+              faces[i] = lowCellId;
+              return;
+            }
+          if (faces[i] == lowCellId)
+            return;
+        }
+    }
+  ASSERT(0);
+}
+
+/*! Create a list of faces described by a vtk Type and  an ordered set of Node Id's
+ * The ordering of the thirteen points defining the quadratic pyramid cell is point id's (0-4,5-12)
+ * where point id's 0-4 are the five corner vertices of the pyramid; followed
+ * by eight mid-edge nodes (5-12). Note that these mid-edge nodes lie on the edges defined by
+ * 5(0,1), 6(1,2), 7(2,3), 8(3,0), 9(0,4), 10(1,4), 11(2,4), 12(3,4).
+ * @see vtkQuadraticPyramid.h in Filtering.
+ * @param cellId volumeId in vtkUnstructuredGrid
+ * @param facesWithNodes vector of face descriptors to be filled
+ */
+void SMDS_DownQuadPyramid::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
+{
+  // --- find point id's of the volume
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(cellId, npts, nodes);
+
+  // --- create all the ordered list of node id's for each face
+
+  facesWithNodes.nbElems = 5;
+
+  facesWithNodes.elems[0].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[0].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[0].nodeIds[2] = nodes[2];
+  facesWithNodes.elems[0].nodeIds[3] = nodes[3];
+  facesWithNodes.elems[0].nodeIds[4] = nodes[5];
+  facesWithNodes.elems[0].nodeIds[5] = nodes[6];
+  facesWithNodes.elems[0].nodeIds[6] = nodes[7];
+  facesWithNodes.elems[0].nodeIds[7] = nodes[8];
+  facesWithNodes.elems[0].nbNodes = 8;
+  facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_QUAD;
+
+  facesWithNodes.elems[1].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[1].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[1].nodeIds[2] = nodes[4];
+  facesWithNodes.elems[1].nodeIds[3] = nodes[5];
+  facesWithNodes.elems[1].nodeIds[4] = nodes[10];
+  facesWithNodes.elems[1].nodeIds[5] = nodes[9];
+  facesWithNodes.elems[1].nbNodes = 6;
+  facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_TRIANGLE;
+
+  facesWithNodes.elems[2].nodeIds[0] = nodes[1];
+  facesWithNodes.elems[2].nodeIds[1] = nodes[2];
+  facesWithNodes.elems[2].nodeIds[2] = nodes[4];
+  facesWithNodes.elems[2].nodeIds[3] = nodes[6];
+  facesWithNodes.elems[2].nodeIds[4] = nodes[11];
+  facesWithNodes.elems[2].nodeIds[5] = nodes[10];
+  facesWithNodes.elems[2].nbNodes = 6;
+  facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_TRIANGLE;
+
+  facesWithNodes.elems[3].nodeIds[0] = nodes[2];
+  facesWithNodes.elems[3].nodeIds[1] = nodes[3];
+  facesWithNodes.elems[3].nodeIds[2] = nodes[4];
+  facesWithNodes.elems[3].nodeIds[3] = nodes[7];
+  facesWithNodes.elems[3].nodeIds[4] = nodes[12];
+  facesWithNodes.elems[3].nodeIds[5] = nodes[11];
+  facesWithNodes.elems[3].nbNodes = 6;
+  facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_TRIANGLE;
+
+  facesWithNodes.elems[4].nodeIds[0] = nodes[3];
+  facesWithNodes.elems[4].nodeIds[1] = nodes[0];
+  facesWithNodes.elems[4].nodeIds[2] = nodes[4];
+  facesWithNodes.elems[4].nodeIds[3] = nodes[8];
+  facesWithNodes.elems[4].nodeIds[4] = nodes[9];
+  facesWithNodes.elems[4].nodeIds[5] = nodes[12];
+  facesWithNodes.elems[4].nbNodes = 6;
+  facesWithNodes.elems[4].vtkType = VTK_QUADRATIC_TRIANGLE;
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_DownPenta::SMDS_DownPenta(SMDS_UnstructuredGrid *grid) :
+  SMDS_Down3D(grid, 5)
+{
+  _cellTypes.push_back(VTK_QUAD);
+  _cellTypes.push_back(VTK_QUAD);
+  _cellTypes.push_back(VTK_QUAD);
+  _cellTypes.push_back(VTK_TRIANGLE);
+  _cellTypes.push_back(VTK_TRIANGLE);
+}
+
+SMDS_DownPenta::~SMDS_DownPenta()
+{
+}
+
+void SMDS_DownPenta::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
+{
+  set<int> setNodes;
+  setNodes.clear();
+  for (int i = 0; i < orderedNodes.size(); i++)
+    setNodes.insert(orderedNodes[i]);
+  //MESSAGE("cellId = " << cellId);
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
+
+  set<int> tofind;
+//int ids[18] = { 0, 2, 1,  3, 4, 5,   0, 1, 4, 3,   1, 2, 5, 4,   2, 0, 3, 5 };
+  int ids[18] = { 0, 1, 2,  3, 5, 4,   0, 3, 4, 1,   1, 4, 5, 2,   2, 5, 3, 0 };
+
+  for (int k = 0; k < 2; k++)
+    {
+      tofind.clear();
+      for (int i = 0; i < 3; i++)
+        tofind.insert(nodes[ids[3 * k + i]]);
+      if (setNodes == tofind)
+        {
+          for (int i = 0; i < 3; i++)
+            orderedNodes[i] = nodes[ids[3 * k + i]];
+          return;
+        }
+    }
+  for (int k = 0; k < 3; k++)
+    {
+      tofind.clear();
+      for (int i = 0; i < 4; i++)
+        tofind.insert(nodes[ids[6 + 4 * k + i]]);
+      if (setNodes == tofind)
+        {
+          for (int i = 0; i < 4; i++)
+            orderedNodes[i] = nodes[ids[6 + 4 * k + i]];
+          return;
+        }
+    }
+  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
+  MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
+  MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
+}
+
+void SMDS_DownPenta::addDownCell(int cellId, int lowCellId, unsigned char aType)
+{
+  //ASSERT((cellId >=0) && (cellId < _maxId));
+  int *faces = &_cellIds[_nbDownCells * cellId];
+  if (aType == VTK_QUAD)
+    for (int i = 0; i < 3; i++)
+      {
+        if (faces[i] < 0)
+          {
+            faces[i] = lowCellId;
+            return;
+          }
+        if (faces[i] == lowCellId)
+          return;
+      }
+  else
+    {
+      //ASSERT(aType == VTK_TRIANGLE);
+      for (int i = 3; i < _nbDownCells; i++)
+        {
+          if (faces[i] < 0)
+            {
+              faces[i] = lowCellId;
+              return;
+            }
+          if (faces[i] == lowCellId)
+            return;
+        }
+    }
+  ASSERT(0);
+}
+
+/*! Create a list of faces described by a vtk Type and  an ordered set of Node Id's.
+ * A wedge or pentahedron consists of two triangular and three quadrilateral faces
+ * and is defined by the six points (0-5) where (0,1,2) is the base of the wedge which,
+ * using the right hand rule, forms a triangle whose normal points outward
+ * (away from the triangular face (3,4,5)).
+ * @see vtkWedge.h in Filtering
+ * @param cellId volumeId in vtkUnstructuredGrid
+ * @param facesWithNodes vector of face descriptors to be filled
+ */
+void SMDS_DownPenta::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
+{
+  // --- find point id's of the volume
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(cellId, npts, nodes);
+
+  // --- create all the ordered list of node id's for each face
+
+  facesWithNodes.nbElems = 5;
+
+  facesWithNodes.elems[0].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[0].nodeIds[1] = nodes[2];
+  facesWithNodes.elems[0].nodeIds[2] = nodes[5];
+  facesWithNodes.elems[0].nodeIds[3] = nodes[3];
+  facesWithNodes.elems[0].nbNodes = 4;
+  facesWithNodes.elems[0].vtkType = VTK_QUAD;
+
+  facesWithNodes.elems[1].nodeIds[0] = nodes[1];
+  facesWithNodes.elems[1].nodeIds[1] = nodes[2];
+  facesWithNodes.elems[1].nodeIds[2] = nodes[5];
+  facesWithNodes.elems[1].nodeIds[3] = nodes[4];
+  facesWithNodes.elems[1].nbNodes = 4;
+  facesWithNodes.elems[1].vtkType = VTK_QUAD;
+
+  facesWithNodes.elems[2].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[2].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[2].nodeIds[2] = nodes[4];
+  facesWithNodes.elems[2].nodeIds[3] = nodes[3];
+  facesWithNodes.elems[2].nbNodes = 4;
+  facesWithNodes.elems[2].vtkType = VTK_QUAD;
+
+  facesWithNodes.elems[3].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[3].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[3].nodeIds[2] = nodes[2];
+  facesWithNodes.elems[3].nbNodes = 3;
+  facesWithNodes.elems[3].vtkType = VTK_TRIANGLE;
+
+  facesWithNodes.elems[4].nodeIds[0] = nodes[3];
+  facesWithNodes.elems[4].nodeIds[1] = nodes[4];
+  facesWithNodes.elems[4].nodeIds[2] = nodes[5];
+  facesWithNodes.elems[4].nbNodes = 3;
+  facesWithNodes.elems[4].vtkType = VTK_TRIANGLE;
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_DownQuadPenta::SMDS_DownQuadPenta(SMDS_UnstructuredGrid *grid) :
+  SMDS_Down3D(grid, 5)
+{
+  _cellTypes.push_back(VTK_QUADRATIC_QUAD);
+  _cellTypes.push_back(VTK_QUADRATIC_QUAD);
+  _cellTypes.push_back(VTK_QUADRATIC_QUAD);
+  _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
+  _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
+}
+
+SMDS_DownQuadPenta::~SMDS_DownQuadPenta()
+{
+}
+
+void SMDS_DownQuadPenta::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
+{
+  set<int> setNodes;
+  setNodes.clear();
+  for (int i = 0; i < orderedNodes.size(); i++)
+    setNodes.insert(orderedNodes[i]);
+  //MESSAGE("cellId = " << cellId);
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
+
+  set<int> tofind;
+//int ids[18] = { 0, 2, 1,  3, 4, 5,   0, 1, 4, 3,   1, 2, 5, 4,   2, 0, 3, 5 };
+  int ids[36] = { 0, 1, 2, 6, 7, 8,  3, 5, 4, 11, 10, 9,
+                  0, 3, 4, 1, 12, 9, 13, 6,   1, 4, 5, 2, 13, 10, 14, 7,   2, 5, 3, 0, 14, 11, 12, 8 };
+
+  for (int k = 0; k < 2; k++)
+    {
+      tofind.clear();
+      for (int i = 0; i < 6; i++)
+        tofind.insert(nodes[ids[6 * k + i]]);
+      if (setNodes == tofind)
+        {
+          for (int i = 0; i < 6; i++)
+            orderedNodes[i] = nodes[ids[6 * k + i]];
+          return;
+        }
+    }
+  for (int k = 0; k < 3; k++)
+    {
+      tofind.clear();
+      for (int i = 0; i < 8; i++)
+        tofind.insert(nodes[ids[12 + 8 * k + i]]);
+      if (setNodes == tofind)
+        {
+          for (int i = 0; i < 8; i++)
+            orderedNodes[i] = nodes[ids[12 + 8 * k + i]];
+          return;
+        }
+    }
+  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
+  MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
+  MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
+}
+
+void SMDS_DownQuadPenta::addDownCell(int cellId, int lowCellId, unsigned char aType)
+{
+  //ASSERT((cellId >=0) && (cellId < _maxId));
+  int *faces = &_cellIds[_nbDownCells * cellId];
+  if (aType == VTK_QUADRATIC_QUAD)
+    for (int i = 0; i < 3; i++)
+      {
+        if (faces[i] < 0)
+          {
+            faces[i] = lowCellId;
+            return;
+          }
+        if (faces[i] == lowCellId)
+          return;
+      }
+  else
+    {
+      //ASSERT(aType == VTK_QUADRATIC_TRIANGLE);
+      for (int i = 3; i < _nbDownCells; i++)
+        {
+          if (faces[i] < 0)
+            {
+              faces[i] = lowCellId;
+              return;
+            }
+          if (faces[i] == lowCellId)
+            return;
+        }
+    }
+  ASSERT(0);
+}
+
+/*! Create a list of faces described by a vtk Type and  an ordered set of Node Id's
+ * The quadratic wedge (or pentahedron) is defined by fifteen points.
+ * The ordering of the fifteen points defining the cell is point id's (0-5,6-14)
+ * where point id's 0-5 are the six corner vertices of the wedge, followed by
+ * nine mid-edge nodes (6-14). Note that these mid-edge nodes lie on the edges defined by
+ * (0,1), (1,2), (2,0), (3,4), (4,5), (5,3), (0,3), (1,4), (2,5).
+ * @see vtkQuadraticWedge.h in Filtering
+ * @param cellId volumeId in vtkUnstructuredGrid
+ * @param facesWithNodes vector of face descriptors to be filled
+ */
+void SMDS_DownQuadPenta::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
+{
+  // --- find point id's of the volume
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(cellId, npts, nodes);
+
+  // --- create all the ordered list of node id's for each face
+
+  facesWithNodes.nbElems = 5;
+
+  facesWithNodes.elems[0].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[0].nodeIds[1] = nodes[2];
+  facesWithNodes.elems[0].nodeIds[2] = nodes[5];
+  facesWithNodes.elems[0].nodeIds[3] = nodes[3];
+  facesWithNodes.elems[0].nodeIds[4] = nodes[8];
+  facesWithNodes.elems[0].nodeIds[5] = nodes[14];
+  facesWithNodes.elems[0].nodeIds[6] = nodes[11];
+  facesWithNodes.elems[0].nodeIds[7] = nodes[12];
+  facesWithNodes.elems[0].nbNodes = 8;
+  facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_QUAD;
+
+  facesWithNodes.elems[1].nodeIds[0] = nodes[1];
+  facesWithNodes.elems[1].nodeIds[1] = nodes[2];
+  facesWithNodes.elems[1].nodeIds[2] = nodes[5];
+  facesWithNodes.elems[1].nodeIds[3] = nodes[4];
+  facesWithNodes.elems[1].nodeIds[4] = nodes[7];
+  facesWithNodes.elems[1].nodeIds[5] = nodes[14];
+  facesWithNodes.elems[1].nodeIds[6] = nodes[10];
+  facesWithNodes.elems[1].nodeIds[7] = nodes[13];
+  facesWithNodes.elems[1].nbNodes = 8;
+  facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_QUAD;
+
+  facesWithNodes.elems[2].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[2].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[2].nodeIds[2] = nodes[4];
+  facesWithNodes.elems[2].nodeIds[3] = nodes[3];
+  facesWithNodes.elems[2].nodeIds[4] = nodes[6];
+  facesWithNodes.elems[2].nodeIds[5] = nodes[13];
+  facesWithNodes.elems[2].nodeIds[6] = nodes[9];
+  facesWithNodes.elems[2].nodeIds[7] = nodes[12];
+  facesWithNodes.elems[2].nbNodes = 8;
+  facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_QUAD;
+
+  facesWithNodes.elems[3].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[3].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[3].nodeIds[2] = nodes[2];
+  facesWithNodes.elems[3].nodeIds[3] = nodes[6];
+  facesWithNodes.elems[3].nodeIds[4] = nodes[7];
+  facesWithNodes.elems[3].nodeIds[5] = nodes[8];
+  facesWithNodes.elems[3].nbNodes = 6;
+  facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_TRIANGLE;
+
+  facesWithNodes.elems[4].nodeIds[0] = nodes[3];
+  facesWithNodes.elems[4].nodeIds[1] = nodes[4];
+  facesWithNodes.elems[4].nodeIds[2] = nodes[5];
+  facesWithNodes.elems[4].nodeIds[3] = nodes[9];
+  facesWithNodes.elems[4].nodeIds[4] = nodes[10];
+  facesWithNodes.elems[4].nodeIds[5] = nodes[11];
+  facesWithNodes.elems[4].nbNodes = 6;
+  facesWithNodes.elems[4].vtkType = VTK_QUADRATIC_TRIANGLE;
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_DownHexa::SMDS_DownHexa(SMDS_UnstructuredGrid *grid) :
+  SMDS_Down3D(grid, 6)
+{
+  _cellTypes.push_back(VTK_QUAD);
+  _cellTypes.push_back(VTK_QUAD);
+  _cellTypes.push_back(VTK_QUAD);
+  _cellTypes.push_back(VTK_QUAD);
+  _cellTypes.push_back(VTK_QUAD);
+  _cellTypes.push_back(VTK_QUAD);
+}
+
+SMDS_DownHexa::~SMDS_DownHexa()
+{
+}
+
+void SMDS_DownHexa::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
+{
+  set<int> setNodes;
+  setNodes.clear();
+  for (int i = 0; i < orderedNodes.size(); i++)
+    setNodes.insert(orderedNodes[i]);
+  //MESSAGE("cellId = " << cellId);
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
+
+  set<int> tofind;
+//int ids[24] = { 0, 1, 2, 3,  7, 6, 5, 4,  4, 0, 3, 7,  5, 1, 0, 4,  6, 2, 1, 5,  7, 3, 2, 6};
+  int ids[24] = { 3, 2, 1, 0,  4, 5, 6, 7,  7, 3, 0, 4,  4, 0, 1, 5,  5, 1, 2, 6,  6, 2, 3, 7};
+  for (int k = 0; k < 6; k++) // loop on the 6 faces
+    {
+      tofind.clear();
+      for (int i = 0; i < 4; i++)
+        tofind.insert(nodes[ids[4 * k + i]]); // node ids of the face i
+      if (setNodes == tofind)
+        {
+          for (int i = 0; i < 4; i++)
+            orderedNodes[i] = nodes[ids[4 * k + i]];
+          return;
+        }
+    }
+  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
+  MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2] << " " << orderedNodes[3]);
+  MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
+  MESSAGE(nodes[4] << " " << nodes[5] << " " << nodes[6] << " " << nodes[7]);
+}
+
+void SMDS_DownHexa::addDownCell(int cellId, int lowCellId, unsigned char aType)
+{
+  //ASSERT((cellId >=0)&& (cellId < _maxId));
+  int *faces = &_cellIds[_nbDownCells * cellId];
+  for (int i = 0; i < _nbDownCells; i++)
+    {
+      if (faces[i] < 0)
+        {
+          faces[i] = lowCellId;
+          return;
+        }
+      if (faces[i] == lowCellId)
+        return;
+    }
+  ASSERT(0);
+  // MESSAGE("-------------------------------------> trop de faces ! " << cellId << " " << lowCellId);
+}
+
+/*! Create a list of faces described by a vtk Type and  an ordered set of Node Id's
+ * The hexahedron is defined by the eight points (0-7), where (0,1,2,3) is the base
+ * of the hexahedron which, using the right hand rule, forms a quadrilateral whose normal
+ * points in the direction of the opposite face (4,5,6,7).
+ * @see vtkHexahedron.h in Filtering
+ * @param cellId volumeId in vtkUnstructuredGrid
+ * @param facesWithNodes vector of face descriptors to be filled
+ */
+void SMDS_DownHexa::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
+{
+  // --- find point id's of the volume
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(cellId, npts, nodes);
+
+  // --- create all the ordered list of node id's for each face
+
+  facesWithNodes.nbElems = 6;
+
+  facesWithNodes.elems[0].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[0].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[0].nodeIds[2] = nodes[2];
+  facesWithNodes.elems[0].nodeIds[3] = nodes[3];
+  facesWithNodes.elems[0].nbNodes = 4;
+  facesWithNodes.elems[0].vtkType = VTK_QUAD;
+
+  facesWithNodes.elems[1].nodeIds[0] = nodes[4];
+  facesWithNodes.elems[1].nodeIds[1] = nodes[5];
+  facesWithNodes.elems[1].nodeIds[2] = nodes[6];
+  facesWithNodes.elems[1].nodeIds[3] = nodes[7];
+  facesWithNodes.elems[1].nbNodes = 4;
+  facesWithNodes.elems[1].vtkType = VTK_QUAD;
+
+  facesWithNodes.elems[2].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[2].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[2].nodeIds[2] = nodes[5];
+  facesWithNodes.elems[2].nodeIds[3] = nodes[4];
+  facesWithNodes.elems[2].nbNodes = 4;
+  facesWithNodes.elems[2].vtkType = VTK_QUAD;
+
+  facesWithNodes.elems[3].nodeIds[0] = nodes[1];
+  facesWithNodes.elems[3].nodeIds[1] = nodes[2];
+  facesWithNodes.elems[3].nodeIds[2] = nodes[6];
+  facesWithNodes.elems[3].nodeIds[3] = nodes[5];
+  facesWithNodes.elems[3].nbNodes = 4;
+  facesWithNodes.elems[3].vtkType = VTK_QUAD;
+
+  facesWithNodes.elems[4].nodeIds[0] = nodes[2];
+  facesWithNodes.elems[4].nodeIds[1] = nodes[6];
+  facesWithNodes.elems[4].nodeIds[2] = nodes[7];
+  facesWithNodes.elems[4].nodeIds[3] = nodes[3];
+  facesWithNodes.elems[4].nbNodes = 4;
+  facesWithNodes.elems[4].vtkType = VTK_QUAD;
+
+  facesWithNodes.elems[5].nodeIds[0] = nodes[3];
+  facesWithNodes.elems[5].nodeIds[1] = nodes[7];
+  facesWithNodes.elems[5].nodeIds[2] = nodes[4];
+  facesWithNodes.elems[5].nodeIds[3] = nodes[0];
+  facesWithNodes.elems[5].nbNodes = 4;
+  facesWithNodes.elems[5].vtkType = VTK_QUAD;
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_DownQuadHexa::SMDS_DownQuadHexa(SMDS_UnstructuredGrid *grid) :
+  SMDS_Down3D(grid, 6)
+{
+  _cellTypes.push_back(VTK_QUADRATIC_QUAD);
+  _cellTypes.push_back(VTK_QUADRATIC_QUAD);
+  _cellTypes.push_back(VTK_QUADRATIC_QUAD);
+  _cellTypes.push_back(VTK_QUADRATIC_QUAD);
+  _cellTypes.push_back(VTK_QUADRATIC_QUAD);
+  _cellTypes.push_back(VTK_QUADRATIC_QUAD);
+}
+
+SMDS_DownQuadHexa::~SMDS_DownQuadHexa()
+{
+}
+
+void SMDS_DownQuadHexa::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
+{
+  set<int> setNodes;
+  setNodes.clear();
+  for (int i = 0; i < orderedNodes.size(); i++)
+    setNodes.insert(orderedNodes[i]);
+  //MESSAGE("cellId = " << cellId);
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
+
+  set<int> tofind;
+  //int ids[24] = { 3, 2, 1, 0,  4, 5, 6, 7,  7, 3, 0, 4,  4, 0, 1, 5,  5, 1, 2, 6,  6, 2, 3, 7};
+  int ids[48] = { 3, 2, 1, 0,10, 9, 8,11,   4, 5, 6, 7,12,13,14,15,   7, 3, 0, 4,19,11,16,15,
+                  4, 0, 1, 5,16, 8,17,12,   5, 1, 2, 6,17, 9,18,13,   6, 2, 3, 7,18,10,19,14};
+  for (int k = 0; k < 6; k++)
+    {
+      tofind.clear();
+      for (int i = 0; i < 8; i++)
+        tofind.insert(nodes[ids[8 * k + i]]);
+      if (setNodes == tofind)
+        {
+          for (int i = 0; i < 8; i++)
+            orderedNodes[i] = nodes[ids[8 * k + i]];
+          return;
+        }
+    }
+  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
+  MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2] << " " << orderedNodes[3]);
+  MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
+}
+
+void SMDS_DownQuadHexa::addDownCell(int cellId, int lowCellId, unsigned char aType)
+{
+  //ASSERT((cellId >=0)&& (cellId < _maxId));
+  int *faces = &_cellIds[_nbDownCells * cellId];
+  for (int i = 0; i < _nbDownCells; i++)
+    {
+      if (faces[i] < 0)
+        {
+          faces[i] = lowCellId;
+          return;
+        }
+      if (faces[i] == lowCellId)
+        return;
+    }
+  ASSERT(0);
+}
+
+/*! Create a list of faces described by a vtk Type and  an ordered set of Node Id's
+ * The ordering of the twenty points defining the quadratic hexahedron cell is point id's (0-7,8-19)
+ * where point id's 0-7 are the eight corner vertices of the cube, followed by twelve mid-edge nodes (8-19).
+ * Note that these mid-edge nodes lie on the edges defined by
+ * (0,1), (1,2), (2,3), (3,0), (4,5), (5,6), (6,7), (7,4), (0,4), (1,5), (2,6), (3,7).
+ * @see vtkQuadraticHexahedron.h in Filtering
+ * @param cellId volumeId in vtkUnstructuredGrid
+ * @param facesWithNodes vector of face descriptors to be filled
+ */
+void SMDS_DownQuadHexa::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
+{
+  // --- find point id's of the volume
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(cellId, npts, nodes);
+
+  // --- create all the ordered list of node id's for each face
+
+  facesWithNodes.nbElems = 6;
+
+  facesWithNodes.elems[0].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[0].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[0].nodeIds[2] = nodes[2];
+  facesWithNodes.elems[0].nodeIds[3] = nodes[3];
+  facesWithNodes.elems[0].nodeIds[4] = nodes[8];
+  facesWithNodes.elems[0].nodeIds[5] = nodes[9];
+  facesWithNodes.elems[0].nodeIds[6] = nodes[10];
+  facesWithNodes.elems[0].nodeIds[7] = nodes[11];
+  facesWithNodes.elems[0].nbNodes = 8;
+  facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_QUAD;
+
+  facesWithNodes.elems[1].nodeIds[0] = nodes[4];
+  facesWithNodes.elems[1].nodeIds[1] = nodes[5];
+  facesWithNodes.elems[1].nodeIds[2] = nodes[6];
+  facesWithNodes.elems[1].nodeIds[3] = nodes[7];
+  facesWithNodes.elems[1].nodeIds[4] = nodes[12];
+  facesWithNodes.elems[1].nodeIds[5] = nodes[13];
+  facesWithNodes.elems[1].nodeIds[6] = nodes[14];
+  facesWithNodes.elems[1].nodeIds[7] = nodes[15];
+  facesWithNodes.elems[1].nbNodes = 8;
+  facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_QUAD;
+
+  facesWithNodes.elems[2].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[2].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[2].nodeIds[2] = nodes[5];
+  facesWithNodes.elems[2].nodeIds[3] = nodes[4];
+  facesWithNodes.elems[2].nodeIds[4] = nodes[8];
+  facesWithNodes.elems[2].nodeIds[5] = nodes[17];
+  facesWithNodes.elems[2].nodeIds[6] = nodes[12];
+  facesWithNodes.elems[2].nodeIds[7] = nodes[16];
+  facesWithNodes.elems[2].nbNodes = 8;
+  facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_QUAD;
+
+  facesWithNodes.elems[3].nodeIds[0] = nodes[1];
+  facesWithNodes.elems[3].nodeIds[1] = nodes[2];
+  facesWithNodes.elems[3].nodeIds[2] = nodes[6];
+  facesWithNodes.elems[3].nodeIds[3] = nodes[5];
+  facesWithNodes.elems[3].nodeIds[4] = nodes[9];
+  facesWithNodes.elems[3].nodeIds[5] = nodes[18];
+  facesWithNodes.elems[3].nodeIds[6] = nodes[13];
+  facesWithNodes.elems[3].nodeIds[7] = nodes[17];
+  facesWithNodes.elems[3].nbNodes = 8;
+  facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_QUAD;
+
+  facesWithNodes.elems[4].nodeIds[0] = nodes[2];
+  facesWithNodes.elems[4].nodeIds[1] = nodes[6];
+  facesWithNodes.elems[4].nodeIds[2] = nodes[7];
+  facesWithNodes.elems[4].nodeIds[3] = nodes[3];
+  facesWithNodes.elems[4].nodeIds[4] = nodes[18];
+  facesWithNodes.elems[4].nodeIds[5] = nodes[14];
+  facesWithNodes.elems[4].nodeIds[6] = nodes[19];
+  facesWithNodes.elems[4].nodeIds[7] = nodes[10];
+  facesWithNodes.elems[4].nbNodes = 8;
+  facesWithNodes.elems[4].vtkType = VTK_QUADRATIC_QUAD;
+
+  facesWithNodes.elems[5].nodeIds[0] = nodes[3];
+  facesWithNodes.elems[5].nodeIds[1] = nodes[7];
+  facesWithNodes.elems[5].nodeIds[2] = nodes[4];
+  facesWithNodes.elems[5].nodeIds[3] = nodes[0];
+  facesWithNodes.elems[5].nodeIds[4] = nodes[19];
+  facesWithNodes.elems[5].nodeIds[5] = nodes[15];
+  facesWithNodes.elems[5].nodeIds[6] = nodes[16];
+  facesWithNodes.elems[5].nodeIds[7] = nodes[11];
+  facesWithNodes.elems[5].nbNodes = 8;
+  facesWithNodes.elems[5].vtkType = VTK_QUADRATIC_QUAD;
+}
+
+// ---------------------------------------------------------------------------
+
diff --git a/src/SMDS/SMDS_Downward.hxx b/src/SMDS/SMDS_Downward.hxx
new file mode 100644 (file)
index 0000000..56854fd
--- /dev/null
@@ -0,0 +1,381 @@
+// Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+// File: SMDS_Downward.hxx
+// Created: Jun 3, 2010
+// Author: prascle
+
+#ifndef SMDS_DOWNWARD_HXX_
+#define SMDS_DOWNWARD_HXX_
+
+#include "SMDS_UnstructuredGrid.hxx"
+
+#include <vector>
+#include <set>
+
+typedef struct
+{
+  int nodeIds[8]; //!< max number of nodes in a face or edge: quad quad = 8
+  int nbNodes;
+  unsigned char vtkType;
+} ElemByNodesType; // TODO resize for polyhedrons
+
+typedef struct
+{
+  ElemByNodesType elems[6]; //!< max number of faces in a volume or edges in a face : hexahedron = 6
+  int nbElems;
+} ListElemByNodesType; // TODO resize for polyhedrons
+
+class DownIdType
+{
+public:
+  DownIdType(int a, unsigned char b) :
+    cellId(a), cellType(b)
+  {
+  }
+  int cellId;
+  unsigned char cellType;
+};
+
+struct DownIdCompare
+{
+  bool operator ()(const DownIdType e1, const DownIdType e2) const
+  {
+    if (e1.cellId == e2.cellId)
+      return (e1.cellType < e2.cellType);
+    else
+      return (e1.cellId < e2.cellId);
+  }
+};
+
+class SMDS_Downward
+{
+  friend class SMDS_UnstructuredGrid;
+  friend class SMDS_Down2D;
+  friend class SMDS_Down3D;
+public:
+  virtual int getNumberOfDownCells(int cellId);
+  virtual const int* getDownCells(int cellId);
+  virtual const unsigned char* getDownTypes(int cellId);
+  virtual int getNumberOfUpCells(int cellId) = 0;
+  virtual const int* getUpCells(int cellId) = 0;
+  virtual const unsigned char* getUpTypes(int cellId) = 0;
+  virtual void getNodeIds(int cellId, std::set<int>& nodeSet) = 0;
+  virtual int getNodes(int cellId, int* nodevec) {return 0; }
+  virtual void getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes) {};
+  int getVtkCellId(int cellId)
+  {
+    return _vtkCellIds[cellId];
+  }
+  int getMaxId()
+  {
+    return _maxId;
+  }
+  static int getCellDimension(unsigned char cellType);
+protected:
+  SMDS_Downward(SMDS_UnstructuredGrid *grid, int nbDownCells);
+  ~SMDS_Downward();
+  int addCell(int vtkId = -1);
+  virtual void initCell(int cellId);
+  virtual void allocate(int nbElems) = 0;
+  virtual void compactStorage() = 0;
+  virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); //!< Id's are downward connectivity id's
+  virtual void addUpCell(int cellId, int upCellId, unsigned char aType); //!< Id's are downward connectivity id's
+  virtual int getNodeSet(int cellId, int* nodeSet);
+
+  SMDS_UnstructuredGrid* _grid;
+  int _maxId;
+  int _nbDownCells; //!< the same number for all cells of a derived class
+  std::vector<int> _cellIds; //!< growing size: all the down cell id's, size = _maxId * _nbDownCells
+  std::vector<int> _vtkCellIds; //!< growing size: size = _maxId, either vtkId or -1
+  std::vector<unsigned char> _cellTypes; //!< fixed size: the same vector for all cells of a derived class
+
+  static std::vector<int> _cellDimension; //!< conversion table: type --> dimension
+};
+
+class SMDS_Down1D: public SMDS_Downward
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+  virtual int getNumberOfUpCells(int cellId);
+  virtual const int* getUpCells(int cellId);
+  virtual const unsigned char* getUpTypes(int cellId);
+  virtual void getNodeIds(int cellId, std::set<int>& nodeSet);
+  virtual int getNodes(int cellId, int* nodevec) { return getNodeSet(cellId, nodevec); }
+protected:
+  SMDS_Down1D(SMDS_UnstructuredGrid *grid, int nbDownCells);
+  ~SMDS_Down1D();
+  virtual void initCell(int cellId);
+  virtual void allocate(int nbElems);
+  virtual void compactStorage();
+  virtual void addUpCell(int cellId, int upCellId, unsigned char aType); //!< Id's are downward connectivity id's
+  virtual int getNodeSet(int cellId, int* nodeSet);
+  void setNodes(int cellId, int vtkId);
+  void setNodes(int cellId, const int* nodeIds);
+  int computeVtkCells(int cellId, std::vector<int>& vtkIds);
+  int computeVtkCells(int* pts, std::vector<int>& vtkIds);
+  int computeFaces(int cellId, int* vtkIds, int nbcells, int* downFaces, unsigned char* downTypes);
+  int computeFaces(int* pts, int* vtkIds, int nbcells, int* downFaces, unsigned char* downTypes);
+
+  std::vector<std::vector<int> > _upCellIdsVector; //!< the number of faces sharing an edge is not known
+  std::vector<std::vector<unsigned char> > _upCellTypesVector; //!< the number of faces sharing an edge is not known
+  std::vector<int> _upCellIds; //!< compacted storage after connectivity calculation
+  std::vector<unsigned char> _upCellTypes; //!< compacted storage after connectivity calculation
+  std::vector<int> _upCellIndex; //!< compacted storage after connectivity calculation
+};
+
+class SMDS_Down2D: public SMDS_Downward
+{
+  friend class SMDS_UnstructuredGrid;
+  friend class SMDS_Down1D;
+public:
+  virtual int getNumberOfUpCells(int cellId);
+  virtual const int* getUpCells(int cellId);
+  virtual const unsigned char* getUpTypes(int cellId);
+  virtual void getNodeIds(int cellId, std::set<int>& nodeSet);
+protected:
+  SMDS_Down2D(SMDS_UnstructuredGrid *grid, int nbDownCells);
+  ~SMDS_Down2D();
+  virtual void allocate(int nbElems);
+  virtual void compactStorage();
+  virtual void addUpCell(int cellId, int upCellId, unsigned char aType);
+  virtual void computeEdgesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) = 0;
+  virtual int getNodeSet(int cellId, int* nodeSet);
+  int computeVolumeIds(int cellId, int* ids);
+  int computeVolumeIds(ElemByNodesType& faceByNodes, int* ids);
+  int computeVolumeIdsFromNodesFace(int* nodes, int nbNodes, int* ids);
+  void setTempNodes(int cellId, int vtkId);
+  void setTempNodes(int cellId, ElemByNodesType& faceByNodes);
+  bool isInFace(int cellId, int *pts, int npts);
+  int FindEdgeByNodes(int cellId, ElemByNodesType& edgeByNodes);
+
+  std::vector<int> _upCellIds; //!< 2 volumes max. per face
+  std::vector<unsigned char> _upCellTypes; //!< 2 volume types per face
+  std::vector<int> _tempNodes; //!< temporary storage of nodes, until downward connectivity completion
+  int _nbNodes; //!< number of nodes in a face
+};
+
+class SMDS_Down3D: public SMDS_Downward
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+  virtual int getNumberOfUpCells(int cellId);
+  virtual const int* getUpCells(int cellId);
+  virtual const unsigned char* getUpTypes(int cellId);
+  virtual void getNodeIds(int cellId, std::set<int>& nodeSet);
+protected:
+  SMDS_Down3D(SMDS_UnstructuredGrid *grid, int nbDownCells);
+  ~SMDS_Down3D();
+  virtual void allocate(int nbElems);
+  virtual void compactStorage();
+  virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) = 0;
+  int FindFaceByNodes(int cellId, ElemByNodesType& faceByNodes);
+};
+
+class SMDS_DownEdge: public SMDS_Down1D
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+protected:
+  SMDS_DownEdge(SMDS_UnstructuredGrid *grid);
+  ~SMDS_DownEdge();
+};
+
+class SMDS_DownQuadEdge: public SMDS_Down1D
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+protected:
+  SMDS_DownQuadEdge(SMDS_UnstructuredGrid *grid);
+  ~SMDS_DownQuadEdge();
+};
+
+class SMDS_DownTriangle: public SMDS_Down2D
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+protected:
+  SMDS_DownTriangle(SMDS_UnstructuredGrid *grid);
+  ~SMDS_DownTriangle();
+  virtual void computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes);
+  virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); //!< Id's are downward connectivity id's
+};
+
+class SMDS_DownQuadTriangle: public SMDS_Down2D
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+protected:
+  SMDS_DownQuadTriangle(SMDS_UnstructuredGrid *grid);
+  ~SMDS_DownQuadTriangle();
+  virtual void computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes);
+  virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); //!< Id's are downward connectivity id's
+};
+
+class SMDS_DownQuadrangle: public SMDS_Down2D
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+protected:
+  SMDS_DownQuadrangle(SMDS_UnstructuredGrid *grid);
+  ~SMDS_DownQuadrangle();
+  virtual void computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes);
+  virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); //!< Id's are downward connectivity id's
+};
+
+class SMDS_DownQuadQuadrangle: public SMDS_Down2D
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+protected:
+  SMDS_DownQuadQuadrangle(SMDS_UnstructuredGrid *grid);
+  ~SMDS_DownQuadQuadrangle();
+  virtual void computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes);
+  virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); //!< Id's are downward connectivity id's
+};
+
+//class SMDS_DownPolygon: public SMDS_Down2D
+//{
+//public:
+//  SMDS_DownPolygon(SMDS_UnstructuredGrid *grid);
+//  ~SMDS_DownPolygon();
+//protected:
+//};
+
+//class SMDS_DownQuadPolygon: public SMDS_Down2D
+//{
+//public:
+//  SMDS_DownQuadPolygon(SMDS_UnstructuredGrid *grid);
+//  ~SMDS_DownQuadPolygon();
+//protected:
+//};
+
+class SMDS_DownTetra: public SMDS_Down3D
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+  virtual void getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes);
+protected:
+  SMDS_DownTetra(SMDS_UnstructuredGrid *grid);
+  ~SMDS_DownTetra();
+  virtual void addDownCell(int cellId, int lowCellId, unsigned char aType);
+  virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes);
+};
+
+class SMDS_DownQuadTetra: public SMDS_Down3D
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+  virtual void getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes);
+protected:
+  SMDS_DownQuadTetra(SMDS_UnstructuredGrid *grid);
+  ~SMDS_DownQuadTetra();
+  virtual void addDownCell(int cellId, int lowCellId, unsigned char aType);
+  virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes);
+};
+
+class SMDS_DownPyramid: public SMDS_Down3D
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+  virtual void getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes);
+protected:
+  SMDS_DownPyramid(SMDS_UnstructuredGrid *grid);
+  ~SMDS_DownPyramid();
+  virtual void addDownCell(int cellId, int lowCellId, unsigned char aType);
+  virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes);
+};
+
+class SMDS_DownQuadPyramid: public SMDS_Down3D
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+  virtual void getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes);
+protected:
+  SMDS_DownQuadPyramid(SMDS_UnstructuredGrid *grid);
+  ~SMDS_DownQuadPyramid();
+  virtual void addDownCell(int cellId, int lowCellId, unsigned char aType);
+  virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes);
+};
+
+class SMDS_DownPenta: public SMDS_Down3D
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+  virtual void getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes);
+protected:
+  SMDS_DownPenta(SMDS_UnstructuredGrid *grid);
+  ~SMDS_DownPenta();
+  virtual void addDownCell(int cellId, int lowCellId, unsigned char aType);
+  virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes);
+};
+
+class SMDS_DownQuadPenta: public SMDS_Down3D
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+  virtual void getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes);
+protected:
+  SMDS_DownQuadPenta(SMDS_UnstructuredGrid *grid);
+  ~SMDS_DownQuadPenta();
+  virtual void addDownCell(int cellId, int lowCellId, unsigned char aType);
+  virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes);
+};
+
+class SMDS_DownHexa: public SMDS_Down3D
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+  virtual void getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes);
+protected:
+  SMDS_DownHexa(SMDS_UnstructuredGrid *grid);
+  ~SMDS_DownHexa();
+  virtual void addDownCell(int cellId, int lowCellId, unsigned char aType);
+  virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes);
+};
+
+class SMDS_DownQuadHexa: public SMDS_Down3D
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+  virtual void getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes);
+protected:
+  SMDS_DownQuadHexa(SMDS_UnstructuredGrid *grid);
+  ~SMDS_DownQuadHexa();
+  virtual void addDownCell(int cellId, int lowCellId, unsigned char aType);
+  virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes);
+};
+
+//class SMDS_DownPolyhedra: public SMDS_Down3D
+//{
+//public:
+//  SMDS_DownPolyhedra(SMDS_UnstructuredGrid *grid);
+//  ~SMDS_DownPolyhedra();
+//protected:
+//};
+
+//class SMDS_DownQuadPolyhedra: public SMDS_Down3D
+//{
+//public:
+//  SMDS_DownQuadPolyhedra(SMDS_UnstructuredGrid *grid);
+//  ~SMDS_DownQuadPolyhedra();
+//protected:
+//};
+
+#endif /* SMDS_DOWNWARD_HXX_ */
index 1317d2b75e899c2ba359c788b2d8c6b5a1509d6e..dcc47f72ac2186e453ebb725d59b9cd02da8246a 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_EdgePosition.cxx
 //  Author : Jean-Michel BOULCOURT
@@ -35,33 +36,23 @@ using namespace std;
 //purpose  : 
 //=======================================================================
 
-SMDS_EdgePosition::SMDS_EdgePosition(const int aEdgeId,
-       const double aUParam):SMDS_Position(aEdgeId), myUParameter(aUParam)
-{
-}
-
-//=======================================================================
-//function : Coords
-//purpose  : 
-//=======================================================================
-
-const double *SMDS_EdgePosition::Coords() const
+SMDS_EdgePosition::SMDS_EdgePosition(const double aUParam): myUParameter(aUParam)
 {
-       static double origin[]={0,0,0};
-       MESSAGE("SMDS_EdgePosition::Coords not implemented");
-       return origin;
+  //MESSAGE("********************************* SMDS_EdgePosition " << myUParameter);
 }
 
 /**
 */
 SMDS_TypeOfPosition SMDS_EdgePosition::GetTypeOfPosition() const
 {
-       return SMDS_TOP_EDGE;
+  //MESSAGE("###################################### SMDS_EdgePosition::GetTypeOfPosition");
+        return SMDS_TOP_EDGE;
 }
 
 void SMDS_EdgePosition::SetUParameter(double aUparam)
 {
-       myUParameter = aUparam;
+  //MESSAGE("############################### SMDS_EdgePosition::SetUParameter " << aUparam);
+        myUParameter = aUparam;
 }
 
 //=======================================================================
@@ -71,5 +62,6 @@ void SMDS_EdgePosition::SetUParameter(double aUparam)
 
 double SMDS_EdgePosition::GetUParameter() const 
 {
-       return myUParameter;
+  //MESSAGE("########################## SMDS_EdgePosition::GetUParameter " << myUParameter);
+        return myUParameter;
 }
index f6005e947138a9deaee714dccac98723626a7538..ced2e940322910bf0e9be81aa80d22347ed641ff 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_EdgePosition.hxx
 //  Module : SMESH
@@ -34,15 +35,14 @@ class SMDS_EXPORT SMDS_EdgePosition:public SMDS_Position
 {
 
   public:
-       SMDS_EdgePosition(const int aEdgeId=0, const double aUParam=0);
-       const virtual double * Coords() const;
-       SMDS_TypeOfPosition GetTypeOfPosition() const;
-       void SetUParameter(double aUparam);
-       double GetUParameter() const;
+        SMDS_EdgePosition(const double aUParam=0);
+        SMDS_TypeOfPosition GetTypeOfPosition() const;
+        void SetUParameter(double aUparam);
+        double GetUParameter() const;
 
   private:
 
-       double myUParameter;
+        double myUParameter;
 
 };
 
index 511426e5d89151c953d855e9e959b3b63d632463..129d8f6c4862d81528b48e9d74635cd713a744d2 100755 (executable)
@@ -1,29 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_MeshElement.hxx
 //  Module : SMESH
-// Created:   12.01.05 18:02:52
-// Author:    Michael Sazonov
+//  Created:   12.01.05 18:02:52
+//  Author:    Michael Sazonov
 //
 #ifndef SMDS_ElemIterator_HeaderFile
 #define SMDS_ElemIterator_HeaderFile
@@ -33,6 +34,7 @@
 
 class SMDS_MeshElement;
 class SMDS_MeshNode;
+class SMDS_Mesh0DElement;
 class SMDS_MeshEdge;
 class SMDS_MeshFace;
 class SMDS_MeshVolume;
@@ -43,6 +45,9 @@ typedef boost::shared_ptr<SMDS_Iterator<const SMDS_MeshElement *> > SMDS_ElemIte
 typedef SMDS_Iterator<const SMDS_MeshNode *> SMDS_NodeIterator;
 typedef boost::shared_ptr<SMDS_Iterator<const SMDS_MeshNode *> > SMDS_NodeIteratorPtr;
 
+typedef SMDS_Iterator<const SMDS_Mesh0DElement *> SMDS_0DElementIterator;
+typedef boost::shared_ptr<SMDS_Iterator<const SMDS_Mesh0DElement *> > SMDS_0DElementIteratorPtr;
+
 typedef SMDS_Iterator<const SMDS_MeshEdge *> SMDS_EdgeIterator;
 typedef boost::shared_ptr<SMDS_Iterator<const SMDS_MeshEdge *> > SMDS_EdgeIteratorPtr;
 
index 5b5483022691d541dfaae7d2376a10021f62ca87..a03bc0bf7d3d012d485236aae5025e11a3ba3189 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //
 #ifdef _MSC_VER
@@ -28,6 +29,7 @@
 #include "SMDS_FaceOfEdges.hxx"
 #include "SMDS_IteratorOfElements.hxx"
 #include "SMDS_MeshNode.hxx"
+#include "utilities.h"
 
 using namespace std;
 
@@ -38,12 +40,12 @@ using namespace std;
 
 int SMDS_FaceOfEdges::NbEdges() const
 {
-       return myNbEdges;
+        return myNbEdges;
 }
 
 int SMDS_FaceOfEdges::NbFaces() const
 {
-       return 1;
+        return 1;
 }
 //=======================================================================
 //function : Print
@@ -52,15 +54,15 @@ int SMDS_FaceOfEdges::NbFaces() const
 
 void SMDS_FaceOfEdges::Print(ostream & OS) const
 {
-       OS << "face <" << GetID() << " > : ";
-       int i;
-       for (i = 0; i < NbEdges() - 1; i++) OS << myEdges[i] << ",";
-       OS << myEdges[i] << ") " << endl;
+        OS << "face <" << GetID() << " > : ";
+        int i;
+        for (i = 0; i < NbEdges() - 1; i++) OS << myEdges[i] << ",";
+        OS << myEdges[i] << ") " << endl;
 }
 
 SMDSAbs_ElementType SMDS_FaceOfEdges::GetType() const
 {
-       return SMDSAbs_Face;
+        return SMDSAbs_Face;
 }
 
 //=======================================================================
@@ -86,7 +88,7 @@ class SMDS_FaceOfEdges_MyIterator:public SMDS_ElemIterator
   {
     index++;
     return mySet[index-1];
-  }    
+  }     
 };
 
 SMDS_ElemIteratorPtr SMDS_FaceOfEdges::elementsIterator
@@ -110,11 +112,12 @@ SMDS_FaceOfEdges::SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1,
                                    const SMDS_MeshEdge* edge2,
                                    const SMDS_MeshEdge* edge3)
 {
-       myNbEdges = 3;
-       myEdges[0]=edge1;
-       myEdges[1]=edge2;
-       myEdges[2]=edge3;
-       myEdges[3]=0;
+  //MESSAGE("****************************************************** SMDS_FaceOfEdges");
+        myNbEdges = 3;
+        myEdges[0]=edge1;
+        myEdges[1]=edge2;
+        myEdges[2]=edge3;
+        myEdges[3]=0;
 }
 
 SMDS_FaceOfEdges::SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1,
@@ -122,38 +125,39 @@ SMDS_FaceOfEdges::SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1,
                                    const SMDS_MeshEdge* edge3,
                                    const SMDS_MeshEdge* edge4)
 {
-       myNbEdges = 4;
-       myEdges[0]=edge1;
-       myEdges[1]=edge2;
-       myEdges[2]=edge3;
-       myEdges[3]=edge4;       
+  //MESSAGE("****************************************************** SMDS_FaceOfEdges");
+        myNbEdges = 4;
+        myEdges[0]=edge1;
+        myEdges[1]=edge2;
+        myEdges[2]=edge3;
+        myEdges[3]=edge4;       
 }
 
 /*bool operator<(const SMDS_FaceOfEdges& f1, const SMDS_FaceOfEdges& f2)
 {
-       set<SMDS_MeshNode> set1,set2;
-       SMDS_ElemIteratorPtr it;
-       const SMDS_MeshNode * n;
-
-       it=f1.nodesIterator();
-
-       while(it->more())
-       {
-               n=static_cast<const SMDS_MeshNode *>(it->next());
-               set1.insert(*n);
-       }
-
-       delete it;
-       it=f2.nodesIterator();
-       
-       while(it->more())
-       {       
-               n=static_cast<const SMDS_MeshNode *>(it->next());
-               set2.insert(*n);
-       }
-
-       delete it;
-       return set1<set2;       
+        set<SMDS_MeshNode> set1,set2;
+        SMDS_ElemIteratorPtr it;
+        const SMDS_MeshNode * n;
+
+        it=f1.nodesIterator();
+
+        while(it->more())
+        {
+                n=static_cast<const SMDS_MeshNode *>(it->next());
+                set1.insert(*n);
+        }
+
+        delete it;
+        it=f2.nodesIterator();
+        
+        while(it->more())
+        {       
+                n=static_cast<const SMDS_MeshNode *>(it->next());
+                set2.insert(*n);
+        }
+
+        delete it;
+        return set1<set2;       
 
 }*/
 
@@ -168,12 +172,10 @@ int SMDS_FaceOfEdges::NbNodes() const
  * \brief Return node by its index
  * \param ind - node index
  * \retval const SMDS_MeshNode* - the node
- * 
- * Index is wrapped if it is out of a valid range
  */
 const SMDS_MeshNode* SMDS_FaceOfEdges::GetNode(const int ind) const
 {
-  int index = WrappedIndex( ind );
+  int index = ind;
   for ( int i = 0; i < myNbEdges; ++i ) {
     if ( index >= myEdges[ i ]->NbNodes() )
       index -= myEdges[ i ]->NbNodes();
@@ -183,3 +185,12 @@ const SMDS_MeshNode* SMDS_FaceOfEdges::GetNode(const int ind) const
   return 0;
 }
 
+SMDSAbs_EntityType SMDS_FaceOfEdges::GetEntityType() const
+{
+  return myNbEdges == 3 ? SMDSEntity_Triangle : SMDSEntity_Quadrangle;
+}
+
+SMDSAbs_GeometryType SMDS_FaceOfEdges::GetGeomType() const
+{
+  return myNbEdges == 3 ? SMDSGeom_TRIANGLE : SMDSGeom_QUADRANGLE;
+}
index 23659b85cd6326c5bb86e6db29e17fb24ef227af..9eb81b1f00eb868b345a30104401f74aeae12513 100644 (file)
@@ -1,25 +1,26 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-//  SMESH SMDS : implementaion of Salome mesh data structure
+
+//  SMESH SMDS : implementation of Salome mesh data structure
 //
 #ifndef _SMDS_FaceOfEdges_HeaderFile
 #define _SMDS_FaceOfEdges_HeaderFile
 class SMDS_EXPORT SMDS_FaceOfEdges:public SMDS_MeshFace
 {
   public:
-       void Print(std::ostream & OS) const;
-       SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1,
+        void Print(std::ostream & OS) const;
+        SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1,
                          const SMDS_MeshEdge* edge2,
                          const SMDS_MeshEdge* edge3);
-       SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1,
+        SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1,
                          const SMDS_MeshEdge* edge2,
                          const SMDS_MeshEdge* edge3,
                          const SMDS_MeshEdge* edge4);
-               
-       SMDSAbs_ElementType GetType() const;
-       int NbNodes() const;
-       int NbEdges() const;
-       int NbFaces() const;
-//     friend bool operator<(const SMDS_FaceOfEdges& e1, const SMDS_FaceOfEdges& e2);
-
-
-  /*!
-   * \brief Return node by its index
-    * \param ind - node index
-    * \retval const SMDS_MeshNode* - the node
-   * 
-   * Index is wrapped if it is out of a valid range
-   */
-  virtual const SMDS_MeshNode* GetNode(const int ind) const;
+                
+        virtual SMDSAbs_ElementType  GetType() const;
+        virtual SMDSAbs_EntityType   GetEntityType() const;
+        virtual SMDSAbs_GeometryType GetGeomType() const;
+        virtual bool ChangeNodes(const SMDS_MeshNode* nodes[],
+                                 const int            nbNodes) {return false;}
+        virtual int NbNodes() const;
+        virtual int NbEdges() const;
+        virtual int NbFaces() const;
+        virtual const SMDS_MeshNode* GetNode(const int ind) const;
 
   protected:
-       SMDS_ElemIteratorPtr
-               elementsIterator(SMDSAbs_ElementType type) const;
+        virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const;
 
   private:
-       const SMDS_MeshEdge* myEdges[4];
+        const SMDS_MeshEdge* myEdges[4];
         int                  myNbEdges;
 
 };
index 645e934ddf777bc3539ab332b57b2203f97aa04c..9d05d450531589c03a9c3d27a62083a192a595c9 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //
 #ifdef _MSC_VER
@@ -42,17 +43,17 @@ using namespace std;
 
 int SMDS_FaceOfNodes::NbEdges() const
 {
-       return NbNodes();
+        return NbNodes();
 }
 
 int SMDS_FaceOfNodes::NbFaces() const
 {
-       return 1;
+        return 1;
 }
 
 int SMDS_FaceOfNodes::NbNodes() const
 {
-       return myNbNodes;
+        return myNbNodes;
 }
 
 //=======================================================================
@@ -62,10 +63,10 @@ int SMDS_FaceOfNodes::NbNodes() const
 
 void SMDS_FaceOfNodes::Print(ostream & OS) const
 {
-       OS << "face <" << GetID() << " > : ";
-       int i;
-       for (i = 0; i < NbNodes() - 1; i++) OS << myNodes[i] << ",";
-       OS << myNodes[i] << ") " << endl;
+        OS << "face <" << GetID() << " > : ";
+        int i;
+        for (i = 0; i < NbNodes() - 1; i++) OS << myNodes[i] << ",";
+        OS << myNodes[i] << ") " << endl;
 }
 
 //=======================================================================
@@ -95,7 +96,7 @@ public:
     myElems.reserve( face->NbNodes() );
     for ( int i = 0; i < face->NbNodes(); ++i ) {
       const SMDS_MeshElement* edge =
-        SMDS_Mesh::FindEdge( face->GetNode( i ), face->GetNode( i + 1 ));
+        SMDS_Mesh::FindEdge( face->GetNode( i ), face->GetNodeWrap( i + 1 ));
       if ( edge )
         myElems.push_back( edge );
     }
@@ -132,11 +133,12 @@ SMDS_FaceOfNodes::SMDS_FaceOfNodes(const SMDS_MeshNode* node1,
                                    const SMDS_MeshNode* node2,
                                    const SMDS_MeshNode* node3)
 {
-       myNbNodes = 3;
-       myNodes[0]=node1;
-       myNodes[1]=node2;
-       myNodes[2]=node3;
-       myNodes[3]=0;
+  //MESSAGE("******************************************************* SMDS_FaceOfNodes");
+        myNbNodes = 3;
+        myNodes[0]=node1;
+        myNodes[1]=node2;
+        myNodes[2]=node3;
+        myNodes[3]=0;
 }
 
 SMDS_FaceOfNodes::SMDS_FaceOfNodes(const SMDS_MeshNode* node1,
@@ -144,11 +146,12 @@ SMDS_FaceOfNodes::SMDS_FaceOfNodes(const SMDS_MeshNode* node1,
                                    const SMDS_MeshNode* node3,
                                    const SMDS_MeshNode* node4)
 {
-       myNbNodes = 4;
-       myNodes[0]=node1;
-       myNodes[1]=node2;
-       myNodes[2]=node3;
-       myNodes[3]=node4;       
+  //MESSAGE("******************************************************* SMDS_FaceOfNodes");
+        myNbNodes = 4;
+        myNodes[0]=node1;
+        myNodes[1]=node2;
+        myNodes[2]=node3;
+        myNodes[3]=node4;       
 }
 bool SMDS_FaceOfNodes::ChangeNodes(const SMDS_MeshNode* nodes[],
                                    const int            nbNodes)
@@ -169,39 +172,17 @@ bool SMDS_FaceOfNodes::ChangeNodes(const SMDS_MeshNode* nodes[],
  * \brief Return node by its index
  * \param ind - node index
  * \retval const SMDS_MeshNode* - the node
- * 
- * Index is wrapped if it is out of a valid range
  */
 const SMDS_MeshNode* SMDS_FaceOfNodes::GetNode(const int ind) const
 {
-  return myNodes[ WrappedIndex( ind )];
+  return myNodes[ ind ];
 }
 
-/*bool operator<(const SMDS_FaceOfNodes& f1, const SMDS_FaceOfNodes& f2)
+SMDSAbs_EntityType SMDS_FaceOfNodes::GetEntityType() const
 {
-       set<SMDS_MeshNode> set1,set2;
-       SMDS_ElemIteratorPtr it;
-       const SMDS_MeshNode * n;
-
-       it=f1.nodesIterator();
-
-       while(it->more())
-       {
-               n=static_cast<const SMDS_MeshNode *>(it->next());
-               set1.insert(*n);
-       }
-
-       delete it;
-       it=f2.nodesIterator();
-       
-       while(it->more())
-       {       
-               n=static_cast<const SMDS_MeshNode *>(it->next());
-               set2.insert(*n);
-       }
-
-       delete it;
-       return set1<set2;       
-
-}*/
-
+  return NbNodes() == 3 ? SMDSEntity_Triangle : SMDSEntity_Quadrangle;
+}
+SMDSAbs_GeometryType SMDS_FaceOfNodes::GetGeomType() const
+{
+  return NbNodes() == 3 ? SMDSGeom_TRIANGLE : SMDSGeom_QUADRANGLE;
+}
index bf1fac24cc4c6f7c73f8b99a267775fde59609c5..79b94ba05e4a9342a7f183f1579e02246aeaeba7 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //
 #ifndef _SMDS_FaceOfNodes_HeaderFile
 class SMDS_EXPORT SMDS_FaceOfNodes:public SMDS_MeshFace
 {
   public:
-       void Print(std::ostream & OS) const;
-       SMDS_FaceOfNodes(const SMDS_MeshNode* node1,
+        void Print(std::ostream & OS) const;
+        SMDS_FaceOfNodes(const SMDS_MeshNode* node1,
                          const SMDS_MeshNode* node2,
                          const SMDS_MeshNode* node3);
-       SMDS_FaceOfNodes(const SMDS_MeshNode* node1,
+        SMDS_FaceOfNodes(const SMDS_MeshNode* node1,
                          const SMDS_MeshNode* node2,
                          const SMDS_MeshNode* node3,
                          const SMDS_MeshNode* node4);
         bool ChangeNodes(const SMDS_MeshNode* nodes[],
                          const int            nbNodes);
-       int NbEdges() const;
-       int NbFaces() const;
-       int NbNodes() const;
+        int NbEdges() const;
+        int NbFaces() const;
+        int NbNodes() const;
 
   /*!
    * \brief Return node by its index
     * \param ind - node index
     * \retval const SMDS_MeshNode* - the node
-   * 
-   * Index is wrapped if it is out of a valid range
    */
   virtual const SMDS_MeshNode* GetNode(const int ind) const;
 
+  virtual SMDSAbs_EntityType   GetEntityType() const;
+  virtual SMDSAbs_GeometryType GetGeomType() const;
+
   protected:
-       SMDS_ElemIteratorPtr
-               elementsIterator(SMDSAbs_ElementType type) const;
+        SMDS_ElemIteratorPtr
+                elementsIterator(SMDSAbs_ElementType type) const;
 
   private:
-       const SMDS_MeshNode* myNodes[4];
+        const SMDS_MeshNode* myNodes[4];
         int                  myNbNodes;
 
 };
index 20498554e04d473acfed84767aca92198582ac23..fe37b035aa2837ea84ac39758e99b259321821ab 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_FacePosition.cxx
 //  Author : Jean-Michel BOULCOURT
@@ -35,35 +36,23 @@ using namespace std;
 //purpose  : 
 //=======================================================================
 
-SMDS_FacePosition::SMDS_FacePosition(const int aEdgeId,
-                                    const double aUParam,
-                                    const double aVParam)
-  :SMDS_Position(aEdgeId),
-   myUParameter(aUParam),myVParameter(aVParam)
-{
-}
-
-//=======================================================================
-//function : Coords
-//purpose  : 
-//=======================================================================
-const double *SMDS_FacePosition::Coords() const
+SMDS_FacePosition::SMDS_FacePosition(const double aUParam,
+                                     const double aVParam)
+   : myUParameter(aUParam),myVParameter(aVParam)
 {
-       static double origin[]={0,0,0};
-       MESSAGE("SMDS_EdgePosition::Coords not implemented");
-       return origin;
+  //MESSAGE("******************************************************** SMDS_FacePosition");
 }
 
 /**
 */
 SMDS_TypeOfPosition SMDS_FacePosition::GetTypeOfPosition() const
 {
-       return SMDS_TOP_FACE;
+        return SMDS_TOP_FACE;
 }
 
 void SMDS_FacePosition::SetUParameter(double aUparam)
 {
-       myUParameter = aUparam;
+        myUParameter = aUparam;
 }
 
 //=======================================================================
@@ -73,7 +62,7 @@ void SMDS_FacePosition::SetUParameter(double aUparam)
 
 void SMDS_FacePosition::SetVParameter(double aVparam)
 {
-       myVParameter = aVparam;
+        myVParameter = aVparam;
 }
 
 //=======================================================================
@@ -83,7 +72,7 @@ void SMDS_FacePosition::SetVParameter(double aVparam)
 
 double SMDS_FacePosition::GetUParameter() const 
 {
-       return myUParameter;
+        return myUParameter;
 }
 
 //=======================================================================
@@ -93,5 +82,5 @@ double SMDS_FacePosition::GetUParameter() const
 
 double SMDS_FacePosition::GetVParameter() const 
 {
-       return myVParameter;
+        return myVParameter;
 }
index 425d7cf1c118a5cdbf376470f930e377d124e676..13341baacabccae602a907890dbc94a85545866a 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_FacePosition.hxx
 //  Module : SMESH
@@ -34,17 +35,15 @@ class SMDS_EXPORT SMDS_FacePosition:public SMDS_Position
 {
 
   public:
-       SMDS_FacePosition(int aFaceId=0, double aUParam=0,
-               double aVParam=0);
-       const virtual double * Coords() const;
-       SMDS_TypeOfPosition GetTypeOfPosition() const;
-       void SetUParameter(double aUparam);
-       void SetVParameter(double aVparam);
-       double GetUParameter() const;
-       double GetVParameter() const;
+        SMDS_FacePosition(double aUParam=0, double aVParam=0);
+        SMDS_TypeOfPosition GetTypeOfPosition() const;
+        void SetUParameter(double aUparam);
+        void SetVParameter(double aVparam);
+        double GetUParameter() const;
+        double GetVParameter() const;
 
   private:
-       double myUParameter;
-       double myVParameter;
+        double myUParameter;
+        double myVParameter;
 };
 #endif
index e4e900b5bc722e7fcc96986c0515fc79c5400969..74af6fdc58fc4a05776e308327362fcd913ac6df 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //
 #ifndef _SMDS_Iterator_HeaderFile
 template<typename VALUE> class SMDS_Iterator
 {
   public:
-       /// Return true if and only if there are other object in this iterator
-         virtual bool more()=0;
-       
-       /// Return the current object and step to the next one
-         virtual VALUE next()=0;
-       
-       /// Delete the current element and step to the next one
-       virtual void remove(){}
-       
-       /// Provide virtual destructor just for case if some derived iterator
+        /// Return true if and only if there are other object in this iterator
+          virtual bool more()=0;
+        
+        /// Return the current object and step to the next one
+          virtual VALUE next()=0;
+        
+        /// Delete the current element and step to the next one
+        virtual void remove(){}
+        
+        /// Provide virtual destructor just for case if some derived iterator
         /// must have a destructor
-       virtual ~SMDS_Iterator(){}
+        virtual ~SMDS_Iterator(){}
 };
 
 #endif
index 220e67ac9cdbc24e363e41ec4d742d4d60b5a7c2..761fa55e9958f238a3a046b2e2cde9e729c9a63c 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //
 #ifdef _MSC_VER
 
 bool SMDS_IteratorOfElements::subMore()
 {
-       if((t2Iterator.get()==NULL)||(!t2Iterator->more()))
-       {
-               if(t1Iterator->more())
-               {
-                       t2Iterator=t1Iterator->next()->elementsIterator(myType);
-                       return subMore();
-               }
-               else return false;
-       }
-       else return true;
+        if((t2Iterator.get()==NULL)||(!t2Iterator->more()))
+        {
+                if(t1Iterator->more())
+                {
+                        t2Iterator=t1Iterator->next()->elementsIterator(myType);
+                        return subMore();
+                }
+                else return false;
+        }
+        else return true;
 }
 
 const SMDS_MeshElement * SMDS_IteratorOfElements::subNext()
 {
-       if((t2Iterator.get()==NULL)||(!t2Iterator->more()))
-               if(t1Iterator->more())
-                       t2Iterator=t1Iterator->next()->elementsIterator(myType);
-       return t2Iterator->next();
+        if((t2Iterator.get()==NULL)||(!t2Iterator->more()))
+                if(t1Iterator->more())
+                        t2Iterator=t1Iterator->next()->elementsIterator(myType);
+        return t2Iterator->next();
 }
 
 /////////////////////////////////////////////////////////////////////////////
@@ -61,48 +62,48 @@ SMDS_IteratorOfElements::SMDS_IteratorOfElements(const SMDS_MeshElement * elemen
        myType(type), myElement(element),
        myProxyElement(NULL)
 {
-       while(subMore())
-               alreadyReturnedElements.insert(subNext());
-       itAlreadyReturned= alreadyReturnedElements.begin();
-       switch(myElement->GetType())
-       {
-       case SMDSAbs_Node: 
-       case SMDSAbs_Edge: myReverseIteration=true; break;
-       case SMDSAbs_Face: myReverseIteration=(type==SMDSAbs_Volume); break;
-       default: myReverseIteration=false;
-       }       
+        while(subMore())
+                alreadyReturnedElements.insert(subNext());
+        itAlreadyReturned= alreadyReturnedElements.begin();
+        switch(myElement->GetType())
+        {
+        case SMDSAbs_Node: 
+        case SMDSAbs_Edge: myReverseIteration=true; break;
+        case SMDSAbs_Face: myReverseIteration=(type==SMDSAbs_Volume); break;
+        default: myReverseIteration=false;
+        }       
 }
 
 bool SMDS_IteratorOfElements::more()
 {
-       if(myProxyElement==NULL)
-       {
-               while(itAlreadyReturned!=alreadyReturnedElements.end())
-               {
-                       myProxyElement=*itAlreadyReturned;
-                       itAlreadyReturned++;    
+        if(myProxyElement==NULL)
+        {
+                while(itAlreadyReturned!=alreadyReturnedElements.end())
+                {
+                        myProxyElement=*itAlreadyReturned;
+                        itAlreadyReturned++;    
 
-                       if(myReverseIteration)
-                       {
-                               SMDS_ElemIteratorPtr it=
-                                       myProxyElement->elementsIterator(myElement->GetType());
-                               while(it->more())
-                               {                               
-                                       if(it->next()==myElement) return true;
-                               }
-                       }
-                       else return true;
-               }
-               myProxyElement=NULL;
-               return false;
-       }
-       else return true;
+                        if(myReverseIteration)
+                        {
+                                SMDS_ElemIteratorPtr it=
+                                        myProxyElement->elementsIterator(myElement->GetType());
+                                while(it->more())
+                                {                               
+                                        if(it->next()==myElement) return true;
+                                }
+                        }
+                        else return true;
+                }
+                myProxyElement=NULL;
+                return false;
+        }
+        else return true;
 }
 
 const SMDS_MeshElement * SMDS_IteratorOfElements::next()
 {
-       more();
-       const SMDS_MeshElement *e=myProxyElement;
-       myProxyElement=NULL;
-       return e;
+        more();
+        const SMDS_MeshElement *e=myProxyElement;
+        myProxyElement=NULL;
+        return e;
 }
index 381ff647a442f3f18c8b9d3fd21ac8cf35eb6411..239cb9fb0a94f7c8a6a5532313bf2ab5fafb601a 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //
 #include "SMESH_SMDS.hxx"
@@ -35,22 +36,22 @@ class SMDS_EXPORT SMDS_IteratorOfElements:public SMDS_ElemIterator
 /// Create an iterator which look for elements of type type which are linked 
 /// to the element element. it is the iterator to get connectivity of element
 //////////////////////////////////////////////////////////////////////////////
-       SMDS_IteratorOfElements(const SMDS_MeshElement * element,
+        SMDS_IteratorOfElements(const SMDS_MeshElement * element,
                                 SMDSAbs_ElementType type,
                                 const SMDS_ElemIteratorPtr& it);
-       bool more();
-       const SMDS_MeshElement * next();
+        bool more();
+        const SMDS_MeshElement * next();
 
   private:
-       SMDS_ElemIteratorPtr t2Iterator;
-       SMDS_ElemIteratorPtr t1Iterator;
-       SMDSAbs_ElementType myType;     
-       const SMDS_MeshElement * myProxyElement;
-       const SMDS_MeshElement * myElement;             
-       bool myReverseIteration;
+        SMDS_ElemIteratorPtr t2Iterator;
+        SMDS_ElemIteratorPtr t1Iterator;
+        SMDSAbs_ElementType myType;     
+        const SMDS_MeshElement * myProxyElement;
+        const SMDS_MeshElement * myElement;             
+        bool myReverseIteration;
 
-       std::set<const SMDS_MeshElement*> alreadyReturnedElements;
-       std::set<const SMDS_MeshElement*>::iterator itAlreadyReturned;  
-       bool subMore();
-       const SMDS_MeshElement * subNext();
+        std::set<const SMDS_MeshElement*> alreadyReturnedElements;
+        std::set<const SMDS_MeshElement*>::iterator itAlreadyReturned;  
+        bool subMore();
+        const SMDS_MeshElement * subNext();
 };
diff --git a/src/SMDS/SMDS_IteratorOnIterators.hxx b/src/SMDS/SMDS_IteratorOnIterators.hxx
new file mode 100644 (file)
index 0000000..105edfd
--- /dev/null
@@ -0,0 +1,67 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+//  SMESH SMDS : implementaion of Salome mesh data structure
+// File      : SMDS_IteratorOnIterators.hxx
+// Author    : Edward AGAPOV (eap)
+//
+#ifndef SMDS_IteratorOnIterators_HeaderFile
+#define SMDS_IteratorOnIterators_HeaderFile
+
+#include "SMDS_Iterator.hxx"
+
+///////////////////////////////////////////////////////////////////////////////
+/// SMDS_Iterator iterating over all elements provided by other iterators
+///
+/// Other iterators must implement SMDS_Iterator iterface and
+/// must be provided within a stl-like container
+/// BE CAREFUL: iterator pointed value is static_cast'ed to VALUE
+///////////////////////////////////////////////////////////////////////////////
+
+template<typename VALUE,
+         typename CONTAINER_OF_ITERATORS >
+class SMDS_IteratorOnIterators : public SMDS_Iterator<VALUE>
+{
+protected:
+  CONTAINER_OF_ITERATORS _iterators;
+  typename CONTAINER_OF_ITERATORS::iterator _beg, _end;
+public:
+  SMDS_IteratorOnIterators(const CONTAINER_OF_ITERATORS& iterators):
+    _iterators( iterators ), _beg( _iterators.begin()), _end(_iterators.end() )
+  {
+    while ( _beg != _end && !(*_beg)->more()) ++_beg;
+  }
+
+  /// Return true iff there are other object in this iterator
+  virtual bool more() { return _beg != _end && (*_beg)->more(); }
+
+  /// Return the current object and step to the next one
+  virtual VALUE next()
+  {
+    VALUE __v = (VALUE)(*_beg)->next();
+    while ( _beg != _end && !(*_beg)->more())
+      ++_beg;
+    return __v;
+  }
+};
+
+#endif
diff --git a/src/SMDS/SMDS_LinearEdge.cxx b/src/SMDS/SMDS_LinearEdge.cxx
new file mode 100644 (file)
index 0000000..fd2ba30
--- /dev/null
@@ -0,0 +1,162 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+//  File   : SMDS_LinearEdge.cxx
+//  Author : Jean-Michel BOULCOURT
+//  Module : SMESH
+//
+#ifdef _MSC_VER
+#pragma warning(disable:4786)
+#endif
+
+#include "SMDS_LinearEdge.hxx"
+#include "SMDS_IteratorOfElements.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "utilities.h"
+
+using namespace std;
+
+//=======================================================================
+//function : SMDS_LinearEdge
+//purpose  : 
+//=======================================================================
+
+SMDS_LinearEdge::SMDS_LinearEdge(const SMDS_MeshNode * node1,
+                                 const SMDS_MeshNode * node2)
+{
+  //MESSAGE("SMDS_LinearEdge " << GetID());
+  myNodes[0] = node1;
+  myNodes[1] = node2;
+}
+
+//=======================================================================
+//function : Print
+//purpose  : 
+//=======================================================================
+
+void SMDS_LinearEdge::Print(ostream & OS) const
+{
+  OS << "edge <" << GetID() << "> : (" << myNodes[0] << " , " << myNodes[1]
+      << ") " << endl;
+}
+
+int SMDS_LinearEdge::NbNodes() const
+{
+  return 2;
+}
+
+int SMDS_LinearEdge::NbEdges() const
+{
+  return 1;
+}
+
+class SMDS_LinearEdge_MyNodeIterator: public SMDS_ElemIterator
+{
+  const SMDS_MeshNode * const * myNodes;
+  int myIndex;
+public:
+  SMDS_LinearEdge_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_LinearEdge::elementsIterator(SMDSAbs_ElementType type) const
+{
+  switch (type)
+  {
+    case SMDSAbs_Edge:
+      return SMDS_MeshElement::elementsIterator(SMDSAbs_Edge);
+    case SMDSAbs_Node:
+      return SMDS_ElemIteratorPtr(new SMDS_LinearEdge_MyNodeIterator(myNodes));
+    default:
+      return SMDS_ElemIteratorPtr(
+                                  new SMDS_IteratorOfElements(
+                                                              this,
+                                                              type,
+                                                              SMDS_ElemIteratorPtr(
+                                                                                   new SMDS_LinearEdge_MyNodeIterator(
+                                                                                                                      myNodes))));
+  }
+}
+
+bool operator<(const SMDS_LinearEdge & e1, const SMDS_LinearEdge & e2)
+{
+  int id11 = e1.myNodes[0]->getVtkId();
+  int id21 = e2.myNodes[0]->getVtkId();
+  int id12 = e1.myNodes[1]->getVtkId();
+  int id22 = e2.myNodes[1]->getVtkId();
+  int tmp;
+
+  if (id11 >= id12)
+    {
+      tmp = id11;
+      id11 = id12;
+      id12 = tmp;
+    }
+  if (id21 >= id22)
+    {
+      tmp = id21;
+      id21 = id22;
+      id22 = tmp;
+    }
+
+  if (id11 < id21)
+    return true;
+  else if (id11 == id21)
+    return (id21 < id22);
+  else
+    return false;
+}
+
+/*!
+ * \brief Return node by its index
+ * \param ind - node index
+ * \retval const SMDS_MeshNode* - the node
+ */
+const SMDS_MeshNode* SMDS_LinearEdge::GetNode(const int ind) const
+{
+  return myNodes[ind];
+}
+
+//=======================================================================
+//function : ChangeNodes
+//purpose  : 
+//=======================================================================
+
+bool SMDS_LinearEdge::ChangeNodes(const SMDS_MeshNode * node1,
+                                  const SMDS_MeshNode * node2)
+{
+  myNodes[0] = node1;
+  myNodes[1] = node2;
+  return true;
+}
diff --git a/src/SMDS/SMDS_LinearEdge.hxx b/src/SMDS/SMDS_LinearEdge.hxx
new file mode 100644 (file)
index 0000000..34ca147
--- /dev/null
@@ -0,0 +1,68 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+//  File   : SMDS_LinearEdge.hxx
+//  Module : SMESH
+//
+#ifndef _SMDS_LinearEdge_HeaderFile
+#define _SMDS_LinearEdge_HeaderFile
+
+#include "SMESH_SMDS.hxx"
+
+#include "SMDS_MeshEdge.hxx"
+#include <iostream>
+
+class SMDS_EXPORT SMDS_LinearEdge: public SMDS_MeshEdge
+{
+
+public:
+  SMDS_LinearEdge(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2);
+  bool ChangeNodes(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2);
+  void Print(std::ostream & OS) const;
+
+  virtual SMDSAbs_EntityType GetEntityType() const
+  {
+    return SMDSEntity_Edge;
+  }
+  virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)
+  {
+    return false;
+  }
+  int NbNodes() const;
+  int NbEdges() const;
+  friend bool operator<(const SMDS_LinearEdge& e1, const SMDS_LinearEdge& e2);
+
+  /*!
+   * \brief Return node by its index
+   * \param ind - node index
+   * \retval const SMDS_MeshNode* - the node
+   */
+  virtual const SMDS_MeshNode* GetNode(const int ind) const;
+
+protected:
+  SMDS_ElemIteratorPtr
+  elementsIterator(SMDSAbs_ElementType type) const;
+
+protected:
+  const SMDS_MeshNode* myNodes[3];
+
+};
+#endif
index 4de22248e04cf97a9e8e5f8df2c925587d651d31..8df52064a4a0b199e09f124e2f70c285f513f38a 100644 (file)
@@ -1,24 +1,22 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  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 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.
 //
-//  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
 //
-//  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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File      : SMDS_MemoryLimit.cxx
 // Created   : Fri Sep 21 17:16:42 2007
 // Author    : Edward AGAPOV (eap)
index e8d8af69741b1a6fca138db954aaab98cda10f2c..fe6f186e496b9b33a9f76da95648fa5b9a0a5598 100644 (file)
@@ -1,52 +1,70 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-//  SMESH SMDS : implementaion of Salome mesh data structure
+
+//  SMESH SMDS : implementation of Salome mesh data structure
 //
 #ifdef _MSC_VER
 #pragma warning(disable:4786)
 #endif
 
-#include "utilities.h"
-#include "SMDS_Mesh.hxx"
-#include "SMDS_VolumeOfNodes.hxx"
-#include "SMDS_VolumeOfFaces.hxx"
-#include "SMDS_FaceOfNodes.hxx"
 #include "SMDS_FaceOfEdges.hxx"
-#include "SMDS_PolyhedralVolumeOfNodes.hxx"
+#include "SMDS_FaceOfNodes.hxx"
+#include "SMDS_Mesh.hxx"
 #include "SMDS_PolygonalFaceOfNodes.hxx"
+#include "SMDS_PolyhedralVolumeOfNodes.hxx"
 #include "SMDS_QuadraticEdge.hxx"
 #include "SMDS_QuadraticFaceOfNodes.hxx"
 #include "SMDS_QuadraticVolumeOfNodes.hxx"
+#include "SMDS_SetIterator.hxx"
+#include "SMDS_SpacePosition.hxx"
+#include "SMDS_UnstructuredGrid.hxx"
+#include "SMDS_VolumeOfFaces.hxx"
+#include "SMDS_VolumeOfNodes.hxx"
+
+#include "utilities.h"
+
+#include <vtkUnstructuredGrid.h>
+#include <vtkUnstructuredGridWriter.h>
+#include <vtkUnsignedCharArray.h>
+#include <vtkCell.h>
+#include <vtkCellLinks.h>
+#include <vtkIdList.h>
 
 #include <algorithm>
 #include <map>
+#include <iostream>
+#include <fstream>
 using namespace std;
 
 #ifndef WIN32
 #include <sys/sysinfo.h>
 #endif
 
-// number of added entitis to check memory after
-#define CHECKMEMORY_INTERVAL 1000
+// number of added entities to check memory after
+#define CHECKMEMORY_INTERVAL 100000
+
+vector<SMDS_Mesh*> SMDS_Mesh::_meshList = vector<SMDS_Mesh*>();
+int SMDS_Mesh::chunkSize = 1024;
+
 
 //================================================================================
 /*!
@@ -64,35 +82,38 @@ int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
   if ( err )
     return -1;
 
+  const unsigned long Mbyte = 1024 * 1024;
+
   static int limit = -1;
   if ( limit < 0 ) {
     int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM
     if (status >= 0 ) {
       limit = WEXITSTATUS(status);
     }
+    else {
+      double factor = ( si.totalswap == 0 ) ? 0.1 : 0.2;
+      limit = int(( factor * si.totalram * si.mem_unit ) / Mbyte );
+    }
     if ( limit < 20 )
       limit = 20;
     else
-      limit = int( limit * 1.5 );
-#ifdef _DEBUG_
+      limit = int ( limit * 1.5 );
     MESSAGE ( "SMDS_Mesh::CheckMemory() memory limit = " << limit << " MB" );
-#endif
   }
 
-  const unsigned long Mbyte = 1024 * 1024;
   // compute separately to avoid overflow
   int freeMb =
     ( si.freeram  * si.mem_unit ) / Mbyte +
     ( si.freeswap * si.mem_unit ) / Mbyte;
+  //cout << "freeMb = " << freeMb << " limit = " << limit << endl;
 
   if ( freeMb > limit )
     return freeMb - limit;
 
   if ( doNotRaise )
     return 0;
-#ifdef _DEBUG_
+
   MESSAGE ("SMDS_Mesh::CheckMemory() throws as free memory too low: " << freeMb <<" MB" );
-#endif
   throw std::bad_alloc();
 #else
   return -1;
@@ -103,12 +124,50 @@ int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
 /// Create a new mesh object
 ///////////////////////////////////////////////////////////////////////////////
 SMDS_Mesh::SMDS_Mesh()
-       :myParent(NULL),
-        myNodeIDFactory(new SMDS_MeshElementIDFactory()),
-       myElementIDFactory(new SMDS_MeshElementIDFactory()),
-       myHasConstructionEdges(false), myHasConstructionFaces(false),
-       myHasInverseElements(true)
-{
+        :myParent(NULL),
+         myNodeIDFactory(new SMDS_MeshNodeIDFactory()),
+         myElementIDFactory(new SMDS_MeshElementIDFactory()),
+         myHasConstructionEdges(false), myHasConstructionFaces(false),
+         myHasInverseElements(true),
+         myNodeMin(0), myNodeMax(0),
+         myNodePool(0), myEdgePool(0), myFacePool(0), myVolumePool(0),myBallPool(0),
+         myModified(false), myModifTime(0), myCompactTime(0),
+         xmin(0), xmax(0), ymin(0), ymax(0), zmin(0), zmax(0)
+{
+  myMeshId = _meshList.size();         // --- index of the mesh to push back in the vector
+  MESSAGE("myMeshId=" << myMeshId);
+  MESSAGE("sizeof(SMDS_MeshElement) " << sizeof(SMDS_MeshElement) );
+  MESSAGE("sizeof(SMDS_MeshNode) " << sizeof(SMDS_MeshNode) );
+  MESSAGE("sizeof(SMDS_MeshCell) " << sizeof(SMDS_MeshCell) );
+  MESSAGE("sizeof(SMDS_VtkVolume) " << sizeof(SMDS_VtkVolume) );
+  MESSAGE("sizeof(SMDS_Position) " << sizeof(SMDS_Position) );
+  MESSAGE("sizeof(SMDS_SpacePosition) " << sizeof(SMDS_SpacePosition) );
+  myNodeIDFactory->SetMesh(this);
+  myElementIDFactory->SetMesh(this);
+  _meshList.push_back(this);
+  myNodePool = new ObjectPool<SMDS_MeshNode>(SMDS_Mesh::chunkSize);
+  myEdgePool = new ObjectPool<SMDS_VtkEdge>(SMDS_Mesh::chunkSize);
+  myFacePool = new ObjectPool<SMDS_VtkFace>(SMDS_Mesh::chunkSize);
+  myVolumePool = new ObjectPool<SMDS_VtkVolume>(SMDS_Mesh::chunkSize);
+  myBallPool = new ObjectPool<SMDS_BallElement>(SMDS_Mesh::chunkSize);
+
+  myNodes.clear();
+  myCells.clear();
+  //myCellIdSmdsToVtk.clear();
+  myCellIdVtkToSmds.clear();
+  myGrid = SMDS_UnstructuredGrid::New();
+  myGrid->setSMDS_mesh(this);
+  myGrid->Initialize();
+  myGrid->Allocate();
+  vtkPoints* points = vtkPoints::New();
+  // rnv: to fix bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion"
+  // using double type for storing coordinates of nodes instead float.
+  points->SetDataType(VTK_DOUBLE);
+  points->SetNumberOfPoints(SMDS_Mesh::chunkSize);
+  myGrid->SetPoints( points );
+  points->Delete();
+  myGrid->BuildLinks();
+  this->Modified();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -117,10 +176,15 @@ SMDS_Mesh::SMDS_Mesh()
 /// (2003-09-08) of SMESH
 ///////////////////////////////////////////////////////////////////////////////
 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
-       :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
-       myElementIDFactory(parent->myElementIDFactory),
-       myHasConstructionEdges(false), myHasConstructionFaces(false),
-       myHasInverseElements(true)
+        :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
+         myElementIDFactory(parent->myElementIDFactory),
+         myHasConstructionEdges(false), myHasConstructionFaces(false),
+         myHasInverseElements(true),
+         myNodePool(parent->myNodePool),
+         myEdgePool(parent->myEdgePool),
+         myFacePool(parent->myFacePool),
+         myVolumePool(parent->myVolumePool),
+         myBallPool(parent->myBallPool)
 {
 }
 
@@ -130,9 +194,9 @@ SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
 
 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
 {
-       SMDS_Mesh *submesh = new SMDS_Mesh(this);
-       myChildren.insert(myChildren.end(), submesh);
-       return submesh;
+        SMDS_Mesh *submesh = new SMDS_Mesh(this);
+        myChildren.insert(myChildren.end(), submesh);
+        return submesh;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -156,22 +220,131 @@ 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){
-    if ( myNodes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
-    SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z);
-    myNodes.Add(node);
+    if (ID < 1)
+      {
+        MESSAGE("=============>  Bad Node Id: " << ID);
+        ID = myNodeIDFactory->GetFreeID();
+      }
+    myNodeIDFactory->adjustMaxId(ID);
+    SMDS_MeshNode * node = myNodePool->getNew();
+    node->init(ID, myMeshId, 0, x, y, z);
+
+    if (ID >= myNodes.size())
+    {
+        myNodes.resize(ID+SMDS_Mesh::chunkSize, 0);
+//         MESSAGE(" ------------------ myNodes resize " << ID << " --> " << ID+SMDS_Mesh::chunkSize);
+    }
+    myNodes[ID] = node;
     myNodeIDFactory->BindID(ID,node);
     myInfo.myNbNodes++;
+    myModified = true;
+    this->adjustBoundingBox(x, y, z);
     return node;
   }else
     return NULL;
 }
 
+///////////////////////////////////////////////////////////////////////////////
+/// create a Mesh0DElement and add it to the current Mesh
+/// @return : The created Mesh0DElement
+///////////////////////////////////////////////////////////////////////////////
+SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID)
+{
+  SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode);
+  if (!node) return NULL;
+  return SMDS_Mesh::Add0DElementWithID(node, ID);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// create a Mesh0DElement and add it to the current Mesh
+/// @return : The created Mesh0DElement
+///////////////////////////////////////////////////////////////////////////////
+SMDS_Mesh0DElement* SMDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
+{
+  return SMDS_Mesh::Add0DElementWithID(node, myElementIDFactory->GetFreeID());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Create a new Mesh0DElement and at it to the mesh
+/// @param idnode ID of the node
+/// @param ID ID of the 0D element to create
+/// @return The created 0D element or NULL if an element with this
+///         ID already exists or if input node is not found.
+///////////////////////////////////////////////////////////////////////////////
+SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int ID)
+{
+  if (!n) return 0;
+
+  if (Nb0DElements() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
+  //MESSAGE("Add0DElementWithID" << ID)
+  SMDS_Mesh0DElement * el0d = new SMDS_Mesh0DElement(n);
+  if (myElementIDFactory->BindID(ID, el0d)) {
+    //SMDS_MeshNode *node = const_cast<SMDS_MeshNode*>(n);
+    //node->AddInverseElement(el0d);// --- fait avec BindID
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = el0d;
+    myInfo.myNb0DElements++;
+    return el0d;
+  }
+
+  delete el0d;
+  return NULL;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// create a Ball and add it to the current Mesh
+/// @return : The created Ball
+///////////////////////////////////////////////////////////////////////////////
+SMDS_BallElement* SMDS_Mesh::AddBallWithID(int idnode, double diameter, int ID)
+{
+  SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode);
+  if (!node) return NULL;
+  return SMDS_Mesh::AddBallWithID(node, diameter, ID);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// create a Ball and add it to the current Mesh
+/// @return : The created Ball
+///////////////////////////////////////////////////////////////////////////////
+SMDS_BallElement* SMDS_Mesh::AddBall(const SMDS_MeshNode * node, double diameter)
+{
+  return SMDS_Mesh::AddBallWithID(node, diameter, myElementIDFactory->GetFreeID());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Create a new Ball and at it to the mesh
+/// @param idnode ID of the node
+//  @param diameter ball diameter
+/// @param ID ID of the 0D element to create
+/// @return The created 0D element or NULL if an element with this
+///         ID already exists or if input node is not found.
+///////////////////////////////////////////////////////////////////////////////
+SMDS_BallElement* SMDS_Mesh::AddBallWithID(const SMDS_MeshNode * n, double diameter, int ID)
+{
+  if (!n) return 0;
+
+  if (NbBalls() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
+
+  SMDS_BallElement *ball = myBallPool->getNew();
+  ball->init(n->getVtkId(), diameter, this);
+  if (!this->registerElement(ID,ball))
+    {
+      this->myGrid->GetCellTypesArray()->SetValue(ball->getVtkId(), VTK_EMPTY_CELL);
+      myBallPool->destroy(ball);
+      return 0;
+    }
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = ball;
+  myInfo.myNbBalls++;
+  return ball;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 /// create a MeshEdge and add it to the current Mesh
 /// @return : The created MeshEdge
 ///////////////////////////////////////////////////////////////////////////////
 
-SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, 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);
@@ -185,7 +358,7 @@ 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 SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
 }
@@ -200,28 +373,37 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
-                                       const SMDS_MeshNode * n2, 
-                                       int ID)
+                                        const SMDS_MeshNode * n2,
+                                        int ID)
 {
   if ( !n1 || !n2 ) return 0;
+  SMDS_MeshEdge * edge = 0;
 
-  if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  // --- retreive nodes ID
+  vector<vtkIdType> nodeIds;
+  nodeIds.clear();
+  nodeIds.push_back(n1->getVtkId());
+  nodeIds.push_back(n2->getVtkId());
 
-  SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2);
-  if(myElementIDFactory->BindID(ID, edge)) {
-    SMDS_MeshNode *node1,*node2;
-    node1=const_cast<SMDS_MeshNode*>(n1);
-    node2=const_cast<SMDS_MeshNode*>(n2);
-    node1->AddInverseElement(edge);
-    node2->AddInverseElement(edge);            
-    myEdges.Add(edge);
-    myInfo.myNbEdges++;
-    return edge;
-  } 
-  else {
-    delete edge;
-    return NULL;
-  }
+  SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
+  edgevtk->init(nodeIds, this);
+  if (!this->registerElement(ID,edgevtk))
+    {
+      this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
+      myEdgePool->destroy(edgevtk);
+      return 0;
+    }
+  edge = edgevtk;
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = edge;
+  myInfo.myNbEdges++;
+
+//  if (edge && !registerElement(ID, edge))
+//  {
+//    RemoveElement(edge, false);
+//    edge = NULL;
+//  }
+  return edge;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -230,8 +412,8 @@ 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 SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
 }
@@ -246,7 +428,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, i
   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);    
+  return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -258,12 +440,13 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
                                         const SMDS_MeshNode * n3,
                                         int ID)
 {
-  SMDS_MeshFace * face=createTriangle(n1, n2, n3);
+  //MESSAGE("AddFaceWithID " << ID)
+  SMDS_MeshFace * face=createTriangle(n1, n2, n3, ID);
 
-  if (face && !registerElement(ID, face)) {
-    RemoveElement(face, false);
-    face = NULL;
-  }
+//  if (face && !registerElement(ID, face)) {
+//    RemoveElement(face, false);
+//    face = NULL;
+//  }
   return face;
 }
 
@@ -273,9 +456,9 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
 ///////////////////////////////////////////////////////////////////////////////
 
 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 SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
 }
@@ -284,11 +467,11 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
 /// 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);
@@ -296,7 +479,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
   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);     
+  return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -309,12 +492,13 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
                                         const SMDS_MeshNode * n4,
                                         int ID)
 {
-  SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4);
+  //MESSAGE("AddFaceWithID " << ID);
+  SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4, ID);
 
-  if (face && !registerElement(ID, face)) {
-    RemoveElement(face, false);
-    face = NULL;
-  }
+//  if (face && !registerElement(ID, face)) {
+//    RemoveElement(face, false);
+//    face = NULL;
+//  }
   return face;
 }
 
@@ -329,7 +513,8 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
 {
   if (!hasConstructionEdges())
     return NULL;
-  return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
+     //MESSAGE("AddFaceWithID");
+ return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -345,15 +530,18 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
     return NULL;
   if ( !e1 || !e2 || !e3 ) return 0;
 
-  if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  MESSAGE("AddFaceWithID" << ID);
 
   SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
-  myFaces.Add(face);
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = face;
   myInfo.myNbTriangles++;
 
   if (!registerElement(ID, face)) {
-    RemoveElement(face, false);
-    face = NULL;
+    registerElement(myElementIDFactory->GetFreeID(), face);
+    //RemoveElement(face, false);
+    //face = NULL;
   }
   return face;
 }
@@ -370,7 +558,8 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
 {
   if (!hasConstructionEdges())
     return NULL;
-  return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
+     //MESSAGE("AddFaceWithID" );
+ return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -385,49 +574,54 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
 {
   if (!hasConstructionEdges())
     return NULL;
+  MESSAGE("AddFaceWithID" << ID);
   if ( !e1 || !e2 || !e3 || !e4 ) return 0;
-  if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
-  myFaces.Add(face);
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = face;
   myInfo.myNbQuadrangles++;
 
   if (!registerElement(ID, face))
   {
-    RemoveElement(face, false);
-    face = NULL;
+    registerElement(myElementIDFactory->GetFreeID(), face);
+    //RemoveElement(face, false);
+    //face = NULL;
   }
   return face;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-///Create a new tetrahedron and add it to the mesh. 
-///@return The created tetrahedron 
+///Create a new tetrahedron and add it to the mesh.
+///@return The created tetrahedron
 ///////////////////////////////////////////////////////////////////////////////
 
 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();
+    //MESSAGE("AddVolumeWithID " << ID);
   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. 
+///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 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)
 {
+    //MESSAGE("AddVolumeWithID" << ID);
   SMDS_MeshNode *node1, *node2, *node3, *node4;
   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
@@ -436,11 +630,11 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
   if(!node1 || !node2 || !node3 || !node4) return NULL;
   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
 }
-       
+
 ///////////////////////////////////////////////////////////////////////////////
-///Create a new tetrahedron and add it to the mesh. 
+///Create a new tetrahedron and add it to the mesh.
 ///@param ID The ID of the new volume
-///@return The created tetrahedron 
+///@return The created tetrahedron
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
@@ -449,16 +643,18 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n4,
                                             int ID)
 {
+    //MESSAGE("AddVolumeWithID " << ID);
   SMDS_MeshVolume* volume = 0;
   if ( !n1 || !n2 || !n3 || !n4) return volume;
-  if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   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.Add(volume);
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = volume;
     myInfo.myNbTetras++;
   }
   else if(hasConstructionEdges()) {
@@ -466,51 +662,70 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     return NULL;
   }
   else {
-    volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4);
-    myVolumes.Add(volume);
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(n1->getVtkId());
+    nodeIds.push_back(n3->getVtkId()); // order SMDS-->VTK
+    nodeIds.push_back(n2->getVtkId());
+    nodeIds.push_back(n4->getVtkId());
+
+    SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+    volvtk->init(nodeIds, this);
+    if (!this->registerElement(ID,volvtk))
+      {
+        this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+        myVolumePool->destroy(volvtk);
+        return 0;
+      }
+    volume = volvtk;
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = volume;
     myInfo.myNbTetras++;
   }
 
-  if (!registerElement(ID, volume)) {
-    RemoveElement(volume, false);
-    volume = NULL;
-  }
+//  if (!registerElement(ID, volume)) {
+//    RemoveElement(volume, false);
+//    volume = NULL;
+//  }
   return volume;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-///Create a new pyramid and add it to the mesh. 
+///Create a new pyramid and add it to the mesh.
 ///Nodes 1,2,3 and 4 define the base of the pyramid
-///@return The created pyramid 
+///@return The created pyramid
 ///////////////////////////////////////////////////////////////////////////////
 
 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();
+    //MESSAGE("AddVolumeWithID " << ID);
   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. 
+///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 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)
 {
+    //MESSAGE("AddVolumeWithID " << ID);
   SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
@@ -520,7 +735,7 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
   if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
 }
-       
+
 ///////////////////////////////////////////////////////////////////////////////
 ///Create a new pyramid and add it to the mesh.
 ///Nodes 1,2,3 and 4 define the base of the pyramid
@@ -535,16 +750,18 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n5,
                                             int ID)
 {
+    //MESSAGE("AddVolumeWithID " << ID);
   SMDS_MeshVolume* volume = 0;
   if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
-  if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   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.Add(volume);
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = volume;
     myInfo.myNbPyramids++;
   }
   else if(hasConstructionEdges()) {
@@ -552,53 +769,73 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     return NULL;
   }
   else {
-    volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5);
-    myVolumes.Add(volume);
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(n1->getVtkId());
+    nodeIds.push_back(n4->getVtkId());
+    nodeIds.push_back(n3->getVtkId());
+    nodeIds.push_back(n2->getVtkId());
+    nodeIds.push_back(n5->getVtkId());
+
+    SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+    volvtk->init(nodeIds, this);
+    if (!this->registerElement(ID,volvtk))
+      {
+        this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+        myVolumePool->destroy(volvtk);
+        return 0;
+      }
+    volume = volvtk;
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = volume;
     myInfo.myNbPyramids++;
   }
 
-  if (!registerElement(ID, volume)) {
-    RemoveElement(volume, false);
-    volume = NULL;
-  }
+//  if (!registerElement(ID, volume)) {
+//    RemoveElement(volume, false);
+//    volume = NULL;
+//  }
   return volume;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-///Create a new prism and add it to the mesh. 
+///Create a new prism and add it to the mesh.
 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
-///@return The created prism 
+///@return The created prism
 ///////////////////////////////////////////////////////////////////////////////
 
 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();
+    //MESSAGE("AddVolumeWithID " << ID);
   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. 
+///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 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_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
+                                             int idnode2,
+                                             int idnode3,
+                                             int idnode4,
+                                             int idnode5,
+                                             int idnode6,
+                                             int ID)
 {
+    //MESSAGE("AddVolumeWithID " << ID);
   SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
@@ -609,7 +846,7 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
   if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
 }
-       
+
 ///////////////////////////////////////////////////////////////////////////////
 ///Create a new prism and add it to the mesh.
 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
@@ -625,9 +862,10 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n6,
                                             int ID)
 {
+    //MESSAGE("AddVolumeWithID " << ID);
   SMDS_MeshVolume* volume = 0;
   if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
-  if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   if(hasConstructionFaces()) {
     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
     SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
@@ -635,7 +873,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     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.Add(volume);
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = volume;
     myInfo.myNbPrisms++;
   }
   else if(hasConstructionEdges()) {
@@ -643,57 +882,208 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     return NULL;
   }
   else {
-    volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6);
-    myVolumes.Add(volume);
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(n1->getVtkId());
+    nodeIds.push_back(n2->getVtkId());
+    nodeIds.push_back(n3->getVtkId());
+    nodeIds.push_back(n4->getVtkId());
+    nodeIds.push_back(n5->getVtkId());
+    nodeIds.push_back(n6->getVtkId());
+
+    SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+    volvtk->init(nodeIds, this);
+    if (!this->registerElement(ID,volvtk))
+      {
+        this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+        myVolumePool->destroy(volvtk);
+        return 0;
+      }
+    volume = volvtk;
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = volume;
     myInfo.myNbPrisms++;
   }
 
-  if (!registerElement(ID, volume)) {
-    RemoveElement(volume, false);
-    volume = NULL;
+//  if (!registerElement(ID, volume)) {
+//    RemoveElement(volume, false);
+//    volume = NULL;
+//  }
+  return volume;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Create a new hexagonal prism and add it to the mesh.
+///@return The created prism
+///////////////////////////////////////////////////////////////////////////////
+
+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 * n9,
+                                      const SMDS_MeshNode * n10,
+                                      const SMDS_MeshNode * n11,
+                                      const SMDS_MeshNode * n12)
+{
+  int ID = myElementIDFactory->GetFreeID();
+  SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6,
+                                                   n7, n8, n9, n10, n11, n12,
+                                                   ID);
+  if(v==NULL) myElementIDFactory->ReleaseID(ID);
+  return v;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Create a new hexagonal prism and add it to the mesh.
+///@param ID The ID of the new volume
+///@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 idnode7,
+                                             int idnode8,
+                                             int idnode9,
+                                             int idnode10,
+                                             int idnode11,
+                                             int idnode12,
+                                             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);
+  SMDS_MeshNode *node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
+  SMDS_MeshNode *node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
+  SMDS_MeshNode *node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
+  SMDS_MeshNode *node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
+  SMDS_MeshNode *node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
+  SMDS_MeshNode *node9 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode9);
+  SMDS_MeshNode *node10 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode10);
+  SMDS_MeshNode *node11 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode11);
+  SMDS_MeshNode *node12 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode12);
+  return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
+                                    node7, node8, node9, node10, node11, node12,
+                                    ID);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Create a new hexagonal prism 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_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 * n9,
+                                            const SMDS_MeshNode * n10,
+                                            const SMDS_MeshNode * n11,
+                                            const SMDS_MeshNode * n12,
+                                            int ID)
+{
+  SMDS_MeshVolume* volume = 0;
+  if(!n1 || !n2 || !n3 || !n4 || !n5 || !n6 ||
+     !n7 || !n8 || !n9 || !n10 || !n11 || !n12 )
+    return volume;
+  if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  if(hasConstructionFaces()) {
+    MESSAGE("Error : Not implemented");
+    return NULL;
+  }
+  else if(hasConstructionEdges()) {
+    MESSAGE("Error : Not implemented");
+    return NULL;
+  }
+  else {
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.push_back(n1->getVtkId());
+    nodeIds.push_back(n6->getVtkId());
+    nodeIds.push_back(n5->getVtkId());
+    nodeIds.push_back(n4->getVtkId());
+    nodeIds.push_back(n3->getVtkId());
+    nodeIds.push_back(n2->getVtkId());
+
+    nodeIds.push_back(n7->getVtkId());
+    nodeIds.push_back(n12->getVtkId());
+    nodeIds.push_back(n11->getVtkId());
+    nodeIds.push_back(n10->getVtkId());
+    nodeIds.push_back(n9->getVtkId());
+    nodeIds.push_back(n8->getVtkId());
+
+    SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+    volvtk->init(nodeIds, this);
+    if (!this->registerElement(ID,volvtk))
+      {
+        this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+        myVolumePool->destroy(volvtk);
+        return 0;
+      }
+    volume = volvtk;
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = volume;
+    myInfo.myNbHexPrism++;
   }
+
   return volume;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-///Create a new hexahedron and add it to the mesh. 
+///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.
-///@return The created hexahedron 
+///@return The created hexahedron
 ///////////////////////////////////////////////////////////////////////////////
 
 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 = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
+ 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. 
+///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 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_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
+                                             int idnode2,
+                                             int idnode3,
+                                             int idnode4,
+                                             int idnode5,
+                                             int idnode6,
+                                             int idnode7,
+                                             int idnode8,
+                                             int ID)
 {
+    //MESSAGE("AddVolumeWithID " << ID);
   SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
@@ -708,7 +1098,7 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
   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.
@@ -727,9 +1117,10 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n8,
                                             int ID)
 {
+    //MESSAGE("AddVolumeWithID " << ID);
   SMDS_MeshVolume* volume = 0;
   if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
-  if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   if(hasConstructionFaces()) {
     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
     SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
@@ -738,7 +1129,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     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.Add(volume);
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = volume;
     myInfo.myNbHexas++;
   }
   else if(hasConstructionEdges()) {
@@ -746,16 +1138,36 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     return NULL;
   }
   else {
-//    volume=new SMDS_HexahedronOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
-    volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
-    myVolumes.Add(volume);
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(n1->getVtkId());
+    nodeIds.push_back(n4->getVtkId());
+    nodeIds.push_back(n3->getVtkId());
+    nodeIds.push_back(n2->getVtkId());
+    nodeIds.push_back(n5->getVtkId());
+    nodeIds.push_back(n8->getVtkId());
+    nodeIds.push_back(n7->getVtkId());
+    nodeIds.push_back(n6->getVtkId());
+
+    SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+    volvtk->init(nodeIds, this);
+    if (!this->registerElement(ID,volvtk))
+      {
+        this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+        myVolumePool->destroy(volvtk);
+        return 0;
+      }
+    volume = volvtk;
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = volume;
     myInfo.myNbHexas++;
   }
-
-  if (!registerElement(ID, volume)) {
-    RemoveElement(volume, false);
-    volume = NULL;
-  }
+//  if (!registerElement(ID, volume)) {
+//    RemoveElement(volume, false);
+//    volume = NULL;
+//  }
   return volume;
 }
 
@@ -769,6 +1181,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
                                       const SMDS_MeshFace * f3,
                                       const SMDS_MeshFace * f4)
 {
+    //MESSAGE("AddVolumeWithID");
   if (!hasConstructionFaces())
     return NULL;
   return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
@@ -777,7 +1190,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
 ///////////////////////////////////////////////////////////////////////////////
 ///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 
+///@return The created tetrahedron
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
@@ -786,17 +1199,20 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
                                             const SMDS_MeshFace * f4,
                                             int ID)
 {
+  MESSAGE("AddVolumeWithID" << ID);
   if (!hasConstructionFaces())
     return NULL;
   if ( !f1 || !f2 || !f3 || !f4) return 0;
-  if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
-  myVolumes.Add(volume);
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = volume;
   myInfo.myNbTetras++;
 
   if (!registerElement(ID, volume)) {
-    RemoveElement(volume, false);
-    volume = NULL;
+    registerElement(myElementIDFactory->GetFreeID(), volume);
+    //RemoveElement(volume, false);
+    //volume = NULL;
   }
   return volume;
 }
@@ -812,7 +1228,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
                                       const SMDS_MeshFace * f4,
                                       const SMDS_MeshFace * f5)
 {
-  if (!hasConstructionFaces())
+     //MESSAGE("AddVolumeWithID");
+ if (!hasConstructionFaces())
     return NULL;
   return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
 }
@@ -820,7 +1237,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
 ///////////////////////////////////////////////////////////////////////////////
 ///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 
+///@return The created pyramid
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
@@ -830,17 +1247,20 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
                                             const SMDS_MeshFace * f5,
                                             int ID)
 {
+  MESSAGE("AddVolumeWithID" << ID);
   if (!hasConstructionFaces())
     return NULL;
   if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
-  if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
-  myVolumes.Add(volume);
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = volume;
   myInfo.myNbPyramids++;
 
   if (!registerElement(ID, volume)) {
-    RemoveElement(volume, false);
-    volume = NULL;
+    registerElement(myElementIDFactory->GetFreeID(), volume);
+    //RemoveElement(volume, false);
+    //volume = NULL;
   }
   return volume;
 }
@@ -857,7 +1277,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
                                       const SMDS_MeshFace * f5,
                                       const SMDS_MeshFace * f6)
 {
-  if (!hasConstructionFaces())
+     //MESSAGE("AddVolumeWithID" );
+ if (!hasConstructionFaces())
     return NULL;
   return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
 }
@@ -865,7 +1286,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
 ///////////////////////////////////////////////////////////////////////////////
 ///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 
+///@return The created prism
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
@@ -876,17 +1297,20 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
                                             const SMDS_MeshFace * f6,
                                             int ID)
 {
+  MESSAGE("AddVolumeWithID" << ID);
   if (!hasConstructionFaces())
     return NULL;
   if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
-  if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
-  myVolumes.Add(volume);
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = volume;
   myInfo.myNbPrisms++;
 
   if (!registerElement(ID, volume)) {
-    RemoveElement(volume, false);
-    volume = NULL;
+    registerElement(myElementIDFactory->GetFreeID(), volume);
+    //RemoveElement(volume, false);
+    //volume = NULL;
   }
   return volume;
 }
@@ -895,16 +1319,16 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
 /// Add a polygon defined by its nodes IDs
 ///////////////////////////////////////////////////////////////////////////////
 
-SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
-                                                  const int        ID)
+SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (const vector<int> & nodes_ids,
+                                                  const int           ID)
 {
   int nbNodes = nodes_ids.size();
-  std::vector<const SMDS_MeshNode*> nodes (nbNodes);
+  vector<const SMDS_MeshNode*> nodes (nbNodes);
   for (int i = 0; i < nbNodes; i++) {
     nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
     if (!nodes[i]) return NULL;
   }
-  return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID); 
+  return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -912,31 +1336,56 @@ SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
-                          (std::vector<const SMDS_MeshNode*> nodes,
-                           const int                         ID)
+                          (const vector<const SMDS_MeshNode*> & nodes,
+                           const int                            ID)
 {
   SMDS_MeshFace * face;
 
-  if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   if (hasConstructionEdges())
-  {
-    MESSAGE("Error : Not implemented");
-    return NULL;
-  }
+    {
+      MESSAGE("Error : Not implemented");
+      return NULL;
+    }
   else
-  {
-    for ( int i = 0; i < nodes.size(); ++i )
-      if ( !nodes[ i ] ) return 0;
-    face = new SMDS_PolygonalFaceOfNodes(nodes);
-    myFaces.Add(face);
-    myInfo.myNbPolygons++;
-  }
+    {
+//#ifdef VTK_HAVE_POLYHEDRON
+    //MESSAGE("AddPolygonalFaceWithID vtk " << ID);
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    vector<const SMDS_MeshNode*>::const_iterator it = nodes.begin();
+    for ( ; it != nodes.end(); ++it)
+      nodeIds.push_back((*it)->getVtkId());
+
+    SMDS_VtkFace *facevtk = myFacePool->getNew();
+    facevtk->initPoly(nodeIds, this);
+    if (!this->registerElement(ID,facevtk))
+      {
+        this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
+        myFacePool->destroy(facevtk);
+        return 0;
+      }
+    face = facevtk;
+//#else
+//    MESSAGE("AddPolygonalFaceWithID smds " << ID);
+//     for ( int i = 0; i < nodes.size(); ++i )
+//      if ( !nodes[ i ] ) return 0;
+//      face = new SMDS_PolygonalFaceOfNodes(nodes);
+//#endif
+      adjustmyCellsCapacity(ID);
+      myCells[ID] = face;
+      myInfo.myNbPolygons++;
+    }
 
-  if (!registerElement(ID, face)) {
-    RemoveElement(face, false);
-    face = NULL;
-  }
-  return face;
+//#ifndef VTK_HAVE_POLYHEDRON
+//  if (!registerElement(ID, face))
+//    {
+//      registerElement(myElementIDFactory->GetFreeID(), face);
+//      //RemoveElement(face, false);
+//      //face = NULL;
+//    }
+//#endif
+ return face;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -944,25 +1393,25 @@ SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
 /// An ID is automatically affected to the created face.
 ///////////////////////////////////////////////////////////////////////////////
 
-SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (std::vector<const SMDS_MeshNode*> nodes)
+SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (const vector<const SMDS_MeshNode*> & nodes)
 {
   return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-/// Create a new polyhedral volume and add it to the mesh. 
+/// Create a new polyhedral volume and add it to the mesh.
 /// @param ID The ID of the new volume
 /// @return The created volume or NULL if an element with this ID already exists
 /// or if input nodes are not found.
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
-                             (std::vector<int> nodes_ids,
-                              std::vector<int> quantities,
-                              const int        ID)
+                             (const vector<int> & nodes_ids,
+                              const vector<int> & quantities,
+                              const int           ID)
 {
   int nbNodes = nodes_ids.size();
-  std::vector<const SMDS_MeshNode*> nodes (nbNodes);
+  vector<const SMDS_MeshNode*> nodes (nbNodes);
   for (int i = 0; i < nbNodes; i++) {
     nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
     if (!nodes[i]) return NULL;
@@ -971,47 +1420,79 @@ SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-/// Create a new polyhedral volume and add it to the mesh. 
+/// Create a new polyhedral volume and add it to the mesh.
 /// @param ID The ID of the new volume
 /// @return The created  volume
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
-                            (std::vector<const SMDS_MeshNode*> nodes,
-                             std::vector<int>                  quantities,
-                             const int                         ID)
+                            (const vector<const SMDS_MeshNode*>& nodes,
+                             const vector<int>                 & quantities,
+                             const int                           ID)
 {
-  SMDS_MeshVolume* volume;
-  if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
-  if (hasConstructionFaces()) {
-    MESSAGE("Error : Not implemented");
-    return NULL;
-  } else if (hasConstructionEdges()) {
-    MESSAGE("Error : Not implemented");
+  SMDS_MeshVolume* volume = 0;
+  if ( nodes.empty() || quantities.empty() )
     return NULL;
-  } else {
-    for ( int i = 0; i < nodes.size(); ++i )
-      if ( !nodes[ i ] ) return 0;
-    volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
-    myVolumes.Add(volume);
-    myInfo.myNbPolyhedrons++;
-  }
+  if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  if (hasConstructionFaces())
+    {
+      MESSAGE("Error : Not implemented");
+      return NULL;
+    }
+  else if (hasConstructionEdges())
+    {
+      MESSAGE("Error : Not implemented");
+      return NULL;
+    }
+  else
+    {
+//#ifdef VTK_HAVE_POLYHEDRON
+      //MESSAGE("AddPolyhedralVolumeWithID vtk " << ID);
+      vector<vtkIdType> nodeIds;
+      nodeIds.clear();
+      vector<const SMDS_MeshNode*>::const_iterator it = nodes.begin();
+      for (; it != nodes.end(); ++it)
+        nodeIds.push_back((*it)->getVtkId());
+
+      SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+      volvtk->initPoly(nodeIds, quantities, this);
+      if (!this->registerElement(ID, volvtk))
+        {
+          this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+          myVolumePool->destroy(volvtk);
+          return 0;
+        }
+      volume = volvtk;
+//#else
+//      MESSAGE("AddPolyhedralVolumeWithID smds " << ID);
+//      for ( int i = 0; i < nodes.size(); ++i )
+//      if ( !nodes[ i ] ) return 0;
+//      volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
+//#endif
+      adjustmyCellsCapacity(ID);
+      myCells[ID] = volume;
+      myInfo.myNbPolyhedrons++;
+    }
 
-  if (!registerElement(ID, volume)) {
-    RemoveElement(volume, false);
-    volume = NULL;
-  }
+//#ifndef VTK_HAVE_POLYHEDRON
+//  if (!registerElement(ID, volume))
+//    {
+//      registerElement(myElementIDFactory->GetFreeID(), volume);
+//      //RemoveElement(volume, false);
+//      //volume = NULL;
+//    }
+//#endif
   return volume;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-/// Create a new polyhedral volume and add it to the mesh. 
+/// Create a new polyhedral volume and add it to the mesh.
 /// @return The created  volume
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
-                            (std::vector<const SMDS_MeshNode*> nodes,
-                             std::vector<int>                  quantities)
+                            (const vector<const SMDS_MeshNode*> & nodes,
+                             const vector<int>                  & quantities)
 {
   int ID = myElementIDFactory->GetFreeID();
   SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
@@ -1019,41 +1500,186 @@ SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
   return v;
 }
 
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds)
+{
+  int ID = myElementIDFactory->GetFreeID();
+  SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeFromVtkIdsWithID(vtkNodeIds, ID);
+  if (v == NULL) myElementIDFactory->ReleaseID(ID);
+  return v;
+}
+
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIdsWithID(const std::vector<vtkIdType>& vtkNodeIds, const int ID)
+{
+  SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+  volvtk->init(vtkNodeIds, this);
+  if (!this->registerElement(ID,volvtk))
+    {
+      this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+      myVolumePool->destroy(volvtk);
+      return 0;
+    }
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = volvtk;
+  vtkIdType aVtkType = volvtk->GetVtkType();
+  switch (aVtkType)
+  {
+    case VTK_TETRA:
+      myInfo.myNbTetras++;
+      break;
+    case VTK_PYRAMID:
+      myInfo.myNbPyramids++;
+      break;
+    case VTK_WEDGE:
+      myInfo.myNbPrisms++;
+      break;
+    case VTK_HEXAHEDRON:
+      myInfo.myNbHexas++;
+      break;
+    case VTK_QUADRATIC_TETRA:
+      myInfo.myNbQuadTetras++;
+      break;
+    case VTK_QUADRATIC_PYRAMID:
+      myInfo.myNbQuadPyramids++;
+      break;
+    case VTK_QUADRATIC_WEDGE:
+      myInfo.myNbQuadPrisms++;
+      break;
+    case VTK_QUADRATIC_HEXAHEDRON:
+      myInfo.myNbQuadHexas++;
+      break;
+//#ifdef VTK_HAVE_POLYHEDRON
+    case VTK_POLYHEDRON:
+      myInfo.myNbPolyhedrons++;
+      break;
+//#endif
+    default:
+      myInfo.myNbPolyhedrons++;
+      break;
+  }
+  return volvtk;
+}
+
+SMDS_MeshFace* SMDS_Mesh::AddFaceFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds)
+{
+  int ID = myElementIDFactory->GetFreeID();
+  SMDS_MeshFace * f = SMDS_Mesh::AddFaceFromVtkIdsWithID(vtkNodeIds, ID);
+  if (f == NULL) myElementIDFactory->ReleaseID(ID);
+  return f;
+}
+
+SMDS_MeshFace* SMDS_Mesh::AddFaceFromVtkIdsWithID(const std::vector<vtkIdType>& vtkNodeIds, const int ID)
+{
+  SMDS_VtkFace *facevtk = myFacePool->getNew();
+  facevtk->init(vtkNodeIds, this);
+  if (!this->registerElement(ID,facevtk))
+    {
+      this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
+      myFacePool->destroy(facevtk);
+      return 0;
+    }
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = facevtk;
+  vtkIdType aVtkType = facevtk->GetVtkType();
+  switch (aVtkType)
+  {
+    case VTK_TRIANGLE:
+      myInfo.myNbTriangles++;
+      break;
+    case VTK_QUAD:
+      myInfo.myNbQuadrangles++;
+      break;
+    case VTK_QUADRATIC_TRIANGLE:
+      myInfo.myNbQuadTriangles++;
+      break;
+    case VTK_QUADRATIC_QUAD:
+      myInfo.myNbQuadQuadrangles++;
+      break;
+    case VTK_BIQUADRATIC_QUAD:
+      myInfo.myNbBiQuadQuadrangles++;
+      break;
+    case VTK_POLYGON:
+      myInfo.myNbPolygons++;
+      break;
+     default:
+      myInfo.myNbPolygons++;
+  }
+  return facevtk;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 /// Registers element with the given ID, maintains inverse connections
 ///////////////////////////////////////////////////////////////////////////////
-bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement * element)
+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<SMDS_MeshNode*>
-        (const_cast<SMDS_MeshElement*>(it->next()));
-      node->AddInverseElement(element);
-    }
-    return true;
+  //MESSAGE("registerElement " << ID);
+  if ((ID >=0) && (ID < myCells.size()) && myCells[ID]) // --- already bound
+  {
+    MESSAGE(" ------------------ already bound "<< ID << " " << myCells[ID]->getVtkId());
+    return false;
   }
-  return false;
+
+  element->myID = ID;
+  element->myMeshId = myMeshId;
+
+  SMDS_MeshCell *cell = dynamic_cast<SMDS_MeshCell*>(element);
+  MYASSERT(cell);
+  int vtkId = cell->getVtkId();  
+  if (vtkId == -1)
+    vtkId = myElementIDFactory->SetInVtkGrid(element);
+
+  if (vtkId >= myCellIdVtkToSmds.size()) // --- resize local vector
+  {
+//     MESSAGE(" --------------------- resize myCellIdVtkToSmds " << vtkId << " --> " << vtkId + SMDS_Mesh::chunkSize);
+    myCellIdVtkToSmds.resize(vtkId + SMDS_Mesh::chunkSize, -1);
+  }
+  myCellIdVtkToSmds[vtkId] = ID;
+
+  myElementIDFactory->updateMinMax(ID);
+  return true;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-/// Return the node whose ID is 'ID'.
+/// Return the node whose SMDS ID is 'ID'.
 ///////////////////////////////////////////////////////////////////////////////
 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
 {
-  return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID);
+  if (ID < 1 || ID >= myNodes.size())
+  {
+//     MESSAGE("------------------------------------------------------------------------- ");
+//     MESSAGE("----------------------------------- bad ID " << ID << " " << myNodes.size());
+//     MESSAGE("------------------------------------------------------------------------- ");
+    return 0;
+  }
+  return (const SMDS_MeshNode *)myNodes[ID];
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Return the node whose VTK ID is 'vtkId'.
+///////////////////////////////////////////////////////////////////////////////
+const SMDS_MeshNode * SMDS_Mesh::FindNodeVtk(int vtkId) const
+{
+  // TODO if needed use mesh->nodeIdFromVtkToSmds
+  if (vtkId < 0 || vtkId >= (myNodes.size() -1))
+  {
+    MESSAGE("------------------------------------------------------------------------- ");
+    MESSAGE("---------------------------- bad VTK ID " << vtkId << " " << myNodes.size());
+    MESSAGE("------------------------------------------------------------------------- ");
+    return 0;
+  }
+  return (const SMDS_MeshNode *)myNodes[vtkId+1];
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-///Create a triangle and add it to the current mesh. This methode do not bind a
+///Create a triangle and add it to the current mesh. This method do not bind an
 ///ID to the create triangle.
 ///////////////////////////////////////////////////////////////////////////////
 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
                                           const SMDS_MeshNode * node2,
-                                          const SMDS_MeshNode * node3)
+                                          const SMDS_MeshNode * node3,
+                                          int ID)
 {
   if ( !node1 || !node2 || !node3) return 0;
-  if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   if(hasConstructionEdges())
   {
     SMDS_MeshEdge *edge1, *edge2, *edge3;
@@ -1061,15 +1687,35 @@ SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
     edge2=FindEdgeOrCreate(node2,node3);
     edge3=FindEdgeOrCreate(node3,node1);
 
+    //int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
     SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
-    myFaces.Add(face);
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = face;
     myInfo.myNbTriangles++;
     return face;
   }
   else
   {
-    SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3);
-    myFaces.Add(face);
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(node1->getVtkId());
+    nodeIds.push_back(node2->getVtkId());
+    nodeIds.push_back(node3->getVtkId());
+
+    SMDS_MeshFace * face = 0;
+    SMDS_VtkFace *facevtk = myFacePool->getNew();
+    facevtk->init(nodeIds, this); // put in vtkUnstructuredGrid
+    if (!this->registerElement(ID,facevtk))
+      {
+        this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
+        myFacePool->destroy(facevtk);
+        return 0;
+      }
+    face = facevtk;
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = face;
+    //MESSAGE("createTriangle " << ID << " " << face);
     myInfo.myNbTriangles++;
     return face;
   }
@@ -1080,14 +1726,16 @@ SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
 ///a ID to the create triangle.
 ///////////////////////////////////////////////////////////////////////////////
 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
-                                           const SMDS_MeshNode * node2,
-                                           const SMDS_MeshNode * node3,
-                                           const SMDS_MeshNode * node4)
+                                            const SMDS_MeshNode * node2,
+                                            const SMDS_MeshNode * node3,
+                                            const SMDS_MeshNode * node4,
+                                            int ID)
 {
   if ( !node1 || !node2 || !node3 || !node4 ) return 0;
-  if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   if(hasConstructionEdges())
   {
+      //MESSAGE("createQuadrangle hasConstructionEdges "<< ID);
     SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
     edge1=FindEdgeOrCreate(node1,node2);
     edge2=FindEdgeOrCreate(node2,node3);
@@ -1095,14 +1743,33 @@ SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
     edge4=FindEdgeOrCreate(node4,node1);
 
     SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
-    myFaces.Add(face);
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = face;
     myInfo.myNbQuadrangles++;
     return face;
   }
   else
   {
-    SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4);
-    myFaces.Add(face);
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(node1->getVtkId());
+    nodeIds.push_back(node2->getVtkId());
+    nodeIds.push_back(node3->getVtkId());
+    nodeIds.push_back(node4->getVtkId());
+
+    SMDS_MeshFace * face = 0;
+    SMDS_VtkFace *facevtk = myFacePool->getNew();
+    facevtk->init(nodeIds, this);
+    if (!this->registerElement(ID,facevtk))
+      {
+        this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
+        myFacePool->destroy(facevtk);
+        return 0;
+      }
+    face = facevtk;
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = face;
     myInfo.myNbQuadrangles++;
     return face;
   }
@@ -1114,7 +1781,18 @@ SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
 
 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
 {
-       RemoveElement(node, true);
+    MESSAGE("RemoveNode");
+        RemoveElement(node, true);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Remove an edge and all the elements which own this edge
+///////////////////////////////////////////////////////////////////////////////
+
+void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
+{
+    MESSAGE("Remove0DElement");
+  RemoveElement(elem0d,true);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1123,7 +1801,8 @@ void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
 
 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
 {
-       RemoveElement(edge,true);
+    MESSAGE("RemoveEdge");
+        RemoveElement(edge,true);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1132,7 +1811,8 @@ void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
 
 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
 {
-       RemoveElement(face, true);
+    MESSAGE("RemoveFace");
+        RemoveElement(face, true);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1141,7 +1821,8 @@ void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
 
 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
 {
-       RemoveElement(volume, true);
+    MESSAGE("RemoveVolume");
+        RemoveElement(volume, true);
 }
 
 //=======================================================================
@@ -1151,8 +1832,8 @@ void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
 
 bool SMDS_Mesh::RemoveFromParent()
 {
-       if (myParent==NULL) return false;
-       else return (myParent->RemoveSubMesh(this));
+        if (myParent==NULL) return false;
+        else return (myParent->RemoveSubMesh(this));
 }
 
 //=======================================================================
@@ -1162,89 +1843,54 @@ bool SMDS_Mesh::RemoveFromParent()
 
 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
 {
-       bool found = false;
+        bool found = false;
 
-       list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
-       for (; itmsh!=myChildren.end() && !found; itmsh++)
-       {
-               SMDS_Mesh * submesh = *itmsh;
-               if (submesh == aMesh)
-               {
-                       found = true;
-                       myChildren.erase(itmsh);
-               }
-       }
+        list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
+        for (; itmsh!=myChildren.end() && !found; itmsh++)
+        {
+                SMDS_Mesh * submesh = *itmsh;
+                if (submesh == aMesh)
+                {
+                        found = true;
+                        myChildren.erase(itmsh);
+                }
+        }
 
-       return found;
+        return found;
 }
 
 //=======================================================================
 //function : ChangeElementNodes
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
                                    const SMDS_MeshNode    * nodes[],
                                    const int                nbnodes)
 {
+  MESSAGE("SMDS_Mesh::ChangeElementNodes");
   // keep current nodes of elem
-  set<const SMDS_MeshElement*> oldNodes;
-  SMDS_ElemIteratorPtr itn = element->nodesIterator();
-  while(itn->more())
-    oldNodes.insert(  itn->next() );
-
-  if ( !element->IsPoly() )
-    myInfo.remove( element ); // element may change type
+  set<const SMDS_MeshNode*> oldNodes( element->begin_nodes(), element->end_nodes() );
 
   // change nodes
   bool Ok = false;
-  SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(element);
-  switch ( elem->GetType() )
-  {
-  case SMDSAbs_Edge: {
-    if ( nbnodes == 2 ) {
-      if ( SMDS_MeshEdge* edge = dynamic_cast<SMDS_MeshEdge*>( elem ))
-        Ok = edge->ChangeNodes( nodes[0], nodes[1] );
-    }
-    else if ( nbnodes == 3 ) {
-      if ( SMDS_QuadraticEdge* edge = dynamic_cast<SMDS_QuadraticEdge*>( elem ))
-        Ok = edge->ChangeNodes( nodes[0], nodes[1], nodes[2] );
+  SMDS_MeshCell* cell = dynamic_cast<SMDS_MeshCell*>((SMDS_MeshElement*) element);
+  if (cell)
+    {
+      Ok = cell->vtkOrder(nodes, nbnodes);
+      Ok = cell->ChangeNodes(nodes, nbnodes);
     }
-    break;
-  }
-  case SMDSAbs_Face: {
-    if ( SMDS_FaceOfNodes* face = dynamic_cast<SMDS_FaceOfNodes*>( elem ))
-      Ok = face->ChangeNodes( nodes, nbnodes );
-    else
-      if ( SMDS_QuadraticFaceOfNodes* QF = dynamic_cast<SMDS_QuadraticFaceOfNodes*>( elem ))
-        Ok = QF->ChangeNodes( nodes, nbnodes );
-      else
-        if (SMDS_PolygonalFaceOfNodes* face = dynamic_cast<SMDS_PolygonalFaceOfNodes*>(elem))
-          Ok = face->ChangeNodes(nodes, nbnodes);
-    break;
-  }
-  case SMDSAbs_Volume: {
-    if ( SMDS_VolumeOfNodes* vol = dynamic_cast<SMDS_VolumeOfNodes*>( elem ))
-      Ok = vol->ChangeNodes( nodes, nbnodes );
-    else 
-      if ( SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast<SMDS_QuadraticVolumeOfNodes*>( elem ))
-        Ok = QV->ChangeNodes( nodes, nbnodes );
-    break;
-  }
-  default:
-    MESSAGE ( "WRONG ELEM TYPE");
-  }
 
   if ( Ok ) { // update InverseElements
 
-    set<const SMDS_MeshElement*>::iterator it;
+    set<const SMDS_MeshNode*>::iterator it;
 
     // AddInverseElement to new nodes
     for ( int i = 0; i < nbnodes; i++ ) {
       it = oldNodes.find( nodes[i] );
       if ( it == oldNodes.end() )
         // new node
-        const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( elem );
+        const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( cell );
       else
         // remove from oldNodes a node that remains in elem
         oldNodes.erase( it );
@@ -1252,15 +1898,11 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
     // RemoveInverseElement from the nodes removed from elem
     for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
     {
-      SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
-        (const_cast<SMDS_MeshElement *>( *it ));
-      n->RemoveInverseElement( elem );
+      SMDS_MeshNode * n = const_cast<SMDS_MeshNode *>( *it );
+      n->RemoveInverseElement( cell );
     }
   }
 
-  if ( !element->IsPoly() )
-    myInfo.add( element ); // element may change type
-
   return Ok;
 }
 
@@ -1277,7 +1919,7 @@ bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement *            elem,
     return false;
   }
 
-  const SMDS_PolyhedralVolumeOfNodes* vol = dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>(elem);
+  const SMDS_VtkVolume* vol = dynamic_cast<const SMDS_VtkVolume*>(elem);
   if (!vol) {
     return false;
   }
@@ -1290,7 +1932,9 @@ bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement *            elem,
   }
 
   // change nodes
-  bool Ok = const_cast<SMDS_PolyhedralVolumeOfNodes*>(vol)->ChangeNodes(nodes, quantities);
+  // TODO remove this function
+  //bool Ok = const_cast<SMDS_VtkVolume*>(vol)->ChangeNodes(nodes, quantities);
+  bool Ok = false;
   if (!Ok) {
     return false;
   }
@@ -1322,6 +1966,75 @@ bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement *            elem,
 }
 
 
+//=======================================================================
+//function : Find0DElement
+//purpose  :
+//=======================================================================
+const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(int idnode) const
+{
+  const SMDS_MeshNode * node = FindNode(idnode);
+  if(node == NULL) return NULL;
+  return Find0DElement(node);
+}
+
+const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
+{
+  if (!node) return 0;
+  const SMDS_Mesh0DElement* toReturn = NULL;
+  SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement);
+  while (it1->more() && (toReturn == NULL)) {
+    const SMDS_MeshElement* e = it1->next();
+    if (e->NbNodes() == 1) {
+      toReturn = static_cast<const SMDS_Mesh0DElement*>(e);
+    }
+  }
+  return toReturn;
+}
+
+//=======================================================================
+//function : FindBall
+//purpose  :
+//=======================================================================
+
+const SMDS_BallElement* SMDS_Mesh::FindBall(int idnode) const
+{
+  const SMDS_MeshNode * node = FindNode(idnode);
+  if(node == NULL) return NULL;
+  return FindBall(node);
+}
+
+const SMDS_BallElement* SMDS_Mesh::FindBall(const SMDS_MeshNode * node)
+{
+  if (!node) return 0;
+  const SMDS_BallElement* toReturn = NULL;
+  SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_Ball);
+  while (it1->more() && (toReturn == NULL)) {
+    const SMDS_MeshElement* e = it1->next();
+    if (e->GetGeomType() == SMDSGeom_BALL)
+      toReturn = static_cast<const SMDS_BallElement*>(e);
+  }
+  return toReturn;
+}
+
+//=======================================================================
+//function : Find0DElementOrCreate
+//purpose  :
+//=======================================================================
+//SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node)
+//{
+//  if (!node) return 0;
+//  SMDS_Mesh0DElement * toReturn = NULL;
+//  toReturn = const_cast<SMDS_Mesh0DElement*>(Find0DElement(node));
+//  if (toReturn == NULL) {
+//    //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
+//    toReturn = new SMDS_Mesh0DElement(node);
+//    my0DElements.Add(toReturn);
+//    myInfo.myNb0DElements++;
+//  }
+//  return toReturn;
+//}
+
+
 //=======================================================================
 //function : FindEdge
 //purpose  :
@@ -1364,15 +2077,30 @@ const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
 //=======================================================================
 
 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
-                                           const SMDS_MeshNode * node2) 
+                                           const SMDS_MeshNode * node2)
 {
   if ( !node1 || !node2) return 0;
   SMDS_MeshEdge * toReturn=NULL;
   toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
   if(toReturn==NULL) {
-    if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
-    toReturn=new SMDS_MeshEdge(node1,node2);
-    myEdges.Add(toReturn);
+    if ( NbEdges() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+    int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
+    adjustmyCellsCapacity(ID);
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(node1->getVtkId());
+    nodeIds.push_back(node2->getVtkId());
+
+    SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
+    edgevtk->init(nodeIds, this);
+    if (!this->registerElement(ID,edgevtk))
+      {
+        this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
+        myEdgePool->destroy(edgevtk);
+        return 0;
+      }
+    toReturn = edgevtk;
+    myCells[ID] = toReturn;
     myInfo.myNbEdges++;
   }
   return toReturn;
@@ -1427,7 +2155,7 @@ const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
 //=======================================================================
 
 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
-       int idnode3) const
+        int idnode3) const
 {
   const SMDS_MeshNode * node1=FindNode(idnode1);
   const SMDS_MeshNode * node2=FindNode(idnode2);
@@ -1469,7 +2197,8 @@ SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
   SMDS_MeshFace * toReturn=NULL;
   toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
   if(toReturn==NULL) {
-    toReturn = createTriangle(node1,node2,node3);
+    int ID = myElementIDFactory->GetFreeID();
+    toReturn = createTriangle(node1,node2,node3, ID);
   }
   return toReturn;
 }
@@ -1527,7 +2256,8 @@ SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
   SMDS_MeshFace * toReturn=NULL;
   toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
   if(toReturn==NULL) {
-    toReturn=createQuadrangle(node1,node2,node3,node4);
+    int ID = myElementIDFactory->GetFreeID();
+    toReturn=createQuadrangle(node1,node2,node3,node4,ID);
   }
   return toReturn;
 }
@@ -1651,7 +2381,16 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
 
 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
 {
-  return myElementIDFactory->MeshElement(IDelem);
+  if ((IDelem <= 0) || IDelem >= myCells.size())
+  {
+    MESSAGE("--------------------------------------------------------------------------------- ");
+    MESSAGE("----------------------------------- bad IDelem " << IDelem << " " << myCells.size());
+    MESSAGE("--------------------------------------------------------------------------------- ");
+    // TODO raise an exception
+    //assert(0);
+    return 0;
+  }
+  return myCells[IDelem];
 }
 
 //=======================================================================
@@ -1659,33 +2398,55 @@ const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
 //purpose  : find polygon
 //=======================================================================
 
-const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<int> nodes_ids) const
+const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<int>& nodes_ids) const
 {
   int nbnodes = nodes_ids.size();
-  std::vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
+  vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
   for (int inode = 0; inode < nbnodes; inode++) {
     const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
     if (node == NULL) return NULL;
+    poly_nodes[inode] = node;
   }
   return FindFace(poly_nodes);
 }
 
-const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<const SMDS_MeshNode *> nodes)
+const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<const SMDS_MeshNode *>& nodes)
 {
-  if ( nodes.size() > 2 && nodes[0] ) {
-    SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
-    while (itF->more()) {
-      const SMDS_MeshElement* f = itF->next();
-      if ( f->NbNodes() == nodes.size() ) {
-        SMDS_ElemIteratorPtr it2 = f->nodesIterator();
-        while(it2->more()) {
-          if ( find( nodes.begin(), nodes.end(), it2->next() ) == nodes.end() ) {
-            f = 0;
-            break;
-          }
+  return (const SMDS_MeshFace*) FindElement( nodes, SMDSAbs_Face );
+}
+
+
+//================================================================================
+/*!
+ * \brief Return element based on all given nodes
+ *  \param nodes - node of element
+ *  \param type - type of element
+ *  \param noMedium - true if medium nodes of quadratic element are not included in <nodes>
+ *  \retval const SMDS_MeshElement* - found element or NULL
+ */
+//================================================================================
+
+const SMDS_MeshElement* SMDS_Mesh::FindElement (const vector<const SMDS_MeshNode *>& nodes,
+                                                const SMDSAbs_ElementType            type,
+                                                const bool                           noMedium)
+{
+  if ( nodes.size() > 0 && nodes[0] )
+  {
+    SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(type);
+    while (itF->more())
+    {
+      const SMDS_MeshElement* e = itF->next();
+      int nbNodesToCheck = noMedium ? e->NbCornerNodes() : e->NbNodes();
+      if ( nbNodesToCheck == nodes.size() )
+      {
+        for ( int i = 1; e && i < nodes.size(); ++ i )
+        {
+          int nodeIndex = e->GetNodeIndex( nodes[ i ]);
+          if ( nodeIndex < 0 || nodeIndex >= nbNodesToCheck )
+            e = 0;
         }
-        if ( f )
-          return static_cast<const SMDS_MeshFace *> (f);
+        if ( e )
+          return static_cast<const SMDS_MeshFace *> (e);
       }
     }
   }
@@ -1694,100 +2455,111 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<const SMDS_MeshNode *> nod
 
 //=======================================================================
 //function : DumpNodes
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 void SMDS_Mesh::DumpNodes() const
 {
-       MESSAGE("dump nodes of mesh : ");
-       SMDS_NodeIteratorPtr itnode=nodesIterator();
-       while(itnode->more()) MESSAGE(itnode->next());
+        MESSAGE("dump nodes of mesh : ");
+        SMDS_NodeIteratorPtr itnode=nodesIterator();
+        while(itnode->more()) ; //MESSAGE(itnode->next());
+}
+
+//=======================================================================
+//function : Dump0DElements
+//purpose  :
+//=======================================================================
+void SMDS_Mesh::Dump0DElements() const
+{
+  MESSAGE("dump 0D elements of mesh : ");
+  SMDS_ElemIteratorPtr it0d = elementsIterator(SMDSAbs_0DElement);
+  while(it0d->more()) ; //MESSAGE(it0d->next());
 }
 
 //=======================================================================
 //function : DumpEdges
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 void SMDS_Mesh::DumpEdges() const
 {
-       MESSAGE("dump edges of mesh : ");
-       SMDS_EdgeIteratorPtr itedge=edgesIterator();
-       while(itedge->more()) MESSAGE(itedge->next());
+        MESSAGE("dump edges of mesh : ");
+        SMDS_EdgeIteratorPtr itedge=edgesIterator();
+        while(itedge->more()) ; //MESSAGE(itedge->next());
 }
 
 //=======================================================================
 //function : DumpFaces
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 void SMDS_Mesh::DumpFaces() const
 {
-       MESSAGE("dump faces of mesh : ");
-       SMDS_FaceIteratorPtr itface=facesIterator();
-       while(itface->more()) MESSAGE(itface->next());
+        MESSAGE("dump faces of mesh : ");
+        SMDS_FaceIteratorPtr itface=facesIterator();
+        while(itface->more()) ; //MESSAGE(itface->next());
 }
 
 //=======================================================================
 //function : DumpVolumes
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 void SMDS_Mesh::DumpVolumes() const
 {
-       MESSAGE("dump volumes of mesh : ");
-       SMDS_VolumeIteratorPtr itvol=volumesIterator();
-       while(itvol->more()) MESSAGE(itvol->next());
+        MESSAGE("dump volumes of mesh : ");
+        SMDS_VolumeIteratorPtr itvol=volumesIterator();
+        while(itvol->more()) ; //MESSAGE(itvol->next());
 }
 
 //=======================================================================
 //function : DebugStats
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 void SMDS_Mesh::DebugStats() const
 {
-       MESSAGE("Debug stats of mesh : ");
+  MESSAGE("Debug stats of mesh : ");
 
-       MESSAGE("===== NODES ====="<<NbNodes());
-       MESSAGE("===== EDGES ====="<<NbEdges());
-       MESSAGE("===== FACES ====="<<NbFaces());
-       MESSAGE("===== VOLUMES ====="<<NbVolumes());
+  MESSAGE("===== NODES ====="<<NbNodes());
+  MESSAGE("===== 0DELEMS ====="<<Nb0DElements());
+  MESSAGE("===== EDGES ====="<<NbEdges());
+  MESSAGE("===== FACES ====="<<NbFaces());
+  MESSAGE("===== VOLUMES ====="<<NbVolumes());
 
-       MESSAGE("End Debug stats of mesh ");
+  MESSAGE("End Debug stats of mesh ");
 
-       //#ifdef DEB
-       
-       SMDS_NodeIteratorPtr itnode=nodesIterator();
-       int sizeofnodes = 0;
-       int sizeoffaces = 0;
+  //#ifdef DEB
 
-       while(itnode->more())
-       {
-               const SMDS_MeshNode *node = itnode->next();
+  SMDS_NodeIteratorPtr itnode=nodesIterator();
+  int sizeofnodes = 0;
+  int sizeoffaces = 0;
 
-               sizeofnodes += sizeof(*node);
-               
-               SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
-               while(it->more())
-               {
-                       const SMDS_MeshElement *me = it->next();
-                       sizeofnodes += sizeof(me);
-               }
+  while(itnode->more())
+  {
+    const SMDS_MeshNode *node = itnode->next();
+
+    sizeofnodes += sizeof(*node);
 
-       }
+    SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
+    while(it->more())
+    {
+      const SMDS_MeshElement *me = it->next();
+      sizeofnodes += sizeof(me);
+    }
+  }
 
-       SMDS_FaceIteratorPtr itface=facesIterator();
-       while(itface->more())
-       {
-               const SMDS_MeshElement *face = itface->next();          
-               sizeoffaces += sizeof(*face);
+  SMDS_FaceIteratorPtr itface=facesIterator();
+  while(itface->more())
+  {
+    const SMDS_MeshElement *face = itface->next();
+    sizeoffaces += sizeof(*face);
+  }
 
-       }
-       MESSAGE("total size of node elements = " << sizeofnodes);;
-       MESSAGE("total size of face elements = " << sizeoffaces);;
+  MESSAGE("total size of node elements = " << sizeofnodes);;
+  MESSAGE("total size of face elements = " << sizeoffaces);;
 
-       //#endif
+  //#endif
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1795,7 +2567,26 @@ void SMDS_Mesh::DebugStats() const
 ///////////////////////////////////////////////////////////////////////////////
 int SMDS_Mesh::NbNodes() const
 {
-       return myNodes.Size();
+        //MESSAGE(myGrid->GetNumberOfPoints());
+        //MESSAGE(myInfo.NbNodes());
+        //MESSAGE(myNodeMax);
+    return myInfo.NbNodes();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Return the number of 0D elements
+///////////////////////////////////////////////////////////////////////////////
+int SMDS_Mesh::Nb0DElements() const
+{
+  return myInfo.Nb0DElements();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Return the number of 0D elements
+///////////////////////////////////////////////////////////////////////////////
+int SMDS_Mesh::NbBalls() const
+{
+  return myInfo.NbBalls();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1803,7 +2594,7 @@ int SMDS_Mesh::NbNodes() const
 ///////////////////////////////////////////////////////////////////////////////
 int SMDS_Mesh::NbEdges() const
 {
-       return myEdges.Size();
+  return myInfo.NbEdges();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1811,7 +2602,7 @@ int SMDS_Mesh::NbEdges() const
 ///////////////////////////////////////////////////////////////////////////////
 int SMDS_Mesh::NbFaces() const
 {
-       return myFaces.Size();
+  return myInfo.NbFaces();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1819,17 +2610,16 @@ int SMDS_Mesh::NbFaces() const
 ///////////////////////////////////////////////////////////////////////////////
 int SMDS_Mesh::NbVolumes() const
 {
-       return myVolumes.Size();
+  return myInfo.NbVolumes();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 /// Return the number of child mesh of this mesh.
-/// Note that the tree structure of SMDS_Mesh seems to be unused in this version
-/// (2003-09-08) of SMESH
+/// Note that the tree structure of SMDS_Mesh is unused in SMESH
 ///////////////////////////////////////////////////////////////////////////////
 int SMDS_Mesh::NbSubMesh() const
 {
-       return myChildren.size();
+  return myChildren.size();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1854,36 +2644,18 @@ SMDS_Mesh::~SMDS_Mesh()
   {
     SMDS_ElemIteratorPtr eIt = elementsIterator();
     while ( eIt->more() )
-      myElementIDFactory->ReleaseID(eIt->next()->GetID());
+      {
+        const SMDS_MeshElement *elem = eIt->next();
+        myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
+      }
     SMDS_NodeIteratorPtr itn = nodesIterator();
     while (itn->more())
-      myNodeIDFactory->ReleaseID(itn->next()->GetID());
-  }
-  SetOfNodes::Iterator itn(myNodes);
-  for (; itn.More(); itn.Next())
-    delete itn.Value();
-
-  SetOfEdges::Iterator ite(myEdges);
-  for (; ite.More(); ite.Next())
-  {
-    SMDS_MeshElement* elem = ite.Value();
-    delete elem;
-  }
-
-  SetOfFaces::Iterator itf(myFaces);
-  for (; itf.More(); itf.Next())
-  {
-    SMDS_MeshElement* elem = itf.Value();
-    delete elem;
-  }
-
-  SetOfVolumes::Iterator itv(myVolumes);
-  for (; itv.More(); itv.Next())
-  {
-    SMDS_MeshElement* elem = itv.Value();
-    delete elem;
+      {
+        const SMDS_MeshNode *node = itn->next();
+        ((SMDS_MeshNode*)node)->SetPosition(SMDS_SpacePosition::originSpacePosition());
+        myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
+      }
   }
-
 }
 
 //================================================================================
@@ -1894,43 +2666,88 @@ SMDS_Mesh::~SMDS_Mesh()
 
 void SMDS_Mesh::Clear()
 {
-  if (myParent!=NULL) {
+  MESSAGE("SMDS_Mesh::Clear");
+  if (myParent!=NULL)
+    {
     SMDS_ElemIteratorPtr eIt = elementsIterator();
     while ( eIt->more() )
-      myElementIDFactory->ReleaseID(eIt->next()->GetID());
+      {
+        const SMDS_MeshElement *elem = eIt->next();
+        myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
+      }
     SMDS_NodeIteratorPtr itn = nodesIterator();
     while (itn->more())
-      myNodeIDFactory->ReleaseID(itn->next()->GetID());
-  }
-  else {
+      {
+        const SMDS_MeshNode *node = itn->next();
+        myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
+      }
+    }
+  else
+    {
     myNodeIDFactory->Clear();
     myElementIDFactory->Clear();
-  }
-  SMDS_VolumeIteratorPtr itv = volumesIterator();
+    }
+
+  SMDS_ElemIteratorPtr itv = elementsIterator();
   while (itv->more())
-    delete itv->next();
-  myVolumes.Clear();
-
-  SMDS_FaceIteratorPtr itf = facesIterator();
-  while (itf->more())
-    delete itf->next();
-  myFaces.Clear();
-      
-  SMDS_EdgeIteratorPtr ite = edgesIterator();
-  while (ite->more())
-    delete ite->next();
-  myEdges.Clear();
+    {
+      SMDS_MeshElement* elem = (SMDS_MeshElement*)(itv->next());
+      SMDSAbs_ElementType aType = elem->GetType();
+      switch (aType)
+      {
+        case SMDSAbs_0DElement:
+          delete elem;
+          break;
+        case SMDSAbs_Edge:
+           myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(elem));
+          break;
+        case SMDSAbs_Face:
+          myFacePool->destroy(static_cast<SMDS_VtkFace*>(elem));
+          break;
+        case SMDSAbs_Volume:
+          myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(elem));
+          break;
+        case SMDSAbs_Ball:
+          myBallPool->destroy(static_cast<SMDS_BallElement*>(elem));
+          break;
+        default:
+          break;
+      }
+    }
+  myCells.clear();
+  myCellIdVtkToSmds.clear();
+  //myCellIdSmdsToVtk.clear();
 
   SMDS_NodeIteratorPtr itn = nodesIterator();
   while (itn->more())
-    delete itn->next();
-  myNodes.Clear();
+    {
+      SMDS_MeshNode *node = (SMDS_MeshNode*)(itn->next());
+      node->SetPosition(SMDS_SpacePosition::originSpacePosition());
+      myNodePool->destroy(node);
+    }
+  myNodes.clear();
 
   list<SMDS_Mesh*>::iterator itc=myChildren.begin();
   while(itc!=myChildren.end())
     (*itc)->Clear();
 
+  myModified = false;
+  xmin = 0; xmax = 0;
+  ymin = 0; ymax = 0;
+  zmin = 0; zmax = 0;
+
   myInfo.Clear();
+
+  myGrid->Initialize();
+  myGrid->Allocate();
+  vtkPoints* points = vtkPoints::New();
+  // rnv: to fix bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion"
+  // using double type for storing coordinates of nodes instead float.
+  points->SetDataType(VTK_DOUBLE);
+  points->SetNumberOfPoints(0 /*SMDS_Mesh::chunkSize*/);
+  myGrid->SetPoints( points );
+  points->Delete();
+  myGrid->BuildLinks();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1940,7 +2757,7 @@ void SMDS_Mesh::Clear()
 ///////////////////////////////////////////////////////////////////////////////
 bool SMDS_Mesh::hasConstructionEdges()
 {
-       return myHasConstructionEdges;
+        return myHasConstructionEdges;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1952,7 +2769,7 @@ bool SMDS_Mesh::hasConstructionEdges()
 ///////////////////////////////////////////////////////////////////////////////
 bool SMDS_Mesh::hasConstructionFaces()
 {
-       return myHasConstructionFaces;
+        return myHasConstructionFaces;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1961,7 +2778,7 @@ bool SMDS_Mesh::hasConstructionFaces()
 ///////////////////////////////////////////////////////////////////////////////
 bool SMDS_Mesh::hasInverseElements()
 {
-       return myHasInverseElements;
+        return myHasInverseElements;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1970,7 +2787,7 @@ bool SMDS_Mesh::hasInverseElements()
 ///////////////////////////////////////////////////////////////////////////////
 void SMDS_Mesh::setConstructionEdges(bool b)
 {
-       myHasConstructionEdges=b;
+        myHasConstructionEdges=b;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1979,7 +2796,7 @@ void SMDS_Mesh::setConstructionEdges(bool b)
 ///////////////////////////////////////////////////////////////////////////////
 void SMDS_Mesh::setConstructionFaces(bool b)
 {
-        myHasConstructionFaces=b;
+         myHasConstructionFaces=b;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1988,283 +2805,339 @@ void SMDS_Mesh::setConstructionFaces(bool b)
 ///////////////////////////////////////////////////////////////////////////////
 void SMDS_Mesh::setInverseElements(bool b)
 {
-       if(!b) MESSAGE("Error : inverseElement=false not implemented");
-       myHasInverseElements=b;
+  if(!b) MESSAGE("Error : inverseElement=false not implemented");
+  myHasInverseElements=b;
+}
+
+namespace {
+
+  //================================================================================
+  /*!
+   * \brief Iterator on elements in id increasing order
+   */
+  //================================================================================
+
+  template <typename ELEM=const SMDS_MeshElement*>
+  class IdSortedIterator : public SMDS_Iterator<ELEM>
+  {
+    SMDS_MeshElementIDFactory&       myIDFact;
+    int                              myID, myMaxID, myNbFound, myTotalNb;
+    SMDSAbs_ElementType              myType;
+    ELEM                             myElem;
+
+  public:
+    IdSortedIterator(const SMDS_MeshElementIDFactory& fact,
+                     const SMDSAbs_ElementType        type, // SMDSAbs_All NOT allowed!!! 
+                     const int                        totalNb)
+      :myIDFact( fact ),
+       myID(1), myMaxID( myIDFact.GetMaxID() ),myNbFound(0), myTotalNb( totalNb ),
+       myType( type ),
+       myElem(0)
+    {
+      next();
+    }
+    bool more()
+    {
+      return myElem;
+    }
+    ELEM next()
+    {
+      ELEM current = myElem;
+
+      for ( myElem = 0;  !myElem && myNbFound < myTotalNb && myID <= myMaxID; ++myID )
+        if ((myElem = (ELEM) myIDFact.MeshElement( myID ))
+            && myElem->GetType() != myType )
+          myElem = 0;
+
+      myNbFound += bool(myElem);
+
+      return current;
+    }
+  };
+
+  //================================================================================
+  /*!
+   * \brief Iterator on vector of elements, possibly being resized while iteration
+   */
+  //================================================================================
+
+  template<typename RETURN_VALUE,
+           typename VECTOR_VALUE=SMDS_MeshCell*,
+           typename VALUE_FILTER=SMDS::NonNullFilter<VECTOR_VALUE> >
+  class ElemVecIterator: public SMDS_Iterator<RETURN_VALUE>
+  {
+    const std::vector<VECTOR_VALUE>& _vector;
+    size_t                           _index;
+    bool                             _more;
+    VALUE_FILTER                     _filter;
+  public:
+    ElemVecIterator(const std::vector<VECTOR_VALUE>& vec,
+                    const VALUE_FILTER&              filter=VALUE_FILTER() )
+      :_vector( vec ), _index(0), _more( !vec.empty() ), _filter( filter )
+    {
+      if ( _more && !_filter( _vector[ _index ]))
+        next();
+    }
+    virtual bool more()
+    {
+      return _more;
+    }
+    virtual RETURN_VALUE next()
+    {
+      if ( !_more ) return NULL;
+      VECTOR_VALUE current = _vector[ _index ];
+      _more = 0;
+      while ( !_more && ++_index < _vector.size() )
+        _more = _filter( _vector[ _index ]);
+      return (RETURN_VALUE) current;
+    }
+  };
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 /// Return an iterator on nodes of the current mesh factory
 ///////////////////////////////////////////////////////////////////////////////
-class SMDS_Mesh_MyNodeIterator:public SMDS_NodeIterator
-{
-  SMDS_ElemIteratorPtr myIterator;
- public:
-  SMDS_Mesh_MyNodeIterator(const SMDS_ElemIteratorPtr& it):myIterator(it)
-  {}
 
-  bool more()
-  {
-    return myIterator->more();
-  }
+SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator(bool idInceasingOrder) const
+{
+  // naturally always sorted by ID
+  typedef ElemVecIterator<const SMDS_MeshNode*, SMDS_MeshNode*> TIterator;
+  return SMDS_NodeIteratorPtr( new TIterator(myNodes));
+}
 
-  const SMDS_MeshNode* next()
-  {
-    return static_cast<const SMDS_MeshNode*>(myIterator->next());
-  }
-};
+SMDS_ElemIteratorPtr SMDS_Mesh::elementGeomIterator(SMDSAbs_GeometryType type) const
+{
+  // naturally always sorted by ID
+  typedef ElemVecIterator
+    < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::GeomFilter > TIterator;
+  return SMDS_ElemIteratorPtr
+    (new TIterator(myCells, SMDS_MeshElement::GeomFilter( type )));
+}
 
-SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
+SMDS_ElemIteratorPtr SMDS_Mesh::elementEntityIterator(SMDSAbs_EntityType type) const
 {
-  return SMDS_NodeIteratorPtr
-    (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator()));
+  // naturally always sorted by ID
+  typedef ElemVecIterator
+    < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::EntityFilter > TIterator;
+  return SMDS_ElemIteratorPtr
+    (new TIterator(myCells, SMDS_MeshElement::EntityFilter( type )));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 /// Return an iterator on elements of the current mesh factory
 ///////////////////////////////////////////////////////////////////////////////
-SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator() const
+SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
 {
-  return myElementIDFactory->elementsIterator();
+  // naturally always sorted by ID
+  switch ( type ) {
+
+  case SMDSAbs_All:
+    return SMDS_ElemIteratorPtr (new ElemVecIterator<const SMDS_MeshElement*>(myCells));
+
+  case SMDSAbs_Node:
+    return SMDS_ElemIteratorPtr
+      ( new ElemVecIterator<const SMDS_MeshElement*, SMDS_MeshNode*>( myNodes ));
+
+  default:
+    typedef ElemVecIterator
+      < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator;
+    return SMDS_ElemIteratorPtr (new TIterator(myCells, SMDS_MeshElement::TypeFilter( type )));
+  }
+  return SMDS_ElemIteratorPtr();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 ///Return an iterator on edges of the current mesh.
 ///////////////////////////////////////////////////////////////////////////////
-class SMDS_Mesh_MyEdgeIterator:public SMDS_EdgeIterator
-{
-  typedef SMDS_Mesh::SetOfEdges SetOfEdges;
-  SetOfEdges::Iterator myIterator;
- public:
-  SMDS_Mesh_MyEdgeIterator(const SetOfEdges& s):myIterator(s)
-  {}
 
-  bool more()
-  {
-    while(myIterator.More())
-    {
-      if(myIterator.Value()->GetID()!=-1)
-        return true;
-      myIterator.Next();
-    }
-    return false;
-  }
-
-  const SMDS_MeshEdge* next()
-  {
-    const SMDS_MeshEdge* current = myIterator.Value();
-    myIterator.Next();
-    return current;
-  }
-};
-
-SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
+SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator(bool idInceasingOrder) const
 {
-  return SMDS_EdgeIteratorPtr(new SMDS_Mesh_MyEdgeIterator(myEdges));
+  // naturally always sorted by ID
+  typedef ElemVecIterator
+    < const SMDS_MeshEdge*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator;
+  return SMDS_EdgeIteratorPtr
+    (new TIterator(myCells, SMDS_MeshElement::TypeFilter( SMDSAbs_Edge )));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 ///Return an iterator on faces of the current mesh.
 ///////////////////////////////////////////////////////////////////////////////
-class SMDS_Mesh_MyFaceIterator:public SMDS_FaceIterator
-{
-  typedef SMDS_Mesh::SetOfFaces SetOfFaces;
-  SetOfFaces::Iterator myIterator;
- public:
-  SMDS_Mesh_MyFaceIterator(const SetOfFaces& s):myIterator(s)
-  {}
-
-  bool more()
-  {
-    while(myIterator.More())
-    {
-      if(myIterator.Value()->GetID()!=-1)
-        return true;
-      myIterator.Next();
-    }
-    return false;
-  }
 
-  const SMDS_MeshFace* next()
-  {
-    const SMDS_MeshFace* current = myIterator.Value();
-    myIterator.Next();
-    return current;
-  }
-};
-
-SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
+SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator(bool idInceasingOrder) const
 {
-  return SMDS_FaceIteratorPtr(new SMDS_Mesh_MyFaceIterator(myFaces));
+  // naturally always sorted by ID
+  typedef ElemVecIterator
+    < const SMDS_MeshFace*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator;
+  return SMDS_FaceIteratorPtr
+    (new TIterator(myCells, SMDS_MeshElement::TypeFilter( SMDSAbs_Face )));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 ///Return an iterator on volumes of the current mesh.
 ///////////////////////////////////////////////////////////////////////////////
-class SMDS_Mesh_MyVolumeIterator:public SMDS_VolumeIterator
-{
-  typedef SMDS_Mesh::SetOfVolumes SetOfVolumes;
-  SetOfVolumes::Iterator myIterator;
- public:
-  SMDS_Mesh_MyVolumeIterator(const SetOfVolumes& s):myIterator(s)
-  {}
-
-  bool more()
-  {
-    return myIterator.More() != Standard_False;
-  }
-
-  const SMDS_MeshVolume* next()
-  {
-    const SMDS_MeshVolume* current = myIterator.Value();
-    myIterator.Next();
-    return current;
-  }
-};
 
-SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
+SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator(bool idInceasingOrder) const
 {
-  return SMDS_VolumeIteratorPtr(new SMDS_Mesh_MyVolumeIterator(myVolumes));
+  // naturally always sorted by ID
+  typedef ElemVecIterator
+    < const SMDS_MeshVolume*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator;
+  return SMDS_VolumeIteratorPtr
+    (new TIterator(myCells, SMDS_MeshElement::TypeFilter( SMDSAbs_Volume )));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 /// Do intersection of sets (more than 2)
 ///////////////////////////////////////////////////////////////////////////////
 static set<const SMDS_MeshElement*> * intersectionOfSets(
-       set<const SMDS_MeshElement*> vs[], int numberOfSets)
+        set<const SMDS_MeshElement*> vs[], int numberOfSets)
 {
-       set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
-       set<const SMDS_MeshElement*>* rsetB;
+        set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
+        set<const SMDS_MeshElement*>* rsetB;
 
-       for(int i=0; i<numberOfSets-1; i++)
-       {
-               rsetB=new set<const SMDS_MeshElement*>();
-               set_intersection(
-                       rsetA->begin(), rsetA->end(),
-                       vs[i+1].begin(), vs[i+1].end(),
-                       inserter(*rsetB, rsetB->begin()));
-               delete rsetA;
-               rsetA=rsetB;
-       }
-       return rsetA;
+        for(int i=0; i<numberOfSets-1; i++)
+        {
+                rsetB=new set<const SMDS_MeshElement*>();
+                set_intersection(
+                        rsetA->begin(), rsetA->end(),
+                        vs[i+1].begin(), vs[i+1].end(),
+                        inserter(*rsetB, rsetB->begin()));
+                delete rsetA;
+                rsetA=rsetB;
+        }
+        return rsetA;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-/// Return the list of finit elements owning the given element
+/// Return the list of finite elements owning the given element: elements
+/// containing all the nodes of the given element, for instance faces and
+/// volumes containing a given edge.
 ///////////////////////////////////////////////////////////////////////////////
 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
 {
-       int numberOfSets=element->NbNodes();
-       set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
+        int numberOfSets=element->NbNodes();
+        set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
 
-       SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
+        SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
 
-       int i=0;
-       while(itNodes->more())
-       {
-               const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
-               SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
+        int i=0;
+        while(itNodes->more())
+        {
+          const SMDS_MeshElement* node = itNodes->next();
+          MYASSERT(node);
+                const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(node);
+                SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
+
+                //initSet[i]=set<const SMDS_MeshElement*>();
+                while(itFe->more())
+                {
+                  const SMDS_MeshElement* elem = itFe->next();
+                  MYASSERT(elem);
+                  initSet[i].insert(elem);
 
-               //initSet[i]=set<const SMDS_MeshElement*>();
-               while(itFe->more())
-                  initSet[i].insert(itFe->next());
+                }
 
-               i++;
-       }
-       set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
+                i++;
+        }
+        set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
+//         MESSAGE("nb elems " << i << " intersection " << retSet->size());
         delete [] initSet;
-       return retSet;
+        return retSet;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 /// Return the list of nodes used only by the given elements
 ///////////////////////////////////////////////////////////////////////////////
 static set<const SMDS_MeshElement*> * getExclusiveNodes(
-       set<const SMDS_MeshElement*>& elements)
-{
-       set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
-       set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
-
-       while(itElements!=elements.end())
-       {
-               SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
-               itElements++;
-       
-               while(itNodes->more())
-               {
-                       const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
-                       SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
-                       set<const SMDS_MeshElement*> s;
-                       while(itFe->more())
+        set<const SMDS_MeshElement*>& elements)
+{
+        set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
+        set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
+
+        while(itElements!=elements.end())
+        {
+                SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
+                itElements++;
+
+                while(itNodes->more())
+                {
+                        const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
+                        SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
+                        set<const SMDS_MeshElement*> s;
+                        while(itFe->more())
                           s.insert(itFe->next());
-                       if(s==elements) toReturn->insert(n);
-               }
-       }
-       return toReturn;        
+                        if(s==elements) toReturn->insert(n);
+                }
+        }
+        return toReturn;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-///Find the children of an element that are made of given nodes 
+///Find the children of an element that are made of given nodes
 ///@param setOfChildren The set in which matching children will be inserted
 ///@param element The element were to search matching children
 ///@param nodes The nodes that the children must have to be selected
 ///////////////////////////////////////////////////////////////////////////////
-void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>&     setOfChildren, 
-       const SMDS_MeshElement * element, set<const SMDS_MeshElement*>& nodes)
-{
-       
-       switch(element->GetType())
-       {
-       case SMDSAbs_Node:
-               MESSAGE("Internal Error: This should not append");
-               break;
-       case SMDSAbs_Edge:
-       {
-               SMDS_ElemIteratorPtr itn=element->nodesIterator();
-               while(itn->more())
-               {
-                       const SMDS_MeshElement * e=itn->next();
-                       if(nodes.find(e)!=nodes.end())
+void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
+                                     const SMDS_MeshElement *      element,
+                                     set<const SMDS_MeshElement*>& nodes)
+{
+  switch(element->GetType())
+    {
+    case SMDSAbs_Node:
+      MESSAGE("Internal Error: This should not happen");
+      break;
+    case SMDSAbs_0DElement:
+      {
+      }
+      break;
+    case SMDSAbs_Edge:
+        {
+                SMDS_ElemIteratorPtr itn=element->nodesIterator();
+                while(itn->more())
+                {
+                        const SMDS_MeshElement * e=itn->next();
+                        if(nodes.find(e)!=nodes.end())
                         {
                           setOfChildren.insert(element);
                           break;
                         }
-               }
-       } break;
-       case SMDSAbs_Face:
-       {
-               SMDS_ElemIteratorPtr itn=element->nodesIterator();
-               while(itn->more())
-               {
-                       const SMDS_MeshElement * e=itn->next();
-                       if(nodes.find(e)!=nodes.end())
+                }
+        } break;
+    case SMDSAbs_Face:
+        {
+                SMDS_ElemIteratorPtr itn=element->nodesIterator();
+                while(itn->more())
+                {
+                        const SMDS_MeshElement * e=itn->next();
+                        if(nodes.find(e)!=nodes.end())
                         {
                           setOfChildren.insert(element);
                           break;
                         }
-               }
-               if(hasConstructionEdges())
-               {
-                       SMDS_ElemIteratorPtr ite=element->edgesIterator();
-                       while(ite->more())
-                               addChildrenWithNodes(setOfChildren, ite->next(), nodes);
-               }
-       } break;        
-       case SMDSAbs_Volume:
-       {
-               if(hasConstructionFaces())
-               {
-                       SMDS_ElemIteratorPtr ite=element->facesIterator();
-                       while(ite->more())
-                               addChildrenWithNodes(setOfChildren, ite->next(), nodes);
-               }
-               else if(hasConstructionEdges())
-               {
-                       SMDS_ElemIteratorPtr ite=element->edgesIterator();
-                       while(ite->more())
-                               addChildrenWithNodes(setOfChildren, ite->next(), nodes);
-               }
-       }
-       }
+                }
+                if(hasConstructionEdges())
+                {
+                        SMDS_ElemIteratorPtr ite=element->edgesIterator();
+                        while(ite->more())
+                                addChildrenWithNodes(setOfChildren, ite->next(), nodes);
+                }
+        } break;
+    case SMDSAbs_Volume:
+        {
+                if(hasConstructionFaces())
+                {
+                        SMDS_ElemIteratorPtr ite=element->facesIterator();
+                        while(ite->more())
+                                addChildrenWithNodes(setOfChildren, ite->next(), nodes);
+                }
+                else if(hasConstructionEdges())
+                {
+                        SMDS_ElemIteratorPtr ite=element->edgesIterator();
+                        while(ite->more())
+                                addChildrenWithNodes(setOfChildren, ite->next(), nodes);
+                }
+        }
+    }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -2272,17 +3145,17 @@ void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>&      setOfChildren
 ///@param removenodes if true remaining nodes will be removed
 ///////////////////////////////////////////////////////////////////////////////
 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
-       const bool removenodes)
+                              const bool removenodes)
 {
   list<const SMDS_MeshElement *> removedElems;
   list<const SMDS_MeshElement *> removedNodes;
   RemoveElement( elem, removedElems, removedNodes, removenodes );
 }
-  
+
 ///////////////////////////////////////////////////////////////////////////////
 ///@param elem The element to delete
-///@param removedElems contains all removed elements
-///@param removedNodes contains all removed nodes
+///@param removedElems to be filled with all removed elements
+///@param removedNodes to be filled with all removed nodes
 ///@param removenodes if true remaining nodes will be removed
 ///////////////////////////////////////////////////////////////////////////////
 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
@@ -2290,125 +3163,195 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
                               list<const SMDS_MeshElement *>& removedNodes,
                               bool                            removenodes)
 {
+  //MESSAGE("SMDS_Mesh::RemoveElement " << elem->getVtkId() << " " << removenodes);
   // get finite elements built on elem
   set<const SMDS_MeshElement*> * s1;
-  if (!hasConstructionEdges() && elem->GetType() == SMDSAbs_Edge ||
-      !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face ||
-      elem->GetType() == SMDSAbs_Volume)
-  {
-    s1 = new set<const SMDS_MeshElement*>();
-    s1->insert(elem);
-  }
+  if (    (elem->GetType() == SMDSAbs_0DElement)
+      || ((elem->GetType() == SMDSAbs_Edge) && !hasConstructionEdges())
+      || ((elem->GetType() == SMDSAbs_Face) && !hasConstructionFaces())
+      ||  (elem->GetType() == SMDSAbs_Volume) )
+    {
+      s1 = new set<const SMDS_MeshElement*> ();
+      s1->insert(elem);
+    }
   else
     s1 = getFinitElements(elem);
 
   // get exclusive nodes (which would become free afterwards)
   set<const SMDS_MeshElement*> * s2;
   if (elem->GetType() == SMDSAbs_Node) // a node is removed
-  {
-    // do not remove nodes except elem
-    s2 = new set<const SMDS_MeshElement*>();
-    s2->insert(elem);
-    removenodes = true;
-  }
+    {
+      // do not remove nodes except elem
+      s2 = new set<const SMDS_MeshElement*> ();
+      s2->insert(elem);
+      removenodes = true;
+    }
   else
     s2 = getExclusiveNodes(*s1);
 
   // form the set of finite and construction elements to remove
   set<const SMDS_MeshElement*> s3;
-  set<const SMDS_MeshElement*>::iterator it=s1->begin();
-  while(it!=s1->end())
-  {
-    addChildrenWithNodes(s3, *it ,*s2);
-    s3.insert(*it);
-    it++;
-  }
-  if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
+  set<const SMDS_MeshElement*>::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 <InverseElements> of its nodes
-    SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
-    while(itn->more())
+  it = s3.begin();
+  while (it != s3.end())
     {
-      SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
-        (const_cast<SMDS_MeshElement *>(itn->next()));
-      n->RemoveInverseElement( (*it) );
+      // Remove element from <InverseElements> of its nodes
+      SMDS_ElemIteratorPtr itn = (*it)->nodesIterator();
+      while (itn->more())
+        {
+          SMDS_MeshNode * n = static_cast<SMDS_MeshNode *> (const_cast<SMDS_MeshElement *> (itn->next()));
+          n->RemoveInverseElement((*it));
+        }
+      int IdToRemove = (*it)->GetID();
+      int vtkid = (*it)->getVtkId();
+      //MESSAGE("elem Id to remove " << IdToRemove << " vtkid " << vtkid <<
+      //        " vtktype " << (*it)->GetVtkType() << " type " << (*it)->GetType());
+      switch ((*it)->GetType())
+      {
+        case SMDSAbs_Node:
+          MYASSERT("Internal Error: This should not happen")
+          ;
+          break;
+        case SMDSAbs_0DElement:
+          if (IdToRemove >= 0)
+            {
+              myCells[IdToRemove] = 0; // -PR- ici ou dans myElementIDFactory->ReleaseID ?
+              myInfo.remove(*it);
+            }
+          removedElems.push_back((*it));
+          myElementIDFactory->ReleaseID(IdToRemove, vtkid);
+          delete (*it);
+          break;
+        case SMDSAbs_Edge:
+          if (IdToRemove >= 0)
+            {
+              myCells[IdToRemove] = 0;
+              myInfo.RemoveEdge(*it);
+            }
+          removedElems.push_back((*it));
+          myElementIDFactory->ReleaseID(IdToRemove, vtkid);
+          if (const SMDS_VtkEdge* vtkElem = dynamic_cast<const SMDS_VtkEdge*>(*it))
+            myEdgePool->destroy((SMDS_VtkEdge*) vtkElem);
+          else
+            delete (*it);
+          break;
+        case SMDSAbs_Face:
+          if (IdToRemove >= 0)
+            {
+              myCells[IdToRemove] = 0;
+              myInfo.RemoveFace(*it);
+            }
+          removedElems.push_back((*it));
+          myElementIDFactory->ReleaseID(IdToRemove, vtkid);
+          if (const SMDS_VtkFace* vtkElem = dynamic_cast<const SMDS_VtkFace*>(*it))
+            myFacePool->destroy((SMDS_VtkFace*) vtkElem);
+          else
+            delete (*it);
+          break;
+        case SMDSAbs_Volume:
+          if (IdToRemove >= 0)
+            {
+              myCells[IdToRemove] = 0;
+              myInfo.RemoveVolume(*it);
+            }
+          removedElems.push_back((*it));
+          myElementIDFactory->ReleaseID(IdToRemove, vtkid);
+          if (const SMDS_VtkVolume* vtkElem = dynamic_cast<const SMDS_VtkVolume*>(*it))
+            myVolumePool->destroy((SMDS_VtkVolume*) vtkElem);
+          else
+            delete (*it);
+          break;
+        case SMDSAbs_Ball:
+          if (IdToRemove >= 0)
+            {
+              myCells[IdToRemove] = 0;
+              myInfo.remove(*it);
+            }
+          removedElems.push_back((*it));
+          myElementIDFactory->ReleaseID(IdToRemove, vtkid);
+          if (const SMDS_BallElement* vtkElem = dynamic_cast<const SMDS_BallElement*>(*it))
+            myBallPool->destroy(const_cast<SMDS_BallElement*>( vtkElem ));
+          else
+            delete (*it);
+          break;
+      }
+      if (vtkid >= 0)
+        {
+          //MESSAGE("VTK_EMPTY_CELL in " << vtkid);
+          this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
+        }
+      it++;
     }
 
-    switch((*it)->GetType())
-    {
-    case SMDSAbs_Node:
-      MESSAGE("Internal Error: This should not happen");
-      break;
-    case SMDSAbs_Edge:
-      myEdges.Remove(static_cast<SMDS_MeshEdge*>
-                    (const_cast<SMDS_MeshElement*>(*it)));
-      myInfo.RemoveEdge(*it);
-      break;
-    case SMDSAbs_Face:
-      myFaces.Remove(static_cast<SMDS_MeshFace*>
-                    (const_cast<SMDS_MeshElement*>(*it)));
-      myInfo.RemoveFace(*it);
-      break;
-    case SMDSAbs_Volume:
-      myVolumes.Remove(static_cast<SMDS_MeshVolume*>
-                      (const_cast<SMDS_MeshElement*>(*it)));
-      myInfo.RemoveVolume(*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())
+  if (removenodes)
     {
-      //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
-      myNodes.Remove(static_cast<SMDS_MeshNode*>
-                    (const_cast<SMDS_MeshElement*>(*it)));
-      myInfo.myNbNodes--;
-      myNodeIDFactory->ReleaseID((*it)->GetID());
-      removedNodes.push_back( (*it) );
-      delete *it;
-      it++;
+      it = s2->begin();
+      while (it != s2->end())
+        {
+          int IdToRemove = (*it)->GetID();
+          //MESSAGE( "SMDS: RM node " << IdToRemove);
+          if (IdToRemove >= 0)
+            {
+              myNodes[IdToRemove] = 0;
+              myInfo.myNbNodes--;
+            }
+          myNodeIDFactory->ReleaseID((*it)->GetID(), (*it)->getVtkId());
+          removedNodes.push_back((*it));
+          if (const SMDS_MeshNode* vtkElem = dynamic_cast<const SMDS_MeshNode*>(*it))
+          {
+            ((SMDS_MeshNode*)vtkElem)->SetPosition(SMDS_SpacePosition::originSpacePosition());
+            myNodePool->destroy((SMDS_MeshNode*) vtkElem);
+          }
+          else
+            delete (*it);
+          it++;
+        }
     }
-  }
 
   delete s2;
   delete s1;
 }
 
-  
+
 ///////////////////////////////////////////////////////////////////////////////
 ///@param elem The element to delete
 ///////////////////////////////////////////////////////////////////////////////
 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
 {
+  int elemId = elem->GetID();
+  int vtkId = elem->getVtkId();
+  //MESSAGE("RemoveFreeElement " << elemId);
   SMDSAbs_ElementType aType = elem->GetType();
+  SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem);
   if (aType == SMDSAbs_Node) {
+    //MESSAGE("Remove free node " << elemId);
     // only free node can be removed by this method
-    const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>(elem);
+    const SMDS_MeshNode* n = static_cast<SMDS_MeshNode*>(todest);
     SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
     if (!itFe->more()) { // free node
-      myNodes.Remove(const_cast<SMDS_MeshNode*>(n));
+      myNodes[elemId] = 0;
       myInfo.myNbNodes--;
-      myNodeIDFactory->ReleaseID(elem->GetID());
-      delete elem;
+      ((SMDS_MeshNode*) n)->SetPosition(SMDS_SpacePosition::originSpacePosition());
+      myNodePool->destroy(static_cast<SMDS_MeshNode*>(todest));
+      myNodeIDFactory->ReleaseID(elemId, vtkId);
     }
   } else {
     if (hasConstructionEdges() || hasConstructionFaces())
       // this methods is only for meshes without descendants
       return;
 
+    //MESSAGE("Remove free element " << elemId);
     // Remove element from <InverseElements> of its nodes
     SMDS_ElemIteratorPtr itn = elem->nodesIterator();
     while (itn->more()) {
@@ -2418,27 +3361,39 @@ void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
     }
 
     // in meshes without descendants elements are always free
-    switch (aType) {
+     switch (aType) {
+    case SMDSAbs_0DElement:
+      myCells[elemId] = 0;
+      myInfo.remove(elem);
+      delete elem;
+      break;
     case SMDSAbs_Edge:
-      myEdges.Remove(static_cast<SMDS_MeshEdge*>
-                     (const_cast<SMDS_MeshElement*>(elem)));
+      myCells[elemId] = 0;
       myInfo.RemoveEdge(elem);
+      myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(todest));
       break;
     case SMDSAbs_Face:
-      myFaces.Remove(static_cast<SMDS_MeshFace*>
-                     (const_cast<SMDS_MeshElement*>(elem)));
+      myCells[elemId] = 0;
       myInfo.RemoveFace(elem);
+      myFacePool->destroy(static_cast<SMDS_VtkFace*>(todest));
       break;
     case SMDSAbs_Volume:
-      myVolumes.Remove(static_cast<SMDS_MeshVolume*>
-                       (const_cast<SMDS_MeshElement*>(elem)));
+      myCells[elemId] = 0;
       myInfo.RemoveVolume(elem);
+      myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(todest));
+      break;
+    case SMDSAbs_Ball:
+      myCells[elemId] = 0;
+      myInfo.remove(elem);
+      myBallPool->destroy(static_cast<SMDS_BallElement*>(todest));
       break;
     default:
       break;
     }
-    myElementIDFactory->ReleaseID(elem->GetID());
-    delete elem;
+    myElementIDFactory->ReleaseID(elemId, vtkId);
+
+    this->myGrid->GetCellTypesArray()->SetValue(vtkId, VTK_EMPTY_CELL);
+    // --- to do: keep vtkid in a list of reusable cells
   }
 }
 
@@ -2454,44 +3409,36 @@ bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
   while (itn->more())
     if (elem == itn->next())
       return true;
-  SMDS_EdgeIteratorPtr ite = edgesIterator();
+  SMDS_ElemIteratorPtr ite = elementsIterator();
   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;
 }
 
 //=======================================================================
 //function : MaxNodeID
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 int SMDS_Mesh::MaxNodeID() const
 {
-  return myNodeIDFactory->GetMaxID();
+  return myNodeMax;
 }
 
 //=======================================================================
 //function : MinNodeID
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 int SMDS_Mesh::MinNodeID() const
 {
-  return myNodeIDFactory->GetMinID();
+  return myNodeMin;
 }
 
 //=======================================================================
 //function : MaxElementID
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 int SMDS_Mesh::MaxElementID() const
@@ -2501,7 +3448,7 @@ int SMDS_Mesh::MaxElementID() const
 
 //=======================================================================
 //function : MinElementID
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 int SMDS_Mesh::MinElementID() const
@@ -2516,10 +3463,11 @@ int SMDS_Mesh::MinElementID() const
 
 void SMDS_Mesh::Renumber (const bool isNodes, const int  startID, const int  deltaID)
 {
+    MESSAGE("Renumber");
   if ( deltaID == 0 )
     return;
 
-  SMDS_MeshElementIDFactory * idFactory =
+  SMDS_MeshNodeIDFactory * idFactory =
     isNodes ? myNodeIDFactory : myElementIDFactory;
 
   // get existing elements in the order of ID increasing
@@ -2582,9 +3530,9 @@ SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem )
 
 //=======================================================================
 //function : AddEdgeWithID
-//purpose  : 
+//purpose  :
 //=======================================================================
-SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID) 
+SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
 {
   return SMDS_Mesh::AddEdgeWithID
     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
@@ -2595,10 +3543,10 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
 
 //=======================================================================
 //function : AddEdge
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
-                                 const SMDS_MeshNode* n2,
+                                  const SMDS_MeshNode* n2,
                                   const SMDS_MeshNode* n12)
 {
   return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
@@ -2606,41 +3554,52 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
 
 //=======================================================================
 //function : AddEdgeWithID
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
-                                       const SMDS_MeshNode * n2, 
-                                       const SMDS_MeshNode * n12, 
-                                       int ID)
+                                        const SMDS_MeshNode * n2,
+                                        const SMDS_MeshNode * n12,
+                                        int ID)
 {
   if ( !n1 || !n2 || !n12 ) return 0;
-  SMDS_QuadraticEdge* edge = new SMDS_QuadraticEdge(n1,n2,n12);
-  if(myElementIDFactory->BindID(ID, edge)) {
-    SMDS_MeshNode *node1,*node2, *node12;
-    node1 = const_cast<SMDS_MeshNode*>(n1);
-    node2 = const_cast<SMDS_MeshNode*>(n2);
-    node12 = const_cast<SMDS_MeshNode*>(n12);
-    node1->AddInverseElement(edge);
-    node2->AddInverseElement(edge);
-    node12->AddInverseElement(edge);
-    myEdges.Add(edge);
-    myInfo.myNbQuadEdges++;
-    return edge;
-  } 
-  else {
-    delete edge;
-    return NULL;
-  }
+
+  // --- retrieve nodes ID
+  vector<vtkIdType> nodeIds;
+  nodeIds.clear();
+  nodeIds.push_back(n1->getVtkId());
+  nodeIds.push_back(n2->getVtkId());
+  nodeIds.push_back(n12->getVtkId());
+
+  SMDS_MeshEdge * edge = 0;
+  SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
+  edgevtk->init(nodeIds, this);
+  if (!this->registerElement(ID,edgevtk))
+    {
+      this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
+      myEdgePool->destroy(edgevtk);
+      return 0;
+    }
+  edge = edgevtk;
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = edge;
+  myInfo.myNbQuadEdges++;
+
+//  if (!registerElement(ID, edge)) {
+//        RemoveElement(edge, false);
+//        edge = NULL;
+//  }
+  return edge;
+
 }
 
 
 //=======================================================================
 //function : AddFace
-//purpose  : 
+//purpose  :
 //=======================================================================
 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,
                                   const SMDS_MeshNode * n12,
                                   const SMDS_MeshNode * n23,
                                   const SMDS_MeshNode * n31)
@@ -2651,7 +3610,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
 
 //=======================================================================
 //function : AddFaceWithID
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
                                         int n12,int n23,int n31, int ID)
@@ -2668,14 +3627,14 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
 
 //=======================================================================
 //function : AddFaceWithID
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
                                         const SMDS_MeshNode * n2,
                                         const SMDS_MeshNode * n3,
                                         const SMDS_MeshNode * n12,
                                         const SMDS_MeshNode * n23,
-                                        const SMDS_MeshNode * n31, 
+                                        const SMDS_MeshNode * n31,
                                         int ID)
 {
   if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
@@ -2683,27 +3642,49 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
     // creation quadratic edges - not implemented
     return 0;
   }
-  SMDS_QuadraticFaceOfNodes* face =
-    new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n12,n23,n31);
-  myFaces.Add(face);
-  myInfo.myNbQuadTriangles++;
-
-  if (!registerElement(ID, face)) {
-    RemoveElement(face, false);
-    face = NULL;
+  else
+  {
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(n1->getVtkId());
+    nodeIds.push_back(n2->getVtkId());
+    nodeIds.push_back(n3->getVtkId());
+    nodeIds.push_back(n12->getVtkId());
+    nodeIds.push_back(n23->getVtkId());
+    nodeIds.push_back(n31->getVtkId());
+
+    SMDS_MeshFace * face = 0;
+    SMDS_VtkFace *facevtk = myFacePool->getNew();
+    facevtk->init(nodeIds, this);
+    if (!this->registerElement(ID,facevtk))
+      {
+        this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
+        myFacePool->destroy(facevtk);
+        return 0;
+      }
+    face = facevtk;
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = face;
+    myInfo.myNbQuadTriangles++;
+
+//    if (!registerElement(ID, face)) {
+//      RemoveElement(face, false);
+//      face = NULL;
+//    }
+    return face;
   }
-  return face;
 }
 
 
 //=======================================================================
 //function : AddFace
-//purpose  : 
+//purpose  :
 //=======================================================================
 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,
                                   const SMDS_MeshNode * n12,
                                   const SMDS_MeshNode * n23,
                                   const SMDS_MeshNode * n34,
@@ -2715,7 +3696,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
 
 //=======================================================================
 //function : AddFaceWithID
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
                                         int n12,int n23,int n34,int n41, int ID)
@@ -2734,7 +3715,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
 
 //=======================================================================
 //function : AddFaceWithID
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
                                         const SMDS_MeshNode * n2,
@@ -2742,39 +3723,159 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
                                         const SMDS_MeshNode * n4,
                                         const SMDS_MeshNode * n12,
                                         const SMDS_MeshNode * n23,
-                                        const SMDS_MeshNode * n34, 
-                                        const SMDS_MeshNode * n41, 
+                                        const SMDS_MeshNode * n34,
+                                        const SMDS_MeshNode * n41,
                                         int ID)
 {
   if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
   if(hasConstructionEdges()) {
     // creation quadratic edges - not implemented
+        return 0;
+  }
+  else
+  {
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(n1->getVtkId());
+    nodeIds.push_back(n2->getVtkId());
+    nodeIds.push_back(n3->getVtkId());
+    nodeIds.push_back(n4->getVtkId());
+    nodeIds.push_back(n12->getVtkId());
+    nodeIds.push_back(n23->getVtkId());
+    nodeIds.push_back(n34->getVtkId());
+    nodeIds.push_back(n41->getVtkId());
+
+    SMDS_MeshFace * face = 0;
+    SMDS_VtkFace *facevtk = myFacePool->getNew();
+    facevtk->init(nodeIds, this);
+    if (!this->registerElement(ID,facevtk))
+      {
+        this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
+        myFacePool->destroy(facevtk);
+        return 0;
+      }
+    face = facevtk;
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = face;
+    myInfo.myNbQuadQuadrangles++;
+
+//    if (!registerElement(ID, face)) {
+//      RemoveElement(face, false);
+//      face = NULL;
+//    }
+    return face;
   }
-  SMDS_QuadraticFaceOfNodes* face =
-    new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n4,n12,n23,n34,n41);
-  myFaces.Add(face);
-  myInfo.myNbQuadQuadrangles++;
+}
 
-  if (!registerElement(ID, face)) {
-    RemoveElement(face, false);
-    face = NULL;
+//=======================================================================
+//function : AddFace
+//purpose  :
+//=======================================================================
+SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
+                                  const SMDS_MeshNode * n2,
+                                  const SMDS_MeshNode * n3,
+                                  const SMDS_MeshNode * n4,
+                                  const SMDS_MeshNode * n12,
+                                  const SMDS_MeshNode * n23,
+                                  const SMDS_MeshNode * n34,
+                                  const SMDS_MeshNode * n41,
+                                  const SMDS_MeshNode * nCenter)
+{
+  return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,nCenter,
+                                  myElementIDFactory->GetFreeID());
+}
+
+//=======================================================================
+//function : AddFaceWithID
+//purpose  :
+//=======================================================================
+SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
+                                        int n12,int n23,int n34,int n41, int nCenter, int ID)
+{
+  return SMDS_Mesh::AddFaceWithID
+    ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
+     (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
+     (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
+     (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
+     (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
+     (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
+     (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
+     (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
+     (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nCenter),
+     ID);
+}
+
+//=======================================================================
+//function : AddFaceWithID
+//purpose  :
+//=======================================================================
+SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
+                                        const SMDS_MeshNode * n2,
+                                        const SMDS_MeshNode * n3,
+                                        const SMDS_MeshNode * n4,
+                                        const SMDS_MeshNode * n12,
+                                        const SMDS_MeshNode * n23,
+                                        const SMDS_MeshNode * n34,
+                                        const SMDS_MeshNode * n41,
+                                        const SMDS_MeshNode * nCenter,
+                                        int ID)
+{
+  if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41 || !nCenter) return 0;
+  if(hasConstructionEdges()) {
+    // creation quadratic edges - not implemented
+        return 0;
+  }
+  else
+  {
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(n1->getVtkId());
+    nodeIds.push_back(n2->getVtkId());
+    nodeIds.push_back(n3->getVtkId());
+    nodeIds.push_back(n4->getVtkId());
+    nodeIds.push_back(n12->getVtkId());
+    nodeIds.push_back(n23->getVtkId());
+    nodeIds.push_back(n34->getVtkId());
+    nodeIds.push_back(n41->getVtkId());
+    nodeIds.push_back(nCenter->getVtkId());
+
+    SMDS_MeshFace * face = 0;
+    SMDS_VtkFace *facevtk = myFacePool->getNew();
+    facevtk->init(nodeIds, this);
+    if (!this->registerElement(ID,facevtk))
+      {
+        this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
+        myFacePool->destroy(facevtk);
+        return 0;
+      }
+    face = facevtk;
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = face;
+    myInfo.myNbBiQuadQuadrangles++;
+
+//    if (!registerElement(ID, face)) {
+//      RemoveElement(face, false);
+//      face = NULL;
+//    }
+    return face;
   }
-  return face;
 }
 
 
 //=======================================================================
 //function : AddVolume
-//purpose  : 
+//purpose  :
 //=======================================================================
 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,
                                       const SMDS_MeshNode * n12,
                                       const SMDS_MeshNode * n23,
                                       const SMDS_MeshNode * n31,
-                                      const SMDS_MeshNode * n14, 
+                                      const SMDS_MeshNode * n14,
                                       const SMDS_MeshNode * n24,
                                       const SMDS_MeshNode * n34)
 {
@@ -2787,7 +3888,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
 
 //=======================================================================
 //function : AddVolumeWithID
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
                                             int n12,int n23,int n31,
@@ -2818,7 +3919,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n12,
                                             const SMDS_MeshNode * n23,
                                             const SMDS_MeshNode * n31,
-                                            const SMDS_MeshNode * n14, 
+                                            const SMDS_MeshNode * n14,
                                             const SMDS_MeshNode * n24,
                                             const SMDS_MeshNode * n34,
                                             int ID)
@@ -2829,33 +3930,56 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     // creation quadratic faces - not implemented
     return 0;
   }
-  SMDS_QuadraticVolumeOfNodes * volume =
-    new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
-  myVolumes.Add(volume);
+  // --- retrieve nodes ID
+  vector<vtkIdType> nodeIds;
+  nodeIds.clear();
+  nodeIds.push_back(n1->getVtkId());
+  nodeIds.push_back(n3->getVtkId());
+  nodeIds.push_back(n2->getVtkId());
+  nodeIds.push_back(n4->getVtkId());
+
+  nodeIds.push_back(n31->getVtkId());
+  nodeIds.push_back(n23->getVtkId());
+  nodeIds.push_back(n12->getVtkId());
+
+  nodeIds.push_back(n14->getVtkId());
+  nodeIds.push_back(n34->getVtkId());
+  nodeIds.push_back(n24->getVtkId());
+
+  SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+  volvtk->init(nodeIds, this);
+  if (!this->registerElement(ID,volvtk))
+    {
+      this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+      myVolumePool->destroy(volvtk);
+      return 0;
+    }
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = volvtk;
   myInfo.myNbQuadTetras++;
 
-  if (!registerElement(ID, volume)) {
-    RemoveElement(volume, false);
-    volume = NULL;
-  }
-  return volume;
+//  if (!registerElement(ID, volvtk)) {
+//    RemoveElement(volvtk, false);
+//    volvtk = NULL;
+//  }
+  return volvtk;
 }
 
 
 //=======================================================================
 //function : AddVolume
-//purpose  : 
+//purpose  :
 //=======================================================================
 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,
                                       const SMDS_MeshNode * n12,
                                       const SMDS_MeshNode * n23,
                                       const SMDS_MeshNode * n34,
                                       const SMDS_MeshNode * n41,
-                                      const SMDS_MeshNode * n15, 
+                                      const SMDS_MeshNode * n15,
                                       const SMDS_MeshNode * n25,
                                       const SMDS_MeshNode * n35,
                                       const SMDS_MeshNode * n45)
@@ -2870,7 +3994,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
 
 //=======================================================================
 //function : AddVolumeWithID
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
                                             int n12,int n23,int n34,int n41,
@@ -2901,12 +4025,12 @@ 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 * n5,
                                             const SMDS_MeshNode * n12,
                                             const SMDS_MeshNode * n23,
                                             const SMDS_MeshNode * n34,
                                             const SMDS_MeshNode * n41,
-                                            const SMDS_MeshNode * n15, 
+                                            const SMDS_MeshNode * n15,
                                             const SMDS_MeshNode * n25,
                                             const SMDS_MeshNode * n35,
                                             const SMDS_MeshNode * n45,
@@ -2919,36 +4043,61 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     // creation quadratic faces - not implemented
     return 0;
   }
-  SMDS_QuadraticVolumeOfNodes * volume =
-    new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n12,n23,
-                                    n34,n41,n15,n25,n35,n45);
-  myVolumes.Add(volume);
+  // --- retrieve nodes ID
+  vector<vtkIdType> nodeIds;
+  nodeIds.clear();
+  nodeIds.push_back(n1->getVtkId());
+  nodeIds.push_back(n4->getVtkId());
+  nodeIds.push_back(n3->getVtkId());
+  nodeIds.push_back(n2->getVtkId());
+  nodeIds.push_back(n5->getVtkId());
+
+  nodeIds.push_back(n41->getVtkId());
+  nodeIds.push_back(n34->getVtkId());
+  nodeIds.push_back(n23->getVtkId());
+  nodeIds.push_back(n12->getVtkId());
+
+  nodeIds.push_back(n15->getVtkId());
+  nodeIds.push_back(n45->getVtkId());
+  nodeIds.push_back(n35->getVtkId());
+  nodeIds.push_back(n25->getVtkId());
+
+  SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+  volvtk->init(nodeIds, this);
+  if (!this->registerElement(ID,volvtk))
+    {
+      this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+      myVolumePool->destroy(volvtk);
+      return 0;
+    }
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = volvtk;
   myInfo.myNbQuadPyramids++;
 
-  if (!registerElement(ID, volume)) {
-    RemoveElement(volume, false);
-    volume = NULL;
-  }
-  return volume;
+//  if (!registerElement(ID, volvtk)) {
+//    RemoveElement(volvtk, false);
+//    volvtk = NULL;
+//  }
+  return volvtk;
 }
 
 
 //=======================================================================
 //function : AddVolume
-//purpose  : 
+//purpose  :
 //=======================================================================
 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,
                                       const SMDS_MeshNode * n12,
                                       const SMDS_MeshNode * n23,
-                                      const SMDS_MeshNode * n31, 
+                                      const SMDS_MeshNode * n31,
                                       const SMDS_MeshNode * n45,
                                       const SMDS_MeshNode * n56,
-                                      const SMDS_MeshNode * n64, 
+                                      const SMDS_MeshNode * n64,
                                       const SMDS_MeshNode * n14,
                                       const SMDS_MeshNode * n25,
                                       const SMDS_MeshNode * n36)
@@ -2963,7 +4112,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
 
 //=======================================================================
 //function : AddVolumeWithID
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
                                             int n4, int n5, int n6,
@@ -2998,14 +4147,14 @@ 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 * n5,
+                                            const SMDS_MeshNode * n6,
                                             const SMDS_MeshNode * n12,
                                             const SMDS_MeshNode * n23,
-                                            const SMDS_MeshNode * n31, 
+                                            const SMDS_MeshNode * n31,
                                             const SMDS_MeshNode * n45,
                                             const SMDS_MeshNode * n56,
-                                            const SMDS_MeshNode * n64, 
+                                            const SMDS_MeshNode * n64,
                                             const SMDS_MeshNode * n14,
                                             const SMDS_MeshNode * n25,
                                             const SMDS_MeshNode * n36,
@@ -3018,40 +4167,69 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     // creation quadratic faces - not implemented
     return 0;
   }
-  SMDS_QuadraticVolumeOfNodes * volume =
-    new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n12,n23,n31,
-                                    n45,n56,n64,n14,n25,n36);
-  myVolumes.Add(volume);
+  // --- retrieve nodes ID
+  vector<vtkIdType> nodeIds;
+  nodeIds.clear();
+  nodeIds.push_back(n1->getVtkId());
+  nodeIds.push_back(n2->getVtkId());
+  nodeIds.push_back(n3->getVtkId());
+
+  nodeIds.push_back(n4->getVtkId());
+  nodeIds.push_back(n5->getVtkId());
+  nodeIds.push_back(n6->getVtkId());
+
+  nodeIds.push_back(n12->getVtkId());
+  nodeIds.push_back(n23->getVtkId());
+  nodeIds.push_back(n31->getVtkId());
+
+  nodeIds.push_back(n45->getVtkId());
+  nodeIds.push_back(n56->getVtkId());
+  nodeIds.push_back(n64->getVtkId());
+
+  nodeIds.push_back(n14->getVtkId());
+  nodeIds.push_back(n25->getVtkId());
+  nodeIds.push_back(n36->getVtkId());
+
+  SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+  volvtk->init(nodeIds, this);
+  if (!this->registerElement(ID,volvtk))
+    {
+      this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+      myVolumePool->destroy(volvtk);
+      return 0;
+    }
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = volvtk;
   myInfo.myNbQuadPrisms++;
 
-  if (!registerElement(ID, volume)) {
-    RemoveElement(volume, false);
-    volume = NULL;
-  }
-  return volume;
+//  if (!registerElement(ID, volvtk)) {
+//    RemoveElement(volvtk, false);
+//    volvtk = NULL;
+//  }
+  return volvtk;
 }
 
 
 //=======================================================================
 //function : AddVolume
-//purpose  : 
+//purpose  :
 //=======================================================================
 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,
                                       const SMDS_MeshNode * n7,
-                                      const SMDS_MeshNode * n8, 
+                                      const SMDS_MeshNode * n8,
                                       const SMDS_MeshNode * n12,
                                       const SMDS_MeshNode * n23,
                                       const SMDS_MeshNode * n34,
-                                      const SMDS_MeshNode * n41, 
+                                      const SMDS_MeshNode * n41,
                                       const SMDS_MeshNode * n56,
                                       const SMDS_MeshNode * n67,
                                       const SMDS_MeshNode * n78,
-                                      const SMDS_MeshNode * n85, 
+                                      const SMDS_MeshNode * n85,
                                       const SMDS_MeshNode * n15,
                                       const SMDS_MeshNode * n26,
                                       const SMDS_MeshNode * n37,
@@ -3067,7 +4245,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
 
 //=======================================================================
 //function : AddVolumeWithID
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
                                             int n5, int n6, int n7, int n8,
@@ -3107,18 +4285,18 @@ 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 * n5,
+                                            const SMDS_MeshNode * n6,
                                             const SMDS_MeshNode * n7,
-                                            const SMDS_MeshNode * n8, 
+                                            const SMDS_MeshNode * n8,
                                             const SMDS_MeshNode * n12,
                                             const SMDS_MeshNode * n23,
                                             const SMDS_MeshNode * n34,
-                                            const SMDS_MeshNode * n41, 
+                                            const SMDS_MeshNode * n41,
                                             const SMDS_MeshNode * n56,
                                             const SMDS_MeshNode * n67,
                                             const SMDS_MeshNode * n78,
-                                            const SMDS_MeshNode * n85, 
+                                            const SMDS_MeshNode * n85,
                                             const SMDS_MeshNode * n15,
                                             const SMDS_MeshNode * n26,
                                             const SMDS_MeshNode * n37,
@@ -3132,15 +4310,391 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     return 0;
     // creation quadratic faces - not implemented
   }
-  SMDS_QuadraticVolumeOfNodes * volume =
-    new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
-                                    n56,n67,n78,n85,n15,n26,n37,n48);
-  myVolumes.Add(volume);
+  // --- retrieve nodes ID
+  vector<vtkIdType> nodeIds;
+  nodeIds.clear();
+  nodeIds.push_back(n1->getVtkId());
+  nodeIds.push_back(n4->getVtkId());
+  nodeIds.push_back(n3->getVtkId());
+  nodeIds.push_back(n2->getVtkId());
+
+  nodeIds.push_back(n5->getVtkId());
+  nodeIds.push_back(n8->getVtkId());
+  nodeIds.push_back(n7->getVtkId());
+  nodeIds.push_back(n6->getVtkId());
+
+  nodeIds.push_back(n41->getVtkId());
+  nodeIds.push_back(n34->getVtkId());
+  nodeIds.push_back(n23->getVtkId());
+  nodeIds.push_back(n12->getVtkId());
+
+  nodeIds.push_back(n85->getVtkId());
+  nodeIds.push_back(n78->getVtkId());
+  nodeIds.push_back(n67->getVtkId());
+  nodeIds.push_back(n56->getVtkId());
+
+  nodeIds.push_back(n15->getVtkId());
+  nodeIds.push_back(n48->getVtkId());
+  nodeIds.push_back(n37->getVtkId());
+  nodeIds.push_back(n26->getVtkId());
+
+  SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+  volvtk->init(nodeIds, this);
+  if (!this->registerElement(ID,volvtk))
+    {
+      this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+      myVolumePool->destroy(volvtk);
+      return 0;
+    }
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = volvtk;
   myInfo.myNbQuadHexas++;
 
-  if (!registerElement(ID, volume)) {
-    RemoveElement(volume, false);
-    volume = NULL;
+//  if (!registerElement(ID, volvtk)) {
+//    RemoveElement(volvtk, false);
+//    volvtk = NULL;
+//  }
+  return volvtk;
+}
+
+//=======================================================================
+//function : AddVolume
+//purpose  :
+//=======================================================================
+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 * n12,
+                                      const SMDS_MeshNode * n23,
+                                      const SMDS_MeshNode * n34,
+                                      const SMDS_MeshNode * n41,
+                                      const SMDS_MeshNode * n56,
+                                      const SMDS_MeshNode * n67,
+                                      const SMDS_MeshNode * n78,
+                                      const SMDS_MeshNode * n85,
+                                      const SMDS_MeshNode * n15,
+                                      const SMDS_MeshNode * n26,
+                                      const SMDS_MeshNode * n37,
+                                      const SMDS_MeshNode * n48,
+                                      const SMDS_MeshNode * n1234,
+                                      const SMDS_MeshNode * n1256,
+                                      const SMDS_MeshNode * n2367,
+                                      const SMDS_MeshNode * n3478,
+                                      const SMDS_MeshNode * n1458,
+                                      const SMDS_MeshNode * n5678,
+                                      const SMDS_MeshNode * nCenter)
+{
+  int ID = myElementIDFactory->GetFreeID();
+  SMDS_MeshVolume * v =
+    SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
+                               n56, n67, n78, n85, n15, n26, n37, n48,
+                               n1234, n1256, n2367, n3478, n1458, n5678, nCenter,
+                               ID);
+  if(v==NULL) myElementIDFactory->ReleaseID(ID);
+  return v;
+}
+
+//=======================================================================
+//function : AddVolumeWithID
+//purpose  :
+//=======================================================================
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
+                                            int n5, int n6, int n7, int n8,
+                                            int n12,int n23,int n34,int n41,
+                                            int n56,int n67,int n78,int n85,
+                                            int n15,int n26,int n37,int n48,
+                                            int n1234,int n1256,int n2367,int n3478,
+                                            int n1458,int n5678,int nCenter, int ID)
+{
+  return SMDS_Mesh::AddVolumeWithID
+    ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1234),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1256),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2367),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3478),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1458),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5678),
+     (SMDS_MeshNode*) myNodeIDFactory->MeshElement(nCenter),
+     ID);
+}
+
+//=======================================================================
+//function : AddVolumeWithID
+//purpose  : 2d order Hexahedrons with 20 nodes
+//=======================================================================
+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,
+                                            const SMDS_MeshNode * n12,
+                                            const SMDS_MeshNode * n23,
+                                            const SMDS_MeshNode * n34,
+                                            const SMDS_MeshNode * n41,
+                                            const SMDS_MeshNode * n56,
+                                            const SMDS_MeshNode * n67,
+                                            const SMDS_MeshNode * n78,
+                                            const SMDS_MeshNode * n85,
+                                            const SMDS_MeshNode * n15,
+                                            const SMDS_MeshNode * n26,
+                                            const SMDS_MeshNode * n37,
+                                            const SMDS_MeshNode * n48,
+                                            const SMDS_MeshNode * n1234,
+                                            const SMDS_MeshNode * n1256,
+                                            const SMDS_MeshNode * n2367,
+                                            const SMDS_MeshNode * n3478,
+                                            const SMDS_MeshNode * n1458,
+                                            const SMDS_MeshNode * n5678,
+                                            const SMDS_MeshNode * nCenter,
+                                            int ID)
+{
+  if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
+      !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48 ||
+      !n1234 || !n1256 || !n2367 || !n3478 || !n1458 || !n5678 || !nCenter )
+    return 0;
+  if(hasConstructionFaces()) {
+    return 0;
+    // creation quadratic faces - not implemented
   }
-  return volume;
+  // --- retrieve nodes ID
+  vector<vtkIdType> nodeIds;
+  nodeIds.clear();
+  nodeIds.push_back(n1->getVtkId());
+  nodeIds.push_back(n4->getVtkId());
+  nodeIds.push_back(n3->getVtkId());
+  nodeIds.push_back(n2->getVtkId());
+
+  nodeIds.push_back(n5->getVtkId());
+  nodeIds.push_back(n8->getVtkId());
+  nodeIds.push_back(n7->getVtkId());
+  nodeIds.push_back(n6->getVtkId());
+
+  nodeIds.push_back(n41->getVtkId());
+  nodeIds.push_back(n34->getVtkId());
+  nodeIds.push_back(n23->getVtkId());
+  nodeIds.push_back(n12->getVtkId());
+
+  nodeIds.push_back(n85->getVtkId());
+  nodeIds.push_back(n78->getVtkId());
+  nodeIds.push_back(n67->getVtkId());
+  nodeIds.push_back(n56->getVtkId());
+
+  nodeIds.push_back(n15->getVtkId());
+  nodeIds.push_back(n48->getVtkId());
+  nodeIds.push_back(n37->getVtkId());
+  nodeIds.push_back(n26->getVtkId());
+
+  nodeIds.push_back(n1256->getVtkId());
+  nodeIds.push_back(n3478->getVtkId());
+  nodeIds.push_back(n1458->getVtkId());
+  nodeIds.push_back(n2367->getVtkId());
+  nodeIds.push_back(n1234->getVtkId());
+  nodeIds.push_back(n5678->getVtkId());
+  nodeIds.push_back(nCenter->getVtkId());
+
+  SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+  volvtk->init(nodeIds, this);
+  if (!this->registerElement(ID,volvtk))
+    {
+      this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+      myVolumePool->destroy(volvtk);
+      return 0;
+    }
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = volvtk;
+  myInfo.myNbTriQuadHexas++;
+
+  return volvtk;
+}
+
+
+void SMDS_Mesh::updateNodeMinMax()
+{
+  myNodeMin = 0;
+  if (myNodes.size() == 0)
+  {
+        myNodeMax=0;
+        return;
+  }
+  while (!myNodes[myNodeMin] && (myNodeMin<myNodes.size()))
+    myNodeMin++;
+  myNodeMax=myNodes.size()-1;
+  while (!myNodes[myNodeMax] && (myNodeMin>=0))
+    myNodeMin--;
+}
+
+void SMDS_Mesh::incrementNodesCapacity(int nbNodes)
+{
+//  int val = myCellIdSmdsToVtk.size();
+//  MESSAGE(" ------------------- resize myCellIdSmdsToVtk " << val << " --> " << val + nbNodes);
+//  myCellIdSmdsToVtk.resize(val + nbNodes, -1); // fill new elements with -1
+  int val = myNodes.size();
+  MESSAGE(" ------------------- resize myNodes " << val << " --> " << val + nbNodes);
+  myNodes.resize(val +nbNodes, 0);
+}
+
+void SMDS_Mesh::incrementCellsCapacity(int nbCells)
+{
+  int val = myCellIdVtkToSmds.size();
+  MESSAGE(" ------------------- resize myCellIdVtkToSmds " << val << " --> " << val + nbCells);
+  myCellIdVtkToSmds.resize(val + nbCells, -1); // fill new elements with -1
+  val = myCells.size();
+  MESSAGE(" ------------------- resize myCells " << val << " --> " << val + nbCells);
+  myNodes.resize(val +nbCells, 0);
+}
+
+void SMDS_Mesh::adjustStructure()
+{
+  myGrid->GetPoints()->GetData()->SetNumberOfTuples(myNodeIDFactory->GetMaxID());
+}
+
+void SMDS_Mesh::dumpGrid(string ficdump)
+{
+        MESSAGE("SMDS_Mesh::dumpGrid " << ficdump);
+//  vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
+//  aWriter->SetFileName(ficdump.c_str());
+//  aWriter->SetInput(myGrid);
+//  if(myGrid->GetNumberOfCells())
+//  {
+//    aWriter->Write();
+//  }
+//  aWriter->Delete();
+  ficdump = ficdump + "_connectivity";
+  ofstream ficcon(ficdump.c_str(), ios::out);
+  int nbPoints = myGrid->GetNumberOfPoints();
+  ficcon << "-------------------------------- points " <<  nbPoints << endl;
+  for (int i=0; i<nbPoints; i++)
+  {
+        ficcon << i << " " << *(myGrid->GetPoint(i)) << " " << *(myGrid->GetPoint(i)+1) << " " << " " << *(myGrid->GetPoint(i)+2) << endl;
+  }
+  int nbCells = myGrid->GetNumberOfCells();
+  ficcon << "-------------------------------- cells " <<  nbCells << endl;
+  for (int i=0; i<nbCells; i++)
+  {
+//      MESSAGE(i << " " << myGrid->GetCell(i));
+//      MESSAGE("  " << myGrid->GetCell(i)->GetCellType());
+        ficcon << i << " - " << myGrid->GetCell(i)->GetCellType() << " -";
+        int nbptcell = myGrid->GetCell(i)->GetNumberOfPoints();
+        vtkIdList *listid = myGrid->GetCell(i)->GetPointIds();
+        for (int j=0; j<nbptcell; j++)
+        {
+                ficcon << " " <<  listid->GetId(j);
+        }
+        ficcon << endl;
+  }
+  ficcon << "-------------------------------- connectivity " <<  nbPoints << endl;
+        vtkCellLinks *links = myGrid->GetCellLinks();
+  for (int i=0; i<nbPoints; i++)
+  {
+        int ncells = links->GetNcells(i);
+        vtkIdType *cells = links->GetCells(i);
+        ficcon << i << " - " << ncells << " -";
+        for (int j=0; j<ncells; j++)
+        {
+                ficcon << " " << cells[j];
+        }
+        ficcon << endl;
+  }
+  ficcon.close();
+
+}
+
+void SMDS_Mesh::compactMesh()
+{
+  MESSAGE("SMDS_Mesh::compactMesh do nothing!");
+}
+
+int SMDS_Mesh::fromVtkToSmds(int vtkid)
+{
+  if (vtkid >= 0 && vtkid < myCellIdVtkToSmds.size())
+    return myCellIdVtkToSmds[vtkid];
+  throw SALOME_Exception(LOCALIZED ("vtk id out of bounds"));
+}
+
+void SMDS_Mesh::updateBoundingBox()
+{
+  xmin = 0; xmax = 0;
+  ymin = 0; ymax = 0;
+  zmin = 0; zmax = 0;
+  vtkPoints *points = myGrid->GetPoints();
+  int myNodesSize = this->myNodes.size();
+  for (int i = 0; i < myNodesSize; i++)
+    {
+      if (SMDS_MeshNode *n = myNodes[i])
+        {
+          double coords[3];
+          points->GetPoint(n->myVtkID, coords);
+          if (coords[0] < xmin) xmin = coords[0];
+          else if (coords[0] > xmax) xmax = coords[0];
+          if (coords[1] < ymin) ymin = coords[1];
+          else if (coords[1] > ymax) ymax = coords[1];
+          if (coords[2] < zmin) zmin = coords[2];
+          else if (coords[2] > zmax) zmax = coords[2];
+        }
+    }
+}
+
+double SMDS_Mesh::getMaxDim()
+{
+  double dmax = 1.e-3;
+  if ((xmax - xmin) > dmax) dmax = xmax -xmin;
+  if ((ymax - ymin) > dmax) dmax = ymax -ymin;
+  if ((zmax - zmin) > dmax) dmax = zmax -zmin;
+  MESSAGE("getMaxDim " << dmax);
+  return dmax;
+}
+
+//! modification that needs compact structure and redraw
+void SMDS_Mesh::Modified()
+{
+  if (this->myModified)
+    {
+      this->myModifTime++;
+      MESSAGE("modified");
+      myModified = false;
+    }
+}
+
+//! get last modification timeStamp
+unsigned long SMDS_Mesh::GetMTime() const
+{
+  return this->myModifTime;
+}
+
+bool SMDS_Mesh::isCompacted()
+{
+  if (this->myModifTime > this->myCompactTime)
+    {
+      MESSAGE(" *** isCompacted " << myCompactTime << " < " << myModifTime);
+      this->myCompactTime = this->myModifTime;
+      return false;
+    }
+  return true;
 }
index a0def42babed485b46a05903deee31dd1af8009a..7e03612867568cae15b26cee5ed7b0cf55ef377f 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_Mesh.hxx
 //  Module : SMESH
 #include "SMESH_SMDS.hxx"
 
 #include "SMDS_MeshNode.hxx"
+#include "SMDS_MeshCell.hxx"
+#include "SMDS_Mesh0DElement.hxx"
 #include "SMDS_MeshEdge.hxx"
 #include "SMDS_MeshFace.hxx"
 #include "SMDS_MeshVolume.hxx"
+#include "SMDS_MeshNodeIDFactory.hxx"
 #include "SMDS_MeshElementIDFactory.hxx"
 #include "SMDS_MeshInfo.hxx"
 #include "SMDS_ElemIterator.hxx"
-#include <NCollection_Map.hxx>
+#include "SMDS_VolumeOfNodes.hxx"
+#include "SMDS_VtkEdge.hxx"
+#include "SMDS_VtkFace.hxx"
+#include "SMDS_VtkVolume.hxx"
+#include "ObjectPool.hxx"
+#include "SMDS_UnstructuredGrid.hxx"
+#include "SMDS_BallElement.hxx"
 
 #include <boost/shared_ptr.hpp>
 #include <set>
 #include <list>
+#include <vector>
+#include <vtkSystemIncludes.h>
+#include <cassert>
+
+#include "Utils_SALOME_Exception.hxx"
 
-class SMDS_EXPORT SMDS_Mesh:public SMDS_MeshObject{
+#define MYASSERT(val) if (!(val)) throw SALOME_Exception(LOCALIZED("assertion not verified"));
+
+class SMDS_EXPORT SMDS_Mesh:public SMDS_MeshObject
+{
 public:
-  
+  friend class SMDS_MeshIDFactory;
+  friend class SMDS_MeshNodeIDFactory;
+  friend class SMDS_MeshElementIDFactory;
+  friend class SMDS_MeshVolumeVtkNodes;
+  friend class SMDS_MeshNode;
+
   SMDS_Mesh();
   
-  SMDS_NodeIteratorPtr nodesIterator() const;
-  SMDS_EdgeIteratorPtr edgesIterator() const;
-  SMDS_FaceIteratorPtr facesIterator() const;
-  SMDS_VolumeIteratorPtr volumesIterator() const;
-  SMDS_ElemIteratorPtr elementsIterator() const;  
-  
+  //! to retreive this SMDS_Mesh instance from its elements (index stored in SMDS_Elements)
+  static std::vector<SMDS_Mesh*> _meshList;
+
+  //! actual nodes coordinates, cells definition and reverse connectivity are stored in a vtkUnstructuredGrid
+  inline SMDS_UnstructuredGrid* getGrid() {return myGrid; }
+  inline int getMeshId() {return myMeshId; }
+
+  virtual SMDS_NodeIteratorPtr   nodesIterator     (bool idInceasingOrder=false) const;
+  virtual SMDS_EdgeIteratorPtr   edgesIterator     (bool idInceasingOrder=false) const;
+  virtual SMDS_FaceIteratorPtr   facesIterator     (bool idInceasingOrder=false) const;
+  virtual SMDS_VolumeIteratorPtr volumesIterator   (bool idInceasingOrder=false) const;
+
+  virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type=SMDSAbs_All) const;
+  virtual SMDS_ElemIteratorPtr elementGeomIterator(SMDSAbs_GeometryType type) const;
+  virtual SMDS_ElemIteratorPtr elementEntityIterator(SMDSAbs_EntityType type) const;
+
   SMDSAbs_ElementType GetElementType( const int id, const bool iselem ) 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_MeshNode* AddNode      (double x, double y, double z);
+
+  virtual SMDS_Mesh0DElement* Add0DElementWithID(int n,                   int ID);
+  virtual SMDS_Mesh0DElement* Add0DElementWithID(const SMDS_MeshNode * n, int ID);
+  virtual SMDS_Mesh0DElement* Add0DElement      (const SMDS_MeshNode * n);
+
+  virtual SMDS_BallElement* AddBallWithID(int n,                   double diameter, int ID);
+  virtual SMDS_BallElement* AddBallWithID(const SMDS_MeshNode * n, double diameter, int ID);
+  virtual SMDS_BallElement* AddBall      (const SMDS_MeshNode * n, double diameter);
+
   virtual SMDS_MeshEdge* AddEdgeWithID(int n1, int n2, int ID);
   virtual SMDS_MeshEdge* AddEdgeWithID(const SMDS_MeshNode * n1,
-                                      const SMDS_MeshNode * n2, 
-                                      int ID);
+                                       const SMDS_MeshNode * n2,
+                                       int ID);
   virtual SMDS_MeshEdge* AddEdge(const SMDS_MeshNode * n1,
-                                const SMDS_MeshNode * n2);
-  
+                                 const SMDS_MeshNode * n2);
+
   // 2d order edge with 3 nodes: n12 - node between n1 and n2
   virtual SMDS_MeshEdge* AddEdgeWithID(int n1, int n2, int n12, int ID);
   virtual SMDS_MeshEdge* AddEdgeWithID(const SMDS_MeshNode * n1,
-                                      const SMDS_MeshNode * n2, 
-                                      const SMDS_MeshNode * n12, 
-                                      int ID);
+                                       const SMDS_MeshNode * n2,
+                                       const SMDS_MeshNode * n12,
+                                       int ID);
   virtual SMDS_MeshEdge* AddEdge(const SMDS_MeshNode * n1,
                                  const SMDS_MeshNode * n2,
                                  const SMDS_MeshNode * n12);
 
   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);
+                                       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);
-  
+                                 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);
+                                       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);
-  
+                                 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);
@@ -116,100 +157,122 @@ public:
   virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3,
                                        int n12,int n23,int n31, int ID);
   virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1,
-                                      const SMDS_MeshNode * n2,
-                                      const SMDS_MeshNode * n3, 
-                                      const SMDS_MeshNode * n12,
-                                      const SMDS_MeshNode * n23,
-                                      const SMDS_MeshNode * n31, 
-                                      int ID);
+                                       const SMDS_MeshNode * n2,
+                                       const SMDS_MeshNode * n3,
+                                       const SMDS_MeshNode * n12,
+                                       const SMDS_MeshNode * n23,
+                                       const SMDS_MeshNode * n31,
+                                       int ID);
   virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1,
-                                const SMDS_MeshNode * n2,
-                                const SMDS_MeshNode * n3,
+                                 const SMDS_MeshNode * n2,
+                                 const SMDS_MeshNode * n3,
                                  const SMDS_MeshNode * n12,
-                                const SMDS_MeshNode * n23,
-                                const SMDS_MeshNode * n31);
+                                 const SMDS_MeshNode * n23,
+                                 const SMDS_MeshNode * n31);
 
   // 2d order quadrangle
   virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int n4,
                                        int n12,int n23,int n34,int n41, int ID);
   virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1,
-                                      const SMDS_MeshNode * n2,
-                                      const SMDS_MeshNode * n3,
-                                      const SMDS_MeshNode * n4, 
-                                      const SMDS_MeshNode * n12,
-                                      const SMDS_MeshNode * n23,
-                                      const SMDS_MeshNode * n34,
-                                      const SMDS_MeshNode * n41, 
-                                      int ID);
+                                       const SMDS_MeshNode * n2,
+                                       const SMDS_MeshNode * n3,
+                                       const SMDS_MeshNode * n4,
+                                       const SMDS_MeshNode * n12,
+                                       const SMDS_MeshNode * n23,
+                                       const SMDS_MeshNode * n34,
+                                       const SMDS_MeshNode * n41,
+                                       int ID);
   virtual SMDS_MeshFace* 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,
                                  const SMDS_MeshNode * n12,
-                                const SMDS_MeshNode * n23,
-                                const SMDS_MeshNode * n34,
-                                const SMDS_MeshNode * n41);
+                                 const SMDS_MeshNode * n23,
+                                 const SMDS_MeshNode * n34,
+                                 const SMDS_MeshNode * n41);
+
+  virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int n4,
+                                       int n12,int n23,int n34,int n41, int nCenter, int ID);
+  virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1,
+                                       const SMDS_MeshNode * n2,
+                                       const SMDS_MeshNode * n3,
+                                       const SMDS_MeshNode * n4,
+                                       const SMDS_MeshNode * n12,
+                                       const SMDS_MeshNode * n23,
+                                       const SMDS_MeshNode * n34,
+                                       const SMDS_MeshNode * n41,
+                                       const SMDS_MeshNode * nCenter,
+                                       int ID);
+  virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1,
+                                 const SMDS_MeshNode * n2,
+                                 const SMDS_MeshNode * n3,
+                                 const SMDS_MeshNode * n4,
+                                 const SMDS_MeshNode * n12,
+                                 const SMDS_MeshNode * n23,
+                                 const SMDS_MeshNode * n34,
+                                 const SMDS_MeshNode * n41,
+                                 const SMDS_MeshNode * nCenter);
 
   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);
+                                           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);
-  
+                                     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);
+                                           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);
-  
+                                     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);
+                                           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);
-  
+                                     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);
+                                           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);
+                                     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,
@@ -244,29 +307,59 @@ public:
                                      const SMDS_MeshFace * f5,
                                      const SMDS_MeshFace * f6);
 
+  // hexagonal prism
+  virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6,
+                                           int n7, int n8, int n9, int n10, int n11, int n12,
+                                           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,
+                                           const SMDS_MeshNode * n9,
+                                           const SMDS_MeshNode * n10,
+                                           const SMDS_MeshNode * n11,
+                                           const SMDS_MeshNode * n12,
+                                           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,
+                                     const SMDS_MeshNode * n9,
+                                     const SMDS_MeshNode * n10,
+                                     const SMDS_MeshNode * n11,
+                                     const SMDS_MeshNode * n12);
+
   // 2d order tetrahedron of 10 nodes
   virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4,
                                            int n12,int n23,int n31,
                                            int n14,int n24,int n34, 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 * n12,
-                                          const SMDS_MeshNode * n23,
-                                          const SMDS_MeshNode * n31,
-                                          const SMDS_MeshNode * n14, 
-                                          const SMDS_MeshNode * n24,
-                                          const SMDS_MeshNode * n34, 
-                                          int ID);
+                                           const SMDS_MeshNode * n2,
+                                           const SMDS_MeshNode * n3,
+                                           const SMDS_MeshNode * n4,
+                                           const SMDS_MeshNode * n12,
+                                           const SMDS_MeshNode * n23,
+                                           const SMDS_MeshNode * n31,
+                                           const SMDS_MeshNode * n14,
+                                           const SMDS_MeshNode * n24,
+                                           const SMDS_MeshNode * n34,
+                                           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 * n2,
+                                     const SMDS_MeshNode * n3,
+                                     const SMDS_MeshNode * n4,
                                      const SMDS_MeshNode * n12,
                                      const SMDS_MeshNode * n23,
                                      const SMDS_MeshNode * n31,
-                                     const SMDS_MeshNode * n14, 
+                                     const SMDS_MeshNode * n14,
                                      const SMDS_MeshNode * n24,
                                      const SMDS_MeshNode * n34);
 
@@ -276,28 +369,28 @@ public:
                                            int n15,int n25,int n35,int n45,
                                            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 * n12,
-                                          const SMDS_MeshNode * n23,
-                                          const SMDS_MeshNode * n34,
-                                          const SMDS_MeshNode * n41, 
-                                          const SMDS_MeshNode * n15,
-                                          const SMDS_MeshNode * n25,
-                                          const SMDS_MeshNode * n35,
-                                          const SMDS_MeshNode * n45, 
-                                          int ID);
+                                           const SMDS_MeshNode * n2,
+                                           const SMDS_MeshNode * n3,
+                                           const SMDS_MeshNode * n4,
+                                           const SMDS_MeshNode * n5,
+                                           const SMDS_MeshNode * n12,
+                                           const SMDS_MeshNode * n23,
+                                           const SMDS_MeshNode * n34,
+                                           const SMDS_MeshNode * n41,
+                                           const SMDS_MeshNode * n15,
+                                           const SMDS_MeshNode * n25,
+                                           const SMDS_MeshNode * n35,
+                                           const SMDS_MeshNode * n45,
+                                           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 * n2,
+                                     const SMDS_MeshNode * n3,
+                                     const SMDS_MeshNode * n4,
+                                     const SMDS_MeshNode * n5,
                                      const SMDS_MeshNode * n12,
                                      const SMDS_MeshNode * n23,
                                      const SMDS_MeshNode * n34,
-                                     const SMDS_MeshNode * n41, 
+                                     const SMDS_MeshNode * n41,
                                      const SMDS_MeshNode * n15,
                                      const SMDS_MeshNode * n25,
                                      const SMDS_MeshNode * n35,
@@ -311,33 +404,33 @@ public:
                                            int n14,int n25,int n36,
                                            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 * n12,
-                                          const SMDS_MeshNode * n23,
-                                          const SMDS_MeshNode * n31, 
-                                          const SMDS_MeshNode * n45,
-                                          const SMDS_MeshNode * n56,
-                                          const SMDS_MeshNode * n64, 
-                                          const SMDS_MeshNode * n14,
-                                          const SMDS_MeshNode * n25,
-                                          const SMDS_MeshNode * n36, 
-                                          int ID);
+                                           const SMDS_MeshNode * n2,
+                                           const SMDS_MeshNode * n3,
+                                           const SMDS_MeshNode * n4,
+                                           const SMDS_MeshNode * n5,
+                                           const SMDS_MeshNode * n6,
+                                           const SMDS_MeshNode * n12,
+                                           const SMDS_MeshNode * n23,
+                                           const SMDS_MeshNode * n31,
+                                           const SMDS_MeshNode * n45,
+                                           const SMDS_MeshNode * n56,
+                                           const SMDS_MeshNode * n64,
+                                           const SMDS_MeshNode * n14,
+                                           const SMDS_MeshNode * n25,
+                                           const SMDS_MeshNode * n36,
+                                           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 * n2,
+                                     const SMDS_MeshNode * n3,
+                                     const SMDS_MeshNode * n4,
+                                     const SMDS_MeshNode * n5,
+                                     const SMDS_MeshNode * n6,
                                      const SMDS_MeshNode * n12,
                                      const SMDS_MeshNode * n23,
-                                     const SMDS_MeshNode * n31, 
+                                     const SMDS_MeshNode * n31,
                                      const SMDS_MeshNode * n45,
                                      const SMDS_MeshNode * n56,
-                                     const SMDS_MeshNode * n64, 
+                                     const SMDS_MeshNode * n64,
                                      const SMDS_MeshNode * n14,
                                      const SMDS_MeshNode * n25,
                                      const SMDS_MeshNode * n36);
@@ -350,68 +443,143 @@ public:
                                            int n15,int n26,int n37,int n48,
                                            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, 
-                                          const SMDS_MeshNode * n12,
-                                          const SMDS_MeshNode * n23,
-                                          const SMDS_MeshNode * n34,
-                                          const SMDS_MeshNode * n41, 
-                                          const SMDS_MeshNode * n56,
-                                          const SMDS_MeshNode * n67,
-                                          const SMDS_MeshNode * n78,
-                                          const SMDS_MeshNode * n85, 
-                                          const SMDS_MeshNode * n15,
-                                          const SMDS_MeshNode * n26,
-                                          const SMDS_MeshNode * n37,
-                                          const SMDS_MeshNode * n48, 
-                                          int ID);
+                                           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 * n12,
+                                           const SMDS_MeshNode * n23,
+                                           const SMDS_MeshNode * n34,
+                                           const SMDS_MeshNode * n41,
+                                           const SMDS_MeshNode * n56,
+                                           const SMDS_MeshNode * n67,
+                                           const SMDS_MeshNode * n78,
+                                           const SMDS_MeshNode * n85,
+                                           const SMDS_MeshNode * n15,
+                                           const SMDS_MeshNode * n26,
+                                           const SMDS_MeshNode * n37,
+                                           const SMDS_MeshNode * n48,
+                                           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, 
+                                     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 * n12,
                                      const SMDS_MeshNode * n23,
                                      const SMDS_MeshNode * n34,
-                                     const SMDS_MeshNode * n41, 
+                                     const SMDS_MeshNode * n41,
                                      const SMDS_MeshNode * n56,
                                      const SMDS_MeshNode * n67,
                                      const SMDS_MeshNode * n78,
-                                     const SMDS_MeshNode * n85, 
+                                     const SMDS_MeshNode * n85,
                                      const SMDS_MeshNode * n15,
                                      const SMDS_MeshNode * n26,
                                      const SMDS_MeshNode * n37,
                                      const SMDS_MeshNode * n48);
 
-  virtual SMDS_MeshFace* AddPolygonalFaceWithID (std::vector<int> nodes_ids,
-                                                 const int        ID);
+  // 2d oreder Hexahedrons with 27 nodes
+  virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4,
+                                           int n5, int n6, int n7, int n8,
+                                           int n12,int n23,int n34,int n41,
+                                           int n56,int n67,int n78,int n85,
+                                           int n15,int n26,int n37,int n48,
+                                           int n1234,int n1256,int n2367,int n3478,
+                                           int n1458,int n5678,int nCenter,
+                                           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,
+                                           const SMDS_MeshNode * n12,
+                                           const SMDS_MeshNode * n23,
+                                           const SMDS_MeshNode * n34,
+                                           const SMDS_MeshNode * n41,
+                                           const SMDS_MeshNode * n56,
+                                           const SMDS_MeshNode * n67,
+                                           const SMDS_MeshNode * n78,
+                                           const SMDS_MeshNode * n85,
+                                           const SMDS_MeshNode * n15,
+                                           const SMDS_MeshNode * n26,
+                                           const SMDS_MeshNode * n37,
+                                           const SMDS_MeshNode * n48,
+                                           const SMDS_MeshNode * n1234,
+                                           const SMDS_MeshNode * n1256,
+                                           const SMDS_MeshNode * n2367,
+                                           const SMDS_MeshNode * n3478,
+                                           const SMDS_MeshNode * n1458,
+                                           const SMDS_MeshNode * n5678,
+                                           const SMDS_MeshNode * nCenter,
+                                           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,
+                                     const SMDS_MeshNode * n12,
+                                     const SMDS_MeshNode * n23,
+                                     const SMDS_MeshNode * n34,
+                                     const SMDS_MeshNode * n41,
+                                     const SMDS_MeshNode * n56,
+                                     const SMDS_MeshNode * n67,
+                                     const SMDS_MeshNode * n78,
+                                     const SMDS_MeshNode * n85,
+                                     const SMDS_MeshNode * n15,
+                                     const SMDS_MeshNode * n26,
+                                     const SMDS_MeshNode * n37,
+                                     const SMDS_MeshNode * n48,
+                                     const SMDS_MeshNode * n1234,
+                                     const SMDS_MeshNode * n1256,
+                                     const SMDS_MeshNode * n2367,
+                                     const SMDS_MeshNode * n3478,
+                                     const SMDS_MeshNode * n1458,
+                                     const SMDS_MeshNode * n5678,
+                                     const SMDS_MeshNode * nCenter);
+
+  virtual SMDS_MeshFace* AddPolygonalFaceWithID (const std::vector<int> & nodes_ids,
+                                                 const int                ID);
 
-  virtual SMDS_MeshFace* AddPolygonalFaceWithID (std::vector<const SMDS_MeshNode*> nodes,
-                                                 const int                         ID);
+  virtual SMDS_MeshFace* AddPolygonalFaceWithID (const std::vector<const SMDS_MeshNode*> & nodes,
+                                                 const int                                 ID);
 
-  virtual SMDS_MeshFace* AddPolygonalFace (std::vector<const SMDS_MeshNode*> nodes);
+  virtual SMDS_MeshFace* AddPolygonalFace (const std::vector<const SMDS_MeshNode*> & nodes);
 
   virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID
-                           (std::vector<int> nodes_ids,
-                            std::vector<int> quantities,
-                            const int        ID);
+                           (const std::vector<int> & nodes_ids,
+                            const std::vector<int> & quantities,
+                            const int                ID);
 
   virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID
-                           (std::vector<const SMDS_MeshNode*> nodes,
-                            std::vector<int>                  quantities,
-                            const int                         ID);
+                           (const std::vector<const SMDS_MeshNode*> & nodes,
+                            const std::vector<int>                  & quantities,
+                            const int                                 ID);
 
   virtual SMDS_MeshVolume* AddPolyhedralVolume
-                           (std::vector<const SMDS_MeshNode*> nodes,
-                            std::vector<int>                  quantities);
+                           (const std::vector<const SMDS_MeshNode*> & nodes,
+                            const std::vector<int>                  & quantities);
+
+  virtual SMDS_MeshVolume* AddVolumeFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds);
+
+  virtual SMDS_MeshVolume* AddVolumeFromVtkIdsWithID(const std::vector<vtkIdType>& vtkNodeIds,
+                                                     const int ID);
+
+  virtual SMDS_MeshFace* AddFaceFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds);
+
+  virtual SMDS_MeshFace* AddFaceFromVtkIdsWithID(const std::vector<vtkIdType>& vtkNodeIds,
+                                                     const int ID);
 
   virtual void RemoveElement(const SMDS_MeshElement *        elem,
                              std::list<const SMDS_MeshElement *>& removedElems,
@@ -419,6 +587,7 @@ public:
                              const bool                      removenodes = false);
   virtual void RemoveElement(const SMDS_MeshElement * elem, bool removenodes = false);
   virtual void RemoveNode(const SMDS_MeshNode * node);
+  virtual void Remove0DElement(const SMDS_Mesh0DElement * elem0d);
   virtual void RemoveEdge(const SMDS_MeshEdge * edge);
   virtual void RemoveFace(const SMDS_MeshFace * face);
   virtual void RemoveVolume(const SMDS_MeshVolume * volume);
@@ -430,7 +599,7 @@ public:
   virtual void RemoveFreeElement(const SMDS_MeshElement * elem);
 
   virtual void Clear();
-  
+
   virtual bool RemoveFromParent();
   virtual bool RemoveSubMesh(const SMDS_Mesh * aMesh);
 
@@ -443,8 +612,12 @@ public:
 
   virtual void Renumber (const bool isNodes, const int startID = 1, const int deltaID = 1);
   // Renumber all nodes or elements.
+  virtual void compactMesh();
 
   const SMDS_MeshNode *FindNode(int idnode) const;
+  const SMDS_MeshNode *FindNodeVtk(int idnode) const;
+  const SMDS_Mesh0DElement* Find0DElement(int idnode) const;
+  const SMDS_BallElement* FindBall(int idnode) const;
   const SMDS_MeshEdge *FindEdge(int idnode1, int idnode2) const;
   const SMDS_MeshEdge *FindEdge(int idnode1, int idnode2, int idnode3) const;
   const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3) const;
@@ -454,6 +627,8 @@ public:
   const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3, int idnode4,
                                 int idnode5, int idnode6, int idnode7, int idnode8) const;
   const SMDS_MeshElement *FindElement(int IDelem) const;
+  static const SMDS_Mesh0DElement* Find0DElement(const SMDS_MeshNode * n);
+  static const SMDS_BallElement* FindBall(const SMDS_MeshNode * n);
   static const SMDS_MeshEdge* FindEdge(const SMDS_MeshNode * n1,
                                        const SMDS_MeshNode * n2);
   static const SMDS_MeshEdge* FindEdge(const SMDS_MeshNode * n1,
@@ -481,8 +656,11 @@ public:
                                        const SMDS_MeshNode *n7,
                                        const SMDS_MeshNode *n8);
 
-  const SMDS_MeshFace *FindFace(std::vector<int> nodes_ids) const;
-  static const SMDS_MeshFace* FindFace(std::vector<const SMDS_MeshNode *> nodes);
+  const SMDS_MeshFace *FindFace(const std::vector<int>& nodes_ids) const;
+  static const SMDS_MeshFace* FindFace(const std::vector<const SMDS_MeshNode *>& nodes);
+  static const SMDS_MeshElement* FindElement(const std::vector<const SMDS_MeshNode *>& nodes,
+                                             const SMDSAbs_ElementType                 type=SMDSAbs_All,
+                                             const bool                                noMedium=true);
 
   /*!
    * \brief Raise an exception if free memory (ram+swap) too low
@@ -498,19 +676,23 @@ public:
 
   const SMDS_MeshInfo& GetMeshInfo() const { return myInfo; }
 
-  int NbNodes() const;
-  int NbEdges() const;
-  int NbFaces() const;
-  int NbVolumes() const;
-  int NbSubMesh() const;
+  virtual int NbNodes() const;
+  virtual int Nb0DElements() const;
+  virtual int NbBalls() const;
+  virtual int NbEdges() const;
+  virtual int NbFaces() const;
+  virtual int NbVolumes() const;
+  virtual int NbSubMesh() const;
+
   void DumpNodes() const;
+  void Dump0DElements() 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();
@@ -526,52 +708,127 @@ public:
    */
   bool Contains (const SMDS_MeshElement* elem) const;
 
-  typedef NCollection_Map<SMDS_MeshNode *> SetOfNodes;
-  typedef NCollection_Map<SMDS_MeshEdge *> SetOfEdges;
-  typedef NCollection_Map<SMDS_MeshFace *> SetOfFaces;
-  typedef NCollection_Map<SMDS_MeshVolume *> SetOfVolumes;
+  typedef std::vector<SMDS_MeshNode *> SetOfNodes;
+  typedef std::vector<SMDS_MeshCell *> SetOfCells;
+
+  void updateNodeMinMax();
+  void updateBoundingBox();
+  double getMaxDim();
+  int fromVtkToSmds(int vtkid);
+
+  void incrementNodesCapacity(int nbNodes);
+  void incrementCellsCapacity(int nbCells);
+  void adjustStructure();
+  void dumpGrid(string ficdump="dumpGrid");
+  static int chunkSize;
 
-private:
+  //! low level modification: add, change or remove node or element
+  inline void setMyModified() { this->myModified = true; }
+
+  void Modified();
+  unsigned long GetMTime() const;
+  bool isCompacted();
+
+protected:
   SMDS_Mesh(SMDS_Mesh * parent);
 
-  SMDS_MeshFace * createTriangle(const SMDS_MeshNode * node1, 
-                                const SMDS_MeshNode * node2, 
-                                const SMDS_MeshNode * node3);
+  SMDS_MeshFace * createTriangle(const SMDS_MeshNode * node1,
+                                 const SMDS_MeshNode * node2,
+                                 const SMDS_MeshNode * node3,
+                                 int ID);
   SMDS_MeshFace * createQuadrangle(const SMDS_MeshNode * node1,
-                                  const SMDS_MeshNode * node2, 
-                                  const SMDS_MeshNode * node3, 
-                                  const SMDS_MeshNode * node4);
+                                   const SMDS_MeshNode * node2,
+                                   const SMDS_MeshNode * node3,
+                                   const SMDS_MeshNode * node4,
+                                   int ID);
   SMDS_MeshEdge* FindEdgeOrCreate(const SMDS_MeshNode * n1,
-                                 const SMDS_MeshNode * n2);
+                                  const SMDS_MeshNode * n2);
   SMDS_MeshFace* FindFaceOrCreate(const SMDS_MeshNode *n1,
-                                 const SMDS_MeshNode *n2,
-                                 const SMDS_MeshNode *n3);
+                                  const SMDS_MeshNode *n2,
+                                  const SMDS_MeshNode *n3);
   SMDS_MeshFace* FindFaceOrCreate(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);
 
   bool registerElement(int ID, SMDS_MeshElement * element);
 
-  void addChildrenWithNodes(std::set<const SMDS_MeshElement*>& setOfChildren, 
-                           const SMDS_MeshElement * element, 
-                           std::set<const SMDS_MeshElement*>& nodes);
+  void addChildrenWithNodes(std::set<const SMDS_MeshElement*>& setOfChildren,
+                            const SMDS_MeshElement * element,
+                            std::set<const SMDS_MeshElement*>& nodes);
+
+  inline void adjustmyCellsCapacity(int ID)
+  {
+    assert(ID >= 0);
+    myElementIDFactory->adjustMaxId(ID);
+    if (ID >= myCells.size())
+      myCells.resize(ID+SMDS_Mesh::chunkSize,0);
+  }
+
+  inline void adjustBoundingBox(double x, double y, double z)
+  {
+    if (x > xmax) xmax = x;
+    else if (x < xmin) xmin = x;
+    if (y > ymax) ymax = y;
+    else if (y < ymin) ymin = y;
+    if (z > zmax) zmax = z;
+    else if (z < zmin) zmin = z;
+  }
 
   // Fields PRIVATE
-  
+
+  //! index of this SMDS_mesh in the static vector<SMDS_Mesh*> _meshList
+  int myMeshId;
+
+  //! actual nodes coordinates, cells definition and reverse connectivity are stored in a vtkUnstructuredGrid
+  SMDS_UnstructuredGrid*      myGrid;
+
+  //! Small objects like SMDS_MeshNode are allocated by chunks to limit memory costs of new
+  ObjectPool<SMDS_MeshNode>* myNodePool;
+
+  //! Small objects like SMDS_VtkVolume are allocated by chunks to limit memory costs of new
+  ObjectPool<SMDS_VtkVolume>*   myVolumePool;
+  ObjectPool<SMDS_VtkFace>*     myFacePool;
+  ObjectPool<SMDS_VtkEdge>*     myEdgePool;
+  ObjectPool<SMDS_BallElement>* myBallPool;
+
+  //! SMDS_MeshNodes refer to vtk nodes (vtk id = index in myNodes),store reference to this mesh, and sub-shape
   SetOfNodes             myNodes;
-  SetOfEdges             myEdges;
-  SetOfFaces             myFaces;
-  SetOfVolumes           myVolumes;
+
+  //! SMDS_MeshCells refer to vtk cells (vtk id != index in myCells),store reference to this mesh, and sub-shape
+  SetOfCells             myCells;
+
+  //! for cells only: index = ID for SMDS users, value = ID in vtkUnstructuredGrid
+  //std::vector<int>       myCellIdSmdsToVtk;
+
+  //! for cells only: index = ID in vtkUnstructuredGrid, value = ID for SMDS users
+  std::vector<int>       myCellIdVtkToSmds;
+
   SMDS_Mesh *            myParent;
   std::list<SMDS_Mesh *> myChildren;
-  SMDS_MeshElementIDFactory *myNodeIDFactory;
+  SMDS_MeshNodeIDFactory *myNodeIDFactory;
   SMDS_MeshElementIDFactory *myElementIDFactory;
   SMDS_MeshInfo          myInfo;
 
+  //! use a counter to keep track of modifications
+  unsigned long myModifTime, myCompactTime;
+
+  int myNodeMin;
+  int myNodeMax;
+
   bool myHasConstructionEdges;
   bool myHasConstructionFaces;
   bool myHasInverseElements;
+
+  //! any add, remove or change of node or cell
+  bool myModified;
+
+  double xmin;
+  double xmax;
+  double ymin;
+  double ymax;
+  double zmin;
+  double zmax;
 };
 
 
diff --git a/src/SMDS/SMDS_Mesh0DElement.cxx b/src/SMDS/SMDS_Mesh0DElement.cxx
new file mode 100644 (file)
index 0000000..a1a244c
--- /dev/null
@@ -0,0 +1,147 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+//  SMESH SMDS : implementaion of Salome mesh data structure
+//  File   : SMDS_Mesh0DElement.cxx
+//  Module : SMESH
+//
+#ifdef _MSC_VER
+#pragma warning(disable:4786)
+#endif
+
+#include "SMDS_Mesh0DElement.hxx"
+#include "SMDS_IteratorOfElements.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "utilities.h"
+
+using namespace std;
+
+//=======================================================================
+//function : SMDS_Mesh0DElement
+//purpose  :
+//=======================================================================
+SMDS_Mesh0DElement::SMDS_Mesh0DElement (const SMDS_MeshNode * node)
+{
+  MESSAGE("SMDS_Mesh0DElement " << GetID());
+  myNode = node;
+}
+
+//=======================================================================
+//function : Print
+//purpose  :
+//=======================================================================
+void SMDS_Mesh0DElement::Print (ostream & OS) const
+{
+  OS << "0D Element <" << GetID() << "> : (" << myNode << ") " << endl;
+}
+
+//=======================================================================
+//function : NbNodes
+//purpose  :
+//=======================================================================
+int SMDS_Mesh0DElement::NbNodes() const
+{
+  return 1;
+}
+
+//=======================================================================
+//function : NbEdges
+//purpose  :
+//=======================================================================
+int SMDS_Mesh0DElement::NbEdges() const
+{
+  return 0;
+}
+
+//=======================================================================
+//function : GetType
+//purpose  :
+//=======================================================================
+SMDSAbs_ElementType SMDS_Mesh0DElement::GetType() const
+{
+  return SMDSAbs_0DElement;
+}
+
+vtkIdType SMDS_Mesh0DElement::GetVtkType() const
+{
+  return VTK_VERTEX;
+}
+
+//=======================================================================
+//function : elementsIterator
+//purpose  :
+//=======================================================================
+class SMDS_Mesh0DElement_MyNodeIterator: public SMDS_ElemIterator
+{
+  const SMDS_MeshNode * myNode;
+  int myIndex;
+ public:
+  SMDS_Mesh0DElement_MyNodeIterator(const SMDS_MeshNode * node):
+    myNode(node),myIndex(0) {}
+
+  bool more()
+  {
+    return myIndex < 1;
+  }
+
+  const SMDS_MeshElement* next()
+  {
+    myIndex++;
+    if (myIndex == 1)
+      return myNode;
+    return NULL;
+  }
+};
+
+SMDS_ElemIteratorPtr SMDS_Mesh0DElement::elementsIterator (SMDSAbs_ElementType type) const
+{
+  switch(type)
+  {
+  case SMDSAbs_0DElement:
+    return SMDS_MeshElement::elementsIterator(SMDSAbs_0DElement);
+  case SMDSAbs_Node:
+    return SMDS_ElemIteratorPtr(new SMDS_Mesh0DElement_MyNodeIterator(myNode));
+  default:
+    return SMDS_ElemIteratorPtr
+      (new SMDS_IteratorOfElements
+       (this,type, SMDS_ElemIteratorPtr(new SMDS_Mesh0DElement_MyNodeIterator(myNode))));
+  }
+}
+
+/*!
+ * \brief Return node by its index
+ * \param ind - node index
+ * \retval const SMDS_MeshNode* - the node
+ */
+const SMDS_MeshNode* SMDS_Mesh0DElement::GetNode(const int ind) const
+{
+  if (ind == 0)
+    return myNode;
+  return NULL;
+}
+
+//=======================================================================
+//function : ChangeNode
+//purpose  :
+//=======================================================================
+bool SMDS_Mesh0DElement::ChangeNode (const SMDS_MeshNode * node)
+{
+  myNode = node;
+  return true;
+}
diff --git a/src/SMDS/SMDS_Mesh0DElement.hxx b/src/SMDS/SMDS_Mesh0DElement.hxx
new file mode 100644 (file)
index 0000000..81578a8
--- /dev/null
@@ -0,0 +1,56 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+//  SMESH SMDS : implementaion of Salome mesh data structure
+//  File   : SMDS_Mesh0DElement.hxx
+//  Module : SMESH
+//
+#ifndef _SMDS_Mesh0DElement_HeaderFile
+#define _SMDS_Mesh0DElement_HeaderFile
+
+#include "SMESH_SMDS.hxx"
+
+#include "SMDS_MeshCell.hxx"
+
+#include <iostream>
+
+class SMDS_EXPORT SMDS_Mesh0DElement: public SMDS_MeshCell
+{
+ public:
+  SMDS_Mesh0DElement (const SMDS_MeshNode * node);
+  bool ChangeNode (const SMDS_MeshNode * node);
+  virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) {return false;};
+  virtual void Print (std::ostream & OS) const;
+
+  virtual SMDSAbs_ElementType  GetType() const;
+  virtual vtkIdType            GetVtkType() const;
+  virtual SMDSAbs_EntityType   GetEntityType() const {return SMDSEntity_0D;}
+  virtual SMDSAbs_GeometryType GetGeomType() const { return SMDSGeom_POINT; }
+  virtual const SMDS_MeshNode* GetNode (const int ind) const;
+  virtual int NbNodes() const;
+  virtual int NbEdges() const;
+
+ protected:
+  virtual SMDS_ElemIteratorPtr elementsIterator (SMDSAbs_ElementType type) const;
+
+ protected:
+  const SMDS_MeshNode* myNode;
+};
+
+#endif
diff --git a/src/SMDS/SMDS_MeshCell.cxx b/src/SMDS/SMDS_MeshCell.cxx
new file mode 100644 (file)
index 0000000..521c976
--- /dev/null
@@ -0,0 +1,428 @@
+// Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+#include "SMDS_MeshCell.hxx"
+#include "utilities.h"
+
+int SMDS_MeshCell::nbCells = 0;
+
+SMDS_MeshCell::SMDS_MeshCell() :
+  SMDS_MeshElement(-1)
+{
+  nbCells++;
+  myVtkID = -1;
+}
+
+SMDS_MeshCell::~SMDS_MeshCell()
+{
+  nbCells--;
+}
+//================================================================================
+/*!
+ * \brief Return VTKCellType corresponding to SMDSAbs_EntityType
+ */
+//================================================================================
+
+VTKCellType SMDS_MeshCell::toVtkType (SMDSAbs_EntityType smdsType)
+{
+  static std::vector< VTKCellType > vtkTypes;
+  if ( vtkTypes.empty() )
+  {
+    vtkTypes.resize( SMDSEntity_Last+1, VTK_EMPTY_CELL );
+    vtkTypes[ SMDSEntity_Node ]              = VTK_VERTEX;
+    vtkTypes[ SMDSEntity_0D ]                = VTK_VERTEX;
+    vtkTypes[ SMDSEntity_Edge ]              = VTK_LINE;
+    vtkTypes[ SMDSEntity_Quad_Edge ]         = VTK_QUADRATIC_EDGE;
+    vtkTypes[ SMDSEntity_Triangle ]          = VTK_TRIANGLE;
+    vtkTypes[ SMDSEntity_Quad_Triangle ]     = VTK_QUADRATIC_TRIANGLE;
+    vtkTypes[ SMDSEntity_Quadrangle ]        = VTK_QUAD;
+    vtkTypes[ SMDSEntity_Quad_Quadrangle ]   = VTK_QUADRATIC_QUAD;
+    vtkTypes[ SMDSEntity_BiQuad_Quadrangle ] = VTK_BIQUADRATIC_QUAD;
+    vtkTypes[ SMDSEntity_Polygon ]           = VTK_POLYGON;
+    //vtkTypes[ SMDSEntity_Quad_Polygon ]      = ;
+    vtkTypes[ SMDSEntity_Tetra ]             = VTK_TETRA;
+    vtkTypes[ SMDSEntity_Quad_Tetra ]        = VTK_QUADRATIC_TETRA;
+    vtkTypes[ SMDSEntity_Pyramid ]           = VTK_PYRAMID;
+    vtkTypes[ SMDSEntity_Quad_Pyramid ]      = VTK_QUADRATIC_PYRAMID;
+    vtkTypes[ SMDSEntity_Hexa ]              = VTK_HEXAHEDRON;
+    vtkTypes[ SMDSEntity_Quad_Hexa ]         = VTK_QUADRATIC_HEXAHEDRON;
+    vtkTypes[ SMDSEntity_TriQuad_Hexa ]      = VTK_TRIQUADRATIC_HEXAHEDRON;
+    vtkTypes[ SMDSEntity_Penta ]             = VTK_WEDGE;
+    vtkTypes[ SMDSEntity_Quad_Penta ]        = VTK_QUADRATIC_WEDGE;
+    vtkTypes[ SMDSEntity_Hexagonal_Prism ]   = VTK_HEXAGONAL_PRISM;
+    vtkTypes[ SMDSEntity_Polyhedra ]         = VTK_POLYHEDRON;
+    //vtkTypes[ SMDSEntity_Quad_Polyhedra ]    = ;
+    vtkTypes[ SMDSEntity_Ball ]              = VTK_POLY_VERTEX;
+  }
+  return vtkTypes[ smdsType ];
+}
+
+//================================================================================
+/*!
+ * \brief Return indices to transform cell connectivity from SMDS to VTK
+ * Usage: vtkIDs[i] = smdsIDs[ indices[ i ]]
+ */
+//================================================================================
+
+const std::vector< int >& SMDS_MeshCell::toVtkOrder(SMDSAbs_EntityType smdsType)
+{
+  static std::vector< std::vector< int > > toVtkInterlaces;
+  if ( toVtkInterlaces.empty() )
+  {
+    toVtkInterlaces.resize( SMDSEntity_Last+1 );
+    // {
+    //   const int ids[] = {0};
+    //   toVtkInterlaces[SMDSEntity_0D].assign( &ids[0], &ids[0]+1 );
+    //   toVtkInterlaces[SMDSEntity_Node].assign( &ids[0], &ids[0]+1 );
+    // }
+    // {
+    //   const int ids[] = {0,1};
+    //   toVtkInterlaces[SMDSEntity_Edge].assign( &ids[0], &ids[0]+2 );
+    // }
+    // {
+    //   const int ids[] = {0,1,2};
+    //   toVtkInterlaces[SMDSEntity_Quad_Edge].assign( &ids[0], &ids[0]+3 );
+    // }
+    // {
+    //   const int ids[] = {0,1,2};
+    //   toVtkInterlaces[SMDSEntity_Triangle].assign( &ids[0], &ids[0]+3 );
+    // }
+    // {
+    //   const int ids[] = {0,1,2,3,4,5};
+    //   toVtkInterlaces[SMDSEntity_Quad_Triangle].assign( &ids[0], &ids[0]+6 );
+    // }
+    // {
+    //   const int ids[] = {0,1,2,3};
+    //   toVtkInterlaces[SMDSEntity_Quadrangle].assign( &ids[0], &ids[0]+4 );
+    // }
+    // {
+    //   const int ids[] = {0,1,2,3,4,5,6,7};
+    //   toVtkInterlaces[SMDSEntity_Quad_Quadrangle].assign( &ids[0], &ids[0]+8 );
+    // }
+    // {
+    //   const int ids[] = {0,1,2,3,4,5,6,7,8};
+    //   toVtkInterlaces[SMDSEntity_BiQuad_Quadrangle].assign( &ids[0], &ids[0]+9 );
+    // }
+    {
+      const int ids[] = {0,2,1,3};
+      toVtkInterlaces[SMDSEntity_Tetra].assign( &ids[0], &ids[0]+4 );
+    }
+    {
+      const int ids[] = {0,2,1,3,6,5,4,7,9,8};
+      toVtkInterlaces[SMDSEntity_Quad_Tetra].assign( &ids[0], &ids[0]+10 );
+    }
+    {
+      const int ids[] = {0,3,2,1,4};
+      toVtkInterlaces[SMDSEntity_Pyramid].assign( &ids[0], &ids[0]+5 );
+    }
+    {
+      const int ids[] = {0,3,2,1,4,8,7,6,5,9,12,11,10};
+      toVtkInterlaces[SMDSEntity_Quad_Pyramid].assign( &ids[0], &ids[0]+13 );
+    }
+    {
+      const int ids[] = {0,3,2,1,4,7,6,5};
+      toVtkInterlaces[SMDSEntity_Hexa].assign( &ids[0], &ids[0]+8 );
+    }
+    {
+      const int ids[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17};
+      toVtkInterlaces[SMDSEntity_Quad_Hexa].assign( &ids[0], &ids[0]+20 );
+    }
+    {
+      const int ids[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17, 21,23,24,22,20,25,26};
+      toVtkInterlaces[SMDSEntity_TriQuad_Hexa].assign( &ids[0], &ids[0]+27 );
+    }
+    {
+      const int ids[] = {0,1,2,3,4,5};
+      toVtkInterlaces[SMDSEntity_Penta].assign( &ids[0], &ids[0]+6 );
+    }
+    {
+      const int ids[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14};
+      toVtkInterlaces[SMDSEntity_Quad_Penta].assign( &ids[0], &ids[0]+15 );
+    }
+    {
+      const int ids[] = {0,5,4,3,2,1,6,11,10,9,8,7};
+      toVtkInterlaces[SMDSEntity_Hexagonal_Prism].assign( &ids[0], &ids[0]+12 );
+    }
+  }
+  return toVtkInterlaces[smdsType];
+}
+
+//================================================================================
+/*!
+ * \brief Return indices to reverse an SMDS cell of given type
+ * Usage: reverseIDs[i] = forwardIDs[ indices[ i ]]
+ */
+//================================================================================
+
+const std::vector<int>& SMDS_MeshCell::reverseSmdsOrder(SMDSAbs_EntityType smdsType)
+{
+  static std::vector< std::vector< int > > reverseInterlaces;
+  if ( reverseInterlaces.empty() )
+  {
+    reverseInterlaces.resize( SMDSEntity_Last+1 );
+    {
+      const int ids[] = {0};
+      reverseInterlaces[SMDSEntity_0D].assign( &ids[0], &ids[0]+1 );
+      reverseInterlaces[SMDSEntity_Node].assign( &ids[0], &ids[0]+1 );
+      reverseInterlaces[SMDSEntity_Ball].assign( &ids[0], &ids[0]+1 );
+    }
+    {
+      const int ids[] = {1,0};
+      reverseInterlaces[SMDSEntity_Edge].assign( &ids[0], &ids[0]+2 );
+    }
+    {
+      const int ids[] = {1,0,2};
+      reverseInterlaces[SMDSEntity_Quad_Edge].assign( &ids[0], &ids[0]+3 );
+    }
+    {
+      const int ids[] = {0,2,1};
+      reverseInterlaces[SMDSEntity_Triangle].assign( &ids[0], &ids[0]+3 );
+    }
+    {
+      const int ids[] = {0,2,1,5,4,3};
+      reverseInterlaces[SMDSEntity_Quad_Triangle].assign( &ids[0], &ids[0]+6 );
+    }
+    {
+      const int ids[] = {0,3,2,1};
+      reverseInterlaces[SMDSEntity_Quadrangle].assign( &ids[0], &ids[0]+4 );
+    }
+    {
+      const int ids[] = {0,3,2,1,7,6,5,4};
+      reverseInterlaces[SMDSEntity_Quad_Quadrangle].assign( &ids[0], &ids[0]+8 );
+    }
+    {
+      const int ids[] = {0,3,2,1,7,6,5,4,8};
+      reverseInterlaces[SMDSEntity_BiQuad_Quadrangle].assign( &ids[0], &ids[0]+9 );
+    }
+    {
+      const int ids[] = {0,2,1,3};
+      reverseInterlaces[SMDSEntity_Tetra].assign( &ids[0], &ids[0]+4 );
+    }
+    {
+      const int ids[] = {0,2,1,3,6,5,4,7,9,8};
+      reverseInterlaces[SMDSEntity_Quad_Tetra].assign( &ids[0], &ids[0]+10 );
+    }
+    {
+      const int ids[] = {0,3,2,1,4};
+      reverseInterlaces[SMDSEntity_Pyramid].assign( &ids[0], &ids[0]+5 );
+    }
+    {
+      const int ids[] = {0,3,2,1,4,8,7,6,5,9,12,11,10};
+      reverseInterlaces[SMDSEntity_Quad_Pyramid].assign( &ids[0], &ids[0]+13 );
+    }
+    {
+      const int ids[] = {0,3,2,1,4,7,6,5};
+      reverseInterlaces[SMDSEntity_Hexa].assign( &ids[0], &ids[0]+8 );
+    }
+    {
+      const int ids[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17};
+      reverseInterlaces[SMDSEntity_Quad_Hexa].assign( &ids[0], &ids[0]+20 );
+    }
+    {
+      const int ids[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17, 20,24,23,22,21,25,26};
+      reverseInterlaces[SMDSEntity_TriQuad_Hexa].assign( &ids[0], &ids[0]+27 );
+    }
+    {
+      const int ids[] = {0,2,1,3,5,4};
+      reverseInterlaces[SMDSEntity_Penta].assign( &ids[0], &ids[0]+6 );
+    }
+    {
+      const int ids[] = {0,2,1,3,5,4, 8,7,6,11,10,9,12,14,13};
+      reverseInterlaces[SMDSEntity_Quad_Penta].assign( &ids[0], &ids[0]+15 );
+    }
+    {
+      const int ids[] = {0,5,4,3,2,1,6,11,10,9,8,7};
+      reverseInterlaces[SMDSEntity_Hexagonal_Prism].assign( &ids[0], &ids[0]+12 );
+    }
+  }
+  return reverseInterlaces[smdsType];
+}
+
+//================================================================================
+/*!
+ * \brief Return indices to set nodes of a quadratic 1D or 2D element in interlaced order
+ * Usage: interlacedIDs[i] = smdsIDs[ indices[ i ]]
+ */
+//================================================================================
+
+const std::vector<int>& SMDS_MeshCell::interlacedSmdsOrder(SMDSAbs_EntityType smdsType)
+{
+  static std::vector< std::vector< int > > interlace;
+  if ( interlace.empty() )
+  {
+    interlace.resize( SMDSEntity_Last+1 );
+    {
+      const int ids[] = {0,2,1};
+      interlace[SMDSEntity_Quad_Edge].assign( &ids[0], &ids[0]+3 );
+    }
+    {
+      const int ids[] = {0,3,1,4,2,5};
+      interlace[SMDSEntity_Quad_Triangle].assign( &ids[0], &ids[0]+6 );
+    }
+    {
+      const int ids[] = {0,4,1,5,2,6,3,7,8};
+      interlace[SMDSEntity_Quad_Quadrangle].assign( &ids[0], &ids[0]+8 );
+      interlace[SMDSEntity_BiQuad_Quadrangle].assign( &ids[0], &ids[0]+9 );
+    }
+  }
+  return interlace[smdsType];
+}
+
+//================================================================================
+/*!
+ * \brief Return SMDSAbs_EntityType corresponding to VTKCellType
+ */
+//================================================================================
+
+SMDSAbs_EntityType SMDS_MeshCell::toSmdsType(VTKCellType vtkType)
+{
+  static std::vector< SMDSAbs_EntityType > smdsTypes;
+  if ( smdsTypes.empty() )
+  {
+    smdsTypes.resize( VTK_NUMBER_OF_CELL_TYPES, SMDSEntity_Last );
+    for ( int iSMDS = 0; iSMDS < SMDSEntity_Last; ++iSMDS )
+      smdsTypes[ toVtkType( SMDSAbs_EntityType( iSMDS ))] = SMDSAbs_EntityType( iSMDS );
+  }
+  return smdsTypes[ vtkType ];
+}
+
+//================================================================================
+/*!
+ * \brief Return SMDSAbs_ElementType by SMDSAbs_GeometryType
+ */
+//================================================================================
+
+SMDSAbs_ElementType SMDS_MeshCell::toSmdsType(SMDSAbs_GeometryType geomType)
+{
+  switch ( geomType ) {
+  case SMDSGeom_POINT:     return SMDSAbs_0DElement;
+
+  case SMDSGeom_EDGE:      return SMDSAbs_Edge; 
+
+  case SMDSGeom_TRIANGLE:
+  case SMDSGeom_QUADRANGLE:
+  case SMDSGeom_POLYGON:   return SMDSAbs_Face;
+
+  case SMDSGeom_TETRA:
+  case SMDSGeom_PYRAMID:
+  case SMDSGeom_HEXA:
+  case SMDSGeom_PENTA:
+  case SMDSGeom_HEXAGONAL_PRISM:
+  case SMDSGeom_POLYHEDRA: return SMDSAbs_Volume;
+
+  case SMDSGeom_BALL:      return SMDSAbs_Ball;
+
+  case SMDSGeom_NONE: ;
+  }
+  return SMDSAbs_All;
+}
+
+//================================================================================
+/*!
+ * \brief Return SMDSAbs_ElementType by SMDSAbs_EntityType
+ */
+//================================================================================
+
+SMDSAbs_ElementType SMDS_MeshCell::toSmdsType(SMDSAbs_EntityType entityType)
+{
+  switch ( entityType ) {
+  case SMDSEntity_Node:           return SMDSAbs_Node;
+
+  case SMDSEntity_0D:             return SMDSAbs_0DElement;
+
+  case SMDSEntity_Edge:
+  case SMDSEntity_Quad_Edge:      return SMDSAbs_Edge;
+
+  case SMDSEntity_Triangle:
+  case SMDSEntity_Quad_Triangle:
+  case SMDSEntity_Quadrangle:
+  case SMDSEntity_Quad_Quadrangle:
+  case SMDSEntity_BiQuad_Quadrangle:
+  case SMDSEntity_Polygon:
+  case SMDSEntity_Quad_Polygon:   return SMDSAbs_Face;
+
+  case SMDSEntity_Tetra:
+  case SMDSEntity_Quad_Tetra:
+  case SMDSEntity_Pyramid:
+  case SMDSEntity_Quad_Pyramid:
+  case SMDSEntity_Hexa:
+  case SMDSEntity_Quad_Hexa:
+  case SMDSEntity_TriQuad_Hexa:
+  case SMDSEntity_Penta:
+  case SMDSEntity_Quad_Penta:
+  case SMDSEntity_Hexagonal_Prism:
+  case SMDSEntity_Polyhedra:
+  case SMDSEntity_Quad_Polyhedra: return SMDSAbs_Volume;
+
+  case SMDSEntity_Ball:           return SMDSAbs_Ball;
+
+  case SMDSEntity_Last:;
+  }
+  return SMDSAbs_All;
+}
+
+
+//================================================================================
+/*!
+ * \brief Return indices to transform cell connectivity from VTK to SMDS
+ * Usage: smdsIDs[i] = vtkIDs[ indices[ i ]]
+ */
+//================================================================================
+
+const std::vector<int>& SMDS_MeshCell::fromVtkOrder(SMDSAbs_EntityType smdsType)
+{
+  static std::vector< std::vector<int> > fromVtkInterlaces;
+  if ( fromVtkInterlaces.empty() )
+  {
+    fromVtkInterlaces.resize( SMDSEntity_Last+1 );
+    for ( int iSMDS = 0; iSMDS < SMDSEntity_Last; ++iSMDS )
+    {
+      const std::vector<int> & toVtk = toVtkOrder( SMDSAbs_EntityType( iSMDS ));
+      std::vector<int> &      toSmds = fromVtkInterlaces[ iSMDS ];
+      toSmds.resize( toVtk.size() );
+      for ( size_t i = 0; i < toVtk.size(); ++i )
+        toSmds[ toVtk[i] ] = i;
+    }
+  }
+  return fromVtkInterlaces[ smdsType ];
+}
+
+//================================================================================
+/*!
+ * \brief Return indices to transform cell connectivity from SMDS to VTK
+ * Usage: vtkIDs[i] = smdsIDs[ indices[ i ]]
+ */
+//================================================================================
+
+const std::vector<int>& SMDS_MeshCell::toVtkOrder(VTKCellType vtkType)
+{
+  return toVtkOrder( toSmdsType( vtkType ));
+}
+
+//================================================================================
+/*!
+ * \brief Return indices to transform cell connectivity from VTK to SMDS
+ * Usage: smdsIDs[i] = vtkIDs[ indices[ i ]]
+ */
+//================================================================================
+
+const std::vector<int>& SMDS_MeshCell::fromVtkOrder(VTKCellType vtkType)
+{
+  return fromVtkOrder( toSmdsType( vtkType ));
+}
diff --git a/src/SMDS/SMDS_MeshCell.hxx b/src/SMDS/SMDS_MeshCell.hxx
new file mode 100644 (file)
index 0000000..ca006b5
--- /dev/null
@@ -0,0 +1,72 @@
+// Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+#ifndef _SMDS_MESHCELL_HXX_
+#define _SMDS_MESHCELL_HXX_
+
+#include "SMDS_MeshElement.hxx"
+
+/*!
+ * \brief Base class for all cells
+ */
+
+class SMDS_EXPORT SMDS_MeshCell: public SMDS_MeshElement
+{
+public:
+  SMDS_MeshCell();
+  virtual ~SMDS_MeshCell();
+
+  virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)= 0;
+  virtual bool vtkOrder(const SMDS_MeshNode* nodes[], const int nbNodes) {return true; }
+
+  static VTKCellType         toVtkType (SMDSAbs_EntityType vtkType);
+  static SMDSAbs_EntityType  toSmdsType(VTKCellType vtkType);
+  static SMDSAbs_ElementType toSmdsType(SMDSAbs_GeometryType geomType);
+  static SMDSAbs_ElementType toSmdsType(SMDSAbs_EntityType entityType);
+
+  static const std::vector<int>& toVtkOrder(VTKCellType vtkType);
+  static const std::vector<int>& toVtkOrder(SMDSAbs_EntityType smdsType);
+  static const std::vector<int>& fromVtkOrder(VTKCellType vtkType);
+  static const std::vector<int>& fromVtkOrder(SMDSAbs_EntityType smdsType);
+
+  static const std::vector<int>& reverseSmdsOrder(SMDSAbs_EntityType smdsType);
+  static const std::vector<int>& interlacedSmdsOrder(SMDSAbs_EntityType smdsType);
+
+  template< class VECT >
+    static void applyInterlace( const std::vector<int>& interlace, VECT & data)
+  {
+    if ( interlace.empty() ) return;
+    VECT tmpData( data.size() );
+    for ( size_t i = 0; i < data.size(); ++i )
+      tmpData[i] = data[ interlace[i] ];
+    data.swap( tmpData );
+  }
+
+  static int nbCells;
+
+protected:
+  inline void exchange(const SMDS_MeshNode* nodes[],int a, int b)
+  {
+    const SMDS_MeshNode* noda = nodes[a];
+    nodes[a] = nodes[b];
+    nodes[b] = noda;
+  }
+};
+
+#endif
index 9d17cd439bd043c60d9dd89a88fdfcc21f419d72..8590618429880946df7f00fbf4efd90931f6db48 100644 (file)
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  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 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.
 //
-//  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
 //
-//  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.com
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-//  SMESH SMDS : implementaion of Salome mesh data structure
-//  File   : SMDS_MeshEdge.cxx
-//  Author : Jean-Michel BOULCOURT
-//  Module : SMESH
-//
-#ifdef _MSC_VER
-#pragma warning(disable:4786)
-#endif
 
 #include "SMDS_MeshEdge.hxx"
-#include "SMDS_IteratorOfElements.hxx"
-#include "SMDS_MeshNode.hxx"
-
-using namespace std;
-
-//=======================================================================
-//function : SMDS_MeshEdge
-//purpose  : 
-//=======================================================================
-
-SMDS_MeshEdge::SMDS_MeshEdge(const SMDS_MeshNode * node1,
-                             const SMDS_MeshNode * node2)
-{      
-       myNodes[0]=node1;
-       myNodes[1]=node2;
-}
-
-//=======================================================================
-//function : Print
-//purpose  : 
-//=======================================================================
-
-void SMDS_MeshEdge::Print(ostream & OS) const
-{
-       OS << "edge <" << GetID() << "> : (" << myNodes[0] << " , " << myNodes[1] <<
-               ") " << endl;
-}
-
-int SMDS_MeshEdge::NbNodes() const
-{
-       return 2;
-}
-
-int SMDS_MeshEdge::NbEdges() const
-{
-       return 1;
-}
 
 SMDSAbs_ElementType SMDS_MeshEdge::GetType() const
 {
-       return SMDSAbs_Edge;
+        return SMDSAbs_Edge;
 }
 
-class SMDS_MeshEdge_MyNodeIterator:public SMDS_ElemIterator
+vtkIdType SMDS_MeshEdge::GetVtkType() const
 {
-  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
-{
-  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)
-{
-       int id11=e1.myNodes[0]->GetID();
-       int id21=e2.myNodes[0]->GetID();
-       int id12=e1.myNodes[1]->GetID();
-       int id22=e2.myNodes[1]->GetID();
-       int tmp;
-
-       if(id11>=id12) 
-       {
-               tmp=id11;
-               id11=id12;
-               id12=tmp;       
-       }
-       if(id21>=id22) 
-       {
-               tmp=id21;
-               id21=id22;
-               id22=tmp;       
-       }
-
-       if(id11<id21) return true;
-       else if(id11==id21) return (id21<id22);
-       else return false;
+  return VTK_POLY_VERTEX; // --- must be reimplemented in derived classes
 }
-
-/*!
- * \brief Return node by its index
- * \param ind - node index
- * \retval const SMDS_MeshNode* - the node
- * 
- * Index is wrapped if it is out of a valid range
- */
-const SMDS_MeshNode* SMDS_MeshEdge::GetNode(const int ind) const
-{
-  return myNodes[ WrappedIndex( ind )];
-}
-
-//=======================================================================
-//function : ChangeNodes
-//purpose  : 
-//=======================================================================
-
-bool SMDS_MeshEdge::ChangeNodes(const SMDS_MeshNode * node1,
-                                const SMDS_MeshNode * node2)
-{
-  myNodes[0]=node1;
-  myNodes[1]=node2;
-  return true;
-}
-
index b8a6c28ac67ef34511c5cb2b0a3aedb165f7bb19..63ae2f071ef62182e90f49c40288bf7787ab09e5 100644 (file)
@@ -1,24 +1,22 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  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 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.
 //
-//  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
 //
-//  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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_MeshEdge.hxx
 //  Module : SMESH
 
 #include "SMESH_SMDS.hxx"
 
-#include "SMDS_MeshElement.hxx"
-#include <iostream>
+#include "SMDS_MeshCell.hxx"
 
-class SMDS_EXPORT SMDS_MeshEdge:public SMDS_MeshElement
+class SMDS_EXPORT SMDS_MeshEdge: public SMDS_MeshCell
 {
-
-  public:
-       SMDS_MeshEdge(const SMDS_MeshNode * node1,
-                      const SMDS_MeshNode * node2);
-        bool ChangeNodes(const SMDS_MeshNode * node1,
-                         const SMDS_MeshNode * node2);
-       void Print(std::ostream & OS) const;
-
-       SMDSAbs_ElementType GetType() const;
-       int NbNodes() const;
-       int NbEdges() const;
-       friend bool operator<(const SMDS_MeshEdge& e1, const SMDS_MeshEdge& e2);
-
-  /*!
-   * \brief Return node by its index
-    * \param ind - node index
-    * \retval const SMDS_MeshNode* - the node
-   * 
-   * Index is wrapped if it is out of a valid range
-   */
-  virtual const SMDS_MeshNode* GetNode(const int ind) const;
-
-  protected:
-       SMDS_ElemIteratorPtr
-               elementsIterator(SMDSAbs_ElementType type) const;
-
-  protected:
-       const SMDS_MeshNode* myNodes[3];
-
+        
+ public:
+  virtual SMDSAbs_ElementType  GetType() const;
+  virtual vtkIdType            GetVtkType() const;
+  virtual SMDSAbs_GeometryType GetGeomType() const { return SMDSGeom_EDGE; }
 };
 #endif
index 646f92d10cf6de7901a1d3c1dabb7f067c8d6e9a..1f422d3829b5e50704c0c30fb5d9f8d71ee36d57 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //
 #ifdef _MSC_VER
 
 using namespace std;
 
-SMDS_MeshElement::SMDS_MeshElement(int ID):myID(ID)
+SMDS_MeshElement::SMDS_MeshElement(int ID)
+{
+  init(ID);
+}
+
+SMDS_MeshElement::SMDS_MeshElement(int id, ShortType meshId, LongType shapeId)
+{
+  init(id, meshId, shapeId);
+}
+
+void SMDS_MeshElement::init(int id, ShortType meshId, LongType shapeId )
 {
+  myID = id;
+  myMeshId = meshId;
+  myShapeId = shapeId;
+  myIdInShape = -1;
 }
 
 void SMDS_MeshElement::Print(ostream & OS) const
 {
-       OS << "dump of mesh element" << endl;
+        OS << "dump of mesh element" << endl;
 }
 
 ostream & operator <<(ostream & OS, const SMDS_MeshElement * ME)
 {
-       ME->Print(OS);
-       return OS;
+        ME->Print(OS);
+        return OS;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -55,7 +70,7 @@ ostream & operator <<(ostream & OS, const SMDS_MeshElement * ME)
 ///////////////////////////////////////////////////////////////////////////////
 SMDS_ElemIteratorPtr SMDS_MeshElement::nodesIterator() const
 {
-       return elementsIterator(SMDSAbs_Node);
+        return elementsIterator(SMDSAbs_Node);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -64,7 +79,7 @@ SMDS_ElemIteratorPtr SMDS_MeshElement::nodesIterator() const
 ///////////////////////////////////////////////////////////////////////////////
 SMDS_ElemIteratorPtr SMDS_MeshElement::edgesIterator() const
 {
-       return elementsIterator(SMDSAbs_Edge);
+        return elementsIterator(SMDSAbs_Edge);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -73,7 +88,7 @@ SMDS_ElemIteratorPtr SMDS_MeshElement::edgesIterator() const
 ///////////////////////////////////////////////////////////////////////////////
 SMDS_ElemIteratorPtr SMDS_MeshElement::facesIterator() const
 {
-       return elementsIterator(SMDSAbs_Face);
+        return elementsIterator(SMDSAbs_Face);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -81,14 +96,14 @@ SMDS_ElemIteratorPtr SMDS_MeshElement::facesIterator() const
 ///////////////////////////////////////////////////////////////////////////////
 int SMDS_MeshElement::NbNodes() const
 {
-       int nbnodes=0;
-       SMDS_ElemIteratorPtr it=nodesIterator();
-       while(it->more())
-       {
-               it->next();
-               nbnodes++;
-       }
-       return nbnodes;
+        int nbnodes=0;
+        SMDS_ElemIteratorPtr it=nodesIterator();
+        while(it->more())
+        {
+                it->next();
+                nbnodes++;
+        }
+        return nbnodes;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -96,14 +111,14 @@ int SMDS_MeshElement::NbNodes() const
 ///////////////////////////////////////////////////////////////////////////////
 int SMDS_MeshElement::NbEdges() const
 {
-       int nbedges=0;
-       SMDS_ElemIteratorPtr it=edgesIterator();
-       while(it->more())
-       {
-               it->next();
-               nbedges++;
-       }
-       return nbedges;
+        int nbedges=0;
+        SMDS_ElemIteratorPtr it=edgesIterator();
+        while(it->more())
+        {
+                it->next();
+                nbedges++;
+        }
+        return nbedges;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -111,14 +126,14 @@ int SMDS_MeshElement::NbEdges() const
 ///////////////////////////////////////////////////////////////////////////////
 int SMDS_MeshElement::NbFaces() const
 {
-       int nbfaces=0;
-       SMDS_ElemIteratorPtr it=facesIterator();
-       while(it->more())
-       {
-               it->next();
-               nbfaces++;
-       }
-       return nbfaces;
+        int nbfaces=0;
+        SMDS_ElemIteratorPtr it=facesIterator();
+        while(it->more())
+        {
+                it->next();
+                nbfaces++;
+        }
+        return nbfaces;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -142,56 +157,63 @@ class SMDS_MeshElement_MyIterator:public SMDS_ElemIterator
   const SMDS_MeshElement* next()
   {
     myMore=false;
-    return myElement;  
-  }    
+    return myElement;   
+  }     
 };
+
 SMDS_ElemIteratorPtr SMDS_MeshElement::
-       elementsIterator(SMDSAbs_ElementType type) const
+        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 */
-       
-       if(type==GetType())
+        /** @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 */
+        
+        if(type==GetType())
           return SMDS_ElemIteratorPtr(new SMDS_MeshElement_MyIterator(this));
-       else 
-       {
+        else 
+        {
           MESSAGE("Iterator not implemented");
           return SMDS_ElemIteratorPtr((SMDS_ElemIterator*)NULL);
-       }
+        }
 }
 
-///////////////////////////////////////////////////////////////////////////////
-///Return the ID of the element
-///////////////////////////////////////////////////////////////////////////////
-int SMDS_MeshElement::GetID() const
+//! virtual, redefined in vtkEdge, vtkFace and vtkVolume classes
+SMDS_ElemIteratorPtr SMDS_MeshElement::nodesIteratorToUNV() const
 {
-       return myID;
+  MESSAGE("Iterator not implemented");
+  return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL);
+}
+
+//! virtual, redefined in vtkEdge, vtkFace and vtkVolume classes
+SMDS_ElemIteratorPtr SMDS_MeshElement::interlacedNodesElemIterator() const
+{
+  MESSAGE("Iterator not implemented");
+  return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL);
 }
 
 bool operator<(const SMDS_MeshElement& e1, const SMDS_MeshElement& e2)
 {
-       if(e1.GetType()!=e2.GetType()) return false;
-       switch(e1.GetType())
-       {
-       case SMDSAbs_Node:
-               return static_cast<const SMDS_MeshNode &>(e1) <
-                       static_cast<const SMDS_MeshNode &>(e2);
+        if(e1.GetType()!=e2.GetType()) return false;
+        switch(e1.GetType())
+        {
+        case SMDSAbs_Node:
+                return static_cast<const SMDS_MeshNode &>(e1) <
+                        static_cast<const SMDS_MeshNode &>(e2);
 
-       case SMDSAbs_Edge:
-               return static_cast<const SMDS_MeshEdge &>(e1) <
-                       static_cast<const SMDS_MeshEdge &>(e2);
+        case SMDSAbs_Edge:
+                return static_cast<const SMDS_MeshEdge &>(e1) <
+                        static_cast<const SMDS_MeshEdge &>(e2);
 
-       case SMDSAbs_Face:
-               return static_cast<const SMDS_MeshFace &>(e1) <
-                       static_cast<const SMDS_MeshFace &>(e2);
+        case SMDSAbs_Face:
+                return static_cast<const SMDS_MeshFace &>(e1) <
+                        static_cast<const SMDS_MeshFace &>(e2);
 
-       case SMDSAbs_Volume:
-               return static_cast<const SMDS_MeshVolume &>(e1) <
-                       static_cast<const SMDS_MeshVolume &>(e2);
+        case SMDSAbs_Volume:
+                return static_cast<const SMDS_MeshVolume &>(e1) <
+                        static_cast<const SMDS_MeshVolume &>(e2);
 
-       default : MESSAGE("Internal Error");
-       }
+        default : MESSAGE("Internal Error");
+        }
         return false;
 }
 
@@ -202,12 +224,13 @@ bool SMDS_MeshElement::IsValidIndex(const int ind) const
 
 const SMDS_MeshNode* SMDS_MeshElement::GetNode(const int ind) const
 {
-  SMDS_ElemIteratorPtr it = nodesIterator();
-  int i = 0, index = WrappedIndex( ind );
-  while ( index != i++ )
-    it->next();
-  if ( it->more() )
-    return static_cast<const SMDS_MeshNode*> (it->next());
+  if ( ind >= 0 ) {
+    SMDS_ElemIteratorPtr it = nodesIterator();
+    for ( int i = 0; i < ind; ++i )
+      it->next();
+    if ( it->more() )
+      return static_cast<const SMDS_MeshNode*> (it->next());
+  }
   return 0;
 }
 
@@ -221,6 +244,17 @@ bool SMDS_MeshElement::IsMediumNode(const SMDS_MeshNode* node) const
   return false;
 }
 
+//================================================================================
+/*!
+ * \brief Return number of nodes excluding medium ones
+ */
+//================================================================================
+
+int SMDS_MeshElement::NbCornerNodes() const
+{
+  return IsQuadratic() ? NbNodes() - NbEdges() : NbNodes();
+}
+
 //================================================================================
   /*!
    * \brief Check if a node belongs to the element
index 2716456d34cfcf70f4a6057412c176be096f5c4e..918ebb668efe33ac67a27d406d4447f14296d1f7 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_MeshElement.hxx
 //  Module : SMESH
 #define _SMDS_MeshElement_HeaderFile
 
 #include "SMESH_SMDS.hxx"
-       
+        
 #include "SMDSAbs_ElementType.hxx"
 #include "SMDS_MeshObject.hxx"
 #include "SMDS_ElemIterator.hxx"
 #include "SMDS_MeshElementIDFactory.hxx"
+#include "SMDS_StdIterator.hxx"
 
 #include <vector>
 #include <iostream>
 
+#include <vtkType.h>
+#include <vtkCellType.h>
+
+//typedef unsigned short UShortType;
+typedef short ShortType;
+typedef int   LongType;
+
 class SMDS_MeshNode;
 class SMDS_MeshEdge;
-class SMDS_MeshFace;   
+class SMDS_MeshFace;
+class SMDS_Mesh;
+
+// ============================================================
+/*!
+ * \brief Base class for elements
+ */
+// ============================================================
+
 
-///////////////////////////////////////////////////////////////////////////////
-/// Base class for elements
-///////////////////////////////////////////////////////////////////////////////
 class SMDS_EXPORT SMDS_MeshElement:public SMDS_MeshObject
 {
 public:
@@ -51,25 +65,47 @@ public:
   SMDS_ElemIteratorPtr edgesIterator() const;
   SMDS_ElemIteratorPtr facesIterator() const;
   virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const;
+  virtual SMDS_ElemIteratorPtr nodesIteratorToUNV() const;
+  virtual SMDS_ElemIteratorPtr interlacedNodesElemIterator() const;
+
+  // std-like iteration on nodes
+  typedef SMDS_StdIterator< const SMDS_MeshNode*, SMDS_ElemIteratorPtr > iterator;
+  iterator begin_nodes() const { return iterator( nodesIterator() ); }
+  iterator end_nodes()   const { return iterator(); }
 
   virtual int NbNodes() const;
   virtual int NbEdges() const;
   virtual int NbFaces() const;
-  int GetID() const;
+  inline int GetID() const { return myID; };
 
   ///Return the type of the current element
   virtual SMDSAbs_ElementType GetType() const = 0;
-  virtual bool IsPoly() const { return false; };
+  virtual SMDSAbs_EntityType GetEntityType() const = 0;
+  virtual SMDSAbs_GeometryType GetGeomType() const = 0;
+  virtual vtkIdType GetVtkType() const = 0;
+  virtual bool IsPoly() const { return false; }
   virtual bool IsQuadratic() const;
 
   virtual bool IsMediumNode(const SMDS_MeshNode* node) const;
+  virtual int  NbCornerNodes() const;
 
   friend SMDS_EXPORT std::ostream & operator <<(std::ostream & OS, const SMDS_MeshElement *);
-  friend SMDS_EXPORT bool SMDS_MeshElementIDFactory::BindID(int ID,SMDS_MeshElement*elem);
+  friend SMDS_EXPORT bool SMDS_MeshElementIDFactory::BindID(int ID,SMDS_MeshElement* elem);
+  friend class SMDS_Mesh;
+  friend class SMESHDS_Mesh;
+  friend class SMESHDS_SubMesh;
+  friend class SMDS_MeshElementIDFactory;
 
   // ===========================
   //  Access to nodes by index
   // ===========================
+  /*!
+   * \brief Return node by its index
+    * \param ind - node index
+    * \retval const SMDS_MeshNode* - the node
+   */
+  virtual const SMDS_MeshNode* GetNode(const int ind) const;
+
   /*!
    * \brief Return node by its index
     * \param ind - node index
@@ -77,7 +113,7 @@ public:
    * 
    * Index is wrapped if it is out of a valid range
    */
-  virtual const SMDS_MeshNode* GetNode(const int ind) const;
+  const SMDS_MeshNode* GetNodeWrap(const int ind) const { return GetNode( WrappedIndex( ind )); }
 
   /*!
    * \brief Return true if index of node is valid (0 <= ind < NbNodes())
@@ -104,12 +140,65 @@ public:
    */
   int GetNodeIndex( const SMDS_MeshNode* node ) const;
 
+  inline ShortType getMeshId()  const { return myMeshId; }
+  inline LongType  getshapeId() const { return myShapeId; }
+  inline int getIdInShape()     const { return myIdInShape; }
+  inline int getVtkId()         const { return myVtkID; }
+
+  /*!
+   * \brief Filters of elements, to be used with SMDS_SetIterator
+   */
+  struct TypeFilter
+  {
+    SMDSAbs_ElementType _type;
+    TypeFilter( SMDSAbs_ElementType t = SMDSAbs_NbElementTypes ):_type(t) {}
+    bool operator()(const SMDS_MeshElement* e) const { return e && e->GetType() == _type; }
+  };
+  struct EntityFilter
+  {
+    SMDSAbs_EntityType _type;
+    EntityFilter( SMDSAbs_EntityType t = SMDSEntity_Last ):_type(t) {}
+    bool operator()(const SMDS_MeshElement* e) const { return e && e->GetEntityType() == _type; }
+  };
+  struct GeomFilter
+  {
+    SMDSAbs_GeometryType _type;
+    GeomFilter( SMDSAbs_GeometryType t = SMDSGeom_NONE ):_type(t) {}
+    bool operator()(const SMDS_MeshElement* e) const { return e && e->GetGeomType() == _type; }
+  };
+
 protected:
+  inline void setId(int id) {myID = id; }
+  inline void setShapeId(LongType shapeId) {myShapeId = shapeId; }
+  inline void setIdInShape(int id) { myIdInShape = id; }
+  inline void setVtkId(int vtkId) { myVtkID = vtkId; }
   SMDS_MeshElement(int ID=-1);
+  SMDS_MeshElement(int id, ShortType meshId, LongType shapeId = 0);
+  virtual void init(int id = -1, ShortType meshId = -1, LongType shapeId = 0);
   virtual void Print(std::ostream & OS) const;
 
-private:
+  //! Element index in vector SMDS_Mesh::myNodes or SMDS_Mesh::myCells
   int myID;
+  //! index in vtkUnstructuredGrid
+  int myVtkID;
+  //! SMDS_Mesh identification in SMESH
+  ShortType myMeshId;
+  //! SubShape and SubMesh identification in SMESHDS
+  LongType myShapeId;
+  //! Element index in SMESHDS_SubMesh vector
+  int myIdInShape;
+};
+
+
+// ============================================================
+/*!
+ * \brief Comparator of elements by ID for usage in std containers
+ */
+// ============================================================
+
+struct TIDCompare {
+  bool operator () (const SMDS_MeshElement* e1, const SMDS_MeshElement* e2) const
+  { return e1->GetID() < e2->GetID(); }
 };
 
 #endif
index 7ecfba5b025d022cb5534b882250deaf280d0c09..204d7215d41c3abd2ece2a97717195b4f31c6acc 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_MeshElementIDFactory.cxx
 //  Author : Jean-Michel BOULCOURT
 
 #include "SMDS_MeshElementIDFactory.hxx"
 #include "SMDS_MeshElement.hxx"
+#include "SMDS_Mesh.hxx"
+
+#include "utilities.h"
+
+#include "SMDS_UnstructuredGrid.hxx"
+#include <vtkCellType.h>
+
+#include <climits>
 
 using namespace std;
 
@@ -38,23 +47,46 @@ using namespace std;
 //purpose  : 
 //=======================================================================
 SMDS_MeshElementIDFactory::SMDS_MeshElementIDFactory():
-  SMDS_MeshIDFactory(),
-  myMin(0), myMax(0)
+  SMDS_MeshNodeIDFactory()
+{
+}
+
+int SMDS_MeshElementIDFactory::SetInVtkGrid(SMDS_MeshElement * elem)
 {
+   // --- retrieve nodes ID
+
+  SMDS_MeshCell *cell = dynamic_cast<SMDS_MeshCell*>(elem);
+  assert(cell);
+  vector<vtkIdType> nodeIds;
+  SMDS_ElemIteratorPtr it = elem->nodesIterator();
+  while(it->more())
+  {
+      int nodeId = (static_cast<const SMDS_MeshNode*>(it->next()))->getVtkId();
+      MESSAGE("   node in cell " << cell->getVtkId() << " : " << nodeId)
+      nodeIds.push_back(nodeId);
+  }
+
+  // --- insert cell in vtkUnstructuredGrid
+
+  vtkUnstructuredGrid * grid = myMesh->getGrid();
+  //int locType = elem->GetType();
+  int typ = VTK_VERTEX;//GetVtkCellType(locType);
+  int cellId = grid->InsertNextLinkedCell(typ, nodeIds.size(), &nodeIds[0]);
+  cell->setVtkId(cellId); 
+  //MESSAGE("SMDS_MeshElementIDFactory::SetInVtkGrid " << cellId);
+  return cellId;
 }
 
 //=======================================================================
 //function : BindID
 //purpose  : 
 //=======================================================================
+
 bool SMDS_MeshElementIDFactory::BindID(int ID, SMDS_MeshElement * elem)
 {
-  if (myIDElements.IsBound(ID))
-    return false;
-  myIDElements.Bind(ID,elem);
-  elem->myID=ID;
-  updateMinMax (ID);
-  return true;
+  MESSAGE("SMDS_MeshElementIDFactory::BindID " << ID);
+  SetInVtkGrid(elem);
+  return myMesh->registerElement(ID, elem);
 }
 
 //=======================================================================
@@ -63,22 +95,23 @@ bool SMDS_MeshElementIDFactory::BindID(int ID, SMDS_MeshElement * elem)
 //=======================================================================
 SMDS_MeshElement* SMDS_MeshElementIDFactory::MeshElement(int ID)
 {
-  if (!myIDElements.IsBound(ID))
+  if ((ID<1) || (ID>=myMesh->myCells.size()))
     return NULL;
-  return myIDElements.Find(ID);
+  const SMDS_MeshElement* elem = GetMesh()->FindElement(ID);
+  return (SMDS_MeshElement*)(elem);
 }
 
-
 //=======================================================================
 //function : GetFreeID
 //purpose  : 
 //=======================================================================
+
 int SMDS_MeshElementIDFactory::GetFreeID()
 {
   int ID;
   do {
     ID = SMDS_MeshIDFactory::GetFreeID();
-  } while (myIDElements.IsBound(ID));
+  } while ( MeshElement( ID ));
   return ID;
 }
 
@@ -86,38 +119,25 @@ int SMDS_MeshElementIDFactory::GetFreeID()
 //function : ReleaseID
 //purpose  : 
 //=======================================================================
-void SMDS_MeshElementIDFactory::ReleaseID(const int ID)
+void SMDS_MeshElementIDFactory::ReleaseID(int ID, int vtkId)
 {
-  myIDElements.UnBind(ID);
+  if (ID < 1) // TODO check case ID == O
+    {
+      MESSAGE("~~~~~~~~~~~~~~ SMDS_MeshElementIDFactory::ReleaseID ID = " << ID);
+      return;
+    }
+  //MESSAGE("~~~~~~~~~~~~~~ SMDS_MeshElementIDFactory::ReleaseID smdsId vtkId " << ID << " " << vtkId);
+  if (vtkId >= 0)
+    {
+      assert(vtkId < myMesh->myCellIdVtkToSmds.size());
+      myMesh->myCellIdVtkToSmds[vtkId] = -1;
+      myMesh->setMyModified();
+    }
   SMDS_MeshIDFactory::ReleaseID(ID);
   if (ID == myMax)
     myMax = 0;
   if (ID == myMin)
-    myMin = 0;
-}
-
-//=======================================================================
-//function : GetMaxID
-//purpose  : 
-//=======================================================================
-
-int SMDS_MeshElementIDFactory::GetMaxID() const
-{
-  if (myMax == 0)
-    updateMinMax();
-  return myMax;
-}
-
-//=======================================================================
-//function : GetMinID
-//purpose  : 
-//=======================================================================
-
-int SMDS_MeshElementIDFactory::GetMinID() const
-{
-  if (myMin == 0)
-    updateMinMax();
-  return myMin;
+    myMax = 0;
 }
 
 //=======================================================================
@@ -127,12 +147,20 @@ int SMDS_MeshElementIDFactory::GetMinID() const
 
 void SMDS_MeshElementIDFactory::updateMinMax() const
 {
-  myMin = IntegerLast();
+  myMin = INT_MAX;
   myMax = 0;
-  SMDS_IdElementMap::Iterator it(myIDElements);
-  for (; it.More(); it.Next())
-    updateMinMax (it.Key());
-  if (myMin == IntegerLast())
+  for (int i = 0; i < myMesh->myCells.size(); i++)
+    {
+      if (myMesh->myCells[i])
+        {
+          int id = myMesh->myCells[i]->GetID();
+          if (id > myMax)
+            myMax = id;
+          if (id < myMin)
+            myMin = id;
+        }
+    }
+  if (myMin == INT_MAX)
     myMin = 0;
 }
 
@@ -141,35 +169,15 @@ void SMDS_MeshElementIDFactory::updateMinMax() const
 //purpose  : Return an iterator on elements of the factory
 //=======================================================================
 
-class SMDS_Fact_MyElemIterator:public SMDS_ElemIterator
-{
-  SMDS_IdElementMap::Iterator myIterator;
- public:
-  SMDS_Fact_MyElemIterator(const SMDS_IdElementMap& s):myIterator(s)
-  {}
-
-  bool more()
-  {
-    return myIterator.More() != Standard_False;
-  }
-
-  const SMDS_MeshElement* next()
-  {
-    const SMDS_MeshElement* current = myIterator.Value();
-    myIterator.Next();
-    return current;
-  }
-};
-
 SMDS_ElemIteratorPtr SMDS_MeshElementIDFactory::elementsIterator() const
 {
-  return SMDS_ElemIteratorPtr
-    (new SMDS_Fact_MyElemIterator(myIDElements));
+    return myMesh->elementsIterator(SMDSAbs_All);
 }
 
 void SMDS_MeshElementIDFactory::Clear()
 {
-  myIDElements.Clear();
+  //myMesh->myCellIdSmdsToVtk.clear();
+  myMesh->myCellIdVtkToSmds.clear();
   myMin = myMax = 0;
   SMDS_MeshIDFactory::Clear();
 }
index a574def92ad12fbdc208d601b64ab5663c4ecbf0..793ff0b323a6f47a76c6fdc3e50258f4976184f4 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_MeshElementIDFactory.hxx
 //  Module : SMESH
 
 #include "SMESH_SMDS.hxx"
 
-#include "SMDS_MeshIDFactory.hxx"
-#include "SMDS_ElemIterator.hxx"
+#include "SMDS_MeshNodeIDFactory.hxx"
 
-#include <NCollection_DataMap.hxx>
+#include <vector>
 
 class SMDS_MeshElement;
+class SMDS_Mesh;
 
-typedef NCollection_DataMap<int, SMDS_MeshElement *> SMDS_IdElementMap;
-
-class SMDS_EXPORT SMDS_MeshElementIDFactory:public SMDS_MeshIDFactory
+class SMDS_EXPORT SMDS_MeshElementIDFactory:public SMDS_MeshNodeIDFactory
 {
 public:
+  friend class SMDS_Mesh;
+  
   SMDS_MeshElementIDFactory();
   bool BindID(int ID, SMDS_MeshElement * elem);
+  int SetInVtkGrid(SMDS_MeshElement * elem);
   SMDS_MeshElement * MeshElement(int ID);
   virtual int GetFreeID();
-  virtual void ReleaseID(int ID);
-  int GetMaxID() const;
-  int GetMinID() const;
+  virtual void ReleaseID(int ID, int vtkId = -1);
   SMDS_ElemIteratorPtr elementsIterator() const;
   virtual void Clear();
-private:
+
+protected:
   void updateMinMax() const;
   void updateMinMax(int id) const
   {
@@ -57,9 +58,6 @@ private:
     if (id < myMin) myMin = id;
   }
 
-  SMDS_IdElementMap myIDElements;
-  mutable int myMin, myMax;
-
 };
 
 #endif
index a4a19f03f43d79e4ace3c76bd8e4780f47aa84eb..a3e4cf5212df70fb74e323e130943c5f4121e0ee 100644 (file)
@@ -1,29 +1,35 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //
 #include "SMDS_MeshFace.hxx"
 
 SMDSAbs_ElementType SMDS_MeshFace::GetType() const
 {
-       return SMDSAbs_Face;
+        return SMDSAbs_Face;
+}
+
+vtkIdType SMDS_MeshFace::GetVtkType() const
+{
+  return VTK_POLY_LINE;  // --- must be reimplemented in derived classes
 }
index a633e4ecf0f89a8cfd1153aecefe8f6dc02747ac..15e06572a3184efe9d3bc8f42bdf7eb2f6a9d0de 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_MeshFace.hxx
 //  Module : SMESH
 
 #include "SMESH_SMDS.hxx"
 
-#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshCell.hxx"
 
-class SMDS_EXPORT SMDS_MeshFace:public SMDS_MeshElement
+class SMDS_EXPORT SMDS_MeshFace:public SMDS_MeshCell
 {
   public:
-       SMDSAbs_ElementType GetType() const;
+        SMDSAbs_ElementType GetType() const;
+        virtual vtkIdType GetVtkType() const;
 };
 
 #endif
index 67c1df42616525e0e5abb2eb4412faf75ecfef33..b81ffe55a4dcaf614a0be982932c51e61fae2bfc 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_MeshGroup.cxx
 //  Author : Jean-Michel BOULCOURT
@@ -40,7 +41,7 @@ using namespace std;
 
 SMDS_MeshGroup::SMDS_MeshGroup(const SMDS_Mesh * theMesh,
                                const SMDSAbs_ElementType theType)
-       :myMesh(theMesh),myType(theType), myParent(NULL)
+  :myMesh(theMesh),myType(theType), myParent(NULL), myTic(0)
 {
 }
 
@@ -51,7 +52,7 @@ SMDS_MeshGroup::SMDS_MeshGroup(const SMDS_Mesh * theMesh,
 
 SMDS_MeshGroup::SMDS_MeshGroup(SMDS_MeshGroup * theParent,
                                const SMDSAbs_ElementType theType)
-       :myMesh(theParent->myMesh),myType(theType), myParent(theParent)
+        :myMesh(theParent->myMesh),myType(theType), myParent(theParent)
 {
 }
 
@@ -63,9 +64,9 @@ SMDS_MeshGroup::SMDS_MeshGroup(SMDS_MeshGroup * theParent,
 const SMDS_MeshGroup *SMDS_MeshGroup::AddSubGroup
                 (const SMDSAbs_ElementType theType)
 {
-       const SMDS_MeshGroup * subgroup = new SMDS_MeshGroup(this,theType);
-       myChildren.insert(myChildren.end(),subgroup);
-       return subgroup;
+        const SMDS_MeshGroup * subgroup = new SMDS_MeshGroup(this,theType);
+        myChildren.insert(myChildren.end(),subgroup);
+        return subgroup;
 }
 
 //=======================================================================
@@ -75,19 +76,19 @@ const SMDS_MeshGroup *SMDS_MeshGroup::AddSubGroup
 
 bool SMDS_MeshGroup::RemoveSubGroup(const SMDS_MeshGroup * theGroup)
 {
-       bool found = false;     
-       list<const SMDS_MeshGroup*>::iterator itgroup;
-       for(itgroup=myChildren.begin(); itgroup!=myChildren.end(); itgroup++)
-       {
-               const SMDS_MeshGroup* subgroup=*itgroup;
-               if (subgroup == theGroup)
-               {
-                       found = true;
-                       myChildren.erase(itgroup);
-               }
-       }
-
-       return found;
+        bool found = false;     
+        list<const SMDS_MeshGroup*>::iterator itgroup;
+        for(itgroup=myChildren.begin(); itgroup!=myChildren.end(); itgroup++)
+        {
+                const SMDS_MeshGroup* subgroup=*itgroup;
+                if (subgroup == theGroup)
+                {
+                        found = true;
+                        myChildren.erase(itgroup);
+                }
+        }
+
+        return found;
 }
 
 //=======================================================================
@@ -97,12 +98,12 @@ bool SMDS_MeshGroup::RemoveSubGroup(const SMDS_MeshGroup * theGroup)
 
 bool SMDS_MeshGroup::RemoveFromParent()
 {
-       
-       if (myParent==NULL) return false;
-       else
-       {
-               return (myParent->RemoveSubGroup(this));
-       }
+        
+        if (myParent==NULL) return false;
+        else
+        {
+                return (myParent->RemoveSubGroup(this));
+        }
 }
 //=======================================================================
 //function : Clear
@@ -111,8 +112,9 @@ bool SMDS_MeshGroup::RemoveFromParent()
 
 void SMDS_MeshGroup::Clear()
 {
-       myElements.clear();
-       myType = SMDSAbs_All;
+  myElements.clear();
+  myType = SMDSAbs_All;
+  ++myTic;
 }
 
 //=======================================================================
@@ -122,14 +124,15 @@ void SMDS_MeshGroup::Clear()
 
 void SMDS_MeshGroup::Add(const SMDS_MeshElement * theElem)
 {
-       // the type of the group is determined by the first element added
-       if (myElements.empty()) myType = theElem->GetType();
-       else if (theElem->GetType() != myType) {
-         MESSAGE("SMDS_MeshGroup::Add : Type Mismatch "<<theElem->GetType()<<"!="<<myType);
-         return;
-       }
-       
-       myElements.insert(theElem);
+  // the type of the group is determined by the first element added
+  if (myElements.empty()) myType = theElem->GetType();
+  else if (theElem->GetType() != myType) {
+    MESSAGE("SMDS_MeshGroup::Add : Type Mismatch "<<theElem->GetType()<<"!="<<myType);
+    return;
+  }
+        
+  myElements.insert(myElements.end(), theElem);
+  ++myTic;
 }
 
 //=======================================================================
@@ -139,11 +142,11 @@ void SMDS_MeshGroup::Add(const SMDS_MeshElement * theElem)
 
 bool SMDS_MeshGroup::Remove(const SMDS_MeshElement * theElem)
 {
-  std::set<const SMDS_MeshElement *>::iterator found
-    = myElements.find(theElem);
+  set<const SMDS_MeshElement *>::iterator found = myElements.find(theElem);
   if ( found != myElements.end() ) {
     myElements.erase(found);
     if (myElements.empty()) myType = SMDSAbs_All;
+    ++myTic;
     return true;
   }
   return false;
@@ -156,7 +159,7 @@ bool SMDS_MeshGroup::Remove(const SMDS_MeshElement * theElem)
 
 bool SMDS_MeshGroup::Contains(const SMDS_MeshElement * theElem) const
 {
-       return myElements.find(theElem)!=myElements.end();
+        return myElements.find(theElem)!=myElements.end();
 }
 
 //=======================================================================
index 788aaa79a729fc86e1efc5804cf33c18e0cd0b59..c46184ea9dac57799f8c721207b4a5f04036626a 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_MeshGroup.hxx
 //  Module : SMESH
 class SMDS_EXPORT SMDS_MeshGroup:public SMDS_MeshObject
 {
   public:
-       SMDS_MeshGroup(const SMDS_Mesh * theMesh,
+        SMDS_MeshGroup(const SMDS_Mesh * theMesh,
                        const SMDSAbs_ElementType theType = SMDSAbs_All);
-       const SMDS_MeshGroup * AddSubGroup
+        const SMDS_MeshGroup * AddSubGroup
                       (const SMDSAbs_ElementType theType = SMDSAbs_All);
-       virtual bool RemoveSubGroup(const SMDS_MeshGroup* theGroup);
-       virtual bool RemoveFromParent();
+        virtual bool RemoveSubGroup(const SMDS_MeshGroup* theGroup);
+        virtual bool RemoveFromParent();
 
         const SMDS_Mesh* GetMesh() const { return myMesh; }
 
         void SetType (const SMDSAbs_ElementType theType);
         void Clear();
-       void Add(const SMDS_MeshElement * theElem);
-       bool Remove(const SMDS_MeshElement * theElem);
-       bool IsEmpty() const { return myElements.empty(); }
-       int Extent() const { return myElements.size(); }
+        void Add(const SMDS_MeshElement * theElem);
+        bool Remove(const SMDS_MeshElement * theElem);
+        bool IsEmpty() const { return myElements.empty(); }
+        int Extent() const { return myElements.size(); }
+        int Tic() const { return myTic; }
 
-       int SubGroupsNb() const { return myChildren.size(); }
+        int SubGroupsNb() const { return myChildren.size(); }
 
         SMDSAbs_ElementType GetType() const { return myType; }
 
-       bool Contains(const SMDS_MeshElement * theElem) const;
+        bool Contains(const SMDS_MeshElement * theElem) const;
 
         void InitIterator() const
         { const_cast<TIterator&>(myIterator) = myElements.begin(); }
@@ -73,18 +75,19 @@ class SMDS_EXPORT SMDS_MeshGroup:public SMDS_MeshObject
         { return *(const_cast<TGroupIterator&>(myGroupIterator))++; }
 
   private:
-       SMDS_MeshGroup(SMDS_MeshGroup* theParent,
+        SMDS_MeshGroup(SMDS_MeshGroup* theParent,
                        const SMDSAbs_ElementType theType = SMDSAbs_All);
 
         typedef std::set<const SMDS_MeshElement *>::const_iterator TIterator;
         typedef std::list<const SMDS_MeshGroup *>::const_iterator TGroupIterator;
 
-       const SMDS_Mesh *                       myMesh;
-       SMDSAbs_ElementType                     myType;
-       std::set<const SMDS_MeshElement *>      myElements;
-       SMDS_MeshGroup *                        myParent;
-       std::list<const SMDS_MeshGroup*>        myChildren;
+        const SMDS_Mesh *                       myMesh;
+        SMDSAbs_ElementType                     myType;
+        std::set<const SMDS_MeshElement*>       myElements; /* - not sorted by ID because it */
+        SMDS_MeshGroup *                        myParent;   /* can contain deleted elements */
+        std::list<const SMDS_MeshGroup*>        myChildren;
         TIterator                               myIterator;
         TGroupIterator                          myGroupIterator;
+        int                                     myTic; // to track changes
 };
 #endif
index 88b9ce38d55e6931ea39301692c9c291c3affb95..ce8f45d2ff1df5fd9b84a9b6ad0fd56b1454f2a3 100644 (file)
@@ -1,30 +1,33 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_MeshIDFactory.cxx
 //  Author : Jean-Michel BOULCOURT
 //  Module : SMESH
 //
 #include "SMDS_MeshIDFactory.hxx"
+#include "SMDS_Mesh.hxx"
+#include "utilities.h"
 
 using namespace std;
 
@@ -33,27 +36,33 @@ using namespace std;
 //purpose  : 
 //=======================================================================
 
-SMDS_MeshIDFactory::SMDS_MeshIDFactory():myMaxID(0)
+SMDS_MeshIDFactory::SMDS_MeshIDFactory():myMaxID(0), myMesh(0)
 {
 }
 
 int SMDS_MeshIDFactory::GetFreeID()
 {
-       if (myPoolOfID.empty()) return ++myMaxID;
-       else
-       {
+        int newid;
+        if (myPoolOfID.empty())
+        {
+            newid = ++myMaxID;
+            //MESSAGE("GetFreeID new " << newid);
+        }
+        else
+        {
                 set<int>::iterator i = myPoolOfID.begin();
-               int ID = *i;//myPoolOfID.top();
-               myPoolOfID.erase( i );//myPoolOfID.pop();
-               return ID;
-       }
+                newid = *i;//myPoolOfID.top();
+                myPoolOfID.erase( i );//myPoolOfID.pop();
+                //MESSAGE("GetFreeID pool " << newid);
+        }
+    return newid;
 }
 
 //=======================================================================
 //function : ReleaseID
 //purpose  : 
 //=======================================================================
-void SMDS_MeshIDFactory::ReleaseID(const int ID)
+void SMDS_MeshIDFactory::ReleaseID(int ID, int vtkId)
 {
   if ( ID > 0 )
   {
@@ -82,6 +91,24 @@ void SMDS_MeshIDFactory::ReleaseID(const int ID)
 
 void SMDS_MeshIDFactory::Clear()
 {
-  myMaxID = 0;
-  myPoolOfID.clear();
+        myMaxID = 0;
+        myPoolOfID.clear();
+}
+
+void SMDS_MeshIDFactory::SetMesh(SMDS_Mesh *mesh)
+{
+        myMesh = mesh;
 }
+
+SMDS_Mesh* SMDS_MeshIDFactory::GetMesh()
+{
+        return myMesh;
+}
+
+void SMDS_MeshIDFactory::emptyPool(int maxId)
+{
+        MESSAGE("SMDS_MeshIDFactory::emptyPool " << myMaxID << " --> " << maxId);
+        myMaxID = maxId;
+        myPoolOfID.clear();
+}
+
index e81b41890597948577f2b48533c28984c50cc826..c79e17aaaf55c784475b9646ed507b9d36416818 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_MeshIDFactory.hxx
 //  Module : SMESH
 #include "SMDS_MeshObject.hxx"
 #include <set>
 
+class SMDS_Mesh;
 
 class SMDS_EXPORT SMDS_MeshIDFactory:public SMDS_MeshObject
 {
 public:
-  virtual int  GetFreeID();
-  virtual void ReleaseID(int ID);
+  int  GetFreeID();
+  virtual void ReleaseID(int ID, int vtkId = -1);
   virtual void Clear();
 
-  protected:
-       SMDS_MeshIDFactory();
-       int myMaxID;
-       std::set<int> myPoolOfID;
+  void SetMesh(SMDS_Mesh *mesh);
+  SMDS_Mesh* GetMesh();
+  inline bool isPoolIdEmpty() { return myPoolOfID.empty(); };
+  virtual void emptyPool(int maxId);
+  inline void adjustMaxId(int ID) { if (ID > myMaxID) myMaxID = ID;};
+protected:
+  SMDS_MeshIDFactory();
+  int myMaxID;
+  std::set<int> myPoolOfID;
+  SMDS_Mesh *myMesh;
 };
 
 #endif
index 6b00427d93e3d6dc87ccb288d5a6c5bc9f42f26d..026590a2e58a91c7aee552f3b3c1c9b033a7f828 100644 (file)
@@ -1,24 +1,22 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  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 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.
 //
-//  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
 //
-//  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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File      : SMDS_MeshInfo.hxx
 // Created   : Mon Sep 24 18:32:41 2007
 // Author    : Edward AGAPOV (eap)
@@ -26,6 +24,7 @@
 #ifndef SMDS_MeshInfo_HeaderFile
 #define SMDS_MeshInfo_HeaderFile
 
+#include <vector>
 using namespace std;
 
 #include "SMESH_SMDS.hxx"
@@ -37,14 +36,21 @@ class SMDS_EXPORT SMDS_MeshInfo
 public:
 
   inline SMDS_MeshInfo();
+  inline SMDS_MeshInfo& operator=(const SMDS_MeshInfo& other);
   inline void Clear();
 
-  int NbNodes() const { return myNbNodes; }
+  inline int NbElements(SMDSAbs_ElementType type=SMDSAbs_All) const;
+  inline int NbEntities(SMDSAbs_EntityType  type) const;
 
+  int NbNodes()      const { return myNbNodes; }
+  int Nb0DElements() const { return myNb0DElements; }
+  int NbBalls()      const { return myNbBalls; }
   inline int NbEdges      (SMDSAbs_ElementOrder order = ORDER_ANY) const;
+
   inline int NbFaces      (SMDSAbs_ElementOrder order = ORDER_ANY) const;
   inline int NbTriangles  (SMDSAbs_ElementOrder order = ORDER_ANY) const;
   inline int NbQuadrangles(SMDSAbs_ElementOrder order = ORDER_ANY) const;
+  int NbBiQuadQuadrangles() const { return myNbBiQuadQuadrangles; }
   int NbPolygons() const { return myNbPolygons; }
 
   inline int NbVolumes (SMDSAbs_ElementOrder order = ORDER_ANY) const;
@@ -52,15 +58,21 @@ public:
   inline int NbHexas   (SMDSAbs_ElementOrder order = ORDER_ANY) const;
   inline int NbPyramids(SMDSAbs_ElementOrder order = ORDER_ANY) const;
   inline int NbPrisms  (SMDSAbs_ElementOrder order = ORDER_ANY) const;
+  inline int NbHexPrisms(SMDSAbs_ElementOrder order = ORDER_ANY) const;
+  int NbTriQuadHexas() const { return myNbTriQuadHexas; }
   int NbPolyhedrons() const { return myNbPolyhedrons; }
 
+protected:
+  inline void addWithPoly(const SMDS_MeshElement* el);
+  inline void setNb(const SMDSAbs_EntityType geomType, const int nb);
+
 private:
   friend class SMDS_Mesh;
 
   // methods to count NOT POLY elements
   inline void remove(const SMDS_MeshElement* el);
   inline void add   (const SMDS_MeshElement* el);
-  inline int  index(SMDSAbs_ElementType type, int nbNodes);
+  inline int  index(SMDSAbs_ElementType type, int nbNodes) const;
   // methods to remove elements of ANY kind
   inline void RemoveEdge(const SMDS_MeshElement* el);
   inline void RemoveFace(const SMDS_MeshElement* el);
@@ -68,15 +80,18 @@ private:
 
   int myNbNodes;
 
+  int myNb0DElements;
+  int myNbBalls;
   int myNbEdges      , myNbQuadEdges      ;
   int myNbTriangles  , myNbQuadTriangles  ;
-  int myNbQuadrangles, myNbQuadQuadrangles;
+  int myNbQuadrangles, myNbQuadQuadrangles, myNbBiQuadQuadrangles;
   int myNbPolygons;
 
   int myNbTetras  , myNbQuadTetras  ;
-  int myNbHexas   , myNbQuadHexas   ;
+  int myNbHexas   , myNbQuadHexas,    myNbTriQuadHexas;
   int myNbPyramids, myNbQuadPyramids;
   int myNbPrisms  , myNbQuadPrisms  ;
+  int myNbHexPrism;
   int myNbPolyhedrons;
 
   std::vector<int*> myNb; // pointers to myNb... fields
@@ -84,51 +99,69 @@ private:
 };
 
 inline SMDS_MeshInfo::SMDS_MeshInfo():
-  myNbNodes(0),
+  myNbNodes      (0),
+  myNb0DElements (0),
+  myNbBalls      (0),
   myNbEdges      (0), myNbQuadEdges      (0),
   myNbTriangles  (0), myNbQuadTriangles  (0),
-  myNbQuadrangles(0), myNbQuadQuadrangles(0),
-  myNbPolygons(0),
-  myNbTetras  (0), myNbQuadTetras  (0),
-  myNbHexas   (0), myNbQuadHexas   (0),
-  myNbPyramids(0), myNbQuadPyramids(0),
-  myNbPrisms  (0), myNbQuadPrisms  (0),
+  myNbQuadrangles(0), myNbQuadQuadrangles(0), myNbBiQuadQuadrangles(0),
+  myNbPolygons   (0),
+  myNbTetras     (0), myNbQuadTetras  (0),
+  myNbHexas      (0), myNbQuadHexas   (0), myNbTriQuadHexas(0),
+  myNbPyramids   (0), myNbQuadPyramids(0),
+  myNbPrisms     (0), myNbQuadPrisms  (0),
+  myNbHexPrism   (0),
   myNbPolyhedrons(0)
 {
-  // Number of nodes in standard element types
-  // n   v  f  e
-  // o   o  a  d
-  // d   l  c  g
-  // e      e  e
-  // -----------
-  // 1      
-  // 2         *
-  // 3      *
-  // 4   *  *  *
-  // 5   *  
-  // 6   *  *
-  // 7      
-  // 8   *  *
-  // 9      
-  // 10  *  
-  // 11     
-  // 12     
-  // 13  *  
-  // 14     
-  // 15  *  
-  // 16     
-  // 17     
-  // 18     
-  // 19     
+  // Number of nodes in standard element types (. - actual nb, * - after the shift)
+  // n   v  f  e  0  n b
+  // o   o  a  d  d  o a
+  // d   l  c  g     d l
+  // e      e  e     e l
+  // s
+  // ====================
+  // 0 ------------------  - DON't USE 0!!!
+  // 1            .  * .
+  // 2         .       *
+  // 3      .     *
+  // 4   *  .  .
+  // 5   *
+  // 6   *  .
+  // 7         *
+  // 8   *  .
+  // 9      .  *
+  // 10  *
+  // 11
+  // 12  *
+  // 13  *
+  // 14
+  // 15  *
+  // 16     *
+  // 17     *
+  // 18
+  // 19     *
   // 20  *
+  // 21     *
+  // 22     *
+  // 23
+  // 24
+  // 25
+  // 26
+  // 27  *
   //
   // So to have a unique index for each type basing on nb of nodes, we use a shift:
-  myShift.resize(SMDSAbs_Volume + 1, 0);
-  myShift[ SMDSAbs_Face ] = +8; // 3->11, 4->12, 6->14, 8->16
-  myShift[ SMDSAbs_Edge ] = -2; // 2->0, 4->2
+  myShift.resize(SMDSAbs_NbElementTypes, 0);
+
+  myShift[ SMDSAbs_Face            ] = +13;// 3->16, 4->17, 6->19, 8->21, 9->22
+  myShift[ SMDSAbs_Edge            ] = +5; // 2->7, 4->9
+  myShift[ SMDSAbs_0DElement       ] = +2; // 1->3
+  myShift[ SMDSAbs_Ball ] = +1; // 1->2
+
+  myNb.resize( index( SMDSAbs_Volume,27 ) + 1, NULL);
 
-  myNb.resize( index( SMDSAbs_Volume,20 ) + 1, NULL);
   myNb[ index( SMDSAbs_Node,1 )] = & myNbNodes;
+  myNb[ index( SMDSAbs_0DElement,1 )] = & myNb0DElements;
+  myNb[ index( SMDSAbs_Ball,1 )] = & myNbBalls;
 
   myNb[ index( SMDSAbs_Edge,2 )] = & myNbEdges;
   myNb[ index( SMDSAbs_Edge,4 )] = & myNbQuadEdges;
@@ -137,22 +170,36 @@ inline SMDS_MeshInfo::SMDS_MeshInfo():
   myNb[ index( SMDSAbs_Face,4 )] = & myNbQuadrangles;
   myNb[ index( SMDSAbs_Face,6 )] = & myNbQuadTriangles;
   myNb[ index( SMDSAbs_Face,8 )] = & myNbQuadQuadrangles;
+  myNb[ index( SMDSAbs_Face,9 )] = & myNbBiQuadQuadrangles;
 
   myNb[ index( SMDSAbs_Volume, 4)]  = & myNbTetras;
   myNb[ index( SMDSAbs_Volume, 5)]  = & myNbPyramids;
   myNb[ index( SMDSAbs_Volume, 6)]  = & myNbPrisms;
   myNb[ index( SMDSAbs_Volume, 8)]  = & myNbHexas;
   myNb[ index( SMDSAbs_Volume, 10)] = & myNbQuadTetras;  
+  myNb[ index( SMDSAbs_Volume, 12)] = & myNbHexPrism;
   myNb[ index( SMDSAbs_Volume, 13)] = & myNbQuadPyramids;
   myNb[ index( SMDSAbs_Volume, 15)] = & myNbQuadPrisms;  
   myNb[ index( SMDSAbs_Volume, 20)] = & myNbQuadHexas;   
+  myNb[ index( SMDSAbs_Volume, 27)] = & myNbTriQuadHexas;   
+}
+
+inline SMDS_MeshInfo& // operator=
+SMDS_MeshInfo::operator=(const SMDS_MeshInfo& other)
+{ for ( int i=0; i<myNb.size(); ++i ) if ( myNb[i] ) (*myNb[i])=(*other.myNb[i]);
+  myNbPolygons = other.myNbPolygons;
+  myNbPolyhedrons = other.myNbPolyhedrons;
+  return *this;
 }
+
 inline void // Clear
 SMDS_MeshInfo::Clear()
-{ for ( int i=0; i<myNb.size(); ++i ) if ( myNb[i] ) (*myNb[i])=0; }
+{ for ( int i=0; i<myNb.size(); ++i ) if ( myNb[i] ) (*myNb[i])=0;
+  myNbPolygons=myNbPolyhedrons=0;
+}
 
 inline int // index
-SMDS_MeshInfo::index(SMDSAbs_ElementType type, int nbNodes)
+SMDS_MeshInfo::index(SMDSAbs_ElementType type, int nbNodes) const
 { return nbNodes + myShift[ type ]; }
 
 inline void // remove
@@ -163,6 +210,14 @@ inline void // add
 SMDS_MeshInfo::add(const SMDS_MeshElement* el)
 { ++(*myNb[ index(el->GetType(), el->NbNodes()) ]); }
 
+inline void // addWithPoly
+SMDS_MeshInfo::addWithPoly(const SMDS_MeshElement* el)
+{
+  if ( el->IsPoly() )
+    ++( el->GetType()==SMDSAbs_Face ? myNbPolygons : myNbPolyhedrons );
+  else
+    add(el);
+}
 inline void // RemoveEdge
 SMDS_MeshInfo::RemoveEdge(const SMDS_MeshElement* el)
 { if ( el->IsQuadratic() ) --myNbQuadEdges; else --myNbEdges; }
@@ -189,11 +244,11 @@ SMDS_MeshInfo::NbTriangles  (SMDSAbs_ElementOrder order) const
 
 inline int // NbQuadrangles
 SMDS_MeshInfo::NbQuadrangles(SMDSAbs_ElementOrder order) const
-{ return order == ORDER_ANY ? myNbQuadrangles+myNbQuadQuadrangles : order == ORDER_LINEAR ? myNbQuadrangles : myNbQuadQuadrangles; }
+{ return order == ORDER_ANY ? myNbQuadrangles+myNbQuadQuadrangles+myNbBiQuadQuadrangles : order == ORDER_LINEAR ? myNbQuadrangles : myNbQuadQuadrangles+myNbBiQuadQuadrangles; }
 
 inline int // NbVolumes
 SMDS_MeshInfo::NbVolumes (SMDSAbs_ElementOrder order) const
-{ return NbTetras(order) + NbHexas(order) + NbPyramids(order) + NbPrisms(order) + (order == ORDER_QUADRATIC ? 0 : myNbPolyhedrons); }
+{ return NbTetras(order) + NbHexas(order) + NbPyramids(order) + NbPrisms(order) + NbHexPrisms(order) + (order == ORDER_QUADRATIC ? 0 : myNbPolyhedrons); }
 
 inline int // NbTetras
 SMDS_MeshInfo::NbTetras  (SMDSAbs_ElementOrder order) const
@@ -201,7 +256,7 @@ SMDS_MeshInfo::NbTetras  (SMDSAbs_ElementOrder order) const
 
 inline int // NbHexas
 SMDS_MeshInfo::NbHexas   (SMDSAbs_ElementOrder order) const
-{ return order == ORDER_ANY ? myNbHexas+myNbQuadHexas : order == ORDER_LINEAR ? myNbHexas : myNbQuadHexas; }
+{ return order == ORDER_ANY ? myNbHexas+myNbQuadHexas+myNbTriQuadHexas : order == ORDER_LINEAR ? myNbHexas : myNbQuadHexas+myNbTriQuadHexas; }
 
 inline int // NbPyramids
 SMDS_MeshInfo::NbPyramids(SMDSAbs_ElementOrder order) const
@@ -211,4 +266,108 @@ inline int // NbPrisms
 SMDS_MeshInfo::NbPrisms  (SMDSAbs_ElementOrder order) const
 { return order == ORDER_ANY ? myNbPrisms+myNbQuadPrisms : order == ORDER_LINEAR ? myNbPrisms : myNbQuadPrisms; }
 
+inline int // NbHexPrisms
+SMDS_MeshInfo::NbHexPrisms  (SMDSAbs_ElementOrder order) const
+{ return order == ORDER_ANY ? myNbHexPrism : order == ORDER_LINEAR ? myNbHexPrism : 0; }
+
+inline int // NbElements
+SMDS_MeshInfo::NbElements(SMDSAbs_ElementType type) const
+{ 
+  int nb = 0;
+  switch (type) {
+  case SMDSAbs_All:
+    for ( int i=1+index( SMDSAbs_Node,1 ); i<myNb.size(); ++i ) if ( myNb[i] ) nb += *myNb[i];
+    nb += myNbPolygons + myNbPolyhedrons;
+    break;
+  case SMDSAbs_Volume:
+    nb = myNbTetras+ myNbPyramids+ myNbPrisms+ myNbHexas+ myNbHexPrism+
+      myNbQuadTetras+ myNbQuadPyramids+ myNbQuadPrisms+ myNbQuadHexas+ myNbTriQuadHexas+
+      myNbPolyhedrons;
+    break;
+  case SMDSAbs_Face:
+    nb = myNbTriangles+ myNbQuadrangles+
+      myNbQuadTriangles+ myNbQuadQuadrangles+ myNbBiQuadQuadrangles+ myNbPolygons;
+    break;
+  case SMDSAbs_Edge:
+    nb = myNbEdges + myNbQuadEdges;
+    break;
+  case SMDSAbs_Node:
+    nb = myNbNodes;
+    break;
+  case SMDSAbs_0DElement:
+    nb = myNb0DElements;
+    break;
+  case SMDSAbs_Ball:
+    nb = myNbBalls;
+    break;
+  default:;
+  }
+  return nb;
+}
+
+int // NbEntities
+SMDS_MeshInfo::NbEntities(SMDSAbs_EntityType type) const
+{
+  switch (type) {
+  case SMDSEntity_Node:             return myNbNodes;
+  case SMDSEntity_Edge:             return myNbEdges;
+  case SMDSEntity_Quad_Edge:        return myNbQuadEdges;
+  case SMDSEntity_Triangle:         return myNbTriangles;
+  case SMDSEntity_Quad_Triangle:    return myNbQuadTriangles;
+  case SMDSEntity_Quadrangle:       return myNbQuadrangles;
+  case SMDSEntity_Quad_Quadrangle:  return myNbQuadQuadrangles;
+  case SMDSEntity_BiQuad_Quadrangle:return myNbBiQuadQuadrangles;
+  case SMDSEntity_Polygon:          return myNbPolygons;
+  case SMDSEntity_Tetra:            return myNbTetras;
+  case SMDSEntity_Quad_Tetra:       return myNbQuadTetras;
+  case SMDSEntity_Pyramid:          return myNbPyramids;
+  case SMDSEntity_Quad_Pyramid:     return myNbQuadPyramids;
+  case SMDSEntity_Hexa:             return myNbHexas;
+  case SMDSEntity_Quad_Hexa:        return myNbQuadHexas;
+  case SMDSEntity_TriQuad_Hexa:     return myNbTriQuadHexas;
+  case SMDSEntity_Penta:            return myNbPrisms;
+  case SMDSEntity_Quad_Penta:       return myNbQuadPrisms;
+  case SMDSEntity_Hexagonal_Prism:  return myNbHexPrism;
+  case SMDSEntity_Polyhedra:        return myNbPolyhedrons;
+  case SMDSEntity_0D:               return myNb0DElements;
+  case SMDSEntity_Ball:             return myNbBalls;
+  case SMDSEntity_Quad_Polygon:
+  case SMDSEntity_Quad_Polyhedra:
+    break;
+  }
+  return 0;
+}
+
+void // set
+SMDS_MeshInfo::setNb(const SMDSAbs_EntityType geomType, const int nb)
+{
+  switch (geomType) {
+  case SMDSEntity_Node:             myNbNodes             = nb; break;
+  case SMDSEntity_0D:               myNb0DElements        = nb; break;
+  case SMDSEntity_Ball:             myNbBalls             = nb; break;
+  case SMDSEntity_BiQuad_Quadrangle:myNbBiQuadQuadrangles = nb; break;
+  case SMDSEntity_Edge:             myNbEdges             = nb; break;
+  case SMDSEntity_Hexa:             myNbHexas             = nb; break;
+  case SMDSEntity_Hexagonal_Prism:  myNbHexPrism          = nb; break;
+  case SMDSEntity_Penta:            myNbPrisms            = nb; break;
+  case SMDSEntity_Polygon:          myNbPolygons          = nb; break;
+  case SMDSEntity_Polyhedra:        myNbPolyhedrons       = nb; break;
+  case SMDSEntity_Pyramid:          myNbPyramids          = nb; break;
+  case SMDSEntity_Quad_Edge:        myNbQuadEdges         = nb; break;
+  case SMDSEntity_Quad_Hexa:        myNbQuadHexas         = nb; break;
+  case SMDSEntity_Quad_Penta:       myNbQuadPrisms        = nb; break;
+  case SMDSEntity_Quad_Pyramid:     myNbQuadPyramids      = nb; break;
+  case SMDSEntity_Quad_Quadrangle:  myNbQuadQuadrangles   = nb; break;
+  case SMDSEntity_Quad_Tetra:       myNbQuadTetras        = nb; break;
+  case SMDSEntity_Quad_Triangle:    myNbQuadTriangles     = nb; break;
+  case SMDSEntity_Quadrangle:       myNbQuadrangles       = nb; break;
+  case SMDSEntity_Tetra:            myNbTetras            = nb; break;
+  case SMDSEntity_TriQuad_Hexa:     myNbTriQuadHexas      = nb; break;
+  case SMDSEntity_Triangle:         myNbTriangles         = nb; break;
+  case SMDSEntity_Quad_Polygon:
+  case SMDSEntity_Quad_Polyhedra:
+    break;
+  }
+}
+
 #endif
index d7c291b520ef059bf962734466b24a9fa36608af..309be4ceba8472d4ab288ed53b6acfd60bd67b57 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //
 #ifdef _MSC_VER
 #include "SMDS_MeshNode.hxx"
 #include "SMDS_SpacePosition.hxx"
 #include "SMDS_IteratorOfElements.hxx"
+#include "SMDS_Mesh.hxx"
+#include <vtkUnstructuredGrid.h>
+
+#include "utilities.h"
+#include "Utils_SALOME_Exception.hxx"
+#include <cassert>
 
 using namespace std;
 
+int SMDS_MeshNode::nbNodes =0;
+
 //=======================================================================
 //function : SMDS_MeshNode
 //purpose  : 
 //=======================================================================
+SMDS_MeshNode::SMDS_MeshNode() :
+  SMDS_MeshElement(-1, -1, 0),
+  myPosition(SMDS_SpacePosition::originSpacePosition())
+{
+  nbNodes++;
+}
+
+SMDS_MeshNode::SMDS_MeshNode(int id, int meshId, int shapeId, double x, double y, double z):
+  SMDS_MeshElement(id, meshId, shapeId),
+  myPosition(SMDS_SpacePosition::originSpacePosition())
+{
+  nbNodes++;
+  init(id, meshId, shapeId, x, y ,z);
+}
+
+void SMDS_MeshNode::init(int id, int meshId, int shapeId, double x, double y, double z)
+{
+  SMDS_MeshElement::init(id, meshId, shapeId);
+  myVtkID = id -1;
+  assert(myVtkID >= 0);
+  //MESSAGE("Node " << myID << " " << myVtkID << " (" << x << ", " << y << ", " << z << ")");
+  SMDS_Mesh* mesh = SMDS_Mesh::_meshList[myMeshId];
+  SMDS_UnstructuredGrid * grid = mesh->getGrid();
+  vtkPoints *points = grid->GetPoints();
+  points->InsertPoint(myVtkID, x, y, z);
+  SMDS_CellLinks *cellLinks = dynamic_cast<SMDS_CellLinks*>(grid->GetCellLinks());
+  assert(cellLinks);
+  if (myVtkID >= cellLinks->GetLinksSize())
+          cellLinks->ResizeL(myVtkID+SMDS_Mesh::chunkSize);
+}
 
-SMDS_MeshNode::SMDS_MeshNode(double x, double y, double z):
-       myX(x), myY(y), myZ(z),
-       myPosition(SMDS_SpacePosition::originSpacePosition())
+SMDS_MeshNode::~SMDS_MeshNode()
 {
+  nbNodes--;
+  if ( myPosition && myPosition != SMDS_SpacePosition::originSpacePosition() )
+    delete myPosition, myPosition = 0;
 }
 
 //=======================================================================
@@ -49,14 +89,10 @@ SMDS_MeshNode::SMDS_MeshNode(double x, double y, double z):
 
 void SMDS_MeshNode::RemoveInverseElement(const SMDS_MeshElement * parent)
 {
-  NCollection_List<const SMDS_MeshElement*>::Iterator it(myInverseElements);
-  while (it.More()) {
-    const SMDS_MeshElement* elem = it.Value();
-    if (elem == parent)
-      myInverseElements.Remove(it);
-    else
-      it.Next();
-  }
+    //MESSAGE("RemoveInverseElement " << myID << " " << parent->GetID());
+    const SMDS_MeshCell* cell = dynamic_cast<const SMDS_MeshCell*>(parent);
+    MYASSERT(cell);
+    SMDS_Mesh::_meshList[myMeshId]->getGrid()->RemoveReferenceToCell(myVtkID, cell->getVtkId());
 }
 
 //=======================================================================
@@ -66,8 +102,8 @@ void SMDS_MeshNode::RemoveInverseElement(const SMDS_MeshElement * parent)
 
 void SMDS_MeshNode::Print(ostream & OS) const
 {
-       OS << "Node <" << GetID() << "> : X = " << myX << " Y = "
-               << myY << " Z = " << myZ << endl;
+        OS << "Node <" << myID << "> : X = " << X() << " Y = "
+                << Y() << " Z = " << Z() << endl;
 }
 
 //=======================================================================
@@ -77,7 +113,11 @@ void SMDS_MeshNode::Print(ostream & OS) const
 
 void SMDS_MeshNode::SetPosition(const SMDS_PositionPtr& aPos)
 {
-       myPosition = aPos;
+  if ( myPosition &&
+       myPosition != SMDS_SpacePosition::originSpacePosition() &&
+       myPosition != aPos )
+    delete myPosition;
+  myPosition = aPos;
 }
 
 //=======================================================================
@@ -87,7 +127,7 @@ void SMDS_MeshNode::SetPosition(const SMDS_PositionPtr& aPos)
 
 const SMDS_PositionPtr& SMDS_MeshNode::GetPosition() const
 {
-       return myPosition;
+        return myPosition;
 }
 
 //=======================================================================
@@ -96,121 +136,186 @@ const SMDS_PositionPtr& SMDS_MeshNode::GetPosition() const
  */
 //=======================================================================
 
-class SMDS_MeshNode_MyInvIterator:public SMDS_ElemIterator
+class SMDS_MeshNode_MyInvIterator: public SMDS_ElemIterator
 {
-  NCollection_List<const SMDS_MeshElement*>::Iterator myIterator;
-  SMDSAbs_ElementType                                 myType;
- public:
-  SMDS_MeshNode_MyInvIterator(const NCollection_List<const SMDS_MeshElement*>& s,
-                              SMDSAbs_ElementType type):
-    myIterator(s), myType(type)
-  {}
+private:
+  SMDS_Mesh* myMesh;
+  vtkIdType* myCells;
+  int myNcells;
+  SMDSAbs_ElementType myType;
+  int iter;
+  vector<vtkIdType> cellList;
+
+public:
+  SMDS_MeshNode_MyInvIterator(SMDS_Mesh *mesh, vtkIdType* cells, int ncells, SMDSAbs_ElementType type) :
+    myMesh(mesh), myCells(cells), myNcells(ncells), myType(type), iter(0)
+  {
+    //MESSAGE("SMDS_MeshNode_MyInvIterator : ncells " << myNcells);
+    cellList.clear();
+    if (type == SMDSAbs_All)
+      for (int i = 0; i < ncells; i++)
+        cellList.push_back(cells[i]);
+    else for (int i = 0; i < ncells; i++)
+      {
+        int vtkId = cells[i];
+        int smdsId = myMesh->fromVtkToSmds(vtkId);
+        const SMDS_MeshElement* elem = myMesh->FindElement(smdsId);
+        if (elem->GetType() == type)
+          {
+            //MESSAGE("Add element vtkId " << vtkId << " " << elem->GetType())
+            cellList.push_back(vtkId);
+          }
+      }
+    myCells = &cellList[0];
+    myNcells = cellList.size();
+    //MESSAGE("myNcells="<<myNcells);
+  }
 
   bool more()
   {
-    if ( myType != SMDSAbs_All ) {
-      while ( myIterator.More() && myIterator.Value()->GetType() != myType)
-        myIterator.Next();
-    }
-    return myIterator.More() != Standard_False;
+    //MESSAGE("iter " << iter << " ncells " << myNcells);
+    return (iter < myNcells);
   }
 
   const SMDS_MeshElement* next()
   {
-    const SMDS_MeshElement* current=myIterator.Value();
-    myIterator.Next();
-    return current;
-  }    
+    int vtkId = myCells[iter];
+    int smdsId = myMesh->fromVtkToSmds(vtkId);
+    const SMDS_MeshElement* elem = myMesh->FindElement(smdsId);
+    if (!elem)
+      {
+        MESSAGE("SMDS_MeshNode_MyInvIterator problem Null element");
+        throw SALOME_Exception("SMDS_MeshNode_MyInvIterator problem Null element");
+      }
+    //MESSAGE("vtkId " << vtkId << " smdsId " << smdsId << " " << elem->GetType());
+    iter++;
+    return elem;
+  }
 };
 
 SMDS_ElemIteratorPtr SMDS_MeshNode::
-       GetInverseElementIterator(SMDSAbs_ElementType type) const
+        GetInverseElementIterator(SMDSAbs_ElementType type) const
 {
-  return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyInvIterator(myInverseElements,type));
+    vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID);
+    //MESSAGE("myID " << myID << " ncells " << l.ncells);
+    return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyInvIterator(SMDS_Mesh::_meshList[myMeshId], l.cells, l.ncells, type));
 }
 
 // Same as GetInverseElementIterator but the create iterator only return
 // wanted type elements.
 class SMDS_MeshNode_MyIterator:public SMDS_ElemIterator
 {
-  NCollection_List<const SMDS_MeshElement*> mySet;
-  NCollection_List<const SMDS_MeshElement*>::Iterator myIterator;
+private:
+  SMDS_Mesh* myMesh;
+  vtkIdType* myCells;
+  int  myNcells;
+  SMDSAbs_ElementType                                 myType;
+  int  iter;
+  vector<SMDS_MeshElement*> myFiltCells;
+
  public:
-  SMDS_MeshNode_MyIterator(SMDSAbs_ElementType type,
-                           const NCollection_List<const SMDS_MeshElement*>& s)
+  SMDS_MeshNode_MyIterator(SMDS_Mesh *mesh,
+                           vtkIdType* cells,
+                           int ncells,
+                           SMDSAbs_ElementType type):
+    myMesh(mesh), myCells(cells), myNcells(ncells), myType(type), iter(0)
   {
-    const SMDS_MeshElement * e;
-    bool toInsert;
-    NCollection_List<const SMDS_MeshElement*>::Iterator it(s);
-    for(; it.More(); it.Next())
-    {
-      e=it.Value();
-      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.Append(e);
-    }
-    myIterator.Init(mySet);
+        //MESSAGE("myNcells " << myNcells);
+       for (; iter<ncells; iter++)
+        {
+           int vtkId = myCells[iter];
+           int smdsId = myMesh->fromVtkToSmds(vtkId);
+           //MESSAGE("vtkId " << vtkId << " smdsId " << smdsId);
+           const SMDS_MeshElement* elem = myMesh->FindElement(smdsId);
+           if (elem->GetType() == type)
+               myFiltCells.push_back((SMDS_MeshElement*)elem);
+        }
+        myNcells = myFiltCells.size();
+        //MESSAGE("myNcells " << myNcells);
+       iter = 0;
+        //MESSAGE("SMDS_MeshNode_MyIterator (filter) " << ncells << " " << myNcells);
   }
 
   bool more()
   {
-    return myIterator.More() != Standard_False;
+      return (iter< myNcells);
   }
 
   const SMDS_MeshElement* next()
   {
-    const SMDS_MeshElement* current=myIterator.Value();
-    myIterator.Next();
-    return current;
+      const SMDS_MeshElement* elem = myFiltCells[iter];
+      iter++;
+      return elem;
   }
 };
 
 SMDS_ElemIteratorPtr SMDS_MeshNode::
-       elementsIterator(SMDSAbs_ElementType type) const
+        elementsIterator(SMDSAbs_ElementType type) const
 {
   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))));
+  {
+    vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID);
+    return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyIterator(SMDS_Mesh::_meshList[myMeshId], l.cells, l.ncells, type));
+  }
 }
 
 int SMDS_MeshNode::NbNodes() const
 {
-       return 1;
+        return 1;
+}
+
+double* SMDS_MeshNode::getCoord() const
+{
+  return SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetPoint(myVtkID);
 }
 
 double SMDS_MeshNode::X() const
 {
-       return myX;
+  double *coord = getCoord();
+  return coord[0];
 }
 
 double SMDS_MeshNode::Y() const
 {
-       return myY;
+  double *coord = getCoord();
+  return coord[1];
 }
 
 double SMDS_MeshNode::Z() const
 {
-       return myZ;
+  double *coord = getCoord();
+  return coord[2];
 }
 
+//================================================================================
+/*!
+ * \brief thread safe getting coords
+ */
+void SMDS_MeshNode::GetXYZ(double xyz[3]) const
+{
+  return SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetPoint(myVtkID,xyz);
+}
+
+//* resize the vtkPoints structure every SMDS_Mesh::chunkSize points
 void SMDS_MeshNode::setXYZ(double x, double y, double z)
 {
-       myX=x;
-       myY=y;
-       myZ=z;  
+  SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myMeshId];
+  vtkPoints *points = mesh->getGrid()->GetPoints();
+  points->InsertPoint(myVtkID, x, y, z);
+  mesh->adjustBoundingBox(x, y, z);
+  mesh->setMyModified();
 }
 
 SMDSAbs_ElementType SMDS_MeshNode::GetType() const
 {
-       return SMDSAbs_Node;
+        return SMDSAbs_Node;
+}
+
+vtkIdType SMDS_MeshNode::GetVtkType() const
+{
+  return VTK_VERTEX;
 }
 
 //=======================================================================
@@ -219,13 +324,12 @@ SMDSAbs_ElementType SMDS_MeshNode::GetType() const
 //=======================================================================
 void SMDS_MeshNode::AddInverseElement(const SMDS_MeshElement* ME)
 {
-  NCollection_List<const SMDS_MeshElement*>::Iterator it(myInverseElements);
-  for (; it.More(); it.Next()) {
-    const SMDS_MeshElement* elem = it.Value();
-    if (elem == ME)
-      return;
-  }
-  myInverseElements.Append(ME);
+  const SMDS_MeshCell *cell = dynamic_cast<const SMDS_MeshCell*> (ME);
+  assert(cell);
+  SMDS_UnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkCellLinks *Links = grid->GetCellLinks();
+  Links->ResizeCellList(myVtkID, 1);
+  Links->AddCellReference(cell->getVtkId(), myVtkID);
 }
 
 //=======================================================================
@@ -234,12 +338,13 @@ void SMDS_MeshNode::AddInverseElement(const SMDS_MeshElement* ME)
 //=======================================================================
 void SMDS_MeshNode::ClearInverseElements()
 {
-  myInverseElements.Clear();
+  SMDS_Mesh::_meshList[myMeshId]->getGrid()->ResizeCellList(myVtkID, 0);
 }
 
 bool SMDS_MeshNode::emptyInverseElements()
 {
-  return myInverseElements.IsEmpty() != Standard_False;
+  vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID);
+  return (l.ncells == 0);
 }
 
 //================================================================================
@@ -250,13 +355,19 @@ bool SMDS_MeshNode::emptyInverseElements()
 
 int SMDS_MeshNode::NbInverseElements(SMDSAbs_ElementType type) const
 {
+  vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID);
+
   if ( type == SMDSAbs_All )
-    return myInverseElements.Extent();
+    return l.ncells;
+
   int nb = 0;
-  NCollection_List<const SMDS_MeshElement*>::Iterator it( myInverseElements );
-  for ( ; it.More(); it.Next() )
-    if ( it.Value()->GetType() == type )
-      nb++;
+  SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myMeshId];
+  for (int i=0; i<l.ncells; i++)
+        {
+           const SMDS_MeshElement* elem = mesh->FindElement(mesh->fromVtkToSmds(l.cells[i]));
+           if (elem->GetType() == type)
+                nb++;
+        }
   return nb;
 }
 
@@ -265,14 +376,14 @@ int SMDS_MeshNode::NbInverseElements(SMDSAbs_ElementType type) const
 ///////////////////////////////////////////////////////////////////////////////
 bool operator<(const SMDS_MeshNode& e1, const SMDS_MeshNode& e2)
 {
-       return e1.GetID()<e2.GetID();
-       /*if(e1.myX<e2.myX) return true;
-       else if(e1.myX==e2.myX)
-       {
-               if(e1.myY<e2.myY) return true;
-               else if(e1.myY==e2.myY) return (e1.myZ<e2.myZ);
-               else return false;
-       }
-       else return false;*/
+        return e1.getVtkId()<e2.getVtkId();
+        /*if(e1.myX<e2.myX) return true;
+        else if(e1.myX==e2.myX)
+        {
+                if(e1.myY<e2.myY) return true;
+                else if(e1.myY==e2.myY) return (e1.myZ<e2.myZ);
+                else return false;
+        }
+        else return false;*/
 }
 
index 69b937034aa76ac1ae905996e78bb8fe1238c38f..78966bc5795fda355d610bb51f09ce9069995d02 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_MeshNode.hxx
 //  Module : SMESH
 
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_Position.hxx"
-#include <NCollection_List.hxx>
+#include "ObjectPool.hxx"
 
-class SMDS_EXPORT SMDS_MeshNode:public SMDS_MeshElement
+class SMDS_EXPORT SMDS_MeshNode: public SMDS_MeshElement
 {
+public:
+  friend class SMESHDS_Mesh;
+  friend class SMDS_Mesh;
+  friend class ObjectPool<SMDS_MeshNode>;
+  friend class SMDS_VtkFace;
+
+  void Print(std::ostream & OS) const;
+  double X() const; // ! NOT thread safe methods !
+  double Y() const;
+  double Z() const;
+  void   GetXYZ(double xyx[3]) const; // thread safe getting coords
+  SMDS_ElemIteratorPtr    GetInverseElementIterator(SMDSAbs_ElementType type=SMDSAbs_All) const;
+  int                     NbInverseElements(SMDSAbs_ElementType type=SMDSAbs_All) const;
+  const SMDS_PositionPtr& GetPosition() const;
+  virtual SMDSAbs_ElementType  GetType() const;
+  virtual vtkIdType            GetVtkType() const;
+  virtual SMDSAbs_EntityType   GetEntityType() const { return SMDSEntity_Node;}
+  virtual SMDSAbs_GeometryType GetGeomType() const   { return SMDSGeom_NONE; }
+  virtual int                  NbNodes() const;
+
+  void SetPosition(const SMDS_PositionPtr& aPos);
+  void setXYZ(double x, double y, double z);
 
-  public:
-       SMDS_MeshNode(double x, double y, double z);
-       void Print(std::ostream & OS) const;
-       double X() const;
-       double Y() const;
-       double Z() const;
-       void AddInverseElement(const SMDS_MeshElement * ME);
-       void RemoveInverseElement(const SMDS_MeshElement * parent);
-       void ClearInverseElements();
-       bool emptyInverseElements();
-       SMDS_ElemIteratorPtr GetInverseElementIterator(SMDSAbs_ElementType type=SMDSAbs_All) const;
-        int NbInverseElements(SMDSAbs_ElementType type=SMDSAbs_All) 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);
+  static int nbNodes;
 
-  /*!
-   * \brief Return node by its index
-    * \param ind - node index
-    * \retval const SMDS_MeshNode* - the node
-   * 
-   * Index is wrapped if it is out of a valid range
-   */
-  virtual const SMDS_MeshNode* GetNode(const int) const { return this; }
+protected:
+  SMDS_MeshNode();
+  SMDS_MeshNode(int id, int meshId, int shapeId = -1, double x=0, double y=0, double z=0);
+  virtual ~SMDS_MeshNode();
+  void init(int id, int meshId, int shapeId = -1, double x=0, double y=0, double z=0);
+  inline void setVtkId(int vtkId) { myVtkID = vtkId; };
+  double* getCoord() const;
+  void AddInverseElement(const SMDS_MeshElement * ME);
+  void RemoveInverseElement(const SMDS_MeshElement * parent);
+  void ClearInverseElements();
+  bool emptyInverseElements();
 
-  protected:
-       SMDS_ElemIteratorPtr
-               elementsIterator(SMDSAbs_ElementType type) const;
+  SMDS_ElemIteratorPtr
+  elementsIterator(SMDSAbs_ElementType type) const;
 
-  private:
-       double myX, myY, myZ;
-       SMDS_PositionPtr myPosition;
-       NCollection_List<const SMDS_MeshElement*> myInverseElements;
+private:
+  SMDS_PositionPtr myPosition;
 };
 
 #endif
diff --git a/src/SMDS/SMDS_MeshNodeIDFactory.cxx b/src/SMDS/SMDS_MeshNodeIDFactory.cxx
new file mode 100644 (file)
index 0000000..0884a5b
--- /dev/null
@@ -0,0 +1,149 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+//  File   : SMDS_MeshNodeIDFactory.cxx
+//  Author : Jean-Michel BOULCOURT
+//  Module : SMESH
+//
+#ifdef _MSC_VER
+#pragma warning(disable:4786)
+#endif
+
+#include "SMDS_MeshNodeIDFactory.hxx"
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_Mesh.hxx"
+
+#include <vtkUnstructuredGrid.h>
+#include <vtkCellType.h>
+
+using namespace std;
+
+//=======================================================================
+//function : SMDS_MeshNodeIDFactory
+//purpose  : 
+//=======================================================================
+SMDS_MeshNodeIDFactory::SMDS_MeshNodeIDFactory() :
+  SMDS_MeshIDFactory(), myMin(0), myMax(0)
+{
+}
+
+//=======================================================================
+//function : BindID
+//purpose  : 
+//=======================================================================
+bool SMDS_MeshNodeIDFactory::BindID(int ID, SMDS_MeshElement * elem)
+{
+  updateMinMax(ID);
+  return true;
+}
+
+//=======================================================================
+//function : MeshElement
+//purpose  : 
+//=======================================================================
+SMDS_MeshElement* SMDS_MeshNodeIDFactory::MeshElement(int ID)
+{
+  // commented since myMax can be 0 after ReleaseID()
+//   if ((ID < 1) || (ID > myMax))
+//     return NULL;
+  const SMDS_MeshElement* elem = GetMesh()->FindNode(ID);
+  return (SMDS_MeshElement*) (elem);
+}
+
+//=======================================================================
+//function : GetFreeID
+//purpose  : 
+//=======================================================================
+int SMDS_MeshNodeIDFactory::GetFreeID()
+{
+  int ID;
+  do {
+    ID = SMDS_MeshIDFactory::GetFreeID();
+  } while ( MeshElement( ID ));
+  return ID;
+}
+
+//=======================================================================
+//function : ReleaseID
+//purpose  : 
+//=======================================================================
+void SMDS_MeshNodeIDFactory::ReleaseID(const int ID, int vtkId)
+{
+  SMDS_MeshIDFactory::ReleaseID(ID);
+  myMesh->setMyModified();
+  if (ID == myMax)
+    myMax = 0; // --- force updateMinMax
+  if (ID == myMin)
+    myMax = 0; // --- force updateMinMax
+}
+
+//=======================================================================
+//function : GetMaxID
+//purpose  : 
+//=======================================================================
+
+int SMDS_MeshNodeIDFactory::GetMaxID() const
+{
+  if (myMax == 0)
+    updateMinMax();
+  return myMax;
+}
+
+//=======================================================================
+//function : GetMinID
+//purpose  : 
+//=======================================================================
+
+int SMDS_MeshNodeIDFactory::GetMinID() const
+{
+  if (myMax == 0)
+    updateMinMax();
+  return myMin;
+}
+
+//=======================================================================
+//function : updateMinMax
+//purpose  : 
+//=======================================================================
+
+void SMDS_MeshNodeIDFactory::updateMinMax() const
+{
+  myMesh->updateNodeMinMax();
+  myMin = myMesh->MinNodeID();
+  myMax = myMesh->MaxNodeID();
+}
+
+SMDS_ElemIteratorPtr SMDS_MeshNodeIDFactory::elementsIterator() const
+{
+  return myMesh->elementsIterator(SMDSAbs_Node);
+}
+
+void SMDS_MeshNodeIDFactory::Clear()
+{
+  myMin = myMax = 0;
+  SMDS_MeshIDFactory::Clear();
+}
+
+void SMDS_MeshNodeIDFactory::emptyPool(int maxId)
+{
+  SMDS_MeshIDFactory::emptyPool(maxId);
+  myMax = maxId;
+}
diff --git a/src/SMDS/SMDS_MeshNodeIDFactory.hxx b/src/SMDS/SMDS_MeshNodeIDFactory.hxx
new file mode 100644 (file)
index 0000000..07c0341
--- /dev/null
@@ -0,0 +1,65 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+//  File   : SMDS_MeshElementIDFactory.hxx
+//  Module : SMESH
+//
+#ifndef _SMDS_MeshNodeIDFactory_HeaderFile
+#define _SMDS_MeshNodeIDFactory_HeaderFile
+
+#include "SMESH_SMDS.hxx"
+
+#include "SMDS_MeshIDFactory.hxx"
+#include "SMDS_ElemIterator.hxx"
+
+#include <vector>
+
+class SMDS_MeshElement;
+
+class SMDS_EXPORT SMDS_MeshNodeIDFactory: public SMDS_MeshIDFactory
+{
+public:
+  SMDS_MeshNodeIDFactory();
+  bool BindID(int ID, SMDS_MeshElement * elem);
+  SMDS_MeshElement * MeshElement(int ID);
+  virtual int GetFreeID();
+  virtual void ReleaseID(int ID, int vtkId = -1);
+  int GetMaxID() const;
+  int GetMinID() const;
+  SMDS_ElemIteratorPtr elementsIterator() const;
+  virtual void Clear();
+  virtual void emptyPool(int maxId);
+
+protected:
+  void updateMinMax() const;
+  void updateMinMax(int id) const
+  {
+    if (id > myMax)
+      myMax = id;
+    if (id < myMin)
+      myMin = id;
+  }
+
+  mutable int myMin, myMax;
+
+};
+
+#endif
index b023c73e966ef7f4dfe7dfcbe166ee97f5ec0c59..f880cff6cee510a1b05b4ab09b57821ac0488939 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_MeshObject.cxx
 //  Author : Jean-Michel BOULCOURT
index 8004fcbf9a6dd615a03a6080d65a6590d40be1c4..c3bd07de6c09ef90c497a384e95c67c5458139dd 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_MeshObject.hxx
 //  Module : SMESH
index 574b5b0ffd512e29d1137018ca17ac0d87053cd1..7cf865a32db1eab2cd9f7d40f7c8e07de74ce836 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_MeshVolume.cxx
 //  Author : Jean-Michel BOULCOURT
 
 SMDSAbs_ElementType SMDS_MeshVolume::GetType() const
 {
-       return SMDSAbs_Volume;
+        return SMDSAbs_Volume;
 }
 
+vtkIdType SMDS_MeshVolume::GetVtkType() const
+{
+  return VTK_CONVEX_POINT_SET; // --- must be reimplemented in derived classes
+}
index aa3498eac3b7cb0286fd5ad3ec50df076fe6d03b..1f928c61082630393f105aae72b05fa98dc893e2 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_MeshVolume.hxx
 //  Module : SMESH
 
 #include "SMESH_SMDS.hxx"
 
-#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshCell.hxx"
 
-class SMDS_EXPORT SMDS_MeshVolume:public SMDS_MeshElement
+class SMDS_EXPORT SMDS_MeshVolume:public SMDS_MeshCell
 {
-       
+        
   public:
-       SMDSAbs_ElementType GetType() const;
+        SMDSAbs_ElementType GetType() const;
+  virtual vtkIdType GetVtkType() const;
 };
 #endif
index 282256c7fb4d064508e0260dfd25cd245a9c56d1..4738a02209b73d94cd1bd804fd92cac4d3d8ef9d 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //
 #ifdef _MSC_VER
@@ -42,6 +43,7 @@ using namespace std;
 SMDS_PolygonalFaceOfNodes::SMDS_PolygonalFaceOfNodes
                           (std::vector<const SMDS_MeshNode *> nodes)
 {
+  //MESSAGE("******************************************** SMDS_PolygonalFaceOfNodes");
   myNodes = nodes;
 }
 
@@ -154,7 +156,7 @@ public:
     myElems.reserve( face->NbNodes() );
     for ( int i = 0; i < face->NbNodes(); ++i ) {
       const SMDS_MeshElement* edge =
-        SMDS_Mesh::FindEdge( face->GetNode( i ), face->GetNode( i + 1 ));
+        SMDS_Mesh::FindEdge( face->GetNode( i ), face->GetNodeWrap( i + 1 ));
       if ( edge )
         myElems.push_back( edge );
     }
@@ -191,11 +193,8 @@ SMDS_ElemIteratorPtr SMDS_PolygonalFaceOfNodes::elementsIterator
  * \brief Return node by its index
  * \param ind - node index
  * \retval const SMDS_MeshNode* - the node
- * 
- * Index is wrapped if it is out of a valid range
  */
 const SMDS_MeshNode* SMDS_PolygonalFaceOfNodes::GetNode(const int ind) const
 {
   return myNodes[ WrappedIndex( ind )];
 }
-
index 3c9f9a50832d3f77f011c24641e9a20f6a209320..1586f25144728ea76605ef605bb7f3c15ffa30ae 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //
 #ifndef _SMDS_PolygonalFaceOfNodes_HeaderFile
@@ -40,6 +41,7 @@ class SMDS_EXPORT SMDS_PolygonalFaceOfNodes:public SMDS_MeshFace
   SMDS_PolygonalFaceOfNodes (std::vector<const SMDS_MeshNode *> nodes);
 
   virtual SMDSAbs_ElementType GetType() const;
+  virtual SMDSAbs_EntityType  GetEntityType() const { return SMDSEntity_Polygon; }
   virtual bool IsPoly() const { return true; };
 
   bool ChangeNodes (std::vector<const SMDS_MeshNode *> nodes);
@@ -58,8 +60,6 @@ class SMDS_EXPORT SMDS_PolygonalFaceOfNodes:public SMDS_MeshFace
    * \brief Return node by its index
     * \param ind - node index
     * \retval const SMDS_MeshNode* - the node
-   * 
-   * Index is wrapped if it is out of a valid range
    */
   virtual const SMDS_MeshNode* GetNode(const int ind) const;
 
index 4b20720f6be27552ca927a27b6f579962d2f794b..b030440ecb2ff7750e0c883f2169920f9a5ca3bb 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //
 #ifdef _MSC_VER
@@ -44,6 +45,7 @@ SMDS_PolyhedralVolumeOfNodes::SMDS_PolyhedralVolumeOfNodes
                                  vector<int>                   quantities)
 : SMDS_VolumeOfNodes(NULL, NULL, NULL, NULL)
 {
+  //MESSAGE("****************************************** SMDS_PolyhedralVolumeOfNodes");
   ChangeNodes(nodes, quantities);
 }
 
@@ -259,5 +261,5 @@ SMDS_ElemIteratorPtr SMDS_PolyhedralVolumeOfNodes::uniqueNodesIterator() const
 
 const SMDS_MeshNode* SMDS_PolyhedralVolumeOfNodes::GetNode(const int ind) const
 {
-  return myNodesByFaces[ WrappedIndex( ind )];
+  return myNodesByFaces[ ind ];
 }
index 9cddb1f02b771de50ed7ecfc7eee9ea6ba02041e..237c92571c4eedd2b25559022036835e7496f333 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_PolyhedralVolumeOfNodes.hxx
 //  Module : SMESH
@@ -38,7 +39,8 @@ class SMDS_EXPORT SMDS_PolyhedralVolumeOfNodes:public SMDS_VolumeOfNodes
 
   //virtual ~SMDS_PolyhedralVolumeOfNodes();
 
-  virtual SMDSAbs_ElementType GetType() const; 
+  virtual SMDSAbs_ElementType GetType() const;  
+  virtual SMDSAbs_EntityType   GetEntityType() const { return SMDSEntity_Polyhedra; }
   virtual bool IsPoly() const { return true; };
 
   bool ChangeNodes (const std::vector<const SMDS_MeshNode *> & nodes,
index 46b63e1f8ac4d5acc7f4ab99d576674888f0f0c8..939b50fe96ec57d8fc75efacf74295df28f00471 100644 (file)
@@ -1,58 +1,41 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_Position.cxx
 //  Author : Jean-Michel BOULCOURT
 //  Module : SMESH
 //
 #include "SMDS_Position.hxx"
+#include "utilities.h"
 
 //=======================================================================
 //function : SMDS_Position
 //purpose  : 
 //=======================================================================
 
-SMDS_Position::SMDS_Position(int aShapeId) :myShapeId(aShapeId)
-{
-}
-
-//=======================================================================
-//function : SetShapeId
-//purpose  : 
-//=======================================================================
-
-void SMDS_Position::SetShapeId(int aShapeId)
-{
-       myShapeId = aShapeId;
-}
-
-//=======================================================================
-//function : GetShapeId
-//purpose  : 
-//=======================================================================
-
-int SMDS_Position::GetShapeId() const
+SMDS_Position::SMDS_Position()
 {
-       return myShapeId;
+  //MESSAGE("########################## SMDS_Position ");
 }
 
 //=======================================================================
index 687bc098ebcf97c90ddd81023773089ae6245df2..3b4530e1d1ab51a1f932d0cf5129cbaa4005ab87 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_Position.hxx
 //  Module : SMESH
 #include <boost/shared_ptr.hpp>
 
 class SMDS_Position;
-typedef boost::shared_ptr<SMDS_Position> SMDS_PositionPtr;
+//typedef boost::shared_ptr<SMDS_Position> SMDS_PositionPtr;
+typedef SMDS_Position* SMDS_PositionPtr;
 
 class SMDS_EXPORT SMDS_Position
 {
 
   public:
-       const virtual double * Coords() const = 0;
-       virtual SMDS_TypeOfPosition GetTypeOfPosition() const = 0;
-       virtual int GetDim() const;
-       void SetShapeId(int aShapeId);
-       int GetShapeId() const;
-       virtual ~SMDS_Position() {}
+        virtual SMDS_TypeOfPosition GetTypeOfPosition() const = 0;
+        virtual int GetDim() const;
+        virtual ~SMDS_Position() {}
 
   protected:
-         SMDS_Position(int aShapeId);
-
-  private:
-       int myShapeId;
+          SMDS_Position();
 };
 
 
index d314cf281ec6cde6fa650ee9c529a6eb9626c7ce..78a3bc1f033f39f7babaa1b1162a9a3295675f1d 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 // File:      SMDS_QuadraticEdge.cxx
 // Created:   16.01.06 16:25:42
@@ -29,6 +30,7 @@
 #include "SMDS_SetIterator.hxx"
 #include "SMDS_IteratorOfElements.hxx"
 #include "SMDS_MeshNode.hxx"
+#include "utilities.h"
 
 using namespace std;
 
@@ -40,8 +42,9 @@ using namespace std;
 SMDS_QuadraticEdge::SMDS_QuadraticEdge(const SMDS_MeshNode * node1,
                                        const SMDS_MeshNode * node2,
                                        const SMDS_MeshNode * node12)
-     :SMDS_MeshEdge(node1,node2)
-{      
+     :SMDS_LinearEdge(node1,node2)
+{
+  //MESSAGE("******************************************************* SMDS_QuadraticEdge");
   myNodes[2]=node12;
 }
 
@@ -182,4 +185,3 @@ SMDS_ElemIteratorPtr SMDS_QuadraticEdge::elementsIterator(SMDSAbs_ElementType ty
        (this,type, SMDS_ElemIteratorPtr(new _MyNodeIterator(myNodes))));
   }
 }
-
index 83877d6a16bd80b2f861a863da6af45a37695634..2a0d0bc400cf08a3ad2f16ef7c19cbff839066c7 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_QuadraticEdge.hxx
 //  Module : SMESH
 
 #include "SMESH_SMDS.hxx"
 
-#include "SMDS_MeshEdge.hxx"
+#include "SMDS_LinearEdge.hxx"
 #include <iostream>
 
-class SMDS_EXPORT SMDS_QuadraticEdge: public SMDS_MeshEdge
+class SMDS_EXPORT SMDS_QuadraticEdge: public SMDS_LinearEdge
 {
 
 public:
@@ -47,6 +48,8 @@ public:
 
   int NbNodes() const;
 
+  virtual SMDSAbs_EntityType GetEntityType() const { return SMDSEntity_Quad_Edge; }
+
   virtual bool IsQuadratic() const { return true; }
 
   virtual bool IsMediumNode(const SMDS_MeshNode* node) const;
index b981bd92f68be7168097e340fda17f730aaf9a21..6a70243c083ff3923812ab551e6ead4010a3159a 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 // File:      SMDS_QuadraticFaceOfNodes.cxx
 // Created:   16.01.06 17:12:58
@@ -48,6 +49,7 @@ SMDS_QuadraticFaceOfNodes::SMDS_QuadraticFaceOfNodes(const SMDS_MeshNode * n1,
                                                      const SMDS_MeshNode * n23,
                                                      const SMDS_MeshNode * n31)
 {
+  //MESSAGE("********************************************** SMDS_QuadraticFaceOfNodes 1");
   myNodes.resize( 6 );
   myNodes[ 0 ] = n1;
   myNodes[ 1 ] = n2;
@@ -72,6 +74,7 @@ SMDS_QuadraticFaceOfNodes::SMDS_QuadraticFaceOfNodes(const SMDS_MeshNode * n1,
                                                      const SMDS_MeshNode * n34,
                                                      const SMDS_MeshNode * n41)
 {
+  //MESSAGE("********************************************* SMDS_QuadraticFaceOfNodes 2");
   myNodes.resize( 8 );
   myNodes[ 0 ] = n1;
   myNodes[ 1 ] = n2;
@@ -255,7 +258,7 @@ public:
   _MyEdgeIterator(const SMDS_QuadraticFaceOfNodes* face):myIndex(0) {
     myElems.reserve( face->NbNodes() );
     SMDS_ElemIteratorPtr nIt = face->interlacedNodesElemIterator();
-    const SMDS_MeshNode* n0 = face->GetNode( -1 );
+    const SMDS_MeshNode* n0 = face->GetNodeWrap( -1 );
     while ( nIt->more() ) {
       const SMDS_MeshNode* n1 = static_cast<const SMDS_MeshNode*>( nIt->next() );
       const SMDS_MeshElement* edge = SMDS_Mesh::FindEdge( n0, n1 );
@@ -300,11 +303,13 @@ SMDS_ElemIteratorPtr SMDS_QuadraticFaceOfNodes::elementsIterator
  * \brief Return node by its index
  * \param ind - node index
  * \retval const SMDS_MeshNode* - the node
- * 
- * Index is wrapped if it is out of a valid range
  */
 const SMDS_MeshNode* SMDS_QuadraticFaceOfNodes::GetNode(const int ind) const
 {
-  return myNodes[ WrappedIndex( ind )];
+  return myNodes[ ind ];
 }
 
+SMDSAbs_EntityType SMDS_QuadraticFaceOfNodes::GetEntityType() const
+{
+  return NbNodes() == 6 ? SMDSEntity_Quad_Triangle : SMDSEntity_Quad_Quadrangle;
+}
index f4284918adbb68efb6deae5ad2921bb0983c6119..21c2a7e6b7162148312b80991abad8f7c43116e2 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_QuadraticVolumeOfNodes.hxx
 //  Module : SMESH
@@ -49,6 +50,7 @@ public:
                             const SMDS_MeshNode * n34,
                             const SMDS_MeshNode * n41);
 
+  virtual SMDSAbs_EntityType GetEntityType() const;
   virtual bool IsQuadratic() const { return true; }
 
   virtual bool IsMediumNode(const SMDS_MeshNode* node) const;
@@ -70,8 +72,6 @@ public:
    * \brief Return node by its index
     * \param ind - node index
     * \retval const SMDS_MeshNode* - the node
-   * 
-   * Index is wrapped if it is out of a valid range
    */
   virtual const SMDS_MeshNode* GetNode(const int ind) const;
 
index 4a0ae2e7e4cbb8cbfe5570a328d87eaefac5464c..579b3e420f29b179f858a245e7d7ae40f80ebcc7 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 // File:      SMDS_QuadraticVolumeOfNodes.cxx
 // Created:   17.01.06 09:46:11
@@ -53,6 +54,7 @@ SMDS_QuadraticVolumeOfNodes::SMDS_QuadraticVolumeOfNodes
                                                 const SMDS_MeshNode * n24,
                                                 const SMDS_MeshNode * n34)
 {
+  //MESSAGE("*********************************************** SMDS_QuadraticVolumeOfNodes");
   myNodes.resize( 10 );
   myNodes[ 0 ] = n1;
   myNodes[ 1 ] = n2;
@@ -87,6 +89,7 @@ SMDS_QuadraticVolumeOfNodes::SMDS_QuadraticVolumeOfNodes
                                                 const SMDS_MeshNode * n35,
                                                 const SMDS_MeshNode * n45)
 {
+  //MESSAGE("*********************************************** SMDS_QuadraticVolumeOfNodes");
   myNodes.resize( 13 );
   myNodes[ 0 ] = n1;
   myNodes[ 1 ] = n2;
@@ -126,6 +129,7 @@ SMDS_QuadraticVolumeOfNodes::SMDS_QuadraticVolumeOfNodes
                                                 const SMDS_MeshNode * n25,
                                                 const SMDS_MeshNode * n36)
 {
+  //MESSAGE("*********************************************** SMDS_QuadraticVolumeOfNodes");
   myNodes.resize( 15 );
   myNodes[ 0 ] = n1;
   myNodes[ 1 ] = n2;
@@ -172,6 +176,7 @@ SMDS_QuadraticVolumeOfNodes::SMDS_QuadraticVolumeOfNodes
                                                 const SMDS_MeshNode * n37,
                                                 const SMDS_MeshNode * n48)
 {
+  //MESSAGE("*********************************************** SMDS_QuadraticVolumeOfNodes");
   myNodes.resize( 20 );
   myNodes[ 0 ] = n1;
   myNodes[ 1 ] = n2;
@@ -362,11 +367,22 @@ SMDS_ElemIteratorPtr SMDS_QuadraticVolumeOfNodes::elementsIterator
  * \brief Return node by its index
  * \param ind - node index
  * \retval const SMDS_MeshNode* - the node
- * 
- * Index is wrapped if it is out of a valid range
  */
 const SMDS_MeshNode* SMDS_QuadraticVolumeOfNodes::GetNode(const int ind) const
 {
-  return myNodes[ WrappedIndex( ind )];
+  return myNodes[ ind ];
 }
 
+SMDSAbs_EntityType SMDS_QuadraticVolumeOfNodes::GetEntityType() const
+{
+  SMDSAbs_EntityType aType = SMDSEntity_Quad_Tetra;
+  switch(NbNodes())
+  {
+  case 10: aType = SMDSEntity_Quad_Tetra;   break;
+  case 13: aType = SMDSEntity_Quad_Pyramid; break;
+  case 15: aType = SMDSEntity_Quad_Penta;   break;
+  case 20:
+  default: aType = SMDSEntity_Quad_Hexa;    break;
+  }
+  return aType;
+}
index 34ce542a6d967154d407b7457a6d0247af8fc458..80312496c5f8e28a3f05ea732ebf663bad84f2b9 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_QuadraticVolumeOfNodes.hxx
 //  Module : SMESH
@@ -99,6 +100,7 @@ public:
                               const SMDS_MeshNode * n37,
                               const SMDS_MeshNode * n48);
 
+  virtual SMDSAbs_EntityType   GetEntityType() const;
   virtual bool IsQuadratic() const { return true; }
 
   virtual bool IsMediumNode(const SMDS_MeshNode* node) const;
@@ -116,8 +118,6 @@ public:
    * \brief Return node by its index
     * \param ind - node index
     * \retval const SMDS_MeshNode* - the node
-   * 
-   * Index is wrapped if it is out of a valid range
    */
   virtual const SMDS_MeshNode* GetNode(const int ind) const;
 
index e76ea8ce569927f86030f8701bdb67f93cfe75f4..a200bdd9fdba7e2f42bbd814b08f42a842a88aad 100644 (file)
@@ -1,27 +1,28 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 // File      : SMDS_SetIterator.hxx
-// Created   : Mon Feb 27 16:57:43 2006
+// Created   : Feb 27 2006
 // Author    : Edward AGAPOV (eap)
 //
 #ifndef SMDS_SetIterator_HeaderFile
 
 #include "SMDS_Iterator.hxx"
 
-///////////////////////////////////////////////////////////////////////////////
-/// Accessors to value pointed by iterator
-///////////////////////////////////////////////////////////////////////////////
-
 namespace SMDS {
 
+  ///////////////////////////////////////////////////////////////////////////////
+  /// Accessors to value pointed by iterator
+  ///////////////////////////////////////////////////////////////////////////////
+
   template<typename VALUE,typename VALUE_SET_ITERATOR>
   struct SimpleAccessor {
     static VALUE value(VALUE_SET_ITERATOR it) { return (VALUE) *it; }
@@ -49,6 +50,22 @@ namespace SMDS {
   struct ValueAccessor {
     static VALUE value(VALUE_SET_ITERATOR it) { return (VALUE) it->second; }
   };
+
+  ///////////////////////////////////////////////////////////////////////////////
+  /// Filters of value pointed by iterator
+  ///////////////////////////////////////////////////////////////////////////////
+
+  template <typename VALUE>
+  struct PassAllValueFilter
+  {
+    bool operator()(const VALUE& t ) { return true; }
+  };
+
+  template <typename VALUE>
+  struct NonNullFilter
+  {
+    bool operator()(const VALUE& t ) { return bool( t ); }
+  };
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -60,26 +77,43 @@ namespace SMDS {
 
 template<typename VALUE,
          typename VALUE_SET_ITERATOR,
-         typename ACCESOR=SMDS::SimpleAccessor<VALUE,VALUE_SET_ITERATOR> >
+         typename ACCESOR=SMDS::SimpleAccessor<VALUE,VALUE_SET_ITERATOR>,
+         typename VALUE_FILTER=SMDS::PassAllValueFilter<VALUE> >
 class SMDS_SetIterator : public SMDS_Iterator<VALUE>
 {
 protected:
   VALUE_SET_ITERATOR _beg, _end;
+  VALUE_FILTER _filter;
 public:
   SMDS_SetIterator(const VALUE_SET_ITERATOR & begin,
-                   const VALUE_SET_ITERATOR & end)
-  { init ( begin, end ); }
+                   const VALUE_SET_ITERATOR & end,
+                   const VALUE_FILTER&        filter=VALUE_FILTER())
+  { init ( begin, end, filter ); }
 
   /// Initialization
   virtual void init(const VALUE_SET_ITERATOR & begin,
-                    const VALUE_SET_ITERATOR & end)
-  { _beg = begin; _end = end; }
-
-  /// Return true if and only if there are other object in this iterator
-  virtual bool more() { return _beg != _end; }
-
+                    const VALUE_SET_ITERATOR & end,
+                    const VALUE_FILTER&        filter=VALUE_FILTER())
+  {
+    _beg = begin;
+    _end = end;
+    _filter = filter;
+    if ( more() && !_filter( ACCESOR::value( _beg )))
+      next();
+  }
+  /// Return true iff there are other object in this iterator
+  virtual bool more()
+  {
+    return _beg != _end;
+  }
   /// Return the current object and step to the next one
-  virtual VALUE next() { return ACCESOR::value( _beg++ ); }
+  virtual VALUE next()
+  {
+    VALUE ret = ACCESOR::value( _beg++ );
+    while ( more() && !_filter( ACCESOR::value( _beg )))
+      ++_beg;
+    return ret;
+  }
 };
 
 ///////////////////////////////////////////////////////////////////////////////
index 09532f3476bce08f60fbf6bade8028391ebeff6d..422de6a3fdf07b9ef72c65874580e99c4b150146 100644 (file)
@@ -1,58 +1,45 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_SpacePosition.cxx
 //  Author : Jean-Michel BOULCOURT
 //  Module : SMESH
 //
+
 #include "SMDS_SpacePosition.hxx"
 
-//=======================================================================
-//function : SMDS_SpacePosition
-//purpose  : 
-//=======================================================================
+SMDS_SpacePosition* SMDS_SpacePosition::_originPosition = new SMDS_SpacePosition();
 
-SMDS_SpacePosition::SMDS_SpacePosition(double x, double y, double z):
-       SMDS_Position(0)
+SMDS_SpacePosition::SMDS_SpacePosition(double x, double y, double z)
 {
-       myCoords[0]=x;
-       myCoords[1]=y;
-       myCoords[2]=z;
 }
 
-/**
-*/
 SMDS_TypeOfPosition SMDS_SpacePosition::GetTypeOfPosition() const
 {
-       return SMDS_TOP_3DSPACE;
-}
-
-const double * SMDS_SpacePosition::Coords() const
-{
-       return myCoords;
+  return SMDS_TOP_3DSPACE;
 }
 
 SMDS_PositionPtr SMDS_SpacePosition::originSpacePosition()
 {
-  static SMDS_PositionPtr staticpos (new SMDS_SpacePosition());
-  return staticpos;
+  return _originPosition;
 }
index f80f3210af374672a29b5d29caf29c38134f8da7..1313ed5cc2d1c21f7938defbd646396700416ebc 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_SpacePosition.hxx
 //  Module : SMESH
 class SMDS_EXPORT SMDS_SpacePosition:public SMDS_Position
 {
 
-  public:
-       SMDS_SpacePosition(double x=0, double y=0, double z=0);
-       const virtual double * Coords() const;
-       virtual inline SMDS_TypeOfPosition GetTypeOfPosition() const;
-       inline void SetCoords(const double x, const double y, const double z);
-        static SMDS_PositionPtr originSpacePosition();
-  private:
-       double myCoords[3];     
+public:
+  SMDS_SpacePosition(double x=0, double y=0, double z=0);
+  virtual inline SMDS_TypeOfPosition GetTypeOfPosition() const;
+  static SMDS_PositionPtr originSpacePosition();
+private:
+  static SMDS_SpacePosition* _originPosition;
 };
 
 #endif
diff --git a/src/SMDS/SMDS_StdIterator.hxx b/src/SMDS/SMDS_StdIterator.hxx
new file mode 100644 (file)
index 0000000..f09647f
--- /dev/null
@@ -0,0 +1,80 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+//  SMESH SMDS : implementaion of Salome mesh data structure
+// File      : SMDS_StdIterator.hxx
+// Created   : Fri Feb  5 11:03:46 2010
+// Author    : Edward AGAPOV (eap)
+//
+#ifndef __SMDS_StdIterator_HXX__
+#define __SMDS_StdIterator_HXX__
+
+
+///////////////////////////////////////////////////////////////////////////////
+/*!
+ * \brief Wrapper over pointer to SMDS_Iterator, like SMDS_ElemIteratorPtr, enabling
+ *   its usage in std-like way: provide operators ++, *,  etc.
+ */
+///////////////////////////////////////////////////////////////////////////////
+
+template<typename VALUE, class PtrSMDSIterator, class EqualVALUE = std::equal_to<VALUE> >
+class SMDS_StdIterator : public std::iterator< std::input_iterator_tag, VALUE >
+{
+  VALUE           _value;
+  PtrSMDSIterator _piterator;
+  EqualVALUE      _EqualVALUE;
+
+public:
+  typedef SMDS_StdIterator<VALUE, PtrSMDSIterator> _Self;
+
+  // constructor to use as return from begin()
+  SMDS_StdIterator( PtrSMDSIterator pItr )
+    : _value( pItr->more() ? (VALUE)(pItr->next()) : 0 ), _piterator(pItr)
+  {}
+  // constructor to use as return from end()
+  SMDS_StdIterator(): _value( 0 )
+  {}
+
+  /// Return the current object
+  VALUE operator*() const
+  { return _value; }
+
+  //  Step to the next one
+  _Self&
+  operator++()
+  { _value = _piterator->more() ? VALUE( _piterator->next()) : 0; return *this; }
+
+  //  Step to the next one
+  _Self
+  operator++(int)
+  { _Self res = *this; _value = _piterator->more() ? VALUE( _piterator->next()) : 0; return res; }
+
+  // Test of end
+  bool
+  operator!=(const _Self& __x) const
+  { return !_EqualVALUE( _value, __x._value); }
+
+  // Test of equality
+  bool
+  operator==(const _Self& __x) const
+  { return _EqualVALUE( _value, __x._value); }
+
+};
+
+#endif
index da5b39c48eabe832344c15f4d424f11b7c507716..c1c7249b488c6c82c38d1f77803fa6178ab63e95 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_TypeOfPosition.hxx
 //  Module : SMESH
 
 enum SMDS_TypeOfPosition // Value is equal to shape dimention
 {
-       SMDS_TOP_UNSPEC  = -1,
-       SMDS_TOP_VERTEX  = 0,
-       SMDS_TOP_EDGE    = 1,
-       SMDS_TOP_FACE    = 2,
-       SMDS_TOP_3DSPACE = 3
+        SMDS_TOP_UNSPEC  = -1,
+        SMDS_TOP_VERTEX  = 0,
+        SMDS_TOP_EDGE    = 1,
+        SMDS_TOP_FACE    = 2,
+        SMDS_TOP_3DSPACE = 3
 };
 
 #endif
diff --git a/src/SMDS/SMDS_UnstructuredGrid.cxx b/src/SMDS/SMDS_UnstructuredGrid.cxx
new file mode 100644 (file)
index 0000000..0d9b1e6
--- /dev/null
@@ -0,0 +1,1145 @@
+// Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+#define CHRONODEF
+#include "SMDS_UnstructuredGrid.hxx"
+#include "SMDS_Mesh.hxx"
+#include "SMDS_MeshInfo.hxx"
+#include "SMDS_Downward.hxx"
+#include "SMDS_MeshVolume.hxx"
+
+#include "utilities.h"
+
+#include <vtkCellArray.h>
+#include <vtkCellData.h>
+#include <vtkCellLinks.h>
+#include <vtkDoubleArray.h>
+#include <vtkIdTypeArray.h>
+#include <vtkUnsignedCharArray.h>
+
+#include <list>
+#include <climits>
+
+using namespace std;
+
+SMDS_CellLinks* SMDS_CellLinks::New()
+{
+  MESSAGE("SMDS_CellLinks::New");
+  return new SMDS_CellLinks();
+}
+
+vtkCellLinks::Link* SMDS_CellLinks::ResizeL(vtkIdType sz)
+{
+  return vtkCellLinks::Resize(sz);
+}
+
+vtkIdType SMDS_CellLinks::GetLinksSize()
+{
+  return this->Size;
+}
+
+SMDS_CellLinks::SMDS_CellLinks() :
+  vtkCellLinks()
+{
+}
+
+SMDS_CellLinks::~SMDS_CellLinks()
+{
+}
+
+SMDS_UnstructuredGrid* SMDS_UnstructuredGrid::New()
+{
+  MESSAGE("SMDS_UnstructuredGrid::New");
+  return new SMDS_UnstructuredGrid();
+}
+
+SMDS_UnstructuredGrid::SMDS_UnstructuredGrid() :
+  vtkUnstructuredGrid()
+{
+  _cellIdToDownId.clear();
+  _downTypes.clear();
+  _downArray.clear();
+  _mesh = 0;
+}
+
+SMDS_UnstructuredGrid::~SMDS_UnstructuredGrid()
+{
+}
+
+unsigned long SMDS_UnstructuredGrid::GetMTime()
+{
+  unsigned long mtime = vtkUnstructuredGrid::GetMTime();
+  MESSAGE("vtkUnstructuredGrid::GetMTime: " << mtime);
+  return mtime;
+}
+
+void SMDS_UnstructuredGrid::Update()
+{
+  MESSAGE("SMDS_UnstructuredGrid::Update");
+  return vtkUnstructuredGrid::Update();
+}
+
+void SMDS_UnstructuredGrid::UpdateInformation()
+{
+  MESSAGE("SMDS_UnstructuredGrid::UpdateInformation");
+  return vtkUnstructuredGrid::UpdateInformation();
+}
+
+vtkPoints* SMDS_UnstructuredGrid::GetPoints()
+{
+  // TODO erreur incomprehensible de la macro vtk GetPoints apparue avec la version paraview de fin aout 2010
+  //MESSAGE("*********************** SMDS_UnstructuredGrid::GetPoints " << this->Points << " " << vtkUnstructuredGrid::GetPoints());
+  return this->Points;
+}
+
+//#ifdef VTK_HAVE_POLYHEDRON
+int SMDS_UnstructuredGrid::InsertNextLinkedCell(int type, int npts, vtkIdType *pts)
+{
+  if (type != VTK_POLYHEDRON)
+    return vtkUnstructuredGrid::InsertNextLinkedCell(type, npts, pts);
+
+  // --- type = VTK_POLYHEDRON
+  //MESSAGE("InsertNextLinkedCell VTK_POLYHEDRON");
+  int cellid = this->InsertNextCell(type, npts, pts);
+
+  set<vtkIdType> setOfNodes;
+  setOfNodes.clear();
+  int nbfaces = npts;
+  int i = 0;
+  for (int nf = 0; nf < nbfaces; nf++)
+    {
+      int nbnodes = pts[i];
+      i++;
+      for (int k = 0; k < nbnodes; k++)
+        {
+          //MESSAGE(" cell " << cellid << " face " << nf << " node " << pts[i]);
+          setOfNodes.insert(pts[i]);
+          i++;
+        }
+    }
+
+  set<vtkIdType>::iterator it = setOfNodes.begin();
+  for (; it != setOfNodes.end(); ++it)
+    {
+      //MESSAGE("reverse link for node " << *it << " cell " << cellid);
+      this->Links->ResizeCellList(*it, 1);
+      this->Links->AddCellReference(cellid, *it);
+    }
+
+  return cellid;
+}
+//#endif
+
+void SMDS_UnstructuredGrid::setSMDS_mesh(SMDS_Mesh *mesh)
+{
+  _mesh = mesh;
+}
+
+void SMDS_UnstructuredGrid::compactGrid(std::vector<int>& idNodesOldToNew, int newNodeSize,
+                                        std::vector<int>& idCellsOldToNew, int newCellSize)
+{
+  MESSAGE("------------------------- SMDS_UnstructuredGrid::compactGrid " << newNodeSize << " " << newCellSize);CHRONO(1);
+  int alreadyCopied = 0;
+
+  // --- if newNodeSize, create a new compacted vtkPoints
+
+  vtkPoints *newPoints = vtkPoints::New();
+  newPoints->SetDataType(VTK_DOUBLE);
+  newPoints->SetNumberOfPoints(newNodeSize);
+  if (newNodeSize)
+    {
+      MESSAGE("-------------- compactGrid, newNodeSize " << newNodeSize);
+      // rnv: to fix bug "21125: EDF 1233 SMESH: Degradation of precision in a test case for quadratic conversion"
+      // using double type for storing coordinates of nodes instead float.
+      int oldNodeSize = idNodesOldToNew.size();
+
+      int i = 0;
+      while ( i < oldNodeSize )
+      {
+        // skip a hole if any
+        while ( i < oldNodeSize && idNodesOldToNew[i] < 0 )
+          ++i;
+        int startBloc = i;
+        // look for a block end
+        while ( i < oldNodeSize && idNodesOldToNew[i] >= 0 )
+          ++i;
+        int endBloc = i;
+        copyNodes(newPoints, idNodesOldToNew, alreadyCopied, startBloc, endBloc);
+      }
+      newPoints->Squeeze();
+    }
+
+  // --- create new compacted Connectivity, Locations and Types
+
+  int oldCellSize = this->Types->GetNumberOfTuples();
+
+  vtkCellArray *newConnectivity = vtkCellArray::New();
+  newConnectivity->Initialize();
+  int oldCellDataSize = this->Connectivity->GetData()->GetSize();
+  newConnectivity->Allocate(oldCellDataSize);
+  MESSAGE("oldCellSize="<< oldCellSize << " oldCellDataSize=" << oldCellDataSize);
+
+  vtkUnsignedCharArray *newTypes = vtkUnsignedCharArray::New();
+  newTypes->Initialize();
+  newTypes->SetNumberOfValues(newCellSize);
+
+  vtkIdTypeArray *newLocations = vtkIdTypeArray::New();
+  newLocations->Initialize();
+  newLocations->SetNumberOfValues(newCellSize);
+
+  // TODO some polyhedron may be huge (only in some tests)
+  vtkIdType tmpid[NBMAXNODESINCELL];
+  vtkIdType *pointsCell = &tmpid[0]; // --- points id to fill a new cell
+
+  alreadyCopied = 0;
+  int i = 0;
+  while ( i < oldCellSize )
+  {
+    // skip a hole if any
+    while ( i < oldCellSize && this->Types->GetValue(i) == VTK_EMPTY_CELL )
+      ++i;
+    int startBloc = i;
+    // look for a block end
+    while ( i < oldCellSize && this->Types->GetValue(i) != VTK_EMPTY_CELL )
+      ++i;
+    int endBloc = i;
+    if ( endBloc > startBloc )
+      copyBloc(newTypes,
+               idCellsOldToNew, idNodesOldToNew,
+               newConnectivity, newLocations,
+               pointsCell, alreadyCopied,
+               startBloc, endBloc);
+  }
+  newConnectivity->Squeeze();
+
+  if (1/*newNodeSize*/)
+    {
+      MESSAGE("------- newNodeSize, setPoints");
+      this->SetPoints(newPoints);
+      MESSAGE("NumberOfPoints: " << this->GetNumberOfPoints());
+    }
+
+  if (vtkDoubleArray* diameters =
+      vtkDoubleArray::SafeDownCast( vtkDataSet::CellData->GetScalars() )) // Balls
+  {
+    for (int oldCellID = 0; oldCellID < oldCellSize; oldCellID++)
+    {
+      if (this->Types->GetValue(oldCellID) == VTK_EMPTY_CELL)
+        continue;
+      int newCellId = idCellsOldToNew[ oldCellID ];
+      if (newTypes->GetValue(newCellId) == VTK_POLY_VERTEX)
+        diameters->SetValue( newCellId, diameters->GetValue( oldCellID ));
+    }
+  }
+
+  if (this->FaceLocations)
+    {
+      vtkIdTypeArray *newFaceLocations = vtkIdTypeArray::New();
+      newFaceLocations->Initialize();
+      newFaceLocations->Allocate(newTypes->GetSize());
+      vtkIdTypeArray *newFaces = vtkIdTypeArray::New();
+      newFaces->Initialize();
+      newFaces->Allocate(this->Faces->GetSize());
+      for (int i = 0; i < oldCellSize; i++)
+        {
+          if (this->Types->GetValue(i) == VTK_EMPTY_CELL)
+            continue;
+          int newCellId = idCellsOldToNew[i];
+          if (newTypes->GetValue(newCellId) == VTK_POLYHEDRON)
+            {
+               newFaceLocations->InsertNextValue(newFaces->GetMaxId()+1);
+               int oldFaceLoc = this->FaceLocations->GetValue(i);
+               int nCellFaces = this->Faces->GetValue(oldFaceLoc++);
+               newFaces->InsertNextValue(nCellFaces);
+               for (int n=0; n<nCellFaces; n++)
+                 {
+                   int nptsInFace = this->Faces->GetValue(oldFaceLoc++);
+                   newFaces->InsertNextValue(nptsInFace);
+                   for (int k=0; k<nptsInFace; k++)
+                     {
+                       int oldpt = this->Faces->GetValue(oldFaceLoc++);
+                       newFaces->InsertNextValue(idNodesOldToNew[oldpt]);
+                     }
+                 }
+            }
+          else
+            {
+               newFaceLocations->InsertNextValue(-1);
+            }
+        }
+      newFaceLocations->Squeeze();
+      newFaces->Squeeze();
+      newFaceLocations->Register(this);
+      newFaces->Register(this);
+      this->SetCells(newTypes, newLocations, newConnectivity, newFaceLocations, newFaces);
+      newFaceLocations->Delete();
+      newFaces->Delete();
+    }
+  else
+  {
+    this->SetCells(newTypes, newLocations, newConnectivity, FaceLocations, Faces);
+  }
+
+  newPoints->Delete();
+  newTypes->Delete();
+  newLocations->Delete();
+  newConnectivity->Delete();
+  this->BuildLinks();
+}
+
+void SMDS_UnstructuredGrid::copyNodes(vtkPoints *newPoints, std::vector<int>& idNodesOldToNew, int& alreadyCopied,
+                                      int start, int end)
+{
+  MESSAGE("copyNodes " << alreadyCopied << " " << start << " " << end << " size: " << end - start << " total: " << alreadyCopied + end - start);
+  void *target = newPoints->GetVoidPointer(3 * alreadyCopied);
+  void *source = this->Points->GetVoidPointer(3 * start);
+  int nbPoints = end - start;
+  if (nbPoints > 0)
+    {
+      memcpy(target, source, 3 * sizeof(double) * nbPoints);
+      for (int j = start; j < end; j++)
+        idNodesOldToNew[j] = alreadyCopied++; // old vtkId --> new vtkId
+    }
+}
+
+void SMDS_UnstructuredGrid::copyBloc(vtkUnsignedCharArray *newTypes,
+                                     std::vector<int>&     idCellsOldToNew,
+                                     std::vector<int>&     idNodesOldToNew,
+                                     vtkCellArray*         newConnectivity,
+                                     vtkIdTypeArray*       newLocations,
+                                     vtkIdType*            pointsCell,
+                                     int&                  alreadyCopied,
+                                     int                   start,
+                                     int                   end)
+{
+  MESSAGE("copyBloc " << alreadyCopied << " " << start << " " << end << " size: " << end - start << " total: " << alreadyCopied + end - start);
+  for (int j = start; j < end; j++)
+    {
+      newTypes->SetValue(alreadyCopied, this->Types->GetValue(j));
+      idCellsOldToNew[j] = alreadyCopied; // old vtkId --> new vtkId
+      vtkIdType oldLoc = this->Locations->GetValue(j);
+      vtkIdType nbpts;
+      vtkIdType *oldPtsCell = 0;
+      this->Connectivity->GetCell(oldLoc, nbpts, oldPtsCell);
+      assert(nbpts < NBMAXNODESINCELL);
+      //MESSAGE(j << " " << alreadyCopied << " " << (int)this->Types->GetValue(j) << " " << oldLoc << " " << nbpts );
+      for (int l = 0; l < nbpts; l++)
+        {
+          int oldval = oldPtsCell[l];
+          pointsCell[l] = idNodesOldToNew[oldval];
+          //MESSAGE("   " << oldval << " " << pointsCell[l]);
+        }
+      /*int newcnt = */newConnectivity->InsertNextCell(nbpts, pointsCell);
+      int newLoc = newConnectivity->GetInsertLocation(nbpts);
+      //MESSAGE(newcnt << " " << newLoc);
+      newLocations->SetValue(alreadyCopied, newLoc);
+      alreadyCopied++;
+    }
+}
+
+int SMDS_UnstructuredGrid::CellIdToDownId(int vtkCellId)
+{
+  if((vtkCellId < 0) || (vtkCellId >= _cellIdToDownId.size()))
+    {
+      //MESSAGE("SMDS_UnstructuredGrid::CellIdToDownId structure not up to date: vtkCellId="
+      //    << vtkCellId << " max="<< _cellIdToDownId.size());
+      return -1;
+    }
+  return _cellIdToDownId[vtkCellId];
+}
+
+void SMDS_UnstructuredGrid::setCellIdToDownId(int vtkCellId, int downId)
+{
+  // ASSERT((vtkCellId >= 0) && (vtkCellId < _cellIdToDownId.size()));
+  _cellIdToDownId[vtkCellId] = downId;
+}
+
+void SMDS_UnstructuredGrid::CleanDownwardConnectivity()
+{
+  for (int i = 0; i < _downArray.size(); i++)
+    {
+      if (_downArray[i])
+        delete _downArray[i];
+      _downArray[i] = 0;
+    }
+  _cellIdToDownId.clear();
+}
+
+/*! Build downward connectivity: to do only when needed because heavy memory load.
+ *  Downward connectivity is no more valid if vtkUnstructuredGrid is modified.
+ *
+ */
+void SMDS_UnstructuredGrid::BuildDownwardConnectivity(bool withEdges)
+{
+  MESSAGE("SMDS_UnstructuredGrid::BuildDownwardConnectivity");CHRONO(2);
+  // TODO calcul partiel sans edges
+
+  // --- erase previous data if any
+
+  this->CleanDownwardConnectivity();
+
+  // --- create SMDS_Downward structures (in _downArray vector[vtkCellType])
+
+  _downArray.resize(VTK_MAXTYPE + 1, 0);
+
+  _downArray[VTK_LINE]                    = new SMDS_DownEdge(this);
+  _downArray[VTK_QUADRATIC_EDGE]          = new SMDS_DownQuadEdge(this);
+  _downArray[VTK_TRIANGLE]                = new SMDS_DownTriangle(this);
+  _downArray[VTK_QUADRATIC_TRIANGLE]      = new SMDS_DownQuadTriangle(this);
+  _downArray[VTK_QUAD]                    = new SMDS_DownQuadrangle(this);
+  _downArray[VTK_QUADRATIC_QUAD]          = new SMDS_DownQuadQuadrangle(this);
+  _downArray[VTK_BIQUADRATIC_QUAD]        = new SMDS_DownQuadQuadrangle(this);
+  _downArray[VTK_TETRA]                   = new SMDS_DownTetra(this);
+  _downArray[VTK_QUADRATIC_TETRA]         = new SMDS_DownQuadTetra(this);
+  _downArray[VTK_PYRAMID]                 = new SMDS_DownPyramid(this);
+  _downArray[VTK_QUADRATIC_PYRAMID]       = new SMDS_DownQuadPyramid(this);
+  _downArray[VTK_WEDGE]                   = new SMDS_DownPenta(this);
+  _downArray[VTK_QUADRATIC_WEDGE]         = new SMDS_DownQuadPenta(this);
+  _downArray[VTK_HEXAHEDRON]              = new SMDS_DownHexa(this);
+  _downArray[VTK_QUADRATIC_HEXAHEDRON]    = new SMDS_DownQuadHexa(this);
+  _downArray[VTK_TRIQUADRATIC_HEXAHEDRON] = new SMDS_DownQuadHexa(this);
+  _downArray[VTK_HEXAGONAL_PRISM]         = new SMDS_DownPenta(this);
+
+  // --- get detailed info of number of cells of each type, allocate SMDS_downward structures
+
+  const SMDS_MeshInfo &meshInfo = _mesh->GetMeshInfo();
+
+  int nbLinTetra  = meshInfo.NbTetras  (ORDER_LINEAR);
+  int nbQuadTetra = meshInfo.NbTetras  (ORDER_QUADRATIC);
+  int nbLinPyra   = meshInfo.NbPyramids(ORDER_LINEAR);
+  int nbQuadPyra  = meshInfo.NbPyramids(ORDER_QUADRATIC);
+  int nbLinPrism  = meshInfo.NbPrisms  (ORDER_LINEAR);
+  int nbQuadPrism = meshInfo.NbPrisms  (ORDER_QUADRATIC);
+  int nbLinHexa   = meshInfo.NbHexas   (ORDER_LINEAR);
+  int nbQuadHexa  = meshInfo.NbHexas   (ORDER_QUADRATIC);
+  int nbHexPrism  = meshInfo.NbHexPrisms();
+
+  int nbLineGuess     = int((4.0 / 3.0) * nbLinTetra + 2 * nbLinPrism + 2.5 * nbLinPyra + 3 * nbLinHexa);
+  int nbQuadEdgeGuess = int((4.0 / 3.0) * nbQuadTetra + 2 * nbQuadPrism + 2.5 * nbQuadPyra + 3 * nbQuadHexa);
+  int nbLinTriaGuess  = 2 * nbLinTetra + nbLinPrism + 2 * nbLinPyra;
+  int nbQuadTriaGuess = 2 * nbQuadTetra + nbQuadPrism + 2 * nbQuadPyra;
+  int nbLinQuadGuess  = int((2.0 / 3.0) * nbLinPrism + (1.0 / 2.0) * nbLinPyra + 3 * nbLinHexa);
+  int nbQuadQuadGuess = int((2.0 / 3.0) * nbQuadPrism + (1.0 / 2.0) * nbQuadPyra + 3 * nbQuadHexa);
+
+  int GuessSize[VTK_MAXTYPE];
+  GuessSize[VTK_LINE]                    = nbLineGuess;
+  GuessSize[VTK_QUADRATIC_EDGE]          = nbQuadEdgeGuess;
+  GuessSize[VTK_TRIANGLE]                = nbLinTriaGuess;
+  GuessSize[VTK_QUADRATIC_TRIANGLE]      = nbQuadTriaGuess;
+  GuessSize[VTK_QUAD]                    = nbLinQuadGuess;
+  GuessSize[VTK_QUADRATIC_QUAD]          = nbQuadQuadGuess;
+  GuessSize[VTK_BIQUADRATIC_QUAD]        = nbQuadQuadGuess;
+  GuessSize[VTK_TETRA]                   = nbLinTetra;
+  GuessSize[VTK_QUADRATIC_TETRA]         = nbQuadTetra;
+  GuessSize[VTK_PYRAMID]                 = nbLinPyra;
+  GuessSize[VTK_QUADRATIC_PYRAMID]       = nbQuadPyra;
+  GuessSize[VTK_WEDGE]                   = nbLinPrism;
+  GuessSize[VTK_QUADRATIC_WEDGE]         = nbQuadPrism;
+  GuessSize[VTK_HEXAHEDRON]              = nbLinHexa;
+  GuessSize[VTK_QUADRATIC_HEXAHEDRON]    = nbQuadHexa;
+  GuessSize[VTK_TRIQUADRATIC_HEXAHEDRON] = nbQuadHexa;
+  GuessSize[VTK_HEXAGONAL_PRISM]         = nbHexPrism;
+
+  _downArray[VTK_LINE]                   ->allocate(nbLineGuess);
+  _downArray[VTK_QUADRATIC_EDGE]         ->allocate(nbQuadEdgeGuess);
+  _downArray[VTK_TRIANGLE]               ->allocate(nbLinTriaGuess);
+  _downArray[VTK_QUADRATIC_TRIANGLE]     ->allocate(nbQuadTriaGuess);
+  _downArray[VTK_QUAD]                   ->allocate(nbLinQuadGuess);
+  _downArray[VTK_QUADRATIC_QUAD]         ->allocate(nbQuadQuadGuess);
+  _downArray[VTK_BIQUADRATIC_QUAD]       ->allocate(nbQuadQuadGuess);
+  _downArray[VTK_TETRA]                  ->allocate(nbLinTetra);
+  _downArray[VTK_QUADRATIC_TETRA]        ->allocate(nbQuadTetra);
+  _downArray[VTK_PYRAMID]                ->allocate(nbLinPyra);
+  _downArray[VTK_QUADRATIC_PYRAMID]      ->allocate(nbQuadPyra);
+  _downArray[VTK_WEDGE]                  ->allocate(nbLinPrism);
+  _downArray[VTK_QUADRATIC_WEDGE]        ->allocate(nbQuadPrism);
+  _downArray[VTK_HEXAHEDRON]             ->allocate(nbLinHexa);
+  _downArray[VTK_QUADRATIC_HEXAHEDRON]   ->allocate(nbQuadHexa);
+  _downArray[VTK_TRIQUADRATIC_HEXAHEDRON]->allocate(nbQuadHexa);
+  _downArray[VTK_HEXAGONAL_PRISM]        ->allocate(nbHexPrism);
+
+  // --- iteration on vtkUnstructuredGrid cells, only faces
+  //     for each vtk face:
+  //       create a downward face entry with its downward id.
+  //       compute vtk volumes, create downward volumes entry.
+  //       mark face in downward volumes
+  //       mark volumes in downward face
+
+  MESSAGE("--- iteration on vtkUnstructuredGrid cells, only faces");CHRONO(20);
+  int cellSize = this->Types->GetNumberOfTuples();
+  _cellIdToDownId.resize(cellSize, -1);
+
+  for (int i = 0; i < cellSize; i++)
+    {
+      int vtkFaceType = this->GetCellType(i);
+      if (SMDS_Downward::getCellDimension(vtkFaceType) == 2)
+        {
+          int vtkFaceId = i;
+          //ASSERT(_downArray[vtkFaceType]);
+          int connFaceId = _downArray[vtkFaceType]->addCell(vtkFaceId);
+          SMDS_Down2D* downFace = static_cast<SMDS_Down2D*> (_downArray[vtkFaceType]);
+          downFace->setTempNodes(connFaceId, vtkFaceId);
+          int vols[2] = { -1, -1 };
+          int nbVolumes = downFace->computeVolumeIds(vtkFaceId, vols);
+          //MESSAGE("nbVolumes="<< nbVolumes);
+          for (int ivol = 0; ivol < nbVolumes; ivol++)
+            {
+              int vtkVolId = vols[ivol];
+              int vtkVolType = this->GetCellType(vtkVolId);
+              //ASSERT(_downArray[vtkVolType]);
+              int connVolId = _downArray[vtkVolType]->addCell(vtkVolId);
+              _downArray[vtkVolType]->addDownCell(connVolId, connFaceId, vtkFaceType);
+              _downArray[vtkFaceType]->addUpCell(connFaceId, connVolId, vtkVolType);
+              // MESSAGE("Face " << vtkFaceId << " belongs to volume " << vtkVolId);
+            }
+        }
+    }
+
+  // --- iteration on vtkUnstructuredGrid cells, only volumes
+  //     for each vtk volume:
+  //       create downward volumes entry if not already done
+  //       build a temporary list of faces described with their nodes
+  //       for each face
+  //         compute the vtk volumes containing this face
+  //         check if the face is already listed in the volumes (comparison of ordered list of nodes)
+  //         if not, create a downward face entry (resizing of structure required)
+  //         (the downward faces store a temporary list of nodes to ease the comparison)
+  //         create downward volumes entry if not already done
+  //         mark volumes in downward face
+  //         mark face in downward volumes
+
+  CHRONOSTOP(20);
+  MESSAGE("--- iteration on vtkUnstructuredGrid cells, only volumes");CHRONO(21);
+
+  for (int i = 0; i < cellSize; i++)
+    {
+      int vtkType = this->GetCellType(i);
+      if (SMDS_Downward::getCellDimension(vtkType) == 3)
+        {
+          //CHRONO(31);
+          int vtkVolId = i;
+          // MESSAGE("vtk volume " << vtkVolId);
+          //ASSERT(_downArray[vtkType]);
+          /*int connVolId = */_downArray[vtkType]->addCell(vtkVolId);
+
+          // --- find all the faces of the volume, describe the faces by their nodes
+
+          SMDS_Down3D* downVol = static_cast<SMDS_Down3D*> (_downArray[vtkType]);
+          ListElemByNodesType facesWithNodes;
+          downVol->computeFacesWithNodes(vtkVolId, facesWithNodes);
+          // MESSAGE("vtk volume " << vtkVolId << " contains " << facesWithNodes.nbElems << " faces");
+          //CHRONOSTOP(31);
+          for (int iface = 0; iface < facesWithNodes.nbElems; iface++)
+            {
+              // --- find the volumes containing the face
+
+              //CHRONO(32);
+              int vtkFaceType = facesWithNodes.elems[iface].vtkType;
+              SMDS_Down2D* downFace = static_cast<SMDS_Down2D*> (_downArray[vtkFaceType]);
+              int vols[2] = { -1, -1 };
+              int *nodes = &facesWithNodes.elems[iface].nodeIds[0];
+              int lg = facesWithNodes.elems[iface].nbNodes;
+              int nbVolumes = downFace->computeVolumeIdsFromNodesFace(nodes, lg, vols);
+              // MESSAGE("vtk volume " << vtkVolId << " face " << iface << " belongs to " << nbVolumes << " volumes");
+
+              // --- check if face is registered in the volumes
+              //CHRONOSTOP(32);
+
+              //CHRONO(33);
+              int connFaceId = -1;
+              for (int ivol = 0; ivol < nbVolumes; ivol++)
+                {
+                  int vtkVolId2 = vols[ivol];
+                  int vtkVolType = this->GetCellType(vtkVolId2);
+                  //ASSERT(_downArray[vtkVolType]);
+                  int connVolId2 = _downArray[vtkVolType]->addCell(vtkVolId2);
+                  SMDS_Down3D* downVol2 = static_cast<SMDS_Down3D*> (_downArray[vtkVolType]);
+                  connFaceId = downVol2->FindFaceByNodes(connVolId2, facesWithNodes.elems[iface]);
+                  if (connFaceId >= 0)
+                    break; // --- face already created
+                }//CHRONOSTOP(33);
+
+              // --- if face is not registered in the volumes, create face
+
+              //CHRONO(34);
+              if (connFaceId < 0)
+                {
+                  connFaceId = _downArray[vtkFaceType]->addCell();
+                  downFace->setTempNodes(connFaceId, facesWithNodes.elems[iface]);
+                }//CHRONOSTOP(34);
+
+              // --- mark volumes in downward face and mark face in downward volumes
+
+              //CHRONO(35);
+              for (int ivol = 0; ivol < nbVolumes; ivol++)
+                {
+                  int vtkVolId2 = vols[ivol];
+                  int vtkVolType = this->GetCellType(vtkVolId2);
+                  //ASSERT(_downArray[vtkVolType]);
+                  int connVolId2 = _downArray[vtkVolType]->addCell(vtkVolId2);
+                  _downArray[vtkVolType]->addDownCell(connVolId2, connFaceId, vtkFaceType);
+                  _downArray[vtkFaceType]->addUpCell(connFaceId, connVolId2, vtkVolType);
+                  // MESSAGE(" From volume " << vtkVolId << " face " << connFaceId << " belongs to volume " << vtkVolId2);
+                }//CHRONOSTOP(35);
+            }
+        }
+    }
+
+  // --- iteration on vtkUnstructuredGrid cells, only edges
+  //     for each vtk edge:
+  //       create downward edge entry
+  //       store the nodes id's in downward edge (redundant with vtkUnstructuredGrid)
+  //       find downward faces
+  //       (from vtk faces or volumes, get downward faces, they have a temporary list of nodes)
+  //       mark edge in downward faces
+  //       mark faces in downward edge
+
+  CHRONOSTOP(21);
+  MESSAGE("--- iteration on vtkUnstructuredGrid cells, only edges");CHRONO(22);
+
+  for (int i = 0; i < cellSize; i++)
+    {
+      int vtkEdgeType = this->GetCellType(i);
+      if (SMDS_Downward::getCellDimension(vtkEdgeType) == 1)
+        {
+          int vtkEdgeId = i;
+          //ASSERT(_downArray[vtkEdgeType]);
+          int connEdgeId = _downArray[vtkEdgeType]->addCell(vtkEdgeId);
+          SMDS_Down1D* downEdge = static_cast<SMDS_Down1D*> (_downArray[vtkEdgeType]);
+          downEdge->setNodes(connEdgeId, vtkEdgeId);
+          vector<int> vtkIds;
+          int nbVtkCells = downEdge->computeVtkCells(connEdgeId, vtkIds);
+          int downFaces[1000];
+          unsigned char downTypes[1000];
+          int nbDownFaces = downEdge->computeFaces(connEdgeId, &vtkIds[0], nbVtkCells, downFaces, downTypes);
+          for (int n = 0; n < nbDownFaces; n++)
+            {
+              _downArray[downTypes[n]]->addDownCell(downFaces[n], connEdgeId, vtkEdgeType);
+              _downArray[vtkEdgeType]->addUpCell(connEdgeId, downFaces[n], downTypes[n]);
+            }
+        }
+    }
+
+  // --- iteration on downward faces (they are all listed now)
+  //     for each downward face:
+  //       build a temporary list of edges with their ordered list of nodes
+  //       for each edge:
+  //         find all the vtk cells containing this edge
+  //         then identify all the downward faces containing the edge, from the vtk cells
+  //         check if the edge is already listed in the faces (comparison of ordered list of nodes)
+  //         if not, create a downward edge entry with the node id's
+  //         mark edge in downward faces
+  //         mark downward faces in edge (size of list unknown, to be allocated)
+
+  CHRONOSTOP(22);CHRONO(23);
+
+  for (int vtkFaceType = 0; vtkFaceType < VTK_QUADRATIC_PYRAMID; vtkFaceType++)
+    {
+      if (SMDS_Downward::getCellDimension(vtkFaceType) != 2)
+        continue;
+
+      // --- find all the edges of the face, describe the edges by their nodes
+
+      SMDS_Down2D* downFace = static_cast<SMDS_Down2D*> (_downArray[vtkFaceType]);
+      int maxId = downFace->getMaxId();
+      for (int faceId = 0; faceId < maxId; faceId++)
+        {
+          //CHRONO(40);
+          ListElemByNodesType edgesWithNodes;
+          downFace->computeEdgesWithNodes(faceId, edgesWithNodes);
+          // MESSAGE("downward face type " << vtkFaceType << " num " << faceId << " contains " << edgesWithNodes.nbElems << " edges");
+
+          //CHRONOSTOP(40);
+          for (int iedge = 0; iedge < edgesWithNodes.nbElems; iedge++)
+            {
+
+              // --- check if the edge is already registered by exploration of the faces
+
+              //CHRONO(41);
+              vector<int> vtkIds;
+              unsigned char vtkEdgeType = edgesWithNodes.elems[iedge].vtkType;
+              int *pts = &edgesWithNodes.elems[iedge].nodeIds[0];
+              SMDS_Down1D* downEdge = static_cast<SMDS_Down1D*> (_downArray[vtkEdgeType]);
+              int nbVtkCells = downEdge->computeVtkCells(pts, vtkIds);
+              //CHRONOSTOP(41);CHRONO(42);
+              int downFaces[1000];
+              unsigned char downTypes[1000];
+              int nbDownFaces = downEdge->computeFaces(pts, &vtkIds[0], nbVtkCells, downFaces, downTypes);
+              //CHRONOSTOP(42);
+
+              //CHRONO(43);
+              int connEdgeId = -1;
+              for (int idf = 0; idf < nbDownFaces; idf++)
+                {
+                  int faceId2 = downFaces[idf];
+                  int faceType = downTypes[idf];
+                  //ASSERT(_downArray[faceType]);
+                  SMDS_Down2D* downFace2 = static_cast<SMDS_Down2D*> (_downArray[faceType]);
+                  connEdgeId = downFace2->FindEdgeByNodes(faceId2, edgesWithNodes.elems[iedge]);
+                  if (connEdgeId >= 0)
+                    break; // --- edge already created
+                }//CHRONOSTOP(43);
+
+              // --- if edge is not registered in the faces, create edge
+
+              if (connEdgeId < 0)
+                {
+                  //CHRONO(44);
+                  connEdgeId = _downArray[vtkEdgeType]->addCell();
+                  downEdge->setNodes(connEdgeId, edgesWithNodes.elems[iedge].nodeIds);
+                  //CHRONOSTOP(44);
+                }
+
+              // --- mark faces in downward edge and mark edge in downward faces
+
+              //CHRONO(45);
+              for (int idf = 0; idf < nbDownFaces; idf++)
+                {
+                  int faceId2 = downFaces[idf];
+                  int faceType = downTypes[idf];
+                  //ASSERT(_downArray[faceType]);
+                  //SMDS_Down2D* downFace2 = static_cast<SMDS_Down2D*> (_downArray[faceType]);
+                  _downArray[vtkEdgeType]->addUpCell(connEdgeId, faceId2, faceType);
+                  _downArray[faceType]->addDownCell(faceId2, connEdgeId, vtkEdgeType);
+                  // MESSAGE(" From face t:" << vtkFaceType << " " << faceId <<
+                  //  " edge " << connEdgeId << " belongs to face t:" << faceType << " " << faceId2);
+                }//CHRONOSTOP(45);
+            }
+        }
+    }
+
+  CHRONOSTOP(23);CHRONO(24);
+
+  // compact downward connectivity structure: adjust downward arrays size, replace vector<vector int>> by a single vector<int>
+  // 3D first then 2D and last 1D to release memory before edge upCells reorganization, (temporary memory use)
+
+  for (int vtkType = VTK_QUADRATIC_PYRAMID; vtkType >= 0; vtkType--)
+    {
+      if (SMDS_Downward *down = _downArray[vtkType])
+        {
+          down->compactStorage();
+        }
+    }
+
+  // --- Statistics
+
+  for (int vtkType = 0; vtkType <= VTK_QUADRATIC_PYRAMID; vtkType++)
+    {
+      if (SMDS_Downward *down = _downArray[vtkType])
+        {
+          if (down->getMaxId())
+            {
+              MESSAGE("Cells of Type " << vtkType << " : number of entities, est: "
+                  << GuessSize[vtkType] << " real: " << down->getMaxId());
+            }
+        }
+    }CHRONOSTOP(24);CHRONOSTOP(2);
+  counters::stats();
+}
+
+/*! Get the neighbors of a cell.
+ * Only the neighbors having the dimension of the cell are taken into account
+ * (neighbors of a volume are the volumes sharing a face with this volume,
+ *  neighbors of a face are the faces sharing an edge with this face...).
+ * @param neighborsVtkIds vector of neighbors vtk id's to fill (reserve enough space).
+ * @param downIds downward id's of cells of dimension n-1, to fill (reserve enough space).
+ * @param downTypes vtk types of cells of dimension n-1, to fill (reserve enough space).
+ * @param vtkId the vtk id of the cell
+ * @return number of neighbors
+ */
+int SMDS_UnstructuredGrid::GetNeighbors(int* neighborsVtkIds, int* downIds, unsigned char* downTypes, int vtkId)
+{
+  int vtkType = this->GetCellType(vtkId);
+  int cellDim = SMDS_Downward::getCellDimension(vtkType);
+  if (cellDim <2)
+    return 0; // TODO voisins des edges = edges connectees
+  int cellId = this->_cellIdToDownId[vtkId];
+
+  int nbCells = _downArray[vtkType]->getNumberOfDownCells(cellId);
+  const int *downCells = _downArray[vtkType]->getDownCells(cellId);
+  const unsigned char* downTyp = _downArray[vtkType]->getDownTypes(cellId);
+
+  // --- iteration on faces of the 3D cell (or edges on the 2D cell).
+
+  int nb = 0;
+  for (int i = 0; i < nbCells; i++)
+    {
+      int downId = downCells[i];
+      int cellType = downTyp[i];
+      int nbUp = _downArray[cellType]->getNumberOfUpCells(downId);
+      const int *upCells = _downArray[cellType]->getUpCells(downId);
+      const unsigned char* upTypes = _downArray[cellType]->getUpTypes(downId);
+
+      // ---for a volume, max 2 upCells, one is this cell, the other is a neighbor
+      //    for a face, number of neighbors (connected faces) not known
+
+      for (int j = 0; j < nbUp; j++)
+        {
+          if ((upCells[j] == cellId) && (upTypes[j] == vtkType))
+            continue;
+          int vtkNeighbor = _downArray[upTypes[j]]->getVtkCellId(upCells[j]);
+          neighborsVtkIds[nb] = vtkNeighbor;
+          downIds[nb] = downId;
+          downTypes[nb] = cellType;
+          nb++;
+        }
+      if (nb >= NBMAXNEIGHBORS)
+        assert(0);
+    }
+  return nb;
+}
+
+/*! get the volumes containing a face or an edge of the grid
+ * The edge or face belongs to the vtkUnstructuredGrid
+ * @param volVtkIds vector of parent volume ids to fill (reserve enough space!)
+ * @param vtkId vtk id of the face or edge
+ */
+int SMDS_UnstructuredGrid::GetParentVolumes(int* volVtkIds, int vtkId)
+{
+  int vtkType = this->GetCellType(vtkId);
+  int dim = SMDS_Downward::getCellDimension(vtkType);
+  int nbFaces = 0;
+  unsigned char cellTypes[1000];
+  int downCellId[1000];
+  if (dim == 1)
+    {
+      int downId = this->CellIdToDownId(vtkId);
+      if (downId < 0)
+        {
+          MESSAGE("Downward structure not up to date: new edge not taken into account");
+          return 0;
+        }
+      nbFaces = _downArray[vtkType]->getNumberOfUpCells(downId);
+      const int *upCells = _downArray[vtkType]->getUpCells(downId);
+      const unsigned char* upTypes = _downArray[vtkType]->getUpTypes(downId);
+      for (int i=0; i< nbFaces; i++)
+        {
+          cellTypes[i] = upTypes[i];
+          downCellId[i] = upCells[i];
+        }
+    }
+  else if (dim == 2)
+    {
+      nbFaces = 1;
+      cellTypes[0] = this->GetCellType(vtkId);
+      int downId = this->CellIdToDownId(vtkId);
+      if (downId < 0)
+        {
+          MESSAGE("Downward structure not up to date: new face not taken into account");
+          return 0;
+        }
+      downCellId[0] = downId;
+    }
+
+  int nbvol =0;
+  for (int i=0; i<nbFaces; i++)
+    {
+      int vtkTypeFace = cellTypes[i];
+      int downId = downCellId[i];
+      int nv = _downArray[vtkTypeFace]->getNumberOfUpCells(downId);
+      const int *upCells = _downArray[vtkTypeFace]->getUpCells(downId);
+      const unsigned char* upTypes = _downArray[vtkTypeFace]->getUpTypes(downId);
+       for (int j=0; j<nv; j++)
+        {
+          int vtkVolId = _downArray[upTypes[j]]->getVtkCellId(upCells[j]);
+          if (vtkVolId >= 0)
+            volVtkIds[nbvol++] = vtkVolId;
+        }
+    }
+  return nbvol;
+}
+
+/*! get the volumes containing a face or an edge of the downward structure
+ * The edge or face does not necessary belong to the vtkUnstructuredGrid
+ * @param volVtkIds vector of parent volume ids to fill (reserve enough space!)
+ * @param downId id in the downward structure
+ * @param downType type of cell
+ */
+int SMDS_UnstructuredGrid::GetParentVolumes(int* volVtkIds, int downId, unsigned char downType)
+{
+  int vtkType = downType;
+  int dim = SMDS_Downward::getCellDimension(vtkType);
+  int nbFaces = 0;
+  unsigned char cellTypes[1000];
+  int downCellId[1000];
+  if (dim == 1)
+    {
+      nbFaces = _downArray[vtkType]->getNumberOfUpCells(downId);
+      const int *upCells = _downArray[vtkType]->getUpCells(downId);
+      const unsigned char* upTypes = _downArray[vtkType]->getUpTypes(downId);
+      for (int i=0; i< nbFaces; i++)
+        {
+          cellTypes[i] = upTypes[i];
+          downCellId[i] = upCells[i];
+        }
+    }
+  else if (dim == 2)
+    {
+      nbFaces = 1;
+      cellTypes[0] = vtkType;
+      downCellId[0] = downId;
+    }
+
+  int nbvol =0;
+  for (int i=0; i<nbFaces; i++)
+    {
+      int vtkTypeFace = cellTypes[i];
+      int downId = downCellId[i];
+      int nv = _downArray[vtkTypeFace]->getNumberOfUpCells(downId);
+      const int *upCells = _downArray[vtkTypeFace]->getUpCells(downId);
+      const unsigned char* upTypes = _downArray[vtkTypeFace]->getUpTypes(downId);
+       for (int j=0; j<nv; j++)
+        {
+          int vtkVolId = _downArray[upTypes[j]]->getVtkCellId(upCells[j]);
+          if (vtkVolId >= 0)
+            volVtkIds[nbvol++] = vtkVolId;
+        }
+    }
+  return nbvol;
+}
+
+/*! get the node id's of a cell.
+ * The cell is defined by it's downward connectivity id and type.
+ * @param nodeSet set of of vtk node id's to fill.
+ * @param downId downward connectivity id of the cell.
+ * @param downType type of cell.
+ */
+void SMDS_UnstructuredGrid::GetNodeIds(std::set<int>& nodeSet, int downId, unsigned char downType)
+{
+  _downArray[downType]->getNodeIds(downId, nodeSet);
+}
+
+/*! change some nodes in cell without modifying type or internal connectivity.
+ * Nodes inverse connectivity is maintained up to date.
+ * @param vtkVolId vtk id of the cell
+ * @param localClonedNodeIds map old node id to new node id.
+ */
+void SMDS_UnstructuredGrid::ModifyCellNodes(int vtkVolId, std::map<int, int> localClonedNodeIds)
+{
+  vtkIdType npts = 0;
+  vtkIdType *pts; // will refer to the point id's of the face
+  this->GetCellPoints(vtkVolId, npts, pts);
+  for (int i = 0; i < npts; i++)
+    {
+      if (localClonedNodeIds.count(pts[i]))
+        {
+          vtkIdType oldpt = pts[i];
+          pts[i] = localClonedNodeIds[oldpt];
+          //MESSAGE(oldpt << " --> " << pts[i]);
+          //this->RemoveReferenceToCell(oldpt, vtkVolId);
+          //this->AddReferenceToCell(pts[i], vtkVolId);
+        }
+    }
+}
+
+/*! reorder the nodes of a face
+ * @param vtkVolId vtk id of a volume containing the face, to get an orientation for the face.
+ * @param orderedNodes list of nodes to reorder (in out)
+ * @return size of the list
+ */
+int SMDS_UnstructuredGrid::getOrderedNodesOfFace(int vtkVolId, int& dim, std::vector<vtkIdType>& orderedNodes)
+{
+  int vtkType = this->GetCellType(vtkVolId);
+  dim = SMDS_Downward::getCellDimension(vtkType);
+  if (dim == 3)
+    {
+      SMDS_Down3D *downvol = static_cast<SMDS_Down3D*> (_downArray[vtkType]);
+      int downVolId = this->_cellIdToDownId[vtkVolId];
+      downvol->getOrderedNodesOfFace(downVolId, orderedNodes);
+    }
+  // else nothing to do;
+  return orderedNodes.size();
+}
+
+void SMDS_UnstructuredGrid::BuildLinks()
+{
+  // Remove the old links if they are already built
+  if (this->Links)
+    {
+    this->Links->UnRegister(this);
+    }
+
+  this->Links = SMDS_CellLinks::New();
+  this->Links->Allocate(this->GetNumberOfPoints());
+  this->Links->Register(this);
+  this->Links->BuildLinks(this, this->Connectivity);
+  this->Links->Delete();
+}
+
+/*! Create a volume (prism or hexahedron) by duplication of a face.
+ * Designed for use in creation of flat elements separating volume domains.
+ * A face separating two domains is shared by two volume cells.
+ * All the nodes are already created (for the two faces).
+ * Each original Node is associated to corresponding nodes in the domains.
+ * Some nodes may be duplicated for more than two domains, when domain separations intersect.
+ * In that case, even some of the nodes to use for the original face may be changed.
+ * @param vtkVolId: vtk id of a volume containing the face, to get an orientation for the face.
+ * @param domain1: domain of the original face
+ * @param domain2: domain of the duplicated face
+ * @param originalNodes: the vtk node ids of the original face
+ * @param nodeDomains: map(original id --> map(domain --> duplicated node id))
+ * @return ok if success.
+ */
+SMDS_MeshCell* SMDS_UnstructuredGrid::extrudeVolumeFromFace(int vtkVolId,
+                                                  int domain1,
+                                                  int domain2,
+                                                  std::set<int>& originalNodes,
+                                                  std::map<int, std::map<int, int> >& nodeDomains,
+                                                  std::map<int, std::map<long, int> >& nodeQuadDomains)
+{
+  //MESSAGE("extrudeVolumeFromFace " << vtkVolId);
+  vector<vtkIdType> orderedOriginals;
+  orderedOriginals.clear();
+  set<int>::const_iterator it = originalNodes.begin();
+  for (; it != originalNodes.end(); ++it)
+    orderedOriginals.push_back(*it);
+
+  int dim = 0;
+  int nbNodes = this->getOrderedNodesOfFace(vtkVolId, dim, orderedOriginals);
+  vector<vtkIdType> orderedNodes;
+
+  bool isQuadratic = false;
+  switch (orderedOriginals.size())
+  {
+    case 3:
+      if (dim == 2)
+        isQuadratic = true;
+      break;
+    case 6:
+    case 8:
+      isQuadratic = true;
+      break;
+    default:
+      isQuadratic = false;
+      break;
+  }
+
+  if (isQuadratic)
+    {
+      long dom1 = domain1;
+      long dom2 = domain2;
+      long dom1_2; // for nodeQuadDomains
+      if (domain1 < domain2)
+        dom1_2 = dom1 + INT_MAX * dom2;
+      else
+        dom1_2 = dom2 + INT_MAX * dom1;
+      //cerr << "dom1=" << dom1 << " dom2=" << dom2 << " dom1_2=" << dom1_2 << endl;
+      int ima = orderedOriginals.size();
+      int mid = orderedOriginals.size() / 2;
+      //cerr << "ima=" << ima << " mid=" << mid << endl;
+      for (int i = 0; i < mid; i++)
+        orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain1]);
+      for (int i = 0; i < mid; i++)
+        orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]);
+      for (int i = mid; i < ima; i++)
+        orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain1]);
+      for (int i = mid; i < ima; i++)
+        orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]);
+      for (int i = 0; i < mid; i++)
+        {
+          int oldId = orderedOriginals[i];
+          int newId;
+          if (nodeQuadDomains.count(oldId) && nodeQuadDomains[oldId].count(dom1_2))
+            newId = nodeQuadDomains[oldId][dom1_2];
+          else
+            {
+              double *coords = this->GetPoint(oldId);
+              SMDS_MeshNode *newNode = _mesh->AddNode(coords[0], coords[1], coords[2]);
+              newId = newNode->getVtkId();
+              std::map<long, int> emptyMap;
+              nodeQuadDomains[oldId] = emptyMap;
+              nodeQuadDomains[oldId][dom1_2] = newId;
+            }
+          orderedNodes.push_back(newId);
+        }
+    }
+  else
+    {
+      for (int i = 0; i < nbNodes; i++)
+        orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain1]);
+      if (dim == 3)
+        for (int i = 0; i < nbNodes; i++)
+          orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]);
+      else
+        for (int i = nbNodes-1; i >= 0; i--)
+          orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]);
+
+    }
+
+  if (dim == 3)
+    {
+      SMDS_MeshVolume *vol = _mesh->AddVolumeFromVtkIds(orderedNodes);
+      return vol;
+    }
+  else if (dim == 2)
+    {
+      SMDS_MeshFace *face = _mesh->AddFaceFromVtkIds(orderedNodes);
+      return face;
+    }
+
+  // TODO update sub-shape list of elements and nodes
+  return 0;
+}
+
+//================================================================================
+/*!
+ * \brief Allocates data array for ball diameters
+ *  \param MaxVtkID - max ID of a ball element
+ */
+//================================================================================
+
+void SMDS_UnstructuredGrid::AllocateDiameters( vtkIdType MaxVtkID )
+{
+  SetBallDiameter( MaxVtkID, 0 );
+}
+
+//================================================================================
+/*!
+ * \brief Sets diameter of a ball element
+ *  \param vtkID - vtk id of the ball element
+ *  \param diameter - diameter of the ball element
+ */
+//================================================================================
+
+void SMDS_UnstructuredGrid::SetBallDiameter( vtkIdType vtkID, double diameter )
+{
+  vtkDoubleArray* array = vtkDoubleArray::SafeDownCast( vtkDataSet::CellData->GetScalars() );
+  if ( !array )
+  {
+    array = vtkDoubleArray::New();
+    array->SetNumberOfComponents(1);
+    vtkDataSet::CellData->SetScalars( array );
+  }
+  array->InsertValue( vtkID, diameter );
+}
+
+//================================================================================
+/*!
+ * \brief Returns diameter of a ball element
+ *  \param vtkID - vtk id of the ball element
+ */
+//================================================================================
+
+double SMDS_UnstructuredGrid::GetBallDiameter( vtkIdType vtkID ) const
+{
+  if ( vtkDataSet::CellData )
+    return vtkDoubleArray::SafeDownCast( vtkDataSet::CellData->GetScalars() )->GetValue( vtkID );
+  return 0;
+}
+
diff --git a/src/SMDS/SMDS_UnstructuredGrid.hxx b/src/SMDS/SMDS_UnstructuredGrid.hxx
new file mode 100644 (file)
index 0000000..4c1cc7b
--- /dev/null
@@ -0,0 +1,125 @@
+// Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+// File:    SMDS_UnstructuredGrid.hxx
+// Author:  prascle
+// Created: September 16, 2009, 10:28 PM
+
+#ifndef _SMDS_UNSTRUCTUREDGRID_HXX
+#define _SMDS_UNSTRUCTUREDGRID_HXX
+
+#include "SMESH_SMDS.hxx"
+
+#include <vtkUnstructuredGrid.h>
+#include <vtkCellLinks.h>
+#include "chrono.hxx"
+
+#include <vector>
+#include <set>
+#include <map>
+
+//#define VTK_HAVE_POLYHEDRON
+//#ifdef VTK_HAVE_POLYHEDRON
+#define VTK_MAXTYPE VTK_POLYHEDRON
+//#else
+//  #define VTK_MAXTYPE VTK_QUADRATIC_PYRAMID
+//#endif
+
+#define NBMAXNEIGHBORS 100
+
+// allow very huge polyhedrons in tests
+#define NBMAXNODESINCELL 5000
+
+class SMDS_Downward;
+class SMDS_Mesh;
+class SMDS_MeshCell;
+class SMDS_MeshVolume;
+
+class SMDS_EXPORT SMDS_CellLinks: public vtkCellLinks
+{
+public:
+  vtkCellLinks::Link* ResizeL(vtkIdType sz);
+  vtkIdType GetLinksSize();
+  static SMDS_CellLinks* New();
+protected:
+  SMDS_CellLinks();
+  ~SMDS_CellLinks();
+};
+
+class SMDS_EXPORT SMDS_UnstructuredGrid: public vtkUnstructuredGrid
+{
+public:
+  void setSMDS_mesh(SMDS_Mesh *mesh);
+  void compactGrid(std::vector<int>& idNodesOldToNew,
+                   int               newNodeSize,
+                   std::vector<int>& idCellsOldToNew,
+                   int               newCellSize);
+  virtual unsigned long GetMTime();
+  virtual void Update();
+  virtual void UpdateInformation();
+  virtual vtkPoints *GetPoints();
+
+  //#ifdef VTK_HAVE_POLYHEDRON
+  int InsertNextLinkedCell(int type, int npts, vtkIdType *pts);
+  //#endif
+
+  int CellIdToDownId(int vtkCellId);
+  void setCellIdToDownId(int vtkCellId, int downId);
+  void CleanDownwardConnectivity();
+  void BuildDownwardConnectivity(bool withEdges);
+  int GetNeighbors(int* neighborsVtkIds, int* downIds, unsigned char* downTypes, int vtkId);
+  int GetParentVolumes(int* volVtkIds, int vtkId);
+  int GetParentVolumes(int* volVtkIds, int downId, unsigned char downType);
+  void GetNodeIds(std::set<int>& nodeSet, int downId, unsigned char downType);
+  void ModifyCellNodes(int vtkVolId, std::map<int, int> localClonedNodeIds);
+  int getOrderedNodesOfFace(int vtkVolId, int& dim, std::vector<vtkIdType>& orderedNodes);
+  void BuildLinks();
+  SMDS_MeshCell* extrudeVolumeFromFace(int vtkVolId, int domain1, int domain2,
+                                       std::set<int>&                      originalNodes,
+                                       std::map<int, std::map<int, int> >& nodeDomains,
+                                       std::map<int, std::map<long,int> >& nodeQuadDomains);
+  vtkCellLinks* GetLinks()
+  {
+    return Links;
+  }
+  SMDS_Downward* getDownArray(unsigned char vtkType)
+  {
+    return _downArray[vtkType];
+  }
+  void AllocateDiameters( vtkIdType maxVtkID );
+  void SetBallDiameter( vtkIdType vtkID, double diameter );
+  double GetBallDiameter( vtkIdType vtkID ) const;
+
+  static SMDS_UnstructuredGrid* New();
+  SMDS_Mesh *_mesh;
+protected:
+  SMDS_UnstructuredGrid();
+  ~SMDS_UnstructuredGrid();
+  void copyNodes(vtkPoints *newPoints, std::vector<int>& idNodesOldToNew, int& alreadyCopied, int start, int end);
+  void copyBloc(vtkUnsignedCharArray *newTypes, std::vector<int>& idCellsOldToNew, std::vector<int>& idNodesOldToNew,
+                vtkCellArray* newConnectivity, vtkIdTypeArray* newLocations, vtkIdType* pointsCell, int& alreadyCopied,
+                int start, int end);
+
+  std::vector<int> _cellIdToDownId; //!< convert vtk Id to downward[vtkType] id, initialized with -1
+  std::vector<unsigned char> _downTypes;
+  std::vector<SMDS_Downward*> _downArray;
+};
+
+#endif  /* _SMDS_UNSTRUCTUREDGRID_HXX */
+
index c3311b5a599f8ba5a617185bbcb4733a865efcf7..20584970c80a70373c0be317ca371a66e9cb707e 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_VertexPosition.cxx
 //  Author : Jean-Michel BOULCOURT
@@ -35,25 +36,13 @@ using namespace std;
 //purpose  : 
 //=======================================================================
 
-SMDS_VertexPosition:: SMDS_VertexPosition(const int aVertexId)
-       :SMDS_Position(aVertexId)
+SMDS_VertexPosition:: SMDS_VertexPosition()
 {
+  //MESSAGE("*********************************************** SMDS_VertexPosition " << aVertexId);
 }
 
-//=======================================================================
-//function : Coords
-//purpose  : 
-//=======================================================================
-
-const double *SMDS_VertexPosition::Coords() const
-{
-       const static double origin[]={0,0,0};
-       MESSAGE("SMDS_VertexPosition::Coords not implemented");
-       return origin;
-}
-
-
 SMDS_TypeOfPosition SMDS_VertexPosition::GetTypeOfPosition() const
 {
-       return SMDS_TOP_VERTEX;
+  //MESSAGE("################################################# GetTypeOfPosition");
+        return SMDS_TOP_VERTEX;
 }
index dad7b5a1320831ef7940e6f486bf9cc41f6f933d..6b574cd11c61ae7627bc4a1070d58e4d0600ec6e 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_VertexPosition.hxx
 //  Module : SMESH
 class SMDS_EXPORT SMDS_VertexPosition:public SMDS_Position
 {
 
-  public:      
-       SMDS_TypeOfPosition GetTypeOfPosition() const;
-       SMDS_VertexPosition(int aVertexId=0);
-       const double *Coords() const;
+  public:       
+        SMDS_TypeOfPosition GetTypeOfPosition() const;
+        SMDS_VertexPosition();
 };
 
 #endif
index c993dcc66f56132add69211e51d2dbd50c4f3a07..e5aa46096702d8ab9cf73c53489511f38ca3a505 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_VolumeOfFaces.cxx
 //  Author : Jean-Michel BOULCOURT
@@ -30,6 +31,7 @@
 
 #include "SMDS_VolumeOfFaces.hxx"
 #include "SMDS_IteratorOfElements.hxx"
+#include "utilities.h"
 
 using namespace std;
 
@@ -40,16 +42,16 @@ using namespace std;
 
 void SMDS_VolumeOfFaces::Print(ostream & OS) const
 {
-       OS << "volume <" << GetID() << "> : ";
-       int i;
-       for (i = 0; i < NbFaces()-1; ++i) OS << myFaces[i] << ",";
-       OS << myFaces[i]<< ") " << endl;
+        OS << "volume <" << GetID() << "> : ";
+        int i;
+        for (i = 0; i < NbFaces()-1; ++i) OS << myFaces[i] << ",";
+        OS << myFaces[i]<< ") " << endl;
 }
 
 
 int SMDS_VolumeOfFaces::NbFaces() const
 {
-       return myNbFaces;
+        return myNbFaces;
 }
 
 class SMDS_VolumeOfFaces_MyIterator:public SMDS_ElemIterator
@@ -74,7 +76,7 @@ class SMDS_VolumeOfFaces_MyIterator:public SMDS_ElemIterator
 };
 
 SMDS_ElemIteratorPtr SMDS_VolumeOfFaces::
-       elementsIterator(SMDSAbs_ElementType type) const
+        elementsIterator(SMDSAbs_ElementType type) const
 {
   switch(type)
   {
@@ -95,13 +97,14 @@ SMDS_VolumeOfFaces::SMDS_VolumeOfFaces(const SMDS_MeshFace * face1,
                                        const SMDS_MeshFace * face3,
                                        const SMDS_MeshFace * face4)
 {
-       myNbFaces = 4;
-       myFaces[0]=face1;
-       myFaces[1]=face2;
-       myFaces[2]=face3;
-       myFaces[3]=face4;
-       myFaces[4]=0;
-       myFaces[5]=0;
+  //MESSAGE("****************************************************** SMDS_VolumeOfFaces");
+        myNbFaces = 4;
+        myFaces[0]=face1;
+        myFaces[1]=face2;
+        myFaces[2]=face3;
+        myFaces[3]=face4;
+        myFaces[4]=0;
+        myFaces[5]=0;
 }
 
 SMDS_VolumeOfFaces::SMDS_VolumeOfFaces(const SMDS_MeshFace * face1,
@@ -110,13 +113,14 @@ SMDS_VolumeOfFaces::SMDS_VolumeOfFaces(const SMDS_MeshFace * face1,
                                        const SMDS_MeshFace * face4,
                                        const SMDS_MeshFace * face5)
 {
-       myNbFaces = 5;
-       myFaces[0]=face1;
-       myFaces[1]=face2;
-       myFaces[2]=face3;
-       myFaces[3]=face4;
-       myFaces[4]=face5;
-       myFaces[5]=0;
+  //MESSAGE("****************************************************** SMDS_VolumeOfFaces");
+        myNbFaces = 5;
+        myFaces[0]=face1;
+        myFaces[1]=face2;
+        myFaces[2]=face3;
+        myFaces[3]=face4;
+        myFaces[4]=face5;
+        myFaces[5]=0;
 }
 
 SMDS_VolumeOfFaces::SMDS_VolumeOfFaces(const SMDS_MeshFace * face1,
@@ -126,12 +130,40 @@ SMDS_VolumeOfFaces::SMDS_VolumeOfFaces(const SMDS_MeshFace * face1,
                                        const SMDS_MeshFace * face5,
                                        const SMDS_MeshFace * face6)
 {
-       myNbFaces = 6;
-       myFaces[0]=face1;
-       myFaces[1]=face2;
-       myFaces[2]=face3;
-       myFaces[3]=face4;
-       myFaces[4]=face5;
-       myFaces[5]=face6;
+  //MESSAGE("****************************************************** SMDS_VolumeOfFaces");
+        myNbFaces = 6;
+        myFaces[0]=face1;
+        myFaces[1]=face2;
+        myFaces[2]=face3;
+        myFaces[3]=face4;
+        myFaces[4]=face5;
+        myFaces[5]=face6;
+}
+
+SMDSAbs_EntityType SMDS_VolumeOfFaces::GetEntityType() const
+{
+  SMDSAbs_EntityType aType = SMDSEntity_Tetra;
+  switch(myNbFaces)
+  {
+  case 4: aType = SMDSEntity_Tetra;   break;
+  case 5: aType = SMDSEntity_Pyramid; break;
+  case 6: aType = SMDSEntity_Penta;   break;
+  case 8:
+  default: aType = SMDSEntity_Hexa;    break;
+  }
+  return aType;
 }
 
+SMDSAbs_GeometryType SMDS_VolumeOfFaces::GetGeomType() const
+{
+  SMDSAbs_GeometryType aType = SMDSGeom_NONE;
+  switch(myNbFaces)
+  {
+  case 4: aType = SMDSGeom_TETRA;   break;
+  case 5: aType = SMDSGeom_PYRAMID; break;
+  case 6: aType = SMDSGeom_PENTA;   break;
+  case 8:
+  default: aType = SMDSGeom_HEXA;   break;
+  }
+  return aType;
+}
index 074fbec23d546d65bc5d211c8179c0b7bb8c20e3..a64d53ab51f6c46c668a085e9cec370ac0a52cc0 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_VolumeOfFaces.hxx
 //  Module : SMESH
 
 class SMDS_EXPORT SMDS_VolumeOfFaces:public SMDS_MeshVolume
 {
-       
+        
   public:
-       SMDS_VolumeOfFaces(const SMDS_MeshFace * face1,
+        SMDS_VolumeOfFaces(const SMDS_MeshFace * face1,
                            const SMDS_MeshFace * face2,
                            const SMDS_MeshFace * face3,
                            const SMDS_MeshFace * face4);
-       SMDS_VolumeOfFaces(const SMDS_MeshFace * face1,
+        SMDS_VolumeOfFaces(const SMDS_MeshFace * face1,
                            const SMDS_MeshFace * face2,
                            const SMDS_MeshFace * face3,
                            const SMDS_MeshFace * face4,
                            const SMDS_MeshFace * face5);
-       SMDS_VolumeOfFaces(const SMDS_MeshFace * face1,
+        SMDS_VolumeOfFaces(const SMDS_MeshFace * face1,
                            const SMDS_MeshFace * face2,
                            const SMDS_MeshFace * face3,
                            const SMDS_MeshFace * face4,
                            const SMDS_MeshFace * face5,
                            const SMDS_MeshFace * face6);
 
-       void Print(std::ostream & OS) const;
-       
-       int NbFaces() const;
+        virtual SMDSAbs_EntityType GetEntityType() const;
+        virtual SMDSAbs_GeometryType GetGeomType() const;
+        virtual bool ChangeNodes(const SMDS_MeshNode* nodes[],
+                                 const int            nbNodes) {return false;}
+        virtual void Print(std::ostream & OS) const;
+
+        virtual int NbFaces() const;
 
   protected:
-       SMDS_ElemIteratorPtr
-               elementsIterator(SMDSAbs_ElementType type) const;
-       const SMDS_MeshFace * myFaces[6];
-       int                   myNbFaces;
+        virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const;
+        const SMDS_MeshFace * myFaces[6];
+        int                   myNbFaces;
 };
 #endif
index ff46fc318ab25cfd98512f9f25436a9052a9455b..cb4cdfa34d4d26494c6d89e19e1ae604f47e84ff 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //
 #ifdef _MSC_VER
 #include "SMDS_MeshNode.hxx"
 #include "SMDS_SetIterator.hxx"
 #include "SMDS_VolumeTool.hxx"
+#include "SMDS_Mesh.hxx"
 #include "utilities.h"
 
-#include <vector>
-
 using namespace std;
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -40,73 +40,77 @@ using namespace std;
 /// 5,1 and 7,3 are an edges.
 ///////////////////////////////////////////////////////////////////////////////
 SMDS_VolumeOfNodes::SMDS_VolumeOfNodes(
-               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)
-{
-       myNbNodes = 8;
-       myNodes = new const SMDS_MeshNode* [myNbNodes];
-       myNodes[0]=node1;
-       myNodes[1]=node2;
-       myNodes[2]=node3;
-       myNodes[3]=node4;
-       myNodes[4]=node5;
-       myNodes[5]=node6;
-       myNodes[6]=node7;
-       myNodes[7]=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)
+{
+  //MESSAGE("***************************************************** SMDS_VolumeOfNodes");
+        myNbNodes = 8;
+        myNodes = new const SMDS_MeshNode* [myNbNodes];
+        myNodes[0]=node1;
+        myNodes[1]=node2;
+        myNodes[2]=node3;
+        myNodes[3]=node4;
+        myNodes[4]=node5;
+        myNodes[5]=node6;
+        myNodes[6]=node7;
+        myNodes[7]=node8;
 }
 
 SMDS_VolumeOfNodes::SMDS_VolumeOfNodes(
-               const SMDS_MeshNode * node1,
-               const SMDS_MeshNode * node2,
-               const SMDS_MeshNode * node3,
-               const SMDS_MeshNode * node4)
-{
-       myNbNodes = 4;
-       myNodes = new const SMDS_MeshNode* [myNbNodes];
-       myNodes[0]=node1;
-       myNodes[1]=node2;
-       myNodes[2]=node3;
-       myNodes[3]=node4;
+                const SMDS_MeshNode * node1,
+                const SMDS_MeshNode * node2,
+                const SMDS_MeshNode * node3,
+                const SMDS_MeshNode * node4)
+{
+  //MESSAGE("***************************************************** SMDS_VolumeOfNodes");
+        myNbNodes = 4;
+        myNodes = new const SMDS_MeshNode* [myNbNodes];
+        myNodes[0]=node1;
+        myNodes[1]=node2;
+        myNodes[2]=node3;
+        myNodes[3]=node4;
 }
 
 SMDS_VolumeOfNodes::SMDS_VolumeOfNodes(
-               const SMDS_MeshNode * node1,
-               const SMDS_MeshNode * node2,
-               const SMDS_MeshNode * node3,
-               const SMDS_MeshNode * node4,
-               const SMDS_MeshNode * node5)
-{
-       myNbNodes = 5;
-       myNodes = new const SMDS_MeshNode* [myNbNodes];
-       myNodes[0]=node1;
-       myNodes[1]=node2;
-       myNodes[2]=node3;
-       myNodes[3]=node4;
-       myNodes[4]=node5;
+                const SMDS_MeshNode * node1,
+                const SMDS_MeshNode * node2,
+                const SMDS_MeshNode * node3,
+                const SMDS_MeshNode * node4,
+                const SMDS_MeshNode * node5)
+{
+  //MESSAGE("***************************************************** SMDS_VolumeOfNodes");
+        myNbNodes = 5;
+        myNodes = new const SMDS_MeshNode* [myNbNodes];
+        myNodes[0]=node1;
+        myNodes[1]=node2;
+        myNodes[2]=node3;
+        myNodes[3]=node4;
+        myNodes[4]=node5;
 }
 
 SMDS_VolumeOfNodes::SMDS_VolumeOfNodes(
-               const SMDS_MeshNode * node1,
-               const SMDS_MeshNode * node2,
-               const SMDS_MeshNode * node3,
-               const SMDS_MeshNode * node4,
-               const SMDS_MeshNode * node5,
-               const SMDS_MeshNode * node6)
-{
-       myNbNodes = 6;
-       myNodes = new const SMDS_MeshNode* [myNbNodes];
-       myNodes[0]=node1;
-       myNodes[1]=node2;
-       myNodes[2]=node3;
-       myNodes[3]=node4;
-       myNodes[4]=node5;
-       myNodes[5]=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)
+{
+  //MESSAGE("***************************************************** SMDS_VolumeOfNodes");
+        myNbNodes = 6;
+        myNodes = new const SMDS_MeshNode* [myNbNodes];
+        myNodes[0]=node1;
+        myNodes[1]=node2;
+        myNodes[2]=node3;
+        myNodes[3]=node4;
+        myNodes[4]=node5;
+        myNodes[5]=node6;
 }
 
 bool SMDS_VolumeOfNodes::ChangeNodes(const SMDS_MeshNode* nodes[],
@@ -132,56 +136,48 @@ SMDS_VolumeOfNodes::~SMDS_VolumeOfNodes()
   }
 }
 
-//=======================================================================
-//function : Print
-//purpose  : 
-//=======================================================================
-
 void SMDS_VolumeOfNodes::Print(ostream & OS) const
 {
-       OS << "volume <" << GetID() << "> : ";
-       int i;
-       for (i = 0; i < NbNodes(); ++i) OS << myNodes[i] << ",";
-       OS << myNodes[NbNodes()-1]<< ") " << endl;
+        OS << "volume <" << GetID() << "> : ";
+        int i;
+        for (i = 0; i < NbNodes()-1; ++i) OS << myNodes[i] << ",";
+        OS << myNodes[NbNodes()-1]<< ") " << endl;
 }
 
 int SMDS_VolumeOfNodes::NbFaces() const
 {
-       switch(NbNodes())
-       {
-       case 4: return 4;
-       case 5: return 5;
-       case 6: return 5;
-       case 8: return 6;
-       default: MESSAGE("invalid number of nodes");
-       }
+        switch(NbNodes())
+        {
+        case 4: return 4;
+        case 5: return 5;
+        case 6: return 5;
+        case 8: return 6;
+        default: MESSAGE("invalid number of nodes");
+        }
         return 0;
 }
 
 int SMDS_VolumeOfNodes::NbNodes() const
 {
-       return myNbNodes;
+        return myNbNodes;
 }
 
 int SMDS_VolumeOfNodes::NbEdges() const
 {
-       switch(NbNodes())
-       {
-       case 4: return 6;
-       case 5: return 8;
-       case 6: return 9;
-       case 8: return 12;
-       default: MESSAGE("invalid number of nodes");
-       }
+        switch(NbNodes())
+        {
+        case 4: return 6;
+        case 5: return 8;
+        case 6: return 9;
+        case 8: return 12;
+        default: MESSAGE("invalid number of nodes");
+        }
         return 0;
 }
 
-/// ===================================================================
 /*!
  * \brief Iterator on node of volume
  */
-/// ===================================================================
-
 class SMDS_VolumeOfNodes_MyIterator:public SMDS_NodeArrayElemIterator
 {
  public:
@@ -189,12 +185,9 @@ class SMDS_VolumeOfNodes_MyIterator:public SMDS_NodeArrayElemIterator
     SMDS_NodeArrayElemIterator( s, & s[ l ]) {}
 };
 
-/// ===================================================================
 /*!
  * \brief Iterator on faces or edges of volume
  */
-/// ===================================================================
-
 class _MySubIterator : public SMDS_ElemIterator
 {
   vector< const SMDS_MeshElement* > myElems;
@@ -234,17 +227,45 @@ SMDS_ElemIteratorPtr SMDS_VolumeOfNodes::elementsIterator(SMDSAbs_ElementType ty
 
 SMDSAbs_ElementType SMDS_VolumeOfNodes::GetType() const
 {
-       return SMDSAbs_Volume;
+        return SMDSAbs_Volume;
 }
 
 /*!
  * \brief Return node by its index
  * \param ind - node index
  * \retval const SMDS_MeshNode* - the node
- * 
- * Index is wrapped if it is out of a valid range
  */
 const SMDS_MeshNode* SMDS_VolumeOfNodes::GetNode(const int ind) const
 {
-  return myNodes[ WrappedIndex( ind )];
+  return myNodes[ ind ];
+}
+
+SMDSAbs_EntityType SMDS_VolumeOfNodes::GetEntityType() const
+{
+  SMDSAbs_EntityType aType = SMDSEntity_Tetra;
+  switch(myNbNodes)
+  {
+  case 4: aType = SMDSEntity_Tetra;   break;
+  case 5: aType = SMDSEntity_Pyramid; break;
+  case 6: aType = SMDSEntity_Penta;   break;
+  case 8:
+  default: aType = SMDSEntity_Hexa;    break;
+  }
+  return aType;
+}
+
+SMDSAbs_GeometryType SMDS_VolumeOfNodes::GetGeomType() const
+{
+  SMDSAbs_GeometryType aType = SMDSGeom_NONE;
+  switch(myNbNodes)
+  {
+  case 4: aType = SMDSGeom_TETRA;   break;
+  case 5: aType = SMDSGeom_PYRAMID; break;
+  case 6: aType = SMDSGeom_PENTA;   break;
+  case 12: aType = SMDSGeom_HEXAGONAL_PRISM; break;
+  case 8:
+  default: aType = SMDSGeom_HEXA;    break;
+  }
+  return aType;
 }
+
index ee773285b39f4d4a6e6943ed43f4b54d739d8e68..86e22b6229638450cbfc0840492b6e79255494c8 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 //  File   : SMDS_MeshVolume.hxx
 //  Module : SMESH
 
 class SMDS_EXPORT SMDS_VolumeOfNodes:public SMDS_MeshVolume
 {
-       
+        
   public:
-       SMDS_VolumeOfNodes(
-               const SMDS_MeshNode * node1,
-               const SMDS_MeshNode * node2,
-               const SMDS_MeshNode * node3,
-               const SMDS_MeshNode * node4);
-       SMDS_VolumeOfNodes(
-               const SMDS_MeshNode * node1,
-               const SMDS_MeshNode * node2,
-               const SMDS_MeshNode * node3,
-               const SMDS_MeshNode * node4,
-               const SMDS_MeshNode * node5);
-       SMDS_VolumeOfNodes(
-               const SMDS_MeshNode * node1,
-               const SMDS_MeshNode * node2,
-               const SMDS_MeshNode * node3,
-               const SMDS_MeshNode * node4,
-               const SMDS_MeshNode * node5,
-               const SMDS_MeshNode * node6);
-       SMDS_VolumeOfNodes(
-               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);
+        SMDS_VolumeOfNodes(
+                const SMDS_MeshNode * node1,
+                const SMDS_MeshNode * node2,
+                const SMDS_MeshNode * node3,
+                const SMDS_MeshNode * node4);
+        SMDS_VolumeOfNodes(
+                const SMDS_MeshNode * node1,
+                const SMDS_MeshNode * node2,
+                const SMDS_MeshNode * node3,
+                const SMDS_MeshNode * node4,
+                const SMDS_MeshNode * node5);
+        SMDS_VolumeOfNodes(
+                const SMDS_MeshNode * node1,
+                const SMDS_MeshNode * node2,
+                const SMDS_MeshNode * node3,
+                const SMDS_MeshNode * node4,
+                const SMDS_MeshNode * node5,
+                const SMDS_MeshNode * node6);
+        SMDS_VolumeOfNodes(
+                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);
         bool ChangeNodes(const SMDS_MeshNode* nodes[],
                          const int            nbNodes);
         ~SMDS_VolumeOfNodes();
 
-       void Print(std::ostream & OS) const;
-       int NbFaces() const;
-       int NbNodes() const;
-       int NbEdges() const;
-       SMDSAbs_ElementType GetType() const;    
+        void Print(std::ostream & OS) const;
+        int NbFaces() const;
+        int NbNodes() const;
+        int NbEdges() const;
+        virtual SMDSAbs_ElementType  GetType() const;    
+        virtual SMDSAbs_EntityType   GetEntityType() const;
+        virtual SMDSAbs_GeometryType GetGeomType() const;
 
   /*!
    * \brief Return node by its index
     * \param ind - node index
     * \retval const SMDS_MeshNode* - the node
-   * 
-   * Index is wrapped if it is out of a valid range
    */
   virtual const SMDS_MeshNode* GetNode(const int ind) const;
 
   protected:
-       SMDS_ElemIteratorPtr
-               elementsIterator(SMDSAbs_ElementType type) const;
-       const SMDS_MeshNode** myNodes;
-       int                   myNbNodes;
+        SMDS_ElemIteratorPtr
+                elementsIterator(SMDSAbs_ElementType type) const;
+        const SMDS_MeshNode** myNodes;
+        int                   myNbNodes;
+
 };
+
 #endif
index 0984cb50557e7f684a05180d4f827760c948cd42..841d2354078e16761d4f199c4c189b93391d6c91 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File      : SMDS_VolumeTool.cxx
 // Created   : Tue Jul 13 12:22:13 2004
 // Author    : Edward AGAPOV (eap)
 
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
-#include "SMDS_PolyhedralVolumeOfNodes.hxx"
+#include "SMDS_VtkVolume.hxx"
 #include "SMDS_Mesh.hxx"
 
 #include "utilities.h"
 
 #include <map>
-#include <float.h>
-#include <math.h>
+#include <limits>
+#include <cmath>
 
 using namespace std;
 
@@ -46,6 +47,10 @@ using namespace std;
 // Node indices in faces depending on volume orientation
 // making most faces normals external
 // ======================================================
+// For all elements, 0-th face is bottom based on the first nodes.
+// For prismatic elements (tetra,hexa,prisms), 1-th face is a top one.
+// For all elements, side faces follow order of bottom nodes
+// ======================================================
 
 /*
 //           N3
@@ -66,11 +71,6 @@ static int Tetra_F [4][4] = { // FORWARD == EXTERNAL
   { 0, 3, 1, 0 },
   { 1, 3, 2, 1 },
   { 0, 2, 3, 0 }}; 
-static int Tetra_R [4][4] = { // REVERSED
-  { 0, 1, 2, 0 },             // All faces but a bottom have external normals
-  { 0, 1, 3, 0 },
-  { 1, 2, 3, 1 },
-  { 0, 3, 2, 0 }};
 static int Tetra_RE [4][4] = { // REVERSED -> FORWARD (EXTERNAL)
   { 0, 2, 1, 0 },              // All faces have external normals
   { 0, 1, 3, 0 },
@@ -86,13 +86,8 @@ static int Pyramid_F [5][5] = { // FORWARD == EXTERNAL
   { 0, 4, 1, 0, 4 },
   { 1, 4, 2, 1, 4 },
   { 2, 4, 3, 2, 4 },
-  { 3, 4, 0, 3, 4 }}; 
-static int Pyramid_R [5][5] = { // REVERSED
-  { 0, 1, 2, 3, 0 },            // All faces but a bottom have external normals
-  { 0, 1, 4, 0, 4 },
-  { 1, 2, 4, 1, 4 },
-  { 2, 3, 4, 2, 4 },
-  { 3, 0, 4, 3, 4 }}; 
+  { 3, 4, 0, 3, 4 }
+}; 
 static int Pyramid_RE [5][5] = { // REVERSED -> FORWARD (EXTERNAL)
   { 0, 3, 2, 1, 0 },             // All faces but a bottom have external normals
   { 0, 1, 4, 0, 4 },
@@ -117,29 +112,17 @@ static int Pyramid_nbN [] = { 4, 3, 3, 3, 3 };
 //    N0 +---------+ N2
 */
 static int Penta_F [5][5] = { // FORWARD
-  { 0, 1, 2, 0, 0 },          // Top face has an internal normal, other - external
-  { 3, 4, 5, 3, 3 },          // 0 is bottom, 1 is top face
-  { 0, 2, 5, 3, 0 },
-  { 1, 4, 5, 2, 1 },
-  { 0, 3, 4, 1, 0 }}; 
-static int Penta_R [5][5] = { // REVERSED
-  { 0, 1, 2, 0, 0 },          // Bottom face has an internal normal, other - external
-  { 3, 4, 5, 3, 3 },          // 0 is bottom, 1 is top face
-  { 0, 3, 5, 2, 0 },
-  { 1, 2, 5, 4, 1 },
-  { 0, 1, 4, 3, 0 }}; 
-static int Penta_FE [5][5] = { // FORWARD -> EXTERNAL
-  { 0, 1, 2, 0, 0 },
-  { 3, 5, 4, 3, 3 },
-  { 0, 2, 5, 3, 0 },
+  { 0, 1, 2, 0, 0 },          // All faces have external normals
+  { 3, 5, 4, 3, 3 },          // 0 is bottom, 1 is top face
+  { 0, 3, 4, 1, 0 },
   { 1, 4, 5, 2, 1 },
-  { 0, 3, 4, 1, 0 }}; 
+  { 0, 2, 5, 3, 0 }}; 
 static int Penta_RE [5][5] = { // REVERSED -> EXTERNAL
   { 0, 2, 1, 0, 0 },
   { 3, 4, 5, 3, 3 },
-  { 0, 3, 5, 2, 0 },
+  { 0, 1, 4, 3, 0 },
   { 1, 2, 5, 4, 1 },
-  { 0, 1, 4, 3, 0 }}; 
+  { 0, 3, 5, 2, 0 }}; 
 static int Penta_nbN [] = { 3, 3, 4, 4, 4 };
 
 /*
@@ -158,35 +141,58 @@ static int Penta_nbN [] = { 3, 3, 4, 4, 4 };
 //     N0+----------+N3
 */
 static int Hexa_F [6][5] = { // FORWARD
-  { 0, 1, 2, 3, 0 },         // opposite faces are neighbouring,
-  { 4, 5, 6, 7, 4 },         // odd face(1,3,5) normal is internal, even(0,2,4) - external
-  { 1, 0, 4, 5, 1 },         // same index nodes of opposite faces are linked
-  { 2, 3, 7, 6, 2 }, 
-  { 0, 3, 7, 4, 0 }, 
-  { 1, 2, 6, 5, 1 }};
-// static int Hexa_R [6][5] = { // REVERSED
-//   { 0, 3, 2, 1, 0 },         // opposite faces are neighbouring,
-//   { 4, 7, 6, 5, 4 },         // odd face(1,3,5) normal is external, even(0,2,4) - internal
-//   { 1, 5, 4, 0, 1 },         // same index nodes of opposite faces are linked
-//   { 2, 6, 7, 3, 2 }, 
-//   { 0, 4, 7, 3, 0 }, 
-//   { 1, 5, 6, 2, 1 }};
-static int Hexa_FE [6][5] = { // FORWARD -> EXTERNAL
-  { 0, 1, 2, 3, 0 } ,         // opposite faces are neighbouring,
-  { 4, 7, 6, 5, 4 },          // all face normals are external,
-  { 0, 4, 5, 1, 0 },          // links in opposite faces: 0-0, 1-3, 2-2, 3-1
+  { 0, 1, 2, 3, 0 },
+  { 4, 7, 6, 5, 4 },          // all face normals are external
+  { 0, 4, 5, 1, 0 },
+  { 1, 5, 6, 2, 1 },
   { 3, 2, 6, 7, 3 }, 
-  { 0, 3, 7, 4, 0 },
-  { 1, 5, 6, 2, 1 }};
+  { 0, 3, 7, 4, 0 }};
 static int Hexa_RE [6][5] = { // REVERSED -> EXTERNAL
-  { 0, 3, 2, 1, 0 },          // opposite faces are neighbouring,
-  { 4, 5, 6, 7, 4 },          // all face normals are external,
-  { 0, 1, 5, 4, 0 },          // links in opposite faces: 0-0, 1-3, 2-2, 3-1
+  { 0, 3, 2, 1, 0 },
+  { 4, 5, 6, 7, 4 },          // all face normals are external
+  { 0, 1, 5, 4, 0 },
+  { 1, 2, 6, 5, 1 },
   { 3, 7, 6, 2, 3 }, 
-  { 0, 4, 7, 3, 0 },
-  { 1, 2, 6, 5, 1 }};
+  { 0, 4, 7, 3, 0 }};
 static int Hexa_nbN [] = { 4, 4, 4, 4, 4, 4 };
 
+/*   
+//      N8 +------+ N9
+//        /        \
+//       /          \
+//   N7 +            + N10
+//       \          /
+//        \        /
+//      N6 +------+ N11
+//                             HEXAGONAL PRISM
+//      N2 +------+ N3
+//        /        \
+//       /          \
+//   N1 +            + N4
+//       \          /
+//        \        /
+//      N0 +------+ N5
+*/
+static int HexPrism_F [8][7] = { // FORWARD
+  { 0, 1, 2, 3, 4, 5, 0 },
+  { 6,11,10, 9, 8, 7, 6 },
+  { 0, 6, 7, 1, 0, 0, 0 },
+  { 1, 7, 8, 2, 1, 1, 1 },
+  { 2, 8, 9, 3, 2, 2, 2 },
+  { 3, 9,10, 4, 3, 3, 3 },
+  { 4,10,11, 5, 4, 4, 4 },
+  { 5,11, 6, 0, 5, 5, 5 }}; 
+static int HexPrism_RE [8][7] = { // REVERSED -> EXTERNAL
+  { 0, 5, 4, 3, 2, 1, 0 },
+  { 6,11,10, 9, 8, 7, 6 },
+  { 0, 6, 7, 1, 0, 0, 0 },
+  { 1, 7, 8, 2, 1, 1, 1 },
+  { 2, 8, 9, 3, 2, 2, 2 },
+  { 3, 9,10, 4, 3, 3, 3 },
+  { 4,10,11, 5, 4, 4, 4 },
+  { 5,11, 6, 0, 5, 5, 5 }}; 
+static int HexPrism_nbN [] = { 6, 6, 4, 4, 4, 4, 4, 4 };
+
 
 /*
 //           N3
@@ -202,18 +208,13 @@ static int Hexa_nbN [] = { 4, 4, 4, 4, 4, 4 };
 //           +
 //           N2
 */
-static int QuadTetra_F [4][7] = { // FORWARD == EXTERNAL
+static int QuadTetra_F [4][7] = { // FORWARD
   { 0, 4, 1, 5, 2, 6, 0 },        // All faces have external normals
   { 0, 7, 3, 8, 1, 4, 0 },
   { 1, 8, 3, 9, 2, 5, 1 },
   { 0, 6, 2, 9, 3, 7, 0 }}; 
-static int QuadTetra_R [4][7] = { // REVERSED
-  { 0, 4, 1, 5, 2, 6, 0 },        // All faces but a bottom have external normals
-  { 0, 4, 1, 8, 3, 7, 0 },
-  { 1, 5, 2, 9, 3, 8, 1 },
-  { 0, 7, 3, 9, 2, 6, 0 }};
 static int QuadTetra_RE [4][7] = { // REVERSED -> FORWARD (EXTERNAL)
-  { 0, 6, 2, 5, 1, 4, 0 },              // All faces have external normals
+  { 0, 6, 2, 5, 1, 4, 0 },         // All faces have external normals
   { 0, 4, 1, 8, 3, 7, 0 },
   { 1, 5, 2, 9, 3, 8, 1 },
   { 0, 7, 3, 9, 2, 6, 0 }};
@@ -240,18 +241,12 @@ static int QuadTetra_nbN [] = { 6, 6, 6, 6 };
 //       |         |
 //      0+----+----+3
 //            8
-static int QuadPyram_F [5][9] = {  // FORWARD == EXTERNAL
+static int QuadPyram_F [5][9] = {  // FORWARD
   { 0, 5, 1, 6, 2, 7, 3, 8, 0 },   // All faces have external normals
   { 0, 9, 4, 10,1, 5, 0, 4, 4 },
   { 1, 10,4, 11,2, 6, 1, 4, 4 },
   { 2, 11,4, 12,3, 7, 2, 4, 4 },
   { 3, 12,4, 9, 0, 8, 3, 4, 4 }}; 
-static int QuadPyram_R [5][9] = {  // REVERSED
-  { 0, 5, 1, 6, 2, 7, 3, 8, 0 },   // All faces but a bottom have external normals
-  { 0, 5, 1, 10,4, 9, 0, 4, 4 },
-  { 1, 6, 2, 11,4, 10,1, 4, 4 },
-  { 2, 7, 3, 12,4, 11,2, 4, 4 },
-  { 3, 8, 0, 9, 4, 12,3, 4, 4 }}; 
 static int QuadPyram_RE [5][9] = { // REVERSED -> FORWARD (EXTERNAL)
   { 0, 8, 3, 7, 2, 6, 1, 5, 0 },   // All faces but a bottom have external normals
   { 0, 5, 1, 10,4, 9, 0, 4, 4 },
@@ -271,9 +266,6 @@ static int QuadPyram_nbN [] = { 8, 6, 6, 6, 6 };
 //       |    |    |
 //       |    +13  |                QUADRATIC
 //       |    |    |                PENTAHEDRON
-//       |    |    |
-//       |    |    |
-//       |    |    |
 //     12+    |    +14
 //       |    |    |
 //       |    |    |
@@ -286,29 +278,17 @@ static int QuadPyram_nbN [] = { 8, 6, 6, 6, 6 };
 //            8
 */
 static int QuadPenta_F [5][9] = {  // FORWARD
-  { 0, 6, 1, 7, 2, 8, 0, 0, 0 },   // Top face has an internal normal, other - external
-  { 3, 9, 4, 10,5, 11,3, 3, 3 },   // 0 is bottom, 1 is top face
-  { 0, 8, 2, 14,5, 11,3, 12,0 },
-  { 1, 13,4, 10,5, 14,2, 7, 1 },
-  { 0, 12,3, 9, 4, 13,1, 6, 0 }}; 
-static int QuadPenta_R [5][9] = { // REVERSED
-  { 0, 6, 1, 7, 2, 8, 0, 0, 0 },  // Bottom face has an internal normal, other - external
-  { 3, 9, 4, 10,5, 11,3, 3, 3 },  // 0 is bottom, 1 is top face
-  { 0, 12,3, 11,5, 14,2, 8, 0 },
-  { 1, 7, 2, 14,5, 10,4, 13,1 },
-  { 0, 6, 1, 13,4, 9, 3, 12,0 }}; 
-static int QuadPenta_FE [5][9] = { // FORWARD -> EXTERNAL
   { 0, 6, 1, 7, 2, 8, 0, 0, 0 },
   { 3,11, 5, 10,4, 9, 3, 3, 3 },
-  { 0, 8, 2, 14,5, 11,3, 12,0 },
+  { 0, 12,3, 9, 4, 13,1, 6, 0 },
   { 1, 13,4, 10,5, 14,2, 7, 1 },
-  { 0, 12,3, 9, 4, 13,1, 6, 0 }}; 
+  { 0, 8, 2, 14,5, 11,3, 12,0 }}; 
 static int QuadPenta_RE [5][9] = { // REVERSED -> EXTERNAL
   { 0, 8, 2, 7, 1, 6, 0, 0, 0 },
   { 3, 9, 4, 10,5, 11,3, 3, 3 },
-  { 0, 12,3, 11,5, 14,2, 8, 0 },
+  { 0, 6, 1, 13,4, 9, 3, 12,0 },
   { 1, 7, 2, 14,5, 10,4, 13,1 },
-  { 0, 6, 1, 13,4, 9, 3, 12,0 }}; 
+  { 0, 12,3, 11,5, 14,2, 8, 0 }}; 
 static int QuadPenta_nbN [] = { 6, 6, 8, 8, 8 };
 
 /*
@@ -335,39 +315,43 @@ static int QuadPenta_nbN [] = { 6, 6, 8, 8, 8 };
 //             11
 */
 static int QuadHexa_F [6][9] = {  // FORWARD
-  { 0, 8, 1, 9, 2, 10,3, 11,0 },  // opposite faces are neighbouring,
-  { 4, 12,5, 13,6, 14,7, 15,4 },  // odd face(1,3,5) normal is internal, even(0,2,4) - external
-  { 1, 8, 0, 16,4, 12,5, 17,1 },  // same index nodes of opposite faces are linked
-  { 2, 10,3, 19,7, 14,6, 18,2 }, 
-  { 0, 11,3, 19,7, 15,4, 16,0 }, 
-  { 1, 9, 2, 18,6, 13,5, 17,1 }};
-// static int Hexa_R [6][5] = { // REVERSED
-//   { 0, 3, 2, 1, 0 },         // opposite faces are neighbouring,
-//   { 4, 7, 6, 5, 4 },         // odd face(1,3,5) normal is external, even(0,2,4) - internal
-//   { 1, 5, 4, 0, 1 },         // same index nodes of opposite faces are linked
-//   { 2, 6, 7, 3, 2 }, 
-//   { 0, 4, 7, 3, 0 }, 
-//   { 1, 5, 6, 2, 1 }};
-static int QuadHexa_FE [6][9] = {  // FORWARD -> EXTERNAL
-  { 0, 8, 1, 9, 2, 10,3, 11,0 },   // opposite faces are neighbouring,
-  { 4, 15,7, 14,6, 13,5, 12,4 },   // all face normals are external,
-  { 0, 16,4, 12,5, 17,1, 8, 0 },   // links in opposite faces: 0-0, 1-3, 2-2, 3-1
+  { 0, 8, 1, 9, 2, 10,3, 11,0 },   // all face normals are external,
+  { 4, 15,7, 14,6, 13,5, 12,4 },
+  { 0, 16,4, 12,5, 17,1, 8, 0 },
+  { 1, 17,5, 13,6, 18,2, 9, 1 },
   { 3, 10,2, 18,6, 14,7, 19,3 }, 
-  { 0, 11,3, 19,7, 15,4, 16,0 },
-  { 1, 17,5, 13,6, 18,2, 9, 1 }};
+  { 0, 11,3, 19,7, 15,4, 16,0 }};
 static int QuadHexa_RE [6][9] = {  // REVERSED -> EXTERNAL
-  { 0, 11,3, 10,2, 9, 1, 8, 0 },   // opposite faces are neighbouring,
-  { 4, 12,5, 13,6, 14,7, 15,4 },   // all face normals are external,
-  { 0, 8, 1, 17,5, 12,4, 16,0 },   // links in opposite faces: 0-0, 1-3, 2-2, 3-1
+  { 0, 11,3, 10,2, 9, 1, 8, 0 },   // all face normals are external
+  { 4, 12,5, 13,6, 14,7, 15,4 },
+  { 0, 8, 1, 17,5, 12,4, 16,0 },
+  { 1, 9, 2, 18,6, 13,5, 17,1 },
   { 3, 19,7, 14,6, 18,2, 10,3 }, 
-  { 0, 16,4, 15,7, 19,3, 11,0 },
-  { 1, 9, 2, 18,6, 13,5, 17,1 }};
+  { 0, 16,4, 15,7, 19,3, 11,0 }};
 static int QuadHexa_nbN [] = { 8, 8, 8, 8, 8, 8 };
 
+static int TriQuadHexa_F [6][9] = {  // FORWARD
+  { 0, 8, 1, 9, 2, 10,3, 11, 20 },   // all face normals are external
+  { 4, 15,7, 14,6, 13,5, 12, 25 },
+  { 0, 16,4, 12,5, 17,1, 8,  21 },
+  { 1, 17,5, 13,6, 18,2, 9,  22 },
+  { 3, 10,2, 18,6, 14,7, 19, 23 }, 
+  { 0, 11,3, 19,7, 15,4, 16, 24 }};
+static int TriQuadHexa_RE [6][9] = {  // REVERSED -> EXTERNAL
+  { 0, 11,3, 10,2, 9, 1, 8,  20 },   // opposite faces are neighbouring,
+  { 4, 12,5, 13,6, 14,7, 15, 25 },   // all face normals are external
+  { 0, 8, 1, 17,5, 12,4, 16, 21 },
+  { 1, 9, 2, 18,6, 13,5, 17, 22 },
+  { 3, 19,7, 14,6, 18,2, 10, 23 }, 
+  { 0, 16,4, 15,7, 19,3, 11, 24 }};
+static int TriQuadHexa_nbN [] = { 9, 9, 9, 9, 9, 9 };
+
 
 // ========================================================
 // to perform some calculations without linkage to CASCADE
 // ========================================================
+namespace
+{
 struct XYZ {
   double x;
   double y;
@@ -376,25 +360,56 @@ struct XYZ {
   XYZ( double X, double Y, double Z ) { x = X; y = Y; z = Z; }
   XYZ( const XYZ& other )             { x = other.x; y = other.y; z = other.z; }
   XYZ( const SMDS_MeshNode* n )       { x = n->X(); y = n->Y(); z = n->Z(); }
-  XYZ operator-( const XYZ& other );
-  XYZ Crossed( const XYZ& other );
-  double Dot( const XYZ& other );
-  double Magnitude();
+  inline XYZ operator-( const XYZ& other );
+  inline XYZ operator+( const XYZ& other );
+  inline XYZ Crossed( const XYZ& other );
+  inline double Dot( const XYZ& other );
+  inline double Magnitude();
+  inline double SquareMagnitude();
 };
-XYZ XYZ::operator-( const XYZ& Right ) {
+inline XYZ XYZ::operator-( const XYZ& Right ) {
   return XYZ(x - Right.x, y - Right.y, z - Right.z);
 }
-XYZ XYZ::Crossed( const XYZ& Right ) {
+inline XYZ XYZ::operator+( const XYZ& Right ) {
+  return XYZ(x + Right.x, y + Right.y, z + Right.z);
+}
+inline XYZ XYZ::Crossed( const XYZ& Right ) {
   return XYZ (y * Right.z - z * Right.y,
               z * Right.x - x * Right.z,
               x * Right.y - y * Right.x);
 }
-double XYZ::Dot( const XYZ& Other ) {
+inline double XYZ::Dot( const XYZ& Other ) {
   return(x * Other.x + y * Other.y + z * Other.z);
 }
-double XYZ::Magnitude() {
+inline double XYZ::Magnitude() {
   return sqrt (x * x + y * y + z * z);
 }
+inline double XYZ::SquareMagnitude() {
+  return (x * x + y * y + z * z);
+}
+
+  //================================================================================
+  /*!
+   * \brief Return linear type corresponding to a quadratic one
+   */
+  //================================================================================
+
+  SMDS_VolumeTool::VolumeType quadToLinear(SMDS_VolumeTool::VolumeType quadType)
+  {
+    SMDS_VolumeTool::VolumeType linType = SMDS_VolumeTool::VolumeType( int(quadType)-4 );
+    const int nbCornersByQuad = SMDS_VolumeTool::NbCornerNodes( quadType );
+    if ( SMDS_VolumeTool::NbCornerNodes( linType ) == nbCornersByQuad )
+      return linType;
+
+    int iLin = 0;
+    for ( ; iLin < SMDS_VolumeTool::NB_VOLUME_TYPES; ++iLin )
+      if ( SMDS_VolumeTool::NbCornerNodes( SMDS_VolumeTool::VolumeType( iLin )) == nbCornersByQuad)
+        return SMDS_VolumeTool::VolumeType( iLin );
+
+    return SMDS_VolumeTool::UNKNOWN;
+  }
+
+} // namespace
 
 //=======================================================================
 //function : SMDS_VolumeTool
@@ -402,18 +417,10 @@ double XYZ::Magnitude() {
 //=======================================================================
 
 SMDS_VolumeTool::SMDS_VolumeTool ()
-     : myVolume( 0 ),
-       myPolyedre( 0 ),
-       myVolForward( true ),
-       myNbFaces( 0 ),
-       myVolumeNbNodes( 0 ),
-       myVolumeNodes( NULL ),
-       myExternalFaces( false ),
-       myFaceNbNodes( 0 ),
-       myCurFace( -1 ),
-       myFaceNodeIndices( NULL ),
-       myFaceNodes( NULL )
+  : myVolumeNodes( NULL ),
+    myFaceNodes( NULL )
 {
+  Set( 0 );
 }
 
 //=======================================================================
@@ -421,20 +428,12 @@ SMDS_VolumeTool::SMDS_VolumeTool ()
 //purpose  : 
 //=======================================================================
 
-SMDS_VolumeTool::SMDS_VolumeTool (const SMDS_MeshElement* theVolume)
-     : myVolume( 0 ),
-       myPolyedre( 0 ),
-       myVolForward( true ),
-       myNbFaces( 0 ),
-       myVolumeNbNodes( 0 ),
-       myVolumeNodes( NULL ),
-       myExternalFaces( false ),
-       myFaceNbNodes( 0 ),
-       myCurFace( -1 ),
-       myFaceNodeIndices( NULL ),
-       myFaceNodes( NULL )
+SMDS_VolumeTool::SMDS_VolumeTool (const SMDS_MeshElement* theVolume,
+                                  const bool              ignoreCentralNodes)
+  : myVolumeNodes( NULL ),
+    myFaceNodes( NULL )
 {
-  Set( theVolume );
+  Set( theVolume, ignoreCentralNodes );
 }
 
 //=======================================================================
@@ -444,14 +443,11 @@ SMDS_VolumeTool::SMDS_VolumeTool (const SMDS_MeshElement* theVolume)
 
 SMDS_VolumeTool::~SMDS_VolumeTool()
 {
-  if (myVolumeNodes != NULL) {
-    delete [] myVolumeNodes;
-    myVolumeNodes = NULL;
-  }
-  if (myFaceNodes != NULL) {
-    delete [] myFaceNodes;
-    myFaceNodes = NULL;
-  }
+  if ( myVolumeNodes != NULL ) delete [] myVolumeNodes;
+  if ( myFaceNodes != NULL   ) delete [] myFaceNodes;
+
+  myFaceNodeIndices = NULL;
+  myVolumeNodes = myFaceNodes = NULL;
 }
 
 //=======================================================================
@@ -459,10 +455,13 @@ SMDS_VolumeTool::~SMDS_VolumeTool()
 //purpose  : Set volume to iterate on
 //=======================================================================
 
-bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume)
+bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume,
+                           const bool              ignoreCentralNodes)
 {
+  // reset fields
   myVolume = 0;
   myPolyedre = 0;
+  myIgnoreCentralNodes = ignoreCentralNodes;
 
   myVolForward = true;
   myNbFaces = 0;
@@ -471,66 +470,63 @@ bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume)
     delete [] myVolumeNodes;
     myVolumeNodes = NULL;
   }
+  myPolyIndices.clear();
 
   myExternalFaces = false;
-  myFaceNbNodes = 0;
+
+  myAllFacesNodeIndices_F  = 0;
+  //myAllFacesNodeIndices_FE = 0;
+  myAllFacesNodeIndices_RE = 0;
+  myAllFacesNbNodes        = 0;
 
   myCurFace = -1;
+  myFaceNbNodes = 0;
   myFaceNodeIndices = NULL;
   if (myFaceNodes != NULL) {
     delete [] myFaceNodes;
     myFaceNodes = NULL;
   }
 
-  if ( theVolume && theVolume->GetType() == SMDSAbs_Volume )
-  {
-    myVolume = theVolume;
+  // set volume data
+  if ( !theVolume || theVolume->GetType() != SMDSAbs_Volume )
+    return false;
 
-    myNbFaces = theVolume->NbFaces();
-    myVolumeNbNodes = theVolume->NbNodes();
+  myVolume = theVolume;
+  if (myVolume->IsPoly())
+    myPolyedre = dynamic_cast<const SMDS_VtkVolume*>( myVolume );
 
-    // set volume nodes
-    int iNode = 0;
-    myVolumeNodes = new const SMDS_MeshNode* [myVolumeNbNodes];
-    SMDS_ElemIteratorPtr nodeIt = myVolume->nodesIterator();
-    while ( nodeIt->more() ) {
-      myVolumeNodes[ iNode++ ] = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-    }
+  myNbFaces = theVolume->NbFaces();
+  myVolumeNbNodes = theVolume->NbNodes();
 
-    if (myVolume->IsPoly()) {
-      myPolyedre = static_cast<const SMDS_PolyhedralVolumeOfNodes*>( myVolume );
-      if (!myPolyedre) {
-        MESSAGE("Warning: bad volumic element");
-        return false;
-      }
-    }
-    else {
-      switch ( myVolumeNbNodes ) {
-      case 4:
-      case 5:
-      case 6:
-      case 8:
-      case 10:
-      case 13:
-      case 15:
-      case 20: {
-        // define volume orientation
-        XYZ botNormal;
-        GetFaceNormal( 0, botNormal.x, botNormal.y, botNormal.z );
-        const SMDS_MeshNode* topNode = myVolumeNodes[ myVolumeNbNodes - 1 ];
-        const SMDS_MeshNode* botNode = myVolumeNodes[ 0 ];
-        XYZ upDir (topNode->X() - botNode->X(),
-                   topNode->Y() - botNode->Y(),
-                   topNode->Z() - botNode->Z() );
-        myVolForward = ( botNormal.Dot( upDir ) < 0 );
-        break;
-      }
-      default:
-        break;
-      }
-    }
+  // set nodes
+  int iNode = 0;
+  myVolumeNodes = new const SMDS_MeshNode* [myVolumeNbNodes];
+  SMDS_ElemIteratorPtr nodeIt = myVolume->nodesIterator();
+  while ( nodeIt->more() )
+    myVolumeNodes[ iNode++ ] = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+
+  // check validity
+  if ( !setFace(0) )
+    return ( myVolume = 0 );
+
+  if ( !myPolyedre )
+  {
+    // define volume orientation
+    XYZ botNormal;
+    GetFaceNormal( 0, botNormal.x, botNormal.y, botNormal.z );
+    const SMDS_MeshNode* botNode = myVolumeNodes[ 0 ];
+    int topNodeIndex = myVolume->NbCornerNodes() - 1;
+    while ( !IsLinked( 0, topNodeIndex, /*ignoreMediumNodes=*/true )) --topNodeIndex;
+    const SMDS_MeshNode* topNode = myVolumeNodes[ topNodeIndex ];
+    XYZ upDir (topNode->X() - botNode->X(),
+               topNode->Y() - botNode->Y(),
+               topNode->Z() - botNode->Z() );
+    myVolForward = ( botNormal.Dot( upDir ) < 0 );
+
+    if ( !myVolForward )
+      myCurFace = -1; // previous setFace(0) didn't take myVolForward into account
   }
-  return ( myVolume != 0 );
+  return true;
 }
 
 //=======================================================================
@@ -572,6 +568,12 @@ void SMDS_VolumeTool::Inverse ()
     SWAP_NODES( myVolumeNodes, 1, 3 );
     SWAP_NODES( myVolumeNodes, 5, 7 );
     break;
+  case 12:
+    SWAP_NODES( myVolumeNodes, 1, 5 );
+    SWAP_NODES( myVolumeNodes, 2, 4 );
+    SWAP_NODES( myVolumeNodes, 7, 11 );
+    SWAP_NODES( myVolumeNodes, 8, 10 );
+    break;
 
   case 10:
     SWAP_NODES( myVolumeNodes, 1, 2 );
@@ -600,6 +602,17 @@ void SMDS_VolumeTool::Inverse ()
     SWAP_NODES( myVolumeNodes, 13, 14 );
     SWAP_NODES( myVolumeNodes, 17, 19 );
     break;
+  case 27:
+    SWAP_NODES( myVolumeNodes, 1, 3 );
+    SWAP_NODES( myVolumeNodes, 5, 7 );
+    SWAP_NODES( myVolumeNodes, 8, 11 );
+    SWAP_NODES( myVolumeNodes, 9, 10 );
+    SWAP_NODES( myVolumeNodes, 12, 15 );
+    SWAP_NODES( myVolumeNodes, 13, 14 );
+    SWAP_NODES( myVolumeNodes, 17, 19 );
+    SWAP_NODES( myVolumeNodes, 21, 24 );
+    SWAP_NODES( myVolumeNodes, 22, 23 );
+    break;
   default:;
   }
 }
@@ -614,26 +627,18 @@ SMDS_VolumeTool::VolumeType SMDS_VolumeTool::GetVolumeType() const
   if ( myPolyedre )
     return POLYHEDA;
 
-  if ( myVolume ) {
-//    static const VolumeType types[] = {
-//      TETRA,     // myVolumeNbNodes = 4
-//      PYRAM,     // myVolumeNbNodes = 5
-//      PENTA,     // myVolumeNbNodes = 6
-//      UNKNOWN,   // myVolumeNbNodes = 7
-//      HEXA       // myVolumeNbNodes = 8
-//    };
-//    return types[ myVolumeNbNodes - 4 ];
-    switch(myVolumeNbNodes) {
-    case 4: return TETRA; break;
-    case 5: return PYRAM; break;
-    case 6: return PENTA; break;
-    case 8: return HEXA; break;
-    case 10: return QUAD_TETRA; break;
-    case 13: return QUAD_PYRAM; break;
-    case 15: return QUAD_PENTA; break;
-    case 20: return QUAD_HEXA; break;
-    default: break;
-    }
+  switch( myVolumeNbNodes ) {
+  case 4: return TETRA;
+  case 5: return PYRAM;
+  case 6: return PENTA;
+  case 8: return HEXA;
+  case 12: return HEX_PRISM;
+  case 10: return QUAD_TETRA;
+  case 13: return QUAD_PYRAM;
+  case 15: return QUAD_PENTA;
+  case 20: return QUAD_HEXA;
+  case 27: return QUAD_HEXA;
+  default: break;
   }
 
   return UNKNOWN;
@@ -693,30 +698,29 @@ double SMDS_VolumeTool::GetSize() const
 
     // split a polyhedron into tetrahedrons
 
+    int saveCurFace = myCurFace;
     SMDS_VolumeTool* me = const_cast< SMDS_VolumeTool* > ( this );
-    XYZ baryCenter;
-    me->GetBaryCenter(baryCenter.x, baryCenter.y, baryCenter.z);
-    SMDS_MeshNode bcNode ( baryCenter.x, baryCenter.y, baryCenter.z );
-
     for ( int f = 0; f < NbFaces(); ++f )
     {
-      bool externalFace = me->IsFaceExternal( f ); // it calls setFace()
-      for ( int n = 2; n < myFaceNbNodes; ++n )
+      me->setFace( f );
+      XYZ area (0,0,0), p1( myFaceNodes[0] );
+      for ( int n = 0; n < myFaceNbNodes; ++n )
       {
-        double Vn = getTetraVolume( myFaceNodes[ 0 ],
-                                    myFaceNodes[ n-1 ],
-                                    myFaceNodes[ n ],
-                                    & bcNode );
-///         cout <<"++++   " << Vn << "   nodes " <<myFaceNodes[ 0 ]->GetID() << " " <<myFaceNodes[ n-1 ]->GetID() << " " <<myFaceNodes[ n ]->GetID() << "        < " << V << endl;
-        V += externalFace ? -Vn : Vn;
+        XYZ p2( myFaceNodes[ n+1 ]);
+        area = area + p1.Crossed( p2 );
+        p1 = p2;
       }
+      V += p1.Dot( area );
     }
+    V /= 6;
+    if ( saveCurFace > -1 && saveCurFace != myCurFace )
+      me->setFace( myCurFace );
   }
   else 
   {
     const static int ind[] = {
-      0, 1, 3, 6, 11, 19, 32, 46, 66};
-    const static int vtab[][4] = {
+      0, 1, 3, 6, 11, 23, 31, 44, 58, 78 };
+    const static int vtab[][4] = { // decomposition into tetra in the order of enum VolumeType
       // tetrahedron
       { 0, 1, 2, 3 },
       // pyramid
@@ -732,6 +736,22 @@ double SMDS_VolumeTool::GetSize() const
       { 1, 3, 6, 2 },
       { 4, 6, 3, 7 },
       { 1, 4, 6, 3 },
+      // hexagonal prism
+      { 0, 1, 2, 7 },
+      { 0, 7, 8, 6 },
+      { 2, 7, 8, 0 },
+
+      { 0, 3, 4, 9 },
+      { 0, 9, 10, 6 },
+      { 4, 9, 10, 0 },
+
+      { 0, 3, 4, 9 },
+      { 0, 9, 10, 6 },
+      { 4, 9, 10, 0 },
+
+      { 0, 4, 5, 10 },
+      { 0, 10, 11, 6 },
+      { 5, 10, 11, 0 },
 
       // quadratic tetrahedron
       { 0, 4, 6, 7 },
@@ -837,6 +857,32 @@ bool SMDS_VolumeTool::GetBaryCenter(double & X, double & Y, double & Z) const
   return true;
 }
 
+//================================================================================
+/*!
+ * \brief Classify a point
+ *  \param tol - thickness of faces
+ */
+//================================================================================
+
+bool SMDS_VolumeTool::IsOut(double X, double Y, double Z, double tol) const
+{
+  // LIMITATION: for convex volumes only
+  XYZ p( X,Y,Z );
+  for ( int iF = 0; iF < myNbFaces; ++iF )
+  {
+    XYZ faceNormal;
+    if ( !GetFaceNormal( iF, faceNormal.x, faceNormal.y, faceNormal.z ))
+      continue;
+    if ( !IsFaceExternal( iF ))
+      faceNormal = XYZ() - faceNormal; // reverse
+
+    XYZ face2p( p - XYZ( myFaceNodes[0] ));
+    if ( face2p.Dot( faceNormal ) > tol )
+      return true;
+  }
+  return false;
+}
+
 //=======================================================================
 //function : SetExternalNormal
 //purpose  : Node order will be so that faces normals are external
@@ -853,7 +899,7 @@ void SMDS_VolumeTool::SetExternalNormal ()
 //purpose  : Return number of nodes in the array of face nodes
 //=======================================================================
 
-int SMDS_VolumeTool::NbFaceNodes( int faceIndex )
+int SMDS_VolumeTool::NbFaceNodes( int faceIndex ) const
 {
     if ( !setFace( faceIndex ))
       return 0;
@@ -868,7 +914,7 @@ int SMDS_VolumeTool::NbFaceNodes( int faceIndex )
 //           the last node == the first one.
 //=======================================================================
 
-const SMDS_MeshNode** SMDS_VolumeTool::GetFaceNodes( int faceIndex )
+const SMDS_MeshNode** SMDS_VolumeTool::GetFaceNodes( int faceIndex ) const
 {
   if ( !setFace( faceIndex ))
     return 0;
@@ -883,14 +929,19 @@ const SMDS_MeshNode** SMDS_VolumeTool::GetFaceNodes( int faceIndex )
 //           the last node index == the first one.
 //=======================================================================
 
-const int* SMDS_VolumeTool::GetFaceNodesIndices( int faceIndex )
+const int* SMDS_VolumeTool::GetFaceNodesIndices( int faceIndex ) const
 {
-  if (myVolume->IsPoly()) {
-    MESSAGE("Warning: attempt to obtain FaceNodesIndices of polyhedral volume");
-    return NULL;
-  }
   if ( !setFace( faceIndex ))
     return 0;
+
+  if (myPolyedre)
+  {
+    SMDS_VolumeTool* me = const_cast< SMDS_VolumeTool* > ( this );
+    me->myPolyIndices.resize( myFaceNbNodes + 1 );
+    me->myFaceNodeIndices = & me->myPolyIndices[0];
+    for ( int i = 0; i <= myFaceNbNodes; ++i )
+      me->myFaceNodeIndices[i] = myVolume->GetNodeIndex( myFaceNodes[i] );
+  }
   return myFaceNodeIndices;
 }
 
@@ -900,25 +951,23 @@ const int* SMDS_VolumeTool::GetFaceNodesIndices( int faceIndex )
 //=======================================================================
 
 bool SMDS_VolumeTool::GetFaceNodes (int                        faceIndex,
-                                    set<const SMDS_MeshNode*>& theFaceNodes )
+                                    set<const SMDS_MeshNode*>& theFaceNodes ) const
 {
   if ( !setFace( faceIndex ))
     return false;
 
   theFaceNodes.clear();
-  int iNode, nbNode = myFaceNbNodes;
-  for ( iNode = 0; iNode < nbNode; iNode++ )
-    theFaceNodes.insert( myFaceNodes[ iNode ]);
+  theFaceNodes.insert( myFaceNodes, myFaceNodes + myFaceNbNodes );
 
   return true;
 }
 
 //=======================================================================
 //function : IsFaceExternal
-//purpose  : Check normal orientation of a returned face
+//purpose  : Check normal orientation of a given face
 //=======================================================================
 
-bool SMDS_VolumeTool::IsFaceExternal( int faceIndex )
+bool SMDS_VolumeTool::IsFaceExternal( int faceIndex ) const
 {
   if ( myExternalFaces || !myVolume )
     return true;
@@ -933,26 +982,29 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex )
     return true;
   }
 
-  switch ( myVolumeNbNodes ) {
-  case 4:
-  case 5:
-  case 10:
-  case 13:
-    // only the bottom of a reversed tetrahedron can be internal
-    return ( myVolForward || faceIndex != 0 );
-  case 6:
-  case 15:
-    // in a forward pentahedron, the top is internal, in a reversed one - bottom
-    return ( myVolForward ? faceIndex != 1 : faceIndex != 0 );
-  case 8:
-  case 20: {
-    // in a forward hexahedron, even face normal is external, odd - internal
-    bool odd = faceIndex % 2;
-    return ( myVolForward ? !odd : odd );
-  }
-  default:;
-  }
-  return false;
+  // switch ( myVolumeNbNodes ) {
+  // case 4:
+  // case 5:
+  // case 10:
+  // case 13:
+  //   // only the bottom of a reversed tetrahedron can be internal
+  //   return ( myVolForward || faceIndex != 0 );
+  // case 6:
+  // case 15:
+  // case 12:
+  //   // in a forward prism, the top is internal, in a reversed one - bottom
+  //   return ( myVolForward ? faceIndex != 1 : faceIndex != 0 );
+  // case 8:
+  // case 20:
+  // case 27: {
+  //   // in a forward hexahedron, even face normal is external, odd - internal
+  //   bool odd = faceIndex % 2;
+  //   return ( myVolForward ? !odd : odd );
+  // }
+  // default:;
+  // }
+  // return false;
+  return true;
 }
 
 //=======================================================================
@@ -960,30 +1012,28 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex )
 //purpose  : Return a normal to a face
 //=======================================================================
 
-bool SMDS_VolumeTool::GetFaceNormal (int faceIndex, double & X, double & Y, double & Z)
+bool SMDS_VolumeTool::GetFaceNormal (int faceIndex, double & X, double & Y, double & Z) const
 {
   if ( !setFace( faceIndex ))
     return false;
 
-  XYZ p1 ( myFaceNodes[0] );
-  XYZ p2 ( myFaceNodes[1] );
-  XYZ p3 ( myFaceNodes[2] );
+  const int iQuad = ( myFaceNbNodes > 6 && !myPolyedre ) ? 2 : 1;
+  XYZ p1 ( myFaceNodes[0*iQuad] );
+  XYZ p2 ( myFaceNodes[1*iQuad] );
+  XYZ p3 ( myFaceNodes[2*iQuad] );
   XYZ aVec12( p2 - p1 );
   XYZ aVec13( p3 - p1 );
   XYZ cross = aVec12.Crossed( aVec13 );
 
-  //if ( myFaceNbNodes == 4 ) {
-  if ( myFaceNbNodes >3 ) {
-    XYZ p4 ( myFaceNodes[3] );
+  if ( myFaceNbNodes >3*iQuad ) {
+    XYZ p4 ( myFaceNodes[3*iQuad] );
     XYZ aVec14( p4 - p1 );
     XYZ cross2 = aVec13.Crossed( aVec14 );
-    cross.x += cross2.x;
-    cross.y += cross2.y;
-    cross.z += cross2.z;    
+    cross = cross + cross2;
   }
 
   double size = cross.Magnitude();
-  if ( size <= DBL_MIN )
+  if ( size <= numeric_limits<double>::min() )
     return false;
 
   X = cross.x / size;
@@ -993,12 +1043,33 @@ bool SMDS_VolumeTool::GetFaceNormal (int faceIndex, double & X, double & Y, doub
   return true;
 }
 
+//================================================================================
+/*!
+ * \brief Return barycenter of a face
+ */
+//================================================================================
+
+bool SMDS_VolumeTool::GetFaceBaryCenter (int faceIndex, double & X, double & Y, double & Z) const
+{
+  if ( !setFace( faceIndex ))
+    return false;
+
+  X = Y = Z = 0.0;
+  for ( int i = 0; i < myFaceNbNodes; ++i )
+  {
+    X += myFaceNodes[i]->X() / myFaceNbNodes;
+    Y += myFaceNodes[i]->Y() / myFaceNbNodes;
+    Z += myFaceNodes[i]->Z() / myFaceNbNodes;
+  }
+  return true;
+}
+
 //=======================================================================
 //function : GetFaceArea
 //purpose  : Return face area
 //=======================================================================
 
-double SMDS_VolumeTool::GetFaceArea( int faceIndex )
+double SMDS_VolumeTool::GetFaceArea( int faceIndex ) const
 {
   if (myVolume->IsPoly()) {
     MESSAGE("Warning: attempt to obtain area of a face of polyhedral volume");
@@ -1023,6 +1094,26 @@ double SMDS_VolumeTool::GetFaceArea( int faceIndex )
   return area;
 }
 
+//================================================================================
+/*!
+ * \brief Return index of the node located at face center of a quadratic element like HEX27
+ */
+//================================================================================
+
+int SMDS_VolumeTool::GetCenterNodeIndex( int faceIndex ) const
+{
+  if ( myAllFacesNbNodes && myVolumeNbNodes == 27 ) // classic element with 27 nodes
+  {
+    switch ( faceIndex ) {
+    case 0: return 20;
+    case 1: return 25;
+    default:
+      return faceIndex + 19;
+    }
+  }
+  return -1;
+}
+
 //=======================================================================
 //function : GetOppFaceIndex
 //purpose  : Return index of the opposite face if it exists, else -1.
@@ -1031,19 +1122,37 @@ double SMDS_VolumeTool::GetFaceArea( int faceIndex )
 int SMDS_VolumeTool::GetOppFaceIndex( int faceIndex ) const
 {
   int ind = -1;
-  if (myVolume->IsPoly()) {
+  if (myPolyedre) {
     MESSAGE("Warning: attempt to obtain opposite face on polyhedral volume");
     return ind;
   }
 
+  const int nbHoriFaces = 2;
+
   if ( faceIndex >= 0 && faceIndex < NbFaces() ) {
     switch ( myVolumeNbNodes ) {
     case 6:
+    case 15:
       if ( faceIndex == 0 || faceIndex == 1 )
         ind = 1 - faceIndex;
         break;
     case 8:
-      ind = faceIndex + ( faceIndex % 2 ? -1 : 1 );
+    case 12:
+      if ( faceIndex <= 1 ) // top or bottom
+        ind = 1 - faceIndex;
+      else {
+        const int nbSideFaces = myAllFacesNbNodes[0];
+        ind = ( faceIndex - nbHoriFaces + nbSideFaces/2 ) % nbSideFaces + nbHoriFaces;
+      }
+      break;
+    case 20:
+    case 27:
+      if ( faceIndex <= 1 ) // top or bottom
+        ind = 1 - faceIndex;
+      else {
+        const int nbSideFaces = myAllFacesNbNodes[0] / 2;
+        ind = ( faceIndex - nbHoriFaces + nbSideFaces/2 ) % nbSideFaces + nbHoriFaces;
+      }
       break;
     default:;
     }
@@ -1054,10 +1163,12 @@ int SMDS_VolumeTool::GetOppFaceIndex( int faceIndex ) const
 //=======================================================================
 //function : IsLinked
 //purpose  : return true if theNode1 is linked with theNode2
+// If theIgnoreMediumNodes then corner nodes of quadratic cell are considered linked as well
 //=======================================================================
 
 bool SMDS_VolumeTool::IsLinked (const SMDS_MeshNode* theNode1,
-                                const SMDS_MeshNode* theNode2) const
+                                const SMDS_MeshNode* theNode2,
+                                const bool           theIgnoreMediumNodes) const
 {
   if ( !myVolume )
     return false;
@@ -1090,12 +1201,13 @@ bool SMDS_VolumeTool::IsLinked (const SMDS_MeshNode* theNode1,
   }
 
   // find nodes indices
-  int i1 = -1, i2 = -1;
-  for ( int i = 0; i < myVolumeNbNodes; i++ ) {
+  int i1 = -1, i2 = -1, nbFound = 0;
+  for ( int i = 0; i < myVolumeNbNodes && nbFound < 2; i++ )
+  {
     if ( myVolumeNodes[ i ] == theNode1 )
-      i1 = i;
+      i1 = i, ++nbFound;
     else if ( myVolumeNodes[ i ] == theNode2 )
-      i2 = i;
+      i2 = i, ++nbFound;
   }
   return IsLinked( i1, i2 );
 }
@@ -1104,10 +1216,12 @@ bool SMDS_VolumeTool::IsLinked (const SMDS_MeshNode* theNode1,
 //function : IsLinked
 //purpose  : return true if the node with theNode1Index is linked
 //           with the node with theNode2Index
+// If theIgnoreMediumNodes then corner nodes of quadratic cell are considered linked as well
 //=======================================================================
 
 bool SMDS_VolumeTool::IsLinked (const int theNode1Index,
-                                const int theNode2Index) const
+                                const int theNode2Index,
+                                bool      theIgnoreMediumNodes) const
 {
   if ( myVolume->IsPoly() ) {
     return IsLinked(myVolumeNodes[theNode1Index], myVolumeNodes[theNode2Index]);
@@ -1119,10 +1233,33 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index,
   if ( minInd < 0 || maxInd > myVolumeNbNodes - 1 || maxInd == minInd )
     return false;
 
-  switch ( myVolumeNbNodes ) {
-  case 4:
+  VolumeType type = GetVolumeType();
+  if ( myVolume->IsQuadratic() )
+  {
+    int firstMediumInd = myVolume->NbCornerNodes();
+    if ( minInd >= firstMediumInd )
+      return false; // both nodes are medium - not linked
+    if ( maxInd < firstMediumInd ) // both nodes are corners
+    {
+      if ( theIgnoreMediumNodes )
+        type = quadToLinear(type); // to check linkage of corner nodes only
+      else
+        return false; // corner nodes are not linked directly in a quadratic cell
+    }
+  }
+
+  switch ( type ) {
+  case TETRA:
     return true;
-  case 5:
+  case HEXA:
+    switch ( maxInd - minInd ) {
+    case 1: return minInd != 3;
+    case 3: return minInd == 0 || minInd == 4;
+    case 4: return true;
+    default:;
+    }
+    break;
+  case PYRAM:
     if ( maxInd == 4 )
       return true;
     switch ( maxInd - minInd ) {
@@ -1131,7 +1268,7 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index,
     default:;
     }
     break;
-  case 6:
+  case PENTA:
     switch ( maxInd - minInd ) {
     case 1: return minInd != 2;
     case 2: return minInd == 0 || minInd == 3;
@@ -1139,15 +1276,7 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index,
     default:;
     }
     break;
-  case 8:
-    switch ( maxInd - minInd ) {
-    case 1: return minInd != 3;
-    case 3: return minInd == 0 || minInd == 4;
-    case 4: return true;
-    default:;
-    }
-    break;
-  case 10:
+  case QUAD_TETRA:
     {
       switch ( minInd ) {
       case 0: if( maxInd==4 ||  maxInd==6 ||  maxInd==7 ) return true;
@@ -1158,7 +1287,22 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index,
       }
       break;
     }
-  case 13:
+  case QUAD_HEXA:
+    {
+      switch ( minInd ) {
+      case 0: if( maxInd==8 ||  maxInd==11 ||  maxInd==16 ) return true;
+      case 1: if( maxInd==8 ||  maxInd==9 ||  maxInd==17 ) return true;
+      case 2: if( maxInd==9 ||  maxInd==10 ||  maxInd==18 ) return true;
+      case 3: if( maxInd==10 ||  maxInd==11 ||  maxInd==19 ) return true;
+      case 4: if( maxInd==12 ||  maxInd==15 ||  maxInd==16 ) return true;
+      case 5: if( maxInd==12 ||  maxInd==13 ||  maxInd==17 ) return true;
+      case 6: if( maxInd==13 ||  maxInd==14 ||  maxInd==18 ) return true;
+      case 7: if( maxInd==14 ||  maxInd==15 ||  maxInd==19 ) return true;
+      default:;
+      }
+      break;
+    }
+  case QUAD_PYRAM:
     {
       switch ( minInd ) {
       case 0: if( maxInd==5 ||  maxInd==8 ||  maxInd==9 ) return true;
@@ -1170,7 +1314,7 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index,
       }
       break;
     }
-  case 15:
+  case QUAD_PENTA:
     {
       switch ( minInd ) {
       case 0: if( maxInd==6 ||  maxInd==8 ||  maxInd==12 ) return true;
@@ -1183,20 +1327,12 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index,
       }
       break;
     }
-  case 20:
+  case HEX_PRISM:
     {
-      switch ( minInd ) {
-      case 0: if( maxInd==8 ||  maxInd==11 ||  maxInd==16 ) return true;
-      case 1: if( maxInd==8 ||  maxInd==9 ||  maxInd==17 ) return true;
-      case 2: if( maxInd==9 ||  maxInd==10 ||  maxInd==18 ) return true;
-      case 3: if( maxInd==10 ||  maxInd==11 ||  maxInd==19 ) return true;
-      case 4: if( maxInd==12 ||  maxInd==15 ||  maxInd==16 ) return true;
-      case 5: if( maxInd==12 ||  maxInd==13 ||  maxInd==17 ) return true;
-      case 6: if( maxInd==13 ||  maxInd==14 ||  maxInd==18 ) return true;
-      case 7: if( maxInd==14 ||  maxInd==15 ||  maxInd==19 ) return true;
-      default:;
-      }
-      break;
+      const int diff = maxInd-minInd;
+      if ( diff > 6  ) return false;// not linked top and bottom
+      if ( diff == 6 ) return true; // linked top and bottom
+      return diff == 1 || diff == 7;
     }
   default:;
   }
@@ -1227,10 +1363,9 @@ int SMDS_VolumeTool::GetNodeIndex(const SMDS_MeshNode* theNode) const
  */
 //================================================================================
 
-int SMDS_VolumeTool::GetAllExistingFaces(vector<const SMDS_MeshElement*> & faces)
+int SMDS_VolumeTool::GetAllExistingFaces(vector<const SMDS_MeshElement*> & faces) const
 {
   faces.clear();
-  faces.reserve( NbFaces() );
   for ( int iF = 0; iF < NbFaces(); ++iF ) {
     const SMDS_MeshFace* face = 0;
     const SMDS_MeshNode** nodes = GetFaceNodes( iF );
@@ -1265,7 +1400,7 @@ int SMDS_VolumeTool::GetAllExistingEdges(vector<const SMDS_MeshElement*> & edges
 {
   edges.clear();
   edges.reserve( myVolumeNbNodes * 2 );
-  for ( int i = 0; i < myVolumeNbNodes; ++i ) {
+  for ( int i = 0; i < myVolumeNbNodes-1; ++i ) {
     for ( int j = i + 1; j < myVolumeNbNodes; ++j ) {
       if ( IsLinked( i, j )) {
         const SMDS_MeshElement* edge =
@@ -1278,47 +1413,83 @@ int SMDS_VolumeTool::GetAllExistingEdges(vector<const SMDS_MeshElement*> & edges
   return edges.size();
 }
 
-//=======================================================================
-//function : IsFreeFace
-//purpose  : check that only one volume is build on the face nodes
-//=======================================================================
+//================================================================================
+/*!
+ * \brief Return minimal square distance between connected corner nodes
+ */
+//================================================================================
 
-bool SMDS_VolumeTool::IsFreeFace( int faceIndex )
+double SMDS_VolumeTool::MinLinearSize2() const
 {
-  const int free = true;
+  double minSize = 1e+100;
+  int iQ = myVolume->IsQuadratic() ? 2 : 1;
+
+  // store current face data
+  int curFace = myCurFace, nbN = myFaceNbNodes;
+  int* ind = myFaceNodeIndices;
+  myFaceNodeIndices = NULL;
+  const SMDS_MeshNode** nodes = myFaceNodes;
+  myFaceNodes = NULL;
+  
+  // it seems that compute distance twice is faster than organization of a sole computing
+  myCurFace = -1;
+  for ( int iF = 0; iF < myNbFaces; ++iF )
+  {
+    setFace( iF );
+    for ( int iN = 0; iN < myFaceNbNodes; iN += iQ )
+    {
+      XYZ n1( myFaceNodes[ iN ]);
+      XYZ n2( myFaceNodes[(iN + iQ) % myFaceNbNodes]);
+      minSize = std::min( minSize, (n1 - n2).SquareMagnitude());
+    }
+  }
+  // restore current face data
+  myCurFace = curFace;
+  myFaceNbNodes = nbN;
+  myFaceNodeIndices = ind;
+  delete [] myFaceNodes; myFaceNodes = nodes;
+
+  return minSize;
+}
+
+//================================================================================
+/*!
+ * \brief check that only one volume is build on the face nodes
+ *
+ * If a face is shared by one of <ignoreVolumes>, it is considered free
+ */
+//================================================================================
+
+bool SMDS_VolumeTool::IsFreeFace( int faceIndex, const SMDS_MeshElement** otherVol/*=0*/ ) const
+{
+  const bool isFree = true;
 
   if (!setFace( faceIndex ))
-    return !free;
+    return !isFree;
 
   const SMDS_MeshNode** nodes = GetFaceNodes( faceIndex );
-  int nbFaceNodes = myFaceNbNodes;
+  const int nbFaceNodes = myFaceNbNodes;
 
-  // evaluate nb of face nodes shared by other volume
+  // evaluate nb of face nodes shared by other volumes
   int maxNbShared = -1;
   typedef map< const SMDS_MeshElement*, int > TElemIntMap;
   TElemIntMap volNbShared;
   TElemIntMap::iterator vNbIt;
   for ( int iNode = 0; iNode < nbFaceNodes; iNode++ ) {
     const SMDS_MeshNode* n = nodes[ iNode ];
-    SMDS_ElemIteratorPtr eIt = n->GetInverseElementIterator();
+    SMDS_ElemIteratorPtr eIt = n->GetInverseElementIterator( SMDSAbs_Volume );
     while ( eIt->more() ) {
       const SMDS_MeshElement* elem = eIt->next();
-      if ( elem != myVolume && elem->GetType() == SMDSAbs_Volume ) {
-        int nbShared = 1;
-        vNbIt = volNbShared.find( elem );
-        if ( vNbIt == volNbShared.end() ) {
-          volNbShared.insert ( TElemIntMap::value_type( elem, nbShared ));
-        }
-        else {
-          nbShared = ++(*vNbIt).second;
-        }
-        if ( nbShared > maxNbShared )
-          maxNbShared = nbShared;
+      if ( elem != myVolume ) {
+        vNbIt = volNbShared.insert( make_pair( elem, 0 )).first;
+        (*vNbIt).second++;
+        if ( vNbIt->second > maxNbShared )
+          maxNbShared = vNbIt->second;
       }
     }
   }
   if ( maxNbShared < 3 )
-    return free; // is free
+    return isFree; // is free
 
   // find volumes laying on the opposite side of the face
   // and sharing all nodes
@@ -1327,55 +1498,81 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex )
   if ( IsFaceExternal( faceIndex ))
     intNormal = XYZ( -intNormal.x, -intNormal.y, -intNormal.z );
   XYZ p0 ( nodes[0] ), baryCenter;
-  for ( vNbIt = volNbShared.begin(); vNbIt != volNbShared.end(); vNbIt++ ) {
-    int nbShared = (*vNbIt).second;
+  for ( vNbIt = volNbShared.begin(); vNbIt != volNbShared.end();  ) {
+    const int& nbShared = (*vNbIt).second;
     if ( nbShared >= 3 ) {
       SMDS_VolumeTool volume( (*vNbIt).first );
       volume.GetBaryCenter( baryCenter.x, baryCenter.y, baryCenter.z );
       XYZ intNormal2( baryCenter - p0 );
-      if ( intNormal.Dot( intNormal2 ) < 0 )
-        continue; // opposite side
+      if ( intNormal.Dot( intNormal2 ) < 0 ) {
+        // opposite side
+        if ( nbShared >= nbFaceNodes )
+        {
+          // a volume shares the whole facet
+          if ( otherVol ) *otherVol = vNbIt->first;
+          return !isFree; 
+        }
+        ++vNbIt;
+        continue;
+      }
     }
     // remove a volume from volNbShared map
-    volNbShared.erase( vNbIt-- );
+    volNbShared.erase( vNbIt++ );
   }
 
-  // here volNbShared contains only volumes laying on the
-  // opposite side of the face
-  if ( volNbShared.empty() ) {
-    return free; // is free
+  // here volNbShared contains only volumes laying on the opposite side of
+  // the face and sharing 3 or more but not all face nodes with myVolume
+  if ( volNbShared.size() < 2 ) {
+    return isFree; // is free
   }
 
   // check if the whole area of a face is shared
-  bool isShared[] = { false, false, false, false }; // 4 triangle parts of a quadrangle
-  for ( vNbIt = volNbShared.begin(); vNbIt != volNbShared.end(); vNbIt++ ) {
-    SMDS_VolumeTool volume( (*vNbIt).first );
-    bool prevLinkShared = false;
-    int nbSharedLinks = 0;
-    for ( int iNode = 0; iNode < nbFaceNodes; iNode++ ) {
-      bool linkShared = volume.IsLinked( nodes[ iNode ], nodes[ iNode + 1] );
-      if ( linkShared )
-        nbSharedLinks++;
-      if ( linkShared && prevLinkShared &&
-          volume.IsLinked( nodes[ iNode - 1 ], nodes[ iNode + 1] ))
-        isShared[ iNode ] = true;
-      prevLinkShared = linkShared;
-    }
-    if ( nbSharedLinks == nbFaceNodes )
-      return !free; // is not free
-    if ( nbFaceNodes == 4 ) {
-      // check traingle parts 1 & 3
-      if ( isShared[1] && isShared[3] )
-        return !free; // is not free
-      // check triangle parts 0 & 2;
-      // 0 part could not be checked in the loop; check it here
-      if ( isShared[2] && prevLinkShared &&
-          volume.IsLinked( nodes[ 0 ], nodes[ 1 ] ) &&
-          volume.IsLinked( nodes[ 1 ], nodes[ 3 ] ) )
-        return !free; // is not free
-    }
+  for ( int iNode = 0; iNode < nbFaceNodes; iNode++ )
+  {
+    const SMDS_MeshNode* n = nodes[ iNode ];
+    // check if n is shared by one of volumes of volNbShared
+    bool isShared = false;
+    SMDS_ElemIteratorPtr eIt = n->GetInverseElementIterator( SMDSAbs_Volume );
+    while ( eIt->more() && !isShared )
+      isShared = volNbShared.count( eIt->next() );
+    if ( !isShared )
+      return isFree;
   }
-  return free;
+  if ( otherVol ) *otherVol = volNbShared.begin()->first;
+  return !isFree;
+
+//   if ( !myVolume->IsPoly() )
+//   {
+//     bool isShared[] = { false, false, false, false }; // 4 triangle parts of a quadrangle
+//     for ( vNbIt = volNbShared.begin(); vNbIt != volNbShared.end(); vNbIt++ ) {
+//       SMDS_VolumeTool volume( (*vNbIt).first );
+//       bool prevLinkShared = false;
+//       int nbSharedLinks = 0;
+//       for ( int iNode = 0; iNode < nbFaceNodes; iNode++ ) {
+//         bool linkShared = volume.IsLinked( nodes[ iNode ], nodes[ iNode + 1] );
+//         if ( linkShared )
+//           nbSharedLinks++;
+//         if ( linkShared && prevLinkShared &&
+//              volume.IsLinked( nodes[ iNode - 1 ], nodes[ iNode + 1] ))
+//           isShared[ iNode ] = true;
+//         prevLinkShared = linkShared;
+//       }
+//       if ( nbSharedLinks == nbFaceNodes )
+//         return !free; // is not free
+//       if ( nbFaceNodes == 4 ) {
+//         // check traingle parts 1 & 3
+//         if ( isShared[1] && isShared[3] )
+//           return !free; // is not free
+//         // check triangle parts 0 & 2;
+//         // 0 part could not be checked in the loop; check it here
+//         if ( isShared[2] && prevLinkShared &&
+//              volume.IsLinked( nodes[ 0 ], nodes[ 1 ] ) &&
+//              volume.IsLinked( nodes[ 1 ], nodes[ 3 ] ) )
+//           return !free; // is not free
+//       }
+//     }
+//   }
+//  return free;
 }
 
 //=======================================================================
@@ -1383,7 +1580,7 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex )
 //purpose  : Return index of a face formed by theFaceNodes
 //=======================================================================
 
-int SMDS_VolumeTool::GetFaceIndex( const set<const SMDS_MeshNode*>& theFaceNodes )
+int SMDS_VolumeTool::GetFaceIndex( const set<const SMDS_MeshNode*>& theFaceNodes ) const
 {
   for ( int iFace = 0; iFace < myNbFaces; iFace++ ) {
     const SMDS_MeshNode** nodes = GetFaceNodes( iFace );
@@ -1421,7 +1618,7 @@ int SMDS_VolumeTool::GetFaceIndex( const set<const SMDS_MeshNode*>& theFaceNodes
 //purpose  : 
 //=======================================================================
 
-bool SMDS_VolumeTool::setFace( int faceIndex )
+bool SMDS_VolumeTool::setFace( int faceIndex ) const
 {
   if ( !myVolume )
     return false;
@@ -1439,93 +1636,120 @@ bool SMDS_VolumeTool::setFace( int faceIndex )
     myFaceNodes = NULL;
   }
 
-  if (myVolume->IsPoly()) {
+  if (myVolume->IsPoly())
+  {
     if (!myPolyedre) {
       MESSAGE("Warning: bad volumic element");
       return false;
     }
 
-    // check orientation
-    bool isGoodOri = true;
-    if (myExternalFaces)
-      isGoodOri = IsFaceExternal( faceIndex );
-
     // set face nodes
     int iNode;
     myFaceNbNodes = myPolyedre->NbFaceNodes(faceIndex + 1);
     myFaceNodes = new const SMDS_MeshNode* [myFaceNbNodes + 1];
-    if (isGoodOri) {
-      for ( iNode = 0; iNode < myFaceNbNodes; iNode++ )
-        myFaceNodes[ iNode ] = myPolyedre->GetFaceNode(faceIndex + 1, iNode + 1);
-    } else {
-      for ( iNode = 0; iNode < myFaceNbNodes; iNode++ )
-        myFaceNodes[ iNode ] = myPolyedre->GetFaceNode(faceIndex + 1, myFaceNbNodes - iNode);
-    }
+    for ( iNode = 0; iNode < myFaceNbNodes; iNode++ )
+      myFaceNodes[ iNode ] = myPolyedre->GetFaceNode(faceIndex + 1, iNode + 1);
     myFaceNodes[ myFaceNbNodes ] = myFaceNodes[ 0 ]; // last = first
 
+    // check orientation
+    if (myExternalFaces)
+    {
+      myCurFace = faceIndex; // avoid infinite recursion in IsFaceExternal()
+      myExternalFaces = false; // force normal computation by IsFaceExternal()
+      if ( !IsFaceExternal( faceIndex ))
+        for ( int i = 0, j = myFaceNbNodes; i < j; ++i, --j )
+          std::swap( myFaceNodes[i], myFaceNodes[j] );
+      myExternalFaces = true;
+    }
   }
-  else {
-    // choose face node indices
-    switch ( myVolumeNbNodes ) {
-    case 4:
-      myFaceNbNodes = Tetra_nbN[ faceIndex ];
-      if ( myExternalFaces )
-        myFaceNodeIndices = myVolForward ? Tetra_F[ faceIndex ] : Tetra_RE[ faceIndex ];
-      else
-        myFaceNodeIndices = myVolForward ? Tetra_F[ faceIndex ] : Tetra_R[ faceIndex ];
-      break;
-    case 5:
-      myFaceNbNodes = Pyramid_nbN[ faceIndex ];
-      if ( myExternalFaces )
-        myFaceNodeIndices = myVolForward ? Pyramid_F[ faceIndex ] : Pyramid_RE[ faceIndex ];
-      else
-        myFaceNodeIndices = myVolForward ? Pyramid_F[ faceIndex ] : Pyramid_R[ faceIndex ];
-      break;
-    case 6:
-      myFaceNbNodes = Penta_nbN[ faceIndex ];
-      if ( myExternalFaces )
-        myFaceNodeIndices = myVolForward ? Penta_FE[ faceIndex ] : Penta_RE[ faceIndex ];
-      else
-        myFaceNodeIndices = myVolForward ? Penta_F[ faceIndex ] : Penta_R[ faceIndex ];
-      break;
-    case 8:
-      myFaceNbNodes = Hexa_nbN[ faceIndex ];
-      if ( myExternalFaces )
-        myFaceNodeIndices = myVolForward ? Hexa_FE[ faceIndex ] : Hexa_RE[ faceIndex ];
-      else
-        myFaceNodeIndices = Hexa_F[ faceIndex ];
-      break;
-    case 10:
-      myFaceNbNodes = QuadTetra_nbN[ faceIndex ];
-      if ( myExternalFaces )
-        myFaceNodeIndices = myVolForward ? QuadTetra_F[ faceIndex ] : QuadTetra_RE[ faceIndex ];
-      else
-        myFaceNodeIndices = myVolForward ? QuadTetra_F[ faceIndex ] : QuadTetra_R[ faceIndex ];
-      break;
-    case 13:
-      myFaceNbNodes = QuadPyram_nbN[ faceIndex ];
-      if ( myExternalFaces )
-        myFaceNodeIndices = myVolForward ? QuadPyram_F[ faceIndex ] : QuadPyram_RE[ faceIndex ];
-      else
-        myFaceNodeIndices = myVolForward ? QuadPyram_F[ faceIndex ] : QuadPyram_R[ faceIndex ];
-      break;
-    case 15:
-      myFaceNbNodes = QuadPenta_nbN[ faceIndex ];
-      if ( myExternalFaces )
-        myFaceNodeIndices = myVolForward ? QuadPenta_FE[ faceIndex ] : QuadPenta_RE[ faceIndex ];
-      else
-        myFaceNodeIndices = myVolForward ? QuadPenta_F[ faceIndex ] : QuadPenta_R[ faceIndex ];
-      break;
-    case 20:
-      myFaceNbNodes = QuadHexa_nbN[ faceIndex ];
-      if ( myExternalFaces )
-        myFaceNodeIndices = myVolForward ? QuadHexa_FE[ faceIndex ] : QuadHexa_RE[ faceIndex ];
-      else
-        myFaceNodeIndices = QuadHexa_F[ faceIndex ];
-      break;
-    default:
-      return false;
+  else
+  {
+    if ( !myAllFacesNodeIndices_F )
+    {
+      // choose data for an element type
+      switch ( myVolumeNbNodes ) {
+      case 4:
+        myAllFacesNodeIndices_F  = &Tetra_F [0][0];
+        //myAllFacesNodeIndices_FE = &Tetra_F [0][0];
+        myAllFacesNodeIndices_RE = &Tetra_RE[0][0];
+        myAllFacesNbNodes        = Tetra_nbN;
+        myMaxFaceNbNodes         = sizeof(Tetra_F[0])/sizeof(Tetra_F[0][0]);
+        break;
+      case 5:
+        myAllFacesNodeIndices_F  = &Pyramid_F [0][0];
+        //myAllFacesNodeIndices_FE = &Pyramid_F [0][0];
+        myAllFacesNodeIndices_RE = &Pyramid_RE[0][0];
+        myAllFacesNbNodes        = Pyramid_nbN;
+        myMaxFaceNbNodes         = sizeof(Pyramid_F[0])/sizeof(Pyramid_F[0][0]);
+        break;
+      case 6:
+        myAllFacesNodeIndices_F  = &Penta_F [0][0];
+        //myAllFacesNodeIndices_FE = &Penta_FE[0][0];
+        myAllFacesNodeIndices_RE = &Penta_RE[0][0];
+        myAllFacesNbNodes        = Penta_nbN;
+        myMaxFaceNbNodes         = sizeof(Penta_F[0])/sizeof(Penta_F[0][0]);
+        break;
+      case 8:
+        myAllFacesNodeIndices_F  = &Hexa_F [0][0];
+        ///myAllFacesNodeIndices_FE = &Hexa_FE[0][0];
+        myAllFacesNodeIndices_RE = &Hexa_RE[0][0];
+        myAllFacesNbNodes        = Hexa_nbN;
+        myMaxFaceNbNodes         = sizeof(Hexa_F[0])/sizeof(Hexa_F[0][0]);
+        break;
+      case 10:
+        myAllFacesNodeIndices_F  = &QuadTetra_F [0][0];
+        //myAllFacesNodeIndices_FE = &QuadTetra_F [0][0];
+        myAllFacesNodeIndices_RE = &QuadTetra_RE[0][0];
+        myAllFacesNbNodes        = QuadTetra_nbN;
+        myMaxFaceNbNodes         = sizeof(QuadTetra_F[0])/sizeof(QuadTetra_F[0][0]);
+        break;
+      case 13:
+        myAllFacesNodeIndices_F  = &QuadPyram_F [0][0];
+        //myAllFacesNodeIndices_FE = &QuadPyram_F [0][0];
+        myAllFacesNodeIndices_RE = &QuadPyram_RE[0][0];
+        myAllFacesNbNodes        = QuadPyram_nbN;
+        myMaxFaceNbNodes         = sizeof(QuadPyram_F[0])/sizeof(QuadPyram_F[0][0]);
+        break;
+      case 15:
+        myAllFacesNodeIndices_F  = &QuadPenta_F [0][0];
+        //myAllFacesNodeIndices_FE = &QuadPenta_FE[0][0];
+        myAllFacesNodeIndices_RE = &QuadPenta_RE[0][0];
+        myAllFacesNbNodes        = QuadPenta_nbN;
+        myMaxFaceNbNodes         = sizeof(QuadPenta_F[0])/sizeof(QuadPenta_F[0][0]);
+        break;
+      case 20:
+      case 27:
+        myAllFacesNodeIndices_F  = &QuadHexa_F [0][0];
+        //myAllFacesNodeIndices_FE = &QuadHexa_FE[0][0];
+        myAllFacesNodeIndices_RE = &QuadHexa_RE[0][0];
+        myAllFacesNbNodes        = QuadHexa_nbN;
+        myMaxFaceNbNodes         = sizeof(QuadHexa_F[0])/sizeof(QuadHexa_F[0][0]);
+        if ( !myIgnoreCentralNodes && myVolumeNbNodes == 27 )
+        {
+          myAllFacesNodeIndices_F  = &TriQuadHexa_F [0][0];
+          //myAllFacesNodeIndices_FE = &TriQuadHexa_FE[0][0];
+          myAllFacesNodeIndices_RE = &TriQuadHexa_RE[0][0];
+          myAllFacesNbNodes        = TriQuadHexa_nbN;
+          myMaxFaceNbNodes         = sizeof(TriQuadHexa_F[0])/sizeof(TriQuadHexa_F[0][0]);
+        }
+        break;
+      case 12:
+        myAllFacesNodeIndices_F  = &HexPrism_F [0][0];
+        //myAllFacesNodeIndices_FE = &HexPrism_FE[0][0];
+        myAllFacesNodeIndices_RE = &HexPrism_RE[0][0];
+        myAllFacesNbNodes        = HexPrism_nbN;
+        myMaxFaceNbNodes         = sizeof(HexPrism_F[0])/sizeof(HexPrism_F[0][0]);
+        break;
+      default:
+        return false;
+      }
     }
+    myFaceNbNodes = myAllFacesNbNodes[ faceIndex ];
+    // if ( myExternalFaces )
+    //   myFaceNodeIndices = (int*)( myVolForward ? myAllFacesNodeIndices_FE + faceIndex*myMaxFaceNbNodes : myAllFacesNodeIndices_RE + faceIndex*myMaxFaceNbNodes );
+    // else
+    //   myFaceNodeIndices = (int*)( myAllFacesNodeIndices_F + faceIndex*myMaxFaceNbNodes );
+    myFaceNodeIndices = (int*)( myVolForward ? myAllFacesNodeIndices_F + faceIndex*myMaxFaceNbNodes : myAllFacesNodeIndices_RE + faceIndex*myMaxFaceNbNodes );
 
     // set face nodes
     myFaceNodes = new const SMDS_MeshNode* [myFaceNbNodes + 1];
@@ -1554,7 +1778,9 @@ SMDS_VolumeTool::VolumeType SMDS_VolumeTool::GetType(int nbNodes)
   case 10: return QUAD_TETRA;
   case 13: return QUAD_PYRAM;
   case 15: return QUAD_PENTA;
-  case 20: return QUAD_HEXA;
+  case 20:
+  case 27: return QUAD_HEXA;
+  case 12: return HEX_PRISM;
   default:return UNKNOWN;
   }
 }
@@ -1575,7 +1801,8 @@ int SMDS_VolumeTool::NbFaces( VolumeType type )
   case QUAD_PENTA: return 5;
   case HEXA      :
   case QUAD_HEXA : return 6;
-  default:    return 0;
+  case HEX_PRISM : return 8;
+  default:         return 0;
   }
 }
 
@@ -1598,7 +1825,8 @@ int SMDS_VolumeTool::NbCornerNodes(VolumeType type)
   case QUAD_PENTA: return 6;
   case HEXA      :
   case QUAD_HEXA : return 8;
-  default:    return 0;
+  case HEX_PRISM : return 12;
+  default:         return 0;
   }
   return 0;
 }
@@ -1619,12 +1847,14 @@ const int* SMDS_VolumeTool::GetFaceNodesIndices(VolumeType type,
   switch ( type ) {
   case TETRA: return Tetra_F[ faceIndex ];
   case PYRAM: return Pyramid_F[ faceIndex ];
-  case PENTA: return external ? Penta_FE[ faceIndex ] : Penta_F[ faceIndex ];
-  case HEXA:  return external ? Hexa_FE[ faceIndex ] : Hexa_F[ faceIndex ];
+  case PENTA: return external ? Penta_F[ faceIndex ] : Penta_F[ faceIndex ];
+  case HEXA:  return external ? Hexa_F[ faceIndex ] : Hexa_F[ faceIndex ];
   case QUAD_TETRA: return QuadTetra_F[ faceIndex ];
   case QUAD_PYRAM: return QuadPyram_F[ faceIndex ];
-  case QUAD_PENTA: return external ? QuadPenta_FE[ faceIndex ] : QuadPenta_F[ faceIndex ];
-  case QUAD_HEXA:  return external ? QuadHexa_FE[ faceIndex ] : QuadHexa_F[ faceIndex ];
+  case QUAD_PENTA: return external ? QuadPenta_F[ faceIndex ] : QuadPenta_F[ faceIndex ];
+    // what about SMDSEntity_TriQuad_Hexa?
+  case QUAD_HEXA:  return external ? QuadHexa_F[ faceIndex ] : QuadHexa_F[ faceIndex ];
+  case HEX_PRISM:  return external ? HexPrism_F[ faceIndex ] : HexPrism_F[ faceIndex ];
   default:;
   }
   return 0;
@@ -1646,18 +1876,20 @@ int SMDS_VolumeTool::NbFaceNodes(VolumeType type,
   case QUAD_TETRA: return QuadTetra_nbN[ faceIndex ];
   case QUAD_PYRAM: return QuadPyram_nbN[ faceIndex ];
   case QUAD_PENTA: return QuadPenta_nbN[ faceIndex ];
+    // what about SMDSEntity_TriQuad_Hexa?
   case QUAD_HEXA:  return QuadHexa_nbN[ faceIndex ];
+  case HEX_PRISM:  return HexPrism_nbN[ faceIndex ];
   default:;
   }
   return 0;
 }
 
 //=======================================================================
-//function : Get
+//function : Element
 //purpose  : return element
 //=======================================================================
 
-const SMDS_MeshVolume* SMDS_VolumeTool::Get() const
+const SMDS_MeshVolume* SMDS_VolumeTool::Element() const
 {
   return static_cast<const SMDS_MeshVolume*>( myVolume );
 }
index b95bc8a620f48c5bf41568db9d440820de98f967..5c22c3edab61f1063f2c9e118ea0daccf5a69e2e 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMDS : implementaion of Salome mesh data structure
 // File      : SMDS_VolumeTool.hxx
 // Module    : SMESH
@@ -32,7 +33,7 @@
 
 class SMDS_MeshElement;
 class SMDS_MeshNode;
-class SMDS_PolyhedralVolumeOfNodes;
+class SMDS_VtkVolume;
 class SMDS_MeshVolume;
 
 #include <vector>
@@ -50,18 +51,23 @@ class SMDS_EXPORT SMDS_VolumeTool
 {
  public:
 
-  enum VolumeType { UNKNOWN = -1, TETRA = 0, PYRAM, PENTA, HEXA, QUAD_TETRA,
-                    QUAD_PYRAM, QUAD_PENTA, QUAD_HEXA, POLYHEDA };
+  enum VolumeType { UNKNOWN = -1, TETRA = 0, PYRAM, PENTA, HEXA,
+                    HEX_PRISM, QUAD_TETRA, QUAD_PYRAM, QUAD_PENTA, QUAD_HEXA,
+                    POLYHEDA, NB_VOLUME_TYPES }; // to keep synchronised with GetSize()!
 
   SMDS_VolumeTool ();
   ~SMDS_VolumeTool ();
-  SMDS_VolumeTool (const SMDS_MeshElement* theVolume);
+  SMDS_VolumeTool (const SMDS_MeshElement* theVolume,
+                   const bool              ignoreCentralNodes=true);
 
-  bool Set (const SMDS_MeshElement* theVolume);
+  bool Set (const SMDS_MeshElement* theVolume,
+            const bool              ignoreCentralNodes=true);
   // Set volume.
-  // Return false if theVolume is not of type SMDSAbs_Volume
+  // Return false if theVolume is not of type SMDSAbs_Volume.
+  // ignoreCentralNodes makes skip nodes at face centers when returning
+  // nodes of faces of SMDSEntity_TriQuad_Hexa
 
-  const SMDS_MeshVolume* Get() const;
+  const SMDS_MeshVolume* Element() const;
   // return element
 
   int ID() const;
@@ -93,19 +99,25 @@ class SMDS_EXPORT SMDS_VolumeTool
 
   bool GetBaryCenter (double & X, double & Y, double & Z) const;
 
+  bool IsOut(double X, double Y, double Z, double tol) const;
+  // Classify a point
 
   // -----------------------
   // info on node connection
   // -----------------------
 
   bool IsLinked (const SMDS_MeshNode* theNode1,
-                 const SMDS_MeshNode* theNode2) const;
+                 const SMDS_MeshNode* theNode2,
+                 const bool           theIgnoreMediumNodes=false) const;
   // Return true if theNode1 is linked with theNode2.
+  // If theIgnoreMediumNodes then corner nodes of quadratic cell are considered linked as well
 
   bool IsLinked (const int theNode1Index,
-                 const int theNode2Index) const;
+                 const int theNode2Index,
+                 bool      theIgnoreMediumNodes=false) const;
   // Return true if the node with theNode1Index is linked
   // with the node with theNode2Index
+  // If theIgnoreMediumNodes then corner nodes of quadratic cell are considered linked as well
 
   int GetNodeIndex(const SMDS_MeshNode* theNode) const;
   // Return an index of theNode
@@ -113,9 +125,15 @@ class SMDS_EXPORT SMDS_VolumeTool
   int GetAllExistingEdges(std::vector<const SMDS_MeshElement*> & edges) const;
   // Fill vector with boundary edges existing in the mesh
 
+  double MinLinearSize2() const;
+  // Return minimal square distance between connected corner nodes
+
   // -------------
   // info on faces
   // -------------
+  // For all elements, 0-th face is bottom based on the first nodes.
+  // For prismatic elements (tetra,hexa,prisms), 1-th face is a top one.
+  // For all elements, side faces follow order of bottom nodes
 
   void SetExternalNormal ();
   // Node order in faces  will be so that faces normals are external.
@@ -124,44 +142,57 @@ class SMDS_EXPORT SMDS_VolumeTool
   // Return number of faces of the volume. In the following
   // methods 0 <= faceIndex < NbFaces()
 
-  int NbFaceNodes( int faceIndex );
+  int NbFaceNodes( int faceIndex ) const;
   // Return number of nodes in the array of face nodes
 
-  const int* GetFaceNodesIndices( int faceIndex );
+  const int* GetFaceNodesIndices( int faceIndex ) const;
   // Return the array of face nodes indices
   // To comfort link iteration, the array
   // length == NbFaceNodes( faceIndex ) + 1 and
-  // the last node index == the first one.
+  // the last node index == the first one, except for
+  // SMDSEntity_TriQuad_Hexa at ignoreCentralNodes==false.
+  // NOTE: for the quadratic volume, node indices are in the order the nodes encounter
+  // in face boundary and not the order they are in the mesh face
 
-  const SMDS_MeshNode** GetFaceNodes( int faceIndex );
+  const SMDS_MeshNode** GetFaceNodes( int faceIndex ) const;
   // Return the array of face nodes.
   // To comfort link iteration, the array
   // length == NbFaceNodes( faceIndex ) + 1 and
-  // the last node == the first one.
+  // the last node == the first one, except for
+  // SMDSEntity_TriQuad_Hexa at ignoreCentralNodes==false.
+  // NOTE: for the quadratic volume, nodes are in the order they encounter in face boundary
+  // and not the order they are in the mesh face
   // WARNING: do not modify the array, some methods
   //          work basing on its contents
 
   bool GetFaceNodes (int faceIndex,
-                     std::set<const SMDS_MeshNode*>& theFaceNodes );
+                     std::set<const SMDS_MeshNode*>& theFaceNodes ) const;
   // Return a set of face nodes.
 
-  bool IsFaceExternal( int faceIndex );
+  bool IsFaceExternal( int faceIndex ) const;
   // Check normal orientation of a face.
   // SetExternalNormal() is taken into account.
 
-  bool IsFreeFace(  int faceIndex );
+  bool IsFreeFace(  int faceIndex, const SMDS_MeshElement** otherVol=0 ) const;
   // Check that all volumes built on the face nodes lays on one side
+  // otherVol returns another volume sharing the given facet
 
-  bool GetFaceNormal (int faceIndex, double & X, double & Y, double & Z);
+  bool GetFaceNormal (int faceIndex, double & X, double & Y, double & Z) const;
   // Return a normal to a face
 
-  double GetFaceArea( int faceIndex );
+  bool GetFaceBaryCenter (int faceIndex, double & X, double & Y, double & Z) const;
+  // Return barycenter of a face
+
+  double GetFaceArea( int faceIndex ) const;
   // Return face area
 
   int GetOppFaceIndex( int faceIndex ) const;
   // Return index of the opposite face if it exists, else -1.
 
-  int GetFaceIndex( const std::set<const SMDS_MeshNode*>& theFaceNodes );
+  int GetCenterNodeIndex( int faceIndex ) const;
+  // Return index of the node located at face center of a quadratic element like HEX27
+
+  int GetFaceIndex( const std::set<const SMDS_MeshNode*>& theFaceNodes ) const;
   // Return index of a face formed by theFaceNodes.
   // Return -1 if a face not found
 
@@ -169,7 +200,7 @@ class SMDS_EXPORT SMDS_VolumeTool
   // Return index of a face formed by theFaceNodesIndices
   // Return -1 if a face not found
 
-  int GetAllExistingFaces(std::vector<const SMDS_MeshElement*> & faces);
+  int GetAllExistingFaces(std::vector<const SMDS_MeshElement*> & faces) const;
   // Fill vector with boundary faces existing in the mesh
 
   // ------------------------
@@ -189,32 +220,40 @@ class SMDS_EXPORT SMDS_VolumeTool
   // To comfort link iteration, the array
   // length == NbFaceNodes( faceIndex ) + 1 and
   // the last node index == the first one.
+  // Nodes at face centers of SMDSEntity_TriQuad_Hexa are ignored
 
-  static int NbFaceNodes(VolumeType type,
-                         int        faceIndex );
+  static int NbFaceNodes(VolumeType type, int faceIndex );
   // Return number of nodes in the array of face nodes
+  // Nodes at face centers of SMDSEntity_TriQuad_Hexa are ignored
 
   static int NbCornerNodes(VolumeType type);
   // Useful to know nb of corner nodes of a quadratic volume
 
 private:
 
-  bool setFace( int faceIndex );
+  bool setFace( int faceIndex ) const;
 
   const SMDS_MeshElement* myVolume;
-  const SMDS_PolyhedralVolumeOfNodes* myPolyedre;
+  const SMDS_VtkVolume*   myPolyedre;
+  bool                    myIgnoreCentralNodes;
 
   bool                    myVolForward;
   int                     myNbFaces;
   int                     myVolumeNbNodes;
   const SMDS_MeshNode**   myVolumeNodes;
+  std::vector< int >      myPolyIndices;
+
+  mutable bool                    myExternalFaces;
 
-  bool                    myExternalFaces;
+  mutable const int*              myAllFacesNodeIndices_F;
+  mutable const int*              myAllFacesNodeIndices_RE;
+  mutable const int*              myAllFacesNbNodes;
+  mutable int                     myMaxFaceNbNodes;
 
-  int                     myCurFace;
-  int                     myFaceNbNodes;
-  int*                    myFaceNodeIndices;
-  const SMDS_MeshNode**   myFaceNodes;
+  mutable int                     myCurFace;
+  mutable int                     myFaceNbNodes;
+  mutable int*                    myFaceNodeIndices;
+  mutable const SMDS_MeshNode**   myFaceNodes;
 
 };
 #endif
diff --git a/src/SMDS/SMDS_VtkCellIterator.cxx b/src/SMDS/SMDS_VtkCellIterator.cxx
new file mode 100644 (file)
index 0000000..80b421c
--- /dev/null
@@ -0,0 +1,205 @@
+// Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+#include "SMDS_VtkCellIterator.hxx"
+#include "utilities.h"
+
+SMDS_VtkCellIterator::SMDS_VtkCellIterator(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType) :
+  _mesh(mesh), _cellId(vtkCellId), _index(0), _type(aType)
+{
+  vtkUnstructuredGrid* grid = _mesh->getGrid();
+  _vtkIdList = vtkIdList::New();
+  const std::vector<int>& interlace = SMDS_MeshCell::fromVtkOrder( aType );
+  if ( interlace.empty() )
+  {
+    grid->GetCellPoints(_cellId, _vtkIdList);
+    _nbNodes = _vtkIdList->GetNumberOfIds();
+  }
+  else
+  {
+    vtkIdType npts, *pts;
+    grid->GetCellPoints( _cellId, npts, pts );
+    _vtkIdList->SetNumberOfIds( _nbNodes = npts );
+    for (int i = 0; i < _nbNodes; i++)
+      _vtkIdList->SetId(i, pts[interlace[i]]);
+  }
+}
+
+SMDS_VtkCellIterator::~SMDS_VtkCellIterator()
+{
+  _vtkIdList->Delete();
+}
+
+bool SMDS_VtkCellIterator::more()
+{
+  return (_index < _nbNodes);
+}
+
+const SMDS_MeshElement* SMDS_VtkCellIterator::next()
+{
+  vtkIdType id = _vtkIdList->GetId(_index++);
+  return _mesh->FindNodeVtk(id);
+}
+
+SMDS_VtkCellIteratorToUNV::SMDS_VtkCellIteratorToUNV(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType) :
+  SMDS_VtkCellIterator()
+{
+  _mesh = mesh;
+  _cellId = vtkCellId;
+  _index = 0;
+  _type = aType;
+  //MESSAGE("SMDS_VtkCellInterlacedIterator (UNV)" << _type);
+
+  _vtkIdList = vtkIdList::New();
+  vtkIdType* pts;
+  vtkUnstructuredGrid* grid = _mesh->getGrid();
+  grid->GetCellPoints((vtkIdType)_cellId, (vtkIdType&)_nbNodes, pts);
+  _vtkIdList->SetNumberOfIds(_nbNodes);
+  int *ids = 0;
+  switch (_type)
+  {
+    case SMDSEntity_Quad_Edge:
+      {
+        static int id[] = { 0, 2, 1 };
+        ids = id;
+        break;
+      }
+    case SMDSEntity_Quad_Triangle:
+      {
+        static int id[] = { 0, 3, 1, 4, 2, 5 };
+        ids = id;
+        break;
+      }
+    case SMDSEntity_Quad_Quadrangle:
+    case SMDSEntity_BiQuad_Quadrangle:
+      {
+        static int id[] = { 0, 4, 1, 5, 2, 6, 3, 7 };
+        ids = id;
+        _nbNodes = 8;
+        break;
+      }
+    case SMDSEntity_Quad_Tetra:
+      {
+        static int id[] = { 0, 4, 1, 5, 2, 6, 7, 8, 9, 3 };
+        ids = id;
+        break;
+      }
+    case SMDSEntity_Quad_Pyramid:
+      {
+        static int id[] = { 0, 5, 1, 6, 2, 7, 3, 8, 9, 10, 11, 12, 4 };
+        ids = id;
+        break;
+      }
+    case SMDSEntity_Penta:
+      {
+        static int id[] = { 0, 2, 1, 3, 5, 4 };
+        ids = id;
+        break;
+      }
+    case SMDSEntity_Quad_Penta:
+      {
+        static int id[] = { 0, 8, 2, 7, 1, 6, 12, 14, 13, 3, 11, 5, 10, 4, 9 };
+        ids = id;
+        break;
+      }
+    case SMDSEntity_Quad_Hexa:
+    case SMDSEntity_TriQuad_Hexa:
+      {
+        static int id[] = { 0, 8, 1, 9, 2, 10, 3, 11, 16, 17, 18, 19, 4, 12, 5, 13, 6, 14, 7, 15 };
+        ids = id;
+        _nbNodes = 20;
+        break;
+      }
+    case SMDSEntity_Polygon:
+    case SMDSEntity_Quad_Polygon:
+    case SMDSEntity_Polyhedra:
+    case SMDSEntity_Quad_Polyhedra:
+    default:
+      {
+        // static int id[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+        //                     25, 26, 27, 28, 29 };
+        // ids = id;
+        // break;
+      }
+  }
+  if ( ids )
+    for (int i = 0; i < _nbNodes; i++)
+      _vtkIdList->SetId(i, pts[ids[i]]);
+  else
+    for (int i = 0; i < _nbNodes; i++)
+      _vtkIdList->SetId(i, pts[i]);
+}
+
+SMDS_VtkCellIteratorToUNV::~SMDS_VtkCellIteratorToUNV()
+{
+}
+
+SMDS_VtkCellIteratorPolyH::SMDS_VtkCellIteratorPolyH(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType) :
+  SMDS_VtkCellIterator()
+{
+  _mesh = mesh;
+  _cellId = vtkCellId;
+  _index = 0;
+  _type = aType;
+  //MESSAGE("SMDS_VtkCellIteratorPolyH " << _type);
+  _vtkIdList = vtkIdList::New();
+  vtkUnstructuredGrid* grid = _mesh->getGrid();
+  grid->GetCellPoints(_cellId, _vtkIdList);
+  _nbNodes = _vtkIdList->GetNumberOfIds();
+  switch (_type)
+  {
+    case SMDSEntity_Polyhedra:
+      {
+        //MESSAGE("SMDS_VtkCellIterator Polyhedra");
+        vtkIdType nFaces = 0;
+        vtkIdType* ptIds = 0;
+        grid->GetFaceStream(_cellId, nFaces, ptIds);
+        int id = 0;
+        _nbNodesInFaces = 0;
+        for (int i = 0; i < nFaces; i++)
+          {
+            int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace]
+            _nbNodesInFaces += nodesInFace;
+            id += (nodesInFace + 1);
+          }
+        _vtkIdList->SetNumberOfIds(_nbNodesInFaces);
+        id = 0;
+        int n = 0;
+        for (int i = 0; i < nFaces; i++)
+          {
+            int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace]
+            for (int k = 1; k <= nodesInFace; k++)
+              _vtkIdList->SetId(n++, ptIds[id + k]);
+            id += (nodesInFace + 1);
+          }
+        break;
+      }
+    default:
+      assert(0);
+  }
+}
+
+SMDS_VtkCellIteratorPolyH::~SMDS_VtkCellIteratorPolyH()
+{
+}
+
+bool SMDS_VtkCellIteratorPolyH::more()
+{
+  return (_index < _nbNodesInFaces);
+}
diff --git a/src/SMDS/SMDS_VtkCellIterator.hxx b/src/SMDS/SMDS_VtkCellIterator.hxx
new file mode 100644 (file)
index 0000000..ce15109
--- /dev/null
@@ -0,0 +1,72 @@
+// Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+#ifndef _SMDS_VTKCELLITERATOR_HXX_
+#define _SMDS_VTKCELLITERATOR_HXX_
+
+#include "SMDS_ElemIterator.hxx"
+#include "SMDS_Mesh.hxx"
+#include "SMDSAbs_ElementType.hxx"
+
+#include <vtkCell.h>
+#include <vtkIdList.h>
+
+class SMDS_VtkCellIterator: public SMDS_ElemIterator
+{
+public:
+  SMDS_VtkCellIterator(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType);
+  virtual ~SMDS_VtkCellIterator();
+  virtual bool more();
+  virtual const SMDS_MeshElement* next();
+  inline void exchange(vtkIdType a, vtkIdType b)
+  {
+    vtkIdType t = _vtkIdList->GetId(a);
+    _vtkIdList->SetId(a, _vtkIdList->GetId(b));
+    _vtkIdList->SetId(b, t);
+  }
+
+protected:
+  SMDS_VtkCellIterator() {};
+
+  SMDS_Mesh* _mesh;
+  int _cellId;
+  int _index;
+  int _nbNodes;
+  SMDSAbs_EntityType _type;
+  vtkIdList* _vtkIdList;
+};
+
+class SMDS_VtkCellIteratorToUNV: public SMDS_VtkCellIterator
+{
+public:
+  SMDS_VtkCellIteratorToUNV(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType);
+  virtual ~SMDS_VtkCellIteratorToUNV();
+};
+
+class SMDS_VtkCellIteratorPolyH: public SMDS_VtkCellIterator
+{
+public:
+  SMDS_VtkCellIteratorPolyH(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType);
+  virtual ~SMDS_VtkCellIteratorPolyH();
+  virtual bool more();
+protected:
+  int _nbNodesInFaces;
+};
+
+#endif
diff --git a/src/SMDS/SMDS_VtkEdge.cxx b/src/SMDS/SMDS_VtkEdge.cxx
new file mode 100644 (file)
index 0000000..cb32401
--- /dev/null
@@ -0,0 +1,172 @@
+// Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+#include "SMDS_VtkEdge.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_Mesh.hxx"
+#include "SMDS_VtkCellIterator.hxx"
+
+#include "utilities.h"
+
+#include <vector>
+#include <cassert>
+
+using namespace std;
+
+SMDS_VtkEdge::SMDS_VtkEdge()
+{
+}
+
+SMDS_VtkEdge::SMDS_VtkEdge(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
+{
+  init(nodeIds, mesh);
+}
+
+SMDS_VtkEdge::~SMDS_VtkEdge()
+{
+}
+
+void SMDS_VtkEdge::init(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
+{
+  SMDS_MeshEdge::init();
+  vtkUnstructuredGrid* grid = mesh->getGrid();
+  myMeshId = mesh->getMeshId();
+  vtkIdType aType = VTK_LINE;
+  if (nodeIds.size() == 3)
+    aType = VTK_QUADRATIC_EDGE;
+  myVtkID = grid->InsertNextLinkedCell(aType, nodeIds.size(), &nodeIds[0]);
+  mesh->setMyModified();
+  //MESSAGE("SMDS_VtkEdge::init myVtkID " << myVtkID);
+}
+
+bool SMDS_VtkEdge::ChangeNodes(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2)
+{
+  const SMDS_MeshNode* nodes[] = { node1, node2 };
+  SMDS_Mesh::_meshList[myMeshId]->setMyModified();
+  return ChangeNodes(nodes, 2);
+}
+
+bool SMDS_VtkEdge::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType npts = 0;
+  vtkIdType* pts = 0;
+  grid->GetCellPoints(myVtkID, npts, pts);
+  if (nbNodes != npts)
+    {
+      MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << nbNodes);
+      return false;
+    }
+  for (int i = 0; i < nbNodes; i++)
+    {
+      pts[i] = nodes[i]->getVtkId();
+    }
+  SMDS_Mesh::_meshList[myMeshId]->setMyModified();
+  return true;
+}
+
+bool SMDS_VtkEdge::IsMediumNode(const SMDS_MeshNode* node) const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType npts = 0;
+  vtkIdType* pts = 0;
+  grid->GetCellPoints(myVtkID, npts, pts);
+  //MESSAGE("IsMediumNode " << npts  << " " << (node->getVtkId() == pts[npts-1]));
+  return ((npts == 3) && (node->getVtkId() == pts[2]));
+}
+
+void SMDS_VtkEdge::Print(std::ostream & OS) const
+{
+  OS << "edge <" << GetID() << "> : ";
+}
+
+int SMDS_VtkEdge::NbNodes() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  int nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints();
+  assert(nbPoints >= 2);
+  return nbPoints;
+}
+
+int SMDS_VtkEdge::NbEdges() const
+{
+  return 1;
+}
+
+SMDSAbs_EntityType SMDS_VtkEdge::GetEntityType() const
+{
+  if (NbNodes() == 2)
+    return SMDSEntity_Edge;
+  else
+    return SMDSEntity_Quad_Edge;
+}
+
+vtkIdType SMDS_VtkEdge::GetVtkType() const
+{
+  if (NbNodes() == 2)
+    return VTK_LINE;
+  else
+    return VTK_QUADRATIC_EDGE;
+
+}
+
+/*!
+ * \brief Return node by its index
+ * \param ind - node index
+ * \retval const SMDS_MeshNode* - the node
+ */
+const SMDS_MeshNode*
+SMDS_VtkEdge::GetNode(const int ind) const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType npts, *pts;
+  grid->GetCellPoints( this->myVtkID, npts, pts );
+  return SMDS_Mesh::_meshList[myMeshId]->FindNodeVtk( pts[ ind ]);
+}
+
+bool SMDS_VtkEdge::IsQuadratic() const
+{
+  if (this->NbNodes() > 2)
+    return true;
+  else
+    return false;
+}
+
+SMDS_ElemIteratorPtr SMDS_VtkEdge::elementsIterator(SMDSAbs_ElementType type) const
+{
+  switch (type)
+  {
+    case SMDSAbs_Node:
+      return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
+    default:
+      MESSAGE("ERROR : Iterator not implemented")
+      ;
+      return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL);
+  }
+}
+
+SMDS_ElemIteratorPtr SMDS_VtkEdge::nodesIteratorToUNV() const
+{
+  return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
+}
+
+SMDS_ElemIteratorPtr SMDS_VtkEdge::interlacedNodesElemIterator() const
+{
+  return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
+}
diff --git a/src/SMDS/SMDS_VtkEdge.hxx b/src/SMDS/SMDS_VtkEdge.hxx
new file mode 100644 (file)
index 0000000..c5f0430
--- /dev/null
@@ -0,0 +1,59 @@
+// Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+//  SMESH SMDS : implementaion of Salome mesh data structure
+//  File   : SMDS_VtkEdge.hxx
+//  Module : SMESH
+
+#ifndef _SMDS_VTKEDGE_HXX_
+#define _SMDS_VTKEDGE_HXX_
+
+#include "SMESH_SMDS.hxx"
+
+#include "SMDS_MeshEdge.hxx"
+#include <vtkUnstructuredGrid.h>
+#include <vector>
+
+class SMDS_EXPORT SMDS_VtkEdge: public SMDS_MeshEdge
+{
+
+public:
+  SMDS_VtkEdge();
+  SMDS_VtkEdge(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh);
+  ~SMDS_VtkEdge();
+  void init(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh);
+  bool ChangeNodes(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2);
+  virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes);
+  virtual bool IsMediumNode(const SMDS_MeshNode* node) const;
+
+  virtual void Print(std::ostream & OS) const;
+  virtual int NbNodes() const;
+  virtual int NbEdges() const;
+
+  virtual vtkIdType GetVtkType() const;
+  virtual SMDSAbs_EntityType GetEntityType() const;
+  virtual const SMDS_MeshNode* GetNode(const int ind) const;
+  virtual bool IsQuadratic() const;
+
+  virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const;
+  virtual SMDS_ElemIteratorPtr nodesIteratorToUNV() const;
+  virtual SMDS_ElemIteratorPtr interlacedNodesElemIterator() const;
+protected:
+};
+#endif
diff --git a/src/SMDS/SMDS_VtkFace.cxx b/src/SMDS/SMDS_VtkFace.cxx
new file mode 100644 (file)
index 0000000..80644c7
--- /dev/null
@@ -0,0 +1,301 @@
+// Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+#include "SMDS_VtkFace.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_Mesh.hxx"
+#include "SMDS_VtkCellIterator.hxx"
+
+#include "utilities.h"
+
+#include <vector>
+
+using namespace std;
+
+SMDS_VtkFace::SMDS_VtkFace()
+{
+}
+
+SMDS_VtkFace::SMDS_VtkFace(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh)
+{
+  init(nodeIds, mesh);
+}
+
+SMDS_VtkFace::~SMDS_VtkFace()
+{
+}
+
+void SMDS_VtkFace::init(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh)
+{
+  SMDS_MeshFace::init();
+  vtkUnstructuredGrid* grid = mesh->getGrid();
+  myMeshId = mesh->getMeshId();
+  vtkIdType aType = VTK_TRIANGLE;
+  switch (nodeIds.size())
+  {
+    case 3:
+      aType = VTK_TRIANGLE;
+      break;
+    case 4:
+      aType = VTK_QUAD;
+      break;
+    case 6:
+      aType = VTK_QUADRATIC_TRIANGLE;
+      break;
+    case 8:
+      aType = VTK_QUADRATIC_QUAD;
+      break;
+    case 9:
+      aType = VTK_BIQUADRATIC_QUAD;
+      break;
+    default:
+      aType = VTK_POLYGON;
+      break;
+  }
+  myVtkID = grid->InsertNextLinkedCell(aType, nodeIds.size(), (vtkIdType*) &nodeIds[0]);
+  mesh->setMyModified();
+  //MESSAGE("SMDS_VtkFace::init myVtkID " << myVtkID);
+}
+
+void SMDS_VtkFace::initPoly(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh)
+{
+  SMDS_MeshFace::init();
+  vtkUnstructuredGrid* grid = mesh->getGrid();
+  myMeshId = mesh->getMeshId();
+  myVtkID = grid->InsertNextLinkedCell(VTK_POLYGON, nodeIds.size(), (vtkIdType*) &nodeIds[0]);
+  mesh->setMyModified();
+}
+
+bool SMDS_VtkFace::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType npts = 0;
+  vtkIdType* pts = 0;
+  grid->GetCellPoints(myVtkID, npts, pts);
+  if (nbNodes != npts)
+    {
+      MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << nbNodes);
+      return false;
+    }
+  for (int i = 0; i < nbNodes; i++)
+    {
+      pts[i] = nodes[i]->getVtkId();
+    }
+  SMDS_Mesh::_meshList[myMeshId]->setMyModified();
+  return true;
+}
+
+void SMDS_VtkFace::Print(std::ostream & OS) const
+{
+  OS << "face <" << GetID() << "> : ";
+}
+
+int SMDS_VtkFace::NbEdges() const
+{
+  // TODO quadratic polygons ?
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  int nbEdges = 3;
+  switch (aVtkType)
+  {
+    case VTK_TRIANGLE:
+    case VTK_QUADRATIC_TRIANGLE:
+      nbEdges = 3;
+      break;
+    case VTK_QUAD:
+    case VTK_QUADRATIC_QUAD:
+    case VTK_BIQUADRATIC_QUAD:
+      nbEdges = 4;
+      break;
+    case VTK_POLYGON:
+    default:
+      nbEdges = grid->GetCell(myVtkID)->GetNumberOfPoints();
+      break;
+  }
+  return nbEdges;
+}
+
+int SMDS_VtkFace::NbFaces() const
+{
+  return 1;
+}
+
+int SMDS_VtkFace::NbNodes() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  int nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints();
+  return nbPoints;
+}
+
+/*!
+ * \brief Return node by its index
+ * \param ind - node index
+ * \retval const SMDS_MeshNode* - the node
+ */
+const SMDS_MeshNode*
+SMDS_VtkFace::GetNode(const int ind) const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType npts, *pts;
+  grid->GetCellPoints( this->myVtkID, npts, pts );
+  return SMDS_Mesh::_meshList[myMeshId]->FindNodeVtk( pts[ ind ]);
+}
+
+bool SMDS_VtkFace::IsQuadratic() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  // TODO quadratic polygons ?
+  switch (aVtkType)
+  {
+    case VTK_QUADRATIC_TRIANGLE:
+    case VTK_QUADRATIC_QUAD:
+    case VTK_BIQUADRATIC_QUAD:
+      return true;
+      break;
+    default:
+      return false;
+  }
+}
+
+bool SMDS_VtkFace::IsPoly() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  return (aVtkType == VTK_POLYGON);
+}
+
+bool SMDS_VtkFace::IsMediumNode(const SMDS_MeshNode* node) const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  int rankFirstMedium = 0;
+  switch (aVtkType)
+  {
+    case VTK_QUADRATIC_TRIANGLE:
+      rankFirstMedium = 3; // medium nodes are of rank 3,4,5
+      break;
+    case VTK_QUADRATIC_QUAD:
+    case VTK_BIQUADRATIC_QUAD:
+      rankFirstMedium = 4; // medium nodes are of rank 4,5,6,7
+      break;
+    default:
+      //MESSAGE("wrong element type " << aVtkType);
+      return false;
+  }
+  vtkIdType npts = 0;
+  vtkIdType* pts = 0;
+  grid->GetCellPoints(myVtkID, npts, pts);
+  vtkIdType nodeId = node->getVtkId();
+  for (int rank = 0; rank < npts; rank++)
+    {
+      if (pts[rank] == nodeId)
+        {
+          //MESSAGE("rank " << rank << " is medium node " << (rank < rankFirstMedium));
+          if (rank < rankFirstMedium)
+            return false;
+          else
+            return true;
+        }
+    }
+  //throw SALOME_Exception(LOCALIZED("node does not belong to this element"));
+  MESSAGE("======================================================");
+  MESSAGE("= IsMediumNode: node does not belong to this element =");
+  MESSAGE("======================================================");
+  return false;
+}
+
+int SMDS_VtkFace::NbCornerNodes() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  int       nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints();
+  vtkIdType aVtkType = grid->GetCellType(myVtkID);
+  if ( aVtkType != VTK_POLYGON )
+    return nbPoints <= 4 ? nbPoints : nbPoints / 2;
+  return nbPoints;
+}
+
+SMDSAbs_EntityType SMDS_VtkFace::GetEntityType() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  return SMDS_MeshCell::toSmdsType( VTKCellType( aVtkType ));
+}
+
+SMDSAbs_GeometryType SMDS_VtkFace::GetGeomType() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  switch ( aVtkType ) {
+  case VTK_TRIANGLE:
+  case VTK_QUADRATIC_TRIANGLE:
+    return SMDSGeom_TRIANGLE;
+  case VTK_QUAD:
+  case VTK_QUADRATIC_QUAD:
+  case VTK_BIQUADRATIC_QUAD:
+    return SMDSGeom_QUADRANGLE;
+  case VTK_POLYGON:
+    return SMDSGeom_POLYGON;
+  default:;
+  }
+  return SMDSGeom_NONE;
+}
+
+vtkIdType SMDS_VtkFace::GetVtkType() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  return aVtkType;
+}
+
+SMDS_ElemIteratorPtr SMDS_VtkFace::elementsIterator(SMDSAbs_ElementType type) const
+{
+  switch (type)
+  {
+    case SMDSAbs_Node:
+      return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
+    default:
+      MESSAGE("ERROR : Iterator not implemented")
+      ;
+      return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL);
+  }
+}
+
+SMDS_ElemIteratorPtr SMDS_VtkFace::nodesIteratorToUNV() const
+{
+  return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
+}
+
+SMDS_ElemIteratorPtr SMDS_VtkFace::interlacedNodesElemIterator() const
+{
+  return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
+}
+
+//! change only the first node, used for temporary triangles in quadrangle to triangle adaptor
+void SMDS_VtkFace::ChangeApex(SMDS_MeshNode* node)
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType npts = 0;
+  vtkIdType* pts = 0;
+  grid->GetCellPoints(myVtkID, npts, pts);
+  grid->RemoveReferenceToCell(pts[0], myVtkID);
+  pts[0] = node->getVtkId();
+  node->AddInverseElement(this),
+  SMDS_Mesh::_meshList[myMeshId]->setMyModified();
+}
diff --git a/src/SMDS/SMDS_VtkFace.hxx b/src/SMDS/SMDS_VtkFace.hxx
new file mode 100644 (file)
index 0000000..f84192f
--- /dev/null
@@ -0,0 +1,62 @@
+// Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+#ifndef _SMDS_VTKFACE_HXX_
+#define _SMDS_VTKFACE_HXX_
+
+#include "SMESH_SMDS.hxx"
+
+#include "SMDS_MeshFace.hxx"
+#include <vtkUnstructuredGrid.h>
+#include <vector>
+
+class SMDS_EXPORT SMDS_VtkFace: public SMDS_MeshFace
+{
+public:
+  SMDS_VtkFace();
+  SMDS_VtkFace(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh);
+  ~SMDS_VtkFace();
+  void init(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh);
+  void initPoly(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh);
+
+  bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes);
+  void ChangeApex(SMDS_MeshNode* node); // to use only for tmp triangles
+
+  virtual void Print(std::ostream & OS) const;
+  virtual int NbEdges() const;
+  virtual int NbFaces() const;
+  virtual int NbNodes() const;
+
+  virtual vtkIdType            GetVtkType() const;
+  virtual SMDSAbs_EntityType   GetEntityType() const;
+  virtual SMDSAbs_GeometryType GetGeomType() const;
+  virtual const SMDS_MeshNode* GetNode(const int ind) const;
+
+  virtual bool IsQuadratic() const;
+  virtual bool IsPoly() const;
+  virtual bool IsMediumNode(const SMDS_MeshNode* node) const;
+  virtual int  NbCornerNodes() const;
+
+  virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const;
+  virtual SMDS_ElemIteratorPtr nodesIteratorToUNV() const;
+  virtual SMDS_ElemIteratorPtr interlacedNodesElemIterator() const;
+protected:
+};
+
+#endif
diff --git a/src/SMDS/SMDS_VtkVolume.cxx b/src/SMDS/SMDS_VtkVolume.cxx
new file mode 100644 (file)
index 0000000..de9174e
--- /dev/null
@@ -0,0 +1,675 @@
+// Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+#include "SMDS_VtkVolume.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_Mesh.hxx"
+#include "SMDS_VtkCellIterator.hxx"
+
+#include "utilities.h"
+
+#include <vector>
+
+SMDS_VtkVolume::SMDS_VtkVolume()
+{
+}
+
+SMDS_VtkVolume::SMDS_VtkVolume(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh)
+{
+  init(nodeIds, mesh);
+}
+/*!
+ * typed used are vtk types (@see vtkCellType.h)
+ * see GetEntityType() for conversion in SMDS type (@see SMDSAbs_ElementType.hxx)
+ */
+void SMDS_VtkVolume::init(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh)
+{
+  SMDS_MeshVolume::init();
+  vtkUnstructuredGrid* grid = mesh->getGrid();
+  myMeshId = mesh->getMeshId();
+  vtkIdType aType = VTK_TETRA;
+  switch (nodeIds.size()) // cases are in order of usage frequency
+  {
+    case 4:
+      aType = VTK_TETRA;
+      break;
+    case 8:
+      aType = VTK_HEXAHEDRON;
+      break;
+    case 5:
+      aType = VTK_PYRAMID;
+      break;
+    case 6:
+      aType = VTK_WEDGE;
+      break;
+    case 10:
+      aType = VTK_QUADRATIC_TETRA;
+      break;
+    case 20:
+      aType = VTK_QUADRATIC_HEXAHEDRON;
+      break;
+    case 13:
+      aType = VTK_QUADRATIC_PYRAMID;
+      break;
+    case 15:
+      aType = VTK_QUADRATIC_WEDGE;
+      break;
+    case 12:
+      aType = VTK_HEXAGONAL_PRISM;
+      break;
+    case 27:
+      aType = VTK_TRIQUADRATIC_HEXAHEDRON;
+      break;
+    default:
+      aType = VTK_HEXAHEDRON;
+      break;
+  }
+  myVtkID = grid->InsertNextLinkedCell(aType, nodeIds.size(), (vtkIdType *) &nodeIds[0]);
+  mesh->setMyModified();
+  //MESSAGE("SMDS_VtkVolume::init myVtkID " << myVtkID);
+}
+
+//#ifdef VTK_HAVE_POLYHEDRON
+void SMDS_VtkVolume::initPoly(const std::vector<vtkIdType>& nodeIds,
+                              const std::vector<int>&       nbNodesPerFace,
+                              SMDS_Mesh*                    mesh)
+{
+  SMDS_MeshVolume::init();
+  //MESSAGE("SMDS_VtkVolume::initPoly");
+  SMDS_UnstructuredGrid* grid = mesh->getGrid();
+  //double center[3];
+  //this->gravityCenter(grid, &nodeIds[0], nodeIds.size(), &center[0]);
+  vector<vtkIdType> ptIds;
+  vtkIdType nbFaces = nbNodesPerFace.size();
+  int k = 0;
+  for (int i = 0; i < nbFaces; i++)
+    {
+      int nf = nbNodesPerFace[i];
+      ptIds.push_back(nf);
+      // EAP: a right approach is:
+      // - either the user should care of order of nodes or
+      // - the user should use a service method arranging nodes if he
+      //   don't want or can't to do it by him-self
+      // The method below works OK only with planar faces and convex polyhedrones
+      //
+      // double a[3];
+      // double b[3];
+      // double c[3];
+      // grid->GetPoints()->GetPoint(nodeIds[k], a);
+      // grid->GetPoints()->GetPoint(nodeIds[k + 1], b);
+      // grid->GetPoints()->GetPoint(nodeIds[k + 2], c);
+      // bool isFaceForward = this->isForward(a, b, c, center);
+      //MESSAGE("isFaceForward " << i << " " << isFaceForward);
+      const vtkIdType *facePts = &nodeIds[k];
+      //if (isFaceForward)
+        for (int n = 0; n < nf; n++)
+          ptIds.push_back(facePts[n]);
+      // else
+      //   for (int n = nf - 1; n >= 0; n--)
+      //     ptIds.push_back(facePts[n]);
+      k += nf;
+    }
+  myVtkID = grid->InsertNextLinkedCell(VTK_POLYHEDRON, nbFaces, &ptIds[0]);
+  mesh->setMyModified();
+}
+//#endif
+
+bool SMDS_VtkVolume::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType npts = 0;
+  vtkIdType* pts = 0;
+  grid->GetCellPoints(myVtkID, npts, pts);
+  if (nbNodes != npts)
+    {
+      MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << nbNodes);
+      return false;
+    }
+  for (int i = 0; i < nbNodes; i++)
+    {
+      pts[i] = nodes[i]->getVtkId();
+    }
+  SMDS_Mesh::_meshList[myMeshId]->setMyModified();
+  return true;
+}
+
+/*!
+ * Reorder in VTK order a list of nodes given in SMDS order.
+ * To be used before ChangeNodes: lists are given or computed in SMDS order.
+ */
+bool SMDS_VtkVolume::vtkOrder(const SMDS_MeshNode* nodes[], const int nbNodes)
+{
+  if (nbNodes != this->NbNodes())
+    {
+      MESSAGE("vtkOrder, wrong number of nodes " << nbNodes << " instead of "<< this->NbNodes());
+      return false;
+    }
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  const std::vector<int>& interlace = SMDS_MeshCell::toVtkOrder( VTKCellType( aVtkType ));
+  if ( !interlace.empty() )
+  {
+    ASSERT( interlace.size() == nbNodes );
+    std::vector<const SMDS_MeshNode*> initNodes( nodes, nodes+nbNodes );
+    for ( size_t i = 0; i < interlace.size(); ++i )
+      nodes[i] = initNodes[ interlace[i] ];
+  }
+  return true;
+}
+
+SMDS_VtkVolume::~SMDS_VtkVolume()
+{
+}
+
+void SMDS_VtkVolume::Print(ostream & OS) const
+{
+  OS << "volume <" << GetID() << "> : ";
+}
+
+int SMDS_VtkVolume::NbFaces() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  int nbFaces = 4;
+  switch (aVtkType)
+  {
+    case VTK_TETRA:
+    case VTK_QUADRATIC_TETRA:
+      nbFaces = 4;
+      break;
+    case VTK_PYRAMID:
+    case VTK_WEDGE:
+    case VTK_QUADRATIC_PYRAMID:
+    case VTK_QUADRATIC_WEDGE:
+      nbFaces = 5;
+      break;
+    case VTK_HEXAHEDRON:
+    case VTK_QUADRATIC_HEXAHEDRON:
+    case VTK_TRIQUADRATIC_HEXAHEDRON:
+      nbFaces = 6;
+      break;
+    case VTK_POLYHEDRON:
+      {
+        vtkIdType nFaces = 0;
+        vtkIdType* ptIds = 0;
+        grid->GetFaceStream(this->myVtkID, nFaces, ptIds);
+        nbFaces = nFaces;
+        break;
+      }
+    case VTK_HEXAGONAL_PRISM:
+      nbFaces = 8;
+      break;
+    default:
+      MESSAGE("invalid volume type")
+      ;
+      nbFaces = 0;
+      break;
+  }
+  return nbFaces;
+}
+
+int SMDS_VtkVolume::NbNodes() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  int nbPoints = 0;
+  if (aVtkType != VTK_POLYHEDRON)
+    {
+      nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints();
+    }
+  else
+    {
+      vtkIdType nFaces = 0;
+      vtkIdType* ptIds = 0;
+      grid->GetFaceStream(this->myVtkID, nFaces, ptIds);
+      int id = 0;
+      for (int i = 0; i < nFaces; i++)
+        {
+          int nodesInFace = ptIds[id];
+          nbPoints += nodesInFace;
+          id += (nodesInFace + 1);
+        }
+    }
+  return nbPoints;
+}
+
+int SMDS_VtkVolume::NbEdges() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  int nbEdges = 6;
+  switch (aVtkType)
+  {
+    case VTK_TETRA:
+    case VTK_QUADRATIC_TETRA:
+      nbEdges = 6;
+      break;
+    case VTK_PYRAMID:
+    case VTK_QUADRATIC_PYRAMID:
+      nbEdges = 8;
+      break;
+    case VTK_WEDGE:
+    case VTK_QUADRATIC_WEDGE:
+      nbEdges = 9;
+      break;
+    case VTK_HEXAHEDRON:
+    case VTK_QUADRATIC_HEXAHEDRON:
+    case VTK_TRIQUADRATIC_HEXAHEDRON:
+      nbEdges = 12;
+      break;
+    case VTK_POLYHEDRON:
+      {
+        vtkIdType nFaces = 0;
+        vtkIdType* ptIds = 0;
+        grid->GetFaceStream(this->myVtkID, nFaces, ptIds);
+        nbEdges = 0;
+        int id = 0;
+        for (int i = 0; i < nFaces; i++)
+          {
+            int edgesInFace = ptIds[id];
+            id += (edgesInFace + 1);
+            nbEdges += edgesInFace;
+          }
+        nbEdges = nbEdges / 2;
+        break;
+      }
+    case VTK_HEXAGONAL_PRISM:
+      nbEdges = 18;
+      break;
+    default:
+      MESSAGE("invalid volume type")
+      ;
+      nbEdges = 0;
+      break;
+  }
+  return nbEdges;
+}
+
+/*! polyhedron only,
+ *  1 <= face_ind <= NbFaces()
+ */
+int SMDS_VtkVolume::NbFaceNodes(const int face_ind) const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  int nbNodes = 0;
+  if (aVtkType == VTK_POLYHEDRON)
+    {
+      vtkIdType nFaces = 0;
+      vtkIdType* ptIds = 0;
+      grid->GetFaceStream(this->myVtkID, nFaces, ptIds);
+      int id = 0;
+      for (int i = 0; i < nFaces; i++)
+        {
+          int nodesInFace = ptIds[id];
+          id += (nodesInFace + 1);
+          if (i == face_ind - 1)
+            {
+              nbNodes = nodesInFace;
+              break;
+            }
+        }
+    }
+  return nbNodes;
+}
+
+/*! polyhedron only,
+ *  1 <= face_ind <= NbFaces()
+ *  1 <= node_ind <= NbFaceNodes()
+ */
+const SMDS_MeshNode* SMDS_VtkVolume::GetFaceNode(const int face_ind, const int node_ind) const
+{
+  SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myMeshId];
+  vtkUnstructuredGrid* grid = mesh->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  const SMDS_MeshNode* node = 0;
+  if (aVtkType == VTK_POLYHEDRON)
+    {
+      vtkIdType nFaces = 0;
+      vtkIdType* ptIds = 0;
+      grid->GetFaceStream(this->myVtkID, nFaces, ptIds);
+      int id = 0;
+      for (int i = 0; i < nFaces; i++)
+        {
+          int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace]
+          if (i == face_ind - 1) // first face is number 1
+            {
+              if ((node_ind > 0) && (node_ind <= nodesInFace))
+                node = mesh->FindNodeVtk(ptIds[id + node_ind]); // ptIds[id+1] : first node
+              break;
+            }
+          id += (nodesInFace + 1);
+        }
+    }
+  return node;
+}
+
+/*! polyhedron only,
+ *  return number of nodes for each face
+ */
+std::vector<int> SMDS_VtkVolume::GetQuantities() const
+{
+  vector<int> quantities;
+  quantities.clear();
+  SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myMeshId];
+  vtkUnstructuredGrid* grid = mesh->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  if (aVtkType == VTK_POLYHEDRON)
+    {
+      vtkIdType nFaces = 0;
+      vtkIdType* ptIds = 0;
+      grid->GetFaceStream(this->myVtkID, nFaces, ptIds);
+      int id = 0;
+      for (int i = 0; i < nFaces; i++)
+        {
+          int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace]
+          quantities.push_back(nodesInFace);
+          id += (nodesInFace + 1);
+        }
+    }
+  return quantities;
+}
+
+SMDS_ElemIteratorPtr SMDS_VtkVolume::elementsIterator(SMDSAbs_ElementType type) const
+{
+  switch (type)
+  {
+    case SMDSAbs_Node:
+      {
+        SMDSAbs_EntityType aType = this->GetEntityType();
+        if (aType == SMDSEntity_Polyhedra)
+          return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorPolyH(SMDS_Mesh::_meshList[myMeshId], myVtkID, aType));
+        else
+          return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, aType));
+      }
+    default:
+      MESSAGE("ERROR : Iterator not implemented");
+      return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL);
+  }
+}
+
+SMDS_ElemIteratorPtr SMDS_VtkVolume::nodesIteratorToUNV() const
+{
+  return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
+}
+
+SMDS_ElemIteratorPtr SMDS_VtkVolume::interlacedNodesElemIterator() const
+{
+  return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
+}
+
+SMDSAbs_ElementType SMDS_VtkVolume::GetType() const
+{
+  return SMDSAbs_Volume;
+}
+
+/*!
+ * \brief Return node by its index
+ * \param ind - node index
+ * \retval const SMDS_MeshNode* - the node
+ */
+const SMDS_MeshNode* SMDS_VtkVolume::GetNode(const int ind) const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  vtkIdType npts, *pts;
+  grid->GetCellPoints( this->myVtkID, npts, pts );
+  const std::vector<int>& interlace = SMDS_MeshCell::fromVtkOrder( VTKCellType( aVtkType ));
+  return SMDS_Mesh::_meshList[myMeshId]->FindNodeVtk( pts[ interlace.empty() ? ind : interlace[ind]] );
+}
+
+bool SMDS_VtkVolume::IsQuadratic() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  // TODO quadratic polyhedrons ?
+  switch (aVtkType)
+  {
+    case VTK_QUADRATIC_TETRA:
+    case VTK_QUADRATIC_PYRAMID:
+    case VTK_QUADRATIC_WEDGE:
+    case VTK_QUADRATIC_HEXAHEDRON:
+    case VTK_TRIQUADRATIC_HEXAHEDRON:
+      return true;
+      break;
+    default:
+      return false;
+  }
+}
+
+bool SMDS_VtkVolume::IsPoly() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  return (aVtkType == VTK_POLYHEDRON);
+}
+
+bool SMDS_VtkVolume::IsMediumNode(const SMDS_MeshNode* node) const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  int rankFirstMedium = 0;
+  switch (aVtkType)
+  {
+    case VTK_QUADRATIC_TETRA:
+      rankFirstMedium = 4; // medium nodes are of rank 4 to 9
+      break;
+    case VTK_QUADRATIC_PYRAMID:
+      rankFirstMedium = 5; // medium nodes are of rank 5 to 12
+      break;
+    case VTK_QUADRATIC_WEDGE:
+      rankFirstMedium = 6; // medium nodes are of rank 6 to 14
+      break;
+    case VTK_QUADRATIC_HEXAHEDRON:
+    case VTK_TRIQUADRATIC_HEXAHEDRON:
+      rankFirstMedium = 8; // medium nodes are of rank 8 to 19
+      break;
+    default:
+      return false;
+  }
+  vtkIdType npts = 0;
+  vtkIdType* pts = 0;
+  grid->GetCellPoints(myVtkID, npts, pts);
+  vtkIdType nodeId = node->getVtkId();
+  for (int rank = 0; rank < npts; rank++)
+    {
+      if (pts[rank] == nodeId)
+        {
+          if (rank < rankFirstMedium)
+            return false;
+          else
+            return true;
+        }
+    }
+  //throw SALOME_Exception(LOCALIZED("node does not belong to this element"));
+  MESSAGE("======================================================");
+  MESSAGE("= IsMediumNode: node does not belong to this element =");
+  MESSAGE("======================================================");
+  return false;
+}
+
+int SMDS_VtkVolume::NbCornerNodes() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  int            nbN = grid->GetCell(myVtkID)->GetNumberOfPoints();
+  vtkIdType aVtkType = grid->GetCellType(myVtkID);
+  switch (aVtkType)
+  {
+  case VTK_QUADRATIC_TETRA:         return 4;
+  case VTK_QUADRATIC_PYRAMID:       return 5;
+  case VTK_QUADRATIC_WEDGE:         return 6;
+  case VTK_QUADRATIC_HEXAHEDRON:
+  case VTK_TRIQUADRATIC_HEXAHEDRON: return 8;
+  default:;
+  }
+  return nbN;
+}
+
+SMDSAbs_EntityType SMDS_VtkVolume::GetEntityType() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+
+  SMDSAbs_EntityType aType = SMDSEntity_Tetra;
+  switch (aVtkType)
+  {
+    case VTK_TETRA:
+      aType = SMDSEntity_Tetra;
+      break;
+    case VTK_PYRAMID:
+      aType = SMDSEntity_Pyramid;
+      break;
+    case VTK_WEDGE:
+      aType = SMDSEntity_Penta;
+      break;
+    case VTK_HEXAHEDRON:
+      aType = SMDSEntity_Hexa;
+      break;
+    case VTK_QUADRATIC_TETRA:
+      aType = SMDSEntity_Quad_Tetra;
+      break;
+    case VTK_QUADRATIC_PYRAMID:
+      aType = SMDSEntity_Quad_Pyramid;
+      break;
+    case VTK_QUADRATIC_WEDGE:
+      aType = SMDSEntity_Quad_Penta;
+      break;
+    case VTK_QUADRATIC_HEXAHEDRON:
+      aType = SMDSEntity_Quad_Hexa;
+      break;
+    case VTK_TRIQUADRATIC_HEXAHEDRON:
+      aType = SMDSEntity_TriQuad_Hexa;
+      break;
+    case VTK_HEXAGONAL_PRISM:
+      aType = SMDSEntity_Hexagonal_Prism;
+      break;
+//#ifdef VTK_HAVE_POLYHEDRON
+    case VTK_POLYHEDRON:
+      aType = SMDSEntity_Polyhedra;
+      break;
+//#endif
+    default:
+      aType = SMDSEntity_Polyhedra;
+      break;
+  }
+  return aType;
+}
+
+SMDSAbs_GeometryType SMDS_VtkVolume::GetGeomType() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+
+  SMDSAbs_GeometryType aType = SMDSGeom_NONE;
+  switch (aVtkType)
+  {
+    case VTK_TETRA:
+    case VTK_QUADRATIC_TETRA:
+      aType = SMDSGeom_TETRA;
+      break;
+    case VTK_PYRAMID:
+    case VTK_QUADRATIC_PYRAMID:
+      aType = SMDSGeom_PYRAMID;
+      break;
+    case VTK_WEDGE:
+    case VTK_QUADRATIC_WEDGE:
+      aType = SMDSGeom_PENTA;
+      break;
+    case VTK_HEXAHEDRON:
+    case VTK_QUADRATIC_HEXAHEDRON:
+    case VTK_TRIQUADRATIC_HEXAHEDRON:
+      aType = SMDSGeom_HEXA;
+      break;
+    case VTK_HEXAGONAL_PRISM:
+      aType = SMDSGeom_HEXAGONAL_PRISM;
+      break;
+//#ifdef VTK_HAVE_POLYHEDRON
+    case VTK_POLYHEDRON:
+      aType = SMDSGeom_POLYHEDRA;
+      break;
+//#endif
+    default:
+      aType = SMDSGeom_POLYHEDRA;
+      break;
+  }
+  return aType;
+}
+
+vtkIdType SMDS_VtkVolume::GetVtkType() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aType = grid->GetCellType(myVtkID);
+  return aType;
+}
+
+void SMDS_VtkVolume::gravityCenter(SMDS_UnstructuredGrid* grid,
+                                   const vtkIdType *      nodeIds,
+                                   int                    nbNodes,
+                                   double*                result)
+{
+  for (int j = 0; j < 3; j++)
+    result[j] = 0;
+  if (nbNodes <= 0)
+    return;
+  for (int i = 0; i < nbNodes; i++)
+    {
+      double *coords = grid->GetPoint(nodeIds[i]);
+      for (int j = 0; j < 3; j++)
+        result[j] += coords[j];
+    }
+  for (int j = 0; j < 3; j++)
+    result[j] = result[j] / nbNodes;
+  //MESSAGE("center " << result[0] << " " << result[1] << " "  << result[2]);
+  return;
+}
+
+bool SMDS_VtkVolume::isForward(double* a, double* b, double* c, double* d)
+{
+  double u[3], v[3], w[3];
+  for (int j = 0; j < 3; j++)
+    {
+      //MESSAGE("a,b,c,d " << a[j] << " " << b[j] << " " << c[j] << " " << d[j]);
+      u[j] = b[j] - a[j];
+      v[j] = c[j] - a[j];
+      w[j] = d[j] - a[j];
+      //MESSAGE("u,v,w " << u[j] << " " << v[j] << " " << w[j]);
+    }
+  double prodmixte = (u[1]*v[2] - u[2]*v[1]) * w[0]
+                   + (u[2]*v[0] - u[0]*v[2]) * w[1]
+                   + (u[0]*v[1] - u[1]*v[0]) * w[2];
+  return (prodmixte < 0);
+}
+
+/*! For polyhedron only
+ *  @return actual number of nodes (not the sum of nodes of all faces)
+ */
+int SMDS_VtkVolume::NbUniqueNodes() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  return grid->GetCell(myVtkID)->GetNumberOfPoints();
+}
+
+/*! For polyhedron use only
+ *  @return iterator on actual nodes (not through the faces)
+ */
+SMDS_ElemIteratorPtr SMDS_VtkVolume::uniqueNodesIterator() const
+{
+  MESSAGE("uniqueNodesIterator");
+  return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
+}
diff --git a/src/SMDS/SMDS_VtkVolume.hxx b/src/SMDS/SMDS_VtkVolume.hxx
new file mode 100644 (file)
index 0000000..5f3f62b
--- /dev/null
@@ -0,0 +1,79 @@
+// Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+#ifndef _SMDS_VTKVOLUME_HXX_
+#define _SMDS_VTKVOLUME_HXX_
+
+#include "SMESH_SMDS.hxx"
+
+#include "SMDS_MeshVolume.hxx"
+#include "SMDS_UnstructuredGrid.hxx"
+#include <vector>
+
+class SMDS_EXPORT SMDS_VtkVolume: public SMDS_MeshVolume
+{
+public:
+  SMDS_VtkVolume();
+  SMDS_VtkVolume(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh);
+  ~SMDS_VtkVolume();
+  void init(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh);
+//#ifdef VTK_HAVE_POLYHEDRON
+  void initPoly(const std::vector<vtkIdType>& nodeIds,
+                const std::vector<int>& nbNodesPerFace, SMDS_Mesh* mesh);
+//#endif
+  virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes);
+  virtual bool vtkOrder(const SMDS_MeshNode* nodes[], const int nbNodes);
+
+  virtual void Print(std::ostream & OS) const;
+  virtual int NbFaces() const;
+  virtual int NbNodes() const;
+  virtual int NbEdges() const;
+
+  // 1 <= face_ind <= NbFaces()
+  int NbFaceNodes (const int face_ind) const;
+  // 1 <= face_ind <= NbFaces()
+  // 1 <= node_ind <= NbFaceNodes()
+  const SMDS_MeshNode* GetFaceNode (const int face_ind, const int node_ind) const;
+
+  virtual SMDSAbs_ElementType  GetType() const;
+  virtual vtkIdType            GetVtkType() const;
+  virtual SMDSAbs_EntityType   GetEntityType() const;
+  virtual SMDSAbs_GeometryType GetGeomType() const;
+  virtual const SMDS_MeshNode* GetNode(const int ind) const;
+  virtual bool IsQuadratic() const;
+  virtual bool IsPoly() const;
+  virtual bool IsMediumNode(const SMDS_MeshNode* node) const;
+  virtual int  NbCornerNodes() const;
+  static void gravityCenter(SMDS_UnstructuredGrid* grid,
+                            const vtkIdType *nodeIds,
+                            int nbNodes,
+                            double* result);
+  static bool isForward(double* a,double* b,double* c,double* d);
+  int NbUniqueNodes() const;
+  SMDS_ElemIteratorPtr uniqueNodesIterator() const;
+  std::vector<int> GetQuantities() const;
+
+  virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const;
+  virtual SMDS_ElemIteratorPtr nodesIteratorToUNV() const;
+  virtual SMDS_ElemIteratorPtr interlacedNodesElemIterator() const;
+
+protected:
+};
+
+#endif
index 97a1b63ff14f0c7c0d062b195462ce8811c8e01a..d99e401df909606ae546dc75df3c0979af9d7640 100755 (executable)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  File   : SMESH_SMDS.hxx
 //  Author : Alexander A. BORODIN
 //  Module : SMESH
diff --git a/src/SMDS/chrono.cxx b/src/SMDS/chrono.cxx
new file mode 100644 (file)
index 0000000..8956ce3
--- /dev/null
@@ -0,0 +1,86 @@
+// Copyright (C) 2006-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+#include "chrono.hxx"
+#include "utilities.h"
+
+using namespace std;
+
+cntStruct* counters::_ctrs = 0;
+int counters::_nbChrono = 0;
+
+counters::counters(int nb)
+{
+  MESSAGE("counters::counters(int nb)");
+  _nbChrono = nb;
+  _ctrs = new cntStruct[_nbChrono];
+
+  for (int i = 0; i < _nbChrono; i++)
+    {
+      _ctrs[i]._ctrNames = 0;
+      _ctrs[i]._ctrLines = 0;
+      _ctrs[i]._ctrOccur = 0;
+      _ctrs[i]._ctrCumul = 0;
+    }
+
+  MESSAGE("counters::counters()");
+}
+
+counters::~counters()
+{
+  stats();
+}
+
+void counters::stats()
+{
+  MESSAGE("counters::stats()");
+  for (int i = 0; i < _nbChrono; i++)
+    if (_ctrs[i]._ctrOccur)
+      {
+        MESSAGE("Compteur[" << i << "]: "<< _ctrs[i]._ctrNames << "[" << _ctrs[i]._ctrLines << "]");
+        MESSAGE("  " << _ctrs[i]._ctrOccur);
+        MESSAGE("  " << _ctrs[i]._ctrCumul);
+      }
+}
+
+chrono::chrono(int i) :
+  _ctr(i), _run(true)
+{
+  //MESSAGE("chrono::chrono " << _ctr << " " << _run);
+  _start = clock();
+}
+
+chrono::~chrono()
+{
+  if (_run)
+    stop();
+}
+
+void chrono::stop()
+{
+  //MESSAGE("chrono::stop " << _ctr << " " << _run);
+  if (_run)
+    {
+      _run = false;
+      _end = clock();
+      double elapse = double(_end - _start) / double(CLOCKS_PER_SEC);
+      counters::_ctrs[_ctr]._ctrOccur++;
+      counters::_ctrs[_ctr]._ctrCumul += elapse;
+    }
+}
diff --git a/src/SMDS/chrono.hxx b/src/SMDS/chrono.hxx
new file mode 100644 (file)
index 0000000..bee39b0
--- /dev/null
@@ -0,0 +1,75 @@
+// Copyright (C) 2006-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+#ifndef _CHRONO_HXX_
+#define _CHRONO_HXX_
+
+#include "SMESH_SMDS.hxx"
+
+#include <vector>
+#include <string>
+#include <iostream>
+#include <ctime>
+
+typedef struct acnt
+{
+  char*  _ctrNames;
+  int    _ctrLines;
+  int    _ctrOccur;
+  double _ctrCumul;
+} cntStruct;
+
+class SMDS_EXPORT counters
+{
+public:
+  static cntStruct *_ctrs;
+  counters(int nb);
+  ~counters();
+  static void stats();
+protected:
+  static int _nbChrono;
+};
+
+class SMDS_EXPORT chrono
+{
+public:
+  chrono(int i);
+  ~chrono();
+  void stop();
+protected:
+  bool _run;
+  int _ctr;
+  clock_t _start, _end;
+};
+
+#ifdef CHRONODEF
+#define CHRONO(i) counters::_ctrs[i]._ctrNames = (char *)__FILE__; \
+  counters::_ctrs[i]._ctrLines = __LINE__; \
+  chrono aChrono##i(i);
+
+#define CHRONOSTOP(i) aChrono##i.stop();
+
+#else  // CHRONODEF
+
+#define CHRONO(i)
+#define CHRONOSTOP(i)
+
+#endif // CHRONODEF
+
+#endif // _CHRONO_HXX_
index 2905cc92bec9cb0e5b81f7f7c78515004437671b..3008e024fe790155b5fff9483b1339205a00a2c2 100644 (file)
@@ -1,31 +1,28 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  SMESH SMESH : implementaion of SMESH idl descriptions
 #  File   : Makefile.in
 #  Author : Paul RASCLE, EDF
 #  Modified by : Alexander BORODIN (OCN) - autotools usage
 #  Module : SMESH
-#  $Header$
-#
+
 include $(top_srcdir)/adm_local/unix/make_common_starter.am
 
 # header files 
@@ -43,17 +40,9 @@ salomeinclude_HEADERS = \
        SMESH_3D_Algo.hxx \
        SMESH_Group.hxx \
        SMESH_MeshEditor.hxx \
-       SMESH_Block.hxx \
        SMESH_Pattern.hxx \
-       SMESH_IndexedDataMapOfShapeIndexedMapOfShape.hxx \
-       SMESH_DataMapOfElemPtrSequenceOfElemPtr.hxx \
-       SMESH_SequenceOfElemPtr.hxx \
-       SMESH_SequenceOfNode.hxx \
        SMESH_MesherHelper.hxx \
-       SMESH_Octree.hxx \
-       SMESH_OctreeNode.hxx \
-       SMESH_Comment.hxx \
-       SMESH_ComputeError.hxx \
+       SMESH_ProxyMesh.hxx \
        SMESH_SMESH.hxx
 
 # Libraries targets
@@ -61,6 +50,7 @@ salomeinclude_HEADERS = \
 lib_LTLIBRARIES = libSMESHimpl.la
 
 dist_libSMESHimpl_la_SOURCES = \
+       memoire.h \
        SMESH_Gen.cxx \
        SMESH_Mesh.cxx \
        SMESH_subMesh.cxx \
@@ -72,12 +62,10 @@ dist_libSMESHimpl_la_SOURCES = \
        SMESH_3D_Algo.cxx \
        SMESH_Group.cxx \
        SMESH_MeshEditor.cxx \
-       SMESH_Block.cxx \
        SMESH_Pattern.cxx \
        SMESH_HypoFilter.cxx \
-       SMESH_MesherHelper.cxx \
-       SMESH_Octree.cxx \
-       SMESH_OctreeNode.cxx
+       SMESH_ProxyMesh.cxx \
+       SMESH_MesherHelper.cxx
 
 # additionnal information to compile and link file
 libSMESHimpl_la_CPPFLAGS = \
@@ -85,6 +73,7 @@ libSMESHimpl_la_CPPFLAGS = \
        $(CAS_CPPFLAGS) \
        $(MED_CXXFLAGS) \
        $(GEOM_CXX_FLAGS) \
+        $(VTK_INCLUDES) \
        $(BOOST_CPPFLAGS) \
        @HDF5_INCLUDES@ \
        -I$(srcdir)/../Controls \
@@ -93,10 +82,14 @@ libSMESHimpl_la_CPPFLAGS = \
        -I$(srcdir)/../DriverMED \
        -I$(srcdir)/../DriverUNV \
        -I$(srcdir)/../DriverSTL \
+       -I$(srcdir)/../DriverCGNS \
        -I$(srcdir)/../SMDS \
        -I$(srcdir)/../SMESHDS \
-       -I$(top_builddir)/salome_adm/unix
+       -I$(srcdir)/../SMESHUtils
 
+if WITH_CGNS
+  DriverCGNS_LIB = ../DriverCGNS/libMeshDriverCGNS.la
+endif
 
 libSMESHimpl_la_LDFLAGS = \
        ../SMESHDS/libSMESHDS.la \
@@ -105,5 +98,8 @@ libSMESHimpl_la_LDFLAGS = \
        ../DriverSTL/libMeshDriverSTL.la \
        ../DriverMED/libMeshDriverMED.la \
        ../DriverUNV/libMeshDriverUNV.la \
+       $(DriverCGNS_LIB) \
+       ../SMESHUtils/libSMESHUtils.la \
+       $(BOOST_LIB_THREAD)  \
        $(GEOM_LDFLAGS) -lNMTTools \
-       $(CAS_LDPATH) -lTKShHealing
+       $(CAS_LDPATH) -lTKShHealing -lTKPrim -lTKG2d
index f20074cc3d00a9d252a6e8cd8b6f55d4732999b5..bc3461d10612c2447bfad84f029476f2d136a7de 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : SMESH_0D_Algo.cxx
 //  Module : SMESH
index 71f7476e6b86be87a9e559254110c2fac7918561..d7ba782d8e51b40e40e7fd42e7c834f7e86a2333 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : SMESH_0D_Algo.hxx
 //  Module : SMESH
index ff6b9f7ff2c8ae7f7f54b64d695959ab26450c20..3027f82f42d6d077d5d8b488a62167053770ed25 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : SMESH_1D_Algo.cxx
 //  Author : Paul RASCLE, EDF
index 9da4fd9858aeebc354aa7143434b861d18edbda8..e10aa197df1a4838d09ad17207ec7c7f235f5222 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : SMESH_1D_Algo.hxx
 //  Author : Paul RASCLE, EDF
index 00723cbd7268d4a4ee18c4f333395c5ac854be32..a4feece7bb848475621f6227378f703ff79042cc 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : SMESH_2D_Algo.cxx
 //  Author : Paul RASCLE, EDF
index 41a8bc1afae551e608dffc5c13d41b1ffea3992f..0a2a127f32f480a659d9a22c83e8906f8671f8cf 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : SMESH_2D_Algo.hxx
 //  Author : Paul RASCLE, EDF
index ee547368fd03a9886a90ed1c311bb5c5cbe5d656..d7a0ed88d8c25d6aef293124a6c94b66f62e1095 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : SMESH_3D_Algo.cxx
 //  Author : Paul RASCLE, EDF
index 9c47614088254db108a4089c10e0d4546eeee2bf..2b64d9eb0fc7f8e298a6d76f984ee24b9c69643b 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : SMESH_3D_Algo.hxx
 //  Author : Paul RASCLE, EDF
index 7398cf856ed4199cf815b9829f71293c72c0b465..9768eb04976821b7074851e63a137942747a2409 100644 (file)
@@ -1,41 +1,46 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : SMESH_Algo.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//
 
 #include "SMESH_Algo.hxx"
-#include "SMESH_Comment.hxx"
-#include "SMESH_Gen.hxx"
-#include "SMESH_Mesh.hxx"
-#include "SMESH_HypoFilter.hxx"
-#include "SMDS_FacePosition.hxx"
+
 #include "SMDS_EdgePosition.hxx"
+#include "SMDS_FacePosition.hxx"
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
+#include "SMDS_VolumeTool.hxx"
 #include "SMESHDS_Mesh.hxx"
 #include "SMESHDS_SubMesh.hxx"
+#include "SMESH_Comment.hxx"
+#include "SMESH_Gen.hxx"
+#include "SMESH_HypoFilter.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_TypeDefs.hxx"
+
+#include <Basics_OCCTVersion.hxx>
 
 #include <BRepAdaptor_Curve.hxx>
 #include <BRepLProp.hxx>
@@ -61,6 +66,7 @@
 #include "utilities.h"
 
 #include <algorithm>
+#include <limits>
 
 using namespace std;
 
@@ -75,8 +81,8 @@ SMESH_Algo::SMESH_Algo (int hypId, int studyId, SMESH_Gen * gen)
 {
   gen->_mapAlgo[hypId] = this;
 
-  _onlyUnaryInput = _requireDescretBoundary = _requireShape = true;
-  _quadraticMesh = false;
+  _onlyUnaryInput = _requireDiscreteBoundary = _requireShape = true;
+  _quadraticMesh = _supportSubmeshes = false;
   _error = COMPERR_OK;
 }
 
@@ -170,11 +176,42 @@ double SMESH_Algo::EdgeLength(const TopoDS_Edge & E)
     return 0;
   TopLoc_Location L;
   Handle(Geom_Curve) C = BRep_Tool::Curve(E, L, UMin, UMax);
-  GeomAdaptor_Curve AdaptCurve(C);
+  GeomAdaptor_Curve AdaptCurve(C, UMin, UMax); //range is important for periodic curves
   double length = GCPnts_AbscissaPoint::Length(AdaptCurve, UMin, UMax);
   return length;
 }
 
+//================================================================================
+/*!
+ * \brief Calculate normal of a mesh face
+ */
+//================================================================================
+
+bool SMESH_Algo::FaceNormal(const SMDS_MeshElement* F, gp_XYZ& normal, bool normalized)
+{
+  if ( !F || F->GetType() != SMDSAbs_Face )
+    return false;
+
+  normal.SetCoord(0,0,0);
+  int nbNodes = F->IsQuadratic() ? F->NbNodes()/2 : F->NbNodes();
+  for ( int i = 0; i < nbNodes-2; ++i )
+  {
+    gp_XYZ p[3];
+    for ( int n = 0; n < 3; ++n )
+    {
+      const SMDS_MeshNode* node = F->GetNode( i + n );
+      p[n].SetCoord( node->X(), node->Y(), node->Z() );
+    }
+    normal += ( p[2] - p[1] ) ^ ( p[0] - p[1] );
+  }
+  double size2 = normal.SquareModulus();
+  bool ok = ( size2 > numeric_limits<double>::min() * numeric_limits<double>::min());
+  if ( normalized && ok )
+    normal /= sqrt( size2 );
+
+  return ok;
+}
+
 //================================================================================
 /*!
  * \brief Find out elements orientation on a geometrical face
@@ -223,10 +260,10 @@ bool SMESH_Algo::IsReversedSubMesh (const TopoDS_Face&  theFace,
         const SMDS_PositionPtr& pos = node->GetPosition();
         if ( !pos ) continue;
         if ( pos->GetTypeOfPosition() == SMDS_TOP_FACE ) {
-          fPos = dynamic_cast< const SMDS_FacePosition* >( pos.get() );
+          fPos = dynamic_cast< const SMDS_FacePosition* >( pos );
         }
         else if ( pos->GetTypeOfPosition() == SMDS_TOP_VERTEX ) {
-          vID = pos->GetShapeId();
+          vID = node->getshapeId();
         }
       }
       if ( fPos || ( !normalOK && vID )) {
@@ -321,7 +358,7 @@ bool SMESH_Algo::GetNodeParamOnEdge(const SMESHDS_Mesh* theMesh,
   if ( !eSubMesh || !eSubMesh->GetElements()->more() )
     return false; // edge is not meshed
 
-  int nbEdgeNodes = 0;
+  //int nbEdgeNodes = 0;
   set < double > paramSet;
   if ( eSubMesh )
   {
@@ -334,17 +371,19 @@ bool SMESH_Algo::GetNodeParamOnEdge(const SMESHDS_Mesh* theMesh,
       if ( pos->GetTypeOfPosition() != SMDS_TOP_EDGE )
         return false;
       const SMDS_EdgePosition* epos =
-        static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
-      paramSet.insert( epos->GetUParameter() );
-      ++nbEdgeNodes;
+        static_cast<const SMDS_EdgePosition*>(node->GetPosition());
+      if ( !paramSet.insert( epos->GetUParameter() ).second )
+        return false; // equal parameters
     }
   }
   // add vertex nodes params
-  Standard_Real f, l;
-  BRep_Tool::Range(theEdge, f, l);
-  paramSet.insert( f );
-  paramSet.insert( l );
-  if ( paramSet.size() != nbEdgeNodes + 2 )
+  TopoDS_Vertex V1,V2;
+  TopExp::Vertices( theEdge, V1, V2);
+  if ( VertexNode( V1, theMesh ) &&
+       !paramSet.insert( BRep_Tool::Parameter(V1,theEdge) ).second )
+    return false; // there are equal parameters
+  if ( VertexNode( V2, theMesh ) &&
+       !paramSet.insert( BRep_Tool::Parameter(V2,theEdge) ).second )
     return false; // there are equal parameters
 
   // fill the vector
@@ -399,8 +438,9 @@ bool SMESH_Algo::GetSortedNodesOnEdge(const SMESHDS_Mesh*                   theM
       if ( pos->GetTypeOfPosition() != SMDS_TOP_EDGE )
         return false;
       const SMDS_EdgePosition* epos =
-        static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
-      theNodes.insert( make_pair( epos->GetUParameter(), node ));
+        static_cast<const SMDS_EdgePosition*>(node->GetPosition());
+      theNodes.insert( theNodes.end(), make_pair( epos->GetUParameter(), node ));
+      //MESSAGE("U " << epos->GetUParameter() << " ID " << node->GetID());
       ++nbNodes;
     }
   }
@@ -409,6 +449,7 @@ bool SMESH_Algo::GetSortedNodesOnEdge(const SMESHDS_Mesh*                   theM
   TopExp::Vertices(theEdge, v1, v2);
   const SMDS_MeshNode* n1 = VertexNode( v1, (SMESHDS_Mesh*) theMesh );
   const SMDS_MeshNode* n2 = VertexNode( v2, (SMESHDS_Mesh*) theMesh );
+  //MESSAGE("Vertices ID " << n1->GetID() << " " << n2->GetID());
   Standard_Real f, l;
   BRep_Tool::Range(theEdge, f, l);
   if ( v1.Orientation() != TopAbs_FORWARD )
@@ -455,20 +496,31 @@ bool SMESH_Algo::InitCompatibleHypoFilter( SMESH_HypoFilter & theFilter,
  */
 //================================================================================
 
-GeomAbs_Shape SMESH_Algo::Continuity(const TopoDS_Edge & E1,
-                                     const TopoDS_Edge & E2)
+GeomAbs_Shape SMESH_Algo::Continuity(TopoDS_Edge E1,
+                                     TopoDS_Edge E2)
 {
-  TopoDS_Vertex V = TopExp::LastVertex (E1, true);
-  if ( !V.IsSame( TopExp::FirstVertex(E2, true )))
-    if ( !TopExp::CommonVertex( E1, E2, V ))
-      return GeomAbs_C0;
+  //E1.Orientation(TopAbs_FORWARD), E2.Orientation(TopAbs_FORWARD); // avoid pb with internal edges
+  if (E1.Orientation() > TopAbs_REVERSED) // INTERNAL
+    E1.Orientation( TopAbs_FORWARD );
+  if (E2.Orientation() > TopAbs_REVERSED) // INTERNAL
+    E2.Orientation( TopAbs_FORWARD );
+
+  TopoDS_Vertex V, VV1[2], VV2[2];
+  TopExp::Vertices( E1, VV1[0], VV1[1], true );
+  TopExp::Vertices( E2, VV2[0], VV2[1], true );
+  if      ( VV1[1].IsSame( VV2[0] ))  { V = VV1[1]; }
+  else if ( VV1[0].IsSame( VV2[1] ))  { V = VV1[0]; }
+  else if ( VV1[1].IsSame( VV2[1] ))  { V = VV1[1]; E1.Reverse(); }
+  else if ( VV1[0].IsSame( VV2[0] ))  { V = VV1[0]; E1.Reverse(); }
+  else { return GeomAbs_C0; }
+
   Standard_Real u1 = BRep_Tool::Parameter( V, E1 );
   Standard_Real u2 = BRep_Tool::Parameter( V, E2 );
   BRepAdaptor_Curve C1( E1 ), C2( E2 );
   Standard_Real tol = BRep_Tool::Tolerance( V );
   Standard_Real angTol = 2e-3;
   try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
+#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
 #endif
     return BRepLProp::Continuity(C1, C2, u1, u2, tol, angTol);
@@ -488,7 +540,7 @@ GeomAbs_Shape SMESH_Algo::Continuity(const TopoDS_Edge & E1,
 //================================================================================
 
 const SMDS_MeshNode* SMESH_Algo::VertexNode(const TopoDS_Vertex& V,
-                                            SMESHDS_Mesh*        meshDS)
+                                            const SMESHDS_Mesh*  meshDS)
 {
   if ( SMESHDS_SubMesh* sm = meshDS->MeshElements(V) ) {
     SMDS_NodeIteratorPtr nIt= sm->GetNodes();
@@ -498,6 +550,103 @@ const SMDS_MeshNode* SMESH_Algo::VertexNode(const TopoDS_Vertex& V,
   return 0;
 }
 
+//=======================================================================
+//function : GetCommonNodes
+//purpose  : Return nodes common to two elements
+//=======================================================================
+
+vector< const SMDS_MeshNode*> SMESH_Algo::GetCommonNodes(const SMDS_MeshElement* e1,
+                                                         const SMDS_MeshElement* e2)
+{
+  vector< const SMDS_MeshNode*> common;
+  for ( int i = 0 ; i < e1->NbNodes(); ++i )
+    if ( e2->GetNodeIndex( e1->GetNode( i )) >= 0 )
+      common.push_back( e1->GetNode( i ));
+  return common;
+}
+
+//=======================================================================
+//function : GetMeshError
+//purpose  : Finds topological errors of a sub-mesh
+//WARNING  : 1D check is NOT implemented so far
+//=======================================================================
+
+SMESH_Algo::EMeshError SMESH_Algo::GetMeshError(SMESH_subMesh* subMesh)
+{
+  EMeshError err = MEr_OK;
+
+  SMESHDS_SubMesh* smDS = subMesh->GetSubMeshDS();
+  if ( !smDS )
+    return MEr_EMPTY;
+
+  switch ( subMesh->GetSubShape().ShapeType() )
+  {
+  case TopAbs_FACE: { // ====================== 2D =====================
+
+    SMDS_ElemIteratorPtr fIt = smDS->GetElements();
+    if ( !fIt->more() )
+      return MEr_EMPTY;
+
+    // We check that olny links on EDGEs encouter once, the rest links, twice
+    set< SMESH_TLink > links;
+    while ( fIt->more() )
+    {
+      const SMDS_MeshElement* f = fIt->next();
+      int nbNodes = f->NbCornerNodes(); // ignore medium nodes
+      for ( int i = 0; i < nbNodes; ++i )
+      {
+        const SMDS_MeshNode* n1 = f->GetNode( i );
+        const SMDS_MeshNode* n2 = f->GetNode(( i+1 ) % nbNodes);
+        std::pair< set< SMESH_TLink >::iterator, bool > it_added =
+          links.insert( SMESH_TLink( n1, n2 ));
+        if ( !it_added.second )
+          // As we do NOT(!) check if mesh is manifold, we believe that a link can
+          // encounter once or twice only (not three times), we erase a link as soon
+          // as it encounters twice to speed up search in the <links> map.
+          links.erase( it_added.first );
+      }
+    }
+    // the links remaining in the <links> should all be on EDGE
+    set< SMESH_TLink >::iterator linkIt = links.begin();
+    for ( ; linkIt != links.end(); ++linkIt )
+    {
+      const SMESH_TLink& link = *linkIt;
+      if ( link.node1()->GetPosition()->GetTypeOfPosition() > SMDS_TOP_EDGE ||
+           link.node2()->GetPosition()->GetTypeOfPosition() > SMDS_TOP_EDGE )
+        return MEr_HOLES;
+    }
+    // TODO: to check orientation
+    break;
+  }
+  case TopAbs_SOLID: { // ====================== 3D =====================
+
+    SMDS_ElemIteratorPtr vIt = smDS->GetElements();
+    if ( !vIt->more() )
+      return MEr_EMPTY;
+
+    SMDS_VolumeTool vTool;
+    while ( !vIt->more() )
+    {
+      if (!vTool.Set( vIt->next() ))
+        continue; // strange
+
+      for ( int iF = 0; iF < vTool.NbFaces(); ++iF )
+        if ( vTool.IsFreeFace( iF ))
+        {
+          int nbN = vTool.NbFaceNodes( iF );
+          const SMDS_MeshNode** nodes =  vTool.GetFaceNodes( iF );
+          for ( int i = 0; i < nbN; ++i )
+            if ( nodes[i]->GetPosition()->GetTypeOfPosition() > SMDS_TOP_FACE )
+              return MEr_HOLES;
+        }
+    }
+    break;
+  }
+  default:;
+  }
+  return err;
+}
+
 //================================================================================
 /*!
  * \brief Sets event listener to submeshes if necessary
@@ -539,6 +688,18 @@ bool SMESH_Algo::Compute(SMESH_Mesh & /*aMesh*/, SMESH_MesherHelper* /*aHelper*/
   return error( COMPERR_BAD_INPUT_MESH, "Mesh built on shape expected");
 }
 
+//=======================================================================
+//function : CancelCompute
+//purpose  : Sets _computeCanceled to true. It's usage depends on
+//  *        implementation of a particular mesher.
+//=======================================================================
+
+void SMESH_Algo::CancelCompute()
+{
+  _computeCanceled = true;
+  _error = COMPERR_CANCELED;
+}
+
 //================================================================================
 /*!
  * \brief store error and comment and then return ( error == COMPERR_OK )
@@ -599,6 +760,8 @@ void SMESH_Algo::InitComputeError()
     if ( (*elem)->GetID() < 1 )
       delete *elem;
   _badInputElements.clear();
+
+  _computeCanceled = false;
 }
 
 //================================================================================
index 4b681dc0a75a4d6e6e1ace83812c6b87a160a2be..580445b48057b0cc1c100d6ef30f66ce65cbdde0 100644 (file)
@@ -1,30 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : SMESH_Algo.hxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
 //
-
 #ifndef _SMESH_ALGO_HXX_
 #define _SMESH_ALGO_HXX_
 
@@ -53,8 +53,20 @@ class SMESHDS_Mesh;
 class SMDS_MeshNode;
 class SMESH_subMesh;
 class SMESH_MesherHelper;
-
-
+class gp_XYZ;
+
+typedef std::map< SMESH_subMesh*, std::vector<int> >           MapShapeNbElems;
+typedef std::map< SMESH_subMesh*, std::vector<int> >::iterator MapShapeNbElemsItr;
+
+/*!
+ * \brief Root of all algorithms
+ *
+ *  Methods of the class are grouped into several parts:
+ *  - main lifecycle methods, like Compute()
+ *  - methods describing features of the algorithm, like NeedShape()
+ *  - methods related to dependencies between sub-meshes imposed by the algorith
+ *  - static utilities, like EdgeLength()
+ */
 class SMESH_EXPORT SMESH_Algo:public SMESH_Hypothesis
 {
 public:
@@ -74,14 +86,14 @@ public:
   /*!
    * \brief Saves nothing in a stream
     * \param save - the stream
-    * \retval virtual std::ostream & - the stream
+    * \retval std::ostream & - the stream
    */
   virtual std::ostream & SaveTo(std::ostream & save);
 
   /*!
    * \brief Loads nothing from a stream
     * \param load - the stream
-    * \retval virtual std::ostream & - the stream
+    * \retval std::ostream & - the stream
    */
   virtual std::istream & LoadFrom(std::istream & load);
 
@@ -106,9 +118,9 @@ public:
     * \param aShape - the shape
     * \retval bool - is a success
     *
-    * Algorithms that !NeedDescretBoundary() || !OnlyUnaryInput() are
+    * Algorithms that !NeedDiscreteBoundary() || !OnlyUnaryInput() are
     * to set SMESH_ComputeError returned by SMESH_submesh::GetComputeError()
-    * to report problematic subshapes
+    * to report problematic sub-shapes
    */
   virtual bool Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) = 0;
 
@@ -122,6 +134,22 @@ public:
    */
   virtual bool Compute(SMESH_Mesh & aMesh, SMESH_MesherHelper* aHelper);
 
+  /*!
+   * \brief Sets _computeCanceled to true. It's usage depends on
+   *        implementation of a particular mesher.
+   */
+  virtual void CancelCompute();
+
+  /*!
+   * \brief evaluates size of prospective mesh on a shape
+    * \param aMesh - the mesh
+    * \param aShape - the shape
+    * \param aNbElems - prospective number of elements by types
+    * \retval bool - is a success
+   */
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap) = 0;
+
   /*!
    * \brief Returns a list of compatible hypotheses used to mesh a shape
     * \param aMesh - the mesh 
@@ -193,14 +221,14 @@ public:
   // an input temporary shape that is neither MainShape nor
   // its child.
 
-  bool NeedDescretBoundary() const { return _requireDescretBoundary; }
+  bool NeedDiscreteBoundary() const { return _requireDiscreteBoundary; }
   // 3 - is a Dim-1 mesh prerequisite
 
   bool NeedShape() const { return _requireShape; }
   // 4 - is shape existance required
 
   bool SupportSubmeshes() const { return _supportSubmeshes; }
-  // 5 - whether supports submeshes if !NeedDescretBoundary()
+  // 5 - whether supports submeshes if !NeedDiscreteBoundary()
 
 
 public:
@@ -214,7 +242,7 @@ public:
    *
    * This method is called when a submesh gets HYP_OK algo_state.
    * After being set, event listener is notified on each event of a submesh.
-   * By default non listener is set
+   * By default none listener is set
    */
   virtual void SetEventListener(SMESH_subMesh* subMesh);
   
@@ -268,13 +296,18 @@ public:
    */
   static double EdgeLength(const TopoDS_Edge & E);
 
+  /*!
+   * \brief Calculate normal of a mesh face
+   */
+  static bool FaceNormal(const SMDS_MeshElement* F, gp_XYZ& normal, bool normalized=true);
+
   /*!
    * \brief Return continuity of two edges
     * \param E1 - the 1st edge
     * \param E2 - the 2nd edge
     * \retval GeomAbs_Shape - regularity at the junction between E1 and E2
    */
-  static GeomAbs_Shape Continuity(const TopoDS_Edge & E1, const TopoDS_Edge & E2);
+  static GeomAbs_Shape Continuity(TopoDS_Edge E1, TopoDS_Edge E2);
 
   /*!
    * \brief Return true if an edge can be considered as a continuation of another
@@ -289,10 +322,22 @@ public:
     * \param meshDS - mesh
     * \retval const SMDS_MeshNode* - found node or NULL
    */
-  static const SMDS_MeshNode* VertexNode(const TopoDS_Vertex& V,
-                                         SMESHDS_Mesh*        meshDS);
+  static const SMDS_MeshNode* VertexNode(const TopoDS_Vertex& V, const SMESHDS_Mesh* meshDS);
 
-protected:
+  /*!
+   * \brief Return nodes common to two elements
+   */
+  static std::vector< const SMDS_MeshNode*> GetCommonNodes(const SMDS_MeshElement* e1,
+                                                           const SMDS_MeshElement* e2);
+
+  enum EMeshError { MEr_OK = 0, MEr_HOLES, MEr_BAD_ORI, MEr_EMPTY };
+
+  /*!
+   * \brief Finds topological errors of a sub-mesh 
+   */
+  static EMeshError GetMeshError(SMESH_subMesh* subMesh);
+
+ protected:
 
   /*!
    * \brief store error and comment and then return ( error == COMPERR_OK )
@@ -322,11 +367,11 @@ protected:
 
   // Algo features influencing which Compute() and how is called:
   // in what turn and with what input shape.
-  // This fields must be redefined if necessary by each descendant at constructor.
+  // These fields must be redefined if necessary by each descendant at constructor.
   bool _onlyUnaryInput;         // mesh one shape of GetDim() at once. Default TRUE
-  bool _requireDescretBoundary; // GetDim()-1 mesh must be present. Default TRUE
+  bool _requireDiscreteBoundary; // GetDim()-1 mesh must be present. Default TRUE
   bool _requireShape;           // work with GetDim()-1 mesh bound to geom only. Default TRUE
-  bool _supportSubmeshes;       // if !_requireDescretBoundary. Default FALSE
+  bool _supportSubmeshes;       // if !_requireDiscreteBoundary. Default FALSE
 
   // quadratic mesh creation required,
   // is usually set trough SMESH_MesherHelper::IsQuadraticSubMesh()
@@ -335,6 +380,8 @@ protected:
   int         _error;    //!< SMESH_ComputeErrorName or anything algo specific
   std::string _comment;  //!< any text explaining what is wrong in Compute()
   std::list<const SMDS_MeshElement*> _badInputElements; //!< to explain COMPERR_BAD_INPUT_MESH
+
+  volatile bool _computeCanceled; //!< is set to True while computing to stop it
 };
 
 #endif
diff --git a/src/SMESH/SMESH_Block.cxx b/src/SMESH/SMESH_Block.cxx
deleted file mode 100644 (file)
index 0fd4996..0000000
+++ /dev/null
@@ -1,1710 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-// File      : SMESH_Pattern.hxx
-// Created   : Mon Aug  2 10:30:00 2004
-// Author    : Edward AGAPOV (eap)
-//
-#include "SMESH_Block.hxx"
-
-#include <BRepAdaptor_Curve.hxx>
-#include <BRepAdaptor_Curve2d.hxx>
-#include <BRepAdaptor_Surface.hxx>
-#include <BRepTools.hxx>
-#include <BRepTools_WireExplorer.hxx>
-#include <BRep_Builder.hxx>
-#include <BRep_Tool.hxx>
-#include <Bnd_Box.hxx>
-#include <Extrema_ExtPC.hxx>
-#include <Extrema_POnCurv.hxx>
-#include <Geom2d_Curve.hxx>
-#include <TopExp_Explorer.hxx>
-#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
-#include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <TopTools_ListOfShape.hxx>
-#include <TopoDS.hxx>
-#include <TopoDS_Compound.hxx>
-#include <TopoDS_Face.hxx>
-#include <TopoDS_Iterator.hxx>
-#include <TopoDS_Wire.hxx>
-#include <gp_Trsf.hxx>
-#include <gp_Vec.hxx>
-#include <math_FunctionSetRoot.hxx>
-#include <math_Matrix.hxx>
-#include <math_Vector.hxx>
-
-#include "SMDS_MeshNode.hxx"
-#include "SMDS_MeshVolume.hxx"
-#include "SMDS_VolumeTool.hxx"
-#include "utilities.h"
-
-#include <list>
-
-using namespace std;
-
-//#define DEBUG_PARAM_COMPUTE
-
-//================================================================================
-/*!
- * \brief Set edge data
-  * \param edgeID - block subshape ID
-  * \param curve - edge geometry
-  * \param isForward - is curve orientation coincides with edge orientation in the block
- */
-//================================================================================
-
-void SMESH_Block::TEdge::Set( const int edgeID, Adaptor3d_Curve* curve, const bool isForward )
-{
-  myCoordInd = SMESH_Block::GetCoordIndOnEdge( edgeID );
-  if ( myC3d ) delete myC3d;
-  myC3d = curve;
-  myFirst = curve->FirstParameter();
-  myLast = curve->LastParameter();
-  if ( !isForward )
-    std::swap( myFirst, myLast );
-}
-
-//================================================================================
-/*!
- * \brief Set coordinates of nodes at edge ends to work with mesh block
-  * \param edgeID - block subshape ID
-  * \param node1 - coordinates of node with lower ID
-  * \param node2 - coordinates of node with upper ID
- */
-//================================================================================
-
-void SMESH_Block::TEdge::Set( const int edgeID, const gp_XYZ& node1, const gp_XYZ& node2 )
-{
-  myCoordInd = SMESH_Block::GetCoordIndOnEdge( edgeID );
-  myNodes[ 0 ] = node1;
-  myNodes[ 1 ] = node2;
-
-  if ( myC3d ) delete myC3d;
-  myC3d = 0;
-}
-
-//=======================================================================
-//function : SMESH_Block::TEdge::GetU
-//purpose  : 
-//=======================================================================
-
-double SMESH_Block::TEdge::GetU( const gp_XYZ& theParams ) const
-{
-  double u = theParams.Coord( myCoordInd );
-  if ( !myC3d ) // if mesh block
-    return u;
-  return ( 1 - u ) * myFirst + u * myLast;
-}
-
-//=======================================================================
-//function : SMESH_Block::TEdge::Point
-//purpose  : 
-//=======================================================================
-
-gp_XYZ SMESH_Block::TEdge::Point( const gp_XYZ& theParams ) const
-{
-  double u = GetU( theParams );
-  if ( myC3d ) return myC3d->Value( u ).XYZ();
-  // mesh block
-  return myNodes[0] * ( 1 - u ) + myNodes[1] * u;
-}
-
-//================================================================================
-/*!
- * \brief Destructor
- */
-//================================================================================
-
-SMESH_Block::TEdge::~TEdge()
-{
-  if ( myC3d ) delete myC3d;
-}
-
-//================================================================================
-/*!
- * \brief Set face data
-  * \param faceID - block subshape ID
-  * \param S - face surface geometry
-  * \param c2d - 4 pcurves in the order as returned by GetFaceEdgesIDs(faceID)
-  * \param isForward - orientation of pcurves comparing with block edge direction
- */
-//================================================================================
-
-void SMESH_Block::TFace::Set( const int          faceID,
-                              Adaptor3d_Surface* S,
-                              Adaptor2d_Curve2d* c2D[4],
-                              const bool         isForward[4] )
-{
-  if ( myS ) delete myS;
-  myS = S;
-  // pcurves
-  vector< int > edgeIdVec;
-  GetFaceEdgesIDs( faceID, edgeIdVec );
-  for ( int iE = 0; iE < edgeIdVec.size(); iE++ ) // loop on 4 edges
-  {
-    myCoordInd[ iE ] = GetCoordIndOnEdge( edgeIdVec[ iE ] );
-    if ( myC2d[ iE ]) delete myC2d[ iE ];
-    myC2d[ iE ] = c2D[ iE ];
-    myFirst[ iE ] = myC2d[ iE ]->FirstParameter();
-    myLast [ iE ] = myC2d[ iE ]->LastParameter();
-    if ( !isForward[ iE ])
-      std::swap( myFirst[ iE ], myLast[ iE ] );
-  }
-  // 2d corners
-  myCorner[ 0 ] = myC2d[ 0 ]->Value( myFirst[0] ).XY();
-  myCorner[ 1 ] = myC2d[ 0 ]->Value( myLast[0] ).XY();
-  myCorner[ 2 ] = myC2d[ 1 ]->Value( myLast[1] ).XY();
-  myCorner[ 3 ] = myC2d[ 1 ]->Value( myFirst[1] ).XY();
-}
-
-//================================================================================
-/*!
- * \brief Set face data to work with mesh block
-  * \param faceID - block subshape ID
-  * \param edgeU0 - filled data of edge u0 = GetFaceEdgesIDs(faceID)[ 0 ]
-  * \param edgeU1 - filled data of edge u1 = GetFaceEdgesIDs(faceID)[ 1 ]
- */
-//================================================================================
-
-void SMESH_Block::TFace::Set( const int faceID, const TEdge& edgeU0, const TEdge& edgeU1 )
-{
-  vector< int > edgeIdVec;
-  GetFaceEdgesIDs( faceID, edgeIdVec );
-  myNodes[ 0 ] = edgeU0.NodeXYZ( 1 );
-  myNodes[ 1 ] = edgeU0.NodeXYZ( 0 );
-  myNodes[ 2 ] = edgeU1.NodeXYZ( 0 );
-  myNodes[ 3 ] = edgeU1.NodeXYZ( 1 );
-  myCoordInd[ 0 ] = GetCoordIndOnEdge( edgeIdVec[ 0 ] );
-  myCoordInd[ 1 ] = GetCoordIndOnEdge( edgeIdVec[ 1 ] );
-  myCoordInd[ 2 ] = GetCoordIndOnEdge( edgeIdVec[ 2 ] );
-  myCoordInd[ 3 ] = GetCoordIndOnEdge( edgeIdVec[ 3 ] );
-  if ( myS ) delete myS;
-  myS = 0;
-}
-
-//================================================================================
-/*!
- * \brief Destructor
- */
-//================================================================================
-
-SMESH_Block::TFace::~TFace()
-{
-  if ( myS ) delete myS;
-  for ( int i = 0 ; i < 4; ++i )
-    if ( myC2d[ i ]) delete myC2d[ i ];
-}
-
-//=======================================================================
-//function : SMESH_Block::TFace::GetCoefs
-//purpose  : return coefficients for addition of [0-3]-th edge and vertex
-//=======================================================================
-
-void SMESH_Block::TFace::GetCoefs(int           iE,
-                                  const gp_XYZ& theParams,
-                                  double&       Ecoef,
-                                  double&       Vcoef ) const
-{
-  double dU = theParams.Coord( GetUInd() );
-  double dV = theParams.Coord( GetVInd() );
-  switch ( iE ) {
-  case 0:
-    Ecoef = ( 1 - dV ); // u0
-    Vcoef = ( 1 - dU ) * ( 1 - dV ); break; // 00
-  case 1:
-    Ecoef = dV; // u1
-    Vcoef = dU * ( 1 - dV ); break; // 10
-  case 2:
-    Ecoef = ( 1 - dU ); // 0v
-    Vcoef = dU * dV  ; break; // 11
-  case 3:
-    Ecoef = dU  ; // 1v
-    Vcoef = ( 1 - dU ) * dV  ; break; // 01
-  default: ASSERT(0);
-  }
-}
-
-//=======================================================================
-//function : SMESH_Block::TFace::GetUV
-//purpose  : 
-//=======================================================================
-
-gp_XY SMESH_Block::TFace::GetUV( const gp_XYZ& theParams ) const
-{
-  gp_XY uv(0.,0.);
-  for ( int iE = 0; iE < 4; iE++ ) // loop on 4 edges
-  {
-    double Ecoef = 0, Vcoef = 0;
-    GetCoefs( iE, theParams, Ecoef, Vcoef );
-    // edge addition
-    double u = theParams.Coord( myCoordInd[ iE ] );
-    u = ( 1 - u ) * myFirst[ iE ] + u * myLast[ iE ];
-    uv += Ecoef * myC2d[ iE ]->Value( u ).XY();
-    // corner addition
-    uv -= Vcoef * myCorner[ iE ];
-  }
-  return uv;
-}
-
-//=======================================================================
-//function : SMESH_Block::TFace::Point
-//purpose  : 
-//=======================================================================
-
-gp_XYZ SMESH_Block::TFace::Point( const gp_XYZ& theParams ) const
-{
-  gp_XYZ p(0.,0.,0.);
-  if ( !myS ) // if mesh block
-  {
-    for ( int iE = 0; iE < 4; iE++ ) // loop on 4 edges
-    {
-      double Ecoef = 0, Vcoef = 0;
-      GetCoefs( iE, theParams, Ecoef, Vcoef );
-      // edge addition
-      double u = theParams.Coord( myCoordInd[ iE ] );
-      int i1 = 0, i2 = 1;
-      switch ( iE ) {
-      case 1: i1 = 3; i2 = 2; break;
-      case 2: i1 = 1; i2 = 2; break;
-      case 3: i1 = 0; i2 = 3; break;
-      }
-      p += Ecoef * ( myNodes[ i1 ] * ( 1 - u ) + myNodes[ i2 ] * u );
-      // corner addition
-      p -= Vcoef * myNodes[ iE ];
-    }
-    
-  }
-  else // shape block
-  {
-    gp_XY uv = GetUV( theParams );
-    p = myS->Value( uv.X(), uv.Y() ).XYZ();
-  }
-  return p;
-}
-
-//=======================================================================
-//function : GetShapeCoef
-//purpose  : 
-//=======================================================================
-
-double* SMESH_Block::GetShapeCoef (const int theShapeID)
-{
-  static double shapeCoef[][3] = {
-    //    V000,        V100,        V010,         V110
-    { -1,-1,-1 }, {  1,-1,-1 }, { -1, 1,-1 }, {  1, 1,-1 },
-    //    V001,        V101,        V011,         V111,
-    { -1,-1, 1 }, {  1,-1, 1 }, { -1, 1, 1 }, {  1, 1, 1 },
-    //    Ex00,        Ex10,        Ex01,         Ex11,
-    {  0,-1,-1 }, {  0, 1,-1 }, {  0,-1, 1 }, {  0, 1, 1 },
-    //    E0y0,        E1y0,        E0y1,         E1y1,
-    { -1, 0,-1 }, {  1, 0,-1 }, { -1, 0, 1 }, {  1, 0, 1 },
-    //    E00z,        E10z,        E01z,         E11z,
-    { -1,-1, 0 }, {  1,-1, 0 }, { -1, 1, 0 }, {  1, 1, 0 },
-    //    Fxy0,        Fxy1,        Fx0z,         Fx1z,         F0yz,           F1yz,
-    {  0, 0,-1 }, {  0, 0, 1 }, {  0,-1, 0 }, {  0, 1, 0 }, { -1, 0, 0 }, {  1, 0, 0 },
-    // ID_Shell
-    {  0, 0, 0 }
-  };
-  if ( theShapeID < ID_V000 || theShapeID > ID_F1yz )
-    return shapeCoef[ ID_Shell - 1 ];
-
-  return shapeCoef[ theShapeID - 1 ];
-}
-
-//=======================================================================
-//function : ShellPoint
-//purpose  : return coordinates of a point in shell
-//=======================================================================
-
-bool SMESH_Block::ShellPoint( const gp_XYZ& theParams, gp_XYZ& thePoint ) const
-{
-  thePoint.SetCoord( 0., 0., 0. );
-  for ( int shapeID = ID_V000; shapeID < ID_Shell; shapeID++ )
-  {
-    // coef
-    double* coefs = GetShapeCoef( shapeID );
-    double k = 1;
-    for ( int iCoef = 0; iCoef < 3; iCoef++ ) {
-      if ( coefs[ iCoef ] != 0 ) {
-        if ( coefs[ iCoef ] < 0 )
-          k *= ( 1. - theParams.Coord( iCoef + 1 ));
-        else
-          k *= theParams.Coord( iCoef + 1 );
-      }
-    }
-    // add point on a shape
-    if ( fabs( k ) > DBL_MIN )
-    {
-      gp_XYZ Ps;
-      if ( shapeID < ID_Ex00 ) // vertex
-        VertexPoint( shapeID, Ps );
-      else if ( shapeID < ID_Fxy0 ) { // edge
-        EdgePoint( shapeID, theParams, Ps );
-        k = -k;
-      } else // face
-        FacePoint( shapeID, theParams, Ps );
-
-      thePoint += k * Ps;
-    }
-  }
-  return true;
-}
-
-//=======================================================================
-//function : ShellPoint
-//purpose  : computes coordinates of a point in shell by points on sub-shapes;
-//           thePointOnShape[ subShapeID ] must be a point on a subShape
-//=======================================================================
-
-bool SMESH_Block::ShellPoint(const gp_XYZ&         theParams,
-                             const vector<gp_XYZ>& thePointOnShape,
-                             gp_XYZ&               thePoint )
-{
-  if ( thePointOnShape.size() < ID_F1yz )
-    return false;
-
-  double x = theParams.X(), y = theParams.Y(), z = theParams.Z();
-  double x1 = 1. - x,       y1 = 1. - y,       z1 = 1. - z;
-  const vector<gp_XYZ>& p = thePointOnShape;
-
-  thePoint = 
-    x1 * p[ID_F0yz] + x * p[ID_F1yz] +
-    y1 * p[ID_Fx0z] + y * p[ID_Fx1z] +
-    z1 * p[ID_Fxy0] + z * p[ID_Fxy1] +
-    x1 * (y1 * (z1 * p[ID_V000] + z * p[ID_V001])  +
-          y  * (z1 * p[ID_V010] + z * p[ID_V011])) +
-    x  * (y1 * (z1 * p[ID_V100] + z * p[ID_V101])  +
-          y  * (z1 * p[ID_V110] + z * p[ID_V111]));
-  thePoint -=
-    x1 * (y1 * p[ID_E00z] + y * p[ID_E01z]) + 
-    x  * (y1 * p[ID_E10z] + y * p[ID_E11z]) + 
-    y1 * (z1 * p[ID_Ex00] + z * p[ID_Ex01]) + 
-    y  * (z1 * p[ID_Ex10] + z * p[ID_Ex11]) + 
-    z1 * (x1 * p[ID_E0y0] + x * p[ID_E1y0]) + 
-    z  * (x1 * p[ID_E0y1] + x * p[ID_E1y1]);
-
-  return true;
-}
-
-//=======================================================================
-//function : Constructor
-//purpose  : 
-//=======================================================================
-
-SMESH_Block::SMESH_Block():
-  myNbIterations(0),
-  mySumDist(0.),
-  myTolerance(-1.) // to be re-initialized
-{
-}
-
-
-//=======================================================================
-//function : NbVariables
-//purpose  : 
-//=======================================================================
-
-Standard_Integer SMESH_Block::NbVariables() const
-{
-  return 3;
-}
-
-//=======================================================================
-//function : NbEquations
-//purpose  : 
-//=======================================================================
-
-Standard_Integer SMESH_Block::NbEquations() const
-{
-  return 1;
-}
-
-//=======================================================================
-//function : Value
-//purpose  : 
-//=======================================================================
-
-Standard_Boolean SMESH_Block::Value(const math_Vector& theXYZ, math_Vector& theFxyz) 
-{
-  gp_XYZ P, params( theXYZ(1), theXYZ(2), theXYZ(3) );
-  if ( params.IsEqual( myParam, DBL_MIN )) { // same param
-    theFxyz( 1 ) = funcValue( myValues[ SQUARE_DIST ]);
-  }
-  else {
-    ShellPoint( params, P );
-    gp_Vec dP( P - myPoint );
-    theFxyz(1) = funcValue( dP.SquareMagnitude() );
-  }
-  return true;
-}
-
-//=======================================================================
-//function : Derivatives
-//purpose  : 
-//=======================================================================
-
-Standard_Boolean SMESH_Block::Derivatives(const math_Vector& XYZ,math_Matrix& Df) 
-{
-  math_Vector F(1,3);
-  return Values(XYZ,F,Df);
-}
-
-//=======================================================================
-//function : GetStateNumber
-//purpose  : 
-//=======================================================================
-
-Standard_Integer SMESH_Block::GetStateNumber ()
-{
-  return 0; //myValues[0] < 1e-1;
-}
-
-//=======================================================================
-//function : Values
-//purpose  : 
-//=======================================================================
-
-Standard_Boolean SMESH_Block::Values(const math_Vector& theXYZ,
-                                     math_Vector&       theFxyz,
-                                     math_Matrix&       theDf) 
-{
-  gp_XYZ P, params( theXYZ(1), theXYZ(2), theXYZ(3) );
-  if ( params.IsEqual( myParam, DBL_MIN )) { // same param
-    theFxyz( 1 )      = funcValue( myValues[ SQUARE_DIST ] );
-    theDf( 1, DRV_1 ) = myValues[ DRV_1 ];
-    theDf( 1, DRV_2 ) = myValues[ DRV_2 ];
-    theDf( 1, DRV_3 ) = myValues[ DRV_3 ];
-    return true;
-  }
-#ifdef DEBUG_PARAM_COMPUTE
-  MESSAGE ( "PARAM GUESS: " << params.X() << " "<< params.Y() << " "<< params.X() );
-  myNbIterations++; // how many times call ShellPoint()
-#endif
-  ShellPoint( params, P );
-
-  gp_Vec dP( myPoint, P );
-  double sqDist = dP.SquareMagnitude();
-  theFxyz(1) = funcValue( sqDist );
-
-  if ( sqDist < myTolerance * myTolerance ) { // a solution found
-    myParam = params;
-    myValues[ SQUARE_DIST ] = sqDist;
-    theFxyz(1)  = theDf( 1,1 ) = theDf( 1,2 ) = theDf( 1,3 ) = 0;
-    return true;
-  }
-
-  if ( sqDist < myValues[ SQUARE_DIST ] ) // a better guess
-  {
-    // 3 partial derivatives
-    gp_Vec drv[ 3 ]; // where we move with a small step in each direction
-    for ( int iP = 1; iP <= 3; iP++ ) {
-      if ( iP == myFaceIndex ) {
-        drv[ iP - 1 ] = gp_Vec(0,0,0);
-        continue;
-      }
-      gp_XYZ Pi;
-      bool onEdge = ( theXYZ( iP ) + 0.001 > 1. );
-      if ( onEdge )
-        params.SetCoord( iP, theXYZ( iP ) - 0.001 );
-      else
-        params.SetCoord( iP, theXYZ( iP ) + 0.001 );
-      ShellPoint( params, Pi );
-      params.SetCoord( iP, theXYZ( iP ) ); // restore params
-      gp_Vec dPi ( P, Pi );
-      if ( onEdge ) dPi *= -1.;
-      double mag = dPi.Magnitude();
-      if ( mag > DBL_MIN )
-        dPi /= mag;
-      drv[ iP - 1 ] = dPi;
-    }
-    for ( int iP = 0; iP < 3; iP++ ) {
-#if 1
-      theDf( 1, iP + 1 ) = dP * drv[iP];
-#else
-      // Distance from P to plane passing through myPoint and defined
-      // by the 2 other derivative directions:
-      // like IntAna_IntConicQuad::Perform (const gp_Lin& L, const gp_Pln& P)
-      // where L is (P -> myPoint), P is defined by the 2 other derivative direction
-      int iPrev = ( iP ? iP - 1 : 2 );
-      int iNext = ( iP == 2 ? 0 : iP + 1 );
-      gp_Vec plnNorm = drv[ iPrev ].Crossed( drv [ iNext ] );
-      double Direc = plnNorm * drv[ iP ];
-      if ( Abs(Direc) <= DBL_MIN )
-        theDf( 1, iP + 1 ) = dP * drv[ iP ];
-      else {
-        double Dis = plnNorm * P - plnNorm * myPoint;
-        theDf( 1, iP + 1 ) = Dis/Direc;
-      }
-#endif
-    }
-#ifdef DEBUG_PARAM_COMPUTE
-    MESSAGE ( "F = " << theFxyz(1) << " DRV: " << theDf(1,1) << " " << theDf(1,2) << " " << theDf(1,3) );
-    myNbIterations +=3; // how many times call ShellPoint()
-#endif
-
-    // store better values
-    myParam              = params;
-    myValues[SQUARE_DIST]= sqDist;
-    myValues[DRV_1]      = theDf(1,DRV_1);
-    myValues[DRV_2]      = theDf(1,DRV_2);
-    myValues[DRV_3]      = theDf(1,DRV_3);
-  }
-
-  return true;
-}
-
-//============================================================================
-//function : computeParameters
-//purpose  : compute point parameters in the block using math_FunctionSetRoot
-//============================================================================
-
-bool SMESH_Block::computeParameters(const gp_Pnt& thePoint,
-                                    gp_XYZ&       theParams,
-                                    const gp_XYZ& theParamsHint)
-{
-  myPoint = thePoint.XYZ();
-
-  myParam.SetCoord( -1,-1,-1 );
-  myValues[ SQUARE_DIST ] = 1e100;
-
-  math_Vector low  ( 1, 3, 0.0 );
-  math_Vector up   ( 1, 3, 1.0 );
-  math_Vector tol  ( 1, 3, 1e-4 );
-  math_Vector start( 1, 3, 0.0 );
-  start( 1 ) = theParamsHint.X();
-  start( 2 ) = theParamsHint.Y();
-  start( 3 ) = theParamsHint.Z();
-
-  math_FunctionSetRoot paramSearch( *this, tol );
-
-  mySquareFunc = 0; // large approaching steps
-  //if ( hasHint ) mySquareFunc = 1; // small approaching steps
-
-  double loopTol = 10 * myTolerance;
-  int nbLoops = 0;
-  while ( distance() > loopTol && nbLoops <= 3 )
-  {
-    paramSearch.Perform ( *static_cast<math_FunctionSetWithDerivatives*>(this),
-                          start, low, up );
-    start( 1 ) = myParam.X();
-    start( 2 ) = myParam.Y();
-    start( 3 ) = myParam.Z();
-    mySquareFunc = !mySquareFunc;
-    nbLoops++;
-  }
-#ifdef DEBUG_PARAM_COMPUTE
-  mySumDist += distance();
-  MESSAGE ( " ------ SOLUTION: ( "<< myParam.X() <<" "<< myParam.Y() <<" "<< myParam.Z() <<" )"<<endl
-         << " ------ DIST : " << distance() << "\t Tol=" << myTolerance << "\t Nb LOOPS=" << nbLoops << endl
-         << " ------ NB IT: " << myNbIterations << ",  SUM DIST: " << mySumDist );
-#endif
-
-  theParams = myParam;
-
-  if ( myFaceIndex > 0 )
-    theParams.SetCoord( myFaceIndex, myFaceParam );
-
-  return true;
-}
-
-//=======================================================================
-//function : ComputeParameters
-//purpose  : compute point parameters in the block
-//=======================================================================
-
-bool SMESH_Block::ComputeParameters(const gp_Pnt& thePoint,
-                                    gp_XYZ&       theParams,
-                                    const int     theShapeID,
-                                    const gp_XYZ& theParamsHint)
-{
-  if ( VertexParameters( theShapeID, theParams ))
-    return true;
-
-  if ( IsEdgeID( theShapeID )) {
-    TEdge& e = myEdge[ theShapeID - ID_FirstE ];
-    Adaptor3d_Curve* curve = e.GetCurve();
-    Extrema_ExtPC anExtPC( thePoint, *curve, curve->FirstParameter(), curve->LastParameter() );
-    int i, nb = anExtPC.IsDone() ? anExtPC.NbExt() : 0;
-    for ( i = 1; i <= nb; i++ ) {
-      if ( anExtPC.IsMin( i ))
-        return EdgeParameters( theShapeID, anExtPC.Point( i ).Parameter(), theParams );
-    }
-    return false;
-  }
-
-  const bool isOnFace = IsFaceID( theShapeID );
-  double * coef = GetShapeCoef( theShapeID );
-
-  // Find the first guess paremeters
-
-  gp_XYZ start(0, 0, 0);
-
-  bool hasHint = ( 0 <= theParamsHint.X() && theParamsHint.X() <= 1 &&
-                   0 <= theParamsHint.Y() && theParamsHint.Y() <= 1 &&
-                   0 <= theParamsHint.Y() && theParamsHint.Y() <= 1 );
-  if ( !hasHint && !myGridComputed )
-  {
-    // define the first guess by thePoint projection on lines
-    // connecting vertices
-    bool needGrid = false;
-    gp_XYZ par000( 0, 0, 0 ), par111( 1, 1, 1 );
-    double zero = DBL_MIN * DBL_MIN;
-    for ( int iEdge = 0, iParam = 1; iParam <= 3 && !needGrid; iParam++ )
-    {
-      if ( isOnFace && coef[ iParam - 1 ] != 0 ) {
-        iEdge += 4;
-        continue;
-      }
-      double sumParam = 0;
-      for ( int iE = 0; iE < 4; iE++, iEdge++ ) { // loop on 4 parallel edges
-        gp_Pnt p0 = myEdge[ iEdge ].Point( par000 );
-        gp_Pnt p1 = myEdge[ iEdge ].Point( par111 );
-        gp_Vec v01( p0, p1 ), v0P( p0, thePoint );
-        double len2 = v01.SquareMagnitude();
-        double par = 0;
-        if ( len2 > zero ) {
-          par = v0P.Dot( v01 ) / len2;
-          if ( par < 0 || par > 1 ) { // projection falls out of line ends => needGrid
-            needGrid = true;
-            break;
-          }
-        }
-        sumParam += par;
-      }
-      start.SetCoord( iParam, sumParam / 4.);
-    }
-    if ( needGrid ) {
-      // compute nodes of 3 x 3 x 3 grid
-      int iNode = 0;
-      Bnd_Box box;
-      for ( double x = 0.25; x < 0.9; x += 0.25 )
-        for ( double y = 0.25; y < 0.9; y += 0.25 )
-          for ( double z = 0.25; z < 0.9; z += 0.25 ) {
-            TxyzPair & prmPtn = my3x3x3GridNodes[ iNode++ ];
-            prmPtn.first.SetCoord( x, y, z );
-            ShellPoint( prmPtn.first, prmPtn.second );
-            box.Add( gp_Pnt( prmPtn.second ));
-          }
-      myGridComputed = true;
-      myTolerance = sqrt( box.SquareExtent() ) * 1e-5;
-    }
-  }
-
-  if ( hasHint )
-  {
-    start = theParamsHint;
-  }
-  else if ( myGridComputed )
-  {
-    double minDist = DBL_MAX;
-    gp_XYZ* bestParam = 0;
-    for ( int iNode = 0; iNode < 27; iNode++ ) {
-      TxyzPair & prmPtn = my3x3x3GridNodes[ iNode ];
-      double dist = ( thePoint.XYZ() - prmPtn.second ).SquareModulus();
-      if ( dist < minDist ) {
-        minDist = dist;
-        bestParam = & prmPtn.first;
-      }
-    }
-    start = *bestParam;
-  }
-
-  myFaceIndex = -1;
-  myFaceParam = 0.;
-  if ( isOnFace ) {
-    // put a point on the face
-    for ( int iCoord = 0; iCoord < 3; iCoord++ )
-      if ( coef[ iCoord ] ) {
-        myFaceIndex = iCoord + 1;
-        myFaceParam = ( coef[ iCoord ] < 0.5 ) ? 0.0 : 1.0;
-        start.SetCoord( myFaceIndex, myFaceParam );
-      }
-  }
-
-#ifdef DEBUG_PARAM_COMPUTE
-  MESSAGE ( " #### POINT " <<thePoint.X()<<" "<<thePoint.Y()<<" "<<thePoint.Z()<<" ####" );
-#endif
-
-  if ( myTolerance < 0 ) myTolerance = 1e-6;
-
-  const double parDelta = 1e-4;
-  const double sqTolerance = myTolerance * myTolerance;
-
-  gp_XYZ solution = start, params = start;
-  double sqDistance = 1e100; 
-  int nbLoops = 0, nbGetWorst = 0;
-
-  while ( nbLoops <= 100 )
-  {
-    gp_XYZ P, Pi;
-    ShellPoint( params, P );
-
-    gp_Vec dP( thePoint, P );
-    double sqDist = dP.SquareMagnitude();
-
-    if ( sqDist > sqDistance ) { // solution get worse
-      if ( ++nbGetWorst > 2 )
-        return computeParameters( thePoint, theParams, solution );
-    }
-#ifdef DEBUG_PARAM_COMPUTE
-    MESSAGE ( "PARAMS: ( " << params.X() <<" "<< params.Y() <<" "<< params.Z() <<" )" );
-    MESSAGE ( "DIST: " << sqrt( sqDist ) );
-#endif
-
-    if ( sqDist < sqDistance ) { // get better
-      sqDistance = sqDist;
-      solution   = params;
-      nbGetWorst = 0;
-      if ( sqDistance < sqTolerance ) // a solution found
-        break;
-    }
-
-        // look for a next better solution
-    for ( int iP = 1; iP <= 3; iP++ ) {
-      if ( iP == myFaceIndex )
-        continue;
-      // see where we move with a small (=parDelta) step in this direction
-      gp_XYZ nearParams = params;
-      bool onEdge = ( params.Coord( iP ) + parDelta > 1. );
-      if ( onEdge )
-        nearParams.SetCoord( iP, params.Coord( iP ) - parDelta );
-      else
-        nearParams.SetCoord( iP, params.Coord( iP ) + parDelta );
-      ShellPoint( nearParams, Pi );
-      gp_Vec dPi ( P, Pi );
-      if ( onEdge ) dPi *= -1.;
-      // modify a parameter
-      double mag = dPi.Magnitude();
-      if ( mag < DBL_MIN )
-        continue;
-      gp_Vec dir = dPi / mag; // dir we move modifying the parameter
-      double dist = dir * dP; // where we should get to
-      double dPar = dist / mag * parDelta; // predict parameter change
-      double curPar = params.Coord( iP );
-      double par = curPar - dPar; // new parameter value
-      while ( par > 1 || par < 0 ) {
-        dPar /= 2.;
-        par = curPar - dPar;
-      }
-      params.SetCoord( iP, par );
-    }
-
-    nbLoops++;
-  }
-#ifdef DEBUG_PARAM_COMPUTE
-  myNbIterations += nbLoops*4; // how many times ShellPoint called
-  mySumDist += sqrt( sqDistance );
-  MESSAGE ( " ------ SOLUTION: ( "<<solution.X()<<" "<<solution.Y()<<" "<<solution.Z()<<" )"<< std::endl
-         << " ------ DIST : " << sqrt( sqDistance ) << "\t Tol=" << myTolerance << "\t Nb LOOPS=" << nbLoops << std::endl
-         << " ------ NB IT: " << myNbIterations << ",  SUM DIST: " << mySumDist );
-#endif
-
-  theParams = solution;
-
-  if ( myFaceIndex > 0 )
-    theParams.SetCoord( myFaceIndex, myFaceParam );
-
-  return true;
-}
-
-//=======================================================================
-//function : VertexParameters
-//purpose  : return parameters of a vertex given by TShapeID
-//=======================================================================
-
-bool SMESH_Block::VertexParameters(const int theVertexID, gp_XYZ& theParams)
-{
-  switch ( theVertexID ) {
-  case ID_V000: theParams.SetCoord(0., 0., 0.); return true;
-  case ID_V100: theParams.SetCoord(1., 0., 0.); return true;
-  case ID_V110: theParams.SetCoord(1., 1., 0.); return true;
-  case ID_V010: theParams.SetCoord(0., 1., 0.); return true;
-  default:;
-  }
-  return false;
-}
-
-//=======================================================================
-//function : EdgeParameters
-//purpose  : return parameters of a point given by theU on edge
-//=======================================================================
-
-bool SMESH_Block::EdgeParameters(const int theEdgeID, const double theU, gp_XYZ& theParams)
-{
-  if ( IsEdgeID( theEdgeID )) {
-    vector< int > vertexVec;
-    GetEdgeVertexIDs( theEdgeID, vertexVec );
-    VertexParameters( vertexVec[0], theParams );
-    TEdge& e = myEdge[ theEdgeID - ID_Ex00 ];
-    double param = ( theU - e.EndParam(0) ) / ( e.EndParam(1) - e.EndParam(0) );
-    theParams.SetCoord( e.CoordInd(), param );
-    return true;
-  }
-  return false;
-}
-
-//=======================================================================
-//function : DumpShapeID
-//purpose  : debug an id of a block sub-shape
-//=======================================================================
-
-#define CASEDUMP(id,strm) case id: strm << #id; break;
-
-ostream& SMESH_Block::DumpShapeID (const int id, ostream& stream)
-{
-  switch ( id ) {
-  CASEDUMP( ID_V000, stream );
-  CASEDUMP( ID_V100, stream );
-  CASEDUMP( ID_V010, stream );
-  CASEDUMP( ID_V110, stream );
-  CASEDUMP( ID_V001, stream );
-  CASEDUMP( ID_V101, stream );
-  CASEDUMP( ID_V011, stream );
-  CASEDUMP( ID_V111, stream );
-  CASEDUMP( ID_Ex00, stream );
-  CASEDUMP( ID_Ex10, stream );
-  CASEDUMP( ID_Ex01, stream );
-  CASEDUMP( ID_Ex11, stream );
-  CASEDUMP( ID_E0y0, stream );
-  CASEDUMP( ID_E1y0, stream );
-  CASEDUMP( ID_E0y1, stream );
-  CASEDUMP( ID_E1y1, stream );
-  CASEDUMP( ID_E00z, stream );
-  CASEDUMP( ID_E10z, stream );
-  CASEDUMP( ID_E01z, stream );
-  CASEDUMP( ID_E11z, stream );
-  CASEDUMP( ID_Fxy0, stream );
-  CASEDUMP( ID_Fxy1, stream );
-  CASEDUMP( ID_Fx0z, stream );
-  CASEDUMP( ID_Fx1z, stream );
-  CASEDUMP( ID_F0yz, stream );
-  CASEDUMP( ID_F1yz, stream );
-  CASEDUMP( ID_Shell, stream );
-  default: stream << "ID_INVALID";
-  }
-  return stream;
-}
-
-//=======================================================================
-//function : GetShapeIDByParams
-//purpose  : define an id of the block sub-shape by normlized point coord
-//=======================================================================
-
-int SMESH_Block::GetShapeIDByParams ( const gp_XYZ& theCoord )
-{
-  //   id ( 0 - 26 ) computation:
-
-  //   vertex     ( 0 - 7 )  : id = 1*x + 2*y + 4*z
-
-  //   edge || X  ( 8 - 11 ) : id = 8   + 1*y + 2*z
-  //   edge || Y  ( 12 - 15 ): id = 1*x + 12  + 2*z
-  //   edge || Z  ( 16 - 19 ): id = 1*x + 2*y + 16 
-
-  //   face || XY ( 20 - 21 ): id = 8   + 12  + 1*z - 0
-  //   face || XZ ( 22 - 23 ): id = 8   + 1*y + 16  - 2
-  //   face || YZ ( 24 - 25 ): id = 1*x + 12  + 16  - 4
-
-  static int iAddBnd[]    = { 1, 2, 4 };
-  static int iAddNotBnd[] = { 8, 12, 16 };
-  static int iFaceSubst[] = { 0, 2, 4 };
-
-  int id = 0;
-  int iOnBoundary = 0;
-  for ( int iCoord = 0; iCoord < 3; iCoord++ )
-  {
-    double val = theCoord.Coord( iCoord + 1 );
-    if ( val == 0.0 )
-      iOnBoundary++;
-    else if ( val == 1.0 )
-      id += iAddBnd[ iOnBoundary++ ];
-    else
-      id += iAddNotBnd[ iCoord ];
-  }
-  if ( iOnBoundary == 1 ) // face
-    id -= iFaceSubst[ (id - 20) / 4 ];
-  else if ( iOnBoundary == 0 ) // shell
-    id = 26;
-
-  if ( id > 26 || id < 0 ) {
-    MESSAGE( "GetShapeIDByParams() = " << id
-            <<" "<< theCoord.X() <<" "<< theCoord.Y() <<" "<< theCoord.Z() );
-  }
-
-  return id + 1; // shape ids start at 1
-}
-
-//=======================================================================
-//function : GetOrderedEdges
-//purpose  : return nb wires and a list of oredered edges
-//=======================================================================
-
-int SMESH_Block::GetOrderedEdges (const TopoDS_Face&   theFace,
-                                  TopoDS_Vertex        theFirstVertex,
-                                  list< TopoDS_Edge >& theEdges,
-                                  list< int >  &       theNbVertexInWires)
-{
-  // put wires in a list, so that an outer wire comes first
-  list<TopoDS_Wire> aWireList;
-  TopoDS_Wire anOuterWire = BRepTools::OuterWire( theFace );
-  aWireList.push_back( anOuterWire );
-  for ( TopoDS_Iterator wIt (theFace); wIt.More(); wIt.Next() )
-    if ( !anOuterWire.IsSame( wIt.Value() ))
-      aWireList.push_back( TopoDS::Wire( wIt.Value() ));
-
-  // loop on edges of wires
-  theNbVertexInWires.clear();
-  list<TopoDS_Wire>::iterator wlIt = aWireList.begin();
-  for ( ; wlIt != aWireList.end(); wlIt++ )
-  {
-    int iE;
-    BRepTools_WireExplorer wExp( *wlIt, theFace );
-    for ( iE = 0; wExp.More(); wExp.Next(), iE++ )
-    {
-      TopoDS_Edge edge = wExp.Current();
-      edge = TopoDS::Edge( edge.Oriented( wExp.Orientation() ));
-      theEdges.push_back( edge );
-    }
-    theNbVertexInWires.push_back( iE );
-    iE = 0;
-    if ( wlIt == aWireList.begin() && theEdges.size() > 1 ) { // the outer wire
-      // orient closed edges
-      list< TopoDS_Edge >::iterator eIt, eIt2;
-      for ( eIt = theEdges.begin(); eIt != theEdges.end(); eIt++ )
-      {
-        TopoDS_Edge& edge = *eIt;
-        if ( TopExp::FirstVertex( edge ).IsSame( TopExp::LastVertex( edge ) ))
-        {
-          eIt2 = eIt;
-          bool isNext = ( eIt2 == theEdges.begin() );
-          TopoDS_Edge edge2 = isNext ? *(++eIt2) : *(--eIt2);
-          double f1,l1,f2,l2;
-          Handle(Geom2d_Curve) c1 = BRep_Tool::CurveOnSurface( edge, theFace, f1,l1 );
-          Handle(Geom2d_Curve) c2 = BRep_Tool::CurveOnSurface( edge2, theFace, f2,l2 );
-          gp_Pnt2d pf = c1->Value( edge.Orientation() == TopAbs_FORWARD ? f1 : l1 );
-          gp_Pnt2d pl = c1->Value( edge.Orientation() == TopAbs_FORWARD ? l1 : f1 );
-          bool isFirst = ( edge2.Orientation() == TopAbs_FORWARD ? isNext : !isNext );
-          gp_Pnt2d p2 = c2->Value( isFirst ? f2 : l2 );
-          isFirst = ( p2.SquareDistance( pf ) < p2.SquareDistance( pl ));
-          if ( isNext ? isFirst : !isFirst )
-            edge.Reverse();
-          // to make a seam go first
-          if ( theFirstVertex.IsNull() )
-            theFirstVertex = TopExp::FirstVertex( edge, true );
-        }
-      }
-      // rotate theEdges until it begins from theFirstVertex
-      if ( ! theFirstVertex.IsNull() ) {
-        TopoDS_Vertex vv[2];
-        TopExp::Vertices( theEdges.front(), vv[0], vv[1], true );
-        // on closed face, make seam edge the first in the list
-        while ( !vv[0].IsSame( theFirstVertex ) || vv[0].IsSame( vv[1] ))
-        {
-          theEdges.splice(theEdges.end(), theEdges,
-                          theEdges.begin(), ++theEdges.begin());
-          TopExp::Vertices( theEdges.front(), vv[0], vv[1], true );
-          if ( iE++ > theNbVertexInWires.back() ) {
-#ifdef _DEBUG_
-            gp_Pnt p = BRep_Tool::Pnt( theFirstVertex );
-            MESSAGE ( " : Warning : vertex "<< theFirstVertex.TShape().operator->()
-                   << " ( " << p.X() << " " << p.Y() << " " << p.Z() << " )" 
-                   << " not found in outer wire of face "<< theFace.TShape().operator->()
-                   << " with vertices: " );
-            wExp.Init( *wlIt, theFace );
-            for ( int i = 0; wExp.More(); wExp.Next(), i++ )
-            {
-              TopoDS_Edge edge = wExp.Current();
-              edge = TopoDS::Edge( edge.Oriented( wExp.Orientation() ));
-              TopoDS_Vertex v = TopExp::FirstVertex( edge, true );
-              gp_Pnt p = BRep_Tool::Pnt( v );
-              MESSAGE_ADD ( i << " " << v.TShape().operator->() << " "
-                            << p.X() << " " << p.Y() << " " << p.Z() << " " << std::endl );
-            }
-#endif
-            break; // break infinite loop
-          }
-        }
-      }
-    } // end outer wire
-  }
-
-  return aWireList.size();
-}
-//================================================================================
-/*!
- * \brief Call it after geometry initialisation
- */
-//================================================================================
-
-void SMESH_Block::init()
-{
-  myNbIterations = 0;
-  mySumDist = 0;
-  myGridComputed = false;
-}
-
-//=======================================================================
-//function : LoadMeshBlock
-//purpose  : prepare to work with theVolume
-//=======================================================================
-
-#define gpXYZ(n) gp_XYZ(n->X(),n->Y(),n->Z())
-
-bool SMESH_Block::LoadMeshBlock(const SMDS_MeshVolume*        theVolume,
-                                const int                     theNode000Index,
-                                const int                     theNode001Index,
-                                vector<const SMDS_MeshNode*>& theOrderedNodes)
-{
-  MESSAGE(" ::LoadMeshBlock()");
-  init();
-
-  SMDS_VolumeTool vTool;
-  if (!vTool.Set( theVolume ) || vTool.NbNodes() != 8 ||
-      !vTool.IsLinked( theNode000Index, theNode001Index )) {
-    MESSAGE(" Bad arguments ");
-    return false;
-  }
-  vTool.SetExternalNormal();
-  // In terms of indices used for access to nodes and faces in SMDS_VolumeTool:
-  int V000, V100, V010, V110, V001, V101, V011, V111; // 8 vertices
-  int Fxy0, Fxy1; // bottom and top faces
-  // vertices of faces
-  vector<int> vFxy0, vFxy1;
-
-  V000 = theNode000Index;
-  V001 = theNode001Index;
-
-  // get faces sharing V000 and V001
-  list<int> fV000, fV001;
-  int i, iF, iE, iN;
-  for ( iF = 0; iF < vTool.NbFaces(); ++iF ) {
-    const int* nid = vTool.GetFaceNodesIndices( iF );
-    for ( iN = 0; iN < 4; ++iN )
-      if ( nid[ iN ] == V000 ) {
-        fV000.push_back( iF );
-      } else if ( nid[ iN ] == V001 ) {
-        fV001.push_back( iF );
-      }
-  }
-
-  // find the bottom (Fxy0), the top (Fxy1) faces
-  list<int>::iterator fIt1, fIt2, Fxy0Pos;
-  for ( fIt1 = fV000.begin(); fIt1 != fV000.end(); fIt1++) {
-    fIt2 = std::find( fV001.begin(), fV001.end(), *fIt1 );
-    if ( fIt2 != fV001.end() ) { // *fIt1 is in the both lists
-      fV001.erase( fIt2 ); // erase Fx0z or F0yz from fV001
-    } else { // *fIt1 is in fV000 only
-      Fxy0Pos = fIt1; // points to Fxy0
-    }
-  }
-  Fxy0 = *Fxy0Pos;
-  Fxy1 = fV001.front();
-  const SMDS_MeshNode** nn = vTool.GetNodes();
-
-  // find bottom veritices, their order is that a face normal is external
-  vFxy0.resize(4);
-  const int* nid = vTool.GetFaceNodesIndices( Fxy0 );
-  for ( i = 0; i < 4; ++i )
-    if ( nid[ i ] == V000 )
-      break;
-  for ( iN = 0; iN < 4; ++iN, ++i ) {
-    if ( i == 4 ) i = 0;
-    vFxy0[ iN ] = nid[ i ];
-  }
-  // find top veritices, their order is that a face normal is external
-  vFxy1.resize(4);
-  nid = vTool.GetFaceNodesIndices( Fxy1 );
-  for ( i = 0; i < 4; ++i )
-    if ( nid[ i ] == V001 )
-      break;
-  for ( iN = 0; iN < 4; ++iN, ++i ) {
-    if ( i == 4 ) i = 0;
-    vFxy1[ iN ] = nid[ i ];
-  }
-  // find indices of the rest veritices 
-  V100 = vFxy0[3];
-  V010 = vFxy0[1];
-  V110 = vFxy0[2];
-  V101 = vFxy1[1];
-  V011 = vFxy1[3];
-  V111 = vFxy1[2];
-
-  // set points coordinates
-  myPnt[ ID_V000 - 1 ] = gpXYZ( nn[ V000 ] );
-  myPnt[ ID_V100 - 1 ] = gpXYZ( nn[ V100 ] );
-  myPnt[ ID_V010 - 1 ] = gpXYZ( nn[ V010 ] );
-  myPnt[ ID_V110 - 1 ] = gpXYZ( nn[ V110 ] );
-  myPnt[ ID_V001 - 1 ] = gpXYZ( nn[ V001 ] );
-  myPnt[ ID_V101 - 1 ] = gpXYZ( nn[ V101 ] );
-  myPnt[ ID_V011 - 1 ] = gpXYZ( nn[ V011 ] );
-  myPnt[ ID_V111 - 1 ] = gpXYZ( nn[ V111 ] );
-
-  // fill theOrderedNodes
-  theOrderedNodes.resize( 8 );
-  theOrderedNodes[ 0 ] = nn[ V000 ];
-  theOrderedNodes[ 1 ] = nn[ V100 ];
-  theOrderedNodes[ 2 ] = nn[ V010 ];
-  theOrderedNodes[ 3 ] = nn[ V110 ];
-  theOrderedNodes[ 4 ] = nn[ V001 ];
-  theOrderedNodes[ 5 ] = nn[ V101 ];
-  theOrderedNodes[ 6 ] = nn[ V011 ];
-  theOrderedNodes[ 7 ] = nn[ V111 ];
-  
-  // fill edges
-  vector< int > vertexVec;
-  for ( iE = 0; iE < NbEdges(); ++iE ) {
-    GetEdgeVertexIDs(( iE + ID_FirstE ), vertexVec );
-    myEdge[ iE ].Set(( iE + ID_FirstE ),
-                     myPnt[ vertexVec[0] - 1 ],
-                     myPnt[ vertexVec[1] - 1 ]);
-  }
-
-  // fill faces' corners
-  for ( iF = ID_Fxy0; iF < ID_Shell; ++iF )
-  {
-    TFace& tFace = myFace[ iF - ID_FirstF ];
-    vector< int > edgeIdVec(4, -1);
-    GetFaceEdgesIDs( iF, edgeIdVec );
-    tFace.Set( iF, myEdge[ edgeIdVec [ 0 ] - ID_Ex00], myEdge[ edgeIdVec [ 1 ] - ID_Ex00]);
-  }
-
-  return true;
-}
-
-//=======================================================================
-//function : LoadBlockShapes
-//purpose  : Initialize block geometry with theShell,
-//           add sub-shapes of theBlock to theShapeIDMap so that they get
-//           IDs acoording to enum TShapeID
-//=======================================================================
-
-bool SMESH_Block::LoadBlockShapes(const TopoDS_Shell&         theShell,
-                                  const TopoDS_Vertex&        theVertex000,
-                                  const TopoDS_Vertex&        theVertex001,
-                                  TopTools_IndexedMapOfOrientedShape& theShapeIDMap )
-{
-  MESSAGE(" ::LoadBlockShapes()");
-  return ( FindBlockShapes( theShell, theVertex000, theVertex001, theShapeIDMap ) &&
-           LoadBlockShapes( theShapeIDMap ));
-}
-
-//=======================================================================
-//function : LoadBlockShapes
-//purpose  : add sub-shapes of theBlock to theShapeIDMap so that they get
-//           IDs acoording to enum TShapeID
-//=======================================================================
-
-bool SMESH_Block::FindBlockShapes(const TopoDS_Shell&         theShell,
-                                  const TopoDS_Vertex&        theVertex000,
-                                  const TopoDS_Vertex&        theVertex001,
-                                  TopTools_IndexedMapOfOrientedShape& theShapeIDMap )
-{
-  MESSAGE(" ::FindBlockShapes()");
-
-  // 8 vertices
-  TopoDS_Shape V000, V100, V010, V110, V001, V101, V011, V111;
-  // 12 edges
-  TopoDS_Shape Ex00, Ex10, Ex01, Ex11;
-  TopoDS_Shape E0y0, E1y0, E0y1, E1y1;
-  TopoDS_Shape E00z, E10z, E01z, E11z;
-  // 6 faces
-  TopoDS_Shape Fxy0, Fx0z, F0yz, Fxy1, Fx1z, F1yz;
-
-  // nb of faces bound to a vertex in TopTools_IndexedDataMapOfShapeListOfShape
-  // filled by TopExp::MapShapesAndAncestors()
-  const int NB_FACES_BY_VERTEX = 6;
-
-  TopTools_IndexedDataMapOfShapeListOfShape vfMap;
-  TopExp::MapShapesAndAncestors( theShell, TopAbs_VERTEX, TopAbs_FACE, vfMap );
-  if ( vfMap.Extent() != 8 ) {
-    MESSAGE(" Wrong nb of vertices in the block: " << vfMap.Extent() );
-    return false;
-  }
-
-  V000 = theVertex000;
-  V001 = theVertex001;
-
-  if ( V000.IsNull() ) {
-    // find vertex 000 - the one with smallest coordinates
-    double minVal = DBL_MAX, minX, val;
-    for ( int i = 1; i <= 8; i++ ) {
-      const TopoDS_Vertex& v = TopoDS::Vertex( vfMap.FindKey( i ));
-      gp_Pnt P = BRep_Tool::Pnt( v );
-      val = P.X() + P.Y() + P.Z();
-      if ( val < minVal || ( val == minVal && P.X() < minX )) {
-        V000 = v;
-        minVal = val;
-        minX = P.X();
-      }
-    }
-    // find vertex 001 - the one on the most vertical edge passing through V000
-    TopTools_IndexedDataMapOfShapeListOfShape veMap;
-    TopExp::MapShapesAndAncestors( theShell, TopAbs_VERTEX, TopAbs_EDGE, veMap );
-    gp_Vec dir001 = gp::DZ();
-    gp_Pnt p000 = BRep_Tool::Pnt( TopoDS::Vertex( V000 ));
-    double maxVal = -DBL_MAX;
-    TopTools_ListIteratorOfListOfShape eIt ( veMap.FindFromKey( V000 ));
-    for (  ; eIt.More(); eIt.Next() ) {
-      const TopoDS_Edge& e = TopoDS::Edge( eIt.Value() );
-      TopoDS_Vertex v = TopExp::FirstVertex( e );
-      if ( v.IsSame( V000 ))
-        v = TopExp::LastVertex( e );
-      val = dir001 * gp_Vec( p000, BRep_Tool::Pnt( v )).Normalized();
-      if ( val > maxVal ) {
-        V001 = v;
-        maxVal = val;
-      }
-    }
-  }
-
-  // find the bottom (Fxy0), Fx0z and F0yz faces
-
-  const TopTools_ListOfShape& f000List = vfMap.FindFromKey( V000 );
-  const TopTools_ListOfShape& f001List = vfMap.FindFromKey( V001 );
-  if (f000List.Extent() != NB_FACES_BY_VERTEX ||
-      f001List.Extent() != NB_FACES_BY_VERTEX ) {
-    MESSAGE(" LoadBlockShapes() " << f000List.Extent() << " " << f001List.Extent());
-    return false;
-  }
-  TopTools_ListIteratorOfListOfShape f001It, f000It ( f000List );
-  int i, j, iFound1, iFound2;
-  for ( j = 0; f000It.More(); f000It.Next(), j++ )
-  {
-    if ( NB_FACES_BY_VERTEX == 6 && j % 2 ) continue; // each face encounters twice
-    const TopoDS_Shape& F = f000It.Value();
-    for ( i = 0, f001It.Initialize( f001List ); f001It.More(); f001It.Next(), i++ ) {
-      if ( NB_FACES_BY_VERTEX == 6 && i % 2 ) continue; // each face encounters twice
-      if ( F.IsSame( f001It.Value() ))
-        break;
-    }
-    if ( f001It.More() ) // Fx0z or F0yz found
-      if ( Fx0z.IsNull() ) {
-        Fx0z = F;
-        iFound1 = i;
-      } else {
-        F0yz = F;
-        iFound2 = i;
-      }
-    else // F is the bottom face
-      Fxy0 = F;
-  }
-  if ( Fxy0.IsNull() || Fx0z.IsNull() || F0yz.IsNull() ) {
-    MESSAGE( Fxy0.IsNull() <<" "<< Fx0z.IsNull() <<" "<< F0yz.IsNull() );
-    return false;
-  }
-
-  // choose the top face (Fxy1)
-  for ( i = 0, f001It.Initialize( f001List ); f001It.More(); f001It.Next(), i++ ) {
-    if ( NB_FACES_BY_VERTEX == 6 && i % 2 ) continue; // each face encounters twice
-    if ( i != iFound1 && i != iFound2 )
-      break;
-  }
-  Fxy1 = f001It.Value();
-  if ( Fxy1.IsNull() ) {
-    MESSAGE(" LoadBlockShapes() error ");
-    return false;
-  }
-
-  // find bottom edges and veritices
-  list< TopoDS_Edge > eList;
-  list< int >         nbVertexInWires;
-  GetOrderedEdges( TopoDS::Face( Fxy0 ), TopoDS::Vertex( V000 ), eList, nbVertexInWires );
-  if ( nbVertexInWires.size() != 1 || nbVertexInWires.front() != 4 ) {
-    MESSAGE(" LoadBlockShapes() error ");
-    return false;
-  }
-  list< TopoDS_Edge >::iterator elIt = eList.begin();
-  for ( i = 0; elIt != eList.end(); elIt++, i++ )
-    switch ( i ) {
-    case 0: E0y0 = *elIt; V010 = TopExp::LastVertex( *elIt, true ); break;
-    case 1: Ex10 = *elIt; V110 = TopExp::LastVertex( *elIt, true ); break;
-    case 2: E1y0 = *elIt; V100 = TopExp::LastVertex( *elIt, true ); break;
-    case 3: Ex00 = *elIt; break;
-    default:;
-    }
-  if ( i != 4 || E0y0.IsNull() || Ex10.IsNull() || E1y0.IsNull() || Ex00.IsNull() ) {
-    MESSAGE(" LoadBlockShapes() error, eList.size()=" << eList.size());
-    return false;
-  }
-
-
-  // find top edges and veritices
-  eList.clear();
-  GetOrderedEdges( TopoDS::Face( Fxy1 ), TopoDS::Vertex( V001 ), eList, nbVertexInWires );
-  if ( nbVertexInWires.size() != 1 || nbVertexInWires.front() != 4 ) {
-    MESSAGE(" LoadBlockShapes() error ");
-    return false;
-  }
-  for ( i = 0, elIt = eList.begin(); elIt != eList.end(); elIt++, i++ )
-    switch ( i ) {
-    case 0: Ex01 = *elIt; V101 = TopExp::LastVertex( *elIt, true ); break;
-    case 1: E1y1 = *elIt; V111 = TopExp::LastVertex( *elIt, true ); break;
-    case 2: Ex11 = *elIt; V011 = TopExp::LastVertex( *elIt, true ); break;
-    case 3: E0y1 = *elIt; break;
-    default:;
-    }
-  if ( i != 4 || Ex01.IsNull() || E1y1.IsNull() || Ex11.IsNull() || E0y1.IsNull() ) {
-    MESSAGE(" LoadBlockShapes() error, eList.size()=" << eList.size());
-    return false;
-  }
-
-  // swap Fx0z and F0yz if necessary
-  TopExp_Explorer exp( Fx0z, TopAbs_VERTEX );
-  for ( ; exp.More(); exp.Next() ) // Fx0z shares V101 and V100
-    if ( V101.IsSame( exp.Current() ) || V100.IsSame( exp.Current() ))
-      break; // V101 or V100 found
-  if ( !exp.More() ) { // not found
-    std::swap( Fx0z, F0yz);
-  }
-
-  // find Fx1z and F1yz faces
-  const TopTools_ListOfShape& f111List = vfMap.FindFromKey( V111 );
-  const TopTools_ListOfShape& f110List = vfMap.FindFromKey( V110 );
-  if (f111List.Extent() != NB_FACES_BY_VERTEX ||
-      f110List.Extent() != NB_FACES_BY_VERTEX ) {
-    MESSAGE(" LoadBlockShapes() " << f111List.Extent() << " " << f110List.Extent());
-    return false;
-  }
-  TopTools_ListIteratorOfListOfShape f111It, f110It ( f110List);
-  for ( j = 0 ; f110It.More(); f110It.Next(), j++ ) {
-    if ( NB_FACES_BY_VERTEX == 6 && j % 2 ) continue; // each face encounters twice
-    const TopoDS_Shape& F = f110It.Value();
-    for ( i = 0, f111It.Initialize( f111List ); f111It.More(); f111It.Next(), i++ ) {
-      if ( NB_FACES_BY_VERTEX == 6 && i % 2 ) continue; // each face encounters twice
-      if ( F.IsSame( f111It.Value() )) { // Fx1z or F1yz found
-        if ( Fx1z.IsNull() )
-          Fx1z = F;
-        else
-          F1yz = F;
-      }
-    }
-  }
-  if ( Fx1z.IsNull() || F1yz.IsNull() ) {
-    MESSAGE(" LoadBlockShapes() error ");
-    return false;
-  }
-
-  // swap Fx1z and F1yz if necessary
-  for ( exp.Init( Fx1z, TopAbs_VERTEX ); exp.More(); exp.Next() )
-    if ( V010.IsSame( exp.Current() ) || V011.IsSame( exp.Current() ))
-      break;
-  if ( !exp.More() ) {
-    std::swap( Fx1z, F1yz);
-  }
-
-  // find vertical edges
-  for ( exp.Init( Fx0z, TopAbs_EDGE ); exp.More(); exp.Next() ) {
-    const TopoDS_Edge& edge = TopoDS::Edge( exp.Current() );
-    const TopoDS_Shape& vFirst = TopExp::FirstVertex( edge, true );
-    if ( vFirst.IsSame( V001 ))
-      E00z = edge;
-    else if ( vFirst.IsSame( V100 ))
-      E10z = edge;
-  }
-  if ( E00z.IsNull() || E10z.IsNull() ) {
-    MESSAGE(" LoadBlockShapes() error ");
-    return false;
-  }
-  for ( exp.Init( Fx1z, TopAbs_EDGE ); exp.More(); exp.Next() ) {
-    const TopoDS_Edge& edge = TopoDS::Edge( exp.Current() );
-    const TopoDS_Shape& vFirst = TopExp::FirstVertex( edge, true );
-    if ( vFirst.IsSame( V111 ))
-      E11z = edge;
-    else if ( vFirst.IsSame( V010 ))
-      E01z = edge;
-  }
-  if ( E01z.IsNull() || E11z.IsNull() ) {
-    MESSAGE(" LoadBlockShapes() error ");
-    return false;
-  }
-
-  // load shapes in theShapeIDMap
-
-  theShapeIDMap.Clear();
-  
-  theShapeIDMap.Add(V000.Oriented( TopAbs_FORWARD ));
-  theShapeIDMap.Add(V100.Oriented( TopAbs_FORWARD ));
-  theShapeIDMap.Add(V010.Oriented( TopAbs_FORWARD ));
-  theShapeIDMap.Add(V110.Oriented( TopAbs_FORWARD ));
-  theShapeIDMap.Add(V001.Oriented( TopAbs_FORWARD ));
-  theShapeIDMap.Add(V101.Oriented( TopAbs_FORWARD ));
-  theShapeIDMap.Add(V011.Oriented( TopAbs_FORWARD ));
-  theShapeIDMap.Add(V111.Oriented( TopAbs_FORWARD ));
-
-  theShapeIDMap.Add(Ex00);
-  theShapeIDMap.Add(Ex10);
-  theShapeIDMap.Add(Ex01);
-  theShapeIDMap.Add(Ex11);
-
-  theShapeIDMap.Add(E0y0);
-  theShapeIDMap.Add(E1y0);
-  theShapeIDMap.Add(E0y1);
-  theShapeIDMap.Add(E1y1);
-
-  theShapeIDMap.Add(E00z);
-  theShapeIDMap.Add(E10z);
-  theShapeIDMap.Add(E01z);
-  theShapeIDMap.Add(E11z);
-
-  theShapeIDMap.Add(Fxy0);
-  theShapeIDMap.Add(Fxy1);
-  theShapeIDMap.Add(Fx0z);
-  theShapeIDMap.Add(Fx1z);
-  theShapeIDMap.Add(F0yz);
-  theShapeIDMap.Add(F1yz);
-  
-  theShapeIDMap.Add(theShell);
-
-  return true;
-}
-
-//================================================================================
-/*!
- * \brief Initialize block geometry with shapes from theShapeIDMap
-  * \param theShapeIDMap - map of block subshapes
-  * \retval bool - is a success
- */
-//================================================================================
-
-bool SMESH_Block::LoadBlockShapes(const TopTools_IndexedMapOfOrientedShape& theShapeIDMap)
-{
-  init();
-
-  // store shapes geometry
-  for ( int shapeID = 1; shapeID < theShapeIDMap.Extent(); shapeID++ )
-  {
-    const TopoDS_Shape& S = theShapeIDMap( shapeID );
-    switch ( S.ShapeType() )
-    {
-    case TopAbs_VERTEX: {
-
-      if ( !IsVertexID( ID_V111 )) return false;
-      myPnt[ shapeID - ID_V000 ] = BRep_Tool::Pnt( TopoDS::Vertex( S )).XYZ();
-      break;
-    }
-    case TopAbs_EDGE: {
-
-      if ( !IsEdgeID( shapeID )) return false;
-      const TopoDS_Edge& edge = TopoDS::Edge( S );
-      TEdge& tEdge = myEdge[ shapeID - ID_FirstE ];
-      tEdge.Set( shapeID,
-                 new BRepAdaptor_Curve( edge ),
-                 IsForwardEdge( edge, theShapeIDMap ));
-      break;
-    }
-    case TopAbs_FACE: {
-
-      if ( !LoadFace( TopoDS::Face( S ), shapeID, theShapeIDMap ))
-        return false;
-      break;
-    }
-    default: break;
-    }
-  } // loop on shapes in theShapeIDMap
-
-  return true;
-}
-
-//================================================================================
-/*!
- * \brief Load face geometry
-  * \param theFace - face
-  * \param theFaceID - face in-block ID
-  * \param theShapeIDMap - map of block subshapes
-  * \retval bool - is a success
- * 
- * It is enough to compute params or coordinates on the face.
- * Face subshapes must be loaded into theShapeIDMap before
- */
-//================================================================================
-
-bool SMESH_Block::LoadFace(const TopoDS_Face& theFace,
-                           const int          theFaceID,
-                           const TopTools_IndexedMapOfOrientedShape& theShapeIDMap)
-{
-  if ( !IsFaceID( theFaceID ) ) return false;
-  // pcurves
-  Adaptor2d_Curve2d* c2d[4];
-  bool isForward[4];
-  vector< int > edgeIdVec;
-  GetFaceEdgesIDs( theFaceID, edgeIdVec );
-  for ( int iE = 0; iE < edgeIdVec.size(); iE++ ) // loop on 4 edges
-  {
-    if ( edgeIdVec[ iE ] > theShapeIDMap.Extent() )
-      return false;
-    const TopoDS_Edge& edge = TopoDS::Edge( theShapeIDMap( edgeIdVec[ iE ]));
-    c2d[ iE ] = new BRepAdaptor_Curve2d( edge, theFace );
-    isForward[ iE ] = IsForwardEdge( edge, theShapeIDMap );
-  }
-  TFace& tFace = myFace[ theFaceID - ID_FirstF ];
-  tFace.Set( theFaceID, new BRepAdaptor_Surface( theFace ), c2d, isForward );
-  return true;
-}
-
-//================================================================================
-/*!
- * \brief/ Insert theShape into theShapeIDMap with theShapeID
-  * \param theShape - shape to insert
-  * \param theShapeID - shape in-block ID
-  * \param theShapeIDMap - map of block subshapes
- */
-//================================================================================
-
-bool SMESH_Block::Insert(const TopoDS_Shape& theShape,
-                         const int           theShapeID,
-                         TopTools_IndexedMapOfOrientedShape& theShapeIDMap)
-{
-  if ( !theShape.IsNull() && theShapeID > 0 )
-  {
-    if ( theShapeIDMap.Contains( theShape ))
-      return ( theShapeIDMap.FindIndex( theShape ) == theShapeID );
-
-    if ( theShapeID <= theShapeIDMap.Extent() ) {
-        theShapeIDMap.Substitute( theShapeID, theShape );
-    }
-    else {
-      while ( theShapeIDMap.Extent() < theShapeID - 1 ) {
-        TopoDS_Compound comp;
-        BRep_Builder().MakeCompound( comp );
-        theShapeIDMap.Add( comp );
-      }
-      theShapeIDMap.Add( theShape );
-    }
-    return true;
-  }
-  return false;
-}
-
-//=======================================================================
-//function : GetFaceEdgesIDs
-//purpose  : return edges IDs in the order u0, u1, 0v, 1v
-//           u0 means "|| u, v == 0"
-//=======================================================================
-
-void SMESH_Block::GetFaceEdgesIDs (const int faceID, vector< int >& edgeVec )
-{
-  edgeVec.resize( 4 );
-  switch ( faceID ) {
-  case ID_Fxy0:
-    edgeVec[ 0 ] = ID_Ex00;
-    edgeVec[ 1 ] = ID_Ex10;
-    edgeVec[ 2 ] = ID_E0y0;
-    edgeVec[ 3 ] = ID_E1y0;
-    break;
-  case ID_Fxy1:
-    edgeVec[ 0 ] = ID_Ex01;
-    edgeVec[ 1 ] = ID_Ex11;
-    edgeVec[ 2 ] = ID_E0y1;
-    edgeVec[ 3 ] = ID_E1y1;
-    break;
-  case ID_Fx0z:
-    edgeVec[ 0 ] = ID_Ex00;
-    edgeVec[ 1 ] = ID_Ex01;
-    edgeVec[ 2 ] = ID_E00z;
-    edgeVec[ 3 ] = ID_E10z;
-    break;
-  case ID_Fx1z:
-    edgeVec[ 0 ] = ID_Ex10;
-    edgeVec[ 1 ] = ID_Ex11;
-    edgeVec[ 2 ] = ID_E01z;
-    edgeVec[ 3 ] = ID_E11z;
-    break;
-  case ID_F0yz:
-    edgeVec[ 0 ] = ID_E0y0;
-    edgeVec[ 1 ] = ID_E0y1;
-    edgeVec[ 2 ] = ID_E00z;
-    edgeVec[ 3 ] = ID_E01z;
-    break;
-  case ID_F1yz:
-    edgeVec[ 0 ] = ID_E1y0;
-    edgeVec[ 1 ] = ID_E1y1;
-    edgeVec[ 2 ] = ID_E10z;
-    edgeVec[ 3 ] = ID_E11z;
-    break;
-  default:
-    MESSAGE(" GetFaceEdgesIDs(), wrong face ID: " << faceID );
-  }
-}
-
-//=======================================================================
-//function : GetEdgeVertexIDs
-//purpose  : return vertex IDs of an edge
-//=======================================================================
-
-void SMESH_Block::GetEdgeVertexIDs (const int edgeID, vector< int >& vertexVec )
-{
-  vertexVec.resize( 2 );
-  switch ( edgeID ) {
-
-  case ID_Ex00:
-    vertexVec[ 0 ] = ID_V000;
-    vertexVec[ 1 ] = ID_V100;
-    break;
-  case ID_Ex10:
-    vertexVec[ 0 ] = ID_V010;
-    vertexVec[ 1 ] = ID_V110;
-    break;
-  case ID_Ex01:
-    vertexVec[ 0 ] = ID_V001;
-    vertexVec[ 1 ] = ID_V101;
-    break;
-  case ID_Ex11:
-    vertexVec[ 0 ] = ID_V011;
-    vertexVec[ 1 ] = ID_V111;
-    break;
-
-  case ID_E0y0:
-    vertexVec[ 0 ] = ID_V000;
-    vertexVec[ 1 ] = ID_V010;
-    break;
-  case ID_E1y0:
-    vertexVec[ 0 ] = ID_V100;
-    vertexVec[ 1 ] = ID_V110;
-    break;
-  case ID_E0y1:
-    vertexVec[ 0 ] = ID_V001;
-    vertexVec[ 1 ] = ID_V011;
-    break;
-  case ID_E1y1:
-    vertexVec[ 0 ] = ID_V101;
-    vertexVec[ 1 ] = ID_V111;
-    break;
-
-  case ID_E00z:
-    vertexVec[ 0 ] = ID_V000;
-    vertexVec[ 1 ] = ID_V001;
-    break;
-  case ID_E10z:
-    vertexVec[ 0 ] = ID_V100;
-    vertexVec[ 1 ] = ID_V101;
-    break;
-  case ID_E01z:
-    vertexVec[ 0 ] = ID_V010;
-    vertexVec[ 1 ] = ID_V011;
-    break;
-  case ID_E11z:
-    vertexVec[ 0 ] = ID_V110;
-    vertexVec[ 1 ] = ID_V111;
-    break;
-  default:
-    vertexVec.resize(0);
-    MESSAGE(" GetEdgeVertexIDs(), wrong edge ID: " << edgeID );
-  }
-}
diff --git a/src/SMESH/SMESH_Block.hxx b/src/SMESH/SMESH_Block.hxx
deleted file mode 100644 (file)
index 20c1816..0000000
+++ /dev/null
@@ -1,387 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-// File      : SMESH_Block.hxx
-// Created   : Tue Nov 30 12:42:18 2004
-// Author    : Edward AGAPOV (eap)
-//
-#ifndef SMESH_Block_HeaderFile
-#define SMESH_Block_HeaderFile
-
-#include "SMESH_SMESH.hxx"
-
-//#include <Geom2d_Curve.hxx>
-//#include <Geom_Curve.hxx>
-//#include <Geom_Surface.hxx>
-
-#include <TopExp.hxx>
-#include <TopTools_IndexedMapOfOrientedShape.hxx>
-#include <TopoDS_Edge.hxx>
-#include <TopoDS_Face.hxx>
-#include <TopoDS_Shell.hxx>
-#include <TopoDS_Vertex.hxx>
-#include <gp_XY.hxx>
-#include <gp_XYZ.hxx>
-#include <math_FunctionSetWithDerivatives.hxx>
-
-#include <ostream>
-#include <vector>
-#include <list>
-
-class SMDS_MeshVolume;
-class SMDS_MeshNode;
-class Adaptor3d_Surface;
-class Adaptor2d_Curve2d;
-class Adaptor3d_Curve;
-class gp_Pnt;
-
-// =========================================================
-// class calculating coordinates of 3D points by normalized
-// parameters inside the block and vice versa
-// =========================================================
-
-class SMESH_EXPORT SMESH_Block: public math_FunctionSetWithDerivatives
-{
- public:
-  enum TShapeID {
-    // ----------------------------
-    // Ids of the block sub-shapes
-    // ----------------------------
-    ID_NONE = 0,
-
-    ID_V000 = 1, ID_V100, ID_V010, ID_V110, ID_V001, ID_V101, ID_V011, ID_V111,
-
-    ID_Ex00, ID_Ex10, ID_Ex01, ID_Ex11,
-    ID_E0y0, ID_E1y0, ID_E0y1, ID_E1y1,
-    ID_E00z, ID_E10z, ID_E01z, ID_E11z,
-
-    ID_Fxy0, ID_Fxy1, ID_Fx0z, ID_Fx1z, ID_F0yz, ID_F1yz,
-
-    ID_Shell
-    };
-  enum { // to use TShapeID for indexing certain type subshapes
-
-    ID_FirstV = ID_V000, ID_FirstE = ID_Ex00, ID_FirstF = ID_Fxy0
-
-  };
-
-
- public:
-  // -------------------------------------------------
-  // Block topology in terms of block sub-shapes' ids
-  // -------------------------------------------------
-
-  static int NbVertices()  { return  8; }
-  static int NbEdges()     { return 12; }
-  static int NbFaces()     { return  6; }
-  static int NbSubShapes() { return ID_Shell; }
-  // to avoid magic numbers when allocating memory for subshapes
-
-  static inline bool IsVertexID( int theShapeID )
-  { return ( theShapeID >= ID_V000 && theShapeID <= ID_V111 ); }
-
-  static inline bool IsEdgeID( int theShapeID )
-  { return ( theShapeID >= ID_Ex00 && theShapeID <= ID_E11z ); }
-
-  static inline bool IsFaceID( int theShapeID )
-  { return ( theShapeID >= ID_Fxy0 && theShapeID <= ID_F1yz ); }
-
-  static int ShapeIndex( int theShapeID )
-  {
-    if ( IsVertexID( theShapeID )) return theShapeID - ID_V000;
-    if ( IsEdgeID( theShapeID ))   return theShapeID - ID_Ex00;
-    if ( IsFaceID( theShapeID ))   return theShapeID - ID_Fxy0;
-    return 0;
-  }
-  // return index [0-...] for each type of sub-shapes,
-  // for example :
-  // ShapeIndex( ID_Ex00 ) == 0
-  // ShapeIndex( ID_Ex10 ) == 1
-
-  static void GetFaceEdgesIDs (const int faceID, std::vector< int >& edgeVec );
-  // return edges IDs of a face in the order u0, u1, 0v, 1v
-
-  static void GetEdgeVertexIDs (const int edgeID, std::vector< int >& vertexVec );
-  // return vertex IDs of an edge
-
-  static int GetCoordIndOnEdge (const int theEdgeID)
-  { return (theEdgeID < ID_E0y0) ? 1 : (theEdgeID < ID_E00z) ? 2 : 3; }
-  // return an index of a coordinate which varies along the edge
-
-  static double* GetShapeCoef (const int theShapeID);
-  // for theShapeID( TShapeID ), returns 3 coefficients used
-  // to compute an addition of an on-theShape point to coordinates
-  // of an in-shell point. If an in-shell point has parameters (Px,Py,Pz),
-  // then the addition of a point P is computed as P*kx*ky*kz and ki is
-  // defined by the returned coef like this:
-  // ki = (coef[i] == 0) ? 1 : (coef[i] < 0) ? 1 - Pi : Pi
-
-  static int GetShapeIDByParams ( const gp_XYZ& theParams );
-  // define an id of the block sub-shape by point parameters
-
-  static std::ostream& DumpShapeID (const int theBlockShapeID, std::ostream& stream);
-  // DEBUG: dump an id of a block sub-shape
-
-
- public:
-  // ---------------
-  // Initialization
-  // ---------------
-
-  SMESH_Block();
-
-  bool LoadBlockShapes(const TopoDS_Shell&         theShell,
-                       const TopoDS_Vertex&        theVertex000,
-                       const TopoDS_Vertex&        theVertex001,
-                       TopTools_IndexedMapOfOrientedShape& theShapeIDMap );
-  // Initialize block geometry with theShell,
-  // add sub-shapes of theBlock to theShapeIDMap so that they get
-  // IDs acoording to enum TShapeID
-
-  bool LoadBlockShapes(const TopTools_IndexedMapOfOrientedShape& theShapeIDMap);
-  // Initialize block geometry with shapes from theShapeIDMap
-
-  bool LoadMeshBlock(const SMDS_MeshVolume*        theVolume,
-                     const int                     theNode000Index,
-                     const int                     theNode001Index,
-                     std::vector<const SMDS_MeshNode*>& theOrderedNodes);
-  // prepare to work with theVolume and
-  // return nodes in theVolume corners in the order of TShapeID enum
-
-  bool LoadFace(const TopoDS_Face& theFace,
-                const int          theFaceID,
-                const TopTools_IndexedMapOfOrientedShape& theShapeIDMap);
-  // Load face geometry.
-  // It is enough to compute params or coordinates on the face.
-  // Face subshapes must be loaded into theShapeIDMap before
-
-  static bool Insert(const TopoDS_Shape& theShape,
-                     const int           theShapeID,
-                     TopTools_IndexedMapOfOrientedShape& theShapeIDMap);
-  // Insert theShape into theShapeIDMap with theShapeID,
-  // Not yet set shapes preceding theShapeID are filled with compounds
-  // Return true if theShape was successfully bound to theShapeID
-
-  static bool FindBlockShapes(const TopoDS_Shell&         theShell,
-                              const TopoDS_Vertex&        theVertex000,
-                              const TopoDS_Vertex&        theVertex001,
-                              TopTools_IndexedMapOfOrientedShape& theShapeIDMap );
-  // add sub-shapes of theBlock to theShapeIDMap so that they get
-  // IDs acoording to enum TShapeID
-
-public:
-  // ---------------------------------
-  // Define coordinates by parameters
-  // ---------------------------------
-
-  bool VertexPoint( const int theVertexID, gp_XYZ& thePoint ) const {
-    if ( !IsVertexID( theVertexID ))           return false;
-    thePoint = myPnt[ theVertexID - ID_FirstV ]; return true;
-  }
-  // return vertex coordinates, parameters are defined by theVertexID
-
-  bool EdgePoint( const int theEdgeID, const gp_XYZ& theParams, gp_XYZ& thePoint ) const {
-    if ( !IsEdgeID( theEdgeID ))                                 return false;
-    thePoint = myEdge[ theEdgeID - ID_FirstE ].Point( theParams ); return true;
-  }
-  // return coordinates of a point on edge
-
-  bool EdgeU( const int theEdgeID, const gp_XYZ& theParams, double& theU ) const {
-    if ( !IsEdgeID( theEdgeID ))                              return false;
-    theU = myEdge[ theEdgeID - ID_FirstE ].GetU( theParams ); return true;
-  }
-  // return parameter on edge by in-block parameters
-
-  bool FacePoint( const int theFaceID, const gp_XYZ& theParams, gp_XYZ& thePoint ) const {
-    if ( !IsFaceID ( theFaceID ))                                return false;
-    thePoint = myFace[ theFaceID - ID_FirstF ].Point( theParams ); return true;
-  }
-  // return coordinates of a point on face
-
-  bool FaceUV( const int theFaceID, const gp_XYZ& theParams, gp_XY& theUV ) const {
-    if ( !IsFaceID ( theFaceID ))                               return false;
-    theUV = myFace[ theFaceID - ID_FirstF ].GetUV( theParams ); return true;
-  }
-  // return UV coordinates on a face by in-block parameters
-
-  bool ShellPoint( const gp_XYZ& theParams, gp_XYZ& thePoint ) const;
-  // return coordinates of a point in shell
-
-  static bool ShellPoint(const gp_XYZ&         theParams,
-                         const std::vector<gp_XYZ>& thePointOnShape,
-                         gp_XYZ&               thePoint );
-  // computes coordinates of a point in shell by points on sub-shapes
-  // and point parameters.
-  // thePointOnShape[ subShapeID ] must be a point on a subShape;
-  // thePointOnShape.size() == ID_Shell, thePointOnShape[0] not used
-
-
- public:
-  // ---------------------------------
-  // Define parameters by coordinates
-  // ---------------------------------
-
-  bool ComputeParameters (const gp_Pnt& thePoint,
-                          gp_XYZ&       theParams,
-                          const int     theShapeID    = ID_Shell,
-                          const gp_XYZ& theParamsHint = gp_XYZ(-1,-1,-1));
-  // compute point parameters in the block.
-  // Note: for edges, it is better to use EdgeParameters()
-
-  bool VertexParameters(const int theVertexID, gp_XYZ& theParams);
-  // return parameters of a vertex given by TShapeID
-
-  bool EdgeParameters(const int theEdgeID, const double theU, gp_XYZ& theParams);
-  // return parameters of a point given by theU on edge
-
-
- public:
-  // ---------------
-  // Block geomerty
-  // ---------------
-
-  
-  
- public:
-  // ---------
-  // Services
-  // ---------
-
-  static bool IsForwardEdge (const TopoDS_Edge &                       theEdge,
-                             const TopTools_IndexedMapOfOrientedShape& theShapeIDMap) {
-    int v1ID = theShapeIDMap.FindIndex( TopExp::FirstVertex( theEdge ).Oriented( TopAbs_FORWARD ));
-    int v2ID = theShapeIDMap.FindIndex( TopExp::LastVertex( theEdge ).Oriented( TopAbs_FORWARD ));
-    return ( v1ID < v2ID );
-  }
-  // Return true if an in-block parameter increases along theEdge curve
-
-  static int GetOrderedEdges (const TopoDS_Face&        theFace,
-                              TopoDS_Vertex             theFirstVertex,
-                              std::list< TopoDS_Edge >& theEdges,
-                              std::list< int >  &       theNbVertexInWires);
-  // Return nb wires and a list of oredered edges.
-  // It is used to assign indices to subshapes.
-  // theFirstVertex may be NULL.
-  // Always try to set a seam edge first
-
- public:
-  // -----------------------------------------------------------
-  // Methods of math_FunctionSetWithDerivatives used internally
-  // to define parameters by coordinates
-  // -----------------------------------------------------------
-  Standard_Integer NbVariables() const;
-  Standard_Integer NbEquations() const;
-  Standard_Boolean Value(const math_Vector& X,math_Vector& F) ;
-  Standard_Boolean Derivatives(const math_Vector& X,math_Matrix& D) ;
-  Standard_Boolean Values(const math_Vector& X,math_Vector& F,math_Matrix& D) ;
-  Standard_Integer GetStateNumber ();
-
- protected:
-
-  /*!
-   * \brief Call it after geometry initialisation
-   */
-  void init();
-
-  // Note: to compute params of a point on a face, it is enough to set
-  // TFace, TEdge's and points for that face only
-
-  // Note 2: curve adaptors need to have only Value(double), FirstParameter() and
-  // LastParameter() defined to be used by Block algoritms
-
-  class SMESH_EXPORT TEdge {
-    int                myCoordInd;
-    double             myFirst;
-    double             myLast;
-    Adaptor3d_Curve*   myC3d;
-    // if mesh volume
-    gp_XYZ             myNodes[2];
-  public:
-    void Set( const int edgeID, Adaptor3d_Curve* curve, const bool isForward );
-    void Set( const int edgeID, const gp_XYZ& node1, const gp_XYZ& node2 );
-    Adaptor3d_Curve* GetCurve() const { return myC3d; }
-    double EndParam(int i) const { return i ? myLast : myFirst; }
-    int CoordInd() const { return myCoordInd; }
-    const gp_XYZ& NodeXYZ(int i) const { return i ? myNodes[1] : myNodes[0]; }
-    gp_XYZ Point( const gp_XYZ& theParams ) const; // Return coord by params
-    double GetU( const gp_XYZ& theParams ) const;  // Return U by params
-    TEdge(): myC3d(0) {}
-    ~TEdge();
-  };
-
-  class SMESH_EXPORT TFace {
-    // 4 edges in the order u0, u1, 0v, 1v
-    int                  myCoordInd[ 4 ];
-    double               myFirst   [ 4 ];
-    double               myLast    [ 4 ];
-    Adaptor2d_Curve2d*   myC2d     [ 4 ];
-    // 4 corner points in the order 00, 10, 11, 01
-    gp_XY                myCorner  [ 4 ];
-    // surface
-    Adaptor3d_Surface*   myS;
-    // if mesh volume
-    gp_XYZ               myNodes[4];
-  public:
-    void Set( const int faceID, Adaptor3d_Surface* S, // must be in GetFaceEdgesIDs() order:
-              Adaptor2d_Curve2d* c2d[4], const bool isForward[4] );
-    void Set( const int faceID, const TEdge& edgeU0, const TEdge& edgeU1 );
-    gp_XY  GetUV( const gp_XYZ& theParams ) const;
-    gp_XYZ Point( const gp_XYZ& theParams ) const;
-    int GetUInd() const { return myCoordInd[ 0 ]; }
-    int GetVInd() const { return myCoordInd[ 2 ]; }
-    void GetCoefs( int i, const gp_XYZ& theParams, double& eCoef, double& vCoef ) const;
-    TFace(): myS(0) { myC2d[0]=myC2d[1]=myC2d[2]=myC2d[3]=0; }
-    ~TFace();
-  };
-
-  // geometry in the order as in TShapeID:
-  // 8 vertices
-  gp_XYZ myPnt[ 8 ];
-  // 12 edges
-  TEdge  myEdge[ 12 ];
-  // 6 faces
-  TFace  myFace[ 6 ];
-
-  // for param computation
-
-  enum { SQUARE_DIST = 0, DRV_1, DRV_2, DRV_3 };
-  double distance () const { return sqrt( myValues[ SQUARE_DIST ]); }
-  double funcValue(double sqDist) const { return mySquareFunc ? sqDist : sqrt(sqDist); }
-  bool computeParameters(const gp_Pnt& thePoint, gp_XYZ& theParams, const gp_XYZ& theParamsHint);
-
-  int      myFaceIndex;
-  double   myFaceParam;
-  int      myNbIterations;
-  double   mySumDist;
-  double   myTolerance;
-  bool     mySquareFunc;
-
-  gp_XYZ   myPoint; // the given point
-  gp_XYZ   myParam; // the best parameters guess
-  double   myValues[ 4 ]; // values computed at myParam: square distance and 3 derivatives
-
-  typedef std::pair<gp_XYZ,gp_XYZ> TxyzPair;
-  TxyzPair my3x3x3GridNodes[ 27 ]; // to compute the first param guess
-  bool     myGridComputed;
-};
-
-
-#endif
diff --git a/src/SMESH/SMESH_Comment.hxx b/src/SMESH/SMESH_Comment.hxx
deleted file mode 100644 (file)
index 14d42fa..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-//  SMESH SMESH : implementaion of SMESH idl descriptions
-// File      : SMESH_Comment.hxx
-// Created   : Wed Mar 14 18:28:45 2007
-// Author    : Edward AGAPOV (eap)
-// Module    : SMESH
-// $Header: 
-//
-#ifndef SMESH_Comment_HeaderFile
-#define SMESH_Comment_HeaderFile
-
-# include <string>
-# include <sstream>
-
-using namespace std;
-
-/*!
- * \brief Class to generate string from any type
- */
-class SMESH_Comment : public string
-{
-  ostringstream _s ;
-
-public :
-
-  SMESH_Comment():string("") {}
-
-  SMESH_Comment(const SMESH_Comment& c):string() {
-    _s << c.c_str() ;
-    this->string::operator=( _s.str() );
-  }
-
-  template <class T>
-  SMESH_Comment( const T &anything ) {
-    _s << anything ;
-    this->string::operator=( _s.str() );
-  }
-
-  template <class T>
-  SMESH_Comment & operator<<( const T &anything ) {
-    _s << anything ;
-    this->string::operator=( _s.str() );
-    return *this ;
-  }
-};
-
-
-#endif
diff --git a/src/SMESH/SMESH_ComputeError.hxx b/src/SMESH/SMESH_ComputeError.hxx
deleted file mode 100644 (file)
index a764f0a..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-//  SMESH SMESH : implementaion of SMESH idl descriptions
-//  File   : SMESH_Hypothesis.hxx
-//  Author : Edward AGAPOV (eap)
-//  Module : SMESH
-//  $Header: 
-//
-#ifndef SMESH_ComputeError_HeaderFile
-#define SMESH_ComputeError_HeaderFile
-
-#include <string>
-#include <list>
-#include <boost/shared_ptr.hpp>
-
-class SMESH_Algo;
-class SMDS_MeshElement;
-struct SMESH_ComputeError;
-
-typedef boost::shared_ptr<SMESH_ComputeError> SMESH_ComputeErrorPtr;
-
-// =============================================================
-
-enum SMESH_ComputeErrorName
-{
-  // If you modify it, pls update SMESH_ComputeError::CommonName() below.
-  // Positive values are for algo specific errors
-  COMPERR_OK             = -1,
-  COMPERR_BAD_INPUT_MESH = -2,  //!< wrong mesh on lower submesh
-  COMPERR_STD_EXCEPTION  = -3,  //!< some std exception raised
-  COMPERR_OCC_EXCEPTION  = -4,  //!< OCC exception raised
-  COMPERR_SLM_EXCEPTION  = -5,  //!< SALOME exception raised
-  COMPERR_EXCEPTION      = -6,  //!< other exception raised
-  COMPERR_MEMORY_PB      = -7,  //!< std::bad_alloc exception
-  COMPERR_ALGO_FAILED    = -8,  //!< algo failed for some reason
-  COMPERR_BAD_SHAPE      = -9   //!< bad geometry
-};
-
-// =============================================================
-/*!
- * \brief Contains algorithm and description of occured error
- */
-// =============================================================
-
-struct SMESH_ComputeError
-{
-  int               myName; //!< SMESH_ComputeErrorName or anything algo specific
-  std::string       myComment;
-  const SMESH_Algo* myAlgo;
-
-  std::list<const SMDS_MeshElement*> myBadElements; //!< to explain COMPERR_BAD_INPUT_MESH
-
-  static SMESH_ComputeErrorPtr New( int               error   = COMPERR_OK,
-                                    std::string       comment = "",
-                                    const SMESH_Algo* algo    = 0)
-  { return SMESH_ComputeErrorPtr( new SMESH_ComputeError( error, comment, algo )); }
-
-  SMESH_ComputeError(int               error   = COMPERR_OK,
-                     std::string       comment = "",
-                     const SMESH_Algo* algo    = 0)
-    :myName(error),myComment(comment),myAlgo(algo) {}
-
-  bool IsOK()     { return myName == COMPERR_OK; }
-  bool IsCommon() { return myName < 0; }
-  inline std::string CommonName() const;
-
-};
-
-#define _case2char(err) case err: return #err;
-
-std::string SMESH_ComputeError::CommonName() const
-{
-  switch( myName ) {
-  _case2char(COMPERR_OK            );
-  _case2char(COMPERR_BAD_INPUT_MESH);
-  _case2char(COMPERR_STD_EXCEPTION );
-  _case2char(COMPERR_OCC_EXCEPTION );
-  _case2char(COMPERR_SLM_EXCEPTION );
-  _case2char(COMPERR_EXCEPTION     );
-  _case2char(COMPERR_MEMORY_PB     );
-  _case2char(COMPERR_ALGO_FAILED   );
-  default:;
-  }
-  return "";
-}
-
-#endif
diff --git a/src/SMESH/SMESH_DataMapOfElemPtrSequenceOfElemPtr.hxx b/src/SMESH/SMESH_DataMapOfElemPtrSequenceOfElemPtr.hxx
deleted file mode 100644 (file)
index 0ac60ca..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-// File:      SMESH_DataMapOfElemPtrSequenceOfElemPtr.hxx
-// Created:   26.09.05 17:41:10
-// Author:    Sergey KUUL
-//
-#ifndef SMESH_DataMapOfElemPtrSequenceOfElemPtr_HeaderFile
-#define SMESH_DataMapOfElemPtrSequenceOfElemPtr_HeaderFile
-
-#include "SMESH_SMESH.hxx"
-
-#include <SMESH_SequenceOfElemPtr.hxx>
-
-#include <NCollection_DefineDataMap.hxx>
-
-SMESH_EXPORT 
-inline Standard_Integer HashCode(SMDS_MeshElementPtr theElem,
-                                 const Standard_Integer theUpper)
-{
-  void* anElem = (void*) theElem;
-  return HashCode(anElem,theUpper);
-}
-
-SMESH_EXPORT 
-inline Standard_Boolean IsEqual(SMDS_MeshElementPtr theOne,
-                                SMDS_MeshElementPtr theTwo)
-{
-  return theOne == theTwo;
-}
-
-DEFINE_BASECOLLECTION (SMESH_BaseCollectionSequenceOfElemPtr, SMESH_SequenceOfElemPtr)
-DEFINE_DATAMAP (SMESH_DataMapOfElemPtrSequenceOfElemPtr,
-                SMESH_BaseCollectionSequenceOfElemPtr,
-                SMDS_MeshElementPtr, SMESH_SequenceOfElemPtr)
-#endif 
index 955e1335d1cad3cfc332aeb822780284fa8b6dff..dae945eec5e6b328942f1f362a686f9df6e1184b 100644 (file)
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : SMESH_Gen.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
+//
+
+//#define CHRONODEF
 
 #include "SMESH_Gen.hxx"
-#include "SMESH_subMesh.hxx"
-#include "SMESH_HypoFilter.hxx"
-#include "SMESHDS_Document.hxx"
+
+#include "SMDS_Mesh.hxx"
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
+#include "SMESHDS_Document.hxx"
+#include "SMESH_HypoFilter.hxx"
+#include "SMESH_MesherHelper.hxx"
+#include "SMESH_subMesh.hxx"
 
 #include "utilities.h"
 #include "OpUtil.hxx"
 #include "Utils_ExceptHandlers.hxx"
 
-#include <gp_Pnt.hxx>
-#include <BRep_Tool.hxx>
-#include <TopTools_ListOfShape.hxx>
-#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopoDS_Iterator.hxx>
+
+#include "memoire.h"
 
 using namespace std;
 
 //=============================================================================
 /*!
- *  default constructor:
+ *  Constructor
  */
 //=============================================================================
 
 SMESH_Gen::SMESH_Gen()
 {
-       MESSAGE("SMESH_Gen::SMESH_Gen");
-       _localId = 0;
-       _hypId = 0;
-        _segmentation = 10;
+        MESSAGE("SMESH_Gen::SMESH_Gen");
+        _localId = 0;
+        _hypId = 0;
+        _segmentation = _nbSegments = 10;
+        SMDS_Mesh::_meshList.clear();
+        MESSAGE(SMDS_Mesh::_meshList.size());
+        _counters = new counters(100);
+#ifdef WITH_SMESH_CANCEL_COMPUTE
+        _compute_canceled = false;
+        _sm_current = NULL;
+#endif
 }
 
 //=============================================================================
 /*!
- *
+ * Destructor
  */
 //=============================================================================
 
 SMESH_Gen::~SMESH_Gen()
 {
-       MESSAGE("SMESH_Gen::~SMESH_Gen");
+  MESSAGE("SMESH_Gen::~SMESH_Gen");
 }
 
 //=============================================================================
 /*!
- *
- */
-//=============================================================================
-
-/*SMESH_Hypothesis *SMESH_Gen::CreateHypothesis(const char *anHyp, int studyId)
-       throw(SALOME_Exception)
-{
-
-       MESSAGE("CreateHypothesis("<<anHyp<<","<<studyId<<")");
-       // Get studyContext, create it if it does'nt exist, with a SMESHDS_Document
-
-       StudyContextStruct *myStudyContext = GetStudyContext(studyId);
-
-       // create a new hypothesis object, store its ref. in studyContext
-
-       SMESH_Hypothesis *myHypothesis = _hypothesisFactory.Create(anHyp, studyId);
-       int hypId = myHypothesis->GetID();
-       myStudyContext->mapHypothesis[hypId] = myHypothesis;
-       SCRUTE(studyId);
-       SCRUTE(hypId);
-
-       // store hypothesis in SMESHDS document
-
-       myStudyContext->myDocument->AddHypothesis(myHypothesis);
-       return myHypothesis;
-}*/
-
-//=============================================================================
-/*!
- *
+ * Creates a mesh in a study.
+ * if (theIsEmbeddedMode) { mesh modification commands are not logged }
  */
 //=============================================================================
 
@@ -113,11 +98,11 @@ SMESH_Mesh* SMESH_Gen::CreateMesh(int theStudyId, bool theIsEmbeddedMode)
 
   // create a new SMESH_mesh object
   SMESH_Mesh *aMesh = new SMESH_Mesh(_localId++,
-                                    theStudyId,
-                                    this,
-                                    theIsEmbeddedMode,
-                                    aStudyContext->myDocument);
-  aStudyContext->mapMesh[_localId] = aMesh;
+                                     theStudyId,
+                                     this,
+                                     theIsEmbeddedMode,
+                                     aStudyContext->myDocument);
+  aStudyContext->mapMesh[_localId-1] = aMesh;
 
   return aMesh;
 }
@@ -131,10 +116,11 @@ SMESH_Mesh* SMESH_Gen::CreateMesh(int theStudyId, bool theIsEmbeddedMode)
 bool SMESH_Gen::Compute(SMESH_Mesh &          aMesh,
                         const TopoDS_Shape &  aShape,
                         const bool            anUpward,
-                       const ::MeshDimension aDim,
-                       TSetOfInt*            aShapesId)
+                        const ::MeshDimension aDim,
+                        TSetOfInt*            aShapesId)
 {
   MESSAGE("SMESH_Gen::Compute");
+  MEMOSTAT;
 
   bool ret = true;
 
@@ -142,13 +128,14 @@ bool SMESH_Gen::Compute(SMESH_Mesh &          aMesh,
 
   const bool includeSelf = true;
   const bool complexShapeFirst = true;
+  const int  globalAlgoDim = 100;
 
   SMESH_subMeshIteratorPtr smIt;
 
   if ( anUpward ) // is called from below code here
   {
     // -----------------------------------------------
-    // mesh all the subshapes starting from vertices
+    // mesh all the sub-shapes starting from vertices
     // -----------------------------------------------
     smIt = sm->getDependsOnIterator(includeSelf, !complexShapeFirst);
     while ( smIt->more() )
@@ -166,28 +153,47 @@ bool SMESH_Gen::Compute(SMESH_Mesh &          aMesh,
         // clear compute state to not show previous compute errors
         //  if preview invoked less dimension less than previous
         smToCompute->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
-       continue;
+        continue;
       }
 
       if (smToCompute->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE)
+      {
+#ifdef WITH_SMESH_CANCEL_COMPUTE
+        if (_compute_canceled)
+          return false;
+        _sm_current = smToCompute;
+#endif
         smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
+#ifdef WITH_SMESH_CANCEL_COMPUTE
+        _sm_current = NULL;
+#endif
+      }
 
       // we check all the submeshes here and detect if any of them failed to compute
       if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE)
         ret = false;
       else if ( aShapesId )
-       aShapesId->insert( smToCompute->GetId() );
+        aShapesId->insert( smToCompute->GetId() );
     }
+    //aMesh.GetMeshDS()->Modified();
     return ret;
   }
   else
   {
     // -----------------------------------------------------------------
-    // apply algos that DO NOT require descretized boundaries and DO NOT
+    // apply algos that DO NOT require Discreteized boundaries and DO NOT
     // support submeshes, starting from the most complex shapes
     // and collect submeshes with algos that DO support submeshes
     // -----------------------------------------------------------------
     list< SMESH_subMesh* > smWithAlgoSupportingSubmeshes;
+
+    // map to sort sm with same dim algos according to dim of
+    // the shape the algo assigned to (issue 0021217)
+    multimap< int, SMESH_subMesh* > shDim2sm;
+    multimap< int, SMESH_subMesh* >::reverse_iterator shDim2smIt;
+    TopoDS_Shape algoShape;
+    int prevShapeDim = -1;
+
     smIt = sm->getDependsOnIterator(includeSelf, complexShapeFirst);
     while ( smIt->more() )
     {
@@ -196,40 +202,87 @@ bool SMESH_Gen::Compute(SMESH_Mesh &          aMesh,
         continue;
 
       const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
-      const int aShapeDim = GetShapeDim( aSubShape );
+      int aShapeDim = GetShapeDim( aSubShape );
       if ( aShapeDim < 1 ) break;
       
       // check for preview dimension limitations
       if ( aShapesId && aShapeDim > (int)aDim )
-       continue;
+        continue;
 
-      SMESH_Algo* algo = GetAlgo( aMesh, aSubShape );
-      if ( algo && !algo->NeedDescretBoundary() )
+      SMESH_Algo* algo = GetAlgo( aMesh, aSubShape, &algoShape );
+      if ( algo && !algo->NeedDiscreteBoundary() )
       {
         if ( algo->SupportSubmeshes() )
-          smWithAlgoSupportingSubmeshes.push_back( smToCompute );
+        {
+          // reload sub-meshes from shDim2sm into smWithAlgoSupportingSubmeshes
+          // so that more local algos to go first
+          if ( prevShapeDim != aShapeDim )
+          {
+            prevShapeDim = aShapeDim;
+            for ( shDim2smIt = shDim2sm.rbegin(); shDim2smIt != shDim2sm.rend(); ++shDim2smIt )
+              if ( shDim2smIt->first == globalAlgoDim )
+                smWithAlgoSupportingSubmeshes.push_back( shDim2smIt->second );
+              else
+                smWithAlgoSupportingSubmeshes.push_front( shDim2smIt->second );
+            shDim2sm.clear();
+          }
+          // add smToCompute to shDim2sm map
+          if ( algoShape.IsSame( aMesh.GetShapeToMesh() ))
+          {
+            aShapeDim = globalAlgoDim; // to compute last
+          }
+          else
+          {
+            aShapeDim = GetShapeDim( algoShape );
+            if ( algoShape.ShapeType() == TopAbs_COMPOUND )
+            {
+              TopoDS_Iterator it( algoShape );
+              aShapeDim += GetShapeDim( it.Value() );
+            }
+          }
+          shDim2sm.insert( make_pair( aShapeDim, smToCompute ));
+        }
         else
-       {
+        {
+#ifdef WITH_SMESH_CANCEL_COMPUTE
+          if (_compute_canceled)
+            return false;
+          _sm_current = smToCompute;
+#endif
           smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
-         if ( aShapesId )
-           aShapesId->insert( smToCompute->GetId() );
-       }
+#ifdef WITH_SMESH_CANCEL_COMPUTE
+          _sm_current = NULL;
+#endif
+          if ( aShapesId )
+            aShapesId->insert( smToCompute->GetId() );
+        }
       }
     }
+    // reload sub-meshes from shDim2sm into smWithAlgoSupportingSubmeshes
+    for ( shDim2smIt = shDim2sm.rbegin(); shDim2smIt != shDim2sm.rend(); ++shDim2smIt )
+      if ( shDim2smIt->first == globalAlgoDim )
+        smWithAlgoSupportingSubmeshes.push_back( shDim2smIt->second );
+      else
+        smWithAlgoSupportingSubmeshes.push_front( shDim2smIt->second );
+
+    // ------------------------------------------------------------
+    // sort list of submeshes according to mesh order
+    // ------------------------------------------------------------
+    aMesh.SortByMeshOrder( smWithAlgoSupportingSubmeshes );
+
     // ------------------------------------------------------------
     // compute submeshes under shapes with algos that DO NOT require
-    // descretized boundaries and DO support submeshes
+    // Discreteized boundaries and DO support submeshes
     // ------------------------------------------------------------
-    list< SMESH_subMesh* >::reverse_iterator subIt, subEnd;
-    subIt  = smWithAlgoSupportingSubmeshes.rbegin();
-    subEnd = smWithAlgoSupportingSubmeshes.rend();
+    list< SMESH_subMesh* >::iterator subIt, subEnd;
+    subIt  = smWithAlgoSupportingSubmeshes.begin();
+    subEnd = smWithAlgoSupportingSubmeshes.end();
     // start from lower shapes
     for ( ; subIt != subEnd; ++subIt )
     {
       sm = *subIt;
 
       // get a shape the algo is assigned to
-      TopoDS_Shape algoShape;
       if ( !GetAlgo( aMesh, sm->GetSubShape(), & algoShape ))
         continue; // strange...
 
@@ -240,18 +293,18 @@ bool SMESH_Gen::Compute(SMESH_Mesh &          aMesh,
         SMESH_subMesh* smToCompute = smIt->next();
 
         const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
-       const int aShapeDim = GetShapeDim( aSubShape );
+        const int aShapeDim = GetShapeDim( aSubShape );
         //if ( aSubShape.ShapeType() == TopAbs_VERTEX ) continue;
-       if ( aShapeDim < 1 ) continue;
+        if ( aShapeDim < 1 ) continue;
 
-       // check for preview dimension limitations
-       if ( aShapesId && GetShapeDim( aSubShape.ShapeType() ) > (int)aDim )
-         continue;
-       
+        // check for preview dimension limitations
+        if ( aShapesId && GetShapeDim( aSubShape.ShapeType() ) > (int)aDim )
+          continue;
+        
         SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() );
         filter
           .And( SMESH_HypoFilter::IsApplicableTo( aSubShape ))
-          .And( SMESH_HypoFilter::IsMoreLocalThan( algoShape ));
+          .And( SMESH_HypoFilter::IsMoreLocalThan( algoShape, aMesh ));
 
         if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( aSubShape, filter, true )) {
           SMESH_Hypothesis::Hypothesis_Status status;
@@ -262,31 +315,239 @@ bool SMESH_Gen::Compute(SMESH_Mesh &          aMesh,
       }
     }
     // ----------------------------------------------------------
-    // apply the algos that do not require descretized boundaries
+    // apply the algos that do not require Discreteized boundaries
     // ----------------------------------------------------------
-    for ( subIt = smWithAlgoSupportingSubmeshes.rbegin(); subIt != subEnd; ++subIt )
+    for ( subIt = smWithAlgoSupportingSubmeshes.begin(); subIt != subEnd; ++subIt )
+    {
+      sm = *subIt;
       if ( sm->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE)
       {
-       const TopAbs_ShapeEnum aShType = sm->GetSubShape().ShapeType();
-       // check for preview dimension limitations
-       if ( aShapesId && GetShapeDim( aShType ) > (int)aDim )
-         continue;
-
+        const TopAbs_ShapeEnum aShType = sm->GetSubShape().ShapeType();
+        // check for preview dimension limitations
+        if ( aShapesId && GetShapeDim( aShType ) > (int)aDim )
+          continue;
+
+#ifdef WITH_SMESH_CANCEL_COMPUTE
+        if (_compute_canceled)
+          return false;
+        _sm_current = sm;
+#endif
         sm->ComputeStateEngine( SMESH_subMesh::COMPUTE );
-       if ( aShapesId )
-         aShapesId->insert( sm->GetId() );
+#ifdef WITH_SMESH_CANCEL_COMPUTE
+        _sm_current = NULL;
+#endif
+        if ( aShapesId )
+          aShapesId->insert( sm->GetId() );
       }
-
+    }
     // -----------------------------------------------
-    // mesh the rest subshapes starting from vertices
+    // mesh the rest sub-shapes starting from vertices
     // -----------------------------------------------
     ret = Compute( aMesh, aShape, /*anUpward=*/true, aDim, aShapesId );
   }
 
   MESSAGE( "VSR - SMESH_Gen::Compute() finished, OK = " << ret);
+  MEMOSTAT;
+
+  SMESHDS_Mesh *myMesh = aMesh.GetMeshDS();
+  myMesh->adjustStructure();
+  MESSAGE("*** compactMesh after compute");
+  myMesh->compactMesh();
+  //myMesh->adjustStructure();
+  list<int> listind = myMesh->SubMeshIndices();
+  list<int>::iterator it = listind.begin();
+  int total = 0;
+  for(; it != listind.end(); ++it)
+    {
+      ::SMESHDS_SubMesh *subMesh = myMesh->MeshElements(*it);
+      total +=  subMesh->getSize();
+    }
+  MESSAGE("total elements and nodes in submesh sets:" << total);
+  MESSAGE("Number of node objects " << SMDS_MeshNode::nbNodes);
+  MESSAGE("Number of cell objects " << SMDS_MeshCell::nbCells);
+  //myMesh->dumpGrid();
+  //aMesh.GetMeshDS()->Modified();
+
+  // fix quadratic mesh by bending iternal links near concave boundary
+  if ( aShape.IsSame( aMesh.GetShapeToMesh() ) &&
+       !aShapesId ) // not preview
+  {
+    SMESH_MesherHelper aHelper( aMesh );
+    if ( aHelper.IsQuadraticMesh() != SMESH_MesherHelper::LINEAR )
+      aHelper.FixQuadraticElements();
+  }
+  return ret;
+}
+
+
+#ifdef WITH_SMESH_CANCEL_COMPUTE
+//=============================================================================
+/*!
+ * Prepare Compute a mesh
+ */
+//=============================================================================
+void SMESH_Gen::PrepareCompute(SMESH_Mesh &          aMesh,
+                               const TopoDS_Shape &  aShape)
+{
+  _compute_canceled = false;
+  _sm_current = NULL;
+}
+//=============================================================================
+/*!
+ * Cancel Compute a mesh
+ */
+//=============================================================================
+void SMESH_Gen::CancelCompute(SMESH_Mesh &          aMesh,
+                              const TopoDS_Shape &  aShape)
+{
+  _compute_canceled = true;
+  if(_sm_current)
+    {
+      _sm_current->ComputeStateEngine( SMESH_subMesh::COMPUTE_CANCELED );
+    }
+}
+#endif
+
+//=============================================================================
+/*!
+ * Evaluate a mesh
+ */
+//=============================================================================
+
+bool SMESH_Gen::Evaluate(SMESH_Mesh &          aMesh,
+                         const TopoDS_Shape &  aShape,
+                         MapShapeNbElems&      aResMap,
+                         const bool            anUpward,
+                         TSetOfInt*            aShapesId)
+{
+  MESSAGE("SMESH_Gen::Evaluate");
+
+  bool ret = true;
+
+  SMESH_subMesh *sm = aMesh.GetSubMesh(aShape);
+
+  const bool includeSelf = true;
+  const bool complexShapeFirst = true;
+  SMESH_subMeshIteratorPtr smIt;
+
+  if ( anUpward ) { // is called from below code here
+    // -----------------------------------------------
+    // mesh all the sub-shapes starting from vertices
+    // -----------------------------------------------
+    smIt = sm->getDependsOnIterator(includeSelf, !complexShapeFirst);
+    while ( smIt->more() ) {
+      SMESH_subMesh* smToCompute = smIt->next();
+
+      // do not mesh vertices of a pseudo shape
+      const TopAbs_ShapeEnum aShType = smToCompute->GetSubShape().ShapeType();
+      //if ( !aMesh.HasShapeToMesh() && aShType == TopAbs_VERTEX )
+      //  continue;
+      if ( !aMesh.HasShapeToMesh() ) {
+        if( aShType == TopAbs_VERTEX || aShType == TopAbs_WIRE ||
+            aShType == TopAbs_SHELL )
+          continue;
+      }
+
+      smToCompute->Evaluate(aResMap);
+      if( aShapesId )
+        aShapesId->insert( smToCompute->GetId() );
+    }
+    return ret;
+  }
+  else {
+    // -----------------------------------------------------------------
+    // apply algos that DO NOT require Discreteized boundaries and DO NOT
+    // support submeshes, starting from the most complex shapes
+    // and collect submeshes with algos that DO support submeshes
+    // -----------------------------------------------------------------
+    list< SMESH_subMesh* > smWithAlgoSupportingSubmeshes;
+    smIt = sm->getDependsOnIterator(includeSelf, complexShapeFirst);
+    while ( smIt->more() ) {
+      SMESH_subMesh* smToCompute = smIt->next();
+      const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
+      const int aShapeDim = GetShapeDim( aSubShape );
+      if ( aShapeDim < 1 ) break;
+      
+      SMESH_Algo* algo = GetAlgo( aMesh, aSubShape );
+      if ( algo && !algo->NeedDiscreteBoundary() ) {
+        if ( algo->SupportSubmeshes() ) {
+          smWithAlgoSupportingSubmeshes.push_front( smToCompute );
+        }
+        else {
+          smToCompute->Evaluate(aResMap);
+          if ( aShapesId )
+            aShapesId->insert( smToCompute->GetId() );
+        }
+      }
+    }
+
+    // ------------------------------------------------------------
+    // sort list of meshes according to mesh order
+    // ------------------------------------------------------------
+    aMesh.SortByMeshOrder( smWithAlgoSupportingSubmeshes );
+
+    // ------------------------------------------------------------
+    // compute submeshes under shapes with algos that DO NOT require
+    // Discreteized boundaries and DO support submeshes
+    // ------------------------------------------------------------
+    list< SMESH_subMesh* >::iterator subIt, subEnd;
+    subIt  = smWithAlgoSupportingSubmeshes.begin();
+    subEnd = smWithAlgoSupportingSubmeshes.end();
+    // start from lower shapes
+    for ( ; subIt != subEnd; ++subIt ) {
+      sm = *subIt;
+
+      // get a shape the algo is assigned to
+      TopoDS_Shape algoShape;
+      if ( !GetAlgo( aMesh, sm->GetSubShape(), & algoShape ))
+        continue; // strange...
+
+      // look for more local algos
+      smIt = sm->getDependsOnIterator(!includeSelf, !complexShapeFirst);
+      while ( smIt->more() ) {
+        SMESH_subMesh* smToCompute = smIt->next();
+
+        const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
+        const int aShapeDim = GetShapeDim( aSubShape );
+        if ( aShapeDim < 1 ) continue;
+
+        //const TopAbs_ShapeEnum aShType = smToCompute->GetSubShape().ShapeType();
+
+        SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() );
+        filter
+          .And( SMESH_HypoFilter::IsApplicableTo( aSubShape ))
+          .And( SMESH_HypoFilter::IsMoreLocalThan( algoShape, aMesh ));
+
+        if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( aSubShape, filter, true )) {
+          SMESH_Hypothesis::Hypothesis_Status status;
+          if ( subAlgo->CheckHypothesis( aMesh, aSubShape, status ))
+            // mesh a lower smToCompute starting from vertices
+            Evaluate( aMesh, aSubShape, aResMap, /*anUpward=*/true, aShapesId );
+        }
+      }
+    }
+    // ----------------------------------------------------------
+    // apply the algos that do not require Discreteized boundaries
+    // ----------------------------------------------------------
+    for ( subIt = smWithAlgoSupportingSubmeshes.begin(); subIt != subEnd; ++subIt )
+    {
+      sm = *subIt;
+      sm->Evaluate(aResMap);
+      if ( aShapesId )
+        aShapesId->insert( sm->GetId() );
+    }
+
+    // -----------------------------------------------
+    // mesh the rest sub-shapes starting from vertices
+    // -----------------------------------------------
+    ret = Evaluate( aMesh, aShape, aResMap, /*anUpward=*/true, aShapesId );
+  }
+
+  MESSAGE( "VSR - SMESH_Gen::Evaluate() finished, OK = " << ret);
   return ret;
 }
 
+
 //=======================================================================
 //function : checkConformIgnoredAlgos
 //purpose  :
@@ -297,7 +558,7 @@ static bool checkConformIgnoredAlgos(SMESH_Mesh&               aMesh,
                                      const SMESH_Algo*         aGlobIgnoAlgo,
                                      const SMESH_Algo*         aLocIgnoAlgo,
                                      bool &                    checkConform,
-                                     map<int, SMESH_subMesh*>& aCheckedMap,
+                                     set<SMESH_subMesh*>&      aCheckedMap,
                                      list< SMESH_Gen::TAlgoStateError > & theErrors)
 {
   ASSERT( aSubMesh );
@@ -337,7 +598,7 @@ static bool checkConformIgnoredAlgos(SMESH_Mesh&               aMesh,
               << " <" << algo->GetName() << "> is hidden by global <"
               << aGlobIgnoAlgo->GetName() << ">");
       }
-      else if ( !algo->NeedDescretBoundary() && !isGlobal)
+      else if ( !algo->NeedDiscreteBoundary() && !isGlobal)
       {
         // local algo is not hidden and hides algos on sub-shapes
         if (checkConform && !aSubMesh->IsConform( algo ))
@@ -352,19 +613,15 @@ static bool checkConformIgnoredAlgos(SMESH_Mesh&               aMesh,
         }
 
         // sub-algos will be hidden by a local <algo>
-        const map<int, SMESH_subMesh*>& smMap = aSubMesh->DependsOn();
-        map<int, SMESH_subMesh*>::const_reverse_iterator revItSub;
+        SMESH_subMeshIteratorPtr revItSub =
+          aSubMesh->getDependsOnIterator( /*includeSelf=*/false, /*complexShapeFirst=*/true);
         bool checkConform2 = false;
-        for ( revItSub = smMap.rbegin(); revItSub != smMap.rend(); revItSub++)
+        while ( revItSub->more() )
         {
-          checkConformIgnoredAlgos (aMesh, (*revItSub).second, aGlobIgnoAlgo,
+          SMESH_subMesh* sm = revItSub->next();
+          checkConformIgnoredAlgos (aMesh, sm, aGlobIgnoAlgo,
                                     algo, checkConform2, aCheckedMap, theErrors);
-          int key = (*revItSub).first;
-         SMESH_subMesh* sm = (*revItSub).second;
-          if ( aCheckedMap.find( key ) == aCheckedMap.end() )
-          {
-            aCheckedMap[ key ] = sm;
-          }
+          aCheckedMap.insert( sm );
         }
       }
     }
@@ -385,7 +642,7 @@ static bool checkMissing(SMESH_Gen*                aGen,
                          const int                 aTopAlgoDim,
                          bool*                     globalChecked,
                          const bool                checkNoAlgo,
-                         map<int, SMESH_subMesh*>& aCheckedMap,
+                         set<SMESH_subMesh*>&      aCheckedMap,
                          list< SMESH_Gen::TAlgoStateError > & theErrors)
 {
   if ( aSubMesh->GetSubShape().ShapeType() == TopAbs_VERTEX)
@@ -455,18 +712,16 @@ static bool checkMissing(SMESH_Gen*                aGen,
   ASSERT (algo);
   bool isTopLocalAlgo =
     ( aTopAlgoDim <= algo->GetDim() && !aGen->IsGlobalHypothesis( algo, aMesh ));
-  if (!algo->NeedDescretBoundary() || isTopLocalAlgo)
+  if (!algo->NeedDiscreteBoundary() || isTopLocalAlgo)
   {
-    bool checkNoAlgo2 = ( algo->NeedDescretBoundary() );
-    const map<int, SMESH_subMesh*>& subMeshes = aSubMesh->DependsOn();
-    map<int, SMESH_subMesh*>::const_iterator itsub;
-    for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
+    bool checkNoAlgo2 = ( algo->NeedDiscreteBoundary() );
+    SMESH_subMeshIteratorPtr itsub = aSubMesh->getDependsOnIterator( /*includeSelf=*/false,
+                                                                     /*complexShapeFirst=*/false);
+    while ( itsub->more() )
     {
       // sub-meshes should not be checked further more
-      int key = (*itsub).first;
-      SMESH_subMesh* sm = (*itsub).second;
-      if ( aCheckedMap.find( key ) == aCheckedMap.end() )
-        aCheckedMap[ key ] = sm;
+      SMESH_subMesh* sm = itsub->next();
+      aCheckedMap.insert( sm );
 
       if (isTopLocalAlgo)
       {
@@ -542,7 +797,7 @@ bool SMESH_Gen::GetAlgoState(SMESH_Mesh&               theMesh,
 
   // --------------------------------------------------------
   // info on algos that will be ignored because of ones that
-  // don't NeedDescretBoundary() attached to super-shapes,
+  // don't NeedDiscreteBoundary() attached to super-shapes,
   // check that a conform mesh will be produced
   // --------------------------------------------------------
 
@@ -553,46 +808,32 @@ bool SMESH_Gen::GetAlgoState(SMESH_Mesh&               theMesh,
   for (dim = 3; dim > 0; dim--)
   {
     if (aGlobAlgoArr[ dim ] &&
-        !aGlobAlgoArr[ dim ]->NeedDescretBoundary())
+        !aGlobAlgoArr[ dim ]->NeedDiscreteBoundary())
     {
       aGlobIgnoAlgo = aGlobAlgoArr[ dim ];
       break;
     }
   }
 
-  const map<int, SMESH_subMesh*>& smMap = sm->DependsOn();
-  map<int, SMESH_subMesh*>::const_reverse_iterator revItSub = smMap.rbegin();
-  map<int, SMESH_subMesh*> aCheckedMap;
+  set<SMESH_subMesh*> aCheckedSubs;
   bool checkConform = ( !theMesh.IsNotConformAllowed() );
-  int aKey = 1;
-  SMESH_subMesh* smToCheck = sm;
 
   // loop on theShape and its sub-shapes
-  while ( smToCheck )
+  SMESH_subMeshIteratorPtr revItSub = sm->getDependsOnIterator( /*includeSelf=*/true,
+                                                                /*complexShapeFirst=*/true);
+  while ( revItSub->more() )
   {
+    SMESH_subMesh* smToCheck = revItSub->next();
     if ( smToCheck->GetSubShape().ShapeType() == TopAbs_VERTEX)
       break;
 
-    if ( aCheckedMap.find( aKey ) == aCheckedMap.end() )
+    if ( aCheckedSubs.insert( smToCheck ).second ) // not yet checked
       if (!checkConformIgnoredAlgos (theMesh, smToCheck, aGlobIgnoAlgo,
-                                     0, checkConform, aCheckedMap, theErrors))
+                                     0, checkConform, aCheckedSubs, theErrors))
         ret = false;
 
     if ( smToCheck->GetAlgoState() != SMESH_subMesh::NO_ALGO )
       hasAlgo = true;
-
-    // next subMesh
-    if (revItSub != smMap.rend())
-    {
-      aKey = (*revItSub).first;
-      smToCheck = (*revItSub).second;
-      revItSub++;
-    }
-    else
-    {
-      smToCheck = 0;
-    }
-
   }
 
   // ----------------------------------------------------------------
@@ -612,36 +853,26 @@ bool SMESH_Gen::GetAlgoState(SMESH_Mesh&               theMesh,
       break;
     }
   }
-  aCheckedMap.clear();
-  smToCheck = sm;
-  revItSub = smMap.rbegin();
   bool checkNoAlgo = theMesh.HasShapeToMesh() ? bool( aTopAlgoDim ) : false;
   bool globalChecked[] = { false, false, false, false };
 
   // loop on theShape and its sub-shapes
-  while ( smToCheck )
+  aCheckedSubs.clear();
+  revItSub = sm->getDependsOnIterator( /*includeSelf=*/true, /*complexShapeFirst=*/true);
+  while ( revItSub->more() )
   {
+    SMESH_subMesh* smToCheck = revItSub->next();
     if ( smToCheck->GetSubShape().ShapeType() == TopAbs_VERTEX)
       break;
 
-    if ( aCheckedMap.find( aKey ) == aCheckedMap.end() )
+    if ( aCheckedSubs.insert( smToCheck ).second ) // not yet checked
       if (!checkMissing (this, theMesh, smToCheck, aTopAlgoDim,
-                         globalChecked, checkNoAlgo, aCheckedMap, theErrors))
+                         globalChecked, checkNoAlgo, aCheckedSubs, theErrors))
       {
         ret = false;
         if (smToCheck->GetAlgoState() == SMESH_subMesh::NO_ALGO )
           checkNoAlgo = false;
       }
-
-    // next subMesh
-    if (revItSub != smMap.rend())
-    {
-      aKey = (*revItSub).first;
-      smToCheck = (*revItSub).second;
-      revItSub++;
-    }
-    else
-      smToCheck = 0;
   }
 
   if ( !hasAlgo ) {
@@ -667,7 +898,7 @@ bool SMESH_Gen::IsGlobalHypothesis(const SMESH_Hypothesis* theHyp, SMESH_Mesh& a
 
 //=============================================================================
 /*!
- *
+ * Finds algo to mesh a shape. Optionally returns a shape the found algo is bound to
  */
 //=============================================================================
 
@@ -675,7 +906,6 @@ SMESH_Algo *SMESH_Gen::GetAlgo(SMESH_Mesh &         aMesh,
                                const TopoDS_Shape & aShape,
                                TopoDS_Shape*        assignedTo)
 {
-
   SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() );
   filter.And( filter.IsApplicableTo( aShape ));
 
@@ -684,59 +914,28 @@ SMESH_Algo *SMESH_Gen::GetAlgo(SMESH_Mesh &         aMesh,
 
 //=============================================================================
 /*!
- *
+ * Returns StudyContextStruct for a study
  */
 //=============================================================================
 
 StudyContextStruct *SMESH_Gen::GetStudyContext(int studyId)
 {
-       // Get studyContext, create it if it does'nt exist, with a SMESHDS_Document
-
-       if (_mapStudyContext.find(studyId) == _mapStudyContext.end())
-       {
-               _mapStudyContext[studyId] = new StudyContextStruct;
-               _mapStudyContext[studyId]->myDocument = new SMESHDS_Document(studyId);
-       }
-       StudyContextStruct *myStudyContext = _mapStudyContext[studyId];
-//   ASSERT(_mapStudyContext.find(studyId) != _mapStudyContext.end());
-       return myStudyContext;
-}
-
-// //=============================================================================
-// /*!
-//  *
-//  */
-// //=============================================================================
-
-// void SMESH_Gen::Save(int studyId, const char *aUrlOfFile)
-// {
-// }
-
-// //=============================================================================
-// /*!
-//  *
-//  */
-// //=============================================================================
-
-// void SMESH_Gen::Load(int studyId, const char *aUrlOfFile)
-// {
-// }
-
-// //=============================================================================
-// /*!
-//  *
-//  */
-// //=============================================================================
+  // Get studyContext, create it if it does'nt exist, with a SMESHDS_Document
 
-// void SMESH_Gen::Close(int studyId)
-// {
-// }
+  if (_mapStudyContext.find(studyId) == _mapStudyContext.end())
+  {
+    _mapStudyContext[studyId] = new StudyContextStruct;
+    _mapStudyContext[studyId]->myDocument = new SMESHDS_Document(studyId);
+  }
+  StudyContextStruct *myStudyContext = _mapStudyContext[studyId];
+  return myStudyContext;
+}
 
-//=============================================================================
+//================================================================================
 /*!
- *
+ * \brief Return shape dimension by TopAbs_ShapeEnum
  */
-//=============================================================================
+//================================================================================
 
 int SMESH_Gen::GetShapeDim(const TopAbs_ShapeEnum & aShapeType)
 {
@@ -747,7 +946,7 @@ int SMESH_Gen::GetShapeDim(const TopAbs_ShapeEnum & aShapeType)
     dim[ TopAbs_COMPOUND ]  = MeshDim_3D;
     dim[ TopAbs_COMPSOLID ] = MeshDim_3D;
     dim[ TopAbs_SOLID ]     = MeshDim_3D;
-    dim[ TopAbs_SHELL ]     = MeshDim_3D;
+    dim[ TopAbs_SHELL ]     = MeshDim_2D;
     dim[ TopAbs_FACE  ]     = MeshDim_2D;
     dim[ TopAbs_WIRE ]      = MeshDim_1D;
     dim[ TopAbs_EDGE ]      = MeshDim_1D;
@@ -758,12 +957,11 @@ int SMESH_Gen::GetShapeDim(const TopAbs_ShapeEnum & aShapeType)
 
 //=============================================================================
 /*!
- *
+ * Genarate a new id unique withing this Gen
  */
 //=============================================================================
 
 int SMESH_Gen::GetANewId()
 {
-       //MESSAGE("SMESH_Gen::GetANewId");
-       return _hypId++;
+  return _hypId++;
 }
index 46c00dc2c9ff6ae9c69e495b12de89e1c17e0f67..353cba6df6c66568b8e0dac8dc3413d02581d51c 100644 (file)
@@ -1,30 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : SMESH_Gen.hxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
 //
-
 #ifndef _SMESH_GEN_HXX_
 #define _SMESH_GEN_HXX_
 
@@ -41,6 +41,8 @@
 #include "SMESH_3D_Algo.hxx"
 #include "SMESH_Mesh.hxx"
 
+#include "chrono.hxx"
+
 #include <TopoDS_Shape.hxx>
 
 #include <map>
@@ -61,7 +63,7 @@ typedef std::set<int> TSetOfInt;
 
 class SMESH_EXPORT  SMESH_Gen
 {
- public:
+public:
   SMESH_Gen();
   ~SMESH_Gen();
 
@@ -78,8 +80,28 @@ class SMESH_EXPORT  SMESH_Gen
   bool Compute(::SMESH_Mesh &        aMesh,
                const TopoDS_Shape &  aShape,
                const bool            anUpward=false,
-              const ::MeshDimension aDim=::MeshDim_3D,
-              TSetOfInt*            aShapesId=0);
+               const ::MeshDimension aDim=::MeshDim_3D,
+               TSetOfInt*            aShapesId=0);
+
+#ifdef WITH_SMESH_CANCEL_COMPUTE
+  void PrepareCompute(::SMESH_Mesh &        aMesh,
+                      const TopoDS_Shape &  aShape);
+  void CancelCompute(::SMESH_Mesh &        aMesh,
+                     const TopoDS_Shape &  aShape);
+#endif
+
+  /*!
+   * \brief evaluates size of prospective mesh on a shape 
+   * \param aMesh - the mesh
+   * \param aShape - the shape
+   * \param aResMap - map for prospective numbers of elements
+   * \retval bool - is a success
+   */
+  bool Evaluate(::SMESH_Mesh &        aMesh,
+                const TopoDS_Shape &  aShape,
+                MapShapeNbElems&      aResMap,
+                const bool            anUpward=false,
+                TSetOfInt*            aShapesId=0);
 
   bool CheckAlgoState(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
   // notify on bad state of attached algos, return false
@@ -96,7 +118,7 @@ class SMESH_EXPORT  SMESH_Gen
    */
   void SetDefaultNbSegments(int nb) { _nbSegments = nb; }
   int GetDefaultNbSegments() const { return _nbSegments; }
-  
+
   struct TAlgoStateError
   {
     TAlgoStateErrorName _name;
@@ -125,16 +147,6 @@ class SMESH_EXPORT  SMESH_Gen
   SMESH_Algo* GetAlgo(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, TopoDS_Shape* assignedTo=0);
   static bool IsGlobalHypothesis(const SMESH_Hypothesis* theHyp, SMESH_Mesh& aMesh);
 
-  // inherited methods from SALOMEDS::Driver
-
-//   void Save(int studyId, const char *aUrlOfFile);
-//   void Load(int studyId, const char *aUrlOfFile);
-//   void Close(int studyId);
-//   const char *ComponentDataType();
-
-//   const char *IORToLocalPersistentID(const char *IORString, bool & IsAFile);
-//   const char *LocalPersistentIDToIOR(const char *aLocalPersistentID);
-
   int GetANewId();
 
   std::map < int, SMESH_Algo * >_mapAlgo;
@@ -143,9 +155,9 @@ class SMESH_EXPORT  SMESH_Gen
   std::map < int, SMESH_2D_Algo * >_map2D_Algo;
   std::map < int, SMESH_3D_Algo * >_map3D_Algo;
 
- private:
+private:
 
-  int _localId;                                // unique Id of created objects, within SMESH_Gen entity
+  int _localId;                         // unique Id of created objects, within SMESH_Gen entity
   std::map < int, StudyContextStruct * >_mapStudyContext;
 
   // hypotheses managing
@@ -156,6 +168,12 @@ class SMESH_EXPORT  SMESH_Gen
   int _segmentation;
   // default of segments
   int _nbSegments;
+  counters *_counters;
+
+#ifdef WITH_SMESH_CANCEL_COMPUTE
+  volatile bool _compute_canceled;
+  SMESH_subMesh* _sm_current;
+#endif
 };
 
 #endif
index a05204d31f333a490cf3ca1a0f9311b47b17689d..7ef568593a2f492f535a7fb6a1b0934fa444a11f 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : SMESH_Group.cxx
 //  Author : Michael Sazonov (OCC)
@@ -29,6 +30,7 @@
 #include "SMESH_Mesh.hxx"
 #include "SMESHDS_Group.hxx"
 #include "SMESHDS_GroupOnGeom.hxx"
+#include "SMESHDS_GroupOnFilter.hxx"
 
 //=============================================================================
 /*!
@@ -40,18 +42,36 @@ SMESH_Group::SMESH_Group (int                       theID,
                           const SMESH_Mesh*         theMesh,
                           const SMDSAbs_ElementType theType,
                           const char*               theName,
-                          const TopoDS_Shape&       theShape)
+                          const TopoDS_Shape&       theShape,
+                          const SMESH_PredicatePtr& thePredicate)
      : myName(theName)
 {
-  if ( theShape.IsNull() )
-    myGroupDS = new SMESHDS_Group (theID,
-                                   const_cast<SMESH_Mesh*>(theMesh)->GetMeshDS(),
-                                   theType);
-  else
+  if ( !theShape.IsNull() )
     myGroupDS = new SMESHDS_GroupOnGeom (theID,
                                          const_cast<SMESH_Mesh*>(theMesh)->GetMeshDS(),
                                          theType,
                                          theShape);
+  else if ( thePredicate )
+    myGroupDS = new SMESHDS_GroupOnFilter (theID,
+                                           const_cast<SMESH_Mesh*>(theMesh)->GetMeshDS(),
+                                           theType,
+                                           thePredicate);
+  else
+    myGroupDS = new SMESHDS_Group (theID,
+                                   const_cast<SMESH_Mesh*>(theMesh)->GetMeshDS(),
+                                   theType);
+}
+
+//================================================================================
+/*!
+ * \brief Constructor accesible to SMESH_Mesh only
+ */
+//================================================================================
+
+SMESH_Group::SMESH_Group (SMESHDS_GroupBase* groupDS): myGroupDS( groupDS )
+{
+  if ( myGroupDS )
+    myName = myGroupDS->GetStoreName();
 }
 
 //=============================================================================
@@ -62,5 +82,5 @@ SMESH_Group::SMESH_Group (int                       theID,
 
 SMESH_Group::~SMESH_Group ()
 {
-  delete myGroupDS;
+  delete myGroupDS; myGroupDS=0;
 }
index ab353082733e54458734e2114d51b28b3168fc8f..f378be29696008a32361cbc0a2c04536b002abf5 100644 (file)
@@ -1,29 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : SMESH_Group.hxx
 //  Author : Michael Sazonov (OCC)
 //  Module : SMESH
-//  $Header$
 //
 #ifndef _SMESH_Group_HeaderFile
 #define _SMESH_Group_HeaderFile
@@ -31,6 +31,7 @@
 #include "SMESH_SMESH.hxx"
 
 #include "SMDSAbs_ElementType.hxx"
+#include "SMESH_Controls.hxx"
 
 #include <string>
 #include <TopoDS_Shape.hxx>
@@ -46,7 +47,9 @@ class SMESH_EXPORT  SMESH_Group
                const SMESH_Mesh*         theMesh,
                const SMDSAbs_ElementType theType,
                const char*               theName,
-               const TopoDS_Shape&       theShape = TopoDS_Shape());
+               const TopoDS_Shape&       theShape = TopoDS_Shape(),
+               const SMESH_PredicatePtr& thePredicate = SMESH_PredicatePtr());
+  SMESH_Group (SMESHDS_GroupBase* groupDS);
   ~SMESH_Group ();
 
   void SetName (const char* theName) { myName = theName; }
index d23f7cbe0825d0dadbe20d870dd2101a75016850..5552964bbcffce76194533616607fc53fa0bab27 100644 (file)
@@ -1,34 +1,38 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : SMESH_HypoFilter.cxx
 //  Module : SMESH
-//  $Header$
 //
 #include "SMESH_HypoFilter.hxx"
 
+#include "SMESH_Gen.hxx"
 #include "SMESH_Hypothesis.hxx"
+#include "SMESH_MesherHelper.hxx"
 #include "SMESH_subMesh.hxx"
 
+#include <TopExp_Explorer.hxx>
+
 using namespace std;
 
 
@@ -112,11 +116,39 @@ bool SMESH_HypoFilter::InstancePredicate::IsOk(const SMESH_Hypothesis* aHyp,
 //=======================================================================
 
 bool SMESH_HypoFilter::IsAssignedToPredicate::IsOk(const SMESH_Hypothesis* aHyp,
-                                               const TopoDS_Shape&     aShape) const
+                                                   const TopoDS_Shape&     aShape) const
 {
   return ( !_mainShape.IsNull() && !aShape.IsNull() && _mainShape.IsSame( aShape ));
 }
 
+//================================================================================
+/*!
+ * \brief Finds shapes preferable over _shape due to sub-mesh order
+ */
+//================================================================================
+
+void SMESH_HypoFilter::IsMoreLocalThanPredicate::findPreferable()
+{
+  const int shapeID = _mesh.GetMeshDS()->ShapeToIndex( _shape );
+  const TListOfListOfInt& listOfShapeIDList = _mesh.GetMeshOrder();
+  TListOfListOfInt::const_iterator listsIt = listOfShapeIDList.begin();
+  for ( ; listsIt != listOfShapeIDList.end(); ++listsIt )
+  {
+    const TListOfInt& idList  = *listsIt;
+    TListOfInt::const_iterator idIt =
+      std::find( idList.begin(), idList.end(), shapeID );
+    if ( idIt != idList.end() && *idIt != idList.front() )
+    {
+      for ( ; idIt != idList.end(); --idIt )
+      {
+        const TopoDS_Shape& shape = _mesh.GetMeshDS()->IndexToShape( *idIt );
+        if ( !shape.IsNull())
+          _preferableShapes.Add( shape );
+      }
+    }
+  }
+}
+
 //=======================================================================
 //function : IsMoreLocalThanPredicate::IsOk
 //purpose  : 
@@ -125,7 +157,26 @@ bool SMESH_HypoFilter::IsAssignedToPredicate::IsOk(const SMESH_Hypothesis* aHyp,
 bool SMESH_HypoFilter::IsMoreLocalThanPredicate::IsOk(const SMESH_Hypothesis* aHyp,
                                                       const TopoDS_Shape&     aShape) const
 {
-  return ( aShape.ShapeType() > _shapeType );
+  if ( aShape.IsSame( _mesh.GetShapeToMesh() ))
+    return false; // aHyp is global
+
+  if ( SMESH_MesherHelper::IsSubShape( aShape, /*mainShape=*/_shape ))
+    return true;
+
+  if ( aShape.ShapeType() == TopAbs_COMPOUND && 
+       !SMESH_MesherHelper::IsSubShape( _shape, /*mainShape=*/aShape)) // issue 0020963
+  {
+    for ( int type = TopAbs_SOLID; type < TopAbs_SHAPE; ++type )
+      if ( aHyp->GetDim() == SMESH_Gen::GetShapeDim( TopAbs_ShapeEnum( type )))
+        for ( TopExp_Explorer exp( aShape, TopAbs_ShapeEnum( type )); exp.More(); exp.Next())
+          if ( SMESH_MesherHelper::IsSubShape( exp.Current(), /*mainShape=*/_shape ))
+            return true;
+  }
+
+  if ( _preferableShapes.Contains( aShape ))
+    return true; // issue 21559, Mesh_6
+
+  return false;
 }
 
 //=======================================================================
@@ -277,9 +328,10 @@ SMESH_HypoPredicate* SMESH_HypoFilter::IsApplicableTo(const TopoDS_Shape& theSha
 //purpose  : 
 //=======================================================================
 
-SMESH_HypoPredicate* SMESH_HypoFilter::IsMoreLocalThan(const TopoDS_Shape& theShape)
+SMESH_HypoPredicate* SMESH_HypoFilter::IsMoreLocalThan(const TopoDS_Shape& theShape,
+                                                       const SMESH_Mesh&   theMesh)
 {
-  return new IsMoreLocalThanPredicate( theShape );
+  return new IsMoreLocalThanPredicate( theShape, theMesh );
 }
 
 //=======================================================================
@@ -346,3 +398,5 @@ SMESH_HypoFilter::~SMESH_HypoFilter()
   Init(0);
 }
 
+
+
index c7aa1ed82ca67b9c250eac4059dda0d619b0a112..b4ace7d2a2434ed538024baf67ac90d6ab67b083 100644 (file)
@@ -1,28 +1,28 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : SMESH_HypoFilter.hxx
 //  Module : SMESH
-//  $Header$
 //
 #ifndef SMESH_HypoFilter_HeaderFile
 #define SMESH_HypoFilter_HeaderFile
 #include <list>
 #include <string>
 #include <TopoDS_Shape.hxx>
+#include <TopTools_MapOfShape.hxx>
 
 class SMESH_HypoFilter;
 class SMESH_Hypothesis;
+class SMESH_Mesh;
 
 class SMESH_EXPORT SMESH_HypoPredicate {
  public:
@@ -72,11 +74,14 @@ class SMESH_EXPORT SMESH_HypoFilter: public SMESH_HypoPredicate
   static SMESH_HypoPredicate* IsAssignedTo(const TopoDS_Shape& theShape);
   static SMESH_HypoPredicate* Is(const SMESH_Hypothesis* theHypo);
   static SMESH_HypoPredicate* IsGlobal(const TopoDS_Shape& theMainShape);
-  static SMESH_HypoPredicate* IsMoreLocalThan(const TopoDS_Shape& theShape);
+  static SMESH_HypoPredicate* IsMoreLocalThan(const TopoDS_Shape& theShape,
+                                              const SMESH_Mesh&   theMesh);
   static SMESH_HypoPredicate* HasName(const std::string & theName);
   static SMESH_HypoPredicate* HasDim(const int theDim);
   static SMESH_HypoPredicate* HasType(const int theHypType);
 
+  bool IsEmpty() const { return myPredicates.empty(); }
+
   /*!
    * \brief check aHyp or/and aShape it is assigned to
    */
@@ -167,10 +172,15 @@ class SMESH_EXPORT SMESH_HypoFilter: public SMESH_HypoPredicate
   };
         
   struct IsMoreLocalThanPredicate : public SMESH_HypoPredicate {
-    TopAbs_ShapeEnum _shapeType;
-    IsMoreLocalThanPredicate( const TopoDS_Shape& shape ):_shapeType(shape.ShapeType()){}
+    TopoDS_Shape        _shape;
+    const SMESH_Mesh&   _mesh;
+    TopTools_MapOfShape _preferableShapes;
+    IsMoreLocalThanPredicate( const TopoDS_Shape& shape,
+                              const SMESH_Mesh&   mesh )
+      :_shape(shape),_mesh(mesh) { findPreferable(); }
     bool IsOk(const SMESH_Hypothesis* aHyp,
               const TopoDS_Shape&     aShape) const;
+    void findPreferable();
   };
         
   struct IsAuxiliaryPredicate : public SMESH_HypoPredicate {
index 4b288a0d90311b7285255ff45bb3537ee7fd1c29..fee310f27caa8a44af2a462ba3b359f0074b916a 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : SMESH_Hypothesis.cxx
 //  Author : Paul RASCLE, EDF
@@ -39,8 +40,8 @@ using namespace std;
 //=============================================================================
 
 SMESH_Hypothesis::SMESH_Hypothesis(int hypId,
-                                  int studyId,
-                                  SMESH_Gen* gen) : SMESHDS_Hypothesis(hypId)
+                                   int studyId,
+                                   SMESH_Gen* gen) : SMESHDS_Hypothesis(hypId)
 {
   //MESSAGE("SMESH_Hypothesis::SMESH_Hypothesis");
   _gen = gen;
@@ -51,6 +52,8 @@ SMESH_Hypothesis::SMESH_Hypothesis(int hypId,
   _shapeType = 0; // to be set by algo with TopAbs_Enum
   _param_algo_dim = -1; // to be set by algo parameter
   _parameters = string();
+  _lastParameters = string();
+  _libName = string();
 }
 
 //=============================================================================
@@ -151,6 +154,24 @@ void SMESH_Hypothesis::SetLibName(const char* theLibName)
   _libName = string(theLibName);
 }
 
+//=======================================================================
+//function : GetMeshByPersistentID
+//purpose  : Find a mesh with given persistent ID
+//=======================================================================
+
+SMESH_Mesh* SMESH_Hypothesis::GetMeshByPersistentID(int id)
+{
+  StudyContextStruct* myStudyContext = _gen->GetStudyContext(_studyId);
+  map<int, SMESH_Mesh*>::iterator itm = itm = myStudyContext->mapMesh.begin();
+  for ( ; itm != myStudyContext->mapMesh.end(); itm++)
+  {
+    SMESH_Mesh* mesh = (*itm).second;
+    if ( mesh->GetMeshDS()->GetPersistentId() == id )
+      return mesh;
+  }
+  return 0;
+}
+
 //=============================================================================
 /*!
  * 
index 55ed9dd5fb2f84970161c6d1c523350965caa0db..0c81caac7a248b7785cae8af9ff5660e6126b9fe 100644 (file)
@@ -1,30 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : SMESH_Hypothesis.hxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
 //
-
 #ifndef _SMESH_HYPOTHESIS_HXX_
 #define _SMESH_HYPOTHESIS_HXX_
 
@@ -61,7 +61,7 @@ public:
     HYP_NOTCONFORM,   // not conform mesh is produced appling a hypothesis
     HYP_ALREADY_EXIST,// such hypothesis already exist
     HYP_BAD_DIM,      // bad dimension
-    HYP_BAD_SUBSHAPE, // shape is neither the main one, nor its subshape, nor a group
+    HYP_BAD_SUBSHAPE, // shape is neither the main one, nor its sub-shape, nor a group
     HYP_BAD_GEOMETRY, // shape geometry mismatches algorithm's expectation
     HYP_NEED_SHAPE    // algorithm can work on shape only
   };
@@ -94,8 +94,9 @@ public:
 
   struct TDefaults
   {
-    double _elemLength;
-    int    _nbSegments;
+    double        _elemLength;
+    int           _nbSegments;
+    TopoDS_Shape* _shape; // future shape of the mesh being created
   };
   /*!
    * \brief Initialize my parameter values by default parameters.
@@ -114,11 +115,16 @@ public:
   virtual bool IsAuxiliary() const
   { return GetType() == PARAM_ALGO && _param_algo_dim < 0; }
 
+  /*!
+   * \brief Find a mesh with given persistent ID
+   */
+  SMESH_Mesh* GetMeshByPersistentID(int id);
+
 protected:
   SMESH_Gen* _gen;
   int _studyId;
   int _shapeType;
-  int _param_algo_dim;
+  int _param_algo_dim; // to be set at descendant hypothesis constructor
 
 private:
   std::string _libName;
diff --git a/src/SMESH/SMESH_IndexedDataMapOfShapeIndexedMapOfShape.hxx b/src/SMESH/SMESH_IndexedDataMapOfShapeIndexedMapOfShape.hxx
deleted file mode 100644 (file)
index 7daa8b4..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-// File:      SMESH_IndexedDataMapOfShapeIndexedMapOfShape.hxx
-// Created:   20.09.05 09:51:12
-// Author:    Sergey KUUL
-//
-#ifndef SMESH_IndexedMapOfShape_HeaderFile
-#define SMESH_IndexedMapOfShape_HeaderFile
-
-#include "SMESH_SMESH.hxx"
-
-#include "SMESHDS_DataMapOfShape.hxx"
-
-#include <NCollection_DefineIndexedMap.hxx>
-
-#include <TopoDS_Shape.hxx>
-
-///  Class SMESH_IndexedMapOfShape
-
-DEFINE_BASECOLLECTION (SMESH_BaseCollectionShape, TopoDS_Shape)
-DEFINE_INDEXEDMAP (SMESH_IndexedMapOfShape, SMESH_BaseCollectionShape, TopoDS_Shape)
-
-#endif 
-
-#ifndef SMESH_IndexedDataMapOfShapeIndexedMapOfShape_HeaderFile
-#define SMESH_IndexedDataMapOfShapeIndexedMapOfShape_HeaderFile
-
-#include <NCollection_DefineIndexedDataMap.hxx>
-
-///  Class SMESH_IndexedDataMapOfShapeIndexedMapOfShape
-
-DEFINE_BASECOLLECTION (SMESH_BaseCollectionIndexedMapOfShape, SMESH_IndexedMapOfShape)
-DEFINE_INDEXEDDATAMAP (SMESH_IndexedDataMapOfShapeIndexedMapOfShape,
-                       SMESH_BaseCollectionIndexedMapOfShape, TopoDS_Shape,
-                       SMESH_IndexedMapOfShape)
-#endif 
index 866fda73926e79edab0079252b506292f3b302d2..1057d3deee69e87f7e9ea71f983b7a9638267865 100644 (file)
@@ -1,30 +1,31 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-//  SMESH SMESH : implementaion of SMESH idl descriptions
+
 //  File   : SMESH_Mesh.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
 //
 #include "SMESH_Mesh.hxx"
+#include "SMESH_MesherHelper.hxx"
 #include "SMESH_subMesh.hxx"
 #include "SMESH_Gen.hxx"
 #include "SMESH_Hypothesis.hxx"
 #include "DriverMED_R_SMESHDS_Mesh.h"
 #include "DriverUNV_R_SMDS_Mesh.h"
 #include "DriverSTL_R_SMDS_Mesh.h"
+#ifdef WITH_CGNS
+#include "DriverCGNS_Read.hxx"
+#include "DriverCGNS_Write.hxx"
+#endif
 
 #undef _Precision_HeaderFile
 #include <BRepBndLib.hxx>
 
 #include "Utils_ExceptHandlers.hxx"
 
+#include <boost/thread/thread.hpp>
+#include <boost/bind.hpp>
+
+using namespace std;
+
 // maximum stored group name length in MED file
 #define MAX_MED_GROUP_NAME_LENGTH 80
 
@@ -81,11 +91,11 @@ typedef SMESH_HypoFilter THypType;
 //=============================================================================
 
 SMESH_Mesh::SMESH_Mesh(int               theLocalId, 
-                      int               theStudyId, 
-                      SMESH_Gen*        theGen,
-                      bool              theIsEmbeddedMode,
-                      SMESHDS_Document* theDocument):
-  _groupId( 0 )
+                       int               theStudyId, 
+                       SMESH_Gen*        theGen,
+                       bool              theIsEmbeddedMode,
+                       SMESHDS_Document* theDocument):
+  _groupId( 0 ), _nbSubShapes( 0 )
 {
   MESSAGE("SMESH_Mesh::SMESH_Mesh(int localId)");
   _id            = theLocalId;
@@ -96,10 +106,44 @@ SMESH_Mesh::SMESH_Mesh(int               theLocalId,
   _myMeshDS      = theDocument->GetMesh(_idDoc);
   _isShapeToMesh = false;
   _isAutoColor   = false;
+  _isModified    = false;
   _shapeDiagonal = 0.0;
+  _callUp = 0;
   _myMeshDS->ShapeToMesh( PseudoShape() );
 }
 
+//================================================================================
+/*!
+ * \brief Constructor of SMESH_Mesh being a base of some descendant class
+ */
+//================================================================================
+
+SMESH_Mesh::SMESH_Mesh():
+  _id(-1),
+  _studyId(-1),
+  _idDoc(-1),
+  _groupId( 0 ),
+  _nbSubShapes( 0 ),
+  _isShapeToMesh( false ),
+  _myDocument( 0 ),
+  _myMeshDS( 0 ),
+  _gen( 0 ),
+  _isAutoColor( false ),
+  _isModified( false ),
+  _shapeDiagonal( 0.0 ),
+  _callUp( 0 )
+{
+}
+
+namespace
+{
+  void deleteMeshDS(SMESHDS_Mesh* meshDS)
+  {
+    //cout << "deleteMeshDS( " << meshDS << endl;
+    delete meshDS;
+  }
+}
+
 //=============================================================================
 /*!
  * 
@@ -108,15 +152,57 @@ SMESH_Mesh::SMESH_Mesh(int               theLocalId,
 
 SMESH_Mesh::~SMESH_Mesh()
 {
-  INFOS("SMESH_Mesh::~SMESH_Mesh");
+  MESSAGE("SMESH_Mesh::~SMESH_Mesh");
+
+  // issue 0020340: EDF 1022 SMESH : Crash with FindNodeClosestTo in a second new study
+  //   Notify event listeners at least that something happens
+  if ( SMESH_subMesh * sm = GetSubMeshContaining(1))
+    sm->ComputeStateEngine( SMESH_subMesh::MESH_ENTITY_REMOVED );
 
   // delete groups
-  std::map < int, SMESH_Group * >::iterator itg;
+  map < int, SMESH_Group * >::iterator itg;
   for (itg = _mapGroup.begin(); itg != _mapGroup.end(); itg++) {
     SMESH_Group *aGroup = (*itg).second;
     delete aGroup;
   }
   _mapGroup.clear();
+
+  // delete sub-meshes
+  map <int, SMESH_subMesh*>::iterator sm = _mapSubMesh.begin();
+  for ( ; sm != _mapSubMesh.end(); ++sm )
+  {
+    delete sm->second;
+    sm->second = 0;
+  }
+  _mapSubMesh.clear();
+
+  if ( _callUp) delete _callUp;
+  _callUp = 0;
+
+  // remove self from studyContext
+  if ( _gen )
+  {
+    StudyContextStruct * studyContext = _gen->GetStudyContext( _studyId );
+    studyContext->mapMesh.erase( _id );
+  }
+  if ( _myDocument )
+    _myDocument->RemoveMesh( _id );
+  _myDocument = 0;
+
+  if ( _myMeshDS )
+    // delete _myMeshDS, in a thread in order not to block closing a study with large meshes
+    boost::thread aThread(boost::bind( & deleteMeshDS, _myMeshDS ));
+}
+
+//================================================================================
+/*!
+ * \brief Return true if a mesh with given id exists
+ */
+//================================================================================
+
+bool SMESH_Mesh::MeshExists( int meshId ) const
+{
+  return _myDocument ? _myDocument->GetMesh( meshId ) : false;
 }
 
 //=============================================================================
@@ -129,20 +215,22 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape)
 {
   if(MYDEBUG) MESSAGE("SMESH_Mesh::ShapeToMesh");
 
-  if ( !aShape.IsNull() && _isShapeToMesh )
-    throw SALOME_Exception(LOCALIZED ("a shape to mesh has already been defined"));
-
+  if ( !aShape.IsNull() && _isShapeToMesh ) {
+    if ( aShape.ShapeType() != TopAbs_COMPOUND && // group contents is allowed to change
+         _myMeshDS->ShapeToMesh().ShapeType() != TopAbs_COMPOUND )
+      throw SALOME_Exception(LOCALIZED ("a shape to mesh has already been defined"));
+  }
   // clear current data
   if ( !_myMeshDS->ShapeToMesh().IsNull() )
   {
     // removal of a shape to mesh, delete objects referring to sub-shapes:
     // - sub-meshes
-    std::map <int, SMESH_subMesh *>::iterator i_sm = _mapSubMesh.begin();
+    map <int, SMESH_subMesh *>::iterator i_sm = _mapSubMesh.begin();
     for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
       delete i_sm->second;
     _mapSubMesh.clear();
     //  - groups on geometry
-    std::map <int, SMESH_Group *>::iterator i_gr = _mapGroup.begin();
+    map <int, SMESH_Group *>::iterator i_gr = _mapGroup.begin();
     while ( i_gr != _mapGroup.end() ) {
       if ( dynamic_cast<SMESHDS_GroupOnGeom*>( i_gr->second->GetGroupDS() )) {
         _myMeshDS->RemoveGroup( i_gr->second->GetGroupDS() );
@@ -166,16 +254,18 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape)
   {
     _myMeshDS->ShapeToMesh(aShape);
     _isShapeToMesh = true;
+    _nbSubShapes = _myMeshDS->MaxShapeIndex();
 
-    // fill _mapAncestors
-    int desType, ancType;
-    for ( desType = TopAbs_VERTEX; desType > TopAbs_COMPOUND; desType-- )
-      for ( ancType = desType - 1; ancType >= TopAbs_COMPOUND; ancType-- )
-        TopExp::MapShapesAndAncestors ( aShape,
-                                        (TopAbs_ShapeEnum) desType,
-                                        (TopAbs_ShapeEnum) ancType,
-                                        _mapAncestors );
+    // fill map of ancestors
+    fillAncestorsMap(aShape);
   }
+  else
+  {
+    _isShapeToMesh = false;
+    _shapeDiagonal = 0.0;
+    _myMeshDS->ShapeToMesh( PseudoShape() );
+  }
+  _isModified = false;
 }
 
 //=======================================================================
@@ -236,6 +326,18 @@ double SMESH_Mesh::GetShapeDiagonalSize() const
   return _shapeDiagonal;
 }
 
+//================================================================================
+/*!
+ * \brief Load mesh from study file
+ */
+//================================================================================
+
+void SMESH_Mesh::Load()
+{
+  if (_callUp)
+    _callUp->Load();
+}
+
 //=======================================================================
 /*!
  * \brief Remove all nodes and elements
@@ -248,55 +350,14 @@ void SMESH_Mesh::Clear()
   _myMeshDS->ClearMesh();
 
   // update compute state of submeshes
-  if ( SMESH_subMesh *sm = GetSubMeshContaining( GetShapeToMesh() ) ) {
-    SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true,
-                                                             /*complexShapeFirst=*/false);
-    while ( smIt->more() ) {
-      sm = smIt->next();
-      sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
-    }
+  if ( SMESH_subMesh *sm = GetSubMeshContaining( GetShapeToMesh() ) )
+  {
+    sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+    sm->ComputeSubMeshStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+    sm->ComputeStateEngine( SMESH_subMesh::CLEAN ); // for event listeners (issue 0020918)
+    sm->ComputeSubMeshStateEngine( SMESH_subMesh::CLEAN );
   }
-
-//   // clear sub-meshes; get ready to re-compute as a side-effect 
-
-//   if ( SMESH_subMesh *sm = GetSubMeshContaining( GetShapeToMesh() ) )
-//   {
-//     SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true,
-//                                                              /*complexShapeFirst=*/false);
-//     while ( smIt->more() )
-//     {
-//       sm = smIt->next();
-//       TopAbs_ShapeEnum shapeType = sm->GetSubShape().ShapeType();      
-//       if ( shapeType == TopAbs_VERTEX || shapeType < TopAbs_SOLID )
-//         // all other shapes depends on vertices so they are already cleaned
-//         sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
-//       // to recompute even if failed
-//       sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
-//     }
-//   }
-
-//   // clear entities not on sub-meshes
-
-//   SMDS_VolumeIteratorPtr vIt = _myMeshDS->volumesIterator();
-//   while ( vIt->more() )
-//     _myMeshDS->RemoveFreeElement( vIt->next(), 0 );
-
-//   SMDS_FaceIteratorPtr fIt = _myMeshDS->facesIterator();
-//   while ( fIt->more() )
-//     _myMeshDS->RemoveFreeElement( fIt->next(), 0 );
-
-//   SMDS_EdgeIteratorPtr eIt = _myMeshDS->edgesIterator();
-//   while ( eIt->more() )
-//     _myMeshDS->RemoveFreeElement( eIt->next(), 0 );
-
-//   SMDS_NodeIteratorPtr nIt = _myMeshDS->nodesIterator();
-//   while ( nIt->more() ) {
-//     const SMDS_MeshNode * node = nIt->next();
-//     if ( node->NbInverseElements() == 0 )
-//       _myMeshDS->RemoveFreeNode( node, 0 );
-//     else
-//       _myMeshDS->RemoveNode(node);
-//   }
+  _isModified = false;
 }
 
 //=======================================================================
@@ -311,14 +372,14 @@ void SMESH_Mesh::ClearSubMesh(const int theShapeId)
   if ( SMESH_subMesh *sm = GetSubMeshContaining( theShapeId ) )
   {
     SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true,
-                                                            /*complexShapeFirst=*/false);
+                                                             /*complexShapeFirst=*/false);
     while ( smIt->more() )
     {
       sm = smIt->next();
       TopAbs_ShapeEnum shapeType = sm->GetSubShape().ShapeType();      
       if ( shapeType == TopAbs_VERTEX || shapeType < TopAbs_SOLID )
-       // all other shapes depends on vertices so they are already cleaned
-       sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
+        // all other shapes depends on vertices so they are already cleaned
+        sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
       // to recompute even if failed
       sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
     }
@@ -354,26 +415,26 @@ int SMESH_Mesh::UNVToMesh(const char* theFileName)
     aGroup->InitSubGroupsIterator();
     while (aGroup->MoreSubGroups()) {
       SMDS_MeshGroup* aSubGroup = (SMDS_MeshGroup*) aGroup->NextSubGroup();
-      std::string aName = aGroupNames[aSubGroup];
+      string aName = aGroupNames[aSubGroup];
       int aId;
 
       SMESH_Group* aSMESHGroup = AddGroup( aSubGroup->GetType(), aName.c_str(), aId );
       if ( aSMESHGroup ) {
-       if(MYDEBUG) MESSAGE("UNVToMesh - group added: "<<aName);      
-       SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( aSMESHGroup->GetGroupDS() );
-       if ( aGroupDS ) {
-         aGroupDS->SetStoreName(aName.c_str());
-         aSubGroup->InitIterator();
-         const SMDS_MeshElement* aElement = 0;
-         while (aSubGroup->More()) {
-           aElement = aSubGroup->Next();
-           if (aElement) {
-             aGroupDS->SMDSGroup().Add(aElement);
-           }
-         }
-         if (aElement)
-           aGroupDS->SetType(aElement->GetType());
-       }
+        if(MYDEBUG) MESSAGE("UNVToMesh - group added: "<<aName);      
+        SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( aSMESHGroup->GetGroupDS() );
+        if ( aGroupDS ) {
+          aGroupDS->SetStoreName(aName.c_str());
+          aSubGroup->InitIterator();
+          const SMDS_MeshElement* aElement = 0;
+          while (aSubGroup->More()) {
+            aElement = aSubGroup->Next();
+            if (aElement) {
+              aGroupDS->SMDSGroup().Add(aElement);
+            }
+          }
+          if (aElement)
+            aGroupDS->SetType(aElement->GetType());
+        }
       }
     }
   }
@@ -405,10 +466,10 @@ int SMESH_Mesh::MEDToMesh(const char* theFileName, const char* theMeshName)
   }
 
   // Reading groups (sub-meshes are out of scope of MED import functionality)
-  std::list<TNameAndType> aGroupNames = myReader.GetGroupNamesAndTypes();
+  list<TNameAndType> aGroupNames = myReader.GetGroupNamesAndTypes();
   if(MYDEBUG) MESSAGE("MEDToMesh - Nb groups = "<<aGroupNames.size()); 
   int anId;
-  std::list<TNameAndType>::iterator name_type = aGroupNames.begin();
+  list<TNameAndType>::iterator name_type = aGroupNames.begin();
   for ( ; name_type != aGroupNames.end(); name_type++ ) {
     SMESH_Group* aGroup = AddGroup( name_type->second, name_type->first.c_str(), anId );
     if ( aGroup ) {
@@ -448,6 +509,35 @@ int SMESH_Mesh::STLToMesh(const char* theFileName)
   return 1;
 }
 
+//================================================================================
+/*!
+ * \brief Reads the given mesh from the CGNS file
+ *  \param theFileName - name of the file
+ *  \retval int - Driver_Mesh::Status
+ */
+//================================================================================
+
+int SMESH_Mesh::CGNSToMesh(const char*  theFileName,
+                           const int    theMeshIndex,
+                           std::string& theMeshName)
+{
+  int res = Driver_Mesh::DRS_FAIL;
+#ifdef WITH_CGNS
+
+  DriverCGNS_Read myReader;
+  myReader.SetMesh(_myMeshDS);
+  myReader.SetFile(theFileName);
+  myReader.SetMeshId(theMeshIndex);
+  res = myReader.Perform();
+  theMeshName = myReader.GetMeshName();
+
+  // create groups
+  SynchronizeGroups();
+
+#endif
+  return res;
+}
+
 //=============================================================================
 /*!
  * 
@@ -465,33 +555,6 @@ SMESH_Hypothesis::Hypothesis_Status
   if ( !subMesh || !subMesh->GetId())
     return SMESH_Hypothesis::HYP_BAD_SUBSHAPE;
 
-  SMESHDS_SubMesh *subMeshDS = subMesh->GetSubMeshDS();
-  if ( subMeshDS && subMeshDS->IsComplexSubmesh() ) // group of sub-shapes and maybe of not sub-
-  {
-    MESSAGE("AddHypothesis() to complex submesh");
-    // return the worst but not fatal state of all group memebers
-    SMESH_Hypothesis::Hypothesis_Status aBestRet, aWorstNotFatal, ret;
-    aBestRet = SMESH_Hypothesis::HYP_BAD_DIM;
-    aWorstNotFatal = SMESH_Hypothesis::HYP_OK;
-    for ( TopoDS_Iterator itS ( aSubShape ); itS.More(); itS.Next())
-    {
-      if ( !GetMeshDS()->ShapeToIndex( itS.Value() ))
-        continue; // not sub-shape
-      ret = AddHypothesis( itS.Value(), anHypId );
-      if ( !SMESH_Hypothesis::IsStatusFatal( ret ) && ret > aWorstNotFatal )
-        aWorstNotFatal = ret;
-      if ( ret < aBestRet )
-        aBestRet = ret;
-    }
-    // bind hypotheses to a group just to know
-    SMESH_Hypothesis *anHyp = _gen->GetStudyContext(_studyId)->mapHypothesis[anHypId];
-    GetMeshDS()->AddHypothesis( aSubShape, anHyp );
-
-    if ( SMESH_Hypothesis::IsStatusFatal( aBestRet ))
-      return aBestRet;
-    return aWorstNotFatal;
-  }
-
   StudyContextStruct *sc = _gen->GetStudyContext(_studyId);
   if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end())
   {
@@ -511,6 +574,9 @@ SMESH_Hypothesis::Hypothesis_Status
   // NotConformAllowed can be only global
   if ( !isGlobalHyp )
   {
+    // NOTE: this is not a correct way to check a name of hypothesis,
+    // there should be an attribute of hypothesis saying that it can/can't
+    // be global/local
     string hypName = anHyp->GetName();
     if ( hypName == "NotConformAllowed" )
     {
@@ -526,7 +592,7 @@ SMESH_Hypothesis::Hypothesis_Status
 
   SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp);
 
-  // subShapes
+  // sub-shapes
   if (!SMESH_Hypothesis::IsStatusFatal(ret) &&
       anHyp->GetDim() <= SMESH_Gen::GetShapeDim(aSubShape)) // is added on father
   {
@@ -537,7 +603,7 @@ SMESH_Hypothesis::Hypothesis_Status
     if (ret2 > ret)
       ret = ret2;
 
-    // check concurent hypotheses on ansestors
+    // check concurent hypotheses on ancestors
     if (ret < SMESH_Hypothesis::HYP_CONCURENT && !isGlobalHyp )
     {
       SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false);
@@ -553,9 +619,12 @@ SMESH_Hypothesis::Hypothesis_Status
       }
     }
   }
+  HasModificationsToDiscard(); // to reset _isModified flag if a mesh becomes empty
+
+  GetMeshDS()->Modified();
 
   if(MYDEBUG) subMesh->DumpAlgoState(true);
-  SCRUTE(ret);
+  if(MYDEBUG) SCRUTE(ret);
   return ret;
 }
 
@@ -572,45 +641,23 @@ SMESH_Hypothesis::Hypothesis_Status
   Unexpect aCatch(SalomeException);
   if(MYDEBUG) MESSAGE("SMESH_Mesh::RemoveHypothesis");
   
-  SMESH_subMesh *subMesh = GetSubMesh(aSubShape);
-  SMESHDS_SubMesh *subMeshDS = subMesh->GetSubMeshDS();
-  if ( subMeshDS && subMeshDS->IsComplexSubmesh() )
-  {
-    // return the worst but not fatal state of all group memebers
-    SMESH_Hypothesis::Hypothesis_Status aBestRet, aWorstNotFatal, ret;
-    aBestRet = SMESH_Hypothesis::HYP_BAD_DIM;
-    aWorstNotFatal = SMESH_Hypothesis::HYP_OK;
-    for ( TopoDS_Iterator itS ( aSubShape ); itS.More(); itS.Next())
-    {
-      if ( !GetMeshDS()->ShapeToIndex( itS.Value() ))
-        continue; // not sub-shape
-      ret = RemoveHypothesis( itS.Value(), anHypId );
-      if ( !SMESH_Hypothesis::IsStatusFatal( ret ) && ret > aWorstNotFatal )
-        aWorstNotFatal = ret;
-      if ( ret < aBestRet )
-        aBestRet = ret;
-    }
-    SMESH_Hypothesis *anHyp = _gen->GetStudyContext(_studyId)->mapHypothesis[anHypId];
-    GetMeshDS()->RemoveHypothesis( aSubShape, anHyp );
-
-    if ( SMESH_Hypothesis::IsStatusFatal( aBestRet ))
-      return aBestRet;
-    return aWorstNotFatal;
-  }
-
   StudyContextStruct *sc = _gen->GetStudyContext(_studyId);
   if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end())
     throw SALOME_Exception(LOCALIZED("hypothesis does not exist"));
   
   SMESH_Hypothesis *anHyp = sc->mapHypothesis[anHypId];
-  int hypType = anHyp->GetType();
-  if(MYDEBUG) SCRUTE(hypType);
+  if(MYDEBUG) {
+    int hypType = anHyp->GetType();
+    SCRUTE(hypType);
+  }
   
   // shape 
   
   bool isAlgo = ( !anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO );
   int event = isAlgo ? SMESH_subMesh::REMOVE_ALGO : SMESH_subMesh::REMOVE_HYP;
 
+  SMESH_subMesh *subMesh = GetSubMesh(aSubShape);
+
   SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp);
 
   // there may appear concurrent hyps that were covered by the removed hyp
@@ -619,7 +666,7 @@ SMESH_Hypothesis::Hypothesis_Status
       subMesh->CheckConcurentHypothesis( anHyp->GetType() ) != SMESH_Hypothesis::HYP_OK)
     ret = SMESH_Hypothesis::HYP_CONCURENT;
 
-  // subShapes
+  // sub-shapes
   if (!SMESH_Hypothesis::IsStatusFatal(ret) &&
       anHyp->GetDim() <= SMESH_Gen::GetShapeDim(aSubShape)) // is removed from father
   {
@@ -630,7 +677,7 @@ SMESH_Hypothesis::Hypothesis_Status
     if (ret2 > ret) // more severe
       ret = ret2;
 
-    // check concurent hypotheses on ansestors
+    // check concurent hypotheses on ancestors
     if (ret < SMESH_Hypothesis::HYP_CONCURENT && !IsMainShape( aSubShape ) )
     {
       SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false);
@@ -646,7 +693,11 @@ SMESH_Hypothesis::Hypothesis_Status
       }
     }
   }
-  
+
+  HasModificationsToDiscard(); // to reset _isModified flag if mesh become empty
+
+  GetMeshDS()->Modified();
+
   if(MYDEBUG) subMesh->DumpAlgoState(true);
   if(MYDEBUG) SCRUTE(ret);
   return ret;
@@ -658,7 +709,7 @@ SMESH_Hypothesis::Hypothesis_Status
  */
 //=============================================================================
 
-const std::list<const SMESHDS_Hypothesis*>&
+const list<const SMESHDS_Hypothesis*>&
 SMESH_Mesh::GetHypothesisList(const TopoDS_Shape & aSubShape) const
   throw(SALOME_Exception)
 {
@@ -683,8 +734,8 @@ const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const TopoDS_Shape &    aSubS
                                                    TopoDS_Shape*           assignedTo) const
 {
   {
-    const std::list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(aSubShape);
-    std::list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
+    const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(aSubShape);
+    list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
     for ( ; hyp != hypList.end(); hyp++ ) {
       const SMESH_Hypothesis * h = cSMESH_Hyp( *hyp );
       if ( aFilter.IsOk( h, aSubShape)) {
@@ -695,15 +746,18 @@ const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const TopoDS_Shape &    aSubS
   }
   if ( andAncestors )
   {
-    TopTools_ListIteratorOfListOfShape it( GetAncestors( aSubShape ));
-    for (; it.More(); it.Next() )
+    // user sorted submeshes of ancestors, according to stored submesh priority
+    const list<SMESH_subMesh*> smList = getAncestorsSubMeshes( aSubShape );
+    list<SMESH_subMesh*>::const_iterator smIt = smList.begin(); 
+    for ( ; smIt != smList.end(); smIt++ )
     {
-      const std::list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(it.Value());
-      std::list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
+      const TopoDS_Shape& curSh = (*smIt)->GetSubShape();
+      const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(curSh);
+      list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
       for ( ; hyp != hypList.end(); hyp++ ) {
         const SMESH_Hypothesis * h = cSMESH_Hyp( *hyp );
-        if (aFilter.IsOk( h, it.Value() )) {
-          if ( assignedTo ) *assignedTo = it.Value();
+        if (aFilter.IsOk( h, curSh )) {
+          if ( assignedTo ) *assignedTo = curSh;
           return h;
         }
       }
@@ -735,7 +789,7 @@ int SMESH_Mesh::GetHypotheses(const TopoDS_Shape &                aSubShape,
   bool mainHypFound = false;
 
   // fill in hypTypes
-  std::list<const SMESHDS_Hypothesis*>::const_iterator hyp;
+  list<const SMESHDS_Hypothesis*>::const_iterator hyp;
   for ( hyp = aHypList.begin(); hyp != aHypList.end(); hyp++ ) {
     if ( hypTypes.insert( (*hyp)->GetName() ).second )
       nbHyps++;
@@ -745,7 +799,7 @@ int SMESH_Mesh::GetHypotheses(const TopoDS_Shape &                aSubShape,
 
   // get hypos from aSubShape
   {
-    const std::list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(aSubShape);
+    const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(aSubShape);
     for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ )
       if ( aFilter.IsOk (cSMESH_Hyp( *hyp ), aSubShape) &&
            ( cSMESH_Hyp(*hyp)->IsAuxiliary() || !mainHypFound ) &&
@@ -762,14 +816,18 @@ int SMESH_Mesh::GetHypotheses(const TopoDS_Shape &                aSubShape,
   if ( andAncestors )
   {
     TopTools_MapOfShape map;
-    TopTools_ListIteratorOfListOfShape it( GetAncestors( aSubShape ));
-    for (; it.More(); it.Next() )
+
+    // user sorted submeshes of ancestors, according to stored submesh priority
+    const list<SMESH_subMesh*> smList = getAncestorsSubMeshes( aSubShape );
+    list<SMESH_subMesh*>::const_iterator smIt = smList.begin(); 
+    for ( ; smIt != smList.end(); smIt++ )
     {
-     if ( !map.Add( it.Value() ))
+      const TopoDS_Shape& curSh = (*smIt)->GetSubShape();
+     if ( !map.Add( curSh ))
         continue;
-      const std::list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(it.Value());
+      const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(curSh);
       for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ )
-        if (aFilter.IsOk( cSMESH_Hyp( *hyp ), it.Value() ) &&
+        if (aFilter.IsOk( cSMESH_Hyp( *hyp ), curSh ) &&
             ( cSMESH_Hyp(*hyp)->IsAuxiliary() || !mainHypFound ) &&
             hypTypes.insert( (*hyp)->GetName() ).second )
         {
@@ -789,7 +847,7 @@ int SMESH_Mesh::GetHypotheses(const TopoDS_Shape &                aSubShape,
  */
 //=============================================================================
 
-const std::list<SMESHDS_Command*> & SMESH_Mesh::GetLog() throw(SALOME_Exception)
+const list<SMESHDS_Command*> & SMESH_Mesh::GetLog() throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
   if(MYDEBUG) MESSAGE("SMESH_Mesh::GetLog");
@@ -822,10 +880,16 @@ SMESH_subMesh *SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape)
   int index = _myMeshDS->ShapeToIndex(aSubShape);
 
   // for submeshes on GEOM Group
-  if ( !index && aSubShape.ShapeType() == TopAbs_COMPOUND ) {
+  if (( !index || index > _nbSubShapes ) && aSubShape.ShapeType() == TopAbs_COMPOUND ) {
     TopoDS_Iterator it( aSubShape );
     if ( it.More() )
+    {
       index = _myMeshDS->AddCompoundSubmesh( aSubShape, it.Value().ShapeType() );
+      if ( index > _nbSubShapes ) _nbSubShapes = index; // not to create sm for this group again
+
+      // fill map of Ancestors
+      fillAncestorsMap(aSubShape);
+    }
   }
 //   if ( !index )
 //     return NULL; // neither sub-shape nor a group
@@ -883,37 +947,47 @@ throw(SALOME_Exception)
 }
 //================================================================================
 /*!
- * \brief Return submeshes of groups containing the given subshape
+ * \brief Return submeshes of groups containing the given sub-shape
  */
 //================================================================================
 
-std::list<SMESH_subMesh*>
+list<SMESH_subMesh*>
 SMESH_Mesh::GetGroupSubMeshesContaining(const TopoDS_Shape & aSubShape) const
   throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
-  std::list<SMESH_subMesh*> found;
+  list<SMESH_subMesh*> found;
 
   SMESH_subMesh * subMesh = GetSubMeshContaining(aSubShape);
   if ( !subMesh )
     return found;
 
   // submeshes of groups have max IDs, so search from the map end
-  std::map<int, SMESH_subMesh *>::const_reverse_iterator i_sm;
+  map<int, SMESH_subMesh *>::const_reverse_iterator i_sm;
   for ( i_sm = _mapSubMesh.rbegin(); i_sm != _mapSubMesh.rend(); ++i_sm) {
     SMESHDS_SubMesh * ds = i_sm->second->GetSubMeshDS();
     if ( ds && ds->IsComplexSubmesh() ) {
-      TopExp_Explorer exp( i_sm->second->GetSubShape(), aSubShape.ShapeType() );
-      for ( ; exp.More(); exp.Next() ) {
-        if ( aSubShape.IsSame( exp.Current() )) {
-          found.push_back( i_sm->second );
-          break;
-        }
+      if ( SMESH_MesherHelper::IsSubShape( aSubShape, i_sm->second->GetSubShape() ))
+      {
+        found.push_back( i_sm->second );
+        //break;
       }
     } else {
-      break;
+      break; // the rest sub-meshes are not those of groups
     }
   }
+
+  if ( found.empty() ) // maybe the main shape is a COMPOUND (issue 0021530)
+  {
+    if ( SMESH_subMesh * mainSM = GetSubMeshContaining(1))
+      if ( mainSM->GetSubShape().ShapeType() == TopAbs_COMPOUND )
+      {
+        TopoDS_Iterator it( mainSM->GetSubShape() );
+        if ( it.Value().ShapeType() == aSubShape.ShapeType() &&
+             SMESH_MesherHelper::IsSubShape( aSubShape, mainSM->GetSubShape() ))
+          found.push_back( mainSM );
+      }
+  }
   return found;
 }
 //=======================================================================
@@ -987,6 +1061,12 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* h
 {
   Unexpect aCatch(SalomeException);
 
+  if ( !GetMeshDS()->IsUsedHypothesis( hyp ))
+    return;
+
+  if (_callUp)
+    _callUp->HypothesisModified();
+
   const SMESH_Algo *foundAlgo = 0;
   SMESH_HypoFilter algoKind, compatibleHypoKind;
   list <const SMESHDS_Hypothesis * > usedHyps;
@@ -1029,6 +1109,8 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* h
       }
     }
   }
+  HasModificationsToDiscard(); // to reset _isModified flag if mesh becomes empty
+  GetMeshDS()->Modified();
 }
 
 //=============================================================================
@@ -1048,37 +1130,98 @@ bool SMESH_Mesh::GetAutoColor() throw(SALOME_Exception)
   return _isAutoColor;
 }
 
-//=============================================================================
-/*! Export* methods.
- *  To store mesh contents on disk in different formats.
+//=======================================================================
+//function : SetIsModified
+//purpose  : Set the flag meaning that the mesh has been edited "manually"
+//=======================================================================
+
+void SMESH_Mesh::SetIsModified(bool isModified)
+{
+  _isModified = isModified;
+
+  if ( _isModified )
+    // check if mesh becomes empty as result of modification
+    HasModificationsToDiscard();
+}
+
+//=======================================================================
+//function : HasModificationsToDiscard
+//purpose  : Return true if the mesh has been edited since a total re-compute
+//           and those modifications may prevent successful partial re-compute.
+//           As a side effect reset _isModified flag if mesh is empty
+//issue    : 0020693
+//=======================================================================
+
+bool SMESH_Mesh::HasModificationsToDiscard() const
+{
+  if ( ! _isModified )
+    return false;
+
+  // return true if the next Compute() will be partial and
+  // existing but changed elements may prevent successful re-compute
+  bool hasComputed = false, hasNotComputed = false;
+  map <int, SMESH_subMesh*>::const_iterator i_sm = _mapSubMesh.begin();
+  for ( ; i_sm != _mapSubMesh.end() ; ++i_sm )
+    switch ( i_sm->second->GetSubShape().ShapeType() )
+    {
+    case TopAbs_EDGE:
+    case TopAbs_FACE:
+    case TopAbs_SOLID:
+      if ( i_sm->second->IsMeshComputed() )
+        hasComputed = true;
+      else
+        hasNotComputed = true;
+      if ( hasComputed && hasNotComputed)
+        return true;
+    }
+
+  if ( NbNodes() < 1 )
+    const_cast<SMESH_Mesh*>(this)->_isModified = false;
+
+  return false;
+}
+
+//================================================================================
+/*!
+ * \brief Check if any groups of the same type have equal names
  */
-//=============================================================================
+//================================================================================
 
 bool SMESH_Mesh::HasDuplicatedGroupNamesMED()
 {
-  set<string> aGroupNames;
-  for ( std::map<int, SMESH_Group*>::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) {
+  //set<string> aGroupNames; // Corrected for Mantis issue 0020028
+  map< SMDSAbs_ElementType, set<string> > aGroupNames;
+  for ( map<int, SMESH_Group*>::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ )
+  {
     SMESH_Group* aGroup = it->second;
-    std::string aGroupName = aGroup->GetName();
+    SMDSAbs_ElementType aType = aGroup->GetGroupDS()->GetType();
+    string aGroupName = aGroup->GetName();
     aGroupName.resize(MAX_MED_GROUP_NAME_LENGTH);
-    if (!aGroupNames.insert(aGroupName).second)
+    if (!aGroupNames[aType].insert(aGroupName).second)
       return true;
   }
 
   return false;
 }
 
-void SMESH_Mesh::ExportMED(const char *file, 
-                          const char* theMeshName, 
-                          bool theAutoGroups,
-                          int theVersion) 
+//================================================================================
+/*!
+ * \brief Export the mesh to a med file
+ */
+//================================================================================
+
+void SMESH_Mesh::ExportMED(const char *        file, 
+                           const char*         theMeshName, 
+                           bool                theAutoGroups,
+                           int                 theVersion,
+                           const SMESHDS_Mesh* meshPart) 
   throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
 
   DriverMED_W_SMESHDS_Mesh myWriter;
   myWriter.SetFile    ( file, MED::EVersion(theVersion) );
-  myWriter.SetMesh    ( _myMeshDS   );
+  myWriter.SetMesh    ( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS   );
   if ( !theMeshName ) 
     myWriter.SetMeshId  ( _idDoc      );
   else {
@@ -1094,79 +1237,167 @@ void SMESH_Mesh::ExportMED(const char *file,
   }
 
   // Pass groups to writer. Provide unique group names.
-  set<string> aGroupNames;
-  char aString [256];
-  int maxNbIter = 10000; // to guarantee cycle finish
-  for ( std::map<int, SMESH_Group*>::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) {
-    SMESH_Group*       aGroup   = it->second;
-    SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS();
-    if ( aGroupDS ) {
-      string aGroupName0 = aGroup->GetName();
-      aGroupName0.resize(MAX_MED_GROUP_NAME_LENGTH);
-      string aGroupName = aGroupName0;
-      for (int i = 1; !aGroupNames.insert(aGroupName).second && i < maxNbIter; i++) {
-        sprintf(&aString[0], "GR_%d_%s", i, aGroupName0.c_str());
-        aGroupName = aString;
-        aGroupName.resize(MAX_MED_GROUP_NAME_LENGTH);
+  //set<string> aGroupNames; // Corrected for Mantis issue 0020028
+  if ( !meshPart )
+  {
+    map< SMDSAbs_ElementType, set<string> > aGroupNames;
+    char aString [256];
+    int maxNbIter = 10000; // to guarantee cycle finish
+    for ( map<int, SMESH_Group*>::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) {
+      SMESH_Group*       aGroup   = it->second;
+      SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS();
+      if ( aGroupDS ) {
+        SMDSAbs_ElementType aType = aGroupDS->GetType();
+        string aGroupName0 = aGroup->GetName();
+        aGroupName0.resize(MAX_MED_GROUP_NAME_LENGTH);
+        string aGroupName = aGroupName0;
+        for (int i = 1; !aGroupNames[aType].insert(aGroupName).second && i < maxNbIter; i++) {
+          sprintf(&aString[0], "GR_%d_%s", i, aGroupName0.c_str());
+          aGroupName = aString;
+          aGroupName.resize(MAX_MED_GROUP_NAME_LENGTH);
+        }
+        aGroupDS->SetStoreName( aGroupName.c_str() );
+        myWriter.AddGroup( aGroupDS );
       }
-      aGroupDS->SetStoreName( aGroupName.c_str() );
-      myWriter.AddGroup( aGroupDS );
     }
   }
-
   // Perform export
   myWriter.Perform();
 }
 
-void SMESH_Mesh::ExportDAT(const char *file) throw(SALOME_Exception)
+void SMESH_Mesh::ExportSAUV(const char *file, 
+                            const char* theMeshName, 
+                            bool theAutoGroups)
+  throw(SALOME_Exception)
+{
+  std::string medfilename(file);
+  medfilename += ".med";
+  std::string cmd;
+#ifdef WNT
+  cmd = "%PYTHONBIN% ";
+#else
+  cmd = "python ";
+#endif
+  cmd += "-c \"";
+  cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')";
+  cmd += "\"";
+  system(cmd.c_str());
+  ExportMED(medfilename.c_str(), theMeshName, theAutoGroups, 1);
+#ifdef WNT
+  cmd = "%PYTHONBIN% ";
+#else
+  cmd = "python ";
+#endif
+  cmd += "-c \"";
+  cmd += "from medutilities import convert ; convert(r'" + medfilename + "', 'MED', 'GIBI', 1, r'" + file + "')";
+  cmd += "\"";
+  system(cmd.c_str());
+#ifdef WNT
+  cmd = "%PYTHONBIN% ";
+#else
+  cmd = "python ";
+#endif
+  cmd += "-c \"";
+  cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')";
+  cmd += "\"";
+  system(cmd.c_str());
+}
+
+//================================================================================
+/*!
+ * \brief Export the mesh to a DAT file
+ */
+//================================================================================
+
+void SMESH_Mesh::ExportDAT(const char *        file,
+                           const SMESHDS_Mesh* meshPart) throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
   DriverDAT_W_SMDS_Mesh myWriter;
-  myWriter.SetFile(string(file));
-  myWriter.SetMesh(_myMeshDS);
+  myWriter.SetFile( file );
+  myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS );
   myWriter.SetMeshId(_idDoc);
   myWriter.Perform();
 }
 
-void SMESH_Mesh::ExportUNV(const char *file) throw(SALOME_Exception)
+//================================================================================
+/*!
+ * \brief Export the mesh to an UNV file
+ */
+//================================================================================
+
+void SMESH_Mesh::ExportUNV(const char *        file,
+                           const SMESHDS_Mesh* meshPart) throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
   DriverUNV_W_SMDS_Mesh myWriter;
-  myWriter.SetFile(string(file));
-  myWriter.SetMesh(_myMeshDS);
+  myWriter.SetFile( file );
+  myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS );
   myWriter.SetMeshId(_idDoc);
   //  myWriter.SetGroups(_mapGroup);
 
-  for ( std::map<int, SMESH_Group*>::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) {
-    SMESH_Group*       aGroup   = it->second;
-    SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS();
-    if ( aGroupDS ) {
-      std::string aGroupName = aGroup->GetName();
-      aGroupDS->SetStoreName( aGroupName.c_str() );
-      myWriter.AddGroup( aGroupDS );
+  if ( !meshPart )
+  {
+    for ( map<int, SMESH_Group*>::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) {
+      SMESH_Group*       aGroup   = it->second;
+      SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS();
+      if ( aGroupDS ) {
+        string aGroupName = aGroup->GetName();
+        aGroupDS->SetStoreName( aGroupName.c_str() );
+        myWriter.AddGroup( aGroupDS );
+      }
     }
   }
   myWriter.Perform();
 }
 
-void SMESH_Mesh::ExportSTL(const char *file, const bool isascii) throw(SALOME_Exception)
+//================================================================================
+/*!
+ * \brief Export the mesh to an STL file
+ */
+//================================================================================
+
+void SMESH_Mesh::ExportSTL(const char *        file,
+                           const bool          isascii,
+                           const SMESHDS_Mesh* meshPart) throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
   DriverSTL_W_SMDS_Mesh myWriter;
-  myWriter.SetFile(string(file));
+  myWriter.SetFile( file );
   myWriter.SetIsAscii( isascii );
-  myWriter.SetMesh(_myMeshDS);
+  myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS);
   myWriter.SetMeshId(_idDoc);
   myWriter.Perform();
 }
 
+//================================================================================
+/*!
+ * \brief Export the mesh to the CGNS file
+ */
+//================================================================================
+
+void SMESH_Mesh::ExportCGNS(const char *        file,
+                            const SMESHDS_Mesh* meshDS)
+{
+  int res = Driver_Mesh::DRS_FAIL;
+#ifdef WITH_CGNS
+  DriverCGNS_Write myWriter;
+  myWriter.SetFile( file );
+  myWriter.SetMesh( const_cast<SMESHDS_Mesh*>( meshDS ));
+  myWriter.SetMeshName( SMESH_Comment("Mesh_") << meshDS->GetPersistentId());
+  res = myWriter.Perform();
+#endif
+  if ( res != Driver_Mesh::DRS_OK )
+    throw SALOME_Exception("Export failed");
+}
+
 //================================================================================
 /*!
  * \brief Return number of nodes in the mesh
  */
 //================================================================================
 
-int SMESH_Mesh::NbNodes() throw(SALOME_Exception)
+int SMESH_Mesh::NbNodes() const throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
   return _myMeshDS->NbNodes();
@@ -1178,7 +1409,19 @@ int SMESH_Mesh::NbNodes() throw(SALOME_Exception)
  */
 //================================================================================
 
-int SMESH_Mesh::NbEdges(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
+int SMESH_Mesh::Nb0DElements() const throw(SALOME_Exception)
+{
+  Unexpect aCatch(SalomeException);
+  return _myMeshDS->GetMeshInfo().Nb0DElements();
+}
+
+//================================================================================
+/*!
+ * \brief  Return number of edges of given order in the mesh
+ */
+//================================================================================
+
+int SMESH_Mesh::NbEdges(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
   return _myMeshDS->GetMeshInfo().NbEdges(order);
@@ -1190,7 +1433,7 @@ int SMESH_Mesh::NbEdges(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
  */
 //================================================================================
 
-int SMESH_Mesh::NbFaces(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
+int SMESH_Mesh::NbFaces(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
   return _myMeshDS->GetMeshInfo().NbFaces(order);
@@ -1202,7 +1445,7 @@ int SMESH_Mesh::NbFaces(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
  */
 //================================================================================
 
-int SMESH_Mesh::NbTriangles(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
+int SMESH_Mesh::NbTriangles(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
   return _myMeshDS->GetMeshInfo().NbTriangles(order);
@@ -1214,19 +1457,31 @@ int SMESH_Mesh::NbTriangles(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
  */
 //================================================================================
 
-int SMESH_Mesh::NbQuadrangles(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
+int SMESH_Mesh::NbQuadrangles(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
   return _myMeshDS->GetMeshInfo().NbQuadrangles(order);
 }
 
+//================================================================================
+/*!
+ * \brief Return number of biquadratic quadrangles in the mesh
+ */
+//================================================================================
+
+int SMESH_Mesh::NbBiQuadQuadrangles() const throw(SALOME_Exception)
+{
+  Unexpect aCatch(SalomeException);
+  return _myMeshDS->GetMeshInfo().NbBiQuadQuadrangles();
+}
+
 //================================================================================
 /*!
  * \brief Return the number of polygonal faces in the mesh
  */
 //================================================================================
 
-int SMESH_Mesh::NbPolygons() throw(SALOME_Exception)
+int SMESH_Mesh::NbPolygons() const throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
   return _myMeshDS->GetMeshInfo().NbPolygons();
@@ -1238,7 +1493,7 @@ int SMESH_Mesh::NbPolygons() throw(SALOME_Exception)
  */
 //================================================================================
 
-int SMESH_Mesh::NbVolumes(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
+int SMESH_Mesh::NbVolumes(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
   return _myMeshDS->GetMeshInfo().NbVolumes(order);
@@ -1250,7 +1505,7 @@ int SMESH_Mesh::NbVolumes(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
  */
 //================================================================================
 
-int SMESH_Mesh::NbTetras(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
+int SMESH_Mesh::NbTetras(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
   return _myMeshDS->GetMeshInfo().NbTetras(order);
@@ -1262,19 +1517,31 @@ int SMESH_Mesh::NbTetras(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
  */
 //================================================================================
 
-int SMESH_Mesh::NbHexas(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
+int SMESH_Mesh::NbHexas(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
   return _myMeshDS->GetMeshInfo().NbHexas(order);
 }
 
+//================================================================================
+/*!
+ * \brief  Return number of triquadratic hexahedrons in the mesh
+ */
+//================================================================================
+
+int SMESH_Mesh::NbTriQuadraticHexas() const throw(SALOME_Exception)
+{
+  Unexpect aCatch(SalomeException);
+  return _myMeshDS->GetMeshInfo().NbTriQuadHexas();
+}
+
 //================================================================================
 /*!
  * \brief  Return number of pyramids of given order in the mesh
  */
 //================================================================================
 
-int SMESH_Mesh::NbPyramids(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
+int SMESH_Mesh::NbPyramids(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
   return _myMeshDS->GetMeshInfo().NbPyramids(order);
@@ -1286,31 +1553,55 @@ int SMESH_Mesh::NbPyramids(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
  */
 //================================================================================
 
-int SMESH_Mesh::NbPrisms(SMDSAbs_ElementOrder order) throw(SALOME_Exception)
+int SMESH_Mesh::NbPrisms(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
   return _myMeshDS->GetMeshInfo().NbPrisms(order);
 }
 
+//================================================================================
+/*!
+ * \brief  Return number of hexagonal prisms in the mesh
+ */
+//================================================================================
+
+int SMESH_Mesh::NbHexagonalPrisms() const throw(SALOME_Exception)
+{
+  Unexpect aCatch(SalomeException);
+  return _myMeshDS->GetMeshInfo().NbHexPrisms();
+}
+
 //================================================================================
 /*!
  * \brief  Return number of polyhedrons in the mesh
  */
 //================================================================================
 
-int SMESH_Mesh::NbPolyhedrons() throw(SALOME_Exception)
+int SMESH_Mesh::NbPolyhedrons() const throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
   return _myMeshDS->GetMeshInfo().NbPolyhedrons();
 }
 
+//================================================================================
+/*!
+ * \brief  Return number of ball elements in the mesh
+ */
+//================================================================================
+
+int SMESH_Mesh::NbBalls() const throw(SALOME_Exception)
+{
+  Unexpect aCatch(SalomeException);
+  return _myMeshDS->GetMeshInfo().NbBalls();
+}
+
 //================================================================================
 /*!
  * \brief  Return number of submeshes in the mesh
  */
 //================================================================================
 
-int SMESH_Mesh::NbSubMesh() throw(SALOME_Exception)
+int SMESH_Mesh::NbSubMesh() const throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
   return _myMeshDS->NbSubMesh();
@@ -1347,18 +1638,45 @@ bool SMESH_Mesh::IsMainShape(const TopoDS_Shape& theShape) const
 
 SMESH_Group* SMESH_Mesh::AddGroup (const SMDSAbs_ElementType theType,
                                    const char*               theName,
-                                  int&                      theId,
-                                   const TopoDS_Shape&       theShape)
+                                   int&                      theId,
+                                   const TopoDS_Shape&       theShape,
+                                   const SMESH_PredicatePtr& thePredicate)
 {
-  if (_mapGroup.find(_groupId) != _mapGroup.end())
+  if (_mapGroup.count(_groupId))
     return NULL;
   theId = _groupId;
-  SMESH_Group* aGroup = new SMESH_Group (theId, this, theType, theName, theShape);
+  SMESH_Group* aGroup = new SMESH_Group (theId, this, theType, theName, theShape, thePredicate);
   GetMeshDS()->AddGroup( aGroup->GetGroupDS() );
   _mapGroup[_groupId++] = aGroup;
   return aGroup;
 }
 
+//================================================================================
+/*!
+ * \brief Creates SMESH_Groups for not wrapped SMESHDS_Groups
+ *  \retval bool - true if new SMESH_Groups have been created
+ * 
+ */
+//================================================================================
+
+bool SMESH_Mesh::SynchronizeGroups()
+{
+  int nbGroups = _mapGroup.size();
+  const set<SMESHDS_GroupBase*>& groups = _myMeshDS->GetGroups();
+  set<SMESHDS_GroupBase*>::const_iterator gIt = groups.begin();
+  for ( ; gIt != groups.end(); ++gIt )
+  {
+    SMESHDS_GroupBase* groupDS = (SMESHDS_GroupBase*) *gIt;
+    _groupId = groupDS->GetID();
+    if ( !_mapGroup.count( _groupId ))
+      _mapGroup[_groupId] = new SMESH_Group( groupDS );
+  }
+  if ( !_mapGroup.empty() )
+    _groupId = _mapGroup.rbegin()->first + 1;
+
+  return nbGroups < _mapGroup.size();
+}
+
 //================================================================================
 /*!
  * \brief Return iterator on all existing groups
@@ -1391,15 +1709,27 @@ SMESH_Group* SMESH_Mesh::GetGroup (const int theGroupID)
  */
 //=============================================================================
 
-std::list<int> SMESH_Mesh::GetGroupIds() const
+list<int> SMESH_Mesh::GetGroupIds() const
 {
-  std::list<int> anIds;
-  for ( std::map<int, SMESH_Group*>::const_iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ )
+  list<int> anIds;
+  for ( map<int, SMESH_Group*>::const_iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ )
     anIds.push_back( it->first );
   
   return anIds;
 }
 
+//================================================================================
+/*!
+ * \brief Set a caller of methods at level of CORBA API implementation.
+ * The set upCaller will be deleted by SMESH_Mesh
+ */
+//================================================================================
+
+void SMESH_Mesh::SetCallUp( TCallUp* upCaller )
+{
+  if ( _callUp ) delete _callUp;
+  _callUp = upCaller;
+}
 
 //=============================================================================
 /*!
@@ -1407,13 +1737,16 @@ std::list<int> SMESH_Mesh::GetGroupIds() const
  */
 //=============================================================================
 
-void SMESH_Mesh::RemoveGroup (const int theGroupID)
+bool SMESH_Mesh::RemoveGroup (const int theGroupID)
 {
   if (_mapGroup.find(theGroupID) == _mapGroup.end())
-    return;
+    return false;
   GetMeshDS()->RemoveGroup( _mapGroup[theGroupID]->GetGroupDS() );
   delete _mapGroup[theGroupID];
   _mapGroup.erase (theGroupID);
+  if (_callUp)
+    _callUp->RemoveGroup( theGroupID );
+  return true;
 }
 
 //=======================================================================
@@ -1459,7 +1792,7 @@ ostream& SMESH_Mesh::Dump(ostream& save)
       save << clause << ".1) Number of " << orderStr << " triangles:  \t" << nb3 << endl;
       save << clause << ".2) Number of " << orderStr << " quadrangles:\t" << nb4 << endl;
       if ( nb3 + nb4 !=  NbFaces(order) ) {
-        std::map<int,int> myFaceMap;
+        map<int,int> myFaceMap;
         SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator();
         while( itFaces->more( ) ) {
           int nbNodes = itFaces->next()->NbNodes();
@@ -1484,7 +1817,7 @@ ostream& SMESH_Mesh::Dump(ostream& save)
       save << clause << ".3) Number of " << orderStr << " prisms:      \t" << nb6 << endl;
       save << clause << ".4) Number of " << orderStr << " pyramids:\t" << nb5 << endl;
       if ( nb8 + nb4 + nb5 + nb6 != NbVolumes(order) ) {
-        std::map<int,int> myVolumesMap;
+        map<int,int> myVolumesMap;
         SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
         while( itVolumes->more( ) ) {
           int nbNodes = itVolumes->next()->NbNodes();
@@ -1523,7 +1856,7 @@ SMDSAbs_ElementType SMESH_Mesh::GetElementType( const int id, const bool iselem
 SMESH_Group* SMESH_Mesh::ConvertToStandalone ( int theGroupID )
 {
   SMESH_Group* aGroup = 0;
-  std::map < int, SMESH_Group * >::iterator itg = _mapGroup.find( theGroupID );
+  map < int, SMESH_Group * >::iterator itg = _mapGroup.find( theGroupID );
   if ( itg == _mapGroup.end() )
     return aGroup;
 
@@ -1545,9 +1878,153 @@ SMESH_Group* SMESH_Mesh::ConvertToStandalone ( int theGroupID )
   while ( anItr->more() )
     aNewGrpDS->Add( (anItr->next())->GetID() );
 
+  // set color
+  aNewGrpDS->SetColor( anOldGrpDS->GetColor() );
+
   // remove old group
   delete anOldGrp;
 
   return aGroup;
 }
 
+//=============================================================================
+/*!
+ *  \brief remove submesh order  from Mesh
+ */
+//=============================================================================
+
+void SMESH_Mesh::ClearMeshOrder()
+{
+  _mySubMeshOrder.clear();
+}
+
+//=============================================================================
+/*!
+ *  \brief remove submesh order  from Mesh
+ */
+//=============================================================================
+
+void SMESH_Mesh::SetMeshOrder(const TListOfListOfInt& theOrder )
+{
+  _mySubMeshOrder = theOrder;
+}
+
+//=============================================================================
+/*!
+ *  \brief return submesh order if any
+ */
+//=============================================================================
+
+const TListOfListOfInt& SMESH_Mesh::GetMeshOrder() const
+{
+  return _mySubMeshOrder;
+}
+
+//=============================================================================
+/*!
+ *  \brief fill _mapAncestors
+ */
+//=============================================================================
+
+void SMESH_Mesh::fillAncestorsMap(const TopoDS_Shape& theShape)
+{
+
+  int desType, ancType;
+  if ( !theShape.IsSame( GetShapeToMesh()) && theShape.ShapeType() == TopAbs_COMPOUND )
+  {
+    // a geom group is added. Insert it into lists of ancestors before
+    // the first ancestor more complex than group members
+    int memberType = TopoDS_Iterator( theShape ).Value().ShapeType();
+    for ( desType = TopAbs_VERTEX; desType >= memberType; desType-- )
+      for (TopExp_Explorer des( theShape, TopAbs_ShapeEnum( desType )); des.More(); des.Next())
+      {
+        if ( !_mapAncestors.Contains( des.Current() )) continue;// issue 0020982
+        TopTools_ListOfShape& ancList = _mapAncestors.ChangeFromKey( des.Current() );
+        TopTools_ListIteratorOfListOfShape ancIt (ancList);
+        while ( ancIt.More() && ancIt.Value().ShapeType() >= memberType )
+          ancIt.Next();
+        if ( ancIt.More() )
+          ancList.InsertBefore( theShape, ancIt );
+      }
+  }
+  {
+    for ( desType = TopAbs_VERTEX; desType > TopAbs_COMPOUND; desType-- )
+      for ( ancType = desType - 1; ancType >= TopAbs_COMPOUND; ancType-- )
+        TopExp::MapShapesAndAncestors ( theShape,
+                                        (TopAbs_ShapeEnum) desType,
+                                        (TopAbs_ShapeEnum) ancType,
+                                        _mapAncestors );
+  }
+}
+
+//=============================================================================
+/*!
+ * \brief sort submeshes according to stored mesh order
+ * \param theListToSort in out list to be sorted
+ * \return FALSE if nothing sorted
+ */
+//=============================================================================
+
+bool SMESH_Mesh::SortByMeshOrder(list<SMESH_subMesh*>& theListToSort) const
+{
+  if ( !_mySubMeshOrder.size() || theListToSort.size() < 2)
+    return true;
+  
+  bool res = false;
+  list<SMESH_subMesh*> onlyOrderedList;
+  // collect all ordered submeshes in one list as pointers
+  // and get their positions within theListToSort
+  typedef list<SMESH_subMesh*>::iterator TPosInList;
+  map< int, TPosInList > sortedPos;
+  TPosInList smBeg = theListToSort.begin(), smEnd = theListToSort.end();
+  TListOfListOfInt::const_iterator listIddIt = _mySubMeshOrder.begin();
+  for( ; listIddIt != _mySubMeshOrder.end(); listIddIt++) {
+    const TListOfInt& listOfId = *listIddIt;
+    TListOfInt::const_iterator idIt = listOfId.begin();
+    for ( ; idIt != listOfId.end(); idIt++ ) {
+      if ( SMESH_subMesh * sm = GetSubMeshContaining( *idIt )) {
+        TPosInList smPos = find( smBeg, smEnd, sm );
+        if ( smPos != smEnd ) {
+          onlyOrderedList.push_back( sm );
+          sortedPos[ distance( smBeg, smPos )] = smPos;
+        }
+      }
+    }
+  }
+  if (onlyOrderedList.size() < 2)
+    return res;
+  res = true;
+
+  list<SMESH_subMesh*>::iterator onlyBIt = onlyOrderedList.begin();
+  list<SMESH_subMesh*>::iterator onlyEIt = onlyOrderedList.end();
+
+  // iterate on ordered submeshes and insert them in detected positions
+  map< int, TPosInList >::iterator i_pos = sortedPos.begin();
+  for ( ; onlyBIt != onlyEIt; ++onlyBIt, ++i_pos )
+    *(i_pos->second) = *onlyBIt;
+
+  return res;
+}
+
+//=============================================================================
+/*!
+ * \brief sort submeshes according to stored mesh order
+ * \param theListToSort in out list to be sorted
+ * \return FALSE if nothing sorted
+ */
+//=============================================================================
+
+list<SMESH_subMesh*> SMESH_Mesh::getAncestorsSubMeshes
+  (const TopoDS_Shape& theSubShape) const
+{
+  list<SMESH_subMesh*> listOfSubMesh;
+  TopTools_ListIteratorOfListOfShape it( GetAncestors( theSubShape ));
+  for (; it.More(); it.Next() )
+    if ( SMESH_subMesh* sm = GetSubMeshContaining( it.Value() ))
+      listOfSubMesh.push_back(sm);
+
+  // sort submeshes according to stored mesh order
+  SortByMeshOrder( listOfSubMesh );
+
+  return listOfSubMesh;
+}
index 91ae67eda4fb1ccfe496f9c93922f268bb8a91fe..5ae3cc61c74899b386205e1231d7e81a630e89c6 100644 (file)
@@ -1,25 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-//  SMESH SMESH : implementaion of SMESH idl descriptions
+
 //  File   : SMESH_Mesh.hxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
@@ -30,6 +30,7 @@
 #include "SMESH_SMESH.hxx"
 
 #include "SMESH_Hypothesis.hxx"
+#include "SMESH_Controls.hxx"
 
 #include "SMESHDS_Mesh.hxx"
 #include "SMESHDS_Command.hxx"
 #include <TopoDS_Shape.hxx>
 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
 
-#include <list>
 #include <map>
+#include <list>
+
+#ifdef WNT
+#pragma warning(disable:4251) // Warning DLL Interface ...
+#pragma warning(disable:4290) // Warning Exception ...
+#endif
 
 class SMESH_Gen;
 class SMESHDS_Document;
@@ -51,14 +57,17 @@ class SMESH_subMesh;
 class SMESH_HypoFilter;
 class TopoDS_Solid;
 
+typedef std::list<int> TListOfInt;
+typedef std::list<TListOfInt> TListOfListOfInt;
+
 class SMESH_EXPORT SMESH_Mesh
 {
 public:
   SMESH_Mesh(int               theLocalId, 
-            int               theStudyId, 
-            SMESH_Gen*        theGen,
-            bool              theIsEmbeddedMode,
-            SMESHDS_Document* theDocument);
+             int               theStudyId, 
+             SMESH_Gen*        theGen,
+             bool              theIsEmbeddedMode,
+             SMESHDS_Document* theDocument);
   
   virtual ~SMESH_Mesh();
   
@@ -88,24 +97,30 @@ public:
    */
   static const TopoDS_Solid& PseudoShape();
 
+  /*!
+   * \brief Load mesh from study file
+   */
+  void Load();
   /*!
    * \brief Remove all nodes and elements
    */
   void Clear();
-
   /*!
    * \brief Remove all nodes and elements of indicated shape
    */
   void ClearSubMesh(const int theShapeId);
 
-  int UNVToMesh(const char* theFileName);
   /*!
    * consult DriverMED_R_SMESHDS_Mesh::ReadStatus for returned value
    */
+  int UNVToMesh(const char* theFileName);
+
   int MEDToMesh(const char* theFileName, const char* theMeshName);
   
   int STLToMesh(const char* theFileName);
 
+  int CGNSToMesh(const char* theFileName, const int theMeshIndex, std::string& theMeshName);
+  
   SMESH_Hypothesis::Hypothesis_Status
   AddHypothesis(const TopoDS_Shape & aSubShape, int anHypId)
     throw(SALOME_Exception);
@@ -132,12 +147,16 @@ public:
   
   void ClearLog() throw(SALOME_Exception);
   
-  int GetId()                { return _id; }
+  int GetId() const          { return _id; }
+  
+  bool MeshExists( int meshId ) const;
   
   SMESHDS_Mesh * GetMeshDS() { return _myMeshDS; }
   
-  SMESH_Gen *GetGen()        { return _gen; }
+  const SMESHDS_Mesh * GetMeshDS() const { return _myMeshDS; }
   
+  SMESH_Gen *GetGen()        { return _gen; }
+
   SMESH_subMesh *GetSubMesh(const TopoDS_Shape & aSubShape)
     throw(SALOME_Exception);
   
@@ -162,7 +181,7 @@ public:
    * \brief Return True if anHyp is used to mesh aSubShape
    */
   bool IsUsedHypothesis(SMESHDS_Hypothesis *  anHyp,
-                       const SMESH_subMesh * aSubMesh);
+                        const SMESH_subMesh * aSubMesh);
   /*!
    * \brief check if a hypothesis alowing notconform mesh is present
    */
@@ -179,6 +198,21 @@ public:
 
   bool GetAutoColor() throw(SALOME_Exception);
 
+  /*!
+   * \brief Set the flag meaning that the mesh has been edited "manually".
+   * It is to set to false after Clear() and to set to true by MeshEditor
+   */
+  void SetIsModified(bool isModified);
+
+  bool GetIsModified() const { return _isModified; }
+
+  /*!
+   * \brief Return true if the mesh has been edited since a total re-compute
+   *        and those modifications may prevent successful partial re-compute.
+   *        As a side effect reset _isModified flag if mesh is empty
+   */
+  bool HasModificationsToDiscard() const;
+
   /*!
    * \brief Return data map of descendant to ancestor shapes
    */
@@ -191,47 +225,68 @@ public:
   bool HasDuplicatedGroupNamesMED();
 
   void ExportMED(const char *file, 
-                const char* theMeshName = NULL, 
-                bool theAutoGroups = true, 
-                int theVersion = 0) 
+                 const char* theMeshName = NULL, 
+                 bool theAutoGroups = true, 
+                 int theVersion = 0,
+                 const SMESHDS_Mesh* meshPart = 0) 
     throw(SALOME_Exception);
 
-  void ExportDAT(const char *file) throw(SALOME_Exception);
-  void ExportUNV(const char *file) throw(SALOME_Exception);
-  void ExportSTL(const char *file, const bool isascii) throw(SALOME_Exception);
+  void ExportDAT(const char *        file,
+                 const SMESHDS_Mesh* meshPart = 0) throw(SALOME_Exception);
+  void ExportUNV(const char *        file,
+                 const SMESHDS_Mesh* meshPart = 0) throw(SALOME_Exception);
+  void ExportSTL(const char *        file,
+                 const bool          isascii,
+                 const SMESHDS_Mesh* meshPart = 0) throw(SALOME_Exception);
+  void ExportCGNS(const char *        file,
+                  const SMESHDS_Mesh* mesh);
+  void ExportSAUV(const char *file, 
+                  const char* theMeshName = NULL, 
+                  bool theAutoGroups = true) throw(SALOME_Exception);
+  
+  int NbNodes() const throw(SALOME_Exception);
   
-  int NbNodes() throw(SALOME_Exception);
+  int Nb0DElements() const throw(SALOME_Exception);
   
-  int NbEdges(SMDSAbs_ElementOrder order = ORDER_ANY) throw(SALOME_Exception);
+  int NbEdges(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception);
   
-  int NbFaces(SMDSAbs_ElementOrder order = ORDER_ANY) throw(SALOME_Exception);
+  int NbFaces(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception);
   
-  int NbTriangles(SMDSAbs_ElementOrder order = ORDER_ANY) throw(SALOME_Exception);
+  int NbTriangles(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception);
   
-  int NbQuadrangles(SMDSAbs_ElementOrder order = ORDER_ANY) throw(SALOME_Exception);
+  int NbQuadrangles(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception);
 
-  int NbPolygons() throw(SALOME_Exception);
+  int NbBiQuadQuadrangles() const throw(SALOME_Exception);
+  
+  int NbPolygons() const throw(SALOME_Exception);
   
-  int NbVolumes(SMDSAbs_ElementOrder order = ORDER_ANY) throw(SALOME_Exception);
+  int NbVolumes(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception);
   
-  int NbTetras(SMDSAbs_ElementOrder order = ORDER_ANY) throw(SALOME_Exception);
+  int NbTetras(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception);
   
-  int NbHexas(SMDSAbs_ElementOrder order = ORDER_ANY) throw(SALOME_Exception);
+  int NbHexas(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception);
   
-  int NbPyramids(SMDSAbs_ElementOrder order = ORDER_ANY) throw(SALOME_Exception);
+  int NbTriQuadraticHexas() const throw(SALOME_Exception);
+  
+  int NbPyramids(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception);
 
-  int NbPrisms(SMDSAbs_ElementOrder order = ORDER_ANY) throw(SALOME_Exception);
+  int NbPrisms(SMDSAbs_ElementOrder order = ORDER_ANY) const throw(SALOME_Exception);
   
-  int NbPolyhedrons() throw(SALOME_Exception);
+  int NbHexagonalPrisms() const throw(SALOME_Exception);
   
-  int NbSubMesh() throw(SALOME_Exception);
+  int NbPolyhedrons() const throw(SALOME_Exception);
   
-  int NbGroup() const { return _mapGroup.size(); }
+  int NbBalls() const throw(SALOME_Exception);
+  
+  int NbSubMesh() const throw(SALOME_Exception);
   
+  int NbGroup() const { return _mapGroup.size(); }
+
   SMESH_Group* AddGroup (const SMDSAbs_ElementType theType,
-                        const char*               theName,
-                        int&                      theId,
-                         const TopoDS_Shape&       theShape=TopoDS_Shape());
+                         const char*               theName,
+                         int&                      theId,
+                         const TopoDS_Shape&       theShape=TopoDS_Shape(),
+                         const SMESH_PredicatePtr& thePredicate=SMESH_PredicatePtr());
   
   typedef boost::shared_ptr< SMDS_Iterator<SMESH_Group*> > GroupIteratorPtr;
   GroupIteratorPtr GetGroups() const;
@@ -240,39 +295,76 @@ public:
   
   SMESH_Group* GetGroup (const int theGroupID);
 
-  void RemoveGroup (const int theGroupID);
+  bool RemoveGroup (const int theGroupID);
 
   SMESH_Group* ConvertToStandalone ( int theGroupID );
 
+  struct TCallUp // callback from SMESH to SMESH_I level
+  {
+    virtual void RemoveGroup (const int theGroupID)=0;
+    virtual void HypothesisModified ()=0;
+    virtual void Load ()=0;
+    virtual ~TCallUp() {}
+  };
+  void SetCallUp( TCallUp * upCaller );
+
+  bool SynchronizeGroups();
+
+
   SMDSAbs_ElementType GetElementType( const int id, const bool iselem );
 
+  void ClearMeshOrder();
+  void SetMeshOrder(const TListOfListOfInt& theOrder );
+  const TListOfListOfInt& GetMeshOrder() const;
+
+  /*!
+   * \brief sort submeshes according to stored mesh order
+   * \param theListToSort in out list to be sorted
+   * \return FALSE if nothing sorted
+   */
+  bool SortByMeshOrder(std::list<SMESH_subMesh*>& theListToSort) const;
+
   //
   
   ostream& Dump(ostream & save);
   
 private:
+
+  void fillAncestorsMap(const TopoDS_Shape& theShape);
+  std::list<SMESH_subMesh*> getAncestorsSubMeshes
+    (const TopoDS_Shape& theSubShape) const;
   
 protected:
   int                        _id;           // id given by creator (unique within the creator instance)
   int                        _studyId;
   int                        _idDoc;        // id given by SMESHDS_Document
   int                        _groupId;      // id generator for group objects
+  int                        _nbSubShapes;  // initial nb of subshapes in the shape to mesh
   bool                       _isShapeToMesh;// set to true when a shape is given (only once)
   std::list <SMESH_subMesh*> _subMeshesUsingHypothesisList;
   SMESHDS_Document *         _myDocument;
   SMESHDS_Mesh *             _myMeshDS;
+  SMESH_Gen *                _gen;
   std::map <int, SMESH_subMesh*> _mapSubMesh;
   std::map <int, SMESH_Group*>   _mapGroup;
-  SMESH_Gen *                _gen;
-
+  
   bool                       _isAutoColor;
+  bool                       _isModified; //!< modified since last total re-compute, issue 0020693
 
   double                     _shapeDiagonal; //!< diagonal size of bounding box of shape to mesh
   
   TopTools_IndexedDataMapOfShapeListOfShape _mapAncestors;
 
+  TListOfListOfInt           _mySubMeshOrder;
+
+  // Struct calling methods at CORBA API implementation level, used to
+  // 1) make an upper level be consistent with a lower one when group removal
+  // is invoked by hyp modification (issue 0020918)
+  // 2) to forget not loaded mesh data at hyp modification
+  TCallUp*                    _callUp;
+
 protected:
-  SMESH_Mesh() {};
+  SMESH_Mesh();
   SMESH_Mesh(const SMESH_Mesh&) {};
 };
 
index 063f68819b32d16555af4e0042897aa02c1fdbac..324b6b81dabf7a55c2d5b9085717e9d949de8ae6 100644 (file)
@@ -1,66 +1,83 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-//  SMESH SMESH : idl implementation based on 'SMESH' unit's classes
+
 // File      : SMESH_MeshEditor.cxx
 // Created   : Mon Apr 12 16:10:22 2004
 // Author    : Edward AGAPOV (eap)
-//
+
 #include "SMESH_MeshEditor.hxx"
 
 #include "SMDS_FaceOfNodes.hxx"
 #include "SMDS_VolumeTool.hxx"
 #include "SMDS_EdgePosition.hxx"
-#include "SMDS_PolyhedralVolumeOfNodes.hxx"
 #include "SMDS_FacePosition.hxx"
 #include "SMDS_SpacePosition.hxx"
-#include "SMDS_QuadraticFaceOfNodes.hxx"
 #include "SMDS_MeshGroup.hxx"
+#include "SMDS_LinearEdge.hxx"
+#include "SMDS_Downward.hxx"
+#include "SMDS_SetIterator.hxx"
 
 #include "SMESHDS_Group.hxx"
 #include "SMESHDS_Mesh.hxx"
 
-#include "SMESH_subMesh.hxx"
+#include "SMESH_Algo.hxx"
 #include "SMESH_ControlsDef.hxx"
+#include "SMESH_Group.hxx"
 #include "SMESH_MesherHelper.hxx"
 #include "SMESH_OctreeNode.hxx"
-#include "SMESH_Group.hxx"
+#include "SMESH_subMesh.hxx"
+
+#include <Basics_OCCTVersion.hxx>
 
 #include "utilities.h"
 
+#include <BRepAdaptor_Surface.hxx>
+#include <BRepBuilderAPI_MakeEdge.hxx>
+#include <BRepClass3d_SolidClassifier.hxx>
 #include <BRep_Tool.hxx>
 #include <ElCLib.hxx>
 #include <Extrema_GenExtPS.hxx>
+#include <Extrema_POnCurv.hxx>
 #include <Extrema_POnSurf.hxx>
+#include <GC_MakeSegment.hxx>
 #include <Geom2d_Curve.hxx>
+#include <GeomAPI_ExtremaCurveCurve.hxx>
 #include <GeomAdaptor_Surface.hxx>
 #include <Geom_Curve.hxx>
+#include <Geom_Line.hxx>
 #include <Geom_Surface.hxx>
+#include <IntAna_IntConicQuad.hxx>
+#include <IntAna_Quadric.hxx>
+#include <Precision.hxx>
 #include <TColStd_ListOfInteger.hxx>
+#include <TopAbs_State.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopTools_ListOfShape.hxx>
+#include <TopTools_SequenceOfShape.hxx>
 #include <TopoDS.hxx>
 #include <TopoDS_Face.hxx>
+#include <TopoDS_Solid.hxx>
 #include <gp.hxx>
 #include <gp_Ax1.hxx>
 #include <gp_Dir.hxx>
 #include <gp_Vec.hxx>
 #include <gp_XY.hxx>
 #include <gp_XYZ.hxx>
-#include <math.h>
+
+#include <cmath>
 
 #include <map>
 #include <set>
+#include <numeric>
+#include <limits>
+#include <algorithm>
+#include <sstream>
+
+#include <Standard_Failure.hxx>
+#include <Standard_ErrorHandler.hxx>
 
 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
 
@@ -82,13 +107,8 @@ using namespace SMESH::Controls;
 
 typedef map<const SMDS_MeshElement*, list<const SMDS_MeshNode*> >    TElemOfNodeListMap;
 typedef map<const SMDS_MeshElement*, list<const SMDS_MeshElement*> > TElemOfElemListMap;
-//typedef map<const SMDS_MeshNode*, vector<const SMDS_MeshNode*> >     TNodeOfNodeVecMap;
-//typedef TNodeOfNodeVecMap::iterator                                  TNodeOfNodeVecMapItr;
-//typedef map<const SMDS_MeshElement*, vector<TNodeOfNodeVecMapItr> >  TElemOfVecOfMapNodesMap;
 
-struct TNodeXYZ : public gp_XYZ {
-  TNodeXYZ( const SMDS_MeshNode* n ):gp_XYZ( n->X(), n->Y(), n->Z() ) {}
-};
+typedef SMDS_SetIterator< SMDS_pElement, TIDSortedElemSet::const_iterator> TSetIterator;
 
 //=======================================================================
 //function : SMESH_MeshEditor
@@ -110,101 +130,170 @@ SMDS_MeshElement*
 SMESH_MeshEditor::AddElement(const vector<const SMDS_MeshNode*> & node,
                              const SMDSAbs_ElementType            type,
                              const bool                           isPoly,
-                             const int                            ID)
+                             const int                            ID,
+                             const double                         ballDiameter)
 {
+  //MESSAGE("AddElement " <<node.size() << " " << type << " " << isPoly << " " << ID);
   SMDS_MeshElement* e = 0;
   int nbnode = node.size();
   SMESHDS_Mesh* mesh = GetMeshDS();
   switch ( type ) {
-  case SMDSAbs_Edge:
-    if ( nbnode == 2 )
-      if ( ID ) e = mesh->AddEdgeWithID(node[0], node[1], ID);
-      else      e = mesh->AddEdge      (node[0], node[1] );
-    else if ( nbnode == 3 )
-      if ( ID ) e = mesh->AddEdgeWithID(node[0], node[1], node[2], ID);
-      else      e = mesh->AddEdge      (node[0], node[1], node[2] );
-    break;
   case SMDSAbs_Face:
     if ( !isPoly ) {
-      if      (nbnode == 3)
-        if ( ID ) e = mesh->AddFaceWithID(node[0], node[1], node[2], ID);
-        else      e = mesh->AddFace      (node[0], node[1], node[2] );
-      else if (nbnode == 4) 
-        if ( ID ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3], ID);
-        else      e = mesh->AddFace      (node[0], node[1], node[2], node[3] );
-      else if (nbnode == 6)
-        if ( ID ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3],
-                                          node[4], node[5], ID);
-        else      e = mesh->AddFace      (node[0], node[1], node[2], node[3],
-                                          node[4], node[5] );
-      else if (nbnode == 8)
-        if ( ID ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3],
-                                          node[4], node[5], node[6], node[7], ID);
-        else      e = mesh->AddFace      (node[0], node[1], node[2], node[3],
-                                          node[4], node[5], node[6], node[7] );
+      if      (nbnode == 3) {
+        if ( ID >= 1 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], ID);
+        else           e = mesh->AddFace      (node[0], node[1], node[2] );
+      }
+      else if (nbnode == 4) {
+        if ( ID >= 1 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3], ID);
+        else           e = mesh->AddFace      (node[0], node[1], node[2], node[3] );
+      }
+      else if (nbnode == 6) {
+        if ( ID >= 1 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3],
+                                               node[4], node[5], ID);
+        else           e = mesh->AddFace      (node[0], node[1], node[2], node[3],
+                                               node[4], node[5] );
+      }
+      else if (nbnode == 8) {
+        if ( ID >= 1 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3],
+                                               node[4], node[5], node[6], node[7], ID);
+        else           e = mesh->AddFace      (node[0], node[1], node[2], node[3],
+                                               node[4], node[5], node[6], node[7] );
+      }
+      else if (nbnode == 9) {
+        if ( ID >= 1 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3],
+                                               node[4], node[5], node[6], node[7], node[8], ID);
+        else           e = mesh->AddFace      (node[0], node[1], node[2], node[3],
+                                               node[4], node[5], node[6], node[7], node[8] );
+      }
     } else {
-      if ( ID ) e = mesh->AddPolygonalFaceWithID(node, ID);
-      else      e = mesh->AddPolygonalFace      (node    );
+      if ( ID >= 1 ) e = mesh->AddPolygonalFaceWithID(node, ID);
+      else           e = mesh->AddPolygonalFace      (node    );
     }
     break;
+
   case SMDSAbs_Volume:
     if ( !isPoly ) {
-      if      (nbnode == 4)
-        if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], ID);
-        else      e = mesh->AddVolume      (node[0], node[1], node[2], node[3] );
-      else if (nbnode == 5)
-        if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
-                                            node[4], ID);
-        else      e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
-                                            node[4] );
-      else if (nbnode == 6)
-        if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
-                                            node[4], node[5], ID);
-        else      e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
-                                            node[4], node[5] );
-      else if (nbnode == 8)
-        if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
-                                            node[4], node[5], node[6], node[7], ID);
-        else      e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
-                                            node[4], node[5], node[6], node[7] );
-      else if (nbnode == 10)
-        if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
-                                            node[4], node[5], node[6], node[7],
-                                            node[8], node[9], ID);
-        else      e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
-                                            node[4], node[5], node[6], node[7],
-                                            node[8], node[9] );
-      else if (nbnode == 13)
-        if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
-                                            node[4], node[5], node[6], node[7],
-                                            node[8], node[9], node[10],node[11],
-                                            node[12],ID);
-        else      e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
-                                            node[4], node[5], node[6], node[7],
-                                            node[8], node[9], node[10],node[11],
-                                            node[12] );
-      else if (nbnode == 15)
-        if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
-                                            node[4], node[5], node[6], node[7],
-                                            node[8], node[9], node[10],node[11],
-                                            node[12],node[13],node[14],ID);
-        else      e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
-                                            node[4], node[5], node[6], node[7],
-                                            node[8], node[9], node[10],node[11],
-                                            node[12],node[13],node[14] );
-      else if (nbnode == 20)
-        if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
-                                            node[4], node[5], node[6], node[7],
-                                            node[8], node[9], node[10],node[11],
-                                            node[12],node[13],node[14],node[15],
-                                            node[16],node[17],node[18],node[19],ID);
-        else      e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
-                                            node[4], node[5], node[6], node[7],
-                                            node[8], node[9], node[10],node[11],
-                                            node[12],node[13],node[14],node[15],
-                                            node[16],node[17],node[18],node[19] );
+      if      (nbnode == 4) {
+        if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], ID);
+        else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3] );
+      }
+      else if (nbnode == 5) {
+        if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+                                                 node[4], ID);
+        else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
+                                                 node[4] );
+      }
+      else if (nbnode == 6) {
+        if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], ID);
+        else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
+                                                 node[4], node[5] );
+      }
+      else if (nbnode == 8) {
+        if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7], ID);
+        else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7] );
+      }
+      else if (nbnode == 10) {
+        if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9], ID);
+        else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9] );
+      }
+      else if (nbnode == 12) {
+        if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9], node[10], node[11], ID);
+        else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9], node[10], node[11] );
+      }
+      else if (nbnode == 13) {
+        if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9], node[10],node[11],
+                                                 node[12],ID);
+        else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9], node[10],node[11],
+                                                 node[12] );
+      }
+      else if (nbnode == 15) {
+        if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9], node[10],node[11],
+                                                 node[12],node[13],node[14],ID);
+        else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9], node[10],node[11],
+                                                 node[12],node[13],node[14] );
+      }
+      else if (nbnode == 20) {
+        if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9], node[10],node[11],
+                                                 node[12],node[13],node[14],node[15],
+                                                 node[16],node[17],node[18],node[19],ID);
+        else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9], node[10],node[11],
+                                                 node[12],node[13],node[14],node[15],
+                                                 node[16],node[17],node[18],node[19] );
+      }
+      else if (nbnode == 27) {
+        if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9], node[10],node[11],
+                                                 node[12],node[13],node[14],node[15],
+                                                 node[16],node[17],node[18],node[19],
+                                                 node[20],node[21],node[22],node[23],
+                                                 node[24],node[25],node[26], ID);
+        else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9], node[10],node[11],
+                                                 node[12],node[13],node[14],node[15],
+                                                 node[16],node[17],node[18],node[19],
+                                                 node[20],node[21],node[22],node[23],
+                                                 node[24],node[25],node[26] );
+      }
     }
+    break;
+
+  case SMDSAbs_Edge:
+    if ( nbnode == 2 ) {
+      if ( ID >= 1 ) e = mesh->AddEdgeWithID(node[0], node[1], ID);
+      else           e = mesh->AddEdge      (node[0], node[1] );
+    }
+    else if ( nbnode == 3 ) {
+      if ( ID >= 1 ) e = mesh->AddEdgeWithID(node[0], node[1], node[2], ID);
+      else           e = mesh->AddEdge      (node[0], node[1], node[2] );
+    }
+    break;
+
+  case SMDSAbs_0DElement:
+    if ( nbnode == 1 ) {
+      if ( ID >= 1 ) e = mesh->Add0DElementWithID(node[0], ID);
+      else           e = mesh->Add0DElement      (node[0] );
+    }
+    break;
+
+  case SMDSAbs_Node:
+    if ( ID >= 1 ) e = mesh->AddNodeWithID(node[0]->X(), node[0]->Y(), node[0]->Z(), ID);
+    else           e = mesh->AddNode      (node[0]->X(), node[0]->Y(), node[0]->Z());
+    break;
+
+  case SMDSAbs_Ball:
+    if ( ID >= 1 ) e = mesh->AddBallWithID(node[0], ballDiameter, ID);
+    else           e = mesh->AddBall      (node[0], ballDiameter);
+    break;
+
+  default:;
   }
+  if ( e ) myLastCreatedElems.Append( e );
   return e;
 }
 
@@ -237,8 +326,8 @@ SMDS_MeshElement* SMESH_MeshEditor::AddElement(const vector<int> &       nodeIDs
 //           Modify a compute state of sub-meshes which become empty
 //=======================================================================
 
-bool SMESH_MeshEditor::Remove (const list< int >& theIDs,
-                               const bool         isNodes )
+int SMESH_MeshEditor::Remove (const list< int >& theIDs,
+                              const bool         isNodes )
 {
   myLastCreatedElems.Clear();
   myLastCreatedNodes.Clear();
@@ -246,6 +335,7 @@ bool SMESH_MeshEditor::Remove (const list< int >& theIDs,
   SMESHDS_Mesh* aMesh = GetMeshDS();
   set< SMESH_subMesh *> smmap;
 
+  int removed = 0;
   list<int>::const_iterator it = theIDs.begin();
   for ( ; it != theIDs.end(); it++ ) {
     const SMDS_MeshElement * elem;
@@ -260,28 +350,29 @@ bool SMESH_MeshEditor::Remove (const list< int >& theIDs,
     if ( isNodes ) {
       const SMDS_MeshNode* node = cast2Node( elem );
       if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX )
-        if ( int aShapeID = node->GetPosition()->GetShapeId() )
+        if ( int aShapeID = node->getshapeId() )
           if ( SMESH_subMesh * sm = GetMesh()->GetSubMeshContaining( aShapeID ) )
             smmap.insert( sm );
     }
     // Find sub-meshes to notify about modification
-//     SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
-//     while ( nodeIt->more() ) {
-//       const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-//       const SMDS_PositionPtr& aPosition = node->GetPosition();
-//       if ( aPosition.get() ) {
-//         if ( int aShapeID = aPosition->GetShapeId() ) {
-//           if ( SMESH_subMesh * sm = GetMesh()->GetSubMeshContaining( aShapeID ) )
-//             smmap.insert( sm );
-//         }
-//       }
-//     }
+    //     SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
+    //     while ( nodeIt->more() ) {
+    //       const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+    //       const SMDS_PositionPtr& aPosition = node->GetPosition();
+    //       if ( aPosition.get() ) {
+    //         if ( int aShapeID = aPosition->GetShapeId() ) {
+    //           if ( SMESH_subMesh * sm = GetMesh()->GetSubMeshContaining( aShapeID ) )
+    //             smmap.insert( sm );
+    //         }
+    //       }
+    //     }
 
     // Do remove
     if ( isNodes )
       aMesh->RemoveNode( static_cast< const SMDS_MeshNode* >( elem ));
     else
       aMesh->RemoveElement( elem );
+    removed++;
   }
 
   // Notify sub-meshes about modification
@@ -291,11 +382,11 @@ bool SMESH_MeshEditor::Remove (const list< int >& theIDs,
       (*smIt)->ComputeStateEngine( SMESH_subMesh::MESH_ENTITY_REMOVED );
   }
 
-//   // Check if the whole mesh becomes empty
-//   if ( SMESH_subMesh * sm = GetMesh()->GetSubMeshContaining( 1 ) )
-//     sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+  //   // Check if the whole mesh becomes empty
+  //   if ( SMESH_subMesh * sm = GetMesh()->GetSubMeshContaining( 1 ) )
+  //     sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
 
-  return true;
+  return removed;
 }
 
 //=======================================================================
@@ -313,46 +404,55 @@ int SMESH_MeshEditor::FindShape (const SMDS_MeshElement * theElem)
   if ( aMesh->ShapeToMesh().IsNull() )
     return 0;
 
+  int aShapeID = theElem->getshapeId();
+  if ( aShapeID < 1 )
+    return 0;
+
+  if ( SMESHDS_SubMesh * sm = aMesh->MeshElements( aShapeID ))
+    if ( sm->Contains( theElem ))
+      return aShapeID;
+
   if ( theElem->GetType() == SMDSAbs_Node ) {
-    const SMDS_PositionPtr& aPosition =
-      static_cast<const SMDS_MeshNode*>( theElem )->GetPosition();
-    if ( aPosition.get() )
-      return aPosition->GetShapeId();
-    else
-      return 0;
+    MESSAGE( ":( Error: invalid myShapeId of node " << theElem->GetID() );
+  }
+  else {
+    MESSAGE( ":( Error: invalid myShapeId of element " << theElem->GetID() );
   }
 
-  TopoDS_Shape aShape; // the shape a node is on
-  SMDS_ElemIteratorPtr nodeIt = theElem->nodesIterator();
-  while ( nodeIt->more() ) {
-    const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-    const SMDS_PositionPtr& aPosition = node->GetPosition();
-    if ( aPosition.get() ) {
-      int aShapeID = aPosition->GetShapeId();
-      SMESHDS_SubMesh * sm = aMesh->MeshElements( aShapeID );
-      if ( sm ) {
-        if ( sm->Contains( theElem ))
-          return aShapeID;
-        if ( aShape.IsNull() )
-          aShape = aMesh->IndexToShape( aShapeID );
-      }
-      else {
-        //MESSAGE ( "::FindShape() No SubShape for aShapeID " << aShapeID );
+  TopoDS_Shape aShape; // the shape a node of theElem is on
+  if ( theElem->GetType() != SMDSAbs_Node )
+  {
+    SMDS_ElemIteratorPtr nodeIt = theElem->nodesIterator();
+    while ( nodeIt->more() ) {
+      const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+      if ((aShapeID = node->getshapeId()) > 0) {
+        if ( SMESHDS_SubMesh * sm = aMesh->MeshElements( aShapeID ) ) {
+          if ( sm->Contains( theElem ))
+            return aShapeID;
+          if ( aShape.IsNull() )
+            aShape = aMesh->IndexToShape( aShapeID );
+        }
       }
     }
   }
 
   // None of nodes is on a proper shape,
   // find the shape among ancestors of aShape on which a node is
-  if ( aShape.IsNull() ) {
-    //MESSAGE ("::FindShape() - NONE node is on shape")
-    return 0;
+  if ( !aShape.IsNull() ) {
+    TopTools_ListIteratorOfListOfShape ancIt( GetMesh()->GetAncestors( aShape ));
+    for ( ; ancIt.More(); ancIt.Next() ) {
+      SMESHDS_SubMesh * sm = aMesh->MeshElements( ancIt.Value() );
+      if ( sm && sm->Contains( theElem ))
+        return aMesh->ShapeToIndex( ancIt.Value() );
+    }
   }
-  TopTools_ListIteratorOfListOfShape ancIt( GetMesh()->GetAncestors( aShape ));
-  for ( ; ancIt.More(); ancIt.Next() ) {
-    SMESHDS_SubMesh * sm = aMesh->MeshElements( ancIt.Value() );
-    if ( sm && sm->Contains( theElem ))
-      return aMesh->ShapeToIndex( ancIt.Value() );
+  else
+  {
+    const map<int,SMESHDS_SubMesh*>& id2sm = GetMeshDS()->SubMeshes();
+    map<int,SMESHDS_SubMesh*>::const_iterator id_sm = id2sm.begin();
+    for ( ; id_sm != id2sm.end(); ++id_sm )
+      if ( id_sm->second->Contains( theElem ))
+        return id_sm->first;
   }
 
   //MESSAGE ("::FindShape() - SHAPE NOT FOUND")
@@ -394,6 +494,25 @@ static void ShiftNodesQuadTria(const SMDS_MeshNode* aNodes[])
   aNodes[5] = nd2;
 }
 
+//=======================================================================
+//function : edgeConnectivity
+//purpose  : auxilary 
+//           return number of the edges connected with the theNode.
+//           if theEdges has connections with the other type of the
+//           elements, return -1 
+//=======================================================================
+static int nbEdgeConnectivity(const SMDS_MeshNode* theNode)
+{
+  SMDS_ElemIteratorPtr elemIt = theNode->GetInverseElementIterator();
+  int nb=0;
+  while(elemIt->more()) {
+    elemIt->next();
+    nb++;
+  }
+  return nb;
+}
+
+
 //=======================================================================
 //function : GetNodesFromTwoTria
 //purpose  : auxilary
@@ -459,15 +578,19 @@ static bool GetNodesFromTwoTria(const SMDS_MeshElement * theTria1,
 bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshElement * theTria1,
                                     const SMDS_MeshElement * theTria2 )
 {
+  MESSAGE("InverseDiag");
   myLastCreatedElems.Clear();
   myLastCreatedNodes.Clear();
 
   if (!theTria1 || !theTria2)
     return false;
 
-  const SMDS_FaceOfNodes* F1 = dynamic_cast<const SMDS_FaceOfNodes*>( theTria1 );
-  const SMDS_FaceOfNodes* F2 = dynamic_cast<const SMDS_FaceOfNodes*>( theTria2 );
-  if (F1 && F2) {
+  const SMDS_VtkFace* F1 = dynamic_cast<const SMDS_VtkFace*>( theTria1 );
+  if (!F1) return false;
+  const SMDS_VtkFace* F2 = dynamic_cast<const SMDS_VtkFace*>( theTria2 );
+  if (!F2) return false;
+  if ((theTria1->GetEntityType() == SMDSEntity_Triangle) &&
+      (theTria2->GetEntityType() == SMDSEntity_Triangle)) {
 
     //  1 +--+ A  theTria1: ( 1 A B ) A->2 ( 1 2 B ) 1 +--+ A
     //    | /|    theTria2: ( B A 2 ) B->1 ( 1 A 2 )   |\ |
@@ -504,12 +627,14 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshElement * theTria1,
     // find indices of 1,2 and of A,B in theTria1
     int iA = 0, iB = 0, i1 = 0, i2 = 0;
     for ( i = 0; i < 6; i++ ) {
-      if ( sameInd [ i ] == 0 )
+      if ( sameInd [ i ] == 0 ) {
         if ( i < 3 ) i1 = i;
         else         i2 = i;
-      else if (i < 3)
+      }
+      else if (i < 3) {
         if ( iA ) iB = i;
         else      iA = i;
+      }
     }
     // nodes 1 and 2 should not be the same
     if ( aNodes[ i1 ] == aNodes[ i2 ] )
@@ -520,24 +645,18 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshElement * theTria1,
     // theTria2: B->1
     aNodes[ sameInd[ iB ]] = aNodes[ i1 ];
 
-    //MESSAGE( theTria1 << theTria2 );
-
     GetMeshDS()->ChangeElementNodes( theTria1, aNodes, 3 );
     GetMeshDS()->ChangeElementNodes( theTria2, &aNodes[ 3 ], 3 );
 
-    //MESSAGE( theTria1 << theTria2 );
-
     return true;
 
   } // end if(F1 && F2)
 
   // check case of quadratic faces
-  const SMDS_QuadraticFaceOfNodes* QF1 =
-    dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (theTria1);
-  if(!QF1) return false;
-  const SMDS_QuadraticFaceOfNodes* QF2 =
-    dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (theTria2);
-  if(!QF2) return false;
+  if (theTria1->GetEntityType() != SMDSEntity_Quad_Triangle)
+    return false;
+  if (theTria2->GetEntityType() != SMDSEntity_Quad_Triangle)
+    return false;
 
   //       5
   //  1 +--+--+ 2  theTria1: (1 2 4 5 9 7) or (2 4 1 9 7 5) or (4 1 2 7 5 9)
@@ -602,7 +721,7 @@ static bool findTriangles(const SMDS_MeshNode *    theNode1,
   it = theNode2->GetInverseElementIterator(SMDSAbs_Face);
   while (it->more()) {
     const SMDS_MeshElement* elem = it->next();
-    if ( emap.find( elem ) != emap.end() )
+    if ( emap.find( elem ) != emap.end() ) {
       if ( theTria1 ) {
         // theTria1 must be element with minimum ID
         if( theTria1->GetID() < elem->GetID() ) {
@@ -617,6 +736,7 @@ static bool findTriangles(const SMDS_MeshNode *    theNode1,
       else {
         theTria1 = elem;
       }
+    }
   }
   return ( theTria1 && theTria2 );
 }
@@ -640,11 +760,12 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshNode * theNode1,
   if ( !findTriangles( theNode1, theNode2, tr1, tr2 ))
     return false;
 
-  const SMDS_FaceOfNodes* F1 = dynamic_cast<const SMDS_FaceOfNodes*>( tr1 );
-  //if (!F1) return false;
-  const SMDS_FaceOfNodes* F2 = dynamic_cast<const SMDS_FaceOfNodes*>( tr2 );
-  //if (!F2) return false;
-  if (F1 && F2) {
+  const SMDS_VtkFace* F1 = dynamic_cast<const SMDS_VtkFace*>( tr1 );
+  if (!F1) return false;
+  const SMDS_VtkFace* F2 = dynamic_cast<const SMDS_VtkFace*>( tr2 );
+  if (!F2) return false;
+  if ((tr1->GetEntityType() == SMDSEntity_Triangle) &&
+      (tr2->GetEntityType() == SMDSEntity_Triangle)) {
 
     //  1 +--+ A  tr1: ( 1 A B ) A->2 ( 1 2 B ) 1 +--+ A
     //    | /|    tr2: ( B A 2 ) B->1 ( 1 A 2 )   |\ |
@@ -682,23 +803,13 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshNode * theNode1,
     // tr2: B->1
     aNodes2[ iB2 ] = aNodes1[ i1 ];
 
-    //MESSAGE( tr1 << tr2 );
-
     GetMeshDS()->ChangeElementNodes( tr1, aNodes1, 3 );
     GetMeshDS()->ChangeElementNodes( tr2, aNodes2, 3 );
 
-    //MESSAGE( tr1 << tr2 );
-
     return true;
   }
 
   // check case of quadratic faces
-  const SMDS_QuadraticFaceOfNodes* QF1 =
-    dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (tr1);
-  if(!QF1) return false;
-  const SMDS_QuadraticFaceOfNodes* QF2 =
-    dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (tr2);
-  if(!QF2) return false;
   return InverseDiag(tr1,tr2);
 }
 
@@ -772,34 +883,39 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1,
   if ( !findTriangles( theNode1, theNode2, tr1, tr2 ))
     return false;
 
-  const SMDS_FaceOfNodes* F1 = dynamic_cast<const SMDS_FaceOfNodes*>( tr1 );
-  //if (!F1) return false;
-  const SMDS_FaceOfNodes* F2 = dynamic_cast<const SMDS_FaceOfNodes*>( tr2 );
-  //if (!F2) return false;
-  if (F1 && F2) {
+  const SMDS_VtkFace* F1 = dynamic_cast<const SMDS_VtkFace*>( tr1 );
+  if (!F1) return false;
+  const SMDS_VtkFace* F2 = dynamic_cast<const SMDS_VtkFace*>( tr2 );
+  if (!F2) return false;
+  SMESHDS_Mesh * aMesh = GetMeshDS();
+
+  if ((tr1->GetEntityType() == SMDSEntity_Triangle) &&
+      (tr2->GetEntityType() == SMDSEntity_Triangle)) {
 
     const SMDS_MeshNode* aNodes [ 4 ];
     if ( ! getQuadrangleNodes( aNodes, theNode1, theNode2, tr1, tr2 ))
       return false;
 
-    //MESSAGE( endl << tr1 << tr2 );
-
-    GetMeshDS()->ChangeElementNodes( tr1, aNodes, 4 );
-    myLastCreatedElems.Append(tr1);
-    GetMeshDS()->RemoveElement( tr2 );
-
-    //MESSAGE( endl << tr1 );
+    const SMDS_MeshElement* newElem = 0;
+    newElem = aMesh->AddFace( aNodes[0], aNodes[1], aNodes[2], aNodes[3] );
+    myLastCreatedElems.Append(newElem);
+    AddToSameGroups( newElem, tr1, aMesh );
+    int aShapeId = tr1->getshapeId();
+    if ( aShapeId )
+      {
+        aMesh->SetMeshElementOnShape( newElem, aShapeId );
+      }
+    aMesh->RemoveElement( tr1 );
+    aMesh->RemoveElement( tr2 );
 
     return true;
   }
 
   // check case of quadratic faces
-  const SMDS_QuadraticFaceOfNodes* QF1 =
-    dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (tr1);
-  if(!QF1) return false;
-  const SMDS_QuadraticFaceOfNodes* QF2 =
-    dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (tr2);
-  if(!QF2) return false;
+  if (tr1->GetEntityType() != SMDSEntity_Quad_Triangle)
+    return false;
+  if (tr2->GetEntityType() != SMDSEntity_Quad_Triangle)
+    return false;
 
   //       5
   //  1 +--+--+ 2  tr1: (1 2 4 5 9 7) or (2 4 1 9 7 5) or (4 1 2 7 5 9)
@@ -829,9 +945,18 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1,
   aNodes[6] = N2[3];
   aNodes[7] = N1[5];
 
-  GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 );
-  myLastCreatedElems.Append(tr1);
-  GetMeshDS()->RemoveElement( tr2 );
+  const SMDS_MeshElement* newElem = 0;
+  newElem = aMesh->AddFace( aNodes[0], aNodes[1], aNodes[2], aNodes[3],
+                            aNodes[4], aNodes[5], aNodes[6], aNodes[7]);
+  myLastCreatedElems.Append(newElem);
+  AddToSameGroups( newElem, tr1, aMesh );
+  int aShapeId = tr1->getshapeId();
+  if ( aShapeId )
+    {
+      aMesh->SetMeshElementOnShape( newElem, aShapeId );
+    }
+  aMesh->RemoveElement( tr1 );
+  aMesh->RemoveElement( tr2 );
 
   // remove middle node (9)
   GetMeshDS()->RemoveNode( N1[4] );
@@ -846,6 +971,7 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1,
 
 bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem)
 {
+  MESSAGE("Reorient");
   myLastCreatedElems.Clear();
   myLastCreatedNodes.Clear();
 
@@ -892,8 +1018,10 @@ bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem)
   }
   case SMDSAbs_Volume: {
     if (theElem->IsPoly()) {
-      const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
-        static_cast<const SMDS_PolyhedralVolumeOfNodes*>( theElem );
+      // TODO reorient vtk polyhedron
+      MESSAGE("reorient vtk polyhedron ?");
+      const SMDS_VtkVolume* aPolyedre =
+        dynamic_cast<const SMDS_VtkVolume*>( theElem );
       if (!aPolyedre) {
         MESSAGE("Warning: bad volumic element");
         return false;
@@ -922,6 +1050,7 @@ bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem)
       if ( !vTool.Set( theElem ))
         return false;
       vTool.Inverse();
+      MESSAGE("ChangeElementNodes reorient: check vTool.Inverse");
       return GetMeshDS()->ChangeElementNodes( theElem, vTool.GetNodes(), vTool.NbNodes() );
     }
   }
@@ -931,6 +1060,97 @@ bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem)
   return false;
 }
 
+//================================================================================
+/*!
+ * \brief Reorient faces.
+ * \param theFaces - the faces to reorient. If empty the whole mesh is meant
+ * \param theDirection - desired direction of normal of \a theFace
+ * \param theFace - one of \a theFaces that sould be orientated according to
+ *        \a theDirection and whose orientation defines orientation of other faces
+ * \return number of reoriented faces.
+ */
+//================================================================================
+
+int SMESH_MeshEditor::Reorient2D (TIDSortedElemSet &       theFaces,
+                                  const gp_Dir&            theDirection,
+                                  const SMDS_MeshElement * theFace)
+{
+  int nbReori = 0;
+  if ( !theFace || theFace->GetType() != SMDSAbs_Face ) return nbReori;
+
+  if ( theFaces.empty() )
+  {
+    SMDS_FaceIteratorPtr fIt = GetMeshDS()->facesIterator(/*idInceasingOrder=*/true);
+    while ( fIt->more() )
+      theFaces.insert( theFaces.end(), fIt->next() );
+  }
+
+  // orient theFace according to theDirection
+  gp_XYZ normal;
+  SMESH_Algo::FaceNormal( theFace, normal, /*normalized=*/false );
+  if ( normal * theDirection.XYZ() < 0 )
+    nbReori += Reorient( theFace );
+
+  // Orient other faces
+
+  set< const SMDS_MeshElement* > startFaces;
+  TIDSortedElemSet avoidSet;
+  set< SMESH_TLink > checkedLinks;
+  pair< set< SMESH_TLink >::iterator, bool > linkIt_isNew;
+
+  if ( theFaces.size() > 1 )// leave 1 face to prevent finding not selected faces
+    theFaces.erase( theFace );
+  startFaces.insert( theFace );
+
+  set< const SMDS_MeshElement* >::iterator startFace = startFaces.begin();
+  while ( startFace != startFaces.end() )
+  {
+    theFace = *startFace;
+    const int nbNodes = theFace->NbCornerNodes();
+
+    avoidSet.clear();
+    avoidSet.insert(theFace);
+
+    NLink link( theFace->GetNode( 0 ), 0 );
+    for ( int i = 0; i < nbNodes; ++i ) // loop on links of theFace
+    {
+      link.second = theFace->GetNode(( i+1 ) % nbNodes );
+      linkIt_isNew = checkedLinks.insert( link );
+      if ( !linkIt_isNew.second )
+      {
+        // link has already been checked and won't be encountered more
+        // if the group (theFaces) is manifold
+        checkedLinks.erase( linkIt_isNew.first );
+      }
+      else
+      {
+        int nodeInd1, nodeInd2;
+        const SMDS_MeshElement* otherFace = FindFaceInSet( link.first, link.second,
+                                                           theFaces, avoidSet,
+                                                           & nodeInd1, & nodeInd2);
+        if ( otherFace && otherFace != theFace)
+        {
+          // link must be reversed in otherFace if orientation ot otherFace
+          // is same as that of theFace
+          if ( abs(nodeInd2-nodeInd1) == 1 ? nodeInd2 > nodeInd1 : nodeInd1 > nodeInd2 )
+          {
+            // cout << "Reorient " << otherFace->GetID() << " near theFace=" <<theFace->GetID()
+            //      << " \tlink( " << link.first->GetID() << " " << link.second->GetID() << endl;
+            nbReori += Reorient( otherFace );
+          }
+          startFaces.insert( otherFace );
+          if ( theFaces.size() > 1 ) // leave 1 face to prevent finding not selected faces
+            theFaces.erase( otherFace );
+        }
+      }
+      std::swap( link.first, link.second );
+    }
+    startFaces.erase( startFace );
+    startFace = startFaces.begin();
+  }
+  return nbReori;
+}
+
 //=======================================================================
 //function : getBadRate
 //purpose  :
@@ -973,15 +1193,11 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet &                   theElems,
     const SMDS_MeshElement* elem = *itElem;
     if ( !elem || elem->GetType() != SMDSAbs_Face )
       continue;
-    if ( elem->NbNodes() != ( elem->IsQuadratic() ? 8 : 4 ))
+    if ( elem->NbCornerNodes() != 4 )
       continue;
 
     // retrieve element nodes
-    const SMDS_MeshNode* aNodes [8];
-    SMDS_ElemIteratorPtr itN = elem->nodesIterator();
-    int i = 0;
-    while ( itN->more() )
-      aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
+    vector< const SMDS_MeshNode* > aNodes( elem->begin_nodes(), elem->end_nodes() );
 
     // compare two sets of possible triangles
     double aBadRate1, aBadRate2; // to what extent a set is bad
@@ -994,7 +1210,8 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet &                   theElems,
     aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit );
 
     int aShapeId = FindShape( elem );
-    const SMDS_MeshElement* newElem = 0;
+    const SMDS_MeshElement* newElem1 = 0;
+    const SMDS_MeshElement* newElem2 = 0;
 
     if( !elem->IsQuadratic() ) {
 
@@ -1002,13 +1219,13 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet &                   theElems,
 
       if ( aBadRate1 <= aBadRate2 ) {
         // tr1 + tr2 is better
-        aMesh->ChangeElementNodes( elem, aNodes, 3 );
-        newElem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] );
+        newElem1 = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] );
+        newElem2 = aMesh->AddFace( aNodes[2], aNodes[0], aNodes[1] );
       }
       else {
         // tr3 + tr4 is better
-        aMesh->ChangeElementNodes( elem, &aNodes[1], 3 );
-        newElem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] );
+        newElem1 = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] );
+        newElem2 = aMesh->AddFace( aNodes[3], aNodes[1], aNodes[2] );
       }
     }
     else {
@@ -1028,72 +1245,70 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet &                   theElems,
             helper.SetSubShape( shape );
         }
       }
-      // get elem nodes
-      const SMDS_MeshNode* aNodes [8];
-      const SMDS_MeshNode* inFaceNode = 0;
-      SMDS_ElemIteratorPtr itN = elem->nodesIterator();
-      int i = 0;
-      while ( itN->more() ) {
-        aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
-        if ( !inFaceNode && helper.GetNodeUVneedInFaceNode() &&
-             aNodes[ i-1 ]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE )
-        {
-          inFaceNode = aNodes[ i-1 ];
-        }
-      }
       // find middle point for (0,1,2,3)
       // and create a node in this point;
-      gp_XYZ p( 0,0,0 );
-      if ( surface.IsNull() ) {
-        for(i=0; i<4; i++)
-          p += gp_XYZ(aNodes[i]->X(), aNodes[i]->Y(), aNodes[i]->Z() );
-        p /= 4;
+      const SMDS_MeshNode* newN = 0;
+      if ( aNodes.size() == 9 )
+      {
+        // SMDSEntity_BiQuad_Quadrangle
+        newN = aNodes.back();
       }
-      else {
-        TopoDS_Face face = TopoDS::Face( helper.GetSubShape() );
-        gp_XY uv( 0,0 );
-        for(i=0; i<4; i++)
-          uv += helper.GetNodeUV( face, aNodes[i], inFaceNode );
-        uv /= 4.;
-        p = surface->Value( uv.X(), uv.Y() ).XYZ();
+      else
+      {
+        gp_XYZ p( 0,0,0 );
+        if ( surface.IsNull() )
+        {
+          for ( int i = 0; i < 4; i++ )
+            p += gp_XYZ(aNodes[i]->X(), aNodes[i]->Y(), aNodes[i]->Z() );
+          p /= 4;
+        }
+        else
+        {
+          const SMDS_MeshNode* inFaceNode = 0;
+          if ( helper.GetNodeUVneedInFaceNode() )
+            for ( size_t i = 0; i < aNodes.size() && !inFaceNode; ++i )
+              if ( aNodes[ i ]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE )
+                inFaceNode = aNodes[ i ];
+
+          TopoDS_Face face = TopoDS::Face( helper.GetSubShape() );
+          gp_XY uv( 0,0 );
+          for ( int i = 0; i < 4; i++ )
+            uv += helper.GetNodeUV( face, aNodes[i], inFaceNode );
+          uv /= 4.;
+          p = surface->Value( uv.X(), uv.Y() ).XYZ();
+        }
+        newN = aMesh->AddNode( p.X(), p.Y(), p.Z() );
+        myLastCreatedNodes.Append(newN);
       }
-      const SMDS_MeshNode* newN = aMesh->AddNode( p.X(), p.Y(), p.Z() );
-      myLastCreatedNodes.Append(newN);
-
       // create a new element
-      const SMDS_MeshNode* N[6];
       if ( aBadRate1 <= aBadRate2 ) {
-        N[0] = aNodes[0];
-        N[1] = aNodes[1];
-        N[2] = aNodes[2];
-        N[3] = aNodes[4];
-        N[4] = aNodes[5];
-        N[5] = newN;
-        newElem = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0],
-                                 aNodes[6], aNodes[7], newN );
+        newElem1 = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0],
+                                  aNodes[6], aNodes[7], newN );
+        newElem2 = aMesh->AddFace(aNodes[2], aNodes[0], aNodes[1],
+                                  newN,      aNodes[4], aNodes[5] );
       }
       else {
-        N[0] = aNodes[1];
-        N[1] = aNodes[2];
-        N[2] = aNodes[3];
-        N[3] = aNodes[5];
-        N[4] = aNodes[6];
-        N[5] = newN;
-        newElem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1],
-                                 aNodes[7], aNodes[4], newN );
+        newElem1 = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1],
+                                  aNodes[7], aNodes[4], newN );
+        newElem2 = aMesh->AddFace(aNodes[3], aNodes[1], aNodes[2],
+                                  newN,      aNodes[5], aNodes[6] );
       }
-      aMesh->ChangeElementNodes( elem, N, 6 );
-
     } // quadratic case
 
     // care of a new element
 
-    myLastCreatedElems.Append(newElem);
-    AddToSameGroups( newElem, elem, aMesh );
+    myLastCreatedElems.Append(newElem1);
+    myLastCreatedElems.Append(newElem2);
+    AddToSameGroups( newElem1, elem, aMesh );
+    AddToSameGroups( newElem2, elem, aMesh );
 
     // put a new triangle on the same shape
     if ( aShapeId )
-      aMesh->SetMeshElementOnShape( newElem, aShapeId );
+      {
+        aMesh->SetMeshElementOnShape( newElem1, aShapeId );
+        aMesh->SetMeshElementOnShape( newElem2, aShapeId );
+      }
+    aMesh->RemoveElement( elem );
   }
   return true;
 }
@@ -1102,6 +1317,7 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet &                   theElems,
 //function : BestSplit
 //purpose  : Find better diagonal for cutting.
 //=======================================================================
+
 int SMESH_MeshEditor::BestSplit (const SMDS_MeshElement*              theQuad,
                                  SMESH::Controls::NumericalFunctorPtr theCrit)
 {
@@ -1143,85 +1359,681 @@ int SMESH_MeshEditor::BestSplit (const SMDS_MeshElement*              theQuad,
   return -1;
 }
 
-//=======================================================================
-//function : AddToSameGroups
-//purpose  : add elemToAdd to the groups the elemInGroups belongs to
-//=======================================================================
-
-void SMESH_MeshEditor::AddToSameGroups (const SMDS_MeshElement* elemToAdd,
-                                        const SMDS_MeshElement* elemInGroups,
-                                        SMESHDS_Mesh *          aMesh)
+namespace
 {
-  const set<SMESHDS_GroupBase*>& groups = aMesh->GetGroups();
-  if (!groups.empty()) {
-    set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
-    for ( ; grIt != groups.end(); grIt++ ) {
-      SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>( *grIt );
-      if ( group && group->Contains( elemInGroups ))
-        group->SMDSGroup().Add( elemToAdd );
-    }
-  }
-}
+  // Methods of splitting volumes into tetra
 
+  const int theHexTo5_1[5*4+1] =
+    {
+      0, 1, 2, 5,    0, 4, 5, 7,     0, 2, 3, 7,    2, 5, 6, 7,     0, 5, 2, 7,   -1
+    };
+  const int theHexTo5_2[5*4+1] =
+    {
+      1, 2, 3, 6,    1, 4, 5, 6,     0, 1, 3, 4,    3, 4, 6, 7,     1, 3, 4, 6,   -1
+    };
+  const int* theHexTo5[2] = { theHexTo5_1, theHexTo5_2 };
 
-//=======================================================================
-//function : RemoveElemFromGroups
-//purpose  : Remove removeelem to the groups the elemInGroups belongs to
-//=======================================================================
-void SMESH_MeshEditor::RemoveElemFromGroups (const SMDS_MeshElement* removeelem,
-                                             SMESHDS_Mesh *          aMesh)
-{
-  const set<SMESHDS_GroupBase*>& groups = aMesh->GetGroups();
-  if (!groups.empty())
-  {
-    set<SMESHDS_GroupBase*>::const_iterator GrIt = groups.begin();
-    for (; GrIt != groups.end(); GrIt++)
+  const int theHexTo6_1[6*4+1] =
     {
-      SMESHDS_Group* grp = dynamic_cast<SMESHDS_Group*>(*GrIt);
-      if (!grp || grp->IsEmpty()) continue;
-      grp->SMDSGroup().Remove(removeelem);
-    }
-  }
-}
+      1, 5, 6, 0,    0, 1, 2, 6,     0, 4, 5, 6,    0, 4, 6, 7,     0, 2, 3, 6,   0, 3, 7, 6,  -1
+    };
+  const int theHexTo6_2[6*4+1] =
+    {
+      2, 6, 7, 1,    1, 2, 3, 7,     1, 5, 6, 7,    1, 5, 7, 4,     1, 3, 0, 7,   1, 0, 4, 7,  -1
+    };
+  const int theHexTo6_3[6*4+1] =
+    {
+      3, 7, 4, 2,    2, 3, 0, 4,     2, 6, 7, 4,    2, 6, 4, 5,     2, 0, 1, 4,   2, 1, 5, 4,  -1
+    };
+  const int theHexTo6_4[6*4+1] =
+    {
+      0, 4, 5, 3,    3, 0, 1, 5,     3, 7, 4, 5,    3, 7, 5, 6,     3, 1, 2, 5,   3, 2, 6, 5,  -1
+    };
+  const int* theHexTo6[4] = { theHexTo6_1, theHexTo6_2, theHexTo6_3, theHexTo6_4 };
 
-//=======================================================================
-//function : ReplaceElemInGroups
-//purpose  : replace elemToRm by elemToAdd in the all groups
-//=======================================================================
+  const int thePyraTo2_1[2*4+1] =
+    {
+      0, 1, 2, 4,    0, 2, 3, 4,   -1
+    };
+  const int thePyraTo2_2[2*4+1] =
+    {
+      1, 2, 3, 4,    1, 3, 0, 4,   -1
+    };
+  const int* thePyraTo2[2] = { thePyraTo2_1, thePyraTo2_2 };
 
-void SMESH_MeshEditor::ReplaceElemInGroups (const SMDS_MeshElement* elemToRm,
-                                            const SMDS_MeshElement* elemToAdd,
-                                            SMESHDS_Mesh *          aMesh)
-{
-  const set<SMESHDS_GroupBase*>& groups = aMesh->GetGroups();
-  if (!groups.empty()) {
-    set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
-    for ( ; grIt != groups.end(); grIt++ ) {
-      SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>( *grIt );
-      if ( group && group->SMDSGroup().Remove( elemToRm ) && elemToAdd )
-        group->SMDSGroup().Add( elemToAdd );
+  const int thePentaTo3_1[3*4+1] =
+    {
+      0, 1, 2, 3,    1, 3, 4, 2,     2, 3, 4, 5,    -1
+    };
+  const int thePentaTo3_2[3*4+1] =
+    {
+      1, 2, 0, 4,    2, 4, 5, 0,     0, 4, 5, 3,    -1
+    };
+  const int thePentaTo3_3[3*4+1] =
+    {
+      2, 0, 1, 5,    0, 5, 3, 1,     1, 5, 3, 4,    -1
+    };
+  const int thePentaTo3_4[3*4+1] =
+    {
+      0, 1, 2, 3,    1, 3, 4, 5,     2, 3, 1, 5,    -1
+    };
+  const int thePentaTo3_5[3*4+1] =
+    {
+      1, 2, 0, 4,    2, 4, 5, 3,     0, 4, 2, 3,    -1
+    };
+  const int thePentaTo3_6[3*4+1] =
+    {
+      2, 0, 1, 5,    0, 5, 3, 4,     1, 5, 0, 4,    -1
+    };
+  const int* thePentaTo3[6] = { thePentaTo3_1, thePentaTo3_2, thePentaTo3_3,
+                                thePentaTo3_4, thePentaTo3_5, thePentaTo3_6 };
+
+  struct TTriangleFacet //!< stores indices of three nodes of tetra facet
+  {
+    int _n1, _n2, _n3;
+    TTriangleFacet(int n1, int n2, int n3): _n1(n1), _n2(n2), _n3(n3) {}
+    bool contains(int n) const { return ( n == _n1 || n == _n2 || n == _n3 ); }
+    bool hasAdjacentTetra( const SMDS_MeshElement* elem ) const;
+  };
+  struct TSplitMethod
+  {
+    int        _nbTetra;
+    const int* _connectivity; //!< foursomes of tetra connectivy finished by -1
+    bool       _baryNode;     //!< additional node is to be created at cell barycenter
+    bool       _ownConn;      //!< to delete _connectivity in destructor
+    map<int, const SMDS_MeshNode*> _faceBaryNode; //!< map face index to node at BC of face
+
+    TSplitMethod( int nbTet=0, const int* conn=0, bool addNode=false)
+      : _nbTetra(nbTet), _connectivity(conn), _baryNode(addNode), _ownConn(false) {}
+    ~TSplitMethod() { if ( _ownConn ) delete [] _connectivity; _connectivity = 0; }
+    bool hasFacet( const TTriangleFacet& facet ) const
+    {
+      const int* tetConn = _connectivity;
+      for ( ; tetConn[0] >= 0; tetConn += 4 )
+        if (( facet.contains( tetConn[0] ) +
+              facet.contains( tetConn[1] ) +
+              facet.contains( tetConn[2] ) +
+              facet.contains( tetConn[3] )) == 3 )
+          return true;
+      return false;
     }
-  }
-}
+  };
 
-//=======================================================================
-//function : QuadToTri
-//purpose  : Cut quadrangles into triangles.
-//           theCrit is used to select a diagonal to cut
-//=======================================================================
+  //=======================================================================
+  /*!
+   * \brief return TSplitMethod for the given element
+   */
+  //=======================================================================
 
-bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems,
-                                  const bool         the13Diag)
-{
-  myLastCreatedElems.Clear();
-  myLastCreatedNodes.Clear();
+  TSplitMethod getSplitMethod( SMDS_VolumeTool& vol, const int theMethodFlags)
+  {
+    const int iQ = vol.Element()->IsQuadratic() ? 2 : 1;
 
-  MESSAGE( "::QuadToTri()" );
+    // at HEXA_TO_24 method, each face of volume is split into triangles each based on
+    // an edge and a face barycenter; tertaherdons are based on triangles and
+    // a volume barycenter
+    const bool is24TetMode = ( theMethodFlags == SMESH_MeshEditor::HEXA_TO_24 );
 
-  SMESHDS_Mesh * aMesh = GetMeshDS();
+    // Find out how adjacent volumes are split
 
-  Handle(Geom_Surface) surface;
-  SMESH_MesherHelper   helper( *GetMesh() );
+    vector < list< TTriangleFacet > > triaSplitsByFace( vol.NbFaces() ); // splits of each side
+    int hasAdjacentSplits = 0, maxTetConnSize = 0;
+    for ( int iF = 0; iF < vol.NbFaces(); ++iF )
+    {
+      int nbNodes = vol.NbFaceNodes( iF ) / iQ;
+      maxTetConnSize += 4 * ( nbNodes - (is24TetMode ? 0 : 2));
+      if ( nbNodes < 4 ) continue;
+
+      list< TTriangleFacet >& triaSplits = triaSplitsByFace[ iF ];
+      const int* nInd = vol.GetFaceNodesIndices( iF );
+      if ( nbNodes == 4 )
+      {
+        TTriangleFacet t012( nInd[0*iQ], nInd[1*iQ], nInd[2*iQ] );
+        TTriangleFacet t123( nInd[1*iQ], nInd[2*iQ], nInd[3*iQ] );
+        if      ( t012.hasAdjacentTetra( vol.Element() )) triaSplits.push_back( t012 );
+        else if ( t123.hasAdjacentTetra( vol.Element() )) triaSplits.push_back( t123 );
+      }
+      else
+      {
+        int iCom = 0; // common node of triangle faces to split into
+        for ( int iVar = 0; iVar < nbNodes; ++iVar, ++iCom )
+        {
+          TTriangleFacet t012( nInd[ iQ * ( iCom             )],
+                               nInd[ iQ * ( (iCom+1)%nbNodes )],
+                               nInd[ iQ * ( (iCom+2)%nbNodes )]);
+          TTriangleFacet t023( nInd[ iQ * ( iCom             )],
+                               nInd[ iQ * ( (iCom+2)%nbNodes )],
+                               nInd[ iQ * ( (iCom+3)%nbNodes )]);
+          if ( t012.hasAdjacentTetra( vol.Element() ) && t023.hasAdjacentTetra( vol.Element() ))
+          {
+            triaSplits.push_back( t012 );
+            triaSplits.push_back( t023 );
+            break;
+          }
+        }
+      }
+      if ( !triaSplits.empty() )
+        hasAdjacentSplits = true;
+    }
+
+    // Among variants of split method select one compliant with adjacent volumes
+
+    TSplitMethod method;
+    if ( !vol.Element()->IsPoly() && !is24TetMode )
+    {
+      int nbVariants = 2, nbTet = 0;
+      const int** connVariants = 0;
+      switch ( vol.Element()->GetEntityType() )
+      {
+      case SMDSEntity_Hexa:
+      case SMDSEntity_Quad_Hexa:
+      case SMDSEntity_TriQuad_Hexa:
+        if ( theMethodFlags == SMESH_MeshEditor::HEXA_TO_5 )
+          connVariants = theHexTo5, nbTet = 5;
+        else
+          connVariants = theHexTo6, nbTet = 6, nbVariants = 4;
+        break;
+      case SMDSEntity_Pyramid:
+      case SMDSEntity_Quad_Pyramid:
+        connVariants = thePyraTo2;  nbTet = 2;
+        break;
+      case SMDSEntity_Penta:
+      case SMDSEntity_Quad_Penta:
+        connVariants = thePentaTo3; nbTet = 3; nbVariants = 6;
+        break;
+      default:
+        nbVariants = 0;
+      }
+      for ( int variant = 0; variant < nbVariants && method._nbTetra == 0; ++variant )
+      {
+        // check method compliancy with adjacent tetras,
+        // all found splits must be among facets of tetras described by this method
+        method = TSplitMethod( nbTet, connVariants[variant] );
+        if ( hasAdjacentSplits && method._nbTetra > 0 )
+        {
+          bool facetCreated = true;
+          for ( int iF = 0; facetCreated && iF < triaSplitsByFace.size(); ++iF )
+          {
+            list< TTriangleFacet >::const_iterator facet = triaSplitsByFace[iF].begin();
+            for ( ; facetCreated && facet != triaSplitsByFace[iF].end(); ++facet )
+              facetCreated = method.hasFacet( *facet );
+          }
+          if ( !facetCreated )
+            method = TSplitMethod(0); // incompatible method
+        }
+      }
+    }
+    if ( method._nbTetra < 1 )
+    {
+      // No standard method is applicable, use a generic solution:
+      // each facet of a volume is split into triangles and
+      // each of triangles and a volume barycenter form a tetrahedron.
+
+      const bool isHex27 = ( vol.Element()->GetEntityType() == SMDSEntity_TriQuad_Hexa );
+
+      int* connectivity = new int[ maxTetConnSize + 1 ];
+      method._connectivity = connectivity;
+      method._ownConn = true;
+      method._baryNode = !isHex27; // to create central node or not
+
+      int connSize = 0;
+      int baryCenInd = vol.NbNodes() - int( isHex27 );
+      for ( int iF = 0; iF < vol.NbFaces(); ++iF )
+      {
+        const int nbNodes = vol.NbFaceNodes( iF ) / iQ;
+        const int*   nInd = vol.GetFaceNodesIndices( iF );
+        // find common node of triangle facets of tetra to create
+        int iCommon = 0; // index in linear numeration
+        const list< TTriangleFacet >& triaSplits = triaSplitsByFace[ iF ];
+        if ( !triaSplits.empty() )
+        {
+          // by found facets
+          const TTriangleFacet* facet = &triaSplits.front();
+          for ( ; iCommon < nbNodes-1 ; ++iCommon )
+            if ( facet->contains( nInd[ iQ * iCommon ]) &&
+                 facet->contains( nInd[ iQ * ((iCommon+2)%nbNodes) ]))
+              break;
+        }
+        else if ( nbNodes > 3 && !is24TetMode )
+        {
+          // find the best method of splitting into triangles by aspect ratio
+          SMESH::Controls::NumericalFunctorPtr aspectRatio( new SMESH::Controls::AspectRatio);
+          map< double, int > badness2iCommon;
+          const SMDS_MeshNode** nodes = vol.GetFaceNodes( iF );
+          int nbVariants = ( nbNodes == 4 ? 2 : nbNodes );
+          for ( int iVar = 0; iVar < nbVariants; ++iVar, ++iCommon )
+          {
+            double badness = 0;
+            for ( int iLast = iCommon+2; iLast < iCommon+nbNodes; ++iLast )
+            {
+              SMDS_FaceOfNodes tria ( nodes[ iQ*( iCommon         )],
+                                      nodes[ iQ*((iLast-1)%nbNodes)],
+                                      nodes[ iQ*((iLast  )%nbNodes)]);
+              badness += getBadRate( &tria, aspectRatio );
+            }
+            badness2iCommon.insert( make_pair( badness, iCommon ));
+          }
+          // use iCommon with lowest badness
+          iCommon = badness2iCommon.begin()->second;
+        }
+        if ( iCommon >= nbNodes )
+          iCommon = 0; // something wrong
+
+        // fill connectivity of tetrahedra based on a current face
+        int nbTet = nbNodes - 2;
+        if ( is24TetMode && nbNodes > 3 && triaSplits.empty())
+        {
+          int faceBaryCenInd;
+          if ( isHex27 )
+          {
+            faceBaryCenInd = vol.GetCenterNodeIndex( iF );
+            method._faceBaryNode[ iF ] = vol.GetNodes()[ faceBaryCenInd ];
+          }
+          else
+          {
+            method._faceBaryNode[ iF ] = 0;
+            faceBaryCenInd = baryCenInd + method._faceBaryNode.size();
+          }
+          nbTet = nbNodes;
+          for ( int i = 0; i < nbTet; ++i )
+          {
+            int i1 = i, i2 = (i+1) % nbNodes;
+            if ( !vol.IsFaceExternal( iF )) swap( i1, i2 );
+            connectivity[ connSize++ ] = nInd[ iQ * i1 ];
+            connectivity[ connSize++ ] = nInd[ iQ * i2 ];
+            connectivity[ connSize++ ] = faceBaryCenInd;
+            connectivity[ connSize++ ] = baryCenInd;
+          }
+        }
+        else
+        {
+          for ( int i = 0; i < nbTet; ++i )
+          {
+            int i1 = (iCommon+1+i) % nbNodes, i2 = (iCommon+2+i) % nbNodes;
+            if ( !vol.IsFaceExternal( iF )) swap( i1, i2 );
+            connectivity[ connSize++ ] = nInd[ iQ * iCommon ];
+            connectivity[ connSize++ ] = nInd[ iQ * i1 ];
+            connectivity[ connSize++ ] = nInd[ iQ * i2 ];
+            connectivity[ connSize++ ] = baryCenInd;
+          }
+        }
+        method._nbTetra += nbTet;
+
+      } // loop on volume faces
+
+      connectivity[ connSize++ ] = -1;
+
+    } // end of generic solution
+
+    return method;
+  }
+  //================================================================================
+  /*!
+   * \brief Check if there is a tetraherdon adjacent to the given element via this facet
+   */
+  //================================================================================
+
+  bool TTriangleFacet::hasAdjacentTetra( const SMDS_MeshElement* elem ) const
+  {
+    // find the tetrahedron including the three nodes of facet
+    const SMDS_MeshNode* n1 = elem->GetNode(_n1);
+    const SMDS_MeshNode* n2 = elem->GetNode(_n2);
+    const SMDS_MeshNode* n3 = elem->GetNode(_n3);
+    SMDS_ElemIteratorPtr volIt1 = n1->GetInverseElementIterator(SMDSAbs_Volume);
+    while ( volIt1->more() )
+    {
+      const SMDS_MeshElement* v = volIt1->next();
+      SMDSAbs_EntityType type = v->GetEntityType();
+      if ( type != SMDSEntity_Tetra && type != SMDSEntity_Quad_Tetra )
+        continue;
+      if ( type == SMDSEntity_Quad_Tetra && v->GetNodeIndex( n1 ) > 3 )
+        continue; // medium node not allowed
+      const int ind2 = v->GetNodeIndex( n2 );
+      if ( ind2 < 0 || 3 < ind2 )
+        continue;
+      const int ind3 = v->GetNodeIndex( n3 );
+      if ( ind3 < 0 || 3 < ind3 )
+        continue;
+      return true;
+    }
+    return false;
+  }
+
+  //=======================================================================
+  /*!
+   * \brief A key of a face of volume
+   */
+  //=======================================================================
+
+  struct TVolumeFaceKey: pair< pair< int, int>, pair< int, int> >
+  {
+    TVolumeFaceKey( SMDS_VolumeTool& vol, int iF )
+    {
+      TIDSortedNodeSet sortedNodes;
+      const int iQ = vol.Element()->IsQuadratic() ? 2 : 1;
+      int nbNodes = vol.NbFaceNodes( iF );
+      const SMDS_MeshNode** fNodes = vol.GetFaceNodes( iF );
+      for ( int i = 0; i < nbNodes; i += iQ )
+        sortedNodes.insert( fNodes[i] );
+      TIDSortedNodeSet::iterator n = sortedNodes.begin();
+      first.first   = (*(n++))->GetID();
+      first.second  = (*(n++))->GetID();
+      second.first  = (*(n++))->GetID();
+      second.second = ( sortedNodes.size() > 3 ) ? (*(n++))->GetID() : 0;
+    }
+  };
+} // namespace
+
+//=======================================================================
+//function : SplitVolumesIntoTetra
+//purpose  : Split volume elements into tetrahedra.
+//=======================================================================
+
+void SMESH_MeshEditor::SplitVolumesIntoTetra (const TIDSortedElemSet & theElems,
+                                              const int                theMethodFlags)
+{
+  // std-like iterator on coordinates of nodes of mesh element
+  typedef SMDS_StdIterator< SMESH_TNodeXYZ, SMDS_ElemIteratorPtr > NXyzIterator;
+  NXyzIterator xyzEnd;
+
+  SMDS_VolumeTool    volTool;
+  SMESH_MesherHelper helper( *GetMesh());
+
+  SMESHDS_SubMesh* subMesh = 0;//GetMeshDS()->MeshElements(1);
+  SMESHDS_SubMesh* fSubMesh = 0;//subMesh;
+  
+  SMESH_SequenceOfElemPtr newNodes, newElems;
+
+  // map face of volume to it's baricenrtic node
+  map< TVolumeFaceKey, const SMDS_MeshNode* > volFace2BaryNode;
+  double bc[3];
+
+  TIDSortedElemSet::const_iterator elem = theElems.begin();
+  for ( ; elem != theElems.end(); ++elem )
+  {
+    if ( (*elem)->GetType() != SMDSAbs_Volume )
+      continue;
+    SMDSAbs_EntityType geomType = (*elem)->GetEntityType();
+    if ( geomType == SMDSEntity_Tetra || geomType == SMDSEntity_Quad_Tetra )
+      continue;
+
+    if ( !volTool.Set( *elem, /*ignoreCentralNodes=*/false )) continue; // strange...
+
+    TSplitMethod splitMethod = getSplitMethod( volTool, theMethodFlags );
+    if ( splitMethod._nbTetra < 1 ) continue;
+
+    // find submesh to add new tetras to
+    if ( !subMesh || !subMesh->Contains( *elem ))
+    {
+      int shapeID = FindShape( *elem );
+      helper.SetSubShape( shapeID ); // helper will add tetras to the found submesh
+      subMesh = GetMeshDS()->MeshElements( shapeID );
+    }
+    int iQ;
+    if ( (*elem)->IsQuadratic() )
+    {
+      iQ = 2;
+      // add quadratic links to the helper
+      for ( int iF = 0; iF < volTool.NbFaces(); ++iF )
+      {
+        const SMDS_MeshNode** fNodes = volTool.GetFaceNodes( iF );
+        int nbN = volTool.NbFaceNodes( iF ) - bool( volTool.GetCenterNodeIndex(iF) > 0 );
+        for ( int iN = 0; iN < nbN; iN += iQ )
+          helper.AddTLinkNode( fNodes[iN], fNodes[iN+2], fNodes[iN+1] );
+      }
+      helper.SetIsQuadratic( true );
+    }
+    else
+    {
+      iQ = 1;
+      helper.SetIsQuadratic( false );
+    }
+    vector<const SMDS_MeshNode*> nodes( (*elem)->begin_nodes(), (*elem)->end_nodes() );
+    helper.SetElementsOnShape( true );
+    if ( splitMethod._baryNode )
+    {
+      // make a node at barycenter
+      volTool.GetBaryCenter( bc[0], bc[1], bc[2] );
+      SMDS_MeshNode* gcNode = helper.AddNode( bc[0], bc[1], bc[2] );
+      nodes.push_back( gcNode );
+      newNodes.Append( gcNode );
+    }
+    if ( !splitMethod._faceBaryNode.empty() )
+    {
+      // make or find baricentric nodes of faces
+      map<int, const SMDS_MeshNode*>::iterator iF_n = splitMethod._faceBaryNode.begin();
+      for ( ; iF_n != splitMethod._faceBaryNode.end(); ++iF_n )
+      {
+        map< TVolumeFaceKey, const SMDS_MeshNode* >::iterator f_n =
+          volFace2BaryNode.insert
+          ( make_pair( TVolumeFaceKey( volTool,iF_n->first ), iF_n->second )).first;
+        if ( !f_n->second )
+        {
+          volTool.GetFaceBaryCenter( iF_n->first, bc[0], bc[1], bc[2] );
+          newNodes.Append( f_n->second = helper.AddNode( bc[0], bc[1], bc[2] ));
+        }
+        nodes.push_back( iF_n->second = f_n->second );
+      }
+    }
+
+    // make tetras
+    vector<const SMDS_MeshElement* > tetras( splitMethod._nbTetra ); // splits of a volume
+    const int* tetConn = splitMethod._connectivity;
+    for ( int i = 0; i < splitMethod._nbTetra; ++i, tetConn += 4 )
+      newElems.Append( tetras[ i ] = helper.AddVolume( nodes[ tetConn[0] ],
+                                                       nodes[ tetConn[1] ],
+                                                       nodes[ tetConn[2] ],
+                                                       nodes[ tetConn[3] ]));
+
+    ReplaceElemInGroups( *elem, tetras, GetMeshDS() );
+
+    // Split faces on sides of the split volume
+
+    const SMDS_MeshNode** volNodes = volTool.GetNodes();
+    for ( int iF = 0; iF < volTool.NbFaces(); ++iF )
+    {
+      const int nbNodes = volTool.NbFaceNodes( iF ) / iQ;
+      if ( nbNodes < 4 ) continue;
+
+      // find an existing face
+      vector<const SMDS_MeshNode*> fNodes( volTool.GetFaceNodes( iF ),
+                                           volTool.GetFaceNodes( iF ) + volTool.NbFaceNodes( iF ));
+      while ( const SMDS_MeshElement* face = GetMeshDS()->FindElement( fNodes, SMDSAbs_Face,
+                                                                       /*noMedium=*/false))
+      {
+        // make triangles
+        helper.SetElementsOnShape( false );
+        vector< const SMDS_MeshElement* > triangles;
+
+        // find submesh to add new triangles in
+        if ( !fSubMesh || !fSubMesh->Contains( face ))
+        {
+          int shapeID = FindShape( face );
+          fSubMesh = GetMeshDS()->MeshElements( shapeID );
+        }
+        map<int, const SMDS_MeshNode*>::iterator iF_n = splitMethod._faceBaryNode.find(iF);
+        if ( iF_n != splitMethod._faceBaryNode.end() )
+        {
+          for ( int iN = 0; iN < nbNodes*iQ; iN += iQ )
+          {
+            const SMDS_MeshNode* n1 = fNodes[iN];
+            const SMDS_MeshNode *n2 = fNodes[(iN+iQ)%(nbNodes*iQ)];
+            const SMDS_MeshNode *n3 = iF_n->second;
+            if ( !volTool.IsFaceExternal( iF ))
+              swap( n2, n3 );
+            triangles.push_back( helper.AddFace( n1,n2,n3 ));
+
+            if ( fSubMesh && n3->getshapeId() < 1 )
+              fSubMesh->AddNode( n3 );
+          }
+        }
+        else
+        {
+          // among possible triangles create ones discribed by split method
+          const int* nInd = volTool.GetFaceNodesIndices( iF );
+          int nbVariants = ( nbNodes == 4 ? 2 : nbNodes );
+          int iCom = 0; // common node of triangle faces to split into
+          list< TTriangleFacet > facets;
+          for ( int iVar = 0; iVar < nbVariants; ++iVar, ++iCom )
+          {
+            TTriangleFacet t012( nInd[ iQ * ( iCom                )],
+                                 nInd[ iQ * ( (iCom+1)%nbNodes )],
+                                 nInd[ iQ * ( (iCom+2)%nbNodes )]);
+            TTriangleFacet t023( nInd[ iQ * ( iCom                )],
+                                 nInd[ iQ * ( (iCom+2)%nbNodes )],
+                                 nInd[ iQ * ( (iCom+3)%nbNodes )]);
+            if ( splitMethod.hasFacet( t012 ) && splitMethod.hasFacet( t023 ))
+            {
+              facets.push_back( t012 );
+              facets.push_back( t023 );
+              for ( int iLast = iCom+4; iLast < iCom+nbNodes; ++iLast )
+                facets.push_back( TTriangleFacet( nInd[ iQ * ( iCom             )],
+                                                  nInd[ iQ * ((iLast-1)%nbNodes )],
+                                                  nInd[ iQ * ((iLast  )%nbNodes )]));
+              break;
+            }
+          }
+          list< TTriangleFacet >::iterator facet = facets.begin();
+          for ( ; facet != facets.end(); ++facet )
+          {
+            if ( !volTool.IsFaceExternal( iF ))
+              swap( facet->_n2, facet->_n3 );
+            triangles.push_back( helper.AddFace( volNodes[ facet->_n1 ],
+                                                 volNodes[ facet->_n2 ],
+                                                 volNodes[ facet->_n3 ]));
+          }
+        }
+        for ( int i = 0; i < triangles.size(); ++i )
+        {
+          if ( !triangles[i] ) continue;
+          if ( fSubMesh )
+            fSubMesh->AddElement( triangles[i]);
+          newElems.Append( triangles[i] );
+        }
+        ReplaceElemInGroups( face, triangles, GetMeshDS() );
+        GetMeshDS()->RemoveFreeElement( face, fSubMesh, /*fromGroups=*/false );
+      }
+
+    } // loop on volume faces to split them into triangles
+
+    GetMeshDS()->RemoveFreeElement( *elem, subMesh, /*fromGroups=*/false );
+
+    if ( geomType == SMDSEntity_TriQuad_Hexa )
+    {
+      // remove medium nodes that could become free
+      for ( int i = 20; i < volTool.NbNodes(); ++i )
+        if ( volNodes[i]->NbInverseElements() == 0 )
+          GetMeshDS()->RemoveNode( volNodes[i] );
+    }
+  } // loop on volumes to split
+
+  myLastCreatedNodes = newNodes;
+  myLastCreatedElems = newElems;
+}
+
+//=======================================================================
+//function : AddToSameGroups
+//purpose  : add elemToAdd to the groups the elemInGroups belongs to
+//=======================================================================
+
+void SMESH_MeshEditor::AddToSameGroups (const SMDS_MeshElement* elemToAdd,
+                                        const SMDS_MeshElement* elemInGroups,
+                                        SMESHDS_Mesh *          aMesh)
+{
+  const set<SMESHDS_GroupBase*>& groups = aMesh->GetGroups();
+  if (!groups.empty()) {
+    set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
+    for ( ; grIt != groups.end(); grIt++ ) {
+      SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>( *grIt );
+      if ( group && group->Contains( elemInGroups ))
+        group->SMDSGroup().Add( elemToAdd );
+    }
+  }
+}
+
+
+//=======================================================================
+//function : RemoveElemFromGroups
+//purpose  : Remove removeelem to the groups the elemInGroups belongs to
+//=======================================================================
+void SMESH_MeshEditor::RemoveElemFromGroups (const SMDS_MeshElement* removeelem,
+                                             SMESHDS_Mesh *          aMesh)
+{
+  const set<SMESHDS_GroupBase*>& groups = aMesh->GetGroups();
+  if (!groups.empty())
+  {
+    set<SMESHDS_GroupBase*>::const_iterator GrIt = groups.begin();
+    for (; GrIt != groups.end(); GrIt++)
+    {
+      SMESHDS_Group* grp = dynamic_cast<SMESHDS_Group*>(*GrIt);
+      if (!grp || grp->IsEmpty()) continue;
+      grp->SMDSGroup().Remove(removeelem);
+    }
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Replace elemToRm by elemToAdd in the all groups
+ */
+//================================================================================
+
+void SMESH_MeshEditor::ReplaceElemInGroups (const SMDS_MeshElement* elemToRm,
+                                            const SMDS_MeshElement* elemToAdd,
+                                            SMESHDS_Mesh *          aMesh)
+{
+  const set<SMESHDS_GroupBase*>& groups = aMesh->GetGroups();
+  if (!groups.empty()) {
+    set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
+    for ( ; grIt != groups.end(); grIt++ ) {
+      SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>( *grIt );
+      if ( group && group->SMDSGroup().Remove( elemToRm ) && elemToAdd )
+        group->SMDSGroup().Add( elemToAdd );
+    }
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Replace elemToRm by elemToAdd in the all groups
+ */
+//================================================================================
+
+void SMESH_MeshEditor::ReplaceElemInGroups (const SMDS_MeshElement*                elemToRm,
+                                            const vector<const SMDS_MeshElement*>& elemToAdd,
+                                            SMESHDS_Mesh *                         aMesh)
+{
+  const set<SMESHDS_GroupBase*>& groups = aMesh->GetGroups();
+  if (!groups.empty())
+  {
+    set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
+    for ( ; grIt != groups.end(); grIt++ ) {
+      SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>( *grIt );
+      if ( group && group->SMDSGroup().Remove( elemToRm ) )
+        for ( int i = 0; i < elemToAdd.size(); ++i )
+          group->SMDSGroup().Add( elemToAdd[ i ] );
+    }
+  }
+}
+
+//=======================================================================
+//function : QuadToTri
+//purpose  : Cut quadrangles into triangles.
+//           theCrit is used to select a diagonal to cut
+//=======================================================================
+
+bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems,
+                                  const bool         the13Diag)
+{
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
+
+  MESSAGE( "::QuadToTri()" );
+
+  SMESHDS_Mesh * aMesh = GetMeshDS();
+
+  Handle(Geom_Surface) surface;
+  SMESH_MesherHelper   helper( *GetMesh() );
 
   TIDSortedElemSet::iterator itElem;
   for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
@@ -1240,20 +2052,28 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems,
         aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
 
       int aShapeId = FindShape( elem );
-      const SMDS_MeshElement* newElem = 0;
+      const SMDS_MeshElement* newElem1 = 0;
+      const SMDS_MeshElement* newElem2 = 0;
       if ( the13Diag ) {
-        aMesh->ChangeElementNodes( elem, aNodes, 3 );
-        newElem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] );
+        newElem1 = aMesh->AddFace( aNodes[2], aNodes[0], aNodes[1] );
+        newElem2 = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] );
       }
       else {
-        aMesh->ChangeElementNodes( elem, &aNodes[1], 3 );
-        newElem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] );
+        newElem1 = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] );
+        newElem2 = aMesh->AddFace( aNodes[3], aNodes[1], aNodes[2] );
       }
-      myLastCreatedElems.Append(newElem);
+      myLastCreatedElems.Append(newElem1);
+      myLastCreatedElems.Append(newElem2);
       // put a new triangle on the same shape and add to the same groups
       if ( aShapeId )
-        aMesh->SetMeshElementOnShape( newElem, aShapeId );
-      AddToSameGroups( newElem, elem, aMesh );
+        {
+          aMesh->SetMeshElementOnShape( newElem1, aShapeId );
+          aMesh->SetMeshElementOnShape( newElem2, aShapeId );
+        }
+      AddToSameGroups( newElem1, elem, aMesh );
+      AddToSameGroups( newElem2, elem, aMesh );
+      //aMesh->RemoveFreeElement(elem, aMesh->MeshElements(aShapeId), true);
+      aMesh->RemoveElement( elem );
     }
 
     // Quadratic quadrangle
@@ -1308,34 +2128,31 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems,
       myLastCreatedNodes.Append(newN);
 
       // create a new element
-      const SMDS_MeshElement* newElem = 0;
-      const SMDS_MeshNode* N[6];
+      const SMDS_MeshElement* newElem1 = 0;
+      const SMDS_MeshElement* newElem2 = 0;
       if ( the13Diag ) {
-        N[0] = aNodes[0];
-        N[1] = aNodes[1];
-        N[2] = aNodes[2];
-        N[3] = aNodes[4];
-        N[4] = aNodes[5];
-        N[5] = newN;
-        newElem = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0],
-                                 aNodes[6], aNodes[7], newN );
+        newElem1 = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0],
+                                  aNodes[6], aNodes[7], newN );
+        newElem2 = aMesh->AddFace(aNodes[2], aNodes[0], aNodes[1],
+                                  newN,      aNodes[4], aNodes[5] );
       }
       else {
-        N[0] = aNodes[1];
-        N[1] = aNodes[2];
-        N[2] = aNodes[3];
-        N[3] = aNodes[5];
-        N[4] = aNodes[6];
-        N[5] = newN;
-        newElem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1],
-                                 aNodes[7], aNodes[4], newN );
+        newElem1 = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1],
+                                  aNodes[7], aNodes[4], newN );
+        newElem2 = aMesh->AddFace(aNodes[3], aNodes[1], aNodes[2],
+                                  newN,      aNodes[5], aNodes[6] );
       }
-      myLastCreatedElems.Append(newElem);
-      aMesh->ChangeElementNodes( elem, N, 6 );
+      myLastCreatedElems.Append(newElem1);
+      myLastCreatedElems.Append(newElem2);
       // put a new triangle on the same shape and add to the same groups
       if ( aShapeId )
-        aMesh->SetMeshElementOnShape( newElem, aShapeId );
-      AddToSameGroups( newElem, elem, aMesh );
+        {
+          aMesh->SetMeshElementOnShape( newElem1, aShapeId );
+          aMesh->SetMeshElementOnShape( newElem2, aShapeId );
+        }
+      AddToSameGroups( newElem1, elem, aMesh );
+      AddToSameGroups( newElem2, elem, aMesh );
+      aMesh->RemoveElement( elem );
     }
   }
 
@@ -1352,7 +2169,7 @@ double getAngle(const SMDS_MeshElement * tr1,
                 const SMDS_MeshNode *    n1,
                 const SMDS_MeshNode *    n2)
 {
-  double angle = 2*PI; // bad angle
+  double angle = 2. * M_PI; // bad angle
 
   // get normals
   SMESH::Controls::TSequenceOfXYZ P1, P2;
@@ -1381,7 +2198,7 @@ double getAngle(const SMDS_MeshElement * tr1,
     int i = 0, iDiag = -1;
     while ( it->more()) {
       const SMDS_MeshElement *n = it->next();
-      if ( n == n1 || n == n2 )
+      if ( n == n1 || n == n2 ) {
         if ( iDiag < 0)
           iDiag = i;
         else {
@@ -1391,6 +2208,7 @@ double getAngle(const SMDS_MeshElement * tr1,
             nFirst[ t ] = n;
           break;
         }
+      }
       i++;
     }
   }
@@ -1407,7 +2225,7 @@ double getAngle(const SMDS_MeshElement * tr1,
 // and able to return nodes by that ID
 // =================================================
 class LinkID_Gen {
- public:
+public:
 
   LinkID_Gen( const SMESHDS_Mesh* theMesh )
     :myMesh( theMesh ), myMaxID( theMesh->MaxNodeID() + 1)
@@ -1430,7 +2248,7 @@ class LinkID_Gen {
     return true;
   }
 
- private:
+private:
   LinkID_Gen();
   const SMESHDS_Mesh* myMesh;
   long                myMaxID;
@@ -1631,16 +2449,17 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet &                   theElems,
           mapEl_setLi.erase( tr2 );
           mapLi_listEl.erase( *link12 );
           if(tr1->NbNodes()==3) {
-            if( tr1->GetID() < tr2->GetID() ) {
-              aMesh->ChangeElementNodes( tr1, n12, 4 );
-              myLastCreatedElems.Append(tr1);
-              aMesh->RemoveElement( tr2 );
-            }
-            else {
-              aMesh->ChangeElementNodes( tr2, n12, 4 );
-              myLastCreatedElems.Append(tr2);
-              aMesh->RemoveElement( tr1);
-            }
+            const SMDS_MeshElement* newElem = 0;
+            newElem = aMesh->AddFace(n12[0], n12[1], n12[2], n12[3] );
+            myLastCreatedElems.Append(newElem);
+            AddToSameGroups( newElem, tr1, aMesh );
+            int aShapeId = tr1->getshapeId();
+            if ( aShapeId )
+              {
+                aMesh->SetMeshElementOnShape( newElem, aShapeId );
+              }
+            aMesh->RemoveElement( tr1 );
+            aMesh->RemoveElement( tr2 );
           }
           else {
             const SMDS_MeshNode* N1 [6];
@@ -1658,16 +2477,18 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet &                   theElems,
             aNodes[5] = N2[5];
             aNodes[6] = N2[3];
             aNodes[7] = N1[5];
-            if( tr1->GetID() < tr2->GetID() ) {
-              GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 );
-              myLastCreatedElems.Append(tr1);
-              GetMeshDS()->RemoveElement( tr2 );
-            }
-            else {
-              GetMeshDS()->ChangeElementNodes( tr2, aNodes, 8 );
-              myLastCreatedElems.Append(tr2);
-              GetMeshDS()->RemoveElement( tr1 );
-            }
+            const SMDS_MeshElement* newElem = 0;
+            newElem = aMesh->AddFace(aNodes[0], aNodes[1], aNodes[2], aNodes[3],
+                                     aNodes[4], aNodes[5], aNodes[6], aNodes[7]);
+            myLastCreatedElems.Append(newElem);
+            AddToSameGroups( newElem, tr1, aMesh );
+            int aShapeId = tr1->getshapeId();
+            if ( aShapeId )
+              {
+                aMesh->SetMeshElementOnShape( newElem, aShapeId );
+              }
+            aMesh->RemoveElement( tr1 );
+            aMesh->RemoveElement( tr2 );
             // remove middle node (9)
             GetMeshDS()->RemoveNode( N1[4] );
           }
@@ -1676,16 +2497,17 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet &                   theElems,
           mapEl_setLi.erase( tr3 );
           mapLi_listEl.erase( *link13 );
           if(tr1->NbNodes()==3) {
-            if( tr1->GetID() < tr2->GetID() ) {
-              aMesh->ChangeElementNodes( tr1, n13, 4 );
-              myLastCreatedElems.Append(tr1);
-              aMesh->RemoveElement( tr3 );
-            }
-            else {
-              aMesh->ChangeElementNodes( tr3, n13, 4 );
-              myLastCreatedElems.Append(tr3);
-              aMesh->RemoveElement( tr1 );
-            }
+            const SMDS_MeshElement* newElem = 0;
+            newElem = aMesh->AddFace(n13[0], n13[1], n13[2], n13[3] );
+            myLastCreatedElems.Append(newElem);
+            AddToSameGroups( newElem, tr1, aMesh );
+            int aShapeId = tr1->getshapeId();
+            if ( aShapeId )
+              {
+                aMesh->SetMeshElementOnShape( newElem, aShapeId );
+              }
+            aMesh->RemoveElement( tr1 );
+            aMesh->RemoveElement( tr3 );
           }
           else {
             const SMDS_MeshNode* N1 [6];
@@ -1703,16 +2525,18 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet &                   theElems,
             aNodes[5] = N2[5];
             aNodes[6] = N2[3];
             aNodes[7] = N1[5];
-            if( tr1->GetID() < tr2->GetID() ) {
-              GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 );
-              myLastCreatedElems.Append(tr1);
-              GetMeshDS()->RemoveElement( tr3 );
-            }
-            else {
-              GetMeshDS()->ChangeElementNodes( tr3, aNodes, 8 );
-              myLastCreatedElems.Append(tr3);
-              GetMeshDS()->RemoveElement( tr1 );
-            }
+            const SMDS_MeshElement* newElem = 0;
+            newElem = aMesh->AddFace(aNodes[0], aNodes[1], aNodes[2], aNodes[3],
+                                     aNodes[4], aNodes[5], aNodes[6], aNodes[7]);
+            myLastCreatedElems.Append(newElem);
+            AddToSameGroups( newElem, tr1, aMesh );
+            int aShapeId = tr1->getshapeId();
+            if ( aShapeId )
+              {
+                aMesh->SetMeshElementOnShape( newElem, aShapeId );
+              }
+            aMesh->RemoveElement( tr1 );
+            aMesh->RemoveElement( tr3 );
             // remove middle node (9)
             GetMeshDS()->RemoveNode( N1[4] );
           }
@@ -1739,15 +2563,15 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet &                   theElems,
 //=============================================================================
 static void swap( int i1, int i2, int idNodes[], gp_Pnt P[] )
 {
-  if ( i1 == i2 )
-    return;
-  int tmp = idNodes[ i1 ];
-  idNodes[ i1 ] = idNodes[ i2 ];
-  idNodes[ i2 ] = tmp;
-  gp_Pnt Ptmp = P[ i1 ];
-  P[ i1 ] = P[ i2 ];
-  P[ i2 ] = Ptmp;
-  DUMPSO( i1 << "(" << idNodes[ i2 ] << ") <-> " << i2 << "(" << idNodes[ i1 ] << ")");
+if ( i1 == i2 )
+return;
+int tmp = idNodes[ i1 ];
+idNodes[ i1 ] = idNodes[ i2 ];
+idNodes[ i2 ] = tmp;
+gp_Pnt Ptmp = P[ i1 ];
+P[ i1 ] = P[ i2 ];
+P[ i2 ] = Ptmp;
+DUMPSO( i1 << "(" << idNodes[ i2 ] << ") <-> " << i2 << "(" << idNodes[ i1 ] << ")");
 }
 
 //=======================================================================
@@ -1758,7 +2582,7 @@ static void swap( int i1, int i2, int idNodes[], gp_Pnt P[] )
 //=======================================================================
 
 int SMESH_MeshEditor::SortQuadNodes (const SMDS_Mesh * theMesh,
-                                     int               idNodes[] )
+int               idNodes[] )
 {
   gp_Pnt P[4];
   int i;
@@ -1787,10 +2611,10 @@ int SMESH_MeshEditor::SortQuadNodes (const SMDS_Mesh * theMesh,
       i = 1;
     swap ( i, i + 1, idNodes, P );
 
-//     for ( int ii = 0; ii < 4; ii++ ) {
-//       const SMDS_MeshNode *n = theMesh->FindNode( idNodes[ii] );
-//       DUMPSO( ii << "(" << idNodes[ii] <<") : "<<n->X()<<" "<<n->Y()<<" "<<n->Z());
-//     }
+    //     for ( int ii = 0; ii < 4; ii++ ) {
+    //       const SMDS_MeshNode *n = theMesh->FindNode( idNodes[ii] );
+    //       DUMPSO( ii << "(" << idNodes[ii] <<") : "<<n->X()<<" "<<n->Y()<<" "<<n->Z());
+    //     }
   }
   return i;
 }
@@ -1906,7 +2730,7 @@ bool SMESH_MeshEditor::SortHexaNodes (const SMDS_Mesh * theMesh,
           faceNodes.insert( idNodes[ 2 ] );
           faceNodes.insert( idNodes[ iMin ] );
           DUMPSO( "loop " << iLoop2 << " id2 " << idNodes[ 1 ] << " id3 " << idNodes[ 2 ]
-            << " leastDist = " << leastDist);
+                  << " leastDist = " << leastDist);
           if ( leastDist <= DBL_MIN )
             break;
         }
@@ -1944,11 +2768,11 @@ bool SMESH_MeshEditor::SortHexaNodes (const SMDS_Mesh * theMesh,
     P[ i ] = P[ i+1 ];
     P[ i+1 ] = Ptmp;
   }
-//   else
-//     for ( int ii = 0; ii < 4; ii++ ) {
-//       const SMDS_MeshNode *n = theMesh->FindNode( idNodes[ii] );
-//       DUMPSO( ii << "(" << idNodes[ii] <<") : "<<n->X()<<" "<<n->Y()<<" "<<n->Z());
-//    }
+  //   else
+  //     for ( int ii = 0; ii < 4; ii++ ) {
+  //       const SMDS_MeshNode *n = theMesh->FindNode( idNodes[ii] );
+  //       DUMPSO( ii << "(" << idNodes[ii] <<") : "<<n->X()<<" "<<n->Y()<<" "<<n->Z());
+  //    }
 
   // Gravity center of the top and bottom faces
   gp_Pnt aGCb = ( P[0].XYZ() + P[1].XYZ() + P[2].XYZ() + P[3].XYZ() ) / 4.;
@@ -2000,11 +2824,11 @@ bool SMESH_MeshEditor::SortHexaNodes (const SMDS_Mesh * theMesh,
     swap( 5, 7, idNodes, P );
   }
 
-//   DUMPSO( "OUTPUT: ========================================");
-//   for ( i = 0; i < 8; i++ ) {
-//     float *p = ugrid->GetPoint(idNodes[i]);
-//     DUMPSO( i << "(" << idNodes[i] << ") : " << p[0] << " " << p[1] << " " << p[2]);
-//   }
+  //   DUMPSO( "OUTPUT: ========================================");
+  //   for ( i = 0; i < 8; i++ ) {
+  //     float *p = ugrid->GetPoint(idNodes[i]);
+  //     DUMPSO( i << "(" << idNodes[i] << ") : " << p[0] << " " << p[1] << " " << p[2]);
+  //   }
 
   return true;
 }*/
@@ -2012,11 +2836,11 @@ bool SMESH_MeshEditor::SortHexaNodes (const SMDS_Mesh * theMesh,
 //================================================================================
 /*!
  * \brief Return nodes linked to the given one
 * \param theNode - the node
 * \param linkedNodes - the found nodes
 * \param type - the type of elements to check
 *
 * Medium nodes are ignored
+ * \param theNode - the node
+ * \param linkedNodes - the found nodes
+ * \param type - the type of elements to check
+ *
+ * Medium nodes are ignored
  */
 //================================================================================
 
@@ -2028,6 +2852,9 @@ void SMESH_MeshEditor::GetLinkedNodes( const SMDS_MeshNode* theNode,
   while ( elemIt->more() )
   {
     const SMDS_MeshElement* elem = elemIt->next();
+    if(elem->GetType() == SMDSAbs_0DElement)
+      continue;
+    
     SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
     if ( elem->GetType() == SMDSAbs_Volume )
     {
@@ -2050,8 +2877,8 @@ void SMESH_MeshEditor::GetLinkedNodes( const SMDS_MeshNode* theNode,
             iAfter  = SMESH_MesherHelper::WrapIndex( iAfter, nb );
             iBefore = SMESH_MesherHelper::WrapIndex( iBefore, nb );
           }
-          linkedNodes.insert( elem->GetNode( iAfter ));
-          linkedNodes.insert( elem->GetNode( iBefore ));
+          linkedNodes.insert( elem->GetNodeWrap( iAfter ));
+          linkedNodes.insert( elem->GetNodeWrap( iBefore ));
         }
       }
     }
@@ -2184,8 +3011,13 @@ static bool getClosestUV (Extrema_GenExtPS& projector,
   if ( projector.IsDone() ) {
     double u, v, minVal = DBL_MAX;
     for ( int i = projector.NbExt(); i > 0; i-- )
+#if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
+      if ( projector.SquareDistance( i ) < minVal ) {
+        minVal = projector.SquareDistance( i );
+#else
       if ( projector.Value( i ) < minVal ) {
         minVal = projector.Value( i );
+#endif
         projector.Point( i ).Parameter( u, v );
       }
     result.SetCoord( u, v );
@@ -2260,7 +3092,7 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet &          theElems,
     Handle(Geom_Surface) surface;
     SMESHDS_SubMesh* faceSubMesh = 0;
     TopoDS_Face face;
-    double fToler2 = 0, vPeriod = 0., uPeriod = 0., f,l;
+    double fToler2 = 0, f,l;
     double u1 = 0, u2 = 0, v1 = 0, v2 = 0;
     bool isUPeriodic = false, isVPeriodic = false;
     if ( *fId ) {
@@ -2271,10 +3103,10 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet &          theElems,
       fToler2 *= fToler2 * 10.;
       isUPeriodic = surface->IsUPeriodic();
       if ( isUPeriodic )
-        vPeriod = surface->UPeriod();
+        surface->UPeriod();
       isVPeriodic = surface->IsVPeriodic();
       if ( isVPeriodic )
-        uPeriod = surface->VPeriod();
+        surface->VPeriod();
       surface->Bounds( u1, u2, v1, v2 );
     }
     // ---------------------------------------------------------
@@ -2296,14 +3128,14 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet &          theElems,
     }
     int nbElemOnFace = 0;
     itElem = theElems.begin();
-     // loop on not yet smoothed elements: look for elems on a face
+    // loop on not yet smoothed elements: look for elems on a face
     while ( itElem != theElems.end() ) {
       if ( faceSubMesh && nbElemOnFace == faceSubMesh->NbElements() )
         break; // all elements found
 
       const SMDS_MeshElement* elem = *itElem;
       if ( !elem || elem->GetType() != SMDSAbs_Face || elem->NbNodes() < 3 ||
-          ( faceSubMesh && !faceSubMesh->Contains( elem ))) {
+           ( faceSubMesh && !faceSubMesh->Contains( elem ))) {
         ++itElem;
         continue;
       }
@@ -2324,7 +3156,7 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet &          theElems,
       while ( nn++ < nbn ) {
         node = static_cast<const SMDS_MeshNode*>( itN->next() );
         const SMDS_PositionPtr& pos = node->GetPosition();
-        posType = pos.get() ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE;
+        posType = pos ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE;
         if (posType != SMDS_TOP_EDGE &&
             posType != SMDS_TOP_VERTEX &&
             theFixedNodes.find( node ) == theFixedNodes.end())
@@ -2362,19 +3194,19 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet &          theElems,
         if ( uvMap.find( node ) == uvMap.end() )
           uvCheckNodes.push_back( node );
         // add nodes of elems sharing node
-//         SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator(SMDSAbs_Face);
-//         while ( eIt->more() ) {
-//           const SMDS_MeshElement* e = eIt->next();
-//           if ( e != elem ) {
-//             SMDS_ElemIteratorPtr nIt = e->nodesIterator();
-//             while ( nIt->more() ) {
-//               const SMDS_MeshNode* n =
-//                 static_cast<const SMDS_MeshNode*>( nIt->next() );
-//               if ( uvMap.find( n ) == uvMap.end() )
-//                 uvCheckNodes.push_back( n );
-//             }
-//           }
-//         }
+        //         SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator(SMDSAbs_Face);
+        //         while ( eIt->more() ) {
+        //           const SMDS_MeshElement* e = eIt->next();
+        //           if ( e != elem ) {
+        //             SMDS_ElemIteratorPtr nIt = e->nodesIterator();
+        //             while ( nIt->more() ) {
+        //               const SMDS_MeshNode* n =
+        //                 static_cast<const SMDS_MeshNode*>( nIt->next() );
+        //               if ( uvMap.find( n ) == uvMap.end() )
+        //                 uvCheckNodes.push_back( n );
+        //             }
+        //           }
+        //         }
       }
       // check UV on face
       list< const SMDS_MeshNode* >::iterator n = uvCheckNodes.begin();
@@ -2382,27 +3214,27 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet &          theElems,
         node = *n;
         gp_XY uv( 0, 0 );
         const SMDS_PositionPtr& pos = node->GetPosition();
-        posType = pos.get() ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE;
+        posType = pos ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE;
         // get existing UV
         switch ( posType ) {
         case SMDS_TOP_FACE: {
-          SMDS_FacePosition* fPos = ( SMDS_FacePosition* ) pos.get();
+          SMDS_FacePosition* fPos = ( SMDS_FacePosition* ) pos;
           uv.SetCoord( fPos->GetUParameter(), fPos->GetVParameter() );
           break;
         }
         case SMDS_TOP_EDGE: {
-          TopoDS_Shape S = aMesh->IndexToShape( pos->GetShapeId() );
+          TopoDS_Shape S = aMesh->IndexToShape( node->getshapeId() );
           Handle(Geom2d_Curve) pcurve;
           if ( !S.IsNull() && S.ShapeType() == TopAbs_EDGE )
             pcurve = BRep_Tool::CurveOnSurface( TopoDS::Edge( S ), face, f,l );
           if ( !pcurve.IsNull() ) {
-            double u = (( SMDS_EdgePosition* ) pos.get() )->GetUParameter();
+            double u = (( SMDS_EdgePosition* ) pos )->GetUParameter();
             uv = pcurve->Value( u ).XY();
           }
           break;
         }
         case SMDS_TOP_VERTEX: {
-          TopoDS_Shape S = aMesh->IndexToShape( pos->GetShapeId() );
+          TopoDS_Shape S = aMesh->IndexToShape( node->getshapeId() );
           if ( !S.IsNull() && S.ShapeType() == TopAbs_VERTEX )
             uv = BRep_Tool::Parameters( TopoDS::Vertex( S ), face ).XY();
           break;
@@ -2446,35 +3278,27 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet &          theElems,
     // fix nodes on mesh boundary
 
     if ( checkBoundaryNodes ) {
-      map< NLink, int > linkNbMap; // how many times a link encounters in elemsOnFace
-      map< NLink, int >::iterator link_nb;
+      map< SMESH_TLink, int > linkNbMap; // how many times a link encounters in elemsOnFace
+      map< SMESH_TLink, int >::iterator link_nb;
       // put all elements links to linkNbMap
       list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin();
       for ( ; elemIt != elemsOnFace.end(); ++elemIt ) {
         const SMDS_MeshElement* elem = (*elemIt);
-        int nbn =  elem->NbNodes();
-        if(elem->IsQuadratic())
-          nbn = nbn/2;
+        int nbn =  elem->NbCornerNodes();
         // loop on elem links: insert them in linkNbMap
-        const SMDS_MeshNode* curNode, *prevNode = elem->GetNode( nbn );
         for ( int iN = 0; iN < nbn; ++iN ) {
-          curNode = elem->GetNode( iN );
-          NLink link;
-          if ( curNode < prevNode ) link = make_pair( curNode , prevNode );
-          else                      link = make_pair( prevNode , curNode );
-          prevNode = curNode;
-          link_nb = linkNbMap.find( link );
-          if ( link_nb == linkNbMap.end() )
-            linkNbMap.insert( make_pair ( link, 1 ));
-          else
-            link_nb->second++;
+          const SMDS_MeshNode* n1 = elem->GetNode( iN );
+          const SMDS_MeshNode* n2 = elem->GetNode(( iN+1 ) % nbn);
+          SMESH_TLink link( n1, n2 );
+          link_nb = linkNbMap.insert( make_pair( link, 0 )).first;
+          link_nb->second++;
         }
       }
       // remove nodes that are in links encountered only once from setMovableNodes
       for ( link_nb = linkNbMap.begin(); link_nb != linkNbMap.end(); ++link_nb ) {
         if ( link_nb->second == 1 ) {
-          setMovableNodes.erase( link_nb->first.first );
-          setMovableNodes.erase( link_nb->first.second );
+          setMovableNodes.erase( link_nb->first.node1() );
+          setMovableNodes.erase( link_nb->first.node2() );
         }
       }
     }
@@ -2665,7 +3489,7 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet &          theElems,
       if ( node_uv != uvMap.end() ) {
         gp_XY* uv = node_uv->second;
         node->SetPosition
-          ( SMDS_PositionPtr( new SMDS_FacePosition( *fId, uv->X(), uv->Y() )));
+          ( SMDS_PositionPtr( new SMDS_FacePosition( uv->X(), uv->Y() )));
       }
     }
 
@@ -2677,14 +3501,14 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet &          theElems,
         helper.SetSubShape( face );
       list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin();
       for ( ; elemIt != elemsOnFace.end(); ++elemIt ) {
-        const SMDS_QuadraticFaceOfNodes* QF =
-          dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (*elemIt);
-        if(QF) {
+        const SMDS_VtkFace* QF =
+          dynamic_cast<const SMDS_VtkFace*> (*elemIt);
+        if(QF && QF->IsQuadratic()) {
           vector<const SMDS_MeshNode*> Ns;
           Ns.reserve(QF->NbNodes()+1);
-          SMDS_NodeIteratorPtr anIter = QF->interlacedNodesIterator();
+          SMDS_ElemIteratorPtr anIter = QF->interlacedNodesElemIterator();
           while ( anIter->more() )
-            Ns.push_back( anIter->next() );
+            Ns.push_back( cast2Node(anIter->next()) );
           Ns.push_back( Ns[0] );
           double x, y, z;
           for(int i=0; i<QF->NbNodes(); i=i+2) {
@@ -2719,30 +3543,22 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet &          theElems,
 //function : isReverse
 //purpose  : Return true if normal of prevNodes is not co-directied with
 //           gp_Vec(prevNodes[iNotSame],nextNodes[iNotSame]).
-//           iNotSame is where prevNodes and nextNodes are different
+//           iNotSame is where prevNodes and nextNodes are different.
+//           If result is true then future volume orientation is OK
 //=======================================================================
 
-static bool isReverse(vector<const SMDS_MeshNode*> prevNodes,
-                      vector<const SMDS_MeshNode*> nextNodes,
-                      const int            nbNodes,
-                      const int            iNotSame)
+static bool isReverse(const SMDS_MeshElement*             face,
+                      const vector<const SMDS_MeshNode*>& prevNodes,
+                      const vector<const SMDS_MeshNode*>& nextNodes,
+                      const int                           iNotSame)
 {
-  int iBeforeNotSame = ( iNotSame == 0 ? nbNodes - 1 : iNotSame - 1 );
-  int iAfterNotSame  = ( iNotSame + 1 == nbNodes ? 0 : iNotSame + 1 );
-
-  const SMDS_MeshNode* nB = prevNodes[ iBeforeNotSame ];
-  const SMDS_MeshNode* nA = prevNodes[ iAfterNotSame ];
-  const SMDS_MeshNode* nP = prevNodes[ iNotSame ];
-  const SMDS_MeshNode* nN = nextNodes[ iNotSame ];
 
-  gp_Pnt pB ( nB->X(), nB->Y(), nB->Z() );
-  gp_Pnt pA ( nA->X(), nA->Y(), nA->Z() );
-  gp_Pnt pP ( nP->X(), nP->Y(), nP->Z() );
-  gp_Pnt pN ( nN->X(), nN->Y(), nN->Z() );
+  SMESH_TNodeXYZ pP = prevNodes[ iNotSame ];
+  SMESH_TNodeXYZ pN = nextNodes[ iNotSame ];
+  gp_XYZ extrDir( pN - pP ), faceNorm;
+  SMESH_Algo::FaceNormal( face, faceNorm, /*normalized=*/false );
 
-  gp_Vec vB ( pP, pB ), vA ( pP, pA ), vN ( pP, pN );
-
-  return (vA ^ vB) * vN < 0.0;
+  return faceNorm * extrDir < 0.0;
 }
 
 //=======================================================================
@@ -2762,296 +3578,413 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement*               elem,
                                     const int                             nbSteps,
                                     SMESH_SequenceOfElemPtr&              srcElements)
 {
+  //MESSAGE("sweepElement " << nbSteps);
   SMESHDS_Mesh* aMesh = GetMeshDS();
 
+  const int           nbNodes = elem->NbNodes();          
+  const int         nbCorners = elem->NbCornerNodes();
+  SMDSAbs_EntityType baseType = elem->GetEntityType(); /* it can change in case of 
+                                                          polyhedron creation !!! */
   // Loop on elem nodes:
   // find new nodes and detect same nodes indices
-  int nbNodes = elem->NbNodes();
   vector < list< const SMDS_MeshNode* >::const_iterator > itNN( nbNodes );
   vector<const SMDS_MeshNode*> prevNod( nbNodes );
   vector<const SMDS_MeshNode*> nextNod( nbNodes );
   vector<const SMDS_MeshNode*> midlNod( nbNodes );
 
-  int iNode, nbSame = 0, iNotSameNode = 0, iSameNode = 0;
+  int iNode, nbSame = 0, nbDouble = 0, iNotSameNode = 0;
   vector<int> sames(nbNodes);
-
-  //bool issimple[nbNodes];
-  vector<bool> issimple(nbNodes);
+  vector<bool> isSingleNode(nbNodes);
 
   for ( iNode = 0; iNode < nbNodes; iNode++ ) {
-    TNodeOfNodeListMapItr nnIt = newNodesItVec[ iNode ];
-    const SMDS_MeshNode*                 node         = nnIt->first;
+    TNodeOfNodeListMapItr                        nnIt = newNodesItVec[ iNode ];
+    const SMDS_MeshNode*                         node = nnIt->first;
     const list< const SMDS_MeshNode* > & listNewNodes = nnIt->second;
     if ( listNewNodes.empty() )
       return;
 
-    if(listNewNodes.size()==nbSteps) {
-      issimple[iNode] = true;
-    }
-    else {
-      issimple[iNode] = false;
-    }
-
-    itNN[ iNode ] = listNewNodes.begin();
+    itNN   [ iNode ] = listNewNodes.begin();
     prevNod[ iNode ] = node;
     nextNod[ iNode ] = listNewNodes.front();
-//cout<<"iNode="<<iNode<<endl;
-//cout<<" prevNod[iNode]="<< prevNod[iNode]<<" nextNod[iNode]="<< nextNod[iNode]<<endl;
+
+    isSingleNode[iNode] = (listNewNodes.size()==nbSteps); /* medium node of quadratic or
+                                                             corner node of linear */
     if ( prevNod[ iNode ] != nextNod [ iNode ])
-      iNotSameNode = iNode;
-    else {
-      iSameNode = iNode;
-      //nbSame++;
-      sames[nbSame++] = iNode;
+      nbDouble += !isSingleNode[iNode];
+
+    if( iNode < nbCorners ) { // check corners only
+      if ( prevNod[ iNode ] == nextNod [ iNode ])
+        sames[nbSame++] = iNode;
+      else
+        iNotSameNode = iNode;
     }
   }
-//cout<<"1 nbSame="<<nbSame<<endl;
+
   if ( nbSame == nbNodes || nbSame > 2) {
     MESSAGE( " Too many same nodes of element " << elem->GetID() );
     return;
   }
 
-//  if( elem->IsQuadratic() && nbSame>0 ) {
-//    MESSAGE( "Can not rotate quadratic element " << elem->GetID() );
-//    return;
-//  }
-
-  int iBeforeSame = 0, iAfterSame = 0, iOpposSame = 0;
-  if ( nbSame > 0 ) {
-    iBeforeSame = ( iSameNode == 0 ? nbNodes - 1 : iSameNode - 1 );
-    iAfterSame  = ( iSameNode + 1 == nbNodes ? 0 : iSameNode + 1 );
-    iOpposSame  = ( iSameNode - 2 < 0  ? iSameNode + 2 : iSameNode - 2 );
+  if ( elem->GetType() == SMDSAbs_Face && !isReverse( elem, prevNod, nextNod, iNotSameNode ))
+  {
+    // fix nodes order to have bottom normal external
+    if ( baseType == SMDSEntity_Polygon )
+    {
+      std::reverse( itNN.begin(), itNN.end() );
+      std::reverse( prevNod.begin(), prevNod.end() );
+      std::reverse( midlNod.begin(), midlNod.end() );
+      std::reverse( nextNod.begin(), nextNod.end() );
+      std::reverse( isSingleNode.begin(), isSingleNode.end() );
+    }
+    else
+    {
+      const vector<int>& ind = SMDS_MeshCell::reverseSmdsOrder( baseType );
+      SMDS_MeshCell::applyInterlace( ind, itNN );
+      SMDS_MeshCell::applyInterlace( ind, prevNod );
+      SMDS_MeshCell::applyInterlace( ind, nextNod );
+      SMDS_MeshCell::applyInterlace( ind, midlNod );
+      SMDS_MeshCell::applyInterlace( ind, isSingleNode );
+      if ( nbSame > 0 )
+      {
+        sames[nbSame] = iNotSameNode;
+        for ( int j = 0; j <= nbSame; ++j )
+          for ( size_t i = 0; i < ind.size(); ++i )
+            if ( ind[i] == sames[j] )
+            {
+              sames[j] = i;
+              break;
+            }
+        iNotSameNode = sames[nbSame];
+      }
+    }
   }
 
-//if(nbNodes==8)
-//cout<<" prevNod[0]="<< prevNod[0]<<" prevNod[1]="<< prevNod[1]
-//    <<" prevNod[2]="<< prevNod[2]<<" prevNod[3]="<< prevNod[4]
-//    <<" prevNod[4]="<< prevNod[4]<<" prevNod[5]="<< prevNod[5]
-//    <<" prevNod[6]="<< prevNod[6]<<" prevNod[7]="<< prevNod[7]<<endl;
-
-  // check element orientation
-  int i0 = 0, i2 = 2;
-  if ( nbNodes > 2 && !isReverse( prevNod, nextNod, nbNodes, iNotSameNode )) {
-    //MESSAGE("Reversed elem " << elem );
-    i0 = 2;
-    i2 = 0;
-    if ( nbSame > 0 ) {
-      int iAB = iAfterSame + iBeforeSame;
-      iBeforeSame = iAB - iBeforeSame;
-      iAfterSame  = iAB - iAfterSame;
-    }
+  int iSameNode = 0, iBeforeSame = 0, iAfterSame = 0, iOpposSame = 0;
+  if ( nbSame > 0 ) {
+    iSameNode    = sames[ nbSame-1 ];
+    iBeforeSame  = ( iSameNode + nbCorners - 1 ) % nbCorners;
+    iAfterSame   = ( iSameNode + 1 ) % nbCorners;
+    iOpposSame   = ( iSameNode - 2 < 0  ? iSameNode + 2 : iSameNode - 2 );
   }
 
   // make new elements
-  for (int iStep = 0; iStep < nbSteps; iStep++ ) {
+  for (int iStep = 0; iStep < nbSteps; iStep++ )
+  {
     // get next nodes
-    for ( iNode = 0; iNode < nbNodes; iNode++ ) {
-      if(issimple[iNode]) {
-        nextNod[ iNode ] = *itNN[ iNode ];
-        itNN[ iNode ]++;
-      }
-      else {
-        if( elem->GetType()==SMDSAbs_Node ) {
-          // we have to use two nodes
-          midlNod[ iNode ] = *itNN[ iNode ];
-          itNN[ iNode ]++;
-          nextNod[ iNode ] = *itNN[ iNode ];
-          itNN[ iNode ]++;
-        }
-        else if(!elem->IsQuadratic() ||
-           elem->IsQuadratic() && elem->IsMediumNode(prevNod[iNode]) ) {
-          // we have to use each second node
-          itNN[ iNode ]++;
-          nextNod[ iNode ] = *itNN[ iNode ];
-          itNN[ iNode ]++;
-        }
-        else {
-          // we have to use two nodes
-          midlNod[ iNode ] = *itNN[ iNode ];
-          itNN[ iNode ]++;
-          nextNod[ iNode ] = *itNN[ iNode ];
-          itNN[ iNode ]++;
-        }
-      }
+    for ( iNode = 0; iNode < nbNodes; iNode++ )
+    {
+      midlNod[ iNode ] = isSingleNode[iNode] ? 0 : *itNN[ iNode ]++;
+      nextNod[ iNode ] = *itNN[ iNode ]++;
     }
+
     SMDS_MeshElement* aNewElem = 0;
-    if(!elem->IsPoly()) {
-      switch ( nbNodes ) {
-      case 0:
-        return;
-      case 1: { // NODE
+    /*if(!elem->IsPoly())*/ {
+      switch ( baseType ) {
+      case SMDSEntity_0D:
+      case SMDSEntity_Node: { // sweep NODE
         if ( nbSame == 0 ) {
-          if(issimple[0])
+          if ( isSingleNode[0] )
             aNewElem = aMesh->AddEdge( prevNod[ 0 ], nextNod[ 0 ] );
           else
             aNewElem = aMesh->AddEdge( prevNod[ 0 ], nextNod[ 0 ], midlNod[ 0 ] );
         }
+        else
+          return;
         break;
       }
-      case 2: { // EDGE
-        if ( nbSame == 0 )
-          aNewElem = aMesh->AddFace(prevNod[ 0 ], prevNod[ 1 ],
-                                    nextNod[ 1 ], nextNod[ 0 ] );
-        else
-          aNewElem = aMesh->AddFace(prevNod[ 0 ], prevNod[ 1 ],
-                                    nextNod[ iNotSameNode ] );
+      case SMDSEntity_Edge: { // sweep EDGE
+        if ( nbDouble == 0 )
+        {
+          if ( nbSame == 0 ) // ---> quadrangle
+            aNewElem = aMesh->AddFace(prevNod[ 0 ], prevNod[ 1 ],
+                                      nextNod[ 1 ], nextNod[ 0 ] );
+          else               // ---> triangle
+            aNewElem = aMesh->AddFace(prevNod[ 0 ], prevNod[ 1 ],
+                                      nextNod[ iNotSameNode ] );
+        }
+        else                 // ---> polygon
+        {
+          vector<const SMDS_MeshNode*> poly_nodes;
+          poly_nodes.push_back( prevNod[0] );
+          poly_nodes.push_back( prevNod[1] );
+          if ( prevNod[1] != nextNod[1] )
+          {
+            if ( midlNod[1]) poly_nodes.push_back( midlNod[1]);
+            poly_nodes.push_back( nextNod[1] );
+          }
+          if ( prevNod[0] != nextNod[0] )
+          {
+            poly_nodes.push_back( nextNod[0] );
+            if ( midlNod[0]) poly_nodes.push_back( midlNod[0]);
+          }
+          switch ( poly_nodes.size() ) {
+          case 3:
+            aNewElem = aMesh->AddFace( poly_nodes[ 0 ], poly_nodes[ 1 ], poly_nodes[ 2 ]);
+            break;
+          case 4:
+            aNewElem = aMesh->AddFace( poly_nodes[ 0 ], poly_nodes[ 1 ],
+                                       poly_nodes[ 2 ], poly_nodes[ 3 ]);
+            break;
+          default:
+            aNewElem = aMesh->AddPolygonalFace (poly_nodes);
+          }
+        }
         break;
       }
-
-      case 3: { // TRIANGLE or quadratic edge
-        if(elem->GetType() == SMDSAbs_Face) { // TRIANGLE
-
-          if ( nbSame == 0 )       // --- pentahedron
-            aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ],
-                                         nextNod[ i0 ], nextNod[ 1 ], nextNod[ i2 ] );
-
-          else if ( nbSame == 1 )  // --- pyramid
-            aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ],  prevNod[ iAfterSame ],
-                                         nextNod[ iAfterSame ], nextNod[ iBeforeSame ],
+      case SMDSEntity_Triangle: // TRIANGLE --->
+        {
+          if ( nbDouble > 0 ) break;
+          if ( nbSame == 0 )       // ---> pentahedron
+            aNewElem = aMesh->AddVolume (prevNod[ 0 ], prevNod[ 1 ], prevNod[ 2 ],
+                                         nextNod[ 0 ], nextNod[ 1 ], nextNod[ 2 ] );
+
+          else if ( nbSame == 1 )  // ---> pyramid
+            aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iAfterSame ],
+                                         nextNod[ iAfterSame ],  nextNod[ iBeforeSame ],
                                          nextNod[ iSameNode ]);
 
-          else // 2 same nodes:      --- tetrahedron
-            aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ],
+          else // 2 same nodes:       ---> tetrahedron
+            aNewElem = aMesh->AddVolume (prevNod[ 0 ], prevNod[ 1 ], prevNod[ 2 ],
                                          nextNod[ iNotSameNode ]);
+          break;
         }
-        else { // quadratic edge
-          if(nbSame==0) {     // quadratic quadrangle
-            aNewElem = aMesh->AddFace(prevNod[0], nextNod[0], nextNod[1], prevNod[1],
-                                      midlNod[0], nextNod[2], midlNod[1], prevNod[2]);
-          }
-          else if(nbSame==1) { // quadratic triangle
-            if(sames[0]==2)
-              return; // medium node on axis
-            else if(sames[0]==0) {
-              aNewElem = aMesh->AddFace(prevNod[0], nextNod[1], prevNod[1],
-                                        nextNod[2], midlNod[1], prevNod[2]);
+      case SMDSEntity_Quad_Edge: // sweep quadratic EDGE --->
+        {
+          if ( nbSame == 2 )
+            return;
+          if ( nbDouble+nbSame == 2 )
+          {
+            if(nbSame==0) {      // ---> quadratic quadrangle
+              aNewElem = aMesh->AddFace(prevNod[0], prevNod[1], nextNod[1], nextNod[0],
+                                        prevNod[2], midlNod[1], nextNod[2], midlNod[0]);
+            }
+            else { //(nbSame==1) // ---> quadratic triangle
+              if(sames[0]==2) {
+                return; // medium node on axis
+              }
+              else if(sames[0]==0)
+                aNewElem = aMesh->AddFace(prevNod[0], nextNod[1], prevNod[1],
+                                          nextNod[2], midlNod[1], prevNod[2]);
+              else // sames[0]==1
+                aNewElem = aMesh->AddFace(prevNod[0], nextNod[0], prevNod[1],
+                                          midlNod[0], nextNod[2], prevNod[2]);
             }
-            else { // sames[0]==1
-              aNewElem = aMesh->AddFace(prevNod[0], nextNod[0], prevNod[1],
-                                        midlNod[0], nextNod[2], prevNod[2]);
+          }
+          else if ( nbDouble == 3 )
+          {
+            if ( nbSame == 0 ) {  // ---> bi-quadratic quadrangle
+              aNewElem = aMesh->AddFace(prevNod[0], prevNod[1], nextNod[1], nextNod[0],
+                                        prevNod[2], midlNod[1], nextNod[2], midlNod[0], midlNod[2]);
             }
           }
           else
             return;
+          break;
         }
-        break;
-      }
-      case 4: { // QUADRANGLE
+      case SMDSEntity_Quadrangle: { // sweep QUADRANGLE --->
+        if ( nbDouble > 0 ) break;
 
-        if ( nbSame == 0 )       // --- hexahedron
-          aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ], prevNod[ 3 ],
-                                       nextNod[ i0 ], nextNod[ 1 ], nextNod[ i2 ], nextNod[ 3 ]);
+        if ( nbSame == 0 )       // ---> hexahedron
+          aNewElem = aMesh->AddVolume (prevNod[ 0 ], prevNod[ 1 ], prevNod[ 2 ], prevNod[ 3 ],
+                                       nextNod[ 0 ], nextNod[ 1 ], nextNod[ 2 ], nextNod[ 3 ]);
 
-        else if ( nbSame == 1 ) { // --- pyramid + pentahedron
-          aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ],  prevNod[ iAfterSame ],
-                                       nextNod[ iAfterSame ], nextNod[ iBeforeSame ],
+        else if ( nbSame == 1 ) { // ---> pyramid + pentahedron
+          aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iAfterSame ],
+                                       nextNod[ iAfterSame ],  nextNod[ iBeforeSame ],
                                        nextNod[ iSameNode ]);
           newElems.push_back( aNewElem );
-          aNewElem = aMesh->AddVolume (prevNod[ iAfterSame ], prevNod[ iOpposSame ],
-                                       prevNod[ iBeforeSame ],  nextNod[ iAfterSame ],
+          aNewElem = aMesh->AddVolume (prevNod[ iAfterSame ],  prevNod[ iOpposSame ],
+                                       prevNod[ iBeforeSame ], nextNod[ iAfterSame ],
                                        nextNod[ iOpposSame ],  nextNod[ iBeforeSame ] );
         }
-        else if ( nbSame == 2 ) { // pentahedron
+        else if ( nbSame == 2 ) { // ---> pentahedron
           if ( prevNod[ iBeforeSame ] == nextNod[ iBeforeSame ] )
             // iBeforeSame is same too
             aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iOpposSame ],
-                                         nextNod[ iOpposSame ], prevNod[ iSameNode ],
+                                         nextNod[ iOpposSame ],  prevNod[ iSameNode ],
                                          prevNod[ iAfterSame ],  nextNod[ iAfterSame ]);
           else
             // iAfterSame is same too
-            aNewElem = aMesh->AddVolume (prevNod[ iSameNode ], prevNod[ iBeforeSame ],
+            aNewElem = aMesh->AddVolume (prevNod[ iSameNode ],   prevNod[ iBeforeSame ],
                                          nextNod[ iBeforeSame ], prevNod[ iAfterSame ],
                                          prevNod[ iOpposSame ],  nextNod[ iOpposSame ]);
         }
         break;
       }
-      case 6: { // quadratic triangle
-        // create pentahedron with 15 nodes
-        if(i0>0) { // reversed case
-          aNewElem = aMesh->AddVolume (prevNod[0], prevNod[2], prevNod[1],
-                                       nextNod[0], nextNod[2], nextNod[1],
-                                       prevNod[5], prevNod[4], prevNod[3],
-                                       nextNod[5], nextNod[4], nextNod[3],
-                                       midlNod[0], midlNod[2], midlNod[1]);
-        }
-        else { // not reversed case
+      case SMDSEntity_Quad_Triangle: { // sweep Quadratic TRIANGLE --->
+        if ( nbDouble+nbSame != 3 ) break;
+        if(nbSame==0) {
+          // --->  pentahedron with 15 nodes
           aNewElem = aMesh->AddVolume (prevNod[0], prevNod[1], prevNod[2],
                                        nextNod[0], nextNod[1], nextNod[2],
                                        prevNod[3], prevNod[4], prevNod[5],
                                        nextNod[3], nextNod[4], nextNod[5],
                                        midlNod[0], midlNod[1], midlNod[2]);
         }
+        else if(nbSame==1) {
+          // --->  2d order pyramid of 13 nodes
+          int apex = iSameNode;
+          int i0 = ( apex + 1 ) % nbCorners;
+          int i1 = ( apex - 1 + nbCorners ) % nbCorners;
+          int i0a = apex + 3;
+          int i1a = i1 + 3;
+          int i01 = i0 + 3;
+          aNewElem = aMesh->AddVolume(prevNod[i1], prevNod[i0],
+                                      nextNod[i0], nextNod[i1], prevNod[apex],
+                                      prevNod[i01], midlNod[i0],
+                                      nextNod[i01], midlNod[i1],
+                                      prevNod[i1a], prevNod[i0a],
+                                      nextNod[i0a], nextNod[i1a]);
+        }
+        else if(nbSame==2) {
+          // --->  2d order tetrahedron of 10 nodes
+          int n1 = iNotSameNode;
+          int n2 = ( n1 + 1             ) % nbCorners;
+          int n3 = ( n1 + nbCorners - 1 ) % nbCorners;
+          int n12 = n1 + 3;
+          int n23 = n2 + 3;
+          int n31 = n3 + 3;
+          aNewElem = aMesh->AddVolume (prevNod[n1], prevNod[n2], prevNod[n3], nextNod[n1],
+                                       prevNod[n12], prevNod[n23], prevNod[n31],
+                                       midlNod[n1], nextNod[n12], nextNod[n31]);
+        }
         break;
       }
-      case 8: { // quadratic quadrangle
-        // create hexahedron with 20 nodes
-        if(i0>0) { // reversed case
-          aNewElem = aMesh->AddVolume (prevNod[0], prevNod[3], prevNod[2], prevNod[1],
-                                       nextNod[0], nextNod[3], nextNod[2], nextNod[1],
-                                       prevNod[7], prevNod[6], prevNod[5], prevNod[4],
-                                       nextNod[7], nextNod[6], nextNod[5], nextNod[4],
-                                       midlNod[0], midlNod[3], midlNod[2], midlNod[1]);
-        }
-        else { // not reversed case
+      case SMDSEntity_Quad_Quadrangle: { // sweep Quadratic QUADRANGLE --->
+        if( nbSame == 0 ) {
+          if ( nbDouble != 4 ) break;
+          // --->  hexahedron with 20 nodes
           aNewElem = aMesh->AddVolume (prevNod[0], prevNod[1], prevNod[2], prevNod[3],
                                        nextNod[0], nextNod[1], nextNod[2], nextNod[3],
                                        prevNod[4], prevNod[5], prevNod[6], prevNod[7],
                                        nextNod[4], nextNod[5], nextNod[6], nextNod[7],
                                        midlNod[0], midlNod[1], midlNod[2], midlNod[3]);
         }
+        else if(nbSame==1) {
+          // ---> pyramid + pentahedron - can not be created since it is needed 
+          // additional middle node at the center of face
+          INFOS( " Sweep for face " << elem->GetID() << " can not be created" );
+          return;
+        }
+        else if( nbSame == 2 ) {
+          if ( nbDouble != 2 ) break;
+          // --->  2d order Pentahedron with 15 nodes
+          int n1,n2,n4,n5;
+          if ( prevNod[ iBeforeSame ] == nextNod[ iBeforeSame ] ) {
+            // iBeforeSame is same too
+            n1 = iBeforeSame;
+            n2 = iOpposSame;
+            n4 = iSameNode;
+            n5 = iAfterSame;
+          }
+          else {
+            // iAfterSame is same too
+            n1 = iSameNode;
+            n2 = iBeforeSame;
+            n4 = iAfterSame;
+            n5 = iOpposSame;
+          }
+          int n12 = n2 + 4;
+          int n45 = n4 + 4;
+          int n14 = n1 + 4;
+          int n25 = n5 + 4;
+          aNewElem = aMesh->AddVolume (prevNod[n1], prevNod[n2], nextNod[n2],
+                                       prevNod[n4], prevNod[n5], nextNod[n5],
+                                       prevNod[n12], midlNod[n2], nextNod[n12],
+                                       prevNod[n45], midlNod[n5], nextNod[n45],
+                                       prevNod[n14], prevNod[n25], nextNod[n25]);
+        }
         break;
       }
-      default: {
-        // realized for extrusion only
-        //vector<const SMDS_MeshNode*> polyedre_nodes (nbNodes*2 + 4*nbNodes);
-        //vector<int> quantities (nbNodes + 2);
-
-        //quantities[0] = nbNodes; // bottom of prism
-        //for (int inode = 0; inode < nbNodes; inode++) {
-        //  polyedre_nodes[inode] = prevNod[inode];
-        //}
-
-        //quantities[1] = nbNodes; // top of prism
-        //for (int inode = 0; inode < nbNodes; inode++) {
-        //  polyedre_nodes[nbNodes + inode] = nextNod[inode];
-        //}
-
-        //for (int iface = 0; iface < nbNodes; iface++) {
-        //  quantities[iface + 2] = 4;
-        //  int inextface = (iface == nbNodes - 1) ? 0 : iface + 1;
-        //  polyedre_nodes[2*nbNodes + 4*iface + 0] = prevNod[iface];
-        //  polyedre_nodes[2*nbNodes + 4*iface + 1] = prevNod[inextface];
-        //  polyedre_nodes[2*nbNodes + 4*iface + 2] = nextNod[inextface];
-        //  polyedre_nodes[2*nbNodes + 4*iface + 3] = nextNod[iface];
-        //}
-        //aNewElem = aMesh->AddPolyhedralVolume (polyedre_nodes, quantities);
+      case SMDSEntity_BiQuad_Quadrangle: { // sweep BiQuadratic QUADRANGLE --->
+
+        if( nbSame == 0 && nbDouble == 9 ) {
+          // --->  tri-quadratic hexahedron with 27 nodes
+          aNewElem = aMesh->AddVolume (prevNod[0], prevNod[1], prevNod[2], prevNod[3],
+                                       nextNod[0], nextNod[1], nextNod[2], nextNod[3],
+                                       prevNod[4], prevNod[5], prevNod[6], prevNod[7],
+                                       nextNod[4], nextNod[5], nextNod[6], nextNod[7],
+                                       midlNod[0], midlNod[1], midlNod[2], midlNod[3],
+                                       prevNod[8], // bottom center
+                                       midlNod[4], midlNod[5], midlNod[6], midlNod[7],
+                                       nextNod[8], // top center
+                                       midlNod[8]);// elem center
+        }
+        else
+        {
+          return;
+        }
         break;
       }
-      }
-    }
-
-    if(!aNewElem) {
-      // realized for extrusion only
-      vector<const SMDS_MeshNode*> polyedre_nodes (nbNodes*2 + 4*nbNodes);
-      vector<int> quantities (nbNodes + 2);
+      case SMDSEntity_Polygon: { // sweep POLYGON
 
-      quantities[0] = nbNodes; // bottom of prism
-      for (int inode = 0; inode < nbNodes; inode++) {
-        polyedre_nodes[inode] = prevNod[inode];
+        if ( nbNodes == 6 && nbSame == 0 && nbDouble == 0 ) {
+          // --->  hexagonal prism
+          aNewElem = aMesh->AddVolume (prevNod[0], prevNod[1], prevNod[2],
+                                       prevNod[3], prevNod[4], prevNod[5],
+                                       nextNod[0], nextNod[1], nextNod[2],
+                                       nextNod[3], nextNod[4], nextNod[5]);
+        }
+        break;
       }
+      case SMDSEntity_Ball:
+        return;
 
-      quantities[1] = nbNodes; // top of prism
-      for (int inode = 0; inode < nbNodes; inode++) {
-        polyedre_nodes[nbNodes + inode] = nextNod[inode];
+      default:
+        break;
       }
+    }
 
-      for (int iface = 0; iface < nbNodes; iface++) {
-        quantities[iface + 2] = 4;
-        int inextface = (iface == nbNodes - 1) ? 0 : iface + 1;
-        polyedre_nodes[2*nbNodes + 4*iface + 0] = prevNod[iface];
-        polyedre_nodes[2*nbNodes + 4*iface + 1] = prevNod[inextface];
-        polyedre_nodes[2*nbNodes + 4*iface + 2] = nextNod[inextface];
-        polyedre_nodes[2*nbNodes + 4*iface + 3] = nextNod[iface];
+    if ( !aNewElem && elem->GetType() == SMDSAbs_Face ) // try to create a polyherdal prism
+    {
+      if ( baseType != SMDSEntity_Polygon )
+      {
+        const std::vector<int>& ind = SMDS_MeshCell::interlacedSmdsOrder(baseType);
+        SMDS_MeshCell::applyInterlace( ind, prevNod );
+        SMDS_MeshCell::applyInterlace( ind, nextNod );
+        SMDS_MeshCell::applyInterlace( ind, midlNod );
+        SMDS_MeshCell::applyInterlace( ind, itNN );
+        SMDS_MeshCell::applyInterlace( ind, isSingleNode );
+        baseType = SMDSEntity_Polygon; // WARNING: change baseType !!!!
+      }
+      vector<const SMDS_MeshNode*> polyedre_nodes (nbNodes*2 + 4*nbNodes);
+      vector<int> quantities (nbNodes + 2);
+      polyedre_nodes.clear();
+      quantities.clear();
+
+      // bottom of prism
+      for (int inode = 0; inode < nbNodes; inode++)
+        polyedre_nodes.push_back( prevNod[inode] );
+      quantities.push_back( nbNodes );
+
+      // top of prism
+      polyedre_nodes.push_back( nextNod[0] );
+      for (int inode = nbNodes; inode-1; --inode )
+        polyedre_nodes.push_back( nextNod[inode-1] );
+      quantities.push_back( nbNodes );
+
+      // side faces
+      for (int iface = 0; iface < nbNodes; iface++)
+      {
+        const int prevNbNodes = polyedre_nodes.size();
+        int inextface = (iface+1) % nbNodes;
+        polyedre_nodes.push_back( prevNod[inextface] );
+        polyedre_nodes.push_back( prevNod[iface] );
+        if ( prevNod[iface] != nextNod[iface] )
+        {
+          if ( midlNod[ iface ]) polyedre_nodes.push_back( midlNod[ iface ]);
+          polyedre_nodes.push_back( nextNod[iface] );
+        }
+        if ( prevNod[inextface] != nextNod[inextface] )
+        {
+          polyedre_nodes.push_back( nextNod[inextface] );
+          if ( midlNod[ inextface ]) polyedre_nodes.push_back( midlNod[ inextface ]);
+        }
+        const int nbFaceNodes = polyedre_nodes.size() - prevNbNodes;
+        if ( nbFaceNodes > 2 )
+          quantities.push_back( nbFaceNodes );
+        else // degenerated face
+          polyedre_nodes.resize( prevNbNodes );
       }
       aNewElem = aMesh->AddPolyhedralVolume (polyedre_nodes, quantities);
     }
@@ -3094,7 +4027,8 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
   // Find nodes belonging to only one initial element - sweep them to get edges.
 
   TNodeOfNodeListMapItr nList = mapNewNodes.begin();
-  for ( ; nList != mapNewNodes.end(); nList++ ) {
+  for ( ; nList != mapNewNodes.end(); nList++ )
+  {
     const SMDS_MeshNode* node =
       static_cast<const SMDS_MeshNode*>( nList->first );
     SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator();
@@ -3109,11 +4043,10 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
         nbInitElems = 0;
         highType = type;
       }
-      if ( elemSet.find(el) != elemSet.end() )
-        nbInitElems++;
+      nbInitElems += elemSet.count(el);
     }
     if ( nbInitElems < 2 ) {
-      bool NotCreateEdge = el && el->IsQuadratic() && el->IsMediumNode(node);
+      bool NotCreateEdge = el && el->IsMediumNode(node);
       if(!NotCreateEdge) {
         vector<TNodeOfNodeListMapItr> newNodesItVec( 1, nList );
         list<const SMDS_MeshElement*> newEdges;
@@ -3127,13 +4060,18 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
 
   TElemOfElemListMap::iterator   itElem      = newElemsMap.begin();
   TElemOfVecOfNnlmiMap::iterator itElemNodes = elemNewNodesMap.begin();
-  for ( ; itElem != newElemsMap.end(); itElem++, itElemNodes++ ) {
+  for ( ; itElem != newElemsMap.end(); itElem++, itElemNodes++ )
+  {
     const SMDS_MeshElement* elem = itElem->first;
     vector<TNodeOfNodeListMapItr>& vecNewNodes = itElemNodes->second;
 
+    if(itElem->second.size()==0) continue;
+
+    const bool isQuadratic = elem->IsQuadratic();
+
     if ( elem->GetType() == SMDSAbs_Edge ) {
       // create a ceiling edge
-      if (!elem->IsQuadratic()) {
+      if ( !isQuadratic ) {
         if ( !aMesh->FindEdge( vecNewNodes[ 0 ]->second.back(),
                                vecNewNodes[ 1 ]->second.back())) {
           myLastCreatedElems.Append(aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(),
@@ -3155,8 +4093,6 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
     if ( elem->GetType() != SMDSAbs_Face )
       continue;
 
-    if(itElem->second.size()==0) continue;
-
     bool hasFreeLinks = false;
 
     TIDSortedElemSet avoidSet;
@@ -3164,7 +4100,7 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
 
     set<const SMDS_MeshNode*> aFaceLastNodes;
     int iNode, nbNodes = vecNewNodes.size();
-    if(!elem->IsQuadratic()) {
+    if ( !isQuadratic ) {
       // loop on the face nodes
       for ( iNode = 0; iNode < nbNodes; iNode++ ) {
         aFaceLastNodes.insert( vecNewNodes[ iNode ]->second.back() );
@@ -3196,12 +4132,14 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
         int iNext = ( iNode + 1 == nbn ) ? 0 : iNode + 1;
         const SMDS_MeshNode* n1 = vecNewNodes[ iNode ]->first;
         const SMDS_MeshNode* n2 = vecNewNodes[ iNext ]->first;
+        const SMDS_MeshNode* n3 = vecNewNodes[ iNode+nbn ]->first;
         // check if a link is free
-        if ( ! SMESH_MeshEditor::FindFaceInSet ( n1, n2, elemSet, avoidSet )) {
+        if ( ! SMESH_MeshEditor::FindFaceInSet ( n1, n2, elemSet, avoidSet ) &&
+             ! SMESH_MeshEditor::FindFaceInSet ( n1, n3, elemSet, avoidSet ) &&
+             ! SMESH_MeshEditor::FindFaceInSet ( n3, n2, elemSet, avoidSet ) ) {
           hasFreeLinks = true;
           // make an edge and a ceiling for a new edge
           // find medium node
-          const SMDS_MeshNode* n3 = vecNewNodes[ iNode+nbn ]->first;
           if ( !aMesh->FindEdge( n1, n2, n3 )) {
             myLastCreatedElems.Append(aMesh->AddEdge( n1, n2, n3 )); // free link edge
             srcElements.Append( myLastCreatedElems.Last() );
@@ -3215,7 +4153,7 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
           }
         }
       }
-      for ( iNode = nbn; iNode < 2*nbn; iNode++ ) {
+      for ( iNode = nbn; iNode < nbNodes; iNode++ ) {
         aFaceLastNodes.insert( vecNewNodes[ iNode ]->second.back() );
       }
     }
@@ -3233,12 +4171,11 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
       }
       for ( volNb = 0; volNb < nbVolumesByStep; volNb++ ) {
         list<const SMDS_MeshElement*>::iterator v = newVolumes.begin();
-        iVol = 0;
-        while ( iVol++ < volNb ) v++;
+        std::advance( v, volNb );
         // find indices of free faces of a volume and their source edges
         list< int > freeInd;
         list< const SMDS_MeshElement* > srcEdges; // source edges of free faces
-        SMDS_VolumeTool vTool( *v );
+        SMDS_VolumeTool vTool( *v, /*ignoreCentralNodes=*/false );
         int iF, nbF = vTool.NbFaces();
         for ( iF = 0; iF < nbF; iF ++ ) {
           if (vTool.IsFreeFace( iF ) &&
@@ -3273,62 +4210,137 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
         // create faces for all steps;
         // if such a face has been already created by sweep of edge,
         // assure that its orientation is OK
-        for ( int iStep = 0; iStep < nbSteps; iStep++ )  {
-          vTool.Set( *v );
+        for ( int iStep = 0; iStep < nbSteps; iStep++ ) {
+          vTool.Set( *v, /*ignoreCentralNodes=*/false );
           vTool.SetExternalNormal();
+          const int nextShift = vTool.IsForward() ? +1 : -1;
           list< int >::iterator ind = freeInd.begin();
           list< const SMDS_MeshElement* >::iterator srcEdge = srcEdges.begin();
           for ( ; ind != freeInd.end(); ++ind, ++srcEdge ) // loop on free faces
           {
             const SMDS_MeshNode** nodes = vTool.GetFaceNodes( *ind );
             int nbn = vTool.NbFaceNodes( *ind );
-            switch ( nbn ) {
-            case 3: { ///// triangle
-              const SMDS_MeshFace * f = aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ]);
-              if ( !f )
-                myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ));
-              else if ( nodes[ 1 ] != f->GetNode( f->GetNodeIndex( nodes[ 0 ] ) + 1 ))
-                aMesh->ChangeElementNodes( f, nodes, nbn );
-              break;
+            const SMDS_MeshElement * f = 0;
+            if ( nbn == 3 )              ///// triangle
+            {
+              f = aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ]);
+              if ( !f ||
+                   nodes[ 1 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ]) + nextShift ))
+              {
+                const SMDS_MeshNode* newOrder[3] = { nodes[ 1 - nextShift ],
+                                                     nodes[ 1 ],
+                                                     nodes[ 1 + nextShift ] };
+                if ( f )
+                  aMesh->ChangeElementNodes( f, &newOrder[0], nbn );
+                else
+                  myLastCreatedElems.Append(aMesh->AddFace( newOrder[ 0 ], newOrder[ 1 ],
+                                                            newOrder[ 2 ] ));
+              }
             }
-            case 4: { ///// quadrangle
-              const SMDS_MeshFace * f = aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ]);
-              if ( !f )
-                myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] ));
-              else if ( nodes[ 1 ] != f->GetNode( f->GetNodeIndex( nodes[ 0 ] ) + 1 ))
-                aMesh->ChangeElementNodes( f, nodes, nbn );
-              break;
+            else if ( nbn == 4 )       ///// quadrangle
+            {
+              f = aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ]);
+              if ( !f ||
+                   nodes[ 1 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ]) + nextShift ))
+              {
+                const SMDS_MeshNode* newOrder[4] = { nodes[ 0 ], nodes[ 2-nextShift ],
+                                                     nodes[ 2 ], nodes[ 2+nextShift ] };
+                if ( f )
+                  aMesh->ChangeElementNodes( f, &newOrder[0], nbn );
+                else
+                  myLastCreatedElems.Append(aMesh->AddFace( newOrder[ 0 ], newOrder[ 1 ],
+                                                            newOrder[ 2 ], newOrder[ 3 ]));
+              }
             }
-            default:
-              if( (*v)->IsQuadratic() ) {
-                if(nbn==6) { /////// quadratic triangle
-                  const SMDS_MeshFace * f = aMesh->FindFace( nodes[0], nodes[2], nodes[4],
-                                                             nodes[1], nodes[3], nodes[5] );
-                  if ( !f )
-                    myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4],
-                                                             nodes[1], nodes[3], nodes[5]));
-                  else if ( nodes[ 2 ] != f->GetNode( f->GetNodeIndex( nodes[ 0 ] ) + 1 ))
-                    aMesh->ChangeElementNodes( f, nodes, nbn );
-                }
-                else {       /////// quadratic quadrangle
-                  const SMDS_MeshFace * f = aMesh->FindFace( nodes[0], nodes[2], nodes[4], nodes[6],
-                                                             nodes[1], nodes[3], nodes[5], nodes[7] );
-                  if ( !f )
-                    myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6],
-                                                             nodes[1], nodes[3], nodes[5], nodes[7]));
-                  else if ( nodes[ 2 ] != f->GetNode( f->GetNodeIndex( nodes[ 0 ] ) + 1 ))
-                    aMesh->ChangeElementNodes( f, nodes, nbn );
-                }
+            else if ( nbn == 6 && isQuadratic ) /////// quadratic triangle
+            {
+              f = aMesh->FindFace( nodes[0], nodes[2], nodes[4], nodes[1], nodes[3], nodes[5] );
+              if ( !f ||
+                   nodes[2] != f->GetNodeWrap( f->GetNodeIndex( nodes[0] ) + 2*nextShift ))
+              {
+                const SMDS_MeshNode* newOrder[6] = { nodes[2 - 2*nextShift],
+                                                     nodes[2],
+                                                     nodes[2 + 2*nextShift],
+                                                     nodes[3 - 2*nextShift],
+                                                     nodes[3],
+                                                     nodes[3 + 2*nextShift]};
+                if ( f )
+                  aMesh->ChangeElementNodes( f, &newOrder[0], nbn );
+                else
+                  myLastCreatedElems.Append(aMesh->AddFace( newOrder[ 0 ],
+                                                            newOrder[ 1 ],
+                                                            newOrder[ 2 ],
+                                                            newOrder[ 3 ],
+                                                            newOrder[ 4 ],
+                                                            newOrder[ 5 ] ));
+              }
+            }
+            else if ( nbn == 8 && isQuadratic ) /////// quadratic quadrangle
+            {
+              f = aMesh->FindFace( nodes[0], nodes[2], nodes[4], nodes[6],
+                                   nodes[1], nodes[3], nodes[5], nodes[7] );
+              if ( !f ||
+                   nodes[ 2 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + 2*nextShift ))
+              {
+                const SMDS_MeshNode* newOrder[8] = { nodes[0],
+                                                     nodes[4 - 2*nextShift],
+                                                     nodes[4],
+                                                     nodes[4 + 2*nextShift],
+                                                     nodes[1],
+                                                     nodes[5 - 2*nextShift],
+                                                     nodes[5],
+                                                     nodes[5 + 2*nextShift] };
+                if ( f )
+                  aMesh->ChangeElementNodes( f, &newOrder[0], nbn );
+                else
+                  myLastCreatedElems.Append(aMesh->AddFace(newOrder[ 0 ], newOrder[ 1 ],
+                                                           newOrder[ 2 ], newOrder[ 3 ],
+                                                           newOrder[ 4 ], newOrder[ 5 ],
+                                                           newOrder[ 6 ], newOrder[ 7 ]));
+              }
+            }
+            else if ( nbn == 9 && isQuadratic ) /////// bi-quadratic quadrangle
+            {
+              f = aMesh->FindElement( vector<const SMDS_MeshNode*>( nodes, nodes+nbn ),
+                                      SMDSAbs_Face, /*noMedium=*/false);
+              if ( !f ||
+                   nodes[ 2 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + 2*nextShift ))
+              {
+                const SMDS_MeshNode* newOrder[9] = { nodes[0],
+                                                     nodes[4 - 2*nextShift],
+                                                     nodes[4],
+                                                     nodes[4 + 2*nextShift],
+                                                     nodes[1],
+                                                     nodes[5 - 2*nextShift],
+                                                     nodes[5],
+                                                     nodes[5 + 2*nextShift],
+                                                     nodes[8] };
+                if ( f )
+                  aMesh->ChangeElementNodes( f, &newOrder[0], nbn );
+                else
+                  myLastCreatedElems.Append(aMesh->AddFace(newOrder[ 0 ], newOrder[ 1 ],
+                                                           newOrder[ 2 ], newOrder[ 3 ],
+                                                           newOrder[ 4 ], newOrder[ 5 ],
+                                                           newOrder[ 6 ], newOrder[ 7 ],
+                                                           newOrder[ 8 ]));
               }
-              else { //////// polygon
-                vector<const SMDS_MeshNode*> polygon_nodes ( nodes, &nodes[nbn] );
-                const SMDS_MeshFace * f = aMesh->FindFace( polygon_nodes );
-                if ( !f )
-                  myLastCreatedElems.Append(aMesh->AddPolygonalFace(polygon_nodes));
-                else if ( nodes[ 1 ] != f->GetNode( f->GetNodeIndex( nodes[ 0 ] ) + 1 ))
-                  aMesh->ChangeElementNodes( f, nodes, nbn );
+            }
+            else  //////// polygon
+            {
+              vector<const SMDS_MeshNode*> polygon_nodes ( nodes, nodes+nbn );
+              const SMDS_MeshFace * f = aMesh->FindFace( polygon_nodes );
+              if ( !f ||
+                   nodes[ 1 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + nextShift ))
+              {
+                if ( !vTool.IsForward() )
+                  std::reverse( polygon_nodes.begin(), polygon_nodes.end());
+                if ( f )
+                  aMesh->ChangeElementNodes( f, &polygon_nodes[0], nbn );
+                else
+                  AddElement(polygon_nodes, SMDSAbs_Face, polygon_nodes.size()>4);
               }
             }
+
             while ( srcElements.Length() < myLastCreatedElems.Length() )
               srcElements.Append( *srcEdge );
 
@@ -3337,54 +4349,60 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
           // go to the next volume
           iVol = 0;
           while ( iVol++ < nbVolumesByStep ) v++;
-        }
-      }
+
+        } // loop on steps
+      } // loop on volumes of one step
     } // sweep free links into faces
 
     // Make a ceiling face with a normal external to a volume
 
-    SMDS_VolumeTool lastVol( itElem->second.back() );
+    SMDS_VolumeTool lastVol( itElem->second.back(), /*ignoreCentralNodes=*/false );
 
     int iF = lastVol.GetFaceIndex( aFaceLastNodes );
     if ( iF >= 0 ) {
       lastVol.SetExternalNormal();
       const SMDS_MeshNode** nodes = lastVol.GetFaceNodes( iF );
       int nbn = lastVol.NbFaceNodes( iF );
-      switch ( nbn ) {
-      case 3:
+      if ( nbn == 3 ) {
         if (!hasFreeLinks ||
             !aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ]))
           myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ));
-        break;
-      case 4:
+      }
+      else if ( nbn == 4 )
+      {
         if (!hasFreeLinks ||
             !aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ]))
-          myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] ));
-        break;
-      default:
-        if(itElem->second.back()->IsQuadratic()) {
-          if(nbn==6) {
-            if (!hasFreeLinks ||
-                !aMesh->FindFace(nodes[0], nodes[2], nodes[4],
-                                 nodes[1], nodes[3], nodes[5]) ) {
-              myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4],
-                                                       nodes[1], nodes[3], nodes[5]));
-            }
-          }
-          else { // nbn==8
-            if (!hasFreeLinks ||
-                !aMesh->FindFace(nodes[0], nodes[2], nodes[4], nodes[6],
-                                 nodes[1], nodes[3], nodes[5], nodes[7]) )
-              myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6],
-                                                       nodes[1], nodes[3], nodes[5], nodes[7]));
-          }
-        }
-        else {
-          vector<const SMDS_MeshNode*> polygon_nodes ( nodes, &nodes[nbn] );
-          if (!hasFreeLinks || !aMesh->FindFace(polygon_nodes))
-            myLastCreatedElems.Append(aMesh->AddPolygonalFace(polygon_nodes));
-        }
-      } // switch
+          myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ]));
+      }
+      else if ( nbn == 6 && isQuadratic )
+      {
+        if (!hasFreeLinks ||
+            !aMesh->FindFace(nodes[0], nodes[2], nodes[4], nodes[1], nodes[3], nodes[5]) )
+          myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4],
+                                                   nodes[1], nodes[3], nodes[5]));
+      }
+      else if ( nbn == 8 && isQuadratic )
+      {
+        if (!hasFreeLinks ||
+            !aMesh->FindFace(nodes[0], nodes[2], nodes[4], nodes[6],
+                             nodes[1], nodes[3], nodes[5], nodes[7]) )
+          myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6],
+                                                   nodes[1], nodes[3], nodes[5], nodes[7]));
+      }
+      else if ( nbn == 9 && isQuadratic )
+      {
+        if (!hasFreeLinks ||
+            !aMesh->FindElement(vector<const SMDS_MeshNode*>( nodes, nodes+nbn ),
+                                SMDSAbs_Face, /*noMedium=*/false) )
+          myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6],
+                                                   nodes[1], nodes[3], nodes[5], nodes[7],
+                                                   nodes[8]));
+      }
+      else {
+        vector<const SMDS_MeshNode*> polygon_nodes ( nodes, nodes + nbn );
+        if (!hasFreeLinks || !aMesh->FindFace(polygon_nodes))
+          myLastCreatedElems.Append(aMesh->AddPolygonalFace(polygon_nodes));
+      }
 
       while ( srcElements.Length() < myLastCreatedElems.Length() )
         srcElements.Append( myLastCreatedElems.Last() );
@@ -3427,6 +4445,9 @@ SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems,
   TElemOfVecOfNnlmiMap mapElemNewNodes;
   TElemOfElemListMap newElemsMap;
 
+  const bool isQuadraticMesh = bool( myMesh->NbEdges(ORDER_QUADRATIC) +
+                                     myMesh->NbFaces(ORDER_QUADRATIC) +
+                                     myMesh->NbVolumes(ORDER_QUADRATIC) );
   // loop on theElems
   TIDSortedElemSet::iterator itElem;
   for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
@@ -3442,64 +4463,58 @@ SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems,
     {
       // check if a node has been already sweeped
       const SMDS_MeshNode* node = cast2Node( itN->next() );
-      TNodeOfNodeListMapItr nIt = mapNewNodes.find( node );
-      if ( nIt == mapNewNodes.end() ) {
-        nIt = mapNewNodes.insert( make_pair( node, list<const SMDS_MeshNode*>() )).first;
-        list<const SMDS_MeshNode*>& listNewNodes = nIt->second;
+
+      gp_XYZ aXYZ( node->X(), node->Y(), node->Z() );
+      double coord[3];
+      aXYZ.Coord( coord[0], coord[1], coord[2] );
+      bool isOnAxis = ( aLine.SquareDistance( aXYZ ) <= aSqTol );
+
+      TNodeOfNodeListMapItr nIt =
+        mapNewNodes.insert( make_pair( node, list<const SMDS_MeshNode*>() )).first;
+      list<const SMDS_MeshNode*>& listNewNodes = nIt->second;
+      if ( listNewNodes.empty() )
+      {
+        // check if we are to create medium nodes between corner ones
+        bool needMediumNodes = false;
+        if ( isQuadraticMesh )
+        {
+          SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
+          while (it->more() && !needMediumNodes )
+          {
+            const SMDS_MeshElement* invElem = it->next();
+            if ( invElem != elem && !theElems.count( invElem )) continue;
+            needMediumNodes = ( invElem->IsQuadratic() && !invElem->IsMediumNode(node) );
+            if ( !needMediumNodes && invElem->GetEntityType() == SMDSEntity_BiQuad_Quadrangle )
+              needMediumNodes = true;
+          }
+        }
 
         // make new nodes
-        gp_XYZ aXYZ( node->X(), node->Y(), node->Z() );
-        double coord[3];
-        aXYZ.Coord( coord[0], coord[1], coord[2] );
-        bool isOnAxis = ( aLine.SquareDistance( aXYZ ) <= aSqTol );
         const SMDS_MeshNode * newNode = node;
         for ( int i = 0; i < theNbSteps; i++ ) {
           if ( !isOnAxis ) {
-            if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) {
-              // create two nodes
+            if ( needMediumNodes )  // create a medium node
+            {
               aTrsf2.Transforms( coord[0], coord[1], coord[2] );
-              //aTrsf.Transforms( coord[0], coord[1], coord[2] );
               newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
               myLastCreatedNodes.Append(newNode);
               srcNodes.Append( node );
               listNewNodes.push_back( newNode );
               aTrsf2.Transforms( coord[0], coord[1], coord[2] );
-              //aTrsf.Transforms( coord[0], coord[1], coord[2] );
             }
             else {
               aTrsf.Transforms( coord[0], coord[1], coord[2] );
             }
+            // create a corner node
             newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
             myLastCreatedNodes.Append(newNode);
             srcNodes.Append( node );
+            listNewNodes.push_back( newNode );
           }
-          listNewNodes.push_back( newNode );
-        }
-      }
-      else {
-        // if current elem is quadratic and current node is not medium
-        // we have to check - may be it is needed to insert additional nodes
-        if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) {
-          list< const SMDS_MeshNode* > & listNewNodes = nIt->second;
-          if(listNewNodes.size()==theNbSteps) {
-            listNewNodes.clear();
-            // make new nodes
-            gp_XYZ aXYZ( node->X(), node->Y(), node->Z() );
-            double coord[3];
-            aXYZ.Coord( coord[0], coord[1], coord[2] );
-            const SMDS_MeshNode * newNode = node;
-            for(int i = 0; i<theNbSteps; i++) {
-              aTrsf2.Transforms( coord[0], coord[1], coord[2] );
-              newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
-              myLastCreatedNodes.Append(newNode);
-              listNewNodes.push_back( newNode );
-              srcNodes.Append( node );
-              aTrsf2.Transforms( coord[0], coord[1], coord[2] );
-              newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
-              myLastCreatedNodes.Append(newNode);
-              srcNodes.Append( node );
-              listNewNodes.push_back( newNode );
-            }
+          else {
+            listNewNodes.push_back( newNode );
+            // if ( needMediumNodes )
+            //   listNewNodes.push_back( newNode );
           }
         }
       }
@@ -3511,7 +4526,7 @@ SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems,
 
   if ( theMakeWalls )
     makeWalls( mapNewNodes, newElemsMap, mapElemNewNodes, theElems, theNbSteps, srcElems );
-  
+
   PGroupIDs newGroupIDs;
   if ( theMakeGroups )
     newGroupIDs = generateGroups( srcNodes, srcElems, "rotated");
@@ -3530,8 +4545,8 @@ const SMDS_MeshNode* SMESH_MeshEditor::CreateNode(const double x,
                                                   const double tolnode,
                                                   SMESH_SequenceOfNode& aNodes)
 {
-  myLastCreatedElems.Clear();
-  myLastCreatedNodes.Clear();
+  // myLastCreatedElems.Clear();
+  // myLastCreatedNodes.Clear();
 
   gp_Pnt P1(x,y,z);
   SMESHDS_Mesh * aMesh = myMesh->GetMeshDS();
@@ -3559,7 +4574,7 @@ const SMDS_MeshNode* SMESH_MeshEditor::CreateNode(const double x,
 
   // create new node and return it
   const SMDS_MeshNode* NewNode = aMesh->AddNode(x,y,z);
-  myLastCreatedNodes.Append(NewNode);
+  //myLastCreatedNodes.Append(NewNode);
   return NewNode;
 }
 
@@ -3619,6 +4634,9 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet &  theElems,
   TElemOfVecOfNnlmiMap mapElemNewNodes;
   //TElemOfVecOfMapNodesMap mapElemNewNodes;
 
+  const bool isQuadraticMesh = bool( myMesh->NbEdges(ORDER_QUADRATIC) +
+                                     myMesh->NbFaces(ORDER_QUADRATIC) +
+                                     myMesh->NbVolumes(ORDER_QUADRATIC) );
   // loop on theElems
   TIDSortedElemSet::iterator itElem;
   for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
@@ -3628,7 +4646,6 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet &  theElems,
       continue;
 
     vector<TNodeOfNodeListMapItr> & newNodesItVec = mapElemNewNodes[ elem ];
-    //vector<TNodeOfNodeVecMapItr> & newNodesItVec = mapElemNewNodes[ elem ];
     newNodesItVec.reserve( elem->NbNodes() );
 
     // loop on elem nodes
@@ -3637,21 +4654,33 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet &  theElems,
     {
       // check if a node has been already sweeped
       const SMDS_MeshNode* node = cast2Node( itN->next() );
-      TNodeOfNodeListMap::iterator nIt = mapNewNodes.find( node );
-      //TNodeOfNodeVecMap::iterator nIt = mapNewNodes.find( node );
-      if ( nIt == mapNewNodes.end() ) {
-        nIt = mapNewNodes.insert( make_pair( node, list<const SMDS_MeshNode*>() )).first;
-        //nIt = mapNewNodes.insert( make_pair( node, vector<const SMDS_MeshNode*>() )).first;
-        list<const SMDS_MeshNode*>& listNewNodes = nIt->second;
-        //vector<const SMDS_MeshNode*>& vecNewNodes = nIt->second;
-        //vecNewNodes.reserve(nbsteps);
-
+      TNodeOfNodeListMap::iterator nIt =
+        mapNewNodes.insert( make_pair( node, list<const SMDS_MeshNode*>() )).first;
+      list<const SMDS_MeshNode*>& listNewNodes = nIt->second;
+      if ( listNewNodes.empty() )
+      {
         // make new nodes
-        double coord[] = { node->X(), node->Y(), node->Z() };
-        //int nbsteps = theParams.mySteps->Length();
-        for ( int i = 0; i < nbsteps; i++ ) {
-          if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) {
-            // create additional node
+
+        // check if we are to create medium nodes between corner ones
+        bool needMediumNodes = false;
+        if ( isQuadraticMesh )
+        {
+          SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
+          while (it->more() && !needMediumNodes )
+          {
+            const SMDS_MeshElement* invElem = it->next();
+            if ( invElem != elem && !theElems.count( invElem )) continue;
+            needMediumNodes = ( invElem->IsQuadratic() && !invElem->IsMediumNode(node) );
+            if ( !needMediumNodes && invElem->GetEntityType() == SMDSEntity_BiQuad_Quadrangle )
+              needMediumNodes = true;
+          }
+        }
+
+        double coord[] = { node->X(), node->Y(), node->Z() };
+        for ( int i = 0; i < nbsteps; i++ )
+        {
+          if ( needMediumNodes ) // create a medium node
+          {
             double x = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1)/2.;
             double y = coord[1] + theParams.myDir.Y()*theParams.mySteps->Value(i+1)/2.;
             double z = coord[2] + theParams.myDir.Z()*theParams.mySteps->Value(i+1)/2.;
@@ -3667,7 +4696,7 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet &  theElems,
               listNewNodes.push_back( newNode );
             }
           }
-          //aTrsf.Transforms( coord[0], coord[1], coord[2] );
+          // create a corner node
           coord[0] = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1);
           coord[1] = coord[1] + theParams.myDir.Y()*theParams.mySteps->Value(i+1);
           coord[2] = coord[2] + theParams.myDir.Z()*theParams.mySteps->Value(i+1);
@@ -3675,55 +4704,12 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet &  theElems,
             const SMDS_MeshNode * newNode = CreateNode(coord[0], coord[1], coord[2],
                                                        theTolerance, theParams.myNodes);
             listNewNodes.push_back( newNode );
-            //vecNewNodes[i]=newNode;
           }
           else {
             const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
             myLastCreatedNodes.Append(newNode);
             srcNodes.Append( node );
             listNewNodes.push_back( newNode );
-            //vecNewNodes[i]=newNode;
-          }
-        }
-      }
-      else {
-        // if current elem is quadratic and current node is not medium
-        // we have to check - may be it is needed to insert additional nodes
-        if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) {
-          list< const SMDS_MeshNode* > & listNewNodes = nIt->second;
-          if(listNewNodes.size()==nbsteps) {
-            listNewNodes.clear();
-            double coord[] = { node->X(), node->Y(), node->Z() };
-            for ( int i = 0; i < nbsteps; i++ ) {
-              double x = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1);
-              double y = coord[1] + theParams.myDir.Y()*theParams.mySteps->Value(i+1);
-              double z = coord[2] + theParams.myDir.Z()*theParams.mySteps->Value(i+1);
-              if( theFlags & EXTRUSION_FLAG_SEW ) {
-                const SMDS_MeshNode * newNode = CreateNode(x, y, z,
-                                                           theTolerance, theParams.myNodes);
-                listNewNodes.push_back( newNode );
-              }
-              else {
-                const SMDS_MeshNode * newNode = aMesh->AddNode(x, y, z);
-                myLastCreatedNodes.Append(newNode);
-                srcNodes.Append( node );
-                listNewNodes.push_back( newNode );
-              }
-              coord[0] = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1);
-              coord[1] = coord[1] + theParams.myDir.Y()*theParams.mySteps->Value(i+1);
-              coord[2] = coord[2] + theParams.myDir.Z()*theParams.mySteps->Value(i+1);
-              if( theFlags & EXTRUSION_FLAG_SEW ) {
-                const SMDS_MeshNode * newNode = CreateNode(coord[0], coord[1], coord[2],
-                                                           theTolerance, theParams.myNodes);
-                listNewNodes.push_back( newNode );
-              }
-              else {
-                const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
-                myLastCreatedNodes.Append(newNode);
-                srcNodes.Append( node );
-                listNewNodes.push_back( newNode );
-              }
-            }
           }
         }
       }
@@ -3743,82 +4729,30 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet &  theElems,
   return newGroupIDs;
 }
 
-
-//=======================================================================
-//class    : SMESH_MeshEditor_PathPoint
-//purpose  : auxiliary class
-//=======================================================================
-class SMESH_MeshEditor_PathPoint {
-public:
-  SMESH_MeshEditor_PathPoint() {
-    myPnt.SetCoord(99., 99., 99.);
-    myTgt.SetCoord(1.,0.,0.);
-    myAngle=0.;
-    myPrm=0.;
-  }
-  void SetPnt(const gp_Pnt& aP3D){
-    myPnt=aP3D;
-  }
-  void SetTangent(const gp_Dir& aTgt){
-    myTgt=aTgt;
-  }
-  void SetAngle(const double& aBeta){
-    myAngle=aBeta;
-  }
-  void SetParameter(const double& aPrm){
-    myPrm=aPrm;
-  }
-  const gp_Pnt& Pnt()const{
-    return myPnt;
-  }
-  const gp_Dir& Tangent()const{
-    return myTgt;
-  }
-  double Angle()const{
-    return myAngle;
-  }
-  double Parameter()const{
-    return myPrm;
-  }
-
-protected:
-  gp_Pnt myPnt;
-  gp_Dir myTgt;
-  double myAngle;
-  double myPrm;
-};
-
 //=======================================================================
 //function : ExtrusionAlongTrack
 //purpose  :
 //=======================================================================
 SMESH_MeshEditor::Extrusion_Error
-  SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet &   theElements,
-                                        SMESH_subMesh*       theTrack,
-                                        const SMDS_MeshNode* theN1,
-                                        const bool           theHasAngles,
-                                        list<double>&        theAngles,
-                                        const bool           theHasRefPoint,
-                                        const gp_Pnt&        theRefPoint,
-                                         const bool           theMakeGroups)
+SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet &   theElements,
+                                       SMESH_subMesh*       theTrack,
+                                       const SMDS_MeshNode* theN1,
+                                       const bool           theHasAngles,
+                                       list<double>&        theAngles,
+                                       const bool           theLinearVariation,
+                                       const bool           theHasRefPoint,
+                                       const gp_Pnt&        theRefPoint,
+                                       const bool           theMakeGroups)
 {
+  MESSAGE("ExtrusionAlongTrack");
   myLastCreatedElems.Clear();
   myLastCreatedNodes.Clear();
 
-  // source elements for each generated one
-  SMESH_SequenceOfElemPtr srcElems, srcNodes;
-
-  int j, aNbTP, aNbE, aNb;
-  double aT1, aT2, aT, aAngle, aX, aY, aZ;
+  int aNbE;
   std::list<double> aPrms;
-  std::list<double>::iterator aItD;
   TIDSortedElemSet::iterator itElem;
 
-  Standard_Real aTx1, aTx2, aL2, aTolVec, aTolVec2;
-  gp_Pnt aP3D, aV0;
-  gp_Vec aVec;
   gp_XYZ aGC;
-  Handle(Geom_Curve) aC3D;
   TopoDS_Edge aTrackEdge;
   TopoDS_Vertex aV1, aV2;
 
@@ -3827,11 +4761,6 @@ SMESH_MeshEditor::Extrusion_Error
   SMDSAbs_ElementType aTypeE;
 
   TNodeOfNodeListMap mapNewNodes;
-  TElemOfVecOfNnlmiMap mapElemNewNodes;
-  TElemOfElemListMap newElemsMap;
-
-  aTolVec=1.e-7;
-  aTolVec2=aTolVec*aTolVec;
 
   // 1. Check data
   aNbE = theElements.size();
@@ -3842,7 +4771,7 @@ SMESH_MeshEditor::Extrusion_Error
   // 1.1 Track Pattern
   ASSERT( theTrack );
 
-  SMESHDS_SubMesh* pSubMeshDS=theTrack->GetSubMeshDS();
+  SMESHDS_SubMesh* pSubMeshDS = theTrack->GetSubMeshDS();
 
   aItE = pSubMeshDS->GetElements();
   while ( aItE->more() ) {
@@ -3853,63 +4782,441 @@ SMESH_MeshEditor::Extrusion_Error
       return EXTR_PATH_NOT_EDGE;
   }
 
+  list<SMESH_MeshEditor_PathPoint> fullList;
+
   const TopoDS_Shape& aS = theTrack->GetSubShape();
-  // Sub shape for the Pattern must be an Edge
-  if ( aS.ShapeType() != TopAbs_EDGE )
+  // Sub-shape for the Pattern must be an Edge or Wire
+  if( aS.ShapeType() == TopAbs_EDGE ) {
+    aTrackEdge = TopoDS::Edge( aS );
+    // the Edge must not be degenerated
+    if ( BRep_Tool::Degenerated( aTrackEdge ) )
+      return EXTR_BAD_PATH_SHAPE;
+    TopExp::Vertices( aTrackEdge, aV1, aV2 );
+    aItN = theTrack->GetFather()->GetSubMesh( aV1 )->GetSubMeshDS()->GetNodes();
+    const SMDS_MeshNode* aN1 = aItN->next();
+    aItN = theTrack->GetFather()->GetSubMesh( aV2 )->GetSubMeshDS()->GetNodes();
+    const SMDS_MeshNode* aN2 = aItN->next();
+    // starting node must be aN1 or aN2
+    if ( !( aN1 == theN1 || aN2 == theN1 ) )
+      return EXTR_BAD_STARTING_NODE;
+    aItN = pSubMeshDS->GetNodes();
+    while ( aItN->more() ) {
+      const SMDS_MeshNode* pNode = aItN->next();
+      const SMDS_EdgePosition* pEPos =
+        static_cast<const SMDS_EdgePosition*>( pNode->GetPosition() );
+      double aT = pEPos->GetUParameter();
+      aPrms.push_back( aT );
+    }
+    //Extrusion_Error err =
+    MakeEdgePathPoints(aPrms, aTrackEdge, (aN1==theN1), fullList);
+  } else if( aS.ShapeType() == TopAbs_WIRE ) {
+    list< SMESH_subMesh* > LSM;
+    TopTools_SequenceOfShape Edges;
+    SMESH_subMeshIteratorPtr itSM = theTrack->getDependsOnIterator(false,true);
+    while(itSM->more()) {
+      SMESH_subMesh* SM = itSM->next();
+      LSM.push_back(SM);
+      const TopoDS_Shape& aS = SM->GetSubShape();
+      Edges.Append(aS);
+    }
+    list< list<SMESH_MeshEditor_PathPoint> > LLPPs;
+    int startNid = theN1->GetID();
+    TColStd_MapOfInteger UsedNums;
+    
+    int NbEdges = Edges.Length();
+    int i = 1;
+    for(; i<=NbEdges; i++) {
+      int k = 0;
+      list< SMESH_subMesh* >::iterator itLSM = LSM.begin();
+      for(; itLSM!=LSM.end(); itLSM++) {
+        k++;
+        if(UsedNums.Contains(k)) continue;
+        aTrackEdge = TopoDS::Edge( Edges.Value(k) );
+        SMESH_subMesh* locTrack = *itLSM;
+        SMESHDS_SubMesh* locMeshDS = locTrack->GetSubMeshDS();
+        TopExp::Vertices( aTrackEdge, aV1, aV2 );
+        aItN = locTrack->GetFather()->GetSubMesh(aV1)->GetSubMeshDS()->GetNodes();
+        const SMDS_MeshNode* aN1 = aItN->next();
+        aItN = locTrack->GetFather()->GetSubMesh(aV2)->GetSubMeshDS()->GetNodes();
+        const SMDS_MeshNode* aN2 = aItN->next();
+        // starting node must be aN1 or aN2
+        if ( !( aN1->GetID() == startNid || aN2->GetID() == startNid ) ) continue;
+        // 2. Collect parameters on the track edge
+        aPrms.clear();
+        aItN = locMeshDS->GetNodes();
+        while ( aItN->more() ) {
+          const SMDS_MeshNode* pNode = aItN->next();
+          const SMDS_EdgePosition* pEPos =
+            static_cast<const SMDS_EdgePosition*>( pNode->GetPosition() );
+          double aT = pEPos->GetUParameter();
+          aPrms.push_back( aT );
+        }
+        list<SMESH_MeshEditor_PathPoint> LPP;
+        //Extrusion_Error err =
+        MakeEdgePathPoints(aPrms, aTrackEdge,(aN1->GetID()==startNid), LPP);
+        LLPPs.push_back(LPP);
+        UsedNums.Add(k);
+        // update startN for search following egde
+        if( aN1->GetID() == startNid ) startNid = aN2->GetID();
+        else startNid = aN1->GetID();
+        break;
+      }
+    }
+    list< list<SMESH_MeshEditor_PathPoint> >::iterator itLLPP = LLPPs.begin();
+    list<SMESH_MeshEditor_PathPoint> firstList = *itLLPP;
+    list<SMESH_MeshEditor_PathPoint>::iterator itPP = firstList.begin();
+    for(; itPP!=firstList.end(); itPP++) {
+      fullList.push_back( *itPP );
+    }
+    SMESH_MeshEditor_PathPoint PP1 = fullList.back();
+    fullList.pop_back();
+    itLLPP++;
+    for(; itLLPP!=LLPPs.end(); itLLPP++) {
+      list<SMESH_MeshEditor_PathPoint> currList = *itLLPP;
+      itPP = currList.begin();
+      SMESH_MeshEditor_PathPoint PP2 = currList.front();
+      gp_Dir D1 = PP1.Tangent();
+      gp_Dir D2 = PP2.Tangent();
+      gp_Dir Dnew( gp_Vec( (D1.X()+D2.X())/2, (D1.Y()+D2.Y())/2,
+                           (D1.Z()+D2.Z())/2 ) );
+      PP1.SetTangent(Dnew);
+      fullList.push_back(PP1);
+      itPP++;
+      for(; itPP!=firstList.end(); itPP++) {
+        fullList.push_back( *itPP );
+      }
+      PP1 = fullList.back();
+      fullList.pop_back();
+    }
+    // if wire not closed
+    fullList.push_back(PP1);
+    // else ???
+  }
+  else {
     return EXTR_BAD_PATH_SHAPE;
+  }
 
-  aTrackEdge = TopoDS::Edge( aS );
-  // the Edge must not be degenerated
-  if ( BRep_Tool::Degenerated( aTrackEdge ) )
-    return EXTR_BAD_PATH_SHAPE;
+  return MakeExtrElements(theElements, fullList, theHasAngles, theAngles, theLinearVariation,
+                          theHasRefPoint, theRefPoint, theMakeGroups);
+}
 
-  TopExp::Vertices( aTrackEdge, aV1, aV2 );
-  aT1=BRep_Tool::Parameter( aV1, aTrackEdge );
-  aT2=BRep_Tool::Parameter( aV2, aTrackEdge );
 
-  aItN = theTrack->GetFather()->GetSubMesh( aV1 )->GetSubMeshDS()->GetNodes();
-  const SMDS_MeshNode* aN1 = aItN->next();
+//=======================================================================
+//function : ExtrusionAlongTrack
+//purpose  :
+//=======================================================================
+SMESH_MeshEditor::Extrusion_Error
+SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet &   theElements,
+                                       SMESH_Mesh*          theTrack,
+                                       const SMDS_MeshNode* theN1,
+                                       const bool           theHasAngles,
+                                       list<double>&        theAngles,
+                                       const bool           theLinearVariation,
+                                       const bool           theHasRefPoint,
+                                       const gp_Pnt&        theRefPoint,
+                                       const bool           theMakeGroups)
+{
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
+
+  int aNbE;
+  std::list<double> aPrms;
+  TIDSortedElemSet::iterator itElem;
+
+  gp_XYZ aGC;
+  TopoDS_Edge aTrackEdge;
+  TopoDS_Vertex aV1, aV2;
+
+  SMDS_ElemIteratorPtr aItE;
+  SMDS_NodeIteratorPtr aItN;
+  SMDSAbs_ElementType aTypeE;
 
-  aItN = theTrack->GetFather()->GetSubMesh( aV2 )->GetSubMeshDS()->GetNodes();
-  const SMDS_MeshNode* aN2 = aItN->next();
+  TNodeOfNodeListMap mapNewNodes;
 
-  // starting node must be aN1 or aN2
-  if ( !( aN1 == theN1 || aN2 == theN1 ) )
-    return EXTR_BAD_STARTING_NODE;
+  // 1. Check data
+  aNbE = theElements.size();
+  // nothing to do
+  if ( !aNbE )
+    return EXTR_NO_ELEMENTS;
 
-  aNbTP = pSubMeshDS->NbNodes() + 2;
+  // 1.1 Track Pattern
+  ASSERT( theTrack );
 
-  // 1.2. Angles
-  vector<double> aAngles( aNbTP );
+  SMESHDS_Mesh* pMeshDS = theTrack->GetMeshDS();
 
-  for ( j=0; j < aNbTP; ++j ) {
-    aAngles[j] = 0.;
+  aItE = pMeshDS->elementsIterator();
+  while ( aItE->more() ) {
+    const SMDS_MeshElement* pE = aItE->next();
+    aTypeE = pE->GetType();
+    // Pattern must contain links only
+    if ( aTypeE != SMDSAbs_Edge )
+      return EXTR_PATH_NOT_EDGE;
   }
 
-  if ( theHasAngles ) {
-    aItD = theAngles.begin();
-    for ( j=1; (aItD != theAngles.end()) && (j<aNbTP); ++aItD, ++j ) {
-      aAngle = *aItD;
-      aAngles[j] = aAngle;
+  list<SMESH_MeshEditor_PathPoint> fullList;
+
+  const TopoDS_Shape& aS = theTrack->GetShapeToMesh();
+
+  if( aS == SMESH_Mesh::PseudoShape() ) {
+    //Mesh without shape
+    const SMDS_MeshNode* currentNode = NULL;
+    const SMDS_MeshNode* prevNode = theN1;
+    std::vector<const SMDS_MeshNode*> aNodesList;
+    aNodesList.push_back(theN1);
+    int nbEdges = 0, conn=0;
+    const SMDS_MeshElement* prevElem = NULL;
+    const SMDS_MeshElement* currentElem = NULL;
+    int totalNbEdges = theTrack->NbEdges();
+    SMDS_ElemIteratorPtr nIt;
+
+    //check start node
+    if( !theTrack->GetMeshDS()->Contains(theN1) ) {
+      return EXTR_BAD_STARTING_NODE;
+    }
+    
+    conn = nbEdgeConnectivity(theN1);
+    if(conn > 2)
+      return EXTR_PATH_NOT_EDGE;
+
+    aItE = theN1->GetInverseElementIterator();
+    prevElem = aItE->next();
+    currentElem = prevElem;
+    //Get all nodes
+    if(totalNbEdges == 1 ) {
+      nIt = currentElem->nodesIterator();
+      currentNode = static_cast<const SMDS_MeshNode*>(nIt->next());
+      if(currentNode == prevNode)
+        currentNode = static_cast<const SMDS_MeshNode*>(nIt->next());
+      aNodesList.push_back(currentNode);
+    } else { 
+      nIt = currentElem->nodesIterator();
+      while( nIt->more() ) {
+        currentNode = static_cast<const SMDS_MeshNode*>(nIt->next());
+        if(currentNode == prevNode)
+          currentNode = static_cast<const SMDS_MeshNode*>(nIt->next());
+        aNodesList.push_back(currentNode);
+        
+        //case of the closed mesh
+        if(currentNode == theN1) {
+          nbEdges++;
+          break;
+        }
+
+        conn = nbEdgeConnectivity(currentNode);
+        if(conn > 2) {
+          return EXTR_PATH_NOT_EDGE;    
+        }else if( conn == 1 && nbEdges > 0 ) {
+          //End of the path
+          nbEdges++;
+          break;
+        }else {
+          prevNode = currentNode;
+          aItE = currentNode->GetInverseElementIterator();
+          currentElem = aItE->next();
+          if( currentElem  == prevElem)
+            currentElem = aItE->next();
+          nIt = currentElem->nodesIterator();
+          prevElem = currentElem;
+          nbEdges++;
+        }
+      }
+    } 
+    
+    if(nbEdges != totalNbEdges)
+      return EXTR_PATH_NOT_EDGE;
+
+    TopTools_SequenceOfShape Edges;
+    double x1,x2,y1,y2,z1,z2;
+    list< list<SMESH_MeshEditor_PathPoint> > LLPPs;
+    int startNid = theN1->GetID();
+    for(int i = 1; i < aNodesList.size(); i++) {
+      x1 = aNodesList[i-1]->X();x2 = aNodesList[i]->X();
+      y1 = aNodesList[i-1]->Y();y2 = aNodesList[i]->Y();
+      z1 = aNodesList[i-1]->Z();z2 = aNodesList[i]->Z();
+      TopoDS_Edge e = BRepBuilderAPI_MakeEdge(gp_Pnt(x1,y1,z1),gp_Pnt(x2,y2,z2));  
+      list<SMESH_MeshEditor_PathPoint> LPP;
+      aPrms.clear();
+      MakeEdgePathPoints(aPrms, e, (aNodesList[i-1]->GetID()==startNid), LPP);
+      LLPPs.push_back(LPP);
+      if( aNodesList[i-1]->GetID() == startNid ) startNid = aNodesList[i]->GetID();
+      else startNid = aNodesList[i-1]->GetID();
+
+    }
+
+    list< list<SMESH_MeshEditor_PathPoint> >::iterator itLLPP = LLPPs.begin();
+    list<SMESH_MeshEditor_PathPoint> firstList = *itLLPP;
+    list<SMESH_MeshEditor_PathPoint>::iterator itPP = firstList.begin();
+    for(; itPP!=firstList.end(); itPP++) {
+      fullList.push_back( *itPP );
+    }
+
+    SMESH_MeshEditor_PathPoint PP1 = fullList.back();
+    SMESH_MeshEditor_PathPoint PP2;
+    fullList.pop_back();
+    itLLPP++;
+    for(; itLLPP!=LLPPs.end(); itLLPP++) {
+      list<SMESH_MeshEditor_PathPoint> currList = *itLLPP;
+      itPP = currList.begin();
+      PP2 = currList.front();
+      gp_Dir D1 = PP1.Tangent();
+      gp_Dir D2 = PP2.Tangent();
+      gp_Dir Dnew( gp_Vec( (D1.X()+D2.X())/2, (D1.Y()+D2.Y())/2,
+                           (D1.Z()+D2.Z())/2 ) );
+      PP1.SetTangent(Dnew);
+      fullList.push_back(PP1);
+      itPP++;
+      for(; itPP!=currList.end(); itPP++) {
+        fullList.push_back( *itPP );
+      }
+      PP1 = fullList.back();
+      fullList.pop_back();
+    }
+    fullList.push_back(PP1);
+    
+  } // Sub-shape for the Pattern must be an Edge or Wire
+  else if( aS.ShapeType() == TopAbs_EDGE ) {
+    aTrackEdge = TopoDS::Edge( aS );
+    // the Edge must not be degenerated
+    if ( BRep_Tool::Degenerated( aTrackEdge ) )
+      return EXTR_BAD_PATH_SHAPE;
+    TopExp::Vertices( aTrackEdge, aV1, aV2 );
+    aItN = theTrack->GetSubMesh( aV1 )->GetSubMeshDS()->GetNodes();
+    const SMDS_MeshNode* aN1 = aItN->next();
+    aItN = theTrack->GetSubMesh( aV2 )->GetSubMeshDS()->GetNodes();
+    const SMDS_MeshNode* aN2 = aItN->next();
+    // starting node must be aN1 or aN2
+    if ( !( aN1 == theN1 || aN2 == theN1 ) )
+      return EXTR_BAD_STARTING_NODE;
+    aItN = pMeshDS->nodesIterator();
+    while ( aItN->more() ) {
+      const SMDS_MeshNode* pNode = aItN->next();
+      if( pNode==aN1 || pNode==aN2 ) continue;
+      const SMDS_EdgePosition* pEPos =
+        static_cast<const SMDS_EdgePosition*>( pNode->GetPosition() );
+      double aT = pEPos->GetUParameter();
+      aPrms.push_back( aT );
+    }
+    //Extrusion_Error err =
+    MakeEdgePathPoints(aPrms, aTrackEdge, (aN1==theN1), fullList);
+  }
+  else if( aS.ShapeType() == TopAbs_WIRE ) {
+    list< SMESH_subMesh* > LSM;
+    TopTools_SequenceOfShape Edges;
+    TopExp_Explorer eExp(aS, TopAbs_EDGE);
+    for(; eExp.More(); eExp.Next()) {
+      TopoDS_Edge E = TopoDS::Edge( eExp.Current() );
+      if( BRep_Tool::Degenerated(E) ) continue;
+      SMESH_subMesh* SM = theTrack->GetSubMesh(E);
+      if(SM) {
+        LSM.push_back(SM);
+        Edges.Append(E);
+      }
+    }
+    list< list<SMESH_MeshEditor_PathPoint> > LLPPs;
+    int startNid = theN1->GetID();
+    TColStd_MapOfInteger UsedNums;
+    int NbEdges = Edges.Length();
+    int i = 1;
+    for(; i<=NbEdges; i++) {
+      int k = 0;
+      list< SMESH_subMesh* >::iterator itLSM = LSM.begin();
+      for(; itLSM!=LSM.end(); itLSM++) {
+        k++;
+        if(UsedNums.Contains(k)) continue;
+        aTrackEdge = TopoDS::Edge( Edges.Value(k) );
+        SMESH_subMesh* locTrack = *itLSM;
+        SMESHDS_SubMesh* locMeshDS = locTrack->GetSubMeshDS();
+        TopExp::Vertices( aTrackEdge, aV1, aV2 );
+        aItN = locTrack->GetFather()->GetSubMesh(aV1)->GetSubMeshDS()->GetNodes();
+        const SMDS_MeshNode* aN1 = aItN->next();
+        aItN = locTrack->GetFather()->GetSubMesh(aV2)->GetSubMeshDS()->GetNodes();
+        const SMDS_MeshNode* aN2 = aItN->next();
+        // starting node must be aN1 or aN2
+        if ( !( aN1->GetID() == startNid || aN2->GetID() == startNid ) ) continue;
+        // 2. Collect parameters on the track edge
+        aPrms.clear();
+        aItN = locMeshDS->GetNodes();
+        while ( aItN->more() ) {
+          const SMDS_MeshNode* pNode = aItN->next();
+          const SMDS_EdgePosition* pEPos =
+            static_cast<const SMDS_EdgePosition*>( pNode->GetPosition() );
+          double aT = pEPos->GetUParameter();
+          aPrms.push_back( aT );
+        }
+        list<SMESH_MeshEditor_PathPoint> LPP;
+        //Extrusion_Error err =
+        MakeEdgePathPoints(aPrms, aTrackEdge,(aN1->GetID()==startNid), LPP);
+        LLPPs.push_back(LPP);
+        UsedNums.Add(k);
+        // update startN for search following egde
+        if( aN1->GetID() == startNid ) startNid = aN2->GetID();
+        else startNid = aN1->GetID();
+        break;
+      }
     }
+    list< list<SMESH_MeshEditor_PathPoint> >::iterator itLLPP = LLPPs.begin();
+    list<SMESH_MeshEditor_PathPoint> firstList = *itLLPP;
+    list<SMESH_MeshEditor_PathPoint>::iterator itPP = firstList.begin();
+    for(; itPP!=firstList.end(); itPP++) {
+      fullList.push_back( *itPP );
+    }
+    SMESH_MeshEditor_PathPoint PP1 = fullList.back();
+    fullList.pop_back();
+    itLLPP++;
+    for(; itLLPP!=LLPPs.end(); itLLPP++) {
+      list<SMESH_MeshEditor_PathPoint> currList = *itLLPP;
+      itPP = currList.begin();
+      SMESH_MeshEditor_PathPoint PP2 = currList.front();
+      gp_Dir D1 = PP1.Tangent();
+      gp_Dir D2 = PP2.Tangent();
+      gp_Dir Dnew( gp_Vec( (D1.X()+D2.X())/2, (D1.Y()+D2.Y())/2,
+                           (D1.Z()+D2.Z())/2 ) );
+      PP1.SetTangent(Dnew);
+      fullList.push_back(PP1);
+      itPP++;
+      for(; itPP!=currList.end(); itPP++) {
+        fullList.push_back( *itPP );
+      }
+      PP1 = fullList.back();
+      fullList.pop_back();
+    }
+    // if wire not closed
+    fullList.push_back(PP1);
+    // else ???
+  }
+  else {
+    return EXTR_BAD_PATH_SHAPE;
   }
 
-  // 2. Collect parameters on the track edge
-  aPrms.push_back( aT1 );
-  aPrms.push_back( aT2 );
+  return MakeExtrElements(theElements, fullList, theHasAngles, theAngles, theLinearVariation,
+                          theHasRefPoint, theRefPoint, theMakeGroups);
+}
 
-  aItN = pSubMeshDS->GetNodes();
-  while ( aItN->more() ) {
-    const SMDS_MeshNode* pNode = aItN->next();
-    const SMDS_EdgePosition* pEPos =
-      static_cast<const SMDS_EdgePosition*>( pNode->GetPosition().get() );
-    aT = pEPos->GetUParameter();
-    aPrms.push_back( aT );
-  }
 
+//=======================================================================
+//function : MakeEdgePathPoints
+//purpose  : auxilary for ExtrusionAlongTrack
+//=======================================================================
+SMESH_MeshEditor::Extrusion_Error
+SMESH_MeshEditor::MakeEdgePathPoints(std::list<double>& aPrms,
+                                     const TopoDS_Edge& aTrackEdge,
+                                     bool FirstIsStart,
+                                     list<SMESH_MeshEditor_PathPoint>& LPP)
+{
+  Standard_Real aTx1, aTx2, aL2, aTolVec, aTolVec2;
+  aTolVec=1.e-7;
+  aTolVec2=aTolVec*aTolVec;
+  double aT1, aT2;
+  TopoDS_Vertex aV1, aV2;
+  TopExp::Vertices( aTrackEdge, aV1, aV2 );
+  aT1=BRep_Tool::Parameter( aV1, aTrackEdge );
+  aT2=BRep_Tool::Parameter( aV2, aTrackEdge );
+  // 2. Collect parameters on the track edge
+  aPrms.push_front( aT1 );
+  aPrms.push_back( aT2 );
   // sort parameters
   aPrms.sort();
-  if ( aN1 == theN1 ) {
+  if( FirstIsStart ) {
     if ( aT1 > aT2 ) {
       aPrms.reverse();
     }
@@ -3919,33 +5226,87 @@ SMESH_MeshEditor::Extrusion_Error
       aPrms.reverse();
     }
   }
-
   // 3. Path Points
   SMESH_MeshEditor_PathPoint aPP;
-  vector<SMESH_MeshEditor_PathPoint> aPPs( aNbTP );
-  //
-  aC3D = BRep_Tool::Curve( aTrackEdge, aTx1, aTx2 );
-  //
-  aItD = aPrms.begin();
-  for ( j=0; aItD != aPrms.end(); ++aItD, ++j ) {
-    aT = *aItD;
+  Handle(Geom_Curve) aC3D = BRep_Tool::Curve( aTrackEdge, aTx1, aTx2 );
+  std::list<double>::iterator aItD = aPrms.begin();
+  for(; aItD != aPrms.end(); ++aItD) {
+    double aT = *aItD;
+    gp_Pnt aP3D;
+    gp_Vec aVec;
     aC3D->D1( aT, aP3D, aVec );
     aL2 = aVec.SquareMagnitude();
     if ( aL2 < aTolVec2 )
       return EXTR_CANT_GET_TANGENT;
-
     gp_Dir aTgt( aVec );
-    aAngle = aAngles[j];
-
     aPP.SetPnt( aP3D );
     aPP.SetTangent( aTgt );
-    aPP.SetAngle( aAngle );
     aPP.SetParameter( aT );
-    aPPs[j]=aPP;
+    LPP.push_back(aPP);
+  }
+  return EXTR_OK;
+}
+
+
+//=======================================================================
+//function : MakeExtrElements
+//purpose  : auxilary for ExtrusionAlongTrack
+//=======================================================================
+SMESH_MeshEditor::Extrusion_Error
+SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet&  theElements,
+                                   list<SMESH_MeshEditor_PathPoint>& fullList,
+                                   const bool theHasAngles,
+                                   list<double>& theAngles,
+                                   const bool theLinearVariation,
+                                   const bool theHasRefPoint,
+                                   const gp_Pnt& theRefPoint,
+                                   const bool theMakeGroups)
+{
+  MESSAGE("MakeExtrElements");
+  //cout<<"MakeExtrElements  fullList.size() = "<<fullList.size()<<endl;
+  int aNbTP = fullList.size();
+  vector<SMESH_MeshEditor_PathPoint> aPPs(aNbTP);
+  // Angles
+  if( theHasAngles && theAngles.size()>0 && theLinearVariation ) {
+    LinearAngleVariation(aNbTP-1, theAngles);
+  }
+  vector<double> aAngles( aNbTP );
+  int j = 0;
+  for(; j<aNbTP; ++j) {
+    aAngles[j] = 0.;
+  }
+  if ( theHasAngles ) {
+    double anAngle;;
+    std::list<double>::iterator aItD = theAngles.begin();
+    for ( j=1; (aItD != theAngles.end()) && (j<aNbTP); ++aItD, ++j ) {
+      anAngle = *aItD;
+      aAngles[j] = anAngle;
+    }
+  }
+  // fill vector of path points with angles
+  //aPPs.resize(fullList.size());
+  j = -1;
+  list<SMESH_MeshEditor_PathPoint>::iterator itPP = fullList.begin();
+  for(; itPP!=fullList.end(); itPP++) {
+    j++;
+    SMESH_MeshEditor_PathPoint PP = *itPP;
+    PP.SetAngle(aAngles[j]);
+    aPPs[j] = PP;
   }
 
+  TNodeOfNodeListMap mapNewNodes;
+  TElemOfVecOfNnlmiMap mapElemNewNodes;
+  TElemOfElemListMap newElemsMap;
+  TIDSortedElemSet::iterator itElem;
+  double aX, aY, aZ;
+  int aNb;
+  SMDSAbs_ElementType aTypeE;
+  // source elements for each generated one
+  SMESH_SequenceOfElemPtr srcElems, srcNodes;
+
   // 3. Center of rotation aV0
-  aV0 = theRefPoint;
+  gp_Pnt aV0 = theRefPoint;
+  gp_XYZ aGC;
   if ( !theHasRefPoint ) {
     aNb = 0;
     aGC.SetCoord( 0.,0.,0. );
@@ -3956,19 +5317,19 @@ SMESH_MeshEditor::Extrusion_Error
 
       SMDS_ElemIteratorPtr itN = elem->nodesIterator();
       while ( itN->more() ) {
-       const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( itN->next() );
-       aX = node->X();
-       aY = node->Y();
-       aZ = node->Z();
-
-       if ( mapNewNodes.find( node ) == mapNewNodes.end() ) {
-         list<const SMDS_MeshNode*> aLNx;
-         mapNewNodes[node] = aLNx;
-         //
-         gp_XYZ aXYZ( aX, aY, aZ );
-         aGC += aXYZ;
-         ++aNb;
-       }
+        const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( itN->next() );
+        aX = node->X();
+        aY = node->Y();
+        aZ = node->Z();
+
+        if ( mapNewNodes.find( node ) == mapNewNodes.end() ) {
+          list<const SMDS_MeshNode*> aLNx;
+          mapNewNodes[node] = aLNx;
+          //
+          gp_XYZ aXYZ( aX, aY, aZ );
+          aGC += aXYZ;
+          ++aNb;
+        }
       }
     }
     aGC /= aNb;
@@ -3997,65 +5358,67 @@ SMESH_MeshEditor::Extrusion_Error
       ++nodeIndex;
       // check if a node has been already processed
       const SMDS_MeshNode* node =
-       static_cast<const SMDS_MeshNode*>( itN->next() );
+        static_cast<const SMDS_MeshNode*>( itN->next() );
       TNodeOfNodeListMap::iterator nIt = mapNewNodes.find( node );
       if ( nIt == mapNewNodes.end() ) {
         nIt = mapNewNodes.insert( make_pair( node, list<const SMDS_MeshNode*>() )).first;
         list<const SMDS_MeshNode*>& listNewNodes = nIt->second;
 
-       // make new nodes
-       aX = node->X();  aY = node->Y(); aZ = node->Z();
-
-       Standard_Real aAngle1x, aAngleT1T0, aTolAng;
-       gp_Pnt aP0x, aP1x, aPN0, aPN1, aV0x, aV1x;
-       gp_Ax1 anAx1, anAxT1T0;
-       gp_Dir aDT1x, aDT0x, aDT1T0;
-
-       aTolAng=1.e-4;
-
-       aV0x = aV0;
-       aPN0.SetCoord(aX, aY, aZ);
-
-       const SMESH_MeshEditor_PathPoint& aPP0 = aPPs[0];
-       aP0x = aPP0.Pnt();
-       aDT0x= aPP0.Tangent();
-
-       for ( j = 1; j < aNbTP; ++j ) {
-         const SMESH_MeshEditor_PathPoint& aPP1 = aPPs[j];
-         aP1x = aPP1.Pnt();
-         aDT1x = aPP1.Tangent();
-         aAngle1x = aPP1.Angle();
-
-         gp_Trsf aTrsf, aTrsfRot, aTrsfRotT1T0;
-         // Translation
-         gp_Vec aV01x( aP0x, aP1x );
-         aTrsf.SetTranslation( aV01x );
-
-         // traslated point
-         aV1x = aV0x.Transformed( aTrsf );
-         aPN1 = aPN0.Transformed( aTrsf );
-
-         // rotation 1 [ T1,T0 ]
-         aAngleT1T0=-aDT1x.Angle( aDT0x );
-         if (fabs(aAngleT1T0) > aTolAng) {
-           aDT1T0=aDT1x^aDT0x;
-           anAxT1T0.SetLocation( aV1x );
-           anAxT1T0.SetDirection( aDT1T0 );
-           aTrsfRotT1T0.SetRotation( anAxT1T0, aAngleT1T0 );
-
-           aPN1 = aPN1.Transformed( aTrsfRotT1T0 );
-         }
+        // make new nodes
+        aX = node->X();  aY = node->Y(); aZ = node->Z();
+
+        Standard_Real aAngle1x, aAngleT1T0, aTolAng;
+        gp_Pnt aP0x, aP1x, aPN0, aPN1, aV0x, aV1x;
+        gp_Ax1 anAx1, anAxT1T0;
+        gp_Dir aDT1x, aDT0x, aDT1T0;
+
+        aTolAng=1.e-4;
+
+        aV0x = aV0;
+        aPN0.SetCoord(aX, aY, aZ);
+
+        const SMESH_MeshEditor_PathPoint& aPP0 = aPPs[0];
+        aP0x = aPP0.Pnt();
+        aDT0x= aPP0.Tangent();
+        //cout<<"j = 0   PP: Pnt("<<aP0x.X()<<","<<aP0x.Y()<<","<<aP0x.Z()<<")"<<endl;
+
+        for ( j = 1; j < aNbTP; ++j ) {
+          const SMESH_MeshEditor_PathPoint& aPP1 = aPPs[j];
+          aP1x = aPP1.Pnt();
+          aDT1x = aPP1.Tangent();
+          aAngle1x = aPP1.Angle();
+
+          gp_Trsf aTrsf, aTrsfRot, aTrsfRotT1T0;
+          // Translation
+          gp_Vec aV01x( aP0x, aP1x );
+          aTrsf.SetTranslation( aV01x );
+
+          // traslated point
+          aV1x = aV0x.Transformed( aTrsf );
+          aPN1 = aPN0.Transformed( aTrsf );
+
+          // rotation 1 [ T1,T0 ]
+          aAngleT1T0=-aDT1x.Angle( aDT0x );
+          if (fabs(aAngleT1T0) > aTolAng) {
+            aDT1T0=aDT1x^aDT0x;
+            anAxT1T0.SetLocation( aV1x );
+            anAxT1T0.SetDirection( aDT1T0 );
+            aTrsfRotT1T0.SetRotation( anAxT1T0, aAngleT1T0 );
+
+            aPN1 = aPN1.Transformed( aTrsfRotT1T0 );
+          }
 
-         // rotation 2
-         if ( theHasAngles ) {
-           anAx1.SetLocation( aV1x );
-           anAx1.SetDirection( aDT1x );
-           aTrsfRot.SetRotation( anAx1, aAngle1x );
+          // rotation 2
+          if ( theHasAngles ) {
+            anAx1.SetLocation( aV1x );
+            anAx1.SetDirection( aDT1x );
+            aTrsfRot.SetRotation( anAx1, aAngle1x );
 
-           aPN1 = aPN1.Transformed( aTrsfRot );
-         }
+            aPN1 = aPN1.Transformed( aTrsfRot );
+          }
 
-         // make new node
+          // make new node
+          //MESSAGE("elem->IsQuadratic " << elem->IsQuadratic() << " " << elem->IsMediumNode(node));
           if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) {
             // create additional node
             double x = ( aPN1.X() + aPN0.X() )/2.;
@@ -4066,19 +5429,19 @@ SMESH_MeshEditor::Extrusion_Error
             srcNodes.Append( node );
             listNewNodes.push_back( newNode );
           }
-         aX = aPN1.X();
-         aY = aPN1.Y();
-         aZ = aPN1.Z();
-         const SMDS_MeshNode* newNode = aMesh->AddNode( aX, aY, aZ );
+          aX = aPN1.X();
+          aY = aPN1.Y();
+          aZ = aPN1.Z();
+          const SMDS_MeshNode* newNode = aMesh->AddNode( aX, aY, aZ );
           myLastCreatedNodes.Append(newNode);
           srcNodes.Append( node );
-         listNewNodes.push_back( newNode );
+          listNewNodes.push_back( newNode );
 
-         aPN0 = aPN1;
-         aP0x = aP1x;
-         aV0x = aV1x;
-         aDT0x = aDT1x;
-       }
+          aPN0 = aPN1;
+          aP0x = aP1x;
+          aV0x = aV1x;
+          aDT0x = aDT1x;
+        }
       }
 
       else {
@@ -4127,10 +5490,67 @@ SMESH_MeshEditor::Extrusion_Error
   return EXTR_OK;
 }
 
+
 //=======================================================================
-//function : Transform
-//purpose  :
+//function : LinearAngleVariation
+//purpose  : auxilary for ExtrusionAlongTrack
 //=======================================================================
+void SMESH_MeshEditor::LinearAngleVariation(const int nbSteps,
+                                            list<double>& Angles)
+{
+  int nbAngles = Angles.size();
+  if( nbSteps > nbAngles ) {
+    vector<double> theAngles(nbAngles);
+    list<double>::iterator it = Angles.begin();
+    int i = -1;
+    for(; it!=Angles.end(); it++) {
+      i++;
+      theAngles[i] = (*it);
+    }
+    list<double> res;
+    double rAn2St = double( nbAngles ) / double( nbSteps );
+    double angPrev = 0, angle;
+    for ( int iSt = 0; iSt < nbSteps; ++iSt ) {
+      double angCur = rAn2St * ( iSt+1 );
+      double angCurFloor  = floor( angCur );
+      double angPrevFloor = floor( angPrev );
+      if ( angPrevFloor == angCurFloor )
+        angle = rAn2St * theAngles[ int( angCurFloor ) ];
+      else {
+        int iP = int( angPrevFloor );
+        double angPrevCeil = ceil(angPrev);
+        angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
+
+        int iC = int( angCurFloor );
+        if ( iC < nbAngles )
+          angle += ( angCur - angCurFloor ) * theAngles[ iC ];
+
+        iP = int( angPrevCeil );
+        while ( iC-- > iP )
+          angle += theAngles[ iC ];
+      }
+      res.push_back(angle);
+      angPrev = angCur;
+    }
+    Angles.clear();
+    it = res.begin();
+    for(; it!=res.end(); it++)
+      Angles.push_back( *it );
+  }
+}
+
+
+//================================================================================
+/*!
+ * \brief Move or copy theElements applying theTrsf to their nodes
+ *  \param theElems - elements to transform, if theElems is empty then apply to all mesh nodes
+ *  \param theTrsf - transformation to apply
+ *  \param theCopy - if true, create translated copies of theElems
+ *  \param theMakeGroups - if true and theCopy, create translated groups
+ *  \param theTargetMesh - mesh to copy translated elements into
+ *  \return SMESH_MeshEditor::PGroupIDs - list of ids of created groups
+ */
+//================================================================================
 
 SMESH_MeshEditor::PGroupIDs
 SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
@@ -4146,21 +5566,37 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
   string groupPostfix;
   switch ( theTrsf.Form() ) {
   case gp_PntMirror:
+    MESSAGE("gp_PntMirror");
+    needReverse = true;
+    groupPostfix = "mirrored";
+    break;
   case gp_Ax1Mirror:
+    MESSAGE("gp_Ax1Mirror");
+    groupPostfix = "mirrored";
+    break;
   case gp_Ax2Mirror:
+    MESSAGE("gp_Ax2Mirror");
     needReverse = true;
     groupPostfix = "mirrored";
     break;
   case gp_Rotation:
+    MESSAGE("gp_Rotation");
     groupPostfix = "rotated";
     break;
   case gp_Translation:
+    MESSAGE("gp_Translation");
     groupPostfix = "translated";
     break;
   case gp_Scale:
+    MESSAGE("gp_Scale");
+    groupPostfix = "scaled";
+    break;
+  case gp_CompoundTrsf: // different scale by axis
+    MESSAGE("gp_CompoundTrsf");
     groupPostfix = "scaled";
     break;
   default:
+    MESSAGE("default");
     needReverse = false;
     groupPostfix = "transformed";
   }
@@ -4168,7 +5604,7 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
   SMESH_MeshEditor targetMeshEditor( theTargetMesh );
   SMESHDS_Mesh* aTgtMesh = theTargetMesh ? theTargetMesh->GetMeshDS() : 0;
   SMESHDS_Mesh* aMesh    = GetMeshDS();
-  
+
 
   // map old node to new one
   TNodeNodeMap nodeMap;
@@ -4180,9 +5616,29 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
   // source elements for each generated one
   SMESH_SequenceOfElemPtr srcElems, srcNodes;
 
-  // loop on theElems
+  // issue 021015: EDF 1578 SMESH: Free nodes are removed when translating a mesh
+  TIDSortedElemSet orphanNode;
+
+  if ( theElems.empty() ) // transform the whole mesh
+  {
+    // add all elements
+    SMDS_ElemIteratorPtr eIt = aMesh->elementsIterator();
+    while ( eIt->more() ) theElems.insert( eIt->next() );
+    // add orphan nodes
+    SMDS_NodeIteratorPtr nIt = aMesh->nodesIterator();
+    while ( nIt->more() )
+    {
+      const SMDS_MeshNode* node = nIt->next();
+      if ( node->NbInverseElements() == 0)
+        orphanNode.insert( node );
+    }
+  }
+
+  // loop on elements to transform nodes : first orphan nodes then elems
   TIDSortedElemSet::iterator itElem;
-  for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
+  TIDSortedElemSet *elements[] = {&orphanNode, &theElems };
+  for (int i=0; i<2; i++)
+  for ( itElem = elements[i]->begin(); itElem != elements[i]->end(); itElem++ ) {
     const SMDS_MeshElement* elem = *itElem;
     if ( !elem )
       continue;
@@ -4191,8 +5647,8 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
     SMDS_ElemIteratorPtr itN = elem->nodesIterator();
     while ( itN->more() ) {
 
-      // check if a node has been already transformed
       const SMDS_MeshNode* node = cast2Node( itN->next() );
+      // check if a node has been already transformed
       pair<TNodeNodeMap::iterator,bool> n2n_isnew =
         nodeMap.insert( make_pair ( node, node ));
       if ( !n2n_isnew.second )
@@ -4241,203 +5697,167 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
   for ( ; invElemIt != inverseElemSet.end(); invElemIt++ )
     theElems.insert( *invElemIt );
 
-  // replicate or reverse elements
-
-  enum {
-    REV_TETRA   = 0,  //  = nbNodes - 4
-    REV_PYRAMID = 1,  //  = nbNodes - 4
-    REV_PENTA   = 2,  //  = nbNodes - 4
-    REV_FACE    = 3,
-    REV_HEXA    = 4,  //  = nbNodes - 4
-    FORWARD     = 5
-    };
-  int index[][8] = {
-    { 2, 1, 0, 3, 4, 0, 0, 0 },  // REV_TETRA
-    { 2, 1, 0, 3, 4, 0, 0, 0 },  // REV_PYRAMID
-    { 2, 1, 0, 5, 4, 3, 0, 0 },  // REV_PENTA
-    { 2, 1, 0, 3, 0, 0, 0, 0 },  // REV_FACE
-    { 2, 1, 0, 3, 6, 5, 4, 7 },  // REV_HEXA
-    { 0, 1, 2, 3, 4, 5, 6, 7 }   // FORWARD
-  };
+  // Replicate or reverse elements
 
+  std::vector<int> iForw;
   for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
   {
     const SMDS_MeshElement* elem = *itElem;
-    if ( !elem || elem->GetType() == SMDSAbs_Node )
-      continue;
+    if ( !elem ) continue;
 
-    int nbNodes = elem->NbNodes();
-    int elemType = elem->GetType();
+    SMDSAbs_GeometryType geomType = elem->GetGeomType();
+    int                  nbNodes  = elem->NbNodes();
+    if ( geomType == SMDSGeom_POINT ) continue; // node
 
-    if (elem->IsPoly()) {
-      // Polygon or Polyhedral Volume
-      switch ( elemType ) {
-      case SMDSAbs_Face:
-        {
-          vector<const SMDS_MeshNode*> poly_nodes (nbNodes);
-          int iNode = 0;
-          SMDS_ElemIteratorPtr itN = elem->nodesIterator();
-          while (itN->more()) {
-            const SMDS_MeshNode* node =
-              static_cast<const SMDS_MeshNode*>(itN->next());
-            TNodeNodeMap::iterator nodeMapIt = nodeMap.find(node);
-            if (nodeMapIt == nodeMap.end())
-              break; // not all nodes transformed
-            if (needReverse) {
-              // reverse mirrored faces and volumes
-              poly_nodes[nbNodes - iNode - 1] = (*nodeMapIt).second;
-            } else {
-              poly_nodes[iNode] = (*nodeMapIt).second;
-            }
-            iNode++;
-          }
-          if ( iNode != nbNodes )
-            continue; // not all nodes transformed
+    switch ( geomType ) {
 
-          if ( theTargetMesh ) {
-            myLastCreatedElems.Append(aTgtMesh->AddPolygonalFace(poly_nodes));
-            srcElems.Append( elem );
-          }
-          else if ( theCopy ) {
-            myLastCreatedElems.Append(aMesh->AddPolygonalFace(poly_nodes));
-            srcElems.Append( elem );
-          }
-          else {
-            aMesh->ChangePolygonNodes(elem, poly_nodes);
+    case SMDSGeom_POLYGON:  // ---------------------- polygon
+      {
+        vector<const SMDS_MeshNode*> poly_nodes (nbNodes);
+        int iNode = 0;
+        SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+        while (itN->more()) {
+          const SMDS_MeshNode* node =
+            static_cast<const SMDS_MeshNode*>(itN->next());
+          TNodeNodeMap::iterator nodeMapIt = nodeMap.find(node);
+          if (nodeMapIt == nodeMap.end())
+            break; // not all nodes transformed
+          if (needReverse) {
+            // reverse mirrored faces and volumes
+            poly_nodes[nbNodes - iNode - 1] = (*nodeMapIt).second;
+          } else {
+            poly_nodes[iNode] = (*nodeMapIt).second;
           }
+          iNode++;
         }
-        break;
-      case SMDSAbs_Volume:
-        {
-          // ATTENTION: Reversing is not yet done!!!
-          const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
-            dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>( elem );
-          if (!aPolyedre) {
-            MESSAGE("Warning: bad volumic element");
-            continue;
-          }
+        if ( iNode != nbNodes )
+          continue; // not all nodes transformed
 
-          vector<const SMDS_MeshNode*> poly_nodes;
-          vector<int> quantities;
+        if ( theTargetMesh ) {
+          myLastCreatedElems.Append(aTgtMesh->AddPolygonalFace(poly_nodes));
+          srcElems.Append( elem );
+        }
+        else if ( theCopy ) {
+          myLastCreatedElems.Append(aMesh->AddPolygonalFace(poly_nodes));
+          srcElems.Append( elem );
+        }
+        else {
+          aMesh->ChangePolygonNodes(elem, poly_nodes);
+        }
+      }
+      break;
 
-          bool allTransformed = true;
-          int nbFaces = aPolyedre->NbFaces();
-          for (int iface = 1; iface <= nbFaces && allTransformed; iface++) {
-            int nbFaceNodes = aPolyedre->NbFaceNodes(iface);
-            for (int inode = 1; inode <= nbFaceNodes && allTransformed; inode++) {
-              const SMDS_MeshNode* node = aPolyedre->GetFaceNode(iface, inode);
-              TNodeNodeMap::iterator nodeMapIt = nodeMap.find(node);
-              if (nodeMapIt == nodeMap.end()) {
-                allTransformed = false; // not all nodes transformed
-              } else {
-                poly_nodes.push_back((*nodeMapIt).second);
-              }
+    case SMDSGeom_POLYHEDRA:  // ------------------ polyhedral volume
+      {
+        const SMDS_VtkVolume* aPolyedre =
+          dynamic_cast<const SMDS_VtkVolume*>( elem );
+        if (!aPolyedre) {
+          MESSAGE("Warning: bad volumic element");
+          continue;
+        }
+
+        vector<const SMDS_MeshNode*> poly_nodes; poly_nodes.reserve( nbNodes );
+        vector<int> quantities; quantities.reserve( nbNodes );
+
+        bool allTransformed = true;
+        int nbFaces = aPolyedre->NbFaces();
+        for (int iface = 1; iface <= nbFaces && allTransformed; iface++) {
+          int nbFaceNodes = aPolyedre->NbFaceNodes(iface);
+          for (int inode = 1; inode <= nbFaceNodes && allTransformed; inode++) {
+            const SMDS_MeshNode* node = aPolyedre->GetFaceNode(iface, inode);
+            TNodeNodeMap::iterator nodeMapIt = nodeMap.find(node);
+            if (nodeMapIt == nodeMap.end()) {
+              allTransformed = false; // not all nodes transformed
+            } else {
+              poly_nodes.push_back((*nodeMapIt).second);
             }
-            quantities.push_back(nbFaceNodes);
+            if ( needReverse && allTransformed )
+              std::reverse( poly_nodes.end() - nbFaceNodes, poly_nodes.end() );
           }
-          if ( !allTransformed )
-            continue; // not all nodes transformed
+          quantities.push_back(nbFaceNodes);
+        }
+        if ( !allTransformed )
+          continue; // not all nodes transformed
 
-          if ( theTargetMesh ) {
-            myLastCreatedElems.Append(aTgtMesh->AddPolyhedralVolume(poly_nodes, quantities));
-            srcElems.Append( elem );
-          }
-          else if ( theCopy ) {
-            myLastCreatedElems.Append(aMesh->AddPolyhedralVolume(poly_nodes, quantities));
-            srcElems.Append( elem );
-          }
-          else {
-            aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities);
-          }
-        }
-        break;
-    default:;
-    }
-    continue;
-  }
-
-  // Regular elements
-  int* i = index[ FORWARD ];
-  if ( needReverse && nbNodes > 2) // reverse mirrored faces and volumes
-    if ( elemType == SMDSAbs_Face )
-      i = index[ REV_FACE ];
-    else
-      i = index[ nbNodes - 4 ];
-
-    if(elem->IsQuadratic()) {
-      static int anIds[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
-      i = anIds;
-      if(needReverse) {
-        if(nbNodes==3) { // quadratic edge
-          static int anIds[] = {1,0,2};
-          i = anIds;
+        if ( theTargetMesh ) {
+          myLastCreatedElems.Append(aTgtMesh->AddPolyhedralVolume(poly_nodes, quantities));
+          srcElems.Append( elem );
         }
-        else if(nbNodes==6) { // quadratic triangle
-          static int anIds[] = {0,2,1,5,4,3};
-          i = anIds;
+        else if ( theCopy ) {
+          myLastCreatedElems.Append(aMesh->AddPolyhedralVolume(poly_nodes, quantities));
+          srcElems.Append( elem );
         }
-        else if(nbNodes==8) { // quadratic quadrangle
-          static int anIds[] = {0,3,2,1,7,6,5,4};
-          i = anIds;
-        }
-        else if(nbNodes==10) { // quadratic tetrahedron of 10 nodes
-          static int anIds[] = {0,2,1,3,6,5,4,7,9,8};
-          i = anIds;
-        }
-        else if(nbNodes==13) { // quadratic pyramid of 13 nodes
-          static int anIds[] = {0,3,2,1,4,8,7,6,5,9,12,11,10};
-          i = anIds;
+        else {
+          aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities);
         }
-        else if(nbNodes==15) { // quadratic pentahedron with 15 nodes
-          static int anIds[] = {0,2,1,3,5,4,8,7,6,11,10,9,12,14,13};
-          i = anIds;
+      }
+      break;
+
+    case SMDSGeom_BALL: // -------------------- Ball
+      {
+        if ( !theCopy && !theTargetMesh ) continue;
+
+        TNodeNodeMap::iterator nodeMapIt = nodeMap.find( elem->GetNode(0) );
+        if (nodeMapIt == nodeMap.end())
+          continue; // not all nodes transformed
+
+        double diameter = static_cast<const SMDS_BallElement*>(elem)->GetDiameter();
+        if ( theTargetMesh ) {
+          myLastCreatedElems.Append(aTgtMesh->AddBall( nodeMapIt->second, diameter ));
+          srcElems.Append( elem );
         }
-        else { // nbNodes==20 - quadratic hexahedron with 20 nodes
-          static int anIds[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17};
-          i = anIds;
+        else {
+          myLastCreatedElems.Append(aMesh->AddBall( nodeMapIt->second, diameter ));
+          srcElems.Append( elem );
         }
       }
-    }
+      break;
 
-    // find transformed nodes
-    vector<const SMDS_MeshNode*> nodes(nbNodes);
-    int iNode = 0;
-    SMDS_ElemIteratorPtr itN = elem->nodesIterator();
-    while ( itN->more() ) {
-      const SMDS_MeshNode* node =
-        static_cast<const SMDS_MeshNode*>( itN->next() );
-      TNodeNodeMap::iterator nodeMapIt = nodeMap.find( node );
-      if ( nodeMapIt == nodeMap.end() )
-        break; // not all nodes transformed
-      nodes[ i [ iNode++ ]] = (*nodeMapIt).second;
-    }
-    if ( iNode != nbNodes )
-      continue; // not all nodes transformed
+    default: // ----------------------- Regular elements
+
+      while ( iForw.size() < nbNodes ) iForw.push_back( iForw.size() );
+      const std::vector<int>& iRev = SMDS_MeshCell::reverseSmdsOrder( elem->GetEntityType() );
+      const std::vector<int>& i = needReverse ? iRev : iForw;
+
+      // find transformed nodes
+      vector<const SMDS_MeshNode*> nodes(nbNodes);
+      int iNode = 0;
+      SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+      while ( itN->more() ) {
+        const SMDS_MeshNode* node =
+          static_cast<const SMDS_MeshNode*>( itN->next() );
+        TNodeNodeMap::iterator nodeMapIt = nodeMap.find( node );
+        if ( nodeMapIt == nodeMap.end() )
+          break; // not all nodes transformed
+        nodes[ i [ iNode++ ]] = (*nodeMapIt).second;
+      }
+      if ( iNode != nbNodes )
+        continue; // not all nodes transformed
 
-    if ( theTargetMesh ) {
-      if ( SMDS_MeshElement* copy =
-           targetMeshEditor.AddElement( nodes, elem->GetType(), elem->IsPoly() )) {
-        myLastCreatedElems.Append( copy );
-        srcElems.Append( elem );
+      if ( theTargetMesh ) {
+        if ( SMDS_MeshElement* copy =
+             targetMeshEditor.AddElement( nodes, elem->GetType(), elem->IsPoly() )) {
+          myLastCreatedElems.Append( copy );
+          srcElems.Append( elem );
+        }
       }
-    }
-    else if ( theCopy ) {
-      if ( SMDS_MeshElement* copy = AddElement( nodes, elem->GetType(), elem->IsPoly() )) {
-        myLastCreatedElems.Append( copy );
-        srcElems.Append( elem );
+      else if ( theCopy ) {
+        if ( AddElement( nodes, elem->GetType(), elem->IsPoly() ))
+          srcElems.Append( elem );
       }
-    }
-    else {
-      // reverse element as it was reversed by transformation
-      if ( nbNodes > 2 )
-        aMesh->ChangeElementNodes( elem, &nodes[0], nbNodes );
-    }
-  }
+      else {
+        // reverse element as it was reversed by transformation
+        if ( nbNodes > 2 )
+          aMesh->ChangeElementNodes( elem, &nodes[0], nbNodes );
+      }
+    } // switch ( geomType )
+
+  } // loop on elements
 
   PGroupIDs newGroupIDs;
 
-  if ( theMakeGroups && theCopy ||
-       theMakeGroups && theTargetMesh )
+  if ( ( theMakeGroups && theCopy ) ||
+       ( theMakeGroups && theTargetMesh ) )
     newGroupIDs = generateGroups( srcNodes, srcElems, groupPostfix, theTargetMesh );
 
   return newGroupIDs;
@@ -4515,9 +5935,9 @@ SMESH_MeshEditor::generateGroups(const SMESH_SequenceOfElemPtr& nodeGens,
           if ( resElem != sourceElem )
             resultElems.push_back( resElem );
       // do not generate element groups from node ones
-      if ( sourceElem->GetType() == SMDSAbs_Node &&
-           elems( iElem )->GetType() != SMDSAbs_Node )
-        continue;
+//      if ( sourceElem->GetType() == SMDSAbs_Node &&
+//           elems( iElem )->GetType() != SMDSAbs_Node )
+//        continue;
 
       // add resultElems to groups made by ones the sourceElem belongs to
       list< TOldNewGroup >::iterator gOldNew, gLast = groupsOldNew.end();
@@ -4569,33 +5989,32 @@ SMESH_MeshEditor::generateGroups(const SMESH_SequenceOfElemPtr& nodeGens,
   return newGroupIDs;
 }
 
-//=======================================================================
-//function : FindCoincidentNodes
-//purpose  : Return list of group of nodes close to each other within theTolerance
-//           Search among theNodes or in the whole mesh if theNodes is empty using
-//           an Octree algorithm
-//=======================================================================
+//================================================================================
+/*!
+ * \brief Return list of group of nodes close to each other within theTolerance
+ *        Search among theNodes or in the whole mesh if theNodes is empty using
+ *        an Octree algorithm
+ */
+//================================================================================
 
-void SMESH_MeshEditor::FindCoincidentNodes (set<const SMDS_MeshNode*> & theNodes,
-                                            const double                theTolerance,
-                                            TListOfListOfNodes &        theGroupsOfNodes)
+void SMESH_MeshEditor::FindCoincidentNodes (TIDSortedNodeSet &   theNodes,
+                                            const double         theTolerance,
+                                            TListOfListOfNodes & theGroupsOfNodes)
 {
   myLastCreatedElems.Clear();
   myLastCreatedNodes.Clear();
 
-  set<const SMDS_MeshNode*> nodes;
   if ( theNodes.empty() )
   { // get all nodes in the mesh
-    SMDS_NodeIteratorPtr nIt = GetMeshDS()->nodesIterator();
+    SMDS_NodeIteratorPtr nIt = GetMeshDS()->nodesIterator(/*idInceasingOrder=*/true);
     while ( nIt->more() )
-      nodes.insert( nodes.end(),nIt->next());
+      theNodes.insert( theNodes.end(),nIt->next());
   }
-  else
-    nodes=theNodes;
-  SMESH_OctreeNode::FindCoincidentNodes ( nodes, &theGroupsOfNodes, theTolerance);
 
+  SMESH_OctreeNode::FindCoincidentNodes ( theNodes, &theGroupsOfNodes, theTolerance);
 }
 
+
 //=======================================================================
 /*!
  * \brief Implementation of search for the node closest to point
@@ -4604,31 +6023,57 @@ void SMESH_MeshEditor::FindCoincidentNodes (set<const SMDS_MeshNode*> & theNodes
 
 struct SMESH_NodeSearcherImpl: public SMESH_NodeSearcher
 {
+  //---------------------------------------------------------------------
   /*!
    * \brief Constructor
    */
   SMESH_NodeSearcherImpl( const SMESHDS_Mesh* theMesh )
   {
-    set<const SMDS_MeshNode*> nodes;
+    myMesh = ( SMESHDS_Mesh* ) theMesh;
+
+    TIDSortedNodeSet nodes;
     if ( theMesh ) {
-      SMDS_NodeIteratorPtr nIt = theMesh->nodesIterator();
+      SMDS_NodeIteratorPtr nIt = theMesh->nodesIterator(/*idInceasingOrder=*/true);
       while ( nIt->more() )
         nodes.insert( nodes.end(), nIt->next() );
     }
     myOctreeNode = new SMESH_OctreeNode(nodes) ;
+
+    // get max size of a leaf box
+    SMESH_OctreeNode* tree = myOctreeNode;
+    while ( !tree->isLeaf() )
+    {
+      SMESH_OctreeNodeIteratorPtr cIt = tree->GetChildrenIterator();
+      if ( cIt->more() )
+        tree = cIt->next();
+    }
+    myHalfLeafSize = tree->maxSize() / 2.;
+  }
+
+  //---------------------------------------------------------------------
+  /*!
+   * \brief Move node and update myOctreeNode accordingly
+   */
+  void MoveNode( const SMDS_MeshNode* node, const gp_Pnt& toPnt )
+  {
+    myOctreeNode->UpdateByMoveNode( node, toPnt );
+    myMesh->MoveNode( node, toPnt.X(), toPnt.Y(), toPnt.Z() );
   }
+
+  //---------------------------------------------------------------------
   /*!
    * \brief Do it's job
    */
   const SMDS_MeshNode* FindClosestTo( const gp_Pnt& thePnt )
   {
-    SMDS_MeshNode tgtNode( thePnt.X(), thePnt.Y(), thePnt.Z() );
+    map<double, const SMDS_MeshNode*> dist2Nodes;
+    myOctreeNode->NodesAround( thePnt.Coord(), dist2Nodes, myHalfLeafSize );
+    if ( !dist2Nodes.empty() )
+      return dist2Nodes.begin()->second;
     list<const SMDS_MeshNode*> nodes;
-    const double precision = 1e-6;
-    myOctreeNode->NodesAround( &tgtNode, &nodes, precision );
+    //myOctreeNode->NodesAround( &tgtNode, &nodes, myHalfLeafSize );
 
     double minSqDist = DBL_MAX;
-    Bnd_B3d box;
     if ( nodes.empty() )  // get all nodes of OctreeNode's closest to thePnt
     {
       // sort leafs by their distance from thePnt
@@ -4637,20 +6082,26 @@ struct SMESH_NodeSearcherImpl: public SMESH_NodeSearcher
       list< SMESH_OctreeNode* > treeList;
       list< SMESH_OctreeNode* >::iterator trIt;
       treeList.push_back( myOctreeNode );
+
+      gp_XYZ pointNode( thePnt.X(), thePnt.Y(), thePnt.Z() );
+      bool pointInside = myOctreeNode->isInside( pointNode, myHalfLeafSize );
       for ( trIt = treeList.begin(); trIt != treeList.end(); ++trIt)
       {
         SMESH_OctreeNode* tree = *trIt;
-        if ( !tree->isLeaf() ) { // put children to the queue
+        if ( !tree->isLeaf() ) // put children to the queue
+        {
+          if ( pointInside && !tree->isInside( pointNode, myHalfLeafSize )) continue;
           SMESH_OctreeNodeIteratorPtr cIt = tree->GetChildrenIterator();
           while ( cIt->more() )
             treeList.push_back( cIt->next() );
         }
-        else if ( tree->NbNodes() ) { // put tree to treeMap
-          tree->getBox( box );
+        else if ( tree->NbNodes() ) // put a tree to the treeMap
+        {
+          const Bnd_B3d& box = tree->getBox();
           double sqDist = thePnt.SquareDistance( 0.5 * ( box.CornerMin() + box.CornerMax() ));
           pair<TDistTreeMap::iterator,bool> it_in = treeMap.insert( make_pair( sqDist, tree ));
           if ( !it_in.second ) // not unique distance to box center
-            treeMap.insert( it_in.first, make_pair( sqDist - 1e-13*treeMap.size(), tree ));
+            treeMap.insert( it_in.first, make_pair( sqDist + 1e-13*treeMap.size(), tree ));
         }
       }
       // find distance after which there is no sense to check tree's
@@ -4658,7 +6109,7 @@ struct SMESH_NodeSearcherImpl: public SMESH_NodeSearcher
       TDistTreeMap::iterator sqDist_tree = treeMap.begin();
       if ( treeMap.size() > 5 ) {
         SMESH_OctreeNode* closestTree = sqDist_tree->second;
-        closestTree->getBox( box );
+        const Bnd_B3d& box = closestTree->getBox();
         double limit = sqrt( sqDist_tree->first ) + sqrt ( box.SquareExtent() );
         sqLimit = limit * limit;
       }
@@ -4675,7 +6126,7 @@ struct SMESH_NodeSearcherImpl: public SMESH_NodeSearcher
     const SMDS_MeshNode* closestNode = 0;
     list<const SMDS_MeshNode*>::iterator nIt = nodes.begin();
     for ( ; nIt != nodes.end(); ++nIt ) {
-      double sqDist = thePnt.SquareDistance( TNodeXYZ( *nIt ) );
+      double sqDist = thePnt.SquareDistance( SMESH_TNodeXYZ( *nIt ) );
       if ( minSqDist > sqDist ) {
         closestNode = *nIt;
         minSqDist = sqDist;
@@ -4683,12 +6134,23 @@ struct SMESH_NodeSearcherImpl: public SMESH_NodeSearcher
     }
     return closestNode;
   }
+
+  //---------------------------------------------------------------------
   /*!
    * \brief Destructor
    */
   ~SMESH_NodeSearcherImpl() { delete myOctreeNode; }
+
+  //---------------------------------------------------------------------
+  /*!
+   * \brief Return the node tree
+   */
+  const SMESH_OctreeNode* getTree() const { return myOctreeNode; }
+
 private:
   SMESH_OctreeNode* myOctreeNode;
+  SMESHDS_Mesh*     myMesh;
+  double            myHalfLeafSize; // max size of a leaf box
 };
 
 //=======================================================================
@@ -4702,156 +6164,1400 @@ SMESH_NodeSearcher* SMESH_MeshEditor::GetNodeSearcher()
   return new SMESH_NodeSearcherImpl( GetMeshDS() );
 }
 
-//=======================================================================
-//function : SimplifyFace
-//purpose  :
-//=======================================================================
-int SMESH_MeshEditor::SimplifyFace (const vector<const SMDS_MeshNode *> faceNodes,
-                                    vector<const SMDS_MeshNode *>&      poly_nodes,
-                                    vector<int>&                        quantities) const
+// ========================================================================
+namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
 {
-  int nbNodes = faceNodes.size();
+  const int MaxNbElemsInLeaf = 10; // maximal number of elements in a leaf of tree
+  const int MaxLevel         = 7;  // maximal tree height -> nb terminal boxes: 8^7 = 2097152
+  const double NodeRadius = 1e-9;  // to enlarge bnd box of element
 
-  if (nbNodes < 3)
-    return 0;
+  //=======================================================================
+  /*!
+   * \brief Octal tree of bounding boxes of elements
+   */
+  //=======================================================================
 
-  set<const SMDS_MeshNode*> nodeSet;
+  class ElementBndBoxTree : public SMESH_Octree
+  {
+  public:
+
+    ElementBndBoxTree(const SMDS_Mesh&     mesh,
+                      SMDSAbs_ElementType  elemType,
+                      SMDS_ElemIteratorPtr theElemIt = SMDS_ElemIteratorPtr(),
+                      double               tolerance = NodeRadius );
+    void getElementsNearPoint( const gp_Pnt& point, TIDSortedElemSet& foundElems );
+    void getElementsNearLine ( const gp_Ax1& line, TIDSortedElemSet& foundElems);
+    void getElementsInSphere ( const gp_XYZ& center,
+                               const double  radius, TIDSortedElemSet& foundElems);
+    size_t getSize() { return std::max( _size, _elements.size() ); }
+    ~ElementBndBoxTree();
+
+  protected:
+    ElementBndBoxTree():_size(0) {}
+    SMESH_Octree* allocateOctreeChild() const { return new ElementBndBoxTree; }
+    void          buildChildrenData();
+    Bnd_B3d*      buildRootBox();
+  private:
+    //!< Bounding box of element
+    struct ElementBox : public Bnd_B3d
+    {
+      const SMDS_MeshElement* _element;
+      int                     _refCount; // an ElementBox can be included in several tree branches
+      ElementBox(const SMDS_MeshElement* elem, double tolerance);
+    };
+    vector< ElementBox* > _elements;
+    size_t                _size;
+  };
 
-  // get simple seq of nodes
-  //const SMDS_MeshNode* simpleNodes[ nbNodes ];
-  vector<const SMDS_MeshNode*> simpleNodes( nbNodes );
-  int iSimple = 0, nbUnique = 0;
+  //================================================================================
+  /*!
+   * \brief ElementBndBoxTree creation
+   */
+  //================================================================================
 
-  simpleNodes[iSimple++] = faceNodes[0];
-  nbUnique++;
-  for (int iCur = 1; iCur < nbNodes; iCur++) {
-    if (faceNodes[iCur] != simpleNodes[iSimple - 1]) {
-      simpleNodes[iSimple++] = faceNodes[iCur];
-      if (nodeSet.insert( faceNodes[iCur] ).second)
-        nbUnique++;
-    }
+  ElementBndBoxTree::ElementBndBoxTree(const SMDS_Mesh& mesh, SMDSAbs_ElementType elemType, SMDS_ElemIteratorPtr theElemIt, double tolerance)
+    :SMESH_Octree( new SMESH_Octree::Limit( MaxLevel, /*minSize=*/0. ))
+  {
+    int nbElems = mesh.GetMeshInfo().NbElements( elemType );
+    _elements.reserve( nbElems );
+
+    SMDS_ElemIteratorPtr elemIt = theElemIt ? theElemIt : mesh.elementsIterator( elemType );
+    while ( elemIt->more() )
+      _elements.push_back( new ElementBox( elemIt->next(),tolerance  ));
+
+    compute();
   }
-  int nbSimple = iSimple;
-  if (simpleNodes[nbSimple - 1] == simpleNodes[0]) {
-    nbSimple--;
-    iSimple--;
+
+  //================================================================================
+  /*!
+   * \brief Destructor
+   */
+  //================================================================================
+
+  ElementBndBoxTree::~ElementBndBoxTree()
+  {
+    for ( int i = 0; i < _elements.size(); ++i )
+      if ( --_elements[i]->_refCount <= 0 )
+        delete _elements[i];
   }
 
-  if (nbUnique < 3)
-    return 0;
+  //================================================================================
+  /*!
+   * \brief Return the maximal box
+   */
+  //================================================================================
 
-  // separate loops
-  int nbNew = 0;
-  bool foundLoop = (nbSimple > nbUnique);
-  while (foundLoop) {
-    foundLoop = false;
-    set<const SMDS_MeshNode*> loopSet;
-    for (iSimple = 0; iSimple < nbSimple && !foundLoop; iSimple++) {
-      const SMDS_MeshNode* n = simpleNodes[iSimple];
-      if (!loopSet.insert( n ).second) {
-        foundLoop = true;
+  Bnd_B3d* ElementBndBoxTree::buildRootBox()
+  {
+    Bnd_B3d* box = new Bnd_B3d;
+    for ( int i = 0; i < _elements.size(); ++i )
+      box->Add( *_elements[i] );
+    return box;
+  }
 
-        // separate loop
-        int iC = 0, curLast = iSimple;
-        for (; iC < curLast; iC++) {
-          if (simpleNodes[iC] == n) break;
-        }
-        int loopLen = curLast - iC;
-        if (loopLen > 2) {
-          // create sub-element
-          nbNew++;
-          quantities.push_back(loopLen);
-          for (; iC < curLast; iC++) {
-            poly_nodes.push_back(simpleNodes[iC]);
-          }
-        }
-        // shift the rest nodes (place from the first loop position)
-        for (iC = curLast + 1; iC < nbSimple; iC++) {
-          simpleNodes[iC - loopLen] = simpleNodes[iC];
+  //================================================================================
+  /*!
+   * \brief Redistrubute element boxes among children
+   */
+  //================================================================================
+
+  void ElementBndBoxTree::buildChildrenData()
+  {
+    for ( int i = 0; i < _elements.size(); ++i )
+    {
+      for (int j = 0; j < 8; j++)
+      {
+        if ( !_elements[i]->IsOut( myChildren[j]->getBox() ))
+        {
+          _elements[i]->_refCount++;
+          ((ElementBndBoxTree*)myChildren[j])->_elements.push_back( _elements[i]);
         }
-        nbSimple -= loopLen;
-        iSimple -= loopLen;
       }
-    } // for (iSimple = 0; iSimple < nbSimple; iSimple++)
-  } // while (foundLoop)
+      _elements[i]->_refCount--;
+    }
+    _size = _elements.size();
+    SMESHUtils::FreeVector( _elements ); // = _elements.clear() + free memory
 
-  if (iSimple > 2) {
-    nbNew++;
-    quantities.push_back(iSimple);
-    for (int i = 0; i < iSimple; i++)
-      poly_nodes.push_back(simpleNodes[i]);
+    for (int j = 0; j < 8; j++)
+    {
+      ElementBndBoxTree* child = static_cast<ElementBndBoxTree*>( myChildren[j]);
+      if ( child->_elements.size() <= MaxNbElemsInLeaf )
+        child->myIsLeaf = true;
+
+      if ( child->_elements.capacity() - child->_elements.size() > 1000 )
+        SMESHUtils::CompactVector( child->_elements );
+    }
   }
 
-  return nbNew;
-}
+  //================================================================================
+  /*!
+   * \brief Return elements which can include the point
+   */
+  //================================================================================
 
-//=======================================================================
-//function : MergeNodes
-//purpose  : In each group, the cdr of nodes are substituted by the first one
-//           in all elements.
-//=======================================================================
+  void ElementBndBoxTree::getElementsNearPoint( const gp_Pnt&     point,
+                                                TIDSortedElemSet& foundElems)
+  {
+    if ( getBox().IsOut( point.XYZ() ))
+      return;
 
-void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
-{
-  myLastCreatedElems.Clear();
-  myLastCreatedNodes.Clear();
+    if ( isLeaf() )
+    {
+      for ( int i = 0; i < _elements.size(); ++i )
+        if ( !_elements[i]->IsOut( point.XYZ() ))
+          foundElems.insert( _elements[i]->_element );
+    }
+    else
+    {
+      for (int i = 0; i < 8; i++)
+        ((ElementBndBoxTree*) myChildren[i])->getElementsNearPoint( point, foundElems );
+    }
+  }
 
-  SMESHDS_Mesh* aMesh = GetMeshDS();
+  //================================================================================
+  /*!
+   * \brief Return elements which can be intersected by the line
+   */
+  //================================================================================
 
-  TNodeNodeMap nodeNodeMap; // node to replace - new node
-  set<const SMDS_MeshElement*> elems; // all elements with changed nodes
-  list< int > rmElemIds, rmNodeIds;
+  void ElementBndBoxTree::getElementsNearLine( const gp_Ax1&     line,
+                                               TIDSortedElemSet& foundElems)
+  {
+    if ( getBox().IsOut( line ))
+      return;
 
-  // Fill nodeNodeMap and elems
+    if ( isLeaf() )
+    {
+      for ( int i = 0; i < _elements.size(); ++i )
+        if ( !_elements[i]->IsOut( line ))
+          foundElems.insert( _elements[i]->_element );
+    }
+    else
+    {
+      for (int i = 0; i < 8; i++)
+        ((ElementBndBoxTree*) myChildren[i])->getElementsNearLine( line, foundElems );
+    }
+  }
 
-  TListOfListOfNodes::iterator grIt = theGroupsOfNodes.begin();
-  for ( ; grIt != theGroupsOfNodes.end(); grIt++ ) {
-    list<const SMDS_MeshNode*>& nodes = *grIt;
-    list<const SMDS_MeshNode*>::iterator nIt = nodes.begin();
-    const SMDS_MeshNode* nToKeep = *nIt;
-    for ( ++nIt; nIt != nodes.end(); nIt++ ) {
-      const SMDS_MeshNode* nToRemove = *nIt;
-      nodeNodeMap.insert( TNodeNodeMap::value_type( nToRemove, nToKeep ));
-      if ( nToRemove != nToKeep ) {
-        rmNodeIds.push_back( nToRemove->GetID() );
-        AddToSameGroups( nToKeep, nToRemove, aMesh );
-      }
+  //================================================================================
+  /*!
+   * \brief Return elements from leaves intersecting the sphere
+   */
+  //================================================================================
 
-      SMDS_ElemIteratorPtr invElemIt = nToRemove->GetInverseElementIterator();
-      while ( invElemIt->more() ) {
-        const SMDS_MeshElement* elem = invElemIt->next();
-          elems.insert(elem);
-      }
+  void ElementBndBoxTree::getElementsInSphere ( const gp_XYZ&     center,
+                                                const double      radius,
+                                                TIDSortedElemSet& foundElems)
+  {
+    if ( getBox().IsOut( center, radius ))
+      return;
+
+    if ( isLeaf() )
+    {
+      for ( int i = 0; i < _elements.size(); ++i )
+        if ( !_elements[i]->IsOut( center, radius ))
+          foundElems.insert( _elements[i]->_element );
+    }
+    else
+    {
+      for (int i = 0; i < 8; i++)
+        ((ElementBndBoxTree*) myChildren[i])->getElementsInSphere( center, radius, foundElems );
     }
   }
-  // Change element nodes or remove an element
 
-  set<const SMDS_MeshElement*>::iterator eIt = elems.begin();
-  for ( ; eIt != elems.end(); eIt++ ) {
-    const SMDS_MeshElement* elem = *eIt;
-    int nbNodes = elem->NbNodes();
-    int aShapeId = FindShape( elem );
+  //================================================================================
+  /*!
+   * \brief Construct the element box
+   */
+  //================================================================================
 
-    set<const SMDS_MeshNode*> nodeSet;
-    vector< const SMDS_MeshNode*> curNodes( nbNodes ), uniqueNodes( nbNodes );
-    int iUnique = 0, iCur = 0, nbRepl = 0;
-    vector<int> iRepl( nbNodes );
+  ElementBndBoxTree::ElementBox::ElementBox(const SMDS_MeshElement* elem, double tolerance)
+  {
+    _element  = elem;
+    _refCount = 1;
+    SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
+    while ( nIt->more() )
+      Add( SMESH_TNodeXYZ( nIt->next() ));
+    Enlarge( tolerance );
+  }
 
-    // get new seq of nodes
-    SMDS_ElemIteratorPtr itN = elem->nodesIterator();
-    while ( itN->more() ) {
-      const SMDS_MeshNode* n =
-        static_cast<const SMDS_MeshNode*>( itN->next() );
+} // namespace
 
-      TNodeNodeMap::iterator nnIt = nodeNodeMap.find( n );
-      if ( nnIt != nodeNodeMap.end() ) { // n sticks
-        n = (*nnIt).second;
-        iRepl[ nbRepl++ ] = iCur;
+//=======================================================================
+/*!
+ * \brief Implementation of search for the elements by point and
+ *        of classification of point in 2D mesh
+ */
+//=======================================================================
+
+struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher
+{
+  SMESHDS_Mesh*                _mesh;
+  SMDS_ElemIteratorPtr         _meshPartIt;
+  ElementBndBoxTree*           _ebbTree;
+  SMESH_NodeSearcherImpl*      _nodeSearcher;
+  SMDSAbs_ElementType          _elementType;
+  double                       _tolerance;
+  bool                         _outerFacesFound;
+  set<const SMDS_MeshElement*> _outerFaces; // empty means "no internal faces at all"
+
+  SMESH_ElementSearcherImpl( SMESHDS_Mesh& mesh, SMDS_ElemIteratorPtr elemIt=SMDS_ElemIteratorPtr())
+    : _mesh(&mesh),_meshPartIt(elemIt),_ebbTree(0),_nodeSearcher(0),_tolerance(-1),_outerFacesFound(false) {}
+  ~SMESH_ElementSearcherImpl()
+  {
+    if ( _ebbTree )      delete _ebbTree;      _ebbTree      = 0;
+    if ( _nodeSearcher ) delete _nodeSearcher; _nodeSearcher = 0;
+  }
+  virtual int FindElementsByPoint(const gp_Pnt&                      point,
+                                  SMDSAbs_ElementType                type,
+                                  vector< const SMDS_MeshElement* >& foundElements);
+  virtual TopAbs_State GetPointState(const gp_Pnt& point);
+  virtual const SMDS_MeshElement* FindClosestTo( const gp_Pnt&       point,
+                                                 SMDSAbs_ElementType type );
+
+  void GetElementsNearLine( const gp_Ax1&                      line,
+                            SMDSAbs_ElementType                type,
+                            vector< const SMDS_MeshElement* >& foundElems);
+  double getTolerance();
+  bool getIntersParamOnLine(const gp_Lin& line, const SMDS_MeshElement* face,
+                            const double tolerance, double & param);
+  void findOuterBoundary(const SMDS_MeshElement* anyOuterFace);
+  bool isOuterBoundary(const SMDS_MeshElement* face) const
+  {
+    return _outerFaces.empty() || _outerFaces.count(face);
+  }
+  struct TInters //!< data of intersection of the line and the mesh face (used in GetPointState())
+  {
+    const SMDS_MeshElement* _face;
+    gp_Vec                  _faceNorm;
+    bool                    _coincides; //!< the line lays in face plane
+    TInters(const SMDS_MeshElement* face, const gp_Vec& faceNorm, bool coinc=false)
+      : _face(face), _faceNorm( faceNorm ), _coincides( coinc ) {}
+  };
+  struct TFaceLink //!< link and faces sharing it (used in findOuterBoundary())
+  {
+    SMESH_TLink      _link;
+    TIDSortedElemSet _faces;
+    TFaceLink( const SMDS_MeshNode* n1, const SMDS_MeshNode* n2, const SMDS_MeshElement* face)
+      : _link( n1, n2 ), _faces( &face, &face + 1) {}
+  };
+};
+
+ostream& operator<< (ostream& out, const SMESH_ElementSearcherImpl::TInters& i)
+{
+  return out << "TInters(face=" << ( i._face ? i._face->GetID() : 0)
+             << ", _coincides="<<i._coincides << ")";
+}
+
+//=======================================================================
+/*!
+ * \brief define tolerance for search
+ */
+//=======================================================================
+
+double SMESH_ElementSearcherImpl::getTolerance()
+{
+  if ( _tolerance < 0 )
+  {
+    const SMDS_MeshInfo& meshInfo = _mesh->GetMeshInfo();
+
+    _tolerance = 0;
+    if ( _nodeSearcher && meshInfo.NbNodes() > 1 )
+    {
+      double boxSize = _nodeSearcher->getTree()->maxSize();
+      _tolerance = 1e-8 * boxSize/* / meshInfo.NbNodes()*/;
+    }
+    else if ( _ebbTree && meshInfo.NbElements() > 0 )
+    {
+      double boxSize = _ebbTree->maxSize();
+      _tolerance = 1e-8 * boxSize/* / meshInfo.NbElements()*/;
+    }
+    if ( _tolerance == 0 )
+    {
+      // define tolerance by size of a most complex element
+      int complexType = SMDSAbs_Volume;
+      while ( complexType > SMDSAbs_All &&
+              meshInfo.NbElements( SMDSAbs_ElementType( complexType )) < 1 )
+        --complexType;
+      if ( complexType == SMDSAbs_All ) return 0; // empty mesh
+      double elemSize;
+      if ( complexType == int( SMDSAbs_Node ))
+      {
+        SMDS_NodeIteratorPtr nodeIt = _mesh->nodesIterator();
+        elemSize = 1;
+        if ( meshInfo.NbNodes() > 2 )
+          elemSize = SMESH_TNodeXYZ( nodeIt->next() ).Distance( nodeIt->next() );
+      }
+      else
+      {
+        SMDS_ElemIteratorPtr elemIt =
+            _mesh->elementsIterator( SMDSAbs_ElementType( complexType ));
+        const SMDS_MeshElement* elem = elemIt->next();
+        SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
+        SMESH_TNodeXYZ n1( cast2Node( nodeIt->next() ));
+        elemSize = 0;
+        while ( nodeIt->more() )
+        {
+          double dist = n1.Distance( cast2Node( nodeIt->next() ));
+          elemSize = max( dist, elemSize );
+        }
+      }
+      _tolerance = 1e-4 * elemSize;
+    }
+  }
+  return _tolerance;
+}
+
+//================================================================================
+/*!
+ * \brief Find intersection of the line and an edge of face and return parameter on line
+ */
+//================================================================================
+
+bool SMESH_ElementSearcherImpl::getIntersParamOnLine(const gp_Lin&           line,
+                                                     const SMDS_MeshElement* face,
+                                                     const double            tol,
+                                                     double &                param)
+{
+  int nbInts = 0;
+  param = 0;
+
+  GeomAPI_ExtremaCurveCurve anExtCC;
+  Handle(Geom_Curve) lineCurve = new Geom_Line( line );
+  
+  int nbNodes = face->IsQuadratic() ? face->NbNodes()/2 : face->NbNodes();
+  for ( int i = 0; i < nbNodes && nbInts < 2; ++i )
+  {
+    GC_MakeSegment edge( SMESH_TNodeXYZ( face->GetNode( i )),
+                         SMESH_TNodeXYZ( face->GetNode( (i+1)%nbNodes) )); 
+    anExtCC.Init( lineCurve, edge);
+    if ( anExtCC.NbExtrema() > 0 && anExtCC.LowerDistance() <= tol)
+    {
+      Quantity_Parameter pl, pe;
+      anExtCC.LowerDistanceParameters( pl, pe );
+      param += pl;
+      if ( ++nbInts == 2 )
+        break;
+    }
+  }
+  if ( nbInts > 0 ) param /= nbInts;
+  return nbInts > 0;
+}
+//================================================================================
+/*!
+ * \brief Find all faces belonging to the outer boundary of mesh
+ */
+//================================================================================
+
+void SMESH_ElementSearcherImpl::findOuterBoundary(const SMDS_MeshElement* outerFace)
+{
+  if ( _outerFacesFound ) return;
+
+  // Collect all outer faces by passing from one outer face to another via their links
+  // and BTW find out if there are internal faces at all.
+
+  // checked links and links where outer boundary meets internal one
+  set< SMESH_TLink > visitedLinks, seamLinks;
+
+  // links to treat with already visited faces sharing them
+  list < TFaceLink > startLinks;
+
+  // load startLinks with the first outerFace
+  startLinks.push_back( TFaceLink( outerFace->GetNode(0), outerFace->GetNode(1), outerFace));
+  _outerFaces.insert( outerFace );
+
+  TIDSortedElemSet emptySet;
+  while ( !startLinks.empty() )
+  {
+    const SMESH_TLink& link  = startLinks.front()._link;
+    TIDSortedElemSet&  faces = startLinks.front()._faces;
+
+    outerFace = *faces.begin();
+    // find other faces sharing the link
+    const SMDS_MeshElement* f;
+    while (( f = SMESH_MeshEditor::FindFaceInSet(link.node1(), link.node2(), emptySet, faces )))
+      faces.insert( f );
+
+    // select another outer face among the found 
+    const SMDS_MeshElement* outerFace2 = 0;
+    if ( faces.size() == 2 )
+    {
+      outerFace2 = (outerFace == *faces.begin() ? *faces.rbegin() : *faces.begin());
+    }
+    else if ( faces.size() > 2 )
+    {
+      seamLinks.insert( link );
+
+      // link direction within the outerFace
+      gp_Vec n1n2( SMESH_TNodeXYZ( link.node1()),
+                   SMESH_TNodeXYZ( link.node2()));
+      int i1 = outerFace->GetNodeIndex( link.node1() );
+      int i2 = outerFace->GetNodeIndex( link.node2() );
+      bool rev = ( abs(i2-i1) == 1 ? i1 > i2 : i2 > i1 );
+      if ( rev ) n1n2.Reverse();
+      // outerFace normal
+      gp_XYZ ofNorm, fNorm;
+      if ( SMESH_Algo::FaceNormal( outerFace, ofNorm, /*normalized=*/false ))
+      {
+        // direction from the link inside outerFace
+        gp_Vec dirInOF = gp_Vec( ofNorm ) ^ n1n2;
+        // sort all other faces by angle with the dirInOF
+        map< double, const SMDS_MeshElement* > angle2Face;
+        set< const SMDS_MeshElement*, TIDCompare >::const_iterator face = faces.begin();
+        for ( ; face != faces.end(); ++face )
+        {
+          if ( !SMESH_Algo::FaceNormal( *face, fNorm, /*normalized=*/false ))
+            continue;
+          gp_Vec dirInF = gp_Vec( fNorm ) ^ n1n2;
+          double angle = dirInOF.AngleWithRef( dirInF, n1n2 );
+          if ( angle < 0 ) angle += 2. * M_PI;
+          angle2Face.insert( make_pair( angle, *face ));
+        }
+        if ( !angle2Face.empty() )
+          outerFace2 = angle2Face.begin()->second;
+      }
+    }
+    // store the found outer face and add its links to continue seaching from
+    if ( outerFace2 )
+    {
+      _outerFaces.insert( outerFace );
+      int nbNodes = outerFace2->NbNodes()/( outerFace2->IsQuadratic() ? 2 : 1 );
+      for ( int i = 0; i < nbNodes; ++i )
+      {
+        SMESH_TLink link2( outerFace2->GetNode(i), outerFace2->GetNode((i+1)%nbNodes));
+        if ( visitedLinks.insert( link2 ).second )
+          startLinks.push_back( TFaceLink( link2.node1(), link2.node2(), outerFace2 ));
+      }
+    }
+    startLinks.pop_front();
+  }
+  _outerFacesFound = true;
+
+  if ( !seamLinks.empty() )
+  {
+    // There are internal boundaries touching the outher one,
+    // find all faces of internal boundaries in order to find
+    // faces of boundaries of holes, if any.
+    
+  }
+  else
+  {
+    _outerFaces.clear();
+  }
+}
+
+//=======================================================================
+/*!
+ * \brief Find elements of given type where the given point is IN or ON.
+ *        Returns nb of found elements and elements them-selves.
+ *
+ * 'ALL' type means elements of any type excluding nodes, balls and 0D elements 
+ */
+//=======================================================================
+
+int SMESH_ElementSearcherImpl::
+FindElementsByPoint(const gp_Pnt&                      point,
+                    SMDSAbs_ElementType                type,
+                    vector< const SMDS_MeshElement* >& foundElements)
+{
+  foundElements.clear();
+
+  double tolerance = getTolerance();
+
+  // =================================================================================
+  if ( type == SMDSAbs_Node || type == SMDSAbs_0DElement || type == SMDSAbs_Ball)
+  {
+    if ( !_nodeSearcher )
+      _nodeSearcher = new SMESH_NodeSearcherImpl( _mesh );
+
+    const SMDS_MeshNode* closeNode = _nodeSearcher->FindClosestTo( point );
+    if ( !closeNode ) return foundElements.size();
+
+    if ( point.Distance( SMESH_TNodeXYZ( closeNode )) > tolerance )
+      return foundElements.size(); // to far from any node
+
+    if ( type == SMDSAbs_Node )
+    {
+      foundElements.push_back( closeNode );
+    }
+    else
+    {
+      SMDS_ElemIteratorPtr elemIt = closeNode->GetInverseElementIterator( type );
+      while ( elemIt->more() )
+        foundElements.push_back( elemIt->next() );
+    }
+  }
+  // =================================================================================
+  else // elements more complex than 0D
+  {
+    if ( !_ebbTree || _elementType != type )
+    {
+      if ( _ebbTree ) delete _ebbTree;
+      _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = type, _meshPartIt, tolerance );
+    }
+    TIDSortedElemSet suspectElems;
+    _ebbTree->getElementsNearPoint( point, suspectElems );
+    TIDSortedElemSet::iterator elem = suspectElems.begin();
+    for ( ; elem != suspectElems.end(); ++elem )
+      if ( !SMESH_MeshEditor::IsOut( *elem, point, tolerance ))
+        foundElements.push_back( *elem );
+  }
+  return foundElements.size();
+}
+
+//=======================================================================
+/*!
+ * \brief Find an element of given type most close to the given point
+ *
+ * WARNING: Only face search is implemeneted so far
+ */
+//=======================================================================
+
+const SMDS_MeshElement*
+SMESH_ElementSearcherImpl::FindClosestTo( const gp_Pnt&       point,
+                                          SMDSAbs_ElementType type )
+{
+  const SMDS_MeshElement* closestElem = 0;
+
+  if ( type == SMDSAbs_Face )
+  {
+    if ( !_ebbTree || _elementType != type )
+    {
+      if ( _ebbTree ) delete _ebbTree;
+      _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = type, _meshPartIt );
+    }
+    TIDSortedElemSet suspectElems;
+    _ebbTree->getElementsNearPoint( point, suspectElems );
+    
+    if ( suspectElems.empty() && _ebbTree->maxSize() > 0 )
+    {
+      gp_Pnt boxCenter = 0.5 * ( _ebbTree->getBox().CornerMin() +
+                                 _ebbTree->getBox().CornerMax() );
+      double radius;
+      if ( _ebbTree->getBox().IsOut( point.XYZ() ))
+        radius = point.Distance( boxCenter ) - 0.5 * _ebbTree->maxSize();
+      else
+        radius = _ebbTree->maxSize() / pow( 2., _ebbTree->getHeight()) / 2;
+      while ( suspectElems.empty() )
+      {
+        _ebbTree->getElementsInSphere( point.XYZ(), radius, suspectElems );
+        radius *= 1.1;
+      }
+    }
+    double minDist = std::numeric_limits<double>::max();
+    multimap< double, const SMDS_MeshElement* > dist2face;
+    TIDSortedElemSet::iterator elem = suspectElems.begin();
+    for ( ; elem != suspectElems.end(); ++elem )
+    {
+      double dist = SMESH_MeshEditor::GetDistance( dynamic_cast<const SMDS_MeshFace*>(*elem),
+                                                   point );
+      if ( dist < minDist + 1e-10)
+      {
+        minDist = dist;
+        dist2face.insert( dist2face.begin(), make_pair( dist, *elem ));
+      }
+    }
+    if ( !dist2face.empty() )
+    {
+      multimap< double, const SMDS_MeshElement* >::iterator d2f = dist2face.begin();
+      closestElem = d2f->second;
+      // if there are several elements at the same distance, select one
+      // with GC closest to the point
+      typedef SMDS_StdIterator< SMESH_TNodeXYZ, SMDS_ElemIteratorPtr > TXyzIterator;
+      double minDistToGC = 0;
+      for ( ++d2f; d2f != dist2face.end() && fabs( d2f->first - minDist ) < 1e-10; ++d2f )
+      {
+        if ( minDistToGC == 0 )
+        {
+          gp_XYZ gc(0,0,0);
+          gc = accumulate( TXyzIterator(closestElem->nodesIterator()),
+                           TXyzIterator(), gc ) / closestElem->NbNodes();
+          minDistToGC = point.SquareDistance( gc );
+        }
+        gp_XYZ gc(0,0,0);
+        gc = accumulate( TXyzIterator( d2f->second->nodesIterator()),
+                         TXyzIterator(), gc ) / d2f->second->NbNodes();
+        double d = point.SquareDistance( gc );
+        if ( d < minDistToGC )
+        {
+          minDistToGC = d;
+          closestElem = d2f->second;
+        }
+      }
+      // cout << "FindClosestTo( " <<point.X()<<", "<<point.Y()<<", "<<point.Z()<<" ) FACE "
+      //      <<closestElem->GetID() << " DIST " << minDist << endl;
+    }
+  }
+  else
+  {
+    // NOT IMPLEMENTED SO FAR
+  }
+  return closestElem;
+}
+
+
+//================================================================================
+/*!
+ * \brief Classify the given point in the closed 2D mesh
+ */
+//================================================================================
+
+TopAbs_State SMESH_ElementSearcherImpl::GetPointState(const gp_Pnt& point)
+{
+  double tolerance = getTolerance();
+  if ( !_ebbTree || _elementType != SMDSAbs_Face )
+  {
+    if ( _ebbTree ) delete _ebbTree;
+    _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = SMDSAbs_Face, _meshPartIt );
+  }
+  // Algo: analyse transition of a line starting at the point through mesh boundary;
+  // try three lines parallel to axis of the coordinate system and perform rough
+  // analysis. If solution is not clear perform thorough analysis.
+
+  const int nbAxes = 3;
+  gp_Dir axisDir[ nbAxes ] = { gp::DX(), gp::DY(), gp::DZ() };
+  map< double, TInters >   paramOnLine2TInters[ nbAxes ];
+  list< TInters > tangentInters[ nbAxes ]; // of faces whose plane includes the line
+  multimap< int, int > nbInt2Axis; // to find the simplest case
+  for ( int axis = 0; axis < nbAxes; ++axis )
+  {
+    gp_Ax1 lineAxis( point, axisDir[axis]);
+    gp_Lin line    ( lineAxis );
+
+    TIDSortedElemSet suspectFaces; // faces possibly intersecting the line
+    _ebbTree->getElementsNearLine( lineAxis, suspectFaces );
+
+    // Intersect faces with the line
+
+    map< double, TInters > & u2inters = paramOnLine2TInters[ axis ];
+    TIDSortedElemSet::iterator face = suspectFaces.begin();
+    for ( ; face != suspectFaces.end(); ++face )
+    {
+      // get face plane
+      gp_XYZ fNorm;
+      if ( !SMESH_Algo::FaceNormal( *face, fNorm, /*normalized=*/false)) continue;
+      gp_Pln facePlane( SMESH_TNodeXYZ( (*face)->GetNode(0)), fNorm );
+
+      // perform intersection
+      IntAna_IntConicQuad intersection( line, IntAna_Quadric( facePlane ));
+      if ( !intersection.IsDone() )
+        continue;
+      if ( intersection.IsInQuadric() )
+      {
+        tangentInters[ axis ].push_back( TInters( *face, fNorm, true ));
+      }
+      else if ( ! intersection.IsParallel() && intersection.NbPoints() > 0 )
+      {
+        gp_Pnt intersectionPoint = intersection.Point(1);
+        if ( !SMESH_MeshEditor::IsOut( *face, intersectionPoint, tolerance ))
+          u2inters.insert(make_pair( intersection.ParamOnConic(1), TInters( *face, fNorm )));
+      }
+    }
+    // Analyse intersections roughly
+
+    int nbInter = u2inters.size();
+    if ( nbInter == 0 )
+      return TopAbs_OUT; 
+
+    double f = u2inters.begin()->first, l = u2inters.rbegin()->first;
+    if ( nbInter == 1 ) // not closed mesh
+      return fabs( f ) < tolerance ? TopAbs_ON : TopAbs_UNKNOWN;
+
+    if ( fabs( f ) < tolerance || fabs( l ) < tolerance )
+      return TopAbs_ON;
+
+    if ( (f<0) == (l<0) )
+      return TopAbs_OUT;
+
+    int nbIntBeforePoint = std::distance( u2inters.begin(), u2inters.lower_bound(0));
+    int nbIntAfterPoint  = nbInter - nbIntBeforePoint;
+    if ( nbIntBeforePoint == 1 || nbIntAfterPoint == 1 )
+      return TopAbs_IN;
+
+    nbInt2Axis.insert( make_pair( min( nbIntBeforePoint, nbIntAfterPoint ), axis ));
+
+    if ( _outerFacesFound ) break; // pass to thorough analysis
+
+  } // three attempts - loop on CS axes
+
+  // Analyse intersections thoroughly.
+  // We make two loops maximum, on the first one we only exclude touching intersections,
+  // on the second, if situation is still unclear, we gather and use information on
+  // position of faces (internal or outer). If faces position is already gathered,
+  // we make the second loop right away.
+
+  for ( int hasPositionInfo = _outerFacesFound; hasPositionInfo < 2; ++hasPositionInfo )
+  {
+    multimap< int, int >::const_iterator nb_axis = nbInt2Axis.begin();
+    for ( ; nb_axis != nbInt2Axis.end(); ++nb_axis )
+    {
+      int axis = nb_axis->second;
+      map< double, TInters > & u2inters = paramOnLine2TInters[ axis ];
+
+      gp_Ax1 lineAxis( point, axisDir[axis]);
+      gp_Lin line    ( lineAxis );
+
+      // add tangent intersections to u2inters
+      double param;
+      list< TInters >::const_iterator tgtInt = tangentInters[ axis ].begin();
+      for ( ; tgtInt != tangentInters[ axis ].end(); ++tgtInt )
+        if ( getIntersParamOnLine( line, tgtInt->_face, tolerance, param ))
+          u2inters.insert(make_pair( param, *tgtInt ));
+      tangentInters[ axis ].clear();
+
+      // Count intersections before and after the point excluding touching ones.
+      // If hasPositionInfo we count intersections of outer boundary only
+
+      int nbIntBeforePoint = 0, nbIntAfterPoint = 0;
+      double f = numeric_limits<double>::max(), l = -numeric_limits<double>::max();
+      map< double, TInters >::iterator u_int1 = u2inters.begin(), u_int2 = u_int1;
+      bool ok = ! u_int1->second._coincides;
+      while ( ok && u_int1 != u2inters.end() )
+      {
+        double u = u_int1->first;
+        bool touchingInt = false;
+        if ( ++u_int2 != u2inters.end() )
+        {
+          // skip intersections at the same point (if the line passes through edge or node)
+          int nbSamePnt = 0;
+          while ( u_int2 != u2inters.end() && fabs( u_int2->first - u ) < tolerance )
+          {
+            ++nbSamePnt;
+            ++u_int2;
+          }
+
+          // skip tangent intersections
+          int nbTgt = 0;
+          const SMDS_MeshElement* prevFace = u_int1->second._face;
+          while ( ok && u_int2->second._coincides )
+          {
+            if ( SMESH_Algo::GetCommonNodes(prevFace , u_int2->second._face).empty() )
+              ok = false;
+            else
+            {
+              nbTgt++;
+              u_int2++;
+              ok = ( u_int2 != u2inters.end() );
+            }
+          }
+          if ( !ok ) break;
+
+          // skip intersections at the same point after tangent intersections
+          if ( nbTgt > 0 )
+          {
+            double u2 = u_int2->first;
+            ++u_int2;
+            while ( u_int2 != u2inters.end() && fabs( u_int2->first - u2 ) < tolerance )
+            {
+              ++nbSamePnt;
+              ++u_int2;
+            }
+          }
+          // decide if we skipped a touching intersection
+          if ( nbSamePnt + nbTgt > 0 )
+          {
+            double minDot = numeric_limits<double>::max(), maxDot = -numeric_limits<double>::max();
+            map< double, TInters >::iterator u_int = u_int1;
+            for ( ; u_int != u_int2; ++u_int )
+            {
+              if ( u_int->second._coincides ) continue;
+              double dot = u_int->second._faceNorm * line.Direction();
+              if ( dot > maxDot ) maxDot = dot;
+              if ( dot < minDot ) minDot = dot;
+            }
+            touchingInt = ( minDot*maxDot < 0 );
+          }
+        }
+        if ( !touchingInt )
+        {
+          if ( !hasPositionInfo || isOuterBoundary( u_int1->second._face ))
+          {
+            if ( u < 0 )
+              ++nbIntBeforePoint;
+            else
+              ++nbIntAfterPoint;
+          }
+          if ( u < f ) f = u;
+          if ( u > l ) l = u;
+        }
+
+        u_int1 = u_int2; // to next intersection
+
+      } // loop on intersections with one line
+
+      if ( ok )
+      {
+        if ( fabs( f ) < tolerance || fabs( l ) < tolerance )
+          return TopAbs_ON;
+
+        if ( nbIntBeforePoint == 0  || nbIntAfterPoint == 0)
+          return TopAbs_OUT; 
+
+        if ( nbIntBeforePoint + nbIntAfterPoint == 1 ) // not closed mesh
+          return fabs( f ) < tolerance ? TopAbs_ON : TopAbs_UNKNOWN;
+
+        if ( nbIntBeforePoint == 1 || nbIntAfterPoint == 1 )
+          return TopAbs_IN;
+
+        if ( (f<0) == (l<0) )
+          return TopAbs_OUT;
+
+        if ( hasPositionInfo )
+          return nbIntBeforePoint % 2 ? TopAbs_IN : TopAbs_OUT;
+      }
+    } // loop on intersections of the tree lines - thorough analysis
+
+    if ( !hasPositionInfo )
+    {
+      // gather info on faces position - is face in the outer boundary or not
+      map< double, TInters > & u2inters = paramOnLine2TInters[ 0 ];
+      findOuterBoundary( u2inters.begin()->second._face );
+    }
+
+  } // two attempts - with and w/o faces position info in the mesh
+
+  return TopAbs_UNKNOWN;
+}
+
+//=======================================================================
+/*!
+ * \brief Return elements possibly intersecting the line
+ */
+//=======================================================================
+
+void SMESH_ElementSearcherImpl::GetElementsNearLine( const gp_Ax1&                      line,
+                                                     SMDSAbs_ElementType                type,
+                                                     vector< const SMDS_MeshElement* >& foundElems)
+{
+  if ( !_ebbTree || _elementType != type )
+  {
+    if ( _ebbTree ) delete _ebbTree;
+    _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = type, _meshPartIt );
+  }
+  TIDSortedElemSet suspectFaces; // elements possibly intersecting the line
+  _ebbTree->getElementsNearLine( line, suspectFaces );
+  foundElems.assign( suspectFaces.begin(), suspectFaces.end());
+}
+
+//=======================================================================
+/*!
+ * \brief Return SMESH_ElementSearcher
+ */
+//=======================================================================
+
+SMESH_ElementSearcher* SMESH_MeshEditor::GetElementSearcher()
+{
+  return new SMESH_ElementSearcherImpl( *GetMeshDS() );
+}
+
+//=======================================================================
+/*!
+ * \brief Return SMESH_ElementSearcher acting on a sub-set of elements
+ */
+//=======================================================================
+
+SMESH_ElementSearcher* SMESH_MeshEditor::GetElementSearcher(SMDS_ElemIteratorPtr elemIt)
+{
+  return new SMESH_ElementSearcherImpl( *GetMeshDS(), elemIt );
+}
+
+//=======================================================================
+/*!
+ * \brief Return true if the point is IN or ON of the element
+ */
+//=======================================================================
+
+bool SMESH_MeshEditor::IsOut( const SMDS_MeshElement* element, const gp_Pnt& point, double tol )
+{
+  if ( element->GetType() == SMDSAbs_Volume)
+  {
+    return SMDS_VolumeTool( element ).IsOut( point.X(), point.Y(), point.Z(), tol );
+  }
+
+  // get ordered nodes
+
+  vector< gp_XYZ > xyz;
+  vector<const SMDS_MeshNode*> nodeList;
+
+  SMDS_ElemIteratorPtr nodeIt = element->nodesIterator();
+  if ( element->IsQuadratic() ) {
+    if (const SMDS_VtkFace* f=dynamic_cast<const SMDS_VtkFace*>(element))
+      nodeIt = f->interlacedNodesElemIterator();
+    else if (const SMDS_VtkEdge*  e =dynamic_cast<const SMDS_VtkEdge*>(element))
+      nodeIt = e->interlacedNodesElemIterator();
+  }
+  while ( nodeIt->more() )
+    {
+      const SMDS_MeshNode* node = cast2Node( nodeIt->next() );
+      xyz.push_back( SMESH_TNodeXYZ(node) );
+      nodeList.push_back(node);
+    }
+
+  int i, nbNodes = element->NbNodes();
+
+  if ( element->GetType() == SMDSAbs_Face ) // --------------------------------------------------
+  {
+    // compute face normal
+    gp_Vec faceNorm(0,0,0);
+    xyz.push_back( xyz.front() );
+    nodeList.push_back( nodeList.front() );
+    for ( i = 0; i < nbNodes; ++i )
+    {
+      gp_Vec edge1( xyz[i+1], xyz[i]);
+      gp_Vec edge2( xyz[i+1], xyz[(i+2)%nbNodes] );
+      faceNorm += edge1 ^ edge2;
+    }
+    double normSize = faceNorm.Magnitude();
+    if ( normSize <= tol )
+    {
+      // degenerated face: point is out if it is out of all face edges
+      for ( i = 0; i < nbNodes; ++i )
+      {
+        SMDS_LinearEdge edge( nodeList[i], nodeList[i+1] );
+        if ( !IsOut( &edge, point, tol ))
+          return false;
+      }
+      return true;
+    }
+    faceNorm /= normSize;
+
+    // check if the point lays on face plane
+    gp_Vec n2p( xyz[0], point );
+    if ( fabs( n2p * faceNorm ) > tol )
+      return true; // not on face plane
+
+    // check if point is out of face boundary:
+    // define it by closest transition of a ray point->infinity through face boundary
+    // on the face plane.
+    // First, find normal of a plane perpendicular to face plane, to be used as a cutting tool
+    // to find intersections of the ray with the boundary.
+    gp_Vec ray = n2p;
+    gp_Vec plnNorm = ray ^ faceNorm;
+    normSize = plnNorm.Magnitude();
+    if ( normSize <= tol ) return false; // point coincides with the first node
+    plnNorm /= normSize;
+    // for each node of the face, compute its signed distance to the plane
+    vector<double> dist( nbNodes + 1);
+    for ( i = 0; i < nbNodes; ++i )
+    {
+      gp_Vec n2p( xyz[i], point );
+      dist[i] = n2p * plnNorm;
+    }
+    dist.back() = dist.front();
+    // find the closest intersection
+    int    iClosest = -1;
+    double rClosest, distClosest = 1e100;;
+    gp_Pnt pClosest;
+    for ( i = 0; i < nbNodes; ++i )
+    {
+      double r;
+      if ( fabs( dist[i]) < tol )
+        r = 0.;
+      else if ( fabs( dist[i+1]) < tol )
+        r = 1.;
+      else if ( dist[i] * dist[i+1] < 0 )
+        r = dist[i] / ( dist[i] - dist[i+1] );
+      else
+        continue; // no intersection
+      gp_Pnt pInt = xyz[i] * (1.-r) + xyz[i+1] * r;
+      gp_Vec p2int ( point, pInt);
+      if ( p2int * ray > -tol ) // right half-space
+      {
+        double intDist = p2int.SquareMagnitude();
+        if ( intDist < distClosest )
+        {
+          iClosest = i;
+          rClosest = r;
+          pClosest = pInt;
+          distClosest = intDist;
+        }
+      }
+    }
+    if ( iClosest < 0 )
+      return true; // no intesections - out
+
+    // analyse transition
+    gp_Vec edge( xyz[iClosest], xyz[iClosest+1] );
+    gp_Vec edgeNorm = -( edge ^ faceNorm ); // normal to intersected edge pointing out of face
+    gp_Vec p2int ( point, pClosest );
+    bool out = (edgeNorm * p2int) < -tol;
+    if ( rClosest > 0. && rClosest < 1. ) // not node intersection
+      return out;
+
+    // ray pass through a face node; analyze transition through an adjacent edge
+    gp_Pnt p1 = xyz[ (rClosest == 0.) ? ((iClosest+nbNodes-1) % nbNodes) : (iClosest+1) ];
+    gp_Pnt p2 = xyz[ (rClosest == 0.) ? iClosest : ((iClosest+2) % nbNodes) ];
+    gp_Vec edgeAdjacent( p1, p2 );
+    gp_Vec edgeNorm2 = -( edgeAdjacent ^ faceNorm );
+    bool out2 = (edgeNorm2 * p2int) < -tol;
+
+    bool covexCorner = ( edgeNorm * edgeAdjacent * (rClosest==1. ? 1. : -1.)) < 0;
+    return covexCorner ? (out || out2) : (out && out2);
+  }
+  if ( element->GetType() == SMDSAbs_Edge ) // --------------------------------------------------
+  {
+    // point is out of edge if it is NOT ON any straight part of edge
+    // (we consider quadratic edge as being composed of two straight parts)
+    for ( i = 1; i < nbNodes; ++i )
+    {
+      gp_Vec edge( xyz[i-1], xyz[i]);
+      gp_Vec n1p ( xyz[i-1], point);
+      double dist = ( edge ^ n1p ).Magnitude() / edge.Magnitude();
+      if ( dist > tol )
+        continue;
+      gp_Vec n2p( xyz[i], point );
+      if ( fabs( edge.Magnitude() - n1p.Magnitude() - n2p.Magnitude()) > tol )
+        continue;
+      return false; // point is ON this part
+    }
+    return true;
+  }
+  // Node or 0D element -------------------------------------------------------------------------
+  {
+    gp_Vec n2p ( xyz[0], point );
+    return n2p.Magnitude() <= tol;
+  }
+  return true;
+}
+
+//=======================================================================
+
+namespace
+{
+  // Position of a point relative to a segment
+  //            .           .
+  //            .  LEFT     .
+  //            .           .
+  //  VERTEX 1  o----ON----->  VERTEX 2
+  //            .           .
+  //            .  RIGHT    .
+  //            .           .
+  enum PositionName { POS_LEFT = 1, POS_VERTEX = 2, POS_RIGHT = 4, //POS_ON = 8,
+                      POS_ALL = POS_LEFT | POS_RIGHT | POS_VERTEX };
+  struct PointPos
+  {
+    PositionName _name; 
+    int          _index; // index of vertex or segment
+
+    PointPos( PositionName n, int i=-1 ): _name(n), _index(i) {}
+    bool operator < (const PointPos& other ) const
+    {
+      if ( _name == other._name )
+        return  ( _index < 0 || other._index < 0 ) ? false : _index < other._index;
+      return _name < other._name;
+    }
+  };
+
+  //================================================================================
+  /*!
+   * \brief Return of a point relative to a segment
+   *  \param point2D      - the point to analyze position of
+   *  \param xyVec        - end points of segments
+   *  \param index0       - 0-based index of the first point of segment
+   *  \param posToFindOut - flags of positions to detect
+   *  \retval PointPos - point position
+   */
+  //================================================================================
+
+  PointPos getPointPosition( const gp_XY& point2D,
+                             const gp_XY* segEnds,
+                             const int    index0 = 0,
+                             const int    posToFindOut = POS_ALL)
+  {
+    const gp_XY& p1 = segEnds[ index0   ];
+    const gp_XY& p2 = segEnds[ index0+1 ];
+    const gp_XY grad = p2 - p1;
+
+    if ( posToFindOut & POS_VERTEX )
+    {
+      // check if the point2D is at "vertex 1" zone
+      gp_XY pp1[2] = { p1, gp_XY( p1.X() - grad.Y(),
+                                  p1.Y() + grad.X() ) };
+      if ( getPointPosition( point2D, pp1, 0, POS_LEFT|POS_RIGHT )._name == POS_LEFT )
+        return PointPos( POS_VERTEX, index0 );
+
+      // check if the point2D is at "vertex 2" zone
+      gp_XY pp2[2] = { p2, gp_XY( p2.X() - grad.Y(),
+                                  p2.Y() + grad.X() ) };
+      if ( getPointPosition( point2D, pp2, 0, POS_LEFT|POS_RIGHT )._name == POS_RIGHT )
+        return PointPos( POS_VERTEX, index0 + 1);
+    }
+    double edgeEquation =
+      ( point2D.X() - p1.X() ) * grad.Y() - ( point2D.Y() - p1.Y() ) * grad.X();
+    return PointPos( edgeEquation < 0 ? POS_LEFT : POS_RIGHT, index0 );
+  }
+}
+
+//=======================================================================
+/*!
+ * \brief Return minimal distance from a point to a face
+ *
+ * Currently we ignore non-planarity and 2nd order of face
+ */
+//=======================================================================
+
+double SMESH_MeshEditor::GetDistance( const SMDS_MeshFace* face,
+                                      const gp_Pnt&        point )
+{
+  double badDistance = -1;
+  if ( !face ) return badDistance;
+
+  // coordinates of nodes (medium nodes, if any, ignored)
+  typedef SMDS_StdIterator< SMESH_TNodeXYZ, SMDS_ElemIteratorPtr > TXyzIterator;
+  vector<gp_XYZ> xyz( TXyzIterator( face->nodesIterator()), TXyzIterator() );
+  xyz.resize( face->NbCornerNodes()+1 );
+
+  // transformation to get xyz[0] lies on the origin, xyz[1] lies on the Z axis,
+  // and xyz[2] lies in the XZ plane. This is to pass to 2D space on XZ plane.
+  gp_Trsf trsf;
+  gp_Vec OZ ( xyz[0], xyz[1] );
+  gp_Vec OX ( xyz[0], xyz[2] );
+  if ( OZ.Magnitude() < std::numeric_limits<double>::min() )
+  {
+    if ( xyz.size() < 4 ) return badDistance;
+    OZ = gp_Vec ( xyz[0], xyz[2] );
+    OX = gp_Vec ( xyz[0], xyz[3] );
+  }
+  gp_Ax3 tgtCS;
+  try {
+    tgtCS = gp_Ax3( xyz[0], OZ, OX );
+  }
+  catch ( Standard_Failure ) {
+    return badDistance;
+  }
+  trsf.SetTransformation( tgtCS );
+
+  // move all the nodes to 2D
+  vector<gp_XY> xy( xyz.size() );
+  for ( size_t i = 0;i < xyz.size()-1; ++i )
+  {
+    gp_XYZ p3d = xyz[i];
+    trsf.Transforms( p3d );
+    xy[i].SetCoord( p3d.X(), p3d.Z() );
+  }
+  xyz.back() = xyz.front();
+  xy.back() = xy.front();
+
+  // // move the point in 2D
+  gp_XYZ tmpPnt = point.XYZ();
+  trsf.Transforms( tmpPnt );
+  gp_XY point2D( tmpPnt.X(), tmpPnt.Z() );
+
+  // loop on segments of the face to analyze point position ralative to the face
+  set< PointPos > pntPosSet;
+  for ( size_t i = 1; i < xy.size(); ++i )
+  {
+    PointPos pos = getPointPosition( point2D, &xy[0], i-1 );
+    pntPosSet.insert( pos );
+  }
+
+  // compute distance
+  PointPos pos = *pntPosSet.begin();
+  // cout << "Face " << face->GetID() << " DIST: ";
+  switch ( pos._name )
+  {
+  case POS_LEFT: {
+    // point is most close to a segment
+    gp_Vec p0p1( point, xyz[ pos._index ] );
+    gp_Vec p1p2( xyz[ pos._index ], xyz[ pos._index+1 ]); // segment vector
+    p1p2.Normalize();
+    double projDist = p0p1 * p1p2; // distance projected to the segment
+    gp_Vec projVec = p1p2 * projDist;
+    gp_Vec distVec = p0p1 - projVec;
+    // cout << distVec.Magnitude()  << ", SEG " << face->GetNode(pos._index)->GetID()
+    //      << " - " << face->GetNodeWrap(pos._index+1)->GetID() << endl;
+    return distVec.Magnitude();
+  }
+  case POS_RIGHT: {
+    // point is inside the face
+    double distToFacePlane = tmpPnt.Y();
+    // cout << distToFacePlane << ", INSIDE " << endl;
+    return Abs( distToFacePlane );
+  }
+  case POS_VERTEX: {
+    // point is most close to a node
+    gp_Vec distVec( point, xyz[ pos._index ]);
+    // cout << distVec.Magnitude()  << " VERTEX " << face->GetNode(pos._index)->GetID() << endl;
+    return distVec.Magnitude();
+  }
+  }
+  return badDistance;
+}
+
+//=======================================================================
+//function : SimplifyFace
+//purpose  :
+//=======================================================================
+int SMESH_MeshEditor::SimplifyFace (const vector<const SMDS_MeshNode *> faceNodes,
+                                    vector<const SMDS_MeshNode *>&      poly_nodes,
+                                    vector<int>&                        quantities) const
+{
+  int nbNodes = faceNodes.size();
+
+  if (nbNodes < 3)
+    return 0;
+
+  set<const SMDS_MeshNode*> nodeSet;
+
+  // get simple seq of nodes
+  //const SMDS_MeshNode* simpleNodes[ nbNodes ];
+  vector<const SMDS_MeshNode*> simpleNodes( nbNodes );
+  int iSimple = 0, nbUnique = 0;
+
+  simpleNodes[iSimple++] = faceNodes[0];
+  nbUnique++;
+  for (int iCur = 1; iCur < nbNodes; iCur++) {
+    if (faceNodes[iCur] != simpleNodes[iSimple - 1]) {
+      simpleNodes[iSimple++] = faceNodes[iCur];
+      if (nodeSet.insert( faceNodes[iCur] ).second)
+        nbUnique++;
+    }
+  }
+  int nbSimple = iSimple;
+  if (simpleNodes[nbSimple - 1] == simpleNodes[0]) {
+    nbSimple--;
+    iSimple--;
+  }
+
+  if (nbUnique < 3)
+    return 0;
+
+  // separate loops
+  int nbNew = 0;
+  bool foundLoop = (nbSimple > nbUnique);
+  while (foundLoop) {
+    foundLoop = false;
+    set<const SMDS_MeshNode*> loopSet;
+    for (iSimple = 0; iSimple < nbSimple && !foundLoop; iSimple++) {
+      const SMDS_MeshNode* n = simpleNodes[iSimple];
+      if (!loopSet.insert( n ).second) {
+        foundLoop = true;
+
+        // separate loop
+        int iC = 0, curLast = iSimple;
+        for (; iC < curLast; iC++) {
+          if (simpleNodes[iC] == n) break;
+        }
+        int loopLen = curLast - iC;
+        if (loopLen > 2) {
+          // create sub-element
+          nbNew++;
+          quantities.push_back(loopLen);
+          for (; iC < curLast; iC++) {
+            poly_nodes.push_back(simpleNodes[iC]);
+          }
+        }
+        // shift the rest nodes (place from the first loop position)
+        for (iC = curLast + 1; iC < nbSimple; iC++) {
+          simpleNodes[iC - loopLen] = simpleNodes[iC];
+        }
+        nbSimple -= loopLen;
+        iSimple -= loopLen;
+      }
+    } // for (iSimple = 0; iSimple < nbSimple; iSimple++)
+  } // while (foundLoop)
+
+  if (iSimple > 2) {
+    nbNew++;
+    quantities.push_back(iSimple);
+    for (int i = 0; i < iSimple; i++)
+      poly_nodes.push_back(simpleNodes[i]);
+  }
+
+  return nbNew;
+}
+
+//=======================================================================
+//function : MergeNodes
+//purpose  : In each group, the cdr of nodes are substituted by the first one
+//           in all elements.
+//=======================================================================
+
+void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
+{
+  MESSAGE("MergeNodes");
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
+
+  SMESHDS_Mesh* aMesh = GetMeshDS();
+
+  TNodeNodeMap nodeNodeMap; // node to replace - new node
+  set<const SMDS_MeshElement*> elems; // all elements with changed nodes
+  list< int > rmElemIds, rmNodeIds;
+
+  // Fill nodeNodeMap and elems
+
+  TListOfListOfNodes::iterator grIt = theGroupsOfNodes.begin();
+  for ( ; grIt != theGroupsOfNodes.end(); grIt++ ) {
+    list<const SMDS_MeshNode*>& nodes = *grIt;
+    list<const SMDS_MeshNode*>::iterator nIt = nodes.begin();
+    const SMDS_MeshNode* nToKeep = *nIt;
+    //MESSAGE("node to keep " << nToKeep->GetID());
+    for ( ++nIt; nIt != nodes.end(); nIt++ ) {
+      const SMDS_MeshNode* nToRemove = *nIt;
+      nodeNodeMap.insert( TNodeNodeMap::value_type( nToRemove, nToKeep ));
+      if ( nToRemove != nToKeep ) {
+        //MESSAGE("  node to remove " << nToRemove->GetID());
+        rmNodeIds.push_back( nToRemove->GetID() );
+        AddToSameGroups( nToKeep, nToRemove, aMesh );
+      }
+
+      SMDS_ElemIteratorPtr invElemIt = nToRemove->GetInverseElementIterator();
+      while ( invElemIt->more() ) {
+        const SMDS_MeshElement* elem = invElemIt->next();
+        elems.insert(elem);
+      }
+    }
+  }
+  // Change element nodes or remove an element
+
+  set<const SMDS_MeshElement*>::iterator eIt = elems.begin();
+  for ( ; eIt != elems.end(); eIt++ ) {
+    const SMDS_MeshElement* elem = *eIt;
+    //MESSAGE(" ---- inverse elem on node to remove " << elem->GetID());
+    int nbNodes = elem->NbNodes();
+    int aShapeId = FindShape( elem );
+
+    set<const SMDS_MeshNode*> nodeSet;
+    vector< const SMDS_MeshNode*> curNodes( nbNodes ), uniqueNodes( nbNodes );
+    int iUnique = 0, iCur = 0, nbRepl = 0;
+    vector<int> iRepl( nbNodes );
+
+    // get new seq of nodes
+    SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+    while ( itN->more() ) {
+      const SMDS_MeshNode* n =
+        static_cast<const SMDS_MeshNode*>( itN->next() );
+
+      TNodeNodeMap::iterator nnIt = nodeNodeMap.find( n );
+      if ( nnIt != nodeNodeMap.end() ) { // n sticks
+        n = (*nnIt).second;
+        // BUG 0020185: begin
+        {
+          bool stopRecur = false;
+          set<const SMDS_MeshNode*> nodesRecur;
+          nodesRecur.insert(n);
+          while (!stopRecur) {
+            TNodeNodeMap::iterator nnIt_i = nodeNodeMap.find( n );
+            if ( nnIt_i != nodeNodeMap.end() ) { // n sticks
+              n = (*nnIt_i).second;
+              if (!nodesRecur.insert(n).second) {
+                // error: recursive dependancy
+                stopRecur = true;
+              }
+            }
+            else
+              stopRecur = true;
+          }
+        }
+        // BUG 0020185: end
       }
       curNodes[ iCur ] = n;
       bool isUnique = nodeSet.insert( n ).second;
       if ( isUnique )
         uniqueNodes[ iUnique++ ] = n;
+      else
+        iRepl[ nbRepl++ ] = iCur;
       iCur++;
     }
 
@@ -4859,6 +7565,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
 
     bool isOk = true;
     int nbUniqueNodes = nodeSet.size();
+    //MESSAGE("nbNodes nbUniqueNodes " << nbNodes << " " << nbUniqueNodes);
     if ( nbNodes != nbUniqueNodes ) { // some nodes stick
       // Polygons and Polyhedral volumes
       if (elem->IsPoly()) {
@@ -4874,10 +7581,9 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
           vector<const SMDS_MeshNode *> polygons_nodes;
           vector<int> quantities;
           int nbNew = SimplifyFace(face_nodes, polygons_nodes, quantities);
-
           if (nbNew > 0) {
             inode = 0;
-            for (int iface = 0; iface < nbNew - 1; iface++) {
+            for (int iface = 0; iface < nbNew; iface++) {
               int nbNodes = quantities[iface];
               vector<const SMDS_MeshNode *> poly_nodes (nbNodes);
               for (int ii = 0; ii < nbNodes; ii++, inode++) {
@@ -4888,7 +7594,19 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
               if (aShapeId)
                 aMesh->SetMeshElementOnShape(newElem, aShapeId);
             }
-            aMesh->ChangeElementNodes(elem, &polygons_nodes[inode], quantities[nbNew - 1]);
+
+            MESSAGE("ChangeElementNodes MergeNodes Polygon");
+            //aMesh->ChangeElementNodes(elem, &polygons_nodes[inode], quantities[nbNew - 1]);
+            vector<const SMDS_MeshNode *> polynodes(polygons_nodes.begin()+inode,polygons_nodes.end());
+            int quid =0;
+            if (nbNew > 0) quid = nbNew - 1;
+            vector<int> newquant(quantities.begin()+quid, quantities.end());
+            const SMDS_MeshElement* newElem = 0;
+            newElem = aMesh->AddPolyhedralVolume(polynodes, newquant);
+            myLastCreatedElems.Append(newElem);
+            if ( aShapeId && newElem )
+              aMesh->SetMeshElementOnShape( newElem, aShapeId );
+            rmElemIds.push_back(elem->GetID());
           }
           else {
             rmElemIds.push_back(elem->GetID());
@@ -4901,9 +7619,9 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
             rmElemIds.push_back(elem->GetID());
           }
           else {
-            // each face has to be analized in order to check volume validity
-            const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
-              static_cast<const SMDS_PolyhedralVolumeOfNodes*>( elem );
+            // each face has to be analyzed in order to check volume validity
+            const SMDS_VtkVolume* aPolyedre =
+              dynamic_cast<const SMDS_VtkVolume*>( elem );
             if (aPolyedre) {
               int nbFaces = aPolyedre->NbFaces();
 
@@ -4931,10 +7649,16 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
               }
 
               if (quantities.size() > 3)
-                aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities);
-              else
-                rmElemIds.push_back(elem->GetID());
-
+                {
+                  MESSAGE("ChangeElementNodes MergeNodes Polyhedron");
+                  //aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities);
+                  const SMDS_MeshElement* newElem = 0;
+                  newElem = aMesh->AddPolyhedralVolume(poly_nodes, quantities);
+                  myLastCreatedElems.Append(newElem);
+                  if ( aShapeId && newElem )
+                    aMesh->SetMeshElementOnShape( newElem, aShapeId );
+                  rmElemIds.push_back(elem->GetID());
+                }
             }
             else {
               rmElemIds.push_back(elem->GetID());
@@ -4945,9 +7669,10 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
         }
 
         continue;
-      }
+      } // poly element
 
       // Regular elements
+      // TODO not all the possible cases are solved. Find something more generic?
       switch ( nbNodes ) {
       case 2: ///////////////////////////////////// EDGE
         isOk = false; break;
@@ -4961,6 +7686,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
             isOk = false;
           else if ( nbRepl == 2 && iRepl[ 1 ] - iRepl[ 0 ] == 2 )
             isOk = false; // opposite nodes stick
+          //MESSAGE("isOk " << isOk);
         }
         break;
       case 6: ///////////////////////////////////// PENTAHEDRON
@@ -5025,7 +7751,11 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
           //    +---+---+
           //   0    7    3
           isOk = false;
+          if(nbRepl==2) {
+            MESSAGE("nbRepl=2: " << iRepl[0] << " " << iRepl[1]);
+          }
           if(nbRepl==3) {
+            MESSAGE("nbRepl=3: " << iRepl[0] << " " << iRepl[1]  << " " << iRepl[2]);
             nbUniqueNodes = 6;
             if( iRepl[0]==0 && iRepl[1]==1 && iRepl[2]==4 ) {
               uniqueNodes[0] = curNodes[0];
@@ -5100,14 +7830,20 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
               isOk = true;
             }
           }
+          if(nbRepl==4) {
+            MESSAGE("nbRepl=4: " << iRepl[0] << " " << iRepl[1]  << " " << iRepl[2] << " " << iRepl[3]);
+          }
+          if(nbRepl==5) {
+            MESSAGE("nbRepl=5: " << iRepl[0] << " " << iRepl[1]  << " " << iRepl[2] << " " << iRepl[3] << " " << iRepl[4]);
+          }
           break;
         }
         //////////////////////////////////// HEXAHEDRON
         isOk = false;
         SMDS_VolumeTool hexa (elem);
         hexa.SetExternalNormal();
-        if ( nbUniqueNodes == 4 && nbRepl == 6 ) {
-          //////////////////////// ---> tetrahedron
+        if ( nbUniqueNodes == 4 && nbRepl == 4 ) {
+          //////////////////////// HEX ---> 1 tetrahedron
           for ( int iFace = 0; iFace < 6; iFace++ ) {
             const int *ind = hexa.GetFaceNodesIndices( iFace ); // indices of face nodes
             if (curNodes[ind[ 0 ]] == curNodes[ind[ 1 ]] &&
@@ -5117,12 +7853,9 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
               int iOppFace = hexa.GetOppFaceIndex( iFace );
               ind = hexa.GetFaceNodesIndices( iOppFace );
               int nbStick = 0;
-              iUnique = 2; // reverse a tetrahedron bottom
               for ( iCur = 0; iCur < 4 && nbStick < 2; iCur++ ) {
                 if ( curNodes[ind[ iCur ]] == curNodes[ind[ iCur + 1 ]] )
                   nbStick++;
-                else if ( iUnique >= 0 )
-                  uniqueNodes[ iUnique-- ] = curNodes[ind[ iCur ]];
               }
               if ( nbStick == 1 ) {
                 // ... and the opposite one - into a triangle.
@@ -5135,6 +7868,45 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
             }
           }
         }
+        else if ( nbUniqueNodes == 6 && nbRepl == 2 ) {
+          //////////////////////// HEX ---> 1 prism
+          int nbTria = 0, iTria[3];
+          const int *ind; // indices of face nodes
+          // look for triangular faces
+          for ( int iFace = 0; iFace < 6 && nbTria < 3; iFace++ ) {
+            ind = hexa.GetFaceNodesIndices( iFace );
+            TIDSortedNodeSet faceNodes;
+            for ( iCur = 0; iCur < 4; iCur++ )
+              faceNodes.insert( curNodes[ind[iCur]] );
+            if ( faceNodes.size() == 3 )
+              iTria[ nbTria++ ] = iFace;
+          }
+          // check if triangles are opposite
+          if ( nbTria == 2 && iTria[0] == hexa.GetOppFaceIndex( iTria[1] ))
+          {
+            isOk = true;
+            // set nodes of the bottom triangle
+            ind = hexa.GetFaceNodesIndices( iTria[ 0 ]);
+            vector<int> indB;
+            for ( iCur = 0; iCur < 4; iCur++ )
+              if ( ind[iCur] != iRepl[0] && ind[iCur] != iRepl[1])
+                indB.push_back( ind[iCur] );
+            if ( !hexa.IsForward() )
+              std::swap( indB[0], indB[2] );
+            for ( iCur = 0; iCur < 3; iCur++ )
+              uniqueNodes[ iCur ] = curNodes[indB[iCur]];
+            // set nodes of the top triangle
+            const int *indT = hexa.GetFaceNodesIndices( iTria[ 1 ]);
+            for ( iCur = 0; iCur < 3; ++iCur )
+              for ( int j = 0; j < 4; ++j )
+                if ( hexa.IsLinked( indB[ iCur ], indT[ j ] ))
+                {
+                  uniqueNodes[ iCur + 3 ] = curNodes[ indT[ j ]];
+                  break;
+                }
+          }
+          break;
+        }
         else if (nbUniqueNodes == 5 && nbRepl == 4 ) {
           //////////////////// HEXAHEDRON ---> 2 tetrahedrons
           for ( int iFace = 0; iFace < 6; iFace++ ) {
@@ -5272,6 +8044,10 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
             }
           }
         } // if ( nbUniqueNodes == 6 && nbRepl == 4 )
+        else
+        {
+          MESSAGE("MergeNodes() removes hexahedron "<< elem);
+        }
         break;
       } // HEXAHEDRON
 
@@ -5281,11 +8057,12 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
 
     } // if ( nbNodes != nbUniqueNodes ) // some nodes stick
 
-    if ( isOk ) {
-      if (elem->IsPoly() && elem->GetType() == SMDSAbs_Volume) {
+    if ( isOk ) { // the elem remains valid after sticking nodes
+      if (elem->IsPoly() && elem->GetType() == SMDSAbs_Volume)
+      {
         // Change nodes of polyedre
-        const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
-          static_cast<const SMDS_PolyhedralVolumeOfNodes*>( elem );
+        const SMDS_VtkVolume* aPolyedre =
+          dynamic_cast<const SMDS_VtkVolume*>( elem );
         if (aPolyedre) {
           int nbFaces = aPolyedre->NbFaces();
 
@@ -5309,9 +8086,21 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
           aMesh->ChangePolyhedronNodes( elem, poly_nodes, quantities );
         }
       }
-      else {
-        // Change regular element or polygon
-        aMesh->ChangeElementNodes( elem, & uniqueNodes[0], nbUniqueNodes );
+      else // replace non-polyhedron elements
+      {
+        const SMDSAbs_ElementType etyp = elem->GetType();
+        const int elemId               = elem->GetID();
+        const bool isPoly              = (elem->GetEntityType() == SMDSEntity_Polygon);
+        uniqueNodes.resize(nbUniqueNodes);
+
+        SMESHDS_SubMesh * sm = aShapeId > 0 ? aMesh->MeshElements(aShapeId) : 0;
+
+        aMesh->RemoveFreeElement(elem, sm, /*fromGroups=*/false);
+        SMDS_MeshElement* newElem = this->AddElement(uniqueNodes, etyp, isPoly, elemId);
+        if ( sm && newElem )
+          sm->AddElement( newElem );
+        if ( elem != newElem )
+          ReplaceElemInGroups( elem, newElem, aMesh );
       }
     }
     else {
@@ -5321,10 +8110,10 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
 
   } // loop on elements
 
-  // Remove equal nodes and bad elements
+  // Remove bad elements, then equal nodes (order important)
 
-  Remove( rmNodeIds, true );
   Remove( rmElemIds, false );
+  Remove( rmNodeIds, true );
 
 }
 
@@ -5335,24 +8124,24 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
 // ========================================================
 class SortableElement : public set <const SMDS_MeshElement*>
 {
- public:
+public:
 
   SortableElement( const SMDS_MeshElement* theElem )
-    {
-      myElem = theElem;
-      SMDS_ElemIteratorPtr nodeIt = theElem->nodesIterator();
-      while ( nodeIt->more() )
-        this->insert( nodeIt->next() );
-    }
+  {
+    myElem = theElem;
+    SMDS_ElemIteratorPtr nodeIt = theElem->nodesIterator();
+    while ( nodeIt->more() )
+      this->insert( nodeIt->next() );
+  }
 
   const SMDS_MeshElement* Get() const
-    { return myElem; }
+  { return myElem; }
 
   void Set(const SMDS_MeshElement* e) const
-    { myElem = e; }
+  { myElem = e; }
 
 
- private:
+private:
   mutable const SMDS_MeshElement* myElem;
 };
 
@@ -5362,7 +8151,7 @@ class SortableElement : public set <const SMDS_MeshElement*>
 //           Search among theElements or in the whole mesh if theElements is empty
 //=======================================================================
 void SMESH_MeshEditor::FindEqualElements(set<const SMDS_MeshElement*> & theElements,
-                                        TListOfListOfElementsID &      theGroupsOfElementsID)
+                                         TListOfListOfElementsID &      theGroupsOfElementsID)
 {
   myLastCreatedElems.Clear();
   myLastCreatedNodes.Clear();
@@ -5460,7 +8249,7 @@ void SMESH_MeshEditor::MergeElements(TListOfListOfElementsID & theGroupsOfElemen
 void SMESH_MeshEditor::MergeEqualElements()
 {
   set<const SMDS_MeshElement*> aMeshElements; /* empty input -
-                                                to merge equal elements in the whole mesh */
+                                                 to merge equal elements in the whole mesh */
   TListOfListOfElementsID aGroupsOfElementsID;
   FindEqualElements(aMeshElements, aGroupsOfElementsID);
   MergeElements(aGroupsOfElementsID);
@@ -5471,83 +8260,68 @@ void SMESH_MeshEditor::MergeEqualElements()
 //purpose  : Return a face having linked nodes n1 and n2 and which is
 //           - not in avoidSet,
 //           - in elemSet provided that !elemSet.empty()
+//           i1 and i2 optionally returns indices of n1 and n2
 //=======================================================================
 
 const SMDS_MeshElement*
-  SMESH_MeshEditor::FindFaceInSet(const SMDS_MeshNode*    n1,
-                                  const SMDS_MeshNode*    n2,
-                                  const TIDSortedElemSet& elemSet,
-                                  const TIDSortedElemSet& avoidSet)
+SMESH_MeshEditor::FindFaceInSet(const SMDS_MeshNode*    n1,
+                                const SMDS_MeshNode*    n2,
+                                const TIDSortedElemSet& elemSet,
+                                const TIDSortedElemSet& avoidSet,
+                                int*                    n1ind,
+                                int*                    n2ind)
 
 {
+  int i1, i2;
+  const SMDS_MeshElement* face = 0;
+
   SMDS_ElemIteratorPtr invElemIt = n1->GetInverseElementIterator(SMDSAbs_Face);
-  while ( invElemIt->more() ) { // loop on inverse elements of n1
+  //MESSAGE("n1->GetInverseElementIterator(SMDSAbs_Face) " << invElemIt);
+  while ( invElemIt->more() && !face ) // loop on inverse faces of n1
+  {
+    //MESSAGE("in while ( invElemIt->more() && !face )");
     const SMDS_MeshElement* elem = invElemIt->next();
-    if (avoidSet.find( elem ) != avoidSet.end() )
+    if (avoidSet.count( elem ))
       continue;
-    if ( !elemSet.empty() && elemSet.find( elem ) == elemSet.end())
+    if ( !elemSet.empty() && !elemSet.count( elem ))
       continue;
-    // get face nodes and find index of n1
-    int i1, nbN = elem->NbNodes(), iNode = 0;
-    //const SMDS_MeshNode* faceNodes[ nbN ], *n;
-    vector<const SMDS_MeshNode*> faceNodes( nbN );
-    const SMDS_MeshNode* n;
-    SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
-    while ( nIt->more() ) {
-      faceNodes[ iNode ] = static_cast<const SMDS_MeshNode*>( nIt->next() );
-      if ( faceNodes[ iNode++ ] == n1 )
-        i1 = iNode - 1;
-    }
+    // index of n1
+    i1 = elem->GetNodeIndex( n1 );
     // find a n2 linked to n1
-    if(!elem->IsQuadratic()) {
-      for ( iNode = 0; iNode < 2; iNode++ ) {
-        if ( iNode ) // node before n1
-          n = faceNodes[ i1 == 0 ? nbN - 1 : i1 - 1 ];
-        else         // node after n1
-          n = faceNodes[ i1 + 1 == nbN ? 0 : i1 + 1 ];
-        if ( n == n2 )
-          return elem;
-      }
-    }
-    else { // analysis for quadratic elements
-      bool IsFind = false;
-      // check using only corner nodes
-      for ( iNode = 0; iNode < 2; iNode++ ) {
-        if ( iNode ) // node before n1
-          n = faceNodes[ i1 == 0 ? nbN/2 - 1 : i1 - 1 ];
-        else         // node after n1
-          n = faceNodes[ i1 + 1 == nbN/2 ? 0 : i1 + 1 ];
-        if ( n == n2 )
-          IsFind = true;
-      }
-      if(IsFind) {
-        return elem;
-      }
-      else {
-        // check using all nodes
-        const SMDS_QuadraticFaceOfNodes* F =
-          static_cast<const SMDS_QuadraticFaceOfNodes*>(elem);
-        // use special nodes iterator
-        iNode = 0;
-        SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
-        while ( anIter->more() ) {
-          faceNodes[iNode] = static_cast<const SMDS_MeshNode*>(anIter->next());
-          if ( faceNodes[ iNode++ ] == n1 )
-            i1 = iNode - 1;
-        }
-        for ( iNode = 0; iNode < 2; iNode++ ) {
-          if ( iNode ) // node before n1
-            n = faceNodes[ i1 == 0 ? nbN - 1 : i1 - 1 ];
-          else         // node after n1
-            n = faceNodes[ i1 + 1 == nbN ? 0 : i1 + 1 ];
-          if ( n == n2 ) {
-            return elem;
-          }
+    int nbN = elem->IsQuadratic() ? elem->NbNodes()/2 : elem->NbNodes();
+    for ( int di = -1; di < 2 && !face; di += 2 )
+    {
+      i2 = (i1+di+nbN) % nbN;
+      if ( elem->GetNode( i2 ) == n2 )
+        face = elem;
+    }
+    if ( !face && elem->IsQuadratic())
+    {
+      // analysis for quadratic elements using all nodes
+      const SMDS_VtkFace* F =
+        dynamic_cast<const SMDS_VtkFace*>(elem);
+      if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace"));
+      // use special nodes iterator
+      SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator();
+      const SMDS_MeshNode* prevN = cast2Node( anIter->next() );
+      for ( i1 = -1, i2 = 0; anIter->more() && !face; i1++, i2++ )
+      {
+        const SMDS_MeshNode* n = cast2Node( anIter->next() );
+        if ( n1 == prevN && n2 == n )
+        {
+          face = elem;
+        }
+        else if ( n2 == prevN && n1 == n )
+        {
+          face = elem; swap( i1, i2 );
         }
+        prevN = n;
       }
-    } // end analysis for quadratic elements
+    }
   }
-  return 0;
+  if ( n1ind ) *n1ind = i1;
+  if ( n2ind ) *n2ind = i2;
+  return face;
 }
 
 //=======================================================================
@@ -5591,7 +8365,7 @@ bool SMESH_MeshEditor::FindFreeBorder (const SMDS_MeshNode*             theFirst
 
   //vector<const SMDS_MeshNode*> nodes;
   const SMDS_MeshNode *nIgnore = theFirstNode, *nStart = theSecondNode;
-  set < const SMDS_MeshElement* > foundElems;
+  TIDSortedElemSet foundElems;
   bool needTheLast = ( theLastNode != 0 );
 
   while ( nStart != theLastNode ) {
@@ -5610,14 +8384,15 @@ bool SMESH_MeshEditor::FindFreeBorder (const SMDS_MeshNode*             theFirst
         int iNode = 0, nbNodes = e->NbNodes();
         //const SMDS_MeshNode* nodes[nbNodes+1];
         vector<const SMDS_MeshNode*> nodes(nbNodes+1);
-        
+
         if(e->IsQuadratic()) {
-          const SMDS_QuadraticFaceOfNodes* F =
-            static_cast<const SMDS_QuadraticFaceOfNodes*>(e);
+          const SMDS_VtkFace* F =
+            dynamic_cast<const SMDS_VtkFace*>(e);
+          if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace"));
           // use special nodes iterator
-          SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+          SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator();
           while( anIter->more() ) {
-            nodes[ iNode++ ] = anIter->next();
+            nodes[ iNode++ ] = cast2Node(anIter->next());
           }
         }
         else {
@@ -5730,15 +8505,15 @@ bool SMESH_MeshEditor::CheckFreeBorderNodes(const SMDS_MeshNode* theNode1,
 //=======================================================================
 
 SMESH_MeshEditor::Sew_Error
-  SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode,
-                                   const SMDS_MeshNode* theBordSecondNode,
-                                   const SMDS_MeshNode* theBordLastNode,
-                                   const SMDS_MeshNode* theSideFirstNode,
-                                   const SMDS_MeshNode* theSideSecondNode,
-                                   const SMDS_MeshNode* theSideThirdNode,
-                                   const bool           theSideIsFreeBorder,
-                                   const bool           toCreatePolygons,
-                                   const bool           toCreatePolyedrs)
+SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode,
+                                 const SMDS_MeshNode* theBordSecondNode,
+                                 const SMDS_MeshNode* theBordLastNode,
+                                 const SMDS_MeshNode* theSideFirstNode,
+                                 const SMDS_MeshNode* theSideSecondNode,
+                                 const SMDS_MeshNode* theSideThirdNode,
+                                 const bool           theSideIsFreeBorder,
+                                 const bool           toCreatePolygons,
+                                 const bool           toCreatePolyedrs)
 {
   myLastCreatedElems.Clear();
   myLastCreatedNodes.Clear();
@@ -5787,7 +8562,7 @@ SMESH_MeshEditor::Sew_Error
     //    links of the free border
     // -------------------------------------------------------------------------
 
-    // 1. Since sewing may brake if there are volumes to split on the side 2,
+    // 1. Since sewing may break if there are volumes to split on the side 2,
     //    we wont move nodes but just compute new coordinates for them
     typedef map<const SMDS_MeshNode*, gp_XYZ> TNodeXYZMap;
     TNodeXYZMap nBordXYZ;
@@ -5885,12 +8660,13 @@ SMESH_MeshEditor::Sew_Error
         else if ( elem->GetType()==SMDSAbs_Face ) { // --face
           // retrieve all face nodes and find iPrevNode - an index of the prevSideNode
           if(elem->IsQuadratic()) {
-            const SMDS_QuadraticFaceOfNodes* F =
-              static_cast<const SMDS_QuadraticFaceOfNodes*>(elem);
+            const SMDS_VtkFace* F =
+              dynamic_cast<const SMDS_VtkFace*>(elem);
+            if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace"));
             // use special nodes iterator
-            SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+            SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator();
             while( anIter->more() ) {
-              nodes[ iNode ] = anIter->next();
+              nodes[ iNode ] = cast2Node(anIter->next());
               if ( nodes[ iNode++ ] == prevSideNode )
                 iPrevNode = iNode - 1;
             }
@@ -5992,7 +8768,7 @@ SMESH_MeshEditor::Sew_Error
 
   TListOfListOfNodes nodeGroupsToMerge;
   if ( nbNodes[0] == nbNodes[1] ||
-      ( theSideIsFreeBorder && !theSideThirdNode)) {
+       ( theSideIsFreeBorder && !theSideThirdNode)) {
 
     // all nodes are to be merged
 
@@ -6204,12 +8980,13 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
   vector<const SMDS_MeshNode*> nodes( theFace->NbNodes() );
 
   if(theFace->IsQuadratic()) {
-    const SMDS_QuadraticFaceOfNodes* F =
-      static_cast<const SMDS_QuadraticFaceOfNodes*>(theFace);
+    const SMDS_VtkFace* F =
+      dynamic_cast<const SMDS_VtkFace*>(theFace);
+    if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace"));
     // use special nodes iterator
-    SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+    SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator();
     while( anIter->more() ) {
-      const SMDS_MeshNode* n = anIter->next();
+      const SMDS_MeshNode* n = cast2Node(anIter->next());
       if ( n == theBetweenNode1 )
         il1 = iNode;
       else if ( n == theBetweenNode2 )
@@ -6265,12 +9042,13 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
     bool isFLN = false;
 
     if(theFace->IsQuadratic()) {
-      const SMDS_QuadraticFaceOfNodes* F =
-        static_cast<const SMDS_QuadraticFaceOfNodes*>(theFace);
+      const SMDS_VtkFace* F =
+        dynamic_cast<const SMDS_VtkFace*>(theFace);
+      if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace"));
       // use special nodes iterator
-      SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+      SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator();
       while( anIter->more()  && !isFLN ) {
-        const SMDS_MeshNode* n = anIter->next();
+        const SMDS_MeshNode* n = cast2Node(anIter->next());
         poly_nodes[iNode++] = n;
         if (n == nodes[il1]) {
           isFLN = true;
@@ -6283,7 +9061,7 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
       }
       // add nodes of face starting from last node of link
       while ( anIter->more() ) {
-        poly_nodes[iNode++] = anIter->next();
+        poly_nodes[iNode++] = cast2Node(anIter->next());
       }
     }
     else {
@@ -6326,6 +9104,7 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
     return;
   }
 
+  SMESHDS_Mesh *aMesh = GetMeshDS();
   if( !theFace->IsQuadratic() ) {
 
     // put aNodesToInsert between theBetweenNode1 and theBetweenNode2
@@ -6376,7 +9155,6 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
     }
 
     // create new elements
-    SMESHDS_Mesh *aMesh = GetMeshDS();
     int aShapeId = FindShape( theFace );
 
     i1 = 0; i2 = 1;
@@ -6402,8 +9180,16 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
     newNodes[ 1 ] = linkNodes[ i2 ];
     newNodes[ 2 ] = nodes[ iSplit >= iBestQuad ? i3 : i4 ];
     newNodes[ 3 ] = nodes[ i4 ];
-    aMesh->ChangeElementNodes( theFace, newNodes, iSplit == iBestQuad ? 4 : 3 );
-  } // end if(!theFace->IsQuadratic())
+    //aMesh->ChangeElementNodes( theFace, newNodes, iSplit == iBestQuad ? 4 : 3 );
+    const SMDS_MeshElement* newElem = 0;
+    if (iSplit == iBestQuad)
+      newElem = aMesh->AddFace( newNodes[0], newNodes[1], newNodes[2], newNodes[3] );
+    else
+      newElem = aMesh->AddFace( newNodes[0], newNodes[1], newNodes[2] );
+    myLastCreatedElems.Append(newElem);
+    if ( aShapeId && newElem )
+      aMesh->SetMeshElementOnShape( newElem, aShapeId );
+} // end if(!theFace->IsQuadratic())
   else { // theFace is quadratic
     // we have to split theFace on simple triangles and one simple quadrangle
     int tmp = il1/2;
@@ -6430,7 +9216,6 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
     //           n4           n6      n5     n4
 
     // create new elements
-    SMESHDS_Mesh *aMesh = GetMeshDS();
     int aShapeId = FindShape( theFace );
 
     int n1,n2,n3;
@@ -6513,9 +9298,9 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
       if ( aShapeId && newElem )
         aMesh->SetMeshElementOnShape( newElem, aShapeId );
     }
-    // remove old quadratic face
-    aMesh->RemoveElement(theFace);
   }
+  // remove old face
+  aMesh->RemoveElement(theFace);
 }
 
 //=======================================================================
@@ -6604,10 +9389,34 @@ void SMESH_MeshEditor::UpdateVolumes (const SMDS_MeshNode*        theBetweenNode
   }
 }
 
+namespace
+{
+  //================================================================================
+  /*!
+   * \brief Transform any volume into data of SMDSEntity_Polyhedra
+   */
+  //================================================================================
+
+  void volumeToPolyhedron( const SMDS_MeshElement*         elem,
+                           vector<const SMDS_MeshNode *> & nodes,
+                           vector<int> &                   nbNodeInFaces )
+  {
+    nodes.clear();
+    nbNodeInFaces.clear();
+    SMDS_VolumeTool vTool ( elem );
+    for ( int iF = 0; iF < vTool.NbFaces(); ++iF )
+    {
+      const SMDS_MeshNode** fNodes = vTool.GetFaceNodes( iF );
+      nodes.insert( nodes.end(), fNodes, fNodes + vTool.NbFaceNodes( iF ));
+      nbNodeInFaces.push_back( vTool.NbFaceNodes( iF ));
+    }
+  }
+}
+
 //=======================================================================
 /*!
  * \brief Convert elements contained in a submesh to quadratic
- * \retval int - nb of checked elements
+ * \return int - nb of checked elements
  */
 //=======================================================================
 
@@ -6618,7 +9427,8 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh *   theSm,
   int nbElem = 0;
   if( !theSm ) return nbElem;
 
-  const bool notFromGroups = false;
+  vector<int> nbNodeInFaces;
+  vector<const SMDS_MeshNode *> nodes;
   SMDS_ElemIteratorPtr ElemItr = theSm->GetElements();
   while(ElemItr->more())
   {
@@ -6626,61 +9436,69 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh *   theSm,
     const SMDS_MeshElement* elem = ElemItr->next();
     if( !elem || elem->IsQuadratic() ) continue;
 
-    int id = elem->GetID();
-    int nbNodes = elem->NbNodes();
-    vector<const SMDS_MeshNode *> aNds (nbNodes);
-
-    for(int i = 0; i < nbNodes; i++)
-    {
-      aNds[i] = elem->GetNode(i);
-    }
-    SMDSAbs_ElementType aType = elem->GetType();
-
-    GetMeshDS()->RemoveFreeElement(elem, theSm, notFromGroups);
+    // get elem data needed to re-create it
+    //
+    const int id                        = elem->GetID();
+    const int nbNodes                   = elem->NbNodes();
+    const SMDSAbs_ElementType aType     = elem->GetType();
+    const SMDSAbs_EntityType  aGeomType = elem->GetEntityType();
+    nodes.assign(elem->begin_nodes(), elem->end_nodes());
+    if ( aGeomType == SMDSEntity_Polyhedra )
+      nbNodeInFaces = static_cast<const SMDS_VtkVolume* >( elem )->GetQuantities();
+    else if ( aGeomType == SMDSEntity_Hexagonal_Prism )
+      volumeToPolyhedron( elem, nodes, nbNodeInFaces );
+
+    // remove a linear element
+    GetMeshDS()->RemoveFreeElement(elem, theSm, /*fromGroups=*/false);
 
     const SMDS_MeshElement* NewElem = 0;
 
     switch( aType )
     {
     case SMDSAbs_Edge :
-    {
-      NewElem = theHelper.AddEdge(aNds[0], aNds[1], id, theForce3d);
-      break;
-    }
+      {
+        NewElem = theHelper.AddEdge(nodes[0], nodes[1], id, theForce3d);
+        break;
+      }
     case SMDSAbs_Face :
-    {
-      switch(nbNodes)
       {
-      case 3:
-       NewElem = theHelper.AddFace(aNds[0], aNds[1], aNds[2], id, theForce3d);
-       break;
-      case 4:
-       NewElem = theHelper.AddFace(aNds[0], aNds[1], aNds[2], aNds[3], id, theForce3d);
-       break;
-      default:
-       continue;
+        switch(nbNodes)
+        {
+        case 3:
+          NewElem = theHelper.AddFace(nodes[0], nodes[1], nodes[2], id, theForce3d);
+          break;
+        case 4:
+          NewElem = theHelper.AddFace(nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d);
+          break;
+        default:
+          NewElem = theHelper.AddPolygonalFace(nodes, id, theForce3d);
+          continue;
+        }
+        break;
       }
-      break;
-    }
     case SMDSAbs_Volume :
-    {
-      switch(nbNodes)
       {
-      case 4:
-       NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], id, theForce3d);
-       break;
-      case 6:
-       NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], aNds[4], aNds[5], id, theForce3d);
-       break;
-      case 8:
-       NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3],
-                                      aNds[4], aNds[5], aNds[6], aNds[7], id, theForce3d);
-       break;
-      default:
-       continue;
+        switch( aGeomType )
+        {
+        case SMDSEntity_Tetra:
+          NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d);
+          break;
+        case SMDSEntity_Pyramid:
+          NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], id, theForce3d);
+          break;
+        case SMDSEntity_Penta:
+          NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], nodes[5], id, theForce3d);
+          break;
+        case SMDSEntity_Hexa:
+          NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3],
+                                        nodes[4], nodes[5], nodes[6], nodes[7], id, theForce3d);
+          break;
+        case SMDSEntity_Hexagonal_Prism:
+        default:
+          NewElem = theHelper.AddPolyhedralVolume(nodes, nbNodeInFaces, id, theForce3d);
+        }
+        break;
       }
-      break;
-    }
     default :
       continue;
     }
@@ -6695,13 +9513,13 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh *   theSm,
 //function : ConvertToQuadratic
 //purpose  :
 //=======================================================================
+
 void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d)
 {
   SMESHDS_Mesh* meshDS = GetMeshDS();
 
   SMESH_MesherHelper aHelper(*myMesh);
   aHelper.SetIsQuadratic( true );
-  const bool notFromGroups = false;
 
   int nbCheckedElems = 0;
   if ( myMesh->HasShapeToMesh() )
@@ -6728,11 +9546,12 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d)
       const SMDS_MeshEdge* edge = aEdgeItr->next();
       if(edge && !edge->IsQuadratic())
       {
-       int id = edge->GetID();
-       const SMDS_MeshNode* n1 = edge->GetNode(0);
-       const SMDS_MeshNode* n2 = edge->GetNode(1);
+        int id = edge->GetID();
+        //MESSAGE("edge->GetID() " << id);
+        const SMDS_MeshNode* n1 = edge->GetNode(0);
+        const SMDS_MeshNode* n2 = edge->GetNode(1);
 
-       meshDS->RemoveFreeElement(edge, smDS, notFromGroups);
+        meshDS->RemoveFreeElement(edge, smDS, /*fromGroups=*/false);
 
         const SMDS_MeshEdge* NewEdge = aHelper.AddEdge(n1, n2, id, theForce3d);
         ReplaceElemInGroups( edge, NewEdge, GetMeshDS());
@@ -6744,75 +9563,220 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d)
       const SMDS_MeshFace* face = aFaceItr->next();
       if(!face || face->IsQuadratic() ) continue;
 
-      int id = face->GetID();
-      int nbNodes = face->NbNodes();
-      vector<const SMDS_MeshNode *> aNds (nbNodes);
+      const int id = face->GetID();
+      const SMDSAbs_EntityType type = face->GetEntityType();
+      vector<const SMDS_MeshNode *> nodes ( face->begin_nodes(), face->end_nodes());
+
+      meshDS->RemoveFreeElement(face, smDS, /*fromGroups=*/false);
+
+      SMDS_MeshFace * NewFace = 0;
+      switch( type )
+      {
+      case SMDSEntity_Triangle:
+        NewFace = aHelper.AddFace(nodes[0], nodes[1], nodes[2], id, theForce3d);
+        break;
+      case SMDSEntity_Quadrangle:
+        NewFace = aHelper.AddFace(nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d);
+        break;
+      default:
+        NewFace = aHelper.AddPolygonalFace(nodes, id, theForce3d);
+      }
+      ReplaceElemInGroups( face, NewFace, GetMeshDS());
+    }
+    vector<int> nbNodeInFaces;
+    SMDS_VolumeIteratorPtr aVolumeItr = meshDS->volumesIterator();
+    while(aVolumeItr->more())
+    {
+      const SMDS_MeshVolume* volume = aVolumeItr->next();
+      if(!volume || volume->IsQuadratic() ) continue;
+
+      const int id = volume->GetID();
+      const SMDSAbs_EntityType type = volume->GetEntityType();
+      vector<const SMDS_MeshNode *> nodes (volume->begin_nodes(), volume->end_nodes());
+      if ( type == SMDSEntity_Polyhedra )
+        nbNodeInFaces = static_cast<const SMDS_VtkVolume* >(volume)->GetQuantities();
+      else if ( type == SMDSEntity_Hexagonal_Prism )
+        volumeToPolyhedron( volume, nodes, nbNodeInFaces );
+
+      meshDS->RemoveFreeElement(volume, smDS, /*fromGroups=*/false);
+
+      SMDS_MeshVolume * NewVolume = 0;
+      switch ( type )
+      {
+      case SMDSEntity_Tetra:
+        NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d );
+        break;
+      case SMDSEntity_Hexa:
+        NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3],
+                                      nodes[4], nodes[5], nodes[6], nodes[7], id, theForce3d);
+        break;
+      case SMDSEntity_Pyramid:
+        NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2],
+                                      nodes[3], nodes[4], id, theForce3d);
+        break;
+      case SMDSEntity_Penta:
+        NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2],
+                                      nodes[3], nodes[4], nodes[5], id, theForce3d);
+        break;
+      case SMDSEntity_Hexagonal_Prism:
+      default:
+        NewVolume = aHelper.AddPolyhedralVolume(nodes, nbNodeInFaces, id, theForce3d);
+      }
+      ReplaceElemInGroups(volume, NewVolume, meshDS);
+    }
+  }
+
+  if ( !theForce3d )
+  { // setenv NO_FixQuadraticElements to know if FixQuadraticElements() is guilty of bad conversion
+    aHelper.SetSubShape(0); // apply FixQuadraticElements() to the whole mesh
+    aHelper.FixQuadraticElements();
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Makes given elements quadratic
+ *  \param theForce3d - if true, the medium nodes will be placed in the middle of link
+ *  \param theElements - elements to make quadratic 
+ */
+//================================================================================
 
-      for(int i = 0; i < nbNodes; i++)
+void SMESH_MeshEditor::ConvertToQuadratic(const bool        theForce3d,
+                                          TIDSortedElemSet& theElements)
+{
+  if ( theElements.empty() ) return;
+
+  // we believe that all theElements are of the same type
+  const SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
+  
+  // get all nodes shared by theElements
+  TIDSortedNodeSet allNodes;
+  TIDSortedElemSet::iterator eIt = theElements.begin();
+  for ( ; eIt != theElements.end(); ++eIt )
+    allNodes.insert( (*eIt)->begin_nodes(), (*eIt)->end_nodes() );
+
+  // complete theElements with elements of lower dim whose all nodes are in allNodes
+
+  TIDSortedElemSet quadAdjacentElems    [ SMDSAbs_NbElementTypes ]; // quadratic adjacent elements
+  TIDSortedElemSet checkedAdjacentElems [ SMDSAbs_NbElementTypes ];
+  TIDSortedNodeSet::iterator nIt = allNodes.begin();
+  for ( ; nIt != allNodes.end(); ++nIt )
+  {
+    const SMDS_MeshNode* n = *nIt;
+    SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator();
+    while ( invIt->more() )
+    {
+      const SMDS_MeshElement* e = invIt->next();
+      if ( e->IsQuadratic() )
       {
-       aNds[i] = face->GetNode(i);
+        quadAdjacentElems[ e->GetType() ].insert( e );
+        continue;
       }
-
-      meshDS->RemoveFreeElement(face, smDS, notFromGroups);
-
-      SMDS_MeshFace * NewFace = 0;
-      switch(nbNodes)
+      if ( e->GetType() >= elemType )
       {
-      case 3:
-       NewFace = aHelper.AddFace(aNds[0], aNds[1], aNds[2], id, theForce3d);
-       break;
-      case 4:
-       NewFace = aHelper.AddFace(aNds[0], aNds[1], aNds[2], aNds[3], id, theForce3d);
-       break;
-      default:
-       continue;
+        continue; // same type of more complex linear element
       }
-      ReplaceElemInGroups( face, NewFace, GetMeshDS());
+
+      if ( !checkedAdjacentElems[ e->GetType() ].insert( e ).second )
+        continue; // e is already checked
+
+      // check nodes
+      bool allIn = true;
+      SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
+      while ( nodeIt->more() && allIn )
+        allIn = allNodes.count( cast2Node( nodeIt->next() ));
+      if ( allIn )
+        theElements.insert(e );
     }
-    SMDS_VolumeIteratorPtr aVolumeItr = meshDS->volumesIterator();
-    while(aVolumeItr->more())
+  }
+
+  SMESH_MesherHelper helper(*myMesh);
+  helper.SetIsQuadratic( true );
+
+  // add links of quadratic adjacent elements to the helper
+
+  if ( !quadAdjacentElems[SMDSAbs_Edge].empty() )
+    for ( eIt  = quadAdjacentElems[SMDSAbs_Edge].begin();
+          eIt != quadAdjacentElems[SMDSAbs_Edge].end(); ++eIt )
     {
-      const SMDS_MeshVolume* volume = aVolumeItr->next();
-      if(!volume || volume->IsQuadratic() ) continue;
+      helper.AddTLinks( static_cast< const SMDS_MeshEdge*> (*eIt) );
+    }
+  if ( !quadAdjacentElems[SMDSAbs_Face].empty() )
+    for ( eIt  = quadAdjacentElems[SMDSAbs_Face].begin();
+          eIt != quadAdjacentElems[SMDSAbs_Face].end(); ++eIt )
+    {
+      helper.AddTLinks( static_cast< const SMDS_MeshFace*> (*eIt) );
+    }
+  if ( !quadAdjacentElems[SMDSAbs_Volume].empty() )
+    for ( eIt  = quadAdjacentElems[SMDSAbs_Volume].begin();
+          eIt != quadAdjacentElems[SMDSAbs_Volume].end(); ++eIt )
+    {
+      helper.AddTLinks( static_cast< const SMDS_MeshVolume*> (*eIt) );
+    }
 
-      int id = volume->GetID();
-      int nbNodes = volume->NbNodes();
-      vector<const SMDS_MeshNode *> aNds (nbNodes);
+  // make quadratic elements instead of linear ones
 
-      for(int i = 0; i < nbNodes; i++)
-      {
-       aNds[i] = volume->GetNode(i);
-      }
+  SMESHDS_Mesh* meshDS = GetMeshDS();
+  SMESHDS_SubMesh* smDS = 0;
+  for ( eIt = theElements.begin(); eIt != theElements.end(); ++eIt )
+  {
+    const SMDS_MeshElement* elem = *eIt;
+    if( elem->IsQuadratic() || elem->NbNodes() < 2 || elem->IsPoly() )
+      continue;
 
-      meshDS->RemoveFreeElement(volume, smDS, notFromGroups);
+    const int id                   = elem->GetID();
+    const SMDSAbs_ElementType type = elem->GetType();
+    vector<const SMDS_MeshNode *> nodes ( elem->begin_nodes(), elem->end_nodes());
 
-      SMDS_MeshVolume * NewVolume = 0;
-      switch(nbNodes)
-      {
-      case 4:
-       NewVolume = aHelper.AddVolume(aNds[0], aNds[1], aNds[2],
-                                      aNds[3], id, theForce3d );
-       break;
-      case 6:
-       NewVolume = aHelper.AddVolume(aNds[0], aNds[1], aNds[2],
-                                      aNds[3], aNds[4], aNds[5], id, theForce3d);
-       break;
-      case 8:
-       NewVolume = aHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3],
-                                      aNds[4], aNds[5], aNds[6], aNds[7], id, theForce3d);
-       break;
-      default:
-       continue;
-      }
-      ReplaceElemInGroups(volume, NewVolume, meshDS);
+    if ( !smDS || !smDS->Contains( elem ))
+      smDS = meshDS->MeshElements( elem->getshapeId() );
+    meshDS->RemoveFreeElement(elem, smDS, /*fromGroups=*/false);
+
+    SMDS_MeshElement * newElem = 0;
+    switch( nodes.size() )
+    {
+    case 4: // cases for most frequently used element types go first (for optimization)
+      if ( type == SMDSAbs_Volume )
+        newElem = helper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d);
+      else
+        newElem = helper.AddFace  (nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d);
+      break;
+    case 8:
+      newElem = helper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3],
+                                 nodes[4], nodes[5], nodes[6], nodes[7], id, theForce3d);
+      break;
+    case 3:
+      newElem = helper.AddFace  (nodes[0], nodes[1], nodes[2], id, theForce3d);
+      break;
+    case 2:
+      newElem = helper.AddEdge(nodes[0], nodes[1], id, theForce3d);
+      break;
+    case 5:
+      newElem = helper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3],
+                                 nodes[4], id, theForce3d);
+      break;
+    case 6:
+      newElem = helper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3],
+                                 nodes[4], nodes[5], id, theForce3d);
+      break;
+    default:;
     }
+    ReplaceElemInGroups( elem, newElem, meshDS);
+    if( newElem && smDS )
+      smDS->AddElement( newElem );
+  }
+
+  if ( !theForce3d  && !getenv("NO_FixQuadraticElements"))
+  { // setenv NO_FixQuadraticElements to know if FixQuadraticElements() is guilty of bad conversion
+    helper.SetSubShape(0); // apply FixQuadraticElements() to the whole mesh
+    helper.FixQuadraticElements();
   }
 }
 
 //=======================================================================
 /*!
  * \brief Convert quadratic elements to linear ones and remove quadratic nodes
- * \retval int - nb of checked elements
+ * \return int - nb of checked elements
  */
 //=======================================================================
 
@@ -6822,7 +9786,6 @@ int SMESH_MeshEditor::removeQuadElem(SMESHDS_SubMesh *    theSm,
 {
   int nbElem = 0;
   SMESHDS_Mesh* meshDS = GetMeshDS();
-  const bool notFromGroups = false;
 
   while( theItr->more() )
   {
@@ -6830,44 +9793,28 @@ int SMESH_MeshEditor::removeQuadElem(SMESHDS_SubMesh *    theSm,
     nbElem++;
     if( elem && elem->IsQuadratic())
     {
-      int id = elem->GetID();
-      int nbNodes = elem->NbNodes();
-      vector<const SMDS_MeshNode *> aNds, mediumNodes;
-      aNds.reserve( nbNodes );
-      mediumNodes.reserve( nbNodes );
-
-      for(int i = 0; i < nbNodes; i++)
-      {
-       const SMDS_MeshNode* n = elem->GetNode(i);
-
-       if( elem->IsMediumNode( n ) )
-          mediumNodes.push_back( n );
-       else
-         aNds.push_back( n );
-      }
-      if( aNds.empty() ) continue;
+      int id                    = elem->GetID();
+      int nbCornerNodes         = elem->NbCornerNodes();
       SMDSAbs_ElementType aType = elem->GetType();
 
-      //remove old quadratic element
-      meshDS->RemoveFreeElement( elem, theSm, notFromGroups );
+      vector<const SMDS_MeshNode *> nodes( elem->begin_nodes(), elem->end_nodes() );
 
-      SMDS_MeshElement * NewElem = AddElement( aNds, aType, false, id );
-      ReplaceElemInGroups(elem, NewElem, meshDS);
-      if( theSm && NewElem )
-       theSm->AddElement( NewElem );
+      //remove a quadratic element
+      if ( !theSm || !theSm->Contains( elem ))
+        theSm = meshDS->MeshElements( elem->getshapeId() );
+      meshDS->RemoveFreeElement( elem, theSm, /*fromGroups=*/false );
 
       // remove medium nodes
-      vector<const SMDS_MeshNode*>::iterator nIt = mediumNodes.begin();
-      for ( ; nIt != mediumNodes.end(); ++nIt ) {
-        const SMDS_MeshNode* n = *nIt;
-        if ( n->NbInverseElements() == 0 ) {
-          if ( n->GetPosition()->GetShapeId() != theShapeID )
-            meshDS->RemoveFreeNode( n, meshDS->MeshElements
-                                    ( n->GetPosition()->GetShapeId() ));
-          else
-            meshDS->RemoveFreeNode( n, theSm );
-       }
-      }
+      for ( unsigned i = nbCornerNodes; i < nodes.size(); ++i )
+        if ( nodes[i]->NbInverseElements() == 0 )
+          meshDS->RemoveFreeNode( nodes[i], theSm );
+
+      // add a linear element
+      nodes.resize( nbCornerNodes );
+      SMDS_MeshElement * newElem = AddElement( nodes, aType, false, id );
+      ReplaceElemInGroups(elem, newElem, meshDS);
+      if( theSm && newElem )
+        theSm->AddElement( newElem );
     }
   }
   return nbElem;
@@ -6877,7 +9824,8 @@ int SMESH_MeshEditor::removeQuadElem(SMESHDS_SubMesh *    theSm,
 //function : ConvertFromQuadratic
 //purpose  :
 //=======================================================================
-bool  SMESH_MeshEditor::ConvertFromQuadratic()
+
+bool SMESH_MeshEditor::ConvertFromQuadratic()
 {
   int nbCheckedElems = 0;
   if ( myMesh->HasShapeToMesh() )
@@ -6892,7 +9840,7 @@ bool  SMESH_MeshEditor::ConvertFromQuadratic()
       }
     }
   }
-  
+
   int totalNbElems =
     GetMeshDS()->NbEdges() + GetMeshDS()->NbFaces() + GetMeshDS()->NbVolumes();
   if ( nbCheckedElems < totalNbElems ) // not all elements are in submeshes
@@ -6904,18 +9852,114 @@ bool  SMESH_MeshEditor::ConvertFromQuadratic()
   return true;
 }
 
+namespace
+{
+  //================================================================================
+  /*!
+   * \brief Return true if all medium nodes of the element are in the node set
+   */
+  //================================================================================
+
+  bool allMediumNodesIn(const SMDS_MeshElement* elem, TIDSortedNodeSet& nodeSet )
+  {
+    for ( int i = elem->NbCornerNodes(); i < elem->NbNodes(); ++i )
+      if ( !nodeSet.count( elem->GetNode(i) ))
+        return false;
+    return true;
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Makes given elements linear
+ */
+//================================================================================
+
+void SMESH_MeshEditor::ConvertFromQuadratic(TIDSortedElemSet& theElements)
+{
+  if ( theElements.empty() ) return;
+
+  // collect IDs of medium nodes of theElements; some of these nodes will be removed
+  set<int> mediumNodeIDs;
+  TIDSortedElemSet::iterator eIt = theElements.begin();
+  for ( ; eIt != theElements.end(); ++eIt )
+  {
+    const SMDS_MeshElement* e = *eIt;
+    for ( int i = e->NbCornerNodes(); i < e->NbNodes(); ++i )
+      mediumNodeIDs.insert( e->GetNode(i)->GetID() );
+  }
+
+  // replace given elements by linear ones
+  typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::iterator> TSetIterator;
+  SMDS_ElemIteratorPtr elemIt( new TSetIterator( theElements.begin(), theElements.end() ));
+  removeQuadElem( /*theSm=*/0, elemIt, /*theShapeID=*/0 );
+
+  // we need to convert remaining elements whose all medium nodes are in mediumNodeIDs
+  // except those elements sharing medium nodes of quadratic element whose medium nodes
+  // are not all in mediumNodeIDs
+
+  // get remaining medium nodes
+  TIDSortedNodeSet mediumNodes;
+  set<int>::iterator nIdsIt = mediumNodeIDs.begin();
+  for ( ; nIdsIt != mediumNodeIDs.end(); ++nIdsIt )
+    if ( const SMDS_MeshNode* n = GetMeshDS()->FindNode( *nIdsIt ))
+      mediumNodes.insert( mediumNodes.end(), n );
+
+  // find more quadratic elements to convert
+  TIDSortedElemSet moreElemsToConvert;
+  TIDSortedNodeSet::iterator nIt = mediumNodes.begin();
+  for ( ; nIt != mediumNodes.end(); ++nIt )
+  {
+    SMDS_ElemIteratorPtr invIt = (*nIt)->GetInverseElementIterator();
+    while ( invIt->more() )
+    {
+      const SMDS_MeshElement* e = invIt->next();
+      if ( e->IsQuadratic() && allMediumNodesIn( e, mediumNodes ))
+      {
+        // find a more complex element including e and
+        // whose medium nodes are not in mediumNodes
+        bool complexFound = false;
+        for ( int type = e->GetType() + 1; type < SMDSAbs_0DElement; ++type )
+        {
+          SMDS_ElemIteratorPtr invIt2 =
+            (*nIt)->GetInverseElementIterator( SMDSAbs_ElementType( type ));
+          while ( invIt2->more() )
+          {
+            const SMDS_MeshElement* eComplex = invIt2->next();
+            if ( eComplex->IsQuadratic() && !allMediumNodesIn( eComplex, mediumNodes))
+            {
+              int nbCommonNodes = SMESH_Algo::GetCommonNodes( e, eComplex ).size();
+              if ( nbCommonNodes == e->NbNodes())
+              {
+                complexFound = true;
+                type = SMDSAbs_NbElementTypes; // to quit from the outer loop
+                break;
+              }
+            }
+          }
+        }
+        if ( !complexFound )
+          moreElemsToConvert.insert( e );
+      }
+    }
+  }
+  elemIt = SMDS_ElemIteratorPtr
+    (new TSetIterator( moreElemsToConvert.begin(), moreElemsToConvert.end() ));
+  removeQuadElem( /*theSm=*/0, elemIt, /*theShapeID=*/0 );
+}
+
 //=======================================================================
 //function : SewSideElements
 //purpose  :
 //=======================================================================
 
 SMESH_MeshEditor::Sew_Error
-  SMESH_MeshEditor::SewSideElements (TIDSortedElemSet&    theSide1,
-                                     TIDSortedElemSet&    theSide2,
-                                     const SMDS_MeshNode* theFirstNode1,
-                                     const SMDS_MeshNode* theFirstNode2,
-                                     const SMDS_MeshNode* theSecondNode1,
-                                     const SMDS_MeshNode* theSecondNode2)
+SMESH_MeshEditor::SewSideElements (TIDSortedElemSet&    theSide1,
+                                   TIDSortedElemSet&    theSide2,
+                                   const SMDS_MeshNode* theFirstNode1,
+                                   const SMDS_MeshNode* theFirstNode2,
+                                   const SMDS_MeshNode* theSecondNode1,
+                                   const SMDS_MeshNode* theSecondNode2)
 {
   myLastCreatedElems.Clear();
   myLastCreatedNodes.Clear();
@@ -6934,25 +9978,27 @@ SMESH_MeshEditor::Sew_Error
   // 1. Build set of faces representing each side:
   // =======================================================================
   // a. build set of nodes belonging to faces
-  // b. complete set of faces: find missing fices whose nodes are in set of nodes
+  // b. complete set of faces: find missing faces whose nodes are in set of nodes
   // c. create temporary faces representing side of volumes if correspondent
   //    face does not exist
 
   SMESHDS_Mesh* aMesh = GetMeshDS();
-  SMDS_Mesh aTmpFacesMesh;
-  set<const SMDS_MeshElement*> faceSet1, faceSet2;
+  // TODO algoritm not OK with vtkUnstructuredGrid: 2 meshes can't share nodes
+  //SMDS_Mesh aTmpFacesMesh; // try to use the same mesh
+  TIDSortedElemSet             faceSet1, faceSet2;
   set<const SMDS_MeshElement*> volSet1,  volSet2;
   set<const SMDS_MeshNode*>    nodeSet1, nodeSet2;
-  set<const SMDS_MeshElement*> * faceSetPtr[] = { &faceSet1, &faceSet2 };
-  set<const SMDS_MeshElement*>  * volSetPtr[] = { &volSet1,  &volSet2  };
+  TIDSortedElemSet             * faceSetPtr[] = { &faceSet1, &faceSet2 };
+  set<const SMDS_MeshElement*>  volSetPtr[] = { &volSet1,  &volSet2  };
   set<const SMDS_MeshNode*>    * nodeSetPtr[] = { &nodeSet1, &nodeSet2 };
-  TIDSortedElemSet * elemSetPtr[] = { &theSide1, &theSide2 };
+  TIDSortedElemSet             * elemSetPtr[] = { &theSide1, &theSide2 };
   int iSide, iFace, iNode;
 
+  list<const SMDS_MeshElement* > tempFaceList;
   for ( iSide = 0; iSide < 2; iSide++ ) {
     set<const SMDS_MeshNode*>    * nodeSet = nodeSetPtr[ iSide ];
-    TIDSortedElemSet * elemSet = elemSetPtr[ iSide ];
-    set<const SMDS_MeshElement*> * faceSet = faceSetPtr[ iSide ];
+    TIDSortedElemSet             * elemSet = elemSetPtr[ iSide ];
+    TIDSortedElemSet             * faceSet = faceSetPtr[ iSide ];
     set<const SMDS_MeshElement*> * volSet  = volSetPtr [ iSide ];
     set<const SMDS_MeshElement*>::iterator vIt;
     TIDSortedElemSet::iterator eIt;
@@ -6976,7 +10022,7 @@ SMESH_MeshEditor::Sew_Error
     // -----------------------------------------------------------
     // 1a. Collect nodes of existing faces
     //     and build set of face nodes in order to detect missing
-    //     faces corresponing to sides of volumes
+    //     faces corresponding to sides of volumes
     // -----------------------------------------------------------
 
     set< set <const SMDS_MeshNode*> > setOfFaceNodeSet;
@@ -7000,7 +10046,7 @@ SMESH_MeshEditor::Sew_Error
         volSet->insert( elem );
     }
     // ------------------------------------------------------------------------------
-    // 1b. Complete set of faces: find missing fices whose nodes are in set of nodes
+    // 1b. Complete set of faces: find missing faces whose nodes are in set of nodes
     // ------------------------------------------------------------------------------
 
     for ( nIt = nodeSet->begin(); nIt != nodeSet->end(); nIt++ ) { // loop on nodes of iSide
@@ -7054,40 +10100,38 @@ SMESH_MeshEditor::Sew_Error
           bool isNewFace = setOfFaceNodeSet.insert( faceNodeSet ).second;
           if ( isNewFace ) {
             // no such a face is given but it still can exist, check it
-            if ( nbNodes == 3 ) {
-              aFreeFace = aMesh->FindFace( fNodes[0],fNodes[1],fNodes[2] );
-            }
-            else if ( nbNodes == 4 ) {
-              aFreeFace = aMesh->FindFace( fNodes[0],fNodes[1],fNodes[2],fNodes[3] );
-            }
-            else {
-              vector<const SMDS_MeshNode *> poly_nodes ( fNodes, & fNodes[nbNodes]);
-              aFreeFace = aMesh->FindFace(poly_nodes);
-            }
+            vector<const SMDS_MeshNode *> nodes ( fNodes, fNodes + nbNodes);
+            aFreeFace = aMesh->FindElement( nodes, SMDSAbs_Face, /*noMedium=*/false );
           }
           if ( !aFreeFace ) {
             // create a temporary face
             if ( nbNodes == 3 ) {
-              aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2] );
+              //aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2] );
+              aFreeFace = aMesh->AddFace( fNodes[0],fNodes[1],fNodes[2] );
             }
             else if ( nbNodes == 4 ) {
-              aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2],fNodes[3] );
+              //aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2],fNodes[3] );
+              aFreeFace = aMesh->AddFace( fNodes[0],fNodes[1],fNodes[2],fNodes[3] );
             }
             else {
               vector<const SMDS_MeshNode *> poly_nodes ( fNodes, & fNodes[nbNodes]);
-              aFreeFace = aTmpFacesMesh.AddPolygonalFace(poly_nodes);
+              //aFreeFace = aTmpFacesMesh.AddPolygonalFace(poly_nodes);
+              aFreeFace = aMesh->AddPolygonalFace(poly_nodes);
             }
+            if ( aFreeFace )
+              tempFaceList.push_back( aFreeFace );
           }
+
           if ( aFreeFace )
             freeFaceList.push_back( aFreeFace );
 
         } // loop on faces of a volume
 
-        // choose one of several free faces
-        // --------------------------------------
+        // choose one of several free faces of a volume
+        // --------------------------------------------
         if ( freeFaceList.size() > 1 ) {
           // choose a face having max nb of nodes shared by other elems of a side
-          int maxNbNodes = -1/*, nbExcludedFaces = 0*/;
+          int maxNbNodes = -1;
           list<const SMDS_MeshElement* >::iterator fIt = freeFaceList.begin();
           while ( fIt != freeFaceList.end() ) { // loop on free faces
             int nbSharedNodes = 0;
@@ -7098,18 +10142,20 @@ SMESH_MeshEditor::Sew_Error
               SMDS_ElemIteratorPtr invElemIt = n->GetInverseElementIterator();
               while ( invElemIt->more() ) {
                 const SMDS_MeshElement* e = invElemIt->next();
-                if ( faceSet->find( e ) != faceSet->end() )
-                  nbSharedNodes++;
-                if ( elemSet->find( e ) != elemSet->end() )
-                  nbSharedNodes++;
+                nbSharedNodes += faceSet->count( e );
+                nbSharedNodes += elemSet->count( e );
               }
             }
-            if ( nbSharedNodes >= maxNbNodes ) {
+            if ( nbSharedNodes > maxNbNodes ) {
               maxNbNodes = nbSharedNodes;
+              freeFaceList.erase( freeFaceList.begin(), fIt++ );
+            }
+            else if ( nbSharedNodes == maxNbNodes ) {
               fIt++;
             }
-            else
-              freeFaceList.erase( fIt++ ); // here fIt++ occures before erase
+            else {
+              freeFaceList.erase( fIt++ ); // here fIt++ occurs before erase
+            }
           }
           if ( freeFaceList.size() > 1 )
           {
@@ -7154,48 +10200,51 @@ SMESH_MeshEditor::Sew_Error
           const SMDS_MeshElement* aFreeFace = freeFaceList.front();
           faceSet->insert( aFreeFace );
           // complete a node set with nodes of a found free face
-//           for ( iNode = 0; iNode < ; iNode++ )
-//             nodeSet->insert( fNodes[ iNode ] );
+          //           for ( iNode = 0; iNode < ; iNode++ )
+          //             nodeSet->insert( fNodes[ iNode ] );
         }
 
       } // loop on volumes of a side
 
-//       // complete a set of faces if new nodes in a nodeSet appeared
-//       // ----------------------------------------------------------
-//       if ( nodeSetSize != nodeSet->size() ) {
-//         for ( ; nIt != nodeSet->end(); nIt++ ) { // loop on nodes of iSide
-//           SMDS_ElemIteratorPtr fIt = (*nIt)->GetInverseElementIterator(SMDSAbs_Face);
-//           while ( fIt->more() ) { // loop on faces sharing a node
-//             const SMDS_MeshElement* f = fIt->next();
-//             if ( faceSet->find( f ) == faceSet->end() ) {
-//               // check if all nodes are in nodeSet and
-//               // complete setOfFaceNodeSet if they are
-//               set <const SMDS_MeshNode*> faceNodeSet;
-//               SMDS_ElemIteratorPtr nodeIt = f->nodesIterator();
-//               bool allInSet = true;
-//               while ( nodeIt->more() && allInSet ) { // loop on nodes of a face
-//                 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-//                 if ( nodeSet->find( n ) == nodeSet->end() )
-//                   allInSet = false;
-//                 else
-//                   faceNodeSet.insert( n );
-//               }
-//               if ( allInSet ) {
-//                 faceSet->insert( f );
-//                 setOfFaceNodeSet.insert( faceNodeSet );
-//               }
-//             }
-//           }
-//         }
-//       }
+      //       // complete a set of faces if new nodes in a nodeSet appeared
+      //       // ----------------------------------------------------------
+      //       if ( nodeSetSize != nodeSet->size() ) {
+      //         for ( ; nIt != nodeSet->end(); nIt++ ) { // loop on nodes of iSide
+      //           SMDS_ElemIteratorPtr fIt = (*nIt)->GetInverseElementIterator(SMDSAbs_Face);
+      //           while ( fIt->more() ) { // loop on faces sharing a node
+      //             const SMDS_MeshElement* f = fIt->next();
+      //             if ( faceSet->find( f ) == faceSet->end() ) {
+      //               // check if all nodes are in nodeSet and
+      //               // complete setOfFaceNodeSet if they are
+      //               set <const SMDS_MeshNode*> faceNodeSet;
+      //               SMDS_ElemIteratorPtr nodeIt = f->nodesIterator();
+      //               bool allInSet = true;
+      //               while ( nodeIt->more() && allInSet ) { // loop on nodes of a face
+      //                 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+      //                 if ( nodeSet->find( n ) == nodeSet->end() )
+      //                   allInSet = false;
+      //                 else
+      //                   faceNodeSet.insert( n );
+      //               }
+      //               if ( allInSet ) {
+      //                 faceSet->insert( f );
+      //                 setOfFaceNodeSet.insert( faceNodeSet );
+      //               }
+      //             }
+      //           }
+      //         }
+      //       }
     } // Create temporary faces, if there are volumes given
   } // loop on sides
 
   if ( faceSet1.size() != faceSet2.size() ) {
     // delete temporary faces: they are in reverseElements of actual nodes
-    SMDS_FaceIteratorPtr tmpFaceIt = aTmpFacesMesh.facesIterator();
-    while ( tmpFaceIt->more() )
-      aTmpFacesMesh.RemoveElement( tmpFaceIt->next() );
+//    SMDS_FaceIteratorPtr tmpFaceIt = aTmpFacesMesh.facesIterator();
+//    while ( tmpFaceIt->more() )
+//      aTmpFacesMesh.RemoveElement( tmpFaceIt->next() );
+//    list<const SMDS_MeshElement* >::iterator tmpFaceIt = tempFaceList.begin();
+//    for (; tmpFaceIt !=tempFaceList.end(); ++tmpFaceIt)
+//      aMesh->RemoveElement(*tmpFaceIt);
     MESSAGE("Diff nb of faces");
     return SEW_TOPO_DIFF_SETS_OF_ELEMENTS;
   }
@@ -7205,27 +10254,254 @@ SMESH_MeshEditor::Sew_Error
   //              bind a node to remove to a node to put instead
   // ============================================================
 
-  TNodeNodeMap nReplaceMap; // bind a node to remove to a node to put instead
+  TNodeNodeMap nReplaceMap; // bind a node to remove to a node to put instead
+  if ( theFirstNode1 != theFirstNode2 )
+    nReplaceMap.insert( make_pair( theFirstNode1, theFirstNode2 ));
+  if ( theSecondNode1 != theSecondNode2 )
+    nReplaceMap.insert( make_pair( theSecondNode1, theSecondNode2 ));
+
+  LinkID_Gen aLinkID_Gen( GetMeshDS() );
+  set< long > linkIdSet; // links to process
+  linkIdSet.insert( aLinkID_Gen.GetLinkID( theFirstNode1, theSecondNode1 ));
+
+  typedef pair< const SMDS_MeshNode*, const SMDS_MeshNode* > NLink;
+  list< NLink > linkList[2];
+  linkList[0].push_back( NLink( theFirstNode1, theSecondNode1 ));
+  linkList[1].push_back( NLink( theFirstNode2, theSecondNode2 ));
+  // loop on links in linkList; find faces by links and append links
+  // of the found faces to linkList
+  list< NLink >::iterator linkIt[] = { linkList[0].begin(), linkList[1].begin() } ;
+  for ( ; linkIt[0] != linkList[0].end(); linkIt[0]++, linkIt[1]++ )
+  {
+    NLink link[] = { *linkIt[0], *linkIt[1] };
+    long linkID = aLinkID_Gen.GetLinkID( link[0].first, link[0].second );
+    if ( !linkIdSet.count( linkID ) )
+      continue;
+
+    // by links, find faces in the face sets,
+    // and find indices of link nodes in the found faces;
+    // in a face set, there is only one or no face sharing a link
+    // ---------------------------------------------------------------
+
+    const SMDS_MeshElement* face[] = { 0, 0 };
+    vector<const SMDS_MeshNode*> fnodes[2];
+    int iLinkNode[2][2];
+    TIDSortedElemSet avoidSet;
+    for ( iSide = 0; iSide < 2; iSide++ ) { // loop on 2 sides
+      const SMDS_MeshNode* n1 = link[iSide].first;
+      const SMDS_MeshNode* n2 = link[iSide].second;
+      //cout << "Side " << iSide << " ";
+      //cout << "L( " << n1->GetID() << ", " << n2->GetID() << " ) " << endl;
+      // find a face by two link nodes
+      face[ iSide ] = FindFaceInSet( n1, n2, *faceSetPtr[ iSide ], avoidSet,
+                                     &iLinkNode[iSide][0], &iLinkNode[iSide][1] );
+      if ( face[ iSide ])
+      {
+        //cout << " F " << face[ iSide]->GetID() <<endl;
+        faceSetPtr[ iSide ]->erase( face[ iSide ]);
+        // put face nodes to fnodes
+        if ( face[ iSide ]->IsQuadratic() )
+        {
+          // use interlaced nodes iterator
+          const SMDS_VtkFace* F = dynamic_cast<const SMDS_VtkFace*>( face[ iSide ]);
+          if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace"));
+          SMDS_ElemIteratorPtr nIter = F->interlacedNodesElemIterator();
+          while ( nIter->more() )
+            fnodes[ iSide ].push_back( cast2Node( nIter->next() ));
+        }
+        else
+        {
+          fnodes[ iSide ].assign( face[ iSide ]->begin_nodes(),
+                                  face[ iSide ]->end_nodes() );
+        }
+        fnodes[ iSide ].push_back( fnodes[ iSide ].front());
+      }
+    }
+
+    // check similarity of elements of the sides
+    if (aResult == SEW_OK && (( face[0] && !face[1] ) || ( !face[0] && face[1] ))) {
+      MESSAGE("Correspondent face not found on side " << ( face[0] ? 1 : 0 ));
+      if ( nReplaceMap.size() == 2 ) { // faces on input nodes not found
+        aResult = ( face[0] ? SEW_BAD_SIDE2_NODES : SEW_BAD_SIDE1_NODES );
+      }
+      else {
+        aResult = SEW_TOPO_DIFF_SETS_OF_ELEMENTS;
+      }
+      break; // do not return because it's necessary to remove tmp faces
+    }
+
+    // set nodes to merge
+    // -------------------
+
+    if ( face[0] && face[1] )  {
+      const int nbNodes = face[0]->NbNodes();
+      if ( nbNodes != face[1]->NbNodes() ) {
+        MESSAGE("Diff nb of face nodes");
+        aResult = SEW_TOPO_DIFF_SETS_OF_ELEMENTS;
+        break; // do not return because it s necessary to remove tmp faces
+      }
+      bool reverse[] = { false, false }; // order of nodes in the link
+      for ( iSide = 0; iSide < 2; iSide++ ) { // loop on 2 sides
+        // analyse link orientation in faces
+        int i1 = iLinkNode[ iSide ][ 0 ];
+        int i2 = iLinkNode[ iSide ][ 1 ];
+        reverse[ iSide ] = Abs( i1 - i2 ) == 1 ? i1 > i2 : i2 > i1;
+      }
+      int di1 = reverse[0] ? -1 : +1, i1 = iLinkNode[0][1] + di1;
+      int di2 = reverse[1] ? -1 : +1, i2 = iLinkNode[1][1] + di2;
+      for ( int i = nbNodes - 2; i > 0; --i, i1 += di1, i2 += di2 )
+      {
+        nReplaceMap.insert  ( make_pair ( fnodes[0][ ( i1 + nbNodes ) % nbNodes ],
+                                          fnodes[1][ ( i2 + nbNodes ) % nbNodes ]));
+      }
+
+      // add other links of the faces to linkList
+      // -----------------------------------------
+
+      for ( iNode = 0; iNode < nbNodes; iNode++ )  {
+        linkID = aLinkID_Gen.GetLinkID( fnodes[0][iNode], fnodes[0][iNode+1] );
+        pair< set<long>::iterator, bool > iter_isnew = linkIdSet.insert( linkID );
+        if ( !iter_isnew.second ) { // already in a set: no need to process
+          linkIdSet.erase( iter_isnew.first );
+        }
+        else // new in set == encountered for the first time: add
+        {
+          const SMDS_MeshNode* n1 = fnodes[0][ iNode ];
+          const SMDS_MeshNode* n2 = fnodes[0][ iNode + 1];
+          linkList[0].push_back ( NLink( n1, n2 ));
+          linkList[1].push_back ( NLink( nReplaceMap[n1], nReplaceMap[n2] ));
+        }
+      }
+    } // 2 faces found
+
+    if ( faceSetPtr[0]->empty() || faceSetPtr[1]->empty() )
+      break;
+
+  } // loop on link lists
+
+  if ( aResult == SEW_OK &&
+       ( //linkIt[0] != linkList[0].end() ||
+         !faceSetPtr[0]->empty() || !faceSetPtr[1]->empty() )) {
+    MESSAGE( (linkIt[0] != linkList[0].end()) <<" "<< (faceSetPtr[0]->empty()) <<
+             " " << (faceSetPtr[1]->empty()));
+    aResult = SEW_TOPO_DIFF_SETS_OF_ELEMENTS;
+  }
+
+  // ====================================================================
+  // 3. Replace nodes in elements of the side 1 and remove replaced nodes
+  // ====================================================================
+
+  // delete temporary faces
+//  SMDS_FaceIteratorPtr tmpFaceIt = aTmpFacesMesh.facesIterator();
+//  while ( tmpFaceIt->more() )
+//    aTmpFacesMesh.RemoveElement( tmpFaceIt->next() );
+  list<const SMDS_MeshElement* >::iterator tmpFaceIt = tempFaceList.begin();
+  for (; tmpFaceIt !=tempFaceList.end(); ++tmpFaceIt)
+    aMesh->RemoveElement(*tmpFaceIt);
+
+  if ( aResult != SEW_OK)
+    return aResult;
+
+  list< int > nodeIDsToRemove/*, elemIDsToRemove*/;
+  // loop on nodes replacement map
+  TNodeNodeMap::iterator nReplaceMapIt = nReplaceMap.begin(), nnIt;
+  for ( ; nReplaceMapIt != nReplaceMap.end(); nReplaceMapIt++ )
+    if ( (*nReplaceMapIt).first != (*nReplaceMapIt).second ) {
+      const SMDS_MeshNode* nToRemove = (*nReplaceMapIt).first;
+      nodeIDsToRemove.push_back( nToRemove->GetID() );
+      // loop on elements sharing nToRemove
+      SMDS_ElemIteratorPtr invElemIt = nToRemove->GetInverseElementIterator();
+      while ( invElemIt->more() ) {
+        const SMDS_MeshElement* e = invElemIt->next();
+        // get a new suite of nodes: make replacement
+        int nbReplaced = 0, i = 0, nbNodes = e->NbNodes();
+        vector< const SMDS_MeshNode*> nodes( nbNodes );
+        SMDS_ElemIteratorPtr nIt = e->nodesIterator();
+        while ( nIt->more() ) {
+          const SMDS_MeshNode* n =
+            static_cast<const SMDS_MeshNode*>( nIt->next() );
+          nnIt = nReplaceMap.find( n );
+          if ( nnIt != nReplaceMap.end() ) {
+            nbReplaced++;
+            n = (*nnIt).second;
+          }
+          nodes[ i++ ] = n;
+        }
+        //       if ( nbReplaced == nbNodes && e->GetType() == SMDSAbs_Face )
+        //         elemIDsToRemove.push_back( e->GetID() );
+        //       else
+        if ( nbReplaced )
+          {
+            SMDSAbs_ElementType etyp = e->GetType();
+            SMDS_MeshElement* newElem = this->AddElement(nodes, etyp, false);
+            if (newElem)
+              {
+                myLastCreatedElems.Append(newElem);
+                AddToSameGroups(newElem, e, aMesh);
+                int aShapeId = e->getshapeId();
+                if ( aShapeId )
+                  {
+                    aMesh->SetMeshElementOnShape( newElem, aShapeId );
+                  }
+              }
+            aMesh->RemoveElement(e);
+          }
+      }
+    }
+
+  Remove( nodeIDsToRemove, true );
+
+  return aResult;
+}
+
+//================================================================================
+/*!
+ * \brief Find corresponding nodes in two sets of faces
+ * \param theSide1 - first face set
+ * \param theSide2 - second first face
+ * \param theFirstNode1 - a boundary node of set 1
+ * \param theFirstNode2 - a node of set 2 corresponding to theFirstNode1
+ * \param theSecondNode1 - a boundary node of set 1 linked with theFirstNode1
+ * \param theSecondNode2 - a node of set 2 corresponding to theSecondNode1
+ * \param nReplaceMap - output map of corresponding nodes
+ * \return bool  - is a success or not
+ */
+//================================================================================
+
+#ifdef _DEBUG_
+//#define DEBUG_MATCHING_NODES
+#endif
+
+SMESH_MeshEditor::Sew_Error
+SMESH_MeshEditor::FindMatchingNodes(set<const SMDS_MeshElement*>& theSide1,
+                                    set<const SMDS_MeshElement*>& theSide2,
+                                    const SMDS_MeshNode*          theFirstNode1,
+                                    const SMDS_MeshNode*          theFirstNode2,
+                                    const SMDS_MeshNode*          theSecondNode1,
+                                    const SMDS_MeshNode*          theSecondNode2,
+                                    TNodeNodeMap &                nReplaceMap)
+{
+  set<const SMDS_MeshElement*> * faceSetPtr[] = { &theSide1, &theSide2 };
+
+  nReplaceMap.clear();
   if ( theFirstNode1 != theFirstNode2 )
-    nReplaceMap.insert( TNodeNodeMap::value_type( theFirstNode1, theFirstNode2 ));
+    nReplaceMap.insert( make_pair( theFirstNode1, theFirstNode2 ));
   if ( theSecondNode1 != theSecondNode2 )
-    nReplaceMap.insert( TNodeNodeMap::value_type( theSecondNode1, theSecondNode2 ));
+    nReplaceMap.insert( make_pair( theSecondNode1, theSecondNode2 ));
 
-  LinkID_Gen aLinkID_Gen( GetMeshDS() );
-  set< long > linkIdSet; // links to process
-  linkIdSet.insert( aLinkID_Gen.GetLinkID( theFirstNode1, theSecondNode1 ));
+  set< SMESH_TLink > linkSet; // set of nodes where order of nodes is ignored
+  linkSet.insert( SMESH_TLink( theFirstNode1, theSecondNode1 ));
 
-  typedef pair< const SMDS_MeshNode*, const SMDS_MeshNode* > NLink;
   list< NLink > linkList[2];
   linkList[0].push_back( NLink( theFirstNode1, theSecondNode1 ));
   linkList[1].push_back( NLink( theFirstNode2, theSecondNode2 ));
+
   // loop on links in linkList; find faces by links and append links
   // of the found faces to linkList
   list< NLink >::iterator linkIt[] = { linkList[0].begin(), linkList[1].begin() } ;
   for ( ; linkIt[0] != linkList[0].end(); linkIt[0]++, linkIt[1]++ ) {
     NLink link[] = { *linkIt[0], *linkIt[1] };
-    long linkID = aLinkID_Gen.GetLinkID( link[0].first, link[0].second );
-    if ( linkIdSet.find( linkID ) == linkIdSet.end() )
+    if ( linkSet.find( link[0] ) == linkSet.end() )
       continue;
 
     // by links, find faces in the face sets,
@@ -7234,525 +10510,1467 @@ SMESH_MeshEditor::Sew_Error
     // ---------------------------------------------------------------
 
     const SMDS_MeshElement* face[] = { 0, 0 };
-    //const SMDS_MeshNode* faceNodes[ 2 ][ 5 ];
-    vector<const SMDS_MeshNode*> fnodes1(9);
-    vector<const SMDS_MeshNode*> fnodes2(9);
-    //const SMDS_MeshNode* notLinkNodes[ 2 ][ 2 ] = {{ 0, 0 },{ 0, 0 }} ;
-    vector<const SMDS_MeshNode*> notLinkNodes1(6);
-    vector<const SMDS_MeshNode*> notLinkNodes2(6);
-    int iLinkNode[2][2];
-    for ( iSide = 0; iSide < 2; iSide++ ) { // loop on 2 sides
+    list<const SMDS_MeshNode*> notLinkNodes[2];
+    //bool reverse[] = { false, false }; // order of notLinkNodes
+    int nbNodes[2];
+    for ( int iSide = 0; iSide < 2; iSide++ ) // loop on 2 sides
+    {
       const SMDS_MeshNode* n1 = link[iSide].first;
       const SMDS_MeshNode* n2 = link[iSide].second;
       set<const SMDS_MeshElement*> * faceSet = faceSetPtr[ iSide ];
-      set< const SMDS_MeshElement* > fMap;
-      for ( int i = 0; i < 2; i++ ) { // loop on 2 nodes of a link
-        const SMDS_MeshNode* n = i ? n1 : n2; // a node of a link
+      set< const SMDS_MeshElement* > facesOfNode1;
+      for ( int iNode = 0; iNode < 2; iNode++ ) // loop on 2 nodes of a link
+      {
+        // during a loop of the first node, we find all faces around n1,
+        // during a loop of the second node, we find one face sharing both n1 and n2
+        const SMDS_MeshNode* n = iNode ? n1 : n2; // a node of a link
         SMDS_ElemIteratorPtr fIt = n->GetInverseElementIterator(SMDSAbs_Face);
         while ( fIt->more() ) { // loop on faces sharing a node
           const SMDS_MeshElement* f = fIt->next();
           if (faceSet->find( f ) != faceSet->end() && // f is in face set
-              ! fMap.insert( f ).second ) // f encounters twice
+              ! facesOfNode1.insert( f ).second ) // f encounters twice
           {
             if ( face[ iSide ] ) {
               MESSAGE( "2 faces per link " );
-              aResult = iSide ? SEW_BAD_SIDE2_NODES : SEW_BAD_SIDE1_NODES;
-              break;
+              return ( iSide ? SEW_BAD_SIDE2_NODES : SEW_BAD_SIDE1_NODES );
             }
             face[ iSide ] = f;
             faceSet->erase( f );
-            // get face nodes and find ones of a link
-            iNode = 0;
-            int nbl = -1;
-            if(f->IsPoly()) {
-              if(iSide==0) {
-                fnodes1.resize(f->NbNodes()+1);
-                notLinkNodes1.resize(f->NbNodes()-2);
-              }
-              else {
-                fnodes2.resize(f->NbNodes()+1);
-                notLinkNodes2.resize(f->NbNodes()-2);
-              }
-            }
-            if(!f->IsQuadratic()) {
-              SMDS_ElemIteratorPtr nIt = f->nodesIterator();
-              while ( nIt->more() ) {
-                const SMDS_MeshNode* n =
-                  static_cast<const SMDS_MeshNode*>( nIt->next() );
-                if ( n == n1 ) {
-                  iLinkNode[ iSide ][ 0 ] = iNode;
-                }
-                else if ( n == n2 ) {
-                  iLinkNode[ iSide ][ 1 ] = iNode;
-                }
-                //else if ( notLinkNodes[ iSide ][ 0 ] )
-                //  notLinkNodes[ iSide ][ 1 ] = n;
-                //else
-                //  notLinkNodes[ iSide ][ 0 ] = n;
-                else {
-                  nbl++;
-                  if(iSide==0)
-                    notLinkNodes1[nbl] = n;
-                    //notLinkNodes1.push_back(n);
-                  else
-                    notLinkNodes2[nbl] = n;
-                    //notLinkNodes2.push_back(n);
-                }
-                //faceNodes[ iSide ][ iNode++ ] = n;
-                if(iSide==0) {
-                  fnodes1[iNode++] = n;
-                }
-                else {
-                  fnodes2[iNode++] = n;
-                }
-              }
-            }
-            else { // f->IsQuadratic()
-              const SMDS_QuadraticFaceOfNodes* F =
-                static_cast<const SMDS_QuadraticFaceOfNodes*>(f);
-              // use special nodes iterator
-              SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
-              while ( anIter->more() ) {
-                const SMDS_MeshNode* n =
-                  static_cast<const SMDS_MeshNode*>( anIter->next() );
-                if ( n == n1 ) {
-                  iLinkNode[ iSide ][ 0 ] = iNode;
-                }
-                else if ( n == n2 ) {
-                  iLinkNode[ iSide ][ 1 ] = iNode;
-                }
-                else {
-                  nbl++;
-                  if(iSide==0) {
-                    notLinkNodes1[nbl] = n;
-                  }
-                  else {
-                    notLinkNodes2[nbl] = n;
-                  }
-                }
-                if(iSide==0) {
-                  fnodes1[iNode++] = n;
-                }
-                else {
-                  fnodes2[iNode++] = n;
-                }
-              }
-            }
-            //faceNodes[ iSide ][ iNode ] = faceNodes[ iSide ][ 0 ];
-            if(iSide==0) {
-              fnodes1[iNode] = fnodes1[0];
+
+            // get not link nodes
+            int nbN = f->NbNodes();
+            if ( f->IsQuadratic() )
+              nbN /= 2;
+            nbNodes[ iSide ] = nbN;
+            list< const SMDS_MeshNode* > & nodes = notLinkNodes[ iSide ];
+            int i1 = f->GetNodeIndex( n1 );
+            int i2 = f->GetNodeIndex( n2 );
+            int iEnd = nbN, iBeg = -1, iDelta = 1;
+            bool reverse = ( Abs( i1 - i2 ) == 1 ? i1 > i2 : i2 > i1 );
+            if ( reverse ) {
+              std::swap( iEnd, iBeg ); iDelta = -1;
             }
-            else {
-              fnodes2[iNode] = fnodes1[0];
+            int i = i2;
+            while ( true ) {
+              i += iDelta;
+              if ( i == iEnd ) i = iBeg + iDelta;
+              if ( i == i1 ) break;
+              nodes.push_back ( f->GetNode( i ) );
             }
           }
         }
       }
     }
+    // check similarity of elements of the sides
+    if (( face[0] && !face[1] ) || ( !face[0] && face[1] )) {
+      MESSAGE("Correspondent face not found on side " << ( face[0] ? 1 : 0 ));
+      if ( nReplaceMap.size() == 2 ) { // faces on input nodes not found
+        return ( face[0] ? SEW_BAD_SIDE2_NODES : SEW_BAD_SIDE1_NODES );
+      }
+      else {
+        return SEW_TOPO_DIFF_SETS_OF_ELEMENTS;
+      }
+    }
+
+    // set nodes to merge
+    // -------------------
+
+    if ( face[0] && face[1] )  {
+      if ( nbNodes[0] != nbNodes[1] ) {
+        MESSAGE("Diff nb of face nodes");
+        return SEW_TOPO_DIFF_SETS_OF_ELEMENTS;
+      }
+#ifdef DEBUG_MATCHING_NODES
+      MESSAGE ( " Link 1: " << link[0].first->GetID() <<" "<< link[0].second->GetID()
+                << " F 1: " << face[0] << "| Link 2: " << link[1].first->GetID() <<" "
+                << link[1].second->GetID() << " F 2: " << face[1] << " | Bind: " ) ;
+#endif
+      int nbN = nbNodes[0];
+      {
+        list<const SMDS_MeshNode*>::iterator n1 = notLinkNodes[0].begin();
+        list<const SMDS_MeshNode*>::iterator n2 = notLinkNodes[1].begin();
+        for ( int i = 0 ; i < nbN - 2; ++i ) {
+#ifdef DEBUG_MATCHING_NODES
+          MESSAGE ( (*n1)->GetID() << " to " << (*n2)->GetID() );
+#endif
+          nReplaceMap.insert( make_pair( *(n1++), *(n2++) ));
+        }
+      }
+
+      // add other links of the face 1 to linkList
+      // -----------------------------------------
+
+      const SMDS_MeshElement* f0 = face[0];
+      const SMDS_MeshNode* n1 = f0->GetNode( nbN - 1 );
+      for ( int i = 0; i < nbN; i++ )
+      {
+        const SMDS_MeshNode* n2 = f0->GetNode( i );
+        pair< set< SMESH_TLink >::iterator, bool > iter_isnew =
+          linkSet.insert( SMESH_TLink( n1, n2 ));
+        if ( !iter_isnew.second ) { // already in a set: no need to process
+          linkSet.erase( iter_isnew.first );
+        }
+        else // new in set == encountered for the first time: add
+        {
+#ifdef DEBUG_MATCHING_NODES
+          MESSAGE ( "Add link 1: " << n1->GetID() << " " << n2->GetID() << " "
+                    << " | link 2: " << nReplaceMap[n1]->GetID() << " " << nReplaceMap[n2]->GetID() << " " );
+#endif
+          linkList[0].push_back ( NLink( n1, n2 ));
+          linkList[1].push_back ( NLink( nReplaceMap[n1], nReplaceMap[n2] ));
+        }
+        n1 = n2;
+      }
+    } // 2 faces found
+  } // loop on link lists
+
+  return SEW_OK;
+}
+
+//================================================================================
+/*!
+  \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+  \param theElems - the list of elements (edges or faces) to be replicated
+  The nodes for duplication could be found from these elements
+  \param theNodesNot - list of nodes to NOT replicate
+  \param theAffectedElems - the list of elements (cells and edges) to which the 
+  replicated nodes should be associated to.
+  \return TRUE if operation has been completed successfully, FALSE otherwise
+*/
+//================================================================================
+
+bool SMESH_MeshEditor::DoubleNodes( const TIDSortedElemSet& theElems,
+                                    const TIDSortedElemSet& theNodesNot,
+                                    const TIDSortedElemSet& theAffectedElems )
+{
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
+
+  if ( theElems.size() == 0 )
+    return false;
+
+  SMESHDS_Mesh* aMeshDS = GetMeshDS();
+  if ( !aMeshDS )
+    return false;
+
+  bool res = false;
+  std::map< const SMDS_MeshNode*, const SMDS_MeshNode* > anOldNodeToNewNode;
+  // duplicate elements and nodes
+  res = doubleNodes( aMeshDS, theElems, theNodesNot, anOldNodeToNewNode, true );
+  // replce nodes by duplications
+  res = doubleNodes( aMeshDS, theAffectedElems, theNodesNot, anOldNodeToNewNode, false );
+  return res;
+}
+
+//================================================================================
+/*!
+  \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+  \param theMeshDS - mesh instance
+  \param theElems - the elements replicated or modified (nodes should be changed)
+  \param theNodesNot - nodes to NOT replicate
+  \param theNodeNodeMap - relation of old node to new created node
+  \param theIsDoubleElem - flag os to replicate element or modify
+  \return TRUE if operation has been completed successfully, FALSE otherwise
+*/
+//================================================================================
+
+bool SMESH_MeshEditor::doubleNodes( SMESHDS_Mesh*     theMeshDS,
+                                    const TIDSortedElemSet& theElems,
+                                    const TIDSortedElemSet& theNodesNot,
+                                    std::map< const SMDS_MeshNode*,
+                                    const SMDS_MeshNode* >& theNodeNodeMap,
+                                    const bool theIsDoubleElem )
+{
+  MESSAGE("doubleNodes");
+  // iterate on through element and duplicate them (by nodes duplication)
+  bool res = false;
+  TIDSortedElemSet::const_iterator elemItr = theElems.begin();
+  for ( ;  elemItr != theElems.end(); ++elemItr )
+  {
+    const SMDS_MeshElement* anElem = *elemItr;
+    if (!anElem)
+      continue;
+
+    bool isDuplicate = false;
+    // duplicate nodes to duplicate element
+    std::vector<const SMDS_MeshNode*> newNodes( anElem->NbNodes() );
+    SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
+    int ind = 0;
+    while ( anIter->more() ) 
+    { 
+
+      SMDS_MeshNode* aCurrNode = (SMDS_MeshNode*)anIter->next();
+      SMDS_MeshNode* aNewNode = aCurrNode;
+      if ( theNodeNodeMap.find( aCurrNode ) != theNodeNodeMap.end() )
+        aNewNode = (SMDS_MeshNode*)theNodeNodeMap[ aCurrNode ];
+      else if ( theIsDoubleElem && theNodesNot.find( aCurrNode ) == theNodesNot.end() )
+      {
+        // duplicate node
+        aNewNode = theMeshDS->AddNode( aCurrNode->X(), aCurrNode->Y(), aCurrNode->Z() );
+        theNodeNodeMap[ aCurrNode ] = aNewNode;
+        myLastCreatedNodes.Append( aNewNode );
+      }
+      isDuplicate |= (aCurrNode != aNewNode);
+      newNodes[ ind++ ] = aNewNode;
+    }
+    if ( !isDuplicate )
+      continue;
+
+    if ( theIsDoubleElem )
+      AddElement(newNodes, anElem->GetType(), anElem->IsPoly());
+    else
+      {
+      MESSAGE("ChangeElementNodes");
+      theMeshDS->ChangeElementNodes( anElem, &newNodes[ 0 ], anElem->NbNodes() );
+      }
+    res = true;
+  }
+  return res;
+}
+
+//================================================================================
+/*!
+  \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+  \param theNodes - identifiers of nodes to be doubled
+  \param theModifiedElems - identifiers of elements to be updated by the new (doubled) 
+         nodes. If list of element identifiers is empty then nodes are doubled but 
+         they not assigned to elements
+  \return TRUE if operation has been completed successfully, FALSE otherwise
+*/
+//================================================================================
+
+bool SMESH_MeshEditor::DoubleNodes( const std::list< int >& theListOfNodes, 
+                                    const std::list< int >& theListOfModifiedElems )
+{
+  MESSAGE("DoubleNodes");
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
+
+  if ( theListOfNodes.size() == 0 )
+    return false;
+
+  SMESHDS_Mesh* aMeshDS = GetMeshDS();
+  if ( !aMeshDS )
+    return false;
+
+  // iterate through nodes and duplicate them
+
+  std::map< const SMDS_MeshNode*, const SMDS_MeshNode* > anOldNodeToNewNode;
+
+  std::list< int >::const_iterator aNodeIter;
+  for ( aNodeIter = theListOfNodes.begin(); aNodeIter != theListOfNodes.end(); ++aNodeIter )
+  {
+    int aCurr = *aNodeIter;
+    SMDS_MeshNode* aNode = (SMDS_MeshNode*)aMeshDS->FindNode( aCurr );
+    if ( !aNode )
+      continue;
+
+    // duplicate node
+
+    const SMDS_MeshNode* aNewNode = aMeshDS->AddNode( aNode->X(), aNode->Y(), aNode->Z() );
+    if ( aNewNode )
+    {
+      anOldNodeToNewNode[ aNode ] = aNewNode;
+      myLastCreatedNodes.Append( aNewNode );
+    }
+  }
+
+  // Create map of new nodes for modified elements
+
+  std::map< SMDS_MeshElement*, vector<const SMDS_MeshNode*> > anElemToNodes;
+
+  std::list< int >::const_iterator anElemIter;
+  for ( anElemIter = theListOfModifiedElems.begin(); 
+        anElemIter != theListOfModifiedElems.end(); ++anElemIter )
+  {
+    int aCurr = *anElemIter;
+    SMDS_MeshElement* anElem = (SMDS_MeshElement*)aMeshDS->FindElement( aCurr );
+    if ( !anElem )
+      continue;
 
-    // check similarity of elements of the sides
-    if (aResult == SEW_OK && ( face[0] && !face[1] ) || ( !face[0] && face[1] )) {
-      MESSAGE("Correspondent face not found on side " << ( face[0] ? 1 : 0 ));
-      if ( nReplaceMap.size() == 2 ) { // faces on input nodes not found
-        aResult = ( face[0] ? SEW_BAD_SIDE2_NODES : SEW_BAD_SIDE1_NODES );
-      }
-      else {
-        aResult = SEW_TOPO_DIFF_SETS_OF_ELEMENTS;
+    vector<const SMDS_MeshNode*> aNodeArr( anElem->NbNodes() );
+
+    SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
+    int ind = 0;
+    while ( anIter->more() ) 
+    { 
+      SMDS_MeshNode* aCurrNode = (SMDS_MeshNode*)anIter->next();
+      if ( aCurr && anOldNodeToNewNode.find( aCurrNode ) != anOldNodeToNewNode.end() )
+      {
+        const SMDS_MeshNode* aNewNode = anOldNodeToNewNode[ aCurrNode ];
+        aNodeArr[ ind++ ] = aNewNode;
       }
-      break; // do not return because it s necessary to remove tmp faces
+      else
+        aNodeArr[ ind++ ] = aCurrNode;
     }
+    anElemToNodes[ anElem ] = aNodeArr;
+  }
 
-    // set nodes to merge
-    // -------------------
+  // Change nodes of elements  
 
-    if ( face[0] && face[1] )  {
-      int nbNodes = face[0]->NbNodes();
-      if ( nbNodes != face[1]->NbNodes() ) {
-        MESSAGE("Diff nb of face nodes");
-        aResult = SEW_TOPO_DIFF_SETS_OF_ELEMENTS;
-        break; // do not return because it s necessary to remove tmp faces
-      }
-      bool reverse[] = { false, false }; // order of notLinkNodes of quadrangle
-      if ( nbNodes == 3 ) {
-        //nReplaceMap.insert( TNodeNodeMap::value_type
-        //                   ( notLinkNodes[0][0], notLinkNodes[1][0] ));
-        nReplaceMap.insert( TNodeNodeMap::value_type
-                           ( notLinkNodes1[0], notLinkNodes2[0] ));
-      }
-      else {
-        for ( iSide = 0; iSide < 2; iSide++ ) { // loop on 2 sides
-          // analyse link orientation in faces
-          int i1 = iLinkNode[ iSide ][ 0 ];
-          int i2 = iLinkNode[ iSide ][ 1 ];
-          reverse[ iSide ] = Abs( i1 - i2 ) == 1 ? i1 > i2 : i2 > i1;
-          // if notLinkNodes are the first and the last ones, then
-          // their order does not correspond to the link orientation
-          if (( i1 == 1 && i2 == 2 ) ||
-              ( i1 == 2 && i2 == 1 ))
-            reverse[ iSide ] = !reverse[ iSide ];
-        }
-        if ( reverse[0] == reverse[1] ) {
-          //nReplaceMap.insert( TNodeNodeMap::value_type
-          //                   ( notLinkNodes[0][0], notLinkNodes[1][0] ));
-          //nReplaceMap.insert( TNodeNodeMap::value_type
-          //                   ( notLinkNodes[0][1], notLinkNodes[1][1] ));
-          for(int nn=0; nn<nbNodes-2; nn++) {
-            nReplaceMap.insert( TNodeNodeMap::value_type
-                             ( notLinkNodes1[nn], notLinkNodes2[nn] ));
-          }
-        }
-        else {
-          //nReplaceMap.insert( TNodeNodeMap::value_type
-          //                   ( notLinkNodes[0][0], notLinkNodes[1][1] ));
-          //nReplaceMap.insert( TNodeNodeMap::value_type
-          //                   ( notLinkNodes[0][1], notLinkNodes[1][0] ));
-          for(int nn=0; nn<nbNodes-2; nn++) {
-            nReplaceMap.insert( TNodeNodeMap::value_type
-                             ( notLinkNodes1[nn], notLinkNodes2[nbNodes-3-nn] ));
-          }
-        }
+  std::map< SMDS_MeshElement*, vector<const SMDS_MeshNode*> >::iterator
+    anElemToNodesIter = anElemToNodes.begin();
+  for ( ; anElemToNodesIter != anElemToNodes.end(); ++anElemToNodesIter )
+  {
+    const SMDS_MeshElement* anElem = anElemToNodesIter->first;
+    vector<const SMDS_MeshNode*> aNodeArr = anElemToNodesIter->second;
+    if ( anElem )
+      {
+      MESSAGE("ChangeElementNodes");
+      aMeshDS->ChangeElementNodes( anElem, &aNodeArr[ 0 ], anElem->NbNodes() );
       }
+  }
 
-      // add other links of the faces to linkList
-      // -----------------------------------------
+  return true;
+}
 
-      //const SMDS_MeshNode** nodes = faceNodes[ 0 ];
-      for ( iNode = 0; iNode < nbNodes; iNode++ )  {
-        //linkID = aLinkID_Gen.GetLinkID( nodes[iNode], nodes[iNode+1] );
-        linkID = aLinkID_Gen.GetLinkID( fnodes1[iNode], fnodes1[iNode+1] );
-        pair< set<long>::iterator, bool > iter_isnew = linkIdSet.insert( linkID );
-        if ( !iter_isnew.second ) { // already in a set: no need to process
-          linkIdSet.erase( iter_isnew.first );
-        }
-        else // new in set == encountered for the first time: add
-        {
-          //const SMDS_MeshNode* n1 = nodes[ iNode ];
-          //const SMDS_MeshNode* n2 = nodes[ iNode + 1];
-          const SMDS_MeshNode* n1 = fnodes1[ iNode ];
-          const SMDS_MeshNode* n2 = fnodes1[ iNode + 1];
-          linkList[0].push_back ( NLink( n1, n2 ));
-          linkList[1].push_back ( NLink( nReplaceMap[n1], nReplaceMap[n2] ));
-        }
-      }
-    } // 2 faces found
-  } // loop on link lists
+namespace {
 
-  if ( aResult == SEW_OK &&
-      ( linkIt[0] != linkList[0].end() ||
-       !faceSetPtr[0]->empty() || !faceSetPtr[1]->empty() )) {
-    MESSAGE( (linkIt[0] != linkList[0].end()) <<" "<< (faceSetPtr[0]->empty()) <<
-            " " << (faceSetPtr[1]->empty()));
-    aResult = SEW_TOPO_DIFF_SETS_OF_ELEMENTS;
+  //================================================================================
+  /*!
+  \brief Check if element located inside shape
+  \return TRUE if IN or ON shape, FALSE otherwise
+  */
+  //================================================================================
+
+  template<class Classifier>
+  bool isInside(const SMDS_MeshElement* theElem,
+                Classifier&             theClassifier,
+                const double            theTol)
+  {
+    gp_XYZ centerXYZ (0, 0, 0);
+    SMDS_ElemIteratorPtr aNodeItr = theElem->nodesIterator();
+    while (aNodeItr->more())
+      centerXYZ += SMESH_TNodeXYZ(cast2Node( aNodeItr->next()));
+
+    gp_Pnt aPnt = centerXYZ / theElem->NbNodes();
+    theClassifier.Perform(aPnt, theTol);
+    TopAbs_State aState = theClassifier.State();
+    return (aState == TopAbs_IN || aState == TopAbs_ON );
   }
 
-  // ====================================================================
-  // 3. Replace nodes in elements of the side 1 and remove replaced nodes
-  // ====================================================================
-
-  // delete temporary faces: they are in reverseElements of actual nodes
-  SMDS_FaceIteratorPtr tmpFaceIt = aTmpFacesMesh.facesIterator();
-  while ( tmpFaceIt->more() )
-    aTmpFacesMesh.RemoveElement( tmpFaceIt->next() );
+  //================================================================================
+  /*!
+   * \brief Classifier of the 3D point on the TopoDS_Face
+   *        with interaface suitable for isInside()
+   */
+  //================================================================================
 
-  if ( aResult != SEW_OK)
-    return aResult;
+  struct _FaceClassifier
+  {
+    Extrema_ExtPS       _extremum;
+    BRepAdaptor_Surface _surface;
+    TopAbs_State        _state;
 
-  list< int > nodeIDsToRemove/*, elemIDsToRemove*/;
-  // loop on nodes replacement map
-  TNodeNodeMap::iterator nReplaceMapIt = nReplaceMap.begin(), nnIt;
-  for ( ; nReplaceMapIt != nReplaceMap.end(); nReplaceMapIt++ )
-    if ( (*nReplaceMapIt).first != (*nReplaceMapIt).second ) {
-      const SMDS_MeshNode* nToRemove = (*nReplaceMapIt).first;
-      nodeIDsToRemove.push_back( nToRemove->GetID() );
-      // loop on elements sharing nToRemove
-      SMDS_ElemIteratorPtr invElemIt = nToRemove->GetInverseElementIterator();
-      while ( invElemIt->more() ) {
-        const SMDS_MeshElement* e = invElemIt->next();
-        // get a new suite of nodes: make replacement
-        int nbReplaced = 0, i = 0, nbNodes = e->NbNodes();
-        vector< const SMDS_MeshNode*> nodes( nbNodes );
-        SMDS_ElemIteratorPtr nIt = e->nodesIterator();
-        while ( nIt->more() ) {
-          const SMDS_MeshNode* n =
-            static_cast<const SMDS_MeshNode*>( nIt->next() );
-          nnIt = nReplaceMap.find( n );
-          if ( nnIt != nReplaceMap.end() ) {
-            nbReplaced++;
-            n = (*nnIt).second;
-          }
-          nodes[ i++ ] = n;
-        }
-        //       if ( nbReplaced == nbNodes && e->GetType() == SMDSAbs_Face )
-        //         elemIDsToRemove.push_back( e->GetID() );
-        //       else
-        if ( nbReplaced )
-          aMesh->ChangeElementNodes( e, & nodes[0], nbNodes );
-      }
+    _FaceClassifier(const TopoDS_Face& face):_extremum(),_surface(face),_state(TopAbs_OUT)
+    {
+      _extremum.Initialize( _surface,
+                            _surface.FirstUParameter(), _surface.LastUParameter(),
+                            _surface.FirstVParameter(), _surface.LastVParameter(),
+                            _surface.Tolerance(), _surface.Tolerance() );
     }
-
-  Remove( nodeIDsToRemove, true );
-
-  return aResult;
+    void Perform(const gp_Pnt& aPnt, double theTol)
+    {
+      _state = TopAbs_OUT;
+      _extremum.Perform(aPnt);
+      if ( _extremum.IsDone() )
+        for ( int iSol = 1; iSol <= _extremum.NbExt() && _state == TopAbs_OUT; ++iSol)
+#if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
+          _state = ( _extremum.SquareDistance(iSol) <= theTol ? TopAbs_IN : TopAbs_OUT );
+#else
+          _state = ( _extremum.Value(iSol) <= theTol ? TopAbs_IN : TopAbs_OUT );
+#endif
+    }
+    TopAbs_State State() const
+    {
+      return _state;
+    }
+  };
 }
 
 //================================================================================
-  /*!
-   * \brief Find corresponding nodes in two sets of faces
-    * \param theSide1 - first face set
-    * \param theSide2 - second first face
-    * \param theFirstNode1 - a boundary node of set 1
-    * \param theFirstNode2 - a node of set 2 corresponding to theFirstNode1
-    * \param theSecondNode1 - a boundary node of set 1 linked with theFirstNode1
-    * \param theSecondNode2 - a node of set 2 corresponding to theSecondNode1
-    * \param nReplaceMap - output map of corresponding nodes
-    * \retval bool  - is a success or not
-   */
+/*!
+  \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+  \param theElems - group of of elements (edges or faces) to be replicated
+  \param theNodesNot - group of nodes not to replicate
+  \param theShape - shape to detect affected elements (element which geometric center
+  located on or inside shape).
+  The replicated nodes should be associated to affected elements.
+  \return TRUE if operation has been completed successfully, FALSE otherwise
+*/
 //================================================================================
 
-#ifdef _DEBUG_
-//#define DEBUG_MATCHING_NODES
-#endif
+bool SMESH_MeshEditor::DoubleNodesInRegion( const TIDSortedElemSet& theElems,
+                                            const TIDSortedElemSet& theNodesNot,
+                                            const TopoDS_Shape&     theShape )
+{
+  if ( theShape.IsNull() )
+    return false;
 
-SMESH_MeshEditor::Sew_Error
-SMESH_MeshEditor::FindMatchingNodes(set<const SMDS_MeshElement*>& theSide1,
-                                    set<const SMDS_MeshElement*>& theSide2,
-                                    const SMDS_MeshNode*          theFirstNode1,
-                                    const SMDS_MeshNode*          theFirstNode2,
-                                    const SMDS_MeshNode*          theSecondNode1,
-                                    const SMDS_MeshNode*          theSecondNode2,
-                                    TNodeNodeMap &                nReplaceMap)
+  const double aTol = Precision::Confusion();
+  auto_ptr< BRepClass3d_SolidClassifier> bsc3d;
+  auto_ptr<_FaceClassifier>              aFaceClassifier;
+  if ( theShape.ShapeType() == TopAbs_SOLID )
+  {
+    bsc3d.reset( new BRepClass3d_SolidClassifier(theShape));;
+    bsc3d->PerformInfinitePoint(aTol);
+  }
+  else if (theShape.ShapeType() == TopAbs_FACE )
+  {
+    aFaceClassifier.reset( new _FaceClassifier(TopoDS::Face(theShape)));
+  }
+
+  // iterates on indicated elements and get elements by back references from their nodes
+  TIDSortedElemSet anAffected;
+  TIDSortedElemSet::const_iterator elemItr = theElems.begin();
+  for ( ;  elemItr != theElems.end(); ++elemItr )
+  {
+    SMDS_MeshElement* anElem = (SMDS_MeshElement*)*elemItr;
+    if (!anElem)
+      continue;
+
+    SMDS_ElemIteratorPtr nodeItr = anElem->nodesIterator();
+    while ( nodeItr->more() )
+    {
+      const SMDS_MeshNode* aNode = cast2Node(nodeItr->next());
+      if ( !aNode || theNodesNot.find(aNode) != theNodesNot.end() )
+        continue;
+      SMDS_ElemIteratorPtr backElemItr = aNode->GetInverseElementIterator();
+      while ( backElemItr->more() )
+      {
+        const SMDS_MeshElement* curElem = backElemItr->next();
+        if ( curElem && theElems.find(curElem) == theElems.end() &&
+             ( bsc3d.get() ?
+               isInside( curElem, *bsc3d, aTol ) :
+               isInside( curElem, *aFaceClassifier, aTol )))
+          anAffected.insert( curElem );
+      }
+    }
+  }
+  return DoubleNodes( theElems, theNodesNot, anAffected );
+}
+
+/*!
+ *  \brief compute an oriented angle between two planes defined by four points.
+ *  The vector (p0,p1) defines the intersection of the 2 planes (p0,p1,g1) and (p0,p1,g2)
+ *  @param p0 base of the rotation axe
+ *  @param p1 extremity of the rotation axe
+ *  @param g1 belongs to the first plane
+ *  @param g2 belongs to the second plane
+ */
+double SMESH_MeshEditor::OrientedAngle(const gp_Pnt& p0, const gp_Pnt& p1, const gp_Pnt& g1, const gp_Pnt& g2)
 {
-  set<const SMDS_MeshElement*> * faceSetPtr[] = { &theSide1, &theSide2 };
+//  MESSAGE("    p0: " << p0.X() << " " << p0.Y() << " " << p0.Z());
+//  MESSAGE("    p1: " << p1.X() << " " << p1.Y() << " " << p1.Z());
+//  MESSAGE("    g1: " << g1.X() << " " << g1.Y() << " " << g1.Z());
+//  MESSAGE("    g2: " << g2.X() << " " << g2.Y() << " " << g2.Z());
+  gp_Vec vref(p0, p1);
+  gp_Vec v1(p0, g1);
+  gp_Vec v2(p0, g2);
+  gp_Vec n1 = vref.Crossed(v1);
+  gp_Vec n2 = vref.Crossed(v2);
+  return n2.AngleWithRef(n1, vref);
+}
 
-  nReplaceMap.clear();
-  if ( theFirstNode1 != theFirstNode2 )
-    nReplaceMap.insert( make_pair( theFirstNode1, theFirstNode2 ));
-  if ( theSecondNode1 != theSecondNode2 )
-    nReplaceMap.insert( make_pair( theSecondNode1, theSecondNode2 ));
+/*!
+ * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
+ * The list of groups must describe a partition of the mesh volumes.
+ * The nodes of the internal faces at the boundaries of the groups are doubled.
+ * In option, the internal faces are replaced by flat elements.
+ * Triangles are transformed in prisms, and quadrangles in hexahedrons.
+ * The flat elements are stored in groups of volumes.
+ * @param theElems - list of groups of volumes, where a group of volume is a set of
+ * SMDS_MeshElements sorted by Id.
+ * @param createJointElems - if TRUE, create the elements
+ * @return TRUE if operation has been completed successfully, FALSE otherwise
+ */
+bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSortedElemSet>& theElems,
+                                                     bool createJointElems)
+{
+  MESSAGE("----------------------------------------------");
+  MESSAGE("SMESH_MeshEditor::doubleNodesOnGroupBoundaries");
+  MESSAGE("----------------------------------------------");
+
+  SMESHDS_Mesh *meshDS = this->myMesh->GetMeshDS();
+  meshDS->BuildDownWardConnectivity(true);
+  CHRONO(50);
+  SMDS_UnstructuredGrid *grid = meshDS->getGrid();
+
+  // --- build the list of faces shared by 2 domains (group of elements), with their domain and volume indexes
+  //     build the list of cells with only a node or an edge on the border, with their domain and volume indexes
+  //     build the list of nodes shared by 2 or more domains, with their domain indexes
+
+  std::map<DownIdType, std::map<int,int>, DownIdCompare> faceDomains; // face --> (id domain --> id volume)
+  std::map<int,int>celldom; // cell vtkId --> domain
+  std::map<DownIdType, std::map<int,int>, DownIdCompare> cellDomains;  // oldNode --> (id domain --> id cell)
+  std::map<int, std::map<int,int> > nodeDomains; // oldId -->  (domainId --> newId)
+  faceDomains.clear();
+  celldom.clear();
+  cellDomains.clear();
+  nodeDomains.clear();
+  std::map<int,int> emptyMap;
+  std::set<int> emptySet;
+  emptyMap.clear();
+
+  for (int idom = 0; idom < theElems.size(); idom++)
+    {
 
-  set< SMESH_TLink > linkSet; // set of nodes where order of nodes is ignored
-  linkSet.insert( SMESH_TLink( theFirstNode1, theSecondNode1 ));
+      // --- build a map (face to duplicate --> volume to modify)
+      //     with all the faces shared by 2 domains (group of elements)
+      //     and corresponding volume of this domain, for each shared face.
+      //     a volume has a face shared by 2 domains if it has a neighbor which is not in is domain.
 
-  list< NLink > linkList[2];
-  linkList[0].push_back( NLink( theFirstNode1, theSecondNode1 ));
-  linkList[1].push_back( NLink( theFirstNode2, theSecondNode2 ));
+      //MESSAGE("Domain " << idom);
+      const TIDSortedElemSet& domain = theElems[idom];
+      TIDSortedElemSet::const_iterator elemItr = domain.begin();
+      for (; elemItr != domain.end(); ++elemItr)
+        {
+          SMDS_MeshElement* anElem = (SMDS_MeshElement*) *elemItr;
+          if (!anElem)
+            continue;
+          int vtkId = anElem->getVtkId();
+          //MESSAGE("  vtkId " << vtkId << " smdsId " << anElem->GetID());
+          int neighborsVtkIds[NBMAXNEIGHBORS];
+          int downIds[NBMAXNEIGHBORS];
+          unsigned char downTypes[NBMAXNEIGHBORS];
+          int nbNeighbors = grid->GetNeighbors(neighborsVtkIds, downIds, downTypes, vtkId);
+          for (int n = 0; n < nbNeighbors; n++)
+            {
+              int smdsId = meshDS->fromVtkToSmds(neighborsVtkIds[n]);
+              const SMDS_MeshElement* elem = meshDS->FindElement(smdsId);
+              if (! domain.count(elem)) // neighbor is in another domain : face is shared
+                {
+                  DownIdType face(downIds[n], downTypes[n]);
+                  if (!faceDomains.count(face))
+                    faceDomains[face] = emptyMap; // create an empty entry for face
+                  if (!faceDomains[face].count(idom))
+                    {
+                      faceDomains[face][idom] = vtkId; // volume associated to face in this domain
+                      celldom[vtkId] = idom;
+                      //MESSAGE("       cell with a border " << vtkId << " domain " << idom);
+                    }
+                }
+            }
+        }
+    }
 
-  // loop on links in linkList; find faces by links and append links
-  // of the found faces to linkList
-  list< NLink >::iterator linkIt[] = { linkList[0].begin(), linkList[1].begin() } ;
-  for ( ; linkIt[0] != linkList[0].end(); linkIt[0]++, linkIt[1]++ ) {
-    NLink link[] = { *linkIt[0], *linkIt[1] };
-    if ( linkSet.find( link[0] ) == linkSet.end() )
-      continue;
+  //MESSAGE("Number of shared faces " << faceDomains.size());
+  std::map<DownIdType, std::map<int, int>, DownIdCompare>::iterator itface;
 
-    // by links, find faces in the face sets,
-    // and find indices of link nodes in the found faces;
-    // in a face set, there is only one or no face sharing a link
-    // ---------------------------------------------------------------
+  // --- explore the shared faces domain by domain,
+  //     explore the nodes of the face and see if they belong to a cell in the domain,
+  //     which has only a node or an edge on the border (not a shared face)
 
-    const SMDS_MeshElement* face[] = { 0, 0 };
-    list<const SMDS_MeshNode*> notLinkNodes[2];
-    //bool reverse[] = { false, false }; // order of notLinkNodes
-    int nbNodes[2];
-    for ( int iSide = 0; iSide < 2; iSide++ ) // loop on 2 sides
+  for (int idomain = 0; idomain < theElems.size(); idomain++)
     {
-      const SMDS_MeshNode* n1 = link[iSide].first;
-      const SMDS_MeshNode* n2 = link[iSide].second;
-      set<const SMDS_MeshElement*> * faceSet = faceSetPtr[ iSide ];
-      set< const SMDS_MeshElement* > facesOfNode1;
-      for ( int iNode = 0; iNode < 2; iNode++ ) // loop on 2 nodes of a link
-      {
-        // during a loop of the first node, we find all faces around n1,
-        // during a loop of the second node, we find one face sharing both n1 and n2
-        const SMDS_MeshNode* n = iNode ? n1 : n2; // a node of a link
-        SMDS_ElemIteratorPtr fIt = n->GetInverseElementIterator(SMDSAbs_Face);
-        while ( fIt->more() ) { // loop on faces sharing a node
-          const SMDS_MeshElement* f = fIt->next();
-          if (faceSet->find( f ) != faceSet->end() && // f is in face set
-              ! facesOfNode1.insert( f ).second ) // f encounters twice
-          {
-            if ( face[ iSide ] ) {
-              MESSAGE( "2 faces per link " );
-              return ( iSide ? SEW_BAD_SIDE2_NODES : SEW_BAD_SIDE1_NODES );
+      //MESSAGE("Domain " << idomain);
+      const TIDSortedElemSet& domain = theElems[idomain];
+      itface = faceDomains.begin();
+      for (; itface != faceDomains.end(); ++itface)
+        {
+          std::map<int, int> domvol = itface->second;
+          if (!domvol.count(idomain))
+            continue;
+          DownIdType face = itface->first;
+          //MESSAGE(" --- face " << face.cellId);
+          std::set<int> oldNodes;
+          oldNodes.clear();
+          grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
+          std::set<int>::iterator itn = oldNodes.begin();
+          for (; itn != oldNodes.end(); ++itn)
+            {
+              int oldId = *itn;
+              //MESSAGE("     node " << oldId);
+              std::set<int> cells;
+              cells.clear();
+              vtkCellLinks::Link l = grid->GetCellLinks()->GetLink(oldId);
+              for (int i=0; i<l.ncells; i++)
+                {
+                  int vtkId = l.cells[i];
+                  const SMDS_MeshElement* anElem = GetMeshDS()->FindElement(GetMeshDS()->fromVtkToSmds(vtkId));
+                  if (!domain.count(anElem))
+                    continue;
+                  int vtkType = grid->GetCellType(vtkId);
+                  int downId = grid->CellIdToDownId(vtkId);
+                  if (downId < 0)
+                    {
+                      MESSAGE("doubleNodesOnGroupBoundaries: internal algorithm problem");
+                      continue; // not OK at this stage of the algorithm:
+                                //no cells created after BuildDownWardConnectivity
+                    }
+                  DownIdType aCell(downId, vtkType);
+                  if (celldom.count(vtkId))
+                    continue;
+                  cellDomains[aCell][idomain] = vtkId;
+                  celldom[vtkId] = idomain;
+                  //MESSAGE("       cell " << vtkId << " domain " << idomain);
+                }
             }
-            face[ iSide ] = f;
-            faceSet->erase( f );
+        }
+    }
 
-            // get not link nodes
-            int nbN = f->NbNodes();
-            if ( f->IsQuadratic() )
-              nbN /= 2;
-            nbNodes[ iSide ] = nbN;
-            list< const SMDS_MeshNode* > & nodes = notLinkNodes[ iSide ];
-            int i1 = f->GetNodeIndex( n1 );
-            int i2 = f->GetNodeIndex( n2 );
-            int iEnd = nbN, iBeg = -1, iDelta = 1;
-            bool reverse = ( Abs( i1 - i2 ) == 1 ? i1 > i2 : i2 > i1 );
-            if ( reverse ) {
-              std::swap( iEnd, iBeg ); iDelta = -1;
+  // --- explore the shared faces domain by domain, to duplicate the nodes in a coherent way
+  //     for each shared face, get the nodes
+  //     for each node, for each domain of the face, create a clone of the node
+
+  // --- edges at the intersection of 3 or 4 domains, with the order of domains to build
+  //     junction elements of type prism or hexa. the key is the pair of nodesId (lower first)
+  //     the value is the ordered domain ids. (more than 4 domains not taken into account)
+
+  std::map<std::vector<int>, std::vector<int> > edgesMultiDomains; // nodes of edge --> ordered domains
+  std::map<int, std::vector<int> > mutipleNodes; // nodes multi domains with domain order
+  std::map<int, std::vector<int> > mutipleNodesToFace; // nodes multi domains with domain order to transform in Face (junction between 3 or more 2D domains)
+
+  for (int idomain = 0; idomain < theElems.size(); idomain++)
+    {
+      itface = faceDomains.begin();
+      for (; itface != faceDomains.end(); ++itface)
+        {
+          std::map<int, int> domvol = itface->second;
+          if (!domvol.count(idomain))
+            continue;
+          DownIdType face = itface->first;
+          //MESSAGE(" --- face " << face.cellId);
+          std::set<int> oldNodes;
+          oldNodes.clear();
+          grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
+          bool isMultipleDetected = false;
+          std::set<int>::iterator itn = oldNodes.begin();
+          for (; itn != oldNodes.end(); ++itn)
+            {
+              int oldId = *itn;
+              //MESSAGE("     node " << oldId);
+              if (!nodeDomains.count(oldId))
+                nodeDomains[oldId] = emptyMap; // create an empty entry for node
+              if (nodeDomains[oldId].empty())
+                nodeDomains[oldId][idomain] = oldId; // keep the old node in the first domain
+              std::map<int, int>::iterator itdom = domvol.begin();
+              for (; itdom != domvol.end(); ++itdom)
+                {
+                  int idom = itdom->first;
+                  //MESSAGE("         domain " << idom);
+                  if (!nodeDomains[oldId].count(idom)) // --- node to clone
+                    {
+                      if (nodeDomains[oldId].size() >= 2) // a multiple node
+                        {
+                          vector<int> orderedDoms;
+                          //MESSAGE("multiple node " << oldId);
+                          isMultipleDetected =true;
+                          if (mutipleNodes.count(oldId))
+                            orderedDoms = mutipleNodes[oldId];
+                          else
+                            {
+                              map<int,int>::iterator it = nodeDomains[oldId].begin();
+                              for (; it != nodeDomains[oldId].end(); ++it)
+                                orderedDoms.push_back(it->first);
+                            }
+                          orderedDoms.push_back(idom); // TODO order ==> push_front or back
+                          //stringstream txt;
+                          //for (int i=0; i<orderedDoms.size(); i++)
+                          //  txt << orderedDoms[i] << " ";
+                          //MESSAGE("orderedDoms " << txt.str());
+                          mutipleNodes[oldId] = orderedDoms;
+                        }
+                      double *coords = grid->GetPoint(oldId);
+                      SMDS_MeshNode *newNode = meshDS->AddNode(coords[0], coords[1], coords[2]);
+                      int newId = newNode->getVtkId();
+                      nodeDomains[oldId][idom] = newId; // cloned node for other domains
+                      //MESSAGE("   newNode " << newId << " oldNode " << oldId << " size=" <<nodeDomains[oldId].size());
+                    }
+                  if (nodeDomains[oldId].size() >= 3)
+                    {
+                      //MESSAGE("confirm multiple node " << oldId);
+                      isMultipleDetected =true;
+                    }
+                }
             }
-            int i = i2;
-            while ( true ) {
-              i += iDelta;
-              if ( i == iEnd ) i = iBeg + iDelta;
-              if ( i == i1 ) break;
-              nodes.push_back ( f->GetNode( i ) );
+          if (isMultipleDetected) // check if an edge of the face is shared between 3 or more domains
+            {
+              //MESSAGE("multiple Nodes detected on a shared face");
+              int downId = itface->first.cellId;
+              unsigned char cellType = itface->first.cellType;
+              // --- shared edge or shared face ?
+              if ((cellType == VTK_LINE) || (cellType == VTK_QUADRATIC_EDGE)) // shared edge (between two faces)
+                {
+                  int nodes[3];
+                  int nbNodes = grid->getDownArray(cellType)->getNodes(downId, nodes);
+                  for (int i=0; i< nbNodes; i=i+nbNodes-1) // i=0 , i=nbNodes-1
+                    if (mutipleNodes.count(nodes[i]))
+                      if (!mutipleNodesToFace.count(nodes[i]))
+                        mutipleNodesToFace[nodes[i]] = mutipleNodes[nodes[i]];
+               }
+              else // shared face (between two volumes)
+                {
+                  int nbEdges = grid->getDownArray(cellType)->getNumberOfDownCells(downId);
+                  const int* downEdgeIds = grid->getDownArray(cellType)->getDownCells(downId);
+                  const unsigned char* edgeType = grid->getDownArray(cellType)->getDownTypes(downId);
+                  for (int ie =0; ie < nbEdges; ie++)
+                    {
+                      int nodes[3];
+                      int nbNodes = grid->getDownArray(edgeType[ie])->getNodes(downEdgeIds[ie], nodes);
+                      if (mutipleNodes.count(nodes[0]) && mutipleNodes.count(nodes[nbNodes-1]))
+                        {
+                          vector<int> vn0 = mutipleNodes[nodes[0]];
+                          vector<int> vn1 = mutipleNodes[nodes[nbNodes - 1]];
+                          sort( vn0.begin(), vn0.end() );
+                          sort( vn1.begin(), vn1.end() );
+                          if (vn0 == vn1)
+                            {
+                              //MESSAGE(" detect edgesMultiDomains " << nodes[0] << " " << nodes[nbNodes - 1]);
+                              double *coords = grid->GetPoint(nodes[0]);
+                              gp_Pnt p0(coords[0], coords[1], coords[2]);
+                              coords = grid->GetPoint(nodes[nbNodes - 1]);
+                              gp_Pnt p1(coords[0], coords[1], coords[2]);
+                              gp_Pnt gref;
+                              int vtkVolIds[1000];  // an edge can belong to a lot of volumes
+                              map<int, SMDS_VtkVolume*> domvol; // domain --> a volume with the edge
+                              map<int, double> angleDom; // oriented angles between planes defined by edge and volume centers
+                              int nbvol = grid->GetParentVolumes(vtkVolIds, downEdgeIds[ie], edgeType[ie]);
+                              for (int id=0; id < vn0.size(); id++)
+                                {
+                                  int idom = vn0[id];
+                                  for (int ivol=0; ivol<nbvol; ivol++)
+                                    {
+                                      int smdsId = meshDS->fromVtkToSmds(vtkVolIds[ivol]);
+                                      SMDS_MeshElement* elem = (SMDS_MeshElement*)meshDS->FindElement(smdsId);
+                                      if (theElems[idom].count(elem))
+                                        {
+                                          SMDS_VtkVolume* svol = dynamic_cast<SMDS_VtkVolume*>(elem);
+                                          domvol[idom] = svol;
+                                          //MESSAGE("  domain " << idom << " volume " << elem->GetID());
+                                          double values[3];
+                                          vtkIdType npts = 0;
+                                          vtkIdType* pts = 0;
+                                          grid->GetCellPoints(vtkVolIds[ivol], npts, pts);
+                                          SMDS_VtkVolume::gravityCenter(grid, pts, npts, values);
+                                          if (id ==0)
+                                            {
+                                              gref.SetXYZ(gp_XYZ(values[0], values[1], values[2]));
+                                              angleDom[idom] = 0;
+                                            }
+                                          else
+                                            {
+                                              gp_Pnt g(values[0], values[1], values[2]);
+                                              angleDom[idom] = OrientedAngle(p0, p1, gref, g); // -pi<angle<+pi
+                                              //MESSAGE("  angle=" << angleDom[idom]);
+                                            }
+                                          break;
+                                        }
+                                    }
+                                }
+                              map<double, int> sortedDom; // sort domains by angle
+                              for (map<int, double>::iterator ia = angleDom.begin(); ia != angleDom.end(); ++ia)
+                                sortedDom[ia->second] = ia->first;
+                              vector<int> vnodes;
+                              vector<int> vdom;
+                              for (map<double, int>::iterator ib = sortedDom.begin(); ib != sortedDom.end(); ++ib)
+                                {
+                                  vdom.push_back(ib->second);
+                                  //MESSAGE("  ordered domain " << ib->second << "  angle " << ib->first);
+                                }
+                              for (int ino = 0; ino < nbNodes; ino++)
+                                vnodes.push_back(nodes[ino]);
+                              edgesMultiDomains[vnodes] = vdom; // nodes vector --> ordered domains
+                            }
+                        }
+                    }
+                }
             }
-          }
         }
-      }
     }
-    // check similarity of elements of the sides
-    if (( face[0] && !face[1] ) || ( !face[0] && face[1] )) {
-      MESSAGE("Correspondent face not found on side " << ( face[0] ? 1 : 0 ));
-      if ( nReplaceMap.size() == 2 ) { // faces on input nodes not found
-        return ( face[0] ? SEW_BAD_SIDE2_NODES : SEW_BAD_SIDE1_NODES );
-      }
-      else {
-        return SEW_TOPO_DIFF_SETS_OF_ELEMENTS;
-      }
+
+  // --- iterate on shared faces (volumes to modify, face to extrude)
+  //     get node id's of the face (id SMDS = id VTK)
+  //     create flat element with old and new nodes if requested
+
+  // --- new quad nodes on flat quad elements: oldId --> ((domain1 X domain2) --> newId)
+  //     (domain1 X domain2) = domain1 + MAXINT*domain2
+
+  std::map<int, std::map<long,int> > nodeQuadDomains;
+  std::map<std::string, SMESH_Group*> mapOfJunctionGroups;
+
+  if (createJointElems)
+    {
+      itface = faceDomains.begin();
+      for (; itface != faceDomains.end(); ++itface)
+        {
+          DownIdType face = itface->first;
+          std::set<int> oldNodes;
+          std::set<int>::iterator itn;
+          oldNodes.clear();
+          grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
+
+          std::map<int, int> domvol = itface->second;
+          std::map<int, int>::iterator itdom = domvol.begin();
+          int dom1 = itdom->first;
+          int vtkVolId = itdom->second;
+          itdom++;
+          int dom2 = itdom->first;
+          SMDS_MeshCell *vol = grid->extrudeVolumeFromFace(vtkVolId, dom1, dom2, oldNodes, nodeDomains,
+                                                             nodeQuadDomains);
+          stringstream grpname;
+          grpname << "j_";
+          if (dom1 < dom2)
+            grpname << dom1 << "_" << dom2;
+          else
+            grpname << dom2 << "_" << dom1;
+          int idg;
+          string namegrp = grpname.str();
+          if (!mapOfJunctionGroups.count(namegrp))
+            mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(vol->GetType(), namegrp.c_str(), idg);
+          SMESHDS_Group *sgrp = dynamic_cast<SMESHDS_Group*>(mapOfJunctionGroups[namegrp]->GetGroupDS());
+          if (sgrp)
+            sgrp->Add(vol->GetID());
+        }
     }
 
-    // set nodes to merge
-    // -------------------
+  // --- create volumes on multiple domain intersection if requested
+  //     iterate on mutipleNodesToFace
+  //     iterate on edgesMultiDomains
 
-    if ( face[0] && face[1] )  {
-      if ( nbNodes[0] != nbNodes[1] ) {
-        MESSAGE("Diff nb of face nodes");
-        return SEW_TOPO_DIFF_SETS_OF_ELEMENTS;
-      }
-#ifdef DEBUG_MATCHING_NODES
-      MESSAGE ( " Link 1: " << link[0].first->GetID() <<" "<< link[0].second->GetID()
-             << " F 1: " << face[0] << "| Link 2: " << link[1].first->GetID() <<" "
-            << link[1].second->GetID() << " F 2: " << face[1] << " | Bind: " ) ;
-#endif
-      int nbN = nbNodes[0];
-      {
-        list<const SMDS_MeshNode*>::iterator n1 = notLinkNodes[0].begin();
-        list<const SMDS_MeshNode*>::iterator n2 = notLinkNodes[1].begin();
-        for ( int i = 0 ; i < nbN - 2; ++i ) {
-#ifdef DEBUG_MATCHING_NODES
-          MESSAGE ( (*n1)->GetID() << " to " << (*n2)->GetID() );
-#endif
-          nReplaceMap.insert( make_pair( *(n1++), *(n2++) ));
+  if (createJointElems)
+    {
+      // --- iterate on mutipleNodesToFace
+
+      std::map<int, std::vector<int> >::iterator itn =  mutipleNodesToFace.begin();
+      for (; itn != mutipleNodesToFace.end(); ++itn)
+        {
+          int node = itn->first;
+          vector<int> orderDom = itn->second;
+          vector<vtkIdType> orderedNodes;
+          for (int idom = 0; idom <orderDom.size(); idom++)
+            orderedNodes.push_back( nodeDomains[node][orderDom[idom]] );
+            SMDS_MeshFace* face = this->GetMeshDS()->AddFaceFromVtkIds(orderedNodes);
+
+            stringstream grpname;
+            grpname << "m2j_";
+            grpname << 0 << "_" << 0;
+            int idg;
+            string namegrp = grpname.str();
+            if (!mapOfJunctionGroups.count(namegrp))
+              mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(SMDSAbs_Face, namegrp.c_str(), idg);
+            SMESHDS_Group *sgrp = dynamic_cast<SMESHDS_Group*>(mapOfJunctionGroups[namegrp]->GetGroupDS());
+            if (sgrp)
+              sgrp->Add(face->GetID());
         }
-      }
 
-      // add other links of the face 1 to linkList
-      // -----------------------------------------
+      // --- iterate on edgesMultiDomains
 
-      const SMDS_MeshElement* f0 = face[0];
-      const SMDS_MeshNode* n1 = f0->GetNode( nbN - 1 );
-      for ( int i = 0; i < nbN; i++ )
-      {
-        const SMDS_MeshNode* n2 = f0->GetNode( i );
-        pair< set< SMESH_TLink >::iterator, bool > iter_isnew =
-          linkSet.insert( SMESH_TLink( n1, n2 ));
-        if ( !iter_isnew.second ) { // already in a set: no need to process
-          linkSet.erase( iter_isnew.first );
+      std::map<std::vector<int>, std::vector<int> >::iterator ite = edgesMultiDomains.begin();
+      for (; ite != edgesMultiDomains.end(); ++ite)
+        {
+          vector<int> nodes = ite->first;
+          vector<int> orderDom = ite->second;
+          vector<vtkIdType> orderedNodes;
+          if (nodes.size() == 2)
+            {
+              //MESSAGE(" use edgesMultiDomains " << nodes[0] << " " << nodes[1]);
+              for (int ino=0; ino < nodes.size(); ino++)
+                if (orderDom.size() == 3)
+                  for (int idom = 0; idom <orderDom.size(); idom++)
+                    orderedNodes.push_back( nodeDomains[nodes[ino]][orderDom[idom]] );
+                else
+                  for (int idom = orderDom.size()-1; idom >=0; idom--)
+                    orderedNodes.push_back( nodeDomains[nodes[ino]][orderDom[idom]] );
+              SMDS_MeshVolume* vol = this->GetMeshDS()->AddVolumeFromVtkIds(orderedNodes);
+
+              stringstream grpname;
+              grpname << "mj_";
+              grpname << 0 << "_" << 0;
+              int idg;
+              string namegrp = grpname.str();
+              if (!mapOfJunctionGroups.count(namegrp))
+                mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(SMDSAbs_Volume, namegrp.c_str(), idg);
+              SMESHDS_Group *sgrp = dynamic_cast<SMESHDS_Group*>(mapOfJunctionGroups[namegrp]->GetGroupDS());
+              if (sgrp)
+                sgrp->Add(vol->GetID());
+            }
+          else
+            {
+              MESSAGE("Quadratic multiple joints not implemented");
+              // TODO quadratic nodes
+            }
         }
-        else // new in set == encountered for the first time: add
+    }
+
+  // --- list the explicit faces and edges of the mesh that need to be modified,
+  //     i.e. faces and edges built with one or more duplicated nodes.
+  //     associate these faces or edges to their corresponding domain.
+  //     only the first domain found is kept when a face or edge is shared
+
+  std::map<DownIdType, std::map<int,int>, DownIdCompare> faceOrEdgeDom; // cellToModify --> (id domain --> id cell)
+  std::map<int,int> feDom; // vtk id of cell to modify --> id domain
+  faceOrEdgeDom.clear();
+  feDom.clear();
+
+  for (int idomain = 0; idomain < theElems.size(); idomain++)
+    {
+      std::map<int, std::map<int, int> >::const_iterator itnod = nodeDomains.begin();
+      for (; itnod != nodeDomains.end(); ++itnod)
         {
-#ifdef DEBUG_MATCHING_NODES
-          MESSAGE ( "Add link 1: " << n1->GetID() << " " << n2->GetID() << " "
-         << " | link 2: " << nReplaceMap[n1]->GetID() << " " << nReplaceMap[n2]->GetID() << " " );
-#endif
-          linkList[0].push_back ( NLink( n1, n2 ));
-          linkList[1].push_back ( NLink( nReplaceMap[n1], nReplaceMap[n2] ));
+          int oldId = itnod->first;
+          //MESSAGE("     node " << oldId);
+          vtkCellLinks::Link l = grid->GetCellLinks()->GetLink(oldId);
+          for (int i = 0; i < l.ncells; i++)
+            {
+              int vtkId = l.cells[i];
+              int vtkType = grid->GetCellType(vtkId);
+              int downId = grid->CellIdToDownId(vtkId);
+              if (downId < 0)
+                continue; // new cells: not to be modified
+              DownIdType aCell(downId, vtkType);
+              int volParents[1000];
+              int nbvol = grid->GetParentVolumes(volParents, vtkId);
+              for (int j = 0; j < nbvol; j++)
+                if (celldom.count(volParents[j]) && (celldom[volParents[j]] == idomain))
+                  if (!feDom.count(vtkId))
+                    {
+                      feDom[vtkId] = idomain;
+                      faceOrEdgeDom[aCell] = emptyMap;
+                      faceOrEdgeDom[aCell][idomain] = vtkId; // affect face or edge to the first domain only
+                      //MESSAGE("affect cell " << this->GetMeshDS()->fromVtkToSmds(vtkId) << " domain " << idomain
+                      //        << " type " << vtkType << " downId " << downId);
+                    }
+            }
         }
-        n1 = n2;
-      }
-    } // 2 faces found
-  } // loop on link lists
+    }
 
-  return SEW_OK;
+  // --- iterate on shared faces (volumes to modify, face to extrude)
+  //     get node id's of the face
+  //     replace old nodes by new nodes in volumes, and update inverse connectivity
+
+  std::map<DownIdType, std::map<int,int>, DownIdCompare>* maps[3] = {&faceDomains, &cellDomains, &faceOrEdgeDom};
+  for (int m=0; m<3; m++)
+    {
+      std::map<DownIdType, std::map<int,int>, DownIdCompare>* amap = maps[m];
+      itface = (*amap).begin();
+      for (; itface != (*amap).end(); ++itface)
+        {
+          DownIdType face = itface->first;
+          std::set<int> oldNodes;
+          std::set<int>::iterator itn;
+          oldNodes.clear();
+          grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
+          //MESSAGE("examine cell, downId " << face.cellId << " type " << int(face.cellType));
+          std::map<int, int> localClonedNodeIds;
+
+          std::map<int, int> domvol = itface->second;
+          std::map<int, int>::iterator itdom = domvol.begin();
+          for (; itdom != domvol.end(); ++itdom)
+            {
+              int idom = itdom->first;
+              int vtkVolId = itdom->second;
+              //MESSAGE("modify nodes of cell " << this->GetMeshDS()->fromVtkToSmds(vtkVolId) << " domain " << idom);
+              localClonedNodeIds.clear();
+              for (itn = oldNodes.begin(); itn != oldNodes.end(); ++itn)
+                {
+                  int oldId = *itn;
+                  if (nodeDomains[oldId].count(idom))
+                    {
+                      localClonedNodeIds[oldId] = nodeDomains[oldId][idom];
+                      //MESSAGE("     node " << oldId << " --> " << localClonedNodeIds[oldId]);
+                    }
+                }
+              meshDS->ModifyCellNodes(vtkVolId, localClonedNodeIds);
+            }
+        }
+    }
+
+  meshDS->CleanDownWardConnectivity(); // Mesh has been modified, downward connectivity is no more usable, free memory
+  grid->BuildLinks();
+
+  CHRONOSTOP(50);
+  counters::stats();
+  return true;
 }
 
 /*!
-  \brief Creates a hole in a mesh by doubling the nodes of some particular elements
-  \param theNodes - identifiers of nodes to be doubled
-  \param theModifiedElems - identifiers of elements to be updated by the new (doubled) 
-         nodes. If list of element identifiers is empty then nodes are doubled but 
-         they not assigned to elements
-  \return TRUE if operation has been completed successfully, FALSE otherwise
-*/
-bool SMESH_MeshEditor::DoubleNodes( const std::list< int >& theListOfNodes, 
-                                    const std::list< int >& theListOfModifiedElems )
+ * \brief Double nodes on some external faces and create flat elements.
+ * Flat elements are mainly used by some types of mechanic calculations.
+ *
+ * Each group of the list must be constituted of faces.
+ * Triangles are transformed in prisms, and quadrangles in hexahedrons.
+ * @param theElems - list of groups of faces, where a group of faces is a set of
+ * SMDS_MeshElements sorted by Id.
+ * @return TRUE if operation has been completed successfully, FALSE otherwise
+ */
+bool SMESH_MeshEditor::CreateFlatElementsOnFacesGroups(const std::vector<TIDSortedElemSet>& theElems)
 {
-  myLastCreatedElems.Clear();
-  myLastCreatedNodes.Clear();
+  MESSAGE("-------------------------------------------------");
+  MESSAGE("SMESH_MeshEditor::CreateFlatElementsOnFacesGroups");
+  MESSAGE("-------------------------------------------------");
 
-  if ( theListOfNodes.size() == 0 )
-    return false;
+  SMESHDS_Mesh *meshDS = this->myMesh->GetMeshDS();
 
-  SMESHDS_Mesh* aMeshDS = GetMeshDS();
-  if ( !aMeshDS )
-    return false;
+  // --- For each group of faces
+  //     duplicate the nodes, create a flat element based on the face
+  //     replace the nodes of the faces by their clones
 
-  // iterate through nodes and duplicate them
+  std::map<const SMDS_MeshNode*, const SMDS_MeshNode*> clonedNodes;
+  std::map<const SMDS_MeshNode*, const SMDS_MeshNode*> intermediateNodes;
+  clonedNodes.clear();
+  intermediateNodes.clear();
+  std::map<std::string, SMESH_Group*> mapOfJunctionGroups;
+  mapOfJunctionGroups.clear();
 
-  std::map< const SMDS_MeshNode*, const SMDS_MeshNode* > anOldNodeToNewNode;
+  for (int idom = 0; idom < theElems.size(); idom++)
+    {
+      const TIDSortedElemSet& domain = theElems[idom];
+      TIDSortedElemSet::const_iterator elemItr = domain.begin();
+      for (; elemItr != domain.end(); ++elemItr)
+        {
+          SMDS_MeshElement* anElem = (SMDS_MeshElement*) *elemItr;
+          SMDS_MeshFace* aFace = dynamic_cast<SMDS_MeshFace*> (anElem);
+          if (!aFace)
+            continue;
+          // MESSAGE("aFace=" << aFace->GetID());
+          bool isQuad = aFace->IsQuadratic();
+          vector<const SMDS_MeshNode*> ln0, ln1, ln2, ln3, ln4;
 
-  std::list< int >::const_iterator aNodeIter;
-  for ( aNodeIter = theListOfNodes.begin(); aNodeIter != theListOfNodes.end(); ++aNodeIter )
-  {
-    int aCurr = *aNodeIter;
-    SMDS_MeshNode* aNode = (SMDS_MeshNode*)aMeshDS->FindNode( aCurr );
-    if ( !aNode )
-      continue;
+          // --- clone the nodes, create intermediate nodes for non medium nodes of a quad face
 
-    // duplicate node
+          SMDS_ElemIteratorPtr nodeIt = aFace->nodesIterator();
+          while (nodeIt->more())
+            {
+              const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*> (nodeIt->next());
+              bool isMedium = isQuad && (aFace->IsMediumNode(node));
+              if (isMedium)
+                ln2.push_back(node);
+              else
+                ln0.push_back(node);
 
-    const SMDS_MeshNode* aNewNode = aMeshDS->AddNode( aNode->X(), aNode->Y(), aNode->Z() );
-    if ( aNewNode )
+              const SMDS_MeshNode* clone = 0;
+              if (!clonedNodes.count(node))
+                {
+                  clone = meshDS->AddNode(node->X(), node->Y(), node->Z());
+                  clonedNodes[node] = clone;
+                }
+              else
+                clone = clonedNodes[node];
+
+              if (isMedium)
+                ln3.push_back(clone);
+              else
+                ln1.push_back(clone);
+
+              const SMDS_MeshNode* inter = 0;
+              if (isQuad && (!isMedium))
+                {
+                  if (!intermediateNodes.count(node))
+                    {
+                      inter = meshDS->AddNode(node->X(), node->Y(), node->Z());
+                      intermediateNodes[node] = inter;
+                    }
+                  else
+                    inter = intermediateNodes[node];
+                  ln4.push_back(inter);
+                }
+            }
+
+          // --- extrude the face
+
+          vector<const SMDS_MeshNode*> ln;
+          SMDS_MeshVolume* vol = 0;
+          vtkIdType aType = aFace->GetVtkType();
+          switch (aType)
+          {
+            case VTK_TRIANGLE:
+              vol = meshDS->AddVolume(ln0[2], ln0[1], ln0[0], ln1[2], ln1[1], ln1[0]);
+              // MESSAGE("vol prism " << vol->GetID());
+              ln.push_back(ln1[0]);
+              ln.push_back(ln1[1]);
+              ln.push_back(ln1[2]);
+              break;
+            case VTK_QUAD:
+              vol = meshDS->AddVolume(ln0[3], ln0[2], ln0[1], ln0[0], ln1[3], ln1[2], ln1[1], ln1[0]);
+              // MESSAGE("vol hexa " << vol->GetID());
+              ln.push_back(ln1[0]);
+              ln.push_back(ln1[1]);
+              ln.push_back(ln1[2]);
+              ln.push_back(ln1[3]);
+              break;
+            case VTK_QUADRATIC_TRIANGLE:
+              vol = meshDS->AddVolume(ln1[0], ln1[1], ln1[2], ln0[0], ln0[1], ln0[2], ln3[0], ln3[1], ln3[2],
+                                      ln2[0], ln2[1], ln2[2], ln4[0], ln4[1], ln4[2]);
+              // MESSAGE("vol quad prism " << vol->GetID());
+              ln.push_back(ln1[0]);
+              ln.push_back(ln1[1]);
+              ln.push_back(ln1[2]);
+              ln.push_back(ln3[0]);
+              ln.push_back(ln3[1]);
+              ln.push_back(ln3[2]);
+              break;
+            case VTK_QUADRATIC_QUAD:
+//              vol = meshDS->AddVolume(ln0[0], ln0[1], ln0[2], ln0[3], ln1[0], ln1[1], ln1[2], ln1[3],
+//                                      ln2[0], ln2[1], ln2[2], ln2[3], ln3[0], ln3[1], ln3[2], ln3[3],
+//                                      ln4[0], ln4[1], ln4[2], ln4[3]);
+              vol = meshDS->AddVolume(ln1[0], ln1[1], ln1[2], ln1[3], ln0[0], ln0[1], ln0[2], ln0[3],
+                                      ln3[0], ln3[1], ln3[2], ln3[3], ln2[0], ln2[1], ln2[2], ln2[3],
+                                      ln4[0], ln4[1], ln4[2], ln4[3]);
+              // MESSAGE("vol quad hexa " << vol->GetID());
+              ln.push_back(ln1[0]);
+              ln.push_back(ln1[1]);
+              ln.push_back(ln1[2]);
+              ln.push_back(ln1[3]);
+              ln.push_back(ln3[0]);
+              ln.push_back(ln3[1]);
+              ln.push_back(ln3[2]);
+              ln.push_back(ln3[3]);
+              break;
+            case VTK_POLYGON:
+              break;
+            default:
+              break;
+          }
+
+          if (vol)
+            {
+              stringstream grpname;
+              grpname << "jf_";
+              grpname << idom;
+              int idg;
+              string namegrp = grpname.str();
+              if (!mapOfJunctionGroups.count(namegrp))
+                mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(SMDSAbs_Volume, namegrp.c_str(), idg);
+              SMESHDS_Group *sgrp = dynamic_cast<SMESHDS_Group*>(mapOfJunctionGroups[namegrp]->GetGroupDS());
+              if (sgrp)
+                sgrp->Add(vol->GetID());
+            }
+
+          // --- modify the face
+
+          aFace->ChangeNodes(&ln[0], ln.size());
+        }
+    }
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Generates skin mesh (containing 2D cells) from 3D mesh
+ * The created 2D mesh elements based on nodes of free faces of boundary volumes
+ * \return TRUE if operation has been completed successfully, FALSE otherwise
+ */
+//================================================================================
+
+bool SMESH_MeshEditor::Make2DMeshFrom3D()
+{
+  // iterates on volume elements and detect all free faces on them
+  SMESHDS_Mesh* aMesh = GetMeshDS();
+  if (!aMesh)
+    return false;
+  //bool res = false;
+  int nbFree = 0, nbExisted = 0, nbCreated = 0;
+  SMDS_VolumeIteratorPtr vIt = aMesh->volumesIterator();
+  while(vIt->more())
+  {
+    const SMDS_MeshVolume* volume = vIt->next();
+    SMDS_VolumeTool vTool( volume, /*ignoreCentralNodes=*/false );
+    vTool.SetExternalNormal();
+    //const bool isPoly = volume->IsPoly();
+    const int iQuad = volume->IsQuadratic();
+    for ( int iface = 0, n = vTool.NbFaces(); iface < n; iface++ )
     {
-      anOldNodeToNewNode[ aNode ] = aNewNode;
-      myLastCreatedNodes.Append( aNewNode );
+      if (!vTool.IsFreeFace(iface))
+        continue;
+      nbFree++;
+      vector<const SMDS_MeshNode *> nodes;
+      int nbFaceNodes = vTool.NbFaceNodes(iface);
+      const SMDS_MeshNode** faceNodes = vTool.GetFaceNodes(iface);
+      int inode = 0;
+      for ( ; inode < nbFaceNodes; inode += iQuad+1)
+        nodes.push_back(faceNodes[inode]);
+      if (iQuad) { // add medium nodes
+        for ( inode = 1; inode < nbFaceNodes; inode += 2)
+          nodes.push_back(faceNodes[inode]);
+        if ( nbFaceNodes == 9 ) // bi-quadratic quad
+          nodes.push_back(faceNodes[8]);
+      }
+      // add new face based on volume nodes
+      if (aMesh->FindElement( nodes, SMDSAbs_Face, /*noMedium=*/false) ) {
+        nbExisted++;
+        continue; // face already exsist
+      }
+      AddElement(nodes, SMDSAbs_Face, ( !iQuad && nbFaceNodes/(iQuad+1) > 4 ));
+      nbCreated++;
     }
   }
+  return ( nbFree==(nbExisted+nbCreated) );
+}
 
-  // Create map of new nodes for modified elements
+namespace
+{
+  inline const SMDS_MeshNode* getNodeWithSameID(SMESHDS_Mesh* mesh, const SMDS_MeshNode* node)
+  {
+    if ( const SMDS_MeshNode* n = mesh->FindNode( node->GetID() ))
+      return n;
+    return mesh->AddNodeWithID( node->X(),node->Y(),node->Z(), node->GetID() );
+  }
+}
+//================================================================================
+/*!
+ * \brief Creates missing boundary elements
+ *  \param elements - elements whose boundary is to be checked
+ *  \param dimension - defines type of boundary elements to create
+ *  \param group - a group to store created boundary elements in
+ *  \param targetMesh - a mesh to store created boundary elements in
+ *  \param toCopyElements - if true, the checked elements will be copied into the targetMesh
+ *  \param toCopyExistingBoundary - if true, not only new but also pre-existing
+ *                                boundary elements will be copied into the targetMesh
+ *  \param toAddExistingBondary - if true, not only new but also pre-existing
+ *                                boundary elements will be added into the new group
+ *  \param aroundElements - if true, elements will be created on boundary of given
+ *                          elements else, on boundary of the whole mesh.
+ * \return nb of added boundary elements
+ */
+//================================================================================
 
-  std::map< SMDS_MeshElement*, vector<const SMDS_MeshNode*> > anElemToNodes;
+int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements,
+                                       Bnd_Dimension           dimension,
+                                       SMESH_Group*            group/*=0*/,
+                                       SMESH_Mesh*             targetMesh/*=0*/,
+                                       bool                    toCopyElements/*=false*/,
+                                       bool                    toCopyExistingBoundary/*=false*/,
+                                       bool                    toAddExistingBondary/*= false*/,
+                                       bool                    aroundElements/*= false*/)
+{
+  SMDSAbs_ElementType missType = (dimension == BND_2DFROM3D) ? SMDSAbs_Face : SMDSAbs_Edge;
+  SMDSAbs_ElementType elemType = (dimension == BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
+  // hope that all elements are of the same type, do not check them all
+  if ( !elements.empty() && (*elements.begin())->GetType() != elemType )
+    throw SALOME_Exception(LOCALIZED("wrong element type"));
+
+  if ( !targetMesh )
+    toCopyElements = toCopyExistingBoundary = false;
+
+  SMESH_MeshEditor tgtEditor( targetMesh ? targetMesh : myMesh );
+  SMESHDS_Mesh* aMesh = GetMeshDS(), *tgtMeshDS = tgtEditor.GetMeshDS();
+  int nbAddedBnd = 0;
+
+  // editor adding present bnd elements and optionally holding elements to add to the group
+  SMESH_MeshEditor* presentEditor;
+  SMESH_MeshEditor tgtEditor2( tgtEditor.GetMesh() );
+  presentEditor = toAddExistingBondary ? &tgtEditor : &tgtEditor2;
+
+  SMESH_MesherHelper helper( *myMesh );
+  const TopAbs_ShapeEnum missShapeType = ( missType==SMDSAbs_Face ? TopAbs_FACE : TopAbs_EDGE );
+  SMDS_VolumeTool vTool;
+  TIDSortedElemSet avoidSet;
+  const TIDSortedElemSet emptySet, *elemSet = aroundElements ? &elements : &emptySet;
+  int inode;
+
+  typedef vector<const SMDS_MeshNode*> TConnectivity;
+
+  SMDS_ElemIteratorPtr eIt;
+  if (elements.empty())
+    eIt = aMesh->elementsIterator(elemType);
+  else
+    eIt = SMDS_ElemIteratorPtr( new TSetIterator( elements.begin(), elements.end() ));
 
-  std::list< int >::const_iterator anElemIter;
-  for ( anElemIter = theListOfModifiedElems.begin(); 
-        anElemIter != theListOfModifiedElems.end(); ++anElemIter )
+  while (eIt->more())
   {
-    int aCurr = *anElemIter;
-    SMDS_MeshElement* anElem = (SMDS_MeshElement*)aMeshDS->FindElement( aCurr );
-    if ( !anElem )
-      continue;
-
-    vector<const SMDS_MeshNode*> aNodeArr( anElem->NbNodes() );
+    const SMDS_MeshElement* elem = eIt->next();
+    const int iQuad = elem->IsQuadratic();
+
+    // ------------------------------------------------------------------------------------
+    // 1. For an elem, get present bnd elements and connectivities of missing bnd elements
+    // ------------------------------------------------------------------------------------
+    vector<const SMDS_MeshElement*> presentBndElems;
+    vector<TConnectivity>           missingBndElems;
+    TConnectivity nodes;
+    if ( vTool.Set(elem, /*ignoreCentralNodes=*/true) ) // elem is a volume --------------
+    {
+      vTool.SetExternalNormal();
+      const SMDS_MeshElement* otherVol = 0;
+      for ( int iface = 0, n = vTool.NbFaces(); iface < n; iface++ )
+      {
+        if ( !vTool.IsFreeFace(iface, &otherVol) &&
+             ( !aroundElements || elements.count( otherVol )))
+          continue;
+        const int nbFaceNodes = vTool.NbFaceNodes(iface);
+        const SMDS_MeshNode** nn = vTool.GetFaceNodes(iface);
+        if ( missType == SMDSAbs_Edge ) // boundary edges
+        {
+          nodes.resize( 2+iQuad );
+          for ( int i = 0; i < nbFaceNodes; i += 1+iQuad)
+          {
+            for ( int j = 0; j < nodes.size(); ++j )
+              nodes[j] =nn[i+j];
+            if ( const SMDS_MeshElement* edge =
+                 aMesh->FindElement(nodes,SMDSAbs_Edge,/*noMedium=*/false))
+              presentBndElems.push_back( edge );
+            else
+              missingBndElems.push_back( nodes );
+          }
+        }
+        else // boundary face
+        {
+          nodes.clear();
+          for ( inode = 0; inode < nbFaceNodes; inode += 1+iQuad)
+            nodes.push_back( nn[inode] );
+          if (iQuad) // add medium nodes
+            for ( inode = 1; inode < nbFaceNodes; inode += 2)
+              nodes.push_back( nn[inode] );
+          int iCenter = vTool.GetCenterNodeIndex(iface); // for HEX27
+          if ( iCenter > 0 )
+            nodes.push_back( vTool.GetNodes()[ iCenter ] );
+
+          if (const SMDS_MeshElement * f = aMesh->FindElement( nodes,
+                                                               SMDSAbs_Face, /*noMedium=*/false ))
+            presentBndElems.push_back( f );
+          else
+            missingBndElems.push_back( nodes );
 
-    SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
-    int ind = 0;
-    while ( anIter->more() ) 
-    { 
-      SMDS_MeshNode* aCurrNode = (SMDS_MeshNode*)anIter->next();
-      if ( aCurr && anOldNodeToNewNode.find( aCurrNode ) != anOldNodeToNewNode.end() )
+          if ( targetMesh != myMesh )
+          {
+            // add 1D elements on face boundary to be added to a new mesh
+            const SMDS_MeshElement* edge;
+            for ( inode = 0; inode < nbFaceNodes; inode += 1+iQuad)
+            {
+              if ( iQuad )
+                edge = aMesh->FindEdge( nn[inode], nn[inode+1], nn[inode+2]);
+              else
+                edge = aMesh->FindEdge( nn[inode], nn[inode+1]);
+              if ( edge && avoidSet.insert( edge ).second )
+                presentBndElems.push_back( edge );
+            }
+          }
+        }
+      }
+    }
+    else                     // elem is a face ------------------------------------------
+    {
+      avoidSet.clear(), avoidSet.insert( elem );
+      int nbNodes = elem->NbCornerNodes();
+      nodes.resize( 2 /*+ iQuad*/);
+      for ( int i = 0; i < nbNodes; i++ )
       {
-        const SMDS_MeshNode* aNewNode = anOldNodeToNewNode[ aCurrNode ];
-        aNodeArr[ ind++ ] = aNewNode;
+        nodes[0] = elem->GetNode(i);
+        nodes[1] = elem->GetNode((i+1)%nbNodes);
+        if ( FindFaceInSet( nodes[0], nodes[1], *elemSet, avoidSet))
+          continue; // not free link
+
+        //if ( iQuad )
+        //nodes[2] = elem->GetNode( i + nbNodes );
+        if ( const SMDS_MeshElement* edge =
+             aMesh->FindElement(nodes,SMDSAbs_Edge,/*noMedium=*/true))
+          presentBndElems.push_back( edge );
+        else
+          missingBndElems.push_back( nodes );
       }
-      else
-        aNodeArr[ ind++ ] = aCurrNode;
     }
-    anElemToNodes[ anElem ] = aNodeArr;
-  }
 
-  // Change nodes of elements  
+    // ---------------------------------
+    // 2. Add missing boundary elements
+    // ---------------------------------
+    if ( targetMesh != myMesh )
+      // instead of making a map of nodes in this mesh and targetMesh,
+      // we create nodes with same IDs.
+      for ( int i = 0; i < missingBndElems.size(); ++i )
+      {
+        TConnectivity& srcNodes = missingBndElems[i];
+        TConnectivity  nodes( srcNodes.size() );
+        for ( inode = 0; inode < nodes.size(); ++inode )
+          nodes[inode] = getNodeWithSameID( tgtMeshDS, srcNodes[inode] );
+        if ( aroundElements && tgtEditor.GetMeshDS()->FindElement( nodes,
+                                                                   missType,
+                                                                   /*noMedium=*/false))
+          continue;
+        tgtEditor.AddElement(nodes, missType, !iQuad && nodes.size()/(iQuad+1)>4);
+        ++nbAddedBnd;
+      }
+    else
+      for ( int i = 0; i < missingBndElems.size(); ++i )
+      {
+        TConnectivity& nodes = missingBndElems[i];
+        if ( aroundElements && tgtEditor.GetMeshDS()->FindElement( nodes,
+                                                                   missType,
+                                                                   /*noMedium=*/false))
+          continue;
+        SMDS_MeshElement* elem = 
+          tgtEditor.AddElement(nodes, missType, !iQuad && nodes.size()/(iQuad+1)>4);
+        ++nbAddedBnd;
 
-  std::map< SMDS_MeshElement*, vector<const SMDS_MeshNode*> >::iterator
-    anElemToNodesIter = anElemToNodes.begin();
-  for ( ; anElemToNodesIter != anElemToNodes.end(); ++anElemToNodesIter )
+        // try to set a new element to a shape
+        if ( myMesh->HasShapeToMesh() )
+        {
+          bool ok = true;
+          set< pair<TopAbs_ShapeEnum, int > > mediumShapes;
+          const int nbN = nodes.size() / (iQuad+1 );
+          for ( inode = 0; inode < nbN && ok; ++inode )
+          {
+            pair<int, TopAbs_ShapeEnum> i_stype =
+              helper.GetMediumPos( nodes[inode], nodes[(inode+1)%nbN]);
+            if (( ok = ( i_stype.first > 0 && i_stype.second >= TopAbs_FACE )))
+              mediumShapes.insert( make_pair ( i_stype.second, i_stype.first ));
+          }
+          if ( ok && mediumShapes.size() > 1 )
+          {
+            set< pair<TopAbs_ShapeEnum, int > >::iterator stype_i = mediumShapes.begin();
+            pair<TopAbs_ShapeEnum, int> stype_i_0 = *stype_i;
+            for ( ++stype_i; stype_i != mediumShapes.end() && ok; ++stype_i )
+            {
+              if (( ok = ( stype_i->first != stype_i_0.first )))
+                ok = helper.IsSubShape( aMesh->IndexToShape( stype_i->second ),
+                                        aMesh->IndexToShape( stype_i_0.second ));
+            }
+          }
+          if ( ok && mediumShapes.begin()->first == missShapeType )
+            aMesh->SetMeshElementOnShape( elem, mediumShapes.begin()->second );
+        }
+      }
+
+    // ----------------------------------
+    // 3. Copy present boundary elements
+    // ----------------------------------
+    if ( toCopyExistingBoundary )
+      for ( int i = 0 ; i < presentBndElems.size(); ++i )
+      {
+        const SMDS_MeshElement* e = presentBndElems[i];
+        TConnectivity nodes( e->NbNodes() );
+        for ( inode = 0; inode < nodes.size(); ++inode )
+          nodes[inode] = getNodeWithSameID( tgtMeshDS, e->GetNode(inode) );
+        presentEditor->AddElement(nodes, e->GetType(), e->IsPoly());
+      }
+    else // store present elements to add them to a group
+      for ( int i = 0 ; i < presentBndElems.size(); ++i )
+      {
+        presentEditor->myLastCreatedElems.Append(presentBndElems[i]);
+      }
+      
+  } // loop on given elements
+
+  // ---------------------------------------------
+  // 4. Fill group with boundary elements
+  // ---------------------------------------------
+  if ( group )
   {
-    const SMDS_MeshElement* anElem = anElemToNodesIter->first;
-    vector<const SMDS_MeshNode*> aNodeArr = anElemToNodesIter->second;
-    if ( anElem )
-      aMeshDS->ChangeElementNodes( anElem, &aNodeArr[ 0 ], anElem->NbNodes() );
+    if ( SMESHDS_Group* g = dynamic_cast<SMESHDS_Group*>( group->GetGroupDS() ))
+      for ( int i = 0; i < tgtEditor.myLastCreatedElems.Size(); ++i )
+        g->SMDSGroup().Add( tgtEditor.myLastCreatedElems( i+1 ));
   }
+  tgtEditor.myLastCreatedElems.Clear();
+  tgtEditor2.myLastCreatedElems.Clear();
 
-  return true;
+  // -----------------------
+  // 5. Copy given elements
+  // -----------------------
+  if ( toCopyElements && targetMesh != myMesh )
+  {
+    if (elements.empty())
+      eIt = aMesh->elementsIterator(elemType);
+    else
+      eIt = SMDS_ElemIteratorPtr( new TSetIterator( elements.begin(), elements.end() ));
+    while (eIt->more())
+    {
+      const SMDS_MeshElement* elem = eIt->next();
+      TConnectivity nodes( elem->NbNodes() );
+      for ( inode = 0; inode < nodes.size(); ++inode )
+        nodes[inode] = getNodeWithSameID( tgtMeshDS, elem->GetNode(inode) );
+      tgtEditor.AddElement(nodes, elemType, elem->IsPoly());
+
+      tgtEditor.myLastCreatedElems.Clear();
+    }
+  }
+  return nbAddedBnd;
 }
index ccab3fbb69402cb648d1b77d700f6a476ad11c4c..4bd4558253c964e18cb991e05e8e98091fc5c443 100644 (file)
@@ -1,25 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+
 // File      : SMESH_MeshEditor.hxx
 // Created   : Mon Apr 12 14:56:19 2004
 // Author    : Edward AGAPOV (eap)
 
 #include "SMESH_SMESH.hxx"
 
-#include "SMESH_Mesh.hxx"
-#include "SMESH_Controls.hxx"
-#include "SMESH_SequenceOfNode.hxx"
-#include "SMESH_SequenceOfElemPtr.hxx"
-#include "TColStd_HSequenceOfReal.hxx"
-#include "SMESH_MesherHelper.hxx"
 #include "SMDS_MeshElement.hxx"
+#include "SMESH_Controls.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_TypeDefs.hxx"
+
+#include <utilities.h>
 
+#include <TColStd_HSequenceOfReal.hxx>
 #include <gp_Dir.hxx>
 
 #include <list>
 #include <map>
-
-typedef std::map<const SMDS_MeshElement*,
-                 std::list<const SMDS_MeshElement*> >        TElemOfElemListMap;
-typedef std::map<const SMDS_MeshNode*, const SMDS_MeshNode*> TNodeNodeMap;
-
-
-typedef pair< const SMDS_MeshNode*, const SMDS_MeshNode* > NLink;
-
-//=======================================================================
-/*!
- * \brief A sorted pair of nodes
- */
-//=======================================================================
-
-struct SMESH_TLink: public NLink
-{
-  SMESH_TLink(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2 ):NLink( n1, n2 )
-  { if ( n1->GetID() < n2->GetID() ) std::swap( first, second ); }
-  SMESH_TLink(const NLink& link ):NLink( link )
-  { if ( first->GetID() < second->GetID() ) std::swap( first, second ); }
-};
-
+#include <set>
 
 class SMDS_MeshFace;
 class SMDS_MeshNode;
 class gp_Ax1;
 class gp_Vec;
 class gp_Pnt;
+class SMESH_MesherHelper;
 
-// ============================================================
+
+//=======================================================================
 /*!
- * \brief Set of elements sorted by ID, to be used to assure
- *  predictability of edition
+ * \brief Searcher for the node closest to point
  */
-// ============================================================
-
-template < class TMeshElem = SMDS_MeshElement>
-struct TIDCompare {
-  bool operator () (const TMeshElem* e1, const TMeshElem* e2) const
-  { return e1->GetID() < e2->GetID(); }
+//=======================================================================
+struct SMESH_NodeSearcher
+{
+  virtual const SMDS_MeshNode* FindClosestTo( const gp_Pnt& pnt ) = 0;
+  virtual void MoveNode( const SMDS_MeshNode* node, const gp_Pnt& toPnt ) = 0;
 };
-typedef std::set< const SMDS_MeshElement*, TIDCompare< SMDS_MeshElement> > TIDSortedElemSet;
 
-// ============================================================
+//=======================================================================
 /*!
- * \brief Searcher for the node closest to point
+ * \brief Searcher for elements
  */
-// ============================================================
+//=======================================================================
 
-struct SMESH_NodeSearcher
+struct SMESH_ElementSearcher
 {
-  virtual const SMDS_MeshNode* FindClosestTo( const gp_Pnt& pnt ) = 0;
+  /*!
+   * \brief Find elements of given type where the given point is IN or ON.
+   *        Returns nb of found elements and elements them-selves.
+   *
+   * 'ALL' type means elements of any type excluding nodes and 0D elements
+   */
+  virtual int FindElementsByPoint(const gp_Pnt&                           point,
+                                  SMDSAbs_ElementType                     type,
+                                  std::vector< const SMDS_MeshElement* >& foundElems)=0;
+  /*!
+   * \brief Return an element most close to the given point
+   */
+  virtual const SMDS_MeshElement* FindClosestTo( const gp_Pnt&       point,
+                                                 SMDSAbs_ElementType type) = 0;
+  /*!
+   * \brief Return elements possibly intersecting the line
+   */
+  virtual void GetElementsNearLine( const gp_Ax1&                           line,
+                                    SMDSAbs_ElementType                     type,
+                                    std::vector< const SMDS_MeshElement* >& foundElems)=0;
+  /*!
+   * \brief Find out if the given point is out of closed 2D mesh.
+   */
+  virtual TopAbs_State GetPointState(const gp_Pnt& point) = 0;
+
 };
 
 // ============================================================
@@ -102,8 +104,8 @@ struct SMESH_NodeSearcher
  */
 // ============================================================
 
-class SMESH_EXPORT SMESH_MeshEditor {
-
+class SMESH_EXPORT SMESH_MeshEditor
+{
 public:
 
   SMESH_MeshEditor( SMESH_Mesh* theMesh );
@@ -114,16 +116,17 @@ public:
   SMDS_MeshElement* AddElement(const std::vector<const SMDS_MeshNode*> & nodes,
                                const SMDSAbs_ElementType                 type,
                                const bool                                isPoly,
-                               const int                                 ID = 0);
+                               const int                                 ID = -1,
+                               const double                              ballDiameter=0.);
   /*!
    * \brief Add element
    */
   SMDS_MeshElement* AddElement(const std::vector<int>  & nodeIDs,
                                const SMDSAbs_ElementType type,
                                const bool                isPoly,
-                               const int                 ID = 0);
+                               const int                 ID = -1);
 
-  bool Remove (const std::list< int >& theElemIDs, const bool isNodes);
+  int Remove (const std::list< int >& theElemIDs, const bool isNodes);
   // Remove a node or an element.
   // Modify a compute state of sub-meshes which become empty
 
@@ -148,6 +151,11 @@ public:
   bool Reorient (const SMDS_MeshElement * theElement);
   // Reverse theElement orientation
 
+  int Reorient2D (TIDSortedElemSet &       theFaces,
+                  const gp_Dir&            theDirection,
+                  const SMDS_MeshElement * theFace);
+  // Reverse theFaces whose orientation to be same as that of theFace
+  // oriented according to theDirection. Return nb of reoriented faces
 
   /*!
    * \brief Fuse neighbour triangles into quadrangles.
@@ -155,7 +163,7 @@ public:
    * \param theCriterion - Is used to choose a neighbour to fuse with.
    * \param theMaxAngle  - Is a max angle between element normals at which fusion
    *                       is still performed; theMaxAngle is mesured in radians.
-   * \retval bool - Success or not.
+   * \return bool - Success or not.
    */
   bool TriToQuad (TIDSortedElemSet &                   theElems,
                   SMESH::Controls::NumericalFunctorPtr theCriterion,
@@ -165,7 +173,7 @@ public:
    * \brief Split quadrangles into triangles.
    * \param theElems     - The faces to be splitted.
    * \param theCriterion - Is used to choose a diagonal for splitting.
-   * \retval bool - Success or not.
+   * \return bool - Success or not.
    */
   bool QuadToTri (TIDSortedElemSet &                   theElems,
                   SMESH::Controls::NumericalFunctorPtr theCriterion);
@@ -174,7 +182,7 @@ public:
    * \brief Split quadrangles into triangles.
    * \param theElems  - The faces to be splitted.
    * \param the13Diag - Is used to choose a diagonal for splitting.
-   * \retval bool - Success or not.
+   * \return bool - Success or not.
    */
   bool QuadToTri (TIDSortedElemSet & theElems,
                   const bool         the13Diag);
@@ -183,12 +191,19 @@ public:
    * \brief Find better diagonal for splitting.
    * \param theQuad      - The face to find better splitting of.
    * \param theCriterion - Is used to choose a diagonal for splitting.
-   * \retval int - 1 for 1-3 diagonal, 2 for 2-4, -1 - for errors.
+   * \return int - 1 for 1-3 diagonal, 2 for 2-4, -1 - for errors.
    */
   int BestSplit (const SMDS_MeshElement*              theQuad,
                  SMESH::Controls::NumericalFunctorPtr theCriterion);
 
 
+  enum SplitVolumToTetraFlags { HEXA_TO_5 = 1, HEXA_TO_6 = 2, HEXA_TO_24 = 3 };//!<arg of SplitVolumesIntoTetra()
+  /*!
+   * \brief Split volumic elements into tetrahedra.
+   */
+  void SplitVolumesIntoTetra (const TIDSortedElemSet & theElems, const int theMethodFlags);
+
+
   enum SmoothMethod { LAPLACIAN = 0, CENTROIDAL };
 
   void Smooth (TIDSortedElemSet &               theElements,
@@ -229,7 +244,7 @@ public:
   };
   
   /*!
-   * special structire for control of extrusion functionality
+   * special structure for control of extrusion functionality
    */
   struct ExtrusParam {
     gp_Dir myDir; // direction of extrusion
@@ -239,7 +254,7 @@ public:
 
   /*!
    * Create new node in the mesh with given coordinates
-   * (auxilary for advanced extrusion)
+   * (auxiliary for advanced extrusion)
    */
   const SMDS_MeshNode* CreateNode(const double x,
                                   const double y,
@@ -251,12 +266,12 @@ public:
    * Generate new elements by extrusion of theElements
    * It is a method used in .idl file. All functionality
    * is implemented in the next method (see below) which
-   * is used in the cuurent method.
-   * param theElems - list of elements for extrusion
-   * param newElemsMap returns history of extrusion
-   * param theFlags set flags for performing extrusion (see description
+   * is used in the current method.
+   * @param theElems - list of elements for extrusion
+   * @param newElemsMap returns history of extrusion
+   * @param theFlags set flags for performing extrusion (see description
    *   of enum ExtrusionFlags for additional information)
-   * param theTolerance - uses for comparing locations of nodes if flag
+   * @param theTolerance - uses for comparing locations of nodes if flag
    *   EXTRUSION_FLAG_SEW is set
    */
   PGroupIDs ExtrusionSweep (TIDSortedElemSet &  theElems,
@@ -269,13 +284,13 @@ public:
   
   /*!
    * Generate new elements by extrusion of theElements
-   * param theElems - list of elements for extrusion
-   * param newElemsMap returns history of extrusion
-   * param theFlags set flags for performing extrusion (see description
+   * @param theElems - list of elements for extrusion
+   * @param newElemsMap returns history of extrusion
+   * @param theFlags set flags for performing extrusion (see description
    *   of enum ExtrusionFlags for additional information)
-   * param theTolerance - uses for comparing locations of nodes if flag
+   * @param theTolerance - uses for comparing locations of nodes if flag
    *   EXTRUSION_FLAG_SEW is set
-   * param theParams - special structure for manage of extrusion
+   * @param theParams - special structure for manage of extrusion
    */
   PGroupIDs ExtrusionSweep (TIDSortedElemSet &  theElems,
                             ExtrusParam&        theParams,
@@ -303,6 +318,16 @@ public:
                                        const SMDS_MeshNode* theNodeStart,
                                        const bool           theHasAngles,
                                        std::list<double>&   theAngles,
+                                       const bool           theLinearVariation,
+                                       const bool           theHasRefPoint,
+                                       const gp_Pnt&        theRefPoint,
+                                       const bool           theMakeGroups);
+  Extrusion_Error ExtrusionAlongTrack (TIDSortedElemSet &   theElements,
+                                       SMESH_Mesh*          theTrackPattern,
+                                       const SMDS_MeshNode* theNodeStart,
+                                       const bool           theHasAngles,
+                                       std::list<double>&   theAngles,
+                                       const bool           theLinearVariation,
                                        const bool           theHasRefPoint,
                                        const gp_Pnt&        theRefPoint,
                                        const bool           theMakeGroups);
@@ -316,19 +341,32 @@ public:
                        SMESH_Mesh*        theTargetMesh=0);
   // Move or copy theElements applying theTrsf to their nodes
 
+
   typedef std::list< std::list< const SMDS_MeshNode* > > TListOfListOfNodes;
 
-  void FindCoincidentNodes (std::set<const SMDS_MeshNode*> & theNodes,
-                            const double                     theTolerance,
-                            TListOfListOfNodes &             theGroupsOfNodes);
+  void FindCoincidentNodes (TIDSortedNodeSet &   theNodes,
+                            const double         theTolerance,
+                            TListOfListOfNodes & theGroupsOfNodes);
   // Return list of group of nodes close to each other within theTolerance.
   // Search among theNodes or in the whole mesh if theNodes is empty.
 
   /*!
-   * \brief Return SMESH_NodeSearcher
+   * \brief Return SMESH_NodeSearcher. The caller is responsible for deleteing it
    */
   SMESH_NodeSearcher* GetNodeSearcher();
 
+  /*!
+   * \brief Return SMESH_ElementSearcher. The caller is responsible for deleting it
+   */
+  SMESH_ElementSearcher* GetElementSearcher();
+  SMESH_ElementSearcher* GetElementSearcher( SMDS_ElemIteratorPtr elemIt );
+  /*!
+   * \brief Return true if the point is IN or ON of the element
+   */
+  static bool IsOut( const SMDS_MeshElement* element, const gp_Pnt& point, double tol );
+
+  static double GetDistance( const SMDS_MeshFace* face, const gp_Pnt& point );
+
   int SimplifyFace (const std::vector<const SMDS_MeshNode *> faceNodes,
                     std::vector<const SMDS_MeshNode *>&      poly_nodes,
                     std::vector<int>&                        quantities) const;
@@ -342,7 +380,7 @@ public:
   typedef std::list< std::list< int > > TListOfListOfElementsID;
 
   void FindEqualElements(std::set<const SMDS_MeshElement*> & theElements,
-                        TListOfListOfElementsID &           theGroupsOfElementsID);
+                         TListOfListOfElementsID &           theGroupsOfElementsID);
   // Return list of group of elements build on the same nodes.
   // Search among theElements or in the whole mesh if theElements is empty.
 
@@ -439,24 +477,20 @@ public:
   // theBetweenNode1 - theBetweenNode2, between theBetweenNode1 and theBetweenNode2.
 
   void ConvertToQuadratic(const bool theForce3d);
-  //converts all mesh to quadratic one, deletes old elements, replacing 
-  //them with quadratic ones with the same id.
+  void ConvertToQuadratic(const bool theForce3d, TIDSortedElemSet& theElements);
+  // Converts all mesh to quadratic one, deletes old elements, replacing 
+  // them with quadratic ones with the same id.
+  // If theForce3d = 1; this results in the medium node lying at the 
+  // middle of the line segments connecting start and end node of a mesh 
+  // element
+  // If theForce3d = 0; this results in the medium node lying at the 
+  // geometrical edge from which the mesh element is built
 
   bool ConvertFromQuadratic();
-  //converts all mesh from quadratic to ordinary ones, deletes old quadratic elements, replacing 
-  //them with ordinary mesh elements with the same id.
-
-
-//  static int SortQuadNodes (const SMDS_Mesh * theMesh,
-//                            int               theNodeIds[] );
-//  // Set 4 nodes of a quadrangle face in a good order.
-//  // Swap 1<->2 or 2<->3 nodes and correspondingly return
-//  // 1 or 2 else 0.
-//
-//  static bool SortHexaNodes (const SMDS_Mesh * theMesh,
-//                             int               theNodeIds[] );
-//  // Set 8 nodes of a hexahedron in a good order.
-//  // Return success status
+  void ConvertFromQuadratic(TIDSortedElemSet& theElements);
+  // Converts all mesh from quadratic to ordinary ones, deletes old quadratic elements, replacing 
+  // them with ordinary mesh elements with the same id.
+  // Returns true in case of success, false otherwise.
 
   static void AddToSameGroups (const SMDS_MeshElement* elemToAdd,
                                const SMDS_MeshElement* elemInGroups,
@@ -472,6 +506,11 @@ public:
                                    SMESHDS_Mesh *          aMesh);
   // replace elemToRm by elemToAdd in the all groups
 
+  static void ReplaceElemInGroups (const SMDS_MeshElement*                     elemToRm,
+                                   const std::vector<const SMDS_MeshElement*>& elemToAdd,
+                                   SMESHDS_Mesh *                              aMesh);
+  // replace elemToRm by elemToAdd in the all groups
+
   /*!
    * \brief Return nodes linked to the given one in elements of the type
    */
@@ -479,14 +518,16 @@ public:
                               TIDSortedElemSet &   linkedNodes,
                               SMDSAbs_ElementType  type = SMDSAbs_All );
 
-  static const SMDS_MeshElement*
-    FindFaceInSet(const SMDS_MeshNode*    n1,
-                  const SMDS_MeshNode*    n2,
-                  const TIDSortedElemSet& elemSet,
-                  const TIDSortedElemSet& avoidSet);
+  static const SMDS_MeshElement* FindFaceInSet(const SMDS_MeshNode*    n1,
+                                               const SMDS_MeshNode*    n2,
+                                               const TIDSortedElemSet& elemSet,
+                                               const TIDSortedElemSet& avoidSet,
+                                               int*                    i1=0,
+                                               int*                    i2=0);
   // Return a face having linked nodes n1 and n2 and which is
   // - not in avoidSet,
   // - in elemSet provided that !elemSet.empty()
+  // i1 and i2 optionally returns indices of n1 and n2
 
   /*!
    * \brief Find corresponding nodes in two sets of faces 
@@ -497,21 +538,21 @@ public:
     * \param theSecondNode1 - a boundary node of set 1 linked with theFirstNode1
     * \param theSecondNode2 - a node of set 2 corresponding to theSecondNode1
     * \param nReplaceMap - output map of corresponding nodes
-    * \retval Sew_Error  - is a success or not
+    * \return Sew_Error  - is a success or not
    */
   static Sew_Error FindMatchingNodes(std::set<const SMDS_MeshElement*>& theSide1,
                                      std::set<const SMDS_MeshElement*>& theSide2,
-                                     const SMDS_MeshNode*          theFirstNode1,
-                                     const SMDS_MeshNode*          theFirstNode2,
-                                     const SMDS_MeshNode*          theSecondNode1,
-                                     const SMDS_MeshNode*          theSecondNode2,
-                                     TNodeNodeMap &                nReplaceMap);
+                                     const SMDS_MeshNode*               theFirstNode1,
+                                     const SMDS_MeshNode*               theFirstNode2,
+                                     const SMDS_MeshNode*               theSecondNode1,
+                                     const SMDS_MeshNode*               theSecondNode2,
+                                     TNodeNodeMap &                     theNodeReplaceMap);
 
   /*!
    * \brief Returns true if given node is medium
     * \param n - node to check
     * \param typeToCheck - type of elements containing the node to ask about node status
-    * \retval bool - check result
+    * \return bool - check result
    */
   static bool IsMedium(const SMDS_MeshNode*      node,
                        const SMDSAbs_ElementType typeToCheck = SMDSAbs_All);
@@ -527,15 +568,49 @@ public:
   const SMESH_SequenceOfElemPtr& GetLastCreatedNodes() const { return myLastCreatedNodes; }
 
   const SMESH_SequenceOfElemPtr& GetLastCreatedElems() const { return myLastCreatedElems; }
-  
+
   bool DoubleNodes( const std::list< int >& theListOfNodes, 
                     const std::list< int >& theListOfModifiedElems );
+  
+  bool DoubleNodes( const TIDSortedElemSet& theElems, 
+                    const TIDSortedElemSet& theNodesNot,
+                    const TIDSortedElemSet& theAffectedElems );
 
-private:
+  bool DoubleNodesInRegion( const TIDSortedElemSet& theElems, 
+                            const TIDSortedElemSet& theNodesNot,
+                            const TopoDS_Shape&     theShape );
+  
+  double OrientedAngle(const gp_Pnt& p0, const gp_Pnt& p1, const gp_Pnt& g1, const gp_Pnt& g2);
+
+  bool DoubleNodesOnGroupBoundaries( const std::vector<TIDSortedElemSet>& theElems,
+                                     bool createJointElems);
+
+  bool CreateFlatElementsOnFacesGroups( const std::vector<TIDSortedElemSet>& theElems );
+
+  /*!
+   * \brief Generated skin mesh (containing 2D cells) from 3D mesh
+   * The created 2D mesh elements based on nodes of free faces of boundary volumes
+   * \return TRUE if operation has been completed successfully, FALSE otherwise
+   */
+  bool Make2DMeshFrom3D();
+
+  enum Bnd_Dimension { BND_2DFROM3D, BND_1DFROM3D, BND_1DFROM2D };
+
+  int MakeBoundaryMesh(const TIDSortedElemSet& elements,
+                       Bnd_Dimension           dimension,
+                       SMESH_Group*            group = 0,
+                       SMESH_Mesh*             targetMesh = 0,
+                       bool                    toCopyElements = false,
+                       bool                    toCopyExistingBondary = false,
+                       bool                    toAddExistingBondary = false,
+                       bool                    aroundElements = false);
+
+
+ private:
 
   /*!
    * \brief Convert elements contained in a submesh to quadratic
-    * \retval int - nb of checked elements
+   * \return int - nb of checked elements
    */
   int convertElemToQuadratic(SMESHDS_SubMesh *   theSm,
                              SMESH_MesherHelper& theHelper,
@@ -543,7 +618,7 @@ private:
 
   /*!
    * \brief Convert quadratic elements to linear ones and remove quadratic nodes
-    * \retval int - nb of checked elements
+   * \return nb of checked elements
    */
   int removeQuadElem( SMESHDS_SubMesh *    theSm,
                       SMDS_ElemIteratorPtr theItr,
@@ -567,11 +642,11 @@ private:
 
   /*!
    * \brief Create elements by sweeping an element
-    * \param elem - element to sweep
-    * \param newNodesItVec - nodes generated from each node of the element
-    * \param newElems - generated elements
-    * \param nbSteps - number of sweeping steps
-    * \param srcElements - to append elem for each generated element
+   * \param elem - element to sweep
+   * \param newNodesItVec - nodes generated from each node of the element
+   * \param newElems - generated elements
+   * \param nbSteps - number of sweeping steps
+   * \param srcElements - to append elem for each generated element
    */
   void sweepElement(const SMDS_MeshElement*                    elem,
                     const std::vector<TNodeOfNodeListMapItr> & newNodesItVec,
@@ -581,12 +656,12 @@ private:
 
   /*!
    * \brief Create 1D and 2D elements around swept elements
-    * \param mapNewNodes - source nodes and ones generated from them
-    * \param newElemsMap - source elements and ones generated from them
-    * \param elemNewNodesMap - nodes generated from each node of each element
-    * \param elemSet - all swept elements
-    * \param nbSteps - number of sweeping steps
-    * \param srcElements - to append elem for each generated element
+   * \param mapNewNodes - source nodes and ones generated from them
+   * \param newElemsMap - source elements and ones generated from them
+   * \param elemNewNodesMap - nodes generated from each node of each element
+   * \param elemSet - all swept elements
+   * \param nbSteps - number of sweeping steps
+   * \param srcElements - to append elem for each generated element
    */
   void makeWalls (TNodeOfNodeListMap &     mapNewNodes,
                   TElemOfElemListMap &     newElemsMap,
@@ -594,6 +669,44 @@ private:
                   TIDSortedElemSet&        elemSet,
                   const int                nbSteps,
                   SMESH_SequenceOfElemPtr& srcElements);
+
+  struct SMESH_MeshEditor_PathPoint
+  {
+    gp_Pnt myPnt;
+    gp_Dir myTgt;
+    double myAngle, myPrm;
+
+    SMESH_MeshEditor_PathPoint(): myPnt(99., 99., 99.), myTgt(1.,0.,0.), myAngle(0), myPrm(0) {}
+    void          SetPnt      (const gp_Pnt& aP3D)  { myPnt  =aP3D; }
+    void          SetTangent  (const gp_Dir& aTgt)  { myTgt  =aTgt; }
+    void          SetAngle    (const double& aBeta) { myAngle=aBeta; }
+    void          SetParameter(const double& aPrm)  { myPrm  =aPrm; }
+    const gp_Pnt& Pnt         ()const               { return myPnt; }
+    const gp_Dir& Tangent     ()const               { return myTgt; }
+    double        Angle       ()const               { return myAngle; }
+    double        Parameter   ()const               { return myPrm; }
+  };
+  Extrusion_Error MakeEdgePathPoints(std::list<double>&                     aPrms,
+                                     const TopoDS_Edge&                     aTrackEdge,
+                                     bool                                   aFirstIsStart,
+                                     std::list<SMESH_MeshEditor_PathPoint>& aLPP);
+  Extrusion_Error MakeExtrElements(TIDSortedElemSet&                      theElements,
+                                   std::list<SMESH_MeshEditor_PathPoint>& theFullList,
+                                   const bool                             theHasAngles,
+                                   std::list<double>&                     theAngles,
+                                   const bool                             theLinearVariation,
+                                   const bool                             theHasRefPoint,
+                                   const gp_Pnt&                          theRefPoint,
+                                   const bool                             theMakeGroups);
+  void LinearAngleVariation(const int     NbSteps,
+                            list<double>& theAngles);
+
+  bool doubleNodes( SMESHDS_Mesh*                                           theMeshDS,
+                    const TIDSortedElemSet&                                 theElems,
+                    const TIDSortedElemSet&                                 theNodesNot,
+                    std::map< const SMDS_MeshNode*, const SMDS_MeshNode* >& theNodeNodeMap,
+                    const bool                                              theIsDoubleElem );
+
 private:
 
   SMESH_Mesh * myMesh;
index 292c29ecb7fc8964985f66f29ef4b03eaae0c53c..efaf7a853362f95f3f2dc082aec184ab173b4e68 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File:      SMESH_MesherHelper.cxx
 // Created:   15.02.06 15:22:41
 // Author:    Sergey KUUL
 
 #include "SMDS_FacePosition.hxx" 
 #include "SMDS_EdgePosition.hxx"
-#include "SMESH_MeshEditor.hxx"
+#include "SMDS_VolumeTool.hxx"
+#include "SMESH_subMesh.hxx"
+#include "SMESH_ProxyMesh.hxx"
 
 #include <BRepAdaptor_Surface.hxx>
 #include <BRepTools.hxx>
-#include <BRep_Tool.hxx>
 #include <BRepTools_WireExplorer.hxx>
+#include <BRep_Tool.hxx>
 #include <Geom2d_Curve.hxx>
+#include <GeomAPI_ProjectPointOnCurve.hxx>
+#include <GeomAPI_ProjectPointOnSurf.hxx>
 #include <Geom_Curve.hxx>
+#include <Geom_RectangularTrimmedSurface.hxx>
 #include <Geom_Surface.hxx>
 #include <ShapeAnalysis.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_MapIteratorOfMapOfShape.hxx>
 #include <TopTools_MapOfShape.hxx>
 #include <TopoDS.hxx>
+#include <gp_Ax3.hxx>
 #include <gp_Pnt2d.hxx>
+#include <gp_Trsf.hxx>
 
 #include <Standard_Failure.hxx>
 #include <Standard_ErrorHandler.hxx>
 
 #include <utilities.h>
 
+#include <limits>
+
+using namespace std;
+
 #define RETURN_BAD_RESULT(msg) { MESSAGE(msg); return false; }
 
+namespace {
+
+  gp_XYZ XYZ(const SMDS_MeshNode* n) { return gp_XYZ(n->X(), n->Y(), n->Z()); }
+
+  enum { U_periodic = 1, V_periodic = 2 };
+}
+
 //================================================================================
 /*!
  * \brief Constructor
 //================================================================================
 
 SMESH_MesherHelper::SMESH_MesherHelper(SMESH_Mesh& theMesh)
-  : myMesh(&theMesh), myShapeID(-1), myCreateQuadratic(false)
+  : myParIndex(0), myMesh(&theMesh), myShapeID(0), myCreateQuadratic(false),
+    myFixNodeParameters(false)
 {
+  myPar1[0] = myPar2[0] = myPar1[1] = myPar2[1] = 0;
   mySetElemOnShape = ( ! myMesh->HasShapeToMesh() );
 }
 
 //=======================================================================
-//function : CheckShape
+//function : ~SMESH_MesherHelper
 //purpose  : 
 //=======================================================================
 
+SMESH_MesherHelper::~SMESH_MesherHelper()
+{
+  {
+    TID2ProjectorOnSurf::iterator i_proj = myFace2Projector.begin();
+    for ( ; i_proj != myFace2Projector.end(); ++i_proj )
+      delete i_proj->second;
+  }
+  {
+    TID2ProjectorOnCurve::iterator i_proj = myEdge2Projector.begin();
+    for ( ; i_proj != myEdge2Projector.end(); ++i_proj )
+      delete i_proj->second;
+  }
+}
+
+//=======================================================================
+//function : IsQuadraticSubMesh
+//purpose  : Check submesh for given shape: if all elements on this shape 
+//           are quadratic, quadratic elements will be created.
+//           Also fill myTLinkNodeMap
+//=======================================================================
+
 bool SMESH_MesherHelper::IsQuadraticSubMesh(const TopoDS_Shape& aSh)
 {
   SMESHDS_Mesh* meshDS = GetMeshDS();
   // we can create quadratic elements only if all elements
-  // created on subshapes of given shape are quadratic
-  // also we have to fill myNLinkNodeMap
+  // created on sub-shapes of given shape are quadratic
+  // also we have to fill myTLinkNodeMap
   myCreateQuadratic = true;
   mySeamShapeIds.clear();
   myDegenShapeIds.clear();
   TopAbs_ShapeEnum subType( aSh.ShapeType()==TopAbs_FACE ? TopAbs_EDGE : TopAbs_FACE );
+  if ( aSh.ShapeType()==TopAbs_COMPOUND )
+  {
+    TopoDS_Iterator subIt( aSh );
+    if ( subIt.More() )
+      subType = ( subIt.Value().ShapeType()==TopAbs_FACE ) ? TopAbs_EDGE : TopAbs_FACE;
+  }
   SMDSAbs_ElementType elemType( subType==TopAbs_FACE ? SMDSAbs_Face : SMDSAbs_Edge );
 
-  TopExp_Explorer exp( aSh, subType );
-  for (; exp.More() && myCreateQuadratic; exp.Next()) {
-    if ( SMESHDS_SubMesh * subMesh = meshDS->MeshElements( exp.Current() )) {
-      if ( SMDS_ElemIteratorPtr it = subMesh->GetElements() ) {
-        while(it->more()) {
-          const SMDS_MeshElement* e = it->next();
-          if ( e->GetType() != elemType || !e->IsQuadratic() ) {
-            myCreateQuadratic = false;
-            break;
-          }
-          else {
-            // fill NLinkNodeMap
-            switch ( e->NbNodes() ) {
-            case 3:
-              AddNLinkNode(e->GetNode(0),e->GetNode(1),e->GetNode(2)); break;
-            case 6:
-              AddNLinkNode(e->GetNode(0),e->GetNode(1),e->GetNode(3));
-              AddNLinkNode(e->GetNode(1),e->GetNode(2),e->GetNode(4));
-              AddNLinkNode(e->GetNode(2),e->GetNode(0),e->GetNode(5)); break;
-            case 8:
-              AddNLinkNode(e->GetNode(0),e->GetNode(1),e->GetNode(4));
-              AddNLinkNode(e->GetNode(1),e->GetNode(2),e->GetNode(5));
-              AddNLinkNode(e->GetNode(2),e->GetNode(3),e->GetNode(6));
-              AddNLinkNode(e->GetNode(3),e->GetNode(0),e->GetNode(7));
-              break;
-            default:
+
+  int nbOldLinks = myTLinkNodeMap.size();
+
+  if ( !myMesh->HasShapeToMesh() )
+  {
+    if (( myCreateQuadratic = myMesh->NbFaces( ORDER_QUADRATIC )))
+    {
+      SMDS_FaceIteratorPtr fIt = meshDS->facesIterator();
+      while ( fIt->more() )
+        AddTLinks( static_cast< const SMDS_MeshFace* >( fIt->next() ));
+    }
+  }
+  else
+  {
+    TopExp_Explorer exp( aSh, subType );
+    TopTools_MapOfShape checkedSubShapes;
+    for (; exp.More() && myCreateQuadratic; exp.Next()) {
+      if ( !checkedSubShapes.Add( exp.Current() ))
+        continue; // needed if aSh is compound of solids
+      if ( SMESHDS_SubMesh * subMesh = meshDS->MeshElements( exp.Current() )) {
+        if ( SMDS_ElemIteratorPtr it = subMesh->GetElements() ) {
+          while(it->more()) {
+            const SMDS_MeshElement* e = it->next();
+            if ( e->GetType() != elemType || !e->IsQuadratic() ) {
               myCreateQuadratic = false;
               break;
             }
+            else {
+              // fill TLinkNodeMap
+              switch ( e->NbNodes() ) {
+              case 3:
+                AddTLinkNode(e->GetNode(0),e->GetNode(1),e->GetNode(2)); break;
+              case 6:
+                AddTLinkNode(e->GetNode(0),e->GetNode(1),e->GetNode(3));
+                AddTLinkNode(e->GetNode(1),e->GetNode(2),e->GetNode(4));
+                AddTLinkNode(e->GetNode(2),e->GetNode(0),e->GetNode(5)); break;
+              case 8:
+                AddTLinkNode(e->GetNode(0),e->GetNode(1),e->GetNode(4));
+                AddTLinkNode(e->GetNode(1),e->GetNode(2),e->GetNode(5));
+                AddTLinkNode(e->GetNode(2),e->GetNode(3),e->GetNode(6));
+                AddTLinkNode(e->GetNode(3),e->GetNode(0),e->GetNode(7));
+                break;
+              default:
+                myCreateQuadratic = false;
+                break;
+              }
+            }
           }
         }
       }
     }
   }
 
+  if ( nbOldLinks == myTLinkNodeMap.size() )
+    myCreateQuadratic = false;
+
   if(!myCreateQuadratic) {
-    myNLinkNodeMap.clear();
+    myTLinkNodeMap.clear();
   }
   SetSubShape( aSh );
 
   return myCreateQuadratic;
 }
 
-//================================================================================
-/*!
- * \brief Set geomerty to make elements on
-  * \param aSh - geomertic shape
- */
-//================================================================================
+//=======================================================================
+//function : SetSubShape
+//purpose  : Set geomerty to make elements on
+//=======================================================================
 
 void SMESH_MesherHelper::SetSubShape(const int aShID)
 {
   if ( aShID == myShapeID )
     return;
-  if ( aShID > 1 )
+  if ( aShID > 0 )
     SetSubShape( GetMeshDS()->IndexToShape( aShID ));
   else
     SetSubShape( TopoDS_Shape() );
 }
 
-//================================================================================
-/*!
- * \brief Set geomerty to make elements on
-  * \param aSh - geomertic shape
- */
-//================================================================================
+//=======================================================================
+//function : SetSubShape
+//purpose  : Set geomerty to create elements on
+//=======================================================================
 
 void SMESH_MesherHelper::SetSubShape(const TopoDS_Shape& aSh)
 {
@@ -157,39 +223,45 @@ void SMESH_MesherHelper::SetSubShape(const TopoDS_Shape& aSh)
   myDegenShapeIds.clear();
 
   if ( myShape.IsNull() ) {
-    myShapeID  = -1;
+    myShapeID  = 0;
     return;
   }
   SMESHDS_Mesh* meshDS = GetMeshDS();
   myShapeID = meshDS->ShapeToIndex(aSh);
+  myParIndex = 0;
 
   // treatment of periodic faces
   for ( TopExp_Explorer eF( aSh, TopAbs_FACE ); eF.More(); eF.Next() )
   {
     const TopoDS_Face& face = TopoDS::Face( eF.Current() );
-    BRepAdaptor_Surface surface( face );
-    if ( surface.IsUPeriodic() || surface.IsVPeriodic() )
+    TopLoc_Location loc;
+    Handle(Geom_Surface) surface = BRep_Tool::Surface( face, loc );
+
+    if ( surface->IsUPeriodic() || surface->IsVPeriodic() ||
+         surface->IsUClosed()   || surface->IsVClosed() )
     {
+      //while ( surface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface )))
+      //surface = Handle(Geom_RectangularTrimmedSurface)::DownCast( surface )->BasisSurface();
+      GeomAdaptor_Surface surf( surface );
+
       for (TopExp_Explorer exp( face, TopAbs_EDGE ); exp.More(); exp.Next())
       {
         // look for a seam edge
         const TopoDS_Edge& edge = TopoDS::Edge( exp.Current() );
         if ( BRep_Tool::IsClosed( edge, face )) {
           // initialize myPar1, myPar2 and myParIndex
-          if ( mySeamShapeIds.empty() ) {
-            gp_Pnt2d uv1, uv2;
-            BRep_Tool::UVPoints( edge, face, uv1, uv2 );
-            if ( Abs( uv1.Coord(1) - uv2.Coord(1) ) < Abs( uv1.Coord(2) - uv2.Coord(2) ))
-            {
-              myParIndex = 1; // U periodic
-              myPar1 = surface.FirstUParameter();
-              myPar2 = surface.LastUParameter();
-            }
-            else {
-              myParIndex = 2;  // V periodic
-              myPar1 = surface.FirstVParameter();
-              myPar2 = surface.LastVParameter();
-            }
+          gp_Pnt2d uv1, uv2;
+          BRep_Tool::UVPoints( edge, face, uv1, uv2 );
+          if ( Abs( uv1.Coord(1) - uv2.Coord(1) ) < Abs( uv1.Coord(2) - uv2.Coord(2) ))
+          {
+            myParIndex |= U_periodic;
+            myPar1[0] = surf.FirstUParameter();
+            myPar2[0] = surf.LastUParameter();
+          }
+          else {
+            myParIndex |= V_periodic;
+            myPar1[1] = surf.FirstVParameter();
+            myPar2[1] = surf.LastVParameter();
           }
           // store seam shape indices, negative if shape encounters twice
           int edgeID = meshDS->ShapeToIndex( edge );
@@ -211,13 +283,13 @@ void SMESH_MesherHelper::SetSubShape(const TopoDS_Shape& aSh)
   }
 }
 
-//================================================================================
-  /*!
-   * \brief Check if inFaceNode argument is necessary for call GetNodeUV(F,..)
-    * \param F - the face
-    * \retval bool - return true if the face is periodic
-   */
-//================================================================================
+//=======================================================================
+//function : GetNodeUVneedInFaceNode
+//purpose  : Check if inFaceNode argument is necessary for call GetNodeUV(F,..)
+//           Return true if the face is periodic.
+//           If F is Null, answer about sub-shape set through IsQuadraticSubMesh() or
+//           * SetSubShape()
+//=======================================================================
 
 bool SMESH_MesherHelper::GetNodeUVneedInFaceNode(const TopoDS_Face& F) const
 {
@@ -226,7 +298,8 @@ bool SMESH_MesherHelper::GetNodeUVneedInFaceNode(const TopoDS_Face& F) const
   if ( !F.IsNull() && !myShape.IsNull() && myShape.IsSame( F ))
     return !mySeamShapeIds.empty();
 
-  Handle(Geom_Surface) aSurface = BRep_Tool::Surface( F );
+  TopLoc_Location loc;
+  Handle(Geom_Surface) aSurface = BRep_Tool::Surface( F,loc );
   if ( !aSurface.IsNull() )
     return ( aSurface->IsUPeriodic() || aSurface->IsVPeriodic() );
 
@@ -239,125 +312,273 @@ bool SMESH_MesherHelper::GetNodeUVneedInFaceNode(const TopoDS_Face& F) const
 //=======================================================================
 
 bool SMESH_MesherHelper::IsMedium(const SMDS_MeshNode*      node,
-                                 const SMDSAbs_ElementType typeToCheck)
+                                  const SMDSAbs_ElementType typeToCheck)
 {
   return SMESH_MeshEditor::IsMedium( node, typeToCheck );
 }
 
 //=======================================================================
-//function : AddNLinkNode
-//purpose  : 
+//function : GetSubShapeByNode
+//purpose  : Return support shape of a node
+//=======================================================================
+
+TopoDS_Shape SMESH_MesherHelper::GetSubShapeByNode(const SMDS_MeshNode* node,
+                                                   const SMESHDS_Mesh*  meshDS)
+{
+  int shapeID = node->getshapeId();
+  if ( 0 < shapeID && shapeID <= meshDS->MaxShapeIndex() )
+    return meshDS->IndexToShape( shapeID );
+  else
+    return TopoDS_Shape();
+}
+
+
+//=======================================================================
+//function : AddTLinkNode
+//purpose  : add a link in my data structure
 //=======================================================================
+
+void SMESH_MesherHelper::AddTLinkNode(const SMDS_MeshNode* n1,
+                                      const SMDS_MeshNode* n2,
+                                      const SMDS_MeshNode* n12)
+{
+  // add new record to map
+  SMESH_TLink link( n1, n2 );
+  myTLinkNodeMap.insert( make_pair(link,n12));
+}
+
+//================================================================================
 /*!
- * Auxilary function for filling myNLinkNodeMap
+ * \brief Add quadratic links of edge to own data structure
  */
-void SMESH_MesherHelper::AddNLinkNode(const SMDS_MeshNode* n1,
-                                     const SMDS_MeshNode* n2,
-                                     const SMDS_MeshNode* n12)
+//================================================================================
+
+void SMESH_MesherHelper::AddTLinks(const SMDS_MeshEdge* edge)
 {
-  NLink link( n1, n2 );
-  if ( n1 > n2 ) link = NLink( n2, n1 );
-  // add new record to map
-  myNLinkNodeMap.insert( make_pair(link,n12));
+  if ( edge->IsQuadratic() )
+    AddTLinkNode(edge->GetNode(0), edge->GetNode(1), edge->GetNode(2));
 }
 
-//=======================================================================
+//================================================================================
+/*!
+ * \brief Add quadratic links of face to own data structure
+ */
+//================================================================================
+
+void SMESH_MesherHelper::AddTLinks(const SMDS_MeshFace* f)
+{
+  if ( !f->IsPoly() )
+    switch ( f->NbNodes() ) {
+    case 6:
+      AddTLinkNode(f->GetNode(0),f->GetNode(1),f->GetNode(3));
+      AddTLinkNode(f->GetNode(1),f->GetNode(2),f->GetNode(4));
+      AddTLinkNode(f->GetNode(2),f->GetNode(0),f->GetNode(5)); break;
+    case 8:
+      AddTLinkNode(f->GetNode(0),f->GetNode(1),f->GetNode(4));
+      AddTLinkNode(f->GetNode(1),f->GetNode(2),f->GetNode(5));
+      AddTLinkNode(f->GetNode(2),f->GetNode(3),f->GetNode(6));
+      AddTLinkNode(f->GetNode(3),f->GetNode(0),f->GetNode(7));
+    default:;
+    }
+}
+
+//================================================================================
+/*!
+ * \brief Add quadratic links of volume to own data structure
+ */
+//================================================================================
+
+void SMESH_MesherHelper::AddTLinks(const SMDS_MeshVolume* volume)
+{
+  if ( volume->IsQuadratic() )
+  {
+    SMDS_VolumeTool vTool( volume );
+    const SMDS_MeshNode** nodes = vTool.GetNodes();
+    set<int> addedLinks;
+    for ( int iF = 1; iF < vTool.NbFaces(); ++iF )
+    {
+      const int nbN = vTool.NbFaceNodes( iF );
+      const int* iNodes = vTool.GetFaceNodesIndices( iF );
+      for ( int i = 0; i < nbN; )
+      {
+        int iN1  = iNodes[i++];
+        int iN12 = iNodes[i++];
+        int iN2  = iNodes[i++];
+        if ( iN1 > iN2 ) std::swap( iN1, iN2 );
+        int linkID = iN1 * vTool.NbNodes() + iN2;
+        pair< set<int>::iterator, bool > it_isNew = addedLinks.insert( linkID );
+        if ( it_isNew.second )
+          AddTLinkNode( nodes[iN1], nodes[iN2], nodes[iN12] );
+        else
+          addedLinks.erase( it_isNew.first ); // each link encounters only twice
+      }
+    }
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Return true if position of nodes on the shape hasn't yet been checked or
+ * the positions proved to be invalid
+ */
+//================================================================================
+
+bool SMESH_MesherHelper::toCheckPosOnShape(int shapeID ) const
+{
+  map< int,bool >::const_iterator id_ok = myNodePosShapesValidity.find( shapeID );
+  return ( id_ok == myNodePosShapesValidity.end() || !id_ok->second );
+}
+
+//================================================================================
 /*!
- * \brief Select UV on either of 2 pcurves of a seam edge, closest to the given UV
- * \param uv1 - UV on the seam
- * \param uv2 - UV within a face
- * \retval gp_Pnt2d - selected UV
+ * \brief Set validity of positions of nodes on the shape.
+ * Once set, validity is not changed
  */
+//================================================================================
+
+void SMESH_MesherHelper::setPosOnShapeValidity(int shapeID, bool ok ) const
+{
+  ((SMESH_MesherHelper*)this)->myNodePosShapesValidity.insert( make_pair( shapeID, ok));
+}
+
+//=======================================================================
+//function : ToFixNodeParameters
+//purpose  : Enables fixing node parameters on EDGEs and FACEs in 
+//           GetNodeU(...,check=true), GetNodeUV(...,check=true), CheckNodeUV() and
+//           CheckNodeU() in case if a node lies on a shape set via SetSubShape().
+//           Default is False
+//=======================================================================
+
+void SMESH_MesherHelper::ToFixNodeParameters(bool toFix)
+{
+  myFixNodeParameters = toFix;
+}
+
+
+//=======================================================================
+//function : GetUVOnSeam
+//purpose  : Select UV on either of 2 pcurves of a seam edge, closest to the given UV
 //=======================================================================
 
 gp_Pnt2d SMESH_MesherHelper::GetUVOnSeam( const gp_Pnt2d& uv1, const gp_Pnt2d& uv2 ) const
 {
-  double p1 = uv1.Coord( myParIndex );
-  double p2 = uv2.Coord( myParIndex );
-  double p3 = ( Abs( p1 - myPar1 ) < Abs( p1 - myPar2 )) ? myPar2 : myPar1;
-  if ( Abs( p2 - p1 ) > Abs( p2 - p3 ))
-    p1 = p3;
   gp_Pnt2d result = uv1;
-  result.SetCoord( myParIndex, p1 );
+  for ( int i = U_periodic; i <= V_periodic ; ++i )
+  {
+    if ( myParIndex & i )
+    {
+      double p1 = uv1.Coord( i );
+      double dp1 = Abs( p1-myPar1[i-1]), dp2 = Abs( p1-myPar2[i-1]);
+      if ( myParIndex == i ||
+           dp1 < ( myPar2[i-1] - myPar2[i-1] ) / 100. ||
+           dp2 < ( myPar2[i-1] - myPar2[i-1] ) / 100. )
+      {
+        double p2 = uv2.Coord( i );
+        double p1Alt = ( dp1 < dp2 ) ? myPar2[i-1] : myPar1[i-1];
+        if ( Abs( p2 - p1 ) > Abs( p2 - p1Alt ))
+          result.SetCoord( i, p1Alt );
+      }
+    }
+  }
   return result;
 }
 
 //=======================================================================
-/*!
- * \brief Return node UV on face
- * \param F - the face
- * \param n - the node
- * \param n2 - a node of element being created located inside a face
- * \retval gp_XY - resulting UV
- * 
- * Auxilary function called form GetMediumNode()
- */
+//function : GetNodeUV
+//purpose  : Return node UV on face
 //=======================================================================
 
 gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face&   F,
                                     const SMDS_MeshNode* n,
-                                    const SMDS_MeshNode* n2) const
+                                    const SMDS_MeshNode* n2,
+                                    bool*                check) const
 {
-  gp_Pnt2d uv( 1e100, 1e100 );
+  gp_Pnt2d uv( Precision::Infinite(), Precision::Infinite() );
   const SMDS_PositionPtr Pos = n->GetPosition();
+  bool uvOK = false;
   if(Pos->GetTypeOfPosition()==SMDS_TOP_FACE)
   {
     // node has position on face
     const SMDS_FacePosition* fpos =
-      static_cast<const SMDS_FacePosition*>(n->GetPosition().get());
-    uv = gp_Pnt2d(fpos->GetUParameter(),fpos->GetVParameter());
+      static_cast<const SMDS_FacePosition*>(n->GetPosition());
+    uv.SetCoord(fpos->GetUParameter(),fpos->GetVParameter());
+    if ( check )
+      uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 10*MaxTolerance( F ));
   }
   else if(Pos->GetTypeOfPosition()==SMDS_TOP_EDGE)
   {
     // node has position on edge => it is needed to find
     // corresponding edge from face, get pcurve for this
-    // edge and recieve value from this pcurve
+    // edge and retrieve value from this pcurve
     const SMDS_EdgePosition* epos =
-      static_cast<const SMDS_EdgePosition*>(n->GetPosition().get());
-    SMESHDS_Mesh* meshDS = GetMeshDS();
-    int edgeID = Pos->GetShapeId();
-    TopoDS_Edge E = TopoDS::Edge(meshDS->IndexToShape(edgeID));
-    double f, l;
+      static_cast<const SMDS_EdgePosition*>(n->GetPosition());
+    int edgeID = n->getshapeId();
+    TopoDS_Edge E = TopoDS::Edge(GetMeshDS()->IndexToShape(edgeID));
+    double f, l, u = epos->GetUParameter();
     Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
-    uv = C2d->Value( epos->GetUParameter() );
+    bool validU = ( f < u && u < l );
+    if ( validU )
+      uv = C2d->Value( u );
+    else
+      uv.SetCoord( Precision::Infinite(),0.);
+    if ( check || !validU )
+      uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 10*MaxTolerance( F ),/*force=*/ !validU );
+
     // for a node on a seam edge select one of UVs on 2 pcurves
     if ( n2 && IsSeamShape( edgeID ) )
-      uv = GetUVOnSeam( uv, GetNodeUV( F, n2, 0 ));
+    {
+      uv = GetUVOnSeam( uv, GetNodeUV( F, n2, 0, check ));
+    }
+    else
+    { // adjust uv to period
+      TopLoc_Location loc;
+      Handle(Geom_Surface) S = BRep_Tool::Surface(F,loc);
+      Standard_Boolean isUPeriodic = S->IsUPeriodic();
+      Standard_Boolean isVPeriodic = S->IsVPeriodic();
+      if ( isUPeriodic || isVPeriodic ) {
+        Standard_Real UF,UL,VF,VL;
+        S->Bounds(UF,UL,VF,VL);
+        if(isUPeriodic)
+          uv.SetX( uv.X() + ShapeAnalysis::AdjustToPeriod(uv.X(),UF,UL));
+        if(isVPeriodic)
+          uv.SetY( uv.Y() + ShapeAnalysis::AdjustToPeriod(uv.Y(),VF,VL));
+      }
+    }
   }
   else if(Pos->GetTypeOfPosition()==SMDS_TOP_VERTEX)
   {
-    if ( int vertexID = n->GetPosition()->GetShapeId() ) {
-      bool ok = true;
+    if ( int vertexID = n->getshapeId() ) {
       const TopoDS_Vertex& V = TopoDS::Vertex(GetMeshDS()->IndexToShape(vertexID));
       try {
         uv = BRep_Tool::Parameters( V, F );
+        uvOK = true;
       }
       catch (Standard_Failure& exc) {
-        ok = false;
       }
-      if ( !ok ) {
-        for ( TopExp_Explorer vert(F,TopAbs_VERTEX); !ok && vert.More(); vert.Next() )
-          ok = ( V == vert.Current() );
-        if ( !ok ) {
+      if ( !uvOK ) {
+        for ( TopExp_Explorer vert(F,TopAbs_VERTEX); !uvOK && vert.More(); vert.Next() )
+          uvOK = ( V == vert.Current() );
+        if ( !uvOK ) {
 #ifdef _DEBUG_
           MESSAGE ( "SMESH_MesherHelper::GetNodeUV(); Vertex " << vertexID
                << " not in face " << GetMeshDS()->ShapeToIndex( F ) );
 #endif
           // get UV of a vertex closest to the node
           double dist = 1e100;
-          gp_Pnt pn ( n->X(),n->Y(),n->Z() );
-          for ( TopExp_Explorer vert(F,TopAbs_VERTEX); !ok && vert.More(); vert.Next() ) {
+          gp_Pnt pn = XYZ( n );
+          for ( TopExp_Explorer vert(F,TopAbs_VERTEX); !uvOK && vert.More(); vert.Next() ) {
             TopoDS_Vertex curV = TopoDS::Vertex( vert.Current() );
             gp_Pnt p = BRep_Tool::Pnt( curV );
             double curDist = p.SquareDistance( pn );
             if ( curDist < dist ) {
               dist = curDist;
               uv = BRep_Tool::Parameters( curV, F );
-              if ( dist < DBL_MIN ) break;
+              uvOK = ( dist < DBL_MIN );
             }
           }
         }
         else {
+          uvOK = false;
           TopTools_ListIteratorOfListOfShape it( myMesh->GetAncestors( V ));
           for ( ; it.More(); it.Next() ) {
             if ( it.Value().ShapeType() == TopAbs_EDGE ) {
@@ -367,6 +588,7 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face&   F,
               if ( !C2d.IsNull() ) {
                 double u = ( V == TopExp::FirstVertex( edge ) ) ?  f : l;
                 uv = C2d->Value( u );
+                uvOK = true;
                 break;
               }
             }
@@ -377,269 +599,694 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face&   F,
         uv = GetUVOnSeam( uv, GetNodeUV( F, n2, 0 ));
     }
   }
-  return uv.XY();
-}
+  else
+  {
+    uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 10*MaxTolerance( F ));
+  }
 
-//=======================================================================
-/*!
- * \brief Return node U on edge
- * \param E - the Edge
- * \param n - the node
- * \retval double - resulting U
- * 
- * Auxilary function called form GetMediumNode()
- */
-//=======================================================================
+  if ( check )
+    *check = uvOK;
 
-double SMESH_MesherHelper::GetNodeU(const TopoDS_Edge&   E,
-                                    const SMDS_MeshNode* n)
-{
-  double param = 0;
-  const SMDS_PositionPtr Pos = n->GetPosition();
-  if(Pos->GetTypeOfPosition()==SMDS_TOP_EDGE) {
-    const SMDS_EdgePosition* epos =
-      static_cast<const SMDS_EdgePosition*>(n->GetPosition().get());
-    param =  epos->GetUParameter();
-  }
-  else if(Pos->GetTypeOfPosition()==SMDS_TOP_VERTEX) {
-    SMESHDS_Mesh * meshDS = GetMeshDS();
-    int vertexID = n->GetPosition()->GetShapeId();
-    const TopoDS_Vertex& V = TopoDS::Vertex(meshDS->IndexToShape(vertexID));
-    param =  BRep_Tool::Parameter( V, E );
-  }
-  return param;
+  return uv.XY();
 }
 
 //=======================================================================
-//function : GetMediumNode
-//purpose  : 
+//function : CheckNodeUV
+//purpose  : Check and fix node UV on a face
 //=======================================================================
-/*!
- * Special function for search or creation medium node
- */
-const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1,
-                                                       const SMDS_MeshNode* n2,
-                                                       bool force3d)
-{
-  TopAbs_ShapeEnum shapeType = myShape.IsNull() ? TopAbs_SHAPE : myShape.ShapeType();
 
-  NLink link(( n1 < n2 ? n1 : n2 ), ( n1 < n2 ? n2 : n1 ));
-  ItNLinkNode itLN = myNLinkNodeMap.find( link );
-  if ( itLN != myNLinkNodeMap.end() ) {
-    return (*itLN).second;
-  }
-  else {
-    // create medium node
-    SMDS_MeshNode* n12;
-    SMESHDS_Mesh* meshDS = GetMeshDS();
-    int faceID = -1, edgeID = -1;
-    const SMDS_PositionPtr Pos1 = n1->GetPosition();
-    const SMDS_PositionPtr Pos2 = n2->GetPosition();
-  
-    if( myShape.IsNull() )
+bool SMESH_MesherHelper::CheckNodeUV(const TopoDS_Face&   F,
+                                     const SMDS_MeshNode* n,
+                                     gp_XY&               uv,
+                                     const double         tol,
+                                     const bool           force,
+                                     double               distXYZ[4]) const
+{
+  int shapeID = n->getshapeId();
+  bool infinit = ( Precision::IsInfinite( uv.X() ) || Precision::IsInfinite( uv.Y() ));
+  if ( force || toCheckPosOnShape( shapeID ) || infinit )
+  {
+    // check that uv is correct
+    TopLoc_Location loc;
+    Handle(Geom_Surface) surface = BRep_Tool::Surface( F,loc );
+    gp_Pnt nodePnt = XYZ( n ), surfPnt(0,0,0);
+    double dist = 0;
+    if ( !loc.IsIdentity() ) nodePnt.Transform( loc.Transformation().Inverted() );
+    if ( infinit ||
+         (dist = nodePnt.Distance( surfPnt = surface->Value( uv.X(), uv.Y() ))) > tol )
     {
-      if( Pos1->GetTypeOfPosition()==SMDS_TOP_FACE ) {
-        faceID = Pos1->GetShapeId();
+      setPosOnShapeValidity( shapeID, false );
+      if ( !infinit && distXYZ ) {
+        surfPnt.Transform( loc );
+        distXYZ[0] = dist;
+        distXYZ[1] = surfPnt.X(); distXYZ[2] = surfPnt.Y(); distXYZ[3]=surfPnt.Z();
       }
-      else if( Pos2->GetTypeOfPosition()==SMDS_TOP_FACE ) {
-        faceID = Pos2->GetShapeId();
+      // uv incorrect, project the node to surface
+      GeomAPI_ProjectPointOnSurf& projector = GetProjector( F, loc, tol );
+      projector.Perform( nodePnt );
+      if ( !projector.IsDone() || projector.NbPoints() < 1 )
+      {
+        MESSAGE( "SMESH_MesherHelper::CheckNodeUV() failed to project" );
+        return false;
       }
-
-      if( Pos1->GetTypeOfPosition()==SMDS_TOP_EDGE ) {
-        edgeID = Pos1->GetShapeId();
+      Quantity_Parameter U,V;
+      projector.LowerDistanceParameters(U,V);
+      uv.SetCoord( U,V );
+      surfPnt = surface->Value( U, V );
+      dist = nodePnt.Distance( surfPnt );
+      if ( distXYZ ) {
+        surfPnt.Transform( loc );
+        distXYZ[0] = dist;
+        distXYZ[1] = surfPnt.X(); distXYZ[2] = surfPnt.Y(); distXYZ[3]=surfPnt.Z();
       }
-      if( Pos2->GetTypeOfPosition()==SMDS_TOP_EDGE ) {
-        edgeID = Pos2->GetShapeId();
+      if ( dist > tol )
+      {
+        MESSAGE( "SMESH_MesherHelper::CheckNodeUV(), invalid projection" );
+        return false;
       }
+      // store the fixed UV on the face
+      if ( myShape.IsSame(F) && shapeID == myShapeID && myFixNodeParameters )
+        const_cast<SMDS_MeshNode*>(n)->SetPosition
+          ( SMDS_PositionPtr( new SMDS_FacePosition( U, V )));
     }
-
-    if(!force3d) {
-      // we try to create medium node using UV parameters of
-      // nodes, else - medium between corresponding 3d points
-      if(faceID>-1 || shapeType == TopAbs_FACE) {
-       // obtaining a face and 2d points for nodes
-       TopoDS_Face F;
-       if( myShape.IsNull() )
-          F = TopoDS::Face(meshDS->IndexToShape(faceID));
-       else {
-          F = TopoDS::Face(myShape);
-          faceID = myShapeID;
-        }
-
-       gp_XY p1 = GetNodeUV(F,n1,n2);
-        gp_XY p2 = GetNodeUV(F,n2,n1);
-
-       if ( IsDegenShape( Pos1->GetShapeId() ))
-         p1.SetCoord( myParIndex, p2.Coord( myParIndex ));
-       else if ( IsDegenShape( Pos2->GetShapeId() ))
-         p2.SetCoord( myParIndex, p1.Coord( myParIndex ));
-
-       //checking if surface is periodic
-       Handle(Geom_Surface) S = BRep_Tool::Surface(F);
-       Standard_Real UF,UL,VF,VL;
-       S->Bounds(UF,UL,VF,VL);
-
-       Standard_Real u,v;
-       Standard_Boolean isUPeriodic = S->IsUPeriodic();
-       if(isUPeriodic) {
-         Standard_Real UPeriod = S->UPeriod();
-         Standard_Real p2x = p2.X()+ShapeAnalysis::AdjustByPeriod(p2.X(),p1.X(),UPeriod);
-         Standard_Real pmid = (p1.X()+p2x)/2.;
-         u = pmid+ShapeAnalysis::AdjustToPeriod(pmid,UF,UL);
-       }
-       else 
-         u= (p1.X()+p2.X())/2.;
-
-       Standard_Boolean isVPeriodic = S->IsVPeriodic();
-       if(isVPeriodic) {
-         Standard_Real VPeriod = S->VPeriod();
-         Standard_Real p2y = p2.Y()+ShapeAnalysis::AdjustByPeriod(p2.Y(),p1.Y(),VPeriod);
-         Standard_Real pmid = (p1.Y()+p2y)/2.;
-         v = pmid+ShapeAnalysis::AdjustToPeriod(pmid,VF,VL);
-       }
-       else
-         v = (p1.Y()+p2.Y())/2.;
-
-        gp_Pnt P = S->Value(u, v);
-        n12 = meshDS->AddNode(P.X(), P.Y(), P.Z());
-        meshDS->SetNodeOnFace(n12, faceID, u, v);
-        myNLinkNodeMap.insert(NLinkNodeMap::value_type(link,n12));
-        return n12;
-      }
-      if (edgeID>-1 || shapeType == TopAbs_EDGE) {
-
-       TopoDS_Edge E;
-       if( myShape.IsNull() )
-          E = TopoDS::Edge(meshDS->IndexToShape(edgeID));
-       else {
-          E = TopoDS::Edge(myShape);
-          edgeID = myShapeID;
-        }
-
-       double p1 = GetNodeU(E,n1);
-       double p2 = GetNodeU(E,n2);
-
-       double f,l;
-       Handle(Geom_Curve) C = BRep_Tool::Curve(E, f, l);
-       if(!C.IsNull()) {
-
-         Standard_Boolean isPeriodic = C->IsPeriodic();
-         double u;
-         if(isPeriodic) {
-           Standard_Real Period = C->Period();
-           Standard_Real p = p2+ShapeAnalysis::AdjustByPeriod(p2,p1,Period);
-           Standard_Real pmid = (p1+p)/2.;
-           u = pmid+ShapeAnalysis::AdjustToPeriod(pmid,C->FirstParameter(),C->LastParameter());
-         }
-         else
-           u = (p1+p2)/2.;
-
-          gp_Pnt P = C->Value( u );
-          n12 = meshDS->AddNode(P.X(), P.Y(), P.Z());
-          meshDS->SetNodeOnEdge(n12, edgeID, u);
-          myNLinkNodeMap.insert(NLinkNodeMap::value_type(link,n12));
-          return n12;
-       }
-      }
+    else if ( uv.Modulus() > numeric_limits<double>::min() )
+    {
+      setPosOnShapeValidity( shapeID, true );
     }
-    // 3d variant
-    double x = ( n1->X() + n2->X() )/2.;
-    double y = ( n1->Y() + n2->Y() )/2.;
-    double z = ( n1->Z() + n2->Z() )/2.;
-    n12 = meshDS->AddNode(x,y,z);
-    if(edgeID>-1)
-        meshDS->SetNodeOnEdge(n12, edgeID);
-    else if(faceID>-1)
-        meshDS->SetNodeOnFace(n12, faceID);
-    else
-      meshDS->SetNodeInVolume(n12, myShapeID);
-    myNLinkNodeMap.insert(NLinkNodeMap::value_type(link,n12));
-    return n12;
   }
+  return true;
 }
 
 //=======================================================================
-/*!
- * Creates a node
- */
+//function : GetProjector
+//purpose  : Return projector intitialized by given face without location, which is returned
 //=======================================================================
 
-SMDS_MeshNode* SMESH_MesherHelper::AddNode(double x, double y, double z, int ID)
+GeomAPI_ProjectPointOnSurf& SMESH_MesherHelper::GetProjector(const TopoDS_Face& F,
+                                                             TopLoc_Location&   loc,
+                                                             double             tol ) const
 {
-  SMESHDS_Mesh * meshDS = GetMeshDS();
-  SMDS_MeshNode* node = 0;
-  if ( ID )
-    node = meshDS->AddNodeWithID( x, y, z, ID );
-  else
-    node = meshDS->AddNode( x, y, z );
-  if ( mySetElemOnShape && myShapeID > 0 ) {
-    switch ( myShape.ShapeType() ) {
-    case TopAbs_SOLID:  meshDS->SetNodeInVolume( node, myShapeID); break;
-    case TopAbs_SHELL:  meshDS->SetNodeInVolume( node, myShapeID); break;
-    case TopAbs_FACE:   meshDS->SetNodeOnFace(   node, myShapeID); break;
-    case TopAbs_EDGE:   meshDS->SetNodeOnEdge(   node, myShapeID); break;
-    case TopAbs_VERTEX: meshDS->SetNodeOnVertex( node, myShapeID); break;
-    default: ;
-    }
+  Handle(Geom_Surface) surface = BRep_Tool::Surface( F,loc );
+  int faceID = GetMeshDS()->ShapeToIndex( F );
+  TID2ProjectorOnSurf& i2proj = const_cast< TID2ProjectorOnSurf&>( myFace2Projector );
+  TID2ProjectorOnSurf::iterator i_proj = i2proj.find( faceID );
+  if ( i_proj == i2proj.end() )
+  {
+    if ( tol == 0 ) tol = BRep_Tool::Tolerance( F );
+    double U1, U2, V1, V2;
+    surface->Bounds(U1, U2, V1, V2);
+    GeomAPI_ProjectPointOnSurf* proj = new GeomAPI_ProjectPointOnSurf();
+    proj->Init( surface, U1, U2, V1, V2, tol );
+    i_proj = i2proj.insert( make_pair( faceID, proj )).first;
   }
-  return node;
+  return *( i_proj->second );
+}
+
+namespace
+{
+  gp_XY AverageUV(const gp_XY& uv1, const gp_XY& uv2) { return ( uv1 + uv2 ) / 2.; }
+  gp_XY_FunPtr(Added); // define gp_XY_Added pointer to function calling gp_XY::Added(gp_XY)
+  gp_XY_FunPtr(Subtracted); 
 }
 
 //=======================================================================
-/*!
- * Creates quadratic or linear edge
- */
+//function : applyIn2D
+//purpose  : Perform given operation on two 2d points in parameric space of given surface.
+//           It takes into account period of the surface. Use gp_XY_FunPtr macro
+//           to easily define pointer to function of gp_XY class.
 //=======================================================================
 
-SMDS_MeshEdge* SMESH_MesherHelper::AddEdge(const SMDS_MeshNode* n1,
-                                                const SMDS_MeshNode* n2,
-                                                const int id,
-                                                const bool force3d)
+gp_XY SMESH_MesherHelper::applyIn2D(const Handle(Geom_Surface)& surface,
+                                    const gp_XY&                uv1,
+                                    const gp_XY&                uv2,
+                                    xyFunPtr                    fun,
+                                    const bool                  resultInPeriod)
 {
-  SMESHDS_Mesh * meshDS = GetMeshDS();
-  
-  SMDS_MeshEdge* edge = 0;
-  if (myCreateQuadratic) {
-    const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
-    if(id)
-      edge = meshDS->AddEdgeWithID(n1, n2, n12, id);
-    else
-      edge = meshDS->AddEdge(n1, n2, n12);
-  }
-  else {
-    if(id)
-      edge = meshDS->AddEdgeWithID(n1, n2, id);
-    else
-      edge = meshDS->AddEdge(n1, n2);
+  Standard_Boolean isUPeriodic = surface.IsNull() ? false : surface->IsUPeriodic();
+  Standard_Boolean isVPeriodic = surface.IsNull() ? false : surface->IsVPeriodic();
+  if ( !isUPeriodic && !isVPeriodic )
+    return fun(uv1,uv2);
+
+  // move uv2 not far than half-period from uv1
+  double u2 = 
+    uv2.X()+(isUPeriodic ? ShapeAnalysis::AdjustByPeriod(uv2.X(),uv1.X(),surface->UPeriod()) :0);
+  double v2 = 
+    uv2.Y()+(isVPeriodic ? ShapeAnalysis::AdjustByPeriod(uv2.Y(),uv1.Y(),surface->VPeriod()) :0);
+
+  // execute operation
+  gp_XY res = fun( uv1, gp_XY(u2,v2) );
+
+  // move result within period
+  if ( resultInPeriod )
+  {
+    Standard_Real UF,UL,VF,VL;
+    surface->Bounds(UF,UL,VF,VL);
+    if ( isUPeriodic )
+      res.SetX( res.X() + ShapeAnalysis::AdjustToPeriod(res.X(),UF,UL));
+    if ( isVPeriodic )
+      res.SetY( res.Y() + ShapeAnalysis::AdjustToPeriod(res.Y(),VF,VL));
   }
 
-  if ( mySetElemOnShape && myShapeID > 0 )
-    meshDS->SetMeshElementOnShape( edge, myShapeID );
+  return res;
+}
+//=======================================================================
+//function : GetMiddleUV
+//purpose  : Return middle UV taking in account surface period
+//=======================================================================
 
-  return edge;
+gp_XY SMESH_MesherHelper::GetMiddleUV(const Handle(Geom_Surface)& surface,
+                                      const gp_XY&                p1,
+                                      const gp_XY&                p2)
+{
+  // NOTE:
+  // the proper place of getting basic surface seems to be in applyIn2D()
+  // but we put it here to decrease a risk of regressions just before releasing a version
+  Handle(Geom_Surface) surf = surface;
+  while ( !surf.IsNull() && surf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface )))
+    surf = Handle(Geom_RectangularTrimmedSurface)::DownCast( surf )->BasisSurface();
+
+  return applyIn2D( surf, p1, p2, & AverageUV );
 }
 
 //=======================================================================
-/*!
- * Creates quadratic or linear triangle
- */
+//function : GetNodeU
+//purpose  : Return node U on edge
 //=======================================================================
 
-SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1,
-                                           const SMDS_MeshNode* n2,
-                                           const SMDS_MeshNode* n3,
-                                           const int id,
-                                          const bool force3d)
+double SMESH_MesherHelper::GetNodeU(const TopoDS_Edge&   E,
+                                    const SMDS_MeshNode* n,
+                                    const SMDS_MeshNode* inEdgeNode,
+                                    bool*                check)
 {
-  SMESHDS_Mesh * meshDS = GetMeshDS();
-  SMDS_MeshFace* elem = 0;
-  if(!myCreateQuadratic) {
-    if(id)
-      elem = meshDS->AddFaceWithID(n1, n2, n3, id);
-    else
-      elem = meshDS->AddFace(n1, n2, n3);
-  }
-  else {
+  double param = 0;
+  const SMDS_PositionPtr pos = n->GetPosition();
+  if ( pos->GetTypeOfPosition()==SMDS_TOP_EDGE )
+  {
+    const SMDS_EdgePosition* epos = static_cast<const SMDS_EdgePosition*>( pos );
+    param =  epos->GetUParameter();
+  }
+  else if( pos->GetTypeOfPosition() == SMDS_TOP_VERTEX )
+  {
+    if ( inEdgeNode && TopExp::FirstVertex( E ).IsSame( TopExp::LastVertex( E ))) // issue 0020128
+    {
+      Standard_Real f,l;
+      BRep_Tool::Range( E, f,l );
+      double uInEdge = GetNodeU( E, inEdgeNode );
+      param = ( fabs( uInEdge - f ) < fabs( l - uInEdge )) ? f : l;
+    }
+    else
+    {
+      SMESHDS_Mesh * meshDS = GetMeshDS();
+      int vertexID = n->getshapeId();
+      const TopoDS_Vertex& V = TopoDS::Vertex(meshDS->IndexToShape(vertexID));
+      param =  BRep_Tool::Parameter( V, E );
+    }
+  }
+  if ( check )
+  {
+    double tol = BRep_Tool::Tolerance( E );
+    double f,l;  BRep_Tool::Range( E, f,l );
+    bool force = ( param < f-tol || param > l+tol );
+    if ( !force && pos->GetTypeOfPosition()==SMDS_TOP_EDGE )
+      force = ( GetMeshDS()->ShapeToIndex( E ) != n->getshapeId() );
+
+    *check = CheckNodeU( E, n, param, 2*tol, force );
+  }
+  return param;
+}
+
+//=======================================================================
+//function : CheckNodeU
+//purpose  : Check and fix node U on an edge
+//           Return false if U is bad and could not be fixed
+//=======================================================================
+
+bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge&   E,
+                                    const SMDS_MeshNode* n,
+                                    double&              u,
+                                    const double         tol,
+                                    const bool           force,
+                                    double               distXYZ[4]) const
+{
+  int shapeID = n->getshapeId();
+  if ( force || toCheckPosOnShape( shapeID ))
+  {
+    TopLoc_Location loc; double f,l;
+    Handle(Geom_Curve) curve = BRep_Tool::Curve( E,loc,f,l );
+    if ( curve.IsNull() ) // degenerated edge
+    {
+      if ( u+tol < f || u-tol > l )
+      {
+        double r = Max( 0.5, 1 - tol*n->GetID()); // to get a unique u on edge
+        u =  f*r + l*(1-r);
+      }
+    }
+    else
+    {
+      gp_Pnt nodePnt = SMESH_TNodeXYZ( n );
+      if ( !loc.IsIdentity() ) nodePnt.Transform( loc.Transformation().Inverted() );
+      gp_Pnt curvPnt = curve->Value( u );
+      double dist = nodePnt.Distance( curvPnt );
+      if ( distXYZ ) {
+        curvPnt.Transform( loc );
+        distXYZ[0] = dist;
+        distXYZ[1] = curvPnt.X(); distXYZ[2] = curvPnt.Y(); distXYZ[3]=curvPnt.Z();
+      }
+      if ( dist > tol )
+      {
+        setPosOnShapeValidity( shapeID, false );
+        // u incorrect, project the node to the curve
+        int edgeID = GetMeshDS()->ShapeToIndex( E );
+        TID2ProjectorOnCurve& i2proj = const_cast< TID2ProjectorOnCurve&>( myEdge2Projector );
+        TID2ProjectorOnCurve::iterator i_proj =
+          i2proj.insert( make_pair( edgeID, (GeomAPI_ProjectPointOnCurve*) 0 )).first;
+        if ( !i_proj->second  )
+        {
+          i_proj->second = new GeomAPI_ProjectPointOnCurve();
+          i_proj->second->Init( curve, f, l );
+        }
+        GeomAPI_ProjectPointOnCurve* projector = i_proj->second;
+        projector->Perform( nodePnt );
+        if ( projector->NbPoints() < 1 )
+        {
+          MESSAGE( "SMESH_MesherHelper::CheckNodeU() failed to project" );
+          return false;
+        }
+        Quantity_Parameter U = projector->LowerDistanceParameter();
+        u = double( U );
+        curvPnt = curve->Value( u );
+        dist = nodePnt.Distance( curvPnt );
+        if ( distXYZ ) {
+          curvPnt.Transform( loc );
+          distXYZ[0] = dist;
+          distXYZ[1] = curvPnt.X(); distXYZ[2] = curvPnt.Y(); distXYZ[3]=curvPnt.Z();
+        }
+        if ( dist > tol )
+        {
+          MESSAGE( "SMESH_MesherHelper::CheckNodeU(), invalid projection" );
+          MESSAGE("distance " << dist << " " << tol );
+          return false;
+        }
+        // store the fixed U on the edge
+        if ( myShape.IsSame(E) && shapeID == myShapeID && myFixNodeParameters )
+          const_cast<SMDS_MeshNode*>(n)->SetPosition
+            ( SMDS_PositionPtr( new SMDS_EdgePosition( U )));
+      }
+      else if ( fabs( u ) > numeric_limits<double>::min() )
+      {
+        setPosOnShapeValidity( shapeID, true );
+      }
+      if (( u < f-tol || u > l+tol ) && force )
+      {
+        // node is on vertex but is set on periodic but trimmed edge (issue 0020890)
+        try
+        {
+          // do not use IsPeriodic() as Geom_TrimmedCurve::IsPeriodic () returns false
+          double period = curve->Period();
+          u = ( u < f ) ? u + period : u - period;
+        }
+        catch (Standard_Failure& exc)
+        {
+          return false;
+        }
+      }
+    }
+  }
+  return true;
+}
+
+//=======================================================================
+//function : GetMediumPos
+//purpose  : Return index and type of the shape  (EDGE or FACE only) to
+//          set a medium node on
+//=======================================================================
+
+std::pair<int, TopAbs_ShapeEnum> SMESH_MesherHelper::GetMediumPos(const SMDS_MeshNode* n1,
+                                                                  const SMDS_MeshNode* n2)
+{
+  TopAbs_ShapeEnum shapeType = TopAbs_SHAPE;
+  int              shapeID = -1;
+  TopoDS_Shape     shape;
+
+  if (( myShapeID == n1->getshapeId() || myShapeID == n2->getshapeId() ) && myShapeID > 0 )
+  {
+    shapeType = myShape.ShapeType();
+    shapeID   = myShapeID;
+  }
+  else if ( n1->getshapeId() == n2->getshapeId() )
+  {
+    shapeID = n2->getshapeId();
+    shape = GetSubShapeByNode( n1, GetMeshDS() );
+  }
+  else
+  {
+    const SMDS_TypeOfPosition Pos1 = n1->GetPosition()->GetTypeOfPosition();
+    const SMDS_TypeOfPosition Pos2 = n2->GetPosition()->GetTypeOfPosition();
+
+    if ( Pos1 == SMDS_TOP_3DSPACE || Pos2 == SMDS_TOP_3DSPACE )
+    {
+    }
+    else if ( Pos1 == SMDS_TOP_FACE || Pos2 == SMDS_TOP_FACE )
+    {
+      if ( Pos1 != SMDS_TOP_FACE || Pos2 != SMDS_TOP_FACE )
+      {
+        if ( Pos1 != SMDS_TOP_FACE ) std::swap( n1,n2 );
+        TopoDS_Shape F = GetSubShapeByNode( n1, GetMeshDS() );
+        TopoDS_Shape S = GetSubShapeByNode( n2, GetMeshDS() );
+        if ( IsSubShape( S, F ))
+        {
+          shapeType = TopAbs_FACE;
+          shapeID   = n1->getshapeId();
+        }
+      }
+    }
+    else if ( Pos1 == SMDS_TOP_EDGE && Pos2 == SMDS_TOP_EDGE )
+    {
+      TopoDS_Shape E1 = GetSubShapeByNode( n1, GetMeshDS() );
+      TopoDS_Shape E2 = GetSubShapeByNode( n2, GetMeshDS() );
+      shape = GetCommonAncestor( E1, E2, *myMesh, TopAbs_FACE );
+    }
+    else if ( Pos1 == SMDS_TOP_VERTEX && Pos2 == SMDS_TOP_VERTEX )
+    {
+      TopoDS_Shape V1 = GetSubShapeByNode( n1, GetMeshDS() );
+      TopoDS_Shape V2 = GetSubShapeByNode( n2, GetMeshDS() );
+      shape = GetCommonAncestor( V1, V2, *myMesh, TopAbs_EDGE );
+      if ( shape.IsNull() ) shape = GetCommonAncestor( V1, V2, *myMesh, TopAbs_FACE );
+    }
+    else // VERTEX and EDGE
+    {
+      if ( Pos1 != SMDS_TOP_VERTEX ) std::swap( n1,n2 );
+      TopoDS_Shape V = GetSubShapeByNode( n1, GetMeshDS() );
+      TopoDS_Shape E = GetSubShapeByNode( n2, GetMeshDS() );
+      if ( IsSubShape( V, E ))
+        shape = E;
+      else
+        shape = GetCommonAncestor( V, E, *myMesh, TopAbs_FACE );
+    }
+  }
+
+  if ( !shape.IsNull() )
+  {
+    if ( shapeID < 1 )
+      shapeID = GetMeshDS()->ShapeToIndex( shape );
+    shapeType = shape.ShapeType();
+  }
+  return make_pair( shapeID, shapeType );
+}
+
+//=======================================================================
+//function : GetMediumNode
+//purpose  : Return existing or create new medium nodes between given ones
+//=======================================================================
+
+const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1,
+                                                       const SMDS_MeshNode* n2,
+                                                       bool                 force3d)
+{
+  // Find existing node
+
+  SMESH_TLink link(n1,n2);
+  ItTLinkNode itLN = myTLinkNodeMap.find( link );
+  if ( itLN != myTLinkNodeMap.end() ) {
+    return (*itLN).second;
+  }
+
+  // Create medium node
+
+  SMDS_MeshNode* n12;
+  SMESHDS_Mesh* meshDS = GetMeshDS();
+
+  if ( IsSeamShape( n1->getshapeId() ))
+    // to get a correct UV of a node on seam, the second node must have checked UV
+    std::swap( n1, n2 );
+
+  // get type of shape for the new medium node
+  int faceID = -1, edgeID = -1;
+  TopoDS_Edge E; double u [2];
+  TopoDS_Face F; gp_XY  uv[2];
+  bool uvOK[2] = { false, false };
+
+  pair<int, TopAbs_ShapeEnum> pos = GetMediumPos( n1, n2 );
+
+  // get positions of the given nodes on shapes
+  if ( pos.second == TopAbs_FACE )
+  {
+    F = TopoDS::Face(meshDS->IndexToShape( faceID = pos.first ));
+    uv[0] = GetNodeUV(F,n1,n2, force3d ? 0 : &uvOK[0]);
+    uv[1] = GetNodeUV(F,n2,n1, force3d ? 0 : &uvOK[1]);
+  }
+  else if ( pos.second == TopAbs_EDGE )
+  {
+    const SMDS_PositionPtr Pos1 = n1->GetPosition();
+    const SMDS_PositionPtr Pos2 = n2->GetPosition();
+    if ( Pos1->GetTypeOfPosition()==SMDS_TOP_EDGE &&
+         Pos2->GetTypeOfPosition()==SMDS_TOP_EDGE &&
+         n1->getshapeId() != n2->getshapeId() )
+    {
+      // issue 0021006
+      return getMediumNodeOnComposedWire(n1,n2,force3d);
+    }
+    E = TopoDS::Edge(meshDS->IndexToShape( edgeID = pos.first ));
+    u[0] = GetNodeU(E,n1,n2, force3d ? 0 : &uvOK[0]);
+    u[1] = GetNodeU(E,n2,n1, force3d ? 0 : &uvOK[1]);
+  }
+
+  if ( !force3d & uvOK[0] && uvOK[1] )
+  {
+    // we try to create medium node using UV parameters of
+    // nodes, else - medium between corresponding 3d points
+    if( ! F.IsNull() )
+    {
+      //if ( uvOK[0] && uvOK[1] )
+      {
+        if ( IsDegenShape( n1->getshapeId() )) {
+          if ( myParIndex & U_periodic ) uv[0].SetCoord( 1, uv[1].Coord( 1 ));
+          else                           uv[0].SetCoord( 2, uv[1].Coord( 2 ));
+        }
+        else if ( IsDegenShape( n2->getshapeId() )) {
+          if ( myParIndex & U_periodic ) uv[1].SetCoord( 1, uv[0].Coord( 1 ));
+          else                           uv[1].SetCoord( 2, uv[0].Coord( 2 ));
+        }
+
+        TopLoc_Location loc;
+        Handle(Geom_Surface) S = BRep_Tool::Surface(F,loc);
+        gp_XY UV = GetMiddleUV( S, uv[0], uv[1] );
+        gp_Pnt P = S->Value( UV.X(), UV.Y() ).Transformed(loc);
+        n12 = meshDS->AddNode(P.X(), P.Y(), P.Z());
+        meshDS->SetNodeOnFace(n12, faceID, UV.X(), UV.Y());
+        myTLinkNodeMap.insert(make_pair(link,n12));
+        return n12;
+      }
+    }
+    else if ( !E.IsNull() )
+    {
+      double f,l;
+      Handle(Geom_Curve) C = BRep_Tool::Curve(E, f, l);
+      if(!C.IsNull())
+      {
+        Standard_Boolean isPeriodic = C->IsPeriodic();
+        double U;
+        if(isPeriodic) {
+          Standard_Real Period = C->Period();
+          Standard_Real p = u[1]+ShapeAnalysis::AdjustByPeriod(u[1],u[0],Period);
+          Standard_Real pmid = (u[0]+p)/2.;
+          U = pmid+ShapeAnalysis::AdjustToPeriod(pmid,C->FirstParameter(),C->LastParameter());
+        }
+        else
+          U = (u[0]+u[1])/2.;
+
+        gp_Pnt P = C->Value( U );
+        n12 = meshDS->AddNode(P.X(), P.Y(), P.Z());
+        meshDS->SetNodeOnEdge(n12, edgeID, U);
+        myTLinkNodeMap.insert(make_pair(link,n12));
+        return n12;
+      }
+    }
+  }
+
+  // 3d variant
+  double x = ( n1->X() + n2->X() )/2.;
+  double y = ( n1->Y() + n2->Y() )/2.;
+  double z = ( n1->Z() + n2->Z() )/2.;
+  n12 = meshDS->AddNode(x,y,z);
+
+  if ( !F.IsNull() )
+  {
+    gp_XY UV = ( uv[0] + uv[1] ) / 2.;
+    CheckNodeUV( F, n12, UV, 2*BRep_Tool::Tolerance( F ), /*force=*/true);
+    meshDS->SetNodeOnFace(n12, faceID, UV.X(), UV.Y() );
+  }
+  else if ( !E.IsNull() )
+  {
+    double U = ( u[0] + u[1] ) / 2.;
+    CheckNodeU( E, n12, U, 2*BRep_Tool::Tolerance( E ), /*force=*/true);
+    meshDS->SetNodeOnEdge(n12, edgeID, U);
+  }
+  else if ( myShapeID > 0 )
+  {
+    meshDS->SetNodeInVolume(n12, myShapeID);
+  }
+
+  myTLinkNodeMap.insert( make_pair( link, n12 ));
+  return n12;
+}
+
+//================================================================================
+/*!
+ * \brief Makes a medium node if nodes reside different edges
+ */
+//================================================================================
+
+const SMDS_MeshNode* SMESH_MesherHelper::getMediumNodeOnComposedWire(const SMDS_MeshNode* n1,
+                                                                     const SMDS_MeshNode* n2,
+                                                                     bool                 force3d)
+{
+  gp_Pnt middle = 0.5 * XYZ(n1) + 0.5 * XYZ(n2);
+  SMDS_MeshNode* n12 = AddNode( middle.X(), middle.Y(), middle.Z() );
+
+  // To find position on edge and 3D position for n12,
+  // project <middle> to 2 edges and select projection most close to <middle>
+
+  double u = 0, distMiddleProj = Precision::Infinite(), distXYZ[4];
+  int iOkEdge = 0;
+  TopoDS_Edge edges[2];
+  for ( int is2nd = 0; is2nd < 2; ++is2nd )
+  {
+    // get an edge
+    const SMDS_MeshNode* n = is2nd ? n2 : n1;
+    TopoDS_Shape shape = GetSubShapeByNode( n, GetMeshDS() );
+    if ( shape.IsNull() || shape.ShapeType() != TopAbs_EDGE )
+      continue;
+
+    // project to get U of projection and distance from middle to projection
+    TopoDS_Edge edge = edges[ is2nd ] = TopoDS::Edge( shape );
+    double node2MiddleDist = middle.Distance( XYZ(n) );
+    double foundU = GetNodeU( edge, n );
+    CheckNodeU( edge, n12, foundU, 2*BRep_Tool::Tolerance(edge), /*force=*/true, distXYZ );
+    if ( distXYZ[0] < node2MiddleDist )
+    {
+      distMiddleProj = distXYZ[0];
+      u = foundU;
+      iOkEdge = is2nd;
+    }
+  }
+  if ( Precision::IsInfinite( distMiddleProj ))
+  {
+    // both projections failed; set n12 on the edge of n1 with U of a common vertex
+    TopoDS_Vertex vCommon;
+    if ( TopExp::CommonVertex( edges[0], edges[1], vCommon ))
+      u = BRep_Tool::Parameter( vCommon, edges[0] );
+    else
+    {
+      double f,l, u0 = GetNodeU( edges[0], n1 );
+      BRep_Tool::Range( edges[0],f,l );
+      u = ( fabs(u0-f) < fabs(u0-l) ) ? f : l;
+    }
+    iOkEdge = 0;
+    distMiddleProj = 0;
+  }
+
+  // move n12 to position of a successfull projection
+  double tol = BRep_Tool::Tolerance(edges[ iOkEdge ]);
+  if ( !force3d && distMiddleProj > 2*tol )
+  {
+    TopLoc_Location loc; double f,l;
+    Handle(Geom_Curve) curve = BRep_Tool::Curve( edges[iOkEdge],loc,f,l );
+    gp_Pnt p = curve->Value( u );
+    GetMeshDS()->MoveNode( n12, p.X(), p.Y(), p.Z() );
+  }
+
+  GetMeshDS()->SetNodeOnEdge(n12, edges[iOkEdge], u);
+
+  myTLinkNodeMap.insert( make_pair( SMESH_TLink(n1,n2), n12 ));
+
+  return n12;
+}
+
+//=======================================================================
+//function : AddNode
+//purpose  : Creates a node
+//=======================================================================
+
+SMDS_MeshNode* SMESH_MesherHelper::AddNode(double x, double y, double z, int ID,
+                                           double u, double v)
+{
+  SMESHDS_Mesh * meshDS = GetMeshDS();
+  SMDS_MeshNode* node = 0;
+  if ( ID )
+    node = meshDS->AddNodeWithID( x, y, z, ID );
+  else
+    node = meshDS->AddNode( x, y, z );
+  if ( mySetElemOnShape && myShapeID > 0 ) {
+    switch ( myShape.ShapeType() ) {
+    case TopAbs_SOLID:  meshDS->SetNodeInVolume( node, myShapeID);       break;
+    case TopAbs_SHELL:  meshDS->SetNodeInVolume( node, myShapeID);       break;
+    case TopAbs_FACE:   meshDS->SetNodeOnFace(   node, myShapeID, u, v); break;
+    case TopAbs_EDGE:   meshDS->SetNodeOnEdge(   node, myShapeID, u);    break;
+    case TopAbs_VERTEX: meshDS->SetNodeOnVertex( node, myShapeID);       break;
+    default: ;
+    }
+  }
+  return node;
+}
+
+//=======================================================================
+//function : AddEdge
+//purpose  : Creates quadratic or linear edge
+//=======================================================================
+
+SMDS_MeshEdge* SMESH_MesherHelper::AddEdge(const SMDS_MeshNode* n1,
+                                           const SMDS_MeshNode* n2,
+                                           const int            id,
+                                           const bool           force3d)
+{
+  SMESHDS_Mesh * meshDS = GetMeshDS();
+  
+  SMDS_MeshEdge* edge = 0;
+  if (myCreateQuadratic) {
+    const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
+    if(id)
+      edge = meshDS->AddEdgeWithID(n1, n2, n12, id);
+    else
+      edge = meshDS->AddEdge(n1, n2, n12);
+  }
+  else {
+    if(id)
+      edge = meshDS->AddEdgeWithID(n1, n2, id);
+    else
+      edge = meshDS->AddEdge(n1, n2);
+  }
+
+  if ( mySetElemOnShape && myShapeID > 0 )
+    meshDS->SetMeshElementOnShape( edge, myShapeID );
+
+  return edge;
+}
+
+//=======================================================================
+//function : AddFace
+//purpose  : Creates quadratic or linear triangle
+//=======================================================================
+
+SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1,
+                                           const SMDS_MeshNode* n2,
+                                           const SMDS_MeshNode* n3,
+                                           const int id,
+                                           const bool force3d)
+{
+  SMESHDS_Mesh * meshDS = GetMeshDS();
+  SMDS_MeshFace* elem = 0;
+
+  if( n1==n2 || n2==n3 || n3==n1 )
+    return elem;
+
+  if(!myCreateQuadratic) {
+    if(id)
+      elem = meshDS->AddFaceWithID(n1, n2, n3, id);
+    else
+      elem = meshDS->AddFace(n1, n2, n3);
+  }
+  else {
     const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
     const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
     const SMDS_MeshNode* n31 = GetMediumNode(n3,n1,force3d);
@@ -656,20 +1303,39 @@ SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1,
 }
 
 //=======================================================================
-/*!
- * Creates quadratic or linear quadrangle
- */
+//function : AddFace
+//purpose  : Creates quadratic or linear quadrangle
 //=======================================================================
 
 SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1,
                                            const SMDS_MeshNode* n2,
                                            const SMDS_MeshNode* n3,
                                            const SMDS_MeshNode* n4,
-                                           const int id,
-                                          const bool force3d)
+                                           const int            id,
+                                           const bool           force3d)
 {
   SMESHDS_Mesh * meshDS = GetMeshDS();
   SMDS_MeshFace* elem = 0;
+
+  if( n1==n2 ) {
+    return AddFace(n1,n3,n4,id,force3d);
+  }
+  if( n1==n3 ) {
+    return AddFace(n1,n2,n4,id,force3d);
+  }
+  if( n1==n4 ) {
+    return AddFace(n1,n2,n3,id,force3d);
+  }
+  if( n2==n3 ) {
+    return AddFace(n1,n2,n4,id,force3d);
+  }
+  if( n2==n4 ) {
+    return AddFace(n1,n2,n3,id,force3d);
+  }
+  if( n3==n4 ) {
+    return AddFace(n1,n2,n3,id,force3d);
+  }
+
   if(!myCreateQuadratic) {
     if(id)
       elem = meshDS->AddFaceWithID(n1, n2, n3, n4, id);
@@ -694,32 +1360,70 @@ SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1,
 }
 
 //=======================================================================
-/*!
- * Creates quadratic or linear volume
- */
+//function : AddPolygonalFace
+//purpose  : Creates polygon, with additional nodes in quadratic mesh
 //=======================================================================
 
-SMDS_MeshVolume* SMESH_MesherHelper::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 int id,
-                                              const bool force3d)
+SMDS_MeshFace* SMESH_MesherHelper::AddPolygonalFace (const vector<const SMDS_MeshNode*>& nodes,
+                                                     const int                           id,
+                                                     const bool                          force3d)
 {
   SMESHDS_Mesh * meshDS = GetMeshDS();
-  SMDS_MeshVolume* elem = 0;
+  SMDS_MeshFace* elem = 0;
+
   if(!myCreateQuadratic) {
     if(id)
-      elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, id);
+      elem = meshDS->AddPolygonalFaceWithID(nodes, id);
     else
-      elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6);
+      elem = meshDS->AddPolygonalFace(nodes);
   }
   else {
-    const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
-    const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
-    const SMDS_MeshNode* n31 = GetMediumNode(n3,n1,force3d);
+    vector<const SMDS_MeshNode*> newNodes;
+    for ( int i = 0; i < nodes.size(); ++i )
+    {
+      const SMDS_MeshNode* n1 = nodes[i];
+      const SMDS_MeshNode* n2 = nodes[(i+1)%nodes.size()];
+      const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
+      newNodes.push_back( n1 );
+      newNodes.push_back( n12 );
+    }
+    if(id)
+      elem = meshDS->AddPolygonalFaceWithID(newNodes, id);
+    else
+      elem = meshDS->AddPolygonalFace(newNodes);
+  }
+  if ( mySetElemOnShape && myShapeID > 0 )
+    meshDS->SetMeshElementOnShape( elem, myShapeID );
+
+  return elem;
+}
+
+//=======================================================================
+//function : AddVolume
+//purpose  : Creates quadratic or linear prism
+//=======================================================================
+
+SMDS_MeshVolume* SMESH_MesherHelper::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 int id,
+                                               const bool force3d)
+{
+  SMESHDS_Mesh * meshDS = GetMeshDS();
+  SMDS_MeshVolume* elem = 0;
+  if(!myCreateQuadratic) {
+    if(id)
+      elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, id);
+    else
+      elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6);
+  }
+  else {
+    const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
+    const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
+    const SMDS_MeshNode* n31 = GetMediumNode(n3,n1,force3d);
 
     const SMDS_MeshNode* n45 = GetMediumNode(n4,n5,force3d);
     const SMDS_MeshNode* n56 = GetMediumNode(n5,n6,force3d);
@@ -743,9 +1447,8 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
 }
 
 //=======================================================================
-/*!
- * Creates quadratic or linear volume
- */
+//function : AddVolume
+//purpose  : Creates quadratic or linear tetrahedron
 //=======================================================================
 
 SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
@@ -753,7 +1456,7 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
                                                const SMDS_MeshNode* n3,
                                                const SMDS_MeshNode* n4,
                                                const int id, 
-                                              const bool force3d)
+                                               const bool force3d)
 {
   SMESHDS_Mesh * meshDS = GetMeshDS();
   SMDS_MeshVolume* elem = 0;
@@ -784,9 +1487,8 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
 }
 
 //=======================================================================
-/*!
- * Creates quadratic or linear pyramid
- */
+//function : AddVolume
+//purpose  : Creates quadratic or linear pyramid
 //=======================================================================
 
 SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
@@ -795,7 +1497,7 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
                                                const SMDS_MeshNode* n4,
                                                const SMDS_MeshNode* n5,
                                                const int id, 
-                                              const bool force3d)
+                                               const bool force3d)
 {
   SMDS_MeshVolume* elem = 0;
   if(!myCreateQuadratic) {
@@ -832,9 +1534,8 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
 }
 
 //=======================================================================
-/*!
- * Creates quadratic or linear hexahedron
- */
+//function : AddVolume
+//purpose  : Creates quadratic or linear hexahedron
 //=======================================================================
 
 SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
@@ -846,7 +1547,7 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
                                                const SMDS_MeshNode* n7,
                                                const SMDS_MeshNode* n8,
                                                const int id,
-                                              const bool force3d)
+                                               const bool force3d)
 {
   SMESHDS_Mesh * meshDS = GetMeshDS();
   SMDS_MeshVolume* elem = 0;
@@ -888,273 +1589,369 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
 }
 
 //=======================================================================
-/*!
- * \brief Load nodes bound to face into a map of node columns
- * \param theParam2ColumnMap - map of node columns to fill
- * \param theFace - the face on which nodes are searched for
- * \param theBaseEdge - the edge nodes of which are columns' bases
- * \param theMesh - the mesh containing nodes
- * \retval bool - false if something is wrong
- * 
- * The key of the map is a normalized parameter of each
- * base node on theBaseEdge.
- * This method works in supposition that nodes on the face
- * forms a rectangular grid and elements can be quardrangles or triangles
- */
+//function : AddVolume
+//purpose  : Creates LINEAR!!!!!!!!! octahedron
 //=======================================================================
 
-bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap,
-                                         const TopoDS_Face& theFace,
-                                         const TopoDS_Edge& theBaseEdge,
-                                         SMESHDS_Mesh*      theMesh)
+SMDS_MeshVolume* SMESH_MesherHelper::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* n9,
+                                               const SMDS_MeshNode* n10,
+                                               const SMDS_MeshNode* n11,
+                                               const SMDS_MeshNode* n12,
+                                               const int id, 
+                                               bool force3d)
 {
-  // get vertices of theBaseEdge
-  TopoDS_Vertex vfb, vlb, vft; // first and last, bottom and top vertices
-  TopoDS_Edge eFrw = TopoDS::Edge( theBaseEdge.Oriented( TopAbs_FORWARD ));
-  TopExp::Vertices( eFrw, vfb, vlb );
-
-  // find the other edges of theFace and orientation of e1
-  TopoDS_Edge e1, e2, eTop;
-  bool rev1, CumOri = false;
-  TopExp_Explorer exp( theFace, TopAbs_EDGE );
-  int nbEdges = 0;
-  for ( ; exp.More(); exp.Next() ) {
-    if ( ++nbEdges > 4 ) {
-      return false; // more than 4 edges in theFace
-    }
-    TopoDS_Edge e = TopoDS::Edge( exp.Current() );
-    if ( theBaseEdge.IsSame( e ))
-      continue;
-    TopoDS_Vertex vCommon;
-    if ( !TopExp::CommonVertex( theBaseEdge, e, vCommon ))
-      eTop = e;
-    else if ( vCommon.IsSame( vfb )) {
-      e1 = e;
-      vft = TopExp::LastVertex( e1, CumOri );
-      rev1 = vfb.IsSame( vft );
-      if ( rev1 )
-        vft = TopExp::FirstVertex( e1, CumOri );
-    }
+  SMESHDS_Mesh * meshDS = GetMeshDS();
+  SMDS_MeshVolume* elem = 0;
+  if(id)
+    elem = meshDS->AddVolumeWithID(n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,id);
+  else
+    elem = meshDS->AddVolume(n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12);
+  if ( mySetElemOnShape && myShapeID > 0 )
+    meshDS->SetMeshElementOnShape( elem, myShapeID );
+  return elem;
+}
+
+//=======================================================================
+//function : AddPolyhedralVolume
+//purpose  : Creates polyhedron. In quadratic mesh, adds medium nodes
+//=======================================================================
+
+SMDS_MeshVolume*
+SMESH_MesherHelper::AddPolyhedralVolume (const std::vector<const SMDS_MeshNode*>& nodes,
+                                         const std::vector<int>&                  quantities,
+                                         const int                                id,
+                                         const bool                               force3d)
+{
+  SMESHDS_Mesh * meshDS = GetMeshDS();
+  SMDS_MeshVolume* elem = 0;
+  if(!myCreateQuadratic)
+  {
+    if(id)
+      elem = meshDS->AddPolyhedralVolumeWithID(nodes, quantities, id);
     else
-      e2 = e;
-  }
-  if ( nbEdges < 4 ) {
-    return false; // less than 4 edges in theFace
-  }
-  if ( e2.IsNull() && vfb.IsSame( vlb ))
-    e2 = e1;
-
-  // submeshes corresponding to shapes
-  SMESHDS_SubMesh* smFace = theMesh->MeshElements( theFace );
-  SMESHDS_SubMesh* smb = theMesh->MeshElements( theBaseEdge );
-  SMESHDS_SubMesh* smt = theMesh->MeshElements( eTop );
-  SMESHDS_SubMesh* sm1 = theMesh->MeshElements( e1 );
-  SMESHDS_SubMesh* sm2 = theMesh->MeshElements( e2 );
-  SMESHDS_SubMesh* smVfb = theMesh->MeshElements( vfb );
-  SMESHDS_SubMesh* smVlb = theMesh->MeshElements( vlb );
-  SMESHDS_SubMesh* smVft = theMesh->MeshElements( vft );
-  if (!smFace || !smb || !smt || !sm1 || !sm2 || !smVfb || !smVlb || !smVft ) {
-    RETURN_BAD_RESULT( "NULL submesh " <<smFace<<" "<<smb<<" "<<smt<<" "<<
-                       sm1<<" "<<sm2<<" "<<smVfb<<" "<<smVlb<<" "<<smVft);
-  }
-  if ( smb->NbNodes() != smt->NbNodes() || sm1->NbNodes() != sm2->NbNodes() ) {
-    RETURN_BAD_RESULT(" Diff nb of nodes on opposite edges" );
-  }
-  if (smVfb->NbNodes() != 1 || smVlb->NbNodes() != 1 || smVft->NbNodes() != 1) {
-    RETURN_BAD_RESULT("Empty submesh of vertex");
-  }
-  // define whether mesh is quadratic
-  bool isQuadraticMesh = false;
-  SMDS_ElemIteratorPtr eIt = smFace->GetElements();
-  if ( !eIt->more() ) {
-    RETURN_BAD_RESULT("No elements on the face");
-  }
-  const SMDS_MeshElement* e = eIt->next();
-  isQuadraticMesh = e->IsQuadratic();
-  
-  if ( sm1->NbNodes() * smb->NbNodes() != smFace->NbNodes() ) {
-    // check quadratic case
-    if ( isQuadraticMesh ) {
-      // what if there are quadrangles and triangles mixed?
-//       int n1 = sm1->NbNodes()/2;
-//       int n2 = smb->NbNodes()/2;
-//       int n3 = sm1->NbNodes() - n1;
-//       int n4 = smb->NbNodes() - n2;
-//       int nf = sm1->NbNodes()*smb->NbNodes() - n3*n4;
-//       if( nf != smFace->NbNodes() ) {
-//         MESSAGE( "Wrong nb face nodes: " <<
-//                 sm1->NbNodes()<<" "<<smb->NbNodes()<<" "<<smFace->NbNodes());
-//         return false;
-//       }
-    }
-    else {
-      RETURN_BAD_RESULT( "Wrong nb face nodes: " <<
-                         sm1->NbNodes()<<" "<<smb->NbNodes()<<" "<<smFace->NbNodes());
-    }
+      elem = meshDS->AddPolyhedralVolume(nodes, quantities);
   }
-  // IJ size
-  int vsize = sm1->NbNodes() + 2;
-  int hsize = smb->NbNodes() + 2;
-  if(isQuadraticMesh) {
-    vsize = vsize - sm1->NbNodes()/2 -1;
-    hsize = hsize - smb->NbNodes()/2 -1;
+  else
+  {
+    vector<const SMDS_MeshNode*> newNodes;
+    vector<int> newQuantities;
+    for ( int iFace=0, iN=0; iFace < quantities.size(); ++iFace)
+    {
+      int nbNodesInFace = quantities[iFace];
+      newQuantities.push_back(0);
+      for ( int i = 0; i < nbNodesInFace; ++i )
+      {
+        const SMDS_MeshNode* n1 = nodes[ iN + i ];
+        newNodes.push_back( n1 );
+        newQuantities.back()++;
+        
+        const SMDS_MeshNode* n2 = nodes[ iN + ( i+1==nbNodesInFace ? 0 : i+1 )];
+//         if ( n1->GetPosition()->GetTypeOfPosition() != SMDS_TOP_3DSPACE &&
+//              n2->GetPosition()->GetTypeOfPosition() != SMDS_TOP_3DSPACE )
+        {
+          const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
+          newNodes.push_back( n12 );
+          newQuantities.back()++;
+        }
+      }
+      iN += nbNodesInFace;
+    }
+    if(id)
+      elem = meshDS->AddPolyhedralVolumeWithID( newNodes, newQuantities, id );
+    else
+      elem = meshDS->AddPolyhedralVolume( newNodes, newQuantities );
   }
+  if ( mySetElemOnShape && myShapeID > 0 )
+    meshDS->SetMeshElementOnShape( elem, myShapeID );
+
+  return elem;
+}
 
-  // load nodes from theBaseEdge
+//=======================================================================
+//function : LoadNodeColumns
+//purpose  : Load nodes bound to face into a map of node columns
+//=======================================================================
 
-  std::set<const SMDS_MeshNode*> loadedNodes;
-  const SMDS_MeshNode* nullNode = 0;
+bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap,
+                                         const TopoDS_Face& theFace,
+                                         const TopoDS_Edge& theBaseEdge,
+                                         SMESHDS_Mesh*      theMesh,
+                                         SMESH_ProxyMesh*   theProxyMesh)
+{
+  return LoadNodeColumns(theParam2ColumnMap,
+                         theFace,
+                         std::list<TopoDS_Edge>(1,theBaseEdge),
+                         theMesh,
+                         theProxyMesh);
+}
 
-  std::vector<const SMDS_MeshNode*> & nVecf = theParam2ColumnMap[ 0.];
-  nVecf.resize( vsize, nullNode );
-  loadedNodes.insert( nVecf[ 0 ] = smVfb->GetNodes()->next() );
+//=======================================================================
+//function : LoadNodeColumns
+//purpose  : Load nodes bound to face into a map of node columns
+//=======================================================================
 
-  std::vector<const SMDS_MeshNode*> & nVecl = theParam2ColumnMap[ 1.];
-  nVecl.resize( vsize, nullNode );
-  loadedNodes.insert( nVecl[ 0 ] = smVlb->GetNodes()->next() );
+bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap &            theParam2ColumnMap,
+                                         const TopoDS_Face&            theFace,
+                                         const std::list<TopoDS_Edge>& theBaseSide,
+                                         SMESHDS_Mesh*                 theMesh,
+                                         SMESH_ProxyMesh*              theProxyMesh)
+{
+  // get a right submesh of theFace
 
-  double f, l;
-  BRep_Tool::Range( eFrw, f, l );
-  double range = l - f;
-  SMDS_NodeIteratorPtr nIt = smb->GetNodes();
-  const SMDS_MeshNode* node;
-  while ( nIt->more() ) {
-    node = nIt->next();
-    if(IsMedium(node, SMDSAbs_Edge))
-      continue;
-    const SMDS_EdgePosition* pos =
-      dynamic_cast<const SMDS_EdgePosition*>( node->GetPosition().get() );
-    if ( !pos ) {
-      return false;
+  const SMESHDS_SubMesh* faceSubMesh = 0;
+  if ( theProxyMesh )
+  {
+    faceSubMesh = theProxyMesh->GetSubMesh( theFace );
+    if ( !faceSubMesh ||
+         faceSubMesh->NbElements() == 0 ||
+         theProxyMesh->IsTemporary( faceSubMesh->GetElements()->next() ))
+    {
+      // can use a proxy sub-mesh with not temporary elements only
+      faceSubMesh = 0;
+      theProxyMesh = 0;
     }
-    double u = ( pos->GetUParameter() - f ) / range;
-    std::vector<const SMDS_MeshNode*> & nVec = theParam2ColumnMap[ u ];
-    nVec.resize( vsize, nullNode );
-    loadedNodes.insert( nVec[ 0 ] = node );
   }
-  if ( theParam2ColumnMap.size() != hsize ) {
-    RETURN_BAD_RESULT( "Wrong node positions on theBaseEdge" );
+  if ( !faceSubMesh )
+    faceSubMesh = theMesh->MeshElements( theFace );
+  if ( !faceSubMesh || faceSubMesh->NbElements() == 0 )
+    return false;
+
+  // get data of edges for normalization of params
+
+  vector< double > length;
+  double fullLen = 0;
+  list<TopoDS_Edge>::const_iterator edge;
+  {
+    for ( edge = theBaseSide.begin(); edge != theBaseSide.end(); ++edge )
+    {
+      double len = std::max( 1e-10, SMESH_Algo::EdgeLength( *edge ));
+      fullLen += len;
+      length.push_back( len );
+    }
   }
 
-  // load nodes from e1
+  // get nodes on theBaseEdge sorted by param on edge and initialize theParam2ColumnMap with them
+  edge = theBaseSide.begin();
+  for ( int iE = 0; edge != theBaseSide.end(); ++edge, ++iE )
+  {
+    map< double, const SMDS_MeshNode*> sortedBaseNodes;
+    SMESH_Algo::GetSortedNodesOnEdge( theMesh, *edge,/*noMedium=*/true, sortedBaseNodes);
+    if ( sortedBaseNodes.empty() ) continue;
 
-  std::map< double, const SMDS_MeshNode*> sortedNodes; // sort by param on edge
-  nIt = sm1->GetNodes();
-  while ( nIt->more() ) {
-    node = nIt->next();
-    if(IsMedium(node))
-      continue;
-    const SMDS_EdgePosition* pos =
-      dynamic_cast<const SMDS_EdgePosition*>( node->GetPosition().get() );
-    if ( !pos ) {
-      return false;
+    double f, l;
+    BRep_Tool::Range( *edge, f, l );
+    if ( edge->Orientation() == TopAbs_REVERSED ) std::swap( f, l );
+    const double coeff = 1. / ( l - f ) * length[iE] / fullLen;
+    const double prevPar = theParam2ColumnMap.empty() ? 0 : theParam2ColumnMap.rbegin()->first;
+    map< double, const SMDS_MeshNode*>::iterator u_n = sortedBaseNodes.begin();
+    for ( ; u_n != sortedBaseNodes.end(); u_n++ )
+    {
+      double par = prevPar + coeff * ( u_n->first - f );
+      TParam2ColumnMap::iterator u2nn =
+        theParam2ColumnMap.insert( theParam2ColumnMap.end(), make_pair( par, TNodeColumn()));
+      u2nn->second.push_back( u_n->second );
     }
-    sortedNodes.insert( std::make_pair( pos->GetUParameter(), node ));
-  }
-  loadedNodes.insert( nVecf[ vsize - 1 ] = smVft->GetNodes()->next() );
-  std::map< double, const SMDS_MeshNode*>::iterator u_n = sortedNodes.begin();
-  int row  = rev1 ? vsize - 1 : 0;
-  int dRow = rev1 ? -1 : +1;
-  for ( ; u_n != sortedNodes.end(); u_n++ ) {
-    row += dRow;
-    loadedNodes.insert( nVecf[ row ] = u_n->second );
-  }
-
-  // try to load the rest nodes
-
-  // get all faces from theFace
-  TIDSortedElemSet allFaces, foundFaces;
-  eIt = smFace->GetElements();
-  while ( eIt->more() ) {
-    const SMDS_MeshElement* e = eIt->next();
-    if ( e->GetType() == SMDSAbs_Face )
-      allFaces.insert( e );
-  }
-  // Starting from 2 neighbour nodes on theBaseEdge, look for a face
-  // the nodes belong to, and between the nodes of the found face,
-  // look for a not loaded node considering this node to be the next
-  // in a column of the starting second node. Repeat, starting
-  // from nodes next to the previous starting nodes in their columns,
-  // and so on while a face can be found. Then go the the next pair
-  // of nodes on theBaseEdge.
-  TParam2ColumnMap::iterator par_nVec_1 = theParam2ColumnMap.begin();
-  TParam2ColumnMap::iterator par_nVec_2 = par_nVec_1;
-  // loop on columns
-  int col = 0;
-  for ( par_nVec_2++; par_nVec_2 != theParam2ColumnMap.end(); par_nVec_1++, par_nVec_2++ ) {
-    col++;
-    row = 0;
-    const SMDS_MeshNode* n1 = par_nVec_1->second[ row ];
-    const SMDS_MeshNode* n2 = par_nVec_2->second[ row ];
-    const SMDS_MeshElement* face = 0;
-    bool lastColOnClosedFace = ( nVecf[ row ] == n2 );
-    do {
-      // look for a face by 2 nodes
-      face = SMESH_MeshEditor::FindFaceInSet( n1, n2, allFaces, foundFaces );
-      if ( face ) {
-        int nbFaceNodes = face->NbNodes();
-        if ( face->IsQuadratic() )
-          nbFaceNodes /= 2;
-        if ( nbFaceNodes>4 ) {
-          RETURN_BAD_RESULT(" Too many nodes in a face: " << nbFaceNodes );
-        }
-        // look for a not loaded node of the <face>
-        bool found = false;
-        const SMDS_MeshNode* n3 = 0; // a node defferent from n1 and n2
-        for ( int i = 0; i < nbFaceNodes && !found; ++i ) {
-          node = face->GetNode( i );
-          found = loadedNodes.insert( node ).second;
-          if ( !found && node != n1 && node != n2 )
-            n3 = node;
-        }
-        if ( lastColOnClosedFace && row + 1 < vsize ) {
-          node = nVecf[ row + 1 ];
-          found = ( face->GetNodeIndex( node ) >= 0 );
-        }
-        if ( found ) {
-          if ( ++row > vsize - 1 ) {
-            RETURN_BAD_RESULT( "Too many nodes in column "<< col <<": "<< row+1);
-          }
-          par_nVec_2->second[ row ] = node;
-          foundFaces.insert( face );
-          n2 = node;
-          if ( nbFaceNodes==4 ) {
-            n1 = par_nVec_1->second[ row ];
-          }
-        }
-        else if ( nbFaceNodes==3 && n3 == par_nVec_1->second[ row + 1 ] ) {
-          n1 = n3;
-        }
-        else  {
-          RETURN_BAD_RESULT( "Not quad mesh, column "<< col );
-        }
-      }
+  }
+  TParam2ColumnMap::iterator par_nVec_2, par_nVec_1 = theParam2ColumnMap.begin();
+  if ( theProxyMesh )
+  {
+    for ( ; par_nVec_1 != theParam2ColumnMap.end(); ++par_nVec_1 )
+    {
+      const SMDS_MeshNode* & n = par_nVec_1->second[0];
+      n = theProxyMesh->GetProxyNode( n );
     }
-    while ( face && n1 && n2 );
-
-    if ( row < vsize - 1 ) {
-      MESSAGE( "Too few nodes in column "<< col <<": "<< row+1);
-      MESSAGE( "Base node 1: "<< par_nVec_1->second[0]);
-      MESSAGE( "Base node 2: "<< par_nVec_2->second[0]);
-      if ( n1 ) { MESSAGE( "Current node 1: "<< n1); }
-      else      { MESSAGE( "Current node 1: NULL");  }
-      if ( n2 ) { MESSAGE( "Current node 2: "<< n2); }
-      else      { MESSAGE( "Current node 2: NULL");  }
-      MESSAGE( "first base node: "<< theParam2ColumnMap.begin()->second[0]);
-      MESSAGE( "last base node: "<< theParam2ColumnMap.rbegin()->second[0]);
-      return false;
+  }
+
+  int nbRows = 1 + faceSubMesh->NbElements() / ( theParam2ColumnMap.size()-1 );
+
+  // fill theParam2ColumnMap column by column by passing from nodes on
+  // theBaseEdge up via mesh faces on theFace
+
+  par_nVec_2 = theParam2ColumnMap.begin();
+  par_nVec_1 = par_nVec_2++;
+  TIDSortedElemSet emptySet, avoidSet;
+  for ( ; par_nVec_2 != theParam2ColumnMap.end(); ++par_nVec_1, ++par_nVec_2 )
+  {
+    vector<const SMDS_MeshNode*>& nCol1 = par_nVec_1->second;
+    vector<const SMDS_MeshNode*>& nCol2 = par_nVec_2->second;
+    nCol1.resize( nbRows );
+    nCol2.resize( nbRows );
+
+    int i1, i2, iRow = 0;
+    const SMDS_MeshNode *n1 = nCol1[0], *n2 = nCol2[0];
+    // find face sharing node n1 and n2 and belonging to faceSubMesh
+    while ( const SMDS_MeshElement* face =
+            SMESH_MeshEditor::FindFaceInSet( n1, n2, emptySet, avoidSet, &i1, &i2))
+    {
+      if ( faceSubMesh->Contains( face ))
+      {
+        int nbNodes = face->IsQuadratic() ? face->NbNodes()/2 : face->NbNodes();
+        if ( nbNodes != 4 )
+          return false;
+        n1 = face->GetNode( (i2+2) % 4 ); // opposite corner of quadrangle face
+        n2 = face->GetNode( (i1+2) % 4 );
+        if ( ++iRow >= nbRows )
+          return false;
+        nCol1[ iRow ] = n1;
+        nCol2[ iRow ] = n2;
+        avoidSet.clear();
+      }
+      avoidSet.insert( face );
     }
-  } // loop on columns
+    // set a real height
+    nCol1.resize( iRow + 1 );
+    nCol2.resize( iRow + 1 );
+  }
+  return theParam2ColumnMap.size() > 1 && theParam2ColumnMap.begin()->second.size() > 1;
+}
 
-  return true;
+//=======================================================================
+//function : NbAncestors
+//purpose  : Return number of unique ancestors of the shape
+//=======================================================================
+
+int SMESH_MesherHelper::NbAncestors(const TopoDS_Shape& shape,
+                                    const SMESH_Mesh&   mesh,
+                                    TopAbs_ShapeEnum    ancestorType/*=TopAbs_SHAPE*/)
+{
+  TopTools_MapOfShape ancestors;
+  TopTools_ListIteratorOfListOfShape ansIt( mesh.GetAncestors(shape) );
+  for ( ; ansIt.More(); ansIt.Next() ) {
+    if ( ancestorType == TopAbs_SHAPE || ansIt.Value().ShapeType() == ancestorType )
+      ancestors.Add( ansIt.Value() );
+  }
+  return ancestors.Extent();
+}
+
+//=======================================================================
+//function : GetSubShapeOri
+//purpose  : Return orientation of sub-shape in the main shape
+//=======================================================================
+
+TopAbs_Orientation SMESH_MesherHelper::GetSubShapeOri(const TopoDS_Shape& shape,
+                                                      const TopoDS_Shape& subShape)
+{
+  TopAbs_Orientation ori = TopAbs_Orientation(-1);
+  if ( !shape.IsNull() && !subShape.IsNull() )
+  {
+    TopExp_Explorer e( shape, subShape.ShapeType() );
+    if ( shape.Orientation() >= TopAbs_INTERNAL ) // TopAbs_INTERNAL or TopAbs_EXTERNAL
+      e.Init( shape.Oriented(TopAbs_FORWARD), subShape.ShapeType() );
+    for ( ; e.More(); e.Next())
+      if ( subShape.IsSame( e.Current() ))
+        break;
+    if ( e.More() )
+      ori = e.Current().Orientation();
+  }
+  return ori;
+}
+
+//=======================================================================
+//function : IsSubShape
+//purpose  : 
+//=======================================================================
+
+bool SMESH_MesherHelper::IsSubShape( const TopoDS_Shape& shape,
+                                     const TopoDS_Shape& mainShape )
+{
+  if ( !shape.IsNull() && !mainShape.IsNull() )
+  {
+    for ( TopExp_Explorer exp( mainShape, shape.ShapeType());
+          exp.More();
+          exp.Next() )
+      if ( shape.IsSame( exp.Current() ))
+        return true;
+  }
+  SCRUTE((shape.IsNull()));
+  SCRUTE((mainShape.IsNull()));
+  return false;
 }
 
 //=======================================================================
-/**
- * Check mesh without geometry for: if all elements on this shape are quadratic,
- * quadratic elements will be created.
- * Used then generated 3D mesh without geometry.
+//function : IsSubShape
+//purpose  : 
+//=======================================================================
+
+bool SMESH_MesherHelper::IsSubShape( const TopoDS_Shape& shape, SMESH_Mesh* aMesh )
+{
+  if ( shape.IsNull() || !aMesh )
+    return false;
+  return
+    aMesh->GetMeshDS()->ShapeToIndex( shape ) ||
+    // PAL16202
+    (shape.ShapeType() == TopAbs_COMPOUND && aMesh->GetMeshDS()->IsGroupOfSubShapes( shape ));
+}
+
+//================================================================================
+/*!
+ * \brief Return maximal tolerance of shape
+ */
+//================================================================================
+
+double SMESH_MesherHelper::MaxTolerance( const TopoDS_Shape& shape )
+{
+  double tol = Precision::Confusion();
+  TopExp_Explorer exp;
+  for ( exp.Init( shape, TopAbs_FACE ); exp.More(); exp.Next() )
+    tol = Max( tol, BRep_Tool::Tolerance( TopoDS::Face( exp.Current())));
+  for ( exp.Init( shape, TopAbs_EDGE ); exp.More(); exp.Next() )
+    tol = Max( tol, BRep_Tool::Tolerance( TopoDS::Edge( exp.Current())));
+  for ( exp.Init( shape, TopAbs_VERTEX ); exp.More(); exp.Next() )
+    tol = Max( tol, BRep_Tool::Tolerance( TopoDS::Vertex( exp.Current())));
+
+  return tol;
+}
+
+//================================================================================
+/*!
+ * \brief Check if the first and last vertices of an edge are the same
+ * \param anEdge - the edge to check
+ * \retval bool - true if same
+ */
+//================================================================================
+
+bool SMESH_MesherHelper::IsClosedEdge( const TopoDS_Edge& anEdge )
+{
+  if ( anEdge.Orientation() >= TopAbs_INTERNAL )
+    return IsClosedEdge( TopoDS::Edge( anEdge.Oriented( TopAbs_FORWARD )));
+  return TopExp::FirstVertex( anEdge ).IsSame( TopExp::LastVertex( anEdge ));
+}
+
+//================================================================================
+/*!
+ * \brief Wrapper over TopExp::FirstVertex() and TopExp::LastVertex() fixing them
+ *  in the case of INTERNAL edge
  */
+//================================================================================
+
+TopoDS_Vertex SMESH_MesherHelper::IthVertex( const bool  is2nd,
+                                             TopoDS_Edge anEdge,
+                                             const bool  CumOri )
+{
+  if ( anEdge.Orientation() >= TopAbs_INTERNAL )
+    anEdge.Orientation( TopAbs_FORWARD );
+
+  const TopAbs_Orientation tgtOri = is2nd ? TopAbs_REVERSED : TopAbs_FORWARD;
+  TopoDS_Iterator vIt( anEdge, CumOri );
+  while ( vIt.More() && vIt.Value().Orientation() != tgtOri )
+    vIt.Next();
+
+  return ( vIt.More() ? TopoDS::Vertex(vIt.Value()) : TopoDS_Vertex() );
+}
+
+//=======================================================================
+//function : IsQuadraticMesh
+//purpose  : Check mesh without geometry for: if all elements on this shape are quadratic,
+//           quadratic elements will be created.
+//           Used then generated 3D mesh without geometry.
 //=======================================================================
 
 SMESH_MesherHelper:: MType SMESH_MesherHelper::IsQuadraticMesh()
@@ -1184,13 +1981,1520 @@ SMESH_MesherHelper:: MType SMESH_MesherHelper::IsQuadraticMesh()
     return SMESH_MesherHelper::COMP;
 }
 
+//=======================================================================
+//function : GetOtherParam
+//purpose  : Return an alternative parameter for a node on seam
+//=======================================================================
+
+double SMESH_MesherHelper::GetOtherParam(const double param) const
+{
+  int i = myParIndex & U_periodic ? 0 : 1;
+  return fabs(param-myPar1[i]) < fabs(param-myPar2[i]) ? myPar2[i] : myPar1[i];
+}
+
+namespace {
+
+  //=======================================================================
+  /*!
+   * \brief Iterator on ancestors of the given type
+   */
+  //=======================================================================
+
+  struct TAncestorsIterator : public SMDS_Iterator<const TopoDS_Shape*>
+  {
+    TopTools_ListIteratorOfListOfShape _ancIter;
+    TopAbs_ShapeEnum                   _type;
+    TopTools_MapOfShape                _encountered;
+    TAncestorsIterator( const TopTools_ListOfShape& ancestors, TopAbs_ShapeEnum type)
+      : _ancIter( ancestors ), _type( type )
+    {
+      if ( _ancIter.More() ) {
+        if ( _ancIter.Value().ShapeType() != _type ) next();
+        else _encountered.Add( _ancIter.Value() );
+      }
+    }
+    virtual bool more()
+    {
+      return _ancIter.More();
+    }
+    virtual const TopoDS_Shape* next()
+    {
+      const TopoDS_Shape* s = _ancIter.More() ? & _ancIter.Value() : 0;
+      if ( _ancIter.More() )
+        for ( _ancIter.Next();  _ancIter.More(); _ancIter.Next())
+          if ( _ancIter.Value().ShapeType() == _type && _encountered.Add( _ancIter.Value() ))
+            break;
+      return s;
+    }
+  };
+
+} // namespace
+
 //=======================================================================
 /*!
- * \brief Return an alternative parameter for a node on seam
+ * \brief Return iterator on ancestors of the given type
  */
 //=======================================================================
 
-double SMESH_MesherHelper::GetOtherParam(const double param) const
+PShapeIteratorPtr SMESH_MesherHelper::GetAncestors(const TopoDS_Shape& shape,
+                                                   const SMESH_Mesh&   mesh,
+                                                   TopAbs_ShapeEnum    ancestorType)
+{
+  return PShapeIteratorPtr( new TAncestorsIterator( mesh.GetAncestors(shape), ancestorType));
+}
+
+//=======================================================================
+//function : GetCommonAncestor
+//purpose  : Find a common ancestors of two shapes of the given type
+//=======================================================================
+
+TopoDS_Shape SMESH_MesherHelper::GetCommonAncestor(const TopoDS_Shape& shape1,
+                                                   const TopoDS_Shape& shape2,
+                                                   const SMESH_Mesh&   mesh,
+                                                   TopAbs_ShapeEnum    ancestorType)
 {
-  return fabs(param-myPar1) < fabs(param-myPar2) ? myPar2 : myPar1;
+  TopoDS_Shape commonAnc;
+  if ( !shape1.IsNull() && !shape2.IsNull() )
+  {
+    PShapeIteratorPtr ancIt = GetAncestors( shape1, mesh, ancestorType );
+    while ( const TopoDS_Shape* anc = ancIt->next() )
+      if ( IsSubShape( shape2, *anc ))
+      {
+        commonAnc = *anc;
+        break;
+      }
+  }
+  return commonAnc;
 }
+
+//#include <Perf_Meter.hxx>
+
+//=======================================================================
+namespace { // Structures used by FixQuadraticElements()
+//=======================================================================
+
+#define __DMP__(txt) \
+  //cout << txt
+#define MSG(txt) __DMP__(txt<<endl)
+#define MSGBEG(txt) __DMP__(txt)
+
+  //const double straightTol2 = 1e-33; // to detect straing links
+  bool isStraightLink(double linkLen2, double middleNodeMove2)
+  {
+    // straight if <node move> < 1/15 * <link length>
+    return middleNodeMove2 < 1/15./15. * linkLen2;
+  }
+
+  struct QFace;
+  // ---------------------------------------
+  /*!
+   * \brief Quadratic link knowing its faces
+   */
+  struct QLink: public SMESH_TLink
+  {
+    const SMDS_MeshNode*          _mediumNode;
+    mutable vector<const QFace* > _faces;
+    mutable gp_Vec                _nodeMove;
+    mutable int                   _nbMoves;
+
+    QLink(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2, const SMDS_MeshNode* nm):
+      SMESH_TLink( n1,n2 ), _mediumNode(nm), _nodeMove(0,0,0), _nbMoves(0) {
+      _faces.reserve(4);
+      //if ( MediumPos() != SMDS_TOP_3DSPACE )
+        _nodeMove = MediumPnt() - MiddlePnt();
+    }
+    void SetContinuesFaces() const;
+    const QFace* GetContinuesFace( const QFace* face ) const;
+    bool OnBoundary() const;
+    gp_XYZ MiddlePnt() const { return ( XYZ( node1() ) + XYZ( node2() )) / 2.; }
+    gp_XYZ MediumPnt() const { return XYZ( _mediumNode ); }
+
+    SMDS_TypeOfPosition MediumPos() const
+    { return _mediumNode->GetPosition()->GetTypeOfPosition(); }
+    SMDS_TypeOfPosition EndPos(bool isSecond) const
+    { return (isSecond ? node2() : node1())->GetPosition()->GetTypeOfPosition(); }
+    const SMDS_MeshNode* EndPosNode(SMDS_TypeOfPosition pos) const
+    { return EndPos(0) == pos ? node1() : EndPos(1) == pos ? node2() : 0; }
+
+    void Move(const gp_Vec& move, bool sum=false) const
+    { _nodeMove += move; _nbMoves += sum ? (_nbMoves==0) : 1; }
+    gp_XYZ Move() const { return _nodeMove.XYZ() / _nbMoves; }
+    bool IsMoved() const { return (_nbMoves > 0 /*&& !IsStraight()*/); }
+    bool IsStraight() const
+    { return isStraightLink( (XYZ(node1())-XYZ(node2())).SquareModulus(),
+                             _nodeMove.SquareMagnitude());
+    }
+    bool operator<(const QLink& other) const {
+      return (node1()->GetID() == other.node1()->GetID() ?
+              node2()->GetID() < other.node2()->GetID() :
+              node1()->GetID() < other.node1()->GetID());
+    }
+//     struct PtrComparator {
+//       bool operator() (const QLink* l1, const QLink* l2 ) const { return *l1 < *l2; }
+//     };
+  };
+  // ---------------------------------------------------------
+  /*!
+   * \brief Link in the chain of links; it connects two faces
+   */
+  struct TChainLink
+  {
+    const QLink*         _qlink;
+    mutable const QFace* _qfaces[2];
+
+    TChainLink(const QLink* qlink=0):_qlink(qlink) {
+      _qfaces[0] = _qfaces[1] = 0;
+    }
+    void SetFace(const QFace* face) const { int iF = _qfaces[0] ? 1 : 0; _qfaces[iF]=face; }
+
+    bool IsBoundary() const { return !_qfaces[1]; }
+
+    void RemoveFace( const QFace* face ) const
+    { _qfaces[(face == _qfaces[1])] = 0; if (!_qfaces[0]) std::swap(_qfaces[0],_qfaces[1]); }
+
+    const QFace* NextFace( const QFace* f ) const
+    { return _qfaces[0]==f ? _qfaces[1] : _qfaces[0]; }
+
+    const SMDS_MeshNode* NextNode( const SMDS_MeshNode* n ) const
+    { return n == _qlink->node1() ? _qlink->node2() : _qlink->node1(); }
+
+    bool operator<(const TChainLink& other) const { return *_qlink < *other._qlink; }
+
+    operator bool() const { return (_qlink); }
+
+    const QLink* operator->() const { return _qlink; }
+
+    gp_Vec Normal() const;
+
+    bool IsStraight() const;
+  };
+  // --------------------------------------------------------------------
+  typedef list< TChainLink > TChain;
+  typedef set < TChainLink > TLinkSet;
+  typedef TLinkSet::const_iterator TLinkInSet;
+
+  const int theFirstStep = 5;
+
+  enum { ERR_OK, ERR_TRI, ERR_PRISM, ERR_UNKNOWN }; // errors of QFace::GetLinkChain()
+  // --------------------------------------------------------------------
+  /*!
+   * \brief Face shared by two volumes and bound by QLinks
+   */
+  struct QFace: public TIDSortedNodeSet
+  {
+    mutable const SMDS_MeshElement* _volumes[2];
+    mutable vector< const QLink* >  _sides;
+    mutable bool                    _sideIsAdded[4]; // added in chain of links
+    gp_Vec                          _normal;
+#ifdef _DEBUG_
+    mutable const SMDS_MeshElement* _face;
+#endif
+
+    QFace( const vector< const QLink*>& links, const SMDS_MeshElement* face=0 );
+
+    void SetVolume(const SMDS_MeshElement* v) const { _volumes[ _volumes[0] ? 1 : 0 ] = v; }
+
+    int NbVolumes() const { return !_volumes[0] ? 0 : !_volumes[1] ? 1 : 2; }
+
+    void AddSelfToLinks() const {
+      for ( int i = 0; i < _sides.size(); ++i )
+        _sides[i]->_faces.push_back( this );
+    }
+    int LinkIndex( const QLink* side ) const {
+      for (int i=0; i<_sides.size(); ++i ) if ( _sides[i] == side ) return i;
+      return -1;
+    }
+    bool GetLinkChain( int iSide, TChain& chain, SMDS_TypeOfPosition pos, int& err) const;
+
+    bool GetLinkChain( TChainLink& link, TChain& chain, SMDS_TypeOfPosition pos, int& err) const
+    {
+      int i = LinkIndex( link._qlink );
+      if ( i < 0 ) return true;
+      _sideIsAdded[i] = true;
+      link.SetFace( this );
+      // continue from opposite link
+      return GetLinkChain( (i+2)%_sides.size(), chain, pos, err );
+    }
+    bool IsBoundary() const { return !_volumes[1]; }
+
+    bool Contains( const SMDS_MeshNode* node ) const { return count(node); }
+
+    bool IsSpoiled(const QLink* bentLink ) const;
+
+    TLinkInSet GetBoundaryLink( const TLinkSet&      links,
+                                const TChainLink&    avoidLink,
+                                TLinkInSet *         notBoundaryLink = 0,
+                                const SMDS_MeshNode* nodeToContain = 0,
+                                bool *               isAdjacentUsed = 0,
+                                int                  nbRecursionsLeft = -1) const;
+
+    TLinkInSet GetLinkByNode( const TLinkSet&      links,
+                              const TChainLink&    avoidLink,
+                              const SMDS_MeshNode* nodeToContain) const;
+
+    const SMDS_MeshNode* GetNodeInFace() const {
+      for ( int iL = 0; iL < _sides.size(); ++iL )
+        if ( _sides[iL]->MediumPos() == SMDS_TOP_FACE ) return _sides[iL]->_mediumNode;
+      return 0;
+    }
+
+    gp_Vec LinkNorm(const int i, SMESH_MesherHelper* theFaceHelper=0) const;
+
+    double MoveByBoundary( const TChainLink&   theLink,
+                           const gp_Vec&       theRefVec,
+                           const TLinkSet&     theLinks,
+                           SMESH_MesherHelper* theFaceHelper=0,
+                           const double        thePrevLen=0,
+                           const int           theStep=theFirstStep,
+                           gp_Vec*             theLinkNorm=0,
+                           double              theSign=1.0) const;
+  };
+
+  //================================================================================
+  /*!
+   * \brief Dump QLink and QFace
+   */
+  ostream& operator << (ostream& out, const QLink& l)
+  {
+    out <<"QLink nodes: "
+        << l.node1()->GetID() << " - "
+        << l._mediumNode->GetID() << " - "
+        << l.node2()->GetID() << endl;
+    return out;
+  }
+  ostream& operator << (ostream& out, const QFace& f)
+  {
+    out <<"QFace nodes: "/*<< &f << "  "*/;
+    for ( TIDSortedNodeSet::const_iterator n = f.begin(); n != f.end(); ++n )
+      out << (*n)->GetID() << " ";
+    out << " \tvolumes: "
+        << (f._volumes[0] ? f._volumes[0]->GetID() : 0) << " "
+        << (f._volumes[1] ? f._volumes[1]->GetID() : 0);
+    out << "  \tNormal: "<< f._normal.X() <<", "<<f._normal.Y() <<", "<<f._normal.Z() << endl;
+    return out;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Construct QFace from QLinks 
+   */
+  //================================================================================
+
+  QFace::QFace( const vector< const QLink*>& links, const SMDS_MeshElement* face )
+  {
+    _volumes[0] = _volumes[1] = 0;
+    _sides = links;
+    _sideIsAdded[0]=_sideIsAdded[1]=_sideIsAdded[2]=_sideIsAdded[3]=false;
+    _normal.SetCoord(0,0,0);
+    for ( int i = 1; i < _sides.size(); ++i ) {
+      const QLink *l1 = _sides[i-1], *l2 = _sides[i];
+      insert( l1->node1() ); insert( l1->node2() );
+      // compute normal
+      gp_Vec v1( XYZ( l1->node2()), XYZ( l1->node1()));
+      gp_Vec v2( XYZ( l2->node1()), XYZ( l2->node2()));
+      if ( l1->node1() != l2->node1() && l1->node2() != l2->node2() )
+        v1.Reverse(); 
+      _normal += v1 ^ v2;
+    }
+    double normSqSize = _normal.SquareMagnitude();
+    if ( normSqSize > numeric_limits<double>::min() )
+      _normal /= sqrt( normSqSize );
+    else
+      _normal.SetCoord(1e-33,0,0);
+
+#ifdef _DEBUG_
+    _face = face;
+#endif
+  }
+  //================================================================================
+  /*!
+   * \brief Make up a chain of links
+   *  \param iSide - link to add first
+   *  \param chain - chain to fill in
+   *  \param pos   - postion of medium nodes the links should have
+   *  \param error - out, specifies what is wrong
+   *  \retval bool - false if valid chain can't be built; "valid" means that links
+   *                 of the chain belongs to rectangles bounding hexahedrons
+   */
+  //================================================================================
+
+  bool QFace::GetLinkChain( int iSide, TChain& chain, SMDS_TypeOfPosition pos, int& error) const
+  {
+    if ( iSide >= _sides.size() ) // wrong argument iSide
+      return false;
+    if ( _sideIsAdded[ iSide ]) // already in chain
+      return true;
+
+    if ( _sides.size() != 4 ) { // triangle - visit all my continous faces
+      MSGBEG( *this );
+      TLinkSet links;
+      list< const QFace* > faces( 1, this );
+      while ( !faces.empty() ) {
+        const QFace* face = faces.front();
+        for ( int i = 0; i < face->_sides.size(); ++i ) {
+          if ( !face->_sideIsAdded[i] && face->_sides[i] ) {
+            face->_sideIsAdded[i] = true;
+            // find a face side in the chain
+            TLinkInSet chLink = links.insert( TChainLink(face->_sides[i])).first;
+//             TChain::iterator chLink = chain.begin();
+//             for ( ; chLink != chain.end(); ++chLink )
+//               if ( chLink->_qlink == face->_sides[i] )
+//                 break;
+//             if ( chLink == chain.end() )
+//               chLink = chain.insert( chain.begin(), TChainLink(face->_sides[i]));
+            // add a face to a chained link and put a continues face in the queue
+            chLink->SetFace( face );
+            if ( face->_sides[i]->MediumPos() == pos )
+              if ( const QFace* contFace = face->_sides[i]->GetContinuesFace( face ))
+                if ( contFace->_sides.size() == 3 )
+                  faces.push_back( contFace );
+          }
+        }
+        faces.pop_front();
+      }
+      if ( error < ERR_TRI )
+        error = ERR_TRI;
+      chain.insert( chain.end(), links.begin(),links.end() );
+      return false;
+    }
+    _sideIsAdded[iSide] = true; // not to add this link to chain again
+    const QLink* link = _sides[iSide];
+    if ( !link)
+      return true;
+
+    // add link into chain
+    TChain::iterator chLink = chain.insert( chain.begin(), TChainLink(link));
+    chLink->SetFace( this );
+    MSGBEG( *this );
+
+    // propagate from quadrangle to neighbour faces
+    if ( link->MediumPos() >= pos ) {
+      int nbLinkFaces = link->_faces.size();
+      if ( nbLinkFaces == 4 || (/*nbLinkFaces < 4 && */link->OnBoundary())) {
+        // hexahedral mesh or boundary quadrangles - goto a continous face
+        if ( const QFace* f = link->GetContinuesFace( this ))
+          if ( f->_sides.size() == 4 )
+            return f->GetLinkChain( *chLink, chain, pos, error );
+      }
+      else {
+        TChainLink chLink(link); // side face of prismatic mesh - visit all faces of iSide
+        for ( int i = 0; i < nbLinkFaces; ++i )
+          if ( link->_faces[i] )
+            link->_faces[i]->GetLinkChain( chLink, chain, pos, error );
+        if ( error < ERR_PRISM )
+          error = ERR_PRISM;
+        return false;
+      }
+    }
+    return true;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Return a boundary link of the triangle face
+   *  \param links - set of all links
+   *  \param avoidLink - link not to return
+   *  \param notBoundaryLink - out, neither the returned link nor avoidLink
+   *  \param nodeToContain - node the returned link must contain; if provided, search
+   *                         also performed on adjacent faces
+   *  \param isAdjacentUsed - returns true if link is found in adjacent faces
+   *  \param nbRecursionsLeft - to limit recursion
+   */
+  //================================================================================
+
+  TLinkInSet QFace::GetBoundaryLink( const TLinkSet&      links,
+                                     const TChainLink&    avoidLink,
+                                     TLinkInSet *         notBoundaryLink,
+                                     const SMDS_MeshNode* nodeToContain,
+                                     bool *               isAdjacentUsed,
+                                     int                  nbRecursionsLeft) const
+  {
+    TLinkInSet linksEnd = links.end(), boundaryLink = linksEnd;
+
+    typedef list< pair< const QFace*, TLinkInSet > > TFaceLinkList;
+    TFaceLinkList adjacentFaces;
+
+    for ( int iL = 0; iL < _sides.size(); ++iL )
+    {
+      if ( avoidLink._qlink == _sides[iL] )
+        continue;
+      TLinkInSet link = links.find( _sides[iL] );
+      if ( link == linksEnd ) continue;
+      if ( (*link)->MediumPos() > SMDS_TOP_FACE )
+        continue; // We work on faces here, don't go inside a solid
+
+      // check link
+      if ( link->IsBoundary() ) {
+        if ( !nodeToContain ||
+             (*link)->node1() == nodeToContain ||
+             (*link)->node2() == nodeToContain )
+        {
+          boundaryLink = link;
+          if ( !notBoundaryLink ) break;
+        }
+      }
+      else if ( notBoundaryLink ) {
+        *notBoundaryLink = link;
+        if ( boundaryLink != linksEnd ) break;
+      }
+
+      if ( boundaryLink == linksEnd && nodeToContain ) // collect adjacent faces
+        if ( const QFace* adj = link->NextFace( this ))
+          if ( adj->Contains( nodeToContain ))
+            adjacentFaces.push_back( make_pair( adj, link ));
+    }
+
+    if ( isAdjacentUsed ) *isAdjacentUsed = false;
+    if ( boundaryLink == linksEnd && nodeToContain && nbRecursionsLeft) // check adjacent faces
+    {
+      if ( nbRecursionsLeft < 0 )
+        nbRecursionsLeft = nodeToContain->NbInverseElements();
+      TFaceLinkList::iterator adj = adjacentFaces.begin();
+      for ( ; boundaryLink == linksEnd && adj != adjacentFaces.end(); ++adj )
+        boundaryLink = adj->first->GetBoundaryLink( links, *(adj->second), 0, nodeToContain,
+                                                    isAdjacentUsed, nbRecursionsLeft-1);
+      if ( isAdjacentUsed ) *isAdjacentUsed = true;
+    }
+    return boundaryLink;
+  }
+  //================================================================================
+  /*!
+   * \brief Return a link ending at the given node but not avoidLink
+   */
+  //================================================================================
+
+  TLinkInSet QFace::GetLinkByNode( const TLinkSet&      links,
+                                   const TChainLink&    avoidLink,
+                                   const SMDS_MeshNode* nodeToContain) const
+  {
+    for ( int i = 0; i < _sides.size(); ++i )
+      if ( avoidLink._qlink != _sides[i] &&
+           (_sides[i]->node1() == nodeToContain || _sides[i]->node2() == nodeToContain ))
+        return links.find( _sides[ i ]);
+    return links.end();
+  }
+
+  //================================================================================
+  /*!
+   * \brief Return normal to the i-th side pointing outside the face
+   */
+  //================================================================================
+
+  gp_Vec QFace::LinkNorm(const int i, SMESH_MesherHelper* /*uvHelper*/) const
+  {
+    gp_Vec norm, vecOut;
+//     if ( uvHelper ) {
+//       TopoDS_Face face = TopoDS::Face( uvHelper->GetSubShape());
+//       const SMDS_MeshNode* inFaceNode = uvHelper->GetNodeUVneedInFaceNode() ? GetNodeInFace() : 0;
+//       gp_XY uv1 = uvHelper->GetNodeUV( face, _sides[i]->node1(), inFaceNode );
+//       gp_XY uv2 = uvHelper->GetNodeUV( face, _sides[i]->node2(), inFaceNode );
+//       norm.SetCoord( uv1.Y() - uv2.Y(), uv2.X() - uv1.X(), 0 );
+
+//       const QLink* otherLink = _sides[(i + 1) % _sides.size()];
+//       const SMDS_MeshNode* otherNode =
+//         otherLink->node1() == _sides[i]->node1() ? otherLink->node2() : otherLink->node1();
+//       gp_XY pIn = uvHelper->GetNodeUV( face, otherNode, inFaceNode );
+//       vecOut.SetCoord( uv1.X() - pIn.X(), uv1.Y() - pIn.Y(), 0 );
+//     }
+//     else {
+      norm = _normal ^ gp_Vec( XYZ(_sides[i]->node1()), XYZ(_sides[i]->node2()));
+      gp_XYZ pIn = ( XYZ( _sides[0]->node1() ) +
+                     XYZ( _sides[0]->node2() ) +
+                     XYZ( _sides[1]->node1() )) / 3.;
+      vecOut.SetXYZ( _sides[i]->MiddlePnt() - pIn );
+      //}
+    if ( norm * vecOut < 0 )
+      norm.Reverse();
+    double mag2 = norm.SquareMagnitude();
+    if ( mag2 > numeric_limits<double>::min() )
+      norm /= sqrt( mag2 );
+    return norm;
+  }
+  //================================================================================
+  /*!
+   * \brief Move medium node of theLink according to its distance from boundary
+   *  \param theLink - link to fix
+   *  \param theRefVec - movement of boundary
+   *  \param theLinks - all adjacent links of continous triangles
+   *  \param theFaceHelper - helper is not used so far
+   *  \param thePrevLen - distance from the boundary
+   *  \param theStep - number of steps till movement propagation limit
+   *  \param theLinkNorm - out normal to theLink
+   *  \param theSign - 1 or -1 depending on movement of boundary
+   *  \retval double - distance from boundary to propagation limit or other boundary
+   */
+  //================================================================================
+
+  double QFace::MoveByBoundary( const TChainLink&   theLink,
+                                const gp_Vec&       theRefVec,
+                                const TLinkSet&     theLinks,
+                                SMESH_MesherHelper* theFaceHelper,
+                                const double        thePrevLen,
+                                const int           theStep,
+                                gp_Vec*             theLinkNorm,
+                                double              theSign) const
+  {
+    if ( !theStep )
+      return thePrevLen; // propagation limit reached
+
+    int iL; // index of theLink
+    for ( iL = 0; iL < _sides.size(); ++iL )
+      if ( theLink._qlink == _sides[ iL ])
+        break;
+
+    MSG(string(theStep,'.')<<" Ref( "<<theRefVec.X()<<","<<theRefVec.Y()<<","<<theRefVec.Z()<<" )"
+        <<" thePrevLen " << thePrevLen);
+    MSG(string(theStep,'.')<<" "<<*theLink._qlink);
+
+    gp_Vec linkNorm = -LinkNorm( iL/*, theFaceHelper*/ ); // normal to theLink
+    double refProj = theRefVec * linkNorm; // project movement vector to normal of theLink
+    if ( theStep == theFirstStep )
+      theSign = refProj < 0. ? -1. : 1.;
+    else if ( theSign * refProj < 0.4 * theRefVec.Magnitude())
+      return thePrevLen; // to propagate movement forward only, not in side dir or backward
+
+    int iL1 = (iL + 1) % 3, iL2 = (iL + 2) % 3; // indices of the two other links of triangle
+    TLinkInSet link1 = theLinks.find( _sides[iL1] );
+    TLinkInSet link2 = theLinks.find( _sides[iL2] );
+    if ( link1 == theLinks.end() || link2 == theLinks.end() )
+      return thePrevLen;
+    const QFace* f1 = link1->NextFace( this ); // adjacent faces
+    const QFace* f2 = link2->NextFace( this );
+
+    // propagate to adjacent faces till limit step or boundary
+    double len1 = thePrevLen + (theLink->MiddlePnt() - _sides[iL1]->MiddlePnt()).Modulus();
+    double len2 = thePrevLen + (theLink->MiddlePnt() - _sides[iL2]->MiddlePnt()).Modulus();
+    gp_Vec linkDir1(0,0,0); // initialize to avoid valgrind error ("Conditional jump...")
+    gp_Vec linkDir2(0,0,0);
+    try {
+      OCC_CATCH_SIGNALS;
+      if ( f1 && theLink->MediumPos() <= (*link1)->MediumPos() )
+        len1 = f1->MoveByBoundary
+          ( *link1, theRefVec, theLinks, theFaceHelper, len1, theStep-1, &linkDir1, theSign);
+      else
+        linkDir1 = LinkNorm( iL1/*, theFaceHelper*/ );
+    } catch (...) {
+      MSG( " --------------- EXCEPTION");
+      return thePrevLen;
+    }
+    try {
+      OCC_CATCH_SIGNALS;
+      if ( f2 && theLink->MediumPos() <= (*link2)->MediumPos() )
+        len2 = f2->MoveByBoundary
+          ( *link2, theRefVec, theLinks, theFaceHelper, len2, theStep-1, &linkDir2, theSign);
+      else
+        linkDir2 = LinkNorm( iL2/*, theFaceHelper*/ );
+    } catch (...) {
+      MSG( " --------------- EXCEPTION");
+      return thePrevLen;
+    }
+
+    double fullLen = 0;
+    if ( theStep != theFirstStep )
+    {
+      // choose chain length by direction of propagation most codirected with theRefVec
+      bool choose1 = ( theRefVec * linkDir1 * theSign > theRefVec * linkDir2 * theSign );
+      fullLen = choose1 ? len1 : len2;
+      double r = thePrevLen / fullLen;
+
+      gp_Vec move = linkNorm * refProj * ( 1 - r );
+      theLink->Move( move, true );
+
+      MSG(string(theStep,'.')<<" Move "<< theLink->_mediumNode->GetID()<<
+          " by " << refProj * ( 1 - r ) << " following " <<
+          (choose1 ? *link1->_qlink : *link2->_qlink));
+
+      if ( theLinkNorm ) *theLinkNorm = linkNorm;
+    }
+    return fullLen;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Checks if the face is distorted due to bentLink
+   */
+  //================================================================================
+
+  bool QFace::IsSpoiled(const QLink* bentLink ) const
+  {
+    // code is valid for convex faces only
+    gp_XYZ gc(0,0,0);
+    for ( TIDSortedNodeSet::const_iterator n = begin(); n!=end(); ++n)
+      gc += XYZ( *n ) / size();
+    for (unsigned i = 0; i < _sides.size(); ++i )
+    {
+      if ( _sides[i] == bentLink ) continue;
+      gp_Vec linkNorm = _normal ^ gp_Vec( XYZ(_sides[i]->node1()), XYZ(_sides[i]->node2()));
+      gp_Vec vecOut( gc, _sides[i]->MiddlePnt() );
+      if ( linkNorm * vecOut < 0 )
+        linkNorm.Reverse();
+      double mag2 = linkNorm.SquareMagnitude();
+      if ( mag2 > numeric_limits<double>::min() )
+        linkNorm /= sqrt( mag2 );
+      gp_Vec vecBent    ( _sides[i]->MiddlePnt(), bentLink->MediumPnt());
+      gp_Vec vecStraight( _sides[i]->MiddlePnt(), bentLink->MiddlePnt());
+      if ( vecBent * linkNorm > -0.1*vecStraight.Magnitude() )
+        return true;
+    }
+    return false;
+    
+  }
+
+  //================================================================================
+  /*!
+   * \brief Find pairs of continues faces 
+   */
+  //================================================================================
+
+  void QLink::SetContinuesFaces() const
+  {
+    //       x0         x - QLink, [-|] - QFace, v - volume
+    //   v0  |   v1   
+    //       |          Between _faces of link x2 two vertical faces are continues
+    // x1----x2-----x3  and two horizontal faces are continues. We set vertical faces
+    //       |          to _faces[0] and _faces[1] and horizontal faces to
+    //   v2  |   v3     _faces[2] and _faces[3] (or vise versa).
+    //       x4
+
+    if ( _faces.empty() )
+      return;
+    int iFaceCont = -1, nbBoundary = 0, iBoundary[2]={-1,-1};
+    if ( _faces[0]->IsBoundary() )
+      iBoundary[ nbBoundary++ ] = 0;
+    for ( int iF = 1; iFaceCont < 0 && iF < _faces.size(); ++iF )
+    {
+      // look for a face bounding none of volumes bound by _faces[0]
+      bool sameVol = false;
+      int nbVol = _faces[iF]->NbVolumes();
+      for ( int iV = 0; !sameVol && iV < nbVol; ++iV )
+        sameVol = ( _faces[iF]->_volumes[iV] == _faces[0]->_volumes[0] ||
+                    _faces[iF]->_volumes[iV] == _faces[0]->_volumes[1]);
+      if ( !sameVol )
+        iFaceCont = iF;
+      if ( _faces[iF]->IsBoundary() )
+        iBoundary[ nbBoundary++ ] = iF;
+    }
+    // Set continues faces: arrange _faces to have
+    // _faces[0] continues to _faces[1]
+    // _faces[2] continues to _faces[3]
+    if ( nbBoundary == 2 ) // bnd faces are continues
+    {
+      if (( iBoundary[0] < 2 ) != ( iBoundary[1] < 2 ))
+      {
+        int iNear0 = iBoundary[0] < 2 ? 1-iBoundary[0] : 5-iBoundary[0];
+        std::swap( _faces[ iBoundary[1] ], _faces[iNear0] );
+      }
+    }
+    else if ( iFaceCont > 0 ) // continues faces found
+    {
+      if ( iFaceCont != 1 )
+        std::swap( _faces[1], _faces[iFaceCont] );
+    }
+    else if ( _faces.size() > 1 ) // not found, set NULL by the first face
+    {
+      _faces.insert( ++_faces.begin(), 0 );
+    }
+  }
+  //================================================================================
+  /*!
+   * \brief Return a face continues to the given one
+   */
+  //================================================================================
+
+  const QFace* QLink::GetContinuesFace( const QFace* face ) const
+  {
+    for ( int i = 0; i < _faces.size(); ++i ) {
+      if ( _faces[i] == face ) {
+        int iF = i < 2 ? 1-i : 5-i;
+        return iF < _faces.size() ? _faces[iF] : 0;
+      }
+    }
+    return 0;
+  }
+  //================================================================================
+  /*!
+   * \brief True if link is on mesh boundary
+   */
+  //================================================================================
+
+  bool QLink::OnBoundary() const
+  {
+    for ( int i = 0; i < _faces.size(); ++i )
+      if (_faces[i] && _faces[i]->IsBoundary()) return true;
+    return false;
+  }
+  //================================================================================
+  /*!
+   * \brief Return normal of link of the chain
+   */
+  //================================================================================
+
+  gp_Vec TChainLink::Normal() const {
+    gp_Vec norm;
+    if (_qfaces[0]) norm  = _qfaces[0]->_normal;
+    if (_qfaces[1]) norm += _qfaces[1]->_normal;
+    return norm;
+  }
+  //================================================================================
+  /*!
+   * \brief Test link curvature taking into account size of faces
+   */
+  //================================================================================
+
+  bool TChainLink::IsStraight() const
+  {
+    bool isStraight = _qlink->IsStraight();
+    if ( isStraight && _qfaces[0] && !_qfaces[1] )
+    {
+      int i = _qfaces[0]->LinkIndex( _qlink );
+      int iOpp = ( i + 2 ) % _qfaces[0]->_sides.size();
+      gp_XYZ mid1 = _qlink->MiddlePnt();
+      gp_XYZ mid2 = _qfaces[0]->_sides[ iOpp ]->MiddlePnt();
+      double faceSize2 = (mid1-mid2).SquareModulus();
+      isStraight = _qlink->_nodeMove.SquareMagnitude() < 1/10./10. * faceSize2;
+    }
+    return isStraight;
+  }
+  
+  //================================================================================
+  /*!
+   * \brief Move medium nodes of vertical links of pentahedrons adjacent by side faces
+   */
+  //================================================================================
+
+  void fixPrism( TChain& allLinks )
+  {
+    // separate boundary links from internal ones
+    typedef set<const QLink*/*, QLink::PtrComparator*/> QLinkSet;
+    QLinkSet interLinks, bndLinks1, bndLink2;
+
+    bool isCurved = false;
+    for ( TChain::iterator lnk = allLinks.begin(); lnk != allLinks.end(); ++lnk ) {
+      if ( (*lnk)->OnBoundary() )
+        bndLinks1.insert( lnk->_qlink );
+      else
+        interLinks.insert( lnk->_qlink );
+      isCurved = isCurved || !lnk->IsStraight();
+    }
+    if ( !isCurved )
+      return; // no need to move
+
+    QLinkSet *curBndLinks = &bndLinks1, *newBndLinks = &bndLink2;
+
+    while ( !interLinks.empty() && !curBndLinks->empty() )
+    {
+      // propagate movement from boundary links to connected internal links
+      QLinkSet::iterator bnd = curBndLinks->begin(), bndEnd = curBndLinks->end();
+      for ( ; bnd != bndEnd; ++bnd )
+      {
+        const QLink* bndLink = *bnd;
+        for ( int i = 0; i < bndLink->_faces.size(); ++i ) // loop on faces of bndLink
+        {
+          const QFace* face = bndLink->_faces[i]; // quadrange lateral face of a prism
+          if ( !face ) continue;
+          // find and move internal link opposite to bndLink within the face
+          int interInd = ( face->LinkIndex( bndLink ) + 2 ) % face->_sides.size();
+          const QLink* interLink = face->_sides[ interInd ];
+          QLinkSet::iterator pInterLink = interLinks.find( interLink );
+          if ( pInterLink == interLinks.end() ) continue; // not internal link
+          interLink->Move( bndLink->_nodeMove );
+          // treated internal links become new boundary ones
+          interLinks. erase( pInterLink );
+          newBndLinks->insert( interLink );
+        }
+      }
+      curBndLinks->clear();
+      std::swap( curBndLinks, newBndLinks );
+    }
+  }
+
+  //================================================================================
+  /*!
+   * \brief Fix links of continues triangles near curved boundary
+   */
+  //================================================================================
+
+  void fixTriaNearBoundary( TChain & allLinks, SMESH_MesherHelper& /*helper*/)
+  {
+    if ( allLinks.empty() ) return;
+
+    TLinkSet linkSet( allLinks.begin(), allLinks.end());
+    TLinkInSet linkIt = linkSet.begin(), linksEnd = linkSet.end();
+
+    for ( linkIt = linkSet.begin(); linkIt != linksEnd; ++linkIt)
+    {
+      if ( linkIt->IsBoundary() && !linkIt->IsStraight() && linkIt->_qfaces[0])
+      {
+        // move iff a boundary link is bent towards inside of a face (issue 0021084)
+        const QFace* face = linkIt->_qfaces[0];
+        gp_XYZ pIn = ( face->_sides[0]->MiddlePnt() +
+                       face->_sides[1]->MiddlePnt() +
+                       face->_sides[2]->MiddlePnt() ) / 3.;
+        gp_XYZ insideDir( pIn - (*linkIt)->MiddlePnt());
+        bool linkBentInside = ((*linkIt)->_nodeMove.Dot( insideDir ) > 0 );
+        //if ( face->IsSpoiled( linkIt->_qlink ))
+        if ( linkBentInside )
+          face->MoveByBoundary( *linkIt, (*linkIt)->_nodeMove, linkSet );
+      }
+    }
+  }
+
+  //================================================================================
+  /*!
+   * \brief Detect rectangular structure of links and build chains from them
+   */
+  //================================================================================
+
+  enum TSplitTriaResult {
+    _OK, _NO_CORNERS, _FEW_ROWS, _MANY_ROWS, _NO_SIDELINK, _BAD_MIDQUAD, _NOT_RECT,
+    _NO_MIDQUAD, _NO_UPTRIA, _BAD_SET_SIZE, _BAD_CORNER, _BAD_START, _NO_BOTLINK, _TWISTED_CHAIN };
+
+  TSplitTriaResult splitTrianglesIntoChains( TChain &            allLinks,
+                                             vector< TChain> &   resultChains,
+                                             SMDS_TypeOfPosition pos )
+  {
+    // put links in the set and evalute number of result chains by number of boundary links
+    TLinkSet linkSet;
+    int nbBndLinks = 0;
+    for ( TChain::iterator lnk = allLinks.begin(); lnk != allLinks.end(); ++lnk ) {
+      linkSet.insert( *lnk );
+      nbBndLinks += lnk->IsBoundary();
+    }
+    resultChains.clear();
+    resultChains.reserve( nbBndLinks / 2 );
+
+    TLinkInSet linkIt, linksEnd = linkSet.end();
+
+    // find a boundary link with corner node; corner node has position pos-2
+    // i.e. SMDS_TOP_VERTEX for links on faces and SMDS_TOP_EDGE for
+    // links in volume
+    SMDS_TypeOfPosition cornerPos = SMDS_TypeOfPosition(pos-2);
+    const SMDS_MeshNode* corner = 0;
+    for ( linkIt = linkSet.begin(); linkIt != linksEnd; ++linkIt )
+      if ( linkIt->IsBoundary() && (corner = (*linkIt)->EndPosNode(cornerPos)))
+        break;
+    if ( !corner)
+      return _NO_CORNERS;
+
+    TLinkInSet           startLink = linkIt;
+    const SMDS_MeshNode* startCorner = corner;
+    vector< TChain* >    rowChains;
+    int iCol = 0;
+
+    while ( startLink != linksEnd) // loop on columns
+    {
+      // We suppose we have a rectangular structure like shown here. We have found a
+      //               corner of the rectangle (startCorner) and a boundary link sharing  
+      //    |/  |/  |  the startCorner (startLink). We are going to loop on rows of the   
+      //  --o---o---o  structure making several chains at once. One chain (columnChain)   
+      //    |\  |  /|  starts at startLink and continues upward (we look at the structure 
+      //  \ | \ | / |  from such point that startLink is on the bottom of the structure). 
+      //   \|  \|/  |  While going upward we also fill horizontal chains (rowChains) we   
+      //  --o---o---o  encounter.                                                         
+      //   /|\  |\  |
+      //  / | \ | \ |  startCorner
+      //    |  \|  \|,'
+      //  --o---o---o
+      //          `.startLink
+
+      if ( resultChains.size() == nbBndLinks / 2 )
+        return _NOT_RECT;
+      resultChains.push_back( TChain() );
+      TChain& columnChain = resultChains.back();
+
+      TLinkInSet botLink = startLink; // current horizontal link to go up from
+      corner = startCorner; // current corner the botLink ends at
+      int iRow = 0;
+      while ( botLink != linksEnd ) // loop on rows
+      {
+        // add botLink to the columnChain
+        columnChain.push_back( *botLink );
+
+        const QFace* botTria = botLink->_qfaces[0]; // bottom triangle bound by botLink
+        if ( !botTria )
+        { // the column ends
+          if ( botLink == startLink )
+            return _TWISTED_CHAIN; // issue 0020951
+          linkSet.erase( botLink );
+          if ( iRow != rowChains.size() )
+            return _FEW_ROWS; // different nb of rows in columns
+          break;
+        }
+        // find the link dividing the quadrangle (midQuadLink) and vertical boundary
+        // link ending at <corner> (sideLink); there are two cases:
+        // 1) midQuadLink does not end at <corner>, then we easily find it by botTria,
+        //   since midQuadLink is not at boundary while sideLink is.
+        // 2) midQuadLink ends at <corner>
+        bool isCase2;
+        TLinkInSet midQuadLink = linksEnd;
+        TLinkInSet sideLink = botTria->GetBoundaryLink( linkSet, *botLink, &midQuadLink,
+                                                        corner, &isCase2 );
+        if ( isCase2 ) { // find midQuadLink among links of botTria
+          midQuadLink = botTria->GetLinkByNode( linkSet, *botLink, corner );
+          if ( midQuadLink->IsBoundary() )
+            return _BAD_MIDQUAD;
+        }
+        if ( sideLink == linksEnd || midQuadLink == linksEnd || sideLink == midQuadLink )
+          return sideLink == linksEnd ? _NO_SIDELINK : _NO_MIDQUAD;
+
+        // fill chains
+        columnChain.push_back( *midQuadLink );
+        if ( iRow >= rowChains.size() ) {
+          if ( iCol > 0 )
+            return _MANY_ROWS; // different nb of rows in columns
+          if ( resultChains.size() == nbBndLinks / 2 )
+            return _NOT_RECT;
+          resultChains.push_back( TChain() );
+          rowChains.push_back( & resultChains.back() );
+        }
+        rowChains[iRow]->push_back( *sideLink );
+        rowChains[iRow]->push_back( *midQuadLink );
+
+        const QFace* upTria = midQuadLink->NextFace( botTria ); // upper tria of the rectangle
+        if ( !upTria)
+          return _NO_UPTRIA;
+        if ( iRow == 0 ) {
+          // prepare startCorner and startLink for the next column
+          startCorner = startLink->NextNode( startCorner );
+          if (isCase2)
+            startLink = botTria->GetBoundaryLink( linkSet, *botLink, 0, startCorner );
+          else
+            startLink = upTria->GetBoundaryLink( linkSet, *midQuadLink, 0, startCorner );
+          // check if no more columns remains
+          if ( startLink != linksEnd ) {
+            const SMDS_MeshNode* botNode = startLink->NextNode( startCorner );
+            if ( (isCase2 ? botTria : upTria)->Contains( botNode ))
+              startLink = linksEnd; // startLink bounds upTria or botTria
+            else if ( startLink == botLink || startLink == midQuadLink || startLink == sideLink )
+              return _BAD_START;
+          }
+        }
+        // find bottom link and corner for the next row
+        corner = sideLink->NextNode( corner );
+        // next bottom link ends at the new corner
+        linkSet.erase( botLink );
+        botLink = upTria->GetLinkByNode( linkSet, (isCase2 ? *sideLink : *midQuadLink), corner );
+        if ( botLink == linksEnd || botLink == midQuadLink || botLink == sideLink)
+          return _NO_BOTLINK;
+        if ( midQuadLink == startLink || sideLink == startLink )
+          return _TWISTED_CHAIN; // issue 0020951
+        linkSet.erase( midQuadLink );
+        linkSet.erase( sideLink );
+
+        // make faces neighboring the found ones be boundary
+        if ( startLink != linksEnd ) {
+          const QFace* tria = isCase2 ? botTria : upTria;
+          for ( int iL = 0; iL < 3; ++iL ) {
+            linkIt = linkSet.find( tria->_sides[iL] );
+            if ( linkIt != linksEnd )
+              linkIt->RemoveFace( tria );
+          }
+        }
+        if ( botLink->_qfaces[0] == upTria || botLink->_qfaces[1] == upTria )
+          botLink->RemoveFace( upTria ); // make next botTria first in vector
+
+        iRow++;
+      } // loop on rows
+
+      iCol++;
+    }
+    // In the linkSet, there must remain the last links of rowChains; add them
+    if ( linkSet.size() != rowChains.size() )
+      return _BAD_SET_SIZE;
+    for ( int iRow = 0; iRow < rowChains.size(); ++iRow ) {
+      // find the link (startLink) ending at startCorner
+      corner = 0;
+      for ( startLink = linkSet.begin(); startLink != linksEnd; ++startLink ) {
+        if ( (*startLink)->node1() == startCorner ) {
+          corner = (*startLink)->node2(); break;
+        }
+        else if ( (*startLink)->node2() == startCorner) {
+          corner = (*startLink)->node1(); break;
+        }
+      }
+      if ( startLink == linksEnd )
+        return _BAD_CORNER;
+      rowChains[ iRow ]->push_back( *startLink );
+      linkSet.erase( startLink );
+      startCorner = corner;
+    }
+
+    return _OK;
+  }
+} //namespace
+
+//=======================================================================
+/*!
+ * \brief Move medium nodes of faces and volumes to fix distorted elements
+ * \param volumeOnly - to fix nodes on faces or not, if the shape is solid
+ * 
+ * Issue 0020307: EDF 992 SMESH : Linea/Quadratic with Medium Node on Geometry
+ */
+//=======================================================================
+
+void SMESH_MesherHelper::FixQuadraticElements(bool volumeOnly)
+{
+  // setenv NO_FixQuadraticElements to know if FixQuadraticElements() is guilty of bad conversion
+  if ( getenv("NO_FixQuadraticElements") )
+    return;
+
+  // 0. Apply algorithm to SOLIDs or FACEs
+  // ----------------------------------------------
+  if ( myShape.IsNull() ) {
+    if ( !myMesh->HasShapeToMesh() ) return;
+    SetSubShape( myMesh->GetShapeToMesh() );
+
+#ifdef _DEBUG_
+    int nbSolids = 0;
+    TopTools_IndexedMapOfShape solids;
+    TopExp::MapShapes(myShape,TopAbs_SOLID,solids);
+    nbSolids = solids.Extent();
+#endif
+    TopTools_MapOfShape faces; // faces not in solid or in not meshed solid
+    for ( TopExp_Explorer f(myShape,TopAbs_FACE,TopAbs_SOLID); f.More(); f.Next() ) {
+      faces.Add( f.Current() ); // not in solid
+    }
+    for ( TopExp_Explorer s(myShape,TopAbs_SOLID); s.More(); s.Next() ) {
+      if ( myMesh->GetSubMesh( s.Current() )->IsEmpty() ) { // get faces of solid
+        for ( TopExp_Explorer f( s.Current(), TopAbs_FACE); f.More(); f.Next() )
+          faces.Add( f.Current() ); // in not meshed solid
+      }
+      else { // fix nodes in the solid and its faces
+#ifdef _DEBUG_
+        MSG("FIX SOLID " << nbSolids-- << " #" << GetMeshDS()->ShapeToIndex(s.Current()));
+#endif
+        SMESH_MesherHelper h(*myMesh);
+        h.SetSubShape( s.Current() );
+        h.FixQuadraticElements(false);
+      }
+    }
+    // fix nodes on geom faces
+#ifdef _DEBUG_
+    int nbfaces = faces.Extent(); /*avoid "unused varianbles": */ nbfaces++, nbfaces--; 
+#endif
+    for ( TopTools_MapIteratorOfMapOfShape fIt( faces ); fIt.More(); fIt.Next() ) {
+      MSG("FIX FACE " << nbfaces-- << " #" << GetMeshDS()->ShapeToIndex(fIt.Key()));
+      SMESH_MesherHelper h(*myMesh);
+      h.SetSubShape( fIt.Key() );
+      h.FixQuadraticElements(true);
+      h.ToFixNodeParameters(true);
+    }
+    //perf_print_all_meters(1);
+    return;
+  }
+
+  // 1. Find out type of elements and get iterator on them
+  // ---------------------------------------------------
+
+  SMDS_ElemIteratorPtr elemIt;
+  SMDSAbs_ElementType elemType = SMDSAbs_All;
+
+  SMESH_subMesh* submesh = myMesh->GetSubMeshContaining( myShapeID );
+  if ( !submesh )
+    return;
+  if ( SMESHDS_SubMesh* smDS = submesh->GetSubMeshDS() ) {
+    elemIt = smDS->GetElements();
+    if ( elemIt->more() ) {
+      elemType = elemIt->next()->GetType();
+      elemIt = smDS->GetElements();
+    }
+  }
+  if ( !elemIt || !elemIt->more() || elemType < SMDSAbs_Face )
+    return;
+
+  // 2. Fill in auxiliary data structures
+  // ----------------------------------
+
+  set< QLink > links;
+  set< QFace > faces;
+  set< QLink >::iterator pLink;
+  set< QFace >::iterator pFace;
+
+  bool isCurved = false;
+  //bool hasRectFaces = false;
+  //set<int> nbElemNodeSet;
+  SMDS_VolumeTool volTool;
+
+  TIDSortedNodeSet apexOfPyramid;
+  const int apexIndex = 4;
+
+  if ( elemType == SMDSAbs_Volume )
+  {
+    while ( elemIt->more() ) // loop on volumes
+    {
+      const SMDS_MeshElement* vol = elemIt->next();
+      if ( !vol->IsQuadratic() || !volTool.Set( vol ))
+        return;
+      double volMinSize2 = -1.;
+      for ( int iF = 0; iF < volTool.NbFaces(); ++iF ) // loop on faces of volume
+      {
+        int nbN = volTool.NbFaceNodes( iF );
+        //nbElemNodeSet.insert( nbN );
+        const SMDS_MeshNode** faceNodes = volTool.GetFaceNodes( iF );
+        vector< const QLink* > faceLinks( nbN/2 );
+        for ( int iN = 0; iN < nbN; iN += 2 ) // loop on links of a face
+        {
+          // store QLink
+          QLink link( faceNodes[iN], faceNodes[iN+2], faceNodes[iN+1] );
+          pLink = links.insert( link ).first;
+          faceLinks[ iN/2 ] = & *pLink;
+
+          if ( link.MediumPos() == SMDS_TOP_3DSPACE )
+          {
+            if ( !link.IsStraight() )
+              return; // already fixed
+          }
+          else if ( !isCurved )
+          {
+            if ( volMinSize2 < 0 ) volMinSize2 = volTool.MinLinearSize2();
+            isCurved = !isStraightLink( volMinSize2, link._nodeMove.SquareMagnitude() );
+          }
+        }
+        // store QFace
+        pFace = faces.insert( QFace( faceLinks )).first;
+        if ( pFace->NbVolumes() == 0 )
+          pFace->AddSelfToLinks();
+        pFace->SetVolume( vol );
+//         hasRectFaces = hasRectFaces ||
+//           ( volTool.GetVolumeType() == SMDS_VolumeTool::QUAD_HEXA ||
+//             volTool.GetVolumeType() == SMDS_VolumeTool::QUAD_PENTA );
+#ifdef _DEBUG_
+        if ( nbN == 6 )
+          pFace->_face = GetMeshDS()->FindFace(faceNodes[0],faceNodes[2],faceNodes[4]);
+        else
+          pFace->_face = GetMeshDS()->FindFace(faceNodes[0],faceNodes[2],
+                                               faceNodes[4],faceNodes[6] );
+#endif
+      }
+      // collect pyramid apexes for further correction
+      if ( vol->NbCornerNodes() == 5 )
+        apexOfPyramid.insert( vol->GetNode( apexIndex ));
+    }
+    set< QLink >::iterator pLink = links.begin();
+    for ( ; pLink != links.end(); ++pLink )
+      pLink->SetContinuesFaces();
+  }
+  else
+  {
+    while ( elemIt->more() ) // loop on faces
+    {
+      const SMDS_MeshElement* face = elemIt->next();
+      if ( !face->IsQuadratic() )
+        continue;
+      //nbElemNodeSet.insert( face->NbNodes() );
+      int nbN = face->NbNodes()/2;
+      vector< const QLink* > faceLinks( nbN );
+      for ( int iN = 0; iN < nbN; ++iN ) // loop on links of a face
+      {
+        // store QLink
+        QLink link( face->GetNode(iN), face->GetNode((iN+1)%nbN), face->GetNode(iN+nbN) );
+        pLink = links.insert( link ).first;
+        faceLinks[ iN ] = & *pLink;
+        if ( !isCurved )
+          isCurved = !link.IsStraight();
+      }
+      // store QFace
+      pFace = faces.insert( QFace( faceLinks )).first;
+      pFace->AddSelfToLinks();
+      //hasRectFaces = ( hasRectFaces || nbN == 4 );
+    }
+  }
+  if ( !isCurved )
+    return; // no curved edges of faces
+
+  // 3. Compute displacement of medium nodes
+  // ---------------------------------------
+
+  // two loops on QFaces: the first is to treat boundary links, the second is for internal ones
+  TopLoc_Location loc;
+  // not treat boundary of volumic submesh
+  int isInside = ( elemType == SMDSAbs_Volume && volumeOnly ) ? 1 : 0;
+  for ( ; isInside < 2; ++isInside ) {
+    MSG( "--------------- LOOP (inside=" << isInside << ") ------------------");
+    SMDS_TypeOfPosition pos = isInside ? SMDS_TOP_3DSPACE : SMDS_TOP_FACE;
+    SMDS_TypeOfPosition bndPos = isInside ? SMDS_TOP_FACE : SMDS_TOP_EDGE;
+
+    for ( pFace = faces.begin(); pFace != faces.end(); ++pFace ) {
+      if ( bool(isInside) == pFace->IsBoundary() )
+        continue;
+      for ( int dir = 0; dir < 2; ++dir ) // 2 directions of propagation from the quadrangle
+      {
+        MSG( "CHAIN");
+        // make chain of links connected via continues faces
+        int error = ERR_OK;
+        TChain rawChain;
+        if ( !pFace->GetLinkChain( dir, rawChain, pos, error) && error ==ERR_UNKNOWN ) continue;
+        rawChain.reverse();
+        if ( !pFace->GetLinkChain( dir+2, rawChain, pos, error ) && error ==ERR_UNKNOWN ) continue;
+
+        vector< TChain > chains;
+        if ( error == ERR_OK ) { // chain contains continues rectangles
+          chains.resize(1);
+          chains[0].splice( chains[0].begin(), rawChain );
+        }
+        else if ( error == ERR_TRI ) {  // chain contains continues triangles
+          TSplitTriaResult res = splitTrianglesIntoChains( rawChain, chains, pos );
+          if ( res != _OK ) { // not quadrangles split into triangles
+            fixTriaNearBoundary( rawChain, *this );
+            break;
+          }
+        }
+        else if ( error == ERR_PRISM ) { // quadrangle side faces of prisms
+          fixPrism( rawChain );
+          break;
+        }
+        else {
+          continue;
+        }
+        for ( int iC = 0; iC < chains.size(); ++iC )
+        {
+          TChain& chain = chains[iC];
+          if ( chain.empty() ) continue;
+          if ( chain.front().IsStraight() && chain.back().IsStraight() ) {
+            MSG("3D straight - ignore");
+            continue;
+          }
+          if ( chain.front()->MediumPos() > bndPos ||
+               chain.back() ->MediumPos() > bndPos ) {
+            MSG("Internal chain - ignore");
+            continue;
+          }
+          // mesure chain length and compute link position along the chain
+          double chainLen = 0;
+          vector< double > linkPos;
+          MSGBEG( "Link medium nodes: ");
+          TChain::iterator link0 = chain.begin(), link1 = chain.begin(), link2;
+          for ( ++link1; link1 != chain.end(); ++link1, ++link0 ) {
+            MSGBEG( (*link0)->_mediumNode->GetID() << "-" <<(*link1)->_mediumNode->GetID()<<" ");
+            double len = ((*link0)->MiddlePnt() - (*link1)->MiddlePnt()).Modulus();
+            while ( len < numeric_limits<double>::min() ) { // remove degenerated link
+              link1 = chain.erase( link1 );
+              if ( link1 == chain.end() )
+                break;
+              len = ((*link0)->MiddlePnt() - (*link1)->MiddlePnt()).Modulus();
+            }
+            chainLen += len;
+            linkPos.push_back( chainLen );
+          }
+          MSG("");
+          if ( linkPos.size() < 2 )
+            continue;
+
+          gp_Vec move0 = chain.front()->_nodeMove;
+          gp_Vec move1 = chain.back ()->_nodeMove;
+
+          TopoDS_Face face;
+          bool checkUV = true;
+          if ( !isInside )
+          {
+            // compute node displacement of end links of chain in parametric space of face
+            TChainLink& linkOnFace = *(++chain.begin());
+            const SMDS_MeshNode* nodeOnFace = linkOnFace->_mediumNode;
+            TopoDS_Shape f = GetSubShapeByNode( nodeOnFace, GetMeshDS() );
+            if ( !f.IsNull() && f.ShapeType() == TopAbs_FACE )
+            {
+              face = TopoDS::Face( f );
+              Handle(Geom_Surface) surf = BRep_Tool::Surface(face,loc);
+              bool isStraight[2];
+              for ( int is1 = 0; is1 < 2; ++is1 ) // move0 or move1
+              {
+                TChainLink& link = is1 ? chain.back() : chain.front();
+                gp_XY uvm = GetNodeUV( face, link->_mediumNode, nodeOnFace, &checkUV);
+                gp_XY uv1 = GetNodeUV( face, link->node1(), nodeOnFace, &checkUV);
+                gp_XY uv2 = GetNodeUV( face, link->node2(), nodeOnFace, &checkUV);
+                gp_XY uv12 = GetMiddleUV( surf, uv1, uv2);
+                // uvMove = uvm - uv12
+                gp_XY uvMove = applyIn2D(surf, uvm, uv12, gp_XY_Subtracted, /*inPeriod=*/false);
+                ( is1 ? move1 : move0 ).SetCoord( uvMove.X(), uvMove.Y(), 0 );
+                if ( !is1 ) // correct nodeOnFace for move1 (issue 0020919)
+                  nodeOnFace = (*(++chain.rbegin()))->_mediumNode;
+                isStraight[is1] = isStraightLink( (uv2-uv1).SquareModulus(),
+                                                  10 * uvMove.SquareModulus());
+              }
+              if ( isStraight[0] && isStraight[1] ) {
+                MSG("2D straight - ignore");
+                continue; // straight - no need to move nodes of internal links
+              }
+
+              // check if a chain is already fixed
+              gp_XY uvm = GetNodeUV( face, linkOnFace->_mediumNode, 0, &checkUV);
+              gp_XY uv1 = GetNodeUV( face, linkOnFace->node1(), nodeOnFace, &checkUV);
+              gp_XY uv2 = GetNodeUV( face, linkOnFace->node2(), nodeOnFace, &checkUV);
+              gp_XY uv12 = GetMiddleUV( surf, uv1, uv2);
+              if (( uvm - uv12 ).SquareModulus() > 1e-10 )
+              {
+                MSG("Already fixed - ignore");
+                continue;
+              }
+            }
+          }
+          gp_Trsf trsf;
+          if ( isInside || face.IsNull() )
+          {
+            // compute node displacement of end links in their local coord systems
+            {
+              TChainLink& ln0 = chain.front(), ln1 = *(++chain.begin());
+              trsf.SetTransformation( gp_Ax3( gp::Origin(), ln0.Normal(),
+                                              gp_Vec( ln0->MiddlePnt(), ln1->MiddlePnt() )));
+              move0.Transform(trsf);
+            }
+            {
+              TChainLink& ln0 = *(++chain.rbegin()), ln1 = chain.back();
+              trsf.SetTransformation( gp_Ax3( gp::Origin(), ln1.Normal(),
+                                              gp_Vec( ln0->MiddlePnt(), ln1->MiddlePnt() )));
+              move1.Transform(trsf);
+            }
+          }
+          // compute displacement of medium nodes
+          link2 = chain.begin();
+          link0 = link2++;
+          link1 = link2++;
+          for ( int i = 0; link2 != chain.end(); ++link0, ++link1, ++link2, ++i )
+          {
+            double r = linkPos[i] / chainLen;
+            // displacement in local coord system
+            gp_Vec move = (1. - r) * move0 + r * move1;
+            if ( isInside || face.IsNull()) {
+              // transform to global
+              gp_Vec x01( (*link0)->MiddlePnt(), (*link1)->MiddlePnt() );
+              gp_Vec x12( (*link1)->MiddlePnt(), (*link2)->MiddlePnt() );
+              gp_Vec x = x01.Normalized() + x12.Normalized();
+              trsf.SetTransformation( gp_Ax3( gp::Origin(), link1->Normal(), x), gp_Ax3() );
+              move.Transform(trsf);
+            }
+            else {
+              // compute 3D displacement by 2D one
+              Handle(Geom_Surface) s = BRep_Tool::Surface(face,loc);
+              gp_XY oldUV   = GetNodeUV( face, (*link1)->_mediumNode, 0, &checkUV);
+              gp_XY newUV   = applyIn2D( s, oldUV, gp_XY( move.X(),move.Y()), gp_XY_Added);
+              gp_Pnt newPnt = s->Value( newUV.X(), newUV.Y());
+              move = gp_Vec( XYZ((*link1)->_mediumNode), newPnt.Transformed(loc) );
+#ifdef _DEBUG_
+              if ( (XYZ((*link1)->node1()) - XYZ((*link1)->node2())).SquareModulus() <
+                   move.SquareMagnitude())
+              {
+                gp_XY uv0 = GetNodeUV( face, (*link0)->_mediumNode, 0, &checkUV);
+                gp_XY uv2 = GetNodeUV( face, (*link2)->_mediumNode, 0, &checkUV);
+                MSG( "TOO LONG MOVE \t" <<
+                     "uv0: "<<uv0.X()<<", "<<uv0.Y()<<" \t" <<
+                     "uv2: "<<uv2.X()<<", "<<uv2.Y()<<" \t" <<
+                     "uvOld: "<<oldUV.X()<<", "<<oldUV.Y()<<" \t" <<
+                     "newUV: "<<newUV.X()<<", "<<newUV.Y()<<" \t");
+              }
+#endif
+            }
+            (*link1)->Move( move );
+            MSG( "Move " << (*link1)->_mediumNode->GetID() << " following "
+                 << chain.front()->_mediumNode->GetID() <<"-"
+                 << chain.back ()->_mediumNode->GetID() <<
+                 " by " << move.Magnitude());
+          }
+        } // loop on chains of links
+      } // loop on 2 directions of propagation from quadrangle
+    } // loop on faces
+  }
+
+  // 4. Move nodes
+  // -------------
+
+//   vector<const SMDS_MeshElement*> vols( 100 );
+//   vector<double>                  volSize( 100 );
+//   int nbVols;
+//   bool ok;
+  for ( pLink = links.begin(); pLink != links.end(); ++pLink ) {
+    if ( pLink->IsMoved() ) {
+      gp_Pnt p = pLink->MiddlePnt() + pLink->Move();
+      GetMeshDS()->MoveNode( pLink->_mediumNode, p.X(), p.Y(), p.Z());
+      //
+//       gp_Pnt pNew = pLink->MiddlePnt() + pLink->Move();
+//       if ( pLink->MediumPos() != SMDS_TOP_3DSPACE )
+//       {
+//         // avoid making distorted volumes near boundary
+//         SMDS_ElemIteratorPtr volIt =
+//           (*pLink)._mediumNode->GetInverseElementIterator( SMDSAbs_Volume );
+//         for ( nbVols = 0; volIt->more() && volTool.Set( volIt->next() ); ++nbVols )
+//         {
+//           vols   [ nbVols ] = volTool.Element();
+//           volSize[ nbVols ] = volTool.GetSize();
+//         }
+//         gp_Pnt pOld = pLink->MediumPnt();
+//         const_cast<SMDS_MeshNode*>( pLink->_mediumNode )->setXYZ( pNew.X(), pNew.Y(), pNew.Z() );
+//         ok = true;
+//         while ( nbVols-- && ok )
+//         {
+//           volTool.Set( vols[ nbVols ]);
+//           ok = ( volSize[ nbVols ] * volTool.GetSize() > 1e-20 ); 
+//         }
+//         if ( !ok )
+//         {
+//           const_cast<SMDS_MeshNode*>( pLink->_mediumNode )->setXYZ( pOld.X(), pOld.Y(), pOld.Z() );
+//           MSG( "Do NOT move \t" << pLink->_mediumNode->GetID()
+//                << " because of distortion of volume " << vols[ nbVols+1 ]->GetID());
+//           continue;
+//         }
+//       }
+//       GetMeshDS()->MoveNode( pLink->_mediumNode, pNew.X(), pNew.Y(), pNew.Z() );
+    }
+  }
+
+  //return;
+
+  // issue 0020982
+  // Move the apex of pyramid together with the most curved link
+
+  TIDSortedNodeSet::iterator apexIt = apexOfPyramid.begin();
+  for ( ; apexIt != apexOfPyramid.end(); ++apexIt )
+  {
+    SMESH_TNodeXYZ apex = *apexIt;
+
+    gp_Vec maxMove( 0,0,0 );
+    double maxMoveSize2 = 0;
+
+    // shift of node index to get medium nodes between the base nodes
+    const int base2MediumShift = 5;
+
+    // find maximal movement of medium node
+    SMDS_ElemIteratorPtr volIt = apex._node->GetInverseElementIterator( SMDSAbs_Volume );
+    vector< const SMDS_MeshElement* > pyramids;
+    while ( volIt->more() )
+    {
+      const SMDS_MeshElement* pyram = volIt->next();
+      if ( pyram->GetEntityType() != SMDSEntity_Quad_Pyramid ) continue;
+      pyramids.push_back( pyram );
+
+      for ( int iBase = 0; iBase < apexIndex; ++iBase )
+      {
+        SMESH_TNodeXYZ medium = pyram->GetNode( iBase + base2MediumShift );
+        if ( medium._node->GetPosition()->GetTypeOfPosition() != SMDS_TOP_3DSPACE )
+        {
+          SMESH_TNodeXYZ n1 = pyram->GetNode( iBase );
+          SMESH_TNodeXYZ n2 = pyram->GetNode( ( iBase+1 ) % 4 );
+          gp_Pnt middle = 0.5 * ( n1 + n2 );
+          gp_Vec move( middle, medium );
+          double moveSize2 = move.SquareMagnitude();
+          if ( moveSize2 > maxMoveSize2 )
+            maxMove = move, maxMoveSize2 = moveSize2;
+        }
+      }
+    }
+
+    // move the apex
+    if ( maxMoveSize2 > 1e-20 )
+    {
+      apex += maxMove.XYZ();
+      GetMeshDS()->MoveNode( apex._node, apex.X(), apex.Y(), apex.Z());
+
+      // move medium nodes neighboring the apex to the middle
+      const int base2MediumShift_2 = 9;
+      for ( unsigned i = 0; i < pyramids.size(); ++i )
+        for ( int iBase = 0; iBase < apexIndex; ++iBase )
+        {
+          SMESH_TNodeXYZ         base = pyramids[i]->GetNode( iBase );
+          const SMDS_MeshNode* medium = pyramids[i]->GetNode( iBase + base2MediumShift_2 );
+          gp_XYZ middle = 0.5 * ( apex + base );
+          GetMeshDS()->MoveNode( medium, middle.X(), middle.Y(), middle.Z());
+        }
+    }
+  }
+}
+
index f88f1fc08e0732b60c2a42140967ea005f5454e4..c74dfb8583e122094edb5cda02d5706073122e1e 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File:      SMESH_MesherHelper.hxx
 // Created:   15.02.06 14:48:09
 // Author:    Sergey KUUL
 
 #include "SMESH_SMESH.hxx"
 
-#include <SMESH_Mesh.hxx>
-#include <TopoDS_Shape.hxx>
+#include "SMESH_MeshEditor.hxx" // needed for many meshers
 #include <SMDS_MeshNode.hxx>
+#include <SMDS_QuadraticEdge.hxx>
+
+#include <Geom_Surface.hxx>
 #include <TopoDS_Face.hxx>
+#include <TopoDS_Shape.hxx>
 #include <gp_Pnt2d.hxx>
-#include <SMDS_QuadraticEdge.hxx>
 
 #include <map>
+#include <vector>
+
+class GeomAPI_ProjectPointOnSurf;
+class GeomAPI_ProjectPointOnCurve;
+class SMESH_ProxyMesh;
+
+typedef std::map<SMESH_TLink, const SMDS_MeshNode*>           TLinkNodeMap;
+typedef std::map<SMESH_TLink, const SMDS_MeshNode*>::iterator ItTLinkNode;
+
+typedef SMDS_Iterator<const TopoDS_Shape*>  PShapeIterator;
+typedef boost::shared_ptr< PShapeIterator > PShapeIteratorPtr;
+  
+typedef std::vector<const SMDS_MeshNode* > TNodeColumn;
+typedef std::map< double, TNodeColumn >    TParam2ColumnMap;
 
-typedef std::pair<const SMDS_MeshNode*, const SMDS_MeshNode*> NLink;
-typedef std::map<NLink, const SMDS_MeshNode*> NLinkNodeMap;
-typedef std::map<NLink, const SMDS_MeshNode*>::iterator ItNLinkNode;
+typedef gp_XY (*xyFunPtr)(const gp_XY& uv1, const gp_XY& uv2);
 
+//=======================================================================
 /*!
  * \brief It helps meshers to add elements
  *
@@ -49,9 +65,7 @@ typedef std::map<NLink, const SMDS_MeshNode*>::iterator ItNLinkNode;
  * It defines degree of elements to create when IsQuadraticSubMesh()
  * is called.
  */
-
-typedef std::vector<const SMDS_MeshNode* > TNodeColumn;
-typedef std::map< double, TNodeColumn > TParam2ColumnMap;
+//=======================================================================
 
 class SMESH_EXPORT SMESH_MesherHelper
 {
@@ -71,28 +85,36 @@ public:
    * \brief Load nodes bound to face into a map of node columns
     * \param theParam2ColumnMap - map of node columns to fill
     * \param theFace - the face on which nodes are searched for
-    * \param theBaseEdge - the edge nodes of which are columns' bases
+    * \param theBaseSide - the edges holding nodes on which columns' bases
     * \param theMesh - the mesh containing nodes
     * \retval bool - false if something is wrong
    * 
    * The key of the map is a normalized parameter of each
-   * base node on theBaseEdge.
+   * base node on theBaseSide. Edges in theBaseSide must be sequenced.
    * This method works in supposition that nodes on the face
    * forms a rectangular grid and elements can be quardrangles or triangles
    */
+  static bool LoadNodeColumns(TParam2ColumnMap &            theParam2ColumnMap,
+                              const TopoDS_Face&            theFace,
+                              const std::list<TopoDS_Edge>& theBaseSide,
+                              SMESHDS_Mesh*                 theMesh,
+                              SMESH_ProxyMesh*              theProxyMesh=0);
+  /*!
+   * \brief Variant of LoadNodeColumns() above with theBaseSide given by one edge
+   */
   static bool LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap,
                               const TopoDS_Face& theFace,
                               const TopoDS_Edge& theBaseEdge,
-                              SMESHDS_Mesh*      theMesh);
+                              SMESHDS_Mesh*      theMesh,
+                              SMESH_ProxyMesh*   theProxyMesh=0);
   /*!
    * \brief Return support shape of a node
    * \param node - the node
    * \param meshDS - mesh DS
    * \retval TopoDS_Shape - found support shape
    */
-  static const TopoDS_Shape& GetSubShapeByNode(const SMDS_MeshNode* node,
-                                               SMESHDS_Mesh*        meshDS)
-  { return meshDS->IndexToShape( node->GetPosition()->GetShapeId() ); }
+  static TopoDS_Shape GetSubShapeByNode(const SMDS_MeshNode* node,
+                                        const SMESHDS_Mesh*  meshDS);
 
   /*!
    * \brief Return a valid node index, fixing the given one if necessary
@@ -106,6 +128,43 @@ public:
     return ind;
   }
 
+  /*!
+   * \brief Return number of unique ancestors of the shape
+   */
+  static int NbAncestors(const TopoDS_Shape& shape,
+                         const SMESH_Mesh&   mesh,
+                         TopAbs_ShapeEnum    ancestorType=TopAbs_SHAPE);
+  /*!
+   * \brief Return iterator on ancestors of the given type
+   */
+  static PShapeIteratorPtr GetAncestors(const TopoDS_Shape& shape,
+                                        const SMESH_Mesh&   mesh,
+                                        TopAbs_ShapeEnum    ancestorType);
+  /*!
+   * \brief Find a common ancestors of two shapes of the given type
+   */
+  static TopoDS_Shape GetCommonAncestor(const TopoDS_Shape& shape1,
+                                        const TopoDS_Shape& shape2,
+                                        const SMESH_Mesh&   mesh,
+                                        TopAbs_ShapeEnum    ancestorType);
+
+  /*!
+   * \brief Return orientation of sub-shape in the main shape
+   */
+  static TopAbs_Orientation GetSubShapeOri(const TopoDS_Shape& shape,
+                                           const TopoDS_Shape& subShape);
+
+  static bool IsSubShape( const TopoDS_Shape& shape, const TopoDS_Shape& mainShape );
+
+  static bool IsSubShape( const TopoDS_Shape& shape, SMESH_Mesh* aMesh );
+
+  static double MaxTolerance( const TopoDS_Shape& shape );
+
+  static bool IsClosedEdge( const TopoDS_Edge& anEdge );
+
+  static TopoDS_Vertex IthVertex( const bool is2nd, TopoDS_Edge anEdge, const bool CumOri=true );
+
+
 public:
   // ---------- PUBLIC INSTANCE METHODS ----------
 
@@ -118,7 +177,7 @@ public:
     
   /*!
    * Check submesh for given shape: if all elements on this shape are quadratic,
-   * quadratic elements will be created. Also fill myNLinkNodeMap
+   * quadratic elements will be created. Also fill myTLinkNodeMap
    */
   bool IsQuadraticSubMesh(const TopoDS_Shape& theShape);
   /*!
@@ -131,6 +190,12 @@ public:
    */
   bool GetIsQuadratic() const { return myCreateQuadratic; }
 
+  /*!
+   * \brief Move medium nodes of faces and volumes to fix distorted elements
+   * \param volumeOnly - fix nodes on geom faces or not if the shape is solid
+   */
+  void FixQuadraticElements(bool volumeOnly=true);
+
   /*!
    * \brief To set created elements on the shape set by IsQuadraticSubMesh()
    *        or the next methods. By defaul elements are set on the shape if
@@ -151,12 +216,12 @@ public:
   /*!
    * \brief Return the shape set by IsQuadraticSubMesh() or SetSubShape() 
    */
-  TopoDS_Shape GetSubShape() const  { return myShape; }
+  const TopoDS_Shape& GetSubShape() const  { return myShape; }
 
   /*!
    * Creates a node
    */
-  SMDS_MeshNode* AddNode(double x, double y, double z, int ID = 0);
+  SMDS_MeshNode* AddNode(double x, double y, double z, int ID = 0, double u=0., double v=0.);
   /*!
    * Creates quadratic or linear edge
    */
@@ -171,7 +236,7 @@ public:
                          const SMDS_MeshNode* n2,
                          const SMDS_MeshNode* n3,
                          const int id=0, 
-                        const bool force3d = false);
+                         const bool force3d = false);
   /*!
    * Creates quadratic or linear quadrangle
    */
@@ -180,16 +245,23 @@ public:
                          const SMDS_MeshNode* n3,
                          const SMDS_MeshNode* n4,
                          const int id = 0,
-                        const bool force3d = false);
+                         const bool force3d = false);
+
   /*!
-   * Creates quadratic or linear tetraahedron
+   * Creates polygon, with additional nodes in quadratic mesh
+   */
+  SMDS_MeshFace* AddPolygonalFace (const std::vector<const SMDS_MeshNode*>& nodes,
+                                   const int id = 0,
+                                   const bool force3d = false);
+  /*!
+   * Creates quadratic or linear tetrahedron
    */
   SMDS_MeshVolume* AddVolume(const SMDS_MeshNode* n1,
                              const SMDS_MeshNode* n2,
                              const SMDS_MeshNode* n3,
                              const SMDS_MeshNode* n4,
                              const int id = 0,
-                            const bool force3d = true);
+                             const bool force3d = true);
   /*!
    * Creates quadratic or linear pyramid
    */
@@ -199,7 +271,7 @@ public:
                              const SMDS_MeshNode* n4,
                              const SMDS_MeshNode* n5,
                              const int id = 0,
-                            const bool force3d = true);
+                             const bool force3d = true);
   /*!
    * Creates quadratic or linear pentahedron
    */
@@ -210,7 +282,7 @@ public:
                              const SMDS_MeshNode* n5,
                              const SMDS_MeshNode* n6,
                              const int id = 0, 
-                            const bool force3d = true);
+                             const bool force3d = true);
   /*!
    * Creates quadratic or linear hexahedron
    */
@@ -223,28 +295,124 @@ public:
                              const SMDS_MeshNode* n7,
                              const SMDS_MeshNode* n8,
                              const int id = 0, 
-                            bool force3d = true);
+                             bool force3d = true);
+
+  /*!
+   * Creates LINEAR!!!!!!!!! octahedron
+   */
+  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,
+                             const SMDS_MeshNode* n9,
+                             const SMDS_MeshNode* n10,
+                             const SMDS_MeshNode* n11,
+                             const SMDS_MeshNode* n12,
+                             const int id = 0, 
+                             bool force3d = true);
+
+  /*!
+   * Creates polyhedron. In quadratic mesh, adds medium nodes
+   */
+  SMDS_MeshVolume* AddPolyhedralVolume (const std::vector<const SMDS_MeshNode*>& nodes,
+                                        const std::vector<int>&                  quantities,
+                                        const int                                ID=0,
+                                        const bool                               force3d = true);
+  /*!
+   * \brief Enables fixing node parameters on EDGEs and FACEs by
+   * GetNodeU(...,check=true), GetNodeUV(...,check=true), CheckNodeUV() and
+   * CheckNodeU() in case if a node lies on a shape set via SetSubShape().
+   * Default is False
+   */
+  void ToFixNodeParameters(bool toFix);
+
   /*!
    * \brief Return U of the given node on the edge
    */
   double GetNodeU(const TopoDS_Edge&   theEdge,
-                  const SMDS_MeshNode* theNode);
+                  const SMDS_MeshNode* theNode,
+                  const SMDS_MeshNode* inEdgeNode=0,
+                  bool*                check=0);
   /*!
    * \brief Return node UV on face
-    * \param inFaceNode - a node of element being created located inside a face
+    \param inFaceNode - a node of element being created located inside a face
    */
   gp_XY GetNodeUV(const TopoDS_Face&   F,
                   const SMDS_MeshNode* n,
-                  const SMDS_MeshNode* inFaceNode=0) const;
+                  const SMDS_MeshNode* inFaceNode=0,
+                  bool*                check=0) const;
+  /*!
+   * \brief Check and fix node UV on a face
+   *  \param force - check even if checks of other nodes on this face passed OK
+   *  \param distXYZ - returns result distance and point coordinates
+   *  \retval bool - false if UV is bad and could not be fixed
+   */
+  bool CheckNodeUV(const TopoDS_Face&   F,
+                   const SMDS_MeshNode* n,
+                   gp_XY&               uv,
+                   const double         tol,
+                   const bool           force=false,
+                   double               distXYZ[4]=0) const;
+  /*!
+   * \brief Check and fix node U on an edge
+   *  \param force - check even if checks of other nodes on this edge passed OK
+   *  \param distXYZ - returns result distance and point coordinates
+   *  \retval bool - false if U is bad and could not be fixed
+   */
+  bool CheckNodeU(const TopoDS_Edge&   E,
+                  const SMDS_MeshNode* n,
+                  double&              u,
+                  const double         tol,
+                  const bool           force=false,
+                  double               distXYZ[4]=0) const;
+  /*!
+   * \brief Return middle UV taking in account surface period
+   */
+  static gp_XY GetMiddleUV(const Handle(Geom_Surface)& surface,
+                           const gp_XY&                uv1,
+                           const gp_XY&                uv2);
+  /*!
+   * \brief Define a pointer to wrapper over a function of gp_XY class,
+   *       suitable to pass as xyFunPtr to applyIn2D().
+   *       For exaple gp_XY_FunPtr(Added) defines pointer gp_XY_Added to function
+   *       calling gp_XY::Added(gp_XY), which is to be used like following
+   *       applyIn2D(surf, uv1, uv2, gp_XY_Added)
+   */
+#define gp_XY_FunPtr(meth) \
+  static gp_XY __gpXY_##meth (const gp_XY& uv1, const gp_XY& uv2) { return uv1.meth( uv2 ); } \
+  static xyFunPtr gp_XY_##meth = & __gpXY_##meth
+
+  /*!
+   * \brief Perform given operation on two 2d points in parameric space of given surface.
+   *        It takes into account period of the surface. Use gp_XY_FunPtr macro
+   *        to easily define pointer to function of gp_XY class.
+   */
+  static gp_XY applyIn2D(const Handle(Geom_Surface)& surface,
+                         const gp_XY&                uv1,
+                         const gp_XY&                uv2,
+                         xyFunPtr                    fun,
+                         const bool                  resultInPeriod=true);
+                          
   /*!
    * \brief Check if inFaceNode argument is necessary for call GetNodeUV(F,..)
     * \retval bool - return true if the face is periodic
     *
-    * if F is Null, answer about subshape set through IsQuadraticSubMesh() or
+    * If F is Null, answer about subshape set through IsQuadraticSubMesh() or
     * SetSubShape()
    */
   bool GetNodeUVneedInFaceNode(const TopoDS_Face& F = TopoDS_Face()) const;
 
+  /*!
+   * \brief Return projector intitialized by given face without location, which is returned
+   */
+  GeomAPI_ProjectPointOnSurf& GetProjector(const TopoDS_Face& F,
+                                           TopLoc_Location&   loc,
+                                           double             tol=0 ) const; 
+
   /*!
    * \brief Check if shape is a degenerated edge or it's vertex
     * \param subShape - edge or vertex index in SMESHDS
@@ -254,6 +422,13 @@ public:
    */
   bool IsDegenShape(const int subShape) const
   { return myDegenShapeIds.find( subShape ) != myDegenShapeIds.end(); }
+  /*!
+   * \brief Check if the shape set through IsQuadraticSubMesh() or SetSubShape()
+   *        has a degenerated edges
+    * \retval bool - true if it has
+   */
+  bool HasDegeneratedEdges() const { return !myDegenShapeIds.empty(); }
+
   /*!
    * \brief Check if shape is a seam edge or it's vertex
     * \param subShape - edge or vertex index in SMESHDS
@@ -302,28 +477,40 @@ public:
    */
   double GetOtherParam(const double param) const;
 
-  /**
-   * Special function for search or creation medium node
+  /*!
+   * \brief Return existing or create new medium nodes between given ones
+   *  \param force3d - true means node creation at the middle between the
+   *                   two given nodes, else node position is found on its
+   *                   supporting geometrical shape, if any.
    */
   const SMDS_MeshNode* GetMediumNode(const SMDS_MeshNode* n1,
                                      const SMDS_MeshNode* n2,
                                      const bool force3d);
   /*!
-   * Auxilary function for filling myNLinkNodeMap
+   * \brief Return index and type of the shape (EDGE or FACE only) to set a medium node on
+   */
+  std::pair<int, TopAbs_ShapeEnum> GetMediumPos(const SMDS_MeshNode* n1,
+                                                const SMDS_MeshNode* n2);
+  /*!
+   * \brief Add a link in my data structure
    */
-  void AddNLinkNode(const SMDS_MeshNode* n1,
+  void AddTLinkNode(const SMDS_MeshNode* n1,
                     const SMDS_MeshNode* n2,
                     const SMDS_MeshNode* n12);
-  /**
-   * Auxilary function for filling myNLinkNodeMap
+  /*!
+   * \brief Add many links in my data structure
    */
-  void AddNLinkNodeMap(const NLinkNodeMap& aMap)
-    { myNLinkNodeMap.insert(aMap.begin(), aMap.end()); }
+  void AddTLinkNodeMap(const TLinkNodeMap& aMap)
+    { myTLinkNodeMap.insert(aMap.begin(), aMap.end()); }
+
+  void AddTLinks(const SMDS_MeshEdge*   edge);
+  void AddTLinks(const SMDS_MeshFace*   face);
+  void AddTLinks(const SMDS_MeshVolume* vol);
 
   /**
-   * Returns myNLinkNodeMap
+   * Returns myTLinkNodeMap
    */
-  const NLinkNodeMap& GetNLinkNodeMap() const { return myNLinkNodeMap; }
+  const TLinkNodeMap& GetTLinkNodeMap() const { return myTLinkNodeMap; }
 
   /**
    * Check mesh without geometry for: if all elements on this shape are quadratic,
@@ -333,6 +520,8 @@ public:
   enum MType{ LINEAR, QUADRATIC, COMP };
   MType IsQuadraticMesh();
   
+  virtual ~SMESH_MesherHelper();
+
 protected:
 
   /*!
@@ -343,26 +532,38 @@ protected:
    */
   gp_Pnt2d GetUVOnSeam( const gp_Pnt2d& uv1, const gp_Pnt2d& uv2 ) const;
 
+  const SMDS_MeshNode* getMediumNodeOnComposedWire(const SMDS_MeshNode* n1,
+                                                   const SMDS_MeshNode* n2,
+                                                   bool                 force3d);
  private:
 
   // Forbiden copy constructor
   SMESH_MesherHelper (const SMESH_MesherHelper& theOther) {};
 
   // special map for using during creation of quadratic elements
-  NLinkNodeMap    myNLinkNodeMap;
+  TLinkNodeMap    myTLinkNodeMap;
 
   std::set< int > myDegenShapeIds;
   std::set< int > mySeamShapeIds;
-  double          myPar1, myPar2; // bounds of a closed periodic surface
-  int             myParIndex;     // bounds' index (1-U, 2-V)
+  double          myPar1[2], myPar2[2]; // U and V bounds of a closed periodic surface
+  int             myParIndex;     // bounds' index (1-U, 2-V, 3-both)
+
+  typedef std::map< int, GeomAPI_ProjectPointOnSurf* > TID2ProjectorOnSurf;
+  TID2ProjectorOnSurf myFace2Projector;
+  typedef std::map< int, GeomAPI_ProjectPointOnCurve* > TID2ProjectorOnCurve;
+  TID2ProjectorOnCurve myEdge2Projector;
 
   TopoDS_Shape    myShape;
   SMESH_Mesh*     myMesh;
   int             myShapeID;
 
-  // to create quadratic elements
   bool            myCreateQuadratic;
   bool            mySetElemOnShape;
+  bool            myFixNodeParameters;
+
+  std::map< int,bool > myNodePosShapesValidity;
+  bool toCheckPosOnShape(int shapeID ) const;
+  void setPosOnShapeValidity(int shapeID, bool ok ) const;
 
 };
 
diff --git a/src/SMESH/SMESH_Octree.cxx b/src/SMESH/SMESH_Octree.cxx
deleted file mode 100644 (file)
index 6345708..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-//  SMESH  SMESH_Octree : global Octree implementation
-// File      : SMESH_Octree.cxx
-// Created   : Tue Jan 16 16:00:00 2007
-// Author    : Nicolas Geimer & Aurélien Motteux(OCC)
-// Module    : SMESH
-//
-#include "SMESH_Octree.hxx"
-
-//===========================================================================
-/*!
- * \brief SMESH_Octree Constructor
- * \param maxLevel     - The level max the octree can reach (If <0 unlimited)
- */
-//===========================================================================
-SMESH_Octree::SMESH_Octree (const int maxLevel, const double minBoxSize):
-    myChildren(NULL),
-    myFather(NULL),
-    myLevel(0),
-    myMaxLevel(maxLevel),
-    myMinBoxSize(minBoxSize),
-    myIsLeaf(-1)
-{
-  myBox = new Bnd_B3d();
-}
-
-//======================================
-/*!
- * \brief SMESH_Octree Destructor
- */
-//======================================
-SMESH_Octree::~SMESH_Octree ()
-{
-  if(myChildren != NULL)
-  {
-    if(!myIsLeaf)
-    {
-      for(int i = 0; i<8; i++)
-        delete myChildren[i];
-      delete[] myChildren ;
-    }
-  }
-  delete myBox;
-}
-
-//===========================================================================
-/*!
- * \brief Set the bounding box of the Octree
- * \param box          - 3d Bounding Box of the Octree
- */
-//===========================================================================
-void SMESH_Octree::setBox(const Bnd_B3d* box)
-{
-//   delete myBox;
-//   myBox=new Bnd_B3d(*box);
-  *myBox = *box;
-}
-
-//===========================================================================
-/*!
- * \brief Set box to the 3d Bounding Box of the Octree
- * \param box          - Set box to the 3d Bounding Box of the Octree
- */
-//===========================================================================
-void SMESH_Octree::getBox(Bnd_B3d& box)
-{
-//   if(box != NULL)
-//     delete box;
-//   box = new Bnd_B3d (*myBox);
-  box = *myBox;
-}
-
-//===========================================================================
-/*!
- * \brief Set the max level of the Octree
- * \param maxLevel     - The level max the octree can reach (If <0 unlimited)
- */
-//===========================================================================
-void SMESH_Octree::setMaxLevel(const int maxLevel)
-{myMaxLevel = maxLevel;}
-
-
-//===========================================================================
-/*!
- * \brief Compute the bigger dimension of the box
- * \param box          - 3d Box
- * \retval double - bigger dimension of the box
- */
-//===========================================================================
-double SMESH_Octree::maxSize(const Bnd_B3d* box)
-{
-  if(box ==NULL)
-    return 0;
-  gp_XYZ min = box->CornerMin();
-  gp_XYZ max = box->CornerMax();
-  gp_XYZ Size = (max - min);
-  double returnVal = (Size.X()>Size.Y())?Size.X():Size.Y();
-  return (returnVal>Size.Z())?returnVal:Size.Z();
-}
-
-//=============================
-/*!
- * \brief Compute the Octree
- */
-//=============================
-void SMESH_Octree::Compute()
-{
-  // As soon as the Octree is a Leaf, I stop building his children
-  if(!isLeaf())
-    buildChildren();
-}
-
-//=================================================================
-/*!
- * \brief Build the 8 children boxes and call buildChildrenData()
- */
-//=================================================================
-void SMESH_Octree::buildChildren()
-{
-  myChildren = new SMESH_Octree*[8];
-
-  gp_XYZ min = myBox->CornerMin();
-  gp_XYZ max = myBox->CornerMax();
-  gp_XYZ HSize = (max - min)/2.;
-  gp_XYZ mid = min + HSize;
-  gp_XYZ childHsize = HSize/2.;
-
-  Standard_Real XminChild, YminChild, ZminChild;
-  Bnd_B3d* box;
-  gp_XYZ minChild;
-  for (int i =0; i<8; i++)
-  {
-    // We build the eight boxes, we need 2 points to do that.
-    // Min, and Mid
-    // In binary, we can write i from 0 to 7
-    // For instance :
-    // 5 is 101, it corresponds here in coordinates to ZYX
-    // If coordinate is 0 in Y-> box from Ymin to Ymid
-    // If coordinate is 1 in Y-> box from Ymid to Ymax
-    // Same scheme for X and Z
-    // I need the minChild to build the Bnd_B3d box.
-
-    XminChild= (i%2==0)?min.X():mid.X();
-    YminChild= ((i%4)/2==0)?min.Y():mid.Y();
-    ZminChild= (i<4)?min.Z():mid.Z();
-    minChild.SetCoord(XminChild, YminChild, ZminChild);
-
-    box = new Bnd_B3d(minChild+childHsize,childHsize);
-    // The child is of the same type than its father (For instance, a SMESH_OctreeNode)
-    // We allocate the memory we need fot the child
-    myChildren[i] = allocateOctreeChild();
-    // and we assign to him its box.
-    myChildren[i]->setBox(box);
-    delete box;
-  }
-
-  // After building the 8 boxes, we put the data into the children..
-  buildChildrenData();
-
-  //After we pass to the next level of the Octree
-  for (int i =0; i<8; i++)
-    myChildren[i]->Compute();
-}
diff --git a/src/SMESH/SMESH_Octree.hxx b/src/SMESH/SMESH_Octree.hxx
deleted file mode 100644 (file)
index 1d40b39..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-//  SMESH SMESH_Octree : global Octree implementation
-// File      : SMESH_Octree.hxx
-// Created   : Tue Jan 16 16:00:00 2007
-// Author    : Nicolas Geimer & Aurélien Motteux (OCC)
-// Module    : SMESH
-//
-#ifndef _SMESH_OCTREE_HXX_
-#define _SMESH_OCTREE_HXX_
-
-#include <Bnd_B3d.hxx>
-
-class SMESH_Octree {
-
-public:
-  // Constructor
-  SMESH_Octree (const int maxLevel = -1, const double minBoxSize = 0.);
-
-  // Destructor
-  virtual ~SMESH_Octree ();
-
-  // Tell if Octree is a leaf or not (has to be implemented in inherited classes)
-  virtual const bool     isLeaf() = 0;
-
-  // Compute the Octree
-  void                   Compute();
-
-  // Set the maximal level of the Octree
-  void                   setMaxLevel(const int maxLevel);
-
-  // Set the minimal size of the Box
-  void                   setMinBoxSize(const double minBoxSize){myMinBoxSize = minBoxSize;};
-
-  // Set the bounding box of the Octree
-  void                   setBox(const Bnd_B3d* box);
-
-  // Set box to the 3d Bounding Box of the Octree
-  void                   getBox(Bnd_B3d & box);
-
-  // Compute the bigger dimension of the box
-  static double          maxSize(const Bnd_B3d* box);
-
-  // Return its level
-  int                    level() const { return myLevel; }
-
-protected:
-  // Constructor for children (has to be implemented in inherited classes)
-  virtual SMESH_Octree* allocateOctreeChild() = 0;
-
-  // Build the 8 children boxes
-  void buildChildren();
-
-  // Build the data in the 8 children (has to be implemented in inherited classes)
-  virtual void buildChildrenData() = 0;
-
-  // members
-
-  // Box of the Octree
-  Bnd_B3d*       myBox;
-
-  // Array of 8 Octree children
-  SMESH_Octree** myChildren;
-
-  // Point the father, set to NULL for the level 0
-  SMESH_Octree*  myFather;
-
-  // Level of the Octree
-  int            myLevel;
-
-  // MaxLevel of the Octree
-  int            myMaxLevel;
-
-  // Minimal size of the Box
-  double         myMinBoxSize;
-
-  // Tell us if the Octree is a leaf or not (-1 if not initialized)
-  int            myIsLeaf;
-};
-#endif
diff --git a/src/SMESH/SMESH_OctreeNode.cxx b/src/SMESH/SMESH_OctreeNode.cxx
deleted file mode 100644 (file)
index 48e8c5a..0000000
+++ /dev/null
@@ -1,352 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-//  SMESH SMESH_OctreeNode : Octree with Nodes set
-//  inherites global class SMESH_Octree
-// File      : SMESH_OctreeNode.cxx
-// Created   : Tue Jan 16 16:00:00 2007
-// Author    : Nicolas Geimer & Aurélien Motteux (OCC)
-// Module    : SMESH
-//
-#include "SMESH_OctreeNode.hxx"
-
-#include "SMDS_MeshNode.hxx"
-#include "SMDS_SetIterator.hxx"
-#include <gp_Pnt.hxx>
-
-using namespace std;
-
-//===============================================================
-/*!
- * \brief Constructor : Build all the Octree using Compute()
- * \param theNodes - Set of nodes, the Octree is built from this nodes
- * \param maxLevel - Maximum level for the leaves
- * \param maxNbNodes - Maximum number of nodes, a leaf can contain
- * \param minBoxSize - Minimal size of the Octree Box
- */
-//================================================================
-SMESH_OctreeNode::SMESH_OctreeNode (const set<const SMDS_MeshNode*> & theNodes, const int maxLevel,
-                                    const int maxNbNodes , const double minBoxSize )
-  :SMESH_Octree(maxLevel,minBoxSize),
-  myMaxNbNodes(maxNbNodes),
-  myNodes(theNodes)
-{
-  // We need to compute the first bounding box via a special method
-  computeBoxForFather();
-  myNbNodes = myNodes.size();
-  myIsLeaf = (myLevel == myMaxLevel)||(myNbNodes<=myMaxNbNodes)||(myMinBoxSize>=maxSize(myBox));
-  // All the children (Boxes and Data) are computed in Compute()
-  Compute();
-}
-
-//==================================================================================
-/*!
- * \brief Construct an empty SMESH_OctreeNode used by SMESH_Octree::buildChildren()
- */
-//==================================================================================
-SMESH_Octree* SMESH_OctreeNode::allocateOctreeChild()
-{
-  SMESH_OctreeNode * theOctree = new SMESH_OctreeNode();
-  theOctree->myFather = this;
-  theOctree->myLevel = myLevel + 1;
-  theOctree->myMaxLevel = myMaxLevel;
-  theOctree->myMaxNbNodes = myMaxNbNodes;
-  theOctree->myMinBoxSize = myMinBoxSize;
-  theOctree->myNbNodes = 0;
-  return theOctree;
-}
-
-
-
-//======================================
-/*!
- * \brief Compute the first bounding box
- *
- * We take the max/min coord of  the nodes
- */
-//======================================
-void SMESH_OctreeNode::computeBoxForFather()
-{
-  set<const SMDS_MeshNode*>::iterator it=myNodes.begin();
-  for( ;it!=myNodes.end();it++){
-    const SMDS_MeshNode* n1 = *it;
-    gp_XYZ p1( n1->X(), n1->Y(), n1->Z() );
-    myBox->Add(p1);
-  }
-}
-
-//====================================================================================
-/*!
- * \brief Tell if Octree is a leaf or not (has to be implemented in inherited classes)
- * \retval      - True if the Octree is a leaf
- */
-//====================================================================================
-const bool SMESH_OctreeNode::isLeaf()
-{
-  return myIsLeaf;
-}
-
-//====================================================================================
-/*!
- * \brief Tells us if Node is inside the current box with the precision "precision"
- * \param Node - Node
- * \param precision - The box is enlarged with this precision
- * \retval bool - True if Node is in the box within precision
- */
-//====================================================================================
-const bool SMESH_OctreeNode::isInside(const SMDS_MeshNode * Node, const double precision )
-{
-  double X=Node->X();
-  double Y=Node->Y();
-  double Z=Node->Z();
-  bool Out = 1 ;
-  if (precision<=0.)
-     return !(myBox->IsOut(gp_XYZ(X,Y,Z)));
-  Bnd_B3d BoxWithPrecision;
-  getBox(BoxWithPrecision);
-  BoxWithPrecision.Enlarge(precision);
-  Out=BoxWithPrecision.IsOut(gp_XYZ(X,Y,Z));
-  return !(Out);
-}
-
-
-//================================================
-/*!
- * \brief Set the data of the children
- * Shares the father's data with each of his child
- */
-//================================================
-void SMESH_OctreeNode::buildChildrenData()
-{
-  gp_XYZ min = myBox->CornerMin();
-  gp_XYZ max = myBox->CornerMax();
-  gp_XYZ mid = (min + max)/2.;
-
-  set<const SMDS_MeshNode*>::iterator it=myNodes.begin();
-  int ChildBoxNum;
-  while( it!=myNodes.end())
-  {
-    const SMDS_MeshNode* n1 = *it;
-    ChildBoxNum= (n1->X()>mid.X()) + (n1->Y()>mid.Y())*2 + (n1->Z()>mid.Z())*4;
-    SMESH_OctreeNode* myChild = dynamic_cast<SMESH_OctreeNode*> (myChildren[ChildBoxNum]);
-    myChild->myNodes.insert(myChild->myNodes.end(),n1);
-    myNodes.erase( it );
-    it=myNodes.begin();
-  }
-  for (int i = 0; i<8; i++)
-  {
-    SMESH_OctreeNode* myChild = dynamic_cast<SMESH_OctreeNode*> (myChildren[i]);
-    myChild->myNbNodes = (myChild->myNodes).size();
-    myChild->myIsLeaf = (myChild->myLevel == myMaxLevel)||(myChild->myNbNodes<=myMaxNbNodes)||(myMinBoxSize>=maxSize(myChild->myBox));
-  }
-}
-
-//===================================================================
-/*!
- * \brief Return in Result a list of Nodes potentials to be near Node
- * \param Node - Node
- * \param precision - precision used
- * \param Result - list of Nodes potentials to be near Node
- */
-//====================================================================
-void SMESH_OctreeNode::NodesAround( const SMDS_MeshNode * Node,
-                                    list<const SMDS_MeshNode*>* Result, const double precision)
-{
-  if (isInside(Node,precision))
-  {
-    if (myIsLeaf)
-    {
-      Result->insert( Result->end(), myNodes.begin(), myNodes.end() );
-    }
-    else
-    {
-      for(int i=0;i<8;i++)
-      {
-        SMESH_OctreeNode* myChild = dynamic_cast<SMESH_OctreeNode*> (myChildren[i]);
-        myChild->NodesAround( Node, Result, precision);
-      }
-    }
-  }
-}
-
-
-
-//=============================
-/*!
- * \brief  Return in theGroupsOfNodes a list of group of nodes close to each other within theTolerance
- * Search for all the nodes in nodes
- * Static Method : no need to create an SMESH_OctreeNode
- * \param nodes - set of nodes we look at, modified during research
- * \param theGroupsOfNodes - list of nodes closed to each other returned
- * \param theTolerance - Precision used, default value is 0.00001
- * \param maxLevel - Maximum level for SMESH_OctreeNode constructed, default value is -1 (Infinite)
- * \param maxNbNodes - maximum Nodes in a Leaf of the SMESH_OctreeNode constructed, default value is 5
- */
-//=============================
-void SMESH_OctreeNode::FindCoincidentNodes ( set<const SMDS_MeshNode*> nodes,
-                                             list< list< const SMDS_MeshNode*> >* theGroupsOfNodes,
-                                             const double theTolerance, const int maxLevel,
-                                             const int maxNbNodes)
-{
-  SMESH_OctreeNode* theOctreeNode = new SMESH_OctreeNode(nodes, maxLevel, maxNbNodes, theTolerance);
-  theOctreeNode->FindCoincidentNodes (&nodes, theTolerance, theGroupsOfNodes);
-  delete theOctreeNode;
-}
-
-
-//=============================
-/*!
- * \brief  Return in theGroupsOfNodes a list of group of nodes close to each other within theTolerance
- * Search for all the nodes in nodes
- * \param nodes - set of nodes we look at, modified during research
- * \param theTolerance - Precision used
- * \param theGroupsOfNodes - list of nodes closed to each other returned
- */
-//=============================
-void SMESH_OctreeNode::FindCoincidentNodes ( set<const SMDS_MeshNode*>* nodes,
-                                             const double                theTolerance,
-                                             list< list< const SMDS_MeshNode*> >* theGroupsOfNodes)
-{
-  set<const SMDS_MeshNode*>::iterator it1 = nodes->begin();
-  list<const SMDS_MeshNode*>::iterator it2;
-
-  while (it1 != nodes->end())
-  {
-    const SMDS_MeshNode * n1 = *it1;
-
-    list<const SMDS_MeshNode*> ListofCoincidentNodes;// Initialize the lists via a declaration, it's enough
-
-    list<const SMDS_MeshNode*> * groupPtr = 0;
-
-    // Searching for Nodes around n1 and put them in ListofCoincidentNodes
-    FindCoincidentNodes(n1, nodes, &ListofCoincidentNodes, theTolerance);
-
-    // We build a list {n1 + his neigbours} and add this list in theGroupsOfNodes
-    for (it2=ListofCoincidentNodes.begin();it2 != ListofCoincidentNodes.end(); it2++)
-    {
-      const SMDS_MeshNode* n2 = *it2;
-      if ( !groupPtr )
-      {
-        theGroupsOfNodes->push_back( list<const SMDS_MeshNode*>() );
-        groupPtr = & theGroupsOfNodes->back();
-        groupPtr->push_back( n1 );
-      }
-      if(groupPtr->front()>n2)
-        groupPtr->push_front( n2 );
-      else
-        groupPtr->push_back( n2 );
-    }
-    if(groupPtr != 0)
-      groupPtr->sort();
-
-    nodes->erase(it1);
-    it1=nodes->begin();
-  }
-}
-
-//======================================================================================
-/*!
- * \brief Return a list of nodes closed to Node and remove it from SetOfNodes
- * \param Node - We're searching the nodes next to him.
- * \param SetOfNodes - set of nodes in which we erase the found nodes
- * \param Result - list of nodes closed to Node
- * \param precision - Precision used
- */
-//======================================================================================
-void SMESH_OctreeNode::FindCoincidentNodes( const SMDS_MeshNode * Node,
-                                            set<const SMDS_MeshNode*>* SetOfNodes,
-                                            list<const SMDS_MeshNode*>* Result,
-                                            const double precision)
-{
-  bool isInsideBool = isInside(Node,precision);
-
-  if (isInsideBool)
-  {
-    // I'm only looking in the leaves, since all the nodes are stored there.
-    if (myIsLeaf)
-    {
-      gp_Pnt p1( Node->X(), Node->Y(), Node->Z() );
-
-      set<const SMDS_MeshNode*> myNodesCopy = myNodes;
-      set<const SMDS_MeshNode*>::iterator it = myNodesCopy.begin();
-      double tol2 = precision * precision;
-      bool squareBool;
-
-      while (it != myNodesCopy.end())
-      {
-        const SMDS_MeshNode* n2 = *it;
-        // We're only looking at nodes with a superior Id.
-        if(Node->GetID() < n2->GetID())
-        {
-          gp_Pnt p2( n2->X(), n2->Y(), n2->Z() );
-          // Distance optimized computation
-          squareBool = (p1.SquareDistance( p2 ) <= tol2);
-
-          // If n2 inside  the SquareDistance, we add it in Result and remove it from SetOfNodes and myNodes
-          if(squareBool)
-          {
-            Result->insert(Result->begin(), n2);
-            SetOfNodes->erase( n2 );
-            myNodes.erase( n2 );
-          }
-        }
-        myNodesCopy.erase( it );
-        it = myNodesCopy.begin();
-      }
-
-    }
-    else
-    {
-      // If I'm not a leaf, I'm going to see my children !
-      for(int i = 0; i < 8; i++)
-      {
-        SMESH_OctreeNode* myChild = dynamic_cast<SMESH_OctreeNode*> (myChildren[i]);
-        myChild->FindCoincidentNodes(Node,  SetOfNodes, Result, precision);
-      }
-    }
-  }
-}
-
-//================================================================================
-/*!
- * \brief Return iterator over children
- */
-//================================================================================
-
-SMESH_OctreeNodeIteratorPtr SMESH_OctreeNode::GetChildrenIterator()
-{
-  return SMESH_OctreeNodeIteratorPtr
-    ( new SMDS_SetIterator< SMESH_OctreeNode*, SMESH_Octree** >
-      ( myChildren, ( isLeaf() ? myChildren : &myChildren[ 8 ] )));
-}
-
-//================================================================================
-/*!
- * \brief Return nodes iterator
- */
-//================================================================================
-
-SMDS_NodeIteratorPtr SMESH_OctreeNode::GetNodeIterator()
-{
-  return SMDS_NodeIteratorPtr
-    ( new SMDS_SetIterator< SMDS_pNode, set< SMDS_pNode >::const_iterator >
-      ( myNodes.begin(), myNodes.end() ));
-}
diff --git a/src/SMESH/SMESH_OctreeNode.hxx b/src/SMESH/SMESH_OctreeNode.hxx
deleted file mode 100644 (file)
index 54ab75c..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-//  SMESH SMESH_OctreeNode : Octree with Nodes set
-//  inherites global class SMESH_Octree
-// File      : SMESH_OctreeNode.hxx
-// Created   : Tue Jan 16 16:00:00 2007
-// Author    : Nicolas Geimer & Aurélien Motteux  (OCC)
-// Module    : SMESH
-//
-#ifndef _SMESH_OCTREENODE_HXX_
-#define _SMESH_OCTREENODE_HXX_
-
-#include "SMESH_Octree.hxx"
-
-#include <list>
-#include <set>
-
-#include "SMDS_ElemIterator.hxx"
-
-//forward declaration
-class SMDS_MeshNode;
-class SMESH_OctreeNode;
-
-typedef SMDS_Iterator<SMESH_OctreeNode*>            SMESH_OctreeNodeIterator;
-typedef boost::shared_ptr<SMESH_OctreeNodeIterator> SMESH_OctreeNodeIteratorPtr;
-
-class SMESH_OctreeNode : public SMESH_Octree{
-
-public:
-
-  // Constructor
-  SMESH_OctreeNode (const std::set<const SMDS_MeshNode*>& theNodes, const int maxLevel = -1,
-                    const int maxNbNodes = 5 , const double minBoxSize = 0.);
-
-//=============================
-/*!
- * \brief Empty destructor
- */
-//=============================
-  virtual ~SMESH_OctreeNode () {};
-
-  // Tells us if SMESH_OctreeNode is a leaf or not (-1 = not initialiazed)
-  virtual const bool isLeaf();
-
-  // Tells us if Node is inside the current box with the precision "precision"
-  virtual const bool isInside(const SMDS_MeshNode * Node, const double precision = 0. );
-
-  // Return in Result a list of Nodes potentials to be near Node
-  void               NodesAround( const SMDS_MeshNode * Node , std::list<const SMDS_MeshNode*>* Result,
-                                  const double precision = 0. );
-
-  // Return in theGroupsOfNodes a list of group of nodes close to each other within theTolerance
-  // Search for all the nodes in nodes
-  void               FindCoincidentNodes ( std::set<const SMDS_MeshNode*>* nodes,
-                                           const double                theTolerance,
-                                           std::list< std::list< const SMDS_MeshNode*> >* theGroupsOfNodes);
-
-  // Static method that return in theGroupsOfNodes a list of group of nodes close to each other within
-  // theTolerance search for all the nodes in nodes
-  static void        FindCoincidentNodes ( std::set<const SMDS_MeshNode*> nodes,
-                                           std::list< std::list< const SMDS_MeshNode*> >* theGroupsOfNodes,
-                                           const double theTolerance = 0.00001, const int maxLevel = -1,
-                                           const int maxNbNodes = 5);
-  /*!
-   * \brief Return iterator over children
-   */
-  SMESH_OctreeNodeIteratorPtr GetChildrenIterator();
-  /*!
-   * \brief Return nodes iterator
-   */
-  SMDS_NodeIteratorPtr        GetNodeIterator();
-  /*!
-   * \brief Return nb nodes in a tree
-   */
-  int                         NbNodes() const { return myNbNodes; }
-
-protected:
-
-//=============================
-/*!
- * \brief Empty constructor
- */
-//=============================
-  SMESH_OctreeNode (){};
-
-  // Shares the father's data with each of his child
-  virtual void          buildChildrenData();
-
-  // Compute the bounding box of the whole set of nodes myNodes (only used for OctreeNode level 0)
-  void                  computeBoxForFather();
-
-  // Construct an empty SMESH_OctreeNode used by SMESH_Octree::buildChildren()
-  virtual SMESH_Octree* allocateOctreeChild();
-
-  // Return in result a list of nodes closed to Node and remove it from SetOfNodes
-  void                  FindCoincidentNodes( const SMDS_MeshNode * Node,
-                                             std::set<const SMDS_MeshNode*>* SetOfNodes,
-                                             std::list<const SMDS_MeshNode*>* Result,
-                                             const double precision);
-
-  // The max number of nodes a leaf box can contain
-  int                         myMaxNbNodes;
-
-  // The set of nodes inside the box of the Octree (Empty if Octree is not a leaf)
-  std::set<const SMDS_MeshNode*>   myNodes;
-
-  // The number of nodes I have inside the box
-  int                         myNbNodes;
-};
-#endif
index 7b5746773c01e00c832b1e6fc5c1909f7e2ca9a4..cc493ca3439cfed759fbb3153f1a8a1518d2ecb1 100644 (file)
@@ -1,28 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File      : SMESH_Pattern.hxx
 // Created   : Mon Aug  2 10:30:00 2004
 // Author    : Edward AGAPOV (eap)
-//
+
 #include "SMESH_Pattern.hxx"
 
 #include <BRepAdaptor_Curve.hxx>
@@ -39,6 +40,7 @@
 #include <GeomAdaptor_Surface.hxx>
 #include <Geom_Curve.hxx>
 #include <Geom_Surface.hxx>
+#include <Precision.hxx>
 #include <TopAbs_ShapeEnum.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 #include "SMESHDS_SubMesh.hxx"
 #include "SMESH_Block.hxx"
 #include "SMESH_Mesh.hxx"
-#include "SMESH_MeshEditor.hxx"
+#include "SMESH_MesherHelper.hxx"
 #include "SMESH_subMesh.hxx"
 
+#include <Basics_OCCTVersion.hxx>
+
+#include <Basics_Utils.hxx>
 #include "utilities.h"
 
 using namespace std;
@@ -209,6 +214,8 @@ bool SMESH_Pattern::Load (const char* theFileContents)
 {
   MESSAGE("Load( file ) ");
 
+  Kernel_Utils::Localizer loc;
+  
   // file structure:
 
   // ! This is a comment
@@ -352,6 +359,9 @@ bool SMESH_Pattern::Load (const char* theFileContents)
 bool SMESH_Pattern::Save (ostream& theFile)
 {
   MESSAGE(" ::Save(file) " );
+  
+  Kernel_Utils::Localizer loc;
+    
   if ( !IsLoaded() ) {
     MESSAGE(" Pattern not loaded ");
     return setErrorCode( ERR_SAVE_NOT_LOADED );
@@ -436,8 +446,13 @@ static gp_XY project (const SMDS_MeshNode* theNode,
   }
   double u, v, minVal = DBL_MAX;
   for ( int i = theProjectorPS.NbExt(); i > 0; i-- )
+#if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
+    if ( theProjectorPS.SquareDistance( i ) < minVal ) {
+      minVal = theProjectorPS.SquareDistance( i );
+#else
     if ( theProjectorPS.Value( i ) < minVal ) {
       minVal = theProjectorPS.Value( i );
+#endif
       theProjectorPS.Point( i ).Parameter( u, v );
     }
   return gp_XY( u, v );
@@ -456,8 +471,7 @@ template <class TFaceIterator> bool areNodesBound( TFaceIterator & faceItr )
     while ( nIt->more() )
     {
       const SMDS_MeshNode* node = smdsNode( nIt->next() );
-      SMDS_PositionPtr pos = node->GetPosition();
-      if ( !pos || !pos->GetShapeId() ) {
+      if (node->getshapeId() <1) {
         return false;
       }
     }
@@ -508,6 +522,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
 
   SMESHDS_Mesh * aMeshDS = theMesh->GetMeshDS();
   SMESHDS_SubMesh * fSubMesh = aMeshDS->MeshElements( theFace );
+  const bool isQuadMesh = aMeshDS->GetMeshInfo().NbFaces( ORDER_QUADRATIC );
   SMESH_MesherHelper helper( *theMesh );
   helper.SetSubShape( theFace );
 
@@ -576,15 +591,15 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
     {
       myElemPointIDs.push_back( TElemDef() );
       TElemDef& elemPoints = myElemPointIDs.back();
-      SMDS_ElemIteratorPtr nIt = (*fIt)->nodesIterator();
-      while ( nIt->more() )
+      int nbNodes = (*fIt)->NbCornerNodes();
+      for ( int i = 0;i < nbNodes; ++i )
       {
-        const SMDS_MeshElement* node = nIt->next();
-        TNodePointIDMap::iterator nIdIt = nodePointIDMap.find( node );
-        if ( nIdIt == nodePointIDMap.end() )
+        const SMDS_MeshElement* node = (*fIt)->GetNode( i );
+        TNodePointIDMap::iterator nIdIt = nodePointIDMap.insert( make_pair( node, -1 )).first;
+        if ( nIdIt->second == -1 )
         {
           elemPoints.push_back( iPoint );
-          nodePointIDMap.insert( make_pair( node, iPoint++ ));
+          nIdIt->second = iPoint++;
         }
         else
           elemPoints.push_back( (*nIdIt).second );
@@ -728,12 +743,17 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
         // loop on nodes of an edge: sort them by param on edge
         typedef map < double, const SMDS_MeshNode* > TParamNodeMap;
         TParamNodeMap paramNodeMap;
+        int nbMeduimNodes = 0;
         SMDS_NodeIteratorPtr nIt = eSubMesh->GetNodes();
         while ( nIt->more() )
         {
-          const SMDS_MeshNode* node = smdsNode( nIt->next() );
+          const SMDS_MeshNode* node = nIt->next();
+          if ( isQuadMesh && helper.IsMedium( node, SMDSAbs_Face )) {
+            ++nbMeduimNodes;
+            continue;
+          }
           const SMDS_EdgePosition* epos =
-            static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+            static_cast<const SMDS_EdgePosition*>(node->GetPosition());
           double u = epos->GetUParameter();
           paramNodeMap.insert( make_pair( u, node ));
         }
@@ -745,7 +765,9 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
           paramNodeMap.clear();
           nIt = eSubMesh->GetNodes();
           for ( int iNode = 0; nIt->more(); ++iNode ) {
-            const SMDS_MeshNode* node = smdsNode( nIt->next() );
+            const SMDS_MeshNode* node = nIt->next();
+            if ( isQuadMesh && helper.IsMedium( node, SMDSAbs_Face ))
+              continue;
             proj.Perform( gp_Pnt( node->X(), node->Y(), node->Z()));
             double u = 0;
             if ( proj.IsDone() ) {
@@ -759,7 +781,12 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
             }
             paramNodeMap.insert( make_pair( u, node ));
           }
+
+          //rnv : To fix the bug IPAL21999 Pattern Mapping - New - collapse of pattern mesh
+          if ( paramNodeMap.size() != eSubMesh->NbNodes() - nbMeduimNodes )
+            return setErrorCode(ERR_UNEXPECTED);
         }
+
         // put U in [0,1] so that the first key-point has U==0
         bool isSeam = helper.IsRealSeam( edge );
         double du = l - f;
@@ -842,7 +869,9 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
       SMDS_NodeIteratorPtr nIt = fSubMesh->GetNodes();
       while ( nIt->more() )
       {
-        const SMDS_MeshNode* node = smdsNode( nIt->next() );
+        const SMDS_MeshNode* node = nIt->next();
+        if ( isQuadMesh && helper.IsMedium( node, SMDSAbs_Face ))
+          continue;
         nodePointIDMap.insert( make_pair( node, iPoint ));
         TPoint* p = &myPoints[ iPoint++ ];
         fPoints.push_back( p );
@@ -850,7 +879,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
           p->myInitUV = project( node, projector );
         else {
           const SMDS_FacePosition* pos =
-            static_cast<const SMDS_FacePosition*>(node->GetPosition().get());
+            static_cast<const SMDS_FacePosition*>(node->GetPosition());
           p->myInitUV.SetCoord( pos->GetUParameter(), pos->GetVParameter() );
         }
         p->myInitXYZ.SetCoord( p->myInitUV.X(), p->myInitUV.Y(), 0 );
@@ -868,9 +897,12 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
         while ( nIt->more() )
         {
           const SMDS_MeshNode* node = smdsNode( nIt->next() );
-          iPoint = nodePointIDMap[ node ]; // point index of interest
+          n_id = nodePointIDMap.find( node );
+          if ( n_id == nodePointIDMap.end() )
+            continue; // medium node
+          iPoint = n_id->second; // point index of interest
           // for a node on a seam edge there are two points
-          if ( helper.IsRealSeam( node->GetPosition()->GetShapeId() ) &&
+          if ( helper.IsRealSeam( node->getshapeId() ) &&
                ( n_id = closeNodePointIDMap.find( node )) != not_found )
           {
             TPoint & p1 = myPoints[ iPoint ];
@@ -881,7 +913,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
             // find node not on a seam edge
             while ( nIt2->more() && !notSeamNode ) {
               const SMDS_MeshNode* n = smdsNode( nIt2->next() );
-              if ( !helper.IsSeamShape( n->GetPosition()->GetShapeId() ))
+              if ( !helper.IsSeamShape( n->getshapeId() ))
                 notSeamNode = n;
             }
             gp_Pnt2d uv = helper.GetNodeUV( theFace, node, notSeamNode );
@@ -894,6 +926,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
         }
       }
     }
+    myPoints.resize( nodePointIDMap.size() + closeNodePointIDMap.size() );
 
     myIsBoundaryPointsFound = true;
   }
@@ -1228,7 +1261,7 @@ static bool checkQuads (const TIsoNode* node,
         maxLen2 = Max( maxLen2, ( n[1]->myUV - n[2]->myUV ).SquareModulus() );
       }
       maxLen2 = Max( maxLen2, ( n[2]->myUV - node->myUV ).SquareModulus() );
-      minDiag = sqrt( maxLen2 ) * PI / 60.; // ~ maxLen * Sin( 3 deg )
+      minDiag = sqrt( maxLen2 ) * M_PI / 60.; // ~ maxLen * Sin( 3 deg )
     }
 
     // check if newUV is behind 3 dirs: n[0]-n[1], n[1]-n[2] and n[0]-n[2]
@@ -1779,7 +1812,7 @@ bool SMESH_Pattern::
     double initAngle = initTgt1.Angle( initTgt2 );
     double angle = node->myDir[0].Angle( node->myDir[1] );
     if ( reversed ) angle = -angle;
-    if ( initAngle > angle && initAngle - angle > PI / 2.1 ) {
+    if ( initAngle > angle && initAngle - angle > M_PI / 2.1 ) {
       // find a close internal node
       TIsoNode* nClose = 0;
       list< TIsoNode* > testNodes;
@@ -1873,7 +1906,7 @@ bool SMESH_Pattern::
 
   for ( nIt = startNodes.begin(); nIt != startNodes.end(); nIt++ )
   {
-    TIsoNode* prevN[2], *node = *nIt;
+    TIsoNode *node = *nIt;
     if ( node->IsUVComputed() || !node->IsMovable() )
       continue;
     gp_XY newUV( 0, 0 ), sumDir( 0, 0 );
@@ -1934,7 +1967,6 @@ bool SMESH_Pattern::
           newUV += prevNode1->myUV + dir * step[ iDir ];
         }
         sumDir += dir;
-        prevN[ iDir ] = prevNode1;
         nbComp++;
       }
     }
@@ -1996,7 +2028,7 @@ bool SMESH_Pattern::
       }
       // define ratio
       bool ok = true; // <- stupid fix TO AVOID PB OF NODES WITH NULL BND NODES
-      double locR[2] = { 0, 0 };
+//      double locR[2] = { 0, 0 };
       for ( iDir = 0; iDir < 2; iDir++ )
       {
         const int iCoord = 2 - iDir; // coord changing along an isoline
@@ -2010,7 +2042,7 @@ bool SMESH_Pattern::
         double par3 = bndNode2->myInitUV.Coord( iCoord );
         double r = ( par2 - par1 ) / ( par3 - par1 );
         r = Abs ( r - 0.5 ) * 2.0;  // [0,1] - distance from the middle
-        locR[ iDir ] = ( 1 - r * r ) * 0.25;
+//        locR[ iDir ] = ( 1 - r * r ) * 0.25;
       }
       //locR[0] = locR[1] = 0.25;
       // intersect the 2 lines and move a node
@@ -2589,8 +2621,9 @@ bool SMESH_Pattern::Apply (const SMDS_MeshFace* theFace,
   }
 
   // check nb of nodes
-  if (theFace->NbNodes() != myNbKeyPntInBoundary.front() ) {
-    MESSAGE( myKeyPointIDs.size() << " != " << theFace->NbNodes() );
+  const int nbFaceNodes = theFace->NbCornerNodes();
+  if ( nbFaceNodes != myNbKeyPntInBoundary.front() ) {
+    MESSAGE( myKeyPointIDs.size() << " != " << nbFaceNodes );
     return setErrorCode( ERR_APPL_BAD_NB_VERTICES );
   }
 
@@ -2609,7 +2642,7 @@ bool SMESH_Pattern::Apply (const SMDS_MeshFace* theFace,
   list< const SMDS_MeshNode* >::iterator n = nodes.end();
   SMDS_ElemIteratorPtr noIt = theFace->nodesIterator();
   int iSub = 0;
-  while ( noIt->more() ) {
+  while ( noIt->more() && iSub < nbFaceNodes ) {
     const SMDS_MeshNode* node = smdsNode( noIt->next() );
     nodes.push_back( node );
     if ( iSub++ == theNodeIndexOnKeyPoint1 )
@@ -2625,7 +2658,7 @@ bool SMESH_Pattern::Apply (const SMDS_MeshFace* theFace,
       nodes.splice( nodes.end(), nodes, nodes.begin(), n );
   }
   list< gp_XYZ > xyzList;
-  myOrderedNodes.resize( theFace->NbNodes() );
+  myOrderedNodes.resize( nbFaceNodes );
   for ( iSub = 0, n = nodes.begin(); n != nodes.end(); ++n ) {
     xyzList.push_back( gp_XYZ( (*n)->X(), (*n)->Y(), (*n)->Z() ));
     myOrderedNodes[ iSub++] = *n;
@@ -2980,7 +3013,7 @@ bool SMESH_Pattern::Apply (SMESH_Mesh*                     theMesh,
     }
     // put points on links to myIdsOnBoundary,
     // they will be used to sew new elements on adjacent refined elements
-    int nbNodes = (*face)->NbNodes(), eID = nbNodes + 1;
+    int nbNodes = (*face)->NbCornerNodes(), eID = nbNodes + 1;
     for ( int i = 0; i < nbNodes; i++ )
     {
       list< TPoint* > & linkPoints = getShapePoints( eID++ );
@@ -3140,6 +3173,8 @@ bool SMESH_Pattern::Load (SMESH_Mesh*         theMesh,
   myIs2D = false;
   SMESHDS_SubMesh * aSubMesh;
 
+  const bool isQuadMesh = theMesh->NbVolumes( ORDER_QUADRATIC );
+
   // load shapes in myShapeIDMap
   SMESH_Block block;
   TopoDS_Vertex v1, v2;
@@ -3172,6 +3207,8 @@ bool SMESH_Pattern::Load (SMESH_Mesh*         theMesh,
       // store a node and a point
     while ( nIt->more() ) {
       const SMDS_MeshNode* node = smdsNode( nIt->next() );
+      if ( isQuadMesh && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Volume ))
+        continue;
       nodePointIDMap.insert( make_pair( node, iPoint ));
       if ( block.IsVertexID( shapeID ))
         myKeyPointIDs.push_back( iPoint );
@@ -3206,9 +3243,11 @@ bool SMESH_Pattern::Load (SMESH_Mesh*         theMesh,
       nIt = aSubMesh->GetNodes();
       for ( ; nIt->more(); pIt++ )
       {
-        const SMDS_MeshNode* node = smdsNode( nIt->next() );
+        const SMDS_MeshNode* node = nIt->next();
+        if ( isQuadMesh && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge ))
+          continue;
         const SMDS_EdgePosition* epos =
-          static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+          static_cast<const SMDS_EdgePosition*>(node->GetPosition());
         double u = ( epos->GetUParameter() - f ) / ( l - f );
         (*pIt)->myInitXYZ.SetCoord( iCoord, isForward ? u : 1 - u );
       }
@@ -3232,11 +3271,12 @@ bool SMESH_Pattern::Load (SMESH_Mesh*         theMesh,
   {
     SMDS_ElemIteratorPtr elemIt = aSubMesh->GetElements();
     while ( elemIt->more() ) {
-      SMDS_ElemIteratorPtr nIt = elemIt->next()->nodesIterator();
+      const SMDS_MeshElement* elem = elemIt->next();
       myElemPointIDs.push_back( TElemDef() );
       TElemDef& elemPoints = myElemPointIDs.back();
-      while ( nIt->more() )
-        elemPoints.push_back( nodePointIDMap[ nIt->next() ]);
+      int nbNodes = elem->NbCornerNodes();
+      for ( int i = 0;i < nbNodes; ++i )
+        elemPoints.push_back( nodePointIDMap[ elem->GetNode( i )]);
     }
   }
 
@@ -3684,13 +3724,8 @@ bool SMESH_Pattern::
                      vector<int>&                          theQuantity)
 {
   bool makePoly = false;
-//   cout << "FROM FACE NODES: " <<endl;
-//   for ( int i = 0; i < theNbBndNodes; ++i )
-//     cout << theBndNodes[ i ];
 
-  set< const SMDS_MeshNode* > bndNodeSet;
-  for ( int i = 0; i < theNbBndNodes; ++i )
-    bndNodeSet.insert( theBndNodes[ i ]);
+  set< const SMDS_MeshNode* > bndNodeSet( theBndNodes, theBndNodes + theNbBndNodes);
 
   map< TNodeSet, list< list< int > > >::iterator nn_IdList;
 
@@ -3699,12 +3734,13 @@ bool SMESH_Pattern::
   if ( !myIs2D ) { // for 2D, merge only edges
     nn_IdList = myIdsOnBoundary.find( bndNodeSet );
     if ( nn_IdList != myIdsOnBoundary.end() ) {
-      makePoly = true;
       list< int > & faceIds = nn_IdList->second.front();
-      ids.insert( faceIds.begin(), faceIds.end() );
+      if ( !faceIds.empty() ) {
+        makePoly = true;
+        ids.insert( faceIds.begin(), faceIds.end() );
+      }
     }
   }
-  //bool hasIdsInFace = !ids.empty();
 
   // add ids on links and bnd nodes
   int lastFreeId = Max( myXYZIdToNodeMap.rbegin()->first, theNodes.size() );
@@ -3720,22 +3756,26 @@ bool SMESH_Pattern::
       bndId = nn_IdList->second.front().front();
       ids.insert( bndId );
     }
-    else
+    else {
       myXYZIdToNodeMap.insert( make_pair( bndId, theBndNodes[ iN ] ));
+    }
     faceDef.push_back( bndId );
     // add ids on a link
     TNodeSet linkNodes;
     linkNodes.insert( theBndNodes[ iN ]);
-    linkNodes.insert( theBndNodes[ iN + 1 == theNbBndNodes ? 0 : iN + 1 ]);
+    linkNodes.insert( theBndNodes[ (iN + 1) % theNbBndNodes] );
     nn_IdList = myIdsOnBoundary.find( linkNodes );
     if ( nn_IdList != myIdsOnBoundary.end() ) {
-      makePoly = true;
       list< int > & linkIds = nn_IdList->second.front();
-      ids.insert( linkIds.begin(), linkIds.end() );
-      if ( isReversed( theBndNodes[ iN ], linkIds ))
-        faceDef.insert( faceDef.end(), linkIds.begin(), linkIds.end() );
-      else
-        faceDef.insert( faceDef.end(), linkIds.rbegin(), linkIds.rend() );
+      if ( !linkIds.empty() )
+      {
+        makePoly = true;
+        ids.insert( linkIds.begin(), linkIds.end() );
+        if ( isReversed( theBndNodes[ iN ], linkIds ))
+          faceDef.insert( faceDef.end(), linkIds.begin(), linkIds.end() );
+        else
+          faceDef.insert( faceDef.end(), linkIds.rbegin(), linkIds.rend() );
+      }
     }
   }
 
@@ -3757,9 +3797,7 @@ bool SMESH_Pattern::
       {
         if ( !checkedVolDefs.insert( *pIdList ).second )
           continue; // skip already checked volume definition
-        vector< int > idVec;
-        idVec.reserve( (*pIdList)->size() );
-        idVec.insert( idVec.begin(), (*pIdList)->begin(), (*pIdList)->end() );
+        vector< int > idVec( (*pIdList)->begin(), (*pIdList)->end() );
         // loop on face defs of a volume
         SMDS_VolumeTool::VolumeType volType = vol.GetType( idVec.size() );
         if ( volType == SMDS_VolumeTool::UNKNOWN )
@@ -3789,7 +3827,7 @@ bool SMESH_Pattern::
   }
   if ( !defsAdded ) {
     theQuantity.push_back( faceDef.size() );
-    theFaceDefs.splice( theFaceDefs.end(), faceDef, faceDef.begin(), faceDef.end() );
+    theFaceDefs.splice( theFaceDefs.end(), faceDef );
   }
 
   return makePoly;
@@ -3853,7 +3891,7 @@ void SMESH_Pattern::clearMesh(SMESH_Mesh* theMesh) const
 //           coordinates computed by either of Apply...() methods
 // WARNING : StdMeshers_Projection_... relies on MakeMesh() behavior: that
 //           it does not care of nodes and elements already existing on
-//           subshapes. DO NOT MERGE them or modify also StdMeshers_Projection_..
+//           sub-shapes. DO NOT MERGE them or modify also StdMeshers_Projection_..
 //=======================================================================
 
 bool SMESH_Pattern::MakeMesh(SMESH_Mesh* theMesh,
@@ -3922,7 +3960,7 @@ bool SMESH_Pattern::MakeMesh(SMESH_Mesh* theMesh,
                                                 point->myXYZ.Z());
         nodesVector [ pIndex ] = node;
 
-        if ( true /*subMeshDS*/ ) {
+        if ( !S.IsNull() /*subMeshDS*/ ) {
           // !!!!! do not merge new nodes with ones existing on submeshes (see method comment)
           switch ( S.ShapeType() ) {
           case TopAbs_VERTEX: {
@@ -3960,6 +3998,8 @@ bool SMESH_Pattern::MakeMesh(SMESH_Mesh* theMesh,
     createElements( theMesh, nodesVector, myElemPointIDs, myElements );
   }
 
+  aMeshDS->compactMesh();
+
 //   const map<int,SMESHDS_SubMesh*>& sm = aMeshDS->SubMeshes();
 //   map<int,SMESHDS_SubMesh*>::const_iterator i_sm = sm.begin();
 //   for ( ; i_sm != sm.end(); i_sm++ )
@@ -4107,10 +4147,12 @@ void SMESH_Pattern::createElements(SMESH_Mesh*                            theMes
         SMDS_ElemIteratorPtr noIt = elem->nodesIterator();
         while ( noIt->more() ) {
           SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>(smdsNode( noIt->next() ));
-          if (!node->GetPosition()->GetShapeId() &&
+          if (!node->getshapeId() &&
               shellNodes.find( node ) == shellNodes.end() ) {
             if ( S.ShapeType() == TopAbs_FACE )
-              aMeshDS->SetNodeOnFace( node, shapeID );
+              aMeshDS->SetNodeOnFace( node, shapeID,
+                                      Precision::Infinite(),// <- it's a sign that UV is not set
+                                      Precision::Infinite());
             else {
               aMeshDS->SetNodeInVolume( node, shapeID );
               shellNodes.insert( node );
@@ -4540,6 +4582,29 @@ void SMESH_Pattern::Clear()
   myShapeIDMap.Clear();
   myShape.Nullify();
   myNbKeyPntInBoundary.clear();
+
+  myXYZ.clear();
+  myElemXYZIDs.clear();
+  myXYZIdToNodeMap.clear();
+  myElements.clear();
+  myOrderedNodes.clear();
+  myPolyElems.clear();
+  myPolyElemXYZIDs.clear();
+  myPolyhedronQuantities.clear();
+  myIdsOnBoundary.clear();
+  myReverseConnectivity.clear();
+}
+
+//================================================================================
+/*!
+ * \brief set ErrorCode and return true if it is Ok
+ */
+//================================================================================
+
+bool SMESH_Pattern::setErrorCode( const ErrorCode theErrorCode )
+{
+  myErrorCode = theErrorCode;
+  return myErrorCode == ERR_OK;
 }
 
 //=======================================================================
index ee87cbfb85d46582e2d9c97de759740a5458ca6b..2ba7666aa93790ec1e1ede12ab847505970bba24 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File      : SMESH_Pattern.hxx
 // Created   : Mon Aug  2 10:30:00 2004
 // Author    : Edward AGAPOV (eap)
@@ -190,7 +191,9 @@ class SMESH_EXPORT SMESH_Pattern {
     // Apply(mesh_face)
     ERR_APPLF_BAD_FACE_GEOM, // bad face geometry
     // MakeMesh
-    ERR_MAKEM_NOT_COMPUTED // mapping failed
+    ERR_MAKEM_NOT_COMPUTED, // mapping failed
+    //Unexpected error 
+    ERR_UNEXPECTED // Unexpected of the pattern mapping alorithm
   };
 
   ErrorCode GetErrorCode() const { return myErrorCode; }
@@ -241,8 +244,7 @@ private:
   };
   friend std::ostream & operator <<(std::ostream & OS, const TPoint& p);
 
-  bool setErrorCode( const ErrorCode theErrorCode )
-  { myErrorCode = theErrorCode; return myErrorCode == ERR_OK; }
+  bool setErrorCode( const ErrorCode theErrorCode );
   // set ErrorCode and return true if it is Ok
 
   bool setShapeToMesh(const TopoDS_Shape& theShape);
diff --git a/src/SMESH/SMESH_ProxyMesh.cxx b/src/SMESH/SMESH_ProxyMesh.cxx
new file mode 100644 (file)
index 0000000..a4e4f59
--- /dev/null
@@ -0,0 +1,545 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+// File      : SMESH_ProxyMesh.cxx
+// Created   : Thu Dec  2 12:32:53 2010
+// Author    : Edward AGAPOV (eap)
+
+#include "SMESH_ProxyMesh.hxx"
+
+#include "SMDS_IteratorOnIterators.hxx"
+#include "SMDS_SetIterator.hxx"
+#include "SMESH_MesherHelper.hxx"
+
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopExp.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+
+//================================================================================
+/*!
+ * \brief Constructor; mesh must be set by a descendant class
+ */
+//================================================================================
+
+SMESH_ProxyMesh::SMESH_ProxyMesh():_mesh(0)
+{
+}
+//================================================================================
+/*!
+ * \brief Make a proxy mesh from components. Components become empty
+ */
+//================================================================================
+
+SMESH_ProxyMesh::SMESH_ProxyMesh(vector<SMESH_ProxyMesh::Ptr>& components):
+  _mesh(0)
+{
+  if ( components.empty() ) return;
+
+  for ( unsigned i = 0; i < components.size(); ++i )
+  {
+    SMESH_ProxyMesh* m = components[i].get();
+    if ( !m ) continue;
+
+    takeTmpElemsInMesh( m );
+
+    if ( !_mesh ) _mesh = m->_mesh;
+    if ( _allowedTypes.empty() ) _allowedTypes = m->_allowedTypes;
+
+    if ( _subMeshes.size() < m->_subMeshes.size() )
+      _subMeshes.resize( m->_subMeshes.size(), 0 );
+    for ( unsigned j = 0; j < m->_subMeshes.size(); ++j )
+    {
+      if ( !m->_subMeshes[j] ) continue;
+      if ( _subMeshes[j] )
+      {
+        // unite 2 sub-meshes
+        set< const SMDS_MeshElement * > elems( _subMeshes[j]->_elements.begin(),
+                                               _subMeshes[j]->_elements.end());
+        elems.insert( m->_subMeshes[j]->_elements.begin(),
+                      m->_subMeshes[j]->_elements.end());
+        _subMeshes[j]->_elements.assign( elems.begin(), elems.end() );
+        m->_subMeshes[j]->_elements.clear();
+
+        if ( !_subMeshes[j]->_n2n )
+          _subMeshes[j]->_n2n = m->_subMeshes[j]->_n2n, m->_subMeshes[j]->_n2n = 0;
+
+        else if ( _subMeshes[j]->_n2n && m->_subMeshes[j]->_n2n )
+          _subMeshes[j]->_n2n->insert( m->_subMeshes[j]->_n2n->begin(),
+                                       m->_subMeshes[j]->_n2n->end());
+      }
+      else
+      {
+        _subMeshes[j] = m->_subMeshes[j];
+        m->_subMeshes[j] = 0;
+      }
+    }
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Destructor deletes proxy submeshes and tmp elemens
+ */
+//================================================================================
+
+SMESH_ProxyMesh::~SMESH_ProxyMesh()
+{
+  for ( unsigned i = 0; i < _subMeshes.size(); ++i )
+    delete _subMeshes[i];
+  _subMeshes.clear();
+
+  set< const SMDS_MeshElement* >::iterator i = _elemsInMesh.begin();
+  for ( ; i != _elemsInMesh.end(); ++i )
+    GetMeshDS()->RemoveFreeElement( *i, 0 );
+  _elemsInMesh.clear();
+}
+
+//================================================================================
+/*!
+ * \brief Returns index of a shape
+ */
+//================================================================================
+
+int SMESH_ProxyMesh::shapeIndex(const TopoDS_Shape& shape) const
+{
+  return ( shape.IsNull() || !_mesh->HasShapeToMesh() ? 0 : GetMeshDS()->ShapeToIndex(shape));
+}
+
+//================================================================================
+/*!
+ * \brief Returns the submesh of a shape; it can be a proxy sub-mesh
+ */
+//================================================================================
+
+const SMESHDS_SubMesh* SMESH_ProxyMesh::GetSubMesh(const TopoDS_Shape& shape) const
+{
+  const SMESHDS_SubMesh* sm = 0;
+
+  int i = shapeIndex(shape);
+  if ( i < _subMeshes.size() )
+    sm = _subMeshes[i];
+  if ( !sm )
+    sm = GetMeshDS()->MeshElements( i );
+
+  return sm;
+}
+
+//================================================================================
+/*!
+ * \brief Returns the proxy sub-mesh of a shape; it can be NULL
+ */
+//================================================================================
+
+const SMESH_ProxyMesh::SubMesh*
+SMESH_ProxyMesh::GetProxySubMesh(const TopoDS_Shape& shape) const
+{
+  int i = shapeIndex(shape);
+  return i < _subMeshes.size() ? _subMeshes[i] : 0;
+}
+
+//================================================================================
+/*!
+ * \brief Returns the proxy node of a node; the input node is returned if no proxy exists
+ */
+//================================================================================
+
+const SMDS_MeshNode* SMESH_ProxyMesh::GetProxyNode( const SMDS_MeshNode* node ) const
+{
+  const SMDS_MeshNode* proxy = node;
+  if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE )
+  {
+    if ( const SubMesh* proxySM = findProxySubMesh( node->getshapeId() ))
+      proxy = proxySM->GetProxyNode( node );
+  }
+  else
+  {
+    TopoDS_Shape shape = SMESH_MesherHelper::GetSubShapeByNode( node, GetMeshDS());
+    TopTools_ListIteratorOfListOfShape ancIt;
+    if ( !shape.IsNull() ) ancIt.Initialize( _mesh->GetAncestors( shape ));
+    for ( ; ancIt.More() && proxy == node; ancIt.Next() )
+      if ( const SubMesh* proxySM = findProxySubMesh( shapeIndex(ancIt.Value())))
+        proxy = proxySM->GetProxyNode( node );
+  }
+  return proxy;
+}
+
+namespace
+{
+  //================================================================================
+  /*!
+   * \brief Iterator filtering elements by type
+   */
+  //================================================================================
+
+  class TFilteringIterator : public SMDS_ElemIterator
+  {
+    SMDS_ElemIteratorPtr        _iter;
+    const SMDS_MeshElement *    _curElem;
+    vector< SMDSAbs_EntityType> _okTypes;
+  public:
+    TFilteringIterator( const vector< SMDSAbs_EntityType>& okTypes,
+                        const SMDS_ElemIteratorPtr&        elemIterator)
+      :_iter(elemIterator), _curElem(0), _okTypes(okTypes)
+    {
+      next();
+    }
+    virtual bool more()
+    {
+      return _curElem;
+    }
+    virtual const SMDS_MeshElement* next()
+    {
+      const SMDS_MeshElement* res = _curElem;
+      _curElem = 0;
+      while ( _iter->more() && !_curElem )
+      {
+        _curElem = _iter->next();
+        if ( find( _okTypes.begin(), _okTypes.end(), _curElem->GetEntityType()) == _okTypes.end())
+          _curElem = 0;
+      }
+      return res;
+    }
+  };
+}
+
+//================================================================================
+/*!
+ * \brief Returns iterator on all faces on the shape taking into account substitutions
+ */
+//================================================================================
+
+SMDS_ElemIteratorPtr SMESH_ProxyMesh::GetFaces(const TopoDS_Shape& shape) const
+{
+  if ( !_mesh->HasShapeToMesh() )
+    return SMDS_ElemIteratorPtr();
+
+  _subContainer.RemoveAllSubmeshes();
+
+  TopTools_IndexedMapOfShape FF;
+  TopExp::MapShapes( shape, TopAbs_FACE, FF );
+  for ( int i = 1; i <= FF.Extent(); ++i )
+    if ( const SMESHDS_SubMesh* sm = GetSubMesh( FF(i)))
+      _subContainer.AddSubMesh( sm );
+
+  return _subContainer.SMESHDS_SubMesh::GetElements();
+}
+
+//================================================================================
+/*!
+ * \brief Returns iterator on all faces of the mesh taking into account substitutions
+ * To be used in case of mesh without shape
+ */
+//================================================================================
+
+SMDS_ElemIteratorPtr SMESH_ProxyMesh::GetFaces() const
+{
+  if ( _mesh->HasShapeToMesh() )
+    return SMDS_ElemIteratorPtr();
+
+  _subContainer.RemoveAllSubmeshes();
+  for ( unsigned i = 0; i < _subMeshes.size(); ++i )
+    if ( _subMeshes[i] )
+      _subContainer.AddSubMesh( _subMeshes[i] );
+
+  if ( _subContainer.NbSubMeshes() == 0 ) // no elements substituted
+    return GetMeshDS()->elementsIterator(SMDSAbs_Face);
+
+  // if _allowedTypes is empty, only elements from _subMeshes are returned,...
+  SMDS_ElemIteratorPtr proxyIter = _subContainer.SMESHDS_SubMesh::GetElements();
+  if ( _allowedTypes.empty() || NbFaces() == _mesh->NbFaces() )
+    return proxyIter;
+
+  // ... else elements filtered using allowedTypes are additionally returned
+  SMDS_ElemIteratorPtr facesIter = GetMeshDS()->elementsIterator(SMDSAbs_Face);
+  SMDS_ElemIteratorPtr filterIter( new TFilteringIterator( _allowedTypes, facesIter ));
+  vector< SMDS_ElemIteratorPtr > iters(2);
+  iters[0] = proxyIter;
+  iters[1] = filterIter;
+    
+  typedef vector< SMDS_ElemIteratorPtr > TElemIterVector;
+  typedef SMDS_IteratorOnIterators<const SMDS_MeshElement *, TElemIterVector> TItersIter;
+  return SMDS_ElemIteratorPtr( new TItersIter( iters ));
+}
+
+//================================================================================
+/*!
+ * \brief Return total nb of faces taking into account substitutions
+ */
+//================================================================================
+
+int SMESH_ProxyMesh::NbFaces() const
+{
+  int nb = 0;
+  if ( _mesh->HasShapeToMesh() )
+  {
+    TopTools_IndexedMapOfShape FF;
+    TopExp::MapShapes( _mesh->GetShapeToMesh(), TopAbs_FACE, FF );
+    for ( int i = 1; i <= FF.Extent(); ++i )
+      if ( const SMESHDS_SubMesh* sm = GetSubMesh( FF(i)))
+        nb += sm->NbElements();
+  }
+  else
+  {
+    if ( _subMeshes.empty() )
+      return GetMeshDS()->NbFaces();
+
+    for ( unsigned i = 0; i < _subMeshes.size(); ++i )
+      if ( _subMeshes[i] )
+        nb += _subMeshes[i]->NbElements();
+
+    // if _allowedTypes is empty, only elements from _subMeshes are returned,
+    // else elements filtered using allowedTypes are additionally returned
+    if ( !_allowedTypes.empty() )
+    {
+      for ( int t = SMDSEntity_Triangle; t <= SMDSEntity_Quad_Quadrangle; ++t )
+      {
+        bool allowed =
+          ( find( _allowedTypes.begin(), _allowedTypes.end(), t ) != _allowedTypes.end() );
+        if ( allowed )
+          nb += GetMeshDS()->GetMeshInfo().NbEntities( SMDSAbs_EntityType( t ));
+      }
+    }
+  }
+  return nb;
+}
+
+//================================================================================
+/*!
+ * \brief Returns a proxy sub-mesh; it is created if not yet exists
+ */
+//================================================================================
+
+SMESH_ProxyMesh::SubMesh* SMESH_ProxyMesh::getProxySubMesh(int index)
+{
+  if ( int(_subMeshes.size()) <= index )
+    _subMeshes.resize( index+1, 0 );
+  if ( !_subMeshes[index] )
+    _subMeshes[index] = new SubMesh( index );
+  return _subMeshes[index];
+}
+
+//================================================================================
+/*!
+ * \brief Returns a proxy sub-mesh; it is created if not yet exists
+ */
+//================================================================================
+
+SMESH_ProxyMesh::SubMesh* SMESH_ProxyMesh::getProxySubMesh(const TopoDS_Shape& shape)
+{
+  return getProxySubMesh( shapeIndex( shape ));
+}
+
+//================================================================================
+/*!
+ * \brief Returns a proxy sub-mesh
+ */
+//================================================================================
+
+SMESH_ProxyMesh::SubMesh* SMESH_ProxyMesh::findProxySubMesh(int shapeIndex) const
+{
+  return shapeIndex < int(_subMeshes.size()) ? _subMeshes[shapeIndex] : 0;
+}
+
+//================================================================================
+/*!
+ * \brief Returns mesh DS
+ */
+//================================================================================
+
+SMESHDS_Mesh* SMESH_ProxyMesh::GetMeshDS() const
+{
+  return (SMESHDS_Mesh*)( _mesh ? _mesh->GetMeshDS() : 0 );
+}
+
+//================================================================================
+/*!
+ * \brief Move proxy sub-mesh from other proxy mesh to this, returns true if sub-mesh found
+ */
+//================================================================================
+
+bool SMESH_ProxyMesh::takeProxySubMesh( const TopoDS_Shape&   shape,
+                                             SMESH_ProxyMesh* proxyMesh )
+{
+  if ( proxyMesh && proxyMesh->_mesh == _mesh )
+  {
+    int iS = shapeIndex( shape );
+    if ( SubMesh* sm = proxyMesh->findProxySubMesh( iS ))
+    {
+      if ( iS >= int(_subMeshes.size()) )
+        _subMeshes.resize( iS + 1, 0 );
+      _subMeshes[iS] = sm;
+      proxyMesh->_subMeshes[iS] = 0;
+      return true;
+    }
+  }
+  return false;
+}
+
+//================================================================================
+/*!
+ * \brief Move tmp elements residing the _mesh from other proxy mesh to this
+ */
+//================================================================================
+
+void SMESH_ProxyMesh::takeTmpElemsInMesh( SMESH_ProxyMesh* proxyMesh )
+{
+  if ( proxyMesh )
+  {
+    _elemsInMesh.insert( proxyMesh->_elemsInMesh.begin(),
+                         proxyMesh->_elemsInMesh.end());
+    proxyMesh->_elemsInMesh.clear();
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Removes tmp faces from the _mesh
+ */
+//================================================================================
+
+void SMESH_ProxyMesh::removeTmpElement( const SMDS_MeshElement* face )
+{
+  if ( face && face->GetID() > 0 )
+  {
+    set< const SMDS_MeshElement* >::iterator i =  _elemsInMesh.find( face );
+    if ( i != _elemsInMesh.end() )
+    {
+      GetMeshDS()->RemoveFreeElement( face, 0 );
+      _elemsInMesh.erase( i );
+    }
+  }
+  else
+  {
+    delete face;
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Stores tmp element residing the _mesh
+ */
+//================================================================================
+
+void SMESH_ProxyMesh::storeTmpElement( const SMDS_MeshElement* face )
+{
+  _elemsInMesh.insert( face );
+}
+
+//================================================================================
+/*!
+ * \brief Set node-node correspondence
+ */
+//================================================================================
+
+void SMESH_ProxyMesh::setNode2Node(const SMDS_MeshNode* srcNode,
+                                   const SMDS_MeshNode* proxyNode,
+                                   const SubMesh*       subMesh)
+{
+  SubMesh* sm = const_cast<SubMesh*>( subMesh );
+  if ( !subMesh->_n2n )
+    sm->_n2n = new TN2NMap;
+  sm->_n2n->insert( make_pair( srcNode, proxyNode ));
+}
+
+//================================================================================
+/*!
+ * \brief Return true if the element is a temporary one
+ */
+//================================================================================
+
+bool SMESH_ProxyMesh::IsTemporary(const SMDS_MeshElement* elem ) const
+{
+  return ( elem->GetID() < 1 ) || _elemsInMesh.count( elem );
+}
+
+//================================================================================
+/*!
+ * \brief Return a proxy node or an input node
+ */
+//================================================================================
+
+const SMDS_MeshNode* SMESH_ProxyMesh::SubMesh::GetProxyNode( const SMDS_MeshNode* n ) const
+{
+  TN2NMap::iterator n2n;
+  if ( _n2n && ( n2n = _n2n->find( n )) != _n2n->end())
+    return n2n->second;
+  return n;
+}
+
+//================================================================================
+/*!
+ * \brief Deletes temporary elements
+ */
+//================================================================================
+
+void SMESH_ProxyMesh::SubMesh::Clear()
+{
+  for ( unsigned i = 0; i < _elements.size(); ++i )
+    if ( _elements[i]->GetID() < 0 )
+      delete _elements[i];
+  _elements.clear();
+  if ( _n2n )
+    delete _n2n, _n2n = 0;
+}
+
+//================================================================================
+/*!
+ * \brief Return number of elements in a proxy submesh
+ */
+//================================================================================
+
+int SMESH_ProxyMesh::SubMesh::NbElements() const
+{
+  return _elements.size();
+}
+
+//================================================================================
+/*!
+ * \brief Return elements of a proxy submesh
+ */
+//================================================================================
+
+SMDS_ElemIteratorPtr SMESH_ProxyMesh::SubMesh::GetElements() const
+{
+  return SMDS_ElemIteratorPtr
+    ( new SMDS_ElementVectorIterator( _elements.begin(), _elements.end() ));
+}
+
+//================================================================================
+/*!
+ * \brief Store an element
+ */
+//================================================================================
+
+void SMESH_ProxyMesh::SubMesh::AddElement(const SMDS_MeshElement * e)
+{
+  _elements.push_back( e );
+}
+
+//================================================================================
+/*!
+ * \brief Check presence of element inside it-self
+ */
+//================================================================================
+
+bool SMESH_ProxyMesh::SubMesh::Contains(const SMDS_MeshElement * ME) const
+{
+  if ( ME->GetType() != SMDSAbs_Node )
+    return find( _elements.begin(), _elements.end(), ME ) != _elements.end();
+  return false;
+}
diff --git a/src/SMESH/SMESH_ProxyMesh.hxx b/src/SMESH/SMESH_ProxyMesh.hxx
new file mode 100644 (file)
index 0000000..faf6773
--- /dev/null
@@ -0,0 +1,173 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+// File      : SMESH_ProxyMesh.hxx
+// Created   : Thu Dec  2 10:05:35 2010
+// Author    : Edward AGAPOV (eap)
+
+#ifndef __SMESH_ProxyMesh_HXX__
+#define __SMESH_ProxyMesh_HXX__
+
+#include "SMESH_SMESH.hxx"
+
+#include "SMDS_MeshElement.hxx"
+#include "SMESHDS_SubMesh.hxx"
+
+#include <TopoDS_Shape.hxx>
+
+#include <map>
+#include <vector>
+#include <boost/shared_ptr.hpp>
+
+class SMDS_MeshNode;
+class SMESHDS_Mesh;
+class SMESH_Mesh;
+
+/*!
+ * \brief Container of mesh faces substituting other faces in the input mesh of 3D algorithm
+ */
+class SMESH_EXPORT SMESH_ProxyMesh
+{
+public:
+
+  typedef boost::shared_ptr<SMESH_ProxyMesh> Ptr;
+
+  typedef std::map<const SMDS_MeshNode*, const SMDS_MeshNode*, TIDCompare > TN2NMap;
+
+  //--------------------------------------------------------------------------------
+  /*!
+   * \brief Proxy sub-mesh
+   */
+  class SubMesh : public SMESHDS_SubMesh
+  {
+  public:
+
+    const TN2NMap* GetNodeNodeMap() const { return _n2n; }
+    const SMDS_MeshNode* GetProxyNode( const SMDS_MeshNode* n ) const;
+    virtual void AddElement(const SMDS_MeshElement * e);
+    virtual int NbElements() const;
+    virtual SMDS_ElemIteratorPtr GetElements() const;
+    virtual void Clear();
+    virtual bool Contains(const SMDS_MeshElement * ME) const;
+
+    template< class ITERATOR >
+    void ChangeElements( ITERATOR it, ITERATOR end )
+    {
+      // change SubMesh contents without deleting tmp faces
+      // for which the caller is responsible
+      _elements.clear();
+      while ( it != end ) _elements.push_back( *it++ );
+    }
+    SubMesh(int index=0):SMESHDS_SubMesh(0,index),_n2n(0) {}
+    ~SubMesh() { Clear(); }
+
+  private:
+    std::vector<const SMDS_MeshElement *> _elements;
+    TN2NMap*                              _n2n;
+    friend class SMESH_ProxyMesh;
+  };
+  //--------------------------------------------------------------------------------
+  // Public interface
+
+  SMESH_ProxyMesh();
+  SMESH_ProxyMesh(std::vector<SMESH_ProxyMesh::Ptr>& components);
+  SMESH_ProxyMesh(const SMESH_Mesh& mesh) { _mesh = &mesh; }
+  virtual ~SMESH_ProxyMesh();
+
+  // Returns the submesh of a face; it can be a proxy sub-mesh
+  const SMESHDS_SubMesh* GetSubMesh(const TopoDS_Shape& face) const;
+
+  // Returns the proxy sub-mesh of a face; it can be NULL
+  const SubMesh* GetProxySubMesh(const TopoDS_Shape& face) const;
+
+  // Returns the proxy node of a node; the input node is returned if no proxy exists
+  const SMDS_MeshNode* GetProxyNode( const SMDS_MeshNode* node ) const;
+
+  // Returns iterator on all faces of the mesh taking into account substitutions
+  // To be used in case of mesh without shape
+  SMDS_ElemIteratorPtr GetFaces() const;
+
+  // Returns iterator on all faces on the face taking into account substitutions
+  SMDS_ElemIteratorPtr GetFaces(const TopoDS_Shape& face) const;
+
+  // Return total nb of faces taking into account substitutions
+  int NbFaces() const;
+
+  bool IsTemporary(const SMDS_MeshElement* elem ) const;
+
+
+
+  const SMESH_Mesh* GetMesh() const { return _mesh; }
+
+  SMESHDS_Mesh* GetMeshDS() const;
+
+  //--------------------------------------------------------------------------------
+  // Interface for descendants
+ protected:
+
+  void setMesh(const SMESH_Mesh& mesh) { _mesh = &mesh; }
+
+  int shapeIndex(const TopoDS_Shape& shape) const;
+
+  // returns a proxy sub-mesh; zero index is for the case of mesh w/o shape
+  SubMesh* findProxySubMesh(int shapeIndex=0) const;
+
+  // returns a proxy sub-mesh; it is created if not yet exists
+  SubMesh* getProxySubMesh(int shapeIndex);
+
+  // returns a proxy sub-mesh; it is created if not yet exists
+  SubMesh* getProxySubMesh(const TopoDS_Shape& shape=TopoDS_Shape());
+
+  // move proxy sub-mesh from other proxy mesh to this, returns true if sub-mesh found
+  bool takeProxySubMesh( const TopoDS_Shape& shape, SMESH_ProxyMesh* proxyMesh );
+
+  // move tmp elements residing the _mesh from other proxy mesh to this
+  void takeTmpElemsInMesh( SMESH_ProxyMesh* proxyMesh );
+
+  // removes tmp faces from the _mesh
+  void removeTmpElement( const SMDS_MeshElement* face );
+
+  // stores tmp element residing the _mesh
+  void storeTmpElement( const SMDS_MeshElement* face );
+
+  // store node-node correspondence
+  void setNode2Node(const SMDS_MeshNode* srcNode,
+                    const SMDS_MeshNode* proxyNode,
+                    const SubMesh*       subMesh);
+
+  // types of elements needed to implement NbFaces() and GetFaces();
+  // if _allowedTypes is empty, only elements from _subMeshes are returned,
+  // else elements of _mesh filtered using allowedTypes are additionally returned
+  std::vector< SMDSAbs_EntityType> _allowedTypes;
+
+ private:
+
+  const SMESH_Mesh*       _mesh;
+
+  // proxy sub-meshes; index in vector == shapeIndex(shape)
+  std::vector< SubMesh* > _subMeshes;
+
+  // tmp elements residing the _mesh, to be deleted at destruction
+  std::set< const SMDS_MeshElement* > _elemsInMesh;
+
+  // Complex submesh used to iterate over elements in other sub-meshes
+  mutable SubMesh _subContainer;
+};
+
+#endif
index 249fc6a8553846ec234709ced4b4219c1169cb5e..977f5fa1f43bec921e0bbb78c951c14d35626ad0 100755 (executable)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  File   : SMESH_SMESH.hxx
 //  Author : Alexander A. BORODIN
 //  Module : SMESH
@@ -27,7 +28,7 @@
 #define _SMESH_SMESH_HXX_
 
 #ifdef WNT
- #if defined SMESH_EXPORTS
+ #if defined SMESHimpl_EXPORTS
   #define SMESH_EXPORT __declspec( dllexport )
  #else
   #define SMESH_EXPORT __declspec( dllimport )
diff --git a/src/SMESH/SMESH_SequenceOfElemPtr.hxx b/src/SMESH/SMESH_SequenceOfElemPtr.hxx
deleted file mode 100644 (file)
index 77c92ad..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-// File:      SMESH_SequenceOfElemPtr.hxx
-// Created:   26.09.05 17:41:10
-// Author:    Sergey KUUL
-//
-#ifndef SMESH_SequenceOfElemPtr_HeaderFile
-#define SMESH_SequenceOfElemPtr_HeaderFile
-
-#include "SMESH_SMESH.hxx"
-
-#include <NCollection_DefineSequence.hxx>
-
-#include <SMDS_MeshElement.hxx>
-
-typedef const SMDS_MeshElement* SMDS_MeshElementPtr;
-
-DEFINE_BASECOLLECTION (SMESH_BaseCollectionElemPtr, SMDS_MeshElementPtr)
-DEFINE_SEQUENCE (SMESH_SequenceOfElemPtr, SMESH_BaseCollectionElemPtr, SMDS_MeshElementPtr)
-
-#endif 
diff --git a/src/SMESH/SMESH_SequenceOfNode.hxx b/src/SMESH/SMESH_SequenceOfNode.hxx
deleted file mode 100644 (file)
index 4eabe0e..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-// File:      SMESH_SequenceOfNode.hxx
-// Created:   11.11.05 10:00:04
-// Author:    Sergey KUUL
-//
-#ifndef SMESH_SequenceOfNode_HeaderFile
-#define SMESH_SequenceOfNode_HeaderFile
-
-#include "SMESH_SMESH.hxx"
-
-#include <NCollection_DefineSequence.hxx>
-
-typedef const SMDS_MeshNode* SMDS_MeshNodePtr;
-
-DEFINE_BASECOLLECTION (SMESH_BaseCollectionNodePtr, SMDS_MeshNodePtr)
-DEFINE_SEQUENCE(SMESH_SequenceOfNode,
-                SMESH_BaseCollectionNodePtr, SMDS_MeshNodePtr)
-
-
-#endif
index 6c484c80a20e6d9eff3ddef37a83010a4532a7c4..65ffac712f0240230d5e2296957ad7f026e09241 100644 (file)
@@ -1,30 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : SMESH_subMesh.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//  $Header$
-//
+
 #include "SMESH_subMesh.hxx"
 
 #include "SMESH_Algo.hxx"
 #include "SMESH_subMeshEventListener.hxx"
 #include "SMESH_Comment.hxx"
 #include "SMDS_SetIterator.hxx"
+#include "SMDSAbs_ElementType.hxx"
+
+#include <Basics_OCCTVersion.hxx>
 
 #include "utilities.h"
 #include "OpUtil.hxx"
+#include "Basics_Utils.hxx"
 
 #include <BRep_Builder.hxx>
 #include <BRep_Tool.hxx>
@@ -54,6 +58,8 @@
 #include <Standard_OutOfMemory.hxx>
 #include <Standard_ErrorHandler.hxx>
 
+#include <numeric>
+
 using namespace std;
 
 //=============================================================================
@@ -82,22 +88,22 @@ SMESH_subMesh::SMESH_subMesh(int                  Id,
                              SMESHDS_Mesh *       meshDS,
                              const TopoDS_Shape & aSubShape)
 {
-       _subShape = aSubShape;
-       _subMeshDS = meshDS->MeshElements(_subShape);   // may be null ...
-       _father = father;
-       _Id = Id;
-       _dependenceAnalysed = _alwaysComputed = false;
-
-       if (_subShape.ShapeType() == TopAbs_VERTEX)
-       {
-               _algoState = HYP_OK;
-               _computeState = READY_TO_COMPUTE;
-       }
-       else
-       {
+        _subShape = aSubShape;
+        _subMeshDS = meshDS->MeshElements(_subShape);   // may be null ...
+        _father = father;
+        _Id = Id;
+        _dependenceAnalysed = _alwaysComputed = false;
+
+        if (_subShape.ShapeType() == TopAbs_VERTEX)
+        {
+                _algoState = HYP_OK;
+                _computeState = READY_TO_COMPUTE;
+        }
+        else
+        {
           _algoState = NO_ALGO;
           _computeState = NOT_READY;
-       }
+        }
 }
 
 //=============================================================================
@@ -110,7 +116,7 @@ SMESH_subMesh::~SMESH_subMesh()
 {
   MESSAGE("SMESH_subMesh::~SMESH_subMesh");
   // ****
-  DeleteOwnListeners();
+  deleteOwnListeners();
 }
 
 //=============================================================================
@@ -171,7 +177,18 @@ SMESH_subMesh *SMESH_subMesh::GetFirstToCompute()
 
 //================================================================================
 /*!
- * \brief Allow algo->Compute() if a subshape of lower dim is meshed but
+ * \brief Returns a current algorithm
+ */
+//================================================================================
+
+SMESH_Algo* SMESH_subMesh::GetAlgo() const
+{
+  return _father->GetGen()->GetAlgo(*_father, _subShape);
+}
+
+//================================================================================
+/*!
+ * \brief Allow algo->Compute() if a sub-shape of lower dim is meshed but
  *        none mesh entity is bound to it (PAL13615, 2nd part)
  */
 //================================================================================
@@ -240,7 +257,7 @@ bool SMESH_subMesh::IsMeshComputed() const
  */
 //=============================================================================
 
-bool SMESH_subMesh::SubMeshesComputed()
+bool SMESH_subMesh::subMeshesComputed()
 {
   int myDim = SMESH_Gen::GetShapeDim( _subShape );
   int dimToCheck = myDim - 1;
@@ -261,7 +278,7 @@ bool SMESH_subMesh::SubMeshesComputed()
       break; // the rest subMeshes are all of less dimension
     SMESHDS_SubMesh * ds = sm->GetSubMeshDS();
     bool computeOk = (sm->GetComputeState() == COMPUTE_OK ||
-                      (ds && ( ds->NbNodes() || ds->NbElements() )));
+                      (ds && ( dimToCheck ? ds->NbElements() : ds->NbNodes()  )));
     if (!computeOk)
     {
       int type = ss.ShapeType();
@@ -324,23 +341,23 @@ bool SMESH_subMesh::SubMeshesComputed()
  */
 //=============================================================================
 
-bool SMESH_subMesh::SubMeshesReady()
-{
-  bool subMeshesReady = true;
-  SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,true);
-  while ( smIt->more() ) {
-    SMESH_subMesh *sm = smIt->next();
-    bool computeOk = (sm->GetComputeState() == COMPUTE_OK ||
-                      sm->GetComputeState() == READY_TO_COMPUTE);
-    if (!computeOk)
-    {
-      subMeshesReady = false;
-      SCRUTE(sm->GetId());
-      break;
-    }
-  }
-  return subMeshesReady;
-}
+// bool SMESH_subMesh::SubMeshesReady()
+// {
+//   bool subMeshesReady = true;
+//   SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,true);
+//   while ( smIt->more() ) {
+//     SMESH_subMesh *sm = smIt->next();
+//     bool computeOk = (sm->GetComputeState() == COMPUTE_OK ||
+//                       sm->GetComputeState() == READY_TO_COMPUTE);
+//     if (!computeOk)
+//     {
+//       subMeshesReady = false;
+//       SCRUTE(sm->GetId());
+//       break;
+//     }
+//   }
+//   return subMeshesReady;
+// }
 
 //=============================================================================
 /*!
@@ -368,55 +385,53 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn()
   case TopAbs_COMPOUND:
     {
       //MESSAGE("compound");
-      for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More();
-           exp.Next())
+      for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More();exp.Next())
       {
-        InsertDependence(exp.Current());
+        insertDependence(exp.Current());
       }
-      for (TopExp_Explorer exp(_subShape, TopAbs_SHELL, TopAbs_SOLID); exp.More();
-           exp.Next())
+      for (TopExp_Explorer exp(_subShape, TopAbs_SHELL, TopAbs_SOLID); exp.More(); exp.Next())
       {
-          InsertDependence(exp.Current());      //only shell not in solid
+        if ( BRep_Tool::IsClosed(exp.Current() ))
+          insertDependence(exp.Current());      //only shell not in solid
+        else
+          for (TopExp_Explorer expF(exp.Current(), TopAbs_FACE); expF.More();expF.Next())
+            insertDependence(expF.Current());    // issue 0020959: HEXA_3D fails on shell
+
       }
-      for (TopExp_Explorer exp(_subShape, TopAbs_FACE, TopAbs_SHELL); exp.More();
-           exp.Next())
+      for (TopExp_Explorer exp(_subShape, TopAbs_FACE, TopAbs_SHELL); exp.More();exp.Next())
       {
-        InsertDependence(exp.Current());
+        insertDependence(exp.Current());
       }
-      for (TopExp_Explorer exp(_subShape, TopAbs_EDGE, TopAbs_FACE); exp.More();
-           exp.Next())
+      for (TopExp_Explorer exp(_subShape, TopAbs_EDGE, TopAbs_FACE); exp.More();exp.Next())
       {
-        InsertDependence(exp.Current());
+        insertDependence(exp.Current());
       }
       break;
     }
   case TopAbs_COMPSOLID:
     {
-               //MESSAGE("compsolid");
-      for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More();
-           exp.Next())
+      //MESSAGE("compsolid");
+      for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More(); exp.Next())
       {
-        InsertDependence(exp.Current());
+        insertDependence(exp.Current());
       }
       break;
     }
   case TopAbs_SHELL:
     {
       //MESSAGE("shell");
-      for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More();
-           exp.Next())
+      for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More(); exp.Next())
       {
-        InsertDependence(exp.Current());
+        insertDependence(exp.Current());
       }
       break;
     }
   case TopAbs_WIRE:
     {
       //MESSAGE("wire");
-      for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More();
-           exp.Next())
+      for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More(); exp.Next())
       {
-        InsertDependence(exp.Current());
+        insertDependence(exp.Current());
       }
       break;
     }
@@ -424,10 +439,9 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn()
     {
       //MESSAGE("solid");
       if(_father->HasShapeToMesh()) {
-        for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More();
-             exp.Next())
+        for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More();exp.Next())
         {
-          InsertDependence(exp.Current());
+          insertDependence(exp.Current());
         }
       }
       break;
@@ -435,21 +449,19 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn()
   case TopAbs_FACE:
     {
       //MESSAGE("face");
-      for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More();
-           exp.Next())
+      for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More();exp.Next())
       {
-        InsertDependence(exp.Current());
+        insertDependence(exp.Current());
       }
       break;
     }
   case TopAbs_EDGE:
     {
       //MESSAGE("edge");
-      for (TopExp_Explorer exp(_subShape, TopAbs_VERTEX); exp.More();
-           exp.Next())
+      for (TopExp_Explorer exp(_subShape, TopAbs_VERTEX); exp.More(); exp.Next())
       {
-                       InsertDependence(exp.Current());
-                      }
+        insertDependence(exp.Current());
+      }
       break;
     }
   case TopAbs_VERTEX:
@@ -471,9 +483,8 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn()
  */
 //=============================================================================
 
-void SMESH_subMesh::InsertDependence(const TopoDS_Shape aSubShape)
+void SMESH_subMesh::insertDependence(const TopoDS_Shape aSubShape)
 {
-  //MESSAGE("SMESH_subMesh::InsertDependence");
   SMESH_subMesh *aSubMesh = _father->GetSubMesh(aSubShape);
   int type = aSubShape.ShapeType();
   int ordType = 9 - type;               // 2 = Vertex, 8 = CompSolid
@@ -495,8 +506,8 @@ void SMESH_subMesh::InsertDependence(const TopoDS_Shape aSubShape)
 
 const TopoDS_Shape & SMESH_subMesh::GetSubShape() const
 {
-       //MESSAGE("SMESH_subMesh::GetSubShape");
-       return _subShape;
+        //MESSAGE("SMESH_subMesh::GetSubShape");
+        return _subShape;
 }
 
 
@@ -510,12 +521,13 @@ bool SMESH_subMesh::CanAddHypothesis(const SMESH_Hypothesis* theHypothesis) cons
 {
   int aHypDim   = theHypothesis->GetDim();
   int aShapeDim = SMESH_Gen::GetShapeDim(_subShape);
-  if (aHypDim == 3 && aShapeDim == 3) {
-    // check case of open shell
-    //if (_subShape.ShapeType() == TopAbs_SHELL && !_subShape.Closed())
-    if (_subShape.ShapeType() == TopAbs_SHELL && !BRep_Tool::IsClosed(_subShape))
-      return false;
-  }
+  // issue 21106. Forbid 3D mesh on the SHELL
+  // if (aHypDim == 3 && aShapeDim == 3) {
+  //   // check case of open shell
+  //   //if (_subShape.ShapeType() == TopAbs_SHELL && !_subShape.Closed())
+  //   if (_subShape.ShapeType() == TopAbs_SHELL && !BRep_Tool::IsClosed(_subShape))
+  //     return false;
+  // }
   if ( aHypDim <= aShapeDim )
     return true;
 
@@ -531,8 +543,14 @@ bool SMESH_subMesh::IsApplicableHypotesis(const SMESH_Hypothesis* theHypothesis,
                                           const TopAbs_ShapeEnum  theShapeType)
 {
   if ( theHypothesis->GetType() > SMESHDS_Hypothesis::PARAM_ALGO)
+  {
     // algorithm
-    return ( theHypothesis->GetShapeType() & (1<< theShapeType));
+    if ( theHypothesis->GetShapeType() & (1<< theShapeType))
+      // issue 21106. Forbid 3D mesh on the SHELL
+      return !( theHypothesis->GetDim() == 3 && theShapeType == TopAbs_SHELL );
+    else
+      return false;
+  }
 
   // hypothesis
   switch ( theShapeType ) {
@@ -579,7 +597,7 @@ SMESH_Hypothesis::Hypothesis_Status
   SMESH_Hypothesis::Hypothesis_Status aux_ret, ret = SMESH_Hypothesis::HYP_OK;
 
   SMESHDS_Mesh* meshDS =_father->GetMeshDS();
-  SMESH_Gen*    gen    =_father->GetGen();
+  //SMESH_Gen*    gen    =_father->GetGen();
   SMESH_Algo*   algo   = 0;
 
   if (_subShape.ShapeType() == TopAbs_VERTEX )
@@ -596,7 +614,7 @@ SMESH_Hypothesis::Hypothesis_Status
       if ( event != REMOVE_FATHER_ALGO )
       {
         _algoState = NO_ALGO;
-        algo = gen->GetAlgo(*_father, _subShape);
+        algo = GetAlgo();
         if ( algo ) {
           _algoState = MISSING_HYP;
           if ( event == REMOVE_FATHER_HYP ||
@@ -609,6 +627,7 @@ SMESH_Hypothesis::Hypothesis_Status
 
   int oldAlgoState = _algoState;
   bool modifiedHyp = (event == MODIF_HYP);  // if set to true, force event MODIF_ALGO_STATE
+  bool needFullClean = false;
 
   bool isApplicableHyp = IsApplicableHypotesis( anHyp );
 
@@ -625,6 +644,15 @@ SMESH_Hypothesis::Hypothesis_Status
     // ----------------------
     if (isApplicableHyp && !_father->IsNotConformAllowed() && !IsConform( algo ))
       return SMESH_Hypothesis::HYP_NOTCONFORM;
+
+    // check if all-dimensional algo is hidden by other local one
+    if ( event == ADD_ALGO ) {
+      SMESH_HypoFilter filter( SMESH_HypoFilter::HasType( algo->GetType() ));
+      filter.Or( SMESH_HypoFilter::HasType( algo->GetType()+1 ));
+      filter.Or( SMESH_HypoFilter::HasType( algo->GetType()+2 ));
+      if ( SMESH_Algo * curAlgo = (SMESH_Algo*) _father->GetHypothesis( _subShape, filter, true ))
+        needFullClean = ( !curAlgo->NeedDiscreteBoundary() );
+    }
   }
 
   // ----------------------------------
@@ -635,7 +663,7 @@ SMESH_Hypothesis::Hypothesis_Status
     if ( ! CanAddHypothesis( anHyp )) // check dimension
       return SMESH_Hypothesis::HYP_BAD_DIM;
 
-    if ( /*!anHyp->IsAuxiliary() &&*/ GetSimilarAttached( _subShape, anHyp ) )
+    if ( /*!anHyp->IsAuxiliary() &&*/ getSimilarAttached( _subShape, anHyp ) )
       return SMESH_Hypothesis::HYP_ALREADY_EXIST;
 
     if ( !meshDS->AddHypothesis(_subShape, anHyp))
@@ -653,15 +681,12 @@ SMESH_Hypothesis::Hypothesis_Status
     if (event == REMOVE_ALGO)
     {
       algo = dynamic_cast<SMESH_Algo*> (anHyp);
-      if (!algo->NeedDescretBoundary())
+      if (!algo->NeedDiscreteBoundary())
       {
         // clean all mesh in the tree of the current submesh;
         // we must perform it now because later
         // we will have no information about the type of the removed algo
-        CleanDependants();
-       ComputeStateEngine( CLEAN );
-        CleanDependsOn();
-        ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE );
+        needFullClean = true;
       }
     }
   }
@@ -682,16 +707,16 @@ SMESH_Hypothesis::Hypothesis_Status
     case ADD_HYP:
       break;
     case ADD_ALGO: {
-      algo = gen->GetAlgo((*_father), _subShape);
+      algo = GetAlgo();
       ASSERT(algo);
       if (algo->CheckHypothesis((*_father),_subShape, aux_ret))
-        SetAlgoState(HYP_OK);
+        setAlgoState(HYP_OK);
       else if ( algo->IsStatusFatal( aux_ret )) {
         meshDS->RemoveHypothesis(_subShape, anHyp);
         ret = aux_ret;
       }
       else
-        SetAlgoState(MISSING_HYP);
+        setAlgoState(MISSING_HYP);
       break;
     }
     case REMOVE_HYP:
@@ -699,26 +724,26 @@ SMESH_Hypothesis::Hypothesis_Status
     case ADD_FATHER_HYP:
       break;
     case ADD_FATHER_ALGO: {    // Algo just added in father
-      algo = gen->GetAlgo((*_father), _subShape);
+      algo = GetAlgo();
       ASSERT(algo);
       if ( algo == anHyp ) {
         if ( algo->CheckHypothesis((*_father),_subShape, aux_ret))
-          SetAlgoState(HYP_OK);
+          setAlgoState(HYP_OK);
         else
-          SetAlgoState(MISSING_HYP);
+          setAlgoState(MISSING_HYP);
       }
       break;
     }
     case REMOVE_FATHER_HYP:
       break;
     case REMOVE_FATHER_ALGO: {
-      algo = gen->GetAlgo((*_father), _subShape);
+      algo = GetAlgo();
       if (algo)
       {
         if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
-            SetAlgoState(HYP_OK);
+            setAlgoState(HYP_OK);
         else
-          SetAlgoState(MISSING_HYP);
+          setAlgoState(MISSING_HYP);
       }
       break;
     }
@@ -735,10 +760,10 @@ SMESH_Hypothesis::Hypothesis_Status
     switch (event)
     {
     case ADD_HYP: {
-      algo = gen->GetAlgo((*_father), _subShape);
+      algo = GetAlgo();
       ASSERT(algo);
       if ( algo->CheckHypothesis((*_father),_subShape, ret ))
-        SetAlgoState(HYP_OK);
+        setAlgoState(HYP_OK);
       if (SMESH_Hypothesis::IsStatusFatal( ret ))
         meshDS->RemoveHypothesis(_subShape, anHyp);
       else if (!_father->IsUsedHypothesis( anHyp, this ))
@@ -749,70 +774,70 @@ SMESH_Hypothesis::Hypothesis_Status
       break;
     }
     case ADD_ALGO: {           //already existing algo : on father ?
-      algo = gen->GetAlgo((*_father), _subShape);
+      algo = GetAlgo();
       ASSERT(algo);
       if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))// ignore hyp status
-        SetAlgoState(HYP_OK);
+        setAlgoState(HYP_OK);
       else if ( algo->IsStatusFatal( aux_ret )) {
         meshDS->RemoveHypothesis(_subShape, anHyp);
         ret = aux_ret;
       }
       else
-        SetAlgoState(MISSING_HYP);
+        setAlgoState(MISSING_HYP);
       break;
     }
     case REMOVE_HYP:
       break;
     case REMOVE_ALGO: {        // perhaps a father algo applies ?
-      algo = gen->GetAlgo((*_father), _subShape);
-      if (algo == NULL)  // no more algo applying on subShape...
+      algo = GetAlgo();
+      if (algo == NULL)  // no more algo applying on sub-shape...
       {
-        SetAlgoState(NO_ALGO);
+        setAlgoState(NO_ALGO);
       }
       else
       {
         if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
-          SetAlgoState(HYP_OK);
+          setAlgoState(HYP_OK);
         else
-          SetAlgoState(MISSING_HYP);
+          setAlgoState(MISSING_HYP);
       }
       break;
     }
     case MODIF_HYP: // assigned hypothesis value may become good
     case ADD_FATHER_HYP: {
-      algo = gen->GetAlgo((*_father), _subShape);
+      algo = GetAlgo();
       ASSERT(algo);
       if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
-        SetAlgoState(HYP_OK);
+        setAlgoState(HYP_OK);
       else
-        SetAlgoState(MISSING_HYP);
+        setAlgoState(MISSING_HYP);
       break;
     }
     case ADD_FATHER_ALGO: { // new father algo
-      algo = gen->GetAlgo((*_father), _subShape);
+      algo = GetAlgo();
       ASSERT( algo );
       if ( algo == anHyp ) {
         if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
-          SetAlgoState(HYP_OK);
+          setAlgoState(HYP_OK);
         else
-          SetAlgoState(MISSING_HYP);
+          setAlgoState(MISSING_HYP);
       }
       break;
     }
     case REMOVE_FATHER_HYP:    // nothing to do
       break;
     case REMOVE_FATHER_ALGO: {
-      algo = gen->GetAlgo((*_father), _subShape);
+      algo = GetAlgo();
       if (algo == NULL)  // no more applying algo on father
       {
-        SetAlgoState(NO_ALGO);
+        setAlgoState(NO_ALGO);
       }
       else
       {
         if ( algo->CheckHypothesis((*_father),_subShape , aux_ret ))
-          SetAlgoState(HYP_OK);
+          setAlgoState(HYP_OK);
         else
-          SetAlgoState(MISSING_HYP);
+          setAlgoState(MISSING_HYP);
       }
       break;
     }
@@ -828,7 +853,7 @@ SMESH_Hypothesis::Hypothesis_Status
     switch (event)
     {
     case ADD_HYP: {
-      algo = gen->GetAlgo((*_father), _subShape);
+      algo = GetAlgo();
       ASSERT(algo);
       if (!algo->CheckHypothesis((*_father),_subShape, ret ))
       {
@@ -851,7 +876,7 @@ SMESH_Hypothesis::Hypothesis_Status
       break;
     }
     case ADD_ALGO: {           //already existing algo : on father ?
-      algo = gen->GetAlgo((*_father), _subShape);
+      algo = GetAlgo();
       if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) {
         // check if algo changes
         SMESH_HypoFilter f;
@@ -864,24 +889,24 @@ SMESH_Hypothesis::Hypothesis_Status
           modifiedHyp = true;
       }
       else
-        SetAlgoState(MISSING_HYP);
+        setAlgoState(MISSING_HYP);
       break;
     }
     case REMOVE_HYP: {
-      algo = gen->GetAlgo((*_father), _subShape);
+      algo = GetAlgo();
       ASSERT(algo);
       if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
-        SetAlgoState(HYP_OK);
+        setAlgoState(HYP_OK);
       else
-        SetAlgoState(MISSING_HYP);
+        setAlgoState(MISSING_HYP);
       modifiedHyp = true;
       break;
     }
     case REMOVE_ALGO: {         // perhaps a father algo applies ?
-      algo = gen->GetAlgo((*_father), _subShape);
-      if (algo == NULL)   // no more algo applying on subShape...
+      algo = GetAlgo();
+      if (algo == NULL)   // no more algo applying on sub-shape...
       {
-        SetAlgoState(NO_ALGO);
+        setAlgoState(NO_ALGO);
       }
       else
       {
@@ -891,13 +916,13 @@ SMESH_Hypothesis::Hypothesis_Status
             modifiedHyp = true;
         }
         else
-          SetAlgoState(MISSING_HYP);
+          setAlgoState(MISSING_HYP);
       }
       break;
     }
     case MODIF_HYP: // hypothesis value may become bad
     case ADD_FATHER_HYP: {  // new father hypothesis ?
-      algo = gen->GetAlgo((*_father), _subShape);
+      algo = GetAlgo();
       ASSERT(algo);
       if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))
       {
@@ -905,11 +930,11 @@ SMESH_Hypothesis::Hypothesis_Status
           modifiedHyp = true;
       }
       else
-        SetAlgoState(MISSING_HYP);
+        setAlgoState(MISSING_HYP);
       break;
     }
     case ADD_FATHER_ALGO: {
-      algo = gen->GetAlgo((*_father), _subShape);
+      algo = GetAlgo();
       if ( algo == anHyp ) { // a new algo on father
         if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) {
           // check if algo changes
@@ -923,27 +948,33 @@ SMESH_Hypothesis::Hypothesis_Status
             modifiedHyp = true;
         }
         else
-          SetAlgoState(MISSING_HYP);
+          setAlgoState(MISSING_HYP);
       }
       break;
     }
     case REMOVE_FATHER_HYP: {
-      algo = gen->GetAlgo((*_father), _subShape);
+      algo = GetAlgo();
       ASSERT(algo);
       if ( algo->CheckHypothesis((*_father),_subShape, aux_ret )) {
         // is there the same local hyp or maybe a new father algo applied?
-        if ( !GetSimilarAttached( _subShape, anHyp ) )
+        if ( !getSimilarAttached( _subShape, anHyp ) )
           modifiedHyp = true;
       }
       else
-        SetAlgoState(MISSING_HYP);
+        setAlgoState(MISSING_HYP);
       break;
     }
     case REMOVE_FATHER_ALGO: {
-      algo = gen->GetAlgo((*_father), _subShape);
+      // IPAL21346. Edges not removed when Netgen 1d-2d is removed from a SOLID.
+      // CLEAN was not called at event REMOVE_ALGO because the algo is not applicable to SOLID.
+      algo = dynamic_cast<SMESH_Algo*> (anHyp);
+      if (!algo->NeedDiscreteBoundary())
+        needFullClean = true;
+
+      algo = GetAlgo();
       if (algo == NULL)  // no more applying algo on father
       {
-        SetAlgoState(NO_ALGO);
+        setAlgoState(NO_ALGO);
       }
       else
       {
@@ -953,7 +984,7 @@ SMESH_Hypothesis::Hypothesis_Status
             modifiedHyp = true;
         }
         else
-          SetAlgoState(MISSING_HYP);
+          setAlgoState(MISSING_HYP);
       }
       break;
     }
@@ -981,16 +1012,19 @@ SMESH_Hypothesis::Hypothesis_Status
     TopTools_ListIteratorOfListOfShape it( _father->GetAncestors( _subShape ));
     for ( ; ( ret == SMESH_Hypothesis::HYP_OK && it.More()); it.Next() ) {
       if ( SMESH_Algo* upperAlgo = gen->GetAlgo( *_father, it.Value() ))
-        if ( !upperAlgo->NeedDescretBoundary() && !upperAlgo->SupportSubmeshes())
+        if ( !upperAlgo->NeedDiscreteBoundary() && !upperAlgo->SupportSubmeshes())
           ret = SMESH_Hypothesis::HYP_HIDDEN_ALGO;
     }
     // is algo hiding?
     if ( ret == SMESH_Hypothesis::HYP_OK &&
-         !algo->NeedDescretBoundary()    &&
+         !algo->NeedDiscreteBoundary()    &&
          !algo->SupportSubmeshes()) {
+      TopoDS_Shape algoAssignedTo, otherAssignedTo;
+      gen->GetAlgo( *_father, _subShape, &algoAssignedTo );
       map<int, SMESH_subMesh*>::reverse_iterator i_sm = _mapDepend.rbegin();
       for ( ; ( ret == SMESH_Hypothesis::HYP_OK && i_sm != _mapDepend.rend()) ; ++i_sm )
-        if ( gen->GetAlgo( *_father, i_sm->second->_subShape ))
+        if ( gen->GetAlgo( *_father, i_sm->second->_subShape, &otherAssignedTo ) &&
+             SMESH_MesherHelper::IsSubShape( /*sub=*/otherAssignedTo, /*main=*/algoAssignedTo ))
           ret = SMESH_Hypothesis::HYP_HIDING_ALGO;
     }
   }
@@ -1000,10 +1034,10 @@ SMESH_Hypothesis::Hypothesis_Status
   if ( stateChange && _algoState == HYP_OK ) // hyp becomes OK
     algo->SetEventListener( this );
 
-  NotifyListenersOnEvent( event, ALGO_EVENT, anHyp );
+  notifyListenersOnEvent( event, ALGO_EVENT, anHyp );
 
   if ( stateChange && oldAlgoState == HYP_OK ) { // hyp becomes KO
-    DeleteOwnListeners();
+    deleteOwnListeners();
     SetIsAlwaysComputed( false );
     if (_subShape.ShapeType() == TopAbs_VERTEX ) {
       // restore default states
@@ -1012,6 +1046,13 @@ SMESH_Hypothesis::Hypothesis_Status
     }
   }
 
+  if ( needFullClean ) {
+    // added or removed algo is all-dimensional
+    ComputeStateEngine( CLEAN );
+    cleanDependsOn();
+    ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE );
+  }
+
   if (stateChange || modifiedHyp)
     ComputeStateEngine(MODIF_ALGO_STATE);
 
@@ -1031,9 +1072,9 @@ bool SMESH_subMesh::IsConform(const SMESH_Algo* theAlgo)
   // Suppose that theAlgo is applicable to _subShape, do not check it here
   //if ( !IsApplicableHypotesis( theAlgo )) return false;
 
-  // check only algo that doesn't NeedDescretBoundary(): because mesh made
+  // check only algo that doesn't NeedDiscreteBoundary(): because mesh made
   // on a sub-shape will be ignored by theAlgo
-  if ( theAlgo->NeedDescretBoundary() ||
+  if ( theAlgo->NeedDiscreteBoundary() ||
        !theAlgo->OnlyUnaryInput() ) // all adjacent shapes will be meshed by this algo?
     return true;
 
@@ -1062,7 +1103,7 @@ bool SMESH_subMesh::IsConform(const SMESH_Algo* theAlgo)
       // check algo attached to smAdjacent
       SMESH_Algo * algo = gen->GetAlgo((*_father), adjacent);
       if (algo &&
-          !algo->NeedDescretBoundary() &&
+          !algo->NeedDiscreteBoundary() &&
           algo->OnlyUnaryInput())
         return false; // NOT CONFORM MESH WILL BE PRODUCED
     }
@@ -1077,7 +1118,7 @@ bool SMESH_subMesh::IsConform(const SMESH_Algo* theAlgo)
  */
 //=============================================================================
 
-void SMESH_subMesh::SetAlgoState(int state)
+void SMESH_subMesh::setAlgoState(int state)
 {
   _algoState = state;
 }
@@ -1113,7 +1154,7 @@ SMESH_Hypothesis::Hypothesis_Status
  */
 //=============================================================================
 
-void SMESH_subMesh::CleanDependsOn()
+void SMESH_subMesh::cleanDependsOn()
 {
   SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false);
   while ( smIt->more() )
@@ -1128,48 +1169,48 @@ void SMESH_subMesh::CleanDependsOn()
 
 void SMESH_subMesh::DumpAlgoState(bool isMain)
 {
-       int dim = SMESH_Gen::GetShapeDim(_subShape);
+        int dim = SMESH_Gen::GetShapeDim(_subShape);
 //   if (dim < 1) return;
-       if (isMain)
-       {
-               const map < int, SMESH_subMesh * >&subMeshes = DependsOn();
-
-               map < int, SMESH_subMesh * >::const_iterator itsub;
-               for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
-               {
-                       SMESH_subMesh *sm = (*itsub).second;
-                       sm->DumpAlgoState(false);
-               }
-       }
-       int type = _subShape.ShapeType();
-       MESSAGE("dim = " << dim << " type of shape " << type);
-       switch (_algoState)
-       {
-       case NO_ALGO:
-               MESSAGE(" AlgoState = NO_ALGO");
-               break;
-       case MISSING_HYP:
-               MESSAGE(" AlgoState = MISSING_HYP");
-               break;
-       case HYP_OK:
-               MESSAGE(" AlgoState = HYP_OK");
-               break;
-       }
-       switch (_computeState)
-       {
-       case NOT_READY:
-               MESSAGE(" ComputeState = NOT_READY");
-               break;
-       case READY_TO_COMPUTE:
-               MESSAGE(" ComputeState = READY_TO_COMPUTE");
-               break;
-       case COMPUTE_OK:
-               MESSAGE(" ComputeState = COMPUTE_OK");
-               break;
-       case FAILED_TO_COMPUTE:
-               MESSAGE(" ComputeState = FAILED_TO_COMPUTE");
-               break;
-       }
+        if (isMain)
+        {
+                const map < int, SMESH_subMesh * >&subMeshes = DependsOn();
+
+                map < int, SMESH_subMesh * >::const_iterator itsub;
+                for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
+                {
+                        SMESH_subMesh *sm = (*itsub).second;
+                        sm->DumpAlgoState(false);
+                }
+        }
+        int type = _subShape.ShapeType();
+        MESSAGE("dim = " << dim << " type of shape " << type);
+        switch (_algoState)
+        {
+        case NO_ALGO:
+                MESSAGE(" AlgoState = NO_ALGO");
+                break;
+        case MISSING_HYP:
+                MESSAGE(" AlgoState = MISSING_HYP");
+                break;
+        case HYP_OK:
+                MESSAGE(" AlgoState = HYP_OK");
+                break;
+        }
+        switch (_computeState)
+        {
+        case NOT_READY:
+                MESSAGE(" ComputeState = NOT_READY");
+                break;
+        case READY_TO_COMPUTE:
+                MESSAGE(" ComputeState = READY_TO_COMPUTE");
+                break;
+        case COMPUTE_OK:
+                MESSAGE(" ComputeState = COMPUTE_OK");
+                break;
+        case FAILED_TO_COMPUTE:
+                MESSAGE(" ComputeState = FAILED_TO_COMPUTE");
+                break;
+        }
 }
 
 //================================================================================
@@ -1225,7 +1266,7 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
     SMESHDS_SubMesh* smDS = GetSubMeshDS();
     if ( smDS && smDS->NbNodes() ) {
       if ( event == CLEAN ) {
-        CleanDependants();
+        cleanDependants();
         cleanSubMesh( this );
       }
       else
@@ -1240,7 +1281,7 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
       }
     }
     if ( event == MODIF_ALGO_STATE )
-      CleanDependants();
+      cleanDependants();
     return true;
   }
   SMESH_Gen *gen = _father->GetGen();
@@ -1258,25 +1299,33 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
     switch (event)
     {
     case MODIF_ALGO_STATE:
-      algo = gen->GetAlgo((*_father), _subShape);
-      if (algo && !algo->NeedDescretBoundary())
-        CleanDependsOn(); // clean sub-meshes with event CLEAN
+      algo = GetAlgo();
+      if (algo && !algo->NeedDiscreteBoundary())
+        cleanDependsOn(); // clean sub-meshes with event CLEAN
       if ( _algoState == HYP_OK )
         _computeState = READY_TO_COMPUTE;
       break;
-    case COMPUTE:              // nothing to do
+    case COMPUTE:               // nothing to do
+      break;
+#ifdef WITH_SMESH_CANCEL_COMPUTE
+    case COMPUTE_CANCELED:               // nothing to do
       break;
+#endif
     case CLEAN:
-      CleanDependants();
-      RemoveSubMeshElementsAndNodes();
+      cleanDependants();
+      removeSubMeshElementsAndNodes();
       break;
-    case SUBMESH_COMPUTED:     // nothing to do
+    case SUBMESH_COMPUTED:      // nothing to do
       break;
     case SUBMESH_RESTORED:
       ComputeSubMeshStateEngine( SUBMESH_RESTORED );
       break;
     case MESH_ENTITY_REMOVED:
       break;
+    case SUBMESH_LOADED:
+      loadDependentMeshes();
+      ComputeSubMeshStateEngine( SUBMESH_LOADED );
+      //break;
     case CHECK_COMPUTE_STATE:
       if ( IsMeshComputed() )
         _computeState = COMPUTE_OK;
@@ -1294,25 +1343,25 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
     {
     case MODIF_ALGO_STATE:
       _computeState = NOT_READY;
-      algo = gen->GetAlgo((*_father), _subShape);
+      algo = GetAlgo();
       if (algo)
       {
-        if (!algo->NeedDescretBoundary())
-          CleanDependsOn(); // clean sub-meshes with event CLEAN
+        if (!algo->NeedDiscreteBoundary())
+          cleanDependsOn(); // clean sub-meshes with event CLEAN
         if ( _algoState == HYP_OK )
           _computeState = READY_TO_COMPUTE;
       }
       break;
     case COMPUTE:
       {
-        algo = gen->GetAlgo((*_father), _subShape);
+        algo = GetAlgo();
         ASSERT(algo);
         ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
         if (!ret)
         {
           MESSAGE("***** verify compute state *****");
           _computeState = NOT_READY;
-          SetAlgoState(MISSING_HYP);
+          setAlgoState(MISSING_HYP);
           break;
         }
         TopoDS_Shape shape = _subShape;
@@ -1320,34 +1369,37 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
         if (_father->HasShapeToMesh() ) {
           bool subComputed = false;
           if (!algo->OnlyUnaryInput())
-            shape = GetCollection( gen, algo, subComputed );
+            shape = getCollection( gen, algo, subComputed );
           else
-            subComputed = SubMeshesComputed();
-          ret = ( algo->NeedDescretBoundary() ? subComputed :
+            subComputed = subMeshesComputed();
+          ret = ( algo->NeedDiscreteBoundary() ? subComputed :
                   algo->SupportSubmeshes() ? true :
                   ( !subComputed || _father->IsNotConformAllowed() ));
           if (!ret) {
             _computeState = FAILED_TO_COMPUTE;
-            if ( !algo->NeedDescretBoundary() )
+            if ( !algo->NeedDiscreteBoundary() )
               _computeError =
                 SMESH_ComputeError::New(COMPERR_BAD_INPUT_MESH,
                                         "Unexpected computed submesh",algo);
             break;
           }
         }
-        // compute
-//         CleanDependants(); for "UseExisting_*D" algos
-//         RemoveSubMeshElementsAndNodes();
+        // Compute
+
+        //cleanDependants(); for "UseExisting_*D" algos
+        //removeSubMeshElementsAndNodes();
+        loadDependentMeshes();
         ret = false;
         _computeState = FAILED_TO_COMPUTE;
         _computeError = SMESH_ComputeError::New(COMPERR_OK,"",algo);
         try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
+#if OCC_VERSION_LARGE > 0x06010000
           OCC_CATCH_SIGNALS;
 #endif
           algo->InitComputeError();
           MemoryReserve aMemoryReserve;
           SMDS_Mesh::CheckMemory();
+          Kernel_Utils::Localizer loc;
           if ( !_father->HasShapeToMesh() ) // no shape
           {
             SMESH_MesherHelper helper( *_father );
@@ -1362,6 +1414,11 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
           if ( !_computeError || ( !ret && _computeError->IsOK() ) ) // algo can set _computeError of submesh
             _computeError = algo->GetComputeError();
         }
+        catch ( ::SMESH_ComputeError& comperr ) {
+          cout << " SMESH_ComputeError caught" << endl;
+          if ( !_computeError ) _computeError = SMESH_ComputeError::New();
+          *_computeError = comperr;
+        }
         catch ( std::bad_alloc& exc ) {
           MESSAGE("std::bad_alloc thrown inside algo->Compute()");
           if ( _computeError ) {
@@ -1405,38 +1462,53 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
           else
             ret = false;
         }
-        if (ret && !_alwaysComputed && shape == _subShape) { // check if anything was built
-          ret = ( GetSubMeshDS() && ( GetSubMeshDS()->NbElements() || GetSubMeshDS()->NbNodes() ));
+        TopExp_Explorer subS(shape, _subShape.ShapeType());
+        if (ret) // check if anything was built
+        {
+          for (; ret && subS.More(); subS.Next())
+            ret = _father->GetSubMesh( subS.Current() )->IsMeshComputed();
         }
-        bool isComputeErrorSet = !CheckComputeError( algo, shape );
+        bool isComputeErrorSet = !checkComputeError( algo, shape );
         if (!ret && !isComputeErrorSet)
         {
           // Set _computeError
-          if ( !_computeError )
-            _computeError = SMESH_ComputeError::New();
-          if ( _computeError->IsOK() )
-            _computeError->myName = COMPERR_ALGO_FAILED;
-          _computeState = FAILED_TO_COMPUTE;
+          for (subS.ReInit(); subS.More(); subS.Next())
+          {
+            SMESH_subMesh* sm = _father->GetSubMesh( subS.Current() );
+            if ( !sm->IsMeshComputed() )
+            {
+              if ( !sm->_computeError )
+                sm->_computeError = SMESH_ComputeError::New();
+              if ( sm->_computeError->IsOK() )
+                sm->_computeError->myName = COMPERR_ALGO_FAILED;
+              sm->_computeState = FAILED_TO_COMPUTE;
+              sm->_computeError->myAlgo = algo;
+            }
+          }
         }
-        if (ret)
+        if (ret && _computeError && _computeError->myName != COMPERR_WARNING )
         {
           _computeError.reset();
         }
-        UpdateDependantsState( SUBMESH_COMPUTED ); // send event SUBMESH_COMPUTED
+        updateDependantsState( SUBMESH_COMPUTED ); // send event SUBMESH_COMPUTED
       }
       break;
+#ifdef WITH_SMESH_CANCEL_COMPUTE
+    case COMPUTE_CANCELED:               // nothing to do
+      break;
+#endif
     case CLEAN:
-      CleanDependants();
-      RemoveSubMeshElementsAndNodes();
+      cleanDependants();
+      removeSubMeshElementsAndNodes();
       _computeState = NOT_READY;
-      algo = gen->GetAlgo((*_father), _subShape);
+      algo = GetAlgo();
       if (algo)
       {
         ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
         if (ret)
           _computeState = READY_TO_COMPUTE;
         else
-          SetAlgoState(MISSING_HYP);
+          setAlgoState(MISSING_HYP);
       }
       break;
     case SUBMESH_COMPUTED:      // nothing to do
@@ -1446,11 +1518,15 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
       // happen after retrieval from a file
       ComputeStateEngine( CHECK_COMPUTE_STATE );
       ComputeSubMeshStateEngine( SUBMESH_RESTORED );
-      algo = gen->GetAlgo(*_father, _subShape);
+      algo = GetAlgo();
       if (algo) algo->SubmeshRestored( this );
       break;
     case MESH_ENTITY_REMOVED:
       break;
+    case SUBMESH_LOADED:
+      loadDependentMeshes();
+      ComputeSubMeshStateEngine( SUBMESH_LOADED );
+      //break;
     case CHECK_COMPUTE_STATE:
       if ( IsMeshComputed() )
         _computeState = COMPUTE_OK;
@@ -1468,15 +1544,19 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
     {
     case MODIF_ALGO_STATE:
       ComputeStateEngine( CLEAN );
-      algo = gen->GetAlgo((*_father), _subShape);
-      if (algo && !algo->NeedDescretBoundary())
-        CleanDependsOn(); // clean sub-meshes with event CLEAN
+      algo = GetAlgo();
+      if (algo && !algo->NeedDiscreteBoundary())
+        cleanDependsOn(); // clean sub-meshes with event CLEAN
       break;
     case COMPUTE:               // nothing to do
       break;
+#ifdef WITH_SMESH_CANCEL_COMPUTE
+    case COMPUTE_CANCELED:               // nothing to do
+      break;
+#endif
     case CLEAN:
-      CleanDependants();  // clean sub-meshes, dependant on this one, with event CLEAN
-      RemoveSubMeshElementsAndNodes();
+      cleanDependants();  // clean sub-meshes, dependant on this one, with event CLEAN
+      removeSubMeshElementsAndNodes();
       _computeState = NOT_READY;
       if ( _algoState == HYP_OK )
         _computeState = READY_TO_COMPUTE;
@@ -1486,20 +1566,24 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
     case SUBMESH_RESTORED:
       ComputeStateEngine( CHECK_COMPUTE_STATE );
       ComputeSubMeshStateEngine( SUBMESH_RESTORED );
-      algo = gen->GetAlgo(*_father, _subShape);
+      algo = GetAlgo();
       if (algo) algo->SubmeshRestored( this );
       break;
     case MESH_ENTITY_REMOVED:
-      UpdateDependantsState( CHECK_COMPUTE_STATE );
-      ComputeStateEngine( CHECK_COMPUTE_STATE );
+      updateDependantsState    ( CHECK_COMPUTE_STATE );
+      ComputeStateEngine       ( CHECK_COMPUTE_STATE );
       ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE );
       break;
     case CHECK_COMPUTE_STATE:
-      if ( !IsMeshComputed() )
+      if ( !IsMeshComputed() ) {
         if (_algoState == HYP_OK)
           _computeState = READY_TO_COMPUTE;
         else
           _computeState = NOT_READY;
+      }
+      break;
+    case SUBMESH_LOADED:
+      // already treated event, thanks to which _computeState == COMPUTE_OK
       break;
     default:
       ASSERT(0);
@@ -1513,9 +1597,11 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
     switch (event)
     {
     case MODIF_ALGO_STATE:
-      algo = gen->GetAlgo((*_father), _subShape);
-      if (algo && !algo->NeedDescretBoundary())
-        CleanDependsOn(); // clean sub-meshes with event CLEAN
+      if ( !IsEmpty() )
+        ComputeStateEngine( CLEAN );
+      algo = GetAlgo();
+      if (algo && !algo->NeedDiscreteBoundary())
+        cleanDependsOn(); // clean sub-meshes with event CLEAN
       if (_algoState == HYP_OK)
         _computeState = READY_TO_COMPUTE;
       else
@@ -1523,9 +1609,15 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
       break;
     case COMPUTE:      // nothing to do
       break;
+    case COMPUTE_CANCELED:
+      {
+        algo = GetAlgo();
+        algo->CancelCompute();
+      }
+      break;
     case CLEAN:
-      CleanDependants(); // submeshes dependent on me should be cleaned as well
-      RemoveSubMeshElementsAndNodes();
+      cleanDependants(); // submeshes dependent on me should be cleaned as well
+      removeSubMeshElementsAndNodes();
       break;
     case SUBMESH_COMPUTED:      // allow retry compute
       if (_algoState == HYP_OK)
@@ -1547,6 +1639,8 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
         else
           _computeState = NOT_READY;
       break;
+    // case SUBMESH_LOADED:
+    //   break;
     default:
       ASSERT(0);
       break;
@@ -1559,11 +1653,68 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
     break;
   }
 
-  NotifyListenersOnEvent( event, COMPUTE_EVENT );
+  notifyListenersOnEvent( event, COMPUTE_EVENT );
+
+  return ret;
+}
+
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+bool SMESH_subMesh::Evaluate(MapShapeNbElems& aResMap)
+{
+  _computeError.reset();
+
+  bool ret = true;
+
+  if (_subShape.ShapeType() == TopAbs_VERTEX) {
+    vector<int> aVec(SMDSEntity_Last,0);
+    aVec[SMDSEntity_Node] = 1;
+    aResMap.insert(make_pair(this,aVec));
+    return ret;
+  }
+
+  //SMESH_Gen *gen = _father->GetGen();
+  SMESH_Algo *algo = 0;
+  SMESH_Hypothesis::Hypothesis_Status hyp_status;
+
+  algo = GetAlgo();
+  if(algo && !aResMap.count(this) )
+  {
+    ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
+    if (!ret) return false;
+
+    if (_father->HasShapeToMesh() && algo->NeedDiscreteBoundary())
+    {
+      // check submeshes needed
+      bool subMeshEvaluated = true;
+      int dimToCheck = SMESH_Gen::GetShapeDim( _subShape ) - 1;
+      SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,/*complexShapeFirst=*/true);
+      while ( smIt->more() && subMeshEvaluated )
+      {
+        SMESH_subMesh* sm = smIt->next();
+        int dim = SMESH_Gen::GetShapeDim( sm->GetSubShape() );
+        if (dim < dimToCheck) break; // the rest subMeshes are all of less dimension
+        const vector<int> & nbs = aResMap[ sm ];
+        subMeshEvaluated = (std::accumulate( nbs.begin(), nbs.end(), 0 ) > 0 );
+      }
+      if ( !subMeshEvaluated )
+        return false;
+    }
+    _computeError = SMESH_ComputeError::New(COMPERR_OK,"",algo);
+    ret = algo->Evaluate((*_father), _subShape, aResMap);
+
+    aResMap.insert( make_pair( this,vector<int>(0)));
+  }
 
   return ret;
 }
 
+
 //=======================================================================
 /*!
  * \brief Update compute_state by _computeError and send proper events to
@@ -1572,18 +1723,18 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
  */
 //=======================================================================
 
-bool SMESH_subMesh::CheckComputeError(SMESH_Algo* theAlgo, const TopoDS_Shape& theShape)
+bool SMESH_subMesh::checkComputeError(SMESH_Algo* theAlgo, const TopoDS_Shape& theShape)
 {
   bool noErrors = true;
 
   if ( !theShape.IsNull() )
   {
     // Check state of submeshes
-    if ( !theAlgo->NeedDescretBoundary())
+    if ( !theAlgo->NeedDiscreteBoundary())
     {
       SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false);
       while ( smIt->more() )
-        if ( !smIt->next()->CheckComputeError( theAlgo ))
+        if ( !smIt->next()->checkComputeError( theAlgo ))
           noErrors = false;
     }
 
@@ -1595,9 +1746,9 @@ bool SMESH_subMesh::CheckComputeError(SMESH_Algo* theAlgo, const TopoDS_Shape& t
       for (TopoDS_Iterator subIt( theShape ); subIt.More(); subIt.Next()) {
         SMESH_subMesh* sm = _father->GetSubMesh( subIt.Value() );
         if ( sm != this ) {
-          if ( !sm->CheckComputeError( theAlgo, sm->GetSubShape() ))
+          if ( !sm->checkComputeError( theAlgo, sm->GetSubShape() ))
             noErrors = false;
-          UpdateDependantsState( SUBMESH_COMPUTED ); // send event SUBMESH_COMPUTED
+          updateDependantsState( SUBMESH_COMPUTED ); // send event SUBMESH_COMPUTED
         }
       }
     }
@@ -1606,7 +1757,8 @@ bool SMESH_subMesh::CheckComputeError(SMESH_Algo* theAlgo, const TopoDS_Shape& t
     // Check my state
     if ( !_computeError || _computeError->IsOK() )
     {
-      _computeState = COMPUTE_OK;
+      // no error description is set to this sub-mesh, check if any mesh is computed
+      _computeState = IsMeshComputed() ? COMPUTE_OK : FAILED_TO_COMPUTE;
     }
     else
     {
@@ -1615,7 +1767,7 @@ bool SMESH_subMesh::CheckComputeError(SMESH_Algo* theAlgo, const TopoDS_Shape& t
 
       // Show error
       SMESH_Comment text;
-      text << theAlgo->GetName() << " failed on subshape #" << _Id << " with error ";
+      text << theAlgo->GetName() << " failed on sub-shape #" << _Id << " with error ";
       if (_computeError->IsCommon() )
         text << _computeError->CommonName();
       else
@@ -1623,73 +1775,22 @@ bool SMESH_subMesh::CheckComputeError(SMESH_Algo* theAlgo, const TopoDS_Shape& t
       if ( _computeError->myComment.size() > 0 )
         text << " \"" << _computeError->myComment << "\"";
 
-#ifdef _DEBUG_
-      MESSAGE_BEGIN ( text );
-      // Show vertices location of a failed shape
-      TopTools_IndexedMapOfShape vMap;
-      TopExp::MapShapes( _subShape, TopAbs_VERTEX, vMap );
-      MESSAGE_ADD ( "Subshape vertices " << ( vMap.Extent()>10 ? "(first 10):" : ":") );
-      for ( int iv = 1; iv <= vMap.Extent() && iv < 11; ++iv ) {
-        gp_Pnt P( BRep_Tool::Pnt( TopoDS::Vertex( vMap( iv ) )));
-        MESSAGE_ADD ( "#" << _father->GetMeshDS()->ShapeToIndex( vMap( iv )) << " "
-                   << P.X() << " " << P.Y() << " " << P.Z() << " " );
-      }
-#else
       INFOS( text );
-#endif
-      _computeState = FAILED_TO_COMPUTE;
-      noErrors = false;
-    }
-  }
-  return noErrors;
-}
-
-//=======================================================================
-//function : ApplyToCollection
-//purpose  : Apply theAlgo to all subshapes in theCollection
-//=======================================================================
-
-bool SMESH_subMesh::ApplyToCollection (SMESH_Algo*         theAlgo,
-                                       const TopoDS_Shape& theCollection)
-{
-  MESSAGE("SMESH_subMesh::ApplyToCollection");
-  ASSERT ( !theAlgo->NeedDescretBoundary() );
-
-  if ( _computeError )
-    _computeError->myName = COMPERR_OK;
 
-  bool ok = theAlgo->Compute( *_father, theCollection );
+      _computeState = _computeError->IsKO() ? FAILED_TO_COMPUTE : COMPUTE_OK;
 
-  // set _computeState of subshapes
-  TopExp_Explorer anExplorer( theCollection, _subShape.ShapeType() );
-  for ( ; anExplorer.More(); anExplorer.Next() )
-  {
-    if ( SMESH_subMesh* subMesh = _father->GetSubMeshContaining( anExplorer.Current() ))
-    {
-      bool localOK = subMesh->CheckComputeError( theAlgo );
-      if ( !ok && localOK && !subMesh->IsMeshComputed() )
-      {
-        subMesh->_computeError = theAlgo->GetComputeError();
-        if ( subMesh->_computeError->IsOK() )
-          _computeError = SMESH_ComputeError::New(COMPERR_ALGO_FAILED);
-        localOK = CheckComputeError( theAlgo );
-      }
-      if ( localOK )
-        subMesh->UpdateDependantsState( SUBMESH_COMPUTED );
-      subMesh->UpdateSubMeshState( localOK ? COMPUTE_OK : FAILED_TO_COMPUTE );
+      noErrors = false;
     }
   }
-
-  return true;
+  return noErrors;
 }
 
-
 //=======================================================================
-//function : UpdateSubMeshState
+//function : updateSubMeshState
 //purpose  :
 //=======================================================================
 
-void SMESH_subMesh::UpdateSubMeshState(const compute_state theState)
+void SMESH_subMesh::updateSubMeshState(const compute_state theState)
 {
   SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false);
   while ( smIt->more() )
@@ -1701,21 +1802,20 @@ void SMESH_subMesh::UpdateSubMeshState(const compute_state theState)
 //purpose  :
 //=======================================================================
 
-void SMESH_subMesh::ComputeSubMeshStateEngine(int event)
+void SMESH_subMesh::ComputeSubMeshStateEngine(int event, const bool includeSelf)
 {
-  SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false);
+  SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(includeSelf,false);
   while ( smIt->more() )
     smIt->next()->ComputeStateEngine(event);
 }
 
 //=======================================================================
-//function : UpdateDependantsState
+//function : updateDependantsState
 //purpose  :
 //=======================================================================
 
-void SMESH_subMesh::UpdateDependantsState(const compute_event theEvent)
+void SMESH_subMesh::updateDependantsState(const compute_event theEvent)
 {
-  //MESSAGE("SMESH_subMesh::UpdateDependantsState");
   TopTools_ListIteratorOfListOfShape it( _father->GetAncestors( _subShape ));
   for (; it.More(); it.Next())
   {
@@ -1733,7 +1833,7 @@ void SMESH_subMesh::UpdateDependantsState(const compute_event theEvent)
  */
 //=============================================================================
 
-void SMESH_subMesh::CleanDependants()
+void SMESH_subMesh::cleanDependants()
 {
   int dimToClean = SMESH_Gen::GetShapeDim( _subShape ) + 1;
 
@@ -1746,7 +1846,8 @@ void SMESH_subMesh::CleanDependants()
       // will erase mesh on other shapes in a compound
       if ( ancestor.ShapeType() >= TopAbs_SOLID ) {
         SMESH_subMesh *aSubMesh = _father->GetSubMeshContaining(ancestor);
-        if (aSubMesh)
+        if (aSubMesh &&
+            !aSubMesh->IsEmpty() ) // prevent infinite CLEAN via event lesteners
           aSubMesh->ComputeStateEngine(CLEAN);
       }
     }
@@ -1759,10 +1860,8 @@ void SMESH_subMesh::CleanDependants()
  */
 //=============================================================================
 
-void SMESH_subMesh::RemoveSubMeshElementsAndNodes()
+void SMESH_subMesh::removeSubMeshElementsAndNodes()
 {
-  //SCRUTE(_subShape.ShapeType());
-
   cleanSubMesh( this );
 
   // algo may bind a submesh not to _subShape, eg 3D algo
@@ -1783,18 +1882,16 @@ void SMESH_subMesh::RemoveSubMeshElementsAndNodes()
 }
 
 //=======================================================================
-//function : GetCollection
+//function : getCollection
 //purpose  : return a shape containing all sub-shapes of the MainShape that can be
 //           meshed at once along with _subShape
 //=======================================================================
 
-TopoDS_Shape SMESH_subMesh::GetCollection(SMESH_Gen * theGen,
+TopoDS_Shape SMESH_subMesh::getCollection(SMESH_Gen * theGen,
                                           SMESH_Algo* theAlgo,
                                           bool &      theSubComputed)
 {
-  MESSAGE("SMESH_subMesh::GetCollection");
-
-  theSubComputed = SubMeshesComputed();
+  theSubComputed = subMeshesComputed();
 
   TopoDS_Shape mainShape = _father->GetMeshDS()->ShapeToMesh();
 
@@ -1827,7 +1924,7 @@ TopoDS_Shape SMESH_subMesh::GetCollection(SMESH_Gen * theGen,
       if (strcmp( anAlgo->GetName(), theAlgo->GetName()) == 0 && // same algo
           anAlgo->GetUsedHypothesis( *_father, S, ignoreAuxiliaryHyps ) == aUsedHyp) // same hyps
         aBuilder.Add( aCompound, S );
-      if ( !subMesh->SubMeshesComputed() )
+      if ( !subMesh->subMeshesComputed() )
         theSubComputed = false;
     }
   }
@@ -1836,14 +1933,14 @@ TopoDS_Shape SMESH_subMesh::GetCollection(SMESH_Gen * theGen,
 }
 
 //=======================================================================
-//function : GetSimilarAttached
+//function : getSimilarAttached
 //purpose  : return a hypothesis attached to theShape.
 //           If theHyp is provided, similar but not same hypotheses
 //           is returned; else only applicable ones having theHypType
 //           is returned
 //=======================================================================
 
-const SMESH_Hypothesis* SMESH_subMesh::GetSimilarAttached(const TopoDS_Shape&      theShape,
+const SMESH_Hypothesis* SMESH_subMesh::getSimilarAttached(const TopoDS_Shape&      theShape,
                                                           const SMESH_Hypothesis * theHyp,
                                                           const int                theHypType)
 {
@@ -1876,7 +1973,7 @@ SMESH_Hypothesis::Hypothesis_Status
   MESSAGE ("SMESH_subMesh::CheckConcurentHypothesis");
 
   // is there local hypothesis on me?
-  if ( GetSimilarAttached( _subShape, 0, theHypType ) )
+  if ( getSimilarAttached( _subShape, 0, theHypType ) )
     return SMESH_Hypothesis::HYP_OK;
 
 
@@ -1886,7 +1983,7 @@ SMESH_Hypothesis::Hypothesis_Status
   for (; it.More(); it.Next())
   {
     const TopoDS_Shape& ancestor = it.Value();
-    const SMESH_Hypothesis* hyp = GetSimilarAttached( ancestor, 0, theHypType );
+    const SMESH_Hypothesis* hyp = getSimilarAttached( ancestor, 0, theHypType );
     if ( hyp )
     {
       if ( aPrevWithHyp.IsNull() || aPrevWithHyp.IsSame( ancestor ))
@@ -1903,14 +2000,26 @@ SMESH_Hypothesis::Hypothesis_Status
   return SMESH_Hypothesis::HYP_OK;
 }
 
+//================================================================================
+/*!
+ * \brief Constructor of OwnListenerData
+ */
+//================================================================================
+
+SMESH_subMesh::OwnListenerData::OwnListenerData( SMESH_subMesh* sm, EventListener* el):
+  mySubMesh( sm ),
+  myMeshID( sm ? sm->GetFather()->GetId() : -1 ),
+  mySubMeshID( sm ? sm->GetId() : -1 ),
+  myListener( el )
+{
+}
+
 //================================================================================
 /*!
  * \brief Sets an event listener and its data to a submesh
  * \param listener - the listener to store
  * \param data - the listener data to store
  * \param where - the submesh to store the listener and it's data
- * \param deleteListener - if true then the listener will be deleted as
- *        it is removed from where submesh
  * 
  * It remembers the submesh where it puts the listener in order to delete
  * them when HYP_OK algo_state is lost
@@ -1923,8 +2032,8 @@ void SMESH_subMesh::SetEventListener(EventListener*     listener,
                                      SMESH_subMesh*     where)
 {
   if ( listener && where ) {
-    where->SetEventListener( listener, data );
-    myOwnListeners.push_back( make_pair( where, listener ));
+    where->setEventListener( listener, data );
+    _ownListeners.push_back( OwnListenerData( where, listener ));
   }
 }
 
@@ -1938,18 +2047,18 @@ void SMESH_subMesh::SetEventListener(EventListener*     listener,
  */
 //================================================================================
 
-void SMESH_subMesh::SetEventListener(EventListener* listener, EventListenerData* data)
+void SMESH_subMesh::setEventListener(EventListener* listener, EventListenerData* data)
 {
   map< EventListener*, EventListenerData* >::iterator l_d =
-    myEventListeners.find( listener );
-  if ( l_d != myEventListeners.end() ) {
+    _eventListeners.find( listener );
+  if ( l_d != _eventListeners.end() ) {
     EventListenerData* curData = l_d->second;
     if ( curData && curData != data && curData->IsDeletable() )
       delete curData;
     l_d->second = data;
   }
   else 
-    myEventListeners.insert( make_pair( listener, data ));
+    _eventListeners.insert( make_pair( listener, data ));
 }
 
 //================================================================================
@@ -1963,8 +2072,8 @@ void SMESH_subMesh::SetEventListener(EventListener* listener, EventListenerData*
 EventListenerData* SMESH_subMesh::GetEventListenerData(EventListener* listener) const
 {
   map< EventListener*, EventListenerData* >::const_iterator l_d =
-    myEventListeners.find( listener );
-  if ( l_d != myEventListeners.end() )
+    _eventListeners.find( listener );
+  if ( l_d != _eventListeners.end() )
     return l_d->second;
   return 0;
 }
@@ -1974,19 +2083,27 @@ EventListenerData* SMESH_subMesh::GetEventListenerData(EventListener* listener)
  * \brief Notify stored event listeners on the occured event
  * \param event - algo_event or compute_event itself
  * \param eventType - algo_event or compute_event
- * \param subMesh - the submesh where the event occures
- * \param data - listener data stored in the subMesh
  * \param hyp - hypothesis, if eventType is algo_event
  */
 //================================================================================
 
-void SMESH_subMesh::NotifyListenersOnEvent( const int         event,
+void SMESH_subMesh::notifyListenersOnEvent( const int         event,
                                             const event_type  eventType,
                                             SMESH_Hypothesis* hyp)
 {
-  map< EventListener*, EventListenerData* >::iterator l_d = myEventListeners.begin();
-  for ( ; l_d != myEventListeners.end(); ++l_d )
-    l_d->first->ProcessEvent( event, eventType, this, l_d->second, hyp );
+  map< EventListener*, EventListenerData* >::iterator l_d = _eventListeners.begin();
+  for ( ; l_d != _eventListeners.end(); ++l_d )
+  {
+    std::pair< EventListener*, EventListenerData* > li_da = *l_d; /* copy to enable removal
+                                                                     of a listener from
+                                                                     _eventListeners by
+                                                                     its ProcessEvent() */
+    if ( li_da.first->myBusySM.insert( this ).second )
+    {
+      li_da.first->ProcessEvent( event, eventType, this, li_da.second, hyp );
+      li_da.first->myBusySM.erase( this );
+    }
+  }
 }
 
 //================================================================================
@@ -1999,11 +2116,11 @@ void SMESH_subMesh::NotifyListenersOnEvent( const int         event,
 void SMESH_subMesh::DeleteEventListener(EventListener* listener)
 {
   map< EventListener*, EventListenerData* >::iterator l_d =
-    myEventListeners.find( listener );
-  if ( l_d != myEventListeners.end() ) {
+    _eventListeners.find( listener );
+  if ( l_d != _eventListeners.end() ) {
     if ( l_d->first  && l_d->first->IsDeletable() )  delete l_d->first;
     if ( l_d->second && l_d->second->IsDeletable() ) delete l_d->second;
-    myEventListeners.erase( l_d );
+    _eventListeners.erase( l_d );
   }
 }
 
@@ -2013,12 +2130,42 @@ void SMESH_subMesh::DeleteEventListener(EventListener* listener)
  */
 //================================================================================
 
-void SMESH_subMesh::DeleteOwnListeners()
+void SMESH_subMesh::deleteOwnListeners()
+{
+  list< OwnListenerData >::iterator d;
+  for ( d = _ownListeners.begin(); d != _ownListeners.end(); ++d )
+  {
+    if ( !_father->MeshExists( d->myMeshID ))
+      continue;
+    if ( _father->GetId() == d->myMeshID && !_father->GetSubMeshContaining( d->mySubMeshID ))
+      continue;
+    d->mySubMesh->DeleteEventListener( d->myListener );
+  }
+  _ownListeners.clear();
+}
+
+//=======================================================================
+//function : loadDependentMeshes
+//purpose  : loads dependent meshes on SUBMESH_LOADED event
+//=======================================================================
+
+void SMESH_subMesh::loadDependentMeshes()
 {
-  list< pair< SMESH_subMesh*, EventListener* > >::iterator sm_l;
-  for ( sm_l = myOwnListeners.begin(); sm_l != myOwnListeners.end(); ++sm_l)
-    sm_l->first->DeleteEventListener( sm_l->second );
-  myOwnListeners.clear();
+  list< OwnListenerData >::iterator d;
+  for ( d = _ownListeners.begin(); d != _ownListeners.end(); ++d )
+    if ( _father != d->mySubMesh->_father )
+      d->mySubMesh->_father->Load();
+
+  // map< EventListener*, EventListenerData* >::iterator l_d = _eventListeners.begin();
+  // for ( ; l_d != _eventListeners.end(); ++l_d )
+  //   if ( l_d->second )
+  //   {
+  //     const list<SMESH_subMesh*>& smList = l_d->second->mySubMeshes;
+  //     list<SMESH_subMesh*>::const_iterator sm = smList.begin();
+  //     for ( ; sm != smList.end(); ++sm )
+  //       if ( _father != (*sm)->_father )
+  //         (*sm)->_father->Load();
+  //   }
 }
 
 //================================================================================
@@ -2129,3 +2276,29 @@ SMESH_subMeshIteratorPtr SMESH_subMesh::getDependsOnIterator(const bool includeS
       ( new _Iterator( new SMDS_mapIterator<TMap>( DependsOn() ), prepend, append ));
   }
 }
+
+//================================================================================
+/*!
+ * \brief  Find common submeshes (based on shared sub-shapes with other
+  * \param theOther submesh to check
+  * \param theSetOfCommon set of common submesh
+ */
+//================================================================================
+
+bool SMESH_subMesh::FindIntersection(const SMESH_subMesh* theOther,
+                                     std::set<const SMESH_subMesh*>& theSetOfCommon ) const
+{
+  int oldNb = theSetOfCommon.size();
+  // check main submeshes
+  const map <int, SMESH_subMesh*>::const_iterator otherEnd = theOther->_mapDepend.end();
+  if ( theOther->_mapDepend.find(this->GetId()) != otherEnd )
+    theSetOfCommon.insert( this );
+  if ( _mapDepend.find(theOther->GetId()) != _mapDepend.end() )
+    theSetOfCommon.insert( theOther );
+  // check common submeshes
+  map <int, SMESH_subMesh*>::const_iterator mapIt = _mapDepend.begin();
+  for( ; mapIt != _mapDepend.end(); mapIt++ )
+    if ( theOther->_mapDepend.find((*mapIt).first) != otherEnd )
+      theSetOfCommon.insert( (*mapIt).second );
+  return oldNb < theSetOfCommon.size();
+}
index ace3a346fbae381e6a850e08a9a1f57b0adacbc1..ee4b96658b924c75c42cf6816548066d79db2bb2 100644 (file)
@@ -1,29 +1,28 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-//  SMESH SMESH : implementaion of SMESH idl descriptions
+
 //  File   : SMESH_subMesh.hxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//  $Header$
 //
 #ifndef _SMESH_SUBMESH_HXX_
 #define _SMESH_SUBMESH_HXX_
@@ -34,6 +33,7 @@
 #include "SMESHDS_SubMesh.hxx"
 #include "SMESH_Hypothesis.hxx"
 #include "SMESH_ComputeError.hxx"
+#include "SMESH_Algo.hxx"
 
 #include "Utils_SALOME_Exception.hxx"
 
@@ -60,7 +60,7 @@ class SMESH_EXPORT SMESH_subMesh
 {
  public:
   SMESH_subMesh(int Id, SMESH_Mesh * father, SMESHDS_Mesh * meshDS,
-               const TopoDS_Shape & aSubShape);
+                const TopoDS_Shape & aSubShape);
   virtual ~ SMESH_subMesh();
 
   int GetId() const;
@@ -74,8 +74,9 @@ class SMESH_EXPORT SMESH_subMesh
 
   SMESH_subMesh *GetFirstToCompute();
 
+  SMESH_Algo* GetAlgo() const;
+
   const std::map < int, SMESH_subMesh * >& DependsOn();
-  //const map < int, SMESH_subMesh * >&Dependants();
   /*!
    * \brief Return iterator on the submeshes this one depends on
    */
@@ -88,11 +89,11 @@ class SMESH_EXPORT SMESH_subMesh
   {
     NOT_READY, READY_TO_COMPUTE,
     COMPUTE_OK, FAILED_TO_COMPUTE
-    };
+  };
   enum algo_state
   {
     NO_ALGO, MISSING_HYP, HYP_OK
-    };
+  };
   enum algo_event
   {
     ADD_HYP          , ADD_ALGO,
@@ -100,13 +101,13 @@ class SMESH_EXPORT SMESH_subMesh
     ADD_FATHER_HYP   , ADD_FATHER_ALGO,
     REMOVE_FATHER_HYP, REMOVE_FATHER_ALGO,
     MODIF_HYP
-    };
+  };
   enum compute_event
   {
-    MODIF_ALGO_STATE, COMPUTE,
-    CLEAN, SUBMESH_COMPUTED, SUBMESH_RESTORED,
+    MODIF_ALGO_STATE, COMPUTE, COMPUTE_CANCELED,
+    CLEAN, SUBMESH_COMPUTED, SUBMESH_RESTORED, SUBMESH_LOADED,
     MESH_ENTITY_REMOVED, CHECK_COMPUTE_STATE
-    };
+  };
   enum event_type
   {
     ALGO_EVENT, COMPUTE_EVENT
@@ -123,7 +124,7 @@ class SMESH_EXPORT SMESH_subMesh
     * \param where - the submesh to store the listener and it's data
    * 
    * The method remembers the submesh \awhere it puts the listener in order to delete
-   * them when HYP_OK algo_state is lost
+   * it when HYP_OK algo_state is lost
    * After being set, event listener is notified on each event of \awhere submesh.
    */
   void SetEventListener(EventListener*     listener,
@@ -146,9 +147,17 @@ class SMESH_EXPORT SMESH_subMesh
 protected:
 
   //!< event listeners to notify
-  std::map< EventListener*, EventListenerData* >           myEventListeners;
+  std::map< EventListener*, EventListenerData* > _eventListeners;
+
   //!< event listeners to delete when HYP_OK algo_state is lost
-  std::list< std::pair< SMESH_subMesh*, EventListener* > > myOwnListeners;
+  struct OwnListenerData {
+    SMESH_subMesh* mySubMesh;
+    int            myMeshID; // id of mySubMesh->GetFather()
+    int            mySubMeshID;
+    EventListener* myListener;
+    OwnListenerData( SMESH_subMesh* sm=0, EventListener* el=0);
+  };
+  std::list< OwnListenerData >                    _ownListeners;
 
   /*!
    * \brief Sets an event listener and its data to a submesh
@@ -157,7 +166,7 @@ protected:
    * 
    * After being set, event listener is notified on each event of a submesh.
    */
-  void SetEventListener(EventListener* listener, EventListenerData* data);
+  void setEventListener(EventListener* listener, EventListenerData* data);
 
   /*!
    * \brief Notify stored event listeners on the occured event
@@ -165,16 +174,22 @@ protected:
    * \param eventType - algo_event or compute_event
    * \param hyp - hypothesis, if eventType is algo_event
    */
-  void NotifyListenersOnEvent( const int         event,
+  void notifyListenersOnEvent( const int         event,
                                const event_type  eventType,
                                SMESH_Hypothesis* hyp = 0);
 
   /*!
    * \brief Delete event listeners depending on algo of this submesh
    */
-  void DeleteOwnListeners();
+  void deleteOwnListeners();
 
-  // ==================================================================
+  /*!
+   * \brief loads dependent meshes on SUBMESH_LOADED event
+   */
+  void loadDependentMeshes();
+
+  // END: Members to track non hierarchical dependencies between submeshes
+  // =====================================================================
 
 public:
 
@@ -191,6 +206,9 @@ public:
   void DumpAlgoState(bool isMain);
 
   bool ComputeStateEngine(int event);
+  void ComputeSubMeshStateEngine(int event, const bool includeSelf=false);
+
+  bool Evaluate(MapShapeNbElems& aResMap);
 
   bool IsConform(const SMESH_Algo* theAlgo);
   // check if a conform mesh will be produced by the Algo
@@ -223,43 +241,44 @@ public:
    *        none mesh entity is bound to it
    */
   void SetIsAlwaysComputed(bool isAlCo);
+  bool IsAlwaysComputed() { return _alwaysComputed; }
 
+  
+  /*!
+   * \brief  Find common submeshes (based on shared subshapes with other
+   * \param theOther submesh to check
+   * \param theCommonIds set of common submesh IDs
+   * NOTE: this method does not cleat set before collect common IDs
+   */
+  bool FindIntersection( const SMESH_subMesh *           theOther,
+                         std::set<const SMESH_subMesh*>& theSetOfCommon ) const;
 
 protected:
   // ==================================================================
-  void InsertDependence(const TopoDS_Shape aSubShape);
+  void insertDependence(const TopoDS_Shape aSubShape);
 
-  bool SubMeshesComputed();
+  bool subMeshesComputed();
+  //bool SubMeshesReady();
 
-  bool SubMeshesReady();
-
-  void RemoveSubMeshElementsAndNodes();
-  void UpdateDependantsState(const compute_event theEvent);
-  void UpdateSubMeshState(const compute_state theState);
-  void ComputeSubMeshStateEngine(int event);
-  void CleanDependants();
-  void CleanDependsOn();
-  void SetAlgoState(int state);
+  void removeSubMeshElementsAndNodes();
+  void updateDependantsState(const compute_event theEvent);
+  void updateSubMeshState(const compute_state theState);
+  void cleanDependants();
+  void cleanDependsOn();
+  void setAlgoState(int state);
 
   /*!
    * \brief Return a shape containing all sub-shapes of the MainShape that can be
    * meshed at once along with _subShape
    */
-  TopoDS_Shape GetCollection(SMESH_Gen * theGen,
+  TopoDS_Shape getCollection(SMESH_Gen * theGen,
                              SMESH_Algo* theAlgo,
                              bool &      theSubComputed);
-
-  /*!
-   * \brief Apply theAlgo to all subshapes in theCollection
-   */
-  bool ApplyToCollection (SMESH_Algo*         theAlgo,
-                          const TopoDS_Shape& theCollection);
-
   /*!
    * \brief Update compute_state by _computeError
     * \retval bool - false if there are errors
    */
-  bool CheckComputeError(SMESH_Algo* theAlgo, const TopoDS_Shape& theShape=TopoDS_Shape());
+  bool checkComputeError(SMESH_Algo* theAlgo, const TopoDS_Shape& theShape=TopoDS_Shape());
 
   /*!
    * \brief Return a hypothesis attached to theShape.
@@ -268,7 +287,7 @@ protected:
    * is returned; else an applicable ones having theHypType
    * is returned
    */
-  const SMESH_Hypothesis* GetSimilarAttached(const TopoDS_Shape&      theShape,
+  const SMESH_Hypothesis* getSimilarAttached(const TopoDS_Shape&      theShape,
                                              const SMESH_Hypothesis * theHyp,
                                              const int                theHypType = 0);
   // 
index 51a79a9c27f20d2c4e01838eb590d302875b5a15..ae911cfefbde029507c776f3b7a214bdcf4c444d 100644 (file)
@@ -1,28 +1,28 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-//  SMESH SMESH : implementaion of SMESH idl descriptions
-// File      : SMESH_subMeshEventListener.hxx
-// Created   : Mon Nov 13 10:45:49 2006
-// Author    : Edward AGAPOV (eap)
+
+// File    : SMESH_subMeshEventListener.hxx
+// Created : Mon Nov 13 10:45:49 2006
+// Author  : Edward AGAPOV (eap)
 //
 #ifndef SMESH_subMeshEventListener_HeaderFile
 #define SMESH_subMeshEventListener_HeaderFile
@@ -30,6 +30,7 @@
 #include "SMESH_SMESH.hxx"
 
 #include <list>
+#include <set>
 
 class  SMESH_subMesh;
 class  SMESH_Hypothesis;
@@ -41,10 +42,21 @@ struct SMESH_subMeshEventListenerData;
  */
 // ------------------------------------------------------------------
 
-class SMESH_EXPORT SMESH_subMeshEventListener {
+class SMESH_EXPORT SMESH_subMeshEventListener
+{
   bool myIsDeletable; //!< if true, it will be deleted by SMESH_subMesh
-public:
-  SMESH_subMeshEventListener(bool isDeletable):myIsDeletable(isDeletable) {}
+  mutable std::set<SMESH_subMesh*> myBusySM; //!< to avoid infinite recursion via events
+  friend class SMESH_subMesh;
+#ifdef _DEBUG_
+  const char* myName; //!< identifier used for debug
+#endif
+
+ public:
+  SMESH_subMeshEventListener(bool isDeletable, const char* name) :myIsDeletable(isDeletable)
+#ifdef _DEBUG_
+    ,myName(name)
+#endif
+  {}
   bool IsDeletable() const { return myIsDeletable; }
   /*!
    * \brief Do something on a certain event
@@ -54,9 +66,9 @@ public:
    * \param data - listener data stored in the subMesh
    * \param hyp - hypothesis, if eventType is algo_event
    * 
-   * The base implementation translates CLEAN event to the subMesh stored
-   * in the listener data. Also it sends SUBMESH_COMPUTED event in case of
-   * successful COMPUTE event.
+   * The base implementation (see SMESH_subMesh.cxx) translates CLEAN event
+   * to the subMeshes stored in the listener data. Also it sends SUBMESH_COMPUTED
+   * event in case of successful COMPUTE event.
    */
   virtual void ProcessEvent(const int          event,
                             const int          eventType,
@@ -75,10 +87,13 @@ struct SMESH_subMeshEventListenerData
 {
   bool myIsDeletable; //!< if true, it will be deleted by SMESH_subMesh
   int myType;         //!< to recognize data type
-  std::list<SMESH_subMesh*> mySubMeshes; //!< generally: submeshes depending
-                                         // on the one storing this data
+  std::list<SMESH_subMesh*> mySubMeshes; /* generally: submeshes depending
+                                            on the one storing this data;
+                                            !! they are used to track intermesh
+                                            dependencies at mesh loading as well !! */
 public:
   SMESH_subMeshEventListenerData(bool isDeletable):myIsDeletable(isDeletable) {}
+  virtual ~SMESH_subMeshEventListenerData() {}
   bool IsDeletable() const { return myIsDeletable; }
 
   /*!
diff --git a/src/SMESH/memoire.h b/src/SMESH/memoire.h
new file mode 100644 (file)
index 0000000..258eda2
--- /dev/null
@@ -0,0 +1,43 @@
+// Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+#ifndef _MEMOIRE_H_
+#define _MEMOIRE_H_
+
+#include <malloc.h>
+#include <iostream>
+
+void memostat(const char* f, int l);
+
+void memostat(const char* f, int l)
+{
+#ifdef WIN32
+       //rnv: TODO: find alternative of the malloc_stats() on windows platform
+#else
+  /*  struct mallinfo mem = mallinfo(); */
+  /*  std::cerr << f << ":"<< l << " " << mem.arena << " " << mem.ordblks << " " << mem.hblks << " " << mem.hblkhd << " "  << mem.uordblks << " "  << mem.fordblks << " " << mem.keepcost << std::endl; */
+  std::cerr << f << ":" << l << " --------------------------" << std::endl;
+  malloc_stats();
+  std::cerr << f << ":" << l << " --------------------------" << std::endl;
+#endif
+}
+
+#define MEMOSTAT //memostat( __FILE__, __LINE__ )
+
+#endif
index ebb0d97f770ebb4bf6f5951d30382550a45388f8..86fd92dc0a027aa6fca3e3c4c0c2d397da0e226b 100644 (file)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  GEOM GEOMClient : tool to transfer BREP files from GEOM server to GEOM client
 #  File   : Makefile.in
 #  Author : Pavel TELKOV (OCC)
@@ -47,6 +45,7 @@ libSMESHClient_la_CPPFLAGS = \
        $(MED_CXXFLAGS) \
        $(GEOM_CXXFLAGS) \
        $(BOOST_CPPFLAGS) \
+        $(VTK_INCLUDES) \
        $(CAS_CPPFLAGS) \
        $(CORBA_CXXFLAGS) \
        $(CORBA_INCLUDES) \
@@ -59,8 +58,7 @@ libSMESHClient_la_CPPFLAGS = \
        -I$(srcdir)/../SMDS \
        -I$(srcdir)/../SMESHDS \
        -I$(srcdir)/../SMESH \
-       -I$(top_builddir)/idl \
-       -I$(top_builddir)/salome_adm/unix
+       -I$(top_builddir)/idl
 
 libSMESHClient_la_LDFLAGS  = \
        ../../idl/libSalomeIDLSMESH.la \
@@ -68,15 +66,16 @@ libSMESHClient_la_LDFLAGS  = \
        ../SMESH/libSMESHimpl.la \
        ../SMESHDS/libSMESHDS.la \
        ../Controls/libSMESHControls.la \
-       $(KERNEL_LDFLAGS) -lSalomeLifeCycleCORBA \
-       $(GEOM_LDFLAGS) -lNMTDS \
-       $(MED_LDFLAGS) -lMEDWrapper_V2_2 -lMEDWrapper_V2_1 \
+       $(KERNEL_LDFLAGS) -lSalomeLifeCycleCORBA -lSalomeNS -lOpUtil -lSALOMEBasics \
+       -lSalomeIDLKernel -lSALOMELocalTrace \
+       $(GEOM_LDFLAGS) -lNMTDS -lSalomeIDLGEOM \
+       $(MED_LDFLAGS) -lMEDWrapper_V2_2 -lMEDWrapper_V2_1 -lSalomeIDLMED -lMEDWrapper \
        $(CAS_KERNEL)
 
 SMESHClientBin_CPPFLAGS = \
        $(libSMESHClient_la_CPPFLAGS)
 
 SMESHClientBin_LDADD = \
-       $(libSMESHClient_la_LDFLAGS)
+       $(libSMESHClient_la_LDFLAGS) @CORBA_LIBS@
 
 
index df47e31f13765bc5431d07224bd008515a0333ed..3183818ff58cc2a0b75932d8133ca5847f3c92f4 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  File   : 
 //  Author : 
 //  Module : 
index af83fe0413484262e1e07f63eaad48690aed420c..f7195b89e3f6687751baea46c397fe3e41e6f335 100644 (file)
@@ -1,31 +1,31 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-//  SMESH SMESHClient : tool to update client mesh structure by mesh from server
 //  File   : SMESH_Client.cxx
 //  Author : Pavel TELKOV
 //  Module : SMESH
-//
+
 #include "SMESH_Client.hxx"
 #include "SMESH_Mesh.hxx"
+#include "SMESHDS_Script.hxx"
 
 #include "SALOME_NamingService.hxx"
 #include "SALOME_LifeCycleCORBA.hxx"
@@ -54,7 +54,7 @@
 #endif
 
 #ifdef _DEBUG_
-static int MYDEBUG = 0;
+static int MYDEBUG = 1;
 #else
 static int MYDEBUG = 0;
 #endif
@@ -83,9 +83,9 @@ namespace
   //=======================================================================
   //function : AddNodesWithID
   //=======================================================================
-  inline void AddNodesWithID(SMDS_Mesh* theMesh, 
-                            SMESH::log_array_var& theSeq,
-                            CORBA::Long theId)
+  inline void AddNodesWithID(SMDS_Mesh* theMesh,
+                             SMESH::log_array_var& theSeq,
+                             CORBA::Long theId)
   {
     const SMESH::double_array& aCoords = theSeq[theId].coords;
     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
@@ -94,11 +94,59 @@ namespace
       EXCEPTION(runtime_error,"AddNodesWithID - 3*aNbElems != aCoords.length()");
     for(CORBA::Long aCoordId = 0; anElemId < aNbElems; anElemId++, aCoordId+=3){
       SMDS_MeshElement* anElem = theMesh->AddNodeWithID(aCoords[aCoordId],
-                                                       aCoords[aCoordId+1],
-                                                       aCoords[aCoordId+2],
-                                                       anIndexes[anElemId]);
+                                                        aCoords[aCoordId+1],
+                                                        aCoords[aCoordId+2],
+                                                        anIndexes[anElemId]);
       if(!anElem)
-       EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddNodeWithID for ID = "<<anElemId);
+        EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddNodeWithID for ID = "<<anElemId);
+    }
+  }
+
+
+  //=======================================================================
+  //function : Add0DElementsWithID
+  //=======================================================================
+  inline void Add0DElementsWithID(SMDS_Mesh* theMesh,
+                                  SMESH::log_array_var& theSeq,
+                                  CORBA::Long theId)
+  {
+    const SMESH::long_array& anIndexes = theSeq[theId].indexes;
+    CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
+    if (2*aNbElems != anIndexes.length())
+      EXCEPTION(runtime_error,"AddEdgeWithID - 2*aNbElems != aCoords.length()");
+    CORBA::Long anIndexId = 0;
+    for (; anElemId < aNbElems; anElemId++, anIndexId+=2)
+    {
+      SMDS_MeshElement* anElem = theMesh->Add0DElementWithID(anIndexes[anIndexId+1],
+                                                             anIndexes[anIndexId]);
+      if (!anElem)
+        EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot Add0DElementWithID for ID = "<<anElemId);
+    }
+  }
+
+
+  //=======================================================================
+  //function : AddBallsWithID
+  //=======================================================================
+  inline void AddBallsWithID(SMDS_Mesh*            theMesh,
+                             SMESH::log_array_var& theSeq,
+                             CORBA::Long           theId)
+  {
+    const SMESH::double_array& aDiameter = theSeq[theId].coords;
+    const SMESH::long_array& anIndexes   = theSeq[theId].indexes;
+    CORBA::Long anElemId = 0, aNbElems   = theSeq[theId].number;
+    if (2*aNbElems != anIndexes.length() )
+      EXCEPTION(runtime_error,"AddEdgeWithID - 2*aNbElems != anIndexes.length()");
+    if (aNbElems != aDiameter.length())
+      EXCEPTION(runtime_error,"AddEdgeWithID - aNbElems != aDiameter.length()");
+    CORBA::Long anIndexId = 0;
+    for (; anElemId < aNbElems; anElemId++, anIndexId+=2)
+    {
+      SMDS_MeshElement* anElem = theMesh->AddBallWithID(anIndexes[anIndexId+1],
+                                                        aDiameter[anElemId],
+                                                        anIndexes[anIndexId]);
+      if (!anElem)
+        EXCEPTION(runtime_error,"cannot SMDS_Mesh::AddBallsWithID for ID = "<<anElemId);
     }
   }
 
@@ -106,9 +154,9 @@ namespace
   //=======================================================================
   //function : AddEdgesWithID
   //=======================================================================
-  inline void AddEdgesWithID(SMDS_Mesh* theMesh, 
-                            SMESH::log_array_var& theSeq,
-                            CORBA::Long theId)
+  inline void AddEdgesWithID(SMDS_Mesh* theMesh,
+                             SMESH::log_array_var& theSeq,
+                             CORBA::Long theId)
   {
     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
@@ -116,10 +164,10 @@ namespace
       EXCEPTION(runtime_error,"AddEdgeWithID - 3*aNbElems != aCoords.length()");
     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=3){
       SMDS_MeshElement* anElem = theMesh->AddEdgeWithID(anIndexes[anIndexId+1],
-                                                       anIndexes[anIndexId+2],
-                                                       anIndexes[anIndexId]);
+                                                        anIndexes[anIndexId+2],
+                                                        anIndexes[anIndexId]);
       if(!anElem)
-       EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddEdgeWithID for ID = "<<anElemId);
+        EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddEdgeWithID for ID = "<<anElemId);
     }
   }
 
@@ -127,9 +175,9 @@ namespace
   //=======================================================================
   //function : AddTriasWithID
   //=======================================================================
-  inline void AddTriasWithID(SMDS_Mesh* theMesh, 
-                            SMESH::log_array_var& theSeq,
-                            CORBA::Long theId)
+  inline void AddTriasWithID(SMDS_Mesh* theMesh,
+                             SMESH::log_array_var& theSeq,
+                             CORBA::Long theId)
   {
     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
@@ -137,11 +185,11 @@ namespace
       EXCEPTION(runtime_error,"AddTriasWithID - 4*aNbElems != anIndexes.length()");
     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=4){
       SMDS_MeshElement* anElem = theMesh->AddFaceWithID(anIndexes[anIndexId+1],
-                                                       anIndexes[anIndexId+2],
-                                                       anIndexes[anIndexId+3],
-                                                       anIndexes[anIndexId]);
+                                                        anIndexes[anIndexId+2],
+                                                        anIndexes[anIndexId+3],
+                                                        anIndexes[anIndexId]);
       if(!anElem)
-       EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
+        EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
     }
   }
 
@@ -149,9 +197,9 @@ namespace
   //=======================================================================
   //function : AddQuadsWithID
   //=======================================================================
-  inline void AddQuadsWithID(SMDS_Mesh* theMesh, 
-                            SMESH::log_array_var theSeq,
-                            CORBA::Long theId)
+  inline void AddQuadsWithID(SMDS_Mesh* theMesh,
+                             SMESH::log_array_var theSeq,
+                             CORBA::Long theId)
   {
     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
@@ -159,12 +207,12 @@ namespace
       EXCEPTION(runtime_error,"AddQuadsWithID - 4*aNbElems != anIndexes.length()");
     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=5){
       SMDS_MeshElement* anElem = theMesh->AddFaceWithID(anIndexes[anIndexId+1],
-                                                       anIndexes[anIndexId+2],
-                                                       anIndexes[anIndexId+3],
-                                                       anIndexes[anIndexId+4],
-                                                       anIndexes[anIndexId]);
+                                                        anIndexes[anIndexId+2],
+                                                        anIndexes[anIndexId+3],
+                                                        anIndexes[anIndexId+4],
+                                                        anIndexes[anIndexId]);
       if(!anElem)
-       EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
+        EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
     }
   }
 
@@ -172,7 +220,7 @@ namespace
   //=======================================================================
   //function : AddPolygonsWithID
   //=======================================================================
-  inline void AddPolygonsWithID(SMDS_Mesh* theMesh, 
+  inline void AddPolygonsWithID(SMDS_Mesh* theMesh,
                                 SMESH::log_array_var& theSeq,
                                 CORBA::Long theId)
   {
@@ -190,7 +238,7 @@ namespace
 
       SMDS_MeshElement* anElem = theMesh->AddPolygonalFaceWithID(nodes_ids, aFaceId);
       if (!anElem)
-       EXCEPTION(runtime_error, "SMDS_Mesh::FindElement - cannot AddPolygonalFaceWithID for ID = "
+        EXCEPTION(runtime_error, "SMDS_Mesh::FindElement - cannot AddPolygonalFaceWithID for ID = "
                   << anElemId);
     }
   }
@@ -199,9 +247,9 @@ namespace
   //=======================================================================
   //function : AddTetrasWithID
   //=======================================================================
-  inline void AddTetrasWithID(SMDS_Mesh* theMesh, 
-                             SMESH::log_array_var& theSeq,
-                             CORBA::Long theId)
+  inline void AddTetrasWithID(SMDS_Mesh* theMesh,
+                              SMESH::log_array_var& theSeq,
+                              CORBA::Long theId)
   {
     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
@@ -209,12 +257,12 @@ namespace
       EXCEPTION(runtime_error,"AddTetrasWithID - 5*aNbElems != anIndexes.length()");
     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=5){
       SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
-                                                         anIndexes[anIndexId+2],
-                                                         anIndexes[anIndexId+3],
-                                                         anIndexes[anIndexId+4],
-                                                         anIndexes[anIndexId]);
+                                                          anIndexes[anIndexId+2],
+                                                          anIndexes[anIndexId+3],
+                                                          anIndexes[anIndexId+4],
+                                                          anIndexes[anIndexId]);
       if(!anElem)
-       EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
+        EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
     }
   }
 
@@ -222,9 +270,9 @@ namespace
   //=======================================================================
   //function : AddPiramidsWithID
   //=======================================================================
-  inline void AddPiramidsWithID(SMDS_Mesh* theMesh, 
-                               SMESH::log_array_var& theSeq,
-                               CORBA::Long theId)
+  inline void AddPiramidsWithID(SMDS_Mesh* theMesh,
+                                SMESH::log_array_var& theSeq,
+                                CORBA::Long theId)
   {
     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
@@ -232,13 +280,13 @@ namespace
       EXCEPTION(runtime_error,"AddPiramidsWithID - 6*aNbElems != anIndexes.length()");
     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=6){
       SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
-                                                         anIndexes[anIndexId+2],
-                                                         anIndexes[anIndexId+3],
-                                                         anIndexes[anIndexId+4],
-                                                         anIndexes[anIndexId+5],
-                                                         anIndexes[anIndexId]);
+                                                          anIndexes[anIndexId+2],
+                                                          anIndexes[anIndexId+3],
+                                                          anIndexes[anIndexId+4],
+                                                          anIndexes[anIndexId+5],
+                                                          anIndexes[anIndexId]);
       if(!anElem)
-       EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
+        EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
     }
   }
 
@@ -246,9 +294,9 @@ namespace
   //=======================================================================
   //function : AddPrismsWithID
   //=======================================================================
-  inline void AddPrismsWithID(SMDS_Mesh* theMesh, 
-                             SMESH::log_array_var& theSeq,
-                             CORBA::Long theId)
+  inline void AddPrismsWithID(SMDS_Mesh* theMesh,
+                              SMESH::log_array_var& theSeq,
+                              CORBA::Long theId)
   {
     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
@@ -256,14 +304,14 @@ namespace
       EXCEPTION(runtime_error,"AddPrismsWithID - 7*aNbElems != anIndexes.length()");
     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=7){
       SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
-                                                         anIndexes[anIndexId+2],
-                                                         anIndexes[anIndexId+3],
-                                                         anIndexes[anIndexId+4],
-                                                         anIndexes[anIndexId+5],
-                                                         anIndexes[anIndexId+6],
-                                                         anIndexes[anIndexId]);
+                                                          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 AddVolumeWithID for ID = "<<anElemId);
+        EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
     }
   }
 
@@ -271,9 +319,9 @@ namespace
   //=======================================================================
   //function : AddHexasWithID
   //=======================================================================
-  inline void AddHexasWithID(SMDS_Mesh* theMesh, 
-                            SMESH::log_array_var& theSeq,
-                            CORBA::Long theId)
+  inline void AddHexasWithID(SMDS_Mesh* theMesh,
+                             SMESH::log_array_var& theSeq,
+                             CORBA::Long theId)
   {
     const SMESH::long_array& anIndexes = theSeq[theId].indexes;
     CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
@@ -281,16 +329,46 @@ namespace
       EXCEPTION(runtime_error,"AddHexasWithID - 9*aNbElems != anIndexes.length()");
     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=9){
       SMDS_MeshElement* anElem = theMesh->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]);
+                                                          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 AddVolumeWithID for ID = "<<anElemId);
+        EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
+    }
+  }
+
+  //=======================================================================
+  //function : AddHexPrismWithID
+  //=======================================================================
+  inline void AddHexPrismWithID(SMDS_Mesh* theMesh,
+                                SMESH::log_array_var& theSeq,
+                                CORBA::Long theId)
+  {
+    const SMESH::long_array& anIndexes = theSeq[theId].indexes;
+    CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
+    if(13*aNbElems != anIndexes.length())
+      EXCEPTION(runtime_error,"AddHexPrismWithID - 13*aNbElems != anIndexes.length()");
+    for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=13){
+      SMDS_MeshElement* anElem = theMesh->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+9],
+                                                          anIndexes[anIndexId+10],
+                                                          anIndexes[anIndexId+11],
+                                                          anIndexes[anIndexId+12],
+                                                          anIndexes[anIndexId]);
+      if(!anElem)
+        EXCEPTION(runtime_error,"AddHexPrismWithID - cannot AddVolumeWithID for ID = "<<anElemId);
     }
   }
 
@@ -298,7 +376,7 @@ namespace
   //=======================================================================
   //function : AddPolyhedronsWithID
   //=======================================================================
-  inline void AddPolyhedronsWithID (SMDS_Mesh* theMesh, 
+  inline void AddPolyhedronsWithID (SMDS_Mesh* theMesh,
                                     SMESH::log_array_var& theSeq,
                                     CORBA::Long theId)
   {
@@ -323,7 +401,7 @@ namespace
       SMDS_MeshElement* anElem =
         theMesh->AddPolyhedralVolumeWithID(nodes_ids, quantities, aFaceId);
       if (!anElem)
-       EXCEPTION(runtime_error, "SMDS_Mesh::FindElement - cannot AddPolyhedralVolumeWithID for ID = "
+        EXCEPTION(runtime_error, "SMDS_Mesh::FindElement - cannot AddPolyhedralVolumeWithID for ID = "
                   << anElemId);
     }
   }
@@ -332,7 +410,7 @@ namespace
   //=======================================================================
   //function : AddQuadEdgesWithID
   //=======================================================================
-  inline void AddQuadEdgesWithID(SMDS_Mesh* theMesh, 
+  inline void AddQuadEdgesWithID(SMDS_Mesh* theMesh,
                                  SMESH::log_array_var& theSeq,
                                  CORBA::Long theId)
   {
@@ -342,11 +420,11 @@ namespace
       EXCEPTION(runtime_error,"AddQuadEdgeWithID - 4*aNbElems != aCoords.length()");
     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=4){
       SMDS_MeshElement* anElem = theMesh->AddEdgeWithID(anIndexes[anIndexId+1],
-                                                       anIndexes[anIndexId+2],
-                                                       anIndexes[anIndexId+3],
-                                                       anIndexes[anIndexId]);
+                                                        anIndexes[anIndexId+2],
+                                                        anIndexes[anIndexId+3],
+                                                        anIndexes[anIndexId]);
       if(!anElem)
-       EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddEdgeWithID for ID = "<<anElemId);
+        EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddEdgeWithID for ID = "<<anElemId);
     }
   }
 
@@ -354,7 +432,7 @@ namespace
   //=======================================================================
   //function : AddQuadTriasWithID
   //=======================================================================
-  inline void AddQuadTriasWithID(SMDS_Mesh* theMesh, 
+  inline void AddQuadTriasWithID(SMDS_Mesh* theMesh,
                                  SMESH::log_array_var& theSeq,
                                  CORBA::Long theId)
   {
@@ -364,14 +442,14 @@ namespace
       EXCEPTION(runtime_error,"AddQuadTriasWithID - 7*aNbElems != anIndexes.length()");
     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=7){
       SMDS_MeshElement* anElem = theMesh->AddFaceWithID(anIndexes[anIndexId+1],
-                                                       anIndexes[anIndexId+2],
-                                                       anIndexes[anIndexId+3],
-                                                       anIndexes[anIndexId+4],
-                                                       anIndexes[anIndexId+5],
-                                                       anIndexes[anIndexId+6],
-                                                       anIndexes[anIndexId]);
+                                                        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 = "<<anElemId);
+        EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
     }
   }
 
@@ -379,7 +457,7 @@ namespace
   //=======================================================================
   //function : AddQuadQuadsWithID
   //=======================================================================
-  inline void AddQuadQuadsWithID(SMDS_Mesh* theMesh, 
+  inline void AddQuadQuadsWithID(SMDS_Mesh* theMesh,
                                  SMESH::log_array_var theSeq,
                                  CORBA::Long theId)
   {
@@ -389,16 +467,43 @@ namespace
       EXCEPTION(runtime_error,"AddQuadQuadsWithID - 9*aNbElems != anIndexes.length()");
     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=9){
       SMDS_MeshElement* anElem = theMesh->AddFaceWithID(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]);
+                                                        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 = "<<anElemId);
+        EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
+    }
+  }
+
+  //=======================================================================
+  //function : AddBiQuadQuadsWithID
+  //=======================================================================
+  inline void AddBiQuadQuadsWithID(SMDS_Mesh* theMesh,
+                                   SMESH::log_array_var theSeq,
+                                   CORBA::Long theId)
+  {
+    const SMESH::long_array& anIndexes = theSeq[theId].indexes;
+    CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
+    if(10*aNbElems != anIndexes.length())
+      EXCEPTION(runtime_error,"AddBiQuadQuadsWithID - 10*aNbElems != anIndexes.length()");
+    for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=10){
+      SMDS_MeshElement* anElem = theMesh->AddFaceWithID(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+9],
+                                                        anIndexes[anIndexId]);
+      if(!anElem)
+        EXCEPTION(runtime_error,"AddBiQuadQuadsWithID() - cannot AddFaceWithID for ID = "<<anElemId);
     }
   }
 
@@ -406,7 +511,7 @@ namespace
   //=======================================================================
   //function : AddQuadTetrasWithID
   //=======================================================================
-  inline void AddQuadTetrasWithID(SMDS_Mesh* theMesh, 
+  inline void AddQuadTetrasWithID(SMDS_Mesh* theMesh,
                                   SMESH::log_array_var& theSeq,
                                   CORBA::Long theId)
   {
@@ -416,18 +521,18 @@ namespace
       EXCEPTION(runtime_error,"AddQuadTetrasWithID - 11*aNbElems != anIndexes.length()");
     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=11){
       SMDS_MeshElement* anElem = theMesh->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+9],
-                                                         anIndexes[anIndexId+10],
-                                                         anIndexes[anIndexId]);
+                                                          anIndexes[anIndexId+2],
+                                                          anIndexes[anIndexId+3],
+                                                          anIndexes[anIndexId+4],
+                                                          anIndexes[anIndexId+5],
+                                                          anIndexes[anIndexId+6],
+                                                          anIndexes[anIndexId+7],
+                                                          anIndexes[anIndexId+8],
+                                                          anIndexes[anIndexId+9],
+                                                          anIndexes[anIndexId+10],
+                                                          anIndexes[anIndexId]);
       if(!anElem)
-       EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
+        EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
     }
   }
 
@@ -435,7 +540,7 @@ namespace
   //=======================================================================
   //function : AddQuadPiramidsWithID
   //=======================================================================
-  inline void AddQuadPiramidsWithID(SMDS_Mesh* theMesh, 
+  inline void AddQuadPiramidsWithID(SMDS_Mesh* theMesh,
                                     SMESH::log_array_var& theSeq,
                                     CORBA::Long theId)
   {
@@ -445,21 +550,21 @@ namespace
       EXCEPTION(runtime_error,"AddQuadPiramidsWithID - 14*aNbElems != anIndexes.length()");
     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=14){
       SMDS_MeshElement* anElem = theMesh->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+9],
-                                                         anIndexes[anIndexId+10],
-                                                         anIndexes[anIndexId+11],
-                                                         anIndexes[anIndexId+12],
-                                                         anIndexes[anIndexId+13],
-                                                         anIndexes[anIndexId]);
+                                                          anIndexes[anIndexId+2],
+                                                          anIndexes[anIndexId+3],
+                                                          anIndexes[anIndexId+4],
+                                                          anIndexes[anIndexId+5],
+                                                          anIndexes[anIndexId+6],
+                                                          anIndexes[anIndexId+7],
+                                                          anIndexes[anIndexId+8],
+                                                          anIndexes[anIndexId+9],
+                                                          anIndexes[anIndexId+10],
+                                                          anIndexes[anIndexId+11],
+                                                          anIndexes[anIndexId+12],
+                                                          anIndexes[anIndexId+13],
+                                                          anIndexes[anIndexId]);
       if(!anElem)
-       EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
+        EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
     }
   }
 
@@ -467,7 +572,7 @@ namespace
   //=======================================================================
   //function : AddQuadPentasWithID
   //=======================================================================
-  inline void AddQuadPentasWithID(SMDS_Mesh* theMesh, 
+  inline void AddQuadPentasWithID(SMDS_Mesh* theMesh,
                                   SMESH::log_array_var& theSeq,
                                   CORBA::Long theId)
   {
@@ -477,23 +582,23 @@ namespace
       EXCEPTION(runtime_error,"AddQuadPentasWithID - 16*aNbElems != anIndexes.length()");
     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=16){
       SMDS_MeshElement* anElem = theMesh->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+9],
-                                                         anIndexes[anIndexId+10],
-                                                         anIndexes[anIndexId+11],
-                                                         anIndexes[anIndexId+12],
-                                                         anIndexes[anIndexId+13],
-                                                         anIndexes[anIndexId+14],
-                                                         anIndexes[anIndexId+15],
-                                                         anIndexes[anIndexId]);
+                                                          anIndexes[anIndexId+2],
+                                                          anIndexes[anIndexId+3],
+                                                          anIndexes[anIndexId+4],
+                                                          anIndexes[anIndexId+5],
+                                                          anIndexes[anIndexId+6],
+                                                          anIndexes[anIndexId+7],
+                                                          anIndexes[anIndexId+8],
+                                                          anIndexes[anIndexId+9],
+                                                          anIndexes[anIndexId+10],
+                                                          anIndexes[anIndexId+11],
+                                                          anIndexes[anIndexId+12],
+                                                          anIndexes[anIndexId+13],
+                                                          anIndexes[anIndexId+14],
+                                                          anIndexes[anIndexId+15],
+                                                          anIndexes[anIndexId]);
       if(!anElem)
-       EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
+        EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
     }
   }
 
@@ -501,7 +606,7 @@ namespace
   //=======================================================================
   //function : AddQuadHexasWithID
   //=======================================================================
-  inline void AddQuadHexasWithID(SMDS_Mesh* theMesh, 
+  inline void AddQuadHexasWithID(SMDS_Mesh* theMesh,
                                  SMESH::log_array_var& theSeq,
                                  CORBA::Long theId)
   {
@@ -511,28 +616,73 @@ namespace
       EXCEPTION(runtime_error,"AddQuadHexasWithID - 21*aNbElems != anIndexes.length()");
     for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=21){
       SMDS_MeshElement* anElem = theMesh->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+9],
-                                                         anIndexes[anIndexId+10],
-                                                         anIndexes[anIndexId+11],
-                                                         anIndexes[anIndexId+12],
-                                                         anIndexes[anIndexId+13],
-                                                         anIndexes[anIndexId+14],
-                                                         anIndexes[anIndexId+15],
-                                                         anIndexes[anIndexId+16],
-                                                         anIndexes[anIndexId+17],
-                                                         anIndexes[anIndexId+18],
-                                                         anIndexes[anIndexId+19],
-                                                         anIndexes[anIndexId+20],
-                                                         anIndexes[anIndexId]);
+                                                          anIndexes[anIndexId+2],
+                                                          anIndexes[anIndexId+3],
+                                                          anIndexes[anIndexId+4],
+                                                          anIndexes[anIndexId+5],
+                                                          anIndexes[anIndexId+6],
+                                                          anIndexes[anIndexId+7],
+                                                          anIndexes[anIndexId+8],
+                                                          anIndexes[anIndexId+9],
+                                                          anIndexes[anIndexId+10],
+                                                          anIndexes[anIndexId+11],
+                                                          anIndexes[anIndexId+12],
+                                                          anIndexes[anIndexId+13],
+                                                          anIndexes[anIndexId+14],
+                                                          anIndexes[anIndexId+15],
+                                                          anIndexes[anIndexId+16],
+                                                          anIndexes[anIndexId+17],
+                                                          anIndexes[anIndexId+18],
+                                                          anIndexes[anIndexId+19],
+                                                          anIndexes[anIndexId+20],
+                                                          anIndexes[anIndexId]);
       if(!anElem)
-       EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
+        EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
+    }
+  }
+
+  //=======================================================================
+  //function : AddTriQuadHexasWithID
+  //=======================================================================
+  inline void AddTriQuadHexasWithID(SMDS_Mesh* theMesh,
+                                    SMESH::log_array_var& theSeq,
+                                    CORBA::Long theId)
+  {
+    const SMESH::long_array& anIndexes = theSeq[theId].indexes;
+    CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
+    if(28*aNbElems != anIndexes.length())
+      EXCEPTION(runtime_error,"AddTriQuadHexasWithID - 28*aNbElems != anIndexes.length()");
+    for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=28){
+      SMDS_MeshElement* anElem = theMesh->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+9],
+                                                          anIndexes[anIndexId+10],
+                                                          anIndexes[anIndexId+11],
+                                                          anIndexes[anIndexId+12],
+                                                          anIndexes[anIndexId+13],
+                                                          anIndexes[anIndexId+14],
+                                                          anIndexes[anIndexId+15],
+                                                          anIndexes[anIndexId+16],
+                                                          anIndexes[anIndexId+17],
+                                                          anIndexes[anIndexId+18],
+                                                          anIndexes[anIndexId+19],
+                                                          anIndexes[anIndexId+20],
+                                                          anIndexes[anIndexId+21],
+                                                          anIndexes[anIndexId+22],
+                                                          anIndexes[anIndexId+23],
+                                                          anIndexes[anIndexId+24],
+                                                          anIndexes[anIndexId+25],
+                                                          anIndexes[anIndexId+26],
+                                                          anIndexes[anIndexId+27],
+                                                          anIndexes[anIndexId]);
+      if(!anElem)
+        EXCEPTION(runtime_error,"AddTriQuadHexasWithID() - cannot AddVolumeWithID for ID = "<<anElemId);
     }
   }
 
@@ -540,7 +690,7 @@ namespace
   //=======================================================================
   //function : ChangePolyhedronNodes
   //=======================================================================
-  inline void ChangePolyhedronNodes (SMDS_Mesh* theMesh, 
+  inline void ChangePolyhedronNodes (SMDS_Mesh* theMesh,
                                      SMESH::log_array_var& theSeq,
                                      CORBA::Long theId)
   {
@@ -572,13 +722,13 @@ namespace
 }
 
 //=======================================================================
-SMESH::SMESH_Gen_var 
+SMESH::SMESH_Gen_var
 SMESH_Client::GetSMESHGen(CORBA::ORB_ptr theORB,
-                         CORBA::Boolean& theIsEmbeddedMode)
+                          CORBA::Boolean& theIsEmbeddedMode)
 {
   static SMESH::SMESH_Gen_var aMeshGen;
 
-  if(CORBA::is_nil(aMeshGen.in())){    
+  if(CORBA::is_nil(aMeshGen.in())){
 #ifdef WNT
     long aClientPID = (long)_getpid();
 #else
@@ -587,9 +737,9 @@ SMESH_Client::GetSMESHGen(CORBA::ORB_ptr theORB,
 
     SALOME_NamingService aNamingService(theORB);
     SALOME_LifeCycleCORBA aLifeCycleCORBA(&aNamingService);
-    Engines::Component_var aComponent = aLifeCycleCORBA.FindOrLoad_Component("FactoryServer","SMESH");
+    Engines::EngineComponent_var aComponent = aLifeCycleCORBA.FindOrLoad_Component("FactoryServer","SMESH");
     aMeshGen = SMESH::SMESH_Gen::_narrow(aComponent);
-    
+
     std::string aClientHostName = Kernel_Utils::GetHostname();
     Engines::Container_var aServerContainer = aMeshGen->GetContainerRef();
     CORBA::String_var aServerHostName = aServerContainer->getHostName();
@@ -604,14 +754,15 @@ SMESH_Client::GetSMESHGen(CORBA::ORB_ptr theORB,
 
 //=======================================================================
 // function : Create()
-// purpose  : 
+// purpose  :
 //=======================================================================
 SMESH_Client::SMESH_Client(CORBA::ORB_ptr theORB,
-                          SMESH::SMESH_Mesh_ptr theMesh):
+                           SMESH::SMESH_Mesh_ptr theMesh):
   myMeshServer(SMESH::SMESH_Mesh::_duplicate(theMesh)),
   mySMESHDSMesh(NULL),
   mySMDSMesh(NULL)
 {
+  MESSAGE("SMESH_Client::SMESH_Client");
   myMeshServer->Register();
 
   CORBA::Boolean anIsEmbeddedMode;
@@ -627,7 +778,8 @@ SMESH_Client::SMESH_Client(CORBA::ORB_ptr theORB,
     SMESH_Mesh* aMesh = reinterpret_cast<SMESH_Mesh*> (pointeur);
     if ( MYDEBUG )
       MESSAGE("SMESH_Client::SMESH_Client aMesh "<<aMesh);
-    if(aMesh->GetMeshDS()->IsEmbeddedMode()){
+    //if(aMesh->GetMeshDS()->IsEmbeddedMode()){
+    if(anIsEmbeddedMode){
       mySMESHDSMesh = aMesh->GetMeshDS();
       mySMDSMesh = mySMESHDSMesh;
     }
@@ -643,17 +795,17 @@ SMESH_Client::SMESH_Client(CORBA::ORB_ptr theORB,
 //=================================================================================
 SMESH_Client::~SMESH_Client()
 {
-  myMeshServer->Destroy();
+  myMeshServer->UnRegister();
   if(!mySMESHDSMesh)
     delete mySMDSMesh;
 }
 
 
 //=================================================================================
-SMDS_Mesh* 
-SMESH_Client::GetMesh() const 
+SMDS_Mesh*
+SMESH_Client::GetMesh() const
 {
-  return mySMDSMesh; 
+  return mySMDSMesh;
 }
 
 
@@ -669,7 +821,7 @@ SMESH_Client::operator->() const
 SMESH::SMESH_Mesh_ptr
 SMESH_Client::GetMeshServer()
 {
-  return myMeshServer.in(); 
+  return myMeshServer.in();
 }
 
 
@@ -682,16 +834,18 @@ SMESH_Client::Update(bool theIsClear)
 {
   bool anIsModified = true;
   if(mySMESHDSMesh){
+        MESSAGE("Update mySMESHDSMesh");
     SMESHDS_Script* aScript = mySMESHDSMesh->GetScript();
     anIsModified = aScript->IsModified();
     aScript->SetModified(false);
   }else{
+        MESSAGE("Update CORBA");
     SMESH::log_array_var aSeq = myMeshServer->GetLog( theIsClear );
     CORBA::Long aLength = aSeq->length();
     anIsModified = aLength > 0;
     if( MYDEBUG )
       MESSAGE( "Update: length of the script is "<<aLength );
-  
+
     if(!anIsModified)
       return false;
 
@@ -700,31 +854,36 @@ SMESH_Client::Update(bool theIsClear)
     {
       for ( CORBA::Long anId = 0; anId < aLength; anId++)
       {
-       const SMESH::double_array& aCoords = aSeq[anId].coords;
-       const SMESH::long_array& anIndexes = aSeq[anId].indexes;
-       CORBA::Long anElemId = 0, aNbElems = aSeq[anId].number;
-       CORBA::Long aCommand = aSeq[anId].commandType;
+        const SMESH::double_array& aCoords = aSeq[anId].coords;
+        const SMESH::long_array& anIndexes = aSeq[anId].indexes;
+        CORBA::Long anElemId = 0, aNbElems = aSeq[anId].number;
+        CORBA::Long aCommand = aSeq[anId].commandType;
 
-       switch(aCommand)
+        switch(aCommand)
         {
-       case SMESH::ADD_NODE       : AddNodesWithID      ( mySMDSMesh, aSeq, anId ); break;
-        case SMESH::ADD_EDGE       : AddEdgesWithID      ( mySMDSMesh, aSeq, anId ); break;
-        case SMESH::ADD_TRIANGLE   : AddTriasWithID      ( mySMDSMesh, aSeq, anId ); break;
-        case SMESH::ADD_QUADRANGLE : AddQuadsWithID      ( mySMDSMesh, aSeq, anId ); break;
-        case SMESH::ADD_POLYGON    : AddPolygonsWithID   ( mySMDSMesh, aSeq, anId ); break;
-        case SMESH::ADD_TETRAHEDRON: AddTetrasWithID     ( mySMDSMesh, aSeq, anId ); break;
-        case SMESH::ADD_PYRAMID    : AddPiramidsWithID   ( mySMDSMesh, aSeq, anId ); break;
-        case SMESH::ADD_PRISM      : AddPrismsWithID     ( mySMDSMesh, aSeq, anId ); break;
-        case SMESH::ADD_HEXAHEDRON : AddHexasWithID      ( mySMDSMesh, aSeq, anId ); break;
-        case SMESH::ADD_POLYHEDRON : AddPolyhedronsWithID( mySMDSMesh, aSeq, anId ); break;
-
-        case SMESH::ADD_QUADEDGE       : AddQuadEdgesWithID   ( mySMDSMesh, aSeq, anId ); break;
-        case SMESH::ADD_QUADTRIANGLE   : AddQuadTriasWithID   ( mySMDSMesh, aSeq, anId ); break;
-        case SMESH::ADD_QUADQUADRANGLE : AddQuadQuadsWithID   ( mySMDSMesh, aSeq, anId ); break;
-        case SMESH::ADD_QUADTETRAHEDRON: AddQuadTetrasWithID  ( mySMDSMesh, aSeq, anId ); break;
-        case SMESH::ADD_QUADPYRAMID    : AddQuadPiramidsWithID( mySMDSMesh, aSeq, anId ); break;
-        case SMESH::ADD_QUADPENTAHEDRON: AddQuadPentasWithID  ( mySMDSMesh, aSeq, anId ); break;
-        case SMESH::ADD_QUADHEXAHEDRON : AddQuadHexasWithID   ( mySMDSMesh, aSeq, anId ); break;
+        case SMESH::ADD_NODE             : AddNodesWithID      ( mySMDSMesh, aSeq, anId ); break;
+        case SMESH::ADD_EDGE             : AddEdgesWithID      ( mySMDSMesh, aSeq, anId ); break;
+        case SMESH::ADD_TRIANGLE         : AddTriasWithID      ( mySMDSMesh, aSeq, anId ); break;
+        case SMESH::ADD_QUADRANGLE       : AddQuadsWithID      ( mySMDSMesh, aSeq, anId ); break;
+        case SMESH::ADD_POLYGON          : AddPolygonsWithID   ( mySMDSMesh, aSeq, anId ); break;
+        case SMESH::ADD_TETRAHEDRON      : AddTetrasWithID     ( mySMDSMesh, aSeq, anId ); break;
+        case SMESH::ADD_PYRAMID          : AddPiramidsWithID   ( mySMDSMesh, aSeq, anId ); break;
+        case SMESH::ADD_PRISM            : AddPrismsWithID     ( mySMDSMesh, aSeq, anId ); break;
+        case SMESH::ADD_HEXAHEDRON       : AddHexasWithID      ( mySMDSMesh, aSeq, anId ); break;
+        case SMESH::ADD_HEXAGONAL_PRISM  : AddHexPrismWithID   ( mySMDSMesh, aSeq, anId ); break;
+        case SMESH::ADD_POLYHEDRON       : AddPolyhedronsWithID( mySMDSMesh, aSeq, anId ); break;
+        case SMESH::ADD_ELEM0D           : Add0DElementsWithID ( mySMDSMesh, aSeq, anId ); break;
+        case SMESH::ADD_BALL             : AddBallsWithID      ( mySMDSMesh, aSeq, anId ); break;
+
+        case SMESH::ADD_QUADEDGE         : AddQuadEdgesWithID   ( mySMDSMesh, aSeq, anId ); break;
+        case SMESH::ADD_QUADTRIANGLE     : AddQuadTriasWithID   ( mySMDSMesh, aSeq, anId ); break;
+        case SMESH::ADD_QUADQUADRANGLE   : AddQuadQuadsWithID   ( mySMDSMesh, aSeq, anId ); break;
+        case SMESH::ADD_BIQUAD_QUADRANGLE: AddBiQuadQuadsWithID ( mySMDSMesh, aSeq, anId ); break;
+        case SMESH::ADD_QUADTETRAHEDRON  : AddQuadTetrasWithID  ( mySMDSMesh, aSeq, anId ); break;
+        case SMESH::ADD_QUADPYRAMID      : AddQuadPiramidsWithID( mySMDSMesh, aSeq, anId ); break;
+        case SMESH::ADD_QUADPENTAHEDRON  : AddQuadPentasWithID  ( mySMDSMesh, aSeq, anId ); break;
+        case SMESH::ADD_QUADHEXAHEDRON   : AddQuadHexasWithID   ( mySMDSMesh, aSeq, anId ); break;
+        case SMESH::ADD_TRIQUAD_HEXA     : AddTriQuadHexasWithID( mySMDSMesh, aSeq, anId ); break;
 
         case SMESH::CLEAR_MESH:
           mySMDSMesh->Clear();
@@ -734,7 +893,7 @@ SMESH_Client::Update(bool theIsClear)
           for( ; anElemId < aNbElems; anElemId++ )
             mySMDSMesh->RemoveNode( FindNode( mySMDSMesh, anIndexes[anElemId] ) );
         break;
-        
+
         case SMESH::REMOVE_ELEMENT:
           for( ; anElemId < aNbElems; anElemId++ )
             mySMDSMesh->RemoveElement( FindElement( mySMDSMesh, anIndexes[anElemId] ) );
@@ -775,9 +934,9 @@ SMESH_Client::Update(bool theIsClear)
             mySMDSMesh->Renumber( anIndexes[i], anIndexes[i+1], anIndexes[i+2] );
           }
           break;
-          
+
         default:;
-       }
+        }
       }
     }
     catch ( SALOME::SALOME_Exception& exc )
@@ -796,11 +955,12 @@ SMESH_Client::Update(bool theIsClear)
     if ( MYDEBUG && mySMDSMesh )
     {
       MESSAGE("Update - mySMDSMesh->NbNodes() = "<<mySMDSMesh->NbNodes());
+      MESSAGE("Update - mySMDSMesh->Nb0DElements() = "<<mySMDSMesh->Nb0DElements());
       MESSAGE("Update - mySMDSMesh->NbEdges() = "<<mySMDSMesh->NbEdges());
       MESSAGE("Update - mySMDSMesh->NbFaces() = "<<mySMDSMesh->NbFaces());
       MESSAGE("Update - mySMDSMesh->NbVolumes() = "<<mySMDSMesh->NbVolumes());
     }
   } // end of update mesh by log script
-  
+
   return anIsModified;
 }
index 99e3de4b851179a2cd52979590903109b5ef2332..65c111c2e097ef97ad464efe8b2b25d3bd2c3f6d 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESHClient : tool to update client mesh structure by mesh from server
 //  File   : SMESH_Client.hxx
 //  Author : Pavel TELKOV
@@ -32,7 +33,7 @@
 #include CORBA_SERVER_HEADER(SMESH_Mesh)
 
 #ifdef WNT
-# ifdef SMESHCLIENT_EXPORTS
+# if defined SMESHCLIENT_EXPORTS || defined SMESHClient_EXPORTS
 #  define SMESHCLIENT_EXPORT __declspec( dllexport )
 # else
 #  define SMESHCLIENT_EXPORT __declspec( dllimport )
@@ -54,10 +55,10 @@ public:
   static 
   SMESH::SMESH_Gen_var
   GetSMESHGen(CORBA::ORB_ptr theORB,
-             CORBA::Boolean& theIsEmbeddedMode);
+              CORBA::Boolean& theIsEmbeddedMode);
 
   SMESH_Client(CORBA::ORB_ptr theORB,
-              SMESH::SMESH_Mesh_ptr theMesh);
+               SMESH::SMESH_Mesh_ptr theMesh);
   ~SMESH_Client();
 
   bool 
index b9c3673f33a592578403e2b44fd49bb7c17b0066..745ccca8f724a4e4ad77b47367355fc76473addc 100644 (file)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  SMESH SMESHDS : management of mesh data and SMESH document
 #  File   : Makefile.in
 #  Author : Patrick GOLDBRONN (CEA)
@@ -39,8 +37,10 @@ salomeinclude_HEADERS = \
        SMESHDS_GroupBase.hxx \
        SMESHDS_Group.hxx \
        SMESHDS_GroupOnGeom.hxx \
+       SMESHDS_GroupOnFilter.hxx \
        SMESH_SMESHDS.hxx \
-       SMESHDS_DataMapOfShape.hxx
+       SMESHDS_DataMapOfShape.hxx \
+       SMESH_Controls.hxx
 
 # Libraries targets
 lib_LTLIBRARIES = libSMESHDS.la
@@ -54,12 +54,14 @@ dist_libSMESHDS_la_SOURCES = \
        SMESHDS_Mesh.cxx \
        SMESHDS_GroupBase.cxx \
        SMESHDS_Group.cxx \
-       SMESHDS_GroupOnGeom.cxx
+       SMESHDS_GroupOnGeom.cxx \
+       SMESHDS_GroupOnFilter.cxx
 
 # additionnal information to compil and link file
 libSMESHDS_la_CPPFLAGS = \
        $(KERNEL_CXXFLAGS) \
        $(CAS_CPPFLAGS) \
+        $(VTK_INCLUDES) \
        $(BOOST_CPPFLAGS) \
        -I$(srcdir)/../SMDS
 
index be0e5e63250766699e165ca6873e23ee883887ef..658ad24aec08c31fe857207d49bd6fb651fd5ef9 100644 (file)
@@ -1,29 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESHDS : management of mesh data and SMESH document
 //  File   : SMESH_Command.cxx
 //  Author : Yves FRICAUD, OCC
 //  Module : SMESH
-//  $Header: 
 //
 #include "SMESHDS_Command.hxx"
 
@@ -54,16 +54,16 @@ SMESHDS_Command::~SMESHDS_Command()
 //=======================================================================
 void SMESHDS_Command::AddNode(int NewNodeID, double x, double y, double z)
 {
-       if (!myType == SMESHDS_AddNode)
-       {
-               MESSAGE("SMESHDS_Command::AddNode : Bad Type");
-               return;
-       }
-       myIntegers.push_back(NewNodeID);
-       myReals.push_back(x);
-       myReals.push_back(y);
-       myReals.push_back(z);
-       myNumber++;
+        if (!myType == SMESHDS_AddNode)
+        {
+                MESSAGE("SMESHDS_Command::AddNode : Bad Type");
+                return;
+        }
+        myIntegers.push_back(NewNodeID);
+        myReals.push_back(x);
+        myReals.push_back(y);
+        myReals.push_back(z);
+        myNumber++;
 }
 
 //=======================================================================
@@ -72,16 +72,32 @@ void SMESHDS_Command::AddNode(int NewNodeID, double x, double y, double z)
 //=======================================================================
 void SMESHDS_Command::MoveNode(int NodeID, double x, double y, double z)
 {
-       if (!myType == SMESHDS_MoveNode)
-       {
-               MESSAGE("SMESHDS_Command::MoveNode : Bad Type");
-               return;
-       }
-       myIntegers.push_back(NodeID);
-       myReals.push_back(x);
-       myReals.push_back(y);
-       myReals.push_back(z);
-       myNumber++;
+        if (!myType == SMESHDS_MoveNode)
+        {
+                MESSAGE("SMESHDS_Command::MoveNode : Bad Type");
+                return;
+        }
+        myIntegers.push_back(NodeID);
+        myReals.push_back(x);
+        myReals.push_back(y);
+        myReals.push_back(z);
+        myNumber++;
+}
+
+//=======================================================================
+//function : 
+//purpose  : 
+//=======================================================================
+void SMESHDS_Command::Add0DElement(int New0DElementID, int idnode)
+{
+  if (!myType == SMESHDS_Add0DElement)
+  {
+    MESSAGE("SMESHDS_Command::Add0DElement : Bad Type");
+    return;
+  }
+  myIntegers.push_back(New0DElementID);
+  myIntegers.push_back(idnode);
+  myNumber++;
 }
 
 //=======================================================================
@@ -90,15 +106,15 @@ void SMESHDS_Command::MoveNode(int NodeID, double x, double y, double z)
 //=======================================================================
 void SMESHDS_Command::AddEdge(int NewEdgeID, int idnode1, int idnode2)
 {
-       if (!myType == SMESHDS_AddEdge)
-       {
-               MESSAGE("SMESHDS_Command::AddEdge : Bad Type");
-               return;
-       }
-       myIntegers.push_back(NewEdgeID);
-       myIntegers.push_back(idnode1);
-       myIntegers.push_back(idnode2);
-       myNumber++;
+        if (!myType == SMESHDS_AddEdge)
+        {
+                MESSAGE("SMESHDS_Command::AddEdge : Bad Type");
+                return;
+        }
+        myIntegers.push_back(NewEdgeID);
+        myIntegers.push_back(idnode1);
+        myIntegers.push_back(idnode2);
+        myNumber++;
 }
 
 //=======================================================================
@@ -106,18 +122,18 @@ void SMESHDS_Command::AddEdge(int NewEdgeID, int idnode1, int idnode2)
 //purpose  : 
 //=======================================================================
 void SMESHDS_Command::AddFace(int NewFaceID,
-       int idnode1, int idnode2, int idnode3)
+        int idnode1, int idnode2, int idnode3)
 {
-       if (!myType == SMESHDS_AddTriangle)
-       {
-               MESSAGE("SMESHDS_Command::AddFace : Bad Type");
-               return;
-       }
-       myIntegers.push_back(NewFaceID);
-       myIntegers.push_back(idnode1);
-       myIntegers.push_back(idnode2);
-       myIntegers.push_back(idnode3);
-       myNumber++;
+        if (!myType == SMESHDS_AddTriangle)
+        {
+                MESSAGE("SMESHDS_Command::AddFace : Bad Type");
+                return;
+        }
+        myIntegers.push_back(NewFaceID);
+        myIntegers.push_back(idnode1);
+        myIntegers.push_back(idnode2);
+        myIntegers.push_back(idnode3);
+        myNumber++;
 }
 
 //=======================================================================
@@ -125,19 +141,19 @@ void SMESHDS_Command::AddFace(int NewFaceID,
 //purpose  : 
 //=======================================================================
 void SMESHDS_Command::AddFace(int NewFaceID,
-       int idnode1, int idnode2, int idnode3, int idnode4)
+        int idnode1, int idnode2, int idnode3, int idnode4)
 {
-       if (!myType == SMESHDS_AddQuadrangle)
-       {
-               MESSAGE("SMESHDS_Command::AddFace : Bad Type");
-               return;
-       }
-       myIntegers.push_back(NewFaceID);
-       myIntegers.push_back(idnode1);
-       myIntegers.push_back(idnode2);
-       myIntegers.push_back(idnode3);
-       myIntegers.push_back(idnode4);
-       myNumber++;
+        if (!myType == SMESHDS_AddQuadrangle)
+        {
+                MESSAGE("SMESHDS_Command::AddFace : Bad Type");
+                return;
+        }
+        myIntegers.push_back(NewFaceID);
+        myIntegers.push_back(idnode1);
+        myIntegers.push_back(idnode2);
+        myIntegers.push_back(idnode3);
+        myIntegers.push_back(idnode4);
+        myNumber++;
 }
 
 //=======================================================================
@@ -145,19 +161,19 @@ void SMESHDS_Command::AddFace(int NewFaceID,
 //purpose  : 
 //=======================================================================
 void SMESHDS_Command::AddVolume(int NewVolID,
-       int idnode1, int idnode2, int idnode3, int idnode4)
+        int idnode1, int idnode2, int idnode3, int idnode4)
 {
-       if (!myType == SMESHDS_AddTetrahedron)
-       {
-               MESSAGE("SMESHDS_Command::AddVolume : Bad Type");
-               return;
-       }
-       myIntegers.push_back(NewVolID);
-       myIntegers.push_back(idnode1);
-       myIntegers.push_back(idnode2);
-       myIntegers.push_back(idnode3);
-       myIntegers.push_back(idnode4);
-       myNumber++;
+        if (!myType == SMESHDS_AddTetrahedron)
+        {
+                MESSAGE("SMESHDS_Command::AddVolume : Bad Type");
+                return;
+        }
+        myIntegers.push_back(NewVolID);
+        myIntegers.push_back(idnode1);
+        myIntegers.push_back(idnode2);
+        myIntegers.push_back(idnode3);
+        myIntegers.push_back(idnode4);
+        myNumber++;
 }
 
 //=======================================================================
@@ -165,20 +181,20 @@ void SMESHDS_Command::AddVolume(int NewVolID,
 //purpose  : 
 //=======================================================================
 void SMESHDS_Command::AddVolume(int NewVolID,
-       int idnode1, int idnode2, int idnode3, int idnode4, int idnode5)
+        int idnode1, int idnode2, int idnode3, int idnode4, int idnode5)
 {
-       if (!myType == SMESHDS_AddPyramid)
-       {
-               MESSAGE("SMESHDS_Command::AddVolume : Bad Type");
-               return;
-       }
-       myIntegers.push_back(NewVolID);
-       myIntegers.push_back(idnode1);
-       myIntegers.push_back(idnode2);
-       myIntegers.push_back(idnode3);
-       myIntegers.push_back(idnode4);
-       myIntegers.push_back(idnode5);
-       myNumber++;
+        if (!myType == SMESHDS_AddPyramid)
+        {
+                MESSAGE("SMESHDS_Command::AddVolume : Bad Type");
+                return;
+        }
+        myIntegers.push_back(NewVolID);
+        myIntegers.push_back(idnode1);
+        myIntegers.push_back(idnode2);
+        myIntegers.push_back(idnode3);
+        myIntegers.push_back(idnode4);
+        myIntegers.push_back(idnode5);
+        myNumber++;
 }
 
 //=======================================================================
@@ -186,22 +202,22 @@ void SMESHDS_Command::AddVolume(int NewVolID,
 //purpose  : 
 //=======================================================================
 void SMESHDS_Command::AddVolume(int NewVolID,
-       int idnode1,
-       int idnode2, int idnode3, int idnode4, int idnode5, int idnode6)
+        int idnode1,
+        int idnode2, int idnode3, int idnode4, int idnode5, int idnode6)
 {
-       if (!myType == SMESHDS_AddPrism)
-       {
-               MESSAGE("SMESHDS_Command::AddVolume : Bad Type");
-               return;
-       }
-       myIntegers.push_back(NewVolID);
-       myIntegers.push_back(idnode1);
-       myIntegers.push_back(idnode2);
-       myIntegers.push_back(idnode3);
-       myIntegers.push_back(idnode4);
-       myIntegers.push_back(idnode5);
-       myIntegers.push_back(idnode6);
-       myNumber++;
+        if (!myType == SMESHDS_AddPrism)
+        {
+                MESSAGE("SMESHDS_Command::AddVolume : Bad Type");
+                return;
+        }
+        myIntegers.push_back(NewVolID);
+        myIntegers.push_back(idnode1);
+        myIntegers.push_back(idnode2);
+        myIntegers.push_back(idnode3);
+        myIntegers.push_back(idnode4);
+        myIntegers.push_back(idnode5);
+        myIntegers.push_back(idnode6);
+        myNumber++;
 }
 
 //=======================================================================
@@ -209,34 +225,60 @@ void SMESHDS_Command::AddVolume(int NewVolID,
 //purpose  : 
 //=======================================================================
 void SMESHDS_Command::AddVolume(int NewVolID,
-       int idnode1,
-       int idnode2,
-       int idnode3,
-       int idnode4, int idnode5, int idnode6, int idnode7, int idnode8)
-{
-       if (!myType == SMESHDS_AddHexahedron)
-       {
-               MESSAGE("SMESHDS_Command::AddVolume : Bad Type");
-               return;
-       }
-       myIntegers.push_back(NewVolID);
-       myIntegers.push_back(idnode1);
-       myIntegers.push_back(idnode2);
-       myIntegers.push_back(idnode3);
-       myIntegers.push_back(idnode4);
-       myIntegers.push_back(idnode5);
-       myIntegers.push_back(idnode6);
-       myIntegers.push_back(idnode7);
-       myIntegers.push_back(idnode8);
-       myNumber++;
+        int idnode1,
+        int idnode2,
+        int idnode3,
+        int idnode4, int idnode5, int idnode6, int idnode7, int idnode8)
+{
+        if (!myType == SMESHDS_AddHexahedron)
+        {
+                MESSAGE("SMESHDS_Command::AddVolume : Bad Type");
+                return;
+        }
+        myIntegers.push_back(NewVolID);
+        myIntegers.push_back(idnode1);
+        myIntegers.push_back(idnode2);
+        myIntegers.push_back(idnode3);
+        myIntegers.push_back(idnode4);
+        myIntegers.push_back(idnode5);
+        myIntegers.push_back(idnode6);
+        myIntegers.push_back(idnode7);
+        myIntegers.push_back(idnode8);
+        myNumber++;
+}
+
+void SMESHDS_Command::AddVolume(int NewVolID,
+                                int idnode1,int idnode2,int idnode3,int idnode4,
+                                int idnode5, int idnode6, int idnode7, int idnode8,
+                                int idnode9, int idnode10, int idnode11, int idnode12)
+{
+  if (myType != SMESHDS_AddHexagonalPrism)
+  {
+    MESSAGE("SMESHDS_Command::AddVolume : Bad Type");
+    return;
+  }
+  myIntegers.push_back(NewVolID);
+  myIntegers.push_back(idnode1);
+  myIntegers.push_back(idnode2);
+  myIntegers.push_back(idnode3);
+  myIntegers.push_back(idnode4);
+  myIntegers.push_back(idnode5);
+  myIntegers.push_back(idnode6);
+  myIntegers.push_back(idnode7);
+  myIntegers.push_back(idnode8);
+  myIntegers.push_back(idnode9);
+  myIntegers.push_back(idnode10);
+  myIntegers.push_back(idnode11);
+  myIntegers.push_back(idnode12);
+  myNumber++;
 }
 
 //=======================================================================
 //function : AddPolygonalFace
 //purpose  : 
 //=======================================================================
-void SMESHDS_Command::AddPolygonalFace (const int        ElementID,
-                                        std::vector<int> nodes_ids)
+void SMESHDS_Command::AddPolygonalFace (const int               ElementID,
+                                        const std::vector<int>& nodes_ids)
 {
   if (!myType == SMESHDS_AddPolygon) {
     MESSAGE("SMESHDS_Command::AddPolygonalFace : Bad Type");
@@ -257,9 +299,9 @@ void SMESHDS_Command::AddPolygonalFace (const int        ElementID,
 //function : AddPolyhedralVolume
 //purpose  : 
 //=======================================================================
-void SMESHDS_Command::AddPolyhedralVolume (const int        ElementID,
-                                           std::vector<int> nodes_ids,
-                                           std::vector<int> quantities)
+void SMESHDS_Command::AddPolyhedralVolume (const int               ElementID,
+                                           const std::vector<int>& nodes_ids,
+                                           const std::vector<int>& quantities)
 {
   if (!myType == SMESHDS_AddPolyhedron) {
     MESSAGE("SMESHDS_Command::AddPolyhedralVolume : Bad Type");
@@ -288,13 +330,13 @@ void SMESHDS_Command::AddPolyhedralVolume (const int        ElementID,
 //=======================================================================
 void SMESHDS_Command::RemoveNode(int NodeID)
 {
-       if (!myType == SMESHDS_RemoveNode)
-       {
-               MESSAGE("SMESHDS_Command::RemoveNode : Bad Type");
-               return;
-       }
-       myIntegers.push_back(NodeID);
-       myNumber++;
+        if (!myType == SMESHDS_RemoveNode)
+        {
+                MESSAGE("SMESHDS_Command::RemoveNode : Bad Type");
+                return;
+        }
+        myIntegers.push_back(NodeID);
+        myNumber++;
 }
 
 //=======================================================================
@@ -303,13 +345,13 @@ void SMESHDS_Command::RemoveNode(int NodeID)
 //=======================================================================
 void SMESHDS_Command::RemoveElement(int ElementID)
 {
-       if (!myType == SMESHDS_RemoveElement)
-       {
-               MESSAGE("SMESHDS_Command::RemoveElement : Bad Type");
-               return;
-       }
-       myIntegers.push_back(ElementID);
-       myNumber++;
+        if (!myType == SMESHDS_RemoveElement)
+        {
+                MESSAGE("SMESHDS_Command::RemoveElement : Bad Type");
+                return;
+        }
+        myIntegers.push_back(ElementID);
+        myNumber++;
 }
 
 //=======================================================================
@@ -336,9 +378,9 @@ void SMESHDS_Command::ChangeElementNodes(int ElementID, int nodes[], int nbnodes
 //function : ChangePolyhedronNodes
 //purpose  : 
 //=======================================================================
-void SMESHDS_Command::ChangePolyhedronNodes (const int ElementID,
-                                             std::vector<int> nodes_ids,
-                                             std::vector<int> quantities)
+void SMESHDS_Command::ChangePolyhedronNodes (const int               ElementID,
+                                             const std::vector<int>& nodes_ids,
+                                             const std::vector<int>& quantities)
 {
   if (myType != SMESHDS_ChangePolyhedronNodes)
   {
@@ -386,7 +428,7 @@ void SMESHDS_Command::Renumber (const bool isNodes, const int startID, const int
 //=======================================================================
 SMESHDS_CommandType SMESHDS_Command::GetType()
 {
-       return myType;
+        return myType;
 }
 
 //=======================================================================
@@ -395,7 +437,7 @@ SMESHDS_CommandType SMESHDS_Command::GetType()
 //=======================================================================
 int SMESHDS_Command::GetNumber()
 {
-       return myNumber;
+        return myNumber;
 }
 
 //=======================================================================
@@ -404,7 +446,7 @@ int SMESHDS_Command::GetNumber()
 //=======================================================================
 const list < int >&SMESHDS_Command::GetIndexes()
 {
-       return myIntegers;
+        return myIntegers;
 }
 
 //=======================================================================
@@ -413,7 +455,7 @@ const list < int >&SMESHDS_Command::GetIndexes()
 //=======================================================================
 const list < double >&SMESHDS_Command::GetCoords()
 {
-       return myReals;
+        return myReals;
 }
 
 
@@ -484,6 +526,31 @@ void SMESHDS_Command::AddFace(int NewFaceID,
   myNumber++;
 }
 
+//=======================================================================
+//function : AddFace
+//purpose  : 
+//=======================================================================
+void SMESHDS_Command::AddFace(int NewFaceID,
+                              int n1, int n2, int n3, int n4,
+                              int n12, int n23, int n34, int n41, int nCenter)
+{
+  if (myType != SMESHDS_AddBiQuadQuadrangle) {
+    MESSAGE("SMESHDS_Command::AddFace : Bad Type");
+    return;
+  }
+  myIntegers.push_back(NewFaceID);
+  myIntegers.push_back(n1);
+  myIntegers.push_back(n2);
+  myIntegers.push_back(n3);
+  myIntegers.push_back(n4);
+  myIntegers.push_back(n12);
+  myIntegers.push_back(n23);
+  myIntegers.push_back(n34);
+  myIntegers.push_back(n41);
+  myIntegers.push_back(nCenter);
+  myNumber++;
+}
+
 //=======================================================================
 //function : AddVolume
 //purpose  : 
@@ -611,3 +678,68 @@ void SMESHDS_Command::AddVolume(int NewVolID, int n1, int n2, int n3,
   myNumber++;
 }
 
+//=======================================================================
+//function : AddVolume
+//purpose  : 
+//=======================================================================
+void SMESHDS_Command::AddVolume(int NewVolID, int n1, int n2, int n3,
+                                int n4, int n5, int n6, int n7, int n8,
+                                int n12, int n23, int n34, int n41,
+                                int n56, int n67, int n78, int n85,
+                                int n15, int n26, int n37, int n48,
+                                int n1234,int n1256,int n2367,int n3478,
+                                int n1458,int n5678,int nCenter)
+{
+  if (!myType == SMESHDS_AddQuadHexahedron) {
+    MESSAGE("SMESHDS_Command::AddVolume : Bad Type");
+    return;
+  }
+  myIntegers.push_back(NewVolID);
+  myIntegers.push_back(n1);
+  myIntegers.push_back(n2);
+  myIntegers.push_back(n3);
+  myIntegers.push_back(n4);
+  myIntegers.push_back(n5);
+  myIntegers.push_back(n6);
+  myIntegers.push_back(n7);
+  myIntegers.push_back(n8);
+  myIntegers.push_back(n12);
+  myIntegers.push_back(n23);
+  myIntegers.push_back(n34);
+  myIntegers.push_back(n41);
+  myIntegers.push_back(n56);
+  myIntegers.push_back(n67);
+  myIntegers.push_back(n78);
+  myIntegers.push_back(n85);
+  myIntegers.push_back(n15);
+  myIntegers.push_back(n26);
+  myIntegers.push_back(n37);
+  myIntegers.push_back(n48);
+  myIntegers.push_back(n1234);
+  myIntegers.push_back(n1256);
+  myIntegers.push_back(n2367);
+  myIntegers.push_back(n3478);
+  myIntegers.push_back(n1458);
+  myIntegers.push_back(n5678);
+  myIntegers.push_back(nCenter);
+  myNumber++;
+}
+
+//================================================================================
+/*!
+ * \brief Record adding a Ball
+ */
+//================================================================================
+
+void SMESHDS_Command::AddBall(int NewBallID, int node, double diameter)
+{
+  if (!myType == SMESHDS_AddBall)
+  {
+    MESSAGE("SMESHDS_Command::SMESHDS_AddBall : Bad Type");
+    return;
+  }
+  myIntegers.push_back(NewBallID);
+  myIntegers.push_back(node);
+  myReals.push_back(diameter);
+  myNumber++;
+}
index 09d720b9acbac45a8d47388fd54afb73f598949c..72acadc58089c89970faa30122af244e66c83b37 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESHDS : management of mesh data and SMESH document
 //  File   : SMESHDS_Command.hxx
 //  Module : SMESH
@@ -36,31 +37,38 @@ class SMESHDS_EXPORT SMESHDS_Command
 {
 
   public:
-       SMESHDS_Command(const SMESHDS_CommandType aType);
-       void AddNode(int NewNodeID, double x, double y, double z);
-       void AddEdge(int NewEdgeID, int idnode1, int idnode2);
-       void AddFace(int NewFaceID, int idnode1, int idnode2, int idnode3);
-       void AddFace(int NewFaceID, int idnode1, int idnode2, int idnode3,
-               int idnode4);
-       void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3,
-               int idnode4);
-       void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3,
-               int idnode4, int idnode5);
-       void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3,
-               int idnode4, int idnode5, int idnode6);
-       void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3,
-               int idnode4, int idnode5, int idnode6, int idnode7, int idnode8);
-        void AddPolygonalFace (const int        ElementID,
-                               std::vector<int> nodes_ids);
-        void AddPolyhedralVolume (const int        ElementID,
-                                  std::vector<int> nodes_ids,
-                                  std::vector<int> quantities);
+        SMESHDS_Command(const SMESHDS_CommandType aType);
+        void AddNode(int NewNodeID, double x, double y, double z);
+        void Add0DElement(int New0DElementID, int idnode);
+        void AddEdge(int NewEdgeID, int idnode1, int idnode2);
+        void AddFace(int NewFaceID, int idnode1, int idnode2, int idnode3);
+        void AddFace(int NewFaceID, int idnode1, int idnode2, int idnode3,
+                     int idnode4);
+        void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3,
+                       int idnode4);
+        void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3,
+                       int idnode4, int idnode5);
+        void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3,
+                       int idnode4, int idnode5, int idnode6);
+        void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3,
+                       int idnode4, int idnode5, int idnode6, int idnode7, int idnode8);
+        void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3,
+                       int idnode4, int idnode5, int idnode6, int idnode7, int idnode8,
+                       int idnode9, int idnode10, int idnode11, int idnode12);
+        void AddPolygonalFace (const int               ElementID,
+                               const std::vector<int>& nodes_ids);
+        void AddPolyhedralVolume (const int               ElementID,
+                                  const std::vector<int>& nodes_ids,
+                                  const std::vector<int>& quantities);
+        void AddBall(int NewBallID, int node, double diameter);
         // special methods for quadratic elements
-       void AddEdge(int NewEdgeID, int n1, int n2, int n12);
+        void AddEdge(int NewEdgeID, int n1, int n2, int n12);
         void AddFace(int NewFaceID, int n1, int n2, int n3,
                      int n12, int n23, int n31);
         void AddFace(int NewFaceID, int n1, int n2, int n3, int n4,
                      int n12, int n23, int n34, int n41);
+        void AddFace(int NewFaceID, int n1, int n2, int n3, int n4,
+                     int n12, int n23, int n34, int n41, int nCenter);
         void AddVolume(int NewVolID, int n1, int n2, int n3, int n4,
                        int n12, int n23, int n31, int n14, int n24, int n34);
         void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, int n5,
@@ -72,28 +80,35 @@ class SMESHDS_EXPORT SMESHDS_Command
                        int n45, int n56, int n64,
                        int n14, int n25, int n36);
         void AddVolume(int NewVolID, int n1, int n2, int n3, int n4,
-                       int n5, int n6, int n7, int n8,
+                       int n5,  int n6,  int n7,  int n8,
                        int n12, int n23, int n34, int n41,
                        int n56, int n67, int n78, int n85,
                        int n15, int n26, int n37, int n48);
+        void AddVolume(int NewVolID, int n1, int n2, int n3, int n4,
+                       int n5,  int n6,  int n7,  int n8,
+                       int n12, int n23, int n34, int n41,
+                       int n56, int n67, int n78, int n85,
+                       int n15, int n26, int n37, int n48,
+                       int n1234,int n1256,int n2367,int n3478,
+                       int n1458,int n5678,int nCenter);
         
-       void MoveNode(int NewNodeID, double x, double y, double z);
-       void RemoveNode(int NodeID);
-       void RemoveElement(int ElementID);
-       void ChangeElementNodes(int ElementID, int nodes[], int nbnodes);
-       void ChangePolyhedronNodes(const int ElementID,
-                                   std::vector<int> nodes_ids,
-                                   std::vector<int> quantities);
-       void Renumber (const bool isNodes, const int startID, const int deltaID);
-       SMESHDS_CommandType GetType();
-       int GetNumber();
-       const std::list<int> & GetIndexes();
-       const std::list<double> & GetCoords();
-        ~SMESHDS_Command();
+        void MoveNode(int NewNodeID, double x, double y, double z);
+        void RemoveNode(int NodeID);
+        void RemoveElement(int ElementID);
+        void ChangeElementNodes(int ElementID, int nodes[], int nbnodes);
+        void ChangePolyhedronNodes(const int               ElementID,
+                                   const std::vector<int>& nodes_ids,
+                                   const std::vector<int>& quantities);
+        void Renumber (const bool isNodes, const int startID, const int deltaID);
+        SMESHDS_CommandType GetType();
+        int GetNumber();
+        const std::list<int> & GetIndexes();
+        const std::list<double> & GetCoords();
+         ~SMESHDS_Command();
   private:
-       SMESHDS_CommandType myType;
-       int myNumber;
-       std::list<double> myReals;
-       std::list<int> myIntegers;
+        SMESHDS_CommandType myType;
+        int myNumber;
+        std::list<double> myReals;
+        std::list<int> myIntegers;
 };
 #endif
index bafaba8632f0b5c36872c39da8afc2e072b37809..7870d1e67167133f737c596ff232a390805bc773 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESHDS : management of mesh data and SMESH document
 //  File   : SMESHDS_CommandType.hxx
 //  Module : SMESH
@@ -26,8 +27,6 @@
 #ifndef _SMESHDS_CommandType_HeaderFile
 #define _SMESHDS_CommandType_HeaderFile
 
-//#include <Standard_PrimitiveTypes.hxx>
-
 enum SMESHDS_CommandType { 
   SMESHDS_AddNode,
   SMESHDS_AddEdge,
@@ -53,7 +52,13 @@ enum SMESHDS_CommandType {
   SMESHDS_AddQuadTetrahedron,
   SMESHDS_AddQuadPyramid,
   SMESHDS_AddQuadPentahedron,
-  SMESHDS_AddQuadHexahedron
+  SMESHDS_AddQuadHexahedron,
+  //
+  SMESHDS_Add0DElement,
+  SMESHDS_AddBiQuadQuadrangle,
+  SMESHDS_AddTriQuadHexa,
+  SMESHDS_AddHexagonalPrism,
+  SMESHDS_AddBall
 };
 
 
index ae748956484f5872f7b0bb29095be014fcf89f15..e9482e7bba2acdfabdabf499324d6a12c15389f2 100755 (executable)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File:      SMESHDS_DataMapOfShape.hxx
 // Created:   20.09.05 09:51:12
 // Author:    Alexander BORODIN
index 9e568e2974ab123c639507851a097b14745f6c18..315275e33ac9f742e6ddc35552229d47e1285a31 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESHDS : management of mesh data and SMESH document
 //  File   : SMESHDS_Document.cxx
 //  Author : Yves FRICAUD, OCC
@@ -69,13 +70,13 @@ int SMESHDS_Document::NewMesh(bool theIsEmbeddedMode)
 //=======================================================================
 SMESHDS_Mesh *SMESHDS_Document::GetMesh(int MeshID)
 {
-       map<int,SMESHDS_Mesh*>::iterator it=myMeshes.find(MeshID);
-       if (it==myMeshes.end())
-       {
-               MESSAGE("SMESHDS_Document::GetMesh : ID not found");
-               return NULL;
-       }
-       else return (*it).second;
+        map<int,SMESHDS_Mesh*>::iterator it=myMeshes.find(MeshID);
+        if (it==myMeshes.end())
+        {
+                MESSAGE("SMESHDS_Document::GetMesh : ID not found");
+                return NULL;
+        }
+        else return (*it).second;
 }
 
 //=======================================================================
@@ -84,10 +85,9 @@ SMESHDS_Mesh *SMESHDS_Document::GetMesh(int MeshID)
 //=======================================================================
 void SMESHDS_Document::RemoveMesh(int MeshID)
 {
-       map<int,SMESHDS_Mesh*>::iterator it=myMeshes.find(MeshID);
-       if (it==myMeshes.end())
-               MESSAGE("SMESHDS_Document::RemoveMesh : ID not found"); 
-       myMeshes.erase(it);
+  map<int,SMESHDS_Mesh*>::iterator it=myMeshes.find(MeshID);
+  if (it!=myMeshes.end())
+    myMeshes.erase(it);
 }
 
 //=======================================================================
@@ -96,7 +96,7 @@ void SMESHDS_Document::RemoveMesh(int MeshID)
 //=======================================================================
 void SMESHDS_Document::AddHypothesis(SMESHDS_Hypothesis * H)
 {
-       myHypothesis[H->GetID()]=H;
+  myHypothesis[H->GetID()]=H;
 }
 
 //=======================================================================
@@ -105,13 +105,13 @@ void SMESHDS_Document::AddHypothesis(SMESHDS_Hypothesis * H)
 //=======================================================================
 SMESHDS_Hypothesis * SMESHDS_Document::GetHypothesis(int HypID)
 {
-       map<int,SMESHDS_Hypothesis*>::iterator it=myHypothesis.find(HypID);
-       if (it==myHypothesis.end())
-       {
-               MESSAGE("SMESHDS_Document::GetHypothesis : ID not found");
-               return NULL;
-       }
-       else return (*it).second;
+        map<int,SMESHDS_Hypothesis*>::iterator it=myHypothesis.find(HypID);
+        if (it==myHypothesis.end())
+        {
+                MESSAGE("SMESHDS_Document::GetHypothesis : ID not found");
+                return NULL;
+        }
+        else return (*it).second;
 }
 
 //=======================================================================
@@ -120,10 +120,10 @@ SMESHDS_Hypothesis * SMESHDS_Document::GetHypothesis(int HypID)
 //=======================================================================
 void SMESHDS_Document::RemoveHypothesis(int HypID)
 {
-       map<int,SMESHDS_Hypothesis*>::iterator it=myHypothesis.find(HypID);
-       if (it==myHypothesis.end())
-               MESSAGE("SMESHDS_Document::RemoveHypothesis : ID not found");   
-       myHypothesis.erase(it);
+        map<int,SMESHDS_Hypothesis*>::iterator it=myHypothesis.find(HypID);
+        if (it==myHypothesis.end())
+                MESSAGE("SMESHDS_Document::RemoveHypothesis : ID not found");   
+        myHypothesis.erase(it);
 }
 
 //=======================================================================
@@ -132,7 +132,7 @@ void SMESHDS_Document::RemoveHypothesis(int HypID)
 //=======================================================================
 int SMESHDS_Document::NbMeshes()
 {
-       return myMeshes.size();
+        return myMeshes.size();
 }
 
 //=======================================================================
@@ -141,7 +141,7 @@ int SMESHDS_Document::NbMeshes()
 //=======================================================================
 int SMESHDS_Document::NbHypothesis()
 {
-       return myHypothesis.size();
+        return myHypothesis.size();
 }
 
 //=======================================================================
@@ -150,7 +150,7 @@ int SMESHDS_Document::NbHypothesis()
 //=======================================================================
 void SMESHDS_Document::InitMeshesIterator()
 {
-       myMeshesIt=myMeshes.begin();
+        myMeshesIt=myMeshes.begin();
 }
 
 //=======================================================================
@@ -159,9 +159,9 @@ void SMESHDS_Document::InitMeshesIterator()
 //=======================================================================
 SMESHDS_Mesh * SMESHDS_Document::NextMesh()
 {
-       SMESHDS_Mesh * toReturn=(*myMeshesIt).second;
-       myMeshesIt++;
-       return toReturn;
+        SMESHDS_Mesh * toReturn=(*myMeshesIt).second;
+        myMeshesIt++;
+        return toReturn;
 }
 
 //=======================================================================
@@ -170,7 +170,7 @@ SMESHDS_Mesh * SMESHDS_Document::NextMesh()
 //=======================================================================
 bool SMESHDS_Document::MoreMesh()
 {
-       return myMeshesIt!=myMeshes.end();
+        return myMeshesIt!=myMeshes.end();
 }
 
 //=======================================================================
@@ -179,7 +179,7 @@ bool SMESHDS_Document::MoreMesh()
 //=======================================================================
 void SMESHDS_Document::InitHypothesisIterator()
 {
-       myHypothesisIt=myHypothesis.begin();
+        myHypothesisIt=myHypothesis.begin();
 }
 
 //=======================================================================
@@ -188,9 +188,9 @@ void SMESHDS_Document::InitHypothesisIterator()
 //=======================================================================
 SMESHDS_Hypothesis * SMESHDS_Document::NextHypothesis()
 {
-       SMESHDS_Hypothesis * toReturn=(*myHypothesisIt).second;
-       myHypothesisIt++;
-       return toReturn;
+        SMESHDS_Hypothesis * toReturn=(*myHypothesisIt).second;
+        myHypothesisIt++;
+        return toReturn;
 }
 
 //=======================================================================
@@ -199,5 +199,5 @@ SMESHDS_Hypothesis * SMESHDS_Document::NextHypothesis()
 //=======================================================================
 bool SMESHDS_Document::MoreHypothesis()
 {
-       return myHypothesisIt!=myHypothesis.end();
+        return myHypothesisIt!=myHypothesis.end();
 }
index 6abea04a4083f713921d8cd1fc61d254409139ef..1825812560504b8c7b8cec5db6c834f302d6e304 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESHDS : management of mesh data and SMESH document
 //  File   : SMESHDS_Document.hxx
 //  Module : SMESH
 class SMESHDS_EXPORT SMESHDS_Document
 {
   public:
-       SMESHDS_Document(int UserID);
-       int NewMesh(bool theIsEmbeddedMode);
-       void RemoveMesh(int MeshID);
-       SMESHDS_Mesh * GetMesh(int MeshID);
-       void AddHypothesis(SMESHDS_Hypothesis * H);
-       void RemoveHypothesis(int HypID);
-       SMESHDS_Hypothesis * GetHypothesis(int HypID);
-       int NbMeshes();
-       int NbHypothesis();
-       void InitMeshesIterator();
-       SMESHDS_Mesh * NextMesh();
-       bool MoreMesh();        
-       void InitHypothesisIterator();
-       SMESHDS_Hypothesis * NextHypothesis();
-       bool MoreHypothesis();  
-        ~SMESHDS_Document();
+        SMESHDS_Document(int UserID);
+        int NewMesh(bool theIsEmbeddedMode);
+        void RemoveMesh(int MeshID);
+        SMESHDS_Mesh * GetMesh(int MeshID);
+        void AddHypothesis(SMESHDS_Hypothesis * H);
+        void RemoveHypothesis(int HypID);
+        SMESHDS_Hypothesis * GetHypothesis(int HypID);
+        int NbMeshes();
+        int NbHypothesis();
+        void InitMeshesIterator();
+        SMESHDS_Mesh * NextMesh();
+        bool MoreMesh();        
+        void InitHypothesisIterator();
+        SMESHDS_Hypothesis * NextHypothesis();
+        bool MoreHypothesis();  
+         ~SMESHDS_Document();
 
   private:
-       int myUserID;
-       std::map<int,SMESHDS_Mesh*> myMeshes;
-       std::map<int,SMESHDS_Hypothesis*> myHypothesis;
-       std::map<int,SMESHDS_Mesh*>::iterator myMeshesIt;
-       std::map<int,SMESHDS_Hypothesis*>::iterator myHypothesisIt;
+        int myUserID;
+        std::map<int,SMESHDS_Mesh*> myMeshes;
+        std::map<int,SMESHDS_Hypothesis*> myHypothesis;
+        std::map<int,SMESHDS_Mesh*>::iterator myMeshesIt;
+        std::map<int,SMESHDS_Hypothesis*>::iterator myHypothesisIt;
 };
 
 #endif
index fd0ba61d512a95b346d446f795033ff1e289f215..c3e1820e5c5cc3942d3a19747672091b94c787aa 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESHDS : idl implementation based on 'SMESH' unit's classes
 //  File   : SMESHDS_Group.cxx
 //  Module : SMESH
@@ -48,7 +49,7 @@ SMESHDS_Group::SMESHDS_Group (const int                 theID,
 //purpose  : 
 //=======================================================================
 
-int SMESHDS_Group::Extent()
+int SMESHDS_Group::Extent() const
 {
   return myGroup.Extent();
 }
@@ -155,11 +156,22 @@ class MyGroupIterator: public SMDS_ElemIterator
 //purpose  : 
 //=======================================================================
 
-SMDS_ElemIteratorPtr SMESHDS_Group::GetElements()
+SMDS_ElemIteratorPtr SMESHDS_Group::GetElements() const
 {
   return SMDS_ElemIteratorPtr( new MyGroupIterator ( myGroup ));
 }
 
+//================================================================================
+/*!
+ * \brief Return a value allowing to find out if a group has changed or not
+ */
+//================================================================================
+
+int SMESHDS_Group::GetTic() const
+{
+  return myGroup.Tic();
+}
+
 //=======================================================================
 //function : SetType
 //purpose  : 
index 85d7d14c2407b6e95a777a97fda0068f55d38f49..6c798d96107ee59b42454e7769350379034a103f 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESHDS : management of mesh data and SMESH document
 //  File   : SMESHDS_Group.hxx
 //  Module : SMESH
@@ -45,7 +46,7 @@ class SMESHDS_EXPORT SMESHDS_Group : public SMESHDS_GroupBase
 
   virtual void SetType(SMDSAbs_ElementType theType);
 
-  virtual int Extent();
+  virtual int Extent() const;
 
   virtual bool IsEmpty();
 
@@ -53,7 +54,9 @@ class SMESHDS_EXPORT SMESHDS_Group : public SMESHDS_GroupBase
 
   virtual bool Contains (const SMDS_MeshElement* elem);
 
-  virtual SMDS_ElemIteratorPtr GetElements();
+  virtual SMDS_ElemIteratorPtr GetElements() const;
+
+  virtual int GetTic() const;
 
   bool Add (const int theID);
 
index b14afd408ff1ac732e937a202c6c2df5e49d1daf..383d796a29d9ac6015a3d73010cf6c9785d8796e 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESHDS : idl implementation based on 'SMESH' unit's classes
 //  File   : SMESHDS_Group.cxx
 //  Module : SMESH
@@ -104,7 +105,7 @@ void SMESHDS_GroupBase::resetIterator()
 //purpose  : 
 //=======================================================================
 
-int SMESHDS_GroupBase::Extent()
+int SMESHDS_GroupBase::Extent() const
 {
   SMDS_ElemIteratorPtr it = GetElements();
   int nb = 0;
index ced9543fa5f37c5b6a9c7f5486712f2cfe36109a..cc9411f993c2bba9d1e583426b5519c69358163e 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESHDS : management of mesh data and SMESH document
 //  File   : SMESHDS_Group.hxx
 //  Module : SMESH
@@ -57,7 +58,7 @@ class SMESHDS_EXPORT SMESHDS_GroupBase
 
   const char* GetStoreName () const { return myStoreName.c_str(); }
 
-  virtual int Extent();
+  virtual int Extent() const;
 
   virtual bool IsEmpty();
 
@@ -65,11 +66,13 @@ class SMESHDS_EXPORT SMESHDS_GroupBase
 
   virtual bool Contains (const SMDS_MeshElement* elem);
 
-  virtual SMDS_ElemIteratorPtr GetElements() = 0;
+  virtual SMDS_ElemIteratorPtr GetElements() const = 0;
 
-  int GetID (const int theIndex);
+  virtual int GetID (const int theIndex);
   // use it for iterations 1..Extent()
 
+  virtual int GetTic() const = 0;
+
   virtual ~SMESHDS_GroupBase() {}
 
   void SetColor (const Quantity_Color& theColor)
@@ -96,11 +99,12 @@ class SMESHDS_EXPORT SMESHDS_GroupBase
   const SMESHDS_Mesh*  myMesh;
   SMDSAbs_ElementType  myType;
   std::string          myStoreName;
+  Quantity_Color       myColor;
+
   // for GetID()
   int                  myCurIndex;
   int                  myCurID;
   SMDS_ElemIteratorPtr myIterator;
-  Quantity_Color       myColor;
 };
 
 #endif
diff --git a/src/SMESHDS/SMESHDS_GroupOnFilter.cxx b/src/SMESHDS/SMESHDS_GroupOnFilter.cxx
new file mode 100644 (file)
index 0000000..32bd8c7
--- /dev/null
@@ -0,0 +1,190 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+//  File   : SMESHDS_GroupOnFilter.cxx
+//  Module : SMESH
+//
+#include "SMESHDS_GroupOnFilter.hxx"
+
+#include "SMESHDS_Mesh.hxx"
+#include "SMDS_SetIterator.hxx"
+
+using namespace std;
+
+//=============================================================================
+/*!
+ * Creates a group based on thePredicate
+ */
+//=============================================================================
+
+SMESHDS_GroupOnFilter::SMESHDS_GroupOnFilter (const int                 theID,
+                                              const SMESHDS_Mesh*       theMesh,
+                                              const SMDSAbs_ElementType theType,
+                                              const SMESH_PredicatePtr& thePredicate)
+  : SMESHDS_GroupBase(theID,theMesh,theType), myMeshModifTime(0), myPredicateTic(0)
+{
+  setChanged();
+  SetPredicate( thePredicate );
+}
+
+//================================================================================
+/*!
+ * \brief Sets a new predicate
+ */
+//================================================================================
+
+void SMESHDS_GroupOnFilter::SetPredicate( const SMESH_PredicatePtr& thePredicate)
+{
+  myPredicate = thePredicate;
+  ++myPredicateTic;
+  setChanged();
+  if ( myPredicate )
+    myPredicate->SetMesh( GetMesh() );
+}
+
+//================================================================================
+/*!
+ * \brief Returns nb of elements
+ */
+//================================================================================
+
+int SMESHDS_GroupOnFilter::Extent() const
+{
+  update();
+  return myElements.size();
+}
+
+//================================================================================
+/*!
+ * \brief Checks if the element belongs to the group
+ */
+//================================================================================
+
+bool SMESHDS_GroupOnFilter::Contains (const int theID)
+{
+  return myPredicate ? myPredicate->IsSatisfy( theID ) : false;
+}
+
+//================================================================================
+/*!
+ * \brief Checks if the element belongs to the group
+ */
+//================================================================================
+
+bool SMESHDS_GroupOnFilter::Contains (const SMDS_MeshElement* elem)
+{
+  return myPredicate ? myPredicate->IsSatisfy( elem->GetID() ) : false;
+}
+
+//================================================================================
+/*!
+ * \brief Return iterator on all elements
+ */
+//================================================================================
+
+SMDS_ElemIteratorPtr SMESHDS_GroupOnFilter::GetElements() const
+{
+  update();
+  return SMDS_ElemIteratorPtr
+    ( new SMDS_ElementVectorIterator( myElements.begin(), myElements.end() ));
+}
+
+//================================================================================
+/*!
+ * \brief return ID of theIndex-th element
+ *  \param theIndex - index countered from 1
+ *  \retval int - element ID
+ */
+//================================================================================
+
+int SMESHDS_GroupOnFilter::GetID (const int theIndex)
+{
+  update();
+  if ( theIndex < 1 || theIndex > myElements.size() )
+    return -1;
+  return myElements[ theIndex-1 ]->GetID();
+}
+
+//================================================================================
+/*!
+ * \brief Return a value allowing to find out if a group has changed or not
+ */
+//================================================================================
+
+int SMESHDS_GroupOnFilter::GetTic() const
+{
+  return GetMesh()->GetMTime() * myPredicateTic;
+}
+
+//================================================================================
+/*!
+ * \brief Return false if update() is needed
+ */
+//================================================================================
+
+bool SMESHDS_GroupOnFilter::IsUpToDate() const
+{
+  return !( myMeshModifTime < GetMesh()->GetMTime() );
+}
+
+//================================================================================
+/*!
+ * \brief Updates myElements if necessary
+ */
+//================================================================================
+
+void SMESHDS_GroupOnFilter::update() const
+{
+  if ( !IsUpToDate() )
+  {
+    SMESHDS_GroupOnFilter* me = const_cast<SMESHDS_GroupOnFilter*>( this );
+    me->myElements.clear();
+    if ( myPredicate )
+    {
+      myPredicate->SetMesh( GetMesh() ); // hope myPredicate updates self here if necessary
+      me->myElements.reserve( GetMesh()->GetMeshInfo().NbElements(GetType()));
+      SMDS_ElemIteratorPtr elIt = GetMesh()->elementsIterator(GetType());
+      while ( elIt->more() )
+      {
+        const SMDS_MeshElement* e = elIt->next();
+        if ( myPredicate->IsSatisfy( e->GetID() ))
+          me->myElements.push_back( e );
+      }
+      vector< const SMDS_MeshElement*> elems( me->myElements.begin(), me->myElements.end() );
+      me->myElements.swap( elems );
+    }
+    me->setChanged( false );
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Sets myMeshModifTime according to modification state
+ */
+//================================================================================
+
+void SMESHDS_GroupOnFilter::setChanged(bool changed)
+{
+  myMeshModifTime = GetMesh()->GetMTime();
+  if ( changed && myMeshModifTime != 0 )
+    --myMeshModifTime;
+}
diff --git a/src/SMESHDS/SMESHDS_GroupOnFilter.hxx b/src/SMESHDS/SMESHDS_GroupOnFilter.hxx
new file mode 100644 (file)
index 0000000..b1e33e5
--- /dev/null
@@ -0,0 +1,74 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+//  File   : SMESHDS_GroupOnFilter.hxx
+//  Module : SMESH
+//
+#ifndef _SMESHDS_GroupOnFilter_HeaderFile
+#define _SMESHDS_GroupOnFilter_HeaderFile
+
+#include "SMESH_SMESHDS.hxx"
+
+#include "SMESHDS_GroupBase.hxx"
+#include "SMESH_Controls.hxx"
+  
+/*!
+ * \brief Groups whose contents is dynamically updated using the filter
+ */
+class SMESHDS_EXPORT SMESHDS_GroupOnFilter: public SMESHDS_GroupBase
+{
+ public:
+
+  SMESHDS_GroupOnFilter (const int                 theID,
+                         const SMESHDS_Mesh*       theMesh,
+                         const SMDSAbs_ElementType theType,
+                         const SMESH_PredicatePtr& thePredicate);
+
+  void SetPredicate( const SMESH_PredicatePtr& thePredicate);
+
+  SMESH_PredicatePtr GetPredicate() const { return myPredicate; }
+
+  virtual int Extent() const;
+
+  virtual bool Contains (const int theID);
+
+  virtual bool Contains (const SMDS_MeshElement* elem);
+
+  virtual SMDS_ElemIteratorPtr GetElements() const;
+
+  virtual int GetID (const int theIndex);
+
+  virtual int GetTic() const;
+
+  bool IsUpToDate() const;
+
+ private:
+
+  void update() const;
+  void setChanged(bool changed=true);
+
+  SMESH_PredicatePtr                    myPredicate;
+  std::vector< const SMDS_MeshElement*> myElements;
+  unsigned long                         myMeshModifTime; // when myElements was filled
+  int                                   myPredicateTic;
+};
+
+#endif
index 73e1654db6e3b7441998f0d86742b504b62ba7ef..51d7620280c2163ea8aae6de809f8fc9dd8bab51 100644 (file)
@@ -1,28 +1,28 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESHDS : idl implementation based on 'SMESH' unit's classes
 //  File   : SMESHDS_GroupOnGeom.cxx
 //  Module : SMESH
-//  $Header$
 //
 #include "SMESHDS_GroupOnGeom.hxx"
 #include "SMESHDS_Mesh.hxx"
@@ -40,10 +40,16 @@ SMESHDS_GroupOnGeom::SMESHDS_GroupOnGeom (const int                 theID,
                                           const SMESHDS_Mesh*       theMesh,
                                           const SMDSAbs_ElementType theType,
                                           const TopoDS_Shape&       theShape)
-     : SMESHDS_GroupBase(theID,theMesh,theType), myShape(theShape)
+     : SMESHDS_GroupBase(theID,theMesh,theType)
+{
+  SetShape( theShape );
+}
+
+void SMESHDS_GroupOnGeom::SetShape( const TopoDS_Shape& theShape)
 {
-  SMESHDS_Mesh* aMesh = const_cast<SMESHDS_Mesh*>(theMesh);
+  SMESHDS_Mesh* aMesh = const_cast<SMESHDS_Mesh*>( GetMesh() );
   mySubMesh = aMesh->MeshElements( aMesh->AddCompoundSubmesh( theShape ));
+  myShape   = theShape;
 }
 
 // =====================
@@ -60,13 +66,14 @@ class MyIterator: public SMDS_ElemIterator
   MyIterator(SMDSAbs_ElementType type, const SMESHDS_SubMesh* subMesh)
     : myType(type), myElem(0)
   {
-    if ( subMesh ) 
+    if ( subMesh ) {
       if ( myType == SMDSAbs_Node )
         myNodeIt = subMesh->GetNodes();
       else {
         myElemIt = subMesh->GetElements();
         next();
       }
+    }
   }
   bool more()
   {
@@ -96,7 +103,7 @@ class MyIterator: public SMDS_ElemIterator
 //purpose  : 
 //=======================================================================
 
-SMDS_ElemIteratorPtr SMESHDS_GroupOnGeom::GetElements()
+SMDS_ElemIteratorPtr SMESHDS_GroupOnGeom::GetElements() const
 {
   return SMDS_ElemIteratorPtr( new MyIterator ( GetType(), mySubMesh ));
 }
@@ -121,3 +128,14 @@ bool SMESHDS_GroupOnGeom::Contains (const SMDS_MeshElement* elem)
   return mySubMesh->Contains( elem );
 }
 
+//================================================================================
+/*!
+ * \brief Return a value allowing to find out if a group has changed or not
+ */
+//================================================================================
+
+int SMESHDS_GroupOnGeom::GetTic() const
+{
+  return GetMesh()->GetMTime();
+}
+
index a1fa3cb269aa69083ed43bd2b3ac5887a5c32904..1895912b4f0c2cdb42f851d8418805099b4e1310 100644 (file)
@@ -1,28 +1,28 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESHDS : management of mesh data and SMESH document
 //  File   : SMESHDS_GroupOnGeom.hxx
 //  Module : SMESH
-//  $Header$
 //
 #ifndef _SMESHDS_GroupOnGeom_HeaderFile
 #define _SMESHDS_GroupOnGeom_HeaderFile
@@ -43,13 +43,17 @@ class SMESHDS_EXPORT SMESHDS_GroupOnGeom: public SMESHDS_GroupBase
                        const SMDSAbs_ElementType theType,
                        const TopoDS_Shape&       theShape);
 
+  void SetShape( const TopoDS_Shape& theShape);
+
   TopoDS_Shape GetShape() const { return myShape; }
 
   virtual bool Contains (const int theID);
 
   virtual bool Contains (const SMDS_MeshElement* elem);
 
-  virtual SMDS_ElemIteratorPtr GetElements();
+  virtual SMDS_ElemIteratorPtr GetElements() const;
+
+  virtual int GetTic() const;
 
  private:
 
index 84b3a6c32b5ea3279e074069396c582db317b011..ea7c5c6e57429924225e65746c3eedd2ef37af87 100644 (file)
@@ -1,32 +1,34 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESHDS : management of mesh data and SMESH document
 //  File   : SMESHDS_Hypothesis.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//  $Header$
 //
 #include "SMESHDS_Hypothesis.hxx"
 
+#include <sstream>
+
 using namespace std;
 
 //=============================================================================
@@ -37,11 +39,8 @@ using namespace std;
 
 SMESHDS_Hypothesis::SMESHDS_Hypothesis(int hypId)
 {
-//   MESSAGE("SMESHDS_Hypothesis::SMESHDS_Hypothesis");
   _hypId = hypId;
   _name = "generic";
-//   SCRUTE(_name);
-//   SCRUTE(_hypId);
 }
 
 //=============================================================================
@@ -52,7 +51,6 @@ SMESHDS_Hypothesis::SMESHDS_Hypothesis(int hypId)
 
 SMESHDS_Hypothesis::~SMESHDS_Hypothesis()
 {
-//   MESSAGE("SMESHDS_Hypothesis::~SMESHDS_Hypothesis");
 }
 
 //=============================================================================
@@ -63,9 +61,6 @@ SMESHDS_Hypothesis::~SMESHDS_Hypothesis()
 
 const char* SMESHDS_Hypothesis::GetName() const
 {
-//   MESSAGE("SMESHDS_Hypothesis::GetName");
-//   SCRUTE(_name);
-//   SCRUTE(&_name);
   return _name.c_str();
 }
 
@@ -77,8 +72,6 @@ const char* SMESHDS_Hypothesis::GetName() const
 
 int SMESHDS_Hypothesis::GetID() const
 {
-//   MESSAGE("SMESHDS_Hypothesis::GetId");
-//   SCRUTE(_hypId);
   return _hypId;
 }
 
@@ -90,8 +83,23 @@ int SMESHDS_Hypothesis::GetID() const
 
 int SMESHDS_Hypothesis::GetType() const
 {
-//   MESSAGE("SMESHDS_Hypothesis::GetType");
-//   SCRUTE(_type);
   return _type;
 }
 
+//=============================================================================
+/*!
+ * Equality
+ */
+//=============================================================================
+
+bool SMESHDS_Hypothesis::operator==(const SMESHDS_Hypothesis& other) const
+{
+  if ( this == &other )
+    return true;
+  if ( _name != other._name )
+    return false;
+  ostringstream mySave, otherSave;
+  ((SMESHDS_Hypothesis*)this  )->SaveTo(mySave);
+  ((SMESHDS_Hypothesis*)&other)->SaveTo(otherSave);
+  return mySave.str() == otherSave.str();
+}
index 4478b4a0b9317d6860616bff6f63c313e976baf2..d819684af6a8e8b2d36f32a5a1cfc1b50b6de343 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESHDS : management of mesh data and SMESH document
 //  File   : SMESHDS_Hypothesis.hxx
 //  Author : Paul RASCLE, EDF
@@ -46,6 +47,9 @@ public:
   virtual std::ostream & SaveTo(std::ostream & save)=0;
   virtual std::istream & LoadFrom(std::istream & load)=0;
 
+  virtual bool operator==(const SMESHDS_Hypothesis& other) const;
+  bool operator!=(const SMESHDS_Hypothesis& other) const { return !(*this==other); }
+
 enum hypothesis_type {PARAM_ALGO, ALGO_0D, ALGO_1D, ALGO_2D, ALGO_3D};
 
 protected:
index b2dab77199e533f82e0e18f4de3ddf43d172fb37..a42b9acc0f07774b9dacb630d577ffd27d18ad30 100644 (file)
@@ -1,29 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESHDS : management of mesh data and SMESH document
 //  File   : SMESH_Mesh.cxx
 //  Author : Yves FRICAUD, OCC
 //  Module : SMESH
-//  $Header: 
 //
 #include "SMESHDS_Mesh.hxx"
 
 #include "SMDS_EdgePosition.hxx"
 #include "SMDS_FacePosition.hxx"
 #include "SMDS_SpacePosition.hxx"
+#include "SMDS_Downward.hxx"
 #include "SMESHDS_GroupOnGeom.hxx"
+#include "SMESHDS_Script.hxx"
 
-#include <TopExp_Explorer.hxx>
+#include <Standard_ErrorHandler.hxx>
+#include <Standard_OutOfRange.hxx>
 #include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
 #include <TopoDS_Iterator.hxx>
+#include <TopoDS_Shell.hxx>
+#include <TopoDS_Solid.hxx>
+#include <TopoDS_Vertex.hxx>
 
 #include "utilities.h"
 
 using namespace std;
 
-/*Standard_Boolean IsEqual( const TopoDS_Shape& S1, const TopoDS_Shape& S2 ) 
-  {
-    return S1.IsSame( S2 );
-  }*/
-
 //=======================================================================
 //function : Create
 //purpose  : 
@@ -58,6 +62,7 @@ SMESHDS_Mesh::SMESHDS_Mesh(int theMeshID, bool theIsEmbeddedMode):
 {
   myScript = new SMESHDS_Script(theIsEmbeddedMode);
   myCurSubMesh = 0;
+  SetPersistentId(theMeshID);
 }
 
 //=======================================================================
@@ -66,6 +71,30 @@ bool SMESHDS_Mesh::IsEmbeddedMode()
   return myIsEmbeddedMode;
 }
 
+//================================================================================
+/*!
+ * \brief Store ID persistent during lifecycle
+ *
+ * Initially it was used to have a persistent reference to the mesh from the hypothesis
+ */
+//================================================================================
+
+void SMESHDS_Mesh::SetPersistentId(int id)
+{
+  if (NbNodes() == 0)
+    myPersistentID = id;
+}
+//================================================================================
+/*!
+ * \brief Return ID persistent during lifecycle
+ */
+//================================================================================
+
+int SMESHDS_Mesh::GetPersistentId() const
+{
+  return myPersistentID;
+}
+
 //=======================================================================
 //function : ShapeToMesh
 //purpose  : 
@@ -83,12 +112,15 @@ void SMESHDS_Mesh::ShapeToMesh(const TopoDS_Shape & S)
       if ( !i_sub->second->IsComplexSubmesh() ) {
         SMDS_NodeIteratorPtr nIt = i_sub->second->GetNodes();
         while ( nIt->more() )
-          nIt->next()->GetPosition()->SetShapeId( 0 );
+          i_sub->second->RemoveNode(nIt->next(), false);
       }
     }
     // - sub-meshes
-    myIndexToShape.Clear();
+    TShapeIndexToSubMesh::iterator i_sm = myShapeIndexToSubMesh.begin();
+    for ( ; i_sm != myShapeIndexToSubMesh.end(); ++i_sm )
+      delete i_sm->second;
     myShapeIndexToSubMesh.clear();
+    myIndexToShape.Clear();
     // - groups on geometry
     set<SMESHDS_GroupBase*>::iterator gr = myGroups.begin();
     while ( gr != myGroups.end() ) {
@@ -186,6 +218,7 @@ bool SMESHDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem,
                                       const SMDS_MeshNode    * nodes[],
                                       const int                nbnodes)
 {
+  //MESSAGE("SMESHDS_Mesh::ChangeElementNodes");
   if ( ! SMDS_Mesh::ChangeElementNodes( elem, nodes, nbnodes ))
     return false;
 
@@ -241,14 +274,71 @@ bool SMESHDS_Mesh::ChangePolyhedronNodes
 
 void SMESHDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
 {
-  SMDS_Mesh::Renumber( isNodes, startID, deltaID );
-  myScript->Renumber( isNodes, startID, deltaID );
+  // TODO not possible yet to have node numbers not starting to O and continuous.
+  if (!this->isCompacted())
+    this->compactMesh();
+//  SMDS_Mesh::Renumber( isNodes, startID, deltaID );
+//  myScript->Renumber( isNodes, startID, deltaID );
+}
+
+//=======================================================================
+//function : Add0DElement
+//purpose  :
+//=======================================================================
+SMDS_Mesh0DElement* SMESHDS_Mesh::Add0DElementWithID(int nodeID, int ID)
+{
+  SMDS_Mesh0DElement* anElem = SMDS_Mesh::Add0DElementWithID(nodeID, ID);
+  if (anElem) myScript->Add0DElement(ID, nodeID);
+  return anElem;
+}
+
+SMDS_Mesh0DElement* SMESHDS_Mesh::Add0DElementWithID
+                                  (const SMDS_MeshNode * node, int ID)
+{
+  return Add0DElementWithID(node->GetID(), ID);
+}
+
+SMDS_Mesh0DElement* SMESHDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
+{
+  SMDS_Mesh0DElement* anElem = SMDS_Mesh::Add0DElement(node);
+  if (anElem) myScript->Add0DElement(anElem->GetID(), node->GetID());
+  return anElem;
+}
+
+//=======================================================================
+//function :AddBallWithID
+//purpose  : 
+//=======================================================================
+
+SMDS_BallElement* SMESHDS_Mesh::AddBallWithID(int node, double diameter, int ID)
+{
+  SMDS_BallElement* anElem = SMDS_Mesh::AddBallWithID(node,diameter,ID);
+  if (anElem) myScript->AddBall(anElem->GetID(), node, diameter);
+  return anElem;
+}
+
+SMDS_BallElement* SMESHDS_Mesh::AddBallWithID(const SMDS_MeshNode * node,
+                                              double                diameter,
+                                              int                   ID)
+{
+  SMDS_BallElement* anElem = SMDS_Mesh::AddBallWithID(node,diameter,ID);
+  if (anElem) myScript->AddBall(anElem->GetID(), node->GetID(), diameter);
+  return anElem;
+}
+
+SMDS_BallElement* SMESHDS_Mesh::AddBall (const SMDS_MeshNode * node,
+                                         double                diameter)
+{
+  SMDS_BallElement* anElem = SMDS_Mesh::AddBall(node,diameter);
+  if (anElem) myScript->AddBall(anElem->GetID(), node->GetID(), diameter);
+  return anElem;
 }
 
 //=======================================================================
 //function :AddEdgeWithID
 //purpose  : 
 //=======================================================================
+
 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int ID)
 {
   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,ID);
@@ -257,21 +347,21 @@ SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int ID)
 }
 
 SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
-                                          const SMDS_MeshNode * n2, 
-                                          int ID)
+                                           const SMDS_MeshNode * n2, 
+                                           int ID)
 {
   return AddEdgeWithID(n1->GetID(),
-                      n2->GetID(),
-                      ID);
+                       n2->GetID(),
+                       ID);
 }
 
 SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode * n1,
-                                    const SMDS_MeshNode * n2)
+                                     const SMDS_MeshNode * n2)
 {
   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2);
   if(anElem) myScript->AddEdge(anElem->GetID(), 
-                              n1->GetID(), 
-                              n2->GetID());
+                               n1->GetID(), 
+                               n2->GetID());
   return anElem;
 }
 
@@ -287,25 +377,25 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int ID)
 }
 
 SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
-                                          const SMDS_MeshNode * n2,
-                                          const SMDS_MeshNode * n3, 
-                                          int ID)
+                                           const SMDS_MeshNode * n2,
+                                           const SMDS_MeshNode * n3, 
+                                           int ID)
 {
   return AddFaceWithID(n1->GetID(),
-                      n2->GetID(),
-                      n3->GetID(),
-                      ID);
+                       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 *anElem = SMDS_Mesh::AddFace(n1, n2, n3);
   if(anElem) myScript->AddFace(anElem->GetID(), 
-                              n1->GetID(), 
-                              n2->GetID(),
-                              n3->GetID());
+                               n1->GetID(), 
+                               n2->GetID(),
+                               n3->GetID());
   return anElem;
 }
 
@@ -321,29 +411,29 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, int I
 }
 
 SMDS_MeshFace* SMESHDS_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)
 {
   return AddFaceWithID(n1->GetID(),
-                      n2->GetID(),
-                      n3->GetID(),
-                      n4->GetID(),
-                      ID);
+                       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 *anElem = SMDS_Mesh::AddFace(n1, n2, n3, n4);
   if(anElem) myScript->AddFace(anElem->GetID(), 
-                              n1->GetID(), 
-                              n2->GetID(), 
-                              n3->GetID(),
-                              n4->GetID());
+                               n1->GetID(), 
+                               n2->GetID(), 
+                               n3->GetID(),
+                               n4->GetID());
   return anElem;
 }
 
@@ -359,29 +449,29 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, i
 }
 
 SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(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)
 {
   return AddVolumeWithID(n1->GetID(), 
-                        n2->GetID(), 
-                        n3->GetID(),
-                        n4->GetID(),
-                        ID);
+                         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)
+                                         const SMDS_MeshNode * n2,
+                                         const SMDS_MeshNode * n3,
+                                         const SMDS_MeshNode * n4)
 {
   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4);
   if(anElem) myScript->AddVolume(anElem->GetID(), 
-                                n1->GetID(), 
-                                n2->GetID(), 
-                                n3->GetID(),
-                                n4->GetID());
+                                 n1->GetID(), 
+                                 n2->GetID(), 
+                                 n3->GetID(),
+                                 n4->GetID());
   return anElem;
 }
 
@@ -397,33 +487,33 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, i
 }
 
 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)
+                                               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);
+                         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)
+                                         const SMDS_MeshNode * n2,
+                                         const SMDS_MeshNode * n3,
+                                         const SMDS_MeshNode * n4,
+                                         const SMDS_MeshNode * n5)
 {
   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());
+                                 n1->GetID(), 
+                                 n2->GetID(), 
+                                 n3->GetID(),
+                                 n4->GetID(), 
+                                 n5->GetID());
   return anElem;
 }
 
@@ -439,37 +529,37 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, i
 }
 
 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)
+                                               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);
+                         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)
+                                         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());
+                                 n1->GetID(), 
+                                 n2->GetID(), 
+                                 n3->GetID(),
+                                 n4->GetID(), 
+                                 n5->GetID(), 
+                                 n6->GetID());
   return anElem;
 }
 
@@ -485,54 +575,129 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, i
 }
 
 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)
+                                               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);
+                         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)
+                                         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());
+                                 n1->GetID(), 
+                                 n2->GetID(), 
+                                 n3->GetID(),
+                                 n4->GetID(), 
+                                 n5->GetID(), 
+                                 n6->GetID(), 
+                                 n7->GetID(), 
+                                 n8->GetID());
   return anElem;
 }
 
+
+//=======================================================================
+//function :AddVolume
+//purpose  : add hexagonal prism
+//=======================================================================
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
+                                               int n5, int n6, int n7, int n8,
+                                               int n9, int n10, int n11, int n12,
+                                               int ID)
+{
+  SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, ID);
+  if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12);
+  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, 
+                                               const SMDS_MeshNode * n9, 
+                                               const SMDS_MeshNode * n10, 
+                                               const SMDS_MeshNode * n11, 
+                                               const SMDS_MeshNode * n12, 
+                                               int ID)
+{
+  return AddVolumeWithID(n1->GetID(), 
+                         n2->GetID(),
+                         n3->GetID(),
+                         n4->GetID(),
+                         n5->GetID(),
+                         n6->GetID(),
+                         n7->GetID(),
+                         n8->GetID(),
+                         n9->GetID(),
+                         n10->GetID(),
+                         n11->GetID(),
+                         n12->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, 
+                                         const SMDS_MeshNode * n9, 
+                                         const SMDS_MeshNode * n10, 
+                                         const SMDS_MeshNode * n11, 
+                                         const SMDS_MeshNode * n12)
+{
+  SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12);
+  if(anElem) myScript->AddVolume(anElem->GetID(), 
+                                 n1->GetID(),
+                                 n2->GetID(),
+                                 n3->GetID(),
+                                 n4->GetID(),
+                                 n5->GetID(),
+                                 n6->GetID(),
+                                 n7->GetID(),
+                                 n8->GetID(),
+                                 n9->GetID(),
+                                 n10->GetID(),
+                                 n11->GetID(),
+                                 n12->GetID());
+  return anElem;
+}
+
+
 //=======================================================================
 //function : AddPolygonalFace
 //purpose  : 
 //=======================================================================
-SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
-                                                     const int        ID)
+SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (const std::vector<int>& nodes_ids,
+                                                     const int               ID)
 {
   SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes_ids, ID);
   if (anElem) {
@@ -542,8 +707,8 @@ SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
 }
 
 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID
-                             (std::vector<const SMDS_MeshNode*> nodes,
-                              const int                         ID)
+                             (const std::vector<const SMDS_MeshNode*>& nodes,
+                              const int                                ID)
 {
   SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
   if (anElem) {
@@ -558,7 +723,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID
 }
 
 SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFace
-                             (std::vector<const SMDS_MeshNode*> nodes)
+                             (const std::vector<const SMDS_MeshNode*>& nodes)
 {
   SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFace(nodes);
   if (anElem) {
@@ -576,9 +741,9 @@ SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFace
 //function : AddPolyhedralVolume
 //purpose  : 
 //=======================================================================
-SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID (std::vector<int> nodes_ids,
-                                                          std::vector<int> quantities,
-                                                          const int        ID)
+SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID (const std::vector<int>& nodes_ids,
+                                                          const std::vector<int>& quantities,
+                                                          const int               ID)
 {
   SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes_ids, quantities, ID);
   if (anElem) {
@@ -588,9 +753,9 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID (std::vector<int> nodes
 }
 
 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID
-                               (std::vector<const SMDS_MeshNode*> nodes,
-                                std::vector<int>                  quantities,
-                                const int                         ID)
+                               (const std::vector<const SMDS_MeshNode*>& nodes,
+                                const std::vector<int>&                  quantities,
+                                const int                                ID)
 {
   SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
   if (anElem) {
@@ -605,8 +770,8 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID
 }
 
 SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolume
-                               (std::vector<const SMDS_MeshNode*> nodes,
-                                std::vector<int>                  quantities)
+                               (const std::vector<const SMDS_MeshNode*>& nodes,
+                                const std::vector<int>&                  quantities)
 {
   SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolume(nodes, quantities);
   if (anElem) {
@@ -652,43 +817,50 @@ static void removeFromContainers (map<int,SMESHDS_SubMesh*>&     theSubMeshes,
     }
   }
 
+  const bool deleted=true;
+
   // Rm from sub-meshes
   // Element should belong to only one sub-mesh
-  map<int,SMESHDS_SubMesh*>::iterator SubIt = theSubMeshes.begin();
-  for ( ; SubIt != theSubMeshes.end(); SubIt++ )
+  if ( !theSubMeshes.empty() )
   {
-    int size = isNode ? (*SubIt).second->NbNodes() : (*SubIt).second->NbElements();
-    if ( size == 0 ) continue;
-
+    SMESHDS_Mesh* mesh = theSubMeshes.begin()->second->getParent();
     list<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
-    while ( elIt != theElems.end() )
-    {
-      bool removed = false;
-      if ( isNode )
-        removed = (*SubIt).second->RemoveNode( static_cast<const SMDS_MeshNode*> (*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++ ;
-      }
+    if ( isNode ) {
+      for ( ; elIt != theElems.end(); ++elIt )
+        if ( SMESHDS_SubMesh* sm = mesh->MeshElements( (*elIt)->getshapeId() ))
+          sm->RemoveNode( static_cast<const SMDS_MeshNode*> (*elIt), deleted );
+    }
+    else {
+      for ( ; elIt != theElems.end(); ++elIt )
+        if ( SMESHDS_SubMesh* sm = mesh->MeshElements( (*elIt)->getshapeId() ))
+          sm->RemoveElement( *elIt, deleted );
     }
   }
 }
-  
+
 //=======================================================================
 //function : RemoveNode
 //purpose  : 
 //=======================================================================
 void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n)
 {
+  if ( n->NbInverseElements() == 0 && !(hasConstructionEdges() || hasConstructionFaces()))
+  {
+    SMESHDS_SubMesh* subMesh=0;
+    map<int,SMESHDS_SubMesh*>::iterator SubIt =
+      myShapeIndexToSubMesh.find( n->getshapeId() );
+    if ( SubIt != myShapeIndexToSubMesh.end() )
+      subMesh = SubIt->second;
+    else
+      SubIt = myShapeIndexToSubMesh.begin();
+    for ( ; !subMesh && SubIt != myShapeIndexToSubMesh.end(); SubIt++ )
+      if (!SubIt->second->IsComplexSubmesh() && SubIt->second->Contains( n ))
+        subMesh = SubIt->second;
+
+    RemoveFreeNode( n, subMesh, true);
+    return;
+  }
+    
   myScript->RemoveNode(n->GetID());
   
   list<const SMDS_MeshElement *> removedElems;
@@ -724,7 +896,7 @@ void SMESHDS_Mesh::RemoveFreeNode(const SMDS_MeshNode * n,
   // Rm from sub-mesh
   // Node should belong to only one sub-mesh
   if( subMesh )
-    subMesh->RemoveNode(n);
+    subMesh->RemoveNode(n,/*deleted=*/false);
 
   SMDS_Mesh::RemoveFreeElement(n);
 }
@@ -740,7 +912,18 @@ void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt)
     RemoveNode( static_cast<const SMDS_MeshNode*>( elt ));
     return;
   }
-
+  if (!hasConstructionEdges() && !hasConstructionFaces())
+  {
+    SMESHDS_SubMesh* subMesh=0;
+    map<int,SMESHDS_SubMesh*>::iterator SubIt = myShapeIndexToSubMesh.begin();
+    for ( ; !subMesh && SubIt != myShapeIndexToSubMesh.end(); SubIt++ )
+      if (!SubIt->second->IsComplexSubmesh() && SubIt->second->Contains( elt ))
+        subMesh = SubIt->second;
+    //MESSAGE("subMesh " << elt->getshapeId());
+    RemoveFreeElement( elt, subMesh, true);
+    return;
+  }
   myScript->RemoveElement(elt->GetID());
 
   list<const SMDS_MeshElement *> removedElems;
@@ -759,6 +942,7 @@ void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt,
                                      SMESHDS_SubMesh *        subMesh,
                                      bool                     fromGroups)
 {
+  //MESSAGE(" --------------------------------> SMESHDS_Mesh::RemoveFreeElement " << subMesh << " " << fromGroups);
   if (elt->GetType() == SMDSAbs_Node) {
     RemoveFreeNode( static_cast<const SMDS_MeshNode*>(elt), subMesh);
     return;
@@ -784,7 +968,7 @@ void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt,
   // Rm from sub-mesh
   // Element should belong to only one sub-mesh
   if( subMesh )
-    subMesh->RemoveElement(elt);
+    subMesh->RemoveElement(elt, /*deleted=*/false);
 
   SMDS_Mesh::RemoveFreeElement(elt);
 }
@@ -819,7 +1003,7 @@ void SMESHDS_Mesh::ClearMesh()
 //================================================================================
 /*!
  * \brief return submesh by shape
-  * \param shape - the subshape
+  * \param shape - the sub-shape
   * \retval SMESHDS_SubMesh* - the found submesh
   *
  * search of submeshes is optimized
@@ -841,8 +1025,8 @@ SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const TopoDS_Shape & shape )
 
 //================================================================================
 /*!
- * \brief return submesh by subshape index
-  * \param Index - the subshape index
+ * \brief return submesh by sub-shape index
+  * \param Index - the sub-shape index
   * \retval SMESHDS_SubMesh* - the found submesh
  * search of submeshes is optimized
  */
@@ -854,7 +1038,7 @@ SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const int Index )
   if ( Index != myCurSubID ) {
     map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
     if ( it == myShapeIndexToSubMesh.end() )
-      it = myShapeIndexToSubMesh.insert( make_pair(Index, new SMESHDS_SubMesh() )).first;
+      it = myShapeIndexToSubMesh.insert( make_pair(Index, new SMESHDS_SubMesh(this, Index) )).first;
     myCurSubMesh = it->second;
     myCurSubID = Index;
     myCurSubShape.Nullify(); // myCurSubShape no more corresponds to submesh
@@ -882,22 +1066,6 @@ bool SMESHDS_Mesh::add(const SMDS_MeshElement* elem, SMESHDS_SubMesh* subMesh )
   return false;
 }
 
-namespace {
-
-  //================================================================================
-  /*!
-   * \brief Creates a node position in volume
-   */
-  //================================================================================
-
-  inline SMDS_PositionPtr volumePosition(int volId)
-  {
-    SMDS_SpacePosition* pos = new SMDS_SpacePosition();
-    pos->SetShapeId( volId );
-    return SMDS_PositionPtr(pos);
-  }
-}
-
 //=======================================================================
 //function : SetNodeOnVolume
 //purpose  : 
@@ -906,8 +1074,9 @@ void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode *      aNode,
                                    const TopoDS_Shell & S)
 {
   if ( add( aNode, getSubmesh(S) ))
-    aNode->SetPosition ( volumePosition( myCurSubID ));
+    aNode->SetPosition ( SMDS_SpacePosition::originSpacePosition() );
 }
+
 //=======================================================================
 //function : SetNodeOnVolume
 //purpose  : 
@@ -916,7 +1085,7 @@ void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode *      aNode,
                                    const TopoDS_Solid & S)
 {
   if ( add( aNode, getSubmesh(S) ))
-    aNode->SetPosition ( volumePosition( myCurSubID ));
+    aNode->SetPosition ( SMDS_SpacePosition::originSpacePosition() );
 }
 
 //=======================================================================
@@ -929,7 +1098,7 @@ void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode *     aNode,
                                  double              v)
 {
   if ( add( aNode, getSubmesh(S) ))
-    aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(myCurSubID, u, v)));
+    aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition( u, v)));
 }
 
 //=======================================================================
@@ -941,7 +1110,7 @@ void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode *     aNode,
                                  double              u)
 {
   if ( add( aNode, getSubmesh(S) ))
-    aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(myCurSubID, u)));
+    aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(u)));
 }
 
 //=======================================================================
@@ -952,7 +1121,7 @@ void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode *       aNode,
                                    const TopoDS_Vertex & S)
 {
   if ( add( aNode, getSubmesh(S) ))
-    aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(myCurSubID)));
+    aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition()));
 }
 
 //=======================================================================
@@ -961,12 +1130,13 @@ void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode *       aNode,
 //=======================================================================
 void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode)
 {
-  if ( aNode && aNode->GetPosition() ) {
-    map<int,SMESHDS_SubMesh*>::iterator it =
-      myShapeIndexToSubMesh.find( aNode->GetPosition()->GetShapeId() );
-    if ( it != myShapeIndexToSubMesh.end() )
-      it->second->RemoveNode( aNode );
-  }
+  int shapeId = aNode->getshapeId();
+  if (shapeId >= 0)
+    {
+      map<int, SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find(shapeId);
+      if (it != myShapeIndexToSubMesh.end())
+        it->second->RemoveNode(aNode, /*deleted=*/false);
+    }
 }
 
 //=======================================================================
@@ -990,10 +1160,12 @@ void SMESHDS_Mesh::UnSetMeshElementOnShape(const SMDS_MeshElement * elem,
 
   map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
   if ( it != myShapeIndexToSubMesh.end() )
-    if ( elem->GetType() == SMDSAbs_Node )
-      it->second->RemoveNode( static_cast<const SMDS_MeshNode* >( elem ));
-    else
-      it->second->RemoveElement( elem );
+    {
+      if (elem->GetType() == SMDSAbs_Node)
+        it->second->RemoveNode(static_cast<const SMDS_MeshNode*> (elem), /*deleted=*/false);
+      else
+        it->second->RemoveElement(elem, /*deleted=*/false);
+    }
 }
 
 //=======================================================================
@@ -1002,26 +1174,24 @@ void SMESHDS_Mesh::UnSetMeshElementOnShape(const SMDS_MeshElement * elem,
 //=======================================================================
 TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const
 {
-       return myShape;
+        return myShape;
 }
 
 //=======================================================================
 //function : IsGroupOfSubShapes
-//purpose  : return true if at least one subshape of theShape is a subshape
+//purpose  : return true if at least one sub-shape of theShape is a sub-shape
 //           of myShape or theShape == myShape
 //=======================================================================
 
 bool SMESHDS_Mesh::IsGroupOfSubShapes (const TopoDS_Shape& theShape) const
 {
-  if ( myShape.IsSame( theShape ))
+  if ( myIndexToShape.Contains(theShape) )
     return true;
 
-  for ( TopoDS_Iterator it( theShape ); it.More(); it.Next() ) {
-    if (myIndexToShape.Contains( it.Value() ) ||
-        IsGroupOfSubShapes( it.Value() ))
+  for ( TopoDS_Iterator it( theShape ); it.More(); it.Next() )
+    if (IsGroupOfSubShapes( it.Value() ))
       return true;
-  }
-  
+
   return false;
 }
 
@@ -1042,7 +1212,7 @@ SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const TopoDS_Shape & S) const
 ///////////////////////////////////////////////////////////////////////////////
 /// Return the sub mesh by Id of shape it is linked to
 ///////////////////////////////////////////////////////////////////////////////
-SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index)
+SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index) const
 {
   TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
   if (anIter != myShapeIndexToSubMesh.end())
@@ -1055,10 +1225,10 @@ SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index)
 //function : SubMeshIndices
 //purpose  : 
 //=======================================================================
-list<int> SMESHDS_Mesh::SubMeshIndices()
+list<int> SMESHDS_Mesh::SubMeshIndices() const
 {
   list<int> anIndices;
-  std::map<int,SMESHDS_SubMesh*>::iterator anIter = myShapeIndexToSubMesh.begin();
+  std::map<int,SMESHDS_SubMesh*>::const_iterator anIter = myShapeIndexToSubMesh.begin();
   for (; anIter != myShapeIndexToSubMesh.end(); anIter++) {
     anIndices.push_back((*anIter).first);
   }
@@ -1080,13 +1250,28 @@ SMESHDS_Mesh::GetHypothesis(const TopoDS_Shape & S) const
   return empty;
 }
 
+//================================================================================
+/*!
+ * \brief returns true if the hypothesis is assigned to any sub-shape
+ */
+//================================================================================
+
+bool SMESHDS_Mesh::IsUsedHypothesis(const SMESHDS_Hypothesis * H) const
+{
+  ShapeToHypothesis::Iterator s2h( myShapeToHypothesis );
+  for ( ; s2h.More(); s2h.Next() )
+    if ( std::find( s2h.Value().begin(), s2h.Value().end(), H ) != s2h.Value().end() )
+      return true;
+  return false;
+}
+
 //=======================================================================
 //function : GetScript
 //purpose  : 
 //=======================================================================
 SMESHDS_Script* SMESHDS_Mesh::GetScript()
 {
-       return myScript;
+        return myScript;
 }
 
 //=======================================================================
@@ -1095,18 +1280,18 @@ SMESHDS_Script* SMESHDS_Mesh::GetScript()
 //=======================================================================
 void SMESHDS_Mesh::ClearScript()
 {
-       myScript->Clear();
+        myScript->Clear();
 }
 
 //=======================================================================
 //function : HasMeshElements
 //purpose  : 
 //=======================================================================
-bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S)
+bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S) const
 {
-       if (myShape.IsNull()) MESSAGE("myShape is NULL");
-       int Index = myIndexToShape.FindIndex(S);
-       return myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end();
+        if (myShape.IsNull()) MESSAGE("myShape is NULL");
+        int Index = myIndexToShape.FindIndex(S);
+        return myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end();
 }
 
 //=======================================================================
@@ -1128,7 +1313,7 @@ SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index)
   TShapeIndexToSubMesh::iterator anIter = myShapeIndexToSubMesh.find(Index);
   if (anIter == myShapeIndexToSubMesh.end())
   {
-    SM = new SMESHDS_SubMesh();
+    SM = new SMESHDS_SubMesh(this, Index);
     myShapeIndexToSubMesh[Index]=SM;
   }
   else
@@ -1145,7 +1330,7 @@ int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S,
                                      TopAbs_ShapeEnum    type)
 {
   int aMainIndex = 0;
-  if ( IsGroupOfSubShapes( S ) || (S.ShapeType() == TopAbs_VERTEX && myIndexToShape.Contains(S)) )
+  if ( IsGroupOfSubShapes( S ))
   {
     aMainIndex = myIndexToShape.Add( S );
     bool all = ( type == TopAbs_SHAPE );
@@ -1155,7 +1340,7 @@ int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S,
     SMESHDS_SubMesh * aNewSub = NewSubMesh( aMainIndex );
     if ( !aNewSub->IsComplexSubmesh() ) // is empty
     {
-      int shapeType = all ? myShape.ShapeType() : type;
+      int shapeType = Max( TopAbs_SOLID, all ? myShape.ShapeType() : type );
       int typeLimit = all ? TopAbs_VERTEX : type;
       for ( ; shapeType <= typeLimit; shapeType++ )
       {
@@ -1178,7 +1363,26 @@ int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S,
 //=======================================================================
 const TopoDS_Shape& SMESHDS_Mesh::IndexToShape(int ShapeIndex) const
 {
-       return myIndexToShape.FindKey(ShapeIndex);
+  try
+  {
+    return myIndexToShape.FindKey(ShapeIndex);
+  }
+  catch ( Standard_OutOfRange )
+  {
+  }
+  static TopoDS_Shape nullShape;
+  return nullShape;
+}
+
+//================================================================================
+/*!
+ * \brief Return max index of sub-mesh
+ */
+//================================================================================
+
+int SMESHDS_Mesh::MaxSubMeshIndex() const
+{
+  return myShapeIndexToSubMesh.empty() ? 0 : myShapeIndexToSubMesh.rbegin()->first;
 }
 
 //=======================================================================
@@ -1201,8 +1405,9 @@ int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const
 //=======================================================================
 void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index)
 {
+  //add(aNode, getSubmesh(Index));
   if ( add( aNode, getSubmesh( Index )))
-    ((SMDS_MeshNode*) aNode)->SetPosition( volumePosition( Index ));
+    ((SMDS_MeshNode*) aNode)->SetPosition( SMDS_SpacePosition::originSpacePosition());
 }
 
 //=======================================================================
@@ -1213,7 +1418,7 @@ void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode* aNode, int Index, double u, doub
 {
   //Set Position on Node
   if ( add( aNode, getSubmesh( Index )))
-    aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(Index, u, v)));
+    aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition( u, v)));
 }
 
 //=======================================================================
@@ -1226,7 +1431,7 @@ void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode* aNode,
 {
   //Set Position on Node
   if ( add( aNode, getSubmesh( Index )))
-    aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(Index, u)));
+    aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(u)));
 }
 
 //=======================================================================
@@ -1237,7 +1442,7 @@ void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode* aNode, int Index)
 {
   //Set Position on Node
   if ( add( aNode, getSubmesh( Index )))
-    aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(Index)));
+    aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition()));
 }
 
 //=======================================================================
@@ -1294,8 +1499,8 @@ SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
 {
   SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2,n12);
   if(anElem) myScript->AddEdge(anElem->GetID(), 
-                              n1->GetID(), 
-                              n2->GetID(),
+                               n1->GetID(), 
+                               n2->GetID(),
                                n12->GetID());
   return anElem;
 }
@@ -1310,9 +1515,9 @@ SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
                                            int ID)
 {
   return AddEdgeWithID(n1->GetID(),
-                      n2->GetID(),
+                       n2->GetID(),
                        n12->GetID(),
-                      ID);
+                       ID);
 }
 
 
@@ -1329,7 +1534,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
 {
   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n12,n23,n31);
   if(anElem) myScript->AddFace(anElem->GetID(), 
-                              n1->GetID(), n2->GetID(), n3->GetID(),
+                               n1->GetID(), n2->GetID(), n3->GetID(),
                                n12->GetID(), n23->GetID(), n31->GetID());
   return anElem;
 }
@@ -1360,7 +1565,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
 {
   return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(),
                        n12->GetID(), n23->GetID(), n31->GetID(),
-                      ID);
+                       ID);
 }
 
 
@@ -1379,7 +1584,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
 {
   SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41);
   if(anElem) myScript->AddFace(anElem->GetID(), 
-                              n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
+                               n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
                                n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID());
   return anElem;
 }
@@ -1412,7 +1617,63 @@ SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
 {
   return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
                        n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
-                      ID);
+                       ID);
+}
+
+
+//=======================================================================
+//function : AddFace
+//purpose  : 
+//=======================================================================
+SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
+                                     const SMDS_MeshNode * n2,
+                                     const SMDS_MeshNode * n3,
+                                     const SMDS_MeshNode * n4,
+                                     const SMDS_MeshNode * n12,
+                                     const SMDS_MeshNode * n23,
+                                     const SMDS_MeshNode * n34,
+                                     const SMDS_MeshNode * n41, 
+                                     const SMDS_MeshNode * nCenter)
+{
+  SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1,n2,n3,n4,n12,n23,n34,n41,nCenter);
+  if(anElem) myScript->AddFace(anElem->GetID(), 
+                               n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
+                               n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
+                               nCenter->GetID());
+  return anElem;
+}
+
+//=======================================================================
+//function : AddFaceWithID
+//purpose  : 
+//=======================================================================
+SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
+                                           int n12,int n23,int n34,int n41,
+                                           int nCenter, int ID)
+{
+  SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,nCenter,ID);
+  if(anElem) myScript->AddFace(ID,n1,n2,n3,n4,n12,n23,n34,n41,nCenter);
+  return anElem;
+}
+
+//=======================================================================
+//function : AddFaceWithID
+//purpose  : 
+//=======================================================================
+SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
+                                           const SMDS_MeshNode * n2,
+                                           const SMDS_MeshNode * n3,
+                                           const SMDS_MeshNode * n4,
+                                           const SMDS_MeshNode * n12,
+                                           const SMDS_MeshNode * n23,
+                                           const SMDS_MeshNode * n34, 
+                                           const SMDS_MeshNode * n41, 
+                                           const SMDS_MeshNode * nCenter, 
+                                           int ID)
+{
+  return AddFaceWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
+                       n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
+                       nCenter->GetID(), ID);
 }
 
 
@@ -1433,8 +1694,8 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
 {
   SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
   if(anElem) myScript->AddVolume(anElem->GetID(), 
-                                n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
-                                n12->GetID(), n23->GetID(), n31->GetID(),
+                                 n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
+                                 n12->GetID(), n23->GetID(), n31->GetID(),
                                  n14->GetID(), n24->GetID(), n34->GetID());
   return anElem;
 }
@@ -1452,7 +1713,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
   if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
   return anElem;
 }
-       
+        
 //=======================================================================
 //function : AddVolumeWithID
 //purpose  : 2d order tetrahedron of 10 nodes
@@ -1518,7 +1779,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, i
                                  n15,n25,n35,n45);
   return anElem;
 }
-       
+        
 //=======================================================================
 //function : AddVolumeWithID
 //purpose  : 2d order pyramid of 13 nodes
@@ -1595,7 +1856,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
                                  n45,n56,n64,n14,n25,n36);
   return anElem;
 }
-       
+        
 //=======================================================================
 //function : AddVolumeWithID
 //purpose  : 2d order Pentahedron with 15 nodes
@@ -1628,7 +1889,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
 
 //=======================================================================
 //function : AddVolume
-//purpose  : 
+//purpose  : add quadratic hexahedron
 //=======================================================================
 SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
                                          const SMDS_MeshNode * n2, 
@@ -1683,7 +1944,7 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
                                  n56,n67,n78,n85,n15,n26,n37,n48);
   return anElem;
 }
-       
+        
 //=======================================================================
 //function : AddVolumeWithID
 //purpose  : 2d order Hexahedrons with 20 nodes
@@ -1718,4 +1979,293 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                          ID);
 }
 
+//=======================================================================
+//function : AddVolume
+//purpose  : add tri-quadratic hexahedron of 27 nodes
+//=======================================================================
+
+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, 
+                                         const SMDS_MeshNode * n12,
+                                         const SMDS_MeshNode * n23,
+                                         const SMDS_MeshNode * n34,
+                                         const SMDS_MeshNode * n41, 
+                                         const SMDS_MeshNode * n56,
+                                         const SMDS_MeshNode * n67,
+                                         const SMDS_MeshNode * n78,
+                                         const SMDS_MeshNode * n85, 
+                                         const SMDS_MeshNode * n15,
+                                         const SMDS_MeshNode * n26,
+                                         const SMDS_MeshNode * n37,
+                                         const SMDS_MeshNode * n48, 
+                                         const SMDS_MeshNode * n1234,
+                                         const SMDS_MeshNode * n1256,
+                                         const SMDS_MeshNode * n2367,
+                                         const SMDS_MeshNode * n3478,
+                                         const SMDS_MeshNode * n1458,
+                                         const SMDS_MeshNode * n5678,
+                                         const SMDS_MeshNode * nCenter)
+{
+  SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1,n2,n3,n4,n5,n6,n7,n8,
+                                                 n12,n23,n34,n41,
+                                                 n56,n67,n78,n85,
+                                                 n15,n26,n37,n48,
+                                                 n1234,n1256,n2367,n3478,n1458,n5678,nCenter);
+  if(anElem)
+    myScript->AddVolume(anElem->GetID(), n1->GetID(), n2->GetID(),
+                        n3->GetID(), n4->GetID(), n5->GetID(),
+                        n6->GetID(), n7->GetID(), n8->GetID(),
+                        n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
+                        n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
+                        n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID(),
+                        n1234->GetID(),n1256->GetID(),n2367->GetID(),n3478->GetID(),
+                        n1458->GetID(),n5678->GetID(),nCenter->GetID());
+  return anElem;
+}
+
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
+                                               int n5, int n6, int n7, int n8,
+                                               int n12,int n23,int n34,int n41,
+                                               int n56,int n67,int n78,int n85,
+                                               int n15,int n26,int n37,int n48,
+                                               int n1234,int n1256,int n2367,int n3478,
+                                               int n1458,int n5678,int nCenter,
+                                               int ID)
+{
+  SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1,n2,n3,n4,n5,n6,n7,n8,
+                                                       n12,n23,n34,n41,
+                                                       n56,n67,n78,n85,
+                                                       n15,n26,n37,n48,
+                                                       n1234, n1256, n2367, n3478,
+                                                       n1458, n5678, nCenter,
+                                                       ID);
+  if(anElem) myScript->AddVolume(ID,n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
+                                 n56,n67,n78,n85,n15,n26,n37,n48,
+                                 n1234, n1256, n2367, n3478,
+                                 n1458, n5678, nCenter);
+  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, 
+                                               const SMDS_MeshNode * n12,
+                                               const SMDS_MeshNode * n23,
+                                               const SMDS_MeshNode * n34,
+                                               const SMDS_MeshNode * n41, 
+                                               const SMDS_MeshNode * n56,
+                                               const SMDS_MeshNode * n67,
+                                               const SMDS_MeshNode * n78,
+                                               const SMDS_MeshNode * n85, 
+                                               const SMDS_MeshNode * n15,
+                                               const SMDS_MeshNode * n26,
+                                               const SMDS_MeshNode * n37,
+                                               const SMDS_MeshNode * n48, 
+                                               const SMDS_MeshNode * n1234,
+                                               const SMDS_MeshNode * n1256,
+                                               const SMDS_MeshNode * n2367,
+                                               const SMDS_MeshNode * n3478,
+                                               const SMDS_MeshNode * n1458,
+                                               const SMDS_MeshNode * n5678,
+                                               const SMDS_MeshNode * nCenter,
+                                               int ID)
+{
+  return AddVolumeWithID(n1->GetID(), n2->GetID(), n3->GetID(), n4->GetID(),
+                         n5->GetID(), n6->GetID(), n7->GetID(), n8->GetID(),
+                         n12->GetID(), n23->GetID(), n34->GetID(), n41->GetID(),
+                         n56->GetID(), n67->GetID(), n78->GetID(), n85->GetID(),
+                         n15->GetID(), n26->GetID(), n37->GetID(), n48->GetID(),
+                         n1234->GetID(),n1256->GetID(),n2367->GetID(),n3478->GetID(),
+                         n1458->GetID(),n5678->GetID(),nCenter->GetID(), ID);
+}
+
+void SMESHDS_Mesh::compactMesh()
+{
+  int newNodeSize = 0;
+  int nbNodes = myNodes.size();
+  int nbVtkNodes = myGrid->GetNumberOfPoints();
+  MESSAGE("nbNodes=" << nbNodes << " nbVtkNodes=" << nbVtkNodes);
+  int nbNodeTemp = nbVtkNodes;
+  if (nbNodes > nbVtkNodes)
+    nbNodeTemp = nbNodes;
+  vector<int> idNodesOldToNew;
+  idNodesOldToNew.clear();
+  idNodesOldToNew.resize(nbNodeTemp, -1); // all unused id will be -1
+
+  for (int i = 0; i < nbNodes; i++)
+    {
+      if (myNodes[i])
+        {
+          int vtkid = myNodes[i]->getVtkId();
+          idNodesOldToNew[vtkid] = i; // old vtkId --> old smdsId (valid smdsId are >= 0)
+          newNodeSize++;
+        }
+    }
+  bool areNodesModified = (newNodeSize < nbVtkNodes);
+  MESSAGE("------------------------- compactMesh Nodes Modified: " << areNodesModified);
+  areNodesModified = true;
+
+  int newCellSize = 0;
+  int nbCells = myCells.size();
+  int nbVtkCells = myGrid->GetNumberOfCells();
+  MESSAGE("nbCells=" << nbCells << " nbVtkCells=" << nbVtkCells);
+  int nbCellTemp = nbVtkCells;
+  if (nbCells > nbVtkCells)
+    nbCellTemp = nbCells;
+  vector<int> idCellsOldToNew;
+  idCellsOldToNew.clear();
+  idCellsOldToNew.resize(nbCellTemp, -1); // all unused id will be -1
+
+  for (int i = 0; i < nbCells; i++)
+    {
+      if (myCells[i])
+        {
+//          //idCellsOldToNew[i] = myCellIdVtkToSmds[i]; // valid vtk indexes are > = 0
+//          int vtkid = myCells[i]->getVtkId();
+//          idCellsOldToNew[vtkid] = i; // old vtkId --> old smdsId (not used in input)
+          newCellSize++;
+        }
+    }
+  if (areNodesModified)
+    myGrid->compactGrid(idNodesOldToNew, newNodeSize, idCellsOldToNew, newCellSize);
+  else
+    myGrid->compactGrid(idNodesOldToNew, 0, idCellsOldToNew, newCellSize);
+
+  int nbVtkPts = myGrid->GetNumberOfPoints();
+  nbVtkCells = myGrid->GetNumberOfCells();
+  if (nbVtkPts != newNodeSize)
+    {
+      MESSAGE("===> nbVtkPts != newNodeSize " << nbVtkPts << " " << newNodeSize);
+      if (nbVtkPts > newNodeSize) newNodeSize = nbVtkPts; // several points with same SMDS Id
+    }
+  if (nbVtkCells != newCellSize)
+    {
+      MESSAGE("===> nbVtkCells != newCellSize " << nbVtkCells << " " << newCellSize);
+      if (nbVtkCells > newCellSize) newCellSize = nbVtkCells; // several cells with same SMDS Id
+    }
+
+  // --- SMDS_MeshNode and myNodes (id in SMDS and in VTK are the same), myNodeIdFactory
+
+  if (areNodesModified)
+    {
+      MESSAGE("-------------- modify myNodes");
+      SetOfNodes newNodes;
+      newNodes.resize(newNodeSize+1,0); // 0 not used, SMDS numbers 1..n
+      int newSmdsId = 0;
+      for (int i = 0; i < nbNodes; i++)
+        {
+          if (myNodes[i])
+            {
+              newSmdsId++; // SMDS id start to 1
+              int oldVtkId = myNodes[i]->getVtkId();
+              int newVtkId = idNodesOldToNew[oldVtkId];
+              //MESSAGE("myNodes["<< i << "] vtkId " << oldVtkId << " --> " << newVtkId);
+              myNodes[i]->setVtkId(newVtkId);
+              myNodes[i]->setId(newSmdsId);
+              newNodes[newSmdsId] = myNodes[i];
+              //MESSAGE("myNodes["<< i << "] --> newNodes[" << newSmdsId << "]");
+            }
+        }
+      myNodes.swap(newNodes);
+      this->myNodeIDFactory->emptyPool(newSmdsId); // newSmdsId = number of nodes
+      MESSAGE("myNodes.size " << myNodes.size());
+    }
+
+  // --- SMDS_MeshCell, myCellIdVtkToSmds, myCellIdSmdsToVtk, myCells
+
+  int vtkIndexSize = myCellIdVtkToSmds.size();
+  int maxVtkId = -1;
+  for (int oldVtkId = 0; oldVtkId < vtkIndexSize; oldVtkId++)
+    {
+      int oldSmdsId = this->myCellIdVtkToSmds[oldVtkId];
+      if (oldSmdsId > 0)
+        {
+          int newVtkId = idCellsOldToNew[oldVtkId];
+          if (newVtkId > maxVtkId)
+            maxVtkId = newVtkId;
+          //MESSAGE("myCells["<< oldSmdsId << "] vtkId " << oldVtkId << " --> " << newVtkId);
+          myCells[oldSmdsId]->setVtkId(newVtkId);
+        }
+    }
+//  MESSAGE("myCells.size()=" << myCells.size()
+//          << " myCellIdSmdsToVtk.size()=" << myCellIdSmdsToVtk.size()
+//          << " myCellIdVtkToSmds.size()=" << myCellIdVtkToSmds.size() );
+
+  SetOfCells newCells;
+  //vector<int> newSmdsToVtk;
+  vector<int> newVtkToSmds;
+
+  assert(maxVtkId < newCellSize);
+  newCells.resize(newCellSize+1, 0); // 0 not used, SMDS numbers 1..n
+  //newSmdsToVtk.resize(newCellSize+1, -1);
+  newVtkToSmds.resize(newCellSize+1, -1);
+
+  int myCellsSize = myCells.size();
+  int newSmdsId = 0;
+  for (int i = 0; i < myCellsSize; i++)
+    {
+      if (myCells[i])
+        {
+          newSmdsId++; // SMDS id start to 1
+          assert(newSmdsId <= newCellSize);
+          newCells[newSmdsId] = myCells[i];
+          newCells[newSmdsId]->setId(newSmdsId);
+          //MESSAGE("myCells["<< i << "] --> newCells[" << newSmdsId << "]");
+          int idvtk = myCells[i]->getVtkId();
+          //newSmdsToVtk[newSmdsId] = idvtk;
+          assert(idvtk < newCellSize);
+          newVtkToSmds[idvtk] = newSmdsId;
+        }
+    }
+
+  myCells.swap(newCells);
+  //myCellIdSmdsToVtk.swap(newSmdsToVtk);
+  myCellIdVtkToSmds.swap(newVtkToSmds);
+  MESSAGE("myCells.size()=" << myCells.size()
+          << " myCellIdVtkToSmds.size()=" << myCellIdVtkToSmds.size() );
+  this->myElementIDFactory->emptyPool(newSmdsId);
+
+  this->myScript->SetModified(true); // notify GUI client for buildPrs when update
+
+  // --- compact list myNodes and myElements in submeshes
+
+  map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.begin();
+  for(; it != myShapeIndexToSubMesh.end(); ++it)
+    {
+      (*it).second->compactList();
+    }
+
+}
+
+void SMESHDS_Mesh::CleanDownWardConnectivity()
+{
+  myGrid->CleanDownwardConnectivity();
+}
 
+void SMESHDS_Mesh::BuildDownWardConnectivity(bool withEdges)
+{
+  myGrid->BuildDownwardConnectivity(withEdges);
+}
+
+/*! change some nodes in cell without modifying type or internal connectivity.
+ * Nodes inverse connectivity is maintained up to date.
+ * @param vtkVolId vtk id of the cell.
+ * @param localClonedNodeIds map old node id to new node id.
+ * @return ok if success.
+ */
+bool SMESHDS_Mesh::ModifyCellNodes(int vtkVolId, std::map<int,int> localClonedNodeIds)
+{
+  myGrid->ModifyCellNodes(vtkVolId, localClonedNodeIds);
+  return true;
+}
index d3df2e688e116420ec8bed330a7da7aee267da29..573e06b9187797d88b8332a7d0cd71a3fe2412eb 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESHDS : management of mesh data and SMESH document
 //  File   : SMESHDS_Mesh.hxx
 //  Module : SMESH
 #include "SMESH_SMESHDS.hxx"
 
 #include "SMDS_Mesh.hxx"
-#include "SMDS_MeshNode.hxx"
-#include "SMDS_MeshEdge.hxx"
-#include "SMDS_MeshFace.hxx"
-#include "SMDS_MeshVolume.hxx"
-#include "SMESHDS_Hypothesis.hxx"
 #include "SMESHDS_SubMesh.hxx"
-#include "SMESHDS_Script.hxx"
 
 #include <TopTools_IndexedMapOfShape.hxx>
 #include <TopoDS_Shape.hxx>
-#include <TopoDS_Solid.hxx>
-#include <TopoDS_Shell.hxx>
-#include <TopoDS_Face.hxx>
-#include <TopoDS_Vertex.hxx>
-#include <TopoDS_Edge.hxx>
+
+class TopoDS_Solid ;
+class TopoDS_Shell ;
+class TopoDS_Face  ;
+class TopoDS_Vertex;
+class TopoDS_Edge  ;
+
+class SMESHDS_Script;
+class SMESHDS_Hypothesis;
+class SMDS_MeshNode     ;
+class SMDS_MeshEdge     ;
+class SMDS_MeshFace     ;
+class SMDS_MeshVolume   ;
+class SMDS_Mesh0DElement;
+class SMDS_BallElement;
 
 #include <NCollection_DataMap.hxx>
 #include <map>
 /*
- * Using of native haah_map isn't portable and don't work on WIN32 platform.
+ * Using of native hash_map isn't portable and don't work on WIN32 platform.
  * So this functionality implement on new NCollection_DataMap technology
  */
 #include "SMESHDS_DataMapOfShape.hxx"
 
 class SMESHDS_GroupBase;
+class DownIdType;
 
 class SMESHDS_EXPORT SMESHDS_Mesh:public SMDS_Mesh{
 public:
   SMESHDS_Mesh(int theMeshID, bool theIsEmbeddedMode);
   bool IsEmbeddedMode();
+  void SetPersistentId(int id);
+  int GetPersistentId() const;
 
   void ShapeToMesh(const TopoDS_Shape & S);
   TopoDS_Shape ShapeToMesh() const;
@@ -66,160 +74,219 @@ public:
   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_MeshNode* AddNode(double x, double y, double z);
   
+  virtual SMDS_Mesh0DElement* Add0DElementWithID(int nodeID, int ID);
+  virtual SMDS_Mesh0DElement* Add0DElementWithID(const SMDS_MeshNode * node, int ID);
+  virtual SMDS_Mesh0DElement* Add0DElement      (const SMDS_MeshNode * node);
+  
+  virtual SMDS_BallElement* AddBallWithID(int n,                   double diameter, int ID);
+  virtual SMDS_BallElement* AddBallWithID(const SMDS_MeshNode * n, double diameter, int ID);
+  virtual SMDS_BallElement* AddBall      (const SMDS_MeshNode * n, double diameter);
+
   virtual SMDS_MeshEdge* AddEdgeWithID(int n1, int n2, int ID);
   virtual SMDS_MeshEdge* AddEdgeWithID(const SMDS_MeshNode * n1,
-                                      const SMDS_MeshNode * n2, 
-                                      int ID);
+                                       const SMDS_MeshNode * n2, 
+                                       int ID);
   virtual SMDS_MeshEdge* AddEdge(const SMDS_MeshNode * n1,
-                                const SMDS_MeshNode * n2);
+                                 const SMDS_MeshNode * n2);
   
   // 2d order edge with 3 nodes: n12 - node between n1 and n2
   virtual SMDS_MeshEdge* AddEdgeWithID(int n1, int n2, int n12, int ID);
   virtual SMDS_MeshEdge* AddEdgeWithID(const SMDS_MeshNode * n1,
-                                      const SMDS_MeshNode * n2, 
-                                      const SMDS_MeshNode * n12, 
-                                      int ID);
+                                       const SMDS_MeshNode * n2, 
+                                       const SMDS_MeshNode * n12, 
+                                       int ID);
   virtual SMDS_MeshEdge* AddEdge(const SMDS_MeshNode * n1,
                                  const SMDS_MeshNode * n2,
                                  const SMDS_MeshNode * n12);
-
+  // tria 3
   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);
+                                       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);
-
+                                 const SMDS_MeshNode * n2,
+                                 const SMDS_MeshNode * n3);
+  // quad 4
   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);
+                                       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);
+                                 const SMDS_MeshNode * n2,
+                                 const SMDS_MeshNode * n3,
+                                 const SMDS_MeshNode * n4);
 
   // 2d order triangle of 6 nodes
   virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3,
                                        int n12,int n23,int n31, int ID);
   virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1,
-                                      const SMDS_MeshNode * n2,
-                                      const SMDS_MeshNode * n3, 
-                                      const SMDS_MeshNode * n12,
-                                      const SMDS_MeshNode * n23,
-                                      const SMDS_MeshNode * n31, 
-                                      int ID);
+                                       const SMDS_MeshNode * n2,
+                                       const SMDS_MeshNode * n3, 
+                                       const SMDS_MeshNode * n12,
+                                       const SMDS_MeshNode * n23,
+                                       const SMDS_MeshNode * n31, 
+                                       int ID);
   virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1,
-                                const SMDS_MeshNode * n2,
-                                const SMDS_MeshNode * n3,
+                                 const SMDS_MeshNode * n2,
+                                 const SMDS_MeshNode * n3,
                                  const SMDS_MeshNode * n12,
-                                const SMDS_MeshNode * n23,
-                                const SMDS_MeshNode * n31);
+                                 const SMDS_MeshNode * n23,
+                                 const SMDS_MeshNode * n31);
 
   // 2d order quadrangle
   virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int n4,
                                        int n12,int n23,int n34,int n41, int ID);
   virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1,
-                                      const SMDS_MeshNode * n2,
-                                      const SMDS_MeshNode * n3,
-                                      const SMDS_MeshNode * n4, 
-                                      const SMDS_MeshNode * n12,
-                                      const SMDS_MeshNode * n23,
-                                      const SMDS_MeshNode * n34,
-                                      const SMDS_MeshNode * n41, 
-                                      int ID);
+                                       const SMDS_MeshNode * n2,
+                                       const SMDS_MeshNode * n3,
+                                       const SMDS_MeshNode * n4, 
+                                       const SMDS_MeshNode * n12,
+                                       const SMDS_MeshNode * n23,
+                                       const SMDS_MeshNode * n34,
+                                       const SMDS_MeshNode * n41, 
+                                       int ID);
   virtual SMDS_MeshFace* 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,
                                  const SMDS_MeshNode * n12,
-                                const SMDS_MeshNode * n23,
-                                const SMDS_MeshNode * n34,
-                                const SMDS_MeshNode * n41);
+                                 const SMDS_MeshNode * n23,
+                                 const SMDS_MeshNode * n34,
+                                 const SMDS_MeshNode * n41);
 
+  // bi-quadratic quadrangle of 9 nodes
+  virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int n4,
+                                       int n12,int n23,int n34,int n41, int nCenter, int ID);
+  virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1,
+                                       const SMDS_MeshNode * n2,
+                                       const SMDS_MeshNode * n3,
+                                       const SMDS_MeshNode * n4, 
+                                       const SMDS_MeshNode * n12,
+                                       const SMDS_MeshNode * n23,
+                                       const SMDS_MeshNode * n34,
+                                       const SMDS_MeshNode * n41, 
+                                       const SMDS_MeshNode * nCenter, 
+                                       int ID);
+  virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1,
+                                 const SMDS_MeshNode * n2,
+                                 const SMDS_MeshNode * n3,
+                                 const SMDS_MeshNode * n4,
+                                 const SMDS_MeshNode * n12,
+                                 const SMDS_MeshNode * n23,
+                                 const SMDS_MeshNode * n34,
+                                 const SMDS_MeshNode * n41,
+                                 const SMDS_MeshNode * nCenter);
+  // tetra 4
   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);
+                                           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);
-
+                                     const SMDS_MeshNode * n2,
+                                     const SMDS_MeshNode * n3,
+                                     const SMDS_MeshNode * n4);
+  // pyra 5
   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);
+                                           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);
-
+                                     const SMDS_MeshNode * n2,
+                                     const SMDS_MeshNode * n3,
+                                     const SMDS_MeshNode * n4,
+                                     const SMDS_MeshNode * n5);
+  // penta 6
   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);
+                                           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);
-
+                                     const SMDS_MeshNode * n2,
+                                     const SMDS_MeshNode * n3,
+                                     const SMDS_MeshNode * n4,
+                                     const SMDS_MeshNode * n5,
+                                     const SMDS_MeshNode * n6);
+  // hexa 8
   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);
+                                           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);
-  
+                                     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);
+  // hexagonal prism of 12 nodes
+  virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6,
+                                           int n7, int n8, int n9, int n10, int n11, int n12, 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, 
+                                           const SMDS_MeshNode * n9, 
+                                           const SMDS_MeshNode * n10, 
+                                           const SMDS_MeshNode * n11, 
+                                           const SMDS_MeshNode * n12, 
+                                           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, 
+                                     const SMDS_MeshNode * n9, 
+                                     const SMDS_MeshNode * n10, 
+                                     const SMDS_MeshNode * n11, 
+                                     const SMDS_MeshNode * n12);
+
   // 2d order tetrahedron of 10 nodes
   virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4,
                                            int n12,int n23,int n31,
                                            int n14,int n24,int n34, 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 * n12,
-                                          const SMDS_MeshNode * n23,
-                                          const SMDS_MeshNode * n31,
-                                          const SMDS_MeshNode * n14, 
-                                          const SMDS_MeshNode * n24,
-                                          const SMDS_MeshNode * n34, 
-                                          int ID);
+                                           const SMDS_MeshNode * n2,
+                                           const SMDS_MeshNode * n3,
+                                           const SMDS_MeshNode * n4, 
+                                           const SMDS_MeshNode * n12,
+                                           const SMDS_MeshNode * n23,
+                                           const SMDS_MeshNode * n31,
+                                           const SMDS_MeshNode * n14, 
+                                           const SMDS_MeshNode * n24,
+                                           const SMDS_MeshNode * n34, 
+                                           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 * n2,
+                                     const SMDS_MeshNode * n3,
+                                     const SMDS_MeshNode * n4,
                                      const SMDS_MeshNode * n12,
                                      const SMDS_MeshNode * n23,
                                      const SMDS_MeshNode * n31,
@@ -233,24 +300,24 @@ public:
                                            int n15,int n25,int n35,int n45,
                                            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 * n12,
-                                          const SMDS_MeshNode * n23,
-                                          const SMDS_MeshNode * n34,
-                                          const SMDS_MeshNode * n41, 
-                                          const SMDS_MeshNode * n15,
-                                          const SMDS_MeshNode * n25,
-                                          const SMDS_MeshNode * n35,
-                                          const SMDS_MeshNode * n45, 
-                                          int ID);
+                                           const SMDS_MeshNode * n2,
+                                           const SMDS_MeshNode * n3,
+                                           const SMDS_MeshNode * n4,
+                                           const SMDS_MeshNode * n5, 
+                                           const SMDS_MeshNode * n12,
+                                           const SMDS_MeshNode * n23,
+                                           const SMDS_MeshNode * n34,
+                                           const SMDS_MeshNode * n41, 
+                                           const SMDS_MeshNode * n15,
+                                           const SMDS_MeshNode * n25,
+                                           const SMDS_MeshNode * n35,
+                                           const SMDS_MeshNode * n45, 
+                                           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 * n2,
+                                     const SMDS_MeshNode * n3,
+                                     const SMDS_MeshNode * n4,
+                                     const SMDS_MeshNode * n5,
                                      const SMDS_MeshNode * n12,
                                      const SMDS_MeshNode * n23,
                                      const SMDS_MeshNode * n34,
@@ -268,27 +335,27 @@ public:
                                            int n14,int n25,int n36,
                                            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 * n12,
-                                          const SMDS_MeshNode * n23,
-                                          const SMDS_MeshNode * n31, 
-                                          const SMDS_MeshNode * n45,
-                                          const SMDS_MeshNode * n56,
-                                          const SMDS_MeshNode * n64, 
-                                          const SMDS_MeshNode * n14,
-                                          const SMDS_MeshNode * n25,
-                                          const SMDS_MeshNode * n36, 
-                                          int ID);
+                                           const SMDS_MeshNode * n2,
+                                           const SMDS_MeshNode * n3,
+                                           const SMDS_MeshNode * n4,
+                                           const SMDS_MeshNode * n5,
+                                           const SMDS_MeshNode * n6, 
+                                           const SMDS_MeshNode * n12,
+                                           const SMDS_MeshNode * n23,
+                                           const SMDS_MeshNode * n31, 
+                                           const SMDS_MeshNode * n45,
+                                           const SMDS_MeshNode * n56,
+                                           const SMDS_MeshNode * n64, 
+                                           const SMDS_MeshNode * n14,
+                                           const SMDS_MeshNode * n25,
+                                           const SMDS_MeshNode * n36, 
+                                           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 * n2,
+                                     const SMDS_MeshNode * n3,
+                                     const SMDS_MeshNode * n4,
+                                     const SMDS_MeshNode * n5,
+                                     const SMDS_MeshNode * n6, 
                                      const SMDS_MeshNode * n12,
                                      const SMDS_MeshNode * n23,
                                      const SMDS_MeshNode * n31, 
@@ -307,34 +374,34 @@ public:
                                            int n15,int n26,int n37,int n48,
                                            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, 
-                                          const SMDS_MeshNode * n12,
-                                          const SMDS_MeshNode * n23,
-                                          const SMDS_MeshNode * n34,
-                                          const SMDS_MeshNode * n41, 
-                                          const SMDS_MeshNode * n56,
-                                          const SMDS_MeshNode * n67,
-                                          const SMDS_MeshNode * n78,
-                                          const SMDS_MeshNode * n85, 
-                                          const SMDS_MeshNode * n15,
-                                          const SMDS_MeshNode * n26,
-                                          const SMDS_MeshNode * n37,
-                                          const SMDS_MeshNode * n48, 
-                                          int ID);
+                                           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 * n12,
+                                           const SMDS_MeshNode * n23,
+                                           const SMDS_MeshNode * n34,
+                                           const SMDS_MeshNode * n41, 
+                                           const SMDS_MeshNode * n56,
+                                           const SMDS_MeshNode * n67,
+                                           const SMDS_MeshNode * n78,
+                                           const SMDS_MeshNode * n85, 
+                                           const SMDS_MeshNode * n15,
+                                           const SMDS_MeshNode * n26,
+                                           const SMDS_MeshNode * n37,
+                                           const SMDS_MeshNode * n48, 
+                                           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, 
+                                     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 * n12,
                                      const SMDS_MeshNode * n23,
                                      const SMDS_MeshNode * n34,
@@ -348,27 +415,92 @@ public:
                                      const SMDS_MeshNode * n37,
                                      const SMDS_MeshNode * n48);
 
-  virtual SMDS_MeshFace* AddPolygonalFaceWithID (std::vector<int> nodes_ids,
-                                                 const int        ID);
+  // 2d order Hexahedrons with 27 nodes
+  virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4,
+                                           int n5, int n6, int n7, int n8,
+                                           int n12,int n23,int n34,int n41,
+                                           int n56,int n67,int n78,int n85,
+                                           int n15,int n26,int n37,int n48,
+                                           int n1234,int n1256,int n2367,int n3478,
+                                           int n1458,int n5678,int nCenter,
+                                           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, 
+                                           const SMDS_MeshNode * n12,
+                                           const SMDS_MeshNode * n23,
+                                           const SMDS_MeshNode * n34,
+                                           const SMDS_MeshNode * n41, 
+                                           const SMDS_MeshNode * n56,
+                                           const SMDS_MeshNode * n67,
+                                           const SMDS_MeshNode * n78,
+                                           const SMDS_MeshNode * n85, 
+                                           const SMDS_MeshNode * n15,
+                                           const SMDS_MeshNode * n26,
+                                           const SMDS_MeshNode * n37,
+                                           const SMDS_MeshNode * n48, 
+                                           const SMDS_MeshNode * n1234,
+                                           const SMDS_MeshNode * n1256,
+                                           const SMDS_MeshNode * n2367,
+                                           const SMDS_MeshNode * n3478,
+                                           const SMDS_MeshNode * n1458,
+                                           const SMDS_MeshNode * n5678,
+                                           const SMDS_MeshNode * nCenter,
+                                           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, 
+                                     const SMDS_MeshNode * n12,
+                                     const SMDS_MeshNode * n23,
+                                     const SMDS_MeshNode * n34,
+                                     const SMDS_MeshNode * n41, 
+                                     const SMDS_MeshNode * n56,
+                                     const SMDS_MeshNode * n67,
+                                     const SMDS_MeshNode * n78,
+                                     const SMDS_MeshNode * n85, 
+                                     const SMDS_MeshNode * n15,
+                                     const SMDS_MeshNode * n26,
+                                     const SMDS_MeshNode * n37,
+                                     const SMDS_MeshNode * n48,
+                                     const SMDS_MeshNode * n1234,
+                                     const SMDS_MeshNode * n1256,
+                                     const SMDS_MeshNode * n2367,
+                                     const SMDS_MeshNode * n3478,
+                                     const SMDS_MeshNode * n1458,
+                                     const SMDS_MeshNode * n5678,
+                                     const SMDS_MeshNode * nCenter);
+
+  virtual SMDS_MeshFace* AddPolygonalFaceWithID (const std::vector<int>& nodes_ids,
+                                                 const int               ID);
 
-  virtual SMDS_MeshFace* AddPolygonalFaceWithID (std::vector<const SMDS_MeshNode*> nodes,
-                                                 const int                         ID);
+  virtual SMDS_MeshFace* AddPolygonalFaceWithID (const std::vector<const SMDS_MeshNode*>& nodes,
+                                                 const int                                ID);
 
-  virtual SMDS_MeshFace* AddPolygonalFace (std::vector<const SMDS_MeshNode*> nodes);
+  virtual SMDS_MeshFace* AddPolygonalFace (const std::vector<const SMDS_MeshNode*>& nodes);
 
   virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID
-                           (std::vector<int> nodes_ids,
-                            std::vector<int> quantities,
-                            const int        ID);
+                           (const std::vector<int>& nodes_ids,
+                            const std::vector<int>& quantities,
+                            const int               ID);
 
   virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID
-                           (std::vector<const SMDS_MeshNode*> nodes,
-                            std::vector<int>                  quantities,
-                            const int                         ID);
+                           (const std::vector<const SMDS_MeshNode*>& nodes,
+                            const std::vector<int>&                  quantities,
+                            const int                                ID);
 
   virtual SMDS_MeshVolume* AddPolyhedralVolume
-                           (std::vector<const SMDS_MeshNode*> nodes,
-                            std::vector<int>                  quantities);
+                           (const std::vector<const SMDS_MeshNode*>& nodes,
+                            const std::vector<int>&                  quantities);
 
   void MoveNode(const SMDS_MeshNode *, double x, double y, double z);
   virtual void RemoveNode(const SMDS_MeshNode *);
@@ -391,6 +523,7 @@ public:
   bool ChangePolyhedronNodes(const SMDS_MeshElement * elem,
                              std::vector<const SMDS_MeshNode*> nodes,
                              std::vector<int>                  quantities);
+  bool ModifyCellNodes(int smdsVolId, std::map<int,int> localClonedNodeIds);
   void Renumber (const bool isNodes, const int startID=1, const int deltaID=1);
 
   void SetNodeInVolume(SMDS_MeshNode * aNode, const TopoDS_Shell & S);
@@ -400,23 +533,25 @@ public:
   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);
+                             const TopoDS_Shape & S);
   void UnSetMeshElementOnShape(const SMDS_MeshElement * anElt,
-                              const TopoDS_Shape & S);
-  bool HasMeshElements(const TopoDS_Shape & S);
+                               const TopoDS_Shape & S);
+  bool HasMeshElements(const TopoDS_Shape & S) const;
   SMESHDS_SubMesh * MeshElements(const TopoDS_Shape & S) const;
-  SMESHDS_SubMesh * MeshElements(const int Index);
-  std::list<int> SubMeshIndices();
+  SMESHDS_SubMesh * MeshElements(const int Index) const;
+  std::list<int> SubMeshIndices() const;
   const std::map<int,SMESHDS_SubMesh*>& SubMeshes() const
   { return myShapeIndexToSubMesh; }
 
   bool HasHypothesis(const TopoDS_Shape & S);
   const std::list<const SMESHDS_Hypothesis*>& GetHypothesis(const TopoDS_Shape & S) const;
+  bool IsUsedHypothesis(const SMESHDS_Hypothesis * H) const;
   SMESHDS_Script * GetScript();
   void ClearScript();
   int ShapeToIndex(const TopoDS_Shape & aShape) const;
   const TopoDS_Shape& IndexToShape(int ShapeIndex) const;
   int MaxShapeIndex() const { return myIndexToShape.Extent(); }
+  int MaxSubMeshIndex() const;
 
   SMESHDS_SubMesh * NewSubMesh(int Index);
   int AddCompoundSubmesh(const TopoDS_Shape& S, TopAbs_ShapeEnum type = TopAbs_SHAPE);
@@ -426,6 +561,7 @@ public:
   void SetNodeOnVertex(SMDS_MeshNode * aNode, int Index);
   void SetMeshElementOnShape(const SMDS_MeshElement * anElt, int Index);
 
+  // Groups. SMESHDS_Mesh is not an owner of groups
   void AddGroup (SMESHDS_GroupBase* theGroup)      { myGroups.insert(theGroup); }
   void RemoveGroup (SMESHDS_GroupBase* theGroup)   { myGroups.erase(theGroup); }
   int GetNbGroups() const                      { return myGroups.size(); }
@@ -433,6 +569,10 @@ public:
 
   bool IsGroupOfSubShapes (const TopoDS_Shape& aSubShape) const;
 
+  virtual void compactMesh();
+  void CleanDownWardConnectivity();
+  void BuildDownWardConnectivity(bool withEdges);
+
   ~SMESHDS_Mesh();
   
 private:
@@ -441,9 +581,9 @@ private:
     //Update or build submesh
     std::map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
     if ( it == myShapeIndexToSubMesh.end() )
-      it = myShapeIndexToSubMesh.insert( std::make_pair(Index, new SMESHDS_SubMesh() )).first;
+      it = myShapeIndexToSubMesh.insert( std::make_pair(Index, new SMESHDS_SubMesh(this, Index) )).first;
     it->second->AddNode( aNode ); // add aNode to submesh
-    }
+  }
   
   /*int HashCode( const TopoDS_Shape& S, const Standard_Integer theUpper ) const
   {
@@ -456,7 +596,7 @@ private:
 
   ShapeToHypothesis          myShapeToHypothesis;
 
-  int                        myMeshID;
+  int                        myMeshID, myPersistentID;
   TopoDS_Shape               myShape;
 
   typedef std::map<int,SMESHDS_SubMesh*> TShapeIndexToSubMesh;
index 9b6daa8b1a538abd5489278466e530c11d87dd03..b4ec13f7c903e773219a5aa7cb0948d8412917c2 100644 (file)
@@ -1,31 +1,32 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESHDS : management of mesh data and SMESH document
 //  File   : SMESH_Script.cxx
 //  Author : Yves FRICAUD, OCC
 //  Module : SMESH
-//  $Header: 
 //
 #include "SMESHDS_Script.hxx"
+#include <iostream>
 
 using namespace std;
 
@@ -35,7 +36,9 @@ using namespace std;
 //=======================================================================
 SMESHDS_Script::SMESHDS_Script(bool theIsEmbeddedMode):
   myIsEmbeddedMode(theIsEmbeddedMode)
-{}
+{
+  //cerr << "=========================== myIsEmbeddedMode " << myIsEmbeddedMode << endl;
+}
 
 //=======================================================================
 //function : Destructor
@@ -95,6 +98,19 @@ void SMESHDS_Script::AddNode(int NewNodeID, double x, double y, double z)
   getCommand(SMESHDS_AddNode)->AddNode(NewNodeID, x, y, z);
 }
 
+//=======================================================================
+//function :
+//purpose  :
+//=======================================================================
+void SMESHDS_Script::Add0DElement (int New0DElementID, int idnode)
+{
+  if (myIsEmbeddedMode) {
+    myIsModified = true;
+    return;
+  }
+  getCommand(SMESHDS_Add0DElement)->Add0DElement(New0DElementID, idnode);
+}
+
 //=======================================================================
 //function : 
 //purpose  : 
@@ -208,11 +224,29 @@ void SMESHDS_Script::AddVolume(int NewID,
                                                idnode5, idnode6, idnode7, idnode8);
 }
 
+//=======================================================================
+//function : 
+//purpose  : 
+//=======================================================================
+void SMESHDS_Script::AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3,
+                               int idnode4, int idnode5, int idnode6, int idnode7, int idnode8,
+                               int idnode9, int idnode10, int idnode11, int idnode12)
+{
+  if(myIsEmbeddedMode){
+    myIsModified = true;
+    return;
+  }
+  getCommand(SMESHDS_AddHexagonalPrism)->AddVolume(NewVolID,
+                                                   idnode1, idnode2, idnode3, idnode4,
+                                                   idnode5, idnode6, idnode7, idnode8,
+                                                   idnode9, idnode10, idnode11, idnode12);
+}
+
 //=======================================================================
 //function : AddPolygonalFace
 //purpose  : 
 //=======================================================================
-void SMESHDS_Script::AddPolygonalFace (int NewFaceID, std::vector<int> nodes_ids)
+void SMESHDS_Script::AddPolygonalFace (int NewFaceID, const std::vector<int>& nodes_ids)
 {
   if(myIsEmbeddedMode){
     myIsModified = true;
@@ -225,9 +259,9 @@ void SMESHDS_Script::AddPolygonalFace (int NewFaceID, std::vector<int> nodes_ids
 //function : AddPolyhedralVolume
 //purpose  : 
 //=======================================================================
-void SMESHDS_Script::AddPolyhedralVolume (int NewID,
-                                          std::vector<int> nodes_ids,
-                                          std::vector<int> quantities)
+void SMESHDS_Script::AddPolyhedralVolume (int                     NewID,
+                                          const std::vector<int>& nodes_ids,
+                                          const std::vector<int>& quantities)
 {
   if(myIsEmbeddedMode){
     myIsModified = true;
@@ -237,6 +271,19 @@ void SMESHDS_Script::AddPolyhedralVolume (int NewID,
     (NewID, nodes_ids, quantities);
 }
 
+//=======================================================================
+//function : AddBall
+//purpose  : Record adding a Ball
+//=======================================================================
+
+void SMESHDS_Script::AddBall(int NewBallID, int node, double diameter)
+{
+  if ( myIsEmbeddedMode )
+    myIsModified = true;
+  else
+    getCommand(SMESHDS_AddBall)->AddBall(NewBallID, node, diameter);
+}
+
 //=======================================================================
 //function : 
 //purpose  : 
@@ -294,9 +341,9 @@ void SMESHDS_Script::ChangeElementNodes(int ElementID, int nodes[], int nbnodes)
 //function : ChangePolyhedronNodes
 //purpose  : 
 //=======================================================================
-void SMESHDS_Script::ChangePolyhedronNodes (const int        ElementID,
-                                            std::vector<int> nodes_ids,
-                                            std::vector<int> quantities)
+void SMESHDS_Script::ChangePolyhedronNodes (const int               ElementID,
+                                            const std::vector<int>& nodes_ids,
+                                            const std::vector<int>& quantities)
 {
   if(myIsEmbeddedMode){
     myIsModified = true;
@@ -403,6 +450,21 @@ void SMESHDS_Script::AddFace(int NewFaceID, int n1, int n2, int n3, int n4,
                                                  n12, n23, n34, n41);
 }
 
+//=======================================================================
+//function : AddFace
+//purpose  : 
+//=======================================================================
+void SMESHDS_Script::AddFace(int NewFaceID, int n1, int n2, int n3, int n4,
+                             int n12, int n23, int n34, int n41, int nCenter)
+{
+  if(myIsEmbeddedMode){
+    myIsModified = true;
+    return;
+  }
+  getCommand(SMESHDS_AddBiQuadQuadrangle)->AddFace(NewFaceID, n1, n2, n3, n4,
+                                                   n12, n23, n34, n41, nCenter);
+}
+
 //=======================================================================
 //function : AddVolume
 //purpose  : 
@@ -477,3 +539,28 @@ void SMESHDS_Script::AddVolume(int NewVolID, int n1, int n2, int n3,
                                                    n15, n26, n37, n48);
 }
 
+//=======================================================================
+//function : AddVolume
+//purpose  : 
+//=======================================================================
+void SMESHDS_Script::AddVolume(int NewVolID, int n1, int n2, int n3,
+                               int n4, int n5, int n6, int n7, int n8,
+                               int n12, int n23, int n34, int n41,
+                               int n56, int n67, int n78, int n85,
+                               int n15, int n26, int n37, int n48,
+                               int n1234,int n1256,int n2367,int n3478,
+                               int n1458,int n5678,int nCenter)
+{
+  if(myIsEmbeddedMode){
+    myIsModified = true;
+    return;
+  }
+  getCommand(SMESHDS_AddTriQuadHexa)->AddVolume(NewVolID, n1, n2, n3, n4,
+                                                n5, n6, n7, n8,
+                                                n12, n23, n34, n41,
+                                                n56, n67, n78, n85,
+                                                n15, n26, n37, n48,
+                                                n1234, n1256, n2367, n3478,
+                                                n1458, n5678, nCenter);
+}
+
index 808066bc3e8f4d90bcb1bd1bf19585a1c2fbebfe..8bd3fc5794ebbb8e2481585454f39ffb96b899af 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESHDS : management of mesh data and SMESH document
 //  File   : SMESHDS_Script.hxx
 //  Module : SMESH
 class SMESHDS_EXPORT SMESHDS_Script
 {
   public:
-       SMESHDS_Script(bool theIsEmbeddedMode);
-       ~SMESHDS_Script();
+        SMESHDS_Script(bool theIsEmbeddedMode);
+        ~SMESHDS_Script();
   
         void SetModified(bool theModified);
         bool IsModified();
 
-       void AddNode(int NewNodeID, double x, double y, double z);
-       void AddEdge(int NewEdgeID, int idnode1, int idnode2);
-       void AddFace(int NewFaceID, int idnode1, int idnode2, int idnode3);
-       void AddFace(int NewFaceID, int idnode1, int idnode2, int idnode3,
-               int idnode4);
-       void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3,
-               int idnode4);
-       void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3,
-               int idnode4, int idnode5);
-       void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3,
-               int idnode4, int idnode5, int idnode6);
-       void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3,
-               int idnode4, int idnode5, int idnode6, int idnode7, int idnode8);
+        void AddNode(int NewNodeID, double x, double y, double z);
+        void Add0DElement(int New0DElementID, int idnode);
+        void AddEdge(int NewEdgeID, int idnode1, int idnode2);
+        void AddFace(int NewFaceID, int idnode1, int idnode2, int idnode3);
+        void AddFace(int NewFaceID, int idnode1, int idnode2, int idnode3,
+                int idnode4);
+        void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3,
+                int idnode4);
+        void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3,
+                int idnode4, int idnode5);
+        void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3,
+                int idnode4, int idnode5, int idnode6);
+        void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3,
+                int idnode4, int idnode5, int idnode6, int idnode7, int idnode8);
+        void AddVolume(int NewVolID, int idnode1, int idnode2, int idnode3,
+                       int idnode4, int idnode5, int idnode6, int idnode7, int idnode8,
+                       int idnode9, int idnode10, int idnode11, int idnode12);
 
-        void AddPolygonalFace (const int NewFaceID,
-                               std::vector<int> nodes_ids);
-       void AddPolyhedralVolume (const int NewVolID,
-                                  std::vector<int> nodes_ids,
-                                  std::vector<int> quantities);
+        void AddPolygonalFace (const int               NewFaceID,
+                               const std::vector<int>& nodes_ids);
+        void AddPolyhedralVolume (const int               NewVolID,
+                                  const std::vector<int>& nodes_ids,
+                                  const std::vector<int>& quantities);
+        void AddBall(int NewBallID, int node, double diameter);
 
         // special methods for quadratic elements
-       void AddEdge(int NewEdgeID, int n1, int n2, int n12);
+        void AddEdge(int NewEdgeID, int n1, int n2, int n12);
         void AddFace(int NewFaceID, int n1, int n2, int n3,
                      int n12, int n23, int n31);
         void AddFace(int NewFaceID, int n1, int n2, int n3, int n4,
                      int n12, int n23, int n34, int n41);
+        void AddFace(int NewFaceID, int n1, int n2, int n3, int n4,
+                     int n12, int n23, int n34, int n41, int nCenter);
         void AddVolume(int NewVolID, int n1, int n2, int n3, int n4,
                        int n12, int n23, int n31, int n14, int n24, int n34);
         void AddVolume(int NewVolID, int n1, int n2, int n3, int n4, int n5,
@@ -84,22 +92,29 @@ class SMESHDS_EXPORT SMESHDS_Script
                        int n12, int n23, int n34, int n41,
                        int n56, int n67, int n78, int n85,
                        int n15, int n26, int n37, int n48);
+        void AddVolume(int NewVolID, int n1, int n2, int n3, int n4,
+                       int n5,  int n6,  int n7,  int n8,
+                       int n12, int n23, int n34, int n41,
+                       int n56, int n67, int n78, int n85,
+                       int n15, int n26, int n37, int n48,
+                       int n1234,int n1256,int n2367,int n3478,
+                       int n1458,int n5678,int nCenter);
         void MoveNode(int NewNodeID, double x, double y, double z);
-       void RemoveNode(int NodeID);
-       void RemoveElement(int ElementID);
-       void ChangeElementNodes(int ElementID, int nodes[], int nbnodes);
-       void ChangePolyhedronNodes(const int        ElementID,
-                                   std::vector<int> nodes_ids,
-                                   std::vector<int> quantities);
-       void Renumber (const bool isNodes, const int startID, const int deltaID);
-       void ClearMesh();
-       void Clear();
-       const std::list<SMESHDS_Command*> & GetCommands();
+        void RemoveNode(int NodeID);
+        void RemoveElement(int ElementID);
+        void ChangeElementNodes(int ElementID, int nodes[], int nbnodes);
+        void ChangePolyhedronNodes(const int               ElementID,
+                                   const std::vector<int>& nodes_ids,
+                                   const std::vector<int>& quantities);
+        void Renumber (const bool isNodes, const int startID, const int deltaID);
+        void ClearMesh();
+        void Clear();
+        const std::list<SMESHDS_Command*> & GetCommands();
 
   private:
-       SMESHDS_Command* getCommand(const SMESHDS_CommandType aType);
+        SMESHDS_Command* getCommand(const SMESHDS_CommandType aType);
 
-       std::list<SMESHDS_Command*> myCommands;
+        std::list<SMESHDS_Command*> myCommands;
 
         bool myIsEmbeddedMode;
         bool myIsModified;
index 127c5c2d99ccd100786b66dd0e3c858ab40f4574..32073bb50bb9e179eca45bf9f615772fc798acc3 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESHDS : management of mesh data and SMESH document
 //  File   : SMESH_SubMesh.cxx
 //  Author : Yves FRICAUD, OCC
 //  $Header: 
 //
 #include "SMESHDS_SubMesh.hxx"
+#include "SMESHDS_Mesh.hxx"
 
 #include "utilities.h"
 #include "SMDS_SetIterator.hxx"
+#include <iostream>
+#include <cassert>
 
 using namespace std;
 
+
+//================================================================================
+/*!
+ * \brief Constructor
+ */
+//================================================================================
+
+SMESHDS_SubMesh::SMESHDS_SubMesh(SMESHDS_Mesh *parent, int index)
+{
+  myParent = parent;
+  myElements.clear();
+  myNodes.clear();
+  myIndex = index;
+  myUnusedIdNodes = 0;
+  myUnusedIdElements = 0;
+}
+
+//================================================================================
+/*!
+ * \brief Destructor
+ */
+//================================================================================
+
+SMESHDS_SubMesh::~SMESHDS_SubMesh()
+{
+}
+
 //=======================================================================
 //function : AddElement
 //purpose  : 
 //=======================================================================
 void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * ME)
 {
-  if ( !IsComplexSubmesh() )
-    myElements.insert(ME);
+  if (!IsComplexSubmesh())
+    {
+      if ( ME->GetType() == SMDSAbs_Node )
+      {
+        AddNode( static_cast< const SMDS_MeshNode* >( ME ));
+        return;
+      }
+      //MESSAGE("in " << myIndex << " AddElement "<< ME->GetID());
+      int oldShapeId = ME->getshapeId();
+      if ( oldShapeId > 0 )
+        {
+          if (oldShapeId != myIndex)
+            {
+              MESSAGE("add element in subshape already belonging to another subshape "
+                << ME->GetID() << " " << oldShapeId << " " << myIndex);
+              throw SALOME_Exception(LOCALIZED("add element in subshape already belonging to a subshape"));
+            }
+          else
+            {
+              int idInSubShape = ME->getIdInShape();
+              if (idInSubShape >= 0)
+                {
+                  MESSAGE("add element in subshape already belonging to that subshape "
+                      << ME->GetID() << " " << oldShapeId << " " << idInSubShape);
+                  // check if ok: do nothing if ok
+                  if (idInSubShape >= myElements.size())
+                    {
+                      MESSAGE("out of bounds " << idInSubShape << " " << myElements.size());
+                      throw SALOME_Exception(LOCALIZED("out of bounds"));
+                    }
+                  if (ME != myElements[idInSubShape])
+                    {
+                      MESSAGE("not the same element");
+                      throw SALOME_Exception(LOCALIZED("not the same element"));
+                    }
+                  MESSAGE("already done, OK, nothing to do");
+                  return;
+                }
+            }
+        }
+
+      SMDS_MeshElement* elem = (SMDS_MeshElement*) (ME);
+      elem->setShapeId(myIndex);
+      elem->setIdInShape(myElements.size());
+      myElements.push_back(ME);
+    }
 }
 
 //=======================================================================
 //function : RemoveElement
 //purpose  : 
 //=======================================================================
-bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME)
+bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME, bool isElemDeleted)
 {
-  if ( !IsComplexSubmesh() && NbElements() )
-    return myElements.erase(ME);
-  
+  if (!ME)
+    {
+      MESSAGE("-----------------> Remove Null Element " << isElemDeleted);
+      return false;
+    }
+  //MESSAGE("-----------------> RemoveElement "<< ME->GetID() << " " << isElemDeleted);
+  if (!IsComplexSubmesh())
+    {
+      if ( ME->getshapeId() != myIndex )
+        return false;
+      int idInSubShape = ME->getIdInShape();
+      //MESSAGE("in "<< myIndex << " RemoveElement " << ME->GetID() << " " << idInSubShape << " " << myUnusedIdElements);
+      SMDS_MeshElement* elem = (SMDS_MeshElement*) (ME);
+      elem->setShapeId(0);
+      elem->setIdInShape(-1);
+      if ((idInSubShape >= 0) && (idInSubShape < myElements.size()))
+        {
+          myElements[idInSubShape] = 0; // this vector entry is no more used
+          myUnusedIdElements++;
+          return true;
+        }
+      return false;
+      //  }
+    }
+  MESSAGE("Try to remove an element from a complex submesh ");
   return false;
 }
 
@@ -61,7 +158,22 @@ bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME)
 void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N)
 {
   if ( !IsComplexSubmesh() )
-    myNodes.insert(N);
+    {
+      int idInSubShape = N->getIdInShape();
+      int shapeId = N->getshapeId();
+      if ((shapeId > 0) && (idInSubShape >= 0))
+        {
+//           MESSAGE("========== AddNode already belonging to other subShape " << N->GetID());
+          // OK for vertex nodes
+          throw SALOME_Exception(LOCALIZED("add node in subshape already belonging to a subshape"));
+        }
+      SMDS_MeshNode* node = (SMDS_MeshNode*)(N);
+      node->setShapeId(myIndex);
+      node->setIdInShape(myNodes.size());
+      myNodes.push_back(N);
+      //MESSAGE("in "<< myIndex << " AddNode " << node->GetID());
+    }
+  //MESSAGE("try to add node in a complex submesh " << N->GetID());
 }
 
 //=======================================================================
@@ -69,11 +181,30 @@ void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N)
 //purpose  : 
 //=======================================================================
 
-bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N)
+bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N, bool isNodeDeleted)
 {
-  if ( !IsComplexSubmesh() && NbNodes() )
-    return myNodes.erase(N);
-
+  if (!IsComplexSubmesh())
+    {
+      // if (!isNodeDeleted) // alive node has valid ID and can be found
+      // {
+      if ( N->getshapeId() != myIndex )
+        return false;
+      int idInSubShape = N->getIdInShape();
+      //int shapeId = N->getshapeId();
+      //MESSAGE("in "<< myIndex << " RemoveNode " << shapeId << " " << idInSubShape << " " << N->GetID());
+      SMDS_MeshNode* node = (SMDS_MeshNode*) (N);
+      node->setShapeId(0);
+      node->setIdInShape(-1);
+      if ((idInSubShape >= 0) && (idInSubShape < myNodes.size()))
+        {
+          myNodes[idInSubShape] = 0; // this vector entry is no more used
+          myUnusedIdNodes++;
+          return true;
+        }
+      return false;
+      // }
+    }
+  MESSAGE("Try to remove a node from a complex submesh");
   return false;
 }
 
@@ -83,15 +214,12 @@ bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N)
 //=======================================================================
 int SMESHDS_SubMesh::NbElements() const
 {
+  //MESSAGE(this << " NbElements " << IsComplexSubmesh() << " " << myElements.size() - myUnusedIdElements);
   if ( !IsComplexSubmesh() )
-    return myElements.size();
+    return myElements.size() - myUnusedIdElements;
 
   int nbElems = 0;
-#ifndef WNT
-  set<const SMESHDS_SubMesh*>::iterator it = mySubMeshes.begin();
-#else
   set<const SMESHDS_SubMesh*>::const_iterator it = mySubMeshes.begin();
-#endif
   for ( ; it != mySubMeshes.end(); it++ )
     nbElems += (*it)->NbElements();
 
@@ -105,46 +233,53 @@ int SMESHDS_SubMesh::NbElements() const
 
 int SMESHDS_SubMesh::NbNodes() const
 {
- if ( !IsComplexSubmesh() )
-   return myNodes.size(); 
+  //MESSAGE(this << " NbNodes " << IsComplexSubmesh() << " " << myNodes.size() - myUnusedIdNodes);
+  if ( !IsComplexSubmesh() )
+    return myNodes.size() - myUnusedIdNodes;
 
   int nbElems = 0;
-#ifndef WNT
-  set<const SMESHDS_SubMesh*>::iterator it = mySubMeshes.begin();
-#else
   set<const SMESHDS_SubMesh*>::const_iterator it = mySubMeshes.begin();
-#endif
   for ( ; it != mySubMeshes.end(); it++ )
     nbElems += (*it)->NbNodes();
 
   return nbElems;
 }
 
-// =====================
-// class MySetIterator
-// =====================
-
-template<typename T> class MySetIterator:public SMDS_Iterator<const T*>
+/*!
+ * template class used for iteration on submesh elements. Interface of iterator remains
+ * unchanged after redesign of SMDS to avoid modification everywhere in SMESH.
+ * instances are stored in shared_ptr for automatic destruction.
+ * Container is copied for iteration, because original can be modified
+ * by addition of elements, for instance, and then reallocated (vector)
+ */
+template <class ELEM, typename TSET> class MySetIterator : public SMDS_Iterator<ELEM>
 {
-  typedef const set<const T*> TSet;
-  typename TSet::const_iterator myIt;
-  TSet& mySet;
-
-  public:
-       MySetIterator(const set<const T*>& s):mySet(s), myIt(s.begin())
-       {
-       }
-
-       bool more()
-       {
-               return myIt!=mySet.end();
-       }
-       const T* next()
-       {
-               const T* t=*myIt;
-               myIt++;
-               return t;                       
-       }
+protected:
+  typename TSET::const_iterator _it, _end;
+  TSET _table;
+public:
+  MySetIterator(const TSET& table)
+  {
+    _table = table;
+    _it = _table.begin();
+    _end = _table.end();
+    while ((_it != _end) && (*_it == 0))
+      _it++;
+  }
+
+  virtual bool more()
+  {
+    while ((_it != _end) && (*_it == 0))
+      _it++;
+    return (_it != _end);
+  }
+
+  virtual ELEM next()
+  {
+    ELEM e = *_it;
+    _it++;
+    return e;
+  }
 };
 
 // =====================
@@ -155,12 +290,11 @@ template<typename VALUE> class MyIterator : public SMDS_Iterator<VALUE>
 {
  public:
   MyIterator (const set<const SMESHDS_SubMesh*>& theSubMeshes)
-    : mySubMeshes( theSubMeshes ), mySubIt( theSubMeshes.begin() ), myMore(false)
+    : mySubIt( theSubMeshes.begin() ), mySubEnd( theSubMeshes.end() ), myMore(false)
     {}
   bool more()
   {
-    while (( !myElemIt.get() || !myElemIt->more() ) &&
-           mySubIt != mySubMeshes.end())
+    while (( !myElemIt.get() || !myElemIt->more() ) && mySubIt != mySubEnd)
     {
       myElemIt = getElements(*mySubIt);
       mySubIt++;
@@ -181,8 +315,7 @@ template<typename VALUE> class MyIterator : public SMDS_Iterator<VALUE>
 
  private:
   bool                                        myMore;
-  const set<const SMESHDS_SubMesh*>&          mySubMeshes;
-  set<const SMESHDS_SubMesh*>::const_iterator mySubIt;
+  set<const SMESHDS_SubMesh*>::const_iterator mySubIt, mySubEnd;
   boost::shared_ptr< SMDS_Iterator<VALUE> >   myElemIt;
 };
 
@@ -221,8 +354,7 @@ SMDS_ElemIteratorPtr SMESHDS_SubMesh::GetElements() const
 {
   if ( IsComplexSubmesh() )
     return SMDS_ElemIteratorPtr( new MyElemIterator( mySubMeshes ));
-
-  return SMDS_ElemIteratorPtr(new MySetIterator<SMDS_MeshElement>(myElements));
+  return SMDS_ElemIteratorPtr(new MySetIterator<const SMDS_MeshElement*, std::vector<const SMDS_MeshElement*> >(myElements));
 }
 
 //=======================================================================
@@ -235,7 +367,7 @@ SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes() const
   if ( IsComplexSubmesh() )
     return SMDS_NodeIteratorPtr( new MyNodeIterator( mySubMeshes ));
 
-  return SMDS_NodeIteratorPtr(new MySetIterator<SMDS_MeshNode>(myNodes));
+  return SMDS_NodeIteratorPtr(new MySetIterator<const SMDS_MeshNode*, std::vector<const SMDS_MeshNode*> >(myNodes));
 }
 
 //=======================================================================
@@ -246,25 +378,34 @@ SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes() const
 bool SMESHDS_SubMesh::Contains(const SMDS_MeshElement * ME) const
 {
   // DO NOT TRY TO FIND A REMOVED ELEMENT !!
-  if ( !ME )
-    return false;
-
-  if ( IsComplexSubmesh() )
-  {
-    set<const SMESHDS_SubMesh*>::const_iterator aSubIt = mySubMeshes.begin();
-    for ( ; aSubIt != mySubMeshes.end(); aSubIt++ )
-      if ( (*aSubIt)->Contains( ME ))
-        return true;
+  //if ( IsComplexSubmesh() || !ME )
+  if (!ME)
     return false;
-  }
 
-  if ( ME->GetType() == SMDSAbs_Node )
-  {
-    const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( ME );
-    return ( myNodes.find( n ) != myNodes.end() );
-  }
+  if (IsComplexSubmesh())
+    {
+      set<const SMESHDS_SubMesh*>::const_iterator aSubIt = mySubMeshes.begin();
+      for (; aSubIt != mySubMeshes.end(); aSubIt++)
+        if ((*aSubIt)->Contains(ME))
+          return true;
+      return false;
+    }
 
-  return ( myElements.find( ME ) != myElements.end() );
+  if (ME->GetType() == SMDSAbs_Node)
+    {
+      int idInShape = ME->getIdInShape();
+      if ((idInShape >= 0) && (idInShape < myNodes.size()))
+        if (myNodes[idInShape] == ME)
+          return true;
+    }
+  else
+    {
+      int idInShape = ME->getIdInShape();
+      if ((idInShape >= 0) && (idInShape < myElements.size()))
+        if (myElements[idInShape] == ME)
+          return true;
+    }
+  return false;
 }
 
 //=======================================================================
@@ -288,6 +429,16 @@ bool SMESHDS_SubMesh::RemoveSubMesh( const SMESHDS_SubMesh* theSubMesh )
   return mySubMeshes.erase( theSubMesh );
 }
 
+//=======================================================================
+//function : RemoveAllSubmeshes
+//purpose  : 
+//=======================================================================
+
+void SMESHDS_SubMesh::RemoveAllSubmeshes()
+{
+  mySubMeshes.clear();
+}
+
 //=======================================================================
 //function : ContainsSubMesh
 //purpose  : 
@@ -320,9 +471,66 @@ void SMESHDS_SubMesh::Clear()
 {
   myElements.clear();
   myNodes.clear();
+  myUnusedIdNodes = 0;
+  myUnusedIdElements = 0;
   SMESHDS_SubMeshIteratorPtr sub = GetSubMeshIterator();
   while ( sub->more() ) {
     if ( SMESHDS_SubMesh* sm = (SMESHDS_SubMesh*) sub->next())
       sm->Clear();
   }
 }
+
+int SMESHDS_SubMesh::getSize()
+{
+  int c = NbNodes();
+  int d = NbElements();
+  //cerr << "SMESHDS_SubMesh::NbNodes " << c << endl;
+  //cerr << "SMESHDS_SubMesh::NbElements " << d << endl;
+  return c+d;
+}
+
+void SMESHDS_SubMesh::compactList()
+{
+  //MESSAGE("compactList old: nodes " << myNodes.size() << " elements " << myElements.size());
+  //stringstream a;
+  //stringstream b;
+  //stringstream c;
+  //stringstream d;
+
+  std::vector<const SMDS_MeshElement*> newElems;
+  newElems.clear();
+  for (int i = 0; i < myElements.size(); i++)
+    if (myElements[i])
+      {
+        SMDS_MeshElement* elem = (SMDS_MeshElement*)myElements[i];
+        elem->setIdInShape(newElems.size());
+        newElems.push_back(elem);
+        //a << elem->GetID() << " ";
+        //b << elem->GetID() << " ";
+      }
+    //else
+    //  a << "_ ";
+  myElements.swap(newElems);
+  myUnusedIdElements = 0;
+  //MESSAGE("in " << myIndex << " oldElems " << a.str());
+  //MESSAGE("in " << myIndex << " newElems " << b.str());
+
+  std::vector<const SMDS_MeshNode*> newNodes;
+  newNodes.clear();
+  for (int i = 0; i < myNodes.size(); i++)
+    if (myNodes[i])
+      {
+        SMDS_MeshNode* node = (SMDS_MeshNode*)myNodes[i];
+        node->setIdInShape(newNodes.size());
+        newNodes.push_back(node);
+        //c << node->GetID() << " ";
+        //d << node->GetID() << " ";
+      }
+    //else
+    //  c << "_ ";
+  myNodes.swap(newNodes);
+  myUnusedIdNodes = 0;
+  //MESSAGE("in " << myIndex << " oldNodes " << c.str());
+  //MESSAGE("in " << myIndex << " newNodes " << d.str());
+  //MESSAGE("compactList new: nodes " << myNodes.size() << " elements " << myElements.size());
+}
index 7b2eaa4169ada04d6018cbd49e6cd976d36bbbde..049c73e33b19e0cd4e4482fcff7d1f713b400770 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESHDS : management of mesh data and SMESH document
 //  File   : SMESHDS_SubMesh.hxx
 //  Module : SMESH
 
 #include "SMDS_Mesh.hxx"
 #include <set>
+#include <vector>
 
 class SMESHDS_SubMesh;
 typedef SMDS_Iterator<const SMESHDS_SubMesh*> SMESHDS_SubMeshIterator;
 typedef boost::shared_ptr< SMESHDS_SubMeshIterator > SMESHDS_SubMeshIteratorPtr;
 
+class SMESHDS_Mesh;
+
 class SMESHDS_EXPORT SMESHDS_SubMesh
 {
  public:
+  SMESHDS_SubMesh(SMESHDS_Mesh *parent, int index);
+  virtual ~SMESHDS_SubMesh();
 
-  bool IsComplexSubmesh() const { return !mySubMeshes.empty(); }
+  virtual bool IsComplexSubmesh() const { return !mySubMeshes.empty(); }
 
   // if !IsComplexSubmesh()
-  void AddElement(const SMDS_MeshElement * ME);
-  bool RemoveElement(const SMDS_MeshElement * ME); // ret true if ME was in
-  void AddNode(const SMDS_MeshNode * ME);
-  bool RemoveNode(const SMDS_MeshNode * ME);       // ret true if ME was in
+  virtual void AddElement(const SMDS_MeshElement * ME);
+  virtual bool RemoveElement(const SMDS_MeshElement * ME, bool isElemDeleted); // ret true if ME was in
+  virtual void AddNode(const SMDS_MeshNode * ME);
+  virtual bool RemoveNode(const SMDS_MeshNode * ME, bool isNodeDeleted);       // ret true if ME was in
 
   // if IsComplexSubmesh()
   void AddSubMesh( const SMESHDS_SubMesh* theSubMesh );
   bool RemoveSubMesh( const SMESHDS_SubMesh* theSubMesh );
+  void RemoveAllSubmeshes();
   bool ContainsSubMesh( const SMESHDS_SubMesh* theSubMesh ) const;
   int  NbSubMeshes() const { return mySubMeshes.size(); }
   SMESHDS_SubMeshIteratorPtr GetSubMeshIterator() const;
 
   // for both types
-  int NbElements() const;
-  SMDS_ElemIteratorPtr GetElements() const;
-  int NbNodes() const;
-  SMDS_NodeIteratorPtr GetNodes() const;
-  bool Contains(const SMDS_MeshElement * ME) const;      // check if elem or node is in
+  virtual int NbElements() const;
+  virtual SMDS_ElemIteratorPtr GetElements() const;
+  virtual int NbNodes() const;
+  virtual SMDS_NodeIteratorPtr GetNodes() const;
+  virtual bool Contains(const SMDS_MeshElement * ME) const;      // check if elem or node is in
 
   // clear the contents
-  void Clear();
+  virtual void Clear();
+  int getSize();
+  void compactList();
+
+  inline SMESHDS_Mesh *getParent() {return myParent; };
 
  private:
-  //const SMDS_Mesh * myMesh;
-  std::set<const SMDS_MeshElement*> myElements;
-  std::set<const SMDS_MeshNode*>    myNodes;
-  std::set<const SMESHDS_SubMesh*>  mySubMeshes;
+  SMESHDS_Mesh * myParent;
+  std::vector<const SMDS_MeshElement*> myElements;
+  std::vector<const SMDS_MeshNode*> myNodes;
+
+  int myUnusedIdNodes;
+  int myUnusedIdElements;
+  int myIndex;
+
+  std::set<const SMESHDS_SubMesh*> mySubMeshes;
 };
 #endif
diff --git a/src/SMESHDS/SMESH_Controls.hxx b/src/SMESHDS/SMESH_Controls.hxx
new file mode 100644 (file)
index 0000000..49d6ab1
--- /dev/null
@@ -0,0 +1,79 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+#ifndef _SMESH_CONTROLS_HXX_
+#define _SMESH_CONTROLS_HXX_
+
+#include "SMDSAbs_ElementType.hxx"
+
+#include <boost/shared_ptr.hpp>
+
+#ifdef WNT
+ #if defined SMESHCONTROLS_EXPORTS || defined SMESHControls_EXPORTS
+  #define SMESHCONTROLS_EXPORT __declspec( dllexport )
+ #else
+  #define SMESHCONTROLS_EXPORT __declspec( dllimport )
+ #endif
+#else
+ #define SMESHCONTROLS_EXPORT
+#endif
+
+class SMDS_Mesh;
+
+namespace SMESH{
+  namespace Controls{
+
+    /*
+      Class       : Functor
+      Description : Root of all Functors
+    */
+    class SMESHCONTROLS_EXPORT Functor
+    {
+    public:
+      ~Functor(){}
+      virtual void SetMesh( const SMDS_Mesh* theMesh ) = 0;
+      virtual SMDSAbs_ElementType GetType() const = 0;
+    };
+    typedef boost::shared_ptr<Functor> FunctorPtr;
+
+
+    class NumericalFunctor;
+    typedef boost::shared_ptr<NumericalFunctor> NumericalFunctorPtr;
+  
+    /*
+      Class       : Predicate
+      Description : Base class for all predicates
+    */
+    class SMESHCONTROLS_EXPORT Predicate: public virtual Functor{
+    public:
+      virtual bool IsSatisfy( long theElementId ) = 0;
+      virtual SMDSAbs_ElementType GetType() const = 0;
+    };
+    typedef boost::shared_ptr<Predicate> PredicatePtr;
+
+  }
+}
+
+typedef SMESH::Controls::PredicatePtr SMESH_PredicatePtr;
+
+
+#endif
index 4e45bbfaaf4241b244d928cbc82a710e0f7b5ab5..cc22f1f6de8ded573265387b8d04b202c5043500 100755 (executable)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  File   : SMESH_SMESHDS.hxx
 //  Author : Alexander A. BORODIN
 //  Module : SMESH
index 183083cc7e644211a0fa3421ee72041c46e04106..6b15a26b37eae7c5854fdab4edb9fd82943eee0b 100644 (file)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  SMESH SMESHFiltersSelection : filter selector for viewer
 #  File   : Makefile.in
 #  Author : Patrick GOLDBRONN (CEA)
@@ -57,12 +55,12 @@ libSMESHFiltersSelection_la_CPPFLAGS = \
        $(BOOST_CPPFLAGS) \
        $(CORBA_CXXFLAGS) \
        $(CORBA_INCLUDES) \
-       -I$(top_builddir)/idl \
-       -I$(top_builddir)/salome_adm/unix
+       -I$(top_builddir)/idl
 
 libSMESHFiltersSelection_la_LDFLAGS  = \
        ../../idl/libSalomeIDLSMESH.la \
        $(KERNEL_LDFLAGS) -lSalomeDSClient -lSalomeDS \
-       $(GUI_LDFLAGS) -lSalomeApp -lsuit \
-       $(GEOM_LDFLAGS) -lGEOM \
-       $(CAS_LDPATH) -lTKernel
+       $(GUI_LDFLAGS) -lSalomeApp -lsuit -lLightApp \
+       $(GEOM_LDFLAGS) -lGEOM -lGEOMClient \
+       $(CAS_LDPATH) -lTKernel -lTKMath -lTKBRep \
+       $(QT_MT_LIBS)
index f8f908f833ba3afd7130ba3b16d86e617b414455..bcfa96bcb4eafaf28a1655b2371a7e416a63039e 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  File   : SMESH_LogicalFilter.cxx
 //  Module : SMESH
 //
@@ -29,7 +30,9 @@
 // Purpose : Constructor
 //=======================================================================
 SMESH_LogicalFilter::SMESH_LogicalFilter (const QList<SUIT_SelectionFilter*>& theFilters,
-                                          const int                           theLogOp)
+                                          const int                           theLogOp,
+                                          bool                                takeOwnership)
+  : myOwnership( takeOwnership )
 {
   setFilters(theFilters);
   setOperation(theLogOp);
@@ -41,6 +44,7 @@ SMESH_LogicalFilter::SMESH_LogicalFilter (const QList<SUIT_SelectionFilter*>& th
 //=======================================================================
 SMESH_LogicalFilter::~SMESH_LogicalFilter()
 {
+  deleteFilters();
 }
 
 //=======================================================================
@@ -69,6 +73,7 @@ bool SMESH_LogicalFilter::isOk (const SUIT_DataOwner* owner) const
 //=======================================================================
 void SMESH_LogicalFilter::setFilters (const QList<SUIT_SelectionFilter*>& theFilters)
 {
+  deleteFilters();
   myFilters = theFilters;
 }
 
@@ -98,3 +103,18 @@ int SMESH_LogicalFilter::getOperation() const
 {
   return myOperation;
 }
+//================================================================================
+/*!
+ * \brief Deletes filters if has an ownership
+ */
+//================================================================================
+
+void SMESH_LogicalFilter::deleteFilters()
+{
+  if ( myOwnership )
+  {
+    SUIT_SelectionFilter* filter;
+    foreach( filter, myFilters )
+      delete filter;
+  }
+}
index 928313f80507414d1fbbb8f94259f8232470adf1..3069fa89025284ecaf45c08d100dd9ae129a4139 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  File   : SMESH_LogicalFilter.hxx
 //  Module : SMESH
 //
@@ -37,7 +38,7 @@ class SMESHFILTERSSELECTION_EXPORT SMESH_LogicalFilter : public SUIT_SelectionFi
   enum { LO_OR, LO_AND, LO_NOT, LO_UNDEFINED };
 
  public:
-  SMESH_LogicalFilter( const QList<SUIT_SelectionFilter*>&, const int );
+  SMESH_LogicalFilter( const QList<SUIT_SelectionFilter*>&, const int, bool takeOwnership=false );
   virtual ~SMESH_LogicalFilter();
 
   virtual bool isOk (const SUIT_DataOwner*) const;
@@ -47,9 +48,13 @@ class SMESHFILTERSSELECTION_EXPORT SMESH_LogicalFilter : public SUIT_SelectionFi
   const QList<SUIT_SelectionFilter*>   getFilters() const;
   int                                  getOperation() const;
 
+private:
+  void                          deleteFilters();
+
 private:
   QList<SUIT_SelectionFilter*>  myFilters;
   int                           myOperation;
+  bool                          myOwnership;
 };
 
 #endif
index d8633f307516d25b168d1dfa282d3ca0a6490def..5699e263c90cae0fa0409de8634a48c90cba9fa4 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  File   : SMESH_NumberFilter.cxx
 //  Module : SMESH
 //
index 45724cfa1a9b12de0bac9964e4624fde0f085832..6400d9b3631f3fc7f6d9bf254f80121d514202c0 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  File   : SMESH_NumberFilter.hxx
 //  Module : SMESH
 //
index 106110e09a983e86d6faf718c207edb862b5ede9..e29c918a07dced71801bf5fa6631161bfda1e1d6 100644 (file)
@@ -1,36 +1,36 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  File      : SMESH_Type.h
 //  Created   : Mon Jun 03 15:14:15 2002
 //  Author    : Nicolas REJNERI
 //  Project   : SALOME
 //  Module    : SMESH
-//  $Header$
 //
 #ifndef SMESH_TYPE_HEADER
 #define SMESH_TYPE_HEADER
 
 #ifdef WNT
- #if defined SMESHFILTERSSELECTION_EXPORTS
+ #if defined SMESHFILTERSSELECTION_EXPORTS || defined SMESHFiltersSelection_EXPORTS
   #define SMESHFILTERSSELECTION_EXPORT __declspec( dllexport )
  #else
   #define SMESHFILTERSSELECTION_EXPORT __declspec( dllimport )
@@ -51,7 +51,14 @@ enum MeshObjectType {
   SUBMESH_SOLID,
   SUBMESH_COMPOUND,
   GROUP,
-  COMPONENT
+  GROUP_NODE,
+  GROUP_EDGE,
+  GROUP_FACE,
+  GROUP_VOLUME,
+  GROUP_0D,
+  GROUP_BALL,
+  COMPONENT,
+  IDSOURCE
 };
 
 #endif
index 509b872405e0a524c92836266e5887a9cb212ffc..e9b83166c25add1125c1dc2b2298a27f95208d5d 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #include "SMESH_TypeFilter.hxx"
 
 #include <SUIT_Session.h>
@@ -80,6 +81,7 @@ bool SMESH_TypeFilter::isOk (const SUIT_DataOwner* theDataOwner) const
     // 4       |     |- Applied algorithms ( selectable in Use Case Browser )
     // 5       |          |- Regular 1D
     //         |- Group Of Nodes
+    //            |- Group 1
 
     if (aLevel <= 0)
       return false;
@@ -87,90 +89,132 @@ bool SMESH_TypeFilter::isOk (const SUIT_DataOwner* theDataOwner) const
     switch (myType)
     {
       case HYPOTHESIS:
-       {
-         if      (aLevel == 2 && (objFather->Tag() == SMESH::Tag_HypothesisRoot))
+        {
+          if      (aLevel == 2 && (objFather->Tag() == SMESH::Tag_HypothesisRoot))
             // hypo definition
-           Ok = true;
-         else if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_RefOnAppliedHypothesis))
+            Ok = true;
+          else if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_RefOnAppliedHypothesis))
             // applied global hypo
-           Ok = true;
-         else if (aLevel == 5 && (objFather->Tag() == SMESH::Tag_RefOnAppliedHypothesis))
+            Ok = true;
+          else if (aLevel == 5 && (objFather->Tag() == SMESH::Tag_RefOnAppliedHypothesis))
             // applied local hypo
-           Ok = true;
-         break;
-       }
+            Ok = true;
+          break;
+        }
       case ALGORITHM:
-       {
-         if      (aLevel == 2 && (objFather->Tag() == SMESH::Tag_AlgorithmsRoot))
+        {
+          if      (aLevel == 2 && (objFather->Tag() == SMESH::Tag_AlgorithmsRoot))
             // algo definition
-           Ok = true;
-         else if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_RefOnAppliedAlgorithms))
+            Ok = true;
+          else if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_RefOnAppliedAlgorithms))
             // applied global algo
-           Ok = true;
-         else if (aLevel == 5 && (objFather->Tag() == SMESH::Tag_RefOnAppliedAlgorithms))
+            Ok = true;
+          else if (aLevel == 5 && (objFather->Tag() == SMESH::Tag_RefOnAppliedAlgorithms))
             // applied local algo
-           Ok = true;
-         break;
-       }
+            Ok = true;
+          break;
+        }
       case MESH:
-       {
-         if (aLevel == 1 && (obj->Tag() >= SMESH::Tag_FirstMeshRoot))
-           Ok = true;
-         break;
-       }
+        {
+          if (aLevel == 1 && (obj->Tag() >= SMESH::Tag_FirstMeshRoot))
+            Ok = true;
+          break;
+        }
       case SUBMESH:
-       {
-         // see SMESH_Gen_i.cxx for tag numbers
-         if (aLevel == 3 && (objFather->Tag() >= SMESH::Tag_FirstSubMesh &&
+        {
+          // see SMESH_Gen_i.cxx for tag numbers
+          if (aLevel == 3 && (objFather->Tag() >= SMESH::Tag_FirstSubMesh &&
                               objFather->Tag() <= SMESH::Tag_LastSubMesh))
-           Ok = true;
-         break;
-       }
+            Ok = true;
+          break;
+        }
       case MESHorSUBMESH:
-       {
-         if (aLevel == 1 && (obj->Tag() >= SMESH::Tag_FirstMeshRoot))
-           Ok = true; // mesh
+        {
+          if (aLevel == 1 && (obj->Tag() >= SMESH::Tag_FirstMeshRoot))
+            Ok = true; // mesh
           else if (aLevel == 3 && (objFather->Tag() >= SMESH::Tag_FirstSubMesh &&
                                    objFather->Tag() <= SMESH::Tag_LastSubMesh))
-           Ok = true;
-         break;
-       }
+            Ok = true;
+          break;
+        }
       case SUBMESH_VERTEX: // Label "SubMeshes on vertexes"
-       {
-         if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_SubMeshOnVertex))
-           Ok = true;
-         break;
-       }
+        {
+          if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_SubMeshOnVertex))
+            Ok = true;
+          break;
+        }
       case SUBMESH_EDGE:
-       {
-         if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_SubMeshOnEdge))
-           Ok = true;
-         break;
-       }
+        {
+          if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_SubMeshOnEdge))
+            Ok = true;
+          break;
+        }
       case SUBMESH_FACE:
-       {
-         if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_SubMeshOnFace))
-           Ok = true;
-         break;
-       }
+        {
+          if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_SubMeshOnFace))
+            Ok = true;
+          break;
+        }
       case SUBMESH_SOLID:
-       {
-         if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_SubMeshOnSolid))
-           Ok = true;
-         break;
-       }
+        {
+          if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_SubMeshOnSolid))
+            Ok = true;
+          break;
+        }
       case SUBMESH_COMPOUND:
-       {
-         if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_SubMeshOnCompound))
-           Ok = true;
-         break;
-       }
+        {
+          if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_SubMeshOnCompound))
+            Ok = true;
+          break;
+        }
       case GROUP:
-       {
-         if (aLevel == 3 && (objFather->Tag() >= SMESH::Tag_FirstGroup))
-           Ok = true;
-         break;
-       }
+        {
+          if (aLevel == 3 && (objFather->Tag() >= SMESH::Tag_FirstGroup))
+            Ok = true;
+          break;
+        }
+      case GROUP_NODE:
+        {
+          if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_NodeGroups))
+            Ok = true;
+          break;
+        }
+      case GROUP_EDGE:
+        {
+          if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_EdgeGroups))
+            Ok = true;
+          break;
+        }
+      case GROUP_FACE:
+        {
+          if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_FaceGroups))
+            Ok = true;
+          break;
+        }
+      case GROUP_VOLUME:
+        {
+          if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_VolumeGroups))
+            Ok = true;
+          break;
+        }
+      case GROUP_0D:
+        {
+          if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_0DElementsGroups))
+            Ok = true;
+          break;
+        }
+      case GROUP_BALL:
+        {
+          if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_BallElementsGroups))
+            Ok = true;
+          break;
+        }
+      case IDSOURCE:
+        {
+          Ok = ( SMESH_TypeFilter(MESHorSUBMESH).isOk( theDataOwner ) ||
+                 SMESH_TypeFilter(GROUP)        .isOk( theDataOwner ));
+          break;
+        }
     }
   }
   return Ok;
index d966bfaa59a369483809f00278c320f50873415a..0821917d03a2404d97adb84b99d23f192ea65b46 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  File   : SMESH_TypeFilter.hxx
 //  Module : SMESH
 //
index db288673a8023989a9e19e1f35b078d20749f0b5..15925385f603cb7ab08057838533111ce11b600e 100644 (file)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # SMESH SMESHGUI : GUI for SMESH component
 # File   : Makefile.am
 # Author : Alexander BORODIN, Open CASCADE S.A.S.
@@ -49,12 +47,10 @@ salomeinclude_HEADERS = \
        SMESHGUI_GroupDlg.h \
        SMESHGUI_RemoveNodesDlg.h \
        SMESHGUI_RemoveElementsDlg.h \
-       SMESHGUI_MeshInfosDlg.h \
-       SMESHGUI_StandardMeshInfosDlg.h \
-       SMESHGUI_WhatIsDlg.h \
+       SMESHGUI_MeshInfo.h \
+       SMESHGUI_Measurements.h \
        SMESHGUI_Preferences_ColorDlg.h \
        SMESHGUI_Preferences_ScalarBarDlg.h \
-       SMESHGUI_MoveNodesDlg.h \
        SMESHGUI_AddMeshElementDlg.h \
        SMESHGUI_XmlHandler.h \
        SMESHGUI_Filter.h \
@@ -71,9 +67,11 @@ salomeinclude_HEADERS = \
        SMESHGUI_RevolutionDlg.h \
        SMESHGUI_RotationDlg.h \
        SMESHGUI_TranslationDlg.h \
+       SMESHGUI_ScaleDlg.h \
        SMESHGUI_SymmetryDlg.h \
        SMESHGUI_SewingDlg.h \
-       SMESHGUI_EditMeshDlg.h \
+       SMESHGUI_DuplicateNodesDlg.h \
+       SMESHGUI_MergeDlg.h \
        SMESHGUI_MeshUtils.h \
        SMESHGUI_CreatePolyhedralVolumeDlg.h \
        SMESHGUI_Operation.h \
@@ -90,6 +88,15 @@ salomeinclude_HEADERS = \
        SMESHGUI_MakeNodeAtPointDlg.h \
        SMESHGUI_MeshEditPreview.h \
        SMESHGUI_IdValidator.h \
+       SMESHGUI_MeshInfosBox.h \
+       SMESHGUI_Make2DFrom3DOp.h \
+       SMESHGUI_FindElemByPointDlg.h \
+       SMESHGUI_MeshOrderDlg.h \
+       SMESHGUI_MeshOrderOp.h \
+       SMESHGUI_FileValidator.h \
+       SMESHGUI_CopyMeshDlg.h \
+       SMESHGUI_PreviewDlg.h  \
+       SMESHGUI_ReorientFacesDlg.h \
        SMESH_SMESHGUI.hxx
 
 # Libraries targets
@@ -106,12 +113,10 @@ dist_libSMESH_la_SOURCES = \
        SMESHGUI_GroupDlg.cxx \
        SMESHGUI_RemoveNodesDlg.cxx \
        SMESHGUI_RemoveElementsDlg.cxx \
-       SMESHGUI_MeshInfosDlg.cxx \
-       SMESHGUI_StandardMeshInfosDlg.cxx \
-       SMESHGUI_WhatIsDlg.cxx \
+       SMESHGUI_MeshInfo.cxx \
+       SMESHGUI_Measurements.cxx \
        SMESHGUI_Preferences_ColorDlg.cxx \
        SMESHGUI_Preferences_ScalarBarDlg.cxx \
-       SMESHGUI_MoveNodesDlg.cxx \
        SMESHGUI_AddMeshElementDlg.cxx \
        SMESHGUI_XmlHandler.cxx \
        SMESHGUI_Filter.cxx \
@@ -128,9 +133,11 @@ dist_libSMESH_la_SOURCES = \
        SMESHGUI_RevolutionDlg.cxx \
        SMESHGUI_RotationDlg.cxx \
        SMESHGUI_TranslationDlg.cxx \
+       SMESHGUI_ScaleDlg.cxx \
        SMESHGUI_SymmetryDlg.cxx \
        SMESHGUI_SewingDlg.cxx \
-       SMESHGUI_EditMeshDlg.cxx \
+       SMESHGUI_DuplicateNodesDlg.cxx \
+       SMESHGUI_MergeDlg.cxx \
        SMESHGUI_Utils.cxx \
        SMESHGUI_GEOMGenUtils.cxx \
        SMESHGUI_MeshUtils.cxx \
@@ -157,7 +164,16 @@ dist_libSMESH_la_SOURCES = \
        SMESHGUI_MakeNodeAtPointDlg.cxx \
        SMESHGUI_MeshEditPreview.cxx \
        SMESHGUI_GroupOnShapeDlg.cxx \
-       SMESHGUI_FileInfoDlg.cxx
+       SMESHGUI_FileInfoDlg.cxx \
+       SMESHGUI_MeshInfosBox.cxx \
+       SMESHGUI_Make2DFrom3DOp.cxx \
+       SMESHGUI_FindElemByPointDlg.cxx \
+       SMESHGUI_MeshOrderDlg.cxx \
+       SMESHGUI_MeshOrderOp.cxx \
+       SMESHGUI_CopyMeshDlg.cxx \
+       SMESHGUI_FileValidator.cxx \
+       SMESHGUI_PreviewDlg.cxx  \
+       SMESHGUI_ReorientFacesDlg.cxx
 
 MOC_FILES = \
        SMESHGUI_moc.cxx \
@@ -171,12 +187,10 @@ MOC_FILES = \
        SMESHGUI_GroupDlg_moc.cxx \
        SMESHGUI_RemoveNodesDlg_moc.cxx \
        SMESHGUI_RemoveElementsDlg_moc.cxx \
-       SMESHGUI_MeshInfosDlg_moc.cxx \
-       SMESHGUI_StandardMeshInfosDlg_moc.cxx \
-       SMESHGUI_WhatIsDlg_moc.cxx \
+       SMESHGUI_MeshInfo_moc.cxx \
+       SMESHGUI_Measurements_moc.cxx \
        SMESHGUI_Preferences_ColorDlg_moc.cxx \
        SMESHGUI_Preferences_ScalarBarDlg_moc.cxx \
-       SMESHGUI_MoveNodesDlg_moc.cxx \
        SMESHGUI_AddMeshElementDlg_moc.cxx \
        SMESHGUI_FilterDlg_moc.cxx \
        SMESHGUI_FilterLibraryDlg_moc.cxx \
@@ -191,9 +205,11 @@ MOC_FILES = \
        SMESHGUI_RevolutionDlg_moc.cxx \
        SMESHGUI_RotationDlg_moc.cxx \
        SMESHGUI_TranslationDlg_moc.cxx \
+       SMESHGUI_ScaleDlg_moc.cxx \
        SMESHGUI_SymmetryDlg_moc.cxx \
        SMESHGUI_SewingDlg_moc.cxx \
-       SMESHGUI_EditMeshDlg_moc.cxx \
+       SMESHGUI_DuplicateNodesDlg_moc.cxx \
+       SMESHGUI_MergeDlg_moc.cxx \
        SMESHGUI_CreatePolyhedralVolumeDlg_moc.cxx \
        SMESHGUI_Operation_moc.cxx \
        SMESHGUI_SelectionOp_moc.cxx \
@@ -209,7 +225,15 @@ MOC_FILES = \
        SMESHGUI_ComputeDlg_moc.cxx \
        SMESHGUI_MakeNodeAtPointDlg_moc.cxx \
        SMESHGUI_GroupOnShapeDlg_moc.cxx \
-       SMESHGUI_FileInfoDlg_moc.cxx
+       SMESHGUI_FileInfoDlg_moc.cxx \
+       SMESHGUI_MeshInfosBox_moc.cxx \
+       SMESHGUI_Make2DFrom3DOp_moc.cxx \
+       SMESHGUI_FindElemByPointDlg_moc.cxx \
+       SMESHGUI_MeshOrderDlg_moc.cxx \
+       SMESHGUI_CopyMeshDlg_moc.cxx \
+       SMESHGUI_MeshOrderOp_moc.cxx \
+       SMESHGUI_PreviewDlg_moc.cxx \
+       SMESHGUI_ReorientFacesDlg_moc.cxx
 
 nodist_libSMESH_la_SOURCES= \
        $(MOC_FILES)
@@ -223,33 +247,38 @@ libSMESH_la_CPPFLAGS = \
        $(PYTHON_INCLUDES) \
        $(KERNEL_CXXFLAGS)  \
        $(GUI_CXXFLAGS) \
+       $(QWT_INCLUDES) \
        $(GEOM_CXXFLAGS) \
        $(MED_CXXFLAGS) \
        $(BOOST_CPPFLAGS) \
        $(CORBA_CXXFLAGS) \
        $(CORBA_INCLUDES) \
-       $(MED2_INCLUDES) \
+       $(MED3_INCLUDES) \
        $(HDF5_INCLUDES) \
        -I$(srcdir)/../OBJECT \
        -I$(srcdir)/../SMESHFiltersSelection \
        -I$(srcdir)/../SMDS \
+       -I$(srcdir)/../SMESHDS \
        -I$(srcdir)/../SMESH \
+       -I$(srcdir)/../SMESHUtils \
        -I$(srcdir)/../SMESH_I \
        -I$(srcdir)/../Controls \
        -I$(srcdir)/../SMESHClient \
-       -I$(top_builddir)/idl \
-       -I$(top_builddir)/salome_adm/unix
-
+       -I$(top_builddir) \
+       -I$(top_builddir)/idl
 
 libSMESH_la_LDFLAGS  = \
        ../SMESHFiltersSelection/libSMESHFiltersSelection.la \
        ../SMDS/libSMDS.la \
        ../Controls/libSMESHControls.la \
        ../OBJECT/libSMESHObject.la \
-       $(GEOM_LDFLAGS) \
-       -lGEOMBase
+       $(CAS_LDFLAGS) -lTKV3d \
+       $(GUI_LDFLAGS) -lSalomePrs -lsuit -lSUITApp -lCAM -lstd \
+       $(GEOM_LDFLAGS) -lGEOMBase -lGEOMFiltersSelection -lGEOMObject \
+       $(PYTHON_LIBS)
 
 # resources files
 nodist_salomeres_DATA= \
        SMESH_images.qm \
-       SMESH_msg_en.qm
+       SMESH_msg_en.qm \
+       SMESH_msg_fr.qm
index 50f44fb18b8fc5def2e34667645a29a6df991ce4..52f3180adab914968c21c6acefd7b3f7ff9e247f 100644 (file)
@@ -1,72 +1,82 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
-//
-// SMESH SMESHGUI : GUI for SMESH component
-// File   : SMESHGUI.cxx
-// Author : Nicolas REJNERI, Open CASCADE S.A.S.
-// SMESH includes
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+//  File   : SMESHGUI.cxx
+//  Author : Nicolas REJNERI, Open CASCADE S.A.S.
+
+#include <Standard_math.hxx>  // E.A. must be included before Python.h to fix compilation on windows
+#ifdef HAVE_FINITE
+#undef HAVE_FINITE            // VSR: avoid compilation warning on Linux : "HAVE_FINITE" redefined
+#endif
+#include "Python.h"
+//  SMESH includes
 #include "SMESHGUI.h"
-#include "SMESHGUI_NodesDlg.h"
-#include "SMESHGUI_TransparencyDlg.h"
-#include "SMESHGUI_ClippingDlg.h"
-#include "SMESHGUI_GroupDlg.h"
-#include "SMESHGUI_RemoveNodesDlg.h"
-#include "SMESHGUI_RemoveElementsDlg.h"
-#include "SMESHGUI_MeshInfosDlg.h"
-#include "SMESHGUI_StandardMeshInfosDlg.h"
-#include "SMESHGUI_WhatIsDlg.h"
-#include "SMESHGUI_Preferences_ColorDlg.h"
-#include "SMESHGUI_Preferences_ScalarBarDlg.h"
-#include "SMESHGUI_Hypotheses.h"
-#include "SMESHGUI_MoveNodesDlg.h"
 #include "SMESHGUI_AddMeshElementDlg.h"
 #include "SMESHGUI_AddQuadraticElementDlg.h"
+#include "SMESHGUI_BuildCompoundDlg.h"
+#include "SMESHGUI_ClippingDlg.h"
+#include "SMESHGUI_ComputeDlg.h"
+#include "SMESHGUI_ConvToQuadOp.h"
+#include "SMESHGUI_CreatePolyhedralVolumeDlg.h"
+#include "SMESHGUI_DeleteGroupDlg.h"
+#include "SMESHGUI_Displayer.h"
+#include "SMESHGUI_MergeDlg.h"
+#include "SMESHGUI_ExtrusionAlongPathDlg.h"
+#include "SMESHGUI_ExtrusionDlg.h"
+#include "SMESHGUI_FileInfoDlg.h"
+#include "SMESHGUI_FileValidator.h"
 #include "SMESHGUI_FilterDlg.h"
 #include "SMESHGUI_FilterLibraryDlg.h"
-#include "SMESHGUI_SingleEditDlg.h"
-#include "SMESHGUI_MultiEditDlg.h"
-#include "SMESHGUI_GroupOpDlg.h"
+#include "SMESHGUI_FindElemByPointDlg.h"
+#include "SMESHGUI_GroupDlg.h"
 #include "SMESHGUI_GroupOnShapeDlg.h"
-#include "SMESHGUI_DeleteGroupDlg.h"
-#include "SMESHGUI_SmoothingDlg.h"
+#include "SMESHGUI_GroupOpDlg.h"
+#include "SMESHGUI_Hypotheses.h"
+#include "SMESHGUI_Make2DFrom3DOp.h"
+#include "SMESHGUI_MakeNodeAtPointDlg.h"
+#include "SMESHGUI_Measurements.h"
+#include "SMESHGUI_MeshInfo.h"
+#include "SMESHGUI_MeshOp.h"
+#include "SMESHGUI_MeshOrderOp.h"
+#include "SMESHGUI_MeshPatternDlg.h"
+#include "SMESHGUI_MultiEditDlg.h"
+#include "SMESHGUI_NodesDlg.h"
+#include "SMESHGUI_Preferences_ColorDlg.h"
+#include "SMESHGUI_Preferences_ScalarBarDlg.h"
+#include "SMESHGUI_RemoveElementsDlg.h"
+#include "SMESHGUI_RemoveNodesDlg.h"
 #include "SMESHGUI_RenumberingDlg.h"
-#include "SMESHGUI_ExtrusionDlg.h"
-#include "SMESHGUI_ExtrusionAlongPathDlg.h"
 #include "SMESHGUI_RevolutionDlg.h"
-#include "SMESHGUI_TranslationDlg.h"
 #include "SMESHGUI_RotationDlg.h"
-#include "SMESHGUI_SymmetryDlg.h"
-#include "SMESHGUI_SewingDlg.h"
-#include "SMESHGUI_EditMeshDlg.h"
-#include "SMESHGUI_MeshPatternDlg.h"
 #include "SMESHGUI_Selection.h"
-#include "SMESHGUI_CreatePolyhedralVolumeDlg.h"
-#include "SMESHGUI_ConvToQuadOp.h"
-#include "SMESHGUI_MeshOp.h"
-#include "SMESHGUI_Displayer.h"
-#include "SMESHGUI_MakeNodeAtPointDlg.h"
-#include "SMESHGUI_BuildCompoundDlg.h"
-#include "SMESHGUI_ComputeDlg.h"
-#include "SMESHGUI_FileInfoDlg.h"
+#include "SMESHGUI_SewingDlg.h"
+#include "SMESHGUI_SingleEditDlg.h"
+#include "SMESHGUI_SmoothingDlg.h"
+#include "SMESHGUI_SymmetryDlg.h"
+#include "SMESHGUI_TranslationDlg.h"
+#include "SMESHGUI_ScaleDlg.h"
+#include "SMESHGUI_TransparencyDlg.h"
+#include "SMESHGUI_DuplicateNodesDlg.h"
+#include "SMESHGUI_CopyMeshDlg.h"
+#include "SMESHGUI_ReorientFacesDlg.h"
 
 #include "SMESHGUI_Utils.h"
 #include "SMESHGUI_MeshUtils.h"
 #include "SMESHGUI_VTKUtils.h"
 #include "SMESHGUI_HypothesesUtils.h"
 
+#include <SMESH_version.h>
+
 #include <SMESH_Client.hxx>
 #include <SMESH_Actor.h>
+#include <SMESH_ScalarBarActor.h>
+#include <SMESH_ActorUtils.h>
 #include <SMESH_TypeFilter.hxx>
+#include "SMESH_ControlsDef.hxx"
 
 // SALOME GUI includes
 #include <SalomeApp_Tools.h>
 #include <SalomeApp_Study.h>
 #include <SalomeApp_Application.h>
 #include <SalomeApp_CheckFileDlg.h>
+#include <SalomeApp_DataObject.h>
 
 #include <LightApp_DataOwner.h>
 #include <LightApp_Preferences.h>
 #include <SVTK_ViewModel.h>
 #include <SVTK_ViewManager.h>
 
+#include <VTKViewer_Algorithm.h>
+
 #include <SUIT_MessageBox.h>
 #include <SUIT_ResourceMgr.h>
 #include <SUIT_FileDlg.h>
 #include <SALOME_ListIO.hxx>
 #include <SALOME_ListIteratorOfListIO.hxx>
 
+#ifndef DISABLE_PLOT2DVIEWER
+#include <SPlot2d_ViewModel.h>
+#include <SPlot2d_Histogram.h>
+#endif
+
 // IDL includes
 #include <SALOMEconfig.h>
 #include CORBA_CLIENT_HEADER(SALOMEDS_Attributes)
 #include CORBA_CLIENT_HEADER(SMESH_MeshEditor)
+#include CORBA_CLIENT_HEADER(SMESH_Measurements)
 
 // Qt includes
-// #define      INCLUDE_MENUITEM_DEF // VSR commented ????????
+// #define       INCLUDE_MENUITEM_DEF // VSR commented ????????
+#include <QApplication>
 #include <QMenu>
+#include <QTextStream>
 
 // BOOST includes
 #include <boost/shared_ptr.hpp>
 
 // VTK includes
-#include <vtkScalarBarActor.h>
 #include <vtkCamera.h>
 #include <vtkRenderer.h>
 #include <vtkPlane.h>
+#include <vtkCallbackCommand.h>
+#include <vtkLookupTable.h>
 
 // SALOME KERNEL includes
 #include <SALOMEDS_Study.hxx>
 #include <Standard_ErrorHandler.hxx>
 #include <NCollection_DataMap.hxx>
 
+//To disable automatic genericobj management, the following line should be commented.
+//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
+#define WITHGENERICOBJ
+
 //namespace{
   // Declarations
   //=============================================================
   void ImportMeshesFromFile(SMESH::SMESH_Gen_ptr theComponentMesh,
-                           int theCommandID);
+                            int theCommandID);
 
   void ExportMeshToFile(int theCommandID);
 
-  void SetDisplayMode(int theCommandID);
+  void SetDisplayMode(int theCommandID, SMESHGUI_StudyId2MarkerMap& theMarkerMap);
 
   void SetDisplayEntity(int theCommandID);
 
   // Definitions
   //=============================================================
   void ImportMeshesFromFile( SMESH::SMESH_Gen_ptr theComponentMesh,
-                            int theCommandID )
+                             int theCommandID )
   {
     QStringList filter;
     std::string myExtension;
 
     if ( theCommandID == 113 ) {
-      filter.append( QObject::tr( "MED files (*.med)" ) );
-      filter.append( QObject::tr( "All files (*)" ) );
+      filter.append( QObject::tr( "MED_FILES_FILTER" ) + " (*.med)" );
+      filter.append( QObject::tr( "ALL_FILES_FILTER" ) + " (*)" );
     }
     else if ( theCommandID == 112 ) {
-      filter.append( QObject::tr( "IDEAS files (*.unv)" ) );
+      filter.append( QObject::tr( "IDEAS_FILES_FILTER" ) + " (*.unv)" );
     }
     else if ( theCommandID == 111 ) {
-      filter.append( QObject::tr( "DAT files (*.dat)" ) );
+      filter.append( QObject::tr( "DAT_FILES_FILTER" ) + " (*.dat)" );
+    }
+    else if ( theCommandID == 115 ) {
+      filter.append( QObject::tr( "STL_ASCII_FILES_FILTER" ) + " (*.stl)" );
+    }
+    else if ( theCommandID == 116 ) {
+      filter.append( QObject::tr( "CGNS_FILES_FILTER" ) + " (*.cgns)" );
+    }
+    else if ( theCommandID == 117 ) {
+      filter.append( QObject::tr( "SAUV files (*.sauv*)" ) );
+      filter.append( QObject::tr( "All files (*)" ) );
     }
 
     QString anInitialPath = "";
       anInitialPath = QDir::currentPath();
 
     QStringList filenames = SUIT_FileDlg::getOpenFileNames( SMESHGUI::desktop(),
-                                                           anInitialPath,
-                                                           filter,
-                                                           QObject::tr( "SMESH_IMPORT_MESH" ) );
+                                                            anInitialPath,
+                                                            filter,
+                                                            QObject::tr( "SMESH_IMPORT_MESH" ) );
     if ( filenames.count() > 0 ) {
       SUIT_OverrideCursor wc;
       _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
 
       QStringList errors;
+      QStringList anEntryList;
       bool isEmpty = false;
       for ( QStringList::ConstIterator it = filenames.begin(); it != filenames.end(); ++it ) {
-       QString filename = *it;
-       SMESH::mesh_array_var aMeshes = new SMESH::mesh_array;
-       try {
-         switch ( theCommandID ) {
-         case 111:
-           {
-             // DAT format (currently unsupported)
-             errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
-                            arg( QObject::tr( "SMESH_ERR_NOT_SUPPORTED_FORMAT" ) ) );
-             break;
-           }
-         case 112:
-           {
-             // UNV format
-             aMeshes->length( 1 );
-             aMeshes[0] = theComponentMesh->CreateMeshesFromUNV( filename.toLatin1().constData() );
-             if ( aMeshes[0]->_is_nil() )
-               errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
-                              arg( QObject::tr( "SMESH_ERR_UNKNOWN_IMPORT_ERROR" ) ) );
-             break;
-           }
-         case 113:
-           {
-             // MED format
-             SMESH::DriverMED_ReadStatus res;
-             aMeshes = theComponentMesh->CreateMeshesFromMED( filename.toLatin1().constData(), res );
-             if ( res != SMESH::DRS_OK ) {
-               errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
-                              arg( QObject::tr( QString( "SMESH_DRS_%1" ).arg( res ).toLatin1().data() ) ) );
-             }
-             break;
-           }
-         }
-       }
-       catch ( const SALOME::SALOME_Exception& S_ex ) {
-         errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
-                        arg( QObject::tr( "SMESH_ERR_UNKNOWN_IMPORT_ERROR" ) ) );
-       }
-
-       for ( int i = 0, iEnd = aMeshes->length(); i < iEnd; i++ ) {
-         _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshes[i] );
-         if ( aMeshSO ) {
-           _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
-           _PTR(AttributePixMap) aPixmap = aBuilder->FindOrCreateAttribute( aMeshSO, "AttributePixMap" );
-           aPixmap->SetPixMap( "ICON_SMESH_TREE_MESH_IMPORTED" );
-           if ( theCommandID == 112 ) // mesh names aren't taken from the file for UNV import
-             SMESH::SetName( aMeshSO, QFileInfo(filename).fileName() );
-         }
-         else {
-           isEmpty = true;
-         }
-       }
+        QString filename = *it;
+        SMESH::mesh_array_var aMeshes = new SMESH::mesh_array;
+        try {
+          switch ( theCommandID ) {
+          case 111:
+            {
+              // DAT format (currently unsupported)
+              errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
+                             arg( QObject::tr( "SMESH_ERR_NOT_SUPPORTED_FORMAT" ) ) );
+              break;
+            }
+          case 112:
+            {
+              // UNV format
+              aMeshes->length( 1 );
+              aMeshes[0] = theComponentMesh->CreateMeshesFromUNV( filename.toLatin1().constData() );
+              if ( aMeshes[0]->_is_nil() )
+                errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
+                               arg( QObject::tr( "SMESH_ERR_UNKNOWN_IMPORT_ERROR" ) ) );
+              break;
+            }
+          case 113:
+            {
+              // MED format
+              SMESH::DriverMED_ReadStatus res;
+              aMeshes = theComponentMesh->CreateMeshesFromMED( filename.toLatin1().constData(), res );
+              if ( res != SMESH::DRS_OK ) {
+                errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
+                               arg( QObject::tr( QString( "SMESH_DRS_%1" ).arg( res ).toLatin1().data() ) ) );
+              }
+              break;
+            }
+          case 115:
+            {
+              // STL format
+              aMeshes->length( 1 );
+              aMeshes[0] = theComponentMesh->CreateMeshesFromSTL( filename.toLatin1().constData() );
+              if ( aMeshes[0]->_is_nil() ) {
+                errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
+                               arg( QObject::tr( "SMESH_ERR_UNKNOWN_IMPORT_ERROR" ) ) );
+              }
+              break;
+            }
+          case 116:
+            {
+              // CGNS format
+              SMESH::DriverMED_ReadStatus res;
+              aMeshes = theComponentMesh->CreateMeshesFromCGNS( filename.toLatin1().constData(), res );
+              if ( res != SMESH::DRS_OK ) {
+                errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
+                               arg( QObject::tr( QString( "SMESH_DRS_%1" ).arg( res ).toLatin1().data() ) ) );
+              }
+              break;
+            }
+          case 117:
+            {
+              // SAUV format
+              SMESH::DriverMED_ReadStatus res;
+              aMeshes = theComponentMesh->CreateMeshesFromSAUV( filename.toLatin1().constData(), res );
+              if ( res != SMESH::DRS_OK ) {
+                errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
+                               arg( QObject::tr( QString( "SMESH_DRS_%1" ).arg( res ).toLatin1().data() ) ) );
+              }
+              break;
+            }
+          }
+        }
+        catch ( const SALOME::SALOME_Exception& S_ex ) {
+          errors.append( QString( "%1 :\n\t%2" ).arg( filename ).
+                         arg( QObject::tr( "SMESH_ERR_UNKNOWN_IMPORT_ERROR" ) ) );
+        }
+
+        for ( int i = 0, iEnd = aMeshes->length(); i < iEnd; i++ ) {
+          _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshes[i] );
+          if ( aMeshSO ) {
+            _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
+            _PTR(AttributePixMap) aPixmap = aBuilder->FindOrCreateAttribute( aMeshSO, "AttributePixMap" );
+            aPixmap->SetPixMap( "ICON_SMESH_TREE_MESH_IMPORTED" );
+            if ( theCommandID == 112 ) // mesh names aren't taken from the file for UNV import
+              SMESH::SetName( aMeshSO, QFileInfo(filename).fileName() );
+
+            anEntryList.append( aMeshSO->GetID().c_str() );
+
+#ifdef WITHGENERICOBJ
+            // obj has been published in study. Its refcount has been incremented.
+            // It is safe to decrement its refcount
+            // so that it will be destroyed when the entry in study will be removed
+            aMeshes[i]->UnRegister();
+#endif
+          }
+          else {
+            isEmpty = true;
+          }
+        }
       }
 
       // update Object browser
       SMESHGUI::GetSMESHGUI()->updateObjBrowser();
 
+      // browse to the published meshes
+      if( LightApp_Application* anApp =
+          dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
+        anApp->browseObjects( anEntryList );
+
       // show Error message box if there were errors
       if ( errors.count() > 0 ) {
-       SUIT_MessageBox::critical( SMESHGUI::desktop(),
-                                  QObject::tr( "SMESH_ERROR" ),
-                                  QObject::tr( "SMESH_IMPORT_ERRORS" ) + "\n" + errors.join( "\n" ) );
+        SUIT_MessageBox::critical( SMESHGUI::desktop(),
+                                   QObject::tr( "SMESH_ERROR" ),
+                                   QObject::tr( "SMESH_IMPORT_ERRORS" ) + "\n" + errors.join( "\n" ) );
       }
 
       // show warning message box, if some imported mesh is empty
       if ( isEmpty ) {
-         SUIT_MessageBox::warning( SMESHGUI::desktop(),
-                                   QObject::tr( "SMESH_WRN_WARNING" ),
-                                   QObject::tr( "SMESH_DRS_SOME_EMPTY" ) );
+          SUIT_MessageBox::warning( SMESHGUI::desktop(),
+                                    QObject::tr( "SMESH_WRN_WARNING" ),
+                                    QObject::tr( "SMESH_DRS_SOME_EMPTY" ) );
       }
     }
   }
 
+  //================================================================================
+  /*!
+   * \brief Export selected meshes or groups into a file
+   */
+  //================================================================================
+
   void ExportMeshToFile( int theCommandID )
   {
     LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
     if( aSel )
       aSel->selectedObjects( selected );
 
-    SMESH::SMESH_Mesh_var aMesh;
-    if(selected.Extent() == 1)
-      aMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(selected.First());
-    if ( aMesh->_is_nil() ) {
-      SUIT_MessageBox::warning( SMESHGUI::desktop(),
-                                QObject::tr( "SMESH_WRN_WARNING" ),
-                                QObject::tr( "SMESH_BAD_MESH_SELECTION" ));
+    const bool isMED = ( theCommandID == 122 || theCommandID == 125 );
+    const bool isDAT = ( theCommandID == 121 || theCommandID == 124 );
+    const bool isUNV = ( theCommandID == 123 || theCommandID == 126 );
+    const bool isSTL = ( theCommandID == 140 || theCommandID == 141 );
+    const bool isCGNS= ( theCommandID == 142 || theCommandID == 143 );
+    const bool isSAUV= ( theCommandID == 144 || theCommandID == 145 );
+
+    // actually, the following condition can't be met (added for insurance)
+    if( selected.Extent() == 0 ||
+        ( selected.Extent() > 1 && !isMED && !isSTL ))
       return;
-    }
 
-    Handle(SALOME_InteractiveObject) anIObject = selected.First();
-    QString aFilter, aTitle = QObject::tr("Export mesh");
-    QMap<QString, SMESH::MED_VERSION> aFilterMap;
-    QMap<QString, int> aFilterMapSTL;
-    switch ( theCommandID ) {
-    case 125:
-    case 122:
-      {
-        if (aMesh->HasDuplicatedGroupNamesMED()) {
-          int aRet = SUIT_MessageBox::warning
-            (SMESHGUI::desktop(),
-             QObject::tr("SMESH_WRN_WARNING"),
-             QObject::tr("SMESH_EXPORT_MED_DUPLICATED_GRP").arg(anIObject->getName()),
-             SUIT_MessageBox::Yes | SUIT_MessageBox::No, SUIT_MessageBox::Yes);
-          if (aRet != SUIT_MessageBox::Yes)
-            return;
-        }
-        // PAL18696
-        QString v21 (aMesh->GetVersionString(SMESH::MED_V2_1, 2));
-        QString v22 (aMesh->GetVersionString(SMESH::MED_V2_2, 2));
-        aFilterMap.insert( QString("MED ") +  v21 + " (*.med)", SMESH::MED_V2_1 );
-        aFilterMap.insert( QString("MED ") +  v22 + " (*.med)", SMESH::MED_V2_2 );
-      }
-      break;
-    case 124:
-    case 121:
-      aFilter = QObject::tr("DAT files (*.dat)");
-      break;
-    case 126:
-    case 123:
-      {
-        if (aMesh->NbPyramids()) {
-          int aRet = SUIT_MessageBox::warning
-            (SMESHGUI::desktop(),
-             QObject::tr("SMESH_WRN_WARNING"),
-             QObject::tr("SMESH_EXPORT_UNV").arg(anIObject->getName()),
-             SUIT_MessageBox::Yes | SUIT_MessageBox::No, SUIT_MessageBox::Yes);
-          if (aRet != SUIT_MessageBox::Yes)
-            return;
-        }
-        aFilter = QObject::tr("IDEAS files (*.unv)");
+    // get mesh object from selection and check duplication of their names
+    bool hasDuplicatedMeshNames = false;
+    QList< QPair< SMESH::SMESH_IDSource_var, QString > > aMeshList;
+    QList< QPair< SMESH::SMESH_IDSource_var, QString > >::iterator aMeshIter;
+    SALOME_ListIteratorOfListIO It( selected );
+    for( ; It.More(); It.Next() )
+    {
+      Handle(SALOME_InteractiveObject) anIObject = It.Value();
+      SMESH::SMESH_IDSource_var aMeshItem = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(anIObject);
+      if ( aMeshItem->_is_nil() ) {
+        SUIT_MessageBox::warning( SMESHGUI::desktop(),
+                                  QObject::tr( "SMESH_WRN_WARNING" ),
+                                  QObject::tr( "SMESH_BAD_MESH_SELECTION" ));
+        return;
       }
-      break;
-    case 140:
-    case 141:
-      {
-        // export STL
-        /*
-          there must be check on others mesh elements not equal triangles
-        */
-        if (aMesh->NbTriangles() < 1) {
-          SUIT_MessageBox::warning
-            (SMESHGUI::desktop(),
-             QObject::tr("SMESH_WRN_WARNING"),
-             QObject::tr("SMESH_EXPORT_STL1").arg(anIObject->getName()));
-          return;
+
+      QString aMeshName = anIObject->getName();
+
+      // check for name duplications
+      if ( !hasDuplicatedMeshNames )
+        for( aMeshIter = aMeshList.begin(); aMeshIter != aMeshList.end(); aMeshIter++ ) {
+          if( aMeshName == (*aMeshIter).second ) {
+            hasDuplicatedMeshNames = true;
+            break;
+          }
         }
-        if (!(aMesh->NbElements() - aMesh->NbTriangles())) {
+
+      aMeshList.append( QPair< SMESH::SMESH_IDSource_var, QString >( aMeshItem, aMeshName ) );
+    }
+
+    if( hasDuplicatedMeshNames && isMED ) {
+      int aRet = SUIT_MessageBox::warning(SMESHGUI::desktop(),
+                                          QObject::tr("SMESH_WRN_WARNING"),
+                                          QObject::tr("SMESH_EXPORT_MED_DUPLICATED_MESH_NAMES"),
+                                          QObject::tr("SMESH_BUT_YES"),
+                                          QObject::tr("SMESH_BUT_NO"), 0, 1);
+      if (aRet != 0)
+        return;
+    }
+
+    aMeshIter = aMeshList.begin();
+    SMESH::SMESH_IDSource_var aMeshOrGroup = (*aMeshIter).first;
+    SMESH::SMESH_Mesh_var aMesh = aMeshOrGroup->GetMesh();
+    QString aMeshName = (*aMeshIter).second;
+
+    if ( isMED || isCGNS || isSAUV )
+    {
+      // check for equal group names within each mesh
+      for( aMeshIter = aMeshList.begin(); aMeshIter != aMeshList.end(); aMeshIter++ ) {
+        SMESH::SMESH_Mesh_var aMeshItem = SMESH::SMESH_Mesh::_narrow( (*aMeshIter).first );
+        if ( !aMeshItem->_is_nil() && aMeshItem->HasDuplicatedGroupNamesMED()) {
           int aRet = SUIT_MessageBox::warning
             (SMESHGUI::desktop(),
              QObject::tr("SMESH_WRN_WARNING"),
-             QObject::tr("SMESH_EXPORT_STL2").arg(anIObject->getName()),
-             SUIT_MessageBox::Yes | SUIT_MessageBox::No, SUIT_MessageBox::Yes);
-          if (aRet != SUIT_MessageBox::Yes)
+             QObject::tr("SMESH_EXPORT_MED_DUPLICATED_GRP").arg((*aMeshIter).second),
+             QObject::tr("SMESH_BUT_YES"),
+             QObject::tr("SMESH_BUT_NO"), 0, 1);
+          if (aRet != 0)
             return;
         }
-
-        aFilterMapSTL.insert( QObject::tr("STL ASCII  (*.stl)"), 1 ); // 1 - ASCII mode
-        aFilterMapSTL.insert( QObject::tr("STL Binary (*.stl)"), 0 ); // 0 - Binary mode
       }
-      break;
-    default:
-      return;
+    }
+    
+    // Warn the user about presence of not supported elements
+    QString format;
+    std::vector< SMESH::EntityType > notSupportedElemTypes, presentNotSupported;
+    if ( isDAT )
+    {
+      format = "DAT";
+      notSupportedElemTypes.push_back( SMESH::Entity_Quad_Quadrangle );
+      notSupportedElemTypes.push_back( SMESH::Entity_BiQuad_Quadrangle );
+      notSupportedElemTypes.push_back( SMESH::Entity_Polygon );
+      notSupportedElemTypes.push_back( SMESH::Entity_Quad_Polygon );
+      notSupportedElemTypes.push_back( SMESH::Entity_Tetra );
+      notSupportedElemTypes.push_back( SMESH::Entity_Quad_Tetra );
+      notSupportedElemTypes.push_back( SMESH::Entity_Pyramid );
+      notSupportedElemTypes.push_back( SMESH::Entity_Quad_Pyramid );
+      notSupportedElemTypes.push_back( SMESH::Entity_Quad_Hexa );
+      notSupportedElemTypes.push_back( SMESH::Entity_TriQuad_Hexa );
+      notSupportedElemTypes.push_back( SMESH::Entity_Penta );
+      notSupportedElemTypes.push_back( SMESH::Entity_Quad_Penta );
+      notSupportedElemTypes.push_back( SMESH::Entity_Hexagonal_Prism );
+      notSupportedElemTypes.push_back( SMESH::Entity_Polyhedra );
+      notSupportedElemTypes.push_back( SMESH::Entity_0D );
+      notSupportedElemTypes.push_back( SMESH::Entity_Ball );
+    }
+    else if ( isUNV )
+    {
+      format = "UNV";
+      notSupportedElemTypes.push_back( SMESH::Entity_Polygon );
+      notSupportedElemTypes.push_back( SMESH::Entity_Quad_Polygon );
+      notSupportedElemTypes.push_back( SMESH::Entity_Polyhedra );
+      notSupportedElemTypes.push_back( SMESH::Entity_Quad_Polyhedra );
+      notSupportedElemTypes.push_back( SMESH::Entity_Pyramid );
+      notSupportedElemTypes.push_back( SMESH::Entity_Hexagonal_Prism );
+      notSupportedElemTypes.push_back( SMESH::Entity_0D );
+      notSupportedElemTypes.push_back( SMESH::Entity_Ball );
+    }
+    else if ( isSTL )
+    {
+      format = "STL";
+      notSupportedElemTypes.push_back( SMESH::Entity_Edge );
+      notSupportedElemTypes.push_back( SMESH::Entity_Quad_Edge );
+      notSupportedElemTypes.push_back( SMESH::Entity_0D );
+      notSupportedElemTypes.push_back( SMESH::Entity_Ball );
+    }
+    else if ( isCGNS )
+    {
+      format = "CGNS";
+      notSupportedElemTypes.push_back( SMESH::Entity_Ball );
+    }
+    else if ( isSAUV )
+    {
+      format = "SAUV";
+      notSupportedElemTypes.push_back( SMESH::Entity_Ball );
+      notSupportedElemTypes.push_back( SMESH::Entity_BiQuad_Quadrangle );
+      notSupportedElemTypes.push_back( SMESH::Entity_TriQuad_Hexa );
+      notSupportedElemTypes.push_back( SMESH::Entity_Hexagonal_Prism );
+      notSupportedElemTypes.push_back( SMESH::Entity_Polygon );
+      notSupportedElemTypes.push_back( SMESH::Entity_Polyhedra );
+    }
+    if ( ! notSupportedElemTypes.empty() )
+    {
+      SMESH::long_array_var nbElems = aMeshOrGroup->GetMeshInfo();
+      for ( size_t iType = 0; iType < notSupportedElemTypes.size(); ++iType )
+        if ( nbElems[ notSupportedElemTypes[ iType ]] > 0 )
+          presentNotSupported.push_back( notSupportedElemTypes[ iType ]);
+    }
+    if ( !presentNotSupported.empty() )
+    {
+      QString typeNames;
+      const char* typeMsg[SMESH::Entity_Last] = { "SMESH_NODES",
+        "SMESH_ELEMS0D","SMESH_EDGES","SMESH_QUADRATIC_EDGES","SMESH_TRIANGLES",
+        "SMESH_QUADRATIC_TRIANGLES","SMESH_QUADRANGLES","SMESH_QUADRATIC_QUADRANGLES",
+        "SMESH_BIQUADRATIC_QUADRANGLES","SMESH_POLYGONS","SMESH_QUADRATIC_POLYGONS",
+        "SMESH_TETRAHEDRA","SMESH_QUADRATIC_TETRAHEDRONS","SMESH_PYRAMIDS",
+        "SMESH_QUADRATIC_PYRAMIDS","SMESH_HEXAHEDRA","SMESH_QUADRATIC_HEXAHEDRONS",
+        "SMESH_TRIQUADRATIC_HEXAHEDRONS","SMESH_PENTAHEDRA","SMESH_QUADRATIC_PENTAHEDRONS",
+        "SMESH_OCTAHEDRA","SMESH_POLYEDRONS","SMESH_QUADRATIC_POLYEDRONS","SMESH_BALLS"
+      };
+      QString andStr = " " + QObject::tr("SMESH_AND") + " ", comma(", ");
+      for ( size_t iType = 0; iType < presentNotSupported.size(); ++iType ) {
+        typeNames += QObject::tr( typeMsg[ presentNotSupported[ iType ]]);
+        if ( iType != presentNotSupported.size() - 1 )
+          typeNames += ( iType == presentNotSupported.size() - 2 ) ? andStr : comma;
+      }
+      int aRet = SUIT_MessageBox::warning
+        (SMESHGUI::desktop(),
+         QObject::tr("SMESH_WRN_WARNING"),
+         QObject::tr("EXPORT_NOT_SUPPORTED").arg(aMeshName).arg(format).arg(typeNames),
+         QObject::tr("SMESH_BUT_YES"),
+         QObject::tr("SMESH_BUT_NO"), 0, 1);
+      if (aRet != 0)
+        return;
     }
 
+    // Get parameters of export operation
+
     QString aFilename;
     SMESH::MED_VERSION aFormat;
-    // Init the parameter with the default value
+    // Init the parameters with the default values
     bool aIsASCII_STL = true;
     bool toCreateGroups = false;
     SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
     if ( resMgr )
       toCreateGroups = resMgr->booleanValue( "SMESH", "auto_groups", false );
+    bool toOverwrite = true;
 
+    QString aFilter, aTitle = QObject::tr("SMESH_EXPORT_MESH");
     QString anInitialPath = "";
     if ( SUIT_FileDlg::getLastVisitedPath().isEmpty() )
       anInitialPath = QDir::currentPath();
 
-    if ( theCommandID != 122 && theCommandID != 125 && theCommandID != 140 && theCommandID != 141) {
+    if ( isUNV || isDAT )
+    {
+      if ( isUNV )
+        aFilter = QObject::tr( "IDEAS_FILES_FILTER" ) + " (*.unv)";
+      else
+        aFilter = QObject::tr( "DAT_FILES_FILTER" ) + " (*.dat)";
       if ( anInitialPath.isEmpty() ) anInitialPath = SUIT_FileDlg::getLastVisitedPath();
-      aFilename = SUIT_FileDlg::getFileName(SMESHGUI::desktop(), anInitialPath + QString("/") + anIObject->getName(),
+      aFilename = SUIT_FileDlg::getFileName(SMESHGUI::desktop(),
+                                            anInitialPath + QString("/") + aMeshName,
                                             aFilter, aTitle, false);
     }
-    else if(theCommandID == 140 || theCommandID == 141) { // Export to STL
+    else if ( isCGNS )// Export to CGNS
+    {
+      SUIT_FileDlg* fd = new SUIT_FileDlg( SMESHGUI::desktop(), false, true, true );
+      fd->setWindowTitle( aTitle );
+      fd->setNameFilter( QObject::tr( "CGNS_FILES_FILTER" ) + " (*.cgns)" );
+      if ( !anInitialPath.isEmpty() )
+        fd->setDirectory( anInitialPath );
+      fd->selectFile(aMeshName);
+      SMESHGUI_FileValidator* fv = new SMESHGUI_FileValidator( fd );
+      fd->setValidator( fv );
+
+      if ( fd->exec() )
+        aFilename = fd->selectedFile();
+      toOverwrite = fv->isOverwrite();
+
+      delete fd;
+    }
+    else if ( isSTL ) // Export to STL
+    {
+      QMap<QString, int> aFilterMap;
+      aFilterMap.insert( QObject::tr( "STL_ASCII_FILES_FILTER" ) + " (*.stl)", 1 );
+      aFilterMap.insert( QObject::tr( "STL_BIN_FILES_FILTER" )   + " (*.stl)", 0 );
+
       QStringList filters;
-      QMap<QString, int>::const_iterator it = aFilterMapSTL.begin();
-      for ( ; it != aFilterMapSTL.end(); ++it )
+      QMap<QString, int>::const_iterator it = aFilterMap.begin();
+      for ( ; it != aFilterMap.end(); ++it )
         filters.push_back( it.key() );
 
       SUIT_FileDlg* fd = new SUIT_FileDlg( SMESHGUI::desktop(), false, true, true );
       fd->setWindowTitle( aTitle );
-      fd->setFilters( filters );
-      fd->selectFilter( QObject::tr("STL ASCII  (*.stl)") );
+      fd->setNameFilters( filters );
+      fd->selectNameFilter( QObject::tr( "STL_ASCII_FILES_FILTER" ) + " (*.stl)" );
       if ( !anInitialPath.isEmpty() )
         fd->setDirectory( anInitialPath );
-      fd->selectFile(anIObject->getName());
+      fd->selectFile(aMeshName);
       bool is_ok = false;
       while (!is_ok) {
         if ( fd->exec() )
           aFilename = fd->selectedFile();
-        aIsASCII_STL = (aFilterMapSTL[fd->selectedFilter()]) == 1 ? true: false;
+        aIsASCII_STL = (aFilterMap[fd->selectedNameFilter()]) == 1 ? true: false;
         is_ok = true;
       }
       delete fd;
     }
-    else { // Export to MED
+    else if ( isMED || isSAUV ) // Export to MED or SAUV
+    {
+      QMap<QString, SMESH::MED_VERSION> aFilterMap;
+      //QString v21 (aMesh->GetVersionString(SMESH::MED_V2_1, 2));
+      if ( isMED ) {
+        QString v22 (aMesh->GetVersionString(SMESH::MED_V2_2, 2));
+        //aFilterMap.insert( QObject::tr( "MED_VX_FILES_FILTER" ).arg( v21 ) + " (*.med)", SMESH::MED_V2_1 );
+        aFilterMap.insert( QObject::tr( "MED_VX_FILES_FILTER" ).arg( v22 ) + " (*.med)", SMESH::MED_V2_2 );
+      }
+      else { // isSAUV
+        aFilterMap.insert("All files (*)", SMESH::MED_V2_1 );
+        aFilterMap.insert("SAUV files (*.sauv)", SMESH::MED_V2_2 );
+        aFilterMap.insert("SAUV files (*.sauve)", SMESH::MED_V2_1 );
+      }
+
       QStringList filters;
       QString aDefaultFilter;
       QMap<QString, SMESH::MED_VERSION>::const_iterator it = aFilterMap.begin();
           aDefaultFilter = it.key();
       }
 
-      //SUIT_FileDlg* fd = new SUIT_FileDlg( SMESHGUI::desktop(), false, true, true );
       SalomeApp_CheckFileDlg* fd = new SalomeApp_CheckFileDlg
         ( SMESHGUI::desktop(), false, QObject::tr("SMESH_AUTO_GROUPS"), true, true );
       fd->setWindowTitle( aTitle );
-      fd->setFilters( filters );
-      //fd->setSelectedFilter( QObject::tr("MED 2.2 (*.med)") );
-      fd->selectFilter(aDefaultFilter);
+      fd->setNameFilters( filters );
+      fd->selectNameFilter(aDefaultFilter);
       fd->SetChecked(toCreateGroups);
       if ( !anInitialPath.isEmpty() )
         fd->setDirectory( anInitialPath );
-      fd->selectFile(anIObject->getName());
+      fd->selectFile(aMeshName);
+
+      SMESHGUI_FileValidator* fv = new SMESHGUI_FileValidator( fd );
+      fd->setValidator( fv );
+
       bool is_ok = false;
       while (!is_ok) {
         if ( fd->exec() )
           aFilename = fd->selectedFile();
-        aFormat = aFilterMap[fd->selectedFilter()];
+        else {
+          aFilename = QString::null;
+          break;
+        }
+        aFormat = aFilterMap[fd->selectedNameFilter()];
+        toOverwrite = fv->isOverwrite();
         is_ok = true;
-        if ( !aFilename.isEmpty()
-             && (aMesh->NbPolygons()>0 || aMesh->NbPolyhedrons()>0)
-             && aFormat==SMESH::MED_V2_1) {
-          int aRet = SUIT_MessageBox::warning(SMESHGUI::desktop(),
-                                              QObject::tr("SMESH_WRN_WARNING"),
-                                              QObject::tr("SMESH_EXPORT_MED_V2_1").arg(anIObject->getName()),
-                                              SUIT_MessageBox::Yes | SUIT_MessageBox::No, SUIT_MessageBox::Yes);
-          if (aRet != SUIT_MessageBox::Yes) {
-            is_ok = false;
+        if ( !aFilename.isEmpty() ) {
+          // med-2.1 does not support poly elements
+          if ( aFormat==SMESH::MED_V2_1 )
+            for( aMeshIter = aMeshList.begin(); aMeshIter != aMeshList.end(); aMeshIter++ ) {
+              SMESH::SMESH_IDSource_var aMeshItem = (*aMeshIter).first;
+              SMESH::long_array_var nbElems = aMeshItem->GetMeshInfo();
+              if ( nbElems[ SMESH::Entity_Polygon   ] + nbElems[ SMESH::Entity_Quad_Polygon   ] +
+                   nbElems[ SMESH::Entity_Polyhedra ] + nbElems[ SMESH::Entity_Quad_Polyhedra ])
+              {
+                int aRet = SUIT_MessageBox::warning(SMESHGUI::desktop(),
+                                                    QObject::tr("SMESH_WRN_WARNING"),
+                                                    QObject::tr("SMESH_EXPORT_MED_V2_1").arg((*aMeshIter).second),
+                                                    QObject::tr("SMESH_BUT_YES"),
+                                                    QObject::tr("SMESH_BUT_NO"), 0, 1);
+                if (aRet != 0) {
+                  is_ok = false;
+                  break;
+                }
+              }
+            }
+          if( !toOverwrite ) {
+            // can't append to an existing using other format
+            SMESH::MED_VERSION aVersion = SMESH::MED_V2_1;
+            bool isVersionOk = SMESHGUI::GetSMESHGen()->GetMEDVersion( aFilename.toLatin1().constData(), aVersion );
+            if( !isVersionOk || aVersion != aFormat ) {
+              int aRet = SUIT_MessageBox::warning(SMESHGUI::desktop(),
+                                                  QObject::tr("SMESH_WRN_WARNING"),
+                                                  QObject::tr("SMESH_EXPORT_MED_VERSION_COLLISION").arg(aFilename),
+                                                  QObject::tr("SMESH_BUT_YES"),
+                                                  QObject::tr("SMESH_BUT_NO"), 0, 1);
+              if (aRet == 0)
+                toOverwrite = true;
+              else
+                is_ok = false;
+            }
+
+            QStringList aMeshNamesCollisionList;
+            SMESH::string_array_var aMeshNames = SMESHGUI::GetSMESHGen()->GetMeshNames( aFilename.toLatin1().constData() );
+            for( int i = 0, n = aMeshNames->length(); i < n; i++ ) {
+              QString anExistingMeshName( aMeshNames[ i ] );
+              for( aMeshIter = aMeshList.begin(); aMeshIter != aMeshList.end(); aMeshIter++ ) {
+                QString anExportMeshName = (*aMeshIter).second;
+                if( anExportMeshName == anExistingMeshName ) {
+                  aMeshNamesCollisionList.append( anExportMeshName );
+                  break;
+                }
+              }
+            }
+            if( !aMeshNamesCollisionList.isEmpty() ) {
+              QString aMeshNamesCollisionString = aMeshNamesCollisionList.join( ", " );
+              int aRet = SUIT_MessageBox::warning(SMESHGUI::desktop(),
+                                                  QObject::tr("SMESH_WRN_WARNING"),
+                                                  QObject::tr("SMESH_EXPORT_MED_MESH_NAMES_COLLISION").arg(aMeshNamesCollisionString),
+                                                  QObject::tr("SMESH_BUT_YES"),
+                                                  QObject::tr("SMESH_BUT_NO"),
+                                                  QObject::tr("SMESH_BUT_CANCEL"), 0, 2);
+              if (aRet == 0)
+                toOverwrite = true;
+              else if (aRet == 2)
+                is_ok = false;
+            }
           }
         }
       }
       toCreateGroups = fd->IsChecked();
       delete fd;
     }
+    else
+    {
+      return;
+    }
+
+    // Perform export
+
     if ( !aFilename.isEmpty() ) {
       // Check whether the file already exists and delete it if yes
       QFile aFile( aFilename );
-      if ( aFile.exists() )
+      if ( aFile.exists() && toOverwrite )
         aFile.remove();
       SUIT_OverrideCursor wc;
 
       try {
-        bool Renumber = false;
-        // PAL 14172  : Check of we have to renumber or not from the preferences before export
-        if (resMgr)
-          Renumber= resMgr->booleanValue("SMESH","renumbering");
-        if (Renumber){
-          SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
-          aMeshEditor->RenumberNodes();
-          aMeshEditor->RenumberElements();
-          if ( SMESHGUI::automaticUpdate() )
-            SMESH::UpdateView();
+        // Renumbering is not needed since SMDS redesign in V6.2.0 (Nov 2010)
+//         bool Renumber = false;
+//         // PAL 14172  : Check of we have to renumber or not from the preferences before export
+//         if (resMgr)
+//           Renumber= resMgr->booleanValue("renumbering");
+//         if (Renumber){
+//           SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
+//           aMeshEditor->RenumberNodes();
+//           aMeshEditor->RenumberElements();
+//           if ( SMESHGUI::automaticUpdate() )
+//             SMESH::UpdateView();
+//         }
+        if ( isMED )
+        {
+          aMeshIter = aMeshList.begin();
+          for( int aMeshIndex = 0; aMeshIter != aMeshList.end(); aMeshIter++, aMeshIndex++ )
+          {
+            SMESH::SMESH_IDSource_var aMeshOrGroup = (*aMeshIter).first;
+            SMESH::SMESH_Mesh_var        aMeshItem = aMeshOrGroup->GetMesh();
+            if ( aMeshOrGroup->_is_equivalent( aMeshItem ))
+              aMeshItem->ExportToMEDX( aFilename.toLatin1().data(), toCreateGroups,
+                                       aFormat, toOverwrite && aMeshIndex == 0 );
+            else
+              aMeshItem->ExportPartToMED( aMeshOrGroup, aFilename.toLatin1().data(), toCreateGroups,
+                                          aFormat, toOverwrite && aMeshIndex == 0 );
+          }
         }
-        switch ( theCommandID ) {
-        case 125:
-        case 122:
-          aMesh->ExportToMED( aFilename.toLatin1().data(), toCreateGroups, aFormat );
-          break;
-        case 124:
-        case 121:
-          aMesh->ExportDAT( aFilename.toLatin1().data() );
-          break;
-        case 126:
-        case 123:
-          aMesh->ExportUNV( aFilename.toLatin1().data() );
-          break;
-        case 140:
-        case 141:
-          aMesh->ExportSTL( aFilename.toLatin1().data(), aIsASCII_STL );
-          break;
-        default:
-          break;
+        else if ( isSAUV )
+        {
+          for( aMeshIter = aMeshList.begin(); aMeshIter != aMeshList.end(); aMeshIter++ )
+          {
+            SMESH::SMESH_Mesh_var aMeshItem = SMESH::SMESH_Mesh::_narrow( (*aMeshIter).first );
+            if( !aMeshItem->_is_nil() )
+              aMeshItem->ExportSAUV( aFilename.toLatin1().data(), toCreateGroups );
+          }
+        }
+        else if ( isDAT )
+        {
+          if ( aMeshOrGroup->_is_equivalent( aMesh ))
+            aMesh->ExportDAT( aFilename.toLatin1().data() );
+          else
+            aMesh->ExportPartToDAT( aMeshOrGroup, aFilename.toLatin1().data() );
+        }
+        else if ( isUNV )
+        {
+          if ( aMeshOrGroup->_is_equivalent( aMesh ))
+            aMesh->ExportUNV( aFilename.toLatin1().data() );
+          else
+            aMesh->ExportPartToUNV( aMeshOrGroup, aFilename.toLatin1().data() );
+        }
+        else if ( isSTL )
+        {
+          if ( aMeshOrGroup->_is_equivalent( aMesh ))
+            aMesh->ExportSTL( aFilename.toLatin1().data(), aIsASCII_STL );
+          else
+            aMesh->ExportPartToSTL( aMeshOrGroup, aFilename.toLatin1().data(), aIsASCII_STL );
+        }
+        else if ( isCGNS )
+        {
+          aMeshIter = aMeshList.begin();
+          for( int aMeshIndex = 0; aMeshIter != aMeshList.end(); aMeshIter++, aMeshIndex++ )
+          {
+            SMESH::SMESH_IDSource_var aMeshOrGroup = (*aMeshIter).first;
+            SMESH::SMESH_Mesh_var        aMeshItem = aMeshOrGroup->GetMesh();
+            aMeshItem->ExportCGNS( aMeshOrGroup,
+                                   aFilename.toLatin1().data(),
+                                   toOverwrite && aMeshIndex == 0 );
+          }
         }
       }
       catch (const SALOME::SALOME_Exception& S_ex){
   }
 
   inline void InverseEntityMode(unsigned int& theOutputMode,
-                               unsigned int theMode)
+                                unsigned int theMode)
   {
     bool anIsNotPresent = ~theOutputMode & theMode;
     if(anIsNotPresent)
     if(selected.Extent() >= 1){
       SALOME_ListIteratorOfListIO It( selected );
       for( ; It.More(); It.Next()){
-       Handle(SALOME_InteractiveObject) IObject = It.Value();
-       if(IObject->hasEntry()){
-         if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){
-           unsigned int aMode = anActor->GetEntityMode();
-           switch(theCommandID){
-           case 217:
-             InverseEntityMode(aMode,SMESH_Actor::eEdges);
-             break;
-           case 218:
-             InverseEntityMode(aMode,SMESH_Actor::eFaces);
-             break;
-           case 219:
-             InverseEntityMode(aMode,SMESH_Actor::eVolumes);
-             break;
-           case 220:
-             aMode = SMESH_Actor::eAllEntity;
-             break;
-           }
-           if(aMode)
-             anActor->SetEntityMode(aMode);
-         }
-       }
+        Handle(SALOME_InteractiveObject) IObject = It.Value();
+        if(IObject->hasEntry()){
+          if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){
+            unsigned int aMode = anActor->GetEntityMode();
+            switch(theCommandID){
+            case 222:
+              InverseEntityMode(aMode,SMESH_Actor::eBallElem);
+              break;
+            case 216:
+              InverseEntityMode(aMode,SMESH_Actor::e0DElements);
+              break;
+            case 217:
+              InverseEntityMode(aMode,SMESH_Actor::eEdges);
+              break;
+            case 218:
+              InverseEntityMode(aMode,SMESH_Actor::eFaces);
+              break;
+            case 219:
+              InverseEntityMode(aMode,SMESH_Actor::eVolumes);
+              break;
+            case 220:
+              aMode = SMESH_Actor::eAllEntity;
+              break;
+            }
+            if(aMode)
+              anActor->SetEntityMode(aMode);
+          }
+        }
       }
     }
   }
     if( aMainObject->_is_nil() )
       return;
 
-    aMainObject->SetAutoColor( true );
-
-    QList<SALOMEDS::Color> aReservedColors;
+    aMainObject->SetAutoColor( true ); // mesh groups are re-colored here
 
     SMESH::ListOfGroups aListOfGroups = *aMainObject->GetGroups();
     for( int i = 0, n = aListOfGroups.length(); i < n; i++ )
     {
       SMESH::SMESH_GroupBase_var aGroupObject = aListOfGroups[i];
-      SALOMEDS::Color aCurrentColor = aGroupObject->GetColor();
-
-      SALOMEDS::Color aColor = SMESHGUI::getUniqueColor( aReservedColors );
-      aGroupObject->SetColor( aColor );
-      aReservedColors.append( aColor );
-
+      SALOMEDS::Color aColor = aGroupObject->GetColor();
       _PTR(SObject) aGroupSObject = SMESH::FindSObject(aGroupObject);
-      if(SMESH_Actor *anActor = SMESH::FindActorByEntry(aGroupSObject->GetID().c_str()))
-      {
-       if( aGroupObject->GetType() == SMESH::NODE )
-         anActor->SetNodeColor( aColor.R, aColor.G, aColor.B );
-       else if( aGroupObject->GetType() == SMESH::EDGE )
-         anActor->SetEdgeColor( aColor.R, aColor.G, aColor.B );
-       else
-         anActor->SetSufaceColor( aColor.R, aColor.G, aColor.B );
+      if (aGroupSObject) {
+        if(SMESH_Actor *anActor = SMESH::FindActorByEntry(aGroupSObject->GetID().c_str())) {
+          switch ( aGroupObject->GetType ()) {
+          case SMESH::NODE:
+            anActor->SetNodeColor( aColor.R, aColor.G, aColor.B ); break;
+          case SMESH::EDGE:
+            anActor->SetEdgeColor( aColor.R, aColor.G, aColor.B ); break;
+          case SMESH::ELEM0D:
+            anActor->Set0DColor( aColor.R, aColor.G, aColor.B ); break;
+          case SMESH::BALL:
+            anActor->SetBallColor( aColor.R, aColor.G, aColor.B ); break;
+          default:
+            QColor c;
+            int delta;
+            SMESH::GetColor("SMESH", "fill_color", c, delta, "0,170,255|-100");
+            anActor->SetSufaceColor( aColor.R, aColor.G, aColor.B, delta );
+          }
+        }
       }
     }
 
     SMESH::RepaintCurrentView();
   }
 
+  QString functorToString( SMESH::Controls::FunctorPtr f )
+  {
+    QString type = QObject::tr( "UNKNOWN_CONTROL" );
+    if ( dynamic_cast< SMESH::Controls::Volume* >( f.get() ) )
+      type = QObject::tr( "VOLUME_3D_ELEMENTS" );
+    else if ( dynamic_cast< SMESH::Controls::MaxElementLength2D* >( f.get() ) )
+      type = QObject::tr( "MAX_ELEMENT_LENGTH_2D" );
+    else if ( dynamic_cast< SMESH::Controls::MaxElementLength3D* >( f.get() ) )
+      type = QObject::tr( "MAX_ELEMENT_LENGTH_3D" );
+    else if ( dynamic_cast< SMESH::Controls::MinimumAngle* >( f.get() ) )
+      type = QObject::tr( "MINIMUMANGLE_ELEMENTS" );
+    else if ( dynamic_cast< SMESH::Controls::AspectRatio* >( f.get() ) )
+      type = QObject::tr( "ASPECTRATIO_ELEMENTS" );
+    else if ( dynamic_cast< SMESH::Controls::AspectRatio3D* >( f.get() ) )
+      type = QObject::tr( "ASPECTRATIO_3D_ELEMENTS" );
+    else if ( dynamic_cast< SMESH::Controls::Warping* >( f.get() ) )
+      type = QObject::tr( "WARP_ELEMENTS" );
+    else if ( dynamic_cast< SMESH::Controls::Taper* >( f.get() ) )
+      type = QObject::tr( "TAPER_ELEMENTS" );
+    else if ( dynamic_cast< SMESH::Controls::Skew* >( f.get() ) )
+      type = QObject::tr( "SKEW_ELEMENTS" );
+    else if ( dynamic_cast< SMESH::Controls::Area* >( f.get() ) )
+      type = QObject::tr( "AREA_ELEMENTS" );
+    else if ( dynamic_cast< SMESH::Controls::Length* >( f.get() ) )
+      type = QObject::tr( "LENGTH_EDGES" );
+    else if ( dynamic_cast< SMESH::Controls::Length2D* >( f.get() ) )
+      type = QObject::tr( "LENGTH2D_EDGES" );
+    else if ( dynamic_cast< SMESH::Controls::MultiConnection* >( f.get() ) )
+      type = QObject::tr( "MULTI_BORDERS" );
+    else if ( dynamic_cast< SMESH::Controls::MultiConnection2D* >( f.get() ) )
+      type = QObject::tr( "MULTI2D_BORDERS" );
+    else if ( dynamic_cast< SMESH::Controls::FreeNodes* >( f.get() ) )
+      type = QObject::tr( "FREE_NODES" );
+    else if ( dynamic_cast< SMESH::Controls::FreeEdges* >( f.get() ) )
+      type = QObject::tr( "FREE_EDGES" );
+    else if ( dynamic_cast< SMESH::Controls::FreeBorders* >( f.get() ) )
+      type = QObject::tr( "FREE_BORDERS" );
+    else if ( dynamic_cast< SMESH::Controls::FreeFaces* >( f.get() ) )
+      type = QObject::tr( "FREE_FACES" );
+    else if ( dynamic_cast< SMESH::Controls::BareBorderVolume* >( f.get() ) )
+      type = QObject::tr( "BARE_BORDER_VOLUME" );
+    else if ( dynamic_cast< SMESH::Controls::BareBorderFace* >( f.get() ) )
+      type = QObject::tr( "BARE_BORDER_FACE" );
+    else if ( dynamic_cast< SMESH::Controls::OverConstrainedVolume* >( f.get() ) )
+      type = QObject::tr( "OVER_CONSTRAINED_VOLUME" );
+    else if ( dynamic_cast< SMESH::Controls::OverConstrainedFace* >( f.get() ) )
+      type = QObject::tr( "OVER_CONSTRAINED_FACE" );
+    else if ( dynamic_cast< SMESH::Controls::CoincidentNodes* >( f.get() ) )
+      type = QObject::tr( "EQUAL_NODE" );
+    else if ( dynamic_cast< SMESH::Controls::CoincidentElements1D* >( f.get() ) )
+      type = QObject::tr( "EQUAL_EDGE" );
+    else if ( dynamic_cast< SMESH::Controls::CoincidentElements2D* >( f.get() ) )
+      type = QObject::tr( "EQUAL_FACE" );
+    else if ( dynamic_cast< SMESH::Controls::CoincidentElements3D* >( f.get() ) )
+      type = QObject::tr( "EQUAL_VOLUME" );
+    return type;
+  }
+
+  void SaveDistribution()
+  {
+    LightApp_SelectionMgr* aSel = SMESHGUI::selectionMgr();
+    SALOME_ListIO selected;
+    if ( aSel )
+      aSel->selectedObjects( selected );
+
+    if ( selected.Extent() == 1 ) {
+      Handle(SALOME_InteractiveObject) anIO = selected.First();
+      if ( anIO->hasEntry() ) {
+        SMESH_Actor* anActor = SMESH::FindActorByEntry( anIO->getEntry() );
+        if ( anActor && anActor->GetScalarBarActor() && anActor->GetControlMode() != SMESH_Actor::eNone ) {
+          SMESH_ScalarBarActor* aScalarBarActor = anActor->GetScalarBarActor();
+          SMESH::Controls::FunctorPtr aFunctor = anActor->GetFunctor();
+          if ( aScalarBarActor && aFunctor ) {
+            SMESH::Controls::NumericalFunctor* aNumFun = dynamic_cast<SMESH::Controls::NumericalFunctor*>( aFunctor.get() );
+            if ( aNumFun ) {
+              std::vector<int> elements;
+              SMESH::SMESH_Mesh_var mesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(anIO);
+              if ( mesh->_is_nil() ) {
+                SMESH::SMESH_IDSource_var idSource =
+                  SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(anIO);
+                if ( !idSource->_is_nil() )
+                {
+                  SMESH::long_array_var ids = idSource->GetIDs();
+                  elements.resize( ids->length() );
+                  for ( unsigned i = 0; i < elements.size(); ++i )
+                    elements[i] = ids[i];
+                }
+              }
+              int nbIntervals = aScalarBarActor->GetMaximumNumberOfColors();
+              vtkLookupTable* lookupTable =
+                static_cast<vtkLookupTable*>(aScalarBarActor->GetLookupTable());
+              double * minmax = lookupTable->GetRange();
+              std::vector<int>    nbEvents;
+              std::vector<double> funValues;
+              aNumFun->GetHistogram( nbIntervals, nbEvents, funValues, elements, minmax );
+              QString anInitialPath = "";
+              if ( SUIT_FileDlg::getLastVisitedPath().isEmpty() )
+                anInitialPath = QDir::currentPath();
+              QString aMeshName = anIO->getName();
+              QStringList filter;
+              filter.append( QObject::tr( "TEXT_FILES_FILTER" ) + " (*.txt)" );
+              filter.append( QObject::tr( "ALL_FILES_FILTER" ) + " (*)" );
+              QString aFilename = anInitialPath + "/" + aMeshName + "_" + 
+                functorToString( aFunctor ).toLower().simplified().replace( QRegExp( " |-" ), "_" ) + ".txt";
+              aFilename = SUIT_FileDlg::getFileName( SMESHGUI::desktop(),
+                                                     aFilename,
+                                                     filter,
+                                                     QObject::tr( "SMESH_SAVE_DISTRIBUTION" ),
+                                                     false );
+              if ( !aFilename.isEmpty() ) {
+                QFile f( aFilename );
+                if ( f.open( QFile::WriteOnly | QFile::Truncate ) ) {
+                  QTextStream out( &f );
+                  out << "# Mesh: " << aMeshName << endl;
+                  out << "# Control: " << functorToString( aFunctor ) << endl;
+                  out << "#" << endl;
+                  out.setFieldWidth( 10 );
+                  for ( int i = 0; i < qMin( nbEvents.size(), funValues.size()-1 ); i++ )
+                    out << funValues[i] << "\t" << funValues[i+1] << "\t" << nbEvents[i] << endl;
+                  f.close();
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  void ShowDistribution() {
+    LightApp_SelectionMgr* aSel = SMESHGUI::selectionMgr();
+    SALOME_ListIO selected;
+    if ( aSel )
+      aSel->selectedObjects( selected );
+    
+    if ( selected.Extent() == 1 ) {
+      Handle(SALOME_InteractiveObject) anIO = selected.First();
+      if ( anIO->hasEntry() ) {
+        SMESH_Actor* anActor = SMESH::FindActorByEntry( anIO->getEntry() );
+        if ( anActor && anActor->GetScalarBarActor() && anActor->GetControlMode() != SMESH_Actor::eNone ) {
+          SMESH_ScalarBarActor *aScalarBarActor = anActor->GetScalarBarActor();
+          aScalarBarActor->SetDistributionVisibility(!aScalarBarActor->GetDistributionVisibility());
+        }
+      }
+    }
+  }
+
+#ifndef DISABLE_PLOT2DVIEWER
+ void PlotDistribution() {
+   SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
+   if( !app )
+     return;
+
+   LightApp_SelectionMgr* aSel = SMESHGUI::selectionMgr();
+   SALOME_ListIO selected;
+   if ( aSel )
+     aSel->selectedObjects( selected );
+    
+   if ( selected.Extent() == 1 ) {
+     Handle(SALOME_InteractiveObject) anIO = selected.First();
+     if ( anIO->hasEntry() ) {
+       //Find Actor by entry before getting Plot2d viewer,
+       //because after call getViewManager( Plot2d_Viewer::Type(), true ) active window is Plot2d Viewer
+       SMESH_Actor* anActor = SMESH::FindActorByEntry( anIO->getEntry() );
+
+       SUIT_ViewManager* aViewManager = app->getViewManager( Plot2d_Viewer::Type(), true ); // create if necessary
+
+       if( !aViewManager )
+         return;
+       
+       SPlot2d_Viewer* aView = dynamic_cast<SPlot2d_Viewer*>(aViewManager->getViewModel());
+       if ( !aView )
+         return;
+
+       Plot2d_ViewFrame* aPlot = aView->getActiveViewFrame();
+       if ( !aPlot )
+         return;
+
+       if ( anActor && anActor->GetControlMode() != SMESH_Actor::eNone ) {
+         SPlot2d_Histogram* aHistogram = anActor->UpdatePlot2Histogram();
+         QString functorName = functorToString( anActor->GetFunctor());
+         QString aHistogramName("%1 : %2");
+         aHistogramName = aHistogramName.arg(anIO->getName()).arg(functorName);
+         aHistogram->setName(aHistogramName);
+         aHistogram->setHorTitle(functorName);
+         aHistogram->setVerTitle(QObject::tr("DISTRIBUTION_NB_ENT"));
+         aPlot->displayObject(aHistogram, true);
+       }
+     }
+   }
+ }
+#endif //DISABLE_PLOT2DVIEWER
+
   void DisableAutoColor(){
     LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
     SALOME_ListIO selected;
       Handle(SALOME_InteractiveObject) anIObject = selected.First();
       SMESH::SMESH_Mesh_var aMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(anIObject);
       if ( !aMesh->_is_nil() ) {
-       aMesh->SetAutoColor( false );
+        aMesh->SetAutoColor( false );
       }
     }
   }
 
-  void SetDisplayMode(int theCommandID){
+  void SetDisplayMode(int theCommandID, SMESHGUI_StudyId2MarkerMap& theMarkerMap)
+  {
     SALOME_ListIO selected;
     SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
     if( !app )
     if( !aSel || !appStudy )
       return;
 
+    if( theCommandID == 1134 ) { // Clipping dialog can be activated without selection
+      if( SMESHGUI* aModule = SMESHGUI::GetSMESHGUI() ) {
+        aModule->EmitSignalDeactivateDialog();
+        if( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( aModule ) )
+          (new SMESHGUI_ClippingDlg( aModule, aViewWindow ))->show();
+      }
+      return;
+    }
+
     _PTR(Study) aStudy = appStudy->studyDS();
 
     aSel->selectedObjects( selected );
 
     if(selected.Extent() >= 1){
       switch(theCommandID){
-      case 1134:{
-       SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
-       (new SMESHGUI_ClippingDlg( SMESHGUI::GetSMESHGUI() ))->show();
-       return;
-      }
       case 1133:{
-       SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
-       (new SMESHGUI_TransparencyDlg( SMESHGUI::GetSMESHGUI() ))->show();
-       return;
-      }}
+        SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
+        (new SMESHGUI_TransparencyDlg( SMESHGUI::GetSMESHGUI() ))->show();
+        return;
+      }
+      case 1132:{
+        QColor c, e, b, n, c0D, cBall, o, outl, selection, preselection;
+        int delta;
+        int size0D = 0, ballSize = 0;
+        int Edgewidth = 0;
+        vtkFloatingPointType Shrink = 0.0;
+        vtkFloatingPointType faces_orientation_scale = 0.0;
+        bool faces_orientation_3dvectors = false;
+
+        VTK::MarkerType aMarkerTypeCurrent = VTK::MT_NONE;
+        VTK::MarkerScale aMarkerScaleCurrent = VTK::MS_NONE;
+        int aMarkerTextureCurrent = 0;
+
+        SALOME_ListIteratorOfListIO It( selected );
+        for( ; It.More(); It.Next()){
+          Handle(SALOME_InteractiveObject) IObject = It.Value();
+          if(IObject->hasEntry()){
+            if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){
+              vtkFloatingPointType color[3];
+              anActor->GetSufaceColor(color[0], color[1], color[2],delta);
+              int c0 = int (color[0] * 255);
+              int c1 = int (color[1] * 255);
+              int c2 = int (color[2] * 255);
+              c.setRgb(c0, c1, c2);
+
+              vtkFloatingPointType edgecolor[3];
+              anActor->GetEdgeColor(edgecolor[0], edgecolor[1], edgecolor[2]);
+              c0 = int (edgecolor[0] * 255);
+              c1 = int (edgecolor[1] * 255);
+              c2 = int (edgecolor[2] * 255);
+              e.setRgb(c0, c1, c2);
+
+              vtkFloatingPointType nodecolor[3];
+              anActor->GetNodeColor(nodecolor[0], nodecolor[1], nodecolor[2]);
+              c0 = int (nodecolor[0] * 255);
+              c1 = int (nodecolor[1] * 255);
+              c2 = int (nodecolor[2] * 255);
+              n.setRgb(c0, c1, c2);
+
+              vtkFloatingPointType color0D[3];
+              anActor->Get0DColor(color0D[0], color0D[1], color0D[2]);
+              c0 = int (color0D[0] * 255);
+              c1 = int (color0D[1] * 255);
+              c2 = int (color0D[2] * 255);
+              c0D.setRgb(c0, c1, c2);
+
+              vtkFloatingPointType ballcolor[3];
+              anActor->GetBallColor(ballcolor[0], ballcolor[1], ballcolor[2]);
+              c0 = int (ballcolor[0] * 255);
+              c1 = int (ballcolor[1] * 255);
+              c2 = int (ballcolor[2] * 255);
+              cBall.setRgb(c0, c1, c2);
+
+              vtkFloatingPointType outlineColor[3];
+              anActor->GetOutlineColor(outlineColor[0], outlineColor[1], outlineColor[2]);
+              c0 = int (outlineColor[0] * 255);
+              c1 = int (outlineColor[1] * 255);
+              c2 = int (outlineColor[2] * 255);
+              outl.setRgb(c0, c1, c2);
+
+              vtkFloatingPointType hColor[3];
+              anActor->GetHighlightColor(hColor[0], hColor[1], hColor[2]);
+              c0 = int (hColor[0] * 255);
+              c1 = int (hColor[1] * 255);
+              c2 = int (hColor[2] * 255);
+              selection.setRgb(c0, c1, c2);
+
+              vtkFloatingPointType phColor[3];
+              anActor->GetPreHighlightColor(phColor[0], phColor[1], phColor[2]);
+              c0 = int (phColor[0] * 255);
+              c1 = int (phColor[1] * 255);
+              c2 = int (phColor[2] * 255);
+              preselection.setRgb(c0, c1, c2);
+
+              size0D = (int)anActor->Get0DSize();
+              if(size0D == 0)
+                size0D = 1;
+              ballSize = (int)anActor->GetBallSize();
+              if(ballSize == 0)
+                ballSize = 1;
+              Edgewidth = (int)anActor->GetLineWidth();
+              if(Edgewidth == 0)
+                Edgewidth = 1;
+              Shrink = anActor->GetShrinkFactor();
+
+              vtkFloatingPointType faces_orientation_color[3];
+              anActor->GetFacesOrientationColor(faces_orientation_color);
+              c0 = int (faces_orientation_color[0] * 255);
+              c1 = int (faces_orientation_color[1] * 255);
+              c2 = int (faces_orientation_color[2] * 255);
+              o.setRgb(c0, c1, c2);
+
+              faces_orientation_scale = anActor->GetFacesOrientationScale();
+              faces_orientation_3dvectors = anActor->GetFacesOrientation3DVectors();
+
+              aMarkerTypeCurrent = anActor->GetMarkerType();
+              aMarkerScaleCurrent = anActor->GetMarkerScale();
+              aMarkerTextureCurrent = anActor->GetMarkerTexture();
+
+              // even if there are multiple objects in the selection,
+              // we need only the first one to get values for the dialog
+              break;
+            }
+          }
+        }
+
+        SMESHGUI_Preferences_ColorDlg *aDlg =
+          new SMESHGUI_Preferences_ColorDlg( SMESHGUI::GetSMESHGUI() );
+        aDlg->SetBooleanValue(1, faces_orientation_3dvectors);
+        aDlg->SetColor(1, c);
+        aDlg->SetColor(2, e);
+        aDlg->SetColor(3, n);
+        aDlg->SetColor(4, outl);
+        aDlg->SetColor(5, c0D);
+        aDlg->SetColor(6, cBall);
+        aDlg->SetColor(7, o);
+        aDlg->SetColor(8, selection);
+        aDlg->SetColor(9, preselection);
+        aDlg->SetDeltaBrightness(delta);
+        aDlg->SetDoubleValue(1, faces_orientation_scale);
+        aDlg->SetIntValue(1, Edgewidth);
+        aDlg->SetIntValue(2, int(Shrink*100.));
+        aDlg->SetIntValue(3, size0D);
+        aDlg->SetIntValue(4, ballSize);
+        aDlg->setCustomMarkerMap( theMarkerMap[ aStudy->StudyId() ] );
+
+        if( aMarkerTypeCurrent != VTK::MT_USER )
+          aDlg->setStandardMarker( aMarkerTypeCurrent, aMarkerScaleCurrent );
+        else
+          aDlg->setCustomMarker( aMarkerTextureCurrent );
+
+        if(aDlg->exec()){
+          QColor color                   = aDlg->GetColor(1);
+          QColor edgecolor               = aDlg->GetColor(2);
+          QColor nodecolor               = aDlg->GetColor(3);
+          QColor outlinecolor            = aDlg->GetColor(4);
+          QColor color0D                 = aDlg->GetColor(5);
+          QColor ballcolor               = aDlg->GetColor(6);
+          QColor faces_orientation_color = aDlg->GetColor(7);
+          QColor selectioncolor          = aDlg->GetColor(8);
+          QColor preSelectioncolor       = aDlg->GetColor(9);
+          int delta = aDlg->GetDeltaBrightness();
+
+          /* Point marker */
+          theMarkerMap[ aStudy->StudyId() ] = aDlg->getCustomMarkerMap();
+
+          SALOME_ListIteratorOfListIO It( selected );
+          for( ; It.More(); It.Next()){
+            Handle(SALOME_InteractiveObject) IObject = It.Value();
+            if(IObject->hasEntry()){
+              if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){
+                /* actor color and backface color */
+                anActor->SetSufaceColor(vtkFloatingPointType (color.red()) / 255.,
+                                        vtkFloatingPointType (color.green()) / 255.,
+                                        vtkFloatingPointType (color.blue()) / 255.,
+                                        delta);
+                /* edge color */
+                anActor->SetEdgeColor(vtkFloatingPointType (edgecolor.red()) / 255.,
+                                      vtkFloatingPointType (edgecolor.green()) / 255.,
+                                      vtkFloatingPointType (edgecolor.blue()) / 255.);
+                /* edge outline */
+                anActor->SetOutlineColor(vtkFloatingPointType (outlinecolor.red()) / 255.,
+                                         vtkFloatingPointType (outlinecolor.green()) / 255.,
+                                         vtkFloatingPointType (outlinecolor.blue()) / 255.);
+
+                /* selection */
+                anActor->SetHighlightColor(vtkFloatingPointType (selectioncolor.red()) / 255.,
+                                           vtkFloatingPointType (selectioncolor.green()) / 255.,
+                                           vtkFloatingPointType (selectioncolor.blue()) / 255.);
+                /* pre-selection */
+                anActor->SetPreHighlightColor(vtkFloatingPointType (preSelectioncolor.red()) / 255.,
+                                              vtkFloatingPointType (preSelectioncolor.green()) / 255.,
+                                              vtkFloatingPointType (preSelectioncolor.blue()) / 255.);
+                
+
+                /* Shrink factor and size edges */
+                anActor->SetShrinkFactor(aDlg->GetIntValue(2) / 100.);
+                anActor->SetLineWidth(aDlg->GetIntValue(1));
+
+                /* Nodes color and size */
+                anActor->SetNodeColor(vtkFloatingPointType (nodecolor.red()) / 255.,
+                                      vtkFloatingPointType (nodecolor.green()) / 255.,
+                                      vtkFloatingPointType (nodecolor.blue()) / 255.);
+
+                /* 0D elements */
+                anActor->Set0DColor(vtkFloatingPointType (color0D.red()) / 255.,
+                                    vtkFloatingPointType (color0D.green()) / 255.,
+                                    vtkFloatingPointType (color0D.blue()) / 255.);
+                anActor->Set0DSize(aDlg->GetIntValue(3));
+
+                /* Ball elements */
+                anActor->SetBallColor(vtkFloatingPointType (ballcolor.red()) / 255.,
+                                      vtkFloatingPointType (ballcolor.green()) / 255.,
+                                      vtkFloatingPointType (ballcolor.blue()) / 255.);
+                anActor->SetBallSize(aDlg->GetIntValue(4));
+
+                /* Faces orientation */
+                vtkFloatingPointType c[3] = {vtkFloatingPointType(faces_orientation_color.redF()),
+                                             vtkFloatingPointType(faces_orientation_color.greenF()),
+                                             vtkFloatingPointType(faces_orientation_color.blueF())};
+                anActor->SetFacesOrientationColor(c);
+                anActor->SetFacesOrientationScale(aDlg->GetDoubleValue(1));
+                anActor->SetFacesOrientation3DVectors(aDlg->GetBooleanValue(1));
+
+                VTK::MarkerType aMarkerTypeNew = aDlg->getMarkerType();
+                VTK::MarkerScale aMarkerScaleNew = aDlg->getStandardMarkerScale();
+                int aMarkerTextureNew = aDlg->getCustomMarkerID();
+                if( aMarkerTypeNew != VTK::MT_USER )
+                  anActor->SetMarkerStd( aMarkerTypeNew, aMarkerScaleNew );
+                else {
+                  const VTK::MarkerMap& aMarkerMap = theMarkerMap[ aStudy->StudyId() ];
+                  VTK::MarkerMap::const_iterator anIter = aMarkerMap.find( aMarkerTextureNew );
+                  if( anIter != aMarkerMap.end() )
+                    anActor->SetMarkerTexture( aMarkerTextureNew, anIter->second.second );
+                }
+
+                SMESH::SMESH_GroupBase_var aGroupObject = SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(IObject);
+                if( !aGroupObject->_is_nil() )
+                {
+                  SMESH::ElementType anElementType = aGroupObject->GetType();
+                  QColor aColor;
+                  switch( anElementType )
+                  {
+                    case SMESH::NODE: aColor = nodecolor; break;
+                    case SMESH::EDGE: aColor = edgecolor; break;
+                    default: aColor = color; break;
+                  }
+
+                  SALOMEDS::Color aGroupColor;
+                  aGroupColor.R = (float)aColor.red() / 255.0;
+                  aGroupColor.G = (float)aColor.green() / 255.0;
+                  aGroupColor.B = (float)aColor.blue() / 255.0;
+                  aGroupObject->SetColor( aGroupColor );
+                }
+              }
+            }
+          }
+          SMESH::RepaintCurrentView();
+        }
+        delete aDlg;
+        return;
+      }
+      }
       SALOME_ListIteratorOfListIO It( selected );
       for( ; It.More(); It.Next()){
-       Handle(SALOME_InteractiveObject) IObject = It.Value();
-       if(IObject->hasEntry()){
-         if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){
-           switch(theCommandID){
-           case 211:
-             anActor->SetRepresentation(SMESH_Actor::eEdge);
-             break;
-           case 212:
-             anActor->SetRepresentation(SMESH_Actor::eSurface);
-             break;
-           case 213:
-             if(anActor->IsShrunk())
-               anActor->UnShrink();
-             else
-               anActor->SetShrink();
-             break;
-           case 215:
-             anActor->SetRepresentation(SMESH_Actor::ePoint);
-             break;
-           case 1132:{
-             vtkFloatingPointType color[3];
-             anActor->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);
-
-             vtkFloatingPointType edgecolor[3];
-             anActor->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);
-
-             vtkFloatingPointType backfacecolor[3];
-             anActor->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);
-
-             vtkFloatingPointType nodecolor[3];
-             anActor->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)anActor->GetLineWidth();
-             if(Edgewidth == 0)
-               Edgewidth = 1;
-             int intValue = int(anActor->GetNodeSize());
-             vtkFloatingPointType Shrink = anActor->GetShrinkFactor();
-
-             SMESHGUI_Preferences_ColorDlg *aDlg =
-               new SMESHGUI_Preferences_ColorDlg( SMESHGUI::GetSMESHGUI() );
-             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 */
-               anActor->SetSufaceColor(vtkFloatingPointType (color.red()) / 255.,
-                                       vtkFloatingPointType (color.green()) / 255.,
-                                       vtkFloatingPointType (color.blue()) / 255.);
-               anActor->SetBackSufaceColor(vtkFloatingPointType (backfacecolor.red()) / 255.,
-                                           vtkFloatingPointType (backfacecolor.green()) / 255.,
-                                           vtkFloatingPointType (backfacecolor.blue()) / 255.);
-
-               /* edge color */
-               anActor->SetEdgeColor(vtkFloatingPointType (edgecolor.red()) / 255.,
-                                     vtkFloatingPointType (edgecolor.green()) / 255.,
-                                     vtkFloatingPointType (edgecolor.blue()) / 255.);
-
-               /* Shrink factor and size edges */
-               anActor->SetShrinkFactor(aDlg->GetIntValue(3) / 100.);
-               anActor->SetLineWidth(aDlg->GetIntValue(1));
-
-               /* Nodes color and size */
-               anActor->SetNodeColor(vtkFloatingPointType (nodecolor.red()) / 255.,
-                                     vtkFloatingPointType (nodecolor.green()) / 255.,
-                                     vtkFloatingPointType (nodecolor.blue()) / 255.);
-               anActor->SetNodeSize(aDlg->GetIntValue(2));
-
-               SMESH::SMESH_GroupBase_var aGroupObject = SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(IObject);
-               if( !aGroupObject->_is_nil() )
-               {
-                 SALOMEDS::Color aColor;
-                 aColor.R = (float)color.red() / 255.0;
-                 aColor.G = (float)color.green() / 255.0;
-                 aColor.B = (float)color.blue() / 255.0;
-                 aGroupObject->SetColor( aColor );
-               }
-
-               delete aDlg;
-             }
-             break;
-           }}
-         }
-       }
+        Handle(SALOME_InteractiveObject) IObject = It.Value();
+        if(IObject->hasEntry()){
+          if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){
+            switch(theCommandID){
+            case 211:
+              anActor->SetRepresentation(SMESH_Actor::eEdge);
+              break;
+            case 212:
+              anActor->SetRepresentation(SMESH_Actor::eSurface);
+              break;
+            case 213:
+              if(anActor->IsShrunk())
+                anActor->UnShrink();
+              else
+                anActor->SetShrink();
+              break;
+            case 215:
+              anActor->SetRepresentation(SMESH_Actor::ePoint);
+              break;
+            case 231:
+              if(anActor->GetQuadratic2DRepresentation() != SMESH_Actor::eLines)
+                anActor->SetQuadratic2DRepresentation(SMESH_Actor::eLines);
+              break;
+            case 232:
+              if(anActor->GetQuadratic2DRepresentation() != SMESH_Actor::eArcs)
+                anActor->SetQuadratic2DRepresentation(SMESH_Actor::eArcs);
+              break;
+            }
+          }
+        }
       }
       SMESH::RepaintCurrentView();
     }
     if( !selected.IsEmpty() ){
       Handle(SALOME_InteractiveObject) anIO = selected.First();
       if(!anIO.IsNull()){
-       QString aTitle;
-       SMESH_Actor::eControl aControl = SMESH_Actor::eNone;
-       if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIO->getEntry())){
-         switch ( theCommandID ){
-         case 6001:
-           aTitle = QObject::tr( "LENGTH_EDGES" );
-           aControl = SMESH_Actor::eLength;
-           break;
-         case 6018:
-           aTitle = QObject::tr( "LENGTH2D_EDGES" );
-           aControl = SMESH_Actor::eLength2D;
-           break;
-         case 6002:
-           aTitle = QObject::tr( "FREE_EDGES" );
-           aControl = SMESH_Actor::eFreeEdges;
-           break;
-         case 6003:
-           aTitle = QObject::tr( "FREE_BORDERS" );
-           aControl = SMESH_Actor::eFreeBorders;
-           break;
-         case 6004:
-           aTitle = QObject::tr( "MULTI_BORDERS" );
-           aControl = SMESH_Actor::eMultiConnection;
-           break;
-         case 6005:
-           aTitle = QObject::tr( "FREE_NODES" );
-           aControl = SMESH_Actor::eFreeNodes;
-           break;
-         case 6019:
-           aTitle = QObject::tr( "MULTI2D_BORDERS" );
-           aControl = SMESH_Actor::eMultiConnection2D;
-           break;
-         case 6011:
-           aTitle = QObject::tr( "AREA_ELEMENTS" );
-           aControl = SMESH_Actor::eArea;
-           break;
-         case 6012:
-           aTitle = QObject::tr( "TAPER_ELEMENTS" );
-           aControl = SMESH_Actor::eTaper;
-           break;
-         case 6013:
-           aTitle = QObject::tr( "ASPECTRATIO_ELEMENTS" );
-           aControl = SMESH_Actor::eAspectRatio;
-           break;
-         case 6017:
-           aTitle = QObject::tr( "ASPECTRATIO_3D_ELEMENTS" );
-           aControl = SMESH_Actor::eAspectRatio3D;
-           break;
-         case 6014:
-           aTitle = QObject::tr( "MINIMUMANGLE_ELEMENTS" );
-           aControl = SMESH_Actor::eMinimumAngle;
-           break;
-         case 6015:
-           aTitle = QObject::tr( "WARP_ELEMENTS" );
-           aControl = SMESH_Actor::eWarping;
-           break;
-         case 6016:
-           aTitle = QObject::tr( "SKEW_ELEMENTS" );
-           aControl = SMESH_Actor::eSkew;
-           break;
-         case 6009:
-           aTitle = QObject::tr( "SMESH_VOLUME" );
-           aControl = SMESH_Actor::eVolume3D;
-           break;
-         case 6021:
-           aTitle = QObject::tr( "FREE_FACES" );
-           aControl = SMESH_Actor::eFreeFaces;
-           break;
-         }
-         anActor->SetControlMode(aControl);
-         anActor->GetScalarBarActor()->SetTitle(aTitle.toLatin1().data());
-         SMESH::RepaintCurrentView();
-       }
+        SMESH_Actor::eControl aControl = SMESH_Actor::eNone;
+        if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIO->getEntry())) {
+          switch ( theCommandID ){
+          case 6001:
+            aControl = SMESH_Actor::eLength;
+            break;
+          case 6018:
+            aControl = SMESH_Actor::eLength2D;
+            break;
+          case 6002:
+            aControl = SMESH_Actor::eFreeEdges;
+            break;
+          case 6003:
+            aControl = SMESH_Actor::eFreeBorders;
+            break;
+          case 6004:
+            aControl = SMESH_Actor::eMultiConnection;
+            break;
+          case 6005:
+            aControl = SMESH_Actor::eFreeNodes;
+            break;
+          case 6019:
+            aControl = SMESH_Actor::eMultiConnection2D;
+            break;
+          case 6011:
+            aControl = SMESH_Actor::eArea;
+            break;
+          case 6012:
+            aControl = SMESH_Actor::eTaper;
+            break;
+          case 6013:
+            aControl = SMESH_Actor::eAspectRatio;
+            break;
+          case 6017:
+            aControl = SMESH_Actor::eAspectRatio3D;
+            break;
+          case 6014:
+            aControl = SMESH_Actor::eMinimumAngle;
+            break;
+          case 6015:
+            aControl = SMESH_Actor::eWarping;
+            break;
+          case 6016:
+            aControl = SMESH_Actor::eSkew;
+            break;
+          case 6009:
+            aControl = SMESH_Actor::eVolume3D;
+            break;
+          case 6021:
+            aControl = SMESH_Actor::eFreeFaces;
+            break;
+          case 6022:
+            aControl = SMESH_Actor::eMaxElementLength2D;
+            break;
+          case 6023:
+            aControl = SMESH_Actor::eMaxElementLength3D;
+            break;
+          case 6024:
+            aControl = SMESH_Actor::eBareBorderVolume;
+            break;
+          case 6025:
+            aControl = SMESH_Actor::eBareBorderFace;
+            break;
+          case 6026:
+            aControl = SMESH_Actor::eOverConstrainedVolume;
+            break;
+          case 6027:
+            aControl = SMESH_Actor::eOverConstrainedFace;
+            break;
+          case 6028:
+            aControl = SMESH_Actor::eCoincidentNodes;
+            break;
+          case 6029:
+            aControl = SMESH_Actor::eCoincidentElems1D;
+            break;
+          case 6030:
+            aControl = SMESH_Actor:: eCoincidentElems2D;
+            break;
+          case 6031:
+            aControl = SMESH_Actor::eCoincidentElems3D;
+            break;
+          }
+            
+          anActor->SetControlMode(aControl);
+          anActor->GetScalarBarActor()->SetTitle( functorToString( anActor->GetFunctor() ).toLatin1().constData() );
+          SMESH::RepaintCurrentView();
+#ifndef DISABLE_PLOT2DVIEWER
+          if(anActor->GetPlot2Histogram()) {
+            SPlot2d_Histogram* aHistogram = anActor->UpdatePlot2Histogram();
+            QString functorName = functorToString( anActor->GetFunctor());
+            QString aHistogramName("%1 : %2");
+            aHistogramName = aHistogramName.arg(anIO->getName()).arg(functorName);
+            aHistogram->setName(aHistogramName);
+            aHistogram->setHorTitle(functorName);
+            SMESH::ProcessIn2DViewers(anActor);
+          }
+#endif
+        }
       }
     }
   }
 
 
   bool CheckOIType(const Handle(SALOME_InteractiveObject) & theIO,
-                  MeshObjectType                           theType,
-                  const QString                            theInTypeName,
-                  QString &                                theOutTypeName)
+                   MeshObjectType                           theType,
+                   const QString                            theInTypeName,
+                   QString &                                theOutTypeName)
   {
     SMESH_TypeFilter aTypeFilter( theType );
     QString entry;
       _PTR(SComponent) aSComp = aSObj->GetFatherComponent();
       CORBA::String_var anID = aSComp->GetID().c_str();
       if (!strcmp(anID.in(),theIO->getEntry()))
-       return "Component";
+        return "Component";
     }
 
     QString aTypeName;
     if (
-       CheckOIType ( theIO, HYPOTHESIS,    "Hypothesis", aTypeName ) ||
-       CheckOIType ( theIO, ALGORITHM,     "Algorithm",  aTypeName ) ||
-       CheckOIType ( theIO, MESH,          "Mesh",       aTypeName ) ||
-       CheckOIType ( theIO, SUBMESH,       "SubMesh",    aTypeName ) ||
-       CheckOIType ( theIO, GROUP,         "Group",      aTypeName )
-       )
+        CheckOIType ( theIO, HYPOTHESIS,    "Hypothesis", aTypeName ) ||
+        CheckOIType ( theIO, ALGORITHM,     "Algorithm",  aTypeName ) ||
+        CheckOIType ( theIO, MESH,          "Mesh",       aTypeName ) ||
+        CheckOIType ( theIO, SUBMESH,       "SubMesh",    aTypeName ) ||
+        CheckOIType ( theIO, GROUP,         "Group",      aTypeName )
+        )
       return aTypeName;
 
     return "NoType";
     SALOME_ListIteratorOfListIO It(selected);
     for ( ; It.More(); It.Next())
       {
-       Handle(SALOME_InteractiveObject) IObject = It.Value();
-       QString Type = CheckTypeObject(IObject);
-       if (Type.compare(RefType) != 0)
-         return "Heterogeneous Selection";
+        Handle(SALOME_InteractiveObject) IObject = It.Value();
+        QString Type = CheckTypeObject(IObject);
+        if (Type.compare(RefType) != 0)
+          return "Heterogeneous Selection";
       }
 
     return RefType;
       QString cur = anIO->getComponentDataType();
       _PTR(SObject) aSO = aStudy->FindObjectID(anIO->getEntry());
       if (aSO) {
-       // check if object is reference
-       _PTR(SObject) aRefSObj;
-       aNameList.append("\n    - ");
-       if ( aSO->ReferencedObject( aRefSObj ) ) {
-         QString aRefName = QString::fromStdString ( aRefSObj->GetName() );
-         aNameList.append( aRefName );
-         cur = QString::fromStdString ( aRefSObj->GetFatherComponent()->ComponentDataType() );
-       }
-       else
-         aNameList.append(anIO->getName());
-       objectCount++;
+        // check if object is reference
+        _PTR(SObject) aRefSObj;
+        aNameList.append("\n    - ");
+        if ( aSO->ReferencedObject( aRefSObj ) ) {
+          QString aRefName = QString::fromStdString ( aRefSObj->GetName() );
+          aNameList.append( aRefName );
+          cur = QString::fromStdString ( aRefSObj->GetFatherComponent()->ComponentDataType() );
+        }
+        else
+          aNameList.append(anIO->getName());
+        objectCount++;
       }
 
       if( aParentComponent.isNull() )
 
     if ( aParentComponent != SMESHGUI::GetSMESHGUI()->name() )  {
       SUIT_MessageBox::warning( SMESHGUI::desktop(),
-                               QObject::tr("ERR_ERROR"),
-                               QObject::tr("NON_SMESH_OBJECTS_SELECTED").arg( SMESHGUI::GetSMESHGUI()->moduleName() ) );
+                                QObject::tr("ERR_ERROR"),
+                                QObject::tr("NON_SMESH_OBJECTS_SELECTED").arg( SMESHGUI::GetSMESHGUI()->moduleName() ) );
       return;
     }
     // VSR 17/11/04: check if all objects selected belong to SMESH component <-- finish
     if (SUIT_MessageBox::warning
-       (SMESHGUI::desktop(),
-        QObject::tr("SMESH_WRN_WARNING"),
-        QObject::tr("SMESH_REALLY_DELETE").arg( objectCount ).arg( aNameList ),
-        SUIT_MessageBox::Yes | SUIT_MessageBox::No,
-        SUIT_MessageBox::Yes) != SUIT_MessageBox::Yes)
+        (SMESHGUI::desktop(),
+         QObject::tr("SMESH_WRN_WARNING"),
+         QObject::tr("SMESH_REALLY_DELETE").arg( objectCount ).arg( aNameList ),
+         SUIT_MessageBox::Yes | SUIT_MessageBox::No,
+         SUIT_MessageBox::Yes) != SUIT_MessageBox::Yes)
       return;
 
     SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
-    SUIT_ViewManager* vm = anApp->activeViewManager();
-    int nbSf = vm->getViewsCount();
 
+    // Put the whole hierarchy of sub-objects of the selected SO's into a list and
+    // then treat them all starting from the deepest objects (at list back)
+    std::list< _PTR(SObject) > listSO;
     SALOME_ListIteratorOfListIO It(selected);
-
-    aStudyBuilder->NewCommand();  // There is a transaction
-    for( ; It.More(); It.Next()){ // loop on selected IO's
+    for( ; It.More(); It.Next()) // loop on selected IO's
+    {
       Handle(SALOME_InteractiveObject) IObject = It.Value();
       if(IObject->hasEntry()) {
-       _PTR(SObject) aSO = aStudy->FindObjectID(IObject->getEntry());
-
-       // disable removal of "SMESH" component object
-       if(aSO->FindAttribute(anAttr, "AttributeIOR")){
-         anIOR = anAttr;
-         if ( engineIOR() == anIOR->Value().c_str() )
-           continue;
-       }
-       //Check the referenced object
-       _PTR(SObject) aRefSObject;
-       if ( aSO && aSO->ReferencedObject( aRefSObject ) )
-         aSO = aRefSObject; // Delete main Object instead of reference
-
-        // put the whole hierarchy of sub-objects of the selected SO into a list and
-        // then treat them all starting from the deepest objects (at list back)
-
-        std::list< _PTR(SObject) > listSO;
+        _PTR(SObject) aSO = aStudy->FindObjectID(IObject->getEntry());
+
+        // disable removal of "SMESH" component object
+        if(aSO->FindAttribute(anAttr, "AttributeIOR")){
+          anIOR = anAttr;
+          if ( engineIOR() == anIOR->Value().c_str() )
+            continue;
+        }
+        //Check the referenced object
+        _PTR(SObject) aRefSObject;
+        if ( aSO && aSO->ReferencedObject( aRefSObject ) )
+          aSO = aRefSObject; // Delete main Object instead of reference
+
         listSO.push_back( aSO );
         std::list< _PTR(SObject) >::iterator itSO = listSO.begin();
         for ( ; itSO != listSO.end(); ++itSO ) {
           for (it->InitEx(false); it->More(); it->Next())
             listSO.push_back( it->Value() );
         }
+      }
+    }
+    // Check if none of objects to delete is referred from outside
+    std::list< _PTR(SObject) >::reverse_iterator ritSO;
+    for ( ritSO = listSO.rbegin(); ritSO != listSO.rend(); ++ritSO )
+    {
+      _PTR(SObject) SO = *ritSO;
+      if ( !SO ) continue;
+      std::vector<_PTR(SObject)> aReferences = aStudy->FindDependances( *ritSO  );
+      for (size_t i = 0; i < aReferences.size(); i++) {
+        _PTR(SComponent) aComponent = aReferences[i]->GetFatherComponent();
+        std::string type = aComponent->ComponentDataType();
+        if ( type != "SMESH" )
+        {
+          SUIT_MessageBox::warning( anApp->desktop(),
+                                    QObject::tr("WRN_WARNING"),
+                                    QObject::tr("DEP_OBJECT") );
+          return; // outside SMESH, there is an object depending on a SMESH object 
+        }
+      }
+    }
 
-        // treat SO's in the list starting from the back
-
-        std::list< _PTR(SObject) >::reverse_iterator ritSO = listSO.rbegin();
-        for ( ; ritSO != listSO.rend(); ++ritSO ) {
-          _PTR(SObject) SO = *ritSO;
-          if ( !SO ) continue;
-          std::string anEntry = SO->GetID();
-
-          /** Erase graphical object **/
-         if(SO->FindAttribute(anAttr, "AttributeIOR")){
-           QVector<SUIT_ViewWindow*> aViews = vm->getViews();
-           for(int i = 0; i < nbSf; i++){
-             SUIT_ViewWindow *sf = aViews[i];
-             if(SMESH_Actor* anActor = SMESH::FindActorByEntry(sf,anEntry.c_str())){
-               SMESH::RemoveActor(sf,anActor);
-             }
-           }
-         }
-
-          /** Remove an object from data structures **/
-          SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( SMESH::SObjectToObject( SO ));
-          SMESH::SMESH_subMesh_var   aSubMesh = SMESH::SMESH_subMesh::_narrow( SMESH::SObjectToObject( SO ));
-          if ( !aGroup->_is_nil() ) {                          // DELETE GROUP
-            SMESH::SMESH_Mesh_var aMesh = aGroup->GetMesh();
-            aMesh->RemoveGroup( aGroup );
+    // Treat SO's in the list starting from the back
+    aStudyBuilder->NewCommand();  // There is a transaction
+    for ( ritSO = listSO.rbegin(); ritSO != listSO.rend(); ++ritSO )
+    {
+      _PTR(SObject) SO = *ritSO;
+      if ( !SO ) continue;
+      std::string anEntry = SO->GetID();
+
+      /** Erase graphical object **/
+      if(SO->FindAttribute(anAttr, "AttributeIOR")){
+        ViewManagerList aViewMenegers = anApp->viewManagers();
+        ViewManagerList::const_iterator it = aViewMenegers.begin();
+        for( ; it != aViewMenegers.end(); it++) {         
+          SUIT_ViewManager* vm = *it;
+          int nbSf = vm ? vm->getViewsCount() : 0;
+          if(vm) {
+            QVector<SUIT_ViewWindow*> aViews = vm->getViews();
+            for(int i = 0; i < nbSf; i++){
+              SUIT_ViewWindow *sf = aViews[i];
+              if(SMESH_Actor* anActor = SMESH::FindActorByEntry(sf,anEntry.c_str())){
+                SMESH::RemoveActor(sf,anActor);
+              }
+            }
           }
-          else if ( !aSubMesh->_is_nil() ) {                   // DELETE SUBMESH
-            SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather();
-            aMesh->RemoveSubMesh( aSubMesh );
+        }
+      }
+      /** Remove an object from data structures **/
+      SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( SMESH::SObjectToObject( SO ));
+      SMESH::SMESH_subMesh_var   aSubMesh = SMESH::SMESH_subMesh::_narrow( SMESH::SObjectToObject( SO ));
+      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 );
 
-            _PTR(SObject) aMeshSO = SMESH::FindSObject(aMesh);
-            if (aMeshSO)
-              SMESH::ModifiedMesh(aMeshSO, false, aMesh->NbNodes()==0);
-          }
-          else {
-            IObject = new SALOME_InteractiveObject
-              ( anEntry.c_str(), engineIOR().toLatin1().data(), SO->GetName().c_str() );
-            QString objType = CheckTypeObject(IObject);
-            if ( objType == "Hypothesis" || objType == "Algorithm" ) {// DELETE HYPOTHESIS
-              SMESH::RemoveHypothesisOrAlgorithmOnMesh(IObject);
-              aStudyBuilder->RemoveObjectWithChildren( SO );
-            }
-            else {// default action: remove SObject from the study
+        _PTR(SObject) aMeshSO = SMESH::FindSObject(aMesh);
+        if (aMeshSO)
+          SMESH::ModifiedMesh(aMeshSO, false, aMesh->NbNodes()==0);
+      }
+      else {
+        Handle(SALOME_InteractiveObject) IObject = new SALOME_InteractiveObject
+          ( anEntry.c_str(), engineIOR().toLatin1().data(), SO->GetName().c_str() );
+        QString objType = CheckTypeObject(IObject);
+        if ( objType == "Hypothesis" || objType == "Algorithm" ) {// DELETE HYPOTHESIS
+          SMESH::RemoveHypothesisOrAlgorithmOnMesh(IObject);
+          aStudyBuilder->RemoveObjectWithChildren( SO );
+        }
+        else {// default action: remove SObject from the study
               // san - it's no use opening a transaction here until UNDO/REDO is provided in SMESH
               //SUIT_Operation *op = new SALOMEGUI_ImportOperation(myActiveStudy);
               //op->start();
-              aStudyBuilder->RemoveObjectWithChildren( SO );
-              //op->finish();
-            }
-          }
-       } /* listSO back loop */
-      } /* IObject->hasEntry() */
-    } /* more/next */
+          aStudyBuilder->RemoveObjectWithChildren( SO );
+          //op->finish();
+        }
+      }
+    } /* listSO back loop */
+
     aStudyBuilder->CommitCommand();
 
     /* Clear any previous selection */
 
     SMESHGUI::GetSMESHGUI()->updateObjBrowser();
   }
-//}
+//} namespace
 
 extern "C" {
   SMESHGUI_EXPORT CAM_Module* createModule()
   {
     return new SMESHGUI();
   }
+
+  SMESHGUI_EXPORT  char* getModuleVersion() {
+    return (char*)SMESH_VERSION_STR;
+  }
 }
 
 SMESH::SMESH_Gen_var SMESHGUI::myComponentSMESH = SMESH::SMESH_Gen::_nil();
@@ -1063,12 +1817,14 @@ SMESH::SMESH_Gen_var SMESHGUI::myComponentSMESH = SMESH::SMESH_Gen::_nil();
  */
 //=============================================================================
 SMESHGUI::SMESHGUI() :
-SalomeApp_Module( "SMESH" )
+SalomeApp_Module( "SMESH" ),
+LightApp_Module( "SMESH" )
 {
   if ( CORBA::is_nil( myComponentSMESH ) )
   {
     CORBA::Boolean anIsEmbeddedMode;
     myComponentSMESH = SMESH_Client::GetSMESHGen(getApp()->orb(),anIsEmbeddedMode);
+    MESSAGE("-------------------------------> anIsEmbeddedMode=" << anIsEmbeddedMode);
 
     //  0019923: EDF 765 SMESH : default values of hypothesis
     SUIT_ResourceMgr* aResourceMgr = SMESH::GetResourceMgr(this);
@@ -1076,6 +1832,14 @@ SalomeApp_Module( "SMESH" )
     myComponentSMESH->SetBoundaryBoxSegmentation( nbSeg );
     nbSeg = aResourceMgr->integerValue( "SMESH", "nb_segments_per_edge", 15 );
     myComponentSMESH->SetDefaultNbSegments( nbSeg );
+
+    const char* options[] = { "historical_python_dump", "forget_mesh_on_hyp_modif" };
+    for ( size_t i = 0; i < sizeof(options)/sizeof(char*); ++i )
+      if ( aResourceMgr->hasValue( "SMESH", options[i] ))
+      {
+        QString val = aResourceMgr->stringValue( "SMESH", options[i] );
+        myComponentSMESH->SetOption( options[i], val.toLatin1().constData() );
+      }
   }
 
   myActiveDialogBox = 0;
@@ -1083,8 +1847,15 @@ SalomeApp_Module( "SMESH" )
   myState = -1;
   myDisplayer = 0;
 
+  myEventCallbackCommand = vtkCallbackCommand::New();
+  myEventCallbackCommand->Delete();
+  myEventCallbackCommand->SetClientData( this );
+  myEventCallbackCommand->SetCallback( SMESHGUI::ProcessEvents );
+  myPriority = 0.0;
+
   SMESH::GetFilterManager();
   SMESH::GetPattern();
+  SMESH::GetMeasurements();
 
   /* load resources for all available meshers */
   SMESH::InitAvailableHypotheses();
@@ -1097,8 +1868,12 @@ SalomeApp_Module( "SMESH" )
 //=============================================================================
 SMESHGUI::~SMESHGUI()
 {
-  SMESH::GetFilterManager()->Destroy();
+#ifdef WITHGENERICOBJ
+  SMESH::GetFilterManager()->UnRegister();
+  SMESH::GetMeasurements()->UnRegister();
+#endif
   SMESH::GetFilterManager() = SMESH::FilterManager::_nil();
+  SMESH::GetMeasurements() = SMESH::Measurements::_nil();
 }
 
 //=============================================================================
@@ -1115,13 +1890,22 @@ LightApp_SelectionMgr* SMESHGUI::selectionMgr()
     return 0;
 }
 
-bool SMESHGUI::automaticUpdate()
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+bool SMESHGUI::automaticUpdate(unsigned int requestedSize, bool* limitExceeded)
 {
   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
   if ( !resMgr )
     return false;
 
-  return resMgr->booleanValue( "SMESH", "auto_update", false );
+  bool autoUpdate  = resMgr->booleanValue( "SMESH", "auto_update",  false );
+  long updateLimit = resMgr->integerValue( "SMESH", "update_limit", 500000 );
+  bool exceeded = updateLimit > 0 && requestedSize > updateLimit;
+  if ( limitExceeded ) *limitExceeded = autoUpdate && exceeded;
+  return autoUpdate && !exceeded;
 }
 
 //=============================================================================
@@ -1156,7 +1940,7 @@ SMESHGUI* SMESHGUI::GetSMESHGUI()
     {
       _PTR(Study) aStudy = study->studyDS();
       if ( aStudy )
-       GetSMESHGen()->SetCurrentStudy( _CAST(Study,aStudy)->GetStudy() );
+        GetSMESHGen()->SetCurrentStudy( _CAST(Study,aStudy)->GetStudy() );
     }
   }
 
@@ -1221,6 +2005,16 @@ void SMESHGUI::EmitSignalCloseAllDialogs()
   emit SignalCloseAllDialogs();
 }
 
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+void SMESHGUI::EmitSignalVisibilityChanged()
+{
+  emit SignalVisibilityChanged();
+}
+
 //=============================================================================
 /*!
  *
@@ -1275,9 +2069,15 @@ SalomeApp_Study* SMESHGUI::activeStudy()
  *
  */
 //=============================================================================
-char* SMESHGUI::JoinObjectParameters(const QStringList& theParametersList)
+void SMESHGUI::Modified( bool theIsUpdateActions )
 {
-  return theParametersList.join(":").toLatin1().data();
+  if( SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() ) ) {
+    if( SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( app->activeStudy() ) ) {
+      appStudy->Modified();
+      if( theIsUpdateActions )
+        app->updateActions();
+    }
+  }
 }
 
 //=============================================================================
@@ -1308,8 +2108,8 @@ static int isStudyLocked(_PTR(Study) theStudy){
 static bool checkLock(_PTR(Study) theStudy) {
   if (isStudyLocked(theStudy)) {
     SUIT_MessageBox::warning( SMESHGUI::desktop(),
-                             QObject::tr("WRN_WARNING"),
-                             QObject::tr("WRN_STUDY_LOCKED") );
+                              QObject::tr("WRN_WARNING"),
+                              QObject::tr("WRN_STUDY_LOCKED") );
     return true;
   }
   return false;
@@ -1351,15 +2151,18 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
 
   //QAction* act = action( theCommandID );
 
-  switch (theCommandID)        {
-  case 33:                                     // DELETE
+  switch (theCommandID) {
+  case 33:                                      // DELETE
     if(checkLock(aStudy)) break;
     OnEditDelete();
     break;
 
-  case 113:                                    // IMPORT
+  case 116:
+  case 115:
+  case 117:
+  case 113:
   case 112:
-  case 111:
+  case 111:                                     // IMPORT
     {
       if(checkLock(aStudy)) break;
       ::ImportMeshesFromFile(GetSMESHGen(),theCommandID);
@@ -1385,7 +2188,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       break;
     }
 
-  case 122:                                    // EXPORT MED
+  case 122:                                     // EXPORT MED
   case 121:
   case 123:
   case 124:
@@ -1393,12 +2196,16 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case 126:
   case 140:
   case 141:
+  case 142:
+  case 143:
+  case 144:
+  case 145:
     {
       ::ExportMeshToFile(theCommandID);
       break;
     }
 
-  case 200:                                    // SCALAR BAR
+  case 200:                                     // SCALAR BAR
     {
       LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
       SALOME_ListIO selected;
@@ -1406,12 +2213,15 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
         aSel->selectedObjects( selected );
 
       if( selected.Extent() ) {
-       Handle(SALOME_InteractiveObject) anIO = selected.First();
-       if( anIO->hasEntry() ) {
-         if( SMESH_Actor* anActor = SMESH::FindActorByEntry( anIO->getEntry() ) ) {
-           anActor->SetControlMode( SMESH_Actor::eNone );
-         }
-       }
+        Handle(SALOME_InteractiveObject) anIO = selected.First();
+        if( anIO->hasEntry() ) {
+          if( SMESH_Actor* anActor = SMESH::FindActorByEntry( anIO->getEntry() ) ) {
+            anActor->SetControlMode( SMESH_Actor::eNone );
+#ifndef DISABLE_PLOT2DVIEWER
+            SMESH::ProcessIn2DViewers(anActor,SMESH::RemoveFrom2dViewer);
+#endif
+          }
+        }
       }
       break;
     }
@@ -1420,6 +2230,28 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       SMESHGUI_Preferences_ScalarBarDlg::ScalarBarProperties( this );
       break;
     }
+  case 2021:
+    {
+      // dump control distribution data to the text file
+      ::SaveDistribution();
+      break;
+    }
+
+  case 2022:
+    {
+      // show/ distribution
+      ::ShowDistribution();
+      break;
+    }
+
+#ifndef DISABLE_PLOT2DVIEWER
+  case 2023:
+    {
+      // plot distribution
+      ::PlotDistribution();
+      break;
+    }
+#endif
 
     // Auto-color
   case 1136:
@@ -1432,21 +2264,29 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
 
   case 1134: // Clipping
   case 1133: // Tranparency
-  case 1132: // Colors / Size
+  case 1132: // Display preferences (colors, shrink size, line width, ...)
 
     // Display Mode
   case 215: // Nodes
   case 213: // Nodes
   case 212: // Nodes
   case 211: // Nodes
-    ::SetDisplayMode(theCommandID);
+    ::SetDisplayMode(theCommandID, myMarkerMap);
   break;
 
-    // Display Entity
+  //2D quadratic representation
+  case 231:
+  case 232:
+    ::SetDisplayMode(theCommandID, myMarkerMap);
+  break;
+
+  // Display Entity
+  case 216: // 0D elements
   case 217: // Edges
   case 218: // Faces
   case 219: // Volumes
   case 220: // All Entity
+  case 222: // Balls
     ::SetDisplayEntity(theCommandID);
   break;
 
@@ -1458,16 +2298,16 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       SALOME_ListIteratorOfListIO it(selected);
       for( ; it.More(); it.Next()) {
         Handle(SALOME_InteractiveObject) anIObject = it.Value();
-       if(anIObject->hasEntry()) {
-         if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIObject->getEntry())){
-           anActor->SetFacesOriented( !anActor->GetFacesOriented() );
-         }
-       }
+        if(anIObject->hasEntry()) {
+          if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIObject->getEntry())){
+            anActor->SetFacesOriented( !anActor->GetFacesOriented() );
+          }
+        }
       }
       break;
     }
 
-  case 214:                                    // UPDATE
+  case 214:                                     // UPDATE
     {
       if(checkLock(aStudy)) break;
       try {
@@ -1490,15 +2330,15 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       break;
     }
 
-  case 300:                                    // ERASE
-  case 301:                                    // DISPLAY
-  case 302:                                    // DISPLAY ONLY
+  case 300:                                     // ERASE
+  case 301:                                     // DISPLAY
+  case 302:                                     // DISPLAY ONLY
     {
       SMESH::EDisplaing anAction;
       switch (theCommandID) {
-      case 300:        anAction = SMESH::eErase; break;
-      case 301:        anAction = SMESH::eDisplay; break;
-      case 302:        anAction = SMESH::eDisplayOnly; break;
+      case 300: anAction = SMESH::eErase; break;
+      case 301: anAction = SMESH::eDisplay; break;
+      case 302: anAction = SMESH::eDisplayOnly; break;
       }
 
       LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
@@ -1507,7 +2347,10 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
         aSel->selectedObjects( sel_objects );
 
       if( theCommandID==302 )
-       startOperation( myEraseAll );
+      {
+        MESSAGE("anAction = SMESH::eDisplayOnly");
+        startOperation( myEraseAll );
+      }
 
       extractContainers( sel_objects, to_process );
 
@@ -1518,19 +2361,29 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
         if (vtkwnd) {
           SALOME_ListIteratorOfListIO It( to_process );
           for ( ; It.More(); It.Next()) {
+                MESSAGE("---");
             Handle(SALOME_InteractiveObject) IOS = It.Value();
             if (IOS->hasEntry()) {
-              if (!SMESH::UpdateView(anAction, IOS->getEntry()))
+                MESSAGE("---");
+              if (!SMESH::UpdateView(anAction, IOS->getEntry())) {
+                SMESHGUI::GetSMESHGUI()->EmitSignalVisibilityChanged();
                 break; // PAL16774 (Crash after display of many groups)
+              }
               if (anAction == SMESH::eDisplayOnly)
+              {
+                MESSAGE("anAction = SMESH::eDisplayOnly");
                 anAction = SMESH::eDisplay;
+              }
             }
           }
         }
 
         // PAL13338 + PAL15161 -->
-        if ( ( theCommandID==301 || theCommandID==302 ) && !checkLock(aStudy))
+        if ( ( theCommandID==301 || theCommandID==302 ) && !checkLock(aStudy)) {
+                MESSAGE("anAction = SMESH::eDisplayOnly");
           SMESH::UpdateView();
+          SMESHGUI::GetSMESHGUI()->EmitSignalVisibilityChanged();
+        }
         // PAL13338 + PAL15161 <--
       }
       catch (...) { // PAL16774 (Crash after display of many groups)
@@ -1538,28 +2391,29 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       }
 
       if (anAction == SMESH::eErase) {
-       SALOME_ListIO l1;
-       aSel->setSelectedObjects( l1 );
+        MESSAGE("anAction == SMESH::eErase");
+        SALOME_ListIO l1;
+        aSel->setSelectedObjects( l1 );
       }
       else
-       aSel->setSelectedObjects( to_process );
+        aSel->setSelectedObjects( to_process );
 
       break;
     }
 
-  case 400:                                    // NODES
+  case 4000:                                    // NODES
     {
       if(checkLock(aStudy)) break;
 
       if ( vtkwnd ) {
-       EmitSignalDeactivateDialog();
+        EmitSignalDeactivateDialog();
 
-       ( new SMESHGUI_NodesDlg( this ) )->show();
+        ( new SMESHGUI_NodesDlg( this ) )->show();
       }
       else {
-       SUIT_MessageBox::warning(desktop(),
-                                tr("SMESH_WRN_WARNING"),
-                                tr("SMESH_WRN_VIEWER_VTK"));
+        SUIT_MessageBox::warning(desktop(),
+                                 tr("SMESH_WRN_WARNING"),
+                                 tr("SMESH_WRN_VIEWER_VTK"));
       }
       break;
     }
@@ -1574,33 +2428,22 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     break;
   }
 
-  case 406:                                    // MOVE NODE
-    {
-      if ( !vtkwnd )
-      {
-        SUIT_MessageBox::warning( desktop(), tr( "SMESH_WRN_WARNING" ),
-                                 tr( "NOT_A_VTK_VIEWER" ) );
-        break;
-      }
-
-      if(checkLock(aStudy)) break;
-      ( new SMESHGUI_MoveNodesDlg( this ) )->show();
-      break;
-    }
-
-  case 701:                                    // COMPUTE MESH
-  case 711:                                    // PRECOMPUTE MESH
-    {
-      if (checkLock(aStudy)) break;
-      startOperation( theCommandID );
-    }
-    break;
-
+  case 701: // COMPUTE MESH
+  case 711: // PRECOMPUTE MESH
+  case 712: // EVALUATE MESH
+  case 713: // MESH ORDER
   case 702: // Create mesh
   case 703: // Create sub-mesh
   case 704: // Edit mesh/sub-mesh
     startOperation( theCommandID );
     break;
+  case 705: // copy mesh
+    {
+      if (checkLock(aStudy)) break;
+      EmitSignalDeactivateDialog();
+      ( new SMESHGUI_CopyMeshDlg( this ) )->show();
+    }
+    break;
   case 710: // Build compound mesh
     {
       if (checkLock(aStudy)) break;
@@ -1615,7 +2458,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       if ( !vtkwnd )
       {
         SUIT_MessageBox::warning( desktop(), tr( "SMESH_WRN_WARNING" ),
-                                 tr( "NOT_A_VTK_VIEWER" ) );
+                                  tr( "NOT_A_VTK_VIEWER" ) );
         break;
       }
 
@@ -1638,14 +2481,15 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
         ( new SMESHGUI_UnionOfTwoTrianglesDlg( this ) )->show();
       break;
     }
-    case 409: // Change orientation
-    case 410: // Union of triangles
-    case 411: // Cutting of quadrangles
+  case 409: // Change orientation
+  case 410: // Union of triangles
+  case 411: // Cutting of quadrangles
+  case 419: // Splitting volumes into tetrahedra
     {
       if ( !vtkwnd )
       {
         SUIT_MessageBox::warning( desktop(), tr( "SMESH_WRN_WARNING" ),
-                                 tr( "NOT_A_VTK_VIEWER" ) );
+                                  tr( "NOT_A_VTK_VIEWER" ) );
         break;
       }
 
@@ -1658,6 +2502,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
         aDlg = new SMESHGUI_ChangeOrientationDlg(this);
       else if ( theCommandID == 410 )
         aDlg = new SMESHGUI_UnionOfTrianglesDlg(this);
+      else if ( theCommandID == 419 )
+        aDlg = new SMESHGUI_CuttingIntoTetraDlg(this);
       else
         aDlg = new SMESHGUI_CuttingOfQuadsDlg(this);
 
@@ -1668,12 +2514,12 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     {
       if(checkLock(aStudy)) break;
       if( vtkwnd ) {
-       EmitSignalDeactivateDialog();
-       ( new SMESHGUI_SmoothingDlg( this ) )->show();
+        EmitSignalDeactivateDialog();
+        ( new SMESHGUI_SmoothingDlg( this ) )->show();
       }
       else {
-       SUIT_MessageBox::warning(desktop(),
-                                tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
+        SUIT_MessageBox::warning(desktop(),
+                                 tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
       }
       break;
     }
@@ -1681,11 +2527,11 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     {
       if (checkLock(aStudy)) break;
       if (vtkwnd) {
-       EmitSignalDeactivateDialog();
-       ( new SMESHGUI_ExtrusionDlg ( this ) )->show();
+        EmitSignalDeactivateDialog();
+        ( new SMESHGUI_ExtrusionDlg ( this ) )->show();
       } else {
-       SUIT_MessageBox::warning(desktop(),
-                                tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
+        SUIT_MessageBox::warning(desktop(),
+                                 tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
       }
       break;
     }
@@ -1693,12 +2539,12 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     {
       if(checkLock(aStudy)) break;
       if( vtkwnd ) {
-       EmitSignalDeactivateDialog();
-       ( new SMESHGUI_RevolutionDlg( this ) )->show();
+        EmitSignalDeactivateDialog();
+        ( new SMESHGUI_RevolutionDlg( this ) )->show();
       }
       else {
-       SUIT_MessageBox::warning(desktop(),
-                                tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
+        SUIT_MessageBox::warning(desktop(),
+                                 tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
       }
       break;
     }
@@ -1712,8 +2558,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
         ( new SMESHGUI_MeshPatternDlg( this ) )->show();
       }
       else {
-       SUIT_MessageBox::warning(desktop(),
-                                tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
+        SUIT_MessageBox::warning(desktop(),
+                                 tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
       }
       break;
     }
@@ -1721,30 +2567,20 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     {
       if (checkLock(aStudy)) break;
       if (vtkwnd) {
-       EmitSignalDeactivateDialog();
-       ( new SMESHGUI_ExtrusionAlongPathDlg( this ) )->show();
-      } else {
-       SUIT_MessageBox::warning(desktop(),
-                                tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
-      }
-      break;
-    }
-  case 417: // Convert mesh to quadratic
-    {
-    startOperation( 417 );
-      /*      if (checkLock(aStudy)) break;
-      if (vtkwnd) {
-       EmitSignalDeactivateDialog();
-       new SMESHGUI_ConvToQuadDlg();
+        EmitSignalDeactivateDialog();
+        ( new SMESHGUI_ExtrusionAlongPathDlg( this ) )->show();
       } else {
-       SUIT_MessageBox::warning(desktop(),
-                               tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
-                              }*/
+        SUIT_MessageBox::warning(desktop(),
+                                 tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
+      }
       break;
     }
-  case 806:                                     // CREATE GEO GROUP
+  case 417: // Convert mesh to quadratic
+  case 418: // create 2D mesh from 3D
+  case 420: // Reorient faces
+  case 806: // CREATE GEO GROUP
     {
-      startOperation( 806 );
+      startOperation( theCommandID );
       break;
     }
   case 801:                                     // CREATE GROUP
@@ -1752,7 +2588,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       if ( !vtkwnd )
       {
         SUIT_MessageBox::warning( desktop(), tr( "SMESH_WRN_WARNING" ),
-                                 tr( "NOT_A_VTK_VIEWER" ) );
+                                  tr( "NOT_A_VTK_VIEWER" ) );
         break;
       }
 
@@ -1767,7 +2603,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
 
       int nbSel = selected.Extent();
       if (nbSel == 1) {
-       // check if mesh is selected
+        // check if mesh is selected
         aMesh = SMESH::GetMeshByIO( selected.First() );
       }
       SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg( this, aMesh);
@@ -1780,7 +2616,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       if ( !vtkwnd )
       {
         SUIT_MessageBox::warning( desktop(), tr( "SMESH_WRN_WARNING" ),
-                                 tr( "NOT_A_VTK_VIEWER" ) );
+                                  tr( "NOT_A_VTK_VIEWER" ) );
         break;
       }
 
@@ -1794,52 +2630,61 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
 
       int nbSel = selected.Extent();
       if (nbSel == 1) {
-       // check if submesh is selected
-       Handle(SALOME_InteractiveObject) IObject = selected.First();
-       if (IObject->hasEntry()) {
-         _PTR(SObject) aSObj = aStudy->FindObjectID(IObject->getEntry());
-         if( aSObj ) {
-           SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( SMESH::SObjectToObject( aSObj ) );
-           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();
-               if (aNodes->length() > 0) {
-                 SMESH::SMESH_Group_var aGroup = SMESH::AddGroup(aMesh, SMESH::NODE, aName + "_Nodes");
-                 aGroup->Add(aNodes.inout());
-               }
-               if (aEdges->length() > 0) {
-                 SMESH::SMESH_Group_var aGroup = SMESH::AddGroup(aMesh, SMESH::EDGE, aName + "_Edges");
-                 aGroup->Add(aEdges.inout());
-               }
-               if (aFaces->length() > 0) {
-                 SMESH::SMESH_Group_var aGroup = SMESH::AddGroup(aMesh, SMESH::FACE, aName + "_Faces");
-                 aGroup->Add(aFaces.inout());
-               }
-               if (aVolumes->length() > 0) {
-                 SMESH::SMESH_Group_var aGroup = SMESH::AddGroup(aMesh, SMESH::VOLUME, aName + "_Volumes");
-                 aGroup->Add(aVolumes.inout());
-               }
-               updateObjBrowser();
-
-             }
+        // check if submesh is selected
+        Handle(SALOME_InteractiveObject) IObject = selected.First();
+        if (IObject->hasEntry()) {
+          _PTR(SObject) aSObj = aStudy->FindObjectID(IObject->getEntry());
+          if( aSObj ) {
+            SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( SMESH::SObjectToObject( aSObj ) );
+            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();
+                QStringList anEntryList;
+                if (aNodes->length() > 0) {
+                  SMESH::SMESH_Group_var aGroup = SMESH::AddGroup(aMesh, SMESH::NODE, aName + "_Nodes");
+                  aGroup->Add(aNodes.inout());
+                  if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( aGroup ) )
+                    anEntryList.append( aSObject->GetID().c_str() );
+                }
+                if (aEdges->length() > 0) {
+                  SMESH::SMESH_Group_var aGroup = SMESH::AddGroup(aMesh, SMESH::EDGE, aName + "_Edges");
+                  aGroup->Add(aEdges.inout());
+                  if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( aGroup ) )
+                    anEntryList.append( aSObject->GetID().c_str() );
+                }
+                if (aFaces->length() > 0) {
+                  SMESH::SMESH_Group_var aGroup = SMESH::AddGroup(aMesh, SMESH::FACE, aName + "_Faces");
+                  aGroup->Add(aFaces.inout());
+                  if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( aGroup ) )
+                    anEntryList.append( aSObject->GetID().c_str() );
+                }
+                if (aVolumes->length() > 0) {
+                  SMESH::SMESH_Group_var aGroup = SMESH::AddGroup(aMesh, SMESH::VOLUME, aName + "_Volumes");
+                  aGroup->Add(aVolumes.inout());
+                  if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( aGroup ) )
+                    anEntryList.append( aSObject->GetID().c_str() );
+                }
+                updateObjBrowser();
+                anApp->browseObjects( anEntryList );
+              }
               catch(const SALOME::SALOME_Exception & S_ex){
-               SalomeApp_Tools::QtCatchCorbaException(S_ex);
-             }
-           }
-         }
-       }
+                SalomeApp_Tools::QtCatchCorbaException(S_ex);
+              }
+            }
+          }
+        }
       }
       else if(nbSel==0) {
         SUIT_MessageBox::warning(desktop(),
-                                tr("SMESH_WRN_WARNING"),
-                                tr("SMESH_WRN_NO_AVAILABLE_DATA"));
+                                 tr("SMESH_WRN_WARNING"),
+                                 tr("SMESH_WRN_NO_AVAILABLE_DATA"));
       }
       break;
     }
@@ -1849,7 +2694,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       if ( !vtkwnd )
       {
         SUIT_MessageBox::warning( desktop(), tr( "SMESH_WRN_WARNING" ),
-                                 tr( "NOT_A_VTK_VIEWER" ) );
+                                  tr( "NOT_A_VTK_VIEWER" ) );
         break;
       }
 
@@ -1868,16 +2713,16 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
         SMESH::SMESH_GroupBase_var aGroup =
           SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(It.Value());
         if (!aGroup->_is_nil()) {
-         nbSelectedGroups++;
+          nbSelectedGroups++;
           SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg( this, aGroup);
           aDlg->show();
-       }
+        }
       }
       if (nbSelectedGroups == 0)
-       {
-         SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg( this, SMESH::SMESH_GroupBase::_nil());
-         aDlg->show();
-       }
+        {
+          SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg( this, SMESH::SMESH_GroupBase::_nil());
+          aDlg->show();
+        }
       break;
     }
 
@@ -1885,8 +2730,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     {
       if(checkLock(aStudy)) break;
       if (myState == 800) {
-       SMESHGUI_GroupDlg *aDlg = (SMESHGUI_GroupDlg*) myActiveDialogBox;
-       if (aDlg) aDlg->onAdd();
+        SMESHGUI_GroupDlg *aDlg = (SMESHGUI_GroupDlg*) myActiveDialogBox;
+        if (aDlg) aDlg->onAdd();
       }
       break;
     }
@@ -1895,8 +2740,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     {
       if(checkLock(aStudy)) break;
       if (myState == 800) {
-       SMESHGUI_GroupDlg *aDlg = (SMESHGUI_GroupDlg*) myActiveDialogBox;
-       if (aDlg) aDlg->onRemove();
+        SMESHGUI_GroupDlg *aDlg = (SMESHGUI_GroupDlg*) myActiveDialogBox;
+        if (aDlg) aDlg->onRemove();
       }
       break;
     }
@@ -1906,7 +2751,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       if ( !vtkwnd )
       {
         SUIT_MessageBox::warning( desktop(), tr( "SMESH_WRN_WARNING" ),
-                                 tr( "NOT_A_VTK_VIEWER" ) );
+                                  tr( "NOT_A_VTK_VIEWER" ) );
         break;
       }
 
@@ -1926,7 +2771,16 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
         if (!aGroup->_is_nil()) {
           SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg( this, aGroup, true );
           aDlg->show();
-       }
+        }
+        else
+        {
+          SMESH::SMESH_GroupOnFilter_var aGroup =
+            SMESH::IObjectToInterface<SMESH::SMESH_GroupOnFilter>(It.Value());
+          if (!aGroup->_is_nil()) {
+            SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg( this, aGroup, true );
+            aDlg->show();
+          }
+        }
       }
       break;
     }
@@ -1938,7 +2792,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       if ( !vtkwnd )
       {
         SUIT_MessageBox::warning( desktop(), tr( "SMESH_WRN_WARNING" ),
-                                 tr( "NOT_A_VTK_VIEWER" ) );
+                                  tr( "NOT_A_VTK_VIEWER" ) );
         break;
       }
 
@@ -1977,7 +2831,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       if ( !vtkwnd )
       {
         SUIT_MessageBox::warning( desktop(), tr( "SMESH_WRN_WARNING" ),
-                                 tr( "NOT_A_VTK_VIEWER" ) );
+                                  tr( "NOT_A_VTK_VIEWER" ) );
         break;
       }
 
@@ -1990,8 +2844,10 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       break;
     }
 
-  case 900:                                    // MESH INFOS
+  case 900:                                     // MESH INFOS
+  case 903:                                     // WHAT IS
     {
+      int page = theCommandID == 900 ? SMESHGUI_MeshInfoDlg::BaseInfo : SMESHGUI_MeshInfoDlg::ElemInfo;
       EmitSignalDeactivateDialog();
       LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
       SALOME_ListIO selected;
@@ -1999,54 +2855,27 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
         aSel->selectedObjects( selected );
 
       if ( selected.Extent() > 1 ) { // a dlg for each IO
-        SALOME_ListIO IOs;
-        SALOME_ListIteratorOfListIO It (selected);
+        SALOME_ListIteratorOfListIO It( selected );
         for ( ; It.More(); It.Next() ) {
-         IOs.Clear(); IOs.Append( It.Value() );
-         aSel->setSelectedObjects( IOs );
-          ( new SMESHGUI_MeshInfosDlg( this ) )->show();
+          SMESHGUI_MeshInfoDlg* dlg = new SMESHGUI_MeshInfoDlg( SMESHGUI::desktop(), page );
+          dlg->showInfo( It.Value() ); 
+          dlg->show();
         }
-        // restore selection
-        aSel->setSelectedObjects( selected );
       }
-      else
-        ( new SMESHGUI_MeshInfosDlg( this ) )->show();
-      break;
-    }
-
-  case 902:                                    // STANDARD MESH INFOS
-    {
-      EmitSignalDeactivateDialog();
-      LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
-      SALOME_ListIO selected;
-      if( aSel )
-        aSel->selectedObjects( selected );
-
-      if ( selected.Extent() > 1 ) { // a dlg for each IO
-        SALOME_ListIO IOs;
-        SALOME_ListIteratorOfListIO It (selected);
-        for ( ; It.More(); It.Next() ) {
-         IOs.Clear();
-         IOs.Append( It.Value() );
-         aSel->setSelectedObjects( IOs );
-          ( new SMESHGUI_StandardMeshInfosDlg( this ) )->show();
-        }
-        // restore selection
-       aSel->setSelectedObjects( selected );
+      else {
+        SMESHGUI_MeshInfoDlg* dlg = new SMESHGUI_MeshInfoDlg( SMESHGUI::desktop(), page );
+        dlg->show();
       }
-      else
-        ( new SMESHGUI_StandardMeshInfosDlg( this ) )->show();
       break;
     }
 
-  case 903:                                    // WHAT IS
+  case 904:                                     // FIND ELEM
     {
-      EmitSignalDeactivateDialog();
-      ( new SMESHGUI_WhatIsDlg( this ) )->show();
+      startOperation( theCommandID );
       break;
     }
 
-  case 1100:                                   // EDIT HYPOTHESIS
+  case 1100:                                    // EDIT HYPOTHESIS
     {
       if(checkLock(aStudy)) break;
 
@@ -2059,82 +2888,28 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
 
       if (nbSel == 1) {
         Handle(SALOME_InteractiveObject) anIObject = selected.First();
-       SMESH::SMESH_Hypothesis_var aHypothesis = SMESH::IObjectToInterface<SMESH::SMESH_Hypothesis>(anIObject);
+        SMESH::SMESH_Hypothesis_var aHypothesis = SMESH::IObjectToInterface<SMESH::SMESH_Hypothesis>(anIObject);
 
         /* 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 ( !aHypothesis->_is_nil() )
         {
+          // BUG 0020378
+          //SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(aHypothesis->GetName());
           SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(aHypothesis->GetName());
-          if (aCreator)
-            aCreator->edit( aHypothesis.in(), anIObject->getName(), desktop() );
+          if (aCreator) {
+            aCreator->edit( aHypothesis.in(), anIObject->getName(), desktop(), this, SLOT( onHypothesisEdit( int ) ) );
+          }
           else
           {
             // report error
           }
         }
       }
-      updateObjBrowser( true );
-      break;
-    }
-
-  case 1101:                                   // RENAME
-    {
-      if ( checkLock( aStudy ) )
-        break;
-
-      LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
-      SALOME_ListIO selected;
-      if( aSel )
-        aSel->selectedObjects( selected );
-
-      bool isAny = false; // is there any appropriate object selected
-
-      SALOME_ListIteratorOfListIO It( selected );
-      for ( ; It.More(); It.Next() )
-      {
-        Handle(SALOME_InteractiveObject) IObject = It.Value();
-        _PTR(SObject) obj = aStudy->FindObjectID( IObject->getEntry() );
-        _PTR(GenericAttribute) anAttr;
-        _PTR(AttributeName) aName;
-        if ( obj )
-        {
-          if ( obj->FindAttribute(anAttr, "AttributeName") )
-          {
-            aName = anAttr;
-            QString newName = QString(aName->Value().c_str());
-
-            // check type to prevent renaming of inappropriate objects
-            int aType = SMESHGUI_Selection::type(IObject->getEntry(), aStudy);
-            if (aType == MESH || aType == GROUP ||
-                aType == SUBMESH || aType == SUBMESH_COMPOUND ||
-                aType == SUBMESH_SOLID || aType == SUBMESH_FACE ||
-                aType == SUBMESH_EDGE || aType == SUBMESH_VERTEX ||
-                aType == HYPOTHESIS || aType == ALGORITHM)
-            {
-              isAny = true;
-              newName = LightApp_NameDlg::getName(desktop(), newName);
-              if ( !newName.isEmpty() )
-              {
-                SMESHGUI::GetSMESHGen()->SetName(obj->GetIOR().c_str(), newName.toLatin1().data());
-
-                updateObjBrowser();
-              }
-            }
-          }
-        }
-      } // for
-
-      if (!isAny) {
-        SUIT_MessageBox::warning(desktop(),
-                                QObject::tr("SMESH_WRN_WARNING"),
-                                QObject::tr("SMESH_WRN_NO_APPROPRIATE_SELECTION"));
-      }
       break;
     }
-
-  case 1102:                                   // REMOVE HYPOTHESIS / ALGORITHMS
+  case 1102:                                    // REMOVE HYPOTHESIS / ALGORITHMS
     {
       if(checkLock(aStudy)) break;
       SUIT_OverrideCursor wc;
@@ -2146,8 +2921,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
 
       SALOME_ListIteratorOfListIO It(selected);
       for (int i = 0; It.More(); It.Next(), i++) {
-       Handle(SALOME_InteractiveObject) IObject = It.Value();
-       SMESH::RemoveHypothesisOrAlgorithmOnMesh(IObject);
+        Handle(SALOME_InteractiveObject) IObject = It.Value();
+        SMESH::RemoveHypothesisOrAlgorithmOnMesh(IObject);
       }
       SALOME_ListIO l1;
       aSel->setSelectedObjects( l1 );
@@ -2155,118 +2930,126 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       break;
     }
 
-  case 401:                                    // GEOM::EDGE
-  case 4021:                                   // TRIANGLE
-  case 4022:                                   // QUAD
-  case 4023:                                   // POLYGON
-  case 4031:                                   // TETRA
-  case 4032:                                   // HEXA
+  case 4008:                                    // BALL
+  case 4009:                                    // ELEM0D
+  case 4010:                                    // EDGE
+  case 4021:                                    // TRIANGLE
+  case 4022:                                    // QUAD
+  case 4023:                                    // POLYGON
+  case 4031:                                    // TETRA
+  case 4032:                                    // HEXA
+  case 4133:                                    // PENTA
+  case 4134:                                    // PYRAMID
+  case 4135:                                    // OCTA12
     {
       if(checkLock(aStudy)) break;
       if ( vtkwnd ) {
-       EmitSignalDeactivateDialog();
-        SMDSAbs_ElementType type    = SMDSAbs_Edge;
-        int                 nbNodes = 2;
+        EmitSignalDeactivateDialog();
+        SMDSAbs_EntityType type = SMDSEntity_Edge;
         switch (theCommandID) {
-        case 4021:                                      // TRIANGLE
-          type = SMDSAbs_Face; nbNodes = 3; break;
-        case 4022:                                      // QUAD
-          type = SMDSAbs_Face; nbNodes = 4; break;
-        case 4031:                                      // TETRA
-          type = SMDSAbs_Volume; nbNodes = 4; break;
-       case 4023:                                      // POLYGON
-         type = SMDSAbs_Face; nbNodes = 5; break;     // 5 - identificator for POLYGON
-        case 4032:                                      // HEXA
-          type = SMDSAbs_Volume; nbNodes = 8; break;
-       case 4033:                                      // POLYHEDRE
-         type = SMDSAbs_Volume; nbNodes = 9; break; // 9 - identificator for POLYHEDRE
+        case 4008: type = SMDSEntity_Ball;            break;
+        case 4009: type = SMDSEntity_0D;              break;
+        case 4021: type = SMDSEntity_Triangle;        break;
+        case 4022: type = SMDSEntity_Quadrangle;      break;
+        case 4031: type = SMDSEntity_Tetra;           break;
+        case 4023: type = SMDSEntity_Polygon;         break;
+        case 4032: type = SMDSEntity_Hexa;            break;
+        case 4133: type = SMDSEntity_Penta;           break;
+        case 4134: type = SMDSEntity_Pyramid;         break;
+        case 4135: type = SMDSEntity_Hexagonal_Prism; break;
         default:;
         }
-       ( new SMESHGUI_AddMeshElementDlg( this, type, nbNodes ) )->show();
+        ( new SMESHGUI_AddMeshElementDlg( this, type ) )->show();
       }
       else {
-       SUIT_MessageBox::warning(desktop(),
-                                tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
+        SUIT_MessageBox::warning(desktop(),
+                                 tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
       }
       break;
     }
-  case 4033:                                   // POLYHEDRON
+  case 4033:                                    // POLYHEDRON
     {
       if(checkLock(aStudy)) break;
       if ( vtkwnd ) {
-       EmitSignalDeactivateDialog();
-       ( new SMESHGUI_CreatePolyhedralVolumeDlg( this ) )->show();
+        EmitSignalDeactivateDialog();
+        ( new SMESHGUI_CreatePolyhedralVolumeDlg( this ) )->show();
       }
       else {
-       SUIT_MessageBox::warning(SMESHGUI::desktop(),
-                                tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
+        SUIT_MessageBox::warning(SMESHGUI::desktop(),
+                                 tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
       }
       break;
     }
   case 4034:     // QUADRATIC EDGE
   case 4035:     // QUADRATIC TRIANGLE
   case 4036:     // QUADRATIC QUADRANGLE
+  case 4136:     // BIQUADRATIC QUADRANGLE
   case 4037:     // QUADRATIC TETRAHEDRON
   case 4038:     // QUADRATIC PYRAMID
   case 4039:     // QUADRATIC PENTAHEDRON
   case 4040:     // QUADRATIC HEXAHEDRON
+  case 4140:     // TRIQUADRATIC HEXAHEDRON
     {
       if(checkLock(aStudy)) break;
       if ( vtkwnd ) {
-       EmitSignalDeactivateDialog();
-       int type;
-
-       switch (theCommandID) {
-       case 4034:
-         type = QUAD_EDGE; break;
-       case 4035:
-         type = QUAD_TRIANGLE; break;
-       case 4036:
-         type = QUAD_QUADRANGLE; break;
-       case 4037:
-         type = QUAD_TETRAHEDRON; break;
-       case 4038:
-         type = QUAD_PYRAMID; break;
-       case 4039:
-         type = QUAD_PENTAHEDRON; break;
-       case 4040:
-         type = QUAD_HEXAHEDRON;
-         break;
-       default:;
-       }
-        ( new SMESHGUI_AddQuadraticElementDlg( this, type ) )->show();
+        EmitSignalDeactivateDialog();
+        SMDSAbs_EntityType type;
+
+        switch (theCommandID) {
+        case 4034:
+          type = SMDSEntity_Quad_Edge; break;
+        case 4035:
+          type = SMDSEntity_Quad_Triangle; break;
+        case 4036:
+          type = SMDSEntity_Quad_Quadrangle; break;
+        case 4136:
+          type = SMDSEntity_BiQuad_Quadrangle; break;
+        case 4037:
+          type = SMDSEntity_Quad_Tetra; break;
+        case 4038:
+          type = SMDSEntity_Quad_Pyramid; break;
+        case 4039:
+          type = SMDSEntity_Quad_Penta; break;
+        case 4040:
+          type = SMDSEntity_Quad_Hexa;
+        case 4140:
+          type = SMDSEntity_TriQuad_Hexa;
+          break;
+        default:;
+        }
+         ( new SMESHGUI_AddQuadraticElementDlg( this, type ) )->show();
       }
       else {
-       SUIT_MessageBox::warning(SMESHGUI::desktop(),
-                                tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
+        SUIT_MessageBox::warning(SMESHGUI::desktop(),
+                                 tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
       }
       break;
     }
-  case 4041:                                   // REMOVES NODES
+  case 4041:                                    // REMOVES NODES
     {
       if(checkLock(aStudy)) break;
       if ( vtkwnd ) {
-       EmitSignalDeactivateDialog();
-       ( new SMESHGUI_RemoveNodesDlg( this ) )->show();
+        EmitSignalDeactivateDialog();
+        ( new SMESHGUI_RemoveNodesDlg( this ) )->show();
       }
       else {
-       SUIT_MessageBox::warning(SMESHGUI::desktop(),
-                                tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
+        SUIT_MessageBox::warning(SMESHGUI::desktop(),
+                                 tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
       }
       break;
     }
-  case 4042:                                   // REMOVES ELEMENTS
+  case 4042:                                    // REMOVES ELEMENTS
     {
       if(checkLock(aStudy)) break;
       if( vtkwnd ) {
-       EmitSignalDeactivateDialog();
-       ( new SMESHGUI_RemoveElementsDlg( this ) )->show();
+        EmitSignalDeactivateDialog();
+        ( new SMESHGUI_RemoveElementsDlg( this ) )->show();
       }
       else
-       {
-         SUIT_MessageBox::warning(SMESHGUI::desktop(),
-                                  tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
-       }
+        {
+          SUIT_MessageBox::warning(SMESHGUI::desktop(),
+                                   tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
+        }
       break;
     }
   case 4043: {                                // CLEAR_MESH
@@ -2286,7 +3069,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
         SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IOS);
       if ( aMesh->_is_nil()) continue;
       try {
-        SMESH::UpdateView(SMESH::eErase, IOS->getEntry());
+        SMESH::RemoveVisualObjectWithActors(IOS->getEntry(), true);
         aMesh->Clear();
         _PTR(SObject) aMeshSObj = SMESH::FindSObject(aMesh);
         SMESH::ModifiedMesh( aMeshSObj, false, true);
@@ -2296,57 +3079,95 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
         for ( anIter->InitEx(true); anIter->More(); anIter->Next() )
         {
           _PTR(SObject) so = anIter->Value();
-          SMESH::UpdateView(SMESH::eErase, so->GetID().c_str());
+          SMESH::RemoveVisualObjectWithActors(so->GetID().c_str(), true);
         }
       }
       catch (const SALOME::SALOME_Exception& S_ex){
-       wc.suspend();
-       SalomeApp_Tools::QtCatchCorbaException(S_ex);
-       wc.resume();
+        wc.suspend();
+        SalomeApp_Tools::QtCatchCorbaException(S_ex);
+        wc.resume();
       }
     }
     SMESH::UpdateView();
     updateObjBrowser();
     break;
   }
-  case 4051:                                   // RENUMBERING NODES
+  case 4044:                                     // REMOVE ORPHAN NODES
+    {
+      if(checkLock(aStudy)) break;
+      SALOME_ListIO selected;
+      if( LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr() )
+        aSel->selectedObjects( selected );
+      if ( selected.Extent() == 1 ) {
+        Handle(SALOME_InteractiveObject) anIO = selected.First();
+        SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(anIO);
+        if ( !aMesh->_is_nil() ) {
+          bool confirm = SUIT_MessageBox::question( SMESHGUI::desktop(),
+                                                    tr( "SMESH_WARNING" ),
+                                                    tr( "REMOVE_ORPHAN_NODES_QUESTION"),
+                                                    SUIT_MessageBox::Yes |
+                                                    SUIT_MessageBox::No,
+                                                    SUIT_MessageBox::No ) == SUIT_MessageBox::Yes;
+          if( confirm ) {
+            try {
+              SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
+              int removed = aMeshEditor->RemoveOrphanNodes();
+              SUIT_MessageBox::information(SMESHGUI::desktop(),
+                                           tr("SMESH_INFORMATION"),
+                                           tr("NB_NODES_REMOVED").arg(removed));
+              if ( removed > 0 ) {
+                SMESH::UpdateView();
+                SMESHGUI::Modified();
+              }
+            }
+            catch (const SALOME::SALOME_Exception& S_ex) {
+              SalomeApp_Tools::QtCatchCorbaException(S_ex);
+            }
+            catch (...) {
+            }
+          }
+        }
+      }
+      break;
+    }
+  case 4051:                                    // RENUMBERING NODES
     {
       if(checkLock(aStudy)) break;
       if( vtkwnd ) {
-       EmitSignalDeactivateDialog();
-       ( new SMESHGUI_RenumberingDlg( this, 0 ) )->show();
+        EmitSignalDeactivateDialog();
+        ( new SMESHGUI_RenumberingDlg( this, 0 ) )->show();
       }
       else
-       {
-         SUIT_MessageBox::warning(SMESHGUI::desktop(),
-                                  tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
-       }
+        {
+          SUIT_MessageBox::warning(SMESHGUI::desktop(),
+                                   tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
+        }
       break;
     }
-  case 4052:                                   // RENUMBERING ELEMENTS
+  case 4052:                                    // RENUMBERING ELEMENTS
     {
       if(checkLock(aStudy)) break;
       if ( vtkwnd ) {
-       EmitSignalDeactivateDialog();
-       ( new SMESHGUI_RenumberingDlg( this, 1 ) )->show();
+        EmitSignalDeactivateDialog();
+        ( new SMESHGUI_RenumberingDlg( this, 1 ) )->show();
       }
       else
-       {
-         SUIT_MessageBox::warning(SMESHGUI::desktop(),
-                                  tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
-       }
+        {
+          SUIT_MessageBox::warning(SMESHGUI::desktop(),
+                                   tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
+        }
       break;
     }
   case 4061:                                   // TRANSLATION
     {
       if(checkLock(aStudy)) break;
       if ( vtkwnd ) {
-       EmitSignalDeactivateDialog();
-       ( new SMESHGUI_TranslationDlg( this ) )->show();
+        EmitSignalDeactivateDialog();
+        ( new SMESHGUI_TranslationDlg( this ) )->show();
       }
       else {
-       SUIT_MessageBox::warning(SMESHGUI::desktop(),
-                                tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
+        SUIT_MessageBox::warning(SMESHGUI::desktop(),
+                                 tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
       }
       break;
     }
@@ -2354,12 +3175,12 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     {
       if(checkLock(aStudy)) break;
       if( vtkwnd ) {
-       EmitSignalDeactivateDialog();
-       ( new SMESHGUI_RotationDlg( this ) )->show();
+        EmitSignalDeactivateDialog();
+        ( new SMESHGUI_RotationDlg( this ) )->show();
       }
       else {
-       SUIT_MessageBox::warning(SMESHGUI::desktop(),
-                                tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
+        SUIT_MessageBox::warning(SMESHGUI::desktop(),
+                                 tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
       }
       break;
     }
@@ -2367,12 +3188,12 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     {
       if(checkLock(aStudy)) break;
       if(vtkwnd) {
-       EmitSignalDeactivateDialog();
-       ( new SMESHGUI_SymmetryDlg( this ) )->show();
+        EmitSignalDeactivateDialog();
+        ( new SMESHGUI_SymmetryDlg( this ) )->show();
       }
       else {
-       SUIT_MessageBox::warning(SMESHGUI::desktop(),
-                                tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
+        SUIT_MessageBox::warning(SMESHGUI::desktop(),
+                                 tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
       }
       break;
     }
@@ -2380,12 +3201,12 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     {
       if(checkLock(aStudy)) break;
       if(vtkwnd) {
-       EmitSignalDeactivateDialog();
-       ( new SMESHGUI_SewingDlg( this ) )->show();
+        EmitSignalDeactivateDialog();
+        ( new SMESHGUI_SewingDlg( this ) )->show();
       }
       else {
-       SUIT_MessageBox::warning(SMESHGUI::desktop(),
-                                tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
+        SUIT_MessageBox::warning(SMESHGUI::desktop(),
+                                 tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
       }
       break;
     }
@@ -2393,12 +3214,12 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     {
       if(checkLock(aStudy)) break;
       if(vtkwnd) {
-       EmitSignalDeactivateDialog();
-       ( new SMESHGUI_EditMeshDlg( this, 0 ) )->show();
+        EmitSignalDeactivateDialog();
+        ( new SMESHGUI_MergeDlg( this, 0 ) )->show();
       }
       else {
-       SUIT_MessageBox::warning(SMESHGUI::desktop(),
-                                tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
+        SUIT_MessageBox::warning(SMESHGUI::desktop(),
+                                 tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
       }
       break;
     }
@@ -2406,11 +3227,11 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     {
       if (checkLock(aStudy)) break;
       if (vtkwnd) {
-       EmitSignalDeactivateDialog();
-       ( new SMESHGUI_EditMeshDlg( this, 1 ) )->show();
+        EmitSignalDeactivateDialog();
+        ( new SMESHGUI_MergeDlg( this, 1 ) )->show();
       } else {
-       SUIT_MessageBox::warning(SMESHGUI::desktop(),
-                                tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
+        SUIT_MessageBox::warning(SMESHGUI::desktop(),
+                                 tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
       }
       break;
     }
@@ -2419,6 +3240,34 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     startOperation( 4067 );
     break;
 
+  case 4068: // SCALE
+    {
+      if(checkLock(aStudy)) break;
+      if ( vtkwnd ) {
+        EmitSignalDeactivateDialog();
+        ( new SMESHGUI_ScaleDlg( this ) )->show();
+      }
+      else {
+        SUIT_MessageBox::warning(SMESHGUI::desktop(),
+                                 tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
+      }
+      break;
+    }
+
+  case 4069: // DUPLICATE NODES
+    {
+      if(checkLock(aStudy)) break;
+      if ( vtkwnd ) {
+        EmitSignalDeactivateDialog();
+        ( new SMESHGUI_DuplicateNodesDlg( this ) )->show();
+      }
+      else {
+        SUIT_MessageBox::warning(SMESHGUI::desktop(),
+                                 tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
+      }
+      break;
+    }
+
   case 5105: // Library of selection filters
   {
     static QList<int> aTypes;
@@ -2437,7 +3286,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   }
   break;
 
-  case 6017:                                   // CONTROLS
+  case 6017:                                    // CONTROLS
   case 6016:
   case 6015:
   case 6014:
@@ -2453,33 +3302,43 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case 6005:
   case 6009:
   case 6021:
+  case 6022:
+  case 6023:
+  case 6024:
+  case 6025:
+  case 6026:
+  case 6027:
+  case 6028:
+  case 6029:
+  case 6030:
+  case 6031:
     if ( vtkwnd ) {
 
       LightApp_SelectionMgr* mgr = selectionMgr();
       SALOME_ListIO selected; mgr->selectedObjects( selected );
 
       if ( selected.Extent() == 1 && selected.First()->hasEntry() ) {
-       _PTR(SObject) SO = aStudy->FindObjectID( selected.First()->getEntry() );
-       if ( SO ) {
-         CORBA::Object_var aObject = SMESH::SObjectToObject( SO );
-         SMESH::SMESH_Mesh_var      aMesh    = SMESH::SMESH_Mesh::_narrow( aObject );
-         SMESH::SMESH_subMesh_var   aSubMesh = SMESH::SMESH_subMesh::_narrow( aObject );
-         SMESH::SMESH_GroupBase_var aGroup   = SMESH::SMESH_GroupBase::_narrow( aObject );
-         if ( !aMesh->_is_nil() || !aSubMesh->_is_nil() || !aGroup->_is_nil() ) {
-           ::Control( theCommandID );
-           break;
-         }
-       }
+        _PTR(SObject) SO = aStudy->FindObjectID( selected.First()->getEntry() );
+        if ( SO ) {
+          CORBA::Object_var aObject = SMESH::SObjectToObject( SO );
+          SMESH::SMESH_Mesh_var      aMesh    = SMESH::SMESH_Mesh::_narrow( aObject );
+          SMESH::SMESH_subMesh_var   aSubMesh = SMESH::SMESH_subMesh::_narrow( aObject );
+          SMESH::SMESH_GroupBase_var aGroup   = SMESH::SMESH_GroupBase::_narrow( aObject );
+          if ( !aMesh->_is_nil() || !aSubMesh->_is_nil() || !aGroup->_is_nil() ) {
+            ::Control( theCommandID );
+            break;
+          }
+        }
       }
       SUIT_MessageBox::warning(desktop(),
-                              tr( "SMESH_WRN_WARNING" ),
-                              tr( "SMESH_BAD_SELECTION" ) );
+                               tr( "SMESH_WRN_WARNING" ),
+                               tr( "SMESH_BAD_SELECTION" ) );
       break;
     }
     else {
       SUIT_MessageBox::warning(desktop(),
-                              tr( "SMESH_WRN_WARNING" ),
-                              tr( "NOT_A_VTK_VIEWER" ) );
+                               tr( "SMESH_WRN_WARNING" ),
+                               tr( "NOT_A_VTK_VIEWER" ) );
     }
     break;
   case 9010:
@@ -2490,11 +3349,11 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       SALOME_ListIteratorOfListIO it(selected);
       for( ; it.More(); it.Next()) {
         Handle(SALOME_InteractiveObject) anIObject = it.Value();
-       if(anIObject->hasEntry()) {
-         if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIObject->getEntry())){
-           anActor->SetPointsLabeled( !anActor->GetPointsLabeled() );
-         }
-       }
+        if(anIObject->hasEntry()) {
+          if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIObject->getEntry())){
+            anActor->SetPointsLabeled( !anActor->GetPointsLabeled() );
+          }
+        }
       }
       break;
     }
@@ -2503,15 +3362,25 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       LightApp_SelectionMgr* mgr = selectionMgr();
       SALOME_ListIO selected; mgr->selectedObjects( selected );
 
-      if (selected.Extent() == 1)      {
-       Handle(SALOME_InteractiveObject) anIObject = selected.First();
-       if(anIObject->hasEntry())
-         if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIObject->getEntry())){
-           anActor->SetCellsLabeled( !anActor->GetCellsLabeled() );
-         }
+      SALOME_ListIteratorOfListIO it(selected);
+      for( ; it.More(); it.Next()) {
+        Handle(SALOME_InteractiveObject) anIObject = it.Value();
+        if(anIObject->hasEntry())
+          if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIObject->getEntry())){
+            anActor->SetCellsLabeled( !anActor->GetCellsLabeled() );
+          }
       }
       break;
     }
+  case 501:
+  case 502:
+    {
+      int page = theCommandID == 501 ? SMESHGUI_MeasureDlg::MinDistance : SMESHGUI_MeasureDlg::BoundingBox;
+      EmitSignalDeactivateDialog();
+      SMESHGUI_MeasureDlg* dlg = new SMESHGUI_MeasureDlg( SMESHGUI::desktop(), page );
+      dlg->show();
+      break;
+    }
   }
 
   anApp->updateActions(); //SRN: To update a Save button in the toolbar
@@ -2567,7 +3436,8 @@ void SMESHGUI::BuildPresentation( const Handle(SALOME_InteractiveObject) & theIO
 // function : createSMESHAction
 // purpose  :
 //=======================================================================
-void SMESHGUI::createSMESHAction( const int id, const QString& po_id, const QString& icon_id, const int key, const bool toggle  )
+void SMESHGUI::createSMESHAction( const int id, const QString& po_id, const QString& icon_id,
+                                  const int key, const bool toggle, const QString& shortcutAction  )
 {
   QIcon icon;
   QWidget* parent = application()->desktop();
@@ -2584,7 +3454,8 @@ void SMESHGUI::createSMESHAction( const int id, const QString& po_id, const QStr
           menu       = tr( QString( "MEN_%1" ).arg( po_id ).toLatin1().data() ),
           status_bar = tr( QString( "STB_%1" ).arg( po_id ).toLatin1().data() );
 
-  createAction( id, tooltip, icon, menu, status_bar, key, parent, toggle, this, SLOT( OnGUIEvent() )  );
+  createAction( id, tooltip, icon, menu, status_bar, key, parent,
+                toggle, this, SLOT( OnGUIEvent() ), shortcutAction );
 }
 
 //=======================================================================
@@ -2595,7 +3466,7 @@ void SMESHGUI::createPopupItem( const int id,
                                 const QString& clients,
                                 const QString& types,
                                 const QString& theRule,
-                               const int pId )
+                                const int pId )
 {
   int parentId = pId;
   if( pId!=-1 )
@@ -2638,18 +3509,25 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   // ----- create actions --------------
 
-  createSMESHAction(  111, "DAT", "", (Qt::CTRL+Qt::Key_B) );
-  createSMESHAction(  112, "UNV", "", (Qt::CTRL+Qt::Key_U) );
-  createSMESHAction(  113, "MED", "", (Qt::CTRL+Qt::Key_M) );
+  createSMESHAction(  111, "IMPORT_DAT", "", (Qt::CTRL+Qt::Key_B) );
+  createSMESHAction(  112, "IMPORT_UNV", "", (Qt::CTRL+Qt::Key_U) );
+  createSMESHAction(  113, "IMPORT_MED", "", (Qt::CTRL+Qt::Key_M) );
   createSMESHAction(  114, "NUM" );
+  createSMESHAction(  115, "IMPORT_STL" );
+  createSMESHAction(  116, "IMPORT_CGNS" );
+  createSMESHAction(  117, "IMPORT_SAUV" );
   createSMESHAction(  121, "DAT" );
   createSMESHAction(  122, "MED" );
   createSMESHAction(  123, "UNV" );
   createSMESHAction(  140, "STL" );
+  createSMESHAction(  142, "CGNS" );
+  createSMESHAction(  144, "SAUV" );
   createSMESHAction(  124, "EXPORT_DAT" );
   createSMESHAction(  125, "EXPORT_MED" );
   createSMESHAction(  126, "EXPORT_UNV" );
   createSMESHAction(  141, "EXPORT_STL" );
+  createSMESHAction(  143, "EXPORT_CGNS" );
+  createSMESHAction(  145, "EXPORT_SAUV" );
   createSMESHAction(  150, "FILE_INFO" );
   createSMESHAction(   33, "DELETE",          "ICON_DELETE", Qt::Key_Delete );
   createSMESHAction( 5105, "SEL_FILTER_LIB" );
@@ -2657,8 +3535,11 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction(  702, "CREATE_MESH",     "ICON_DLG_INIT_MESH" );
   createSMESHAction(  703, "CREATE_SUBMESH",  "ICON_DLG_ADD_SUBMESH" );
   createSMESHAction(  704, "EDIT_MESHSUBMESH","ICON_DLG_EDIT_MESH" );
+  createSMESHAction(  705, "COPY_MESH",       "ICON_COPY_MESH" );
   createSMESHAction(  710, "BUILD_COMPOUND",  "ICON_BUILD_COMPOUND" );
   createSMESHAction(  711, "PRECOMPUTE",      "ICON_PRECOMPUTE" );
+  createSMESHAction(  712, "EVALUATE",        "ICON_COMPUTE" );
+  createSMESHAction(  713, "MESH_ORDER",      "ICON_COMPUTE" );
   createSMESHAction(  806, "CREATE_GEO_GROUP","ICON_CREATE_GEO_GROUP" );
   createSMESHAction(  801, "CREATE_GROUP",    "ICON_CREATE_GROUP" );
   createSMESHAction(  802, "CONSTRUCT_GROUP", "ICON_CONSTRUCT_GROUP" );
@@ -2672,11 +3553,22 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction(  814, "UNDERLYING_ELEMS","ICON_UNDERLYING_ELEMS" );
   createSMESHAction(  813, "DEL_GROUP",       "ICON_DEL_GROUP" );
   createSMESHAction(  900, "ADV_INFO",        "ICON_ADV_INFO" );
-  createSMESHAction(  902, "STD_INFO",        "ICON_STD_INFO" );
-  createSMESHAction(  903, "WHAT_IS",         "ICON_WHAT_IS" );
+  //createSMESHAction(  902, "STD_INFO",        "ICON_STD_INFO" );
+  //createSMESHAction(  903, "WHAT_IS",         "ICON_WHAT_IS" ); // VSR: issue #0021242 (eliminate "Mesh Element Information" command)
+  createSMESHAction(  904, "FIND_ELEM",       "ICON_FIND_ELEM" );
   createSMESHAction( 6001, "LENGTH",          "ICON_LENGTH",        0, true );
   createSMESHAction( 6002, "FREE_EDGE",       "ICON_FREE_EDGE",     0, true );
   createSMESHAction( 6021, "FREE_FACES",      "ICON_FREE_FACES",    0, true );
+  createSMESHAction( 6022, "MAX_ELEMENT_LENGTH_2D",  "ICON_MAX_ELEMENT_LENGTH_2D",   0, true );
+  createSMESHAction( 6023, "MAX_ELEMENT_LENGTH_3D",  "ICON_MAX_ELEMENT_LENGTH_3D",   0, true );
+  createSMESHAction( 6024, "BARE_BORDER_VOLUME",     "ICON_BARE_BORDER_VOLUME",      0, true );
+  createSMESHAction( 6025, "BARE_BORDER_FACE",       "ICON_BARE_BORDER_FACE",        0, true );
+  createSMESHAction( 6026, "OVER_CONSTRAINED_VOLUME","ICON_OVER_CONSTRAINED_VOLUME", 0, true );
+  createSMESHAction( 6027, "OVER_CONSTRAINED_FACE",  "ICON_OVER_CONSTRAINED_FACE",   0, true );
+  createSMESHAction( 6028, "EQUAL_NODE",      "ICON_EQUAL_NODE",    0, true );
+  createSMESHAction( 6029, "EQUAL_EDGE",      "ICON_EQUAL_EDGE",    0, true );
+  createSMESHAction( 6030, "EQUAL_FACE",      "ICON_EQUAL_FACE",    0, true );
+  createSMESHAction( 6031, "EQUAL_VOLUME",    "ICON_EQUAL_VOLUME",  0, true );
   createSMESHAction( 6003, "FREE_BORDER",     "ICON_FREE_EDGE_2D",  0, true );
   createSMESHAction( 6004, "CONNECTION",      "ICON_CONNECTION",    0, true );
   createSMESHAction( 6005, "FREE_NODE",       "ICON_FREE_NODE",     0, true );
@@ -2690,15 +3582,31 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction( 6018, "LENGTH_2D",       "ICON_LENGTH_2D",     0, true );
   createSMESHAction( 6019, "CONNECTION_2D",   "ICON_CONNECTION_2D", 0, true );
   createSMESHAction( 6009, "VOLUME_3D",       "ICON_VOLUME_3D",     0, true );
-  createSMESHAction(  400, "NODE",            "ICON_DLG_NODE" );
-  createSMESHAction(  401, "EDGE",            "ICON_DLG_EDGE" );
+  createSMESHAction( 4000, "NODE",            "ICON_DLG_NODE" );
+  createSMESHAction( 4009, "ELEM0D",          "ICON_DLG_ELEM0D" );
+  createSMESHAction( 4008, "BALL",            "ICON_DLG_BALL" );
+  createSMESHAction( 4010, "EDGE",            "ICON_DLG_EDGE" );
   createSMESHAction( 4021, "TRIANGLE",        "ICON_DLG_TRIANGLE" );
   createSMESHAction( 4022, "QUAD",            "ICON_DLG_QUADRANGLE" );
   createSMESHAction( 4023, "POLYGON",         "ICON_DLG_POLYGON" );
   createSMESHAction( 4031, "TETRA",           "ICON_DLG_TETRAS" );
   createSMESHAction( 4032, "HEXA",            "ICON_DLG_HEXAS" );
-  createSMESHAction( 4041, "REMOVE_NODES",    "ICON_DLG_REM_NODE" );
-  createSMESHAction( 4042, "REMOVE_ELEMENTS", "ICON_DLG_REM_ELEMENT" );
+  createSMESHAction( 4133, "PENTA",           "ICON_DLG_PENTA" );
+  createSMESHAction( 4134, "PYRAMID",         "ICON_DLG_PYRAMID" );
+  createSMESHAction( 4135, "OCTA",            "ICON_DLG_OCTA" );
+  createSMESHAction( 4033, "POLYHEDRON",              "ICON_DLG_POLYHEDRON" );
+  createSMESHAction( 4034, "QUADRATIC_EDGE",          "ICON_DLG_QUADRATIC_EDGE" );
+  createSMESHAction( 4035, "QUADRATIC_TRIANGLE",      "ICON_DLG_QUADRATIC_TRIANGLE" );
+  createSMESHAction( 4036, "QUADRATIC_QUADRANGLE",    "ICON_DLG_QUADRATIC_QUADRANGLE" );
+  createSMESHAction( 4136, "BIQUADRATIC_QUADRANGLE",  "ICON_DLG_BIQUADRATIC_QUADRANGLE" );
+  createSMESHAction( 4037, "QUADRATIC_TETRAHEDRON",   "ICON_DLG_QUADRATIC_TETRAHEDRON" );
+  createSMESHAction( 4038, "QUADRATIC_PYRAMID",       "ICON_DLG_QUADRATIC_PYRAMID" );
+  createSMESHAction( 4039, "QUADRATIC_PENTAHEDRON",   "ICON_DLG_QUADRATIC_PENTAHEDRON" );
+  createSMESHAction( 4040, "QUADRATIC_HEXAHEDRON",    "ICON_DLG_QUADRATIC_HEXAHEDRON" );
+  createSMESHAction( 4140, "TRIQUADRATIC_HEXAHEDRON", "ICON_DLG_TRIQUADRATIC_HEXAHEDRON" );
+  createSMESHAction( 4041, "REMOVE_NODES",          "ICON_DLG_REM_NODE" );
+  createSMESHAction( 4042, "REMOVE_ELEMENTS",       "ICON_DLG_REM_ELEMENT" );
+  createSMESHAction( 4044, "REMOVE_ORPHAN_NODES",   "ICON_DLG_REM_ORPHAN_NODES" );
   createSMESHAction( 4043, "CLEAR_MESH"    ,  "ICON_CLEAR_MESH" );
   createSMESHAction( 4051, "RENUM_NODES",     "ICON_DLG_RENUMBERING_NODES" );
   createSMESHAction( 4052, "RENUM_ELEMENTS",  "ICON_DLG_RENUMBERING_ELEMENTS" );
@@ -2708,8 +3616,9 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction( 4064, "SEW",             "ICON_SMESH_SEWING_FREEBORDERS" );
   createSMESHAction( 4065, "MERGE",           "ICON_SMESH_MERGE_NODES" );
   createSMESHAction( 4066, "MERGE_ELEMENTS",  "ICON_DLG_MERGE_ELEMENTS" );
-  createSMESHAction( 4067, "MESH_THROU_POINT","ICON_DLG_MESH_THROU_POINT" );
-  createSMESHAction(  406, "MOVE",            "ICON_DLG_MOVE_NODE" );
+  createSMESHAction( 4067, "MESH_THROU_POINT","ICON_DLG_MOVE_NODE" );
+  createSMESHAction( 4068, "SCALE",           "ICON_DLG_MESH_SCALE" );
+  createSMESHAction( 4069, "DUPLICATE_NODES", "ICON_SMESH_DUPLICATE_NODES" );
   createSMESHAction(  407, "INV",             "ICON_DLG_MESH_DIAGONAL" );
   createSMESHAction(  408, "UNION2",          "ICON_UNION2TRI" );
   createSMESHAction(  409, "ORIENT",          "ICON_DLG_MESH_ORIENTATION" );
@@ -2721,20 +3630,33 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction(  415, "MAP",             "ICON_MAP" );
   createSMESHAction(  416, "EXTRUSION_ALONG", "ICON_EXTRUSION_ALONG" );
   createSMESHAction(  417, "CONV_TO_QUAD",    "ICON_CONV_TO_QUAD" );
+  createSMESHAction(  418, "2D_FROM_3D",      "ICON_2D_FROM_3D" );
+  createSMESHAction(  419, "SPLIT_TO_TETRA",  "ICON_SPLIT_TO_TETRA" );
+  createSMESHAction(  420, "REORIENT_2D",     "ICON_REORIENT_2D" );
   createSMESHAction(  200, "RESET" );
   createSMESHAction(  201, "SCALAR_BAR_PROP" );
+  createSMESHAction(  2021, "SAVE_DISTRIBUTION" );
+  createSMESHAction(  2022, "SHOW_DISTRIBUTION","",0, true );
+#ifndef DISABLE_PLOT2DVIEWER
+  createSMESHAction(  2023, "PLOT_DISTRIBUTION" );
+#endif
   createSMESHAction(  211, "WIRE",           "ICON_WIRE", 0, true );
   createSMESHAction(  212, "SHADE",          "ICON_SHADE", 0, true );
   createSMESHAction(  213, "SHRINK",         "ICON_SHRINK", 0, true );
   createSMESHAction(  214, "UPDATE",         "ICON_UPDATE" );
   createSMESHAction(  215, "NODES",          "ICON_POINTS", 0, true );
+  createSMESHAction(  222, "BALLS",          "ICON_DLG_BALL", 0, true );
+  createSMESHAction(  216, "ELEMS0D",        "ICON_DLG_ELEM0D", 0, true );
   createSMESHAction(  217, "EDGES",          "ICON_DLG_EDGE", 0, true );
   createSMESHAction(  218, "FACES",          "ICON_DLG_TRIANGLE", 0, true );
   createSMESHAction(  219, "VOLUMES",        "ICON_DLG_TETRAS", 0, true );
   createSMESHAction(  220, "ALL" );
   createSMESHAction(  221, "FACE_ORIENTATION", "", 0, true );
+
+  createSMESHAction(  231, "LINE_REPRESENTATION", "", 0, true );
+  createSMESHAction(  232, "ARC_REPRESENTATION", "", 0, true );
+
   createSMESHAction( 1100, "EDIT_HYPO" );
-  createSMESHAction( 1101, "RENAME", "", Qt::Key_F2 );
   createSMESHAction( 1102, "UNASSIGN" );
   createSMESHAction( 9010, "NUM_NODES", "", 0, true );
   createSMESHAction( 9011, "NUM_ELEMENTS", "", 0, true );
@@ -2747,31 +3669,31 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction( 1137, "DISABLE_AUTO_COLOR" );
   createSMESHAction( 2000, "CTRL" );
 
-  createSMESHAction( 300, "ERASE" );
-  createSMESHAction( 301, "DISPLAY" );
+  createSMESHAction( 501, "MEASURE_MIN_DIST", "ICON_MEASURE_MIN_DIST" );
+  createSMESHAction( 502, "MEASURE_BND_BOX",  "ICON_MEASURE_BND_BOX" );
+
+  createSMESHAction( 300, "HIDE" );
+  createSMESHAction( 301, "SHOW" );
   createSMESHAction( 302, "DISPLAY_ONLY" );
-  createSMESHAction( 4033, "POLYHEDRON", "ICON_DLG_POLYHEDRON" );
-  createSMESHAction( 4034, "QUADRATIC_EDGE", "ICON_DLG_QUADRATIC_EDGE" );
-  createSMESHAction( 4035, "QUADRATIC_TRIANGLE", "ICON_DLG_QUADRATIC_TRIANGLE" );
-  createSMESHAction( 4036, "QUADRATIC_QUADRANGLE", "ICON_DLG_QUADRATIC_QUADRANGLE" );
-  createSMESHAction( 4037, "QUADRATIC_TETRAHEDRON", "ICON_DLG_QUADRATIC_TETRAHEDRON" );
-  createSMESHAction( 4038, "QUADRATIC_PYRAMID", "ICON_DLG_QUADRATIC_PYRAMID" );
-  createSMESHAction( 4039, "QUADRATIC_PENTAHEDRON", "ICON_DLG_QUADRATIC_PENTAHEDRON" );
-  createSMESHAction( 4040, "QUADRATIC_HEXAHEDRON", "ICON_DLG_QUADRATIC_HEXAHEDRON" );
 
   // ----- create menu --------------
-  int fileId   = createMenu( tr( "MEN_FILE" ),   -1,  1 ),
-      editId   = createMenu( tr( "MEN_EDIT" ),   -1,  3 ),
-      toolsId  = createMenu( tr( "MEN_TOOLS" ),  -1,  5, 50 ),
-      meshId   = createMenu( tr( "MEN_MESH" ),   -1, 70, 10 ),
-      ctrlId   = createMenu( tr( "MEN_CTRL" ),   -1, 60, 10 ),
-      modifyId = createMenu( tr( "MEN_MODIFY" ), -1, 40, 10 ),
-      viewId   = createMenu( tr( "MEN_VIEW" ),   -1,  2 );
+  int fileId    = createMenu( tr( "MEN_FILE" ),    -1,  1 ),
+      editId    = createMenu( tr( "MEN_EDIT" ),    -1,  3 ),
+      toolsId   = createMenu( tr( "MEN_TOOLS" ),   -1,  5, 50 ),
+      meshId    = createMenu( tr( "MEN_MESH" ),    -1, 70, 10 ),
+      ctrlId    = createMenu( tr( "MEN_CTRL" ),    -1, 60, 10 ),
+      modifyId  = createMenu( tr( "MEN_MODIFY" ),  -1, 40, 10 ),
+      measureId = createMenu( tr( "MEN_MEASURE" ), -1, 50, 10 ),
+      viewId    = createMenu( tr( "MEN_VIEW" ),    -1,  2 );
 
   createMenu( separator(), fileId );
 
   int importId = createMenu( tr( "MEN_IMPORT" ), fileId, -1, 10 ),
       exportId = createMenu( tr( "MEN_EXPORT" ), fileId, -1, 10 ),
+      nodeId   = createMenu( tr( "MEN_NODE_CTRL" ), ctrlId, -1, 10 ),
+      edgeId   = createMenu( tr( "MEN_EDGE_CTRL" ), ctrlId, -1, 10 ),
+      faceId   = createMenu( tr( "MEN_FACE_CTRL" ), ctrlId, -1, 10 ),
+      volumeId = createMenu( tr( "MEN_VOLUME_CTRL" ), ctrlId, -1, 10 ),
       addId    = createMenu( tr( "MEN_ADD" ),    modifyId, 402 ),
       removeId = createMenu( tr( "MEN_REMOVE" ), modifyId, 403 ),
       renumId  = createMenu( tr( "MEN_RENUM" ),  modifyId, 404 ),
@@ -2780,12 +3702,19 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( 111, importId, -1 );
   createMenu( 112, importId, -1 );
   createMenu( 113, importId, -1 );
-
+  createMenu( 115, importId, -1 );
+#ifdef WITH_CGNS
+  createMenu( 116, importId, -1 );
+#endif
+  createMenu( 117, importId, -1 );
   createMenu( 121, exportId, -1 );
   createMenu( 122, exportId, -1 );
   createMenu( 123, exportId, -1 );
-  createMenu( 140, exportId, -1 ); // export to stl STL
-
+  createMenu( 140, exportId, -1 ); // export to STL
+#ifdef WITH_CGNS
+  createMenu( 142, exportId, -1 ); // export to CGNS
+#endif
+  createMenu( 144, exportId, -1 ); // export to SAUV
   createMenu( separator(), fileId, 10 );
 
   createMenu( 33, editId, -1 );
@@ -2796,9 +3725,12 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( 703, meshId, -1 );
   createMenu( 704, meshId, -1 );
   createMenu( 710, meshId, -1 );
+  createMenu( 705, meshId, -1 );
   createMenu( separator(), meshId, -1 );
   createMenu( 701, meshId, -1 );
   createMenu( 711, meshId, -1 );
+  createMenu( 712, meshId, -1 );
+  createMenu( 713, meshId, -1 );
   createMenu( separator(), meshId, -1 );
   createMenu( 801, meshId, -1 );
   createMenu( 806, meshId, -1 );
@@ -2812,52 +3744,69 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( separator(), meshId, -1 );
   createMenu( 814, meshId, -1 );
   createMenu( separator(), meshId, -1 );
-  createMenu( 813, meshId, -1 );
-  createMenu( separator(), meshId, -1 );
   createMenu( 900, meshId, -1 );
-  createMenu( 902, meshId, -1 );
-  createMenu( 903, meshId, -1 );
+  //createMenu( 902, meshId, -1 );
+  //createMenu( 903, meshId, -1 ); // VSR: issue #0021242 (eliminate "Mesh Element Information" command)
+  createMenu( 904, meshId, -1 );
   createMenu( separator(), meshId, -1 );
 
-  createMenu( 6003, ctrlId, -1 );
-  createMenu( 6001, ctrlId, -1 );
-  createMenu( 6004, ctrlId, -1 );
-  createMenu( separator(), ctrlId, -1 );
-  createMenu( 6005, ctrlId, -1 );
-  createMenu( 6002, ctrlId, -1 );
-  createMenu( 6018, ctrlId, -1 );
-  createMenu( 6019, ctrlId, -1 );
-  createMenu( 6011, ctrlId, -1 );
-  createMenu( 6012, ctrlId, -1 );
-  createMenu( 6013, ctrlId, -1 );
-  createMenu( 6014, ctrlId, -1 );
-  createMenu( 6015, ctrlId, -1 );
-  createMenu( 6016, ctrlId, -1 );
-  createMenu( separator(), ctrlId, -1 );
-  createMenu( 6017, ctrlId, -1 );
-  createMenu( 6009, ctrlId, -1 );
-  createMenu( 6021, ctrlId, -1 );
-  createMenu( separator(), ctrlId, -1 );
-
-  createMenu( 400, addId, -1 );
-  createMenu( 401, addId, -1 );
+  createMenu( 6005, nodeId, -1 );
+  createMenu( 6028, nodeId, -1 );
+  createMenu( 6002, edgeId, -1 );
+  createMenu( 6003, edgeId, -1 );
+  createMenu( 6001, edgeId, -1 );
+  createMenu( 6004, edgeId, -1 );
+  createMenu( 6029, edgeId, -1 );
+  createMenu( 6021, faceId, -1 );
+  createMenu( 6025, faceId, -1 );
+  createMenu( 6027, faceId, -1 );
+  createMenu( 6018, faceId, -1 );
+  createMenu( 6019, faceId, -1 );
+  createMenu( 6011, faceId, -1 );
+  createMenu( 6012, faceId, -1 );
+  createMenu( 6013, faceId, -1 );
+  createMenu( 6014, faceId, -1 );
+  createMenu( 6015, faceId, -1 );
+  createMenu( 6016, faceId, -1 );
+  createMenu( 6022, faceId, -1 );
+  createMenu( 6030, faceId, -1 );
+  createMenu( 6017, volumeId, -1 );
+  createMenu( 6009, volumeId, -1 );
+  createMenu( 6023, volumeId, -1 );
+  createMenu( 6024, volumeId, -1 );
+  createMenu( 6026, volumeId, -1 );
+  createMenu( 6031, volumeId, -1 );
+
+  createMenu( 4000, addId, -1 );
+  createMenu( 4009, addId, -1 );
+  createMenu( 4008, addId, -1 );
+  createMenu( 4010, addId, -1 );
   createMenu( 4021, addId, -1 );
   createMenu( 4022, addId, -1 );
   createMenu( 4023, addId, -1 );
   createMenu( 4031, addId, -1 );
   createMenu( 4032, addId, -1 );
+  createMenu( 4133, addId, -1 );
+  createMenu( 4134, addId, -1 );
+  createMenu( 4135, addId, -1 );
   createMenu( 4033, addId, -1 );
   createMenu( separator(), addId, -1 );
   createMenu( 4034, addId, -1 );
   createMenu( 4035, addId, -1 );
   createMenu( 4036, addId, -1 );
+  createMenu( 4136, addId, -1 );
   createMenu( 4037, addId, -1 );
   createMenu( 4038, addId, -1 );
   createMenu( 4039, addId, -1 );
   createMenu( 4040, addId, -1 );
+  createMenu( 4140, addId, -1 );
 
   createMenu( 4041, removeId, -1 );
   createMenu( 4042, removeId, -1 );
+  createMenu( 4044, removeId, -1 );
+  createMenu( separator(), removeId, -1 );
+  createMenu( 813, removeId, -1 );
+  createMenu( separator(), removeId, -1 );
   createMenu( 4043, removeId, -1 );
 
   createMenu( 4051, renumId, -1 );
@@ -2866,24 +3815,30 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( 4061, transfId, -1 );
   createMenu( 4062, transfId, -1 );
   createMenu( 4063, transfId, -1 );
+  createMenu( 4068, transfId, -1 );
   createMenu( 4064, transfId, -1 );
   createMenu( 4065, transfId, -1 );
   createMenu( 4066, transfId, -1 );
+  createMenu( 4069, transfId, -1 );
 
-  createMenu( 406, modifyId, -1 );
   createMenu( 4067,modifyId, -1 );
   createMenu( 407, modifyId, -1 );
   createMenu( 408, modifyId, -1 );
   createMenu( 409, modifyId, -1 );
+  createMenu( 420, modifyId, -1 );
   createMenu( 410, modifyId, -1 );
   createMenu( 411, modifyId, -1 );
+  createMenu( 419, modifyId, -1 );
   createMenu( 412, modifyId, -1 );
   createMenu( 413, modifyId, -1 );
   createMenu( 416, modifyId, -1 );
   createMenu( 414, modifyId, -1 );
   createMenu( 415, modifyId, -1 );
   createMenu( 417, modifyId, -1 );
+  createMenu( 418, modifyId, -1 );
 
+  createMenu( 501, measureId, -1 );
+  createMenu( 502, measureId, -1 );
   createMenu( 214, viewId, -1 );
 
   // ----- create toolbars --------------
@@ -2897,9 +3852,12 @@ void SMESHGUI::initialize( CAM_Application* app )
   createTool( 703, meshTb );
   createTool( 704, meshTb );
   createTool( 710, meshTb );
+  createTool( 705, meshTb );
   createTool( separator(), meshTb );
   createTool( 701, meshTb );
   createTool( 711, meshTb );
+  createTool( 712, meshTb );
+  createTool( 713, meshTb );
   createTool( separator(), meshTb );
   createTool( 801, meshTb );
   createTool( 806, meshTb );
@@ -2908,16 +3866,23 @@ void SMESHGUI::initialize( CAM_Application* app )
   //createTool( 815, meshTb );
   createTool( separator(), meshTb );
   createTool( 900, meshTb );
-  createTool( 902, meshTb );
-  createTool( 903, meshTb );
+  //createTool( 902, meshTb );
+  //createTool( 903, meshTb ); // VSR: issue #0021242 (eliminate "Mesh Element Information" command)
+  createTool( 904, meshTb );
   createTool( separator(), meshTb );
 
-  createTool( 6001, ctrlTb );
+  createTool( 6005, ctrlTb );
+  createTool( 6028, ctrlTb );
+  createTool( separator(), ctrlTb );
+  createTool( 6002, ctrlTb );
   createTool( 6003, ctrlTb );
+  createTool( 6001, ctrlTb );
   createTool( 6004, ctrlTb );
+  createTool( 6029, ctrlTb );
   createTool( separator(), ctrlTb );
-  createTool( 6005, ctrlTb );
-  createTool( 6002, ctrlTb );
+  createTool( 6021, ctrlTb );
+  createTool( 6025, ctrlTb );
+  createTool( 6027, ctrlTb );
   createTool( 6018, ctrlTb );
   createTool( 6019, ctrlTb );
   createTool( 6011, ctrlTb );
@@ -2926,31 +3891,44 @@ void SMESHGUI::initialize( CAM_Application* app )
   createTool( 6014, ctrlTb );
   createTool( 6015, ctrlTb );
   createTool( 6016, ctrlTb );
+  createTool( 6022, ctrlTb );
+  createTool( 6030, ctrlTb );
   createTool( separator(), ctrlTb );
   createTool( 6017, ctrlTb );
   createTool( 6009, ctrlTb );
-  createTool( 6021, ctrlTb );
+  createTool( 6023, ctrlTb );
+  createTool( 6024, ctrlTb );
+  createTool( 6026, ctrlTb );
+  createTool( 6031, ctrlTb );
   createTool( separator(), ctrlTb );
 
-  createTool( 400, addRemTb );
-  createTool( 401, addRemTb );
+  createTool( 4000, addRemTb );
+  createTool( 4009, addRemTb );
+  createTool( 4008, addRemTb );
+  createTool( 4010, addRemTb );
   createTool( 4021, addRemTb );
   createTool( 4022, addRemTb );
   createTool( 4023, addRemTb );
   createTool( 4031, addRemTb );
   createTool( 4032, addRemTb );
+  createTool( 4133, addRemTb );
+  createTool( 4134, addRemTb );
+  createTool( 4135, addRemTb );
   createTool( 4033, addRemTb );
   createTool( separator(), addRemTb );
   createTool( 4034, addRemTb );
   createTool( 4035, addRemTb );
   createTool( 4036, addRemTb );
+  createTool( 4136, addRemTb );
   createTool( 4037, addRemTb );
   createTool( 4038, addRemTb );
   createTool( 4039, addRemTb );
   createTool( 4040, addRemTb );
+  createTool( 4140, addRemTb );
   createTool( separator(), addRemTb );
   createTool( 4041, addRemTb );
   createTool( 4042, addRemTb );
+  createTool( 4044, addRemTb );
   createTool( 4043, addRemTb );
   createTool( separator(), addRemTb );
   createTool( 4051, addRemTb );
@@ -2959,24 +3937,28 @@ void SMESHGUI::initialize( CAM_Application* app )
   createTool( 4061, addRemTb );
   createTool( 4062, addRemTb );
   createTool( 4063, addRemTb );
+  createTool( 4068, addRemTb );
   createTool( 4064, addRemTb );
   createTool( 4065, addRemTb );
   createTool( 4066, addRemTb );
+  createTool( 4069, addRemTb );
   createTool( separator(), addRemTb );
 
-  createTool( 406, modifyTb );
   createTool( 4067,modifyTb );
   createTool( 407, modifyTb );
   createTool( 408, modifyTb );
   createTool( 409, modifyTb );
+  createTool( 420, modifyTb );
   createTool( 410, modifyTb );
   createTool( 411, modifyTb );
+  createTool( 419, modifyTb );
   createTool( 412, modifyTb );
   createTool( 413, modifyTb );
   createTool( 416, modifyTb );
   createTool( 414, modifyTb );
   createTool( 415, modifyTb );
   createTool( 417, modifyTb );
+  createTool( 418, modifyTb );
 
   createTool( 214, dispModeTb );
 
@@ -2985,59 +3967,83 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   myRules.clear();
   QString OB = "'ObjectBrowser'",
-         View = "'" + SVTK_Viewer::Type() + "'",
-         pat = "'%1'",
-         mesh    = pat.arg( SMESHGUI_Selection::typeName( MESH ) ),
-         group   = pat.arg( SMESHGUI_Selection::typeName( GROUP ) ),
-         hypo    = pat.arg( SMESHGUI_Selection::typeName( HYPOTHESIS ) ),
-         algo    = pat.arg( SMESHGUI_Selection::typeName( ALGORITHM ) ),
-         elems   = QString( "'%1' '%2' '%3' '%4' '%5' '%6'" ).
+          View = "'" + SVTK_Viewer::Type() + "'",
+          pat = "'%1'",
+          mesh    = pat.arg( SMESHGUI_Selection::typeName( MESH ) ),
+          group   = pat.arg( SMESHGUI_Selection::typeName( GROUP ) ),
+          hypo    = pat.arg( SMESHGUI_Selection::typeName( HYPOTHESIS ) ),
+          algo    = pat.arg( SMESHGUI_Selection::typeName( ALGORITHM ) ),
+          elems   = QString( "'%1' '%2' '%3' '%4' '%5' '%6'" ).
                        arg( SMESHGUI_Selection::typeName( SUBMESH_VERTEX ) ).
-                      arg( SMESHGUI_Selection::typeName( SUBMESH_EDGE ) ).
-                      arg( SMESHGUI_Selection::typeName( SUBMESH_FACE ) ).
-                      arg( SMESHGUI_Selection::typeName( SUBMESH_SOLID ) ).
-                      arg( SMESHGUI_Selection::typeName( SUBMESH_COMPOUND ) ).
-                      arg( SMESHGUI_Selection::typeName( SUBMESH ) ),
+                       arg( SMESHGUI_Selection::typeName( SUBMESH_EDGE ) ).
+                       arg( SMESHGUI_Selection::typeName( SUBMESH_FACE ) ).
+                       arg( SMESHGUI_Selection::typeName( SUBMESH_SOLID ) ).
+                       arg( SMESHGUI_Selection::typeName( SUBMESH_COMPOUND ) ).
+                       arg( SMESHGUI_Selection::typeName( SUBMESH ) ),
           subMesh = elems,
-         mesh_group = mesh + " " + subMesh + " " + group,
-         hyp_alg = hypo + " " + algo;
+          mesh_part = mesh + " " + subMesh + " " + group,
+          mesh_group = mesh + " " + group,
+          hyp_alg = hypo + " " + algo;
 
   // popup for object browser
+  QString
+    isInvisible("not( isVisible )"),
+    isEmpty("numberOfNodes = 0"),
+    isNotEmpty("numberOfNodes <> 0"),
+
+    // has nodes, edges, etc in VISIBLE! actor
+    hasNodes("(numberOfNodes > 0 )"),//&& isVisible)"),
+    hasElems("(count( elemTypes ) > 0)"),
+    hasDifferentElems("(count( elemTypes ) > 1)"),
+    hasBalls("({'BallElem'} in elemTypes)"),
+    hasElems0d("({'Elem0d'} in elemTypes)"),
+    hasEdges("({'Edge'} in elemTypes)"),
+    hasFaces("({'Face'} in elemTypes)"),
+    hasVolumes("({'Volume'} in elemTypes)");
 
   createPopupItem( 150, OB, mesh, "&& selcount=1 && isImported" );      // FILE INFORMATION
   createPopupItem( 703, OB, mesh, "&& isComputable");      // CREATE_SUBMESH
-  //createPopupItem( 703, OB, subMesh, "&& isComputable" );  // CREATE_SUBMESH
   createPopupItem( 704, OB, mesh, "&& isComputable");      // EDIT_MESHSUBMESH
   createPopupItem( 704, OB, subMesh, "&& isComputable" );  // EDIT_MESHSUBMESH
   createPopupItem( 803, OB, group );                       // EDIT_GROUP
-  createPopupItem( 815, OB, group, "&& groupType = 'GroupOnGeom'" ); // EDIT_GROUP
+  createPopupItem( 815, OB, group, "&& groupType != 'Group'" ); // EDIT AS STANDALONE
 
   popupMgr()->insert( separator(), -1, 0 );
   createPopupItem( 701, OB, mesh, "&& isComputable" );     // COMPUTE
-  createPopupItem( 711, OB, mesh, "&& isComputable" );     // PRECOMPUTE
-  createPopupItem( 214, OB, mesh_group );                  // UPDATE
-  createPopupItem( 900, OB, mesh_group );                  // ADV_INFO
-  createPopupItem( 902, OB, mesh );                        // STD_INFO
-  createPopupItem( 903, OB, mesh_group );                  // WHAT_IS
+  createPopupItem( 711, OB, mesh, "&& isComputable && isPreComputable" ); // PRECOMPUTE
+  createPopupItem( 712, OB, mesh, "&& isComputable" );     // EVALUATE
+  createPopupItem( 713, OB, mesh, "&& isComputable" );     // MESH ORDER
+  createPopupItem( 214, OB, mesh_part );                   // UPDATE
+  createPopupItem( 900, OB, mesh_part );                   // ADV_INFO
+  createPopupItem( 904, OB, mesh_group );                  // FIND_ELEM
   popupMgr()->insert( separator(), -1, 0 );
   createPopupItem( 801, OB, mesh );                        // CREATE_GROUP
   createPopupItem( 806, OB, mesh );                        // CREATE_GEO_GROUP
   createPopupItem( 802, OB, subMesh );                     // CONSTRUCT_GROUP
   popupMgr()->insert( separator(), -1, 0 );
   createPopupItem( 1100, OB, hypo);                        // EDIT HYPOTHESIS
-  createPopupItem( 1102, OB, hyp_alg ); // REMOVE HYPOTHESIS / ALGORITHMS
-  createPopupItem( 1101, OB, mesh_group + " " + hyp_alg ); // RENAME
+  createPopupItem( 1102, OB, hyp_alg );                    // REMOVE HYPOTHESIS / ALGORITHMS
   popupMgr()->insert( separator(), -1, 0 );
   createPopupItem( 4043, OB, mesh );                       // CLEAR_MESH
   popupMgr()->insert( separator(), -1, 0 );
+  createPopupItem( 417, OB, mesh + " " + subMesh );        // convert to quadratic
+  createPopupItem( 418, OB, mesh + " " + group,            // create 2D mesh from 3D
+                   "&& dim>=2");
+  popupMgr()->insert( separator(), -1, 0 );
 
   QString only_one_non_empty = QString( " && %1=1 && numberOfNodes>0" ).arg( dc );
-
-  createPopupItem( 125, OB, mesh, only_one_non_empty );   // EXPORT_MED
-  createPopupItem( 126, OB, mesh, only_one_non_empty );   // EXPORT_UNV
-  createPopupItem( 141, OB, mesh, only_one_non_empty );   // EXPORT_STL
-  //createPopupItem( 33, OB, subMesh + " " + group );       // DELETE
-  createPopupItem(  33, OB, mesh_group + " " + hyp_alg ); // DELETE
+  QString multiple_non_empty = QString( " && %1>0 && numberOfNodes>0" ).arg( dc );
+  QString only_one_2D        = only_one_non_empty + " && dim>1";
+
+  createPopupItem( 125, OB, mesh_group, multiple_non_empty );   // EXPORT_MED
+  createPopupItem( 126, OB, mesh_group, only_one_non_empty );   // EXPORT_UNV
+  createPopupItem( 141, OB, mesh_group, only_one_2D );          // EXPORT_STL
+#ifdef WITH_CGNS
+  createPopupItem( 143, OB, mesh_group, multiple_non_empty );   // EXPORT_CGNS
+#endif
+  createPopupItem( 145, OB, mesh_group, multiple_non_empty );   // EXPORT_SAUV
+  createPopupItem(  33, OB, mesh_part + " " + hyp_alg );        // DELETE
+  createPopupItem( 813, OB, group );                            // DEL_GROUP with contents
   popupMgr()->insert( separator(), -1, 0 );
 
   // popup for viewer
@@ -3046,10 +4052,9 @@ void SMESHGUI::initialize( CAM_Application* app )
   createPopupItem( 805, View, elems ); // REMOVE
 
   popupMgr()->insert( separator(), -1, 0 );
-  createPopupItem( 214, View, mesh_group ); // UPDATE
-  createPopupItem( 900, View, mesh_group ); // ADV_INFO
-  createPopupItem( 902, View, mesh );       // STD_INFO
-  createPopupItem( 903, View, mesh_group ); // WHAT_IS
+  createPopupItem( 214, View, mesh_part );  // UPDATE
+  createPopupItem( 900, View, mesh_part );  // ADV_INFO
+  createPopupItem( 904, View, mesh );       // FIND_ELEM
   popupMgr()->insert( separator(), -1, 0 );
 
   createPopupItem( 1136, OB + " " + View, mesh, "&& (not isAutoColor)" ); // AUTO_COLOR
@@ -3057,22 +4062,9 @@ void SMESHGUI::initialize( CAM_Application* app )
   popupMgr()->insert( separator(), -1, 0 );
 
   int anId;
-  QString
-    isInvisible("not( isVisible )"),
-    isEmpty("numberOfNodes = 0"),
-    isNotEmpty("numberOfNodes <> 0"),
-
-    // has nodes, edges, etc in VISIBLE! actor
-    hasNodes("(numberOfNodes > 0 )"),//&& isVisible)"),
-    hasElems("(count( elemTypes ) > 0)"),
-    hasDifferentElems("(count( elemTypes ) > 1)"),
-    hasEdges("({'Edge'} in elemTypes)"),
-    hasFaces("({'Face'} in elemTypes)"),
-    hasVolumes("({'Volume'} in elemTypes)");
-
   QString aClient = QString( "%1client in {%2}" ).arg( lc ).arg( "'VTKViewer'" );
   QString aType = QString( "%1type in {%2}" ).arg( lc );
-  aType = aType.arg( mesh_group );
+  aType = aType.arg( mesh_part );
   QString aMeshInVTK = aClient + "&&" + aType;
 
   aClient = "($client in {'VTKViewer' 'ObjectBrowser'})";
@@ -3124,6 +4116,10 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   anId = popupMgr()->insert( tr( "MEN_DISP_ENT" ), -1, -1 );
 
+  popupMgr()->insert( action(216), anId, -1 ); // ELEMS 0D
+  popupMgr()->setRule(action(216), aDiffElemsInVTK + "&& isVisible &&" + hasElems0d, QtxPopupMgr::VisibleRule);
+  popupMgr()->setRule(action(216), "{'Elem0d'} in entityMode", QtxPopupMgr::ToggleRule);
+
   popupMgr()->insert( action( 217 ), anId, -1 ); // EDGES
   popupMgr()->setRule( action( 217 ), aDiffElemsInVTK + "&& isVisible &&" + hasEdges, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 217 ), "{'Edge'} in entityMode", QtxPopupMgr::ToggleRule );
@@ -3136,11 +4132,28 @@ void SMESHGUI::initialize( CAM_Application* app )
   popupMgr()->setRule( action( 219 ), aDiffElemsInVTK + "&& isVisible &&" + hasVolumes, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 219 ), "{'Volume'} in entityMode", QtxPopupMgr::ToggleRule );
 
+  popupMgr()->insert( action( 222 ), anId, -1 ); // BALLS
+  popupMgr()->setRule( action( 222 ), aDiffElemsInVTK + "&& isVisible &&" + hasBalls, QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 222 ), "{'BallElem'} in entityMode", QtxPopupMgr::ToggleRule );
+
   popupMgr()->insert( separator(), anId, -1 );
 
   popupMgr()->insert( action( 220 ), anId, -1 ); // ALL
   popupMgr()->setRule( action( 220 ), aDiffElemsInVTK + "&& isVisible && not( elemTypes in entityMode )", QtxPopupMgr::VisibleRule );
 
+
+  //-------------------------------------------------
+  // Representation of the 2D Quadratic elements
+  //-------------------------------------------------
+  anId = popupMgr()->insert( tr( "MEN_QUADRATIC_REPRESENT" ), -1, -1 );
+  popupMgr()->insert( action( 231 ), anId, -1 ); // LINE REPRESENTATION
+  popupMgr()->setRule( action( 231 ), aMeshInVTK + "and isVisible",QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 231 ), "quadratic2DMode = 'eLines'", QtxPopupMgr::ToggleRule );
+
+  popupMgr()->insert( action( 232 ), anId, -1 ); // ARC REPRESENTATION
+  popupMgr()->setRule( action( 232 ), aMeshInVTK + "and isVisible", QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 232 ), "quadratic2DMode = 'eArcs'", QtxPopupMgr::ToggleRule );
+
   //-------------------------------------------------
   // Orientation of faces
   //-------------------------------------------------
@@ -3160,14 +4173,6 @@ void SMESHGUI::initialize( CAM_Application* app )
   popupMgr()->insert( action( 1133 ), -1, -1 );
   popupMgr()->setRule( action( 1133 ), aMeshInVTK + "&& isVisible", QtxPopupMgr::VisibleRule );
 
-  //-------------------------------------------------
-  // Clipping
-  //-------------------------------------------------
-  popupMgr()->insert( action( 1134 ), -1, -1 );
-  popupMgr()->setRule( action( 1134 ), aMeshInVTK + "&& selcount=1 && isVisible", QtxPopupMgr::VisibleRule );
-
-  popupMgr()->insert( separator(), -1, -1 );
-
   //-------------------------------------------------
   // Controls
   //-------------------------------------------------
@@ -3184,85 +4189,142 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   popupMgr()->insert( separator(), anId, -1 );
 
-  popupMgr()->insert( action( 6003 ), anId, -1 ); // FREE_BORDER
+  int aSubId = popupMgr()->insert( tr( "MEN_NODE_CTRL" ), anId, -1 ); // NODE CONTROLS
+
+  popupMgr()->insert( action( 6005 ), aSubId, -1 ); // FREE_NODE
+  popupMgr()->setRule( action( 6005 ), aMeshInVtkHasNodes, QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 6005 ), "controlMode = 'eFreeNodes'", QtxPopupMgr::ToggleRule );
+
+  popupMgr()->insert ( action( 6028 ), aSubId, -1 ); // EQUAL_NODE
+  popupMgr()->setRule( action( 6028 ), aMeshInVtkHasNodes, QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 6028 ), "controlMode = 'eCoincidentNodes'", QtxPopupMgr::ToggleRule);
+
+  aSubId = popupMgr()->insert( tr( "MEN_EDGE_CTRL" ), anId, -1 ); // EDGE CONTROLS
+
+  popupMgr()->insert( action( 6002 ), aSubId, -1 ); // FREE_EDGE
+  popupMgr()->setRule( action( 6002 ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 6002 ), "controlMode = 'eFreeEdges'", QtxPopupMgr::ToggleRule );
+
+  popupMgr()->insert( action( 6003 ), aSubId, -1 ); // FREE_BORDER
   popupMgr()->setRule( action( 6003 ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6003 ), "controlMode = 'eFreeBorders'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6001 ), anId, -1 ); // LENGTH
+  popupMgr()->insert( action( 6001 ), aSubId, -1 ); // LENGTH
   popupMgr()->setRule( action( 6001 ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6001 ), "controlMode = 'eLength'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6004 ), anId, -1 ); // CONNECTION
+  popupMgr()->insert( action( 6004 ), aSubId, -1 ); // CONNECTION
   popupMgr()->setRule( action( 6004 ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6004 ), "controlMode = 'eMultiConnection'", QtxPopupMgr::ToggleRule );
+  popupMgr()->insert ( action( 6029 ), aSubId, -1 ); // EQUAL_EDGE
+  popupMgr()->setRule( action( 6029 ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 6029 ), "controlMode = 'eCoincidentElems1D'", QtxPopupMgr::ToggleRule);
 
-  popupMgr()->insert( separator(), anId, -1 );
-
-  popupMgr()->insert( action( 6005 ), anId, -1 ); // FREE_NODE
-  popupMgr()->setRule( action( 6005 ), aMeshInVtkHasNodes, QtxPopupMgr::VisibleRule );
-  popupMgr()->setRule( action( 6005 ), "controlMode = 'eFreeNodes'", QtxPopupMgr::ToggleRule );
+  aSubId = popupMgr()->insert( tr( "MEN_FACE_CTRL" ), anId, -1 ); // FACE CONTROLS
 
-  popupMgr()->insert( action( 6002 ), anId, -1 ); // FREE_EDGE
-  popupMgr()->setRule( action( 6002 ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule );
-  popupMgr()->setRule( action( 6002 ), "controlMode = 'eFreeEdges'", QtxPopupMgr::ToggleRule );
+  popupMgr()->insert ( action( 6021 ), aSubId, -1 ); // FREE_FACE
+  popupMgr()->setRule( action( 6021 ), aMeshInVtkHasFaces /*aMeshInVtkHasVolumes*/,
+                                       QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 6021 ), "controlMode = 'eFreeFaces'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6018 ), anId, -1 ); // LENGTH_2D
+  popupMgr()->insert ( action( 6018 ), aSubId, -1 ); // LENGTH_2D
   popupMgr()->setRule( action( 6018 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6018 ), "controlMode = 'eLength2D'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6019 ), anId, -1 ); // CONNECTION_2D
+  popupMgr()->insert ( action( 6019 ), aSubId, -1 ); // CONNECTION_2D
   popupMgr()->setRule( action( 6019 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6019 ), "controlMode = 'eMultiConnection2D'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6011 ), anId, -1 ); // AREA
+  popupMgr()->insert ( action( 6011 ), aSubId, -1 ); // AREA
   popupMgr()->setRule( action( 6011 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6011 ), "controlMode = 'eArea'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6012 ), anId, -1 ); // TAPER
+  popupMgr()->insert ( action( 6012 ), aSubId, -1 ); // TAPER
   popupMgr()->setRule( action( 6012 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6012 ), "controlMode = 'eTaper'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6013 ), anId, -1 ); // ASPECT
+  popupMgr()->insert ( action( 6013 ), aSubId, -1 ); // ASPECT
   popupMgr()->setRule( action( 6013 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6013 ), "controlMode = 'eAspectRatio'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6014 ), anId, -1 ); // MIN_ANG
+  popupMgr()->insert ( action( 6014 ), aSubId, -1 ); // MIN_ANG
   popupMgr()->setRule( action( 6014 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6014 ), "controlMode = 'eMinimumAngle'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6015 ), anId, -1 ); // WARP
+  popupMgr()->insert ( action( 6015 ), aSubId, -1 ); // WARP
   popupMgr()->setRule( action( 6015 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6015 ), "controlMode = 'eWarping'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6016 ), anId, -1 ); // SKEW
+  popupMgr()->insert ( action( 6016 ), aSubId, -1 ); // SKEW
   popupMgr()->setRule( action( 6016 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6016 ), "controlMode = 'eSkew'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( separator(), anId, -1 );
+  popupMgr()->insert ( action( 6022 ), aSubId, -1 ); // MAX_ELEMENT_LENGTH_2D
+  popupMgr()->setRule( action( 6022 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 6022 ), "controlMode = 'eMaxElementLength2D'", QtxPopupMgr::ToggleRule );
+
+  popupMgr()->insert ( action( 6025 ), aSubId, -1 ); // BARE_BORDER_FACE
+  popupMgr()->setRule( action( 6025 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 6025 ), "controlMode = 'eBareBorderFace'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6017 ), anId, -1 ); // ASPECT_3D
+  popupMgr()->insert ( action( 6027 ), aSubId, -1 ); // OVER_CONSTRAINED_FACE
+  popupMgr()->setRule( action( 6027 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 6027 ), "controlMode = 'eOverConstrainedFace'", QtxPopupMgr::ToggleRule );
+  popupMgr()->insert ( action( 6030 ), aSubId, -1 ); // EQUAL_FACE
+  popupMgr()->setRule( action( 6030 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 6030 ), "controlMode = 'eCoincidentElems2D'", QtxPopupMgr::ToggleRule );
+
+  aSubId = popupMgr()->insert( tr( "MEN_VOLUME_CTRL" ), anId, -1 ); // VOLUME CONTROLS
+
+  popupMgr()->insert ( action( 6017 ), aSubId, -1 ); // ASPECT_3D
   popupMgr()->setRule( action( 6017 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6017 ), "controlMode = 'eAspectRatio3D'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert ( action( 6009 ), anId, -1 ); // VOLUME_3D
+  popupMgr()->insert ( action( 6009 ), aSubId, -1 ); // VOLUME_3D
   popupMgr()->setRule( action( 6009 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6009 ), "controlMode = 'eVolume3D'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6021 ), anId, -1 ); // FREE_FACE
-  popupMgr()->setRule( action( 6021 ), aMeshInVtkHasFaces /*aMeshInVtkHasVolumes*/,
-                                       QtxPopupMgr::VisibleRule );
-  popupMgr()->setRule( action( 6021 ), "controlMode = 'eFreeFaces'", QtxPopupMgr::ToggleRule );
+  popupMgr()->insert ( action( 6023 ), aSubId, -1 ); // MAX_ELEMENT_LENGTH_3D
+  popupMgr()->setRule( action( 6023 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 6023 ), "controlMode = 'eMaxElementLength3D'", QtxPopupMgr::ToggleRule );
+
+  popupMgr()->insert ( action( 6024 ), aSubId, -1 ); // BARE_BORDER_VOLUME
+  popupMgr()->setRule( action( 6024 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 6024 ), "controlMode = 'eBareBorderVolume'", QtxPopupMgr::ToggleRule );
+
+  popupMgr()->insert ( action( 6026 ), aSubId, -1 ); // OVER_CONSTRAINED_VOLUME
+  popupMgr()->setRule( action( 6026 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 6026 ), "controlMode = 'eOverConstrainedVolume'", QtxPopupMgr::ToggleRule );
+
+  popupMgr()->insert ( action( 6031 ), aSubId, -1 ); // EQUAL_VOLUME
+  popupMgr()->setRule( action( 6031 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 6031 ), "controlMode = 'eCoincidentElems3D'", QtxPopupMgr::ToggleRule );
 
   popupMgr()->insert( separator(), anId, -1 );
 
   popupMgr()->insert( action( 201 ), anId, -1 ); // SCALAR_BAR_PROP
   popupMgr()->setRule( action( 201 ), aMeshInVTK + "&& controlMode <> 'eNone'", QtxPopupMgr::VisibleRule );
 
-  popupMgr()->insert( separator(), -1, -1 );
+  popupMgr()->insert( separator(), anId, -1 );
+
+  aSubId = popupMgr()->insert( tr( "MEN_DISTRIBUTION_CTRL" ), anId, -1 ); // NODE CONTROLS
+
+  popupMgr()->insert( action( 2021 ), aSubId, -1 ); // SAVE_DISTRIBUTION
+  popupMgr()->setRule( action( 2021 ), aMeshInVTK + "&& isNumFunctor", QtxPopupMgr::VisibleRule );
+
+  popupMgr()->insert( action( 2022 ), aSubId, -1 ); // SHOW_DISTRIBUTION
+  popupMgr()->setRule( action( 2022 ), aMeshInVTK + "&& isNumFunctor", QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 2022 ), aMeshInVTK + "&& isNumFunctor && isDistributionVisible", QtxPopupMgr::ToggleRule);
+
+#ifndef DISABLE_PLOT2DVIEWER
+  popupMgr()->insert( action( 2023 ), aSubId, -1 ); // PLOT_DISTRIBUTION
+  popupMgr()->setRule( action( 2023 ), aMeshInVTK + "&& isNumFunctor", QtxPopupMgr::VisibleRule );
+#endif
 
   //-------------------------------------------------
   // Display / Erase
   //-------------------------------------------------
+  popupMgr()->insert( separator(), -1, -1 );
   QString aRule = "$component={'SMESH'} and ( type='Component' or (" + aClient + " and " +
     aType + " and " + aSelCount + " and " + anActiveVTK + " and " + isNotEmpty + " %1 ) )";
   popupMgr()->insert( action( 301 ), -1, -1 ); // DISPLAY
@@ -3276,8 +4338,19 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   popupMgr()->insert( separator(), -1, -1 );
 
+  //-------------------------------------------------
+  // Clipping
+  //-------------------------------------------------
+  popupMgr()->insert( action( 1134 ), -1, -1 );
+  popupMgr()->setRule( action( 1134 ), "client='VTKViewer'", QtxPopupMgr::VisibleRule );
+
+  popupMgr()->insert( separator(), -1, -1 );
+
   connect( application(), SIGNAL( viewManagerActivated( SUIT_ViewManager* ) ),
-          this, SLOT( onViewManagerActivated( SUIT_ViewManager* ) ) );
+           this, SLOT( onViewManagerActivated( SUIT_ViewManager* ) ) );
+
+  connect( application(), SIGNAL( viewManagerRemoved( SUIT_ViewManager* ) ),
+           this, SLOT( onViewManagerRemoved( SUIT_ViewManager* ) ) );
 }
 
 //================================================================================
@@ -3304,6 +4377,13 @@ bool SMESHGUI::isSelectionCompatible()
   return isCompatible;
 }
 
+
+bool SMESHGUI::reusableOperation( const int id )
+{
+  // compute, evaluate and precompute are not reusable operations
+  return ( id == 701 || id == 711 || id == 712 ) ? false : SalomeApp_Module::reusableOperation( id );
+}
+
 bool SMESHGUI::activateModule( SUIT_Study* study )
 {
   bool res = SalomeApp_Module::activateModule( study );
@@ -3311,13 +4391,45 @@ bool SMESHGUI::activateModule( SUIT_Study* study )
   setMenuShown( true );
   setToolShown( true );
 
+  // import Python module that manages SMESH plugins (need to be here because SalomePyQt API uses active module)
+  PyGILState_STATE gstate = PyGILState_Ensure();
+  PyObject* pluginsmanager=PyImport_ImportModuleNoBlock((char*)"salome_pluginsmanager");
+  if(pluginsmanager==NULL)
+    PyErr_Print();
+  else
+    {
+      PyObject* result=PyObject_CallMethod( pluginsmanager, (char*)"initialize", (char*)"isss",1,"smesh",tr("MEN_MESH").toStdString().c_str(),tr("SMESH_PLUGINS_OTHER").toStdString().c_str());
+      if(result==NULL)
+        PyErr_Print();
+      Py_XDECREF(result);
+    }
+  PyGILState_Release(gstate);
+  // end of GEOM plugins loading
+
   // Reset actions accelerator keys
   action(111)->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_B)); // Import DAT
   action(112)->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_U)); // Import UNV
   action(113)->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_M)); // Import MED
 
   action(  33)->setEnabled(true); // Delete: Key_Delete
-  action(1101)->setEnabled(true); // Rename: Key_F2
+
+  //  0020210. Make SMESH_Gen update meshes at switching GEOM->SMESH
+  GetSMESHGen()->SetCurrentStudy(SALOMEDS::Study::_nil());
+  if ( SalomeApp_Study* s = dynamic_cast<SalomeApp_Study*>( study ))
+    if ( _PTR(Study) aStudy = s->studyDS()) {
+      GetSMESHGen()->SetCurrentStudy( _CAST(Study,aStudy)->GetStudy() );
+      updateObjBrowser(); // objects can be removed
+    }
+
+  // get all view currently opened in the study and connect their signals  to
+  // the corresponding slots of the class.
+  SUIT_Desktop* aDesk = study->application()->desktop();
+  if ( aDesk ) {
+    QList<SUIT_ViewWindow*> wndList = aDesk->windows();
+    SUIT_ViewWindow* wnd;
+    foreach ( wnd, wndList )
+      connectView( wnd );
+  }
 
   return res;
 }
@@ -3335,7 +4447,6 @@ bool SMESHGUI::deactivateModule( SUIT_Study* study )
   action(113)->setShortcut(QKeySequence()); // Import MED
 
   action(  33)->setEnabled(false); // Delete: Key_Delete
-  action(1101)->setEnabled(false); // Rename: Key_F2
 
   return SalomeApp_Module::deactivateModule( study );
 }
@@ -3391,7 +4502,7 @@ void SMESHGUI::contextMenuPopup( const QString& client, QMenu* menu, QString& ti
     if ( obj ) {
       QString aName = QString( obj->GetName().c_str() );
       while ( aName.at( aName.length() - 1 ) == ' ' ) // Remove extraspaces in Name of Popup
-         aName.remove( (aName.length() - 1), 1 );
+          aName.remove( (aName.length() - 1), 1 );
       title = aName;
     }
   }
@@ -3415,8 +4526,58 @@ void SMESHGUI::viewManagers( QStringList& list ) const
 
 void SMESHGUI::onViewManagerActivated( SUIT_ViewManager* mgr )
 {
-  if ( dynamic_cast<SVTK_ViewManager*>( mgr ) )
+  if ( dynamic_cast<SVTK_ViewManager*>( mgr ) ) {
     SMESH::UpdateSelectionProp( this );
+
+    QVector<SUIT_ViewWindow*> aViews = mgr->getViews();
+    for(int i = 0; i < aViews.count() ; i++){
+      SUIT_ViewWindow *sf = aViews[i];
+      connectView( sf );
+    }
+  }
+}
+
+void SMESHGUI::onViewManagerRemoved( SUIT_ViewManager* theViewManager )
+{
+  if( theViewManager && theViewManager->getType() == SVTK_Viewer::Type() )
+    myClippingPlaneInfoMap.erase( theViewManager );
+}
+
+void SMESHGUI::addActorAsObserver( SMESH_Actor* theActor )
+{
+  theActor->AddObserver( SMESH::DeleteActorEvent,
+                         myEventCallbackCommand.GetPointer(),
+                         myPriority );
+}
+
+void SMESHGUI::ProcessEvents( vtkObject* theObject,
+                              unsigned long theEvent,
+                              void* theClientData,
+                              void* theCallData )
+{
+  if( SMESHGUI* aSMESHGUI = reinterpret_cast<SMESHGUI*>( theClientData ) ) {
+    if( theObject && theEvent == SMESH::DeleteActorEvent ) {
+      if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( theObject ) ) {
+        SMESHGUI_ClippingPlaneInfoMap& aClippingPlaneInfoMap = aSMESHGUI->getClippingPlaneInfoMap();
+        SMESHGUI_ClippingPlaneInfoMap::iterator anIter1 = aClippingPlaneInfoMap.begin();
+        for( ; anIter1 != aClippingPlaneInfoMap.end(); anIter1++ ) {
+          SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = anIter1->second;
+          SMESHGUI_ClippingPlaneInfoList::iterator anIter2 = aClippingPlaneInfoList.begin();
+          for( ; anIter2 != aClippingPlaneInfoList.end(); anIter2++ ) {
+            SMESH::ClippingPlaneInfo& aClippingPlaneInfo = *anIter2;
+            std::list<vtkActor*>& anActorList = aClippingPlaneInfo.ActorList;
+            SMESH::TActorList::iterator anIter3 = anActorList.begin();
+            for ( ; anIter3 != anActorList.end(); anIter3++ ) {
+              if( anActor == *anIter3 ) {
+                anActorList.erase( anIter3 );
+                break;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
 }
 
 void SMESHGUI::createPreferences()
@@ -3424,8 +4585,12 @@ void SMESHGUI::createPreferences()
   // General tab ------------------------------------------------------------------------
   int genTab = addPreference( tr( "PREF_TAB_GENERAL" ) );
 
-  int updateGroup = addPreference( tr( "PREF_GROUP_UPDATE" ), genTab );
-  addPreference( tr( "PREF_AUTO_UPDATE" ), updateGroup, LightApp_Preferences::Bool, "SMESH", "auto_update" );
+  int autoUpdate = addPreference( tr( "PREF_AUTO_UPDATE" ), genTab, LightApp_Preferences::Auto, "SMESH", "auto_update" );
+  int lim = addPreference( tr( "PREF_UPDATE_LIMIT" ), autoUpdate, LightApp_Preferences::IntSpin, "SMESH", "update_limit" );
+  setPreferenceProperty( lim, "min",  0 );
+  setPreferenceProperty( lim, "max",  100000000 );
+  setPreferenceProperty( lim, "step", 1000 );
+  setPreferenceProperty( lim, "special", tr( "PREF_UPDATE_LIMIT_NOLIMIT" ) );
 
   int qaGroup = addPreference( tr( "PREF_GROUP_QUALITY" ), genTab );
   setPreferenceProperty( qaGroup, "columns", 2 );
@@ -3434,15 +4599,20 @@ void SMESHGUI::createPreferences()
   int prec = addPreference( tr( "PREF_PRECISION_VALUE" ), qaGroup, LightApp_Preferences::IntSpin, "SMESH", "controls_precision" );
   setPreferenceProperty( prec, "min", 0 );
   setPreferenceProperty( prec, "max", 16 );
+  int doubleNodesTol = addPreference( tr( "PREF_EQUAL_NODES_TOL" ), qaGroup, LightApp_Preferences::DblSpin, "SMESH", "equal_nodes_tolerance" );
+  setPreferenceProperty( doubleNodesTol, "precision", 10 );
+  setPreferenceProperty( doubleNodesTol, "min", 0.0000000001 );
+  setPreferenceProperty( doubleNodesTol, "max", 1000000.0 );
+  setPreferenceProperty( doubleNodesTol, "step", 0.0000001 );
 
   int dispgroup = addPreference( tr( "PREF_DISPLAY_MODE" ), genTab );
   setPreferenceProperty( dispgroup, "columns", 2 );
   int dispmode = addPreference( tr( "PREF_DISPLAY_MODE" ), dispgroup, LightApp_Preferences::Selector, "SMESH", "display_mode" );
   QStringList modes;
-  modes.append( "Wireframe" );
-  modes.append( "Shading" );
-  modes.append( "Nodes" );
-  modes.append( "Shrink" );
+  modes.append( tr("MEN_WIRE") );
+  modes.append( tr("MEN_SHADE") );
+  modes.append( tr("MEN_NODES") );
+  modes.append( tr("MEN_SHRINK") );
   QList<QVariant> indices;
   indices.append( 0 );
   indices.append( 1 );
@@ -3451,6 +4621,25 @@ void SMESHGUI::createPreferences()
   setPreferenceProperty( dispmode, "strings", modes );
   setPreferenceProperty( dispmode, "indexes", indices );
 
+  int arcgroup = addPreference( tr( "QUADRATIC_REPRESENT_MODE" ), genTab );
+  setPreferenceProperty( arcgroup, "columns", 2 );
+  int quadraticmode = addPreference( tr( "QUADRATIC_REPRESENT_MODE" ), arcgroup, LightApp_Preferences::Selector, "SMESH", "quadratic_mode" );
+  QStringList quadraticModes;
+  quadraticModes.append(tr("MEN_LINE_REPRESENTATION"));
+  quadraticModes.append(tr("MEN_ARC_REPRESENTATION"));
+  indices.clear();
+  indices.append( 0 );
+  indices.append( 1 );
+  setPreferenceProperty( quadraticmode, "strings", quadraticModes );
+  setPreferenceProperty( quadraticmode, "indexes", indices );
+
+  int maxAngle = addPreference( tr( "MAX_ARC_ANGLE" ), arcgroup, LightApp_Preferences::IntSpin,
+                              "SMESH", "max_angle" );
+  setPreferenceProperty( maxAngle, "min", 1 );
+  setPreferenceProperty( maxAngle, "max", 90 );
+
+
+
   int exportgroup = addPreference( tr( "PREF_GROUP_EXPORT" ), genTab );
   setPreferenceProperty( exportgroup, "columns", 2 );
   addPreference( tr( "PREF_AUTO_GROUPS" ), exportgroup, LightApp_Preferences::Bool, "SMESH", "auto_groups" );
@@ -3460,9 +4649,9 @@ void SMESHGUI::createPreferences()
   setPreferenceProperty( computeGroup, "columns", 2 );
   int notifyMode = addPreference( tr( "PREF_NOTIFY_MODE" ), computeGroup, LightApp_Preferences::Selector, "SMESH", "show_result_notification" );
   modes.clear();
-  modes.append( "Never" );
-  modes.append( "Errors only" );
-  modes.append( "Always" );
+  modes.append( tr( "PREF_NOTIFY_NEVER" ) );
+  modes.append( tr( "PREF_NOTIFY_ERROR" ) );
+  modes.append( tr( "PREF_NOTIFY_ALWAYS" ) );
   indices.clear();
   indices.append( 0 );
   indices.append( 1 );
@@ -3470,6 +4659,23 @@ void SMESHGUI::createPreferences()
   setPreferenceProperty( notifyMode, "strings", modes );
   setPreferenceProperty( notifyMode, "indexes", indices );
 
+  int infoGroup = addPreference( tr( "PREF_GROUP_INFO" ), genTab );
+  setPreferenceProperty( infoGroup, "columns", 4 );
+  int elemInfo = addPreference( tr( "PREF_ELEM_INFO" ), infoGroup, LightApp_Preferences::Selector, "SMESH", "mesh_elem_info" );
+  modes.clear();
+  modes.append( tr( "PREF_ELEM_INFO_SIMPLE" ) );
+  modes.append( tr( "PREF_ELEM_INFO_TREE" ) );
+  indices.clear();
+  indices.append( 0 );
+  indices.append( 1 );
+  setPreferenceProperty( elemInfo, "strings", modes );
+  setPreferenceProperty( elemInfo, "indexes", indices );
+  int nodesLim = addPreference( tr( "PREF_GPP_NODES_LIMIT" ), infoGroup, LightApp_Preferences::IntSpin, "SMESH", "info_groups_nodes_limit" );
+  setPreferenceProperty( nodesLim, "min", 0 );
+  setPreferenceProperty( nodesLim, "max", 10000000 );
+  setPreferenceProperty( nodesLim, "step", 10000 );
+  setPreferenceProperty( nodesLim, "special", tr( "PREF_UPDATE_LIMIT_NOLIMIT" ) );
+
   int segGroup = addPreference( tr( "PREF_GROUP_SEGMENT_LENGTH" ), genTab );
   setPreferenceProperty( segGroup, "columns", 2 );
   int segLen = addPreference( tr( "PREF_SEGMENT_LENGTH" ), segGroup, LightApp_Preferences::IntSpin,
@@ -3481,30 +4687,109 @@ void SMESHGUI::createPreferences()
   setPreferenceProperty( nbSeg, "min", 1 );
   setPreferenceProperty( nbSeg, "max", 10000000 );
 
+  int loadGroup = addPreference( tr( "SMESH_PREF_MESH_LOADING" ), genTab );
+  addPreference( tr( "PREF_FORGET_MESH_AT_HYP_MODIF" ), loadGroup, LightApp_Preferences::Bool,
+                 "SMESH", "forget_mesh_on_hyp_modif" );
+
+
+  // Quantities with individual precision settings
+  int precGroup = addPreference( tr( "SMESH_PREF_GROUP_PRECISION" ), genTab );
+  setPreferenceProperty( precGroup, "columns", 2 );
+
+  const int nbQuantities = 6;
+  int precs[nbQuantities], ii = 0;
+  precs[ii++] = addPreference( tr( "SMESH_PREF_length_precision" ), precGroup,
+                            LightApp_Preferences::IntSpin, "SMESH", "length_precision" );
+  precs[ii++] = addPreference( tr( "SMESH_PREF_angle_precision" ), precGroup,
+                            LightApp_Preferences::IntSpin, "SMESH", "angle_precision" );
+  precs[ii++] = addPreference( tr( "SMESH_PREF_len_tol_precision" ), precGroup,
+                            LightApp_Preferences::IntSpin, "SMESH", "len_tol_precision" );
+  precs[ii++] = addPreference( tr( "SMESH_PREF_parametric_precision" ), precGroup,
+                            LightApp_Preferences::IntSpin, "SMESH", "parametric_precision" );
+  precs[ii++] = addPreference( tr( "SMESH_PREF_area_precision" ), precGroup,
+                            LightApp_Preferences::IntSpin, "SMESH", "area_precision" );
+  precs[ii  ] = addPreference( tr( "SMESH_PREF_vol_precision" ), precGroup,
+                            LightApp_Preferences::IntSpin, "SMESH", "vol_precision" );
+
+  // Set property for precision value for spinboxes
+  for ( ii = 0; ii < nbQuantities; ii++ ){
+    setPreferenceProperty( precs[ii], "min", -14 );
+    setPreferenceProperty( precs[ii], "max", 14 );
+    setPreferenceProperty( precs[ii], "precision", 2 );
+  }
+
+  int previewGroup = addPreference( tr( "SMESH_PREF_GROUP_PREVIEW" ), genTab );
+  setPreferenceProperty( previewGroup, "columns", 2 );
+  int chunkSize = addPreference( tr( "PREF_PREVIEW_CHUNK_SIZE" ), previewGroup, LightApp_Preferences::IntSpin, "SMESH", "preview_actor_chunk_size" );
+  setPreferenceProperty( chunkSize, "min",  0 );
+  setPreferenceProperty( chunkSize, "max",  1000 );
+  setPreferenceProperty( chunkSize, "step", 50 );
+
+  int pyDumpGroup = addPreference( tr( "PREF_PYTHON_DUMP" ), genTab );
+  addPreference( tr( "PREF_HISTORICAL_PYTHON_DUMP" ), pyDumpGroup, LightApp_Preferences::Bool, "SMESH", "historical_python_dump" );
+
   // Mesh tab ------------------------------------------------------------------------
   int meshTab = addPreference( tr( "PREF_TAB_MESH" ) );
   int nodeGroup = addPreference( tr( "PREF_GROUP_NODES" ), meshTab );
-  setPreferenceProperty( nodeGroup, "columns", 2 );
+  setPreferenceProperty( nodeGroup, "columns", 3 );
 
   addPreference( tr( "PREF_COLOR" ), nodeGroup, LightApp_Preferences::Color, "SMESH", "node_color" );
-  int nodeSz = addPreference( tr( "PREF_SIZE" ), nodeGroup, LightApp_Preferences::IntSpin, "SMESH", "node_size" );
 
-  setPreferenceProperty( nodeSz, "min", 1 );
-  setPreferenceProperty( nodeSz, "max", 5 );
+  int typeOfMarker = addPreference( tr( "PREF_TYPE_OF_MARKER" ), nodeGroup, LightApp_Preferences::Selector, "SMESH", "type_of_marker" );
+
+  SUIT_ResourceMgr* aResourceMgr = SMESH::GetResourceMgr(this);
+  QList<QVariant> aMarkerTypeIndicesList;
+  QList<QVariant> aMarkerTypeIconsList;
+  for ( int i = VTK::MT_POINT; i < VTK::MT_USER; i++ ) {
+    QString icoFile = QString( "ICON_VERTEX_MARKER_%1" ).arg( i );
+    QPixmap pixmap = aResourceMgr->loadPixmap( "VTKViewer", tr( qPrintable( icoFile ) ) );
+    aMarkerTypeIndicesList << i;
+    aMarkerTypeIconsList << pixmap;
+  }
+  setPreferenceProperty( typeOfMarker, "indexes", aMarkerTypeIndicesList );
+  setPreferenceProperty( typeOfMarker, "icons",   aMarkerTypeIconsList );
+
+  int markerScale = addPreference( tr( "PREF_MARKER_SCALE" ), nodeGroup, LightApp_Preferences::Selector, "SMESH", "marker_scale" );
+
+  QList<QVariant> aMarkerScaleIndicesList;
+  QStringList     aMarkerScaleValuesList;
+  for ( int i = VTK::MS_10; i <= VTK::MS_70; i++ ) {
+    aMarkerScaleIndicesList << i;
+    aMarkerScaleValuesList  << QString::number( (i-(int)VTK::MS_10)*0.5 + 1.0 );
+  }
+  setPreferenceProperty( markerScale, "strings", aMarkerScaleValuesList );
+  setPreferenceProperty( markerScale, "indexes", aMarkerScaleIndicesList );
 
   int elemGroup = addPreference( tr( "PREF_GROUP_ELEMENTS" ), meshTab );
   setPreferenceProperty( elemGroup, "columns", 2 );
 
-  addPreference( tr( "PREF_FILL" ), elemGroup, LightApp_Preferences::Color, "SMESH", "fill_color" );
-  addPreference( tr( "PREF_OUTLINE" ), elemGroup, LightApp_Preferences::Color, "SMESH", "outline_color" );
-  addPreference( tr( "PREF_BACKFACE" ), elemGroup, LightApp_Preferences::Color, "SMESH", "backface_color" );
-  int sp = addPreference( "", elemGroup, LightApp_Preferences::Space );
+  int ColorId = addPreference( tr( "PREF_FILL"     ), elemGroup, LightApp_Preferences::BiColor, "SMESH", "fill_color" );
+  addPreference( tr( "PREF_COLOR_0D" ), elemGroup, LightApp_Preferences::Color, "SMESH", "elem0d_color" );
+  addPreference( tr( "PREF_BALL_COLOR" ), elemGroup, LightApp_Preferences::Color, "SMESH", "ball_elem_color" );
+  addPreference( tr( "PREF_OUTLINE"  ), elemGroup, LightApp_Preferences::Color, "SMESH", "outline_color" );
+  addPreference( tr( "PREF_WIREFRAME"  ), elemGroup, LightApp_Preferences::Color, "SMESH", "wireframe_color" );
 
-  setPreferenceProperty( sp, "hstretch", 0 );
-  setPreferenceProperty( sp, "vstretch", 0 );
+  setPreferenceProperty( ColorId, "text", tr("PREF_BACKFACE") );
 
-  int elemW = addPreference( tr( "PREF_WIDTH" ), elemGroup, LightApp_Preferences::IntSpin, "SMESH", "element_width" );
-  int shrink = addPreference( tr( "PREF_SHRINK_COEFF" ), elemGroup, LightApp_Preferences::IntSpin, "SMESH", "shrink_coeff" );
+  int grpGroup = addPreference( tr( "PREF_GROUP_GROUPS" ), meshTab );
+  setPreferenceProperty( grpGroup, "columns", 2 );
+
+  addPreference( tr( "PREF_GRP_NAMES" ), grpGroup, LightApp_Preferences::Color, "SMESH", "group_name_color" );
+
+  int size0d = addPreference(tr("PREF_SIZE_0D"), elemGroup,
+                             LightApp_Preferences::IntSpin, "SMESH", "elem0d_size");
+  int ballSize = addPreference(tr("PREF_BALL_SIZE"), elemGroup,
+                             LightApp_Preferences::IntSpin, "SMESH", "ball_elem_size");
+  int elemW  = addPreference(tr("PREF_WIDTH"), elemGroup,
+                             LightApp_Preferences::IntSpin, "SMESH", "element_width");
+  int shrink = addPreference(tr("PREF_SHRINK_COEFF"), elemGroup,
+                             LightApp_Preferences::IntSpin, "SMESH", "shrink_coeff");
+
+  setPreferenceProperty( size0d, "min", 1 );
+  setPreferenceProperty( size0d, "max", 10 );
+
+  setPreferenceProperty( ballSize, "min", 1 );
+  setPreferenceProperty( ballSize, "max", 10 );
 
   setPreferenceProperty( elemW, "min", 1 );
   setPreferenceProperty( elemW, "max", 5 );
@@ -3532,19 +4817,11 @@ void SMESHGUI::createPreferences()
 
   addPreference( tr( "PREF_OBJECT_COLOR" ), selGroup, LightApp_Preferences::Color, "SMESH", "selection_object_color" );
   addPreference( tr( "PREF_ELEMENT_COLOR" ), selGroup, LightApp_Preferences::Color, "SMESH", "selection_element_color" );
-  int selW = addPreference( tr( "PREF_WIDTH" ), selGroup, LightApp_Preferences::IntSpin, "SMESH", "selection_width" );
-
-  setPreferenceProperty( selW, "min", 1 );
-  setPreferenceProperty( selW, "max", 5 );
 
   int preGroup = addPreference( tr( "PREF_GROUP_PRESELECTION" ), selTab );
   setPreferenceProperty( preGroup, "columns", 2 );
 
   addPreference( tr( "PREF_HIGHLIGHT_COLOR" ), preGroup, LightApp_Preferences::Color, "SMESH", "highlight_color" );
-  int preW = addPreference( tr( "PREF_WIDTH" ), preGroup, LightApp_Preferences::IntSpin, "SMESH", "highlight_width" );
-
-  setPreferenceProperty( preW, "min", 1 );
-  setPreferenceProperty( preW, "max", 5 );
 
   int precSelGroup = addPreference( tr( "PREF_GROUP_PRECISION" ), selTab );
   setPreferenceProperty( precSelGroup, "columns", 2 );
@@ -3625,6 +4902,18 @@ void SMESHGUI::createPreferences()
   setPreferenceProperty( hh, "min", 0.0 );
   setPreferenceProperty( hh, "max", 1.0 );
   setPreferenceProperty( hh, "step", 0.1 );
+
+  int distributionGr = addPreference( tr( "SMESH_DISTRIBUTION_SCALARBAR" ), sbarTab, LightApp_Preferences::Auto, "SMESH", "distribution_visibility" );
+  int coloringType = addPreference( tr( "SMESH_DISTRIBUTION_COLORING_TYPE" ), distributionGr, LightApp_Preferences::Selector, "SMESH", "distribution_coloring_type" );
+  setPreferenceProperty( distributionGr, "columns", 3 );
+  QStringList types;
+  types.append( tr( "SMESH_MONOCOLOR" ) );
+  types.append( tr( "SMESH_MULTICOLOR" ) );
+  indices.clear(); indices.append( 0 ); indices.append( 1 );
+  setPreferenceProperty( coloringType, "strings", types );
+  setPreferenceProperty( coloringType, "indexes", indices );
+  addPreference( tr( "SMESH_DISTRIBUTION_COLOR" ), distributionGr, LightApp_Preferences::Color, "SMESH", "distribution_color" );
+
 }
 
 void SMESHGUI::preferencesChanged( const QString& sect, const QString& name )
@@ -3635,50 +4924,50 @@ void SMESHGUI::preferencesChanged( const QString& sect, const QString& name )
     std::string aWarning;
     SUIT_ResourceMgr* aResourceMgr = SMESH::GetResourceMgr(this);
     if( name=="selection_object_color" || name=="selection_element_color" ||
-        name=="selection_width" || name=="highlight_color" || name=="highlight_width" ||
+        name=="highlight_color" ||
         name=="selection_precision_node" || name=="selection_precision_element" ||
-       name=="selection_precision_object")
+        name=="selection_precision_object")
       SMESH::UpdateSelectionProp( this );
     else if (name == QString("scalar_bar_vertical_x") || name == QString("scalar_bar_vertical_width")){
       sbX1 = aResourceMgr->doubleValue("SMESH", "scalar_bar_vertical_x", sbX1);
       sbW = aResourceMgr->doubleValue("SMESH", "scalar_bar_vertical_width", sbW);
       if(sbX1+sbW > aTol){
-       aWarning = "Origin and Size Vertical: X+Width > 1\n";
-       sbX1=0.01;
-       sbW=0.08;
-       aResourceMgr->setValue("SMESH", "scalar_bar_vertical_x", sbX1);
-       aResourceMgr->setValue("SMESH", "scalar_bar_vertical_width", sbW);
+        aWarning = "Origin and Size Vertical: X+Width > 1\n";
+        sbX1=0.01;
+        sbW=0.08;
+        aResourceMgr->setValue("SMESH", "scalar_bar_vertical_x", sbX1);
+        aResourceMgr->setValue("SMESH", "scalar_bar_vertical_width", sbW);
       }
     }
     else if(name == QString("scalar_bar_vertical_y") || name == QString("scalar_bar_vertical_height")){
       sbY1 = aResourceMgr->doubleValue("SMESH", "scalar_bar_vertical_y", sbY1);
       sbH = aResourceMgr->doubleValue("SMESH", "scalar_bar_vertical_height",sbH);
       if(sbY1+sbH > aTol){
-       aWarning = "Origin and Size Vertical: Y+Height > 1\n";
-       aResourceMgr->setValue("SMESH", "scalar_bar_vertical_y", sbY1);
-       aResourceMgr->setValue("SMESH", "scalar_bar_vertical_height",sbH);
+        aWarning = "Origin and Size Vertical: Y+Height > 1\n";
+        aResourceMgr->setValue("SMESH", "scalar_bar_vertical_y", sbY1);
+        aResourceMgr->setValue("SMESH", "scalar_bar_vertical_height",sbH);
       }
     }
     else if(name ==  QString("scalar_bar_horizontal_x") || name ==  QString("scalar_bar_horizontal_width")){
       sbX1 = aResourceMgr->doubleValue("SMESH", "scalar_bar_horizontal_x", sbX1);
       sbW = aResourceMgr->doubleValue("SMESH", "scalar_bar_horizontal_width", sbW);
       if(sbX1+sbW > aTol){
-       aWarning = "Origin and Size Horizontal: X+Width > 1\n";
-       sbX1=0.1;
-       sbW=0.08;
-       aResourceMgr->setValue("SMESH", "scalar_bar_horizontal_x", sbX1);
-       aResourceMgr->setValue("SMESH", "scalar_bar_horizontal_width", sbW);
+        aWarning = "Origin and Size Horizontal: X+Width > 1\n";
+        sbX1=0.1;
+        sbW=0.08;
+        aResourceMgr->setValue("SMESH", "scalar_bar_horizontal_x", sbX1);
+        aResourceMgr->setValue("SMESH", "scalar_bar_horizontal_width", sbW);
       }
     }
     else if(name ==  QString("scalar_bar_horizontal_y") || name ==  QString("scalar_bar_horizontal_height")){
       sbY1 = aResourceMgr->doubleValue("SMESH", "scalar_bar_horizontal_y", sbY1);
       sbH = aResourceMgr->doubleValue("SMESH", "scalar_bar_horizontal_height",sbH);
       if(sbY1+sbH > aTol){
-       aWarning = "Origin and Size Horizontal: Y+Height > 1\n";
-       sbY1=0.01;
-       sbH=0.08;
-       aResourceMgr->setValue("SMESH", "scalar_bar_horizontal_y", sbY1);
-       aResourceMgr->setValue("SMESH", "scalar_bar_horizontal_height",sbH);
+        aWarning = "Origin and Size Horizontal: Y+Height > 1\n";
+        sbY1=0.01;
+        sbH=0.08;
+        aResourceMgr->setValue("SMESH", "scalar_bar_horizontal_y", sbY1);
+        aResourceMgr->setValue("SMESH", "scalar_bar_horizontal_height",sbH);
       }
     }
     else if ( name == "segmentation" ) {
@@ -3689,12 +4978,17 @@ void SMESHGUI::preferencesChanged( const QString& sect, const QString& name )
       int nbSeg = aResourceMgr->integerValue( "SMESH", "nb_segments_per_edge", 15 );
       myComponentSMESH->SetDefaultNbSegments( nbSeg );
     }
+    else if ( name == "historical_python_dump" ||
+              name == "forget_mesh_on_hyp_modif") {
+      QString val = aResourceMgr->stringValue( "SMESH", name );
+      myComponentSMESH->SetOption( name.toLatin1().constData(), val.toLatin1().constData() );
+    }
 
     if(aWarning.size() != 0){
       aWarning += "The default values are applied instead.";
       SUIT_MessageBox::warning(SMESHGUI::desktop(),
-                              QObject::tr("SMESH_ERR_SCALARBAR_PARAMS"),
-                              QObject::tr(aWarning.c_str()));
+                               QObject::tr("SMESH_ERR_SCALARBAR_PARAMS"),
+                               QObject::tr(aWarning.c_str()));
     }
   }
 }
@@ -3710,7 +5004,7 @@ void SMESHGUI::preferencesChanged( const QString& sect, const QString& name )
 //================================================================================
 void SMESHGUI::update( const int flags )
 {
-  if ( flags & UF_Viewer | flags & UF_Forced )
+  if ( (flags & UF_Viewer) | (flags & UF_Forced) )
     SMESH::UpdateView();
   else
     SalomeApp_Module::update( flags );
@@ -3762,6 +5056,15 @@ LightApp_Operation* SMESHGUI::createOperation( const int id ) const
   // to do : create operation here
   switch( id )
   {
+    case 417: //convert to quadratic
+      op = new SMESHGUI_ConvToQuadOp();
+    break;
+    case 418: // create 2D mesh as boundary on 3D
+      op = new SMESHGUI_Make2DFrom3DOp();
+    break;
+    case 420: // Reorient faces
+      op = new SMESHGUI_ReorientFacesOp();
+      break;
     case 701: // Compute mesh
       op = new SMESHGUI_ComputeOp();
     break;
@@ -3777,12 +5080,18 @@ LightApp_Operation* SMESHGUI::createOperation( const int id ) const
     case 711: // Precompute mesh
       op = new SMESHGUI_PrecomputeOp();
     break;
+    case 712: // Evaluate mesh
+      op = new SMESHGUI_EvaluateOp();
+    break;
+    case 713: // Evaluate mesh
+      op = new SMESHGUI_MeshOrderOp();
+    break;
     case 806: // Create group on geom
       op = new SMESHGUI_GroupOnShapeOp();
       break;
-    case 417: //convert to quadratic
-      op = new SMESHGUI_ConvToQuadOp();
-    break;
+    case 904: // Find element
+      op = new SMESHGUI_FindElemByPointOp();
+      break;
     case 4067: // make mesh pass through point
       op = new SMESHGUI_MakeNodeAtPointOp();
       break;
@@ -3830,14 +5139,11 @@ SALOMEDS::Color SMESHGUI::getUniqueColor( const QList<SALOMEDS::Color>& theReser
     {
       aTolerance /= 2;
       if( aTolerance < 1 )
-       break;
+        break;
     }
-    //cout << "Iteration N" << anIterations << " (tolerance=" << aTolerance << ")"<< endl;
 
     aHue = (int)( 360.0 * rand() / RAND_MAX );
-    //cout << "Hue = " << aHue << endl;
 
-    //cout << "Auto colors : ";
     bool ok = true;
     QList<SALOMEDS::Color>::const_iterator it = theReservedColors.constBegin();
     QList<SALOMEDS::Color>::const_iterator itEnd = theReservedColors.constEnd();
@@ -3848,21 +5154,17 @@ SALOMEDS::Color SMESHGUI::getUniqueColor( const QList<SALOMEDS::Color>& theReser
 
       int h, s, v;
       aQColor.getHsv( &h, &s, &v );
-      //cout << h << " ";
       if( abs( h - aHue ) < aTolerance )
       {
-       ok = false;
-       //cout << "break (diff = " << abs( h - aHue ) << ")";
-       break;
+        ok = false;
+        break;
       }
     }
-    //cout << endl;
 
     if( ok )
       break;
   }
 
-  //cout << "Hue of the returned color = " << aHue << endl;
   QColor aColor;
   aColor.setHsv( aHue, 255, 255 );
 
@@ -3876,6 +5178,7 @@ SALOMEDS::Color SMESHGUI::getUniqueColor( const QList<SALOMEDS::Color>& theReser
 
 const char gSeparator = '_'; // character used to separate parameter names
 const char gDigitsSep = ':'; // character used to separate numeric parameter values (color = r:g:b)
+const char gPathSep   = '|'; // character used to separate paths
 
 /*!
  * \brief Store visual parameters
@@ -3901,6 +5204,39 @@ void SMESHGUI::storeVisualParameters (int savePoint)
                                                              savePoint);
   _PTR(IParameters) ip = ClientFactory::getIParameters(ap);
 
+  // store map of custom markers
+  const VTK::MarkerMap& aMarkerMap = myMarkerMap[ studyDS->StudyId() ];
+  if( !aMarkerMap.empty() )
+  {
+    VTK::MarkerMap::const_iterator anIter = aMarkerMap.begin();
+    for( ; anIter != aMarkerMap.end(); anIter++ )
+    {
+      int anId = anIter->first;
+      VTK::MarkerData aMarkerData = anIter->second;
+      std::string aMarkerFileName = aMarkerData.first;
+      VTK::MarkerTexture aMarkerTexture = aMarkerData.second;
+      if( aMarkerTexture.size() < 3 )
+        continue; // should contain at least width, height and the first value
+
+      QString aPropertyName( "texture" );
+      aPropertyName += gSeparator;
+      aPropertyName += QString::number( anId );
+
+      QString aPropertyValue = aMarkerFileName.c_str();
+      aPropertyValue += gPathSep;
+
+      VTK::MarkerTexture::const_iterator aTextureIter = aMarkerTexture.begin();
+      ushort aWidth = *aTextureIter++;
+      ushort aHeight = *aTextureIter++;
+      aPropertyValue += QString::number( aWidth ); aPropertyValue += gDigitsSep;
+      aPropertyValue += QString::number( aHeight ); aPropertyValue += gDigitsSep;
+      for( ; aTextureIter != aMarkerTexture.end(); aTextureIter++ )
+        aPropertyValue += QString::number( *aTextureIter );
+
+      ip->setProperty( aPropertyName.toStdString(), aPropertyValue.toStdString() );
+    }
+  }
+
   // viewers counters are used for storing view_numbers in IParameters
   int vtkViewers = 0;
 
@@ -3916,21 +5252,53 @@ void SMESHGUI::storeVisualParameters (int savePoint)
     // saving VTK actors properties
     if (vType == SVTK_Viewer::Type())
     {
+      // store the clipping planes attached to the view manager
+      SMESHGUI_ClippingPlaneInfoList aClippingPlaneInfoList;
+      SMESHGUI_ClippingPlaneInfoMap::const_iterator anIter = myClippingPlaneInfoMap.find( vman );
+      if( anIter != myClippingPlaneInfoMap.end() )
+        aClippingPlaneInfoList = anIter->second;
+
+      if( !aClippingPlaneInfoList.empty() ) {
+        SMESHGUI_ClippingPlaneInfoList::const_iterator anIter = aClippingPlaneInfoList.begin();
+        for( int anId = 0; anIter != aClippingPlaneInfoList.end(); anIter++, anId++ )
+        {
+          const SMESH::ClippingPlaneInfo& aClippingPlaneInfo = *anIter;
+          SMESH::OrientedPlane* aPlane = aClippingPlaneInfo.Plane;
+
+          QString aPropertyName( "ClippingPlane" );
+          aPropertyName += gSeparator;
+          aPropertyName += QString::number( vtkViewers );
+          aPropertyName += gSeparator;
+          aPropertyName += QString::number( anId );
+
+          QString aPropertyValue = QString::number( (int)aPlane->GetOrientation() ).toLatin1().constData();
+          aPropertyValue += gDigitsSep;
+          aPropertyValue += QString::number( aPlane->GetDistance() ).toLatin1().constData();
+          aPropertyValue += gDigitsSep;
+          aPropertyValue += QString::number( aPlane->myAngle[0] ).toLatin1().constData();
+          aPropertyValue += gDigitsSep;
+          aPropertyValue += QString::number( aPlane->myAngle[1] ).toLatin1().constData();
+
+          ip->setProperty( aPropertyName.toStdString(), aPropertyValue.toStdString() );
+        }
+      }
+
       QVector<SUIT_ViewWindow*> views = vman->getViews();
       for (int i = 0, iEnd = vman->getViewsCount(); i < iEnd; i++)
       {
-       if (SVTK_ViewWindow* vtkView = dynamic_cast<SVTK_ViewWindow*>(views[i]))
+        if (SVTK_ViewWindow* vtkView = dynamic_cast<SVTK_ViewWindow*>(views[i]))
         {
-         vtkActorCollection* allActors = vtkView->getRenderer()->GetActors();
-         allActors->InitTraversal();
-         while (vtkActor* actor = allActors->GetNextActor())
+          VTK::ActorCollectionCopy aCopy(vtkView->getRenderer()->GetActors());
+          vtkActorCollection* allActors = aCopy.GetActors();
+          allActors->InitTraversal();
+          while (vtkActor* actor = allActors->GetNextActor())
           {
-           if (actor->GetVisibility()) // store only visible actors
+            if (actor->GetVisibility()) // store only visible actors
             {
               SMESH_Actor* aSmeshActor = 0;
               if (actor->IsA("SMESH_Actor"))
                 aSmeshActor = SMESH_Actor::SafeDownCast(actor);
-             if (aSmeshActor && aSmeshActor->hasIO())
+              if (aSmeshActor && aSmeshActor->hasIO())
               {
                 Handle(SALOME_InteractiveObject) io = aSmeshActor->getIO();
                 if (io->hasEntry())
@@ -3976,18 +5344,17 @@ void SMESHGUI::storeVisualParameters (int savePoint)
 
                   // Colors (surface:edge:)
                   vtkFloatingPointType r, g, b;
+                  int delta;
 
-                  aSmeshActor->GetSufaceColor(r, g, b);
+                  aSmeshActor->GetSufaceColor(r, g, b, delta);
                   QString colorStr ("surface");
                   colorStr += gDigitsSep; colorStr += QString::number(r);
                   colorStr += gDigitsSep; colorStr += QString::number(g);
                   colorStr += gDigitsSep; colorStr += QString::number(b);
 
-                  aSmeshActor->GetBackSufaceColor(r, g, b);
                   colorStr += gDigitsSep; colorStr += "backsurface";
-                  colorStr += gDigitsSep; colorStr += QString::number(r);
-                  colorStr += gDigitsSep; colorStr += QString::number(g);
-                  colorStr += gDigitsSep; colorStr += QString::number(b);
+                  colorStr += gDigitsSep; colorStr += QString::number(delta);
+
 
                   aSmeshActor->GetEdgeColor(r, g, b);
                   colorStr += gDigitsSep; colorStr += "edge";
@@ -4001,20 +5368,44 @@ void SMESHGUI::storeVisualParameters (int savePoint)
                   colorStr += gDigitsSep; colorStr += QString::number(g);
                   colorStr += gDigitsSep; colorStr += QString::number(b);
 
+                  aSmeshActor->GetOutlineColor(r, g, b);
+                  colorStr += gDigitsSep; colorStr += "outline";
+                  colorStr += gDigitsSep; colorStr += QString::number(r);
+                  colorStr += gDigitsSep; colorStr += QString::number(g);
+                  colorStr += gDigitsSep; colorStr += QString::number(b);
+
                   param = vtkParam + "Colors";
                   ip->setParameter(entry, param, colorStr.toLatin1().data());
 
                   // Sizes of lines and points
                   QString sizeStr ("line");
                   sizeStr += gDigitsSep; sizeStr += QString::number((int)aSmeshActor->GetLineWidth());
-                  sizeStr += gDigitsSep; sizeStr += "node";
-                  sizeStr += gDigitsSep; sizeStr += QString::number((int)aSmeshActor->GetNodeSize());
                   sizeStr += gDigitsSep; sizeStr += "shrink";
                   sizeStr += gDigitsSep; sizeStr += QString::number(aSmeshActor->GetShrinkFactor());
 
                   param = vtkParam + "Sizes";
                   ip->setParameter(entry, param, sizeStr.toLatin1().data());
 
+                  // Point marker
+                  QString markerStr;
+
+                  VTK::MarkerType aMarkerType = aSmeshActor->GetMarkerType();
+                  if( aMarkerType == VTK::MT_USER ) {
+                    markerStr += "custom";
+                    markerStr += gDigitsSep;
+                    markerStr += QString::number( aSmeshActor->GetMarkerTexture() );
+                  }
+                  else {
+                    markerStr += "std";
+                    markerStr += gDigitsSep;
+                    markerStr += QString::number( (int)aMarkerType );
+                    markerStr += gDigitsSep;
+                    markerStr += QString::number( (int)aSmeshActor->GetMarkerScale() );
+                  }
+
+                  param = vtkParam + "PointMarker";
+                  ip->setParameter(entry, param, markerStr.toLatin1().data());
+
                   // Opacity
                   param = vtkParam + "Opacity";
                   ip->setParameter(entry, param,
@@ -4022,33 +5413,55 @@ void SMESHGUI::storeVisualParameters (int savePoint)
 
                   // Clipping
                   param = vtkParam + "ClippingPlane";
-                  int nPlanes = aSmeshActor->GetNumberOfClippingPlanes();
-                  if (!nPlanes)
-                    ip->setParameter(entry, param, "Off");
-                  for (int ipl = 0; ipl < nPlanes; ipl++) {
-                    //vtkPlane* plane = aSmeshActor->GetClippingPlane(ipl);
-                    SMESH::Orientation anOrientation;
-                    double aDistance;
-                    vtkFloatingPointType anAngle[2];
-                    SMESHGUI_ClippingDlg::GetPlaneParam(aSmeshActor, ipl, anOrientation, aDistance, anAngle);
-                    std::string planeValue = QString::number((int)anOrientation).toLatin1().data();
-                    planeValue += gDigitsSep; planeValue += QString::number(aDistance).toLatin1().data();
-                    planeValue += gDigitsSep; planeValue += QString::number(anAngle[0]).toLatin1().data();
-                    planeValue += gDigitsSep; planeValue += QString::number(anAngle[1]).toLatin1().data();
-
-                    ip->setParameter(entry, param + QString::number(ipl+1).toLatin1().data(), planeValue);
+                  int aPlaneId = 0;
+                  if( !aClippingPlaneInfoList.empty() ) {
+                    SMESHGUI_ClippingPlaneInfoList::const_iterator anIter1 = aClippingPlaneInfoList.begin();
+                    for( int anId = 0; anIter1 != aClippingPlaneInfoList.end(); anIter1++, anId++ )
+                    {
+                      const SMESH::ClippingPlaneInfo& aClippingPlaneInfo = *anIter1;
+                      std::list<vtkActor*> anActorList = aClippingPlaneInfo.ActorList;
+                      SMESH::TActorList::iterator anIter2 = anActorList.begin();
+                      for ( ; anIter2 != anActorList.end(); anIter2++ ) {
+                        if( aSmeshActor == *anIter2 ) {
+                          ip->setParameter( entry, param + QString::number( ++aPlaneId ).toLatin1().constData(),
+                                            QString::number( anId ).toLatin1().constData() );
+                          break;
+                        }
+                      }
+                    }
                   }
+                  if( aPlaneId == 0 )
+                    ip->setParameter( entry, param, "Off" );
                 } // if (io->hasEntry())
-             } // SMESH_Actor && hasIO
-           } // isVisible
-         } // while.. actors traversal
-       } // if (vtkView)
+              } // SMESH_Actor && hasIO
+            } // isVisible
+          } // while.. actors traversal
+        } // if (vtkView)
       } // for (views)
       vtkViewers++;
     } // if (SVTK view model)
   } // for (viewManagers)
 }
 
+// data structures for clipping planes processing
+typedef struct {
+  int Id;
+  vtkIdType Orientation;
+  vtkFloatingPointType Distance;
+  vtkFloatingPointType Angle[2];
+} TPlaneData;
+typedef std::list<TPlaneData>         TPlaneDataList;
+typedef std::map<int, TPlaneDataList> TPlaneDataMap;
+
+typedef std::list<vtkActor*>          TActorList;
+typedef struct {
+  int PlaneId;
+  TActorList ActorList;
+  SUIT_ViewManager* ViewManager;
+} TPlaneInfo;
+typedef std::list<TPlaneInfo>         TPlaneInfoList;
+typedef std::map<int, TPlaneInfoList> TPlaneInfoMap;
+
 /*!
  * \brief Restore visual parameters
  *
@@ -4073,6 +5486,115 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
                                                              savePoint);
   _PTR(IParameters) ip = ClientFactory::getIParameters(ap);
 
+  // restore map of custom markers and map of clipping planes
+  VTK::MarkerMap& aMarkerMap = myMarkerMap[ studyDS->StudyId() ];
+  TPlaneDataMap aPlaneDataMap;
+
+  std::vector<std::string> properties = ip->getProperties();
+  for (std::vector<std::string>::iterator propIt = properties.begin(); propIt != properties.end(); ++propIt)
+  {
+    std::string property = *propIt;
+    QString aPropertyName( property.c_str() );
+    QString aPropertyValue( ip->getProperty( property ).c_str() );
+
+    QStringList aPropertyNameList = aPropertyName.split( gSeparator, QString::SkipEmptyParts );
+    if( aPropertyNameList.isEmpty() )
+      continue;
+
+    QString aPropertyType = aPropertyNameList[0];
+    if( aPropertyType == "texture" )
+    {
+      if( aPropertyNameList.size() != 2 )
+        continue;
+
+      bool ok = false;
+      int anId = aPropertyNameList[1].toInt( &ok );
+      if( !ok || anId < 1 )
+        continue;
+
+      QStringList aPropertyValueList = aPropertyValue.split( gPathSep, QString::SkipEmptyParts );
+      if( aPropertyValueList.size() != 2 )
+        continue;
+
+      std::string aMarkerFileName = aPropertyValueList[0].toStdString();
+      QString aMarkerTextureString = aPropertyValueList[1];
+      QStringList aMarkerTextureStringList = aMarkerTextureString.split( gDigitsSep, QString::SkipEmptyParts );
+      if( aMarkerTextureStringList.size() != 3 )
+        continue;
+
+      ok = false;
+      ushort aWidth = aMarkerTextureStringList[0].toUShort( &ok );
+      if( !ok )
+        continue;
+
+      ok = false;
+      ushort aHeight = aMarkerTextureStringList[1].toUShort( &ok );
+      if( !ok )
+        continue;
+
+      VTK::MarkerTexture aMarkerTexture;
+      aMarkerTexture.push_back( aWidth );
+      aMarkerTexture.push_back( aHeight );
+
+      QString aMarkerTextureData = aMarkerTextureStringList[2];
+      for( int i = 0, n = aMarkerTextureData.length(); i < n; i++ )
+      {
+        QChar aChar = aMarkerTextureData.at( i );
+        if( aChar.isDigit() )
+          aMarkerTexture.push_back( aChar.digitValue() );
+      }
+
+      aMarkerMap[ anId ] = VTK::MarkerData( aMarkerFileName, aMarkerTexture );
+    }
+    else if( aPropertyType == "ClippingPlane" )
+    {
+      if( aPropertyNameList.size() != 3 )
+        continue;
+
+      bool ok = false;
+      int aViewId = aPropertyNameList[1].toInt( &ok );
+      if( !ok || aViewId < 0 )
+        continue;
+
+      ok = false;
+      int aClippingPlaneId = aPropertyNameList[2].toInt( &ok );
+      if( !ok || aClippingPlaneId < 0 )
+        continue;
+
+      QStringList aPropertyValueList = aPropertyValue.split( gDigitsSep, QString::SkipEmptyParts );
+      if( aPropertyValueList.size() != 4 )
+        continue;
+
+      TPlaneData aPlaneData;
+      aPlaneData.Id = aClippingPlaneId;
+
+      ok = false;
+      aPlaneData.Orientation = aPropertyValueList[0].toInt( &ok );
+      if( !ok )
+        continue;
+
+      ok = false;
+      aPlaneData.Distance = aPropertyValueList[1].toDouble( &ok );
+      if( !ok )
+        continue;
+
+      ok = false;
+      aPlaneData.Angle[0] = aPropertyValueList[2].toDouble( &ok );
+      if( !ok )
+        continue;
+
+      ok = false;
+      aPlaneData.Angle[1] = aPropertyValueList[3].toDouble( &ok );
+      if( !ok )
+        continue;
+
+      TPlaneDataList& aPlaneDataList = aPlaneDataMap[ aViewId ];
+      aPlaneDataList.push_back( aPlaneData );
+    }
+  }
+
+  TPlaneInfoMap aPlaneInfoMap;
+
   std::vector<std::string> entries = ip->getEntries();
 
   for (std::vector<std::string>::iterator entIt = entries.begin(); entIt != entries.end(); ++entIt)
@@ -4110,7 +5632,7 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
       bool ok;
       int viewIndex = viewIndexStr.toUInt(&ok);
       if (!ok) // bad conversion of view index to integer
-       continue;
+        continue;
 
       // viewers
       if (viewerTypStr == SVTK_Viewer::Type())
@@ -4119,48 +5641,50 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
         if (vtkActors.IsBound(viewIndex))
           aSmeshActor = vtkActors.Find(viewIndex);
 
+        QList<SUIT_ViewManager*> lst;
+        getApp()->viewManagers(viewerTypStr, lst);
+
+        // SVTK ViewManager always has 1 ViewWindow, so view index is index of view manager
+        SUIT_ViewManager* vman = NULL;
+        if (viewIndex >= 0 && viewIndex < lst.count())
+          vman = lst.at(viewIndex);
+
         if (paramNameStr == "Visibility")
         {
-          if (!aSmeshActor && displayer())
+          if (!aSmeshActor && displayer() && vman)
           {
-            QList<SUIT_ViewManager*> lst;
-            getApp()->viewManagers(viewerTypStr, lst);
-
-            // SVTK ViewManager always has 1 ViewWindow, so view index is index of view manager
-            if (viewIndex >= 0 && viewIndex < lst.count()) {
-              SUIT_ViewManager* vman = lst.at(viewIndex);
-              SUIT_ViewModel* vmodel = vman->getViewModel();
-              // SVTK view model can be casted to SALOME_View
-              displayer()->Display(entry, true, dynamic_cast<SALOME_View*>(vmodel));
-
-              // store displayed actor in a temporary map for quicker
-              // access later when restoring other parameters
-              SVTK_ViewWindow* vtkView = (SVTK_ViewWindow*) vman->getActiveView();
-              vtkRenderer* Renderer = vtkView->getRenderer();
-              vtkActorCollection* theActors = Renderer->GetActors();
-              theActors->InitTraversal();
-              bool isFound = false;
-              vtkActor *ac = theActors->GetNextActor();
-              for (; ac != NULL && !isFound; ac = theActors->GetNextActor()) {
-                if (ac->IsA("SMESH_Actor")) {
-                  SMESH_Actor* aGeomAc = SMESH_Actor::SafeDownCast(ac);
-                  if (aGeomAc->hasIO()) {
-                    Handle(SALOME_InteractiveObject) io =
-                      Handle(SALOME_InteractiveObject)::DownCast(aGeomAc->getIO());
-                    if (io->hasEntry() && strcmp(io->getEntry(), entry.toLatin1().data()) == 0) {
-                      isFound = true;
-                      vtkActors.Bind(viewIndex, aGeomAc);
-                    }
+            SUIT_ViewModel* vmodel = vman->getViewModel();
+            // SVTK view model can be casted to SALOME_View
+            displayer()->Display(entry, true, dynamic_cast<SALOME_View*>(vmodel));
+
+            // store displayed actor in a temporary map for quicker
+            // access later when restoring other parameters
+            SVTK_ViewWindow* vtkView = (SVTK_ViewWindow*) vman->getActiveView();
+            vtkRenderer* Renderer = vtkView->getRenderer();
+            VTK::ActorCollectionCopy aCopy(Renderer->GetActors());
+            vtkActorCollection* theActors = aCopy.GetActors();
+            theActors->InitTraversal();
+            bool isFound = false;
+            vtkActor *ac = theActors->GetNextActor();
+            for (; ac != NULL && !isFound; ac = theActors->GetNextActor()) {
+              if (ac->IsA("SMESH_Actor")) {
+                SMESH_Actor* aGeomAc = SMESH_Actor::SafeDownCast(ac);
+                if (aGeomAc->hasIO()) {
+                  Handle(SALOME_InteractiveObject) io =
+                    Handle(SALOME_InteractiveObject)::DownCast(aGeomAc->getIO());
+                  if (io->hasEntry() && strcmp(io->getEntry(), entry.toLatin1().data()) == 0) {
+                    isFound = true;
+                    vtkActors.Bind(viewIndex, aGeomAc);
                   }
                 }
               }
             }
           }
         } // if (paramNameStr == "Visibility")
-       else
+        else
         {
           // the rest properties "work" with SMESH_Actor
-         if (aSmeshActor)
+          if (aSmeshActor)
           {
             QString val ((*valuesIt).c_str());
 
@@ -4201,49 +5725,115 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
             // Colors
             else if (paramNameStr == "Colors") {
               QStringList colors = val.split(gDigitsSep, QString::SkipEmptyParts);
-              if (colors.count() == 16) {
+              if (colors.count() == 16 || colors.count() == 18 ) {
                 if (colors[0] != "surface" || colors[4]  != "backsurface" ||
-                    colors[8] != "edge"    || colors[12] != "node") {
+                    (colors[8] != "edge" && colors[6] != "edge" ) || (colors[12] != "node" && colors[10] != "node") ||
+                    (colors.count() == 18 && colors[14] != "outline")) {
                   MESSAGE("Invalid order of data in Colors, must be: "
-                          "surface:r:g:b:backsurface:r:g:b:edge:r:g:b:node:r:g:b");
+                          "surface:r:g:b:backsurface:r:g:b:edge:r:g:b:node:r:g:b or surface:r:g:b:backsurface:delta:edge:r:g:b:node:r:g:b:outline:r:g:b");
                 }
                 else {
-                  aSmeshActor->SetSufaceColor(colors[1].toFloat(), colors[2].toFloat(), colors[3].toFloat());
-                  aSmeshActor->SetBackSufaceColor(colors[5].toFloat(), colors[6].toFloat(), colors[7].toFloat());
-                  aSmeshActor->SetEdgeColor(colors[9].toFloat(), colors[10].toFloat(), colors[11].toFloat());
-                  aSmeshActor->SetNodeColor(colors[13].toFloat(), colors[14].toFloat(), colors[15].toFloat());
+                  int delta = 0;
+                  float er,eg,eb;
+                  float nr,ng,nb;
+                  vtkFloatingPointType otr,otg,otb;
+                  //Old case backsurface color is independent
+                  if( colors.count() == 16 ) {
+                    QColor ffc;
+                    SMESH::GetColor( "SMESH", "fill_color", ffc, delta, "0,170,255|-100" ) ;
+                    er = colors[9].toFloat();
+                    eg = colors[10].toFloat();
+                    eb = colors[11].toFloat();
+
+                    nr = colors[13].toFloat();
+                    ng = colors[14].toFloat();
+                    nb = colors[15].toFloat();
+                    SMESH::GetColor("SMESH", "outline_color", otr, otg, otb, QColor( 0, 70, 0 ) );
+                  } else {
+                    //New case backsurface color depends on surface color
+                    delta = colors[5].toInt();
+
+                    er = colors[7].toFloat();
+                    eg = colors[8].toFloat();
+                    eb = colors[9].toFloat();
+
+                    nr = colors[11].toFloat();
+                    ng = colors[12].toFloat();
+                    nb = colors[13].toFloat();
+
+                    otr = colors[15].toFloat();
+                    otg = colors[16].toFloat();
+                    otb = colors[17].toFloat();
+                  }
+                  aSmeshActor->SetSufaceColor(colors[1].toFloat(), colors[2].toFloat(), colors[3].toFloat(), delta);
+                  aSmeshActor->SetEdgeColor(er,eg,eb);
+                  aSmeshActor->SetNodeColor(nr,ng,nb);
+                  aSmeshActor->SetOutlineColor(otr,otg,otb);
                 }
               }
             }
             // Sizes of lines and points
             else if (paramNameStr == "Sizes") {
               QStringList sizes = val.split(gDigitsSep, QString::SkipEmptyParts);
-              if (sizes.count() == 6) {
+              if (sizes.count() == 4) {
+                if (sizes[0] != "line" || sizes[2] != "shrink") {
+                  MESSAGE("Invalid order of data in Sizes, must be: "
+                          "line:int:shrink:float");
+                }
+                else {
+                  aSmeshActor->SetLineWidth(sizes[1].toInt());
+                  aSmeshActor->SetShrinkFactor(sizes[3].toFloat());
+                }
+              }
+              else if (sizes.count() == 6) { // just to support old format
                 if (sizes[0] != "line" || sizes[2]  != "node" || sizes[4] != "shrink") {
                   MESSAGE("Invalid order of data in Sizes, must be: "
                           "line:int:node:int:shrink:float");
                 }
                 else {
                   aSmeshActor->SetLineWidth(sizes[1].toInt());
-                  aSmeshActor->SetNodeSize(sizes[3].toInt());
+                  //aSmeshActor->SetNodeSize(sizes[3].toInt()); // made obsolete
                   aSmeshActor->SetShrinkFactor(sizes[5].toFloat());
                 }
               }
             }
+            // Point marker
+            else if (paramNameStr == "PointMarker") {
+              QStringList data = val.split(gDigitsSep, QString::SkipEmptyParts);
+              if( data.count() >= 2 ) {
+                bool ok = false;
+                int aParam1 = data[1].toInt( &ok );
+                if( ok ) {
+                  if( data[0] == "std" && data.count() == 3 ) {
+                    int aParam2 = data[2].toInt( &ok );
+                    aSmeshActor->SetMarkerStd( (VTK::MarkerType)aParam1, (VTK::MarkerScale)aParam2 );
+                  }
+                  else if( data[0] == "custom" ) {
+                    VTK::MarkerMap::const_iterator markerIt = aMarkerMap.find( aParam1 );
+                    if( markerIt != aMarkerMap.end() ) {
+                      VTK::MarkerData aMarkerData = markerIt->second;
+                      aSmeshActor->SetMarkerTexture( aParam1, aMarkerData.second );
+                    }
+                  }
+                }
+              }
+            }
             // Opacity
             else if (paramNameStr == "Opacity") {
               aSmeshActor->SetOpacity(val.toFloat());
             }
             // Clipping
             else if (paramNameStr.startsWith("ClippingPlane")) {
-              cout << "$$$ ClippingPlane 1" << endl;
-              if (paramNameStr == "ClippingPlane1" || val == "Off")
-                aSmeshActor->RemoveAllClippingPlanes();
-              if (val != "Off") {
-                cout << "$$$ ClippingPlane 2" << endl;
-                QStringList vals = val.split(gDigitsSep, QString::SkipEmptyParts);
-                if (vals.count() == 4) { // format check: 4 values
-                  cout << "$$$ ClippingPlane 3" << endl;
+              QStringList vals = val.split(gDigitsSep, QString::SkipEmptyParts);
+              // old format - val looks like "Off" or "0:0.5:0:0" (orientation, distance, two angles)
+              // new format - val looks like "Off" or "0" (plane id)
+              // (note: in new format "Off" value is used only for consistency,
+              //  so it is processed together with values in old format)
+              bool anIsOldFormat = ( vals.count() == 4 || val == "Off" );
+              if( anIsOldFormat ) {
+                if (paramNameStr == "ClippingPlane1" || val == "Off")
+                  aSmeshActor->RemoveAllClippingPlanes();
+                if (val != "Off") {
                   SMESH::Orientation anOrientation = (SMESH::Orientation)vals[0].toInt();
                   double aDistance = vals[1].toFloat();
                   vtkFloatingPointType anAngle[2];
@@ -4256,18 +5846,156 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
                   if (viewIndex >= 0 && viewIndex < lst.count()) {
                     SUIT_ViewManager* vman = lst.at(viewIndex);
                     SVTK_ViewWindow* vtkView = (SVTK_ViewWindow*) vman->getActiveView();
-                    SMESHGUI_ClippingDlg::AddPlane(aSmeshActor, vtkView,
-                                                   anOrientation, aDistance, anAngle);
+
+                    SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = myClippingPlaneInfoMap[ vman ];
+
+                    SMESH::TActorList anActorList;
+                    anActorList.push_back( aSmeshActor );
+                    SMESH::OrientedPlane* aPlane =
+                      SMESHGUI_ClippingDlg::AddPlane(anActorList, vtkView, anOrientation, aDistance, anAngle);
+                    if( aPlane ) {
+                      SMESH::ClippingPlaneInfo aClippingPlaneInfo;
+                      aClippingPlaneInfo.Plane = aPlane;
+                      aClippingPlaneInfo.ActorList = anActorList;
+                      aClippingPlaneInfoList.push_back( aClippingPlaneInfo );
+                    }
+                  }
+                }
+              }
+              else {
+                bool ok = false;
+                int aPlaneId = val.toInt( &ok );
+                if( ok && aPlaneId >= 0 ) {
+                  bool anIsDefinedPlane = false;
+                  TPlaneInfoList& aPlaneInfoList = aPlaneInfoMap[ viewIndex ];
+                  TPlaneInfoList::iterator anIter = aPlaneInfoList.begin();
+                  for( ; anIter != aPlaneInfoList.end(); anIter++ ) {
+                    TPlaneInfo& aPlaneInfo = *anIter;
+                    if( aPlaneInfo.PlaneId == aPlaneId ) {
+                      aPlaneInfo.ActorList.push_back( aSmeshActor );
+                      anIsDefinedPlane = true;
+                      break;
+                    }
+                  }
+                  if( !anIsDefinedPlane ) {
+                    TPlaneInfo aPlaneInfo;
+                    aPlaneInfo.PlaneId = aPlaneId;
+                    aPlaneInfo.ActorList.push_back( aSmeshActor );
+                    aPlaneInfo.ViewManager = vman;
+
+                    // to make the list sorted by plane id
+                    anIter = aPlaneInfoList.begin();
+                    for( ; anIter != aPlaneInfoList.end(); anIter++ ) {
+                      const TPlaneInfo& aPlaneInfoRef = *anIter;
+                      if( aPlaneInfoRef.PlaneId > aPlaneId )
+                        break;
+                    }
+                    aPlaneInfoList.insert( anIter, aPlaneInfo );
                   }
                 }
               }
             }
           } // if (aSmeshActor)
-       } // other parameters than Visibility
+        } // other parameters than Visibility
       }
     } // for names/parameters iterator
   } // for entries iterator
 
+  // take into account planes with empty list of actors referred to them
+  QList<SUIT_ViewManager*> aVMList;
+  getApp()->viewManagers(SVTK_Viewer::Type(), aVMList);
+
+  TPlaneDataMap::const_iterator aPlaneDataIter = aPlaneDataMap.begin();
+  for( ; aPlaneDataIter != aPlaneDataMap.end(); aPlaneDataIter++ ) {
+    int aViewId = aPlaneDataIter->first;
+    if( aViewId >= 0 && aViewId < aVMList.count() ) {
+      SUIT_ViewManager* aViewManager = aVMList.at( aViewId );
+
+      const TPlaneDataList& aPlaneDataList = aPlaneDataIter->second;
+
+      TPlaneInfoList& aPlaneInfoList = aPlaneInfoMap[ aViewId ];
+      TPlaneDataList::const_iterator anIter2 = aPlaneDataList.begin();
+      for( ; anIter2 != aPlaneDataList.end(); anIter2++ ) {
+        const TPlaneData& aPlaneData = *anIter2;
+        int aPlaneId = aPlaneData.Id;
+
+        bool anIsFound = false;
+        TPlaneInfoList::const_iterator anIter3 = aPlaneInfoList.begin();
+        for( ; anIter3 != aPlaneInfoList.end(); anIter3++ ) {
+          const TPlaneInfo& aPlaneInfo = *anIter3;
+          if( aPlaneInfo.PlaneId == aPlaneId ) {
+            anIsFound = true;
+            break;
+          }
+        }
+
+        if( !anIsFound ) {
+          TPlaneInfo aPlaneInfo; // ActorList field is empty
+          aPlaneInfo.PlaneId = aPlaneId;
+          aPlaneInfo.ViewManager = aViewManager;
+
+          // to make the list sorted by plane id
+          TPlaneInfoList::iterator anIter4 = aPlaneInfoList.begin();
+          for( ; anIter4 != aPlaneInfoList.end(); anIter4++ ) {
+            const TPlaneInfo& aPlaneInfoRef = *anIter4;
+            if( aPlaneInfoRef.PlaneId > aPlaneId )
+              break;
+          }
+          aPlaneInfoList.insert( anIter4, aPlaneInfo );
+        }
+      }
+    }
+  }
+
+  // add clipping planes to actors according to the restored parameters
+  // and update the clipping plane map
+  TPlaneInfoMap::const_iterator anIter1 = aPlaneInfoMap.begin();
+  for( ; anIter1 != aPlaneInfoMap.end(); anIter1++ ) {
+    int aViewId = anIter1->first;
+    const TPlaneInfoList& aPlaneInfoList = anIter1->second;
+
+    TPlaneDataMap::const_iterator anIter2 = aPlaneDataMap.find( aViewId );
+    if( anIter2 == aPlaneDataMap.end() )
+      continue;
+    const TPlaneDataList& aPlaneDataList = anIter2->second;
+
+    TPlaneInfoList::const_iterator anIter3 = aPlaneInfoList.begin();
+    for( ; anIter3 != aPlaneInfoList.end(); anIter3++ ) {
+      const TPlaneInfo& aPlaneInfo = *anIter3;
+      int aPlaneId = aPlaneInfo.PlaneId;
+      const TActorList& anActorList = aPlaneInfo.ActorList;
+      SUIT_ViewManager* aViewManager = aPlaneInfo.ViewManager;
+      if( !aViewManager )
+        continue;
+
+      SVTK_ViewWindow* aViewWindow = dynamic_cast<SVTK_ViewWindow*>( aViewManager->getActiveView() );
+      if( !aViewWindow )
+        continue;
+
+      SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = myClippingPlaneInfoMap[ aViewManager ];
+
+      TPlaneDataList::const_iterator anIter4 = aPlaneDataList.begin();
+      for( ; anIter4 != aPlaneDataList.end(); anIter4++ ) {
+        const TPlaneData& aPlaneData = *anIter4;
+        if( aPlaneData.Id == aPlaneId ) {
+          SMESH::OrientedPlane* aPlane =
+            SMESHGUI_ClippingDlg::AddPlane( anActorList,
+                                            aViewWindow,
+                                            (SMESH::Orientation)aPlaneData.Orientation,
+                                            aPlaneData.Distance,
+                                            aPlaneData.Angle );
+          if( aPlane ) {
+            SMESH::ClippingPlaneInfo aClippingPlaneInfo;
+            aClippingPlaneInfo.Plane = aPlane;
+            aClippingPlaneInfo.ActorList = anActorList;
+            aClippingPlaneInfoList.push_back( aClippingPlaneInfo );
+          }
+          break;
+        }
+      }
+    }
+  }
+
   // update all VTK views
   QList<SUIT_ViewManager*> lst;
   getApp()->viewManagers(lst);
@@ -4290,8 +6018,8 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
 */
 int SMESHGUI::addVtkFontPref( const QString& label, const int pId, const QString& param )
 {
-  int tfont = addPreference( label, pId, LightApp_Preferences::Font, "VISU", param );
-  
+  int tfont = addPreference( label, pId, LightApp_Preferences::Font, "SMESH", param );
+
   setPreferenceProperty( tfont, "mode", QtxFontEdit::Custom );
 
   QStringList fam;
@@ -4307,8 +6035,167 @@ int SMESHGUI::addVtkFontPref( const QString& label, const int pId, const QString
   return tfont;
 }
 
+/*!
+  \brief Actions after hypothesis edition
+  Updates object browser after hypothesis edition
+*/
+void SMESHGUI::onHypothesisEdit( int result )
+{
+  if( result == 1 )
+    SMESHGUI::Modified();
+  updateObjBrowser( true );
+}
+
+
+/*!
+  \brief Signal handler closing(SUIT_ViewWindow*) of a view
+  \param pview view being closed
+*/
+void SMESHGUI::onViewClosed( SUIT_ViewWindow* pview ) {
+#ifndef DISABLE_PLOT2DVIEWER
+  //Crear all Plot2d Viewers if need.
+  SMESH::ClearPlot2Viewers(pview);
+#endif
+}
+
+void SMESHGUI::message( const QString& msg )
+{
+  // dispatch message
+  QStringList data = msg.split("/");
+  if ( data.count() > 0 ) {
+    if ( data.first() == "mesh_loading" ) {
+      // get mesh entry
+      QString entry = data.count() > 1 ? data[1] : QString();
+      if ( entry.isEmpty() )
+        return;
+      // get study
+      _PTR(Study) study = dynamic_cast<SalomeApp_Study*>( application()->activeStudy() )->studyDS();
+      // get mesh name
+      _PTR(SObject) obj = study->FindObjectID( entry.toLatin1().constData() );
+      QString name;
+      if ( obj )
+        name = obj->GetName().c_str();
+      if ( name.isEmpty() )
+        return;
+      
+      if ( data.last() == "stop" )
+        application()->putInfo( tr( "MESH_LOADING_MSG_FINISHED" ).arg( name ) );
+      else
+        application()->putInfo( tr( "MESH_LOADING_MSG" ).arg( name ) );
+      QApplication::processEvents();
+    }
+  }
+}
+
+/*!
+  \brief Connects or disconnects signals about activating and cloning view on the module slots
+  \param pview view which is connected/disconnected
+*/
+void SMESHGUI::connectView( const SUIT_ViewWindow* pview ) {
+  if(!pview)
+    return;
+
+  SUIT_ViewManager* viewMgr = pview->getViewManager();
+  if ( viewMgr ) {
+    disconnect( viewMgr, SIGNAL( deleteView( SUIT_ViewWindow* ) ),
+                this, SLOT( onViewClosed( SUIT_ViewWindow* ) ) );
+
+    connect( viewMgr, SIGNAL( deleteView( SUIT_ViewWindow* ) ),
+             this, SLOT( onViewClosed( SUIT_ViewWindow* ) ) );
+  }
+}
+
+/*!
+  \brief Return \c true if object can be renamed
+*/
+bool SMESHGUI::renameAllowed( const QString& entry) const {
+  SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( application() );
+  if( !anApp )
+    return false;
+
+  SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
+  if( !appStudy )
+    return false;
+
+  SalomeApp_DataObject* obj = dynamic_cast<SalomeApp_DataObject*>(appStudy->findObjectByEntry(entry));
+  
+  if(!obj)
+    return false;
+
+  if(appStudy->isComponent(entry) || obj->isReference())
+    return false;
+
+  // check type to prevent renaming of inappropriate objects
+  int aType = SMESHGUI_Selection::type(qPrintable(entry), SMESH::GetActiveStudyDocument());
+  if (aType == MESH || aType == GROUP ||
+      aType == SUBMESH || aType == SUBMESH_COMPOUND ||
+      aType == SUBMESH_SOLID || aType == SUBMESH_FACE ||
+      aType == SUBMESH_EDGE || aType == SUBMESH_VERTEX ||
+      aType == HYPOTHESIS || aType == ALGORITHM)
+    return true;
+
+  return false;
+}
 
+/*!
+  Rename object by entry.
+  \param entry entry of the object
+  \param name new name of the object
+  \brief Return \c true if rename operation finished successfully, \c false otherwise.
+*/
+bool SMESHGUI::renameObject( const QString& entry, const QString& name) {
 
+  SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( application() );
+  if( !anApp )
+    return false;
+    
+  SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
 
+  if(!appStudy)
+    return false;
+  
+  _PTR(Study) aStudy = appStudy->studyDS();
+  
+  if(!aStudy)
+    return false;
+  
+  bool aLocked = (_PTR(AttributeStudyProperties)(appStudy->studyDS()->GetProperties()))->IsLocked();
+  if ( aLocked ) {
+    SUIT_MessageBox::warning ( anApp->desktop(), QObject::tr("WRN_WARNING"), QObject::tr("WRN_STUDY_LOCKED") );
+    return false;
+  }
 
 
+  _PTR(SObject) obj = aStudy->FindObjectID( qPrintable(entry) );
+  _PTR(GenericAttribute) anAttr;
+  _PTR(AttributeName) aName;
+  if ( obj ) {
+    if ( obj->FindAttribute(anAttr, "AttributeName") ) {
+      aName = anAttr;
+      // check type to prevent renaming of inappropriate objects
+      int aType = SMESHGUI_Selection::type( qPrintable(entry), SMESH::GetActiveStudyDocument() );
+      if (aType == MESH || aType == GROUP ||
+          aType == SUBMESH || aType == SUBMESH_COMPOUND ||
+          aType == SUBMESH_SOLID || aType == SUBMESH_FACE ||
+          aType == SUBMESH_EDGE || aType == SUBMESH_VERTEX ||
+          aType == HYPOTHESIS || aType == ALGORITHM) {
+        if ( !name.isEmpty() ) {
+          SMESHGUI::GetSMESHGen()->SetName(obj->GetIOR().c_str(), qPrintable(name) );
+
+          // update name of group object and its actor
+          Handle(SALOME_InteractiveObject) IObject =
+            new SALOME_InteractiveObject ( qPrintable(entry), "SMESH", qPrintable(name) );
+
+          SMESH::SMESH_GroupBase_var aGroupObject = SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(IObject);
+          if( !aGroupObject->_is_nil() ) {
+            aGroupObject->SetName( qPrintable(name) );
+            if ( SMESH_Actor *anActor = SMESH::FindActorByEntry( qPrintable(entry) ) )
+              anActor->setName( qPrintable(name) );
+          }
+          return true;
+        }
+      }
+    }
+  }
+  return false;
+}
index 230bc3162a7f79c4aa712c76258c64cc71d7dc68..6f5237ce3adbdec3627dfbeff7e797b754037cbc 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI.h
 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
 
 // SALOME GUI includes
 #include <SalomeApp_Module.h>
+#include <VTKViewer_MarkerDef.h>
 #include <SALOME_InteractiveObject.hxx>
 
 // IDL includes
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Gen)
 
+// VTK includes
+#include <vtkSmartPointer.h>
+#include <vtkType.h>
+
+class vtkActor;
+class vtkCallbackCommand;
+class vtkObject;
+
 class QDialog;
 
 class SUIT_Desktop;
@@ -50,8 +60,24 @@ class SalomeApp_Study;
 class LightApp_Selection;
 class LightApp_SelectionMgr;
 
+class SMESH_Actor;
 class SMESHGUI_FilterLibraryDlg;
 
+typedef std::map<int, VTK::MarkerMap> SMESHGUI_StudyId2MarkerMap;
+
+namespace SMESH
+{
+  class OrientedPlane;
+  struct ClippingPlaneInfo
+  {
+    OrientedPlane*       Plane;
+    std::list<vtkActor*> ActorList;
+  };
+}
+
+typedef std::list<SMESH::ClippingPlaneInfo>                         SMESHGUI_ClippingPlaneInfoList;
+typedef std::map<SUIT_ViewManager*, SMESHGUI_ClippingPlaneInfoList> SMESHGUI_ClippingPlaneInfoMap;
+
 //=================================================================================
 // class    : SMESHGUI
 // purpose  :
@@ -70,11 +96,12 @@ public :
   static SUIT_ResourceMgr*        resourceMgr();
   static SUIT_Desktop*            desktop();
   static SalomeApp_Study*         activeStudy();
-  static char*                    JoinObjectParameters(const QStringList& theParametersList);
   
   bool                            isActiveStudyLocked();
 
-  static bool                     automaticUpdate();
+  static bool                     automaticUpdate(unsigned int requestedSize = 0, bool* limitExceeded = 0);
+
+  static void                     Modified( bool = true );
 
   virtual LightApp_Displayer*     displayer();
   virtual QString                 engineIOR() const;
@@ -104,11 +131,14 @@ public :
   void                            EmitSignalDeactivateDialog();
   void                            EmitSignalStudyFrameChanged();
   void                            EmitSignalCloseAllDialogs();
+  void                            EmitSignalVisibilityChanged();
 
   virtual void                    contextMenuPopup( const QString&, QMenu*, QString& );
   virtual void                    createPreferences();
   virtual void                    preferencesChanged( const QString&, const QString& );
 
+  virtual void                    message( const QString& );
+
   virtual void                    update( const int );
 
   static SALOMEDS::Color          getUniqueColor( const QList<SALOMEDS::Color>& );
@@ -116,29 +146,41 @@ public :
   virtual void                    storeVisualParameters  (int savePoint);
   virtual void                    restoreVisualParameters(int savePoint);
 
+  virtual void                    addActorAsObserver( SMESH_Actor* theActor );
+  
+  virtual bool                    renameAllowed( const QString& ) const;
+  virtual bool                    renameObject( const QString&, const QString& );
+
+
+  SMESHGUI_ClippingPlaneInfoMap&  getClippingPlaneInfoMap() { return myClippingPlaneInfoMap; }
+
 public slots:
   virtual bool                    deactivateModule( SUIT_Study* );
   virtual bool                    activateModule( SUIT_Study* );
   virtual void                    studyClosed( SUIT_Study* );
+  void                            onViewClosed( SUIT_ViewWindow* );
 
 private slots:
   void                            OnGUIEvent();
   void                            onViewManagerActivated( SUIT_ViewManager* );
+  void                            onViewManagerRemoved( SUIT_ViewManager* );
   void                            onOperationCommited( SUIT_Operation* );
   void                            onOperationAborted( SUIT_Operation* );
-
+  void                            onHypothesisEdit( int result );
 
 signals:
   void                            SignalDeactivateActiveDialog();
   void                            SignalStudyFrameChanged();
   void                            SignalCloseAllDialogs();
+  void                            SignalVisibilityChanged();
 
 protected:
   void                            createSMESHAction( const int,
                                                      const QString&,
                                                      const QString& = QString(),
                                                      const int = 0,
-                                                     const bool = false );
+                                                     const bool = false,
+                                                     const QString& = QString() );
   void                            createPopupItem( const int,
                                                    const QString&,
                                                    const QString&,
@@ -149,12 +191,22 @@ protected:
 
   virtual bool                    isSelectionCompatible();
 
+  virtual bool                    reusableOperation( const int id ); 
+
+  static void                     ProcessEvents( vtkObject* theObject, 
+                                                 unsigned long theEvent,
+                                                 void* theClientData, 
+                                                 void* theCallData );
+
 private:
   void                            OnEditDelete();
   int                             addVtkFontPref( const QString& label, 
                                                   const int pId, 
                                                   const QString& param );
 
+  void                            connectView( const SUIT_ViewWindow* );
+
 private :
   static SMESH::SMESH_Gen_var     myComponentSMESH;
   QDialog*                        myActiveDialogBox;
@@ -163,6 +215,12 @@ private :
   LightApp_Displayer*             myDisplayer;
 
   SMESHGUI_FilterLibraryDlg*      myFilterLibraryDlg;
+
+  SMESHGUI_StudyId2MarkerMap      myMarkerMap;
+  SMESHGUI_ClippingPlaneInfoMap   myClippingPlaneInfoMap;
+
+  vtkSmartPointer<vtkCallbackCommand> myEventCallbackCommand;
+  vtkFloatingPointType            myPriority;
 };
 
 #endif // SMESHGUI_H
index 97e393a248d67f7c03253f60609e9dbf81802441..2febf76f82f06b54077812d8cbefdc472d8ae509 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_AddMeshElementDlg.cxx
 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
 #include "SMESHGUI_AddMeshElementDlg.h"
 
 #include "SMESHGUI.h"
+#include "SMESHGUI_GroupUtils.h"
+#include "SMESHGUI_IdValidator.h"
+#include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI_SpinBox.h"
 #include "SMESHGUI_Utils.h"
 #include "SMESHGUI_VTKUtils.h"
-#include "SMESHGUI_MeshUtils.h"
-#include "SMESHGUI_IdValidator.h"
 
 #include <SMESH_Actor.h>
 #include <SMESH_ActorUtils.h>
@@ -64,6 +67,7 @@
 #include <vtkProperty.h>
 
 // Qt includes
+#include <QComboBox>
 #include <QGroupBox>
 #include <QLabel>
 #include <QLineEdit>
@@ -154,43 +158,19 @@ namespace SMESH
 
     typedef std::vector<vtkIdType> TVTKIds;
     void SetPosition (SMESH_Actor* theActor,
-                      vtkIdType theType,
-                      const TVTKIds& theIds)
+                      vtkIdType    theType,
+                      TVTKIds&     theIds)
     {
       vtkUnstructuredGrid *aGrid = theActor->GetUnstructuredGrid();
       myGrid->SetPoints(aGrid->GetPoints());
+      myGrid->Reset();
 
-      const int* aConn = NULL;
-      switch (theType) {
-      case VTK_TETRA:
-        {
-          static int anIds[] = {0,2,1,3};
-          aConn = anIds;
-          break;
-        }
-      case VTK_PYRAMID:
-        {
-          static int anIds[] = {0,3,2,1,4};
-          aConn = anIds;
-          break;
-        }
-      case VTK_HEXAHEDRON:
-        {
-          static int anIds[] = {0,3,2,1,4,7,6,5};
-          aConn = anIds;
-          break;
-        }
-      }
+      const std::vector<int>& interlace = SMDS_MeshCell::toVtkOrder( VTKCellType( theType ));
+      SMDS_MeshCell::applyInterlace( interlace, theIds );
 
-      myGrid->Reset();
       vtkIdList *anIds = vtkIdList::New();
-
-      if(aConn)
-       for (int i = 0, iEnd = theIds.size(); i < iEnd; i++)
-         anIds->InsertId(i,theIds[aConn[i]]);
-      else
-       for (int i = 0, iEnd = theIds.size(); i < iEnd; i++)
-         anIds->InsertId(i,theIds[i]);
+      for (int i = 0, iEnd = theIds.size(); i < iEnd; i++)
+        anIds->InsertId(i,theIds[i]);
 
       myGrid->InsertNextCell(theType,anIds);
       anIds->Delete();
@@ -212,8 +192,8 @@ namespace SMESH
     ~TElementSimulation()
     {
       if (FindVtkViewWindow(myApplication->activeViewManager(), myViewWindow)) {
-       myVTKViewWindow->RemoveActor(myPreviewActor);
-       myVTKViewWindow->RemoveActor(myFaceOrientation);
+        myVTKViewWindow->RemoveActor(myPreviewActor);
+        myVTKViewWindow->RemoveActor(myFaceOrientation);
       }
       myPreviewActor->Delete();
       myFaceOrientation->Delete();
@@ -235,12 +215,12 @@ namespace SMESH
 // function : SMESHGUI_AddMeshElementDlg()
 // purpose  : constructor
 //=================================================================================
-SMESHGUI_AddMeshElementDlg::SMESHGUI_AddMeshElementDlg( SMESHGUI* theModule,
-                                                        SMDSAbs_ElementType ElementType, 
-                                                       int nbNodes )
+SMESHGUI_AddMeshElementDlg::SMESHGUI_AddMeshElementDlg( SMESHGUI*          theModule,
+                                                        SMDSAbs_EntityType ElementType)
   : QDialog( SMESH::GetDesktop( theModule ) ),
     mySMESHGUI( theModule ),
-    mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
+    mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
+    myBusy ( false )
 {
   setModal( false );
   setAttribute( Qt::WA_DeleteOnClose, true );
@@ -250,55 +230,80 @@ SMESHGUI_AddMeshElementDlg::SMESHGUI_AddMeshElementDlg( SMESHGUI* theModule,
   myIsPoly = false;
   mySimulation = new SMESH::TElementSimulation (anApp);
   mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
+  myGeomType = ElementType;
+  myElementType = SMDSAbs_Volume;
 
   // verify nb nodes and type
-  myNbNodes = nbNodes;
-  myElementType = ElementType;
-  switch (ElementType) {
-  case SMDSAbs_Face:
-    //     if (myNbNodes != 3 && myNbNodes != 4)
-    //       myNbNodes = 3;
-    //     break;
-  case SMDSAbs_Volume:
-    //     if (myNbNodes != 4 && myNbNodes != 8) //(nbNodes < 4 || nbNodes > 8 || nbNodes == 7)
-    //       myNbNodes = 4;
+  QString elemName;
+  switch ( myGeomType ) {
+  case SMDSEntity_0D:
+    myNbNodes = 1;
+    myElementType = SMDSAbs_0DElement;
+    elemName = "ELEM0D";
+    myHelpFileName = "adding_nodes_and_elements_page.html#adding_0delems_anchor";
     break;
-  default:
-    myElementType = SMDSAbs_Edge;
+  case SMDSEntity_Ball:
+    myNbNodes = 1;
+    myElementType = SMDSAbs_Ball;
+    elemName = "BALL";
+    myHelpFileName = "adding_nodes_and_elements_page.html#adding_ball_anchor";
+    break;
+  case SMDSEntity_Edge:
     myNbNodes = 2;
-  }
-
-  QString elemName;
-  if (myNbNodes == 2) {
+    myElementType = SMDSAbs_Edge;
     elemName = "EDGE";
     myHelpFileName = "adding_nodes_and_elements_page.html#adding_edges_anchor";
-  }
-  else if (myNbNodes == 3) {
+    break;
+  case SMDSEntity_Triangle:
+    myNbNodes = 3;
     elemName = "TRIANGLE";
+    myElementType = SMDSAbs_Face;
     myHelpFileName = "adding_nodes_and_elements_page.html#adding_triangles_anchor";
-  }
-  else if (myNbNodes == 4)
-    if (myElementType == SMDSAbs_Face) {
-      elemName = "QUADRANGLE";
-      myHelpFileName = "adding_nodes_and_elements_page.html#adding_quadrangles_anchor";
-    }
-    else {
-      elemName = "TETRAS";
-      myHelpFileName = "adding_nodes_and_elements_page.html#adding_tetrahedrons_anchor";
-    }
-  else if (myNbNodes == 8) {
-    elemName = "HEXAS";
-    myHelpFileName = "adding_nodes_and_elements_page.html#adding_hexahedrons_anchor";
-  }
-  else if (myElementType == SMDSAbs_Face) {
+    break;
+  case SMDSEntity_Quadrangle:
+    myNbNodes = 4;
+    myElementType = SMDSAbs_Face;
+    elemName = "QUADRANGLE";
+    myHelpFileName = "adding_nodes_and_elements_page.html#adding_quadrangles_anchor";
+    break;
+  case SMDSEntity_Polygon:
+    myNbNodes = 0;
+    myElementType = SMDSAbs_Face;
     elemName = "POLYGON";
     myIsPoly = true;
     myHelpFileName = "adding_nodes_and_elements_page.html#adding_polygons_anchor";
+    break;
+  case SMDSEntity_Tetra:
+    myNbNodes = 4;
+    elemName = "TETRAS";
+    myHelpFileName = "adding_nodes_and_elements_page.html#adding_tetrahedrons_anchor";
+    break;
+  case SMDSEntity_Pyramid:
+    myNbNodes = 5;
+    elemName = "PYRAMID";
+    myHelpFileName = "adding_nodes_and_elements_page.html#adding_pyramids_anchor";
+    break;
+  case SMDSEntity_Hexa:
+    myNbNodes = 8;
+    elemName = "HEXAS";
+    myHelpFileName = "adding_nodes_and_elements_page.html#adding_hexahedrons_anchor";
+    break;
+  case SMDSEntity_Penta:
+    myNbNodes = 6;
+    elemName = "PENTA";
+    myHelpFileName = "adding_nodes_and_elements_page.html#adding_pentahedrons_anchor";
+    break;
+  case SMDSEntity_Hexagonal_Prism:
+    myNbNodes = 12;
+    elemName = "OCTA";
+    myHelpFileName = "adding_nodes_and_elements_page.html#adding_octahedrons_anchor";
+    break;
+  default:
+    myNbNodes = 2;
+    elemName = "EDGE";
+    myHelpFileName = "adding_nodes_and_elements_page.html#adding_edges_anchor";
   }
-  else if (myElementType == SMDSAbs_Volume) {
-    myHelpFileName = "adding_nodes_and_elements_page.html#adding_polyhedrons_anchor";
-  }
-  
+
   QString iconName      = tr(QString("ICON_DLG_%1").arg(elemName).toLatin1().data());
   QString buttonGrTitle = tr(QString("SMESH_%1").arg(elemName).toLatin1().data());
   QString caption       = tr(QString("SMESH_ADD_%1_TITLE").arg(elemName).toLatin1().data());
@@ -314,7 +319,7 @@ SMESHGUI_AddMeshElementDlg::SMESHGUI_AddMeshElementDlg( SMESHGUI* theModule,
   aTopLayout->setSpacing(SPACING);
   aTopLayout->setMargin(MARGIN);
 
-  /***************************************************************/
+  /* Constructor *************************************************/
   GroupConstructors = new QGroupBox(buttonGrTitle, this);
   QButtonGroup* ButtonGroup = new QButtonGroup(this);
   QHBoxLayout* GroupConstructorsLayout = new QHBoxLayout(GroupConstructors);
@@ -328,7 +333,7 @@ SMESHGUI_AddMeshElementDlg::SMESHGUI_AddMeshElementDlg( SMESHGUI* theModule,
   GroupConstructorsLayout->addWidget(Constructor1);
   ButtonGroup->addButton( Constructor1, 0 );
 
-  /***************************************************************/
+  /* Nodes & Reverse *********************************************/
   GroupC1 = new QGroupBox(grBoxTitle, this);
   QGridLayout* GroupC1Layout = new QGridLayout(GroupC1);
   GroupC1Layout->setSpacing(SPACING);
@@ -338,18 +343,42 @@ SMESHGUI_AddMeshElementDlg::SMESHGUI_AddMeshElementDlg( SMESHGUI* theModule,
   SelectButtonC1A1 = new QPushButton(GroupC1);
   SelectButtonC1A1->setIcon(image1);
   LineEditC1A1 = new QLineEdit(GroupC1);
-  //  LineEditC1A1->setReadOnly(true);
-  if (!myIsPoly)
-    LineEditC1A1->setValidator(new SMESHGUI_IdValidator(this, myNbNodes));
+  LineEditC1A1->setValidator(new SMESHGUI_IdValidator(this, myIsPoly ? 1000 : myNbNodes));
 
-  Reverse = myElementType == SMDSAbs_Face ? new QCheckBox(tr("SMESH_REVERSE"), GroupC1) : 0;
+  Reverse = (myElementType == SMDSAbs_Face || myElementType == SMDSAbs_Volume ) ? new QCheckBox(tr("SMESH_REVERSE"), GroupC1) : 0;
+
+  DiameterSpinBox = ( myGeomType == SMDSEntity_Ball ) ? new SMESHGUI_SpinBox(GroupC1) : 0;
+  QLabel* diameterLabel = DiameterSpinBox ? new QLabel( tr("BALL_DIAMETER"),GroupC1) : 0;
 
   GroupC1Layout->addWidget(TextLabelC1A1,    0, 0);
   GroupC1Layout->addWidget(SelectButtonC1A1, 0, 1);
   GroupC1Layout->addWidget(LineEditC1A1,     0, 2);
-  if ( Reverse ) GroupC1Layout->addWidget(Reverse, 1, 0, 1, 3);
+  if ( Reverse ) {
+    GroupC1Layout->addWidget(Reverse, 1, 0, 1, 3);
+  }
+  if ( DiameterSpinBox ) {
+    GroupC1Layout->addWidget(diameterLabel,   1, 0);
+    GroupC1Layout->addWidget(DiameterSpinBox, 1, 1, 1, 2);
 
-  /***************************************************************/
+    DiameterSpinBox->RangeStepAndValidator( 1e-7, 1e+9, 0.1 );
+    DiameterSpinBox->SetValue( 1. );
+  }
+  /* Add to group ************************************************/
+  GroupGroups = new QGroupBox( tr( "SMESH_ADD_TO_GROUP" ), this );
+  GroupGroups->setCheckable( true );
+  QHBoxLayout* GroupGroupsLayout = new QHBoxLayout(GroupGroups);
+  GroupGroupsLayout->setSpacing(SPACING);
+  GroupGroupsLayout->setMargin(MARGIN);
+
+  TextLabel_GroupName = new QLabel( tr( "SMESH_GROUP" ), GroupGroups );
+  ComboBox_GroupName = new QComboBox( GroupGroups );
+  ComboBox_GroupName->setEditable( true );
+  ComboBox_GroupName->setInsertPolicy( QComboBox::NoInsert );
+
+  GroupGroupsLayout->addWidget( TextLabel_GroupName );
+  GroupGroupsLayout->addWidget( ComboBox_GroupName, 1 );
+
+  /* Apply etc ***************************************************/
   GroupButtons = new QGroupBox(this);
   QHBoxLayout* GroupButtonsLayout = new QHBoxLayout(GroupButtons);
   GroupButtonsLayout->setSpacing(SPACING);
@@ -376,6 +405,7 @@ SMESHGUI_AddMeshElementDlg::SMESHGUI_AddMeshElementDlg( SMESHGUI* theModule,
   /***************************************************************/
   aTopLayout->addWidget(GroupConstructors);
   aTopLayout->addWidget(GroupC1);
+  aTopLayout->addWidget(GroupGroups);
   aTopLayout->addWidget(GroupButtons);
 
   Init(); /* Initialisations */
@@ -401,6 +431,10 @@ void SMESHGUI_AddMeshElementDlg::Init()
   myEditCurrentArgument = LineEditC1A1;
   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
 
+  /* reset "Add to group" control */
+  GroupGroups->setChecked( false );
+  //GroupGroups->setVisible( myElementType != SMDSAbs_0DElement );
+
   myNbOkNodes = 0;
   myActor = 0;
 
@@ -416,6 +450,7 @@ void SMESHGUI_AddMeshElementDlg::Init()
   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(SelectionIntoArgument()));
   /* to close dialog if study frame change */
   connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), SLOT(ClickOnCancel()));
+  connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), SLOT(ClickOnCancel()));    
 
   if (Reverse)
     connect(Reverse, SIGNAL(stateChanged(int)), SLOT(CheckBox(int)));
@@ -437,33 +472,99 @@ void SMESHGUI_AddMeshElementDlg::Init()
 //=================================================================================
 void SMESHGUI_AddMeshElementDlg::ClickOnApply()
 {
+  if( !isValid() )
+    return;
+
   if (myNbOkNodes && !mySMESHGUI->isActiveStudyLocked()) {
     myBusy = true;
-    SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array;
-    anArrayOfIdeces->length(myNbNodes);
-    bool reverse = (Reverse && Reverse->isChecked());
+    SMESH::long_array_var anArrayOfIndices = new SMESH::long_array;
+    anArrayOfIndices->length(myNbNodes);
     QStringList aListId = myEditCurrentArgument->text().split(" ", QString::SkipEmptyParts);
-    for (int i = 0; i < aListId.count(); i++)
-      if (reverse)
-        anArrayOfIdeces[i] = aListId[ myNbNodes - i - 1 ].toInt();
-      else
-        anArrayOfIdeces[i] = aListId[ i ].toInt();
+    const std::vector<int>& revIndex = SMDS_MeshCell::reverseSmdsOrder( myGeomType );
+    if ( Reverse && Reverse->isChecked() && !revIndex.empty() )
+      for (int i = 0; i < aListId.count(); i++)
+        anArrayOfIndices[i] = aListId[ revIndex[i] ].toInt();
+    else if ( Reverse && Reverse->isChecked() && revIndex.empty() ) // polygon
+      for (int i = 0; i < aListId.count(); i++)
+        anArrayOfIndices[i] = aListId[ aListId.count()-1 - i ].toInt();
+    else
+      for (int i = 0; i < aListId.count(); i++)
+        anArrayOfIndices[i] = aListId[ i ].toInt();
+
+    bool addToGroup = GroupGroups->isChecked();
+    QString aGroupName;
+
+    SMESH::SMESH_GroupBase_var aGroup;
+    int idx = 0;
+    if( addToGroup ) {
+      aGroupName = ComboBox_GroupName->currentText();
+      for ( int i = 1; i < ComboBox_GroupName->count(); i++ ) {
+        QString aName = ComboBox_GroupName->itemText( i );
+        if ( aGroupName == aName && ( i == ComboBox_GroupName->currentIndex() || idx == 0 ) )
+          idx = i;
+      }
+      if ( idx > 0 && idx < myGroups.count() ) {
+        SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( myGroups[idx-1] );
+        if ( !aGeomGroup->_is_nil() ) {
+          int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ),
+                                               tr( "MESH_STANDALONE_GRP_CHOSEN" ).arg( aGroupName ),
+                                               tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
+          if ( res == 1 ) return;
+        }
+        aGroup = myGroups[idx-1];
+      }
+    }
 
+    long anElemId = -1;
     SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
     switch (myElementType) {
+    case SMDSAbs_0DElement:
+      anElemId = aMeshEditor->Add0DElement(anArrayOfIndices[0]); break;
+    case SMDSAbs_Ball:
+      if ( myGeomType == SMDSEntity_Ball )
+        anElemId = aMeshEditor->AddBall(anArrayOfIndices[0],
+                                        DiameterSpinBox->GetValue()); break;
     case SMDSAbs_Edge:
-      aMeshEditor->AddEdge(anArrayOfIdeces.inout()); break;
-    case SMDSAbs_Face:{
-      if(myIsPoly)
-       aMeshEditor->AddPolygonalFace(anArrayOfIdeces.inout());
+      anElemId = aMeshEditor->AddEdge(anArrayOfIndices.inout()); break;
+    case SMDSAbs_Face:
+      if ( myIsPoly )
+        anElemId = aMeshEditor->AddPolygonalFace(anArrayOfIndices.inout());
       else
-       aMeshEditor->AddFace(anArrayOfIdeces.inout());
+        anElemId = aMeshEditor->AddFace(anArrayOfIndices.inout());
       break;
-
+    default:
+      anElemId = aMeshEditor->AddVolume(anArrayOfIndices.inout()); break;
     }
-    case SMDSAbs_Volume:
-      aMeshEditor->AddVolume(anArrayOfIdeces.inout()); break;
-    default:;
+
+    if ( anElemId != -1 && addToGroup && !aGroupName.isEmpty() ) {
+      SMESH::SMESH_Group_var aGroupUsed;
+      if ( aGroup->_is_nil() ) {
+        // create new group 
+        aGroupUsed = SMESH::AddGroup( myMesh, (SMESH::ElementType)myElementType, aGroupName );
+        if ( !aGroupUsed->_is_nil() ) {
+          myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroupUsed));
+          ComboBox_GroupName->addItem( aGroupName );
+        }
+      }
+      else {
+        SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup );
+        if ( !aGeomGroup->_is_nil() ) {
+          aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup );
+          if ( !aGroupUsed->_is_nil() && idx > 0 ) {
+            myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed);
+            SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser();
+          }
+        }
+        else
+          aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup );
+      }
+
+      if ( !aGroupUsed->_is_nil() ) {
+        SMESH::long_array_var anIdList = new SMESH::long_array;
+        anIdList->length( 1 );
+        anIdList[0] = anElemId;
+        aGroupUsed->Add( anIdList.inout() );
+      }
     }
 
     SALOME_ListIO aList; aList.Append( myActor->getIO() );
@@ -479,6 +580,8 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply()
     myEditCurrentArgument->setText("");
 
     myBusy = false;
+
+    SMESHGUI::Modified();
   }
 }
 
@@ -515,8 +618,9 @@ void SMESHGUI_AddMeshElementDlg::ClickOnCancel()
 void SMESHGUI_AddMeshElementDlg::ClickOnHelp()
 {
   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
-  if (app) 
-    app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
+  if (app)
+    app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""),
+                             myHelpFileName);
   else {
     QString platform;
 #ifdef WIN32
@@ -525,10 +629,10 @@ void SMESHGUI_AddMeshElementDlg::ClickOnHelp()
     platform = "application";
 #endif
     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser", 
-                                                                platform)).
-                            arg(myHelpFileName));
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser",
+                                                                 platform)).
+                             arg(myHelpFileName));
   }
 }
 
@@ -555,40 +659,40 @@ void SMESHGUI_AddMeshElementDlg::onTextChange (const QString& theNewText)
 
   if (aMesh) {
     TColStd_MapOfInteger newIndices;
-    
+
     QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
     bool allOk = true;
     for (int i = 0; i < aListId.count(); i++) {
       if( const SMDS_MeshNode * n = aMesh->FindNode( aListId[ i ].toInt() ) )
-       {
-         newIndices.Add( n->GetID() );
-         myNbOkNodes++;
-       }
+        {
+          newIndices.Add( n->GetID() );
+          myNbOkNodes++;
+        }
       else
-       allOk = false;  
+        allOk = false;  
     }
-    
+
     mySelector->AddOrRemoveIndex( myActor->getIO(), newIndices, false );
     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
       aViewWindow->highlight( myActor->getIO(), true, true );
-    
+
     myNbOkNodes = ( allOk && myNbNodes == aListId.count() );
-    
+
     if (myIsPoly)
       {
-       if ( !allOk || myElementType != SMDSAbs_Face || aListId.count() < 3 )
-         myNbOkNodes = 0;
-       else
-         myNbOkNodes = aListId.count();
+        if ( !allOk || myElementType != SMDSAbs_Face || aListId.count() < 3 )
+          myNbOkNodes = 0;
+        else
+          myNbOkNodes = aListId.count();
       }
   }
-  
+
   if(myNbOkNodes) {
     buttonOk->setEnabled(true);
     buttonApply->setEnabled(true);
     displaySimulation();
   }
-  
+
   myBusy = false;
 }
 
@@ -617,6 +721,8 @@ void SMESHGUI_AddMeshElementDlg::SelectionIntoArgument()
   mySimulation->SetVisibility(false);
   //  SMESH::SetPointRepresentation(true);
 
+  QString aCurrentEntry = myEntry;
+
   // get selected mesh
   SALOME_ListIO aList;
   mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
@@ -625,10 +731,29 @@ void SMESHGUI_AddMeshElementDlg::SelectionIntoArgument()
     return;
 
   Handle(SALOME_InteractiveObject) anIO = aList.First();
+  myEntry = anIO->getEntry();
   myMesh = SMESH::GetMeshByIO(anIO);
   if (myMesh->_is_nil())
     return;
 
+  // process groups
+  if ( !myMesh->_is_nil() && myEntry != aCurrentEntry ) {
+    myGroups.clear();
+    ComboBox_GroupName->clear();
+    ComboBox_GroupName->addItem( QString() );
+    SMESH::ListOfGroups aListOfGroups = *myMesh->GetGroups();
+    for ( int i = 0, n = aListOfGroups.length(); i < n; i++ ) {
+      SMESH::SMESH_GroupBase_var aGroup = aListOfGroups[i];
+      if ( !aGroup->_is_nil() && aGroup->GetType() == (SMESH::ElementType)myElementType ) {
+        QString aGroupName( aGroup->GetName() );
+        if ( !aGroupName.isEmpty() ) {
+          myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup));
+          ComboBox_GroupName->addItem( aGroupName );
+        }
+      }
+    }
+  }
+
   myActor = SMESH::FindActorByEntry(anIO->getEntry());
   if (!myActor)
     return;
@@ -667,24 +792,15 @@ void SMESHGUI_AddMeshElementDlg::displaySimulation()
       anIds.push_back(myActor->GetObject()->GetNodeVTKId(aListId[ i ].toInt()));
 
     if (Reverse && Reverse->isChecked())
-      reverse(anIds.begin(),anIds.end());
-
-    vtkIdType aType = 0;
-    if (myIsPoly)
-      switch ( myElementType ) {
-      case SMDSAbs_Face  : aType = VTK_POLYGON; break;
-      default: return;
-      }
-    else {
-      switch (myNbNodes) {
-      case 2: aType = VTK_LINE; break;
-      case 3: aType = VTK_TRIANGLE; break;
-      case 4: aType = myElementType == SMDSAbs_Face ? VTK_QUAD : VTK_TETRA; break;
-      case 8: aType = VTK_HEXAHEDRON; break;
-      default: return;
-      }
+    {
+      const std::vector<int>& i = SMDS_MeshCell::reverseSmdsOrder( myGeomType );
+      if ( i.empty() ) // polygon
+        std::reverse( anIds.begin(), anIds.end() );
+      else
+        SMDS_MeshCell::applyInterlace( i, anIds );
     }
 
+    vtkIdType aType = SMDS_MeshCell::toVtkType( myGeomType );
     mySimulation->SetPosition(myActor,aType,anIds);
     SMESH::UpdateView();
   }
@@ -795,9 +911,22 @@ void SMESHGUI_AddMeshElementDlg::keyPressEvent( QKeyEvent* e )
   QDialog::keyPressEvent( e );
   if ( e->isAccepted() )
     return;
-  
+
   if ( e->key() == Qt::Key_F1 ) {
     e->accept();
     ClickOnHelp();
   }
 }
+
+//=================================================================================
+// function : isValid
+// purpose  :
+//=================================================================================
+bool SMESHGUI_AddMeshElementDlg::isValid()
+{
+  if( GroupGroups->isChecked() && ComboBox_GroupName->currentText().isEmpty() ) {
+    SUIT_MessageBox::warning( this, tr( "SMESH_WRN_WARNING" ), tr( "GROUP_NAME_IS_EMPTY" ) );
+    return false;
+  }
+  return true;
+}
index ee10b312fb752d8cd77407fe0bf4789c50e31064..72ad06d9308db6cef46c114a8a8e10b3c8ec6884 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_AddMeshElementDlg.h
 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
@@ -38,6 +39,7 @@
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Mesh)
 
+class QComboBox;
 class QGroupBox;
 class QLabel;
 class QLineEdit;
@@ -48,6 +50,7 @@ class SMESHGUI;
 class SMESH_Actor;
 class SVTK_Selector;
 class LightApp_SelectionMgr;
+class SMESHGUI_SpinBox;
 
 namespace SMESH
 {
@@ -63,7 +66,7 @@ class SMESHGUI_EXPORT SMESHGUI_AddMeshElementDlg : public QDialog
   Q_OBJECT
 
 public:
-  SMESHGUI_AddMeshElementDlg( SMESHGUI*, SMDSAbs_ElementType = SMDSAbs_Edge, int = 2 );
+  SMESHGUI_AddMeshElementDlg( SMESHGUI*, SMDSAbs_EntityType = SMDSEntity_Edge );
   ~SMESHGUI_AddMeshElementDlg();
   
 private:
@@ -74,6 +77,10 @@ private:
   void                        keyPressEvent( QKeyEvent* );
   void                        displaySimulation();
   
+  bool                        isValid();
+  
+  typedef QList<SMESH::SMESH_GroupBase_var> GrpList;
+  
   SMESHGUI*                   mySMESHGUI;              /* Current SMESHGUI object */
   LightApp_SelectionMgr*      mySelectionMgr;          /* User shape selection */
   int                         myNbOkNodes;             /* to check when arguments is defined */
@@ -82,6 +89,7 @@ private:
   
   QLineEdit*                  myEditCurrentArgument;   /* Current  LineEdit */
   
+  SMDSAbs_EntityType          myGeomType;
   int                         myElementType;
   int                         myNbNodes;
   bool                        myIsPoly;
@@ -89,9 +97,14 @@ private:
   SMESH::SMESH_Mesh_var       myMesh;
   SMESH_Actor*                myActor;
   SMESH::TElementSimulation*  mySimulation;
+  QString                     myEntry;
+  GrpList                     myGroups;
   
   QGroupBox*                  GroupConstructors;
   QRadioButton*               Constructor1;
+  QGroupBox*                  GroupGroups;
+  QLabel*                     TextLabel_GroupName;
+  QComboBox*                  ComboBox_GroupName;
   QGroupBox*                  GroupButtons;
   QPushButton*                buttonOk;
   QPushButton*                buttonCancel;
@@ -102,6 +115,7 @@ private:
   QPushButton*                SelectButtonC1A1;
   QLineEdit*                  LineEditC1A1;
   QCheckBox*                  Reverse;
+  SMESHGUI_SpinBox*           DiameterSpinBox;
   
   QString                     myHelpFileName;
   
index 1c3106e735eb3c1ed149aceebfa603bd56d8d136..0472de715d82c9e7ccbc259db5c464af50837df8 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_AddMeshElementDlg.cxx
 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
@@ -30,6 +31,7 @@
 #include "SMESHGUI_Utils.h"
 #include "SMESHGUI_VTKUtils.h"
 #include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI_GroupUtils.h"
 #include "SMESHGUI_IdValidator.h"
 
 #include <SMESH_Actor.h>
@@ -69,6 +71,7 @@
 #include <vtkCellType.h>
 
 // Qt includes
+#include <QComboBox>
 #include <QGroupBox>
 #include <QLabel>
 #include <QLineEdit>
 #define SPACING 6
 #define MARGIN  11
 
-namespace SMESH
+namespace
 {
-  void ReverseConnectivity( std::vector<vtkIdType> & ids, int type )
+  void ReverseConnectivity( std::vector<vtkIdType> & ids, SMDSAbs_EntityType type,
+                            bool toReverse, // inverse element
+                            bool toVtkOrder ) // smds connectivity to vtk one
   {
-    // for reverse connectivity of other types keeping the first id, see
-    // void SMESH_VisualObjDef::buildElemPrs() in SMESH_Object.cxx:900
-    const int* conn = 0;
-   
-    switch ( type ) {
-    case QUAD_TETRAHEDRON: {
-      static int aConn[] = {0,2,1,3,6,5,4,7,9,8};
-      conn = aConn;
-      break;
-    }
-    case QUAD_PYRAMID: {
-      static int aConn[] = {0,3,2,1,4,8,7,6,5,9,12,11,10};
-      conn = aConn;
-      break;
-    }
-    case QUAD_PENTAHEDRON: {
-      static int aConn[] = {0,2,1,3,5,4,8,7,6,11,10,9,12,14,13};
-      conn = aConn;
-      break;
-    }
-    case QUAD_HEXAHEDRON: {
-      static int aConn[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17};
-      conn = aConn;
-      break;
-    }
-    case QUAD_EDGE: {
-      static int aConn[] = {1,0,2};
-      conn = aConn;
-      break;
-    }
-    case QUAD_TRIANGLE: {
-      static int aConn[] = {0,2,1,5,4,3};
-      conn = aConn;
-      break;
-    }
-    case QUAD_QUADRANGLE: {
-      static int aConn[] = {0,3,2,1,7,6,5,4};
-      conn = aConn;
-      break;
-    }
-    default:;
-    }
-    if ( !conn ) {
-      reverse( ids.begin(), ids.end() );
+    if ( toReverse ) // first reverse smds order
+    {
+      const std::vector<int>& index = SMDS_MeshCell::reverseSmdsOrder(type);
+      SMDS_MeshCell::applyInterlace( index, ids );
     }
-    else {
-      std::vector<vtkIdType> aRevIds( ids.size() );
-      for ( int i = 0; i < ids.size(); i++)
-        aRevIds[ i ] = ids[ conn[ i ]];
-      ids = aRevIds;
+    if ( toVtkOrder ) // from smds to vtk connectivity
+    {
+      const std::vector<int>& index = SMDS_MeshCell::toVtkOrder(type);
+      SMDS_MeshCell::applyInterlace( index, ids );
     }
   }
-
+}
+namespace SMESH
+{
   class TElementSimulation {
     SalomeApp_Application* myApplication;
     SUIT_ViewWindow* myViewWindow;
@@ -218,85 +184,36 @@ namespace SMESH
     }
 
     typedef std::vector<vtkIdType> TVTKIds;
-    void SetPosition (SMESH_Actor* theActor,
-                      const int    theType,
-                      TVTKIds&     theIds,
-                     const int    theMode,
-                      const bool   theReverse)
+    void SetPosition (SMESH_Actor*       theActor,
+                      SMDSAbs_EntityType theType,
+                      TVTKIds&           theIds,
+                      const int          theMode,
+                      const bool         theReverse)
     {
       vtkUnstructuredGrid *aGrid = theActor->GetUnstructuredGrid();
       myGrid->SetPoints(aGrid->GetPoints());
 
       //add points
 
-      vtkIdType aType = 0;
+      ReverseConnectivity( theIds, theType, theReverse, /*toVtkOrder=*/true);
 
-      switch (theType) {
-      case QUAD_EDGE:
-        aType = VTK_QUADRATIC_EDGE;
-        break;
-      case QUAD_TRIANGLE:
-        aType = VTK_QUADRATIC_TRIANGLE; 
-        break;
-      case QUAD_QUADRANGLE:
-        aType = VTK_QUADRATIC_QUAD; 
-        break;
-      case QUAD_TETRAHEDRON:
-        aType = VTK_QUADRATIC_TETRA; 
-        break;
-      case QUAD_PYRAMID:
-        //aType = VTK_QUADRATIC_PYRAMID; // NOT SUPPORTED IN VTK4.2
-        aType = VTK_CONVEX_POINT_SET;
-        break;
-      case QUAD_PENTAHEDRON:
-        aType = VTK_QUADRATIC_WEDGE;
-        //aType = VTK_CONVEX_POINT_SET;
-        break; 
-      case QUAD_HEXAHEDRON:
-        aType = VTK_QUADRATIC_HEXAHEDRON;
-        break;
-      }
-
-      // take care of orientation
-      if ( aType == VTK_CONVEX_POINT_SET ) {
-        if ( theReverse && theMode == VTK_SURFACE ) {
-          //myPreviewActor->GetProperty()->SetColor( myBackRGB[0], myBackRGB[1], myBackRGB[2] );
-        }
-      }
-      else {
-        // VTK cell connectivity opposites the MED one for volumic elements
-        if( aType != VTK_QUADRATIC_WEDGE) {
-          if ( theIds.size() > 8 ? !theReverse : theReverse ) {
-            ReverseConnectivity( theIds, theType );
-          }
-        }
-        else if(theReverse)
-          ReverseConnectivity( theIds, theType );          
-      }
-            
       myGrid->Reset();
       vtkIdList *anIds = vtkIdList::New();
-      
+
       for (int i = 0, iEnd = theIds.size(); i < iEnd; i++) {
         anIds->InsertId(i,theIds[i]);
         //std::cout << i<< ": " << theIds[i] << std::endl;
       }
-      
+
+      vtkIdType aType = SMDS_MeshCell::toVtkType(theType);
       myGrid->InsertNextCell(aType,anIds);
       anIds->Delete();
-      
+
       myGrid->Modified();
 
       myPreviewActor->GetMapper()->Update();
       myPreviewActor->SetRepresentation( theMode );
       SetVisibility(true, theActor->GetFacesOriented());
-
-      // restore normal orientation
-      if ( aType == VTK_CONVEX_POINT_SET ) {
-        if ( theReverse  && theMode == VTK_SURFACE ) {
-          //myPreviewActor->GetProperty()->SetColor( myRGB[0], myRGB[1], myRGB[2] );
-        }
-      }
     }
 
 
@@ -311,8 +228,8 @@ namespace SMESH
     ~TElementSimulation()
     {
       if (FindVtkViewWindow(myApplication->activeViewManager(), myViewWindow)) {
-       myVTKViewWindow->RemoveActor(myPreviewActor);
-       myVTKViewWindow->RemoveActor(myFaceOrientation);
+        myVTKViewWindow->RemoveActor(myPreviewActor);
+        myVTKViewWindow->RemoveActor(myFaceOrientation);
       }
       myPreviewActor->Delete();
       myFaceOrientation->Delete();
@@ -356,8 +273,6 @@ static int LastPentahedronIds[] =  {1,2,0,4,5,3,3,4,5};
 static int FirstHexahedronIds[] = {0,1,2,3,4,5,6,7,0,1,2,3};
 static int LastHexahedronIds[] =  {1,2,3,0,5,6,7,4,4,5,6,7};
 
-
-
 /*!
   \class BusyLocker
   \brief Simple 'busy state' flag locker.
@@ -411,11 +326,12 @@ QWidget* IdEditItem::createEditor() const
 // purpose  : constructor
 //=================================================================================
 SMESHGUI_AddQuadraticElementDlg::SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theModule,
-                                                                 const int theType )
+                                                                  const SMDSAbs_EntityType theType )
   : QDialog( SMESH::GetDesktop( theModule ) ),
     mySMESHGUI( theModule ),
     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
-    myType( theType ),
+    myGeomType( theType ),
+    //myType( theType ),
     myBusy( false )
 {
   setModal( false );
@@ -423,36 +339,42 @@ SMESHGUI_AddQuadraticElementDlg::SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theM
 
   SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>
     (SUIT_Session::session()->activeApplication());
-  
+
   mySimulation = new SMESH::TElementSimulation (anApp);
   mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
 
   QString anElementName;
 
-  switch ( myType ) {
-  case QUAD_EDGE:
+  switch ( myGeomType ) {
+  case SMDSEntity_Quad_Edge:
     anElementName = QString("QUADRATIC_EDGE");
     break;
-  case QUAD_TRIANGLE:
+  case SMDSEntity_Quad_Triangle:
     anElementName = QString("QUADRATIC_TRIANGLE");
-    break; 
-  case QUAD_QUADRANGLE:
+    break;
+  case SMDSEntity_Quad_Quadrangle:
     anElementName = QString("QUADRATIC_QUADRANGLE");
     break;
-  case QUAD_TETRAHEDRON:
+  case SMDSEntity_BiQuad_Quadrangle:
+    anElementName = QString("BIQUADRATIC_QUADRANGLE");
+    break;
+  case SMDSEntity_Quad_Tetra:
     anElementName = QString("QUADRATIC_TETRAHEDRON");
     break;
-  case QUAD_PYRAMID:
+  case SMDSEntity_Quad_Pyramid:
     anElementName = QString("QUADRATIC_PYRAMID");
     break;
-  case QUAD_PENTAHEDRON:
+  case SMDSEntity_Quad_Penta:
     anElementName = QString("QUADRATIC_PENTAHEDRON");
     break;
-  case QUAD_HEXAHEDRON:
+  case SMDSEntity_Quad_Hexa:
     anElementName = QString("QUADRATIC_HEXAHEDRON");
     break;
+  case SMDSEntity_TriQuad_Hexa:
+    anElementName = QString("TRIQUADRATIC_HEXAHEDRON");
+    break;
   default:
-    myType = QUAD_EDGE;
+    myGeomType = SMDSEntity_Quad_Edge;
     anElementName = QString("QUADRATIC_EDGE");
   }
 
@@ -460,12 +382,12 @@ SMESHGUI_AddQuadraticElementDlg::SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theM
   QString caption            = tr(QString("SMESH_ADD_%1_TITLE").arg(anElementName).toLatin1().data());
   QString argumentsGrTitle   = tr(QString("SMESH_ADD_%1").arg(anElementName).toLatin1().data());
   QString constructorGrTitle = tr(QString("SMESH_%1").arg(anElementName).toLatin1().data());
-  
+
   QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", iconName));
   QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
 
   setWindowTitle(caption);
-  
+
   setSizeGripEnabled(true);
 
   QVBoxLayout* aDialogLayout = new QVBoxLayout(this);
@@ -490,21 +412,58 @@ SMESHGUI_AddQuadraticElementDlg::SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theM
   aGroupArgumentsLayout->setSpacing(SPACING);
   aGroupArgumentsLayout->setMargin(MARGIN);
 
+  // Corner nodes
   QLabel* aCornerNodesLabel = new QLabel(tr("SMESH_CORNER_NODES"), GroupArguments);
-  mySelectButton = new QPushButton(GroupArguments);
-  mySelectButton->setIcon(image1);
+  myCornerSelectButton = new QPushButton(GroupArguments);
+  myCornerSelectButton->setIcon(image1);
   myCornerNodes = new QLineEdit(GroupArguments);
 
+  // Mid-edge nodes
   myTable = new QTableWidget(GroupArguments);
 
+  // Mid-face nodes
+  myMidFaceLabel = new QLabel(tr("SMESH_MIDFACE_NODES"), GroupArguments);
+  myMidFaceSelectButton = new QPushButton(GroupArguments);
+  myMidFaceSelectButton->setIcon(image1);
+  myMidFaceNodes = new QLineEdit(GroupArguments);
+  myMidFaceNodes->setValidator(new SMESHGUI_IdValidator(this, 6));
+
+  // Central node
+  myCenterLabel = new QLabel(tr("SMESH_CENTER_NODE"), GroupArguments);
+  myCenterSelectButton = new QPushButton(GroupArguments);
+  myCenterSelectButton->setIcon(image1);
+  myCenterNode = new QLineEdit(GroupArguments);
+  myCenterNode->setValidator(new SMESHGUI_IdValidator(this, 1));
+
   myReverseCB = new QCheckBox(tr("SMESH_REVERSE"), GroupArguments);
 
-  aGroupArgumentsLayout->addWidget(aCornerNodesLabel, 0, 0);
-  aGroupArgumentsLayout->addWidget(mySelectButton,    0, 1);
-  aGroupArgumentsLayout->addWidget(myCornerNodes,     0, 2);
-  aGroupArgumentsLayout->addWidget(myTable,           1, 0, 1, 3); 
-  aGroupArgumentsLayout->addWidget(myReverseCB,       2, 0, 1, 3);
-  
+  aGroupArgumentsLayout->addWidget(aCornerNodesLabel,     0, 0);
+  aGroupArgumentsLayout->addWidget(myCornerSelectButton,  0, 1);
+  aGroupArgumentsLayout->addWidget(myCornerNodes,         0, 2);
+  aGroupArgumentsLayout->addWidget(myTable,               1, 0, 1, 3);
+  aGroupArgumentsLayout->addWidget(myMidFaceLabel,        2, 0);
+  aGroupArgumentsLayout->addWidget(myMidFaceSelectButton, 2, 1);
+  aGroupArgumentsLayout->addWidget(myMidFaceNodes,        2, 2);
+  aGroupArgumentsLayout->addWidget(myCenterLabel,         3, 0);
+  aGroupArgumentsLayout->addWidget(myCenterSelectButton,  3, 1);
+  aGroupArgumentsLayout->addWidget(myCenterNode,          3, 2);
+  aGroupArgumentsLayout->addWidget(myReverseCB,           4, 0, 1, 3);
+
+    /***************************************************************/
+  GroupGroups = new QGroupBox( tr( "SMESH_ADD_TO_GROUP" ), this );
+  GroupGroups->setCheckable( true );
+  QHBoxLayout* GroupGroupsLayout = new QHBoxLayout(GroupGroups);
+  GroupGroupsLayout->setSpacing(SPACING);
+  GroupGroupsLayout->setMargin(MARGIN);
+
+  TextLabel_GroupName = new QLabel( tr( "SMESH_GROUP" ), GroupGroups );
+  ComboBox_GroupName = new QComboBox( GroupGroups );
+  ComboBox_GroupName->setEditable( true );
+  ComboBox_GroupName->setInsertPolicy( QComboBox::NoInsert );
+
+  GroupGroupsLayout->addWidget( TextLabel_GroupName );
+  GroupGroupsLayout->addWidget( ComboBox_GroupName, 1 );
+
   /***************************************************************/
   GroupButtons = new QGroupBox(this);
   QHBoxLayout* aGroupButtonsLayout = new QHBoxLayout(GroupButtons);
@@ -532,6 +491,7 @@ SMESHGUI_AddQuadraticElementDlg::SMESHGUI_AddQuadraticElementDlg( SMESHGUI* theM
   /***************************************************************/
   aDialogLayout->addWidget(GroupConstructors);
   aDialogLayout->addWidget(GroupArguments);
+  aDialogLayout->addWidget(GroupGroups);
   aDialogLayout->addWidget(GroupButtons);
 
   Init(); /* Initialisations */
@@ -554,49 +514,74 @@ void SMESHGUI_AddQuadraticElementDlg::Init()
 {
   myRadioButton1->setChecked(true);
   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
-  
+
+  /* reset "Add to group" control */
+  GroupGroups->setChecked( false );
+
   myActor = 0;
+  myNbMidFaceNodes = 0;
+  myNbCenterNodes = 0;
 
   int aNumRows;
 
-  switch (myType) {
-  case QUAD_EDGE:
+  switch (myGeomType) {
+  case SMDSEntity_Quad_Edge:
     aNumRows = 1;
     myNbCorners = 2;
     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_edges
     break;
-  case QUAD_TRIANGLE:
+  case SMDSEntity_Quad_Triangle:
     aNumRows = 3;
     myNbCorners = 3;
     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_triangles
     break;
-  case QUAD_QUADRANGLE:
+  case SMDSEntity_Quad_Quadrangle:
+    aNumRows = 4;
+    myNbCorners = 4;
+    myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_quadrangles
+    break;
+  case SMDSEntity_BiQuad_Quadrangle:
     aNumRows = 4;
     myNbCorners = 4;
+    myNbCenterNodes = 1;
     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_quadrangles
     break;
-  case QUAD_TETRAHEDRON:
+  case SMDSEntity_Quad_Tetra:
     aNumRows = 6;
     myNbCorners = 4;
     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_tetrahedrons
     break;
-  case QUAD_PYRAMID:
+  case SMDSEntity_Quad_Pyramid:
     aNumRows = 8;
     myNbCorners = 5;
     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_pyramids
     break;
-  case QUAD_PENTAHEDRON:
+  case SMDSEntity_Quad_Penta:
     aNumRows = 9;
     myNbCorners = 6;
     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_pentahedrons
-    break; 
-  case QUAD_HEXAHEDRON:
+    break;
+  case SMDSEntity_Quad_Hexa:
+    aNumRows = 12;
+    myNbCorners = 8;
+    myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_hexahedrons
+    break;
+  case SMDSEntity_TriQuad_Hexa:
     aNumRows = 12;
     myNbCorners = 8;
+    myNbMidFaceNodes = 6;
+    myNbCenterNodes = 1;
     myHelpFileName = "adding_quadratic_elements_page.html#?"; //Adding_hexahedrons
     break;
   }
-    
+
+  myMidFaceLabel       ->setVisible( myNbMidFaceNodes );
+  myMidFaceSelectButton->setVisible( myNbMidFaceNodes );
+  myMidFaceNodes       ->setVisible( myNbMidFaceNodes );
+  myCenterLabel        ->setVisible( myNbCenterNodes );
+  myCenterSelectButton ->setVisible( myNbCenterNodes );
+  myCenterNode         ->setVisible( myNbCenterNodes );
+
   myCornerNodes->setValidator(new SMESHGUI_IdValidator(this, myNbCorners));
 
   /* initialize table */
@@ -608,7 +593,7 @@ void SMESHGUI_AddQuadraticElementDlg::Init()
   aColLabels.append(tr("SMESH_MIDDLE"));
   aColLabels.append(tr("SMESH_LAST"));
   myTable->setHorizontalHeaderLabels(aColLabels);
-  
+
   for ( int col = 0; col < myTable->columnCount(); col++ )
     myTable->setColumnWidth(col, 80);
 
@@ -616,7 +601,7 @@ void SMESHGUI_AddQuadraticElementDlg::Init()
   //myTable->setColumnReadOnly(2, true); // VSR: TODO
 
   myTable->setEnabled( false );
-  
+
   for ( int row = 0; row < myTable->rowCount(); row++ )
   {
     myTable->setItem( row, 0, new QTableWidgetItem( "" ) );
@@ -629,13 +614,17 @@ void SMESHGUI_AddQuadraticElementDlg::Init()
     myTable->setItem( row, 2, new QTableWidgetItem( "" ) );
     myTable->item( row, 2 )->setFlags(0);
   }
-  
+
   /* signals and slots connections */
-  connect(mySelectButton, SIGNAL(clicked()), SLOT(SetEditCorners()));
+  connect(myCornerSelectButton, SIGNAL(clicked()), SLOT(SetCurrentSelection()));
+  connect(myMidFaceSelectButton, SIGNAL(clicked()), SLOT(SetCurrentSelection()));
+  connect(myCenterSelectButton, SIGNAL(clicked()), SLOT(SetCurrentSelection()));
   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(SelectionIntoArgument()));
   connect(myTable,        SIGNAL(cellDoubleClicked(int, int)), SLOT(onCellDoubleClicked(int, int)));
   connect(myTable,        SIGNAL(cellChanged (int, int)), SLOT(onCellTextChange(int, int)));
   connect(myCornerNodes,  SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
+  connect(myMidFaceNodes, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
+  connect(myCenterNode,  SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
   connect(myReverseCB,    SIGNAL(stateChanged(int)), SLOT(onReverse(int)));
 
   connect(buttonOk, SIGNAL(clicked()),     SLOT(ClickOnOk()));
@@ -645,6 +634,9 @@ void SMESHGUI_AddQuadraticElementDlg::Init()
 
   connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), SLOT(DeactivateActiveDialog()));
   connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), SLOT(ClickOnCancel()));
+  connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), SLOT(ClickOnCancel()));
+
+  myCurrentLineEdit = myCornerNodes;
 
   // set selection mode
   SMESH::SetPointRepresentation(true);
@@ -652,7 +644,7 @@ void SMESHGUI_AddQuadraticElementDlg::Init()
   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
     aViewWindow->SetSelectionMode( NodeSelection );
 
-  SetEditCorners();
+  SelectionIntoArgument();
 }
 
 //=================================================================================
@@ -661,6 +653,9 @@ void SMESHGUI_AddQuadraticElementDlg::Init()
 //=================================================================================
 void SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
 {
+  if( !isValid() )
+    return;
+
   if ( mySMESHGUI->isActiveStudyLocked() || myBusy || !IsValid() )
     return;
 
@@ -668,59 +663,137 @@ void SMESHGUI_AddQuadraticElementDlg::ClickOnApply()
 
   std::vector<vtkIdType> anIds;
 
-  switch (myType) {
-  case QUAD_EDGE:
+  switch (myGeomType) {
+  case SMDSEntity_Quad_Edge:
     anIds.push_back(myTable->item(0, 0)->text().toInt());
     anIds.push_back(myTable->item(0, 2)->text().toInt());
     anIds.push_back(myTable->item(0, 1)->text().toInt());
     break;
-  case QUAD_TRIANGLE:
-  case QUAD_QUADRANGLE:
-  case QUAD_TETRAHEDRON:
-  case QUAD_PYRAMID:
-  case QUAD_PENTAHEDRON:
-  case QUAD_HEXAHEDRON:
+  case SMDSEntity_Quad_Triangle:
+  case SMDSEntity_Quad_Quadrangle:
+  case SMDSEntity_BiQuad_Quadrangle:
+  case SMDSEntity_Quad_Tetra:
+  case SMDSEntity_Quad_Pyramid:
+  case SMDSEntity_Quad_Penta:
+  case SMDSEntity_Quad_Hexa:
+  case SMDSEntity_TriQuad_Hexa:
     for ( int row = 0; row < myNbCorners; row++ )
       anIds.push_back(myTable->item(row, 0)->text().toInt());
     for ( int row = 0; row < myTable->rowCount(); row++ )
       anIds.push_back(myTable->item(row, 1)->text().toInt());
+    if ( myNbMidFaceNodes )
+    {
+      QStringList aListId = myMidFaceNodes->text().split(" ", QString::SkipEmptyParts);
+      for (int i = 0; i < aListId.count(); i++)
+        anIds.push_back( aListId[ i ].toInt() );
+    }
+    if ( myNbCenterNodes )
+    {
+      QStringList aListId = myCenterNode->text().split(" ", QString::SkipEmptyParts);
+      anIds.push_back( aListId[ 0 ].toInt() );
+    }
     break;
   }
   if ( myReverseCB->isChecked())
-    SMESH::ReverseConnectivity( anIds, myType );
-    
+    ReverseConnectivity( anIds, myGeomType, /*toReverse=*/true, /*toVtkOrder=*/false );
+
   int aNumberOfIds =  anIds.size();
   SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array;
   anArrayOfIdeces->length( aNumberOfIds );
-    
+
   for (int i = 0; i < aNumberOfIds; i++)
     anArrayOfIdeces[i] = anIds[ i ];
 
+  bool addToGroup = GroupGroups->isChecked();
+  QString aGroupName;
+
+  SMESH::SMESH_GroupBase_var aGroup;
+  int idx = 0;
+  if( addToGroup ) {
+    aGroupName = ComboBox_GroupName->currentText();
+    for ( int i = 1; i < ComboBox_GroupName->count(); i++ ) {
+      QString aName = ComboBox_GroupName->itemText( i );
+      if ( aGroupName == aName && ( i == ComboBox_GroupName->currentIndex() || idx == 0 ) )
+        idx = i;
+    }
+    if ( idx > 0 && idx < myGroups.count() ) {
+      SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( myGroups[idx-1] );
+      if ( !aGeomGroup->_is_nil() ) {
+        int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ),
+                                             tr( "MESH_STANDALONE_GRP_CHOSEN" ).arg( aGroupName ),
+                                             tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
+        if ( res == 1 ) return;
+      }
+      aGroup = myGroups[idx-1];
+    }
+  }
+
+  SMESH::ElementType anElementType;
+  long anElemId = -1;
   SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
-  switch (myType) {
-  case QUAD_EDGE:
-    aMeshEditor->AddEdge(anArrayOfIdeces.inout()); break;
-  case QUAD_TRIANGLE:
-  case QUAD_QUADRANGLE:
-    aMeshEditor->AddFace(anArrayOfIdeces.inout()); break;
-  case QUAD_TETRAHEDRON:
-  case QUAD_PYRAMID:
-  case QUAD_PENTAHEDRON: 
-  case QUAD_HEXAHEDRON:
-    aMeshEditor->AddVolume(anArrayOfIdeces.inout()); break;
+  switch (myGeomType) {
+  case SMDSEntity_Quad_Edge:
+    anElementType = SMESH::EDGE;
+    anElemId = aMeshEditor->AddEdge(anArrayOfIdeces.inout()); break;
+  case SMDSEntity_Quad_Triangle:
+  case SMDSEntity_Quad_Quadrangle:
+  case SMDSEntity_BiQuad_Quadrangle:
+    anElementType = SMESH::FACE;
+    anElemId = aMeshEditor->AddFace(anArrayOfIdeces.inout()); break;
+  case SMDSEntity_Quad_Tetra:
+  case SMDSEntity_Quad_Pyramid:
+  case SMDSEntity_Quad_Penta:
+  case SMDSEntity_Quad_Hexa:
+  case SMDSEntity_TriQuad_Hexa:
+    anElementType = SMESH::VOLUME;
+    anElemId = aMeshEditor->AddVolume(anArrayOfIdeces.inout()); break;
+  default: break;
+  }
+
+  if ( anElemId != -1 && addToGroup && !aGroupName.isEmpty() ) {
+    SMESH::SMESH_Group_var aGroupUsed;
+    if ( aGroup->_is_nil() ) {
+      // create new group
+      aGroupUsed = SMESH::AddGroup( myMesh, anElementType, aGroupName );
+      if ( !aGroupUsed->_is_nil() ) {
+        myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroupUsed));
+        ComboBox_GroupName->addItem( aGroupName );
+      }
+    }
+    else {
+      SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup );
+      if ( !aGeomGroup->_is_nil() ) {
+        aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup );
+        if ( !aGroupUsed->_is_nil() && idx > 0 ) {
+          myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed);
+          SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser();
+        }
+      }
+      else
+        aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup );
+    }
+
+    if ( !aGroupUsed->_is_nil() ) {
+      SMESH::long_array_var anIdList = new SMESH::long_array;
+      anIdList->length( 1 );
+      anIdList[0] = anElemId;
+      aGroupUsed->Add( anIdList.inout() );
+    }
   }
-    
+
   SALOME_ListIO aList; aList.Append( myActor->getIO() );
   mySelector->ClearIndex();
   mySelectionMgr->setSelectedObjects( aList, false );
 
   mySimulation->SetVisibility(false);
   SMESH::UpdateView();
-    
+
   UpdateTable();
-  SetEditCorners();
+  SetCurrentSelection();
 
   updateButtons();
+
+  SMESHGUI::Modified();
 }
 
 //=================================================================================
@@ -756,7 +829,7 @@ void SMESHGUI_AddQuadraticElementDlg::ClickOnCancel()
 void SMESHGUI_AddQuadraticElementDlg::ClickOnHelp()
 {
   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
-  if (app) 
+  if (app)
     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
   else {
     QString platform;
@@ -766,10 +839,10 @@ void SMESHGUI_AddQuadraticElementDlg::ClickOnHelp()
     platform = "application";
 #endif
     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser", 
-                                                                platform)).
-                            arg(myHelpFileName));
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser",
+                                                                 platform)).
+                             arg(myHelpFileName));
   }
 }
 
@@ -781,7 +854,7 @@ void SMESHGUI_AddQuadraticElementDlg::onTextChange (const QString& theNewText)
 {
   if (myBusy) return;
   BusyLocker lock( myBusy );
-  
+
   mySimulation->SetVisibility(false);
 
   // hilight entered nodes
@@ -789,31 +862,37 @@ void SMESHGUI_AddQuadraticElementDlg::onTextChange (const QString& theNewText)
   if (myActor)
     aMesh = myActor->GetObject()->GetMesh();
 
+  QLineEdit* send = (QLineEdit*)sender();
+  if (send == myCornerNodes ||
+      send == myMidFaceNodes ||
+      send == myCenterNode)
+    myCurrentLineEdit = send;
+
   if (aMesh) {
     TColStd_MapOfInteger newIndices;
-    
+
     QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
     bool allOk = true;
     for (int i = 0; i < aListId.count(); i++) {
       if ( const SMDS_MeshNode * n = aMesh->FindNode( aListId[ i ].toInt() ) )
       {
-       newIndices.Add( n->GetID() );
+        newIndices.Add( n->GetID() );
       }
       else
       {
-       allOk = false;
-       break;
+        allOk = false;
+        break;
       }
     }
-    
+
     mySelector->AddOrRemoveIndex( myActor->getIO(), newIndices, false );
     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
       aViewWindow->highlight( myActor->getIO(), true, true );
-    
-    if ( sender() == myCornerNodes )
+
+    if ( myCurrentLineEdit == myCornerNodes )
       UpdateTable( allOk );
   }
-  
+
   updateButtons();
   displaySimulation();
 }
@@ -826,55 +905,93 @@ void SMESHGUI_AddQuadraticElementDlg::SelectionIntoArgument()
 {
   if (myBusy) return;
   BusyLocker lock( myBusy );
-  
-  if ( myIsEditCorners )
+
+  QString aCurrentEntry = myEntry;
+
+  if ( myCurrentLineEdit )
   {
     // clear
     myActor = 0;
-    
-    myCornerNodes->setText("");
-    
+
+    myCurrentLineEdit->setText("");
+
     if (!GroupButtons->isEnabled()) // inactive
       return;
-    
+
     mySimulation->SetVisibility(false);
-      
+
     // get selected mesh
     SALOME_ListIO aList;
     mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
-    
+
     if (aList.Extent() != 1)
     {
       UpdateTable();
       updateButtons();
       return;
     }
-      
+
     Handle(SALOME_InteractiveObject) anIO = aList.First();
+    myEntry = anIO->getEntry();
     myMesh = SMESH::GetMeshByIO(anIO);
     if (myMesh->_is_nil()) {
       updateButtons();
       return;
     }
-      
+
     myActor = SMESH::FindActorByEntry(anIO->getEntry());
-  
+
   }
-  
+
+  // process groups
+  if ( !myMesh->_is_nil() && myEntry != aCurrentEntry ) {
+    SMESH::ElementType anElementType;
+    switch ( myGeomType ) {
+    case SMDSEntity_Quad_Edge:
+      anElementType = SMESH::EDGE; break;
+    case SMDSEntity_Quad_Triangle:
+    case SMDSEntity_Quad_Quadrangle:
+    case SMDSEntity_BiQuad_Quadrangle:
+      anElementType = SMESH::FACE; break;
+    case SMDSEntity_Quad_Tetra:
+    case SMDSEntity_Quad_Pyramid:
+    case SMDSEntity_Quad_Penta:
+    case SMDSEntity_Quad_Hexa:
+    case SMDSEntity_TriQuad_Hexa:
+      anElementType = SMESH::VOLUME; break;
+    }
+    myGroups.clear();
+    ComboBox_GroupName->clear();
+    ComboBox_GroupName->addItem( QString() );
+    SMESH::ListOfGroups aListOfGroups = *myMesh->GetGroups();
+    for ( int i = 0, n = aListOfGroups.length(); i < n; i++ ) {
+      SMESH::SMESH_GroupBase_var aGroup = aListOfGroups[i];
+      if ( !aGroup->_is_nil() && aGroup->GetType() == anElementType ) {
+        QString aGroupName( aGroup->GetName() );
+        if ( !aGroupName.isEmpty() ) {
+          myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup));
+          ComboBox_GroupName->addItem( aGroupName );
+        }
+      }
+    }
+  }
+
   if (!myActor) {
     updateButtons();
     return;
   }
-  
+
   // get selected nodes
   QString aString = "";
   int nbNodes = SMESH::GetNameOfSelectedNodes(mySelector,myActor->getIO(),aString);
-  
-  if ( myIsEditCorners )
+
+  if ( myCurrentLineEdit )
   {
-    myCornerNodes->setText(aString);
-    
-    UpdateTable();
+    if ( myCurrentLineEdit != myCenterNode || nbNodes == 1 )
+      myCurrentLineEdit->setText(aString);
+
+    if ( myCurrentLineEdit == myCornerNodes )
+      UpdateTable();
   }
   else if ( myTable->isEnabled() && nbNodes == 1 )
   {
@@ -882,7 +999,7 @@ void SMESHGUI_AddQuadraticElementDlg::SelectionIntoArgument()
     if ( theCol == 1 )
       myTable->item(theRow, 1)->setText(aString);
   }
-  
+
   updateButtons();
   displaySimulation();
 }
@@ -896,13 +1013,13 @@ void SMESHGUI_AddQuadraticElementDlg::displaySimulation()
   if ( IsValid() )
   {
     SMESH::TElementSimulation::TVTKIds anIds;
-    
+
     // Collect ids from the dialog
     int anID;
     bool ok;
     int aDisplayMode = VTK_SURFACE;
-    
-    if ( myType == QUAD_EDGE )
+
+    if ( myGeomType == SMDSEntity_Quad_Edge )
     {
       anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(0, 0)->text().toInt() ) );
       anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(0, 2)->text().toInt() ) );
@@ -914,20 +1031,31 @@ void SMESHGUI_AddQuadraticElementDlg::displaySimulation()
     else
     {
       for ( int row = 0; row < myNbCorners; row++ )
-       anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(row, 0)->text().toInt() ) );
-      
+        anIds.push_back( myActor->GetObject()->GetNodeVTKId( myTable->item(row, 0)->text().toInt() ) );
+
       for ( int row = 0; row < myTable->rowCount(); row++ )
       {
-       anID = myTable->item(row, 1)->text().toInt(&ok);
-       if (!ok) {
-         anID = myTable->item(row, 0)->text().toInt();
-         aDisplayMode = VTK_WIREFRAME;
-       }
-       anIds.push_back( myActor->GetObject()->GetNodeVTKId(anID) );
+        anID = myTable->item(row, 1)->text().toInt(&ok);
+        if (!ok) {
+          anID = myTable->item(row, 0)->text().toInt();
+          aDisplayMode = VTK_WIREFRAME;
+        }
+        anIds.push_back( myActor->GetObject()->GetNodeVTKId(anID) );
+      }
+      if ( myNbMidFaceNodes )
+      {
+        QStringList aListId = myMidFaceNodes->text().split(" ", QString::SkipEmptyParts);
+        for (int i = 0; i < aListId.count(); i++)
+          anIds.push_back( myActor->GetObject()->GetNodeVTKId( aListId[ i ].toInt() ));
+      }
+      if ( myNbCenterNodes )
+      {
+        QStringList aListId = myCenterNode->text().split(" ", QString::SkipEmptyParts);
+        anIds.push_back( myActor->GetObject()->GetNodeVTKId( aListId[ 0 ].toInt() ));
       }
     }
-    
-    mySimulation->SetPosition(myActor,myType,anIds,aDisplayMode,myReverseCB->isChecked());
+
+    mySimulation->SetPosition(myActor,myGeomType,anIds,aDisplayMode,myReverseCB->isChecked());
   }
   else
   {
@@ -937,15 +1065,26 @@ void SMESHGUI_AddQuadraticElementDlg::displaySimulation()
 }
 
 //=================================================================================
-// function : SetEditCorners()
+// function : SetCurrentSelection()
 // purpose  :
 //=================================================================================
-void SMESHGUI_AddQuadraticElementDlg::SetEditCorners()
+void SMESHGUI_AddQuadraticElementDlg::SetCurrentSelection()
 {
-  myCornerNodes->setFocus();
-  myIsEditCorners = true;
-  SelectionIntoArgument();
-  updateButtons();
+  QPushButton* send = (QPushButton*)sender();
+  myCurrentLineEdit = 0;
+
+  if (send == myCornerSelectButton)
+    myCurrentLineEdit = myCornerNodes;
+  else if ( send == myMidFaceSelectButton )
+    myCurrentLineEdit = myMidFaceNodes;
+  else if ( send == myCenterSelectButton )
+    myCurrentLineEdit = myCenterNode;
+
+  if ( myCurrentLineEdit )
+  {
+    myCurrentLineEdit->setFocus();
+    SelectionIntoArgument();
+  }
 }
 
 //=================================================================================
@@ -1040,19 +1179,37 @@ bool SMESHGUI_AddQuadraticElementDlg::IsValid()
     return false;
 
   bool ok;
-  
+  std::set< int > okIDs;
   for ( int row = 0; row < myTable->rowCount(); row++ )
   {
     int anID =  myTable->item(row, 1)->text().toInt(&ok);
     if ( !ok )
       return false;
-    
+
     const SMDS_MeshNode * aNode = aMesh->FindNode(anID);
     if ( !aNode )
       return false;
+    okIDs.insert( anID );
   }
-  
-  return true;
+
+  QStringList aListId;
+  if ( myNbMidFaceNodes )
+    aListId += myMidFaceNodes->text().split(" ", QString::SkipEmptyParts);
+  if ( myNbCenterNodes )
+    aListId += myCenterNode->text().split(" ", QString::SkipEmptyParts);
+
+  for (int i = 0; i < aListId.count(); i++)
+  {
+    int anID = aListId[ i ].toInt(&ok);
+    if ( !ok )
+      return false;
+
+    if ( !aMesh->FindNode(anID) )
+      return false;
+    okIDs.insert( anID );
+  }
+
+  return okIDs.size() == myTable->rowCount() + myNbMidFaceNodes + myNbCenterNodes;
 }
 
 //=================================================================================
@@ -1062,53 +1219,55 @@ bool SMESHGUI_AddQuadraticElementDlg::IsValid()
 void SMESHGUI_AddQuadraticElementDlg::UpdateTable( bool theConersValidity )
 {
   QStringList aListCorners = myCornerNodes->text().split(" ", QString::SkipEmptyParts);
-  
+
   if ( aListCorners.count() == myNbCorners && theConersValidity )
   {
     myTable->setEnabled( true );
-    
-    // clear the Middle column 
+
+    // clear the Middle column
     for ( int row = 0; row < myTable->rowCount(); row++ )
       myTable->item( row, 1 )->setText("");
-    
+
     int* aFirstColIds;
     int* aLastColIds;
-    
-    switch (myType) {
-    case QUAD_EDGE:
+
+    switch (myGeomType) {
+    case SMDSEntity_Quad_Edge:
       aFirstColIds = FirstEdgeIds;
       aLastColIds  = LastEdgeIds;
       break;
-    case QUAD_TRIANGLE:
+    case SMDSEntity_Quad_Triangle:
       aFirstColIds = FirstTriangleIds;
       aLastColIds  = LastTriangleIds;
       break;
-    case QUAD_QUADRANGLE:
+    case SMDSEntity_Quad_Quadrangle:
+    case SMDSEntity_BiQuad_Quadrangle:
       aFirstColIds = FirstQuadrangleIds;
       aLastColIds  = LastQuadrangleIds;
       break;
-    case QUAD_TETRAHEDRON:
+    case SMDSEntity_Quad_Tetra:
       aFirstColIds = FirstTetrahedronIds;
       aLastColIds  = LastTetrahedronIds;
       break;
-    case QUAD_PYRAMID:
+    case SMDSEntity_Quad_Pyramid:
       aFirstColIds = FirstPyramidIds;
       aLastColIds  = LastPyramidIds;
       break;
-    case QUAD_PENTAHEDRON:
+    case SMDSEntity_Quad_Penta:
       aFirstColIds = FirstPentahedronIds;
       aLastColIds  = LastPentahedronIds;
-      break; 
-    case QUAD_HEXAHEDRON:
+      break;
+    case SMDSEntity_Quad_Hexa:
+    case SMDSEntity_TriQuad_Hexa:
       aFirstColIds = FirstHexahedronIds;
       aLastColIds  = LastHexahedronIds;
       break;
     }
-    
+
     // fill the First and the Last columns
     for (int i = 0, iEnd = myTable->rowCount(); i < iEnd; i++)
       myTable->item( i, 0 )->setText( aListCorners[ aFirstColIds[i] ] );
-    
+
     for (int i = 0, iEnd = myTable->rowCount(); i < iEnd; i++)
       myTable->item( i, 2 )->setText( aListCorners[ aLastColIds[i] ] );
   }
@@ -1117,8 +1276,8 @@ void SMESHGUI_AddQuadraticElementDlg::UpdateTable( bool theConersValidity )
     // clear table
     for ( int row = 0; row < myTable->rowCount(); row++ )
       for ( int col = 0; col < myTable->columnCount(); col++ )
-       if ( QTableWidgetItem* aTWI = myTable->item(row, col) ) aTWI->setText("");
-    
+        if ( QTableWidgetItem* aTWI = myTable->item(row, col) ) aTWI->setText("");
+
     myTable->setEnabled( false );
   }
 }
@@ -1130,7 +1289,7 @@ void SMESHGUI_AddQuadraticElementDlg::UpdateTable( bool theConersValidity )
 //=================================================================================
 void SMESHGUI_AddQuadraticElementDlg::onCellDoubleClicked( int theRow, int theCol )
 {
-  myIsEditCorners = false;
+  myCurrentLineEdit = 0;
   displaySimulation();
   updateButtons();
 }
@@ -1142,7 +1301,7 @@ void SMESHGUI_AddQuadraticElementDlg::onCellDoubleClicked( int theRow, int theCo
 //=================================================================================
 void SMESHGUI_AddQuadraticElementDlg::onCellTextChange(int theRow, int theCol)
 {
-  myIsEditCorners = false;
+  myCurrentLineEdit = 0;
   displaySimulation();
   updateButtons();
 }
@@ -1169,3 +1328,16 @@ void SMESHGUI_AddQuadraticElementDlg::updateButtons()
   buttonOk->setEnabled( valid );
   buttonApply->setEnabled( valid );
 }
+
+//=================================================================================
+// function : isValid
+// purpose  :
+//=================================================================================
+bool SMESHGUI_AddQuadraticElementDlg::isValid()
+{
+  if( GroupGroups->isChecked() && ComboBox_GroupName->currentText().isEmpty() ) {
+    SUIT_MessageBox::warning( this, tr( "SMESH_WRN_WARNING" ), tr( "GROUP_NAME_IS_EMPTY" ) );
+    return false;
+  }
+  return true;
+}
index a048a6760baaf5f62b84c464455b21d4aa1decf4..3b2c360b26f6bcf5dcdb889a6cad339b47b321b9 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_AddMeshElementDlg.h
 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
@@ -28,6 +29,7 @@
 
 // SMESH includes
 #include "SMESH_SMESHGUI.hxx"
+#include "SMDSAbs_ElementType.hxx"
 
 // Qt includes
 #include <QDialog>
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Mesh)
 
+class QComboBox;
+class QFrame;
 class QGroupBox;
+class QLabel;
 class QLineEdit;
 class QPushButton;
 class QRadioButton;
@@ -52,9 +57,6 @@ namespace SMESH
   struct TElementSimulation;
 }
 
-enum { QUAD_EDGE, QUAD_TRIANGLE, QUAD_QUADRANGLE, QUAD_TETRAHEDRON, 
-       QUAD_PYRAMID, QUAD_PENTAHEDRON, QUAD_HEXAHEDRON };
-
 //=================================================================================
 // class    : SMESHGUI_AddQuadraticElementDlg
 // purpose  :
@@ -64,10 +66,12 @@ class SMESHGUI_EXPORT SMESHGUI_AddQuadraticElementDlg : public QDialog
   Q_OBJECT
 
 public:
-  SMESHGUI_AddQuadraticElementDlg( SMESHGUI*, const int );
+  SMESHGUI_AddQuadraticElementDlg( SMESHGUI*, const SMDSAbs_EntityType );
   ~SMESHGUI_AddQuadraticElementDlg();
   
 private:
+  typedef QList<SMESH::SMESH_GroupBase_var> GrpList;
+
   void                        Init();
   void                        closeEvent( QCloseEvent* );
   void                        hideEvent( QHideEvent* );    /* ESC key */
@@ -78,28 +82,44 @@ private:
   bool                        IsValid();
   void                        updateButtons();
 
+  bool                        isValid();
+  
   SMESHGUI*                   mySMESHGUI;       /* Current SMESHGUI object */
   LightApp_SelectionMgr*      mySelectionMgr;   /* User shape selection */
   int                         myNbCorners;      /* The required number of corners */
+  int                         myNbMidFaceNodes;
+  int                         myNbCenterNodes;
   bool                        myBusy;
   SVTK_Selector*              mySelector;
   
   SMESH::SMESH_Mesh_var       myMesh;
   SMESH_Actor*                myActor;
   SMESH::TElementSimulation*  mySimulation;
+  QString                     myEntry;
+  GrpList                     myGroups;
   
-  int                         myType;
-  bool                        myIsEditCorners;
+  SMDSAbs_EntityType          myGeomType;
+  QLineEdit*                  myCurrentLineEdit;
   
   QGroupBox*                  GroupConstructors;
   QRadioButton*               myRadioButton1;
   
   QGroupBox*                  GroupArguments;
+  QPushButton*                myCornerSelectButton;
   QLineEdit*                  myCornerNodes;
-  QPushButton*                mySelectButton;
+  QLabel*                     myMidFaceLabel;
+  QPushButton*                myMidFaceSelectButton;
+  QLineEdit*                  myMidFaceNodes;
+  QLabel*                     myCenterLabel;
+  QPushButton*                myCenterSelectButton;
+  QLineEdit*                  myCenterNode;
   QTableWidget*               myTable;
   QCheckBox*                  myReverseCB;
   
+  QGroupBox*                  GroupGroups;
+  QLabel*                     TextLabel_GroupName;
+  QComboBox*                  ComboBox_GroupName;
+
   QGroupBox*                  GroupButtons;
   QPushButton*                buttonOk;
   QPushButton*                buttonCancel;
@@ -118,7 +138,7 @@ private slots:
   void                        ClickOnCancel();
   void                        ClickOnApply();
   void                        ClickOnHelp();
-  void                        SetEditCorners();
+  void                        SetCurrentSelection();
   void                        SelectionIntoArgument();
   void                        DeactivateActiveDialog();
   void                        ActivateThisDialog();
index 2d6b7435bfb7dbc0b048ddf0f0a4495e9904e29a..edee4cecbda29c16d215f47a606bab0bdb28bf3e 100644 (file)
@@ -1,29 +1,28 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
-//
-// SMESH SMESHGUI : GUI for SMESH component
-// File   : SMESHGUI_BuildCompoundDlg.cxx
-// Author : Alexander KOVALEV, Open CASCADE S.A.S.
-// SMESH includes
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+//  File   : SMESHGUI_BuildCompoundDlg.cxx
+//  Author : Alexander KOVALEV, Open CASCADE S.A.S.
+//  SMESH includes
+
 #include "SMESHGUI_BuildCompoundDlg.h"
 
 #include "SMESHGUI.h"
 #define SPACING 6
 #define MARGIN  11
 
+//To disable automatic genericobj management, the following line should be commented.
+//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
+#define WITHGENERICOBJ
+
 //=================================================================================
 // name    : SMESHGUI_BuildCompoundDlg
 // Purpose :
@@ -73,7 +76,8 @@
 SMESHGUI_BuildCompoundDlg::SMESHGUI_BuildCompoundDlg( SMESHGUI* theModule )
   : QDialog(SMESH::GetDesktop(theModule)),
     mySMESHGUI(theModule),
-    mySelectionMgr(SMESH::GetSelectionMgr(theModule))
+    mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
+    myIsApplyAndClose( false )
 {
   setModal(false);
   setAttribute(Qt::WA_DeleteOnClose, true);
@@ -137,12 +141,12 @@ SMESHGUI_BuildCompoundDlg::SMESHGUI_BuildCompoundDlg( SMESHGUI* theModule )
   TextLabelTol = new QLabel(tr("SMESH_TOLERANCE"), GroupArgs);
   TextLabelTol->setAlignment(Qt::AlignCenter);
   SpinBoxTol = new SMESHGUI_SpinBox(GroupArgs);
-  SpinBoxTol->RangeStepAndValidator(0.0, COORD_MAX, 0.00001, 6);
+  SpinBoxTol->RangeStepAndValidator(0.0, COORD_MAX, 0.00001, "len_tol_precision" );
 
   GroupArgsLayout->addWidget(TextLabelMeshes, 0, 0);
   GroupArgsLayout->addWidget(SelectButton,    0, 1);
   GroupArgsLayout->addWidget(LineEditMeshes,  0, 2, 1, 2);
-  GroupArgsLayout->addWidget(TextLabelUnion,  1, 0, 1, 3); 
+  GroupArgsLayout->addWidget(TextLabelUnion,  1, 0, 1, 3);
   GroupArgsLayout->addWidget(ComboBoxUnion,   1, 3);
   GroupArgsLayout->addWidget(CheckBoxCommon,  2, 0, 1, 4);
   GroupArgsLayout->addWidget(CheckBoxMerge,   3, 0, 1, 4);
@@ -289,29 +293,37 @@ bool SMESHGUI_BuildCompoundDlg::ClickOnApply()
   if (!isValid())
     return false;
 
-  if (!myMesh->_is_nil()) {
+  SMESH::SMESH_Mesh_var aCompoundMesh;
+
+  if (!myMesh->_is_nil())
+  {
     QStringList aParameters;
     aParameters << (CheckBoxMerge->isChecked() ? SpinBoxTol->text() : QString(" "));
-    try        {
+
+    QStringList anEntryList;
+    try {
       SUIT_OverrideCursor aWaitCursor;
 
+      myMeshArray[0]->SetParameters( aParameters.join(":").toLatin1().constData() );
+
       SMESH::SMESH_Gen_var aSMESHGen = SMESHGUI::GetSMESHGen();
       // concatenate meshes
-      SMESH::SMESH_Mesh_var aCompoundMesh;
       if(CheckBoxCommon->isChecked())
-       aCompoundMesh = aSMESHGen->ConcatenateWithGroups(myMeshArray, 
-                                                        !(ComboBoxUnion->currentIndex()), 
-                                                        CheckBoxMerge->isChecked(), 
-                                                        SpinBoxTol->GetValue());
+        aCompoundMesh = aSMESHGen->ConcatenateWithGroups(myMeshArray,
+                                                         !(ComboBoxUnion->currentIndex()),
+                                                         CheckBoxMerge->isChecked(),
+                                                         SpinBoxTol->GetValue());
       else
-       aCompoundMesh = aSMESHGen->Concatenate(myMeshArray, 
-                                              !(ComboBoxUnion->currentIndex()), 
-                                              CheckBoxMerge->isChecked(), 
-                                              SpinBoxTol->GetValue());
-     
-      aCompoundMesh->SetParameters( SMESHGUI::JoinObjectParameters(aParameters) );
-
-      SMESH::SetName( SMESH::FindSObject( aCompoundMesh ), LineEditName->text() );
+        aCompoundMesh = aSMESHGen->Concatenate(myMeshArray,
+                                               !(ComboBoxUnion->currentIndex()),
+                                               CheckBoxMerge->isChecked(),
+                                               SpinBoxTol->GetValue());
+
+      _PTR(SObject) aSO = SMESH::FindSObject( aCompoundMesh );
+      if( aSO ) {
+        SMESH::SetName( aSO, LineEditName->text() );
+        anEntryList.append( aSO->GetID().c_str() );
+      }
       mySMESHGUI->updateObjBrowser();
     } catch(...) {
       return false;
@@ -319,8 +331,30 @@ bool SMESHGUI_BuildCompoundDlg::ClickOnApply()
 
     LineEditName->setText(GetDefaultName(tr("COMPOUND_MESH")));
 
-    //mySelectionMgr->clearSelected();
-    SMESH::UpdateView();
+    // IPAL21468 Compound is hidden after creation.
+    if ( SMESHGUI::automaticUpdate() ) {
+      mySelectionMgr->clearSelected();
+      SMESH::UpdateView();
+
+      _PTR(SObject) aSO = SMESH::FindSObject(aCompoundMesh.in());
+      if ( SMESH_Actor* anActor = SMESH::CreateActor(aSO->GetStudy(), aSO->GetID().c_str()) )
+        SMESH::DisplayActor(SMESH::GetActiveWindow(), anActor);
+    }// end IPAL21468
+
+    if( LightApp_Application* anApp =
+        dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
+      anApp->browseObjects( anEntryList, isApplyAndClose() );
+
+    SMESHGUI::Modified();
+
+#ifdef WITHGENERICOBJ
+    // obj has been published in study. Its refcount has been incremented.
+    // It is safe to decrement its refcount
+    // so that it will be destroyed when the entry in study will be removed
+    if (!CORBA::is_nil(aCompoundMesh))
+      aCompoundMesh->UnRegister();
+#endif
+
     return true;
   }
   return false;
@@ -332,6 +366,7 @@ bool SMESHGUI_BuildCompoundDlg::ClickOnApply()
 //=================================================================================
 void SMESHGUI_BuildCompoundDlg::ClickOnOk()
 {
+  setIsApplyAndClose( true );
   if (ClickOnApply())
     ClickOnCancel();
 }
@@ -356,14 +391,14 @@ void SMESHGUI_BuildCompoundDlg::ClickOnCancel()
 void SMESHGUI_BuildCompoundDlg::ClickOnHelp()
 {
   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
-  if (app) 
+  if (app)
     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
   else {
     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser",
-                                                                "application")).
-                            arg(myHelpFileName));
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser",
+                                                                 "application")).
+                             arg(myHelpFileName));
   }
 }
 
@@ -491,7 +526,6 @@ void SMESHGUI_BuildCompoundDlg::keyPressEvent( QKeyEvent* e )
 //=================================================================================
 void SMESHGUI_BuildCompoundDlg::onSelectMerge(bool toMerge)
 {
-  
   TextLabelTol->setEnabled(toMerge);
   SpinBoxTol->setEnabled(toMerge);
   if(!toMerge)
@@ -518,3 +552,23 @@ bool SMESHGUI_BuildCompoundDlg::isValid()
   }
   return true;
 }
+
+//================================================================
+// function : setIsApplyAndClose
+// Purpose  : Set value of the flag indicating that the dialog is
+//            accepted by Apply & Close button
+//================================================================
+void SMESHGUI_BuildCompoundDlg::setIsApplyAndClose( const bool theFlag )
+{
+  myIsApplyAndClose = theFlag;
+}
+
+//================================================================
+// function : isApplyAndClose
+// Purpose  : Get value of the flag indicating that the dialog is
+//            accepted by Apply & Close button
+//================================================================
+bool SMESHGUI_BuildCompoundDlg::isApplyAndClose() const
+{
+  return myIsApplyAndClose;
+}
index c1085739d8d5d6ff9cfa444e341714efd464ab7d..6230022e82f42e9be2a1cbaa1b75854225942a03 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_BuildCompoundDlg.h
 // Author : Alexander KOVALEV, Open CASCADE S.A.S.
@@ -73,6 +74,9 @@ private:
   void                    keyPressEvent( QKeyEvent* );
 
   bool                    isValid();
+
+  void                    setIsApplyAndClose( const bool theFlag );
+  bool                    isApplyAndClose() const;
   
 private:
   SMESHGUI*               mySMESHGUI;     /* Current SMESHGUI object */
@@ -109,6 +113,8 @@ private:
 
   QString                 myHelpFileName;
 
+  bool                    myIsApplyAndClose;
+
 private slots:
   void                    ClickOnOk();
   void                    ClickOnCancel();
index 6f2d9293ecc4f9f201f17a46a447273302202bfc..3143626c66b4b586070defa1cb16bf7124bca7a1 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_ClippingDlg.cxx
 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
 #include <SUIT_OverrideCursor.h>
 #include <SUIT_MessageBox.h>
 #include <SUIT_ResourceMgr.h>
+#include <SUIT_ViewManager.h>
 
 #include <SALOME_ListIO.hxx>
 
+#include <SalomeApp_Study.h>
+
 #include <LightApp_Application.h>
-#include <LightApp_SelectionMgr.h>
+
+#include <VTKViewer_Algorithm.h>
 
 #include <SVTK_ViewWindow.h>
 
 #include <QGridLayout>
 #include <QGroupBox>
 #include <QKeyEvent>
+#include <QListWidget>
 
 // VTK includes
 #include <vtkMath.h>
-#include <vtkPlane.h>
 #include <vtkDataSet.h>
 #include <vtkDataSetMapper.h>
 #include <vtkPlaneSource.h>
 #include <vtkProperty.h>
+#include <vtkRenderer.h>
 
 #define SPACING 6
 #define MARGIN  11
 
-class OrientedPlane: public vtkPlane
+//=================================================================================
+// class    : OrientedPlane
+// purpose  :
+//=================================================================================
+SMESH::OrientedPlane* SMESH::OrientedPlane::New()
 {
-  SVTK_ViewWindow* myViewWindow;
-
-  vtkDataSetMapper* myMapper;
-
-public:
-  static OrientedPlane *New()
-  {
-    return new OrientedPlane();
-  }
-  static OrientedPlane *New(SVTK_ViewWindow* theViewWindow)
-  {
-    return new OrientedPlane(theViewWindow);
-  }
-  vtkTypeMacro (OrientedPlane, vtkPlane);
-
-  SMESH::Orientation myOrientation;
-  float myDistance;
-  double myAngle[2];
-
-  vtkPlaneSource* myPlaneSource;
-  SALOME_Actor *myActor;
-
-  void SetOrientation (SMESH::Orientation theOrientation) { myOrientation = theOrientation; }
-  SMESH::Orientation GetOrientation() { return myOrientation; }
+  return new OrientedPlane();
+}
 
-  void SetDistance (float theDistance) { myDistance = theDistance; }
-  float GetDistance() { return myDistance; }
+SMESH::OrientedPlane* SMESH::OrientedPlane::New(SVTK_ViewWindow* theViewWindow)
+{
+  return new OrientedPlane(theViewWindow);
+}
 
-  void ShallowCopy (OrientedPlane* theOrientedPlane)
-  {
-    SetNormal(theOrientedPlane->GetNormal());
-    SetOrigin(theOrientedPlane->GetOrigin());
+void SMESH::OrientedPlane::ShallowCopy(SMESH::OrientedPlane* theOrientedPlane)
+{
+  SetNormal(theOrientedPlane->GetNormal());
+  SetOrigin(theOrientedPlane->GetOrigin());
 
-    myOrientation = theOrientedPlane->GetOrientation();
-    myDistance = theOrientedPlane->GetDistance();
+  myOrientation = theOrientedPlane->GetOrientation();
+  myDistance = theOrientedPlane->GetDistance();
 
-    myAngle[0] = theOrientedPlane->myAngle[0];
-    myAngle[1] = theOrientedPlane->myAngle[1];
+  myAngle[0] = theOrientedPlane->myAngle[0];
+  myAngle[1] = theOrientedPlane->myAngle[1];
 
-    myPlaneSource->SetNormal(theOrientedPlane->myPlaneSource->GetNormal());
-    myPlaneSource->SetOrigin(theOrientedPlane->myPlaneSource->GetOrigin());
-    myPlaneSource->SetPoint1(theOrientedPlane->myPlaneSource->GetPoint1());
-    myPlaneSource->SetPoint2(theOrientedPlane->myPlaneSource->GetPoint2());
-  }
+  myPlaneSource->SetNormal(theOrientedPlane->myPlaneSource->GetNormal());
+  myPlaneSource->SetOrigin(theOrientedPlane->myPlaneSource->GetOrigin());
+  myPlaneSource->SetPoint1(theOrientedPlane->myPlaneSource->GetPoint1());
+  myPlaneSource->SetPoint2(theOrientedPlane->myPlaneSource->GetPoint2());
+}
 
-protected:
-  OrientedPlane(SVTK_ViewWindow* theViewWindow):
-    myViewWindow(theViewWindow),
-    myOrientation(SMESH::XY),
-    myDistance(0.5)
-  {
-    Init();
-    myViewWindow->AddActor(myActor);
-  }
+SMESH::OrientedPlane::OrientedPlane(SVTK_ViewWindow* theViewWindow):
+  myViewWindow(theViewWindow),
+  myOrientation(SMESH::XY),
+  myDistance(0.5)
+{
+  Init();
+  myViewWindow->AddActor(myActor, false, false); // don't adjust actors
+}
 
-  OrientedPlane():
-    myOrientation(SMESH::XY),
-    myViewWindow(NULL),
-    myDistance(0.5)
-  {
-    Init();
-  }
+SMESH::OrientedPlane::OrientedPlane():
+  myOrientation(SMESH::XY),
+  myViewWindow(NULL),
+  myDistance(0.5)
+{
+  Init();
+}
 
-  void Init()
-  {
-    myPlaneSource = vtkPlaneSource::New();
-
-    myAngle[0] = myAngle[1] = 0.0;
-
-    // Create and display actor
-    myMapper = vtkDataSetMapper::New();
-    myMapper->SetInput(myPlaneSource->GetOutput());
-
-    myActor = SALOME_Actor::New();
-    myActor->VisibilityOff();
-    myActor->PickableOff();
-    myActor->SetInfinitive(true);
-    myActor->SetMapper(myMapper);
-
-    vtkFloatingPointType anRGB[3];
-    vtkProperty* aProp = vtkProperty::New();
-    SMESH::GetColor( "SMESH", "fill_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 170, 255 ) );
-    aProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
-    aProp->SetOpacity(0.75);
-    myActor->SetProperty(aProp);
-    aProp->Delete();
-
-    vtkProperty* aBackProp = vtkProperty::New();
-    SMESH::GetColor( "SMESH", "backface_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 0, 255 ) );
-    aBackProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
-    aBackProp->SetOpacity(0.75);
-    myActor->SetBackfaceProperty(aBackProp);
-    aBackProp->Delete();
-  }
+void SMESH::OrientedPlane::Init()
+{
+  myPlaneSource = vtkPlaneSource::New();
+
+  myAngle[0] = myAngle[1] = 0.0;
+
+  // Create and display actor
+  myMapper = vtkDataSetMapper::New();
+  myMapper->SetInput(myPlaneSource->GetOutput());
+
+  myActor = SALOME_Actor::New();
+  myActor->VisibilityOff();
+  myActor->PickableOff();
+  myActor->SetInfinitive(true);
+  myActor->SetMapper(myMapper);
+
+  vtkFloatingPointType anRGB[3];
+  vtkProperty* aProp = vtkProperty::New();
+  SMESH::GetColor( "SMESH", "fill_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 170, 255 ) );
+  aProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
+  aProp->SetOpacity(0.75);
+  myActor->SetProperty(aProp);
+  aProp->Delete();
+
+  vtkProperty* aBackProp = vtkProperty::New();
+  SMESH::GetColor( "SMESH", "backface_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 0, 255 ) );
+  aBackProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
+  aBackProp->SetOpacity(0.75);
+  myActor->SetBackfaceProperty(aBackProp);
+  aBackProp->Delete();
+}
 
-  ~OrientedPlane(){
+SMESH::OrientedPlane::~OrientedPlane()
+{
+  if (myViewWindow)
     myViewWindow->RemoveActor(myActor);
-    myActor->Delete();
+  myActor->Delete();
     
-    myMapper->RemoveAllInputs();
-    myMapper->Delete();
+  myMapper->RemoveAllInputs();
+  myMapper->Delete();
 
-    // commented: porting to vtk 5.0
-    //    myPlaneSource->UnRegisterAllOutputs();
-    myPlaneSource->Delete();
-  };
+  // commented: porting to vtk 5.0
+  //    myPlaneSource->UnRegisterAllOutputs();
+  myPlaneSource->Delete();
+}
 
-private:
-  // Not implemented.
-  OrientedPlane (const OrientedPlane&);
-  void operator= (const OrientedPlane&);
+//=================================================================================
+// class    : ActorItem
+// purpose  :
+//=================================================================================
+class ActorItem : public QListWidgetItem
+{
+public:
+  ActorItem( SMESH_Actor* theActor, const QString& theName, QListWidget* theListWidget ) :
+    QListWidgetItem( theName, theListWidget ),
+    myActor( theActor ) {}
+
+  SMESH_Actor* getActor() const { return myActor; }
 
+private:
+  SMESH_Actor* myActor;
 };
 
-struct TSetVisiblity {
-  TSetVisiblity(int theIsVisible): myIsVisible(theIsVisible){}
-  void operator()(SMESH::TVTKPlane& theOrientedPlane){
-    theOrientedPlane->myActor->SetVisibility(myIsVisible);
+//=================================================================================
+// class    : TSetVisibility
+// purpose  :
+//=================================================================================
+struct TSetVisibility {
+  TSetVisibility(int theIsVisible): myIsVisible(theIsVisible){}
+  void operator()(SMESH::TPlaneData& thePlaneData){
+    bool anIsEmpty = thePlaneData.ActorList.empty();
+    thePlaneData.Plane.GetPointer()->myActor->SetVisibility(myIsVisible && !anIsEmpty);
   }
   int myIsVisible;
 };
@@ -198,13 +204,13 @@ struct TSetVisiblity {
 // used in SMESHGUI::restoreVisualParameters() to avoid
 // declaration of OrientedPlane outside of SMESHGUI_ClippingDlg.cxx
 //=================================================================================
-void SMESHGUI_ClippingDlg::AddPlane (SMESH_Actor*         theActor,
-                                     SVTK_ViewWindow*     theViewWindow,
-                                     SMESH::Orientation   theOrientation,
-                                     double               theDistance,
-                                     vtkFloatingPointType theAngle[2])
+SMESH::OrientedPlane* SMESHGUI_ClippingDlg::AddPlane (SMESH::TActorList          theActorList,
+                                                      SVTK_ViewWindow*           theViewWindow,
+                                                      SMESH::Orientation         theOrientation,
+                                                      double                     theDistance,
+                                                      const vtkFloatingPointType theAngle[2])
 {
-  OrientedPlane* aPlane = OrientedPlane::New(theViewWindow);
+  SMESH::OrientedPlane* aPlane = SMESH::OrientedPlane::New(theViewWindow);
 
   aPlane->myAngle[0] = theAngle[0];
   aPlane->myAngle[1] = theAngle[1];
@@ -254,41 +260,64 @@ void SMESHGUI_ClippingDlg::AddPlane (SMESH_Actor*         theActor,
     vtkMath::Cross(aNormal,aDir[1],aDir[0]);
   }
 
-  // ???
-  theActor->SetPlaneParam(aNormal, theDistance, aPlane);
-
-  vtkDataSet* aDataSet = theActor->GetInput();
-  vtkFloatingPointType *aPnt = aDataSet->GetCenter();
-
-  vtkFloatingPointType* anOrigin = aPlane->GetOrigin();
-  vtkFloatingPointType aDel = aDataSet->GetLength()/2.0;
+  vtkFloatingPointType aBounds[6];
+  vtkFloatingPointType anOrigin[3];
+
+  bool anIsOk = false;
+  if( theActorList.empty() ) {
+    // to support planes with empty actor list we should create
+    // a nullified plane that will be initialized later 
+    anOrigin[0] = anOrigin[1] = anOrigin[2] = 0;
+    aBounds[0] = aBounds[2] = aBounds[4] = 0;
+    aBounds[1] = aBounds[3] = aBounds[5] = 0;
+    anIsOk = true;
+  }
+  else
+    anIsOk = SMESH::ComputeClippingPlaneParameters( theActorList,
+                                                    aNormal,
+                                                    theDistance,
+                                                    aBounds,
+                                                    anOrigin );
+  if( !anIsOk )
+    return NULL;
+
+  aPlane->SetNormal( aNormal );
+  aPlane->SetOrigin( anOrigin );
+
+  vtkFloatingPointType aPnt[3] = { ( aBounds[0] + aBounds[1] ) / 2.,
+                                   ( aBounds[2] + aBounds[3] ) / 2.,
+                                   ( aBounds[4] + aBounds[5] ) / 2. };
+
+  vtkFloatingPointType aDel = pow( pow( aBounds[1] - aBounds[0], 2 ) +
+                                   pow( aBounds[3] - aBounds[2], 2 ) +
+                                   pow( aBounds[5] - aBounds[4], 2 ), 0.5 );
 
   vtkFloatingPointType aDelta[2][3] = {{aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel},
-                                      {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}};
+                                       {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}};
   vtkFloatingPointType aParam, aPnt0[3], aPnt1[3], aPnt2[3];
 
   vtkFloatingPointType aPnt01[3] = {aPnt[0] - aDelta[0][0] - aDelta[1][0],
-                                   aPnt[1] - aDelta[0][1] - aDelta[1][1],
-                                   aPnt[2] - aDelta[0][2] - aDelta[1][2]};
+                                    aPnt[1] - aDelta[0][1] - aDelta[1][1],
+                                    aPnt[2] - aDelta[0][2] - aDelta[1][2]};
   vtkFloatingPointType aPnt02[3] = {aPnt01[0] + aNormal[0],
-                                   aPnt01[1] + aNormal[1],
-                                   aPnt01[2] + aNormal[2]};
+                                    aPnt01[1] + aNormal[1],
+                                    aPnt01[2] + aNormal[2]};
   vtkPlane::IntersectWithLine(aPnt01,aPnt02,aNormal,anOrigin,aParam,aPnt0);
 
   vtkFloatingPointType aPnt11[3] = {aPnt[0] - aDelta[0][0] + aDelta[1][0],
-                                   aPnt[1] - aDelta[0][1] + aDelta[1][1],
-                                   aPnt[2] - aDelta[0][2] + aDelta[1][2]};
+                                    aPnt[1] - aDelta[0][1] + aDelta[1][1],
+                                    aPnt[2] - aDelta[0][2] + aDelta[1][2]};
   vtkFloatingPointType aPnt12[3] = {aPnt11[0] + aNormal[0],
-                                   aPnt11[1] + aNormal[1],
-                                   aPnt11[2] + aNormal[2]};
+                                    aPnt11[1] + aNormal[1],
+                                    aPnt11[2] + aNormal[2]};
   vtkPlane::IntersectWithLine(aPnt11,aPnt12,aNormal,anOrigin,aParam,aPnt1);
 
   vtkFloatingPointType aPnt21[3] = {aPnt[0] + aDelta[0][0] - aDelta[1][0],
-                                   aPnt[1] + aDelta[0][1] - aDelta[1][1],
-                                   aPnt[2] + aDelta[0][2] - aDelta[1][2]};
+                                    aPnt[1] + aDelta[0][1] - aDelta[1][1],
+                                    aPnt[2] + aDelta[0][2] - aDelta[1][2]};
   vtkFloatingPointType aPnt22[3] = {aPnt21[0] + aNormal[0],
-                                   aPnt21[1] + aNormal[1],
-                                   aPnt21[2] + aNormal[2]};
+                                    aPnt21[1] + aNormal[1],
+                                    aPnt21[2] + aNormal[2]};
   vtkPlane::IntersectWithLine(aPnt21,aPnt22,aNormal,anOrigin,aParam,aPnt2);
 
   vtkPlaneSource* aPlaneSource = aPlane->myPlaneSource;
@@ -297,28 +326,13 @@ void SMESHGUI_ClippingDlg::AddPlane (SMESH_Actor*         theActor,
   aPlaneSource->SetPoint1(aPnt1[0],aPnt1[1],aPnt1[2]);
   aPlaneSource->SetPoint2(aPnt2[0],aPnt2[1],aPnt2[2]);
 
-  theActor->AddClippingPlane(aPlane);
-  aPlane->Delete();
-}
+  SMESH::TActorList::iterator anIter = theActorList.begin();
+  for ( ; anIter != theActorList.end(); anIter++ )
+    if( vtkActor* aVTKActor = *anIter )
+      if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) )
+        anActor->AddClippingPlane( aPlane );
 
-//=================================================================================
-// used in SMESHGUI::restoreVisualParameters() to avoid
-// declaration of OrientedPlane outside of SMESHGUI_ClippingDlg.cxx
-//=================================================================================
-void SMESHGUI_ClippingDlg::GetPlaneParam (SMESH_Actor*          theActor,
-                                          int                   thePlaneIndex,
-                                          SMESH::Orientation&   theOrientation,
-                                          double&               theDistance,
-                                          vtkFloatingPointType* theAngle)
-{
-  if (vtkPlane* aPln = theActor->GetClippingPlane(thePlaneIndex)) {
-    if (OrientedPlane* aPlane = OrientedPlane::SafeDownCast(aPln)) {
-      theOrientation = aPlane->GetOrientation();
-      theDistance = aPlane->GetDistance();
-      theAngle[0] = aPlane->myAngle[0];
-      theAngle[1] = aPlane->myAngle[1];
-    }
-  }
+  return aPlane;
 }
 
 //=================================================================================
@@ -326,11 +340,10 @@ void SMESHGUI_ClippingDlg::GetPlaneParam (SMESH_Actor*          theActor,
 // purpose  :
 //
 //=================================================================================
-SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ):
+SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule, SVTK_ViewWindow* theViewWindow ):
   QDialog( SMESH::GetDesktop(theModule) ),
-  mySelector(SMESH::GetViewWindow(theModule)->GetSelector()),
-  mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
-  mySMESHGUI(theModule)
+  mySMESHGUI(theModule),
+  myViewWindow(theViewWindow)
 {
   setModal( false );
   setAttribute( Qt::WA_DeleteOnClose, true );
@@ -342,8 +355,8 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ):
   SMESHGUI_ClippingDlgLayout->setMargin(MARGIN);
 
   // Controls for selecting, creating, deleting planes
-  QGroupBox* GroupPlanes = new QGroupBox(tr("Clipping planes"), this);
-  QHBoxLayout* GroupPlanesLayout = new QHBoxLayout(GroupPlanes);
+  QGroupBox* GroupPlanes = new QGroupBox(tr("CLIP_PLANES"), this);
+  QGridLayout* GroupPlanesLayout = new QGridLayout(GroupPlanes);
   GroupPlanesLayout->setSpacing(SPACING);
   GroupPlanesLayout->setMargin(MARGIN);
 
@@ -353,10 +366,21 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ):
 
   buttonDelete = new QPushButton(tr("SMESH_BUT_DELETE"), GroupPlanes);
 
-  GroupPlanesLayout->addWidget(ComboBoxPlanes);
-  GroupPlanesLayout->addStretch();
-  GroupPlanesLayout->addWidget(buttonNew);
-  GroupPlanesLayout->addWidget(buttonDelete);
+  QLabel* aLabel = new QLabel(tr("MESHES_SUBMESHES_GROUPS"), GroupPlanes);
+
+  ActorList = new QListWidget(GroupPlanes);
+  ActorList->setSelectionMode(QAbstractItemView::SingleSelection);
+
+  SelectAllCheckBox = new QCheckBox(tr("SELECT_ALL"), GroupPlanes);
+
+  GroupPlanesLayout->addWidget(ComboBoxPlanes,    0, 0);
+  GroupPlanesLayout->addWidget(new QWidget(),     0, 1);
+  GroupPlanesLayout->addWidget(buttonNew,         0, 2);
+  GroupPlanesLayout->addWidget(buttonDelete,      0, 3);
+  GroupPlanesLayout->addWidget(aLabel,            1, 0, 1, 4);
+  GroupPlanesLayout->addWidget(ActorList,         2, 0, 1, 4);
+  GroupPlanesLayout->addWidget(SelectAllCheckBox, 3, 0, 1, 4);
+  GroupPlanesLayout->setColumnStretch( 1, 1 );
 
   // Controls for defining plane parameters
   QGroupBox* GroupParameters = new QGroupBox(tr("SMESH_PARAMETERS"), this);
@@ -372,18 +396,18 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ):
 
   SpinBoxDistance = new SMESHGUI_SpinBox(GroupParameters);
 
-  TextLabelRot1 = new QLabel(tr("Rotation around X (Y to Z):"), GroupParameters);
+  TextLabelRot1 = new QLabel(tr("ROTATION_AROUND_X_Y2Z"), GroupParameters);
 
   SpinBoxRot1 = new SMESHGUI_SpinBox(GroupParameters);
 
-  TextLabelRot2 = new QLabel(tr("Rotation around Y (X to Z):"), GroupParameters);
+  TextLabelRot2 = new QLabel(tr("ROTATION_AROUND_Y_X2Z"), GroupParameters);
 
   SpinBoxRot2 = new SMESHGUI_SpinBox(GroupParameters);
 
-  PreviewCheckBox = new QCheckBox(tr("Show preview"), GroupParameters);
+  PreviewCheckBox = new QCheckBox(tr("SHOW_PREVIEW"), GroupParameters);
   PreviewCheckBox->setChecked(true);
 
-  AutoApplyCheckBox = new QCheckBox(tr("Auto Apply"), GroupParameters);
+  AutoApplyCheckBox = new QCheckBox(tr("AUTO_APPLY"), GroupParameters);
   AutoApplyCheckBox->setChecked(false);
 
   GroupParametersLayout->addWidget(TextLabelOrientation, 0, 0);
@@ -425,19 +449,20 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ):
   SMESHGUI_ClippingDlgLayout->addWidget(GroupButtons);
 
   // Initial state
-  SpinBoxDistance->RangeStepAndValidator(0.0, 1.0, 0.01, 3);
-  SpinBoxRot1->RangeStepAndValidator(-180.0, 180.0, 1, 3);
-  SpinBoxRot2->RangeStepAndValidator(-180.0, 180.0, 1, 3);
+  SpinBoxDistance->RangeStepAndValidator(0.0, 1.0, 0.01, "length_precision" );
+  SpinBoxRot1->RangeStepAndValidator(-180.0, 180.0, 1, "angle_precision" );
+  SpinBoxRot2->RangeStepAndValidator(-180.0, 180.0, 1, "angle_precision" );
 
-  ComboBoxOrientation->addItem(tr("|| X-Y"));
-  ComboBoxOrientation->addItem(tr("|| Y-Z"));
-  ComboBoxOrientation->addItem(tr("|| Z-X"));
+  ComboBoxOrientation->addItem(tr("ALONG_XY"));
+  ComboBoxOrientation->addItem(tr("ALONG_YZ"));
+  ComboBoxOrientation->addItem(tr("ALONG_ZX"));
 
   SpinBoxDistance->SetValue(0.5);
 
-  myActor = 0;
   myIsSelectPlane = false;
-  onSelectionChanged();
+
+  initializePlaneData();
+  synchronize();
 
   myHelpFileName = "clipping_page.html";
 
@@ -445,6 +470,8 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ):
   connect(ComboBoxPlanes, SIGNAL(activated(int)), this, SLOT(onSelectPlane(int)));
   connect(buttonNew, SIGNAL(clicked()), this, SLOT(ClickOnNew()));
   connect(buttonDelete, SIGNAL(clicked()), this, SLOT(ClickOnDelete()));
+  connect(ActorList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(onActorItemChanged(QListWidgetItem*)));
+  connect(SelectAllCheckBox, SIGNAL(stateChanged(int)), this, SLOT(onSelectAll(int)));
   connect(ComboBoxOrientation, SIGNAL(activated(int)), this, SLOT(onSelectOrientation(int)));
   connect(SpinBoxDistance, SIGNAL(valueChanged(double)), this, SLOT(SetCurrentPlaneParam()));
   connect(SpinBoxRot1, SIGNAL(valueChanged(double)), this, SLOT(SetCurrentPlaneParam()));
@@ -456,7 +483,6 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ):
   connect(buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply()));
   connect(buttonHelp, SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
   connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(ClickOnCancel()));
-  connect(mySelectionMgr,  SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionChanged()));
   /* to close dialog if study frame change */
   connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), this, SLOT(ClickOnCancel()));
 
@@ -470,10 +496,9 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ):
 SMESHGUI_ClippingDlg::~SMESHGUI_ClippingDlg()
 {
   // no need to delete child widgets, Qt does it all for us
-  std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false));
-  if (mySMESHGUI)
-    if (SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(mySMESHGUI))
-      SMESH::RenderViewWindow(aViewWindow);
+  std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisibility(false));
+  if (myViewWindow)
+    SMESH::RenderViewWindow(myViewWindow);
 }
 
 double SMESHGUI_ClippingDlg::getDistance() const
@@ -502,27 +527,58 @@ double SMESHGUI_ClippingDlg::getRotation2() const
 //=======================================================================
 void SMESHGUI_ClippingDlg::ClickOnApply()
 {
-  if (!myActor)
-    return;
-
-  if (SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(mySMESHGUI)) {
+  if (myViewWindow) {
     SUIT_OverrideCursor wc;
     
     QWidget *aCurrWid = this->focusWidget();
     aCurrWid->clearFocus();
     aCurrWid->setFocus();
 
-    myActor->RemoveAllClippingPlanes();
+    SMESHGUI_ClippingPlaneInfoMap& aClippingPlaneInfoMap = mySMESHGUI->getClippingPlaneInfoMap();
+    SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = aClippingPlaneInfoMap[ myViewWindow->getViewManager() ];
+
+    // clean memory allocated for planes
+    SMESHGUI_ClippingPlaneInfoList::iterator anIter1 = aClippingPlaneInfoList.begin();
+    for( ; anIter1 != aClippingPlaneInfoList.end(); anIter1++ )
+      if( SMESH::OrientedPlane* aPlane = (*anIter1).Plane )
+        aPlane->Delete();
+
+    aClippingPlaneInfoList.clear();
+
+    VTK::ActorCollectionCopy aCopy( myViewWindow->getRenderer()->GetActors() );
+    vtkActorCollection* anAllActors = aCopy.GetActors();
+    anAllActors->InitTraversal();
+    while( vtkActor* aVTKActor = anAllActors->GetNextActor() )
+      if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) )
+        anActor->RemoveAllClippingPlanes();
+
+    SMESH::TPlaneDataVector::iterator anIter2 = myPlanes.begin();
+    for( ; anIter2 != myPlanes.end(); anIter2++ ) {
+      SMESH::TPlaneData aPlaneData = *anIter2;
+      SMESH::TPlane aPlane = aPlaneData.Plane;
+      SMESH::TActorList anActorList = aPlaneData.ActorList;
+
+      // the check is disabled to support planes with empty actor list
+      //if( anActorList.empty() )
+      //  continue;
 
-    SMESH::TPlanes::iterator anIter = myPlanes.begin();
-    for ( ; anIter != myPlanes.end(); anIter++) {
-      OrientedPlane* anOrientedPlane = OrientedPlane::New(aViewWindow);
-      anOrientedPlane->ShallowCopy(anIter->GetPointer());
-      myActor->AddClippingPlane(anOrientedPlane);
-      anOrientedPlane->Delete();
+      SMESH::OrientedPlane* anOrientedPlane = SMESH::OrientedPlane::New(myViewWindow);
+      anOrientedPlane->ShallowCopy(aPlane.GetPointer());
+
+      SMESH::TActorList::iterator anIter3 = anActorList.begin();
+      for( ; anIter3 != anActorList.end(); anIter3++ )
+        if( vtkActor* aVTKActor = *anIter3 )
+          if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) )
+            anActor->AddClippingPlane(anOrientedPlane);
+
+      SMESH::ClippingPlaneInfo aClippingPlaneInfo;
+      aClippingPlaneInfo.Plane = anOrientedPlane;
+      aClippingPlaneInfo.ActorList = anActorList;
+
+      aClippingPlaneInfoList.push_back( aClippingPlaneInfo );
     }
 
-    SMESH::RenderViewWindow(aViewWindow);
+    SMESH::RenderViewWindow( myViewWindow );
   }
 }
 
@@ -555,67 +611,31 @@ void SMESHGUI_ClippingDlg::ClickOnHelp()
   if (app) 
     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
   else {
-               QString platform;
+                QString platform;
 #ifdef WIN32
-               platform = "winapplication";
+                platform = "winapplication";
 #else
-               platform = "application";
+                platform = "application";
 #endif
     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser", 
-                                                                platform)).
-                            arg(myHelpFileName));
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser", 
+                                                                 platform)).
+                             arg(myHelpFileName));
   }
 }
 
-//=================================================================================
-// function : onSelectionChanged()
-// purpose  : Called when selection is changed
-//=================================================================================
-void SMESHGUI_ClippingDlg::onSelectionChanged()
-{
-  if (SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(mySMESHGUI)) {
-    const SALOME_ListIO& aList = mySelector->StoredIObjects();
-    if (aList.Extent() > 0) {
-      Handle(SALOME_InteractiveObject) IOS = aList.First();
-      myActor = SMESH::FindActorByEntry(IOS->getEntry());
-      if (myActor) {
-       std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false));
-       myPlanes.clear();
-
-       vtkIdType anId = 0, anEnd = myActor->GetNumberOfClippingPlanes();
-       for ( ; anId < anEnd; anId++) {
-         if (vtkImplicitFunction* aFunction = myActor->GetClippingPlane(anId)) {
-           if(OrientedPlane* aPlane = OrientedPlane::SafeDownCast(aFunction)){
-             OrientedPlane* anOrientedPlane = OrientedPlane::New(aViewWindow);
-             SMESH::TVTKPlane aTVTKPlane(anOrientedPlane);
-             anOrientedPlane->Delete();
-             aTVTKPlane->ShallowCopy(aPlane);
-             myPlanes.push_back(aTVTKPlane);
-           }
-         }
-       }
-
-       std::for_each(myPlanes.begin(),myPlanes.end(),
-                     TSetVisiblity(PreviewCheckBox->isChecked()));
-      }
-    }
-    SMESH::RenderViewWindow(aViewWindow);
-  }
-  Sinchronize();
-}
-
 //=======================================================================
 // function : onSelectPlane()
 // purpose  :
 //=======================================================================
 void SMESHGUI_ClippingDlg::onSelectPlane (int theIndex)
 {
-  if (!myActor || myPlanes.empty())
+  if (myPlanes.empty())
     return;
 
-  OrientedPlane* aPlane = myPlanes[theIndex].GetPointer();
+  SMESH::TPlaneData aPlaneData = myPlanes[theIndex];
+  SMESH::OrientedPlane* aPlane = aPlaneData.Plane.GetPointer();
 
   // Orientation
   SMESH::Orientation anOrientation = aPlane->GetOrientation();
@@ -642,6 +662,11 @@ void SMESHGUI_ClippingDlg::onSelectPlane (int theIndex)
     break;
   }
   myIsSelectPlane = false;
+
+  // Actors
+  bool anIsBlocked = ActorList->blockSignals( true );
+  updateActorList();
+  ActorList->blockSignals( anIsBlocked );
 }
 
 //=======================================================================
@@ -650,19 +675,31 @@ void SMESHGUI_ClippingDlg::onSelectPlane (int theIndex)
 //=======================================================================
 void SMESHGUI_ClippingDlg::ClickOnNew()
 {
-  if (!myActor)
-    return;
+  if(myViewWindow){
+    SMESH::OrientedPlane* aPlane = SMESH::OrientedPlane::New(myViewWindow);
+    SMESH::TPlane aTPlane(aPlane);
+
+    SMESH::TActorList anActorList;
+    VTK::ActorCollectionCopy aCopy( myViewWindow->getRenderer()->GetActors() );
+    vtkActorCollection* anAllActors = aCopy.GetActors();
+    anAllActors->InitTraversal();
+    while( vtkActor* aVTKActor = anAllActors->GetNextActor() )
+      if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) )
+        anActorList.push_back( anActor );
 
-  if(SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(mySMESHGUI)){
-    OrientedPlane* aPlane = OrientedPlane::New(aViewWindow);
-    SMESH::TVTKPlane aTVTKPlane(aPlane);
-    myPlanes.push_back(aTVTKPlane);
+    SMESH::TPlaneData aPlaneData(aTPlane, anActorList);
+
+    myPlanes.push_back(aPlaneData);
 
     if (PreviewCheckBox->isChecked())
-      aTVTKPlane->myActor->VisibilityOn();
-    
-    Sinchronize();
+      aTPlane->myActor->VisibilityOn();
+
+    bool anIsBlocked = ActorList->blockSignals( true );
+
+    synchronize();
     SetCurrentPlaneParam();
+
+    ActorList->blockSignals( anIsBlocked );
   }
 }
 
@@ -672,20 +709,105 @@ void SMESHGUI_ClippingDlg::ClickOnNew()
 //=======================================================================
 void SMESHGUI_ClippingDlg::ClickOnDelete()
 {
-  if (!myActor || myPlanes.empty())
+  if (myPlanes.empty())
     return;
 
   int aPlaneIndex = ComboBoxPlanes->currentIndex();
 
-  SMESH::TPlanes::iterator anIter = myPlanes.begin() + aPlaneIndex;
-  anIter->GetPointer()->myActor->SetVisibility(false);
+  SMESH::TPlaneDataVector::iterator anIter = myPlanes.begin() + aPlaneIndex;
+  SMESH::TPlaneData aPlaneData = *anIter;
+  aPlaneData.Plane.GetPointer()->myActor->SetVisibility(false);
   myPlanes.erase(anIter);
 
   if(AutoApplyCheckBox->isChecked())
     ClickOnApply();
 
-  Sinchronize();
-  SMESH::RenderViewWindow(SMESH::GetCurrentVtkView());
+  synchronize();
+  SMESH::RenderViewWindow( myViewWindow );
+}
+
+//=======================================================================
+// function : updateActorItem()
+// purpose  :
+//=======================================================================
+void SMESHGUI_ClippingDlg::updateActorItem( QListWidgetItem* theItem,
+                                            bool theUpdateSelectAll,
+                                            bool theUpdateClippingPlaneMap )
+{
+  // update Select All check box
+  if( theUpdateSelectAll ) {
+    int aNbItems = ActorList->count(), aNbChecked = 0;
+    for( int i = 0; i < aNbItems; i++ )
+      if( QListWidgetItem* anItem = ActorList->item( i ) )
+        if( anItem->checkState() == Qt::Checked )
+          aNbChecked++;
+
+    Qt::CheckState aCheckState = Qt::Unchecked;
+    if( aNbChecked == aNbItems )
+      aCheckState = Qt::Checked;
+    else if( aNbChecked > 0 )
+      aCheckState = Qt::PartiallyChecked;
+
+    bool anIsBlocked = SelectAllCheckBox->blockSignals( true );
+    SelectAllCheckBox->setCheckState( aCheckState );
+    SelectAllCheckBox->blockSignals( anIsBlocked );
+  }
+
+  // update clipping plane map
+  if( theUpdateClippingPlaneMap ) {
+    int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
+    if( ActorItem* anItem = dynamic_cast<ActorItem*>( theItem ) ) {
+      if( SMESH_Actor* anActor = anItem->getActor() ) {
+        SMESH::TPlaneData& aPlaneData = myPlanes[ aCurPlaneIndex ];
+        SMESH::TActorList& anActorList = aPlaneData.ActorList;
+        bool anIsPushed = false;
+        SMESH::TActorList::iterator anIter = anActorList.begin();
+        for ( ; anIter != anActorList.end(); anIter++ ) {
+          if( anActor == *anIter ) {
+            anIsPushed = true;
+            break;
+          }
+        }
+        if( theItem->checkState() == Qt::Checked && !anIsPushed )
+          anActorList.push_back( anActor );
+        else if( theItem->checkState() == Qt::Unchecked && anIsPushed )
+          anActorList.remove( anActor );
+      }
+    }
+  }
+}
+
+//=======================================================================
+// function : onActorItemChanged()
+// purpose  :
+//=======================================================================
+void SMESHGUI_ClippingDlg::onActorItemChanged( QListWidgetItem* theItem )
+{
+  updateActorItem( theItem, true, true );
+  SetCurrentPlaneParam();
+}
+
+//=======================================================================
+// function : onSelectAll()
+// purpose  :
+//=======================================================================
+void SMESHGUI_ClippingDlg::onSelectAll( int theState )
+{
+  if( theState == Qt::PartiallyChecked ) {
+    SelectAllCheckBox->setCheckState( Qt::Checked );
+    return;
+  }
+
+  bool anIsBlocked = ActorList->blockSignals( true );
+  for( int i = 0, n = ActorList->count(); i < n; i++ ) {
+    if( QListWidgetItem* anItem = ActorList->item( i ) ) {
+      anItem->setCheckState( theState == Qt::Checked ? Qt::Checked : Qt::Unchecked );
+      updateActorItem( anItem, false, true );
+    }
+  }
+  SelectAllCheckBox->setTristate( false );
+  ActorList->blockSignals( anIsBlocked );
+  SetCurrentPlaneParam();
 }
 
 //=======================================================================
@@ -698,16 +820,16 @@ void SMESHGUI_ClippingDlg::onSelectOrientation (int theItem)
     return;
 
   if      (theItem == 0) {
-    TextLabelRot1->setText(tr("Rotation around X (Y to Z):"));
-    TextLabelRot2->setText(tr("Rotation around Y (X to Z):"));
+    TextLabelRot1->setText(tr("ROTATION_AROUND_X_Y2Z"));
+    TextLabelRot2->setText(tr("ROTATION_AROUND_Y_X2Z"));
   }
   else if (theItem == 1) {
-    TextLabelRot1->setText(tr("Rotation around Y (Z to X):"));
-    TextLabelRot2->setText(tr("Rotation around Z (Y to X):"));
+    TextLabelRot1->setText(tr("ROTATION_AROUND_Y_Z2X"));
+    TextLabelRot2->setText(tr("ROTATION_AROUND_Z_Y2X"));
   }
   else if (theItem == 2) {
-    TextLabelRot1->setText(tr("Rotation around Z (X to Y):"));
-    TextLabelRot2->setText(tr("Rotation around X (Z to Y):"));
+    TextLabelRot1->setText(tr("ROTATION_AROUND_Z_X2Y"));
+    TextLabelRot2->setText(tr("ROTATION_AROUND_X_Z2Y"));
   }
 
   if((QComboBox*)sender() == ComboBoxOrientation)
@@ -715,17 +837,17 @@ void SMESHGUI_ClippingDlg::onSelectOrientation (int theItem)
 }
 
 //=======================================================================
-// function : Sinchronize()
+// function : synchronize()
 // purpose  :
 //=======================================================================
-void SMESHGUI_ClippingDlg::Sinchronize()
+void SMESHGUI_ClippingDlg::synchronize()
 {
   int aNbPlanes = myPlanes.size();
   ComboBoxPlanes->clear();
 
   QString aName;
   for(int i = 1; i<=aNbPlanes; i++) {
-    aName = QString(tr("Plane# %1")).arg(i);
+    aName = QString(tr("PLANE_NUM")).arg(i);
     ComboBoxPlanes->addItem(aName);
   }
 
@@ -735,17 +857,22 @@ void SMESHGUI_ClippingDlg::Sinchronize()
   bool anIsControlsEnable = (aPos >= 0);
   if (anIsControlsEnable) {
     onSelectPlane(aPos);
+    updateActorList();
   } else {
-    ComboBoxPlanes->addItem(tr("No planes"));
+    ComboBoxPlanes->addItem(tr("NO_PLANES"));
+    ActorList->clear();
     SpinBoxRot1->SetValue(0.0);
     SpinBoxRot2->SetValue(0.0);
     SpinBoxDistance->SetValue(0.5);
   }
 
+  ActorList->setEnabled(anIsControlsEnable);
+  SelectAllCheckBox->setEnabled(anIsControlsEnable);
   buttonDelete->setEnabled(anIsControlsEnable);
-  buttonApply->setEnabled(anIsControlsEnable);
-  PreviewCheckBox->setEnabled(anIsControlsEnable);
-  AutoApplyCheckBox->setEnabled(anIsControlsEnable);
+  // the following 3 controls should be enabled
+  //buttonApply->setEnabled(anIsControlsEnable);
+  //PreviewCheckBox->setEnabled(anIsControlsEnable);
+  //AutoApplyCheckBox->setEnabled(anIsControlsEnable);
   ComboBoxOrientation->setEnabled(anIsControlsEnable);
   SpinBoxDistance->setEnabled(anIsControlsEnable);
   SpinBoxRot1->setEnabled(anIsControlsEnable);
@@ -773,7 +900,8 @@ void SMESHGUI_ClippingDlg::SetCurrentPlaneParam()
 
   int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
 
-  OrientedPlane* aPlane = myPlanes[aCurPlaneIndex].GetPointer();
+  SMESH::TPlaneData aPlaneData = myPlanes[aCurPlaneIndex];
+  SMESH::OrientedPlane* aPlane = aPlaneData.Plane.GetPointer();
 
   vtkFloatingPointType aNormal[3];
   SMESH::Orientation anOrientation;
@@ -831,52 +959,69 @@ void SMESHGUI_ClippingDlg::SetCurrentPlaneParam()
   aPlane->SetOrientation(anOrientation);
   aPlane->SetDistance(getDistance());
 
-  myActor->SetPlaneParam(aNormal, getDistance(), aPlane);
-
-  vtkDataSet* aDataSet = myActor->GetInput();
-  vtkFloatingPointType *aPnt = aDataSet->GetCenter();
-
-  vtkFloatingPointType* anOrigin = aPlane->GetOrigin();
-  vtkFloatingPointType aDel = aDataSet->GetLength()/2.0;
-
-  vtkFloatingPointType aDelta[2][3] = {{aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel},
-                                      {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}};
-  vtkFloatingPointType aParam, aPnt0[3], aPnt1[3], aPnt2[3];
-
-  vtkFloatingPointType aPnt01[3] = {aPnt[0] - aDelta[0][0] - aDelta[1][0],
-                                   aPnt[1] - aDelta[0][1] - aDelta[1][1],
-                                   aPnt[2] - aDelta[0][2] - aDelta[1][2]};
-  vtkFloatingPointType aPnt02[3] = {aPnt01[0] + aNormal[0],
-                                   aPnt01[1] + aNormal[1],
-                                   aPnt01[2] + aNormal[2]};
-  vtkPlane::IntersectWithLine(aPnt01,aPnt02,aNormal,anOrigin,aParam,aPnt0);
-
-  vtkFloatingPointType aPnt11[3] = {aPnt[0] - aDelta[0][0] + aDelta[1][0],
-                                   aPnt[1] - aDelta[0][1] + aDelta[1][1],
-                                   aPnt[2] - aDelta[0][2] + aDelta[1][2]};
-  vtkFloatingPointType aPnt12[3] = {aPnt11[0] + aNormal[0],
-                                   aPnt11[1] + aNormal[1],
-                                   aPnt11[2] + aNormal[2]};
-  vtkPlane::IntersectWithLine(aPnt11,aPnt12,aNormal,anOrigin,aParam,aPnt1);
-
-  vtkFloatingPointType aPnt21[3] = {aPnt[0] + aDelta[0][0] - aDelta[1][0],
-                                   aPnt[1] + aDelta[0][1] - aDelta[1][1],
-                                   aPnt[2] + aDelta[0][2] - aDelta[1][2]};
-  vtkFloatingPointType aPnt22[3] = {aPnt21[0] + aNormal[0],
-                                   aPnt21[1] + aNormal[1],
-                                   aPnt21[2] + aNormal[2]};
-  vtkPlane::IntersectWithLine(aPnt21,aPnt22,aNormal,anOrigin,aParam,aPnt2);
-
-  vtkPlaneSource* aPlaneSource = aPlane->myPlaneSource;
-  aPlaneSource->SetNormal(aNormal[0],aNormal[1],aNormal[2]);
-  aPlaneSource->SetOrigin(aPnt0[0],aPnt0[1],aPnt0[2]);
-  aPlaneSource->SetPoint1(aPnt1[0],aPnt1[1],aPnt1[2]);
-  aPlaneSource->SetPoint2(aPnt2[0],aPnt2[1],aPnt2[2]);
+  SMESH::TActorList anActorList = aPlaneData.ActorList;
+
+  vtkFloatingPointType aBounds[6];
+  vtkFloatingPointType anOrigin[3];
+  bool anIsOk = SMESH::ComputeClippingPlaneParameters( anActorList,
+                                                       aNormal,
+                                                       getDistance(),
+                                                       aBounds,
+                                                       anOrigin );
+
+  aPlane->myActor->SetVisibility( anIsOk && PreviewCheckBox->isChecked() );
+
+  if( anIsOk ) {
+    aPlane->SetNormal( aNormal );
+    aPlane->SetOrigin( anOrigin );
+
+    vtkFloatingPointType aPnt[3] = { ( aBounds[0] + aBounds[1] ) / 2.,
+                                     ( aBounds[2] + aBounds[3] ) / 2.,
+                                     ( aBounds[4] + aBounds[5] ) / 2. };
+
+    vtkFloatingPointType aDel = pow( pow( aBounds[1] - aBounds[0], 2 ) +
+                                     pow( aBounds[3] - aBounds[2], 2 ) +
+                                     pow( aBounds[5] - aBounds[4], 2 ), 0.5 );
+
+    vtkFloatingPointType aDelta[2][3] = {{aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel},
+                                         {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}};
+    vtkFloatingPointType aParam, aPnt0[3], aPnt1[3], aPnt2[3];
+
+    vtkFloatingPointType aPnt01[3] = {aPnt[0] - aDelta[0][0] - aDelta[1][0],
+                                      aPnt[1] - aDelta[0][1] - aDelta[1][1],
+                                      aPnt[2] - aDelta[0][2] - aDelta[1][2]};
+    vtkFloatingPointType aPnt02[3] = {aPnt01[0] + aNormal[0],
+                                      aPnt01[1] + aNormal[1],
+                                      aPnt01[2] + aNormal[2]};
+    vtkPlane::IntersectWithLine(aPnt01,aPnt02,aNormal,anOrigin,aParam,aPnt0);
+
+    vtkFloatingPointType aPnt11[3] = {aPnt[0] - aDelta[0][0] + aDelta[1][0],
+                                      aPnt[1] - aDelta[0][1] + aDelta[1][1],
+                                      aPnt[2] - aDelta[0][2] + aDelta[1][2]};
+    vtkFloatingPointType aPnt12[3] = {aPnt11[0] + aNormal[0],
+                                      aPnt11[1] + aNormal[1],
+                                      aPnt11[2] + aNormal[2]};
+    vtkPlane::IntersectWithLine(aPnt11,aPnt12,aNormal,anOrigin,aParam,aPnt1);
+
+    vtkFloatingPointType aPnt21[3] = {aPnt[0] + aDelta[0][0] - aDelta[1][0],
+                                      aPnt[1] + aDelta[0][1] - aDelta[1][1],
+                                      aPnt[2] + aDelta[0][2] - aDelta[1][2]};
+    vtkFloatingPointType aPnt22[3] = {aPnt21[0] + aNormal[0],
+                                      aPnt21[1] + aNormal[1],
+                                      aPnt21[2] + aNormal[2]};
+    vtkPlane::IntersectWithLine(aPnt21,aPnt22,aNormal,anOrigin,aParam,aPnt2);
+
+    vtkPlaneSource* aPlaneSource = aPlane->myPlaneSource;
+    aPlaneSource->SetNormal(aNormal[0],aNormal[1],aNormal[2]);
+    aPlaneSource->SetOrigin(aPnt0[0],aPnt0[1],aPnt0[2]);
+    aPlaneSource->SetPoint1(aPnt1[0],aPnt1[1],aPnt1[2]);
+    aPlaneSource->SetPoint2(aPnt2[0],aPnt2[1],aPnt2[2]);
+  }
 
   if(AutoApplyCheckBox->isChecked())
     ClickOnApply();
 
-  SMESH::RenderViewWindow(SMESH::GetCurrentVtkView());
+  SMESH::RenderViewWindow( myViewWindow );
 }
 
 //=======================================================================
@@ -885,8 +1030,8 @@ void SMESHGUI_ClippingDlg::SetCurrentPlaneParam()
 //=======================================================================
 void SMESHGUI_ClippingDlg::OnPreviewToggle (bool theIsToggled)
 {
-  std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(theIsToggled));
-  SMESH::RenderViewWindow(SMESH::GetCurrentVtkView());
+  std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisibility(theIsToggled));
+  SMESH::RenderViewWindow( myViewWindow );
 }
 
 //=================================================================================
@@ -904,3 +1049,124 @@ void SMESHGUI_ClippingDlg::keyPressEvent( QKeyEvent* e )
     ClickOnHelp();
   }
 }
+
+//=================================================================================
+// function : initializePlaneData()
+// purpose  :
+//=================================================================================
+void SMESHGUI_ClippingDlg::initializePlaneData()
+{
+  const SMESHGUI_ClippingPlaneInfoMap& aClippingPlaneInfoMap = mySMESHGUI->getClippingPlaneInfoMap();
+  SMESHGUI_ClippingPlaneInfoMap::const_iterator anIter1 = aClippingPlaneInfoMap.find( myViewWindow->getViewManager() );
+  if( anIter1 != aClippingPlaneInfoMap.end() ) {
+    const SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = anIter1->second;
+    SMESHGUI_ClippingPlaneInfoList::const_iterator anIter2 = aClippingPlaneInfoList.begin();
+    for( ; anIter2 != aClippingPlaneInfoList.end(); anIter2++ ) {
+      const SMESH::ClippingPlaneInfo& aClippingPlaneInfo = *anIter2;
+      SMESH::TPlane aTPlane( aClippingPlaneInfo.Plane );
+      SMESH::TPlaneData aPlaneData( aTPlane, aClippingPlaneInfo.ActorList );
+      myPlanes.push_back( aPlaneData );
+    }
+  }
+  std::for_each( myPlanes.begin(),myPlanes.end(), TSetVisibility( PreviewCheckBox->isChecked() ) );
+}
+
+//=================================================================================
+// function : updateActorList()
+// purpose  :
+//=================================================================================
+void SMESHGUI_ClippingDlg::updateActorList()
+{
+  ActorList->clear();
+
+  SalomeApp_Study* anAppStudy = SMESHGUI::activeStudy();
+  if( !anAppStudy )
+    return;
+
+  _PTR(Study) aStudy = anAppStudy->studyDS();
+  if( !aStudy )
+    return;
+
+  if( !myViewWindow )
+    return;
+
+  int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
+  const SMESH::TPlaneData& aPlaneData = myPlanes[ aCurPlaneIndex ];
+  const SMESH::TActorList& anActorList = aPlaneData.ActorList;
+
+  VTK::ActorCollectionCopy aCopy( myViewWindow->getRenderer()->GetActors() );
+  vtkActorCollection* anAllActors = aCopy.GetActors();
+  anAllActors->InitTraversal();
+  while( vtkActor* aVTKActor = anAllActors->GetNextActor() ) {
+    if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) {
+      if( anActor->hasIO() ) {
+        Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
+        if( _PTR(SObject) aSObj = aStudy->FindObjectID( anIO->getEntry() ) ) {
+          bool anIsChecked = false;
+          SMESH::TActorList::const_iterator anIter = anActorList.begin();
+          for ( ; anIter != anActorList.end(); anIter++ ) {
+            if( vtkActor* aVTKActorRef = *anIter ) {
+              if( SMESH_Actor* anActorRef = SMESH_Actor::SafeDownCast( aVTKActorRef ) ) {
+                if( anActorRef == anActor ) {
+                  anIsChecked = true;
+                  break;
+                }
+              }
+            }
+          }
+          QString aName = QString( aSObj->GetName().c_str() );
+          QListWidgetItem* anItem = new ActorItem( anActor, aName, ActorList );
+          anItem->setCheckState( anIsChecked ? Qt::Checked : Qt::Unchecked );
+          updateActorItem( anItem, true, false );
+        }
+      }
+    }
+  }
+}
+
+//=================================================================================
+// function : getCurrentActors()
+// purpose  :
+//=================================================================================
+SMESH::TActorList SMESHGUI_ClippingDlg::getCurrentActors()
+{
+  SMESH::TActorList anActorList;
+  for( int i = 0, n = ActorList->count(); i < n; i++ )
+    if( ActorItem* anItem = dynamic_cast<ActorItem*>( ActorList->item( i ) ) )
+      if( anItem->checkState() == Qt::Checked )
+        if( SMESH_Actor* anActor = anItem->getActor() )
+          anActorList.push_back( anActor );
+  return anActorList;
+}
+
+//=================================================================================
+// function : dumpPlaneData()
+// purpose  :
+//=================================================================================
+void SMESHGUI_ClippingDlg::dumpPlaneData() const
+{
+  printf( "----------- Plane Data -----------\n" );
+  int anId = 1;
+  SMESH::TPlaneDataVector::const_iterator anIter1 = myPlanes.begin();
+  for ( ; anIter1 != myPlanes.end(); anIter1++, anId++ ) {
+    SMESH::TPlaneData aPlaneData = *anIter1;
+    SMESH::TPlane aPlane = aPlaneData.Plane;
+    vtkFloatingPointType* aNormal = aPlane->GetNormal();
+    vtkFloatingPointType* anOrigin = aPlane->GetOrigin();
+    printf( "Plane N%d:\n", anId );
+    printf( "  Normal = ( %f, %f, %f )\n", aNormal[0], aNormal[1], aNormal[2] );
+    printf( "  Origin = ( %f, %f, %f )\n", anOrigin[0], anOrigin[1], anOrigin[2] );
+
+    SMESH::TActorList anActorList = aPlaneData.ActorList;
+    SMESH::TActorList::const_iterator anIter2 = anActorList.begin();
+    for ( ; anIter2 != anActorList.end(); anIter2++ ) {
+      if( vtkActor* aVTKActor = *anIter2 ) {
+        if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) )
+          printf( "  - Actor: '%s'\n", anActor->getName() );
+      }
+      else
+        printf( "  - Actor: NULL\n");
+    }
+  }
+  printf( "----------------------------------\n" );
+}
index af9829762b20cf065cb3f82ef5f8a5e11171d918..70bd03b89e0a6ed407f0267aa93a4d08f932ac0c 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_ClippingDlg.h
 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
 
 // Qt includes
 #include <QDialog>
+#include <QPointer>
 
 // VTK includes
+#include <vtkPlane.h>
 #include <vtkSmartPointer.h>
 
 // STL includes
+#include <list>
+#include <map>
 #include <vector>
 
 class QLabel;
 class QPushButton;
 class QCheckBox;
 class QComboBox;
-class LightApp_SelectionMgr;
-class SVTK_Selector;
+class QListWidget;
+class QListWidgetItem;
+class SALOME_Actor;
 class SMESHGUI;
 class SMESH_Actor;
-class OrientedPlane;
 class SMESHGUI_SpinBox;
+class vtkActor;
+class vtkDataSetMapper;
+class vtkPlaneSource;
 
 namespace SMESH
 {
-  typedef vtkSmartPointer<OrientedPlane> TVTKPlane;
-  typedef std::vector<TVTKPlane> TPlanes;
   enum Orientation { XY, YZ, ZX };
-};
 
+  class OrientedPlane: public vtkPlane
+  {
+    QPointer<SVTK_ViewWindow> myViewWindow;
+    vtkDataSetMapper* myMapper;
+
+  public:
+    static OrientedPlane *New();
+    static OrientedPlane *New(SVTK_ViewWindow* theViewWindow);
+    vtkTypeMacro (OrientedPlane, vtkPlane);
+
+    SMESH::Orientation myOrientation;
+    float myDistance;
+    double myAngle[2];
+
+    vtkPlaneSource* myPlaneSource;
+    SALOME_Actor *myActor;
+
+    void SetOrientation (SMESH::Orientation theOrientation) { myOrientation = theOrientation; }
+    SMESH::Orientation GetOrientation() { return myOrientation; }
+
+    void SetDistance (float theDistance) { myDistance = theDistance; }
+    float GetDistance() { return myDistance; }
+
+    void ShallowCopy (OrientedPlane* theOrientedPlane);
+
+  protected:
+    OrientedPlane(SVTK_ViewWindow* theViewWindow);
+    OrientedPlane();
+
+    void Init();
+
+    ~OrientedPlane();
+  private:
+    // Not implemented.
+    OrientedPlane (const OrientedPlane&);
+    void operator= (const OrientedPlane&);
+  };
+
+  typedef vtkSmartPointer<OrientedPlane>    TPlane;
+  typedef std::list<vtkActor*>              TActorList;
+
+  struct TPlaneData
+  {
+    TPlaneData( TPlane thePlane,
+                TActorList theActorList )
+    {
+      Plane = thePlane;
+      ActorList = theActorList;
+    }
+    TPlane     Plane;
+    TActorList ActorList;
+  };
+
+  typedef std::vector<TPlane>               TPlaneVector;
+  typedef std::vector<TPlaneData>           TPlaneDataVector;
+};
 
 //=================================================================================
 // class    : SMESHGUI_ClippingDlg
@@ -69,7 +130,7 @@ class SMESHGUI_EXPORT SMESHGUI_ClippingDlg : public QDialog
   Q_OBJECT
 
 public:
-  SMESHGUI_ClippingDlg( SMESHGUI* );
+  SMESHGUI_ClippingDlg( SMESHGUI*, SVTK_ViewWindow* );
   ~SMESHGUI_ClippingDlg();
   
   double                  getDistance() const;
@@ -77,35 +138,42 @@ public:
   double                  getRotation1() const;
   double                  getRotation2() const;
   void                    setRotation( const double, const double );
-  void                    Sinchronize();
 
   // used in SMESHGUI::restoreVisualParameters() to avoid
   // declaration of OrientedPlane outside of SMESHGUI_ClippingDlg.cxx
-  static void             AddPlane (SMESH_Actor*         theActor,
-                                   SVTK_ViewWindow*     theViewWindow,
-                                   SMESH::Orientation   theOrientation,
-                                   double               theDistance,
-                                   vtkFloatingPointType theAngle[2]);
-
-  static void             GetPlaneParam (SMESH_Actor*          theActor,
-                                        int                   thePlaneIndex,
-                                        SMESH::Orientation&   theOrientation,
-                                        double&               theDistance,
-                                        vtkFloatingPointType* theAngle);
+  static SMESH::OrientedPlane* AddPlane (SMESH::TActorList          theActorList,
+                                         SVTK_ViewWindow*           theViewWindow,
+                                         SMESH::Orientation         theOrientation,
+                                         double                     theDistance,
+                                         const vtkFloatingPointType theAngle[2]);
 
 protected:  
   void                    keyPressEvent( QKeyEvent* );
 
 private:
-  LightApp_SelectionMgr*  mySelectionMgr;
-  SVTK_Selector*          mySelector;
+  void                    initializePlaneData();
+
+  void                    synchronize();
+
+  void                    updateActorList();
+  SMESH::TActorList       getCurrentActors();
+
+  void                    updateActorItem( QListWidgetItem* theItem,
+                                           bool theUpdateSelectAll,
+                                           bool theUpdateClippingPlaneMap );
+
+  void                    dumpPlaneData() const;
+
+private:
   SMESHGUI*               mySMESHGUI;
-  SMESH_Actor*            myActor;
-  SMESH::TPlanes          myPlanes;
+  SVTK_ViewWindow*        myViewWindow;
+  SMESH::TPlaneDataVector myPlanes;
   
   QComboBox*              ComboBoxPlanes;
   QPushButton*            buttonNew;
   QPushButton*            buttonDelete;
+  QListWidget*            ActorList;
+  QCheckBox*              SelectAllCheckBox;
   QLabel*                 TextLabelOrientation;
   QComboBox*              ComboBoxOrientation;
   QLabel*                 TextLabelDistance;
@@ -128,9 +196,10 @@ public slots:
   void                    onSelectPlane( int );
   void                    ClickOnNew();
   void                    ClickOnDelete();
+  void                    onActorItemChanged( QListWidgetItem* );
+  void                    onSelectAll( int );
   void                    onSelectOrientation( int );
   void                    SetCurrentPlaneParam();
-  void                    onSelectionChanged();
   void                    OnPreviewToggle( bool );
   void                    ClickOnOk();
   void                    ClickOnCancel();
index 147a6a46403c70757003e42ea855c45e591584f8..0bb2fa5ef2bac0a06e1fdafb4cbc706ef3229c52 100644 (file)
@@ -1,24 +1,22 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  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 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.
 //
-//  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
 //
-//  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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : SMESHGUI_ComputeDlg.cxx
 // Author : Edward AGAPOV, Open CASCADE S.A.S.
 // SMESH includes
 #include "SMESHGUI_GEOMGenUtils.h"
 #include "SMESHGUI_MeshUtils.h"
 #include "SMESHGUI_VTKUtils.h"
+#include "SMESHGUI_MeshInfosBox.h"
 #include "SMESHGUI_HypothesesUtils.h"
 #include "SMESHGUI_MeshEditPreview.h"
+#include "SMESHGUI_MeshOrderOp.h"
+#include "SMESHGUI_MeshOrderDlg.h"
+
 #include "SMESH_ActorUtils.h"
 
 #include <SMDS_SetIterator.hxx>
@@ -83,6 +85,8 @@
 #include <QHBoxLayout>
 #include <QVBoxLayout>
 #include <QButtonGroup>
+#include <QCloseEvent>
+#include <QTimerEvent>
 
 // VTK includes
 #include <vtkProperty.h>
 
 #define COLONIZE(str)   (QString(str).contains(":") > 0 ? QString(str) : QString(str) + " :" )
 
+/* OBSOLETE
 static void addSeparator( QWidget* parent )
 {
   QGridLayout* l = qobject_cast<QGridLayout*>( parent->layout() );
@@ -107,6 +112,7 @@ static void addSeparator( QWidget* parent )
     l->addWidget( hline, row, i );
   }
 }
+*/
 
 enum TCol {
   COL_ALGO = 0, COL_SHAPE, COL_ERROR, COL_SHAPEID, COL_PUBLISHED, COL_BAD_MESH, NB_COLUMNS
@@ -339,10 +345,13 @@ namespace SMESH
       CASE2TEXT( COMPERR_EXCEPTION     );
       CASE2TEXT( COMPERR_MEMORY_PB     );
       CASE2TEXT( COMPERR_BAD_SHAPE     );
+      CASE2TEXT( COMPERR_CANCELED      );
     case SMESH::COMPERR_ALGO_FAILED:
       if ( strlen(comment) == 0 )
         text = QObject::tr("COMPERR_ALGO_FAILED");
       break;
+    case SMESH::COMPERR_WARNING:
+      return comment ? QString(comment) : QObject::tr("COMPERR_UNKNOWN");
     default:
       text = QString("#%1").arg( -errCode );
     }
@@ -351,7 +360,7 @@ namespace SMESH
   }
   // -----------------------------------------------------------------------
   /*!
-   * \brief Return SO of a subshape
+   * \brief Return SO of a sub-shape
    */
   _PTR(SObject) getSubShapeSO( int subShapeID, GEOM::GEOM_Object_var aMainShape)
   {
@@ -376,7 +385,7 @@ namespace SMESH
   }
   // -----------------------------------------------------------------------
   /*!
-   * \brief Return subshape by ID
+   * \brief Return sub-shape by ID
    */
   GEOM::GEOM_Object_ptr getSubShape( int subShapeID, GEOM::GEOM_Object_var aMainShape)
   {
@@ -414,7 +423,7 @@ namespace SMESH
   }
   // -----------------------------------------------------------------------
   /*!
-   * \brief Return text describing a subshape
+   * \brief Return text describing a sub-shape
    */
   QString shapeText(int subShapeID, GEOM::GEOM_Object_var aMainShape )
   {
@@ -452,351 +461,20 @@ namespace SMESH
 } // namespace SMESH
 
 
-// =========================================================================================
-/*!
- * \brief Box showing mesh info
- */
-// =========================================================================================
-
-SMESHGUI_MeshInfosBox::SMESHGUI_MeshInfosBox(const bool full, QWidget* theParent)
-  : QGroupBox( tr("SMESH_MESHINFO_TITLE"), theParent ), myFull( full )
-{
-  QGridLayout* l = new QGridLayout(this);
-  l->setMargin( MARGIN );
-  l->setSpacing( SPACING );
-
-  QFont italic = font(); italic.setItalic(true);
-  QFont bold   = font(); bold.setBold(true);
-
-  QLabel* lab;
-  int row = 0;
-
-  // title
-  lab = new QLabel( this );
-  lab->setMinimumWidth(100); lab->setFont( italic );
-  l->addWidget( lab, row, 0 );
-  // --
-  lab = new QLabel(tr("SMESH_MESHINFO_ORDER0"), this );
-  lab->setMinimumWidth(100); lab->setFont( italic );
-  l->addWidget( lab, row, 1 );
-  // --
-  lab = new QLabel(tr("SMESH_MESHINFO_ORDER1"), this );
-  lab->setMinimumWidth(100); lab->setFont( italic );
-  l->addWidget( lab, row, 2 );
-  // --
-  lab = new QLabel(tr("SMESH_MESHINFO_ORDER2"), this );
-  lab->setMinimumWidth(100); lab->setFont( italic );
-  l->addWidget( lab, row, 3 );
-
-  if ( myFull )
-  {
-    // nodes
-    row = l->rowCount();         // retrieve current row count
-    // --
-    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_NODES")), this );
-    lab->setFont( bold );
-    l->addWidget( lab,           row, 0 );
-    // --
-    myNbNode = new QLabel( this );
-    l->addWidget( myNbNode,      row, 1 );
-
-    addSeparator(this);          // add separator
-
-    // edges
-    row = l->rowCount();         // retrieve current row count
-    // --
-    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_EDGES")), this );
-    lab->setFont( bold );
-    l->addWidget( lab,           row, 0 );
-    // --
-    myNbEdge = new QLabel( this );
-    l->addWidget( myNbEdge,      row, 1 );
-    // --
-    myNbLinEdge = new QLabel( this );
-    l->addWidget( myNbLinEdge,   row, 2 );
-    // --
-    myNbQuadEdge = new QLabel( this );
-    l->addWidget( myNbQuadEdge,  row, 3 );
-
-    addSeparator(this);          // add separator
-
-    // faces
-    row = l->rowCount();         // retrieve current row count
-    // --
-    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_FACES")), this);
-    lab->setFont( bold );
-    l->addWidget( lab,           row, 0 );
-    // --
-    myNbFace     = new QLabel( this );
-    l->addWidget( myNbFace,      row, 1 );
-    // --
-    myNbLinFace  = new QLabel( this );
-    l->addWidget( myNbLinFace,   row, 2 );
-    // --
-    myNbQuadFace = new QLabel( this );
-    l->addWidget( myNbQuadFace,  row, 3 );
-    // --
-    row++;                       // increment row count
-    // ... triangles
-    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_TRIANGLES")), this );
-    l->addWidget( lab,           row, 0 );
-    // --
-    myNbTrai     = new QLabel( this );
-    l->addWidget( myNbTrai,      row, 1 );
-    // --
-    myNbLinTrai  = new QLabel( this );
-    l->addWidget( myNbLinTrai,   row, 2 );
-    // --
-    myNbQuadTrai = new QLabel( this );
-    l->addWidget( myNbQuadTrai,  row, 3 );
-    // --
-    row++;                       // increment row count
-    // ... quadrangles
-    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_QUADRANGLES")), this );
-    l->addWidget( lab,           row, 0 );
-    // --
-    myNbQuad     = new QLabel( this );
-    l->addWidget( myNbQuad,      row, 1 );
-    // --
-    myNbLinQuad  = new QLabel( this );
-    l->addWidget( myNbLinQuad,   row, 2 );
-    // --
-    myNbQuadQuad = new QLabel( this );
-    l->addWidget( myNbQuadQuad,  row, 3 );
-    // --
-    row++;                       // increment row count
-    // ... poligones
-    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_POLYGONES")), this );
-    l->addWidget( lab,           row, 0 );
-    myNbPolyg    = new QLabel( this );
-    l->addWidget( myNbPolyg,     row, 1 );
-
-    addSeparator(this);          // add separator
-
-    // volumes
-    row = l->rowCount();         // retrieve current row count
-    // --
-    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_VOLUMES")), this);
-    lab->setFont( bold );
-    l->addWidget( lab,           row, 0 );
-    // --
-    myNbVolum     = new QLabel( this );
-    l->addWidget( myNbVolum,     row, 1 );
-    // --
-    myNbLinVolum  = new QLabel( this );
-    l->addWidget( myNbLinVolum,  row, 2 );
-    // --
-    myNbQuadVolum = new QLabel( this );
-    l->addWidget( myNbQuadVolum, row, 3 );
-    // --
-    row++;                       // increment row count
-    // ... tetras
-    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_TETRAS")), this );
-    l->addWidget( lab,           row, 0 );
-    // --
-    myNbTetra     = new QLabel( this );
-    l->addWidget( myNbTetra,     row, 1 );
-    // --
-    myNbLinTetra  = new QLabel( this );
-    l->addWidget( myNbLinTetra,  row, 2 );
-    // --
-    myNbQuadTetra = new QLabel( this );
-    l->addWidget( myNbQuadTetra, row, 3 );
-    // --
-    row++;                       // increment row count
-    // ... hexas
-    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_HEXAS")), this );
-    l->addWidget( lab,           row, 0 );
-    // --
-    myNbHexa      = new QLabel( this );
-    l->addWidget( myNbHexa,      row, 1 );
-    // --
-    myNbLinHexa   = new QLabel( this );
-    l->addWidget( myNbLinHexa,   row, 2 );
-    // --
-    myNbQuadHexa  = new QLabel( this );
-    l->addWidget( myNbQuadHexa,  row, 3 );
-    // --
-    row++;                       // increment row count
-    // ... pyras
-    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_PYRAS")), this );
-    l->addWidget( lab,           row, 0 );
-    // --
-    myNbPyra      = new QLabel( this );
-    l->addWidget( myNbPyra,      row, 1 );
-    // --
-    myNbLinPyra   = new QLabel( this );
-    l->addWidget( myNbLinPyra,   row, 2 );
-    // --
-    myNbQuadPyra  = new QLabel( this );
-    l->addWidget( myNbQuadPyra,  row, 3 );
-    // --
-    row++;                       // increment row count
-    // ... prisms
-    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_PRISMS")), this );
-    l->addWidget( lab,           row, 0 );
-    // --
-    myNbPrism     = new QLabel( this );
-    l->addWidget( myNbPrism,     row, 1 );
-    // --
-    myNbLinPrism  = new QLabel( this );
-    l->addWidget( myNbLinPrism,  row, 2 );
-    // --
-    myNbQuadPrism = new QLabel( this );
-    l->addWidget( myNbQuadPrism, row, 3 );
-    // --
-    row++;                       // increment row count
-    // ... polyedres
-    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_POLYEDRES")), this );
-    l->addWidget( lab,           row, 0 );
-    // --
-    myNbPolyh     = new QLabel( this );
-    l->addWidget( myNbPolyh,     row, 1 );
-  }
-  else
-  {
-    // nodes
-    row = l->rowCount();         // retrieve current row count
-    // --
-    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_NODES")), this );
-    l->addWidget( lab,           row, 0 );
-    // --
-    myNbNode      = new QLabel( this );
-    l->addWidget( myNbNode,      row, 1 );
-
-    // edges
-    row = l->rowCount();         // retrieve current row count
-    // --
-    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_EDGES")), this );
-    l->addWidget( lab,           row, 0 );
-    // --
-    myNbEdge      = new QLabel( this );
-    l->addWidget( myNbEdge,      row, 1 );
-    // --
-    myNbLinEdge   = new QLabel( this );
-    l->addWidget( myNbLinEdge,   row, 2 );
-    // --
-    myNbQuadEdge  = new QLabel( this );
-    l->addWidget( myNbQuadEdge,  row, 3 );
-
-    // faces
-    row = l->rowCount();         // retrieve current row count
-    // --
-    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_FACES")), this);
-    l->addWidget( lab,           row, 0 );
-    // --
-    myNbFace      = new QLabel( this );
-    l->addWidget( myNbFace,      row, 1 );
-    // --
-    myNbLinFace   = new QLabel( this );
-    l->addWidget( myNbLinFace,   row, 2 );
-    // --
-    myNbQuadFace  = new QLabel( this );
-    l->addWidget( myNbQuadFace,  row, 3 );
-
-    // volumes
-    row = l->rowCount();         // retrieve current row count
-    // --
-    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_VOLUMES")), this);
-    l->addWidget( lab,           row, 0 );
-    // --
-    myNbVolum     = new QLabel( this );
-    l->addWidget( myNbVolum,     row, 1 );
-    // --
-    myNbLinVolum  = new QLabel( this );
-    l->addWidget( myNbLinVolum,  row, 2 );
-    // --
-    myNbQuadVolum = new QLabel( this );
-    l->addWidget( myNbQuadVolum, row, 3 );
-  }
-}
-
-// =========================================================================================
-/*!
- * \brief Set mesh info
- */
-// =========================================================================================
-
-void SMESHGUI_MeshInfosBox::SetInfoByMesh(SMESH::SMESH_Mesh_var mesh)
-{
-  const SMESH::ElementOrder lin = SMESH::ORDER_LINEAR;
-  int nbTot, nbLin;
-
-  // nodes
-  myNbNode     ->setText( QString("%1").arg( mesh->NbNodes() ));
-
-  // edges
-  nbTot = mesh->NbEdges(), nbLin = mesh->NbEdgesOfOrder(lin);
-  myNbEdge     ->setText( QString("%1").arg( nbTot ));
-  myNbLinEdge  ->setText( QString("%1").arg( nbLin ));
-  myNbQuadEdge ->setText( QString("%1").arg( nbTot - nbLin ));
-
-  // faces
-  nbTot = mesh->NbFaces(), nbLin = mesh->NbFacesOfOrder(lin);
-  myNbFace     ->setText( QString("%1").arg( nbTot ));
-  myNbLinFace  ->setText( QString("%1").arg( nbLin ));
-  myNbQuadFace ->setText( QString("%1").arg( nbTot - nbLin ));
-
-  // volumes
-  nbTot = mesh->NbVolumes(), nbLin = mesh->NbVolumesOfOrder(lin);
-  myNbVolum    ->setText( QString("%1").arg( nbTot ));
-  myNbLinVolum ->setText( QString("%1").arg( nbLin ));
-  myNbQuadVolum->setText( QString("%1").arg( nbTot - nbLin ));
-
-  if ( myFull )
-  {
-    // triangles
-    nbTot = mesh->NbTriangles(), nbLin = mesh->NbTrianglesOfOrder(lin);
-    myNbTrai     ->setText( QString("%1").arg( nbTot ));
-    myNbLinTrai  ->setText( QString("%1").arg( nbLin ));
-    myNbQuadTrai ->setText( QString("%1").arg( nbTot - nbLin ));
-    // quadrangles
-    nbTot = mesh->NbQuadrangles(), nbLin = mesh->NbQuadranglesOfOrder(lin);
-    myNbQuad     ->setText( QString("%1").arg( nbTot ));
-    myNbLinQuad  ->setText( QString("%1").arg( nbLin ));
-    myNbQuadQuad ->setText( QString("%1").arg( nbTot - nbLin ));
-    // poligones
-    myNbPolyg    ->setText( QString("%1").arg( mesh->NbPolygons() ));
-
-    // tetras
-    nbTot = mesh->NbTetras(), nbLin = mesh->NbTetrasOfOrder(lin);
-    myNbTetra    ->setText( QString("%1").arg( nbTot ));
-    myNbLinTetra ->setText( QString("%1").arg( nbLin ));
-    myNbQuadTetra->setText( QString("%1").arg( nbTot - nbLin ));
-    // hexas
-    nbTot = mesh->NbHexas(), nbLin = mesh->NbHexasOfOrder(lin);
-    myNbHexa     ->setText( QString("%1").arg( nbTot ));
-    myNbLinHexa  ->setText( QString("%1").arg( nbLin ));
-    myNbQuadHexa ->setText( QString("%1").arg( nbTot - nbLin ));
-    // pyras
-    nbTot = mesh->NbPyramids(), nbLin = mesh->NbPyramidsOfOrder(lin);
-    myNbPyra     ->setText( QString("%1").arg( nbTot ));
-    myNbLinPyra  ->setText( QString("%1").arg( nbLin ));
-    myNbQuadPyra ->setText( QString("%1").arg( nbTot - nbLin ));
-    // prisms
-    nbTot = mesh->NbPrisms(), nbLin = mesh->NbPrismsOfOrder(lin);
-    myNbPrism    ->setText( QString("%1").arg( nbTot ));
-    myNbLinPrism ->setText( QString("%1").arg( nbLin ));
-    myNbQuadPrism->setText( QString("%1").arg( nbTot - nbLin ));
-    // polyedres
-    myNbPolyh    ->setText( QString("%1").arg( mesh->NbPolyhedrons() ));
-  }
-}
-
 // =========================================================================================
 /*!
  * \brief Dialog to compute a mesh and show computation errors
  */
 //=======================================================================
 
-SMESHGUI_ComputeDlg::SMESHGUI_ComputeDlg( QWidget* parent )
+SMESHGUI_ComputeDlg::SMESHGUI_ComputeDlg( QWidget* parent, bool ForEval )
  : SMESHGUI_Dialog( parent, false, true, Close/* | Help*/ )
 {
   QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame());
   aDlgLay->setMargin( 0 );
   aDlgLay->setSpacing( SPACING );
 
-  QFrame* aMainFrame = createMainFrame  (mainFrame());
+  QFrame* aMainFrame = createMainFrame(mainFrame(),ForEval);
 
   aDlgLay->addWidget(aMainFrame);
 
@@ -818,7 +496,7 @@ SMESHGUI_ComputeDlg::~SMESHGUI_ComputeDlg()
 // purpose  : Create frame containing dialog's fields
 //=======================================================================
 
-QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent)
+QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent, bool ForEval)
 {
   QFrame* aFrame = new QFrame(theParent);
 
@@ -827,7 +505,13 @@ QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent)
 
   // constructor
 
-  QGroupBox* aPixGrp = new QGroupBox(tr("CONSTRUCTOR"), aFrame);
+  QGroupBox* aPixGrp;
+  if(ForEval) {
+    aPixGrp = new QGroupBox(tr("EVAL_DLG"), aFrame);
+  }
+  else {
+    aPixGrp = new QGroupBox(tr("CONSTRUCTOR"), aFrame);
+  }
   QButtonGroup* aBtnGrp = new QButtonGroup(this);
   QHBoxLayout* aPixGrpLayout = new QHBoxLayout(aPixGrp);
   aPixGrpLayout->setMargin(MARGIN); aPixGrpLayout->setSpacing(SPACING);
@@ -854,10 +538,11 @@ QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent)
   // Computation errors
 
   myCompErrorGroup = new QGroupBox(tr("ERRORS"), aFrame);
-  myTable      = new QTableWidget( 1, NB_COLUMNS, myCompErrorGroup);
-  myShowBtn    = new QPushButton(tr("SHOW_SHAPE"), myCompErrorGroup);
-  myPublishBtn = new QPushButton(tr("PUBLISH_SHAPE"), myCompErrorGroup);
-  myBadMeshBtn = new QPushButton(tr("SHOW_BAD_MESH"), myCompErrorGroup);
+  myWarningLabel = new QLabel(QString("<b>%1</b>").arg(tr("COMPUTE_WARNING")), myCompErrorGroup);
+  myTable        = new QTableWidget( 1, NB_COLUMNS, myCompErrorGroup);
+  myShowBtn      = new QPushButton(tr("SHOW_SHAPE"), myCompErrorGroup);
+  myPublishBtn   = new QPushButton(tr("PUBLISH_SHAPE"), myCompErrorGroup);
+  myBadMeshBtn   = new QPushButton(tr("SHOW_BAD_MESH"), myCompErrorGroup);
 
   //myTable->setReadOnly( true ); // VSR: check
   myTable->setEditTriggers( QAbstractItemView::NoEditTriggers );
@@ -879,11 +564,12 @@ QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent)
   QGridLayout* grpLayout = new QGridLayout(myCompErrorGroup);
   grpLayout->setSpacing(SPACING);
   grpLayout->setMargin(MARGIN);
-  grpLayout->addWidget( myTable,      0, 0, 4, 1 );
-  grpLayout->addWidget( myShowBtn,    0, 1 );
-  grpLayout->addWidget( myPublishBtn, 1, 1 );
-  grpLayout->addWidget( myBadMeshBtn, 2, 1 );
-  grpLayout->setRowStretch( 3, 1 );
+  grpLayout->addWidget( myWarningLabel, 0, 0 );
+  grpLayout->addWidget( myTable,        1, 0, 4, 1 );
+  grpLayout->addWidget( myShowBtn,      1, 1 );
+  grpLayout->addWidget( myPublishBtn,   2, 1 );
+  grpLayout->addWidget( myBadMeshBtn,   3, 1 );
+  grpLayout->setRowStretch( 4, 1 );
 
   // Hypothesis definition errors
 
@@ -931,8 +617,7 @@ QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent)
 //================================================================================
 
 SMESHGUI_BaseComputeOp::SMESHGUI_BaseComputeOp()
-  : SMESHGUI_Operation(),
-    myCompDlg( 0 )
+  : SMESHGUI_Operation(), myCompDlg( 0 )
 {
   myTShapeDisplayer = new SMESH::TShapeDisplayer();
   myBadMeshDisplayer = 0;
@@ -941,6 +626,15 @@ SMESHGUI_BaseComputeOp::SMESHGUI_BaseComputeOp()
   myHelpFileName = "about_meshes_page.html"; // V4
 }
 
+SMESH::SMESH_Mesh_ptr SMESHGUI_BaseComputeOp::getMesh()
+{
+  LightApp_SelectionMgr* Sel = selectionMgr();
+  SALOME_ListIO selected; Sel->selectedObjects( selected );
+  Handle(SALOME_InteractiveObject) anIO = selected.First();
+  SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(anIO);
+  return myMesh->_is_nil() ? aMesh._retn() : SMESH::SMESH_Mesh::_duplicate( myMesh );
+}
+
 //================================================================================
 /*!
  * \brief Start operation
@@ -963,8 +657,8 @@ void SMESHGUI_BaseComputeOp::startOperation()
   int nbSel = selected.Extent();
   if (nbSel != 1) {
     SUIT_MessageBox::warning(desktop(),
-                            tr("SMESH_WRN_WARNING"),
-                            tr("SMESH_WRN_NO_AVAILABLE_DATA"));
+                             tr("SMESH_WRN_WARNING"),
+                             tr("SMESH_WRN_NO_AVAILABLE_DATA"));
     onCancel();
     return;
   }
@@ -973,16 +667,97 @@ void SMESHGUI_BaseComputeOp::startOperation()
   myMesh = SMESH::GetMeshByIO(myIObject);
   if (myMesh->_is_nil()) {
     SUIT_MessageBox::warning(desktop(),
-                            tr("SMESH_WRN_WARNING"),
-                            tr("SMESH_WRN_NO_AVAILABLE_DATA"));
+                             tr("SMESH_WRN_WARNING"),
+                             tr("SMESH_WRN_NO_AVAILABLE_DATA"));
     onCancel();
-
+    return;
   }
   myMainShape = myMesh->GetShapeToMesh();
 
   SMESHGUI_Operation::startOperation();
 }
 
+//================================================================================
+//================================================================================
+
+SMESHGUI_ComputeDlg_QThread::SMESHGUI_ComputeDlg_QThread(SMESH::SMESH_Gen_var gen,
+                                                         SMESH::SMESH_Mesh_var mesh,
+                                                         GEOM::GEOM_Object_var mainShape)
+{
+  myResult = false;
+  myGen = gen;
+  myMesh = mesh;
+  myMainShape = mainShape;
+}
+
+void SMESHGUI_ComputeDlg_QThread::run()
+{
+  myResult = myGen->Compute(myMesh, myMainShape);
+}
+
+bool SMESHGUI_ComputeDlg_QThread::result()
+{
+  return myResult;
+}
+
+void SMESHGUI_ComputeDlg_QThread::cancel()
+{
+  myGen->CancelCompute(myMesh, myMainShape);
+}
+
+//================================================================================
+//================================================================================
+
+SMESHGUI_ComputeDlg_QThreadQDialog::SMESHGUI_ComputeDlg_QThreadQDialog(QWidget *parent,
+                                                                       SMESH::SMESH_Gen_var gen,
+                                                                       SMESH::SMESH_Mesh_var mesh,
+                                                                       GEOM::GEOM_Object_var mainShape)
+  : QDialog(parent),
+    qthread(gen, mesh, mainShape)
+{
+  // --
+  setWindowTitle(tr("Compute"));
+  cancelButton = new QPushButton(tr("Cancel"));
+  cancelButton->setDefault(true);
+  connect(cancelButton, SIGNAL(clicked()), this, SLOT(onCancel()));
+  QHBoxLayout *layout = new QHBoxLayout;
+  layout->addWidget(cancelButton);
+  setLayout(layout);
+  resize(200, 50);
+  // --
+  startTimer(30); // 30 millisecs
+  qthread.start();
+}
+
+bool SMESHGUI_ComputeDlg_QThreadQDialog::result()
+{
+  return qthread.result();
+}
+
+void SMESHGUI_ComputeDlg_QThreadQDialog::onCancel()
+{
+  qthread.cancel();
+}  
+
+void SMESHGUI_ComputeDlg_QThreadQDialog::timerEvent(QTimerEvent *event)
+{
+  if(qthread.isFinished())
+    {
+      close();
+    }
+  event->accept();
+}
+
+void SMESHGUI_ComputeDlg_QThreadQDialog::closeEvent(QCloseEvent *event)
+{
+  if(qthread.isRunning())
+    {
+      event->ignore();
+      return;
+    }
+  event->accept();
+}
+
 //================================================================================
 /*!
  * \brief computeMesh()
@@ -1001,9 +776,11 @@ void SMESHGUI_BaseComputeOp::computeMesh()
   bool computeFailed = true, memoryLack = false;
 
   _PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh);
+  if ( !aMeshSObj ) // IPAL 21340
+    return;
   bool hasShape = myMesh->HasShapeToMesh();
   bool shapeOK = myMainShape->_is_nil() ? !hasShape : hasShape;
-  if ( shapeOK && aMeshSObj )
+  if ( shapeOK )
   {
     myCompDlg->myMeshName->setText( aMeshSObj->GetName().c_str() );
     SMESH::SMESH_Gen_var gen = getSMESHGUI()->GetSMESHGen();
@@ -1011,12 +788,26 @@ void SMESHGUI_BaseComputeOp::computeMesh()
     if ( errors->length() > 0 ) {
       aHypErrors = SMESH::GetMessageOnAlgoStateErrors( errors.in() );
     }
+    if ( myMesh->HasModificationsToDiscard() && // issue 0020693
+         SUIT_MessageBox::question( desktop(), tr( "SMESH_WARNING" ),
+                                    tr( "FULL_RECOMPUTE_QUESTION" ),
+                                    tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 1, 0 ) == 0 )
+      myMesh->Clear();
     SUIT_OverrideCursor aWaitCursor;
     try {
 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
       OCC_CATCH_SIGNALS;
 #endif
-      if (gen->Compute(myMesh, myMainShape))
+      //SMESH::UpdateNulData(myIObject, true);
+      bool res;
+#ifdef WITH_SMESH_CANCEL_COMPUTE
+      SMESHGUI_ComputeDlg_QThreadQDialog qthreaddialog(desktop(), gen, myMesh, myMainShape);
+      qthreaddialog.exec();
+      res = qthreaddialog.result();
+#else
+      res = gen->Compute(myMesh, myMainShape);
+#endif
+      if (res)
         computeFailed = false;
     }
     catch(const SALOME::SALOME_Exception & S_ex){
@@ -1035,6 +826,10 @@ void SMESHGUI_BaseComputeOp::computeMesh()
       memoryLack = true;
     }
 
+    if ( !memoryLack && !SMDS_Mesh::CheckMemory(true) ) { // has memory to show dialog boxes?
+      memoryLack = true;
+    }
+
     // NPAL16631: if ( !memoryLack )
     {
       SMESH::ModifiedMesh(aMeshSObj, !computeFailed, myMesh->NbNodes() == 0);
@@ -1042,32 +837,45 @@ void SMESHGUI_BaseComputeOp::computeMesh()
 
       // SHOW MESH
       // NPAL16631: if ( getSMESHGUI()->automaticUpdate() )
-      if ( !memoryLack && getSMESHGUI()->automaticUpdate() )
+      SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( SMESHGUI::GetSMESHGUI() );
+      long newSize = myMesh->NbElements();
+      bool limitExceeded;
+      if ( !memoryLack )
       {
-        try {
+        if ( getSMESHGUI()->automaticUpdate( newSize, &limitExceeded ) )
+        {
+          try {
 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
-          OCC_CATCH_SIGNALS;
+            OCC_CATCH_SIGNALS;
 #endif
-          SMESH::Update(myIObject, true);
-        }
-        catch (...) {
+            SMESH::Update(myIObject, true);
+          }
+          catch (...) {
 #ifdef _DEBUG_
-          MESSAGE ( "Exception thrown during mesh visualization" );
+            MESSAGE ( "Exception thrown during mesh visualization" );
 #endif
-          if ( SMDS_Mesh::CheckMemory(true) ) { // has memory to show warning?
-            SMESH::OnVisuException();
-          }
-          else {
-            memoryLack = true;
+            if ( SMDS_Mesh::CheckMemory(true) ) { // has memory to show warning?
+              SMESH::OnVisuException();
+            }
+            else {
+              memoryLack = true;
+            }
           }
         }
+        else if ( limitExceeded )
+        {
+          long limitSize = resMgr->integerValue( "SMESH", "update_limit", 500000 );
+          SUIT_MessageBox::warning( desktop(),
+                                    tr( "SMESH_WRN_WARNING" ),
+                                    tr( "SMESH_WRN_SIZE_LIMIT_EXCEEDED" ).arg( newSize ).arg( limitSize ) );
+        }
       }
       LightApp_SelectionMgr *Sel = selectionMgr();
       if ( Sel )
       {
-       SALOME_ListIO selected;
-       selected.Append( myIObject );
-       Sel->setSelectedObjects( selected );
+        SALOME_ListIO selected;
+        selected.Append( myIObject );
+        Sel->setSelectedObjects( selected );
       }
     }
   }
@@ -1110,10 +918,10 @@ void SMESHGUI_BaseComputeOp::computeMesh()
 }
 
 void SMESHGUI_BaseComputeOp::showComputeResult( const bool theMemoryLack,
-                                               const bool theNoCompError,
-                                               SMESH::compute_error_array_var& theCompErrors,
-                                               const bool     theNoHypoError,
-                                               const QString& theHypErrors )
+                                                const bool theNoCompError,
+                                                SMESH::compute_error_array_var& theCompErrors,
+                                                const bool theNoHypoError,
+                                                const QString& theHypErrors )
 {
   bool hasShape = myMesh->HasShapeToMesh();
   SMESHGUI_ComputeDlg* aCompDlg = computeDlg();
@@ -1129,7 +937,8 @@ void SMESHGUI_BaseComputeOp::showComputeResult( const bool theMemoryLack,
   }
   else if ( theNoCompError && theNoHypoError )
   {
-    aCompDlg->myFullInfo->SetInfoByMesh( myMesh );
+    SMESH::long_array_var aRes = myMesh->GetMeshInfo();
+    aCompDlg->myFullInfo->SetMeshInfo( aRes );
     aCompDlg->myFullInfo->show();
     aCompDlg->myBriefInfo->hide();
     aCompDlg->myHypErrorGroup->hide();
@@ -1137,25 +946,44 @@ void SMESHGUI_BaseComputeOp::showComputeResult( const bool theMemoryLack,
   }
   else
   {
-    QTableWidget* tbl = aCompDlg->myTable;
-    aCompDlg->myBriefInfo->SetInfoByMesh( myMesh );
-    aCompDlg->myBriefInfo->show();
-    aCompDlg->myFullInfo->hide();
+    bool onlyWarnings = !theNoCompError; // == valid mesh computed but there are errors reported
+    for ( int i = 0; i < theCompErrors->length() && onlyWarnings; ++i )
+      onlyWarnings = ( theCompErrors[ i ].code == SMESH::COMPERR_WARNING );
+
+    // full or brief mesh info
+    SMESH::long_array_var aRes = myMesh->GetMeshInfo();
+    if ( onlyWarnings ) {
+      aCompDlg->myFullInfo->SetMeshInfo( aRes );
+      aCompDlg->myFullInfo->show();
+      aCompDlg->myBriefInfo->hide();
+    } else {
+      aCompDlg->myBriefInfo->SetMeshInfo( aRes );
+      aCompDlg->myBriefInfo->show();
+      aCompDlg->myFullInfo->hide();
+    }
 
+    // pbs of hypo dfinitions
     if ( theNoHypoError ) {
       aCompDlg->myHypErrorGroup->hide();
-    }
-    else {
+    } else {
       aCompDlg->myHypErrorGroup->show();
       aCompDlg->myHypErrorLabel->setText( theHypErrors );
     }
 
-    if ( theNoCompError ) {
+    // table of errors
+    if ( theNoCompError )
+    {
       aCompDlg->myCompErrorGroup->hide();
     }
-    else {
+    else
+    {
       aCompDlg->myCompErrorGroup->show();
 
+      if ( onlyWarnings )
+        aCompDlg->myWarningLabel->show();
+      else
+        aCompDlg->myWarningLabel->hide();
+
       if ( !hasShape ) {
         aCompDlg->myPublishBtn->hide();
         aCompDlg->myShowBtn->hide();
@@ -1166,6 +994,7 @@ void SMESHGUI_BaseComputeOp::showComputeResult( const bool theMemoryLack,
       }
 
       // fill table of errors
+      QTableWidget* tbl = aCompDlg->myTable;
       tbl->setRowCount( theCompErrors->length() );
       if ( !hasShape ) tbl->hideColumn( COL_SHAPE );
       else             tbl->showColumn( COL_SHAPE );
@@ -1176,29 +1005,29 @@ void SMESHGUI_BaseComputeOp::showComputeResult( const bool theMemoryLack,
       {
         SMESH::ComputeError & err = theCompErrors[ row ];
 
-       QString text = err.algoName.in();
-       if ( !tbl->item( row, COL_ALGO ) ) tbl->setItem( row, COL_ALGO, new QTableWidgetItem( text ) );
-       else tbl->item( row, COL_ALGO )->setText( text );
+        QString text = err.algoName.in();
+        if ( !tbl->item( row, COL_ALGO ) ) tbl->setItem( row, COL_ALGO, new QTableWidgetItem( text ) );
+        else tbl->item( row, COL_ALGO )->setText( text );
 
-       text = SMESH::errorText( err.code, err.comment.in() );
-       if ( !tbl->item( row, COL_ERROR ) ) tbl->setItem( row, COL_ERROR, new QTableWidgetItem( text ) );
-       else tbl->item( row, COL_ERROR )->setText( text );
+        text = SMESH::errorText( err.code, err.comment.in() );
+        if ( !tbl->item( row, COL_ERROR ) ) tbl->setItem( row, COL_ERROR, new QTableWidgetItem( text ) );
+        else tbl->item( row, COL_ERROR )->setText( text );
 
-       text = QString("%1").arg( err.subShapeID );
-       if ( !tbl->item( row, COL_SHAPEID ) ) tbl->setItem( row, COL_SHAPEID, new QTableWidgetItem( text ) );
-       else tbl->item( row, COL_SHAPEID )->setText( text );
+        text = QString("%1").arg( err.subShapeID );
+        if ( !tbl->item( row, COL_SHAPEID ) ) tbl->setItem( row, COL_SHAPEID, new QTableWidgetItem( text ) );
+        else tbl->item( row, COL_SHAPEID )->setText( text );
 
         text = hasShape ? SMESH::shapeText( err.subShapeID, myMainShape ) : QString("");
-       if ( !tbl->item( row, COL_SHAPE ) ) tbl->setItem( row, COL_SHAPE, new QTableWidgetItem( text ) );
-       else tbl->item( row, COL_SHAPE )->setText( text );
+        if ( !tbl->item( row, COL_SHAPE ) ) tbl->setItem( row, COL_SHAPE, new QTableWidgetItem( text ) );
+        else tbl->item( row, COL_SHAPE )->setText( text );
 
         text = ( !hasShape || SMESH::getSubShapeSO( err.subShapeID, myMainShape )) ? "PUBLISHED" : "";
-       if ( !tbl->item( row, COL_PUBLISHED ) ) tbl->setItem( row, COL_PUBLISHED, new QTableWidgetItem( text ) );
-       else tbl->item( row, COL_PUBLISHED )->setText( text ); // if text=="", "PUBLISH" button enabled
+        if ( !tbl->item( row, COL_PUBLISHED ) ) tbl->setItem( row, COL_PUBLISHED, new QTableWidgetItem( text ) );
+        else tbl->item( row, COL_PUBLISHED )->setText( text ); // if text=="", "PUBLISH" button enabled
 
         text = err.hasBadMesh ? "hasBadMesh" : "";
-       if ( !tbl->item( row, COL_BAD_MESH ) ) tbl->setItem( row, COL_BAD_MESH, new QTableWidgetItem( text ) );
-       else tbl->item( row, COL_BAD_MESH )->setText( text );
+        if ( !tbl->item( row, COL_BAD_MESH ) ) tbl->setItem( row, COL_BAD_MESH, new QTableWidgetItem( text ) );
+        else tbl->item( row, COL_BAD_MESH )->setText( text );
         if ( err.hasBadMesh ) hasBadMesh = true;
 
         //tbl->item( row, COL_ERROR )->setWordWrap( true ); // VSR: TODO ???
@@ -1244,7 +1073,7 @@ void SMESHGUI_BaseComputeOp::stopOperation()
 
 //================================================================================
 /*!
- * \brief publish selected subshape
+ * \brief publish selected sub-shape
  */
 //================================================================================
 
@@ -1420,7 +1249,7 @@ SMESHGUI_ComputeDlg* SMESHGUI_BaseComputeOp::computeDlg() const
   if ( !myCompDlg )
   {
     SMESHGUI_BaseComputeOp* me = (SMESHGUI_BaseComputeOp*)this;
-    me->myCompDlg = new SMESHGUI_ComputeDlg( desktop() );
+    me->myCompDlg = new SMESHGUI_ComputeDlg( desktop(), false );
     // connect signals and slots
     connect(myCompDlg->myShowBtn,    SIGNAL (clicked()), SLOT(onPreviewShape()));
     connect(myCompDlg->myPublishBtn, SIGNAL (clicked()), SLOT(onPublishShape()));
@@ -1433,6 +1262,17 @@ SMESHGUI_ComputeDlg* SMESHGUI_BaseComputeOp::computeDlg() const
   return myCompDlg;
 }
 
+//================================================================================
+/*!
+ * \brief returns from compute mesh result dialog
+ */
+//================================================================================
+
+bool SMESHGUI_BaseComputeOp::onApply()
+{
+  return true;
+}
+
 //================================================================================
 /*!
  * \brief Return a table
@@ -1476,18 +1316,26 @@ SMESHGUI_ComputeOp::~SMESHGUI_ComputeOp()
 void SMESHGUI_ComputeOp::startOperation()
 {
   SMESHGUI_BaseComputeOp::startOperation();
+  if (myMesh->_is_nil())
+    return;
   computeMesh();
 }
 
 //================================================================================
 /*!
- * \brief perform it's intention action: compute mesh
+ * \brief check the same operations on the same mesh
  */
 //================================================================================
 
-bool SMESHGUI_ComputeOp::onApply()
+bool SMESHGUI_BaseComputeOp::isValid(  SUIT_Operation* theOp  ) const
 {
-  return true;
+  SMESHGUI_BaseComputeOp* baseOp = dynamic_cast<SMESHGUI_BaseComputeOp*>( theOp );
+  bool ret = true;
+  if ( !myMesh->_is_nil() && baseOp ) {
+    SMESH::SMESH_Mesh_var aMesh = baseOp->getMesh();
+    if ( !aMesh->_is_nil() && aMesh->GetId() == myMesh->GetId() ) ret = false;
+  }
+  return ret;
 }
 
 //================================================================================
@@ -1511,10 +1359,11 @@ LightApp_Dialog* SMESHGUI_ComputeOp::dlg() const
 SMESHGUI_PrecomputeOp::SMESHGUI_PrecomputeOp()
  : SMESHGUI_BaseComputeOp(),
  myDlg( 0 ),
+ myOrderMgr( 0 ),
  myActiveDlg( 0 ),
  myPreviewDisplayer( 0 )
 {
-  myHelpFileName = "preview_meshes_page.html"; // V4
+  myHelpFileName = "constructing_meshes_page.html#preview_mesh_anchor";
 }
 
 //================================================================================
@@ -1527,6 +1376,8 @@ SMESHGUI_PrecomputeOp::~SMESHGUI_PrecomputeOp()
 {
   delete myDlg;
   myDlg = 0;
+  delete myOrderMgr;
+  myOrderMgr = 0;
   myActiveDlg = 0;
   if ( myPreviewDisplayer )
     delete myPreviewDisplayer;
@@ -1559,6 +1410,8 @@ void SMESHGUI_PrecomputeOp::startOperation()
     
     // connect signals
     connect( myDlg, SIGNAL( preview() ), this, SLOT( onPreview() ) );
+    connect( myDlg, SIGNAL( dlgOk() ), this, SLOT( onCompute() ) );
+    connect( myDlg, SIGNAL( dlgApply() ), this, SLOT( onCompute() ) );
   }
   myActiveDlg = myDlg;
 
@@ -1587,6 +1440,22 @@ void SMESHGUI_PrecomputeOp::startOperation()
   }
 
   SMESHGUI_BaseComputeOp::startOperation();
+  if (myMesh->_is_nil())
+    return;
+
+  if (myDlg->getPreviewMode() == -1)
+  {
+    // nothing to preview
+    SUIT_MessageBox::warning(desktop(),
+                             tr("SMESH_WRN_WARNING"),
+                             tr("SMESH_WRN_NOTHING_PREVIEW"));
+    onCancel();
+    return;
+  }
+
+  // disconnect slot from preview dialog to have Apply from results of compute operation only 
+  disconnect( myDlg, SIGNAL( dlgOk() ), this, SLOT( onOk() ) );
+  disconnect( myDlg, SIGNAL( dlgApply() ), this, SLOT( onApply() ) );
 
   myDlg->show();
 }
@@ -1611,7 +1480,7 @@ void SMESHGUI_PrecomputeOp::stopOperation()
 
 //================================================================================
 /*!
- * \brief perform it's intention action: reinitialise dialog
+ * \brief reinitialize dialog after operaiton become active again
  */
 //================================================================================
 
@@ -1622,16 +1491,57 @@ void SMESHGUI_PrecomputeOp::resumeOperation()
   SMESHGUI_BaseComputeOp::resumeOperation();
 }
 
+//================================================================================
+/*!
+ * \brief perform it's intention action: reinitialise dialog
+ */
+//================================================================================
+
 void SMESHGUI_PrecomputeOp::initDialog()
 {
   QList<int> modes;
+
   QMap<int, int> modeMap;
+  _PTR(SObject)  pMesh = studyDS()->FindObjectID( myIObject->getEntry() );
+  getAssignedAlgos( pMesh, modeMap );
+  if ( modeMap.contains( SMESH::DIM_3D ) )
+  {
+    if ( modeMap.contains( SMESH::DIM_2D ) )
+      modes.append( SMESH::DIM_2D );
+    if ( modeMap.contains( SMESH::DIM_1D ) )
+      modes.append( SMESH::DIM_1D );
+  }
+  else if ( modeMap.contains( SMESH::DIM_2D ) )
+  {
+    if ( modeMap.contains( SMESH::DIM_1D ) )
+      modes.append( SMESH::DIM_1D );
+  }
+
+  myOrderMgr = new SMESHGUI_MeshOrderMgr( myDlg->getMeshOrderBox() );
+  myOrderMgr->SetMesh( myMesh );
+  bool isOrder = myOrderMgr->GetMeshOrder(myPrevOrder);
+  myDlg->getMeshOrderBox()->setShown(isOrder);
+  if ( !isOrder ) {
+    delete myOrderMgr;
+    myOrderMgr = 0;
+  }
+
+  myDlg->setPreviewModes( modes );
+}
+
+//================================================================================
+/*!
+ * \brief detect asigned mesh algorithms
+ */
+//================================================================================
+
+void SMESHGUI_PrecomputeOp::getAssignedAlgos(_PTR(SObject) theMesh,
+                                             QMap<int,int>& theModeMap)
+{
   _PTR(SObject)          aHypRoot;
   _PTR(GenericAttribute) anAttr;
   int aPart = SMESH::Tag_RefOnAppliedAlgorithms;
-
-  _PTR(SObject) pMesh = studyDS()->FindObjectID( myIObject->getEntry() );
-  if ( pMesh && pMesh->FindSubObject( aPart, aHypRoot ) )
+  if ( theMesh && theMesh->FindSubObject( aPart, aHypRoot ) )
   {
     _PTR(ChildIterator) anIter =
       SMESH::GetActiveStudyDocument()->NewChildIterator( aHypRoot );
@@ -1649,50 +1559,38 @@ void SMESHGUI_PrecomputeOp::initDialog()
         CORBA::Object_var aVar = _CAST(SObject,anObj)->GetObject();
         if ( CORBA::is_nil( aVar ) )
           continue;
-
-        SMESH::SMESH_Algo_var algo = SMESH::SMESH_3D_Algo::_narrow( aVar );
-        if ( !algo->_is_nil() )
-        {
-         modeMap[ SMESH::DIM_1D ] = 0;
-         modeMap[ SMESH::DIM_2D ] = 0;
-        }
-        else
+        
+        for( int dim = SMESH::DIM_1D; dim <= SMESH::DIM_3D; dim++ )
         {
-          algo = SMESH::SMESH_2D_Algo::_narrow( aVar );
+          SMESH::SMESH_Algo_var algo;
+          switch(dim) {
+          case SMESH::DIM_1D: algo = SMESH::SMESH_1D_Algo::_narrow( aVar ); break;
+          case SMESH::DIM_2D: algo = SMESH::SMESH_2D_Algo::_narrow( aVar ); break;
+          case SMESH::DIM_3D: algo = SMESH::SMESH_3D_Algo::_narrow( aVar ); break;
+          default: break;
+          }
           if ( !algo->_is_nil() )
-            modeMap[ SMESH::DIM_2D ] = 0;
+            theModeMap[ dim ] = 0;
         }
       }
     }
   }
-  if ( modeMap.contains( SMESH::DIM_1D ) )
-    modes.append( SMESH::DIM_1D );
-  if ( modeMap.contains( SMESH::DIM_2D ) )
-    modes.append( SMESH::DIM_2D );
-
-  myDlg->setPreviewModes( modes );
 }
 
 //================================================================================
 /*!
- * \brief perform it's intention action: 
+ * \brief perform it's intention action: compute mesh
  */
 //================================================================================
 
-bool SMESHGUI_PrecomputeOp::onApply()
+void SMESHGUI_PrecomputeOp::onCompute()
 {
-  QObject* obj = sender();
-  if ( obj != myDlg && myActiveDlg == myDlg )
-    return true; // just return from error messages
-  if ( myActiveDlg == myDlg )
-  {
-    myDlg->hide();
-    myMapShapeId.clear();
-    myActiveDlg = computeDlg();
-    computeMesh();
-  }
-
-  return true;
+  myDlg->hide();
+  if (myOrderMgr && myOrderMgr->IsOrderChanged())
+    myOrderMgr->SetMeshOrder();
+  myMapShapeId.clear();
+  myActiveDlg = computeDlg();
+  computeMesh();
 }
 
 //================================================================================
@@ -1704,14 +1602,14 @@ bool SMESHGUI_PrecomputeOp::onApply()
 void SMESHGUI_PrecomputeOp::onCancel()
 {
   QObject* curDlg = sender();
-  if ( curDlg == computeDlg() )
+  if ( curDlg == computeDlg() && myActiveDlg == myDlg )
   {
-    if ( myActiveDlg == myDlg ) // return from error messages
-      myDlg->show();
-
+    // return from error messages
+    myDlg->show();
     return;
   }
 
+  bool isRestoreOrder = false;
   if ( myActiveDlg == myDlg  && !myMesh->_is_nil() && myMapShapeId.count() )
   {
     // ask to remove already computed mesh elements
@@ -1723,8 +1621,24 @@ void SMESHGUI_PrecomputeOp::onCancel()
       QMap<int,int>::const_iterator it = myMapShapeId.constBegin();
       for ( ; it != myMapShapeId.constEnd(); ++it )
         myMesh->ClearSubMesh( *it );
+      isRestoreOrder = true;
     }
   }
+
+  // return previous mesh order
+  if (myOrderMgr && myOrderMgr->IsOrderChanged()) {
+    if (!isRestoreOrder)
+      isRestoreOrder = 
+        (SUIT_MessageBox::question( desktop(), tr( "SMESH_WARNING" ),
+                                    tr( "SMESH_REJECT_MESH_ORDER" ),
+                                    tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 ) == 0);
+    if (isRestoreOrder)
+      myOrderMgr->SetMeshOrder(myPrevOrder);
+  }
+
+  delete myOrderMgr;
+  myOrderMgr = 0;
+
   myMapShapeId.clear();
   SMESHGUI_BaseComputeOp::onCancel();
 }
@@ -1743,6 +1657,11 @@ void SMESHGUI_PrecomputeOp::onPreview()
   _PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh);
   if ( !aMeshSObj )
     return;
+
+  // set modified submesh priority if any
+  if (myOrderMgr && myOrderMgr->IsOrderChanged())
+    myOrderMgr->SetMeshOrder();
+
   // Compute preview of mesh, 
   // i.e. compute mesh till indicated dimension
   int dim = myDlg->getPreviewMode();
@@ -1778,6 +1697,7 @@ void SMESHGUI_PrecomputeOp::onPreview()
       
     SMESH::MeshPreviewStruct_var previewData =
       gen->Precompute(myMesh, myMainShape, (SMESH::Dimension)dim, aShapesId);
+
     SMESH::MeshPreviewStruct* previewRes = previewData._retn();
     if ( previewRes && previewRes->nodesXYZ.length() > 0 )
     {
@@ -1785,7 +1705,7 @@ void SMESHGUI_PrecomputeOp::onPreview()
       myPreviewDisplayer->SetData( previewRes );
       // append shape indeces with computed mesh entities
       for ( int i = 0, n = aShapesId->length(); i < n; i++ )
-       myMapShapeId[ aShapesId[ i ] ] = 0;
+        myMapShapeId[ aShapesId[ i ] ] = 0;
     }
     else
       myPreviewDisplayer->SetVisibility(false);
@@ -1847,7 +1767,8 @@ void SMESHGUI_PrecomputeOp::onPreview()
 //================================================================================
 
 SMESHGUI_PrecomputeDlg::SMESHGUI_PrecomputeDlg( QWidget* parent )
- : SMESHGUI_Dialog( parent, false, false, OK | Cancel | Help )
+ : SMESHGUI_Dialog( parent, false, false, OK | Cancel | Help ),
+   myOrderBox(0)
 {
   setWindowTitle( tr( "CAPTION" ) );
 
@@ -1856,6 +1777,9 @@ SMESHGUI_PrecomputeDlg::SMESHGUI_PrecomputeDlg( QWidget* parent )
 
   QVBoxLayout* layout = new QVBoxLayout( main );
 
+  myOrderBox = new SMESHGUI_MeshOrderBox( main );
+  layout->addWidget(myOrderBox);
+
   QFrame* frame = new QFrame( main );
   layout->setMargin(0); layout->setSpacing(0);
   layout->addWidget( frame );
@@ -1911,3 +1835,292 @@ int SMESHGUI_PrecomputeDlg::getPreviewMode() const
 {
   return myPreviewMode->currentId();
 }
+
+//================================================================================
+/*!
+ * \brief Returns current preview mesh mode
+*/
+//================================================================================
+
+SMESHGUI_MeshOrderBox* SMESHGUI_PrecomputeDlg::getMeshOrderBox() const
+{
+  return myOrderBox;
+}
+
+
+//================================================================================
+/*!
+ * \brief Constructor
+*/
+//================================================================================
+
+SMESHGUI_EvaluateOp::SMESHGUI_EvaluateOp()
+ : SMESHGUI_BaseComputeOp()
+{
+}
+
+
+//================================================================================
+/*!
+ * \brief Desctructor
+*/
+//================================================================================
+
+SMESHGUI_EvaluateOp::~SMESHGUI_EvaluateOp()
+{
+}
+
+//================================================================================
+/*!
+ * \brief perform it's intention action: compute mesh
+ */
+//================================================================================
+
+void SMESHGUI_EvaluateOp::startOperation()
+{
+  SMESHGUI_BaseComputeOp::evaluateDlg();
+  SMESHGUI_BaseComputeOp::startOperation();
+  if (myMesh->_is_nil())
+    return;
+  evaluateMesh();
+}
+
+//================================================================================
+/*!
+ * \brief Gets dialog of this operation
+ * \retval LightApp_Dialog* - pointer to dialog of this operation
+ */
+//================================================================================
+
+LightApp_Dialog* SMESHGUI_EvaluateOp::dlg() const
+{
+  return evaluateDlg();
+}
+
+//================================================================================
+/*!
+ * \brief evaluateMesh()
+*/
+//================================================================================
+
+void SMESHGUI_BaseComputeOp::evaluateMesh()
+{
+  // EVALUATE MESH
+
+  SMESH::MemoryReserve aMemoryReserve;
+
+  SMESH::compute_error_array_var aCompErrors;
+  QString                        aHypErrors;
+
+  bool evaluateFailed = true, memoryLack = false;
+  SMESH::long_array_var aRes;
+
+  _PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh);
+  if ( !aMeshSObj ) //  IPAL21340
+    return;
+
+  bool hasShape = myMesh->HasShapeToMesh();
+  bool shapeOK = myMainShape->_is_nil() ? !hasShape : hasShape;
+  if ( shapeOK )
+  {
+    myCompDlg->myMeshName->setText( aMeshSObj->GetName().c_str() );
+    SMESH::SMESH_Gen_var gen = getSMESHGUI()->GetSMESHGen();
+    SMESH::algo_error_array_var errors = gen->GetAlgoState(myMesh,myMainShape);
+    if ( errors->length() > 0 ) {
+      aHypErrors = SMESH::GetMessageOnAlgoStateErrors( errors.in() );
+    }
+    SUIT_OverrideCursor aWaitCursor;
+    try {
+#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
+      OCC_CATCH_SIGNALS;
+#endif
+      aRes = gen->Evaluate(myMesh, myMainShape);
+    }
+    catch(const SALOME::SALOME_Exception & S_ex){
+      memoryLack = true;
+    }
+
+    try {
+#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
+      OCC_CATCH_SIGNALS;
+#endif
+      aCompErrors = gen->GetComputeErrors( myMesh, myMainShape );
+    }
+    catch(const SALOME::SALOME_Exception & S_ex){
+      memoryLack = true;
+    }
+  }
+
+  if ( memoryLack )
+    aMemoryReserve.release();
+
+  evaluateFailed =  ( aCompErrors->length() > 0 );
+  myCompDlg->setWindowTitle(tr( evaluateFailed ? "SMESH_WRN_EVALUATE_FAILED" : "SMESH_EVALUATE_SUCCEED"));
+
+  // SHOW ERRORS
+  
+  bool noCompError = ( !aCompErrors.operator->() || aCompErrors->length() == 0 );
+  bool noHypoError = ( aHypErrors.isEmpty() );
+
+  //SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( SMESHGUI::GetSMESHGUI() );
+  //int aNotifyMode = resMgr->integerValue( "SMESH", "show_result_notification" );
+
+  bool isShowResultDlg = true;
+  //if( noHypoError )
+  //switch( aNotifyMode ) {
+  //case 0: // show the mesh computation result dialog NEVER
+  //isShowResultDlg = false;
+  //commit();
+  //break;
+  //case 1: // show the mesh computation result dialog if there are some errors
+  //if ( memoryLack || !noHypoError )
+  //  isShowResultDlg = true;
+  //else
+  //{
+  //  isShowResultDlg = false;
+  //  commit();
+  //}
+  //break;
+  //default: // show the result dialog after each mesh computation
+  //isShowResultDlg = true;
+  //}
+
+  // SHOW RESULTS
+  if ( isShowResultDlg )
+    showEvaluateResult( aRes, memoryLack, noCompError, aCompErrors,
+                        noHypoError, aHypErrors);
+}
+
+
+void SMESHGUI_BaseComputeOp::showEvaluateResult(const SMESH::long_array& theRes,
+                                                const bool theMemoryLack,
+                                                const bool theNoCompError,
+                                                SMESH::compute_error_array_var& theCompErrors,
+                                                const bool theNoHypoError,
+                                                const QString& theHypErrors)
+{
+  bool hasShape = myMesh->HasShapeToMesh();
+  SMESHGUI_ComputeDlg* aCompDlg = evaluateDlg();
+  aCompDlg->myMemoryLackGroup->hide();
+
+  if ( theMemoryLack )
+  {
+    aCompDlg->myMemoryLackGroup->show();
+    aCompDlg->myFullInfo->hide();
+    aCompDlg->myBriefInfo->hide();
+    aCompDlg->myHypErrorGroup->hide();
+    aCompDlg->myCompErrorGroup->hide();
+  }
+  else if ( theNoCompError && theNoHypoError )
+  {
+    aCompDlg->myFullInfo->SetMeshInfo( theRes );
+    aCompDlg->myFullInfo->show();
+    aCompDlg->myBriefInfo->hide();
+    aCompDlg->myHypErrorGroup->hide();
+    aCompDlg->myCompErrorGroup->hide();
+  }
+  else
+  {
+    QTableWidget* tbl = aCompDlg->myTable;
+    aCompDlg->myBriefInfo->SetMeshInfo( theRes );
+    aCompDlg->myBriefInfo->show();
+    aCompDlg->myFullInfo->hide();
+
+    if ( theNoHypoError ) {
+      aCompDlg->myHypErrorGroup->hide();
+    }
+    else {
+      aCompDlg->myHypErrorGroup->show();
+      aCompDlg->myHypErrorLabel->setText( theHypErrors );
+    }
+
+    if ( theNoCompError ) {
+      aCompDlg->myCompErrorGroup->hide();
+    }
+    else {
+      aCompDlg->myCompErrorGroup->show();
+
+      aCompDlg->myPublishBtn->hide();
+      aCompDlg->myShowBtn->hide();
+
+      // fill table of errors
+      tbl->setRowCount( theCompErrors->length() );
+      if ( !hasShape ) tbl->hideColumn( COL_SHAPE );
+      else             tbl->showColumn( COL_SHAPE );
+      tbl->setColumnWidth( COL_ERROR, 200 );
+
+      bool hasBadMesh = false;
+      for ( int row = 0; row < theCompErrors->length(); ++row )
+      {
+        SMESH::ComputeError & err = theCompErrors[ row ];
+
+        QString text = err.algoName.in();
+        if ( !tbl->item( row, COL_ALGO ) ) tbl->setItem( row, COL_ALGO, new QTableWidgetItem( text ) );
+        else tbl->item( row, COL_ALGO )->setText( text );
+
+        text = SMESH::errorText( err.code, err.comment.in() );
+        if ( !tbl->item( row, COL_ERROR ) ) tbl->setItem( row, COL_ERROR, new QTableWidgetItem( text ) );
+        else tbl->item( row, COL_ERROR )->setText( text );
+
+        text = QString("%1").arg( err.subShapeID );
+        if ( !tbl->item( row, COL_SHAPEID ) ) tbl->setItem( row, COL_SHAPEID, new QTableWidgetItem( text ) );
+        else tbl->item( row, COL_SHAPEID )->setText( text );
+
+        text = hasShape ? SMESH::shapeText( err.subShapeID, myMainShape ) : QString("");
+        if ( !tbl->item( row, COL_SHAPE ) ) tbl->setItem( row, COL_SHAPE, new QTableWidgetItem( text ) );
+        else tbl->item( row, COL_SHAPE )->setText( text );
+
+        text = ( !hasShape || SMESH::getSubShapeSO( err.subShapeID, myMainShape )) ? "PUBLISHED" : "";
+        if ( !tbl->item( row, COL_PUBLISHED ) ) tbl->setItem( row, COL_PUBLISHED, new QTableWidgetItem( text ) );
+        else tbl->item( row, COL_PUBLISHED )->setText( text ); // if text=="", "PUBLISH" button enabled
+
+        text = err.hasBadMesh ? "hasBadMesh" : "";
+        if ( !tbl->item( row, COL_BAD_MESH ) ) tbl->setItem( row, COL_BAD_MESH, new QTableWidgetItem( text ) );
+        else tbl->item( row, COL_BAD_MESH )->setText( text );
+        if ( err.hasBadMesh ) hasBadMesh = true;
+
+        //tbl->item( row, COL_ERROR )->setWordWrap( true ); // VSR: TODO ???
+        tbl->resizeRowToContents( row );
+      }
+      tbl->resizeColumnToContents( COL_ALGO );
+      tbl->resizeColumnToContents( COL_SHAPE );
+
+      if ( hasBadMesh )
+        aCompDlg->myBadMeshBtn->show();
+      else
+        aCompDlg->myBadMeshBtn->hide();
+
+      tbl->setCurrentCell(0,0);
+      currentCellChanged(); // to update buttons
+    }
+  }
+  // show dialog and wait, becase Compute can be invoked from Preview operation
+  //aCompDlg->exec(); // this way it becomes modal - impossible to rotate model in the Viewer
+  aCompDlg->show();
+}
+
+
+//================================================================================
+/*!
+ * \brief Gets dialog of evaluate operation
+ * \retval SMESHGUI_ComputeDlg* - pointer to dialog of this operation
+ */
+//================================================================================
+
+SMESHGUI_ComputeDlg* SMESHGUI_BaseComputeOp::evaluateDlg() const
+{
+  if ( !myCompDlg )
+  {
+    SMESHGUI_BaseComputeOp* me = (SMESHGUI_BaseComputeOp*)this;
+    me->myCompDlg = new SMESHGUI_ComputeDlg( desktop(), true );
+    // connect signals and slots
+    connect(myCompDlg->myShowBtn,    SIGNAL (clicked()), SLOT(onPreviewShape()));
+    connect(myCompDlg->myPublishBtn, SIGNAL (clicked()), SLOT(onPublishShape()));
+    connect(myCompDlg->myBadMeshBtn, SIGNAL (clicked()), SLOT(onShowBadMesh()));
+    QTableWidget* aTable = me->table();
+    connect(aTable, SIGNAL(itemSelectionChanged()), SLOT(currentCellChanged()));
+    connect(aTable, SIGNAL(currentCellChanged(int,int,int,int)), SLOT(currentCellChanged()));
+  }
+  return myCompDlg;
+}
+
index 5ec969cc7777b6f32c94c986415c05e935eb326d..49aa2477c77ba31127699f7d1c66e54abd1565cd 100644 (file)
@@ -1,24 +1,22 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  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 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.
 //
-//  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
 //
-//  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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : SMESHGUI_ComputeDlg.h
 // Author : Edward AGAPOV, Open CASCADE S.A.S.
 //
 
 // Qt includes
 #include <QMap>
+#include <QList>
 #include <QPointer>
 #include <QGroupBox>
+#include <QThread>
 
 // IDL includes
 #include <SALOMEconfig.h>
@@ -50,11 +50,10 @@ class QTableWidget;
 class QLabel;
 class QtxComboBox;
 class SMESHGUI_ComputeDlg;
+class SMESHGUI_MeshInfosBox;
 class SMESHGUI_PrecomputeDlg;
 class SMESHGUI_MeshEditPreview;
 
-class SMESH::compute_error_array;
-
 namespace SMESH
 {
   class TShapeDisplayer;
@@ -71,6 +70,8 @@ public:
   SMESHGUI_BaseComputeOp();
   virtual ~SMESHGUI_BaseComputeOp();
 
+  SMESH::SMESH_Mesh_ptr          getMesh();
+
 protected:
   virtual void                   startOperation();
   virtual void                   stopOperation();
@@ -78,12 +79,23 @@ protected:
   SMESHGUI_ComputeDlg*           computeDlg() const;
   void                           computeMesh();
   void                           showComputeResult( const bool,
-                                                   const bool,
-                                                   SMESH::compute_error_array_var&,
-                                                   const bool,
-                                                   const QString& );
+                                                    const bool,
+                                                    SMESH::compute_error_array_var&,
+                                                    const bool,
+                                                    const QString& );
+  SMESHGUI_ComputeDlg*           evaluateDlg() const;
+  void                           evaluateMesh();
+  void                           showEvaluateResult(const SMESH::long_array& theRes,
+                                                    const bool,
+                                                    const bool,
+                                                    SMESH::compute_error_array_var&,
+                                                    const bool,
+                                                    const QString&);
+
+  virtual bool                   isValid( SUIT_Operation* theOp ) const;
     
 protected slots:
+  virtual bool                   onApply();
   void                           onPreviewShape();
   void                           onPublishShape();
   void                           onShowBadMesh();
@@ -120,9 +132,10 @@ protected:
   virtual void                   startOperation();
 
 protected slots:
-  virtual bool                   onApply();
 };
 
+class SMESHGUI_MeshOrderMgr;
+
 /*!
  * \brief Operation to preview and compute a mesh and show computation errors
  */
@@ -136,6 +149,12 @@ public:
 
   virtual LightApp_Dialog*       dlg() const;
 
+  /**
+   * \brief returns map of assigned algorithms modes
+   */
+  static void                    getAssignedAlgos(_PTR(SObject) theMesh,
+                                                  QMap<int,int>& theModeMap);
+
 protected:
   virtual void                   startOperation();
   virtual void                   stopOperation();
@@ -144,64 +163,42 @@ protected:
   virtual void                   initDialog();
 
 protected slots:
-  virtual bool                   onApply();
   virtual void                   onCancel();
 
 private slots:
   void                           onPreview();
+  void                           onCompute();
 
 private:
+  //! private fields
   QMap< int, int >               myMapShapeId;
   QPointer<LightApp_Dialog>      myActiveDlg;
   QPointer<SMESHGUI_PrecomputeDlg> myDlg;
   SMESHGUI_MeshEditPreview*      myPreviewDisplayer;
+  //! fields for mesh order
+  typedef QList<int>             TListOfInt;
+  typedef QList<TListOfInt>      TListOfListOfInt;
+  TListOfListOfInt               myPrevOrder;
+  SMESHGUI_MeshOrderMgr*         myOrderMgr;
 };
 
 /*!
- * \brief Box showing mesh info
+ * \brief Operation to evaluate a mesh and show result
  */
-
-class SMESHGUI_EXPORT SMESHGUI_MeshInfosBox : public QGroupBox
+class SMESHGUI_EXPORT SMESHGUI_EvaluateOp: public SMESHGUI_BaseComputeOp
 {
   Q_OBJECT
 
 public:
-  SMESHGUI_MeshInfosBox( const bool, QWidget* );
+  SMESHGUI_EvaluateOp();
+  virtual ~SMESHGUI_EvaluateOp();
 
-  void    SetInfoByMesh( SMESH::SMESH_Mesh_var );
+  virtual LightApp_Dialog*       dlg() const;
 
-private:
-  bool    myFull;
-  QLabel* myNbNode;
-  QLabel* myNbEdge;
-  QLabel* myNbLinEdge;
-  QLabel* myNbQuadEdge;
-  QLabel* myNbTrai;
-  QLabel* myNbLinTrai;
-  QLabel* myNbQuadTrai;
-  QLabel* myNbQuad;
-  QLabel* myNbLinQuad;
-  QLabel* myNbQuadQuad;
-  QLabel* myNbFace;
-  QLabel* myNbLinFace;
-  QLabel* myNbQuadFace;
-  QLabel* myNbPolyg;
-  QLabel* myNbHexa;
-  QLabel* myNbLinHexa;
-  QLabel* myNbQuadHexa;
-  QLabel* myNbTetra;
-  QLabel* myNbLinTetra;
-  QLabel* myNbQuadTetra;
-  QLabel* myNbPyra;
-  QLabel* myNbLinPyra;
-  QLabel* myNbQuadPyra;
-  QLabel* myNbPrism;
-  QLabel* myNbLinPrism;
-  QLabel* myNbQuadPrism;
-  QLabel* myNbVolum;
-  QLabel* myNbLinVolum;
-  QLabel* myNbQuadVolum;
-  QLabel* myNbPolyh;
+protected:
+  virtual void                   startOperation();
+
+protected slots:
 };
 
 /*!
@@ -213,17 +210,18 @@ class SMESHGUI_EXPORT SMESHGUI_ComputeDlg : public SMESHGUI_Dialog
   Q_OBJECT
 
 public:
-  SMESHGUI_ComputeDlg( QWidget* );
+  SMESHGUI_ComputeDlg( QWidget*, bool );
   virtual ~SMESHGUI_ComputeDlg();
 
 protected:
-  QFrame*                      createMainFrame( QWidget* );
+  QFrame*                      createMainFrame( QWidget*, bool );
 
   QLabel*                      myMeshName;
   QGroupBox*                   myMemoryLackGroup;
   QGroupBox*                   myCompErrorGroup;
   QGroupBox*                   myHypErrorGroup;
   QLabel*                      myHypErrorLabel;
+  QLabel*                      myWarningLabel;
   QTableWidget*                myTable;
   QPushButton*                 myShowBtn;
   QPushButton*                 myPublishBtn;
@@ -236,6 +234,8 @@ protected:
   friend class SMESHGUI_PrecomputeOp;
 };
 
+class SMESHGUI_MeshOrderBox;
+
 /*!
  * \brief Dialog to preview and compute a mesh and show computation errors
  */
@@ -250,14 +250,69 @@ public:
   
   void                         setPreviewModes( const QList<int>& );
   int                          getPreviewMode() const;
+  
+  SMESHGUI_MeshOrderBox*       getMeshOrderBox() const;
 
 signals:
   void                         preview();
 
 private:
+  SMESHGUI_MeshOrderBox*       myOrderBox;
   QPushButton*                 myPreviewBtn;
   QtxComboBox*                 myPreviewMode;
 };
 
+/*!
+ * \brief Thread to launch computation
+ */
+
+class SMESHGUI_EXPORT SMESHGUI_ComputeDlg_QThread : public QThread
+{
+  Q_OBJECT
+    
+public:
+  SMESHGUI_ComputeDlg_QThread(SMESH::SMESH_Gen_var gen,
+                              SMESH::SMESH_Mesh_var mesh,
+                              GEOM::GEOM_Object_var mainShape);
+  bool result();
+  void cancel();
+  
+protected:
+  void run();
+  
+private:
+  SMESH::SMESH_Gen_var myGen;
+  SMESH::SMESH_Mesh_var myMesh;
+  GEOM::GEOM_Object_var myMainShape;
+  bool myResult;
+};
+
+/*!
+ * \brief Dialog to display Cancel button
+ */
+
+class SMESHGUI_EXPORT SMESHGUI_ComputeDlg_QThreadQDialog : public QDialog
+{
+  Q_OBJECT
+    
+public:
+  SMESHGUI_ComputeDlg_QThreadQDialog(QWidget *parent,
+                                     SMESH::SMESH_Gen_var gen,
+                                     SMESH::SMESH_Mesh_var mesh,
+                                     GEOM::GEOM_Object_var mainShape);
+  bool result();
+  
+protected:
+  void timerEvent(QTimerEvent *timer);
+  void closeEvent(QCloseEvent *event);
+  
+private slots:
+  void onCancel();
+  
+private:
+  SMESHGUI_ComputeDlg_QThread qthread;
+  QPushButton *cancelButton;
+  
+};
 
 #endif // SMESHGUI_COMPUTEDLG_H
index 5db422cddc058bef5bbf2fd7de800c2dbfbbbdbe..b42d728ae9cae0e872609710006ba17b2ef59f70 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_ConvToQuadDlg.cxx
 // Author : Open CASCADE S.A.S.
@@ -35,6 +36,7 @@
 #include <QFrame>
 #include <QHBoxLayout>
 #include <QGridLayout>
+#include <QLabel>
 
 #define SPACING 6
 #define MARGIN  11
@@ -69,6 +71,8 @@ SMESHGUI_ConvToQuadDlg::SMESHGUI_ConvToQuadDlg()
   myBG->addButton(myRB2, 1);
   myRB1->setChecked( true );
 
+  myWarning = new QLabel(QString("<b>%1</b>").arg(tr("NON_CONFORM_WARNING")), mainFrame());
+
   // Fill layout
   QGridLayout* aLay = new QGridLayout( mainFrame() );
   aLay->setMargin( 5 );
@@ -79,6 +83,7 @@ SMESHGUI_ConvToQuadDlg::SMESHGUI_ConvToQuadDlg()
   aLay->addWidget( objectWg( 0,  Control ), 0, 2 );
   aLay->addWidget( myMedNdsOnGeom,          1, 0, 1, 3 );
   aLay->addWidget( myBGBox,                 2, 0, 1, 3 );
+  aLay->addWidget( myWarning,               3, 0, 1, 3 );
   
   connect(myBG, SIGNAL( buttonClicked( int ) ), this, SIGNAL( onClicked( int ) ) );
 }
@@ -112,11 +117,26 @@ int SMESHGUI_ConvToQuadDlg::CurrentRB( )
   return myBG->checkedId();
 }
 
+void SMESHGUI_ConvToQuadDlg::ShowWarning(bool toShow)
+{
+  if ( toShow )
+    myWarning->show();
+  else
+    myWarning->hide();
+}
+
+bool SMESHGUI_ConvToQuadDlg::isWarningShown()
+{
+  return myWarning->isVisible();
+}
+
 void SMESHGUI_ConvToQuadDlg::SetEnabledControls( const bool theCheck )
 {
-  myBGBox->setEnabled( theCheck );
+  //myBGBox->setEnabled( theCheck );
+  myRB1->setEnabled( theCheck );
+  myRB2->setEnabled( theCheck );
   myMedNdsOnGeom->setEnabled( theCheck );
-  setButtonEnabled( theCheck, QtxDialog::OK | QtxDialog::Apply );
+  //setButtonEnabled( theCheck, QtxDialog::OK | QtxDialog::Apply );
 }
 
 void SMESHGUI_ConvToQuadDlg::SetEnabledRB( const int idx, const bool theCheck ) 
index 53240eae6b9853be477824e09833b43d6ed8f60b..660dbc7318a82b64ebda02df64c86b8781896ddc 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_ConvToQuadDlg.h
 // Author : Open CASCADE S.A.S.
@@ -35,6 +36,7 @@ class QCheckBox;
 class QRadioButton;
 class QButtonGroup;
 class QGroupBox;
+class QLabel;
 
 class SMESHGUI_EXPORT SMESHGUI_ConvToQuadDlg : public SMESHGUI_Dialog
 { 
@@ -52,6 +54,8 @@ public:
   void          SetEnabledControls( const bool );
   void          SetEnabledRB( const int, const bool );
   int           CurrentRB(); //returns the ID of the selected toggle button
+  void          ShowWarning(bool);
+  bool          isWarningShown();
 
 signals:
   void          onClicked( int );
@@ -62,6 +66,7 @@ private:
   QButtonGroup* myBG;
   QRadioButton* myRB1;
   QRadioButton* myRB2;
+  QLabel* myWarning;
 };
 
 #endif // SMESHGUI_CONVTOQUADDLG_H
index 962b11abdf95ddca42b1ac344acaa8c4961664b3..a62d0b94993be4b23b7dcdf7e644cf7d431b31ec 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_ConvToQuadOp.cxx
 // Author : Open CASCADE S.A.S.
 //
 #include "SMESHGUI_ConvToQuadOp.h"
 
+#include "SMESHGUI.h"
 #include "SMESHGUI_ConvToQuadDlg.h"
 #include "SMESHGUI_Utils.h"
+#include "SMDSAbs_ElementType.hxx"
 
-#include <SMESH_TypeFilter.hxx>
+#include "SMESH_TypeFilter.hxx"
 
 // SALOME GUI includes
-#include <SalomeApp_Tools.h>
-#include <SUIT_MessageBox.h>
 #include <LightApp_UpdateFlags.h>
+#include <SUIT_MessageBox.h>
+#include <SUIT_OverrideCursor.h>
+#include <SalomeApp_Tools.h>
 
 // IDL includes
 #include <SALOMEconfig.h>
@@ -97,6 +101,7 @@ void SMESHGUI_ConvToQuadOp::startOperation()
 
   myDlg->SetMediumNdsOnGeom( false );
   myDlg->activateObject( 0 );
+  myDlg->ShowWarning( false );
   myDlg->show();
 
   selectionDone();
@@ -117,22 +122,26 @@ void SMESHGUI_ConvToQuadOp::selectionDone()
   SMESHGUI_SelectionOp::selectionDone();
   try
   {
-    QString anMeshEntry = myDlg->selectedObject( 0 );
-    _PTR(SObject) pMesh = studyDS()->FindObjectID( anMeshEntry.toLatin1().data() );
-    if ( !pMesh ) return;
+    QString anObjEntry = myDlg->selectedObject( 0 );
+    _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() );
+    if ( !pObj ) return;
 
-    SMESH::SMESH_Mesh_var mesh =
-    SMESH::SObjectToInterface<SMESH::SMESH_Mesh>( pMesh );  
+    SMESH::SMESH_IDSource_var idSource = 
+      SMESH::SObjectToInterface<SMESH::SMESH_IDSource>( pObj );  
 
-    if( mesh->_is_nil() )
+    myDlg->setButtonEnabled( true, QtxDialog::OK | QtxDialog::Apply );
+    if( idSource->_is_nil() )
     {
       myDlg->SetEnabledControls( false );
+      myDlg->setButtonEnabled( false, QtxDialog::OK | QtxDialog::Apply );
+      return;
     }
-    else if( ConsistMesh( mesh ) == SMESHGUI_ConvToQuadOp::Quadratic )
+    MeshType meshType = ConsistMesh( idSource );
+    if( meshType == SMESHGUI_ConvToQuadOp::Quadratic )
     {
       myDlg->SetEnabledRB( 0, false );
     }
-    else if( ConsistMesh( mesh ) == SMESHGUI_ConvToQuadOp::Linear )
+    else if( meshType == SMESHGUI_ConvToQuadOp::Linear )
     {
       myDlg->SetEnabledRB( 1, false );
     }
@@ -140,6 +149,22 @@ void SMESHGUI_ConvToQuadOp::selectionDone()
     {
       myDlg->SetEnabledControls( true );
     }
+
+    // show warning on non-conformal result mesh
+    if ( ! idSource->_is_nil() )
+    {
+      SMESH::SMESH_subMesh_var subMesh = 
+        SMESH::SObjectToInterface<SMESH::SMESH_subMesh>( pObj );
+      bool toShow = false;
+      if ( !subMesh->_is_nil() )
+      {
+        SMESH::SMESH_Mesh_var mesh = idSource->GetMesh();
+        idSource = SMESH::SMESH_IDSource::_narrow( mesh );
+        MeshType fullMeshType = ConsistMesh( idSource );
+        toShow = ( fullMeshType != Comp );
+      }
+      myDlg->ShowWarning( toShow );
+    }
   }
   catch ( const SALOME::SALOME_Exception& S_ex )
   {
@@ -162,7 +187,7 @@ void SMESHGUI_ConvToQuadOp::selectionDone()
 SUIT_SelectionFilter* SMESHGUI_ConvToQuadOp::createFilter( const int theId ) const
 {
   if ( theId == 0 )
-    return new SMESH_TypeFilter( MESH );
+    return new SMESH_TypeFilter( MESHorSUBMESH );
   else
     return 0;
 }
@@ -176,48 +201,57 @@ SUIT_SelectionFilter* SMESHGUI_ConvToQuadOp::createFilter( const int theId ) con
 //================================================================================
 bool SMESHGUI_ConvToQuadOp::onApply()
 {
+  SUIT_OverrideCursor aWaitCursor;
 
   QString aMess;
 
-  QString anMeshEntry = myDlg->selectedObject( 0 );
-  _PTR(SObject) pMesh = studyDS()->FindObjectID( anMeshEntry.toLatin1().data() );
-  if ( !pMesh )
+  QString anObjEntry = myDlg->selectedObject( 0 );
+  _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() );
+  if ( !pObj )
   {
     dlg()->show();
     SUIT_MessageBox::warning( myDlg,
-                             tr( "SMESH_WRN_WARNING" ), tr("MESH_IS_NOT_SELECTED") );
-   
+                              tr( "SMESH_WRN_WARNING" ), tr("MESH_IS_NOT_SELECTED") );
     return false;
   }
 
-  SMESH::SMESH_Mesh_var mesh =
-  SMESH::SObjectToInterface<SMESH::SMESH_Mesh>( pMesh );  
+  SMESH::SMESH_Mesh_var mesh;
+  SMESH::SMESH_IDSource_var idSource = 
+    SMESH::SObjectToInterface<SMESH::SMESH_IDSource>( pObj );  
+  if( !CORBA::is_nil(idSource) )
+    mesh = idSource->GetMesh();
 
   if( CORBA::is_nil(mesh) )
   {
     SUIT_MessageBox::warning( myDlg,
-                             tr( "SMESH_WRN_WARNING" ), tr("REF_IS_NULL") );
-
+                              tr( "SMESH_WRN_WARNING" ), tr("REF_IS_NULL") );
     return false;
-  } 
+  }
 
   bool aResult = false;
 
   try
   {
     SMESH::SMESH_MeshEditor_var aEditor = mesh->GetMeshEditor();
+    aResult = true; 
+    SMESH::SMESH_Mesh_var sourceMesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>( pObj );  
     if( !myDlg->CurrentRB() )
     {
       bool aParam = true;
       if( myDlg->IsEnabledCheck() )
-       aParam = myDlg->IsMediumNdsOnGeom();
+        aParam = myDlg->IsMediumNdsOnGeom();
 
-      aEditor->ConvertToQuadratic( aParam );
-      aResult = true; 
+      if ( sourceMesh->_is_nil() )
+        aEditor->ConvertToQuadraticObject( aParam, idSource );
+      else
+        aEditor->ConvertToQuadratic( aParam );
     }
     else
     {
-      aResult = aEditor->ConvertFromQuadratic();
+      if ( sourceMesh->_is_nil() )
+        aEditor->ConvertFromQuadraticObject( idSource );
+      else
+        aEditor->ConvertFromQuadratic();
     }
   }
   catch ( const SALOME::SALOME_Exception& S_ex )
@@ -231,6 +265,7 @@ bool SMESHGUI_ConvToQuadOp::onApply()
   }
   if( aResult )
   {
+    SMESHGUI::Modified();
     update( UF_ObjBrowser | UF_Model | UF_Viewer );
     selectionDone();
   }
@@ -242,42 +277,43 @@ bool SMESHGUI_ConvToQuadOp::onApply()
  *  Determines, what elements this mesh contains. 
  */
 //================================================================================
-SMESHGUI_ConvToQuadOp::MeshType SMESHGUI_ConvToQuadOp::ConsistMesh( const SMESH::SMESH_Mesh_var& mesh) const
+SMESHGUI_ConvToQuadOp::MeshType SMESHGUI_ConvToQuadOp::ConsistMesh( const SMESH::SMESH_IDSource_var& idSource) const
 {
-  int nbAllElem = 0, nbQEdges =0, nbQFaces =0, nbQVolum = 0;
-  int nbEdges = 0, nbFaces = 0, nbVolum = 0;
-
-  nbAllElem = (int)mesh->NbElements();
-  nbQEdges = (int)mesh->NbEdgesOfOrder(SMESH::ORDER_QUADRATIC);
-  nbQFaces = (int)mesh->NbFacesOfOrder(SMESH::ORDER_QUADRATIC);
-  nbQVolum = (int)mesh->NbVolumesOfOrder(SMESH::ORDER_QUADRATIC);
-
-  nbEdges = (int)mesh->NbEdgesOfOrder(SMESH::ORDER_LINEAR);
-  nbFaces = (int)mesh->NbFacesOfOrder(SMESH::ORDER_LINEAR);
-  nbVolum = (int)mesh->NbVolumesOfOrder(SMESH::ORDER_LINEAR);
-
-  if( nbAllElem == (nbQEdges+nbQFaces+nbQVolum) )
-    return SMESHGUI_ConvToQuadOp::Quadratic;
-  else if ( nbAllElem == (nbEdges+nbFaces+nbVolum) )
-    return SMESHGUI_ConvToQuadOp::Linear;
-  else 
-    return SMESHGUI_ConvToQuadOp::Comp;
+  SMESH::long_array_var nbElemOfType = idSource->GetMeshInfo();
+  bool hasQuad = ( nbElemOfType[SMDSEntity_Quad_Edge      ] ||
+                   nbElemOfType[SMDSEntity_Quad_Triangle  ] ||
+                   nbElemOfType[SMDSEntity_Quad_Quadrangle] ||
+                   nbElemOfType[SMDSEntity_Quad_Tetra     ] ||
+                   nbElemOfType[SMDSEntity_Quad_Hexa      ] ||
+                   nbElemOfType[SMDSEntity_Quad_Pyramid   ] ||
+                   nbElemOfType[SMDSEntity_Quad_Penta     ] );
+
+  bool hasLin  = ( nbElemOfType[SMDSEntity_Edge      ] ||
+                   nbElemOfType[SMDSEntity_Triangle  ] ||
+                   nbElemOfType[SMDSEntity_Quadrangle] ||
+                   nbElemOfType[SMDSEntity_Tetra     ] ||
+                   nbElemOfType[SMDSEntity_Hexa      ] ||
+                   nbElemOfType[SMDSEntity_Pyramid   ] ||
+                   nbElemOfType[SMDSEntity_Penta     ] );
+
+  if ( hasQuad && hasLin )
+    return Comp;
+  return hasQuad ? Quadratic : Linear;
 }
 
-
 void SMESHGUI_ConvToQuadOp::ConnectRadioButtons( int id )
 {
-  QString anMeshEntry = myDlg->selectedObject( 0 );
-  _PTR(SObject) pMesh = studyDS()->FindObjectID( anMeshEntry.toLatin1().data() );
-  if ( !pMesh ) return;
+  QString anObjEntry = myDlg->selectedObject( 0 );
+  _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() );
+  if ( !pObj ) return;
 
-  SMESH::SMESH_Mesh_var mesh =
-    SMESH::SObjectToInterface<SMESH::SMESH_Mesh>( pMesh );  
+  SMESH::SMESH_IDSource_var idSource = 
+    SMESH::SObjectToInterface<SMESH::SMESH_IDSource>( pObj );  
+  SMESH::SMESH_Mesh_var mesh = idSource->GetMesh();
 
-  GEOM::GEOM_Object_var mainGeom;
-  mainGeom = mesh->GetShapeToMesh();
+  bool hasGeom = mesh->HasShapeToMesh();
 
-  if( id || mainGeom->_is_nil() )
+  if( id || !hasGeom )
     myDlg->SetEnabledCheck( false );
   else
     myDlg->SetEnabledCheck( true );
index ad60ea5ea35ec826dbdeab9f3394deb43b8d6f3e..9e2cbb1298941da564a5c71a40e91d11d112165f 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_ConvToQuadOp.h
 // Author : Open CASCADE S.A.S.
@@ -54,7 +55,7 @@ protected:
   virtual void                   startOperation();
   virtual void                   selectionDone();
   virtual SUIT_SelectionFilter*  createFilter( const int ) const;
-  MeshType                       ConsistMesh( const SMESH::SMESH_Mesh_var& ) const;
+  MeshType                       ConsistMesh( const SMESH::SMESH_IDSource_var& ) const;
 
 protected slots:
   virtual bool                   onApply();
diff --git a/src/SMESHGUI/SMESHGUI_CopyMeshDlg.cxx b/src/SMESHGUI/SMESHGUI_CopyMeshDlg.cxx
new file mode 100644 (file)
index 0000000..7c3d1d6
--- /dev/null
@@ -0,0 +1,697 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+//  File   : SMESHGUI_CopyMeshDlg.cxx
+
+#include "SMESHGUI_CopyMeshDlg.h"
+
+#include "SMESHGUI.h"
+#include "SMESHGUI_SpinBox.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_VTKUtils.h"
+#include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI_IdValidator.h"
+#include "SMESHGUI_FilterDlg.h"
+
+#include <SMESH_Actor.h>
+#include <SMESH_TypeFilter.hxx>
+#include <SMDS_Mesh.hxx>
+
+// SALOME GUI includes
+#include <SUIT_Desktop.h>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_Session.h>
+#include <SUIT_MessageBox.h>
+#include <SUIT_OverrideCursor.h>
+
+#include <LightApp_Application.h>
+#include <LightApp_SelectionMgr.h>
+
+#include <SVTK_ViewModel.h>
+#include <SVTK_ViewWindow.h>
+#include <SALOME_ListIO.hxx>
+
+// SALOME KERNEL includes
+#include <SALOMEDSClient_SObject.hxx>
+
+// OCCT includes
+#include <TColStd_MapOfInteger.hxx>
+
+// Qt includes
+#include <QApplication>
+#include <QButtonGroup>
+#include <QGroupBox>
+#include <QLabel>
+#include <QLineEdit>
+#include <QPushButton>
+#include <QRadioButton>
+#include <QCheckBox>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QGridLayout>
+#include <QSpinBox>
+#include <QKeyEvent>
+
+// IDL includes
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
+/*!
+  \class BusyLocker
+  \brief Simple 'busy state' flag locker.
+  \internal
+*/
+
+namespace
+{
+  class BusyLocker
+  {
+  public:
+    //! Constructor. Sets passed boolean flag to \c true.
+    BusyLocker( bool& busy ) : myBusy( busy ) { myBusy = true; }
+    //! Destructor. Clear external boolean flag passed as parameter to the constructor to \c false.
+    ~BusyLocker() { myBusy = false; }
+  private:
+    bool& myBusy; //! External 'busy state' boolean flag
+  };
+}
+
+#define SPACING 6
+#define MARGIN  11
+
+//To disable automatic genericobj management, the following line should be commented.
+//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
+#define WITHGENERICOBJ
+
+
+//================================================================================
+/*!
+ * \brief Constructor
+ */
+//================================================================================
+
+SMESHGUI_CopyMeshDlg::SMESHGUI_CopyMeshDlg( SMESHGUI* theModule )
+  : QDialog( SMESH::GetDesktop( theModule ) ),
+    mySMESHGUI( theModule ),
+    mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
+    myFilterDlg(0),
+    mySelectedObject(SMESH::SMESH_IDSource::_nil()),
+    myIsApplyAndClose( false )
+{
+  QPixmap image (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_COPY_MESH")));
+
+  setModal(false);
+  setAttribute(Qt::WA_DeleteOnClose, true);
+  setWindowTitle(tr("SMESH_COPY_MESH_TITLE"));
+  setSizeGripEnabled(true);
+
+  QVBoxLayout* SMESHGUI_CopyMeshDlgLayout = new QVBoxLayout(this);
+  SMESHGUI_CopyMeshDlgLayout->setSpacing(SPACING);
+  SMESHGUI_CopyMeshDlgLayout->setMargin(MARGIN);
+
+  /***************************************************************/
+  ConstructorsBox = new QGroupBox(tr("SMESH_COPY_MESH_TITLE"), this);
+  QButtonGroup* GroupConstructors = new QButtonGroup(this);
+  QHBoxLayout* ConstructorsBoxLayout = new QHBoxLayout(ConstructorsBox);
+  ConstructorsBoxLayout->setSpacing(SPACING);
+  ConstructorsBoxLayout->setMargin(MARGIN);
+
+  QRadioButton* RadioButton1= new QRadioButton(ConstructorsBox);
+  RadioButton1->setIcon(image);
+  GroupConstructors->addButton(RadioButton1, 0);
+
+  ConstructorsBoxLayout->addWidget(RadioButton1);
+  RadioButton1->setChecked(true);
+  GroupConstructors->addButton(RadioButton1, 0);
+
+  /***************************************************************/
+  GroupArguments = new QGroupBox(tr("SMESH_ARGUMENTS"), this);
+  QGridLayout* GroupArgumentsLayout = new QGridLayout(GroupArguments);
+  GroupArgumentsLayout->setSpacing(SPACING);
+  GroupArgumentsLayout->setMargin(MARGIN);
+
+  myIdValidator = new SMESHGUI_IdValidator(this);
+
+  // Controls for idSource/elements selection
+  myTextLabelElements = new QLabel(tr("OBJECT_NAME"), GroupArguments);
+  myLineEditElements = new QLineEdit(GroupArguments);
+  myLineEditElements->setValidator(myIdValidator);
+  myLineEditElements->setMaxLength(-1);
+  myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
+  connect(myFilterBtn,   SIGNAL(clicked()), this, SLOT(setFilters()));
+
+  // Control for the mesh objects selection
+  myIdSourceCheck = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments);
+
+  // Name of a mesh to create
+  QLabel* meshNameLabel = new QLabel(tr("NEW_NAME"), GroupArguments);
+  myMeshNameEdit = new QLineEdit(GroupArguments);
+
+  // CheckBox for copying groups
+  myCopyGroupsCheck = new QCheckBox(tr("SMESH_MAKE_GROUPS"), GroupArguments);
+  myCopyGroupsCheck->setChecked(false);
+
+  // CheckBox for keeping ids
+  myKeepIdsCheck = new QCheckBox(tr("SMESH_KEEP_IDS"), GroupArguments);
+  myKeepIdsCheck->setChecked(true);
+
+  // layout
+  GroupArgumentsLayout->addWidget(myTextLabelElements,  0, 0);
+  GroupArgumentsLayout->addWidget(myLineEditElements,   0, 1, 1, 5);
+  GroupArgumentsLayout->addWidget(myFilterBtn,          0, 6);
+  GroupArgumentsLayout->addWidget(myIdSourceCheck,      1, 0, 1, 6);
+  GroupArgumentsLayout->addWidget(meshNameLabel,        2, 0);
+  GroupArgumentsLayout->addWidget(myMeshNameEdit,       2, 1, 1, 5);
+  GroupArgumentsLayout->addWidget(myCopyGroupsCheck,    3, 0, 1, 6);
+  GroupArgumentsLayout->addWidget(myKeepIdsCheck,       4, 0, 1, 6);
+
+  /***************************************************************/
+  GroupButtons = new QGroupBox(this);
+  QHBoxLayout* GroupButtonsLayout = new QHBoxLayout(GroupButtons);
+  GroupButtonsLayout->setSpacing(SPACING);
+  GroupButtonsLayout->setMargin(MARGIN);
+
+  buttonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), GroupButtons);
+  buttonOk->setAutoDefault(true);
+  buttonOk->setDefault(true);
+  buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons);
+  buttonApply->setAutoDefault(true);
+  buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons);
+  buttonCancel->setAutoDefault(true);
+  buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons);
+  buttonHelp->setAutoDefault(true);
+
+  GroupButtonsLayout->addWidget(buttonOk);
+  GroupButtonsLayout->addSpacing(10);
+  GroupButtonsLayout->addWidget(buttonApply);
+  GroupButtonsLayout->addSpacing(10);
+  GroupButtonsLayout->addStretch();
+  GroupButtonsLayout->addWidget(buttonCancel);
+  GroupButtonsLayout->addWidget(buttonHelp);
+
+  /***************************************************************/
+  SMESHGUI_CopyMeshDlgLayout->addWidget(ConstructorsBox);
+  SMESHGUI_CopyMeshDlgLayout->addWidget(GroupArguments);
+  SMESHGUI_CopyMeshDlgLayout->addWidget(GroupButtons);
+
+  /* Initialisations */
+  mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
+
+  mySMESHGUI->SetActiveDialogBox((QDialog*)this);
+
+  // Selection filter
+  myIdSourceFilter = new SMESH_TypeFilter( IDSOURCE );
+
+  myHelpFileName = "copy_mesh_page.html";
+
+  Init();
+
+  /* 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(buttonHelp,   SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
+
+  connect(mySMESHGUI,     SIGNAL (SignalDeactivateActiveDialog()),
+          this,           SLOT   (DeactivateActiveDialog()));
+  connect(mySelectionMgr, SIGNAL (currentSelectionChanged()),
+          this,           SLOT   (SelectionIntoArgument()));
+  connect(mySMESHGUI,     SIGNAL (SignalCloseAllDialogs()),/* to close dialog if study change */
+          this,           SLOT   (ClickOnCancel()));
+
+  connect(myLineEditElements, SIGNAL(textChanged(const QString&)),
+          this,               SLOT  (onTextChange(const QString&)));
+  connect(myIdSourceCheck,    SIGNAL(toggled(bool)),
+          this,               SLOT  (onSelectIdSource(bool)));
+
+  SelectionIntoArgument();
+}
+
+//=================================================================================
+// function : ~SMESHGUI_CopyMeshDlg()
+// purpose  : Destroys the object and frees any allocated resources
+//=================================================================================
+
+SMESHGUI_CopyMeshDlg::~SMESHGUI_CopyMeshDlg()
+{
+  if ( myFilterDlg )
+  {
+    myFilterDlg->setParent( 0 );
+    delete myFilterDlg; myFilterDlg = 0;
+  }
+  if ( myIdSourceFilter )
+  {
+    if ( mySelectionMgr )
+      mySelectionMgr->removeFilter( myIdSourceFilter );
+    delete myIdSourceFilter; myIdSourceFilter=0;
+  }
+}
+
+//=================================================================================
+// function : Init()
+// purpose  :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::Init (bool ResetControls)
+{
+  myBusy = false;
+
+  myMeshNameEdit->setText( SMESH::UniqueMeshName("Mesh"));
+  if ( ResetControls )
+  {
+    myLineEditElements->clear();
+    //myElementsId = "";
+    myNbOkElements = 0;
+
+    buttonOk->setEnabled(false);
+    buttonApply->setEnabled(false);
+
+    myActor = 0;
+    myMesh = SMESH::SMESH_Mesh::_nil();
+
+    myIdSourceCheck->setChecked(true);
+    myCopyGroupsCheck->setChecked(false);
+    myKeepIdsCheck->setChecked(false);
+
+    onSelectIdSource( myIdSourceCheck->isChecked() );
+  }
+}
+
+//=================================================================================
+// function : ClickOnApply()
+// purpose  :
+//=================================================================================
+
+bool SMESHGUI_CopyMeshDlg::ClickOnApply()
+{
+  if (mySMESHGUI->isActiveStudyLocked())
+    return false;
+
+  if( !isValid() )
+    return false;
+
+  QStringList anEntryList;
+  try
+  {
+    SUIT_OverrideCursor aWaitCursor;
+    SMESH::SMESH_IDSource_var aPartToCopy;
+    if ( myIdSourceCheck->isChecked())
+    {
+      aPartToCopy = mySelectedObject;
+    }
+    else
+    {
+      QStringList aListElementsId = myLineEditElements->text().split(" ", QString::SkipEmptyParts);
+      SMESH::long_array_var anElementsId = new SMESH::long_array;
+      anElementsId->length(aListElementsId.count());
+      for (int i = 0; i < aListElementsId.count(); i++)
+        anElementsId[i] = aListElementsId[i].toInt();
+
+      SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
+      aPartToCopy = aMeshEditor->MakeIDSource( anElementsId, SMESH::ALL );
+    }
+    QByteArray meshName = myMeshNameEdit->text().toLatin1();
+    bool toCopyGroups = ( myCopyGroupsCheck->isChecked() );
+    bool toKeepIDs    = ( myKeepIdsCheck->isChecked() );
+
+    SMESH::SMESH_Gen_var gen = SMESHGUI::GetSMESHGen();
+    SMESH::SMESH_Mesh_var newMesh =
+      gen->CopyMesh(aPartToCopy, meshName.constData(), toCopyGroups, toKeepIDs);
+    if( !newMesh->_is_nil() )
+      if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( newMesh ) )
+        anEntryList.append( aSObject->GetID().c_str() );
+#ifdef WITHGENERICOBJ
+    // obj has been published in study. Its refcount has been incremented.
+    // It is safe to decrement its refcount
+    // so that it will be destroyed when the entry in study will be removed
+    newMesh->UnRegister();
+#endif
+  } catch (...) {
+  }
+
+  mySMESHGUI->updateObjBrowser(true);
+  SMESHGUI::Modified();
+
+  if( LightApp_Application* anApp =
+      dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
+    anApp->browseObjects( anEntryList, isApplyAndClose() );
+
+  Init(false);
+  mySelectedObject = SMESH::SMESH_IDSource::_nil();
+  SelectionIntoArgument();
+
+  return true;
+}
+
+//=================================================================================
+// function : ClickOnOk()
+// purpose  :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::ClickOnOk()
+{
+  setIsApplyAndClose( true );
+  if( ClickOnApply() )
+    ClickOnCancel();
+}
+
+//=================================================================================
+// function : ClickOnCancel()
+// purpose  :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::ClickOnCancel()
+{
+  disconnect(mySelectionMgr, 0, this, 0);
+  if ( mySelectionMgr )
+    mySelectionMgr->removeFilter( myIdSourceFilter );
+  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+    aViewWindow->SetSelectionMode( ActorSelection );
+  mySMESHGUI->ResetState();
+  reject();
+}
+
+//=================================================================================
+// function : ClickOnHelp()
+// purpose  :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::ClickOnHelp()
+{
+  LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
+  if (app)
+    app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
+  else {
+    QString platform;
+#ifdef WIN32
+    platform = "winapplication";
+#else
+    platform = "application";
+#endif
+    SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser",
+                                                                 platform)).
+                             arg(myHelpFileName));
+  }
+}
+
+//=======================================================================
+// function : onTextChange()
+// purpose  :
+//=======================================================================
+
+void SMESHGUI_CopyMeshDlg::onTextChange (const QString& theNewText)
+{
+  QLineEdit* send = (QLineEdit*)sender();
+
+  if (myBusy) return;
+  BusyLocker lock( myBusy );
+
+  //if (send == myLineEditElements)
+  myNbOkElements = 0;
+
+  buttonOk->setEnabled(false);
+  buttonApply->setEnabled(false);
+
+  // hilight entered elements
+  SMDS_Mesh* aMesh = 0;
+  if (myActor)
+    aMesh = myActor->GetObject()->GetMesh();
+
+  QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
+  if (myActor && aMesh)
+  {
+    TColStd_MapOfInteger newIndices;
+    if (send == myLineEditElements) {
+      for (int i = 0; i < aListId.count(); i++)
+        if ( const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt()))
+        {
+          newIndices.Add(e->GetID());
+        }
+    }
+    myNbOkElements = newIndices.Extent();
+
+    Handle(SALOME_InteractiveObject) anIO = myActor->getIO();
+    mySelector->AddOrRemoveIndex( anIO, newIndices, false );
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->highlight( anIO, true, true );
+  }
+  else
+  {
+    myNbOkElements = aListId.count();
+  }
+
+  if (myNbOkElements) {
+    buttonOk->setEnabled(true);
+    buttonApply->setEnabled(true);
+  }
+}
+
+//=================================================================================
+// function : SelectionIntoArgument()
+// purpose  : Called when selection as changed or other case
+//=================================================================================
+
+void SMESHGUI_CopyMeshDlg::SelectionIntoArgument()
+{
+  if (myBusy) return;
+  BusyLocker lock( myBusy );
+
+  // clear
+  myActor = 0;
+  QString aString = "";
+
+  myLineEditElements->setText(aString);
+  myNbOkElements = 0;
+  buttonOk->setEnabled(false);
+  buttonApply->setEnabled(false);
+  myFilterBtn->setEnabled(false);
+
+  // get selected mesh
+  SALOME_ListIO aList;
+  mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
+  int nbSel = aList.Extent();
+  if (nbSel != 1)
+    return;
+
+  Handle(SALOME_InteractiveObject) IO = aList.First();
+  mySelectedObject = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
+  if ( mySelectedObject->_is_nil() )
+    return;
+
+  myMesh = SMESH::GetMeshByIO(IO);
+  if (myMesh->_is_nil())
+    return;
+
+  myActor = SMESH::FindActorByEntry(IO->getEntry());
+  if (!myActor)
+    myActor = SMESH::FindActorByObject(myMesh);
+
+  if (myIdSourceCheck->isChecked())
+  {
+    SMESH::GetNameOfSelectedIObjects( mySelectionMgr, aString );
+    if ( aString.isEmpty() ) aString = " ";
+    else                     aString = aString.trimmed(); // issue 0021327
+  }
+  else
+  {
+    SMESH::GetNameOfSelectedElements( mySelector, IO, aString );
+    myNbOkElements = aString.size();
+    myFilterBtn->setEnabled(true);
+  }
+  myLineEditElements->setText( aString );
+  bool ok = !aString.isEmpty();
+
+  buttonOk->setEnabled(ok);
+  buttonApply->setEnabled(ok);
+}
+
+//=======================================================================
+//function : onSelectIdSource
+//purpose  :
+//=======================================================================
+void SMESHGUI_CopyMeshDlg::onSelectIdSource (bool toSelectMesh)
+{
+  if (toSelectMesh)
+    myTextLabelElements->setText(tr("OBJECT_NAME"));
+  else
+    myTextLabelElements->setText(tr("ELEM_IDS"));
+
+  if (toSelectMesh) {
+    myLineEditElements->clear();
+  }
+
+  mySelectionMgr->clearFilters();
+  mySelectionMgr->installFilter(myIdSourceFilter);
+  SMESH::SetPointRepresentation(false);
+
+  if (toSelectMesh) {
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->SetSelectionMode( ActorSelection );
+    myLineEditElements->setReadOnly(true);
+    myLineEditElements->setValidator(0);
+  }
+  else
+  {
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->SetSelectionMode( CellSelection );
+    myLineEditElements->setReadOnly(false);
+    myLineEditElements->setValidator(myIdValidator);
+    onTextChange(myLineEditElements->text());
+  }
+
+  SelectionIntoArgument();
+}
+
+//=================================================================================
+// function : isValid
+// purpose  :
+//=================================================================================
+
+bool SMESHGUI_CopyMeshDlg::isValid()
+{
+  if ( myIdSourceCheck->isChecked() )
+    return !mySelectedObject->_is_nil();
+
+  return myNbOkElements > 0;
+}
+
+//=================================================================================
+// function : DeactivateActiveDialog()
+// purpose  :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::DeactivateActiveDialog()
+{
+  if (ConstructorsBox->isEnabled()) {
+    ConstructorsBox->setEnabled(false);
+    GroupArguments->setEnabled(false);
+    GroupButtons->setEnabled(false);
+    mySMESHGUI->ResetState();
+    mySMESHGUI->SetActiveDialogBox(0);
+    if ( mySelectionMgr )
+      mySelectionMgr->removeFilter( myIdSourceFilter );
+  }
+}
+
+//=================================================================================
+// function : ActivateThisDialog()
+// purpose  :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::ActivateThisDialog()
+{
+  /* Emit a signal to deactivate the active dialog */
+  mySMESHGUI->EmitSignalDeactivateDialog();
+  ConstructorsBox->setEnabled(true);
+  GroupArguments->setEnabled(true);
+  GroupButtons->setEnabled(true);
+
+  mySMESHGUI->SetActiveDialogBox((QDialog*)this);
+
+  onSelectIdSource( myIdSourceCheck->isChecked() );
+
+  SelectionIntoArgument();
+}
+
+//=================================================================================
+// function : enterEvent()
+// purpose  :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::enterEvent (QEvent*)
+{
+  if (!ConstructorsBox->isEnabled())
+    ActivateThisDialog();
+}
+
+//=================================================================================
+// function : closeEvent()
+// purpose  :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::closeEvent (QCloseEvent*)
+{
+  /* same than click on cancel button */
+  ClickOnCancel();
+}
+
+//=======================================================================
+//function : hideEvent
+//purpose  : caused by ESC key
+//=======================================================================
+void SMESHGUI_CopyMeshDlg::hideEvent (QHideEvent*)
+{
+  if (!isMinimized())
+    ClickOnCancel();
+}
+
+//=================================================================================
+// function : keyPressEvent()
+// purpose  :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::keyPressEvent( QKeyEvent* e )
+{
+  QDialog::keyPressEvent( e );
+  if ( e->isAccepted() )
+    return;
+
+  if ( e->key() == Qt::Key_F1 ) {
+    e->accept();
+    ClickOnHelp();
+  }
+}
+
+//=================================================================================
+// function : setFilters()
+// purpose  : SLOT. Called when "Filter" button pressed.
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::setFilters()
+{
+  if(myMesh->_is_nil()) {
+    SUIT_MessageBox::critical(this,
+                              tr("SMESH_ERROR"),
+                              tr("NO_MESH_SELECTED"));
+   return;
+  }
+  if ( !myFilterDlg )
+    myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL );
+
+  myFilterDlg->SetSelection();
+  myFilterDlg->SetMesh( myMesh );
+  myFilterDlg->SetSourceWg( myLineEditElements );
+
+  myFilterDlg->show();
+}
+
+//================================================================
+// function : setIsApplyAndClose
+// Purpose  : Set value of the flag indicating that the dialog is
+//            accepted by Apply & Close button
+//================================================================
+void SMESHGUI_CopyMeshDlg::setIsApplyAndClose( const bool theFlag )
+{
+  myIsApplyAndClose = theFlag;
+}
+
+//================================================================
+// function : isApplyAndClose
+// Purpose  : Get value of the flag indicating that the dialog is
+//            accepted by Apply & Close button
+//================================================================
+bool SMESHGUI_CopyMeshDlg::isApplyAndClose() const
+{
+  return myIsApplyAndClose;
+}
diff --git a/src/SMESHGUI/SMESHGUI_CopyMeshDlg.h b/src/SMESHGUI/SMESHGUI_CopyMeshDlg.h
new file mode 100644 (file)
index 0000000..b0c3b93
--- /dev/null
@@ -0,0 +1,130 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+// SMESH SMESHGUI : GUI for SMESH component
+// File   : SMESHGUI_CopyMeshDlg.h
+//
+#ifndef SMESHGUI_CopyMeshDLG_H
+#define SMESHGUI_CopyMeshDLG_H
+
+// SMESH includes
+#include "SMESH_SMESHGUI.hxx"
+
+// Qt includes
+#include <QDialog>
+
+// IDL includes
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+
+class QCheckBox;
+class QGroupBox;
+class QLabel;
+class QLineEdit;
+class QPushButton;
+
+class SMESHGUI;
+class SMESHGUI_IdValidator;
+class SMESHGUI_FilterDlg;
+class SMESH_Actor;
+class SVTK_Selector;
+class LightApp_SelectionMgr;
+class SUIT_SelectionFilter;
+
+//=================================================================================
+// class    : SMESHGUI_CopyMeshDlg
+// purpose  : copy some elements or a mesh object into a new mesh
+//=================================================================================
+
+class SMESHGUI_EXPORT SMESHGUI_CopyMeshDlg : public QDialog
+{ 
+  Q_OBJECT
+
+public:
+  SMESHGUI_CopyMeshDlg( SMESHGUI* );
+  ~SMESHGUI_CopyMeshDlg();
+
+private:
+  void                   Init( bool = true );
+  void                   closeEvent( QCloseEvent* );
+  void                   enterEvent( QEvent* );           /* mouse enter the QWidget */
+  void                   hideEvent( QHideEvent* );        /* ESC key */
+  void                   keyPressEvent( QKeyEvent* );
+  int                    GetConstructorId();
+  void                   setNewMeshName();
+
+  bool                   isValid();
+
+  void                   setIsApplyAndClose( const bool theFlag );
+  bool                   isApplyAndClose() const;
+
+  SMESHGUI*              mySMESHGUI;              /* Current SMESHGUI object */
+  SMESHGUI_IdValidator*  myIdValidator;
+  LightApp_SelectionMgr* mySelectionMgr;          /* User shape selection */
+  int                    myNbOkElements;          /* to check when elements are defined */
+
+  SVTK_Selector*         mySelector;
+
+  bool                   myBusy;
+  SMESH::SMESH_Mesh_var  myMesh;
+  SMESH_Actor*           myActor;
+  SUIT_SelectionFilter*  myIdSourceFilter;
+
+  SMESH::SMESH_IDSource_var mySelectedObject;
+
+  QGroupBox*             ConstructorsBox;
+  QGroupBox*             GroupArguments;
+  QGroupBox*             GroupButtons;
+  
+  QPushButton*           buttonOk;
+  QPushButton*           buttonCancel;
+  QPushButton*           buttonApply;
+  QPushButton*           buttonHelp;
+
+  QLabel*                myTextLabelElements;
+  QLineEdit*             myLineEditElements;
+  QLineEdit*             myMeshNameEdit;
+  QCheckBox*             myIdSourceCheck;
+  QCheckBox*             myCopyGroupsCheck;
+  QCheckBox*             myKeepIdsCheck;
+
+  QPushButton*           myFilterBtn;
+  SMESHGUI_FilterDlg*    myFilterDlg;
+   
+  QString                myHelpFileName;
+
+  bool                   myIsApplyAndClose;
+
+private slots:
+  void                   ClickOnOk();
+  void                   ClickOnCancel();
+  bool                   ClickOnApply();
+  void                   ClickOnHelp();
+  void                   SelectionIntoArgument();
+  void                   DeactivateActiveDialog();
+  void                   ActivateThisDialog();
+  void                   onTextChange( const QString& );
+  void                   onSelectIdSource( bool );
+  void                   setFilters();
+};
+
+#endif // SMESHGUI_CopyMeshDLG_H
index ef7f198ee9966f23ef4d9b82eb4e8875173d3c39..ac3c7193196579be1b4678894c07883b0815141f 100755 (executable)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : SMESHGUI_CreatePatternDlg.cxx
 // Author : Sergey LITONIN, Open CASCADE S.A.S.
 // SMESH includes
@@ -193,11 +194,11 @@ QWidget* SMESHGUI_CreatePatternDlg::createMainFrame( QWidget* theParent )
   // Connect signals and slots
 
   connect( myTypeGrp,    SIGNAL( buttonClicked( int )  ),
-          this,         SLOT( onTypeChanged( int ) ) );
+           this,         SLOT( onTypeChanged( int ) ) );
   connect( myProjectChk, SIGNAL( toggled( bool ) ),
-          this,         SLOT( onProject( bool ) ) );
+           this,         SLOT( onProject( bool ) ) );
   connect( aSelBtn,      SIGNAL( clicked() ),
-          this,         SLOT( onSelBtnClicked() ) );
+           this,         SLOT( onSelBtnClicked() ) );
 
   return aMainGrp;
 }
@@ -274,11 +275,11 @@ void SMESHGUI_CreatePatternDlg::Init( const int theType )
 
   // selection and SMESHGUI
   connect( mySelectionMgr, SIGNAL( currentSelectionChanged() ),
-          this,           SLOT( onSelectionDone() ) );
+           this,           SLOT( onSelectionDone() ) );
   connect( mySMESHGUI,     SIGNAL( SignalDeactivateActiveDialog() ),
-          this,           SLOT( onDeactivate() ) );
+           this,           SLOT( onDeactivate() ) );
   connect( mySMESHGUI,     SIGNAL( SignalCloseAllDialogs() ),
-          this,           SLOT( onClose() ) );
+           this,           SLOT( onClose() ) );
 
   mySwitch2d->setEnabled( theType == Type_2d );
   mySwitch3d->setEnabled( theType == Type_3d );
@@ -291,7 +292,7 @@ void SMESHGUI_CreatePatternDlg::Init( const int theType )
 
   QApplication::instance()->processEvents();
   updateGeometry();
-  resize( minimumSize() );
+  resize(100,100);
 
   activateSelection();
   onSelectionDone();
@@ -342,8 +343,8 @@ bool SMESHGUI_CreatePatternDlg::isValid()
 {
   if ( myGeomObj->_is_nil() ) {
     SUIT_MessageBox::information( this,
-                                 tr( "SMESH_INSUFFICIENT_DATA" ),
-                                 tr( "SMESHGUI_INVALID_PARAMETERS" ) );
+                                  tr( "SMESH_INSUFFICIENT_DATA" ),
+                                  tr( "SMESHGUI_INVALID_PARAMETERS" ) );
     return false;
   }
   return true;
@@ -406,13 +407,13 @@ void SMESHGUI_CreatePatternDlg::onSave()
 
     if ( aWritten != aLen ) {
       SUIT_MessageBox::information( this,
-                                   tr( "SMESH_ERROR" ),
-                                   tr( "ERROR_OF_SAVING" ) );
+                                    tr( "SMESH_ERROR" ),
+                                    tr( "ERROR_OF_SAVING" ) );
     } 
     else {
       //SUIT_Application::getDesktop()->setSelectionModes(ActorSelection);
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ) )
-       aViewWindow->SetSelectionMode( ActorSelection );
+        aViewWindow->SetSelectionMode( ActorSelection );
       disconnect( mySelectionMgr, 0, this, 0 );
       disconnect( mySMESHGUI, 0, this, 0 );
       mySMESHGUI->ResetState();
@@ -465,7 +466,7 @@ void SMESHGUI_CreatePatternDlg::onOk()
     else {
       //SUIT_Application::getDesktop()->setSelectionModes(ActorSelection);
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ) )
-       aViewWindow->SetSelectionMode( ActorSelection );
+        aViewWindow->SetSelectionMode( ActorSelection );
       disconnect( mySelectionMgr, 0, this, 0 );
       disconnect( mySMESHGUI, 0, this, 0 );
       mySMESHGUI->ResetState();
@@ -512,11 +513,11 @@ void SMESHGUI_CreatePatternDlg::onHelp()
     platform = "application";
 #endif
     SUIT_MessageBox::warning( this, 
-                             tr( "WRN_WARNING" ),
-                             tr( "EXTERNAL_BROWSER_CANNOT_SHOW_PAGE" ).
-                             arg( app->resourceMgr()->stringValue( "ExternalBrowser", 
-                                                                   platform ) ).
-                             arg( myHelpFileName ) );
+                              tr( "WRN_WARNING" ),
+                              tr( "EXTERNAL_BROWSER_CANNOT_SHOW_PAGE" ).
+                              arg( app->resourceMgr()->stringValue( "ExternalBrowser", 
+                                                                    platform ) ).
+                              arg( myHelpFileName ) );
   }
 }
 
@@ -532,7 +533,7 @@ bool SMESHGUI_CreatePatternDlg::loadFromObject( const bool theMess )
     if ( myPattern->_is_nil() )
       myPattern = SMESH::GetPattern();
 
-    if ( myMesh->_is_nil() && mySubMesh->_is_nil() || myGeomObj->_is_nil() )
+    if ( (myMesh->_is_nil() && mySubMesh->_is_nil()) || myGeomObj->_is_nil() )
       return false;
 
     SMESH::SMESH_Mesh_ptr aMesh = mySubMesh->_is_nil() ? myMesh.in() : mySubMesh->GetFather();
@@ -754,20 +755,20 @@ void SMESHGUI_CreatePatternDlg::activateSelection()
 
   if ( myType == Type_2d ) {
     mySelectionMgr->installFilter( new SMESH_NumberFilter( "SMESH",
-                                                          TopAbs_SHAPE,
-                                                          -1,
-                                                          TopAbs_FACE ) );
+                                                           TopAbs_SHAPE,
+                                                           -1,
+                                                           TopAbs_FACE ) );
   } 
   else {
     TColStd_MapOfInteger aTypes;
     aTypes.Add( TopAbs_SHELL );
     aTypes.Add( TopAbs_SOLID );
     mySelectionMgr->installFilter( new SMESH_NumberFilter( "SMESH",
-                                                          TopAbs_FACE,
-                                                          6,
-                                                          aTypes,
-                                                          GEOM::GEOM_Object::_nil(),
-                                                          true ) );
+                                                           TopAbs_FACE,
+                                                           6,
+                                                           aTypes,
+                                                           GEOM::GEOM_Object::_nil(),
+                                                           true ) );
   }
 }
 
index 838b609d4f126969a0d5cfadec6bc15ea46d7d0d..0a03e1061d8542fc70f1b32fced52f5735546c52 100755 (executable)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : SMESHGUI_CreatePatternDlg.h
 // Author : Sergey LITONIN, Open CASCADE S.A.S.
 //
index db615c8c4c43c18fdaa1409ecf0f8153ce940358..ffc22ecdbfdd9631aecb99e61681edf005265ee6 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_CreatePolyhedralVolumeDlg.cxx
 // Author : Michael ZORIN, Open CASCADE S.A.S.
@@ -30,6 +31,7 @@
 #include "SMESHGUI_Utils.h"
 #include "SMESHGUI_VTKUtils.h"
 #include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI_GroupUtils.h"
 #include "SMESHGUI_IdValidator.h"
 
 #include <SMESH_Actor.h>
@@ -63,6 +65,7 @@
 // Qt includes
 #include <QApplication>
 #include <QButtonGroup>
+#include <QComboBox>
 #include <QGroupBox>
 #include <QLabel>
 #include <QLineEdit>
@@ -129,9 +132,9 @@ namespace SMESH
 
     typedef std::vector<vtkIdType> TVTKIds;
     void SetPosition(SMESH_Actor* theActor, 
-                    vtkIdType theType, 
-                    const TVTKIds& theIds,
-                    bool theReset=true)
+                     vtkIdType theType, 
+                     const TVTKIds& theIds,
+                     bool theReset=true)
     {
       vtkUnstructuredGrid *aGrid = theActor->GetUnstructuredGrid();
       myGrid->SetPoints(aGrid->GetPoints());
@@ -141,14 +144,14 @@ namespace SMESH
       vtkIdList *anIds = vtkIdList::New();
 
       for (int i = 0, iEnd = theIds.size(); i < iEnd; i++)
-       anIds->InsertId(i,theIds[i]);
+        anIds->InsertId(i,theIds[i]);
 
       myGrid->InsertNextCell(theType,anIds);
       if(theIds.size()!=0){
-       myGrid->InsertNextCell(theType,anIds);
-       myGrid->Modified();
+        myGrid->InsertNextCell(theType,anIds);
+        myGrid->Modified();
       }
-       
+        
       anIds->Delete();
 
       SetVisibility(true);
@@ -167,7 +170,7 @@ namespace SMESH
 
     ~TPolySimulation(){
       if( myViewWindow )
-       myViewWindow->RemoveActor(myPreviewActor);
+        myViewWindow->RemoveActor(myPreviewActor);
 
       myPreviewActor->Delete();
 
@@ -246,6 +249,21 @@ SMESHGUI_CreatePolyhedralVolumeDlg::SMESHGUI_CreatePolyhedralVolumeDlg( SMESHGUI
   GroupContentLayout->addWidget( RemoveButton,         3, 3 );
   GroupContentLayout->addWidget( Preview,              5, 0, 1, 4 );
 
+  /***************************************************************/
+  GroupGroups = new QGroupBox( tr( "SMESH_ADD_TO_GROUP" ), this );
+  GroupGroups->setCheckable( true );
+  QHBoxLayout* GroupGroupsLayout = new QHBoxLayout(GroupGroups);
+  GroupGroupsLayout->setSpacing(SPACING);
+  GroupGroupsLayout->setMargin(MARGIN);
+
+  TextLabel_GroupName = new QLabel( tr( "SMESH_GROUP" ), GroupGroups );
+  ComboBox_GroupName = new QComboBox( GroupGroups );
+  ComboBox_GroupName->setEditable( true );
+  ComboBox_GroupName->setInsertPolicy( QComboBox::NoInsert );
+
+  GroupGroupsLayout->addWidget( TextLabel_GroupName );
+  GroupGroupsLayout->addWidget( ComboBox_GroupName, 1 );
+
   /***************************************************************/
   GroupButtons = new QGroupBox( this );
   QHBoxLayout* GroupButtonsLayout = new QHBoxLayout( GroupButtons );
@@ -273,6 +291,7 @@ SMESHGUI_CreatePolyhedralVolumeDlg::SMESHGUI_CreatePolyhedralVolumeDlg( SMESHGUI
   /***************************************************************/
   topLayout->addWidget( ConstructorsBox );
   topLayout->addWidget( GroupContent );
+  topLayout->addWidget( GroupGroups );
   topLayout->addWidget( GroupButtons );
   
   mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
@@ -306,6 +325,9 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::Init()
   myEditCurrentArgument = LineEditElements;
   mySMESHGUI->SetActiveDialogBox( (QDialog*)this );
 
+  /* reset "Add to group" control */
+  GroupGroups->setChecked( false );
+
   myNbOkElements = 0;
   myActor = 0;
 
@@ -321,7 +343,7 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::Init()
   connect(SelectElementsButton, SIGNAL( clicked() ), SLOT( SetEditCurrentArgument() ) );
   connect(LineEditElements, SIGNAL( textChanged(const QString&) ), SLOT(onTextChange(const QString&)));
 
-  connect(myFacesByNodes, SIGNAL(selectionChanged()), this, SLOT(onListSelectionChanged()));
+  connect(myFacesByNodes, SIGNAL(itemSelectionChanged()), this, SLOT(onListSelectionChanged()));
   connect(AddButton, SIGNAL(clicked()), this, SLOT(onAdd()));
   connect(RemoveButton, SIGNAL(clicked()), this, SLOT(onRemove()));
   
@@ -358,42 +380,42 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::ConstructorsClicked(int constructorId)
     {
     case 0 :
       { 
-       if ( myActor ){
+        if ( myActor ){
           myActor->SetPointRepresentation(true);
-       }
+        }
         else
           SMESH::SetPointRepresentation(true);
-       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-         aViewWindow->SetSelectionMode(NodeSelection);
-       
-       AddButton->setEnabled(false);
-       RemoveButton->setEnabled(false);
-       TextLabelIds->setText( tr( "SMESH_ID_NODES" ) );
-       myFacesByNodesLabel->show();
-       myFacesByNodes->clear();
-       myFacesByNodes->show();
-       AddButton->show();
-       RemoveButton->show();
-       Preview->show();
-       break;
+        if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+          aViewWindow->SetSelectionMode(NodeSelection);
+        
+        AddButton->setEnabled(false);
+        RemoveButton->setEnabled(false);
+        TextLabelIds->setText( tr( "SMESH_ID_NODES" ) );
+        myFacesByNodesLabel->show();
+        myFacesByNodes->clear();
+        myFacesByNodes->show();
+        AddButton->show();
+        RemoveButton->show();
+        Preview->show();
+        break;
       }
     case 1 :
       {
-       if( myActor ){
-         myActor->SetPointRepresentation(false);
-       } else {
-         SMESH::SetPointRepresentation(false);
-       }
-       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-         aViewWindow->SetSelectionMode(FaceSelection);
-       
-       TextLabelIds->setText( tr( "SMESH_ID_FACES" ) );
-       myFacesByNodesLabel->hide();
-       myFacesByNodes->hide();
-       AddButton->hide();
-       RemoveButton->hide();
-       Preview->show();
-       break;
+        if( myActor ){
+          myActor->SetPointRepresentation(false);
+        } else {
+          SMESH::SetPointRepresentation(false);
+        }
+        if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+          aViewWindow->SetSelectionMode(FaceSelection);
+        
+        TextLabelIds->setText( tr( "SMESH_ID_FACES" ) );
+        myFacesByNodesLabel->hide();
+        myFacesByNodes->hide();
+        AddButton->hide();
+        RemoveButton->hide();
+        Preview->show();
+        break;
       }
     }
   
@@ -402,7 +424,7 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::ConstructorsClicked(int constructorId)
 
   QApplication::instance()->processEvents();
   updateGeometry();
-  resize( minimumSize() );
+  resize(100,100);
 }
 
 //=================================================================================
@@ -420,80 +442,143 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::ClickOnPreview(bool theToggled){
 //=================================================================================
 void SMESHGUI_CreatePolyhedralVolumeDlg::ClickOnApply()
 {
+  if( !isValid() )
+    return;
+
   if ( myNbOkElements>0 && !mySMESHGUI->isActiveStudyLocked())
     {
       if(checkEditLine(false) == -1) {return;}
       busy = true;
+      long anElemId = -1;
+
+      bool addToGroup = GroupGroups->isChecked();
+      QString aGroupName;
+      
+      SMESH::SMESH_GroupBase_var aGroup;
+      int idx = 0;
+      if( addToGroup ) {
+        aGroupName = ComboBox_GroupName->currentText();
+        for ( int i = 1; i < ComboBox_GroupName->count(); i++ ) {
+          QString aName = ComboBox_GroupName->itemText( i );
+          if ( aGroupName == aName && ( i == ComboBox_GroupName->currentIndex() || idx == 0 ) )
+            idx = i;
+        }
+        if ( idx > 0 && idx < myGroups.count() ) {
+          SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( myGroups[idx-1] );
+          if ( !aGeomGroup->_is_nil() ) {
+            int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ),
+                                                 tr( "MESH_STANDALONE_GRP_CHOSEN" ).arg( aGroupName ),
+                                                 tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
+            if ( res == 1 ) return;
+          }
+          aGroup = myGroups[idx-1];
+        }
+      }
+
       if (GetConstructorId() == 0)
-       {
-         SMESH::long_array_var anIdsOfNodes = new SMESH::long_array;
-         SMESH::long_array_var aQuantities  = new SMESH::long_array;
-
-         aQuantities->length( myFacesByNodes->count() );
-
-         TColStd_ListOfInteger aNodesIds;
-
-         int aNbQuantities = 0;
-         for (int i = 0; i < myFacesByNodes->count(); i++ ) {
-           QStringList anIds = myFacesByNodes->item(i)->text().split( " ", QString::SkipEmptyParts );
-           for (QStringList::iterator it = anIds.begin(); it != anIds.end(); ++it)
-             aNodesIds.Append( (*it).toInt() );
-
-           aQuantities[aNbQuantities++] = anIds.count();
-         }
-
-         anIdsOfNodes->length(aNodesIds.Extent());
-
-         int aNbIdsOfNodes = 0;
-         TColStd_ListIteratorOfListOfInteger It;
-         It.Initialize(aNodesIds);
-         for( ;It.More();It.Next())
-           anIdsOfNodes[aNbIdsOfNodes++] = It.Value();
-           
-         try{
-           SUIT_OverrideCursor aWaitCursor;
-           SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
-           aMeshEditor->AddPolyhedralVolume(anIdsOfNodes, aQuantities);
-         }catch(SALOME::SALOME_Exception& exc){
-           INFOS("Follow exception was cought:\n\t"<<exc.details.text);
-         }catch(std::exception& exc){
-           INFOS("Follow exception was cought:\n\t"<<exc.what());
-         }catch(...){
-           INFOS("Unknown exception was cought !!!");
-         }
-       }
+        {
+          SMESH::long_array_var anIdsOfNodes = new SMESH::long_array;
+          SMESH::long_array_var aQuantities  = new SMESH::long_array;
+
+          aQuantities->length( myFacesByNodes->count() );
+
+          TColStd_ListOfInteger aNodesIds;
+
+          int aNbQuantities = 0;
+          for (int i = 0; i < myFacesByNodes->count(); i++ ) {
+            QStringList anIds = myFacesByNodes->item(i)->text().split( " ", QString::SkipEmptyParts );
+            for (QStringList::iterator it = anIds.begin(); it != anIds.end(); ++it)
+              aNodesIds.Append( (*it).toInt() );
+
+            aQuantities[aNbQuantities++] = anIds.count();
+          }
+
+          anIdsOfNodes->length(aNodesIds.Extent());
+
+          int aNbIdsOfNodes = 0;
+          TColStd_ListIteratorOfListOfInteger It;
+          It.Initialize(aNodesIds);
+          for( ;It.More();It.Next())
+            anIdsOfNodes[aNbIdsOfNodes++] = It.Value();
+            
+          try{
+            SUIT_OverrideCursor aWaitCursor;
+            SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
+            anElemId = aMeshEditor->AddPolyhedralVolume(anIdsOfNodes, aQuantities);
+          }catch(SALOME::SALOME_Exception& exc){
+            INFOS("Follow exception was cought:\n\t"<<exc.details.text);
+          }catch(std::exception& exc){
+            INFOS("Follow exception was cought:\n\t"<<exc.what());
+          }catch(...){
+            INFOS("Unknown exception was cought !!!");
+          }
+        }
       else if (GetConstructorId() == 1)
-       {
-         SMESH::long_array_var anIdsOfFaces = new SMESH::long_array;
-         
-         QStringList aListId = myEditCurrentArgument->text().split( " ", QString::SkipEmptyParts );
-         anIdsOfFaces->length(aListId.count());
-         for ( int i = 0; i < aListId.count(); i++ )
-           anIdsOfFaces[i] = aListId[i].toInt();
-         
-         try{
-           SUIT_OverrideCursor aWaitCursor;
-           SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
-           aMeshEditor->AddPolyhedralVolumeByFaces(anIdsOfFaces);
-         }catch(SALOME::SALOME_Exception& exc){
-           INFOS("Follow exception was cought:\n\t"<<exc.details.text);
-         }catch(std::exception& exc){
-           INFOS("Follow exception was cought:\n\t"<<exc.what());
-         }catch(...){
-           INFOS("Unknown exception was cought !!!");
-         }
-       }
-      
+        {
+          SMESH::long_array_var anIdsOfFaces = new SMESH::long_array;
+          
+          QStringList aListId = myEditCurrentArgument->text().split( " ", QString::SkipEmptyParts );
+          anIdsOfFaces->length(aListId.count());
+          for ( int i = 0; i < aListId.count(); i++ )
+            anIdsOfFaces[i] = aListId[i].toInt();
+          
+          try{
+            SUIT_OverrideCursor aWaitCursor;
+            SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
+            anElemId = aMeshEditor->AddPolyhedralVolumeByFaces(anIdsOfFaces);
+          }catch(SALOME::SALOME_Exception& exc){
+            INFOS("Follow exception was cought:\n\t"<<exc.details.text);
+          }catch(std::exception& exc){
+            INFOS("Follow exception was cought:\n\t"<<exc.what());
+          }catch(...){
+            INFOS("Unknown exception was cought !!!");
+          }
+        }
+
+      if ( anElemId != -1 && addToGroup && !aGroupName.isEmpty() ) {
+        SMESH::SMESH_Group_var aGroupUsed;
+        if ( aGroup->_is_nil() ) {
+          // create new group 
+          aGroupUsed = SMESH::AddGroup( myMesh, SMESH::VOLUME, aGroupName );
+          if ( !aGroupUsed->_is_nil() ) {
+            myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroupUsed));
+            ComboBox_GroupName->addItem( aGroupName );
+          }
+        }
+        else {
+          SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup );
+          if ( !aGeomGroup->_is_nil() ) {
+            aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup );
+            if ( !aGroupUsed->_is_nil() && idx > 0 ) {
+              myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed);
+              SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser();
+            }
+          }
+          else
+            aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup );
+        }
+        
+        if ( !aGroupUsed->_is_nil() ) {
+          SMESH::long_array_var anIdList = new SMESH::long_array;
+          anIdList->length( 1 );
+          anIdList[0] = anElemId;
+          aGroupUsed->Add( anIdList.inout() );
+        }
+      }
+
       //SALOME_ListIO aList;
       //mySelectionMgr->setSelectedObjects( aList );
       SMESH::UpdateView();
       if( myActor ){
-       unsigned int anEntityMode = myActor->GetEntityMode();
-       myActor->SetEntityMode(SMESH_Actor::eVolumes | anEntityMode);
+        unsigned int anEntityMode = myActor->GetEntityMode();
+        myActor->SetEntityMode(SMESH_Actor::eVolumes | anEntityMode);
       }
       //ConstructorsClicked( GetConstructorId() );
       busy = false;
+
+      SMESHGUI::Modified();
     }
+    myFacesByNodes->clear();
 }
 
 //=================================================================================
@@ -507,7 +592,7 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::ClickOnOk()
   ClickOnCancel();
 }
 
-       
+        
 //=================================================================================
 // function : ClickOnCancel()
 // purpose  :
@@ -543,10 +628,10 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::ClickOnHelp()
     platform = "application";
 #endif
     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser",
-                                                                platform)).
-                            arg(myHelpFileName));
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser",
+                                                                 platform)).
+                             arg(myHelpFileName));
   }
 }
 
@@ -570,67 +655,67 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::onTextChange(const QString& theNewText)
   if (GetConstructorId() == 0)
     {
       if ( aMesh ) {
-       TColStd_MapOfInteger newIndices;
+        TColStd_MapOfInteger newIndices;
       
-       QStringList aListId = theNewText.split( " ", QString::SkipEmptyParts );
-       for ( int i = 0; i < aListId.count(); i++ ) {
-         const SMDS_MeshNode * n = aMesh->FindNode( aListId[ i ].toInt() );
-         if ( n ) {
-           newIndices.Add(n->GetID());
-           myNbOkElements++;
-         }
-       }
+        QStringList aListId = theNewText.split( " ", QString::SkipEmptyParts );
+        for ( int i = 0; i < aListId.count(); i++ ) {
+          const SMDS_MeshNode * n = aMesh->FindNode( aListId[ i ].toInt() );
+          if ( n ) {
+            newIndices.Add(n->GetID());
+            myNbOkElements++;
+          }
+        }
       
-       mySelector->AddOrRemoveIndex( myActor->getIO(), newIndices, false );
+        mySelector->AddOrRemoveIndex( myActor->getIO(), newIndices, false );
       
-       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-         aViewWindow->highlight( myActor->getIO(), true, true );
+        if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+          aViewWindow->highlight( myActor->getIO(), true, true );
       
-       if ( myNbOkElements>0 && aListId.count()>=3)
-         AddButton->setEnabled(true);
-       else
-         AddButton->setEnabled(false);
+        if ( myNbOkElements>0 && aListId.count()>=3)
+          AddButton->setEnabled(true);
+        else
+          AddButton->setEnabled(false);
       
-       displaySimulation();
+        displaySimulation();
       }
     } else if (GetConstructorId() == 1)
       {
-       myNbOkElements = 0;
-       buttonOk->setEnabled( false );
-       buttonApply->setEnabled( false );
+        myNbOkElements = 0;
+        buttonOk->setEnabled( false );
+        buttonApply->setEnabled( false );
       
-       // check entered ids of faces and hilight them
-       QStringList aListId;
-       if ( aMesh ) {
-         TColStd_MapOfInteger newIndices;
+        // check entered ids of faces and hilight them
+        QStringList aListId;
+        if ( aMesh ) {
+          TColStd_MapOfInteger newIndices;
       
-         aListId = theNewText.split( " ", QString::SkipEmptyParts );
-
-         for ( int i = 0; i < aListId.count(); i++ ) {
-           const SMDS_MeshElement * e = aMesh->FindElement( aListId[ i ].toInt() );
-           if ( e ) {
-             newIndices.Add(e->GetID());
-             myNbOkElements++;  
-           }
-         }
-
-         mySelector->AddOrRemoveIndex( myActor->getIO(), newIndices, false );
-         if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-           aViewWindow->highlight( myActor->getIO(), true, true );
+          aListId = theNewText.split( " ", QString::SkipEmptyParts );
+
+          for ( int i = 0; i < aListId.count(); i++ ) {
+            const SMDS_MeshElement * e = aMesh->FindElement( aListId[ i ].toInt() );
+            if ( e ) {
+              newIndices.Add(e->GetID());
+              myNbOkElements++;  
+            }
+          }
+
+          mySelector->AddOrRemoveIndex( myActor->getIO(), newIndices, false );
+          if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+            aViewWindow->highlight( myActor->getIO(), true, true );
       
-         if ( myNbOkElements ) {
-           if (aListId.count()>1){ 
-             buttonOk->setEnabled( true );
-             buttonApply->setEnabled( true );
-           }
-           else{
-             buttonOk->setEnabled( false );
-             buttonApply->setEnabled( false );
-           }
-           if(aListId.count()>1)
-             displaySimulation();
-         }
-       }
+          if ( myNbOkElements ) {
+            if (aListId.count()>1){ 
+              buttonOk->setEnabled( true );
+              buttonApply->setEnabled( true );
+            }
+            else{
+              buttonOk->setEnabled( false );
+              buttonApply->setEnabled( false );
+            }
+            if(aListId.count()>1)
+              displaySimulation();
+          }
+        }
       }
   busy = false;
 }
@@ -663,6 +748,8 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::SelectionIntoArgument()
   
   mySimulation->SetVisibility(false);
   
+  QString aCurrentEntry = myEntry;
+
   // get selected mesh
   
   SALOME_ListIO selected;
@@ -672,10 +759,29 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::SelectionIntoArgument()
     return;
   }
   
+  myEntry = selected.First()->getEntry();
   myMesh = SMESH::GetMeshByIO( selected.First() );
   if ( myMesh->_is_nil() )
     return;
   
+  // process groups
+  if ( !myMesh->_is_nil() && myEntry != aCurrentEntry ) {
+    myGroups.clear();
+    ComboBox_GroupName->clear();
+    ComboBox_GroupName->addItem( QString() );
+    SMESH::ListOfGroups aListOfGroups = *myMesh->GetGroups();
+    for ( int i = 0, n = aListOfGroups.length(); i < n; i++ ) {
+      SMESH::SMESH_GroupBase_var aGroup = aListOfGroups[i];
+      if ( !aGroup->_is_nil() && aGroup->GetType() == SMESH::VOLUME ) {
+        QString aGroupName( aGroup->GetName() );
+        if ( !aGroupName.isEmpty() ) {
+          myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup));
+          ComboBox_GroupName->addItem( aGroupName );
+        }
+      }
+    }
+  }
+
   myActor = SMESH::FindActorByObject(myMesh);
   if ( !myActor )
     return;
@@ -749,13 +855,13 @@ int SMESHGUI_CreatePolyhedralVolumeDlg::checkEditLine(bool checkLast)
     case 0:{ // nodes
       const SMDS_MeshNode    * aNode = aMesh->FindNode( aListId[ i ].toInt() );
       if( !aNode ){
-       SUIT_MessageBox::warning(this,
-                                tr("SMESH_POLYEDRE_CREATE_ERROR"),
-                                tr("The incorrect indices of nodes!"));
-       
-       myEditCurrentArgument->clear();
-       myEditCurrentArgument->setText( aString );
-       return -1;
+        SUIT_MessageBox::warning(this,
+                                 tr("SMESH_POLYEDRE_CREATE_ERROR"),
+                                 tr("The incorrect indices of nodes!"));
+        
+        myEditCurrentArgument->clear();
+        myEditCurrentArgument->setText( aString );
+        return -1;
       }
 
       break;
@@ -764,24 +870,24 @@ int SMESHGUI_CreatePolyhedralVolumeDlg::checkEditLine(bool checkLast)
       bool aElemIsOK = true;
       const SMDS_MeshElement * aElem = aMesh->FindElement( aListId[ i ].toInt() );
       if (!aElem)
-       {
-         aElemIsOK = false;
-       }
+        {
+          aElemIsOK = false;
+        }
       else
-       {
-         SMDSAbs_ElementType aType = aMesh->GetElementType( aElem->GetID(),true );
-         if (aType != SMDSAbs_Face){
-           aElemIsOK = false;
-         }
-       }
+        {
+          SMDSAbs_ElementType aType = aMesh->GetElementType( aElem->GetID(),true );
+          if (aType != SMDSAbs_Face){
+            aElemIsOK = false;
+          }
+        }
       if (!aElemIsOK){
-       SUIT_MessageBox::warning(this,
-                                tr("SMESH_POLYEDRE_CREATE_ERROR"),
-                                tr("The incorrect indices of faces!"));
-       
-       myEditCurrentArgument->clear();
-       myEditCurrentArgument->setText( aString );
-       return -1;
+        SUIT_MessageBox::warning(this,
+                                 tr("SMESH_POLYEDRE_CREATE_ERROR"),
+                                 tr("The incorrect indices of faces!"));
+        
+        myEditCurrentArgument->clear();
+        myEditCurrentArgument->setText( aString );
+        return -1;
       }
       break;
     }
@@ -804,66 +910,66 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::displaySimulation()
       vtkIdType aType = VTK_CONVEX_POINT_SET;
       SMDS_Mesh* aMesh = 0;
       if ( myActor ){
-       aMesh = myActor->GetObject()->GetMesh();
+        aMesh = myActor->GetObject()->GetMesh();
       }
       if (GetConstructorId() == 0 && aMesh){
-       if (!AddButton->isEnabled()){
-         mySimulation->ResetGrid(true);
-         for (int i = 0; i < myFacesByNodes->count(); i++) {
-           QStringList anIds = myFacesByNodes->item(i)->text().split( " ", QString::SkipEmptyParts );
-           SMESH::TPolySimulation::TVTKIds aVTKIds_faces;
-           for (QStringList::iterator it = anIds.begin(); it != anIds.end(); ++it){
-             const SMDS_MeshNode* aNode = aMesh->FindNode( (*it).toInt() );
-             if (!aNode) continue;
-             vtkIdType aId = myActor->GetObject()->GetNodeVTKId( (*it).toInt() );
-             aVTKIds.push_back(aId);
-             aVTKIds_faces.push_back(aId);
-           }
-           if(!Preview->isChecked()){
-             aType = VTK_POLYGON;
-             mySimulation->SetPosition(myActor, aType, aVTKIds_faces,false);
-           }
-         }
-         if(myFacesByNodes->count() == 0){
-           mySimulation->SetVisibility(false);
-         } else {
-           mySimulation->SetVisibility(true);
-         }
-         if(Preview->isChecked()){
-           mySimulation->SetPosition(myActor, aType, aVTKIds);
-         }
-       } else {
-         // add ids from edit line
-         QStringList anEditIds = myEditCurrentArgument->text().split( " ", QString::SkipEmptyParts );
-         for ( int i = 0; i < anEditIds.count(); i++ )
-           aVTKIds.push_back( myActor->GetObject()->GetNodeVTKId( anEditIds[ i ].toInt() ));
-         aType = VTK_POLYGON;
-         mySimulation->SetPosition(myActor, aType, aVTKIds);
-       }
+        if (!AddButton->isEnabled()){
+          mySimulation->ResetGrid(true);
+          for (int i = 0; i < myFacesByNodes->count(); i++) {
+            QStringList anIds = myFacesByNodes->item(i)->text().split( " ", QString::SkipEmptyParts );
+            SMESH::TPolySimulation::TVTKIds aVTKIds_faces;
+            for (QStringList::iterator it = anIds.begin(); it != anIds.end(); ++it){
+              const SMDS_MeshNode* aNode = aMesh->FindNode( (*it).toInt() );
+              if (!aNode) continue;
+              vtkIdType aId = myActor->GetObject()->GetNodeVTKId( (*it).toInt() );
+              aVTKIds.push_back(aId);
+              aVTKIds_faces.push_back(aId);
+            }
+            if(!Preview->isChecked()){
+              aType = VTK_POLYGON;
+              mySimulation->SetPosition(myActor, aType, aVTKIds_faces,false);
+            }
+          }
+          if(myFacesByNodes->count() == 0){
+            mySimulation->SetVisibility(false);
+          } else {
+            mySimulation->SetVisibility(true);
+          }
+          if(Preview->isChecked()){
+            mySimulation->SetPosition(myActor, aType, aVTKIds);
+          }
+        } else {
+          // add ids from edit line
+          QStringList anEditIds = myEditCurrentArgument->text().split( " ", QString::SkipEmptyParts );
+          for ( int i = 0; i < anEditIds.count(); i++ )
+            aVTKIds.push_back( myActor->GetObject()->GetNodeVTKId( anEditIds[ i ].toInt() ));
+          aType = VTK_POLYGON;
+          mySimulation->SetPosition(myActor, aType, aVTKIds);
+        }
       }else if(GetConstructorId() == 1 && aMesh){
-       QStringList aListId = myEditCurrentArgument->text().split( " ", QString::SkipEmptyParts );
-       for ( int i = 0; i < aListId.count(); i++ )
-         {
-           const SMDS_MeshElement * anElem = aMesh->FindElement( aListId[ i ].toInt() );
-           if ( !anElem ) continue;
-           SMDSAbs_ElementType aFaceType = aMesh->GetElementType( anElem->GetID(),true );
-           if (aFaceType != SMDSAbs_Face) continue;
-             
-           SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
-           SMESH::TPolySimulation::TVTKIds aVTKIds_faces;
-           while( anIter->more() )
-             if ( const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next() ){
-               vtkIdType aId = myActor->GetObject()->GetNodeVTKId( aNode->GetID() );
-               aVTKIds.push_back(aId);
-               aVTKIds_faces.push_back(aId);
-             }
-           if(!Preview->isChecked()){
-             aType = VTK_POLYGON;
-             mySimulation->SetPosition(myActor, aType, aVTKIds_faces);
-           }
-         }
-       if(Preview->isChecked())
-         mySimulation->SetPosition(myActor, aType, aVTKIds);
+        QStringList aListId = myEditCurrentArgument->text().split( " ", QString::SkipEmptyParts );
+        for ( int i = 0; i < aListId.count(); i++ )
+          {
+            const SMDS_MeshElement * anElem = aMesh->FindElement( aListId[ i ].toInt() );
+            if ( !anElem ) continue;
+            SMDSAbs_ElementType aFaceType = aMesh->GetElementType( anElem->GetID(),true );
+            if (aFaceType != SMDSAbs_Face) continue;
+              
+            SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
+            SMESH::TPolySimulation::TVTKIds aVTKIds_faces;
+            while( anIter->more() )
+              if ( const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next() ){
+                vtkIdType aId = myActor->GetObject()->GetNodeVTKId( aNode->GetID() );
+                aVTKIds.push_back(aId);
+                aVTKIds_faces.push_back(aId);
+              }
+            if(!Preview->isChecked()){
+              aType = VTK_POLYGON;
+              mySimulation->SetPosition(myActor, aType, aVTKIds_faces);
+            }
+          }
+        if(Preview->isChecked())
+          mySimulation->SetPosition(myActor, aType, aVTKIds);
       }
       SMESH::UpdateView();
     }
@@ -985,8 +1091,8 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::onAdd()
       myNbOkElements = 1;
       myEditCurrentArgument->clear();
       AddButton->setEnabled(false);
-      buttonOk->setEnabled( true );
-      if(myFacesByNodes->count()>1) buttonApply->setEnabled( true );
+      buttonApply->setEnabled( myFacesByNodes->count() > 1 );
+      buttonOk->setEnabled( myFacesByNodes->count() > 1 );
     }
   busy = false;
   onListSelectionChanged();
@@ -1062,3 +1168,16 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::keyPressEvent( QKeyEvent* e )
     ClickOnHelp();
   }
 }
+
+//=================================================================================
+// function : isValid
+// purpose  :
+//=================================================================================
+bool SMESHGUI_CreatePolyhedralVolumeDlg::isValid()
+{
+  if( GroupGroups->isChecked() && ComboBox_GroupName->currentText().isEmpty() ) {
+    SUIT_MessageBox::warning( this, tr( "SMESH_WRN_WARNING" ), tr( "GROUP_NAME_IS_EMPTY" ) );
+    return false;
+  }
+  return true;
+}
index b46d0c35bd48f316994c4a9f2eb4cfd954c6ed1f..44dd3ab5de905b97d3909f6f2e47512901c68aa8 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_CreatePolyhedralVolumeDlg.h
 // Author : Michael ZORIN, Open CASCADE S.A.S.
@@ -37,6 +38,7 @@
 #include CORBA_SERVER_HEADER(SMESH_Mesh)
 
 class QButtonGroup;
+class QComboBox;
 class QGroupBox;
 class QListWidget;
 class QLabel;
@@ -67,6 +69,8 @@ public:
   ~SMESHGUI_CreatePolyhedralVolumeDlg();
 
 private:
+  typedef QList<SMESH::SMESH_GroupBase_var> GrpList;
+
   void                     Init();
   void                     closeEvent( QCloseEvent* );
   void                     enterEvent( QEvent* );          /* mouse enter the QWidget */
@@ -75,6 +79,8 @@ private:
   int                      GetConstructorId();
   void                     displaySimulation();
     
+  bool                     isValid();
+  
   int                      checkEditLine( bool = true ); /*! Checking for indices, return 1 if all ok, esle -1*/
     
   SMESHGUI*                mySMESHGUI;                   /* Current SMESHGUI object */
@@ -88,12 +94,17 @@ private:
   SMESH::SMESH_Mesh_var    myMesh;
   SMESH_Actor*             myActor;
   SMESH::TPolySimulation*  mySimulation;
+  QString                  myEntry;
+  GrpList                  myGroups;
   
   QGroupBox*               ConstructorsBox;
   QButtonGroup*            GroupConstructors;
   QRadioButton*            RadioButton1;
   QRadioButton*            RadioButton2;
   QCheckBox*               Preview;
+  QGroupBox*               GroupGroups;
+  QLabel*                  TextLabel_GroupName;
+  QComboBox*               ComboBox_GroupName;
   QGroupBox*               GroupButtons;
   QPushButton*             buttonOk;
   QPushButton*             buttonCancel;
index 6e2a106a244b79dd743e9cc90c6de371c518d177..ac5a1c686b0bfbba699b15325f67e154384246e5 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : SMESHGUI_DeleteGroupDlg.cxx
 // Author : Sergey LITONIN, Open CASCADE S.A.S.
 // SMESH includes
@@ -189,7 +190,7 @@ bool SMESHGUI_DeleteGroupDlg::isValid()
 {
   if (myListBox->count() == 0) {
     SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
-                                tr("NO_SELECTED_GROUPS"));
+                                 tr("NO_SELECTED_GROUPS"));
     return false;
   }
 
@@ -218,6 +219,7 @@ bool SMESHGUI_DeleteGroupDlg::onApply()
   myListGrp.clear();
   mySelectionMgr->clearSelected();
   SMESH::UpdateView();
+  SMESHGUI::Modified();
   mySMESHGUI->updateObjBrowser(true);
 
   myBlockSelection = false;
@@ -266,10 +268,10 @@ void SMESHGUI_DeleteGroupDlg::onHelp()
     platform = "application";
 #endif
     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser", 
-                                                                platform)).
-                            arg(myHelpFileName));
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser", 
+                                                                 platform)).
+                             arg(myHelpFileName));
   }
 }
 
index c9d6bd029a4af65b1e541706e4310a454b83f745..48e418417f3e83ea296b04a9ff17a393db3d5ddb 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : SMESHGUI_DeleteGroupDlg.h
 // Author : Sergey LITONIN, Open CASCADE S.A.S.
 //
index 7542215217caaf2228eb2da467f12e945b8e4634..958f609ffecba6ab305279fed245d0506c02bb48 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_Dialog.cxx
 // Author : Alexander SOLOVYOV, Open CASCADE S.A.S.
index 7da64f71ee55f1f57991d6121361a8dca0cc6967..374cbe72bd78341ba7ea58623a1a2c0bae1c0ef3 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_Dialog.h
 // Author : Alexander SOLOVYOV, Open CASCADE S.A.S.
@@ -44,8 +45,8 @@ class SMESHGUI_EXPORT SMESHGUI_Dialog : public LightApp_Dialog
   Q_OBJECT
   
 public:
-  SMESHGUI_Dialog( QWidget* = 0, const bool = false, const bool = false, 
-                  const int = OK | Close | Apply | Help );
+  SMESHGUI_Dialog( QWidget* = 0, const bool modal = false, const bool allowResize = false, 
+                   const int = OK | Close | Apply | Help );
   virtual ~SMESHGUI_Dialog();
 
   virtual void      show();
index 613fbb9e4349512b65c611b9c7b4d371140b999a..153c34825e4849db45783e65dea27c1a173bec08 100644 (file)
@@ -1,32 +1,34 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : Displayer for SMESH module
 // File   : SMESHGUI_Displayer.cxx
 // Author : Alexander SOLOVYOV, Open CASCADE S.A.S.
 // SMESH includes
 //
-#include "SMESHGUI_Displayer.h"
 
+#include "SMESHGUI_Displayer.h"
 #include "SMESHGUI_VTKUtils.h"
+#include "SMESHGUI_Utils.h"
 
 // SALOME GUI includes
 #include <SalomeApp_Study.h>
 #include <SVTK_ViewModel.h>
 #include <SVTK_ViewWindow.h>
 
+
+// IDL includes
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+
+
 SMESHGUI_Displayer::SMESHGUI_Displayer( SalomeApp_Application* app )
 : LightApp_Displayer(),
   myApp( app )
@@ -59,16 +68,16 @@ SALOME_Prs* SMESHGUI_Displayer::buildPresentation( const QString& entry, SALOME_
       SUIT_ViewWindow* wnd = vtk_viewer->getViewManager()->getActiveView();
       SMESH_Actor* anActor = SMESH::FindActorByEntry( wnd, entry.toLatin1().data() );
       if( !anActor )
-       anActor = SMESH::CreateActor( study()->studyDS(), entry.toLatin1().data(), true );
+        anActor = SMESH::CreateActor( study()->studyDS(), entry.toLatin1().data(), true );
       if( anActor )
       {
-       SMESH::DisplayActor( wnd, anActor );
+        SMESH::DisplayActor( wnd, anActor );
         prs = LightApp_Displayer::buildPresentation( entry.toLatin1().data(), aViewFrame );
       }
       if( prs )
-       UpdatePrs( prs );
+        UpdatePrs( prs );
       else if( anActor )
-       SMESH::RemoveActor( vtk_viewer->getViewManager()->getActiveView(), anActor );
+        SMESH::RemoveActor( vtk_viewer->getViewManager()->getActiveView(), anActor );
     }
   }
 
@@ -80,7 +89,38 @@ SalomeApp_Study* SMESHGUI_Displayer::study() const
   return dynamic_cast<SalomeApp_Study*>( myApp->activeStudy() );
 }
 
-bool SMESHGUI_Displayer::canBeDisplayed( const QString& /*entry*/, const QString& viewer_type ) const
-{
-  return viewer_type==SVTK_Viewer::Type();
+bool SMESHGUI_Displayer::canBeDisplayed( const QString& entry, const QString& viewer_type ) const {
+  bool res = false;
+  if(viewer_type != SVTK_Viewer::Type())
+    return res;
+  
+  SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( myApp->activeStudy() );
+  if( !study )
+    return res;
+  
+  
+  _PTR(SObject) obj = study->studyDS()->FindObjectID( (const char*)entry.toLatin1() );
+  CORBA::Object_var anObj = SMESH::SObjectToObject( obj );
+  
+    /*
+    if( !CORBA::is_nil( anObj ) ) {
+    SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( anObj );
+    if ( ! mesh->_is_nil() )
+    res = (mesh->NbNodes() > 0);
+    
+    SMESH::SMESH_subMesh_var aSubMeshObj = SMESH::SMESH_subMesh::_narrow( anObj );
+    if ( !aSubMeshObj->_is_nil() )
+    res = (aSubMeshObj->GetNumberOfNodes(true) > 0);
+    
+    SMESH::SMESH_GroupBase_var aGroupObj = SMESH::SMESH_GroupBase::_narrow( anObj );
+    if ( !aGroupObj->_is_nil() )
+    res = !aGroupObj->IsEmpty();
+    }*/
+  if( !CORBA::is_nil( anObj ) ) {
+    if(!SMESH::SMESH_Mesh::_narrow( anObj )->_is_nil() ||
+       !SMESH::SMESH_subMesh::_narrow( anObj )->_is_nil() ||
+       !SMESH::SMESH_GroupBase::_narrow( anObj )->_is_nil())
+    res = true;
+  }
+  return res;
 }
index 61288ee13f672e978939707844e4d70f82c684fc..6a0920b4ac2d232074ed7d03b58eed5088537ab3 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : Displayer for SMESH module
 // File   : SMESHGUI_Displayer.h
 // Author : Alexander SOLOVYOV, Open CASCADE S.A.S.
diff --git a/src/SMESHGUI/SMESHGUI_DuplicateNodesDlg.cxx b/src/SMESHGUI/SMESHGUI_DuplicateNodesDlg.cxx
new file mode 100644 (file)
index 0000000..e49250a
--- /dev/null
@@ -0,0 +1,624 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+// SMESH SMESHGUI : GUI for SMESH component
+// File   : SMESHGUI_DuplicateNodesDlg.cxx
+// Author : Michael ZORIN, Open CASCADE S.A.S.
+
+// SMESH includes
+#include "SMESHGUI_DuplicateNodesDlg.h"
+
+#include "SMESHGUI.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_VTKUtils.h"
+
+#include <SMESH_TypeFilter.hxx>
+
+// SALOME GUI includes
+#include <SUIT_Session.h>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_Desktop.h>
+#include <SUIT_MessageBox.h>
+#include <SUIT_OverrideCursor.h>
+
+#include <LightApp_Application.h>
+#include <LightApp_SelectionMgr.h>
+
+#include <SalomeApp_Tools.h>
+
+#include <SVTK_ViewWindow.h>
+#include <SALOME_ListIO.hxx>
+#include <SALOME_ListIteratorOfListIO.hxx>
+
+// Qt includes
+#include <QApplication>
+#include <QButtonGroup>
+#include <QGroupBox>
+#include <QLabel>
+#include <QLineEdit>
+#include <QPushButton>
+#include <QRadioButton>
+#include <QCheckBox>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QKeyEvent>
+
+#include <utilities.h>
+
+// IDL includes
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
+#define SPACING 6
+#define MARGIN  11
+
+/*!
+  \class BusyLocker
+  \brief Simple 'busy state' flag locker.
+  \internal
+*/
+
+class BusyLocker
+{
+public:
+  //! Constructor. Sets passed boolean flag to \c true.
+  BusyLocker( bool& busy ) : myBusy( busy ) { myBusy = true; }
+  //! Destructor. Clear external boolean flag passed as parameter to the constructor to \c false.
+  ~BusyLocker() { myBusy = false; }
+private:
+  bool& myBusy; //! External 'busy state' boolean flag
+};
+
+/*!
+  \brief Constructor
+  \param theModule Mesh module instance
+*/
+SMESHGUI_DuplicateNodesDlg::SMESHGUI_DuplicateNodesDlg( SMESHGUI* theModule )
+  : QDialog( SMESH::GetDesktop( theModule ) ),
+    mySMESHGUI( theModule ),
+    mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
+{
+  // Dialog attributes
+  setModal(false);
+  setAttribute(Qt::WA_DeleteOnClose, true);
+  setWindowTitle(tr("SMESH_DUPLICATE_TITLE"));
+  setSizeGripEnabled(true);
+
+  // Icons for the dialog operation modes and selection button
+  SUIT_ResourceMgr* aResMgr = SMESH::GetResourceMgr( mySMESHGUI );
+  QPixmap iconWithoutElem (aResMgr->loadPixmap("SMESH", tr("ICON_SMESH_DUPLICATE_NODES")));
+  QPixmap iconWithElem (aResMgr->loadPixmap("SMESH", tr("ICON_SMESH_DUPLICATE_NODES_WITH_ELEM")));
+  QPixmap iconSelect (aResMgr->loadPixmap("SMESH", tr("ICON_SELECT")));
+
+  // Main layout
+  QVBoxLayout* aMainLayout = new QVBoxLayout(this);
+  aMainLayout->setSpacing(SPACING);
+  aMainLayout->setMargin(MARGIN);
+
+  // Operation modes selector
+  QGroupBox* aConstructorsBox = new QGroupBox(tr("DUPLICATION_MODE"), this);
+  myGroupConstructors = new QButtonGroup(this);
+  QHBoxLayout* aConstructorsBoxLayout = new QHBoxLayout(aConstructorsBox);
+  aConstructorsBoxLayout->setSpacing(SPACING);
+  aConstructorsBoxLayout->setMargin(MARGIN);
+
+  QRadioButton* aRadioButton1 = new QRadioButton(aConstructorsBox);
+  aRadioButton1->setIcon(iconWithoutElem);
+  QRadioButton* aRadioButton2 = new QRadioButton(aConstructorsBox);
+  aRadioButton2->setIcon(iconWithElem);
+  
+  aConstructorsBoxLayout->addWidget(aRadioButton1);
+  aConstructorsBoxLayout->addWidget(aRadioButton2);
+  myGroupConstructors->addButton(aRadioButton1, 0);
+  myGroupConstructors->addButton(aRadioButton2, 1);
+
+  // Arguments
+  myGroupArguments = new QGroupBox(this);
+  QGridLayout* aGroupArgumentsLayout = new QGridLayout(myGroupArguments);
+  aGroupArgumentsLayout->setSpacing(SPACING);
+  aGroupArgumentsLayout->setMargin(MARGIN);
+    
+  myTextLabel1 = new QLabel(myGroupArguments);
+  mySelectButton1 = new QPushButton(myGroupArguments);
+  mySelectButton1->setIcon(iconSelect);
+  myLineEdit1 = new QLineEdit(myGroupArguments);
+  myLineEdit1->setReadOnly(true);
+
+  myTextLabel2 = new QLabel(myGroupArguments);
+  mySelectButton2 = new QPushButton(myGroupArguments);
+  mySelectButton2->setIcon(iconSelect);
+  myLineEdit2 = new QLineEdit(myGroupArguments);
+  myLineEdit2->setReadOnly(true);
+
+  myTextLabel3 = new QLabel(myGroupArguments);
+  mySelectButton3 = new QPushButton(myGroupArguments);
+  mySelectButton3->setIcon(iconSelect);
+  myLineEdit3 = new QLineEdit(myGroupArguments);
+  myLineEdit3->setReadOnly(true);
+
+  myCheckBoxNewElemGroup = new QCheckBox(tr("CONSTRUCT_NEW_GROUP_ELEMENTS"), myGroupArguments);
+  myCheckBoxNewNodeGroup = new QCheckBox(tr("CONSTRUCT_NEW_GROUP_NODES"), myGroupArguments);
+
+  aGroupArgumentsLayout->addWidget(myTextLabel1,    0, 0);
+  aGroupArgumentsLayout->addWidget(mySelectButton1, 0, 1);
+  aGroupArgumentsLayout->addWidget(myLineEdit1,     0, 2);
+  aGroupArgumentsLayout->addWidget(myTextLabel2,    1, 0);
+  aGroupArgumentsLayout->addWidget(mySelectButton2, 1, 1);
+  aGroupArgumentsLayout->addWidget(myLineEdit2,     1, 2);
+  aGroupArgumentsLayout->addWidget(myTextLabel3,    2, 0);
+  aGroupArgumentsLayout->addWidget(mySelectButton3, 2, 1);
+  aGroupArgumentsLayout->addWidget(myLineEdit3,     2, 2);
+  aGroupArgumentsLayout->addWidget(myCheckBoxNewElemGroup, 3, 0);
+  aGroupArgumentsLayout->addWidget(myCheckBoxNewNodeGroup, 4, 0);
+  aGroupArgumentsLayout->setRowStretch(5, 1);
+  
+  // Buttons
+  QGroupBox* aGroupButtons = new QGroupBox(this);
+  QHBoxLayout* aGroupButtonsLayout = new QHBoxLayout(aGroupButtons);
+  aGroupButtonsLayout->setSpacing(SPACING);
+  aGroupButtonsLayout->setMargin(MARGIN);
+
+  myButtonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), aGroupButtons);
+  myButtonOk->setAutoDefault(true);
+  myButtonOk->setDefault(true);
+  myButtonApply = new QPushButton(tr("SMESH_BUT_APPLY"), aGroupButtons);
+  myButtonApply->setAutoDefault(true);
+  myButtonClose = new QPushButton(tr("SMESH_BUT_CLOSE"), aGroupButtons);
+  myButtonClose->setAutoDefault(true);
+  myButtonHelp = new QPushButton(tr("SMESH_BUT_HELP"), aGroupButtons);
+  myButtonHelp->setAutoDefault(true);
+
+  aGroupButtonsLayout->addWidget(myButtonOk);
+  aGroupButtonsLayout->addSpacing(10);
+  aGroupButtonsLayout->addWidget(myButtonApply);
+  aGroupButtonsLayout->addSpacing(10);
+  aGroupButtonsLayout->addStretch();
+  aGroupButtonsLayout->addWidget(myButtonClose);
+  aGroupButtonsLayout->addWidget(myButtonHelp);
+
+  // Add mode selector, arguments and buttons to the main layout
+  aMainLayout->addWidget(aConstructorsBox);
+  aMainLayout->addWidget(myGroupArguments);
+  aMainLayout->addWidget(aGroupButtons);
+  
+  // Initialize the dialog
+  Init();
+
+  // Help file name
+  myHelpFileName = "double_nodes_page.html";
+
+  // Signals and slots connections
+  connect(myGroupConstructors, SIGNAL(buttonClicked(int)), SLOT(onConstructorsClicked(int)));
+     
+  connect(mySelectButton1, SIGNAL (clicked()), this, SLOT(onEditCurrentArgument()));
+  connect(mySelectButton2, SIGNAL (clicked()), this, SLOT(onEditCurrentArgument()));
+  connect(mySelectButton3, SIGNAL (clicked()), this, SLOT(onEditCurrentArgument()));
+
+  connect(myButtonOk,     SIGNAL(clicked()), this, SLOT(onOk()));
+  connect(myButtonClose,  SIGNAL(clicked()), this, SLOT(onClose()));
+  connect(myButtonApply,  SIGNAL(clicked()), this, SLOT(onApply()));
+  connect(myButtonHelp,   SIGNAL(clicked()), this, SLOT(onHelp()));
+  
+  connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionChanged()));
+
+  connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), this, SLOT(onDeactivate()));
+  connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(onClose()));
+}
+
+/*!
+  \brief Destructor
+*/
+SMESHGUI_DuplicateNodesDlg::~SMESHGUI_DuplicateNodesDlg()
+{
+}
+
+/*!
+  \brief Destructor
+*/
+void SMESHGUI_DuplicateNodesDlg::Init()
+{
+  mySMESHGUI->SetActiveDialogBox((QDialog*)this);
+  myCheckBoxNewElemGroup->setChecked(true);
+  myCheckBoxNewNodeGroup->setChecked(true);
+
+  // Set initial parameters
+  myBusy = false;
+  myCurrentLineEdit = myLineEdit1;
+
+  myGroups1.clear();
+  myGroups2.clear();
+  myGroups3.clear();
+  
+  // Set selection mode
+  mySelectionMgr->installFilter(new SMESH_TypeFilter(GROUP));
+  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+    aViewWindow->SetSelectionMode(ActorSelection);
+  
+  // Set construction mode
+  int operationMode = myGroupConstructors->checkedId();
+  if (operationMode < 0) {
+    // The dialog has been just displayed
+    operationMode = 0;
+    myGroupConstructors->button(0)->setChecked(true);
+  }
+  onConstructorsClicked(operationMode);
+}
+
+/*!
+  \brief SLOT called to change the dialog operation mode.
+  \param constructorId id of the radio button in mode selector button group
+*/
+void SMESHGUI_DuplicateNodesDlg::onConstructorsClicked (int constructorId)
+{
+  // Clear all fields
+  myLineEdit1->clear();
+  myLineEdit2->clear();
+  myLineEdit3->clear();
+
+  myGroups1.clear();
+  myGroups2.clear();
+  myGroups3.clear();
+
+  // Set the first field as current
+  myCurrentLineEdit = myLineEdit1;
+  myCurrentLineEdit->setFocus();
+
+  switch (constructorId) {
+  case 0:
+    {
+      // Set text to the group of arguments and to the first two labels
+      myGroupArguments->setTitle(tr("DUPLICATION_WITHOUT_ELEMS"));
+      myTextLabel1->setText(tr("GROUP_NODES_TO_DUPLICATE"));
+      myTextLabel2->setText(tr("GROUP_NODES_TO_REPLACE"));
+
+      myCheckBoxNewElemGroup->hide();
+      myCheckBoxNewNodeGroup->show();
+      
+      // Hide the third field
+      myTextLabel3->hide();
+      mySelectButton3->hide();
+      myLineEdit3->hide();
+      
+      break;
+    }
+  case 1:
+    {
+      // Set text to the group of arguments and to all the labels
+      myGroupArguments->setTitle(tr("DUPLICATION_WITH_ELEMS"));
+      myTextLabel1->setText(tr("GROUP_ELEMS_TO_DUPLICATE"));
+      myTextLabel2->setText(tr("GROUP_NODES_NOT_DUPLICATE"));
+      myTextLabel3->setText(tr("GROUP_ELEMS_TO_REPLACE"));
+      
+      myCheckBoxNewElemGroup->show();
+      myCheckBoxNewNodeGroup->show();
+
+      // Show the third field
+      myTextLabel3->show();
+      mySelectButton3->show();
+      myLineEdit3->show();
+
+      break;
+    }
+  }
+  
+  // Process selection
+  onSelectionChanged();
+}
+
+/*!
+  \brief SLOT called to apply changes.
+*/
+bool SMESHGUI_DuplicateNodesDlg::onApply()
+{
+  if ( mySMESHGUI->isActiveStudyLocked() || !isValid() )
+    return false;
+
+  BusyLocker lock( myBusy );
+  bool toCreateElemGroup = myCheckBoxNewElemGroup->isChecked();
+  bool toCreateNodeGroup = myCheckBoxNewNodeGroup->isChecked();
+  int operationMode = myGroupConstructors->checkedId();
+  
+  // Apply changes
+  bool result = false;
+  SUIT_OverrideCursor aWaitCursor;
+
+  try {
+    SMESH::SMESH_Mesh_var aMesh = myGroups1[0]->GetMesh();
+    SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
+
+    if ( operationMode == 0 ) {
+      SMESH::ListOfGroups_var g1 = new SMESH::ListOfGroups();
+      g1->length( myGroups1.count() );
+      for ( int i = 0; i < myGroups1.count(); i++ )
+        g1[i] = myGroups1[i];
+      SMESH::ListOfGroups_var g2 = new SMESH::ListOfGroups();
+      g2->length( myGroups2.count() );
+      for ( int i = 0; i < myGroups2.count(); i++ )
+        g2[i] = myGroups2[i];
+
+      if ( toCreateNodeGroup ) {
+        SMESH::SMESH_GroupBase_var aNewGroup = 
+          aMeshEditor->DoubleNodeGroupsNew( g1.in(), g2.in() );
+        result = !CORBA::is_nil( aNewGroup );
+      }
+      else {
+        result = aMeshEditor->DoubleNodeGroups( g1.in(), g2.in() );
+      }
+    }
+    else {
+      SMESH::ListOfGroups_var g1 = new SMESH::ListOfGroups();
+      g1->length( myGroups1.count() );
+      for ( int i = 0; i < myGroups1.count(); i++ )
+        g1[i] = myGroups1[i];
+      SMESH::ListOfGroups_var g2 = new SMESH::ListOfGroups();
+      g2->length( myGroups2.count() );
+      for ( int i = 0; i < myGroups2.count(); i++ )
+        g2[i] = myGroups2[i];
+      SMESH::ListOfGroups_var g3 = new SMESH::ListOfGroups();
+      g3->length( myGroups3.count() );
+
+      for ( int i = 0; i < myGroups3.count(); i++ )
+        g3[i] = myGroups3[i];
+      if ( toCreateElemGroup || toCreateNodeGroup ) {
+        SMESH::ListOfGroups_var aNewGroups = 
+          aMeshEditor->DoubleNodeElemGroups2New( g1.in(), g2.in(), g3.in(),
+                                                 toCreateElemGroup, toCreateNodeGroup );
+        result = ( aNewGroups[ !toCreateElemGroup ].in() );
+      }
+      else {
+        result = aMeshEditor->DoubleNodeElemGroups( g1.in(), g2.in(), g3.in() );
+      }
+    }
+  }
+  catch (const SALOME::SALOME_Exception& S_ex) {
+    SalomeApp_Tools::QtCatchCorbaException(S_ex);
+  }
+  catch ( const std::exception& exc ) {
+    INFOS( "Follow exception was cought:\n\t" << exc.what() );
+  } 
+  catch (...){
+    INFOS( "Unknown exception was cought !!!" );
+  }
+
+  if (!result) {
+    SUIT_MessageBox::warning(this,
+                             tr("SMESH_WRN_WARNING"),
+                             tr("SMESH_OPERATION_FAILED"));
+    return false;
+  }
+
+  // Update GUI
+  mySelectionMgr->clearSelected();
+  SMESH::UpdateView();
+  SMESHGUI::Modified();
+  mySMESHGUI->updateObjBrowser(true);
+
+  // Reinitialize the dialog
+  Init();
+  
+  return true;
+}
+
+/*!
+  \brief SLOT called to apply changes and close the dialog.
+*/
+void SMESHGUI_DuplicateNodesDlg::onOk()
+{
+  if (onApply())
+    onClose();
+}
+
+/*!
+  \brief SLOT called to close the dialog.
+*/
+void SMESHGUI_DuplicateNodesDlg::onClose()
+{
+  disconnect(mySelectionMgr, 0, this, 0);
+  disconnect(mySMESHGUI, 0, this, 0);
+  mySMESHGUI->ResetState();
+  mySelectionMgr->clearFilters();
+  reject();
+}
+
+/*!
+  \brief  SLOT called when selection changed.
+*/
+void SMESHGUI_DuplicateNodesDlg::onSelectionChanged()
+{
+  if ( myBusy || !isEnabled() ) return;
+  
+  int operationMode = myGroupConstructors->checkedId();
+
+  SALOME_ListIO aList;
+  mySelectionMgr->selectedObjects( aList );
+  //int aNbSel = aList.Extent();
+
+  QList<SMESH::SMESH_GroupBase_var> aGroups;
+
+  SALOME_ListIteratorOfListIO anIter ( aList );
+  bool ok = true;
+  for ( ; anIter.More() && ok; anIter.Next()) {
+    SMESH::SMESH_GroupBase_var aGroup = SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>( anIter.Value() );
+    // check group is selected
+    ok = !CORBA::is_nil( aGroup );
+    // check groups of the same mesh are selected
+    if ( ok ) {
+      SMESH::SMESH_Mesh_var aMesh1;
+      if ( !aGroups.isEmpty() ) aMesh1 = aGroups[0]->GetMesh();
+      SMESH::SMESH_Mesh_var aMesh2 = aGroup->GetMesh();
+      ok = CORBA::is_nil( aMesh1 ) || aMesh1->_is_equivalent( aMesh2 );
+    }
+    // check group of proper type is selected
+    if ( ok ) {
+      SMESH::ElementType aGroupType = aGroup->GetType();
+      if ( operationMode == 0 ) {
+        ok = ( myCurrentLineEdit == myLineEdit1 && aGroupType == SMESH::NODE ) ||
+             ( myCurrentLineEdit == myLineEdit2 && aGroupType != SMESH::NODE );
+      }
+      else {
+        ok = ( myCurrentLineEdit == myLineEdit1 && ( aGroupType == SMESH::EDGE ||
+                                                     aGroupType == SMESH::FACE ) ) ||
+             ( myCurrentLineEdit == myLineEdit2 && aGroupType == SMESH::NODE )     ||
+             ( myCurrentLineEdit == myLineEdit3 && aGroupType != SMESH::NODE );
+      }
+    }
+    if ( ok ) aGroups << aGroup;
+  }
+
+  // Clear current field
+  myCurrentLineEdit->clear();
+
+  if ( ok && !aGroups.isEmpty() ) {
+    if      ( myCurrentLineEdit == myLineEdit1 ) myGroups1 = aGroups;
+    else if ( myCurrentLineEdit == myLineEdit2 ) myGroups2 = aGroups;
+    else if ( myCurrentLineEdit == myLineEdit3 ) myGroups3 = aGroups;
+    CORBA::String_var name = aGroups[0]->GetName();
+    myCurrentLineEdit->setText( aGroups.count() == 1 ? QString(name).trimmed() : 
+                                QObject::tr( "SMESH_OBJECTS_SELECTED" ).arg( aGroups.count() ) );
+  }
+  else {
+    if      ( myCurrentLineEdit == myLineEdit1 ) myGroups1.clear();
+    else if ( myCurrentLineEdit == myLineEdit2 ) myGroups2.clear();
+    else if ( myCurrentLineEdit == myLineEdit3 ) myGroups3.clear();
+    myCurrentLineEdit->clear();
+  }
+
+  // Enable/disable "Apply and Close" and "Apply" buttons
+  bool isDataValid = isValid();
+  myButtonOk->setEnabled( isDataValid );
+  myButtonApply->setEnabled( isDataValid );
+}
+
+/*!
+  \brief  SLOT called when selection button clicked.
+*/
+void SMESHGUI_DuplicateNodesDlg::onEditCurrentArgument()
+{
+  QPushButton* send = (QPushButton*)sender();
+  
+  // Set current field for edition
+  if (send == mySelectButton1) {
+    myCurrentLineEdit = myLineEdit1;
+  } 
+  else if (send == mySelectButton2) {
+    myCurrentLineEdit = myLineEdit2;
+  }
+  else if (send == mySelectButton3) {
+    myCurrentLineEdit = myLineEdit3;
+  }
+  
+  myCurrentLineEdit->setFocus();
+  onSelectionChanged();
+}
+
+/*!
+  \brief Check if the input data is valid.
+  \return \c true id the data is valid
+*/
+bool SMESHGUI_DuplicateNodesDlg::isValid()
+{
+  return myGroupConstructors->checkedId() == 1 ?
+    ( !myGroups1.isEmpty() && !myGroups3.isEmpty()  ) :
+    ( !myGroups1.isEmpty() );
+}
+
+
+/*!
+  \brief SLOT called when dialog shoud be deativated.
+*/
+void SMESHGUI_DuplicateNodesDlg::onDeactivate()
+{
+  if (isEnabled()) {
+    mySelectionMgr->clearFilters();
+    setEnabled(false);
+    mySMESHGUI->ResetState();
+    mySMESHGUI->SetActiveDialogBox(0);
+  }
+}
+
+/*!
+  \brief Receive dialog enter events.
+  Activates the dialog when the mouse cursor enters.
+  Reimplemented from QWidget class.
+*/
+void SMESHGUI_DuplicateNodesDlg::enterEvent (QEvent*)
+{
+  if ( !isEnabled() ) {
+    mySMESHGUI->EmitSignalDeactivateDialog();
+    setEnabled(true);
+    mySMESHGUI->SetActiveDialogBox((QDialog*)this);
+    
+    // Set selection mode
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->SetSelectionMode(ActorSelection);
+    mySelectionMgr->installFilter(new SMESH_TypeFilter (GROUP));
+  }
+}
+
+/*!
+  \brief Receive close events.
+  Reimplemented from QWidget class.
+*/
+void SMESHGUI_DuplicateNodesDlg::closeEvent (QCloseEvent*)
+{
+  onClose();
+}
+
+/*!
+  \brief Receive key press events.
+  Reimplemented from QWidget class.
+*/
+void SMESHGUI_DuplicateNodesDlg::keyPressEvent( QKeyEvent* e )
+{
+  QDialog::keyPressEvent( e );
+  if ( e->isAccepted() )
+    return;
+
+  if ( e->key() == Qt::Key_F1 ) {
+    e->accept();
+    onHelp();
+  }
+}
+
+/*!
+  \brief Show the dialog help page.
+*/
+void SMESHGUI_DuplicateNodesDlg::onHelp()
+{
+  LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
+  if (app) 
+    app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
+  else {
+    QString platform;
+#ifdef WIN32
+    platform = "winapplication";
+#else
+    platform = "application";
+#endif
+    SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser", 
+                                                                 platform)).
+                             arg(myHelpFileName));
+  }
+}
diff --git a/src/SMESHGUI/SMESHGUI_DuplicateNodesDlg.h b/src/SMESHGUI/SMESHGUI_DuplicateNodesDlg.h
new file mode 100644 (file)
index 0000000..2714ba0
--- /dev/null
@@ -0,0 +1,120 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+// SMESH SMESHGUI : GUI for SMESH component
+// File   : SMESHGUI_DuplicateNodesDlg.h
+// Author : Michael ZORIN, Open CASCADE S.A.S.
+//
+#ifndef SMESHGUI_DUPLICATENODESDLG_H
+#define SMESHGUI_DUPLICATENODESDLG_H
+
+// SMESH includes
+#include "SMESH_SMESHGUI.hxx"
+
+// Qt includes
+#include <QDialog>
+
+// IDL includes
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Group)
+
+class QButtonGroup;
+class QGroupBox;
+class QLabel;
+class QLineEdit;
+class QPushButton;
+class QCheckBox;
+
+class LightApp_SelectionMgr;
+
+class SMESHGUI;
+
+/*!
+  \class SMESHGUI_DuplicateNodesDlg
+  \brief Dialog for duplication of nodes.
+*/
+class SMESHGUI_EXPORT SMESHGUI_DuplicateNodesDlg : public QDialog
+{ 
+  Q_OBJECT
+
+public:
+  SMESHGUI_DuplicateNodesDlg( SMESHGUI* );
+  ~SMESHGUI_DuplicateNodesDlg();
+
+private:
+  void                    Init();
+
+  bool                    isValid();
+  
+  void                    closeEvent( QCloseEvent* );
+  void                    enterEvent( QEvent* );
+  void                    keyPressEvent( QKeyEvent* );
+  
+private slots:
+  void                    onConstructorsClicked( int );
+  void                    onOk();
+  void                    onClose();
+  bool                    onApply();
+  void                    onHelp();
+
+  void                    onEditCurrentArgument();
+  void                    onSelectionChanged();
+
+  void                    onDeactivate();
+
+private:
+  QLineEdit*              myCurrentLineEdit;
+  
+  QButtonGroup*           myGroupConstructors;
+  
+  QGroupBox*              myGroupArguments;
+  QLabel*                 myTextLabel1;
+  QLabel*                 myTextLabel2;
+  QLabel*                 myTextLabel3;
+  QPushButton*            mySelectButton1;
+  QPushButton*            mySelectButton2;
+  QPushButton*            mySelectButton3;
+  QLineEdit*              myLineEdit1;
+  QLineEdit*              myLineEdit2;
+  QLineEdit*              myLineEdit3;
+  QCheckBox*              myCheckBoxNewElemGroup;
+  QCheckBox*              myCheckBoxNewNodeGroup;
+
+  QPushButton*            myButtonOk;
+  QPushButton*            myButtonApply;
+  QPushButton*            myButtonClose;
+  QPushButton*            myButtonHelp;
+
+  SMESHGUI*               mySMESHGUI;
+  LightApp_SelectionMgr*  mySelectionMgr;
+
+  QList<SMESH::SMESH_GroupBase_var> myGroups1;
+  QList<SMESH::SMESH_GroupBase_var> myGroups2;
+  QList<SMESH::SMESH_GroupBase_var> myGroups3;
+
+  bool                    myBusy;
+  
+  QString                 myHelpFileName;
+};
+
+#endif // SMESHGUI_DUPLICATENODESDLG_H
diff --git a/src/SMESHGUI/SMESHGUI_EditMeshDlg.cxx b/src/SMESHGUI/SMESHGUI_EditMeshDlg.cxx
deleted file mode 100644 (file)
index c8aa371..0000000
+++ /dev/null
@@ -1,1138 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-// SMESH SMESHGUI : GUI for SMESH component
-// File   : SMESHGUI_EditMeshDlg.cxx
-// Author : Open CASCADE S.A.S.
-// SMESH includes
-//
-#include "SMESHGUI_EditMeshDlg.h"
-
-#include "SMESHGUI.h"
-#include "SMESHGUI_Utils.h"
-#include "SMESHGUI_VTKUtils.h"
-#include "SMESHGUI_MeshUtils.h"
-#include "SMESHGUI_SpinBox.h"
-
-#include <SMESH_Actor.h>
-#include <SMESH_TypeFilter.hxx>
-#include <SMESH_LogicalFilter.hxx>
-#include <SMDS_Mesh.hxx>
-
-// SALOME GUI includes
-#include <SUIT_Desktop.h>
-#include <SUIT_ResourceMgr.h>
-#include <SUIT_Session.h>
-#include <SUIT_MessageBox.h>
-#include <SUIT_OverrideCursor.h>
-
-#include <LightApp_Application.h>
-#include <LightApp_SelectionMgr.h>
-
-#include <SVTK_ViewModel.h>
-#include <SVTK_ViewWindow.h>
-#include <SALOME_ListIO.hxx>
-
-// OCCT includes
-#include <TColStd_MapOfInteger.hxx>
-#include <TColStd_MapIteratorOfMapOfInteger.hxx>
-
-// IDL includes
-#include <SALOMEconfig.h>
-#include CORBA_SERVER_HEADER(SMESH_Group)
-#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
-
-// VTK includes
-#include <vtkUnstructuredGrid.h>
-#include <vtkRenderer.h>
-#include <vtkActor2D.h>
-#include <vtkPoints.h>
-#include <vtkDataSetMapper.h>
-#include <vtkMaskPoints.h>
-#include <vtkSelectVisiblePoints.h>
-#include <vtkLabeledDataMapper.h>
-#include <vtkTextProperty.h>
-#include <vtkIntArray.h>
-#include <vtkProperty2D.h>
-#include <vtkPointData.h>
-
-// Qt includes
-#include <QApplication>
-#include <QGroupBox>
-#include <QLabel>
-#include <QLineEdit>
-#include <QListWidget>
-#include <QPushButton>
-#include <QRadioButton>
-#include <QCheckBox>
-#include <QHBoxLayout>
-#include <QVBoxLayout>
-#include <QGridLayout>
-#include <QKeyEvent>
-#include <QButtonGroup>
-
-#define SPACING 6
-#define MARGIN  11
-
-namespace SMESH
-{
-  class TIdPreview
-  { // to display in the viewer IDs of the selected elements
-    SVTK_ViewWindow* myViewWindow;
-
-    vtkUnstructuredGrid* myIdGrid;
-    SALOME_Actor* myIdActor;
-
-    vtkUnstructuredGrid* myPointsNumDataSet;
-    vtkMaskPoints* myPtsMaskPoints;
-    vtkSelectVisiblePoints* myPtsSelectVisiblePoints;
-    vtkLabeledDataMapper* myPtsLabeledDataMapper;
-    vtkTextProperty* aPtsTextProp;
-    bool myIsPointsLabeled;
-    vtkActor2D* myPointLabels;
-
-    std::vector<int> myIDs;
-
-  public:
-    TIdPreview(SVTK_ViewWindow* theViewWindow):
-      myViewWindow(theViewWindow)
-    {
-      myIdGrid = vtkUnstructuredGrid::New();
-
-      // Create and display actor
-      vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
-      aMapper->SetInput( myIdGrid );
-
-      myIdActor = SALOME_Actor::New();
-      myIdActor->SetInfinitive(true);
-      myIdActor->VisibilityOff();
-      myIdActor->PickableOff();
-
-      myIdActor->SetMapper( aMapper );
-      aMapper->Delete();
-
-      myViewWindow->AddActor(myIdActor);
-
-      //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 = 12;
-      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);
-
-      AddToRender(myViewWindow->getRenderer());
-    }
-
-    void SetPointsData ( SMDS_Mesh* theMesh, 
-                        TColStd_MapOfInteger & theNodesIdMap )
-    {
-      vtkPoints* aPoints = vtkPoints::New();
-      aPoints->SetNumberOfPoints(theNodesIdMap.Extent());
-      myIDs.clear();
-      
-      TColStd_MapIteratorOfMapOfInteger idIter( theNodesIdMap );
-      for( int i = 0; idIter.More(); idIter.Next(), i++ ) {
-       const SMDS_MeshNode* aNode = theMesh->FindNode(idIter.Key());
-       aPoints->SetPoint( i, aNode->X(), aNode->Y(), aNode->Z() );
-       myIDs.push_back(idIter.Key());
-      }
-
-      myIdGrid->SetPoints(aPoints);
-
-      aPoints->Delete();
-
-      myIdActor->GetMapper()->Update();
-    }
-
-    void SetElemsData( TColStd_MapOfInteger & theElemsIdMap, 
-                      std::list<gp_XYZ> & aGrCentersXYZ )
-    {
-      vtkPoints* aPoints = vtkPoints::New();
-      aPoints->SetNumberOfPoints(theElemsIdMap.Extent());
-      myIDs.clear();
-      
-      TColStd_MapIteratorOfMapOfInteger idIter( theElemsIdMap );
-      for( ; idIter.More(); idIter.Next() ) {
-       myIDs.push_back(idIter.Key());
-      }
-
-      gp_XYZ aXYZ;
-      std::list<gp_XYZ>::iterator coordIt = aGrCentersXYZ.begin();
-      for( int i = 0; coordIt != aGrCentersXYZ.end(); coordIt++, i++ ) {
-       aXYZ = *coordIt;
-       aPoints->SetPoint( i, aXYZ.X(), aXYZ.Y(), aXYZ.Z() );
-      }
-      myIdGrid->SetPoints(aPoints);
-      aPoints->Delete();
-      
-      myIdActor->GetMapper()->Update();
-    }
-
-    void AddToRender(vtkRenderer* theRenderer)
-    {
-      myIdActor->AddToRender(theRenderer);
-
-      myPtsSelectVisiblePoints->SetRenderer(theRenderer);
-      theRenderer->AddActor2D(myPointLabels);
-    }
-
-    void RemoveFromRender(vtkRenderer* theRenderer)
-    {
-      myIdActor->RemoveFromRender(theRenderer);
-
-      myPtsSelectVisiblePoints->SetRenderer(theRenderer);
-      theRenderer->RemoveActor(myPointLabels);
-    }
-
-    void SetPointsLabeled( bool theIsPointsLabeled, bool theIsActorVisible = true )
-    {
-      myIsPointsLabeled = theIsPointsLabeled && myIdGrid->GetNumberOfPoints();
-      
-      if ( myIsPointsLabeled ) {
-       myPointsNumDataSet->ShallowCopy(myIdGrid);
-       vtkDataSet *aDataSet = myPointsNumDataSet;
-       int aNbElem = myIDs.size();
-       vtkIntArray *anArray = vtkIntArray::New();
-       anArray->SetNumberOfValues( aNbElem );
-       for ( int i = 0; i < aNbElem; i++ )
-         anArray->SetValue( i, myIDs[i] );
-       aDataSet->GetPointData()->SetScalars( anArray );
-       anArray->Delete();
-       myPtsMaskPoints->SetInput( aDataSet );
-       myPointLabels->SetVisibility( theIsActorVisible );
-      }
-      else {
-       myPointLabels->SetVisibility( false );
-      }
-    }
-    
-    ~TIdPreview()
-    {
-      RemoveFromRender(myViewWindow->getRenderer());
-
-      myIdGrid->Delete();
-
-      myViewWindow->RemoveActor(myIdActor);
-      myIdActor->Delete();
-
-      //Deleting of points numbering pipeline
-      //---------------------------------------
-      myPointsNumDataSet->Delete();
-      
-      //myPtsLabeledDataMapper->RemoveAllInputs();        //vtk 5.0 porting
-      myPtsLabeledDataMapper->Delete();
-
-      //myPtsSelectVisiblePoints->UnRegisterAllOutputs(); //vtk 5.0 porting
-      myPtsSelectVisiblePoints->Delete();
-
-      //myPtsMaskPoints->UnRegisterAllOutputs();         //vtk 5.0 porting
-      myPtsMaskPoints->Delete();
-
-      myPointLabels->Delete();
-
-//       myTimeStamp->Delete();
-    }
-  };
-}
-
-static const char * IconFirst[] = {
-"18 10 2 1",
-"      g None",
-".     g #000000",
-"         .     .  ",
-"  ..    ..    ..  ",
-"  ..   ...   ...  ",
-"  ..  ....  ....  ",
-"  .. ..... .....  ",
-"  .. ..... .....  ",
-"  ..  ....  ....  ",
-"  ..   ...   ...  ",
-"  ..    ..    ..  ",
-"         .     .  "};
-
-//=================================================================================
-// class    : SMESHGUI_EditMeshDlg()
-// purpose  :
-//=================================================================================
-SMESHGUI_EditMeshDlg::SMESHGUI_EditMeshDlg (SMESHGUI* theModule, 
-                                           int theAction)
-  : QDialog(SMESH::GetDesktop(theModule)),
-    mySMESHGUI(theModule),
-    mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
-    myAction(theAction)
-{
-  setModal(false);
-  setAttribute(Qt::WA_DeleteOnClose, true);
-  setWindowTitle(myAction == 1 ? tr("SMESH_MERGE_ELEMENTS") : tr("SMESH_MERGE_NODES"));
-
-  myIdPreview = new SMESH::TIdPreview(SMESH::GetViewWindow( mySMESHGUI ));
-
-  SUIT_ResourceMgr* aResMgr = SMESH::GetResourceMgr( mySMESHGUI );
-  QPixmap IconMergeNodes (aResMgr->loadPixmap("SMESH", tr("ICON_SMESH_MERGE_NODES")));
-  QPixmap IconMergeElems (aResMgr->loadPixmap("SMESH", tr("ICON_DLG_MERGE_ELEMENTS")));
-  QPixmap IconSelect     (aResMgr->loadPixmap("SMESH", tr("ICON_SELECT")));
-  QPixmap IconAdd        (aResMgr->loadPixmap("SMESH", tr("ICON_APPEND")));
-  QPixmap IconRemove     (aResMgr->loadPixmap("SMESH", tr("ICON_REMOVE")));
-
-  setSizeGripEnabled(true);
-
-  QVBoxLayout* DlgLayout = new QVBoxLayout(this);
-  DlgLayout->setSpacing(SPACING);
-  DlgLayout->setMargin(MARGIN);
-
-  /***************************************************************/
-  GroupConstructors = new QGroupBox(myAction == 1 ? 
-                                   tr("SMESH_MERGE_ELEMENTS") : 
-                                   tr("SMESH_MERGE_NODES"), 
-                                   this);
-
-  QButtonGroup* ButtonGroup = new QButtonGroup(this);
-  QHBoxLayout* GroupConstructorsLayout = new QHBoxLayout(GroupConstructors);
-  GroupConstructorsLayout->setSpacing(SPACING);
-  GroupConstructorsLayout->setMargin(MARGIN);
-
-  RadioButton = new QRadioButton(GroupConstructors);
-  RadioButton->setIcon(myAction == 1 ? IconMergeElems : IconMergeNodes);
-  RadioButton->setChecked(true);
-  GroupConstructorsLayout->addWidget(RadioButton);
-  ButtonGroup->addButton(RadioButton, 0);
-
-  /***************************************************************/
-  // Controls for mesh defining
-  GroupMesh = new QGroupBox(tr("SMESH_SELECT_WHOLE_MESH"), this);
-  QHBoxLayout* GroupMeshLayout = new QHBoxLayout(GroupMesh);
-  GroupMeshLayout->setSpacing(SPACING);
-  GroupMeshLayout->setMargin(MARGIN);
-
-  TextLabelName = new QLabel(tr("SMESH_NAME"), GroupMesh);
-  SelectMeshButton = new QPushButton(GroupMesh);
-  SelectMeshButton->setIcon(IconSelect);
-  LineEditMesh = new QLineEdit(GroupMesh);
-  LineEditMesh->setReadOnly(true);
-
-  GroupMeshLayout->addWidget(TextLabelName);
-  GroupMeshLayout->addWidget(SelectMeshButton);
-  GroupMeshLayout->addWidget(LineEditMesh);
-
-  /***************************************************************/
-  // Controls for coincident elements detecting
-  GroupCoincident = new QGroupBox(myAction == 1 ? 
-                                 tr("COINCIDENT_ELEMENTS") : 
-                                 tr("COINCIDENT_NODES"), 
-                                 this);
-
-  QGridLayout* GroupCoincidentLayout = new QGridLayout(GroupCoincident);
-  GroupCoincidentLayout->setSpacing(SPACING);
-  GroupCoincidentLayout->setMargin(MARGIN);
-  
-  if (myAction == 0) { // case merge nodes
-    TextLabelTolerance = new QLabel(tr("SMESH_TOLERANCE"), GroupCoincident);
-    SpinBoxTolerance = new SMESHGUI_SpinBox(GroupCoincident);
-    SpinBoxTolerance->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
-
-    GroupCoincidentLayout->addWidget(TextLabelTolerance, 0, 0);
-    GroupCoincidentLayout->addWidget(SpinBoxTolerance,   0, 1);
-  }
-  else {
-    TextLabelTolerance = 0;
-    SpinBoxTolerance = 0;
-  }
-
-  int row = GroupCoincidentLayout->rowCount();
-
-  ListCoincident = new QListWidget(GroupCoincident);
-  ListCoincident->setSelectionMode(QListWidget::ExtendedSelection);
-
-  DetectButton      = new QPushButton(tr("DETECT"),           GroupCoincident);
-  AddGroupButton    = new QPushButton(tr("SMESH_BUT_ADD"),    GroupCoincident);
-  RemoveGroupButton = new QPushButton(tr("SMESH_BUT_REMOVE"), GroupCoincident);
-
-  SelectAllCB = new QCheckBox(tr("SELECT_ALL"), GroupCoincident);
-
-  GroupCoincidentLayout->addWidget(ListCoincident,    row,   0, 4, 2);
-  GroupCoincidentLayout->addWidget(DetectButton,      row,   2);
-  GroupCoincidentLayout->addWidget(AddGroupButton,    row+2, 2);
-  GroupCoincidentLayout->addWidget(RemoveGroupButton, row+3, 2);
-  GroupCoincidentLayout->addWidget(SelectAllCB,       row+4, 0, 1, 3);
-  GroupCoincidentLayout->setRowMinimumHeight(row+1, 10);
-  GroupCoincidentLayout->setRowStretch(row+1, 5);
-
-  /***************************************************************/
-  // Controls for editing the selected group
-  GroupEdit = new QGroupBox(tr("EDIT_SELECTED_GROUP"), this);
-  QGridLayout* GroupEditLayout = new QGridLayout(GroupEdit);
-  GroupEditLayout->setSpacing(SPACING);
-  GroupEditLayout->setMargin(MARGIN);
-
-  ListEdit = new QListWidget(GroupEdit);
-  //ListEdit->setRowMode(QListBox::FixedNumber);
-  //ListEdit->setHScrollBarMode(QScrollView::AlwaysOn);
-  //ListEdit->setVScrollBarMode(QScrollView::AlwaysOff);
-  ListEdit->setFlow( QListView::LeftToRight );
-  ListEdit->setSelectionMode(QListWidget::ExtendedSelection);
-
-  AddElemButton = new QPushButton(GroupEdit);
-  AddElemButton->setIcon(IconAdd);
-  RemoveElemButton = new QPushButton(GroupEdit);
-  RemoveElemButton->setIcon(IconRemove);
-  SetFirstButton = new QPushButton(GroupEdit);
-  SetFirstButton->setIcon(QPixmap(IconFirst));
-
-  GroupEditLayout->addWidget(ListEdit,         0, 0, 2, 1);
-  GroupEditLayout->addWidget(AddElemButton,    0, 1);
-  GroupEditLayout->addWidget(RemoveElemButton, 0, 2);
-  GroupEditLayout->addWidget(SetFirstButton,   1, 1, 1, 2);
-
-  /***************************************************************/
-  GroupButtons = new QGroupBox(this);
-  QHBoxLayout* GroupButtonsLayout = new QHBoxLayout(GroupButtons);
-  GroupButtonsLayout->setSpacing(SPACING);
-  GroupButtonsLayout->setMargin(MARGIN);
-
-  buttonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), GroupButtons);
-  buttonOk->setAutoDefault(true);
-  buttonOk->setDefault(true);
-  buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons);
-  buttonApply->setAutoDefault(true);
-  buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons);
-  buttonCancel->setAutoDefault(true);
-  buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons);
-  buttonHelp->setAutoDefault(true);
-
-  GroupButtonsLayout->addWidget(buttonOk);
-  GroupButtonsLayout->addSpacing(10);
-  GroupButtonsLayout->addWidget(buttonApply);
-  GroupButtonsLayout->addSpacing(10);
-  GroupButtonsLayout->addStretch();
-  GroupButtonsLayout->addWidget(buttonCancel);
-  GroupButtonsLayout->addWidget(buttonHelp);
-
-  /***************************************************************/
-  DlgLayout->addWidget(GroupConstructors);
-  DlgLayout->addWidget(GroupMesh);
-  DlgLayout->addWidget(GroupCoincident);
-  DlgLayout->addWidget(GroupEdit);
-  DlgLayout->addWidget(GroupButtons);
-
-  Init(); // Initialisations
-}
-
-//=================================================================================
-// function : ~SMESHGUI_EditMeshDlg()
-// purpose  : Destroys the object and frees any allocated resources
-//=================================================================================
-SMESHGUI_EditMeshDlg::~SMESHGUI_EditMeshDlg()
-{
-  delete myIdPreview;
-}
-
-//=================================================================================
-// function : Init()
-// purpose  :
-//=================================================================================
-void SMESHGUI_EditMeshDlg::Init()
-{
-  if (myAction == 0) {
-    SpinBoxTolerance->RangeStepAndValidator(0.0, COORD_MAX, 0.00001, 5);
-    SpinBoxTolerance->SetValue(1e-05);
-  }
-
-  RadioButton->setChecked(true);
-
-  myEditCurrentArgument = (QWidget*)LineEditMesh; 
-
-  myActor = 0;
-  mySubMeshOrGroup = SMESH::SMESH_subMesh::_nil();
-
-  mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
-
-  mySMESHGUI->SetActiveDialogBox((QDialog*)this);
-  myIsBusy = false;
-  
-  // Costruction of the logical filter
-  SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter (MESHorSUBMESH);
-  SMESH_TypeFilter* aSmeshGroupFilter    = new SMESH_TypeFilter (GROUP);
-  
-  QList<SUIT_SelectionFilter*> aListOfFilters;
-  if (aMeshOrSubMeshFilter) aListOfFilters.append(aMeshOrSubMeshFilter);
-  if (aSmeshGroupFilter)    aListOfFilters.append(aSmeshGroupFilter);
-
-  myMeshOrSubMeshOrGroupFilter =
-    new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR);
-  
-  /* 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(buttonHelp,   SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
-
-  connect(SelectMeshButton, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument()));
-  connect(DetectButton, SIGNAL (clicked()), this, SLOT(onDetect()));
-  connect(ListCoincident, SIGNAL (itemSelectionChanged()), this, SLOT(onSelectGroup()));
-  connect(AddGroupButton, SIGNAL (clicked()), this, SLOT(onAddGroup()));
-  connect(RemoveGroupButton, SIGNAL (clicked()), this, SLOT(onRemoveGroup()));
-  connect(SelectAllCB, SIGNAL(toggled(bool)), this, SLOT(onSelectAll(bool)));
-  connect(ListEdit, SIGNAL (itemSelectionChanged()), this, SLOT(onSelectElementFromGroup()));
-  connect(AddElemButton, SIGNAL (clicked()), this, SLOT(onAddElement()));
-  connect(RemoveElemButton, SIGNAL (clicked()), this, SLOT(onRemoveElement()));
-  connect(SetFirstButton, SIGNAL( clicked() ), this, SLOT( onSetFirst() ) );
-
-  connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
-  connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
-  /* to close dialog if study change */
-  connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(ClickOnCancel()));
-
-  SetFirstButton->setEnabled(false);
-  buttonOk->setEnabled(false);
-  buttonApply->setEnabled(false);
-
-  // Init Mesh field from selection
-  SelectionIntoArgument();
-
-  myHelpFileName = "merging_elements_page.html";
-}
-
-//=================================================================================
-// function : FindGravityCenter()
-// purpose  :
-//=================================================================================
-void SMESHGUI_EditMeshDlg::FindGravityCenter(TColStd_MapOfInteger & theElemsIdMap, 
-                                            std::list< gp_XYZ > & theGrCentersXYZ)
-{
-  if (!myActor)
-    return;
-
-  SMDS_Mesh* aMesh = 0;
-  aMesh = myActor->GetObject()->GetMesh();
-  if (!aMesh)
-    return;
-
-  int nbNodes;
-
-  TColStd_MapIteratorOfMapOfInteger idIter( theElemsIdMap );
-  for( ; idIter.More(); idIter.Next() ) {
-    const SMDS_MeshElement* anElem = aMesh->FindElement(idIter.Key());
-    if ( !anElem )
-      continue;
-
-    gp_XYZ anXYZ(0., 0., 0.);
-    SMDS_ElemIteratorPtr nodeIt = anElem->nodesIterator();
-    for ( nbNodes = 0; nodeIt->more(); nbNodes++ ) {
-      const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-      anXYZ.Add( gp_XYZ( node->X(), node->Y(), node->Z() ) );
-    }
-    anXYZ.Divide( nbNodes );
-    
-    theGrCentersXYZ.push_back( anXYZ );
-  }
-}
-
-//=================================================================================
-// function : ClickOnApply()
-// purpose  :
-//=================================================================================
-bool SMESHGUI_EditMeshDlg::ClickOnApply()
-{
-  if (mySMESHGUI->isActiveStudyLocked() || myMesh->_is_nil())
-    return false;
-
-  try {
-    SUIT_OverrideCursor aWaitCursor;
-    SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
-
-    SMESH::long_array_var anIds = new SMESH::long_array;
-    SMESH::array_of_long_array_var aGroupsOfElements = new SMESH::array_of_long_array;
-
-    aGroupsOfElements->length(ListCoincident->count());
-
-    int anArrayNum = 0;
-    for (int i = 0; i < ListCoincident->count(); i++) {
-      QStringList aListIds = ListCoincident->item(i)->text().split(" ", QString::SkipEmptyParts);
-
-      anIds->length(aListIds.count());
-      for (int i = 0; i < aListIds.count(); i++)
-        anIds[i] = aListIds[i].toInt();
-
-      aGroupsOfElements[anArrayNum++] = anIds.inout();
-    }
-
-    if( myAction == 0 )
-      aMeshEditor->MergeNodes (aGroupsOfElements.inout());
-    else
-      aMeshEditor->MergeElements (aGroupsOfElements.inout());
-
-  } catch(...) {
-  }
-  
-  SMESH::UpdateView();
-
-  onDetect();
-  return true;
-}
-
-//=================================================================================
-// function : ClickOnOk()
-// purpose  :
-//=================================================================================
-void SMESHGUI_EditMeshDlg::ClickOnOk()
-{
-  if (ClickOnApply())
-    ClickOnCancel();
-}
-
-//=================================================================================
-// function : ClickOnCancel()
-// purpose  :
-//=================================================================================
-void SMESHGUI_EditMeshDlg::ClickOnCancel()
-{
-  myIdPreview->SetPointsLabeled(false);
-  mySelectionMgr->clearFilters();
-  //mySelectionMgr->clearSelected();
-  SMESH::SetPointRepresentation(false);
-  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-    aViewWindow->SetSelectionMode(ActorSelection);
-  disconnect(mySelectionMgr, 0, this, 0);
-  mySMESHGUI->ResetState();
-  reject();
-}
-
-//=================================================================================
-// function : ClickOnHelp()
-// purpose  :
-//=================================================================================
-void SMESHGUI_EditMeshDlg::ClickOnHelp()
-{
-  LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
-  if (app) 
-    app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
-  else {
-    QString platform;
-#ifdef WIN32
-    platform = "winapplication";
-#else
-    platform = "application";
-#endif
-    SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser", 
-                                                                platform)).
-                            arg(myHelpFileName));
-  }
-}
-
-//=================================================================================
-// function : onEditGroup()
-// purpose  :
-//=================================================================================
-void SMESHGUI_EditMeshDlg::onEditGroup()
-{
-  QList<QListWidgetItem*> selItems = ListCoincident->selectedItems();
-  if ( selItems.count() != 1 ) {
-    ListEdit->clear();
-    return;
-  }
-
-  QStringList aNewIds;
-
-  for (int i = 0; i < ListEdit->count(); i++ )
-    aNewIds.append(ListEdit->item(i)->text());
-
-  ListCoincident->clearSelection();
-  selItems.first()->setText(aNewIds.join(" "));
-  selItems.first()->setSelected(true);
-}
-
-//=================================================================================
-// function : updateControls()
-// purpose  :
-//=================================================================================
-void SMESHGUI_EditMeshDlg::updateControls()
-{
-  if (ListEdit->count() == 0)
-    SetFirstButton->setEnabled(false);
-  bool enable = !(myMesh->_is_nil()) && ListCoincident->count();
-  buttonOk->setEnabled(enable);
-  buttonApply->setEnabled(enable);
-}
-
-//=================================================================================
-// function : onDetect()
-// purpose  :
-//=================================================================================
-void SMESHGUI_EditMeshDlg::onDetect()
-{
-  if ( myMesh->_is_nil() || LineEditMesh->text().isEmpty() )
-    return;
-
-  try {
-    SUIT_OverrideCursor aWaitCursor;
-    SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
-
-    ListCoincident->clear();
-    ListEdit->clear();
-
-    SMESH::array_of_long_array_var aGroupsArray;
-
-    switch (myAction) {
-    case 0 :
-      if(!mySubMeshOrGroup->_is_nil())
-       aMeshEditor->FindCoincidentNodesOnPart(mySubMeshOrGroup, SpinBoxTolerance->GetValue(), aGroupsArray);
-      else
-       aMeshEditor->FindCoincidentNodes(SpinBoxTolerance->GetValue(), aGroupsArray);
-      break;
-    case 1 :
-      if(!mySubMeshOrGroup->_is_nil())
-       aMeshEditor->FindEqualElements(mySubMeshOrGroup, aGroupsArray);
-      else
-       aMeshEditor->FindEqualElements(myMesh, aGroupsArray);
-      break;
-    }
-    
-    for (int i = 0; i < aGroupsArray->length(); i++) {
-      SMESH::long_array& aGroup = aGroupsArray[i];
-
-      QStringList anIDs;
-      for (int j = 0; j < aGroup.length(); j++)
-       anIDs.append(QString::number(aGroup[j]));
-
-      ListCoincident->addItem(anIDs.join(" "));
-    }
-   } catch(...) {
-  }
-
-  ListCoincident->selectAll();
-  updateControls();
-}
-
-//=================================================================================
-// function : onSelectGroup()
-// purpose  :
-//=================================================================================
-void SMESHGUI_EditMeshDlg::onSelectGroup()
-{
-  if (myIsBusy || !myActor)
-    return;
-  myEditCurrentArgument = (QWidget*)ListCoincident;
-
-  ListEdit->clear();
-  
-  TColStd_MapOfInteger anIndices;
-  QList<QListWidgetItem*> selItems = ListCoincident->selectedItems();
-  QListWidgetItem* anItem;
-  QStringList aListIds;
-
-  ListEdit->clear();
-
-  foreach(anItem, selItems) {
-    aListIds = anItem->text().split(" ", QString::SkipEmptyParts);
-    for (int i = 0; i < aListIds.count(); i++)
-      anIndices.Add(aListIds[i].toInt());
-  }
-  
-  if (selItems.count() == 1) {
-    ListEdit->addItems(aListIds);
-    ListEdit->selectAll();
-  }
-
-  mySelector->AddOrRemoveIndex(myActor->getIO(), anIndices, false);
-  SALOME_ListIO aList;
-  aList.Append(myActor->getIO());
-  mySelectionMgr->setSelectedObjects(aList,false);
-  
-  if (myAction == 0) {
-    myIdPreview->SetPointsData(myActor->GetObject()->GetMesh(), anIndices);
-    myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
-  }
-  else {
-    std::list< gp_XYZ > aGrCentersXYZ;
-    FindGravityCenter(anIndices, aGrCentersXYZ);
-    myIdPreview->SetElemsData( anIndices, aGrCentersXYZ);
-    myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
-  }
-
-  updateControls();
-}
-
-//=================================================================================
-// function : onSelectAll()
-// purpose  :
-//=================================================================================
-void SMESHGUI_EditMeshDlg::onSelectAll (bool isToggled)
-{
-  if ( isToggled )
-    ListCoincident->selectAll();
-  else
-    ListCoincident->clearSelection();
-}
-
-//=================================================================================
-// function : onSelectElementFromGroup()
-// purpose  :
-//=================================================================================
-void SMESHGUI_EditMeshDlg::onSelectElementFromGroup()
-{
-  if (myIsBusy || !myActor)
-    return;
-
-  TColStd_MapOfInteger anIndices;
-  QList<QListWidgetItem*> selItems = ListEdit->selectedItems();
-  QListWidgetItem* anItem;
-
-  foreach(anItem, selItems)
-    anIndices.Add(anItem->text().toInt());
-
-  SetFirstButton->setEnabled(selItems.count() == 1);
-
-  mySelector->AddOrRemoveIndex(myActor->getIO(), anIndices, false);
-  SALOME_ListIO aList;
-  aList.Append(myActor->getIO());
-  mySelectionMgr->setSelectedObjects(aList);
-
-  if (myAction == 0) {
-    myIdPreview->SetPointsData(myActor->GetObject()->GetMesh(), anIndices);
-    myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
-  }
-  else {
-    std::list< gp_XYZ > aGrCentersXYZ;
-    FindGravityCenter(anIndices, aGrCentersXYZ);
-    myIdPreview->SetElemsData(anIndices, aGrCentersXYZ);
-    myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
-  }
-}
-
-//=================================================================================
-// function : onAddGroup()
-// purpose  :
-//=================================================================================
-void SMESHGUI_EditMeshDlg::onAddGroup()
-{
-  if ( myMesh->_is_nil() || LineEditMesh->text().isEmpty() )
-    return;
-
-  QString anIDs = "";
-  SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), anIDs);
-  
-  ListCoincident->clearSelection();
-  ListCoincident->addItem(anIDs);
-  int nbGroups = ListCoincident->count();
-  if (nbGroups) {
-    ListCoincident->setCurrentRow(nbGroups-1);
-    ListCoincident->item(nbGroups-1)->setSelected(true);
-  }
-  else {
-    // VSR ? this code seems to be never executed!!!
-    ListCoincident->setCurrentRow(0);
-    //ListCoincident->setSelected(0, true); // VSR: no items - no selection
-  }
-
-  updateControls();
-}
-
-//=================================================================================
-// function : onRemoveGroup()
-// purpose  :
-//=================================================================================
-void SMESHGUI_EditMeshDlg::onRemoveGroup()
-{
-  if (myEditCurrentArgument != (QWidget*)ListCoincident)
-    return;
-  myIsBusy = true;
-
-  QList<QListWidgetItem*> selItems = ListCoincident->selectedItems();
-  QListWidgetItem* anItem;
-
-  foreach(anItem, selItems)
-    delete anItem;
-
-  ListEdit->clear();
-  updateControls();
-
-  myIsBusy = false;
-}
-
-//=================================================================================
-// function : onAddElement()
-// purpose  :
-//=================================================================================
-void SMESHGUI_EditMeshDlg::onAddElement()
-{
-  if (!myActor)
-    return;
-  myIsBusy = true;
-
-  QString aListStr = "";
-  int aNbNnodes = 0;
-
-  aNbNnodes = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aListStr);
-  if (aNbNnodes < 1)
-    return;
-
-  QStringList aNodes = aListStr.split(" ", QString::SkipEmptyParts);
-
-  for (QStringList::iterator it = aNodes.begin(); it != aNodes.end(); ++it) {
-    QList<QListWidgetItem*> found = ListEdit->findItems(*it, Qt::MatchExactly);
-    if ( found.count() == 0 ) {
-      QListWidgetItem* anItem = new QListWidgetItem(*it);
-      ListEdit->addItem(anItem);
-      anItem->setSelected(true);
-    }
-    else {
-      QListWidgetItem* anItem;
-      foreach(anItem, found) anItem->setSelected(true);
-    }
-  }
-
-  myIsBusy = false;
-  onEditGroup();
-}
-
-//=================================================================================
-// function : onRemoveElement()
-// purpose  :
-//=================================================================================
-void SMESHGUI_EditMeshDlg::onRemoveElement()
-{
-  if (myEditCurrentArgument != (QWidget*)ListCoincident)
-    return;
-  myIsBusy = true;
-
-  QList<QListWidgetItem*> selItems = ListEdit->selectedItems();
-  QListWidgetItem* anItem;
-
-  foreach(anItem, selItems)
-    delete anItem;
-  
-  myIsBusy = false;
-  onEditGroup();
-}
-
-//=================================================================================
-// function : onSetFirst()
-// purpose  :
-//=================================================================================
-void SMESHGUI_EditMeshDlg::onSetFirst()
-{
-  if (myEditCurrentArgument != (QWidget*)ListCoincident)
-    return;
-  myIsBusy = true;
-  
-  QList<QListWidgetItem*> selItems = ListEdit->selectedItems();
-  QListWidgetItem* anItem;
-  
-  foreach(anItem, selItems) {
-    ListEdit->takeItem(ListEdit->row(anItem));
-    ListEdit->insertItem(0, anItem);
-  }
-
-  myIsBusy = false;
-  onEditGroup();
-}
-
-//=================================================================================
-// function : SetEditCurrentArgument()
-// purpose  :
-//=================================================================================
-void SMESHGUI_EditMeshDlg::SetEditCurrentArgument()
-{
-  QPushButton* send = (QPushButton*)sender();
-
-  disconnect(mySelectionMgr, 0, this, 0);
-  mySelectionMgr->clearSelected();
-  mySelectionMgr->clearFilters();
-
-  if (send == SelectMeshButton) {
-    myEditCurrentArgument = (QWidget*)LineEditMesh;
-    SMESH::SetPointRepresentation(false);
-    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-      aViewWindow->SetSelectionMode(ActorSelection);
-    mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter);
-  }
-
-  myEditCurrentArgument->setFocus();
-  connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
-  SelectionIntoArgument();
-}
-
-//=================================================================================
-// function : SelectionIntoArgument()
-// purpose  : Called when selection as changed or other case
-//=================================================================================
-void SMESHGUI_EditMeshDlg::SelectionIntoArgument()
-{
-  if (myEditCurrentArgument == (QWidget*)LineEditMesh) {
-    QString aString = "";
-    LineEditMesh->setText(aString);
-    
-    ListCoincident->clear();
-    ListEdit->clear();
-    myActor = 0;
-    
-    int nbSel = SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
-    if (nbSel != 1)
-      return;
-
-    SALOME_ListIO aList;
-    mySelectionMgr->selectedObjects(aList, SVTK_Viewer::Type());
-    
-    Handle(SALOME_InteractiveObject) IO = aList.First();
-    myMesh = SMESH::GetMeshByIO(IO);
-    
-    if (myMesh->_is_nil())
-      return;
-    
-    myActor = SMESH::FindActorByEntry(IO->getEntry());
-    if (!myActor)
-      myActor = SMESH::FindActorByObject(myMesh);
-    if(!myActor)
-      return;
-    
-    mySubMeshOrGroup = SMESH::SMESH_IDSource::_nil();
-    
-    if ((!SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(IO)->_is_nil() || //SUBMESH OR GROUP
-         !SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(IO)->_is_nil()) &&
-        !SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO)->_is_nil())
-      mySubMeshOrGroup = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO);
-     
-    LineEditMesh->setText(aString);
-
-    if (myAction == 0) {
-      SMESH::SetPointRepresentation(true);
-      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-       aViewWindow->SetSelectionMode(NodeSelection);
-    }
-    else
-      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-       aViewWindow->SetSelectionMode(CellSelection);
-  }
-}
-
-//=================================================================================
-// function : DeactivateActiveDialog()
-// purpose  :
-//=================================================================================
-void SMESHGUI_EditMeshDlg::DeactivateActiveDialog()
-{
-  if (GroupConstructors->isEnabled()) {
-    GroupConstructors->setEnabled(false);
-    GroupMesh->setEnabled(false);
-    GroupCoincident->setEnabled(false);
-    GroupEdit->setEnabled(false);
-    GroupButtons->setEnabled(false);
-    mySMESHGUI->ResetState();
-    mySMESHGUI->SetActiveDialogBox(0);
-  }
-
-  mySelectionMgr->clearSelected();
-  disconnect(mySelectionMgr, 0, this, 0);
-}
-
-//=================================================================================
-// function : ActivateThisDialog()
-// purpose  :
-//=================================================================================
-void SMESHGUI_EditMeshDlg::ActivateThisDialog()
-{
-  /* Emit a signal to deactivate the active dialog */
-  mySMESHGUI->EmitSignalDeactivateDialog();
-  GroupConstructors->setEnabled(true);
-  GroupMesh->setEnabled(true);
-  GroupCoincident->setEnabled(true);
-  GroupEdit->setEnabled(true);
-  GroupButtons->setEnabled(true);
-
-  connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
-  mySMESHGUI->SetActiveDialogBox((QDialog*)this);
-  SelectionIntoArgument();
-}
-
-//=================================================================================
-// function : enterEvent()
-// purpose  :
-//=================================================================================
-void SMESHGUI_EditMeshDlg::enterEvent(QEvent*)
-{
-  if (!GroupConstructors->isEnabled())
-    ActivateThisDialog();
-}
-
-//=================================================================================
-// function : closeEvent()
-// purpose  :
-//=================================================================================
-void SMESHGUI_EditMeshDlg::closeEvent(QCloseEvent*)
-{
-  /* same than click on cancel button */
-  ClickOnCancel();
-}
-
-//=======================================================================
-//function : hideEvent
-//purpose  : caused by ESC key
-//=======================================================================
-void SMESHGUI_EditMeshDlg::hideEvent (QHideEvent *)
-{
-  if (!isMinimized())
-    ClickOnCancel();
-}
-
-//=================================================================================
-// function : keyPressEvent()
-// purpose  :
-//=================================================================================
-void SMESHGUI_EditMeshDlg::keyPressEvent( QKeyEvent* e)
-{
-  QDialog::keyPressEvent( e );
-  if ( e->isAccepted() )
-    return;
-
-  if ( e->key() == Qt::Key_F1 ) {
-    e->accept();
-    ClickOnHelp();
-  }
-}
diff --git a/src/SMESHGUI/SMESHGUI_EditMeshDlg.h b/src/SMESHGUI/SMESHGUI_EditMeshDlg.h
deleted file mode 100644 (file)
index 3b96bed..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-// SMESH SMESHGUI : GUI for SMESH component
-// File   : SMESHGUI_EditMeshDlg.h
-// Author : Open CASCADE S.A.S.
-//
-#ifndef SMESHGUI_EDITMESHDLG_H
-#define SMESHGUI_EDITMESHDLG_H
-
-// SMESH includes
-#include "SMESH_SMESHGUI.hxx"
-
-// Qt includes
-#include <QDialog>
-
-// OCCT includes
-#include <gp_XYZ.hxx>
-
-// STL includes
-#include <list>
-
-// IDL includes
-#include <SALOMEconfig.h>
-#include CORBA_SERVER_HEADER(SMESH_Mesh)
-
-class QGroupBox;
-class QLabel;
-class QLineEdit;
-class QPushButton;
-class QRadioButton;
-class QCheckBox;
-class QListWidget;
-class SMESHGUI;
-class SMESHGUI_SpinBox;
-class SMESH_Actor;
-class SVTK_Selector;
-class LightApp_SelectionMgr;
-class SUIT_SelectionFilter;
-class TColStd_MapOfInteger;
-
-namespace SMESH
-{
-  struct TIdPreview;
-}
-
-//=================================================================================
-// class    : SMESHGUI_EditMeshDlg
-// purpose  : 
-//=================================================================================
-class SMESHGUI_EXPORT SMESHGUI_EditMeshDlg : public QDialog
-{
-  Q_OBJECT;
-
-public:
-  SMESHGUI_EditMeshDlg( SMESHGUI*, int );
-  ~SMESHGUI_EditMeshDlg();
-
-private:
-  void                      Init();
-  void                      closeEvent( QCloseEvent* );
-  void                      enterEvent( QEvent* );              /* mouse enter the QWidget */
-  void                      hideEvent( QHideEvent* );           /* ESC key */
-  void                      keyPressEvent( QKeyEvent* );
-  void                      onEditGroup();
-
-  void                      FindGravityCenter( TColStd_MapOfInteger&, 
-                                              std::list<gp_XYZ>& );
-  // add the centers of gravity of ElemsIdMap elements to the GrCentersXYZ list
-
-private:
-  SMESHGUI*                 mySMESHGUI;     /* Current SMESHGUI object */
-  LightApp_SelectionMgr*    mySelectionMgr; /* User shape selection */
-  SVTK_Selector*            mySelector;
-  
-  QWidget*                  myEditCurrentArgument;
-
-  SMESH::SMESH_Mesh_var     myMesh;
-  SMESH::SMESH_IDSource_var mySubMeshOrGroup;
-  SMESH_Actor*              myActor;
-  SUIT_SelectionFilter*     myMeshOrSubMeshOrGroupFilter;
-
-  SMESH::TIdPreview*        myIdPreview;
-
-  int                       myAction;
-  bool                      myIsBusy;
-
-  // Widgets
-  QGroupBox*                GroupConstructors;
-  QRadioButton*             RadioButton;
-
-  QGroupBox*                GroupButtons;
-  QPushButton*              buttonOk;
-  QPushButton*              buttonCancel;
-  QPushButton*              buttonApply;
-  QPushButton*              buttonHelp;
-
-  QGroupBox*                GroupMesh;
-  QLabel*                   TextLabelName;
-  QPushButton*              SelectMeshButton;
-  QLineEdit*                LineEditMesh;
-
-  QGroupBox*                GroupCoincident;
-  QLabel*                   TextLabelTolerance;
-  SMESHGUI_SpinBox*         SpinBoxTolerance;
-  QPushButton*              DetectButton;
-  QListWidget*              ListCoincident;
-  QPushButton*              AddGroupButton;
-  QPushButton*              RemoveGroupButton;
-  QCheckBox*                SelectAllCB;
-
-  QGroupBox*                GroupEdit;
-  QListWidget*              ListEdit;
-  QPushButton*              AddElemButton;
-  QPushButton*              RemoveElemButton;
-  QPushButton*              SetFirstButton;
-    
-  QString                   myHelpFileName;
-
- private slots:
-  void                      ClickOnOk();
-  void                      ClickOnCancel();
-  bool                      ClickOnApply();
-  void                      ClickOnHelp();
-  void                      updateControls();
-  void                      onDetect();
-  void                      onAddGroup();
-  void                      onRemoveGroup();
-  void                      onSelectGroup();
-  void                      onSelectAll( bool );
-  void                      onSelectElementFromGroup();
-  void                      onAddElement();
-  void                      onRemoveElement();
-  void                      onSetFirst();
-  void                      SetEditCurrentArgument();
-  void                      SelectionIntoArgument();
-  void                      DeactivateActiveDialog();
-  void                      ActivateThisDialog();
-};
-
-#endif // SMESHGUI_EDITMESHDLG_H
index a8cffc9e3230a998d426ca7b285f8d7c2799af95..4ec84dce95e8c3384d93871a4497acd0daa5bd3d 100644 (file)
@@ -1,29 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_ExtrusionAlongPathDlg.cxx
 // Author : Vadim SANDLER, Open CASCADE S.A.S.
 // SMESH includes
-//
+
 #include "SMESHGUI_ExtrusionAlongPathDlg.h"
 
 #include "SMESHGUI.h"
@@ -33,6 +34,7 @@
 #include "SMESHGUI_SpinBox.h"
 #include "SMESHGUI_IdValidator.h"
 #include "SMESHGUI_FilterDlg.h"
+#include "SMESHGUI_MeshEditPreview.h"
 
 #include <SMESH_Actor.h>
 #include <SMESH_TypeFilter.hxx>
@@ -108,8 +110,7 @@ private:
 // purpose  : constructor
 //=================================================================================
 SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theModule )
-  : QDialog( SMESH::GetDesktop( theModule ) ),
-    mySMESHGUI( theModule ),
+  : SMESHGUI_PreviewDlg( theModule ),
     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
     myFilterDlg( 0 )
 {
@@ -166,8 +167,9 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod
 
   ElementsLineEdit = new QLineEdit(GroupArguments);
   ElementsLineEdit->setValidator(myIdValidator);
-  QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
-  connect(filterBtn,   SIGNAL(clicked()), this, SLOT(setFilters()));
+  ElementsLineEdit->setMaxLength(-1);
+  myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
+  connect(myFilterBtn,   SIGNAL(clicked()), this, SLOT(setFilters()));
 
   // Controls for the whole mesh selection
   MeshCheck = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments);
@@ -186,15 +188,6 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod
   PathMeshLineEdit = new QLineEdit(PathGrp);
   PathMeshLineEdit->setReadOnly(true);
 
-  // Controls for path shape selection
-  QLabel* PathShapeLab = new QLabel(tr("SMESH_PATH_SHAPE"), PathGrp);
-
-  SelectPathShapeButton = new QToolButton(PathGrp);
-  SelectPathShapeButton->setIcon(selectImage);
-
-  PathShapeLineEdit = new QLineEdit(PathGrp);
-  PathShapeLineEdit->setReadOnly(true);
-
   // Controls for path starting point selection
   QLabel* StartPointLab = new QLabel(tr("SMESH_PATH_START"), PathGrp);
 
@@ -208,12 +201,9 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod
   PathGrpLayout->addWidget(PathMeshLab,            0, 0);
   PathGrpLayout->addWidget(SelectPathMeshButton,   0, 1);
   PathGrpLayout->addWidget(PathMeshLineEdit,       0, 2);
-  PathGrpLayout->addWidget(PathShapeLab,           1, 0);
-  PathGrpLayout->addWidget(SelectPathShapeButton,  1, 1);
-  PathGrpLayout->addWidget(PathShapeLineEdit,      1, 2);
-  PathGrpLayout->addWidget(StartPointLab,          2, 0);
-  PathGrpLayout->addWidget(SelectStartPointButton, 2, 1);
-  PathGrpLayout->addWidget(StartPointLineEdit,     2, 2);
+  PathGrpLayout->addWidget(StartPointLab,          1, 0);
+  PathGrpLayout->addWidget(SelectStartPointButton, 1, 1);
+  PathGrpLayout->addWidget(StartPointLineEdit,     1, 2);
 
   BasePointGrp = new QGroupBox(tr("SMESH_BASE_POINT"), GroupArguments);
   BasePointGrp->setCheckable(true);
@@ -272,16 +262,20 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod
   MakeGroupsCheck = new QCheckBox(tr("SMESH_MAKE_GROUPS"), GroupArguments);
   MakeGroupsCheck->setChecked(true);
 
+  //Preview check box
+  myPreviewCheckBox = new QCheckBox(tr("PREVIEW"), GroupArguments);
+
   // layouting
   GroupArgumentsLayout->addWidget(ElementsLab,          0, 0);
   GroupArgumentsLayout->addWidget(SelectElementsButton, 0, 1);
   GroupArgumentsLayout->addWidget(ElementsLineEdit,     0, 2);
-  GroupArgumentsLayout->addWidget(filterBtn,            0, 3);
+  GroupArgumentsLayout->addWidget(myFilterBtn,          0, 3);
   GroupArgumentsLayout->addWidget(MeshCheck,            1, 0, 1, 4);
   GroupArgumentsLayout->addWidget(PathGrp,              2, 0, 1, 4);
   GroupArgumentsLayout->addWidget(BasePointGrp,         3, 0, 1, 4);
   GroupArgumentsLayout->addWidget(AnglesGrp,            4, 0, 1, 4);
-  GroupArgumentsLayout->addWidget(MakeGroupsCheck,      5, 0, 1, 4);
+  GroupArgumentsLayout->addWidget(myPreviewCheckBox,    5, 0, 1, 4);
+  GroupArgumentsLayout->addWidget(MakeGroupsCheck,      6, 0, 1, 4);
 
   /***************************************************************/
   // common buttons group box
@@ -319,10 +313,10 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod
 
   /***************************************************************/
   // Initialisations
-  XSpin->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
-  YSpin->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
-  ZSpin->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
-  AngleSpin->RangeStepAndValidator(-180.0, 180.0, 5.0, 3);
+  XSpin->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  YSpin->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  ZSpin->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  AngleSpin->RangeStepAndValidator(-180.0, 180.0, 5.0, "angle_precision");
 
   mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
 
@@ -337,7 +331,8 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod
   if (aSmeshGroupFilter)    aListOfFilters.append(aSmeshGroupFilter);
 
   myElementsFilter = new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR);
-  myPathMeshFilter = new SMESH_TypeFilter (MESH);
+  //myPathMeshFilter = new SMESH_TypeFilter (MESH);
+  myPathMeshFilter = new SMESH_TypeFilter(MESHorSUBMESH);
 
   myHelpFileName = "extrusion_along_path_page.html";
 
@@ -357,7 +352,6 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod
 
   connect(SelectElementsButton,   SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
   connect(SelectPathMeshButton,   SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
-  connect(SelectPathShapeButton,  SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
   connect(SelectStartPointButton, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
   connect(SelectBasePointButton,  SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
 
@@ -366,12 +360,23 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod
   connect(mySMESHGUI,  SIGNAL(SignalCloseAllDialogs()),        this, SLOT(reject()));
 
   connect(ElementsLineEdit, SIGNAL(textChanged(const QString&)),
-         SLOT(onTextChange(const QString&)));
+          SLOT(onTextChange(const QString&)));
   connect(StartPointLineEdit, SIGNAL(textChanged(const QString&)),
-         SLOT(onTextChange(const QString&)));
+          SLOT(onTextChange(const QString&)));
 
   connect(MeshCheck,      SIGNAL(toggled(bool)), SLOT(onSelectMesh()));
 
+  connect(XSpin,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(YSpin,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(ZSpin,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(AddAngleButton,  SIGNAL(clicked()), this, SLOT(toDisplaySimulation()));
+  connect(RemoveAngleButton, SIGNAL(clicked()), this, SLOT(toDisplaySimulation()));
+  connect(LinearAnglesCheck, SIGNAL(toggled(bool)), SLOT(onSelectMesh()));
+
+
+  //To Connect preview check box
+  connectPreviewControl();
+
   AnglesList->installEventFilter(this);
   ElementsLineEdit->installEventFilter(this);
   StartPointLineEdit->installEventFilter(this);
@@ -405,12 +410,10 @@ void SMESHGUI_ExtrusionAlongPathDlg::Init (bool ResetControls)
   myMesh      = SMESH::SMESH_Mesh::_nil();
   myIDSource  = SMESH::SMESH_IDSource::_nil();
   myMeshActor = 0;
-  myPathMesh  = SMESH::SMESH_Mesh::_nil();
-  myPathShape = GEOM::GEOM_Object::_nil();
+  myPath  = SMESH::SMESH_IDSource::_nil();
 
   ElementsLineEdit->clear();
   PathMeshLineEdit->clear();
-  PathShapeLineEdit->clear();
   StartPointLineEdit->clear();
 
   if (ResetControls) {
@@ -422,6 +425,8 @@ void SMESHGUI_ExtrusionAlongPathDlg::Init (bool ResetControls)
     MeshCheck->setChecked(false);
     ConstructorsClicked(0);
     onSelectMesh();
+    myPreviewCheckBox->setChecked(false);
+    onDisplaySimulation(false);
   }
   SetEditCurrentArgument(0);
 }
@@ -436,6 +441,8 @@ void SMESHGUI_ExtrusionAlongPathDlg::ConstructorsClicked (int type)
 
   disconnect(mySelectionMgr, 0, this, 0);
 
+  hidePreview();
+
   if (type == 0)
     GroupArguments->setTitle(tr("EXTRUSION_1D"));
   else if (type == 1)
@@ -454,19 +461,19 @@ void SMESHGUI_ExtrusionAlongPathDlg::ConstructorsClicked (int type)
     SMESH::SetPointRepresentation(false);
     if (MeshCheck->isChecked()) {
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-       aViewWindow->SetSelectionMode(ActorSelection);
+        aViewWindow->SetSelectionMode(ActorSelection);
       mySelectionMgr->installFilter(myElementsFilter);
     } else {
       if (type == 0)
-       {
-         if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-           aViewWindow->SetSelectionMode(EdgeSelection);
-       }
+        {
+          if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+            aViewWindow->SetSelectionMode(EdgeSelection);
+        }
       if (type == 1)
-       {
-         if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-           aViewWindow->SetSelectionMode(FaceSelection);
-       }
+        {
+          if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+            aViewWindow->SetSelectionMode(FaceSelection);
+        }
     }
   }
   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
@@ -483,50 +490,21 @@ bool SMESHGUI_ExtrusionAlongPathDlg::ClickOnApply()
   if (mySMESHGUI->isActiveStudyLocked())
     return false;
 
-  if (myMesh->_is_nil() || MeshCheck->isChecked() && myIDSource->_is_nil() ||
-      !myMeshActor || myPathMesh->_is_nil() || myPathShape->_is_nil())
+  //if (myMesh->_is_nil() || MeshCheck->isChecked() && myIDSource->_is_nil() ||
+  //    !myMeshActor || myPathMesh->_is_nil() || myPathShape->_is_nil())
+  if ( myMesh->_is_nil() || (MeshCheck->isChecked() && myIDSource->_is_nil()) ||
+       /*!myMeshActor ||*/ myPath->_is_nil() )
     return false;
 
   if (!isValid())
     return false;
 
-  SMESH::long_array_var anElementsId = new SMESH::long_array;
-
-  if (!MeshCheck->isChecked()) {
-    // If "Select whole mesh, submesh or group" check box is off ->
-    // use only elements of given type selected by user
-
-    SMDS_Mesh* aMesh = myMeshActor->GetObject()->GetMesh();
-    if (aMesh) {
-      QStringList aListElementsId = ElementsLineEdit->text().split(" ", QString::SkipEmptyParts);
-      anElementsId = new SMESH::long_array;
-      anElementsId->length(aListElementsId.count());
-      bool bOk;
-      int j = 0;
-      for (int i = 0; i < aListElementsId.count(); i++) {
-       long ind = aListElementsId[ i ].toLong(&bOk);
-       if  (bOk) {
-         const SMDS_MeshElement* e = aMesh->FindElement(ind);
-         if (e) {
-           bool typeMatch = Elements1dRB->isChecked() && e->GetType() == SMDSAbs_Edge ||
-                            Elements2dRB->isChecked() && e->GetType() == SMDSAbs_Face;
-           if (typeMatch)
-             anElementsId[ j++ ] = ind;
-         }
-       }
-      }
-      anElementsId->length(j);
-    }
-
-    if (anElementsId->length() <= 0) {
-      return false;
-    }
-  }
+  SMESH::long_array_var anElementsId = getSelectedElements();
 
   if (StartPointLineEdit->text().trimmed().isEmpty()) {
     return false;
   }
-
+  
   bool bOk;
   long aNodeStart = StartPointLineEdit->text().toLong(&bOk);
   if (!bOk) {
@@ -534,19 +512,13 @@ bool SMESHGUI_ExtrusionAlongPathDlg::ClickOnApply()
   }
 
   QStringList aParameters;
+  
+  //get angles
+  SMESH::double_array_var anAngles = getAngles();
+  
+  for (int i = 0; i < myAnglesList.count(); i++) 
+    aParameters << AnglesList->item(i)->text();
 
-  // get angles
-  SMESH::double_array_var anAngles = new SMESH::double_array;
-  if (AnglesGrp->isChecked()) {
-    anAngles->length(myAnglesList.count());
-    int j = 0;
-    for (int i = 0; i < myAnglesList.count(); i++) {
-      double angle = myAnglesList[i];
-      anAngles[ j++ ] = angle*PI/180;
-      aParameters << AnglesList->item(i)->text();
-    }
-    anAngles->length(j);
-  }
 
   // get base point
   SMESH::PointStruct aBasePoint;
@@ -562,88 +534,63 @@ bool SMESHGUI_ExtrusionAlongPathDlg::ClickOnApply()
 
   try {
     SUIT_OverrideCursor wc;
-    SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
-    if ( LinearAnglesCheck->isChecked() )
-      anAngles = aMeshEditor->LinearAnglesVariation( myPathMesh, myPathShape, anAngles );
 
+    SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
     SMESH::SMESH_MeshEditor::Extrusion_Error retVal;
-    if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ) {
-      if( MeshCheck->isChecked() ) {
-       if( GetConstructorId() == 0 )
-         SMESH::ListOfGroups_var groups = 
-           aMeshEditor->ExtrusionAlongPathObject1DMakeGroups(myIDSource, myPathMesh,
-                                                             myPathShape, aNodeStart,
-                                                             AnglesGrp->isChecked(), anAngles,
-                                                             BasePointGrp->isChecked(), aBasePoint, retVal);
-       else
-         SMESH::ListOfGroups_var groups = 
-           aMeshEditor->ExtrusionAlongPathObject2DMakeGroups(myIDSource, myPathMesh,
-                                                             myPathShape, aNodeStart,
-                                                             AnglesGrp->isChecked(), anAngles,
-                                                             BasePointGrp->isChecked(), aBasePoint, retVal);
-      }
-      else
-       SMESH::ListOfGroups_var groups = 
-         aMeshEditor->ExtrusionAlongPathMakeGroups(anElementsId, myPathMesh,
-                                                   myPathShape, aNodeStart,
-                                                   AnglesGrp->isChecked(), anAngles,
-                                                   BasePointGrp->isChecked(), aBasePoint, retVal);
+
+    myMesh->SetParameters( aParameters.join(":").toLatin1().constData() );
+
+    bool NeedGroups = ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() );
+    SMESH::ElementType ElemType = SMESH::FACE;
+    if( GetConstructorId() == 0 )
+      ElemType = SMESH::EDGE;
+    if( !MeshCheck->isChecked() ) {
+      SMESH::ListOfGroups_var groups = 
+        aMeshEditor->ExtrusionAlongPathX(anElementsId, myPath, aNodeStart, AnglesGrp->isChecked(),
+                                         anAngles, LinearAnglesCheck->isChecked(),
+                                         BasePointGrp->isChecked(), aBasePoint,
+                                         NeedGroups, ElemType, retVal);
     }
     else {
-      if( MeshCheck->isChecked() ) {
-       if( GetConstructorId() == 0 )
-         retVal = aMeshEditor->ExtrusionAlongPathObject1D(myIDSource, myPathMesh,
-                                                          myPathShape, aNodeStart,
-                                                          AnglesGrp->isChecked(), anAngles,
-                                                          BasePointGrp->isChecked(), aBasePoint);
-       else
-         retVal = aMeshEditor->ExtrusionAlongPathObject2D(myIDSource, myPathMesh,
-                                                          myPathShape, aNodeStart,
-                                                          AnglesGrp->isChecked(), anAngles,
-                                                          BasePointGrp->isChecked(), aBasePoint);
-      }
-      else
-       retVal = aMeshEditor->ExtrusionAlongPath(anElementsId, myPathMesh,
-                                                myPathShape, aNodeStart,
-                                                AnglesGrp->isChecked(), anAngles,
-                                                BasePointGrp->isChecked(), aBasePoint);
+      SMESH::ListOfGroups_var groups = 
+        aMeshEditor->ExtrusionAlongPathObjX(myIDSource, myPath, aNodeStart, AnglesGrp->isChecked(),
+                                          anAngles, LinearAnglesCheck->isChecked(),
+                                          BasePointGrp->isChecked(), aBasePoint,
+                                          NeedGroups, ElemType, retVal);
     }
 
-    if( retVal == SMESH::SMESH_MeshEditor::EXTR_OK )
-      myMesh->SetParameters( SMESHGUI::JoinObjectParameters(aParameters) );
 
-    //wc.stop();
     wc.suspend();
     switch (retVal) {
     case SMESH::SMESH_MeshEditor::EXTR_NO_ELEMENTS:
       SUIT_MessageBox::warning(this,
-                              tr("SMESH_ERROR"),
-                              tr("NO_ELEMENTS_SELECTED"));
+                               tr("SMESH_ERROR"),
+                               tr("NO_ELEMENTS_SELECTED"));
       return false; break;
     case SMESH::SMESH_MeshEditor::EXTR_PATH_NOT_EDGE:
       SUIT_MessageBox::warning(this,
-                              tr("SMESH_ERROR"),
-                              tr("SELECTED_PATH_IS_NOT_EDGE"));
+                               tr("SMESH_ERROR"),
+                               tr("SELECTED_PATH_IS_NOT_EDGE"));
       return false; break;
     case SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE:
       SUIT_MessageBox::warning(this,
-                              tr("SMESH_ERROR"),
-                              tr("BAD_SHAPE_TYPE"));
+                               tr("SMESH_ERROR"),
+                               tr("BAD_SHAPE_TYPE"));
       return false; break;
     case SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE:
       SUIT_MessageBox::warning(this,
-                              tr("SMESH_ERROR"),
-                              tr("EXTR_BAD_STARTING_NODE"));
+                               tr("SMESH_ERROR"),
+                               tr("EXTR_BAD_STARTING_NODE"));
       return false; break;
     case SMESH::SMESH_MeshEditor::EXTR_BAD_ANGLES_NUMBER:
       SUIT_MessageBox::warning(this,
-                              tr("SMESH_ERROR"),
-                              tr("WRONG_ANGLES_NUMBER"));
+                               tr("SMESH_ERROR"),
+                               tr("WRONG_ANGLES_NUMBER"));
       return false; break;
     case SMESH::SMESH_MeshEditor::EXTR_CANT_GET_TANGENT:
       SUIT_MessageBox::warning(this,
-                              tr("SMESH_ERROR"),
-                              tr("CANT_GET_TANGENT"));
+                               tr("SMESH_ERROR"),
+                               tr("CANT_GET_TANGENT"));
       return false; break;
     case SMESH::SMESH_MeshEditor::EXTR_OK:
       break;
@@ -653,7 +600,11 @@ bool SMESHGUI_ExtrusionAlongPathDlg::ClickOnApply()
   }
 
   //mySelectionMgr->clearSelected();
-  SMESH::Update( myMeshActor->getIO(), myMeshActor->GetVisibility() );
+  if ( myMeshActor )
+    SMESH::Update( myMeshActor->getIO(), myMeshActor->GetVisibility() );
+    
+  SMESHGUI::Modified();
+
   if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() )
     mySMESHGUI->updateObjBrowser(true); // new groups may appear
   //SMESH::UpdateView();
@@ -689,10 +640,10 @@ void SMESHGUI_ExtrusionAlongPathDlg::ClickOnHelp()
     platform = "application";
 #endif
     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser", 
-                                                                platform)).
-                            arg(myHelpFileName));
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser", 
+                                                                 platform)).
+                             arg(myHelpFileName));
   }
 }
 
@@ -751,49 +702,50 @@ void SMESHGUI_ExtrusionAlongPathDlg::onTextChange (const QString& theNewText)
       const Handle(SALOME_InteractiveObject)& anIO = myMeshActor->getIO();
       TColStd_MapOfInteger newIndices;
       for (int i = 0; i < aListId.count(); i++) {
-       long ind = aListId[ i ].toLong(&bOk);
-       if (bOk) {
-         const SMDS_MeshElement* e = aMesh->FindElement(ind);
-         if (e) {
-           // check also type of element
-           bool typeMatch = Elements1dRB->isChecked() && e->GetType() == SMDSAbs_Edge ||
-                            Elements2dRB->isChecked() && e->GetType() == SMDSAbs_Face;
-           if (typeMatch)
-             newIndices.Add(e->GetID());
-         }
-       }
+        long ind = aListId[ i ].toLong(&bOk);
+        if (bOk) {
+          const SMDS_MeshElement* e = aMesh->FindElement(ind);
+          if (e) {
+            // check also type of element
+            bool typeMatch = (Elements1dRB->isChecked() && e->GetType() == SMDSAbs_Edge) ||
+                             (Elements2dRB->isChecked() && e->GetType() == SMDSAbs_Face);
+            if (typeMatch)
+              newIndices.Add(e->GetID());
+          }
+        }
       }
       mySelector->AddOrRemoveIndex(anIO, newIndices, false);
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-       aViewWindow->highlight( anIO, true, true );
+        aViewWindow->highlight( anIO, true, true );
     }
-  } else if (send == StartPointLineEdit &&
+  }
+  else if (send == StartPointLineEdit &&
              myEditCurrentArgument == StartPointLineEdit) {
-    if (!myPathMesh->_is_nil()) {
-      SMESH_Actor* aPathActor = SMESH::FindActorByObject(myPathMesh);
+    if (!myPath->_is_nil()) {
+      SMESH_Actor* aPathActor = SMESH::FindActorByObject(myPath);
       SMDS_Mesh* aMesh = 0;
       if (aPathActor)
-       aMesh = aPathActor->GetObject()->GetMesh();
+        aMesh = aPathActor->GetObject()->GetMesh();
       if (aMesh) {
-       //mySelectionMgr->clearSelected();
-       //mySelectionMgr->AddIObject(aPathActor->getIO());
+        //mySelectionMgr->clearSelected();
+        //mySelectionMgr->AddIObject(aPathActor->getIO());
         SALOME_ListIO aList;
         aList.Append(aPathActor->getIO());
         mySelectionMgr->setSelectedObjects(aList, false);
 
-       bool bOk;
-       long ind = theNewText.toLong(&bOk);
-       if (bOk) {
-         const SMDS_MeshNode* n = aMesh->FindNode(ind);
-         if (n) {
-           //if (!mySelectionMgr->IsIndexSelected(aPathActor->getIO(), n->GetID())) {
+        bool bOk;
+        long ind = theNewText.toLong(&bOk);
+        if (bOk) {
+          const SMDS_MeshNode* n = aMesh->FindNode(ind);
+          if (n) {
+            //if (!mySelectionMgr->IsIndexSelected(aPathActor->getIO(), n->GetID())) {
             TColStd_MapOfInteger newIndices;
-           newIndices.Add(n->GetID());
-           mySelector->AddOrRemoveIndex( aPathActor->getIO(), newIndices, false );
-           if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-             aViewWindow->highlight( aPathActor->getIO(), true, true );
-         }
-       }
+            newIndices.Add(n->GetID());
+            mySelector->AddOrRemoveIndex( aPathActor->getIO(), newIndices, false );
+            if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+              aViewWindow->highlight( aPathActor->getIO(), true, true );
+          }
+        }
       }
     }
   }
@@ -843,7 +795,7 @@ void SMESHGUI_ExtrusionAlongPathDlg::SelectionIntoArgument()
     }
     // find actor
     myMeshActor = SMESH::FindActorByObject(myMesh);
-    if (!myMeshActor)
+    if (!myMeshActor && !MeshCheck->isChecked())
       return;
 
     if (MeshCheck->isChecked()) {
@@ -862,57 +814,37 @@ void SMESHGUI_ExtrusionAlongPathDlg::SelectionIntoArgument()
       SMESH::GetNameOfSelectedElements(mySelector, IO, aString);
       ElementsLineEdit->setText(aString);
     }
-  } else if (myEditCurrentArgument == PathMeshLineEdit) {
+  }
+  else if (myEditCurrentArgument == PathMeshLineEdit) {
     // we are now selecting path mesh
     // reset
     PathMeshLineEdit->clear();
-    myPathMesh = SMESH::SMESH_Mesh::_nil();
-    PathShapeLineEdit->clear();
-    myPathShape = GEOM::GEOM_Object::_nil();
+    myPath = SMESH::SMESH_IDSource::_nil();
     StartPointLineEdit->clear();
-
+    
     // try to get mesh from selection
     Handle(SALOME_InteractiveObject) IO = aList.First();
-    myPathMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IO);
-    if(myPathMesh->_is_nil())
+    myPath = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO);
+    if( myPath->_is_nil() )
       return;
-
+    
     QString aString;
     SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
     PathMeshLineEdit->setText(aString);
-  } else if (myEditCurrentArgument == PathShapeLineEdit) {
-    // we are now selecting path mesh
-    // reset
-    PathShapeLineEdit->clear();
-    myPathShape = GEOM::GEOM_Object::_nil();
-    StartPointLineEdit->clear();
-
-    // return if path mesh is not yet selected
-    if (myPathMesh->_is_nil())
-      return;
-
-    // try to get shape from selection
-    Handle(SALOME_InteractiveObject) IO = aList.First();
-    myPathShape = SMESH::IObjectToInterface<GEOM::GEOM_Object>(IO);
-    if (myPathShape->_is_nil())
-      return;
-
-    QString aString;
-    SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
-    PathShapeLineEdit->setText(aString);
-  } else if (myEditCurrentArgument == StartPointLineEdit) {
+  }
+  else if (myEditCurrentArgument == StartPointLineEdit) {
     // we are now selecting start point of path
     // reset
     StartPointLineEdit->clear();
 
     // return if path mesh or path shape is not yet selected
-    if (myPathMesh->_is_nil() || myPathShape->_is_nil())
+    if( myPath->_is_nil() )
       return;
 
     // try to get shape from selection
     Handle(SALOME_InteractiveObject) IO = aList.First();
 
-    SMESH_Actor* aPathActor = SMESH::FindActorByObject(myPathMesh);
+    SMESH_Actor* aPathActor = SMESH::FindActorByObject(myPath);
     if ( !aPathActor )
       return;
     
@@ -937,10 +869,10 @@ void SMESHGUI_ExtrusionAlongPathDlg::SelectionIntoArgument()
     TopoDS_Vertex aVertex;
     if (!aGeomObj->_is_nil()) {
       if (aGeomObj->IsShape() && GEOMBase::GetShape(aGeomObj, aVertex) && !aVertex.IsNull()) {
-       gp_Pnt aPnt = BRep_Tool::Pnt(aVertex);
-       XSpin->SetValue(aPnt.X());
-       YSpin->SetValue(aPnt.Y());
-       ZSpin->SetValue(aPnt.Z());
+        gp_Pnt aPnt = BRep_Tool::Pnt(aVertex);
+        XSpin->SetValue(aPnt.X());
+        YSpin->SetValue(aPnt.Y());
+        ZSpin->SetValue(aPnt.Z());
       }
       return;
     }
@@ -972,6 +904,7 @@ void SMESHGUI_ExtrusionAlongPathDlg::SelectionIntoArgument()
     YSpin->SetValue(n->Y());
     ZSpin->SetValue(n->Z());
   }
+  onDisplaySimulation(true);
 }
 
 //=================================================================================
@@ -983,7 +916,6 @@ void SMESHGUI_ExtrusionAlongPathDlg::SetEditCurrentArgument()
   QToolButton* send = (QToolButton*)sender();
   if (send != SelectElementsButton   &&
       send != SelectPathMeshButton   &&
-      send != SelectPathShapeButton  &&
       send != SelectStartPointButton &&
       send != SelectBasePointButton)
     return;
@@ -997,7 +929,7 @@ void SMESHGUI_ExtrusionAlongPathDlg::SetEditCurrentArgument()
 void SMESHGUI_ExtrusionAlongPathDlg::SetEditCurrentArgument (QToolButton* button)
 {
   disconnect(mySelectionMgr, 0, this, 0);
-  mySelectionMgr->clearSelected();
+  //  mySelectionMgr->clearSelected();
   mySelectionMgr->clearFilters();
   SMESH::SetPickable();
 
@@ -1006,19 +938,19 @@ void SMESHGUI_ExtrusionAlongPathDlg::SetEditCurrentArgument (QToolButton* button
     SMESH::SetPointRepresentation(false);
     if (MeshCheck->isChecked()) {
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-       aViewWindow->SetSelectionMode(ActorSelection);
+        aViewWindow->SetSelectionMode(ActorSelection);
       mySelectionMgr->installFilter(myElementsFilter);
     } else {
       if (Elements1dRB->isChecked())
-       {
-         if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-           aViewWindow->SetSelectionMode(EdgeSelection);
-       }
+        {
+          if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+            aViewWindow->SetSelectionMode(EdgeSelection);
+        }
       else if (Elements2dRB->isChecked())
-       {
-         if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-           aViewWindow->SetSelectionMode(FaceSelection);
-       }
+        {
+          if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+            aViewWindow->SetSelectionMode(FaceSelection);
+        }
     }
   } else if (button == SelectPathMeshButton) {
     myEditCurrentArgument = PathMeshLineEdit;
@@ -1027,31 +959,16 @@ void SMESHGUI_ExtrusionAlongPathDlg::SetEditCurrentArgument (QToolButton* button
       aViewWindow->SetSelectionMode(ActorSelection);
     mySelectionMgr->installFilter(myPathMeshFilter);
   }
-  else if (button == SelectPathShapeButton) {
-    myEditCurrentArgument = PathShapeLineEdit;
-    SMESH::SetPointRepresentation(false);
-    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-      aViewWindow->SetSelectionMode(ActorSelection);
-
-    if (!myPathMesh->_is_nil()) {
-      GEOM::GEOM_Object_var aMainShape = myPathMesh->GetShapeToMesh();
-      SMESH_Actor* aPathActor = SMESH::FindActorByObject(myPathMesh);
-
-      if (!aMainShape->_is_nil() && aPathActor)
-       mySelectionMgr->installFilter(new SMESH_NumberFilter ("GEOM", TopAbs_SHAPE, -1,
-                                                              TopAbs_EDGE, aMainShape));
-       //SMESH::SetPickable(aPathActor);
-    }
-  }
   else if (button == SelectStartPointButton) {
     myEditCurrentArgument = StartPointLineEdit;
-    if (!myPathMesh->_is_nil()) {
-      SMESH_Actor* aPathActor = SMESH::FindActorByObject(myPathMesh);
+    //if (!myPathMesh->_is_nil()) {
+    if (!myPath->_is_nil()) {
+      SMESH_Actor* aPathActor = SMESH::FindActorByObject(myPath);
       if (aPathActor) {
-       SMESH::SetPointRepresentation(true);
-       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-         aViewWindow->SetSelectionMode(NodeSelection);
-       SMESH::SetPickable(aPathActor);
+        SMESH::SetPointRepresentation(true);
+        if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+          aViewWindow->SetSelectionMode(NodeSelection);
+        SMESH::SetPickable(aPathActor);
       }
     }
   }
@@ -1136,6 +1053,7 @@ void SMESHGUI_ExtrusionAlongPathDlg::onSelectMesh()
   ElementsLineEdit->setValidator(toSelectMesh ? 0 : myIdValidator);
   ElementsLab->setText(toSelectMesh ? tr("SMESH_NAME") : tr("SMESH_ID_ELEMENTS"));
   ElementsLineEdit->clear();
+  myFilterBtn->setEnabled(!toSelectMesh);
 
   SetEditCurrentArgument(SelectElementsButton);
 }
@@ -1195,21 +1113,21 @@ bool SMESHGUI_ExtrusionAlongPathDlg::eventFilter (QObject* object, QEvent* event
     QKeyEvent* ke = (QKeyEvent*)event;
     if (object == AnglesList) {
       if (ke->key() == Qt::Key_Delete)
-       OnAngleRemoved();
+        OnAngleRemoved();
     }
   }
   else if (event->type() == QEvent::FocusIn) {
     if (object == ElementsLineEdit) {
       if (myEditCurrentArgument != ElementsLineEdit)
-       SetEditCurrentArgument(SelectElementsButton);
+        SetEditCurrentArgument(SelectElementsButton);
     }
     else if (object == StartPointLineEdit) {
       if (myEditCurrentArgument != StartPointLineEdit)
-       SetEditCurrentArgument(SelectStartPointButton);
+        SetEditCurrentArgument(SelectStartPointButton);
     }
     else if (object == XSpin->editor() || object == YSpin->editor() || object == ZSpin->editor()) {
       if (myEditCurrentArgument != XSpin)
-       SetEditCurrentArgument(SelectBasePointButton);
+        SetEditCurrentArgument(SelectBasePointButton);
     }
   }
   return QDialog::eventFilter(object, event);
@@ -1237,6 +1155,12 @@ void SMESHGUI_ExtrusionAlongPathDlg::keyPressEvent( QKeyEvent* e )
 //=================================================================================
 void SMESHGUI_ExtrusionAlongPathDlg::setFilters()
 {
+  if(myMesh->_is_nil()) {
+    SUIT_MessageBox::critical(this,
+                              tr("SMESH_ERROR"),
+                              tr("NO_MESH_SELECTED"));
+   return;
+  }
   if ( !myFilterDlg )
   {
     QList<int> types;  
@@ -1287,10 +1211,162 @@ void SMESHGUI_ExtrusionAlongPathDlg::updateLinearAngles()
       enableLinear = false;
       anItem->text().toDouble(&enableLinear);
       if( !enableLinear )
-       break;
+        break;
     }
   }
   if( !enableLinear )
     LinearAnglesCheck->setChecked( false );
   LinearAnglesCheck->setEnabled( enableLinear );
 }
+
+//=================================================================================
+// function : isValuesValid()
+// purpose  : Return true in case if values entered into dialog are valid
+//=================================================================================
+bool SMESHGUI_ExtrusionAlongPathDlg::isValuesValid() {
+  
+  if ( (MeshCheck->isChecked() && myIDSource->_is_nil()) ||
+       myMesh->_is_nil() ||
+       myPath->_is_nil() )
+    return false;
+  
+  if(!MeshCheck->isChecked()) {
+    QStringList aListElementsId = ElementsLineEdit->text().split(" ", QString::SkipEmptyParts);
+    if(aListElementsId.count() <= 0)
+      return false;
+  }
+
+  bool bOk;
+  StartPointLineEdit->text().toLong(&bOk);
+  if (!bOk) {
+    return false;
+  }
+
+  return true;
+}
+
+
+//=================================================================================
+// function : onDisplaySimulation
+// purpose  : Show/Hide preview
+//=================================================================================
+void SMESHGUI_ExtrusionAlongPathDlg::onDisplaySimulation( bool toDisplayPreview ) {
+  if (myPreviewCheckBox->isChecked() && toDisplayPreview) {
+    if(isValid() && isValuesValid()) {
+      
+      //Get selected elements:
+      SMESH::long_array_var anElementsId = getSelectedElements();
+
+      // get angles
+      SMESH::double_array_var anAngles = getAngles();
+      
+      // get base point
+      SMESH::PointStruct aBasePoint;
+      if (BasePointGrp->isChecked()) {
+        aBasePoint.x = XSpin->GetValue();
+        aBasePoint.y = YSpin->GetValue();
+        aBasePoint.z = ZSpin->GetValue();
+      }
+      bool bOk;
+      long aNodeStart = StartPointLineEdit->text().toLong(&bOk);
+      if (bOk) {
+        
+        try {
+          SUIT_OverrideCursor wc;
+          
+          SMESH::SMESH_MeshEditor::Extrusion_Error retVal;
+          SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditPreviewer();
+          bool NeedGroups = false;
+          SMESH::ElementType ElemType = SMESH::FACE;
+          if( GetConstructorId() == 0 )
+            ElemType = SMESH::EDGE;
+          if( !MeshCheck->isChecked() ) {
+            aMeshEditor->ExtrusionAlongPathX(anElementsId, myPath, aNodeStart, AnglesGrp->isChecked(),
+                                             anAngles, LinearAnglesCheck->isChecked(),
+                                             BasePointGrp->isChecked(), aBasePoint,
+                                             NeedGroups, ElemType, retVal);
+          }
+          else {
+            SMESH::ListOfGroups_var groups = 
+              aMeshEditor->ExtrusionAlongPathObjX(myIDSource, myPath, aNodeStart, AnglesGrp->isChecked(),
+                                                  anAngles, LinearAnglesCheck->isChecked(),
+                                                  BasePointGrp->isChecked(), aBasePoint,
+                                                  NeedGroups, ElemType, retVal);
+          }
+          
+          wc.suspend();
+          if( retVal == SMESH::SMESH_MeshEditor::EXTR_OK ) {
+            SMESH::MeshPreviewStruct_var aMeshPreviewStruct = aMeshEditor->GetPreviewData();
+            mySimulation->SetData(aMeshPreviewStruct._retn());
+          } else {
+            hidePreview();
+          }
+          
+        } catch (...) {
+          hidePreview();
+        }
+      } else {
+        hidePreview();
+      }
+      
+    } else {
+      hidePreview();
+    }
+  } else {
+    hidePreview();
+  }
+}
+
+
+//=================================================================================
+// function : getSelectedElements
+// purpose  : return list of the selected elements
+//=================================================================================
+SMESH::long_array_var SMESHGUI_ExtrusionAlongPathDlg::getSelectedElements() {
+
+  // If "Select whole mesh, submesh or group" check box is off ->
+  // use only elements of given type selected by user
+  SMESH::long_array_var anElementsId = new SMESH::long_array;
+  if (!MeshCheck->isChecked()) {
+    
+    SMDS_Mesh* aMesh;
+    if ( myMeshActor )
+      aMesh = myMeshActor->GetObject()->GetMesh();
+    
+    if (aMesh) {
+      QStringList aListElementsId = ElementsLineEdit->text().split(" ", QString::SkipEmptyParts);
+      anElementsId = new SMESH::long_array;
+      anElementsId->length(aListElementsId.count());
+      bool bOk;
+      int j = 0;
+      for (int i = 0; i < aListElementsId.count(); i++) {
+        long ind = aListElementsId[ i ].toLong(&bOk);
+        if  (bOk) {
+          const SMDS_MeshElement* e = aMesh->FindElement(ind);
+          if (e) {
+            bool typeMatch = (Elements1dRB->isChecked() && e->GetType() == SMDSAbs_Edge) ||
+                             (Elements2dRB->isChecked() && e->GetType() == SMDSAbs_Face);
+            if (typeMatch)
+                  anElementsId[ j++ ] = ind;
+          }
+        }
+      }
+      anElementsId->length(j);
+    }
+  }
+  return anElementsId;
+}
+
+SMESH::double_array_var SMESHGUI_ExtrusionAlongPathDlg::getAngles() {
+  SMESH::double_array_var anAngles = new SMESH::double_array;
+  if (AnglesGrp->isChecked()) {
+    anAngles->length(myAnglesList.count());
+    int j = 0;
+    for (int i = 0; i < myAnglesList.count(); i++) {
+      double angle = myAnglesList[i];
+      anAngles[ j++ ] = angle*M_PI/180.;
+    }
+    anAngles->length(j);
+  }
+  return anAngles;
+}
index 4e1cbcb9c05ff4cb4ee2d7642a02299b1f864dda..b02aeb7a2b9fe37d4d3eae83856e7c991dae5edd 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_ExtrusionAlongPathDlg.h
 // Author : Vadim SANDLER, Open CASCADE S.A.S.
@@ -28,9 +29,7 @@
 
 // SMESH includes
 #include "SMESH_SMESHGUI.hxx"
-
-// Qt includes
-#include <QDialog>
+#include "SMESHGUI_PreviewDlg.h"
 
 // IDL includes
 #include <SALOMEconfig.h>
@@ -59,7 +58,7 @@ class SUIT_SelectionFilter;
 // class    : SMESHGUI_ExtrusionAlongPathDlg
 // purpose  :
 //=================================================================================
-class SMESHGUI_EXPORT SMESHGUI_ExtrusionAlongPathDlg : public QDialog
+class SMESHGUI_EXPORT SMESHGUI_ExtrusionAlongPathDlg : public SMESHGUI_PreviewDlg
 {
   Q_OBJECT
 
@@ -80,10 +79,13 @@ private:
   void                      SetEditCurrentArgument( QToolButton* );
 
   bool                      isValid();
+  bool                      isValuesValid();
+  
+  SMESH::long_array_var     getSelectedElements();
+  SMESH::double_array_var   getAngles();
 
   void                      updateLinearAngles();
   
-  SMESHGUI*                 mySMESHGUI;            /* Current SMESHGUI object */
   SMESHGUI_IdValidator*     myIdValidator;
   LightApp_SelectionMgr*    mySelectionMgr;        /* User shape selection */
   SVTK_Selector*            mySelector;
@@ -94,8 +96,9 @@ private:
   SMESH::SMESH_Mesh_var     myMesh;
   SMESH_Actor*              myMeshActor;
   SMESH::SMESH_IDSource_var myIDSource;
-  SMESH::SMESH_Mesh_var     myPathMesh;
-  GEOM::GEOM_Object_var     myPathShape;
+  //SMESH::SMESH_Mesh_var     myPathMesh;
+  SMESH::SMESH_IDSource_var myPath;
+  //GEOM::GEOM_Object_var     myPathShape;
   SUIT_SelectionFilter*     myElementsFilter;
   SUIT_SelectionFilter*     myPathMeshFilter;
   int                       myType;
@@ -115,8 +118,8 @@ private:
   QGroupBox*                PathGrp;
   QToolButton*              SelectPathMeshButton;
   QLineEdit*                PathMeshLineEdit;
-  QToolButton*              SelectPathShapeButton;
-  QLineEdit*                PathShapeLineEdit;
+  //QToolButton*              SelectPathShapeButton;
+  //QLineEdit*                PathShapeLineEdit;
   QToolButton*              SelectStartPointButton;
   QLineEdit*                StartPointLineEdit;
   QCheckBox*                LinearAnglesCheck;
@@ -140,10 +143,12 @@ private:
 
   QString                   myHelpFileName;
 
+  QPushButton*              myFilterBtn;
   SMESHGUI_FilterDlg*       myFilterDlg;
    
 protected slots:
   void                      reject();
+  virtual void              onDisplaySimulation( bool );
 
 private slots:
   void                      ConstructorsClicked( int );
index 0626e4575c3b4e4e3adf984e833b58f4f9ac0303..c75af4f45bfd259a32b7b205f1a5f5d02ef2a2ce 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_ExtrusionDlg.cxx
 // Author : Michael ZORIN, Open CASCADE S.A.S.
@@ -33,6 +34,7 @@
 #include "SMESHGUI_SpinBox.h"
 #include "SMESHGUI_IdValidator.h"
 #include "SMESHGUI_FilterDlg.h"
+#include "SMESHGUI_MeshEditPreview.h"
 
 #include <SMESH_Actor.h>
 #include <SMESH_TypeFilter.hxx>
@@ -87,8 +89,7 @@
 // purpose  : constructor
 //=================================================================================
 SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
-  : QDialog( SMESH::GetDesktop( theModule ) ),
-    mySMESHGUI( theModule ),
+  : SMESHGUI_PreviewDlg( theModule ),
     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
     myFilterDlg( 0 ),
     mySelectedObject(SMESH::SMESH_IDSource::_nil())
@@ -96,6 +97,7 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
   QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_DLG_EDGE")));
   QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_DLG_TRIANGLE")));
   QPixmap image2 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
+  QPixmap image3 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_DLG_NODE")));
 
   setModal( false );
   setAttribute( Qt::WA_DeleteOnClose, true );
@@ -113,16 +115,20 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
   ConstructorsBoxLayout->setSpacing(SPACING);
   ConstructorsBoxLayout->setMargin(MARGIN);
 
+  RadioButton0= new QRadioButton(ConstructorsBox);
+  RadioButton0->setIcon(image3);
   RadioButton1= new QRadioButton(ConstructorsBox);
   RadioButton1->setIcon(image0);
   RadioButton2= new QRadioButton(ConstructorsBox);
   RadioButton2->setIcon(image1);
 
+  ConstructorsBoxLayout->addWidget(RadioButton0);
   ConstructorsBoxLayout->addWidget(RadioButton1);
   ConstructorsBoxLayout->addWidget(RadioButton2);
 
-  GroupConstructors->addButton(RadioButton1, 0);
-  GroupConstructors->addButton(RadioButton2, 1);
+  GroupConstructors->addButton(RadioButton0, 0);
+  GroupConstructors->addButton(RadioButton1, 1);
+  GroupConstructors->addButton(RadioButton2, 2);
 
   /***************************************************************/
   GroupButtons = new QGroupBox(this);
@@ -149,7 +155,7 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
   GroupButtonsLayout->addWidget(buttonHelp);
 
   /***************************************************************/
-  GroupArguments = new QGroupBox(tr("EXTRUSION_1D"), this);
+  GroupArguments = new QGroupBox(tr("EXTRUSION_0D"), this);
   QGridLayout* GroupArgumentsLayout = new QGridLayout(GroupArguments);
   GroupArgumentsLayout->setSpacing(SPACING);
   GroupArgumentsLayout->setMargin(MARGIN);
@@ -164,16 +170,21 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
 
   LineEditElements = new QLineEdit(GroupArguments);
   LineEditElements->setValidator(myIdValidator);
-  QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
-  connect(filterBtn,   SIGNAL(clicked()), this, SLOT(setFilters()));
+  LineEditElements->setMaxLength(-1);
+  myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
+  connect(myFilterBtn,   SIGNAL(clicked()), this, SLOT(setFilters()));
 
   // Control for the whole mesh selection
   CheckBoxMesh = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments);
 
+  RadioButton3 = new QRadioButton(GroupArguments);
+  RadioButton3->setText( tr("SMESH_EXTRUSION_TO_DISTANCE") );
+  RadioButton4 = new QRadioButton(GroupArguments);
+  RadioButton4->setText( tr("SMESH_EXTRUSION_ALONG_VECTOR") );
+
   //Control for the Distance selection
   TextLabelDistance = new QLabel(tr("SMESH_DISTANCE"), GroupArguments);
   
-  TextLabelVector = new QLabel(tr("SMESH_VECTOR"), GroupArguments);
   TextLabelDx = new QLabel(tr("SMESH_X"), GroupArguments);
   SpinBox_Dx = new SMESHGUI_SpinBox(GroupArguments);
   
@@ -185,6 +196,8 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
 
   // Controls for vector selection
 
+  TextLabelVector = new QLabel(tr("SMESH_VECTOR"), GroupArguments);
+
   SelectVectorButton = new QPushButton(GroupArguments);
   SelectVectorButton->setIcon(image2);
 
@@ -197,6 +210,9 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
   TextLabelVz = new QLabel(tr("SMESH_DZ"), GroupArguments);
   SpinBox_Vz = new SMESHGUI_SpinBox(GroupArguments);
 
+  TextLabelDist = new QLabel(tr("SMESH_DISTANCE"), GroupArguments);
+  SpinBox_VDist = new SMESHGUI_SpinBox(GroupArguments);
+
   // Controls for nb. steps defining
   TextLabelNbSteps = new QLabel(tr("SMESH_NUMBEROFSTEPS"), GroupArguments);
   SpinBox_NbSteps = new SalomeApp_IntSpinBox(GroupArguments);
@@ -204,29 +220,39 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
   // CheckBox for groups generation
   MakeGroupsCheck = new QCheckBox(tr("SMESH_MAKE_GROUPS"), GroupArguments);
 
+  //Preview check box
+  myPreviewCheckBox = new QCheckBox(tr("PREVIEW"), GroupArguments);
+
   GroupArgumentsLayout->addWidget(TextLabelElements,    0, 0);
   GroupArgumentsLayout->addWidget(SelectElementsButton, 0, 1);
   GroupArgumentsLayout->addWidget(LineEditElements,     0, 2, 1, 5);
-  GroupArgumentsLayout->addWidget(filterBtn,            0, 7);
+  GroupArgumentsLayout->addWidget(myFilterBtn,          0, 7);
   GroupArgumentsLayout->addWidget(CheckBoxMesh,         1, 0, 1, 8);
-  GroupArgumentsLayout->addWidget(TextLabelDistance,    2, 0);
-  GroupArgumentsLayout->addWidget(TextLabelDx,          2, 2);
-  GroupArgumentsLayout->addWidget(SpinBox_Dx,           2, 3);
-  GroupArgumentsLayout->addWidget(TextLabelDy,          2, 4);
-  GroupArgumentsLayout->addWidget(SpinBox_Dy,           2, 5);
-  GroupArgumentsLayout->addWidget(TextLabelDz,          2, 6);
-  GroupArgumentsLayout->addWidget(SpinBox_Dz,           2, 7);
-  GroupArgumentsLayout->addWidget(TextLabelVector,      3, 0);
-  GroupArgumentsLayout->addWidget(SelectVectorButton,   3, 1);
-  GroupArgumentsLayout->addWidget(TextLabelVx,          3, 2);
-  GroupArgumentsLayout->addWidget(SpinBox_Vx,           3, 3);
-  GroupArgumentsLayout->addWidget(TextLabelVy,          3, 4);
-  GroupArgumentsLayout->addWidget(SpinBox_Vy,           3, 5);
-  GroupArgumentsLayout->addWidget(TextLabelVz,          3, 6);
-  GroupArgumentsLayout->addWidget(SpinBox_Vz,           3, 7);
-  GroupArgumentsLayout->addWidget(TextLabelNbSteps,     4, 0);
-  GroupArgumentsLayout->addWidget(SpinBox_NbSteps,      4, 2, 1, 6);
-  GroupArgumentsLayout->addWidget(MakeGroupsCheck,      5, 0, 1, 8);
+  GroupArgumentsLayout->addWidget(RadioButton3,         2, 1, 1, 3);
+  GroupArgumentsLayout->addWidget(RadioButton4,         2, 5, 1, 3);
+  GroupArgumentsLayout->addWidget(TextLabelDistance,    3, 0);
+  GroupArgumentsLayout->addWidget(TextLabelDx,          3, 2);
+  GroupArgumentsLayout->addWidget(SpinBox_Dx,           3, 3);
+  GroupArgumentsLayout->addWidget(TextLabelDy,          3, 4);
+  GroupArgumentsLayout->addWidget(SpinBox_Dy,           3, 5);
+  GroupArgumentsLayout->addWidget(TextLabelDz,          3, 6);
+  GroupArgumentsLayout->addWidget(SpinBox_Dz,           3, 7);
+  GroupArgumentsLayout->addWidget(TextLabelVector,      4, 0);
+  GroupArgumentsLayout->addWidget(SelectVectorButton,   4, 1);
+  GroupArgumentsLayout->addWidget(TextLabelVx,          4, 2);
+  GroupArgumentsLayout->addWidget(SpinBox_Vx,           4, 3);
+  GroupArgumentsLayout->addWidget(TextLabelVy,          4, 4);
+  GroupArgumentsLayout->addWidget(SpinBox_Vy,           4, 5);
+  GroupArgumentsLayout->addWidget(TextLabelVz,          4, 6);
+  GroupArgumentsLayout->addWidget(SpinBox_Vz,           4, 7);
+  GroupArgumentsLayout->addWidget(TextLabelDist,        5, 0);
+  GroupArgumentsLayout->addWidget(SpinBox_VDist,         5, 3);
+  GroupArgumentsLayout->addWidget(TextLabelNbSteps,     6, 0, 1, 3);
+  GroupArgumentsLayout->addWidget(SpinBox_NbSteps,      6, 3);
+  GroupArgumentsLayout->addWidget(myPreviewCheckBox,    7, 0, 1, 8);
+  GroupArgumentsLayout->addWidget(MakeGroupsCheck,      8, 0, 1, 8);
+  GroupArgumentsLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 8, 0);
+
 
   /***************************************************************/
   SMESHGUI_ExtrusionDlgLayout->addWidget(ConstructorsBox);
@@ -234,17 +260,19 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
   SMESHGUI_ExtrusionDlgLayout->addWidget(GroupButtons);
 
   /* Initialisations */
-  SpinBox_Vx->RangeStepAndValidator(-1, 1, 0.01, 3);
-  SpinBox_Vy->RangeStepAndValidator(-1, 1, 0.01, 3);
-  SpinBox_Vz->RangeStepAndValidator(-1, 1, 0.01, 3);
+  SpinBox_Vx->RangeStepAndValidator(COORD_MIN, COORD_MAX, 0.01, "length_precision");
+  SpinBox_Vy->RangeStepAndValidator(COORD_MIN, COORD_MAX, 0.01, "length_precision");
+  SpinBox_Vz->RangeStepAndValidator(COORD_MIN, COORD_MAX, 0.01, "length_precision");
 
-  SpinBox_Dx->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
-  SpinBox_Dy->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
-  SpinBox_Dz->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
+  SpinBox_Dx->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  SpinBox_Dy->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  SpinBox_Dz->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
   
   SpinBox_NbSteps->setRange(1, 999999);
+  SpinBox_VDist->RangeStepAndValidator(0, COORD_MAX, 10.0, "length_precision");
 
-  RadioButton1->setChecked(true);
+  RadioButton0->setChecked(true);
+  RadioButton3->setChecked(true);
   MakeGroupsCheck->setChecked(true);
 
   mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
@@ -273,6 +301,9 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
   connect(buttonApply,  SIGNAL(clicked()), this, SLOT(ClickOnApply()));
   connect(buttonHelp,   SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
 
+  connect(RadioButton3, SIGNAL(clicked()), this, SLOT(ClickOnRadio()));
+  connect(RadioButton4, SIGNAL(clicked()), this, SLOT(ClickOnRadio()));
+
   // to update state of the Ok & Apply buttons
   connect(SpinBox_Vx, SIGNAL(valueChanged(double)), SLOT(CheckIsEnable()));
   connect(SpinBox_Vy, SIGNAL(valueChanged(double)), SLOT(CheckIsEnable()));
@@ -291,9 +322,22 @@ SMESHGUI_ExtrusionDlg::SMESHGUI_ExtrusionDlg (SMESHGUI* theModule)
   connect(LineEditElements,     SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
   connect(CheckBoxMesh,         SIGNAL(toggled(bool)),               SLOT(onSelectMesh(bool)));
 
+  connect(SpinBox_Dx,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(SpinBox_Dy,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(SpinBox_Dz,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(SpinBox_Vx,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(SpinBox_Vy,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(SpinBox_Vz,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(SpinBox_VDist,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(SpinBox_NbSteps,  SIGNAL(valueChanged(int)), this, SLOT(toDisplaySimulation()));
+
+  //To Connect preview check box
+  connectPreviewControl();
+
   /***************************************************************/
   
   ConstructorsClicked(0);
+  ClickOnRadio();
   SelectionIntoArgument();
 }
 
@@ -316,6 +360,7 @@ SMESHGUI_ExtrusionDlg::~SMESHGUI_ExtrusionDlg()
 void SMESHGUI_ExtrusionDlg::Init (bool ResetControls)
 {
   myBusy = false;
+  myIDs.clear();
 
   LineEditElements->clear();
   myNbOkElements = 0;
@@ -325,6 +370,7 @@ void SMESHGUI_ExtrusionDlg::Init (bool ResetControls)
 
   if (ResetControls) {
     SpinBox_NbSteps->setValue(1);
+    SpinBox_VDist->setValue(10);
     SpinBox_Dx->SetValue(0);
     SpinBox_Dy->SetValue(0);
     SpinBox_Dz->SetValue(0);
@@ -334,6 +380,8 @@ void SMESHGUI_ExtrusionDlg::Init (bool ResetControls)
 
     CheckBoxMesh->setChecked(false);
     onSelectMesh(false);
+    myPreviewCheckBox->setChecked(false);
+    onDisplaySimulation(false);
   }
 
   CheckIsEnable();
@@ -344,19 +392,33 @@ void SMESHGUI_ExtrusionDlg::Init (bool ResetControls)
 // purpose  : Check whether the Ok and Apply buttons should be enabled or not
 //=================================================================================
 void SMESHGUI_ExtrusionDlg::CheckIsEnable()
-{
-  
-  double aX = SpinBox_Vx->GetValue()*SpinBox_Dx->GetValue();
-  double aY = SpinBox_Vy->GetValue()*SpinBox_Dy->GetValue();
-  double aZ = SpinBox_Vz->GetValue()*SpinBox_Dz->GetValue();
-  double aModule = sqrt(aX*aX + aY*aY + aZ*aZ);
-  
-  bool anIsEnable = myNbOkElements > 0 && aModule > 1.0E-38;
+{  
+  bool anIsEnable = myNbOkElements > 0 && isValuesValid();
 
   buttonOk->setEnabled(anIsEnable);
   buttonApply->setEnabled(anIsEnable);
 }
 
+//=================================================================================
+// function : isValuesValid()
+// purpose  : Return true in case if values entered into dialog are valid
+//=================================================================================
+bool SMESHGUI_ExtrusionDlg::isValuesValid() {
+  double aX, aY, aZ, aModule = 0;
+  if ( RadioButton3->isChecked() ) {
+    aX = SpinBox_Dx->GetValue();
+    aY = SpinBox_Dy->GetValue();
+    aZ = SpinBox_Dz->GetValue();
+    aModule = sqrt(aX*aX + aY*aY + aZ*aZ);
+  } else   if ( RadioButton4->isChecked() ) {
+    aX = SpinBox_Vx->GetValue();
+    aY = SpinBox_Vy->GetValue();
+    aZ = SpinBox_Vz->GetValue();
+    aModule = sqrt(aX*aX + aY*aY + aZ*aZ);
+  }
+  return aModule > 1.0E-38;
+}
+
 //=================================================================================
 // function : ConstructorsClicked()
 // purpose  : Radio button management
@@ -365,25 +427,45 @@ void SMESHGUI_ExtrusionDlg::ConstructorsClicked (int constructorId)
 {
   disconnect(mySelectionMgr, 0, this, 0);
 
+  hidePreview();
+
+  TextLabelElements->setText(tr( constructorId ? "SMESH_ID_ELEMENTS" : "SMESH_ID_NODES"));
+
   switch (constructorId) {
   case 0:
     {
-      GroupArguments->setTitle(tr("EXTRUSION_1D"));
+      GroupArguments->setTitle(tr("EXTRUSION_0D"));
       if (!CheckBoxMesh->isChecked())
-       {
-         if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-           aViewWindow->SetSelectionMode(EdgeSelection);
-       }
+      {
+        LineEditElements->clear();
+        myIDs.clear();
+        if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+          aViewWindow->SetSelectionMode(NodeSelection);
+      }
       break;
     }
   case 1:
+    {
+      GroupArguments->setTitle(tr("EXTRUSION_1D"));
+      if (!CheckBoxMesh->isChecked())
+      {
+        LineEditElements->clear();
+        myIDs.clear();
+        if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+          aViewWindow->SetSelectionMode(EdgeSelection);
+      }
+      break;
+    }
+  case 2:
     {
       GroupArguments->setTitle(tr("EXTRUSION_2D"));
       if (!CheckBoxMesh->isChecked())
-       {
-         if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-           aViewWindow->SetSelectionMode(FaceSelection);
-       }
+      {
+        LineEditElements->clear();
+        myIDs.clear();
+        if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+          aViewWindow->SetSelectionMode(FaceSelection);
+      }
       break;
     }
   }
@@ -397,6 +479,58 @@ void SMESHGUI_ExtrusionDlg::ConstructorsClicked (int constructorId)
   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
 }
 
+//=================================================================================
+// function : ConstructorsClicked()
+// purpose  : Radio button management
+//=================================================================================
+void SMESHGUI_ExtrusionDlg::ClickOnRadio()
+{
+  if ( RadioButton3->isChecked() ) {
+    TextLabelDistance->show();
+    TextLabelDx->show();
+    SpinBox_Dx->show();
+    TextLabelDy->show();
+    SpinBox_Dy->show();
+    TextLabelDz->show();
+    SpinBox_Dz->show();
+
+    TextLabelVector->hide();
+    TextLabelVx->hide();
+    SpinBox_Vx->hide();
+    TextLabelVy->hide();
+    SpinBox_Vy->hide();
+    TextLabelVz->hide();
+    SpinBox_Vz->hide();
+    TextLabelDist->hide();
+    SpinBox_VDist->hide();
+    SelectVectorButton->hide();
+  } else if ( RadioButton4->isChecked() ) {
+    TextLabelDistance->hide();
+    TextLabelDx->hide();
+    SpinBox_Dx->hide();
+    TextLabelDy->hide();
+    SpinBox_Dy->hide();
+    TextLabelDz->hide();
+    SpinBox_Dz->hide();
+
+    TextLabelVector->show();
+    TextLabelVx->show();
+    SpinBox_Vx->show();
+    TextLabelVy->show();
+    SpinBox_Vy->show();
+    TextLabelVz->show();
+    SpinBox_Vz->show();
+    TextLabelDist->show();
+    SpinBox_VDist->show();
+    SelectVectorButton->show();
+  }
+  onDisplaySimulation(true);
+  // AdjustSize
+  qApp->processEvents();
+  updateGeometry();
+  resize( minimumSizeHint() );
+}
+
 //=================================================================================
 // function : ClickOnApply()
 // purpose  : Called when user presses <Apply> button
@@ -410,66 +544,104 @@ bool SMESHGUI_ExtrusionDlg::ClickOnApply()
     return false;
 
   if (myNbOkElements) {
-    
-    gp_XYZ aNormale(SpinBox_Vx->GetValue(),
-                    SpinBox_Vy->GetValue(),
-                    SpinBox_Vz->GetValue());
-    
-    aNormale /= aNormale.Modulus();
-    
+
     SMESH::DirStruct aVector;
-    aVector.PS.x = SpinBox_Dx->GetValue()*aNormale.X();
-    aVector.PS.y = SpinBox_Dy->GetValue()*aNormale.Y();
-    aVector.PS.z = SpinBox_Dz->GetValue()*aNormale.Z();
+    getExtrusionVector(aVector);
+    
+    QStringList aParameters;
+    if ( RadioButton3->isChecked() ) {
+      aParameters << SpinBox_Dx->text();
+      aParameters << SpinBox_Dy->text();
+      aParameters << SpinBox_Dz->text();
+    } else if ( RadioButton4->isChecked() ) {
+      // only 3 coords in a python dump command :(
+      // aParameters << SpinBox_Vx->text();
+      // aParameters << SpinBox_Vy->text();
+      // aParameters << SpinBox_Vz->text();
+      // aParameters << SpinBox_VDist->text();
+    }
 
     long aNbSteps = (long)SpinBox_NbSteps->value();
 
-    QStringList aParameters;
-    aParameters << SpinBox_Dx->text();
-    aParameters << SpinBox_Dy->text();
-    aParameters << SpinBox_Dz->text();
     aParameters << SpinBox_NbSteps->text();
 
     try {
       SUIT_OverrideCursor aWaitCursor;
       SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
 
+      myMesh->SetParameters( aParameters.join(":").toLatin1().constData() );
+
       if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ) {
-        if( CheckBoxMesh->isChecked() ) {
-         if( GetConstructorId() == 0 )
-           SMESH::ListOfGroups_var groups = 
-             aMeshEditor->ExtrusionSweepObject1DMakeGroups(mySelectedObject, aVector, aNbSteps);
-         else
-           SMESH::ListOfGroups_var groups = 
-             aMeshEditor->ExtrusionSweepObject2DMakeGroups(mySelectedObject, aVector, aNbSteps);
-       }
-       else
-         SMESH::ListOfGroups_var groups = 
-           aMeshEditor->ExtrusionSweepMakeGroups(myElementsId.inout(), aVector, aNbSteps);
+        if( CheckBoxMesh->isChecked() ) 
+          switch (GetConstructorId() ) {
+            case 0:
+              {
+                SMESH::ListOfGroups_var groups = 
+                  aMeshEditor->ExtrusionSweepObject0DMakeGroups(mySelectedObject, aVector, aNbSteps);
+                break;
+              }
+            case 1:
+              {
+                SMESH::ListOfGroups_var groups = 
+                  aMeshEditor->ExtrusionSweepObject1DMakeGroups(mySelectedObject, aVector, aNbSteps);
+                break;
+              }
+            case 2:
+              {
+                SMESH::ListOfGroups_var groups = 
+                  aMeshEditor->ExtrusionSweepObject2DMakeGroups(mySelectedObject, aVector, aNbSteps);
+                break;
+              }
+          }
+        else
+        {
+          SMESH::ListOfGroups_var groups;
+          if (GetConstructorId() == 0)
+            groups = aMeshEditor->ExtrusionSweepMakeGroups0D(myElementsId.inout(), aVector, aNbSteps);
+          else
+            groups = aMeshEditor->ExtrusionSweepMakeGroups(myElementsId.inout(), aVector, aNbSteps);
+        }
+
       }
       else {
-       if( CheckBoxMesh->isChecked() ) {
-         if( GetConstructorId() == 0 )
-           aMeshEditor->ExtrusionSweepObject1D(mySelectedObject, aVector, aNbSteps);
-         else
-           aMeshEditor->ExtrusionSweepObject2D(mySelectedObject, aVector, aNbSteps);
-       }
-       else
-         aMeshEditor->ExtrusionSweep(myElementsId.inout(), aVector, aNbSteps);
+        if( CheckBoxMesh->isChecked() ) 
+          switch( GetConstructorId() ) {
+            case 0:
+              {
+              aMeshEditor->ExtrusionSweepObject0D(mySelectedObject, aVector, aNbSteps);
+                break;
+              }
+            case 1:
+              {
+              aMeshEditor->ExtrusionSweepObject1D(mySelectedObject, aVector, aNbSteps);
+                break;
+              }
+            case 2:
+              {
+              aMeshEditor->ExtrusionSweepObject2D(mySelectedObject, aVector, aNbSteps);
+                break;
+          }
+        }
+        else
+          if (GetConstructorId() == 0)
+            aMeshEditor->ExtrusionSweep0D(myElementsId.inout(), aVector, aNbSteps);
+          else
+            aMeshEditor->ExtrusionSweep(myElementsId.inout(), aVector, aNbSteps);
       }
 
-      myMesh->SetParameters( SMESHGUI::JoinObjectParameters(aParameters) );
-
     } catch (...) {
     }
 
-    SMESH::UpdateView();
+    SMESH::Update(myIO, SMESH::eDisplay);
     if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() )
       mySMESHGUI->updateObjBrowser(true); // new groups may appear
     Init(false);
     ConstructorsClicked(GetConstructorId());
+    mySelectionMgr->clearSelected();
     mySelectedObject = SMESH::SMESH_IDSource::_nil();
     SelectionIntoArgument();
+
+    SMESHGUI::Modified();
   }
   return true;
 }
@@ -490,17 +662,6 @@ void SMESHGUI_ExtrusionDlg::ClickOnOk()
 //=================================================================================
 void SMESHGUI_ExtrusionDlg::ClickOnCancel()
 {
-  disconnect(mySelectionMgr, 0, this, 0);
-  mySelectionMgr->clearFilters();
-  //mySelectionMgr->clearSelected();
-  if (SMESH::GetCurrentVtkView()) {
-    SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters
-    SMESH::SetPointRepresentation(false);
-    SMESH::SetPickable();
-  }
-  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-    aViewWindow->SetSelectionMode(ActorSelection);
-  mySMESHGUI->ResetState();
   reject();
 }
 
@@ -521,10 +682,10 @@ void SMESHGUI_ExtrusionDlg::ClickOnHelp()
     platform = "application";
 #endif
     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser", 
-                                                                platform)).
-                            arg(myHelpFileName));
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser", 
+                                                                 platform)).
+                             arg(myHelpFileName));
   }
 }
 
@@ -553,9 +714,28 @@ void SMESHGUI_ExtrusionDlg::onTextChange (const QString& theNewText)
     if (send == LineEditElements)
     {
       SMDS_Mesh* aMesh = myActor ? myActor->GetObject()->GetMesh() : 0;
-      SMESH::ElementType SMESHType = GetConstructorId() ? SMESH::FACE : SMESH::EDGE;
-      SMDSAbs_ElementType SMDSType = GetConstructorId() ? SMDSAbs_Face: SMDSAbs_Edge;
-
+      SMESH::ElementType SMESHType;
+      SMDSAbs_ElementType SMDSType;
+      switch (GetConstructorId()) {
+      case 0:
+        {
+          SMESHType = SMESH::NODE;
+          SMDSType = SMDSAbs_Node;
+          break;
+        }
+      case 1:
+        {
+          SMESHType = SMESH::EDGE;
+          SMDSType = SMDSAbs_Edge;
+          break;                  
+        }
+      case 2:
+        {
+          SMESHType = SMESH::FACE;
+          SMDSType = SMDSAbs_Face;
+          break;
+        }
+      }
       myElementsId = new SMESH::long_array;
       myElementsId->length( aListId.count() );
       TColStd_MapOfInteger newIndices;
@@ -564,7 +744,11 @@ void SMESHGUI_ExtrusionDlg::onTextChange (const QString& theNewText)
         bool validId = false;
         if ( id > 0 ) {
           if ( aMesh ) {
-            const SMDS_MeshElement * e = aMesh->FindElement( id );
+            const SMDS_MeshElement * e;
+            if (SMDSType == SMDSAbs_Node)
+              e = aMesh->FindNode( id ); 
+            else
+              e = aMesh->FindElement( id );
             validId = ( e && e->GetType() == SMDSType );
           } else {
             validId = ( myMesh->GetElementType( id, true ) == SMESHType );
@@ -576,12 +760,14 @@ void SMESHGUI_ExtrusionDlg::onTextChange (const QString& theNewText)
       myElementsId->length( myNbOkElements = newIndices.Extent() );
       mySelector->AddOrRemoveIndex(myIO, newIndices, false);
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-       aViewWindow->highlight( myIO, true, true );
+        aViewWindow->highlight( myIO, true, true );
     }
   }
 
   CheckIsEnable();
 
+  onDisplaySimulation(true);
+
   myBusy = false;
 }
 
@@ -598,8 +784,11 @@ void SMESHGUI_ExtrusionDlg::SelectionIntoArgument()
     return;
 
   // clear
-  myActor = 0;
-  myIO.Nullify();
+  if(myEditCurrentArgument != (QWidget*)SpinBox_Vx) {
+    myActor = 0;
+    Handle(SALOME_InteractiveObject) resIO = myIO;
+    myIO.Nullify();
+  }
 
   QString aString = "";
   // set busy flag
@@ -617,11 +806,14 @@ void SMESHGUI_ExtrusionDlg::SelectionIntoArgument()
     return;
 
   Handle(SALOME_InteractiveObject) IO = aList.First();
-  myMesh = SMESH::GetMeshByIO(IO);
-  if (myMesh->_is_nil())
-    return;
-  myIO = IO;
-  myActor = SMESH::FindActorByObject(myMesh);
+
+  if(myEditCurrentArgument != (QWidget*)SpinBox_Vx) {
+    myMesh = SMESH::GetMeshByIO(IO);
+    if (myMesh->_is_nil())
+      return;
+    myIO = IO;
+    myActor = SMESH::FindActorByObject(myMesh);
+  }
 
   if (myEditCurrentArgument == (QWidget*)LineEditElements) {    
     int aNbElements = 0;
@@ -648,7 +840,7 @@ void SMESHGUI_ExtrusionDlg::SelectionIntoArgument()
       aNbElements = aMapIndex.Extent();
 
       if (aNbElements < 1)
-       return;
+        return;
 
       myElementsId = new SMESH::long_array;
       myElementsId->length( aNbElements );
@@ -667,7 +859,9 @@ void SMESHGUI_ExtrusionDlg::SelectionIntoArgument()
     TColStd_IndexedMapOfInteger aMapIndex;
     mySelector->GetIndex(IO,aMapIndex);
     int aNbElements = aMapIndex.Extent();
-    SMDS_Mesh* aMesh =  myActor ? myActor->GetObject()->GetMesh() : 0;
+    SMESH::SMESH_Mesh_var aMesh_var = SMESH::GetMeshByIO(IO);
+    SMESH_Actor* anActor = SMESH::FindActorByObject(aMesh_var);
+    SMDS_Mesh* aMesh =  anActor ? anActor->GetObject()->GetMesh() : 0;
 
     if(aNbElements != 1 || !aMesh)
       return;
@@ -684,6 +878,8 @@ void SMESHGUI_ExtrusionDlg::SelectionIntoArgument()
     
   }
   
+  onDisplaySimulation(true);
+  
   // OK
   CheckIsEnable();
 }
@@ -704,20 +900,30 @@ void SMESHGUI_ExtrusionDlg::SetEditCurrentArgument()
     myEditCurrentArgument = (QWidget*)LineEditElements;
     if (CheckBoxMesh->isChecked()) {
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-       aViewWindow->SetSelectionMode(ActorSelection);
+        aViewWindow->SetSelectionMode(ActorSelection);
       mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter);
     } else {
       int aConstructorId = GetConstructorId();
-      if (aConstructorId == 0)
-       {
-         if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-           aViewWindow->SetSelectionMode(EdgeSelection);
-       }
-      else if (aConstructorId == 1)
-       {
-         if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-           aViewWindow->SetSelectionMode(FaceSelection);
-       }
+      switch(aConstructorId) {
+          case 0:
+          {   
+            if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+              aViewWindow->SetSelectionMode(NodeSelection);
+            break;
+          }
+          case 1:
+          {
+            if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+              aViewWindow->SetSelectionMode(EdgeSelection);
+            break;
+          }
+          case 2:
+          {
+            if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+            aViewWindow->SetSelectionMode(FaceSelection);
+            break;
+          }
+      }
     }
   }
   else if (send == SelectVectorButton){
@@ -774,17 +980,47 @@ void SMESHGUI_ExtrusionDlg::enterEvent (QEvent*)
     ActivateThisDialog();
 }
 
+//=================================================================================
+// function : closeEvent()
+// purpose  :
+//=================================================================================
+void SMESHGUI_ExtrusionDlg::closeEvent( QCloseEvent* )
+{
+  /* same than click on cancel button */
+  disconnect(mySelectionMgr, 0, this, 0);
+  mySelectionMgr->clearFilters();
+  //mySelectionMgr->clearSelected();
+  if (SMESH::GetCurrentVtkView()) {
+    SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters
+    SMESH::SetPointRepresentation(false);
+    SMESH::SetPickable();
+  }
+  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+    aViewWindow->SetSelectionMode(ActorSelection);
+  mySMESHGUI->ResetState();
+}
+
+void SMESHGUI_ExtrusionDlg::reject()
+{
+  QDialog::reject();
+  close();
+}
+
 //=================================================================================
 // function : onSelectMesh()
 // purpose  :
 //=================================================================================
 void SMESHGUI_ExtrusionDlg::onSelectMesh (bool toSelectMesh)
 {
-  if (toSelectMesh)
+  if (toSelectMesh) {
+    myIDs = LineEditElements->text();
     TextLabelElements->setText(tr("SMESH_NAME"));
+  }
   else
     TextLabelElements->setText(tr("SMESH_ID_ELEMENTS"));
 
+  myFilterBtn->setEnabled(!toSelectMesh);
+
   if (myEditCurrentArgument != LineEditElements) {
     LineEditElements->clear();
     return;
@@ -800,23 +1036,35 @@ void SMESHGUI_ExtrusionDlg::onSelectMesh (bool toSelectMesh)
     LineEditElements->setValidator(0);
   } else {
     int aConstructorId = GetConstructorId();
-    if (aConstructorId == 0)
-      {
-       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-         aViewWindow->SetSelectionMode(EdgeSelection);
-      }
-    else if (aConstructorId == 0)
-      {
-       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-         aViewWindow->SetSelectionMode(FaceSelection);
-      }
-
+    switch(aConstructorId) {
+      case 0:
+        {
+          if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+            aViewWindow->SetSelectionMode(NodeSelection);
+          break;
+        }
+      case 1:
+        {
+          if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+            aViewWindow->SetSelectionMode(EdgeSelection);
+          break;
+        }
+      case 2:
+        {
+          if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+            aViewWindow->SetSelectionMode(FaceSelection);
+          break;
+        }
+    }
     LineEditElements->setReadOnly(false);
     LineEditElements->setValidator(myIdValidator);
     onTextChange(LineEditElements->text());
   }
 
   SelectionIntoArgument();
+
+  if (!toSelectMesh)
+    LineEditElements->setText( myIDs );
 }
 
 //=================================================================================
@@ -850,14 +1098,38 @@ void SMESHGUI_ExtrusionDlg::keyPressEvent( QKeyEvent* e )
 //=================================================================================
 void SMESHGUI_ExtrusionDlg::setFilters()
 {
+  if(myMesh->_is_nil()) {
+    SUIT_MessageBox::critical(this,
+                              tr("SMESH_ERROR"),
+                              tr("NO_MESH_SELECTED"));
+   return;
+  }
   if ( !myFilterDlg )
   {
     QList<int> types;  
+    types.append( SMESH::NODE );
     types.append( SMESH::EDGE );
     types.append( SMESH::FACE );
     myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, types );
   }
-  myFilterDlg->Init( GetConstructorId() ? SMESH::FACE : SMESH::EDGE );
+  switch( GetConstructorId() ){
+    case 0: 
+      {
+      myFilterDlg->Init( SMESH::NODE );
+        break;
+      }
+    case 1:
+      {
+      myFilterDlg->Init( SMESH::EDGE );
+        break;
+      }
+    case 2:
+      {
+      myFilterDlg->Init( SMESH::FACE );
+        break;
+      }
+  }
+  
 
   myFilterDlg->SetSelection();
   myFilterDlg->SetMesh( myMesh );
@@ -874,9 +1146,16 @@ bool SMESHGUI_ExtrusionDlg::isValid()
 {
   QString msg;
   bool ok = true;
-  ok = SpinBox_Dx->isValid( msg, true ) && ok;
-  ok = SpinBox_Dy->isValid( msg, true ) && ok;
-  ok = SpinBox_Dz->isValid( msg, true ) && ok;
+  if ( RadioButton3->isChecked() ) {
+    ok = SpinBox_Dx->isValid( msg, true ) && ok;
+    ok = SpinBox_Dy->isValid( msg, true ) && ok;
+    ok = SpinBox_Dz->isValid( msg, true ) && ok;
+  } else if ( RadioButton4->isChecked() ) {
+    ok = SpinBox_Vx->isValid( msg, true ) && ok;
+    ok = SpinBox_Vy->isValid( msg, true ) && ok;
+    ok = SpinBox_Vz->isValid( msg, true ) && ok;
+    ok = SpinBox_VDist->isValid( msg, true ) && ok;
+  }
   ok = SpinBox_NbSteps->isValid( msg, true ) && ok;
 
   if( !ok ) {
@@ -888,3 +1167,82 @@ bool SMESHGUI_ExtrusionDlg::isValid()
   }
   return true;
 }
+
+//=================================================================================
+// function : onDisplaySimulation
+// purpose  : Show/Hide preview
+//=================================================================================
+void SMESHGUI_ExtrusionDlg::onDisplaySimulation( bool toDisplayPreview ) {
+  if (myPreviewCheckBox->isChecked() && toDisplayPreview) {
+    if (myNbOkElements && isValid() && isValuesValid()) {
+      //Get input vector
+      SMESH::DirStruct aVector;
+      getExtrusionVector(aVector);
+
+      //Get Number of the steps 
+      long aNbSteps = (long)SpinBox_NbSteps->value();
+      
+      try {
+        SUIT_OverrideCursor aWaitCursor;
+        SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditPreviewer();
+        if( CheckBoxMesh->isChecked() ) {
+          switch (GetConstructorId()) {
+            case 0:
+              {
+                aMeshEditor->ExtrusionSweepObject0D(mySelectedObject, aVector, aNbSteps);
+                                        break;
+              }
+            case 1:
+              {
+                aMeshEditor->ExtrusionSweepObject1D(mySelectedObject, aVector, aNbSteps);
+                                        break;
+              }
+            case 2:
+              {
+                aMeshEditor->ExtrusionSweepObject2D(mySelectedObject, aVector, aNbSteps);
+                                        break;
+              }
+          }
+        }
+        else
+          if(GetConstructorId() == 0)
+            aMeshEditor->ExtrusionSweep0D(myElementsId.inout(), aVector, aNbSteps);
+          else
+            aMeshEditor->ExtrusionSweep(myElementsId.inout(), aVector, aNbSteps);
+        
+        SMESH::MeshPreviewStruct_var aMeshPreviewStruct = aMeshEditor->GetPreviewData();
+        mySimulation->SetData(aMeshPreviewStruct._retn());
+      } catch (...) {
+        hidePreview();
+      }
+    } else {
+      hidePreview();
+    }
+  } else {
+    hidePreview();
+  }
+}
+
+//=================================================================================
+// function : getExtrusionVector()
+// purpose  : get direction of the extrusion
+//=================================================================================
+void SMESHGUI_ExtrusionDlg::getExtrusionVector(SMESH::DirStruct& aVector) {
+  if ( RadioButton3->isChecked() ) {
+    aVector.PS.x = SpinBox_Dx->GetValue();
+    aVector.PS.y = SpinBox_Dy->GetValue();
+    aVector.PS.z = SpinBox_Dz->GetValue();      
+  } else if ( RadioButton4->isChecked() ) {
+    gp_XYZ aNormale(SpinBox_Vx->GetValue(),
+                    SpinBox_Vy->GetValue(),
+                    SpinBox_Vz->GetValue());
+    
+    
+    aNormale /= aNormale.Modulus();
+    double aVDist = (double)SpinBox_VDist->value();
+    
+    aVector.PS.x = aNormale.X()*aVDist;
+    aVector.PS.y = aNormale.Y()*aVDist;
+    aVector.PS.z = aNormale.Z()*aVDist;
+  }
+}
index 99468eaa7dba01107f5183921bd5736015cceb2f..dd0b741a0a178ba1ff44ff7cdd5c9d52909b4bfb 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_ExtrusionDlg.h
 // Author : Michael ZORIN, Open CASCADE S.A.S.
 
 // SMESH includes
 #include "SMESH_SMESHGUI.hxx"
+#include "SMESHGUI_PreviewDlg.h"
 
 // SALOME GUI includes
 #include <SALOME_InteractiveObject.hxx>
 
-// Qt includes
-#include <QDialog>
-
 // IDL includes
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Mesh)
@@ -61,7 +60,7 @@ class SalomeApp_IntSpinBox;
 // class    : SMESHGUI_ExtrusionDlg
 // purpose  :
 //=================================================================================
-class SMESHGUI_EXPORT SMESHGUI_ExtrusionDlg : public QDialog
+class SMESHGUI_EXPORT SMESHGUI_ExtrusionDlg : public SMESHGUI_PreviewDlg
 {
   Q_OBJECT
 
@@ -69,15 +68,19 @@ public:
   SMESHGUI_ExtrusionDlg( SMESHGUI* );
   ~SMESHGUI_ExtrusionDlg();
 
+  void                             reject();
+
 private:
   void                             Init( bool = true );
   void                             enterEvent( QEvent* );       /* mouse enter the QWidget */
+  void                             closeEvent( QCloseEvent* );
   void                             keyPressEvent( QKeyEvent* );
   int                              GetConstructorId();
-
+  void                             getExtrusionVector(SMESH::DirStruct& aVector);
+  
   bool                             isValid();
+  bool                             isValuesValid();
   
-  SMESHGUI*                        mySMESHGUI;            /* Current SMESHGUI object */
   SMESHGUI_IdValidator*            myIdValidator;
   LightApp_SelectionMgr*           mySelectionMgr;        /* User shape selection */
   QWidget*                         myEditCurrentArgument; /* Current  argument editor */
@@ -96,10 +99,14 @@ private:
   // widgets
   QGroupBox*                       ConstructorsBox;
   QButtonGroup*                    GroupConstructors;
+  QRadioButton*                    RadioButton0;
   QRadioButton*                    RadioButton1;
   QRadioButton*                    RadioButton2;
+  QRadioButton*                    RadioButton3;
+  QRadioButton*                    RadioButton4;
 
   QGroupBox*                       GroupArguments;
+  QGroupBox*                       GroupDimensions;
   QLabel*                          TextLabelElements;
   QPushButton*                     SelectElementsButton;
   QLineEdit*                       LineEditElements;
@@ -119,6 +126,8 @@ private:
   SMESHGUI_SpinBox*                SpinBox_Vy;
   QLabel*                          TextLabelVz;
   SMESHGUI_SpinBox*                SpinBox_Vz;
+  QLabel*                          TextLabelDist;
+  SMESHGUI_SpinBox*                SpinBox_VDist;
   QLabel*                          TextLabelNbSteps;
   SalomeApp_IntSpinBox*            SpinBox_NbSteps;
   QCheckBox*                       MakeGroupsCheck;
@@ -130,8 +139,13 @@ private:
   QPushButton*                     buttonHelp;
 
   QString                          myHelpFileName;
+  QString                          myIDs;
 
+  QPushButton*                     myFilterBtn;
   SMESHGUI_FilterDlg*              myFilterDlg;
+
+protected slots:
+  virtual void              onDisplaySimulation( bool );
    
 private slots:
   void                            ConstructorsClicked( int );
@@ -140,6 +154,7 @@ private slots:
   bool                            ClickOnApply();
   void                            ClickOnCancel();
   void                            ClickOnHelp();
+  void                            ClickOnRadio();
   void                            SetEditCurrentArgument();
   void                            SelectionIntoArgument();
   void                            DeactivateActiveDialog();
index b6f6f0e48505edad93513fb2ba27ccf3841921d9..78446f12b97095e96d1b7814797747ff1518d2be 100644 (file)
@@ -1,24 +1,22 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  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 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.
 //
-//  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
 //
-//  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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_FileInfoDlg.cxx
 // Author : Alexandre SOLOVYOV, Open CASCADE S.A.S. (alexander.solovyov@opencascade.com)
index 0303acb61586158dee10b54f8d5af2c775fe64cc..dee3e0764a73ed3b60c98505d4e2a11b6298251e 100644 (file)
@@ -1,24 +1,22 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  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 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.
 //
-//  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
 //
-//  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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_FileInfoDlg.h
 // Author : Alexandre SOLOVYOV, Open CASCADE S.A.S. (alexander.solovyov@opencascade.com)
diff --git a/src/SMESHGUI/SMESHGUI_FileValidator.cxx b/src/SMESHGUI/SMESHGUI_FileValidator.cxx
new file mode 100755 (executable)
index 0000000..e56a495
--- /dev/null
@@ -0,0 +1,74 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+// SMESH SMESHGUI : GUI for SMESH component
+// File   : SMESHGUI_FileValidator.cxx
+// Author : Oleg UVAROV
+// SMESH includes
+//
+#include "SMESHGUI_FileValidator.h"
+
+// SALOME GUI includes
+#include <SUIT_MessageBox.h>
+#include <SUIT_Tools.h>
+
+// Qt includes
+#include <QFileInfo>
+
+//=======================================================================
+//function : SMESHGUI_FileValidator
+//purpose  : 
+//=======================================================================
+SMESHGUI_FileValidator::SMESHGUI_FileValidator( QWidget* parent )
+: SUIT_FileValidator( parent ),
+  myIsOverwrite( true )
+{
+}
+  
+//=======================================================================
+//function : canSave
+//purpose  : 
+//=======================================================================
+bool SMESHGUI_FileValidator::canSave( const QString& fileName, bool checkPermission ) 
+{
+  if ( QFile::exists( fileName ) ) {
+    if ( parent() ) {
+      int anAnswer = SUIT_MessageBox::question( parent(), QObject::tr( "SMESH_WRN_WARNING" ),
+                                                QObject::tr( "SMESH_FILE_EXISTS" ).arg( fileName ),
+                                                QObject::tr( "SMESH_BUT_OVERWRITE" ),
+                                                QObject::tr( "SMESH_BUT_ADD" ),
+                                                QObject::tr( "SMESH_BUT_CANCEL" ), 0, 2 );
+      if( anAnswer == 2 )
+        return false;
+      myIsOverwrite = anAnswer == 0;
+    }
+
+    // copied from SUIT_FileValidator
+    if ( checkPermission && !QFileInfo( fileName ).isWritable() ) {
+      if ( parent() ) 
+        SUIT_MessageBox::critical( parent(), QObject::tr( "SMESH_ERROR" ),
+                                   QObject::tr( "NO_PERMISSION" ).arg( fileName ) );
+      return false; 
+    }
+  }
+  else {
+    return SUIT_FileValidator::canSave( fileName, checkPermission );
+  }
+  return true;
+}
diff --git a/src/SMESHGUI/SMESHGUI_FileValidator.h b/src/SMESHGUI/SMESHGUI_FileValidator.h
new file mode 100755 (executable)
index 0000000..0f6f012
--- /dev/null
@@ -0,0 +1,46 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+// SMESH SMESHGUI : GUI for SMESH component
+// File   : SMESHGUI_FileValidator.h
+// Author : Oleg UVAROV
+//
+#ifndef SMESHGUI_FILEVALIDATOR_H
+#define SMESHGUI_FILEVALIDATOR_H
+
+// SMESH includes
+#include "SMESH_SMESHGUI.hxx"
+
+// SALOME GUI includes
+#include <SUIT_FileValidator.h>
+
+class SMESHGUI_EXPORT SMESHGUI_FileValidator : public SUIT_FileValidator
+{
+public:
+  SMESHGUI_FileValidator( QWidget* = 0 );
+  
+  virtual bool canSave( const QString&, bool = true );
+
+  bool         isOverwrite() const { return myIsOverwrite; }
+
+private:
+  bool         myIsOverwrite;
+};
+
+#endif // SMESHGUI_FILEVALIDATOR_H
index e6d12feec9ec3cfb1249e81792b2fc18777fb36c..c011b9606c4d1414ea939ac53e41ce5372f91757 100755 (executable)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESHGUI_Filter : Filters for VTK viewer
 // File   : SMESHGUI_Filter.cxx
 // Author : Sergey LITONIN, Open CASCADE S.A.S.
@@ -106,8 +107,8 @@ bool SMESHGUI_PredicateFilter::IsObjValid( const int theObjId ) const
   if ( myActor == 0 || myPred->_is_nil() )
     return false;
 
-  SMESH_Actor* anActor = ( SMESH_Actor* )myActor;
-  if ( anActor->GetObject() == 0 )
+  SMESH_Actor* anActor = dynamic_cast< SMESH_Actor* >( myActor );
+  if ( !anActor || anActor->GetObject() == 0 )
     return false;
 
   SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh();
@@ -210,8 +211,8 @@ bool SMESHGUI_QuadrangleFilter::IsValid( const int theCellId ) const
   if ( myActor == 0 )
     return false;
 
-  SMESH_Actor* anActor = ( SMESH_Actor* )myActor;
-  if ( anActor->GetObject() == 0 )
+  SMESH_Actor* anActor = dynamic_cast< SMESH_Actor* >( myActor );
+  if ( !anActor || anActor->GetObject() == 0 )
     return false;
 
   SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh();
@@ -230,8 +231,8 @@ bool SMESHGUI_QuadrangleFilter::IsObjValid( const int theObjId ) const
   if ( myActor == 0 )
     return false;
 
-  SMESH_Actor* anActor = ( SMESH_Actor* )myActor;
-  if ( anActor->GetObject() == 0 )
+  SMESH_Actor* anActor = dynamic_cast< SMESH_Actor* >( myActor );
+  if ( !anActor || anActor->GetObject() == 0 )
     return false;
 
   SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh();
@@ -289,8 +290,8 @@ bool SMESHGUI_TriangleFilter::IsValid( const int theCellId ) const
   if ( myActor == 0 )
     return false;
 
-  SMESH_Actor* anActor = ( SMESH_Actor* )myActor;
-  if ( anActor->GetObject() == 0 )
+  SMESH_Actor* anActor = dynamic_cast< SMESH_Actor* >( myActor );
+  if ( !anActor || anActor->GetObject() == 0 )
     return false;
 
   SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh();
@@ -309,8 +310,8 @@ bool SMESHGUI_TriangleFilter::IsObjValid( const int theObjId ) const
   if ( myActor == 0 )
     return false;
 
-  SMESH_Actor* anActor = ( SMESH_Actor* )myActor;
-  if ( anActor->GetObject() == 0 )
+  SMESH_Actor* anActor = dynamic_cast< SMESH_Actor* >( myActor );
+  if ( !anActor || anActor->GetObject() == 0 )
     return false;
 
   SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh();
@@ -367,8 +368,8 @@ bool SMESHGUI_FacesFilter::IsValid( const int theCellId ) const
   if ( myActor == 0 )
     return false;
 
-  SMESH_Actor* anActor = ( SMESH_Actor* )myActor;
-  if ( anActor->GetObject() == 0 )
+  SMESH_Actor* anActor = dynamic_cast< SMESH_Actor* >( myActor );
+  if ( !anActor || anActor->GetObject() == 0 )
     return false;
 
   SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh();
@@ -386,8 +387,8 @@ bool SMESHGUI_FacesFilter::IsObjValid( const int theObjId ) const
   if ( myActor == 0 )
     return false;
 
-  SMESH_Actor* anActor = ( SMESH_Actor* )myActor;
-  if ( anActor->GetObject() == 0 )
+  SMESH_Actor* anActor = dynamic_cast< SMESH_Actor* >( myActor );
+  if ( !anActor || anActor->GetObject() == 0 )
     return false;
 
   SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh();
@@ -441,11 +442,11 @@ SMESHGUI_VolumesFilter::~SMESHGUI_VolumesFilter()
 //=======================================================================
 bool SMESHGUI_VolumesFilter::IsValid( const int theCellId ) const
 {
-  if ( myActor == 0 )
+  if ( myActor == 0 || theCellId < 1 )
     return false;
 
-  SMESH_Actor* anActor = ( SMESH_Actor* )myActor;
-  if ( anActor->GetObject() == 0 )
+  SMESH_Actor* anActor = dynamic_cast< SMESH_Actor* >( myActor );
+  if ( !anActor || anActor->GetObject() == 0 )
     return false;
 
   SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh();
@@ -463,8 +464,8 @@ bool SMESHGUI_VolumesFilter::IsObjValid( const int theObjId ) const
   if ( myActor == 0 )
     return false;
 
-  SMESH_Actor* anActor = ( SMESH_Actor* )myActor;
-  if ( anActor->GetObject() == 0 )
+  SMESH_Actor* anActor = dynamic_cast< SMESH_Actor* >( myActor );
+  if ( !anActor || anActor->GetObject() == 0 )
     return false;
 
   SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh();
index 6da648be9e203aaaabca06ea32cea099ab267f0c..ed048df679d6938f03eb2a3e9c1069eac5abdea6 100755 (executable)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESHGUI_Filter : Filters for VTK viewer
 // File   : SMESHGUI_Filter.h
 // Author : Sergey LITONIN, Open CASCADE S.A.S.
index 0b55d8b711ff4b2f1b4ed8f739136bca667dea49..ac756a16c204484bcd135d8473fcb041d5b640d4 100755 (executable)
@@ -1,29 +1,31 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_FilterDlg.cxx
 // Author : Sergey LITONIN, Open CASCADE S.A.S.
-// SMESH includes
 //
+
+// SMESH includes
 #include "SMESHGUI_FilterDlg.h"
 
 #include "SMESHGUI.h"
@@ -32,6 +34,7 @@
 #include "SMESHGUI_Filter.h"
 #include "SMESHGUI_FilterUtils.h"
 #include "SMESHGUI_FilterLibraryDlg.h"
+#include "SMESHGUI_SpinBox.h"
 
 #include <SMESH_Actor.h>
 #include <SMESH_NumberFilter.hxx>
@@ -53,6 +56,8 @@
 #include <LightApp_SelectionMgr.h>
 #include <SalomeApp_Tools.h>
 #include <SalomeApp_Study.h>
+#include <SalomeApp_IntSpinBox.h>
+#include <SalomeApp_DoubleSpinBox.h>
 
 #include <SALOME_ListIO.hxx>
 #include <SALOME_ListIteratorOfListIO.hxx>
@@ -159,30 +164,32 @@ public:
   virtual void            SetString(const int, const QString&);
   void                    SetEditable(const int, const bool);
   void                    SetEditable(const bool);
+  void                    SetPrecision(const int, const char* = 0);
 
 private:
-  QMap< int, QLineEdit* > myLineEdits;
+  QMap< int, QWidget* > myWidgets;
 };
 
 SMESHGUI_FilterTable::AdditionalWidget::AdditionalWidget (QWidget* theParent)
   : QWidget(theParent)
 {
   QLabel* aLabel = new QLabel(tr("SMESH_TOLERANCE"), this);
-  myLineEdits[ Tolerance ] = new QLineEdit(this);
-  QDoubleValidator* aValidator = new QDoubleValidator(myLineEdits[ Tolerance ]);
-  aValidator->setBottom(0);
-  myLineEdits[ Tolerance ]->setValidator(aValidator);
+
+  SMESHGUI_SpinBox* sb = new SMESHGUI_SpinBox(this);
+  sb->setAcceptNames( false ); // No Notebook variables allowed
+  sb->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+  sb->RangeStepAndValidator( 0., 1.e20, 0.1, "len_tol_precision" );
+  myWidgets[ Tolerance ] = sb;
 
   QHBoxLayout* aLay = new QHBoxLayout(this);
   aLay->setSpacing(SPACING);
   aLay->setMargin(0);
 
   aLay->addWidget(aLabel);
-  aLay->addWidget(myLineEdits[ Tolerance ]);
+  aLay->addWidget(myWidgets[ Tolerance ]);
   aLay->addStretch();
 
-  QString aText = QString("%1").arg(Precision::Confusion());
-  myLineEdits[ Tolerance ]->setText(aText);
+  SetDouble( Tolerance, Precision::Confusion() );
 }
 
 SMESHGUI_FilterTable::AdditionalWidget::~AdditionalWidget()
@@ -204,13 +211,18 @@ bool SMESHGUI_FilterTable::AdditionalWidget::IsValid (const bool theMsg) const
   QList<int> aParams = GetParameters();
   QList<int>::const_iterator anIter;
   for (anIter = aParams.begin(); anIter != aParams.end(); ++anIter) {
-    const QLineEdit* aWg = myLineEdits[ *anIter ];
-    int p = 0;
-    QString aText = aWg->text();
-    if (aWg->isEnabled() && aWg->validator()->validate(aText, p) != QValidator::Acceptable) {
-      if (theMsg)
-        SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
-                                    tr("SMESHGUI_INVALID_PARAMETERS"));
+    if ( !myWidgets.contains( *anIter ) ) continue;
+    bool valid = true;
+    if ( qobject_cast<QLineEdit*>( myWidgets[ *anIter ] ) ) {
+      valid = qobject_cast<QLineEdit*>( myWidgets[ *anIter ] )->hasAcceptableInput();
+    }
+    else if ( qobject_cast<SMESHGUI_SpinBox*>( myWidgets[ *anIter ] ) ) {
+      QString foo;
+      valid = qobject_cast<SMESHGUI_SpinBox*>( myWidgets[ *anIter ] )->isValid( foo, false );
+    }
+    if (!valid && theMsg) {
+      SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
+                                   tr("SMESHGUI_INVALID_PARAMETERS"));
       return false;
     }
   }
@@ -220,41 +232,78 @@ bool SMESHGUI_FilterTable::AdditionalWidget::IsValid (const bool theMsg) const
 
 double SMESHGUI_FilterTable::AdditionalWidget::GetDouble (const int theId) const
 {
-  return myLineEdits.contains(theId) ? myLineEdits[ theId ]->text().toDouble() : 0;
+  double retval = 0;
+  if ( myWidgets.contains( theId ) ) {
+    if ( qobject_cast<QLineEdit*>( myWidgets[ theId ] ) )
+      retval = qobject_cast<QLineEdit*>( myWidgets[ theId ] )->text().toDouble();
+    if ( qobject_cast<SMESHGUI_SpinBox*>( myWidgets[ theId ] ) )
+      retval = qobject_cast<SMESHGUI_SpinBox*>( myWidgets[ theId ] )->GetValue();
+  }
+  return retval;
 }
 
 int SMESHGUI_FilterTable::AdditionalWidget::GetInteger (const int theId) const
 {
-  return myLineEdits.contains(theId) ? myLineEdits[ theId ]->text().toInt() : 0;
+  int retval = 0;
+  if ( myWidgets.contains( theId ) ) {
+    if ( qobject_cast<QLineEdit*>( myWidgets[ theId ] ) )
+      retval = qobject_cast<QLineEdit*>( myWidgets[ theId ] )->text().toInt();
+    if ( qobject_cast<SMESHGUI_SpinBox*>( myWidgets[ theId ] ) )
+      retval = (int)( qobject_cast<SMESHGUI_SpinBox*>( myWidgets[ theId ] )->GetValue() );
+  }
+  return retval;
 }
 
 QString SMESHGUI_FilterTable::AdditionalWidget::GetString (const int theId) const
 {
-  return myLineEdits.contains(theId) ? myLineEdits[ theId ]->text() : QString("");
+  QString retval = "";
+  if ( myWidgets.contains( theId ) ) {
+    if ( qobject_cast<QLineEdit*>( myWidgets[ theId ] ) )
+      retval = qobject_cast<QLineEdit*>( myWidgets[ theId ] )->text();
+    if ( qobject_cast<SMESHGUI_SpinBox*>( myWidgets[ theId ] ) )
+      retval = QString::number( qobject_cast<SMESHGUI_SpinBox*>( myWidgets[ theId ] )->GetValue() );
+  }
+  return retval;
 }
 
 void SMESHGUI_FilterTable::AdditionalWidget::SetDouble (const int theId, const double theVal)
 {
-  if (myLineEdits.contains(theId))
-    myLineEdits[ theId ]->setText(QString("%1").arg(theVal));
+  if ( myWidgets.contains( theId ) ) {
+    if ( qobject_cast<QLineEdit*>( myWidgets[ theId ] ) )
+      qobject_cast<QLineEdit*>( myWidgets[ theId ] )->setText( QString::number( theVal ) );
+    if ( qobject_cast<SMESHGUI_SpinBox*>( myWidgets[ theId ] ) )
+      qobject_cast<SMESHGUI_SpinBox*>( myWidgets[ theId ] )->SetValue( theVal );
+  }
 }
 
 void SMESHGUI_FilterTable::AdditionalWidget::SetInteger (const int theId, const int theVal)
 {
-  if (myLineEdits.contains(theId))
-    myLineEdits[ theId ]->setText(QString("%1").arg(theVal));
+  if ( myWidgets.contains( theId ) ) {
+    if ( qobject_cast<QLineEdit*>( myWidgets[ theId ] ) )
+      qobject_cast<QLineEdit*>( myWidgets[ theId ] )->setText( QString::number( theVal ) );
+    if ( qobject_cast<SMESHGUI_SpinBox*>( myWidgets[ theId ] ) )
+      qobject_cast<SMESHGUI_SpinBox*>( myWidgets[ theId ] )->SetValue( (double)theVal );
+  }
 }
 
 void SMESHGUI_FilterTable::AdditionalWidget::SetString (const int theId, const QString& theVal)
 {
-  if (myLineEdits.contains(theId))
-    myLineEdits[ theId ]->setText(theVal);
+  if ( myWidgets.contains( theId ) ) {
+    if ( qobject_cast<QLineEdit*>( myWidgets[ theId ] ) )
+      qobject_cast<QLineEdit*>( myWidgets[ theId ] )->setText( theVal );
+    if ( qobject_cast<SMESHGUI_SpinBox*>( myWidgets[ theId ] ) )
+      qobject_cast<SMESHGUI_SpinBox*>( myWidgets[ theId ] )->SetValue( theVal.toDouble() );
+  }
 }
 
 void SMESHGUI_FilterTable::AdditionalWidget::SetEditable (const int theId, const bool isEditable)
 {
-  if (myLineEdits.contains(theId))
-    myLineEdits[ theId ]->setReadOnly(!isEditable);
+  if ( myWidgets.contains( theId ) ) {
+    if ( qobject_cast<QLineEdit*>( myWidgets[ theId ] ) )
+      qobject_cast<QLineEdit*>( myWidgets[ theId ] )->setReadOnly( !isEditable );
+    if ( qobject_cast<SMESHGUI_SpinBox*>( myWidgets[ theId ] ) )
+      qobject_cast<SMESHGUI_SpinBox*>( myWidgets[ theId ] )->setReadOnly( !isEditable );
+  }
 }
 
 void SMESHGUI_FilterTable::AdditionalWidget::SetEditable (const bool isEditable)
@@ -265,6 +314,19 @@ void SMESHGUI_FilterTable::AdditionalWidget::SetEditable (const bool isEditable)
     SetEditable( *anIter,  isEditable );
 }
 
+void SMESHGUI_FilterTable::AdditionalWidget::SetPrecision(const int theId, const char* precision)
+{
+  if ( myWidgets.contains( theId ) ) {
+    if ( qobject_cast<SMESHGUI_SpinBox*>( myWidgets[ theId ] ) ) {
+      SMESHGUI_SpinBox* sb = qobject_cast<SMESHGUI_SpinBox*>( myWidgets[ theId ] );
+      double val = sb->GetValue();
+      double min = pow(10.0, -(sb->decimals()));
+      sb->RangeStepAndValidator( 0., 1.e20, 0.1, precision ? precision : "len_tol_precision" );
+      sb->SetValue( qMax( val, min ) );
+    }
+  }
+}
+
 /*
   Class       : SMESHGUI_FilterTable::ComboItem
   Description : Combo table item. Identificator corresponding to string may be assigned
@@ -411,6 +473,115 @@ bool SMESHGUI_FilterTable::CheckItem::checked() const
   return checkState() == Qt::Checked;
 }
 
+/*
+  Class       : SMESHGUI_FilterTable::IntSpinItem
+  Description : Integer spin table item.
+*/
+
+class SMESHGUI_FilterTable::IntSpinItem : public QTableWidgetItem
+{
+public:
+  static int     Type();
+
+  IntSpinItem( const int theValue );
+
+  int            value() const;
+  void           setValue( const int theValue );
+
+  void           clear();
+};
+
+int SMESHGUI_FilterTable::IntSpinItem::Type()
+{
+  return QTableWidgetItem::UserType + 3;
+}
+
+SMESHGUI_FilterTable::IntSpinItem::IntSpinItem( const int theValue )
+ : QTableWidgetItem( Type() )
+{
+  setValue( theValue );
+}
+
+int SMESHGUI_FilterTable::IntSpinItem::value() const
+{
+  bool ok = false;
+  int value = data( Qt::UserRole ).toInt( &ok );
+  return ok ? value : 0; 
+}
+
+void SMESHGUI_FilterTable::IntSpinItem::setValue( const int theValue )
+{
+  setData( Qt::UserRole, theValue );
+  setText( QString::number( theValue ) ); 
+}
+
+void SMESHGUI_FilterTable::IntSpinItem::clear()
+{
+  setText( "" );
+}
+
+/*
+  Class       : SMESHGUI_FilterTable::DoubleSpinItem
+  Description : Double spin table item.
+*/
+
+class SMESHGUI_FilterTable::DoubleSpinItem : public QTableWidgetItem
+{
+public:
+  static int     Type();
+
+  DoubleSpinItem( const double theValue );
+
+  double         value() const;
+  void           setValue( const double theValue );
+
+  int            precision() const;
+  void           setPrecision( const int thePrecision );
+
+  void           clear();
+};
+
+int SMESHGUI_FilterTable::DoubleSpinItem::Type()
+{
+  return QTableWidgetItem::UserType + 4;
+}
+
+SMESHGUI_FilterTable::DoubleSpinItem::DoubleSpinItem( const double theValue )
+ : QTableWidgetItem( Type() )
+{
+  setValue( theValue );
+}
+
+double SMESHGUI_FilterTable::DoubleSpinItem::value() const
+{
+  bool ok = false;
+  double value = data( Qt::UserRole ).toDouble( &ok );
+  return ok ? value : 0; 
+}
+
+void SMESHGUI_FilterTable::DoubleSpinItem::setValue( const double theValue )
+{
+  setData( Qt::UserRole, theValue );
+  setText( QString::number( theValue ) ); 
+}
+
+int SMESHGUI_FilterTable::DoubleSpinItem::precision() const
+{
+  bool ok = false;
+  int precision = data( Qt::UserRole + 1 ).toInt( &ok );
+  return ok ? precision : 0; 
+}
+
+void SMESHGUI_FilterTable::DoubleSpinItem::setPrecision( const int thePrecision )
+{
+  setData( Qt::UserRole + 1, thePrecision );
+}
+
+void SMESHGUI_FilterTable::DoubleSpinItem::clear()
+{
+  setText( "" );
+}
+
 /*
   Class       : SMESHGUI_FilterTable::ComboDelegate
   Description : Table used by this widget
@@ -423,13 +594,13 @@ public:
   ~ComboDelegate();
   
   QWidget*      createEditor( QWidget*, const QStyleOptionViewItem&,
-                             const QModelIndex& ) const;
+                              const QModelIndex& ) const;
   
   void          setEditorData( QWidget*, const QModelIndex& ) const;
   void          setModelData( QWidget*, QAbstractItemModel*, const QModelIndex& ) const;
   
   void          updateEditorGeometry( QWidget*, const QStyleOptionViewItem&, 
-                                     const QModelIndex& ) const;
+                                      const QModelIndex& ) const;
 private:
   QTableWidget* myTable;
 };
@@ -445,47 +616,86 @@ SMESHGUI_FilterTable::ComboDelegate::~ComboDelegate()
 }
 
 QWidget* SMESHGUI_FilterTable::ComboDelegate::createEditor( QWidget* parent,
-                                                           const QStyleOptionViewItem& option,
-                                                           const QModelIndex& index ) const
-{
-  QStringList l = index.data( Qt::UserRole ).toStringList();
-  if ( !l.isEmpty() ) {
-    QComboBox* cb = new QComboBox( parent );
-    cb->setFrame( false );
-    cb->addItems( l );
-    return cb;
+                                                            const QStyleOptionViewItem& option,
+                                                            const QModelIndex& index ) const
+{
+  QVariant aData = index.data( Qt::UserRole );
+  QVariant::Type aDataType = aData.type();
+  if( aDataType == QVariant::StringList ) {
+    QStringList l = aData.toStringList();
+    if ( !l.isEmpty() ) {
+      QComboBox* cb = new QComboBox( parent );
+      cb->setFrame( false );
+      cb->addItems( l );
+      return cb;
+    }
+  }
+  else if( aDataType == QVariant::Int ) {
+    bool ok = false;
+    int aValue = aData.toInt( &ok );
+    if ( ok ) {
+      SalomeApp_IntSpinBox* intSpin = new SalomeApp_IntSpinBox( 0, 1000, 1, parent, false, true );
+      intSpin->setFrame( false );
+      intSpin->setValue( aValue );
+      return intSpin;
+    }
+  }
+  else if( aDataType == QVariant::Double ) {
+    bool ok = false;
+    double aValue = aData.toDouble( &ok );
+    if ( ok ) {
+      int aPrecision = index.data( Qt::UserRole + 1 ).toInt( &ok );
+      if ( !ok )
+        aPrecision = 0;
+
+      SalomeApp_DoubleSpinBox* dblSpin = new SalomeApp_DoubleSpinBox( -1.e20, 1.e20, 1, aPrecision, 20, parent, false, true );
+      dblSpin->setFrame( false );
+      dblSpin->setValue( aValue );
+      return dblSpin;
+    }
   }
   return QItemDelegate::createEditor( parent, option, index );
 }
 
 void SMESHGUI_FilterTable::ComboDelegate::setEditorData( QWidget* editor, 
-                                                        const QModelIndex& index ) const
+                                                         const QModelIndex& index ) const
 {
-  QString value = index.model()->data( index, Qt::DisplayRole ).toString();
-  QComboBox* cb = dynamic_cast<QComboBox*>( editor );
+  QVariant data = index.model()->data( index, Qt::DisplayRole );
+  QString value = data.toString();
   bool bOk = false;
-  if ( cb ) {
+  if ( QComboBox* cb = dynamic_cast<QComboBox*>( editor ) ) {
     int i = cb->findText( value );
     if ( i >= 0 ) {
       cb->setCurrentIndex( i );
       bOk = true;
     }
   }
+  else if ( SalomeApp_DoubleSpinBox* dblSpin = dynamic_cast<SalomeApp_DoubleSpinBox*>( editor ) ) {
+    if( data.type() == QVariant::Double ) {
+      double valueDouble = data.toDouble( &bOk );
+      if( bOk )
+        dblSpin->setValue( valueDouble );
+    }
+  }
   if ( !bOk ) QItemDelegate::setEditorData( editor, index );
 }
 
 void SMESHGUI_FilterTable::ComboDelegate::setModelData( QWidget* editor,
-                                                       QAbstractItemModel* model,
-                                                       const QModelIndex& index) const
-{
-  QComboBox* cb = dynamic_cast<QComboBox*>( editor );
-  if ( cb ) model->setData( index, cb->currentText(), Qt::DisplayRole );
+                                                        QAbstractItemModel* model,
+                                                        const QModelIndex& index) const
+{
+  if( QComboBox* cb = dynamic_cast<QComboBox*>( editor ) )
+    model->setData( index, cb->currentText(), Qt::DisplayRole );
+  else if( SalomeApp_IntSpinBox* intSpin = dynamic_cast<SalomeApp_IntSpinBox*>( editor ) )
+    model->setData( index, intSpin->value(), Qt::DisplayRole );
+  else if( SalomeApp_DoubleSpinBox* dblSpin = dynamic_cast<SalomeApp_DoubleSpinBox*>( editor ) )
+    model->setData( index, dblSpin->value(), Qt::DisplayRole );
   else QItemDelegate::setModelData( editor, model, index );
 }
 
 void SMESHGUI_FilterTable::ComboDelegate::updateEditorGeometry( QWidget* editor,
-                                                               const QStyleOptionViewItem& option, 
-                                                               const QModelIndex& index ) const
+                                                                const QStyleOptionViewItem& option, 
+                                                                const QModelIndex& index ) const
 {
   editor->setGeometry( option.rect );
 }
@@ -597,8 +807,8 @@ bool SMESHGUI_FilterTable::Table::isEditable (int row, int col) const
 void SMESHGUI_FilterTable::Table::setReadOnly( bool on )
 {
   setEditTriggers( on ? 
-                  QAbstractItemView::NoEditTriggers  :
-                  QAbstractItemView::AllEditTriggers );
+                   QAbstractItemView::NoEditTriggers  :
+                   QAbstractItemView::AllEditTriggers );
 }
 
 bool SMESHGUI_FilterTable::Table::isReadOnly() const
@@ -909,13 +1119,16 @@ bool SMESHGUI_FilterTable::IsValid (const bool theMess, const int theEntityType)
       QtxColorButton* clrBtn = qobject_cast<QtxColorButton*>(aTable->cellWidget(i, 2));
       if (clrBtn && !clrBtn->color().isValid())
         errMsg = tr( "GROUPCOLOR_ERROR" );
-    } else if (aCriterion == SMESH::FT_RangeOfIds ||
-         aCriterion == SMESH::FT_BelongToGeom ||
-         aCriterion == SMESH::FT_BelongToPlane ||
-         aCriterion == SMESH::FT_BelongToCylinder ||
-         aCriterion == SMESH::FT_BelongToGenSurface ||
-         aCriterion == SMESH::FT_ElemGeomType ||
-         aCriterion == SMESH::FT_LyingOnGeom) {
+    }
+    else if (aCriterion == SMESH::FT_RangeOfIds ||
+             aCriterion == SMESH::FT_BelongToGeom ||
+             aCriterion == SMESH::FT_BelongToPlane ||
+             aCriterion == SMESH::FT_BelongToCylinder ||
+             aCriterion == SMESH::FT_BelongToGenSurface ||
+             aCriterion == SMESH::FT_ElemGeomType ||
+             aCriterion == SMESH::FT_CoplanarFaces ||
+             aCriterion == SMESH::FT_LyingOnGeom)
+    {
       if (aTable->text(i, 2).isEmpty())
         errMsg = tr( "ERROR" );
     }
@@ -929,8 +1142,8 @@ bool SMESHGUI_FilterTable::IsValid (const bool theMess, const int theEntityType)
       if (!aRes && aTable->isEditable(i, 2))
         errMsg = tr( "ERROR" );
       else if (aType == SMESH::EDGE &&
-                GetCriterionType(i, aType) == SMESH::FT_MultiConnection &&
-                aThreshold == 1)
+               GetCriterionType(i, aType) == SMESH::FT_MultiConnection &&
+               aThreshold == 1)
         errMsg = tr( "MULTIEDGES_ERROR" );
     }
 
@@ -1029,12 +1242,14 @@ void SMESHGUI_FilterTable::GetCriterion (const int                 theRow,
   }
   else if ( aCriterionType == SMESH::FT_ElemGeomType )
     theCriterion.Threshold = (double)((ComboItem*)aTable->item(theRow, 2))->value();
+  else if ( aCriterionType == SMESH::FT_CoplanarFaces )
+    theCriterion.ThresholdID = aTable->text(theRow, 2).toLatin1().constData();
   else if ( aCriterionType != SMESH::FT_RangeOfIds &&
             aCriterionType != SMESH::FT_BelongToGeom &&
-           aCriterionType != SMESH::FT_BelongToPlane &&
-           aCriterionType != SMESH::FT_BelongToCylinder &&
-           aCriterionType != SMESH::FT_BelongToGenSurface &&
-           aCriterionType != SMESH::FT_LyingOnGeom)
+            aCriterionType != SMESH::FT_BelongToPlane &&
+            aCriterionType != SMESH::FT_BelongToCylinder &&
+            aCriterionType != SMESH::FT_BelongToGenSurface &&
+            aCriterionType != SMESH::FT_LyingOnGeom )
   {
     theCriterion.Compare = ((ComboItem*)aTable->item(theRow, 1))->value();
     theCriterion.Threshold = aTable->item(theRow, 2)->text().toDouble();
@@ -1068,7 +1283,10 @@ void SMESHGUI_FilterTable::SetCriterion (const int                       theRow,
 
   ((ComboItem*)aTable->item(theRow, 0))->setValue(theCriterion.Type);
   onCriterionChanged(theRow, 0, aType);
-  ((ComboItem*)aTable->item(theRow, 1))->setValue(theCriterion.Compare);
+  if ( theCriterion.Compare == SMESH::FT_Undefined )
+    ((ComboItem*)aTable->item(theRow, 1))->setValue( SMESH::FT_EqualTo );
+  else
+    ((ComboItem*)aTable->item(theRow, 1))->setValue(theCriterion.Compare);
   ((CheckItem*)aTable->item(theRow, 3))->setChecked(theCriterion.UnaryOp == SMESH::FT_LogicalNOT);
 
   if (theCriterion.BinaryOp != SMESH::FT_Undefined)
@@ -1100,19 +1318,30 @@ void SMESHGUI_FilterTable::SetCriterion (const int                       theRow,
     ComboItem* typeBox = (ComboItem*)aTable->item(theRow, 2);
     typeBox->setValue( (int)(theCriterion.Threshold + 0.5) );
   }
+  else if (theCriterion.Type == SMESH::FT_CoplanarFaces )
+  {
+    aTable->item( theRow, 2 )->setText( QString( theCriterion.ThresholdID ) );
+  }
   else if (theCriterion.Type != SMESH::FT_RangeOfIds &&
-      theCriterion.Type != SMESH::FT_BelongToGeom &&
-      theCriterion.Type != SMESH::FT_BelongToPlane &&
-      theCriterion.Type != SMESH::FT_BelongToCylinder &&
-      theCriterion.Type != SMESH::FT_BelongToGenSurface &&
-      theCriterion.Type != SMESH::FT_LyingOnGeom &&
-      theCriterion.Type != SMESH::FT_FreeBorders &&
-      theCriterion.Type != SMESH::FT_FreeEdges &&
-      theCriterion.Type != SMESH::FT_FreeNodes &&
-      theCriterion.Type != SMESH::FT_FreeFaces &&
-      theCriterion.Type != SMESH::FT_BadOrientedVolume &&
-      theCriterion.Type != SMESH::FT_LinearOrQuadratic)
+           theCriterion.Type != SMESH::FT_BelongToGeom &&
+           theCriterion.Type != SMESH::FT_BelongToPlane &&
+           theCriterion.Type != SMESH::FT_BelongToCylinder &&
+           theCriterion.Type != SMESH::FT_BelongToGenSurface &&
+           theCriterion.Type != SMESH::FT_LyingOnGeom &&
+           theCriterion.Type != SMESH::FT_CoplanarFaces &&
+           theCriterion.Type != SMESH::FT_FreeBorders &&
+           theCriterion.Type != SMESH::FT_FreeEdges &&
+           theCriterion.Type != SMESH::FT_FreeNodes &&
+           theCriterion.Type != SMESH::FT_FreeFaces &&
+           theCriterion.Type != SMESH::FT_BadOrientedVolume &&
+           theCriterion.Type != SMESH::FT_BareBorderFace &&
+           theCriterion.Type != SMESH::FT_BareBorderVolume &&
+           theCriterion.Type != SMESH::FT_OverConstrainedFace &&
+           theCriterion.Type != SMESH::FT_OverConstrainedVolume &&
+           theCriterion.Type != SMESH::FT_LinearOrQuadratic)
+  {
     aTable->item( theRow, 2 )->setText(QString("%1").arg(theCriterion.Threshold, 0, 'g', 15));
+  }
   else
   {
     aTable->item( theRow, 2 )->setText(QString(theCriterion.ThresholdStr));
@@ -1121,21 +1350,25 @@ void SMESHGUI_FilterTable::SetCriterion (const int                       theRow,
   }
 
   if (theCriterion.Compare == SMESH::FT_EqualTo ||
-       theCriterion.Type    == SMESH::FT_BelongToPlane ||
-       theCriterion.Type    == SMESH::FT_BelongToCylinder ||
-       theCriterion.Type    == SMESH::FT_BelongToGenSurface)
+      theCriterion.Type    == SMESH::FT_BelongToPlane ||
+      theCriterion.Type    == SMESH::FT_BelongToCylinder ||
+      theCriterion.Type    == SMESH::FT_BelongToGenSurface ||
+      theCriterion.Type    == SMESH::FT_BelongToGeom ||
+      theCriterion.Type    == SMESH::FT_LyingOnGeom ||
+      theCriterion.Type    == SMESH::FT_CoplanarFaces ||
+      theCriterion.Type    == SMESH::FT_EqualNodes)
   {
     QTableWidgetItem* anItem = aTable->item(theRow, 0);
     if (!myAddWidgets.contains(anItem))
     {
       myAddWidgets[ anItem ] = new AdditionalWidget(myWgStack);
+      myAddWidgets[ anItem ]->SetPrecision( AdditionalWidget::Tolerance, getPrecision( theCriterion.Type ) );
       myWgStack->addWidget(myAddWidgets[ anItem ]);
     }
     myAddWidgets[ anItem ]->SetDouble(AdditionalWidget::Tolerance, theCriterion.Tolerance);
   }
 
   emit CriterionChanged(theRow, aType);
-
 }
 
 //=======================================================================
@@ -1263,14 +1496,18 @@ void SMESHGUI_FilterTable::updateAdditionalWidget()
 
   ComboItem* anItem = ((ComboItem*)aTable->item(aRow, 0));
   int aCriterion = GetCriterionType(aRow);
-  bool toEnable = ((ComboItem*)aTable->item(aRow, 1))->value() == SMESH::FT_EqualTo &&
-                  aCriterion != SMESH::FT_BelongToGeom &&
-                  aCriterion != SMESH::FT_LyingOnGeom &&
-                  aCriterion != SMESH::FT_RangeOfIds &&
-                  aCriterion != SMESH::FT_FreeEdges &&
-                  aCriterion != SMESH::FT_FreeFaces &&
-                  aCriterion != SMESH::FT_BadOrientedVolume;
-
+  bool toEnable = ((((ComboItem*)aTable->item(aRow, 1))->value() == SMESH::FT_EqualTo &&
+                   aCriterion != SMESH::FT_RangeOfIds &&
+                   aCriterion != SMESH::FT_FreeEdges &&
+                   aCriterion != SMESH::FT_FreeFaces &&
+                   aCriterion != SMESH::FT_BadOrientedVolume &&
+                   aCriterion != SMESH::FT_BareBorderFace &&
+                   aCriterion != SMESH::FT_BareBorderVolume &&
+                   aCriterion != SMESH::FT_OverConstrainedFace &&
+                   aCriterion != SMESH::FT_OverConstrainedVolume)
+                   ||
+                   aCriterion == SMESH::FT_CoplanarFaces);
+  
   if (!myAddWidgets.contains(anItem))
   {
     myAddWidgets[ anItem ] = new AdditionalWidget(myWgStack);
@@ -1278,9 +1515,45 @@ void SMESHGUI_FilterTable::updateAdditionalWidget()
   }
 
   myWgStack->setCurrentWidget(myAddWidgets[ anItem ]);
+  myAddWidgets[ anItem ]->SetPrecision( AdditionalWidget::Tolerance, getPrecision( aCriterion ) );
   myWgStack->setEnabled(toEnable);
 }
 
+const char* SMESHGUI_FilterTable::getPrecision( const int aType )
+{
+  const char* retval = 0;
+  switch ( aType ) {
+  case SMESH::FT_AspectRatio:
+  case SMESH::FT_AspectRatio3D:
+  case SMESH::FT_Taper:
+    retval = "parametric_precision"; break;
+  case SMESH::FT_Warping:
+  case SMESH::FT_MinimumAngle:
+  case SMESH::FT_Skew:
+  case SMESH::FT_CoplanarFaces:
+    retval = "angle_precision"; break;
+  case SMESH::FT_Area:
+    retval = "area_precision"; break;
+  case SMESH::FT_BelongToGeom:
+  case SMESH::FT_BelongToPlane:
+  case SMESH::FT_BelongToCylinder:
+  case SMESH::FT_BelongToGenSurface:
+  case SMESH::FT_LyingOnGeom:
+  case SMESH::FT_EqualNodes:
+    retval = "len_tol_precision"; break;
+  case SMESH::FT_Length:
+  case SMESH::FT_Length2D:
+  case SMESH::FT_MaxElementLength2D:
+  case SMESH::FT_MaxElementLength3D:
+    retval = "length_precision"; break;
+  case SMESH::FT_Volume3D:
+    retval = "vol_precision"; break;
+  default:
+    break;
+  }
+  return retval;
+}
+
 //=======================================================================
 // name    : SMESHGUI_FilterTable::removeAdditionalWidget
 // Purpose : Remove widgets containing additional parameters from widget
@@ -1353,8 +1626,17 @@ static QList<int> geomTypes( const int theType )
     typeIds.append( SMESH::Geom_PYRAMID );
     typeIds.append( SMESH::Geom_HEXA );
     typeIds.append( SMESH::Geom_PENTA );
+    typeIds.append( SMESH::Geom_HEXAGONAL_PRISM );
     typeIds.append( SMESH::Geom_POLYHEDRA );
   }
+  if ( theType == SMESH::ALL || theType == SMESH::ELEM0D )
+  {
+    typeIds.append( SMESH::Geom_POINT );
+  }
+  if ( theType == SMESH::ALL || theType == SMESH::BALL )
+  {
+    typeIds.append( SMESH::Geom_BALL );
+  }
   return typeIds;
 }
 
@@ -1370,10 +1652,56 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con
 
   int aCriterionType = GetCriterionType(row);
   QtxColorButton* clrBtn = qobject_cast<QtxColorButton*>(aTable->cellWidget(row, 2));
-  bool isComboItem = aTable->item(row, 2)->type() == ComboItem::Type();
+  int aComboType = ComboItem::Type();
+  int aIntSpinType = IntSpinItem::Type();
+  int aDoubleSpinType = DoubleSpinItem::Type();
+  QTableWidgetItem* aTableItem = aTable->item(row, 2);
+  bool isComboItem = false;
+  bool isIntSpinItem = false;
+  bool isDoubleSpinItem = false;
+  if (aTableItem) {
+    int aTableType = aTable->item(row, 2)->type();
+    isComboItem = ( aTableType == aComboType );
+    isIntSpinItem = ( aTableType == aIntSpinType );
+    isDoubleSpinItem = ( aTableType == aDoubleSpinType );
+  }
   
+  bool anIsDoubleCriterion =
+    aCriterionType == SMESH::FT_AspectRatio ||
+    aCriterionType == SMESH::FT_AspectRatio3D ||
+    aCriterionType == SMESH::FT_Taper ||
+    aCriterionType == SMESH::FT_Warping ||
+    aCriterionType == SMESH::FT_MinimumAngle ||
+    aCriterionType == SMESH::FT_Skew ||
+    aCriterionType == SMESH::FT_Area ||
+    aCriterionType == SMESH::FT_Length ||
+    aCriterionType == SMESH::FT_Length2D ||
+    aCriterionType == SMESH::FT_MaxElementLength2D ||
+    aCriterionType == SMESH::FT_MaxElementLength3D ||
+    aCriterionType == SMESH::FT_Volume3D;
+
+  int aPrecision = 0;
+  if ( anIsDoubleCriterion ) {
+    const char* aPrecisionType = getPrecision( aCriterionType );
+    SUIT_ResourceMgr* aResourceMgr = SMESH::GetResourceMgr( mySMESHGUI );
+    if( aPrecisionType && aResourceMgr )
+      aPrecision = aResourceMgr->integerValue( "SMESH", aPrecisionType, aPrecision );
+  }
+
+  // if the precision is to be changed we should remove the existing
+  // spin item and create another one with new precision
+  bool anIsPrecisionChanged = false;
+  if ( anIsDoubleCriterion && isDoubleSpinItem ) {
+    if ( DoubleSpinItem* aDoubleSpinItem = dynamic_cast<DoubleSpinItem*>( aTable->item( row, 2 ) ) ) {
+      anIsPrecisionChanged = aDoubleSpinItem->precision() != aPrecision;
+    }
+  }
+
   if ( (aCriterionType != SMESH::FT_GroupColor && clrBtn) ||
-       (aCriterionType != SMESH::FT_ElemGeomType && isComboItem) )
+       (aCriterionType != SMESH::FT_ElemGeomType && isComboItem) ||
+       (aCriterionType != SMESH::FT_MultiConnection && isIntSpinItem) ||
+       (!anIsDoubleCriterion && isDoubleSpinItem) ||
+       anIsPrecisionChanged )
   {
     bool isSignalsBlocked = aTable->signalsBlocked();
     aTable->blockSignals( true );
@@ -1382,13 +1710,16 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con
     aTable->blockSignals( isSignalsBlocked );
   }
   if ( (aCriterionType == SMESH::FT_GroupColor && !clrBtn) ||
-       (aCriterionType == SMESH::FT_ElemGeomType && !isComboItem) )
+       (aCriterionType == SMESH::FT_ElemGeomType && !isComboItem) ||
+       (aCriterionType == SMESH::FT_MultiConnection && !isIntSpinItem) ||
+       (anIsDoubleCriterion && !isDoubleSpinItem) ||
+       anIsPrecisionChanged )
   {
     bool isSignalsBlocked = aTable->signalsBlocked();
     aTable->blockSignals( true );
     if ( aCriterionType == SMESH::FT_GroupColor )
       aTable->setCellWidget( row, 2, new QtxColorButton( aTable ) );
-    else {
+    else if ( aCriterionType == SMESH::FT_ElemGeomType ) {
       QList<int> typeIds = geomTypes( aType );
       QMap<int, QString> typeNames;
       QList<int>::const_iterator anIter = typeIds.begin();
@@ -1400,17 +1731,36 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con
       ComboItem* typeBox = new ComboItem( typeNames );
       aTable->setItem( row, 2, typeBox );
     }
+    else if ( aCriterionType == SMESH::FT_MultiConnection ) {
+      IntSpinItem* intSpin = new IntSpinItem( 0 );
+      aTable->setItem( row, 2, intSpin );
+    }
+    else if ( anIsDoubleCriterion ) {
+      DoubleSpinItem* dblSpin = new DoubleSpinItem( 0 );
+      dblSpin->setPrecision( aPrecision );
+      aTable->setItem( row, 2, dblSpin );
+    }
     aTable->blockSignals( isSignalsBlocked );
   }
 
-  if (aType == SMESH::NODE && aCriterionType == SMESH::FT_FreeNodes ||
-      aType == SMESH::EDGE && aCriterionType == SMESH::FT_FreeBorders ||
-      aType == SMESH::FACE && (aCriterionType == SMESH::FT_FreeEdges ||
-                               aCriterionType == SMESH::FT_FreeFaces) ||
-      aType == SMESH::VOLUME && aCriterionType == SMESH::FT_BadOrientedVolume ||
+  if ((aType == SMESH::NODE && (aCriterionType == SMESH::FT_FreeNodes               ||
+                                aCriterionType == SMESH::FT_EqualNodes ))           ||
+      (aType == SMESH::EDGE && (aCriterionType == SMESH::FT_FreeBorders             ||
+                                aCriterionType == SMESH::FT_EqualEdges ))           ||
+      (aType == SMESH::FACE && (aCriterionType == SMESH::FT_BareBorderFace          ||
+                                aCriterionType == SMESH::FT_OverConstrainedFace     ||
+                                aCriterionType == SMESH::FT_FreeEdges               ||
+                                aCriterionType == SMESH::FT_FreeFaces               ||
+                                aCriterionType == SMESH::FT_EqualFaces))            ||
+      (aType == SMESH::VOLUME && (aCriterionType == SMESH::FT_BadOrientedVolume     ||
+                                  aCriterionType == SMESH::FT_OverConstrainedVolume ||
+                                  aCriterionType == SMESH::FT_BareBorderVolume      ||
+                                  aCriterionType == SMESH::FT_EqualVolumes ))       ||
       aCriterionType == SMESH::FT_LinearOrQuadratic ||
       aCriterionType == SMESH::FT_GroupColor ||
-      aCriterionType == SMESH::FT_ElemGeomType)
+      aCriterionType == SMESH::FT_ElemGeomType ||
+      aCriterionType == SMESH::FT_CoplanarFaces
+      )
   {
     bool isSignalsBlocked = aTable->signalsBlocked();
     aTable->blockSignals( true );
@@ -1418,8 +1768,10 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con
     if (aCompareItem->count() > 0)
       aCompareItem->clear();
     aTable->setEditable(false, row, 1);
+    aTable->item(row, 2)->setText( QString("") );
     aTable->setEditable(aCriterionType == SMESH::FT_GroupColor ||
-                        aCriterionType == SMESH::FT_ElemGeomType, row, 2);
+                        aCriterionType == SMESH::FT_ElemGeomType ||
+                        aCriterionType == SMESH::FT_CoplanarFaces, row, 2);
     aTable->blockSignals( isSignalsBlocked );
   }
   else if (aCriterionType == SMESH::FT_RangeOfIds ||
@@ -1445,19 +1797,21 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con
   }
   else
   {
-    if (aCompareItem->count() != 3)
+    if (aCompareItem && aCompareItem->count() != 3)
     {
       aCompareItem->setItems(getCompare());
     }
 
-    QString aText = aTable->text(row, 2);
-    bool isOk = false;
-    aText.toDouble(&isOk);
-    aTable->item( row, 2 )->setText(isOk ? aText : QString(""));
-    if (!aTable->isEditable(row, 1))
-      aTable->setEditable(true, row, 1);
-    if (!aTable->isEditable(row, 2))
-      aTable->setEditable(true, row, 2);
+    if (aTable->item( row, 2 )) {
+      QString aText = aTable->text(row, 2);
+      bool isOk = false;
+      aText.toDouble(&isOk);
+      aTable->item( row, 2 )->setText(isOk ? aText : QString(""));
+      if (!aTable->isEditable(row, 1))
+        aTable->setEditable(true, row, 1);
+      if (!aTable->isEditable(row, 2))
+        aTable->setEditable(true, row, 2);
+    }
   }
 
   updateAdditionalWidget();
@@ -1472,7 +1826,8 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con
 //=======================================================================
 void SMESHGUI_FilterTable::onCriterionChanged (int row, int col)
 {
-  onCriterionChanged(row, col, -1);
+  if( col == 0 )
+    onCriterionChanged(row, col, -1);
 }
 
 //=======================================================================
@@ -1615,6 +1970,7 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getSupportedTypes() const
   if (aTypes.isEmpty())
   {
     aTypes[ SMESH::NODE   ] = tr("NODES");
+    aTypes[ SMESH::BALL   ] = tr("BALLS");
     aTypes[ SMESH::EDGE   ] = tr("EDGES");
     aTypes[ SMESH::FACE   ] = tr("FACES");
     aTypes[ SMESH::VOLUME ] = tr("VOLUMES");
@@ -1643,6 +1999,7 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
       aCriteria[ SMESH::FT_LyingOnGeom        ] = tr("LYING_ON_GEOM");
       aCriteria[ SMESH::FT_FreeNodes          ] = tr("FREE_NODES");
       aCriteria[ SMESH::FT_GroupColor         ] = tr("GROUP_COLOR");
+      aCriteria[ SMESH::FT_EqualNodes         ] = tr("EQUAL_NODE");
     }
     return aCriteria;
   }
@@ -1663,6 +2020,7 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
       aCriteria[ SMESH::FT_LinearOrQuadratic  ] = tr("LINEAR");
       aCriteria[ SMESH::FT_GroupColor         ] = tr("GROUP_COLOR");
       aCriteria[ SMESH::FT_ElemGeomType       ] = tr("GEOM_TYPE");
+      aCriteria[ SMESH::FT_EqualEdges         ] = tr("EQUAL_EDGE");
     }
     return aCriteria;
   }
@@ -1677,6 +2035,7 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
       aCriteria[ SMESH::FT_Taper              ] = tr("TAPER");
       aCriteria[ SMESH::FT_Skew               ] = tr("SKEW");
       aCriteria[ SMESH::FT_Area               ] = tr("AREA");
+      aCriteria[ SMESH::FT_MaxElementLength2D ] = tr("MAX_ELEMENT_LENGTH_2D");
       aCriteria[ SMESH::FT_FreeEdges          ] = tr("FREE_EDGES");
       aCriteria[ SMESH::FT_RangeOfIds         ] = tr("RANGE_OF_IDS");
       aCriteria[ SMESH::FT_BelongToGeom       ] = tr("BELONG_TO_GEOM");
@@ -1687,9 +2046,13 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
       aCriteria[ SMESH::FT_Length2D           ] = tr("LENGTH2D");
       aCriteria[ SMESH::FT_MultiConnection2D  ] = tr("MULTI2D_BORDERS");
       aCriteria[ SMESH::FT_FreeFaces          ] = tr("FREE_FACES");
+      aCriteria[ SMESH::FT_BareBorderFace     ] = tr("BARE_BORDER_FACE");
+      aCriteria[ SMESH::FT_OverConstrainedFace] = tr("OVER_CONSTRAINED_FACE");
       aCriteria[ SMESH::FT_LinearOrQuadratic  ] = tr("LINEAR");
       aCriteria[ SMESH::FT_GroupColor         ] = tr("GROUP_COLOR");
       aCriteria[ SMESH::FT_ElemGeomType       ] = tr("GEOM_TYPE");
+      aCriteria[ SMESH::FT_CoplanarFaces      ] = tr("COPLANAR_FACES");
+      aCriteria[ SMESH::FT_EqualFaces         ] = tr("EQUAL_FACE");
     }
     return aCriteria;
   }
@@ -1698,15 +2061,48 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
     static QMap<int, QString> aCriteria;
     if (aCriteria.isEmpty())
     {
-      aCriteria[ SMESH::FT_AspectRatio3D     ] = tr("ASPECT_RATIO_3D");
-      aCriteria[ SMESH::FT_RangeOfIds        ] = tr("RANGE_OF_IDS");
-      aCriteria[ SMESH::FT_BelongToGeom      ] = tr("BELONG_TO_GEOM");
-      aCriteria[ SMESH::FT_LyingOnGeom       ] = tr("LYING_ON_GEOM");
-      aCriteria[ SMESH::FT_BadOrientedVolume ] = tr("BAD_ORIENTED_VOLUME");
-      aCriteria[ SMESH::FT_Volume3D          ] = tr("VOLUME_3D");
-      aCriteria[ SMESH::FT_LinearOrQuadratic ] = tr("LINEAR");
-      aCriteria[ SMESH::FT_GroupColor        ] = tr("GROUP_COLOR");
-      aCriteria[ SMESH::FT_ElemGeomType       ] = tr("GEOM_TYPE");
+      aCriteria[ SMESH::FT_AspectRatio3D        ] = tr("ASPECT_RATIO_3D");
+      aCriteria[ SMESH::FT_RangeOfIds           ] = tr("RANGE_OF_IDS");
+      aCriteria[ SMESH::FT_BelongToGeom         ] = tr("BELONG_TO_GEOM");
+      aCriteria[ SMESH::FT_LyingOnGeom          ] = tr("LYING_ON_GEOM");
+      aCriteria[ SMESH::FT_BadOrientedVolume    ] = tr("BAD_ORIENTED_VOLUME");
+      aCriteria[ SMESH::FT_BareBorderVolume     ] = tr("BARE_BORDER_VOLUME");
+      aCriteria[ SMESH::FT_OverConstrainedVolume] = tr("OVER_CONSTRAINED_VOLUME");
+      aCriteria[ SMESH::FT_Volume3D             ] = tr("VOLUME_3D");
+      aCriteria[ SMESH::FT_MaxElementLength3D   ] = tr("MAX_ELEMENT_LENGTH_3D");
+      aCriteria[ SMESH::FT_LinearOrQuadratic    ] = tr("LINEAR");
+      aCriteria[ SMESH::FT_GroupColor           ] = tr("GROUP_COLOR");
+      aCriteria[ SMESH::FT_ElemGeomType         ] = tr("GEOM_TYPE");
+      aCriteria[ SMESH::FT_EqualVolumes         ] = tr("EQUAL_VOLUME");
+    }
+    return aCriteria;
+  }
+  else if (theType == SMESH::ELEM0D)
+  {
+    static QMap<int, QString> aCriteria;
+    if (aCriteria.isEmpty())
+    {
+      aCriteria[ SMESH::FT_RangeOfIds         ] = tr("RANGE_OF_IDS");
+      aCriteria[ SMESH::FT_BelongToGeom       ] = tr("BELONG_TO_GEOM");
+      aCriteria[ SMESH::FT_BelongToPlane      ] = tr("BELONG_TO_PLANE");
+      aCriteria[ SMESH::FT_BelongToCylinder   ] = tr("BELONG_TO_CYLINDER");
+      aCriteria[ SMESH::FT_BelongToGenSurface ] = tr("BELONG_TO_GENSURFACE");
+      aCriteria[ SMESH::FT_GroupColor         ] = tr("GROUP_COLOR");
+    }
+    return aCriteria;
+  }
+  else if (theType == SMESH::BALL)
+  {
+    static QMap<int, QString> aCriteria;
+    if (aCriteria.isEmpty())
+    {
+      aCriteria[ SMESH::FT_BallDiameter       ] = tr("BALL_DIAMETER");
+      aCriteria[ SMESH::FT_RangeOfIds         ] = tr("RANGE_OF_IDS");
+      aCriteria[ SMESH::FT_BelongToGeom       ] = tr("BELONG_TO_GEOM");
+      aCriteria[ SMESH::FT_BelongToPlane      ] = tr("BELONG_TO_PLANE");
+      aCriteria[ SMESH::FT_BelongToCylinder   ] = tr("BELONG_TO_CYLINDER");
+      aCriteria[ SMESH::FT_BelongToGenSurface ] = tr("BELONG_TO_GENSURFACE");
+      aCriteria[ SMESH::FT_GroupColor         ] = tr("GROUP_COLOR");
     }
     return aCriteria;
   }
@@ -1773,7 +2169,7 @@ SMESHGUI_FilterTable::Table* SMESHGUI_FilterTable::createTable (QWidget*  thePar
   }
 
   static int aLenCr = qAbs( aMaxLenCr -
-                           aMetrics.width(tr("CRITERION"))) / aMetrics.width(' ') + 5;
+                            aMetrics.width(tr("CRITERION"))) / aMetrics.width(' ') + 5;
 
   QString aCrStr;
   aCrStr.fill(' ', aLenCr);
@@ -1803,10 +2199,10 @@ SMESHGUI_FilterTable::Table* SMESHGUI_FilterTable::createTable (QWidget*  thePar
   aTable->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding));
 
   connect(aTable, SIGNAL(cellChanged(int, int)),
-         this,   SLOT(onCriterionChanged(int, int)));
+          this,   SLOT(onCriterionChanged(int, int)));
 
   connect(aTable, SIGNAL(currentCellChanged(int, int, int, int)),
-         this,   SLOT(onCurrentChanged(int, int)));
+          this,   SLOT(onCurrentChanged(int, int)));
   
   return aTable;
 }
@@ -1836,15 +2232,15 @@ void SMESHGUI_FilterTable::SetEditable (const bool isEditable)
     Table* aTable = anIter.value();
     for (int i = 0, n = aTable->rowCount(); i < n; i++)
       for (int j = 0, m = aTable->columnCount(); j < m; j++)
-       {
-         QTableWidgetItem* anItem = aTable->item(i, j);
-         if ( dynamic_cast<SMESHGUI_FilterTable::CheckItem*>( anItem ) ) {
-           Qt::ItemFlags f = anItem->flags();
-           if (!isEditable) f = f & ~Qt::ItemIsUserCheckable;
-           else f = f | Qt::ItemIsUserCheckable;
-           anItem->setFlags( f );
-         }
-       }
+        {
+          QTableWidgetItem* anItem = aTable->item(i, j);
+          if ( dynamic_cast<SMESHGUI_FilterTable::CheckItem*>( anItem ) ) {
+            Qt::ItemFlags f = anItem->flags();
+            if (!isEditable) f = f & ~Qt::ItemIsUserCheckable;
+            else f = f | Qt::ItemIsUserCheckable;
+            anItem->setFlags( f );
+          }
+        }
     //end of IPAL19974
 
     if (isEditable)
@@ -2017,8 +2413,8 @@ bool SMESHGUI_FilterTable::GetThreshold (const int      theRow,
 // Purpose : Set text and internal value in cell of ID value 
 //=======================================================================
 void SMESHGUI_FilterTable::SetID( const int      theRow,
-                                         const QString& theText,
-                                         const int      theEntityType )
+                                  const QString& theText,
+                                  const int      theEntityType )
 {
   Table* aTable = myTables[ theEntityType == -1 ? GetType() : theEntityType ];
   aTable->item( theRow, 5 )->setText( theText );
@@ -2029,8 +2425,8 @@ void SMESHGUI_FilterTable::SetID( const int      theRow,
 // Purpose : Get text and internal value from cell of ID value
 //=======================================================================
 bool SMESHGUI_FilterTable::GetID( const int      theRow,
-                                 QString&       theText,
-                                 const int      theEntityType )
+                                  QString&       theText,
+                                  const int      theEntityType )
 {
   Table* aTable = myTables[ theEntityType == -1 ? GetType() : theEntityType ];
   QTableWidgetItem* anItem = aTable->item( theRow, 5 );
@@ -2057,7 +2453,8 @@ SMESHGUI_FilterDlg::SMESHGUI_FilterDlg( SMESHGUI*         theModule,
                                         const QList<int>& theTypes )
 : QDialog( SMESH::GetDesktop( theModule ) ),
   mySMESHGUI( theModule ),
-  mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
+  mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
+  myInitSourceWgOnApply( true )
 {
   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
     mySelector = aViewWindow->GetSelector();
@@ -2073,7 +2470,8 @@ SMESHGUI_FilterDlg::SMESHGUI_FilterDlg( SMESHGUI*   theModule,
                                         const int   theType )
 : QDialog( SMESH::GetDesktop( theModule ) ),
   mySMESHGUI( theModule ),
-  mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
+  mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
+  myInitSourceWgOnApply( true )
 {
   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
     mySelector = aViewWindow->GetSelector();
@@ -2180,7 +2578,7 @@ QWidget* SMESHGUI_FilterDlg::createSourceGroup (QWidget* theParent)
   mySourceGrp->addButton(aSelBtn,  Selection);
   mySourceGrp->addButton(aDlgBtn,  Dialog);
 
-  aSelBtn->setChecked(true);
+  aMeshBtn->setChecked(true);
 
   return aBox;
 }
@@ -2191,19 +2589,15 @@ QWidget* SMESHGUI_FilterDlg::createSourceGroup (QWidget* theParent)
 //=======================================================================
 void SMESHGUI_FilterDlg::updateMainButtons()
 {
+  myButtons[ BTN_Close  ]->show();
   if (myTypes.count() == 1)
   {
-    myButtons[ BTN_Cancel ]->show();
     myButtons[ BTN_Apply  ]->hide();
-    myButtons[ BTN_Close  ]->hide();
   }
   else
   {
-    myButtons[ BTN_Cancel ]->hide();
     myButtons[ BTN_Apply  ]->show();
-    myButtons[ BTN_Close  ]->show();
   }
-
 //  updateGeometry();
 }
 
@@ -2220,7 +2614,6 @@ QWidget* SMESHGUI_FilterDlg::createButtonFrame (QWidget* theParent)
 
   myButtons[ BTN_OK     ] = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), aGrp);
   myButtons[ BTN_Apply  ] = new QPushButton(tr("SMESH_BUT_APPLY"),           aGrp);
-  myButtons[ BTN_Cancel ] = new QPushButton(tr("SMESH_BUT_CANCEL"),          aGrp);
   myButtons[ BTN_Close  ] = new QPushButton(tr("SMESH_BUT_CLOSE"),           aGrp);
   myButtons[ BTN_Help   ] = new QPushButton(tr("SMESH_BUT_HELP"),            aGrp);
 
@@ -2229,12 +2622,10 @@ QWidget* SMESHGUI_FilterDlg::createButtonFrame (QWidget* theParent)
   aLay->addWidget(myButtons[ BTN_Apply  ]);
   aLay->addSpacing(10);
   aLay->addStretch();
-  aLay->addWidget(myButtons[ BTN_Cancel ]);
   aLay->addWidget(myButtons[ BTN_Close  ]);
   aLay->addWidget(myButtons[ BTN_Help   ]);
 
   connect(myButtons[ BTN_OK     ], SIGNAL(clicked()), SLOT(onOk()));
-  connect(myButtons[ BTN_Cancel ], SIGNAL(clicked()), SLOT(onClose()));
   connect(myButtons[ BTN_Close  ], SIGNAL(clicked()), SLOT(onClose()));
   connect(myButtons[ BTN_Apply  ], SIGNAL(clicked()), SLOT(onApply()));
   connect(myButtons[ BTN_Help   ], SIGNAL(clicked()), SLOT(onHelp()));
@@ -2325,8 +2716,8 @@ void SMESHGUI_FilterDlg::Init (const QList<int>& theTypes)
     mySetInViewer->setChecked(true);
 
   mySourceGrp->button(myApplyToState.contains(theTypes.first()) ? 
-                     myApplyToState[ theTypes.first() ] :
-                     Selection)->setChecked(true);
+                      myApplyToState[ theTypes.first() ] :
+                      Mesh)->setChecked(true);
 }
 
 //=======================================================================
@@ -2400,10 +2791,10 @@ void SMESHGUI_FilterDlg::onHelp()
     platform = "application";
 #endif
     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser", 
-                                                                platform)).
-                            arg(myHelpFileName));
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser", 
+                                                                 platform)).
+                             arg(myHelpFileName));
   }
 }
 
@@ -2506,31 +2897,18 @@ void SMESHGUI_FilterDlg::setIdsToWg (QWidget* theWg, const QList<int>& theIds)
   if (theWg == 0)
     return;
 
+  QStringList aStrList;
+  foreach(int id, theIds)
+    aStrList << QString::number(id);
+
   if (theWg->inherits("QListWidget"))
   {
-    QListWidget* aListBox = qobject_cast<QListWidget*>( theWg );
-    aListBox->clear();
-
-    QStringList aStrList;
-    QList<int>::const_iterator anIter;
-    for (anIter = theIds.begin(); anIter != theIds.end(); ++anIter)
-      aStrList.append(QString("%1").arg(*anIter));
-
-    aListBox->addItems(aStrList);
+    qobject_cast<QListWidget*>(theWg)->clear();
+    qobject_cast<QListWidget*>(theWg)->addItems(aStrList);
   }
   else if (theWg->inherits("QLineEdit"))
   {
-    QLineEdit* aLineEdit = qobject_cast<QLineEdit*>( theWg );
-    QString aStr;
-    QList<int>::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);
+    qobject_cast<QLineEdit*>( theWg )->setText(aStrList.join(" "));
   }
 }
 
@@ -2550,7 +2928,8 @@ bool SMESHGUI_FilterDlg::isValid() const
         aType == SMESH::FT_BelongToPlane ||
         aType == SMESH::FT_BelongToCylinder ||
         aType == SMESH::FT_BelongToGenSurface ||
-        aType == SMESH::FT_LyingOnGeom) {
+        aType == SMESH::FT_LyingOnGeom)
+    {
       QString aName;
       myTable->GetThreshold(i, aName);
 
@@ -2558,7 +2937,7 @@ bool SMESHGUI_FilterDlg::isValid() const
         SMESH::GetActiveStudyDocument()->FindObjectByName(aName.toLatin1().constData(), "GEOM");
       if (aList.size() == 0) {
         SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
-                                    tr("BAD_SHAPE_NAME").arg(aName));
+                                     tr("BAD_SHAPE_NAME").arg(aName));
         return false;
       }
 
@@ -2574,31 +2953,54 @@ bool SMESHGUI_FilterDlg::isValid() const
                aFace.IsNull() ||
                aFace.ShapeType() != TopAbs_FACE) {
             SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
-                                        tr("SHAPE_IS_NOT_A_FACE").arg(aName));
+                                         tr("SHAPE_IS_NOT_A_FACE").arg(aName));
             return false;
           }
 
           Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(aFace));
           if (aSurf.IsNull()) {
             SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
-                                        tr("SHAPE_IS_NOT_A_FACE").arg(aName));
+                                         tr("SHAPE_IS_NOT_A_FACE").arg(aName));
             return false;
           }
 
           if (aType == SMESH::FT_BelongToPlane && !aSurf->IsKind(STANDARD_TYPE(Geom_Plane))) {
             SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
-                                        tr("SHAPE_IS_NOT_A_PLANE").arg(aName));
+                                         tr("SHAPE_IS_NOT_A_PLANE").arg(aName));
             return false;
           }
 
           if (aType == SMESH::FT_BelongToCylinder && !aSurf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
             SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
-                                        tr("SHAPE_IS_NOT_A_CYLINDER").arg(aName));
+                                         tr("SHAPE_IS_NOT_A_CYLINDER").arg(aName));
             return false;
           }
         }
       }
     }
+    else if (aType == SMESH::FT_CoplanarFaces)
+    {
+      QString faceID;
+      myTable->GetThreshold(i, faceID);
+      if ( faceID.isEmpty() )
+      {
+        SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
+                                     tr("FACE_ID_NOT_SELECTED"));
+        return false;
+      }
+      if ( myMesh->_is_nil() )
+      {
+        SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
+                                     tr("MESH_IS_NOT_SELECTED"));
+        return false;
+      }
+      if ( myMesh->GetElementType( faceID.toLong(), /*iselem=*/true) != SMESH::FACE )
+      {
+        SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
+                                     tr("NOT_FACE_ID").arg(faceID));
+        return false;
+      }
+    }
   }
 
   return true;
@@ -2609,18 +3011,24 @@ bool SMESHGUI_FilterDlg::isValid() const
 // Purpose : Set widget of parent dialog containing idsto be filtered if
 //           user select corresponding source radio button
 //=======================================================================
-void SMESHGUI_FilterDlg::SetSourceWg (QWidget* theWg)
+void SMESHGUI_FilterDlg::SetSourceWg (QWidget* theWg,
+                                      const bool initOnApply)
 {
   mySourceWg = theWg;
+  myInitSourceWgOnApply = initOnApply;
 }
 
 //=======================================================================
-// name    : SMESHGUI_FilterDlg::SetGroupIds
+// name    : SMESHGUI_FilterDlg::SetMesh
 // Purpose : Set mesh
 //=======================================================================
 void SMESHGUI_FilterDlg::SetMesh (SMESH::SMESH_Mesh_var theMesh)
 {
-  myMesh = theMesh;
+  if ( !theMesh->_is_nil() ) {
+    myMesh = theMesh;
+    if ( !myFilter[ myTable->GetType() ]->_is_nil())
+      myFilter[ myTable->GetType() ]->SetMesh( theMesh );
+  }
   const bool isEnable = !(myMesh->_is_nil());
   myButtons[BTN_OK]->setEnabled(isEnable);
   myButtons[BTN_Apply]->setEnabled(isEnable);
@@ -2637,7 +3045,7 @@ void SMESHGUI_FilterDlg::SetSelection()
 
   if (mySelectionMgr) {
     myIObjects.Clear();
-    const SALOME_ListIO& anObjs = mySelector->StoredIObjects();
+    const SALOME_ListIO& anObjs = mySelector->StoredIObjects(); 
     SALOME_ListIteratorOfListIO anIter (anObjs);
     for ( ; anIter.More(); anIter.Next()) {
       TColStd_IndexedMapOfInteger aMap;
@@ -2674,9 +3082,11 @@ bool SMESHGUI_FilterDlg::onApply()
     if (!myFilter[ aCurrType ]->GetPredicate()->_is_nil()) {
       QList<int> aResultIds;
       filterSource(aCurrType, aResultIds);
+      // select in viewer
       selectInViewer(aCurrType, aResultIds);
     }
 
+
     myInsertState[ aCurrType ] = mySetInViewer->isChecked();
     myApplyToState[ aCurrType ] = mySourceGrp->checkedId();
   }
@@ -2725,6 +3135,36 @@ bool SMESHGUI_FilterDlg::createFilter (const int theType)
   return true;
 }
 
+//================================================================================
+/*!
+ * \brief Return the current filter
+ */
+//================================================================================
+
+SMESH::Filter_var SMESHGUI_FilterDlg::GetFilter() const
+{
+  SMESH::Filter_var filter;
+  try {
+    int aCurrType = myTable->GetType();
+    filter = myFilter[ aCurrType ];
+  }
+  catch(...)
+  {
+  }
+  return filter._retn();
+}
+
+//================================================================================
+/*!
+ * \brief Sets a filter to the table
+ */
+//================================================================================
+
+void SMESHGUI_FilterDlg::SetFilter(SMESH::Filter_var filter, int type)
+{
+  myFilter[ type ] = filter;
+}
+
 //=======================================================================
 // name    : SMESHGUI_FilterDlg::insertFilterInViewer
 // Purpose : Insert filter in viewer
@@ -2787,15 +3227,15 @@ void SMESHGUI_FilterDlg::filterSource (const int theType,
 
     // filter ids
     SMESH::Predicate_ptr aPred = myFilter[ theType ]->GetPredicate();
-    aPred->SetMesh(myMesh);
+    myFilter[ theType ]->SetMesh(myMesh);
     QList<int>::const_iterator anIter;
     for (anIter = aDialogIds.begin(); anIter != aDialogIds.end(); ++ anIter)
       if (aPred->IsSatisfy(*anIter))
         theResIds.append(*anIter);
-
-    // set ids to the dialog
-    setIdsToWg(mySourceWg, theResIds);
   }
+  // set ids to the dialog
+  if (myInitSourceWgOnApply || aSourceId == Dialog)
+    setIdsToWg(mySourceWg, theResIds);
 }
 
 //=======================================================================
@@ -2860,7 +3300,7 @@ void SMESHGUI_FilterDlg::filterSelectionSource (const int theType,
 
   // Filter entities
   SMESH::Predicate_ptr aPred = myFilter[ theType ]->GetPredicate();
-  aPred->SetMesh(myMesh);
+  myFilter[ theType ]->SetMesh(myMesh);
   TColStd_MapIteratorOfMapOfInteger aResIter(aToBeFiltered);
   for ( ; aResIter.More(); aResIter.Next())
     if (aPred->IsSatisfy(aResIter.Key()))
@@ -2966,24 +3406,33 @@ void SMESHGUI_FilterDlg::onSelectionDone()
     }
   }
 
-  int aCriterionType = myTable->GetCriterionType(aRow);
-  if (aList.Extent() != 1 ||
-      !myTable->CurrentCell(aRow, aCol) ||
-      aCriterionType != SMESH::FT_BelongToGeom &&
-      aCriterionType != SMESH::FT_BelongToPlane &&
-      aCriterionType != SMESH::FT_BelongToCylinder &&
-      aCriterionType != SMESH::FT_BelongToGenSurface &&
-      aCriterionType != SMESH::FT_LyingOnGeom)
+  QList<int> types; 
+  types << SMESH::FT_BelongToGeom     << SMESH::FT_BelongToPlane 
+        << SMESH::FT_BelongToCylinder << SMESH::FT_BelongToGenSurface
+        << SMESH::FT_LyingOnGeom      << SMESH::FT_CoplanarFaces;
+  if (aList.Extent() != 1 || !myTable->CurrentCell(aRow, aCol) || 
+      !types.contains(myTable->GetCriterionType(aRow)))
     return;
 
-  Handle(SALOME_InteractiveObject) anIO = aList.First();
-  GEOM::GEOM_Object_var anObj = SMESH::IObjectToInterface<GEOM::GEOM_Object>(anIO);
-  if (!anObj->_is_nil())
+  if ( myTable->GetCriterionType(aRow) == SMESH::FT_CoplanarFaces )
+  {
+    QString aString;
+    int nbElems = SMESH::GetNameOfSelectedElements(mySelector,//myViewWindow->GetSelector(),
+                                                   aList.First(), aString);
+    if (nbElems == 1)
+      myTable->SetThreshold(aRow, aString);
+  }
+  else
+  {
+    Handle(SALOME_InteractiveObject) anIO = aList.First();
+    GEOM::GEOM_Object_var anObj = SMESH::IObjectToInterface<GEOM::GEOM_Object>(anIO);
+    if (!anObj->_is_nil())
     {
       myTable->SetThreshold(aRow, GEOMBase::GetName(anObj));
       //myTable->SetID( aRow, GEOMBase::GetIORFromObject(anObj));
       myTable->SetID(aRow, anIO->getEntry());
     }
+  }
 }
 
 
@@ -3014,9 +3463,9 @@ void SMESHGUI_FilterDlg::updateSelection()
   if (mySelectionMgr == 0)
     return;
 
-  TColStd_MapOfInteger allTypes;
-  for( int i=0; i<10; i++ )
-    allTypes.Add( i );
+//   TColStd_MapOfInteger allTypes;
+//   for( int i=0; i<10; i++ )
+//     allTypes.Add( i );
   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( mySMESHGUI->application()->activeStudy() );
   if( !aStudy )
     return;
@@ -3025,15 +3474,16 @@ void SMESHGUI_FilterDlg::updateSelection()
   mySelectionMgr->clearFilters();
 
   int aRow, aCol;
-
+  
+  bool isCurrentCell = myTable->CurrentCell(aRow, aCol);
   int aCriterionType = myTable->GetCriterionType(aRow);
-  if (myTable->CurrentCell(aRow, aCol) &&
+  if ( isCurrentCell &&
       (aCriterionType == SMESH::FT_BelongToGeom ||
        aCriterionType == SMESH::FT_BelongToPlane ||
        aCriterionType == SMESH::FT_BelongToCylinder ||
        aCriterionType == SMESH::FT_BelongToGenSurface ||
-       aCriterionType == SMESH::FT_LyingOnGeom)) {
-
+       aCriterionType == SMESH::FT_LyingOnGeom))
+  {
     if (aCriterionType == SMESH::FT_BelongToGeom ||
         aCriterionType == SMESH::FT_BelongToGenSurface ||
         aCriterionType == SMESH::FT_LyingOnGeom) {
@@ -3048,9 +3498,12 @@ void SMESHGUI_FilterDlg::updateSelection()
     }
     myIsSelectionChanged = true;
 
-  } else {
+  }
+  else
+  {
     if (myIsSelectionChanged) {
-      mySelectionMgr->installFilter( new GEOM_TypeFilter( aStudy, -1 ) ); // This filter deactivates selection
+      // mySelectionMgr->installFilter( new GEOM_TypeFilter( aStudy, -1 ) ); // This filter deactivates selection
+      // Impossible to select any object in the OB on the second opening of FilterDlg
     }
   }
 }
index ed1c95e9d921d3eb9f90632c1c29f9f8c5eb487b..ace63067b59751f912c7beeff57716d469e2ac38 100755 (executable)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_FilterDlg.h
 // Author : Sergey LITONIN, Open CASCADE S.A.S.
@@ -71,6 +72,8 @@ class SMESHGUI_EXPORT SMESHGUI_FilterTable : public QWidget
 
   class Table;
   class ComboItem;
+  class IntSpinItem;
+  class DoubleSpinItem;
   class CheckItem;
   class AdditionalWidget;
   class ComboDelegate;
@@ -123,12 +126,12 @@ public:
                                           const int = -1 );
 
   void                      SetID( const int,
-                                  const QString&,
-                                  const int = -1 ); 
+                                   const QString&,
+                                   const int = -1 ); 
   
   bool                      GetID( const int,
-                                  QString&,
-                                  const int = -1 );
+                                   QString&,
+                                   const int = -1 );
 
   void                      Update();
 
@@ -167,6 +170,7 @@ private:
   void                      updateBtnState();
   void                      removeAdditionalWidget( QTableWidget*, const int );
   void                      updateAdditionalWidget();
+  const char*               getPrecision( const int );
 
   const QMap<int, QString>& getSupportedTypes() const;
 
@@ -211,7 +215,7 @@ class SMESHGUI_FilterDlg : public QDialog
   enum { Mesh, Selection, Dialog, None };
 
   // Buttons
-  enum { BTN_OK, BTN_Cancel, BTN_Apply, BTN_Close, BTN_Help };
+  enum { BTN_OK, BTN_Apply, BTN_Close, BTN_Help };
 
 public:
   SMESHGUI_FilterDlg( SMESHGUI*, const QList<int>& );
@@ -223,10 +227,13 @@ public:
 
   void                      SetSelection();
   void                      SetMesh (SMESH::SMESH_Mesh_var);
-  void                      SetSourceWg( QWidget* );
+  void                      SetSourceWg( QWidget*, const bool initOnApply = true );
 
   static SMESH::Filter::Criterion createCriterion();
 
+  SMESH::Filter_var         GetFilter() const;
+  void                      SetFilter(SMESH::Filter_var filter, int type);
+
 signals:
 
   void                      Accepted();
@@ -285,6 +292,7 @@ private:
   LightApp_SelectionMgr*    mySelectionMgr;
   SVTK_Selector*            mySelector;
   SMESH::SMESH_Mesh_var     myMesh;
+  bool                      myInitSourceWgOnApply;
   QWidget*                  mySourceWg;
 
   SALOME_DataMapOfIOMapOfInteger myIObjects;
index 47c9e912cbe88bbf68f6cbd98438b73ae2d7c450..c17dde1fa69a7b6b4bbfa2563b0651d8af7a95fe 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_FilterLibraryDlg.cxx
 // Author : Sergey LITONIN, Open CASCADE S.A.S.
@@ -226,7 +227,7 @@ QWidget* SMESHGUI_FilterLibraryDlg::createMainFrame (QWidget* theParent)
   connect(myOpenBtn, SIGNAL(clicked()), this, SLOT(onBrowse()));
 
   connect(myListBox, SIGNAL(itemSelectionChanged()),
-         this, SLOT(onFilterChanged()));
+          this, SLOT(onFilterChanged()));
 
   connect(myAddBtn, SIGNAL(clicked()), this, SLOT(onAddBtnPressed()));
   connect(myDeleteBtn, SIGNAL(clicked()), this, SLOT(onDeleteBtnPressed()));
@@ -256,7 +257,6 @@ QWidget* SMESHGUI_FilterLibraryDlg::createButtonFrame (QWidget* theParent)
   myButtons[ BTN_OK    ] = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), aGrp);
   myButtons[ BTN_Apply ] = new QPushButton(tr("SMESH_BUT_APPLY"), aGrp);
 
-  myButtons[ BTN_Cancel ] = new QPushButton(tr("SMESH_BUT_CANCEL"), aGrp);
   myButtons[ BTN_Close  ] = new QPushButton(tr("SMESH_BUT_CLOSE"),  aGrp);
   myButtons[ BTN_Help   ] = new QPushButton(tr("SMESH_BUT_HELP"),   aGrp);
 
@@ -265,12 +265,10 @@ QWidget* SMESHGUI_FilterLibraryDlg::createButtonFrame (QWidget* theParent)
   aLay->addWidget(myButtons[ BTN_Apply  ]);
   aLay->addSpacing(10);
   aLay->addStretch();
-  aLay->addWidget(myButtons[ BTN_Cancel ]);
   aLay->addWidget(myButtons[ BTN_Close  ]);
   aLay->addWidget(myButtons[ BTN_Help   ]);
 
   connect(myButtons[ BTN_OK     ], SIGNAL(clicked()), SLOT(onOk()));
-  connect(myButtons[ BTN_Cancel ], SIGNAL(clicked()), SLOT(onClose()));
   connect(myButtons[ BTN_Close  ], SIGNAL(clicked()), SLOT(onClose()));
   connect(myButtons[ BTN_Apply  ], SIGNAL(clicked()), SLOT(onApply()));
   connect(myButtons[ BTN_Help   ], SIGNAL(clicked()), SLOT(onHelp()));
@@ -290,14 +288,11 @@ QWidget* SMESHGUI_FilterLibraryDlg::createButtonFrame (QWidget* theParent)
 //=======================================================================
 void SMESHGUI_FilterLibraryDlg::updateMainButtons()
 {
+  myButtons[ BTN_Close  ]->show();
   if (myTypes.count() == 1) {
-    myButtons[ BTN_Cancel ]->show();
     myButtons[ BTN_Apply  ]->hide();
-    myButtons[ BTN_Close  ]->hide();
   } else {
-    myButtons[ BTN_Cancel ]->hide();
     myButtons[ BTN_Apply  ]->show();
-    myButtons[ BTN_Close  ]->show();
   }
 }
 
@@ -423,7 +418,7 @@ bool SMESHGUI_FilterLibraryDlg::onApply()
 
   if (myLibrary->_is_nil()) {
     SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_WRN_WARNING"),
-                                tr("LIBRARY_IS_NOT_LOADED"));
+                                 tr("LIBRARY_IS_NOT_LOADED"));
     return false;
   }
 
@@ -437,11 +432,11 @@ bool SMESHGUI_FilterLibraryDlg::onApply()
   } else if (myMode == EDIT || myMode == ADD_TO) {
     SMESH::Filter_var aFilter = createFilter();
     if (!myListBox->selectedItems().empty() && 
-       !myLibrary->Replace(myCurrFilterName.toLatin1().constData(),
-                           myName->text().toLatin1().constData(),
-                           aFilter.in())) {
+        !myLibrary->Replace(myCurrFilterName.toLatin1().constData(),
+                            myName->text().toLatin1().constData(),
+                            aFilter.in())) {
       SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_ERROR"),
-                                  tr("ERROR_OF_EDITING"));
+                                   tr("ERROR_OF_EDITING"));
       aResult = false;
     }
     else
@@ -457,7 +452,7 @@ bool SMESHGUI_FilterLibraryDlg::onApply()
     delete aFileName;
   } else if (myMode != COPY_FROM) {
     SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_ERROR"),
-                                tr("ERROR_OF_SAVING"));
+                                 tr("ERROR_OF_SAVING"));
   } else {
   }
 
@@ -507,10 +502,10 @@ void SMESHGUI_FilterLibraryDlg::onHelp()
     platform = "application";
 #endif
     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser", 
-                                                                platform)).
-                            arg(myHelpFileName));
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser", 
+                                                                 platform)).
+                             arg(myHelpFileName));
   }
 }
 
@@ -674,7 +669,7 @@ void SMESHGUI_FilterLibraryDlg::processNewLibrary()
   if (myLibrary->_is_nil()) {
     if (myMode == COPY_FROM) {
       SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_ERROR"),
-                                  tr("ERROR_LOAD"));
+                                   tr("ERROR_LOAD"));
       return;
     } else {
       myLibrary = aFilterMgr->CreateLibrary();
@@ -730,7 +725,7 @@ bool SMESHGUI_FilterLibraryDlg::isNameValid(const bool theMess) const
     if (aCurrName.isEmpty()) {
       if (theMess)
         SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
-                                    tr("EMPTY_FILTER_NAME"));
+                                     tr("EMPTY_FILTER_NAME"));
       return false;
     }
 
@@ -739,7 +734,7 @@ bool SMESHGUI_FilterLibraryDlg::isNameValid(const bool theMess) const
       if (aNames[ f ] == aCurrName && aNames[ f ] != myCurrFilterName) {
         if (theMess)
           SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
-                                      tr("ERROR_FILTER_NAME"));
+                                       tr("ERROR_FILTER_NAME"));
         return false;
       }
     }
@@ -787,7 +782,7 @@ bool SMESHGUI_FilterLibraryDlg::isPermissionValid(const bool theIsExistingOnly)
 
   if (!isWritable) {
     SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_WRN_WARNING"),
-                                tr("NO_PERMISSION"));
+                                 tr("NO_PERMISSION"));
     return false;
   }
 
@@ -831,8 +826,8 @@ void SMESHGUI_FilterLibraryDlg::onFilterChanged()
 
     SMESH::Filter_var aFilter = createFilter();
     myLibrary->Replace(myCurrFilterName.toLatin1().constData(), 
-                      myName->text().toLatin1().constData(), 
-                      aFilter);
+                       myName->text().toLatin1().constData(), 
+                       aFilter);
   }
 
   // Fill table with filter parameters
@@ -938,8 +933,8 @@ void SMESHGUI_FilterLibraryDlg::onAddBtnPressed()
 
     SMESH::Filter_var aFilter = createFilter();
     myLibrary->Replace(myCurrFilterName.toLatin1().constData(), 
-                      myName->text().toLatin1().constData(), 
-                      aFilter);
+                       myName->text().toLatin1().constData(), 
+                       aFilter);
   }
   myTable->Clear(myTable->GetType());
 
@@ -955,7 +950,7 @@ void SMESHGUI_FilterLibraryDlg::addFilterToLib (const QString& theName)
 {
   if (myLibrary->_is_nil()) {
     SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_WRN_WARNING"),
-                                tr("LIBRARY_IS_NOT_LOADED"));
+                                 tr("LIBRARY_IS_NOT_LOADED"));
     return;
   }
 
@@ -979,7 +974,7 @@ void SMESHGUI_FilterLibraryDlg::addFilterToLib (const QString& theName)
 
   if (!aResult) {
     SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_ERROR"),
-                                tr("ERROR_OF_ADDING"));
+                                 tr("ERROR_OF_ADDING"));
   }
 
   updateList();
@@ -989,7 +984,7 @@ void SMESHGUI_FilterLibraryDlg::addFilterToLib (const QString& theName)
 
   if (theName != aName)
     SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_WARNING"),
-                                tr("ASSIGN_NEW_NAME").arg(theName).arg(aName));
+                                 tr("ASSIGN_NEW_NAME").arg(theName).arg(aName));
 }
 
 //=======================================================================
@@ -1089,7 +1084,7 @@ void SMESHGUI_FilterLibraryDlg::onDeleteBtnPressed()
 {
   if (myLibrary->_is_nil()) {
     SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_WRN_WARNING"),
-                                tr("LIBRARY_IS_NOT_LOADED"));
+                                 tr("LIBRARY_IS_NOT_LOADED"));
     return;
   }
 
@@ -1097,7 +1092,7 @@ void SMESHGUI_FilterLibraryDlg::onDeleteBtnPressed()
 
   if (anIndex == -1 || !myLibrary->Delete(myCurrFilterName.toLatin1().constData())) {
     SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_ERROR"),
-                                tr("ERROR_OF_DELETING"));
+                                 tr("ERROR_OF_DELETING"));
   } else {
     myCurrFilterName = "";
     myCurrFilter = -1;
@@ -1188,8 +1183,8 @@ void SMESHGUI_FilterLibraryDlg::onNeedValidation()
     {
       SMESH::Filter_var aFilter = createFilter(myTable->GetType());
       myLibrary->Replace(myCurrFilterName.toLatin1().constData(),
-                        myName->text().toLatin1().constData(),
-                        aFilter);
+                         myName->text().toLatin1().constData(),
+                         aFilter);
     }
   }
 }
index eb9fe6134ee04725748511083f99740750622d02..5b5af4fd0cad7e23194261dc3c0ac0b3f6e747d3 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_FilterLibraryDlg.h
 // Author : Sergey LITONIN, Open CASCADE S.A.S.
@@ -55,7 +56,7 @@ class SMESHGUI_EXPORT SMESHGUI_FilterLibraryDlg : public QDialog
   Q_OBJECT
   
   // Buttons
-  enum { BTN_OK, BTN_Cancel, BTN_Apply, BTN_Close, BTN_Help };
+  enum { BTN_OK, BTN_Apply, BTN_Close, BTN_Help };
 
   class Dialog;
   
index d7ce02e58724b04d8200da658f4e7e73a4de6df3..44ca767f1081e54595897c0d6c03a80c432fca40 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_FilterUtils.cxx
 // Author : Open CASCADE S.A.S.
index aa4cfd0be48f8c12a98d8a892cb6003840e1f80e..dd3103d35b80e0b8e8312a80b3af9159d4b95117 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_FilterUtils.h
 // Author : Open CASCADE S.A.S.
diff --git a/src/SMESHGUI/SMESHGUI_FindElemByPointDlg.cxx b/src/SMESHGUI/SMESHGUI_FindElemByPointDlg.cxx
new file mode 100644 (file)
index 0000000..89515ca
--- /dev/null
@@ -0,0 +1,553 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+// File   : SMESHGUI_FindElemByPointDlg.cxx
+// Author : Edward AGAPOV, Open CASCADE S.A.S.
+//
+
+// SMESH includes
+#include "SMESHGUI_FindElemByPointDlg.h"
+
+#include "SMESHGUI.h"
+#include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI_VTKUtils.h"
+#include "SMESHGUI_SpinBox.h"
+#include "SMESHGUI_MeshEditPreview.h"
+
+#include "SMESH_Actor.h"
+#include "SMESH_ActorUtils.h"
+#include "SMESH_TypeFilter.hxx"
+#include "SMESH_LogicalFilter.hxx"
+
+// SALOME GUI includes
+#include <LightApp_SelectionMgr.h>
+#include <QtxComboBox.h>
+#include <SALOME_ListIO.hxx>
+#include <SUIT_Desktop.h>
+#include <SUIT_MessageBox.h>
+#include <SUIT_OverrideCursor.h>
+#include <SUIT_ResourceMgr.h>
+#include <SVTK_ViewModel.h>
+#include <SVTK_ViewWindow.h>
+#include <SalomeApp_Tools.h>
+#include <SalomeApp_TypeFilter.h>
+
+// Qt includes
+#include <QAbstractButton>
+#include <QGridLayout>
+#include <QGroupBox>
+#include <QHBoxLayout>
+#include <QLabel>
+#include <QLineEdit>
+#include <QListWidget>
+#include <QPushButton>
+#include <QVBoxLayout>
+
+// VTK includes
+#include <vtkProperty.h>
+
+// IDL includes
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
+#define SPACING 6
+#define MARGIN  11
+
+//=======================================================================
+/*!
+ * \brief Dialog to find elements by a point coordinates
+ */
+//=======================================================================
+
+SMESHGUI_FindElemByPointDlg::SMESHGUI_FindElemByPointDlg()
+  : SMESHGUI_Dialog( 0, false, true, OK | Help )
+{
+  setWindowTitle(tr("CAPTION"));
+
+  QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame());
+  aDlgLay->setMargin(0);
+  aDlgLay->setSpacing(SPACING);
+
+  QWidget* aMainFrame = createMainFrame  (mainFrame());
+
+  aDlgLay->addWidget(aMainFrame);
+  aDlgLay->setStretchFactor(aMainFrame, 1);
+}
+
+//================================================================================
+/*!
+ * \brief Set types of elements available for search
+ */
+//================================================================================
+
+void SMESHGUI_FindElemByPointDlg::setTypes(SMESH::array_of_ElementType_var & types)
+{
+  myElemTypeCombo->blockSignals(true);
+  myElemTypeCombo->clear();
+  int nbTypes = 0, hasNodes = 0;
+  for ( int i = 0; i < types->length(); ++i )
+  {
+    switch ( types[i] ) {
+    case SMESH::NODE:
+      myElemTypeCombo->addItem( tr( "MEN_NODE" ));
+      myElemTypeCombo->setId( nbTypes++, int( SMESH::NODE  ));
+      hasNodes = 1;
+      break;
+    case SMESH::EDGE:
+      myElemTypeCombo->addItem( tr( "MEN_EDGE" ));
+      myElemTypeCombo->setId( nbTypes++, int( SMESH::EDGE  ));
+      break;
+    case SMESH::FACE:
+      myElemTypeCombo->addItem( tr( "MEN_FACE" ));
+      myElemTypeCombo->setId( nbTypes++, int( SMESH::FACE  ));
+      break;
+    case SMESH::VOLUME:
+      myElemTypeCombo->addItem( tr( "MEN_VOLUME_3D" ));
+      myElemTypeCombo->setId( nbTypes++, int( SMESH::VOLUME  ));
+      break;
+    case SMESH::ELEM0D:
+      myElemTypeCombo->addItem( tr( "MEN_ELEM0D" ));
+      myElemTypeCombo->setId( nbTypes++, int( SMESH::ELEM0D  ));
+      break;
+    case SMESH::BALL:
+      myElemTypeCombo->addItem( tr( "MEN_BALL" ));
+      myElemTypeCombo->setId( nbTypes++, int( SMESH::BALL  ));
+      break;
+    default:;
+    }
+  }
+  if ( nbTypes - hasNodes > 1 )
+  {
+    myElemTypeCombo->addItem( tr( "MEN_ALL" ));
+    myElemTypeCombo->setId( nbTypes++, int( SMESH::ALL   ));
+  }
+  if ( !hasNodes && nbTypes > 0 )
+  {
+    myElemTypeCombo->addItem( tr( "MEN_NODE" ));
+    myElemTypeCombo->setId( nbTypes++, int( SMESH::NODE  ));
+  }
+  myElemTypeCombo->blockSignals(false);
+}
+
+//=======================================================================
+// function : createMainFrame()
+// purpose  : Create frame containing dialog's input fields
+//=======================================================================
+QWidget* SMESHGUI_FindElemByPointDlg::createMainFrame (QWidget* theParent)
+{
+  QWidget* aFrame = new QWidget(theParent);
+
+  //mesh name
+
+  QGroupBox* aMeshGrp = new QGroupBox(tr("MESH_GROUP"), aFrame);
+  QHBoxLayout* aMeshGrpLayout = new QHBoxLayout(aMeshGrp);
+  aMeshGrpLayout->setMargin(MARGIN);
+  aMeshGrpLayout->setSpacing(SPACING);
+
+  myMeshName = new QLineEdit(aMeshGrp);
+  aMeshGrpLayout->addWidget(myMeshName);
+
+  // coordinates
+
+  QGroupBox* aCoordGrp = new QGroupBox(tr("SMESH_COORDINATES"), aFrame);
+  QHBoxLayout* aCoordGrpLayout = new QHBoxLayout(aCoordGrp);
+  aCoordGrpLayout->setMargin(MARGIN);
+  aCoordGrpLayout->setSpacing(SPACING);
+
+  QLabel* aXLabel = new QLabel(tr("SMESH_X"), aCoordGrp);
+  myX = new SMESHGUI_SpinBox(aCoordGrp);
+
+  QLabel* aYLabel = new QLabel(tr("SMESH_Y"), aCoordGrp);
+  myY = new SMESHGUI_SpinBox(aCoordGrp);
+
+  QLabel* aZLabel = new QLabel(tr("SMESH_Z"), aCoordGrp);
+  myZ = new SMESHGUI_SpinBox(aCoordGrp);
+
+  myX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  myY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  myZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  myX->SetValue(0);
+  myY->SetValue(0);
+  myZ->SetValue(0);
+
+  aCoordGrpLayout->addWidget(aXLabel);
+  aCoordGrpLayout->addWidget(myX);
+  aCoordGrpLayout->addWidget(aYLabel);
+  aCoordGrpLayout->addWidget(myY);
+  aCoordGrpLayout->addWidget(aZLabel);
+  aCoordGrpLayout->addWidget(myZ);
+
+  // Elements
+
+  QGroupBox* elementGrp = new QGroupBox(tr("Elements"), aFrame);
+  QGridLayout* elementGrpLayout = new QGridLayout(elementGrp);
+  elementGrpLayout->setSpacing(SPACING);
+  elementGrpLayout->setMargin(MARGIN);
+
+
+  myFindBtn = new QPushButton(elementGrp);
+  myFindBtn->setText(tr("Find"));
+  //myFindBtn->setCheckable(false);
+
+  myElemTypeCombo = new QtxComboBox(elementGrp);
+
+  myFoundList = new QListWidget(elementGrp);
+
+  elementGrpLayout->addWidget( myFindBtn,       0, 0 );
+  elementGrpLayout->addWidget( myElemTypeCombo, 0, 1 );
+  elementGrpLayout->addWidget( myFoundList,     1, 0, 2, 2 );
+
+
+  QVBoxLayout* aLay = new QVBoxLayout(aFrame);
+  aLay->setMargin( 0 );
+  aLay->setSpacing( SPACING );
+  aLay->addWidget(aMeshGrp);
+  aLay->addWidget(aCoordGrp);
+  aLay->addWidget(elementGrp);
+
+  // OK instead of "Apply and Close"
+  if ( QAbstractButton* but = button(OK) )
+    but->setText( tr("SMESH_BUT_OK"));
+
+  return aFrame;
+}
+
+//================================================================================
+/*!
+ * \brief Constructor
+*/
+//================================================================================
+
+SMESHGUI_FindElemByPointOp::SMESHGUI_FindElemByPointOp()
+  :SMESHGUI_SelectionOp()
+{
+  mySimulation = 0;
+  myDlg = new SMESHGUI_FindElemByPointDlg;
+  myHelpFileName = "find_element_by_point_page.html";
+
+  QList<SUIT_SelectionFilter*> filters;
+  filters.append( new SMESH_TypeFilter( MESH ) );
+  filters.append( new SMESH_TypeFilter( GROUP ) );
+  myFilter = new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR );
+
+  myPreview = new SMESH::MeshPreviewStruct();
+
+  myPreview->nodesXYZ.length(1);
+  myPreview->nodesXYZ[0].x = myDlg->myX->GetValue();
+  myPreview->nodesXYZ[0].y = myDlg->myY->GetValue();
+  myPreview->nodesXYZ[0].z = myDlg->myZ->GetValue();
+
+  myPreview->elementTypes.length(1);
+  myPreview->elementTypes[0].SMDS_ElementType = SMESH::NODE;
+  myPreview->elementTypes[0].isPoly = false;
+  myPreview->elementTypes[0].nbNodesInElement = 1;
+
+  myPreview->elementConnectivities.length(1);
+  myPreview->elementConnectivities[0] = 0;
+
+  // connect signals and slots
+  connect(myDlg->myFindBtn,      SIGNAL(clicked()),               this, SLOT(onFind()));
+  connect(myDlg->myX,            SIGNAL(valueChanged(double)),    this, SLOT(redisplayPreview()));
+  connect(myDlg->myY,            SIGNAL(valueChanged(double)),    this, SLOT(redisplayPreview()));
+  connect(myDlg->myZ,            SIGNAL(valueChanged(double)),    this, SLOT(redisplayPreview()));
+  connect(myDlg->myFoundList,    SIGNAL(itemSelectionChanged()),  this, SLOT(onElemSelected()));
+  connect(myDlg->myElemTypeCombo,SIGNAL(currentIndexChanged(int)),this, SLOT(onElemTypeChange(int)));
+  connect(myDlg,                 SIGNAL(rejectedDlg()),           this, SLOT(onRejectedDlg()));
+}
+
+//=======================================================================
+// function : startOperation()
+// purpose  : Init dialog fields, connect signals and slots, show dialog
+//=======================================================================
+void SMESHGUI_FindElemByPointOp::startOperation()
+{
+  // init simulation with a current View
+  if ( mySimulation ) delete mySimulation;
+  mySimulation = new SMESHGUI_MeshEditPreview(SMESH::GetViewWindow( getSMESHGUI() ));
+  vtkProperty* aProp = vtkProperty::New();
+  aProp->SetRepresentationToWireframe();
+  aProp->SetColor(250, 0, 250);
+  aProp->SetPointSize(5);
+  aProp->SetLineWidth( SMESH::GetFloat("SMESH:element_width",1) + 1);
+  mySimulation->GetActor()->SetProperty(aProp);
+  aProp->Delete();
+
+  SMESHGUI_SelectionOp::startOperation();
+  myDlg->show();
+  redisplayPreview();
+
+  onSelectionDone(); // init myMeshOrPart
+}
+
+//================================================================================
+/*!
+ * \brief Stops operation
+ */
+//================================================================================
+
+void SMESHGUI_FindElemByPointOp::stopOperation()
+{
+  if ( mySimulation )
+  {
+    mySimulation->SetVisibility(false);
+    delete mySimulation;
+    mySimulation = 0;
+  }
+  selectionMgr()->removeFilter( myFilter );
+  SMESHGUI_SelectionOp::stopOperation();
+}
+
+//================================================================================
+/*!
+ * \brief hilight found selected elements
+ */
+//================================================================================
+
+void SMESHGUI_FindElemByPointOp::onElemSelected()
+{
+  if ( !myMeshIO.IsNull() )
+  {
+    Selection_Mode selMode =
+      myDlg->myElemTypeCombo->currentId() == int(SMESH::NODE) ? NodeSelection : CellSelection;
+    if ( selectionMode() != selMode )
+      setSelectionMode( selMode );
+
+    QList<QListWidgetItem *> ids = myDlg->myFoundList->selectedItems();
+    QList<QListWidgetItem*>::iterator id = ids.begin();
+    TColStd_MapOfInteger idMap;
+    for ( ; id != ids.end(); ++id )
+      idMap.Add( (*id)->text().toInt() );
+
+    addOrRemoveIndex( myMeshIO, idMap, false );
+
+    SALOME_ListIO aList;
+    aList.Append(myMeshIO);
+    selectionMgr()->setSelectedObjects(aList,false);
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Set selection mode according to element type
+ */
+//================================================================================
+
+void SMESHGUI_FindElemByPointOp::onElemTypeChange(int index)
+{
+  Selection_Mode newMode = (index == 1) ? NodeSelection : CellSelection;
+  if ( selectionMode() != newMode )
+  {
+    selectionMgr()->clearFilters();
+    setSelectionMode( newMode );
+  }
+  myDlg->myFoundList->clear();
+}
+
+//================================================================================
+/*!
+ * \brief Method needed for internal cuisine
+ */
+//================================================================================
+
+void SMESHGUI_FindElemByPointDlg::reject()
+{
+  emit rejectedDlg();
+  QtxDialog::reject();
+}
+
+//================================================================================
+/*!
+ * \brief Method needed for internal cuisine
+ */
+//================================================================================
+
+void SMESHGUI_FindElemByPointOp::onRejectedDlg()
+{
+  myMeshIO.Nullify(); 
+}
+
+//================================================================================
+/*!
+ * \brief perform it's intention action: find elements
+ */
+//================================================================================
+
+void SMESHGUI_FindElemByPointOp::onFind()
+{
+  if ( myMeshOrPart->_is_nil() )
+    return;
+
+  try {
+    SUIT_OverrideCursor wc;
+
+    SMESH::SMESH_Mesh_var aMesh = myMeshOrPart->GetMesh();
+    if ( aMesh->_is_nil() )
+      return;
+    SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
+    if (aMeshEditor->_is_nil())
+      return;
+
+    SMESH::long_array_var foundIds;
+    if ( aMesh->_is_equivalent( myMeshOrPart ) )
+      foundIds =
+        aMeshEditor->FindElementsByPoint( myDlg->myX->GetValue(),
+                                          myDlg->myY->GetValue(),
+                                          myDlg->myZ->GetValue(),
+                                          SMESH::ElementType( myDlg->myElemTypeCombo->currentId()));
+    else
+      foundIds =
+        aMeshEditor->FindAmongElementsByPoint( myMeshOrPart,
+                                               myDlg->myX->GetValue(),
+                                               myDlg->myY->GetValue(),
+                                               myDlg->myZ->GetValue(),
+                                               SMESH::ElementType( myDlg->myElemTypeCombo->currentId()));
+    myDlg->myFoundList->clear();
+    for ( int i = 0; i < foundIds->length(); ++i )
+      myDlg->myFoundList->addItem( QString::number( foundIds[i] ));
+
+    if ( foundIds->length() > 0 )
+      myDlg->myFoundList->setCurrentRow(0);
+  }
+  catch (const SALOME::SALOME_Exception& S_ex) {
+    SalomeApp_Tools::QtCatchCorbaException(S_ex);
+  }
+  catch (...) {
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Method needed for internal cuisine
+ */
+//================================================================================
+
+bool SMESHGUI_FindElemByPointOp::onApply()
+{
+  onRejectedDlg();
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief SLOT called when selection changed
+ */
+//================================================================================
+
+void SMESHGUI_FindElemByPointOp::onSelectionDone()
+{
+  if ( !myDlg->isVisible() || !myDlg->isEnabled() )
+    return;
+
+  QString oldMeshEntry, newMeshEntry;
+  if ( !myMeshIO.IsNull() && myMeshIO->hasEntry() )
+    oldMeshEntry = myMeshIO->getEntry();
+
+  try {
+    SALOME_ListIO aList;
+    selectionMgr()->selectedObjects(aList, SVTK_Viewer::Type());
+    if (aList.Extent() == 1 && aList.First()->hasEntry())
+    {
+      Handle(SALOME_InteractiveObject) anIO = aList.First();
+      _PTR(SObject) pObj = studyDS()->FindObjectID(anIO->getEntry());
+      CORBA::Object_var anObj = SMESH::IObjectToObject( anIO );
+      newMeshEntry = anIO->getEntry();
+      SMESH::SMESH_IDSource_var aMeshOrPart = SMESH::SMESH_IDSource::_narrow(anObj);
+      if ( pObj && !aMeshOrPart->_is_nil() && oldMeshEntry != newMeshEntry )
+      {
+        myMeshOrPart = aMeshOrPart;
+        myMeshIO.Nullify();
+        myMeshIO = anIO;
+        std::string name = pObj->GetName();
+        myDlg->myMeshName->setText("");
+        myDlg->myMeshName->setText( QString( name.c_str() ).trimmed() );
+        SMESH::array_of_ElementType_var  types = myMeshOrPart->GetTypes();
+        myDlg->setTypes( types );
+      }
+    }
+  }
+  catch (...) {
+  }
+
+  if ( oldMeshEntry != newMeshEntry || newMeshEntry.isEmpty() )
+    myDlg->myFoundList->clear();
+
+  myDlg->myFindBtn->setEnabled( !myMeshIO.IsNull() );
+}
+
+//================================================================================
+/*!
+ * \brief show point by coordinates
+ */
+//================================================================================
+
+void SMESHGUI_FindElemByPointOp::redisplayPreview()
+{
+  myDlg->myFoundList->clear();
+
+  myPreview->nodesXYZ[0].x = myDlg->myX->GetValue();
+  myPreview->nodesXYZ[0].y = myDlg->myY->GetValue();
+  myPreview->nodesXYZ[0].z = myDlg->myZ->GetValue();
+
+  mySimulation->SetData(&myPreview.in());
+}
+
+//================================================================================
+/*!
+ * \brief install filter on meshes
+ */
+//================================================================================
+
+void SMESHGUI_FindElemByPointOp::activateSelection()
+{
+  selectionMgr()->clearFilters();
+  selectionMgr()->installFilter( myFilter );
+}
+
+//================================================================================
+/*!
+ * \brief Destructor
+*/
+//================================================================================
+
+SMESHGUI_FindElemByPointOp::~SMESHGUI_FindElemByPointOp()
+{
+  if ( myDlg )         { delete myDlg;        myDlg = 0; }
+  if ( mySimulation )  { delete mySimulation; mySimulation = 0; }
+  if ( myFilter )
+  {
+    QList<SUIT_SelectionFilter*> sub =  ((SMESH_LogicalFilter*)myFilter)->getFilters();
+    delete sub.front();
+    delete sub.back();
+    delete myFilter;
+    myFilter = 0;
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Gets dialog of this operation
+ * \retval LightApp_Dialog* - pointer to dialog of this operation
+ */
+//================================================================================
+
+LightApp_Dialog* SMESHGUI_FindElemByPointOp::dlg() const
+{
+  return myDlg;
+}
+
diff --git a/src/SMESHGUI/SMESHGUI_FindElemByPointDlg.h b/src/SMESHGUI/SMESHGUI_FindElemByPointDlg.h
new file mode 100644 (file)
index 0000000..0999040
--- /dev/null
@@ -0,0 +1,120 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+#ifndef SMESHGUI_FindElemByPointDLG_H
+#define SMESHGUI_FindElemByPointDLG_H
+
+// SMESH includes
+#include "SMESH_SMESHGUI.hxx"
+
+#include "SMESHGUI_Dialog.h"
+#include "SMESHGUI_SelectionOp.h"
+
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+
+class QLineEdit;
+class QPushButton;
+class QListWidget;
+class QtxComboBox;
+class SMESHGUI_SpinBox;
+class SMESHGUI_MeshEditPreview;
+class SMESHGUI_FindElemByPointDlg;
+
+/*!
+ * \brief Operation to find elements by a point coordinates
+ */
+class SMESHGUI_EXPORT SMESHGUI_FindElemByPointOp: public SMESHGUI_SelectionOp
+{
+  Q_OBJECT
+
+public:
+  SMESHGUI_FindElemByPointOp();
+  virtual ~SMESHGUI_FindElemByPointOp();
+
+  virtual LightApp_Dialog*       dlg() const;  
+
+protected:
+
+  virtual void                   startOperation();
+  virtual void                   stopOperation();
+
+  virtual void                   activateSelection();
+
+protected slots:
+
+  virtual void                   onFind();
+  virtual bool                   onApply();
+
+private slots:
+
+  void                           onRejectedDlg();
+  void                           onSelectionDone();
+  void                           onElemSelected();
+  void                           onElemTypeChange(int);
+  void                           redisplayPreview();
+
+private:
+  SMESHGUI_FindElemByPointDlg*     myDlg;
+
+  SUIT_SelectionFilter*            myFilter;
+  SMESHGUI_MeshEditPreview*        mySimulation; // to show point coordinates
+  SMESH::SMESH_IDSource_var        myMeshOrPart;
+  SMESH::MeshPreviewStruct_var     myPreview;
+  Handle(SALOME_InteractiveObject) myMeshIO;
+};
+
+/*!
+ * \brief Dialog to find elements by a point coordinates
+ */
+
+class SMESHGUI_EXPORT SMESHGUI_FindElemByPointDlg : public SMESHGUI_Dialog
+{
+  Q_OBJECT
+
+public:
+  SMESHGUI_FindElemByPointDlg();
+
+  void setTypes(SMESH::array_of_ElementType_var & types);
+
+private:
+  QWidget*                      createMainFrame( QWidget* );
+
+  QLineEdit*                    myMeshName;
+  SMESHGUI_SpinBox*             myX;
+  SMESHGUI_SpinBox*             myY;
+  SMESHGUI_SpinBox*             myZ;
+  QtxComboBox*                  myElemTypeCombo;
+  QPushButton*                  myFindBtn;
+  QListWidget*                  myFoundList;
+
+  QString                       myHelpFileName;
+
+  friend class SMESHGUI_FindElemByPointOp;
+
+signals:
+  void                           rejectedDlg();
+
+protected slots:
+  virtual void                   reject();
+
+private slots:
+//void                          ButtonToggled( bool );
+};
+
+#endif // SMESHGUI_FindElemByPointDLG_H
index 33907aec03508e625ab08fd38c670a12efbffe8f..ead9da3c0ab7d7c1739c680adcba9aac1e6f6120 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_GEOMGenUtils.cxx
 // Author : Open CASCADE S.A.S.
@@ -51,7 +52,8 @@ namespace SMESH
     return aGEOMGen;
   }
 
-  GEOM::GEOM_Object_var GetShapeOnMeshOrSubMesh(_PTR(SObject) theMeshOrSubmesh)
+  GEOM::GEOM_Object_var GetShapeOnMeshOrSubMesh(_PTR(SObject) theMeshOrSubmesh,
+                                                bool*         isMesh)
   {
     SALOMEDS_SObject* aMeshOrSubmesh = _CAST(SObject,theMeshOrSubmesh);
     if(aMeshOrSubmesh) {
@@ -60,11 +62,17 @@ namespace SMESH
         SMESH::SMESH_Mesh_var aMesh =
           SObjectToInterface<SMESH::SMESH_Mesh>( theMeshOrSubmesh );
         if ( !aMesh->_is_nil() )
+        {
+          if ( isMesh ) *isMesh = true;
           return aMesh->GetShapeToMesh();
+        }
         SMESH::SMESH_subMesh_var aSubmesh =
           SObjectToInterface<SMESH::SMESH_subMesh>( theMeshOrSubmesh );
         if ( !aSubmesh->_is_nil() )
-         return aSubmesh->GetSubShape();
+        {
+          if ( isMesh ) *isMesh = false;
+          return aSubmesh->GetSubShape();
+        }
       }
     }
     return GEOM::GEOM_Object::_nil();
@@ -89,7 +97,7 @@ namespace SMESH
         SALOMEDS_SObject* aRefSO = _CAST(SObject,aRefSOClient);
         aMeshShape = GEOM::GEOM_Object::_narrow(aRefSO->GetObject());
       } else {
-       SALOMEDS_SObject* aSO = _CAST(SObject,aSObject);
+        SALOMEDS_SObject* aSO = _CAST(SObject,aSObject);
         aMeshShape = GEOM::GEOM_Object::_narrow(aSO->GetObject());
       }
 
index 8461a643236011d17233762a4096f9946c7b3eaf..807c2576a41b0820605ce842875b95b86b42a716 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_GEOMGenUtils.h
 // Author : Open CASCADE S.A.S.
@@ -42,7 +43,7 @@ namespace SMESH
 {
   SMESHGUI_EXPORT GEOM::GEOM_Gen_var    GetGEOMGen();
 
-  SMESHGUI_EXPORT GEOM::GEOM_Object_var GetShapeOnMeshOrSubMesh( _PTR(SObject) );
+  SMESHGUI_EXPORT GEOM::GEOM_Object_var GetShapeOnMeshOrSubMesh( _PTR(SObject), bool* isMesh=0 );
 
   SMESHGUI_EXPORT GEOM::GEOM_Object_ptr GetGeom( _PTR(SObject) );
 
index 352215c957923d3e79eb4e02e221b14b9abd0033..10995de1942a6c74074942ad7e8ebf7c27e5fddd 100644 (file)
@@ -1,28 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-// SMESH SMESHGUI : GUI for SMESH component
-// File   : SMESHGUI_GroupDlg.cxx
-// Author : Natalia KOPNOVA, Open CASCADE S.A.S.
-// SMESH includes
+
+//  SMESH SMESHGUI : GUI for SMESH component
+//  File   : SMESHGUI_GroupDlg.cxx
+//  Author : Natalia KOPNOVA, Open CASCADE S.A.S.
+//  SMESH includes
 //
 #include "SMESHGUI_GroupDlg.h"
 
@@ -38,6 +39,7 @@
 #include <SMESH_TypeFilter.hxx>
 #include <SMESH_Actor.h>
 #include <SMESH_ActorUtils.h>
+#include <SMESH_LogicalFilter.hxx>
 
 // SALOME GEOM includes
 #include <GEOMBase.h>
@@ -61,6 +63,8 @@
 
 #include <SVTK_ViewWindow.h>
 
+#include <VTKViewer_Algorithm.h>
+
 // SALOME KERNEL includes
 #include <SALOMEDSClient_Study.hxx>
 
 #define SPACING 6
 #define MARGIN  11
 
+enum grpSelectionMode {
+  grpNoSelection       = -1,
+  grpNodeSelection     = 0,
+  grpBallSelection     = 1,
+  grpEdgeSelection     = 2,
+  grpFaceSelection     = 3,
+  grpVolumeSelection   = 4,
+  grpSubMeshSelection  = 5,
+  grpGroupSelection    = 6,
+  grpMeshSelection     = 7,
+  grpGeomSelection     = 8,
+  grpAllSelection      = 9,
+};
+
 //=================================================================================
 // function : SMESHGUI_GroupDlg()
 // purpose  :
 //=================================================================================
 SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( SMESHGUI* theModule,
-                                     SMESH::SMESH_Mesh_ptr theMesh )
+                                      SMESH::SMESH_Mesh_ptr theMesh )
   : QDialog( SMESH::GetDesktop( theModule ) ),
     mySMESHGUI( theModule ),
     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
     mySelector( SMESH::GetViewWindow( theModule )->GetSelector() ),
     myIsBusy( false ),
     myNameChanged( false ),
-    myActor( 0 )
+    myIsApplyAndClose( false ),
+    myNbChangesOfContents(0)
 {
   initDialog( true );
   if ( !theMesh->_is_nil() )
@@ -127,14 +146,15 @@ SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( SMESHGUI* theModule,
 // purpose  :
 //=================================================================================
 SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( SMESHGUI* theModule,
-                                     SMESH::SMESH_GroupBase_ptr theGroup,
+                                      SMESH::SMESH_GroupBase_ptr theGroup,
                                       const bool theIsConvert )
   : QDialog( SMESH::GetDesktop( theModule ) ),
     mySMESHGUI( theModule ),
     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
     mySelector( SMESH::GetViewWindow( theModule )->GetSelector() ),
     myIsBusy( false ),
-    myNameChanged( false )
+    myNameChanged( false ),
+    myNbChangesOfContents(0) // just not to use uninitialized variable
 {
   initDialog( false );
   if ( !theGroup->_is_nil() )
@@ -145,7 +165,7 @@ SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( SMESHGUI* theModule,
     mySelectGroup->setEnabled( false );
 
     myCurrentLineEdit = myMeshGroupLine;
-    setSelectionMode( 5 );
+    setSelectionMode( grpGroupSelection );
   }
 }
 
@@ -194,6 +214,7 @@ void SMESHGUI_GroupDlg::initDialog( bool create)
 
   QStringList types;
   types.append( tr( "MESH_NODE" ) );
+  types.append( tr( "SMESH_BALL_ELEM" ) );
   types.append( tr( "SMESH_EDGE" ) );
   types.append( tr( "SMESH_FACE" ) );
   types.append( tr( "SMESH_VOLUME" ) );
@@ -221,10 +242,13 @@ void SMESHGUI_GroupDlg::initDialog( bool create)
 
   QRadioButton* rb1 = new QRadioButton( tr( "SMESH_GROUP_STANDALONE" ), aGrpTypeBox );
   QRadioButton* rb2 = new QRadioButton( tr( "SMESH_GROUP_GEOMETRY" ),   aGrpTypeBox );
+  QRadioButton* rb3 = new QRadioButton( tr( "SMESH_GROUP_FILTER" ),     aGrpTypeBox );
   myGrpTypeGroup->addButton( rb1, 0 );
   myGrpTypeGroup->addButton( rb2, 1 );
+  myGrpTypeGroup->addButton( rb3, 2 );
   aGrpTypeBoxLayout->addWidget( rb1 );
   aGrpTypeBoxLayout->addWidget( rb2 );
+  aGrpTypeBoxLayout->addWidget( rb3 );
   aGrpTypeBox->setEnabled( create );
   myGrpTypeId = -1;
 
@@ -232,66 +256,72 @@ void SMESHGUI_GroupDlg::initDialog( bool create)
   myWGStack = new QStackedWidget( this );
   QWidget* wg1 = new QWidget( myWGStack );
   QWidget* wg2 = new QWidget( myWGStack );
+  QWidget* wg3 = new QWidget( myWGStack );
 
   /***************************************************************/
-  QGroupBox* aContentBox = new QGroupBox( tr( "SMESH_CONTENT" ), wg1 );
+  QGroupBox* aContentBox         = new QGroupBox( tr( "SMESH_CONTENT" ), wg1 );
   QGridLayout* aContentBoxLayout = new QGridLayout( aContentBox );
   aContentBoxLayout->setMargin( MARGIN );
   aContentBoxLayout->setSpacing( SPACING );
 
-  QLabel* aLabel = new QLabel( tr( "SMESH_ID_ELEMENTS" ), aContentBox );
-  myElements = new QListWidget( aContentBox );
+  mySelectAll       = new QCheckBox( tr( "SELECT_ALL" ), aContentBox );
+  myAllowElemsModif = new QCheckBox( tr( "ALLOW_ELEM_LIST_MODIF" ), aContentBox );
+
+  myElementsLab = new QLabel( tr( "SMESH_ID_ELEMENTS" ), aContentBox );
+  myElements    = new QListWidget( aContentBox );
   myElements->setSelectionMode( QListWidget::ExtendedSelection );
 
-  myFilter = new QPushButton( tr( "SMESH_BUT_FILTER" ), aContentBox );
-  QPushButton* aAddBtn = new QPushButton( tr( "SMESH_BUT_ADD" ), aContentBox );
-  QPushButton* aRemoveBtn = new QPushButton( tr( "SMESH_BUT_REMOVE" ), aContentBox );
-  QPushButton* aSortBtn = new QPushButton( tr( "SMESH_BUT_SORT" ), aContentBox );
+  myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), aContentBox );
+  myAddBtn    = new QPushButton( tr( "SMESH_BUT_ADD" ), aContentBox );
+  myRemoveBtn = new QPushButton( tr( "SMESH_BUT_REMOVE" ), aContentBox );
+  mySortBtn   = new QPushButton( tr( "SMESH_BUT_SORT" ), aContentBox );
 
-  aContentBoxLayout->addWidget( aLabel,     0, 0 );
-  aContentBoxLayout->addWidget( myElements, 1, 0, 6, 1 );
-  aContentBoxLayout->addWidget( myFilter,   1, 1 );
-  aContentBoxLayout->addWidget( aAddBtn,    3, 1 );
-  aContentBoxLayout->addWidget( aRemoveBtn, 4, 1 );
-  aContentBoxLayout->addWidget( aSortBtn,   6, 1 );
+  aContentBoxLayout->addWidget( mySelectAll,       0, 0 );
+  aContentBoxLayout->addWidget( myAllowElemsModif, 1, 0 );
+  aContentBoxLayout->addWidget( myFilterBtn,       1, 1 );
+  aContentBoxLayout->addWidget( myElementsLab,     2, 0 );
+  aContentBoxLayout->addWidget( myElements,        3, 0, 6, 1 );
+  aContentBoxLayout->addWidget( myAddBtn,          3, 1 );
+  aContentBoxLayout->addWidget( myRemoveBtn,       4, 1 );
+  aContentBoxLayout->addWidget( mySortBtn,         8, 1 );
 
   aContentBoxLayout->setColumnStretch( 0, 1 );
-  aContentBoxLayout->setRowStretch( 2, 1 );
-  aContentBoxLayout->setRowStretch( 5, 1 );
+  aContentBoxLayout->setRowStretch( 3, 1 );
+  aContentBoxLayout->setRowStretch( 6, 1 );
 
   /***************************************************************/
-  QGroupBox* aSelectBox = new QGroupBox( tr( "SMESH_SELECT_FROM" ), wg1 );
-  QGridLayout* aSelectBoxLayout = new QGridLayout( aSelectBox );
-  aSelectBoxLayout->setMargin( MARGIN );
-  aSelectBoxLayout->setSpacing( SPACING );
+  mySelectBox = new QGroupBox( tr( "SMESH_SELECT_FROM" ), wg1 );
+  QGridLayout* mySelectBoxLayout = new QGridLayout( mySelectBox );
+  mySelectBoxLayout->setMargin( MARGIN );
+  mySelectBoxLayout->setSpacing( SPACING );
 
-  mySelectSubMesh = new QCheckBox( tr( "SMESH_SUBMESH" ), aSelectBox );
-  mySubMeshBtn = new QPushButton( aSelectBox );
+  mySelectSubMesh = new QCheckBox( tr( "SMESH_SUBMESH" ), mySelectBox );
+  mySubMeshBtn = new QPushButton( mySelectBox );
   mySubMeshBtn->setIcon( image0 );
-  mySubMeshLine = new QLineEdit( aSelectBox );
+  mySubMeshLine = new QLineEdit( mySelectBox );
   mySubMeshLine->setReadOnly( true );
   onSelectSubMesh( false );
 
-  mySelectGroup = new QCheckBox( tr( "SMESH_GROUP" ), aSelectBox );
-  myGroupBtn = new QPushButton( aSelectBox );
+  mySelectGroup = new QCheckBox( tr( "SMESH_GROUP" ), mySelectBox );
+  myGroupBtn = new QPushButton( mySelectBox );
   myGroupBtn->setIcon( image0 );
-  myGroupLine = new QLineEdit( aSelectBox );
+  myGroupLine = new QLineEdit( mySelectBox );
   myGroupLine->setReadOnly( true );
   onSelectGroup( false );
 
-  aSelectBoxLayout->addWidget( mySelectSubMesh, 0, 0 );
-  aSelectBoxLayout->addWidget( mySubMeshBtn,    0, 1 );
-  aSelectBoxLayout->addWidget( mySubMeshLine,   0, 2 );
-  aSelectBoxLayout->addWidget( mySelectGroup,   1, 0 );
-  aSelectBoxLayout->addWidget( myGroupBtn,      1, 1 );
-  aSelectBoxLayout->addWidget( myGroupLine,     1, 2 );
+  mySelectBoxLayout->addWidget( mySelectSubMesh, 0, 0 );
+  mySelectBoxLayout->addWidget( mySubMeshBtn,    0, 1 );
+  mySelectBoxLayout->addWidget( mySubMeshLine,   0, 2 );
+  mySelectBoxLayout->addWidget( mySelectGroup,   1, 0 );
+  mySelectBoxLayout->addWidget( myGroupBtn,      1, 1 );
+  mySelectBoxLayout->addWidget( myGroupLine,     1, 2 );
 
   /***************************************************************/
   QVBoxLayout* wg1Layout = new QVBoxLayout( wg1 );
   wg1Layout->setMargin( 0 );
   wg1Layout->setSpacing( SPACING );
   wg1Layout->addWidget( aContentBox );
-  wg1Layout->addWidget( aSelectBox );
+  wg1Layout->addWidget( mySelectBox );
   wg1Layout->setStretchFactor( aContentBox, 10 );
 
   /***************************************************************/
@@ -309,15 +339,24 @@ void SMESHGUI_GroupDlg::initDialog( bool create)
   /***************************************************************/
   QGridLayout* wg2Layout = new QGridLayout( wg2 );
   wg2Layout->setMargin( 0 );
-  wg1Layout->setSpacing( SPACING );
+  wg2Layout->setSpacing( SPACING );
   wg2Layout->addWidget( geomObject,     0, 0 );
   wg2Layout->addWidget( myGeomGroupBtn, 0, 1 );
   wg2Layout->addWidget( myGeomGroupLine,0, 2 );
   wg2Layout->setRowStretch( 1, 5 );
 
+  /***************************************************************/
+  QPushButton * aFilter2 = new QPushButton( tr( "SMESH_BUT_FILTER" ), wg3 );
+  QGridLayout* wg3Layout = new QGridLayout( wg3 );
+  wg3Layout->setMargin( 0 );
+  wg3Layout->setSpacing( SPACING );
+  wg3Layout->addWidget( aFilter2, 0, 0 );
+  wg3Layout->setRowStretch( 1, 5 );
+
   /***************************************************************/
   myWGStack->insertWidget( 0, wg1 );
   myWGStack->insertWidget( 1, wg2 );
+  myWGStack->insertWidget( 2, wg3 );
 
   /***************************************************************/
   QGroupBox* aColorBox = new QGroupBox(tr( "SMESH_SET_COLOR" ), this);
@@ -328,7 +367,7 @@ void SMESHGUI_GroupDlg::initDialog( bool create)
   QLabel* aColorLab = new QLabel(tr( "SMESH_CHECK_COLOR" ), aColorBox );
   myColorBtn = new QtxColorButton(aColorBox);
   myColorBtn->setSizePolicy( QSizePolicy::MinimumExpanding, 
-                            myColorBtn->sizePolicy().verticalPolicy() );
+                             myColorBtn->sizePolicy().verticalPolicy() );
 
   aColorBoxLayout->addWidget(aColorLab);
   aColorBoxLayout->addWidget(myColorBtn);
@@ -372,45 +411,53 @@ void SMESHGUI_GroupDlg::initDialog( bool create)
   aMainLayout->addWidget(aButtons,        6, 0, 1, 3);
 
   /* signals and slots connections */
-  connect(myMeshGroupBtn, SIGNAL(clicked()),          this, SLOT(setCurrentSelection()));
-  connect(myGrpTypeGroup, SIGNAL(buttonClicked(int)), this, SLOT(onGrpTypeChanged(int)));
-  connect(myTypeGroup,    SIGNAL(buttonClicked(int)), this, SLOT(onTypeChanged(int)));
+  connect(myMeshGroupBtn,  SIGNAL(clicked()),          this, SLOT(setCurrentSelection()));
+  connect(myGrpTypeGroup,  SIGNAL(buttonClicked(int)), this, SLOT(onGrpTypeChanged(int)));
+  connect(myTypeGroup,     SIGNAL(buttonClicked(int)), this, SLOT(onTypeChanged(int)));
 
-  connect(myName,     SIGNAL(textChanged(const QString&)), this, SLOT(onNameChanged(const QString&)));
-  connect(myElements, SIGNAL(itemSelectionChanged()),      this, SLOT(onListSelectionChanged()));
+  connect(myName,          SIGNAL(textChanged(const QString&)), this, SLOT(onNameChanged(const QString&)));
+  connect(myElements,      SIGNAL(itemSelectionChanged()),      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(myFilterBtn,     SIGNAL(clicked()),     this, SLOT(setFilters()));
+  connect(aFilter2,        SIGNAL(clicked()),     this, SLOT(setFilters()));
+  connect(mySelectAll,     SIGNAL(toggled(bool)), this, SLOT(onSelectAll()));
+  connect(myAllowElemsModif,SIGNAL(toggled(bool)), this, SLOT(onSelectAll()));
+  connect(myAddBtn,        SIGNAL(clicked()),     this, SLOT(onAdd()));
+  connect(myRemoveBtn,     SIGNAL(clicked()),     this, SLOT(onRemove()));
+  connect(mySortBtn,       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(mySubMeshBtn,    SIGNAL(clicked()),     this, SLOT(setCurrentSelection()));
+  connect(myGroupBtn,      SIGNAL(clicked()),     this, SLOT(setCurrentSelection()));
   connect(myGeomGroupBtn,  SIGNAL(toggled(bool)), this, SLOT(onGeomSelectionButton(bool)));
 
-  connect(myColorBtn, SIGNAL(changed( QColor )), this, SLOT(onColorChanged( QColor )));
+  connect(myColorBtn,      SIGNAL(changed( QColor )),  this, SLOT(onColorChanged( QColor )));
 
-  connect(myOKBtn,    SIGNAL(clicked()), this, SLOT(onOK()));
-  connect(myApplyBtn, SIGNAL(clicked()), this, SLOT(onApply()));
-  connect(myCloseBtn, SIGNAL(clicked()), this, SLOT(onClose()));
-  connect(myHelpBtn,  SIGNAL(clicked()), this, SLOT(onHelp()));
+  connect(myOKBtn,         SIGNAL(clicked()), this, SLOT(onOK()));
+  connect(myApplyBtn,      SIGNAL(clicked()), this, SLOT(onApply()));
+  connect(myCloseBtn,      SIGNAL(clicked()), this, SLOT(onClose()));
+  connect(myHelpBtn,       SIGNAL(clicked()), this, SLOT(onHelp()));
 
   /* Init selection */
   mySMESHGUI->SetActiveDialogBox(this);
   mySMESHGUI->SetState(800);
 
-  mySelectionMode = -1;
+  mySelectionMode = grpNoSelection;
   myMeshFilter = new SMESH_TypeFilter(MESH);
-  mySubMeshFilter = new SMESH_TypeFilter(SUBMESH);
-  myGroupFilter = new SMESH_TypeFilter(GROUP);
+  mySubMeshFilter = new SMESH_LogicalFilter(QList<SUIT_SelectionFilter*>(),
+                                            SMESH_LogicalFilter::LO_OR,
+                                            /*takeOwnership=*/true);
+  myGroupFilter = new SMESH_LogicalFilter(QList<SUIT_SelectionFilter*>(),
+                                          SMESH_LogicalFilter::LO_OR,
+                                          /*takeOwnership=*/true);
   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( mySMESHGUI->application()->activeStudy() );
   myGeomFilter = new GEOM_SelectionFilter( aStudy, true );
 
   connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(onDeactivate()));
   connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()),        this, SLOT(onClose()));
   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()),  this, SLOT(onObjectSelectionChanged()));
+  connect(mySMESHGUI, SIGNAL(SignalVisibilityChanged()),      this, SLOT(onVisibilityChanged()));
 
   rb1->setChecked(true); // VSR !!!
   onGrpTypeChanged(0); // VSR!!!
@@ -418,8 +465,7 @@ void SMESHGUI_GroupDlg::initDialog( bool create)
   if (myMesh->_is_nil() )
     myTypeGroup->button(0)->setChecked(true);
 
-  updateButtons();
-  //myName->setText(GetDefaultName(tr( "SMESH_GROUP" )));
+  onSelectAll(); //updateButtons();
 }
 
 //=================================================================================
@@ -433,6 +479,10 @@ SMESHGUI_GroupDlg::~SMESHGUI_GroupDlg()
     myFilterDlg->setParent( 0 );
     delete myFilterDlg;
   }
+  if ( myMeshFilter )    delete myMeshFilter;
+  if ( mySubMeshFilter ) delete mySubMeshFilter;
+  if ( myGroupFilter )   delete myGroupFilter;
+  if ( myGeomFilter )    delete myGeomFilter;
 }
 
 //=================================================================================
@@ -485,6 +535,7 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_Mesh_ptr theMesh)
   setShowEntityMode();
   myGroup = SMESH::SMESH_Group::_nil();
   myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_nil();
+  myGroupOnFilter = SMESH::SMESH_GroupOnFilter::_nil();
 
   // NPAL19389: create a group with a selection in another group
   // set actor of myMesh, if it is visible, else try
@@ -513,7 +564,7 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_Mesh_ptr theMesh)
 // purpose  :
 //=================================================================================
 void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup,
-                              const bool theIsConvert)
+                              const bool                 theIsConvert)
 {
   restoreShowEntityMode();
   myMesh = theGroup->GetMesh();
@@ -532,17 +583,20 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup,
 
   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;
+  case SMESH::NODE:   aType = 0; break;
+  case SMESH::BALL:   aType = 1; break;
+  case SMESH::EDGE:   aType = 2; break;
+  case SMESH::FACE:   aType = 3; break;
+  case SMESH::VOLUME: aType = 4; break;
   }
   myTypeGroup->button(aType)->setChecked(true);
 
-  myGroup = SMESH::SMESH_Group::_narrow( theGroup );
-  myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow( theGroup );
+  myGroup         = SMESH::SMESH_Group::_narrow( theGroup );
+  myGroupOnGeom   = SMESH::SMESH_GroupOnGeom::_narrow( theGroup );
+  myGroupOnFilter = SMESH::SMESH_GroupOnFilter::_narrow( theGroup );
+  myFilter        = SMESH::Filter::_nil();
 
-  if (myGroup->_is_nil() && myGroupOnGeom->_is_nil())
+  if (myGroup->_is_nil() && myGroupOnGeom->_is_nil() && myGroupOnFilter->_is_nil() )
     return;
 
   // NPAL19389: create a group with a selection in another group
@@ -550,21 +604,24 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup,
   // actor of theGroup, if it is visible, else try
   // any visible actor of group or submesh of myMesh
   // commented, because an attempt to set selection on not displayed cells leads to error
-  //SetAppropriateActor();
-  myActor = SMESH::FindActorByObject(myMesh);
-  if ( !myActor )
-    myActor = SMESH::FindActorByObject(theGroup);
-  SMESH::SetPickable(myActor);
+  SetAppropriateActor();
 
-  int grpType = (!myGroup->_is_nil() ? 0 : (theIsConvert ? 0 : 1));
+  /*  SMESH_Actor* anActor = SMESH::FindActorByObject(myMesh);
+  if ( !anActor )
+    anActor = SMESH::FindActorByObject(theGroup);
+  SMESH::SetPickable(anActor);*/
+
+  int grpType = (!myGroup->_is_nil() ? 0 : (theIsConvert ? 0 : myGroupOnGeom->_is_nil() ? 2 : 1));
   myGrpTypeGroup->button(grpType)->setChecked(true);
   onGrpTypeChanged(grpType);
 
-  if ( grpType == 0 ) {
+  myTypeId = aType;
+  if ( grpType == 0 ) { // standalone group
     myCurrentLineEdit = 0;
     myElements->clear();
+    myAllowElemsModif->setChecked( true );
+
     setSelectionMode(aType);
-    myTypeId = aType;
 
     setShowEntityMode(); // depends on myTypeId
 
@@ -579,7 +636,7 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup,
       myElements->selectAll();
     }
   }
-  else
+  else if ( grpType == 1 ) // group on geom
   {
     QString aShapeName( "" );
     _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
@@ -587,15 +644,30 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup,
     if (!aGroupShape->_is_nil())
     {
       _PTR(SObject) aGroupShapeSO = aStudy->FindObjectID(aGroupShape->GetStudyEntry());
-      aShapeName = aGroupShapeSO->GetName().c_str();
+      if ( aGroupShapeSO )
+        aShapeName = aGroupShapeSO->GetName().c_str();
     }
     myGeomGroupLine->setText( aShapeName );
+  }
+  else // group on filter
+  {
+    myFilter = myGroupOnFilter->GetFilter();
+    if ( !myFilter->_is_nil() ) {
+      SMESH::Predicate_var perdicate = myFilter->GetPredicate();
+      if ( perdicate->_is_nil() )
+        myFilter = SMESH::Filter::_nil();
+    }
+  }
+
+  if ( grpType != 0 )
+  {
     myNameChanged = true;
     myName->blockSignals(true);
-    myName->setText( "Group On " + aShapeName);
+    myName->setText(theGroup->GetName());
     myName->blockSignals(false);
   }
-  updateButtons();
+
+  onSelectAll(); //updateButtons();
 }
 
 //=================================================================================
@@ -605,14 +677,33 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup,
 void SMESHGUI_GroupDlg::updateButtons()
 {
   bool enable = !myName->text().trimmed().isEmpty();
-
-  if (myGrpTypeId == 0) {
-    enable = enable && myElements->count() > 0;
-    enable = enable && (!myGroup->_is_nil() || !myMesh->_is_nil());
-  }
-  else if (myGrpTypeId == 1) {
-    if (CORBA::is_nil(myGroupOnGeom)) { // creation mode
-      enable = enable && myGeomObjects->length() > 0 && !myMesh->_is_nil();
+  if ( enable )
+  {
+    if (myGrpTypeId == 0) { // standalone
+      if ( !mySelectAll->isChecked() )
+      {
+        if ( myAllowElemsModif->isChecked() )
+        {
+          enable = ( myElements->count() > 0 );
+        }
+        else if ((enable = !myFilter->_is_nil() ))
+        {
+          SMESH::array_of_ElementType_var types = myFilter->GetTypes();
+          enable = types->length();
+        }
+      }
+      enable = enable && (!myGroup->_is_nil() || !myMesh->_is_nil());
+    }
+    else if (myGrpTypeId == 1) // on geom
+    {
+      if (CORBA::is_nil(myGroupOnGeom)) // creation mode
+        enable = ( myGeomObjects->length() > 0 && !myMesh->_is_nil() );
+    }
+    else if (myGrpTypeId == 2) // on filter
+    {
+      if (( enable = !myFilter->_is_nil() ))
+        if (CORBA::is_nil(myGroupOnFilter) )  // creation mode
+          enable = !myMesh->_is_nil();
     }
   }
 
@@ -639,9 +730,13 @@ void SMESHGUI_GroupDlg::onTypeChanged (int id)
 {
   if (myTypeId != id) {
     myElements->clear();
-    if (myCurrentLineEdit == 0)
-      setSelectionMode(id);
     myTypeId = id;
+    if ( myGrpTypeId == 0 && myCurrentLineEdit == 0)
+      setSelectionMode(id);
+    else
+      setSelectionMode( mySelectionMode++ ); // update according to mySelectionMode
+
+    onObjectSelectionChanged();
     setShowEntityMode();
   }
 }
@@ -653,13 +748,14 @@ void SMESHGUI_GroupDlg::onTypeChanged (int id)
 void SMESHGUI_GroupDlg::onGrpTypeChanged (int id)
 {
   if (myGrpTypeId != id) {
+    myGrpTypeId = id;
     myWGStack->setCurrentIndex( id );
     myName->blockSignals(true);
     myName->setText(myOldName);
     myName->blockSignals(false);
-    onSelectGeomGroup(id == 1);
+    onSelectGeomGroup(id != 0);
   }
-  myGrpTypeId = id;
+  updateButtons();
 }
 
 //=================================================================================
@@ -680,48 +776,95 @@ void SMESHGUI_GroupDlg::setSelectionMode (int theMode)
   // PAL7314
   if (myMesh->_is_nil())
     return;
+  SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
+  bool isSelectAll = mySelectAll->isChecked() || !myAllowElemsModif->isChecked() || myGrpTypeId != 0;
   if (mySelectionMode != theMode) {
     // [PAL10408] mySelectionMgr->clearSelected();
     mySelectionMgr->clearFilters();
-    if (myActor)
-      myActor->SetPointRepresentation(false);
+    SMESH::RemoveFilters();
+
+    if (myActorsList.count() > 0)
+      for (QListIterator<SMESH_Actor*> it( myActorsList ); it.hasNext(); )
+        it.next()->SetPointRepresentation(false);
     else
       SMESH::SetPointRepresentation(false);
-    if (theMode < 4) {
-      switch (theMode) {
-      case 0:
-        if (myActor)
-         myActor->SetPointRepresentation(true);
-       else
-         SMESH::SetPointRepresentation(true);
-       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-         aViewWindow->SetSelectionMode(NodeSelection);
-       break;
-      case 1:
-       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-         aViewWindow->SetSelectionMode(EdgeSelection);
-       break;
-      case 2:
-       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-         aViewWindow->SetSelectionMode(FaceSelection);
-       break;
-      default:
-       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-         aViewWindow->SetSelectionMode(VolumeSelection);
+
+    switch (theMode) {
+    case grpNodeSelection:
+      if ( myGrpTypeId == 0 ) // standalone
+      {
+        if (myActorsList.count() > 0)
+          for (QListIterator<SMESH_Actor*> it( myActorsList ); it.hasNext(); )
+            it.next()->SetPointRepresentation(true);
+        else
+          SMESH::SetPointRepresentation(true);
+      }
+      if ( aViewWindow ) aViewWindow->SetSelectionMode(isSelectAll ? ActorSelection : NodeSelection);
+      break;
+    case grpEdgeSelection:
+      if ( aViewWindow ) aViewWindow->SetSelectionMode(isSelectAll ? ActorSelection : EdgeSelection);
+      break;
+    case grpBallSelection:
+      //if ( aViewWindow ) aViewWindow->SetSelectionMode(isSelectAll ? ActorSelection : BallSelection);
+      break;
+    case grpFaceSelection:
+      if ( aViewWindow ) aViewWindow->SetSelectionMode(isSelectAll ? ActorSelection : FaceSelection);
+      break;
+    case grpVolumeSelection:
+      if ( aViewWindow ) aViewWindow->SetSelectionMode(isSelectAll ? ActorSelection : VolumeSelection);
+      break;
+    case grpSubMeshSelection: {
+
+      SMESH_TypeFilter* f = 0;
+      switch (myTypeId) {
+      case grpNodeSelection:   f = new SMESH_TypeFilter(SUBMESH); break;
+      case grpEdgeSelection:   f = new SMESH_TypeFilter(SUBMESH_EDGE); break;
+      case grpFaceSelection:   f = new SMESH_TypeFilter(SUBMESH_FACE); break;
+      case grpVolumeSelection: f = new SMESH_TypeFilter(SUBMESH_SOLID); break;
+      default:                 f = new SMESH_TypeFilter(SUBMESH);
+      }
+      QList<SUIT_SelectionFilter*> filtList;
+      filtList.append( f );
+      filtList.append( new SMESH_TypeFilter(SUBMESH_COMPOUND));
+      mySubMeshFilter->setFilters( filtList );
+
+      mySelectionMgr->installFilter( mySubMeshFilter );
+
+      if ( aViewWindow ) aViewWindow->SetSelectionMode(ActorSelection);
+      break;
+    }
+    case grpGroupSelection: {
+
+      SMESH_TypeFilter* f = 0;
+      switch (myTypeId) {
+      case grpNodeSelection:   f = new SMESH_TypeFilter(GROUP_NODE); break;
+      case grpBallSelection:   f = new SMESH_TypeFilter(GROUP_BALL); break;
+      case grpEdgeSelection:   f = new SMESH_TypeFilter(GROUP_EDGE); break;
+      case grpFaceSelection:   f = new SMESH_TypeFilter(GROUP_FACE); break;
+      case grpVolumeSelection: f = new SMESH_TypeFilter(GROUP_VOLUME); break;
+      default:                 f = new SMESH_TypeFilter(GROUP);
       }
-    } else {
-      if (theMode == 4)
-       mySelectionMgr->installFilter(mySubMeshFilter);
-      else if (theMode == 5)
-       mySelectionMgr->installFilter(myGroupFilter);
-      else if (theMode == 6)
-       mySelectionMgr->installFilter(myMeshFilter);
-      else if (theMode == 7)
-       mySelectionMgr->installFilter(myGeomFilter);
-
-      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-       aViewWindow->SetSelectionMode(ActorSelection);
+      QList<SUIT_SelectionFilter*> filtList;
+      filtList.append( f );
+      myGroupFilter->setFilters( filtList );
+
+      mySelectionMgr->installFilter(myGroupFilter);
+      if ( aViewWindow ) aViewWindow->SetSelectionMode(ActorSelection);
+      break;
+    }
+    case grpMeshSelection:
+      mySelectionMgr->installFilter(myMeshFilter);
+      if ( aViewWindow ) aViewWindow->SetSelectionMode(ActorSelection);
+      break;
+    case grpGeomSelection:
+      mySelectionMgr->installFilter(myGeomFilter);
+      if ( aViewWindow ) aViewWindow->SetSelectionMode(ActorSelection);
+      break;
+    default:
+      if ( aViewWindow ) aViewWindow->SetSelectionMode(ActorSelection);
+      break;
     }
+    if ( aViewWindow ) aViewWindow->Repaint();
     mySelectionMode = theMode;
   }
 }
@@ -738,20 +881,40 @@ bool SMESHGUI_GroupDlg::onApply()
   if (myName->text().trimmed().isEmpty())
     return false;
 
-  if (myGrpTypeId == 0) { // on mesh elements
-    if (!myElements->count())
+  SMESH::ElementType aType = SMESH::ALL;
+  switch (myTypeId) {
+  case grpNodeSelection:   aType = SMESH::NODE; break;
+  case grpBallSelection:   aType = SMESH::BALL; break;
+  case grpEdgeSelection:   aType = SMESH::EDGE; break;
+  case grpFaceSelection:   aType = SMESH::FACE; break;
+  case grpVolumeSelection: aType = SMESH::VOLUME; break;
+  }
+
+  bool anIsOk = false;
+  QStringList anEntryList;
+
+  SMESH::SMESH_GroupBase_var resultGroup;
+  bool isCreation;
+    
+  if (myGrpTypeId == 0)  // standalone
+  {
+    if (!mySelectAll->isChecked() && !myElements->count() && myAllowElemsModif->isChecked())
       return false;
 
     mySelectionMgr->clearSelected();
 
     if (myGroup->_is_nil()) { // creation or conversion
       // check if group on geometry is not null
-      if (!CORBA::is_nil(myGroupOnGeom)) {
+      if (!myGroupOnGeom->_is_nil() || !myGroupOnFilter->_is_nil()) {
         if (myMesh->_is_nil())
           return false;
-        myGroup = myMesh->ConvertToStandalone( myGroupOnGeom );
-       // nullify pointer, because object become dead
+        if ( myGroupOnGeom->_is_nil() )
+          myGroup = myMesh->ConvertToStandalone( myGroupOnFilter );
+        else
+          myGroup = myMesh->ConvertToStandalone( myGroupOnGeom );
+
         myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_nil();
+        myGroupOnFilter = SMESH::SMESH_GroupOnFilter::_nil();
       }
     }
 
@@ -759,107 +922,98 @@ bool SMESHGUI_GroupDlg::onApply()
       if (myMesh->_is_nil())
         return false;
 
-      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);
-      for (i = 0; i < k; i++) {
-       anIdList[i] = myElements->item(i)->text().toInt();
-      }
-
       myGroup = SMESH::AddGroup(myMesh, aType, myName->text());
-      myGroup->Add(anIdList.inout());
 
-      SALOMEDS::Color aColor = getGroupColor();
-      myGroup->SetColor(aColor);
+      resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroup );
+      isCreation = true;
 
-      _PTR(SObject) aMeshGroupSO = SMESH::FindSObject(myGroup);
+      if ( mySelectAll->isChecked() ) {
+        // select all
+        myGroup->AddFrom(myMesh.in());
+      }
+      else {
+        // select manually
 
-      //SMESH::setFileName ( aMeshGroupSO, QString::number(myColorSpinBox->value()) );
-      SMESH::setFileType ( aMeshGroupSO, "COULEURGROUP" );
+        if ( !myFilter->_is_nil() &&
+             ( myNbChangesOfContents == 1 || !myAllowElemsModif->isChecked()))
+        {
+          myGroup->AddFrom( myFilter );
+        }
+        else
+        {
+          SMESH::long_array_var anIdList = new SMESH::long_array;
+          int i, k = myElements->count();
+          anIdList->length(k);
+          for (i = 0; i < k; i++) {
+            anIdList[i] = myElements->item(i)->text().toInt();
+          }
+          myGroup->Add(anIdList.inout());
+        }
+      }
 
-      /* init for next operation */
-      myName->setText( "" );
-      myElements->clear();
-      myGroup = SMESH::SMESH_Group::_nil();
 
     } else { // edition
-      myGroup->SetName(myName->text().toLatin1().data());
-
-      SALOMEDS::Color aColor = getGroupColor();
-      myGroup->SetColor(aColor);
-
-      _PTR(SObject) aMeshGroupSO = SMESH::FindSObject(myGroup);
-      if(SMESH_Actor *anActor = SMESH::FindActorByEntry(aMeshGroupSO->GetID().c_str()))
-       anActor->SetSufaceColor( aColor.R, aColor.G, aColor.B );
 
-      QList<int> aAddList;
+      resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroup );
+      isCreation = false;
 
-      int i, total = myElements->count();
-      for (i = 0; i < total; i++) {
-       int anId = myElements->item(i)->text().toInt();
-       int idx = myIdList.indexOf(anId);
-       if ( idx == -1 )
-         aAddList.append(anId);
-       else
-         myIdList.removeAt(idx);
+      if ( mySelectAll->isChecked() ) {
+        // select all
+        myGroup->Clear();
+        myGroup->AddFrom(myMesh.in());
       }
-      if (!aAddList.empty()) {
-       SMESH::long_array_var anIdList = new SMESH::long_array;
-       int added = aAddList.count();
-       anIdList->length(added);
-       for (i = 0; i < added; i++)
-         anIdList[i] = aAddList[i];
-       myGroup->Add(anIdList.inout());
-      }
-      if (!myIdList.empty()) {
-       SMESH::long_array_var anIdList = new SMESH::long_array;
-       int removed = myIdList.count();
-       anIdList->length(removed);
-       for (i = 0; i < removed; i++)
-         anIdList[i] = myIdList[i];
-       myGroup->Remove(anIdList.inout());
-      }
-      /* init for next operation */
-      myIdList.clear();
-      for (i = 0; i < total; i++) {
-       myIdList.append(myElements->item(i)->text().toInt());
+      else {
+        QList<int> aAddList;
+        
+        int i, total = myElements->count();
+        for (i = 0; i < total; i++) {
+          int anId = myElements->item(i)->text().toInt();
+          int idx = myIdList.indexOf(anId);
+          if ( idx == -1 )
+            aAddList.append(anId);
+          else
+            myIdList.removeAt(idx);
+        }
+        if (!aAddList.empty()) {
+          SMESH::long_array_var anIdList = new SMESH::long_array;
+          int added = aAddList.count();
+          anIdList->length(added);
+          for (i = 0; i < added; i++)
+            anIdList[i] = aAddList[i];
+          myGroup->Add(anIdList.inout());
+        }
+        if (!myIdList.empty()) {
+          SMESH::long_array_var anIdList = new SMESH::long_array;
+          int removed = myIdList.count();
+          anIdList->length(removed);
+          for (i = 0; i < removed; i++)
+            anIdList[i] = myIdList[i];
+          myGroup->Remove(anIdList.inout());
+        }
+        /* init for next operation */
+        myIdList.clear();
+        for (i = 0; i < total; i++) {
+          myIdList.append(myElements->item(i)->text().toInt());
+        }
       }
     }
 
-    mySMESHGUI->updateObjBrowser(true);
-    SMESH::UpdateView(); // asv: fix of BUG PAL5515
-    mySelectionMgr->clearSelected();
-    return true;
+    anIsOk = true;
   }
-  else if (myGrpTypeId == 1) { // on geom object
+  else if (myGrpTypeId == 1) // on geom object
+  {
     if (CORBA::is_nil(myGroupOnGeom)) { // creation
       if (myMesh->_is_nil() || !myGeomObjects->length())
         return false;
 
-      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;
-      }
-
       _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
       GEOM::GEOM_IGroupOperations_var aGroupOp =
-       SMESH::GetGEOMGen()->GetIGroupOperations(aStudy->StudyId());
+        SMESH::GetGEOMGen()->GetIGroupOperations(aStudy->StudyId());
 
       if (myGeomObjects->length() == 1) {
-       myGroupOnGeom = myMesh->CreateGroupFromGEOM(aType,
-                                                   myName->text().toLatin1().data(),
-                                                   myGeomObjects[0]);
+        myGroupOnGeom = myMesh->CreateGroupFromGEOM(aType,
+                                                    myName->text().toLatin1().data(),
+                                                    myGeomObjects[0]);
       }
       else {
         SMESH::SMESH_Gen_var aSMESHGen = SMESHGUI::GetSMESHGen();
@@ -901,43 +1055,101 @@ bool SMESHGUI_GroupDlg::onApply()
           aNewGeomGroupName += myName->text();
           SALOMEDS::SObject_var aNewGroupSO =
             geomGen->AddInStudy(aSMESHGen->GetCurrentStudy(), aGroupVar,
-                               aNewGeomGroupName.toLatin1().data(), aMeshShape);
+                                aNewGeomGroupName.toLatin1().data(), aMeshShape);
         }
 
         myGroupOnGeom = myMesh->CreateGroupFromGEOM(aType,
-                                                   myName->text().toLatin1().data(),
-                                                   aGroupVar);
+                                                    myName->text().toLatin1().data(),
+                                                    aGroupVar);
       }
+      resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroupOnGeom );
+      isCreation = true;
+
+    }
+    else { // edition
+
+      resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroupOnGeom );
+      isCreation = false;
+    }      
+    anIsOk = true;
+  }
+  if (myGrpTypeId == 2) // group on filter
+  {
+    if ( myFilter->_is_nil() ) return false;
 
-      SALOMEDS::Color aColor = getGroupColor();
-      myGroupOnGeom->SetColor(aColor);
+    if (CORBA::is_nil(myGroupOnFilter)) { // creation
+      if (myMesh->_is_nil())
+        return false;
 
-      _PTR(SObject) aMeshGroupSO = SMESH::FindSObject(myGroupOnGeom);
+      myGroupOnFilter = myMesh->CreateGroupFromFilter(aType,
+                                                      myName->text().toLatin1().data(),
+                                                      myFilter);
 
-      //SMESH::setFileName ( aMeshGroupSO, QString::number(myColorSpinBox->value()) );
-      SMESH::setFileType ( aMeshGroupSO,"COULEURGROUP" );
+      resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroupOnFilter );
+      isCreation = true;
+    }
+    else
+    {
+      myGroupOnFilter->SetFilter( myFilter );
 
-      /* init for next operation */
-      myName->setText( "" );
-      myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_nil();
+      resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroupOnFilter );
+      isCreation = false;
     }
-    else { // edition
-      myGroupOnGeom->SetName(myName->text().toLatin1().data());
+    anIsOk = true;
+  }
+
+  if( anIsOk )
+  {
+    SALOMEDS::Color aColor = getGroupColor();
+    resultGroup->SetColor(aColor);
 
-      SALOMEDS::Color aColor = getGroupColor();
-      myGroupOnGeom->SetColor(aColor);
+    _PTR(SObject) aMeshGroupSO = SMESH::FindSObject( resultGroup );
+    if( aMeshGroupSO )
+      anEntryList.append( aMeshGroupSO->GetID().c_str() );
 
-      _PTR(SObject) aMeshGroupSO = SMESH::FindSObject(myGroupOnGeom);
-      if(SMESH_Actor *anActor = SMESH::FindActorByEntry(aMeshGroupSO->GetID().c_str()))
-       anActor->SetSufaceColor( aColor.R, aColor.G, aColor.B );
-    }
+    if ( isCreation )
+    {
+      SMESH::setFileType ( aMeshGroupSO, "COULEURGROUP" );
 
+      /* init for the next operation */
+      myName->setText( "" );
+      myElements->clear();
+      myGroup         = SMESH::SMESH_Group::_nil();
+      myGroupOnGeom   = SMESH::SMESH_GroupOnGeom::_nil();
+      myGroupOnFilter = SMESH::SMESH_GroupOnFilter::_nil();
+      myFilter        = SMESH::Filter::_nil();
+    }
+    else
+    {
+      resultGroup->SetName(myName->text().toLatin1().data());
+
+      if ( aMeshGroupSO )
+        if(SMESH_Actor *anActor = SMESH::FindActorByEntry(aMeshGroupSO->GetID().c_str())) {
+          anActor->setName(myName->text().toLatin1().data());
+          switch ( myTypeId ) {
+          case grpNodeSelection:   anActor->SetNodeColor( aColor.R, aColor.G, aColor.B ); break;
+          case grpBallSelection:   anActor->SetBallColor( aColor.R, aColor.G, aColor.B ); break;
+          case grpEdgeSelection:   anActor->SetEdgeColor( aColor.R, aColor.G, aColor.B ); break;
+          case grpFaceSelection:   
+          case grpVolumeSelection: 
+          default:
+              QColor c;
+              int delta;
+              SMESH::GetColor("SMESH", "fill_color", c , delta, "0,170,255|-100");
+              anActor->SetSufaceColor( aColor.R, aColor.G, aColor.B, delta ); break;          
+          }
+        }
+    }
+    SMESHGUI::Modified();
     mySMESHGUI->updateObjBrowser(true);
+    SMESH::UpdateView(); // asv: fix of BUG PAL5515
     mySelectionMgr->clearSelected();
-    return true;
-  }
 
-  return false;
+    if( LightApp_Application* anApp =
+        dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
+      myObjectToSelect = anApp->browseObjects( anEntryList, isApplyAndClose() );
+  }
+  return anIsOk;
 }
 
 //=================================================================================
@@ -946,8 +1158,10 @@ bool SMESHGUI_GroupDlg::onApply()
 //=================================================================================
 void SMESHGUI_GroupDlg::onOK()
 {
+  setIsApplyAndClose( true );
   if ( onApply() )
     onClose();
+  setIsApplyAndClose( false );
 }
 
 //=================================================================================
@@ -956,9 +1170,9 @@ void SMESHGUI_GroupDlg::onOK()
 //=================================================================================
 void SMESHGUI_GroupDlg::onListSelectionChanged()
 {
-  //  MESSAGE( "SMESHGUI_GroupDlg::onListSelectionChanged(); myActor = " << myActor);
-  if( myIsBusy || !myActor) return;
-    myIsBusy = true;
+  //MESSAGE( "SMESHGUI_GroupDlg::onListSelectionChanged(); myActorsList.count() = " << myActorsList.count());
+  if( myIsBusy || myActorsList.count() == 0 ) return;
+  myIsBusy = true;
 
   if (myCurrentLineEdit == 0) {
     mySelectionMgr->clearSelected();
@@ -966,9 +1180,9 @@ void SMESHGUI_GroupDlg::onListSelectionChanged()
     QList<QListWidgetItem*> selItems = myElements->selectedItems();
     QListWidgetItem* anItem;
     foreach(anItem, selItems) aIndexes.Add(anItem->text().toInt());
-    mySelector->AddOrRemoveIndex(myActor->getIO(), aIndexes, false);
+    mySelector->AddOrRemoveIndex(myActorsList.first()->getIO(), aIndexes, false);
     SALOME_ListIO aList;
-    aList.Append(myActor->getIO());
+    aList.Append(myActorsList.first()->getIO());
     mySelectionMgr->setSelectedObjects(aList,false);
   }
   myIsBusy = false;
@@ -1010,7 +1224,7 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged()
       myGeomObjects->length(0);
 
       if (myGeomGroupBtn->isChecked())
-       myGeomGroupBtn->setChecked(false);
+        myGeomGroupBtn->setChecked(false);
       if (!myCreate)
         myName->setText( "" );
 
@@ -1029,16 +1243,20 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged()
       Handle(SALOME_InteractiveObject) IO = aList.First();
 
       if (myCreate) {
-       restoreShowEntityMode();
-       myMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IO);
+        restoreShowEntityMode();
+        myMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IO);
         setShowEntityMode();
         updateGeomPopup();
         if (myMesh->_is_nil())
-       {
+        {
           updateButtons();
-         myIsBusy = false;
-         return;
-       }
+          myIsBusy = false;
+          return;
+        }
+
+        if ( myFilterDlg && !myMesh->_is_nil()){
+          myFilterDlg->SetMesh( myMesh );
+        }
         myGroup = SMESH::SMESH_Group::_nil();
 
         // NPAL19389: create a group with a selection in another group
@@ -1059,15 +1277,14 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged()
       else {
         SMESH::SMESH_GroupBase_var aGroup = SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(IO);
         if (aGroup->_is_nil())
-       {
-         myIsBusy = false;
+        {
+          myIsBusy = false;
           return;
-       }
+        }
         myIsBusy = false;
-        myCurrentLineEdit = 0;
 
-       myGroup = SMESH::SMESH_Group::_nil();
-       myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_nil();
+        myGroup = SMESH::SMESH_Group::_nil();
+        myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_nil();
 
         init(aGroup);
         myIsBusy = true;
@@ -1081,13 +1298,13 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged()
 
       if (myGrpTypeId == 0)
       {
-       if (myTypeId == -1)
-         onTypeChanged(0);
-       else
-       {
-         myElements->clear();
-         setSelectionMode(myTypeId);
-       }
+        if (myTypeId == -1)
+          onTypeChanged(0);
+        else
+        {
+          myElements->clear();
+          setSelectionMode(myTypeId);
+        }
       }
 
       myIsBusy = false;
@@ -1103,26 +1320,24 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged()
 
       if (aNbSel == 0 || !aMeshSO)
       {
-       myGeomObjects->length(0);
-       updateButtons();
-       myIsBusy = false;
-       return;
+        myGeomObjects->length(0);
+        updateButtons();
+        myIsBusy = false;
+        return;
       }
 
       myGeomObjects->length(aNbSel);
 
       GEOM::GEOM_Object_var aGeomGroup;
-      Standard_Boolean testResult;
       int i = 0;
 
       SALOME_ListIteratorOfListIO anIt (aList);
       for (; anIt.More(); anIt.Next())
       {
-        testResult = Standard_False;
-        aGeomGroup = GEOMBase::ConvertIOinGEOMObject(anIt.Value(), testResult);
+        aGeomGroup = GEOMBase::ConvertIOinGEOMObject(anIt.Value());
 
         // Check if the object is a geometry group
-        if (!testResult || CORBA::is_nil(aGeomGroup))
+        if (CORBA::is_nil(aGeomGroup))
           continue;
 
         // Check if group constructed on the same shape as a mesh or on its child
@@ -1137,21 +1352,17 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged()
         else
           aGroupMainShape = GEOM::GEOM_Object::_duplicate(aGeomGroup);
         _PTR(SObject) aGroupMainShapeSO =
-          //aStudy->FindObjectIOR(aStudy->ConvertObjectToIOR(aGroupMainShape));
           aStudy->FindObjectID(aGroupMainShape->GetStudyEntry());
 
         _PTR(SObject) anObj, aRef;
         bool isRefOrSubShape = false;
         if (aMeshSO->FindSubObject(1, anObj) &&  anObj->ReferencedObject(aRef)) {
-          //if (strcmp(aRef->GetID(), aGroupMainShapeSO->GetID()) == 0) {
           if (aRef->GetID() == aGroupMainShapeSO->GetID()) {
             isRefOrSubShape = true;
           } else {
             _PTR(SObject) aFather = aGroupMainShapeSO->GetFather();
             _PTR(SComponent) aComponent = aGroupMainShapeSO->GetFatherComponent();
-            //while (!isRefOrSubShape && strcmp(aFather->GetID(), aComponent->GetID()) != 0) {
             while (!isRefOrSubShape && aFather->GetID() != aComponent->GetID()) {
-              //if (strcmp(aRef->GetID(), aFather->GetID()) == 0)
               if (aRef->GetID() == aFather->GetID())
                 isRefOrSubShape = true;
               else
@@ -1165,10 +1376,10 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged()
 
       myGeomObjects->length(i);
       if ( i == 0 )
-       {
-         myIsBusy = false;
-         return;
-       }
+        {
+          myIsBusy = false;
+          return;
+        }
 
       aNbSel = i;
     }
@@ -1202,13 +1413,12 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged()
   }
   else // !myCurrentLineEdit: local selection of nodes or elements
   {
-    if (aNbSel == 1 && myActor && myActor->hasIO())
+    if (aNbSel == 1 && myActorsList.count() > 0 )
     {
-#ifdef ENABLE_SWITCH_ACTOR_DURING_ELEMENTS_SELECTION
       // NPAL19389: create a group with a selection in another group
       // Switch myActor to the newly selected one, if the last
       // is visible and belongs to group or submesh of myMesh
-      Handle(SALOME_InteractiveObject) curIO = myActor->getIO();
+      /*      Handle(SALOME_InteractiveObject) curIO = myActor->getIO();
       Handle(SALOME_InteractiveObject) selIO = aList.First();
       if (curIO->hasEntry() && selIO->hasEntry()) {
         const char* selEntry = selIO->getEntry();
@@ -1235,54 +1445,101 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged()
             }
           }
         }
-      }
+      }*/
       // NPAL19389 END
-#endif // ENABLE_SWITCH_ACTOR_DURING_ELEMENTS_SELECTION
 
       QString aListStr = "";
       int aNbItems = 0;
       if (myTypeId == 0) {
-       aNbItems = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aListStr);
+        QListIterator<SMESH_Actor*> it( myActorsList );
+        while ( it.hasNext() ) {
+          QString tmpStr;
+          aNbItems += SMESH::GetNameOfSelectedNodes(mySelector, it.next()->getIO(), tmpStr);
+          aListStr += tmpStr;
+        }
       } else {
-       aNbItems = SMESH::GetNameOfSelectedElements(mySelector, myActor->getIO(), aListStr);
+        QListIterator<SMESH_Actor*> it( myActorsList );
+        while ( it.hasNext() ) {
+          QString tmpStr;
+          aNbItems += SMESH::GetNameOfSelectedElements(mySelector, it.next()->getIO(), tmpStr);
+          aListStr += tmpStr;
+        }
       }
       if (aNbItems > 0) {
-       QListWidgetItem* anItem;
-       QList<QListWidgetItem*> listItemsToSel;
-       QStringList anElements = aListStr.split( " ", QString::SkipEmptyParts);
-       for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) {
-         QList<QListWidgetItem*> found = myElements->findItems(*it, Qt::MatchExactly);
-         foreach(anItem, found)
-           if (!anItem->isSelected())
-             listItemsToSel.push_back(anItem);
-       }
-       bool blocked = myElements->signalsBlocked();
-       myElements->blockSignals(true);
-       foreach(anItem, listItemsToSel) anItem->setSelected(true);
-       myElements->blockSignals(blocked);
-       onListSelectionChanged();
-       listItemsToSel.clear();
+        QListWidgetItem* anItem;
+        QList<QListWidgetItem*> listItemsToSel;
+        QStringList anElements = aListStr.split( " ", QString::SkipEmptyParts);
+        for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) {
+          QList<QListWidgetItem*> found = myElements->findItems(*it, Qt::MatchExactly);
+          foreach(anItem, found)
+            if (!anItem->isSelected())
+              listItemsToSel.push_back(anItem);
+        }
+        bool blocked = myElements->signalsBlocked();
+        myElements->blockSignals(true);
+        foreach(anItem, listItemsToSel) anItem->setSelected(true);
+        myElements->blockSignals(blocked);
+        onListSelectionChanged();
+        listItemsToSel.clear();
       }
     }
   }
-
-  if (!myActor) {
-    if (!myGroup->_is_nil())
-      myActor = SMESH::FindActorByObject(myGroup);
-    else if(!myGroupOnGeom->_is_nil())
-      myActor = SMESH::FindActorByObject(myGroupOnGeom);
-    else
-      myActor = SMESH::FindActorByObject(myMesh);
+  
+  if (myActorsList.count() == 0) {
+    if (!myGroup->_is_nil()) {
+      SMESH_Actor* anActor = SMESH::FindActorByObject(myGroup);
+      if ( anActor )
+        myActorsList.append( anActor  );
+    }
+    else if(!myGroupOnGeom->_is_nil()) {
+      SMESH_Actor* anActor = SMESH::FindActorByObject(myGroupOnGeom);
+      if ( anActor )
+        myActorsList.append( anActor );
+    }
+    else {
+      SMESH_Actor* anActor = SMESH::FindActorByObject( myMesh );
+      if ( anActor )
+        myActorsList.append( anActor );
+    }
   }
 
   // somehow, if we display the mesh, while selecting from another actor,
   // the mesh becomes pickable, and there is no way to select any element
-  if (myActor)
-    SMESH::SetPickable(myActor);
+  if (myActorsList.count() > 0) {
+    QListIterator<SMESH_Actor*> it( myActorsList );
+    while ( it.hasNext() ) {
+      SMESH_Actor* anActor = it.next();
+      if ( IsActorVisible(anActor) )
+        anActor->SetPickable(true);
+    }
+  }
 
   myIsBusy = false;
 }
 
+//=================================================================================
+// function : onSelectAll()
+// purpose  : Called when "Select all" is checked
+//=================================================================================
+void SMESHGUI_GroupDlg::onSelectAll()
+{
+  bool noElemsModif = ( mySelectAll->isChecked() || !myAllowElemsModif->isChecked() );
+
+  myElementsLab->setEnabled( !noElemsModif );
+  myElements->setEnabled   ( !noElemsModif );
+  myFilterBtn->setEnabled  ( !mySelectAll->isChecked() );
+  myAddBtn->setEnabled     ( !noElemsModif );
+  myRemoveBtn->setEnabled  ( !noElemsModif );
+  mySortBtn->setEnabled    ( !noElemsModif );
+  mySelectBox->setEnabled  ( !noElemsModif );
+  myAllowElemsModif->setEnabled( !mySelectAll->isChecked() );
+
+  int selMode     = mySelectionMode;
+  mySelectionMode = grpNoSelection;
+  setSelectionMode( selMode );
+  updateButtons();
+}
+
 //=================================================================================
 // function : onSelectSubMesh()
 // purpose  : Called when selection in 3D view or ObjectBrowser is changed
@@ -1297,7 +1554,7 @@ void SMESHGUI_GroupDlg::onSelectSubMesh(bool on)
     //VSR:   mySelectGeomGroup->setChecked(false);
     //VSR: }
     myCurrentLineEdit = mySubMeshLine;
-    setSelectionMode(4);
+    setSelectionMode(grpSubMeshSelection);
   }
   else {
     mySubMeshLine->setText( "" );
@@ -1321,7 +1578,7 @@ void SMESHGUI_GroupDlg::onSelectGroup(bool on)
       mySelectSubMesh->setChecked(false);
     }
     myCurrentLineEdit = myGroupLine;
-    setSelectionMode(5);
+    setSelectionMode(grpGroupSelection);
   }
   else {
     myGroupLine->setText( "" );
@@ -1336,7 +1593,7 @@ void SMESHGUI_GroupDlg::onSelectGroup(bool on)
 
 //=================================================================================
 // function : (onSelectGeomGroup)
-// purpose  : Called when selection in 3D view or ObjectBrowser is changed
+// purpose  : Called when group type changed. on == "on group" or "on filter"
 //=================================================================================
 void SMESHGUI_GroupDlg::onSelectGeomGroup(bool on)
 {
@@ -1347,9 +1604,14 @@ void SMESHGUI_GroupDlg::onSelectGeomGroup(bool on)
     else if (mySelectGroup->isChecked()) {
       mySelectGroup->setChecked(false);
     }
-    myCurrentLineEdit = myGeomGroupLine;
-    updateGeomPopup();
-    setSelectionMode(8);
+    if ( myGrpTypeId == 1 ) { // on group
+      myCurrentLineEdit = myGeomGroupLine;
+      updateGeomPopup();
+    }
+    else { // on filter
+      myCurrentLineEdit = 0;
+    }
+    setSelectionMode(grpAllSelection);
   }
   else {
     myGeomGroupBtn->setChecked(false);
@@ -1357,11 +1619,10 @@ void SMESHGUI_GroupDlg::onSelectGeomGroup(bool on)
     myGeomGroupLine->setText( "" );
     myCurrentLineEdit = 0;
     if (myTypeId != -1)
-      setSelectionMode(myTypeId);
+      setSelectionMode( myTypeId );
   }
 }
 
-
 //=================================================================================
 // function : setCurrentSelection()
 // purpose  :
@@ -1371,11 +1632,14 @@ void SMESHGUI_GroupDlg::setCurrentSelection()
   QPushButton* send = (QPushButton*)sender();
   myCurrentLineEdit = 0;
   if (send == myMeshGroupBtn) {
-    myCurrentLineEdit = myMeshGroupLine;
+    disconnect(myMeshGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection()));
+    mySelectionMgr->clearSelected();
     if (myCreate)
-      setSelectionMode(6);
+      setSelectionMode(grpMeshSelection);
     else
-      setSelectionMode(5);
+      setSelectionMode(grpGroupSelection);
+    connect(myMeshGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection()));
+    myCurrentLineEdit = myMeshGroupLine;
     onObjectSelectionChanged();
   }
   else if (send == mySubMeshBtn) {
@@ -1395,14 +1659,22 @@ void SMESHGUI_GroupDlg::setCurrentSelection()
 //=================================================================================
 void SMESHGUI_GroupDlg::setFilters()
 {
+  if(myMesh->_is_nil()) {
+    SUIT_MessageBox::critical(this,
+                              tr("SMESH_ERROR"),
+                              tr("NO_MESH_SELECTED"));
+   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;
-    default: return;
+    case grpNodeSelection:   aType = SMESH::NODE; break;
+    case grpBallSelection:   aType = SMESH::BALL; break;
+    case grpEdgeSelection:   aType = SMESH::EDGE; break;
+    case grpFaceSelection:   aType = SMESH::FACE; break;
+    case grpVolumeSelection: aType = SMESH::VOLUME; break;
+    default:                 return;
   }
 
   if ( myFilterDlg == 0 )
@@ -1413,9 +1685,15 @@ void SMESHGUI_GroupDlg::setFilters()
   else
     myFilterDlg->Init( aType );
 
+  if ( !myGroupOnFilter->_is_nil() )
+  {
+    myFilterDlg->SetFilter( myFilter, aType );
+    myFilterDlg->Init( aType );
+  }
+
   myFilterDlg->SetSelection();
   myFilterDlg->SetMesh( myMesh );
-  myFilterDlg->SetSourceWg( myElements );
+  myFilterDlg->SetSourceWg( myElements, false );
 
   myFilterDlg->show();
 }
@@ -1433,6 +1711,28 @@ void SMESHGUI_GroupDlg::onFilterAccepted()
     mySelectSubMesh->setChecked( false );
     mySelectGroup->setChecked( false );
   }
+  // get a filter from myFilterDlg
+  myFilter = myFilterDlg->GetFilter();
+  if ( !myFilter->_is_nil() ) {
+    SMESH::Predicate_var perdicate = myFilter->GetPredicate();
+    if ( perdicate->_is_nil() )
+      myFilter = SMESH::Filter::_nil();
+  }
+  // set mesh to myFilter
+  if ( !myFilter->_is_nil() ) {
+    SMESH::SMESH_Mesh_var mesh = myMesh;
+    if ( mesh->_is_nil() ) {
+      if ( !myGroup->_is_nil() )
+        mesh = myGroup->GetMesh();
+      else if ( !myGroupOnGeom->_is_nil() )
+        mesh = myGroupOnGeom->GetMesh();
+      else if ( !myGroupOnFilter->_is_nil() )
+        mesh = myGroupOnFilter->GetMesh();
+    }
+    myFilter->SetMesh( mesh );
+  }
+
+  updateButtons();
 }
 
 //=================================================================================
@@ -1446,25 +1746,30 @@ void SMESHGUI_GroupDlg::onAdd()
 
   int aNbSel = aList.Extent();
 
-  if (aNbSel == 0 || !myActor || myMesh->_is_nil()) return;
+  if (aNbSel == 0 || myActorsList.count() == 0 || myMesh->_is_nil()) return;
 
   myIsBusy = true;
+  int sizeBefore = myElements->count();
 
   SMESH::ElementType aType = SMESH::ALL;
   switch(myTypeId) {
-  case 0:
+  case grpNodeSelection:
     aType = SMESH::NODE;
     mySelector->SetSelectionMode(NodeSelection);
     break;
-  case 1:
+  case grpBallSelection:
+    aType = SMESH::BALL;
+    //mySelector->SetSelectionMode(BallSelection);
+    break;
+  case grpEdgeSelection:
     aType = SMESH::EDGE;
     mySelector->SetSelectionMode(EdgeSelection);
     break;
-  case 2:
+  case grpFaceSelection:
     aType = SMESH::FACE;
     mySelector->SetSelectionMode(FaceSelection);
     break;
-  case 3:
+  case grpVolumeSelection:
     aType = SMESH::VOLUME;
     mySelector->SetSelectionMode(VolumeSelection);
     break;
@@ -1480,26 +1785,36 @@ void SMESHGUI_GroupDlg::onAdd()
     QString aListStr = "";
     int aNbItems = 0;
     if (myTypeId == 0) {
-      aNbItems = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aListStr);
+      QListIterator<SMESH_Actor*> it( myActorsList );
+      while ( it.hasNext() ) {
+        QString tmpStr;
+        aNbItems += SMESH::GetNameOfSelectedNodes(mySelector, it.next()->getIO(), tmpStr);
+        aListStr += tmpStr;
+      }
     }
     else {
-      aNbItems = SMESH::GetNameOfSelectedElements(mySelector, myActor->getIO(), aListStr);
+      QListIterator<SMESH_Actor*> it( myActorsList );
+      while ( it.hasNext() ) {
+        QString tmpStr;
+        aNbItems += SMESH::GetNameOfSelectedElements(mySelector, it.next()->getIO(), tmpStr);
+        aListStr += tmpStr;
+      }
     }
     if (aNbItems > 0) {
       QStringList anElements = aListStr.split( " ", QString::SkipEmptyParts);
       for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) {
-       QList<QListWidgetItem*> found = myElements->findItems(*it, Qt::MatchExactly);
-       if (found.count() == 0) {
-         anItem = new QListWidgetItem(*it);
-         myElements->addItem(anItem);
-         if (!anItem->isSelected())
-           listItemsToSel.push_back(anItem);
-       }
-       else {
-         foreach(anItem, found)
-           if (!anItem->isSelected())
-             listItemsToSel.push_back(anItem);
-       }
+        QList<QListWidgetItem*> found = myElements->findItems(*it, Qt::MatchExactly);
+        if (found.count() == 0) {
+          anItem = new QListWidgetItem(*it);
+          myElements->addItem(anItem);
+          if (!anItem->isSelected())
+            listItemsToSel.push_back(anItem);
+        }
+        else {
+          foreach(anItem, found)
+            if (!anItem->isSelected())
+              listItemsToSel.push_back(anItem);
+        }
       }
       bool blocked = myElements->signalsBlocked();
       myElements->blockSignals(true);
@@ -1519,8 +1834,8 @@ void SMESHGUI_GroupDlg::onAdd()
       SMESH::SMESH_subMesh_var aSubMesh =
         SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(anIt.Value());
       if (!aSubMesh->_is_nil()) {
-       // check if mesh is the same
-       if (aSubMesh->GetFather()->GetId() == myMesh->GetId()) {
+        // check if mesh is the same
+        if (aSubMesh->GetFather()->GetId() == myMesh->GetId()) {
           try {
             SMESH::long_array_var anElements = aSubMesh->GetElementsByType(aType);
             int k = anElements->length();
@@ -1530,21 +1845,21 @@ void SMESHGUI_GroupDlg::onAdd()
               if (found.count() == 0) {
                 anItem = new QListWidgetItem(aText);
                 myElements->addItem(anItem);
-               if (!anItem->isSelected())
-                 listItemsToSel.push_back(anItem);
+                if (!anItem->isSelected())
+                  listItemsToSel.push_back(anItem);
+              }
+              else {
+                foreach(anItem, found)
+                  if (!anItem->isSelected())
+                    listItemsToSel.push_back(anItem);
               }
-             else {
-               foreach(anItem, found)
-                 if (!anItem->isSelected())
-                   listItemsToSel.push_back(anItem);
-             }
             }
-           bool blocked = myElements->signalsBlocked();
-           myElements->blockSignals(true);
-           foreach(anItem, listItemsToSel) anItem->setSelected(true);
-           myElements->blockSignals(blocked);
-           onListSelectionChanged();
-           listItemsToSel.clear();
+            bool blocked = myElements->signalsBlocked();
+            myElements->blockSignals(true);
+            foreach(anItem, listItemsToSel) anItem->setSelected(true);
+            myElements->blockSignals(blocked);
+            onListSelectionChanged();
+            listItemsToSel.clear();
           }
           catch (const SALOME::SALOME_Exception& ex) {
             SalomeApp_Tools::QtCatchCorbaException(ex);
@@ -1566,32 +1881,32 @@ void SMESHGUI_GroupDlg::onAdd()
       SMESH::SMESH_GroupBase_var aGroup =
         SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(anIt.Value());
       if (!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();
-         for (int i = 0; i < k; i++) {
-           QString aText = QString::number(anElements[i]);
-           QList<QListWidgetItem*> found = myElements->findItems(aText, Qt::MatchExactly);
-           if (found.count() == 0) {
-             anItem = new QListWidgetItem(aText);
-             myElements->addItem(anItem);
-             if (!anItem->isSelected())
-               listItemsToSel.push_back(anItem);
-           }
-           else {
-             foreach(anItem, found)
-               if (!anItem->isSelected())
-                 listItemsToSel.push_back(anItem);
-           }
-         }
-         bool blocked = myElements->signalsBlocked();
-         myElements->blockSignals(true);
-         foreach(anItem, listItemsToSel) anItem->setSelected(true);
-         myElements->blockSignals(blocked);
-         onListSelectionChanged();
-         listItemsToSel.clear();
-       }
+        // 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();
+          for (int i = 0; i < k; i++) {
+            QString aText = QString::number(anElements[i]);
+            QList<QListWidgetItem*> found = myElements->findItems(aText, Qt::MatchExactly);
+            if (found.count() == 0) {
+              anItem = new QListWidgetItem(aText);
+              myElements->addItem(anItem);
+              if (!anItem->isSelected())
+                listItemsToSel.push_back(anItem);
+            }
+            else {
+              foreach(anItem, found)
+                if (!anItem->isSelected())
+                  listItemsToSel.push_back(anItem);
+            }
+          }
+          bool blocked = myElements->signalsBlocked();
+          myElements->blockSignals(true);
+          foreach(anItem, listItemsToSel) anItem->setSelected(true);
+          myElements->blockSignals(blocked);
+          onListSelectionChanged();
+          listItemsToSel.clear();
+        }
       }
     }
     mySelectGroup->setChecked(false);
@@ -1605,10 +1920,10 @@ void SMESHGUI_GroupDlg::onAdd()
 
     SMESH::ElementType aGroupType = SMESH::ALL;
     switch(aGroupOp->GetType(myGeomObjects[0])) {
-    case 7: aGroupType = SMESH::NODE; break;
-    case 6: aGroupType = SMESH::EDGE; break;
-    case 4: aGroupType = SMESH::FACE; break;
-    case 2: aGroupType = SMESH::VOLUME; break;
+    case TopAbs_VERTEX: aGroupType = SMESH::NODE; break;
+    case TopAbs_EDGE:   aGroupType = SMESH::EDGE; break;
+    case TopAbs_FACE:   aGroupType = SMESH::FACE; break;
+    case TopAbs_SOLID:  aGroupType = SMESH::VOLUME; break;
     default: myIsBusy = false; return;
     }
 
@@ -1619,7 +1934,7 @@ void SMESHGUI_GroupDlg::onAdd()
       // Construct filter
       SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
       SMESH::Filter_var aFilter = aFilterMgr->CreateFilter();
-      SMESH::BelongToGeom_var aBelongToGeom = aFilterMgr->CreateBelongToGeom();;
+      SMESH::BelongToGeom_var aBelongToGeom = aFilterMgr->CreateBelongToGeom();
       aBelongToGeom->SetGeom(myGeomObjects[0]);
       aBelongToGeom->SetShapeName(aGroupSO->GetName().c_str());
       aBelongToGeom->SetElementType(aType);
@@ -1629,19 +1944,19 @@ void SMESHGUI_GroupDlg::onAdd()
 
       int k = anElements->length();
       for (int i = 0; i < k; i++) {
-       QString aText = QString::number(anElements[i]);
-       QList<QListWidgetItem*> found = myElements->findItems(aText, Qt::MatchExactly);
-       if (found.count() == 0) {
-         anItem = new QListWidgetItem(aText);
-         myElements->addItem(anItem);
-         if (!anItem->isSelected())
-           listItemsToSel.push_back(anItem);
-       }
-       else {
-         foreach(anItem, found)
-           if (!anItem->isSelected())
-             listItemsToSel.push_back(anItem);
-       }
+        QString aText = QString::number(anElements[i]);
+        QList<QListWidgetItem*> found = myElements->findItems(aText, Qt::MatchExactly);
+        if (found.count() == 0) {
+          anItem = new QListWidgetItem(aText);
+          myElements->addItem(anItem);
+          if (!anItem->isSelected())
+            listItemsToSel.push_back(anItem);
+        }
+        else {
+          foreach(anItem, found)
+            if (!anItem->isSelected())
+              listItemsToSel.push_back(anItem);
+        }
       }
       bool blocked = myElements->signalsBlocked();
       myElements->blockSignals(true);
@@ -1656,6 +1971,8 @@ void SMESHGUI_GroupDlg::onAdd()
     onListSelectionChanged();
   }
   myIsBusy = false;
+  if ( sizeBefore < myElements->count() )
+    ++myNbChangesOfContents;
   //  mySelectionMgr->clearSelected();
   updateButtons();
 }
@@ -1667,6 +1984,8 @@ void SMESHGUI_GroupDlg::onAdd()
 void SMESHGUI_GroupDlg::onRemove()
 {
   myIsBusy = true;
+  int sizeBefore = myElements->count();
+
   if (myCurrentLineEdit == 0) {
     QList<QListWidgetItem*> selItems = myElements->selectedItems();
     QListWidgetItem* item;
@@ -1681,10 +2000,11 @@ void SMESHGUI_GroupDlg::onRemove()
 
     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;
+    case grpNodeSelection:   aType = SMESH::NODE; break;
+    case grpBallSelection:   aType = SMESH::BALL; break;
+    case grpEdgeSelection:   aType = SMESH::EDGE; break;
+    case grpFaceSelection:   aType = SMESH::FACE; break;
+    case grpVolumeSelection: aType = SMESH::VOLUME; break;
     }
 
     if (myCurrentLineEdit == mySubMeshLine) {
@@ -1694,42 +2014,42 @@ void SMESHGUI_GroupDlg::onRemove()
 
       SALOME_ListIteratorOfListIO anIt (aList);
       for ( ; anIt.More(); anIt.Next()) {
-       SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(anIt.Value());
-       if (!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();
-               for (int i = 0; i < k; i++) {
-                 QList<QListWidgetItem*> found = 
-                   myElements->findItems(QString::number(anElements[i]), Qt::MatchExactly);
-                 QListWidgetItem* anItem;
-                 foreach(anItem, found) delete anItem;
-               }
-             }
-             catch (const SALOME::SALOME_Exception& ex) {
-               SalomeApp_Tools::QtCatchCorbaException(ex);
-             }
-           }
-           else {
-             try {
-               SMESH::long_array_var anElements = aSubMesh->GetElementsId();
-               int k = anElements->length();
-               for (int i = 0; i < k; i++) {
-                 QList<QListWidgetItem*> found = 
-                   myElements->findItems(QString::number(anElements[i]), Qt::MatchExactly);
-                 QListWidgetItem* anItem;
-                 foreach(anItem, found) delete anItem;
-               }
-             }
-             catch (const SALOME::SALOME_Exception& ex) {
-               SalomeApp_Tools::QtCatchCorbaException(ex);
-             }
-           }
-         }
-       }
+        SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(anIt.Value());
+        if (!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();
+                for (int i = 0; i < k; i++) {
+                  QList<QListWidgetItem*> found = 
+                    myElements->findItems(QString::number(anElements[i]), Qt::MatchExactly);
+                  QListWidgetItem* anItem;
+                  foreach(anItem, found) delete anItem;
+                }
+              }
+              catch (const SALOME::SALOME_Exception& ex) {
+                SalomeApp_Tools::QtCatchCorbaException(ex);
+              }
+            }
+            else {
+              try {
+                SMESH::long_array_var anElements = aSubMesh->GetElementsId();
+                int k = anElements->length();
+                for (int i = 0; i < k; i++) {
+                  QList<QListWidgetItem*> found = 
+                    myElements->findItems(QString::number(anElements[i]), Qt::MatchExactly);
+                  QListWidgetItem* anItem;
+                  foreach(anItem, found) delete anItem;
+                }
+              }
+              catch (const SALOME::SALOME_Exception& ex) {
+                SalomeApp_Tools::QtCatchCorbaException(ex);
+              }
+            }
+          }
+        }
       }
     }
     else if (myCurrentLineEdit == myGroupLine) {
@@ -1740,24 +2060,26 @@ void SMESHGUI_GroupDlg::onRemove()
 
       SALOME_ListIteratorOfListIO anIt (aList);
       for ( ; anIt.More(); anIt.Next()) {
-       SMESH::SMESH_Group_var aGroup = SMESH::IObjectToInterface<SMESH::SMESH_Group>(anIt.Value());
-       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();
-           for (int i = 0; i < k; i++) {
-             QList<QListWidgetItem*> found = 
-               myElements->findItems(QString::number(anElements[i]), Qt::MatchExactly);
-             QListWidgetItem* anItem;
-             foreach(anItem, found) delete anItem;
-           }
-         }
-       }
+        SMESH::SMESH_Group_var aGroup = SMESH::IObjectToInterface<SMESH::SMESH_Group>(anIt.Value());
+        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();
+            for (int i = 0; i < k; i++) {
+              QList<QListWidgetItem*> found = 
+                myElements->findItems(QString::number(anElements[i]), Qt::MatchExactly);
+              QListWidgetItem* anItem;
+              foreach(anItem, found) delete anItem;
+            }
+          }
+        }
       }
     }
   }
   myIsBusy = false;
+  if ( sizeBefore > myElements->count() )
+    myNbChangesOfContents += 2; // it's used to detect that "Add" was only once
   updateButtons();
 }
 
@@ -1781,7 +2103,7 @@ void SMESHGUI_GroupDlg::onSort()
       int id = myElements->item(i)->text().toInt();
       anArray[i] = id;
       if (myElements->item(i)->isSelected())
-       aSelected.append(id);
+        aSelected.append(id);
     }
     // sort & update list
     std::sort(anArray.begin(), anArray.end());
@@ -1793,7 +2115,7 @@ void SMESHGUI_GroupDlg::onSort()
       anItem = new QListWidgetItem(QString::number(anArray[i]));
       myElements->addItem(anItem);
       if (aSelected.contains(anArray[i]))
-       listItemsToSel.push_back(anItem);
+        listItemsToSel.push_back(anItem);
     }
     bool blocked = myElements->signalsBlocked();
     myElements->blockSignals(true);
@@ -1813,6 +2135,15 @@ void SMESHGUI_GroupDlg::closeEvent (QCloseEvent*)
   onClose();
 }
 
+//=================================================================================
+// function : onVisibilityChanged()
+// purpose  :
+//=================================================================================
+void SMESHGUI_GroupDlg::onVisibilityChanged()
+{
+  SetAppropriateActor();
+}
+
 //=================================================================================
 // function : SMESHGUI_GroupDlg::onClose
 // purpose  : SLOT called when "Close" button pressed. Close dialog
@@ -1826,7 +2157,13 @@ void SMESHGUI_GroupDlg::onClose()
     restoreShowEntityMode();
   }
 
-  mySelectionMgr->clearSelected();
+  if( isApplyAndClose() && !myObjectToSelect.isEmpty() ) {
+    SUIT_DataOwnerPtrList aList;
+    aList.append( new LightApp_DataOwner( myObjectToSelect ) );
+    mySelectionMgr->setSelected( aList );
+  }
+  else
+    mySelectionMgr->clearSelected();
   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
     aViewWindow->SetSelectionMode(ActorSelection);
   mySelectionMgr->clearFilters();
@@ -1852,10 +2189,10 @@ void SMESHGUI_GroupDlg::onHelp()
     platform = "application";
 #endif
     SUIT_MessageBox::warning(this, tr( "WRN_WARNING" ),
-                            tr( "EXTERNAL_BROWSER_CANNOT_SHOW_PAGE" ).
-                            arg(app->resourceMgr()->stringValue( "ExternalBrowser",
-                                                                platform)).
-                            arg(myHelpFileName));
+                             tr( "EXTERNAL_BROWSER_CANNOT_SHOW_PAGE" ).
+                             arg(app->resourceMgr()->stringValue( "ExternalBrowser",
+                                                                 platform)).
+                             arg(myHelpFileName));
   }
 }
 
@@ -1878,7 +2215,7 @@ void SMESHGUI_GroupDlg::enterEvent (QEvent*)
   if (!isEnabled()) {
     mySMESHGUI->EmitSignalDeactivateDialog();
     setEnabled(true);
-    mySelectionMode = -1;
+    mySelectionMode = grpNoSelection;
     setSelectionMode(myTypeId);
     //mySMESHGUI->SetActiveDialogBox((QDialog*)this);
     mySMESHGUI->SetActiveDialogBox(this);
@@ -1956,12 +2293,12 @@ void SMESHGUI_GroupDlg::onGeomSelectionButton(bool isBtnOn)
       myCurrentLineEdit = myGeomGroupLine;
       QAction* a = myGeomPopup->exec( QCursor::pos() );
       if (!a || myActions[a] == DIRECT_GEOM_INDEX)
-       setSelectionMode(7);
+        setSelectionMode(grpGeomSelection);
     }
   else if (!isBtnOn)
     {
       myCurrentLineEdit = 0;
-      setSelectionMode(8);
+      setSelectionMode(grpAllSelection);
     }
 }
 
@@ -1974,19 +2311,19 @@ void SMESHGUI_GroupDlg::onGeomPopup( QAction* a )
   int index = myActions[a];
   if ( index == GEOM_BY_MESH_INDEX )
     {
-      mySelectionMode = -1;
+      mySelectionMode = grpNoSelection;
       if ( !myShapeByMeshOp ) {
-       myShapeByMeshOp = new SMESHGUI_ShapeByMeshOp(true);
-       connect(myShapeByMeshOp, SIGNAL(committed(SUIT_Operation*)),
-               SLOT(onPublishShapeByMeshDlg(SUIT_Operation*)));
-       connect(myShapeByMeshOp, SIGNAL(aborted(SUIT_Operation*)),
-               SLOT(onCloseShapeByMeshDlg(SUIT_Operation*)));
+        myShapeByMeshOp = new SMESHGUI_ShapeByMeshOp(true);
+        connect(myShapeByMeshOp, SIGNAL(committed(SUIT_Operation*)),
+                SLOT(onPublishShapeByMeshDlg(SUIT_Operation*)));
+        connect(myShapeByMeshOp, SIGNAL(aborted(SUIT_Operation*)),
+                SLOT(onCloseShapeByMeshDlg(SUIT_Operation*)));
       }
       // set mesh object to SMESHGUI_ShapeByMeshOp and start it
       if ( !myMesh->_is_nil() ) {
-       myIsBusy = true;
+        myIsBusy = true;
         hide(); // stop processing selection
-       myIsBusy = false;
+        myIsBusy = false;
         myShapeByMeshOp->setModule( mySMESHGUI );
         myShapeByMeshOp->setStudy( 0 ); // it's really necessary
         myShapeByMeshOp->SetMesh( myMesh );
@@ -2013,12 +2350,12 @@ void SMESHGUI_GroupDlg::onPublishShapeByMeshDlg(SUIT_Operation* op)
       QString ID = aGeomVar->GetStudyEntry();
       _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
       if ( _PTR(SObject) aGeomSO = aStudy->FindObjectID( ID.toLatin1().data() )) {
-       SALOME_ListIO anIOList;
-       Handle(SALOME_InteractiveObject) anIO = new SALOME_InteractiveObject
-         ( aGeomSO->GetID().c_str(), "SMESH", aGeomSO->GetName().c_str() );
-       anIOList.Append( anIO );
-       mySelectionMgr->setSelectedObjects( anIOList, false );
-       onObjectSelectionChanged();
+        SALOME_ListIO anIOList;
+        Handle(SALOME_InteractiveObject) anIO = new SALOME_InteractiveObject
+          ( aGeomSO->GetID().c_str(), "SMESH", aGeomSO->GetName().c_str() );
+        anIOList.Append( anIO );
+        mySelectionMgr->setSelectedObjects( anIOList, false );
+        onObjectSelectionChanged();
       }
     }
   }
@@ -2035,7 +2372,7 @@ void SMESHGUI_GroupDlg::onCloseShapeByMeshDlg(SUIT_Operation* op)
   if ( myShapeByMeshOp == op )
     {
       show();
-      setSelectionMode(7);
+      setSelectionMode(grpGeomSelection);
     }
 }
 
@@ -2046,8 +2383,8 @@ void SMESHGUI_GroupDlg::onCloseShapeByMeshDlg(SUIT_Operation* op)
 void SMESHGUI_GroupDlg::setGroupColor( const SALOMEDS::Color& theColor )
 {
   QColor aQColor( (int)( theColor.R * 255.0 ),
-                 (int)( theColor.G * 255.0 ),
-                 (int)( theColor.B * 255.0 ) );
+                  (int)( theColor.G * 255.0 ),
+                  (int)( theColor.B * 255.0 ) );
   setGroupQColor( aQColor );
 }
 
@@ -2118,8 +2455,8 @@ void SMESHGUI_GroupDlg::setDefaultGroupColor()
 
     SALOMEDS::Color aColor = SMESHGUI::getUniqueColor( aReservedColors );
     aQColor.setRgb( (int)( aColor.R * 255.0 ),
-                   (int)( aColor.G * 255.0 ),
-                   (int)( aColor.B * 255.0 ) );
+                    (int)( aColor.G * 255.0 ),
+                    (int)( aColor.B * 255.0 ) );
 
   }
 
@@ -2135,82 +2472,84 @@ void SMESHGUI_GroupDlg::setDefaultGroupColor()
 bool SMESHGUI_GroupDlg::SetAppropriateActor()
 {
   bool isActor = false;
+  myActorsList.clear();
 
   if (myMesh->_is_nil()) return false;
 
   SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView();
 
-  // try mesh actor
-  myActor = SMESH::FindActorByObject(myMesh);
-  if (myActor && myActor->hasIO())
-  {
-    isActor = true;
-    if (aViewWindow && !aViewWindow->isVisible(myActor->getIO()))
-        isActor = false;
-  }
-
-  // try current group actor
-  if (!isActor) {
-    if (!myGroup->_is_nil()) {
-      myActor = SMESH::FindActorByObject(myGroup);
-      if (myActor && myActor->hasIO())
-      {
-        isActor = true;
-        if (aViewWindow && !aViewWindow->isVisible(myActor->getIO()))
-            isActor = false;
+  if (myGeomGroupBtn->isChecked()) {   // try current group on geometry actor
+    if (!isActor) {
+      if (!myGroupOnGeom->_is_nil()) {
+        SMESH_Actor* anActor = SMESH::FindActorByObject(myGroupOnGeom);
+        if (anActor && anActor->hasIO())
+          {
+            isActor = true;
+            if (aViewWindow && !aViewWindow->isVisible(anActor->getIO()))
+              isActor = false;
+            else
+              myActorsList.append(anActor);
+          }
       }
     }
-  }
-
-  // try current group on geometry actor
-  if (!isActor) {
-    if (!myGroupOnGeom->_is_nil()) {
-      myActor = SMESH::FindActorByObject(myGroupOnGeom);
-      if (myActor && myActor->hasIO())
-      {
-        isActor = true;
-        if (aViewWindow && !aViewWindow->isVisible(myActor->getIO()))
-          isActor = false;
-      }
+  } else {
+    // try mesh actor
+    SMESH_Actor* anActor = SMESH::FindActorByObject(myMesh);
+    if (anActor && anActor->hasIO()) {
+      isActor = true;
+      if (aViewWindow && !aViewWindow->isVisible(anActor->getIO()))
+        isActor = false;
+      else
+        myActorsList.append(anActor);
     }
-  }
-
-  // try any visible actor of group or submesh of current mesh
-  if (!isActor && aViewWindow) {
-    // mesh entry
-    _PTR(SObject) aSObject = SMESH::FindSObject(myMesh);
-    if (aSObject) {
-      CORBA::String_var meshEntry = aSObject->GetID().c_str();
-      int len = strlen(meshEntry);
-
-      // iterate on all actors in current view window, search for
-      // any visible actor, that belongs to group or submesh of current mesh
-      vtkActorCollection *aCollection = aViewWindow->getRenderer()->GetActors();
-      aCollection->InitTraversal();
-      for (vtkActor *anAct = aCollection->GetNextActor();
-           anAct && !isActor;
-           anAct = aCollection->GetNextActor())
-      {
-        SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct);
-        if (anActor && anActor->hasIO()) {
-          Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
-          if (aViewWindow->isVisible(anIO)) {
-            if (anIO->hasEntry() && strncmp(anIO->getEntry(), meshEntry, len) == 0) {
-              myActor = anActor;
-              isActor = true;
+    
+    // try group actor
+    if (!isActor && !myGroup->_is_nil()) {
+      SMESH_Actor* anActor = SMESH::FindActorByObject(myGroup);
+      if (anActor && anActor->hasIO())
+        myActorsList.append(anActor);
+    }
+    
+    // try any visible actor of group or submesh of current mesh
+    if (aViewWindow) {
+      // mesh entry
+      _PTR(SObject) aSObject = SMESH::FindSObject(myMesh);
+      if (aSObject) {
+        CORBA::String_var meshEntry = aSObject->GetID().c_str();
+        int len = strlen(meshEntry);
+        
+        // iterate on all actors in current view window, search for
+        // any visible actor, that belongs to group or submesh of current mesh
+        VTK::ActorCollectionCopy aCopy(aViewWindow->getRenderer()->GetActors());
+        vtkActorCollection *aCollection = aCopy.GetActors();
+        int nbItems = aCollection->GetNumberOfItems();
+        for (int i=0; i<nbItems && !isActor; i++)
+          {
+            SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(aCollection->GetItemAsObject(i));
+            if (anActor && anActor->hasIO()) {
+              Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
+              if (aViewWindow->isVisible(anIO)) {
+                if (anIO->hasEntry() && strncmp(anIO->getEntry(), meshEntry, len) == 0 && !myActorsList.contains(anActor) )
+                  myActorsList.append(anActor);
+              }
             }
           }
-        }
       }
     }
   }
-
-  if (isActor)
-    SMESH::SetPickable(myActor);
-
-  return isActor;
+  
+  if (myActorsList.count() > 0) {
+    QListIterator<SMESH_Actor*> it( myActorsList );
+    while ( it.hasNext() ) {
+      SMESH_Actor* anActor = it.next();
+      if ( IsActorVisible(anActor) )
+        anActor->SetPickable(true);
+    }
+  }
+  
+  return ( isActor || (myActorsList.count() > 0) );
 }
-
+  
 //=======================================================================
 //function : setShowEntityMode
 //purpose  : make shown only entity corresponding to my type
@@ -2222,10 +2561,11 @@ void SMESHGUI_GroupDlg::setShowEntityMode()
       if (!myStoredShownEntity)
         myStoredShownEntity = actor->GetEntityMode();
       switch ( myTypeId ) {
-      case 0: restoreShowEntityMode(); break;
-      case 1: actor->SetEntityMode( SMESH_Actor::eEdges ); break;
-      case 2: actor->SetEntityMode( SMESH_Actor::eFaces ); break;
-      case 3: actor->SetEntityMode( SMESH_Actor::eVolumes ); break;
+      case grpNodeSelection:   restoreShowEntityMode(); break;
+      case grpBallSelection:   actor->SetEntityMode( SMESH_Actor::eBallElem ); break;
+      case grpEdgeSelection:   actor->SetEntityMode( SMESH_Actor::eEdges ); break;
+      case grpFaceSelection:   actor->SetEntityMode( SMESH_Actor::eFaces ); break;
+      case grpVolumeSelection: actor->SetEntityMode( SMESH_Actor::eVolumes ); break;
       }
     }
   }
@@ -2244,3 +2584,35 @@ void SMESHGUI_GroupDlg::restoreShowEntityMode()
   }
   myStoredShownEntity = 0;
 }
+
+//=======================================================================
+//function : IsActorVisible
+//purpose  : return visibility of the actor
+//=======================================================================
+bool SMESHGUI_GroupDlg::IsActorVisible( SMESH_Actor* theActor )
+{
+  SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView();
+  if (theActor && aViewWindow)
+    return aViewWindow->isVisible(theActor->getIO());
+  return false;
+}
+
+//================================================================
+//function : setIsApplyAndClose
+//purpose  : Set value of the flag indicating that the dialog is
+//           accepted by Apply & Close button
+//================================================================
+void SMESHGUI_GroupDlg::setIsApplyAndClose( const bool theFlag )
+{
+  myIsApplyAndClose = theFlag;
+}
+
+//================================================================
+//function : isApplyAndClose
+//purpose  : Get value of the flag indicating that the dialog is
+//           accepted by Apply & Close button
+//================================================================
+bool SMESHGUI_GroupDlg::isApplyAndClose() const
+{
+  return myIsApplyAndClose;
+}
index 39a41788704eefa296c2f6210429a489b017305f..2592f4dc491dcfdeb9efe43cd81d501b1f90b357 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_GroupDlg.h
 // Author : Natalia KOPNOVA, Open CASCADE S.A.S.
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Mesh)
 #include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_Filter)
 
+class QGroupBox;
+class QLabel;
 class QLineEdit;
 class QButtonGroup;
 class QListWidget;
@@ -57,6 +61,7 @@ class SUIT_Operation;
 class SVTK_Selector;
 class SUIT_SelectionFilter;
 class LightApp_SelectionMgr;
+class SMESH_LogicalFilter;
 
 //=================================================================================
 // class    : SMESHGUI_GroupDlg
@@ -68,9 +73,9 @@ class SMESHGUI_EXPORT SMESHGUI_GroupDlg : public QDialog
 
 public:
   SMESHGUI_GroupDlg( SMESHGUI*,
-                    SMESH::SMESH_Mesh_ptr = SMESH::SMESH_Mesh::_nil() );
+                     SMESH::SMESH_Mesh_ptr = SMESH::SMESH_Mesh::_nil() );
   SMESHGUI_GroupDlg( SMESHGUI*,
-                    SMESH::SMESH_GroupBase_ptr,
+                     SMESH::SMESH_GroupBase_ptr,
                      const bool theIsConvert = false );
   ~SMESHGUI_GroupDlg();
   
@@ -90,10 +95,12 @@ private slots:
   bool                          onApply();
   void                          onHelp();
   void                          onDeactivate();
+  void                          onVisibilityChanged();
   
   void                          onListSelectionChanged();
   void                          onObjectSelectionChanged();
   
+  void                          onSelectAll();
   void                          onSelectSubMesh( bool );
   void                          onSelectGroup( bool );
   void                          onSelectGeomGroup( bool );
@@ -126,6 +133,8 @@ private:
   bool                          SetAppropriateActor();
   void                          setShowEntityMode();
   void                          restoreShowEntityMode();
+
+  bool                          IsActorVisible( SMESH_Actor* );
   
   void                          setGroupColor( const SALOMEDS::Color& );
   SALOMEDS::Color               getGroupColor() const;
@@ -134,10 +143,14 @@ private:
   QColor                        getGroupQColor() const;
   
   void                          setDefaultGroupColor();
-  
+
+  void                          setIsApplyAndClose( const bool theFlag );
+  bool                          isApplyAndClose() const;
+
+ private:
+
   SMESHGUI*                     mySMESHGUI;              /* Current SMESHGUI object */
   LightApp_SelectionMgr*        mySelectionMgr;          /* User shape selection */
-  SMESH_Actor*                  myActor;                 /* Current mesh actor */
   int                           myGrpTypeId;             /* Current group type id : standalone or group on geometry */
   int                           myTypeId;                /* Current type id = radio button id */
   int                           myStoredShownEntity;     /* Store ShowEntity mode of myMesh */
@@ -154,13 +167,19 @@ private:
   QButtonGroup*                 myGrpTypeGroup;
   
   QStackedWidget*               myWGStack;
+  QCheckBox*                    mySelectAll;
+  QCheckBox*                    myAllowElemsModif;
+  QLabel*                       myElementsLab;
   QListWidget*                  myElements;
-  QPushButton*                  myFilter;
+  QPushButton*                  myFilterBtn;
+  QPushButton*                  myAddBtn;
+  QPushButton*                  myRemoveBtn;
+  QPushButton*                  mySortBtn;
   
+  QGroupBox*                    mySelectBox;
   QCheckBox*                    mySelectSubMesh;
   QPushButton*                  mySubMeshBtn;
   QLineEdit*                    mySubMeshLine;
-  
   QCheckBox*                    mySelectGroup;
   QPushButton*                  myGroupBtn;
   QLineEdit*                    myGroupLine;
@@ -180,8 +199,11 @@ private:
   SMESHGUI_ShapeByMeshOp*       myShapeByMeshOp;
   
   SMESH::SMESH_Mesh_var         myMesh;
+  QList<SMESH_Actor*>           myActorsList;
   SMESH::SMESH_Group_var        myGroup;
   SMESH::SMESH_GroupOnGeom_var  myGroupOnGeom;
+  SMESH::SMESH_GroupOnFilter_var myGroupOnFilter;
+  SMESH::Filter_var             myFilter;
   QList<int>                    myIdList;
   GEOM::ListOfGO_var            myGeomObjects;
   
@@ -190,8 +212,8 @@ private:
   //Handle(SMESH_TypeFilter)      mySubMeshFilter;
   //Handle(SMESH_TypeFilter)      myGroupFilter;
   SUIT_SelectionFilter*         myMeshFilter;
-  SUIT_SelectionFilter*         mySubMeshFilter;
-  SUIT_SelectionFilter*         myGroupFilter;
+  SMESH_LogicalFilter*          mySubMeshFilter;
+  SMESH_LogicalFilter*          myGroupFilter;
   SUIT_SelectionFilter*         myGeomFilter;
   
   SMESHGUI_FilterDlg*           myFilterDlg;
@@ -203,6 +225,10 @@ private:
   QMap<QAction*, int>           myActions;
 
   bool                          myNameChanged; //added by skl for IPAL19574
+  int                           myNbChangesOfContents; // nb add's and remove's
+
+  QString                       myObjectToSelect;
+  bool                          myIsApplyAndClose;
 };
 
 #endif // SMESHGUI_GROUPDLG_H
index c85a269df519848876fedd33013fec7b55d5d1f6..2bfdd1bc948ed16c0d4ad93b626c8138eb087201 100644 (file)
@@ -1,24 +1,22 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  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 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.
 //
-//  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
 //
-//  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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESHGUI : GUI for SMESH component
 // File      : SMESHGUI_GroupOnShapeDlg.cxx
 // Created   : Wed Sep 17 18:36:51 2008
@@ -29,6 +27,7 @@
 #include "SMESHGUI_GroupOnShapeDlg.h"
 
 #include "SMESH_TypeFilter.hxx"
+#include "SMESHGUI.h"
 #include "SMESHGUI_Utils.h"
 #include "SMESHGUI_GEOMGenUtils.h"
 
@@ -37,6 +36,7 @@
 
 #include <SUIT_Session.h>
 #include <SUIT_OverrideCursor.h>
+#include <LightApp_Application.h>
 #include <LightApp_UpdateFlags.h>
 #include <SUIT_ResourceMgr.h>
 
@@ -178,7 +178,7 @@ SMESHGUI_GroupOnShapeOp::SMESHGUI_GroupOnShapeOp()
   : SMESHGUI_SelectionOp(ActorSelection),
     myDlg( 0 )
 {
-  myHelpFileName = "creating_groups_page.html";
+  myHelpFileName = "create_groups_from_geometry_page.html";
 }
 
 SMESHGUI_GroupOnShapeOp::~SMESHGUI_GroupOnShapeOp()
@@ -302,7 +302,7 @@ bool SMESHGUI_GroupOnShapeOp::onApply()
   if ( !aStudy ) return false;
 
   // mesh
-  _PTR(SObject)       meshSO = aStudy->FindObjectID( myMeshID.toLatin1().data() );
+  _PTR(SObject) meshSO = aStudy->FindObjectID( myMeshID.toLatin1().data() );
   SMESH::SMESH_Mesh_var mesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>( meshSO );
   if ( mesh->_is_nil() ) return false;
 
@@ -319,6 +319,7 @@ bool SMESHGUI_GroupOnShapeOp::onApply()
 
   // create groups
   SMESH::SMESH_GroupOnGeom_var group;
+  QStringList anEntryList;
   for ( int isNode = 0; isNode < 2; ++isNode ) // elems and then nodes
   {
     QStringList::iterator geomID = isNode ? myNodeGeoIDs.begin() : myElemGeoIDs.begin();
@@ -347,11 +348,30 @@ bool SMESHGUI_GroupOnShapeOp::onApply()
 
       //printf( "apply() %s %s\n", (*geomID).latin1(), name.latin1() );
       group = mesh->CreateGroupFromGEOM( elemType, name.toLatin1().data(), geom );
+      if( !group->_is_nil() )
+        if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( group ) )
+          anEntryList.append( aSObject->GetID().c_str() );
     }
   }
   update( UF_ObjBrowser | UF_Model );
 
-  init();
+  SMESHGUI::Modified();
+
+  // Re-init controls to create the next group
+  myElemGeoIDs.clear();
+  myNodeGeoIDs.clear();
+  removeCustomFilters();
+  myDlg->myNodeGeomList->clear();
+  myDlg->myElemGeomList->clear();
+  myDlg->myElemGeomBtn->setChecked(false); 
+  myDlg->myNodeGeomBtn->setChecked(false);
+  myDlg->updateButtons();
+
+  update( UF_ObjBrowser | UF_Model );
+
+  if( LightApp_Application* anApp =
+      dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
+    anApp->browseObjects( anEntryList, isApplyAndClose() );
 
   return !group->_is_nil();
 }
@@ -431,6 +451,7 @@ void SMESHGUI_GroupOnShapeOp::selectionDone()
     myDlg->myElemGeomBtn->setEnabled( nbSelected == 1 );
     myDlg->myNodeGeomList->clear();
     myDlg->myNodeGeomBtn->setEnabled( nbSelected == 1 );
+    myDlg->myElemGeomBtn->click();
     return;
   }
 
index 0009e5996678c5bf757979ad4a01a6cdc76f372b..8e5478974fab3df0f2e9d3e606c392d214b065bb 100644 (file)
@@ -1,24 +1,22 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  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 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.
 //
-//  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
 //
-//  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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESHGUI : GUI for SMESH component
 //  File   : SMESHGUI_GroupOnShapeDlg.h
 //  Author : Edard AGAPOV
index 44cdfdf94b337e51c4b1ac53d06e50379d15b709..8588a3c563b2c9208beed71bc45676552fed8d29 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_GroupOpDlg.cxx
 // Author : Sergey LITONIN, Open CASCADE S.A.S.
@@ -44,6 +45,9 @@
 #include <SVTK_ViewWindow.h>
 #include <SALOME_ListIO.hxx>
 
+// SALOME KERNEL includes
+#include <SALOMEDSClient_SObject.hxx>
+
 // Qt includes
 #include <QHBoxLayout>
 #include <QVBoxLayout>
@@ -74,7 +78,8 @@
 SMESHGUI_GroupOpDlg::SMESHGUI_GroupOpDlg( SMESHGUI* theModule )
   : QDialog( SMESH::GetDesktop( theModule ) ),
     mySMESHGUI( theModule ),
-    mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
+    mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
+    myIsApplyAndClose( false )
 {
   setModal(false);
 
@@ -131,7 +136,7 @@ QWidget* SMESHGUI_GroupOpDlg::createMainFrame( QWidget* theParent )
   QLabel* aColorLab = new QLabel(tr( "SMESH_CHECK_COLOR" ), aColorBox );
   myColorBtn = new QtxColorButton(aColorBox);
   myColorBtn->setSizePolicy( QSizePolicy::MinimumExpanding, 
-                            myColorBtn->sizePolicy().verticalPolicy() );
+                             myColorBtn->sizePolicy().verticalPolicy() );
 
   aColorBoxLayout->addWidget(aColorLab);
   aColorBoxLayout->addWidget(myColorBtn);
@@ -242,7 +247,7 @@ bool SMESHGUI_GroupOpDlg::isValid( const QList<SMESH::SMESH_GroupBase_var>& theL
   if ( theListGrp.isEmpty() )
   {
     SUIT_MessageBox::information( this, tr("SMESH_INSUFFICIENT_DATA"),
-                                 tr("INCORRECT_ARGUMENTS") );
+                                  tr("INCORRECT_ARGUMENTS") );
     return false;
   }
 
@@ -289,14 +294,14 @@ bool SMESHGUI_GroupOpDlg::isValid( const QList<SMESH::SMESH_GroupBase_var>& theL
   if ( aMeshId == -1 )
   {
     SUIT_MessageBox::information(this, tr("SMESH_INSUFFICIENT_DATA"),
-                                tr("DIFF_MESHES"));
+                                 tr("DIFF_MESHES"));
     return false;
   }
 
   if ( aGrpType == -1 ) 
   {
     SUIT_MessageBox::information(this, tr("SMESH_INSUFFICIENT_DATA"),
-                                tr("DIFF_TYPES"));
+                                 tr("DIFF_TYPES"));
     return false;
   }
 
@@ -308,8 +313,10 @@ bool SMESHGUI_GroupOpDlg::isValid( const QList<SMESH::SMESH_GroupBase_var>& theL
 */
 void SMESHGUI_GroupOpDlg::onOk()
 {
+  setIsApplyAndClose( true );
   if ( onApply() )
     onClose();
+  setIsApplyAndClose( false );
 }
 
 /*!
@@ -343,10 +350,10 @@ void SMESHGUI_GroupOpDlg::onHelp()
     platform = "application";
 #endif
     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser",
-                                                                platform)).
-                            arg(myHelpFileName));
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser",
+                                                                 platform)).
+                             arg(myHelpFileName));
   }
 }
 
@@ -524,6 +531,28 @@ bool SMESHGUI_GroupOpDlg::onApply()
   return false;
 }
 
+/*!
+  \brief Set value of the flag indicating that the dialog is
+  accepted by Apply & Close button
+  \param theFlag value of the flag
+  \sa isApplyAndClose()
+*/
+void SMESHGUI_GroupOpDlg::setIsApplyAndClose( const bool theFlag )
+{
+  myIsApplyAndClose = theFlag;
+}
+
+/*!
+  \brief Get value of the flag indicating that the dialog is
+  accepted by Apply & Close button
+  \return value of the flag
+  \sa setApplyAndClose()
+*/
+bool SMESHGUI_GroupOpDlg::isApplyAndClose() const
+{
+  return myIsApplyAndClose;
+}
+
 // === === === === === === === === === === === === === === === === === === === === === 
 
 /*!
@@ -585,6 +614,7 @@ bool SMESHGUI_UnionGroupsDlg::onApply()
   QString aName = getName();
   
   bool aRes = false;
+  QStringList anEntryList;
   try
   {
     SMESH::ListOfGroups_var aList = convert( myGroups );
@@ -593,6 +623,8 @@ bool SMESHGUI_UnionGroupsDlg::onApply()
     if ( !CORBA::is_nil( aNewGrp ) )
     {
       aNewGrp->SetColor(  getColor() );
+      if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( aNewGrp ) )
+        anEntryList.append( aSObject->GetID().c_str() );
       aRes = true;
     }
   }
@@ -603,14 +635,18 @@ bool SMESHGUI_UnionGroupsDlg::onApply()
 
   if ( aRes ) 
   {
+    SMESHGUI::Modified();
     getSMESHGUI()->updateObjBrowser(true);
     reset();
+    if( LightApp_Application* anApp =
+        dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
+      anApp->browseObjects( anEntryList, isApplyAndClose() );
     return true;
   } 
   else 
   {
     SUIT_MessageBox::critical(this, tr("SMESH_ERROR"),
-                             tr("SMESH_OPERATION_FAILED"));
+                              tr("SMESH_OPERATION_FAILED"));
     return false;
   }
 }
@@ -687,6 +723,7 @@ bool SMESHGUI_IntersectGroupsDlg::onApply()
   QString aName = getName();
   
   bool aRes = false;
+  QStringList anEntryList;
   try
   {
     SMESH::ListOfGroups_var aList = convert( myGroups );
@@ -695,6 +732,8 @@ bool SMESHGUI_IntersectGroupsDlg::onApply()
     if ( !CORBA::is_nil( aNewGrp ) )
     {
       aNewGrp->SetColor(  getColor() );
+      if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( aNewGrp ) )
+        anEntryList.append( aSObject->GetID().c_str() );
       aRes = true;
     }
   }
@@ -705,14 +744,18 @@ bool SMESHGUI_IntersectGroupsDlg::onApply()
 
   if ( aRes ) 
   {
+    SMESHGUI::Modified();
     getSMESHGUI()->updateObjBrowser(true);
     reset();
+    if( LightApp_Application* anApp =
+        dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
+      anApp->browseObjects( anEntryList, isApplyAndClose() );
     return true;
   } 
   else 
   {
     SUIT_MessageBox::critical(this, tr("SMESH_ERROR"),
-                             tr("SMESH_OPERATION_FAILED"));
+                              tr("SMESH_OPERATION_FAILED"));
     return false;
   }
 }
@@ -852,6 +895,7 @@ bool SMESHGUI_CutGroupsDlg::onApply()
   QString aName = getName();
   
   bool aRes = false;
+  QStringList anEntryList;
   try
   {
     SMESH::ListOfGroups_var aList1 = convert( myGroups1 );
@@ -861,6 +905,8 @@ bool SMESHGUI_CutGroupsDlg::onApply()
     if ( !CORBA::is_nil( aNewGrp ) )
     {
       aNewGrp->SetColor(  getColor() );
+      if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( aNewGrp ) )
+        anEntryList.append( aSObject->GetID().c_str() );
       aRes = true;
     }
   }
@@ -871,14 +917,18 @@ bool SMESHGUI_CutGroupsDlg::onApply()
 
   if ( aRes ) 
   {
+    SMESHGUI::Modified();
     getSMESHGUI()->updateObjBrowser(true);
     reset();
+    if( LightApp_Application* anApp =
+        dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
+      anApp->browseObjects( anEntryList, isApplyAndClose() );
     return true;
   } 
   else 
   {
     SUIT_MessageBox::critical(this, tr("SMESH_ERROR"),
-                             tr("SMESH_OPERATION_FAILED"));
+                              tr("SMESH_OPERATION_FAILED"));
     return false;
   }
 }
@@ -913,7 +963,7 @@ SMESHGUI_DimGroupDlg::SMESHGUI_DimGroupDlg( SMESHGUI* theModule )
 : SMESHGUI_GroupOpDlg( theModule )
 {
   setWindowTitle( tr( "CREATE_GROUP_OF_UNDERLYING_ELEMS" ) );
-  setHelpFileName( "creating_groups_page.html#gui_create_dim_group" );
+  setHelpFileName( "group_of_underlying_elements_page.html" );
 
   QGroupBox* anArgGrp = getArgGrp();
 
@@ -1003,6 +1053,7 @@ bool SMESHGUI_DimGroupDlg::onApply()
   QString aName = getName();
   
   bool aRes = false;
+  QStringList anEntryList;
   try
   {
     SMESH::ListOfGroups_var aList = convert( myGroups );
@@ -1012,6 +1063,8 @@ bool SMESHGUI_DimGroupDlg::onApply()
     if ( !CORBA::is_nil( aNewGrp ) )
     {
       aNewGrp->SetColor(  getColor() );
+      if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( aNewGrp ) )
+        anEntryList.append( aSObject->GetID().c_str() );
       aRes = true;
     }
   }
@@ -1022,14 +1075,18 @@ bool SMESHGUI_DimGroupDlg::onApply()
 
   if ( aRes ) 
   {
+    SMESHGUI::Modified();
     getSMESHGUI()->updateObjBrowser(true);
     reset();
+    if( LightApp_Application* anApp =
+        dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
+      anApp->browseObjects( anEntryList, isApplyAndClose() );
     return true;
   } 
   else 
   {
     SUIT_MessageBox::critical(this, tr("SMESH_ERROR"),
-                             tr("SMESH_OPERATION_FAILED"));
+                              tr("SMESH_OPERATION_FAILED"));
     return false;
   }
 }
index fda94dd0101a732c1c2ba1ca7d18b3f5b7e78285..ec3b4c2f5e28b8365c67d764386040a1e0b78df3 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_GroupOpDlg.h
 // Author : Sergey LITONIN, Open CASCADE S.A.S.
@@ -87,6 +88,9 @@ protected:
 
   SALOMEDS::Color           getColor() const;
 
+  void                      setIsApplyAndClose( const bool theFlag );
+  bool                      isApplyAndClose() const;
+
 private:
   void                      closeEvent( QCloseEvent* );
   void                      enterEvent( QEvent* );            
@@ -118,6 +122,8 @@ private:
   SVTK_Selector*            mySelector;
   
   QString                   myHelpFileName;
+
+  bool                      myIsApplyAndClose;
 };
 
 /*
index e645257e2ebc0d8ac07a9958ab827b8e1d398d15..093426cfdf5bb7813b0a51d50d67171448ff7ebe 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_GroupUtils.cxx
 // Author : Open CASCADE S.A.S.
 namespace SMESH
 {
   SMESH::SMESH_Group_var AddGroup( SMESH::SMESH_Mesh_ptr theMesh,
-                                  SMESH::ElementType theType,
-                                  const QString& theGroupName )
+                                   SMESH::ElementType theType,
+                                   const QString& theGroupName )
   {
     SMESH::SMESH_Group_var aGroup;
     try {
       if ( !theMesh->_is_nil() )
-       aGroup = theMesh->CreateGroup( theType, theGroupName.toLatin1().data() );
+        aGroup = theMesh->CreateGroup( theType, theGroupName.toLatin1().data() );
     }
     catch( const SALOME::SALOME_Exception& S_ex ) {
       SalomeApp_Tools::QtCatchCorbaException( S_ex );
index e0673a783a5c68ceb7ee06e3d4510b18c1c2caf2..1ede5161b6cca43cc1d30b0873b1c3ef911c80af 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_GroupUtils.h
 // Author : Open CASCADE S.A.S.
@@ -40,8 +41,8 @@ namespace SMESH
 {
   SMESHGUI_EXPORT
     SMESH::SMESH_Group_var AddGroup( SMESH::SMESH_Mesh_ptr,
-                                    SMESH::ElementType,
-                                    const QString& );
+                                     SMESH::ElementType,
+                                     const QString& );
 }
 
 #endif // SMESHGUI_GROUPUTILS_H
index 8ca61f49fd0876129aa798574a258fe0377360c6..3d0baf890b2b1d0a856a8d01e474407cce0ff9e0 100644 (file)
@@ -1,29 +1,28 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
-//
-// SMESH SMESHGUI : GUI for SMESH component
-// File   : SMESHGUI_Hypotheses.cxx
-// Author : Julia DOROVSKIKH, Open CASCADE S.A.S.
-// SMESH includes
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+//  File   : SMESHGUI_Hypotheses.cxx
+//  Author : Julia DOROVSKIKH, Open CASCADE S.A.S.
+//  SMESH includes
+
 #include "SMESHGUI_Hypotheses.h"
 
 #include "SMESHGUI.h"
 #include <QLabel>
 #include <QGroupBox>
 #include <QVBoxLayout>
-#include <QEventLoop>
 
 #define SPACING 6
 #define MARGIN  11
 
+//To disable automatic genericobj management, the following line should be commented.
+//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
+#define WITHGENERICOBJ
+
 SMESHGUI_GenericHypothesisCreator::SMESHGUI_GenericHypothesisCreator( const QString& theHypType )
-  : myHypType( theHypType ), myIsCreate( false ), myDlg( 0 ), myEventLoop( 0 )
+  : myHypType( theHypType ), myIsCreate( false ), myDlg( 0 )
 {
 }
 
@@ -69,46 +71,45 @@ void SMESHGUI_GenericHypothesisCreator::setInitParamsHypothesis(SMESH::SMESH_Hyp
 }
 
 void SMESHGUI_GenericHypothesisCreator::create( SMESH::SMESH_Hypothesis_ptr initParamsHyp,
-                                               const QString& theHypName,
-                                                QWidget* parent)
+                                                const QString& theHypName,
+                                                QWidget* parent, QObject* obj, const QString& slot )
 {
   MESSAGE( "Creation of hypothesis with initial params" );
   setInitParamsHypothesis( initParamsHyp );
-  create( false, theHypName, parent );
+  create( false, theHypName, parent, obj, slot );
 }
 
 void SMESHGUI_GenericHypothesisCreator::create( bool isAlgo,
-                                               const QString& theHypName,
-                                               QWidget* theParent )
+                                                const QString& theHypName,
+                                                QWidget* theParent, QObject* obj, const QString& slot )
 {
   MESSAGE( "Creation of hypothesis" );
 
   myIsCreate = true;
 
   // Create hypothesis/algorithm
-  if (isAlgo)
-    SMESH::CreateHypothesis( hypType(), theHypName, isAlgo );
-  else
-  {
-    SMESH::SMESH_Hypothesis_var aHypothesis = 
+  if (isAlgo) {
+    SMESH::SMESH_Hypothesis_var anAlgo =
+      SMESH::CreateHypothesis( hypType(), theHypName, isAlgo );
+#ifdef WITHGENERICOBJ
+    if (!CORBA::is_nil(anAlgo))
+      anAlgo->UnRegister();
+#endif
+  }
+  else {
+    SMESH::SMESH_Hypothesis_var aHypothesis =
       SMESH::CreateHypothesis( hypType(), theHypName, false );
-    if( !editHypothesis( aHypothesis.in(), theHypName, theParent ) )
-    { //remove just created hypothesis
-      _PTR(SObject) aHypSObject = SMESH::FindSObject( aHypothesis.in() );
-      _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
-      if( aStudy && !aStudy->GetProperties()->IsLocked() )
-      {
-       _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
-       aBuilder->RemoveObjectWithChildren( aHypSObject );
-      }
-    }
+    editHypothesis( aHypothesis.in(), theHypName, theParent, obj, slot );
+#ifdef WITHGENERICOBJ
+    if (!CORBA::is_nil(aHypothesis))
+      aHypothesis->UnRegister();
+#endif
   }
-  SMESHGUI::GetSMESHGUI()->updateObjBrowser( true, 0 );
 }
 
 void SMESHGUI_GenericHypothesisCreator::edit( SMESH::SMESH_Hypothesis_ptr theHypothesis,
-                                             const QString& theHypName,
-                                             QWidget* theParent )
+                                              const QString& theHypName,
+                                              QWidget* theParent, QObject* obj, const QString& slot )
 {
   if( CORBA::is_nil( theHypothesis ) )
     return;
@@ -117,37 +118,25 @@ void SMESHGUI_GenericHypothesisCreator::edit( SMESH::SMESH_Hypothesis_ptr theHyp
 
   myIsCreate = false;
 
-  if( !editHypothesis( theHypothesis, theHypName, theParent ) )
-    return;
-
-  SMESH::SObjectList listSOmesh = SMESH::GetMeshesUsingAlgoOrHypothesis( theHypothesis );
-  if( listSOmesh.size() > 0 )
-    for( int i = 0; i < listSOmesh.size(); i++ )
-    {
-      _PTR(SObject) submSO = listSOmesh[i];
-      SMESH::SMESH_Mesh_var aMesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>( submSO );
-      SMESH::SMESH_subMesh_var aSubMesh = SMESH::SObjectToInterface<SMESH::SMESH_subMesh>( submSO );
-      if( !aSubMesh->_is_nil() )
-       aMesh = aSubMesh->GetFather();
-      _PTR(SObject) meshSO = SMESH::FindSObject( aMesh );
-      SMESH::ModifiedMesh( meshSO, false, aMesh->NbNodes()==0);
-    }
-  SMESHGUI::GetSMESHGUI()->updateObjBrowser( true, 0 );
+  editHypothesis( theHypothesis, theHypName, theParent, obj, slot );
 }
 
-bool SMESHGUI_GenericHypothesisCreator::editHypothesis( SMESH::SMESH_Hypothesis_ptr h, 
-                                                       const QString& theHypName,
-                                                       QWidget* theParent )
+void SMESHGUI_GenericHypothesisCreator::editHypothesis( SMESH::SMESH_Hypothesis_ptr h,
+                                                        const QString& theHypName,
+                                                        QWidget* theParent,
+                                                        QObject* obj, const QString& slot )
 {
-  if( CORBA::is_nil( h ) )
-    return false;
-
-  bool res = true;
   myHypName = theHypName;
   myHypo = SMESH::SMESH_Hypothesis::_duplicate( h );
+#ifdef WITHGENERICOBJ
+  myHypo->Register();
+#endif
 
   SMESHGUI_HypothesisDlg* Dlg = new SMESHGUI_HypothesisDlg( this, theParent );
   connect( Dlg, SIGNAL( finished( int ) ), this, SLOT( onDialogFinished( int ) ) );
+  connect( this, SIGNAL( finished( int ) ), obj, slot.toLatin1().constData() );
+  connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), Dlg, SLOT( reject() ));
+
   myDlg = Dlg;
   QFrame* fr = buildFrame();
   if( fr )
@@ -159,25 +148,14 @@ bool SMESHGUI_GenericHypothesisCreator::editHypothesis( SMESH::SMESH_Hypothesis_
     Dlg->setType( type() );
     retrieveParams();
     Dlg->show();
-    if ( !myEventLoop )
-      myEventLoop = new QEventLoop( this );
-    myEventLoop->exec(); // make myDlg not modal
-    res = myDlg->result();
-    if( res ) {
-      QString paramValues = storeParams();
-      if ( !paramValues.isEmpty() ) {
-        if ( _PTR(SObject) SHyp = SMESH::FindSObject( myHypo ))
-          SMESH::SetValue( SHyp, paramValues );
-      }
-    }
+    Dlg->resize( Dlg->minimumSizeHint() );
+  }
+  else {
+    emit finished( QDialog::Accepted );
+        delete myDlg;
   }
-  delete Dlg; myDlg = 0;
-  changeWidgets().clear();
-  myHypo = SMESH::SMESH_Hypothesis::_nil();
-  myInitParamsHypo = SMESH::SMESH_Hypothesis::_nil();
-  return res;
 }
-  
+
 QFrame* SMESHGUI_GenericHypothesisCreator::buildStdFrame()
 {
   if( CORBA::is_nil( hypothesis() ) )
@@ -206,13 +184,13 @@ QFrame* SMESHGUI_GenericHypothesisCreator::buildStdFrame()
     GroupC1Layout->addWidget( lab, i, 0 );
 
     QWidget* w = getCustomWidget( *anIt, GroupC1, i );
-    if ( !w ) 
+    if ( !w )
       switch( (*anIt).myValue.type() )
       {
       case QVariant::Int:
         {
           SalomeApp_IntSpinBox* sb = new SalomeApp_IntSpinBox( GroupC1 );
-         sb->setObjectName( (*anIt).myName );
+          sb->setObjectName( (*anIt).myName );
           attuneStdWidget( sb, i );
           sb->setValue( (*anIt).myValue.toInt() );
           connect( sb, SIGNAL( valueChanged( int ) ), this, SLOT( onValueChanged() ) );
@@ -222,7 +200,7 @@ QFrame* SMESHGUI_GenericHypothesisCreator::buildStdFrame()
       case QVariant::Double:
         {
           SalomeApp_DoubleSpinBox* sb = new SMESHGUI_SpinBox( GroupC1 );
-         sb->setObjectName( (*anIt).myName );
+          sb->setObjectName( (*anIt).myName );
           attuneStdWidget( sb, i );
           sb->setValue( (*anIt).myValue.toDouble() );
           connect( sb, SIGNAL( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
@@ -243,7 +221,7 @@ QFrame* SMESHGUI_GenericHypothesisCreator::buildStdFrame()
               w = sb;
             }
             else if(aStudy->IsReal(aVar.toLatin1().constData())){
-              SalomeApp_DoubleSpinBox* sb = new SalomeApp_DoubleSpinBox( GroupC1 );
+              SalomeApp_DoubleSpinBox* sb = new SMESHGUI_SpinBox( GroupC1 );
               sb->setObjectName( (*anIt).myName );
               attuneStdWidget( sb, i );
               sb->setText( aVar );
@@ -282,10 +260,59 @@ void SMESHGUI_GenericHypothesisCreator::valueChanged( QWidget* )
 {
 }
 
-void SMESHGUI_GenericHypothesisCreator::onDialogFinished( int /*result*/ )
+void SMESHGUI_GenericHypothesisCreator::onDialogFinished( int result )
 {
-  if ( myEventLoop )
-    myEventLoop->exit();
+  bool res = result==QDialog::Accepted;
+  if( res )
+  {
+      /*QString paramValues = */storeParams();
+      // No longer needed since NoteBook appears and "Value" OB field shows names of variable
+//       if ( !paramValues.isEmpty() ) {
+//         if ( _PTR(SObject) SHyp = SMESH::FindSObject( myHypo ))
+//           SMESH::SetValue( SHyp, paramValues );
+//       }
+  }
+
+  changeWidgets().clear();
+
+  if( myIsCreate && !res )
+  {
+    //remove just created hypothesis
+    _PTR(SObject) aHypSObject = SMESH::FindSObject( myHypo );
+    _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
+    if( aStudy && !aStudy->GetProperties()->IsLocked() )
+    {
+      _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
+      aBuilder->RemoveObjectWithChildren( aHypSObject );
+    }
+  }
+  else if( !myIsCreate && res )
+  {
+    SMESH::SObjectList listSOmesh = SMESH::GetMeshesUsingAlgoOrHypothesis( myHypo );
+    if( listSOmesh.size() > 0 )
+      for( int i = 0; i < listSOmesh.size(); i++ )
+      {
+        _PTR(SObject) submSO = listSOmesh[i];
+        SMESH::SMESH_Mesh_var aMesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>( submSO );
+        SMESH::SMESH_subMesh_var aSubMesh = SMESH::SObjectToInterface<SMESH::SMESH_subMesh>( submSO );
+        if( !aSubMesh->_is_nil() )
+          aMesh = aSubMesh->GetFather();
+        _PTR(SObject) meshSO = SMESH::FindSObject( aMesh );
+        SMESH::ModifiedMesh( meshSO, false, aMesh->NbNodes()==0);
+      }
+  }
+  SMESHGUI::GetSMESHGUI()->updateObjBrowser( true, 0 );
+#ifdef WITHGENERICOBJ
+  myHypo->UnRegister();
+#endif
+  myHypo = SMESH::SMESH_Hypothesis::_nil();
+  myInitParamsHypo = SMESH::SMESH_Hypothesis::_nil();
+
+  disconnect( myDlg, SIGNAL( finished( int ) ), this, SLOT( onDialogFinished( int ) ) );
+  myDlg->close();
+  //delete myDlg; since WA_DeleteOnClose==true
+  myDlg = 0;
+  emit finished( result );
 }
 
 bool SMESHGUI_GenericHypothesisCreator::stdParams( ListOfStdParams& ) const
@@ -305,48 +332,52 @@ bool SMESHGUI_GenericHypothesisCreator::getStdParamFromDlg( ListOfStdParams& par
     {
       SalomeApp_IntSpinBox* sb = ( SalomeApp_IntSpinBox* )( *anIt );
       item.myValue = sb->value();
+      item.myText = sb->text();
       params.append( item );
     }
-    
     else if( (*anIt)->inherits( "SalomeApp_DoubleSpinBox" ) )
     {
       SalomeApp_DoubleSpinBox* sb = ( SalomeApp_DoubleSpinBox* )( *anIt );
       item.myValue = sb->value();
+      item.myText = sb->text();
       params.append( item );
     }
-
     else if( (*anIt)->inherits( "QLineEdit" ) )
     {
       QLineEdit* line = ( QLineEdit* )( *anIt );
-      item.myValue = line->text();
+      item.myValue = item.myText = line->text();
       params.append( item );
     }
-
     else if ( getParamFromCustomWidget( item, *anIt ))
     {
       params.append( item );
     }
-
     else
       res = false;
   }
   return res;
 }
 
+QString SMESHGUI_GenericHypothesisCreator::getVariableName(const char* methodName) const
+{
+  SMESH::SMESH_Hypothesis_var h = hypothesis();
+  if ( !h->_is_nil() )
+  {
+    CORBA::String_var aVaribaleName = h->GetVarParameter( methodName );
+    return QString( aVaribaleName.in() );
+  }
+  return QString();
+}
 
 QStringList SMESHGUI_GenericHypothesisCreator::getVariablesFromDlg() const
 {
   QStringList aResult;
   ListOfWidgets::const_iterator anIt = widgets().begin(), aLast = widgets().end();
   for( ; anIt!=aLast; anIt++ ) {
-    if( (*anIt)->inherits( "SalomeApp_IntSpinBox" ) ) {
-      SalomeApp_IntSpinBox* sb = ( SalomeApp_IntSpinBox* )( *anIt );
+    if( (*anIt)->inherits( "QAbstractSpinBox" ) ) {
+      QAbstractSpinBox* sb = ( QAbstractSpinBox* )( *anIt );
       aResult.append(sb->text());
-    } 
-    else if( (*anIt)->inherits( "QtxDoubleSpinBox" ) ) {
-      QtxDoubleSpinBox* sb = ( QtxDoubleSpinBox* )( *anIt );
-      aResult.append(sb->text());
-    } 
+    }
   }
   return aResult;
 }
@@ -386,6 +417,11 @@ SMESH::SMESH_Hypothesis_var SMESHGUI_GenericHypothesisCreator::hypothesis() cons
   return myHypo;
 }
 
+void SMESHGUI_GenericHypothesisCreator::setShapeEntry( const QString& theEntry )
+{
+  myShapeEntry = theEntry;
+}
+
 //================================================================================
 /*!
  * \brief Return hypothesis containing initial parameters
@@ -430,7 +466,7 @@ SMESHGUI_GenericHypothesisCreator::ListOfWidgets& SMESHGUI_GenericHypothesisCrea
 }
 
 QtxDialog* SMESHGUI_GenericHypothesisCreator:: dlg() const
-{ 
+{
   return myDlg;
 }
 
@@ -495,11 +531,15 @@ void SMESHGUI_GenericHypothesisCreator::onReject()
 QString SMESHGUI_GenericHypothesisCreator::helpPage() const
 {
   QString aHypType = hypType();
-  QString aHelpFileName;
+  QString aHelpFileName = "";
   if ( aHypType == "LocalLength" )
     aHelpFileName = "a1d_meshing_hypo_page.html#average_length_anchor";
+  else if ( aHypType == "MaxLength" )
+    aHelpFileName = "a1d_meshing_hypo_page.html#max_length_anchor";
   else if ( aHypType == "Arithmetic1D")
     aHelpFileName = "a1d_meshing_hypo_page.html#arithmetic_1d_anchor";
+  else if ( aHypType == "FixedPoints1D")
+    aHelpFileName = "a1d_meshing_hypo_page.html#fixed_points_1d_anchor";
   else if ( aHypType == "MaxElementArea")
     aHelpFileName = "a2d_meshing_hypo_page.html#max_element_area_anchor";
   else if ( aHypType == "MaxElementVolume")
@@ -520,23 +560,29 @@ QString SMESHGUI_GenericHypothesisCreator::helpPage() const
     aHelpFileName = "projection_algos_page.html";
   else if ( aHypType == "NumberOfLayers")
     aHelpFileName = "radial_prism_algo_page.html";
+  else if ( aHypType == "NumberOfLayers2D")
+    aHelpFileName = "radial_quadrangle_1D2D_algo_page.html";
   else if ( aHypType == "LayerDistribution")
     aHelpFileName = "radial_prism_algo_page.html";
+  else if ( aHypType == "LayerDistribution2D")
+    aHelpFileName = "radial_quadrangle_1D2D_algo_page.html";
   else if ( aHypType == "SegmentLengthAroundVertex")
-    aHelpFileName = "segments_around_vertex_algo.html";
-  else
-    aHelpFileName = "";
+    aHelpFileName = "segments_around_vertex_algo_page.html";
+  else if ( aHypType == "QuadrangleParams")
+    aHelpFileName = "a2d_meshing_hypo_page.html#hypo_quad_params_anchor";
+  else if ( aHypType == "ViscousLayers")
+    aHelpFileName = "additional_hypo_page.html#viscous_layers_anchor";
+  else if ( aHypType == "ImportSource1D" || aHypType == "ImportSource2D")
+    aHelpFileName = "import_algos_page.html";
   return aHelpFileName;
 }
 
-
-
-
 SMESHGUI_HypothesisDlg::SMESHGUI_HypothesisDlg( SMESHGUI_GenericHypothesisCreator* creator, QWidget* parent )
 : QtxDialog( parent, false, true ),
   myCreator( creator )
 {
-  setMinimumSize( 300, height() );
+  setAttribute(Qt::WA_DeleteOnClose, true);
+ // setMinimumSize( 300, height() );
 //  setFixedSize( 300, height() );
   QVBoxLayout* topLayout = new QVBoxLayout( mainFrame() );
   topLayout->setMargin( 0 );
@@ -546,7 +592,7 @@ SMESHGUI_HypothesisDlg::SMESHGUI_HypothesisDlg( SMESHGUI_GenericHypothesisCreato
   QHBoxLayout* titLay = new QHBoxLayout( titFrame );
   titLay->setMargin( 0 );
   titLay->setSpacing( SPACING );
-  
+
   myIconLabel = new QLabel( titFrame );
   myIconLabel->setScaledContents( false );
   myIconLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
@@ -567,6 +613,7 @@ SMESHGUI_HypothesisDlg::SMESHGUI_HypothesisDlg( SMESHGUI_GenericHypothesisCreato
 
 SMESHGUI_HypothesisDlg::~SMESHGUI_HypothesisDlg()
 {
+  delete myCreator;
 }
 
 void SMESHGUI_HypothesisDlg::setCustomFrame( QFrame* f )
@@ -602,8 +649,17 @@ void SMESHGUI_HypothesisDlg::onHelp()
 {
   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
   if (app) {
-    SMESHGUI* aSMESHGUI = dynamic_cast<SMESHGUI*>( app->activeModule() );
-    app->onHelpContextModule(aSMESHGUI ? app->moduleName(aSMESHGUI->moduleName()) : QString(""), myHelpFileName);
+    QString name = "SMESH";
+    if(myCreator) {
+      QVariant pluginName = myCreator->property( PLUGIN_NAME );
+      if( pluginName.isValid() ) {
+       QString rootDir = pluginName.toString() + "PLUGIN_ROOT_DIR";
+       QString varValue = QString( getenv(rootDir.toLatin1().constData()));
+       if(!varValue.isEmpty())
+         name = pluginName.toString() + "PLUGIN";
+      }
+    }    
+    app->onHelpContextModule(name, myHelpFileName);
   }
   else {
     QString platform;
@@ -613,16 +669,16 @@ void SMESHGUI_HypothesisDlg::onHelp()
     platform = "application";
 #endif
     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser", 
-                                                                platform)).
-                            arg(myHelpFileName));
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser",
+                                                                 platform)).
+                             arg(myHelpFileName));
   }
 }
 
 void SMESHGUI_HypothesisDlg::setHIcon( const QPixmap& p )
 {
-  myIconLabel->setPixmap( p );  
+  myIconLabel->setPixmap( p );
 }
 
 void SMESHGUI_HypothesisDlg::setType( const QString& t )
@@ -631,18 +687,18 @@ void SMESHGUI_HypothesisDlg::setType( const QString& t )
 }
 
 HypothesisData::HypothesisData( const QString& theTypeName,
-                               const QString& thePluginName,
-                               const QString& theServerLibName,
-                               const QString& theClientLibName,
-                               const QString& theLabel,
-                               const QString& theIconId,
-                               const QList<int>& theDim,
-                               const bool theIsAux,
-                               const QStringList& theNeededHypos,
-                               const QStringList& theOptionalHypos,
-                               const QStringList& theInputTypes,
-                               const QStringList& theOutputTypes,
-                               const bool theIsNeedGeometry,
+                                const QString& thePluginName,
+                                const QString& theServerLibName,
+                                const QString& theClientLibName,
+                                const QString& theLabel,
+                                const QString& theIconId,
+                                const QList<int>& theDim,
+                                const bool theIsAux,
+                                const QStringList& theNeededHypos,
+                                const QStringList& theOptionalHypos,
+                                const QStringList& theInputTypes,
+                                const QStringList& theOutputTypes,
+                                const bool theIsNeedGeometry,
                                 const bool supportSub)
   : TypeName( theTypeName ),
     PluginName( thePluginName ),
@@ -652,7 +708,7 @@ HypothesisData::HypothesisData( const QString& theTypeName,
     IconId( theIconId ),
     Dim( theDim ),
     IsAux( theIsAux ),
-    NeededHypos( theNeededHypos ), 
+    NeededHypos( theNeededHypos ),
     OptionalHypos( theOptionalHypos ),
     InputTypes( theInputTypes ),
     OutputTypes( theOutputTypes ),
@@ -661,16 +717,96 @@ HypothesisData::HypothesisData( const QString& theTypeName,
 {
 }
 
-HypothesesSet::HypothesesSet( const QString& theSetName ) 
-  : HypoSetName( theSetName )
+HypothesesSet::HypothesesSet( const QString& theSetName )
+  : myHypoSetName( theSetName ),
+    myIsAlgo( false ),
+    myIsCustom( false )
 {
 }
 
 HypothesesSet::HypothesesSet( const QString&     theSetName,
-                             const QStringList& theHypoList,
-                             const QStringList& theAlgoList )
-  : HypoSetName( theSetName ), 
-    HypoList( theHypoList ), 
-    AlgoList( theAlgoList )
+                              const QStringList& theHypoList,
+                              const QStringList& theAlgoList )
+  : myHypoSetName( theSetName ),
+    myHypoList( theHypoList ),
+    myAlgoList( theAlgoList ),
+    myIsAlgo( false ),
+    myIsCustom( false )
+{
+}
+
+QStringList* HypothesesSet::list(bool is_algo) const
+{
+  return const_cast<QStringList*>( &( is_algo ? myAlgoList : myHypoList ) );
+}
+
+QStringList* HypothesesSet::list() const
+{
+  return list( myIsAlgo );
+}
+
+QString HypothesesSet::name() const
+{
+  return myHypoSetName;
+}
+
+void HypothesesSet::set( bool isAlgo, const QStringList& lst )
+{
+  *list(isAlgo) = lst;
+}
+
+int HypothesesSet::count( bool isAlgo ) const
+{
+  return list(isAlgo)->count();
+}
+
+bool HypothesesSet::isAlgo() const
+{
+  return myIsAlgo;
+}
+
+void HypothesesSet::init( bool isAlgo )
 {
+  myIsAlgo = isAlgo;
+  myIndex = -1;
+}
+
+bool HypothesesSet::more() const
+{
+  return myIndex < list()->count();
+}
+
+void HypothesesSet::next()
+{
+  myIndex++;
+}
+
+QString HypothesesSet::current() const
+{
+  return list()->at(myIndex);
+}
+
+void HypothesesSet::setIsCustom( bool isCustom )
+{
+  myIsCustom = isCustom;
+}
+
+bool HypothesesSet::getIsCustom() const
+{
+  return myIsCustom;
+}
+
+int HypothesesSet::maxDim() const
+{
+  HypothesesSet * thisSet = (HypothesesSet*) this;
+  int dim = -1;
+  for ( int isAlgo = 0; isAlgo < 2; ++isAlgo )
+  {
+    thisSet->init( isAlgo );
+    while ( thisSet->next(), thisSet->more() )
+      if ( HypothesisData* hypData = SMESH::GetHypothesisData( thisSet->current() ))
+        for ( int i = 0; i < hypData->Dim.count(); ++i )
+          dim = qMax( dim, hypData->Dim[i] );
+  }
+  return dim;
 }
index 6cf6c524dcd9e78bd7aff30f014367703606ea5a..c15484b84b3accbdf1891af22217c485ddf49273 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_Hypotheses.h
 // Author : Julia DOROVSKIKH, Open CASCADE S.A.S.
@@ -28,6 +29,7 @@
 
 // SMESH includes
 #include "SMESH_SMESHGUI.hxx"
+#include "SMESHGUI_HypothesesUtils.h"
 
 // Qt includes
 #include <QtxDialog.h>
@@ -51,10 +53,9 @@ public:
   virtual ~SMESHGUI_GenericHypothesisCreator();
 
   void                         create( SMESH::SMESH_Hypothesis_ptr,
-                                      const QString&, QWidget* );
-  void                         create( bool, const QString&, QWidget* );
-  void                         edit( SMESH::SMESH_Hypothesis_ptr,
-                                    const QString&, QWidget* );
+                                       const QString&, QWidget*, QObject*, const QString& );
+  void                         create( bool, const QString&, QWidget*, QObject*, const QString& );
+  void                         edit( SMESH::SMESH_Hypothesis_ptr, const QString&, QWidget*, QObject*, const QString& );
   void                         setInitParamsHypothesis(SMESH::SMESH_Hypothesis_ptr);
 
   virtual bool                 checkParams( QString& ) const;
@@ -64,6 +65,15 @@ public:
   QString                      hypType() const;
   QString                      hypName() const;
   bool                         isCreation() const;
+  
+  QString                      getShapeEntry() const { return myShapeEntry; }
+  void                         setShapeEntry( const QString& theEntry );
+
+  QString                      getMainShapeEntry() const { return myMainShapeEntry; }
+  void                         setMainShapeEntry( const QString& theEntry ) { myMainShapeEntry = theEntry; }
+
+signals:
+  void                         finished( int );
 
 protected:
   struct StdParam
@@ -71,9 +81,11 @@ protected:
     QString   myName;
     QVariant  myValue;
     bool      isVariable;
+    QString   myText;
     StdParam(){
       isVariable = false;
     }
+    const char* text() const { return myText.toLatin1().constData(); }
   };
 
   typedef QList<StdParam>      ListOfStdParams;
@@ -85,6 +97,7 @@ protected:
   const ListOfWidgets&         widgets() const;
   ListOfWidgets&               changeWidgets();
   QtxDialog*                   dlg() const;
+  QString                      getVariableName(const char* methodName) const;
 
   virtual QFrame*              buildFrame() = 0;
           QFrame*              buildStdFrame();
@@ -96,7 +109,7 @@ protected:
   static  QString              stdParamValues( const ListOfStdParams& );
   virtual void                 attuneStdWidget( QWidget*, const int ) const;
   virtual QWidget*             getCustomWidget( const StdParam&, 
-                                               QWidget*, const int ) const;
+                                                QWidget*, const int ) const;
   virtual bool                 getParamFromCustomWidget( StdParam&, QWidget* ) const;
   virtual void                 valueChanged( QWidget* );
   virtual QString              caption() const;
@@ -110,8 +123,7 @@ private slots:
   virtual void                 onDialogFinished( int );
 
 private:
-  bool                         editHypothesis( SMESH::SMESH_Hypothesis_ptr,
-                                              const QString&, QWidget* );
+  void                         editHypothesis( SMESH::SMESH_Hypothesis_ptr, const QString&, QWidget*, QObject* obj, const QString& );
 
 private:
   SMESH::SMESH_Hypothesis_var  myHypo, myInitParamsHypo;
@@ -120,7 +132,8 @@ private:
   ListOfWidgets                myParamWidgets;
   bool                         myIsCreate;
   QtxDialog*                   myDlg;
-  QEventLoop*                  myEventLoop;
+  QString                      myShapeEntry;
+  QString                      myMainShapeEntry;
 };
 
 class SMESHGUI_HypothesisDlg : public QtxDialog
@@ -131,20 +144,19 @@ public:
   SMESHGUI_HypothesisDlg( SMESHGUI_GenericHypothesisCreator*, QWidget* );
   virtual ~SMESHGUI_HypothesisDlg();
 
-  void                                 setHIcon( const QPixmap& );
-  void                                 setCustomFrame( QFrame* );
-  void                                 setType( const QString& );
+  void setHIcon( const QPixmap& );
+  void setCustomFrame( QFrame* );
+  void setType( const QString& );
 
 protected slots:
-  virtual void                         accept();
-  virtual void                         reject();
-  void                                 onHelp(); 
+  virtual void accept();
+  virtual void reject();
+  void onHelp(); 
 
 private:
-  SMESHGUI_GenericHypothesisCreator*   myCreator;
-  QLabel*                              myIconLabel;
-  QLabel*                              myTypeLabel;
-  QString                              myHelpFileName;
+  SMESHGUI_GenericHypothesisCreator* myCreator;
+  QLabel *myIconLabel, *myTypeLabel;
+  QString myHelpFileName;
 };
 
 /*!
@@ -158,7 +170,7 @@ public:
                   const QList<int>&, const bool,
                   const QStringList&, const QStringList&,
                   const QStringList&, const QStringList&,
-                 const bool=true, const bool supportSub=false );
+                  const bool=true, const bool supportSub=false );
 
   QString TypeName;        //!< hypothesis type name
   QString PluginName;      //!< plugin name
@@ -189,8 +201,32 @@ public:
   HypothesesSet( const QString& );
   HypothesesSet( const QString&, const QStringList&, const QStringList& );
 
-  QString     HypoSetName;
-  QStringList HypoList, AlgoList;
+  QString name() const;
+  void set( bool, const QStringList& );
+  int count( bool ) const;
+
+  void setIsCustom( bool );
+  bool getIsCustom() const;
+  int maxDim() const;
+
+  bool isAlgo() const;
+
+  //this method sets internal index to -1, thus before any data access it is necessary to call next()
+  void init( bool );
+
+  bool more() const;
+  void next();
+  QString current() const;
+
+private:
+  QStringList* list(bool) const;
+  QStringList* list() const;
+
+private:
+  QString     myHypoSetName;
+  QStringList myHypoList, myAlgoList;
+  bool myIsAlgo, myIsCustom;
+  int myIndex;
 };
 
 #endif // SMESHGUI_HYPOTHESES_H
index 5f3500230d4617ab7c32b62fecc2828bdc845f3c..d7e3e6ce685f63dad94af3d2e0016404a1ae7048 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_HypothesesUtils.cxx
 // Author : Julia DOROVSKIKH, Open CASCADE S.A.S.
 
 // Qt includes
 #include <QMap>
+#include <QDir>
 //#include <QList>
 
+
 // Other includes
 #ifdef WNT
 #include <windows.h>
@@ -78,52 +81,87 @@ static int MYDEBUG = 0;
 
 namespace SMESH
 {
-  typedef QMap<QString,HypothesisData*> THypothesisDataMap;
+  typedef IMap<QString,HypothesisData*> THypothesisDataMap;
   THypothesisDataMap myHypothesesMap;
   THypothesisDataMap myAlgorithmsMap;
-
-  typedef QMap<QString,SMESHGUI_GenericHypothesisCreator*> THypCreatorMap;
-  THypCreatorMap myHypCreatorMap;
+  
+  // BUG 0020378
+  //typedef QMap<QString,SMESHGUI_GenericHypothesisCreator*> THypCreatorMap;
+  //THypCreatorMap myHypCreatorMap;
 
   QList<HypothesesSet*> myListOfHypothesesSets;
 
   void processHypothesisStatus(const int theHypStatus,
-                              SMESH::SMESH_Hypothesis_ptr theHyp,
-                              const bool theIsAddition)
+                               SMESH::SMESH_Hypothesis_ptr theHyp,
+                               const bool theIsAddition)
   {
     if (theHypStatus > SMESH::HYP_OK) {
       // get Hyp name
       QString aHypName ("NULL Hypothesis");
       if (!CORBA::is_nil(theHyp)) {
-       _PTR(SObject) Shyp = SMESH::FindSObject(theHyp);
-       if (Shyp)
-         // name in study
-         aHypName = Shyp->GetName().c_str();
-       else
-         // label in xml file
-         aHypName = GetHypothesisData(theHyp->GetName())->Label;
+        _PTR(SObject) Shyp = SMESH::FindSObject(theHyp);
+        if (Shyp)
+          // name in study
+          aHypName = Shyp->GetName().c_str();
+        else
+          // label in xml file
+          aHypName = GetHypothesisData(theHyp->GetName())->Label;
       }
 
       // message
       bool isFatal = (theHypStatus >= SMESH::HYP_UNKNOWN_FATAL);
       QString aMsg;
       if (theIsAddition)
-       aMsg = (isFatal ? "SMESH_CANT_ADD_HYP" : "SMESH_ADD_HYP_WRN");
+        aMsg = (isFatal ? "SMESH_CANT_ADD_HYP" : "SMESH_ADD_HYP_WRN");
       else
-       aMsg = (isFatal ? "SMESH_CANT_RM_HYP"  : "SMESH_RM_HYP_WRN");
+        aMsg = (isFatal ? "SMESH_CANT_RM_HYP"  : "SMESH_RM_HYP_WRN");
 
       aMsg = QObject::tr(aMsg.toLatin1().data()).arg(aHypName) +
-       QObject::tr(QString("SMESH_HYP_%1").arg(theHypStatus).toLatin1().data());
+        QObject::tr(QString("SMESH_HYP_%1").arg(theHypStatus).toLatin1().data());
 
       if ( theHypStatus == SMESH::HYP_HIDDEN_ALGO ) // PAL18501
         aMsg = aMsg.arg( GetHypothesisData(theHyp->GetName())->Dim[0] );
 
       SUIT_MessageBox::warning(SMESHGUI::desktop(),
-                              QObject::tr("SMESH_WRN_WARNING"),
-                              aMsg);
+                               QObject::tr("SMESH_WRN_WARNING"),
+                               aMsg);
     }
   }
 
+  //================================================================================
+  /*!
+   * \brief Prepends dimension and appends '[custom]' to the name of hypothesis set
+   */
+  //================================================================================
+
+  static QString mangledHypoSetName(HypothesesSet* hypSet)
+  {
+    QString name = hypSet->name();
+
+    // prepend 'xD: '
+    int dim = hypSet->maxDim();
+    if ( dim > -1 )
+      name = QString("%1D: %2").arg(dim).arg(name);
+
+    // custom
+    if ( hypSet->getIsCustom() )
+      name = QString("%1 [custom]").arg(name);
+
+    return name;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Removes dimension and '[custom]' from the name of hypothesis set
+   */
+  //================================================================================
+
+  static QString demangledHypoSetName(QString name)
+  {
+    name.remove(QRegExp("[0-3]D: "));
+    name.remove(" [custom]");
+    return name;
+  }
 
   void InitAvailableHypotheses()
   {
@@ -137,72 +175,93 @@ namespace SMESH
       QString HypsXml;
       char* cenv = getenv("SMESH_MeshersList");
       if (cenv)
-       HypsXml.sprintf("%s", cenv);
+        HypsXml.sprintf("%s", cenv);
 
       QStringList HypsXmlList = HypsXml.split(":", QString::SkipEmptyParts);
       if (HypsXmlList.count() == 0) {
-       SUIT_MessageBox::critical(SMESHGUI::desktop(),
-                                 QObject::tr("SMESH_WRN_WARNING"),
-                                 QObject::tr("MESHERS_FILE_NO_VARIABLE"));
-       return;
+        SUIT_MessageBox::critical(SMESHGUI::desktop(),
+                                  QObject::tr("SMESH_WRN_WARNING"),
+                                  QObject::tr("MESHERS_FILE_NO_VARIABLE"));
+        return;
       }
-
-      // loop on files in HypsXml
-      QString aNoAccessFiles;
+      // get full names of xml files from HypsXmlList
+      QStringList xmlFiles;
+      xmlFiles.append( QDir::home().filePath("CustomMeshers.xml")); // may be inexistent
       for (int i = 0; i < HypsXmlList.count(); i++) {
-       QString HypsXml = HypsXmlList[ i ];
+        QString HypsXml = HypsXmlList[ i ];
 
-       // Find full path to the resource XML file
-       QString xmlFile = resMgr->path("resources", "SMESH", HypsXml + ".xml");
+        // Find full path to the resource XML file
+        QString xmlFile = resMgr->path("resources", "SMESH", HypsXml + ".xml");
         if ( xmlFile.isEmpty() ) // try PLUGIN resources
           xmlFile = resMgr->path("resources", HypsXml, HypsXml + ".xml");
-        
-       QFile file (xmlFile);
-       if (file.exists() && file.open(QIODevice::ReadOnly)) {
-         file.close();
-
-         SMESHGUI_XmlHandler* aXmlHandler = new SMESHGUI_XmlHandler();
-         ASSERT(aXmlHandler);
-
-         QXmlInputSource source (&file);
-         QXmlSimpleReader reader;
-         reader.setContentHandler(aXmlHandler);
-         reader.setErrorHandler(aXmlHandler);
-         bool ok = reader.parse(source);
-         file.close();
-         if (ok) {
-           myHypothesesMap.unite( aXmlHandler->myHypothesesMap );
-            myAlgorithmsMap.unite( aXmlHandler->myAlgorithmsMap );
-           QList<HypothesesSet*>::iterator it, pos = myListOfHypothesesSets.begin();
-           for ( it = aXmlHandler->myListOfHypothesesSets.begin(); 
-                 it != aXmlHandler->myListOfHypothesesSets.end();
-                 ++it ) {
-             myListOfHypothesesSets.insert( pos, *it );
-           }
-         }
-         else {
-           SUIT_MessageBox::critical(SMESHGUI::desktop(),
-                                     QObject::tr("INF_PARSE_ERROR"),
-                                     QObject::tr(aXmlHandler->errorProtocol().toLatin1().data()));
-         }
-       }
-       else {
-         if (aNoAccessFiles.isEmpty())
-           aNoAccessFiles = xmlFile;
-         else
-           aNoAccessFiles += ", " + xmlFile;
-       }
-      } // end loop
+        if ( !xmlFile.isEmpty() )
+          xmlFiles.append( xmlFile );
+      }
+
+      // loop on xmlFiles
+      QString aNoAccessFiles;
+      for (int i = 0; i < xmlFiles.count(); i++)
+      {
+        QString xmlFile = xmlFiles[ i ];
+        QFile file (xmlFile);
+        if (file.exists() && file.open(QIODevice::ReadOnly))
+        {
+          file.close();
+
+          SMESHGUI_XmlHandler* aXmlHandler = new SMESHGUI_XmlHandler();
+          ASSERT(aXmlHandler);
+
+          QXmlInputSource source (&file);
+          QXmlSimpleReader reader;
+          reader.setContentHandler(aXmlHandler);
+          reader.setErrorHandler(aXmlHandler);
+          bool ok = reader.parse(source);
+          file.close();
+          if (ok) {
+
+            THypothesisDataMap::ConstIterator it1 = aXmlHandler->myHypothesesMap.begin();
+            
+            for( ;it1 != aXmlHandler->myHypothesesMap.end(); it1++)
+              myHypothesesMap.insert( it1.key(), it1.value() );
+            
+            
+            it1 = aXmlHandler->myAlgorithmsMap.begin();
+            for( ;it1 != aXmlHandler->myAlgorithmsMap.end(); it1++)
+              myAlgorithmsMap.insert( it1.key(), it1.value() );
+            
+            QList<HypothesesSet*>::iterator it, pos = myListOfHypothesesSets.begin();
+            for ( it = aXmlHandler->myListOfHypothesesSets.begin(); 
+                  it != aXmlHandler->myListOfHypothesesSets.end();
+                  ++it )
+            {
+              (*it)->setIsCustom( i == 0 );
+              myListOfHypothesesSets.insert( pos, *it );
+            }
+          }
+          else {
+            SUIT_MessageBox::critical(SMESHGUI::desktop(),
+                                      QObject::tr("INF_PARSE_ERROR"),
+                                      QObject::tr(aXmlHandler->errorProtocol().toLatin1().data()));
+          }
+          delete aXmlHandler;
+        }
+        else if ( i > 0 ) { // 1st is ~/CustomMeshers.xml
+          if (aNoAccessFiles.isEmpty())
+            aNoAccessFiles = xmlFile;
+          else
+            aNoAccessFiles += ", " + xmlFile;
+        }
+      } // end loop on xmlFiles
 
 
       if (!aNoAccessFiles.isEmpty()) {
-       QString aMess = QObject::tr("MESHERS_FILE_CANT_OPEN") + " " + aNoAccessFiles + "\n";
-       aMess += QObject::tr("MESHERS_FILE_CHECK_VARIABLE");
-       wc.suspend();
-       SUIT_MessageBox::warning(SMESHGUI::desktop(),
-                                QObject::tr("SMESH_WRN_WARNING"),
-                                aMess);
-       wc.resume();
+        QString aMess = QObject::tr("MESHERS_FILE_CANT_OPEN") + " " + aNoAccessFiles + "\n";
+        aMess += QObject::tr("MESHERS_FILE_CHECK_VARIABLE");
+        wc.suspend();
+        SUIT_MessageBox::warning(SMESHGUI::desktop(),
+                                 QObject::tr("SMESH_WRN_WARNING"),
+                                 aMess);
+        wc.resume();
       }
     }
   }
@@ -220,24 +279,25 @@ namespace SMESH
     bool checkGeometry = ( !isNeedGeometry && isAlgo );
     // fill list of hypotheses/algorithms
     THypothesisDataMap& pMap = isAlgo ? myAlgorithmsMap : myHypothesesMap;
-    THypothesisDataMap::iterator anIter;
+    THypothesisDataMap::ConstIterator anIter;
     for ( anIter = pMap.begin(); anIter != pMap.end(); anIter++ ) {
       HypothesisData* aData = anIter.value();
+      if(!aData || aData->Label.isEmpty()) continue;
       if ( ( theDim < 0 || aData->Dim.contains( theDim ) ) && aData->IsAux == isAux) {
-       if (checkGeometry) {
-         if (aData->IsNeedGeometry == isNeedGeometry)
-           aHypList.append(anIter.key());
-       }
-       else {
-         aHypList.append(anIter.key());
-       }
+        if (checkGeometry) {
+          if (aData->IsNeedGeometry == isNeedGeometry)
+            aHypList.append(anIter.key());
+        }
+        else {
+          aHypList.append(anIter.key());
+        }
       }
     }
     return aHypList;
   }
 
 
-  QStringList GetHypothesesSets()
+  QStringList GetHypothesesSets(int maxDim)
   {
     QStringList aSetNameList;
 
@@ -246,26 +306,36 @@ namespace SMESH
 
     QList<HypothesesSet*>::iterator hypoSet;
     for ( hypoSet  = myListOfHypothesesSets.begin(); 
-         hypoSet != myListOfHypothesesSets.end();
-         ++hypoSet ) {
+          hypoSet != myListOfHypothesesSets.end();
+          ++hypoSet ) {
       HypothesesSet* aSet = *hypoSet;
-      if ( aSet && aSet->AlgoList.count() ) {
-       aSetNameList.append( aSet->HypoSetName );
+      if ( aSet &&
+           ( aSet->count( true ) || aSet->count( false )) &&
+           aSet->maxDim() <= maxDim)
+      {
+        aSetNameList.append( mangledHypoSetName( aSet ));
       }
     }
+    aSetNameList.sort();
+
+    //  reverse order of aSetNameList
+    QStringList reversedNames;
+    for ( int i = 0; i < aSetNameList.count(); ++i )
+      reversedNames.prepend( aSetNameList[i] );
     
-    return aSetNameList;
+    return reversedNames;
   }
 
   HypothesesSet* GetHypothesesSet(const QString& theSetName)
   {
+    QString name = demangledHypoSetName( theSetName );
     QList<HypothesesSet*>::iterator hypoSet;
     for ( hypoSet  = myListOfHypothesesSets.begin(); 
-         hypoSet != myListOfHypothesesSets.end();
-         ++hypoSet ) {
+          hypoSet != myListOfHypothesesSets.end();
+          ++hypoSet ) {
       HypothesesSet* aSet = *hypoSet;
-      if ( aSet && aSet->HypoSetName == theSetName )
-       return aSet;
+      if ( aSet && aSet->name() == name )
+        return aSet;
     }
     return 0;
   }
@@ -277,10 +347,10 @@ namespace SMESH
     // Init list of available hypotheses, if needed
     InitAvailableHypotheses();
 
-    if (myHypothesesMap.find(aHypType) != myHypothesesMap.end()) {
+    if (myHypothesesMap.contains(aHypType)) {
       aHypData = myHypothesesMap[aHypType];
     }
-    else if (myAlgorithmsMap.find(aHypType) != myAlgorithmsMap.end()) {
+    else if (myAlgorithmsMap.contains(aHypType)) {
       aHypData = myAlgorithmsMap[aHypType];
     }
     return aHypData;
@@ -326,10 +396,12 @@ namespace SMESH
     SMESHGUI_GenericHypothesisCreator* aCreator = 0;
 
     // check, if creator for this hypothesis type already exists
-    if (myHypCreatorMap.find(aHypType) != myHypCreatorMap.end()) {
-      aCreator = myHypCreatorMap[aHypType];
-    }
-    else {
+    // BUG 0020378
+    //if (myHypCreatorMap.find(aHypType) != myHypCreatorMap.end()) {
+    //  aCreator = myHypCreatorMap[aHypType];
+    //}
+    //else
+    {
       // 1. Init list of available hypotheses, if needed
       InitAvailableHypotheses();
 
@@ -337,52 +409,60 @@ namespace SMESH
       HypothesisData* aHypData = GetHypothesisData(aHypType);
       if (!aHypData) 
         return aCreator;
+
       QString aClientLibName = aHypData->ClientLibName;
       QString aServerLibName = aHypData->ServerLibName;
 
       // 3. Load Client Plugin Library
       try {
-       // load plugin library
-       if(MYDEBUG) MESSAGE("Loading client meshers plugin library ...");
-       LibHandle libHandle = LoadLib( aClientLibName.toLatin1().data() );
-       if (!libHandle) {
-         // report any error, if occured
-         if ( MYDEBUG ) {
+        // load plugin library
+        if(MYDEBUG) MESSAGE("Loading client meshers plugin library ...");
+        LibHandle libHandle = LoadLib( aClientLibName.toLatin1().data() );
+        if (!libHandle) {
+          // report any error, if occured
+          if ( MYDEBUG ) {
 #ifdef WIN32
-           const char* anError = "Can't load client meshers plugin library";
+            const char* anError = "Can't load client meshers plugin library";
 #else
-           const char* anError = dlerror();      
+            const char* anError = dlerror();      
 #endif
-           MESSAGE(anError);
-         }
-       }
-       else {
-         // get method, returning hypothesis creator
-         if(MYDEBUG) MESSAGE("Find GetHypothesisCreator() method ...");
-         typedef SMESHGUI_GenericHypothesisCreator* (*GetHypothesisCreator) \
-           ( const QString& );
-         GetHypothesisCreator procHandle =
-           (GetHypothesisCreator)GetProc(libHandle, "GetHypothesisCreator");
-         if (!procHandle) {
-           if(MYDEBUG) MESSAGE("bad hypothesis client plugin library");
-           UnLoadLib(libHandle);
-         }
-         else {
-           // get hypothesis creator
-           if(MYDEBUG) MESSAGE("Get Hypothesis Creator for " << aHypType.toLatin1().data());
-           aCreator = procHandle( aHypType );
-           if (!aCreator) {
-             if(MYDEBUG) MESSAGE("no such a hypothesis in this plugin");
-           }
-           else {
-             // map hypothesis creator to a hypothesis name
-             myHypCreatorMap[aHypType] = aCreator;
-           }
-         }
-       }
+            MESSAGE(anError);
+          }
+        }
+        else {
+          // get method, returning hypothesis creator
+          if(MYDEBUG) MESSAGE("Find GetHypothesisCreator() method ...");
+          typedef SMESHGUI_GenericHypothesisCreator* (*GetHypothesisCreator) \
+            ( const QString& );
+          GetHypothesisCreator procHandle =
+            (GetHypothesisCreator)GetProc(libHandle, "GetHypothesisCreator");
+          if (!procHandle) {
+            if(MYDEBUG) MESSAGE("bad hypothesis client plugin library");
+            UnLoadLib(libHandle);
+          }
+          else {
+            // get hypothesis creator
+            if(MYDEBUG) MESSAGE("Get Hypothesis Creator for " << aHypType.toLatin1().data());
+            aCreator = procHandle( aHypType );
+            if (!aCreator) {
+              if(MYDEBUG) MESSAGE("no such a hypothesis in this plugin");
+            }
+            else {
+              // map hypothesis creator to a hypothesis name
+              // BUG 0020378
+              //myHypCreatorMap[aHypType] = aCreator;
+
+             //rnv : This dynamic property of the QObject stores the name of the plugin.
+             //      It is used to obtain plugin root dir environment variable
+              //      in the SMESHGUI_HypothesisDlg class. Plugin root dir environment 
+             //      variable is used to display documentation.
+             aCreator->setProperty(PLUGIN_NAME,aHypData->PluginName);
+            }
+          }
+        }
       }
       catch (const SALOME::SALOME_Exception& S_ex) {
-       SalomeApp_Tools::QtCatchCorbaException(S_ex);
+        SalomeApp_Tools::QtCatchCorbaException(S_ex);
       }
     }
 
@@ -391,25 +471,26 @@ namespace SMESH
 
 
   SMESH::SMESH_Hypothesis_ptr CreateHypothesis(const QString& aHypType,
-                                              const QString& aHypName,
-                                              const bool isAlgo)
+                                               const QString& aHypName,
+                                               const bool isAlgo)
   {
     if(MYDEBUG) MESSAGE("Create " << aHypType.toLatin1().data() << 
-                       " with name " << aHypName.toLatin1().data());
+                        " with name " << aHypName.toLatin1().data());
     HypothesisData* aHypData = GetHypothesisData(aHypType);
     QString aServLib = aHypData->ServerLibName;
     try {
       SMESH::SMESH_Hypothesis_var aHypothesis;
       aHypothesis = SMESHGUI::GetSMESHGen()->CreateHypothesis(aHypType.toLatin1().data(),
-                                                             aServLib.toLatin1().data());
+                                                              aServLib.toLatin1().data());
       if (!aHypothesis->_is_nil()) {
-       _PTR(SObject) aHypSObject = SMESH::FindSObject(aHypothesis.in());
-       if (aHypSObject) {
-         if (!aHypName.isEmpty())
-           SMESH::SetName(aHypSObject, aHypName);
-         SMESHGUI::GetSMESHGUI()->updateObjBrowser();
-         return aHypothesis._retn();
-       }
+        _PTR(SObject) aHypSObject = SMESH::FindSObject(aHypothesis.in());
+        if (aHypSObject) {
+          if (!aHypName.isEmpty())
+            SMESH::SetName(aHypSObject, aHypName);
+          SMESHGUI::Modified();
+          SMESHGUI::GetSMESHGUI()->updateObjBrowser();
+          return aHypothesis._retn();
+        }
       }
     } catch (const SALOME::SALOME_Exception & S_ex) {
       SalomeApp_Tools::QtCatchCorbaException(S_ex);
@@ -429,23 +510,23 @@ namespace SMESH
       _PTR(SObject) SM = SMESH::FindSObject(aMesh);
       GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(SM);
       try {
-       res = aMesh->AddHypothesis(aShapeObject, aHyp);
-       if (res < SMESH::HYP_UNKNOWN_FATAL) {
-         _PTR(SObject) aSH = SMESH::FindSObject(aHyp);
-         if (SM && aSH) {
-           SMESH::ModifiedMesh(SM, false, aMesh->NbNodes()==0);
-         }
-       }
-       if (res > SMESH::HYP_OK) {
-         wc.suspend();
-         processHypothesisStatus(res, aHyp, true);
-         wc.resume();
-       }
+        res = aMesh->AddHypothesis(aShapeObject, aHyp);
+        if (res < SMESH::HYP_UNKNOWN_FATAL) {
+          _PTR(SObject) aSH = SMESH::FindSObject(aHyp);
+          if (SM && aSH) {
+            SMESH::ModifiedMesh(SM, false, aMesh->NbNodes()==0);
+          }
+        }
+        if (res > SMESH::HYP_OK) {
+          wc.suspend();
+          processHypothesisStatus(res, aHyp, true);
+          wc.resume();
+        }
       }
       catch(const SALOME::SALOME_Exception& S_ex) {
-       wc.suspend();
-       SalomeApp_Tools::QtCatchCorbaException(S_ex);
-       res = SMESH::HYP_UNKNOWN_FATAL;
+        wc.suspend();
+        SalomeApp_Tools::QtCatchCorbaException(S_ex);
+        res = SMESH::HYP_UNKNOWN_FATAL;
       }
     }
     return res < SMESH::HYP_UNKNOWN_FATAL;
@@ -460,33 +541,33 @@ namespace SMESH
 
     if (!aSubMesh->_is_nil() && ! aHyp->_is_nil()) {
       try {
-       SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather();
-       _PTR(SObject) SsubM = SMESH::FindSObject(aSubMesh);
-       GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(SsubM);
-       if (!aMesh->_is_nil() && SsubM && !aShapeObject->_is_nil()) {
-         res = aMesh->AddHypothesis(aShapeObject, aHyp);
-         if (res < SMESH::HYP_UNKNOWN_FATAL)  {
+        SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather();
+        _PTR(SObject) SsubM = SMESH::FindSObject(aSubMesh);
+        GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(SsubM);
+        if (!aMesh->_is_nil() && SsubM && !aShapeObject->_is_nil()) {
+          res = aMesh->AddHypothesis(aShapeObject, aHyp);
+          if (res < SMESH::HYP_UNKNOWN_FATAL)  {
             _PTR(SObject) meshSO = SMESH::FindSObject(aMesh);
             if (meshSO)
               SMESH::ModifiedMesh(meshSO, false, aMesh->NbNodes()==0);
-         }
-         if (res > SMESH::HYP_OK) {
-           wc.suspend();
-           processHypothesisStatus(res, aHyp, true);
-           wc.resume();
-         }
-       }
-       else {
-         SCRUTE(aHyp->_is_nil());
-         SCRUTE(aMesh->_is_nil());
-         SCRUTE(!SsubM);
-         SCRUTE(aShapeObject->_is_nil());
-       }
+          }
+          if (res > SMESH::HYP_OK) {
+            wc.suspend();
+            processHypothesisStatus(res, aHyp, true);
+            wc.resume();
+          }
+        }
+        else {
+          SCRUTE(aHyp->_is_nil());
+          SCRUTE(aMesh->_is_nil());
+          SCRUTE(!SsubM);
+          SCRUTE(aShapeObject->_is_nil());
+        }
       }
       catch(const SALOME::SALOME_Exception& S_ex) {
-       wc.suspend();
-       SalomeApp_Tools::QtCatchCorbaException(S_ex);
-       res = SMESH::HYP_UNKNOWN_FATAL;
+        wc.suspend();
+        SalomeApp_Tools::QtCatchCorbaException(S_ex);
+        res = SMESH::HYP_UNKNOWN_FATAL;
       }
     }
     else {
@@ -505,28 +586,28 @@ namespace SMESH
       _PTR(Study) aStudy = GetActiveStudyDocument();
       _PTR(SObject) aHypObj = aStudy->FindObjectID( IObject->getEntry() );
       if( aHypObj )
-       {
-         _PTR(SObject) MorSM = SMESH::GetMeshOrSubmesh( aHypObj );
-         _PTR(SObject) aRealHypo;
-         if( aHypObj->ReferencedObject( aRealHypo ) )
-           {
-             SMESH_Hypothesis_var hypo = SMESH_Hypothesis::_narrow( SObjectToObject( aRealHypo ) );
-             RemoveHypothesisOrAlgorithmOnMesh( MorSM, hypo );
-           }
-         else
-           {
-             SMESH_Hypothesis_var hypo = SMESH_Hypothesis::_narrow( SObjectToObject( aHypObj ) );
-             SObjectList meshList = GetMeshesUsingAlgoOrHypothesis( hypo );
-             for( int i = 0; i < meshList.size(); i++ )
-               RemoveHypothesisOrAlgorithmOnMesh( meshList[ i ], hypo );
-           }
-       }
+        {
+          _PTR(SObject) MorSM = SMESH::GetMeshOrSubmesh( aHypObj );
+          _PTR(SObject) aRealHypo;
+          if( aHypObj->ReferencedObject( aRealHypo ) )
+            {
+              SMESH_Hypothesis_var hypo = SMESH_Hypothesis::_narrow( SObjectToObject( aRealHypo ) );
+              RemoveHypothesisOrAlgorithmOnMesh( MorSM, hypo );
+            }
+          else
+            {
+              SMESH_Hypothesis_var hypo = SMESH_Hypothesis::_narrow( SObjectToObject( aHypObj ) );
+              SObjectList meshList = GetMeshesUsingAlgoOrHypothesis( hypo );
+              for( int i = 0; i < meshList.size(); i++ )
+                RemoveHypothesisOrAlgorithmOnMesh( meshList[ i ], hypo );
+            }
+        }
     }
     catch(const SALOME::SALOME_Exception& S_ex)
       {
-       wc.suspend();
-       SalomeApp_Tools::QtCatchCorbaException(S_ex);
-       res = SMESH::HYP_UNKNOWN_FATAL;
+        wc.suspend();
+        SalomeApp_Tools::QtCatchCorbaException(S_ex);
+        res = SMESH::HYP_UNKNOWN_FATAL;
       }
     return res < SMESH::HYP_UNKNOWN_FATAL;
   }
@@ -560,7 +641,7 @@ namespace SMESH
           }
           else if(!aMesh->HasShapeToMesh()){
             res = aMesh->RemoveHypothesis(aShapeObject, anHyp);
-           if (res < SMESH::HYP_UNKNOWN_FATAL) {
+            if (res < SMESH::HYP_UNKNOWN_FATAL) {
               _PTR(SObject) meshSO = SMESH::FindSObject(aMesh);
               if (meshSO)
                 SMESH::ModifiedMesh(meshSO, false, aMesh->NbNodes()==0);              
@@ -573,9 +654,9 @@ namespace SMESH
           }
         }
       } catch(const SALOME::SALOME_Exception& S_ex) {
-       wc.suspend();
-       SalomeApp_Tools::QtCatchCorbaException(S_ex);
-       res = SMESH::HYP_UNKNOWN_FATAL;
+        wc.suspend();
+        SalomeApp_Tools::QtCatchCorbaException(S_ex);
+        res = SMESH::HYP_UNKNOWN_FATAL;
       }
     }
     return res < SMESH::HYP_UNKNOWN_FATAL;
@@ -590,25 +671,25 @@ namespace SMESH
     if (!AlgoOrHyp->_is_nil()) {
       _PTR(SObject) SO_Hypothesis = SMESH::FindSObject(AlgoOrHyp);
       if (SO_Hypothesis) {
-       SObjectList listSO =
-         SMESHGUI::activeStudy()->studyDS()->FindDependances(SO_Hypothesis);
-
-       if(MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): dependency number ="<<listSO.size());
-       for (unsigned int i = 0; i < listSO.size(); i++) {
-         _PTR(SObject) SO = listSO[i];
-         if (SO) {
-           _PTR(SObject) aFather = SO->GetFather();
-           if (aFather) {
-             _PTR(SObject) SOfatherFather = aFather->GetFather();
-             if (SOfatherFather) {
-               if(MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): dependency added to list");
-               index++;
-               listSOmesh.resize(index);
-               listSOmesh[index - 1] = SOfatherFather;
-             }
-           }
-         }
-       }
+        SObjectList listSO =
+          SMESHGUI::activeStudy()->studyDS()->FindDependances(SO_Hypothesis);
+
+        if(MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): dependency number ="<<listSO.size());
+        for (unsigned int i = 0; i < listSO.size(); i++) {
+          _PTR(SObject) SO = listSO[i];
+          if (SO) {
+            _PTR(SObject) aFather = SO->GetFather();
+            if (aFather) {
+              _PTR(SObject) SOfatherFather = aFather->GetFather();
+              if (SOfatherFather) {
+                if(MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): dependency added to list");
+                index++;
+                listSOmesh.resize(index);
+                listSOmesh[index - 1] = SOfatherFather;
+              }
+            }
+          }
+        }
       }
     }
     if (MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): completed");
index 18813f4c8bcd1b1ce834b18673322dc91e9f2da0..c1e4853138e1e792e1994eaa4dbcb7bda9eb4d1c 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_HypothesesUtils.h
 // Author : Julia DOROVSKIKH, Open CASCADE S.A.S.
 // STL includes
 #include <vector>
 
+// boost includes
+#include <boost/shared_ptr.hpp>
+
 class HypothesisData;
 class HypothesesSet;
 class SMESHGUI_GenericHypothesisCreator;
 class SALOMEDSClient_SObject;
 class algo_error_array;
 
+
+#define PLUGIN_NAME "PLUGIN_NAME"
+
 namespace SMESH
 {
   SMESHGUI_EXPORT
@@ -62,9 +69,9 @@ namespace SMESH
   QStringList GetAvailableHypotheses( const bool, 
                                       const int = -1, 
                                       const bool = false,
-                                     const bool = true);
+                                      const bool = true);
   SMESHGUI_EXPORT
-  QStringList GetHypothesesSets();
+  QStringList GetHypothesesSets( int maxDim );
 
   SMESHGUI_EXPORT
   HypothesesSet* GetHypothesesSet( const QString& );
@@ -74,20 +81,20 @@ namespace SMESH
 
   SMESHGUI_EXPORT
   bool IsAvailableHypothesis( const HypothesisData*,
-                             const QString&,
-                             bool& );
+                              const QString&,
+                              bool& );
 
   SMESHGUI_EXPORT
   bool IsCompatibleAlgorithm( const HypothesisData*,
-                             const HypothesisData* );
+                              const HypothesisData* );
 
   SMESHGUI_EXPORT
   SMESHGUI_GenericHypothesisCreator* GetHypothesisCreator( const QString& );
 
   SMESHGUI_EXPORT
   SMESH::SMESH_Hypothesis_ptr CreateHypothesis( const QString&,
-                                               const QString&,
-                                               const bool = false);
+                                                const QString&,
+                                                const bool = false );
 
   SMESHGUI_EXPORT
   bool AddHypothesisOnMesh( SMESH::SMESH_Mesh_ptr, SMESH::SMESH_Hypothesis_ptr );
@@ -100,7 +107,7 @@ namespace SMESH
 
   SMESHGUI_EXPORT
   bool RemoveHypothesisOrAlgorithmOnMesh( _PTR(SObject),
-                                         SMESH::SMESH_Hypothesis_ptr );
+                                          SMESH::SMESH_Hypothesis_ptr );
 
   typedef std::vector<_PTR(SObject)> SObjectList;
   SObjectList GetMeshesUsingAlgoOrHypothesis( SMESH::SMESH_Hypothesis_ptr );
index 66dcd6322dab4ba14efa6f233622b59257705749..b6b06db0b896f624f8c1437e1b4ff3fb4eed1bb2 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_IdValidator.h
 // Author : Edward AGAPOV, Open CASCADE S.A.S.
@@ -47,15 +48,15 @@ public:
       // truncate extra ids
       int ind = 0, nbId = 0;
       while ( ind < input.length() ) {
-       if ( input.at( ind ) != ' ' ) {
-         if ( ++nbId > myMaxNbId ) {
-           input.truncate( ind );
-           break;
-         }
-         ind = input.indexOf( ' ', ind );
-         if ( ind < 0 ) break;
-       }
-       ind++;
+        if ( input.at( ind ) != ' ' ) {
+          if ( ++nbId > myMaxNbId ) {
+            input.truncate( ind );
+            break;
+          }
+          ind = input.indexOf( ' ', ind );
+          if ( ind < 0 ) break;
+        }
+        ind++;
       }
     }
     if ( pos > input.length() )
diff --git a/src/SMESHGUI/SMESHGUI_Make2DFrom3DOp.cxx b/src/SMESHGUI/SMESHGUI_Make2DFrom3DOp.cxx
new file mode 100644 (file)
index 0000000..8cdc5b0
--- /dev/null
@@ -0,0 +1,529 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+// File   : SMESHGUI_Make2DFrom3D.cxx
+// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+
+#include "SMESHGUI_Make2DFrom3DOp.h"
+
+#include "SMESHGUI.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_MeshUtils.h"
+#include "SMESH_TypeFilter.hxx"
+#include "SMESH_LogicalFilter.hxx"
+#include "SMESHGUI_VTKUtils.h"
+#include "SMESH_Actor.h"
+
+// SALOME GUI includes
+#include <LightApp_Application.h>
+#include <LightApp_SelectionMgr.h>
+#include <LightApp_UpdateFlags.h>
+#include <SALOME_ListIO.hxx>
+#include <SUIT_Desktop.h>
+#include <SUIT_MessageBox.h>
+#include <SUIT_OverrideCursor.h>
+#include <SUIT_Session.h>
+#include <SVTK_ViewModel.h>
+//#include <SVTK_ViewWindow.h>
+#include <SalomeApp_Study.h>
+#include <SalomeApp_Tools.h>
+
+// IDL includes
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Group)
+
+// Qt includes
+#include <QGroupBox>
+#include <QRadioButton>
+#include <QLineEdit>
+#include <QCheckBox>
+#include <QHBoxLayout>
+#include <QGridLayout>
+#include <QToolButton>
+
+#include <Standard_ErrorHandler.hxx>
+
+#define SPACING 6
+#define MARGIN  11
+
+/*!
+  \class SMESHGUI_Make2DFrom3DDlg
+  \brief Copy Mesh dialog box
+*/
+
+SMESHGUI_Make2DFrom3DDlg::SMESHGUI_Make2DFrom3DDlg( QWidget* parent )
+  : SMESHGUI_Dialog( parent, false, true, OK | Apply | Close | Help )
+{
+  // title
+  setWindowTitle( tr("CAPTION") );
+
+  // mode
+  QGroupBox* aModeGrp = new QGroupBox( tr( "MODE" ), mainFrame() );
+  QHBoxLayout* aModeGrpLayout = new QHBoxLayout( aModeGrp );
+  aModeGrpLayout->setMargin( MARGIN );
+  aModeGrpLayout->setSpacing( SPACING );
+  my2dFrom3dRB = new QRadioButton( tr( "2D_FROM_3D" ), aModeGrp );
+  my1dFrom2dRB = new QRadioButton( tr( "1D_FROM_2D" ), aModeGrp );
+  //my1dFrom3dRB = new QRadioButton( tr( "1D_FROM_3D" ), aModeGrp );
+  aModeGrpLayout->addWidget( my2dFrom3dRB );
+  aModeGrpLayout->addWidget( my1dFrom2dRB );
+  //aModeGrpLayout->addWidget( my1dFrom3dRB );
+
+//   // Groups of mesh faces
+//   setObjectPixmap( "SMESH", tr( "ICON_SELECT" ) );
+//   createObject( tr( "Groups" ), mainFrame(), Groups );
+//   setNameIndication( Groups, ListOfNames );
+//   objectWg( Groups, Btn )->hide();
+
+  // Mesh or Groups
+  //setObjectPixmap( "SMESH", tr( "ICON_SELECT" ) );
+  createObject( tr( "Groups" ), mainFrame(), MeshOrGroups );
+  setNameIndication( MeshOrGroups, ListOfNames );
+  objectWg( MeshOrGroups, Btn )->hide();
+
+  // target
+  QGroupBox* aTargetGrp = new QGroupBox( tr( "TARGET" ), mainFrame() );
+  QGridLayout* aTargetGrpLayout = new QGridLayout( aTargetGrp );
+  aTargetGrpLayout->setMargin( MARGIN );
+  aTargetGrpLayout->setSpacing( SPACING );
+  myThisMeshRB   = new QRadioButton( tr( "THIS_MESH" ), aTargetGrp );
+  myNewMeshRB    = new QRadioButton( tr( "NEW_MESH" ),  aTargetGrp );
+  myMeshName     = new QLineEdit( aTargetGrp );
+  myCopyCheck    = new QCheckBox( tr( "COPY_SRC" ),     aTargetGrp );
+  aTargetGrpLayout->addWidget( myThisMeshRB,    0, 0 );
+  aTargetGrpLayout->addWidget( myNewMeshRB,     1, 0 );
+  aTargetGrpLayout->addWidget( myMeshName,     1, 1 );
+  aTargetGrpLayout->addWidget( myCopyCheck,    2, 0 );
+  myGroupCheck = new QCheckBox( tr( "CREATE_GROUP" ), mainFrame() );
+  myGroupName  = new QLineEdit( mainFrame() );
+
+  // layout
+  QGridLayout* aDlgLay = new QGridLayout( mainFrame() );
+  aDlgLay->setMargin( 0 );
+  aDlgLay->setSpacing( SPACING );
+  aDlgLay->addWidget( aModeGrp,     0, 0, 1, 3 );
+  aDlgLay->addWidget( objectWg( MeshOrGroups,  Label ),   1, 0 );
+  aDlgLay->addWidget( objectWg( MeshOrGroups,  Control ), 1, 1 );
+  aDlgLay->addWidget( aTargetGrp,   2, 0, 1, 3 );
+  aDlgLay->addWidget( myGroupCheck, 3, 0 );
+  aDlgLay->addWidget( myGroupName,  3, 1, 1, 2 );
+
+  // connect signals  
+  connect( myThisMeshRB, SIGNAL( clicked() ), this, SLOT( onTargetChanged() ) );
+  connect( myNewMeshRB,  SIGNAL( clicked() ), this, SLOT( onTargetChanged() ) );
+  connect( myGroupCheck, SIGNAL( clicked() ), this, SLOT( onGroupChecked() ) );
+
+  // init dlg
+  my2dFrom3dRB->setChecked( true );
+  myThisMeshRB->setChecked( true );
+  onTargetChanged();
+  onGroupChecked();
+}
+
+SMESHGUI_Make2DFrom3DDlg::~SMESHGUI_Make2DFrom3DDlg()
+{
+}
+
+SMESH::Bnd_Dimension SMESHGUI_Make2DFrom3DDlg::mode() const
+{
+  if ( my2dFrom3dRB->isChecked() )
+    return SMESH::BND_2DFROM3D;
+  else if ( my1dFrom2dRB->isChecked() )
+    return SMESH::BND_1DFROM2D;
+  else
+    return SMESH::BND_1DFROM3D;
+}
+
+bool SMESHGUI_Make2DFrom3DDlg::needNewMesh() const
+{
+  return myNewMeshRB->isChecked();
+}
+
+QString SMESHGUI_Make2DFrom3DDlg::getNewMeshName() const
+{
+  return myMeshName->text().trimmed();
+}
+
+void SMESHGUI_Make2DFrom3DDlg::setNewMeshName( const QString& name )
+{
+  myMeshName->setText( name );
+}
+
+void SMESHGUI_Make2DFrom3DDlg::setNewMeshEnabled( bool enable )
+{
+  if ( !enable )
+    myThisMeshRB->setChecked( true );
+
+  myNewMeshRB->setEnabled( enable );
+
+  onTargetChanged();
+}
+
+bool SMESHGUI_Make2DFrom3DDlg::getNewMeshEnabled() const
+{
+  return myNewMeshRB->isEnabled();
+}
+
+bool SMESHGUI_Make2DFrom3DDlg::needGroup() const
+{
+  return myGroupCheck->isChecked();
+}
+
+QString SMESHGUI_Make2DFrom3DDlg::getGroupName() const
+{
+  return myGroupName->text().trimmed();
+}
+
+void SMESHGUI_Make2DFrom3DDlg::setGroupName( const QString& name )
+{
+  myGroupName->setText( name );
+}
+
+bool SMESHGUI_Make2DFrom3DDlg::copySource() const
+{
+  return myCopyCheck->isChecked();
+}
+
+void SMESHGUI_Make2DFrom3DDlg::onTargetChanged()
+{
+  myMeshName->setEnabled( myNewMeshRB->isChecked() );
+  myCopyCheck->setEnabled( myNewMeshRB->isChecked() );
+}
+
+void SMESHGUI_Make2DFrom3DDlg::onGroupChecked()
+{
+  myGroupName->setEnabled( myGroupCheck->isChecked() );
+}
+
+/*!
+  \class SMESHGUI_Make2DFrom3DOp
+  \brief Copy Mesh operation class
+*/
+
+SMESHGUI_Make2DFrom3DOp::SMESHGUI_Make2DFrom3DOp()
+  : SMESHGUI_SelectionOp(),
+    myMeshFilter(MESH),
+    myGroupFilter(GROUP)
+{
+}
+
+SMESHGUI_Make2DFrom3DOp::~SMESHGUI_Make2DFrom3DOp()
+{
+  if ( myDlg )
+    delete myDlg;
+}
+
+LightApp_Dialog* SMESHGUI_Make2DFrom3DOp::dlg() const
+{
+  return myDlg;
+}
+
+void SMESHGUI_Make2DFrom3DOp::startOperation()
+{
+  if( !myDlg )
+    myDlg = new SMESHGUI_Make2DFrom3DDlg( desktop() );
+
+  myHelpFileName = "make_2dmesh_from_3d_page.html";
+
+  SMESHGUI_SelectionOp::startOperation();
+
+  myDlg->setNewMeshName( SMESH::UniqueName( "Mesh_1" ) );
+  myDlg->setGroupName( SMESH::UniqueName( "Group" ) );
+  myDlg->show();
+
+  connect( myDlg->my2dFrom3dRB, SIGNAL( toggled(bool) ), this, SLOT( onModeChanged() ) );
+  connect( myDlg->my1dFrom2dRB, SIGNAL( toggled(bool) ), this, SLOT( onModeChanged() ) );
+  //connect( myDlg->my1dFrom3dRB, SIGNAL( toggled(bool) ), this, SLOT( onModeChanged() ) );
+
+  //onModeChanged();
+
+  myDlg->activateObject( SMESHGUI_Make2DFrom3DDlg::MeshOrGroups );
+  selectionDone();
+}
+
+//================================================================================
+/*!
+ * \brief Set filter corresponding to dimension
+ */
+//================================================================================
+
+void SMESHGUI_Make2DFrom3DOp::onModeChanged()
+{
+//   QRadioButton* b = dynamic_cast<QRadioButton*>( sender());
+//   if ( b && !b->isChecked() )
+//     return;
+
+//   // enable "2D groups" field
+//   bool enableGroups = ( myDlg->mode() == SMESH::BND_1DFROM3D );
+//   myDlg->setObjectEnabled( SMESHGUI_Make2DFrom3DDlg::Groups, enableGroups );
+//   ((QToolButton*) myDlg->objectWg( SMESHGUI_Make2DFrom3DDlg::Groups,
+//                                    SMESHGUI_Make2DFrom3DDlg::Btn ))->setChecked( enableGroups );
+  
+//   // install filter
+//   int id =  enableGroups ? SMESHGUI_Make2DFrom3DDlg::Groups : SMESHGUI_Make2DFrom3DDlg::Mesh;
+//   onDeactivateObject( SMESHGUI_Make2DFrom3DDlg::MeshOrGroups );
+//   onActivateObject  ( SMESHGUI_Make2DFrom3DDlg::MeshOrGroups );
+//   selectionDone();
+}
+
+void SMESHGUI_Make2DFrom3DOp::selectionDone()
+{
+  myDlg->clearSelection( SMESHGUI_Make2DFrom3DDlg::MeshOrGroups );
+  mySrcMesh = SMESH::SMESH_Mesh::_nil();
+
+  if ( !dlg() ) return;
+
+  
+  if ( dlg()->isVisible() ) {
+    try {
+      QStringList names, ids;
+      LightApp_Dialog::TypesList types;
+      selected( names, types, ids );
+      for ( int i = 0; i < names.count(); ++i )
+        names[i] = names[i].trimmed();
+      myDlg->selectObject( names, types, ids );
+
+      // enable/desable "new mesh" button
+      bool isMesh = true;
+      for ( int i = 0; i < ids.count() && isMesh; ++i )
+      {
+        _PTR(SObject) sobj =
+          SMESHGUI::activeStudy()->studyDS()->FindObjectID( ids[i].toLatin1().constData() );
+        mySrcMesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>( sobj );  
+        isMesh = !mySrcMesh->_is_nil();
+      }
+      myDlg->setNewMeshEnabled( isMesh );
+    }
+    catch ( const SALOME::SALOME_Exception& S_ex ) {
+      SalomeApp_Tools::QtCatchCorbaException( S_ex );
+    }
+    catch ( ... ) {
+    }
+  }
+}
+
+SUIT_SelectionFilter* SMESHGUI_Make2DFrom3DOp::createFilter( const int theId ) const
+{
+  SMESHGUI_Make2DFrom3DOp* me = (SMESHGUI_Make2DFrom3DOp*) this;
+
+  QList<SUIT_SelectionFilter*> subFilters;
+  subFilters.append( & me->myMeshFilter );
+  subFilters.append( & me->myGroupFilter );
+
+  SUIT_SelectionFilter* f = new SMESH_LogicalFilter( subFilters, SMESH_LogicalFilter::LO_OR );
+  return f;
+}
+
+bool SMESHGUI_Make2DFrom3DOp::isValid( QString& msg ) const
+{
+  if ( !dlg() ) return false;
+
+  // check if a mesh is selected
+  if ( !myDlg->hasSelection( SMESHGUI_Make2DFrom3DDlg::MeshOrGroups ))
+  {
+    msg = tr( "SMESH_ERR_NO_INPUT_MESH" );
+    return false;
+  }
+  QStringList entries;
+  dlg()->selectedObject( SMESHGUI_Make2DFrom3DDlg::MeshOrGroups, entries );
+  const bool isMeshSelected = ( !mySrcMesh->_is_nil() );
+  if ( isMeshSelected )
+  {
+    // only one mesh is allowed
+    if ( entries.size() > 1 ) {
+      msg = tr( "SMESH_TOO_MANY_MESHES" );
+      return false;
+    }
+  }
+  else
+  {
+    // check if only groups are selected
+    for ( int i = 0; i < entries.count(); ++i )
+    {
+      SMESH::SMESH_GroupBase_var grp;
+      if ( _PTR(SObject) sobj = SMESHGUI::activeStudy()->studyDS()->FindObjectID( entries[i].toLatin1().constData() ))
+        grp = SMESH::SObjectToInterface<SMESH::SMESH_GroupBase>( sobj );
+      if ( grp->_is_nil() ) {
+        msg = tr( "SMESH_NOT_ONLY_GROUPS" );
+        return false;
+      }
+    }
+  }
+  // check if the selected objects contains elements of required type
+  bool hasFaces = false, hasVolumes = false;
+  SMESH::Bnd_Dimension mode = myDlg->mode();
+  for ( int i = 0; i < entries.count(); ++i )
+  {
+    SMESH::SMESH_IDSource_var idSource;
+    if ( _PTR(SObject) sobj = SMESHGUI::activeStudy()->studyDS()->FindObjectID( entries[i].toLatin1().constData() ))
+      idSource = SMESH::SObjectToInterface<SMESH::SMESH_IDSource>( sobj );
+    if ( !idSource->_is_nil() ) {
+      SMESH::array_of_ElementType_var types = idSource->GetTypes();
+      for ( int j = 0; j < types->length(); ++j )
+        if ( types[j] == SMESH::VOLUME )
+          hasVolumes = true;
+        else if ( types[j] == SMESH::FACE )
+          hasFaces = true;
+    }
+  }
+  if ( mode == SMESH::BND_2DFROM3D && !hasVolumes ) {
+    msg = tr( "SMESH_ERR_NO_3D_ELEMENTS" );
+    return false;
+  }
+  else if ( mode == SMESH::BND_1DFROM2D && !hasFaces  ) {
+    msg = tr( "SMESH_ERR_NO_2D_ELEMENTS" );
+    return false;
+  }
+
+  // check if new mesh name is specified
+  if ( myDlg->needNewMesh() && myDlg->getNewMeshName().isEmpty() ) {
+    msg = tr( "SMESH_ERR_MESH_NAME_NOT_SPECIFIED" );
+    return false;
+  }
+
+  // check if group name is specified
+  if ( myDlg->needGroup() && myDlg->getGroupName().isEmpty() ) {
+    msg = tr( "SMESH_ERR_GRP_NAME_NOT_SPECIFIED" );
+    return false;
+  }
+
+  return true;
+}
+
+bool SMESHGUI_Make2DFrom3DOp::compute2DMesh( QStringList& theEntryList )
+{
+  SUIT_OverrideCursor wc;
+
+  bool ok = false;
+  try {
+    SMESH::Bnd_Dimension mode = myDlg->mode();
+    QString meshName          = myDlg->needNewMesh() ? myDlg->getNewMeshName() : QString();
+    QString groupName         = myDlg->needGroup()   ? myDlg->getGroupName()   : QString();
+    bool copyAll              = myDlg->copySource();
+
+    QStringList entries;
+    dlg()->selectedObject( SMESHGUI_Make2DFrom3DDlg::MeshOrGroups, entries );
+    SMESH::ListOfIDSources_var groups = new SMESH::ListOfIDSources;
+    QString wrongGroups = "";
+
+    if ( mySrcMesh->_is_nil() ) // get selected groups, find groups of wrong type
+    {
+      int nbGroups = 0;
+      int goodType = ( mode == SMESH::BND_2DFROM3D ? SMESH::VOLUME : SMESH::FACE );
+      groups->length( entries.count() );
+      for ( int i = 0; i < entries.count(); ++i )
+      {
+        _PTR(SObject) sobj =
+          SMESHGUI::activeStudy()->studyDS()->FindObjectID( entries[i].toLatin1().constData() );
+        SMESH::SMESH_IDSource_var grp = SMESH::SObjectToInterface<SMESH::SMESH_IDSource>( sobj );  
+        SMESH::array_of_ElementType_var types = grp->GetTypes();
+        if ( types->length() < 1 || types[0] != goodType )
+        {
+          if ( !wrongGroups.isEmpty() )
+            wrongGroups += ", ";
+          wrongGroups += sobj->GetName().c_str();
+        }
+        else
+        {
+          groups[ nbGroups++ ] = grp;
+        }
+      }
+      groups->length( nbGroups );
+      mySrcMesh = groups[0]->GetMesh();
+    }
+
+    if ( !CORBA::is_nil( mySrcMesh ) ) {
+      SMESH::SMESH_MeshEditor_var aMeshEditor = mySrcMesh->GetMeshEditor();
+      SMESH::SMESH_Group_var newGrp;
+      SMESH::SMESH_Mesh_var newMesh;
+      CORBA::Long nbAdded = aMeshEditor->MakeBoundaryElements( mode,
+                                                               groupName.toLatin1().constData(),
+                                                               meshName.toLatin1().constData(),
+                                                               copyAll,
+                                                               groups,
+                                                               newMesh.out(),
+                                                               newGrp.out() );
+      QString msg = tr("NB_ADDED").arg( nbAdded );
+      if ( !wrongGroups.isEmpty() )
+        msg += ".\n" + tr("WRONG_GROUPS").arg( wrongGroups );
+      SUIT_MessageBox::information( myDlg, tr("SMESH_INFORMATION"), msg);
+
+      if ( !newMesh->_is_nil() ) {
+        if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( newMesh ) )
+          theEntryList.append( aSObject->GetID().c_str() );
+#ifdef WITHGENERICOBJ
+        newMesh->UnRegister();
+#endif
+      }
+      if ( !newGrp->_is_nil() ) {
+#ifdef WITHGENERICOBJ
+        newGrp->UnRegister();
+#endif
+      }
+      ok = true;
+
+      for ( int i = 0; i < entries.count(); ++i )
+        if ( SMESH_Actor* actor = SMESH::FindActorByEntry( entries[i].toLatin1().constData() ))
+          SMESH::Update(actor->getIO(),actor->GetVisibility());
+      SMESH::RepaintCurrentView();
+    }
+  }
+  catch ( ... ) {
+  }
+  return ok;
+}
+
+bool SMESHGUI_Make2DFrom3DOp::onApply()
+{
+  if ( isStudyLocked() )
+    return false;
+
+  QString msg;
+  if ( !isValid( msg ) ) {
+    dlg()->show();
+    if ( msg != "" )
+      SUIT_MessageBox::warning( myDlg, tr( "SMESH_ERROR" ), msg );
+    return false;
+  }
+
+  QStringList anEntryList;
+  bool res = false;
+  try {
+    res = compute2DMesh( anEntryList );
+  }
+  catch ( const SALOME::SALOME_Exception& S_ex ) {
+    SalomeApp_Tools::QtCatchCorbaException( S_ex );
+  }
+  catch ( ... ) {
+  }
+
+  if ( res ) {
+    SMESHGUI::Modified();
+    update( UF_ObjBrowser | UF_Model );
+    if( LightApp_Application* anApp =
+        dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
+      anApp->browseObjects( anEntryList, isApplyAndClose() );
+    myDlg->setNewMeshName( SMESH::UniqueName( "Mesh_1" ) );
+    myDlg->setGroupName( SMESH::UniqueName( "Group" ) );
+  }
+  else {
+    SUIT_MessageBox::warning( myDlg, tr( "SMESH_ERROR" ), tr( "SMESH_OPERATION_FAILED" ) );
+  }
+
+  return res;
+}
diff --git a/src/SMESHGUI/SMESHGUI_Make2DFrom3DOp.h b/src/SMESHGUI/SMESHGUI_Make2DFrom3DOp.h
new file mode 100644 (file)
index 0000000..79ea60c
--- /dev/null
@@ -0,0 +1,121 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+// File   : SMESHGUI_Make2DFrom3D.h
+// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+
+#ifndef SMESHGUI_Make2DFrom3DOp_H
+#define SMESHGUI_Make2DFrom3DOp_H
+
+// SMESH includes
+#include "SMESH_SMESHGUI.hxx"
+#include "SMESHGUI_Dialog.h"
+#include "SMESHGUI_SelectionOp.h"
+#include "SMESH_TypeFilter.hxx"
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+
+class QCheckBox;
+class QLineEdit;
+class QRadioButton;
+class SMESHGUI_Make2DFrom3DOp;
+
+/*!
+ * \brief Dialog to show result mesh statistic
+ */
+
+class SMESHGUI_EXPORT SMESHGUI_Make2DFrom3DDlg :  public SMESHGUI_Dialog
+{
+  Q_OBJECT
+
+public:
+  enum { MeshOrGroups };
+
+  SMESHGUI_Make2DFrom3DDlg( QWidget* );
+  virtual ~SMESHGUI_Make2DFrom3DDlg();
+
+  SMESH::Bnd_Dimension mode() const;
+
+  bool                 needNewMesh() const;
+  QString              getNewMeshName() const;
+  void                 setNewMeshName( const QString& );
+  void                 setNewMeshEnabled( bool );
+  bool                 getNewMeshEnabled() const;
+
+  bool                 needGroup() const;
+  QString              getGroupName() const;
+  void                 setGroupName( const QString& );
+
+  bool                 copySource() const;
+
+private slots:
+  void                 onTargetChanged();
+  void                 onGroupChecked();
+
+private:
+  QRadioButton* my2dFrom3dRB;
+  QRadioButton* my1dFrom2dRB;
+  QRadioButton* my1dFrom3dRB;
+  QRadioButton* myThisMeshRB;
+  QRadioButton* myNewMeshRB;
+  QLineEdit*    myMeshName;
+  QCheckBox*    myCopyCheck;
+  QCheckBox*    myGroupCheck;
+  QLineEdit*    myGroupName;
+
+  friend class SMESHGUI_Make2DFrom3DOp;
+};
+
+/*!
+ * \brief Operation to compute 2D mesh on 3D
+ */
+
+class SMESHGUI_EXPORT SMESHGUI_Make2DFrom3DOp : public SMESHGUI_SelectionOp
+{
+  Q_OBJECT
+
+public:
+  SMESHGUI_Make2DFrom3DOp();
+  virtual ~SMESHGUI_Make2DFrom3DOp();
+
+  virtual LightApp_Dialog*           dlg() const;
+
+protected:
+  virtual void                       startOperation();
+  virtual void                       selectionDone();
+  virtual SUIT_SelectionFilter*      createFilter( const int ) const;
+  bool                               isValid( QString& ) const;
+
+protected slots:
+  virtual bool                       onApply();
+  void                               onModeChanged();
+
+private:
+  bool                               compute2DMesh( QStringList& );
+
+private:
+  SMESH::SMESH_Mesh_var              mySrcMesh;
+  QPointer<SMESHGUI_Make2DFrom3DDlg> myDlg;
+
+  SMESH_TypeFilter                   myMeshFilter;
+  SMESH_TypeFilter                   myGroupFilter;
+};
+
+#endif // SMESHGUI_Make2DFrom3DOp_H
index ac654fdd6bb4e5cf5d1bc76f65ab8bd91a25a9c3..090a385cc5c541d2e276feb924cf91c1bb96c3bf 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : SMESHGUI_MakeNodeAtPointDlg.cxx
 // Author : Edward AGAPOV, Open CASCADE S.A.S.
 // SMESH includes
@@ -46,6 +47,7 @@
 #include <SALOME_ListIO.hxx>
 #include <SUIT_Desktop.h>
 #include <SVTK_ViewModel.h>
+#include <SVTK_ViewWindow.h>
 #include <SalomeApp_Tools.h>
 #include <SalomeApp_TypeFilter.h>
 #include <SUIT_ResourceMgr.h>
@@ -91,7 +93,7 @@ SMESHGUI_MakeNodeAtPointDlg::SMESHGUI_MakeNodeAtPointDlg()
   setWindowTitle(tr("CAPTION"));
 
   QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame());
-  aDlgLay->setMargin(MARGIN);;
+  aDlgLay->setMargin(0);
   aDlgLay->setSpacing(SPACING);
 
   QWidget* aMainFrame = createMainFrame  (mainFrame());
@@ -115,7 +117,7 @@ QWidget* SMESHGUI_MakeNodeAtPointDlg::createMainFrame (QWidget* theParent)
 
   // constructor
 
-  QGroupBox* aPixGrp = new QGroupBox(tr("MESH_PASS_THROUGH_POINT"), aFrame);
+  QGroupBox* aPixGrp = new QGroupBox(tr("MOVE_NODE"), aFrame);
   QButtonGroup* aBtnGrp = new QButtonGroup(this);
   QHBoxLayout* aPixGrpLayout = new QHBoxLayout(aPixGrp);
   aPixGrpLayout->setMargin(MARGIN);
@@ -129,7 +131,7 @@ QWidget* SMESHGUI_MakeNodeAtPointDlg::createMainFrame (QWidget* theParent)
 
   // coordinates
 
-  QGroupBox* aCoordGrp = new QGroupBox(tr("SMESH_COORDINATES"), aFrame);
+  QGroupBox* aCoordGrp = new QGroupBox(tr("DESTINATION"), aFrame);
   QHBoxLayout* aCoordGrpLayout = new QHBoxLayout(aCoordGrp);
   aCoordGrpLayout->setMargin(MARGIN);
   aCoordGrpLayout->setSpacing(SPACING);
@@ -147,9 +149,9 @@ QWidget* SMESHGUI_MakeNodeAtPointDlg::createMainFrame (QWidget* theParent)
   QLabel* aZLabel = new QLabel(tr("SMESH_Z"), aCoordGrp);
   myZ = new SMESHGUI_SpinBox(aCoordGrp);
 
-  myX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, DBL_DIGITS_DISPLAY);
-  myY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, DBL_DIGITS_DISPLAY);
-  myZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, DBL_DIGITS_DISPLAY);
+  myX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  myY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  myZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
 
   aCoordGrpLayout->addWidget(myCoordBtn);
   aCoordGrpLayout->addWidget(aXLabel);
@@ -158,19 +160,9 @@ QWidget* SMESHGUI_MakeNodeAtPointDlg::createMainFrame (QWidget* theParent)
   aCoordGrpLayout->addWidget(myY);
   aCoordGrpLayout->addWidget(aZLabel);
   aCoordGrpLayout->addWidget(myZ);
-
-  // Method selection
-
-  QGroupBox* aMethodGrp = new QGroupBox(tr("METHOD"), aFrame);
-  QHBoxLayout* aMethodGrpLayout = new QHBoxLayout(aMethodGrp);
-  aMethodGrpLayout->setMargin(MARGIN);
-  aMethodGrpLayout->setSpacing(SPACING);
-
-  myMoveRBtn = new QRadioButton(tr("MOVE_EXISTING_METHOD"), aMethodGrp);
-  myCreateRBtn = new QRadioButton(tr("CREATE_NEW_METHOD"), aMethodGrp);
-
-  aMethodGrpLayout->addWidget(myMoveRBtn);
-  aMethodGrpLayout->addWidget(myCreateRBtn);
+  aCoordGrpLayout->setStretchFactor(myX, 1);
+  aCoordGrpLayout->setStretchFactor(myY, 1);
+  aCoordGrpLayout->setStretchFactor(myZ, 1);
 
   // node ID
 
@@ -182,6 +174,65 @@ QWidget* SMESHGUI_MakeNodeAtPointDlg::createMainFrame (QWidget* theParent)
   myIdBtn->setCheckable(true);
   myId = new QLineEdit(myNodeToMoveGrp);
   myId->setValidator(new SMESHGUI_IdValidator(this, 1));
+
+  QWidget* aCoordWidget = new QWidget(myNodeToMoveGrp);
+
+  QLabel* aCurrentXLabel = new QLabel(tr("SMESH_X"), aCoordWidget);
+  myCurrentX = new SMESHGUI_SpinBox(aCoordWidget);
+  myCurrentX->setButtonSymbols(QAbstractSpinBox::NoButtons);
+  myCurrentX->setReadOnly(true);
+
+  QLabel* aCurrentYLabel = new QLabel(tr("SMESH_Y"), aCoordWidget);
+  myCurrentY = new SMESHGUI_SpinBox(aCoordWidget);
+  myCurrentY->setButtonSymbols(QAbstractSpinBox::NoButtons);
+  myCurrentY->setReadOnly(true);
+
+  QLabel* aCurrentZLabel = new QLabel(tr("SMESH_Z"), aCoordWidget);
+  myCurrentZ = new SMESHGUI_SpinBox(aCoordWidget);
+  myCurrentZ->setButtonSymbols(QAbstractSpinBox::NoButtons);
+  myCurrentZ->setReadOnly(true);
+
+  QLabel* aDXLabel = new QLabel(tr("SMESH_DX"), aCoordWidget);
+  myDX = new SMESHGUI_SpinBox(aCoordWidget);
+  myDX->setButtonSymbols(QAbstractSpinBox::NoButtons);
+  myDX->setReadOnly(true);
+
+  QLabel* aDYLabel = new QLabel(tr("SMESH_DY"), aCoordWidget);
+  myDY = new SMESHGUI_SpinBox(aCoordWidget);
+  myDY->setButtonSymbols(QAbstractSpinBox::NoButtons);
+  myDY->setReadOnly(true);
+
+  QLabel* aDZLabel = new QLabel(tr("SMESH_DZ"), aCoordWidget);
+  myDZ = new SMESHGUI_SpinBox(aCoordWidget);
+  myDZ->setButtonSymbols(QAbstractSpinBox::NoButtons);
+  myDZ->setReadOnly(true);
+
+  myCurrentX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  myCurrentY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  myCurrentZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  myDX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  myDY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  myDZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+
+  QGridLayout* aCoordLayout = new QGridLayout(aCoordWidget);
+  aCoordLayout->setMargin(0);
+  aCoordLayout->setSpacing(SPACING);
+  aCoordLayout->addWidget(aCurrentXLabel, 0, 0);
+  aCoordLayout->addWidget(myCurrentX,     0, 1);
+  aCoordLayout->addWidget(aCurrentYLabel, 0, 2);
+  aCoordLayout->addWidget(myCurrentY,     0, 3);
+  aCoordLayout->addWidget(aCurrentZLabel, 0, 4);
+  aCoordLayout->addWidget(myCurrentZ,     0, 5);
+  aCoordLayout->addWidget(aDXLabel,       1, 0);
+  aCoordLayout->addWidget(myDX,           1, 1);
+  aCoordLayout->addWidget(aDYLabel,       1, 2);
+  aCoordLayout->addWidget(myDY,           1, 3);
+  aCoordLayout->addWidget(aDZLabel,       1, 4);
+  aCoordLayout->addWidget(myDZ,           1, 5);
+  aCoordLayout->setColumnStretch(1, 1);
+  aCoordLayout->setColumnStretch(3, 1);
+  aCoordLayout->setColumnStretch(5, 1);
+
   myAutoSearchChkBox = new QCheckBox( tr("AUTO_SEARCH"), myNodeToMoveGrp);
   myPreviewChkBox = new QCheckBox( tr("PREVIEW"), myNodeToMoveGrp);
 
@@ -192,23 +243,20 @@ QWidget* SMESHGUI_MakeNodeAtPointDlg::createMainFrame (QWidget* theParent)
   myNodeToMoveGrpLayout->addWidget( idLabel, 0, 0 );
   myNodeToMoveGrpLayout->addWidget( myIdBtn, 0, 1 );
   myNodeToMoveGrpLayout->addWidget( myId,    0, 2 );
-  myNodeToMoveGrpLayout->addWidget( myAutoSearchChkBox, 1, 0, 1, 3 );
-  myNodeToMoveGrpLayout->addWidget( myPreviewChkBox,    2, 0, 1, 3 );
+  myNodeToMoveGrpLayout->addWidget( aCoordWidget,       1, 0, 1, 3 );
+  myNodeToMoveGrpLayout->addWidget( myAutoSearchChkBox, 2, 0, 1, 3 );
+  myNodeToMoveGrpLayout->addWidget( myPreviewChkBox,    3, 0, 1, 3 );
 
   QVBoxLayout* aLay = new QVBoxLayout(aFrame);
   aLay->addWidget(aPixGrp);
   aLay->addWidget(aCoordGrp);
-  aLay->addWidget(aMethodGrp);
   aLay->addWidget(myNodeToMoveGrp);
 
   connect(myCoordBtn,         SIGNAL (toggled(bool)), this, SLOT(ButtonToggled(bool)));
-  connect(myMoveRBtn,         SIGNAL (toggled(bool)), this, SLOT(ButtonToggled(bool)));
-  connect(myCreateRBtn,       SIGNAL (toggled(bool)), this, SLOT(ButtonToggled(bool)));
   connect(myIdBtn,            SIGNAL (toggled(bool)), this, SLOT(ButtonToggled(bool)));
   connect(myAutoSearchChkBox, SIGNAL (toggled(bool)), this, SLOT(ButtonToggled(bool)));
 
-  myMoveRBtn->setChecked(true);
-  myIdBtn->setDown(true);
+  myIdBtn->setChecked(true);
   myAutoSearchChkBox->setChecked(true);
 
   return aFrame;
@@ -228,30 +276,27 @@ void SMESHGUI_MakeNodeAtPointDlg::ButtonToggled (bool on)
     if ( aSender == myCoordBtn ) // button to set coord by node selection
     {
       if ( myIdBtn->isEnabled() )
-        myIdBtn->setDown( !on );
+        myIdBtn->setChecked( !on );
     }
     else if ( aSender == myIdBtn ) // button to select a node to move
     {
-      myCoordBtn->setDown( !on );
-    }
-    else if ( aSender == myMoveRBtn ) // move node method
-    {
-      myNodeToMoveGrp->setEnabled( true );
-    }
-    else if ( aSender == myCreateRBtn ) // create node method
-    {
-      myNodeToMoveGrp->setEnabled( false );
-      myCoordBtn->setDown( true ); 
+      myCoordBtn->setChecked( !on );
     }
   }      
   if ( aSender == myAutoSearchChkBox ) // automatic node search
   {
     if ( on ) {
+      myCurrentX->SetValue(0);
+      myCurrentY->SetValue(0);
+      myCurrentZ->SetValue(0);
+      myDX->SetValue(0);
+      myDY->SetValue(0);
+      myDZ->SetValue(0);
       myId->setText("");
       myId->setReadOnly ( true );
-      myIdBtn->setDown( false );
+      myIdBtn->setChecked( false );
       myIdBtn->setEnabled( false );
-      myCoordBtn->setDown( true );
+      myCoordBtn->setChecked( true );
     }
     else {
       myId->setReadOnly ( false );
@@ -280,8 +325,10 @@ SMESHGUI_MakeNodeAtPointOp::SMESHGUI_MakeNodeAtPointOp()
   connect(myDlg->myId,SIGNAL (textChanged(const QString&)),SLOT(redisplayPreview()));
   connect(myDlg->myPreviewChkBox,   SIGNAL (toggled(bool)),SLOT(redisplayPreview()));
   connect(myDlg->myAutoSearchChkBox,SIGNAL (toggled(bool)),SLOT(redisplayPreview()));
-  connect(myDlg->myMoveRBtn,        SIGNAL (toggled(bool)),SLOT(redisplayPreview()));
-  connect(myDlg->myCreateRBtn,      SIGNAL (toggled(bool)),SLOT(redisplayPreview()));
+
+  // IPAL22913: TC6.5.0: selected in "Move node" dialog box node is not highlighted
+  // note: this slot seems to be lost together with removed obsolete SMESHGUI_MoveNodesDlg class
+  connect(myDlg->myId,SIGNAL (textChanged(const QString&)),SLOT(onTextChange(const QString&)));
 }
 
 //=======================================================================
@@ -320,13 +367,18 @@ void SMESHGUI_MakeNodeAtPointOp::startOperation()
   myDlg->myX->SetValue(0);
   myDlg->myY->SetValue(0);
   myDlg->myZ->SetValue(0);
+  myDlg->myCurrentX->SetValue(0);
+  myDlg->myCurrentY->SetValue(0);
+  myDlg->myCurrentZ->SetValue(0);
+  myDlg->myDX->SetValue(0);
+  myDlg->myDY->SetValue(0);
+  myDlg->myDZ->SetValue(0);
   myDlg->myId->setText("");
   myDlg->show();
 
   onSelectionDone(); // init myMeshActor
 
   if ( myMeshActor ) {
-//     myMeshOldDisplayMode = myMeshActor->GetRepresentation();
 //     myMeshActor->SetRepresentation( VTK_WIREFRAME );
     myMeshActor->SetPointRepresentation(true);
     SMESH::RepaintCurrentView();
@@ -345,7 +397,6 @@ void SMESHGUI_MakeNodeAtPointOp::stopOperation()
   myNoPreview = true;
   mySimulation->SetVisibility(false);
   if ( myMeshActor ) {
-//     myMeshActor->SetRepresentation( myMeshOldDisplayMode );
     myMeshActor->SetPointRepresentation(false);
     SMESH::RepaintCurrentView();
     myMeshActor = 0;
@@ -367,7 +418,7 @@ bool SMESHGUI_MakeNodeAtPointOp::onApply()
 
   if ( !myMeshActor ) {
     SUIT_MessageBox::warning( dlg(), tr( "SMESH_WRN_WARNING" ),
-                             tr("INVALID_MESH") );
+                              tr("INVALID_MESH") );
     dlg()->show();
     return false;
   }
@@ -376,46 +427,49 @@ bool SMESHGUI_MakeNodeAtPointOp::onApply()
   if ( !isValid( msg ) ) { // node id is invalid
     if( !msg.isEmpty() )
       SUIT_MessageBox::warning( dlg(), tr( "SMESH_WRN_WARNING" ),
-                               tr("INVALID_ID") );
+                                tr("INVALID_ID") );
     dlg()->show();
     return false;
   }
 
+  QStringList aParameters;
+  aParameters << myDlg->myX->text();
+  aParameters << myDlg->myY->text();
+  aParameters << myDlg->myZ->text();
 
   try {
     SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(myMeshActor->getIO());
     if (aMesh->_is_nil()) {
       SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_ERROR"),
-                                  tr("SMESHG_NO_MESH") );
+                                   tr("SMESHG_NO_MESH") );
       return true;
     }
     SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
     if (aMeshEditor->_is_nil())
       return true;
 
-    int aResult = 0;
-    if ( myDlg->myCreateRBtn->isDown() )
-    {
-      aResult = aMeshEditor->AddNode(myDlg->myX->GetValue(),
-                                     myDlg->myY->GetValue(),
-                                     myDlg->myZ->GetValue());
-    }
-    else
-    {
-      int anId = myDlg->myId->text().toInt();
-      aResult = aMeshEditor->MoveClosestNodeToPoint(myDlg->myX->GetValue(),
-                                                    myDlg->myY->GetValue(),
-                                                    myDlg->myZ->GetValue(),
-                                                    anId);
-    }
+    aMesh->SetParameters( aParameters.join(":").toLatin1().constData() );
+
+    bool ok;
+    int anId = myDlg->myId->text().toInt( &ok );
+    if( !ok || anId < 1 )
+      anId = aMeshEditor->FindNodeClosestTo(myDlg->myX->GetValue(),
+                                            myDlg->myY->GetValue(),
+                                            myDlg->myZ->GetValue());
+
+    int aResult = aMeshEditor->MoveNode(anId,
+                                        myDlg->myX->GetValue(),
+                                        myDlg->myY->GetValue(),
+                                        myDlg->myZ->GetValue() );
+
     if (aResult)
     {
-      QStringList aParameters;
-      aParameters << myDlg->myX->text();
-      aParameters << myDlg->myY->text();
-      aParameters << myDlg->myZ->text();
-      aMesh->SetParameters( SMESHGUI::JoinObjectParameters(aParameters) );
-
+      myDlg->myCurrentX->SetValue(0);
+      myDlg->myCurrentY->SetValue(0);
+      myDlg->myCurrentZ->SetValue(0);
+      myDlg->myDX->SetValue(0);
+      myDlg->myDY->SetValue(0);
+      myDlg->myDZ->SetValue(0);
       myDlg->myId->setText("");
 
       SALOME_ListIO aList;
@@ -423,6 +477,7 @@ bool SMESHGUI_MakeNodeAtPointOp::onApply()
       aList.Append(myMeshActor->getIO());
       selectionMgr()->setSelectedObjects(aList,false);
       SMESH::UpdateView();
+      SMESHGUI::Modified();
     }
   }
   catch (const SALOME::SALOME_Exception& S_ex) {
@@ -444,7 +499,6 @@ bool SMESHGUI_MakeNodeAtPointOp::isValid( QString& msg )
 {
   bool ok = true;
   if ( myMeshActor &&
-       myDlg->myMoveRBtn->isDown() &&
        !myDlg->myAutoSearchChkBox->isChecked() )
   {
     ok = false;
@@ -482,7 +536,7 @@ void SMESHGUI_MakeNodeAtPointOp::onSelectionDone()
     SMESH_Actor* aMeshActor = SMESH::FindActorByEntry(anIO->getEntry());
 
     if (!aMeshActor) { // coord by geom
-      if ( myDlg->myCoordBtn->isDown() ) {
+      if ( myDlg->myCoordBtn->isChecked() ) {
         GEOM::GEOM_Object_var geom = SMESH::IObjectToInterface<GEOM::GEOM_Object>(anIO);
         if ( !geom->_is_nil() ) {
           TopoDS_Vertex aShape;
@@ -510,19 +564,34 @@ void SMESHGUI_MakeNodeAtPointOp::onSelectionDone()
       if (SMDS_Mesh* aMesh = aMeshActor->GetObject()->GetMesh()) {
         if (const SMDS_MeshNode* aNode = aMesh->FindNode(aString.toInt())) {
           myNoPreview = true;
-          if ( myDlg->myCoordBtn->isDown() ) { // set coord
+          if ( myDlg->myCoordBtn->isChecked() ) { // set coord
             myDlg->myX->SetValue(aNode->X());
             myDlg->myY->SetValue(aNode->Y());
             myDlg->myZ->SetValue(aNode->Z());
             myNoPreview = false;
             redisplayPreview();
           }
-          else if ( myDlg->myIdBtn->isDown() &&
+          else if ( myDlg->myIdBtn->isChecked() &&
                     myDlg->myIdBtn->isEnabled() ) { // set node to move
             myDlg->myId->setText(aString);
             myNoPreview = false;
             redisplayPreview();
           }
+
+          if (const SMDS_MeshNode* aCurrentNode = aMesh->FindNode(myDlg->myId->text().toInt())) {
+            double x = aCurrentNode->X();
+            double y = aCurrentNode->Y();
+            double z = aCurrentNode->Z();
+            double dx = myDlg->myX->GetValue() - x;
+            double dy = myDlg->myY->GetValue() - y;
+            double dz = myDlg->myZ->GetValue() - z;
+            myDlg->myCurrentX->SetValue(x);
+            myDlg->myCurrentY->SetValue(y);
+            myDlg->myCurrentZ->SetValue(z);
+            myDlg->myDX->SetValue(dx);
+            myDlg->myDY->SetValue(dy);
+            myDlg->myDZ->SetValue(dz);
+          }
         }
       }
     }
@@ -545,15 +614,22 @@ void SMESHGUI_MakeNodeAtPointOp::redisplayPreview()
   SMESH::MeshPreviewStruct_var aMeshPreviewStruct;
 
   bool moveShown = false;
-  if ( myDlg->myMoveRBtn->isDown() && // Move method
-       myMeshActor)
+  if ( myMeshActor)
   {
     const bool autoSearch = myDlg->myAutoSearchChkBox->isChecked();
     const bool preview    = myDlg->myPreviewChkBox->isChecked();
     if ( autoSearch )
+    {
+      myDlg->myCurrentX->SetValue(0);
+      myDlg->myCurrentY->SetValue(0);
+      myDlg->myCurrentZ->SetValue(0);
+      myDlg->myDX->SetValue(0);
+      myDlg->myDY->SetValue(0);
+      myDlg->myDZ->SetValue(0);
       myDlg->myId->setText("");
+    }
     QString msg;
-    if ( preview && ( autoSearch || isValid( msg ) ))
+    if ( autoSearch || isValid( msg ) )
     {
       try {
         SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(myMeshActor->getIO());
@@ -563,11 +639,19 @@ void SMESHGUI_MakeNodeAtPointOp::redisplayPreview()
           {
             SUIT_OverrideCursor aWaitCursor;
 
+            int anId = 0;
+            if ( autoSearch )
+              anId = aPreviewer->FindNodeClosestTo(myDlg->myX->GetValue(),
+                                                   myDlg->myY->GetValue(),
+                                                   myDlg->myZ->GetValue());
+            else
+              anId = myDlg->myId->text().toInt();
+
             // find id and/or just compute preview
-            int anId = aPreviewer->MoveClosestNodeToPoint(myDlg->myX->GetValue(),
-                                                          myDlg->myY->GetValue(),
-                                                          myDlg->myZ->GetValue(),
-                                                          myDlg->myId->text().toInt());
+            aPreviewer->MoveNode(anId,
+                                 myDlg->myX->GetValue(),
+                                 myDlg->myY->GetValue(),
+                                 myDlg->myZ->GetValue());
             if ( autoSearch ) { // set found id
               QString idTxt("%1");
               if ( anId > 0 )
@@ -576,6 +660,24 @@ void SMESHGUI_MakeNodeAtPointOp::redisplayPreview()
                 idTxt = "";
               myDlg->myId->setText( idTxt );
             }
+
+            SMESH::double_array* aXYZ = aMesh->GetNodeXYZ( anId );
+            if( aXYZ && aXYZ->length() >= 3 )
+            {
+              double x = aXYZ->operator[](0);
+              double y = aXYZ->operator[](1);
+              double z = aXYZ->operator[](2);
+              double dx = myDlg->myX->GetValue() - x;
+              double dy = myDlg->myY->GetValue() - y;
+              double dz = myDlg->myZ->GetValue() - z;
+              myDlg->myCurrentX->SetValue(x);
+              myDlg->myCurrentY->SetValue(y);
+              myDlg->myCurrentZ->SetValue(z);
+              myDlg->myDX->SetValue(dx);
+              myDlg->myDY->SetValue(dy);
+              myDlg->myDZ->SetValue(dz);
+            }
+
             if ( preview ) { // fill preview data
               aMeshPreviewStruct = aPreviewer->GetPreviewData();
               moveShown = ( anId > 0 );
@@ -618,6 +720,35 @@ void SMESHGUI_MakeNodeAtPointOp::redisplayPreview()
   myNoPreview = false;
 }
 
+//================================================================================
+/*!
+ * \brief SLOT called when the node id is manually changed
+ */
+//================================================================================
+
+void SMESHGUI_MakeNodeAtPointOp::onTextChange( const QString& theText )
+{
+  if( myMeshActor )
+  {
+    if( SMDS_Mesh* aMesh = myMeshActor->GetObject()->GetMesh() )
+    {
+      Handle(SALOME_InteractiveObject) anIO = myMeshActor->getIO();
+      SALOME_ListIO aList;
+      aList.Append( anIO );
+      selectionMgr()->setSelectedObjects( aList, false );
+
+      if( const SMDS_MeshNode* aNode = aMesh->FindNode( theText.toInt() ) )
+      {
+        TColStd_MapOfInteger aListInd;
+        aListInd.Add( aNode->GetID() );
+        selector()->AddOrRemoveIndex( anIO, aListInd, false );
+        if( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( SMESHGUI::GetSMESHGUI() ) )
+          aViewWindow->highlight( anIO, true, true );
+      }
+    }
+  }
+}
+
 //================================================================================
 /*!
  * \brief Activate Node selection
index 6df8ba72239fa2b034386f192c8ca0f41c6e47ff..11bf1189c2a02af8586436e4a6466f6ef3328bb7 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : SMESHGUI_MakeNodeAtPointDlg.h
 // Author : Edward AGAPOV, Open CASCADE S.A.S.
 //
@@ -35,7 +36,6 @@ class QGroupBox;
 class QLineEdit;
 class QPushButton;
 class QCheckBox;
-class QRadioButton;
 class SMESHGUI_SpinBox;
 class SMESHGUI_MeshEditPreview;
 class SMESHGUI_MakeNodeAtPointDlg;
@@ -68,6 +68,7 @@ protected slots:
 private slots:
   void                           onSelectionDone();
   void                           redisplayPreview();
+  void                           onTextChange( const QString& );
 
 private:
   SMESHGUI_MakeNodeAtPointDlg*  myDlg;
@@ -97,11 +98,15 @@ private:
   SMESHGUI_SpinBox*             myX;
   SMESHGUI_SpinBox*             myY;
   SMESHGUI_SpinBox*             myZ;
-  QRadioButton*                 myMoveRBtn;
-  QRadioButton*                 myCreateRBtn;
   QGroupBox*                    myNodeToMoveGrp;
   QPushButton*                  myIdBtn;
   QLineEdit*                    myId;
+  SMESHGUI_SpinBox*             myCurrentX;
+  SMESHGUI_SpinBox*             myCurrentY;
+  SMESHGUI_SpinBox*             myCurrentZ;
+  SMESHGUI_SpinBox*             myDX;
+  SMESHGUI_SpinBox*             myDY;
+  SMESHGUI_SpinBox*             myDZ;
   QCheckBox*                    myAutoSearchChkBox;
   QCheckBox*                    myPreviewChkBox;
 
diff --git a/src/SMESHGUI/SMESHGUI_Measurements.cxx b/src/SMESHGUI/SMESHGUI_Measurements.cxx
new file mode 100644 (file)
index 0000000..4e94217
--- /dev/null
@@ -0,0 +1,1231 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+//  File   : SMESHGUI_Measurements.cxx
+//  Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+
+#include "SMESHGUI_Measurements.h"
+
+#include "SMESH_Actor.h"
+#include "SMESHGUI.h"
+#include "SMESHGUI_IdValidator.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_VTKUtils.h"
+#include <SMESH_TypeFilter.hxx>
+#include <SMESH_LogicalFilter.hxx>
+
+#include <LightApp_SelectionMgr.h>
+#include <SUIT_OverrideCursor.h>
+#include <SUIT_ResourceMgr.h>
+#include <SVTK_ViewWindow.h>
+#include <SALOME_ListIteratorOfListIO.hxx>
+
+#include <QButtonGroup>
+#include <QGridLayout>
+#include <QGroupBox>
+#include <QHBoxLayout>
+#include <QKeyEvent>
+#include <QLabel>
+#include <QLineEdit>
+#include <QPushButton>
+#include <QRadioButton>
+#include <QTabWidget>
+#include <QVBoxLayout>
+
+#include <vtkPoints.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkIdList.h>
+#include <vtkCellArray.h>
+#include <vtkUnsignedCharArray.h>
+#include <vtkDataSetMapper.h>
+#include <VTKViewer_CellLocationsArray.h>
+#include <vtkProperty.h>
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+#include CORBA_SERVER_HEADER(SMESH_Measurements)
+
+const int SPACING = 6;            // layout spacing
+const int MARGIN  = 9;            // layout margin
+const int MAX_NB_FOR_EDITOR = 40; // max nb of items in the ID list editor field
+
+// Uncomment as soon as elements are supported by Min Distance operation
+//#define MINDIST_ENABLE_ELEMENT
+
+// Uncomment as soon as objects are supported by Min Distance operation
+//#define MINDIST_ENABLE_OBJECT
+
+/*!
+  \class SMESHGUI_MinDistance
+  \brief Minimum distance measurement widget.
+  
+  Widget to calculate minimum distance between two objects.
+*/
+
+/*!
+  \brief Constructor.
+  \param parent parent widget
+*/
+SMESHGUI_MinDistance::SMESHGUI_MinDistance( QWidget* parent )
+: QWidget( parent ), myCurrentTgt( FirstTgt ), myFirstActor( 0 ), mySecondActor( 0 ), myPreview( 0 )
+{
+  QGroupBox*    aFirstTgtGrp = new QGroupBox( tr( "FIRST_TARGET" ), this );
+  QRadioButton* aFNode       = new QRadioButton( tr( "NODE" ),    aFirstTgtGrp );
+  QRadioButton* aFElem       = new QRadioButton( tr( "ELEMENT" ), aFirstTgtGrp );
+  QRadioButton* aFObject     = new QRadioButton( tr( "OBJECT" ),  aFirstTgtGrp );
+  myFirstTgt                 = new QLineEdit( aFirstTgtGrp );
+
+  QGridLayout* fl = new QGridLayout( aFirstTgtGrp );
+  fl->setMargin( MARGIN );
+  fl->setSpacing( SPACING );
+  fl->addWidget( aFNode,     0, 0 );
+  fl->addWidget( aFElem,     0, 1 );
+  fl->addWidget( aFObject,   0, 2 );
+  fl->addWidget( myFirstTgt, 1, 0, 1, 3 );
+
+  myFirst = new QButtonGroup( this );
+  myFirst->addButton( aFNode,   NodeTgt );
+  myFirst->addButton( aFElem,   ElementTgt );
+  myFirst->addButton( aFObject, ObjectTgt );
+
+  QGroupBox*    aSecondTgtGrp = new QGroupBox( tr( "SECOND_TARGET" ), this );
+  QRadioButton* aSOrigin      = new QRadioButton( tr( "ORIGIN" ),  aSecondTgtGrp );
+  QRadioButton* aSNode        = new QRadioButton( tr( "NODE" ),    aSecondTgtGrp );
+  QRadioButton* aSElem        = new QRadioButton( tr( "ELEMENT" ), aSecondTgtGrp );
+  QRadioButton* aSObject      = new QRadioButton( tr( "OBJECT" ),  aSecondTgtGrp );
+  mySecondTgt                 = new QLineEdit( aSecondTgtGrp );
+
+  QGridLayout* sl = new QGridLayout( aSecondTgtGrp );
+  sl->setMargin( MARGIN );
+  sl->setSpacing( SPACING );
+  sl->addWidget( aSOrigin,   0, 0 );
+  sl->addWidget( aSNode,     0, 1 );
+  sl->addWidget( aSElem,     0, 2 );
+  sl->addWidget( aSObject,   0, 3 );
+  sl->addWidget( mySecondTgt, 1, 0, 1, 4 );
+
+  mySecond = new QButtonGroup( this );
+  mySecond->addButton( aSOrigin, OriginTgt );
+  mySecond->addButton( aSNode,   NodeTgt );
+  mySecond->addButton( aSElem,   ElementTgt );
+  mySecond->addButton( aSObject, ObjectTgt );
+
+  QPushButton* aCompute = new QPushButton( tr( "COMPUTE" ), this );
+  
+  QGroupBox* aResults = new QGroupBox( tr( "RESULT" ), this );
+  QLabel* aDxLab   = new QLabel( "dX", aResults );
+  myDX             = new QLineEdit( aResults );
+  QLabel* aDyLab   = new QLabel( "dY", aResults );
+  myDY             = new QLineEdit( aResults );
+  QLabel* aDzLab   = new QLabel( "dZ", aResults );
+  myDZ             = new QLineEdit( aResults );
+  QLabel* aDistLab = new QLabel( tr( "DISTANCE" ), aResults );
+  myDistance       = new QLineEdit( aResults );
+
+  QGridLayout* rl = new QGridLayout( aResults );
+  rl->setMargin( MARGIN );
+  rl->setSpacing( SPACING );
+  rl->addWidget( aDxLab,     0, 0 );
+  rl->addWidget( myDX,       0, 1 );
+  rl->addWidget( aDyLab,     1, 0 );
+  rl->addWidget( myDY,       1, 1 );
+  rl->addWidget( aDzLab,     2, 0 );
+  rl->addWidget( myDZ,       2, 1 );
+  rl->addWidget( aDistLab,   0, 2 );
+  rl->addWidget( myDistance, 0, 3 );
+
+  QGridLayout* l = new QGridLayout( this );
+  l->setMargin( MARGIN );
+  l->setSpacing( SPACING );
+
+  l->addWidget( aFirstTgtGrp,  0, 0, 1, 2 );
+  l->addWidget( aSecondTgtGrp, 1, 0, 1, 2 );
+  l->addWidget( aCompute,      2, 0 );
+  l->addWidget( aResults,      3, 0, 1, 2 );
+  l->setColumnStretch( 1, 5 );
+  l->setRowStretch( 4, 5 );
+
+  aFNode->setChecked( true );
+  aSOrigin->setChecked( true );
+#ifndef MINDIST_ENABLE_ELEMENT
+  aFElem->setEnabled( false );   // NOT AVAILABLE YET
+  aSElem->setEnabled( false );   // NOT AVAILABLE YET
+#endif
+#ifndef MINDIST_ENABLE_OBJECT
+  aFObject->setEnabled( false ); // NOT AVAILABLE YET
+  aSObject->setEnabled( false ); // NOT AVAILABLE YET
+#endif
+  myDX->setReadOnly( true );
+  myDY->setReadOnly( true );
+  myDZ->setReadOnly( true );
+  myDistance->setReadOnly( true );
+
+  myValidator = new SMESHGUI_IdValidator( this, 1 );
+
+  myFirstTgt->installEventFilter( this );
+  mySecondTgt->installEventFilter( this );
+
+  connect( myFirst,     SIGNAL( buttonClicked( int ) ),  this, SLOT( firstChanged() ) );
+  connect( mySecond,    SIGNAL( buttonClicked( int ) ),  this, SLOT( secondChanged() ) );
+  connect( aCompute,    SIGNAL( clicked() ),             this, SLOT( compute() ) );
+  connect( myFirstTgt,  SIGNAL( textEdited( QString ) ), this, SLOT( firstEdited() ) );
+  connect( mySecondTgt, SIGNAL( textEdited( QString ) ), this, SLOT( secondEdited() ) );
+
+  QList<SUIT_SelectionFilter*> filters;
+  filters.append( new SMESH_TypeFilter( MESHorSUBMESH ) );
+  filters.append( new SMESH_TypeFilter( GROUP ) );
+  myFilter = new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR );
+
+  mySecondTgt->setEnabled( mySecond->checkedId() != OriginTgt );
+  clear();
+
+  //setTarget( FirstTgt );
+}
+
+/*!
+  \brief Destructor
+*/
+SMESHGUI_MinDistance::~SMESHGUI_MinDistance()
+{
+  erasePreview();
+  if ( myPreview )
+    myPreview->Delete();
+}
+
+/*!
+  \brief Event filter
+  \param o object
+  \param o event
+  \return \c true if event is filtered or \c false otherwise
+*/
+bool SMESHGUI_MinDistance::eventFilter( QObject* o, QEvent* e )
+{
+  if ( e->type() == QEvent::FocusIn ) {
+    if ( o == myFirstTgt )
+      setTarget( FirstTgt );
+    else if ( o == mySecondTgt )
+      setTarget( SecondTgt );
+  }
+  return QWidget::eventFilter( o, e );
+}
+
+/*!
+  \brief Setup selection mode depending on the current widget state
+*/
+void SMESHGUI_MinDistance::updateSelection()
+{
+  LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
+
+  disconnect( selMgr, 0, this, 0 );
+  selMgr->clearFilters();
+  
+  bool nodeMode = ( myCurrentTgt == FirstTgt  && myFirst->checkedId() == NodeTgt ) ||
+                  ( myCurrentTgt == SecondTgt && mySecond->checkedId() == NodeTgt );
+  bool elemMode = ( myCurrentTgt == FirstTgt  && myFirst->checkedId() == ElementTgt ) ||
+                  ( myCurrentTgt == SecondTgt && mySecond->checkedId() == ElementTgt );
+  bool objMode  = ( myCurrentTgt == FirstTgt  && myFirst->checkedId() == ObjectTgt ) ||
+                  ( myCurrentTgt == SecondTgt && mySecond->checkedId() == ObjectTgt ) ||
+                  ( myCurrentTgt == NoTgt );
+
+  if ( nodeMode ) {
+    SMESH::SetPointRepresentation( true );
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+      aViewWindow->SetSelectionMode( NodeSelection );
+  }
+  else if ( elemMode ) {
+    SMESH::SetPointRepresentation( false );
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+      aViewWindow->SetSelectionMode( CellSelection );
+  }
+  else if ( objMode ) {
+    SMESH::SetPointRepresentation( false );
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+      aViewWindow->SetSelectionMode( ActorSelection );
+    selMgr->installFilter( myFilter );
+  }
+
+  connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( selectionChanged() ) );
+
+  if ( myCurrentTgt == FirstTgt )
+    firstEdited();
+  else if ( myCurrentTgt == SecondTgt )
+    secondEdited();
+
+  //selectionChanged();
+}
+
+/*!
+  \brief Deactivate widget
+*/
+void SMESHGUI_MinDistance::deactivate()
+{
+  disconnect( SMESHGUI::selectionMgr(), 0, this, 0 );
+}
+
+/*!
+  \brief Set current target for selection
+  \param target new target ID
+*/
+void SMESHGUI_MinDistance::setTarget( int target )
+{
+  if ( myCurrentTgt != target ) {
+    myCurrentTgt = target;
+    updateSelection();
+  }
+}
+
+/*!
+  \brief Erase preview actor
+*/
+void SMESHGUI_MinDistance::erasePreview()
+{
+  SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow();
+  if ( aViewWindow && myPreview ) {
+    aViewWindow->RemoveActor( myPreview );
+    aViewWindow->Repaint();
+  }
+}
+
+/*!
+  \brief Display preview actor
+*/
+void SMESHGUI_MinDistance::displayPreview()
+{
+  SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow();
+  if ( aViewWindow && myPreview ) {
+    aViewWindow->AddActor( myPreview );
+    aViewWindow->Repaint();
+  }
+}
+
+/*!
+  \brief Create preview actor
+  \param x1 X coordinate of first point
+  \param y1 X coordinate of first point
+  \param z1 Y coordinate of first point
+  \param x2 Y coordinate of second point
+  \param y2 Z coordinate of second point
+  \param z2 Z coordinate of second point
+*/
+void SMESHGUI_MinDistance::createPreview( double x1, double y1, double z1, double x2, double y2, double z2 )
+{
+  if ( myPreview )
+    myPreview->Delete();
+
+  vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New();
+  // create points
+  vtkPoints* aPoints = vtkPoints::New();
+  aPoints->SetNumberOfPoints( 2 );
+  aPoints->SetPoint( 0, x1, y1, z1 );
+  aPoints->SetPoint( 1, x2, y2, z2 );
+  aGrid->SetPoints( aPoints );
+  aPoints->Delete();
+  // create cells
+  vtkIdList* anIdList = vtkIdList::New();
+  anIdList->SetNumberOfIds( 2 );
+  vtkCellArray* aCells = vtkCellArray::New();
+  aCells->Allocate( 2, 0);
+  vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
+  aCellTypesArray->SetNumberOfComponents( 1 );
+  aCellTypesArray->Allocate( 1 );
+  anIdList->SetId( 0, 0 ); anIdList->SetId( 1, 1 );
+  aCells->InsertNextCell( anIdList );
+  aCellTypesArray->InsertNextValue( VTK_LINE );
+  anIdList->Delete();
+  VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
+  aCellLocationsArray->SetNumberOfComponents( 1 );
+  aCellLocationsArray->SetNumberOfTuples( 1 );
+  aCells->InitTraversal();
+  for( vtkIdType idType = 0, *pts, npts; aCells->GetNextCell( npts, pts ); idType++ )
+    aCellLocationsArray->SetValue( idType, aCells->GetTraversalLocation( npts ) );
+  aGrid->SetCells( aCellTypesArray, aCellLocationsArray, aCells );
+  aCellLocationsArray->Delete();
+  aCellTypesArray->Delete();
+  aCells->Delete();
+  // create actor
+  vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
+  aMapper->SetInput( aGrid );
+  aGrid->Delete();
+  myPreview = SALOME_Actor::New();
+  myPreview->PickableOff();
+  myPreview->SetMapper( aMapper );
+  aMapper->Delete();
+  vtkProperty* aProp = vtkProperty::New();
+  aProp->SetRepresentationToWireframe();
+  aProp->SetColor( 250, 0, 250 );
+  aProp->SetPointSize( 5 );
+  aProp->SetLineWidth( 3 );
+  myPreview->SetProperty( aProp );
+  aProp->Delete();
+}
+
+/*!
+  \brief Called when selection is changed
+*/
+void SMESHGUI_MinDistance::selectionChanged()
+{
+  SUIT_OverrideCursor wc;
+
+  SALOME_ListIO selected;
+  SMESHGUI::selectionMgr()->selectedObjects( selected );
+
+  if ( selected.Extent() == 1 ) {
+    Handle(SALOME_InteractiveObject) IO = selected.First();
+    SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
+    if ( !CORBA::is_nil( obj ) ) {
+      if ( myCurrentTgt == FirstTgt ) {
+        myFirstSrc = obj;
+        myFirstActor = SMESH::FindActorByEntry( IO->getEntry() );
+        if ( myFirst->checkedId() == ObjectTgt ) {
+          QString aName;
+          SMESH::GetNameOfSelectedIObjects( SMESHGUI::selectionMgr(), aName );
+          myFirstTgt->setText( aName );
+        }
+        else {
+          SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
+          QString ID;
+          int nb = 0;
+          if ( myFirstActor && selector ) {
+            nb = myFirst->checkedId() == NodeTgt ? 
+              SMESH::GetNameOfSelectedElements( selector, IO, ID ) :
+              SMESH::GetNameOfSelectedNodes( selector, IO, ID );
+          }
+          if ( nb == 1 )
+            myFirstTgt->setText( ID.trimmed() );
+          else
+            myFirstTgt->clear();
+        }
+      }
+      else if ( myCurrentTgt == SecondTgt ) {
+        mySecondSrc = obj;
+        mySecondActor = SMESH::FindActorByEntry( IO->getEntry() );
+        if ( mySecond->checkedId() == ObjectTgt ) {
+          QString aName;
+          SMESH::GetNameOfSelectedIObjects( SMESHGUI::selectionMgr(), aName );
+          mySecondTgt->setText( aName );
+        }
+        else {
+          SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
+          QString ID;
+          int nb = 0;
+          if ( mySecondActor && selector ) {
+            nb = mySecond->checkedId() == NodeTgt ? 
+              SMESH::GetNameOfSelectedElements( selector, IO, ID ) :
+              SMESH::GetNameOfSelectedNodes( selector, IO, ID );
+          }
+          if ( nb == 1 )
+            mySecondTgt->setText( ID.trimmed() );
+          else
+            mySecondTgt->clear();
+        }
+      }
+    }
+  }
+  clear();
+}
+
+/*!
+  \brief Called when first target mode is changed by the user
+*/
+void SMESHGUI_MinDistance::firstChanged()
+{
+  myFirstSrc = SMESH::SMESH_IDSource::_nil();
+  myFirstTgt->clear();
+  myFirstTgt->setReadOnly( myFirst->checkedId() == ObjectTgt );
+  myFirstTgt->setValidator( myFirst->checkedId() == ObjectTgt ? 0 : myValidator );
+  setTarget( FirstTgt );
+  updateSelection();
+  clear();
+}
+
+/*!
+  \brief Called when second target mode is changed by the user
+*/
+void SMESHGUI_MinDistance::secondChanged()
+{
+  mySecondSrc = SMESH::SMESH_IDSource::_nil();
+  mySecondTgt->setEnabled( mySecond->checkedId() != OriginTgt );
+  mySecondTgt->setReadOnly( mySecond->checkedId() == ObjectTgt );
+  mySecondTgt->setValidator( mySecond->checkedId() == ObjectTgt ? 0 : myValidator );
+  mySecondTgt->clear();
+  setTarget( mySecond->checkedId() != OriginTgt ? SecondTgt : NoTgt );
+  updateSelection();
+  clear();
+}
+
+/*!
+  \brief Called when first target is edited by the user
+*/
+void SMESHGUI_MinDistance::firstEdited()
+{
+  setTarget( FirstTgt );
+  if ( sender() == myFirstTgt )
+    clear();
+  SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
+  if ( myFirstActor && selector ) {
+    Handle(SALOME_InteractiveObject) IO = myFirstActor->getIO();
+    if ( myFirst->checkedId() == NodeTgt || myFirst->checkedId() == ElementTgt ) {
+      TColStd_MapOfInteger ID;
+      ID.Add( myFirstTgt->text().toLong() );
+      selector->AddOrRemoveIndex( IO, ID, false );
+    }
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+      aViewWindow->highlight( IO, true, true );
+  }
+}
+
+/*!
+  \brief Called when second target is edited by the user
+*/
+void SMESHGUI_MinDistance::secondEdited()
+{
+  setTarget( SecondTgt );
+  if ( sender() == mySecondTgt )
+    clear();
+  SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
+  if ( mySecondActor && selector ) {
+    Handle(SALOME_InteractiveObject) IO = mySecondActor->getIO();
+    if ( mySecond->checkedId() == NodeTgt || mySecond->checkedId() == ElementTgt ) {
+      TColStd_MapOfInteger ID;
+      ID.Add( mySecondTgt->text().toLong() );
+      selector->AddOrRemoveIndex( IO, ID, false );
+    }
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+      aViewWindow->highlight( IO, true, true );
+  }
+}
+
+/*!
+  \brief Compute the minimum distance between targets
+*/
+void SMESHGUI_MinDistance::compute()
+{
+  SUIT_OverrideCursor wc;
+  SMESH::SMESH_IDSource_var s1;
+  SMESH::SMESH_IDSource_var s2;
+  bool isOrigin = mySecond->checkedId() == OriginTgt;
+
+  // process first target
+  if ( !CORBA::is_nil( myFirstSrc ) ) {
+    if ( myFirst->checkedId() == NodeTgt || myFirst->checkedId() == ElementTgt ) {
+      SMESH::SMESH_Mesh_var m = myFirstSrc->GetMesh();
+      long id = myFirstTgt->text().toLong();
+      if ( !CORBA::is_nil( m ) && id ) {
+        SMESH::long_array_var ids = new SMESH::long_array();
+        ids->length( 1 );
+        ids[0] = id;
+        SMESH::SMESH_MeshEditor_var me = m->GetMeshEditor();
+        s1 = me->MakeIDSource( ids.in(), myFirst->checkedId() == NodeTgt ? SMESH::NODE : SMESH::FACE );
+      }
+    }
+    else {
+      s1 = myFirstSrc;
+    }
+  }
+
+  // process second target
+  if ( !CORBA::is_nil( mySecondSrc ) ) {
+    if ( mySecond->checkedId() == NodeTgt || mySecond->checkedId() == ElementTgt ) {
+      SMESH::SMESH_Mesh_var m = mySecondSrc->GetMesh();
+      long id = mySecondTgt->text().toLong();
+      if ( !CORBA::is_nil( m ) && id ) {
+        SMESH::long_array_var ids = new SMESH::long_array();
+        ids->length( 1 );
+        ids[0] = id;
+        SMESH::SMESH_MeshEditor_var me = m->GetMeshEditor();
+        s2 = me->MakeIDSource( ids.in(), mySecond->checkedId() == NodeTgt ? SMESH::NODE : SMESH::FACE );
+      }
+    }
+    else {
+      s2 = mySecondSrc;
+    }
+  }
+
+  if ( !CORBA::is_nil( s1 ) && ( !CORBA::is_nil( s2 ) || isOrigin ) ) {
+    // compute min distance
+    int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
+    SMESH::Measurements_var measure = SMESHGUI::GetSMESHGen()->CreateMeasurements();
+    SMESH::Measure result = measure->MinDistance( s1.in(), s2.in() );
+    measure->UnRegister();
+    myDX->setText( QString::number( result.minX, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+    myDY->setText( QString::number( result.minY, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+    myDZ->setText( QString::number( result.minZ, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+    myDistance->setText( QString::number( result.value, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+    // update preview actor
+    erasePreview();
+    double x1, y1, z1, x2, y2, z2;
+    SMESH::double_array_var coord = s1->GetMesh()->GetNodeXYZ( result.node1 );
+    x1 = coord[0]; y1 = coord[1]; z1 = coord[2];
+    if ( isOrigin ) {
+      x2 = y2 = z2 = 0.;
+    }
+    else {
+      coord = s2->GetMesh()->GetNodeXYZ( result.node2 );
+      x2 = coord[0]; y2 = coord[1]; z2 = coord[2];
+    }
+    createPreview( x1, y1, z1, x2, y2, z2 );
+    displayPreview();
+  }
+  else {
+    clear();
+  }
+}
+
+/*!
+  \brief Reset the widget to the initial state (nullify result fields)
+*/
+void SMESHGUI_MinDistance::clear()
+{
+  myDX->clear();
+  myDY->clear();
+  myDZ->clear();
+  myDistance->clear();
+  erasePreview();
+}
+
+/*!
+  \class SMESHGUI_BoundingBox
+  \brief Bounding box measurement widget.
+  
+  Widget to calculate bounding box of the selected object(s).
+*/
+
+/*!
+  \brief Constructor.
+  \param parent parent widget
+*/
+SMESHGUI_BoundingBox::SMESHGUI_BoundingBox( QWidget* parent )
+: QWidget( parent ), myActor( 0 ), myPreview( 0 )
+{
+  QGroupBox* aSourceGrp = new QGroupBox( tr( "SOURCE" ), this );
+  QRadioButton* aObjects  = new QRadioButton( tr( "OBJECTS" ),  aSourceGrp );
+  QRadioButton* aNodes    = new QRadioButton( tr( "NODES" ),    aSourceGrp );
+  QRadioButton* aElements = new QRadioButton( tr( "ELEMENTS" ), aSourceGrp );
+  mySource = new QLineEdit( aSourceGrp );
+  
+  QGridLayout* fl = new QGridLayout( aSourceGrp );
+  fl->setMargin( MARGIN );
+  fl->setSpacing( SPACING );
+  fl->addWidget( aObjects,   0, 0 );
+  fl->addWidget( aNodes,     0, 1 );
+  fl->addWidget( aElements,  0, 2 );
+  fl->addWidget( mySource,   1, 0, 1, 3 );
+  
+  mySourceMode = new QButtonGroup( this );
+  mySourceMode->addButton( aObjects,  ObjectsSrc );
+  mySourceMode->addButton( aNodes,    NodesSrc );
+  mySourceMode->addButton( aElements, ElementsSrc );
+
+  QPushButton* aCompute = new QPushButton( tr( "COMPUTE" ), this );
+
+  QGroupBox* aResults = new QGroupBox( tr( "RESULT" ), this );
+  QLabel* aXminLab = new QLabel( "Xmin", aResults );
+  myXmin           = new QLineEdit( aResults );
+  QLabel* aXmaxLab = new QLabel( "Xmax", aResults );
+  myXmax           = new QLineEdit( aResults );
+  QLabel* aDxLab   = new QLabel( "dX", aResults );
+  myDX             = new QLineEdit( aResults );
+  QLabel* aYminLab = new QLabel( "Ymin", aResults );
+  myYmin           = new QLineEdit( aResults );
+  QLabel* aYmaxLab = new QLabel( "Ymax", aResults );
+  myYmax           = new QLineEdit( aResults );
+  QLabel* aDyLab   = new QLabel( "dY", aResults );
+  myDY             = new QLineEdit( aResults );
+  QLabel* aZminLab = new QLabel( "Zmin", aResults );
+  myZmin           = new QLineEdit( aResults );
+  QLabel* aZmaxLab = new QLabel( "Zmax", aResults );
+  myZmax           = new QLineEdit( aResults );
+  QLabel* aDzLab   = new QLabel( "dZ", aResults );
+  myDZ             = new QLineEdit( aResults );
+
+  QGridLayout* rl  = new QGridLayout( aResults );
+  rl->setMargin( MARGIN );
+  rl->setSpacing( SPACING );
+  rl->addWidget( aXminLab,   0, 0 );
+  rl->addWidget( myXmin,     0, 1 );
+  rl->addWidget( aXmaxLab,   0, 2 );
+  rl->addWidget( myXmax,     0, 3 );
+  rl->addWidget( aDxLab,     0, 4 );
+  rl->addWidget( myDX,       0, 5 );
+  rl->addWidget( aYminLab,   1, 0 );
+  rl->addWidget( myYmin,     1, 1 );
+  rl->addWidget( aYmaxLab,   1, 2 );
+  rl->addWidget( myYmax,     1, 3 );
+  rl->addWidget( aDyLab,     1, 4 );
+  rl->addWidget( myDY,       1, 5 );
+  rl->addWidget( aZminLab,   2, 0 );
+  rl->addWidget( myZmin,     2, 1 );
+  rl->addWidget( aZmaxLab,   2, 2 );
+  rl->addWidget( myZmax,     2, 3 );
+  rl->addWidget( aDzLab,     2, 4 );
+  rl->addWidget( myDZ,       2, 5 );
+
+  QGridLayout* l = new QGridLayout( this );
+  l->setMargin( MARGIN );
+  l->setSpacing( SPACING );
+
+  l->addWidget( aSourceGrp, 0, 0, 1, 2 );
+  l->addWidget( aCompute,   1, 0 );
+  l->addWidget( aResults,   2, 0, 1, 2 );
+  l->setColumnStretch( 1, 5 );
+  l->setRowStretch( 3, 5 );
+
+  aObjects->setChecked( true );
+  myXmin->setReadOnly( true );
+  myXmax->setReadOnly( true );
+  myDX->setReadOnly( true );
+  myYmin->setReadOnly( true );
+  myYmax->setReadOnly( true );
+  myDY->setReadOnly( true );
+  myZmin->setReadOnly( true );
+  myZmax->setReadOnly( true );
+  myDZ->setReadOnly( true );
+
+  myValidator = new SMESHGUI_IdValidator( this );
+
+  connect( mySourceMode, SIGNAL( buttonClicked( int ) ),  this, SLOT( sourceChanged() ) );
+  connect( aCompute,     SIGNAL( clicked() ),             this, SLOT( compute() ) );
+  connect( mySource,     SIGNAL( textEdited( QString ) ), this, SLOT( sourceEdited() ) );
+
+  QList<SUIT_SelectionFilter*> filters;
+  filters.append( new SMESH_TypeFilter( MESHorSUBMESH ) );
+  filters.append( new SMESH_TypeFilter( GROUP ) );
+  myFilter = new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR );
+
+  clear();
+}
+
+/*!
+  \brief Destructor
+*/
+SMESHGUI_BoundingBox::~SMESHGUI_BoundingBox()
+{
+  erasePreview();
+  if ( myPreview )
+    myPreview->Delete();
+}
+
+/*!
+  \brief Setup selection mode depending on the current widget state
+*/
+void SMESHGUI_BoundingBox::updateSelection()
+{
+  LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
+
+  disconnect( selMgr, 0, this, 0 );
+  selMgr->clearFilters();
+  
+  bool nodeMode = mySourceMode->checkedId() == NodesSrc;
+  bool elemMode = mySourceMode->checkedId() == ElementsSrc;
+  bool objMode  = mySourceMode->checkedId() == ObjectsSrc;
+
+  if ( nodeMode ) {
+    SMESH::SetPointRepresentation( true );
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+      aViewWindow->SetSelectionMode( NodeSelection );
+  }
+  else if ( elemMode ) {
+    SMESH::SetPointRepresentation( false );
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+      aViewWindow->SetSelectionMode( CellSelection );
+  }
+  else if ( objMode ) {
+    SMESH::SetPointRepresentation( false );
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+      aViewWindow->SetSelectionMode( ActorSelection );
+    selMgr->installFilter( myFilter );
+  }
+
+  connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( selectionChanged() ) );
+
+  sourceEdited();
+
+  //selectionChanged();
+}
+
+/*!
+  \brief Deactivate widget
+*/
+void SMESHGUI_BoundingBox::deactivate()
+{
+  disconnect( SMESHGUI::selectionMgr(), 0, this, 0 );
+}
+
+/*!
+  \brief Erase preview actor
+*/
+void SMESHGUI_BoundingBox::erasePreview()
+{
+  SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow();
+  if ( aViewWindow && myPreview ) {
+    aViewWindow->RemoveActor( myPreview );
+    aViewWindow->Repaint();
+  }
+}
+
+/*!
+  \brief Display preview actor
+*/
+void SMESHGUI_BoundingBox::displayPreview()
+{
+  SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow();
+  if ( aViewWindow && myPreview ) {
+    aViewWindow->AddActor( myPreview );
+    aViewWindow->Repaint();
+  }
+}
+
+/*!
+  \brief Create preview actor
+  \param minX min X coordinate of bounding box
+  \param maxX max X coordinate of bounding box
+  \param minY min Y coordinate of bounding box
+  \param maxY max Y coordinate of bounding box
+  \param minZ min Z coordinate of bounding box
+  \param maxZ max Z coordinate of bounding box
+*/
+void SMESHGUI_BoundingBox::createPreview( double minX, double maxX, double minY, double maxY, double minZ, double maxZ )
+{
+  if ( myPreview )
+    myPreview->Delete();
+
+  vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New();
+  // create points
+  vtkPoints* aPoints = vtkPoints::New();
+  aPoints->SetNumberOfPoints( 8 );
+  aPoints->SetPoint( 0, minX, minY, minZ );
+  aPoints->SetPoint( 1, maxX, minY, minZ );
+  aPoints->SetPoint( 2, minX, maxY, minZ );
+  aPoints->SetPoint( 3, maxX, maxY, minZ );
+  aPoints->SetPoint( 4, minX, minY, maxZ );
+  aPoints->SetPoint( 5, maxX, minY, maxZ );
+  aPoints->SetPoint( 6, minX, maxY, maxZ );
+  aPoints->SetPoint( 7, maxX, maxY, maxZ );
+  aGrid->SetPoints( aPoints );
+  aPoints->Delete();
+  // create cells
+  // connectivity: 0-1 0-4 0-2 1-5 1-3 2-6 2-3 3-7 4-6 4-5 5-7 6-7
+  vtkIdList* anIdList = vtkIdList::New();
+  anIdList->SetNumberOfIds( 2 );
+  vtkCellArray* aCells = vtkCellArray::New();
+  aCells->Allocate( 2*12, 0);
+  vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
+  aCellTypesArray->SetNumberOfComponents( 1 );
+  aCellTypesArray->Allocate( 12 );
+  anIdList->SetId( 0, 0 ); anIdList->SetId( 1, 1 );
+  aCells->InsertNextCell( anIdList );
+  aCellTypesArray->InsertNextValue( VTK_LINE );
+  anIdList->SetId( 0, 0 ); anIdList->SetId( 1, 4 );
+  aCells->InsertNextCell( anIdList );
+  aCellTypesArray->InsertNextValue( VTK_LINE );
+  anIdList->SetId( 0, 0 ); anIdList->SetId( 1, 2 );
+  aCells->InsertNextCell( anIdList );
+  aCellTypesArray->InsertNextValue( VTK_LINE );
+  anIdList->SetId( 0, 1 ); anIdList->SetId( 1, 5 );
+  aCells->InsertNextCell( anIdList );
+  aCellTypesArray->InsertNextValue( VTK_LINE );
+  anIdList->SetId( 0, 1 ); anIdList->SetId( 1, 3 );
+  aCells->InsertNextCell( anIdList );
+  aCellTypesArray->InsertNextValue( VTK_LINE );
+  anIdList->SetId( 0, 2 ); anIdList->SetId( 1, 6 );
+  aCells->InsertNextCell( anIdList );
+  aCellTypesArray->InsertNextValue( VTK_LINE );
+  anIdList->SetId( 0, 2 ); anIdList->SetId( 1, 3 );
+  aCells->InsertNextCell( anIdList );
+  aCellTypesArray->InsertNextValue( VTK_LINE );
+  anIdList->SetId( 0, 3 ); anIdList->SetId( 1, 7 );
+  aCells->InsertNextCell( anIdList );
+  aCellTypesArray->InsertNextValue( VTK_LINE );
+  anIdList->SetId( 0, 4 ); anIdList->SetId( 1, 6 );
+  aCells->InsertNextCell( anIdList );
+  aCellTypesArray->InsertNextValue( VTK_LINE );
+  anIdList->SetId( 0, 4 ); anIdList->SetId( 1, 5 );
+  aCells->InsertNextCell( anIdList );
+  aCellTypesArray->InsertNextValue( VTK_LINE );
+  anIdList->SetId( 0, 5 ); anIdList->SetId( 1, 7 );
+  aCells->InsertNextCell( anIdList );
+  aCellTypesArray->InsertNextValue( VTK_LINE );
+  anIdList->SetId( 0, 6 ); anIdList->SetId( 1, 7 );
+  aCells->InsertNextCell( anIdList );
+  aCellTypesArray->InsertNextValue( VTK_LINE );
+  anIdList->Delete();
+  VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
+  aCellLocationsArray->SetNumberOfComponents( 1 );
+  aCellLocationsArray->SetNumberOfTuples( 12 );
+  aCells->InitTraversal();
+  for( vtkIdType idType = 0, *pts, npts; aCells->GetNextCell( npts, pts ); idType++ )
+    aCellLocationsArray->SetValue( idType, aCells->GetTraversalLocation( npts ) );
+  aGrid->SetCells( aCellTypesArray, aCellLocationsArray, aCells );
+  aCellLocationsArray->Delete();
+  aCellTypesArray->Delete();
+  aCells->Delete();
+  // create actor
+  vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
+  aMapper->SetInput( aGrid );
+  aGrid->Delete();
+  myPreview = SALOME_Actor::New();
+  myPreview->PickableOff();
+  myPreview->SetMapper( aMapper );
+  aMapper->Delete();
+  vtkProperty* aProp = vtkProperty::New();
+  aProp->SetRepresentationToWireframe();
+  aProp->SetColor( 250, 0, 250 );
+  aProp->SetPointSize( 5 );
+  aProp->SetLineWidth( 3 );
+  myPreview->SetProperty( aProp );
+  aProp->Delete();
+}
+
+/*!
+  \brief Called when selection is changed
+*/
+void SMESHGUI_BoundingBox::selectionChanged()
+{
+  SUIT_OverrideCursor wc;
+
+  SALOME_ListIO selected;
+  SMESHGUI::selectionMgr()->selectedObjects( selected );
+
+  if ( selected.Extent() == 1 ) {
+    Handle(SALOME_InteractiveObject) IO = selected.First();
+    SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
+    if ( !CORBA::is_nil( obj ) ) {
+      mySrc.clear();
+      mySrc.append( obj );
+      myActor = SMESH::FindActorByEntry( IO->getEntry() );
+      if ( mySourceMode->checkedId() == ObjectsSrc ) {
+        QString aName;
+        SMESH::GetNameOfSelectedIObjects( SMESHGUI::selectionMgr(), aName );
+        mySource->setText( aName );
+      }
+      else {
+        SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
+        QString ID;
+        int nb = 0;
+        if ( myActor && selector ) {
+          nb = mySourceMode->checkedId() == NodesSrc ? 
+            SMESH::GetNameOfSelectedElements( selector, IO, ID ) :
+            SMESH::GetNameOfSelectedNodes( selector, IO, ID );
+        }
+        if ( nb > 0 ) {
+          myIDs = ID.trimmed();
+          if ( nb < MAX_NB_FOR_EDITOR ) {
+            mySource->setReadOnly( false );
+            if ( mySource->validator() != myValidator )
+              mySource->setValidator( myValidator );
+            mySource->setText( ID.trimmed() );
+          }
+          else {
+            mySource->setReadOnly( true );
+            mySource->setValidator( 0 );
+            mySource->setText( tr( "SELECTED_NB_OBJ" ).arg( nb )
+                               .arg( mySourceMode->checkedId() == NodesSrc ? tr( "NB_NODES" ) : tr( "NB_ELEMENTS") ) );
+          }
+        }
+        else {
+          myIDs = "";
+          mySource->clear();
+          mySource->setReadOnly( false );
+          mySource->setValidator( myValidator );
+        }
+      }
+    }
+  }
+  else if ( selected.Extent() > 1 ) {
+    myIDs = "";
+    SALOME_ListIteratorOfListIO It( selected );
+    mySrc.clear();
+    myActor = 0;
+    if ( mySourceMode->checkedId() == ObjectsSrc ) {
+      for( ; It.More(); It.Next()){
+        Handle(SALOME_InteractiveObject) IO = It.Value();
+        SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
+        if ( !CORBA::is_nil( obj ) ) {
+          mySrc.append( obj );
+        }
+      }
+      QString aName;
+      SMESH::GetNameOfSelectedIObjects( SMESHGUI::selectionMgr(), aName );
+      mySource->setText( aName );
+    }
+    else {
+      mySource->clear();
+    }
+  }
+  clear();
+}
+
+/*!
+  \brief Called when source mode is changed by the user
+*/
+void SMESHGUI_BoundingBox::sourceChanged()
+{
+  myIDs = "";
+  mySource->clear();
+  mySource->setReadOnly( mySourceMode->checkedId() == ObjectsSrc );
+  mySource->setValidator( mySourceMode->checkedId() == ObjectsSrc ? 0 : myValidator );
+  updateSelection();
+  clear();
+}
+
+/*!
+  \brief Called when source mode is edited by the user
+*/
+void SMESHGUI_BoundingBox::sourceEdited()
+{
+  if ( sender() == mySource )
+    clear();
+  SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
+  if ( myActor && selector ) {
+    Handle(SALOME_InteractiveObject) IO = myActor->getIO();
+    if ( mySourceMode->checkedId() == NodesSrc || mySourceMode->checkedId() == ElementsSrc ) {
+      TColStd_MapOfInteger ID;
+      if ( !mySource->isReadOnly() )
+        myIDs = mySource->text();
+      QStringList ids = myIDs.split( " ", QString::SkipEmptyParts );
+      foreach ( QString id, ids )
+        ID.Add( id.trimmed().toLong() );
+      selector->AddOrRemoveIndex( IO, ID, false );
+    }
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+      aViewWindow->highlight( IO, true, true );
+  }
+}
+
+/*!
+  \brief Calculate bounding box of the selected object(s)
+*/
+void SMESHGUI_BoundingBox::compute()
+{
+  SUIT_OverrideCursor wc;
+  SMESH::ListOfIDSources_var srcList = new SMESH::ListOfIDSources();
+  if ( mySourceMode->checkedId() == NodesSrc || mySourceMode->checkedId() == ElementsSrc ) {
+    if ( mySrc.count() > 0 && !CORBA::is_nil( mySrc[0] ) ) {
+      SMESH::SMESH_Mesh_var m = mySrc[0]->GetMesh();
+      QStringList ids = myIDs.split( " ", QString::SkipEmptyParts );
+      if ( !CORBA::is_nil( m ) && ids.count() > 0 ) {
+        SMESH::long_array_var ids_in = new SMESH::long_array();
+        ids_in->length( ids.count() );
+        for( int i = 0; i < ids.count(); i++ )
+          ids_in[i] = ids[i].trimmed().toLong();
+        SMESH::SMESH_MeshEditor_var me = m->GetMeshEditor();
+        SMESH::SMESH_IDSource_var s = me->MakeIDSource( ids_in.in(), mySourceMode->checkedId() == NodesSrc ? SMESH::NODE : SMESH::FACE ); 
+        srcList->length( 1 );
+        srcList[0] = s;
+      }
+    }
+  }
+  else {
+    srcList->length( mySrc.count() );
+    for( int i = 0; i < mySrc.count(); i++ )
+      srcList[i] = mySrc[i];
+  }
+  if ( srcList->length() > 0 ) {
+    // compute bounding box
+    int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
+    SMESH::Measurements_var measure = SMESHGUI::GetSMESHGen()->CreateMeasurements();
+    SMESH::Measure result = measure->BoundingBox( srcList.in() );
+    measure->UnRegister();
+    myXmin->setText( QString::number( result.minX, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+    myXmax->setText( QString::number( result.maxX, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+    myDX->setText( QString::number( result.maxX-result.minX, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+    myYmin->setText( QString::number( result.minY, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+    myYmax->setText( QString::number( result.maxY, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+    myDY->setText( QString::number( result.maxY-result.minY, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+    myZmin->setText( QString::number( result.minZ, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+    myZmax->setText( QString::number( result.maxZ, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+    myDZ->setText( QString::number( result.maxZ-result.minZ, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+    // update preview actor
+    erasePreview();
+    createPreview( result.minX, result.maxX, result.minY, result.maxY, result.minZ, result.maxZ );
+    displayPreview();
+  }
+  else {
+    clear();
+  }
+}
+
+/*!
+  \brief Reset the widget to the initial state (nullify result fields)
+*/
+void SMESHGUI_BoundingBox::clear()
+{
+  myXmin->clear();
+  myXmax->clear();
+  myDX->clear();
+  myYmin->clear();
+  myYmax->clear();
+  myDY->clear();
+  myZmin->clear();
+  myZmax->clear();
+  myDZ->clear();
+  erasePreview();
+}
+
+/*!
+  \class SMESHGUI_MeshInfoDlg
+  \brief Centralized dialog box for the measurements
+*/
+
+/*!
+  \brief Constructor
+  \param parent parent widget
+  \param page specifies the dialog page to be shown at the start-up
+*/
+SMESHGUI_MeasureDlg::SMESHGUI_MeasureDlg( QWidget* parent, int page )
+: QDialog( parent )
+{
+  setModal( false );
+  setAttribute( Qt::WA_DeleteOnClose, true );
+  setWindowTitle( tr( "MEASUREMENTS" ) );
+  setSizeGripEnabled( true );
+
+  SUIT_ResourceMgr* resMgr = SMESHGUI::resourceMgr();
+
+  myTabWidget = new QTabWidget( this );
+
+  // min distance
+
+  myMinDist = new SMESHGUI_MinDistance( myTabWidget );
+  myTabWidget->addTab( myMinDist, resMgr->loadPixmap( "SMESH", tr( "ICON_MEASURE_MIN_DIST" ) ), tr( "MIN_DIST" ) );
+
+  // bounding box
+  
+  myBndBox = new SMESHGUI_BoundingBox( myTabWidget );
+  myTabWidget->addTab( myBndBox, resMgr->loadPixmap( "SMESH", tr( "ICON_MEASURE_BND_BOX" ) ), tr( "BND_BOX" ) );
+
+  // buttons
+  QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
+  okBtn->setAutoDefault( true );
+  okBtn->setDefault( true );
+  okBtn->setFocus();
+  QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
+  helpBtn->setAutoDefault( true );
+
+  QHBoxLayout* btnLayout = new QHBoxLayout;
+  btnLayout->setSpacing( SPACING );
+  btnLayout->setMargin( 0 );
+  btnLayout->addWidget( okBtn );
+  btnLayout->addStretch( 10 );
+  btnLayout->addWidget( helpBtn );
+
+  QVBoxLayout* l = new QVBoxLayout ( this );
+  l->setMargin( MARGIN );
+  l->setSpacing( SPACING );
+  l->addWidget( myTabWidget );
+  l->addStretch();
+  l->addLayout( btnLayout );
+
+  myTabWidget->setCurrentIndex( qMax( (int)MinDistance, qMin( (int)BoundingBox, page ) ) );
+
+  connect( okBtn,       SIGNAL( clicked() ),              this, SLOT( reject() ) );
+  connect( helpBtn,     SIGNAL( clicked() ),              this, SLOT( help() ) );
+  connect( myTabWidget, SIGNAL( currentChanged( int  ) ), this, SLOT( updateSelection() ) );
+  connect( SMESHGUI::GetSMESHGUI(),  SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
+  connect( SMESHGUI::GetSMESHGUI(),  SIGNAL( SignalCloseAllDialogs() ),        this, SLOT( reject() ) );
+
+  updateSelection();
+}
+
+/*!
+  \brief Destructor
+*/
+SMESHGUI_MeasureDlg::~SMESHGUI_MeasureDlg()
+{
+}
+
+/*!
+  \brief Perform clean-up actions on the dialog box closing.
+*/
+void SMESHGUI_MeasureDlg::reject()
+{
+  LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
+  selMgr->clearFilters();
+  SMESH::SetPointRepresentation( false );
+  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+    aViewWindow->SetSelectionMode( ActorSelection );
+  QDialog::reject();
+}
+
+/*!
+  \brief Process keyboard event
+  \param e key press event
+*/
+void SMESHGUI_MeasureDlg::keyPressEvent( QKeyEvent* e )
+{
+  QDialog::keyPressEvent( e );
+  if ( !e->isAccepted() && e->key() == Qt::Key_F1 ) {
+    e->accept();
+    help();
+  }
+}
+
+/*!
+  \brief Reactivate dialog box, when mouse pointer goes into it.
+*/
+void SMESHGUI_MeasureDlg::enterEvent( QEvent* )
+{
+  activate();
+}
+
+/*!
+  \brief Setup selection mode depending on the current dialog box state.
+*/
+void SMESHGUI_MeasureDlg::updateSelection()
+{
+  if ( myTabWidget->currentIndex() == MinDistance )
+    myMinDist->updateSelection();
+  else if ( myTabWidget->currentIndex() == BoundingBox )
+    myBndBox->updateSelection();
+    
+}
+
+/*!
+  \brief Show help page
+*/
+void SMESHGUI_MeasureDlg::help()
+{
+  SMESH::ShowHelpFile( myTabWidget->currentIndex() == MinDistance ?
+                       "measurements_page.html#min_distance_anchor" : 
+                       "measurements_page.html#bounding_box_anchor" );
+}
+
+/*!
+  \brief Activate dialog box
+*/
+void SMESHGUI_MeasureDlg::activate()
+{
+  SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
+  SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
+  myTabWidget->setEnabled( true );
+  updateSelection();
+}
+
+/*!
+  \brief Deactivate dialog box
+*/
+void SMESHGUI_MeasureDlg::deactivate()
+{
+  myMinDist->deactivate();
+  myBndBox->deactivate();
+  myTabWidget->setEnabled( false );
+  disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
+}
diff --git a/src/SMESHGUI/SMESHGUI_Measurements.h b/src/SMESHGUI/SMESHGUI_Measurements.h
new file mode 100644 (file)
index 0000000..3b5079f
--- /dev/null
@@ -0,0 +1,172 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+//  File   : SMESHGUI_Measurements.h
+//  Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+
+#ifndef SMESHGUI_MEASUREMENTS_H
+#define SMESHGUI_MEASUREMENTS_H
+
+#include "SMESH_SMESHGUI.hxx"
+
+#include <QDialog>
+
+class QButtonGroup;
+class QLineEdit;
+class QTabWidget;
+class SUIT_SelectionFilter;
+class SALOME_Actor;
+class SMESH_Actor;
+class SMESHGUI_IdValidator;
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+
+class SMESHGUI_EXPORT SMESHGUI_MinDistance : public QWidget
+{
+  Q_OBJECT;
+
+  enum { NoTgt, FirstTgt, SecondTgt };
+  enum { OriginTgt, NodeTgt, ElementTgt, ObjectTgt };
+
+public:
+  SMESHGUI_MinDistance( QWidget* = 0 );
+  ~SMESHGUI_MinDistance();
+
+  bool eventFilter( QObject*, QEvent* );
+  void updateSelection();
+  void deactivate();
+
+private: 
+  void setTarget( int );
+  void erasePreview();
+  void displayPreview();
+  void createPreview( double, double, double, double, double, double );
+
+private slots:
+  void selectionChanged();
+  void firstChanged();
+  void secondChanged();
+  void firstEdited();
+  void secondEdited();
+  void compute();
+  void clear();
+
+private:
+  QButtonGroup*             myFirst;
+  QButtonGroup*             mySecond;
+  QLineEdit*                myFirstTgt;
+  QLineEdit*                mySecondTgt;
+  QLineEdit*                myDX;
+  QLineEdit*                myDY;
+  QLineEdit*                myDZ;
+  QLineEdit*                myDistance;
+  int                       myCurrentTgt;
+  SMESH::SMESH_IDSource_var myFirstSrc;
+  SMESH::SMESH_IDSource_var mySecondSrc;
+  SMESH_Actor*              myFirstActor;
+  SMESH_Actor*              mySecondActor;
+  SMESHGUI_IdValidator*     myValidator;
+  SUIT_SelectionFilter*     myFilter;
+  SALOME_Actor*             myPreview;
+};
+
+class SMESHGUI_EXPORT SMESHGUI_BoundingBox : public QWidget
+{
+  Q_OBJECT;
+
+  enum { ObjectsSrc, NodesSrc, ElementsSrc };
+  
+public:
+  SMESHGUI_BoundingBox( QWidget* = 0 );
+  ~SMESHGUI_BoundingBox();
+
+  void updateSelection();
+  void deactivate();
+
+private:
+  void erasePreview();
+  void displayPreview();
+  void createPreview( double, double, double, double, double, double );
+
+private slots:
+  void selectionChanged();
+  void sourceChanged();
+  void sourceEdited();
+  void compute();
+  void clear();
+
+private:
+  typedef QList<SMESH::SMESH_IDSource_var> SourceList;
+  QButtonGroup*             mySourceMode;
+  QLineEdit*                mySource;
+  QLineEdit*                myXmin;
+  QLineEdit*                myXmax;
+  QLineEdit*                myDX;
+  QLineEdit*                myYmin;
+  QLineEdit*                myYmax;
+  QLineEdit*                myDY;
+  QLineEdit*                myZmin;
+  QLineEdit*                myZmax;
+  QLineEdit*                myDZ;
+  SourceList                mySrc;
+  SMESH_Actor*              myActor;
+  SMESHGUI_IdValidator*     myValidator;
+  QString                   myIDs;
+  SUIT_SelectionFilter*     myFilter;
+  SALOME_Actor*             myPreview;
+};
+
+class SMESHGUI_EXPORT SMESHGUI_MeasureDlg : public QDialog
+{ 
+  Q_OBJECT;
+
+  enum { NodeMode, ElemMode };
+
+public:
+  //! Measurement type
+  enum { 
+    MinDistance,   //!< minimum distance
+    BoundingBox    //!< bounding box
+  };
+
+  SMESHGUI_MeasureDlg( QWidget* = 0, int = MinDistance );
+  ~SMESHGUI_MeasureDlg();
+
+  void reject();
+
+protected:
+  void keyPressEvent( QKeyEvent* );
+  void enterEvent( QEvent* );
+
+private slots:
+  void help();
+  void updateSelection();
+  void activate();
+  void deactivate();
+
+private:
+  QTabWidget*           myTabWidget;
+  SMESHGUI_MinDistance* myMinDist;   
+  SMESHGUI_BoundingBox* myBndBox;
+};
+
+#endif // SMESHGUI_MEASUREMENTS_H
diff --git a/src/SMESHGUI/SMESHGUI_MergeDlg.cxx b/src/SMESHGUI/SMESHGUI_MergeDlg.cxx
new file mode 100644 (file)
index 0000000..7446b54
--- /dev/null
@@ -0,0 +1,1325 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+// SMESH SMESHGUI : GUI for SMESH component
+// File   : SMESHGUI_MergeDlg.cxx
+// Author : Open CASCADE S.A.S.
+// SMESH includes
+//
+#include "SMESHGUI_MergeDlg.h"
+
+#include "SMESHGUI.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_VTKUtils.h"
+#include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI_SpinBox.h"
+
+#include <SMESH_Actor.h>
+#include <SMESH_TypeFilter.hxx>
+#include <SMESH_LogicalFilter.hxx>
+#include <SMDS_Mesh.hxx>
+
+// SALOME GUI includes
+#include <SUIT_Desktop.h>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_Session.h>
+#include <SUIT_MessageBox.h>
+#include <SUIT_OverrideCursor.h>
+
+#include <LightApp_Application.h>
+#include <LightApp_SelectionMgr.h>
+
+#include <SVTK_ViewModel.h>
+#include <SVTK_ViewWindow.h>
+#include <SALOME_ListIO.hxx>
+
+// OCCT includes
+#include <TColStd_MapOfInteger.hxx>
+#include <TColStd_MapIteratorOfMapOfInteger.hxx>
+
+// IDL includes
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
+// VTK includes
+#include <vtkUnstructuredGrid.h>
+#include <vtkRenderer.h>
+#include <vtkActor2D.h>
+#include <vtkPoints.h>
+#include <vtkDataSetMapper.h>
+#include <vtkMaskPoints.h>
+#include <vtkSelectVisiblePoints.h>
+#include <vtkLabeledDataMapper.h>
+#include <vtkTextProperty.h>
+#include <vtkIntArray.h>
+#include <vtkProperty2D.h>
+#include <vtkPointData.h>
+#include <vtkConfigure.h>
+#if !defined(VTK_XVERSION)
+#define VTK_XVERSION (VTK_MAJOR_VERSION<<16)+(VTK_MINOR_VERSION<<8)+(VTK_BUILD_VERSION)
+#endif
+
+// Qt includes
+#include <QApplication>
+#include <QGroupBox>
+#include <QLabel>
+#include <QLineEdit>
+#include <QListWidget>
+#include <QPushButton>
+#include <QRadioButton>
+#include <QCheckBox>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QGridLayout>
+#include <QKeyEvent>
+#include <QButtonGroup>
+
+#define SPACING 6
+#define MARGIN  11
+
+namespace SMESH
+{
+  class TIdPreview
+  { // to display in the viewer IDs of the selected elements
+    SVTK_ViewWindow* myViewWindow;
+
+    vtkUnstructuredGrid* myIdGrid;
+    SALOME_Actor* myIdActor;
+
+    vtkUnstructuredGrid* myPointsNumDataSet;
+    vtkMaskPoints* myPtsMaskPoints;
+    vtkSelectVisiblePoints* myPtsSelectVisiblePoints;
+    vtkLabeledDataMapper* myPtsLabeledDataMapper;
+    vtkTextProperty* aPtsTextProp;
+    bool myIsPointsLabeled;
+    vtkActor2D* myPointLabels;
+
+    std::vector<int> myIDs;
+
+  public:
+    TIdPreview(SVTK_ViewWindow* theViewWindow):
+      myViewWindow(theViewWindow)
+    {
+      myIdGrid = vtkUnstructuredGrid::New();
+
+      // Create and display actor
+      vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
+      aMapper->SetInput( myIdGrid );
+
+      myIdActor = SALOME_Actor::New();
+      myIdActor->SetInfinitive(true);
+      myIdActor->VisibilityOff();
+      myIdActor->PickableOff();
+
+      myIdActor->SetMapper( aMapper );
+      aMapper->Delete();
+
+      myViewWindow->AddActor(myIdActor);
+
+      //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());
+#if (VTK_XVERSION < 0x050200)
+      myPtsLabeledDataMapper->SetLabelFormat("%g");
+#endif
+      myPtsLabeledDataMapper->SetLabelModeToLabelScalars();
+    
+      vtkTextProperty* aPtsTextProp = vtkTextProperty::New();
+      aPtsTextProp->SetFontFamilyToTimes();
+      static int aPointsFontSize = 12;
+      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);
+
+      AddToRender(myViewWindow->getRenderer());
+    }
+
+    void SetPointsData ( SMDS_Mesh* theMesh, 
+                         TColStd_MapOfInteger & theNodesIdMap )
+    {
+      vtkPoints* aPoints = vtkPoints::New();
+      aPoints->SetNumberOfPoints(theNodesIdMap.Extent());
+      myIDs.clear();
+      
+      TColStd_MapIteratorOfMapOfInteger idIter( theNodesIdMap );
+      for( int i = 0; idIter.More(); idIter.Next(), i++ ) {
+        const SMDS_MeshNode* aNode = theMesh->FindNode(idIter.Key());
+        aPoints->SetPoint( i, aNode->X(), aNode->Y(), aNode->Z() );
+        myIDs.push_back(idIter.Key());
+      }
+
+      myIdGrid->SetPoints(aPoints);
+
+      aPoints->Delete();
+
+      myIdActor->GetMapper()->Update();
+    }
+
+    void SetElemsData( TColStd_MapOfInteger & theElemsIdMap, 
+                       std::list<gp_XYZ> & aGrCentersXYZ )
+    {
+      vtkPoints* aPoints = vtkPoints::New();
+      aPoints->SetNumberOfPoints(theElemsIdMap.Extent());
+      myIDs.clear();
+      
+      TColStd_MapIteratorOfMapOfInteger idIter( theElemsIdMap );
+      for( ; idIter.More(); idIter.Next() ) {
+        myIDs.push_back(idIter.Key());
+      }
+
+      gp_XYZ aXYZ;
+      std::list<gp_XYZ>::iterator coordIt = aGrCentersXYZ.begin();
+      for( int i = 0; coordIt != aGrCentersXYZ.end(); coordIt++, i++ ) {
+        aXYZ = *coordIt;
+        aPoints->SetPoint( i, aXYZ.X(), aXYZ.Y(), aXYZ.Z() );
+      }
+      myIdGrid->SetPoints(aPoints);
+      aPoints->Delete();
+      
+      myIdActor->GetMapper()->Update();
+    }
+
+    void AddToRender(vtkRenderer* theRenderer)
+    {
+      myIdActor->AddToRender(theRenderer);
+
+      myPtsSelectVisiblePoints->SetRenderer(theRenderer);
+      theRenderer->AddActor2D(myPointLabels);
+    }
+
+    void RemoveFromRender(vtkRenderer* theRenderer)
+    {
+      myIdActor->RemoveFromRender(theRenderer);
+
+      myPtsSelectVisiblePoints->SetRenderer(theRenderer);
+      theRenderer->RemoveActor(myPointLabels);
+    }
+
+    void SetPointsLabeled( bool theIsPointsLabeled, bool theIsActorVisible = true )
+    {
+      myIsPointsLabeled = theIsPointsLabeled && myIdGrid->GetNumberOfPoints();
+      
+      if ( myIsPointsLabeled ) {
+        myPointsNumDataSet->ShallowCopy(myIdGrid);
+        vtkDataSet *aDataSet = myPointsNumDataSet;
+        int aNbElem = myIDs.size();
+        vtkIntArray *anArray = vtkIntArray::New();
+        anArray->SetNumberOfValues( aNbElem );
+        for ( int i = 0; i < aNbElem; i++ )
+          anArray->SetValue( i, myIDs[i] );
+        aDataSet->GetPointData()->SetScalars( anArray );
+        anArray->Delete();
+        myPtsMaskPoints->SetInput( aDataSet );
+        myPointLabels->SetVisibility( theIsActorVisible );
+      }
+      else {
+        myPointLabels->SetVisibility( false );
+      }
+    }
+    
+    ~TIdPreview()
+    {
+      RemoveFromRender(myViewWindow->getRenderer());
+
+      myIdGrid->Delete();
+
+      myViewWindow->RemoveActor(myIdActor);
+      myIdActor->Delete();
+
+      //Deleting of points numbering pipeline
+      //---------------------------------------
+      myPointsNumDataSet->Delete();
+      
+      //myPtsLabeledDataMapper->RemoveAllInputs();        //vtk 5.0 porting
+      myPtsLabeledDataMapper->Delete();
+
+      //myPtsSelectVisiblePoints->UnRegisterAllOutputs(); //vtk 5.0 porting
+      myPtsSelectVisiblePoints->Delete();
+
+      //myPtsMaskPoints->UnRegisterAllOutputs();          //vtk 5.0 porting
+      myPtsMaskPoints->Delete();
+
+      myPointLabels->Delete();
+
+//       myTimeStamp->Delete();
+    }
+  };
+}
+
+static const char * IconFirst[] = {
+"18 10 2 1",
+"       g None",
+".      g #000000",
+"         .     .  ",
+"  ..    ..    ..  ",
+"  ..   ...   ...  ",
+"  ..  ....  ....  ",
+"  .. ..... .....  ",
+"  .. ..... .....  ",
+"  ..  ....  ....  ",
+"  ..   ...   ...  ",
+"  ..    ..    ..  ",
+"         .     .  "};
+
+//=================================================================================
+// class    : SMESHGUI_MergeDlg()
+// purpose  :
+//=================================================================================
+SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction)
+  : QDialog(SMESH::GetDesktop(theModule)),
+    mySMESHGUI(theModule),
+    mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
+    myAction(theAction)
+{
+  setModal(false);
+  setAttribute(Qt::WA_DeleteOnClose, true);
+  setWindowTitle(myAction == 1 ? tr("SMESH_MERGE_ELEMENTS") : tr("SMESH_MERGE_NODES"));
+
+  myIdPreview = new SMESH::TIdPreview(SMESH::GetViewWindow( mySMESHGUI ));
+
+  SUIT_ResourceMgr* aResMgr = SMESH::GetResourceMgr( mySMESHGUI );
+  QPixmap IconMergeNodes (aResMgr->loadPixmap("SMESH", tr("ICON_SMESH_MERGE_NODES")));
+  QPixmap IconMergeElems (aResMgr->loadPixmap("SMESH", tr("ICON_DLG_MERGE_ELEMENTS")));
+  QPixmap IconSelect     (aResMgr->loadPixmap("SMESH", tr("ICON_SELECT")));
+  QPixmap IconAdd        (aResMgr->loadPixmap("SMESH", tr("ICON_APPEND")));
+  QPixmap IconRemove     (aResMgr->loadPixmap("SMESH", tr("ICON_REMOVE")));
+
+  setSizeGripEnabled(true);
+
+  QVBoxLayout* DlgLayout = new QVBoxLayout(this);
+  DlgLayout->setSpacing(SPACING);
+  DlgLayout->setMargin(MARGIN);
+
+  /***************************************************************/
+  GroupConstructors = new QGroupBox(myAction == 1 ? 
+                                    tr("SMESH_MERGE_ELEMENTS") : 
+                                    tr("SMESH_MERGE_NODES"), 
+                                    this);
+
+  QButtonGroup* ButtonGroup = new QButtonGroup(this);
+  QHBoxLayout* GroupConstructorsLayout = new QHBoxLayout(GroupConstructors);
+  GroupConstructorsLayout->setSpacing(SPACING);
+  GroupConstructorsLayout->setMargin(MARGIN);
+
+  RadioButton = new QRadioButton(GroupConstructors);
+  RadioButton->setIcon(myAction == 1 ? IconMergeElems : IconMergeNodes);
+  RadioButton->setChecked(true);
+  GroupConstructorsLayout->addWidget(RadioButton);
+  ButtonGroup->addButton(RadioButton, 0);
+
+  /***************************************************************/
+  // Controls for mesh defining
+  GroupMesh = new QGroupBox(tr("SMESH_SELECT_WHOLE_MESH"), this);
+  QHBoxLayout* GroupMeshLayout = new QHBoxLayout(GroupMesh);
+  GroupMeshLayout->setSpacing(SPACING);
+  GroupMeshLayout->setMargin(MARGIN);
+
+  TextLabelName = new QLabel(tr("SMESH_NAME"), GroupMesh);
+  SelectMeshButton = new QPushButton(GroupMesh);
+  SelectMeshButton->setIcon(IconSelect);
+  LineEditMesh = new QLineEdit(GroupMesh);
+  LineEditMesh->setReadOnly(true);
+
+  GroupMeshLayout->addWidget(TextLabelName);
+  GroupMeshLayout->addWidget(SelectMeshButton);
+  GroupMeshLayout->addWidget(LineEditMesh);
+
+  /***************************************************************/
+  // Controls for switch dialog behaviour
+
+  TypeBox = new QGroupBox( tr( "SMESH_MODE" ), this );
+  GroupType = new QButtonGroup( this );
+  QHBoxLayout* aTypeBoxLayout = new QHBoxLayout( TypeBox );
+  aTypeBoxLayout->setMargin( MARGIN );
+  aTypeBoxLayout->setSpacing( SPACING );
+
+  QRadioButton* rb1 = new QRadioButton( tr( "SMESH_AUTOMATIC" ), TypeBox );
+  QRadioButton* rb2 = new QRadioButton( tr( "SMESH_MANUAL" ),   TypeBox );
+  GroupType->addButton( rb1, 0 );
+  GroupType->addButton( rb2, 1 );
+  aTypeBoxLayout->addWidget( rb1 );
+  aTypeBoxLayout->addWidget( rb2 );
+
+  myTypeId = 0;
+
+  /***************************************************************/
+  // Controls for coincident elements detecting
+  GroupCoincident = new QGroupBox(myAction == 1 ? 
+                                  tr("COINCIDENT_ELEMENTS") : 
+                                  tr("COINCIDENT_NODES"), 
+                                  this);
+
+  QVBoxLayout* aCoincidentLayout = new QVBoxLayout(GroupCoincident);
+  aCoincidentLayout->setSpacing(SPACING);
+  aCoincidentLayout->setMargin(MARGIN);
+
+  if (myAction == 0) { // case merge nodes
+    QWidget* foo = new QWidget(GroupCoincident);
+    TextLabelTolerance = new QLabel(tr("SMESH_TOLERANCE"), foo);
+    SpinBoxTolerance = new SMESHGUI_SpinBox(foo);
+    SpinBoxTolerance->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
+
+    GroupExclude = new QGroupBox(tr("EXCLUDE_GROUPS"), foo);
+    GroupExclude->setCheckable( true );
+    GroupExclude->setChecked( false );
+    ListExclude = new QListWidget( GroupExclude );
+    QVBoxLayout* GroupExcludeLayout = new QVBoxLayout(GroupExclude);
+    GroupExcludeLayout->setSpacing(SPACING);
+    GroupExcludeLayout->setMargin(MARGIN);
+    GroupExcludeLayout->addWidget(ListExclude);
+
+    QGridLayout* fooLayout = new QGridLayout( foo );
+    fooLayout->setSpacing(SPACING);
+    fooLayout->setMargin(0);
+    fooLayout->addWidget(TextLabelTolerance, 0, 0 );
+    fooLayout->addWidget(SpinBoxTolerance,   0, 1 );
+    fooLayout->addWidget(GroupExclude,       1, 0, 1, 2 );
+    aCoincidentLayout->addWidget(foo);
+  }
+  else {
+    TextLabelTolerance = 0;
+    SpinBoxTolerance = 0;
+    GroupExclude = 0;
+    ListExclude = 0;
+  }
+
+  GroupCoincidentWidget = new QWidget(GroupCoincident);
+  QGridLayout* GroupCoincidentLayout = new QGridLayout(GroupCoincidentWidget);
+  GroupCoincidentLayout->setSpacing(SPACING);
+  GroupCoincidentLayout->setMargin(0);
+
+  ListCoincident = new QListWidget(GroupCoincidentWidget);
+  ListCoincident->setSelectionMode(QListWidget::ExtendedSelection);
+
+  DetectButton      = new QPushButton(tr("DETECT"),           GroupCoincidentWidget);
+  AddGroupButton    = new QPushButton(tr("SMESH_BUT_ADD"),    GroupCoincidentWidget);
+  RemoveGroupButton = new QPushButton(tr("SMESH_BUT_REMOVE"), GroupCoincidentWidget);
+
+  SelectAllCB = new QCheckBox(tr("SELECT_ALL"), GroupCoincidentWidget);
+
+  GroupCoincidentLayout->addWidget(ListCoincident,    0,   0, 4, 2);
+  GroupCoincidentLayout->addWidget(DetectButton,      0,   2);
+  GroupCoincidentLayout->addWidget(AddGroupButton,    2, 2);
+  GroupCoincidentLayout->addWidget(RemoveGroupButton, 3, 2);
+  GroupCoincidentLayout->addWidget(SelectAllCB,       4, 0, 1, 3);
+  GroupCoincidentLayout->setRowMinimumHeight(1, 10);
+  GroupCoincidentLayout->setRowStretch(1, 5);
+
+  aCoincidentLayout->addWidget(GroupCoincidentWidget);
+
+  /***************************************************************/
+  // Controls for editing the selected group
+  GroupEdit = new QGroupBox(tr("EDIT_SELECTED_GROUP"), this);
+  QGridLayout* GroupEditLayout = new QGridLayout(GroupEdit);
+  GroupEditLayout->setSpacing(SPACING);
+  GroupEditLayout->setMargin(MARGIN);
+
+  ListEdit = new QListWidget(GroupEdit);
+  //ListEdit->setRowMode(QListBox::FixedNumber);
+  //ListEdit->setHScrollBarMode(QScrollView::AlwaysOn);
+  //ListEdit->setVScrollBarMode(QScrollView::AlwaysOff);
+  ListEdit->setFlow( QListView::LeftToRight );
+  ListEdit->setSelectionMode(QListWidget::ExtendedSelection);
+
+  AddElemButton = new QPushButton(GroupEdit);
+  AddElemButton->setIcon(IconAdd);
+  RemoveElemButton = new QPushButton(GroupEdit);
+  RemoveElemButton->setIcon(IconRemove);
+  SetFirstButton = new QPushButton(GroupEdit);
+  SetFirstButton->setIcon(QPixmap(IconFirst));
+
+  GroupEditLayout->addWidget(ListEdit,         0, 0, 2, 1);
+  GroupEditLayout->addWidget(AddElemButton,    0, 1);
+  GroupEditLayout->addWidget(RemoveElemButton, 0, 2);
+  GroupEditLayout->addWidget(SetFirstButton,   1, 1, 1, 2);
+
+  /***************************************************************/
+  GroupButtons = new QGroupBox(this);
+  QHBoxLayout* GroupButtonsLayout = new QHBoxLayout(GroupButtons);
+  GroupButtonsLayout->setSpacing(SPACING);
+  GroupButtonsLayout->setMargin(MARGIN);
+
+  buttonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), GroupButtons);
+  buttonOk->setAutoDefault(true);
+  buttonOk->setDefault(true);
+  buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons);
+  buttonApply->setAutoDefault(true);
+  buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons);
+  buttonCancel->setAutoDefault(true);
+  buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons);
+  buttonHelp->setAutoDefault(true);
+
+  GroupButtonsLayout->addWidget(buttonOk);
+  GroupButtonsLayout->addSpacing(10);
+  GroupButtonsLayout->addWidget(buttonApply);
+  GroupButtonsLayout->addSpacing(10);
+  GroupButtonsLayout->addStretch();
+  GroupButtonsLayout->addWidget(buttonCancel);
+  GroupButtonsLayout->addWidget(buttonHelp);
+
+  /***************************************************************/
+  DlgLayout->addWidget(GroupConstructors);
+  DlgLayout->addWidget(GroupMesh);
+  DlgLayout->addWidget(TypeBox);
+  DlgLayout->addWidget(GroupCoincident);
+  DlgLayout->addWidget(GroupEdit);
+  DlgLayout->addWidget(GroupButtons);
+
+  GroupCoincidentWidget->setVisible( myAction != 0 );
+  GroupCoincident->setVisible( myAction == 0 );
+  //if GroupExclude->setVisible( myAction == 0 );
+  GroupEdit->hide();
+
+  this->resize(10,10);
+
+  Init(); // Initialisations
+}
+
+//=================================================================================
+// function : ~SMESHGUI_MergeDlg()
+// purpose  : Destroys the object and frees any allocated resources
+//=================================================================================
+SMESHGUI_MergeDlg::~SMESHGUI_MergeDlg()
+{
+  delete myIdPreview;
+}
+
+//=================================================================================
+// function : Init()
+// purpose  :
+//=================================================================================
+void SMESHGUI_MergeDlg::Init()
+{
+  if (myAction == 0) {
+    SpinBoxTolerance->RangeStepAndValidator(0.0, COORD_MAX, 0.00001, "len_tol_precision");
+    SpinBoxTolerance->SetValue(1e-05);
+  }
+
+  RadioButton->setChecked(true);
+
+  GroupType->button(0)->setChecked(true);
+
+  myEditCurrentArgument = (QWidget*)LineEditMesh; 
+
+  myActor = 0;
+  mySubMeshOrGroup = SMESH::SMESH_subMesh::_nil();
+
+  mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
+
+  mySMESHGUI->SetActiveDialogBox((QDialog*)this);
+  myIsBusy = false;
+  
+  /* 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(buttonHelp,   SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
+
+  connect(SelectMeshButton, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument()));
+  connect(DetectButton, SIGNAL (clicked()), this, SLOT(onDetect()));
+  connect(ListCoincident, SIGNAL (itemSelectionChanged()), this, SLOT(onSelectGroup()));
+  connect(AddGroupButton, SIGNAL (clicked()), this, SLOT(onAddGroup()));
+  connect(RemoveGroupButton, SIGNAL (clicked()), this, SLOT(onRemoveGroup()));
+  connect(SelectAllCB, SIGNAL(toggled(bool)), this, SLOT(onSelectAll(bool)));
+  connect(ListEdit, SIGNAL (itemSelectionChanged()), this, SLOT(onSelectElementFromGroup()));
+  connect(AddElemButton, SIGNAL (clicked()), this, SLOT(onAddElement()));
+  connect(RemoveElemButton, SIGNAL (clicked()), this, SLOT(onRemoveElement()));
+  connect(SetFirstButton, SIGNAL( clicked() ), this, SLOT( onSetFirst() ) );
+  connect(GroupType, SIGNAL(buttonClicked(int)), this, SLOT(onTypeChanged(int)));
+
+  connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
+  connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
+  /* to close dialog if study change */
+  connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(ClickOnCancel()));
+
+  // Init Mesh field from selection
+  SelectionIntoArgument();
+
+  // Update Buttons
+  updateControls();
+  
+  if (myAction == 0)
+    myHelpFileName = "merging_nodes_page.html";
+  else
+    myHelpFileName = "merging_elements_page.html";
+}
+
+//=================================================================================
+// function : FindGravityCenter()
+// purpose  :
+//=================================================================================
+void SMESHGUI_MergeDlg::FindGravityCenter(TColStd_MapOfInteger & theElemsIdMap, 
+                                          std::list< gp_XYZ > & theGrCentersXYZ)
+{
+  if (!myActor)
+    return;
+
+  SMDS_Mesh* aMesh = 0;
+  aMesh = myActor->GetObject()->GetMesh();
+  if (!aMesh)
+    return;
+
+  int nbNodes;
+
+  TColStd_MapIteratorOfMapOfInteger idIter( theElemsIdMap );
+  for( ; idIter.More(); idIter.Next() ) {
+    const SMDS_MeshElement* anElem = aMesh->FindElement(idIter.Key());
+    if ( !anElem )
+      continue;
+
+    gp_XYZ anXYZ(0., 0., 0.);
+    SMDS_ElemIteratorPtr nodeIt = anElem->nodesIterator();
+    for ( nbNodes = 0; nodeIt->more(); nbNodes++ ) {
+      const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+      anXYZ.Add( gp_XYZ( node->X(), node->Y(), node->Z() ) );
+    }
+    anXYZ.Divide( nbNodes );
+    
+    theGrCentersXYZ.push_back( anXYZ );
+  }
+}
+
+//=================================================================================
+// function : ClickOnApply()
+// purpose  :
+//=================================================================================
+bool SMESHGUI_MergeDlg::ClickOnApply()
+{
+  if (mySMESHGUI->isActiveStudyLocked() || myMesh->_is_nil())
+    return false;
+
+  try {
+    if (myTypeId == 0)
+      onDetect();
+
+    SUIT_OverrideCursor aWaitCursor;
+    SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
+
+    SMESH::long_array_var anIds = new SMESH::long_array;
+    SMESH::array_of_long_array_var aGroupsOfElements = new SMESH::array_of_long_array;
+
+    if ( ListCoincident->count() == 0) {
+      if (myAction == 0)
+        SUIT_MessageBox::warning(this,
+                                 tr("SMESH_WARNING"),
+                                 tr("SMESH_NO_NODES_DETECTED"));
+      else
+        SUIT_MessageBox::warning(this,
+                                 tr("SMESH_WARNING"),
+                                 tr("SMESH_NO_ELEMENTS_DETECTED"));
+      return false;
+    }
+
+    aGroupsOfElements->length(ListCoincident->count());
+
+    int anArrayNum = 0;
+    for (int i = 0; i < ListCoincident->count(); i++) {
+      QStringList aListIds = ListCoincident->item(i)->text().split(" ", QString::SkipEmptyParts);
+
+      anIds->length(aListIds.count());
+      for (int i = 0; i < aListIds.count(); i++)
+        anIds[i] = aListIds[i].toInt();
+
+      aGroupsOfElements[anArrayNum++] = anIds.inout();
+    }
+
+    if( myAction == 0 )
+      aMeshEditor->MergeNodes (aGroupsOfElements.inout());
+    else
+      aMeshEditor->MergeElements (aGroupsOfElements.inout());
+
+    if ( myTypeId == 0 ) {
+      if (myAction ==0)
+        SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INFORMATION"),
+                                     tr("SMESH_MERGED_NODES").arg(QString::number(ListCoincident->count()).toLatin1().data()));
+      else
+        SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INFORMATION"),
+                                     tr("SMESH_MERGED_ELEMENTS").arg(QString::number(ListCoincident->count()).toLatin1().data()));
+    }
+      
+
+  } catch(...) {
+  }
+  
+  ListCoincident->clear();
+  
+  SMESH::UpdateView();
+  SMESHGUI::Modified();
+  
+  return true;
+}
+
+//=================================================================================
+// function : ClickOnOk()
+// purpose  :
+//=================================================================================
+void SMESHGUI_MergeDlg::ClickOnOk()
+{
+  if (ClickOnApply())
+    ClickOnCancel();
+}
+
+//=================================================================================
+// function : ClickOnCancel()
+// purpose  :
+//=================================================================================
+void SMESHGUI_MergeDlg::ClickOnCancel()
+{
+  myIdPreview->SetPointsLabeled(false);
+  SMESH::SetPointRepresentation(false);
+  disconnect(mySelectionMgr, 0, this, 0);
+  disconnect(mySMESHGUI, 0, this, 0);
+  mySMESHGUI->ResetState();
+
+  mySelectionMgr->clearFilters();
+  //mySelectionMgr->clearSelected();
+
+  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+    aViewWindow->SetSelectionMode(ActorSelection);
+
+  reject();
+}
+
+//=================================================================================
+// function : ClickOnHelp()
+// purpose  :
+//=================================================================================
+void SMESHGUI_MergeDlg::ClickOnHelp()
+{
+  LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
+  if (app) 
+    app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
+  else {
+    QString platform;
+#ifdef WIN32
+    platform = "winapplication";
+#else
+    platform = "application";
+#endif
+    SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser", 
+                                                                 platform)).
+                             arg(myHelpFileName));
+  }
+}
+
+//=================================================================================
+// function : onEditGroup()
+// purpose  :
+//=================================================================================
+void SMESHGUI_MergeDlg::onEditGroup()
+{
+  QList<QListWidgetItem*> selItems = ListCoincident->selectedItems();
+  if ( selItems.count() != 1 ) {
+    ListEdit->clear();
+    return;
+  }
+
+  QStringList aNewIds;
+
+  for (int i = 0; i < ListEdit->count(); i++ )
+    aNewIds.append(ListEdit->item(i)->text());
+
+  ListCoincident->clearSelection();
+  selItems.first()->setText(aNewIds.join(" "));
+  selItems.first()->setSelected(true);
+}
+
+//=================================================================================
+// function : updateControls()
+// purpose  :
+//=================================================================================
+void SMESHGUI_MergeDlg::updateControls()
+{
+  if (ListEdit->count() == 0)
+    SetFirstButton->setEnabled(false);
+  bool enable = !(myMesh->_is_nil()) && (ListCoincident->count() || (myTypeId == 0));
+  buttonOk->setEnabled(enable);
+  buttonApply->setEnabled(enable);
+}
+
+//=================================================================================
+// function : onDetect()
+// purpose  :
+//=================================================================================
+void SMESHGUI_MergeDlg::onDetect()
+{
+  if ( myMesh->_is_nil() || LineEditMesh->text().isEmpty() )
+    return;
+
+  try {
+    SUIT_OverrideCursor aWaitCursor;
+    SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
+
+    ListCoincident->clear();
+    ListEdit->clear();
+
+    SMESH::array_of_long_array_var aGroupsArray;
+    SMESH::ListOfIDSources_var aExcludeGroups = new SMESH::ListOfIDSources;
+
+    SMESH::SMESH_IDSource_var src;
+    if ( mySubMeshOrGroup->_is_nil() ) src = SMESH::SMESH_IDSource::_duplicate( myMesh );
+    else src = SMESH::SMESH_IDSource::_duplicate( mySubMeshOrGroup );
+
+    switch (myAction) {
+    case 0 :
+      for ( int i = 0; GroupExclude->isChecked() && i < ListExclude->count(); i++ ) {
+        if ( ListExclude->item( i )->checkState() == Qt::Checked ) {
+          aExcludeGroups->length( aExcludeGroups->length()+1 );
+          aExcludeGroups[ aExcludeGroups->length()-1 ] = SMESH::SMESH_IDSource::_duplicate( myGroups[i] );
+        }
+      }
+      aMeshEditor->FindCoincidentNodesOnPartBut(src.in(),
+                                                SpinBoxTolerance->GetValue(), 
+                                                aGroupsArray.out(),
+                                                aExcludeGroups.in());
+      break;
+    case 1 :
+      aMeshEditor->FindEqualElements(src.in(), aGroupsArray.out());
+      break;
+    }
+    
+    for (int i = 0; i < aGroupsArray->length(); i++) {
+      SMESH::long_array& aGroup = aGroupsArray[i];
+
+      QStringList anIDs;
+      for (int j = 0; j < aGroup.length(); j++)
+        anIDs.append(QString::number(aGroup[j]));
+
+      ListCoincident->addItem(anIDs.join(" "));
+    }
+   } catch(...) {
+  }
+
+  ListCoincident->selectAll();
+  updateControls();
+}
+
+//=================================================================================
+// function : onSelectGroup()
+// purpose  :
+//=================================================================================
+void SMESHGUI_MergeDlg::onSelectGroup()
+{
+  if (myIsBusy || !myActor)
+    return;
+  myEditCurrentArgument = (QWidget*)ListCoincident;
+
+  ListEdit->clear();
+  
+  TColStd_MapOfInteger anIndices;
+  QList<QListWidgetItem*> selItems = ListCoincident->selectedItems();
+  QListWidgetItem* anItem;
+  QStringList aListIds;
+
+  ListEdit->clear();
+
+  foreach(anItem, selItems) {
+    aListIds = anItem->text().split(" ", QString::SkipEmptyParts);
+    for (int i = 0; i < aListIds.count(); i++)
+      anIndices.Add(aListIds[i].toInt());
+  }
+  
+  if (selItems.count() == 1) {
+    ListEdit->addItems(aListIds);
+    ListEdit->selectAll();
+  }
+
+  mySelector->AddOrRemoveIndex(myActor->getIO(), anIndices, false);
+  SALOME_ListIO aList;
+  aList.Append(myActor->getIO());
+  mySelectionMgr->setSelectedObjects(aList,false);
+  
+  if (myAction == 0) {
+    myIdPreview->SetPointsData(myActor->GetObject()->GetMesh(), anIndices);
+    myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
+  }
+  else {
+    std::list< gp_XYZ > aGrCentersXYZ;
+    FindGravityCenter(anIndices, aGrCentersXYZ);
+    myIdPreview->SetElemsData( anIndices, aGrCentersXYZ);
+    myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
+  }
+
+  updateControls();
+}
+
+//=================================================================================
+// function : onSelectAll()
+// purpose  :
+//=================================================================================
+void SMESHGUI_MergeDlg::onSelectAll (bool isToggled)
+{
+  if ( isToggled )
+    ListCoincident->selectAll();
+  else
+    ListCoincident->clearSelection();
+}
+
+//=================================================================================
+// function : onSelectElementFromGroup()
+// purpose  :
+//=================================================================================
+void SMESHGUI_MergeDlg::onSelectElementFromGroup()
+{
+  if (myIsBusy || !myActor)
+    return;
+
+  TColStd_MapOfInteger anIndices;
+  QList<QListWidgetItem*> selItems = ListEdit->selectedItems();
+  QListWidgetItem* anItem;
+
+  foreach(anItem, selItems)
+    anIndices.Add(anItem->text().toInt());
+
+  SetFirstButton->setEnabled(selItems.count() == 1);
+
+  mySelector->AddOrRemoveIndex(myActor->getIO(), anIndices, false);
+  SALOME_ListIO aList;
+  aList.Append(myActor->getIO());
+  mySelectionMgr->setSelectedObjects(aList);
+
+  if (myAction == 0) {
+    myIdPreview->SetPointsData(myActor->GetObject()->GetMesh(), anIndices);
+    myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
+  }
+  else {
+    std::list< gp_XYZ > aGrCentersXYZ;
+    FindGravityCenter(anIndices, aGrCentersXYZ);
+    myIdPreview->SetElemsData(anIndices, aGrCentersXYZ);
+    myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
+  }
+}
+
+//=================================================================================
+// function : onAddGroup()
+// purpose  :
+//=================================================================================
+void SMESHGUI_MergeDlg::onAddGroup()
+{
+  if ( myMesh->_is_nil() || LineEditMesh->text().isEmpty() )
+    return;
+
+  QString anIDs = "";
+  int aNbElements = 0;
+  aNbElements = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), anIDs);
+
+  if (aNbElements < 1)
+    return;
+  
+  ListCoincident->clearSelection();
+  ListCoincident->addItem(anIDs);
+  int nbGroups = ListCoincident->count();
+  if (nbGroups) {
+    ListCoincident->setCurrentRow(nbGroups-1);
+    ListCoincident->item(nbGroups-1)->setSelected(true);
+  }
+  else {
+    // VSR ? this code seems to be never executed!!!
+    ListCoincident->setCurrentRow(0);
+    //ListCoincident->setSelected(0, true); // VSR: no items - no selection
+  }
+
+  updateControls();
+}
+
+//=================================================================================
+// function : onRemoveGroup()
+// purpose  :
+//=================================================================================
+void SMESHGUI_MergeDlg::onRemoveGroup()
+{
+  if (myEditCurrentArgument != (QWidget*)ListCoincident)
+    return;
+  myIsBusy = true;
+
+  QList<QListWidgetItem*> selItems = ListCoincident->selectedItems();
+  QListWidgetItem* anItem;
+
+  foreach(anItem, selItems)
+    delete anItem;
+
+  ListEdit->clear();
+  updateControls();
+
+  myIsBusy = false;
+}
+
+//=================================================================================
+// function : onAddElement()
+// purpose  :
+//=================================================================================
+void SMESHGUI_MergeDlg::onAddElement()
+{
+  if (!myActor)
+    return;
+  myIsBusy = true;
+
+  QString aListStr = "";
+  int aNbNnodes = 0;
+
+  aNbNnodes = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aListStr);
+  if (aNbNnodes < 1)
+    return;
+
+  QStringList aNodes = aListStr.split(" ", QString::SkipEmptyParts);
+
+  for (QStringList::iterator it = aNodes.begin(); it != aNodes.end(); ++it) {
+    QList<QListWidgetItem*> found = ListEdit->findItems(*it, Qt::MatchExactly);
+    if ( found.count() == 0 ) {
+      QListWidgetItem* anItem = new QListWidgetItem(*it);
+      ListEdit->addItem(anItem);
+      anItem->setSelected(true);
+    }
+    else {
+      QListWidgetItem* anItem;
+      foreach(anItem, found) anItem->setSelected(true);
+    }
+  }
+
+  myIsBusy = false;
+  onEditGroup();
+}
+
+//=================================================================================
+// function : onRemoveElement()
+// purpose  :
+//=================================================================================
+void SMESHGUI_MergeDlg::onRemoveElement()
+{
+  if (myEditCurrentArgument != (QWidget*)ListCoincident)
+    return;
+  myIsBusy = true;
+
+  QList<QListWidgetItem*> selItems = ListEdit->selectedItems();
+  QListWidgetItem* anItem;
+
+  foreach(anItem, selItems)
+    delete anItem;
+  
+  myIsBusy = false;
+  onEditGroup();
+}
+
+//=================================================================================
+// function : onSetFirst()
+// purpose  :
+//=================================================================================
+void SMESHGUI_MergeDlg::onSetFirst()
+{
+  if (myEditCurrentArgument != (QWidget*)ListCoincident)
+    return;
+  myIsBusy = true;
+  
+  QList<QListWidgetItem*> selItems = ListEdit->selectedItems();
+  QListWidgetItem* anItem;
+  
+  foreach(anItem, selItems) {
+    ListEdit->takeItem(ListEdit->row(anItem));
+    ListEdit->insertItem(0, anItem);
+  }
+
+  myIsBusy = false;
+  onEditGroup();
+}
+
+//=================================================================================
+// function : SetEditCurrentArgument()
+// purpose  :
+//=================================================================================
+void SMESHGUI_MergeDlg::SetEditCurrentArgument()
+{
+  QPushButton* send = (QPushButton*)sender();
+
+  disconnect(mySelectionMgr, 0, this, 0);
+  mySelectionMgr->clearSelected();
+  mySelectionMgr->clearFilters();
+
+  if (send == SelectMeshButton) {
+    myEditCurrentArgument = (QWidget*)LineEditMesh;
+    SMESH::SetPointRepresentation(false);
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->SetSelectionMode(ActorSelection);
+    if (myTypeId == 1)
+      mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter);
+  }
+
+  myEditCurrentArgument->setFocus();
+  connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
+  SelectionIntoArgument();
+}
+
+//=================================================================================
+// function : SelectionIntoArgument()
+// purpose  : Called when selection as changed or other case
+//=================================================================================
+void SMESHGUI_MergeDlg::SelectionIntoArgument()
+{
+  if (myEditCurrentArgument == (QWidget*)LineEditMesh) {
+    QString aString = "";
+    LineEditMesh->setText(aString);
+    
+    ListCoincident->clear();
+    ListEdit->clear();
+    myActor = 0;
+    QString aCurrentEntry = myEntry;
+    
+    int nbSel = SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
+    if (nbSel != 1) {
+      myIdPreview->SetPointsLabeled(false);
+      SMESH::SetPointRepresentation(false);
+      mySelectionMgr->clearFilters();
+      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+        aViewWindow->SetSelectionMode(ActorSelection);
+      return;
+    }
+
+    SALOME_ListIO aList;
+    mySelectionMgr->selectedObjects(aList);
+    
+    Handle(SALOME_InteractiveObject) IO = aList.First();
+    myEntry = IO->getEntry();
+    myMesh = SMESH::GetMeshByIO(IO);
+    
+    if (myMesh->_is_nil())
+      return;
+
+    LineEditMesh->setText(aString);
+    
+    myActor = SMESH::FindActorByEntry(IO->getEntry());
+    if (!myActor)
+      myActor = SMESH::FindActorByObject(myMesh);
+    
+    if ( myActor && myTypeId ==1 ) {
+      mySubMeshOrGroup = SMESH::SMESH_IDSource::_nil();
+      mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter);
+      
+      if ((!SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(IO)->_is_nil() || //SUBMESH OR GROUP
+           !SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(IO)->_is_nil()) &&
+          !SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO)->_is_nil())
+        mySubMeshOrGroup = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO);
+      
+      if (myAction == 0) {
+        SMESH::SetPointRepresentation(true);
+        if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+          aViewWindow->SetSelectionMode(NodeSelection);
+      }
+      else
+        if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+          aViewWindow->SetSelectionMode(CellSelection);
+    }
+
+    // process groups
+    if ( myAction == 0 && !myMesh->_is_nil() && myEntry != aCurrentEntry ) {
+      myGroups.clear();
+      ListExclude->clear();
+      SMESH::ListOfGroups_var aListOfGroups = myMesh->GetGroups();
+      for( int i = 0, n = aListOfGroups->length(); i < n; i++ ) {
+        SMESH::SMESH_GroupBase_var aGroup = aListOfGroups[i];
+        if ( !aGroup->_is_nil() ) { // && aGroup->GetType() == SMESH::NODE
+          QString aGroupName( aGroup->GetName() );
+          if ( !aGroupName.isEmpty() ) {
+            myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup));
+            QListWidgetItem* item = new QListWidgetItem( aGroupName );
+            item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable );
+            item->setCheckState( Qt::Unchecked );
+            ListExclude->addItem( item );
+          }
+        }
+      }
+    }
+
+    updateControls();
+  }
+}
+
+//=================================================================================
+// function : DeactivateActiveDialog()
+// purpose  :
+//=================================================================================
+void SMESHGUI_MergeDlg::DeactivateActiveDialog()
+{
+  if (GroupConstructors->isEnabled()) {
+    GroupConstructors->setEnabled(false);
+    TypeBox->setEnabled(false);
+    GroupMesh->setEnabled(false);
+    GroupCoincident->setEnabled(false);
+    GroupEdit->setEnabled(false);
+    GroupButtons->setEnabled(false);
+    mySMESHGUI->ResetState();
+    mySMESHGUI->SetActiveDialogBox(0);
+  }
+
+  mySelectionMgr->clearSelected();
+  disconnect(mySelectionMgr, 0, this, 0);
+}
+
+//=================================================================================
+// function : ActivateThisDialog()
+// purpose  :
+//=================================================================================
+void SMESHGUI_MergeDlg::ActivateThisDialog()
+{
+  /* Emit a signal to deactivate the active dialog */
+  mySMESHGUI->EmitSignalDeactivateDialog();
+  GroupConstructors->setEnabled(true);
+  TypeBox->setEnabled(true);
+  GroupMesh->setEnabled(true);
+  GroupCoincident->setEnabled(true);
+  GroupEdit->setEnabled(true);
+  GroupButtons->setEnabled(true);
+
+  connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
+  mySMESHGUI->SetActiveDialogBox((QDialog*)this);
+  SelectionIntoArgument();
+}
+
+//=================================================================================
+// function : enterEvent()
+// purpose  :
+//=================================================================================
+void SMESHGUI_MergeDlg::enterEvent(QEvent*)
+{
+  if (!GroupConstructors->isEnabled())
+    ActivateThisDialog();
+}
+
+//=================================================================================
+// function : closeEvent()
+// purpose  :
+//=================================================================================
+void SMESHGUI_MergeDlg::closeEvent(QCloseEvent*)
+{
+  /* same than click on cancel button */
+  ClickOnCancel();
+}
+
+//=======================================================================
+//function : hideEvent
+//purpose  : caused by ESC key
+//=======================================================================
+void SMESHGUI_MergeDlg::hideEvent (QHideEvent *)
+{
+  if (!isMinimized())
+    ClickOnCancel();
+}
+
+//=================================================================================
+// function : keyPressEvent()
+// purpose  :
+//=================================================================================
+void SMESHGUI_MergeDlg::keyPressEvent( QKeyEvent* e)
+{
+  QDialog::keyPressEvent( e );
+  if ( e->isAccepted() )
+    return;
+
+  if ( e->key() == Qt::Key_F1 ) {
+    e->accept();
+    ClickOnHelp();
+  }
+}
+
+//=================================================================================
+// function : onTypeChanged()
+// purpose  : the type radio button management
+//=================================================================================
+void SMESHGUI_MergeDlg::onTypeChanged (int id)
+{
+  if (myTypeId == id)
+    return;
+
+  myTypeId = id;
+  switch (id)
+  {
+  case 0: // automatic
+    myIdPreview->SetPointsLabeled(false);
+    SMESH::SetPointRepresentation(false);
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->SetSelectionMode(ActorSelection);
+    mySelectionMgr->clearFilters();
+    if (myAction == 0)
+      GroupCoincidentWidget->hide();
+    else
+      GroupCoincident->hide();
+    GroupEdit->hide();
+    break;
+
+  case 1: // manual
+    SMESH::UpdateView();
+
+    // Costruction of the logical filter
+    SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter (MESHorSUBMESH);
+    SMESH_TypeFilter* aSmeshGroupFilter    = new SMESH_TypeFilter (GROUP);
+    
+    QList<SUIT_SelectionFilter*> aListOfFilters;
+    if (aMeshOrSubMeshFilter) aListOfFilters.append(aMeshOrSubMeshFilter);
+    if (aSmeshGroupFilter)    aListOfFilters.append(aSmeshGroupFilter);
+    
+    myMeshOrSubMeshOrGroupFilter =
+      new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR);
+
+    if (myAction == 0) {
+      GroupCoincidentWidget->show();
+      SMESH::SetPointRepresentation(true);
+      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+        aViewWindow->SetSelectionMode(NodeSelection);
+    }
+    else {
+      GroupCoincident->show();
+      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+        aViewWindow->SetSelectionMode(CellSelection);
+    }
+    GroupEdit->show();
+    break;
+  }
+  updateControls();
+
+  qApp->processEvents();
+  updateGeometry();
+  resize(10,10);
+
+  SelectionIntoArgument();
+}
diff --git a/src/SMESHGUI/SMESHGUI_MergeDlg.h b/src/SMESHGUI/SMESHGUI_MergeDlg.h
new file mode 100644 (file)
index 0000000..dd9458d
--- /dev/null
@@ -0,0 +1,175 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+// SMESH SMESHGUI : GUI for SMESH component
+// File   : SMESHGUI_MergeDlg.h
+// Author : Open CASCADE S.A.S.
+//
+#ifndef SMESHGUI_MergeDlg_H
+#define SMESHGUI_MergeDlg_H
+
+// SMESH includes
+#include "SMESH_SMESHGUI.hxx"
+
+// Qt includes
+#include <QDialog>
+
+// OCCT includes
+#include <gp_XYZ.hxx>
+
+// STL includes
+#include <list>
+
+// IDL includes
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+
+class QGroupBox;
+class QLabel;
+class QLineEdit;
+class QPushButton;
+class QRadioButton;
+class QCheckBox;
+class QListWidget;
+class QButtonGroup;
+class SMESHGUI;
+class SMESHGUI_SpinBox;
+class SMESH_Actor;
+class SVTK_Selector;
+class LightApp_SelectionMgr;
+class SUIT_SelectionFilter;
+class TColStd_MapOfInteger;
+
+namespace SMESH
+{
+  struct TIdPreview;
+}
+
+//=================================================================================
+// class    : SMESHGUI_MergeDlg
+// purpose  : 
+//=================================================================================
+class SMESHGUI_EXPORT SMESHGUI_MergeDlg : public QDialog
+{
+  Q_OBJECT;
+
+public:
+  SMESHGUI_MergeDlg( SMESHGUI*, int );
+  ~SMESHGUI_MergeDlg();
+
+private:
+  void                      Init();
+  void                      closeEvent( QCloseEvent* );
+  void                      enterEvent( QEvent* );              /* mouse enter the QWidget */
+  void                      hideEvent( QHideEvent* );           /* ESC key */
+  void                      keyPressEvent( QKeyEvent* );
+  void                      onEditGroup();
+
+  void                      FindGravityCenter( TColStd_MapOfInteger&, 
+                                               std::list<gp_XYZ>& );
+  // add the centers of gravity of ElemsIdMap elements to the GrCentersXYZ list
+
+private:
+  typedef QList<SMESH::SMESH_GroupBase_var> GrpList;
+
+  SMESHGUI*                 mySMESHGUI;     /* Current SMESHGUI object */
+  LightApp_SelectionMgr*    mySelectionMgr; /* User shape selection */
+  SVTK_Selector*            mySelector;
+  
+  QWidget*                  myEditCurrentArgument;
+
+  SMESH::SMESH_Mesh_var     myMesh;
+  SMESH::SMESH_IDSource_var mySubMeshOrGroup;
+  SMESH_Actor*              myActor;
+  SUIT_SelectionFilter*     myMeshOrSubMeshOrGroupFilter;
+
+  SMESH::TIdPreview*        myIdPreview;
+
+  int                       myAction;
+  bool                      myIsBusy;
+  int                       myTypeId;
+
+  // Widgets
+  QGroupBox*                GroupConstructors;
+  QRadioButton*             RadioButton;
+
+  QGroupBox*                GroupButtons;
+  QPushButton*              buttonOk;
+  QPushButton*              buttonCancel;
+  QPushButton*              buttonApply;
+  QPushButton*              buttonHelp;
+
+  QGroupBox*                GroupMesh;
+  QLabel*                   TextLabelName;
+  QPushButton*              SelectMeshButton;
+  QLineEdit*                LineEditMesh;
+
+  QGroupBox*                GroupCoincident;
+  QWidget*                  GroupCoincidentWidget;
+  QLabel*                   TextLabelTolerance;
+  SMESHGUI_SpinBox*         SpinBoxTolerance;
+  QPushButton*              DetectButton;
+  QListWidget*              ListCoincident;
+  QPushButton*              AddGroupButton;
+  QPushButton*              RemoveGroupButton;
+  QCheckBox*                SelectAllCB;
+
+  QGroupBox*                GroupEdit;
+  QListWidget*              ListEdit;
+  QPushButton*              AddElemButton;
+  QPushButton*              RemoveElemButton;
+  QPushButton*              SetFirstButton;
+
+  QGroupBox*                GroupExclude;
+  QListWidget*              ListExclude;
+
+  QGroupBox*                TypeBox;
+  QButtonGroup*             GroupType;
+    
+  QString                   myHelpFileName;
+
+  QString                   myEntry;
+  GrpList                   myGroups;
+
+ private slots:
+  void                      ClickOnOk();
+  void                      ClickOnCancel();
+  bool                      ClickOnApply();
+  void                      ClickOnHelp();
+  void                      updateControls();
+  void                      onDetect();
+  void                      onAddGroup();
+  void                      onRemoveGroup();
+  void                      onSelectGroup();
+  void                      onSelectAll( bool );
+  void                      onSelectElementFromGroup();
+  void                      onAddElement();
+  void                      onRemoveElement();
+  void                      onSetFirst();
+  void                      SetEditCurrentArgument();
+  void                      SelectionIntoArgument();
+  void                      DeactivateActiveDialog();
+  void                      ActivateThisDialog();
+  void                      onTypeChanged(int);
+};
+
+#endif // SMESHGUI_MergeDlg_H
index b877f7fc076810d2506e1031f3f9ef8df6273fd3..beafb18b2e707a0863e850109d63a18b16b5b5a2 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_MeshDlg.cxx
 // Author : Sergey LITONIN, Open CASCADE S.A.S.
@@ -112,9 +113,9 @@ SMESHGUI_MeshTab::SMESHGUI_MeshTab( QWidget* theParent )
   // Connect signals and slots
   for ( int i = MainHyp; i <= AddHyp; i++ )
   {
-    connect( myCreateHyp[ i ], SIGNAL( clicked() ), SLOT( onCreateHyp() ) );
-    connect( myEditHyp[ i ], SIGNAL( clicked() ), SLOT( onEditHyp() ) );
-    connect( myHyp[ i ], SIGNAL( activated( int ) ), SLOT( onHyp( int ) ) );
+    connect( myCreateHyp[ i ], SIGNAL( clicked() )       ,  SLOT( onCreateHyp() ) );
+    connect( myEditHyp[ i ]  , SIGNAL( clicked() )       ,  SLOT( onEditHyp() ) );
+    connect( myHyp[ i ]      , SIGNAL( activated( int ) ),  SLOT( onHyp( int ) ) );
   }
   connect( myHyp[ Algo ], SIGNAL( activated( int ) ), SLOT( onHyp( int ) ) );
   
@@ -381,7 +382,7 @@ SMESHGUI_MeshDlg::SMESHGUI_MeshDlg( const bool theToCreate, const bool theIsMesh
   myHypoSetButton->setText( tr( "HYPOTHESES_SETS" ) );
   myHypoSetButton->setEnabled( false );
   myHypoSetButton->setSizePolicy( QSizePolicy::MinimumExpanding, 
-                                 myHypoSetButton->sizePolicy().verticalPolicy() );
+                                  myHypoSetButton->sizePolicy().verticalPolicy() );
   
   // Fill layout
   QGridLayout* aLay = new QGridLayout( mainFrame() );
@@ -478,9 +479,13 @@ void SMESHGUI_MeshDlg::setMaxHypoDim( const int maxDim )
   const int DIM = maxDim;
   for ( int dim = Dim0D; dim <= Dim3D; ++dim ) {
     bool enable = ( dim <= DIM );
-    if ( !enable )
+    if ( !enable ) {
       myTabs[ dim ]->reset();
-    myTabWg->setTabEnabled( myTabWg->indexOf( myTabs[ dim ] ), enable );
+      disableTab( dim );
+    }
+    else {
+      enableTab( dim );
+    }
   }
   // deselect desabled tab
   if ( !myTabWg->isTabEnabled( myTabWg->currentIndex() ) )
@@ -542,14 +547,14 @@ void SMESHGUI_MeshDlg::setGeomPopupEnabled( const bool enable )
         myGeomPopup->addAction( tr("DIRECT_GEOM_SELECTION") )->setData( DIRECT_GEOM_INDEX );
         myGeomPopup->addAction( tr("GEOM_BY_MESH_ELEM_SELECTION") )->setData( GEOM_BY_MESH_INDEX );
         connect( myGeomPopup, SIGNAL( triggered( QAction* ) ), SLOT( onGeomPopup( QAction* ) ) );
-       connect( selBtn, SIGNAL( toggled(bool) ), this, SLOT( onGeomSelectionButton(bool) ));
+        connect( selBtn, SIGNAL( toggled(bool) ), this, SLOT( onGeomSelectionButton(bool) ));
       }
     }
     else {
       disconnect( selBtn, SIGNAL( toggled(bool) ), this, SLOT( onGeomSelectionButton(bool) ));
       if ( myGeomPopup ) {
-       delete myGeomPopup;
-       myGeomPopup = 0;
+        delete myGeomPopup;
+        myGeomPopup = 0;
       }
     }
   }
@@ -564,6 +569,7 @@ void SMESHGUI_MeshDlg::setGeomPopupEnabled( const bool enable )
 //================================================================================
 void SMESHGUI_MeshDlg::disableTab(const int theTabId) {
   myTabWg->setTabEnabled( myTabWg->indexOf( myTabs[ theTabId ] ), false );
+  if ( theTabId == Dim3D ) myHypoSetButton->setEnabled( false );
 }
 
 //================================================================================
@@ -574,6 +580,20 @@ void SMESHGUI_MeshDlg::disableTab(const int theTabId) {
 //================================================================================
 void SMESHGUI_MeshDlg::enableTab(const int theTabId) {
   myTabWg->setTabEnabled( myTabWg->indexOf( myTabs[ theTabId ] ), true );
+  if ( theTabId == Dim3D ) {
+    QMenu* aHypoSetPopup = myHypoSetButton->menu();
+    myHypoSetButton->setEnabled( aHypoSetPopup && !aHypoSetPopup->actions().isEmpty() );
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Check if tab enabled
+ * \param int - tab ID
+ */
+//================================================================================
+bool SMESHGUI_MeshDlg::isTabEnabled(const int theTabId) const {
+  return myTabWg->isTabEnabled( myTabWg->indexOf( myTabs[ theTabId ] ) );
 }
 
 void SMESHGUI_MeshDlg::onGeomSelectionButton(bool isBtnOn)
@@ -586,3 +606,12 @@ void SMESHGUI_MeshDlg::onGeomPopup( QAction* a )
 {
   emit geomSelectionByMesh( a->data().toInt() == GEOM_BY_MESH_INDEX );
 }
+
+int SMESHGUI_MeshDlg::getActiveObject()
+{
+  for (int i = 0; i < 3; ++i )
+    if ( isObjectShown( i ) &&
+         (( QToolButton* )objectWg( i, Btn ))->isChecked())
+      return i;
+  return -1;
+}
index 34ee3a565c3884f16a30de408ad683a75c87d7d5..212449ff96477d1096f73ba2bf8fcf76e6381378 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_MeshDlg.h
 // Author : Sergey LITONIN, Open CASCADE S.A.S.
@@ -71,7 +72,8 @@ public:
   void                         setGeomPopupEnabled( const bool );
   void                         disableTab(const int);
   void                         enableTab(const int);
-
+  bool                         isTabEnabled(const int) const;
+  int                          getActiveObject();
 
 signals:
   void                         hypoSet( const QString& );
index 8bed7191fe0d086a50eceffc8f83ee3b89a40371..ac71ddbc44e1231fca74c8b0f742ef99ccf5f677 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_MeshEditPreview.cxx
 // Author : Open CASCADE S.A.S.
@@ -72,6 +73,11 @@ SMESHGUI_MeshEditPreview::SMESHGUI_MeshEditPreview(SVTK_ViewWindow* theViewWindo
   myPreviewActor->VisibilityOn();
   myPreviewActor->PickableOff();
 
+  vtkFloatingPointType aFactor,aUnits;
+  myPreviewActor->SetResolveCoincidentTopology(true);
+  myPreviewActor->GetPolygonOffsetParameters(aFactor,aUnits);
+  myPreviewActor->SetPolygonOffsetParameters(aFactor,0.2*aUnits);
+
   vtkFloatingPointType anRGB[3];
   SMESH::GetColor( "SMESH", "selection_element_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 170, 255 ) );
   SetColor( anRGB[0], anRGB[1], anRGB[2] );
@@ -122,6 +128,7 @@ vtkIdType getCellType( const SMDSAbs_ElementType theType,
     else if ( theNbNodes == 4 )   return VTK_QUAD;
     else if ( theNbNodes == 6 )   return VTK_QUADRATIC_TRIANGLE;
     else if ( theNbNodes == 8 )   return VTK_QUADRATIC_QUAD;
+    else if ( theNbNodes == 9 )   return VTK_BIQUADRATIC_QUAD;
     else return VTK_EMPTY_CELL;
 
   case SMDSAbs_Volume:
@@ -130,18 +137,11 @@ vtkIdType getCellType( const SMDSAbs_ElementType theType,
     else if ( theNbNodes == 5 )   return VTK_PYRAMID;
     else if ( theNbNodes == 6 )   return VTK_WEDGE;
     else if ( theNbNodes == 8 )   return VTK_HEXAHEDRON;
-    else if ( theNbNodes == 10 )  {
-      return VTK_QUADRATIC_TETRA;
-    }
-    else if ( theNbNodes == 20 )  {
-      return VTK_QUADRATIC_HEXAHEDRON;
-    }
-    else if ( theNbNodes==15  )  {
-      return VTK_QUADRATIC_WEDGE;
-    }
-    else if ( theNbNodes==13  )  {
-      return VTK_CONVEX_POINT_SET;
-    }
+    else if ( theNbNodes == 10 )  return VTK_QUADRATIC_TETRA;
+    else if ( theNbNodes == 20 )  return VTK_QUADRATIC_HEXAHEDRON;
+    else if ( theNbNodes == 27 )  return VTK_TRIQUADRATIC_HEXAHEDRON;
+    else if ( theNbNodes == 15  ) return VTK_QUADRATIC_WEDGE;
+    else if ( theNbNodes == 13  ) return VTK_QUADRATIC_PYRAMID;//VTK_CONVEX_POINT_SET;
     else return VTK_EMPTY_CELL;
 
   default: return VTK_EMPTY_CELL;
index 1b5fb3c9a74d198cef885c03dd4dddd6dac5832c..4a0f840fe04238de36f38c22a82efe1ddfb1b53e 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_MeshEditPreview.h
 // Author : Open CASCADE S.A.S.
diff --git a/src/SMESHGUI/SMESHGUI_MeshInfo.cxx b/src/SMESHGUI/SMESHGUI_MeshInfo.cxx
new file mode 100644 (file)
index 0000000..25ee42a
--- /dev/null
@@ -0,0 +1,2175 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+//  File   : SMESHGUI_MeshInfo.cxx
+//  Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+
+#include "SMESHGUI_MeshInfo.h"
+
+#include "SMESH_Actor.h"
+#include "SMESHGUI.h"
+#include "SMESHGUI_IdValidator.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_VTKUtils.h"
+#include "SMDSAbs_ElementType.hxx"
+#include "SMDS_Mesh.hxx"
+#include "SMDS_BallElement.hxx"
+#include "SMDS_EdgePosition.hxx"
+#include "SMDS_FacePosition.hxx"
+
+#include <LightApp_SelectionMgr.h>
+#include <SUIT_OverrideCursor.h>
+#include <SUIT_ResourceMgr.h>
+#include <SVTK_ViewWindow.h>
+
+#include <SALOMEDSClient_Study.hxx>
+
+#include <QApplication>
+#include <QButtonGroup>
+#include <QGridLayout>
+#include <QHBoxLayout>
+#include <QHeaderView>
+#include <QItemDelegate>
+#include <QKeyEvent>
+#include <QLabel>
+#include <QLineEdit>
+#include <QPushButton>
+#include <QRadioButton>
+#include <QTabWidget>
+#include <QTextBrowser>
+#include <QVBoxLayout>
+
+#include "utilities.h"
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(GEOM_Gen)
+
+const int SPACING      = 6;
+const int MARGIN       = 9;
+const int MAXITEMS     = 10;
+const int GROUPS_ID    = 100;
+const int SUBMESHES_ID = 200;
+
+/*!
+  \class ExtraWidget
+  \internal
+*/
+
+class ExtraWidget : public QWidget
+{
+public:
+  ExtraWidget( QWidget*, bool = false );
+  ~ExtraWidget();
+
+  void updateControls( int, int, int = MAXITEMS );
+
+public:
+  QLabel*      current;
+  QPushButton* prev;
+  QPushButton* next;
+  bool         brief;
+};
+
+ExtraWidget::ExtraWidget( QWidget* parent, bool b ) : QWidget( parent ), brief( b )
+{
+  current = new QLabel( this );
+  current->setAlignment( Qt::AlignRight | Qt::AlignVCenter );
+  prev = new QPushButton( tr( "<<" ), this );
+  next = new QPushButton( tr( ">>" ), this );
+  QHBoxLayout* hbl = new QHBoxLayout( this );
+  hbl->setContentsMargins( 0, SPACING, 0, 0 );
+  hbl->setSpacing( SPACING );
+  hbl->addStretch();
+  hbl->addWidget( current );
+  hbl->addWidget( prev );
+  hbl->addWidget( next );
+}
+
+ExtraWidget::~ExtraWidget()
+{
+}
+
+void ExtraWidget::updateControls( int total, int index, int blockSize )
+{
+  setVisible( total > blockSize );
+  QString format = brief ? QString( "%1-%2 / %3" ) : SMESHGUI_MeshInfoDlg::tr( "X_FROM_Y_ITEMS_SHOWN" );
+  current->setText( format.arg( index*blockSize+1 ).arg( qMin( index*blockSize+blockSize, total ) ).arg( total ) );
+  prev->setEnabled( index > 0 );
+  next->setEnabled( (index+1)*blockSize < total );
+}
+
+/*!
+  \class SMESHGUI_MeshInfo
+  \brief Base mesh information widget
+  
+  Displays the base information about mesh object: mesh, sub-mesh, group or arbitrary ID source.
+*/
+
+/*!
+  \brief Constructor.
+  \param parent parent widget
+*/
+SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent )
+  : QFrame( parent ), myWidgets( iElementsEnd )
+{
+  setFrameStyle( StyledPanel | Sunken );
+
+  QGridLayout* l = new QGridLayout( this );
+  l->setMargin( MARGIN );
+  l->setSpacing( SPACING );
+
+  int index = 0;
+
+  // object
+  QLabel* aNameLab     = new QLabel( tr( "NAME_LAB" ), this );
+  QLabel* aName        = createField();
+  aName->setMinimumWidth( 150 );
+  QLabel* aObjLab      = new QLabel( tr( "OBJECT_LAB" ), this );
+  QLabel* aObj         = createField();
+  aObj->setMinimumWidth( 150 );
+  myWidgets[ index++ ] << aNameLab << aName;
+  myWidgets[ index++ ] << aObjLab  << aObj;
+
+  // nodes
+  QWidget* aNodesLine  = createLine();
+  QLabel*  aNodesLab   = new QLabel( tr( "NODES_LAB" ), this );
+  QLabel*  aNodes      = createField();
+  myWidgets[ index++ ] << aNodesLine;
+  myWidgets[ index++ ] << aNodesLab << aNodes;
+
+  // elements
+  QWidget* aElemLine   = createLine();
+  QLabel*  aElemLab    = new QLabel( tr( "ELEMENTS_LAB" ),  this );
+  QLabel*  aElemTotal  = new QLabel( tr( "TOTAL_LAB" ),     this );
+  QLabel*  aElemLin    = new QLabel( tr( "LINEAR_LAB" ),    this );
+  QLabel*  aElemQuad   = new QLabel( tr( "QUADRATIC_LAB" ), this );
+  myWidgets[ index++ ] << aElemLine;
+  myWidgets[ index++ ] << aElemLab << aElemTotal << aElemLin << aElemQuad;
+
+  // ... 0D elements
+  QWidget* a0DLine     = createLine();
+  QLabel*  a0DLab      = new QLabel( tr( "0D_LAB" ), this );
+  QLabel*  a0DTotal    = createField();
+  myWidgets[ index++ ] << a0DLine;
+  myWidgets[ index++ ] << a0DLab << a0DTotal;
+
+  // ... Ball elements
+  QWidget* aBallLine     = createLine();
+  QLabel*  aBallLab      = new QLabel( tr( "BALL_LAB" ), this );
+  QLabel*  aBallTotal    = createField();
+  myWidgets[ index++ ] << aBallLine;
+  myWidgets[ index++ ] << aBallLab << aBallTotal;
+
+  // ... 1D elements
+  QWidget* a1DLine     = createLine();
+  QLabel*  a1DLab      = new QLabel( tr( "1D_LAB" ), this );
+  QLabel*  a1DTotal    = createField();
+  QLabel*  a1DLin      = createField();
+  QLabel*  a1DQuad     = createField();
+  myWidgets[ index++ ] << a1DLine;
+  myWidgets[ index++ ] << a1DLab << a1DTotal << a1DLin << a1DQuad;
+
+  // ... 2D elements
+  QWidget* a2DLine     = createLine();
+  QLabel*  a2DLab      = new QLabel( tr( "2D_LAB" ), this );
+  QLabel*  a2DTotal    = createField();
+  QLabel*  a2DLin      = createField();
+  QLabel*  a2DQuad     = createField();
+  QLabel*  a2DTriLab   = new QLabel( tr( "TRIANGLES_LAB" ), this );
+  QLabel*  a2DTriTotal = createField();
+  QLabel*  a2DTriLin   = createField();
+  QLabel*  a2DTriQuad  = createField();
+  QLabel*  a2DQuaLab   = new QLabel( tr( "QUADRANGLES_LAB" ), this );
+  QLabel*  a2DQuaTotal = createField();
+  QLabel*  a2DQuaLin   = createField();
+  QLabel*  a2DQuaQuad  = createField();
+  QLabel*  a2DPolLab   = new QLabel( tr( "POLYGONS_LAB" ), this );
+  QLabel*  a2DPolTotal = createField();
+  myWidgets[ index++ ] << a2DLine;
+  myWidgets[ index++ ] << a2DLab    << a2DTotal    << a2DLin    << a2DQuad;
+  myWidgets[ index++ ] << a2DTriLab << a2DTriTotal << a2DTriLin << a2DTriQuad;
+  myWidgets[ index++ ] << a2DQuaLab << a2DQuaTotal << a2DQuaLin << a2DQuaQuad;
+  myWidgets[ index++ ] << a2DPolLab << a2DPolTotal;
+
+  // ... 3D elements
+  QWidget* a3DLine     = createLine();
+  QLabel*  a3DLab      = new QLabel( tr( "3D_LAB" ), this );
+  QLabel*  a3DTotal    = createField();
+  QLabel*  a3DLin      = createField();
+  QLabel*  a3DQuad     = createField();
+  QLabel*  a3DTetLab   = new QLabel( tr( "TETRAHEDRONS_LAB" ), this );
+  QLabel*  a3DTetTotal = createField();
+  QLabel*  a3DTetLin   = createField();
+  QLabel*  a3DTetQuad  = createField();
+  QLabel*  a3DHexLab   = new QLabel( tr( "HEXAHEDONRS_LAB" ), this );
+  QLabel*  a3DHexTotal = createField();
+  QLabel*  a3DHexLin   = createField();
+  QLabel*  a3DHexQuad  = createField();
+  QLabel*  a3DPyrLab   = new QLabel( tr( "PYRAMIDS_LAB" ), this );
+  QLabel*  a3DPyrTotal = createField();
+  QLabel*  a3DPyrLin   = createField();
+  QLabel*  a3DPyrQuad  = createField();
+  QLabel*  a3DPriLab   = new QLabel( tr( "PRISMS_LAB" ), this );
+  QLabel*  a3DPriTotal = createField();
+  QLabel*  a3DPriLin   = createField();
+  QLabel*  a3DPriQuad  = createField();
+  QLabel*  a3DHexPriLab   = new QLabel( tr( "HEX_PRISMS_LAB" ), this );
+  QLabel*  a3DHexPriTotal = createField();
+  QLabel*  a3DPolLab   = new QLabel( tr( "POLYHEDRONS_LAB" ), this );
+  QLabel*  a3DPolTotal = createField();
+  myWidgets[ index++ ] << a3DLine;
+  myWidgets[ index++ ] << a3DLab    << a3DTotal    << a3DLin    << a3DQuad;
+  myWidgets[ index++ ] << a3DTetLab << a3DTetTotal << a3DTetLin << a3DTetQuad;
+  myWidgets[ index++ ] << a3DHexLab << a3DHexTotal << a3DHexLin << a3DHexQuad;
+  myWidgets[ index++ ] << a3DPyrLab << a3DPyrTotal << a3DPyrLin << a3DPyrQuad;
+  myWidgets[ index++ ] << a3DPriLab << a3DPriTotal << a3DPriLin << a3DPriQuad;
+  myWidgets[ index++ ] << a3DHexPriLab << a3DHexPriTotal;
+  myWidgets[ index++ ] << a3DPolLab << a3DPolTotal;
+
+  myLoadBtn = new QPushButton( tr( "BUT_LOAD_MESH" ), this );
+  myLoadBtn->setAutoDefault( true );
+  connect( myLoadBtn, SIGNAL( clicked() ), this, SLOT( loadMesh() ) );
+  
+  setFontAttributes( aNameLab,   Bold );
+  setFontAttributes( aObjLab,    Bold );
+  setFontAttributes( aNodesLab,  Bold );
+  setFontAttributes( aElemLab,   Bold );
+  setFontAttributes( aElemTotal, Italic );
+  setFontAttributes( aElemLin,   Italic );
+  setFontAttributes( aElemQuad,  Italic );
+  setFontAttributes( a0DLab,     Bold );
+  setFontAttributes( aBallLab,     Bold );
+  setFontAttributes( a1DLab,     Bold );
+  setFontAttributes( a2DLab,     Bold );
+  setFontAttributes( a3DLab,     Bold );
+
+  l->addWidget( aNameLab,     0, 0 );
+  l->addWidget( aName,        0, 1, 1, 3 );
+  l->addWidget( aObjLab,      1, 0 );
+  l->addWidget( aObj,         1, 1, 1, 3 );
+  l->addWidget( aNodesLine,   2, 0, 1, 4 );
+  l->addWidget( aNodesLab,    3, 0 );
+  l->addWidget( aNodes,       3, 1 );
+  l->addWidget( aElemLine,    4, 0, 1, 4 );
+  l->addWidget( aElemLab,     5, 0 );
+  l->addWidget( aElemTotal,   5, 1 );
+  l->addWidget( aElemLin,     5, 2 );
+  l->addWidget( aElemQuad,    5, 3 );
+  l->addWidget( a0DLine,      6, 1, 1, 3 );
+  l->addWidget( a0DLab,       7, 0 );
+  l->addWidget( a0DTotal,     7, 1 );
+  l->addWidget( aBallLine,    8, 1, 1, 3 );
+  l->addWidget( aBallLab,     9, 0 );
+  l->addWidget( aBallTotal,   9, 1 );
+  l->addWidget( a1DLine,      10, 1, 1, 3 );
+  l->addWidget( a1DLab,       11, 0 );
+  l->addWidget( a1DTotal,     11, 1 );
+  l->addWidget( a1DLin,       11, 2 );
+  l->addWidget( a1DQuad,      11, 3 );
+  l->addWidget( a2DLine,     12, 1, 1, 3 );
+  l->addWidget( a2DLab,      13, 0 );
+  l->addWidget( a2DTotal,    13, 1 );
+  l->addWidget( a2DLin,      13, 2 );
+  l->addWidget( a2DQuad,     13, 3 );
+  l->addWidget( a2DTriLab,   14, 0 );
+  l->addWidget( a2DTriTotal, 14, 1 );
+  l->addWidget( a2DTriLin,   14, 2 );
+  l->addWidget( a2DTriQuad,  14, 3 );
+  l->addWidget( a2DQuaLab,   15, 0 );
+  l->addWidget( a2DQuaTotal, 15, 1 );
+  l->addWidget( a2DQuaLin,   15, 2 );
+  l->addWidget( a2DQuaQuad,  15, 3 );
+  l->addWidget( a2DPolLab,   16, 0 );
+  l->addWidget( a2DPolTotal, 16, 1 );
+  l->addWidget( a3DLine,     17, 1, 1, 3 );
+  l->addWidget( a3DLab,      18, 0 );
+  l->addWidget( a3DTotal,    18, 1 );
+  l->addWidget( a3DLin,      18, 2 );
+  l->addWidget( a3DQuad,     18, 3 );
+  l->addWidget( a3DTetLab,   19, 0 );
+  l->addWidget( a3DTetTotal, 19, 1 );
+  l->addWidget( a3DTetLin,   19, 2 );
+  l->addWidget( a3DTetQuad,  19, 3 );
+  l->addWidget( a3DHexLab,   20, 0 );
+  l->addWidget( a3DHexTotal, 20, 1 );
+  l->addWidget( a3DHexLin,   20, 2 );
+  l->addWidget( a3DHexQuad,  20, 3 );
+  l->addWidget( a3DPyrLab,   21, 0 );
+  l->addWidget( a3DPyrTotal, 21, 1 );
+  l->addWidget( a3DPyrLin,   21, 2 );
+  l->addWidget( a3DPyrQuad,  21, 3 );
+  l->addWidget( a3DPriLab,   22, 0 );
+  l->addWidget( a3DPriTotal, 22, 1 );
+  l->addWidget( a3DPriLin,   22, 2 );
+  l->addWidget( a3DPriQuad,  22, 3 );
+  l->addWidget( a3DHexPriLab,   23, 0 );
+  l->addWidget( a3DHexPriTotal, 23, 1 );
+  l->addWidget( a3DPolLab,   24, 0 );
+  l->addWidget( a3DPolTotal, 24, 1 );
+  l->addWidget( myLoadBtn,   25, 1, 1, 3 );
+  l->setColumnStretch( 0, 0 );
+  l->setColumnStretch( 1, 5 );
+  l->setColumnStretch( 2, 5 );
+  l->setColumnStretch( 3, 5 );
+  l->setRowStretch( 23, 5 );
+
+  clear();
+}
+
+/*!
+  \brief Destructor
+*/
+SMESHGUI_MeshInfo::~SMESHGUI_MeshInfo()
+{
+}
+
+/*!
+  \brief Show information on the mesh object.
+  \param obj object being processed (mesh, sub-mesh, group, ID source)
+*/
+void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
+{
+  clear();
+  if ( !CORBA::is_nil( obj ) ) {
+    _PTR(SObject) sobj = SMESH::ObjectToSObject( obj );
+    if ( sobj ) 
+      myWidgets[iName][iSingle]->setProperty( "text", sobj->GetName().c_str() );
+    SMESH::SMESH_Mesh_var      aMesh    = SMESH::SMESH_Mesh::_narrow( obj );
+    SMESH::SMESH_subMesh_var   aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
+    SMESH::SMESH_GroupBase_var aGroup   = SMESH::SMESH_GroupBase::_narrow( obj );
+    if ( !aMesh->_is_nil() ) {
+      myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_MESH" ) );
+    }
+    else if ( !aSubMesh->_is_nil() ) {
+      myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_SUBMESH" ) );
+    }
+    else if ( !aGroup->_is_nil() ) {
+      QString objType;
+      switch( aGroup->GetType() ) {
+      case SMESH::NODE:
+        objType = tr( "OBJECT_GROUP_NODES" );
+        break;
+      case SMESH::EDGE:
+        objType = tr( "OBJECT_GROUP_EDGES" );
+        break;
+      case SMESH::FACE:
+        objType = tr( "OBJECT_GROUP_FACES" );
+        break;
+      case SMESH::VOLUME:
+        objType = tr( "OBJECT_GROUP_VOLUMES" );
+        break;
+      case SMESH::ELEM0D:
+        objType = tr( "OBJECT_GROUP_0DELEMS" );
+        break;
+      case SMESH::BALL:
+        objType = tr( "OBJECT_GROUP_BALLS" );
+        break;
+      default:
+        objType = tr( "OBJECT_GROUP" );
+        break;
+      }
+      myWidgets[iObject][iSingle]->setProperty( "text", objType );
+    }
+    SMESH::long_array_var info = obj->GetMeshInfo();
+    myWidgets[iNodes][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Node] ) );
+    myWidgets[i0D][iTotal]    ->setProperty( "text", QString::number( info[SMDSEntity_0D] ) );
+    myWidgets[iBalls][iTotal] ->setProperty( "text", QString::number( info[SMDSEntity_Ball] ) );
+    long nbEdges = info[SMDSEntity_Edge] + info[SMDSEntity_Quad_Edge];
+    myWidgets[i1D][iTotal]    ->setProperty( "text", QString::number( nbEdges ) );
+    myWidgets[i1D][iLinear]   ->setProperty( "text", QString::number( info[SMDSEntity_Edge] ) );
+    myWidgets[i1D][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Edge] ) );
+    long nbTriangles   = info[SMDSEntity_Triangle]   + info[SMDSEntity_Quad_Triangle];
+    long nbQuadrangles = info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle];
+    long nb2DLinear    = info[SMDSEntity_Triangle] + info[SMDSEntity_Quadrangle] + info[SMDSEntity_Polygon];
+    long nb2DQuadratic = info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle];
+    myWidgets[i2D][iTotal]               ->setProperty( "text", QString::number( nb2DLinear + nb2DQuadratic ) );
+    myWidgets[i2D][iLinear]              ->setProperty( "text", QString::number( nb2DLinear ) );
+    myWidgets[i2D][iQuadratic]           ->setProperty( "text", QString::number( nb2DQuadratic ) );
+    myWidgets[i2DTriangles][iTotal]      ->setProperty( "text", QString::number( nbTriangles ) );
+    myWidgets[i2DTriangles][iLinear]     ->setProperty( "text", QString::number( info[SMDSEntity_Triangle] ) );
+    myWidgets[i2DTriangles][iQuadratic]  ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Triangle] ) );
+    myWidgets[i2DQuadrangles][iTotal]    ->setProperty( "text", QString::number( nbQuadrangles ) );
+    myWidgets[i2DQuadrangles][iLinear]   ->setProperty( "text", QString::number( info[SMDSEntity_Quadrangle] ) );
+    myWidgets[i2DQuadrangles][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Quadrangle] + info[SMDSEntity_BiQuad_Quadrangle] ));
+    myWidgets[i2DPolygons][iTotal]       ->setProperty( "text", QString::number( info[SMDSEntity_Polygon] ) );
+    long nbTetrahedrons = info[SMDSEntity_Tetra]   + info[SMDSEntity_Quad_Tetra];
+    long nbHexahedrons  = info[SMDSEntity_Hexa]    + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa];
+    long nbPyramids     = info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid];
+    long nbPrisms       = info[SMDSEntity_Penta]   + info[SMDSEntity_Quad_Penta];
+    long nb3DLinear     = info[SMDSEntity_Tetra] + info[SMDSEntity_Hexa] + info[SMDSEntity_Pyramid] + info[SMDSEntity_Penta] + info[SMDSEntity_Polyhedra] + info[SMDSEntity_Hexagonal_Prism];
+    long nb3DQuadratic  = info[SMDSEntity_Quad_Tetra] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa] + info[SMDSEntity_Quad_Pyramid] + info[SMDSEntity_Quad_Penta];
+    myWidgets[i3D][iTotal]                ->setProperty( "text", QString::number( nb3DLinear + nb3DQuadratic ) );
+    myWidgets[i3D][iLinear]               ->setProperty( "text", QString::number( nb3DLinear ) );
+    myWidgets[i3D][iQuadratic]            ->setProperty( "text", QString::number( nb3DQuadratic ) );
+    myWidgets[i3DTetrahedrons][iTotal]    ->setProperty( "text", QString::number( nbTetrahedrons ) );
+    myWidgets[i3DTetrahedrons][iLinear]   ->setProperty( "text", QString::number( info[SMDSEntity_Tetra] ) );
+    myWidgets[i3DTetrahedrons][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Tetra] ) );
+    myWidgets[i3DHexahedrons][iTotal]     ->setProperty( "text", QString::number( nbHexahedrons ) );
+    myWidgets[i3DHexahedrons][iLinear]    ->setProperty( "text", QString::number( info[SMDSEntity_Hexa] ) );
+    myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_TriQuad_Hexa] ) );
+    myWidgets[i3DPyramids][iTotal]        ->setProperty( "text", QString::number( nbPyramids ) );
+    myWidgets[i3DPyramids][iLinear]       ->setProperty( "text", QString::number( info[SMDSEntity_Pyramid] ) );
+    myWidgets[i3DPyramids][iQuadratic]    ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Pyramid] ) );
+    myWidgets[i3DPrisms][iTotal]          ->setProperty( "text", QString::number( nbPrisms ) );
+    myWidgets[i3DPrisms][iLinear]         ->setProperty( "text", QString::number( info[SMDSEntity_Penta] ) );
+    myWidgets[i3DPrisms][iQuadratic]      ->setProperty( "text", QString::number( info[SMDSEntity_Quad_Penta] ) );
+    myWidgets[i3DHexaPrisms][iTotal]      ->setProperty( "text", QString::number( info[SMDSEntity_Hexagonal_Prism] ) );
+    myWidgets[i3DPolyhedrons][iTotal]     ->setProperty( "text", QString::number( info[SMDSEntity_Polyhedra] ) );
+
+    // before full loading from study file, type of elements in a sub-mesh can't be defined
+    // in some cases
+    bool infoOK = obj->IsMeshInfoCorrect();
+    myLoadBtn->setVisible( !infoOK );
+    if ( !infoOK )
+    {
+      // two options:
+      // 1. Type of 2D or 3D elements is unknown but their nb is OK (for a sub-mesh)
+      // 2. No info at all (for a group on geom or filter)
+      bool hasAnyInfo = false;
+      for ( size_t i = 0; i < info->length() && !hasAnyInfo; ++i )
+        hasAnyInfo = info[i];
+      if ( hasAnyInfo ) // believe it is a sub-mesh
+      {
+        if ( nb2DLinear + nb2DQuadratic > 0 )
+        {
+          myWidgets[i2D][iLinear]              ->setProperty( "text", "?" );
+          myWidgets[i2D][iQuadratic]           ->setProperty( "text", "?" );
+          myWidgets[i2DTriangles][iTotal]      ->setProperty( "text", "?" );
+          myWidgets[i2DTriangles][iLinear]     ->setProperty( "text", "?" );
+          myWidgets[i2DTriangles][iQuadratic]  ->setProperty( "text", "?" );
+          myWidgets[i2DQuadrangles][iTotal]    ->setProperty( "text", "?" );
+          myWidgets[i2DQuadrangles][iLinear]   ->setProperty( "text", "?" );
+          myWidgets[i2DQuadrangles][iQuadratic]->setProperty( "text", "?" );
+          myWidgets[i2DPolygons][iTotal]       ->setProperty( "text", "?" );
+        }
+        else if ( nb3DLinear + nb3DQuadratic > 0 )
+        {
+          myWidgets[i3D][iLinear]               ->setProperty( "text", "?" );
+          myWidgets[i3D][iQuadratic]            ->setProperty( "text", "?" );
+          myWidgets[i3DTetrahedrons][iTotal]    ->setProperty( "text", "?" );
+          myWidgets[i3DTetrahedrons][iLinear]   ->setProperty( "text", "?" );
+          myWidgets[i3DTetrahedrons][iQuadratic]->setProperty( "text", "?" );
+          myWidgets[i3DHexahedrons][iTotal]     ->setProperty( "text", "?" );
+          myWidgets[i3DHexahedrons][iLinear]    ->setProperty( "text", "?" );
+          myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" );
+          myWidgets[i3DPyramids][iTotal]        ->setProperty( "text", "?" );
+          myWidgets[i3DPyramids][iLinear]       ->setProperty( "text", "?" );
+          myWidgets[i3DPyramids][iQuadratic]    ->setProperty( "text", "?" );
+          myWidgets[i3DPrisms][iTotal]          ->setProperty( "text", "?" );
+          myWidgets[i3DPrisms][iLinear]         ->setProperty( "text", "?" );
+          myWidgets[i3DPrisms][iQuadratic]      ->setProperty( "text", "?" );
+          myWidgets[i3DHexaPrisms][iTotal]      ->setProperty( "text", "?" );
+          myWidgets[i3DPolyhedrons][iTotal]     ->setProperty( "text", "?" );
+        }
+      }
+      else
+      {
+        myWidgets[iNodes][iTotal]             ->setProperty( "text", "?" );
+        myWidgets[i0D][iTotal]                ->setProperty( "text", "?" );
+        myWidgets[iBalls][iTotal]             ->setProperty( "text", "?" );
+        myWidgets[i1D][iTotal]                ->setProperty( "text", "?" );
+        myWidgets[i1D][iLinear]               ->setProperty( "text", "?" );
+        myWidgets[i1D][iQuadratic]            ->setProperty( "text", "?" );
+        myWidgets[i2D][iTotal]                ->setProperty( "text", "?" );
+        myWidgets[i2D][iLinear]               ->setProperty( "text", "?" );
+        myWidgets[i2D][iQuadratic]            ->setProperty( "text", "?" );
+        myWidgets[i2DTriangles][iTotal]       ->setProperty( "text", "?" );
+        myWidgets[i2DTriangles][iLinear]      ->setProperty( "text", "?" );
+        myWidgets[i2DTriangles][iQuadratic]   ->setProperty( "text", "?" );
+        myWidgets[i2DQuadrangles][iTotal]     ->setProperty( "text", "?" );
+        myWidgets[i2DQuadrangles][iLinear]    ->setProperty( "text", "?" );
+        myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", "?" );
+        myWidgets[i2DPolygons][iTotal]        ->setProperty( "text", "?" );
+        myWidgets[i3D][iTotal]                ->setProperty( "text", "?" );
+        myWidgets[i3D][iLinear]               ->setProperty( "text", "?" );
+        myWidgets[i3D][iQuadratic]            ->setProperty( "text", "?" );
+        myWidgets[i3DTetrahedrons][iTotal]    ->setProperty( "text", "?" );
+        myWidgets[i3DTetrahedrons][iLinear]   ->setProperty( "text", "?" );
+        myWidgets[i3DTetrahedrons][iQuadratic]->setProperty( "text", "?" );
+        myWidgets[i3DHexahedrons][iTotal]     ->setProperty( "text", "?" );
+        myWidgets[i3DHexahedrons][iLinear]    ->setProperty( "text", "?" );
+        myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", "?" );
+        myWidgets[i3DPyramids][iTotal]        ->setProperty( "text", "?" );
+        myWidgets[i3DPyramids][iLinear]       ->setProperty( "text", "?" );
+        myWidgets[i3DPyramids][iQuadratic]    ->setProperty( "text", "?" );
+        myWidgets[i3DPrisms][iTotal]          ->setProperty( "text", "?" );
+        myWidgets[i3DPrisms][iLinear]         ->setProperty( "text", "?" );
+        myWidgets[i3DPrisms][iQuadratic]      ->setProperty( "text", "?" );
+        myWidgets[i3DHexaPrisms][iTotal]      ->setProperty( "text", "?" );
+        myWidgets[i3DPolyhedrons][iTotal]     ->setProperty( "text", "?" );
+      }
+    }
+  }
+}
+
+/*!
+  \brief Load mesh from a study file
+*/
+void SMESHGUI_MeshInfo::loadMesh()
+{
+  SUIT_OverrideCursor wc;
+
+  SALOME_ListIO selected;
+  SMESHGUI::selectionMgr()->selectedObjects( selected );
+
+  if ( selected.Extent() == 1 ) {
+    Handle(SALOME_InteractiveObject) IO = selected.First();
+    SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
+    if ( !CORBA::is_nil( obj ) ) {
+      SMESH::SMESH_Mesh_var mesh = obj->GetMesh();
+      if ( !mesh->_is_nil() )
+      {
+        mesh->Load();
+        showInfo( obj );
+      }
+    }
+  }
+}
+
+/*!
+  \brief Reset the widget to the initial state (nullify all fields).
+*/
+void SMESHGUI_MeshInfo::clear()
+{
+  myWidgets[iName][iSingle]             ->setProperty( "text", QString() );
+  myWidgets[iObject][iSingle]           ->setProperty( "text", QString() );
+  myWidgets[iNodes][iTotal]             ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i0D][iTotal]                ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[iBalls][iTotal]             ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i1D][iTotal]                ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i1D][iLinear]               ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i1D][iQuadratic]            ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i2D][iTotal]                ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i2D][iLinear]               ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i2D][iQuadratic]            ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i2DTriangles][iTotal]       ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i2DTriangles][iLinear]      ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i2DTriangles][iQuadratic]   ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i2DQuadrangles][iTotal]     ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i2DQuadrangles][iLinear]    ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i2DQuadrangles][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i2DPolygons][iTotal]        ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3D][iTotal]                ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3D][iLinear]               ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3D][iQuadratic]            ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3DTetrahedrons][iTotal]    ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3DTetrahedrons][iLinear]   ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3DTetrahedrons][iQuadratic]->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3DHexahedrons][iTotal]     ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3DHexahedrons][iLinear]    ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3DHexahedrons][iQuadratic] ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3DPyramids][iTotal]        ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3DPyramids][iLinear]       ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3DPyramids][iQuadratic]    ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3DPrisms][iTotal]          ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3DPrisms][iLinear]         ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3DPrisms][iQuadratic]      ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3DHexaPrisms][iTotal]      ->setProperty( "text", QString::number( 0 ) );
+  myWidgets[i3DPolyhedrons][iTotal]     ->setProperty( "text", QString::number( 0 ) );
+}
+
+/*!
+  \brief Create info field
+  \return new info field
+*/
+QLabel* SMESHGUI_MeshInfo::createField()
+{
+  QLabel* lab = new QLabel( this );
+  lab->setFrameStyle( StyledPanel | Sunken );
+  lab->setAlignment( Qt::AlignCenter );
+  lab->setAutoFillBackground( true );
+  QPalette pal = lab->palette();
+  pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ) );
+  lab->setPalette( pal );
+  lab->setMinimumWidth( 70 );
+  return lab;
+}
+
+/*!
+  \brief Create horizontal rule.
+  \return new line object
+*/
+QWidget* SMESHGUI_MeshInfo::createLine()
+{
+  QFrame* line = new QFrame( this );
+  line->setFrameStyle( HLine | Sunken );
+  return line;
+}
+
+/*!
+  \brief Change widget font attributes (bold, italic, ...).
+  \param w widget
+  \param attr font attributes (XORed flags)
+  \param val value to be set to attributes
+*/
+void SMESHGUI_MeshInfo::setFontAttributes( QWidget* w, int attr, bool val )
+{
+  if ( w && attr ) {
+    QFont f = w->font();
+    if ( attr & Bold   ) f.setBold( val );
+    if ( attr & Italic ) f.setItalic( val );
+    w->setFont( f );
+  }
+}
+
+/*!
+  \brief Show/hide group(s) of fields.
+  \param start beginning of the block
+  \param end end of the block
+  \param on visibility flag
+*/
+void SMESHGUI_MeshInfo::setFieldsVisible( int start, int end, bool on )
+{
+  start = qMax( 0, start );
+  end   = qMin( end, (int)iElementsEnd );
+  for ( int i = start; i < end; i++ ) {
+    wlist wl = myWidgets[i];
+    foreach ( QWidget* w, wl ) w->setVisible( on );
+  }
+}
+
+/*!
+  \class SMESHGUI_ElemInfo
+  \brief Base class for the mesh element information widget.
+*/
+
+/*!
+  \brief Constructor
+  \param parent parent widget
+*/
+SMESHGUI_ElemInfo::SMESHGUI_ElemInfo( QWidget* parent )
+: QWidget( parent ), myActor( 0 ), myIsElement( -1 )
+{
+  myFrame = new QWidget( this );
+  myExtra = new ExtraWidget( this );
+  QVBoxLayout* vbl = new QVBoxLayout( this );
+  vbl->setMargin( 0 );
+  vbl->setSpacing( 0 );
+  vbl->addWidget( myFrame );
+  vbl->addWidget( myExtra );
+  connect( myExtra->prev, SIGNAL( clicked() ), this, SLOT( showPrevious() ) );
+  connect( myExtra->next, SIGNAL( clicked() ), this, SLOT( showNext() ) );
+  clear();
+}
+
+/*!
+  \brief Destructor
+*/
+SMESHGUI_ElemInfo::~SMESHGUI_ElemInfo()
+{
+}
+
+/*!
+  \brief Set mesh data source (actor)
+  \param actor mesh object actor
+*/
+void SMESHGUI_ElemInfo::setSource( SMESH_Actor* actor )
+{
+  if ( myActor != actor ) {
+    myActor = actor;
+    myIsElement = -1;
+    clear();
+  }
+}
+
+/*!
+  \brief Show mesh element information
+  \param id mesh node / element ID
+  \param isElem show mesh element information if \c true or mesh node information if \c false
+*/
+void SMESHGUI_ElemInfo::showInfo( long id, bool isElem )
+{
+  QSet<long> ids;
+  ids << id;
+  showInfo( ids, isElem );
+}
+
+/*!
+  \brief Show mesh element information
+  \param ids mesh nodes / elements identifiers
+  \param isElem show mesh element information if \c true or mesh node information if \c false
+*/
+void SMESHGUI_ElemInfo::showInfo( QSet<long> ids, bool isElem )
+{
+  QList<long> newIds = ids.toList();
+  qSort( newIds );
+  if ( myIDs == newIds && myIsElement == isElem ) return;
+
+  myIDs = newIds;
+  myIsElement = isElem;
+  myIndex = 0;
+  updateControls();
+  information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
+}
+
+/*!
+  \brief Clear mesh element information widget
+*/
+void SMESHGUI_ElemInfo::clear()
+{
+  myIDs.clear();
+  myIndex = 0;
+  clearInternal();
+  updateControls();
+}
+
+/*!
+  \brief Get central area widget
+  \return central widget
+*/
+QWidget* SMESHGUI_ElemInfo::frame() const
+{
+  return myFrame;
+}
+
+/*!
+  \brief Get actor
+  \return actor being used
+*/
+SMESH_Actor* SMESHGUI_ElemInfo::actor() const
+{
+  return myActor;
+}
+
+/*!
+  \brief Get current info mode.
+  \return \c true if mesh element information is shown or \c false if node information is shown
+*/
+bool SMESHGUI_ElemInfo::isElements() const
+{
+  return myIsElement;
+}
+
+/*!
+  \fn void SMESHGUI_ElemInfo::information( const QList<long>& ids )
+  \brief Show information on the specified nodes / elements
+
+  This function is to be redefined in sub-classes.
+
+  \param ids nodes / elements identifiers information is to be shown on
+*/
+
+/*!
+  \brief Internal clean-up (reset widget)
+*/
+void SMESHGUI_ElemInfo::clearInternal()
+{
+}
+
+/*!
+  \brief Get node connectivity
+  \param node mesh node
+  \return node connectivity map
+*/
+SMESHGUI_ElemInfo::Connectivity SMESHGUI_ElemInfo::nodeConnectivity( const SMDS_MeshNode* node )
+{
+  Connectivity elmap;
+  if ( node ) {
+    SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
+    while ( it && it->more() ) {
+      const SMDS_MeshElement* ne = it->next();
+      elmap[ ne->GetType() ] << ne->GetID();
+    }
+  }
+  return elmap;
+}
+
+/*!
+  \brief Format connectivity data to string representation
+  \param connectivity connetivity map
+  \param type element type
+  \return string representation of the connectivity
+*/
+QString SMESHGUI_ElemInfo::formatConnectivity( Connectivity connectivity, int type )
+{
+  QStringList str;
+  if ( connectivity.contains( type ) ) {
+    QList<int> elements = connectivity[ type ];
+    qSort( elements );
+    foreach( int id, elements )
+      str << QString::number( id );
+  }
+  return str.join( " " );
+}
+
+/*!
+  \brief Calculate gravity center of the mesh element
+  \param element mesh element
+*/
+SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::gravityCenter( const SMDS_MeshElement* element )
+{
+  XYZ xyz;
+  if ( element ) {
+    SMDS_ElemIteratorPtr nodeIt = element->nodesIterator();
+    while ( nodeIt->more() ) {
+      const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+      xyz.add( node->X(), node->Y(), node->Z() );
+    }
+    xyz.divide( element->NbNodes() );
+  }
+  return xyz;
+}
+
+/*!
+  \brief This slot is called from "Show Previous" button click.
+  Shows information on the previous group of the items.
+*/
+void SMESHGUI_ElemInfo::showPrevious()
+{
+  myIndex = qMax( 0, myIndex-1 );
+  updateControls();
+  information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
+}
+
+/*!
+  \brief This slot is called from "Show Next" button click.
+  Shows information on the next group of the items.
+*/
+void SMESHGUI_ElemInfo::showNext()
+{
+  myIndex = qMin( myIndex+1, myIDs.count() / MAXITEMS );
+  updateControls();
+  information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
+}
+
+/*!
+  \brief Update widgets state
+*/
+void SMESHGUI_ElemInfo::updateControls()
+{
+  myExtra->updateControls( myIDs.count(), myIndex );
+}
+
+/*!
+  \class SMESHGUI_SimpleElemInfo
+  \brief Represents mesh element information in the simple text area.
+*/
+
+/*!
+  \brief Constructor
+  \param parent parent widget
+*/
+SMESHGUI_SimpleElemInfo::SMESHGUI_SimpleElemInfo( QWidget* parent )
+: SMESHGUI_ElemInfo( parent )
+{
+  myInfo = new QTextBrowser( frame() );
+  QVBoxLayout* l = new QVBoxLayout( frame() );
+  l->setMargin( 0 );
+  l->addWidget( myInfo );
+}
+
+/*!
+  \brief Show mesh element information
+  \param ids mesh nodes / elements identifiers
+*/
+void SMESHGUI_SimpleElemInfo::information( const QList<long>& ids )
+{
+  clearInternal();
+  
+  if ( actor() ) {
+    int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
+    foreach ( long id, ids ) {
+      if ( !isElements() ) {
+        //
+        // show node info
+        //
+        const SMDS_MeshNode* node = actor()->GetObject()->GetMesh()->FindNode( id );
+        if ( !node ) return;
+
+        // node ID
+        myInfo->append( QString( "<b>%1 #%2</b>" ).arg( tr( "NODE" ) ).arg( id ) );
+        // separator
+        myInfo->append( "" );
+        // coordinates
+        myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( tr( "COORDINATES" ) ).
+                        arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
+                        arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
+                        arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+        // separator
+        myInfo->append( "" );
+        // connectivity
+        Connectivity connectivity = nodeConnectivity( node );
+        if ( !connectivity.isEmpty() ) {
+          myInfo->append( QString( "<b>%1:</b>" ).arg( tr( "CONNECTIVITY" ) ) );
+          QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
+          if ( !con.isEmpty() )
+            myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "0D_ELEMENTS" ) ).arg( con ) );
+          con = formatConnectivity( connectivity, SMDSAbs_Edge );
+          if ( !con.isEmpty() )
+            myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "EDGES" ) ).arg( con ) );
+          con = formatConnectivity( connectivity, SMDSAbs_Ball );
+          if ( !con.isEmpty() )
+            myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "BALL_ELEMENTS" ) ).arg( con ) );
+          con = formatConnectivity( connectivity, SMDSAbs_Face );
+          if ( !con.isEmpty() )
+            myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "FACES" ) ).arg( con ) );
+          con = formatConnectivity( connectivity, SMDSAbs_Volume );
+          if ( !con.isEmpty() )
+            myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "VOLUMES" ) ).arg( con ) );
+        }
+        else {
+          myInfo->append( QString( "<b>%1</b>" ).arg( tr( "FREE_NODE" ) ).arg( id ) );
+        }
+      }
+      else {
+        //
+        // show element info
+        // 
+        const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id );
+        if ( !e ) return;
+        
+        // element ID && type
+        QString stype;
+        switch( e->GetType() ) {
+        case SMDSAbs_0DElement:
+          stype = tr( "0D ELEMENT" ); break;
+        case SMDSAbs_Ball:
+          stype = tr( "BALL" ); break;
+        case SMDSAbs_Edge:
+          stype = tr( "EDGE" ); break;
+        case SMDSAbs_Face:
+          stype = tr( "FACE" ); break;
+        case SMDSAbs_Volume:
+          stype = tr( "VOLUME" ); break;
+        default: 
+          break;
+        }
+        if ( stype.isEmpty() ) return;
+        myInfo->append( QString( "<b>%1 #%2</b>" ).arg( stype ).arg( id ) );
+        // separator
+        myInfo->append( "" );
+        // geometry type
+        QString gtype;
+        switch( e->GetEntityType() ) {
+        case SMDSEntity_Triangle:
+        case SMDSEntity_Quad_Triangle:
+          gtype = tr( "TRIANGLE" ); break;
+        case SMDSEntity_Quadrangle:
+        case SMDSEntity_Quad_Quadrangle:
+        case SMDSEntity_BiQuad_Quadrangle:
+          gtype = tr( "QUADRANGLE" ); break;
+        case SMDSEntity_Polygon:
+        case SMDSEntity_Quad_Polygon:
+          gtype = tr( "POLYGON" ); break;
+        case SMDSEntity_Tetra:
+        case SMDSEntity_Quad_Tetra:
+          gtype = tr( "TETRAHEDRON" ); break;
+        case SMDSEntity_Pyramid:
+        case SMDSEntity_Quad_Pyramid:
+          gtype = tr( "PYRAMID" ); break;
+        case SMDSEntity_Hexa:
+        case SMDSEntity_Quad_Hexa:
+        case SMDSEntity_TriQuad_Hexa:
+          gtype = tr( "HEXAHEDRON" ); break;
+        case SMDSEntity_Penta:
+        case SMDSEntity_Quad_Penta:
+          gtype = tr( "PRISM" ); break;
+        case SMDSEntity_Hexagonal_Prism:
+          gtype = tr( "HEX_PRISM" ); break;
+        case SMDSEntity_Polyhedra:
+        case SMDSEntity_Quad_Polyhedra:
+          gtype = tr( "POLYHEDRON" ); break;
+        default: 
+          break;
+        }
+        if ( !gtype.isEmpty() )
+          myInfo->append( QString( "<b>%1:</b> %2" ).arg( tr( "TYPE" ) ).arg( gtype ) );
+        // quadratic flag and gravity center (any element except 0D)
+        if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Ball ) {
+          // quadratic flag
+          myInfo->append( QString( "<b>%1?</b> %2" ).arg( tr( "QUADRATIC" ) ).arg( e->IsQuadratic() ? tr( "YES" ) : tr( "NO" ) ) );
+          // separator
+          myInfo->append( "" );
+          // gravity center
+          XYZ gc = gravityCenter( e );
+          myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( tr( "GRAVITY_CENTER" ) ).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ) );
+        }
+        if ( const SMDS_BallElement* ball = dynamic_cast<const SMDS_BallElement*>( e )) {
+          // ball diameter
+          myInfo->append( QString( "<b>%1:</b> %2" ).arg( tr( "BALL_DIAMETER" ) ).arg( ball->GetDiameter() ));
+        }
+        // separator
+        myInfo->append( "" );
+        // connectivity
+        SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
+        for ( int idx = 1; nodeIt->more(); idx++ ) {
+          const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+          // node number and ID
+          myInfo->append( QString( "<b>%1 %2/%3</b> - #%4" ).arg( tr( "NODE" ) ).arg( idx ).arg( e->NbNodes() ).arg( node->GetID() ) );
+          // node coordinates
+          myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( tr( "COORDINATES" ) ).
+                          arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
+                          arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
+                          arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+          // node connectivity
+          Connectivity connectivity = nodeConnectivity( node );
+          if ( !connectivity.isEmpty() ) {
+            myInfo->append( QString( "<b>%1:</b>" ).arg( tr( "CONNECTIVITY" ) ) );
+            QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
+            if ( !con.isEmpty() )
+              myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "0D_ELEMENTS" ) ).arg( con ) );
+            con = formatConnectivity( connectivity, SMDSAbs_Edge );
+            if ( !con.isEmpty() )
+              myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "EDGES" ) ).arg( con ) );
+            con = formatConnectivity( connectivity, SMDSAbs_Face );
+            if ( !con.isEmpty() )
+              myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "FACES" ) ).arg( con ) );
+            con = formatConnectivity( connectivity, SMDSAbs_Volume );
+            if ( !con.isEmpty() )
+              myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "VOLUMES" ) ).arg( con ) );
+          }
+          else {
+            myInfo->append( QString( "<b>%1</b>" ).arg( tr( "FREE_NODE" ) ).arg( id ) );
+          }
+        }
+      }
+      // separator
+      if ( ids.count() > 1 ) {
+        myInfo->append( "" );
+        myInfo->append( "------" );
+        myInfo->append( "" );
+      }
+    }
+  }
+}
+
+/*!
+  \brief Internal clean-up (reset widget)
+*/
+void SMESHGUI_SimpleElemInfo::clearInternal()
+{
+  myInfo->clear();
+}
+
+/*!
+  \class SMESHGUI_TreeElemInfo::ItemDelegate
+  \brief Item delegate for tree mesh info widget
+  \internal
+*/
+class SMESHGUI_TreeElemInfo::ItemDelegate : public QItemDelegate
+{
+public:
+  ItemDelegate( QObject* );
+  QWidget* createEditor( QWidget*, const QStyleOptionViewItem&, const QModelIndex& ) const;
+};
+
+/*!
+  \brief Constructor
+  \internal
+*/
+SMESHGUI_TreeElemInfo::ItemDelegate::ItemDelegate( QObject* parent ) : QItemDelegate( parent )
+{
+}
+
+/*!
+  \brief Create item editor widget
+  \internal
+*/
+QWidget* SMESHGUI_TreeElemInfo::ItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const
+{
+  QWidget* w = index.column() == 0 ? 0: QItemDelegate::createEditor( parent, option, index );
+  if ( qobject_cast<QLineEdit*>( w ) ) qobject_cast<QLineEdit*>( w )->setReadOnly(  true );
+  return w;
+}
+
+/*!
+  \class SMESHGUI_TreeElemInfo
+  \brief Represents mesh element information in the tree-like form.
+*/
+
+/*!
+  \brief Constructor
+  \param parent parent widget
+*/
+SMESHGUI_TreeElemInfo::SMESHGUI_TreeElemInfo( QWidget* parent )
+: SMESHGUI_ElemInfo( parent )
+{
+  myInfo = new QTreeWidget( frame() );
+  myInfo->setColumnCount( 2 );
+  myInfo->setHeaderLabels( QStringList() << tr( "PROPERTY" ) << tr( "VALUE" ) );
+  myInfo->header()->setStretchLastSection( true );
+  myInfo->header()->setResizeMode( 0, QHeaderView::ResizeToContents );
+  myInfo->setItemDelegate( new ItemDelegate( myInfo ) );
+  QVBoxLayout* l = new QVBoxLayout( frame() );
+  l->setMargin( 0 );
+  l->addWidget( myInfo );
+}
+
+/*!
+  \brief Show mesh element information
+  \param ids mesh nodes / elements identifiers
+*/
+void SMESHGUI_TreeElemInfo::information( const QList<long>& ids )
+{
+  clearInternal();
+
+  if ( actor() ) {
+    int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
+    foreach ( long id, ids ) {
+      if ( !isElements() ) {
+        //
+        // show node info
+        //
+        const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindNode( id );
+        if ( !e ) return;
+        const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( e );
+      
+        // node ID
+        QTreeWidgetItem* nodeItem = createItem( 0, Bold | All );
+        nodeItem->setText( 0, tr( "NODE" ) );
+        nodeItem->setText( 1, QString( "#%1" ).arg( id ) );
+        // coordinates
+        QTreeWidgetItem* coordItem = createItem( nodeItem, Bold );
+        coordItem->setText( 0, tr( "COORDINATES" ) );
+        QTreeWidgetItem* xItem = createItem( coordItem );
+        xItem->setText( 0, "X" );
+        xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+        QTreeWidgetItem* yItem = createItem( coordItem );
+        yItem->setText( 0, "Y" );
+        yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+        QTreeWidgetItem* zItem = createItem( coordItem );
+        zItem->setText( 0, "Z" );
+        zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+        // connectivity
+        QTreeWidgetItem* conItem = createItem( nodeItem, Bold );
+        conItem->setText( 0, tr( "CONNECTIVITY" ) );
+        Connectivity connectivity = nodeConnectivity( node );
+        if ( !connectivity.isEmpty() ) {
+          QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
+          if ( !con.isEmpty() ) {
+            QTreeWidgetItem* i = createItem( conItem );
+            i->setText( 0, tr( "0D_ELEMENTS" ) );
+            i->setText( 1, con );
+          }
+          con = formatConnectivity( connectivity, SMDSAbs_Ball );
+          if ( !con.isEmpty() ) {
+            QTreeWidgetItem* i = createItem( conItem );
+            i->setText( 0, tr( "BALL_ELEMENTS" ) );
+            i->setText( 1, con );
+          }
+          con = formatConnectivity( connectivity, SMDSAbs_Edge );
+          if ( !con.isEmpty() ) {
+            QTreeWidgetItem* i = createItem( conItem );
+            i->setText( 0, tr( "EDGES" ) );
+            i->setText( 1, con );
+          }
+          con = formatConnectivity( connectivity, SMDSAbs_Face );
+          if ( !con.isEmpty() ) {
+            QTreeWidgetItem* i = createItem( conItem );
+            i->setText( 0, tr( "FACES" ) );
+            i->setText( 1, con );
+          }
+          con = formatConnectivity( connectivity, SMDSAbs_Volume );
+          if ( !con.isEmpty() ) {
+            QTreeWidgetItem* i = createItem( conItem );
+            i->setText( 0, tr( "VOLUMES" ) );
+            i->setText( 1, con );
+          }
+        }
+        else {
+          conItem->setText( 1, tr( "FREE_NODE" ) );
+        }
+        // node position
+        int shapeID = node->getshapeId();
+        if ( shapeID > 0 )
+        {
+          SMDS_PositionPtr        pos = node->GetPosition();
+          SMDS_TypeOfPosition posType = pos->GetTypeOfPosition();
+          QString shapeType;
+          double u,v;
+          switch ( posType ) {
+          case SMDS_TOP_EDGE:   shapeType = tr( "EDGE" );
+            u = static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
+            break;
+          case SMDS_TOP_FACE:   shapeType = tr( "FACE" );
+            u = static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
+            v = static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
+            break;
+          case SMDS_TOP_VERTEX: shapeType = tr( "VERTEX" ); break;
+          default:              shapeType = tr( "SOLID" );
+          }
+          QTreeWidgetItem* posItem = createItem( nodeItem, Bold );
+          posItem->setText( 0, tr("NODE_POSITION") );
+          posItem->setText( 1, (shapeType + " #%1").arg( shapeID ));
+          if ( posType == SMDS_TOP_EDGE || posType == SMDS_TOP_FACE ) {
+            QTreeWidgetItem* uItem = createItem( posItem );
+            uItem->setText( 0, tr("U_POSITION") );
+            uItem->setText( 1, QString::number( u, precision > 0 ? 'f' : 'g', qAbs( precision )));
+            if ( posType == SMDS_TOP_FACE ) {
+              QTreeWidgetItem* vItem = createItem( posItem );
+              vItem->setText( 0, tr("V_POSITION") );
+              vItem->setText( 1, QString::number( v, precision > 0 ? 'f' : 'g', qAbs( precision )));
+            }
+          }
+        }
+      }
+      else {
+        //
+        // show element info
+        // 
+        const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id );
+        if ( !e ) return;
+        
+        // element ID && type
+        QString stype;
+        switch( e->GetType() ) {
+        case SMDSAbs_0DElement:
+          stype = tr( "0D ELEMENT" ); break;
+        case SMDSAbs_Ball:
+          stype = tr( "BALL" ); break;
+        case SMDSAbs_Edge:
+          stype = tr( "EDGE" ); break;
+        case SMDSAbs_Face:
+          stype = tr( "FACE" ); break;
+        case SMDSAbs_Volume:
+          stype = tr( "VOLUME" ); break;
+        default: 
+          break;
+        }
+        if ( stype.isEmpty() ) return;
+        QTreeWidgetItem* elemItem = createItem( 0, Bold | All );
+        elemItem->setText( 0, stype );
+        elemItem->setText( 1, QString( "#%1" ).arg( id ) );
+        // geometry type
+        QString gtype;
+        switch( e->GetEntityType() ) {
+        case SMDSEntity_Triangle:
+        case SMDSEntity_Quad_Triangle:
+          gtype = tr( "TRIANGLE" ); break;
+        case SMDSEntity_Quadrangle:
+        case SMDSEntity_Quad_Quadrangle:
+        case SMDSEntity_BiQuad_Quadrangle:
+          gtype = tr( "QUADRANGLE" ); break;
+        case SMDSEntity_Polygon:
+        case SMDSEntity_Quad_Polygon:
+          gtype = tr( "POLYGON" ); break;
+        case SMDSEntity_Tetra:
+        case SMDSEntity_Quad_Tetra:
+          gtype = tr( "TETRAHEDRON" ); break;
+        case SMDSEntity_Pyramid:
+        case SMDSEntity_Quad_Pyramid:
+          gtype = tr( "PYRAMID" ); break;
+        case SMDSEntity_Hexa:
+        case SMDSEntity_Quad_Hexa:
+        case SMDSEntity_TriQuad_Hexa:
+          gtype = tr( "HEXAHEDRON" ); break;
+        case SMDSEntity_Penta:
+        case SMDSEntity_Quad_Penta:
+          gtype = tr( "PRISM" ); break;
+        case SMDSEntity_Hexagonal_Prism:
+          gtype = tr( "HEX_PRISM" ); break;
+        case SMDSEntity_Polyhedra:
+        case SMDSEntity_Quad_Polyhedra:
+          gtype = tr( "POLYHEDRON" ); break;
+        default: 
+          break;
+        }
+        if ( !gtype.isEmpty() ) {
+          QTreeWidgetItem* typeItem = createItem( elemItem, Bold );
+          typeItem->setText( 0, tr( "TYPE" ) );
+          typeItem->setText( 1, gtype );
+        }
+        // quadratic flag and gravity center (any element except 0D)
+        if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Ball ) {
+          // quadratic flag
+          QTreeWidgetItem* quadItem = createItem( elemItem, Bold );
+          quadItem->setText( 0, tr( "QUADRATIC" ) );
+          quadItem->setText( 1, e->IsQuadratic() ? tr( "YES" ) : tr( "NO" ) );
+          // gravity center
+          XYZ gc = gravityCenter( e );
+          QTreeWidgetItem* gcItem = createItem( elemItem, Bold );
+          gcItem->setText( 0, tr( "GRAVITY_CENTER" ) );
+          QTreeWidgetItem* xItem = createItem( gcItem );
+          xItem->setText( 0, "X" );
+          xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+          QTreeWidgetItem* yItem = createItem( gcItem );
+          yItem->setText( 0, "Y" );
+          yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+          QTreeWidgetItem* zItem = createItem( gcItem );
+          zItem->setText( 0, "Z" );
+          zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+        }
+        if ( const SMDS_BallElement* ball = dynamic_cast<const SMDS_BallElement*>( e )) {
+          // ball diameter
+          QTreeWidgetItem* diamItem = createItem( elemItem, Bold );
+          diamItem->setText( 0, tr( "BALL_DIAMETER" ) );
+          diamItem->setText( 1, QString( "%1" ).arg( ball->GetDiameter() ));
+        }
+        // connectivity
+        QTreeWidgetItem* conItem = createItem( elemItem, Bold );
+        conItem->setText( 0, tr( "CONNECTIVITY" ) );
+        SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
+        for ( int idx = 1; nodeIt->more(); idx++ ) {
+          const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+          // node number and ID
+          QTreeWidgetItem* nodeItem = createItem( conItem, Bold );
+          nodeItem->setText( 0, QString( "%1 %2 / %3" ).arg( tr( "NODE" ) ).arg( idx ).arg( e->NbNodes() ) );
+          nodeItem->setText( 1, QString( "#%1" ).arg( node->GetID() ) );
+          nodeItem->setExpanded( false );
+          // node coordinates
+          QTreeWidgetItem* coordItem = createItem( nodeItem );
+          coordItem->setText( 0, tr( "COORDINATES" ) );
+          QTreeWidgetItem* xItem = createItem( coordItem );
+          xItem->setText( 0, "X" );
+          xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+          QTreeWidgetItem* yItem = createItem( coordItem );
+          yItem->setText( 0, "Y" );
+          yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+          QTreeWidgetItem* zItem = createItem( coordItem );
+          zItem->setText( 0, "Z" );
+          zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+          // node connectivity
+          QTreeWidgetItem* nconItem = createItem( nodeItem );
+          nconItem->setText( 0, tr( "CONNECTIVITY" ) );
+          Connectivity connectivity = nodeConnectivity( node );
+          if ( !connectivity.isEmpty() ) {
+            QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
+            if ( !con.isEmpty() ) {
+              QTreeWidgetItem* i = createItem( nconItem );
+              i->setText( 0, tr( "0D_ELEMENTS" ) );
+              i->setText( 1, con );
+            }
+            con = formatConnectivity( connectivity, SMDSAbs_Edge );
+            if ( !con.isEmpty() ) {
+              QTreeWidgetItem* i = createItem( nconItem );
+              i->setText( 0, tr( "EDGES" ) );
+              i->setText( 1, con );
+            }
+            con = formatConnectivity( connectivity, SMDSAbs_Ball );
+            if ( !con.isEmpty() ) {
+              QTreeWidgetItem* i = createItem( nconItem );
+              i->setText( 0, tr( "BALL_ELEMENTS" ) );
+              i->setText( 1, con );
+            }
+            con = formatConnectivity( connectivity, SMDSAbs_Face );
+            if ( !con.isEmpty() ) {
+              QTreeWidgetItem* i = createItem( nconItem );
+              i->setText( 0, tr( "FACES" ) );
+              i->setText( 1, con );
+            }
+            con = formatConnectivity( connectivity, SMDSAbs_Volume );
+            if ( !con.isEmpty() ) {
+              QTreeWidgetItem* i = createItem( nconItem );
+              i->setText( 0, tr( "VOLUMES" ) );
+              i->setText( 1, con );
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+/*!
+  \brief Internal clean-up (reset widget)
+*/
+void SMESHGUI_TreeElemInfo::clearInternal()
+{
+  myInfo->clear();
+  myInfo->repaint();
+}
+
+/*!
+  \brief Create new tree item.
+  \param parent parent tree widget item
+  \param flags item flag
+  \return new tree widget item
+*/
+QTreeWidgetItem* SMESHGUI_TreeElemInfo::createItem( QTreeWidgetItem* parent, int flags )
+{
+  QTreeWidgetItem* item;
+  if ( parent )
+    item = new QTreeWidgetItem( parent );
+  else
+    item = new QTreeWidgetItem( myInfo );
+
+  item->setFlags( item->flags() | Qt::ItemIsEditable );
+
+  QFont f = item->font( 0 );
+  f.setBold( true );
+  for ( int i = 0; i < myInfo->columnCount(); i++ ) {
+    if ( ( flags & Bold ) && ( i == 0 || flags & All ) )
+      item->setFont( i, f );
+  }
+
+  item->setExpanded( true );
+  return item;
+}
+
+/*!
+  \class GrpComputor
+  \brief Mesh information computer
+  \internal
+  
+  The class is created for different computation operation. Currently it is used
+  to compute number of underlying nodes for the groups.
+*/
+
+/*!
+  \brief Contructor
+*/
+GrpComputor::GrpComputor( SMESH::SMESH_GroupBase_ptr grp, QTreeWidgetItem* item, QObject* parent )
+  : QObject( parent ), myItem( item )
+{
+  myGroup = SMESH::SMESH_GroupBase::_narrow( grp );
+}
+
+/*!
+  \brief Compute function
+*/
+void GrpComputor::compute()
+{
+  if ( !CORBA::is_nil( myGroup ) && myItem ) {
+    QTreeWidgetItem* item = myItem;
+    myItem = 0;
+    int nbNodes = myGroup->GetNumberOfNodes();
+    item->treeWidget()->removeItemWidget( item, 1 );
+    item->setText( 1, QString::number( nbNodes ));
+  }
+}
+
+/*!
+  \class SMESHGUI_AddInfo
+  \brief The wigdet shows additional information on the mesh object.
+*/
+
+/*!
+  \brief Constructor
+  \param parent parent widget
+*/
+SMESHGUI_AddInfo::SMESHGUI_AddInfo( QWidget* parent )
+: QTreeWidget( parent )
+{
+  setColumnCount( 2 );
+  header()->setStretchLastSection( true );
+  header()->setResizeMode( 0, QHeaderView::ResizeToContents );
+  header()->hide();
+}
+
+/*!
+  \brief Destructor
+*/
+SMESHGUI_AddInfo::~SMESHGUI_AddInfo()
+{
+}
+
+/*!
+  \brief Show additional information on the selected object
+  \param obj object being processed (mesh, sub-mesh, group, ID source)
+*/
+void SMESHGUI_AddInfo::showInfo( SMESH::SMESH_IDSource_ptr obj )
+{
+  setProperty( "group_index", 0 );
+  setProperty( "submesh_index",  0 );
+  myComputors.clear();
+  clear();
+
+  if ( CORBA::is_nil( obj ) ) return;
+
+  _PTR(SObject) sobj = SMESH::ObjectToSObject( obj );
+  if ( !sobj ) return;
+
+  // name
+  QTreeWidgetItem* nameItem = createItem( 0, Bold | All );
+  nameItem->setText( 0, tr( "NAME" ) );
+  nameItem->setText( 1, sobj->GetName().c_str() );
+  
+  SMESH::SMESH_Mesh_var      aMesh    = SMESH::SMESH_Mesh::_narrow( obj );
+  SMESH::SMESH_subMesh_var   aSubMesh = SMESH::SMESH_subMesh::_narrow( obj );
+  SMESH::SMESH_GroupBase_var aGroup   = SMESH::SMESH_GroupBase::_narrow( obj );
+  
+  if ( !aMesh->_is_nil() )
+    meshInfo( aMesh, nameItem );
+  else if ( !aSubMesh->_is_nil() )
+    subMeshInfo( aSubMesh, nameItem );
+  else if ( !aGroup->_is_nil() )
+    groupInfo( aGroup.in(), nameItem );
+}
+
+/*!
+  \brief Create new tree item.
+  \param parent parent tree widget item
+  \param flags item flag
+  \return new tree widget item
+*/
+QTreeWidgetItem* SMESHGUI_AddInfo::createItem( QTreeWidgetItem* parent, int flags )
+{
+  QTreeWidgetItem* item;
+
+  if ( parent )
+    item = new QTreeWidgetItem( parent );
+  else
+    item = new QTreeWidgetItem( this );
+
+  //item->setFlags( item->flags() | Qt::ItemIsEditable );
+
+  QFont f = item->font( 0 );
+  f.setBold( true );
+  for ( int i = 0; i < columnCount(); i++ ) {
+    if ( ( flags & Bold ) && ( i == 0 || flags & All ) )
+      item->setFont( i, f );
+  }
+
+  item->setExpanded( true );
+  return item;
+}
+
+/*!
+  \brief Show mesh info
+  \param mesh mesh object
+  \param parent parent tree item
+*/
+void SMESHGUI_AddInfo::meshInfo( SMESH::SMESH_Mesh_ptr mesh, QTreeWidgetItem* parent )
+{
+  // type
+  GEOM::GEOM_Object_var shape = mesh->GetShapeToMesh();
+  SALOME_MED::MedFileInfo* inf = mesh->GetMEDFileInfo();
+  QTreeWidgetItem* typeItem = createItem( parent, Bold );
+  typeItem->setText( 0, tr( "TYPE" ) );
+  if ( !CORBA::is_nil( shape ) ) {
+    typeItem->setText( 1, tr( "MESH_ON_GEOMETRY" ) );
+    _PTR(SObject) sobj = SMESH::ObjectToSObject( shape );
+    if ( sobj ) {
+      QTreeWidgetItem* gobjItem = createItem( typeItem );
+      gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
+      gobjItem->setText( 1, sobj->GetName().c_str() );
+    }
+  }
+  else if ( strlen( (char*)inf->fileName ) > 0 ) {
+    typeItem->setText( 1, tr( "MESH_FROM_FILE" ) );
+    QTreeWidgetItem* fileItem = createItem( typeItem );
+    fileItem->setText( 0, tr( "FILE_NAME" ) );
+    fileItem->setText( 1, (char*)inf->fileName );
+  }
+  else {
+    typeItem->setText( 1, tr( "STANDALONE_MESH" ) );
+  }
+  
+  // groups
+  myGroups = mesh->GetGroups();
+  showGroups();
+
+  // sub-meshes
+  mySubMeshes = mesh->GetSubMeshes();
+  showSubMeshes();
+}
+
+/*!
+  \brief Show sub-mesh info
+  \param subMesh sub-mesh object
+  \param parent parent tree item
+*/
+void SMESHGUI_AddInfo::subMeshInfo( SMESH::SMESH_subMesh_ptr subMesh, QTreeWidgetItem* parent )
+{
+  bool isShort = parent->parent() != 0;
+
+  if ( !isShort ) {
+    // parent mesh
+    _PTR(SObject) sobj = SMESH::ObjectToSObject( subMesh->GetFather() );
+    if ( sobj ) {
+      QTreeWidgetItem* nameItem = createItem( parent, Bold );
+      nameItem->setText( 0, tr( "PARENT_MESH" ) );
+      nameItem->setText( 1, sobj->GetName().c_str() );
+    }
+  }
+  
+  // shape
+  GEOM::GEOM_Object_var gobj = subMesh->GetSubShape();
+  _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
+  if ( sobj ) {
+    QTreeWidgetItem* gobjItem = createItem( parent, Bold );
+    gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
+    gobjItem->setText( 1, sobj->GetName().c_str() );
+  }
+}
+
+/*!
+  \brief Show group info
+  \param grp mesh group object
+  \param parent parent tree item
+*/
+void SMESHGUI_AddInfo::groupInfo( SMESH::SMESH_GroupBase_ptr grp, QTreeWidgetItem* parent )
+{
+  bool isShort = parent->parent() != 0;
+
+  SMESH::SMESH_Group_var         aStdGroup  = SMESH::SMESH_Group::_narrow( grp );
+  SMESH::SMESH_GroupOnGeom_var   aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( grp );
+  SMESH::SMESH_GroupOnFilter_var aFltGroup  = SMESH::SMESH_GroupOnFilter::_narrow( grp );
+
+  if ( !isShort ) {
+    // parent mesh
+    _PTR(SObject) sobj = SMESH::ObjectToSObject( grp->GetMesh() );
+    if ( sobj ) {
+      QTreeWidgetItem* nameItem = createItem( parent, Bold );
+      nameItem->setText( 0, tr( "PARENT_MESH" ) );
+      nameItem->setText( 1, sobj->GetName().c_str() );
+    }
+  }
+
+  // type : group on geometry, standalone group, group on filter
+  QTreeWidgetItem* typeItem = createItem( parent, Bold );
+  typeItem->setText( 0, tr( "TYPE" ) );
+  if ( !CORBA::is_nil( aStdGroup ) ) {
+    typeItem->setText( 1, tr( "STANDALONE_GROUP" ) );
+  }
+  else if ( !CORBA::is_nil( aGeomGroup ) ) {
+    typeItem->setText( 1, tr( "GROUP_ON_GEOMETRY" ) );
+    GEOM::GEOM_Object_var gobj = aGeomGroup->GetShape();
+    _PTR(SObject) sobj = SMESH::ObjectToSObject( gobj );
+    if ( sobj ) {
+      QTreeWidgetItem* gobjItem = createItem( typeItem );
+      gobjItem->setText( 0, tr( "GEOM_OBJECT" ) );
+      gobjItem->setText( 1, sobj->GetName().c_str() );
+    }
+  }
+  else if ( !CORBA::is_nil( aFltGroup ) ) {
+    typeItem->setText( 1, tr( "GROUP_ON_FILTER" ) );
+  }
+
+  if ( !isShort ) {
+    // entity type
+    QString etype = tr( "UNKNOWN" );
+    switch( grp->GetType() ) {
+    case SMESH::NODE:
+      etype = tr( "NODE" );
+      break;
+    case SMESH::EDGE:
+      etype = tr( "EDGE" );
+      break;
+    case SMESH::FACE:
+      etype = tr( "FACE" );
+      break;
+    case SMESH::VOLUME:
+      etype = tr( "VOLUME" );
+      break;
+    case SMESH::ELEM0D:
+      etype = tr( "0DELEM" );
+      break;
+    case SMESH::BALL:
+      etype = tr( "BALL" );
+      break;
+    default:
+      break;
+    }
+    QTreeWidgetItem* etypeItem = createItem( parent, Bold );
+    etypeItem->setText( 0, tr( "ENTITY_TYPE" ) );
+    etypeItem->setText( 1, etype );
+  }
+
+  // size
+  QTreeWidgetItem* sizeItem = createItem( parent, Bold );
+  sizeItem->setText( 0, tr( "SIZE" ) );
+  sizeItem->setText( 1, QString::number( grp->Size() ) );
+
+  // color
+  SALOMEDS::Color color = grp->GetColor();
+  QTreeWidgetItem* colorItem = createItem( parent, Bold );
+  colorItem->setText( 0, tr( "COLOR" ) );
+  colorItem->setBackground( 1, QBrush( QColor( color.R*255., color.G*255., color.B*255.) ) );
+
+  // nb of underlying nodes
+  if ( grp->GetType() != SMESH::NODE) {
+    QTreeWidgetItem* nodesItem = createItem( parent, Bold );
+    nodesItem->setText( 0, tr( "NB_NODES" ) );
+    int nbNodesLimit = SMESHGUI::resourceMgr()->integerValue( "SMESH", "info_groups_nodes_limit", 100000 );
+    SMESH::SMESH_Mesh_var mesh = grp->GetMesh();
+    bool meshLoaded = mesh->IsLoaded();
+    bool toShowNodes = ( grp->IsNodeInfoAvailable() || nbNodesLimit <= 0 || grp->Size() <= nbNodesLimit );
+    if ( toShowNodes && meshLoaded ) {
+      // already calculated and up-to-date
+      nodesItem->setText( 1, QString::number( grp->GetNumberOfNodes() ) );
+    }
+    else {
+      QPushButton* btn = new QPushButton( tr( meshLoaded ? "COMPUTE" : "LOAD"), this );
+      setItemWidget( nodesItem, 1, btn );
+      GrpComputor* comp = new GrpComputor( grp, nodesItem, this ); 
+      connect( btn, SIGNAL( clicked() ), comp, SLOT( compute() ) );
+      myComputors.append( comp );
+      if ( !meshLoaded )
+        connect( btn, SIGNAL( clicked() ), this, SLOT( changeLoadToCompute() ) );
+    }
+  }
+}
+
+void SMESHGUI_AddInfo::showGroups()
+{
+  myComputors.clear();
+
+  QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
+  if ( !parent ) return;
+
+  int idx = property( "group_index" ).toInt();
+
+  QTreeWidgetItem* itemGroups = 0;
+  for ( int i = 0; i < parent->childCount() && !itemGroups; i++ ) {
+    if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == GROUPS_ID ) {
+      itemGroups = parent->child( i );
+      ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemGroups, 1 ) );
+      if ( extra )
+        extra->updateControls( myGroups->length(), idx );
+      while ( itemGroups->childCount() ) delete itemGroups->child( 0 ); // clear child items
+    }
+  }
+
+  QMap<int, QTreeWidgetItem*> grpItems;
+  for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)myGroups->length() ); i++ ) {
+    SMESH::SMESH_GroupBase_var grp = myGroups[i];
+    if ( CORBA::is_nil( grp ) ) continue;
+    _PTR(SObject) grpSObj = SMESH::ObjectToSObject( grp );
+    if ( !grpSObj ) continue;
+
+    int grpType = grp->GetType();
+
+    if ( !itemGroups ) {
+      // create top-level groups container item
+      itemGroups = createItem( parent, Bold | All );
+      itemGroups->setText( 0, tr( "GROUPS" ) );
+      itemGroups->setData( 0, Qt::UserRole, GROUPS_ID );
+
+      // total number of groups > 10, show extra widgets for info browsing
+      if ( myGroups->length() > MAXITEMS ) {
+        ExtraWidget* extra = new ExtraWidget( this, true );
+        connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousGroups() ) );
+        connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextGroups() ) );
+        setItemWidget( itemGroups, 1, extra );
+        extra->updateControls( myGroups->length(), idx );
+      }
+    }
+
+    if ( grpItems.find( grpType ) == grpItems.end() ) {
+      grpItems[ grpType ] = createItem( itemGroups, Bold | All );
+      grpItems[ grpType ]->setText( 0, tr( QString( "GROUPS_%1" ).arg( grpType ).toLatin1().constData() ) );
+      itemGroups->insertChild( grpType-1, grpItems[ grpType ] );
+    }
+  
+    // group name
+    QTreeWidgetItem* grpNameItem = createItem( grpItems[ grpType ] );
+    grpNameItem->setText( 0, QString( grpSObj->GetName().c_str() ).trimmed() ); // name is trimmed
+
+    // group info
+    groupInfo( grp.in(), grpNameItem );
+  }
+}
+
+void SMESHGUI_AddInfo::showSubMeshes()
+{
+  QTreeWidgetItem* parent = topLevelItemCount() > 0 ? topLevelItem( 0 ) : 0; // parent should be first top level item
+  if ( !parent ) return;
+
+  int idx = property( "submesh_index" ).toInt();
+
+  QTreeWidgetItem* itemSubMeshes = 0;
+  for ( int i = 0; i < parent->childCount() && !itemSubMeshes; i++ ) {
+    if ( parent->child( i )->data( 0, Qt::UserRole ).toInt() == SUBMESHES_ID ) {
+      itemSubMeshes = parent->child( i );
+      ExtraWidget* extra = dynamic_cast<ExtraWidget*>( itemWidget( itemSubMeshes, 1 ) );
+      if ( extra )
+        extra->updateControls( mySubMeshes->length(), idx );
+      while ( itemSubMeshes->childCount() ) delete itemSubMeshes->child( 0 ); // clear child items
+    }
+  }
+
+  QMap<int, QTreeWidgetItem*> smItems;
+  for ( int i = idx*MAXITEMS ; i < qMin( (idx+1)*MAXITEMS, (int)mySubMeshes->length() ); i++ ) {
+    SMESH::SMESH_subMesh_var sm = mySubMeshes[i];
+    if ( CORBA::is_nil( sm ) ) continue;
+    _PTR(SObject) smSObj = SMESH::ObjectToSObject( sm );
+    if ( !smSObj ) continue;
+    
+    GEOM::GEOM_Object_var gobj = sm->GetSubShape();
+    if ( CORBA::is_nil(gobj ) ) continue;
+    
+    int smType = gobj->GetShapeType();
+    if ( smType == GEOM::COMPSOLID ) smType = GEOM::COMPOUND;
+
+    if ( !itemSubMeshes ) {
+      itemSubMeshes = createItem( parent, Bold | All );
+      itemSubMeshes->setText( 0, tr( "SUBMESHES" ) );
+      itemSubMeshes->setData( 0, Qt::UserRole, SUBMESHES_ID );
+
+      // total number of sub-meshes > 10, show extra widgets for info browsing
+      if ( mySubMeshes->length() > MAXITEMS ) {
+        ExtraWidget* extra = new ExtraWidget( this, true );
+        connect( extra->prev, SIGNAL( clicked() ), this, SLOT( showPreviousSubMeshes() ) );
+        connect( extra->next, SIGNAL( clicked() ), this, SLOT( showNextSubMeshes() ) );
+        setItemWidget( itemSubMeshes, 1, extra );
+        extra->updateControls( mySubMeshes->length(), idx );
+      }
+    }
+         
+    if ( smItems.find( smType ) == smItems.end() ) {
+      smItems[ smType ] = createItem( itemSubMeshes, Bold | All );
+      smItems[ smType ]->setText( 0, tr( QString( "SUBMESHES_%1" ).arg( smType ).toLatin1().constData() ) );
+      itemSubMeshes->insertChild( smType, smItems[ smType ] );
+    }
+    
+    // submesh name
+    QTreeWidgetItem* smNameItem = createItem( smItems[ smType ] );
+    smNameItem->setText( 0, QString( smSObj->GetName().c_str() ).trimmed() ); // name is trimmed
+    
+    // submesh info
+    subMeshInfo( sm.in(), smNameItem );
+  }
+}
+
+/*!
+ * \brief Change button label of "nb underlying node" group from "Load" to "Compute"
+ */
+void SMESHGUI_AddInfo::changeLoadToCompute()
+{
+  for ( int i = 0; i < myComputors.count(); ++i )
+  {
+    if ( QTreeWidgetItem* item = myComputors[i]->getItem() )
+    {
+      if ( QPushButton* btn = qobject_cast<QPushButton*>( itemWidget ( item, 1 ) ) )
+        btn->setText( tr("COMPUTE") );
+    }
+  }
+}
+
+void SMESHGUI_AddInfo::showPreviousGroups()
+{
+  int idx = property( "group_index" ).toInt();
+  setProperty( "group_index", idx-1 );
+  showGroups();
+}
+
+void SMESHGUI_AddInfo::showNextGroups()
+{
+  int idx = property( "group_index" ).toInt();
+  setProperty( "group_index", idx+1 );
+  showGroups();
+}
+
+void SMESHGUI_AddInfo::showPreviousSubMeshes()
+{
+  int idx = property( "submesh_index" ).toInt();
+  setProperty( "submesh_index", idx-1 );
+  showSubMeshes();
+}
+
+void SMESHGUI_AddInfo::showNextSubMeshes()
+{
+  int idx = property( "submesh_index" ).toInt();
+  setProperty( "submesh_index", idx+1 );
+  showSubMeshes();
+}
+
+/*!
+  \class SMESHGUI_MeshInfoDlg
+  \brief Mesh information dialog box
+*/
+
+/*!
+  \brief Constructor
+  \param parent parent widget
+  \param page specifies the dialog page to be shown at the start-up
+*/
+SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page )
+: QDialog( parent ), myActor( 0 )
+{
+  setModal( false );
+  setAttribute( Qt::WA_DeleteOnClose, true );
+  setWindowTitle( tr( "MESH_INFO" ) );
+  setSizeGripEnabled( true );
+
+  myTabWidget = new QTabWidget( this );
+
+  // base info 
+
+  myBaseInfo = new SMESHGUI_MeshInfo( myTabWidget );
+  myTabWidget->addTab( myBaseInfo, tr( "BASE_INFO" ) );
+
+  // elem info 
+  
+  QWidget* w = new QWidget( myTabWidget );
+
+  myMode = new QButtonGroup( this );
+  myMode->addButton( new QRadioButton( tr( "NODE_MODE" ), w ), NodeMode );
+  myMode->addButton( new QRadioButton( tr( "ELEM_MODE" ), w ), ElemMode );
+  myMode->button( NodeMode )->setChecked( true );
+  myID = new QLineEdit( w );
+  myID->setValidator( new SMESHGUI_IdValidator( this ) );
+
+  int mode = SMESHGUI::resourceMgr()->integerValue( "SMESH", "mesh_elem_info", 1 );
+  mode = qMin( 1, qMax( 0, mode ) );
+  
+  if ( mode == 0 ) 
+    myElemInfo = new SMESHGUI_SimpleElemInfo( w );
+  else
+    myElemInfo = new SMESHGUI_TreeElemInfo( w );
+
+  QGridLayout* elemLayout = new QGridLayout( w );
+  elemLayout->setMargin( MARGIN );
+  elemLayout->setSpacing( SPACING );
+  elemLayout->addWidget( myMode->button( NodeMode ), 0, 0 );
+  elemLayout->addWidget( myMode->button( ElemMode ), 0, 1 );
+  elemLayout->addWidget( myID, 0, 2 );
+  elemLayout->addWidget( myElemInfo, 1, 0, 1, 3 );
+  
+  myTabWidget->addTab( w, tr( "ELEM_INFO" ) );
+
+  // additional info
+
+  myAddInfo = new SMESHGUI_AddInfo( myTabWidget );
+  myTabWidget->addTab( myAddInfo, tr( "ADDITIONAL_INFO" ) );
+
+  // buttons
+
+  QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this );
+  okBtn->setAutoDefault( true );
+  okBtn->setDefault( true );
+  okBtn->setFocus();
+  QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this );
+  helpBtn->setAutoDefault( true );
+
+  QHBoxLayout* btnLayout = new QHBoxLayout;
+  btnLayout->setSpacing( SPACING );
+  btnLayout->setMargin( 0 );
+
+  btnLayout->addWidget( okBtn );
+  btnLayout->addStretch( 10 );
+  btnLayout->addWidget( helpBtn );
+
+  QVBoxLayout* l = new QVBoxLayout ( this );
+  l->setMargin( MARGIN );
+  l->setSpacing( SPACING );
+  l->addWidget( myTabWidget );
+  l->addLayout( btnLayout );
+
+  myTabWidget->setCurrentIndex( qMax( (int)BaseInfo, qMin( (int)ElemInfo, page ) ) );
+
+  connect( okBtn,       SIGNAL( clicked() ),              this, SLOT( reject() ) );
+  connect( helpBtn,     SIGNAL( clicked() ),              this, SLOT( help() ) );
+  connect( myTabWidget, SIGNAL( currentChanged( int  ) ), this, SLOT( updateSelection() ) );
+  connect( myMode,      SIGNAL( buttonClicked( int  ) ),  this, SLOT( modeChanged() ) );
+  connect( myID,        SIGNAL( textEdited( QString  ) ), this, SLOT( idChanged() ) );
+  connect( SMESHGUI::GetSMESHGUI(),  SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) );
+  connect( SMESHGUI::GetSMESHGUI(),  SIGNAL( SignalCloseAllDialogs() ),        this, SLOT( reject() ) );
+
+  updateSelection();
+}
+
+/*!
+  \brief Destructor
+*/
+SMESHGUI_MeshInfoDlg::~SMESHGUI_MeshInfoDlg()
+{
+}
+
+/*!
+  \brief Show mesh information
+  \param IO interactive object
+*/
+void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO )
+{
+  SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
+  if ( !CORBA::is_nil( obj ) ) {
+    myBaseInfo->showInfo( obj );
+    myAddInfo->showInfo( obj );
+
+    myActor = SMESH::FindActorByEntry( IO->getEntry() );
+    SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
+    QString ID;
+    int nb = 0;
+    if ( myActor && selector ) {
+      nb = myMode->checkedId() == NodeMode ? 
+        SMESH::GetNameOfSelectedElements( selector, IO, ID ) :
+        SMESH::GetNameOfSelectedNodes( selector, IO, ID );
+    }
+    myElemInfo->setSource( myActor ) ;
+    if ( nb > 0 ) {
+      myID->setText( ID.trimmed() );
+      QSet<long> ids;
+      QStringList idTxt = ID.split( " ", QString::SkipEmptyParts );
+      foreach ( ID, idTxt )
+        ids << ID.trimmed().toLong();
+      myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
+    }
+    else {
+      myID->clear();
+      myElemInfo->clear();
+    }
+  }
+}
+
+/*!
+  \brief Perform clean-up actions on the dialog box closing.
+*/
+void SMESHGUI_MeshInfoDlg::reject()
+{
+  LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
+  selMgr->clearFilters();
+  SMESH::SetPointRepresentation( false );
+  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+    aViewWindow->SetSelectionMode( ActorSelection );
+  QDialog::reject();
+}
+
+/*!
+  \brief Process keyboard event
+  \param e key press event
+*/
+void SMESHGUI_MeshInfoDlg::keyPressEvent( QKeyEvent* e )
+{
+  QDialog::keyPressEvent( e );
+  if ( !e->isAccepted() && e->key() == Qt::Key_F1 ) {
+    e->accept();
+    help();
+  }
+}
+
+/*!
+  \brief Reactivate dialog box, when mouse pointer goes into it.
+*/
+void SMESHGUI_MeshInfoDlg::enterEvent( QEvent* )
+{
+  //activate();
+}
+
+/*!
+  \brief Setup selection mode depending on the current dialog box state.
+*/
+void SMESHGUI_MeshInfoDlg::updateSelection()
+{
+  LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr();
+
+  disconnect( selMgr, 0, this, 0 );
+  selMgr->clearFilters();
+
+  if ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo ) {
+    SMESH::SetPointRepresentation( false );
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+      aViewWindow->SetSelectionMode( ActorSelection );
+  }
+  else {
+    if ( myMode->checkedId() == NodeMode ) {
+      SMESH::SetPointRepresentation( true );
+      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+        aViewWindow->SetSelectionMode( NodeSelection );
+    }
+    else {
+      SMESH::SetPointRepresentation( false );
+      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+        aViewWindow->SetSelectionMode( CellSelection );
+    }
+  }
+
+  QString oldID = myID->text().trimmed();
+  SMESH_Actor* oldActor = myActor;
+  myID->clear();
+  
+  connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
+  updateInfo();
+  
+  if ( oldActor == myActor && myActor && !oldID.isEmpty() ) {
+    myID->setText( oldID );
+    idChanged();
+  }
+}
+
+/*!
+  \brief Show help page
+*/
+void SMESHGUI_MeshInfoDlg::help()
+{
+  SMESH::ShowHelpFile( ( myTabWidget->currentIndex() == BaseInfo || myTabWidget->currentIndex() == AddInfo ) ?
+                       "mesh_infos_page.html#advanced_mesh_infos_anchor" : 
+                       "mesh_infos_page.html#mesh_element_info_anchor" );
+}
+
+/*!
+  \brief Show mesh information
+*/
+void SMESHGUI_MeshInfoDlg::updateInfo()
+{
+  SUIT_OverrideCursor wc;
+
+  SALOME_ListIO selected;
+  SMESHGUI::selectionMgr()->selectedObjects( selected );
+
+  if ( selected.Extent() == 1 ) {
+    Handle(SALOME_InteractiveObject) IO = selected.First();
+    showInfo( IO );
+  }
+//   else {
+//     myBaseInfo->clear();
+//     myElemInfo->clear();
+//     myAddInfo->clear();
+//   }
+}
+
+/*!
+  \brief Activate dialog box
+*/
+void SMESHGUI_MeshInfoDlg::activate()
+{
+  SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
+  SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this );
+  myTabWidget->setEnabled( true );
+  updateSelection();
+}
+
+/*!
+  \brief Deactivate dialog box
+*/
+void SMESHGUI_MeshInfoDlg::deactivate()
+{
+  myTabWidget->setEnabled( false );
+  disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
+}
+
+/*!
+  \brief Called when users switches between node / element modes.
+*/
+void SMESHGUI_MeshInfoDlg::modeChanged()
+{
+  myID->clear();
+  updateSelection();
+}
+
+/*!
+  \brief Caled when users prints mesh element ID in the corresponding field.
+*/
+void SMESHGUI_MeshInfoDlg::idChanged()
+{
+  SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector();
+  if ( myActor && selector ) {
+    Handle(SALOME_InteractiveObject) IO = myActor->getIO();
+    TColStd_MapOfInteger ID;
+    QSet<long> ids;
+    QStringList idTxt = myID->text().split( " ", QString::SkipEmptyParts );
+    foreach ( QString tid, idTxt ) {
+      long id = tid.trimmed().toLong();
+      const SMDS_MeshElement* e = myMode->checkedId() == ElemMode ? 
+        myActor->GetObject()->GetMesh()->FindElement( id ) :
+        myActor->GetObject()->GetMesh()->FindNode( id );
+      if ( e ) {
+        ID.Add( id );
+        ids << id;
+      }
+    }
+    selector->AddOrRemoveIndex( IO, ID, false );
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
+      aViewWindow->highlight( IO, true, true );
+    myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
+  }
+}
diff --git a/src/SMESHGUI/SMESHGUI_MeshInfo.h b/src/SMESHGUI/SMESHGUI_MeshInfo.h
new file mode 100644 (file)
index 0000000..a2fa399
--- /dev/null
@@ -0,0 +1,305 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+//  File   : SMESHGUI_MeshInfo.h
+//  Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+
+#ifndef SMESHGUI_MESHINFO_H
+#define SMESHGUI_MESHINFO_H
+
+#include "SMESH_SMESHGUI.hxx"
+#include <SALOME_InteractiveObject.hxx>
+
+#include <QFrame>
+#include <QDialog>
+#include <QList>
+#include <QMap>
+#include <QSet>
+#include <QTreeWidget>
+#include <QVector>
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_Group)
+
+class QButtonGroup;
+class QLabel;
+class QLineEdit;
+class QPushButton;
+class QTabWidget;
+class QTextBrowser;
+class SMESH_Actor;
+class SMDS_MeshNode;
+class SMDS_MeshElement;
+
+class ExtraWidget;
+
+class SMESHGUI_EXPORT SMESHGUI_MeshInfo : public QFrame
+{
+  Q_OBJECT;
+  
+  enum {
+    iName,
+    iObject,
+    iNodesStart,
+    iNodes,
+    iNodesEnd,
+    iElementsStart = iNodesEnd, 
+    iElements,
+    i0DStart,
+    i0D,
+    i0DEnd,
+    iBallsStart = i0DEnd,
+    iBalls,
+    iBallsEnd,
+    i1DStart       = iBallsEnd,
+    i1D,
+    i1DEnd,
+    i2DStart       = i1DEnd,
+    i2D,
+    i2DTriangles,
+    i2DQuadrangles,
+    i2DPolygons,
+    i2DEnd,
+    i3DStart       = i2DEnd,
+    i3D,
+    i3DTetrahedrons,
+    i3DHexahedrons,
+    i3DPyramids,
+    i3DPrisms,
+    i3DHexaPrisms,
+    i3DPolyhedrons,
+    i3DEnd,
+    iElementsEnd   = i3DEnd
+  };
+
+  enum {
+    iSingle = 1,
+    iTotal  = iSingle,
+    iLinear,
+    iQuadratic
+  };
+
+  typedef QList<QWidget*> wlist;
+  typedef QVector<wlist>  iwlist;
+
+public:
+  SMESHGUI_MeshInfo( QWidget* = 0 );
+  ~SMESHGUI_MeshInfo();
+
+  void     showInfo( SMESH::SMESH_IDSource_ptr );
+  void     clear();
+
+private:
+  enum { Bold = 0x01, Italic = 0x02 };
+
+  QLabel*  createField();
+  QWidget* createLine();
+  void     setFontAttributes( QWidget*, int, bool = true );
+  void     setFieldsVisible( int, int, bool );
+
+private slots:
+  void loadMesh();
+
+private:
+  iwlist       myWidgets;
+  QPushButton* myLoadBtn;
+};
+
+class SMESHGUI_EXPORT SMESHGUI_ElemInfo : public QWidget
+{
+  Q_OBJECT;
+
+public:
+  SMESHGUI_ElemInfo( QWidget* = 0 );
+  ~SMESHGUI_ElemInfo();
+
+  void         setSource( SMESH_Actor* );
+  void         showInfo( long, bool );
+  void         showInfo( QSet<long>, bool );
+  void         clear();
+
+protected:
+  struct XYZ
+  {
+    double myX, myY, myZ;
+    XYZ() { myX = myY = myZ = 0.0; }
+    void add( double x, double y, double z ) { myX += x; myY += y; myZ += z; }
+    void divide( double a ) { if ( a != 0.) { myX /= a; myY /= a; myZ /= a; } }
+    double x() const  { return myX; }
+    double y() const  { return myY; }
+    double z() const  { return myZ; }
+  };
+  typedef QMap< int, QList<int> > Connectivity;
+
+  QWidget*     frame() const;
+  SMESH_Actor* actor() const;
+  bool         isElements() const;
+
+  virtual void information( const QList<long>& ) = 0;
+  virtual void clearInternal();
+
+  Connectivity nodeConnectivity( const SMDS_MeshNode* );
+  QString      formatConnectivity( Connectivity, int );
+  XYZ          gravityCenter( const SMDS_MeshElement* );
+
+private slots:
+  void         showPrevious();
+  void         showNext();
+  void         updateControls();
+
+private:
+  SMESH_Actor*     myActor;
+  QList<long>      myIDs;
+  int              myIsElement;
+  QWidget*         myFrame;
+  ExtraWidget*     myExtra;
+  int              myIndex;
+};
+
+class SMESHGUI_EXPORT SMESHGUI_SimpleElemInfo : public SMESHGUI_ElemInfo
+{
+public:
+  SMESHGUI_SimpleElemInfo( QWidget* = 0 );
+
+protected:
+  void          information( const QList<long>& );
+  void          clearInternal();
+
+private:
+  QTextBrowser* myInfo;
+};
+
+class SMESHGUI_EXPORT SMESHGUI_TreeElemInfo : public SMESHGUI_ElemInfo
+{
+  class ItemDelegate;
+
+  enum { Bold = 0x01, All = 0x80 };
+
+public:
+  SMESHGUI_TreeElemInfo( QWidget* = 0 );
+
+protected:
+  void             information( const QList<long>& );
+  void             clearInternal();
+
+private:
+  QTreeWidgetItem* createItem( QTreeWidgetItem* = 0, int = 0 );
+  
+private:
+  QTreeWidget*     myInfo;
+};
+
+class GrpComputor: public QObject
+{
+  Q_OBJECT;
+
+public:
+  GrpComputor( SMESH::SMESH_GroupBase_ptr, QTreeWidgetItem*, QObject* );
+  QTreeWidgetItem* getItem() { return myItem; }
+
+public slots:
+  void compute();
+
+private:
+  SMESH::SMESH_GroupBase_var myGroup;
+  QTreeWidgetItem*           myItem;
+};
+
+class SMESHGUI_EXPORT SMESHGUI_AddInfo : public QTreeWidget
+{
+  Q_OBJECT;
+
+  enum { Bold = 0x01, All = 0x80 };
+
+public:
+  SMESHGUI_AddInfo( QWidget* = 0 );
+  ~SMESHGUI_AddInfo();
+
+  void             showInfo( SMESH::SMESH_IDSource_ptr );
+  //  void             clear();
+
+private slots:
+  void             changeLoadToCompute();
+  void             showPreviousGroups();
+  void             showNextGroups();
+  void             showPreviousSubMeshes();
+  void             showNextSubMeshes();
+
+private:
+  QTreeWidgetItem* createItem( QTreeWidgetItem* = 0, int = 0 );
+  void             meshInfo( SMESH::SMESH_Mesh_ptr, QTreeWidgetItem* );
+  void             subMeshInfo( SMESH::SMESH_subMesh_ptr, QTreeWidgetItem* );
+  void             groupInfo( SMESH::SMESH_GroupBase_ptr, QTreeWidgetItem* );
+
+  void             showGroups();
+  void             showSubMeshes();
+
+private:
+  QList<GrpComputor*>      myComputors;
+  SMESH::ListOfGroups_var  myGroups;
+  SMESH::submesh_array_var mySubMeshes;
+};
+
+class SMESHGUI_EXPORT SMESHGUI_MeshInfoDlg : public QDialog
+{ 
+  Q_OBJECT;
+
+  enum { NodeMode, ElemMode };
+
+public:
+  //! Information type
+  enum { 
+    BaseInfo,  //!< base mesh information
+    ElemInfo,  //!< mesh element information
+    AddInfo    //!< additional information
+  };
+
+  SMESHGUI_MeshInfoDlg( QWidget* = 0, int = BaseInfo );
+  ~SMESHGUI_MeshInfoDlg();
+
+  void showInfo( const Handle(SALOME_InteractiveObject)& );
+  void reject();
+
+protected:
+  void keyPressEvent( QKeyEvent* );
+  void enterEvent( QEvent* );
+
+private slots:
+  void help();
+  void updateSelection();
+  void updateInfo();
+  void activate();
+  void deactivate();
+  void modeChanged();
+  void idChanged();
+
+private:
+  QTabWidget*        myTabWidget;
+  SMESHGUI_MeshInfo* myBaseInfo;
+  QButtonGroup*      myMode;
+  QLineEdit*         myID;
+  SMESHGUI_ElemInfo* myElemInfo;   
+  SMESHGUI_AddInfo*  myAddInfo;
+  SMESH_Actor*       myActor;
+};
+
+#endif // SMESHGUI_MESHINFO_H
diff --git a/src/SMESHGUI/SMESHGUI_MeshInfosBox.cxx b/src/SMESHGUI/SMESHGUI_MeshInfosBox.cxx
new file mode 100644 (file)
index 0000000..17f6539
--- /dev/null
@@ -0,0 +1,475 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+// File   : SMESHGUI_MeshInfosBox.cxx
+// Author : Edward AGAPOV, Open CASCADE S.A.S.
+// SMESH includes
+//
+#include "SMESHGUI_MeshInfosBox.h"
+
+#include "SMDSAbs_ElementType.hxx"
+
+// Qt includes
+#include <QFrame>
+#include <QLabel>
+#include <QGridLayout>
+
+#define SPACING 6
+#define MARGIN  11
+
+#define COLONIZE(str)   (QString(str).contains(":") > 0 ? QString(str) : QString(str) + " :" )
+
+static void addSeparator( QWidget* parent )
+{
+  QGridLayout* l = qobject_cast<QGridLayout*>( parent->layout() );
+  int row  = l->rowCount();
+  int cols = l->columnCount();
+  for ( int i = 0; i < cols; i++ ) {
+    QFrame* hline = new QFrame( parent );
+    hline->setFrameStyle( QFrame::HLine | QFrame::Sunken );
+    l->addWidget( hline, row, i );
+  }
+}
+
+enum TCol {
+  COL_ALGO = 0, COL_SHAPE, COL_ERROR, COL_SHAPEID, COL_PUBLISHED, COL_BAD_MESH, NB_COLUMNS
+};
+
+// =========================================================================================
+/*!
+ * \brief Box showing mesh info
+ */
+// =========================================================================================
+
+SMESHGUI_MeshInfosBox::SMESHGUI_MeshInfosBox(const bool full, QWidget* theParent)
+: QGroupBox( tr("SMESH_MESHINFO_TITLE"), theParent ), myFull( full ),
+  myNbNode(0),
+  my0DElem(0),
+  myBall(0),
+  myNbEdge(0), myNbLinEdge(0), myNbQuadEdge(0),
+  myNbTrai(0), myNbLinTrai(0), myNbQuadTrai(0),
+  myNbQuad(0), myNbLinQuad(0), myNbQuadQuad(0),
+  myNbFace(0), myNbLinFace(0), myNbQuadFace(0),
+  myNbPolyg(0),
+  myNbHexa(0), myNbLinHexa(0), myNbQuadHexa(0),
+  myNbTetra(0),myNbLinTetra(0),myNbQuadTetra(0),
+  myNbPyra(0), myNbLinPyra(0), myNbQuadPyra(0),
+  myNbPrism(0),myNbLinPrism(0), myNbQuadPrism(0),
+  myNbVolum(0), myNbLinVolum(0), myNbQuadVolum(0),
+  myNbHexaPrism(0),
+  myNbPolyh(0)
+{
+  QGridLayout* l = new QGridLayout(this);
+  l->setMargin( MARGIN );
+  l->setSpacing( SPACING );
+
+  QFont italic = font(); italic.setItalic(true);
+  QFont bold   = font(); bold.setBold(true);
+
+  QLabel* lab;
+  int row = 0;
+
+  // title
+  lab = new QLabel( this );
+  lab->setMinimumWidth(100); lab->setFont( italic );
+  l->addWidget( lab, row, 0 );
+  // --
+  lab = new QLabel(tr("SMESH_MESHINFO_ORDER0"), this );
+  lab->setMinimumWidth(100); lab->setFont( italic );
+  l->addWidget( lab, row, 1 );
+  // --
+  lab = new QLabel(tr("SMESH_MESHINFO_ORDER1"), this );
+  lab->setMinimumWidth(100); lab->setFont( italic );
+  l->addWidget( lab, row, 2 );
+  // --
+  lab = new QLabel(tr("SMESH_MESHINFO_ORDER2"), this );
+  lab->setMinimumWidth(100); lab->setFont( italic );
+  l->addWidget( lab, row, 3 );
+
+  if ( myFull )
+  {
+    // nodes
+    row = l->rowCount();         // retrieve current row count
+    // --
+    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_NODES")), this );
+    lab->setFont( bold );
+    l->addWidget( lab,           row, 0 );
+    // --
+    myNbNode = new QLabel( this );
+    l->addWidget( myNbNode,      row, 1 );
+
+    addSeparator(this);          // add separator
+
+    // 0D elements
+    row = l->rowCount();         // retrieve current row count
+    // --
+    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_0DELEMS")), this );
+    lab->setFont( bold );
+    l->addWidget( lab,           row, 0 );
+    // --
+    my0DElem = new QLabel( this );
+    l->addWidget( my0DElem,      row, 1 );
+
+    addSeparator(this);          // add separator
+
+    // balls
+    row = l->rowCount();         // retrieve current row count
+    // --
+    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_BALLS")), this );
+    lab->setFont( bold );
+    l->addWidget( lab,           row, 0 );
+    // --
+    myBall = new QLabel( this );
+    l->addWidget( myBall,      row, 1 );
+
+    addSeparator(this);          // add separator
+
+    // edges
+    row = l->rowCount();         // retrieve current row count
+    // --
+    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_EDGES")), this );
+    lab->setFont( bold );
+    l->addWidget( lab,           row, 0 );
+    // --
+    myNbEdge = new QLabel( this );
+    l->addWidget( myNbEdge,      row, 1 );
+    // --
+    myNbLinEdge = new QLabel( this );
+    l->addWidget( myNbLinEdge,   row, 2 );
+    // --
+    myNbQuadEdge = new QLabel( this );
+    l->addWidget( myNbQuadEdge,  row, 3 );
+
+    addSeparator(this);          // add separator
+
+    // faces
+    row = l->rowCount();         // retrieve current row count
+    // --
+    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_FACES")), this);
+    lab->setFont( bold );
+    l->addWidget( lab,           row, 0 );
+    // --
+    myNbFace     = new QLabel( this );
+    l->addWidget( myNbFace,      row, 1 );
+    // --
+    myNbLinFace  = new QLabel( this );
+    l->addWidget( myNbLinFace,   row, 2 );
+    // --
+    myNbQuadFace = new QLabel( this );
+    l->addWidget( myNbQuadFace,  row, 3 );
+    // --
+    row++;                       // increment row count
+    // ... triangles
+    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_TRIANGLES")), this );
+    l->addWidget( lab,           row, 0 );
+    // --
+    myNbTrai     = new QLabel( this );
+    l->addWidget( myNbTrai,      row, 1 );
+    // --
+    myNbLinTrai  = new QLabel( this );
+    l->addWidget( myNbLinTrai,   row, 2 );
+    // --
+    myNbQuadTrai = new QLabel( this );
+    l->addWidget( myNbQuadTrai,  row, 3 );
+    // --
+    row++;                       // increment row count
+    // ... quadrangles
+    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_QUADRANGLES")), this );
+    l->addWidget( lab,           row, 0 );
+    // --
+    myNbQuad     = new QLabel( this );
+    l->addWidget( myNbQuad,      row, 1 );
+    // --
+    myNbLinQuad  = new QLabel( this );
+    l->addWidget( myNbLinQuad,   row, 2 );
+    // --
+    myNbQuadQuad = new QLabel( this );
+    l->addWidget( myNbQuadQuad,  row, 3 );
+    // --
+    row++;                       // increment row count
+    // ... poligones
+    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_POLYGONES")), this );
+    l->addWidget( lab,           row, 0 );
+    myNbPolyg    = new QLabel( this );
+    l->addWidget( myNbPolyg,     row, 1 );
+
+    addSeparator(this);          // add separator
+
+    // volumes
+    row = l->rowCount();         // retrieve current row count
+    // --
+    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_VOLUMES")), this);
+    lab->setFont( bold );
+    l->addWidget( lab,           row, 0 );
+    // --
+    myNbVolum     = new QLabel( this );
+    l->addWidget( myNbVolum,     row, 1 );
+    // --
+    myNbLinVolum  = new QLabel( this );
+    l->addWidget( myNbLinVolum,  row, 2 );
+    // --
+    myNbQuadVolum = new QLabel( this );
+    l->addWidget( myNbQuadVolum, row, 3 );
+    // --
+    row++;                       // increment row count
+    // ... tetras
+    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_TETRAS")), this );
+    l->addWidget( lab,           row, 0 );
+    // --
+    myNbTetra     = new QLabel( this );
+    l->addWidget( myNbTetra,     row, 1 );
+    // --
+    myNbLinTetra  = new QLabel( this );
+    l->addWidget( myNbLinTetra,  row, 2 );
+    // --
+    myNbQuadTetra = new QLabel( this );
+    l->addWidget( myNbQuadTetra, row, 3 );
+    // --
+    row++;                       // increment row count
+    // ... hexas
+    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_HEXAS")), this );
+    l->addWidget( lab,           row, 0 );
+    // --
+    myNbHexa      = new QLabel( this );
+    l->addWidget( myNbHexa,      row, 1 );
+    // --
+    myNbLinHexa   = new QLabel( this );
+    l->addWidget( myNbLinHexa,   row, 2 );
+    // --
+    myNbQuadHexa  = new QLabel( this );
+    l->addWidget( myNbQuadHexa,  row, 3 );
+    // --
+    row++;                       // increment row count
+    // ... pyras
+    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_PYRAS")), this );
+    l->addWidget( lab,           row, 0 );
+    // --
+    myNbPyra      = new QLabel( this );
+    l->addWidget( myNbPyra,      row, 1 );
+    // --
+    myNbLinPyra   = new QLabel( this );
+    l->addWidget( myNbLinPyra,   row, 2 );
+    // --
+    myNbQuadPyra  = new QLabel( this );
+    l->addWidget( myNbQuadPyra,  row, 3 );
+    // --
+    row++;                       // increment row count
+    // ... prisms
+    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_PRISMS")), this );
+    l->addWidget( lab,           row, 0 );
+    // --
+    myNbPrism     = new QLabel( this );
+    l->addWidget( myNbPrism,     row, 1 );
+    // --
+    myNbLinPrism  = new QLabel( this );
+    l->addWidget( myNbLinPrism,  row, 2 );
+    // --
+    myNbQuadPrism = new QLabel( this );
+    l->addWidget( myNbQuadPrism, row, 3 );
+    // --
+    row++;                       // increment row count
+    // ... hexa prisms
+    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_HEXAPRISM")), this );
+    l->addWidget( lab,           row, 0 );
+    // --
+    myNbHexaPrism     = new QLabel( this );
+    l->addWidget( myNbHexaPrism, row, 1 );
+    // --
+    row++;                       // increment row count
+    // ... polyedres
+    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_POLYEDRES")), this );
+    l->addWidget( lab,           row, 0 );
+    // --
+    myNbPolyh     = new QLabel( this );
+    l->addWidget( myNbPolyh,     row, 1 );
+  }
+  else
+  {
+    // nodes
+    row = l->rowCount();         // retrieve current row count
+    // --
+    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_NODES")), this );
+    l->addWidget( lab,           row, 0 );
+    // --
+    myNbNode      = new QLabel( this );
+    l->addWidget( myNbNode,      row, 1 );
+
+    // 0D elements
+    row = l->rowCount();         // retrieve current row count
+    // --
+    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_0DELEMS")), this );
+    l->addWidget( lab,           row, 0 );
+    // --
+    my0DElem = new QLabel( this );
+    l->addWidget( my0DElem,      row, 1 );
+
+    addSeparator(this);          // add separator
+
+    // edges
+    row = l->rowCount();         // retrieve current row count
+    // --
+    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_EDGES")), this );
+    l->addWidget( lab,           row, 0 );
+    // --
+    myNbEdge      = new QLabel( this );
+    l->addWidget( myNbEdge,      row, 1 );
+    // --
+    myNbLinEdge   = new QLabel( this );
+    l->addWidget( myNbLinEdge,   row, 2 );
+    // --
+    myNbQuadEdge  = new QLabel( this );
+    l->addWidget( myNbQuadEdge,  row, 3 );
+
+    // faces
+    row = l->rowCount();         // retrieve current row count
+    // --
+    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_FACES")), this);
+    l->addWidget( lab,           row, 0 );
+    // --
+    myNbFace      = new QLabel( this );
+    l->addWidget( myNbFace,      row, 1 );
+    // --
+    myNbLinFace   = new QLabel( this );
+    l->addWidget( myNbLinFace,   row, 2 );
+    // --
+    myNbQuadFace  = new QLabel( this );
+    l->addWidget( myNbQuadFace,  row, 3 );
+
+    // volumes
+    row = l->rowCount();         // retrieve current row count
+    // --
+    lab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_VOLUMES")), this);
+    l->addWidget( lab,           row, 0 );
+    // --
+    myNbVolum     = new QLabel( this );
+    l->addWidget( myNbVolum,     row, 1 );
+    // --
+    myNbLinVolum  = new QLabel( this );
+    l->addWidget( myNbLinVolum,  row, 2 );
+    // --
+    myNbQuadVolum = new QLabel( this );
+    l->addWidget( myNbQuadVolum, row, 3 );
+  }
+}
+
+// =========================================================================================
+/*!
+ * \brief Set mesh info
+ */
+// =========================================================================================
+
+void SMESHGUI_MeshInfosBox::SetMeshInfo(const SMESH::long_array& theInfo)
+{
+  // nodes
+  myNbNode     ->setText( QString("%1").arg( theInfo[SMDSEntity_Node] ));
+
+  //0D elements
+  my0DElem     ->setText( QString("%1").arg( theInfo[SMDSEntity_0D] ));
+
+  //balls
+  myBall       ->setText( QString("%1").arg( theInfo[SMDSEntity_Ball] ));
+
+  // edges
+  myNbEdge     ->setText( QString("%1").arg( theInfo[SMDSEntity_Edge] +
+                                             theInfo[SMDSEntity_Quad_Edge] ));
+  myNbLinEdge  ->setText( QString("%1").arg( theInfo[SMDSEntity_Edge] ));
+  myNbQuadEdge ->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Edge] ));
+
+  // faces
+  myNbFace     ->setText( QString("%1").arg( theInfo[SMDSEntity_Triangle] +
+                                             theInfo[SMDSEntity_Quad_Triangle] +
+                                             theInfo[SMDSEntity_Quadrangle] +
+                                             theInfo[SMDSEntity_Quad_Quadrangle] +
+                                             theInfo[SMDSEntity_BiQuad_Quadrangle] +
+                                             theInfo[SMDSEntity_Polygon] ));
+  myNbLinFace  ->setText( QString("%1").arg( theInfo[SMDSEntity_Triangle] +
+                                             theInfo[SMDSEntity_Quadrangle] +
+                                             theInfo[SMDSEntity_Polygon] ));
+  myNbQuadFace ->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Triangle] +
+                                             theInfo[SMDSEntity_Quad_Quadrangle] +
+                                             theInfo[SMDSEntity_BiQuad_Quadrangle] ));
+
+  // volumes
+  myNbVolum    ->setText( QString("%1").arg( theInfo[SMDSEntity_Tetra] +
+                                             theInfo[SMDSEntity_Quad_Tetra] +
+                                             theInfo[SMDSEntity_Pyramid] +
+                                             theInfo[SMDSEntity_Quad_Pyramid] +
+                                             theInfo[SMDSEntity_Hexa] +
+                                             theInfo[SMDSEntity_Quad_Hexa] +
+                                             theInfo[SMDSEntity_TriQuad_Hexa] +
+                                             theInfo[SMDSEntity_Penta] +
+                                             theInfo[SMDSEntity_Quad_Penta] +
+                                             theInfo[SMDSEntity_Hexagonal_Prism] +
+                                             theInfo[SMDSEntity_Polyhedra] ));
+  myNbLinVolum ->setText( QString("%1").arg( theInfo[SMDSEntity_Tetra] +
+                                             theInfo[SMDSEntity_Pyramid] +
+                                             theInfo[SMDSEntity_Hexa] +
+                                             theInfo[SMDSEntity_Penta] +
+                                             theInfo[SMDSEntity_Polyhedra] ));
+  myNbQuadVolum->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Tetra] +
+                                             theInfo[SMDSEntity_Quad_Pyramid] +
+                                             theInfo[SMDSEntity_Quad_Hexa] +
+                                             theInfo[SMDSEntity_TriQuad_Hexa] +
+                                             theInfo[SMDSEntity_Quad_Penta] ));
+
+  if ( myFull )
+  {
+    // triangles
+    myNbTrai     ->setText( QString("%1").arg( theInfo[SMDSEntity_Triangle] +
+                                               theInfo[SMDSEntity_Quad_Triangle] ));
+    myNbLinTrai  ->setText( QString("%1").arg( theInfo[SMDSEntity_Triangle] ));
+    myNbQuadTrai ->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Triangle] ));
+    // quadrangles
+    myNbQuad     ->setText( QString("%1").arg( theInfo[SMDSEntity_Quadrangle] +
+                                               theInfo[SMDSEntity_Quad_Quadrangle] +
+                                               theInfo[SMDSEntity_BiQuad_Quadrangle] ));
+    myNbLinQuad  ->setText( QString("%1").arg( theInfo[SMDSEntity_Quadrangle] ));
+    myNbQuadQuad ->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Quadrangle] +
+                                               theInfo[SMDSEntity_BiQuad_Quadrangle]));
+    // poligones
+    myNbPolyg    ->setText( QString("%1").arg( theInfo[SMDSEntity_Polygon] ));
+
+    // tetras
+    myNbTetra    ->setText( QString("%1").arg( theInfo[SMDSEntity_Tetra] +
+                                               theInfo[SMDSEntity_Quad_Tetra] ));
+    myNbLinTetra ->setText( QString("%1").arg( theInfo[SMDSEntity_Tetra] ));
+    myNbQuadTetra->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Tetra] ));
+    // hexas
+    myNbHexa     ->setText( QString("%1").arg( theInfo[SMDSEntity_Hexa] +
+                                               theInfo[SMDSEntity_TriQuad_Hexa],
+                                               theInfo[SMDSEntity_Quad_Hexa] ));
+    myNbLinHexa  ->setText( QString("%1").arg( theInfo[SMDSEntity_Hexa] ));
+    myNbQuadHexa ->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Hexa] +
+                                               theInfo[SMDSEntity_TriQuad_Hexa] ));
+    // pyras
+    myNbPyra     ->setText( QString("%1").arg( theInfo[SMDSEntity_Pyramid] +
+                                               theInfo[SMDSEntity_Quad_Pyramid] ));
+    myNbLinPyra  ->setText( QString("%1").arg( theInfo[SMDSEntity_Pyramid] ));
+    myNbQuadPyra ->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Pyramid] ));
+    // prisms
+    myNbPrism    ->setText( QString("%1").arg( theInfo[SMDSEntity_Penta] +
+                                               theInfo[SMDSEntity_Quad_Penta] ));
+    myNbLinPrism ->setText( QString("%1").arg( theInfo[SMDSEntity_Penta] ));
+    myNbQuadPrism->setText( QString("%1").arg( theInfo[SMDSEntity_Quad_Penta] ));
+    // octahedra
+    myNbHexaPrism->setText( QString("%1").arg( theInfo[ SMDSEntity_Hexagonal_Prism ]));
+    // polyedres
+    myNbPolyh    ->setText( QString("%1").arg( theInfo[SMDSEntity_Polyhedra] ));
+  }
+}
diff --git a/src/SMESHGUI/SMESHGUI_MeshInfosBox.h b/src/SMESHGUI/SMESHGUI_MeshInfosBox.h
new file mode 100644 (file)
index 0000000..a90a37b
--- /dev/null
@@ -0,0 +1,88 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+// File   : SMESHGUI_MeshInfosBox.h
+// Author : Edward AGAPOV, Open CASCADE S.A.S.
+//
+#ifndef SMESHGUI_MeshInfosBox_H
+#define SMESHGUI_MeshInfosBox_H
+
+// SMESH includes
+#include "SMESH_SMESHGUI.hxx"
+
+// Qt includes
+#include <QGroupBox>
+
+// IDL includes
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+
+class QLabel;
+
+/*!
+ * \brief Box showing mesh info
+ */
+
+class SMESHGUI_EXPORT SMESHGUI_MeshInfosBox : public QGroupBox
+{
+  Q_OBJECT
+
+public:
+  SMESHGUI_MeshInfosBox( const bool, QWidget* );
+
+  void    SetMeshInfo( const SMESH::long_array& theInfo );
+
+private:
+  bool    myFull;
+  QLabel* myNbNode;
+  QLabel* my0DElem;
+  QLabel* myBall;
+  QLabel* myNbEdge;
+  QLabel* myNbLinEdge;
+  QLabel* myNbQuadEdge;
+  QLabel* myNbTrai;
+  QLabel* myNbLinTrai;
+  QLabel* myNbQuadTrai;
+  QLabel* myNbQuad;
+  QLabel* myNbLinQuad;
+  QLabel* myNbQuadQuad;
+  QLabel* myNbFace;
+  QLabel* myNbLinFace;
+  QLabel* myNbQuadFace;
+  QLabel* myNbPolyg;
+  QLabel* myNbHexa;
+  QLabel* myNbLinHexa;
+  QLabel* myNbQuadHexa;
+  QLabel* myNbTetra;
+  QLabel* myNbLinTetra;
+  QLabel* myNbQuadTetra;
+  QLabel* myNbPyra;
+  QLabel* myNbLinPyra;
+  QLabel* myNbQuadPyra;
+  QLabel* myNbPrism;
+  QLabel* myNbLinPrism;
+  QLabel* myNbQuadPrism;
+  QLabel* myNbVolum;
+  QLabel* myNbLinVolum;
+  QLabel* myNbQuadVolum;
+  QLabel* myNbHexaPrism;
+  QLabel* myNbPolyh;
+};
+
+#endif // SMESHGUI_MeshInfosBox_H
diff --git a/src/SMESHGUI/SMESHGUI_MeshInfosDlg.cxx b/src/SMESHGUI/SMESHGUI_MeshInfosDlg.cxx
deleted file mode 100644 (file)
index 0051830..0000000
+++ /dev/null
@@ -1,645 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-// SMESH SMESHGUI : GUI for SMESH component
-// File   : SMESHGUI_MeshInfosDlg.cxx
-// Author : Nicolas BARBEROU
-// SMESH includes
-//
-#include "SMESHGUI_MeshInfosDlg.h"
-
-#include "SMESHGUI.h"
-#include "SMESHGUI_Utils.h"
-
-// SALOME GUI includes
-#include <SUIT_Desktop.h>
-#include <SUIT_ResourceMgr.h>
-#include <SUIT_OverrideCursor.h>
-#include <SUIT_Session.h>
-#include <SUIT_MessageBox.h>
-
-#include <LightApp_SelectionMgr.h>
-#include <LightApp_Application.h>
-#include <SALOME_ListIO.hxx>
-
-// SALOME KERNEL includes
-#include <SALOMEDSClient_Study.hxx>
-
-// Qt includes
-#include <QGroupBox>
-#include <QLabel>
-#include <QFrame>
-#include <QStackedWidget>
-#include <QVBoxLayout>
-#include <QHBoxLayout>
-#include <QGridLayout>
-#include <QPushButton>
-#include <QKeyEvent>
-
-// IDL includes
-#include <SALOMEconfig.h>
-#include CORBA_SERVER_HEADER(SMESH_Mesh)
-#include CORBA_SERVER_HEADER(SMESH_Group)
-
-#define COLONIZE(str)   (QString(str).contains(":") > 0 ? QString(str) : QString(str) + " :" )
-#define SPACING 6
-#define MARGIN  11
-
-//=================================================================================
-// function : SMESHGUI_MeshInfosDlg()
-// purpose  : Constructor
-//=================================================================================
-SMESHGUI_MeshInfosDlg::SMESHGUI_MeshInfosDlg(SMESHGUI* theModule): 
-  QDialog(SMESH::GetDesktop(theModule)),
-  mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
-  mySMESHGUI(theModule)
-{
-  setModal( false );
-  setAttribute( Qt::WA_DeleteOnClose, true );
-  setWindowTitle(tr("SMESH_MESHINFO_TITLE"));
-  setSizeGripEnabled(true);
-
-  myStartSelection = true;
-  myIsActiveWindow = true;
-
-  QVBoxLayout* aTopLayout = new QVBoxLayout(this);
-  aTopLayout->setSpacing(SPACING);  aTopLayout->setMargin(MARGIN);
-
-  // select button & label
-  QPixmap image0(SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH",tr("ICON_SELECT")));
-  mySelectBtn = new QPushButton(this);
-  mySelectBtn->setIcon(image0);
-  mySelectBtn->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
-
-  mySelectLab = new QLabel(this);
-  mySelectLab->setAlignment(Qt::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 QStackedWidget(this);
-
-  // no valid selection
-  QWidget* myBadWidget = new QWidget(myWGStack);
-  QVBoxLayout* aBadLayout = new QVBoxLayout(myBadWidget);
-  QLabel* myBadLab = new QLabel(tr("SMESH_BAD_SELECTION"), myBadWidget);
-  myBadLab->setAlignment(Qt::AlignCenter);
-  myBadLab->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
-  aBadLayout->addWidget(myBadLab);
-  myWGStack->addWidget(myBadWidget);
-
-  // mesh
-  myMeshWidget = new QWidget(myWGStack);
-  QGridLayout* aMeshLayout = new QGridLayout(myMeshWidget);
-  aMeshLayout->setSpacing(SPACING);  aMeshLayout->setMargin(0);
-  myWGStack->addWidget(myMeshWidget);
-
-  // --> name
-  QLabel* myMeshNameLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_NAME")), myMeshWidget);
-  myMeshName    = new QLabel(myMeshWidget);
-  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);
-  myMeshNbNodes    = new QLabel(myMeshWidget);
-  myMeshNbNodes->setMinimumWidth(100);
-
-  // --> header with orders
-  QLabel* myMeshOrder0Lab = new QLabel(tr("SMESH_MESHINFO_ORDER0"), myMeshWidget);
-  QLabel* myMeshOrder1Lab = new QLabel(tr("SMESH_MESHINFO_ORDER1"), myMeshWidget);
-  QLabel* myMeshOrder2Lab = new QLabel(tr("SMESH_MESHINFO_ORDER2"), myMeshWidget);
-  QFont fnti = myMeshOrder0Lab->font(); fnti.setItalic(true);
-  myMeshOrder0Lab->setFont(fnti);
-  myMeshOrder1Lab->setFont(fnti);
-  myMeshOrder2Lab->setFont(fnti);
-
-  // --> edges
-  QLabel* myMeshNbEdgesLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_EDGES")), myMeshWidget);
-  myMeshNbEdges    = new QLabel(myMeshWidget);
-  myMeshNbEdges->setMinimumWidth(100);
-  myMeshNbEdges1   = new QLabel(myMeshWidget);
-  myMeshNbEdges1->setMinimumWidth(100);
-  myMeshNbEdges2   = new QLabel(myMeshWidget);
-  myMeshNbEdges2->setMinimumWidth(100);
-
-  // --> faces
-  myMeshFacesGroup = new QGroupBox(tr("SMESH_MESHINFO_FACES"), myMeshWidget);
-  QGridLayout* myMeshFacesGroupLayout = new QGridLayout(myMeshFacesGroup);
-  myMeshFacesGroupLayout->setSpacing(SPACING);  myMeshFacesGroupLayout->setMargin(MARGIN);
-
-  // --> faces --> total
-  QLabel* myMeshNbFacesLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_TOTAL")), myMeshFacesGroup);
-  myMeshNbFacesLab->setFont(fnt);
-  myMeshNbFaces    = new QLabel(myMeshFacesGroup);
-  myMeshNbFaces->setMinimumWidth(100);
-  myMeshNbFaces->setFont(fnt);
-  myMeshNbFaces1   = new QLabel(myMeshFacesGroup);
-  myMeshNbFaces1->setMinimumWidth(100);
-  myMeshNbFaces1->setFont(fnt);
-  myMeshNbFaces2   = new QLabel(myMeshFacesGroup);
-  myMeshNbFaces2->setMinimumWidth(100);
-  myMeshNbFaces2->setFont(fnt);
-
-  // --> faces --> triangles
-  QLabel* myMeshNbTrianglesLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_TRIANGLES")), myMeshFacesGroup);
-  myMeshNbTriangles    = new QLabel(myMeshFacesGroup);
-  myMeshNbTriangles->setMinimumWidth(100);
-  myMeshNbTriangles1   = new QLabel(myMeshFacesGroup);
-  myMeshNbTriangles1->setMinimumWidth(100);
-  myMeshNbTriangles2   = new QLabel(myMeshFacesGroup);
-  myMeshNbTriangles2->setMinimumWidth(100);
-
-  // --> faces --> quadrangles
-  QLabel* myMeshNbQuadranglesLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_QUADRANGLES")), myMeshFacesGroup);
-  myMeshNbQuadrangles    = new QLabel(myMeshFacesGroup);
-  myMeshNbQuadrangles->setMinimumWidth(100);
-  myMeshNbQuadrangles1   = new QLabel(myMeshFacesGroup);
-  myMeshNbQuadrangles1->setMinimumWidth(100);
-  myMeshNbQuadrangles2   = new QLabel(myMeshFacesGroup);
-  myMeshNbQuadrangles2->setMinimumWidth(100);
-
-  // --> faces --> polygons
-  QLabel* myMeshNbPolygonesLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_POLYGONES" ) ), myMeshFacesGroup );
-  myMeshNbPolygones      = new QLabel( myMeshFacesGroup );
-  myMeshNbPolygones->setMinimumWidth( 100 );
-
-  myMeshFacesGroupLayout->addWidget(myMeshNbFacesLab,       0, 0);
-  myMeshFacesGroupLayout->addWidget(myMeshNbFaces,          0, 1);
-  myMeshFacesGroupLayout->addWidget(myMeshNbFaces1,         0, 2);
-  myMeshFacesGroupLayout->addWidget(myMeshNbFaces2,         0, 3);
-  myMeshFacesGroupLayout->addWidget(myMeshNbTrianglesLab,   1, 0);
-  myMeshFacesGroupLayout->addWidget(myMeshNbTriangles,      1, 1);
-  myMeshFacesGroupLayout->addWidget(myMeshNbTriangles1,     1, 2);
-  myMeshFacesGroupLayout->addWidget(myMeshNbTriangles2,     1, 3);
-  myMeshFacesGroupLayout->addWidget(myMeshNbQuadranglesLab, 2, 0);
-  myMeshFacesGroupLayout->addWidget(myMeshNbQuadrangles,    2, 1);
-  myMeshFacesGroupLayout->addWidget(myMeshNbQuadrangles1,   2, 2);
-  myMeshFacesGroupLayout->addWidget(myMeshNbQuadrangles2,   2, 3);
-  myMeshFacesGroupLayout->addWidget(myMeshNbPolygonesLab,   3, 0);
-  myMeshFacesGroupLayout->addWidget(myMeshNbPolygones,      3, 1);
-  
-  // --> volumes
-  myMeshVolumesGroup = new QGroupBox(tr("SMESH_MESHINFO_VOLUMES"), myMeshWidget);
-  QGridLayout* myMeshVolumesGroupLayout = new QGridLayout(myMeshVolumesGroup);
-  myMeshVolumesGroupLayout->setSpacing(SPACING);  myMeshVolumesGroupLayout->setMargin(MARGIN);
-
-  // --> volumes --> total
-  QLabel* myMeshNbVolumesLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_TOTAL")), myMeshVolumesGroup);
-  myMeshNbVolumesLab->setFont(fnt);
-  myMeshNbVolumes    = new QLabel(myMeshVolumesGroup);
-  myMeshNbVolumes->setMinimumWidth(100);
-  myMeshNbVolumes->setFont(fnt);
-  myMeshNbVolumes1   = new QLabel(myMeshVolumesGroup);
-  myMeshNbVolumes1->setMinimumWidth(100);
-  myMeshNbVolumes1->setFont(fnt);
-  myMeshNbVolumes2   = new QLabel(myMeshVolumesGroup);
-  myMeshNbVolumes2->setMinimumWidth(100);
-  myMeshNbVolumes2->setFont(fnt);
-
-  // --> volumes --> tetrahedrons
-  QLabel* myMeshNbTetraLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_TETRAS")), myMeshVolumesGroup);
-  myMeshNbTetra    = new QLabel(myMeshVolumesGroup);
-  myMeshNbTetra->setMinimumWidth(100);
-  myMeshNbTetra1   = new QLabel(myMeshVolumesGroup);
-  myMeshNbTetra1->setMinimumWidth(100);
-  myMeshNbTetra2   = new QLabel(myMeshVolumesGroup);
-  myMeshNbTetra2->setMinimumWidth(100);
-
-  // --> volumes --> hexahedrons
-  QLabel* myMeshNbHexaLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_HEXAS")), myMeshVolumesGroup);
-  myMeshNbHexa    = new QLabel(myMeshVolumesGroup);
-  myMeshNbHexa->setMinimumWidth(100);
-  myMeshNbHexa1   = new QLabel(myMeshVolumesGroup);
-  myMeshNbHexa1->setMinimumWidth(100);
-  myMeshNbHexa2   = new QLabel(myMeshVolumesGroup);
-  myMeshNbHexa2->setMinimumWidth(100);
-
-  // --> volumes --> prisms
-  QLabel* myMeshNbPrismLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_PRISMS")), myMeshVolumesGroup);
-  myMeshNbPrism    = new QLabel(myMeshVolumesGroup);
-  myMeshNbPrism->setMinimumWidth(100);
-  myMeshNbPrism1   = new QLabel(myMeshVolumesGroup);
-  myMeshNbPrism1->setMinimumWidth(100);
-  myMeshNbPrism2   = new QLabel(myMeshVolumesGroup);
-  myMeshNbPrism2->setMinimumWidth(100);
-
-  // --> volumes --> pyramids
-  QLabel* myMeshNbPyraLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_PYRAS")), myMeshVolumesGroup);
-  myMeshNbPyra    = new QLabel(myMeshVolumesGroup);
-  myMeshNbPyra->setMinimumWidth(100);
-  myMeshNbPyra1   = new QLabel(myMeshVolumesGroup);
-  myMeshNbPyra1->setMinimumWidth(100);
-  myMeshNbPyra2   = new QLabel(myMeshVolumesGroup);
-  myMeshNbPyra2->setMinimumWidth(100);
-
-  // --> volumes --> polyherones
-  QLabel* myMeshNbPolyhedronesLab = new QLabel( COLONIZE( tr( "SMESH_MESHINFO_POLYEDRES" ) ), myMeshVolumesGroup );
-  myMeshNbPolyhedrones = new QLabel( myMeshVolumesGroup );
-  myMeshNbPolyhedrones->setMinimumWidth( 100 );
-
-  myMeshVolumesGroupLayout->addWidget(myMeshNbVolumesLab,      0, 0);
-  myMeshVolumesGroupLayout->addWidget(myMeshNbVolumes,         0, 1);
-  myMeshVolumesGroupLayout->addWidget(myMeshNbVolumes1,        0, 2);
-  myMeshVolumesGroupLayout->addWidget(myMeshNbVolumes2,        0, 3);
-  myMeshVolumesGroupLayout->addWidget(myMeshNbTetraLab,        1, 0);
-  myMeshVolumesGroupLayout->addWidget(myMeshNbTetra,           1, 1);
-  myMeshVolumesGroupLayout->addWidget(myMeshNbTetra1,          1, 2);
-  myMeshVolumesGroupLayout->addWidget(myMeshNbTetra2,          1, 3);
-  myMeshVolumesGroupLayout->addWidget(myMeshNbHexaLab,         2, 0);
-  myMeshVolumesGroupLayout->addWidget(myMeshNbHexa,            2, 1);
-  myMeshVolumesGroupLayout->addWidget(myMeshNbHexa1,           2, 2);
-  myMeshVolumesGroupLayout->addWidget(myMeshNbHexa2,           2, 3);
-  myMeshVolumesGroupLayout->addWidget(myMeshNbPrismLab,        3, 0);
-  myMeshVolumesGroupLayout->addWidget(myMeshNbPrism,           3, 1);
-  myMeshVolumesGroupLayout->addWidget(myMeshNbPrism1,          3, 2);
-  myMeshVolumesGroupLayout->addWidget(myMeshNbPrism2,          3, 3);
-  myMeshVolumesGroupLayout->addWidget(myMeshNbPyraLab,         4, 0);
-  myMeshVolumesGroupLayout->addWidget(myMeshNbPyra,            4, 1);
-  myMeshVolumesGroupLayout->addWidget(myMeshNbPyra1,           4, 2);
-  myMeshVolumesGroupLayout->addWidget(myMeshNbPyra2,           4, 3);
-  myMeshVolumesGroupLayout->addWidget(myMeshNbPolyhedronesLab, 5, 0);
-  myMeshVolumesGroupLayout->addWidget(myMeshNbPolyhedrones,    5, 1);
-
-  aMeshLayout->addWidget(myMeshNameLab,      0, 0);
-  aMeshLayout->addWidget(myMeshName,         0, 1);
-  aMeshLayout->addWidget(line1,              1, 0, 1, 2);
-  aMeshLayout->addWidget(myMeshNbNodesLab,   2, 0);
-  aMeshLayout->addWidget(myMeshNbNodes,      2, 1);
-  aMeshLayout->addWidget(myMeshOrder0Lab,    3, 1);
-  aMeshLayout->addWidget(myMeshOrder1Lab,    3, 2);
-  aMeshLayout->addWidget(myMeshOrder2Lab,    3, 3);
-  aMeshLayout->addWidget(myMeshNbEdgesLab,   4, 0);
-  aMeshLayout->addWidget(myMeshNbEdges,      4, 1);
-  aMeshLayout->addWidget(myMeshNbEdges1,     4, 2);
-  aMeshLayout->addWidget(myMeshNbEdges2,     4, 3);
-  aMeshLayout->addWidget(myMeshFacesGroup,   5, 0, 1, 4);
-  aMeshLayout->addWidget(myMeshVolumesGroup, 6, 0, 1, 4);
-  aMeshLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 7, 0);
-
-  // submesh
-  mySubMeshWidget = new QWidget(myWGStack);
-  QGridLayout* aSubMeshLayout = new QGridLayout(mySubMeshWidget);
-  aSubMeshLayout->setSpacing(SPACING);  aSubMeshLayout->setMargin(0);
-  myWGStack->addWidget(mySubMeshWidget);
-
-  // --> name
-  QLabel* mySubMeshNameLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_NAME")), mySubMeshWidget);
-  mySubMeshName    = new QLabel(mySubMeshWidget);
-  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);
-  mySubMeshNbNodes    = new QLabel(mySubMeshWidget);
-  mySubMeshNbNodes->setMinimumWidth(100);
-
-  // --> elements
-  mySubMeshElementsGroup = new QGroupBox(tr("SMESH_MESHINFO_ELEMENTS"), mySubMeshWidget);
-  QGridLayout* mySubMeshElementsGroupLayout = new QGridLayout(mySubMeshElementsGroup);
-  mySubMeshElementsGroupLayout->setSpacing(SPACING);  mySubMeshElementsGroupLayout->setMargin(MARGIN);
-
-  // --> elements --> total
-  QLabel* mySubMeshNbElementsLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_TOTAL")), mySubMeshElementsGroup);
-  mySubMeshNbElementsLab->setFont(fnt);
-  mySubMeshNbElements    = new QLabel(mySubMeshElementsGroup);
-  mySubMeshNbElements->setMinimumWidth(100);
-  mySubMeshNbElements->setFont(fnt);
-
-  // --> elements --> edges
-  QLabel* mySubMeshNbEdgesLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_EDGES")), mySubMeshElementsGroup);
-  mySubMeshNbEdges    = new QLabel(mySubMeshElementsGroup);
-  mySubMeshNbEdges->setMinimumWidth(100);
-
-  // --> elements --> faces
-  QLabel* mySubMeshNbFacesLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_FACES")), mySubMeshElementsGroup);
-  mySubMeshNbFaces    = new QLabel(mySubMeshElementsGroup);
-  mySubMeshNbFaces->setMinimumWidth(100);
-
-  // --> elements --> volumes
-  QLabel* mySubMeshNbVolumesLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_VOLUMES")), mySubMeshElementsGroup);
-  mySubMeshNbVolumes    = new QLabel(mySubMeshElementsGroup);
-  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->addWidget(line2,                  1, 0, 1, 2);
-  aSubMeshLayout->addWidget(mySubMeshNbNodesLab,    2, 0);
-  aSubMeshLayout->addWidget(mySubMeshNbNodes,       2, 1);
-  aSubMeshLayout->addWidget(mySubMeshElementsGroup, 3, 0, 1, 2);
-  aSubMeshLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 4, 0);
-
-  // group
-  myGroupWidget = new QWidget(myWGStack);
-  QGridLayout* myGroupWidgetLayout = new QGridLayout(myGroupWidget);
-  myGroupWidgetLayout->setSpacing(SPACING);  myGroupWidgetLayout->setMargin(0);
-  myWGStack->addWidget(myGroupWidget);
-
-  // --> name
-  QLabel* myGroupNameLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_NAME")), myGroupWidget);
-  myGroupName = new QLabel(myGroupWidget);
-  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);
-  myGroupType = new QLabel(myGroupWidget);
-  myGroupType->setMinimumWidth(100);
-
-  // --> number of entities
-  QLabel* myGroupNbLab = new QLabel(COLONIZE(tr("SMESH_MESHINFO_ENTITIES")), myGroupWidget);
-  myGroupNb = new QLabel(myGroupWidget);
-  myGroupNb->setMinimumWidth(100);
-
-  myGroupWidgetLayout->addWidget(myGroupNameLab, 0, 0);
-  myGroupWidgetLayout->addWidget(myGroupName,    0, 1);
-  myGroupWidgetLayout->addWidget(line3,          1, 0, 1, 2);
-  myGroupWidgetLayout->addWidget(myGroupTypeLab, 2, 0);
-  myGroupWidgetLayout->addWidget(myGroupType,    2, 1);
-  myGroupWidgetLayout->addWidget(myGroupNbLab,   3, 0);
-  myGroupWidgetLayout->addWidget(myGroupNb,      3, 1);
-  myGroupWidgetLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 4, 0);
-
-  // buttons
-  myButtonsGroup = new QGroupBox(this);
-  QHBoxLayout* myButtonsGroupLayout = new QHBoxLayout(myButtonsGroup);
-  myButtonsGroupLayout->setSpacing(SPACING); myButtonsGroupLayout->setMargin(MARGIN);
-
-  // buttons --> OK and Help buttons
-  myOkBtn = new QPushButton(tr("SMESH_BUT_OK" ), myButtonsGroup);
-  myOkBtn->setAutoDefault(true); myOkBtn->setDefault(true);
-  myHelpBtn = new QPushButton(tr("SMESH_BUT_HELP" ), myButtonsGroup);
-  myHelpBtn->setAutoDefault(true);
-
-  myButtonsGroupLayout->addWidget(myOkBtn);
-  myButtonsGroupLayout->addSpacing(10);
-  myButtonsGroupLayout->addStretch();
-  myButtonsGroupLayout->addWidget(myHelpBtn);
-
-  aTopLayout->addLayout(aSelectLayout);
-  aTopLayout->addWidget(myWGStack);
-  aTopLayout->addWidget(myButtonsGroup);
-
-  mySMESHGUI->SetActiveDialogBox(this);
-
-  // connect signals
-  connect(myOkBtn,                 SIGNAL(clicked()),                      this, SLOT(close()));
-  connect( myHelpBtn,              SIGNAL(clicked()),                      this, SLOT(onHelp()));
-  connect(mySelectBtn,             SIGNAL(clicked()),                      this, SLOT(onStartSelection()));
-  connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()),        this, SLOT(close()));
-  connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
-  connect(mySelectionMgr,          SIGNAL(currentSelectionChanged()),      this, SLOT(onSelectionChanged()));
-
-  // init dialog with current selection
-  onSelectionChanged();
-
-  myHelpFileName = "mesh_infos_page.html#advanced_mesh_infos_anchor";
-}
-
-//=================================================================================
-// function : ~SMESHGUI_MeshInfosDlg()
-// purpose  : Destructor
-//=================================================================================
-SMESHGUI_MeshInfosDlg::~SMESHGUI_MeshInfosDlg()
-{
-}
-
-//=================================================================================
-// function : DumpMeshInfos()
-// purpose  : 
-//=================================================================================
-void SMESHGUI_MeshInfosDlg::DumpMeshInfos()
-{
-  SUIT_OverrideCursor wc;
-
-  SALOME_ListIO aList;
-  mySelectionMgr->selectedObjects(aList);
-
-  int nbSel = aList.Extent();
-  if (nbSel == 1) {
-    myStartSelection = false;
-    mySelectLab->setText("");
-    Handle(SALOME_InteractiveObject) IObject = aList.First();
-    _PTR(SObject) aSO = SMESH::GetActiveStudyDocument()->FindObjectID(IObject->getEntry());
-    if (aSO) {
-      //CORBA::Object_var anObject = aSO->GetObject();
-      CORBA::Object_var anObject = SMESH::SObjectToObject(aSO);
-      if (!CORBA::is_nil(anObject)) {
-       SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(anObject);
-       if (!aMesh->_is_nil()) {
-         myWGStack->setCurrentWidget(myMeshWidget);
-         setWindowTitle(tr("SMESH_MESHINFO_TITLE") + " [" + tr("SMESH_OBJECT_MESH") + "]");
-         myMeshName->setText(aSO->GetName().c_str());
-         myMeshNbNodes->setNum((int)aMesh->NbNodes());
-         myMeshNbEdges->setNum((int)aMesh->NbEdges());
-         myMeshNbEdges1->setNum((int)aMesh->NbEdgesOfOrder(SMESH::ORDER_LINEAR));
-         myMeshNbEdges2->setNum((int)aMesh->NbEdgesOfOrder(SMESH::ORDER_QUADRATIC));
-         myMeshNbFaces->setNum((int)aMesh->NbFaces());
-         myMeshNbFaces1->setNum((int)aMesh->NbFacesOfOrder(SMESH::ORDER_LINEAR));
-         myMeshNbFaces2->setNum((int)aMesh->NbFacesOfOrder(SMESH::ORDER_QUADRATIC));
-         myMeshNbTriangles->setNum((int)aMesh->NbTriangles());
-         myMeshNbTriangles1->setNum((int)aMesh->NbTrianglesOfOrder(SMESH::ORDER_LINEAR));
-         myMeshNbTriangles2->setNum((int)aMesh->NbTrianglesOfOrder(SMESH::ORDER_QUADRATIC));
-         myMeshNbQuadrangles->setNum((int)aMesh->NbQuadrangles());
-         myMeshNbQuadrangles1->setNum((int)aMesh->NbQuadranglesOfOrder(SMESH::ORDER_LINEAR));
-         myMeshNbQuadrangles2->setNum((int)aMesh->NbQuadranglesOfOrder(SMESH::ORDER_QUADRATIC));
-         myMeshNbPolygones->setNum( (int)aMesh->NbPolygons() );
-         myMeshNbVolumes->setNum((int)aMesh->NbVolumes());
-         myMeshNbVolumes1->setNum((int)aMesh->NbVolumesOfOrder(SMESH::ORDER_LINEAR));
-         myMeshNbVolumes2->setNum((int)aMesh->NbVolumesOfOrder(SMESH::ORDER_QUADRATIC));
-         myMeshNbTetra->setNum((int)aMesh->NbTetras());
-         myMeshNbTetra1->setNum((int)aMesh->NbTetrasOfOrder(SMESH::ORDER_LINEAR));
-         myMeshNbTetra2->setNum((int)aMesh->NbTetrasOfOrder(SMESH::ORDER_QUADRATIC));
-         myMeshNbHexa->setNum((int)aMesh->NbHexas());
-         myMeshNbHexa1->setNum((int)aMesh->NbHexasOfOrder(SMESH::ORDER_LINEAR));
-         myMeshNbHexa2->setNum((int)aMesh->NbHexasOfOrder(SMESH::ORDER_QUADRATIC));
-         myMeshNbPrism->setNum((int)aMesh->NbPrisms());
-         myMeshNbPrism1->setNum((int)aMesh->NbPrismsOfOrder(SMESH::ORDER_LINEAR));
-         myMeshNbPrism2->setNum((int)aMesh->NbPrismsOfOrder(SMESH::ORDER_QUADRATIC));
-         myMeshNbPyra->setNum((int)aMesh->NbPyramids());
-         myMeshNbPyra1->setNum((int)aMesh->NbPyramidsOfOrder(SMESH::ORDER_LINEAR));
-         myMeshNbPyra2->setNum((int)aMesh->NbPyramidsOfOrder(SMESH::ORDER_QUADRATIC));
-         myMeshNbPolyhedrones->setNum( (int)aMesh->NbPolyhedrons() );
-         return;
-       }
-       SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow(anObject);
-       if (!aSubMesh->_is_nil()) {
-         myWGStack->setCurrentWidget(mySubMeshWidget);
-         setWindowTitle(tr("SMESH_MESHINFO_TITLE") + " [" + tr("SMESH_SUBMESH") + "]");
-         mySubMeshName->setText(aSO->GetName().c_str());
-         mySubMeshNbNodes->setNum((int)aSubMesh->GetNumberOfNodes(true));
-         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_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(anObject);
-       if (!aGroup->_is_nil()) {
-         myWGStack->setCurrentWidget(myGroupWidget);
-         setWindowTitle(tr("SMESH_MESHINFO_TITLE") + " [" + tr("SMESH_GROUP") + "]");
-         myGroupName->setText(aSO->GetName().c_str());
-         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.toLatin1().data()));
-         myGroupNb->setNum((int)aGroup->Size());
-         return;
-       }
-      }
-    }
-  }
-  myWGStack->setCurrentIndex(0);
-  setWindowTitle(tr("SMESH_MESHINFO_TITLE"));
-}
-
-//=================================================================================
-// function : SelectionIntoArgument()
-// purpose  : Called when selection has changed
-//=================================================================================
-void SMESHGUI_MeshInfosDlg::onSelectionChanged()
-{
-  if (myStartSelection)
-    DumpMeshInfos();
-}
-
-//=================================================================================
-// function : closeEvent()
-// purpose  :
-//=================================================================================
-void SMESHGUI_MeshInfosDlg::closeEvent(QCloseEvent* e)
-{
-  mySMESHGUI->ResetState();
-  QDialog::closeEvent(e);
-}
-
-//=================================================================================
-// function : windowActivationChange()
-// purpose  : called when window is activated/deactivated
-//=================================================================================
-void SMESHGUI_MeshInfosDlg::windowActivationChange(bool oldActive)
-{
-  QDialog::windowActivationChange(oldActive);
-  if (isActiveWindow() && myIsActiveWindow != isActiveWindow())
-    ActivateThisDialog();
-  myIsActiveWindow = isActiveWindow();
-}
-
-//=================================================================================
-// function : DeactivateActiveDialog()
-// purpose  :
-//=================================================================================
-void SMESHGUI_MeshInfosDlg::DeactivateActiveDialog()
-{
-  disconnect(mySelectionMgr, 0, this, 0);
-}
-
-//=================================================================================
-// function : ActivateThisDialog()
-// purpose  :
-//=================================================================================
-void SMESHGUI_MeshInfosDlg::ActivateThisDialog()
-{
-  /* Emit a signal to deactivate any active dialog */
-  mySMESHGUI->EmitSignalDeactivateDialog();
-  connect(mySelectionMgr, 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"));
-}
-
-//=================================================================================
-// function : onHelp()
-// purpose  :
-//=================================================================================
-void SMESHGUI_MeshInfosDlg::onHelp()
-{
-  LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
-  if (app) 
-    app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
-  else {
-    QString platform;
-#ifdef WIN32
-    platform = "winapplication";
-#else
-    platform = "application";
-#endif
-    SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser", 
-                                                                platform)).
-                            arg(myHelpFileName));
-  }
-}
-
-//=================================================================================
-// function : keyPressEvent()
-// purpose  :
-//=================================================================================
-void SMESHGUI_MeshInfosDlg::keyPressEvent( QKeyEvent* e )
-{
-  QDialog::keyPressEvent( e );
-  if ( e->isAccepted() )
-    return;
-
-  if ( e->key() == Qt::Key_F1 ) {
-    e->accept();
-    onHelp();
-  }
-}
diff --git a/src/SMESHGUI/SMESHGUI_MeshInfosDlg.h b/src/SMESHGUI/SMESHGUI_MeshInfosDlg.h
deleted file mode 100644 (file)
index b2b84c9..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-// SMESH SMESHGUI : GUI for SMESH component
-// File   : SMESHGUI_MeshInfosDlg.h
-// Author : Nicolas BARBEROU
-//
-#ifndef SMESHGUI_MESHINFOSDLG_H
-#define SMESHGUI_MESHINFOSDLG_H
-
-// SMESH includes
-#include "SMESH_SMESHGUI.hxx"
-
-// Qt includes
-#include <QDialog>
-
-class QGroupBox;
-class QLabel;
-class QPushButton;
-class QStackedWidget;
-
-class LightApp_SelectionMgr;
-class SMESHGUI;
-
-class SMESHGUI_EXPORT SMESHGUI_MeshInfosDlg : public QDialog
-{ 
-  Q_OBJECT
-
-public:
-  SMESHGUI_MeshInfosDlg( SMESHGUI* );
-  ~SMESHGUI_MeshInfosDlg();
-
-protected:
-  void                    closeEvent( QCloseEvent* );
-  void                    keyPressEvent( QKeyEvent* );
-  void                    windowActivationChange( bool );
-  void                    DumpMeshInfos();
-
-private slots:
-  void                    onSelectionChanged();
-  void                    DeactivateActiveDialog();
-  void                    ActivateThisDialog();
-  void                    onStartSelection();
-  void                    onHelp();
-
-private:
-  SMESHGUI*               mySMESHGUI;
-  LightApp_SelectionMgr*  mySelectionMgr; 
-  bool                    myStartSelection;
-  bool                    myIsActiveWindow;
-  
-  QPushButton*            mySelectBtn;
-  QLabel*                 mySelectLab;
-  
-  QStackedWidget*         myWGStack;
-  
-  QWidget*                myMeshWidget;
-  QLabel*                 myMeshName;
-  QLabel*                 myMeshNbNodes;
-  QLabel*                 myMeshNbEdges;
-  QLabel*                 myMeshNbEdges1;
-  QLabel*                 myMeshNbEdges2;
-  QGroupBox*              myMeshFacesGroup;
-  QLabel*                 myMeshNbFaces;
-  QLabel*                 myMeshNbFaces1;
-  QLabel*                 myMeshNbFaces2;
-  QLabel*                 myMeshNbTriangles;
-  QLabel*                 myMeshNbTriangles1;
-  QLabel*                 myMeshNbTriangles2;
-  QLabel*                 myMeshNbQuadrangles;
-  QLabel*                 myMeshNbQuadrangles1;
-  QLabel*                 myMeshNbQuadrangles2;
-  QLabel*                 myMeshNbPolygones;
-  QGroupBox*              myMeshVolumesGroup;
-  QLabel*                 myMeshNbVolumes;
-  QLabel*                 myMeshNbVolumes1;
-  QLabel*                 myMeshNbVolumes2;
-  QLabel*                 myMeshNbTetra;
-  QLabel*                 myMeshNbTetra1;
-  QLabel*                 myMeshNbTetra2;
-  QLabel*                 myMeshNbHexa;
-  QLabel*                 myMeshNbHexa1;
-  QLabel*                 myMeshNbHexa2;
-  QLabel*                 myMeshNbPyra;
-  QLabel*                 myMeshNbPyra1;
-  QLabel*                 myMeshNbPyra2;
-  QLabel*                 myMeshNbPrism;
-  QLabel*                 myMeshNbPrism1;
-  QLabel*                 myMeshNbPrism2;
-  QLabel*                 myMeshNbPolyhedrones;
-  
-  QWidget*                mySubMeshWidget;
-  QLabel*                 mySubMeshName;
-  QLabel*                 mySubMeshNbNodes;
-  QGroupBox*              mySubMeshElementsGroup;
-  QLabel*                 mySubMeshNbElements;
-  QLabel*                 mySubMeshNbEdges;
-  QLabel*                 mySubMeshNbFaces;
-  QLabel*                 mySubMeshNbVolumes;
-
-  QWidget*                myGroupWidget;
-  QLabel*                 myGroupName;
-  QLabel*                 myGroupType;
-  QLabel*                 myGroupNb;
-
-  QGroupBox*              myButtonsGroup;
-  QPushButton*            myOkBtn;
-  QPushButton*            myHelpBtn;
-
-  QString                 myHelpFileName;
-};
-
-#endif // SMESHGUI_MESHINFOSDLG_H
index 351e6034e8b12e94b0b0515eed3163b2b07f10d7..9ad1a47fc5ae4d4a5ae928f3d6d315ce80107e92 100644 (file)
@@ -1,29 +1,28 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-// SMESH SMESHGUI : GUI for SMESH component
-// File   : SMESHGUI_MeshOp.cxx
-// Author : Sergey LITONIN, Open CASCADE S.A.S.
+//  File   : SMESHGUI_MeshOp.cxx
+//  Author : Sergey LITONIN, Open CASCADE S.A.S.
+
 // SMESH includes
-//
 #include "SMESHGUI_MeshOp.h"
 
 #include "SMESHGUI.h"
 // SALOME GUI includes
 #include <SalomeApp_Tools.h>
 #include <SalomeApp_Application.h>
+#include <LightApp_Application.h>
 #include <LightApp_SelectionMgr.h>
 #include <LightApp_UpdateFlags.h>
 #include <SUIT_MessageBox.h>
 #include <SUIT_OverrideCursor.h>
+#include <SUIT_Session.h>
 #include <SALOME_InteractiveObject.hxx>
 #include <SALOME_ListIO.hxx>
 
 #include <SALOMEconfig.h>
 #include CORBA_CLIENT_HEADER(SMESH_Gen)
 
+//To disable automatic genericobj management, the following line should be commented.
+//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
+#define WITHGENERICOBJ
+
 //================================================================================
 /*!
  * \brief Constructor
@@ -85,7 +90,8 @@ SMESHGUI_MeshOp::SMESHGUI_MeshOp( const bool theToCreate, const bool theIsMesh )
   myToCreate( theToCreate ),
   myIsMesh( theIsMesh ),
   myDlg( 0 ),
-  myShapeByMeshOp( 0 )
+  myShapeByMeshOp( 0 ),
+  myHypoSet( 0 )
 {
   if ( GeometryGUI::GetGeomGen()->_is_nil() )// check that GEOM_Gen exists
     GeometryGUI::InitGeomGen();
@@ -141,14 +147,21 @@ bool SMESHGUI_MeshOp::onApply()
   aMess = "";
   try
   {
+    QStringList anEntryList;
     if ( myToCreate && myIsMesh )
-      aResult = createMesh( aMess );
+      aResult = createMesh( aMess, anEntryList );
     if ( myToCreate && !myIsMesh )
-      aResult = createSubMesh( aMess );
+      aResult = createSubMesh( aMess, anEntryList );
     else if ( !myToCreate )
       aResult = editMeshOrSubMesh( aMess );
     if ( aResult )
+    {
+      SMESHGUI::Modified();
       update( UF_ObjBrowser | UF_Model );
+      if( LightApp_Application* anApp =
+          dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
+        myObjectToSelect = anApp->browseObjects( anEntryList, isApplyAndClose() );
+    }
   }
   catch ( const SALOME::SALOME_Exception& S_ex )
   {
@@ -232,14 +245,36 @@ void SMESHGUI_MeshOp::startOperation()
   else
     myDlg->activateObject( SMESHGUI_MeshDlg::Obj );
 
-  myDlg->setHypoSets( SMESH::GetHypothesesSets() );
-
   myDlg->setCurrentTab( SMESH::DIM_3D );
   myDlg->show();
-
+  myDlg->setGeomPopupEnabled(false);
   selectionDone();
 
   myIgnoreAlgoSelection = false;
+
+  myObjectToSelect.clear();
+}
+
+//=================================================================================
+/*!
+ * \brief Selects a recently created mesh or sub-mesh if necessary
+ *
+ * Virtual method redefined from base class called when operation is commited
+ * selects a recently created mesh or sub-mesh if necessary. Allows to perform
+ * selection when the custom selection filters are removed.
+ */
+//=================================================================================
+void SMESHGUI_MeshOp::commitOperation()
+{
+  SMESHGUI_SelectionOp::commitOperation();
+
+  if ( !myObjectToSelect.isEmpty() ) {
+    if ( LightApp_SelectionMgr* aSelectionMgr = selectionMgr() ) {
+      SUIT_DataOwnerPtrList aList;
+      aList.append( new LightApp_DataOwner( myObjectToSelect ) );
+      aSelectionMgr->setSelected( aList );
+    }
+  }
 }
 
 //================================================================================
@@ -271,11 +306,10 @@ SUIT_SelectionFilter* SMESHGUI_MeshOp::createFilter( const int theId ) const
 
 //================================================================================
 /*!
- * \brief check if selected shape is a subshape of the shape to mesh
+ * \brief check if selected shape is a sub-shape of the shape to mesh
   * \retval bool - check result
  */
 //================================================================================
-
 bool SMESHGUI_MeshOp::isSubshapeOk() const
 {
   if ( !myToCreate || myIsMesh ) // not submesh creation
@@ -338,11 +372,10 @@ bool SMESHGUI_MeshOp::isSubshapeOk() const
 //================================================================================
 /*!
  * \brief Return name of the algorithm that does not support submeshes and makes
- * submesh creation useless 
+ * submesh creation useless
  *  \retval char* - string is to be deleted!!!
  */
 //================================================================================
-
 char* SMESHGUI_MeshOp::isSubmeshIgnored() const
 {
   if ( myToCreate && !myIsMesh ) {
@@ -388,7 +421,6 @@ char* SMESHGUI_MeshOp::isSubmeshIgnored() const
  * \retval _PTR(SObject) - the found submesh SObject
  */
 //================================================================================
-
 _PTR(SObject) SMESHGUI_MeshOp::getSubmeshByGeom() const
 {
   QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
@@ -499,48 +531,52 @@ void SMESHGUI_MeshOp::selectionDone()
       }
 
       if (aSeq->length() > 0) {
-        shapeDim = 0;
+        shapeDim = -1;
         for (int iss = 0; iss < aSeq->length() && shapeDim < 3; iss++) {
           GEOM::GEOM_Object_var aGeomVar = aSeq[iss];
           switch ( aGeomVar->GetShapeType() ) {
           case GEOM::SOLID:  shapeDim = 3; break;
           case GEOM::SHELL:
-            {
-              //shapeDim = 3; // Bug 0016155: EDF PAL 447: If the shape is a Shell, disable 3D tab
-              shapeDim = (shapeDim < 2) ? 2 : shapeDim;
-              TopoDS_Shape aShape;
-              if (GEOMBase::GetShape(aGeomVar, aShape)) {
-                if (/*aShape.Closed()*/BRep_Tool::IsClosed(aShape))
-                  shapeDim = 3;
-              }
-            }
-            break;
-          case GEOM::FACE:   shapeDim = (shapeDim < 2) ? 2 : shapeDim; break;
+            // Bug 0016155: EDF PAL 447: If the shape is a Shell, disable 3D tab
+            // {
+            //   TopoDS_Shape aShape;
+            //   bool isClosed = GEOMBase::GetShape(aGeomVar, aShape) && /*aShape.Closed()*/BRep_Tool::IsClosed(aShape);
+            //   shapeDim = qMax(isClosed ? 3 : 2, shapeDim);
+            // }
+            // break;
+          case GEOM::FACE:   shapeDim = qMax(2, shapeDim); break;
           case GEOM::WIRE:
-          case GEOM::EDGE:   shapeDim = (shapeDim < 1) ? 1 : shapeDim; break;
-          case GEOM::VERTEX: break;
+          case GEOM::EDGE:   shapeDim = qMax(1, shapeDim); break;
+          case GEOM::VERTEX: shapeDim = qMax(0, shapeDim); break;
           default:
             {
               TopoDS_Shape aShape;
-              if (GEOMBase::GetShape(aGeomVar, aShape)) {
-                TopExp_Explorer exp (aShape, TopAbs_SHELL);
+              if (GEOMBase::GetShape(aGeomVar, aShape))
+              {
+                TopExp_Explorer exp (aShape, TopAbs_SOLID);
                 if (exp.More()) {
-                  //shapeDim = 3; // Bug 0016155: EDF PAL 447: If the shape is a Shell, disable 3D tab
-                  shapeDim = (shapeDim < 2) ? 2 : shapeDim;
-                  for (; exp.More() && shapeDim == 2; exp.Next()) {
-                    if (/*exp.Current().Closed()*/BRep_Tool::IsClosed(exp.Current()))
-                      shapeDim = 3;
-                  }
+                  shapeDim = 3;
                 }
+                // Bug 0016155: EDF PAL 447: If the shape is a Shell, disable 3D tab
+                // else if ( exp.Init( aShape, TopAbs_SHELL ), exp.More() )
+                // {
+                //   shapeDim = 2;
+                //   for (; exp.More() && shapeDim == 2; exp.Next()) {
+                //     if (/*exp.Current().Closed()*/BRep_Tool::IsClosed(exp.Current()))
+                //       shapeDim = 3;
+                //   }
+                // }
                 else if ( exp.Init( aShape, TopAbs_FACE ), exp.More() )
-                  shapeDim = (shapeDim < 2) ? 2 : shapeDim;
+                  shapeDim = qMax(2, shapeDim);
                 else if ( exp.Init( aShape, TopAbs_EDGE ), exp.More() )
-                  shapeDim = (shapeDim < 1) ? 1 : shapeDim;
-                else
-                  ;//shapeDim = 0;
+                  shapeDim = qMax(1, shapeDim);
+                else if ( exp.Init( aShape, TopAbs_VERTEX ), exp.More() )
+                  shapeDim = qMax(0, shapeDim);
               }
             }
           }
+          if ( shapeDim == 3 )
+            break;
         }
       }
       for (int i = SMESH::DIM_3D; i > shapeDim; i--) {
@@ -548,7 +584,7 @@ void SMESHGUI_MeshOp::selectionDone()
         onAlgoSelected(-1, i);
       }
       myDlg->setMaxHypoDim( shapeDim );
-
+      myDlg->setHypoSets( SMESH::GetHypothesesSets( shapeDim ));
 
       if (!myToCreate) // edition: read hypotheses
       {
@@ -575,11 +611,11 @@ void SMESHGUI_MeshOp::selectionDone()
             SMESH::SObjectToInterface<SMESH::SMESH_subMesh>( pSubmesh );
           bool editSubmesh = ( !sm->_is_nil() &&
                                SUIT_MessageBox::question( myDlg, tr( "SMESH_WARNING" ),
-                                                         tr( "EDIT_SUBMESH_QUESTION"),
-                                                         SUIT_MessageBox::Yes | 
-                                                         SUIT_MessageBox::No,
-                                                         SUIT_MessageBox::No )
-                              == SUIT_MessageBox::Yes );
+                                                          tr( "EDIT_SUBMESH_QUESTION"),
+                                                          SUIT_MessageBox::Yes |
+                                                          SUIT_MessageBox::No,
+                                                          SUIT_MessageBox::No )
+                               == SUIT_MessageBox::Yes );
           if ( editSubmesh )
           {
             selectionMgr()->clearFilters();
@@ -612,13 +648,19 @@ void SMESHGUI_MeshOp::selectionDone()
         QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
         if ( _PTR(SObject) pMesh = studyDS()->FindObjectID( aMeshEntry.toLatin1().data() )) {
           SMESH::SMESH_Mesh_var mesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>( pMesh );
-          if ( !mesh->_is_nil() )
+          if ( !mesh->_is_nil() ) {
+            //rnv: issue 21056: EDF 1608 SMESH: Dialog Box "Create Sub Mesh": focus should automatically switch to geometry
+            QString aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
+            _PTR(SObject) pGeom = studyDS()->FindObjectID( aGeomEntry.toLatin1().data() );
+            if ( !pGeom || GEOM::GEOM_Object::_narrow( _CAST( SObject,pGeom )->GetObject() )->_is_nil() )
+              myDlg->activateObject(SMESHGUI_MeshDlg::Geom);
             enable = ( shapeDim > 1 ) && ( mesh->NbEdges() > 0 );
+          }
         }
         myDlg->setGeomPopupEnabled( enable );
       }
     }
-    else {
+    else { // no geometry defined
       myDlg->enableTab( SMESH::DIM_3D );
       QStringList hypList;
       availableHyps( SMESH::DIM_3D, Algo, hypList,
@@ -738,7 +780,6 @@ bool SMESHGUI_MeshOp::isValid( QString& theMess ) const
   * \retval bool - check result
  */
 //================================================================================
-
 static bool isCompatible(const HypothesisData* theAlgoData,
                          const HypothesisData* theHypData,
                          const int             theHypType)
@@ -856,6 +897,7 @@ void SMESHGUI_MeshOp::existingHyps( const int theDim,
           if ( !aHypVar->_is_nil() )
           {
             HypothesisData* aData = SMESH::GetHypothesisData( aHypVar->GetName() );
+            if ( !aData) continue;
             if ( ( theDim == -1 || aData->Dim.contains( theDim ) ) &&
                  ( isCompatible ( theAlgoData, aData, theHypType )) &&
                  ( isAux == aData->IsAux ))
@@ -874,14 +916,13 @@ void SMESHGUI_MeshOp::existingHyps( const int theDim,
 //================================================================================
 /*!
  * \brief If create or edit a submesh, return a hypothesis holding parameters used
- *        to mesh a subshape
+ *        to mesh a sub-shape
   * \param aHypType - The hypothesis type name
   * \param aServerLib - Server library name
   * \param hypData - The structure holding the hypothesis type etc.
   * \retval SMESH::SMESH_Hypothesis_var - the hypothesis holding parameter values
  */
 //================================================================================
-
 SMESH::SMESH_Hypothesis_var
 SMESHGUI_MeshOp::getInitParamsHypothesis( const QString& aHypType,
                                           const QString& aServerLib ) const
@@ -944,12 +985,19 @@ SMESHGUI_MeshOp::getInitParamsHypothesis( const QString& aHypType,
     }
   }
 
-  return SMESHGUI::GetSMESHGen()->GetHypothesisParameterValues( aHypType.toLatin1().data(),
-                                                                aServerLib.toLatin1().data(),
-                                                                aMeshVar,
-                                                                aGeomVar,
-                                                                /*byMesh = */isSubMesh);
-
+  SMESH::SMESH_Hypothesis_var hyp =
+    SMESHGUI::GetSMESHGen()->GetHypothesisParameterValues( aHypType.toLatin1().data(),
+                                                           aServerLib.toLatin1().data(),
+                                                           aMeshVar,
+                                                           aGeomVar,
+                                                           /*byMesh = */isSubMesh);
+  if ( hyp->_is_nil() && isSubMesh )
+    hyp = SMESHGUI::GetSMESHGen()->GetHypothesisParameterValues( aHypType.toLatin1().data(),
+                                                                 aServerLib.toLatin1().data(),
+                                                                 aMeshVar,
+                                                                 aGeomVar,
+                                                                 /*byMesh = */false);
+  return hyp;
 }
 
 //================================================================================
@@ -960,7 +1008,6 @@ SMESHGUI_MeshOp::getInitParamsHypothesis( const QString& aHypType,
   * \retval int - dimention
  */
 //================================================================================
-
 static int getTabDim (const QObject* tab, SMESHGUI_MeshDlg* dlg )
 {
   int aDim = -1;
@@ -997,14 +1044,6 @@ void SMESHGUI_MeshOp::onCreateHyp( const int theHypType, const int theIndex )
   createHypothesis(aDim, theHypType, aHypTypeName);
 }
 
-//================================================================================
-/*!
- *  Create hypothesis and update dialog.
- *  \param theDim - dimension of hypothesis to be created
- *  \param theType - hypothesis category (algorithm, hypothesis, additional hypothesis)
- *  \param theTypeName - specifies hypothesis to be created
- */
-//================================================================================
 namespace
 {
   QString GetUniqueName (const QStringList& theHypNames,
@@ -1018,18 +1057,24 @@ namespace
   }
 }
 
-void SMESHGUI_MeshOp::createHypothesis (const int theDim,
-                                        const int theType,
-                                        const QString& theTypeName)
+//================================================================================
+/*!
+ *  Create hypothesis and update dialog.
+ *  \param theDim - dimension of hypothesis to be created
+ *  \param theType - hypothesis category (algorithm, hypothesis, additional hypothesis)
+ *  \param theTypeName - specifies hypothesis to be created
+ */
+//================================================================================
+void SMESHGUI_MeshOp::createHypothesis(const int theDim,
+                                       const int theType,
+                                       const QString& theTypeName)
 {
-  // During a hypothesis creation we might need to select some objects.
-  // Main dialog must not update it's own selected objects in this case.
-  dlg()->deactivateAll();
-
   HypothesisData* aData = SMESH::GetHypothesisData(theTypeName);
   if (!aData)
     return;
 
+  myDim = theDim;
+  myType = theType;
   QStringList aHypNames;
   TDim2Type2HypList::const_iterator aDimIter = myExistingHyps.begin();
   for ( ; aDimIter != myExistingHyps.end(); aDimIter++) {
@@ -1048,14 +1093,21 @@ void SMESHGUI_MeshOp::createHypothesis (const int theDim,
   QString aHypName = GetUniqueName( aHypNames, aData->Label);
 
   // existing hypos
-  int nbHyp = myExistingHyps[theDim][theType].count();
+  bool dialog = false;
 
   QString aClientLibName = aData->ClientLibName;
   if (aClientLibName == "") {
     // Call hypothesis creation server method (without GUI)
-    SMESH::CreateHypothesis(theTypeName, aHypName, false);
+    SMESH::SMESH_Hypothesis_var aHyp =
+      SMESH::CreateHypothesis(theTypeName, aHypName, false);
+#ifdef WITHGENERICOBJ
+    if (!CORBA::is_nil(aHyp))
+      aHyp->UnRegister();
+#endif
   } else {
     // Get hypotheses creator client (GUI)
+    // BUG 0020378
+    //SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(theTypeName);
     SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(theTypeName);
 
     // Create hypothesis
@@ -1063,23 +1115,110 @@ void SMESHGUI_MeshOp::createHypothesis (const int theDim,
       // Get parameters appropriate to initialize a new hypothesis
       SMESH::SMESH_Hypothesis_var initParamHyp =
         getInitParamsHypothesis(theTypeName, aData->ServerLibName);
+
+      removeCustomFilters(); // Issue 0020170
+
+      // Get Entry of the Geom object
+      QString aGeomEntry = "";
+      QString aMeshEntry = "";
+      QString anObjEntry = "";
+      aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
+      aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
+      anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj );
+
+      if ( myToCreate && myIsMesh )
+        aMeshEntry = aGeomEntry;
+
+      if ( aMeshEntry != aGeomEntry ) { // Get Geom object from Mesh of a sub-mesh being edited
+        _PTR(SObject) pObj = studyDS()->FindObjectID( aMeshEntry.toLatin1().data() );
+        GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj );
+        aMeshEntry = ( aGeomVar->_is_nil() ) ? "" : aMeshEntry = aGeomVar->GetStudyEntry();
+      }
+
+      if ( aMeshEntry == "" && aGeomEntry == "" ) { // get geom of an object being edited
+        _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() );
+        bool isMesh;
+        GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj, &isMesh );
+        if ( !aGeomVar->_is_nil() )
+        {
+          aGeomEntry = aGeomVar->GetStudyEntry();
+          if ( isMesh )
+            aMeshEntry = aGeomEntry;
+        }
+      }
+
+      if ( anObjEntry != "" && aGeomEntry != "" && aMeshEntry == "" ) {
+        // take geometry from submesh being created
+        _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() );
+        if ( pObj ) {
+          // if current object is sub-mesh
+          SMESH::SMESH_subMesh_var aSubMeshVar =
+            SMESH::SMESH_subMesh::_narrow( _CAST( SObject,pObj )->GetObject() );
+          if ( !aSubMeshVar->_is_nil() ) {
+            SMESH::SMESH_Mesh_var aMeshVar =  aSubMeshVar->GetFather();
+            if ( !aMeshVar->_is_nil() ) {
+              _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshVar );
+              GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( aMeshSO );
+              if ( !aGeomVar->_is_nil() )
+                aMeshEntry = aGeomVar->GetStudyEntry();
+            }
+          }
+        }
+      }
+
+      aCreator->setShapeEntry( aGeomEntry );
+      if ( aMeshEntry != "" )
+        aCreator->setMainShapeEntry( aMeshEntry );
       myDlg->setEnabled( false );
-      aCreator->create(initParamHyp, aHypName, myDlg);
-      myDlg->setEnabled( true );
-    } else {
-      SMESH::CreateHypothesis(theTypeName, aHypName, false);
+      aCreator->create(initParamHyp, aHypName, myDlg, this, SLOT( onHypoCreated( int ) ) );
+      dialog = true;
+    }
+    else {
+     SMESH::SMESH_Hypothesis_var aHyp =
+       SMESH::CreateHypothesis(theTypeName, aHypName, false);
+#ifdef WITHGENERICOBJ
+     if (!CORBA::is_nil(aHyp))
+       aHyp->UnRegister();
+#endif
     }
   }
 
+  if( !dialog )
+    onHypoCreated(2);
+}
+
+//================================================================================
+/*!
+ *  Necessary steps after hypothesis creation
+ *  \param result - creation result:
+ *   0 = rejected
+ *   1 = accepted
+ *   2 = additional value meaning that slot is called not from dialog box
+ */
+//================================================================================
+void SMESHGUI_MeshOp::onHypoCreated( int result )
+{
+  if( result != 2 )
+  {
+    int obj = myDlg->getActiveObject();
+    onActivateObject( obj ); // Issue 0020170. Restore filters
+    myDlg->setEnabled( true );
+  }
+
   _PTR(SComponent) aFather = SMESH::GetActiveStudyDocument()->FindComponent("SMESH");
 
-  HypothesisData* algoData = hypData( theDim, Algo, currentHyp( theDim, Algo ));
+  int nbHyp = myExistingHyps[myDim][myType].count();
+  HypothesisData* algoData = hypData( myDim, Algo, currentHyp( myDim, Algo ));
   QStringList aNewHyps;
-  existingHyps(theDim, theType, aFather, aNewHyps, myExistingHyps[theDim][theType], algoData);
-  if (aNewHyps.count() > nbHyp) {
+  existingHyps(myDim, myType, aFather, aNewHyps, myExistingHyps[myDim][myType], algoData);
+  if (aNewHyps.count() > nbHyp)
+  {
     for (int i = nbHyp; i < aNewHyps.count(); i++)
-      myDlg->tab(theDim)->addHyp(theType, aNewHyps[i]);
+      myDlg->tab(myDim)->addHyp(myType, aNewHyps[i]);
   }
+
+  if( result!=2 && myHypoSet )
+    processSet();
 }
 
 //================================================================================
@@ -1107,18 +1246,86 @@ void SMESHGUI_MeshOp::onEditHyp( const int theHypType, const int theIndex )
   if ( aHyp->_is_nil() )
     return;
 
-  SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator( aHyp->GetName() );
-  if ( aCreator ) {
+  SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(aHyp->GetName());
+  if ( aCreator )
+  {
     // Get initial parameters
     SMESH::SMESH_Hypothesis_var initParamHyp =
       getInitParamsHypothesis( aHyp->GetName(), aHyp->GetLibName());
-    myDlg->setEnabled( false );
     aCreator->setInitParamsHypothesis( initParamHyp );
-    aCreator->edit( aHyp.in(), aHypItem.second, dlg() );
-    myDlg->setEnabled( true );
+
+    // Get Entry of the Geom object
+    QString aGeomEntry = "";
+    QString aMeshEntry = "";
+    QString anObjEntry = "";
+    aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
+    aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
+    anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj );
+
+    if ( myToCreate && myIsMesh )
+      aMeshEntry = aGeomEntry;
+
+    if ( aMeshEntry != aGeomEntry ) { // Get Geom object from Mesh of a sub-mesh being edited
+      _PTR(SObject) pObj = studyDS()->FindObjectID( aMeshEntry.toLatin1().data() );
+      GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj );
+      aMeshEntry = ( aGeomVar->_is_nil() ) ? "" : aMeshEntry = aGeomVar->GetStudyEntry();
+    }
+
+    if ( aMeshEntry == "" && aGeomEntry == "" ) { // get geom of an object being edited
+      _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() );
+      bool isMesh;
+      GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj, &isMesh );
+      if ( !aGeomVar->_is_nil() )
+      {
+        aGeomEntry = aGeomVar->GetStudyEntry();
+        if ( isMesh )
+          aMeshEntry = aGeomEntry;
+      }
+    }
+
+    if ( anObjEntry != "" && aGeomEntry != "" && aMeshEntry == "" ) {
+      // take geometry from submesh being created
+      _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() );
+      if ( pObj ) {
+        // if current object is sub-mesh
+        SMESH::SMESH_subMesh_var aSubMeshVar =
+          SMESH::SMESH_subMesh::_narrow( _CAST( SObject,pObj )->GetObject() );
+        if ( !aSubMeshVar->_is_nil() ) {
+          SMESH::SMESH_Mesh_var aMeshVar =  aSubMeshVar->GetFather();
+          if ( !aMeshVar->_is_nil() ) {
+            _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshVar );
+            GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( aMeshSO );
+            if ( !aGeomVar->_is_nil() )
+              aMeshEntry = aGeomVar->GetStudyEntry();
+          }
+        }
+      }
+    }
+
+    aCreator->setShapeEntry( aGeomEntry );
+    if ( aMeshEntry != "" )
+      aCreator->setMainShapeEntry( aMeshEntry );
+    removeCustomFilters(); // Issue 0020170
+    myDlg->setEnabled( false );
+    aCreator->edit( aHyp.in(), aHypItem.second, dlg(), this, SLOT( onHypoEdited( int ) ) );
   }
 }
 
+//================================================================================
+/*!
+ *  Necessary steps after hypothesis edition
+ *  \param result - creation result:
+ *   0 = rejected
+ *   1 = accepted
+ */
+//================================================================================
+void SMESHGUI_MeshOp::onHypoEdited( int result )
+{
+  int obj = myDlg->getActiveObject();
+  onActivateObject( obj ); // Issue 0020170. Restore filters
+  myDlg->setEnabled( true );
+}
+
 //================================================================================
 /*!
  * \brief access to hypothesis data
@@ -1128,7 +1335,6 @@ void SMESHGUI_MeshOp::onEditHyp( const int theHypType, const int theIndex )
   * \retval HypothesisData* - result data, may be 0
  */
 //================================================================================
-
 HypothesisData* SMESHGUI_MeshOp::hypData( const int theDim,
                                           const int theHypType,
                                           const int theIndex)
@@ -1146,7 +1352,6 @@ HypothesisData* SMESHGUI_MeshOp::hypData( const int theDim,
   * \param theIndex - algorithm index
  */
 //================================================================================
-
 void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
                                       const int theDim )
 {
@@ -1255,7 +1460,7 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
         CORBA::String_var curHypType = curHyp->GetName();
         if ( !algoDeselectedByUser &&
              myObjHyps[ dim ][ type ].count() > 0 &&
-             curHypType == myObjHyps[ dim ][ type ].first().first->GetName())
+             !strcmp( curHypType, myObjHyps[ dim ][ type ].first().first->GetName()) )
         {
           HypothesisData* hypData = SMESH::GetHypothesisData( curHyp->GetName() );
           for (int i = 0; i < myAvailableHypData[ dim ][ Algo ].count(); ++i) {
@@ -1310,8 +1515,9 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
 //================================================================================
 void SMESHGUI_MeshOp::onHypoSet( const QString& theSetName )
 {
-  HypothesesSet* aHypoSet = SMESH::GetHypothesesSet(theSetName);
-  if (!aHypoSet) return;
+  myHypoSet = SMESH::GetHypothesesSet(theSetName);
+  if (!myHypoSet)
+    return;
 
   // clear all hyps
   for (int dim = SMESH::DIM_0D; dim <= SMESH::DIM_3D; dim++) {
@@ -1320,57 +1526,81 @@ void SMESHGUI_MeshOp::onHypoSet( const QString& theSetName )
     setCurrentHyp(dim, MainHyp, -1);
   }
 
-  for (int aHypType = Algo; aHypType < AddHyp; aHypType++) {
-    bool isAlgo = (aHypType == Algo);
+  myHypoSet->init(true); //algorithms
+  processSet();
+  myHypoSet->init(false); //hypotheses
+  processSet();
+  myHypoSet = 0;
+}
 
-    // set hyps from the set
-    QStringList* aHypoList = isAlgo ? &aHypoSet->AlgoList : &aHypoSet->HypoList;
-    for (int i = 0, n = aHypoList->count(); i < n; i++) {
-      const QString& aHypoTypeName = (*aHypoList)[ i ];
-      HypothesisData* aHypData = SMESH::GetHypothesisData(aHypoTypeName);
-      if (!aHypData)
-        continue;
+//================================================================================
+/*!
+ * \brief One step of hypothesis/algorithm list creation
+ *
+ * Creates a hypothesis or an algorithm for current item of internal list of names myHypoSet
+ */
+//================================================================================
+void SMESHGUI_MeshOp::processSet()
+{
+  myHypoSet->next();
+  if( !myHypoSet->more() )
+    return;
 
-      int aDim = aHypData->Dim[0];
-      // create or/and set
-      if (isAlgo) {
-        int index = myAvailableHypData[aDim][Algo].indexOf( aHypData );
-        if ( index < 0 ) {
-          QStringList anAvailable;
-          availableHyps( aDim, Algo, anAvailable, myAvailableHypData[aDim][Algo] );
-          myDlg->tab( aDim )->setAvailableHyps( Algo, anAvailable );
-          index = myAvailableHypData[aDim][Algo].indexOf( aHypData );
-        }
-        setCurrentHyp( aDim, Algo, index );
-        onAlgoSelected( index, aDim );
-      }
-      else {
-        bool mainHyp = true;
-        QStringList anAvailable;
-        availableHyps( aDim, MainHyp, anAvailable, myAvailableHypData[aDim][MainHyp] );
-        myDlg->tab( aDim )->setAvailableHyps( MainHyp, anAvailable );
-        int index = myAvailableHypData[aDim][MainHyp].indexOf( aHypData );
-        if ( index < 0 ) {
-          mainHyp = false;
-          index = myAvailableHypData[aDim][AddHyp].indexOf( aHypData );
-        }
-        if (index >= 0)
-          createHypothesis(aDim, mainHyp ? MainHyp : AddHyp, aHypoTypeName);
-      }
-    } // loop on hypos in the set
-  } // loop on algo/hypo
+  bool isAlgo = myHypoSet->isAlgo();
+  QString aHypoTypeName = myHypoSet->current();
+  HypothesisData* aHypData = SMESH::GetHypothesisData(aHypoTypeName);
+  if (!aHypData)
+  {
+    processSet();
+    return;
+  }
+
+  int aDim = aHypData->Dim[0];
+  // create or/and set
+  if (isAlgo)
+  {
+    int index = myAvailableHypData[aDim][Algo].indexOf( aHypData );
+    if ( index < 0 )
+    {
+      QStringList anAvailable;
+      availableHyps( aDim, Algo, anAvailable, myAvailableHypData[aDim][Algo] );
+      myDlg->tab( aDim )->setAvailableHyps( Algo, anAvailable );
+      index = myAvailableHypData[aDim][Algo].indexOf( aHypData );
+    }
+    setCurrentHyp( aDim, Algo, index );
+    onAlgoSelected( index, aDim );
+    processSet();
+  }
+  else
+  {
+    bool mainHyp = true;
+    QStringList anAvailable;
+    availableHyps( aDim, MainHyp, anAvailable, myAvailableHypData[aDim][MainHyp] );
+    myDlg->tab( aDim )->setAvailableHyps( MainHyp, anAvailable );
+    int index = myAvailableHypData[aDim][MainHyp].indexOf( aHypData );
+    if ( index < 0 )
+    {
+      mainHyp = false;
+      index = myAvailableHypData[aDim][AddHyp].indexOf( aHypData );
+    }
+    if (index >= 0)
+      createHypothesis(aDim, mainHyp ? MainHyp : AddHyp, aHypoTypeName);
+    else
+      processSet();
+  }
 }
 
 //================================================================================
 /*!
  * \brief Creates mesh
   * \param theMess - Output parameter intended for returning error message
+  * \param theEntryList - List of entries of published objects
   * \retval bool  - TRUE if mesh is created, FALSE otherwise
  *
  * Creates mesh
  */
 //================================================================================
-bool SMESHGUI_MeshOp::createMesh( QString& theMess )
+bool SMESHGUI_MeshOp::createMesh( QString& theMess, QStringList& theEntryList )
 {
   theMess = "";
 
@@ -1398,8 +1628,10 @@ bool SMESHGUI_MeshOp::createMesh( QString& theMess )
     if ( aMeshVar->_is_nil() )
       return false;
     _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshVar.in() );
-    if ( aMeshSO )
+    if ( aMeshSO ) {
       SMESH::SetName( aMeshSO, myDlg->objectText( SMESHGUI_MeshDlg::Obj ) );
+      theEntryList.append( aMeshSO->GetID().c_str() );
+    }
 
     for ( int aDim = SMESH::DIM_0D; aDim <= SMESH::DIM_3D; aDim++ ) {
       if ( !isAccessibleDim( aDim )) continue;
@@ -1418,7 +1650,13 @@ bool SMESHGUI_MeshOp::createMesh( QString& theMess )
       if ( !anAlgoVar->_is_nil() )
         SMESH::AddHypothesisOnMesh( aMeshVar, anAlgoVar );
     }
-
+#ifdef WITHGENERICOBJ
+    // obj has been published in study. Its refcount has been incremented.
+    // It is safe to decrement its refcount
+    // so that it will be destroyed when the entry in study will be removed
+    if (aMeshSO)
+      aMeshVar->UnRegister();
+#endif
   }
   return true;
 }
@@ -1427,12 +1665,13 @@ bool SMESHGUI_MeshOp::createMesh( QString& theMess )
 /*!
  * \brief Creates sub-mesh
   * \param theMess - Output parameter intended for returning error message
+  * \param theEntryList - List of entries of published objects
   * \retval bool  - TRUE if sub-mesh is created, FALSE otherwise
  *
  * Creates sub-mesh
  */
 //================================================================================
-bool SMESHGUI_MeshOp::createSubMesh( QString& theMess )
+bool SMESHGUI_MeshOp::createSubMesh( QString& theMess, QStringList& theEntryList )
 {
   theMess = "";
 
@@ -1506,8 +1745,8 @@ bool SMESHGUI_MeshOp::createSubMesh( QString& theMess )
           QString aNewGeomGroupName ("Auto_group_for_");
           aNewGeomGroupName += aName;
           SALOMEDS::SObject_var aNewGroupSO =
-            geomGen->AddInStudy(aSMESHGen->GetCurrentStudy(), aGeomVar, 
-                               aNewGeomGroupName.toLatin1().data(), mainGeom);
+            geomGen->AddInStudy(aSMESHGen->GetCurrentStudy(), aGeomVar,
+                                aNewGeomGroupName.toLatin1().data(), mainGeom);
         }
       }
     }
@@ -1522,8 +1761,10 @@ bool SMESHGUI_MeshOp::createSubMesh( QString& theMess )
   // create sub-mesh
   SMESH::SMESH_subMesh_var aSubMeshVar = aMeshVar->GetSubMesh( aGeomVar, aName.toLatin1().data() );
   _PTR(SObject) aSubMeshSO = SMESH::FindSObject( aSubMeshVar.in() );
-  if ( aSubMeshSO )
+  if ( aSubMeshSO ) {
     SMESH::SetName( aSubMeshSO, aName.toLatin1().data() );
+    theEntryList.append( aSubMeshSO->GetID().c_str() );
+  }
 
   for ( int aDim = SMESH::DIM_0D; aDim <= SMESH::DIM_3D; aDim++ )
   {
@@ -1547,7 +1788,7 @@ bool SMESHGUI_MeshOp::createSubMesh( QString& theMess )
     }
   }
 
-  // deselect geometry: next submesh should be created on other subshape
+  // deselect geometry: next submesh should be created on other sub-shape
   myDlg->clearSelection( SMESHGUI_MeshDlg::Geom );
   selectObject( _PTR(SObject)() );
   selectionDone();
@@ -1579,7 +1820,7 @@ int SMESHGUI_MeshOp::currentHyp( const int theDim, const int theHypType ) const
 //================================================================================
 bool SMESHGUI_MeshOp::isAccessibleDim( const int theDim ) const
 {
-  return myDlg->tab( theDim )->isEnabled();
+  return myDlg->isTabEnabled( theDim );
 }
 
 //================================================================================
@@ -1653,36 +1894,53 @@ SMESH::SMESH_Hypothesis_var SMESHGUI_MeshOp::getAlgo( const int theDim )
   QStringList tmp;
   existingHyps( theDim, Algo, pObj, tmp, myExistingHyps[ theDim ][ Algo ]);
 
-  // look for anexisting algo of such a type
+  // look for an existing algo of such a type
   THypList& aHypVarList = myExistingHyps[ theDim ][ Algo ];
   THypList::iterator anIter = aHypVarList.begin();
   for ( ; anIter != aHypVarList.end(); anIter++)
   {
     SMESH::SMESH_Hypothesis_var aHypVar = (*anIter).first;
     CORBA::String_var aName = aHypVar->GetName();
-    if ( !aHypVar->_is_nil() && aHypName == aName )
+    if ( !aHypVar->_is_nil() && !strcmp(aHypName.toLatin1().data(), aName) )
     {
       anAlgoVar = aHypVar;
       break;
     }
   }
 
-  if (anAlgoVar->_is_nil()) {
+  if (anAlgoVar->_is_nil())
+  {
     HypothesisData* aHypData = SMESH::GetHypothesisData( aHypName );
-    if (aHypData) {
+    if (aHypData)
+    {
       QString aClientLibName = aHypData->ClientLibName;
-      if (aClientLibName == "") {
+      if (aClientLibName == "")
+      {
         // Call hypothesis creation server method (without GUI)
-        SMESH::CreateHypothesis(aHypName, aHypData->Label, true);
-      } else {
+        SMESH::SMESH_Hypothesis_var aHyp =
+          SMESH::CreateHypothesis(aHypName, aHypName, true);
+#ifdef WITHGENERICOBJ
+        if (!CORBA::is_nil(aHyp))
+          aHyp->UnRegister();
+#endif
+      }
+      else
+      {
         // Get hypotheses creator client (GUI)
+        // BUG 0020378
         SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(aHypName);
 
         // Create algorithm
         if (aCreator)
-          aCreator->create(true, aHypName, myDlg);
-        else
-          SMESH::CreateHypothesis(aHypName, aHypData->Label, true);
+          aCreator->create(true, aHypName, myDlg, 0, QString::null );
+        else {
+          SMESH::SMESH_Hypothesis_var aHyp =
+            SMESH::CreateHypothesis(aHypName, aHypName, true);
+#ifdef WITHGENERICOBJ
+          if (!CORBA::is_nil(aHyp))
+            aHyp->UnRegister();
+#endif
+        }
       }
       QStringList tmpList;
       _PTR(SComponent) aFather = SMESH::GetActiveStudyDocument()->FindComponent( "SMESH" );
@@ -1694,7 +1952,7 @@ SMESH::SMESH_Hypothesis_var SMESHGUI_MeshOp::getAlgo( const int theDim )
     {
       SMESH::SMESH_Hypothesis_var aHypVar = (*anIter).first;
       CORBA::String_var aName = aHypVar->GetName();
-      if ( !aHypVar->_is_nil() && aHypName == aName )
+      if ( !aHypVar->_is_nil() && !strcmp(aHypName.toLatin1().data(), aName) )
       {
         anAlgoVar = aHypVar;
         break;
@@ -1983,14 +2241,14 @@ bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess )
 //================================================================================
 /*!
  * \brief Verifies whether given operator is valid for this one
 * \param theOtherOp - other operation
 * \return Returns TRUE if the given operator is valid for this one, FALSE otherwise
-*
-* method redefined from base class verifies whether given operator is valid for
-* this one (i.e. can be started "above" this operator). In current implementation method
-* retuns false if theOtherOp operation is not intended for deleting objects or mesh
-* elements.
-*/
+ * \param theOtherOp - other operation
+ * \return Returns TRUE if the given operator is valid for this one, FALSE otherwise
+ *
+ * method redefined from base class verifies whether given operator is valid for
+ * this one (i.e. can be started "above" this operator). In current implementation method
+ * retuns false if theOtherOp operation is not intended for deleting objects or mesh
+ * elements.
+ */
 //================================================================================
 bool SMESHGUI_MeshOp::isValid( SUIT_Operation* theOp ) const
 {
@@ -2000,10 +2258,9 @@ bool SMESHGUI_MeshOp::isValid( SUIT_Operation* theOp ) const
 //================================================================================
 /*!
  * \brief SLOT. Is called when the user selects a way of geometry selection
 * \param theByMesh - true if the user wants to find geometry by mesh element
+ * \param theByMesh - true if the user wants to find geometry by mesh element
  */
 //================================================================================
-
 void SMESHGUI_MeshOp::onGeomSelectionByMesh( bool theByMesh )
 {
   if ( theByMesh ) {
@@ -2035,7 +2292,6 @@ void SMESHGUI_MeshOp::onGeomSelectionByMesh( bool theByMesh )
  * \brief SLOT. Is called when Ok is pressed in SMESHGUI_ShapeByMeshDlg
  */
 //================================================================================
-
 void SMESHGUI_MeshOp::onPublishShapeByMeshDlg(SUIT_Operation* op)
 {
   if ( myShapeByMeshOp == op ) {
@@ -2059,7 +2315,6 @@ void SMESHGUI_MeshOp::onPublishShapeByMeshDlg(SUIT_Operation* op)
  * \brief SLOT. Is called when Close is pressed in SMESHGUI_ShapeByMeshDlg
  */
 //================================================================================
-
 void SMESHGUI_MeshOp::onCloseShapeByMeshDlg(SUIT_Operation* op)
 {
   if ( myShapeByMeshOp == op && myDlg ) {
@@ -2070,10 +2325,9 @@ void SMESHGUI_MeshOp::onCloseShapeByMeshDlg(SUIT_Operation* op)
 //================================================================================
 /*!
  * \brief Selects a SObject
 * \param theSObj - the SObject to select
+ * \param theSObj - the SObject to select
  */
 //================================================================================
-
 void SMESHGUI_MeshOp::selectObject( _PTR(SObject) theSObj ) const
 {
   if ( LightApp_SelectionMgr* sm = selectionMgr() ) {
index 1046b699c75d82d24ab612e203799e5ed0a5b116..c7b11d43742bc5bcf1902ead812365699f4e1aa8 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_MeshOp.h
 // Author : Sergey LITONIN, Open CASCADE S.A.S.
@@ -31,6 +32,7 @@
 
 #include "SMESHGUI_SelectionOp.h"
 
+class HypothesesSet;
 class SMESHGUI_MeshDlg;
 class SMESHGUI_ShapeByMeshOp;
 class HypothesisData;
@@ -64,6 +66,7 @@ public:
 
 protected:
   virtual void                   startOperation();
+  virtual void                   commitOperation();
   virtual void                   selectionDone();
   virtual SUIT_SelectionFilter*  createFilter( const int ) const;
   virtual bool                   isValid( SUIT_Operation* ) const;
@@ -77,6 +80,9 @@ protected slots:
   void                           onPublishShapeByMeshDlg( SUIT_Operation* );
   void                           onCloseShapeByMeshDlg( SUIT_Operation* );
   void                           onAlgoSelected( const int, const int = -1 );
+  void                           processSet();
+  void                           onHypoCreated( int );
+  void                           onHypoEdited( int );
 
 private:
   typedef QList<HypothesisData*> THypDataList; // typedef: list of hypothesis data
@@ -98,10 +104,10 @@ private:
                                           const int ); // access to myAvailableHypData
 
   void                           createHypothesis( const int, const int,
-                                                  const QString& );
+                                                   const QString& );
 
-  bool                           createMesh( QString& );
-  bool                           createSubMesh( QString& );
+  bool                           createMesh( QString&, QStringList& );
+  bool                           createSubMesh( QString&, QStringList& );
   bool                           editMeshOrSubMesh( QString& );
 
   int                            currentHyp( const int, const int ) const;
@@ -135,6 +141,10 @@ private:
   THypDataList                   myAvailableHypData[4][NbHypTypes];
 
   bool                           myIgnoreAlgoSelection;
+  HypothesesSet* myHypoSet;
+  int myDim, myType;
+
+  QString                        myObjectToSelect;
 };
 
 #endif // SMESHGUI_MESHOP_H
diff --git a/src/SMESHGUI/SMESHGUI_MeshOrderDlg.cxx b/src/SMESHGUI/SMESHGUI_MeshOrderDlg.cxx
new file mode 100644 (file)
index 0000000..7b55ee5
--- /dev/null
@@ -0,0 +1,330 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+// File   : SMESHGUI_MeshOrderDlg.cxx
+// Author : Pavel TELKOV, Open CASCADE S.A.S.
+// SMESH includes
+//
+#include "SMESHGUI_MeshOrderDlg.h"
+
+// Qt includes
+#include <Qt>
+#include <QFrame>
+#include <QLabel>
+#include <QBoxLayout>
+#include <QSpacerItem>
+#include <QToolButton>
+#include <QListWidget>
+#include <QListWidgetItem>
+
+#define SPACING 6
+#define MARGIN  11
+
+/*! 
+ * Enumeartion of list widget item types (mesh name or separator)
+ */
+enum MeshOrderItemType { MeshItem = QListWidgetItem::UserType, SeparatorItem };
+
+// =========================================================================================
+/*!
+ * \brief Constructor
+ */
+// =========================================================================================
+
+SMESHGUI_MeshOrderBox::SMESHGUI_MeshOrderBox(QWidget* theParent)
+: QGroupBox( theParent ), myIsChanged( false ), myUpBtn(0), myDownBtn(0)
+{
+  QHBoxLayout* hBoxLayout = new QHBoxLayout(this);
+  hBoxLayout->setMargin( MARGIN );
+  hBoxLayout->setSpacing( SPACING );
+  
+  myMeshNames = new QListWidget(this);
+  myMeshNames->setSelectionMode(QAbstractItemView::SingleSelection);
+  myMeshNames->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding ));
+  hBoxLayout->addWidget(myMeshNames);
+  
+  QGroupBox* btnGrp = new QGroupBox(this);
+  hBoxLayout->addWidget(btnGrp);
+
+  myUpBtn   = new QToolButton(btnGrp);
+  myDownBtn = new QToolButton(btnGrp);
+  myUpBtn->  setArrowType( Qt::UpArrow );
+  myDownBtn->setArrowType( Qt::DownArrow );
+  
+  QVBoxLayout* vBoxLayout = new QVBoxLayout(btnGrp);
+  vBoxLayout->addSpacerItem( new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding ) );
+  vBoxLayout->addWidget( myUpBtn );
+  vBoxLayout->addWidget( myDownBtn );
+  vBoxLayout->addSpacerItem( new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding ) );
+
+  connect( myUpBtn,   SIGNAL( clicked() ), this, SLOT( onMoveItem() ) );
+  connect( myDownBtn, SIGNAL( clicked() ), this, SLOT( onMoveItem() ) );
+  connect( myMeshNames, SIGNAL( itemSelectionChanged() ), this, SLOT( onSelectionChanged() ) );
+  
+  onSelectionChanged();
+}
+
+// =========================================================================================
+/*!
+ * \brief Destructor
+ */
+//=======================================================================
+
+SMESHGUI_MeshOrderBox::~SMESHGUI_MeshOrderBox()
+{
+}
+
+// =========================================================================================
+/*!
+ * \brief add separator item
+ */
+// =========================================================================================
+
+static void addSeparator( QListWidget* theList )
+{
+  QListWidgetItem* item = new QListWidgetItem( theList, SeparatorItem );
+  QFrame* hline = new QFrame( theList );
+  hline->setFrameStyle( QFrame::HLine | QFrame::Sunken );
+  theList->addItem( item );
+  theList->setItemWidget( item, hline );
+}
+
+// =========================================================================================
+/*!
+ * \brief add sub-mesh item
+ */
+// =========================================================================================
+
+static void addMeshItem( QListWidget* theList,
+                         const QString& theName,
+                         const int      theId )
+{
+  QListWidgetItem* item = new QListWidgetItem( theName, theList, MeshItem );
+  item->setData( Qt::UserRole, theId );
+  theList->addItem( item );
+}
+
+// =========================================================================================
+/*!
+ * \brief Clear submesh names and indeces
+ */
+// =========================================================================================
+
+void SMESHGUI_MeshOrderBox::Clear()
+{
+  myMeshNames->clear();
+  myIsChanged = false;
+}
+
+// =========================================================================================
+/*!
+ * \brief Set submesh names and indeces
+ */
+// =========================================================================================
+
+void SMESHGUI_MeshOrderBox::SetMeshes(const ListListName& theMeshNames,
+                                      const ListListId&   theMeshIds)
+{
+  Clear();
+  ListListName::const_iterator nLIt = theMeshNames.constBegin();
+  ListListId::const_iterator idLIt  = theMeshIds.constBegin();
+  for ( ; nLIt != theMeshNames.constEnd(); ++nLIt, ++idLIt )
+  {
+    const QStringList& names = (*nLIt);
+    const QList<int>& ids = (*idLIt);
+    if ( myMeshNames->count() )
+      addSeparator( myMeshNames );
+    QStringList::const_iterator nameIt = names.constBegin();
+    QList<int>::const_iterator idIt = ids.constBegin();
+    for ( ; nameIt != names.constEnd(); ++nameIt, ++idIt )
+      addMeshItem( myMeshNames, *nameIt, *idIt );
+  }
+}
+
+// =========================================================================================
+/*!
+ * \brief cehck that item exists and not a separator
+ */
+// =========================================================================================
+
+static bool checkItem(QListWidgetItem* theItem)
+{
+  return theItem && (int)theItem->type() != (int)SeparatorItem;
+}
+
+// =========================================================================================
+/*!
+ * \brief Returns result (ordered by user) mesh names
+ */
+// =========================================================================================
+
+ListListId SMESHGUI_MeshOrderBox::GetMeshIds() const
+{
+  ListListId aLLIds;
+  aLLIds.append( QList<int>() );
+  for ( int i = 0, n = myMeshNames->count(); i < n; i++ )
+  {
+    QListWidgetItem* it = myMeshNames->item( i );
+    if (checkItem( it ))
+      aLLIds.last().append( it->data( Qt::UserRole ).toInt() );
+    else // separator before next list of mesh items
+      aLLIds.append( QList<int>() );
+  }
+  return aLLIds;
+}
+
+// =========================================================================================
+/*!
+ * \brief Returns result (ordered by user) mesh indeces
+ */
+// =========================================================================================
+
+ListListName SMESHGUI_MeshOrderBox::GetMeshNames() const
+{
+  ListListName aLLNames;
+  aLLNames.append( QStringList() );
+  for ( int i = 0, n = myMeshNames->count(); i < n; i++ )
+  {
+    QListWidgetItem* it = myMeshNames->item( i );
+    if (checkItem( it ))
+      aLLNames.last().append( it->text() );
+    else // separator before next list of mesh items
+      aLLNames.append( QStringList() );
+  }
+  return aLLNames;
+}
+
+// =========================================================================================
+/*!
+ * \brief update state of arrow buttons according to selection
+ */
+// =========================================================================================
+
+void SMESHGUI_MeshOrderBox::onSelectionChanged()
+{
+  bool isUp = false;
+  bool isDown = false;
+  QList<QListWidgetItem *> items = myMeshNames->selectedItems();
+  if ( !items.isEmpty() )
+  {
+    QListWidgetItem* selItem = (*(items.begin()));
+    if (checkItem(selItem))
+    {
+      const int rowId = myMeshNames->row( selItem );
+      isUp   = checkItem( myMeshNames->item( rowId - 1 ) );
+      isDown = checkItem( myMeshNames->item( rowId + 1 ) );
+    }
+  }
+  myUpBtn->  setEnabled( isUp );
+  myDownBtn->setEnabled( isDown );
+}
+
+// =========================================================================================
+/*!
+ * \brief move item according to clicked arrow button
+ */
+// =========================================================================================
+
+void SMESHGUI_MeshOrderBox::onMoveItem()
+{
+  moveItem( sender() == myUpBtn );
+}
+
+// =========================================================================================
+/*!
+ * \brief move mesh in order up or down
+ */
+// =========================================================================================
+
+void SMESHGUI_MeshOrderBox::moveItem(const bool theIsUp)
+{
+  // move selected list item up or down
+  QList<QListWidgetItem *> items = myMeshNames->selectedItems();
+  if ( items.isEmpty() )
+    return;
+  QListWidgetItem * selItem = (*(items.begin()));
+  if (!checkItem(selItem))
+    return;
+  int rowId = myMeshNames->row( selItem );
+  if ( rowId == -1 )
+    return;
+
+  // move item in list widget
+  myIsChanged = true;
+  myMeshNames->takeItem( rowId );
+  myMeshNames->insertItem(theIsUp ? rowId-1 : rowId+1, selItem );
+
+  // restore selection and current status
+  selItem->setSelected( true );
+  myMeshNames->setCurrentItem( selItem );
+}
+
+// =========================================================================================
+/*!
+ * \brief returns status is order changed by user
+ */
+// =========================================================================================
+
+bool SMESHGUI_MeshOrderBox:: IsOrderChanged() const
+{
+  return myIsChanged;
+}
+
+// =========================================================================================
+/*!
+ * \brief Constructor
+ */
+// =========================================================================================
+
+SMESHGUI_MeshOrderDlg::SMESHGUI_MeshOrderDlg(QWidget* theParent)
+: SMESHGUI_Dialog( theParent, false, false, OK | Cancel | Help )
+{
+  setWindowTitle( tr( "SMESH_MESHORDER_TITLE") );
+  QFrame* main = mainFrame();
+
+  QVBoxLayout* aDlgLay = new QVBoxLayout (main);
+  aDlgLay->setMargin( 0 );
+  aDlgLay->setSpacing( SPACING );
+
+  myBox = new SMESHGUI_MeshOrderBox( main );
+
+  aDlgLay->addWidget(myBox);
+  aDlgLay->setStretchFactor(main, 1);
+}
+
+// =========================================================================================
+/*!
+ * \brief Destructor
+ */
+// =========================================================================================
+
+SMESHGUI_MeshOrderDlg::~SMESHGUI_MeshOrderDlg()
+{
+}
+
+// =========================================================================================
+/*!
+ * \brief return Box widget to show mesh order
+ */
+// =========================================================================================
+
+SMESHGUI_MeshOrderBox* SMESHGUI_MeshOrderDlg::GetMeshOrderBox() const
+{
+  return myBox;
+}
diff --git a/src/SMESHGUI/SMESHGUI_MeshOrderDlg.h b/src/SMESHGUI/SMESHGUI_MeshOrderDlg.h
new file mode 100644 (file)
index 0000000..ec12055
--- /dev/null
@@ -0,0 +1,112 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+// File   : SMESHGUI_MeshOrderDlg.h
+// Author : Pavel TELKOV, Open CASCADE S.A.S.
+//
+#ifndef SMESHGUI_MeshOrderDlg_H
+#define SMESHGUI_MeshOrderDlg_H
+
+// SMESH includes
+#include "SMESH_SMESHGUI.hxx"
+#include "SMESHGUI_Dialog.h"
+
+// Qt includes
+#include <QGroupBox>
+
+// IDL includes
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+
+class QToolButton;
+class QListWidget;
+
+typedef QList<QStringList> ListListName;
+typedef QList<int>         ListId;
+typedef QList<ListId>  ListListId;
+
+/*!
+ * \brief Reusable widget that shows and allows modify meshing order
+ */
+
+class SMESHGUI_EXPORT SMESHGUI_MeshOrderBox : public QGroupBox
+{
+  Q_OBJECT
+    
+ public:
+  /*! Public methods */
+  SMESHGUI_MeshOrderBox( QWidget* );
+  ~SMESHGUI_MeshOrderBox();
+
+  //! Clear mesh box
+  void         Clear();
+
+  //! Set mesh (submesh) names and indeces
+  void         SetMeshes(const ListListName& theMeshNames,
+                         const ListListId&   theMeshIds);
+
+  //! returns status is order changed by user
+  bool         IsOrderChanged() const;
+
+  //! Returns result (ordered by user) mesh names
+  ListListId   GetMeshIds() const;
+  //! Returns result (ordered by user) mesh indeces
+  ListListName GetMeshNames() const;
+ private slots:
+  /*! Private slots */
+  //! update state of arrow buttons according to selection
+  void         onSelectionChanged();
+  //! move item according to clicked arrow button
+  void         onMoveItem();
+
+ private:
+  /*! Privatemethods */
+  //! move mesh in order up or down
+  void         moveItem(const bool theIsUp);
+
+ private:
+  /*! Private fields */
+  bool         myIsChanged;
+  QToolButton* myUpBtn;
+  QToolButton* myDownBtn;
+  QListWidget* myMeshNames;
+};
+
+/*!
+ * \brief Dialog contains mesh order box for modification operation
+ */
+
+class SMESHGUI_EXPORT SMESHGUI_MeshOrderDlg : public SMESHGUI_Dialog
+{
+  Q_OBJECT
+    
+ public:
+  /*! Public methods */
+  SMESHGUI_MeshOrderDlg( QWidget* );
+  ~SMESHGUI_MeshOrderDlg();
+
+  SMESHGUI_MeshOrderBox* GetMeshOrderBox() const;
+
+ private:
+  /*! Private fields */
+  SMESHGUI_MeshOrderBox* myBox;
+};
+
+#endif // SMESHGUI_MeshOrderDlg_H
diff --git a/src/SMESHGUI/SMESHGUI_MeshOrderOp.cxx b/src/SMESHGUI/SMESHGUI_MeshOrderOp.cxx
new file mode 100644 (file)
index 0000000..f2a138d
--- /dev/null
@@ -0,0 +1,325 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+// File   : SMESHGUI_MeshOrderOp.cxx
+// Author : Pavel TELKOV, Open CASCADE S.A.S.
+//
+#include "SMESHGUI_MeshOrderOp.h"
+
+#include "SMESHGUI.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_MeshUtils.h"
+
+// SALOME GUI includes
+#include <LightApp_SelectionMgr.h>
+#include <SALOME_ListIO.hxx>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_OverrideCursor.h>
+#include <SUIT_MessageBox.h>
+#include <SUIT_Desktop.h>
+
+// SALOME KERNEL includes
+#include <SALOMEDS_SObject.hxx>
+#include <SALOMEDSClient_SObject.hxx>
+
+// STL includes
+#include <set>
+
+//================================================================================
+/*!
+ * \brief Constructor
+*/
+//================================================================================
+
+SMESHGUI_MeshOrderOp::SMESHGUI_MeshOrderOp()
+  : SMESHGUI_Operation(), myDlg(0), myMgr(0)
+{
+  myDlg = new SMESHGUI_MeshOrderDlg( desktop() );
+  
+  myHelpFileName = "constructing_meshes_page.html#mesh_order_anchor";
+}
+
+//================================================================================
+/*!
+ * \brief Destructor
+*/
+//================================================================================
+
+SMESHGUI_MeshOrderOp::~SMESHGUI_MeshOrderOp()
+{
+}
+
+//================================================================================
+/*!
+ * \brief Return operation dialog
+ */
+//================================================================================
+
+LightApp_Dialog* SMESHGUI_MeshOrderOp::dlg() const
+{
+  return myDlg;
+}
+
+//================================================================================
+/*!
+ * \brief perform it's intention action: compute 2D mesh on 3D
+ */
+//================================================================================
+
+void SMESHGUI_MeshOrderOp::startOperation()
+{
+  SMESHGUI_Operation::startOperation();
+  if (myMgr)
+    myDlg->show();
+}
+
+//================================================================================
+/*!
+ * \brief Init dialog and mesh order box
+ */
+//================================================================================
+
+void SMESHGUI_MeshOrderOp::initDialog()
+{
+  if (!myDlg )
+    return;
+  
+  SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_nil();
+  // check selection
+  LightApp_SelectionMgr *Sel = selectionMgr();
+  SALOME_ListIO selected; Sel->selectedObjects( selected );
+
+  if (selected.Extent() == 1)
+    aMesh = SMESH::GetMeshByIO(selected.First());
+  if (aMesh->_is_nil()) {
+    SUIT_MessageBox::warning(desktop(),
+                             tr("SMESH_WRN_WARNING"),
+                             tr("SMESH_WRN_NO_AVAILABLE_DATA"));
+    onCancel();
+    return;
+  }
+
+  myMgr = new SMESHGUI_MeshOrderMgr( myDlg->GetMeshOrderBox() );
+  myMgr->SetMesh( aMesh );
+  if ( !myMgr->GetMeshOrder() ) {
+    SUIT_MessageBox::information(desktop(),
+                             tr("SMESH_INFORMATION"),
+                             tr("SMESH_NO_CONCURENT_MESH"));
+    
+    onCancel();
+    return;
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Apply changes
+ */
+//================================================================================
+
+bool SMESHGUI_MeshOrderOp::onApply()
+{
+  SUIT_OverrideCursor aWaitCursor;
+  bool res = myMgr ? myMgr->SetMeshOrder() : false;
+
+  if( res )
+    SMESHGUI::Modified();
+
+  delete myMgr;
+  myMgr = 0;
+
+  return res;
+}
+
+//================================================================================
+/*!
+ * \brief Apply changes
+ */
+//================================================================================
+
+void SMESHGUI_MeshOrderOp::onCancel()
+{
+  delete myMgr;
+  myMgr = 0;
+
+  abort();
+}
+
+//================================================================================
+/*!
+ * \brief Constructor
+*/
+//================================================================================
+
+SMESHGUI_MeshOrderMgr::SMESHGUI_MeshOrderMgr( SMESHGUI_MeshOrderBox* theBox )
+: myBox( theBox )
+{
+  myMesh = SMESH::SMESH_Mesh::_nil();
+}
+
+//================================================================================
+/*!
+ * \brief Destructor
+*/
+//================================================================================
+
+SMESHGUI_MeshOrderMgr::~SMESHGUI_MeshOrderMgr()
+{
+}
+
+//================================================================================
+/*!
+ * \brief Set root mesh object
+ */
+//================================================================================
+
+void SMESHGUI_MeshOrderMgr::SetMesh(SMESH::SMESH_Mesh_var& theMesh)
+{
+  myMesh = SMESH::SMESH_Mesh::_duplicate(theMesh);
+  _PTR(SObject) aMeshSObj = SMESH::FindSObject(theMesh);
+  if ( myBox && aMeshSObj )
+    myBox->setTitle( aMeshSObj->GetName().c_str() );
+}  
+
+//================================================================================
+/*!
+ * \brief Check for concurents between submesh objects
+ */
+//================================================================================
+
+bool SMESHGUI_MeshOrderMgr::GetMeshOrder()
+{
+  ListListId   idListList;
+  return GetMeshOrder(idListList);
+}
+
+//================================================================================
+/*!
+ * \brief Check for concurents between submesh objects
+ */
+//================================================================================
+
+bool SMESHGUI_MeshOrderMgr::GetMeshOrder(ListListId& theIdListList)
+{
+  if (!myBox || myMesh->_is_nil())
+    return false;
+  myBox->Clear();
+  SMESH::submesh_array_array_var meshOrder = myMesh->GetMeshOrder();
+  if ( !meshOrder.operator->() || !meshOrder->length() )
+    return false;
+  ListListName nameListList;
+  for ( int i = 0, n = meshOrder->length(); i < n; i++ )
+  {
+    QList<int> idList;
+    QStringList nameList;
+    const SMESH::submesh_array& aSMArray = meshOrder[i];
+    for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
+    {
+      const SMESH::SMESH_subMesh_var subMesh = aSMArray[j];
+      
+      _PTR(SObject) aSubMeshSObj = SMESH::FindSObject(subMesh);
+      if ( !aSubMeshSObj )
+        continue;
+
+      idList.append(subMesh->GetId() );
+      nameList.append( QString(aSubMeshSObj->GetName().c_str()) );
+    }
+    theIdListList.append(idList);
+    nameListList.append(nameList);
+  }
+  myBox->SetMeshes(nameListList, theIdListList);
+  return !theIdListList.isEmpty();
+}
+
+//================================================================================
+/*!
+ * \brief Returns status is order changed by user
+ */
+//================================================================================
+
+bool SMESHGUI_MeshOrderMgr::IsOrderChanged() const
+{
+  return myBox && myBox->IsOrderChanged();
+}
+
+//================================================================================
+/*!
+ * \brief Store submesh priority order
+ */
+//================================================================================
+
+bool SMESHGUI_MeshOrderMgr::SetMeshOrder()
+{
+  return myBox ? SetMeshOrder(myBox->GetMeshIds()) : false;
+}
+
+//================================================================================
+/*!
+ * \brief Store submesh priority order
+ */
+//================================================================================
+
+bool SMESHGUI_MeshOrderMgr::SetMeshOrder( const  ListListId& theListListIds )
+{
+  if (theListListIds.isEmpty() || myMesh->_is_nil())
+    return false;
+
+  _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
+  _PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh);
+  if ( !aStudy || !aMeshSObj )
+    return false;
+
+  std::map<int, SMESH::SMESH_subMesh_var> mapOfSubMesh;
+  for (int i = SMESH::Tag_FirstSubMesh; i <= SMESH::Tag_LastSubMesh; i++) {
+    _PTR(SObject) aSubmeshRoot;
+    if ( !aMeshSObj->FindSubObject( i, aSubmeshRoot ) )
+      continue;
+    _PTR(ChildIterator) smIter = aStudy->NewChildIterator( aSubmeshRoot );
+    for ( ; smIter->More(); smIter->Next() ) {
+      _PTR(SObject) aSmObj = smIter->Value();
+      SMESH::SMESH_subMesh_var sm =
+        SMESH::SObjectToInterface<SMESH::SMESH_subMesh>( aSmObj );
+      mapOfSubMesh[ sm->GetId() ] = SMESH::SMESH_subMesh::_duplicate(sm);
+    }
+  }
+
+  // is it enought to set modifid attribute on root mesh objects only?
+  //  it is seems that modifaction flag will be set on child submeshes 
+  //  automatically  (see SMESH::ModifiedMesh for details)
+  SMESH::ModifiedMesh( aMeshSObj, false, false );
+
+  SMESH::submesh_array_array_var meshOrder = new SMESH::submesh_array_array();
+  meshOrder->length(theListListIds.count() );
+  ListListId::const_iterator it = theListListIds.constBegin();
+  for ( int i = 0; it != theListListIds.constEnd(); ++it ) {
+    const QList<int>& ids = *it;
+    SMESH::submesh_array_var subMeshList = new SMESH::submesh_array();
+    subMeshList->length( ids.count() );
+    QList<int>::const_iterator subIt = ids.constBegin();
+    for( int j = 0; subIt != ids.constEnd(); ++subIt )
+      if ( mapOfSubMesh.find( *subIt ) != mapOfSubMesh.end() )
+        subMeshList[ j++ ] = mapOfSubMesh[ *subIt ];
+
+    meshOrder[ i++ ] = subMeshList;
+  }
+  // update object browser
+  SMESHGUI::GetSMESHGUI()->updateObjBrowser( true, 0 );
+
+  return myMesh->SetMeshOrder(meshOrder);
+}
diff --git a/src/SMESHGUI/SMESHGUI_MeshOrderOp.h b/src/SMESHGUI/SMESHGUI_MeshOrderOp.h
new file mode 100644 (file)
index 0000000..f21e848
--- /dev/null
@@ -0,0 +1,93 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+// File   : SMESHGUI_MeshOrderOp.h
+// Author : Pavel TELKOV, Open CASCADE S.A.S.
+//
+#ifndef SMESHGUI_MeshOrderOp_H
+#define SMESHGUI_MeshOrderOp_H
+
+
+// SMESH includes
+#include "SMESH_SMESHGUI.hxx"
+
+#include "SMESHGUI_Operation.h"
+#include "SMESHGUI_MeshOrderDlg.h"
+
+// IDL includes
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Gen)
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+
+/*!
+ * \brief Operator to check and modify mesh computation submesh priority (order)
+ */
+class SMESHGUI_EXPORT SMESHGUI_MeshOrderMgr
+{
+public:
+  SMESHGUI_MeshOrderMgr( SMESHGUI_MeshOrderBox* );
+  virtual ~SMESHGUI_MeshOrderMgr();
+  //! Set root mesh object
+  void                   SetMesh( SMESH::SMESH_Mesh_var& theMesh );
+  //! Check for concurents between submesh objects
+  bool                   GetMeshOrder();
+  //! Check for concurents between submesh objects
+  bool                   GetMeshOrder( ListListId& theIds );
+  //! Store submesh priority order
+  bool                   SetMeshOrder();
+  //! Store given submesh priority order
+  bool                   SetMeshOrder( const  ListListId& theIds );
+
+  //! Returns status is order changed by user
+  bool                   IsOrderChanged() const;
+
+private:
+  SMESH::SMESH_Mesh_var  myMesh;
+  SMESHGUI_MeshOrderBox* myBox;
+};
+
+/*!
+ * \brief Operator to check and modify mesh computation submesh priority (order)
+ */
+class SMESHGUI_EXPORT SMESHGUI_MeshOrderOp: public SMESHGUI_Operation
+{
+  Q_OBJECT
+
+public:
+  SMESHGUI_MeshOrderOp();
+  virtual ~SMESHGUI_MeshOrderOp();
+
+protected:
+  virtual LightApp_Dialog* dlg() const;
+
+  virtual void           startOperation();
+
+  //! sets the dialog widgets to state just after operation start
+  virtual void           initDialog();
+
+ protected slots:
+  virtual bool           onApply();
+  virtual void           onCancel();
+
+ private:
+  SMESHGUI_MeshOrderDlg* myDlg;
+  SMESHGUI_MeshOrderMgr* myMgr;
+};
+
+#endif // SMESHGUI_MeshOrderOp_H
index 8456928f772b1cd96094c5d28c172ea1186fbcc9..cfb1f0e649200e04b3d3db5fa9a6ac26b110c357 100755 (executable)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_MeshPatternDlg.cxx
 // Author : Sergey LITONIN, Open CASCADE S.A.S.
@@ -397,7 +398,7 @@ void SMESHGUI_MeshPatternDlg::Init()
 
   updateGeometry();
 
-  resize(minimumSize());
+  resize(100,100);
 
   activateSelection();
   onSelectionDone();
@@ -420,10 +421,10 @@ bool SMESHGUI_MeshPatternDlg::isValid (const bool theMess)
       ok = myNode2->isValid( msg, theMess ) && ok;
     if( !ok ) {
       if( theMess ) {
-       QString str( tr( "SMESH_INCORRECT_INPUT" ) );
-       if ( !msg.isEmpty() )
-         str += "\n" + msg;
-       SUIT_MessageBox::critical( this, tr( "SMESH_ERROR" ), str );
+        QString str( tr( "SMESH_INCORRECT_INPUT" ) );
+        if ( !msg.isEmpty() )
+          str += "\n" + msg;
+        SUIT_MessageBox::critical( this, tr( "SMESH_ERROR" ), str );
       }
       return false;
     }
@@ -432,22 +433,22 @@ bool SMESHGUI_MeshPatternDlg::isValid (const bool theMess)
   QList<int> ids;
   if ((isRefine() &&
        (myMesh->_is_nil() || !getIds(ids) || getNode(false) < 0 ||
-        myType == Type_3d && (getNode(true) < 0 || getNode(false) == getNode(true))))
+        (myType == Type_3d && (getNode(true) < 0 || getNode(false) == getNode(true)))))
       ||
       (!isRefine() &&
        (myMesh->_is_nil() || myMeshShape->_is_nil() || myGeomObj[ Object ]->_is_nil() ||
-        myGeomObj[ Vertex1 ]->_is_nil() || myType == Type_3d && myGeomObj[ Vertex2 ]->_is_nil())))
+        myGeomObj[ Vertex1 ]->_is_nil() || (myType == Type_3d && myGeomObj[ Vertex2 ]->_is_nil()))))
   {
     if (theMess)
       SUIT_MessageBox::information(this, tr("SMESH_INSUFFICIENT_DATA"),
-                                  tr("SMESHGUI_INVALID_PARAMETERS"));
+                                   tr("SMESHGUI_INVALID_PARAMETERS"));
     return false;
   }
 
   if ( myName->text().isEmpty() ) {
     if (theMess)
       SUIT_MessageBox::information(this, tr("SMESH_INSUFFICIENT_DATA"),
-                                  tr("SMESHGUI_INVALID_PARAMETERS"));
+                                   tr("SMESHGUI_INVALID_PARAMETERS"));
     return false;
   }
 
@@ -467,22 +468,23 @@ bool SMESHGUI_MeshPatternDlg::onApply()
     erasePreview();
 
     if (isRefine()) { // Refining existing mesh elements
+      {
+        QStringList aParameters;
+        aParameters << myNode1->text();
+        if(myType == Type_3d )
+          aParameters << myNode2->text();
+        myMesh->SetParameters( aParameters.join(":").toLatin1().constData() );
+      }
       QList<int> ids;
       getIds(ids);
       SMESH::long_array_var varIds = new SMESH::long_array();
       varIds->length(ids.count());
       int i = 0;
       for (QList<int>::iterator it = ids.begin(); it != ids.end(); ++it)
-       varIds[i++] = *it;
+        varIds[i++] = *it;
       myType == Type_2d
-       ? myPattern->ApplyToMeshFaces  (myMesh, varIds, getNode(false), myReverseChk->isChecked())
-       : myPattern->ApplyToHexahedrons(myMesh, varIds, getNode(false), getNode(true));
-
-      QStringList aParameters;
-      aParameters << myNode1->text();
-      if(myType == Type_3d )
-       aParameters << myNode2->text();
-      myMesh->SetParameters( SMESHGUI::JoinObjectParameters(aParameters) );
+        ? myPattern->ApplyToMeshFaces  (myMesh, varIds, getNode(false), myReverseChk->isChecked())
+        : myPattern->ApplyToHexahedrons(myMesh, varIds, getNode(false), getNode(true));
 
     } else { // Applying a pattern to geometrical object
       if (myType == Type_2d)
@@ -497,18 +499,19 @@ bool SMESHGUI_MeshPatternDlg::onApply()
       //mySelectionMgr->clearSelected();
       bool autoUpdate = SMESHGUI::automaticUpdate();
       if (!isRefine() && autoUpdate) {
-       _PTR(SObject) aSO = SMESH::FindSObject(myMesh.in());
-       SMESH_Actor* anActor = SMESH::FindActorByEntry(aSO->GetID().c_str());
-       if (!anActor) {
-         anActor = SMESH::CreateActor(aSO->GetStudy(), aSO->GetID().c_str());
-         if (anActor) {
-           SMESH::DisplayActor(SMESH::GetActiveWindow(), anActor);
-           SMESH::FitAll();
-         }
-       }
+        _PTR(SObject) aSO = SMESH::FindSObject(myMesh.in());
+        SMESH_Actor* anActor = SMESH::FindActorByEntry(aSO->GetID().c_str());
+        if (!anActor) {
+          anActor = SMESH::CreateActor(aSO->GetStudy(), aSO->GetID().c_str());
+          if (anActor) {
+            SMESH::DisplayActor(SMESH::GetActiveWindow(), anActor);
+            SMESH::FitAll();
+          }
+        }
       }
       mySelectionMgr->clearSelected();
       SMESH::UpdateView();
+      SMESHGUI::Modified();
 
       mySMESHGUI->updateObjBrowser(true);
 
@@ -517,7 +520,7 @@ bool SMESHGUI_MeshPatternDlg::onApply()
       return true;
     } else {
       SUIT_MessageBox::information(this, tr("SMESH_ERROR"),
-                                  tr("SMESH_OPERATION_FAILED"));
+                                   tr("SMESH_OPERATION_FAILED"));
       return false;
     }
   } catch (const SALOME::SALOME_Exception& S_ex) {
@@ -565,17 +568,17 @@ void SMESHGUI_MeshPatternDlg::onHelp()
   if (app) 
     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
   else {
-               QString platform;
+                QString platform;
 #ifdef WIN32
-               platform = "winapplication";
+                platform = "winapplication";
 #else
-               platform = "application";
+                platform = "application";
 #endif
     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser", 
-                                                                platform)).
-                            arg(myHelpFileName));
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser", 
+                                                                 platform)).
+                             arg(myHelpFileName));
   }
 }
 
@@ -593,7 +596,7 @@ void SMESHGUI_MeshPatternDlg::onSelectionDone()
       SALOME_ListIO aList;
       mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
       if (aList.Extent() != 1)
-       return;
+        return;
 
       // Retrieve mesh from selection
       Handle(SALOME_InteractiveObject) anIO = aList.First();
@@ -624,11 +627,11 @@ void SMESHGUI_MeshPatternDlg::onSelectionDone()
       SALOME_ListIO aList;
       mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
       if (aList.Extent() != 1)
-       return;
+        return;
 
       QString anIds;
       if (!SMESH::GetNameOfSelectedElements(mySelector, aList.First(), anIds))
-       anIds = "";
+        anIds = "";
 
       myBusy = true;
       mySelEdit[ Ids ]->setText(anIds);
@@ -638,7 +641,7 @@ void SMESHGUI_MeshPatternDlg::onSelectionDone()
       SALOME_ListIO aList;
       mySelectionMgr->selectedObjects(aList, SVTK_Viewer::Type());
       if (aList.Extent() != 1)
-       return;
+        return;
 
       // Get geom object from selection
       Handle(SALOME_InteractiveObject) anIO = aList.First();
@@ -809,14 +812,14 @@ void SMESHGUI_MeshPatternDlg::onOpen()
   QFile aFile(fName);
   if (!aFile.open(QIODevice::ReadOnly)) {
     SUIT_MessageBox::information(this, tr("SMESH_ERROR"),
-                                tr("ERROR_OF_OPENING"));
+                                 tr("ERROR_OF_OPENING"));
     return;
   }
 
   QByteArray aDataArray = aFile.readAll();
   if (aDataArray.isEmpty()) {
     SUIT_MessageBox::information(this, tr("SMESH_ERROR"),
-                                tr("ERROR_OF_READING"));
+                                 tr("ERROR_OF_READING"));
     return;
   }
 
@@ -1046,11 +1049,11 @@ void SMESHGUI_MeshPatternDlg::updateWgState()
     if (!CORBA::is_nil(myPattern)/* && getIds(ids)*/) {
       SMESH::long_array_var keyPoints = myPattern->GetKeyPoints();
       if (keyPoints->length()) {
-       myNode1->setEnabled(true);
-       myNode2->setEnabled(true);
-       myNode1->setRange(1, keyPoints->length());
-       myNode2->setRange(1, keyPoints->length());
-       return;
+        myNode1->setEnabled(true);
+        myNode2->setEnabled(true);
+        myNode1->setRange(1, keyPoints->length());
+        myNode2->setRange(1, keyPoints->length());
+        return;
       }
     }
 
@@ -1075,13 +1078,13 @@ void SMESHGUI_MeshPatternDlg::activateSelection()
 
     if (myType == Type_2d)
       {
-       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-         aViewWindow->SetSelectionMode(FaceSelection);
+        if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+          aViewWindow->SetSelectionMode(FaceSelection);
       }
     else
       {
-       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-         aViewWindow->SetSelectionMode(CellSelection);
+        if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+          aViewWindow->SetSelectionMode(CellSelection);
       }
   }
   else {
@@ -1123,7 +1126,7 @@ bool SMESHGUI_MeshPatternDlg::loadFromFile (const QString& theName)
     SMESH::SMESH_Pattern_var aPattern = SMESH::GetPattern();
 
     if (!aPattern->LoadFromFile(theName.toLatin1().data()) ||
-        myType == Type_2d && !aPattern->Is2D()) {
+        (myType == Type_2d && !aPattern->Is2D())) {
       SMESH::SMESH_Pattern::ErrorCode aCode = aPattern->GetErrorCode();
       QString aMess;
       if      (aCode == SMESH::SMESH_Pattern::ERR_READ_NB_POINTS     ) aMess = tr("ERR_READ_NB_POINTS");
@@ -1146,7 +1149,7 @@ bool SMESHGUI_MeshPatternDlg::loadFromFile (const QString& theName)
   } catch (const SALOME::SALOME_Exception& S_ex) {
     SalomeApp_Tools::QtCatchCorbaException(S_ex);
     SUIT_MessageBox::information(this, tr("SMESH_ERROR"),
-                                tr("ERROR_OF_LOADING") );
+                                 tr("ERROR_OF_LOADING") );
     return false;
   }
 }
@@ -1229,13 +1232,13 @@ vtkUnstructuredGrid* SMESHGUI_MeshPatternDlg::getGrid()
       varIds->length(ids.count());
       int i = 0;
       for (QList<int>::iterator it = ids.begin(); it != ids.end(); ++it)
-       varIds[i++] = *it;
+        varIds[i++] = *it;
       pnts = myType == Type_2d
-       ? myPattern->ApplyToMeshFaces  (myMesh, varIds, getNode(false), myReverseChk->isChecked())
-       : myPattern->ApplyToHexahedrons(myMesh, varIds, getNode(false), getNode(true));
+        ? myPattern->ApplyToMeshFaces  (myMesh, varIds, getNode(false), myReverseChk->isChecked())
+        : myPattern->ApplyToHexahedrons(myMesh, varIds, getNode(false), getNode(true));
     } else {
       pnts = myType == Type_2d
-       ? myPattern->ApplyToFace   (myGeomObj[ Object ], myGeomObj[ Vertex1 ], myReverseChk->isChecked())
+        ? myPattern->ApplyToFace   (myGeomObj[ Object ], myGeomObj[ Vertex1 ], myReverseChk->isChecked())
       : myPattern->ApplyTo3DBlock(myGeomObj[ Object ], myGeomObj[ Vertex1 ], myGeomObj[ Vertex2 ]);
     }
 
@@ -1380,7 +1383,7 @@ void SMESHGUI_MeshPatternDlg::onTextChanged (const QString& theNewText)
     for (int i = 0; i < aListId.count(); i++) {
       const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt());
       if (e && e->GetType() == (myType == Type_2d ? SMDSAbs_Face : SMDSAbs_Volume))
-       newIndices.Add(e->GetID());
+        newIndices.Add(e->GetID());
     }
     mySelector->AddOrRemoveIndex( anActor->getIO(), newIndices, false);
     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
index e3e2d6870b910b1b30b68e3d8391d93d3f2b83a2..76e6aca7738483d755961b4b04d31e00b7db1b19 100755 (executable)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : SMESHGUI_MeshPatternDlg.h
 // Author : Sergey LITONIN, Open CASCADE S.A.S.
 //
index b524c2f83efe936250a665a5dffa51fa756a3d69..13898d9910b17a2c682979e4991359478c1d4c30 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_MeshUtils.cxx
 // Author : Open CASCADE S.A.S.
@@ -26,6 +27,7 @@
 //
 #include "SMESHGUI_MeshUtils.h"
 
+#include "SMESHGUI.h"
 #include "SMESHGUI_Utils.h"
 
 // SALOME KERNEL includes
@@ -37,6 +39,7 @@
 // IDL includes
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_Measurements)
 
 namespace SMESH
 {
@@ -46,13 +49,13 @@ namespace SMESH
     if(!CORBA::is_nil(anObj)){
       SMESH_Mesh_var aMesh = SMESH_Mesh::_narrow(anObj);
       if(!CORBA::is_nil(aMesh))
-       return aMesh;
+        return aMesh;
       SMESH_GroupBase_var aGroup = SMESH_GroupBase::_narrow(anObj);
       if(!CORBA::is_nil(aGroup))
-       return aGroup->GetMesh();
+        return aGroup->GetMesh();
       SMESH_subMesh_var aSubMesh = SMESH_subMesh::_narrow(anObj);
       if(!CORBA::is_nil(aSubMesh))
-       return aSubMesh->GetFather();
+        return aSubMesh->GetFather();
     }
     return SMESH_Mesh::_nil();
   }
@@ -65,20 +68,69 @@ namespace SMESH
       QString name = baseName;
       while ( !aStudy->FindObjectByName( name.toLatin1().data(), "SMESH" ).empty() ) {
         int nb = 0;
-       QStringList names = name.split("_", QString::KeepEmptyParts);
-       if ( names.count() > 0 ) {
-         bool ok;
-         int index = names.last().toInt( &ok );
-         if ( ok ) {
-           nb = index;
-           names.removeLast();
-         }
-       }
-       names.append( QString::number( nb+1 ) );
-       name = names.join( "_" );
+        QStringList names = name.split("_", QString::KeepEmptyParts);
+        if ( names.count() > 0 ) {
+          bool ok;
+          int index = names.last().toInt( &ok );
+          if ( ok ) {
+            nb = index;
+            names.removeLast();
+          }
+        }
+        names.append( QString::number( nb+1 ) );
+        name = names.join( "_" );
       }
       return name;
     }
     return baseName;
   }
+
+  QString UniqueName(const QString& theBaseName, _PTR(SObject) theParent, const QString& thePostfix)
+  {
+    QString baseName = thePostfix.isEmpty() ? 
+      theBaseName : theBaseName + "_" + thePostfix;
+    QString name = baseName;
+    if ( _PTR(Study) aStudy = GetActiveStudyDocument() ) {
+      _PTR(SObject) p = theParent;
+      if ( !p ) p = aStudy->FindComponent( "SMESH" );
+      if ( p ) {
+        _PTR(ChildIterator) iter = aStudy->NewChildIterator( p );
+        int idx = 0;
+        while( true ) {
+          bool found = false;
+          for ( ; iter->More(); iter->Next() ) {
+            _PTR(SObject) so = iter->Value();
+            if ( !so ) continue; // skip bad objects
+            _PTR(SObject) ref;
+            if ( so->ReferencedObject( ref ) ) continue; // skip references
+            QString n = so->GetName().c_str();
+            if ( !n.isEmpty() && n == name ) {
+              QStringList names = name.split("_", QString::KeepEmptyParts);
+              if ( names.count() > 0 ) {
+                bool ok;
+                names.last().toInt( &ok );
+                if ( ok )
+                  names.removeLast();
+              }
+              names.append( QString::number( ++idx ) );
+              name = names.join( "_" );
+              found = true;
+              break;
+            }
+          }
+          if ( !found ) break;
+        }
+      }
+    }
+    return name;
+  }
+
+  SMESH::Measurements_var& GetMeasurements()
+  {
+    static SMESH::Measurements_var aMeasurements;
+    if (CORBA::is_nil(aMeasurements)) {
+      aMeasurements = SMESHGUI::GetSMESHGen()->CreateMeasurements();
+    }
+    return aMeasurements;
+  }
 } // end of namespace SMESH
index 0544d4306b0619c3be61735007258a371efee241..1adbabccc7e8c9c60501bd6b6c900afa193f396a 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_MeshUtils.h
 // Author : Open CASCADE S.A.S.
 // SALOME GUI includes
 #include <SALOME_InteractiveObject.hxx>
 
+// SALOME KERNEL includes
+#include <SALOMEDSClient_definitions.hxx>
+
 // IDL includes
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_Measurements)
+
+class SALOMEDSClient_SObject;
 
 namespace SMESH
 {
@@ -46,6 +53,10 @@ namespace SMESH
  
   SMESHGUI_EXPORT
     QString        UniqueMeshName( const QString&, const QString& = QString() );
+  SMESHGUI_EXPORT
+    QString        UniqueName( const QString&, _PTR(SObject) = _PTR(SObject)(), const QString& = QString() );
+
+  SMESHGUI_EXPORT  SMESH::Measurements_var& GetMeasurements();
 }
 
 #endif // SMESHGUI_MESHUTILS_H
diff --git a/src/SMESHGUI/SMESHGUI_MoveNodesDlg.cxx b/src/SMESHGUI/SMESHGUI_MoveNodesDlg.cxx
deleted file mode 100644 (file)
index 1995752..0000000
+++ /dev/null
@@ -1,660 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-// SMESH SMESHGUI : GUI for SMESH component
-// File   : SMESHGUI_MoveNodesDlg.cxx
-// Author : Nicolas REJNERI, Open CASCADE S.A.S.
-// SMESH includes
-//
-#include "SMESHGUI_MoveNodesDlg.h"
-
-#include "SMESHGUI.h"
-#include "SMESHGUI_SpinBox.h"
-#include "SMESHGUI_IdValidator.h"
-#include "SMESHGUI_Utils.h"
-#include "SMESHGUI_VTKUtils.h"
-#include "SMESHGUI_MeshUtils.h"
-
-#include <SMESH_Actor.h>
-#include <SMDS_Mesh.hxx>
-
-// SALOME GUI includes
-#include <LightApp_SelectionMgr.h>
-#include <LightApp_Application.h>
-#include <SUIT_ResourceMgr.h>
-#include <SUIT_Desktop.h>
-#include <SUIT_Session.h>
-#include <SUIT_MessageBox.h>
-
-#include <SVTK_ViewModel.h>
-#include <SVTK_ViewWindow.h>
-#include <SALOME_ListIO.hxx>
-
-#include <VTKViewer_CellLocationsArray.h>
-
-// OCCT includes
-#include <TColStd_MapOfInteger.hxx>
-
-// VTK includes
-#include <vtkIdList.h>
-#include <vtkCellArray.h>
-#include <vtkUnsignedCharArray.h>
-#include <vtkUnstructuredGrid.h>
-#include <vtkDataSetMapper.h>
-#include <vtkProperty.h>
-
-// Qt includes
-#include <QGroupBox>
-#include <QLabel>
-#include <QLineEdit>
-#include <QPushButton>
-#include <QRadioButton>
-#include <QHBoxLayout>
-#include <QVBoxLayout>
-#include <QKeyEvent>
-#include <QButtonGroup>
-
-// IDL includes
-#include <SALOMEconfig.h>
-#include CORBA_SERVER_HEADER(SMESH_Mesh)
-#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
-
-#define SPACING 6
-#define MARGIN  11
-
-//=================================================================================
-// name    : SMESHGUI_MoveNodesDlg::SMESHGUI_MoveNodesDlg
-// Purpose :
-//=================================================================================
-SMESHGUI_MoveNodesDlg::SMESHGUI_MoveNodesDlg(SMESHGUI* theModule):
-  QDialog(SMESH::GetDesktop(theModule)),
-  mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
-  mySMESHGUI(theModule)
-{
-  myPreviewActor = 0;
-  myBusy = false;
-
-  setModal(false);
-  setWindowTitle(tr("CAPTION"));
-
-  QVBoxLayout* aDlgLay = new QVBoxLayout(this);
-  aDlgLay->setSpacing(SPACING);
-  aDlgLay->setMargin(MARGIN);
-
-  QWidget* aMainFrame = createMainFrame  (this);
-  QWidget* aBtnFrame  = createButtonFrame(this);
-
-  aDlgLay->addWidget(aMainFrame);
-  aDlgLay->addWidget(aBtnFrame);
-
-  mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
-
-  myHelpFileName = "moving_nodes_page.html";
-
-  Init();
-}
-
-//=======================================================================
-// name    : SMESHGUI_MoveNodesDlg::createButtonFrame
-// Purpose : Create frame containing buttons
-//=======================================================================
-QWidget* SMESHGUI_MoveNodesDlg::createButtonFrame (QWidget* theParent)
-{
-  QFrame* aFrame = new QFrame(theParent);
-  aFrame->setFrameStyle(QFrame::Box | QFrame::Sunken);
-
-  myOkBtn     = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), aFrame);
-  myApplyBtn  = new QPushButton(tr("SMESH_BUT_APPLY"), aFrame);
-  myCloseBtn  = new QPushButton(tr("SMESH_BUT_CLOSE"), aFrame);
-  myHelpBtn   = new QPushButton(tr("SMESH_BUT_HELP"),  aFrame);
-
-  QHBoxLayout* aLay = new QHBoxLayout(aFrame);
-  aLay->setSpacing(SPACING);
-  aLay->setMargin(MARGIN);
-
-  aLay->addWidget(myOkBtn);
-  aLay->addSpacing(10);
-  aLay->addWidget(myApplyBtn);
-  aLay->addSpacing(10);
-  aLay->addStretch();
-  aLay->addWidget(myCloseBtn);
-  aLay->addWidget(myHelpBtn);
-
-  connect(myOkBtn,    SIGNAL(clicked()), SLOT(onOk()));
-  connect(myCloseBtn, SIGNAL(clicked()), SLOT(onClose()));
-  connect(myApplyBtn, SIGNAL(clicked()), SLOT(onApply()));
-  connect(myHelpBtn,  SIGNAL(clicked()), SLOT(onHelp()));
-
-  return aFrame;
-}
-
-//=======================================================================
-// name    : SMESHGUI_MoveNodesDlg::createMainFrame
-// Purpose : Create frame containing dialog's input fields
-//=======================================================================
-QWidget* SMESHGUI_MoveNodesDlg::createMainFrame (QWidget* theParent)
-{
-  QWidget* aFrame = new QWidget(theParent);
-
-  QPixmap iconMoveNode (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_DLG_MOVE_NODE")));
-  QPixmap iconSelect   (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
-
-  //------------------------------------------------------------
-  QGroupBox* aPixGrp = new QGroupBox(tr("MESH_NODE"), aFrame);
-  QButtonGroup* aBtnGrp = new QButtonGroup(this);
-  QHBoxLayout* aPixGrpLayout = new QHBoxLayout(aPixGrp);
-  aPixGrpLayout->setSpacing(SPACING);
-  aPixGrpLayout->setMargin(MARGIN);
-
-  QRadioButton* aRBut = new QRadioButton(aPixGrp);
-  aRBut->setIcon(iconMoveNode);
-  aRBut->setChecked(true);
-
-  aPixGrpLayout->addWidget(aRBut);
-  aBtnGrp->addButton(aRBut, 0);
-
-  //------------------------------------------------------------
-  QGroupBox* anIdGrp = new QGroupBox(tr("SMESH_MOVE"), aFrame);
-  QHBoxLayout* anIdGrpLayout = new QHBoxLayout(anIdGrp);
-  anIdGrpLayout->setSpacing(SPACING);
-  anIdGrpLayout->setMargin(MARGIN);
-
-  QLabel* idLabl = new QLabel(tr("NODE_ID"), anIdGrp);
-  QPushButton* idBtn = new QPushButton(anIdGrp);
-  idBtn->setIcon(iconSelect);
-  myId = new QLineEdit(anIdGrp);
-  myId->setValidator(new SMESHGUI_IdValidator(this, 1));
-
-  anIdGrpLayout->addWidget(idLabl);
-  anIdGrpLayout->addWidget(idBtn);
-  anIdGrpLayout->addWidget(myId);
-
-  //------------------------------------------------------------
-  QGroupBox* aCoordGrp = new QGroupBox(tr("SMESH_COORDINATES"), aFrame);
-  QHBoxLayout* aCoordGrpLayout = new QHBoxLayout(aCoordGrp);
-  aCoordGrpLayout->setSpacing(SPACING);
-  aCoordGrpLayout->setMargin(MARGIN);
-
-  QLabel* aXLabel = new QLabel(tr("SMESH_X"), aCoordGrp);
-  myX = new SMESHGUI_SpinBox(aCoordGrp);
-
-  QLabel* aYLabel = new QLabel(tr("SMESH_Y"), aCoordGrp);
-  myY = new SMESHGUI_SpinBox(aCoordGrp);
-
-  QLabel* aZLabel = new QLabel(tr("SMESH_Z"), aCoordGrp);
-  myZ = new SMESHGUI_SpinBox(aCoordGrp);
-
-  aCoordGrpLayout->addWidget(aXLabel);
-  aCoordGrpLayout->addWidget(myX);
-  aCoordGrpLayout->addWidget(aYLabel);
-  aCoordGrpLayout->addWidget(myY);
-  aCoordGrpLayout->addWidget(aZLabel);
-  aCoordGrpLayout->addWidget(myZ);
-
-  //------------------------------------------------------------
-  myX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 25.0, DBL_DIGITS_DISPLAY);
-  myY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 25.0, DBL_DIGITS_DISPLAY);
-  myZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 25.0, DBL_DIGITS_DISPLAY);
-
-  //------------------------------------------------------------
-  QVBoxLayout* aLay = new QVBoxLayout(aFrame);
-  aLay->setMargin(0);
-  aLay->setMargin(SPACING);
-  aLay->addWidget(aPixGrp);
-  aLay->addWidget(anIdGrp);
-  aLay->addWidget(aCoordGrp);
-
-  //------------------------------------------------------------
-  // connect signale and slots
-  connect(myX, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
-  connect(myY, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
-  connect(myZ, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
-  connect(myId, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
-
-  return aFrame;
-}
-
-//=======================================================================
-// name    : SMESHGUI_MoveNodesDlg::~SMESHGUI_MoveNodesDlg
-// Purpose :
-//=======================================================================
-SMESHGUI_MoveNodesDlg::~SMESHGUI_MoveNodesDlg()
-{
-  erasePreview();
-}
-
-//=======================================================================
-// name    : SMESHGUI_MoveNodesDlg::Init
-// Purpose : Init dialog fields
-//=======================================================================
-void SMESHGUI_MoveNodesDlg::Init()
-{
-  myPreviewActor = 0;
-  myMeshActor = 0;
-  myBusy = false;
-
-  mySMESHGUI->SetActiveDialogBox((QDialog*)this);
-
-  // selection and SMESHGUI
-  connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone()));
-  connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate()));
-  connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(onClose()));
-
-  reset();
-  setEnabled(true);
-
-  // set selection mode
-  SMESH::SetPointRepresentation(true);
-  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-    aViewWindow->SetSelectionMode(NodeSelection);
-
-  onSelectionDone();
-}
-
-//=======================================================================
-// name    : SMESHGUI_MoveNodesDlg::isValid
-// Purpose : Verify validity of entry information
-//=======================================================================
-bool SMESHGUI_MoveNodesDlg::isValid (const bool theMess)
-{
-  if (myId->text().isEmpty()) {
-    if (theMess)
-      SUIT_MessageBox::information(this, tr("SMESH_WARNING"),
-                                  tr("NODE_ID_IS_NOT_DEFINED"));
-    return false;
-  }
-
-  QString msg;
-  bool ok = true;
-  ok = myX->isValid( msg, theMess ) && ok;
-  ok = myY->isValid( msg, theMess ) && ok;
-  ok = myZ->isValid( msg, theMess ) && ok;
-  if( !ok ) {
-    if( theMess ) {
-      QString str( tr( "SMESH_INCORRECT_INPUT" ) );
-      if ( !msg.isEmpty() )
-       str += "\n" + msg;
-      SUIT_MessageBox::critical( this, tr( "SMESH_ERROR" ), str );
-    }
-    return false;
-  }
-
-  return true;
-}
-
-//=======================================================================
-// name    : SMESHGUI_MoveNodesDlg::reset
-// Purpose : Reset the dialog state
-//=======================================================================
-void SMESHGUI_MoveNodesDlg::reset()
-{
-  myId->clear();
-  myX->SetValue(0);
-  myY->SetValue(0);
-  myZ->SetValue(0);
-  redisplayPreview();
-  updateButtons();
-}
-
-//=======================================================================
-// name    : SMESHGUI_MoveNodesDlg::onApply
-// Purpose : SLOT called when "Apply" button pressed.
-//=======================================================================
-bool SMESHGUI_MoveNodesDlg::onApply()
-{
-  if (mySMESHGUI->isActiveStudyLocked())
-    return false;
-
-  if (!isValid(true))
-    return false;
-
-  SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(myMeshActor->getIO());
-  if (aMesh->_is_nil()) {
-    SUIT_MessageBox::information(this, tr("SMESH_ERROR"),
-                                tr("SMESHG_NO_MESH"));
-    return false;
-  }
-
-  SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
-  if (aMeshEditor->_is_nil())
-    return false;
-
-  int anId = myId->text().toInt();
-  bool aResult = false;
-  try {
-    aResult = aMeshEditor->MoveNode(anId, myX->GetValue(), myY->GetValue(), myZ->GetValue());
-
-    QStringList aParameters;
-    aParameters << myX->text();
-    aParameters << myY->text();
-    aParameters << myZ->text();
-    aMesh->SetParameters( SMESHGUI::JoinObjectParameters(aParameters) );
-  } catch (...) {
-  }
-
-  if (aResult) {
-    SALOME_ListIO aList;
-    aList.Append(myMeshActor->getIO());
-    mySelectionMgr->setSelectedObjects(aList,false);
-    SMESH::UpdateView();
-    reset();
-  }
-
-  return aResult;
-}
-
-//=======================================================================
-// name    : SMESHGUI_MoveNodesDlg::onOk
-// Purpose : SLOT called when "Ok" button pressed.
-//=======================================================================
-void SMESHGUI_MoveNodesDlg::onOk()
-{
-  if (onApply())
-    onClose();
-}
-
-//=======================================================================
-// name    : SMESHGUI_MoveNodesDlg::onClose
-// Purpose : SLOT called when "Close" button pressed. Close dialog
-//=======================================================================
-void SMESHGUI_MoveNodesDlg::onClose()
-{
-  //mySelectionMgr->clearSelected();
-  SMESH::SetPointRepresentation(false);
-  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-    aViewWindow->SetSelectionMode(ActorSelection);
-  disconnect(mySelectionMgr, 0, this, 0);
-  disconnect(mySMESHGUI, 0, this, 0);
-  erasePreview();
-  mySMESHGUI->ResetState();
-  reject();
-}
-
-//=================================================================================
-// function : onHelp()
-// purpose  :
-//=================================================================================
-void SMESHGUI_MoveNodesDlg::onHelp()
-{
-  LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
-  if (app) 
-    app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
-  else {
-               QString platform;
-#ifdef WIN32
-               platform = "winapplication";
-#else
-               platform = "application";
-#endif
-    SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser", 
-                                                                platform)).
-                            arg(myHelpFileName));
-  }
-}
-
-//=======================================================================
-// name    : SMESHGUI_MoveNodesDlg::onTextChange
-// Purpose :
-//=======================================================================
-void SMESHGUI_MoveNodesDlg::onTextChange (const QString& theNewText)
-{
-  if (myBusy) return;
-
-  myOkBtn->setEnabled(false);
-  myApplyBtn->setEnabled(false);
-  erasePreview();
-
-  // select entered node
-  if(myMeshActor){
-    if(SMDS_Mesh* aMesh = myMeshActor->GetObject()->GetMesh()){
-      myBusy = true;
-      Handle(SALOME_InteractiveObject) anIO = myMeshActor->getIO();
-      SALOME_ListIO aList;
-      aList.Append(anIO);
-      mySelectionMgr->setSelectedObjects(aList,false);
-      myBusy = false;
-
-      if(const SMDS_MeshElement *anElem = aMesh->FindElement(theNewText.toInt())) {
-       TColStd_MapOfInteger aListInd;
-       aListInd.Add(anElem->GetID());
-       mySelector->AddOrRemoveIndex(anIO,aListInd, false);
-       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-         aViewWindow->highlight(anIO,true,true);
-       
-       onSelectionDone();
-      }
-    }
-  }
-}
-
-//=======================================================================
-// name    : SMESHGUI_MoveNodesDlg::onSelectionDone
-// Purpose : SLOT called when selection changed
-//=======================================================================
-void SMESHGUI_MoveNodesDlg::onSelectionDone()
-{
-  if (myBusy) return;
-  myMeshActor = 0;
-
-  SALOME_ListIO aList;
-  mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
-
-  if (aList.Extent() == 1) {
-    Handle(SALOME_InteractiveObject) anIO = aList.First();
-    myMeshActor = SMESH::FindActorByEntry(anIO->getEntry());
-    if(myMeshActor){
-      QString aText;
-      if (SMESH::GetNameOfSelectedNodes(mySelector,anIO,aText) == 1) {
-        if(SMDS_Mesh* aMesh = myMeshActor->GetObject()->GetMesh()) {
-          if(const SMDS_MeshNode* aNode = aMesh->FindNode(aText.toInt())) {
-            myBusy = true;
-            myId->setText(aText);
-            myX->SetValue(aNode->X());
-            myY->SetValue(aNode->Y());
-            myZ->SetValue(aNode->Z());
-            myBusy = false;
-            erasePreview(); // avoid overlapping of a selection and a preview
-            updateButtons();
-            return;
-          }
-        }
-      }
-    }
-  }
-
-  reset();
-}
-
-//=======================================================================
-// name    : SMESHGUI_MoveNodesDlg::onDeactivate
-// Purpose : SLOT called when dialog must be deativated
-//=======================================================================
-void SMESHGUI_MoveNodesDlg::onDeactivate()
-{
-  setEnabled(false);
-  erasePreview();
-}
-
-//=======================================================================
-// name    : SMESHGUI_MoveNodesDlg::enterEvent
-// Purpose : Event filter
-//=======================================================================
-void SMESHGUI_MoveNodesDlg::enterEvent (QEvent*)
-{
-  if (!isEnabled()) {
-    mySMESHGUI->EmitSignalDeactivateDialog();
-
-    // set selection mode
-    SMESH::SetPointRepresentation(true);
-    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-      aViewWindow->SetSelectionMode(NodeSelection);
-
-    redisplayPreview();
-
-    setEnabled(true);
-  }
-}
-
-//=======================================================================
-// name    : SMESHGUI_MoveNodesDlg::closeEvent
-// Purpose :
-//=======================================================================
-void SMESHGUI_MoveNodesDlg::closeEvent (QCloseEvent*)
-{
-  onClose();
-  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-    aViewWindow->Repaint();
-}
-
-//=======================================================================
-// name    : SMESHGUI_MoveNodesDlg::hideEvent
-// Purpose : may be caused by ESC key
-//=======================================================================
-void SMESHGUI_MoveNodesDlg::hideEvent (QHideEvent*)
-{
-  if (!isMinimized())
-    onClose();
-}
-
-//=======================================================================
-// name    : SMESHGUI_MoveNodesDlg::updateButtons
-// Purpose : Update buttons state
-//=======================================================================
-void SMESHGUI_MoveNodesDlg::updateButtons()
-{
-  bool isEnabled = isValid(false);
-  myOkBtn->setEnabled(isEnabled);
-  myApplyBtn->setEnabled(isEnabled);
-}
-
-//=======================================================================
-// name    : SMESHGUI_MoveNodesDlg::erasePreview
-// Purpose : Erase preview
-//=======================================================================
-void  SMESHGUI_MoveNodesDlg::erasePreview()
-{
-  if (myPreviewActor == 0)
-    return;
-
-  SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
-  if (aViewWindow)
-    aViewWindow->RemoveActor(myPreviewActor);
-  myPreviewActor->Delete();
-  myPreviewActor = 0;
-  if (aViewWindow)
-    aViewWindow->Repaint();
-}
-
-//=======================================================================
-// name    : SMESHGUI_MoveNodesDlg::redisplayPreview
-// Purpose : Redisplay preview
-//=======================================================================
-void SMESHGUI_MoveNodesDlg::redisplayPreview()
-{
-  if (myBusy)
-    return;
-
-  if (myPreviewActor != 0)
-    erasePreview();
-
-  if (!isValid(false))
-    return;
-
-  vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New();
-
-  vtkPoints* aPoints = vtkPoints::New();
-  aPoints->SetNumberOfPoints(1);
-  aPoints->SetPoint(0, myX->GetValue(), myY->GetValue(), myZ->GetValue());
-
-  // Create cells
-
-  vtkIdList *anIdList = vtkIdList::New();
-  anIdList->SetNumberOfIds(1);
-
-  vtkCellArray *aCells = vtkCellArray::New();
-  aCells->Allocate(2, 0);
-
-  vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
-  aCellTypesArray->SetNumberOfComponents(1);
-  aCellTypesArray->Allocate(1);
-
-  anIdList->SetId(0, 0);
-  aCells->InsertNextCell(anIdList);
-  aCellTypesArray->InsertNextValue(VTK_VERTEX);
-  anIdList->Delete();
-
-  VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
-  aCellLocationsArray->SetNumberOfComponents(1);
-  aCellLocationsArray->SetNumberOfTuples(1);
-
-  aCells->InitTraversal();
-  vtkIdType npts;
-  aCellLocationsArray->SetValue(0, aCells->GetTraversalLocation(npts));
-
-  aGrid->SetPoints(aPoints);
-  aPoints->Delete();
-
-  aGrid->SetCells(aCellTypesArray,aCellLocationsArray,aCells);
-  aCellLocationsArray->Delete();
-  aCellTypesArray->Delete();
-  aCells->Delete();
-
-  // Create and display actor
-  vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
-  aMapper->SetInput(aGrid);
-  aGrid->Delete();
-
-  myPreviewActor = SALOME_Actor::New();
-  myPreviewActor->PickableOff();
-  myPreviewActor->SetMapper(aMapper);
-  aMapper->Delete();
-
-  vtkProperty* aProp = vtkProperty::New();
-  aProp->SetRepresentationToWireframe();
-  aProp->SetColor(250, 0, 250);
-  aProp->SetPointSize(5);
-  myPreviewActor->SetProperty(aProp);
-  aProp->Delete();
-
-  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-    {
-      aViewWindow->AddActor(myPreviewActor);
-      aViewWindow->Repaint();
-    }
-}
-
-//=================================================================================
-// function : keyPressEvent()
-// purpose  :
-//=================================================================================
-void SMESHGUI_MoveNodesDlg::keyPressEvent( QKeyEvent* e )
-{
-  QDialog::keyPressEvent( e );
-  if ( e->isAccepted() )
-    return;
-
-  if ( e->key() == Qt::Key_F1 ) {
-    e->accept();
-    onHelp();
-  }
-}
diff --git a/src/SMESHGUI/SMESHGUI_MoveNodesDlg.h b/src/SMESHGUI/SMESHGUI_MoveNodesDlg.h
deleted file mode 100644 (file)
index cfd4378..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-// SMESH SMESHGUI : GUI for SMESH component
-// File   : SMESHGUI_MoveNodesDlg.h
-// Author : Nicolas REJNERI, Open CASCADE S.A.S.
-//
-#ifndef SMESHGUI_MOVENODESDLG_H
-#define SMESHGUI_MOVENODESDLG_H
-
-// SMESH includes
-#include "SMESH_SMESHGUI.hxx"
-
-// Qt includes
-#include <QDialog>
-
-class QLineEdit;
-class QPushButton;
-
-class SMESHGUI;
-class SMESH_Actor;
-class SMESHGUI_SpinBox;
-class SALOME_Actor;
-class SVTK_Selector;
-class LightApp_SelectionMgr;
-
-//=================================================================================
-// class    : SMESHGUI_MoveNodesDlg
-// purpose  :
-//=================================================================================
-class SMESHGUI_EXPORT SMESHGUI_MoveNodesDlg : public QDialog
-{ 
-  Q_OBJECT
-
-public:
-  SMESHGUI_MoveNodesDlg( SMESHGUI* );
-  virtual ~SMESHGUI_MoveNodesDlg();
-    
-  void                          Init();
-
-private slots:
-  void                          onOk();
-  bool                          onApply();
-  void                          onClose();
-  void                          onHelp();
-
-  void                          onDeactivate();
-
-  void                          onSelectionDone();
-  void                          redisplayPreview();
-  void                          onTextChange( const QString& );
-
-private:
-  void                          closeEvent( QCloseEvent* );
-  void                          enterEvent( QEvent* );
-  void                          hideEvent( QHideEvent* );
-  void                          keyPressEvent( QKeyEvent* );
-  void                          erasePreview();
-  QWidget*                      createButtonFrame( QWidget* );
-  QWidget*                      createMainFrame  ( QWidget* );
-  bool                          isValid( const bool );
-  void                          reset();
-  void                          updateButtons();
-
-private:
-  QPushButton*                  myOkBtn;
-  QPushButton*                  myApplyBtn;
-  QPushButton*                  myCloseBtn;
-  QPushButton*                  myHelpBtn;
-  
-  QLineEdit*                    myId;
-  SMESHGUI_SpinBox*             myX;
-  SMESHGUI_SpinBox*             myY;
-  SMESHGUI_SpinBox*             myZ;
-
-  LightApp_SelectionMgr*        mySelectionMgr;
-  SVTK_Selector*                mySelector;
-  SMESHGUI*                     mySMESHGUI;
-  
-  SALOME_Actor*                 myPreviewActor;
-  SMESH_Actor*                  myMeshActor;
-  bool                          myBusy;
-
-  QString                       myHelpFileName;
-};
-
-#endif // SMESHGUI_MOVENODESDLG_H
index 526c3f3e3ea8c5a492396320e96784aeae6deb7d..a12ca8fbe1fed72b8fa009a7d0efc5d2047877ce 100755 (executable)
@@ -1,28 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : SMESHGUI_MultiEditDlg.cxx
 // Author : Sergey LITONIN, Open CASCADE S.A.S.
 // SMESH includes
-//
+
 #include "SMESHGUI_MultiEditDlg.h"
 
 #include "SMESHGUI.h"
 #include <SMDS_Mesh.hxx>
 
 // SALOME GUI includes
-#include <SUIT_ResourceMgr.h>
 #include <SUIT_Desktop.h>
-#include <SUIT_Session.h>
 #include <SUIT_MessageBox.h>
+#include <SUIT_OverrideCursor.h>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_Session.h>
 
 #include <LightApp_SelectionMgr.h>
 #include <LightApp_Application.h>
 #include <SALOME_ListIO.hxx>
 #include <SALOME_ListIteratorOfListIO.hxx>
+#include <SalomeApp_Tools.h>
 
 #include <SVTK_Selector.h>
 #include <SVTK_ViewWindow.h>
 //=======================================================================
 SMESHGUI_MultiEditDlg
 ::SMESHGUI_MultiEditDlg(SMESHGUI* theModule,
-                       const int theMode,
-                       const bool the3d2d):
+                        const int theMode,
+                        const bool the3d2d):
   QDialog(SMESH::GetDesktop(theModule)),
   mySelector(SMESH::GetViewWindow(theModule)->GetSelector()),
   mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
@@ -192,7 +195,7 @@ QWidget* SMESHGUI_MultiEditDlg::createMainFrame (QWidget* theParent, const bool
 
   myToAllChk = new QCheckBox(tr("TO_ALL"), mySelGrp);
   mySelGrpLayout->addWidget(myToAllChk, mySelGrpLayout->rowCount(), 0, 
-                           1, mySelGrpLayout->columnCount());
+                            1, mySelGrpLayout->columnCount());
 
   // Split/Join criterion group
   myCriterionGrp = new QGroupBox(tr("SPLIT_JOIN_CRITERION"), aMainGrp);
@@ -301,7 +304,7 @@ QWidget* SMESHGUI_MultiEditDlg::createButtonFrame (QWidget* theParent)
 bool SMESHGUI_MultiEditDlg::isValid (const bool /*theMess*/)
 {
   return (!myMesh->_is_nil() &&
-          (myListBox->count() > 0 || (myToAllChk->isChecked() && myActor)));
+          (myListBox->count() > 0 || (myToAllChk->isChecked()/* && myActor*/)));
 }
 
 //=======================================================================
@@ -423,63 +426,65 @@ void SMESHGUI_MultiEditDlg::onOk()
 
 //=======================================================================
 // name    : SMESHGUI_MultiEditDlg::getIds
-// Purpose : Retrive identifiers from list box
+// Purpose : Retrive identifiers from list box or the whole object
 //=======================================================================
-SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds()
+
+SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds(SMESH::SMESH_IDSource_var& obj)
 {
   SMESH::long_array_var anIds = new SMESH::long_array;
 
   if (myToAllChk->isChecked())
   {
     myIds.Clear();
-    SMESH_Actor * anActor = SMESH::FindActorByObject(myMesh);
-    if (!anActor)
-      anActor = myActor;
-    if (anActor != 0)
-    {
-      // skl 07.02.2006
-      SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh();
-      if( myFilterType == SMESH::TriaFilter || 
-         myFilterType == SMESH::QuadFilter ||
-         myFilterType == SMESH::FaceFilter ) {
-       SMDS_FaceIteratorPtr it = aMesh->facesIterator();
-       while(it->more()) {
-         const SMDS_MeshFace* f = it->next();
-         if(myFilterType == SMESH::FaceFilter) {
-           myIds.Add(f->GetID());
-         }
-         else if( myFilterType==SMESH::TriaFilter &&
-                  ( f->NbNodes()==3 || f->NbNodes()==6 ) ) {
-           myIds.Add(f->GetID());
-         }
-         else if( myFilterType==SMESH::QuadFilter &&
-                  ( f->NbNodes()==4 || f->NbNodes()==8 ) ) {
-           myIds.Add(f->GetID());
-         }
-       }
-      }
-      else if(myFilterType == SMESH::VolumeFilter) {
-       SMDS_VolumeIteratorPtr it = aMesh->volumesIterator();
-       while(it->more()) {
-         const SMDS_MeshVolume* f = it->next();
-         myIds.Add(f->GetID());
-       }
-      }
-      /* commented by skl 07.02.2006
+    obj = SMESH::SMESH_IDSource::_narrow( myMesh );
+//     SMESH_Actor * anActor = SMESH::FindActorByObject(myMesh);
+//     if (!anActor)
+//       anActor = myActor;
+//     if (anActor != 0)
+//     {
+//       // skl 07.02.2006
+//       SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh();
+//       if( myFilterType == SMESH::TriaFilter || 
+//           myFilterType == SMESH::QuadFilter ||
+//           myFilterType == SMESH::FaceFilter ) {
+//         SMDS_FaceIteratorPtr it = aMesh->facesIterator();
+//         while(it->more()) {
+//           const SMDS_MeshFace* f = it->next();
+//           if(myFilterType == SMESH::FaceFilter) {
+//             myIds.Add(f->GetID());
+//           }
+//           else if( myFilterType==SMESH::TriaFilter &&
+//                    ( f->NbNodes()==3 || f->NbNodes()==6 ) ) {
+//             myIds.Add(f->GetID());
+//           }
+//           else if( myFilterType==SMESH::QuadFilter &&
+//                    ( f->NbNodes()==4 || f->NbNodes()==8 ) ) {
+//             myIds.Add(f->GetID());
+//           }
+//         }
+//       }
+//       else if(myFilterType == SMESH::VolumeFilter) {
+//         SMDS_VolumeIteratorPtr it = aMesh->volumesIterator();
+//         while(it->more()) {
+//           const SMDS_MeshVolume* f = it->next();
+//           myIds.Add(f->GetID());
+//         }
+//       }
+      /* commented by skl 07.02.2006 - to work with quadratic elements
       TVisualObjPtr aVisualObj = anActor->GetObject();
       vtkUnstructuredGrid* aGrid = aVisualObj->GetUnstructuredGrid();
       if (aGrid != 0) {
         for (int i = 0, n = aGrid->GetNumberOfCells(); i < n; i++) {
           vtkCell* aCell = aGrid->GetCell(i);
           if (aCell != 0) {
-           vtkTriangle* aTri = vtkTriangle::SafeDownCast(aCell);
-           vtkQuad*     aQua = vtkQuad::SafeDownCast(aCell);
-           vtkPolygon*  aPG  = vtkPolygon::SafeDownCast(aCell);
+            vtkTriangle* aTri = vtkTriangle::SafeDownCast(aCell);
+            vtkQuad*     aQua = vtkQuad::SafeDownCast(aCell);
+            vtkPolygon*  aPG  = vtkPolygon::SafeDownCast(aCell);
 
-           vtkCell3D*   a3d  = vtkCell3D::SafeDownCast(aCell);
-           vtkConvexPointSet* aPH = vtkConvexPointSet::SafeDownCast(aCell);
+            vtkCell3D*   a3d  = vtkCell3D::SafeDownCast(aCell);
+            vtkConvexPointSet* aPH = vtkConvexPointSet::SafeDownCast(aCell);
 
-           if (aTri && myFilterType == SMESHGUI_TriaFilter ||
+            if (aTri && myFilterType == SMESHGUI_TriaFilter ||
                 aQua && myFilterType == SMESHGUI_QuadFilter ||
                 (aTri || aQua || aPG) && myFilterType == SMESHGUI_FaceFilter ||
                 (a3d || aPH) && myFilterType == SMESHGUI_VolumeFilter) {
@@ -490,7 +495,7 @@ SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds()
         }
       }
       */
-    }
+    //}
   }
 
   anIds->length(myIds.Extent());
@@ -540,10 +545,10 @@ void SMESHGUI_MultiEditDlg::onHelp()
     platform = "application";
 #endif
     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser", 
-                                                                platform)).
-                            arg(myHelpFileName));
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser", 
+                                                                 platform)).
+                             arg(myHelpFileName));
   }
 }
 
@@ -594,10 +599,10 @@ void SMESHGUI_MultiEditDlg::onSelectionDone()
     if (aNbItems > 0) {
       QStringList anElements = aListStr.split(" ", QString::SkipEmptyParts);
       for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) {
-       QList<QListWidgetItem*> items = myListBox->findItems(*it, Qt::MatchExactly);
-       QListWidgetItem* anItem;
-       foreach(anItem, items)
-         anItem->setSelected(true);
+        QList<QListWidgetItem*> items = myListBox->findItems(*it, Qt::MatchExactly);
+        QListWidgetItem* anItem;
+        foreach(anItem, items)
+          anItem->setSelected(true);
       }
     }
     myMesh = SMESH::GetMeshByIO(anIO);
@@ -753,9 +758,8 @@ void SMESHGUI_MultiEditDlg::onAddBtn()
     for ( ; anIter.More(); anIter.Next()) {
       SMESH::SMESH_GroupBase_var aGroup =
         SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(anIter.Value());
-      if (!aGroup->_is_nil() && (aGroup->GetType() == SMESH::FACE &&
-                                 entityType() == 0 || aGroup->GetType() == SMESH::VOLUME &&
-                                 entityType() == 1)) {
+      if (!aGroup->_is_nil() && ((aGroup->GetType() == SMESH::FACE && entityType() == 0) || 
+                                 (aGroup->GetType() == SMESH::VOLUME && entityType() == 1))) {
         if (aGroup->GetMesh()->GetId() == myMesh->GetId()) {
           SMESH::long_array_var anIds = aGroup->GetListOfID();
           for (int i = 0, n = anIds->length(); i < n; i++) {
@@ -772,12 +776,13 @@ void SMESHGUI_MultiEditDlg::onAddBtn()
   bool isGroupOrSubmesh = (mySubmeshChk->isChecked() || myGroupChk->isChecked());
   mySubmeshChk->setChecked(false);
   myGroupChk->setChecked(false);
+  QStringList items;
   for(int i = 1; i <= toBeAdded.Extent(); i++)
     if (myIds.Add(toBeAdded(i))) {
-      QListWidgetItem* item = new QListWidgetItem(QString("%1").arg(toBeAdded(i)));
-      myListBox->addItem(item);
-      item->setSelected(true);
+      items.append(QString("%1").arg(toBeAdded(i)));
     }
+  myListBox->addItems(items);
+  myListBox->selectAll();
   myBusy = false;
 
   emit ListContensChanged();
@@ -1034,9 +1039,12 @@ bool SMESHGUI_MultiEditDlg::onApply()
 
   myBusy = true;
 
-  SMESH::long_array_var anIds = getIds();
+  SUIT_OverrideCursor aWaitCursor;
+
+  SMESH::SMESH_IDSource_var obj;
+  SMESH::long_array_var anIds = getIds(obj);
 
-  bool aResult = process(aMeshEditor, anIds.inout());
+  bool aResult = process(aMeshEditor, anIds.inout(), obj);
   if (aResult) {
     if (myActor) {
       SALOME_ListIO sel;
@@ -1044,6 +1052,7 @@ bool SMESHGUI_MultiEditDlg::onApply()
       mySelector->ClearIndex();
       mySelectionMgr->setSelectedObjects( sel );
       SMESH::UpdateView();
+      SMESHGUI::Modified();
     }
 
     myListBox->clear();
@@ -1124,9 +1133,13 @@ SMESHGUI_ChangeOrientationDlg::~SMESHGUI_ChangeOrientationDlg()
 }
 
 bool SMESHGUI_ChangeOrientationDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
-                                             const SMESH::long_array&    theIds)
+                                             const SMESH::long_array&    theIds,
+                                             SMESH::SMESH_IDSource_ptr   obj)
 {
-  return theEditor->Reorient(theIds);
+  if ( CORBA::is_nil( obj ))
+    return theEditor->Reorient(theIds);
+  else
+    return theEditor->ReorientObject( obj );
 }
 
 /*!
@@ -1152,7 +1165,7 @@ SMESHGUI_UnionOfTrianglesDlg
 
   QLabel* aLab = new QLabel (tr("MAXIMUM_ANGLE"), aMaxAngleGrp);
   myMaxAngleSpin = new SMESHGUI_SpinBox (aMaxAngleGrp);
-  myMaxAngleSpin->RangeStepAndValidator(0, 180.0, 1.0, 3);
+  myMaxAngleSpin->RangeStepAndValidator(0, 180.0, 1.0, "angle_precision");
   myMaxAngleSpin->SetValue(30.0);
 
   aMaxAngleGrpLayout->addWidget(aLab);
@@ -1180,7 +1193,7 @@ bool SMESHGUI_UnionOfTrianglesDlg::isValid (const bool theMess)
     if( theMess ) {
       QString str( tr( "SMESH_INCORRECT_INPUT" ) );
       if ( !msg.isEmpty() )
-       str += "\n" + msg;
+        str += "\n" + msg;
       SUIT_MessageBox::critical( this, tr( "SMESH_ERROR" ), str );
     }
     return false;
@@ -1190,16 +1203,21 @@ bool SMESHGUI_UnionOfTrianglesDlg::isValid (const bool theMess)
 }
 
 bool SMESHGUI_UnionOfTrianglesDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
-                                            const SMESH::long_array&    theIds)
+                                            const SMESH::long_array&    theIds,
+                                            SMESH::SMESH_IDSource_ptr   obj)
 {
-  SMESH::NumericalFunctor_var aCriterion = getNumericalFunctor();
-  double aMaxAngle = myMaxAngleSpin->GetValue() * PI / 180.0;
-  bool ok = theEditor->TriToQuad(theIds, aCriterion, aMaxAngle);
-  if( ok ) {
+  {
     QStringList aParameters;
     aParameters << myMaxAngleSpin->text();
-    myMesh->SetParameters( SMESHGUI::JoinObjectParameters(aParameters) );
+    myMesh->SetParameters( aParameters.join(":").toLatin1().constData() );
   }
+  SMESH::NumericalFunctor_var aCriterion = getNumericalFunctor();
+  double aMaxAngle = myMaxAngleSpin->GetValue() * M_PI / 180.0;
+  bool ok;
+  if ( CORBA::is_nil( obj ))
+    ok = theEditor->TriToQuad(theIds, aCriterion, aMaxAngle);
+  else
+    ok = theEditor->TriToQuadObject(obj, aCriterion, aMaxAngle);
   return ok;
 }
 
@@ -1243,19 +1261,21 @@ void SMESHGUI_CuttingOfQuadsDlg::onClose()
 }
 
 bool SMESHGUI_CuttingOfQuadsDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
-                                          const SMESH::long_array&    theIds)
+                                          const SMESH::long_array&    theIds,
+                                          SMESH::SMESH_IDSource_ptr   obj)
 {
+  bool hasObj = (! CORBA::is_nil( obj ));
   switch (myGroupChoice->checkedId()) {
   case 0: // use diagonal 1-3
-    return theEditor->SplitQuad(theIds, true);
+    return hasObj ? theEditor->SplitQuadObject(obj, true) : theEditor->SplitQuad(theIds, true);
   case 1: // use diagonal 2-4
-    return theEditor->SplitQuad(theIds, false);
+    return hasObj ? theEditor->SplitQuadObject(obj, false) : theEditor->SplitQuad(theIds, false);
   default: // use numeric functor
     break;
   }
 
-  SMESH::NumericalFunctor_var aCriterion = getNumericalFunctor();
-  return theEditor->QuadToTri(theIds, aCriterion);
+  SMESH::NumericalFunctor_var aCrit = getNumericalFunctor();
+  return hasObj ? theEditor->QuadToTriObject(obj, aCrit) : theEditor->QuadToTri(theIds, aCrit);
 }
 
 void SMESHGUI_CuttingOfQuadsDlg::onCriterionRB()
@@ -1295,8 +1315,9 @@ void SMESHGUI_CuttingOfQuadsDlg::displayPreview()
     erasePreview();
 
   // get Ids of elements
-  SMESH::long_array_var anElemIds = getIds();
-  if (getIds()->length() == 0)
+  SMESH::SMESH_IDSource_var obj;
+  SMESH::long_array_var anElemIds = getIds(obj);
+  if (anElemIds->length() == 0 && obj->_is_nil() )
     return;
 
   SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh();
@@ -1449,3 +1470,55 @@ void SMESHGUI_CuttingOfQuadsDlg::displayPreview()
   aCellTypesArray->Delete();
   aCellLocationsArray->Delete();
 }
+
+/*!
+ *  Class       : SMESHGUI_CuttingIntoTetraDlg
+ *  Description : Modification of orientation of faces
+ */
+
+SMESHGUI_CuttingIntoTetraDlg::SMESHGUI_CuttingIntoTetraDlg(SMESHGUI* theModule)
+  : SMESHGUI_MultiEditDlg(theModule, SMESH::VolumeFilter, false)
+{
+  setWindowTitle(tr("CAPTION"));
+  myHelpFileName = "split_to_tetra_page.html";
+  myEntityType = 1;
+
+  myToAllChk->setChecked( true ); //aplly to the whole mesh by default
+
+  bool hasHexa = true;//myMesh->_is_nil() ? false : myMesh->NbHexas();
+
+  if ( hasHexa )
+  {
+    myGroupChoice->button(0)->setText( tr("SPLIT_HEX_TO_5_TETRA"));
+    myGroupChoice->button(1)->setText( tr("SPLIT_HEX_TO_6_TETRA"));
+    myGroupChoice->button(2)->setText( tr("SPLIT_HEX_TO_24_TETRA"));
+
+    myCriterionGrp->setTitle( tr("SPLIT_METHOD"));
+    myCriterionGrp->show();
+    myComboBoxFunctor->hide();
+    myChoiceWidget->show();
+  }
+  setSelectionMode();
+  updateButtons();
+}
+
+SMESHGUI_CuttingIntoTetraDlg::~SMESHGUI_CuttingIntoTetraDlg()
+{
+}
+
+bool SMESHGUI_CuttingIntoTetraDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
+                                            const SMESH::long_array&    theIds,
+                                            SMESH::SMESH_IDSource_ptr   theObj)
+{
+  SMESH::SMESH_IDSource_var obj = theObj;
+  if ( CORBA::is_nil( obj ))
+    obj = theEditor->MakeIDSource( theIds, myEntityType ? SMESH::VOLUME : SMESH::FACE );
+  try {
+    theEditor->SplitVolumesIntoTetra( obj, myGroupChoice->checkedId()+1 );
+  }
+  catch ( const SALOME::SALOME_Exception& S_ex ) {
+    SalomeApp_Tools::QtCatchCorbaException( S_ex );
+    return false;
+  }
+  return true;
+}
index 0ada531f925b40dda1e7819a44e93affa3af542c..de9b0b67fed258a5ffe313a603a25fe72ee53f78 100755 (executable)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : SMESHGUI_MultiEditDlg.h
 // Author : Sergey LITONIN, Open CASCADE S.A.S.
 //
@@ -108,12 +109,13 @@ protected:
   QWidget*                  createButtonFrame( QWidget* );
   QWidget*                  createMainFrame( QWidget*, const bool );
   virtual bool              isValid( const bool );
-  SMESH::long_array_var     getIds();
+  SMESH::long_array_var     getIds(SMESH::SMESH_IDSource_var& obj);
   void                      updateButtons();
   void                      setSelectionMode();
   virtual bool              isIdValid( const int ) const;
   virtual bool              process( SMESH::SMESH_MeshEditor_ptr, 
-                                    const SMESH::long_array& ) = 0;
+                                     const SMESH::long_array& ,
+                                     SMESH::SMESH_IDSource_ptr obj) = 0;
   int                       entityType();
 
 protected:
@@ -174,7 +176,9 @@ public:
   virtual ~SMESHGUI_ChangeOrientationDlg();
 
 protected:
-  virtual bool process( SMESH::SMESH_MeshEditor_ptr, const SMESH::long_array& );
+  virtual bool process( SMESH::SMESH_MeshEditor_ptr,
+                        const SMESH::long_array& ,
+                        SMESH::SMESH_IDSource_ptr obj);
 };
 
 /*!
@@ -191,7 +195,9 @@ public:
 
 protected:
   virtual bool      isValid( const bool );
-  virtual bool      process( SMESH::SMESH_MeshEditor_ptr, const SMESH::long_array& );
+  virtual bool      process( SMESH::SMESH_MeshEditor_ptr,
+                             const SMESH::long_array&,
+                             SMESH::SMESH_IDSource_ptr obj );
 
 private:
   SMESHGUI_SpinBox* myMaxAngleSpin;
@@ -210,7 +216,9 @@ public:
   virtual ~SMESHGUI_CuttingOfQuadsDlg();
 
 protected:
-  virtual bool  process( SMESH::SMESH_MeshEditor_ptr, const SMESH::long_array& );
+  virtual bool  process( SMESH::SMESH_MeshEditor_ptr,
+                         const SMESH::long_array& ,
+                         SMESH::SMESH_IDSource_ptr obj);
 
 protected slots:
   virtual void  onClose();
@@ -226,4 +234,22 @@ private:
   QCheckBox*    myPreviewChk;
 };
 
+/*!
+ * Class       : SMESHGUI_CuttingIntoTetraDlg
+ * Description : Split all volumes into tetrahedrons
+ */
+class  SMESHGUI_CuttingIntoTetraDlg : public SMESHGUI_MultiEditDlg
+{
+  Q_OBJECT
+
+public:
+  SMESHGUI_CuttingIntoTetraDlg( SMESHGUI* );
+  virtual ~SMESHGUI_CuttingIntoTetraDlg();
+
+protected:
+  virtual bool process( SMESH::SMESH_MeshEditor_ptr,
+                        const SMESH::long_array&,
+                        SMESH::SMESH_IDSource_ptr obj );
+};
+
 #endif // SMESHGUI_MULTIEDITDLG_H
index 38869ceddb5f899eff69e34afbf1794f092d6fd9..3f369e79009ffb1b976f3f77e71ff8c940b4d113 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_NodesDlg.cxx
 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
@@ -31,6 +32,7 @@
 #include "SMESHGUI_Utils.h"
 #include "SMESHGUI_VTKUtils.h"
 #include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI_GroupUtils.h"
 
 #include <SMESH_Actor.h>
 #include <SMESH_ActorUtils.h>
 #include <LightApp_Application.h>
 #include <LightApp_SelectionMgr.h>
 
+#include <SalomeApp_Application.h>
+
 #include <SVTK_ViewWindow.h>
+#include <VTKViewer_Algorithm.h>
 #include <VTKViewer_CellLocationsArray.h>
 
 // SALOME KERNEL includes
@@ -69,6 +74,7 @@
 #include <vtkPoints.h>
 
 // Qt includes
+#include <QComboBox>
 #include <QGroupBox>
 #include <QLabel>
 #include <QPushButton>
 
 namespace SMESH
 {
-  void AddNode( SMESH::SMESH_Mesh_ptr theMesh, float x, float y, float z, const QStringList& theParameters )
+  long AddNode( SMESH::SMESH_Mesh_ptr theMesh, float x, float y, float z, const QStringList& theParameters )
   {
+    long aNodeId = -1;
     SUIT_OverrideCursor wc;
     try {
       _PTR(SObject) aSobj = SMESH::FindSObject( theMesh );
       SMESH::SMESH_MeshEditor_var aMeshEditor = theMesh->GetMeshEditor();
-      aMeshEditor->AddNode( x, y, z );
-      theMesh->SetParameters( SMESHGUI::JoinObjectParameters(theParameters) );
+      theMesh->SetParameters( theParameters.join(":").toLatin1().constData() );
+      aNodeId = aMeshEditor->AddNode( x, y, z );
       _PTR(Study) aStudy = GetActiveStudyDocument();
       CORBA::Long anId = aStudy->StudyId();
       if (TVisualObjPtr aVisualObj = SMESH::GetVisualObj( anId, aSobj->GetID().c_str() ) ) {
-       aVisualObj->Update( true );
+        aVisualObj->Update( true );
       }
     } 
     catch ( SALOME::SALOME_Exception& exc ) {
@@ -110,6 +117,7 @@ namespace SMESH
     catch ( ... ) {
       INFOS( "Unknown exception was cought !!!" );
     }
+    return aNodeId;
   }
 
   class TNodeSimulation 
@@ -234,7 +242,7 @@ SMESHGUI_NodesDlg::SMESHGUI_NodesDlg( SMESHGUI* theModule ):
   mySimulation = new SMESH::TNodeSimulation( SMESH::GetViewWindow( mySMESHGUI ) );
   
   QPixmap image0( SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap( "SMESH", 
-                                                                  tr( "ICON_DLG_NODE" ) ) );
+                                                                   tr( "ICON_DLG_NODE" ) ) );
   
   QVBoxLayout* SMESHGUI_NodesDlgLayout = new QVBoxLayout( this );
   SMESHGUI_NodesDlgLayout->setSpacing( SPACING );
@@ -270,11 +278,29 @@ SMESHGUI_NodesDlg::SMESHGUI_NodesDlg( SMESHGUI* theModule ):
   SpinBox_Z = new SMESHGUI_SpinBox( GroupCoordinates );
 
   GroupCoordinatesLayout->addWidget( TextLabel_X );
-  GroupCoordinatesLayout->addWidget( SpinBox_X );
+  GroupCoordinatesLayout->addWidget( SpinBox_X ); 
   GroupCoordinatesLayout->addWidget( TextLabel_Y);
   GroupCoordinatesLayout->addWidget( SpinBox_Y );
   GroupCoordinatesLayout->addWidget( TextLabel_Z );
   GroupCoordinatesLayout->addWidget( SpinBox_Z );
+  GroupCoordinatesLayout->setStretch(1, 1);
+  GroupCoordinatesLayout->setStretch(3, 1);
+  GroupCoordinatesLayout->setStretch(5, 1);
+
+  /***************************************************************/
+  GroupGroups = new QGroupBox( tr( "SMESH_ADD_TO_GROUP" ), this );
+  GroupGroups->setCheckable( true );
+  QHBoxLayout* GroupGroupsLayout = new QHBoxLayout(GroupGroups);
+  GroupGroupsLayout->setSpacing(SPACING);
+  GroupGroupsLayout->setMargin(MARGIN);
+
+  TextLabel_GroupName = new QLabel( tr( "SMESH_GROUP" ), GroupGroups );
+  ComboBox_GroupName = new QComboBox( GroupGroups );
+  ComboBox_GroupName->setEditable( true );
+  ComboBox_GroupName->setInsertPolicy( QComboBox::NoInsert );
+
+  GroupGroupsLayout->addWidget( TextLabel_GroupName );
+  GroupGroupsLayout->addWidget( ComboBox_GroupName, 1 );
 
   /***************************************************************/
   GroupButtons = new QGroupBox( this );
@@ -302,6 +328,7 @@ SMESHGUI_NodesDlg::SMESHGUI_NodesDlg( SMESHGUI* theModule ):
   /***************************************************************/
   SMESHGUI_NodesDlgLayout->addWidget( GroupConstructors );
   SMESHGUI_NodesDlgLayout->addWidget( GroupCoordinates );
+  SMESHGUI_NodesDlgLayout->addWidget( GroupGroups );
   SMESHGUI_NodesDlgLayout->addWidget( GroupButtons );
 
   myHelpFileName = "adding_nodes_and_elements_page.html#adding_nodes_anchor";
@@ -329,13 +356,16 @@ void SMESHGUI_NodesDlg::Init()
   double step = 25.0;
 
   /* min, max, step and decimals for spin boxes */
-  SpinBox_X->RangeStepAndValidator( COORD_MIN, COORD_MAX, step, DBL_DIGITS_DISPLAY );
-  SpinBox_Y->RangeStepAndValidator( COORD_MIN, COORD_MAX, step, DBL_DIGITS_DISPLAY );
-  SpinBox_Z->RangeStepAndValidator( COORD_MIN, COORD_MAX, step, DBL_DIGITS_DISPLAY );
+  SpinBox_X->RangeStepAndValidator( COORD_MIN, COORD_MAX, step, "length_precision" );
+  SpinBox_Y->RangeStepAndValidator( COORD_MIN, COORD_MAX, step, "length_precision" );
+  SpinBox_Z->RangeStepAndValidator( COORD_MIN, COORD_MAX, step, "length_precision" );
   SpinBox_X->SetValue( 0.0 );
   SpinBox_Y->SetValue( 0.0 );
   SpinBox_Z->SetValue( 0.0 );
 
+  /* reset "Add to group" control */
+  GroupGroups->setChecked( false );
+
   mySMESHGUI->SetActiveDialogBox( this );
 
   /* signals and slots connections */
@@ -352,6 +382,7 @@ void SMESHGUI_NodesDlg::Init()
   connect( mySMESHGUI,     SIGNAL( SignalDeactivateActiveDialog() ), SLOT( DeactivateActiveDialog() ) );
   /* to close dialog if study frame change */
   connect( mySMESHGUI,     SIGNAL( SignalStudyFrameChanged() ),      SLOT( ClickOnCancel() ) );
+  connect(mySMESHGUI,      SIGNAL(SignalCloseAllDialogs()),          SLOT(ClickOnCancel()));
 
   // set selection mode
   SMESH::SetPointRepresentation( true );
@@ -397,7 +428,7 @@ bool SMESHGUI_NodesDlg::ClickOnApply()
 
   if ( myMesh->_is_nil() ) {
     SUIT_MessageBox::warning( this, tr( "SMESH_WRN_WARNING" ),
-                             tr( "MESH_IS_NOT_SELECTED" ) );
+                              tr( "MESH_IS_NOT_SELECTED" ) );
     return false;
   }
 
@@ -414,16 +445,74 @@ bool SMESHGUI_NodesDlg::ClickOnApply()
   aParameters << SpinBox_Y->text();
   aParameters << SpinBox_Z->text();
 
+  bool addToGroup = GroupGroups->isChecked();
+  QString aGroupName;
+
+  SMESH::SMESH_GroupBase_var aGroup;
+  int idx = 0;
+  if( addToGroup ) {
+    aGroupName = ComboBox_GroupName->currentText();
+    for ( int i = 1; i < ComboBox_GroupName->count(); i++ ) {
+      QString aName = ComboBox_GroupName->itemText( i );
+      if ( aGroupName == aName && ( i == ComboBox_GroupName->currentIndex() || idx == 0 ) )
+        idx = i;
+    }
+    if ( idx > 0 && idx < myGroups.count() ) {
+      SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( myGroups[idx-1] );
+      if ( !aGeomGroup->_is_nil() ) {
+        int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ),
+                                             tr( "MESH_STANDALONE_GRP_CHOSEN" ).arg( aGroupName ),
+                                             tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 );
+        if ( res == 1 ) return false;
+      }
+      aGroup = myGroups[idx-1];
+    }
+  }
+      
   mySimulation->SetVisibility( false );
-  SMESH::AddNode( myMesh, x, y, z, aParameters );
+
+  long aNodeId = SMESH::AddNode( myMesh, x, y, z, aParameters );
+
   SMESH::SetPointRepresentation( true );
 
+  if ( aNodeId != -1 && addToGroup && !aGroupName.isEmpty() ) {
+    SMESH::SMESH_Group_var aGroupUsed;
+    if ( aGroup->_is_nil() ){
+      // create new group 
+      aGroupUsed = SMESH::AddGroup( myMesh, SMESH::NODE, aGroupName );
+      if ( !aGroupUsed->_is_nil() ) {
+        myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroupUsed));
+        ComboBox_GroupName->addItem( aGroupName );
+      }
+    }
+    else {
+      SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup );
+      if ( !aGeomGroup->_is_nil() ) {
+        aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup );
+        if ( !aGroupUsed->_is_nil() && idx > 0 ) {
+          myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed);
+          SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser();
+        }
+      }
+      else
+        aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup );
+    }
+
+    if ( !aGroupUsed->_is_nil() ) {
+      SMESH::long_array_var anIdList = new SMESH::long_array;
+      anIdList->length( 1 );
+      anIdList[0] = aNodeId;
+      aGroupUsed->Add( anIdList.inout() );
+    }
+  }
+
   // select myMesh
   SALOME_ListIO aList;
   mySelectionMgr->selectedObjects( aList );
   if ( aList.Extent() != 1 ) {
     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView() ) {
-      vtkActorCollection *aCollection = aViewWindow->getRenderer()->GetActors();
+      VTK::ActorCollectionCopy aCopy(aViewWindow->getRenderer()->GetActors());
+      vtkActorCollection *aCollection = aCopy.GetActors();
       aCollection->InitTraversal();
       while ( vtkActor *anAct = aCollection->GetNextActor() ) {
         if ( SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>( anAct ) ) {
@@ -441,6 +530,11 @@ bool SMESHGUI_NodesDlg::ClickOnApply()
       }
     }
   }
+
+  SMESHGUI::Modified();
+  SMESH::UpdateView();
+  mySimulation->SetVisibility(false);
+
   return true;
 }
 
@@ -470,7 +564,7 @@ void SMESHGUI_NodesDlg::ClickOnHelp()
   LightApp_Application* app = (LightApp_Application*)( SUIT_Session::session()->activeApplication() );
   if ( app ) 
     app->onHelpContextModule( mySMESHGUI ? app->moduleName( mySMESHGUI->moduleName() ) : 
-                             QString( "" ), myHelpFileName );
+                              QString( "" ), myHelpFileName );
   else {
     QString platform;
 #ifdef WIN32
@@ -479,10 +573,10 @@ void SMESHGUI_NodesDlg::ClickOnHelp()
     platform = "application";
 #endif
     SUIT_MessageBox::warning( this, tr("WRN_WARNING"),
-                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                             arg( app->resourceMgr()->stringValue( "ExternalBrowser", 
-                                                                   platform ) ).
-                             arg( myHelpFileName ) );
+                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                              arg( app->resourceMgr()->stringValue( "ExternalBrowser", 
+                                                                    platform ) ).
+                              arg( myHelpFileName ) );
   }
 }
 
@@ -498,27 +592,48 @@ void SMESHGUI_NodesDlg::SelectionIntoArgument()
   mySimulation->SetVisibility( false );
   SMESH::SetPointRepresentation( true );
 
+  QString aCurrentEntry = myEntry;
+
   const SALOME_ListIO& aList = mySelector->StoredIObjects();
   if ( aList.Extent() == 1 ) {
     Handle(SALOME_InteractiveObject) anIO = aList.First();
     if ( anIO->hasEntry() ) {
+      myEntry = anIO->getEntry();
       myMesh = SMESH::GetMeshByIO( anIO );
       if ( myMesh->_is_nil() ) return;
       QString aText;
       if ( SMESH::GetNameOfSelectedNodes( mySelector, anIO, aText ) == 1 ) {
-       if ( SMESH_Actor* anActor = SMESH::FindActorByObject( myMesh.in() ) ) {
-         if ( SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh() ) {
-           if ( const SMDS_MeshNode* aNode = aMesh->FindNode( aText.toInt() ) ) {
-             SpinBox_X->SetValue( aNode->X() );
-             SpinBox_Y->SetValue( aNode->Y() );
-             SpinBox_Z->SetValue( aNode->Z() );
+        if ( SMESH_Actor* anActor = SMESH::FindActorByObject( myMesh.in() ) ) {
+          if ( SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh() ) {
+            if ( const SMDS_MeshNode* aNode = aMesh->FindNode( aText.toInt() ) ) {
+              SpinBox_X->SetValue( aNode->X() );
+              SpinBox_Y->SetValue( aNode->Y() );
+              SpinBox_Z->SetValue( aNode->Z() );
             }
-         }
-       }
+          }
+        }
       }
       mySimulation->SetPosition( SpinBox_X->GetValue(),
-                                SpinBox_Y->GetValue(),
-                                SpinBox_Z->GetValue() );
+                                 SpinBox_Y->GetValue(),
+                                 SpinBox_Z->GetValue() );
+    }
+  }
+
+  // process groups
+  if ( !myMesh->_is_nil() && myEntry != aCurrentEntry ) {
+    myGroups.clear();
+    ComboBox_GroupName->clear();
+    ComboBox_GroupName->addItem( QString() );
+    SMESH::ListOfGroups aListOfGroups = *myMesh->GetGroups();
+    for( int i = 0, n = aListOfGroups.length(); i < n; i++ ) {
+      SMESH::SMESH_GroupBase_var aGroup = aListOfGroups[i];
+      if ( !aGroup->_is_nil() && aGroup->GetType() == SMESH::NODE ) {
+        QString aGroupName( aGroup->GetName() );
+        if ( !aGroupName.isEmpty() ) {
+          myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup));
+          ComboBox_GroupName->addItem( aGroupName );
+        }
+      }
     }
   }
 }
@@ -621,5 +736,10 @@ bool SMESHGUI_NodesDlg::isValid()
     SUIT_MessageBox::critical( this, tr( "SMESH_ERROR" ), str );
     return false;
   }
+
+  if( GroupGroups->isChecked() && ComboBox_GroupName->currentText().isEmpty() ) {
+    SUIT_MessageBox::warning( this, tr( "SMESH_WRN_WARNING" ), tr( "GROUP_NAME_IS_EMPTY" ) );
+    return false;
+  }
   return true;
 }
index 8fc28eacca9349099a15787cd6a460b3d6d09174..de2058f5aed72ef2712347b640d67587950a18ad 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_NodesDlg.h
 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
@@ -36,6 +37,7 @@
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Mesh)
 
+class QComboBox;
 class QGroupBox;
 class QLabel;
 class QPushButton;
@@ -64,12 +66,16 @@ public:
   ~SMESHGUI_NodesDlg();
 
 private:
+  typedef QList<SMESH::SMESH_GroupBase_var> GrpList;
+  
   LightApp_SelectionMgr*  mySelectionMgr;
   SVTK_Selector*          mySelector;
   SMESHGUI*               mySMESHGUI;
   
   SMESH::SMESH_Mesh_var   myMesh;
   SMESH::TNodeSimulation* mySimulation;
+  QString                 myEntry;
+  GrpList                 myGroups;
 
   void                    Init();
   void                    enterEvent( QEvent* );
@@ -78,7 +84,7 @@ private:
   void                    keyPressEvent( QKeyEvent* );
   
   bool                    isValid();
-  
+
   QGroupBox*              GroupConstructors;
   QRadioButton*           Constructor1;
   QGroupBox*              GroupCoordinates;
@@ -90,6 +96,10 @@ private:
   QLabel*                 TextLabel_Y;
   QLabel*                 TextLabel_Z;
 
+  QGroupBox*              GroupGroups;
+  QLabel*                 TextLabel_GroupName;
+  QComboBox*              ComboBox_GroupName;
+
   QGroupBox*              GroupButtons;
   QPushButton*            buttonApply;
   QPushButton*            buttonOk;
index 40bb88e6559d6448ad5dc5fb0af3821c601670ff..5646c72029d89af634deffa25a3e8bd229bc35fd 100755 (executable)
@@ -1,29 +1,27 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
-//
-// SMESH SMDS : implementaion of Salome mesh data structure
-// File   : SMESHGUI_Operation.cxx
-// Author : Sergey LITONIN, Open CASCADE S.A.S.
-// SMESH includes
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+//  File   : SMESHGUI_Operation.cxx
+//  Author : Sergey LITONIN, Open CASCADE S.A.S.
+
 #include "SMESHGUI_Operation.h"
 
 #include "SMESHGUI.h"
@@ -51,7 +49,8 @@
 // Purpose : Constructor
 //=======================================================================
 SMESHGUI_Operation::SMESHGUI_Operation()
-: LightApp_Operation()
+: LightApp_Operation(),
+  myIsApplyAndClose( false )
 {
   myHelpFileName = "";
 }
@@ -86,19 +85,19 @@ void SMESHGUI_Operation::startOperation()
     disconnect( dlg(), SIGNAL( dlgCancel() ), this, SLOT( onCancel() ) );
     disconnect( dlg(), SIGNAL( dlgClose() ), this, SLOT( onCancel() ) );
     disconnect( dlg(), SIGNAL( dlgHelp() ), this, SLOT( onHelp() ) );
-    
+
     if( dlg()->testButtonFlags( QtxDialog::OK ) )
       connect( dlg(), SIGNAL( dlgOk() ), this, SLOT( onOk() ) );
-      
+
     if( dlg()->testButtonFlags( QtxDialog::Apply ) )
       connect( dlg(), SIGNAL( dlgApply() ), this, SLOT( onApply() ) );
-      
+
     if( dlg()->testButtonFlags( QtxDialog::Cancel ) )
       connect( dlg(), SIGNAL( dlgCancel() ), this, SLOT( onCancel() ) );
 
     if( dlg()->testButtonFlags( QtxDialog::Help ) )
       connect( dlg(), SIGNAL( dlgHelp() ), this, SLOT( onHelp() ) );
-      
+
     //if( dlg()->testButtonFlags( QtxDialog::Close ) )
     //if dialog hasn't close, cancel, no and etc buttons, dlgClose will be emitted when dialog is closed not by OK
     connect( dlg(), SIGNAL( dlgClose() ), this, SLOT( onCancel() ) );
@@ -120,18 +119,18 @@ bool SMESHGUI_Operation::isReadyToStart() const
   else if ( getSMESHGUI() == 0 )
   {
     SUIT_MessageBox::warning( desktop(), tr( "SMESH_WRN_WARNING" ),
-                             tr( "NO_MODULE" ) );
+                              tr( "NO_MODULE" ) );
     return false;
   }
   else if ( isStudyLocked() )
     return false;
-  
+
   return true;
 }
 
 //=======================================================================
 // name    : setDialogActive
-// Purpose : 
+// Purpose :
 //=======================================================================
 void SMESHGUI_Operation::setDialogActive( const bool active )
 {
@@ -159,8 +158,10 @@ _PTR(Study) SMESHGUI_Operation::studyDS() const
 //=======================================================================
 void SMESHGUI_Operation::onOk()
 {
+  setIsApplyAndClose( true );
   if( onApply() )
     commit();
+  setIsApplyAndClose( false );
   //else
   //  abort();
 }
@@ -190,7 +191,7 @@ void SMESHGUI_Operation::onCancel()
 void SMESHGUI_Operation::onHelp()
 {
   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
-  if (app) 
+  if (app)
     app->onHelpContextModule(getSMESHGUI() ? app->moduleName(getSMESHGUI()->moduleName()) : QString(""), myHelpFileName);
   else {
     QString platform;
@@ -200,10 +201,10 @@ void SMESHGUI_Operation::onHelp()
     platform = "application";
 #endif
     SUIT_MessageBox::warning( desktop(), tr("WRN_WARNING"),
-                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                             arg(app->resourceMgr()->stringValue("ExternalBrowser", 
-                                                                 platform)).
-                             arg(myHelpFileName) );
+                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                              arg(app->resourceMgr()->stringValue("ExternalBrowser",
+                                                                  platform)).
+                              arg(myHelpFileName) );
   }
 }
 
@@ -215,6 +216,26 @@ void SMESHGUI_Operation::initDialog()
 {
 }
 
+//================================================================
+// name    : setIsApplyAndClose
+// Purpose : Set value of the flag indicating that the dialog is
+//           accepted by Apply & Close button
+//================================================================
+void SMESHGUI_Operation::setIsApplyAndClose( const bool theFlag )
+{
+  myIsApplyAndClose = theFlag;
+}
+
+//================================================================
+// name    : isApplyAndClose
+// Purpose : Get value of the flag indicating that the dialog is
+//           accepted by Apply & Close button
+//================================================================
+bool SMESHGUI_Operation::isApplyAndClose() const
+{
+  return myIsApplyAndClose;
+}
+
 /*!
  * \brief Verifies whether study of operation is locked
   * \param theMess - specifies whether message box must be shown if study is locked
@@ -231,11 +252,11 @@ bool SMESHGUI_Operation::isStudyLocked( const bool theMess ) const
     {
       if ( theMess )
         SUIT_MessageBox::warning( SMESHGUI::desktop(), tr( "WRN_WARNING" ),
-                                 tr( "WRN_STUDY_LOCKED" ) );
+                                  tr( "WRN_STUDY_LOCKED" ) );
       return true;
     }
   }
-  
+
   return false;
 }
 
@@ -258,9 +279,9 @@ bool SMESHGUI_Operation::isValid( SUIT_Operation* theOtherOp ) const
     // to do add other operations here
   }
 
-  return theOtherOp && theOtherOp->inherits( "SMESHGUI_Operation" ) &&
-         ( !anOps.contains( theOtherOp->metaObject()->className() ) || 
-          anOps.contains( metaObject()->className() ) );
+  return ( theOtherOp &&
+         ( ( theOtherOp->inherits("SMESHGUI_Operation") && ( !anOps.contains(theOtherOp->metaObject()->className() ) || anOps.contains(metaObject()->className()) ) ) ||
+           ( theOtherOp->inherits("LightApp_ShowHideOp") ) ) );
 
   return true;
 }
index b3b119e7168f43438c2165c0f9e0a01921579916..2bbad5c1f372b5c37111de7db212073b9c8dc886 100755 (executable)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMDS : implementaion of Salome mesh data structure
 // File   : SMESHGUI_Operation.h
 // Author : Sergey LITONIN, Open CASCADE S.A.S.
@@ -57,6 +58,9 @@ protected:
   virtual void      startOperation();
   virtual bool      isReadyToStart() const;
   
+  virtual void      setIsApplyAndClose( const bool theFlag );
+  virtual bool      isApplyAndClose() const;
+
   //! Set according dialog active or inactive
   virtual void      setDialogActive( const bool );
 
@@ -68,6 +72,7 @@ protected:
   virtual bool      isValid( SUIT_Operation* ) const;
 
   QString           myHelpFileName;
+  bool              myIsApplyAndClose;
 
 protected slots:
   virtual void      onOk();
index d6ea44b2e62676b1c6815a5995d1b58fb0d787ff..349314182ba00ff12ffe782720eb6aedd4936ea5 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_PatternUtils.cxx
 // Author : Open CASCADE S.A.S.
index cd5fd704024ee1fba4d88d62c666d760567c9d90..a455061c65a00b153457efc2c3690966f1b58f53 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_PatternUtils.h
 // Author : Open CASCADE S.A.S.
index c8ab77ac83b23ae758217b56393f62f451a7e57d..f3483ba2530112fd245fc1810af89cae56f737ab 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_PatternWidget.cxx
 // Author : Michael ZORIN, Open CASCADE S.A.S.
@@ -95,9 +96,9 @@ void SMESHGUI_PatternWidget::paintEvent( QPaintEvent* )
     QPoint aQPnt = mapCoords( aPoint.x, aPoint.y );
 
     painter.drawPie( aQPnt.x() - Radius, aQPnt.y() - Radius, 
-                    Radius * 2, Radius * 2, 0, 360 * 16 );
+                     Radius * 2, Radius * 2, 0, 360 * 16 );
     painter.drawText( aQPnt.x() + Shift, aQPnt.y() - Shift, 
-                     QString::number( i+1 ) );
+                      QString::number( i+1 ) );
   }
 
   // Draw lines
index e4a6e41d3bc48951a3129730ac1cc8b22af1a144..82ffdeea98b2da9ddc1e022fddac73ceb9b44a0e 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_PatternWidget.h
 // Author : Michael ZORIN, Open CASCADE S.A.S.
@@ -53,8 +54,8 @@ public:
   ~SMESHGUI_PatternWidget();
   
   void               SetPoints( const PointVector&,
-                               const QVector<int>&,
-                               const ConnectivityVector& );
+                                const QVector<int>&,
+                                const ConnectivityVector& );
 
 private:
   PointVector        myPoints;
index 3b16aaf0b02668ada6a464e6fc9382a1eae3785c..c7b6d5e7d3059b4d9a80b1023f972de7b3f9cb07 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_Preferences_ColorDlg.cxx
 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
 #include "SMESHGUI_Preferences_ColorDlg.h"
 
 #include "SMESHGUI.h"
+#include "SMESHGUI_SpinBox.h"
 #include "SMESHGUI_Utils.h"
 
 // SALOME GUI includes
 #include <SUIT_Desktop.h>
+#include <SUIT_MessageBox.h>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_Session.h>
 #include <QtxColorButton.h>
-#include <QtxIntSpinBox.h>
+#include <VTKViewer_MarkerWidget.h>
+#include <LightApp_Application.h>
+#include <SalomeApp_IntSpinBox.h>
 
 // Qt includes
 #include <QGroupBox>
@@ -41,7 +48,8 @@
 #include <QVBoxLayout>
 #include <QHBoxLayout>
 #include <QGridLayout>
-#include <QSpinBox>
+#include <QCheckBox>
+#include <QKeyEvent>
 
 #define SPACING 6
 #define MARGIN  11
@@ -58,7 +66,7 @@ SMESHGUI_Preferences_ColorDlg::SMESHGUI_Preferences_ColorDlg( SMESHGUI* theModul
     mySMESHGUI( theModule )
 {
   setModal( true );
-  setWindowTitle( tr( "Preferences - Set Color" ) );
+  setWindowTitle( tr( "DIALOG_TITLE" ) );
   setSizeGripEnabled( true );
 
   // -------------------------------
@@ -67,65 +75,148 @@ SMESHGUI_Preferences_ColorDlg::SMESHGUI_Preferences_ColorDlg( SMESHGUI* theModul
   topLayout->setMargin( MARGIN );
 
   // -------------------------------
-  QGroupBox* ButtonGroup1 = new QGroupBox( tr( "Elements" ), this );
+  QGroupBox* ButtonGroup1 = new QGroupBox( tr( "GRP_ELEMENTS" ), this );
   QGridLayout* ButtonGroup1Layout = new QGridLayout( ButtonGroup1 );
   ButtonGroup1Layout->setSpacing( SPACING );
   ButtonGroup1Layout->setMargin( MARGIN );
 
-  QLabel* TextLabel_Fill = new QLabel( tr( "Fill" ), ButtonGroup1 );
-  btnFillColor = new QtxColorButton( ButtonGroup1 );
+  QLabel* TextLabel_Fill = new QLabel( tr( "SURFACE_COLOR_LBL" ), ButtonGroup1 );
 
-  QLabel* TextLabel_BackFace = new QLabel( tr( "Back Face" ), ButtonGroup1 );
-  btnBackFaceColor = new QtxColorButton( ButtonGroup1 );
+  toolSurfColor = new QtxBiColorTool(ButtonGroup1);
+  toolSurfColor->setText( tr( "BACKSURFACE_COLOR_LBL" ));
 
-  QLabel* TextLabel_Outine = new QLabel( tr( "Outline" ), ButtonGroup1 );
+  QLabel* TextLabel_Outline = new QLabel( tr( "OUTLINE_COLOR_LBL" ), ButtonGroup1 );
   btnOutlineColor = new QtxColorButton( ButtonGroup1 );
 
-  QLabel* TextLabel_Width = new QLabel( tr( "Width" ), ButtonGroup1 );
-  SpinBox_Width = new QSpinBox( ButtonGroup1 );
-  SpinBox_Width->setRange( 0, 5 );
+  QLabel* TextLabel_Wireframe = new QLabel( tr( "WIREFRAME_COLOR_LBL" ), ButtonGroup1 );
+  btnWireframeColor = new QtxColorButton( ButtonGroup1 );
+
+  QLabel* TextLabel_0DElements_Color = new QLabel( tr( "0D_ELEMENTS_COLOR_LBL" ), ButtonGroup1 );
+  btn0DElementsColor = new QtxColorButton( ButtonGroup1 );
+
+  QLabel* TextLabel_0DElements_Size = new QLabel( tr( "0D_ELEMENTS_SIZE_LBL" ), ButtonGroup1 );
+  SpinBox_0DElements_Size = new SalomeApp_IntSpinBox( ButtonGroup1 );
+  SpinBox_0DElements_Size->setAcceptNames( false ); // No Notebook variables allowed
+  SpinBox_0DElements_Size->setRange( 1, 10 );
+  SpinBox_0DElements_Size->setSingleStep( 1 );
+  SpinBox_0DElements_Size->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+  SpinBox_0DElements_Size->setButtonSymbols( QSpinBox::PlusMinus );
+
+  QLabel* TextLabel_BallElem_Color = new QLabel( tr( "0D_ELEMENTS_COLOR_LBL" ), ButtonGroup1 );
+  btnBallElemColor = new QtxColorButton( ButtonGroup1 );
+
+  QLabel* TextLabel_BallElem_Size = new QLabel( tr( "BALLELEM_SIZE_LBL" ), ButtonGroup1 );
+  SpinBox_BallElem_Size = new SalomeApp_IntSpinBox( ButtonGroup1 );
+  SpinBox_BallElem_Size->setAcceptNames( false ); // No Notebook variables allowed
+  SpinBox_BallElem_Size->setRange( 1, 10 );
+  SpinBox_BallElem_Size->setSingleStep( 1 );
+  SpinBox_BallElem_Size->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+  SpinBox_BallElem_Size->setButtonSymbols( QSpinBox::PlusMinus );
+
+  QLabel* TextLabel_Width = new QLabel( tr( "LINE_WIDTH_LBL" ), ButtonGroup1 );
+  SpinBox_Width = new SalomeApp_IntSpinBox( ButtonGroup1 );
+  SpinBox_Width->setAcceptNames( false ); // No Notebook variables allowed
+  SpinBox_Width->setRange( 1, 5 );
   SpinBox_Width->setSingleStep( 1 );
   SpinBox_Width->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
   SpinBox_Width->setButtonSymbols( QSpinBox::PlusMinus );
 
-  QLabel* TextLabel_ShrinkCoeff = new QLabel( tr( "Shrink coef." ), ButtonGroup1 );
-  SpinBox_Shrink = new QtxIntSpinBox( ButtonGroup1 );
+  QLabel* TextLabel_ShrinkCoeff = new QLabel( tr( "SHRINK_COEF_LBL" ), ButtonGroup1 );
+  SpinBox_Shrink = new SalomeApp_IntSpinBox( ButtonGroup1 );
+  SpinBox_Shrink->setAcceptNames( false ); // No Notebook variables allowed
   SpinBox_Shrink->setRange( 20, 100 );
   SpinBox_Shrink->setSingleStep( 1 );
   SpinBox_Shrink->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
   SpinBox_Shrink->setButtonSymbols( QSpinBox::PlusMinus );
 
-  ButtonGroup1Layout->addWidget( TextLabel_Fill,        0, 0 );
-  ButtonGroup1Layout->addWidget( btnFillColor,          0, 1 );
-  ButtonGroup1Layout->addWidget( TextLabel_BackFace,    0, 2 );
-  ButtonGroup1Layout->addWidget( btnBackFaceColor,      0, 3 );
-  ButtonGroup1Layout->addWidget( TextLabel_Outine,      1, 0 );
-  ButtonGroup1Layout->addWidget( btnOutlineColor,       1, 1 );
-  ButtonGroup1Layout->addWidget( TextLabel_Width,       1, 2 );
-  ButtonGroup1Layout->addWidget( SpinBox_Width,         1, 3 );
-  ButtonGroup1Layout->addWidget( TextLabel_ShrinkCoeff, 2, 0 );
-  ButtonGroup1Layout->addWidget( SpinBox_Shrink,        2, 1, 1, 3 );
+  ButtonGroup1Layout->addWidget( TextLabel_Fill,             0, 0 );
+  ButtonGroup1Layout->addWidget( toolSurfColor,              0, 1, 1, 3 );
+
+  ButtonGroup1Layout->addWidget( TextLabel_Outline,          1, 0 );
+  ButtonGroup1Layout->addWidget( btnOutlineColor,            1, 1 );
+  ButtonGroup1Layout->addWidget( TextLabel_Wireframe,        1, 2 );
+  ButtonGroup1Layout->addWidget( btnWireframeColor,         1, 3 );
+
+  ButtonGroup1Layout->addWidget( TextLabel_0DElements_Color, 2, 0 );
+  ButtonGroup1Layout->addWidget( btn0DElementsColor,         2, 1 );
+
+  ButtonGroup1Layout->addWidget( TextLabel_0DElements_Size,  2, 2 );
+  ButtonGroup1Layout->addWidget( SpinBox_0DElements_Size,    2, 3 );
+
+  ButtonGroup1Layout->addWidget( TextLabel_BallElem_Color, 2, 0 );
+  ButtonGroup1Layout->addWidget( btnBallElemColor,         2, 1 );
+
+  ButtonGroup1Layout->addWidget( TextLabel_BallElem_Size,  2, 2 );
+  ButtonGroup1Layout->addWidget( SpinBox_BallElem_Size,    2, 3 );
+
+  ButtonGroup1Layout->addWidget( TextLabel_Width,            3, 0 );
+  ButtonGroup1Layout->addWidget( SpinBox_Width,              3, 1 );
+  ButtonGroup1Layout->addWidget( TextLabel_ShrinkCoeff,      3, 2 );
+  ButtonGroup1Layout->addWidget( SpinBox_Shrink,             3, 3 );
 
   // -------------------------------
-  QGroupBox* ButtonGroup2 = new QGroupBox( tr( "Nodes" ), this );
-  QHBoxLayout* ButtonGroup2Layout = new QHBoxLayout( ButtonGroup2 );
+  QGroupBox* ButtonGroup2 = new QGroupBox( tr( "GRP_NODES" ), this );
+  QGridLayout* ButtonGroup2Layout = new QGridLayout( ButtonGroup2 );
   ButtonGroup2Layout->setSpacing( SPACING );
   ButtonGroup2Layout->setMargin( MARGIN );
 
-  QLabel* TextLabel_Nodes_Color = new QLabel( tr( "Color" ), ButtonGroup2 );
+  QLabel* TextLabel_Nodes_Color = new QLabel( tr( "NODES_COLOR_LBL" ), ButtonGroup2 );
   btnNodeColor = new QtxColorButton( ButtonGroup2 );
 
-  QLabel* TextLabel_Nodes_Size = new QLabel( tr( "Size" ), ButtonGroup2 );
-  SpinBox_Nodes_Size = new QSpinBox( ButtonGroup2 );
-  SpinBox_Nodes_Size->setRange( 0, 5 );
-  SpinBox_Nodes_Size->setSingleStep( 1 );
-  SpinBox_Nodes_Size->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
-  SpinBox_Nodes_Size->setButtonSymbols( QSpinBox::PlusMinus );
+  QGroupBox* MarkerGroup = new QGroupBox( tr( "NODES_MARKER_LBL" ), ButtonGroup2 );
+  QVBoxLayout* MarkerGroupLayout = new QVBoxLayout( MarkerGroup );
+  MarkerGroupLayout->setSpacing( 0 );
+  MarkerGroupLayout->setMargin( 0 );
+
+  MarkerWidget = new VTKViewer_MarkerWidget( MarkerGroup );
+
+  MarkerGroupLayout->addWidget( MarkerWidget );
+
+  ButtonGroup2Layout->addWidget( TextLabel_Nodes_Color, 0, 0 );
+  ButtonGroup2Layout->addWidget( btnNodeColor,          0, 1 );
+  ButtonGroup2Layout->addWidget( MarkerGroup,           1, 0, 1, 3 );
+  ButtonGroup2Layout->setColumnStretch( 2, 1 );
+
+  // -------------------------------
+  QGroupBox* ButtonGroup3 = new QGroupBox( tr( "GRP_ORIENTATION" ), this );
+  QGridLayout* ButtonGroup3Layout = new QGridLayout( ButtonGroup3 );
+  ButtonGroup3Layout->setSpacing( SPACING );
+  ButtonGroup3Layout->setMargin( MARGIN );
+
+  QLabel* TextLabel_Orientation_Color = new QLabel( tr( "ORIENTATION_COLOR_LBL" ), ButtonGroup3 );
+  btnOrientationColor = new QtxColorButton( ButtonGroup3 );
+
+  QLabel* TextLabel_Orientation_Scale = new QLabel( tr( "ORIENTATION_SCALE_LBL" ), ButtonGroup3 );
+  SpinBox_Orientation_Scale = new SMESHGUI_SpinBox( ButtonGroup3 );
+  SpinBox_Orientation_Scale->setAcceptNames( false ); // No Notebook variables allowed
+  SpinBox_Orientation_Scale->RangeStepAndValidator( .05, .5, .05, "parametric_precision" );
+  SpinBox_Orientation_Scale->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+  SpinBox_Orientation_Scale->setButtonSymbols( QSpinBox::PlusMinus );
+
+  CheckBox_Orientation_3DVectors = new QCheckBox( tr( "3D_VECTORS_LBL" ), ButtonGroup3 );
+
+  ButtonGroup3Layout->addWidget( TextLabel_Orientation_Color,    0, 0 );
+  ButtonGroup3Layout->addWidget( btnOrientationColor,            0, 1 );
+  ButtonGroup3Layout->addWidget( TextLabel_Orientation_Scale,    0, 2 );
+  ButtonGroup3Layout->addWidget( SpinBox_Orientation_Scale,      0, 3 );
+  ButtonGroup3Layout->addWidget( CheckBox_Orientation_3DVectors, 1, 0, 1, 4 );
 
-  ButtonGroup2Layout->addWidget( TextLabel_Nodes_Color );
-  ButtonGroup2Layout->addWidget( btnNodeColor );
-  ButtonGroup2Layout->addWidget( TextLabel_Nodes_Size );
-  ButtonGroup2Layout->addWidget( SpinBox_Nodes_Size );
+  // -------------------------------
+  QGroupBox* ButtonGroup4 = new QGroupBox( tr( "GRP_SELECTION" ), this );
+  QGridLayout* ButtonGroup4Layout = new QGridLayout( ButtonGroup4 );
+  ButtonGroup3Layout->setSpacing( SPACING );
+  ButtonGroup3Layout->setMargin( MARGIN );
+  
+  QLabel* TextLabel_Selection_Color = new QLabel( tr( "SELECTION_COLOR_LBL" ), ButtonGroup4 );
+  btnSelectionColor = new QtxColorButton( ButtonGroup4 );
+  
+  QLabel* TextLabel_Preselection_Color = new QLabel( tr( "PRESELECTION_COLOR_LBL" ), ButtonGroup4 );
+  btnPreselectionColor = new QtxColorButton( ButtonGroup4 );
+  
+  ButtonGroup4Layout->addWidget( TextLabel_Selection_Color,      0, 0 );
+  ButtonGroup4Layout->addWidget( btnSelectionColor,              0, 1 );
+  ButtonGroup4Layout->addWidget( TextLabel_Preselection_Color,   0, 2 );
+  ButtonGroup4Layout->addWidget( btnPreselectionColor,           0, 3 );
 
   // -------------------------------
   QGroupBox* GroupButtons = new QGroupBox( this );
@@ -133,35 +224,46 @@ SMESHGUI_Preferences_ColorDlg::SMESHGUI_Preferences_ColorDlg( SMESHGUI* theModul
   GroupButtonsLayout->setSpacing( SPACING );
   GroupButtonsLayout->setMargin( MARGIN );
 
-  QPushButton* buttonOk = new QPushButton( tr( "&OK" ), GroupButtons );
+  QPushButton* buttonOk = new QPushButton( tr( "SMESH_BUT_OK" ), GroupButtons );
   buttonOk->setAutoDefault( true );
   buttonOk->setDefault( true );
 
-  QPushButton* buttonCancel = new QPushButton( tr( "&Cancel" ), GroupButtons );
+  QPushButton* buttonCancel = new QPushButton( tr( "SMESH_BUT_CANCEL" ), GroupButtons );
   buttonCancel->setAutoDefault( true );
 
+  QPushButton* buttonHelp = new QPushButton( tr( "SMESH_BUT_HELP" ), GroupButtons );
+  buttonHelp->setAutoDefault( true );
+
   GroupButtonsLayout->addWidget( buttonOk );
   GroupButtonsLayout->addSpacing( 10 );
   GroupButtonsLayout->addStretch();
   GroupButtonsLayout->addWidget( buttonCancel );
+  GroupButtonsLayout->addWidget( buttonHelp );
 
   // -------------------------------
   topLayout->addWidget( ButtonGroup1 );
   topLayout->addWidget( ButtonGroup2 );
+  topLayout->addWidget( ButtonGroup3 );
+  //  rnv: Selection and preselection colors are defined only in the Preferences 
+  //  topLayout->addWidget( ButtonGroup4 );
+  ButtonGroup4->hide();
   topLayout->addWidget( GroupButtons );
 
   // -------------------------------
   mySMESHGUI->SetActiveDialogBox( this );
 
+  myHelpFileName = "colors_size_page.html";
+
   /* signals and slots connections */
   connect( buttonOk,     SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
   connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( ClickOnCancel() ) );
+  connect( buttonHelp,   SIGNAL( clicked() ), this, SLOT( ClickOnHelp() ) );
 
   connect( mySMESHGUI, SIGNAL ( SignalDeactivateActiveDialog() ),
-          this,       SLOT( DeactivateActiveDialog() ) );
+           this,       SLOT( DeactivateActiveDialog() ) );
   /* to close dialog if study change */
   connect( mySMESHGUI, SIGNAL ( SignalCloseAllDialogs() ),
-          this,       SLOT( ClickOnCancel() ) );
+           this,       SLOT( ClickOnCancel() ) );
 }
 
 //=================================================================================
@@ -192,6 +294,30 @@ void SMESHGUI_Preferences_ColorDlg::ClickOnCancel()
   reject();
 }
 
+//=================================================================================
+// function : ClickOnHelp()
+// purpose  :
+//=================================================================================
+void SMESHGUI_Preferences_ColorDlg::ClickOnHelp()
+{
+  LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
+  if (app) 
+    app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
+  else {
+    QString platform;
+#ifdef WIN32
+    platform = "winapplication";
+#else
+    platform = "application";
+#endif
+    SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser", 
+                                                                 platform)).
+                             arg(myHelpFileName));
+  }
+}
+
 //=================================================================================
 // function : DeactivateActiveDialog()
 // purpose  :
@@ -226,10 +352,15 @@ void SMESHGUI_Preferences_ColorDlg::ActivateThisDialog()
 void SMESHGUI_Preferences_ColorDlg::SetColor( int type, const QColor& color )
 {
   switch ( type ) {
-  case 1 : btnFillColor->setColor( color );     break; // fill
-  case 2 : btnOutlineColor->setColor( color );  break; // outline
-  case 3 : btnNodeColor->setColor( color );     break; // node
-  case 4 : btnBackFaceColor->setColor( color ); break; // back face
+  case 1 : toolSurfColor->setMainColor( color );     break; // fill
+  case 2 : btnWireframeColor->setColor( color );     break; // wireframe
+  case 3 : btnNodeColor->setColor( color );          break; // node
+  case 4 : btnOutlineColor->setColor( color );       break; // outline
+  case 5 : btn0DElementsColor->setColor( color );    break; // 0d elements
+  case 6 : btnBallElemColor->setColor( color );      break; // ball elements
+  case 7 : btnOrientationColor->setColor( color );   break; // orientation of faces
+  case 8 : btnSelectionColor->setColor( color );     break; // selection color
+  case 9 : btnPreselectionColor->setColor( color );  break; // pre-selection color
   default: break;
   }
 }
@@ -242,10 +373,16 @@ QColor SMESHGUI_Preferences_ColorDlg::GetColor( int type )
 {
   QColor color;
   switch ( type ) {
-  case 1 : color = btnFillColor->color();     break; // fill
-  case 2 : color = btnOutlineColor->color();  break; // outline
-  case 3 : color = btnNodeColor->color();     break; // node
-  case 4 : color = btnBackFaceColor->color(); break; // back face
+  case 1 : color = toolSurfColor->mainColor();    break; // fill
+  case 2 : color = btnWireframeColor->color();    break; // outline
+  case 3 : color = btnNodeColor->color();         break; // node
+  case 4 : color = btnOutlineColor->color();      break; // node
+  case 5 : color = btn0DElementsColor->color();   break; // 0d elements
+  case 6 : color = btnBallElemColor->color();   break; // 0d elements
+  case 7 : color = btnOrientationColor->color();  break; // orientation of faces
+  case 8 : color = btnSelectionColor->color();    break; // selection color
+  case 9 : color = btnPreselectionColor->color(); break; // pre-selection color
+
   default: break;
   }
   return color;
@@ -258,9 +395,10 @@ QColor SMESHGUI_Preferences_ColorDlg::GetColor( int type )
 void SMESHGUI_Preferences_ColorDlg::SetIntValue( int type, int value )
 {
   switch ( type ) {
-  case 1 : SpinBox_Width->setValue( value );      break; // width
-  case 2 : SpinBox_Nodes_Size->setValue( value ); break; // nodes size = value; break;
-  case 3 : SpinBox_Shrink->setValue( value );     break; // shrink coeff
+  case 1 : SpinBox_Width->setValue( value );           break; // width
+  case 2 : SpinBox_Shrink->setValue( value );          break; // shrink coeff
+  case 3 : SpinBox_0DElements_Size->setValue( value ); break; // 0d elements
+  case 4 : SpinBox_BallElem_Size->setValue( value ); break; // 0d elements
   default: break;
   }
 }
@@ -273,10 +411,160 @@ int SMESHGUI_Preferences_ColorDlg::GetIntValue( int type )
 {
   int res = 0;
   switch ( type ) {
-  case 1 : res = SpinBox_Width->value();      break; // width
-  case 2 : res = SpinBox_Nodes_Size->value(); break; // nodes size
-  case 3 : res = SpinBox_Shrink->value();     break; // shrink coeff
+  case 1 : res = SpinBox_Width->value();           break; // width
+  case 2 : res = SpinBox_Shrink->value();          break; // shrink coeff
+  case 3 : res = SpinBox_0DElements_Size->value(); break; // 0d elements
+  case 4 : res = SpinBox_BallElem_Size->value(); break; // 0d elements
+  default: break;
+  }
+  return res;
+}
+
+//=================================================================================
+// function : SetDoubleValue()
+// purpose  :
+//=================================================================================
+void SMESHGUI_Preferences_ColorDlg::SetDoubleValue( int type, double value )
+{
+  switch ( type ) {
+  case 1 : SpinBox_Orientation_Scale->setValue( value ); break; // orientation scale
+  default: break;
+  }
+}
+
+//=================================================================================
+// function : GetDoubleValue()
+// purpose  :
+//=================================================================================
+double SMESHGUI_Preferences_ColorDlg::GetDoubleValue( int type )
+{
+  double res = 0;
+  switch ( type ) {
+  case 1 : res = SpinBox_Orientation_Scale->value(); break; // orientation scale
+  default: break;
+  }
+  return res;
+}
+
+//=================================================================================
+// function : SetBooleanValue()
+// purpose  :
+//=================================================================================
+void SMESHGUI_Preferences_ColorDlg::SetBooleanValue( int type, bool value )
+{
+  switch ( type ) {
+  case 1 : CheckBox_Orientation_3DVectors->setChecked( value ); break; // 3D vectors
+  default: break;
+  }
+}
+
+//=================================================================================
+// function : GetBooleanValue()
+// purpose  :
+//=================================================================================
+bool SMESHGUI_Preferences_ColorDlg::GetBooleanValue( int type )
+{
+  bool res = false;
+  switch ( type ) {
+  case 1 : res = CheckBox_Orientation_3DVectors->isChecked(); break; // 3D vectors
   default: break;
   }
   return res;
 }
+
+//=================================================================================
+// function : setCustomMarkerMap()
+// purpose  :
+//=================================================================================
+void SMESHGUI_Preferences_ColorDlg::setCustomMarkerMap( VTK::MarkerMap theMarkerMap )
+{
+  MarkerWidget->setCustomMarkerMap( theMarkerMap );
+}
+
+//=================================================================================
+// function : getCustomMarkerMap()
+// purpose  :
+//=================================================================================
+VTK::MarkerMap SMESHGUI_Preferences_ColorDlg::getCustomMarkerMap()
+{
+  return MarkerWidget->getCustomMarkerMap();
+}
+
+//=================================================================================
+// function : setStandardMarker()
+// purpose  :
+//=================================================================================
+void SMESHGUI_Preferences_ColorDlg::setStandardMarker( VTK::MarkerType theMarkerType,
+                                                       VTK::MarkerScale theMarkerScale )
+{
+  MarkerWidget->setStandardMarker( theMarkerType, theMarkerScale );
+}
+
+//=================================================================================
+// function : setCustomMarker()
+// purpose  :
+//=================================================================================
+void SMESHGUI_Preferences_ColorDlg::setCustomMarker( int theId )
+{
+  MarkerWidget->setCustomMarker( theId );
+}
+
+//=================================================================================
+// function : getMarkerType()
+// purpose  :
+//=================================================================================
+VTK::MarkerType SMESHGUI_Preferences_ColorDlg::getMarkerType() const
+{
+  return MarkerWidget->getMarkerType();
+}
+
+//=================================================================================
+// function : getStandardMarkerScale()
+// purpose  :
+//=================================================================================
+VTK::MarkerScale SMESHGUI_Preferences_ColorDlg::getStandardMarkerScale() const
+{
+  return MarkerWidget->getStandardMarkerScale();
+}
+
+//=================================================================================
+// function : getCustomMarkerID()
+// purpose  :
+//=================================================================================
+int SMESHGUI_Preferences_ColorDlg::getCustomMarkerID() const
+{
+  return MarkerWidget->getCustomMarkerID();
+}
+
+//=================================================================================
+// function : SetDeltaBrightness(int)
+// purpose  :
+//=================================================================================
+void SMESHGUI_Preferences_ColorDlg::SetDeltaBrightness(int delta) 
+{
+  toolSurfColor->setDelta(delta);
+}
+//=================================================================================
+// function : GetDeltaBrightness()
+// purpose  :
+//=================================================================================
+int SMESHGUI_Preferences_ColorDlg::GetDeltaBrightness() 
+{
+  return toolSurfColor->delta();
+}
+
+//=================================================================================
+// function : keyPressEvent()
+// purpose  :
+//=================================================================================
+void SMESHGUI_Preferences_ColorDlg::keyPressEvent( QKeyEvent* e )
+{
+  QDialog::keyPressEvent( e );
+  if ( e->isAccepted() )
+    return;
+
+  if ( e->key() == Qt::Key_F1 ) {
+    e->accept();
+    ClickOnHelp();
+  }
+}
index f3f43f94dd72255e392648fb1adcad3795f73b31..9533ca748365159b8c277bc9245e95285228d0c4 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_Preferences_ColorDlg.h
 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
 // SMESH includes
 #include "SMESH_SMESHGUI.hxx"
 
+// SALOME GUI includes
+#include <VTKViewer_MarkerDef.h>
+#include <QtxBiColorTool.h>
+
 // Qt includes
 #include <QDialog>
 
-class QSpinBox;
+class QCheckBox;
 class SMESHGUI;
-class QtxIntSpinBox;
+class SMESHGUI_SpinBox;
+class SalomeApp_IntSpinBox;
 class QtxColorButton;
+class VTKViewer_MarkerWidget;
 
 class SMESHGUI_EXPORT SMESHGUI_Preferences_ColorDlg : public QDialog
 { 
@@ -49,26 +56,55 @@ public:
   QColor                GetColor( int );
   void                  SetIntValue( int, int );
   int                   GetIntValue( int );
+  void                  SetDoubleValue( int, double );
+  double                GetDoubleValue( int );
+  void                  SetBooleanValue( int, bool );
+  bool                  GetBooleanValue( int );
+
+  void                  setCustomMarkerMap( VTK::MarkerMap );
+  VTK::MarkerMap        getCustomMarkerMap();
+
+  void                  SetDeltaBrightness(int);
+  int                   GetDeltaBrightness();
+
+  void                  setStandardMarker( VTK::MarkerType, VTK::MarkerScale );
+  void                  setCustomMarker( int );
+  VTK::MarkerType       getMarkerType() const;
+  VTK::MarkerScale      getStandardMarkerScale() const;
+  int                   getCustomMarkerID() const;
 
 protected:
   void                  closeEvent( QCloseEvent* );
+  void                  keyPressEvent( QKeyEvent* );
 
 private slots:
   void                  ClickOnOk();
   void                  ClickOnCancel();
+  void                  ClickOnHelp();
   void                  DeactivateActiveDialog();
   void                  ActivateThisDialog();
   
 private:
   SMESHGUI*             mySMESHGUI;            
-  
-  QtxColorButton*       btnFillColor;
-  QtxColorButton*       btnBackFaceColor;
+
+  QtxBiColorTool*       toolSurfColor; 
+  QtxColorButton*       btnWireframeColor;
   QtxColorButton*       btnOutlineColor;
-  QSpinBox*             SpinBox_Width;
-  QtxIntSpinBox*        SpinBox_Shrink;
+  QtxColorButton*       btn0DElementsColor;
+  QtxColorButton*       btnBallElemColor;
+  SalomeApp_IntSpinBox* SpinBox_0DElements_Size;
+  SalomeApp_IntSpinBox* SpinBox_BallElem_Size;
+  SalomeApp_IntSpinBox* SpinBox_Width;
+  SalomeApp_IntSpinBox* SpinBox_Shrink;
   QtxColorButton*       btnNodeColor;
-  QSpinBox*             SpinBox_Nodes_Size;
+  VTKViewer_MarkerWidget* MarkerWidget;
+  QtxColorButton*       btnOrientationColor;
+  SMESHGUI_SpinBox*     SpinBox_Orientation_Scale;
+  QCheckBox*            CheckBox_Orientation_3DVectors;
+  QtxColorButton*       btnPreselectionColor;
+  QtxColorButton*       btnSelectionColor;
+
+  QString               myHelpFileName;
 };
 
 #endif // SMESHGUI_PREFERENCES_COLORDLG_H
index a6d44e57a2c9ccb6c1b3e83add38bc754a5d7e99..7f0a861ae9f1f1e9bfdeba20d8d2d196c889c04d 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_Preferences_ScalarBarDlg.cxx
 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
 #include "SMESHGUI_Preferences_ScalarBarDlg.h"
 
 #include "SMESHGUI.h"
+#include "SMESHGUI_SpinBox.h"
 #include "SMESHGUI_VTKUtils.h"
 #include "SMESHGUI_Utils.h"
 
 #include <SMESH_Actor.h>
+#include <SMESH_ActorUtils.h>
+#include <SMESH_ScalarBarActor.h>
+#include <SMESH_ControlsDef.hxx>
 
 // SALOME GUI includes
 #include <SUIT_Desktop.h>
@@ -41,8 +46,8 @@
 #include <LightApp_Application.h>
 #include <LightApp_SelectionMgr.h>
 #include <SALOME_ListIO.hxx>
+#include <SalomeApp_IntSpinBox.h>
 
-#include <QtxDoubleSpinBox.h>
 #include <QtxColorButton.h>
 
 // Qt includes
@@ -54,7 +59,6 @@
 #include <QLineEdit>
 #include <QPushButton>
 #include <QRadioButton>
-#include <QSpinBox>
 #include <QHBoxLayout>
 #include <QVBoxLayout>
 #include <QGridLayout>
@@ -62,7 +66,6 @@
 
 // VTK includes
 #include <vtkTextProperty.h>
-#include <vtkScalarBarActor.h>
 #include <vtkLookupTable.h>
 
 #define MINIMUM_WIDTH 70
@@ -199,13 +202,15 @@ SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg( SMESHGUI*
   QHBoxLayout* myLabColorGrpLayout = new QHBoxLayout( myLabColorGrp );
   myLabColorGrpLayout->setSpacing( SPACING_SIZE ); myLabColorGrpLayout->setMargin( MARGIN_SIZE );
 
-  myColorsSpin = new QSpinBox( myLabColorGrp );
+  myColorsSpin = new SalomeApp_IntSpinBox( myLabColorGrp );
+  myColorsSpin->setAcceptNames( false ); // No Notebook variables allowed
   myColorsSpin->setRange( 2, 256 );
   myColorsSpin->setSingleStep( 1 );
   myColorsSpin->setMinimumWidth( MINIMUM_WIDTH );
   myColorsSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
 
-  myLabelsSpin = new QSpinBox( myLabColorGrp );
+  myLabelsSpin = new SalomeApp_IntSpinBox( myLabColorGrp );
+  myLabelsSpin->setAcceptNames( false ); // No Notebook variables allowed
   myLabelsSpin->setRange( 2, 65 );
   myLabelsSpin->setSingleStep( 1 );
   myLabelsSpin->setMinimumWidth( MINIMUM_WIDTH );
@@ -242,19 +247,27 @@ SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg( SMESHGUI*
   QGridLayout* myOriginDimGrpLayout = new QGridLayout( myOriginDimGrp );
   myOriginDimGrpLayout->setSpacing( SPACING_SIZE ); myOriginDimGrpLayout->setMargin( MARGIN_SIZE );
 
-  myXSpin = new QtxDoubleSpinBox (0.0, 1.0, 0.1, myOriginDimGrp);
+  myXSpin = new SMESHGUI_SpinBox(myOriginDimGrp);
+  myXSpin->setAcceptNames( false );
+  myXSpin->RangeStepAndValidator( 0.0, 1.0, 0.1, "parametric_precision" );
   myXSpin->setMinimumWidth( MINIMUM_WIDTH );
   myXSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
 
-  myYSpin = new QtxDoubleSpinBox(0.0, 1.0, 0.1, myOriginDimGrp);
+  myYSpin = new SMESHGUI_SpinBox(myOriginDimGrp);
+  myYSpin->setAcceptNames( false );
+  myYSpin->RangeStepAndValidator( 0.0, 1.0, 0.1, "parametric_precision" );  
   myYSpin->setMinimumWidth( MINIMUM_WIDTH );
   myYSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
 
-  myWidthSpin = new QtxDoubleSpinBox(0.0, 1.0, 0.1, myOriginDimGrp);
+  myWidthSpin = new SMESHGUI_SpinBox(myOriginDimGrp);
+  myWidthSpin->setAcceptNames( false );
+  myWidthSpin->RangeStepAndValidator( 0.0, 1.0, 0.1, "parametric_precision" );    
   myWidthSpin->setMinimumWidth( MINIMUM_WIDTH );
   myWidthSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
 
-  myHeightSpin = new QtxDoubleSpinBox(0.0, 1.0, 0.1, myOriginDimGrp);
+  myHeightSpin = new SMESHGUI_SpinBox(myOriginDimGrp);
+  myHeightSpin->setAcceptNames( false );
+  myHeightSpin->RangeStepAndValidator( 0.0, 1.0, 0.1, "parametric_precision" );    
   myHeightSpin->setMinimumWidth( MINIMUM_WIDTH );
   myHeightSpin->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
 
@@ -268,8 +281,35 @@ SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg( SMESHGUI*
   myOriginDimGrpLayout->addWidget( myHeightSpin, 1, 3 );
 
   aTopLayout->addWidget( myOriginDimGrp );
+  /******************************************************************************/
 
-  /***************************************************************/
+  // Destribution
+  myDistributionGrp = new QGroupBox ( tr( "SMESH_DISTRIBUTION_SCALARBAR" ), this );
+  myDistributionGrp->setCheckable(true);
+  QHBoxLayout* aDistributionGrpLayout = new QHBoxLayout( myDistributionGrp );
+  aDistributionGrpLayout->setSpacing( SPACING_SIZE ); aDistributionGrpLayout->setMargin( MARGIN_SIZE );
+
+  myDistribColorGrp = new QButtonGroup( this );
+
+  myDMonoColor  = new QRadioButton( tr( "SMESH_MONOCOLOR" ) ,  myDistributionGrp );
+  myDMultiColor = new QRadioButton( tr( "SMESH_MULTICOLOR" ),  myDistributionGrp );
+  myDMonoColor->setChecked( true );
+
+  myDistribColorGrp->addButton(myDMonoColor);myDistribColorGrp->setId(myDMonoColor,1);
+  myDistribColorGrp->addButton(myDMultiColor);myDistribColorGrp->setId(myDMultiColor,2);
+  
+  aDistributionGrpLayout->addWidget( myDMultiColor );
+  aDistributionGrpLayout->addWidget( myDMonoColor );
+  
+  //Color of the Distribution in monocolor case:
+  myDistributionColorLbl = new QLabel( tr( "SMESH_DISTRIBUTION_COLOR" ), myDistributionGrp );
+  aDistributionGrpLayout->addWidget( myDistributionColorLbl );
+  myMonoColorBtn = new QtxColorButton( myDistributionGrp  );
+  aDistributionGrpLayout->addWidget(myMonoColorBtn);
+  
+  aTopLayout->addWidget(myDistributionGrp);
+  
+  /******************************************************************************/
   // Common buttons
   myButtonGrp = new QGroupBox( this );
   QHBoxLayout* myButtonGrpLayout = new QHBoxLayout( myButtonGrp );
@@ -300,7 +340,7 @@ SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg( SMESHGUI*
   SUIT_ResourceMgr* mgr = SMESH::GetResourceMgr( mySMESHGUI );
 
   QColor titleColor = mgr->colorValue("SMESH", "scalar_bar_title_color",
-                                     QColor(255, 255, 255));
+                                      QColor(255, 255, 255));
   myTitleColorBtn->setColor(titleColor);
   myTitleFontCombo->setCurrentIndex(0);
   if (mgr->hasValue("SMESH", "scalar_bar_title_font")) {
@@ -316,9 +356,9 @@ SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg( SMESHGUI*
     myTitleItalicCheck->setChecked( f.italic() );
     myTitleShadowCheck->setChecked( f.overline() );
   }
-                                     
+                                      
   QColor labelColor = mgr->colorValue("SMESH", "scalar_bar_label_color", 
-                                     QColor(255, 255, 255));
+                                      QColor(255, 255, 255));
   myLabelsColorBtn->setColor(labelColor);
   myLabelsFontCombo->setCurrentIndex(0);
   if (mgr->hasValue("SMESH", "scalar_bar_label_font")) {
@@ -352,19 +392,39 @@ SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg( SMESHGUI*
   QString name = isHoriz ? "scalar_bar_horizontal_%1" : "scalar_bar_vertical_%1";
 
   myIniX = mgr->doubleValue("SMESH", name.arg( "x" ), 
-                           myHorizRadioBtn->isChecked() ? DEF_HOR_X : DEF_VER_X);
+                            myHorizRadioBtn->isChecked() ? DEF_HOR_X : DEF_VER_X);
 
   myIniY = mgr->doubleValue("SMESH", name.arg( "y" ),
-                           myHorizRadioBtn->isChecked() ? DEF_HOR_Y : DEF_VER_Y);
+                            myHorizRadioBtn->isChecked() ? DEF_HOR_Y : DEF_VER_Y);
 
   myIniW = mgr->doubleValue("SMESH", name.arg( "width" ),
-                           myHorizRadioBtn->isChecked() ? DEF_HOR_W : DEF_VER_W);
+                            myHorizRadioBtn->isChecked() ? DEF_HOR_W : DEF_VER_W);
 
   myIniH = mgr->doubleValue("SMESH", name.arg( "height" ),
-                           myHorizRadioBtn->isChecked() ? DEF_HOR_H : DEF_VER_H);
+                            myHorizRadioBtn->isChecked() ? DEF_HOR_H : DEF_VER_H);
 
   setOriginAndSize(myIniX, myIniY, myIniW, myIniH);
 
+
+  bool distributionVisibility = mgr->booleanValue("SMESH","distribution_visibility");
+  myDistributionGrp->setChecked(distributionVisibility);
+
+  int coloringType = mgr->integerValue("SMESH", "distribution_coloring_type", 0);
+  if( coloringType == SMESH_MONOCOLOR_TYPE ) {
+    myDMonoColor->setChecked(true);
+    onDistributionChanged(myDistribColorGrp->id(myDMonoColor));    
+  } else {
+    myDMultiColor->setChecked(true);
+    onDistributionChanged(myDistribColorGrp->id(myDMultiColor));
+
+  }
+  
+  QColor distributionColor = mgr->colorValue("SMESH", "distribution_color",
+                                             QColor(255, 255, 255));
+  myMonoColorBtn->setColor(distributionColor);
+  
+  
+
   // --> then init from selection if necessary
   onSelectionChanged();
 
@@ -377,10 +437,12 @@ SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg( SMESHGUI*
   connect( myXSpin,             SIGNAL( valueChanged( double ) ), this, SLOT( onXYChanged() ) );
   connect( myYSpin,             SIGNAL( valueChanged( double ) ), this, SLOT( onXYChanged() ) );
   connect( aOrientationGrp,     SIGNAL( buttonClicked( int ) ),   this, SLOT( onOrientationChanged() ) );
+  connect( myDistributionGrp,   SIGNAL( toggled(bool) ), this, SLOT(onDistributionActivated(bool)) );
+  connect( myDistribColorGrp,   SIGNAL( buttonClicked( int ) ),   this, SLOT( onDistributionChanged( int ) ) );
   connect( mySelectionMgr,      SIGNAL( currentSelectionChanged() ), this, SLOT( onSelectionChanged() ) );
   connect( mySMESHGUI,          SIGNAL( SignalCloseAllDialogs() ),   this, SLOT( onCancel() ) );
 
-  myHelpFileName = "about_quality_controls_page.html";
+  myHelpFileName = "quality_page.html";
 }
 
 //=================================================================================================
@@ -419,7 +481,7 @@ bool SMESHGUI_Preferences_ScalarBarDlg::onApply()
   // Scalar Bar properties
   if (!myActor)
     return false;
-  vtkScalarBarActor* myScalarBarActor = myActor->GetScalarBarActor();
+  SMESH_ScalarBarActor* myScalarBarActor = myActor->GetScalarBarActor();
 
   vtkTextProperty* aTitleTextPrp = myScalarBarActor->GetTitleTextProperty();
   QColor aTColor = myTitleColorBtn->color();
@@ -450,7 +512,6 @@ bool SMESHGUI_Preferences_ScalarBarDlg::onApply()
   myScalarBarActor->SetLabelTextProperty( aLabelsTextPrp );
 
   myScalarBarActor->SetNumberOfLabels( myLabelsSpin->value() );
-  myScalarBarActor->SetMaximumNumberOfColors( myColorsSpin->value() );
 
   if ( myHorizRadioBtn->isChecked() )
     myScalarBarActor->SetOrientationToHorizontal();
@@ -461,13 +522,59 @@ bool SMESHGUI_Preferences_ScalarBarDlg::onApply()
   myScalarBarActor->SetWidth( myWidthSpin->value() );
   myScalarBarActor->SetHeight( myHeightSpin->value() );
 
+  // Distribution
+  bool distributionTypeChanged = false, colorChanged=false;
+  myScalarBarActor->SetDistributionVisibility((int)myDistributionGrp->isChecked());
+  if( myDistributionGrp->isChecked() ) {
+    int ColoringType = myDMultiColor->isChecked() ? SMESH_MULTICOLOR_TYPE : SMESH_MONOCOLOR_TYPE;
+    distributionTypeChanged = (ColoringType != myScalarBarActor->GetDistributionColoringType());
+    if(distributionTypeChanged)      
+      myScalarBarActor->SetDistributionColoringType(ColoringType);
+    
+    if( !myDMultiColor->isChecked() ) {
+      QColor aTColor = myMonoColorBtn->color();
+      double rgb[3], oldRgb[3];;
+      rgb [0] = aTColor.red()/255.;
+      rgb [1] = aTColor.green()/255.;
+      rgb [2] = aTColor.blue()/255.;
+      myScalarBarActor->GetDistributionColor(oldRgb);
+      colorChanged = (rgb[0] != oldRgb[0] || rgb[1] != oldRgb[1] || rgb[2] != oldRgb[2]);
+      if(colorChanged)
+        myScalarBarActor->SetDistributionColor(rgb);
+    }
+  }
+
   double aMin = myMinEdit->text().toDouble();
   double aMax = myMaxEdit->text().toDouble();
   vtkLookupTable* myLookupTable =
     static_cast<vtkLookupTable*>(myScalarBarActor->GetLookupTable());
+  double oldMinMax[2] = { myLookupTable->GetRange()[0], myLookupTable->GetRange()[1] };
+  bool rangeChanges = ( fabs( oldMinMax[0] - aMin ) + fabs( oldMinMax[1] - aMax ) >
+                        0.001 * ( aMax-aMin + oldMinMax[1]-oldMinMax[0] ));
+  
+  bool nbColorsChanged = (myColorsSpin->value() != myScalarBarActor->GetMaximumNumberOfColors());
+  if(nbColorsChanged)
+    myScalarBarActor->SetMaximumNumberOfColors(myColorsSpin->value());
+  
+
   myLookupTable->SetRange( aMin, aMax );
   myLookupTable->SetNumberOfTableValues(myColorsSpin->value());
   myLookupTable->Build();
+
+  if( nbColorsChanged || rangeChanges)
+    myActor->UpdateDistribution();
+  
+#ifndef DISABLE_PLOT2DVIEWER
+  if( myActor->GetPlot2Histogram() && 
+      (nbColorsChanged || 
+       rangeChanges ||
+       distributionTypeChanged || 
+       colorChanged ))
+    SMESH::ProcessIn2DViewers(myActor);
+#endif
+    
+    
+
   SMESH::RepaintCurrentView();
   return true;
 }
@@ -504,10 +611,10 @@ void SMESHGUI_Preferences_ScalarBarDlg::onHelp()
     platform = "application";
 #endif
     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser", 
-                                                                platform)).
-                            arg(myHelpFileName));
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser", 
+                                                                 platform)).
+                             arg(myHelpFileName));
   }
 }
 
@@ -528,56 +635,71 @@ void SMESHGUI_Preferences_ScalarBarDlg::onSelectionChanged()
     if( anIO->hasEntry() ) {
       SMESH_Actor* anActor = SMESH::FindActorByEntry(anIO->getEntry());
       if ( anActor && anActor->GetScalarBarActor() && anActor->GetControlMode() != SMESH_Actor::eNone ) {
-       myActor = anActor;
-       vtkScalarBarActor* myScalarBarActor = myActor->GetScalarBarActor();
-
-       if ( myScalarBarActor->GetLookupTable() ) {
-         vtkFloatingPointType *range = myScalarBarActor->GetLookupTable()->GetRange();
-         myMinEdit->setText( QString::number( range[0],'g',12 ) );
-         myMaxEdit->setText( QString::number( range[1],'g',12 ) );
-       }
-
-       vtkTextProperty* aTitleTextPrp = myScalarBarActor->GetTitleTextProperty();
-       vtkFloatingPointType aTColor[3];
-       aTitleTextPrp->GetColor( aTColor );
-       myTitleColorBtn->setColor( QColor( (int)( aTColor[0]*255 ), (int)( aTColor[1]*255 ), (int)( aTColor[2]*255 ) ) );
-       myTitleFontCombo->setCurrentIndex( aTitleTextPrp->GetFontFamily() );
-       myTitleBoldCheck->setChecked( aTitleTextPrp->GetBold() );
-       myTitleItalicCheck->setChecked( aTitleTextPrp->GetItalic() );
-       myTitleShadowCheck->setChecked( aTitleTextPrp->GetShadow() );
-
-       vtkTextProperty* aLabelsTextPrp = myScalarBarActor->GetLabelTextProperty();
-       vtkFloatingPointType aLColor[3];
-       aLabelsTextPrp->GetColor( aLColor );
-       myLabelsColorBtn->setColor( QColor( (int)( aLColor[0]*255 ), (int)( aLColor[1]*255 ), (int)( aLColor[2]*255 ) ) );
-       myLabelsFontCombo->setCurrentIndex( 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 = anActor;
+        SMESH_ScalarBarActor* myScalarBarActor = myActor->GetScalarBarActor();
+
+        if ( myScalarBarActor->GetLookupTable() ) {
+          vtkFloatingPointType *range = myScalarBarActor->GetLookupTable()->GetRange();
+          myMinEdit->setText( QString::number( range[0],'g',12 ) );
+          myMaxEdit->setText( QString::number( range[1],'g',12 ) );
+        }
+
+        vtkTextProperty* aTitleTextPrp = myScalarBarActor->GetTitleTextProperty();
+        vtkFloatingPointType aTColor[3];
+        aTitleTextPrp->GetColor( aTColor );
+        myTitleColorBtn->setColor( QColor( (int)( aTColor[0]*255 ), (int)( aTColor[1]*255 ), (int)( aTColor[2]*255 ) ) );
+        myTitleFontCombo->setCurrentIndex( aTitleTextPrp->GetFontFamily() );
+        myTitleBoldCheck->setChecked( aTitleTextPrp->GetBold() );
+        myTitleItalicCheck->setChecked( aTitleTextPrp->GetItalic() );
+        myTitleShadowCheck->setChecked( aTitleTextPrp->GetShadow() );
+
+        vtkTextProperty* aLabelsTextPrp = myScalarBarActor->GetLabelTextProperty();
+        vtkFloatingPointType aLColor[3];
+        aLabelsTextPrp->GetColor( aLColor );
+        myLabelsColorBtn->setColor( QColor( (int)( aLColor[0]*255 ), (int)( aLColor[1]*255 ), (int)( aLColor[2]*255 ) ) );
+        myLabelsFontCombo->setCurrentIndex( 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 );
+
+        int coloringType = myScalarBarActor->GetDistributionColoringType();
+        myScalarBarActor->GetDistributionColor( aTColor );
+        myMonoColorBtn->setColor( QColor( (int)( aTColor[0]*255 ), (int)( aTColor[1]*255 ), (int)( aTColor[2]*255 ) ) );
+        if ( coloringType == SMESH_MONOCOLOR_TYPE ) {
+          myDMonoColor->setChecked(true);
+          onDistributionChanged(myDistribColorGrp->id(myDMonoColor));    
+        } else {
+          myDMultiColor->setChecked(true);
+          onDistributionChanged(myDistribColorGrp->id(myDMultiColor));
+        }
+        myDistributionGrp->setChecked((bool)myScalarBarActor->GetDistributionVisibility());
+        onDistributionActivated(myScalarBarActor->GetDistributionVisibility());
+        
+        
+        myRangeGrp->setEnabled( true );
+        myFontGrp->setEnabled( true );
+        myLabColorGrp->setEnabled( true );
+        myOrientationGrp->setEnabled( true );
+        myOriginDimGrp->setEnabled( true );
+        myOkBtn->setEnabled( true );
+        myApplyBtn->setEnabled( true );
+        myDistributionGrp->setEnabled( true );
+        return;
       }
     }
   }
@@ -589,6 +711,7 @@ void SMESHGUI_Preferences_ScalarBarDlg::onSelectionChanged()
   myOriginDimGrp->setEnabled( false );
   myOkBtn->setEnabled( false );
   myApplyBtn->setEnabled( false );
+  myDistributionGrp->setEnabled( false );
 }
 
 //=================================================================================================
@@ -625,9 +748,9 @@ void SMESHGUI_Preferences_ScalarBarDlg::onXYChanged()
  */
 //=================================================================================================
 void SMESHGUI_Preferences_ScalarBarDlg::setOriginAndSize( const double x,
-                                                         const double y,
-                                                         const double w,
-                                                         const double h )
+                                                          const double y,
+                                                          const double w,
+                                                          const double h )
 {
   blockSignals( true );
   myXSpin->setValue( x );
@@ -640,6 +763,42 @@ void SMESHGUI_Preferences_ScalarBarDlg::setOriginAndSize( const double x,
   onXYChanged();
 }
 
+
+//=================================================================================================
+/*!
+ *  SMESHGUI_Preferences_ScalarBarDlg::onDistributionChanged
+ *
+ *  Called when coloring type of the distribution is changed
+ */
+//=================================================================================================
+void SMESHGUI_Preferences_ScalarBarDlg::onDistributionChanged( int id ) {
+
+  bool isActive = myDistribColorGrp->id(myDMonoColor) == id;
+
+  myMonoColorBtn->setEnabled(isActive);
+  myDistributionColorLbl->setEnabled(isActive);
+}
+//=================================================================================================
+/*!
+ *  SMESHGUI_Preferences_ScalarBarDlg::onDistributionActivated
+ *
+ *  Called when distribution group check box is changed
+ */
+//=================================================================================================
+void SMESHGUI_Preferences_ScalarBarDlg::onDistributionActivated(bool on) {
+  if(on) {
+    if(myDMonoColor->isChecked())
+      onDistributionChanged(myDistribColorGrp->id(myDMonoColor)  );
+    else if(myDMultiColor->isChecked())
+      onDistributionChanged(myDistribColorGrp->id(myDMultiColor) );
+  }
+  else {
+    myMonoColorBtn->setEnabled(false);
+    myDistributionColorLbl->setEnabled(false);
+  }
+}
+
+
 //=================================================================================================
 /*!
  *  SMESHGUI_Preferences_ScalarBarDlg::onOrientationChanged
@@ -656,9 +815,9 @@ void SMESHGUI_Preferences_ScalarBarDlg::onOrientationChanged()
     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 );
+                      aOrientation ? DEF_VER_Y : DEF_HOR_Y,
+                      aOrientation ? DEF_VER_W : DEF_HOR_W,
+                      aOrientation ? DEF_VER_H : DEF_HOR_H );
 }
 
 //=================================================================================================
index 60963126798977b9d2bdc92fef65e891d65bb40c..804b4aa6aa742a97a9fa4480f28d0724eb7643d7 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_Preferences_ScalarBarDlg.h
 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
@@ -39,11 +40,13 @@ class QLineEdit;
 class QPushButton;
 class QToolButton;
 class QRadioButton;
-class QSpinBox;
+class QButtonGroup;
+class QLabel;
 
 class SMESHGUI;
 class SMESH_Actor;
-class QtxDoubleSpinBox;
+class SMESHGUI_SpinBox;
+class SalomeApp_IntSpinBox;
 class QtxColorButton;
 class LightApp_SelectionMgr;
 
@@ -63,9 +66,9 @@ public:
 
   void                     closeEvent( QCloseEvent* );
   void                     setOriginAndSize( const double,
-                                            const double,
-                                            const double,
-                                            const double );
+                                             const double,
+                                             const double,
+                                             const double );
   void                     initScalarBarFromResources();
 
 protected slots:
@@ -76,6 +79,8 @@ protected slots:
   void                     onSelectionChanged();
   void                     onXYChanged();
   void                     onOrientationChanged();
+  void                     onDistributionChanged( int );
+  void                     onDistributionActivated( bool );
 
 private:
   SMESHGUI*                mySMESHGUI;
@@ -103,20 +108,27 @@ private:
   QCheckBox*               myLabelsShadowCheck;
   
   QGroupBox*               myLabColorGrp;
-  QSpinBox*                myColorsSpin;
-  QSpinBox*                myLabelsSpin;
+  SalomeApp_IntSpinBox*    myColorsSpin;
+  SalomeApp_IntSpinBox*    myLabelsSpin;
 
   QGroupBox*               myOrientationGrp;
   QRadioButton*            myVertRadioBtn;
   QRadioButton*            myHorizRadioBtn;
 
   QGroupBox*               myOriginDimGrp;
-  QtxDoubleSpinBox*        myXSpin;
-  QtxDoubleSpinBox*        myYSpin;
-  QtxDoubleSpinBox*        myWidthSpin;
-  QtxDoubleSpinBox*        myHeightSpin;
+  SMESHGUI_SpinBox*        myXSpin;
+  SMESHGUI_SpinBox*        myYSpin;
+  SMESHGUI_SpinBox*        myWidthSpin;
+  SMESHGUI_SpinBox*        myHeightSpin;
+
+  QGroupBox*               myDistributionGrp;
+  QRadioButton*            myDMonoColor;
+  QRadioButton*            myDMultiColor;
+  QtxColorButton*          myMonoColorBtn;
+  QLabel*                  myDistributionColorLbl;
 
   QGroupBox*               myButtonGrp;
+  QButtonGroup*            myDistribColorGrp;
   QPushButton*             myOkBtn;
   QPushButton*             myApplyBtn;
   QPushButton*             myCancelBtn;
diff --git a/src/SMESHGUI/SMESHGUI_PreviewDlg.cxx b/src/SMESHGUI/SMESHGUI_PreviewDlg.cxx
new file mode 100644 (file)
index 0000000..0a9bf68
--- /dev/null
@@ -0,0 +1,125 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+// SMESH SMESHGUI : GUI for SMESH component
+// File   : SMESHGUI_PreviewDlg.cxx
+// Author : Roman NIKOLAEV, Open CASCADE S.A.S.
+// SMESH includes
+//
+
+//SMESH includes
+#include "SMESHGUI.h"
+#include "SMESHGUI_PreviewDlg.h"
+#include "SMESHGUI_MeshEditPreview.h"
+#include "SMESHGUI_VTKUtils.h"
+#include "SMESHGUI_Utils.h"
+
+//GUI includes
+#include <SUIT_Desktop.h>
+
+//QT includes
+#include <QCheckBox>
+
+
+//=================================================================================
+// class    : SMESHGUI_SMESHGUI_PreviewDlg()
+// purpose  :
+//=================================================================================
+SMESHGUI_PreviewDlg::SMESHGUI_PreviewDlg(SMESHGUI* theModule) :
+  mySMESHGUI(theModule),
+  QDialog(SMESH::GetDesktop( theModule )),
+  myIsApplyAndClose( false )
+{
+  mySimulation = new SMESHGUI_MeshEditPreview(SMESH::GetViewWindow( mySMESHGUI ));
+}
+
+//=================================================================================
+// function : ~SMESHGUI_PreviewDlg()
+// purpose  : Destroys the object and frees any allocated resources
+//=================================================================================
+SMESHGUI_PreviewDlg::~SMESHGUI_PreviewDlg()
+{
+  delete mySimulation;
+}
+
+//=================================================================================
+// function : showPreview
+// purpose  : Show preview in the viewer
+//=================================================================================
+void SMESHGUI_PreviewDlg::showPreview(){
+  if(mySimulation)
+    mySimulation->SetVisibility(true);
+}
+
+//=================================================================================
+// function : hidePreview
+// purpose  : Hide preview in the viewer
+//=================================================================================
+void SMESHGUI_PreviewDlg::hidePreview(){
+  if(mySimulation)
+    mySimulation->SetVisibility(false);
+}
+
+//=================================================================================
+// function : connectPreviewControl
+// purpose  : Connect the preview check box
+//=================================================================================
+void SMESHGUI_PreviewDlg::connectPreviewControl(){
+  connect(myPreviewCheckBox, SIGNAL(toggled(bool)), this, SLOT(onDisplaySimulation(bool)));
+}
+
+
+//=================================================================================
+// function : toDisplaySimulation
+// purpose  : 
+//=================================================================================
+void SMESHGUI_PreviewDlg::toDisplaySimulation() {
+  onDisplaySimulation(true);
+}
+
+//=================================================================================
+// function : onDisplaySimulation
+// purpose  : 
+//=================================================================================
+void SMESHGUI_PreviewDlg::onDisplaySimulation(bool toDisplayPreview) {
+  //Empty implementation here
+}
+
+//================================================================
+// Function : setIsApplyAndClose
+// Purpose  : Set value of the flag indicating that the dialog is
+//            accepted by Apply & Close button
+//================================================================
+void SMESHGUI_PreviewDlg::setIsApplyAndClose( const bool theFlag )
+{
+  myIsApplyAndClose = theFlag;
+}
+
+//================================================================
+// Function : isApplyAndClose
+// Purpose  : Get value of the flag indicating that the dialog is
+//            accepted by Apply & Close button
+//================================================================
+bool SMESHGUI_PreviewDlg::isApplyAndClose() const
+{
+  return myIsApplyAndClose;
+}
diff --git a/src/SMESHGUI/SMESHGUI_PreviewDlg.h b/src/SMESHGUI/SMESHGUI_PreviewDlg.h
new file mode 100644 (file)
index 0000000..f473114
--- /dev/null
@@ -0,0 +1,67 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+// SMESH SMESHGUI : GUI for SMESH component
+// File   : SMESHGUI_RotationDlg.h
+// Author : Roman NIKOLAEV, Open CASCADE S.A.S.
+//
+#ifndef SMESHGUI_PREVIEWDLG_H
+#define SMESHGUI_PREVIEWDLG_H
+
+// SMESH includes
+#include "SMESH_SMESHGUI.hxx"
+
+// Qt includes
+#include <QDialog>
+
+class SMESHGUI;
+class SMESHGUI_MeshEditPreview;
+class QCheckBox;
+
+class SMESHGUI_EXPORT SMESHGUI_PreviewDlg : public QDialog {
+  Q_OBJECT
+public:
+  SMESHGUI_PreviewDlg( SMESHGUI* );
+  ~SMESHGUI_PreviewDlg();
+
+  void showPreview();
+  void hidePreview();
+
+protected:
+  void connectPreviewControl();
+
+  virtual void setIsApplyAndClose( const bool theFlag );
+  virtual bool isApplyAndClose() const;
+
+protected slots:
+ void                      toDisplaySimulation();
+ virtual void              onDisplaySimulation( bool );
+
+  
+protected:
+  SMESHGUI*                 mySMESHGUI;              /* Current SMESHGUI object */  
+  SMESHGUI_MeshEditPreview* mySimulation;
+  QCheckBox*                myPreviewCheckBox;
+  bool                      myIsApplyAndClose;
+};
+
+#endif
index 118d2d17c829f90f738c4078dcdc5e07464bcb02..f16f568fe60a84b276ca3c4f1fde146ae8823ab7 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_RemoveElementsDlg.cxx
 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
@@ -122,6 +123,7 @@ SMESHGUI_RemoveElementsDlg
   SelectButtonC1A1->setIcon(image1);
   LineEditC1A1 = new QLineEdit(GroupC1);
   LineEditC1A1->setValidator(new SMESHGUI_IdValidator(this));
+  LineEditC1A1->setMaxLength(-1);
   QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupC1 );
   connect(filterBtn,   SIGNAL(clicked()), this, SLOT(setFilters()));
 
@@ -204,7 +206,7 @@ void SMESHGUI_RemoveElementsDlg::Init()
   /* to close dialog if study change */
   connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(ClickOnCancel()));
   connect(myEditCurrentArgument, SIGNAL(textChanged(const QString&)),
-         SLOT(onTextChange(const QString&)));
+          SLOT(onTextChange(const QString&)));
 
   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
     aViewWindow->SetSelectionMode(CellSelection);
@@ -231,7 +233,7 @@ void SMESHGUI_RemoveElementsDlg::ClickOnApply()
     bool aResult = false;
     try {
       SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
-      aResult = aMeshEditor->RemoveElements(anArrayOfIdeces.inout());
+      aResult = aMeshEditor->RemoveElements(anArrayOfIdeces.in());
     } catch (const SALOME::SALOME_Exception& S_ex) {
       SalomeApp_Tools::QtCatchCorbaException(S_ex);
       myEditCurrentArgument->clear();
@@ -243,6 +245,7 @@ void SMESHGUI_RemoveElementsDlg::ClickOnApply()
       myEditCurrentArgument->clear();
       mySelector->ClearIndex();
       SMESH::UpdateView();
+      SMESHGUI::Modified();
     }
   }
 }
@@ -291,10 +294,10 @@ void SMESHGUI_RemoveElementsDlg::ClickOnHelp()
     platform = "application";
 #endif
     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser", 
-                                                                platform)).
-                            arg(myHelpFileName));
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser", 
+                                                                 platform)).
+                             arg(myHelpFileName));
   }
 }
 
@@ -309,9 +312,6 @@ void SMESHGUI_RemoveElementsDlg::onTextChange(const QString& theNewText)
 
   myNbOkElements = 0;
 
-  buttonOk->setEnabled(false);
-  buttonApply->setEnabled(false);
-
   // hilight entered elements
   if(myActor){
     if(SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh()){
@@ -321,24 +321,20 @@ void SMESHGUI_RemoveElementsDlg::onTextChange(const QString& theNewText)
       
       QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
       for (int i = 0; i < aListId.count(); i++) {
-       if(const SMDS_MeshElement *anElem = aMesh->FindElement(aListId[i].toInt())) {
-         newIndices.Add(anElem->GetID());
-         myNbOkElements++;
-       }
+        if(const SMDS_MeshElement *anElem = aMesh->FindElement(aListId[i].toInt())) {
+          newIndices.Add(anElem->GetID());
+          myNbOkElements++;
+        }
       }
       
       mySelector->AddOrRemoveIndex(anIO,newIndices,false);
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-       aViewWindow->highlight(anIO,true,true);
+        aViewWindow->highlight(anIO,true,true);
     }
   }
   
-  if (myNbOkElements) {
-    buttonOk->setEnabled(true);
-    buttonApply->setEnabled(true);
-  }
-  
   myBusy = false;
+  updateButtons();
 }
 
 //=================================================================================
@@ -347,56 +343,52 @@ void SMESHGUI_RemoveElementsDlg::onTextChange(const QString& theNewText)
 //=================================================================================
 void SMESHGUI_RemoveElementsDlg::SelectionIntoArgument()
 {
-  if (myBusy) return;
+  if (myBusy) return;                                  // busy
+  if (myFilterDlg && myFilterDlg->isVisible()) return; // filter digl active
+  if (!GroupButtons->isEnabled()) return;              // inactive
 
   // clear
 
-  myNbOkElements = false;
+  myNbOkElements = 0;
   myActor = 0;
 
   myBusy = true;
   myEditCurrentArgument->setText("");
   myBusy = false;
 
-  if (!GroupButtons->isEnabled()) // inactive
-    return;
-
-  buttonOk->setEnabled(false);
-  buttonApply->setEnabled(false);
-
   // get selected mesh
 
   SALOME_ListIO aList;
   mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
 
   int nbSel = aList.Extent();
-  if (nbSel != 1)
-    return;
-
-  Handle(SALOME_InteractiveObject) anIO = aList.First();
-  myMesh = SMESH::GetMeshByIO(anIO);
-  if (myMesh->_is_nil())
-    return;
-
-  myActor = SMESH::FindActorByEntry(anIO->getEntry());
-  if (!myActor)
-    return;
-
-  // get selected nodes
-  QString aString = "";
-  int nbElems = SMESH::GetNameOfSelectedElements(mySelector,anIO,aString);
-  if(nbElems < 1)
-    return;
-  myBusy = true;
-  myEditCurrentArgument->setText(aString);
-  myBusy = false;
-
-  // OK
-
-  myNbOkElements = nbElems;
-
-  buttonOk->setEnabled(true);
-  buttonApply->setEnabled(true);
+  if (nbSel == 1) {
+
+    Handle(SALOME_InteractiveObject) anIO = aList.First();
+    myMesh = SMESH::GetMeshByIO(anIO);
+
+    if (!myMesh->_is_nil()) {
+
+      myActor = SMESH::FindActorByEntry(anIO->getEntry());
+      if (myActor) {
+        
+        // get selected nodes
+        QString aString = "";
+        int nbElems = SMESH::GetNameOfSelectedElements(mySelector,anIO,aString);
+        if (nbElems > 0) {
+          myBusy = true;
+          myEditCurrentArgument->setText(aString);
+          myBusy = false;
+          
+          // OK
+          
+          myNbOkElements = nbElems;
+        } // if (nbElems > 0)
+      } // if (myActor)
+    } // if (!myMesh->_is_nil())
+  } // if (nbSel == 1) {
+
+  updateButtons();        
 }
 
 //=================================================================================
@@ -410,8 +402,8 @@ void SMESHGUI_RemoveElementsDlg::SetEditCurrentArgument()
   case 0: /* default constructor */
     {
       if(send == SelectButtonC1A1) {
-       LineEditC1A1->setFocus();
-       myEditCurrentArgument = LineEditC1A1;
+        LineEditC1A1->setFocus();
+        myEditCurrentArgument = LineEditC1A1;
       }
       SelectionIntoArgument();
       break;
@@ -507,6 +499,12 @@ void SMESHGUI_RemoveElementsDlg::keyPressEvent( QKeyEvent* e )
 //=================================================================================
 void SMESHGUI_RemoveElementsDlg::setFilters()
 {
+  if(myMesh->_is_nil()) {
+    SUIT_MessageBox::critical(this,
+                              tr("SMESH_ERROR"),
+                              tr("NO_MESH_SELECTED"));
+   return;
+  }
   if ( !myFilterDlg )
     myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL );
 
@@ -516,3 +514,13 @@ void SMESHGUI_RemoveElementsDlg::setFilters()
 
   myFilterDlg->show();
 }
+
+//=================================================================================
+// function : updateButtons
+// purpose  : enable / disable control buttons
+//=================================================================================
+void SMESHGUI_RemoveElementsDlg::updateButtons()
+{
+  buttonOk->setEnabled(myNbOkElements > 0);
+  buttonApply->setEnabled(myNbOkElements > 0);
+}
index 7138acfe5f92abed2fe5807ab2ff1b654806ede7..6cc8d5ae44faefa329dd984129d864a65b838894 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_RemoveElementsDlg.h
 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
@@ -106,6 +107,7 @@ private slots:
   void                   ActivateThisDialog();
   void                   onTextChange( const QString& );
   void                   setFilters();
+  void                   updateButtons();
 };
 
 #endif // SMESHGUI_REMOVEELEMENTSDLG_H
index bf218290a568b8f9cf54e86168be337e03469c2b..303aee6f6935fa5fd6e2111f7e621e5c31ef0203 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_RemoveNodesDlg.cxx
 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
@@ -122,6 +123,7 @@ SMESHGUI_RemoveNodesDlg
   SelectButtonC1A1->setIcon(image1);
   LineEditC1A1 = new QLineEdit(GroupC1);
   LineEditC1A1->setValidator(new SMESHGUI_IdValidator(this));
+  LineEditC1A1->setMaxLength(-1);
   QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupC1 );
   connect(filterBtn,   SIGNAL(clicked()), this, SLOT(setFilters()));
 
@@ -204,7 +206,7 @@ void SMESHGUI_RemoveNodesDlg::Init()
   /* to close dialog if study change */
   connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(ClickOnCancel()));
   connect(myEditCurrentArgument, SIGNAL(textChanged(const QString&)),
-         SLOT(onTextChange(const QString&)));
+          SLOT(onTextChange(const QString&)));
   
   SMESH::SetPointRepresentation(true);
   
@@ -233,7 +235,7 @@ void SMESHGUI_RemoveNodesDlg::ClickOnApply()
     bool aResult = false;
     try {
       SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
-      aResult = aMeshEditor->RemoveNodes(anArrayOfIdeces.inout());
+      aResult = aMeshEditor->RemoveNodes(anArrayOfIdeces.in());
     } catch (const SALOME::SALOME_Exception& S_ex) {
       SalomeApp_Tools::QtCatchCorbaException(S_ex);
       myEditCurrentArgument->clear();
@@ -245,6 +247,7 @@ void SMESHGUI_RemoveNodesDlg::ClickOnApply()
       myEditCurrentArgument->clear();
       mySelector->ClearIndex();
       SMESH::UpdateView();
+      SMESHGUI::Modified();
     }
 
     SMESH::SetPointRepresentation(true);
@@ -297,10 +300,10 @@ void SMESHGUI_RemoveNodesDlg::ClickOnHelp()
     platform = "application";
 #endif
     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser", 
-                                                                platform)).
-                            arg(myHelpFileName));
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser", 
+                                                                 platform)).
+                             arg(myHelpFileName));
   }
 }
 
@@ -315,9 +318,6 @@ void SMESHGUI_RemoveNodesDlg::onTextChange(const QString& theNewText)
 
   myNbOkNodes = 0;
 
-  buttonOk->setEnabled(false);
-  buttonApply->setEnabled(false);
-
   // hilight entered nodes
   if(myActor){
     if(SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh()){
@@ -327,24 +327,20 @@ void SMESHGUI_RemoveNodesDlg::onTextChange(const QString& theNewText)
       
       QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
       for (int i = 0; i < aListId.count(); i++) {
-       if (const SMDS_MeshNode *aNode = aMesh->FindNode(aListId[i].toInt())) {
-         newIndices.Add(aNode->GetID());
-         myNbOkNodes++;
-       }
+        if (const SMDS_MeshNode *aNode = aMesh->FindNode(aListId[i].toInt())) {
+          newIndices.Add(aNode->GetID());
+          myNbOkNodes++;
+        }
       }
 
       mySelector->AddOrRemoveIndex(anIO,newIndices,false);
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-       aViewWindow->highlight(anIO,true,true);
+        aViewWindow->highlight(anIO,true,true);
     }
   }
 
-  if (myNbOkNodes) {
-    buttonOk->setEnabled(true);
-    buttonApply->setEnabled(true);
-  }
-
   myBusy = false;
+  updateButtons();
 }
 
 //=================================================================================
@@ -353,56 +349,51 @@ void SMESHGUI_RemoveNodesDlg::onTextChange(const QString& theNewText)
 //=================================================================================
 void SMESHGUI_RemoveNodesDlg::SelectionIntoArgument()
 {
-  if (myBusy) return;
-
+  if (myBusy) return;                                  // busy
+  if (myFilterDlg && myFilterDlg->isVisible()) return; // filter dlg active
+  if (!GroupButtons->isEnabled()) return;              // inactive
+    
   // clear
 
-  myNbOkNodes = false;
+  myNbOkNodes = 0;
   myActor = 0;
 
   myBusy = true;
   myEditCurrentArgument->setText("");
   myBusy = false;
 
-  if (!GroupButtons->isEnabled()) // inactive
-    return;
-
-  buttonOk->setEnabled(false);
-  buttonApply->setEnabled(false);
-
   // get selected mesh
   SALOME_ListIO aList;
   mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
 
   int nbSel = aList.Extent();
-  if (nbSel != 1)
-    return;
-
-  Handle(SALOME_InteractiveObject) anIO = aList.First();
-  myMesh = SMESH::GetMeshByIO(anIO);
-  if (myMesh->_is_nil())
-    return;
-
-  myActor = SMESH::FindActorByEntry(anIO->getEntry());
-  if (!myActor)
-    return;
-
-  // get selected nodes
-
-  QString aString = "";
-  int nbNodes = SMESH::GetNameOfSelectedNodes(mySelector,anIO,aString);
-  if(nbNodes < 1)
-    return;
-  myBusy = true;
-  myEditCurrentArgument->setText(aString);
-  myBusy = false;
-
-  // OK
-
-  myNbOkNodes = true;
-
-  buttonOk->setEnabled(true);
-  buttonApply->setEnabled(true);
+  if (nbSel == 1) {
+
+    Handle(SALOME_InteractiveObject) anIO = aList.First();
+    myMesh = SMESH::GetMeshByIO(anIO);
+
+    if (!myMesh->_is_nil()) {
+
+      myActor = SMESH::FindActorByEntry(anIO->getEntry());
+      if (myActor) {
+
+        // get selected nodes
+        QString aString = "";
+        int nbNodes = SMESH::GetNameOfSelectedNodes(mySelector,anIO,aString);
+        if (nbNodes > 0) {
+          myBusy = true;
+          myEditCurrentArgument->setText(aString);
+          myBusy = false;
+          
+          // OK
+          
+          myNbOkNodes = nbNodes;
+        } // if (nbNodes > 0)
+      } // if (myActor)
+    } // if (!myMesh->_is_nil())
+  } // if (nbSel == 1)
+
+  updateButtons();        
 }
 
 //=================================================================================
@@ -416,8 +407,8 @@ void SMESHGUI_RemoveNodesDlg::SetEditCurrentArgument()
   case 0: /* default constructor */
     {
       if(send == SelectButtonC1A1) {
-       LineEditC1A1->setFocus();
-       myEditCurrentArgument = LineEditC1A1;
+        LineEditC1A1->setFocus();
+        myEditCurrentArgument = LineEditC1A1;
       }
       SelectionIntoArgument();
       break;
@@ -514,6 +505,12 @@ void SMESHGUI_RemoveNodesDlg::keyPressEvent( QKeyEvent* e )
 //=================================================================================
 void SMESHGUI_RemoveNodesDlg::setFilters()
 {
+  if(myMesh->_is_nil()) {
+    SUIT_MessageBox::critical(this,
+                              tr("SMESH_ERROR"),
+                              tr("NO_MESH_SELECTED"));
+   return;
+  }
   if ( !myFilterDlg )
     myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::NODE );
 
@@ -523,3 +520,13 @@ void SMESHGUI_RemoveNodesDlg::setFilters()
 
   myFilterDlg->show();
 }
+
+//=================================================================================
+// function : updateButtons
+// purpose  : enable / disable control buttons
+//=================================================================================
+void SMESHGUI_RemoveNodesDlg::updateButtons()
+{
+  buttonOk->setEnabled(myNbOkNodes > 0);
+  buttonApply->setEnabled(myNbOkNodes > 0);
+}
index e26e963d3eab64f7031dd28054532da1d6427391..75a7afed3df6da7515543b9e3c68732a8a39f418 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_RemoveNodesDlg.h
 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
@@ -106,6 +107,7 @@ private slots:
   void                   ActivateThisDialog();
   void                   onTextChange( const QString& );
   void                   setFilters();
+  void                   updateButtons();
 };
 
 #endif // SMESHGUI_REMOVENODESDLG_H
index 26a2614ac5d8db345584b2455a3c4ddee7c92750..278fe0b9694ead3ea379873735bc6021e2b657b1 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_RenumberingDlg.cxx
 // Author : Michael ZORIN, Open CASCADE S.A.S.
@@ -78,14 +79,14 @@ SMESHGUI_RenumberingDlg::SMESHGUI_RenumberingDlg( SMESHGUI* theModule, const int
   setModal(false);
   setAttribute(Qt::WA_DeleteOnClose, true);
   setWindowTitle(unit == 0 ? 
-                tr("SMESH_RENUMBERING_NODES_TITLE") : 
-                tr("SMESH_RENUMBERING_ELEMENTS_TITLE"));
+                 tr("SMESH_RENUMBERING_NODES_TITLE") : 
+                 tr("SMESH_RENUMBERING_ELEMENTS_TITLE"));
   setSizeGripEnabled(true);
 
   SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( mySMESHGUI );
   QPixmap image0(resMgr->loadPixmap("SMESH", unit == 0 ? 
-                                   tr("ICON_DLG_RENUMBERING_NODES") : 
-                                   tr("ICON_DLG_RENUMBERING_ELEMENTS")));
+                                    tr("ICON_DLG_RENUMBERING_NODES") : 
+                                    tr("ICON_DLG_RENUMBERING_ELEMENTS")));
   QPixmap image1(resMgr->loadPixmap("SMESH",tr("ICON_SELECT")));
 
   QVBoxLayout* SMESHGUI_RenumberingDlgLayout = new QVBoxLayout(this);
@@ -94,9 +95,9 @@ SMESHGUI_RenumberingDlg::SMESHGUI_RenumberingDlg( SMESHGUI* theModule, const int
 
   /***************************************************************/
   GroupConstructors = new QGroupBox(unit == 0 ? 
-                                   tr("SMESH_NODES") :
-                                   tr("SMESH_ELEMENTS"), 
-                                   this);
+                                    tr("SMESH_NODES") :
+                                    tr("SMESH_ELEMENTS"), 
+                                    this);
   myHelpFileName = unit == 0 ? 
     "renumbering_nodes_and_elements_page.html#renumbering_nodes_anchor" :
     "renumbering_nodes_and_elements_page.html#renumbering_elements_anchor";
@@ -219,22 +220,22 @@ void SMESHGUI_RenumberingDlg::ClickOnApply()
       bool isUnitsLabeled = false;
       
       if (myUnit == 0 && anActor) {
-       isUnitsLabeled = anActor->GetPointsLabeled();
-       if (isUnitsLabeled)  anActor->SetPointsLabeled(false);
+        isUnitsLabeled = anActor->GetPointsLabeled();
+        if (isUnitsLabeled)  anActor->SetPointsLabeled(false);
       }
       else if (myUnit == 1 && anActor) {
-       isUnitsLabeled = anActor->GetCellsLabeled();
-       if (isUnitsLabeled)  anActor->SetCellsLabeled(false);
+        isUnitsLabeled = anActor->GetCellsLabeled();
+        if (isUnitsLabeled)  anActor->SetCellsLabeled(false);
       }
       
       SUIT_OverrideCursor aWaitCursor;
       if (myUnit == 0) {
-       aMeshEditor->RenumberNodes();
-       if (isUnitsLabeled && anActor) anActor->SetPointsLabeled(true);
+        aMeshEditor->RenumberNodes();
+        if (isUnitsLabeled && anActor) anActor->SetPointsLabeled(true);
       }
       else if (myUnit == 1) {
-       aMeshEditor->RenumberElements();
-       if (isUnitsLabeled && anActor) anActor->SetCellsLabeled(true);
+        aMeshEditor->RenumberElements();
+        if (isUnitsLabeled && anActor) anActor->SetCellsLabeled(true);
       }
     }
     catch(...) {
@@ -242,6 +243,7 @@ void SMESHGUI_RenumberingDlg::ClickOnApply()
     
     //mySelectionMgr->clearSelected();
     SMESH::UpdateView();
+    SMESHGUI::Modified();
   }
 }
 
@@ -285,10 +287,10 @@ void SMESHGUI_RenumberingDlg::ClickOnHelp()
     platform = "application";
 #endif
     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser", 
-                                                                platform)).
-                            arg(myHelpFileName));
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser", 
+                                                                 platform)).
+                             arg(myHelpFileName));
   }
 }
 
@@ -316,7 +318,7 @@ void SMESHGUI_RenumberingDlg::SelectionIntoArgument()
       Handle(SALOME_InteractiveObject) IO = aList.First();
       myMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IO);
       if (myMesh->_is_nil())
-       aString = "";
+        aString = "";
     }
   }
 
@@ -338,12 +340,12 @@ void SMESHGUI_RenumberingDlg::SetEditCurrentArgument()
     {
     case 0: /* default constructor */
       {
-       if(send == SelectButton) {
-         LineEditMesh->setFocus();
-         myEditCurrentArgument = LineEditMesh;
-       }
-       SelectionIntoArgument();
-       break;
+        if(send == SelectButton) {
+          LineEditMesh->setFocus();
+          myEditCurrentArgument = LineEditMesh;
+        }
+        SelectionIntoArgument();
+        break;
       }
     }
 }
index 95c9d46882c30a68672a809e9e36c75fdd235c6a..5ebbe6ca3bb9250d97386a351d66926349ce5c43 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_RenumberingDlg.h
 // Author : Michael ZORIN, Open CASCADE S.A.S.
diff --git a/src/SMESHGUI/SMESHGUI_ReorientFacesDlg.cxx b/src/SMESHGUI/SMESHGUI_ReorientFacesDlg.cxx
new file mode 100644 (file)
index 0000000..cc5db9f
--- /dev/null
@@ -0,0 +1,852 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+// File   : SMESHGUI_ReorientFacesDlg.cxx
+// Author : Edward AGAPOV, Open CASCADE S.A.S.
+// SMESH includes
+//
+#include "SMESHGUI_ReorientFacesDlg.h"
+
+#include "SMESHGUI.h"
+#include "SMESHGUI_IdValidator.h"
+#include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI_VTKUtils.h"
+#include "SMESHGUI_SpinBox.h"
+#include "SMESHGUI_MeshEditPreview.h"
+
+#include <SMDS_Mesh.hxx>
+#include <SMESH_Actor.h>
+#include <SMESH_ActorUtils.h>
+#include <SMESH_NumberFilter.hxx>
+#include <SMESH_LogicalFilter.hxx>
+#include <SMESH_TypeFilter.hxx>
+
+// SALOME GEOM includes
+#include <GEOMBase.h>
+
+// SALOME GUI includes
+#include <LightApp_SelectionMgr.h>
+#include <SALOME_ListIO.hxx>
+#include <SALOME_ListIteratorOfListIO.hxx>
+#include <SUIT_Desktop.h>
+#include <SUIT_MessageBox.h>
+#include <SUIT_OverrideCursor.h>
+#include <SUIT_ResourceMgr.h>
+#include <SVTK_ViewModel.h>
+#include <SVTK_ViewWindow.h>
+#include <SalomeApp_Tools.h>
+#include <SalomeApp_TypeFilter.h>
+
+// SALOME KERNEL includes
+#include <SALOMEDS_SObject.hxx>
+
+// OCCT includes
+#include <BRep_Tool.hxx>
+#include <TColStd_MapOfInteger.hxx>
+#include <TColgp_SequenceOfXYZ.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <gp_Pnt.hxx>
+
+// Qt includes
+#include <QGroupBox>
+#include <QGridLayout>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QLineEdit>
+#include <QPushButton>
+#include <QLabel>
+#include <QRadioButton>
+#include <QCheckBox>
+#include <QButtonGroup>
+
+// VTK includes
+#include <vtkProperty.h>
+
+// IDL includes
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
+// std
+#include <limits>
+
+#define SPACING 6
+#define MARGIN  11
+
+enum { CONSTRUCTOR_POINT=0, CONSTRUCTOR_FACE,
+       EObject, EPoint, EFace, EDirection };
+
+//=======================================================================
+/*!
+ * \brief Dialog to reorient faces acoording to vector
+ */
+//=======================================================================
+
+SMESHGUI_ReorientFacesDlg::SMESHGUI_ReorientFacesDlg()
+  : SMESHGUI_Dialog( 0, false, true )
+{
+  setWindowTitle(tr("CAPTION"));
+
+  QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame());
+  aDlgLay->setMargin(0);
+  aDlgLay->setSpacing(SPACING);
+
+  QWidget* aMainFrame = createMainFrame  (mainFrame());
+
+  aDlgLay->addWidget(aMainFrame);
+
+  aDlgLay->setStretchFactor(aMainFrame, 1);
+}
+
+//================================================================================
+/*!
+ * \brief Create frame containing dialog's input fields
+ */
+//================================================================================
+
+QWidget* SMESHGUI_ReorientFacesDlg::createMainFrame (QWidget* theParent)
+{
+  QWidget* aFrame = new QWidget(theParent);
+
+  // constructors
+
+  QPixmap iconReoriPoint (resMgr()->loadPixmap("SMESH", tr("ICON_DLG_REORIENT2D_POINT")));
+  QPixmap iconReoriFace  (resMgr()->loadPixmap("SMESH", tr("ICON_DLG_REORIENT2D_FACE")));
+
+  QGroupBox* aConstructorBox = new QGroupBox(tr("REORIENT_FACES"), aFrame);
+  myConstructorGrp = new QButtonGroup(aConstructorBox);
+  QHBoxLayout* aConstructorGrpLayout = new QHBoxLayout(aConstructorBox);
+  aConstructorGrpLayout->setMargin(MARGIN);
+  aConstructorGrpLayout->setSpacing(SPACING);
+
+  QRadioButton* aPntBut = new QRadioButton(aConstructorBox);
+  aPntBut->setIcon(iconReoriPoint);
+  aPntBut->setChecked(true);
+  aConstructorGrpLayout->addWidget(aPntBut);
+  myConstructorGrp->addButton(aPntBut, CONSTRUCTOR_POINT);
+
+  QRadioButton* aFaceBut= new QRadioButton(aConstructorBox);
+  aFaceBut->setIcon(iconReoriFace);
+  aConstructorGrpLayout->addWidget(aFaceBut);
+  myConstructorGrp->addButton(aFaceBut, CONSTRUCTOR_FACE);
+
+  // Create other controls
+
+  setObjectPixmap( "SMESH", tr( "ICON_SELECT" ) );
+
+  createObject( tr("OBJECT")   , aFrame, EObject );
+  createObject( tr("POINT")    , aFrame, EPoint );
+  createObject( tr("FACE")     , aFrame, EFace );
+  createObject( tr("DIRECTION"), aFrame, EDirection );
+  setNameIndication( EObject, OneName );
+  setNameIndication( EFace, OneName );
+  setReadOnly( EFace, false );
+  if ( QLineEdit* le = qobject_cast<QLineEdit*>( objectWg( EFace, Control ) ))
+    le->setValidator( new SMESHGUI_IdValidator( this,1 ));
+
+  const int width = aFaceBut->fontMetrics().width( tr("DIRECTION"));
+  objectWg( EDirection, Label )->setFixedWidth( width );
+  objectWg( EObject   , Label )->setFixedWidth( width );
+  objectWg( EPoint    , Label )->setFixedWidth( width );
+  objectWg( EFace     , Label )->setFixedWidth( width );
+
+  QLabel* aXLabel = new QLabel(tr("SMESH_X"), aFrame);
+  myX = new SMESHGUI_SpinBox(aFrame);
+  QLabel* aYLabel = new QLabel(tr("SMESH_Y"), aFrame);
+  myY = new SMESHGUI_SpinBox(aFrame);
+  QLabel* aZLabel = new QLabel(tr("SMESH_Z"), aFrame);
+  myZ = new SMESHGUI_SpinBox(aFrame);
+
+  myX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  myY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  myZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  myX->SetValue(0);
+  myY->SetValue(0);
+  myZ->SetValue(0);
+
+  QLabel* aDXLabel = new QLabel(tr("SMESH_DX"), aFrame);
+  myDX = new SMESHGUI_SpinBox(aFrame);
+  QLabel* aDYLabel = new QLabel(tr("SMESH_DY"), aFrame);
+  myDY = new SMESHGUI_SpinBox(aFrame);
+  QLabel* aDZLabel = new QLabel(tr("SMESH_DZ"), aFrame);
+  myDZ = new SMESHGUI_SpinBox(aFrame);
+  myDX->SetValue(1);
+  myDY->SetValue(0);
+  myDZ->SetValue(0);
+
+  myDX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  myDY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  myDZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+
+  // Layouting
+
+  QGroupBox* anObjectGrp = new QGroupBox(tr("FACES"), aFrame);
+  QHBoxLayout* anObjectGrpLayout = new QHBoxLayout(anObjectGrp);
+  anObjectGrpLayout->setMargin(MARGIN);
+  anObjectGrpLayout->setSpacing(SPACING);
+  anObjectGrpLayout->addWidget( objectWg( EObject, Label ));
+  anObjectGrpLayout->addWidget( objectWg( EObject, Btn ));
+  anObjectGrpLayout->addWidget( objectWg( EObject, Control ));
+
+  myPointFrm = new QFrame(aFrame);
+  QHBoxLayout* aPointGrpLayout = new QHBoxLayout(myPointFrm);
+  aPointGrpLayout->setMargin(0);
+  objectWg( EPoint, Control )->hide();
+  aPointGrpLayout->addWidget( objectWg( EPoint, Label ) );
+  aPointGrpLayout->addWidget( objectWg( EPoint, Btn ) );
+  aPointGrpLayout->addWidget( aXLabel );
+  aPointGrpLayout->addWidget( myX     );
+  aPointGrpLayout->addWidget( aYLabel );
+  aPointGrpLayout->addWidget( myY     );
+  aPointGrpLayout->addWidget( aZLabel );
+  aPointGrpLayout->addWidget( myZ     );
+
+  myFaceFrm = new QFrame(aFrame);
+  QHBoxLayout* aFaceGrpLayout = new QHBoxLayout(myFaceFrm);
+  aFaceGrpLayout->setMargin(0);
+  aFaceGrpLayout->addWidget( objectWg( EFace, Label ) );
+  aFaceGrpLayout->addWidget( objectWg( EFace, Btn ) );
+  aFaceGrpLayout->addWidget( objectWg( EFace, Control ) );
+
+  QFrame* aDirectFrm = new QFrame(aFrame);
+  QHBoxLayout* aDirectGrpLayout = new QHBoxLayout(aDirectFrm);
+  aDirectGrpLayout->setMargin(0);
+  objectWg( EDirection, Control )->hide();
+  aDirectGrpLayout->addWidget( objectWg( EDirection, Label ) );
+  aDirectGrpLayout->addWidget( objectWg( EDirection, Btn ) );
+  aDirectGrpLayout->addWidget(aDXLabel );
+  aDirectGrpLayout->addWidget(myDX );
+  aDirectGrpLayout->addWidget(aDYLabel );
+  aDirectGrpLayout->addWidget(myDY );
+  aDirectGrpLayout->addWidget(aDZLabel );
+  aDirectGrpLayout->addWidget(myDZ );
+  
+
+  QGroupBox* anOrientGrp = new QGroupBox(tr("ORIENTATION"), aFrame);
+  QVBoxLayout* anOrientGrpLayout = new QVBoxLayout ( anOrientGrp );
+  anOrientGrpLayout->addWidget(myPointFrm);
+  anOrientGrpLayout->addWidget(myFaceFrm);
+  anOrientGrpLayout->addWidget(aDirectFrm);
+  
+
+  QVBoxLayout* aLay = new QVBoxLayout(aFrame);
+  aLay->addWidget(aConstructorBox);
+  aLay->addWidget(anObjectGrp);
+  aLay->addWidget(anOrientGrp);
+
+  connect( myConstructorGrp, SIGNAL(buttonClicked (int)), this, SLOT(constructorChange(int)));
+
+  return aFrame;
+}
+
+//================================================================================
+/*!
+ * \brief Show point or face
+ */
+//================================================================================
+
+void SMESHGUI_ReorientFacesDlg::constructorChange(int id)
+{
+  if ( id == CONSTRUCTOR_FACE )
+  {
+    myPointFrm->hide();
+    myFaceFrm->show();
+    activateObject( EFace );
+  }
+  else
+  {
+    myFaceFrm->hide();
+    myPointFrm->show();
+    activateObject( EPoint );
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Constructor
+*/
+//================================================================================
+
+SMESHGUI_ReorientFacesOp::SMESHGUI_ReorientFacesOp()
+  :SMESHGUI_SelectionOp( ActorSelection )
+{
+  //myVectorPreview = 0;
+  myHelpFileName = "reorient_faces_page.html";
+
+  myDlg = new SMESHGUI_ReorientFacesDlg;
+  myDlg->constructorChange( CONSTRUCTOR_POINT );
+
+  // connect signals and slots
+  connect( myDlg->objectWg( EFace, LightApp_Dialog::Control ), SIGNAL(textChanged(const QString&)),
+           this, SLOT(onTextChange(const QString&)));
+  // connect(myDlg->myX, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
+  // connect(myDlg->myY, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
+  // connect(myDlg->myZ, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
+  // connect(myDlg->myDX, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
+  // connect(myDlg->myDY, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
+  // connect(myDlg->myDZ, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
+
+}
+
+//=======================================================================
+// function : startOperation()
+// purpose  : Init dialog fields, connect signals and slots, show dialog
+//=======================================================================
+
+void SMESHGUI_ReorientFacesOp::startOperation()
+{
+  myObjectActor = 0;
+
+  // init simulation with a current View
+  //if ( myVectorPreview ) delete myVectorPreview;
+  // myVectorPreview = new SMESHGUI_MeshEditPreview(SMESH::GetViewWindow( getSMESHGUI() ));
+  // vtkProperty* aProp = vtkProperty::New();
+  // aProp->SetRepresentationToWireframe();
+  // aProp->SetColor(250, 0, 250);
+  // aProp->SetPointSize(5);
+  // aProp->SetLineWidth( SMESH::GetFloat("SMESH:element_width",1) + 1);
+  // myVectorPreview->GetActor()->SetProperty(aProp);
+  // aProp->Delete();
+
+  SMESHGUI_SelectionOp::startOperation();
+
+  myDlg->show();
+
+  mySelectionMode = 0;
+  myDlg->activateObject( EObject );
+}
+
+//================================================================================
+/*!
+ * \brief Stops operation
+ */
+//================================================================================
+
+void SMESHGUI_ReorientFacesOp::stopOperation()
+{
+  //myVectorPreview->SetVisibility(false);
+  if ( myObjectActor ) {
+    myObjectActor->SetPointRepresentation(false);
+    SMESH::RepaintCurrentView();
+    myObjectActor = 0;
+  }
+  SMESHGUI_SelectionOp::stopOperation();
+  myDlg->deactivateAll();
+}
+
+//================================================================================
+/*!
+ * \brief Set selection mode corresponding to a pressed selection button
+ */
+//================================================================================
+
+void SMESHGUI_ReorientFacesOp::onActivateObject( int what )
+{
+  if ( what == mySelectionMode )
+    return;
+  mySelectionMode = what;
+  switch ( mySelectionMode )
+  {
+  case EPoint:
+  case EDirection:
+    SMESH::SetPointRepresentation(true);
+    setSelectionMode( NodeSelection );
+    SMESH::SetPickable();
+    break;
+  case EObject:
+    SMESH::SetPointRepresentation(false);
+    setSelectionMode( ActorSelection );
+    break;
+  case EFace:
+    SMESH::SetPointRepresentation(false);
+    setSelectionMode( FaceSelection );
+    if ( myObjectActor )
+      SMESH::SetPickable( myObjectActor );
+    else
+      SMESH::SetPickable();
+    break;
+  }
+  SMESHGUI_SelectionOp::onActivateObject( what );
+}
+
+//================================================================================
+/*!
+ * \brief Creates a filter corresponding to a pressed selection button
+ */
+//================================================================================
+
+SUIT_SelectionFilter* SMESHGUI_ReorientFacesOp::createFilter( const int what ) const
+{
+  switch ( what )
+  {
+  case EObject:
+    {
+      QList<SUIT_SelectionFilter*> filters;
+      filters.append( new SMESH_TypeFilter( MESH ));
+      filters.append( new SMESH_TypeFilter( SUBMESH_FACE ));
+      filters.append( new SMESH_TypeFilter( GROUP_FACE ));
+      return new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR );
+    }
+  case EPoint:
+    {
+      QList<SUIT_SelectionFilter*> filters;
+      filters.append( new SMESH_TypeFilter( IDSOURCE ));
+      filters.append( new SMESH_NumberFilter( "GEOM",TopAbs_VERTEX, 1, TopAbs_VERTEX ));
+      return new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR );
+    }
+  case EFace:
+  case EDirection:
+    {
+      return new SMESH_TypeFilter( IDSOURCE );
+    }
+  }
+  return NULL;
+}
+
+//================================================================================
+/*!
+ * \brief get data from selection
+ */
+//================================================================================
+
+void SMESHGUI_ReorientFacesOp::selectionDone()
+{
+  if ( !myDlg->isVisible() || !myDlg->isEnabled() )
+    return;
+
+  myDlg->clearSelection( mySelectionMode );
+
+  SALOME_ListIO aList;
+  selectionMgr()->selectedObjects(aList);
+  const int nbSelected = aList.Extent();
+  if ( nbSelected == 0 )
+    return;
+
+  Handle(SALOME_InteractiveObject) anIO = aList.First();
+
+  try
+  {
+    switch ( mySelectionMode )
+    {
+    case EObject: { // get an actor of object
+
+      if ( nbSelected == 1 )
+      {
+        myDlg->selectObject( EObject, anIO->getName(), 0, anIO->getEntry(), true );
+        // typeById( aList.First()->getEntry(),
+        //           SMESHGUI_SelectionOp::Object ),
+        myObjectActor = SMESH::FindActorByEntry( anIO->getEntry() );
+      }
+      break;
+    }
+    case EFace: {  // get a face ID
+
+      if ( nbSelected == 1 )
+      {
+        TColStd_IndexedMapOfInteger faceIndices;
+        selector()->GetIndex( anIO, faceIndices );
+        if ( faceIndices.Extent() == 1 )
+        {
+          SMESH_Actor* savedActor = myObjectActor;
+          myObjectActor = 0; // to prevent work of onTextChange()
+          myDlg->setObjectText( EFace, QString("%1").arg( faceIndices(1) ));
+          myObjectActor = savedActor;
+
+          if ( !myObjectActor )
+          {
+            myDlg->selectObject( EObject, anIO->getName(), 0, anIO->getEntry(), true );
+            // typeById( aList.First()->getEntry(),
+            //           SMESHGUI_SelectionOp::Object ),
+            myObjectActor = SMESH::FindActorByEntry( anIO->getEntry() );
+          }
+        }
+      }
+      break;
+    }
+    case EPoint:
+    case EDirection: {  // set XYZ by selected nodes or vertices
+
+      if ( mySelectionMode == EPoint && aList.Extent() > 1 )
+        return;
+
+      TColgp_SequenceOfXYZ points;
+      for( SALOME_ListIteratorOfListIO anIt( aList ); anIt.More(); anIt.Next() )
+      {
+        anIO = anIt.Value();
+        GEOM::GEOM_Object_var geom = SMESH::IObjectToInterface<GEOM::GEOM_Object>(anIO);
+        if ( !geom->_is_nil() ) {
+          TopoDS_Vertex aShape;
+          if ( GEOMBase::GetShape(geom, aShape) && aShape.ShapeType() == TopAbs_VERTEX ) {
+            gp_Pnt P = BRep_Tool::Pnt(aShape);
+            points.Append( P.XYZ() );
+          }
+        }
+        else
+        {
+          TColStd_IndexedMapOfInteger nodeIndices;
+          selector()->GetIndex( anIO, nodeIndices );
+          if ( nodeIndices.Extent() > 0 && nodeIndices.Extent() <=2 )
+          {
+            if ( SMESH_Actor* aMeshActor = SMESH::FindActorByEntry(anIO->getEntry()))
+              if (SMDS_Mesh* aMesh = aMeshActor->GetObject()->GetMesh())
+              {
+                if (const SMDS_MeshNode* aNode = aMesh->FindNode( nodeIndices(1)))
+                  points.Append( gp_XYZ( aNode->X(), aNode->Y(), aNode->Z()));
+                if ( nodeIndices.Extent() == 2 )
+                  if (const SMDS_MeshNode* aNode = aMesh->FindNode( nodeIndices(2)))
+                    points.Append( gp_XYZ( aNode->X(), aNode->Y(), aNode->Z()));
+              }
+          }
+        }
+      }
+      gp_XYZ xyz;
+      if ( points.Length() == 1 )
+        xyz = points(1);
+      else if ( points.Length() == 2 )
+        xyz = points(2) - points(1);
+      else
+        return;
+      if ( points.Length() == 1 && mySelectionMode == EPoint )
+      {
+        myDlg->myX->SetValue( xyz.X() );
+        myDlg->myY->SetValue( xyz.Y() );
+        myDlg->myZ->SetValue( xyz.Z() );
+        redisplayPreview();
+      }
+      if ( mySelectionMode == EDirection )
+      {
+        myDlg->myDX->SetValue( xyz.X() );
+        myDlg->myDY->SetValue( xyz.Y() );
+        myDlg->myDZ->SetValue( xyz.Z() );
+        redisplayPreview();
+      }
+      break;
+    } // case EPoint || EDirection
+    } // switch
+  }
+  catch (...)
+  {
+  }
+}
+
+//================================================================================
+/*!
+ * \brief SLOT called when the face id is changed
+ */
+//================================================================================
+
+void SMESHGUI_ReorientFacesOp::onTextChange( const QString& theText )
+{
+  if( myObjectActor )
+  {
+    sender()->blockSignals( true );
+    if ( mySelectionMode != EFace )
+    {
+      myDlg->activateObject( EFace );
+      myDlg->setObjectText( EFace, theText );
+    }
+    TColStd_MapOfInteger ids;
+    if ( !theText.isEmpty() && theText.toInt() > 0 )
+      ids.Add( theText.toInt() );
+
+    SMESHGUI_SelectionOp::addOrRemoveIndex( myObjectActor->getIO(), ids, false );
+    SMESHGUI_SelectionOp::highlight( myObjectActor->getIO(), true, true );
+    sender()->blockSignals( false );
+  }
+}
+
+//================================================================================
+/*!
+ * \brief perform it's intention action: reorient faces of myObject
+ */
+//================================================================================
+
+bool SMESHGUI_ReorientFacesOp::onApply()
+{
+  if( isStudyLocked() )
+    return false;
+
+  QString msg;
+  if ( !isValid( msg ) ) { // node id is invalid
+    if( !msg.isEmpty() )
+      SUIT_MessageBox::warning( dlg(), tr( "SMESH_WRN_WARNING" ), msg );
+    dlg()->show();
+    return false;
+  }
+
+  QStringList aParameters;
+  aParameters << myDlg->myDX->text();
+  aParameters << myDlg->myDY->text();
+  aParameters << myDlg->myDZ->text();
+  aParameters << myDlg->myX->text();
+  aParameters << myDlg->myY->text();
+  aParameters << myDlg->myZ->text();
+
+  try {
+    SUIT_OverrideCursor wc;
+    SMESH::SMESH_Mesh_var aMesh = myObject->GetMesh();
+    if ( aMesh->_is_nil() ) return false;
+
+    SMESH::DirStruct direction;
+    direction.PS.x = myDlg->myDX->GetValue();
+    direction.PS.y = myDlg->myDY->GetValue();
+    direction.PS.z = myDlg->myDZ->GetValue();
+
+    long face = myDlg->objectText( EFace ).toInt();
+    if ( myDlg->myConstructorGrp->checkedId() == CONSTRUCTOR_POINT )
+      face = -1;
+
+    SMESH::PointStruct point;
+    point.x = myDlg->myX->GetValue();
+    point.y = myDlg->myY->GetValue();
+    point.z = myDlg->myZ->GetValue();
+
+    SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
+    if (aMeshEditor->_is_nil()) return false;
+
+    aMesh->SetParameters( aParameters.join(":").toLatin1().constData() );
+
+    int aResult = aMeshEditor->Reorient2D( myObject, direction, face, point );
+    if (aResult)
+    {
+      SALOME_ListIO aList;
+      selectionMgr()->setSelectedObjects(aList,false);
+      SMESH::UpdateView();
+      SMESHGUI::Modified();
+    }
+    wc.suspend();
+    SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INFORMATION"),
+                                 tr("NB_REORIENTED").arg(aResult));
+  }
+  catch (const SALOME::SALOME_Exception& S_ex) {
+    SalomeApp_Tools::QtCatchCorbaException(S_ex);
+  }
+  catch (...) {
+  }
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Check data validity
+ */
+//================================================================================
+
+bool SMESHGUI_ReorientFacesOp::isValid( QString& msg )
+{
+  // check object
+  QString objectEntry = myDlg->selectedObject( EObject );
+  _PTR(SObject) pSObject = studyDS()->FindObjectID( objectEntry.toLatin1().data() );
+  myObject = SMESH::SMESH_IDSource::_narrow( _CAST( SObject,pSObject )->GetObject() );
+  if ( myObject->_is_nil() )
+  {
+    msg = tr("NO_OBJECT_SELECTED");
+    return false;
+  }
+  bool hasFaces = false;
+  SMESH::array_of_ElementType_var types = myObject->GetTypes();
+  for ( size_t i = 0; i < types->length() && !hasFaces; ++i )
+    hasFaces = ( types[i] == SMESH::FACE );
+  if ( !hasFaces )
+  {
+    msg = tr("NO_FACES");
+    return false;
+  }
+
+  // check vector
+  gp_Vec vec( myDlg->myDX->GetValue(),
+              myDlg->myDY->GetValue(),
+              myDlg->myDZ->GetValue() );
+  if ( vec.Magnitude() < std::numeric_limits<double>::min() )
+  {
+    msg = tr("ZERO_SIZE_VECTOR");
+    return false;
+  }
+
+  // check face ID
+  if ( myDlg->myConstructorGrp->checkedId() == CONSTRUCTOR_FACE )
+  {
+    int faceID = myDlg->objectText( EFace ).toInt();
+    bool faceOK = ( faceID > 0 );
+    if ( faceOK )
+    {
+      if ( myObjectActor )
+      {
+        faceOK = ( myObjectActor->GetObject()->GetElemDimension( faceID ) == 2 );
+      }
+      else
+      {
+        SMESH::SMESH_Mesh_var aMesh = myObject->GetMesh();
+        if ( !aMesh->_is_nil() ) 
+          faceOK = ( aMesh->GetElementType( faceID, true ) == SMESH::FACE );
+      }
+    }
+    if ( !faceOK )
+    {
+      msg = tr("INVALID_FACE");
+      return false;
+    }
+  }
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Destructor
+*/
+//================================================================================
+
+SMESHGUI_ReorientFacesOp::~SMESHGUI_ReorientFacesOp()
+{
+  if ( myDlg )        delete myDlg;
+  //if ( myVectorPreview ) delete myVectorPreview;
+}
+
+//================================================================================
+/*!
+ * \brief Gets dialog of this operation
+ * \retval LightApp_Dialog* - pointer to dialog of this operation
+ */
+//================================================================================
+
+LightApp_Dialog* SMESHGUI_ReorientFacesOp::dlg() const
+{
+  return myDlg;
+}
+
+//================================================================================
+/*!
+ * \brief update preview
+ */
+//================================================================================
+
+void SMESHGUI_ReorientFacesOp::redisplayPreview()
+{
+//   SMESH::MeshPreviewStruct_var aMeshPreviewStruct;
+
+//   bool moveShown = false;
+//   if ( myObjectActor)
+//   {
+//     const bool autoSearch = myDlg->myAutoSearchChkBox->isChecked();
+//     const bool preview    = myDlg->myPreviewChkBox->isChecked();
+//     if ( autoSearch )
+//     {
+//       myDlg->myCurrentX->SetValue(0);
+//       myDlg->myCurrentY->SetValue(0);
+//       myDlg->myCurrentZ->SetValue(0);
+//       myDlg->myDX->SetValue(0);
+//       myDlg->myDY->SetValue(0);
+//       myDlg->myDZ->SetValue(0);
+//       myDlg->myId->setText("");
+//     }
+//     QString msg;
+//     if ( autoSearch || isValid( msg ) )
+//     {
+//       try {
+//         SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(myObjectActor->getIO());
+//         if (!aMesh->_is_nil()) {
+//           SMESH::SMESH_MeshEditor_var aPreviewer = aMesh->GetMeshEditPreviewer();
+//           if (!aPreviewer->_is_nil())
+//           {
+//             SUIT_OverrideCursor aWaitCursor;
+
+//             int anId = 0;
+//             if ( autoSearch )
+//               anId = aPreviewer->FindNodeClosestTo(myDlg->myX->GetValue(),
+//                                                    myDlg->myY->GetValue(),
+//                                                    myDlg->myZ->GetValue());
+//             else
+//               anId = myDlg->myId->text().toInt();
+
+//             // find id and/or just compute preview
+//             aPreviewer->MoveNode(anId,
+//                                  myDlg->myX->GetValue(),
+//                                  myDlg->myY->GetValue(),
+//                                  myDlg->myZ->GetValue());
+//             if ( autoSearch ) { // set found id
+//               QString idTxt("%1");
+//               if ( anId > 0 )
+//                 idTxt = idTxt.arg( anId );
+//               else
+//                 idTxt = "";
+//               myDlg->myId->setText( idTxt );
+//             }
+
+//             SMESH::double_array* aXYZ = aMesh->GetNodeXYZ( anId );
+//             if( aXYZ && aXYZ->length() >= 3 )
+//             {
+//               double x = aXYZ->operator[](0);
+//               double y = aXYZ->operator[](1);
+//               double z = aXYZ->operator[](2);
+//               double dx = myDlg->myX->GetValue() - x;
+//               double dy = myDlg->myY->GetValue() - y;
+//               double dz = myDlg->myZ->GetValue() - z;
+//               myDlg->myCurrentX->SetValue(x);
+//               myDlg->myCurrentY->SetValue(y);
+//               myDlg->myCurrentZ->SetValue(z);
+//               myDlg->myDX->SetValue(dx);
+//               myDlg->myDY->SetValue(dy);
+//               myDlg->myDZ->SetValue(dz);
+//             }
+
+//             if ( preview ) { // fill preview data
+//               aMeshPreviewStruct = aPreviewer->GetPreviewData();
+//               moveShown = ( anId > 0 );
+//             }
+//           }
+//         }
+//       }catch (...) {
+//       }
+//     }
+//   }
+
+//   if ( !moveShown )
+//   {
+//     aMeshPreviewStruct = new SMESH::MeshPreviewStruct();
+
+//     aMeshPreviewStruct->nodesXYZ.length(1);
+//     aMeshPreviewStruct->nodesXYZ[0].x = myDlg->myX->GetValue();
+//     aMeshPreviewStruct->nodesXYZ[0].y = myDlg->myY->GetValue();
+//     aMeshPreviewStruct->nodesXYZ[0].z = myDlg->myZ->GetValue();
+
+//     aMeshPreviewStruct->elementTypes.length(1);
+//     aMeshPreviewStruct->elementTypes[0].SMDS_ElementType = SMESH::NODE;
+//     aMeshPreviewStruct->elementTypes[0].isPoly = false;
+//     aMeshPreviewStruct->elementTypes[0].nbNodesInElement = 1;
+
+//     aMeshPreviewStruct->elementConnectivities.length(1);
+//     aMeshPreviewStruct->elementConnectivities[0] = 0;
+//   }
+
+//   // display data
+//   if ( aMeshPreviewStruct.operator->() )
+//   {
+//     myVectorPreview->SetData(aMeshPreviewStruct._retn());
+//   }
+//   else
+//   {
+//     myVectorPreview->SetVisibility(false);
+//   }
+
+}
diff --git a/src/SMESHGUI/SMESHGUI_ReorientFacesDlg.h b/src/SMESHGUI/SMESHGUI_ReorientFacesDlg.h
new file mode 100644 (file)
index 0000000..aaea783
--- /dev/null
@@ -0,0 +1,118 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+// File   : SMESHGUI_ReorientFacesDlg.h
+// Author : Edward AGAPOV, Open CASCADE S.A.S.
+//
+#ifndef SMESHGUI_ReorientFacesDlg_H
+#define SMESHGUI_ReorientFacesDlg_H
+
+// SMESH includes
+#include "SMESH_SMESHGUI.hxx"
+
+#include "SMESHGUI_Dialog.h"
+#include "SMESHGUI_SelectionOp.h"
+
+class QButtonGroup;
+class QLineEdit;
+class SMESHGUI_SpinBox;
+class SMESHGUI_ReorientFacesDlg;
+
+/*!
+ * \brief Operation to reorient faces acoording to vector
+ */
+class SMESHGUI_EXPORT SMESHGUI_ReorientFacesOp: public SMESHGUI_SelectionOp
+{
+  Q_OBJECT
+
+public:
+  SMESHGUI_ReorientFacesOp();
+  virtual ~SMESHGUI_ReorientFacesOp();
+
+  virtual LightApp_Dialog*       dlg() const;
+
+protected:
+
+  virtual void                   startOperation();
+  virtual void                   stopOperation();
+
+  virtual SUIT_SelectionFilter*  createFilter( const int ) const;
+  virtual void                   selectionDone();
+
+  bool                           isValid( QString& );
+
+protected slots:
+  virtual bool                   onApply();
+
+private slots:
+  virtual void                   onActivateObject( int );
+  void                           redisplayPreview();
+  void                           onTextChange( const QString& );
+
+private:
+  SMESHGUI_ReorientFacesDlg*    myDlg;
+
+  //SMESHGUI_MeshEditPreview*     myVectorPreview;
+  SMESH_Actor*                  myObjectActor;
+  int                           mySelectionMode;
+
+  SMESH::SMESH_IDSource_var     myObject;
+};
+
+/*!
+ * \brief Dialog to reorient faces acoording to vector
+ */
+
+class SMESHGUI_EXPORT SMESHGUI_ReorientFacesDlg : public SMESHGUI_Dialog
+{
+  Q_OBJECT
+
+public:
+  SMESHGUI_ReorientFacesDlg();
+
+public slots:
+  void constructorChange(int id);
+
+private:
+  QWidget*                      createMainFrame( QWidget* );
+  
+  QButtonGroup*                 myConstructorGrp;
+  QFrame*                       myFaceFrm;
+  QFrame*                       myPointFrm;
+  SMESHGUI_SpinBox*             myX;
+  SMESHGUI_SpinBox*             myY;
+  SMESHGUI_SpinBox*             myZ;
+  //QPushButton*                  myIdBtn;
+  //QLineEdit*                    myId;
+  SMESHGUI_SpinBox*             myDX;
+  SMESHGUI_SpinBox*             myDY;
+  SMESHGUI_SpinBox*             myDZ;
+
+  QString                       myHelpFileName;
+
+  friend class SMESHGUI_ReorientFacesOp;
+
+  //private slots:
+  //void                          ButtonToggled( bool );
+};
+
+#endif // SMESHGUI_ReorientFacesDlg_H
index 355e01ec3f5d695d38dabb8b13b1b8325d190a31..2d198bb68353e9c17a704300da46e4c4f53587ce 100644 (file)
@@ -1,29 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_RevolutionDlg.cxx
 // Author : Michael ZORIN, Open CASCADE S.A.S.
 // SMESH includes
-//
+
 #include "SMESHGUI_RevolutionDlg.h"
 
 #include "SMESHGUI.h"
 // purpose  :
 //=================================================================================
 SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule )
-  : QDialog( SMESH::GetDesktop( theModule ) ),
-    mySMESHGUI( theModule ),
+  : SMESHGUI_PreviewDlg( theModule ),
     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
     myVectorDefinition(NONE_SELECT),
     myFilterDlg( 0 ),
-    mySelectedObject(SMESH::SMESH_IDSource::_nil())
+    mySelectedObject(SMESH::SMESH_IDSource::_nil()),
+    myActor(0)
 {
   mySimulation = new SMESHGUI_MeshEditPreview(SMESH::GetViewWindow( mySMESHGUI ));
 
@@ -144,8 +145,9 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule )
 
   LineEditElements  = new QLineEdit(GroupArguments);
   LineEditElements->setValidator(myIdValidator);
-  QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
-  connect(filterBtn,   SIGNAL(clicked()), this, SLOT(setFilters()));
+  LineEditElements->setMaxLength(-1);
+  myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
+  connect(myFilterBtn,   SIGNAL(clicked()), this, SLOT(setFilters()));
 
   // Control for the whole mesh selection
   CheckBoxMesh = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments);
@@ -229,7 +231,7 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule )
   SpinBox_Tolerance = new SMESHGUI_SpinBox(GroupArguments);
 
   // Control for mesh preview
-  CheckBoxPreview = new QCheckBox(tr("PREVIEW"), GroupArguments);
+  myPreviewCheckBox = new QCheckBox(tr("PREVIEW"), GroupArguments);
 
   // CheckBox for groups generation
   MakeGroupsCheck = new QCheckBox(tr("SMESH_MAKE_GROUPS"), GroupArguments);
@@ -238,13 +240,13 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule )
   GroupArgumentsLayout->addWidget(TextLabelElements,    0, 0);
   GroupArgumentsLayout->addWidget(SelectElementsButton, 0, 1);
   GroupArgumentsLayout->addWidget(LineEditElements,     0, 2);
-  GroupArgumentsLayout->addWidget(filterBtn,            0, 3);
+  GroupArgumentsLayout->addWidget(myFilterBtn,          0, 3);
   GroupArgumentsLayout->addWidget(CheckBoxMesh,         1, 0, 1, 4);
   GroupArgumentsLayout->addWidget(GroupAxis,            2, 0, 1, 4);
   GroupArgumentsLayout->addWidget(GroupAngleBox,        3, 0, 1, 4);
   GroupArgumentsLayout->addWidget(TextLabelTolerance,   4, 0, 1, 2);
   GroupArgumentsLayout->addWidget(SpinBox_Tolerance,    4, 2, 1, 2);
-  GroupArgumentsLayout->addWidget(CheckBoxPreview,      5, 0, 1, 4);
+  GroupArgumentsLayout->addWidget(myPreviewCheckBox,    5, 0, 1, 4);
   GroupArgumentsLayout->addWidget(MakeGroupsCheck,      6, 0, 1, 4);
 
   /***************************************************************/
@@ -277,20 +279,20 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule )
   SMESHGUI_RevolutionDlgLayout->addWidget(GroupButtons);
 
   /* Initialisations */
-  SpinBox_X->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
-  SpinBox_Y->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
-  SpinBox_Z->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
-  SpinBox_DX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
-  SpinBox_DY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
-  SpinBox_DZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
+  SpinBox_X->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  SpinBox_Y->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  SpinBox_Z->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  SpinBox_DX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  SpinBox_DY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  SpinBox_DZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
 
   RadioButton3->setChecked(true);
 
-  SpinBox_Angle->RangeStepAndValidator(COORD_MIN, COORD_MAX, 5.0, 3);
+  SpinBox_Angle->RangeStepAndValidator(COORD_MIN, COORD_MAX, 5.0, "angle_precision");
 
   SpinBox_NbSteps->setRange(1, 999999);
 
-  SpinBox_Tolerance->RangeStepAndValidator(0.0, COORD_MAX, 0.00001, 6);
+  SpinBox_Tolerance->RangeStepAndValidator(0.0, COORD_MAX, 0.00001, "len_tol_precision");
 
   RadioButton1->setChecked(true);
 
@@ -349,7 +351,9 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule )
   connect(SpinBox_Angle,     SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
   connect(SpinBox_NbSteps,   SIGNAL(valueChanged(int)),    this, SLOT(toDisplaySimulation()));
   connect(SpinBox_Tolerance, SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
-  connect(CheckBoxPreview,   SIGNAL(toggled(bool)),        this, SLOT(onDisplaySimulation(bool)));
+
+  //To Connect preview check box
+  connectPreviewControl();
 
   connect(SpinBox_Angle, SIGNAL(textChanged(const QString&)), this, SLOT(onAngleTextChange(const QString&)));
 
@@ -383,6 +387,7 @@ void SMESHGUI_RevolutionDlg::Init (bool ResetControls)
   LineEditElements->clear();
   myElementsId = "";
   myNbOkElements = 0;
+  myIDs.clear();
 
   myActor = 0;
   myMesh = SMESH::SMESH_Mesh::_nil();
@@ -401,7 +406,7 @@ void SMESHGUI_RevolutionDlg::Init (bool ResetControls)
 
     CheckBoxMesh->setChecked(false);
     onSelectMesh(false);
-    CheckBoxPreview->setChecked(false);
+    myPreviewCheckBox->setChecked(false);
     onDisplaySimulation(false);
   }
 }
@@ -412,14 +417,13 @@ void SMESHGUI_RevolutionDlg::Init (bool ResetControls)
 //=================================================================================
 void SMESHGUI_RevolutionDlg::ConstructorsClicked (int constructorId)
 {
-  //disconnect(mySelectionMgr, 0, this, 0);
+  disconnect(mySelectionMgr, 0, this, 0);
 
-  SALOME_ListIO io;
+  /*  SALOME_ListIO io;
   mySelectionMgr->selectedObjects( io );
   SALOME_ListIO aList;
-  mySelectionMgr->setSelectedObjects( aList );
-//   LineEditElements->clear();
-  myNbOkElements = 0;
+  mySelectionMgr->setSelectedObjects( aList );*/
+
   buttonApply->setEnabled(false);
   buttonOk->setEnabled(false);
   mySimulation->SetVisibility(false);
@@ -447,8 +451,11 @@ void SMESHGUI_RevolutionDlg::ConstructorsClicked (int constructorId)
 
   if (!CheckBoxMesh->isChecked())
     {
+      LineEditElements->clear();
+      myIDs.clear();
+      myNbOkElements = 0;
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-       aViewWindow->SetSelectionMode(aSelMode);
+        aViewWindow->SetSelectionMode(aSelMode);
     }
 
   myEditCurrentArgument = (QWidget*)LineEditElements;
@@ -457,8 +464,8 @@ void SMESHGUI_RevolutionDlg::ConstructorsClicked (int constructorId)
   if (CheckBoxMesh->isChecked())
     onSelectMesh(true);
 
-  //connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
-  mySelectionMgr->setSelectedObjects( io );
+  connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
+  //  mySelectionMgr->setSelectedObjects( io );
 }
 
 //=================================================================================
@@ -491,7 +498,7 @@ bool SMESHGUI_RevolutionDlg::ClickOnApply()
     anAxis.vy = SpinBox_DY->GetValue();
     anAxis.vz = SpinBox_DZ->GetValue();
 
-    double anAngle = (SpinBox_Angle->GetValue())*PI/180;
+    double anAngle = (SpinBox_Angle->GetValue())*M_PI/180.;
     long aNbSteps = (long)SpinBox_NbSteps->value();
     double aTolerance = SpinBox_Tolerance->GetValue();
 
@@ -513,44 +520,48 @@ bool SMESHGUI_RevolutionDlg::ClickOnApply()
       SUIT_OverrideCursor aWaitCursor;
       SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
       
+      myMesh->SetParameters( aParameters.join(":").toLatin1().constData() );
+
       if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ) {
         if( CheckBoxMesh->isChecked() ) {
-         if( GetConstructorId() == 0 )
-           SMESH::ListOfGroups_var groups = 
-             aMeshEditor->RotationSweepObject1DMakeGroups(mySelectedObject, anAxis,
-                                                          anAngle, aNbSteps, aTolerance);
-         else
-           SMESH::ListOfGroups_var groups = 
-             aMeshEditor->RotationSweepObject2DMakeGroups(mySelectedObject, anAxis,
-                                                          anAngle, aNbSteps, aTolerance);
-       }
-       else
-         SMESH::ListOfGroups_var groups = 
-           aMeshEditor->RotationSweepMakeGroups(anElementsId.inout(), anAxis,
-                                                anAngle, aNbSteps, aTolerance);
+          if( GetConstructorId() == 0 )
+            SMESH::ListOfGroups_var groups = 
+              aMeshEditor->RotationSweepObject1DMakeGroups(mySelectedObject, anAxis,
+                                                           anAngle, aNbSteps, aTolerance);
+          else
+            SMESH::ListOfGroups_var groups = 
+              aMeshEditor->RotationSweepObject2DMakeGroups(mySelectedObject, anAxis,
+                                                           anAngle, aNbSteps, aTolerance);
+        }
+        else
+          SMESH::ListOfGroups_var groups = 
+            aMeshEditor->RotationSweepMakeGroups(anElementsId.inout(), anAxis,
+                                                 anAngle, aNbSteps, aTolerance);
       }
       else {
         if( CheckBoxMesh->isChecked() ) {
-         if( GetConstructorId() == 0 )
-           aMeshEditor->RotationSweepObject1D(mySelectedObject, anAxis, anAngle, aNbSteps, aTolerance);
-         else
-           aMeshEditor->RotationSweepObject2D(mySelectedObject, anAxis, anAngle, aNbSteps, aTolerance);
-       }
-       else
-         aMeshEditor->RotationSweep(anElementsId.inout(), anAxis, anAngle, aNbSteps, aTolerance);
+          if( GetConstructorId() == 0 )
+            aMeshEditor->RotationSweepObject1D(mySelectedObject, anAxis, anAngle, aNbSteps, aTolerance);
+          else
+            aMeshEditor->RotationSweepObject2D(mySelectedObject, anAxis, anAngle, aNbSteps, aTolerance);
+        }
+        else
+          aMeshEditor->RotationSweep(anElementsId.inout(), anAxis, anAngle, aNbSteps, aTolerance);
       }
 
-      myMesh->SetParameters( SMESHGUI::JoinObjectParameters(aParameters) );
     } catch (...) {
     }
 
     SMESH::UpdateView();
+    SMESH::Update(myIO, SMESH::eDisplay);
     if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() )
       mySMESHGUI->updateObjBrowser(true); // new groups may appear
     Init(false);
     ConstructorsClicked(GetConstructorId());
     mySelectedObject = SMESH::SMESH_IDSource::_nil();
     SelectionIntoArgument();
+
+    SMESHGUI::Modified();
   }
 
   return true;
@@ -572,19 +583,14 @@ void SMESHGUI_RevolutionDlg::ClickOnOk()
 //=================================================================================
 void SMESHGUI_RevolutionDlg::ClickOnCancel()
 {
-  disconnect(mySelectionMgr, 0, this, 0);
-  mySelectionMgr->clearFilters();
-  //mySelectionMgr->clearSelected();
-  if (SMESH::GetCurrentVtkView()) {
-    SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters
-    SMESH::SetPointRepresentation(false);
-  }
-  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-    aViewWindow->SetSelectionMode(ActorSelection);
-  mySMESHGUI->ResetState();
   reject();
 }
 
+void SMESHGUI_RevolutionDlg::reject()
+{
+  close();
+}
+
 //=================================================================================
 // function : ClickOnHelp()
 // purpose  :
@@ -602,10 +608,10 @@ void SMESHGUI_RevolutionDlg::ClickOnHelp()
     platform = "application";
 #endif
     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser", 
-                                                                platform)).
-                            arg(myHelpFileName));
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser", 
+                                                                 platform)).
+                             arg(myHelpFileName));
   }
 }
 
@@ -653,15 +659,15 @@ void SMESHGUI_RevolutionDlg::onTextChange (const QString& theNewText)
       QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
       
       for (int i = 0; i < aListId.count(); i++) {
-       const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt());
-       if (e)
-         newIndices.Add(e->GetID());
-       myNbOkElements++;
+        const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt());
+        if (e)
+          newIndices.Add(e->GetID());
+        myNbOkElements++;
       }
 
       mySelector->AddOrRemoveIndex(myActor->getIO(), newIndices, false);
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-       aViewWindow->highlight( myActor->getIO(), true, true );
+        aViewWindow->highlight( myActor->getIO(), true, true );
       
       myElementsId = theNewText;
     }
@@ -685,7 +691,6 @@ void SMESHGUI_RevolutionDlg::SelectionIntoArgument()
   if (myBusy) return;
 
   // clear
-  myActor = 0;
   QString aString = "";
 
   myBusy = true;
@@ -704,24 +709,27 @@ void SMESHGUI_RevolutionDlg::SelectionIntoArgument()
   const SALOME_ListIO& aList = mySelector->StoredIObjects();
 
   int nbSel = aList.Extent();
-  if (nbSel != 1)
+  if (nbSel != 1) 
     return;
 
   Handle(SALOME_InteractiveObject) IO = aList.First();
-  myMesh = SMESH::GetMeshByIO(IO);
-  if (myMesh->_is_nil())
+  SMESH::SMESH_Mesh_var aMeshVar = SMESH::GetMeshByIO(IO);
+  if (aMeshVar->_is_nil())
     return;
 
-  myActor = SMESH::FindActorByObject(myMesh);
-  if (!myActor)
-    myActor = SMESH::FindActorByEntry(IO->getEntry());
-  if (!myActor)
+  SMESH_Actor* anActor = SMESH::FindActorByObject(aMeshVar);
+  if (!anActor)
+    anActor = SMESH::FindActorByEntry(IO->getEntry());
+  if (!anActor && !CheckBoxMesh->isChecked())
     return;
 
   int aNbUnits = 0;
 
   if (myEditCurrentArgument == (QWidget*)LineEditElements) {
     myElementsId = "";
+    myMesh = aMeshVar;
+    myActor = anActor;
+    myIO = IO;
 
     // MakeGroups is available if there are groups
     if ( myMesh->NbGroups() == 0 ) {
@@ -742,12 +750,12 @@ void SMESHGUI_RevolutionDlg::SelectionIntoArgument()
       aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, IO, aString);
       myElementsId = aString;
       if (aNbUnits < 1)
-       return;
+        return;
     }
     myNbOkElements = true;
   } else {
 
-    SMDS_Mesh* aMesh =  myActor->GetObject()->GetMesh();
+    SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh();
     if (!aMesh)
       return;
 
@@ -832,20 +840,20 @@ void SMESHGUI_RevolutionDlg::SetEditCurrentArgument()
     SMESH::SetPointRepresentation(false);
     if (CheckBoxMesh->isChecked()) {
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-       aViewWindow->SetSelectionMode(ActorSelection);
+        aViewWindow->SetSelectionMode(ActorSelection);
       mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter);
     } else {
       int aConstructorId = GetConstructorId();
       if (aConstructorId == 0)
-       {
-         if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-           aViewWindow->SetSelectionMode(EdgeSelection);
-       }
+        {
+          if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+            aViewWindow->SetSelectionMode(EdgeSelection);
+        }
       else if (aConstructorId == 1)
-       {
-         if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-           aViewWindow->SetSelectionMode(FaceSelection);
-       }
+        {
+          if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+            aViewWindow->SetSelectionMode(FaceSelection);
+        }
     }
   } else if (send == SelectPointButton) {
     myEditCurrentArgument = (QWidget*)SpinBox_X;
@@ -909,17 +917,16 @@ void SMESHGUI_RevolutionDlg::enterEvent (QEvent*)
 void SMESHGUI_RevolutionDlg::closeEvent (QCloseEvent*)
 {
   /* same than click on cancel button */
-  ClickOnCancel();
-}
-
-//=======================================================================
-// function : hideEvent()
-// purpose  : caused by ESC key
-//=======================================================================
-void SMESHGUI_RevolutionDlg::hideEvent (QHideEvent*)
-{
-  if (!isMinimized())
-    ClickOnCancel();
+  disconnect(mySelectionMgr, 0, this, 0);
+  mySelectionMgr->clearFilters();
+  //mySelectionMgr->clearSelected();
+  if (SMESH::GetCurrentVtkView()) {
+    SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters
+    SMESH::SetPointRepresentation(false);
+  }
+  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+    aViewWindow->SetSelectionMode(ActorSelection);
+  mySMESHGUI->ResetState();
 }
 
 //=======================================================================
@@ -928,10 +935,13 @@ void SMESHGUI_RevolutionDlg::hideEvent (QHideEvent*)
 //=======================================================================
 void SMESHGUI_RevolutionDlg::onSelectMesh (bool toSelectMesh)
 {
-  if (toSelectMesh)
+  if (toSelectMesh) {
+    myIDs = LineEditElements->text();
     TextLabelElements->setText(tr("SMESH_NAME"));
+  }
   else
     TextLabelElements->setText(tr("SMESH_ID_ELEMENTS"));
+  myFilterBtn->setEnabled(!toSelectMesh);
 
   if (myEditCurrentArgument != LineEditElements) {
     LineEditElements->clear();
@@ -952,13 +962,13 @@ void SMESHGUI_RevolutionDlg::onSelectMesh (bool toSelectMesh)
     int aConstructorId = GetConstructorId();
     if (aConstructorId == 0)
       {
-       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-         aViewWindow->SetSelectionMode(EdgeSelection);
+        if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+          aViewWindow->SetSelectionMode(EdgeSelection);
       }
-    else if (aConstructorId == 0)
+    else if (aConstructorId == 1)
       {
-       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-         aViewWindow->SetSelectionMode(FaceSelection);
+        if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+          aViewWindow->SetSelectionMode(FaceSelection);
       }
 
     LineEditElements->setReadOnly(false);
@@ -968,6 +978,9 @@ void SMESHGUI_RevolutionDlg::onSelectMesh (bool toSelectMesh)
   }
 
   SelectionIntoArgument();
+
+  if (!toSelectMesh)
+    LineEditElements->setText( myIDs );
 }
 
 //=================================================================================
@@ -986,8 +999,8 @@ int SMESHGUI_RevolutionDlg::GetConstructorId()
 bool SMESHGUI_RevolutionDlg::IsAxisOk()
 {
   return (SpinBox_DX->GetValue() != 0 ||
-         SpinBox_DY->GetValue() != 0 ||
-         SpinBox_DZ->GetValue() != 0);
+          SpinBox_DY->GetValue() != 0 ||
+          SpinBox_DZ->GetValue() != 0);
 }
 
 //=================================================================================
@@ -1022,22 +1035,13 @@ void SMESHGUI_RevolutionDlg::keyPressEvent( QKeyEvent* e )
   }
 }
 
-//=================================================================================
-// function : toDisplaySimulation()
-// purpose  :
-//=================================================================================
-void SMESHGUI_RevolutionDlg::toDisplaySimulation()
-{
-  onDisplaySimulation(true);
-}
-
 //=================================================================================
 // function : onDisplaySimulation()
-// purpose  :
+// purpose  : Show/Hide preview
 //=================================================================================
 void SMESHGUI_RevolutionDlg::onDisplaySimulation(bool toDisplayPreview)
 {
-  if (CheckBoxPreview->isChecked() && toDisplayPreview)
+  if (myPreviewCheckBox->isChecked() && toDisplayPreview)
   {
     //display preview
     if (myNbOkElements && IsAxisOk())
@@ -1048,7 +1052,7 @@ void SMESHGUI_RevolutionDlg::onDisplaySimulation(bool toDisplayPreview)
       
       anElementsId->length(aListElementsId.count());
       for (int i = 0; i < aListElementsId.count(); i++)
-       anElementsId[i] = aListElementsId[i].toInt();
+        anElementsId[i] = aListElementsId[i].toInt();
       
       SMESH::AxisStruct anAxis;
       
@@ -1058,33 +1062,33 @@ void SMESHGUI_RevolutionDlg::onDisplaySimulation(bool toDisplayPreview)
       anAxis.vx = SpinBox_DX->GetValue();
       anAxis.vy = SpinBox_DY->GetValue();
       anAxis.vz = SpinBox_DZ->GetValue();
-      
-      double anAngle = (SpinBox_Angle->GetValue())*PI/180;
+
+      double anAngle = (SpinBox_Angle->GetValue())*M_PI/180.;
       long aNbSteps = (long)SpinBox_NbSteps->value();
       double aTolerance = SpinBox_Tolerance->GetValue();
       
       if (GroupAngle->checkedId() == 1)
-       anAngle = anAngle/aNbSteps;
+        anAngle = anAngle/aNbSteps;
       
       try {
-       SUIT_OverrideCursor aWaitCursor;
-       SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditPreviewer();
+        SUIT_OverrideCursor aWaitCursor;
+        SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditPreviewer();
         if( CheckBoxMesh->isChecked() ) {
-         if( GetConstructorId() == 0 )
-           aMeshEditor->RotationSweepObject1D(mySelectedObject, anAxis,
-                                              anAngle, aNbSteps, aTolerance);
-         else
-           aMeshEditor->RotationSweepObject2D(mySelectedObject, anAxis,
-                                              anAngle, aNbSteps, aTolerance);
-       }
-       else
-         aMeshEditor->RotationSweep(anElementsId.inout(), 
-                                    anAxis, 
-                                    anAngle, 
-                                    aNbSteps, 
-                                    aTolerance);
-       SMESH::MeshPreviewStruct_var aMeshPreviewStruct = aMeshEditor->GetPreviewData();
-       mySimulation->SetData(aMeshPreviewStruct._retn());
+          if( GetConstructorId() == 0 )
+            aMeshEditor->RotationSweepObject1D(mySelectedObject, anAxis,
+                                               anAngle, aNbSteps, aTolerance);
+          else
+            aMeshEditor->RotationSweepObject2D(mySelectedObject, anAxis,
+                                               anAngle, aNbSteps, aTolerance);
+        }
+        else
+          aMeshEditor->RotationSweep(anElementsId.inout(), 
+                                     anAxis, 
+                                     anAngle, 
+                                     aNbSteps, 
+                                     aTolerance);
+        SMESH::MeshPreviewStruct_var aMeshPreviewStruct = aMeshEditor->GetPreviewData();
+        mySimulation->SetData(aMeshPreviewStruct._retn());
       } catch (...) {}
     }
     else
@@ -1117,6 +1121,8 @@ void SMESHGUI_RevolutionDlg::onSelectVectorMenu( QAction* action){
   if(!action)
     return;
 
+  disconnect(mySelectionMgr, 0, this, 0);
+
   switch(myMenuActions[action]) {
   case POINT_SELECT: 
     SMESH::SetPointRepresentation(true);
@@ -1144,6 +1150,12 @@ void SMESHGUI_RevolutionDlg::onSelectVectorMenu( QAction* action){
 //=================================================================================
 void SMESHGUI_RevolutionDlg::setFilters()
 {
+  if(myMesh->_is_nil()) {
+    SUIT_MessageBox::critical(this,
+                              tr("SMESH_ERROR"),
+                              tr("NO_MESH_SELECTED"));
+   return;
+  }
   if ( !myFilterDlg )
   {
     QList<int> types;  
index a4c3fc1117d0a357a63948364920b68a9cac2545..91d1e4268f1da83d3997011a60c83e005915b76c 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_RevolutionDlg.h
 // Author : Michael ZORIN, Open CASCADE S.A.S.
 
 // SMESH includes
 #include "SMESH_SMESHGUI.hxx"
+#include "SMESHGUI_PreviewDlg.h"
+
+// SALOME GUI includes
+#include <SALOME_InteractiveObject.hxx>
 
 // Qt includes
-#include <QDialog>
 #include <QMap>
 
 // IDL includes
@@ -62,7 +66,7 @@ class QAction;
 // class    : SMESHGUI_RevolutionDlg
 // purpose  :
 //=================================================================================
-class SMESHGUI_EXPORT SMESHGUI_RevolutionDlg : public QDialog
+class SMESHGUI_EXPORT SMESHGUI_RevolutionDlg : public SMESHGUI_PreviewDlg
 { 
   Q_OBJECT
 
@@ -70,26 +74,27 @@ public:
   SMESHGUI_RevolutionDlg( SMESHGUI* );
   ~SMESHGUI_RevolutionDlg();
 
+  void                      reject();
+
 private:
   enum {NONE_SELECT, POINT_SELECT, FACE_SELECT};
   
   void                      Init( bool = true);
   void                      closeEvent( QCloseEvent* );
   void                      enterEvent( QEvent* );           /* mouse enter the QWidget */
-  void                      hideEvent( QHideEvent* );        /* ESC key */
   void                      keyPressEvent( QKeyEvent* );
   int                       GetConstructorId();
   bool                      IsAxisOk();
   
   bool                      isValid();
   
-  SMESHGUI*                 mySMESHGUI;              /* Current SMESHGUI object */
   SMESHGUI_IdValidator*     myIdValidator;
   LightApp_SelectionMgr*    mySelectionMgr;          /* User shape selection */
   int                       myNbOkElements;          /* to check when elements are defined */
   QString                   myElementsId;
   QWidget*                  myEditCurrentArgument;   /* Current  argument */
   SVTK_Selector*            mySelector;
+  Handle(SALOME_InteractiveObject) myIO;
   
   SMESH::SMESH_IDSource_var mySelectedObject;
 
@@ -120,7 +125,6 @@ private:
   QButtonGroup*             GroupAngle;
   QRadioButton*             RadioButton3;
   QRadioButton*             RadioButton4;
-  QCheckBox*                CheckBoxPreview;
   
   QLabel*                   TextLabelPoint;
   QPushButton*              SelectPointButton;
@@ -152,8 +156,13 @@ private:
 
   
   QString                   myHelpFileName;
+  QString                   myIDs;
   
+  QPushButton*              myFilterBtn;
   SMESHGUI_FilterDlg*       myFilterDlg;
+
+protected slots:
+  virtual void              onDisplaySimulation( bool );
    
 private slots:
   void                      ConstructorsClicked( int );
@@ -169,8 +178,6 @@ private slots:
   void                      onAngleTextChange( const QString& );
   void                      onSelectMesh( bool );
   void                      onVectorChanged();
-  void                      toDisplaySimulation();
-  void                      onDisplaySimulation( bool );
   void                      onSelectVectorMenu( QAction* );
   void                      onSelectVectorButton();
   void                      setFilters();
index 1e701097474a88072cf1b6ff6fd3557cc6077a25..f257c3c87471b0e16345e2fcbc402cf524f75ca2 100644 (file)
@@ -1,29 +1,28 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
-//
-// SMESH SMESHGUI : GUI for SMESH component
-// File   : SMESHGUI_RotationDlg.cxx
-// Author : Michael ZORIN, Open CASCADE S.A.S.
-// SMESH includes
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+//  File   : SMESHGUI_RotationDlg.cxx
+//  Author : Michael ZORIN, Open CASCADE S.A.S.
+//  SMESH includes
+
 #include "SMESHGUI_RotationDlg.h"
 
 #include "SMESHGUI.h"
@@ -33,6 +32,7 @@
 #include "SMESHGUI_MeshUtils.h"
 #include "SMESHGUI_IdValidator.h"
 #include "SMESHGUI_FilterDlg.h"
+#include "SMESHGUI_MeshEditPreview.h"
 
 #include <SMESH_Actor.h>
 #include <SMESH_TypeFilter.hxx>
@@ -83,13 +83,16 @@ enum { MOVE_ELEMS_BUTTON = 0, COPY_ELEMS_BUTTON, MAKE_MESH_BUTTON }; //!< action
 #define SPACING 8
 #define MARGIN  11
 
+//To disable automatic genericobj management, the following line should be commented.
+//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
+#define WITHGENERICOBJ
+
 //=================================================================================
 // class    : SMESHGUI_RotationDlg()
 // purpose  :
 //=================================================================================
-SMESHGUI_RotationDlg::SMESHGUI_RotationDlg( SMESHGUI* theModule )
-  : QDialog( SMESH::GetDesktop( theModule ) ),
-    mySMESHGUI( theModule ),
+SMESHGUI_RotationDlg::SMESHGUI_RotationDlg( SMESHGUI* theModule ) :
+    SMESHGUI_PreviewDlg( theModule ),
     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
     myFilterDlg(0),
     mySelectedObject(SMESH::SMESH_IDSource::_nil())
@@ -133,8 +136,9 @@ SMESHGUI_RotationDlg::SMESHGUI_RotationDlg( SMESHGUI* theModule )
   SelectElementsButton->setIcon(image1);
   LineEditElements = new QLineEdit(GroupArguments);
   LineEditElements->setValidator(myIdValidator);
-  QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
-  connect(filterBtn,   SIGNAL(clicked()), this, SLOT(setFilters()));
+  LineEditElements->setMaxLength(-1);
+  myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
+  connect(myFilterBtn,   SIGNAL(clicked()), this, SLOT(setFilters()));
 
   // Control for the whole mesh selection
   CheckBoxMesh = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments);
@@ -212,10 +216,14 @@ SMESHGUI_RotationDlg::SMESHGUI_RotationDlg( SMESHGUI* theModule )
   // Name of a mesh to create
   LineEditNewMesh = new QLineEdit(GroupArguments);
 
+
+  //Preview check box
+  myPreviewCheckBox = new QCheckBox(tr("PREVIEW"), GroupArguments);
+
   GroupArgumentsLayout->addWidget(TextLabelElements,    0, 0);
   GroupArgumentsLayout->addWidget(SelectElementsButton, 0, 1);
   GroupArgumentsLayout->addWidget(LineEditElements,     0, 2, 1, 1);
-  GroupArgumentsLayout->addWidget(filterBtn,            0, 3);
+  GroupArgumentsLayout->addWidget(myFilterBtn,          0, 3);
   GroupArgumentsLayout->addWidget(CheckBoxMesh,         1, 0, 1, 4);
   GroupArgumentsLayout->addWidget(GroupAxis,            2, 0, 1, 4);
   GroupArgumentsLayout->addWidget(TextLabelAngle,       3, 0, 1, 2);
@@ -223,6 +231,8 @@ SMESHGUI_RotationDlg::SMESHGUI_RotationDlg( SMESHGUI* theModule )
   GroupArgumentsLayout->addWidget(ActionBox,            4, 0, 3, 3);
   GroupArgumentsLayout->addWidget(MakeGroupsCheck,      5, 3);
   GroupArgumentsLayout->addWidget(LineEditNewMesh,      6, 3);
+  GroupArgumentsLayout->addWidget(myPreviewCheckBox,    7, 0);
+
 
   /***************************************************************/
   GroupButtons = new QGroupBox(this);
@@ -254,14 +264,14 @@ SMESHGUI_RotationDlg::SMESHGUI_RotationDlg( SMESHGUI* theModule )
   SMESHGUI_RotationDlgLayout->addWidget(GroupButtons);
 
   /* Initialisations */
-  SpinBox_X->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
-  SpinBox_Y->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
-  SpinBox_Z->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
-  SpinBox_DX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
-  SpinBox_DY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
-  SpinBox_DZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
+  SpinBox_X->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  SpinBox_Y->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  SpinBox_Z->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  SpinBox_DX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  SpinBox_DY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  SpinBox_DZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
 
-  SpinBox_Angle->RangeStepAndValidator(-360.0, +360.0, 5.0, 3);
+  SpinBox_Angle->RangeStepAndValidator(-360.0, +360.0, 5.0, "angle_precision");
 
   myConstructorId = 0;
   RadioButton1->setChecked(true);
@@ -307,6 +317,17 @@ SMESHGUI_RotationDlg::SMESHGUI_RotationDlg( SMESHGUI* theModule )
   connect(CheckBoxMesh,     SIGNAL(toggled(bool)),                  SLOT(onSelectMesh(bool)));
   connect(ActionGroup,      SIGNAL(buttonClicked(int)),             SLOT(onActionClicked(int)));
 
+  connect(SpinBox_X,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(SpinBox_Y,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(SpinBox_Z,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(SpinBox_DX,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(SpinBox_DY,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(SpinBox_DZ,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(SpinBox_Angle,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+
+  //To Connect preview check box
+  connectPreviewControl();
+
   onActionClicked(MOVE_ELEMS_BUTTON);
 }
 
@@ -354,6 +375,9 @@ void SMESHGUI_RotationDlg::Init (bool ResetControls)
 
     ActionGroup->button( MOVE_ELEMS_BUTTON )->setChecked(true);
     CheckBoxMesh->setChecked(false);
+    myPreviewCheckBox->setChecked(false);
+    onDisplaySimulation(false);
+
 //     MakeGroupsCheck->setChecked(false);
 //     MakeGroupsCheck->setEnabled(false);
 //    onSelectMesh(false);
@@ -392,7 +416,7 @@ bool SMESHGUI_RotationDlg::ClickOnApply()
     anAxis.vy = SpinBox_DY->GetValue();
     anAxis.vz = SpinBox_DZ->GetValue();
 
-    double anAngle = (SpinBox_Angle->GetValue())*PI/180;
+    double anAngle = (SpinBox_Angle->GetValue())*M_PI/180.;
 
     QStringList aParameters;
     aParameters << SpinBox_X->text();
@@ -405,17 +429,19 @@ bool SMESHGUI_RotationDlg::ClickOnApply()
 
     int actionButton = ActionGroup->checkedId();
     bool makeGroups = ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() );
+    QStringList anEntryList;
     try {
       SUIT_OverrideCursor aWaitCursor;
       SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
+
+      myMesh->SetParameters(aParameters.join(":").toLatin1().constData());
+
       switch ( actionButton ) {
       case MOVE_ELEMS_BUTTON:
         if(CheckBoxMesh->isChecked())
           aMeshEditor->RotateObject(mySelectedObject, anAxis, anAngle, false);
         else
             aMeshEditor->Rotate(anElementsId, anAxis, anAngle, false);
-       if( !myMesh->_is_nil())
-         myMesh->SetParameters(SMESHGUI::JoinObjectParameters(aParameters));
         break;
       case COPY_ELEMS_BUTTON:
         if ( makeGroups ) {
@@ -428,33 +454,47 @@ bool SMESHGUI_RotationDlg::ClickOnApply()
         else {
           if(CheckBoxMesh->isChecked())
             aMeshEditor->RotateObject(mySelectedObject, anAxis, anAngle, true);
-          else 
+          else
             aMeshEditor->Rotate(anElementsId, anAxis, anAngle, true);
         }
-       if( !myMesh->_is_nil())
-         myMesh->SetParameters(SMESHGUI::JoinObjectParameters(aParameters));
         break;
-      case MAKE_MESH_BUTTON:
+      case MAKE_MESH_BUTTON: {
         SMESH::SMESH_Mesh_var mesh;
-        if(CheckBoxMesh->isChecked())
+        if (CheckBoxMesh->isChecked())
           mesh = aMeshEditor->RotateObjectMakeMesh(mySelectedObject, anAxis, anAngle, makeGroups,
                                                    LineEditNewMesh->text().toLatin1().data());
-        else 
+        else
           mesh = aMeshEditor->RotateMakeMesh(anElementsId, anAxis, anAngle, makeGroups,
                                              LineEditNewMesh->text().toLatin1().data());
-       if( !mesh->_is_nil())
-         mesh->SetParameters(SMESHGUI::JoinObjectParameters(aParameters));
+        if (!mesh->_is_nil()) {
+          if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( mesh ) )
+            anEntryList.append( aSObject->GetID().c_str() );
+#ifdef WITHGENERICOBJ
+          // obj has been published in study. Its refcount has been incremented.
+          // It is safe to decrement its refcount
+          // so that it will be destroyed when the entry in study will be removed
+          mesh->UnRegister();
+#endif
+        }
+        break;
+      }
       }
     } catch (...) {
     }
 
     SMESH::UpdateView();
-    if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ||
-         actionButton == MAKE_MESH_BUTTON )
+    if ( ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ) ||
+         actionButton == MAKE_MESH_BUTTON ) {
       mySMESHGUI->updateObjBrowser(true); // new groups may appear
+      if( LightApp_Application* anApp =
+          dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
+        anApp->browseObjects( anEntryList, isApplyAndClose() );
+    }
     Init(false);
     mySelectedObject = SMESH::SMESH_IDSource::_nil();
     SelectionIntoArgument();
+
+    SMESHGUI::Modified();
   }
 
   return true;
@@ -466,6 +506,7 @@ bool SMESHGUI_RotationDlg::ClickOnApply()
 //=================================================================================
 void SMESHGUI_RotationDlg::ClickOnOk()
 {
+  setIsApplyAndClose( true );
   if( ClickOnApply() )
     ClickOnCancel();
 }
@@ -496,7 +537,7 @@ void SMESHGUI_RotationDlg::ClickOnCancel()
 void SMESHGUI_RotationDlg::ClickOnHelp()
 {
   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
-  if (app) 
+  if (app)
     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
   else {
     QString platform;
@@ -506,10 +547,10 @@ void SMESHGUI_RotationDlg::ClickOnHelp()
     platform = "application";
 #endif
     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser",
-                                                                platform)).
-                            arg(myHelpFileName));
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser",
+                                                                 platform)).
+                             arg(myHelpFileName));
   }
 }
 
@@ -538,21 +579,21 @@ void SMESHGUI_RotationDlg::onTextChange (const QString& theNewText)
   if (aMesh) {
     if (send == LineEditElements) {
       Handle(SALOME_InteractiveObject) anIO = myActor->getIO();
-      
+
       TColStd_MapOfInteger newIndices;
-      
+
       QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
       for (int i = 0; i < aListId.count(); i++) {
-       const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt());
-       if (e)
-         newIndices.Add(e->GetID());
-       myNbOkElements++;
+        const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt());
+        if (e)
+          newIndices.Add(e->GetID());
+        myNbOkElements++;
       }
 
       mySelector->AddOrRemoveIndex( anIO, newIndices, false );
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-       aViewWindow->highlight( anIO, true, true );
-      
+        aViewWindow->highlight( anIO, true, true );
+
       myElementsId = theNewText;
     }
   }
@@ -605,7 +646,7 @@ void SMESHGUI_RotationDlg::SelectionIntoArgument()
   myActor = SMESH::FindActorByObject(myMesh);
   if (!myActor)
     myActor = SMESH::FindActorByEntry(IO->getEntry());
-  if (!myActor)
+  if (!myActor && !CheckBoxMesh->isChecked())
     return;
 
   int aNbUnits = 0;
@@ -645,7 +686,7 @@ void SMESHGUI_RotationDlg::SelectionIntoArgument()
       } else if (!SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(IO)->_is_nil()) { //SUBMESH
       // get submesh
         SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(IO);
-        
+
         // get IDs from submesh
         SMESH::long_array_var anElementsIds = new SMESH::long_array;
         anElementsIds = aSubMesh->GetElementsId();
@@ -711,7 +752,7 @@ void SMESHGUI_RotationDlg::SelectionIntoArgument()
     LineEditElements->setText(aString);
     LineEditElements->repaint();
     LineEditElements->setEnabled(false); // to update lineedit IPAL 19809
-    LineEditElements->setEnabled(true); 
+    LineEditElements->setEnabled(true);
     setNewMeshName();
   }
   myBusy = false;
@@ -721,6 +762,7 @@ void SMESHGUI_RotationDlg::SelectionIntoArgument()
     buttonOk->setEnabled(true);
     buttonApply->setEnabled(true);
   }
+  onDisplaySimulation(true);
 }
 
 //=================================================================================
@@ -743,23 +785,23 @@ void SMESHGUI_RotationDlg::SetEditCurrentArgument()
         myEditCurrentArgument = (QWidget*)LineEditElements;
         SMESH::SetPointRepresentation(false);
         if (CheckBoxMesh->isChecked()) {
-         if ( aViewWindow )
-           aViewWindow->SetSelectionMode(ActorSelection);
+          if ( aViewWindow )
+            aViewWindow->SetSelectionMode(ActorSelection);
           mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter);
         } else {
-         if ( aViewWindow )
-           aViewWindow->SetSelectionMode( CellSelection );
-       }
+          if ( aViewWindow )
+            aViewWindow->SetSelectionMode( CellSelection );
+        }
       } else if (send == SelectPointButton) {
         myEditCurrentArgument = (QWidget*)SpinBox_X;
         SMESH::SetPointRepresentation(true);
-       if ( aViewWindow )
-         aViewWindow->SetSelectionMode( NodeSelection );
+        if ( aViewWindow )
+          aViewWindow->SetSelectionMode( NodeSelection );
       } else if (send == SelectVectorButton) {
         myEditCurrentArgument = (QWidget*)SpinBox_DX;
         SMESH::SetPointRepresentation(true);
-       if ( aViewWindow )
-         aViewWindow->SetSelectionMode( NodeSelection );
+        if ( aViewWindow )
+          aViewWindow->SetSelectionMode( NodeSelection );
       }
       break;
     }
@@ -845,6 +887,7 @@ void SMESHGUI_RotationDlg::onSelectMesh (bool toSelectMesh)
     TextLabelElements->setText(tr("SMESH_NAME"));
   else
     TextLabelElements->setText(tr("SMESH_ID_ELEMENTS"));
+  myFilterBtn->setEnabled(!toSelectMesh);
 
   if (myEditCurrentArgument != LineEditElements) {
     LineEditElements->clear();
@@ -866,6 +909,7 @@ void SMESHGUI_RotationDlg::onSelectMesh (bool toSelectMesh)
     LineEditElements->setReadOnly(false);
     LineEditElements->setValidator(myIdValidator);
     onTextChange(LineEditElements->text());
+    hidePreview();
   }
 
   SelectionIntoArgument();
@@ -878,8 +922,8 @@ void SMESHGUI_RotationDlg::onSelectMesh (bool toSelectMesh)
 bool SMESHGUI_RotationDlg::IsAxisOk()
 {
   return (SpinBox_DX->GetValue() != 0 ||
-         SpinBox_DY->GetValue() != 0 ||
-         SpinBox_DZ->GetValue() != 0);
+          SpinBox_DY->GetValue() != 0 ||
+          SpinBox_DZ->GetValue() != 0);
 }
 
 //=================================================================================
@@ -928,6 +972,7 @@ void SMESHGUI_RotationDlg::onActionClicked(int button)
     break;
   }
   setNewMeshName();
+  toDisplaySimulation();
 }
 
 //=======================================================================
@@ -974,6 +1019,12 @@ void SMESHGUI_RotationDlg::keyPressEvent( QKeyEvent* e )
 //=================================================================================
 void SMESHGUI_RotationDlg::setFilters()
 {
+  if(myMesh->_is_nil()) {
+    SUIT_MessageBox::critical(this,
+                              tr("SMESH_ERROR"),
+                              tr("NO_MESH_SELECTED"));
+   return;
+  }
   if ( !myFilterDlg )
     myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL );
 
@@ -1010,3 +1061,52 @@ bool SMESHGUI_RotationDlg::isValid()
   }
   return true;
 }
+
+
+//=================================================================================
+// function : onDisplaySimulation
+// purpose  : Show/Hide preview
+//=================================================================================
+void SMESHGUI_RotationDlg::onDisplaySimulation( bool toDisplayPreview ) {
+  if (myPreviewCheckBox->isChecked() && toDisplayPreview) {
+    if(myNbOkElements && isValid() && IsAxisOk()) {
+      QStringList aListElementsId = myElementsId.split(" ", QString::SkipEmptyParts);
+      SMESH::long_array_var anElementsId = new SMESH::long_array;
+      
+      anElementsId->length(aListElementsId.count());
+      for (int i = 0; i < aListElementsId.count(); i++)
+        anElementsId[i] = aListElementsId[i].toInt();
+      
+      SMESH::AxisStruct anAxis;
+      
+      anAxis.x =  SpinBox_X->GetValue();
+      anAxis.y =  SpinBox_Y->GetValue();
+      anAxis.z =  SpinBox_Z->GetValue();;
+      anAxis.vx = SpinBox_DX->GetValue();
+      anAxis.vy = SpinBox_DY->GetValue();
+      anAxis.vz = SpinBox_DZ->GetValue();
+      double anAngle = (SpinBox_Angle->GetValue())*M_PI/180.;
+      
+      try {
+        SUIT_OverrideCursor aWaitCursor;
+        bool copy = ( ActionGroup->checkedId() == COPY_ELEMS_BUTTON  ||
+                      ActionGroup->checkedId() == MAKE_MESH_BUTTON );
+        SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditPreviewer();
+        if(CheckBoxMesh->isChecked())
+          aMeshEditor->RotateObject(mySelectedObject, anAxis, anAngle, copy);
+        else
+          aMeshEditor->Rotate(anElementsId, anAxis, anAngle, copy);
+
+        SMESH::MeshPreviewStruct_var aMeshPreviewStruct = aMeshEditor->GetPreviewData();
+        mySimulation->SetData(aMeshPreviewStruct._retn());      
+      } catch (...) {
+        hidePreview();
+      }
+    }
+    else {
+      hidePreview();
+    }
+  } else {
+    hidePreview();
+  }
+}
index 4dd572f2913a9bb818d220bc1cdc479f866b11da..a4e6b4af244b4899be68af4c8551597ad7ee9d22 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_RotationDlg.h
 // Author : Michael ZORIN, Open CASCADE S.A.S.
@@ -28,9 +29,8 @@
 
 // SMESH includes
 #include "SMESH_SMESHGUI.hxx"
+#include "SMESHGUI_PreviewDlg.h"
 
-// Qt includes
-#include <QDialog>
 
 // IDL includes
 #include <SALOMEconfig.h>
@@ -56,7 +56,7 @@ class SMESH_LogicalFilter;
 // class    : SMESHGUI_RotationDlg
 // purpose  :
 //=================================================================================
-class SMESHGUI_EXPORT SMESHGUI_RotationDlg : public QDialog
+class SMESHGUI_EXPORT SMESHGUI_RotationDlg : public SMESHGUI_PreviewDlg
 { 
   Q_OBJECT
 
@@ -75,7 +75,6 @@ private:
   
   bool                   isValid();
 
-  SMESHGUI*              mySMESHGUI;              /* Current SMESHGUI object */
   SMESHGUI_IdValidator*  myIdValidator;
   LightApp_SelectionMgr* mySelectionMgr;          /* User shape selection */
   int                    myNbOkElements;          /* to check when elements are defined */
@@ -131,8 +130,12 @@ private:
 
   QString                myHelpFileName;
 
+  QPushButton*           myFilterBtn;
   SMESHGUI_FilterDlg*    myFilterDlg;
 
+protected slots:
+  virtual void              onDisplaySimulation( bool );
 private slots:
   void                   ClickOnOk();
   void                   ClickOnCancel();
diff --git a/src/SMESHGUI/SMESHGUI_ScaleDlg.cxx b/src/SMESHGUI/SMESHGUI_ScaleDlg.cxx
new file mode 100644 (file)
index 0000000..1e3cd9f
--- /dev/null
@@ -0,0 +1,1136 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+//  File   : SMESHGUI_ScaleDlg.cxx
+//  Author : Michael ZORIN, Open CASCADE S.A.S.
+//  SMESH includes
+
+#include "SMESHGUI_ScaleDlg.h"
+
+#include "SMESHGUI.h"
+#include "SMESHGUI_SpinBox.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_VTKUtils.h"
+#include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI_IdValidator.h"
+#include "SMESHGUI_FilterDlg.h"
+#include "SMESHGUI_MeshEditPreview.h"
+
+#include <SMESH_Actor.h>
+#include <SMESH_TypeFilter.hxx>
+#include <SMESH_LogicalFilter.hxx>
+#include <SMDS_Mesh.hxx>
+
+// SALOME GUI includes
+#include <SUIT_Desktop.h>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_Session.h>
+#include <SUIT_MessageBox.h>
+#include <SUIT_OverrideCursor.h>
+
+#include <LightApp_Application.h>
+#include <LightApp_SelectionMgr.h>
+
+#include <SVTK_ViewModel.h>
+#include <SVTK_ViewWindow.h>
+#include <SALOME_ListIO.hxx>
+
+// SALOME KERNEL includes
+#include <SALOMEDSClient_SObject.hxx>
+
+// OCCT includes
+#include <TColStd_MapOfInteger.hxx>
+
+// Qt includes
+#include <QApplication>
+#include <QButtonGroup>
+#include <QGroupBox>
+#include <QLabel>
+#include <QLineEdit>
+#include <QPushButton>
+#include <QRadioButton>
+#include <QCheckBox>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QGridLayout>
+#include <QSpinBox>
+#include <QKeyEvent>
+
+// IDL includes
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
+enum { MOVE_ELEMS_BUTTON = 0, COPY_ELEMS_BUTTON, MAKE_MESH_BUTTON }; //!< action type
+
+/*!
+  \class BusyLocker
+  \brief Simple 'busy state' flag locker.
+  \internal
+*/
+
+class BusyLocker
+{
+public:
+  //! Constructor. Sets passed boolean flag to \c true.
+  BusyLocker( bool& busy ) : myBusy( busy ) { myBusy = true; }
+  //! Destructor. Clear external boolean flag passed as parameter to the constructor to \c false.
+  ~BusyLocker() { myBusy = false; }
+private:
+  bool& myBusy; //! External 'busy state' boolean flag
+};
+
+#define SPACING 6
+#define MARGIN  11
+
+//To disable automatic genericobj management, the following line should be commented.
+//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
+#define WITHGENERICOBJ
+
+//=================================================================================
+// class    : SMESHGUI_ScaleDlg()
+// purpose  :
+//=================================================================================
+SMESHGUI_ScaleDlg::SMESHGUI_ScaleDlg( SMESHGUI* theModule ) : 
+    SMESHGUI_PreviewDlg( theModule ),
+    mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
+    myFilterDlg(0),
+    mySelectedObject(SMESH::SMESH_IDSource::_nil())
+{
+  QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_DLG_MESH_SCALE")));
+  QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_DLG_SCALE_ALONG_AXES")));
+  QPixmap image2 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
+
+  setModal(false);
+  setAttribute(Qt::WA_DeleteOnClose, true);
+  setWindowTitle(tr("SMESH_SCALE_TITLE"));
+  setSizeGripEnabled(true);
+
+  QVBoxLayout* SMESHGUI_ScaleDlgLayout = new QVBoxLayout(this);
+  SMESHGUI_ScaleDlgLayout->setSpacing(SPACING);
+  SMESHGUI_ScaleDlgLayout->setMargin(MARGIN);
+
+  /***************************************************************/
+  ConstructorsBox = new QGroupBox(tr("SMESH_SCALE"), this);
+  GroupConstructors = new QButtonGroup(this);
+  QHBoxLayout* ConstructorsBoxLayout = new QHBoxLayout(ConstructorsBox);
+  ConstructorsBoxLayout->setSpacing(SPACING);
+  ConstructorsBoxLayout->setMargin(MARGIN);
+
+  RadioButton1= new QRadioButton(ConstructorsBox);
+  RadioButton1->setIcon(image0);
+  RadioButton2= new QRadioButton(ConstructorsBox);
+  RadioButton2->setIcon(image1);
+
+  ConstructorsBoxLayout->addWidget(RadioButton1);
+  ConstructorsBoxLayout->addWidget(RadioButton2);
+  GroupConstructors->addButton(RadioButton1, 0);
+  GroupConstructors->addButton(RadioButton2, 1);
+
+  /***************************************************************/
+  GroupArguments = new QGroupBox(tr("SMESH_ARGUMENTS"), this);
+  QGridLayout* GroupArgumentsLayout = new QGridLayout(GroupArguments);
+  GroupArgumentsLayout->setSpacing(SPACING);
+  GroupArgumentsLayout->setMargin(MARGIN);
+
+  myIdValidator = new SMESHGUI_IdValidator(this);
+
+  // Controls for elements selection
+  TextLabelElements = new QLabel(tr("SMESH_ID_ELEMENTS"), GroupArguments);
+  SelectElementsButton = new QPushButton(GroupArguments);
+  SelectElementsButton->setIcon(image2);
+  LineEditElements = new QLineEdit(GroupArguments);
+  LineEditElements->setValidator(myIdValidator);
+  LineEditElements->setMaxLength(-1);
+  myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
+  connect(myFilterBtn,   SIGNAL(clicked()), this, SLOT(setFilters()));
+
+  // Control for the whole mesh selection
+  CheckBoxMesh = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments);
+
+  // Controls for vector and points selection
+  TextLabel1 = new QLabel(tr("SMESH_BASE_POINT"), GroupArguments);
+  SelectButton1 = new QPushButton(GroupArguments);
+  SelectButton1->setIcon(image2);
+
+  TextLabel1_1 = new QLabel(tr("SMESH_X"), GroupArguments);
+  SpinBox1_1 = new SMESHGUI_SpinBox(GroupArguments);
+  TextLabel1_2 = new QLabel(tr("SMESH_Y"), GroupArguments);
+  SpinBox1_2 = new SMESHGUI_SpinBox(GroupArguments);
+  TextLabel1_3 = new QLabel(tr("SMESH_Z"), GroupArguments);
+  SpinBox1_3 = new SMESHGUI_SpinBox(GroupArguments);
+
+  TextLabel2 = new QLabel(tr("SMESH_SCALE_FACTOR"), GroupArguments);
+  SpinBox_FX = new SMESHGUI_SpinBox(GroupArguments);
+
+  TextLabel3 = new QLabel(tr("SMESH_SCALE_FACTOR_Y"), GroupArguments);
+  SpinBox_FY = new SMESHGUI_SpinBox(GroupArguments);
+
+  TextLabel4 = new QLabel(tr("SMESH_SCALE_FACTOR_Z"), GroupArguments);
+  SpinBox_FZ = new SMESHGUI_SpinBox(GroupArguments);
+
+
+  // switch of action type
+  ActionBox = new QGroupBox(GroupArguments);
+  ActionGroup = new QButtonGroup(GroupArguments);
+  QVBoxLayout* ActionBoxLayout = new QVBoxLayout(ActionBox);
+  ActionBoxLayout->addSpacing(SPACING);
+  ActionBoxLayout->setMargin(MARGIN);
+
+  QRadioButton* aMoveElements = new QRadioButton(tr("SMESH_MOVE_ELEMENTS"), ActionBox);
+  QRadioButton* aCopyElements = new QRadioButton(tr("SMESH_COPY_ELEMENTS"), ActionBox);
+  QRadioButton* aCreateMesh   = new QRadioButton(tr("SMESH_CREATE_MESH"),   ActionBox);
+
+  ActionBoxLayout->addWidget(aMoveElements);
+  ActionBoxLayout->addWidget(aCopyElements);
+  ActionBoxLayout->addWidget(aCreateMesh);
+  ActionGroup->addButton(aMoveElements, MOVE_ELEMS_BUTTON);
+  ActionGroup->addButton(aCopyElements, COPY_ELEMS_BUTTON);
+  ActionGroup->addButton(aCreateMesh,   MAKE_MESH_BUTTON);
+
+  // CheckBox for groups generation
+  MakeGroupsCheck = new QCheckBox(tr("SMESH_MAKE_GROUPS"), GroupArguments);
+  MakeGroupsCheck->setChecked(false);
+
+  // Name of a mesh to create
+  LineEditNewMesh = new QLineEdit(GroupArguments);
+
+  //Preview check box
+  myPreviewCheckBox = new QCheckBox(tr("PREVIEW"), GroupArguments);
+
+  // layout
+  GroupArgumentsLayout->addWidget(TextLabelElements,    0, 0);
+  GroupArgumentsLayout->addWidget(SelectElementsButton, 0, 1);
+  GroupArgumentsLayout->addWidget(LineEditElements,     0, 2, 1, 5);
+  GroupArgumentsLayout->addWidget(myFilterBtn,          0, 7);
+  GroupArgumentsLayout->addWidget(CheckBoxMesh,         1, 0, 1, 8);
+  GroupArgumentsLayout->addWidget(TextLabel1,           2, 0);
+  GroupArgumentsLayout->addWidget(SelectButton1,        2, 1);
+  GroupArgumentsLayout->addWidget(TextLabel1_1,         2, 2);
+  GroupArgumentsLayout->addWidget(SpinBox1_1,           2, 3);
+  GroupArgumentsLayout->addWidget(TextLabel1_2,         2, 4);
+  GroupArgumentsLayout->addWidget(SpinBox1_2,           2, 5);
+  GroupArgumentsLayout->addWidget(TextLabel1_3,         2, 6);
+  GroupArgumentsLayout->addWidget(SpinBox1_3,           2, 7);
+  GroupArgumentsLayout->addWidget(TextLabel2,           3, 0);
+  GroupArgumentsLayout->addWidget(SpinBox_FX,           3, 3);
+  GroupArgumentsLayout->addWidget(TextLabel3,           4, 0);
+  GroupArgumentsLayout->addWidget(SpinBox_FY,           4, 3);
+  GroupArgumentsLayout->addWidget(TextLabel4,           5, 0);
+  GroupArgumentsLayout->addWidget(SpinBox_FZ,           5, 3);
+  GroupArgumentsLayout->addWidget(ActionBox,            7, 0, 3, 4);
+  GroupArgumentsLayout->addWidget(MakeGroupsCheck,      8, 5, 1, 4);
+  GroupArgumentsLayout->addWidget(LineEditNewMesh,      9, 5, 1, 4);
+  GroupArgumentsLayout->addWidget(myPreviewCheckBox,    10, 0);
+
+  /***************************************************************/
+  GroupButtons = new QGroupBox(this);
+  QHBoxLayout* GroupButtonsLayout = new QHBoxLayout(GroupButtons);
+  GroupButtonsLayout->setSpacing(SPACING);
+  GroupButtonsLayout->setMargin(MARGIN);
+
+  buttonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), GroupButtons);
+  buttonOk->setAutoDefault(true);
+  buttonOk->setDefault(true);
+  buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons);
+  buttonApply->setAutoDefault(true);
+  buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons);
+  buttonCancel->setAutoDefault(true);
+  buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons);
+  buttonHelp->setAutoDefault(true);
+
+  GroupButtonsLayout->addWidget(buttonOk);
+  GroupButtonsLayout->addSpacing(10);
+  GroupButtonsLayout->addWidget(buttonApply);
+  GroupButtonsLayout->addSpacing(10);
+  GroupButtonsLayout->addStretch();
+  GroupButtonsLayout->addWidget(buttonCancel);
+  GroupButtonsLayout->addWidget(buttonHelp);
+
+  /***************************************************************/
+  SMESHGUI_ScaleDlgLayout->addWidget(ConstructorsBox);
+  SMESHGUI_ScaleDlgLayout->addWidget(GroupArguments);
+  SMESHGUI_ScaleDlgLayout->addWidget(GroupButtons);
+
+  /* Initialisations */
+  SpinBox1_1->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  SpinBox1_2->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  SpinBox1_3->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  SpinBox_FX->RangeStepAndValidator(1.e-6, 1.e+6, 1.0, "parametric_precision");
+  SpinBox_FX->SetStep(0.1);
+  SpinBox_FY->RangeStepAndValidator(1.e-6, 1.e+6, 1.0, "parametric_precision");
+  SpinBox_FY->SetStep(0.1);
+  SpinBox_FZ->RangeStepAndValidator(1.e-6, 1.e+6, 1.0, "parametric_precision");
+  SpinBox_FZ->SetStep(0.1);
+
+  RadioButton1->setChecked(true);
+
+  mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
+
+  mySMESHGUI->SetActiveDialogBox((QDialog*)this);
+
+  // Costruction of the logical filter
+  SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter (MESHorSUBMESH);
+  SMESH_TypeFilter* aSmeshGroupFilter    = new SMESH_TypeFilter (GROUP);
+
+  QList<SUIT_SelectionFilter*> aListOfFilters;
+  if (aMeshOrSubMeshFilter) aListOfFilters.append(aMeshOrSubMeshFilter);
+  if (aSmeshGroupFilter)    aListOfFilters.append(aSmeshGroupFilter);
+
+  myMeshOrSubMeshOrGroupFilter =
+    new SMESH_LogicalFilter(aListOfFilters, SMESH_LogicalFilter::LO_OR);
+
+  myHelpFileName = "scale_page.html";
+
+  Init();
+
+  /* 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(buttonHelp,   SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
+  connect(GroupConstructors, SIGNAL(buttonClicked(int)), SLOT(ConstructorsClicked(int)));
+
+  connect(SelectElementsButton, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument()));
+  connect(SelectButton1,        SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument()));
+
+  connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
+  connect(mySelectionMgr, SIGNAL(currentSelectionChanged()),   this, SLOT(SelectionIntoArgument()));
+  /* to close dialog if study change */
+  connect(mySMESHGUI,       SIGNAL (SignalCloseAllDialogs()), this, SLOT(ClickOnCancel()));
+  connect(LineEditElements, SIGNAL(textChanged(const QString&)),    SLOT(onTextChange(const QString&)));
+  connect(CheckBoxMesh,     SIGNAL(toggled(bool)),                  SLOT(onSelectMesh(bool)));
+  connect(ActionGroup,      SIGNAL(buttonClicked(int)),             SLOT(onActionClicked(int)));
+
+  connect(SpinBox1_1,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(SpinBox1_2,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(SpinBox1_3,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+
+  connect(SpinBox_FX,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(SpinBox_FY,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(SpinBox_FZ,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+
+  //To Connect preview check box
+  connectPreviewControl();
+
+  ConstructorsClicked(0);
+  SelectionIntoArgument();
+  onActionClicked(MOVE_ELEMS_BUTTON);
+}
+
+//=================================================================================
+// function : ~SMESHGUI_ScaleDlg()
+// purpose  : Destroys the object and frees any allocated resources
+//=================================================================================
+SMESHGUI_ScaleDlg::~SMESHGUI_ScaleDlg()
+{
+  if ( myFilterDlg ) {
+    myFilterDlg->setParent( 0 );
+    delete myFilterDlg;
+    myFilterDlg = 0;
+  }
+}
+
+//=================================================================================
+// function : Init()
+// purpose  :
+//=================================================================================
+void SMESHGUI_ScaleDlg::Init (bool ResetControls)
+{
+  myBusy = false;
+
+  myEditCurrentArgument = 0;
+  LineEditElements->clear();
+  myElementsId = "";
+  myNbOkElements = 0;
+
+  buttonOk->setEnabled(false);
+  buttonApply->setEnabled(false);
+
+  myActor = 0;
+  myMesh = SMESH::SMESH_Mesh::_nil();
+
+  if (ResetControls) {
+    SpinBox1_1->SetValue(0.0);
+    SpinBox1_2->SetValue(0.0);
+    SpinBox1_3->SetValue(0.0);
+    SpinBox_FX->SetValue(1.0);
+    SpinBox_FY->SetValue(1.0);
+    SpinBox_FZ->SetValue(1.0);
+    myPreviewCheckBox->setChecked(false);
+    onDisplaySimulation(false);
+
+    ActionGroup->button( MOVE_ELEMS_BUTTON )->setChecked(true);
+    CheckBoxMesh->setChecked(false);
+    onSelectMesh(false);
+  }
+}
+
+//=================================================================================
+// function : ConstructorsClicked()
+// purpose  : Radio button management
+//=================================================================================
+void SMESHGUI_ScaleDlg::ConstructorsClicked (int constructorId)
+{
+  disconnect(mySelectionMgr, 0, this, 0);
+
+  switch (constructorId) {
+  case 0:
+    {
+      TextLabel2->setText(tr("SMESH_SCALE_FACTOR"));
+      TextLabel3->hide();
+      TextLabel4->hide();
+      SpinBox_FY->hide();
+      SpinBox_FZ->hide();
+      break;
+    }
+  case 1:
+    {
+      TextLabel2->setText(tr("SMESH_SCALE_FACTOR_X"));
+      TextLabel3->show();
+      TextLabel4->show();
+      SpinBox_FY->show();
+      SpinBox_FZ->show();
+      break;
+    }
+  }
+
+  if (myEditCurrentArgument != (QWidget*)LineEditElements) {
+    SMESH::SetPointRepresentation(false);
+    if (!CheckBoxMesh->isChecked())
+      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+        aViewWindow->SetSelectionMode( CellSelection );
+  }
+
+  myEditCurrentArgument = (QWidget*)LineEditElements;
+  LineEditElements->setFocus();
+
+  if (CheckBoxMesh->isChecked())
+    onSelectMesh(true);
+
+  connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
+
+  QApplication::instance()->processEvents();
+  updateGeometry();
+  resize(100,100);
+}
+
+//=================================================================================
+// function : ClickOnApply()
+// purpose  :
+//=================================================================================
+bool SMESHGUI_ScaleDlg::ClickOnApply()
+{
+  if (mySMESHGUI->isActiveStudyLocked())
+    return false;
+
+  if( !isValid() )
+    return false;
+
+  if (myNbOkElements) {
+    QStringList aListElementsId = myElementsId.split(" ", QString::SkipEmptyParts);
+
+    SMESH::long_array_var anElementsId = new SMESH::long_array;
+
+    anElementsId->length(aListElementsId.count());
+    for (int i = 0; i < aListElementsId.count(); i++)
+      anElementsId[i] = aListElementsId[i].toInt();
+
+    SMESH::PointStruct aPoint;
+    SMESH::double_array_var aScaleFact = new SMESH::double_array;
+    getScale(aPoint, aScaleFact);
+
+    QStringList aParameters;
+    aParameters << SpinBox1_1->text();
+    aParameters << SpinBox1_2->text();
+    aParameters << SpinBox1_3->text();
+    aParameters << SpinBox_FX->text();
+    if (GetConstructorId() == 1) {
+      aParameters << SpinBox_FX->text();
+      aParameters << SpinBox_FX->text();
+    }
+    else {
+      aParameters << SpinBox_FY->text();
+      aParameters << SpinBox_FZ->text();
+    }
+
+    int actionButton = ActionGroup->checkedId();
+    bool makeGroups = ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() );
+    QStringList anEntryList;
+    try {
+      SUIT_OverrideCursor aWaitCursor;
+      SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
+
+      myMesh->SetParameters( aParameters.join(":").toLatin1().constData() );
+
+      SMESH::SMESH_IDSource_var obj;
+      if ( CheckBoxMesh->isChecked() )
+        obj = mySelectedObject;
+      else
+        obj = aMeshEditor->MakeIDSource(anElementsId, SMESH::ALL);
+
+      switch ( actionButton ) {
+
+      case MOVE_ELEMS_BUTTON:
+        aMeshEditor->Scale(obj, aPoint, aScaleFact, false);
+        break;
+
+      case COPY_ELEMS_BUTTON:
+        if ( makeGroups )
+          SMESH::ListOfGroups_var groups = 
+            aMeshEditor->ScaleMakeGroups(obj, aPoint, aScaleFact);
+        else 
+          aMeshEditor->Scale(obj, aPoint, aScaleFact, true);
+        break;
+
+      case MAKE_MESH_BUTTON: {
+        SMESH::SMESH_Mesh_var mesh =
+          aMeshEditor->ScaleMakeMesh(obj, aPoint, aScaleFact, makeGroups,
+                                     LineEditNewMesh->text().toLatin1().data());
+        if (!mesh->_is_nil()) {
+          if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( mesh ) )
+            anEntryList.append( aSObject->GetID().c_str() );
+#ifdef WITHGENERICOBJ
+          // obj has been published in study. Its refcount has been incremented.
+          // It is safe to decrement its refcount
+          // so that it will be destroyed when the entry in study will be removed
+          mesh->UnRegister();
+#endif
+        }
+        break;
+      }
+      }
+    } catch (...) {
+    }
+
+    SMESH::UpdateView();
+    if ( ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ) ||
+         actionButton == MAKE_MESH_BUTTON ) {
+      mySMESHGUI->updateObjBrowser(true); // new groups may appear
+      if( LightApp_Application* anApp =
+          dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
+        anApp->browseObjects( anEntryList, isApplyAndClose() );
+    }
+    Init(false);
+    ConstructorsClicked(GetConstructorId());
+    mySelectedObject = SMESH::SMESH_IDSource::_nil();
+    SelectionIntoArgument();
+
+    SMESHGUI::Modified();
+  }
+
+  return true;
+}
+
+//=================================================================================
+// function : ClickOnOk()
+// purpose  :
+//=================================================================================
+void SMESHGUI_ScaleDlg::ClickOnOk()
+{
+  setIsApplyAndClose( true );
+  if( ClickOnApply() )
+    ClickOnCancel();
+}
+
+//=================================================================================
+// function : ClickOnCancel()
+// purpose  :
+//=================================================================================
+void SMESHGUI_ScaleDlg::ClickOnCancel()
+{
+  disconnect(mySelectionMgr, 0, this, 0);
+  mySelectionMgr->clearFilters();
+  //mySelectionMgr->clearSelected();
+  if (SMESH::GetCurrentVtkView()) {
+    SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters
+    SMESH::SetPointRepresentation(false);
+  }
+  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+    aViewWindow->SetSelectionMode( ActorSelection );
+  mySMESHGUI->ResetState();
+  reject();
+}
+
+//=================================================================================
+// function : ClickOnHelp()
+// purpose  :
+//=================================================================================
+void SMESHGUI_ScaleDlg::ClickOnHelp()
+{
+  LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
+  if (app)
+    app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
+  else {
+    QString platform;
+#ifdef WIN32
+    platform = "winapplication";
+#else
+    platform = "application";
+#endif
+    SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser",
+                                                                 platform)).
+                             arg(myHelpFileName));
+  }
+}
+
+//=======================================================================
+// function : onTextChange()
+// purpose  :
+//=======================================================================
+void SMESHGUI_ScaleDlg::onTextChange (const QString& theNewText)
+{
+  QLineEdit* send = (QLineEdit*)sender();
+
+  if (myBusy) return;
+  BusyLocker lock( myBusy );
+
+  if (send == LineEditElements)
+    myNbOkElements = 0;
+
+  buttonOk->setEnabled(false);
+  buttonApply->setEnabled(false);
+
+  // hilight entered elements
+  SMDS_Mesh* aMesh = 0;
+  if (myActor)
+    aMesh = myActor->GetObject()->GetMesh();
+
+  if (aMesh) {
+    Handle(SALOME_InteractiveObject) anIO = myActor->getIO();
+
+    TColStd_MapOfInteger newIndices;
+
+    QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
+
+    if (send == LineEditElements) {
+      for (int i = 0; i < aListId.count(); i++) {
+        const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt());
+        if (e)
+          newIndices.Add(e->GetID());
+        myNbOkElements++;
+      }
+    }
+
+    mySelector->AddOrRemoveIndex( anIO, newIndices, false );
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->highlight( anIO, true, true );
+
+    myElementsId = theNewText;
+  }
+
+  if (myNbOkElements) {
+    buttonOk->setEnabled(true);
+    buttonApply->setEnabled(true);
+  }
+}
+
+//=================================================================================
+// function : SelectionIntoArgument()
+// purpose  : Called when selection as changed or other case
+//=================================================================================
+void SMESHGUI_ScaleDlg::SelectionIntoArgument()
+{
+  if (myBusy) return;
+  BusyLocker lock( myBusy );
+  // clear
+  myActor = 0;
+  QString aString = "";
+
+  if (myEditCurrentArgument == (QWidget*)LineEditElements) {
+    LineEditElements->setText(aString);
+    myNbOkElements = 0;
+    buttonOk->setEnabled(false);
+    buttonApply->setEnabled(false);
+  }
+
+  if (!GroupButtons->isEnabled()) // inactive
+    return;
+
+  // get selected mesh
+  SALOME_ListIO aList;
+  mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
+
+  int nbSel = aList.Extent();
+  if (nbSel != 1)
+    return;
+
+  Handle(SALOME_InteractiveObject) IO = aList.First();
+  myMesh = SMESH::GetMeshByIO(IO);
+  if (myMesh->_is_nil())
+    return;
+
+  myActor = SMESH::FindActorByObject(myMesh);
+  if (!myActor)
+    myActor = SMESH::FindActorByEntry(IO->getEntry());
+  if (!myActor && !CheckBoxMesh->isChecked())
+    return;
+
+  int aNbUnits = 0;
+
+  if (myEditCurrentArgument == (QWidget*)LineEditElements) {
+    myElementsId = "";
+
+    // MakeGroups is available if there are groups and "Copy"
+    if ( myMesh->NbGroups() == 0 ) {
+      MakeGroupsCheck->setChecked(false);
+      MakeGroupsCheck->setEnabled(false);
+    }
+    else if ( ActionGroup->checkedId() != MOVE_ELEMS_BUTTON ) {
+      MakeGroupsCheck->setEnabled(true);
+    }
+
+    if (CheckBoxMesh->isChecked()) {
+      SMESH::GetNameOfSelectedIObjects( mySelectionMgr, aString );
+
+      if (!SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO)->_is_nil()) { //MESH, SUBMESH, OR GROUP
+        mySelectedObject = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO);
+      }
+      else
+        return;
+        // get IDs from mesh
+        /*
+        SMDS_Mesh* aSMDSMesh = myActor->GetObject()->GetMesh();
+        if (!aSMDSMesh)
+          return;
+
+        for (int i = aSMDSMesh->MinElementID(); i <= aSMDSMesh->MaxElementID(); i++) {
+          const SMDS_MeshElement * e = aSMDSMesh->FindElement(i);
+          if (e) {
+            myElementsId += QString(" %1").arg(i);
+            aNbUnits++;
+          }
+        }
+      } else if (!SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(IO)->_is_nil()) { //SUBMESH
+        // get submesh
+        SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(IO);
+
+        // get IDs from submesh
+        SMESH::long_array_var anElementsIds = new SMESH::long_array;
+        anElementsIds = aSubMesh->GetElementsId();
+        for (int i = 0; i < anElementsIds->length(); i++) {
+          myElementsId += QString(" %1").arg(anElementsIds[i]);
+        }
+        aNbUnits = anElementsIds->length();
+      } else { // GROUP
+        // get smesh group
+        SMESH::SMESH_GroupBase_var aGroup =
+          SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(IO);
+        if (aGroup->_is_nil())
+          return;
+
+        // get IDs from smesh group
+        SMESH::long_array_var anElementsIds = new SMESH::long_array;
+        anElementsIds = aGroup->GetListOfID();
+        for (int i = 0; i < anElementsIds->length(); i++) {
+          myElementsId += QString(" %1").arg(anElementsIds[i]);
+        }
+        aNbUnits = anElementsIds->length();
+      }
+        */
+    } else {
+      aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, IO, aString);
+      myElementsId = aString;
+      if (aNbUnits < 1)
+        return;
+    }
+
+    myNbOkElements = true;
+  } else {
+    aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
+    if (aNbUnits != 1)
+      return;
+
+    SMDS_Mesh* aMesh =  myActor->GetObject()->GetMesh();
+    if (!aMesh)
+      return;
+
+    const SMDS_MeshNode * n = aMesh->FindNode(aString.toInt());
+    if (!n)
+      return;
+
+    double x = n->X();
+    double y = n->Y();
+    double z = n->Z();
+
+    if (myEditCurrentArgument == (QWidget*)SpinBox1_1) {
+      SpinBox1_1->SetValue(x);
+      SpinBox1_2->SetValue(y);
+      SpinBox1_3->SetValue(z);
+    }
+    else if (myEditCurrentArgument == (QWidget*)SpinBox_FX) {
+      SpinBox_FX->SetValue(x);
+      SpinBox_FY->SetValue(y);
+      SpinBox_FZ->SetValue(z);
+    }
+  }
+
+  if (myEditCurrentArgument == (QWidget*)LineEditElements) {
+    LineEditElements->setText(aString);
+    LineEditElements->repaint();
+    LineEditElements->setEnabled(false); // to fully update lineedit IPAL 19809
+    LineEditElements->setEnabled(true);
+    setNewMeshName();
+  }
+
+  // OK
+  if (myNbOkElements) {
+    buttonOk->setEnabled(true);
+    buttonApply->setEnabled(true);
+  }
+  
+  onDisplaySimulation(true);
+}
+
+//=================================================================================
+// function : SetEditCurrentArgument()
+// purpose  :
+//=================================================================================
+void SMESHGUI_ScaleDlg::SetEditCurrentArgument()
+{
+  QPushButton* send = (QPushButton*)sender();
+
+  disconnect(mySelectionMgr, 0, this, 0);
+  mySelectionMgr->clearSelected();
+  mySelectionMgr->clearFilters();
+
+  if (send == SelectElementsButton) {
+    myEditCurrentArgument = (QWidget*)LineEditElements;
+    SMESH::SetPointRepresentation(false);
+    if (CheckBoxMesh->isChecked()) {
+      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+        aViewWindow->SetSelectionMode( ActorSelection );
+      mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter);
+    }
+    else {
+      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+        aViewWindow->SetSelectionMode( CellSelection );
+    }
+  }
+  else if (send == SelectButton1) {
+    myEditCurrentArgument = (QWidget*)SpinBox1_1;
+    SMESH::SetPointRepresentation(true);
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->SetSelectionMode( NodeSelection );
+  }
+
+  myEditCurrentArgument->setFocus();
+  connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
+  SelectionIntoArgument();
+}
+
+//=================================================================================
+// function : DeactivateActiveDialog()
+// purpose  :
+//=================================================================================
+void SMESHGUI_ScaleDlg::DeactivateActiveDialog()
+{
+  if (ConstructorsBox->isEnabled()) {
+    ConstructorsBox->setEnabled(false);
+    GroupArguments->setEnabled(false);
+    GroupButtons->setEnabled(false);
+    mySMESHGUI->ResetState();
+    mySMESHGUI->SetActiveDialogBox(0);
+  }
+}
+
+//=================================================================================
+// function : ActivateThisDialog()
+// purpose  :
+//=================================================================================
+void SMESHGUI_ScaleDlg::ActivateThisDialog()
+{
+  /* Emit a signal to deactivate the active dialog */
+  mySMESHGUI->EmitSignalDeactivateDialog();
+  ConstructorsBox->setEnabled(true);
+  GroupArguments->setEnabled(true);
+  GroupButtons->setEnabled(true);
+
+  mySMESHGUI->SetActiveDialogBox((QDialog*)this);
+
+  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+    aViewWindow->SetSelectionMode( CellSelection );
+
+  SelectionIntoArgument();
+}
+
+//=================================================================================
+// function : enterEvent()
+// purpose  :
+//=================================================================================
+void SMESHGUI_ScaleDlg::enterEvent (QEvent*)
+{
+  if (!ConstructorsBox->isEnabled())
+    ActivateThisDialog();
+}
+
+//=================================================================================
+// function : closeEvent()
+// purpose  :
+//=================================================================================
+void SMESHGUI_ScaleDlg::closeEvent (QCloseEvent*)
+{
+  /* same than click on cancel button */
+  ClickOnCancel();
+}
+
+//=======================================================================
+//function : hideEvent
+//purpose  : caused by ESC key
+//=======================================================================
+void SMESHGUI_ScaleDlg::hideEvent (QHideEvent*)
+{
+  if (!isMinimized())
+    ClickOnCancel();
+}
+
+//=======================================================================
+//function : onSelectMesh
+//purpose  :
+//=======================================================================
+void SMESHGUI_ScaleDlg::onSelectMesh (bool toSelectMesh)
+{
+  if (toSelectMesh)
+    TextLabelElements->setText(tr("SMESH_NAME"));
+  else
+    TextLabelElements->setText(tr("SMESH_ID_ELEMENTS"));
+  myFilterBtn->setEnabled(!toSelectMesh);
+
+  if (myEditCurrentArgument != LineEditElements) {
+    LineEditElements->clear();
+    return;
+  }
+
+  mySelectionMgr->clearFilters();
+  SMESH::SetPointRepresentation(false);
+
+  if (toSelectMesh) {
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->SetSelectionMode( ActorSelection );
+    mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter);
+    LineEditElements->setReadOnly(true);
+    LineEditElements->setValidator(0);
+  } else {
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->SetSelectionMode( CellSelection );
+    LineEditElements->setReadOnly(false);
+    LineEditElements->setValidator(myIdValidator);
+    onTextChange(LineEditElements->text());
+    hidePreview();
+  }
+
+  SelectionIntoArgument();
+}
+
+//=======================================================================
+//function : onActionClicked
+//purpose  : slot called when an action type changed
+//=======================================================================
+
+void SMESHGUI_ScaleDlg::onActionClicked(int button)
+{
+  switch ( button ) {
+  case MOVE_ELEMS_BUTTON:
+    MakeGroupsCheck->setEnabled(false);
+    LineEditNewMesh->setEnabled(false);
+    break;
+  case COPY_ELEMS_BUTTON:
+    LineEditNewMesh->setEnabled(false);
+    MakeGroupsCheck->setText( tr("SMESH_MAKE_GROUPS"));
+    if ( myMesh->_is_nil() || myMesh->NbGroups() > 0)
+      MakeGroupsCheck->setEnabled(true);
+    else
+      MakeGroupsCheck->setEnabled(false);
+    break;
+  case MAKE_MESH_BUTTON:
+    LineEditNewMesh->setEnabled(true);
+    MakeGroupsCheck->setText( tr("SMESH_COPY_GROUPS"));
+    if ( myMesh->_is_nil() || myMesh->NbGroups() > 0)
+      MakeGroupsCheck->setEnabled(true);
+    else
+      MakeGroupsCheck->setEnabled(false);
+    break;
+  }
+  setNewMeshName();
+  toDisplaySimulation();
+}
+
+//=======================================================================
+//function : setNewMeshName
+//purpose  : update contents of LineEditNewMesh
+//=======================================================================
+
+void SMESHGUI_ScaleDlg::setNewMeshName()
+{
+  LineEditNewMesh->setText("");
+  if ( LineEditNewMesh->isEnabled() && !myMesh->_is_nil() ) {
+    QString name;
+    if ( CheckBoxMesh->isChecked() ) {
+      name = LineEditElements->text();
+    }
+    else {
+      _PTR(SObject) meshSO = SMESH::FindSObject( myMesh );
+      name = meshSO->GetName().c_str();
+    }
+    if ( !name.isEmpty() )
+      LineEditNewMesh->setText( SMESH::UniqueMeshName( name, "scaled"));
+  }
+}
+
+//=================================================================================
+// function : GetConstructorId()
+// purpose  :
+//=================================================================================
+int SMESHGUI_ScaleDlg::GetConstructorId()
+{
+  return GroupConstructors->checkedId();
+}
+
+//=================================================================================
+// function : keyPressEvent()
+// purpose  :
+//=================================================================================
+void SMESHGUI_ScaleDlg::keyPressEvent( QKeyEvent* e )
+{
+  QDialog::keyPressEvent( e );
+  if ( e->isAccepted() )
+    return;
+
+  if ( e->key() == Qt::Key_F1 ) {
+    e->accept();
+    ClickOnHelp();
+  }
+}
+
+//=================================================================================
+// function : setFilters()
+// purpose  : SLOT. Called when "Filter" button pressed.
+//=================================================================================
+void SMESHGUI_ScaleDlg::setFilters()
+{
+  if(myMesh->_is_nil()) {
+    SUIT_MessageBox::critical(this,
+                              tr("SMESH_ERROR"),
+                              tr("NO_MESH_SELECTED"));
+   return;
+  }
+  if ( !myFilterDlg )
+    myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL );
+
+  myFilterDlg->SetSelection();
+  myFilterDlg->SetMesh( myMesh );
+  myFilterDlg->SetSourceWg( LineEditElements );
+
+  myFilterDlg->show();
+}
+
+//=================================================================================
+// function : isValid
+// purpose  :
+//=================================================================================
+bool SMESHGUI_ScaleDlg::isValid()
+{
+  bool ok = true;
+  QString msg;
+
+  ok = SpinBox1_1->isValid( msg, true ) && ok;
+  ok = SpinBox1_2->isValid( msg, true ) && ok;
+  ok = SpinBox1_3->isValid( msg, true ) && ok;
+  ok = SpinBox_FX->isValid( msg, true ) && ok;
+  if (GetConstructorId() == 1) {
+    ok = SpinBox_FY->isValid( msg, true ) && ok;
+    ok = SpinBox_FZ->isValid( msg, true ) && ok;
+  }
+
+  if( !ok ) {
+    QString str( tr( "SMESH_INCORRECT_INPUT" ) );
+    if ( !msg.isEmpty() )
+      str += "\n" + msg;
+    SUIT_MessageBox::critical( this, tr( "SMESH_ERROR" ), str );
+    return false;
+  }
+  return true;
+}
+
+//=================================================================================
+// function : onDisplaySimulation
+// purpose  : Show/Hide preview
+//=================================================================================
+void SMESHGUI_ScaleDlg::onDisplaySimulation( bool toDisplayPreview ) {
+  if (myPreviewCheckBox->isChecked() && toDisplayPreview) {    
+    if ( myNbOkElements && isValid() ) {
+      QStringList aListElementsId = myElementsId.split(" ", QString::SkipEmptyParts);
+
+      SMESH::long_array_var anElementsId = new SMESH::long_array;
+      
+      anElementsId->length(aListElementsId.count());
+      for (int i = 0; i < aListElementsId.count(); i++)
+        anElementsId[i] = aListElementsId[i].toInt();
+      
+      SMESH::PointStruct aPoint;
+      SMESH::double_array_var aScaleFact = new SMESH::double_array;
+      getScale(aPoint, aScaleFact);
+      
+      try {
+        bool copy = ( ActionGroup->checkedId() == COPY_ELEMS_BUTTON ||
+                      ActionGroup->checkedId() == MAKE_MESH_BUTTON );
+        SUIT_OverrideCursor aWaitCursor;
+        SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditPreviewer();
+        SMESH::SMESH_IDSource_var obj;
+        if ( CheckBoxMesh->isChecked() )
+          obj = mySelectedObject;
+        else
+          obj = aMeshEditor->MakeIDSource(anElementsId, SMESH::ALL);
+        aMeshEditor->Scale(obj, aPoint, aScaleFact, copy);
+
+        SMESH::MeshPreviewStruct_var aMeshPreviewStruct = aMeshEditor->GetPreviewData();
+        mySimulation->SetData(aMeshPreviewStruct._retn());      
+
+      } catch (...) {
+        hidePreview();
+      }
+    } else {
+      hidePreview();
+    } 
+  } else {
+    hidePreview();
+  }
+}
+
+//=================================================================================
+// function : getScale
+// purpose  : get scale parameters
+//=================================================================================
+void SMESHGUI_ScaleDlg::getScale( SMESH::PointStruct& thePoint ,  SMESH::double_array_var& theScaleFact) {
+  thePoint.x = SpinBox1_1->GetValue();
+  thePoint.y = SpinBox1_2->GetValue();
+  thePoint.z = SpinBox1_3->GetValue();
+  
+  theScaleFact->length(3);
+  theScaleFact[0] = SpinBox_FX->GetValue();
+  if (GetConstructorId() == 0) {
+    theScaleFact[1] = SpinBox_FX->GetValue();
+    theScaleFact[2] = SpinBox_FX->GetValue();
+  }
+  else {
+    theScaleFact[1] = SpinBox_FY->GetValue();
+    theScaleFact[2] = SpinBox_FZ->GetValue();
+  } 
+}
diff --git a/src/SMESHGUI/SMESHGUI_ScaleDlg.h b/src/SMESHGUI/SMESHGUI_ScaleDlg.h
new file mode 100644 (file)
index 0000000..7293a99
--- /dev/null
@@ -0,0 +1,150 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+// SMESH SMESHGUI : GUI for SMESH component
+// File   : SMESHGUI_ScaleDlg.h
+// Author : Sergey Kuul, Open CASCADE S.A.S.
+//
+#ifndef SMESHGUI_SCALEDLG_H
+#define SMESHGUI_SCALEDLG_H
+
+// SMESH includes
+#include "SMESH_SMESHGUI.hxx"
+#include "SMESHGUI_PreviewDlg.h"
+
+// IDL includes
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+
+class QButtonGroup;
+class QGroupBox;
+class QLabel;
+class QLineEdit;
+class QPushButton;
+class QRadioButton;
+class QCheckBox;
+class SMESHGUI;
+class SMESHGUI_IdValidator;
+class SMESHGUI_SpinBox;
+class SMESHGUI_FilterDlg;
+class SMESH_Actor;
+class SVTK_Selector;
+class LightApp_SelectionMgr;
+class SMESH_LogicalFilter;
+
+//=================================================================================
+// class    : SMESHGUI_ScaleDlg
+// purpose  :
+//=================================================================================
+class SMESHGUI_EXPORT SMESHGUI_ScaleDlg : public SMESHGUI_PreviewDlg
+{ 
+  Q_OBJECT
+
+public:
+  SMESHGUI_ScaleDlg( SMESHGUI* );
+  ~SMESHGUI_ScaleDlg();
+
+private:
+  void                   Init( bool = true );
+  void                   closeEvent( QCloseEvent* );
+  void                   enterEvent( QEvent* );           /* mouse enter the QWidget */
+  void                   hideEvent( QHideEvent* );        /* ESC key */
+  void                   keyPressEvent( QKeyEvent* );
+  int                    GetConstructorId();
+  void                   setNewMeshName();
+
+  bool                   isValid();
+  void                   getScale( SMESH::PointStruct& thePoint,
+                                   SMESH::double_array_var& theScaleFact);
+
+  SMESHGUI_IdValidator*  myIdValidator;
+  LightApp_SelectionMgr* mySelectionMgr;          /* User shape selection */
+  QString                myElementsId;
+  int                    myNbOkElements;          /* to check when elements are defined */
+
+  SVTK_Selector*         mySelector;
+
+  QWidget*               myEditCurrentArgument;
+
+  bool                   myBusy;
+  SMESH::SMESH_Mesh_var  myMesh;
+  SMESH_Actor*           myActor;
+  SMESH_LogicalFilter*   myMeshOrSubMeshOrGroupFilter;
+
+  SMESH::SMESH_IDSource_var mySelectedObject;
+
+  QGroupBox*             ConstructorsBox;
+  QButtonGroup*          GroupConstructors;
+  QRadioButton*          RadioButton1;
+  QRadioButton*          RadioButton2;
+  QGroupBox*             GroupButtons;
+  QPushButton*           buttonOk;
+  QPushButton*           buttonCancel;
+  QPushButton*           buttonApply;
+  QPushButton*           buttonHelp;
+  QGroupBox*             GroupArguments;
+  QLabel*                TextLabelElements;
+  QPushButton*           SelectElementsButton;
+  QLineEdit*             LineEditElements;
+  QCheckBox*             CheckBoxMesh;
+  QLabel*                TextLabel1;
+  QPushButton*           SelectButton1;
+  QLabel*                TextLabel1_1;
+  SMESHGUI_SpinBox*      SpinBox1_1;
+  QLabel*                TextLabel1_2;
+  SMESHGUI_SpinBox*      SpinBox1_2;
+  QLabel*                TextLabel1_3;
+  SMESHGUI_SpinBox*      SpinBox1_3;
+  QLabel*                TextLabel2;
+  SMESHGUI_SpinBox*      SpinBox_FX;
+  QLabel*                TextLabel3;
+  SMESHGUI_SpinBox*      SpinBox_FY;
+  QLabel*                TextLabel4;
+  SMESHGUI_SpinBox*      SpinBox_FZ;
+  QGroupBox*             ActionBox;
+  QButtonGroup*          ActionGroup;
+  QCheckBox*             MakeGroupsCheck;
+  QLineEdit*             LineEditNewMesh;
+
+  QString                myHelpFileName;
+
+  QPushButton*           myFilterBtn;
+  SMESHGUI_FilterDlg*    myFilterDlg;
+
+
+protected slots:
+  virtual void              onDisplaySimulation( bool );
+   
+private slots:
+  void                   ConstructorsClicked( int );
+  void                   ClickOnOk();
+  void                   ClickOnCancel();
+  bool                   ClickOnApply();
+  void                   ClickOnHelp();
+  void                   SetEditCurrentArgument();
+  void                   SelectionIntoArgument();
+  void                   DeactivateActiveDialog();
+  void                   ActivateThisDialog();
+  void                   onTextChange( const QString& );
+  void                   onSelectMesh( bool );
+  void                   onActionClicked( int );
+  void                   setFilters();
+};
+
+#endif // SMESHGUI_SCALEDLG_H
index e0e63d4cc60807bdef8d0c501944566e1f42ac94..8fff50e3ca6bd80df6765f8e38f7f5c948130ee1 100644 (file)
@@ -1,37 +1,41 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI_Selection
 // File   : SMESHGUI_Selection.cxx
 // Author : Alexander SOLOVYOV, Open CASCADE S.A.S.
-// SMESH includes
 //
+
+// SMESH includes
 #include "SMESHGUI_Selection.h"
 
 #include "SMESHGUI_Utils.h"
 #include "SMESHGUI_VTKUtils.h"
 #include "SMESHGUI_GEOMGenUtils.h"
+#include "SMESHGUI_ComputeDlg.h"
 
 #include <SMESH_Type.h>
 #include <SMESH_Actor.h>
+#include <SMESH_ScalarBarActor.h>
 
 // SALOME GUI includes
 #include <SalomeApp_Study.h>
@@ -85,7 +89,7 @@ void SMESHGUI_Selection::init( const QString& client, LightApp_SelectionMgr* mgr
 //function : processOwner
 //purpose  : 
 //=======================================================================
-void SMESHGUI_Selection::processOwner( const LightApp_DataOwner* ow )
+bool SMESHGUI_Selection::processOwner( const LightApp_DataOwner* ow )
 {
   const LightApp_SVTKDataOwner* owner =
     dynamic_cast<const LightApp_SVTKDataOwner*> ( ow );
@@ -93,6 +97,7 @@ void SMESHGUI_Selection::processOwner( const LightApp_DataOwner* ow )
     myActors.append( dynamic_cast<SMESH_Actor*>( owner->GetActor() ) );
   else
     myActors.append( 0 );
+  return true;
 }
 
 //=======================================================================
@@ -107,16 +112,21 @@ QVariant SMESHGUI_Selection::parameter( const int ind, const QString& p ) const
   else if ( p=="elemTypes" )     val = QVariant( elemTypes( ind ) );
   else if ( p=="isAutoColor" )   val = QVariant( isAutoColor( ind ) );
   else if ( p=="numberOfNodes" ) val = QVariant( numberOfNodes( ind ) );
+  else if ( p=="dim" )           val = QVariant( dim( ind ) );
   else if ( p=="labeledTypes" )  val = QVariant( labeledTypes( ind ) );
   else if ( p=="shrinkMode" )    val = QVariant( shrinkMode( ind ) );
   else if ( p=="entityMode" )    val = QVariant( entityMode( ind ) );
   else if ( p=="controlMode" )   val = QVariant( controlMode( ind ) );
+  else if ( p=="isNumFunctor" )  val = QVariant( isNumFunctor( ind ) );
   else if ( p=="displayMode" )   val = QVariant( displayMode( ind ) );
   else if ( p=="isComputable" )  val = QVariant( isComputable( ind ) );
+  else if ( p=="isPreComputable" )  val = QVariant( isPreComputable( ind ) );
   else if ( p=="hasReference" )  val = QVariant( hasReference( ind ) );
   else if ( p=="isImported" )    val = QVariant( isImported( ind ) );
   else if ( p=="facesOrientationMode" ) val = QVariant( facesOrientationMode( ind ) );
   else if ( p=="groupType" )     val = QVariant( groupType( ind ) );
+  else if ( p=="quadratic2DMode") val =  QVariant(quadratic2DMode(ind));
+  else if ( p=="isDistributionVisible") val = QVariant(isDistributionVisible(ind));
 
   if( val.isValid() )
     return val;
@@ -139,7 +149,7 @@ SMESH_Actor* SMESHGUI_Selection::getActor( int ind ) const
 
 //=======================================================================
 //function : elemTypes
-//purpose  : may return {'Edge' 'Face' 'Volume'} at most
+//purpose  : may return {'Elem0d' 'Edge' 'Face' 'Volume' 'BallElem'} at most
 //=======================================================================
 
 QList<QVariant> SMESHGUI_Selection::elemTypes( int ind ) const
@@ -149,6 +159,8 @@ QList<QVariant> SMESHGUI_Selection::elemTypes( int ind ) const
   if ( actor ) {
     TVisualObjPtr object = actor->GetObject();
     if ( object ) {
+      if ( object->GetNbEntities( SMDSAbs_0DElement )) types.append( "Elem0d" );
+      if ( object->GetNbEntities( SMDSAbs_Ball )) types.append( "BallElem" );
       if ( object->GetNbEntities( SMDSAbs_Edge )) types.append( "Edge" );
       if ( object->GetNbEntities( SMDSAbs_Face )) types.append( "Face" );
       if ( object->GetNbEntities( SMDSAbs_Volume )) types.append( "Volume" );
@@ -192,6 +204,34 @@ QString SMESHGUI_Selection::displayMode( int ind ) const
   return "Unknown";
 }
 
+
+//=======================================================================
+//function : quadratic2DMode
+//purpose  : return SMESH_Actor::EQuadratic2DRepresentation
+//=======================================================================
+QString SMESHGUI_Selection::quadratic2DMode( int ind ) const
+{
+  SMESH_Actor* actor = getActor( ind );
+  if ( actor ) {
+    switch( actor->GetQuadratic2DRepresentation() ) {
+    case SMESH_Actor::eLines:    return "eLines";
+    case SMESH_Actor::eArcs: return "eArcs";
+    default: break;
+    }
+  }
+  return "Unknown";
+}
+
+//=======================================================================
+//function : isDistributionVisible
+//purpose  : Visible/Invisible distribution of the ScalarBar Actor
+//=======================================================================
+
+bool SMESHGUI_Selection::isDistributionVisible(int ind) const {
+  SMESH_Actor* actor = getActor( ind );
+  return (actor && actor->GetScalarBarActor() && actor->GetScalarBarActor()->GetDistributionVisibility());
+} 
+
 //=======================================================================
 //function : shrinkMode
 //purpose  : return either 'IsSrunk', 'IsNotShrunk' or 'IsNotShrinkable'
@@ -210,7 +250,7 @@ QString SMESHGUI_Selection::shrinkMode( int ind ) const
 
 //=======================================================================
 //function : entityMode
-//purpose  : may return {'Edge' 'Face' 'Volume'} at most
+//purpose  : may return {'Elem0d' 'Edge' 'Face' 'Volume' 'BallElem' } at most
 //=======================================================================
 
 QList<QVariant> SMESHGUI_Selection::entityMode( int ind ) const
@@ -219,9 +259,11 @@ QList<QVariant> SMESHGUI_Selection::entityMode( int ind ) const
   SMESH_Actor* actor = getActor( ind );
   if ( actor ) {
     unsigned int aMode = actor->GetEntityMode();
-    if ( aMode & SMESH_Actor::eVolumes) types.append( "Volume");
-    if ( aMode & SMESH_Actor::eFaces  ) types.append( "Face"  );
-    if ( aMode & SMESH_Actor::eEdges  ) types.append( "Edge"  );
+    if ( aMode & SMESH_Actor::eVolumes    ) types.append( "Volume" );
+    if ( aMode & SMESH_Actor::eFaces      ) types.append( "Face"   );
+    if ( aMode & SMESH_Actor::eEdges      ) types.append( "Edge"   );
+    if ( aMode & SMESH_Actor::e0DElements ) types.append( "Elem0d" );
+    if ( aMode & SMESH_Actor::eBallElem ) types.append( "BallElem" );
   }
   return types;
 }
@@ -233,28 +275,69 @@ QList<QVariant> SMESHGUI_Selection::entityMode( int ind ) const
 
 QString SMESHGUI_Selection::controlMode( int ind ) const
 {
+  SMESH_Actor* actor = getActor( ind );
+  QString mode = "eNone";
+  if ( actor ) {
+    switch( actor->GetControlMode() ) {
+    case SMESH_Actor::eLength:                mode = "eLength";                break;
+    case SMESH_Actor::eLength2D:              mode = "eLength2D";              break;
+    case SMESH_Actor::eFreeEdges:             mode = "eFreeEdges";             break;
+    case SMESH_Actor::eFreeNodes:             mode = "eFreeNodes";             break;
+    case SMESH_Actor::eFreeBorders:           mode = "eFreeBorders";           break;
+    case SMESH_Actor::eFreeFaces:             mode = "eFreeFaces";             break;
+    case SMESH_Actor::eMultiConnection:       mode = "eMultiConnection";       break;
+    case SMESH_Actor::eMultiConnection2D:     mode = "eMultiConnection2D";     break;
+    case SMESH_Actor::eArea:                  mode = "eArea";                  break;
+    case SMESH_Actor::eVolume3D:              mode = "eVolume3D";              break;
+    case SMESH_Actor::eMaxElementLength2D:    mode = "eMaxElementLength2D";    break;
+    case SMESH_Actor::eMaxElementLength3D:    mode = "eMaxElementLength3D";    break;
+    case SMESH_Actor::eTaper:                 mode = "eTaper";                 break;
+    case SMESH_Actor::eAspectRatio:           mode = "eAspectRatio";           break;
+    case SMESH_Actor::eAspectRatio3D:         mode = "eAspectRatio3D";         break;
+    case SMESH_Actor::eMinimumAngle:          mode = "eMinimumAngle";          break;
+    case SMESH_Actor::eWarping:               mode = "eWarping";               break;
+    case SMESH_Actor::eSkew:                  mode = "eSkew";                  break;
+    case SMESH_Actor::eBareBorderFace:        mode = "eBareBorderFace";        break;
+    case SMESH_Actor::eBareBorderVolume:      mode = "eBareBorderVolume";      break;
+    case SMESH_Actor::eOverConstrainedFace:   mode = "eOverConstrainedFace";   break;
+    case SMESH_Actor::eOverConstrainedVolume: mode = "eOverConstrainedVolume"; break;
+    case SMESH_Actor::eCoincidentNodes:       mode = "eCoincidentNodes";       break;
+    case SMESH_Actor::eCoincidentElems1D:     mode = "eCoincidentElems1D";     break;
+    case SMESH_Actor::eCoincidentElems2D:     mode = "eCoincidentElems2D";     break;
+    case SMESH_Actor::eCoincidentElems3D:     mode = "eCoincidentElems3D";     break;
+    default:break;
+    }
+  }
+  return mode;
+}
+
+bool SMESHGUI_Selection::isNumFunctor( int ind ) const
+{
+  bool result = false;
   SMESH_Actor* actor = getActor( ind );
   if ( actor ) {
     switch( actor->GetControlMode() ) {
-    case SMESH_Actor::eLength:            return "eLength";
-    case SMESH_Actor::eLength2D:          return "eLength2D";
-    case SMESH_Actor::eFreeEdges:         return "eFreeEdges";
-    case SMESH_Actor::eFreeBorders:       return "eFreeBorders";
-    case SMESH_Actor::eFreeFaces:         return "eFreeFaces";
-    case SMESH_Actor::eMultiConnection:   return "eMultiConnection";
-    case SMESH_Actor::eMultiConnection2D: return "eMultiConnection2D";
-    case SMESH_Actor::eArea:              return "eArea";
-    case SMESH_Actor::eVolume3D:          return "eVolume3D";
-    case SMESH_Actor::eTaper:             return "eTaper";
-    case SMESH_Actor::eAspectRatio:       return "eAspectRatio";
-    case SMESH_Actor::eAspectRatio3D:     return "eAspectRatio3D";
-    case SMESH_Actor::eMinimumAngle:      return "eMinimumAngle";
-    case SMESH_Actor::eWarping:           return "eWarping";
-    case SMESH_Actor::eSkew:              return "eSkew";
-    default:;
+    case SMESH_Actor::eLength:
+    case SMESH_Actor::eLength2D:
+    case SMESH_Actor::eMultiConnection:
+    case SMESH_Actor::eMultiConnection2D:
+    case SMESH_Actor::eArea:
+    case SMESH_Actor::eVolume3D:
+    case SMESH_Actor::eMaxElementLength2D:
+    case SMESH_Actor::eMaxElementLength3D:
+    case SMESH_Actor::eTaper:
+    case SMESH_Actor::eAspectRatio:
+    case SMESH_Actor::eAspectRatio3D:
+    case SMESH_Actor::eMinimumAngle:
+    case SMESH_Actor::eWarping:
+    case SMESH_Actor::eSkew:
+      result = true;
+      break;
+    default:
+      break;
     }
   }
-  return "eNone";
+  return result;
 }
 
 //=======================================================================
@@ -321,6 +404,42 @@ int SMESHGUI_Selection::numberOfNodes( int ind ) const
   return 0;
 }
 
+//================================================================================
+/*!
+ * \brief return dimension of elements of the selected object
+ *
+ *  \retval int - 0 for 0D elements, -1 for an empty object (the rest as usual)
+ */
+//================================================================================
+
+int SMESHGUI_Selection::dim( int ind ) const
+{
+  int dim = -1;
+  if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
+  {
+    _PTR(SObject) sobj = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
+    CORBA::Object_var obj = SMESH::SObjectToObject( sobj, SMESH::GetActiveStudyDocument() );
+
+    if ( ! CORBA::is_nil( obj )) {
+      SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( obj );
+      if ( ! idSrc->_is_nil() )
+      {
+        SMESH::array_of_ElementType_var types = idSrc->GetTypes();
+        for ( int i = 0; i < types->length(); ++ i)
+          switch ( types[i] ) {
+          case SMESH::EDGE  : dim = std::max( dim, 1 ); break;
+          case SMESH::FACE  : dim = std::max( dim, 2 ); break;
+          case SMESH::VOLUME: dim = std::max( dim, 3 ); break;
+          case SMESH::ELEM0D: dim = std::max( dim, 0 ); break;
+          case SMESH::BALL  : dim = std::max( dim, 0 ); break;
+          default:;
+          }
+      }
+    }
+  }
+  return dim;
+}
+
 //=======================================================================
 //function : isComputable
 //purpose  : 
@@ -336,7 +455,7 @@ QVariant SMESHGUI_Selection::isComputable( int ind ) const
       SMESH::SMESH_Mesh_var mesh = SMESH::GetMeshByIO(io); // m,sm,gr->m
       if ( !mesh->_is_nil() ) {*/
         _PTR(SObject) so = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
-       //FindSObject( mesh );
+        //FindSObject( mesh );
         if ( so ) {
           CORBA::Object_var obj = SMESH::SObjectToObject(so, SMESH::GetActiveStudyDocument());
           if(!CORBA::is_nil(obj)){
@@ -364,6 +483,23 @@ QVariant SMESHGUI_Selection::isComputable( int ind ) const
   return QVariant( false );
 }
 
+//=======================================================================
+//function : isPreComputable
+//purpose  : 
+//=======================================================================
+
+QVariant SMESHGUI_Selection::isPreComputable( int ind ) const
+{
+  if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
+  {
+    QMap<int,int> modeMap;
+    _PTR(SObject) pMesh = SMESH::GetActiveStudyDocument()->FindObjectID( entry( ind ).toLatin1().data() );
+    SMESHGUI_PrecomputeOp::getAssignedAlgos( pMesh, modeMap );
+    return QVariant( modeMap.size() > 1 );
+  }
+  return QVariant( false );
+}
+
 //=======================================================================
 //function : hasReference
 //purpose  : 
@@ -387,7 +523,7 @@ QVariant SMESHGUI_Selection::isVisible( int ind ) const
     SMESH_Actor* actor = SMESH::FindActorByEntry( ent.toLatin1().data() );
     if ( actor && actor->hasIO() ) {
       if(SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView())
-       return QVariant( aViewWindow->isVisible( actor->getIO() ) );
+        return QVariant( aViewWindow->isVisible( actor->getIO() ) );
     }
   }
   return QVariant( false );
@@ -512,7 +648,6 @@ bool SMESHGUI_Selection::isImported( const int ind ) const
   QString e = entry( ind );
   _PTR(SObject) SO = SMESH::GetActiveStudyDocument()->FindObjectID( e.toLatin1().constData() );
   bool res = false;
-  /*
   if( SO )
   {
     SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( SMESH::SObjectToObject( SO ) );
@@ -522,7 +657,6 @@ bool SMESHGUI_Selection::isImported( const int ind ) const
       res = strlen( (char*)inf->fileName ) > 0;
     }
   }
-  */
   return res;
 }
 
@@ -535,17 +669,19 @@ QString SMESHGUI_Selection::groupType( int ind ) const
 {
   QString e = entry( ind );
   _PTR(SObject) SO = SMESH::GetActiveStudyDocument()->FindObjectID( e.toLatin1().constData() );
-  QString type;
   if( SO )
   {
-    CORBA::Object_var obj = SMESH::SObjectToObject( SO );
-  
-    SMESH::SMESH_Group_var aGroup = SMESH::SMESH_Group::_narrow( obj );
-    SMESH::SMESH_GroupOnGeom_var aGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow( obj );
-    if( !aGroup->_is_nil() )
-      type = QString( "Group" );
-    else if ( !aGroupOnGeom->_is_nil() )
-      type = QString( "GroupOnGeom" );
+    SMESH::SMESH_Group_var g = SMESH::SObjectToInterface<SMESH::SMESH_Group>( SO );
+    if( !g->_is_nil() )
+      return "Group";
+
+    SMESH::SMESH_GroupOnGeom_var gog = SMESH::SObjectToInterface<SMESH::SMESH_GroupOnGeom>( SO );
+    if( !gog->_is_nil() )
+      return "GroupOnGeom";
+
+    SMESH::SMESH_GroupOnFilter_var gof = SMESH::SObjectToInterface<SMESH::SMESH_GroupOnFilter>(SO);
+    if ( !gof->_is_nil() )
+      return "GroupOnFilter";
   }
-  return type;
+  return "";
 }
index 72ed58cb4cff0e9cc0926018eed6839a3f41f17d..82293358c75018f3c7c49bae3c12aaba6aaa51cc 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI_Selection
 // File   : SMESHGUI_Selection.h
 // Author : Alexander SOLOVYOV, Open CASCADE S.A.S.
@@ -48,15 +49,21 @@ public:
 
   virtual void            init( const QString&, LightApp_SelectionMgr* );
   virtual QVariant        parameter( const int, const QString& ) const;
-  virtual void            processOwner( const LightApp_DataOwner* );
+  virtual bool            processOwner( const LightApp_DataOwner* );
 
   // got from object, not from actor
   virtual bool            isAutoColor( int ) const;
   virtual int             numberOfNodes( int ) const;
+  virtual int             dim( int ) const;
   virtual QVariant        isComputable( int ) const;
+  virtual QVariant        isPreComputable( int ) const;
   virtual QVariant        hasReference( int ) const;
   virtual QVariant        isVisible( int ) const;
 
+  virtual QString         quadratic2DMode(int ) const;
+
+  virtual bool            isDistributionVisible(int ) const;
+
   // parameters got from actor return nothing if an actor is not visible
   virtual QList<QVariant> elemTypes( int ) const;
   virtual QList<QVariant> labeledTypes( int ) const;
@@ -64,6 +71,7 @@ public:
   virtual QString         shrinkMode( int ) const;
   virtual QList<QVariant> entityMode( int ) const;
   virtual QString         controlMode( int ) const;
+  virtual bool            isNumFunctor( int ) const;
   virtual QString         facesOrientationMode( int ) const;
   virtual QString         groupType( int ) const;
   
index 1cb2fc21363612b403fc894b370c47aac196fe55..7e4039a3aa647b3e142ffb9dd7b45e18529e20e9 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : SMESHGUI_SelectionOp.cxx
 // Author : Alexander SOLOVYOV, Open CASCADE S.A.S.
 // SMESH includes
@@ -423,9 +424,9 @@ void SMESHGUI_SelectionOp::selected( QStringList& names,
       SalomeApp_Study* _study = dynamic_cast<SalomeApp_Study*>( study() );
       if( _study )
       {
-       _PTR(SObject) obj = _study->studyDS()->FindObjectID( anIt.Value()->getEntry() );
-       if( obj )
-         names.append( obj->GetName().c_str() );
+        _PTR(SObject) obj = _study->studyDS()->FindObjectID( anIt.Value()->getEntry() );
+        if( obj )
+          names.append( obj->GetName().c_str() );
       }
     }
   }
index 34e5e11356d1291602300da203ee7c1b158ae553..874bcea222a1351c808778b9094de54e191c5336 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : SMESHGUI_SelectionOp.h
 // Author : Alexander SOLOVYOV, Open CASCADE S.A.S.
 //
@@ -103,18 +104,18 @@ protected:
 
   //! Hilight object in VTK viewer
   void                          highlight( const Handle( SALOME_InteractiveObject )&,
-                                          const bool, const bool = true );
+                                           const bool, const bool = true );
                                
   //! Select some nodes or elements in VTK
   void                          addOrRemoveIndex( const Handle( SALOME_InteractiveObject )&,
-                                                 const TColStd_MapOfInteger&, const bool );
+                                                  const TColStd_MapOfInteger&, const bool isModeShift);
 
   SVTK_ViewWindow*              viewWindow() const;
   SVTK_Selector*                selector() const;
 
   //! Get names, types and ids of selected objects
   virtual void                  selected( QStringList&, 
-                                         SMESHGUI_Dialog::TypesList&, QStringList& ) const;
+                                          SMESHGUI_Dialog::TypesList&, QStringList& ) const;
 
   //! Find type by id
   virtual int                   typeById( const QString&, const EntityType ) const;
index 1017b19e98d54e2370136b870d5db8c495260948..24d85f012f425fbd6ce5adeb30a1122a9f91af1d 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_SewingDlg.cxx
 // Author : Michael ZORIN, Open CASCADE S.A.S.
@@ -385,9 +386,9 @@ void SMESHGUI_SewingDlg::ConstructorsClicked (int constructorId)
       LineEdit5->setEnabled(false);
 
       if (!CheckBoxPolygons->isVisible())
-       CheckBoxPolygons->show();
+        CheckBoxPolygons->show();
       if (!CheckBoxPolyedrs->isVisible())
-       CheckBoxPolyedrs->show();
+        CheckBoxPolyedrs->show();
       
       myOk5 = true;
 
@@ -412,7 +413,7 @@ void SMESHGUI_SewingDlg::ConstructorsClicked (int constructorId)
       SMESH::SetPointRepresentation(false);
 
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-       aViewWindow->SetSelectionMode(CellSelection);
+        aViewWindow->SetSelectionMode(CellSelection);
       break;
     }
   }
@@ -439,7 +440,7 @@ void SMESHGUI_SewingDlg::ConstructorsClicked (int constructorId)
 
   QApplication::instance()->processEvents();
   updateGeometry();
-  resize( minimumSize() );
+  resize(100,100);
 }
 
 //=================================================================================
@@ -472,8 +473,8 @@ bool SMESHGUI_SewingDlg::ClickOnApply()
                                               LineEdit4->text().toLong(),
                                               LineEdit5->text().toLong(),
                                               LineEdit6->text().toLong(),
-                                             toCreatePolygons,
-                                             toCreatePolyedrs);
+                                              toCreatePolygons,
+                                              toCreatePolyedrs);
       else if (aConstructorId == 1)
         anError = aMeshEditor->SewConformFreeBorders(LineEdit1->text().toLong(),
                                                      LineEdit2->text().toLong(),
@@ -486,8 +487,8 @@ bool SMESHGUI_SewingDlg::ClickOnApply()
                                                LineEdit3->text().toLong(),
                                                LineEdit4->text().toLong(),
                                                LineEdit6->text().toLong(),
-                                              toCreatePolygons,
-                                              toCreatePolyedrs);
+                                               toCreatePolygons,
+                                               toCreatePolyedrs);
       else if (aConstructorId == 3) {
         QStringList aListElementsId1 = LineEdit1->text().split(" ", QString::SkipEmptyParts);
         QStringList aListElementsId2 = LineEdit4->text().split(" ", QString::SkipEmptyParts);
@@ -532,6 +533,8 @@ bool SMESHGUI_SewingDlg::ClickOnApply()
 
       Init();
       ConstructorsClicked(GetConstructorId());
+
+      SMESHGUI::Modified();
     }
   }
 
@@ -580,10 +583,10 @@ void SMESHGUI_SewingDlg::ClickOnHelp()
     platform = "application";
 #endif
     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser", 
-                                                                platform)).
-                            arg(myHelpFileName));
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser", 
+                                                                 platform)).
+                             arg(myHelpFileName));
   }
 }
 
@@ -632,15 +635,15 @@ void SMESHGUI_SewingDlg::onTextChange (const QString& theNewText)
       SMESH::SetPointRepresentation(true);
 
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-       aViewWindow->SetSelectionMode(NodeSelection);
+        aViewWindow->SetSelectionMode(NodeSelection);
 
       const SMDS_MeshNode * n = aMesh->FindNode(theNewText.toInt());
       if (n) {
-       newIndices.Add(n->GetID());
-       mySelector->AddOrRemoveIndex(myActor->getIO(), newIndices, false);
-       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-         aViewWindow->highlight( myActor->getIO(), true, true );
-       
+        newIndices.Add(n->GetID());
+        mySelector->AddOrRemoveIndex(myActor->getIO(), newIndices, false);
+        if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+          aViewWindow->highlight( myActor->getIO(), true, true );
+        
         if      (send == LineEdit1)
           myOk1 = true;
         else if (send == LineEdit2)
@@ -658,7 +661,7 @@ void SMESHGUI_SewingDlg::onTextChange (const QString& theNewText)
       SMESH::SetPointRepresentation(false);
 
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-       aViewWindow->SetSelectionMode(CellSelection);
+        aViewWindow->SetSelectionMode(CellSelection);
 
       QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
 
@@ -667,8 +670,8 @@ void SMESHGUI_SewingDlg::onTextChange (const QString& theNewText)
       for (int i = 0; i < aListId.count(); i++) {
         const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt());
         if (e) 
-         newIndices.Add(e->GetID());
-       
+          newIndices.Add(e->GetID());
+        
           if (!isEvenOneExists)
             isEvenOneExists = true;
       }
@@ -676,7 +679,7 @@ void SMESHGUI_SewingDlg::onTextChange (const QString& theNewText)
 
       mySelector->AddOrRemoveIndex(myActor->getIO(), newIndices, false);
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-       aViewWindow->highlight( myActor->getIO(), true, true );
+        aViewWindow->highlight( myActor->getIO(), true, true );
       
       if (isEvenOneExists) {
         if (send == LineEdit1)
index d21d1b5738c9d58fe5f9c5f0cc06c7918194af65..f8ff617d0a8b1b3e76b58ee3d6354e0bf00c6af9 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_SewingDlg.h
 // Author : Michael ZORIN, Open CASCADE S.A.S.
index 82352334b7f4953197a3766ba5b70383b928f04e..940dd4f3ea43f0f0b0e6398a48ec40bb60c9d8b9 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : SMESHGUI_ShapeByMeshDlg.cxx
 // Author : Edward AGAPOV, Open CASCADE S.A.S.
 // SMESH includes
@@ -129,7 +130,7 @@ QFrame* SMESHGUI_ShapeByMeshDlg::createMainFrame (QWidget* theParent)
   QLabel* anIdLabel = new QLabel( tr("ELEMENT_ID"), aMainGrp );
   myElementId = new QLineEdit( aMainGrp );
   myElementId->setValidator( new SMESHGUI_IdValidator( theParent, 
-                                                      !myIsMultipleAllowed ? 1 : 0 ) ); // 0 for any number of entities
+                                                       !myIsMultipleAllowed ? 1 : 0 ) ); // 0 for any number of entities
 
   // shape name
   QLabel* aNameLabel = new QLabel( tr("GEOMETRY_NAME"), aMainGrp );
@@ -250,36 +251,36 @@ void SMESHGUI_ShapeByMeshOp::SetMesh (SMESH::SMESH_Mesh_ptr thePtr)
       int shapeDim = 0; // max dim with several shapes
       //if ( /*mySelectionMgr*/ selectionMgr()->isOk(anIObj) ) // check that the mesh has a valid shape
       {
-       _PTR(SObject) aSO = SMESH::FindSObject(myMesh.in());
-       GEOM::GEOM_Object_var mainShape = SMESH::GetGeom(aSO);
-       if ( !mainShape->_is_nil() ) 
-         {
-           TopoDS_Shape aShape;
-           if ( GEOMBase::GetShape(mainShape, aShape))
-             {
-               TopAbs_ShapeEnum types[4] = { TopAbs_EDGE, TopAbs_FACE, TopAbs_SHELL, TopAbs_SOLID };
-               for ( int dim = 4; dim > 0; --dim ) {
-                 TopAbs_ShapeEnum type = types[ dim - 1 ];
-                 TopAbs_ShapeEnum avoid = ( type == TopAbs_SHELL ) ? TopAbs_SOLID : TopAbs_SHAPE;
-                 TopExp_Explorer exp( aShape, type, avoid );
-                 for ( ; nbShapes[ type ] < 2 && exp.More(); exp.Next() )
-                   ++nbShapes[ type ];
-                 if ( nbShapes[ type ] > 1 ) {
-                   shapeDim = dim;
-                   break;
-                 }
-               }
-             }
-         }
+        _PTR(SObject) aSO = SMESH::FindSObject(myMesh.in());
+        GEOM::GEOM_Object_var mainShape = SMESH::GetGeom(aSO);
+        if ( !mainShape->_is_nil() ) 
+          {
+            TopoDS_Shape aShape;
+            if ( GEOMBase::GetShape(mainShape, aShape))
+              {
+                TopAbs_ShapeEnum types[4] = { TopAbs_EDGE, TopAbs_FACE, TopAbs_SHELL, TopAbs_SOLID };
+                for ( int dim = 4; dim > 0; --dim ) {
+                  TopAbs_ShapeEnum type = types[ dim - 1 ];
+                  TopAbs_ShapeEnum avoid = ( type == TopAbs_SHELL ) ? TopAbs_SOLID : TopAbs_SHAPE;
+                  TopExp_Explorer exp( aShape, type, avoid );
+                  for ( ; nbShapes[ type ] < 2 && exp.More(); exp.Next() )
+                    ++nbShapes[ type ];
+                  if ( nbShapes[ type ] > 1 ) {
+                    shapeDim = dim;
+                    break;
+                  }
+                }
+              }
+          }
       }
       if (shapeDim > 0)
-       {
-         if ( nbShapes[ TopAbs_SHELL ] + nbShapes[ TopAbs_SOLID ] > 1 )
-           shapeDim = 3;
-         hasElement[ EDGE ]   = shapeDim > 0 && myMesh->NbEdges();
-         hasElement[ FACE ]   = shapeDim > 1 && myMesh->NbFaces();
-         hasElement[ VOLUME ] = shapeDim > 2 && myMesh->NbVolumes();
-       }
+        {
+          if ( nbShapes[ TopAbs_SHELL ] + nbShapes[ TopAbs_SOLID ] > 1 )
+            shapeDim = 3;
+          hasElement[ EDGE ]   = shapeDim > 0 && myMesh->NbEdges();
+          hasElement[ FACE ]   = shapeDim > 1 && myMesh->NbFaces();
+          hasElement[ VOLUME ] = shapeDim > 2 && myMesh->NbVolumes();
+        }
       myHasSolids = nbShapes[ TopAbs_SOLID ];
     }
 
@@ -306,83 +307,83 @@ void SMESHGUI_ShapeByMeshOp::commitOperation()
     QStringList aListId = myDlg->myElementId->text().split( " ", QString::SkipEmptyParts);
     if (aListId.count() == 1)
       {
-       int elemID = (aListId.first()).toInt();
-       myGeomObj = GEOM::GEOM_Object::_duplicate(
-           SMESHGUI::GetSMESHGen()->GetGeometryByMeshElement
-         ( myMesh.in(), elemID, myDlg->myGeomName->text().toLatin1().constData()) );
+        int elemID = (aListId.first()).toInt();
+        myGeomObj = GEOM::GEOM_Object::_duplicate(
+            SMESHGUI::GetSMESHGen()->GetGeometryByMeshElement
+          ( myMesh.in(), elemID, myDlg->myGeomName->text().toLatin1().constData()) );
       }
     else
       {
-       GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen();
-       _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
-       
-       if (geomGen->_is_nil() || !aStudy)
-         return;
-       
-       GEOM::GEOM_IShapesOperations_var aShapesOp =
-         geomGen->GetIShapesOperations(aStudy->StudyId());
-       if (aShapesOp->_is_nil() )
-         return;
-       
-       TopAbs_ShapeEnum aGroupType = TopAbs_SHAPE;
-       
-       std::map<double, GEOM::GEOM_Object_var> aGeomObjectsMap;
-       GEOM::GEOM_Object_var aGeomObject;
-
-       GEOM::GEOM_Object_var aMeshShape = myMesh->GetShapeToMesh();
-       
-       for ( int i = 0; i < aListId.count(); i++ )
-         {
-           aGeomObject =
-             SMESHGUI::GetSMESHGen()->FindGeometryByMeshElement(myMesh.in(), aListId[i].toInt());
-
-           if (aGeomObject->_is_nil()) continue;
-           
-           double anId = aShapesOp->GetSubShapeIndex(aMeshShape, aGeomObject);
-           if (aShapesOp->IsDone() && aGeomObjectsMap.find(anId) == aGeomObjectsMap.end())
-             {
-               aGeomObjectsMap[anId] = aGeomObject;
-
-               TopAbs_ShapeEnum aSubShapeType = (TopAbs_ShapeEnum)aGeomObject->GetShapeType();
-               if (i == 0)
-                 aGroupType = aSubShapeType;
-               else if (aSubShapeType != aGroupType)
-                 aGroupType = TopAbs_SHAPE;
-             }
-         }
-       
-       int aNumberOfGO = aGeomObjectsMap.size();
-       if (aNumberOfGO == 1)
-         myGeomObj = (*aGeomObjectsMap.begin()).second;
-       else if (aNumberOfGO > 1)
-         {
-           GEOM::GEOM_IGroupOperations_var aGroupOp =
-             geomGen->GetIGroupOperations(aStudy->StudyId());
-           if(aGroupOp->_is_nil())
-             return;
-           
-           GEOM::ListOfGO_var aGeomObjects = new GEOM::ListOfGO();
-           aGeomObjects->length( aNumberOfGO );
-
-           int i = 0;
-           std::map<double, GEOM::GEOM_Object_var>::iterator anIter;
-           for (anIter = aGeomObjectsMap.begin(); anIter!=aGeomObjectsMap.end(); anIter++)
-             aGeomObjects[i++] = (*anIter).second;
-         
-           //create geometry group
-           myGeomObj = aGroupOp->CreateGroup(aMeshShape, aGroupType);
-           aGroupOp->UnionList(myGeomObj, aGeomObjects);
-
-           if (!aGroupOp->IsDone())
-             return;
-         }
-       
-       // publish the GEOM object in study
-       QString aNewGeomGroupName ( myDlg->myGeomName->text() );
-         
-       SALOMEDS::SObject_var aNewGroupSO =
-         geomGen->AddInStudy(SMESHGUI::GetSMESHGen()->GetCurrentStudy(), myGeomObj, 
-                             aNewGeomGroupName.toLatin1().data(), aMeshShape);
+        GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen();
+        _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
+        
+        if (geomGen->_is_nil() || !aStudy)
+          return;
+        
+        GEOM::GEOM_IShapesOperations_var aShapesOp =
+          geomGen->GetIShapesOperations(aStudy->StudyId());
+        if (aShapesOp->_is_nil() )
+          return;
+        
+        TopAbs_ShapeEnum aGroupType = TopAbs_SHAPE;
+        
+        std::map<double, GEOM::GEOM_Object_var> aGeomObjectsMap;
+        GEOM::GEOM_Object_var aGeomObject;
+
+        GEOM::GEOM_Object_var aMeshShape = myMesh->GetShapeToMesh();
+        
+        for ( int i = 0; i < aListId.count(); i++ )
+          {
+            aGeomObject =
+              SMESHGUI::GetSMESHGen()->FindGeometryByMeshElement(myMesh.in(), aListId[i].toInt());
+
+            if (aGeomObject->_is_nil()) continue;
+            
+            double anId = aShapesOp->GetSubShapeIndex(aMeshShape, aGeomObject);
+            if (aShapesOp->IsDone() && aGeomObjectsMap.find(anId) == aGeomObjectsMap.end())
+              {
+                aGeomObjectsMap[anId] = aGeomObject;
+
+                TopAbs_ShapeEnum aSubShapeType = (TopAbs_ShapeEnum)aGeomObject->GetShapeType();
+                if (i == 0)
+                  aGroupType = aSubShapeType;
+                else if (aSubShapeType != aGroupType)
+                  aGroupType = TopAbs_SHAPE;
+              }
+          }
+        
+        int aNumberOfGO = aGeomObjectsMap.size();
+        if (aNumberOfGO == 1)
+          myGeomObj = (*aGeomObjectsMap.begin()).second;
+        else if (aNumberOfGO > 1)
+          {
+            GEOM::GEOM_IGroupOperations_var aGroupOp =
+              geomGen->GetIGroupOperations(aStudy->StudyId());
+            if(aGroupOp->_is_nil())
+              return;
+            
+            GEOM::ListOfGO_var aGeomObjects = new GEOM::ListOfGO();
+            aGeomObjects->length( aNumberOfGO );
+
+            int i = 0;
+            std::map<double, GEOM::GEOM_Object_var>::iterator anIter;
+            for (anIter = aGeomObjectsMap.begin(); anIter!=aGeomObjectsMap.end(); anIter++)
+              aGeomObjects[i++] = (*anIter).second;
+          
+            //create geometry group
+            myGeomObj = aGroupOp->CreateGroup(aMeshShape, aGroupType);
+            aGroupOp->UnionList(myGeomObj, aGeomObjects);
+
+            if (!aGroupOp->IsDone())
+              return;
+          }
+        
+        // publish the GEOM object in study
+        QString aNewGeomGroupName ( myDlg->myGeomName->text() );
+          
+        SALOMEDS::SObject_var aNewGroupSO =
+          geomGen->AddInStudy(SMESHGUI::GetSMESHGen()->GetCurrentStudy(), myGeomObj, 
+                              aNewGeomGroupName.toLatin1().data(), aMeshShape);
       }
   }
   catch (const SALOME::SALOME_Exception& S_ex) {
@@ -422,7 +423,7 @@ void SMESHGUI_ShapeByMeshOp::onSelectionDone()
                                                    aList.First(), aString);
     if (nbElems > 0) {
       if (!myIsMultipleAllowed && nbElems != 1 )
-       return;
+        return;
       setElementID( aString );
       myDlg->setButtonEnabled( true, QtxDialog::OK );
     }
@@ -485,31 +486,31 @@ void SMESHGUI_ShapeByMeshOp::onElemIdChanged(const QString& theNewText)
     {
       if ( SMDS_Mesh* aMesh = actor->GetObject()->GetMesh() )
       {
-       SMDSAbs_ElementType type = SMDSAbs_Edge;
-       switch ( myDlg->myElemTypeGroup->checkedId() ) {
-       case EDGE  : type = SMDSAbs_Edge;   break;
-       case FACE  : type = SMDSAbs_Face;   break;
-       case VOLUME: type = SMDSAbs_Volume; break;
-       default: return;
-       }
-       TColStd_MapOfInteger newIndices;
-       QStringList aListId = theNewText.split( " ", QString::SkipEmptyParts);
-       for ( int i = 0; i < aListId.count(); i++ ) {
-         if ( const SMDS_MeshElement * e = aMesh->FindElement( aListId[ i ].toInt() ))
-           if ( e->GetType() == type )
-             newIndices.Add( e->GetID() );
-       }
-       
-       if ( !newIndices.IsEmpty() )
-       {
-         if (!myIsMultipleAllowed && newIndices.Extent() != 1)
-           return;
-         if ( SVTK_Selector* s = selector() ) {
-           s->AddOrRemoveIndex( actor->getIO(), newIndices, false );
-           viewWindow()->highlight( actor->getIO(), true, true );
-           myDlg->setButtonEnabled( true, QtxDialog::OK );
-         }
-       }
+        SMDSAbs_ElementType type = SMDSAbs_Edge;
+        switch ( myDlg->myElemTypeGroup->checkedId() ) {
+        case EDGE  : type = SMDSAbs_Edge;   break;
+        case FACE  : type = SMDSAbs_Face;   break;
+        case VOLUME: type = SMDSAbs_Volume; break;
+        default: return;
+        }
+        TColStd_MapOfInteger newIndices;
+        QStringList aListId = theNewText.split( " ", QString::SkipEmptyParts);
+        for ( int i = 0; i < aListId.count(); i++ ) {
+          if ( const SMDS_MeshElement * e = aMesh->FindElement( aListId[ i ].toInt() ))
+            if ( e->GetType() == type )
+              newIndices.Add( e->GetID() );
+        }
+        
+        if ( !newIndices.IsEmpty() )
+        {
+          if (!myIsMultipleAllowed && newIndices.Extent() != 1)
+            return;
+          if ( SVTK_Selector* s = selector() ) {
+            s->AddOrRemoveIndex( actor->getIO(), newIndices, false );
+            viewWindow()->highlight( actor->getIO(), true, true );
+            myDlg->setButtonEnabled( true, QtxDialog::OK );
+          }
+        }
       }
     }
   }
index 51f74b810b863f378d8fff01beb4c5c164571bea..63477e34c0b608646e751e5e157b5189a148b971 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : SMESHGUI_ShapeByMeshDlg.h
 // Author : Edward AGAPOV, Open CASCADE S.A.S.
 //
index 6a27b17a337f9e4003e8abe4f74cc0847d8520e5..f93ce95565ca740eaef14420091c6bd91cf8bf83 100755 (executable)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : SMESHGUI_SingleEditDlg.cxx
 // Author : Sergey LITONIN, Open CASCADE S.A.S.
 // SMESH includes
@@ -278,10 +279,10 @@ void SMESHGUI_SingleEditDlg::onHelp()
     platform = "application";
 #endif
     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser", 
-                                                                platform)).
-                            arg(myHelpFileName));
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser", 
+                                                                 platform)).
+                             arg(myHelpFileName));
   }
 }
 
@@ -312,12 +313,14 @@ static bool findTriangles (const SMDS_MeshNode *    theNode1,
     const SMDS_MeshElement* elem = it->next();
     if (elem->GetType() == SMDSAbs_Face &&
          emap.find(elem) != emap.end())
+    {
       if (theTria1) {
         theTria2 = elem;
         break;
       } else {
         theTria1 = elem;
       }
+    }
   }
   return (theTria1 && theTria2);
 }
@@ -348,13 +351,13 @@ void SMESHGUI_SingleEditDlg::onTextChange (const QString& theNewText)
 
       int id1, id2;
       if ( !getNodeIds(myEdge->text(), id1, id2) )
-       return;
+        return;
 
       const SMDS_MeshNode* aNode1 = aMesh->FindNode( id1 );
       const SMDS_MeshNode* aNode2 = aMesh->FindNode( id2 );
 
       if ( !aNode1 || !aNode2 || aNode1 == aNode2 )
-       return;
+        return;
 
       // find a triangle and an edge index
       const SMDS_MeshElement* tria1;
@@ -362,23 +365,23 @@ void SMESHGUI_SingleEditDlg::onTextChange (const QString& theNewText)
 
       if ( findTriangles(aNode1,aNode2,tria1,tria2) )
       {
-       newIndices.Add(tria1->GetID());
-
-       const SMDS_MeshNode* a3Nodes[3];
-       SMDS_ElemIteratorPtr it;
-       int edgeInd = 2, i;
-       for (i = 0, it = tria1->nodesIterator(); it->more(); i++) {
-         a3Nodes[ i ] = static_cast<const SMDS_MeshNode*>(it->next());
-         if (i > 0 && ( a3Nodes[ i ] == aNode1 && a3Nodes[ i - 1] == aNode2 ||
-                        a3Nodes[ i ] == aNode2 && a3Nodes[ i - 1] == aNode1 ) ) {
-           edgeInd = i - 1;
-           break;
-         }
-       }
-       newIndices.Add(-edgeInd-1);
-       
-       myOkBtn->setEnabled(true);
-       myApplyBtn->setEnabled(true);
+        newIndices.Add(tria1->GetID());
+
+        const SMDS_MeshNode* a3Nodes[3];
+        SMDS_ElemIteratorPtr it;
+        int edgeInd = 2, i;
+        for (i = 0, it = tria1->nodesIterator(); it->more(); i++) {
+          a3Nodes[ i ] = static_cast<const SMDS_MeshNode*>(it->next());
+          if (i > 0 && ( (a3Nodes[ i ] == aNode1 && a3Nodes[ i - 1] == aNode2) ||
+                         (a3Nodes[ i ] == aNode2 && a3Nodes[ i - 1] == aNode1) ) ) {
+            edgeInd = i - 1;
+            break;
+          }
+        }
+        newIndices.Add(-edgeInd-1);
+        
+        myOkBtn->setEnabled(true);
+        myApplyBtn->setEnabled(true);
       }
       mySelector->AddOrRemoveIndex(anIO,newIndices, false);
       SMESH::GetViewWindow(mySMESHGUI)->highlight( anIO, true, true );
@@ -416,17 +419,17 @@ void SMESHGUI_SingleEditDlg::onSelectionDone()
     {
       const SMDS_MeshElement* tria[2];
       if( SMESH::GetEdgeNodes( mySelector, aVisualObj, anId1, anId2 ) >= 1 &&
-         findTriangles( aMesh->FindNode( anId1 ), aMesh->FindNode( anId2 ), tria[0],tria[1] ) )
+          findTriangles( aMesh->FindNode( anId1 ), aMesh->FindNode( anId2 ), tria[0],tria[1] ) )
       {
-       QString aText = QString("%1-%2").arg(anId1).arg(anId2);
-       myEdge->setText(aText);
-       
-       myOkBtn->setEnabled(true);
-       myApplyBtn->setEnabled(true);
+        QString aText = QString("%1-%2").arg(anId1).arg(anId2);
+        myEdge->setText(aText);
+        
+        myOkBtn->setEnabled(true);
+        myApplyBtn->setEnabled(true);
       }
       else
       {
-       myEdge->clear();
+        myEdge->clear();
       }
     }
   }
@@ -494,8 +497,8 @@ bool SMESHGUI_SingleEditDlg::onApply()
 
   if (aMesh->_is_nil()) {
     SUIT_MessageBox::information(SMESH::GetDesktop(mySMESHGUI), 
-                                tr("SMESH_ERROR"),
-                                tr("SMESHG_NO_MESH"));
+                                 tr("SMESH_ERROR"),
+                                 tr("SMESHG_NO_MESH"));
     return false;
   }
 
@@ -513,6 +516,7 @@ bool SMESHGUI_SingleEditDlg::onApply()
     mySelectionMgr->setSelectedObjects(aList, false);
     onSelectionDone();
     SMESH::UpdateView();
+    SMESHGUI::Modified();
   }
 
   return aResult;
index df0192cb0564d28341a03f10ac469c690816cb8a..cc04610ac82c60117ab94802733e9aa0e1d61b4a 100755 (executable)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : SMESHGUI_SingleEditDlg.h
 // Author : Sergey LITONIN, Open CASCADE S.A.S.
 //
index c2144b1f4692cbe308d78e0c12aa89792c579e57..2eb9b521e218f9a2038d93280e3f0389611622b5 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_SmoothingDlg.cxx
 // Author : Michael ZORIN, Open CASCADE S.A.S.
 #define SPACING 6
 #define MARGIN  11
 
+/*!
+  \class BusyLocker
+  \brief Simple 'busy state' flag locker.
+  \internal
+*/
+
+class BusyLocker
+{
+public:
+  //! Constructor. Sets passed boolean flag to \c true.
+  BusyLocker( bool& busy ) : myBusy( busy ) { myBusy = true; }
+  //! Destructor. Clear external boolean flag passed as parameter to the constructor to \c false.
+  ~BusyLocker() { myBusy = false; }
+private:
+  bool& myBusy; //! External 'busy state' boolean flag
+};
+
+
 //=================================================================================
 // function : SMESHGUI_SmoothingDlg()
 // purpose  : constructor
@@ -137,8 +156,9 @@ SMESHGUI_SmoothingDlg::SMESHGUI_SmoothingDlg( SMESHGUI* theModule )
 
   LineEditElements = new QLineEdit(GroupArguments);
   LineEditElements->setValidator(myIdValidator);
-  QPushButton* filterElemBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
-  connect(filterElemBtn,   SIGNAL(clicked()), this, SLOT(setElemFilters()));
+  LineEditElements->setMaxLength(-1);
+  myElemFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
+  connect(myElemFilterBtn,   SIGNAL(clicked()), this, SLOT(setElemFilters()));
 
   // Control for the whole mesh selection
   CheckBoxMesh = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments);
@@ -151,6 +171,7 @@ SMESHGUI_SmoothingDlg::SMESHGUI_SmoothingDlg( SMESHGUI* theModule )
 
   LineEditNodes  = new QLineEdit(GroupArguments);
   LineEditNodes->setValidator(myIdValidator);
+  LineEditNodes->setMaxLength(-1);
   QPushButton* filterNodeBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
   connect(filterNodeBtn,   SIGNAL(clicked()), this, SLOT(setNodeFilters()));
 
@@ -175,7 +196,7 @@ SMESHGUI_SmoothingDlg::SMESHGUI_SmoothingDlg( SMESHGUI* theModule )
   GroupArgumentsLayout->addWidget(TextLabelElements,      0, 0);
   GroupArgumentsLayout->addWidget(SelectElementsButton,   0, 1);
   GroupArgumentsLayout->addWidget(LineEditElements,       0, 2);
-  GroupArgumentsLayout->addWidget(filterElemBtn,          0, 3);
+  GroupArgumentsLayout->addWidget(myElemFilterBtn,        0, 3);
   GroupArgumentsLayout->addWidget(CheckBoxMesh,           1, 0, 1, 4);
   GroupArgumentsLayout->addWidget(TextLabelNodes,         2, 0);
   GroupArgumentsLayout->addWidget(SelectNodesButton,      2, 1);
@@ -229,7 +250,7 @@ SMESHGUI_SmoothingDlg::SMESHGUI_SmoothingDlg( SMESHGUI* theModule )
   
   SpinBox_IterationLimit->setRange(1, 999999);
   SpinBox_IterationLimit->setValue(20);
-  SpinBox_AspectRatio->RangeStepAndValidator(0.0, +999999.999, 0.1, 3);
+  SpinBox_AspectRatio->RangeStepAndValidator(0.0, +999999.999, 0.1, "parametric_precision");
   SpinBox_AspectRatio->SetValue(1.1);
 
   GroupArguments->show();
@@ -241,12 +262,8 @@ SMESHGUI_SmoothingDlg::SMESHGUI_SmoothingDlg( SMESHGUI* theModule )
   mySMESHGUI->SetActiveDialogBox(this);
 
   // Costruction of the logical filter for the elements: mesh/sub-mesh/group
-  SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter (MESHorSUBMESH);
-  SMESH_TypeFilter* aSmeshGroupFilter    = new SMESH_TypeFilter (GROUP);
-
   QList<SUIT_SelectionFilter*> aListOfFilters;
-  if (aMeshOrSubMeshFilter) aListOfFilters.append(aMeshOrSubMeshFilter);
-  if (aSmeshGroupFilter)    aListOfFilters.append(aSmeshGroupFilter);
+  aListOfFilters << new SMESH_TypeFilter(MESHorSUBMESH) << new SMESH_TypeFilter(GROUP);
 
   myMeshOrSubMeshOrGroupFilter =
     new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR);
@@ -306,10 +323,10 @@ void SMESHGUI_SmoothingDlg::Init()
   LineEditElements->setFocus();
   LineEditElements->clear();
   LineEditNodes->clear();
-  myElementsId = "";
   myNbOkElements = 0;
   myNbOkNodes = 0;
   myActor     = 0;
+  myIO.Nullify();
   myMesh = SMESH::SMESH_Mesh::_nil();
 
   CheckBoxMesh->setChecked(false);
@@ -329,7 +346,7 @@ bool SMESHGUI_SmoothingDlg::ClickOnApply()
     return false;
 
   if (myNbOkElements && (myNbOkNodes || LineEditNodes->text().trimmed().isEmpty())) {
-    QStringList aListElementsId = myElementsId.split(" ", QString::SkipEmptyParts);
+    QStringList aListElementsId = LineEditElements->text().split(" ", QString::SkipEmptyParts);
     QStringList aListNodesId    = LineEditNodes->text().split(" ", QString::SkipEmptyParts);
 
     SMESH::long_array_var anElementsId = new SMESH::long_array;
@@ -363,35 +380,31 @@ bool SMESHGUI_SmoothingDlg::ClickOnApply()
       SUIT_OverrideCursor aWaitCursor;
       SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
 
+      myMesh->SetParameters( aParameters.join(":").toLatin1().constData() );
+
       if ( CheckBoxParametric->isChecked() ) {
         if(CheckBoxMesh->isChecked())
-         aResult = aMeshEditor->SmoothParametricObject(mySelectedObject, aNodesId.inout(),
-                                                       anIterationLimit, aMaxAspectRatio, aMethod);
-       else
-         aResult = aMeshEditor->SmoothParametric(anElementsId.inout(), aNodesId.inout(),
-                                                 anIterationLimit, aMaxAspectRatio, aMethod);
+          aResult = aMeshEditor->SmoothParametricObject(mySelectedObject, aNodesId.inout(),
+                                                        anIterationLimit, aMaxAspectRatio, aMethod);
+        else
+          aResult = aMeshEditor->SmoothParametric(anElementsId.inout(), aNodesId.inout(),
+                                                  anIterationLimit, aMaxAspectRatio, aMethod);
       }
       else {
         if(CheckBoxMesh->isChecked())
-         aResult = aMeshEditor->SmoothObject(mySelectedObject, aNodesId.inout(),
-                                             anIterationLimit, aMaxAspectRatio, aMethod);
-       else
-         aResult = aMeshEditor->Smooth(anElementsId.inout(), aNodesId.inout(),
-                                       anIterationLimit, aMaxAspectRatio, aMethod);
+          aResult = aMeshEditor->SmoothObject(mySelectedObject, aNodesId.inout(),
+                                              anIterationLimit, aMaxAspectRatio, aMethod);
+        else
+          aResult = aMeshEditor->Smooth(anElementsId.inout(), aNodesId.inout(),
+                                        anIterationLimit, aMaxAspectRatio, aMethod);
       }
 
-      myMesh->SetParameters( SMESHGUI::JoinObjectParameters(aParameters) );
-
     } catch (...) {
     }
 
     if (aResult) {
-      Handle(SALOME_InteractiveObject) anIO = myActor->getIO();
-
-      SALOME_ListIO aList;
-      aList.Append(anIO);
-      mySelectionMgr->setSelectedObjects(aList, false);
-      SMESH::UpdateView();
+      SMESH::Update(myIO, SMESH::eDisplay);
+      SMESHGUI::Modified();
       Init();
 
       mySelectedObject = SMESH::SMESH_IDSource::_nil();
@@ -448,10 +461,10 @@ void SMESHGUI_SmoothingDlg::ClickOnHelp()
     platform = "application";
 #endif
     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser",
-                                                                platform)).
-                            arg(myHelpFileName));
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser",
+                                                                 platform)).
+                             arg(myHelpFileName));
   }
 }
 
@@ -464,10 +477,10 @@ void SMESHGUI_SmoothingDlg::onTextChange (const QString& theNewText)
   QLineEdit* send = (QLineEdit*)sender();
 
   // return if busy
-  if (myBusy) return;
+  if (myBusy || myIO.IsNull()) return;
 
   // set busy flag
-  myBusy = true;
+  BusyLocker lock( myBusy );
 
   if (send == LineEditElements)
     myNbOkElements = 0;
@@ -478,40 +491,37 @@ void SMESHGUI_SmoothingDlg::onTextChange (const QString& theNewText)
   buttonApply->setEnabled(false);
 
   // hilight entered elements/nodes
-  SMDS_Mesh* aMesh = 0;
-  if (myActor)
-    aMesh = myActor->GetObject()->GetMesh();
-
-  if (aMesh) {
-    
-    QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
-
-    if (send == LineEditElements) {
-      const Handle(SALOME_InteractiveObject)& anIO = myActor->getIO();
-      TColStd_MapOfInteger newIndices;
-      for (int i = 0; i < aListId.count(); i++) {
-       const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt());
-       if (e)
-         newIndices.Add(e->GetID());
-       myNbOkElements++;
+  SMDS_Mesh* aMesh = myActor ? myActor->GetObject()->GetMesh() : 0;
+  QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
+
+  if (send == LineEditElements) {
+    TColStd_MapOfInteger newIndices;
+    for (int i = 0; i < aListId.count(); i++) {
+      int id = aListId[ i ].toInt();
+      if ( id > 0 ) {
+        bool validId = aMesh ? ( aMesh->FindElement( id ) != 0 ) : ( myMesh->GetElementType( id, true ) != SMESH::EDGE );
+        if ( validId ) 
+          newIndices.Add( id );
       }
-      mySelector->AddOrRemoveIndex(anIO, newIndices, false);
+      myNbOkElements = newIndices.Extent();
+      mySelector->AddOrRemoveIndex(myIO, newIndices, false);
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-       aViewWindow->highlight( anIO, true, true );
-      myElementsId = theNewText;
-
-    } else if (send == LineEditNodes) {
-      TColStd_MapOfInteger newIndices;
-      
-      for (int i = 0; i < aListId.count(); i++) {
-       const SMDS_MeshNode * n = aMesh->FindNode(aListId[ i ].toInt());
-       if (n)
-         newIndices.Add(n->GetID());
-       myNbOkNodes++;
+        aViewWindow->highlight( myIO, true, true );
+    }
+  }
+  else if (send == LineEditNodes) {
+    TColStd_MapOfInteger newIndices;
+    for (int i = 0; i < aListId.count(); i++) {
+      int id = aListId[ i ].toInt();
+      if ( id > 0 ) {
+        bool validId = aMesh ? ( aMesh->FindNode( id ) != 0 ) : ( myMesh->GetElementType( id, false ) != SMESH::EDGE );
+        if ( validId ) 
+          newIndices.Add( id );
       }
-      mySelector->AddOrRemoveIndex(myActor->getIO(), newIndices, false);
+      myNbOkNodes = newIndices.Extent();
+      mySelector->AddOrRemoveIndex(myIO, newIndices, false);
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-       aViewWindow->highlight( myActor->getIO(), true, true );
+        aViewWindow->highlight( myIO, true, true );
     }
   }
 
@@ -519,8 +529,6 @@ void SMESHGUI_SmoothingDlg::onTextChange (const QString& theNewText)
     buttonOk->setEnabled(true);
     buttonApply->setEnabled(true);
   }
-
-  myBusy = false;
 }
 
 //=================================================================================
@@ -534,19 +542,23 @@ void SMESHGUI_SmoothingDlg::SelectionIntoArgument()
   // clear
   QString aString = "";
 
-  myBusy = true;
+  // set busy flag
+  BusyLocker lock( myBusy );
+
   if (myEditCurrentArgument == LineEditElements ||
       myEditCurrentArgument == LineEditNodes) {
     myEditCurrentArgument->setText(aString);
-    if (myEditCurrentArgument == LineEditElements)
+    if (myEditCurrentArgument == LineEditElements) {
       myNbOkElements = 0;
-    else
+      myActor = 0;
+      myIO.Nullify();
+    }
+    else {
       myNbOkNodes = 0;
+    }
     buttonOk->setEnabled(false);
     buttonApply->setEnabled(false);
-    myActor = 0;
   }
-  myBusy = false;
 
   if (!GroupButtons->isEnabled()) // inactive
     return;
@@ -559,50 +571,45 @@ void SMESHGUI_SmoothingDlg::SelectionIntoArgument()
     return;
 
   Handle(SALOME_InteractiveObject) IO = aList.First();
-  myMesh = SMESH::GetMeshByIO(IO);
-  if (myMesh->_is_nil())
-    return;
-
-  myActor = SMESH::FindActorByObject(myMesh);
-  if (!myActor)
-    return;
-
-  int aNbUnits = 0;
 
   if (myEditCurrentArgument == LineEditElements) {
-    myElementsId = "";
+    myMesh = SMESH::GetMeshByIO(IO);
+    if (myMesh->_is_nil())
+      return;
+    myIO = IO;
+    myActor = SMESH::FindActorByObject(myMesh);
 
     if (CheckBoxMesh->isChecked()) {
       SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
 
-      if (!SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO)->_is_nil())
-        mySelectedObject = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO);
+      SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( myIO );
+      if ( !CORBA::is_nil( obj ) )
+        mySelectedObject = obj;
       else
         return;
+      myNbOkElements = true;
     } else {
-      aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, IO, aString);
-      myElementsId = aString;
-      if (aNbUnits < 1)
+      // get indices of selected elements
+      TColStd_IndexedMapOfInteger aMapIndex;
+      mySelector->GetIndex(IO,aMapIndex);
+      myNbOkElements = aMapIndex.Extent();
+
+      if (myNbOkElements < 1)
         return;
+      
+      QStringList elements;
+      for ( int i = 0; i < myNbOkElements; ++i )
+        elements << QString::number( aMapIndex( i+1 ) );
+      aString = elements.join(" ");
     }
-  } else if (myEditCurrentArgument == LineEditNodes && !myMesh->_is_nil() && myActor) {
-    myNbOkNodes = 0;
-    aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
-  } else {
+  } else if (myEditCurrentArgument == LineEditNodes && !myMesh->_is_nil() && myIO == IO ) {
+    myNbOkNodes = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
   }
 
-  myBusy = true;
   myEditCurrentArgument->setText(aString);
   myEditCurrentArgument->repaint();
   myEditCurrentArgument->setEnabled(false); // to update lineedit IPAL 19809
   myEditCurrentArgument->setEnabled(true); 
-  myBusy = false;
-
-  // OK
-  if (myEditCurrentArgument == LineEditElements)
-    myNbOkElements = aNbUnits;
-  else if (myEditCurrentArgument == LineEditNodes)
-    myNbOkNodes = aNbUnits;
 
   if (myNbOkElements && (myNbOkNodes || LineEditNodes->text().trimmed().isEmpty())) {
     buttonOk->setEnabled(true);
@@ -629,21 +636,21 @@ void SMESHGUI_SmoothingDlg::SetEditCurrentArgument()
         myEditCurrentArgument = LineEditElements;
         SMESH::SetPointRepresentation(false);
         if (CheckBoxMesh->isChecked()) {
-         //          mySelectionMgr->setSelectionModes(ActorSelection);
-         if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-           aViewWindow->SetSelectionMode(ActorSelection);
-         mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter);
+          //          mySelectionMgr->setSelectionModes(ActorSelection);
+          if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+            aViewWindow->SetSelectionMode(ActorSelection);
+          mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter);
         } else {
-         if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-           aViewWindow->SetSelectionMode(FaceSelection);
-       }
+          if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+            aViewWindow->SetSelectionMode(FaceSelection);
+        }
       } else if (send == SelectNodesButton) {
-       LineEditNodes->clear();
+        LineEditNodes->clear();
         myEditCurrentArgument = LineEditNodes;
         SMESH::SetPointRepresentation(true);
-       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) {
-         aViewWindow->SetSelectionMode(NodeSelection);
-       }
+        if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) {
+          aViewWindow->SetSelectionMode(NodeSelection);
+        }
       }
 
       myEditCurrentArgument->setFocus();
@@ -727,6 +734,7 @@ void SMESHGUI_SmoothingDlg::onSelectMesh (bool toSelectMesh)
     TextLabelElements->setText(tr("SMESH_NAME"));
   else
     TextLabelElements->setText(tr("SMESH_ID_ELEMENTS"));
+  myElemFilterBtn->setEnabled(!toSelectMesh);
 
   if (myEditCurrentArgument != LineEditElements &&
       myEditCurrentArgument != LineEditNodes) {
@@ -779,6 +787,12 @@ void SMESHGUI_SmoothingDlg::keyPressEvent( QKeyEvent* e )
 //=================================================================================
 void SMESHGUI_SmoothingDlg::setFilters( const bool theIsElem )
 {
+  if(myMesh->_is_nil()) {
+    SUIT_MessageBox::critical(this,
+                              tr("SMESH_ERROR"),
+                              tr("NO_MESH_SELECTED"));
+   return;
+  }
   if ( !myFilterDlg )
   {
     QList<int> types;  
index 40b8170a3cbcbfd9e963bd8b85b0aac6002ef3e4..efb9723a6eb4f764060ad41ca2a8433dd5995992 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_SmoothingDlg.h
 // Author : Michael ZORIN, Open CASCADE S.A.S.
@@ -32,6 +33,9 @@
 // Qt includes
 #include <QDialog>
 
+// SALOME GUI includes
+#include <SALOME_InteractiveObject.hxx>
+
 // IDL includes
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Mesh)
@@ -78,7 +82,6 @@ private:
   SMESHGUI*              mySMESHGUI;              /* Current SMESHGUI object */
   SMESHGUI_IdValidator*  myIdValidator;
   LightApp_SelectionMgr* mySelectionMgr;          /* User shape selection */
-  QString                myElementsId;
   int                    myNbOkElements;          /* to check when elements are defined */
   int                    myNbOkNodes;             /* to check when fixed nodes are defined */
   int                    myConstructorId;         /* Current constructor id = radio button id */
@@ -90,6 +93,7 @@ private:
   bool                   myBusy;
   SMESH::SMESH_Mesh_var  myMesh;
   SMESH_Actor*           myActor;
+  Handle(SALOME_InteractiveObject) myIO;
   SMESH_LogicalFilter*   myMeshOrSubMeshOrGroupFilter;
 
   QGroupBox*             GroupConstructors;
@@ -116,7 +120,8 @@ private:
   QCheckBox*             CheckBoxParametric;
 
   QString                myHelpFileName;
-    
+
+  QPushButton*           myElemFilterBtn;
   SMESHGUI_FilterDlg*    myFilterDlg;
    
 private slots:
index 1b30cb08a33e0ede5f9b3e82e26a9a84c0bd187a..cda1357f081ef01ede40c13d392e74225dc1b357 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_SpinBox.cxx
 // Author : Lucien PIGNOLONI, Open CASCADE S.A.S.
 //
 #include "SMESHGUI_SpinBox.h"
 
+#include <SUIT_Session.h>
+#include <SUIT_ResourceMgr.h>
+
 // Qt includes
-#include <QDoubleValidator>
 #include <QLineEdit>
+#include <QVariant>
 
 //=================================================================================
 // class    : SMESHGUI_SpinBox()
@@ -62,7 +66,7 @@ void SMESHGUI_SpinBox::SetStep( double newStep )
 //=================================================================================
 void SMESHGUI_SpinBox::SetValue( double v )
 {
-  setValue(v);
+  setValue(valueFromText(textFromValue(v)));
   editor()->setCursorPosition( 0 );
 }
 
@@ -93,28 +97,29 @@ QLineEdit* SMESHGUI_SpinBox::editor() const
   return SalomeApp_DoubleSpinBox::lineEdit();
 } 
 
-//=================================================================================
-// function : validator()
-// purpose  : returns validator
-//=================================================================================
-QDoubleValidator* SMESHGUI_SpinBox::validator() const
-{
-  return (QDoubleValidator*)editor()->validator();
-}
-
 //=================================================================================
 // function : RangeStepAndValidator()
 // purpose  :
 //=================================================================================
 void SMESHGUI_SpinBox::RangeStepAndValidator( double min,
-                                             double max,
-                                             double step,
-                                             unsigned short precision )
+                                              double max,
+                                              double step,
+                                              const char* quantity )
 {
-  setPrecision(precision*(-1)); // PAL8769. Minus is for using 'g' double->string conversion specifier,
-  //                               see QtxDoubleSpinBox::mapValueToText( double v )
-  setDecimals(32);
+  // Obtain precision from preferences
+  SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+  int precision = resMgr->integerValue( "SMESH", quantity, -3 );
+  
+  setPrecision(precision); // PAL8769. Minus is for using 'g' double->string conversion specifier,
+  //                          see QtxDoubleSpinBox::mapValueToText( double v )
+  //                          san: this can be achieved using preferences
+  setDecimals( 20 ); // qAbs(precision)
   setRange(min, max);
   setSingleStep( step );
   setDefaultValue( min );
+  
+  // Add a hint for the user saying how to tune precision
+  QString userPropName = QObject::tr( QString( "SMESH_PREF_%1" ).arg( quantity ).toLatin1().constData() );
+  setProperty( "validity_tune_hint", 
+               QVariant( QObject::tr( "SMESH_PRECISION_HINT" ).arg( userPropName ) ) );  
 }
index cdca31653eaf8b2cf4f5e24f3b6157ad878e5a98..d12cd656089f9cb726e136dae50cee0b1588675c 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_SpinBox.h
 // Author : Lucien PIGNOLONI, Open CASCADE S.A.S.
@@ -52,14 +53,13 @@ public:
   ~SMESHGUI_SpinBox();
 
   void       RangeStepAndValidator( double         = -1000000.0,
-                                   double         = +1000000.0,
-                                   double         = 100.0,
-                                   unsigned short = 3 );
+                                    double         = +1000000.0,
+                                    double         = 100.0,
+                                    const char*    = "length_precision" );
   void              SetValue( double );
   double            GetValue() const;
   QString           GetString() const;
   QLineEdit*        editor() const;
-  QDoubleValidator* validator() const;
 
 public slots:
   void              SetStep( double );
diff --git a/src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.cxx b/src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.cxx
deleted file mode 100644 (file)
index 4b7540f..0000000
+++ /dev/null
@@ -1,472 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-// SMESH SMESHGUI : GUI for SMESH component
-// File   : SMESHGUI_StandardMeshInfosDlg.cxx
-// Author : Michael ZORIN, Open CASCADE S.A.S.
-// SMESH includes
-//
-#include "SMESHGUI_StandardMeshInfosDlg.h"
-
-#include "SMESHGUI.h"
-#include "SMESHGUI_Utils.h"
-#include "SMESHGUI_MeshUtils.h"
-
-#include <SMESH_TypeFilter.hxx>
-
-// SALOME KERNEL includes 
-#include <SALOMEDSClient_Study.hxx>
-#include <SALOMEDSClient_SObject.hxx>
-
-// SALOME GUI includes
-#include <SUIT_Desktop.h>
-#include <SUIT_Session.h>
-#include <SUIT_OverrideCursor.h>
-#include <SUIT_MessageBox.h>
-#include <SUIT_ResourceMgr.h>
-
-#include <LightApp_Application.h>
-#include <LightApp_SelectionMgr.h>
-
-#include <SALOME_ListIO.hxx>
-
-// Qt includes
-#include <QGroupBox>
-#include <QLabel>
-#include <QVBoxLayout>
-#include <QHBoxLayout>
-#include <QLineEdit>
-#include <QTextBrowser>
-#include <QPushButton>
-#include <QKeyEvent>
-
-// IDL includes
-#include <SALOMEconfig.h>
-#include CORBA_SERVER_HEADER(SMESH_Mesh)
-#include CORBA_SERVER_HEADER(SMESH_Group)
-
-#define SPACING 6
-#define MARGIN  11
-
-//=================================================================================
-/*!
- *  SMESHGUI_StandardMeshInfosDlg::SMESHGUI_StandardMeshInfosDlg
- *
- *  Constructor
- */
-//=================================================================================
-SMESHGUI_StandardMeshInfosDlg::SMESHGUI_StandardMeshInfosDlg( SMESHGUI* theModule )
-  : QDialog( SMESH::GetDesktop( theModule ) ),
-    mySMESHGUI( theModule ),
-    mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
-{
-  setModal(false);
-  setAttribute(Qt::WA_DeleteOnClose, true);
-  setWindowTitle(tr("SMESH_STANDARD_MESHINFO_TITLE"));
-  setSizeGripEnabled(true);
-
-  myStartSelection = true;
-  myIsActiveWindow = true;
-
-  // dialog layout
-  QVBoxLayout* aDlgLayout = new QVBoxLayout(this);
-  aDlgLayout->setSpacing(SPACING);
-  aDlgLayout->setMargin(MARGIN);
-
-  // mesh group box
-  myMeshGroup = new QGroupBox(tr("SMESH_MESH"), this);
-  QHBoxLayout* myMeshGroupLayout = new QHBoxLayout(myMeshGroup);
-  myMeshGroupLayout->setSpacing(SPACING);
-  myMeshGroupLayout->setMargin(MARGIN);
-
-  // select button, label and line edit with mesh name
-  myNameLab = new QLabel(tr("SMESH_NAME"), myMeshGroup);
-  myMeshGroupLayout->addWidget(myNameLab);
-
-  QPixmap image0(SUIT_Session::session()->resourceMgr()->loadPixmap("SMESH",tr("ICON_SELECT")));
-  mySelectBtn = new QPushButton(myMeshGroup);
-  mySelectBtn->setIcon(image0);
-  myMeshGroupLayout->addWidget(mySelectBtn);
-
-  myMeshLine = new QLineEdit(myMeshGroup);
-  myMeshGroupLayout->addWidget(myMeshLine);
-
-  aDlgLayout->addWidget(myMeshGroup);
-
-  // information group box
-  myInfoGroup  = new QGroupBox(tr("SMESH_INFORMATION"), this);
-  QVBoxLayout* myInfoGroupLayout = new QVBoxLayout(myInfoGroup);
-  myInfoGroupLayout->setSpacing(SPACING);
-  myInfoGroupLayout->setMargin(MARGIN);
-
-  // information text browser
-  myInfo = new QTextBrowser(myInfoGroup);
-  myInfo->setMinimumSize(200, 150);
-  myInfoGroupLayout->addWidget(myInfo);
-
-  aDlgLayout->addWidget(myInfoGroup);
-
-  // buttons group
-  myButtonsGroup = new QGroupBox(this);
-  QHBoxLayout* myButtonsGroupLayout = new QHBoxLayout(myButtonsGroup);
-  myButtonsGroupLayout->setSpacing(SPACING);
-  myButtonsGroupLayout->setMargin(MARGIN);
-
-  // buttons --> OK and Help buttons
-  myOkBtn = new QPushButton(tr("SMESH_BUT_OK"), myButtonsGroup);
-  myOkBtn->setAutoDefault(true); myOkBtn->setDefault(true);
-  myHelpBtn = new QPushButton(tr("SMESH_BUT_HELP"), myButtonsGroup);
-  myHelpBtn->setAutoDefault(true);
-
-  myButtonsGroupLayout->addWidget(myOkBtn);
-  myButtonsGroupLayout->addSpacing(10);
-  myButtonsGroupLayout->addStretch();
-  myButtonsGroupLayout->addWidget(myHelpBtn);
-
-  aDlgLayout->addWidget(myButtonsGroup);
-
-  mySMESHGUI->SetActiveDialogBox(this);
-
-  // connect signals
-  connect( myOkBtn,         SIGNAL(clicked()),                      this, SLOT(close()));
-  connect( myHelpBtn,       SIGNAL(clicked()),                      this, SLOT(onHelp()));
-  connect( mySelectBtn,     SIGNAL(clicked()),                      this, SLOT(onStartSelection()));
-  connect( mySMESHGUI,      SIGNAL(SignalCloseAllDialogs()),        this, SLOT(close()));
-  connect( mySMESHGUI,      SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
-  connect( mySelectionMgr,  SIGNAL(currentSelectionChanged()),      this, SLOT(onSelectionChanged()));
-
-  // init dialog with current selection
-  myMeshFilter = new SMESH_TypeFilter (MESH);
-  mySelectionMgr->installFilter(myMeshFilter);
-  onSelectionChanged();
-
-  myHelpFileName = "mesh_infos_page.html#standard_mesh_infos_anchor";
-}
-
-//=================================================================================
-/*!
- *  SMESHGUI_StandardMeshInfosDlg::~SMESHGUI_StandardMeshInfosDlg
- *
- *  Destructor
- */
-//=================================================================================
-SMESHGUI_StandardMeshInfosDlg::~SMESHGUI_StandardMeshInfosDlg()
-{
-}
-
-//=================================================================================
-/*!
- *  SMESHGUI_StandardMeshInfosDlg::DumpMeshInfos
- */
-//=================================================================================
-void SMESHGUI_StandardMeshInfosDlg::DumpMeshInfos()
-{
-  SUIT_OverrideCursor wc;
-
-  SALOME_ListIO aList;
-  mySelectionMgr->selectedObjects(aList);
-
-  int nbSel = aList.Extent();
-  myInfo->clear();
-  if (nbSel == 1) {
-    myStartSelection = false;
-    myMeshLine->setText("");
-    SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(aList.First());
-
-    if (!aMesh->_is_nil()) {
-      QString aName, anInfo;
-      SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aName);
-      myMeshLine->setText(aName);
-      int aNbNodes =   (int)aMesh->NbNodes();
-      int aNbEdges =   (int)aMesh->NbEdges();
-      int aNbFaces =   (int)aMesh->NbFaces();
-      int aNbVolumes = (int)aMesh->NbVolumes();
-
-      int aDimension = 0;
-      double aNbDimElements = 0;
-      if (aNbVolumes > 0) {
-       aNbDimElements = aNbVolumes;
-       aDimension = 3;
-      }
-      else if(aNbFaces > 0) {
-       aNbDimElements = aNbFaces;
-       aDimension = 2;
-      }
-      else if(aNbEdges > 0) {
-       aNbDimElements = aNbEdges;
-       aDimension = 1;
-      }
-      else if(aNbNodes > 0) {
-       aNbDimElements = aNbNodes;
-       aDimension = 0;
-      }
-
-      // information about the mesh
-      anInfo.append(QString("Nb of element of dimension %1:<b> %2</b><br>").arg(aDimension).arg(aNbDimElements));
-      anInfo.append(QString("Nb of nodes: <b>%1</b><br><br>").arg(aNbNodes));
-
-      // information about the groups of the mesh
-      _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
-      _PTR(SObject) aMeshSO = SMESH::FindSObject(aMesh);
-      _PTR(SObject) anObj;
-
-      bool hasGroup = false;
-
-      // info about groups on nodes
-      aMeshSO->FindSubObject(SMESH::Tag_NodeGroups, anObj);
-      if (anObj) {
-        _PTR(ChildIterator) it = aStudy->NewChildIterator(anObj);
-       if (it->More()) {
-          anInfo.append(QString("Groups:<br><br>"));
-          hasGroup = true;
-        }
-       for ( ; it->More(); it->Next()) {
-          _PTR(SObject) subObj = it->Value();
-          CORBA::Object_var anObject = SMESH::SObjectToObject(subObj);
-         SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(anObject);
-         if (!aGroup->_is_nil()) {
-            anInfo.append(QString("-   <b>%1</b><br>").arg(aGroup->GetName()));
-            anInfo.append(QString("%1<br>").arg("on nodes"));
-            anInfo.append(QString("%1<br>").arg(aGroup->Size()));
-            // check if the group based on geometry
-            SMESH::SMESH_GroupOnGeom_var aGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow(aGroup);
-            if (!aGroupOnGeom->_is_nil()) {
-              GEOM::GEOM_Object_var aGroupMainShape = aGroupOnGeom->GetShape();
-              QString aShapeName = "<unknown>";
-              _PTR(SObject) aGeomObj, aRef;
-              if (subObj->FindSubObject(1, aGeomObj) &&  aGeomObj->ReferencedObject(aRef))
-                aShapeName = aRef->GetName().c_str();
-              anInfo.append(QString("based on <i>%1</i> geometry object<br><br>").arg(aShapeName));
-            } else {
-              anInfo.append(QString("<br>"));
-            }
-          }
-       }
-      }
-
-      // info about groups on edges
-      anObj.reset();
-      aMeshSO->FindSubObject(SMESH::Tag_EdgeGroups, anObj);
-      if (anObj) {
-        _PTR(ChildIterator) it = aStudy->NewChildIterator(anObj);
-        if (!hasGroup && it->More()) {
-          anInfo.append(QString("Groups:<br><br>"));
-          hasGroup = true;
-        }
-       for ( ; it->More(); it->Next()) {
-          _PTR(SObject) subObj = it->Value();
-          CORBA::Object_var anObject = SMESH::SObjectToObject(subObj);
-         SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(anObject);
-         if (!aGroup->_is_nil()) {
-            anInfo.append(QString("-   <b>%1</b><br>").arg(aGroup->GetName()));
-            anInfo.append(QString("%1<br>").arg("on edges"));
-            anInfo.append(QString("%1<br>").arg(aGroup->Size()));
-            // check if the group based on geometry
-            SMESH::SMESH_GroupOnGeom_var aGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow(aGroup);
-            if (!aGroupOnGeom->_is_nil()) {
-              GEOM::GEOM_Object_var aGroupMainShape = aGroupOnGeom->GetShape();
-              QString aShapeName = "<unknown>";
-              _PTR(SObject) aGeomObj, aRef;
-              if (subObj->FindSubObject(1, aGeomObj) && aGeomObj->ReferencedObject(aRef))
-                aShapeName = aRef->GetName().c_str();
-              anInfo.append(QString("based on <i>%1</i> geometry object<br><br>").arg(aShapeName));
-            } else {
-              anInfo.append(QString("<br>"));
-            }
-          }
-       }
-      }
-
-      // info about groups on faces
-      anObj.reset();
-      aMeshSO->FindSubObject(SMESH::Tag_FaceGroups, anObj);
-      if (anObj) {
-        _PTR(ChildIterator) it = aStudy->NewChildIterator(anObj);
-       if (!hasGroup && it->More()) {
-          anInfo.append(QString("Groups:<br><br>"));
-          hasGroup = true;
-        }
-       for ( ; it->More(); it->Next()) {
-          _PTR(SObject) subObj = it->Value();
-          CORBA::Object_var anObject = SMESH::SObjectToObject(subObj);
-         SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(anObject);
-         if (!aGroup->_is_nil()) {
-            anInfo.append(QString("-   <b>%1</b><br>").arg(aGroup->GetName()));
-            anInfo.append(QString("%1<br>").arg("on faces"));
-            anInfo.append(QString("%1<br>").arg(aGroup->Size()));
-            // check if the group based on geometry
-            SMESH::SMESH_GroupOnGeom_var aGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow(aGroup);
-            if (!aGroupOnGeom->_is_nil()) {
-              GEOM::GEOM_Object_var aGroupMainShape = aGroupOnGeom->GetShape();
-              QString aShapeName = "<unknown>";
-              _PTR(SObject) aGeomObj, aRef;
-              if (subObj->FindSubObject(1, aGeomObj) && aGeomObj->ReferencedObject(aRef))
-                aShapeName = aRef->GetName().c_str();
-              anInfo.append(QString("based on <i>%1</i> geometry object<br><br>").arg(aShapeName));
-            } else {
-              anInfo.append(QString("<br>"));
-            }
-          }
-       }
-      }
-
-      // info about groups on volumes
-      anObj.reset();
-      aMeshSO->FindSubObject(SMESH::Tag_VolumeGroups, anObj);
-      if (anObj) {
-        _PTR(ChildIterator) it = aStudy->NewChildIterator(anObj);
-       if (!hasGroup && it->More())
-          anInfo.append(QString("Groups:<br>"));
-       for ( ; it->More(); it->Next()) {
-          _PTR(SObject) subObj = it->Value();
-          CORBA::Object_var anObject = SMESH::SObjectToObject(subObj);
-         SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(anObject);
-         if (!aGroup->_is_nil()) {
-            anInfo.append(QString("-   <b>%1</b><br>").arg(aGroup->GetName()));
-            anInfo.append(QString("%1<br>").arg("on volumes"));
-            anInfo.append(QString("%1<br>").arg(aGroup->Size()));
-            // check if the group based on geometry
-            SMESH::SMESH_GroupOnGeom_var aGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow(aGroup);
-            if (!aGroupOnGeom->_is_nil()) {
-              GEOM::GEOM_Object_var aGroupMainShape = aGroupOnGeom->GetShape();
-              QString aShapeName = "<unknown>";
-              _PTR(SObject) aGeomObj, aRef;
-              if (subObj->FindSubObject(1, aGeomObj) &&  aGeomObj->ReferencedObject(aRef))
-                aShapeName = aRef->GetName().c_str();
-              anInfo.append(QString("based on <i>%1</i> geometry object<br><br>").arg(aShapeName));
-            } else {
-              anInfo.append(QString("<br>"));
-            }
-          }
-       }
-      }
-
-      myInfo->setText(anInfo);
-      return;
-    }
-  }
-}
-
-//=================================================================================
-// function : SelectionIntoArgument()
-// purpose  : Called when selection has changed
-//=================================================================================
-void SMESHGUI_StandardMeshInfosDlg::onSelectionChanged()
-{
-  if (myStartSelection)
-    DumpMeshInfos();
-}
-
-//=================================================================================
-// function : closeEvent()
-// purpose  :
-//=================================================================================
-void SMESHGUI_StandardMeshInfosDlg::closeEvent (QCloseEvent* e)
-{
-  mySelectionMgr->clearFilters();
-  mySMESHGUI->ResetState();
-  QDialog::closeEvent(e);
-}
-
-//=================================================================================
-// function : windowActivationChange()
-// purpose  : called when window is activated/deactivated
-//=================================================================================
-void SMESHGUI_StandardMeshInfosDlg::windowActivationChange (bool oldActive)
-{
-  QDialog::windowActivationChange(oldActive);
-  if (isActiveWindow() && myIsActiveWindow != isActiveWindow())
-    ActivateThisDialog();
-  myIsActiveWindow = isActiveWindow();
-}
-
-//=================================================================================
-// function : DeactivateActiveDialog()
-// purpose  :
-//=================================================================================
-void SMESHGUI_StandardMeshInfosDlg::DeactivateActiveDialog()
-{
-  disconnect(mySelectionMgr, 0, this, 0);
-}
-
-//=================================================================================
-// function : ActivateThisDialog()
-// purpose  :
-//=================================================================================
-void SMESHGUI_StandardMeshInfosDlg::ActivateThisDialog()
-{
-  /* Emit a signal to deactivate any active dialog */
-  mySMESHGUI->EmitSignalDeactivateDialog();
-  connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionChanged()));
-}
-
-//=================================================================================
-// function : onStartSelection()
-// purpose  : starts selection
-//=================================================================================
-void SMESHGUI_StandardMeshInfosDlg::onStartSelection()
-{
-  myStartSelection = true;
-  mySelectionMgr->installFilter(myMeshFilter);
-  myMeshLine->setText(tr("Select a mesh"));
-  onSelectionChanged();
-  myStartSelection = true;
-}
-
-//=================================================================================
-// function : onHelp()
-// purpose  :
-//=================================================================================
-void SMESHGUI_StandardMeshInfosDlg::onHelp()
-{
-  LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
-  if (app)
-    app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
-  else {
-    QString platform;
-#ifdef WIN32
-    platform = "winapplication";
-#else
-    platform = "application";
-#endif
-    SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser",
-                                                                platform)).
-                            arg(myHelpFileName));
-  }
-}
-
-//=================================================================================
-// function : keyPressEvent()
-// purpose  :
-//=================================================================================
-void SMESHGUI_StandardMeshInfosDlg::keyPressEvent( QKeyEvent* e )
-{
-  QDialog::keyPressEvent( e );
-  if ( e->isAccepted() )
-    return;
-
-  if ( e->key() == Qt::Key_F1 ) {
-    e->accept();
-    onHelp();
-  }
-}
diff --git a/src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.h b/src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.h
deleted file mode 100644 (file)
index e6e3432..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-// SMESH SMESHGUI : GUI for SMESH component
-// File   : SMESHGUI_StandardMeshInfosDlg.h
-// Author : Michael ZORIN, Open CASCADE S.A.S.
-//
-#ifndef SMESHGUI_STANDARDMESHINFOSDLG_H
-#define SMESHGUI_STANDARDMESHINFOSDLG_H
-
-// SMESH includes
-#include "SMESH_SMESHGUI.hxx"
-
-// Qt includes
-#include <QDialog>
-
-class QGroupBox;
-class QLabel;
-class QPushButton;
-class QLineEdit;
-class QTextBrowser;
-class SMESHGUI;
-class LightApp_SelectionMgr;
-class SUIT_SelectionFilter;
-
-class SMESHGUI_EXPORT SMESHGUI_StandardMeshInfosDlg : public QDialog
-{ 
-  Q_OBJECT
-
-public:
-  SMESHGUI_StandardMeshInfosDlg( SMESHGUI* );
-  ~SMESHGUI_StandardMeshInfosDlg();
-
-protected:
-  void                     closeEvent( QCloseEvent* );
-  void                     keyPressEvent( QKeyEvent* );
-  void                     windowActivationChange( bool );
-  void                     DumpMeshInfos();
-
-private slots:
-  void                     onSelectionChanged();
-  void                     DeactivateActiveDialog();
-  void                     ActivateThisDialog();
-  void                     onStartSelection();
-  void                     onHelp();
-
-private:
-  SMESHGUI*                mySMESHGUI;
-  LightApp_SelectionMgr*   mySelectionMgr; 
-  bool                     myStartSelection;
-  bool                     myIsActiveWindow;
-    
-  SUIT_SelectionFilter*    myMeshFilter;
-
-  QLabel*                  myNameLab;
-  QPushButton*             mySelectBtn;
-  QLineEdit*               myMeshLine;
-    
-  QTextBrowser*            myInfo;
-    
-  QGroupBox*               myMeshGroup;
-  QGroupBox*               myInfoGroup;
-    
-  QGroupBox*               myButtonsGroup;
-  QPushButton*             myOkBtn;
-  QPushButton*             myHelpBtn;
-    
-  QString                  myHelpFileName;
-};
-
-#endif // SMESHGUI_STANDARDMESHINFOSDLG_H
index ed49f5217b7e4967dcc6c20a9c58081fa566cece..5f4b1e20667aace70103915098c0533a4342bc06 100644 (file)
@@ -1,29 +1,28 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
-//
-// SMESH SMESHGUI : GUI for SMESH component
-// File   : SMESHGUI_SymmetryDlg.cxx
-// Author : Michael ZORIN, Open CASCADE S.A.S.
-// SMESH includes
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+//  File   : SMESHGUI_SymmetryDlg.cxx
+//  Author : Michael ZORIN, Open CASCADE S.A.S.
+//  SMESH includes
+
 #include "SMESHGUI_SymmetryDlg.h"
 
 #include "SMESHGUI.h"
@@ -33,6 +32,7 @@
 #include "SMESHGUI_MeshUtils.h"
 #include "SMESHGUI_IdValidator.h"
 #include "SMESHGUI_FilterDlg.h"
+#include "SMESHGUI_MeshEditPreview.h"
 
 #include <SMESH_Actor.h>
 #include <SMESH_TypeFilter.hxx>
@@ -83,14 +83,17 @@ enum { MOVE_ELEMS_BUTTON = 0, COPY_ELEMS_BUTTON, MAKE_MESH_BUTTON }; //!< action
 #define SPACING 6
 #define MARGIN  11
 
+//To disable automatic genericobj management, the following line should be commented.
+//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
+#define WITHGENERICOBJ
+
 //=================================================================================
 // class    : SMESHGUI_SymmetryDlg()
 // purpose  :
 //=================================================================================
 
 SMESHGUI_SymmetryDlg::SMESHGUI_SymmetryDlg( SMESHGUI* theModule )
-  : QDialog( SMESH::GetDesktop( theModule ) ),
-    mySMESHGUI( theModule ),
+  : SMESHGUI_PreviewDlg( theModule ),
     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
     myFilterDlg(0),
     mySelectedObject(SMESH::SMESH_IDSource::_nil())
@@ -144,8 +147,9 @@ SMESHGUI_SymmetryDlg::SMESHGUI_SymmetryDlg( SMESHGUI* theModule )
   SelectElementsButton->setIcon(image3);
   LineEditElements = new QLineEdit(GroupArguments);
   LineEditElements->setValidator(myIdValidator);
-  QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
-  connect(filterBtn,   SIGNAL(clicked()), this, SLOT(setFilters()));
+  LineEditElements->setMaxLength(-1);
+  myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
+  connect(myFilterBtn,   SIGNAL(clicked()), this, SLOT(setFilters()));
 
   // Control for the whole mesh selection
   CheckBoxMesh = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments);
@@ -220,16 +224,21 @@ SMESHGUI_SymmetryDlg::SMESHGUI_SymmetryDlg( SMESHGUI* theModule )
   // Name of a mesh to create
   LineEditNewMesh = new QLineEdit(GroupArguments);
 
+
+  //Preview check box
+  myPreviewCheckBox = new QCheckBox(tr("PREVIEW"), GroupArguments);
+
   // layout
   GroupArgumentsLayout->addWidget(TextLabelElements,    0, 0);
   GroupArgumentsLayout->addWidget(SelectElementsButton, 0, 1);
   GroupArgumentsLayout->addWidget(LineEditElements,     0, 2, 1, 1);
-  GroupArgumentsLayout->addWidget(filterBtn,            0, 3);
+  GroupArgumentsLayout->addWidget(myFilterBtn,          0, 3);
   GroupArgumentsLayout->addWidget(CheckBoxMesh,         1, 0, 1, 4);
   GroupArgumentsLayout->addWidget(GroupMirror,          2, 0, 1, 4);
   GroupArgumentsLayout->addWidget(ActionBox,            3, 0, 3, 3);
   GroupArgumentsLayout->addWidget(MakeGroupsCheck,      4, 3);
   GroupArgumentsLayout->addWidget(LineEditNewMesh,      5, 3);
+  GroupArgumentsLayout->addWidget(myPreviewCheckBox,    6, 0);
 
   /***************************************************************/
   GroupButtons = new QGroupBox(this);
@@ -261,12 +270,12 @@ SMESHGUI_SymmetryDlg::SMESHGUI_SymmetryDlg( SMESHGUI* theModule )
   SMESHGUI_SymmetryDlgLayout->addWidget(GroupButtons);
 
   /* Initialisations */
-  SpinBox_X->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
-  SpinBox_Y->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
-  SpinBox_Z->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
-  SpinBox_DX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
-  SpinBox_DY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
-  SpinBox_DZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
+  SpinBox_X->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  SpinBox_Y->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  SpinBox_Z->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  SpinBox_DX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  SpinBox_DY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  SpinBox_DZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
 
   RadioButton1->setChecked(true);
 
@@ -312,6 +321,16 @@ SMESHGUI_SymmetryDlg::SMESHGUI_SymmetryDlg( SMESHGUI* theModule )
   connect(CheckBoxMesh,     SIGNAL(toggled(bool)),                 SLOT(onSelectMesh(bool)));
   connect(ActionGroup,      SIGNAL(buttonClicked(int)),            SLOT(onActionClicked(int)));
 
+  connect(SpinBox_X,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(SpinBox_Y,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(SpinBox_Z,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(SpinBox_DX,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(SpinBox_DY,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(SpinBox_DZ,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+
+  //To Connect preview check box
+  connectPreviewControl();
+
   ConstructorsClicked(0);
   SelectionIntoArgument();
   onActionClicked(MOVE_ELEMS_BUTTON);
@@ -358,6 +377,9 @@ void SMESHGUI_SymmetryDlg::Init (bool ResetControls)
 
     ActionGroup->button( MOVE_ELEMS_BUTTON )->setChecked(true);
     CheckBoxMesh->setChecked(false);
+    myPreviewCheckBox->setChecked(false);
+    onDisplaySimulation(false);
+
 //     MakeGroupsCheck->setChecked(false);
 //     MakeGroupsCheck->setEnabled(false);
     onSelectMesh(false);
@@ -416,8 +438,8 @@ void SMESHGUI_SymmetryDlg::ConstructorsClicked (int constructorId)
     SMESH::SetPointRepresentation(false);
     if (!CheckBoxMesh->isChecked())
       {
-       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-         aViewWindow->SetSelectionMode(CellSelection);
+        if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+          aViewWindow->SetSelectionMode(CellSelection);
       }
   }
 
@@ -429,9 +451,11 @@ void SMESHGUI_SymmetryDlg::ConstructorsClicked (int constructorId)
 
   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
 
+  onDisplaySimulation(true);
+
   QApplication::instance()->processEvents();
   updateGeometry();
-  resize( minimumSize() );
+  resize(100,100);
 }
 
 //=================================================================================
@@ -456,17 +480,8 @@ bool SMESHGUI_SymmetryDlg::ClickOnApply()
       anElementsId[i] = aListElementsId[i].toInt();
 
     SMESH::AxisStruct aMirror;
-
-    aMirror.x =  SpinBox_X->GetValue();
-    aMirror.y =  SpinBox_Y->GetValue();
-    aMirror.z =  SpinBox_Z->GetValue();
-    if (GetConstructorId() == 0) {
-      aMirror.vx = aMirror.vy = aMirror.vz = 0;
-    } else {
-      aMirror.vx = SpinBox_DX->GetValue();
-      aMirror.vy = SpinBox_DY->GetValue();
-      aMirror.vz = SpinBox_DZ->GetValue();
-    }
+    SMESH::SMESH_MeshEditor::MirrorType aMirrorType;
+    getMirror(aMirror,aMirrorType);
 
     QStringList aParameters;
     aParameters << SpinBox_X->text();
@@ -476,31 +491,22 @@ bool SMESHGUI_SymmetryDlg::ClickOnApply()
     aParameters << ( GetConstructorId() == 0 ? QString::number(0) : SpinBox_DY->text() );
     aParameters << ( GetConstructorId() == 0 ? QString::number(0) : SpinBox_DZ->text() );
 
-    SMESH::SMESH_MeshEditor::MirrorType aMirrorType;
-
-    if (GetConstructorId() == 0)
-      aMirrorType = SMESH::SMESH_MeshEditor::POINT;
-    if (GetConstructorId() == 1)
-      aMirrorType = SMESH::SMESH_MeshEditor::AXIS;
-    if (GetConstructorId() == 2)
-      aMirrorType = SMESH::SMESH_MeshEditor::PLANE;
-
     int actionButton = ActionGroup->checkedId();
     bool makeGroups = ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() );
-
+    QStringList anEntryList;
     try {
       SUIT_OverrideCursor aWaitCursor;
       SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
 
+      myMesh->SetParameters(aParameters.join(":").toLatin1().constData());
+
       switch ( actionButton ) {
       case MOVE_ELEMS_BUTTON: {
         if(CheckBoxMesh->isChecked())
           aMeshEditor->MirrorObject(mySelectedObject, aMirror, aMirrorType, false );
         else
           aMeshEditor->Mirror(anElementsId, aMirror, aMirrorType, false );
-        
-       if( !myMesh->_is_nil())
-         myMesh->SetParameters(SMESHGUI::JoinObjectParameters(aParameters));
+
         break;
       }
       case COPY_ELEMS_BUTTON: {
@@ -517,34 +523,44 @@ bool SMESHGUI_SymmetryDlg::ClickOnApply()
           else
             aMeshEditor->Mirror(anElementsId, aMirror, aMirrorType, true);
         }
-       if( !myMesh->_is_nil())
-         myMesh->SetParameters(SMESHGUI::JoinObjectParameters(aParameters));
         break;
         }
       case MAKE_MESH_BUTTON: {
         SMESH::SMESH_Mesh_var mesh;
-        if(CheckBoxMesh->isChecked())
+        if (CheckBoxMesh->isChecked())
           mesh = aMeshEditor->MirrorObjectMakeMesh(mySelectedObject, aMirror, aMirrorType, makeGroups,
                                                    LineEditNewMesh->text().toLatin1().data());
         else
           mesh = aMeshEditor->MirrorMakeMesh(anElementsId, aMirror, aMirrorType, makeGroups,
                                              LineEditNewMesh->text().toLatin1().data());
-       if( !mesh->_is_nil())
-         mesh->SetParameters(SMESHGUI::JoinObjectParameters(aParameters));
+          if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( mesh ) )
+            anEntryList.append( aSObject->GetID().c_str() );
+#ifdef WITHGENERICOBJ
+          // obj has been published in study. Its refcount has been incremented.
+          // It is safe to decrement its refcount
+          // so that it will be destroyed when the entry in study will be removed
+          mesh->UnRegister();
+#endif
+        }
         break;
       }
-      }
     } catch (...) {
     }
-    
+
     SMESH::UpdateView();
-    if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ||
-         actionButton == MAKE_MESH_BUTTON )
+    if ( ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ) ||
+         actionButton == MAKE_MESH_BUTTON ) {
       mySMESHGUI->updateObjBrowser(true); // new groups may appear
+      if( LightApp_Application* anApp =
+          dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
+        anApp->browseObjects( anEntryList, isApplyAndClose() );
+    }
     Init(false);
     ConstructorsClicked(GetConstructorId());
     mySelectedObject = SMESH::SMESH_IDSource::_nil();
     SelectionIntoArgument();
+
+    SMESHGUI::Modified();
   }
   return true;
 }
@@ -555,6 +571,7 @@ bool SMESHGUI_SymmetryDlg::ClickOnApply()
 //=================================================================================
 void SMESHGUI_SymmetryDlg::ClickOnOk()
 {
+  setIsApplyAndClose( true );
   if( ClickOnApply() )
     ClickOnCancel();
 }
@@ -585,7 +602,7 @@ void SMESHGUI_SymmetryDlg::ClickOnCancel()
 void SMESHGUI_SymmetryDlg::ClickOnHelp()
 {
   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
-  if (app) 
+  if (app)
     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
   else {
     QString platform;
@@ -595,10 +612,10 @@ void SMESHGUI_SymmetryDlg::ClickOnHelp()
     platform = "application";
 #endif
     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser",
-                                                                platform)).
-                            arg(myHelpFileName));
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser",
+                                                                 platform)).
+                             arg(myHelpFileName));
   }
 }
 
@@ -628,21 +645,21 @@ void SMESHGUI_SymmetryDlg::onTextChange (const QString& theNewText)
     Handle(SALOME_InteractiveObject) anIO = myActor->getIO();
 
     TColStd_MapOfInteger newIndices;
-    
+
     QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
 
     if (send == LineEditElements) {
       for (int i = 0; i < aListId.count(); i++) {
-       const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt());
-       if (e)
-         newIndices.Add(e->GetID());
-       myNbOkElements++;
+        const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt());
+        if (e)
+          newIndices.Add(e->GetID());
+        myNbOkElements++;
       }
 
       mySelector->AddOrRemoveIndex( anIO, newIndices, false );
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-       aViewWindow->highlight( anIO, true, true );
-      
+        aViewWindow->highlight( anIO, true, true );
+
       myElementsId = theNewText;
     }
   }
@@ -695,7 +712,7 @@ void SMESHGUI_SymmetryDlg::SelectionIntoArgument()
   myActor = SMESH::FindActorByObject(myMesh);
   if (!myActor)
     myActor = SMESH::FindActorByEntry(IO->getEntry());
-  if (!myActor)
+  if (!myActor && !CheckBoxMesh->isChecked())
     return;
 
   int aNbUnits = 0;
@@ -732,7 +749,6 @@ void SMESHGUI_SymmetryDlg::SelectionIntoArgument()
             aNbUnits++;
           }
         }
-        
       } else if (!SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(IO)->_is_nil()) { //SUBMESH
         // get submesh
         SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(IO);
@@ -745,7 +761,6 @@ void SMESHGUI_SymmetryDlg::SelectionIntoArgument()
           myElementsId += QString(" %1").arg(anElementsIds[i]);
         }
         aNbUnits = anElementsIds->length();
-        
       } else { // GROUP
         // get smesh group
         SMESH::SMESH_GroupBase_var aGroup =
@@ -768,7 +783,7 @@ void SMESHGUI_SymmetryDlg::SelectionIntoArgument()
       if (aNbUnits < 1)
         return;
     }
-    
+
     myNbOkElements = true;
   } else {
     aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
@@ -803,7 +818,7 @@ void SMESHGUI_SymmetryDlg::SelectionIntoArgument()
     LineEditElements->setText(aString);
     LineEditElements->repaint();
     LineEditElements->setEnabled(false); // to update lineedit IPAL 19809
-    LineEditElements->setEnabled(true); 
+    LineEditElements->setEnabled(true);
     setNewMeshName();
   }
   myBusy = false;
@@ -813,6 +828,7 @@ void SMESHGUI_SymmetryDlg::SelectionIntoArgument()
     buttonOk->setEnabled(true);
     buttonApply->setEnabled(true);
   }
+  onDisplaySimulation(true);
 }
 
 //=================================================================================
@@ -832,11 +848,11 @@ void SMESHGUI_SymmetryDlg::SetEditCurrentArgument()
     SMESH::SetPointRepresentation(false);
     if (CheckBoxMesh->isChecked()) {
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-       aViewWindow->SetSelectionMode(ActorSelection);
+        aViewWindow->SetSelectionMode(ActorSelection);
       mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter);
     } else {
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-       aViewWindow->SetSelectionMode(CellSelection);
+        aViewWindow->SetSelectionMode(CellSelection);
     }
   } else if (send == SelectPointButton) {
     myEditCurrentArgument = (QWidget*)SpinBox_X;
@@ -931,6 +947,7 @@ void SMESHGUI_SymmetryDlg::onSelectMesh (bool toSelectMesh)
     TextLabelElements->setText(tr("SMESH_NAME"));
   else
     TextLabelElements->setText(tr("SMESH_ID_ELEMENTS"));
+  myFilterBtn->setEnabled(!toSelectMesh);
 
   if (myEditCurrentArgument != LineEditElements) {
     LineEditElements->clear();
@@ -952,6 +969,7 @@ void SMESHGUI_SymmetryDlg::onSelectMesh (bool toSelectMesh)
     LineEditElements->setReadOnly(false);
     LineEditElements->setValidator(myIdValidator);
     onTextChange(LineEditElements->text());
+    hidePreview();
   }
 
   SelectionIntoArgument();
@@ -1027,6 +1045,7 @@ void SMESHGUI_SymmetryDlg::onActionClicked(int button)
     break;
   }
   setNewMeshName();
+  toDisplaySimulation();
 }
 
 //=======================================================================
@@ -1073,6 +1092,12 @@ void SMESHGUI_SymmetryDlg::keyPressEvent( QKeyEvent* e )
 //=================================================================================
 void SMESHGUI_SymmetryDlg::setFilters()
 {
+  if(myMesh->_is_nil()) {
+    SUIT_MessageBox::critical(this,
+                              tr("SMESH_ERROR"),
+                              tr("NO_MESH_SELECTED"));
+   return;
+  }
   if ( !myFilterDlg )
     myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL );
 
@@ -1110,3 +1135,68 @@ bool SMESHGUI_SymmetryDlg::isValid()
   }
   return true;
 }
+
+//=================================================================================
+// function : onDisplaySimulation
+// purpose  : Show/Hide preview
+//=================================================================================
+void SMESHGUI_SymmetryDlg::onDisplaySimulation( bool toDisplayPreview ) {
+  if (myPreviewCheckBox->isChecked() && toDisplayPreview) {
+    if ( myNbOkElements && isValid() && IsMirrorOk() ) {
+      QStringList aListElementsId = myElementsId.split(" ", QString::SkipEmptyParts);      
+      SMESH::long_array_var anElementsId = new SMESH::long_array;
+
+      anElementsId->length(aListElementsId.count());
+      for (int i = 0; i < aListElementsId.count(); i++)
+        anElementsId[i] = aListElementsId[i].toInt();
+
+      SMESH::AxisStruct aMirror;
+      SMESH::SMESH_MeshEditor::MirrorType aMirrorType;
+      
+      getMirror(aMirror,aMirrorType);
+
+      try {
+        bool copy = ( ActionGroup->checkedId() == COPY_ELEMS_BUTTON ||
+                      ActionGroup->checkedId() == MAKE_MESH_BUTTON );
+        SUIT_OverrideCursor aWaitCursor;
+        SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditPreviewer();
+        if(CheckBoxMesh->isChecked())
+          aMeshEditor->MirrorObject(mySelectedObject, aMirror, aMirrorType, copy );
+        else
+          aMeshEditor->Mirror(anElementsId, aMirror, aMirrorType, copy );
+        
+        SMESH::MeshPreviewStruct_var aMeshPreviewStruct = aMeshEditor->GetPreviewData();
+        mySimulation->SetData(aMeshPreviewStruct._retn());
+      } catch (...) {
+        hidePreview();
+      }
+    } else {
+      hidePreview();
+    } 
+  } else {
+    hidePreview();
+  }
+}
+
+//=================================================================================
+// function : getMirror
+// purpose  : return mirror parameters
+//=================================================================================
+void SMESHGUI_SymmetryDlg::getMirror(SMESH::AxisStruct& theMirror, SMESH::SMESH_MeshEditor::MirrorType& theMirrorType) {
+  theMirror.x =  SpinBox_X->GetValue();
+  theMirror.y =  SpinBox_Y->GetValue();
+  theMirror.z =  SpinBox_Z->GetValue();
+  if (GetConstructorId() == 0) {
+    theMirror.vx = theMirror.vy = theMirror.vz = 0;
+  } else {
+    theMirror.vx = SpinBox_DX->GetValue();
+    theMirror.vy = SpinBox_DY->GetValue();
+    theMirror.vz = SpinBox_DZ->GetValue();
+  }
+  if (GetConstructorId() == 0)
+    theMirrorType = SMESH::SMESH_MeshEditor::POINT;
+  if (GetConstructorId() == 1)
+    theMirrorType = SMESH::SMESH_MeshEditor::AXIS;
+  if (GetConstructorId() == 2)
+    theMirrorType = SMESH::SMESH_MeshEditor::PLANE;
+}
index c56317d0bcbf7203f4472fcf0a7b00d331899ac7..a039ac27fef9a8b5c38a27d4c6c6137a868e45dc 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_SymmetryDlg.h
 // Author : Michael ZORIN, Open CASCADE S.A.S.
 
 // SMESH includes
 #include "SMESH_SMESHGUI.hxx"
-
-// Qt includes
-#include <QDialog>
+#include "SMESHGUI_PreviewDlg.h"
 
 // IDL includes
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
 
 class QButtonGroup;
 class QGroupBox;
@@ -56,7 +56,7 @@ class SMESH_LogicalFilter;
 // class    : SMESHGUI_SymmetryDlg
 // purpose  :
 //=================================================================================
-class SMESHGUI_EXPORT SMESHGUI_SymmetryDlg : public QDialog
+class SMESHGUI_EXPORT SMESHGUI_SymmetryDlg : public SMESHGUI_PreviewDlg
 { 
   Q_OBJECT
 
@@ -74,9 +74,10 @@ private:
   bool                   IsMirrorOk();
   void                   setNewMeshName();
 
+  void                   getMirror(SMESH::AxisStruct& theMirror, SMESH::SMESH_MeshEditor::MirrorType& aMirrorType);
+
   bool                   isValid();
 
-  SMESHGUI*              mySMESHGUI;              /* Current SMESHGUI object */
   SMESHGUI_IdValidator*  myIdValidator;
   LightApp_SelectionMgr* mySelectionMgr;          /* User shape selection */
   int                    myNbOkElements;          /* to check when elements are defined */
@@ -133,7 +134,11 @@ private:
 
   QString                myHelpFileName;
    
+  QPushButton*           myFilterBtn;
   SMESHGUI_FilterDlg*    myFilterDlg;
+
+protected slots:
+  virtual void           onDisplaySimulation( bool );
    
 private slots:
   void                   ConstructorsClicked( int );
index 091446d10f7ebbad02595cdd10a65b52ca52e792..31ff3a796bc8b733043caf32945176b08df20fe4 100644 (file)
@@ -1,29 +1,28 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
-//
-// SMESH SMESHGUI : GUI for SMESH component
-// File   : SMESHGUI_TranslationDlg.cxx
-// Author : Michael ZORIN, Open CASCADE S.A.S.
-// SMESH includes
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+//  File   : SMESHGUI_TranslationDlg.cxx
+//  Author : Michael ZORIN, Open CASCADE S.A.S.
+//  SMESH includes
+
 #include "SMESHGUI_TranslationDlg.h"
 
 #include "SMESHGUI.h"
@@ -33,6 +32,7 @@
 #include "SMESHGUI_MeshUtils.h"
 #include "SMESHGUI_IdValidator.h"
 #include "SMESHGUI_FilterDlg.h"
+#include "SMESHGUI_MeshEditPreview.h"
 
 #include <SMESH_Actor.h>
 #include <SMESH_TypeFilter.hxx>
@@ -101,16 +101,19 @@ private:
 #define SPACING 6
 #define MARGIN  11
 
+//To disable automatic genericobj management, the following line should be commented.
+//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
+#define WITHGENERICOBJ
+
 //=================================================================================
 // class    : SMESHGUI_TranslationDlg()
 // purpose  :
 //=================================================================================
-SMESHGUI_TranslationDlg::SMESHGUI_TranslationDlg( SMESHGUI* theModule )
-  : QDialog( SMESH::GetDesktop( theModule ) ),
-    mySMESHGUI( theModule ),
-    mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
-    myFilterDlg(0),
-    mySelectedObject(SMESH::SMESH_IDSource::_nil())
+SMESHGUI_TranslationDlg::SMESHGUI_TranslationDlg( SMESHGUI* theModule ) : 
+  SMESHGUI_PreviewDlg( theModule ),
+  mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
+  myFilterDlg(0),
+  mySelectedObject(SMESH::SMESH_IDSource::_nil())
 {
   QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SMESH_TRANSLATION_POINTS")));
   QPixmap image1 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SMESH_TRANSLATION_VECTOR")));
@@ -156,8 +159,9 @@ SMESHGUI_TranslationDlg::SMESHGUI_TranslationDlg( SMESHGUI* theModule )
   SelectElementsButton->setIcon(image2);
   LineEditElements = new QLineEdit(GroupArguments);
   LineEditElements->setValidator(myIdValidator);
-  QPushButton* filterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
-  connect(filterBtn,   SIGNAL(clicked()), this, SLOT(setFilters()));
+  LineEditElements->setMaxLength(-1);
+  myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
+  connect(myFilterBtn,   SIGNAL(clicked()), this, SLOT(setFilters()));
 
   // Control for the whole mesh selection
   CheckBoxMesh = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments);
@@ -210,11 +214,14 @@ SMESHGUI_TranslationDlg::SMESHGUI_TranslationDlg( SMESHGUI* theModule )
   // Name of a mesh to create
   LineEditNewMesh = new QLineEdit(GroupArguments);
 
+  //Preview check box
+  myPreviewCheckBox = new QCheckBox(tr("PREVIEW"), GroupArguments);
+
   // layout
   GroupArgumentsLayout->addWidget(TextLabelElements,    0, 0);
   GroupArgumentsLayout->addWidget(SelectElementsButton, 0, 1);
   GroupArgumentsLayout->addWidget(LineEditElements,     0, 2, 1, 5);
-  GroupArgumentsLayout->addWidget(filterBtn,            0, 7);
+  GroupArgumentsLayout->addWidget(myFilterBtn,          0, 7);
   GroupArgumentsLayout->addWidget(CheckBoxMesh,         1, 0, 1, 8);
   GroupArgumentsLayout->addWidget(TextLabel1,           2, 0);
   GroupArgumentsLayout->addWidget(SelectButton1,        2, 1);
@@ -235,6 +242,7 @@ SMESHGUI_TranslationDlg::SMESHGUI_TranslationDlg( SMESHGUI* theModule )
   GroupArgumentsLayout->addWidget(ActionBox,            4, 0, 3, 4);
   GroupArgumentsLayout->addWidget(MakeGroupsCheck,      5, 5, 1, 4);
   GroupArgumentsLayout->addWidget(LineEditNewMesh,      6, 5, 1, 4);
+  GroupArgumentsLayout->addWidget(myPreviewCheckBox,    7, 0);
 
   /***************************************************************/
   GroupButtons = new QGroupBox(this);
@@ -266,12 +274,12 @@ SMESHGUI_TranslationDlg::SMESHGUI_TranslationDlg( SMESHGUI* theModule )
   SMESHGUI_TranslationDlgLayout->addWidget(GroupButtons);
 
   /* Initialisations */
-  SpinBox1_1->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, DBL_DIGITS_DISPLAY);
-  SpinBox1_2->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, DBL_DIGITS_DISPLAY);
-  SpinBox1_3->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, DBL_DIGITS_DISPLAY);
-  SpinBox2_1->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, DBL_DIGITS_DISPLAY);
-  SpinBox2_2->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, DBL_DIGITS_DISPLAY);
-  SpinBox2_3->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, DBL_DIGITS_DISPLAY);
+  SpinBox1_1->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  SpinBox1_2->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  SpinBox1_3->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  SpinBox2_1->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  SpinBox2_2->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
+  SpinBox2_3->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision");
 
   RadioButton1->setChecked(true);
 
@@ -313,6 +321,19 @@ SMESHGUI_TranslationDlg::SMESHGUI_TranslationDlg( SMESHGUI* theModule )
   connect(CheckBoxMesh,     SIGNAL(toggled(bool)),                  SLOT(onSelectMesh(bool)));
   connect(ActionGroup,      SIGNAL(buttonClicked(int)),             SLOT(onActionClicked(int)));
 
+  connect(SpinBox1_1,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(SpinBox1_2,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(SpinBox1_3,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+
+  connect(SpinBox2_1,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(SpinBox2_2,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(SpinBox2_3,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+  connect(SpinBox2_3,  SIGNAL(valueChanged(double)), this, SLOT(toDisplaySimulation()));
+
+  
+  //To Connect preview check box
+  connectPreviewControl();
+
   ConstructorsClicked(0);
   SelectionIntoArgument();
   onActionClicked(MOVE_ELEMS_BUTTON);
@@ -362,6 +383,8 @@ void SMESHGUI_TranslationDlg::Init (bool ResetControls)
     CheckBoxMesh->setChecked(false);
 //     MakeGroupsCheck->setChecked(false);
 //     MakeGroupsCheck->setEnabled(false);
+    myPreviewCheckBox->setChecked(false);
+    onDisplaySimulation(false);
     onSelectMesh(false);
   }
 }
@@ -417,7 +440,7 @@ void SMESHGUI_TranslationDlg::ConstructorsClicked (int constructorId)
     SMESH::SetPointRepresentation(false);
     if (!CheckBoxMesh->isChecked())
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-       aViewWindow->SetSelectionMode( CellSelection );
+        aViewWindow->SetSelectionMode( CellSelection );
   }
 
   myEditCurrentArgument = (QWidget*)LineEditElements;
@@ -428,9 +451,11 @@ void SMESHGUI_TranslationDlg::ConstructorsClicked (int constructorId)
 
   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
 
+  onDisplaySimulation(true);
+
   QApplication::instance()->processEvents();
   updateGeometry();
-  resize( minimumSize() );
+  resize(100,100);
 }
 
 //=================================================================================
@@ -455,44 +480,43 @@ bool SMESHGUI_TranslationDlg::ClickOnApply()
       anElementsId[i] = aListElementsId[i].toInt();
 
     SMESH::DirStruct aVector;
+    QStringList aParameters;
     if (GetConstructorId() == 0) {
       aVector.PS.x = SpinBox2_1->GetValue() - SpinBox1_1->GetValue();
       aVector.PS.y = SpinBox2_2->GetValue() - SpinBox1_2->GetValue();
       aVector.PS.z = SpinBox2_3->GetValue() - SpinBox1_3->GetValue();
+      // not supported so far
+      // aParameters << QString("%1 - %2").arg( SpinBox2_1->text() ).arg( SpinBox1_1->text() );
+      // aParameters << QString("%1 - %2").arg( SpinBox2_2->text() ).arg( SpinBox1_2->text() );
+      // aParameters << QString("%1 - %2").arg( SpinBox2_3->text() ).arg( SpinBox1_3->text() );
     } else if (GetConstructorId() == 1) {
       aVector.PS.x = SpinBox1_1->GetValue();
       aVector.PS.y = SpinBox1_2->GetValue();
       aVector.PS.z = SpinBox1_3->GetValue();
+      aParameters << SpinBox1_1->text();
+      aParameters << SpinBox1_2->text();
+      aParameters << SpinBox1_3->text();
     }
 
-    QStringList aParameters;
-    aParameters << SpinBox1_1->text();
-    if (GetConstructorId() == 0)
-      aParameters << SpinBox2_1->text();
-    aParameters << SpinBox1_2->text();
-    if (GetConstructorId() == 0)
-      aParameters << SpinBox2_2->text();
-    aParameters << SpinBox1_3->text();
-    if (GetConstructorId() == 0)
-      aParameters << SpinBox2_3->text();
-
     int actionButton = ActionGroup->checkedId();
     bool makeGroups = ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() );
+    QStringList anEntryList;
     try {
       SUIT_OverrideCursor aWaitCursor;
       SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
+
+      myMesh->SetParameters(aParameters.join(":").toLatin1().constData());
+
       switch ( actionButton ) {
       case MOVE_ELEMS_BUTTON:
         if(CheckBoxMesh->isChecked())
           aMeshEditor->TranslateObject(mySelectedObject, aVector, false);
         else
           aMeshEditor->Translate(anElementsId, aVector, false);
-       if( !myMesh->_is_nil())
-         myMesh->SetParameters(SMESHGUI::JoinObjectParameters(aParameters));
         break;
       case COPY_ELEMS_BUTTON:
         if ( makeGroups ) {
-          SMESH::ListOfGroups_var groups; 
+          SMESH::ListOfGroups_var groups;
           if(CheckBoxMesh->isChecked())
             groups = aMeshEditor->TranslateObjectMakeGroups(mySelectedObject,aVector);
           else
@@ -504,33 +528,45 @@ bool SMESHGUI_TranslationDlg::ClickOnApply()
           else
             aMeshEditor->Translate(anElementsId, aVector, true);
         }
-       if( !myMesh->_is_nil())
-         myMesh->SetParameters(SMESHGUI::JoinObjectParameters(aParameters));
         break;
-      case MAKE_MESH_BUTTON:
-        SMESH::SMESH_Mesh_var mesh; 
-        if(CheckBoxMesh->isChecked())
+      case MAKE_MESH_BUTTON: {
+        SMESH::SMESH_Mesh_var mesh;
+        if (CheckBoxMesh->isChecked())
           mesh = aMeshEditor->TranslateObjectMakeMesh(mySelectedObject, aVector, makeGroups,
                                                       LineEditNewMesh->text().toLatin1().data());
         else
           mesh = aMeshEditor->TranslateMakeMesh(anElementsId, aVector, makeGroups,
                                                 LineEditNewMesh->text().toLatin1().data());
-       if( !mesh->_is_nil())
-         mesh->SetParameters(SMESHGUI::JoinObjectParameters(aParameters));
+          if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( mesh ) )
+            anEntryList.append( aSObject->GetID().c_str() );
+#ifdef WITHGENERICOBJ
+          // obj has been published in study. Its refcount has been incremented.
+          // It is safe to decrement its refcount
+          // so that it will be destroyed when the entry in study will be removed
+          mesh->UnRegister();
+#endif
+        }
       }
     } catch (...) {
     }
-    
+
     SMESH::UpdateView();
-    if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ||
-         actionButton == MAKE_MESH_BUTTON )
+    if ( ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() ) ||
+         actionButton == MAKE_MESH_BUTTON ) {
       mySMESHGUI->updateObjBrowser(true); // new groups may appear
+      if( LightApp_Application* anApp =
+          dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
+        anApp->browseObjects( anEntryList, isApplyAndClose() );
+    }
+      
     Init(false);
     ConstructorsClicked(GetConstructorId());
     mySelectedObject = SMESH::SMESH_IDSource::_nil();
     SelectionIntoArgument();
+
+    SMESHGUI::Modified();
   }
-  
+
   return true;
 }
 
@@ -540,6 +576,7 @@ bool SMESHGUI_TranslationDlg::ClickOnApply()
 //=================================================================================
 void SMESHGUI_TranslationDlg::ClickOnOk()
 {
+  setIsApplyAndClose( true );
   if( ClickOnApply() )
     ClickOnCancel();
 }
@@ -570,7 +607,7 @@ void SMESHGUI_TranslationDlg::ClickOnCancel()
 void SMESHGUI_TranslationDlg::ClickOnHelp()
 {
   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
-  if (app) 
+  if (app)
     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
   else {
     QString platform;
@@ -580,10 +617,10 @@ void SMESHGUI_TranslationDlg::ClickOnHelp()
     platform = "application";
 #endif
     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser", 
-                                                                platform)).
-                            arg(myHelpFileName));
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser",
+                                                                 platform)).
+                             arg(myHelpFileName));
   }
 }
 
@@ -611,24 +648,24 @@ void SMESHGUI_TranslationDlg::onTextChange (const QString& theNewText)
 
   if (aMesh) {
     Handle(SALOME_InteractiveObject) anIO = myActor->getIO();
-    
+
     TColStd_MapOfInteger newIndices;
 
     QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
 
     if (send == LineEditElements) {
       for (int i = 0; i < aListId.count(); i++) {
-       const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt());
-       if (e)
-         newIndices.Add(e->GetID());
-       myNbOkElements++;
+        const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt());
+        if (e)
+          newIndices.Add(e->GetID());
+        myNbOkElements++;
       }
     }
 
     mySelector->AddOrRemoveIndex( anIO, newIndices, false );
     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
       aViewWindow->highlight( anIO, true, true );
-    
+
     myElementsId = theNewText;
   }
 
@@ -669,19 +706,24 @@ void SMESHGUI_TranslationDlg::SelectionIntoArgument()
     return;
 
   Handle(SALOME_InteractiveObject) IO = aList.First();
-  myMesh = SMESH::GetMeshByIO(IO);
-  if (myMesh->_is_nil())
+  SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(IO);
+  if (aMesh->_is_nil())
     return;
 
-  myActor = SMESH::FindActorByObject(myMesh);
-  if (!myActor)
-    myActor = SMESH::FindActorByEntry(IO->getEntry());
-  if (!myActor)
-    return;
+  SMESH_Actor* anActor = SMESH::FindActorByObject(aMesh);
+  if (!anActor)
+    anActor = SMESH::FindActorByEntry(IO->getEntry());
+
+  if (!anActor && !CheckBoxMesh->isChecked())
+      return;
 
   int aNbUnits = 0;
 
-  if (myEditCurrentArgument == (QWidget*)LineEditElements) {
+  if (myEditCurrentArgument == (QWidget*)LineEditElements)
+  {
+    myMesh = aMesh;
+    myActor = anActor;
+
     myElementsId = "";
 
     // MakeGroups is available if there are groups and "Copy"
@@ -701,51 +743,11 @@ void SMESHGUI_TranslationDlg::SelectionIntoArgument()
       }
       else
         return;
-        // get IDs from mesh
-        /*
-        SMDS_Mesh* aSMDSMesh = myActor->GetObject()->GetMesh();
-        if (!aSMDSMesh)
-          return;
-
-        for (int i = aSMDSMesh->MinElementID(); i <= aSMDSMesh->MaxElementID(); i++) {
-          const SMDS_MeshElement * e = aSMDSMesh->FindElement(i);
-          if (e) {
-            myElementsId += QString(" %1").arg(i);
-            aNbUnits++;
-          }
-        }
-      } else if (!SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(IO)->_is_nil()) { //SUBMESH
-        // get submesh
-        SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(IO);
-
-        // get IDs from submesh
-        SMESH::long_array_var anElementsIds = new SMESH::long_array;
-        anElementsIds = aSubMesh->GetElementsId();
-        for (int i = 0; i < anElementsIds->length(); i++) {
-          myElementsId += QString(" %1").arg(anElementsIds[i]);
-        }
-        aNbUnits = anElementsIds->length();
-      } else { // GROUP
-        // get smesh group
-        SMESH::SMESH_GroupBase_var aGroup =
-          SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(IO);
-        if (aGroup->_is_nil())
-          return;
-
-        // get IDs from smesh group
-        SMESH::long_array_var anElementsIds = new SMESH::long_array;
-        anElementsIds = aGroup->GetListOfID();
-        for (int i = 0; i < anElementsIds->length(); i++) {
-          myElementsId += QString(" %1").arg(anElementsIds[i]);
-        }
-        aNbUnits = anElementsIds->length();
-      }
-        */
     } else {
       aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, IO, aString);
       myElementsId = aString;
       if (aNbUnits < 1)
-        return;  
+        return;
     }
 
     myNbOkElements = true;
@@ -754,7 +756,7 @@ void SMESHGUI_TranslationDlg::SelectionIntoArgument()
     if (aNbUnits != 1)
       return;
 
-    SMDS_Mesh* aMesh =  myActor->GetObject()->GetMesh();
+    SMDS_Mesh* aMesh =  anActor->GetObject()->GetMesh();
     if (!aMesh)
       return;
 
@@ -781,7 +783,7 @@ void SMESHGUI_TranslationDlg::SelectionIntoArgument()
     LineEditElements->setText(aString);
     LineEditElements->repaint();
     LineEditElements->setEnabled(false); // to fully update lineedit IPAL 19809
-    LineEditElements->setEnabled(true); 
+    LineEditElements->setEnabled(true);
     setNewMeshName();
   }
 
@@ -790,6 +792,7 @@ void SMESHGUI_TranslationDlg::SelectionIntoArgument()
     buttonOk->setEnabled(true);
     buttonApply->setEnabled(true);
   }
+  onDisplaySimulation(true);
 }
 
 //=================================================================================
@@ -803,18 +806,18 @@ void SMESHGUI_TranslationDlg::SetEditCurrentArgument()
   disconnect(mySelectionMgr, 0, this, 0);
   mySelectionMgr->clearSelected();
   mySelectionMgr->clearFilters();
-
+  
   if (send == SelectElementsButton) {
     myEditCurrentArgument = (QWidget*)LineEditElements;
     SMESH::SetPointRepresentation(false);
     if (CheckBoxMesh->isChecked()) {
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-       aViewWindow->SetSelectionMode( ActorSelection );
+        aViewWindow->SetSelectionMode( ActorSelection );
       mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter);
     } else {
 
       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-       aViewWindow->SetSelectionMode( CellSelection );
+        aViewWindow->SetSelectionMode( CellSelection );
     }
   } else if (send == SelectButton1) {
     myEditCurrentArgument = (QWidget*)SpinBox1_1;
@@ -910,6 +913,7 @@ void SMESHGUI_TranslationDlg::onSelectMesh (bool toSelectMesh)
     TextLabelElements->setText(tr("SMESH_NAME"));
   else
     TextLabelElements->setText(tr("SMESH_ID_ELEMENTS"));
+  myFilterBtn->setEnabled(!toSelectMesh);
 
   if (myEditCurrentArgument != LineEditElements) {
     LineEditElements->clear();
@@ -931,6 +935,7 @@ void SMESHGUI_TranslationDlg::onSelectMesh (bool toSelectMesh)
     LineEditElements->setReadOnly(false);
     LineEditElements->setValidator(myIdValidator);
     onTextChange(LineEditElements->text());
+    hidePreview();
   }
 
   SelectionIntoArgument();
@@ -966,6 +971,7 @@ void SMESHGUI_TranslationDlg::onActionClicked(int button)
     break;
   }
   setNewMeshName();
+  toDisplaySimulation();
 }
 
 //=======================================================================
@@ -1021,6 +1027,12 @@ void SMESHGUI_TranslationDlg::keyPressEvent( QKeyEvent* e )
 //=================================================================================
 void SMESHGUI_TranslationDlg::setFilters()
 {
+  if(myMesh->_is_nil()) {
+    SUIT_MessageBox::critical(this,
+                              tr("SMESH_ERROR"),
+                              tr("NO_MESH_SELECTED"));
+   return;
+  }
   if ( !myFilterDlg )
     myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL );
 
@@ -1058,3 +1070,54 @@ bool SMESHGUI_TranslationDlg::isValid()
   }
   return true;
 }
+
+//=================================================================================
+// function : onDisplaySimulation
+// purpose  : Show/Hide preview
+//=================================================================================
+void SMESHGUI_TranslationDlg::onDisplaySimulation( bool toDisplayPreview ) {
+  if (myPreviewCheckBox->isChecked() && toDisplayPreview) {
+    
+    if (isValid() && myNbOkElements) {
+      QStringList aListElementsId = myElementsId.split(" ", QString::SkipEmptyParts);
+      
+      SMESH::long_array_var anElementsId = new SMESH::long_array;
+
+      anElementsId->length(aListElementsId.count());
+      for (int i = 0; i < aListElementsId.count(); i++)
+        anElementsId[i] = aListElementsId[i].toInt();
+
+      SMESH::DirStruct aVector;
+      if (GetConstructorId() == 0) {
+        aVector.PS.x = SpinBox2_1->GetValue() - SpinBox1_1->GetValue();
+        aVector.PS.y = SpinBox2_2->GetValue() - SpinBox1_2->GetValue();
+        aVector.PS.z = SpinBox2_3->GetValue() - SpinBox1_3->GetValue();
+      } else if (GetConstructorId() == 1) {
+        aVector.PS.x = SpinBox1_1->GetValue();
+        aVector.PS.y = SpinBox1_2->GetValue();
+        aVector.PS.z = SpinBox1_3->GetValue();
+      }
+
+      try {
+        bool copy = ( ActionGroup->checkedId() == COPY_ELEMS_BUTTON ||
+                      ActionGroup->checkedId() == MAKE_MESH_BUTTON );
+        SUIT_OverrideCursor aWaitCursor;
+        SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditPreviewer();
+        if(CheckBoxMesh->isChecked())
+          aMeshEditor->TranslateObject(mySelectedObject, aVector, copy);
+        else
+          aMeshEditor->Translate(anElementsId, aVector, copy);
+        
+        SMESH::MeshPreviewStruct_var aMeshPreviewStruct = aMeshEditor->GetPreviewData();
+        mySimulation->SetData(aMeshPreviewStruct._retn());      
+      } catch (...) {
+        
+      }
+    }
+    else {
+      hidePreview();
+    }
+  } else {
+    hidePreview();
+  }
+}
index 279ec596bd9aa53b90c92e407629abf305f5ae81..2c7294378683d247a7ba4419b5988a8f9b25c89d 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_TranslationDlg.h
 // Author : Michael ZORIN, Open CASCADE S.A.S.
@@ -28,9 +29,7 @@
 
 // SMESH includes
 #include "SMESH_SMESHGUI.hxx"
-
-// Qt includes
-#include <QDialog>
+#include "SMESHGUI_PreviewDlg.h"
 
 // IDL includes
 #include <SALOMEconfig.h>
@@ -56,7 +55,7 @@ class SMESH_LogicalFilter;
 // class    : SMESHGUI_TranslationDlg
 // purpose  :
 //=================================================================================
-class SMESHGUI_EXPORT SMESHGUI_TranslationDlg : public QDialog
+class SMESHGUI_EXPORT SMESHGUI_TranslationDlg : public SMESHGUI_PreviewDlg
 { 
   Q_OBJECT
 
@@ -75,7 +74,6 @@ private:
 
   bool                   isValid();
 
-  SMESHGUI*              mySMESHGUI;              /* Current SMESHGUI object */
   SMESHGUI_IdValidator*  myIdValidator;
   LightApp_SelectionMgr* mySelectionMgr;          /* User shape selection */
   QString                myElementsId;
@@ -130,7 +128,11 @@ private:
 
   QString                myHelpFileName;
 
+  QPushButton*           myFilterBtn;
   SMESHGUI_FilterDlg*    myFilterDlg;
+
+protected slots:
+  virtual void              onDisplaySimulation( bool );
    
 private slots:
   void                   ConstructorsClicked( int );
index b979ddffc6bfa7b148d148a02d310c299d39ba39..a279d0be4cf55bb63ff240a6e881e8dfd70e796d 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_TransparencyDlg.cxx
 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
@@ -86,7 +87,7 @@ SMESHGUI_TransparencyDlg::SMESHGUI_TransparencyDlg( SMESHGUI* theModule )
   GroupC1Layout->setMargin( MARGIN );
 
   TextLabelTransparent = new QLabel( tr( "SMESH_TRANSPARENCY_TRANSPARENT" ), GroupC1 );
-  TextLabelTransparent->setAlignment( Qt::AlignLeft );
+  TextLabelTransparent->setAlignment( Qt::AlignRight );
 
   ValueLab = new QLabel( GroupC1 );
   ValueLab->setAlignment( Qt::AlignCenter );
@@ -94,7 +95,7 @@ SMESHGUI_TransparencyDlg::SMESHGUI_TransparencyDlg( SMESHGUI* theModule )
   QFont fnt = ValueLab->font(); fnt.setBold( true ); ValueLab->setFont( fnt );
 
   TextLabelOpaque = new QLabel( tr( "SMESH_TRANSPARENCY_OPAQUE" ), GroupC1 );
-  TextLabelOpaque->setAlignment( Qt::AlignRight );
+  TextLabelOpaque->setAlignment( Qt::AlignLeft );
 
   Slider1 = new QSlider( Qt::Horizontal, GroupC1 );
   Slider1->setRange( 0, 100 );
@@ -106,9 +107,9 @@ SMESHGUI_TransparencyDlg::SMESHGUI_TransparencyDlg( SMESHGUI* theModule )
   Slider1->setFocusPolicy( Qt::NoFocus );
   Slider1->setMinimumWidth( 300 );
 
-  GroupC1Layout->addWidget( TextLabelTransparent, 0, 0 );
+  GroupC1Layout->addWidget( TextLabelOpaque, 0, 0 );
   GroupC1Layout->addWidget( ValueLab, 0, 1 );
-  GroupC1Layout->addWidget( TextLabelOpaque, 0, 2 );
+  GroupC1Layout->addWidget( TextLabelTransparent, 0, 2 );
   GroupC1Layout->addWidget( Slider1, 1, 0, 1, 3 );
 
   /*************************************************************************/
@@ -172,7 +173,7 @@ void SMESHGUI_TransparencyDlg::ClickOnHelp()
   LightApp_Application* app = (LightApp_Application*)( SUIT_Session::session()->activeApplication() );
   if ( app )
     app->onHelpContextModule( mySMESHGUI ? app->moduleName( mySMESHGUI->moduleName() ) : 
-                             QString( "" ), myHelpFileName );
+                              QString( "" ), myHelpFileName );
   else {
     QString platform;
 #ifdef WIN32
@@ -181,10 +182,10 @@ void SMESHGUI_TransparencyDlg::ClickOnHelp()
     platform = "application";
 #endif
     SUIT_MessageBox::warning( this, tr( "WRN_WARNING" ),
-                             tr( "EXTERNAL_BROWSER_CANNOT_SHOW_PAGE" ).
-                             arg( app->resourceMgr()->stringValue( "ExternalBrowser", 
-                                                                   platform ) ).
-                             arg( myHelpFileName ) );
+                              tr( "EXTERNAL_BROWSER_CANNOT_SHOW_PAGE" ).
+                              arg( app->resourceMgr()->stringValue( "ExternalBrowser", 
+                                                                    platform ) ).
+                              arg( myHelpFileName ) );
   }
 }
 
@@ -197,7 +198,7 @@ void SMESHGUI_TransparencyDlg::SetTransparency()
 {
   if ( myViewWindow ) {
     SUIT_OverrideCursor wc;
-    float opacity = Slider1->value() / 100.;
+    float opacity = ( 100 - Slider1->value() ) / 100.;
 
     SALOME_ListIO aList;
     mySelectionMgr->selectedObjects( aList );
@@ -207,7 +208,7 @@ void SMESHGUI_TransparencyDlg::SetTransparency()
       Handle(SALOME_InteractiveObject) IOS = It.Value();
       SMESH_Actor* anActor = SMESH::FindActorByEntry( IOS->getEntry() );
       if ( anActor )
-       anActor->SetOpacity( opacity );
+        anActor->SetOpacity( opacity );
     }
     myViewWindow->Repaint();
   }
@@ -238,35 +239,35 @@ void SMESHGUI_TransparencyDlg::onSelectionChanged()
     if ( aList.Extent() == 1 ) {
       Handle(SALOME_InteractiveObject) FirstIOS = aList.First();
       if ( !FirstIOS.IsNull() ) {
-       SMESH_Actor* anActor = SMESH::FindActorByEntry( FirstIOS->getEntry() );
-       if ( anActor )
-         opacity = int( anActor->GetOpacity() * 100. + 0.5 );
+        SMESH_Actor* anActor = SMESH::FindActorByEntry( FirstIOS->getEntry() );
+        if ( anActor )
+          opacity = int( anActor->GetOpacity() * 100. + 0.5 );
       }
     } 
     else if ( aList.Extent() > 1 ) {
       SALOME_ListIteratorOfListIO It( aList );
       int setOp = -1;
       for ( ; It.More(); It.Next() ) {
-       Handle(SALOME_InteractiveObject) IO = It.Value();
-       if ( !IO.IsNull() ) {
-         SMESH_Actor* anActor = SMESH::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;
-           }
-         }
-       }
+        Handle(SALOME_InteractiveObject) IO = It.Value();
+        if ( !IO.IsNull() ) {
+          SMESH_Actor* anActor = SMESH::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;
+        opacity = setOp;
     } 
     else {
     }
-    Slider1->setValue( opacity );
+    Slider1->setValue( 100 - opacity );
   }
   ValueHasChanged();
 }
index 28595ed7e4846f63a3eb157efd8dd15c133b7182..7659b59cc19bdd419b0929e1c63189451dd94c66 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_TransparencyDlg.h
 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
index 33eb25b96c62066fe11c62e2a03275aaf32b1935..94ef5c93b6b896f44ebfdc9a3c60079116e361bf 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_Utils.cxx
 // Author : Open CASCADE S.A.S.
@@ -26,6 +27,8 @@
 //
 #include "SMESHGUI_Utils.h"
 #include "SMESHGUI.h"
+#include "SMESHGUI_Selection.h"
+#include "SMESH_Type.h"
 
 #include <SMDS_MeshNode.hxx>
 #include <SMDS_MeshFace.hxx>
@@ -47,6 +50,8 @@
 #include <gp_XYZ.hxx>
 #include <TColgp_Array1OfXYZ.hxx>
 
+#include CORBA_SERVER_HEADER(SMESH_Group)
+
 namespace SMESH
 {
   SUIT_Desktop*
@@ -80,11 +85,11 @@ namespace SMESH
     if(theOwner){
       const Handle(SALOME_InteractiveObject)& anIO = theOwner->IO();
       if(!anIO.IsNull()){
-       if(anIO->hasEntry()){
-         _PTR(Study) aStudy = GetActiveStudyDocument();
-         _PTR(SObject) aSObj = aStudy->FindObjectID(anIO->getEntry());
-         anObj = SObjectToObject(aSObj,aStudy);
-       }
+        if(anIO->hasEntry()){
+          _PTR(Study) aStudy = GetActiveStudyDocument();
+          _PTR(SObject) aSObj = aStudy->FindObjectID(anIO->getEntry());
+          anObj = SObjectToObject(aSObj,aStudy);
+        }
       }
     }
     return anObj;
@@ -124,9 +129,9 @@ namespace SMESH
       (SUIT_Session::session()->activeApplication());
     if (app && !CORBA::is_nil(theObject)) {
       if(_PTR(Study) aStudy = GetActiveStudyDocument()){
-       CORBA::String_var anIOR = app->orb()->object_to_string(theObject);
-       if (strcmp(anIOR.in(), "") != 0)
-         return aStudy->FindObjectIOR(anIOR.in());
+        CORBA::String_var anIOR = app->orb()->object_to_string(theObject);
+        if (strcmp(anIOR.in(), "") != 0)
+          return aStudy->FindObjectIOR(anIOR.in());
       }
     }
     return _PTR(SObject)();
@@ -187,9 +192,12 @@ namespace SMESH
     if (theSObject) {
       _PTR(GenericAttribute) anAttr;
       if (theSObject->FindAttribute(anAttr, "AttributeIOR")) {
-       _PTR(AttributeIOR) anIOR = anAttr;
-       CORBA::String_var aVal = anIOR->Value().c_str();
-       return app->orb()->string_to_object(aVal);
+        _PTR(AttributeIOR) anIOR = anAttr;
+        CORBA::String_var aVal = anIOR->Value().c_str();
+        // string_to_object() DOC: If the input string is not valid ...
+        // a CORBA::SystemException is thrown.
+        if ( aVal && strlen( aVal ) > 0 )
+          return app->orb()->string_to_object(aVal);
       }
     }
     return CORBA::Object::_nil();
@@ -201,13 +209,27 @@ namespace SMESH
     return SObjectToObject(theSObject,aStudy);
   }
 
+  _PTR(SObject) ObjectToSObject( CORBA::Object_ptr theObject )
+  {
+    _PTR(SObject) res;
+    SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>
+      (SUIT_Session::session()->activeApplication());
+    if ( app ) {
+      QString IOR = app->orb()->object_to_string( theObject );
+      SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
+      if ( study && !IOR.isEmpty() )
+        res = study->studyDS()->FindObjectIOR( IOR.toLatin1().constData() );
+    }
+    return res;
+  }
+
   CORBA::Object_var IObjectToObject (const Handle(SALOME_InteractiveObject)& theIO)
   {
     if (!theIO.IsNull()) {
       if (theIO->hasEntry()) {
-       _PTR(Study) aStudy = GetActiveStudyDocument();
-       _PTR(SObject) anObj = aStudy->FindObjectID(theIO->getEntry());
-       return SObjectToObject(anObj,aStudy);
+        _PTR(Study) aStudy = GetActiveStudyDocument();
+        _PTR(SObject) anObj = aStudy->FindObjectID(theIO->getEntry());
+        return SObjectToObject(anObj,aStudy);
       }
     }
     return CORBA::Object::_nil();
@@ -230,7 +252,7 @@ namespace SMESH
     int aNbSel = selected.Extent();
     if (aNbSel == 1) {
       Handle(SALOME_InteractiveObject) anIObject = selected.First();
-      theName = anIObject->getName();
+      theName = QString( anIObject->getName() ).trimmed();
     } else {
       theName = QObject::tr("SMESH_OBJECTS_SELECTED").arg(aNbSel);
     }
@@ -261,31 +283,63 @@ namespace SMESH
     _PTR(GenericAttribute) anAttr =
       aBuilder->FindOrCreateAttribute(theSObject,"AttributePixMap");
     _PTR(AttributePixMap) aPixmap = anAttr;
-    if (theIsNotModif) {
-      aPixmap->SetPixMap("ICON_SMESH_TREE_MESH");
-    } else if ( isEmptyMesh ) {
-      aPixmap->SetPixMap("ICON_SMESH_TREE_MESH_WARN");
-    } else {
-      aPixmap->SetPixMap("ICON_SMESH_TREE_MESH_PARTIAL");
-    }
+
+    std::string pmName;
+    if (theIsNotModif)
+      pmName = "ICON_SMESH_TREE_MESH";
+    else if ( isEmptyMesh )
+      pmName = "ICON_SMESH_TREE_MESH_WARN";
+    else
+      pmName = "ICON_SMESH_TREE_MESH_PARTIAL";
+    aPixmap->SetPixMap( pmName );
 
     _PTR(ChildIterator) anIter = aStudy->NewChildIterator(theSObject);
     for (int i = 1; anIter->More(); anIter->Next(), i++) {
       _PTR(SObject) aSObj = anIter->Value();
       if (i >= 4) {
-       _PTR(ChildIterator) anIter1 = aStudy->NewChildIterator(aSObj);
-       for ( ; anIter1->More(); anIter1->Next()) {
-         _PTR(SObject) aSObj1 = anIter1->Value();
-         anAttr = aBuilder->FindOrCreateAttribute(aSObj1, "AttributePixMap");
-         aPixmap = anAttr;
-          if (theIsNotModif) {
-            aPixmap->SetPixMap("ICON_SMESH_TREE_MESH");
-          } else if ( isEmptyMesh ) {
-            aPixmap->SetPixMap("ICON_SMESH_TREE_MESH_WARN");
-          } else {
-            aPixmap->SetPixMap("ICON_SMESH_TREE_MESH_PARTIAL");
+        _PTR(ChildIterator) anIter1 = aStudy->NewChildIterator(aSObj);
+        for ( ; anIter1->More(); anIter1->Next())
+        {
+          _PTR(SObject) aSObj1 = anIter1->Value();
+
+          anAttr = aBuilder->FindOrCreateAttribute(aSObj1, "AttributePixMap");
+          aPixmap = anAttr;
+
+          std::string entry = aSObj1->GetID();
+          int objType = SMESHGUI_Selection::type( entry.c_str(), aStudy );
+
+          SMESH::SMESH_IDSource_var idSrc = SObjectToInterface<SMESH::SMESH_IDSource>( aSObj1 );
+          if ( !idSrc->_is_nil() )
+          {
+            SMESH::SMESH_GroupOnFilter_var gof =
+              SObjectToInterface<SMESH::SMESH_GroupOnFilter>( aSObj1 );
+            const bool isGroupOnFilter = !gof->_is_nil();
+
+            bool isEmpty = false;
+            if ( !isGroupOnFilter ) // GetTypes() can be very long on isGroupOnFilter!
+            {
+              SMESH::array_of_ElementType_var elemTypes = idSrc->GetTypes();
+              isEmpty = ( elemTypes->length() == 0 );
+            }
+            if ( isEmpty )
+              aPixmap->SetPixMap("ICON_SMESH_TREE_MESH_WARN");
+            else if ( objType != GROUP )
+              aPixmap->SetPixMap( "ICON_SMESH_TREE_MESH" );
+            else if ( isGroupOnFilter )
+              aPixmap->SetPixMap( "ICON_SMESH_TREE_GROUP_ON_FILTER" );
+            else
+              aPixmap->SetPixMap( "ICON_SMESH_TREE_GROUP" );
+          }
+          else
+          {
+            if ( !theIsNotModif )
+              aPixmap->SetPixMap( pmName );
+            else if ( objType == GROUP )
+              aPixmap->SetPixMap( "ICON_SMESH_TREE_GROUP" );
+            else
+              aPixmap->SetPixMap( "ICON_SMESH_TREE_MESH" );
           }
-       }
+        }
       }
     }
   }
@@ -300,10 +354,10 @@ namespace SMESH
     }
     else {
       SUIT_MessageBox::warning(0, QObject::tr("WRN_WARNING"),
-                              QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                              arg(app->resourceMgr()->stringValue("ExternalBrowser", 
-                                                                  "application")).
-                              arg(theHelpFileName));
+                               QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                               arg(app->resourceMgr()->stringValue("ExternalBrowser", 
+                                                                   "application")).
+                               arg(theHelpFileName));
     }
   }
 
index 77f26e3e139f2de44aa58bb97e7f07914bb8bd41..c813e10787de2451216fcc9faa6a7d343db46057 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_Utils.h
 // Author : Open CASCADE S.A.S.
@@ -88,7 +89,7 @@ SMESHGUI_EXPORT
     {
       CORBA::Object_var anObj = DataOwnerToObject(theDataOwner);
       if(!CORBA::is_nil(anObj))
-       return TInterface::_narrow(anObj);
+        return TInterface::_narrow(anObj);
       return TInterface::_nil();
     }
 
@@ -114,7 +115,7 @@ SMESHGUI_EXPORT
 
 SMESHGUI_EXPORT
   CORBA::Object_var SObjectToObject( _PTR(SObject),
-                                    _PTR(Study) );
+                                     _PTR(Study) );
 
 SMESHGUI_EXPORT
   CORBA::Object_var SObjectToObject( _PTR(SObject) );
@@ -124,10 +125,13 @@ SMESHGUI_EXPORT
     {
       CORBA::Object_var anObj = SObjectToObject(theSObject);
       if(!CORBA::is_nil(anObj))
-       return TInterface::_narrow(anObj);
+        return TInterface::_narrow(anObj);
       return TInterface::_nil();
     }
 
+SMESHGUI_EXPORT
+  _PTR(SObject) ObjectToSObject( CORBA::Object_ptr );
+
 SMESHGUI_EXPORT
   CORBA::Object_var IObjectToObject( const Handle(SALOME_InteractiveObject)& );
 
@@ -136,7 +140,7 @@ SMESHGUI_EXPORT
     {
       CORBA::Object_var anObj = IObjectToObject(theIO);
       if(!CORBA::is_nil(anObj))
-       return TInterface::_narrow(anObj);
+        return TInterface::_narrow(anObj);
       return TInterface::_nil();
     }
 
@@ -148,7 +152,7 @@ SMESHGUI_EXPORT
     {
       CORBA::Object_var anObj = IORToObject( theIOR );
       if ( !CORBA::is_nil( anObj ) )
-       return TInterface::_narrow( anObj );
+        return TInterface::_narrow( anObj );
       return TInterface::_nil();
     }
 
index 9289f0108e1c0836c13b61637fdb70543f2c5335..baafa985c8de0f04391d5f0606fd94b9437eacae 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_VTKUtils.cxx
 // Author : Open CASCADE S.A.S.
@@ -29,6 +30,7 @@
 #include "SMESHGUI.h"
 #include "SMESHGUI_Utils.h"
 #include "SMESHGUI_Filter.h"
+#include "SMESH_ControlsDef.hxx"
 
 #include <SMESH_Actor.h>
 #include <SMESH_ActorUtils.h>
@@ -49,6 +51,8 @@
 #include <SVTK_ViewModel.h>
 #include <SVTK_ViewWindow.h>
 
+#include <VTKViewer_Algorithm.h>
+
 #include <LightApp_SelectionMgr.h>
 #include <SalomeApp_Application.h>
 #include <SalomeApp_Study.h>
@@ -62,6 +66,7 @@
 #include CORBA_CLIENT_HEADER(SMESH_Group)
 
 // VTK includes
+#include <vtkMath.h>
 #include <vtkRenderer.h>
 #include <vtkActorCollection.h>
 #include <vtkUnstructuredGrid.h>
@@ -98,31 +103,54 @@ namespace SMESH
    */
   //================================================================================
 
-  void RemoveVisualObjectWithActors( const char* theEntry )
+  void RemoveVisualObjectWithActors( const char* theEntry, bool fromAllViews )
   {
-    SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>
-      ( SUIT_Session::session()->activeApplication() );
-    SUIT_ViewManager* aViewManager =
-      app ? app->getViewManager(SVTK_Viewer::Type(), true) : 0;
-    if ( aViewManager ) {
+    SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>(SUIT_Session::session()->activeApplication());
+    if(!app)
+      return;
+    SalomeApp_Study* aStudy  = dynamic_cast<SalomeApp_Study*>(app->activeStudy());
+    if(!aStudy)
+      return;
+    ViewManagerList aList;
+
+    if(fromAllViews) {
+      app->viewManagers(SVTK_Viewer::Type() , aList);
+    } else {
+      SUIT_ViewManager* aVM = app->getViewManager(SVTK_Viewer::Type(), true);
+      if(aVM)
+        aList.append(aVM);
+    }    
+    bool actorRemoved = false;
+    ViewManagerList::ConstIterator it = aList.begin();
+    SUIT_ViewManager* aViewManager = 0;
+    for( ; it!=aList.end();it++) {
+      aViewManager = *it;
       QVector<SUIT_ViewWindow*> views = aViewManager->getViews();
       for ( int iV = 0; iV < views.count(); ++iV ) {
         if ( SMESH_Actor* actor = FindActorByEntry( views[iV], theEntry)) {
-          if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(views[iV]))
+          if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(views[iV])) {
             vtkWnd->RemoveActor(actor);
+            actorRemoved = true;
+          }
           actor->Delete();
         }
       }
+    }
+    
+    if (aViewManager ) {
       int aStudyId = aViewManager->study()->id();
       TVisualObjCont::key_type aKey(aStudyId,theEntry);
       TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.find(aKey);
       if(anIter != VISUAL_OBJ_CONT.end()) {
         // for unknown reason, object destructor is not called, so clear object manually
-        anIter->second->GetUnstructuredGrid()->SetCells(0,0,0);
+        anIter->second->GetUnstructuredGrid()->SetCells(0,0,0,0,0);
         anIter->second->GetUnstructuredGrid()->SetPoints(0);
       }
       VISUAL_OBJ_CONT.erase(aKey);
     }
+
+    if(actorRemoved)
+      aStudy->setVisibilityState(theEntry, Qtx::HiddenState);
   }
   //================================================================================
   /*!
@@ -143,10 +171,11 @@ namespace SMESH
         for ( int iV = 0; iV < views.count(); ++iV ) {
           if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(views[iV])) {
             vtkRenderer *aRenderer = vtkWnd->getRenderer();
-            vtkActorCollection *actors = aRenderer->GetActors();
+            VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
+            vtkActorCollection *actors = aCopy.GetActors();
             for (int i = 0; i < actors->GetNumberOfItems(); ++i ) {
               // size of actors changes inside the loop
-              while (SMESH_Actor *actor = dynamic_cast<SMESH_Actor*>(actors->GetItemAsObject(i)))
+              if (SMESH_Actor *actor = dynamic_cast<SMESH_Actor*>(actors->GetItemAsObject(i)))
               {
                 vtkWnd->RemoveActor(actor);
                 actor->Delete();
@@ -159,7 +188,7 @@ namespace SMESH
     TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.begin();
     for ( ; anIter != VISUAL_OBJ_CONT.end(); ++anIter ) {
       // for unknown reason, object destructor is not called, so clear object manually
-      anIter->second->GetUnstructuredGrid()->SetCells(0,0,0);
+      anIter->second->GetUnstructuredGrid()->SetCells(0,0,0,0,0);
       anIter->second->GetUnstructuredGrid()->SetPoints(0);
     }
     VISUAL_OBJ_CONT.clear();
@@ -185,10 +214,11 @@ namespace SMESH
         for ( int iV = 0; iV < views.count(); ++iV ) {
           if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(views[iV])) {
             vtkRenderer *aRenderer = vtkWnd->getRenderer();
-            vtkActorCollection *actors = aRenderer->GetActors();
+            VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
+            vtkActorCollection *actors = aCopy.GetActors();
             for (int i = 0; i < actors->GetNumberOfItems(); ++i ) {
               // size of actors changes inside the loop
-              while(SMESH_Actor *actor = dynamic_cast<SMESH_Actor*>(actors->GetItemAsObject(i)))
+              if(SMESH_Actor *actor = dynamic_cast<SMESH_Actor*>(actors->GetItemAsObject(i)))
               {
                 vtkWnd->RemoveActor(actor);
                 actor->Delete();
@@ -199,13 +229,16 @@ namespace SMESH
       }
     }
     TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.begin();
-    for ( ; anIter != VISUAL_OBJ_CONT.end(); ++anIter ) {
+    for ( ; anIter != VISUAL_OBJ_CONT.end(); ) {
       int curId = anIter->first.first;
       if ( curId == studyID ) {
         // for unknown reason, object destructor is not called, so clear object manually
-        anIter->second->GetUnstructuredGrid()->SetCells(0,0,0);
+        anIter->second->GetUnstructuredGrid()->SetCells(0,0,0,0,0);
         anIter->second->GetUnstructuredGrid()->SetPoints(0);
-        VISUAL_OBJ_CONT.erase( anIter-- );  // dercement occures before erase()
+        VISUAL_OBJ_CONT.erase( anIter++ ); // anIter++ returns a copy of self before incrementing
+      }
+      else {
+        anIter++;
       }
     }
   }
@@ -227,18 +260,18 @@ namespace SMESH
 //       char* buf = new char[100*1024];
 //       delete [] buf;
       SUIT_MessageBox::warning(SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"),
-                              QObject::tr("SMESH_VISU_PROBLEM"));
+                               QObject::tr("SMESH_VISU_PROBLEM"));
     } catch (...) {
       // no more memory at all: last resort
       MESSAGE_BEGIN ( "SMESHGUI_VTKUtils::OnVisuException(), exception even at showing a message!!!" <<
-                     std::endl << "Try to remove all visual data..." );
+                      std::endl << "Try to remove all visual data..." );
       if (theVISU_MemoryReserve) {
         delete theVISU_MemoryReserve;
         theVISU_MemoryReserve = 0;
       }
       RemoveAllObjectsWithActors();
       SUIT_MessageBox::warning(SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"),
-                              QObject::tr("SMESH_VISU_PROBLEM_CLEAR"));
+                               QObject::tr("SMESH_VISU_PROBLEM_CLEAR"));
       MESSAGE_END ( "...done" );
     }
   }
@@ -248,7 +281,7 @@ namespace SMESH
    */
   //================================================================================
 
-  TVisualObjPtr GetVisualObj(int theStudyId, const char* theEntry){
+  TVisualObjPtr GetVisualObj(int theStudyId, const char* theEntry, bool nulData){
     TVisualObjPtr aVisualObj;
     TVisualObjCont::key_type aKey(theStudyId,theEntry);
     try{
@@ -257,59 +290,59 @@ namespace SMESH
 #endif
       TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.find(aKey);
       if(anIter != VISUAL_OBJ_CONT.end()){
-       aVisualObj = anIter->second;
+        aVisualObj = anIter->second;
       }else{
         SalomeApp_Application* app =
           dynamic_cast<SalomeApp_Application*>( SMESHGUI::activeStudy()->application() );
-       _PTR(Study) aStudy = SMESHGUI::activeStudy()->studyDS();
-       _PTR(SObject) aSObj = aStudy->FindObjectID(theEntry);
-       if(aSObj){
-         _PTR(GenericAttribute) anAttr;
-         if(aSObj->FindAttribute(anAttr,"AttributeIOR")){
-           _PTR(AttributeIOR) anIOR = anAttr;
-           CORBA::String_var aVal = anIOR->Value().c_str();
-           CORBA::Object_var anObj = app->orb()->string_to_object( aVal.in() );
-           if(!CORBA::is_nil(anObj)){
-             //Try narrow to SMESH_Mesh interface
-             SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(anObj);
-             if(!aMesh->_is_nil()){
-               aVisualObj.reset(new SMESH_MeshObj(aMesh));
-               TVisualObjCont::value_type aValue(aKey,aVisualObj);
-               VISUAL_OBJ_CONT.insert(aValue);
-             }
-             //Try narrow to SMESH_Group interface
-             SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(anObj);
-             if(!aGroup->_is_nil()){
-               _PTR(SObject) aFatherSObj = aSObj->GetFather();
-               if(!aFatherSObj) return aVisualObj;
-               aFatherSObj = aFatherSObj->GetFather();
-               if(!aFatherSObj) return aVisualObj;
-               CORBA::String_var anEntry = aFatherSObj->GetID().c_str();
-               TVisualObjPtr aVisObj = GetVisualObj(theStudyId,anEntry.in());
-               if(SMESH_MeshObj* aMeshObj = dynamic_cast<SMESH_MeshObj*>(aVisObj.get())){
-                 aVisualObj.reset(new SMESH_GroupObj(aGroup,aMeshObj));
-                 TVisualObjCont::value_type aValue(aKey,aVisualObj);
-                 VISUAL_OBJ_CONT.insert(aValue);
-               }
-             }
-             //Try narrow to SMESH_subMesh interface
-             SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow(anObj);
-             if(!aSubMesh->_is_nil()){
-               _PTR(SObject) aFatherSObj = aSObj->GetFather();
-               if(!aFatherSObj) return aVisualObj;
-               aFatherSObj = aFatherSObj->GetFather();
-               if(!aFatherSObj) return aVisualObj;
-               CORBA::String_var anEntry = aFatherSObj->GetID().c_str();
-               TVisualObjPtr aVisObj = GetVisualObj(theStudyId,anEntry.in());
-               if(SMESH_MeshObj* aMeshObj = dynamic_cast<SMESH_MeshObj*>(aVisObj.get())){
-                 aVisualObj.reset(new SMESH_subMeshObj(aSubMesh,aMeshObj));
-                 TVisualObjCont::value_type aValue(aKey,aVisualObj);
-                 VISUAL_OBJ_CONT.insert(aValue);
-               }
-             }
-           }
-         }
-       }
+        _PTR(Study) aStudy = SMESHGUI::activeStudy()->studyDS();
+        _PTR(SObject) aSObj = aStudy->FindObjectID(theEntry);
+        if(aSObj){
+          _PTR(GenericAttribute) anAttr;
+          if(aSObj->FindAttribute(anAttr,"AttributeIOR")){
+            _PTR(AttributeIOR) anIOR = anAttr;
+            CORBA::String_var aVal = anIOR->Value().c_str();
+            CORBA::Object_var anObj = app->orb()->string_to_object( aVal.in() );
+            if(!CORBA::is_nil(anObj)){
+              //Try narrow to SMESH_Mesh interface
+              SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(anObj);
+              if(!aMesh->_is_nil()){
+                aVisualObj.reset(new SMESH_MeshObj(aMesh));
+                TVisualObjCont::value_type aValue(aKey,aVisualObj);
+                VISUAL_OBJ_CONT.insert(aValue);
+              }
+              //Try narrow to SMESH_Group interface
+              SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(anObj);
+              if(!aGroup->_is_nil()){
+                _PTR(SObject) aFatherSObj = aSObj->GetFather();
+                if(!aFatherSObj) return aVisualObj;
+                aFatherSObj = aFatherSObj->GetFather();
+                if(!aFatherSObj) return aVisualObj;
+                CORBA::String_var anEntry = aFatherSObj->GetID().c_str();
+                TVisualObjPtr aVisObj = GetVisualObj(theStudyId,anEntry.in());
+                if(SMESH_MeshObj* aMeshObj = dynamic_cast<SMESH_MeshObj*>(aVisObj.get())){
+                  aVisualObj.reset(new SMESH_GroupObj(aGroup,aMeshObj));
+                  TVisualObjCont::value_type aValue(aKey,aVisualObj);
+                  VISUAL_OBJ_CONT.insert(aValue);
+                }
+              }
+              //Try narrow to SMESH_subMesh interface
+              SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow(anObj);
+              if(!aSubMesh->_is_nil()){
+                _PTR(SObject) aFatherSObj = aSObj->GetFather();
+                if(!aFatherSObj) return aVisualObj;
+                aFatherSObj = aFatherSObj->GetFather();
+                if(!aFatherSObj) return aVisualObj;
+                CORBA::String_var anEntry = aFatherSObj->GetID().c_str();
+                TVisualObjPtr aVisObj = GetVisualObj(theStudyId,anEntry.in());
+                if(SMESH_MeshObj* aMeshObj = dynamic_cast<SMESH_MeshObj*>(aVisObj.get())){
+                  aVisualObj.reset(new SMESH_subMeshObj(aSubMesh,aMeshObj));
+                  TVisualObjCont::value_type aValue(aKey,aVisualObj);
+                  VISUAL_OBJ_CONT.insert(aValue);
+                }
+              }
+            }
+          }
+        }
       }
     }catch(...){
       INFOS("GetMeshObj - There is no SMESH_Mesh object for the SALOMEDS::Strudy and Entry!!!");
@@ -322,7 +355,11 @@ namespace SMESH
 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
         OCC_CATCH_SIGNALS;
 #endif
-        objModified = aVisualObj->Update();
+        //MESSAGE("GetVisualObj");
+        if (nulData)
+                objModified = aVisualObj->NulData();
+        else
+          objModified = aVisualObj->Update();
       }
       catch (...) {
 #ifdef _DEBUG_
@@ -336,34 +373,31 @@ namespace SMESH
 
     if ( objModified ) {
       // PAL16631. Mesurements showed that to show aVisualObj in SHADING(default) mode,
-      // ~10 times more memory is used than it occupies.
+      // ~5 times more memory is used than it occupies.
       // Warn the user if there is less free memory than 30 sizes of a grid
       // TODO: estimate memory usage in other modes and take current mode into account
       int freeMB = SMDS_Mesh::CheckMemory(true);
       int usedMB = aVisualObj->GetUnstructuredGrid()->GetActualMemorySize() / 1024;
-      if ( freeMB > 0 && usedMB * 30 > freeMB ) {
-#ifdef _DEBUG_
-        MESSAGE ( "SMESHGUI_VTKUtils::GetVisualObj(), freeMB=" << freeMB
-               << ", usedMB=" << usedMB );
-#endif
-        bool continu = false;
-        if ( usedMB * 10 > freeMB )
-          // even dont try to show
-          SUIT_MessageBox::warning(SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"),
-                                  QObject::tr("SMESH_NO_MESH_VISUALIZATION"));
-        else
-          // there is a chance to succeed
-          continu = SUIT_MessageBox::warning
-            (SMESHGUI::desktop(),
-             QObject::tr("SMESH_WRN_WARNING"),
-             QObject::tr("SMESH_CONTINUE_MESH_VISUALIZATION"),
-             SUIT_MessageBox::Yes | SUIT_MessageBox::No, 
-            SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes;
-        if ( !continu ) {
-          // remove the corresponding actors from all views
-          RemoveVisualObjectWithActors( theEntry );
-          aVisualObj.reset();
-        }
+      MESSAGE("SMESHGUI_VTKUtils::GetVisualObj(), freeMB=" << freeMB << ", usedMB=" <<usedMB);
+      if ( freeMB > 0 && usedMB * 5 > freeMB ) {
+       bool continu = false;
+       if ( usedMB * 3 > freeMB )
+         // even dont try to show
+         SUIT_MessageBox::warning(SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"),
+                                  QObject::tr("SMESH_NO_MESH_VISUALIZATION"));
+       else
+         // there is a chance to succeed
+         continu = SUIT_MessageBox::warning
+           (SMESHGUI::desktop(),
+            QObject::tr("SMESH_WRN_WARNING"),
+            QObject::tr("SMESH_CONTINUE_MESH_VISUALIZATION"),
+            SUIT_MessageBox::Yes | SUIT_MessageBox::No,
+            SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes;
+       if ( !continu ) {
+         // remove the corresponding actors from all views
+         RemoveVisualObjectWithActors( theEntry );
+         aVisualObj.reset();
+       }
       }
     }
 
@@ -387,7 +421,7 @@ namespace SMESH
 
     if (anApp) {
       if (SVTK_ViewWindow* aView = dynamic_cast<SVTK_ViewWindow*>(anApp->desktop()->activeWindow()))
-       return aView;
+        return aView;
 
       SUIT_ViewManager* aViewManager =
         anApp->getViewManager(SVTK_Viewer::Type(), createIfNotFound);
@@ -512,21 +546,22 @@ namespace SMESH
 
 
   SMESH_Actor* FindActorByEntry(SUIT_ViewWindow *theWindow,
-                               const char* theEntry)
+                                const char* theEntry)
   {
     if(SVTK_ViewWindow* aViewWindow = GetVtkViewWindow(theWindow)){
       vtkRenderer *aRenderer = aViewWindow->getRenderer();
-      vtkActorCollection *aCollection = aRenderer->GetActors();
+      VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
+      vtkActorCollection *aCollection = aCopy.GetActors();
       aCollection->InitTraversal();
       while(vtkActor *anAct = aCollection->GetNextActor()){
-       if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
-         if(anActor->hasIO()){
-           Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
-           if(anIO->hasEntry() && strcmp(anIO->getEntry(),theEntry) == 0){
-             return anActor;
-           }
-         }
-       }
+        if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
+          if(anActor->hasIO()){
+            Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
+            if(anIO->hasEntry() && strcmp(anIO->getEntry(),theEntry) == 0){
+              return anActor;
+            }
+          }
+        }
       }
     }
     return NULL;
@@ -548,8 +583,8 @@ namespace SMESH
       CORBA::String_var anIOR = app->orb()->object_to_string( theObject );
       _PTR(SObject) aSObject = aStudy->FindObjectIOR(anIOR.in());
       if(aSObject){
-       CORBA::String_var anEntry = aSObject->GetID().c_str();
-       return FindActorByEntry(anEntry.in());
+        CORBA::String_var anEntry = aSObject->GetID().c_str();
+        return FindActorByEntry(anEntry.in());
       }
     }
     return NULL;
@@ -557,43 +592,51 @@ namespace SMESH
 
 
   SMESH_Actor* CreateActor(_PTR(Study) theStudy,
-                          const char* theEntry,
-                          int theIsClear)
+                           const char* theEntry,
+                           int theIsClear)
   {
     SMESH_Actor *anActor = NULL;
     CORBA::Long anId = theStudy->StudyId();
     if(TVisualObjPtr aVisualObj = GetVisualObj(anId,theEntry)){
       _PTR(SObject) aSObj = theStudy->FindObjectID(theEntry);
       if(aSObj){
-       _PTR(GenericAttribute) anAttr;
-       if(aSObj->FindAttribute(anAttr,"AttributeName")){
-         _PTR(AttributeName) aName = anAttr;
-         std::string aNameVal = aName->Value();
-         anActor = SMESH_Actor::New(aVisualObj,theEntry,aNameVal.c_str(),theIsClear);
-       }
-
-       SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( SMESH::SObjectToObject( aSObj ));
-       if(!CORBA::is_nil(aGroup))
-       {
-         SALOMEDS::Color aColor = aGroup->GetColor();
-         if( !( aColor.R > 0 || aColor.G > 0 || aColor.B > 0 ) )
-         {
-           int r = 0, g = 0, b = 0;
-           SMESH::GetColor( "SMESH", "fill_color", r, g, b, QColor( 0, 170, 255 ) );
-           aColor.R = (float)r / 255.0;
-           aColor.G = (float)g / 255.0;
-           aColor.B = (float)b / 255.0;
-           aGroup->SetColor( aColor );
-         }
-         if( aGroup->GetType() == SMESH::NODE )
-           anActor->SetNodeColor( aColor.R, aColor.G, aColor.B );
-         else if( aGroup->GetType() == SMESH::EDGE )
-           anActor->SetEdgeColor( aColor.R, aColor.G, aColor.B );
-         else
-           anActor->SetSufaceColor( aColor.R, aColor.G, aColor.B );
-       }
+        _PTR(GenericAttribute) anAttr;
+        if(aSObj->FindAttribute(anAttr,"AttributeName")){
+          _PTR(AttributeName) aName = anAttr;
+          std::string aNameVal = aName->Value();
+          anActor = SMESH_Actor::New(aVisualObj,theEntry,aNameVal.c_str(),theIsClear);
+        }
+
+        SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( SMESH::SObjectToObject( aSObj ));
+        if(!CORBA::is_nil(aGroup) && anActor)
+        {
+         QColor c;int delta;
+         SMESH::GetColor( "SMESH", "fill_color", c, delta, "0,170,255|-100"  );
+          SALOMEDS::Color aColor = aGroup->GetColor();
+          if( !( aColor.R > 0 || aColor.G > 0 || aColor.B > 0 ))
+          {
+           aColor.R = (float)c.red() / 255.0;
+           aColor.G = (float)c.green() / 255.0;
+            aColor.B = (float)c.blue() / 255.0;
+            aGroup->SetColor( aColor );
+          }
+          if( aGroup->GetType() == SMESH::NODE )
+            anActor->SetNodeColor( aColor.R, aColor.G, aColor.B );
+          else if( aGroup->GetType() == SMESH::EDGE )
+            anActor->SetEdgeColor( aColor.R, aColor.G, aColor.B );
+          else if( aGroup->GetType() == SMESH::ELEM0D )
+            anActor->Set0DColor( aColor.R, aColor.G, aColor.B );
+          else if( aGroup->GetType() == SMESH::BALL )
+            anActor->SetBallColor( aColor.R, aColor.G, aColor.B );
+          else
+            anActor->SetSufaceColor( aColor.R, aColor.G, aColor.B, delta );
+        }
       }
     }
+    MESSAGE("CreateActor " << anActor);
+    if( anActor )
+      if( SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI() )
+        aSMESHGUI->addActorAsObserver( anActor );
     return anActor;
   }
 
@@ -604,6 +647,7 @@ namespace SMESH
 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
         OCC_CATCH_SIGNALS;
 #endif
+        MESSAGE("DisplayActor " << theActor);
         vtkWnd->AddActor(theActor);
         vtkWnd->Repaint();
       }
@@ -619,16 +663,17 @@ namespace SMESH
 
   void RemoveActor( SUIT_ViewWindow *theWnd, SMESH_Actor* theActor){
     if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd)){
+        MESSAGE("RemoveActor " << theActor);
       vtkWnd->RemoveActor(theActor);
       if(theActor->hasIO()){
-       Handle(SALOME_InteractiveObject) anIO = theActor->getIO();
-       if(anIO->hasEntry()){
-         std::string anEntry = anIO->getEntry();
-         SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( vtkWnd->getViewManager()->study() );
-         int aStudyId = aStudy->id();
-         TVisualObjCont::key_type aKey(aStudyId,anEntry);
-         VISUAL_OBJ_CONT.erase(aKey);
-       }
+        Handle(SALOME_InteractiveObject) anIO = theActor->getIO();
+        if(anIO->hasEntry()){
+          std::string anEntry = anIO->getEntry();
+          SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( vtkWnd->getViewManager()->study() );
+          int aStudyId = aStudy->id();
+          TVisualObjCont::key_type aKey(aStudyId,anEntry);
+          VISUAL_OBJ_CONT.erase(aKey);
+        }
       }
       theActor->Delete();
       vtkWnd->Repaint();
@@ -645,10 +690,11 @@ namespace SMESH
   {
     if(SVTK_ViewWindow* aViewWindow = GetVtkViewWindow(theWnd)) {
       vtkRenderer *aRenderer = aViewWindow->getRenderer();
-      vtkActorCollection *aCollection = aRenderer->GetActors();
+      VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
+      vtkActorCollection *aCollection = aCopy.GetActors();
       aCollection->InitTraversal();
       while(vtkActor *anAct = aCollection->GetNextActor())
-       if(dynamic_cast<SMESH_Actor*>(anAct))
+        if(dynamic_cast<SMESH_Actor*>(anAct))
           return false;
     }
     return true;
@@ -656,60 +702,90 @@ namespace SMESH
 
   bool UpdateView(SUIT_ViewWindow *theWnd, EDisplaing theAction, const char* theEntry)
   {
+        //MESSAGE("UpdateView");
     bool OK = false;
     SVTK_ViewWindow* aViewWnd = GetVtkViewWindow(theWnd);
     if (!aViewWnd)
       return OK;
 
+    SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd);
+    if (!vtkWnd)
+      return OK;
+
+    SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( vtkWnd->getViewManager()->study() );
+    
+    if (!aStudy)
+      return OK;
+
     {
       OK = true;
       vtkRenderer *aRenderer = aViewWnd->getRenderer();
-      vtkActorCollection *aCollection = aRenderer->GetActors();
+      VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
+      vtkActorCollection *aCollection = aCopy.GetActors();
       aCollection->InitTraversal();
 
       switch (theAction) {
       case eDisplayAll: {
-       while (vtkActor *anAct = aCollection->GetNextActor()) {
-         if (SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)) {
-           anActor->SetVisibility(true);
-         }
-       }
-       break;
+        while (vtkActor *anAct = aCollection->GetNextActor()) {
+          if (SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)) {
+                MESSAGE("--- display " << anActor);
+            anActor->SetVisibility(true);
+
+            if(anActor->hasIO()){
+              Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
+              if(anIO->hasEntry()){
+                aStudy->setVisibilityState(anIO->getEntry(), Qtx::ShownState);
+              }
+            }
+          }
+        }
+        break;
       }
       case eDisplayOnly:
       case eEraseAll: {
-       while (vtkActor *anAct = aCollection->GetNextActor()) {
-         if (SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)) {
-           anActor->SetVisibility(false);
-         }
-       }
+        //MESSAGE("---case eDisplayOnly");
+        while (vtkActor *anAct = aCollection->GetNextActor()) {
+          if (SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)) {
+                //MESSAGE("--- erase " << anActor);
+            anActor->SetVisibility(false);
+          }
+        }
+        aStudy->setVisibilityStateForAll(Qtx::HiddenState);
       }
       default: {
-       if (SMESH_Actor *anActor = FindActorByEntry(theWnd,theEntry)) {
-         switch (theAction) {
-           case eDisplay:
-           case eDisplayOnly:
-             anActor->SetVisibility(true);
-             if (theAction == eDisplayOnly) aRenderer->ResetCameraClippingRange();
-             break;
-           case eErase:
-             anActor->SetVisibility(false);
-             break;
-         }
-       } else {
-         switch (theAction) {
-         case eDisplay:
-         case eDisplayOnly:
+        if (SMESH_Actor *anActor = FindActorByEntry(theWnd,theEntry)) {
+          switch (theAction) {
+            case eDisplay:
+            case eDisplayOnly:
+                //MESSAGE("--- display " << anActor);
+              anActor->Update();
+              anActor->SetVisibility(true);
+              if (theAction == eDisplayOnly) aRenderer->ResetCameraClippingRange();
+              aStudy->setVisibilityState(theEntry, Qtx::ShownState);
+              break;
+            case eErase:
+                //MESSAGE("--- erase " << anActor);
+              anActor->SetVisibility(false);
+              aStudy->setVisibilityState(theEntry, Qtx::HiddenState);
+              break;
+          }
+        } else {
+          switch (theAction) {
+          case eDisplay:
+          case eDisplayOnly:
             {
+                //MESSAGE("---");
               SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(theWnd->getViewManager()->study());
               _PTR(Study) aDocument = aStudy->studyDS();
               // Pass non-visual objects (hypotheses, etc.), return true in this case
               CORBA::Long anId = aDocument->StudyId();
-              if (TVisualObjPtr aVisualObj = GetVisualObj(anId,theEntry))
+              TVisualObjPtr aVisualObj;
+              if ( (aVisualObj = GetVisualObj(anId,theEntry)) && aVisualObj->IsValid())
               {
                 if ((anActor = CreateActor(aDocument,theEntry,true))) {
                   bool needFitAll = noSmeshActors(theWnd); // fit for the first object only
                   DisplayActor(theWnd,anActor);
+                  aStudy->setVisibilityState(theEntry, Qtx::ShownState);
                   // FitAll(); - PAL16770(Display of a group performs an automatic fit all)
                   if (needFitAll) FitAll();
                 } else {
@@ -718,8 +794,8 @@ namespace SMESH
               }
               break;
             }
-         }
-       }
+          }
+        }
       }
       }
     }
@@ -728,6 +804,7 @@ namespace SMESH
 
 
   bool UpdateView(EDisplaing theAction, const char* theEntry){
+        //MESSAGE("UpdateView");
     SalomeApp_Study* aStudy = dynamic_cast< SalomeApp_Study* >( GetActiveStudy() );
     SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( aStudy->application() );
     SUIT_ViewWindow *aWnd = app->activeViewManager()->getActiveView();
@@ -740,23 +817,24 @@ namespace SMESH
       SALOME_ListIO selected; mgr->selectedObjects( selected );
 
       if( selected.Extent() == 0){
-       vtkRenderer* aRenderer = aWnd->getRenderer();
-       vtkActorCollection *aCollection = aRenderer->GetActors();
-       aCollection->InitTraversal();
-       while(vtkActor *anAct = aCollection->GetNextActor()){
-         if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
-           if(anActor->hasIO())
-             if (!Update(anActor->getIO(),anActor->GetVisibility()))
+        vtkRenderer* aRenderer = aWnd->getRenderer();
+        VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
+        vtkActorCollection *aCollection = aCopy.GetActors();
+        aCollection->InitTraversal();
+        while(vtkActor *anAct = aCollection->GetNextActor()){
+          if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
+            if(anActor->hasIO())
+              if (!Update(anActor->getIO(),anActor->GetVisibility()))
                 break; // avoid multiple warinings if visu failed
-         }
-       }
+          }
+        }
       }else{
-       SALOME_ListIteratorOfListIO anIter( selected );
-       for( ; anIter.More(); anIter.Next()){
-         Handle(SALOME_InteractiveObject) anIO = anIter.Value();
-         if ( !Update(anIO,true) )
+        SALOME_ListIteratorOfListIO anIter( selected );
+        for( ; anIter.More(); anIter.Next()){
+          Handle(SALOME_InteractiveObject) anIO = anIter.Value();
+          if ( !Update(anIO,true) )
             break; // avoid multiple warinings if visu failed
-       }
+        }
       }
       RepaintCurrentView();
     }
@@ -765,6 +843,7 @@ namespace SMESH
 
   bool Update(const Handle(SALOME_InteractiveObject)& theIO, bool theDisplay)
   {
+        MESSAGE("Update");
     _PTR(Study) aStudy = GetActiveStudyDocument();
     CORBA::Long anId = aStudy->StudyId();
     if ( TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId,theIO->getEntry())) {
@@ -775,6 +854,18 @@ namespace SMESH
     return false;
   }
 
+  bool UpdateNulData(const Handle(SALOME_InteractiveObject)& theIO, bool theDisplay)
+  {
+        MESSAGE("UpdateNulData");
+    _PTR(Study) aStudy = GetActiveStudyDocument();
+    CORBA::Long anId = aStudy->StudyId();
+    if ( TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId,theIO->getEntry(), true)) {
+      if ( theDisplay )
+        UpdateView(SMESH::eDisplay,theIO->getEntry());
+      return true;
+    }
+    return false;
+  }
 
   void UpdateSelectionProp( SMESHGUI* theModule ) {
     if( !theModule )
@@ -805,45 +896,49 @@ namespace SMESH
 
     QColor aHiColor = mgr->colorValue( "SMESH", "selection_object_color", Qt::white ),
            aSelColor = mgr->colorValue( "SMESH", "selection_element_color", Qt::yellow ),
-          aPreColor = mgr->colorValue( "SMESH", "highlight_color", Qt::cyan );
+           aPreColor = mgr->colorValue( "SMESH", "highlight_color", Qt::cyan );
 
-    int SW = mgr->integerValue( "SMESH", "selection_width", 5 ),
-        PW = mgr->integerValue( "SMESH", "highlight_width", 5 );
+    int aElem0DSize = mgr->integerValue("SMESH", "elem0d_size", 5);
+    int aBallSize   = mgr->integerValue("SMESH", "ball_elem_size", 5);
+    int aLineWidth  = mgr->integerValue("SMESH", "element_width", 1);
+    int maxSize = aElem0DSize;
+    if (aElem0DSize > maxSize) maxSize = aElem0DSize;
+    if (aLineWidth > maxSize) maxSize = aLineWidth;
+    if (aBallSize > maxSize) maxSize = aBallSize;
 
     double SP1 = mgr->doubleValue( "SMESH", "selection_precision_node", 0.025 ),
            SP2 = mgr->doubleValue( "SMESH", "selection_precision_element", 0.001 ),
-          SP3 = mgr->doubleValue( "SMESH", "selection_precision_object", 0.025 );
+           SP3 = mgr->doubleValue( "SMESH", "selection_precision_object", 0.025 );
 
     for ( int i=0, n=views.count(); i<n; i++ ){
       // update VTK viewer properties
       if(SVTK_ViewWindow* aVtkView = GetVtkViewWindow( views[i] )){
-       // mesh element selection
-       aVtkView->SetSelectionProp(aSelColor.red()/255.,
-                                  aSelColor.green()/255.,
-                                  aSelColor.blue()/255.,
-                                  SW );
-       // tolerances
-       aVtkView->SetSelectionTolerance(SP1, SP2, SP3);
-
-       // pre-selection
-       aVtkView->SetPreselectionProp(aPreColor.red()/255.,
-                                     aPreColor.green()/255.,
-                                     aPreColor.blue()/255.,
-                                     PW);
-       // update actors
-       vtkRenderer* aRenderer = aVtkView->getRenderer();
-       vtkActorCollection *aCollection = aRenderer->GetActors();
-       aCollection->InitTraversal();
-       while(vtkActor *anAct = aCollection->GetNextActor()){
-         if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
-           anActor->SetHighlightColor(aHiColor.red()/255.,
-                                      aHiColor.green()/255.,
-                                      aHiColor.blue()/255.);
-           anActor->SetPreHighlightColor(aPreColor.red()/255.,
-                                         aPreColor.green()/255.,
-                                         aPreColor.blue()/255.);
-         }
-       }
+        // mesh element selection
+        aVtkView->SetSelectionProp(aSelColor.red()/255.,
+                                   aSelColor.green()/255.,
+                                   aSelColor.blue()/255.);
+        // tolerances
+        aVtkView->SetSelectionTolerance(SP1, SP2, SP3);
+
+        // pre-selection
+        aVtkView->SetPreselectionProp(aPreColor.red()/255.,
+                                      aPreColor.green()/255.,
+                                      aPreColor.blue()/255.);
+        // update actors
+        vtkRenderer* aRenderer = aVtkView->getRenderer();
+        VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
+        vtkActorCollection *aCollection = aCopy.GetActors();
+        aCollection->InitTraversal();
+        while(vtkActor *anAct = aCollection->GetNextActor()){
+          if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
+            anActor->SetHighlightColor(aHiColor.red()/255.,
+                                       aHiColor.green()/255.,
+                                       aHiColor.blue()/255.);
+            anActor->SetPreHighlightColor(aPreColor.red()/255.,
+                                          aPreColor.green()/255.,
+                                          aPreColor.blue()/255.);
+          }
+        }
       }
     }
   }
@@ -860,7 +955,7 @@ namespace SMESH
   }
 
   void SetFilter(const Handle(VTKViewer_Filter)& theFilter,
-                SVTK_Selector* theSelector)
+                 SVTK_Selector* theSelector)
   {
     if (theSelector)
       theSelector->SetFilter(theFilter);
@@ -888,7 +983,7 @@ namespace SMESH
   }
 
   bool IsValid(SALOME_Actor* theActor, int theCellId,
-              SVTK_Selector* theSelector)
+               SVTK_Selector* theSelector)
   {
     return theSelector->IsValid(theActor,theCellId);
   }
@@ -898,14 +993,15 @@ namespace SMESH
   void SetPointRepresentation(bool theIsVisible){
     if(SVTK_ViewWindow* aViewWindow = GetCurrentVtkView()){
       vtkRenderer *aRenderer = aViewWindow->getRenderer();
-      vtkActorCollection *aCollection = aRenderer->GetActors();
+      VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
+      vtkActorCollection *aCollection = aCopy.GetActors();
       aCollection->InitTraversal();
       while(vtkActor *anAct = aCollection->GetNextActor()){
-       if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
-         if(anActor->GetVisibility()){
-           anActor->SetPointRepresentation(theIsVisible);
-         }
-       }
+        if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
+          if(anActor->GetVisibility()){
+            anActor->SetPointRepresentation(theIsVisible);
+          }
+        }
       }
       RepaintCurrentView();
     }
@@ -916,17 +1012,18 @@ namespace SMESH
     if(SVTK_ViewWindow* aWnd = GetCurrentVtkView()){
       int anIsAllPickable = (theActor == NULL);
       vtkRenderer *aRenderer = aWnd->getRenderer();
-      vtkActorCollection *aCollection = aRenderer->GetActors();
+      VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
+      vtkActorCollection *aCollection = aCopy.GetActors();
       aCollection->InitTraversal();
       while(vtkActor *anAct = aCollection->GetNextActor()){
-       if(SALOME_Actor *anActor = dynamic_cast<SALOME_Actor*>(anAct)){
-         if(anActor->GetVisibility()){
-           anActor->SetPickable(anIsAllPickable);
-         }
-       }
+        if(SALOME_Actor *anActor = dynamic_cast<SALOME_Actor*>(anAct)){
+          if(anActor->GetVisibility()){
+            anActor->SetPickable(anIsAllPickable);
+          }
+        }
       }
       if(theActor)
-       theActor->SetPickable(!anIsAllPickable);
+        theActor->SetPickable(!anIsAllPickable);
       RepaintCurrentView();
     }
   }
@@ -934,8 +1031,8 @@ namespace SMESH
 
   //----------------------------------------------------------------------------
   int GetNameOfSelectedNodes(SVTK_Selector* theSelector,
-                            const Handle(SALOME_InteractiveObject)& theIO,
-                            QString& theName)
+                             const Handle(SALOME_InteractiveObject)& theIO,
+                             QString& theName)
   {
     theName = "";
     TColStd_IndexedMapOfInteger aMapIndex;
@@ -948,8 +1045,8 @@ namespace SMESH
   }
 
   int GetNameOfSelectedElements(SVTK_Selector* theSelector,
-                               const Handle(SALOME_InteractiveObject)& theIO,
-                               QString& theName)
+                                const Handle(SALOME_InteractiveObject)& theIO,
+                                QString& theName)
   {
     theName = "";
     TColStd_IndexedMapOfInteger aMapIndex;
@@ -969,9 +1066,9 @@ namespace SMESH
 
 
   int GetEdgeNodes(SVTK_Selector* theSelector,
-                  const TVisualObjPtr& theVisualObject,
-                  int& theId1,
-                  int& theId2)
+                   const TVisualObjPtr& theVisualObject,
+                   int& theId1,
+                   int& theId2)
   {
     const SALOME_ListIO& selected = theSelector->StoredIObjects();
 
@@ -991,9 +1088,9 @@ namespace SMESH
     for ( int i = 1; i <= aMapIndex.Extent(); i++ ) {
       int aVal = aMapIndex( i );
       if ( aVal > 0 )
-       anObjId = aVal;
+        anObjId = aVal;
       else
-       anEdgeNum = abs( aVal ) - 1;
+        anEdgeNum = abs( aVal ) - 1;
     }
 
     if ( anObjId == -1 || anEdgeNum == -1 )
@@ -1004,18 +1101,18 @@ namespace SMESH
 
   //----------------------------------------------------------------------------
   int GetNameOfSelectedNodes(LightApp_SelectionMgr *theMgr,
-                            const Handle(SALOME_InteractiveObject)& theIO,
-                            QString& theName)
+                             const Handle(SALOME_InteractiveObject)& theIO,
+                             QString& theName)
   {
     theName = "";
     if(theIO->hasEntry()){
       if(FindActorByEntry(theIO->getEntry())){
-       TColStd_IndexedMapOfInteger aMapIndex;
-       theMgr->GetIndexes(theIO,aMapIndex);
-       for(int i = 1; i <= aMapIndex.Extent(); i++){
-         theName += QString(" %1").arg(aMapIndex(i));
-       }
-       return aMapIndex.Extent();
+        TColStd_IndexedMapOfInteger aMapIndex;
+        theMgr->GetIndexes(theIO,aMapIndex);
+        for(int i = 1; i <= aMapIndex.Extent(); i++){
+          theName += QString(" %1").arg(aMapIndex(i));
+        }
+        return aMapIndex.Extent();
       }
     }
     return -1;
@@ -1033,23 +1130,23 @@ namespace SMESH
 
 
   int GetNameOfSelectedElements(LightApp_SelectionMgr *theMgr,
-                               const Handle(SALOME_InteractiveObject)& theIO,
-                               QString& theName)
+                                const Handle(SALOME_InteractiveObject)& theIO,
+                                QString& theName)
   {
     theName = "";
     if(theIO->hasEntry()){
       if(FindActorByEntry(theIO->getEntry())){
-       TColStd_IndexedMapOfInteger aMapIndex;
-       theMgr->GetIndexes(theIO,aMapIndex);
-       typedef std::set<int> TIdContainer;
-       TIdContainer anIdContainer;
-       for( int i = 1; i <= aMapIndex.Extent(); i++)
-         anIdContainer.insert(aMapIndex(i));
-       TIdContainer::const_iterator anIter = anIdContainer.begin();
-       for( ; anIter != anIdContainer.end(); anIter++){
-         theName += QString(" %1").arg(*anIter);
-       }
-       return aMapIndex.Extent();
+        TColStd_IndexedMapOfInteger aMapIndex;
+        theMgr->GetIndexes(theIO,aMapIndex);
+        typedef std::set<int> TIdContainer;
+        TIdContainer anIdContainer;
+        for( int i = 1; i <= aMapIndex.Extent(); i++)
+          anIdContainer.insert(aMapIndex(i));
+        TIdContainer::const_iterator anIter = anIdContainer.begin();
+        for( ; anIter != anIdContainer.end(); anIter++){
+          theName += QString(" %1").arg(*anIter);
+        }
+        return aMapIndex.Extent();
       }
     }
     return -1;
@@ -1069,8 +1166,8 @@ namespace SMESH
   }
 
   int GetSelected(LightApp_SelectionMgr*       theMgr,
-                 TColStd_IndexedMapOfInteger& theMap,
-                 const bool                   theIsElement)
+                  TColStd_IndexedMapOfInteger& theMap,
+                  const bool                   theIsElement)
   {
     theMap.Clear();
     SALOME_ListIO selected; theMgr->selectedObjects( selected );
@@ -1079,7 +1176,7 @@ namespace SMESH
     {
       Handle(SALOME_InteractiveObject) anIO = selected.First();
       if ( anIO->hasEntry() ) {
-       theMgr->GetIndexes( anIO, theMap );
+        theMgr->GetIndexes( anIO, theMap );
       }
     }
     return theMap.Extent();
@@ -1110,9 +1207,9 @@ namespace SMESH
     for ( int i = 1; i <= aMapIndex.Extent(); i++ ) {
       int aVal = aMapIndex( i );
       if ( aVal > 0 )
-       anObjId = aVal;
+        anObjId = aVal;
       else
-       anEdgeNum = abs( aVal );
+        anEdgeNum = abs( aVal );
     }
 
     if ( anObjId == -1 || anEdgeNum == -1 )
@@ -1126,7 +1223,8 @@ namespace SMESH
     if( SVTK_ViewWindow* aWnd = SMESH::GetCurrentVtkView() )
     {
       vtkRenderer *aRenderer = aWnd->getRenderer();
-      vtkActorCollection *aCollection = aRenderer->GetActors();
+      VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
+      vtkActorCollection *aCollection = aCopy.GetActors();
       aCollection->InitTraversal();
 
       while ( vtkActor *anAct = aCollection->GetNextActor())
@@ -1140,4 +1238,134 @@ namespace SMESH
 
     }
   }
+
+  //----------------------------------------------------------------------------
+  // internal function
+  void ComputeBoundsParam( vtkFloatingPointType theBounds[6],
+                           vtkFloatingPointType theDirection[3],
+                           vtkFloatingPointType theMinPnt[3],
+                           vtkFloatingPointType& theMaxBoundPrj,
+                           vtkFloatingPointType& theMinBoundPrj )
+  {
+    //Enlarge bounds in order to avoid conflicts of precision
+    for(int i = 0; i < 6; i += 2){
+      static double EPS = 1.0E-3;
+      vtkFloatingPointType aDelta = (theBounds[i+1] - theBounds[i])*EPS;
+      theBounds[i] -= aDelta;
+      theBounds[i+1] += aDelta;
+    }
+
+    vtkFloatingPointType aBoundPoints[8][3] = { {theBounds[0],theBounds[2],theBounds[4]},
+                                                {theBounds[1],theBounds[2],theBounds[4]},
+                                                {theBounds[0],theBounds[3],theBounds[4]},
+                                                {theBounds[1],theBounds[3],theBounds[4]},
+                                                {theBounds[0],theBounds[2],theBounds[5]},
+                                                {theBounds[1],theBounds[2],theBounds[5]}, 
+                                                {theBounds[0],theBounds[3],theBounds[5]}, 
+                                                {theBounds[1],theBounds[3],theBounds[5]}};
+
+    int aMaxId = 0;
+    theMaxBoundPrj = vtkMath::Dot(theDirection,aBoundPoints[aMaxId]);
+    theMinBoundPrj = theMaxBoundPrj;
+    for(int i = 1; i < 8; i++){
+      vtkFloatingPointType aTmp = vtkMath::Dot(theDirection,aBoundPoints[i]);
+      if(theMaxBoundPrj < aTmp){
+        theMaxBoundPrj = aTmp;
+        aMaxId = i;
+      }
+      if(theMinBoundPrj > aTmp){
+        theMinBoundPrj = aTmp;
+      }
+    }
+    vtkFloatingPointType *aMinPnt = aBoundPoints[aMaxId];
+    theMinPnt[0] = aMinPnt[0];
+    theMinPnt[1] = aMinPnt[1];
+    theMinPnt[2] = aMinPnt[2];
+  }
+
+  // internal function
+  void DistanceToPosition( vtkFloatingPointType theBounds[6],
+                           vtkFloatingPointType theDirection[3],
+                           vtkFloatingPointType theDist,
+                           vtkFloatingPointType thePos[3] )
+  {
+    vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
+    ComputeBoundsParam(theBounds,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
+    vtkFloatingPointType aLength = (aMaxBoundPrj-aMinBoundPrj)*theDist;
+    thePos[0] = aMinPnt[0]-theDirection[0]*aLength;
+    thePos[1] = aMinPnt[1]-theDirection[1]*aLength;
+    thePos[2] = aMinPnt[2]-theDirection[2]*aLength;
+  }
+
+  // internal function (currently unused, left just in case)
+  void PositionToDistance( vtkFloatingPointType theBounds[6],
+                           vtkFloatingPointType theDirection[3],
+                           vtkFloatingPointType thePos[3],
+                           vtkFloatingPointType& theDist )
+  {
+    vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
+    ComputeBoundsParam(theBounds,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
+    vtkFloatingPointType aPrj = vtkMath::Dot(theDirection,thePos);
+    theDist = (aPrj-aMinBoundPrj)/(aMaxBoundPrj-aMinBoundPrj);
+  }
+
+  bool ComputeClippingPlaneParameters( std::list<vtkActor*> theActorList,
+                                       vtkFloatingPointType theNormal[3],
+                                       vtkFloatingPointType theDist,
+                                       vtkFloatingPointType theBounds[6],
+                                       vtkFloatingPointType theOrigin[3] )
+  {
+    bool anIsOk = false;
+    theBounds[0] = theBounds[2] = theBounds[4] = VTK_DOUBLE_MAX;
+    theBounds[1] = theBounds[3] = theBounds[5] = -VTK_DOUBLE_MAX;
+    std::list<vtkActor*>::iterator anIter = theActorList.begin();
+    for( ; anIter != theActorList.end(); anIter++ ) {
+      if( vtkActor* aVTKActor = *anIter ) {
+        if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) {
+          vtkFloatingPointType aBounds[6];
+          anActor->GetUnstructuredGrid()->GetBounds( aBounds );
+          theBounds[0] = std::min( theBounds[0], aBounds[0] );
+          theBounds[1] = std::max( theBounds[1], aBounds[1] );
+          theBounds[2] = std::min( theBounds[2], aBounds[2] );
+          theBounds[3] = std::max( theBounds[3], aBounds[3] );
+          theBounds[4] = std::min( theBounds[4], aBounds[4] );
+          theBounds[5] = std::max( theBounds[5], aBounds[5] );
+          anIsOk = true;
+        }
+      }
+    }
+
+    if( !anIsOk )
+      return false;
+
+    DistanceToPosition( theBounds, theNormal, theDist, theOrigin );
+    return true;
+  }
+
+#ifndef DISABLE_PLOT2DVIEWER
+  //================================================================================
+  /*!
+   * \brief Find all SMESH_Actor's in the View Window.
+   * If actor constains Plot2d_Histogram object remove it from each Plot2d Viewer.
+   */
+  //================================================================================
+
+  void ClearPlot2Viewers( SUIT_ViewWindow* theWindow ) {
+    if(SVTK_ViewWindow* aViewWindow = GetVtkViewWindow(theWindow)){
+      vtkRenderer *aRenderer = aViewWindow->getRenderer();
+      VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
+      vtkActorCollection *aCollection = aCopy.GetActors();
+      aCollection->InitTraversal();
+      while(vtkActor *anAct = aCollection->GetNextActor()){
+        if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
+          if(anActor->hasIO() && anActor->GetPlot2Histogram() ){
+            ProcessIn2DViewers(anActor,RemoveFrom2dViewer);
+          }
+        }
+      }
+    }
+  }
+  
+#endif
+
 } // end of namespace SMESH
index 05d2e268bf1472e291b6a3ca7ce426f2f53a5b39..94d69a9cd9d3b08d73add36bbf5f84b793b2149e 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_VTKUtils.h
 // Author : Open CASCADE S.A.S.
@@ -56,20 +57,22 @@ class SMESHGUI;
 class SMESH_Actor;
 class SALOME_Actor;
 
+class vtkActor;
+
 namespace SMESH
 {
   //----------------------------------------------------------------------------
   typedef std::pair<int,std::string> TKeyOfVisualObj;
   
 SMESHGUI_EXPORT
-  TVisualObjPtr GetVisualObj( int, const char* );
+  TVisualObjPtr GetVisualObj( int, const char*, bool nulData =false );
 SMESHGUI_EXPORT
   void OnVisuException(); // PAL16631
 
   //----------------------------------------------------------------------------
 SMESHGUI_EXPORT
   SVTK_ViewWindow* GetViewWindow( const SalomeApp_Module* = 0,
-                                 bool = false );
+                                  bool = false );
 SMESHGUI_EXPORT
   SVTK_ViewWindow* FindVtkViewWindow( SUIT_ViewManager*, SUIT_ViewWindow* );
 SMESHGUI_EXPORT
@@ -112,14 +115,17 @@ SMESHGUI_EXPORT
 
 SMESHGUI_EXPORT
   bool UpdateView( SUIT_ViewWindow*, EDisplaing, const char* = "" );
-SMESHGUI_EXPORT                   
+SMESHGUI_EXPORT            
   bool UpdateView( EDisplaing, const char* = "" );
 
 SMESHGUI_EXPORT
   void UpdateView();
 
 SMESHGUI_EXPORT
-  bool Update( const Handle(SALOME_InteractiveObject)&, bool );
+  bool UpdateNulData( const Handle(SALOME_InteractiveObject)& theIO, bool theDisplay);
+
+SMESHGUI_EXPORT
+  bool Update( const Handle(SALOME_InteractiveObject)& theIO, bool theDisplay);
 
   //----------------------------------------------------------------------------
 SMESHGUI_EXPORT  
@@ -153,37 +159,52 @@ SMESHGUI_EXPORT
   //----------------------------------------------------------------------------
 SMESHGUI_EXPORT  
   int GetNameOfSelectedNodes( SVTK_Selector*,
-                             const Handle(SALOME_InteractiveObject)&,
-                             QString& );
+                              const Handle(SALOME_InteractiveObject)&,
+                              QString& );
 SMESHGUI_EXPORT
   int GetNameOfSelectedElements( SVTK_Selector*,
-                                const Handle(SALOME_InteractiveObject)&,
-                                QString& );
+                                 const Handle(SALOME_InteractiveObject)&,
+                                 QString& );
 SMESHGUI_EXPORT
   int GetEdgeNodes( SVTK_Selector*, const TVisualObjPtr&, int&, int& );
 
   //----------------------------------------------------------------------------
 SMESHGUI_EXPORT  
   int GetNameOfSelectedNodes( LightApp_SelectionMgr*,
-                             const Handle(SALOME_InteractiveObject)&,
-                             QString& );
+                              const Handle(SALOME_InteractiveObject)&,
+                              QString& );
 SMESHGUI_EXPORT
   int GetNameOfSelectedNodes( LightApp_SelectionMgr*, QString& );
 SMESHGUI_EXPORT
   int GetNameOfSelectedElements( LightApp_SelectionMgr*,
-                                const Handle(SALOME_InteractiveObject)&,
-                                QString& );
+                                 const Handle(SALOME_InteractiveObject)&,
+                                 QString& );
 SMESHGUI_EXPORT
   int GetNameOfSelectedElements( LightApp_SelectionMgr*, QString& );
 SMESHGUI_EXPORT
   int GetSelected( LightApp_SelectionMgr*, TColStd_IndexedMapOfInteger&, 
-                  const bool = true );
+                   const bool = true );
 
 SMESHGUI_EXPORT
   int GetEdgeNodes( LightApp_SelectionMgr*, int&, int& );
 
 SMESHGUI_EXPORT
   void SetControlsPrecision( const long );
+
+#ifndef DISABLE_PLOT2DVIEWER
+SMESHGUI_EXPORT
+  void ClearPlot2Viewers( SUIT_ViewWindow* theWindow );
+#endif
+
+  //----------------------------------------------------------------------------
+SMESHGUI_EXPORT
+  bool ComputeClippingPlaneParameters( std::list<vtkActor*> theActorList,
+                                       vtkFloatingPointType theNormal[3],
+                                       vtkFloatingPointType theDist,
+                                       vtkFloatingPointType theBounds[6],
+                                       vtkFloatingPointType theOrigin[3] );
+ SMESHGUI_EXPORT
+   void RemoveVisualObjectWithActors( const char* theEntry, bool fromAllViews = false );
 };
 
 #endif // SMESHGUI_VTKUTILS_H
diff --git a/src/SMESHGUI/SMESHGUI_WhatIsDlg.cxx b/src/SMESHGUI/SMESHGUI_WhatIsDlg.cxx
deleted file mode 100755 (executable)
index c49e2dc..0000000
+++ /dev/null
@@ -1,589 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-// SMESH SMESHGUI : GUI for SMESH component
-// File   : SMESHGUI_WhatIsDlg.cxx
-// Author : Vladimir TURIN, Open CASCADE S.A.S.
-// SMESH includes
-//
-#include "SMESHGUI_WhatIsDlg.h"
-
-#include "SMESHGUI.h"
-#include "SMESHGUI_Utils.h"
-#include "SMESHGUI_VTKUtils.h"
-#include "SMESHGUI_MeshUtils.h"
-#include "SMESHGUI_IdValidator.h"
-
-#include "SMESH_Actor.h"
-#include "SMESH_TypeFilter.hxx"
-#include "SMESH_LogicalFilter.hxx"
-#include "SMDS_Mesh.hxx"
-#include "SMDS_VolumeTool.hxx"
-
-// SALOME GUI includes
-#include <SUIT_Desktop.h>
-#include <SUIT_ResourceMgr.h>
-#include <SUIT_Session.h>
-#include <SUIT_MessageBox.h>
-
-#include <LightApp_Application.h>
-#include <LightApp_SelectionMgr.h>
-
-#include <SVTK_ViewModel.h>
-#include <SVTK_Selection.h>
-#include <SVTK_ViewWindow.h>
-#include <SALOME_ListIO.hxx>
-
-// OCCT includes
-#include <TColStd_MapOfInteger.hxx>
-#include <gp_XYZ.hxx>
-
-// Qt includes
-#include <QButtonGroup>
-#include <QGroupBox>
-#include <QLabel>
-#include <QLineEdit>
-#include <QPushButton>
-#include <QRadioButton>
-#include <QTextBrowser>
-#include <QHBoxLayout>
-#include <QVBoxLayout>
-#include <QGridLayout>
-#include <QKeyEvent>
-
-// IDL includes
-#include <SALOMEconfig.h>
-#include CORBA_SERVER_HEADER(SMESH_Group)
-
-#define SPACING 6
-#define MARGIN  11
-
-//=================================================================================
-// class    : SMESHGUI_WhatIsDlg()
-// purpose  :
-//=================================================================================
-SMESHGUI_WhatIsDlg::SMESHGUI_WhatIsDlg( SMESHGUI* theModule )
-  : QDialog( SMESH::GetDesktop( theModule ) ),
-    mySMESHGUI( theModule ),
-    mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
-{
-  setModal( false );
-  setAttribute( Qt::WA_DeleteOnClose, true );
-  setWindowTitle(tr("SMESH_WHAT_IS_TITLE"));
-  setSizeGripEnabled(true);
-  QVBoxLayout* SMESHGUI_WhatIsDlgLayout = new QVBoxLayout(this);
-  SMESHGUI_WhatIsDlgLayout->setSpacing(SPACING);
-  SMESHGUI_WhatIsDlgLayout->setMargin(MARGIN);
-  
-  /***************************************************************/
-  GroupMesh = new QGroupBox(this);
-  QHBoxLayout* GroupMeshLayout = new QHBoxLayout(GroupMesh);
-  GroupMeshLayout->setSpacing(SPACING);
-  GroupMeshLayout->setMargin(MARGIN);
-
-  MeshLabel = new QLabel(tr("SMESH_NAME"), GroupMesh);
-  GroupMeshLayout->addWidget(MeshLabel);
-  MeshName = new QLineEdit(GroupMesh);
-  MeshName->setReadOnly(true);
-  GroupMeshLayout->addWidget(MeshName);
-
-  /***************************************************************/
-  GroupSelections = new QGroupBox(tr("ENTITY_TYPE"), this);
-  QButtonGroup* GroupSel = new QButtonGroup(this);
-  QHBoxLayout* GroupSelectionsLayout = new QHBoxLayout(GroupSelections);
-  GroupSelectionsLayout->setSpacing(SPACING);
-  GroupSelectionsLayout->setMargin(MARGIN);
-
-  RadioButtonNodes = new QRadioButton(tr("SMESH_NODES"), GroupSelections);
-  GroupSelectionsLayout->addWidget(RadioButtonNodes);
-  GroupSel->addButton(RadioButtonNodes, 0);
-  RadioButtonElements = new QRadioButton(tr("SMESH_ELEMENTS"), GroupSelections);
-  GroupSelectionsLayout->addWidget(RadioButtonElements);
-  GroupSel->addButton(RadioButtonElements, 1);
-
-  /***************************************************************/
-  GroupArguments = new QGroupBox(tr("SMESH_INFORMATION"), this);
-  QGridLayout* GroupArgumentsLayout = new QGridLayout(GroupArguments);
-  GroupArgumentsLayout->setSpacing(SPACING);
-  GroupArgumentsLayout->setMargin(MARGIN);
-
-  // Controls for elements selection
-  TextLabelElements  = new QLabel(tr("SMESH_ID_ELEMENTS"), GroupArguments);
-  GroupArgumentsLayout->addWidget(TextLabelElements, 0, 0);
-
-  LineEditElements  = new QLineEdit(GroupArguments);
-  LineEditElements->setValidator(new SMESHGUI_IdValidator(this));
-  GroupArgumentsLayout->addWidget(LineEditElements, 0, 1);
-
-  // information text browser
-  Info = new QTextBrowser(GroupArguments);
-  Info->setMinimumSize(200, 150);
-  GroupArgumentsLayout->addWidget(Info, 1, 0, 1, 2);
-
-  /***************************************************************/
-  GroupButtons = new QGroupBox(this);
-  QHBoxLayout* GroupButtonsLayout = new QHBoxLayout(GroupButtons);
-  GroupButtonsLayout->setSpacing(SPACING);
-  GroupButtonsLayout->setMargin(MARGIN);
-
-  buttonOk = new QPushButton(tr("SMESH_BUT_OK"), GroupButtons);
-  buttonOk->setAutoDefault(true);
-  buttonOk->setDefault(true);
-  buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons);
-  buttonHelp->setAutoDefault(true);
-
-  GroupButtonsLayout->addWidget(buttonOk);
-  GroupButtonsLayout->addSpacing(10);
-  GroupButtonsLayout->addStretch();
-  GroupButtonsLayout->addWidget(buttonHelp);
-
-  SMESHGUI_WhatIsDlgLayout->addWidget(GroupMesh);
-  SMESHGUI_WhatIsDlgLayout->addWidget(GroupSelections);
-  SMESHGUI_WhatIsDlgLayout->addWidget(GroupArguments);
-  SMESHGUI_WhatIsDlgLayout->addWidget(GroupButtons);
-
-  RadioButtonNodes->setChecked(true);
-
-  mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
-
-  mySMESHGUI->SetActiveDialogBox((QDialog*)this);
-
-  // Costruction of the logical filter
-  SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter (MESHorSUBMESH);
-  SMESH_TypeFilter* aSmeshGroupFilter    = new SMESH_TypeFilter (GROUP);
-
-  QList<SUIT_SelectionFilter*> aListOfFilters;
-  if (aMeshOrSubMeshFilter) aListOfFilters.append(aMeshOrSubMeshFilter);
-  if (aSmeshGroupFilter)    aListOfFilters.append(aSmeshGroupFilter);
-
-  myMeshOrSubMeshOrGroupFilter =
-    new SMESH_LogicalFilter(aListOfFilters, SMESH_LogicalFilter::LO_OR);
-
-  myHelpFileName = "mesh_infos_page.html#mesh_element_info_anchor";
-
-  Init();
-
-  /* signals and slots connections */
-  connect(buttonOk,         SIGNAL(clicked()),     this, SLOT(ClickOnOk()));
-  connect(buttonHelp,       SIGNAL(clicked()),     this, SLOT(ClickOnHelp()));
-  connect(GroupSel,         SIGNAL(buttonClicked(int)), SLOT(SelectionsClicked(int)));
-
-  connect(mySMESHGUI,       SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
-  connect(mySelectionMgr,   SIGNAL(currentSelectionChanged()),      this, SLOT(SelectionIntoArgument()));
-  /* to close dialog if study change */
-  connect(mySMESHGUI,       SIGNAL(SignalCloseAllDialogs()),  this, SLOT(ClickOnCancel()));
-  connect(LineEditElements, SIGNAL(textChanged(const QString&)),    SLOT(onTextChange(const QString&)));
-
-  SelectionsClicked(0);
-  SelectionIntoArgument();
-}
-
-//=================================================================================
-// function : ~SMESHGUI_WhatIsDlg()
-// purpose  : Destroys the object and frees any allocated resources
-//=================================================================================
-SMESHGUI_WhatIsDlg::~SMESHGUI_WhatIsDlg()
-{
-}
-
-//=================================================================================
-// function : Init()
-// purpose  :
-//=================================================================================
-void SMESHGUI_WhatIsDlg::Init (bool ResetControls)
-{
-  myBusy = false;
-
-  LineEditElements->clear();
-
-  myActor = 0;
-  myMesh = SMESH::SMESH_Mesh::_nil();
-
-  if (ResetControls) {
-    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-      aViewWindow->SetSelectionMode( CellSelection );
-    onTextChange(LineEditElements->text());
-    
-    SelectionIntoArgument();
-  }
-}
-
-//=================================================================================
-// function : SelectionsClicked()
-// purpose  : Radio button management
-//=================================================================================
-void SMESHGUI_WhatIsDlg::SelectionsClicked (int selectionId)
-{
-  disconnect(mySelectionMgr, 0, this, 0);
-
-  mySelectionMgr->clearFilters();
-
-  switch (selectionId) {
-  case 0:
-    {
-      SMESH::SetPointRepresentation(true);
-      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-       aViewWindow->SetSelectionMode( NodeSelection );
-      break;
-    }    
-  case 1:
-    {
-      SMESH::SetPointRepresentation(false);
-      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-       aViewWindow->SetSelectionMode( CellSelection );
-      break;
-    }
-  }
-
-  connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
-  SelectionIntoArgument();
-}
-
-//=================================================================================
-// function : ClickOnOk()
-// purpose  :
-//=================================================================================
-void SMESHGUI_WhatIsDlg::ClickOnOk()
-{
-  if (mySMESHGUI->isActiveStudyLocked())
-    return;
-
-  SMESH::UpdateView();
-  Init(false);
-  SelectionIntoArgument();
-  ClickOnCancel();
-}
-
-//=================================================================================
-// function : ClickOnCancel()
-// purpose  :
-//=================================================================================
-void SMESHGUI_WhatIsDlg::ClickOnCancel()
-{
-  disconnect(mySelectionMgr, 0, this, 0);
-  mySelectionMgr->clearFilters();
-  SMESH::SetPointRepresentation(false);
-  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-    aViewWindow->SetSelectionMode( ActorSelection );
-  mySMESHGUI->ResetState();
-  reject();
-}
-
-//=================================================================================
-// function : ClickOnHelp()
-// purpose  :
-//=================================================================================
-void SMESHGUI_WhatIsDlg::ClickOnHelp()
-{
-  LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
-  if (app) 
-    app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
-  else {
-    SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
-                            tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
-                            arg(app->resourceMgr()->stringValue("ExternalBrowser",
-                                                                "application")).
-                            arg(myHelpFileName));
-  }
-}
-
-//=======================================================================
-// function : onTextChange()
-// purpose  :
-//=======================================================================
-void SMESHGUI_WhatIsDlg::onTextChange (const QString& theNewText)
-{
-  if (myBusy) return;
-  myBusy = true;
-
-  // hilight entered elements
-  SMDS_Mesh* aMesh = 0;
-  if (myActor)
-    aMesh = myActor->GetObject()->GetMesh();
-
-  if (aMesh) {
-    Handle(SALOME_InteractiveObject) anIO = myActor->getIO();
-    
-    TColStd_MapOfInteger newIndices;
-
-    QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
-
-    for (int i = 0; i < aListId.count(); i++) {
-      const SMDS_MeshElement * e = RadioButtonNodes->isChecked()?
-       aMesh->FindNode(aListId[ i ].toInt()):
-       aMesh->FindElement(aListId[ i ].toInt());
-      if (e)
-       newIndices.Add(e->GetID());
-    }
-
-    mySelector->AddOrRemoveIndex( anIO, newIndices, false );
-    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
-      aViewWindow->highlight( anIO, true, true );
-  }
-
-  SelectionIntoArgument();
-
-  myBusy = false;
-}
-
-//=================================================================================
-// function : SelectionIntoArgument()
-// purpose  : Called when selection as changed or other case
-//=================================================================================
-void SMESHGUI_WhatIsDlg::SelectionIntoArgument()
-{
-  int curBusy = myBusy;
-
-  // clear
-  myActor = 0;
-  QString aString = "";
-
-  myBusy = true;
-  if(!curBusy)
-    LineEditElements->setText(aString);
-  MeshName->setText(aString);
-  GroupMesh->setTitle(tr(""));
-  Info->clear();
-  myBusy = curBusy;
-
-  if (!GroupButtons->isEnabled()) // inactive
-    return;
-
-  // get selected mesh
-  SALOME_ListIO aList;
-  mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
-
-  int nbSel = aList.Extent();
-
-  if (nbSel != 1)
-    return;
-
-  Handle(SALOME_InteractiveObject) IO = aList.First();
-  myMesh = SMESH::GetMeshByIO(IO);
-  if (myMesh->_is_nil())
-    return;
-
-  myActor = SMESH::FindActorByObject(myMesh);
-  if (!myActor)
-    myActor = SMESH::FindActorByEntry(IO->getEntry());
-  if (!myActor)
-    return;
-
-  QString aName;
-  SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aName);
-  MeshName->setText(aName);
-  if(!SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IO)->_is_nil()) {
-    GroupMesh->setTitle(tr("SMESH_MESH"));
-  } else if(!SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(IO)->_is_nil()) {
-    GroupMesh->setTitle(tr("SMESH_SUBMESH"));
-  } else if(!SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(IO)->_is_nil()) {
-    GroupMesh->setTitle(tr("SMESH_GROUP"));
-  }
-
-  int aNbUnits = 0;
-  
-  aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, IO, aString);
-  
-  if (aNbUnits < 1)
-    return;
-
-  const SMDS_MeshElement * e = RadioButtonNodes->isChecked()?
-    myActor->GetObject()->GetMesh()->FindNode(aString.toInt()):
-    myActor->GetObject()->GetMesh()->FindElement(aString.toInt());
-  if (e) {
-    QString anInfo;
-    anInfo=tr("ENTITY_TYPE") + ": ";
-    if(e->GetType() == SMDSAbs_Node) {
-      anInfo+=tr("MESH_NODE")+"\n";
-      //const SMDS_MeshNode *en = (SMDS_MeshNode*) e; // VSR: not used!
-    } else if(e->GetType() == SMDSAbs_Edge) {
-      anInfo+=tr("SMESH_EDGE")+"\n";
-      anInfo+=tr("SMESH_MESHINFO_TYPE")+": ";
-      const SMDS_MeshEdge *ee = (SMDS_MeshEdge*) e;
-      anInfo+=(ee->IsQuadratic()?tr("SMESH_MESHINFO_ORDER2"):tr("SMESH_MESHINFO_ORDER1"))+"\n";
-    } else if(e->GetType() == SMDSAbs_Face) {
-      const SMDS_MeshFace *ef = (SMDS_MeshFace*) e;
-      anInfo+=tr("SMESH_FACE")+"\n";
-      anInfo+=tr("SMESH_MESHINFO_TYPE")+": ";
-      if(!ef->IsPoly())
-       anInfo+=(ef->IsQuadratic()?tr("SMESH_MESHINFO_ORDER2"):tr("SMESH_MESHINFO_ORDER1"))+" ";
-      switch(ef->NbNodes()) {
-      case 3:
-      case 6:
-       {
-         anInfo+=tr("SMESH_TRIANGLE");
-         break;
-       }
-      case 4:
-      case 8:
-       {
-         anInfo+=tr("SMESH_QUADRANGLE");
-         break;
-       }
-      default:
-       break;
-      }
-      anInfo+="\n";
-    } else if(e->GetType() == SMDSAbs_Volume) {
-      anInfo+=tr("SMESH_VOLUME")+"\n";
-      anInfo+=tr("SMESH_MESHINFO_TYPE")+": ";
-      const SMDS_MeshVolume *ev = (SMDS_MeshVolume*) e;
-      SMDS_VolumeTool vt(ev);
-      if(vt.GetVolumeType() != SMDS_VolumeTool::POLYHEDA)
-       anInfo+=(ev->IsQuadratic()?tr("SMESH_MESHINFO_ORDER2"):tr("SMESH_MESHINFO_ORDER1"))+" ";
-      switch(vt.GetVolumeType()) {
-      case SMDS_VolumeTool::TETRA:
-      case SMDS_VolumeTool::QUAD_TETRA:
-       {
-         anInfo+=tr("SMESH_TETRAS");
-         break;
-       }
-      case SMDS_VolumeTool::PYRAM:
-      case SMDS_VolumeTool::QUAD_PYRAM:
-       {
-         anInfo+=tr("SMESH_PYRAMID");
-         break;
-       }
-      case SMDS_VolumeTool::PENTA:
-      case SMDS_VolumeTool::QUAD_PENTA:
-       {
-         anInfo+=tr("SMESH_PRISM");
-         break;
-       }
-      case SMDS_VolumeTool::HEXA:
-      case SMDS_VolumeTool::QUAD_HEXA:
-       {
-         anInfo+=tr("SMESH_HEXAS");
-         break;
-       }
-      case SMDS_VolumeTool::POLYHEDA:
-       {
-         anInfo+=tr("SMESH_POLYEDRON");
-         break;
-       }
-      default:
-       break;
-      }
-      anInfo+="\n";
-    }
-    if(e->GetType() != SMDSAbs_Node)
-      anInfo+=tr("GRAVITY_CENTER") + ":\n";
-    gp_XYZ anXYZ(0.,0.,0.);
-    SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
-    int nbNodes = 0;
-    for( ; nodeIt->more(); nbNodes++) {
-      const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-      anXYZ.Add( gp_XYZ( node->X(), node->Y(), node->Z() ) );
-    }
-    anXYZ.Divide(e->NbNodes());
-    anInfo+=QString("X=%1\nY=%2\nZ=%3\n").arg(anXYZ.X()).arg(anXYZ.Y()).arg(anXYZ.Z());
-    Info->setText(anInfo);
-  }
-
-  if(!curBusy) {
-    myBusy = true;
-    LineEditElements->setText(aString);
-    myBusy = false;
-  }
-}
-
-//=================================================================================
-// function : DeactivateActiveDialog()
-// purpose  :
-//=================================================================================
-void SMESHGUI_WhatIsDlg::DeactivateActiveDialog()
-{
-  if (GroupArguments->isEnabled()) {
-    GroupSelections->setEnabled(false);
-    GroupMesh->setEnabled(false);
-    GroupArguments->setEnabled(false);
-    GroupButtons->setEnabled(false);
-    mySMESHGUI->ResetState();
-    mySMESHGUI->SetActiveDialogBox(0);
-  }
-}
-
-//=================================================================================
-// function : ActivateThisDialog()
-// purpose  :
-//=================================================================================
-void SMESHGUI_WhatIsDlg::ActivateThisDialog()
-{
-  /* Emit a signal to deactivate the active dialog */
-  mySMESHGUI->EmitSignalDeactivateDialog();
-  GroupArguments->setEnabled(true);
-  GroupButtons->setEnabled(true);
-  GroupSelections->setEnabled(true);
-  GroupMesh->setEnabled(true);
-
-  mySMESHGUI->SetActiveDialogBox((QDialog*)this);
-
-  if ( SMESH::GetViewWindow( mySMESHGUI ))
-    SelectionsClicked(RadioButtonNodes->isChecked()?0:1);
-
-  SelectionIntoArgument();
-}
-
-//=================================================================================
-// function : enterEvent()
-// purpose  :
-//=================================================================================
-void SMESHGUI_WhatIsDlg::enterEvent (QEvent*)
-{
-  if (!GroupArguments->isEnabled())
-    ActivateThisDialog();
-}
-
-//=================================================================================
-// function : closeEvent()
-// purpose  :
-//=================================================================================
-void SMESHGUI_WhatIsDlg::closeEvent (QCloseEvent*)
-{
-  /* same than click on cancel button */
-  ClickOnCancel();
-}
-
-//=======================================================================
-//function : hideEvent
-//purpose  : caused by ESC key
-//=======================================================================
-void SMESHGUI_WhatIsDlg::hideEvent (QHideEvent*)
-{
-  if (!isMinimized())
-    ClickOnCancel();
-}
-
-//=================================================================================
-// function : keyPressEvent()
-// purpose  :
-//=================================================================================
-void SMESHGUI_WhatIsDlg::keyPressEvent( QKeyEvent* e )
-{
-  QDialog::keyPressEvent( e );
-  if ( e->isAccepted() )
-    return;
-
-  if ( e->key() == Qt::Key_F1 ) {
-    e->accept();
-    ClickOnHelp();
-  }
-}
diff --git a/src/SMESHGUI/SMESHGUI_WhatIsDlg.h b/src/SMESHGUI/SMESHGUI_WhatIsDlg.h
deleted file mode 100755 (executable)
index e308c53..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-// SMESH SMESHGUI : GUI for SMESH component
-// File   : SMESHGUI_WhatIsDlg.h
-// Author : Vladimir TURIN, Open CASCADE S.A.S.
-//
-#ifndef SMESHGUI_WHATISDLG_H
-#define SMESHGUI_WHATISDLG_H
-
-// Qt includes
-#include <QDialog>
-
-// IDL includes
-#include <SALOMEconfig.h>
-#include CORBA_SERVER_HEADER(SMESH_Mesh)
-
-class QGroupBox;
-class QLabel;
-class QLineEdit;
-class QPushButton;
-class QRadioButton;
-class QTextBrowser;
-class SMESHGUI;
-class SMESH_Actor;
-class SVTK_Selector;
-class LightApp_SelectionMgr;
-class SMESH_LogicalFilter;
-
-//=================================================================================
-// class    : SMESHGUI_WhatIsDlg
-// purpose  :
-//=================================================================================
-class SMESHGUI_WhatIsDlg : public QDialog
-{ 
-  Q_OBJECT
-   
-public:
-  SMESHGUI_WhatIsDlg( SMESHGUI* );
-  ~SMESHGUI_WhatIsDlg();
-  
-private:
-  void                          Init( bool = true );
-  void                          closeEvent( QCloseEvent* );
-  void                          enterEvent( QEvent* );         /* mouse enter the QWidget */
-  void                          hideEvent( QHideEvent* );      /* ESC key */
-  void                          keyPressEvent( QKeyEvent* );
-
-  SMESHGUI*                     mySMESHGUI;              /* Current SMESHGUI object */
-  LightApp_SelectionMgr*        mySelectionMgr;          /* User shape selection */
-
-  SVTK_Selector*                mySelector;
-
-  bool                          myBusy;
-  SMESH::SMESH_Mesh_var         myMesh;
-  SMESH_Actor*                  myActor;
-  SMESH_LogicalFilter*          myMeshOrSubMeshOrGroupFilter;
-
-  QGroupBox*                    GroupSelections;
-  QRadioButton*                 RadioButtonNodes;
-  QRadioButton*                 RadioButtonElements;
-  QGroupBox*                    GroupButtons;
-  QPushButton*                  buttonOk;
-  QPushButton*                  buttonHelp;
-  QGroupBox*                    GroupArguments;
-  QGroupBox*                    GroupMesh;
-  QLabel*                       TextLabelElements;
-  QLineEdit*                    LineEditElements;
-  QLabel*                       MeshLabel;
-  QLineEdit*                    MeshName;
-
-  QTextBrowser*                 Info;
-    
-  QString                       myHelpFileName;
-
-private slots:
-  void                          SelectionsClicked( int );
-  void                          ClickOnOk();
-  void                          ClickOnCancel();
-  void                          ClickOnHelp();
-  void                          SelectionIntoArgument();
-  void                          DeactivateActiveDialog();
-  void                          ActivateThisDialog();
-  void                          onTextChange( const QString& );
-};
-
-#endif // SMESHGUI_WHATISDLG_H
index f10cb0341f612c95a67ce8313af3ddc3d8d75fc5..d02d9cd0215796ce92692fda5589a19a1d91023a 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : reading of xml file with list of available hypotheses and algorithms
 // File   : SMESHGUI_XmlHandler.cxx
 // Author : Julia DOROVSKIKH, Open CASCADE S.A.S.
@@ -103,7 +104,7 @@ bool SMESHGUI_XmlHandler::startElement (const QString&, const QString&,
       {
         MESSAGE("Loading Resources " << aResName.toLatin1().data());
         SUIT_ResourceMgr* resMgr = SMESHGUI::resourceMgr();
-       QString lang = resMgr->stringValue( resMgr->langSection(), "language", "en" );
+        QString lang = resMgr->stringValue( resMgr->langSection(), "language", "en" );
         resMgr->loadTranslator( "resources", QString( "%1_msg_%2.qm" ).arg( aResName, lang ) );
         resMgr->loadTranslator( "resources", QString( "%1_images.qm" ).arg( aResName, lang ) );
       }
@@ -164,11 +165,11 @@ bool SMESHGUI_XmlHandler::startElement (const QString&, const QString&,
 
       if (qName == "algorithm")
       {
-        myAlgorithmsMap[aHypAlType] = aHypData;
+        myAlgorithmsMap.insert(aHypAlType,aHypData);
       }
       else
       {
-        myHypothesesMap[aHypAlType] = aHypData;
+        myHypothesesMap.insert(aHypAlType,aHypData);
       }
     }
   }
@@ -186,11 +187,17 @@ bool SMESHGUI_XmlHandler::startElement (const QString&, const QString&,
       {
         QString aHypos = isHypo ? atts.value("hypos") : atts.value("algos");
         aHypos = aHypos.remove( ' ' );
-        QStringList* aHypoList = isHypo ? & aHypoSet->HypoList : & aHypoSet->AlgoList;
-        *aHypoList = aHypos.split( ',', QString::SkipEmptyParts );
+        aHypoSet->set( !isHypo, aHypos.split( ',', QString::SkipEmptyParts ) );
       }
     }
   }
+  else if ( qName == "python-wrap" ||
+            qName == "algo"        ||
+            qName == "hypo"         )
+  {
+    // elements used in SMESH_2smeshpy
+    return true;
+  }
   else
   {
     // error
index 09db4421922a37e5fc6bd8debaaecb310dc2f35f..813938ddfaba187eb777ad7030d645b66d4d867e 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : reading of xml file with list of available hypotheses and algorithms
 // File   : SMESHGUI_XmlHandler.h
 // Author : Julia DOROVSKIKH, Open CASCADE S.A.S.
@@ -34,6 +35,9 @@
 #include <QMap>
 #include <QList>
 
+//GUI includes
+#include <QtxMap.h>
+
 class HypothesisData;
 class HypothesesSet;
 
@@ -45,7 +49,7 @@ public:
 
   bool     startDocument();
   bool     startElement( const QString&, const QString&, 
-                        const QString&, const QXmlAttributes& );
+                         const QString&, const QXmlAttributes& );
   bool     endElement( const QString&, const QString&, const QString& );
   bool     characters( const QString& ); 
 
@@ -54,8 +58,8 @@ public:
   bool     fatalError( const QXmlParseException& );
 
 public:
-  QMap<QString, HypothesisData*>         myHypothesesMap;
-  QMap<QString, HypothesisData*>         myAlgorithmsMap;
+  IMap<QString, HypothesisData*>         myHypothesesMap;
+  IMap<QString, HypothesisData*>         myAlgorithmsMap;
 
   QList<HypothesesSet*>                  myListOfHypothesesSets;
 
index 46a6cb93a2374914d28f7187f34e36b4590d661b..62d8609602bb7376d280bacf810cb1f62732b638 100755 (executable)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : SMESH_SMESHGUI.hxx
 // Author : Alexander BORODIN, Open CASCADE S.A.S.
 //
@@ -26,7 +27,7 @@
 #define SMESH_SMESHGUI_HXX
 
 #ifdef WNT
- #if defined SMESHGUI_EXPORTS
+ #if defined SMESHGUI_EXPORTS || defined SMESH_EXPORTS
   #define SMESHGUI_EXPORT __declspec( dllexport )
  #else
   #define SMESHGUI_EXPORT __declspec( dllimport )
index 0319ce68959874a801cb7059db92f63b7b92ca66..6012d758cd3ca8a0977f07111a95e13b2cc67f89 100644 (file)
@@ -1,28 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE TS>
-<!--
-  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-
-  Copyright (C) 2003-2007  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.com
-
--->
-<TS version="1.1" >
+<TS version="2.0" language="fr_FR">
     <context>
         <name>@default</name>
         <message>
             <source>ICON_BUILD_COMPOUND</source>
             <translation>mesh_build_compound.png</translation>
         </message>
+        <message>
+            <source>ICON_COPY_MESH</source>
+            <translation>copy_mesh.png</translation>
+        </message>
         <message>
             <source>ICON_COMPUTE</source>
             <translation>mesh_compute.png</translation>
             <source>ICON_DLG_BUILD_COMPOUND_MESH</source>
             <translation>mesh_build_compound.png</translation>
         </message>
+        <message>
+            <source>ICON_DLG_COPY_MESH</source>
+            <translation>copy_mesh.png</translation>
+        </message>
+        <message>
+            <source>ICON_DLG_BALL</source>
+            <translation>mesh_ball.png</translation>
+        </message>
+        <message>
+            <source>ICON_DLG_BALL_ELEMENT</source>
+            <translation>mesh_ball.png</translation>
+        </message>
+        <message>
+            <source>ICON_DLG_ELEM0D</source>
+            <translation>mesh_vertex.png</translation>
+        </message>
         <message>
             <source>ICON_DLG_EDGE</source>
             <translation>mesh_line.png</translation>
             <source>ICON_DLG_NODE</source>
             <translation>mesh_vertex.png</translation>
         </message>
+        <message>
+            <source>ICON_DLG_OCTA</source>
+            <translation>mesh_octahedron.png</translation>
+        </message>
+        <message>
+            <source>ICON_DLG_PENTA</source>
+            <translation>mesh_pentahedron.png</translation>
+        </message>
         <message>
             <source>ICON_DLG_POLYGON</source>
             <translation>mesh_polygon.png</translation>
             <source>ICON_DLG_POLYHEDRON</source>
             <translation>mesh_polyhedron.png</translation>
         </message>
+        <message>
+            <source>ICON_DLG_PYRAMID</source>
+            <translation>mesh_pyramid.png</translation>
+        </message>
         <message>
             <source>ICON_DLG_QUADRANGLE</source>
             <translation>mesh_quad.png</translation>
             <source>ICON_DLG_QUADRATIC_HEXAHEDRON</source>
             <translation>mesh_quad_hexahedron.png</translation>
         </message>
+        <message>
+            <source>ICON_DLG_TRIQUADRATIC_HEXAHEDRON</source>
+            <translation>mesh_triquad_hexahedron.png</translation>
+        </message>
         <message>
             <source>ICON_DLG_QUADRATIC_PENTAHEDRON</source>
             <translation>mesh_quad_pentahedron.png</translation>
             <source>ICON_DLG_QUADRATIC_QUADRANGLE</source>
             <translation>mesh_quad_quadrangle.png</translation>
         </message>
+        <message>
+            <source>ICON_DLG_BIQUADRATIC_QUADRANGLE</source>
+            <translation>mesh_biquad_quadrangle.png</translation>
+        </message>
         <message>
             <source>ICON_DLG_QUADRATIC_TETRAHEDRON</source>
             <translation>mesh_quad_tetrahedron.png</translation>
             <source>ICON_DLG_REM_NODE</source>
             <translation>mesh_rem_node.png</translation>
         </message>
+        <message>
+            <source>ICON_DLG_REM_ORPHAN_NODES</source>
+            <translation>mesh_rem_orphan_nodes.png</translation>
+        </message>
         <message>
             <source>ICON_DLG_RENUMBERING_ELEMENTS</source>
             <translation>mesh_renumbering_elements.png</translation>
             <source>ICON_FREE_FACES</source>
             <translation>mesh_free_faces.png</translation>
         </message>
+        <message>
+            <source>ICON_FIND_ELEM</source>
+            <translation>mesh_find_elem_by_point.png</translation>
+        </message>
         <message>
             <source>ICON_HYPO</source>
             <translation>mesh_hypo_length.png</translation>
             <source>ICON_MAP</source>
             <translation>mesh_pattern.png</translation>
         </message>
+        <message>
+            <source>ICON_MAX_ELEMENT_LENGTH_2D</source>
+            <translation>mesh_max_element_length_2d.png</translation>
+        </message>
+        <message>
+            <source>ICON_MAX_ELEMENT_LENGTH_3D</source>
+            <translation>mesh_max_element_length_3d.png</translation>
+        </message>
         <message>
             <source>ICON_OBJBROWSER_SMESH</source>
             <translation>mesh.png</translation>
             <source>ICON_SMESH_TRANSLATION_VECTOR</source>
             <translation>mesh_translation_vector.png</translation>
         </message>
+        <message>
+            <source>ICON_DLG_MESH_SCALE</source>
+            <translation>scale.png</translation>
+        </message>
+        <message>
+            <source>ICON_DLG_SCALE_ALONG_AXES</source>
+            <translation>scale_along_axes.png</translation>
+        </message>
+        <message>
+            <source>ICON_DLG_REORIENT2D_POINT</source>
+            <translation>reorient_faces_point.png</translation>
+        </message>
+        <message>
+            <source>ICON_DLG_REORIENT2D_FACE</source>
+            <translation>reorient_faces_face.png</translation>
+        </message>
+        <message>
+            <source>ICON_REORIENT_2D</source>
+            <translation>reorient_faces_face.png</translation>
+        </message>
+       <message>
+            <source>ICON_SMESH_DUPLICATE_NODES</source>
+            <translation>mesh_duplicate_nodes.png</translation>
+        </message>
+       <message>
+            <source>ICON_SMESH_DUPLICATE_NODES_WITH_ELEM</source>
+            <translation>mesh_duplicate_nodes_with_elem.png</translation>
+        </message>
         <message>
             <source>ICON_SMESH_TREE_ALGO</source>
             <translation>mesh_tree_algo.png</translation>
             <source>ICON_SMESH_TREE_GROUP</source>
             <translation>mesh_tree_group.png</translation>
         </message>
+        <message>
+            <source>ICON_SMESH_TREE_GROUP_ON_FILTER</source>
+            <translation>mesh_tree_group_on_filter.png</translation>
+        </message>
         <message>
             <source>ICON_SMESH_TREE_HYPO</source>
             <translation>mesh_tree_hypo.png</translation>
             <source>ICON_VOLUME_3D</source>
             <translation>mesh_volume_3d.png</translation>
         </message>
+        <message>
+            <source>ICON_BARE_BORDER_VOLUME</source>
+            <translation>bare_border_volume.png</translation>
+        </message>
+        <message>
+            <source>ICON_BARE_BORDER_FACE</source>
+            <translation>bare_border_face.png</translation>
+        </message>
+        <message>
+            <source>ICON_OVER_CONSTRAINED_VOLUME</source>
+            <translation>over_constrained_volume.png</translation>
+        </message>
+        <message>
+            <source>ICON_OVER_CONSTRAINED_FACE</source>
+            <translation>over_constrained_face.png</translation>
+        </message>
+        <message>
+            <source>ICON_EQUAL_NODE</source>
+            <translation>mesh_equal_node.png</translation>
+        </message>
+        <message>
+            <source>ICON_EQUAL_EDGE</source>
+            <translation>mesh_equal_edge.png</translation>
+        </message>
+        <message>
+            <source>ICON_EQUAL_FACE</source>
+            <translation>mesh_equal_face.png</translation>
+        </message>
+        <message>
+            <source>ICON_EQUAL_VOLUME</source>
+            <translation>mesh_equal_volume.png</translation>
+        </message>
         <message>
             <source>ICON_WARP</source>
             <translation>mesh_wrap.png</translation>
         </message>
         <message>
             <source>ICON_WHAT_IS</source>
-            <translation>mesh_whatis.png</translation>
+            <translation>mesh_elem_info.png</translation>
         </message>
         <message>
             <source>ICON_WIRE</source>
             <source>ICON_UNDERLYING_ELEMS</source>
             <translation>mesh_extractGroup.png</translation>
         </message>
+        <message>
+            <source>ICON_2D_FROM_3D</source>
+            <translation>mesh_2d_from_3d.png</translation>
+        </message>
+        <message>
+            <source>ICON_SPLIT_TO_TETRA</source>
+            <translation>split_into_tetra.png</translation>
+        </message>
+        <message>
+            <source>ICON_MEASURE_MIN_DIST</source>
+            <translation>mesh_min_dist.png</translation>
+        </message>
+        <message>
+            <source>ICON_MEASURE_BND_BOX</source>
+            <translation>mesh_bounding_box.png</translation>
+        </message>
     </context>
 </TS>
index a93b7d1f611689c5fbf15b28d5bc3c897f223b72..2ac37e0f5ba72ab79e47c84e5157ee320618fb3b 100644 (file)
+<?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE TS>
-<!--
-  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-
-  Copyright (C) 2003-2007  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.com
-
--->
-<TS version="1.1" >
-    <context>
-        <name>@default</name>
-        <message>
-            <source>AREA_ELEMENTS</source>
-            <translation>Area</translation>
-        </message>
-        <message>
-            <source>ASPECTRATIO_3D_ELEMENTS</source>
-            <translation>Aspect Ratio 3D</translation>
-        </message>
-        <message>
-            <source>ASPECTRATIO_ELEMENTS</source>
-            <translation>Aspect Ratio</translation>
-        </message>
-        <message>
-            <source>COL_ALGO_HEADER</source>
-            <translation>Algorithm</translation>
-        </message>
-        <message>
-            <source>COL_ERROR_HEADER</source>
-            <translation>Error</translation>
-        </message>
-        <message>
-            <source>COL_SHAPE_HEADER</source>
-            <translation>SubShape</translation>
-        </message>
-        <message>
-            <source>COMPERR_ALGO_FAILED</source>
-            <translation>Algorithm failed</translation>
-        </message>
-        <message>
-            <source>COMPERR_BAD_INPUT_MESH</source>
-            <translation>Invalid input mesh</translation>
-        </message>
-        <message>
-            <source>COMPERR_BAD_SHAPE</source>
-            <translation>Unexpected geometry</translation>
-        </message>
-        <message>
-            <source>COMPERR_EXCEPTION</source>
-            <translation>Unknown exception</translation>
-        </message>
-        <message>
-            <source>COMPERR_MEMORY_PB</source>
-            <translation>Memory allocation problem</translation>
-        </message>
-        <message>
-            <source>COMPERR_OCC_EXCEPTION</source>
-            <translation>OCC exception</translation>
-        </message>
-        <message>
-            <source>COMPERR_OK</source>
-            <translation>No errors</translation>
-        </message>
-        <message>
-            <source>COMPERR_SLM_EXCEPTION</source>
-            <translation>SALOME exception</translation>
-        </message>
-        <message>
-            <source>COMPERR_STD_EXCEPTION</source>
-            <translation>std::exception</translation>
-        </message>
-        <message>
-            <source>SMESH_GEOM</source>
-            <translation>Geometry</translation>
-        </message>
-        <message>
-            <source>DIRECT_GEOM_SELECTION</source>
-            <translation>Direct geometry selection</translation>
-        </message>
-        <message>
-            <source>ELEMENT_ID</source>
-            <translation>Element ID</translation>
-        </message>
-        <message>
-            <source>FREE_BORDERS</source>
-            <translation>Free Borders</translation>
-        </message>
-        <message>
-            <source>GEOMETRY_NAME</source>
-            <translation>Geometry name</translation>
-        </message>
-        <message>
-            <source>GEOM_BY_MESH_ELEM_SELECTION</source>
-            <translation>Find geometry by mesh element selection</translation>
-        </message>
-        <message>
-            <source>GLOBAL_ALGO</source>
-            <translation>Global</translation>
-        </message>
-        <message>
-            <source>INF_SELECT_OBJECT</source>
-            <translation>Select an object</translation>
-        </message>
-        <message>
-            <source>LENGTH2D_EDGES</source>
-            <translation>Length 2D</translation>
-        </message>
-        <message>
-            <source>LENGTH_EDGES</source>
-            <translation>Length</translation>
-        </message>
-        <message>
-            <source>LOCAL_ALGO</source>
-            <translation>Local</translation>
-        </message>
-        <message>
-            <source>MEN_ADD</source>
-            <translation>Add</translation>
-        </message>
-        <message>
-            <source>MEN_ADV_INFO</source>
-            <translation>Advanced Mesh Infos</translation>
-        </message>
-        <message>
-            <source>MEN_ALL</source>
-            <translation>All</translation>
-        </message>
-        <message>
-            <source>MEN_AREA</source>
-            <translation>Area</translation>
-        </message>
-        <message>
-            <source>MEN_ASPECT</source>
-            <translation>Aspect Ratio</translation>
-        </message>
-        <message>
-            <source>MEN_ASPECT_3D</source>
-            <translation>Aspect Ratio 3D</translation>
-        </message>
-        <message>
-            <source>MEN_AUTO_COLOR</source>
-            <translation>Auto Color</translation>
-        </message>
-        <message>
-            <source>MEN_AUTO_UPD</source>
-            <translation>Automatic Update</translation>
-        </message>
-        <message>
-            <source>MEN_BUILD_COMPOUND</source>
-            <translation>Build Compound</translation>
-        </message>
-        <message>
-            <source>MEN_CLIP</source>
-            <translation>Clipping</translation>
-        </message>
-        <message>
-            <source>MEN_COLORS</source>
-            <translation>Colors / Size</translation>
-        </message>
-        <message>
-            <source>MEN_COMPUTE</source>
-            <translation>Compute</translation>
-        </message>
-        <message>
-            <source>MEN_PRECOMPUTE</source>
-            <translation>Preview</translation>
-        </message>
-        <message>
-            <source>MEN_CONNECTION</source>
-            <translation>Borders at Multi-Connection</translation>
-        </message>
-        <message>
-            <source>MEN_CONNECTION_2D</source>
-            <translation>Borders at Multi-Connection 2D</translation>
-        </message>
-        <message>
-            <source>MEN_CONSTRUCT_GROUP</source>
-            <translation>Construct Group</translation>
-        </message>
-        <message>
-            <source>MEN_CONV_TO_QUAD</source>
-            <translation>Convert to/from quadratic</translation>
-        </message>
-        <message>
-            <source>MEN_CREATE_GROUP</source>
-            <translation>Create Group</translation>
-        </message>
-        <message>
-            <source>MEN_CREATE_GEO_GROUP</source>
-            <translation>Create Groups from Geometry</translation>
-        </message>
-        <message>
-            <source>MEN_CREATE_MESH</source>
-            <translation>Create Mesh</translation>
-        </message>
-        <message>
-            <source>MEN_CREATE_SUBMESH</source>
-            <translation>Create Sub-mesh</translation>
-        </message>
-        <message>
-            <source>MEN_CTRL</source>
-            <translation>Controls</translation>
-        </message>
-        <message>
-            <source>MEN_CUT</source>
-            <translation>Cutting of Quadrangles</translation>
-        </message>
-        <message>
-            <source>MEN_CUT_GROUP</source>
-            <translation>Cut Groups</translation>
-        </message>
-        <message>
-            <source>MEN_DAT</source>
-            <translation>DAT File</translation>
-        </message>
-        <message>
-            <source>MEN_DELETE</source>
-            <translation>Delete</translation>
-        </message>
-        <message>
-            <source>MEN_DEL_GROUP</source>
-            <translation>Delete Groups</translation>
-        </message>
-        <message>
-            <source>MEN_FACE_ORIENTATION</source>
-            <translation>Orientation of Faces</translation>
-        </message>
-        <message>
-            <source>MEN_DISABLE_AUTO_COLOR</source>
-            <translation>Disable Auto Color</translation>
-        </message>
-        <message>
-            <source>MEN_DISPLAY_ONLY</source>
-            <translation>Show Only</translation>
-        </message>
-        <message>
-            <source>MEN_DISPMODE</source>
-            <translation>Display Mode</translation>
-        </message>
-        <message>
-            <source>MEN_DISP_ENT</source>
-            <translation>Display Entity</translation>
-        </message>
-        <message>
-            <source>MEN_EDGE</source>
-            <translation>Edge</translation>
-        </message>
-        <message>
-            <source>MEN_EDGES</source>
-            <translation>Edges</translation>
-        </message>
-        <message>
-            <source>MEN_EDIT</source>
-            <translation>Edit</translation>
-        </message>
-        <message>
-            <source>MEN_EDIT_GROUP</source>
-            <translation>Edit Group</translation>
-        </message>
-        <message>
-            <source>MEN_EDIT_GEOMGROUP_AS_GROUP</source>
-            <translation>Edit Group as Standalone</translation>
-        </message>
-        <message>
-            <source>MEN_EDIT_HYPO</source>
-            <translation>Edit Hypothesis</translation>
-        </message>
-        <message>
-            <source>MEN_EDIT_MESHSUBMESH</source>
-            <translation>Edit Mesh/Sub-mesh</translation>
-        </message>
-        <message>
-            <source>MEN_EXPORT</source>
-            <translation>Export</translation>
-        </message>
-        <message>
-            <source>MEN_EXPORT_DAT</source>
-            <translation>Export to DAT File</translation>
-        </message>
-        <message>
-            <source>MEN_EXPORT_MED</source>
-            <translation>Export to MED File</translation>
-        </message>
-        <message>
-            <source>MEN_EXPORT_STL</source>
-            <translation>Export to STL File</translation>
-        </message>
-        <message>
-            <source>MEN_EXPORT_UNV</source>
-            <translation>Export to UNV File</translation>
-        </message>
-        <message>
-            <source>MEN_EXTRUSION</source>
-            <translation>Extrusion</translation>
-        </message>
-        <message>
-            <source>MEN_EXTRUSION_ALONG</source>
-            <translation>Extrusion Along a Path</translation>
-        </message>
-        <message>
-            <source>MEN_FACES</source>
-            <translation>Faces</translation>
-        </message>
-        <message>
-            <source>MEN_FILE</source>
-            <translation>File</translation>
-        </message>
-        <message>
-            <source>MEN_FREE_BORDER</source>
-            <translation>Free Borders</translation>
-        </message>
-        <message>
-            <source>MEN_FREE_EDGE</source>
-            <translation>Free Edges</translation>
-        </message>
-       <message>
-            <source>MEN_FREE_NODE</source>
-            <translation>Free Nodes</translation>
-        </message>
-        <message>
-            <source>MEN_FREE_FACES</source>
-            <translation>Free Faces</translation>
-        </message>
-        <message>
-            <source>MEN_GLOBAL_HYPO</source>
-            <translation>Global Hypothesis</translation>
-        </message>
-        <message>
-            <source>MEN_HEXA</source>
-            <translation>Hexahedron</translation>
-        </message>
-        <message>
-            <source>MEN_HIDE</source>
-            <translation>Hide</translation>
-        </message>
-        <message>
-            <source>MEN_HYPO</source>
-            <translation>Hypotheses</translation>
-        </message>
-        <message>
-            <source>MEN_IMPORT</source>
-            <translation>Import</translation>
-        </message>
-        <message>
-            <source>MEN_INT_GROUP</source>
-            <translation>Intersect Groups</translation>
-        </message>
-        <message>
-            <source>MEN_INV</source>
-            <translation>Diagonal Inversion</translation>
-        </message>
-        <message>
-            <source>MEN_LENGTH</source>
-            <translation>Length</translation>
-        </message>
-        <message>
-            <source>MEN_LENGTH_2D</source>
-            <translation>Length 2D</translation>
-        </message>
-        <message>
-            <source>MEN_MAP</source>
-            <translation>Pattern Mapping</translation>
-        </message>
-        <message>
-            <source>MEN_MED</source>
-            <translation>MED file</translation>
-        </message>
-        <message>
-            <source>MEN_MERGE</source>
-            <translation>Merge Nodes</translation>
-        </message>
-        <message>
-            <source>MEN_MERGE_ELEMENTS</source>
-            <translation>Merge Elements</translation>
-        </message>
-        <message>
-            <source>MEN_MESH</source>
-            <translation>Mesh</translation>
-        </message>
-        <message>
-            <source>MEN_MESH_THROU_POINT</source>
-            <translation>Mesh to Pass Through a Point</translation>
-        </message>
-        <message>
-            <source>MEN_MIN_ANG</source>
-            <translation>Minimum Angle</translation>
-        </message>
-        <message>
-            <source>MEN_MODIFY</source>
-            <translation>Modification</translation>
-        </message>
-        <message>
-            <source>MEN_MOVE</source>
-            <translation>Move Node</translation>
-        </message>
-        <message>
-            <source>MEN_NODE</source>
-            <translation>Node</translation>
-        </message>
-        <message>
-            <source>MEN_NODES</source>
-            <translation>Nodes</translation>
-        </message>
-        <message>
-            <source>MEN_NUM</source>
-            <translation>Numbering</translation>
-        </message>
-        <message>
-            <source>MEN_NUM_ELEMENTS</source>
-            <translation>Display Elements #</translation>
-        </message>
-        <message>
-            <source>MEN_NUM_NODES</source>
-            <translation>Display Nodes #</translation>
-        </message>
-        <message>
-            <source>MEN_ORIENT</source>
-            <translation>Orientation</translation>
-        </message>
-        <message>
-            <source>MEN_POLYGON</source>
-            <translation>Polygon</translation>
-        </message>
-        <message>
-            <source>MEN_POLYHEDRON</source>
-            <translation>Polyhedron</translation>
-        </message>
-        <message>
-            <source>MEN_PRECISION</source>
-            <translation>Precision</translation>
-        </message>
-        <message>
-            <source>MEN_PREF</source>
-            <translation>Preferences</translation>
-        </message>
-        <message>
-            <source>MEN_QUAD</source>
-            <translation>Quadrangle</translation>
-        </message>
-        <message>
-            <source>MEN_QUADRATIC_EDGE</source>
-            <translation>Quadratic Edge</translation>
-        </message>
-        <message>
-            <source>MEN_QUADRATIC_HEXAHEDRON</source>
-            <translation>Quadratic Hexahedron</translation>
-        </message>
-        <message>
-            <source>MEN_QUADRATIC_PENTAHEDRON</source>
-            <translation>Quadratic Pentahedron</translation>
-        </message>
-        <message>
-            <source>MEN_QUADRATIC_PYRAMID</source>
-            <translation>Quadratic Pyramid</translation>
-        </message>
-        <message>
-            <source>MEN_QUADRATIC_QUADRANGLE</source>
-            <translation>Quadratic Quadrangle</translation>
-        </message>
-        <message>
-            <source>MEN_QUADRATIC_TETRAHEDRON</source>
-            <translation>Quadratic Tetrahedron</translation>
-        </message>
-        <message>
-            <source>MEN_QUADRATIC_TRIANGLE</source>
-            <translation>Quadratic Triangle</translation>
-        </message>
-        <message>
-            <source>MEN_QUALITY</source>
-            <translation>Quality Controls</translation>
-        </message>
-        <message>
-            <source>MEN_REMOVE</source>
-            <translation>Remove</translation>
-        </message>
-        <message>
-            <source>MEN_REMOVE_ELEMENTS</source>
-            <translation>Elements</translation>
-        </message>
-        <message>
-            <source>MEN_REMOVE_NODES</source>
-            <translation>Nodes</translation>
-        </message>
-        <message>
-            <source>MEN_RENAME</source>
-            <translation>Rename</translation>
-        </message>
-        <message>
-            <source>MEN_RENUM</source>
-            <translation>Renumbering</translation>
-        </message>
-        <message>
-            <source>MEN_RENUM_ELEMENTS</source>
-            <translation>Elements</translation>
-        </message>
-        <message>
-            <source>MEN_RENUM_NODES</source>
-            <translation>Nodes</translation>
-        </message>
-        <message>
-            <source>MEN_RESET</source>
-            <translation>Reset</translation>
-        </message>
-        <message>
-            <source>MEN_REVOLUTION</source>
-            <translation>Revolution</translation>
-        </message>
-        <message>
-            <source>MEN_ROT</source>
-            <translation>Rotation</translation>
-        </message>
-        <message>
-            <source>MEN_SCALAR_BAR</source>
-            <translation>Scalar Bar</translation>
-        </message>
-        <message>
-            <source>MEN_SCALAR_BAR_PROP</source>
-            <translation>Scalar Bar Properties</translation>
-        </message>
-        <message>
-            <source>MEN_SELECTION</source>
-            <translation>Selection</translation>
-        </message>
-        <message>
-            <source>MEN_SEL_FILTER_LIB</source>
-            <translation>Selection Filters Library</translation>
-        </message>
-        <message>
-            <source>MEN_SEW</source>
-            <translation>Sewing</translation>
-        </message>
-        <message>
-            <source>MEN_SHADE</source>
-            <translation>Shading</translation>
-        </message>
-        <message>
-            <source>MEN_SHOW</source>
-            <translation>Show</translation>
-        </message>
-        <message>
-            <source>MEN_SHRINK</source>
-            <translation>Shrink</translation>
-        </message>
-        <message>
-            <source>MEN_SKEW</source>
-            <translation>Skew</translation>
-        </message>
-        <message>
-            <source>MEN_SMOOTH</source>
-            <translation>Smoothing</translation>
-        </message>
-        <message>
-            <source>MEN_STD_INFO</source>
-            <translation>Standard Mesh Infos</translation>
-        </message>
-        <message>
-            <source>MEN_STL</source>
-            <translation>STL File</translation>
-        </message>
-        <message>
-            <source>MEN_SYM</source>
-            <translation>Symmetry</translation>
-        </message>
-        <message>
-            <source>MEN_TAPER</source>
-            <translation>Taper</translation>
-        </message>
-        <message>
-            <source>MEN_TETRA</source>
-            <translation>Tetrahedron</translation>
-        </message>
-        <message>
-            <source>MEN_TOOLS</source>
-            <translation>Tools</translation>
-        </message>
-        <message>
-            <source>MEN_TRANS</source>
-            <translation>Translation</translation>
-        </message>
-        <message>
-            <source>MEN_TRANSF</source>
-            <translation>Transformation</translation>
-        </message>
-        <message>
-            <source>MEN_TRANSP</source>
-            <translation>Transparency</translation>
-        </message>
-        <message>
-            <source>MEN_TRIANGLE</source>
-            <translation>Triangle</translation>
-        </message>
-        <message>
-            <source>MEN_UNASSIGN</source>
-            <translation>Unassign</translation>
-        </message>
-        <message>
-            <source>MEN_UNION</source>
-            <translation>Union of Triangles</translation>
-        </message>
-        <message>
-            <source>MEN_UNION2</source>
-            <translation>Union of Two Triangles</translation>
-        </message>
-        <message>
-            <source>MEN_UNV</source>
-            <translation>UNV File</translation>
-        </message>
-        <message>
-            <source>MEN_UN_GROUP</source>
-            <translation>Union Groups</translation>
-        </message>
-        <message>
-            <source>MEN_UNDERLYING_ELEMS</source>
-            <translation>Group of underlying entities</translation>
-        </message>
-        <message>
-            <source>MEN_UPDATE</source>
-            <translation>Update</translation>
-        </message>
-        <message>
-            <source>MEN_VIEW</source>
-            <translation>View</translation>
-        </message>
-        <message>
-            <source>MEN_VOLUMES</source>
-            <translation>Volumes</translation>
-        </message>
-        <message>
-            <source>MEN_VOLUME_3D</source>
-            <translation>Volume</translation>
-        </message>
-        <message>
-            <source>MEN_WARP</source>
-            <translation>Warping Angle</translation>
-        </message>
-        <message>
-            <source>MEN_WHAT_IS</source>
-            <translation>Mesh Element Info</translation>
-        </message>
-        <message>
-            <source>MEN_WIRE</source>
-            <translation>Wireframe</translation>
-        </message>
-        <message>
-            <source>MESHERS_FILE_CANT_OPEN</source>
-            <translation>Can not open resource file</translation>
-        </message>
-        <message>
-            <source>MESHERS_FILE_CHECK_VARIABLE</source>
-            <translation>Check environment variable SMESH_MeshersList</translation>
-        </message>
-        <message>
-            <source>MESHERS_FILE_NO_VARIABLE</source>
-            <translation>Environment variable SMESH_MeshersList is not defined</translation>
-        </message>
-        <message>
-            <source>MESH_IS_NOT_SELECTED</source>
-            <translation>There is no selected mesh
+<TS version="2.0" language="en_US">
+<context>
+    <name>@default</name>
+    <message>
+        <source>SMESH_EXPORT_MESH</source>
+        <translation>Export mesh</translation>
+    </message>
+    <message>
+        <source>MED_FILES_FILTER</source>
+        <translation>MED files</translation>
+    </message>
+    <message>
+        <source>IDEAS_FILES_FILTER</source>
+        <translation>IDEAS files</translation>
+    </message>
+    <message>
+        <source>DAT_FILES_FILTER</source>
+        <translation>DAT files</translation>
+    </message>
+    <message>
+        <source>TEXT_FILES_FILTER</source>
+        <translation>TXT files</translation>
+    </message>
+    <message>
+        <source>MED_VX_FILES_FILTER</source>
+        <translation>MED %1 files</translation>
+    </message>
+    <message>
+        <source>STL_ASCII_FILES_FILTER</source>
+        <translation>STL ASCII files</translation>
+    </message>
+    <message>
+        <source>CGNS_FILES_FILTER</source>
+        <translation>CGNS files</translation>
+    </message>
+    <message>
+        <source>STL_BIN_FILES_FILTER</source>
+        <translation>STL binary files</translation>
+    </message>
+    <message>
+        <source>ALL_FILES_FILTER</source>
+        <translation>All files</translation>
+    </message>
+    <message>
+        <source>SMESH_AND</source>
+        <translation>and</translation>
+    </message>
+    <message>
+        <source>AREA_ELEMENTS</source>
+        <translation>Area</translation>
+    </message>
+    <message>
+        <source>ASPECTRATIO_3D_ELEMENTS</source>
+        <translation>Aspect Ratio 3D</translation>
+    </message>
+    <message>
+        <source>ASPECTRATIO_ELEMENTS</source>
+        <translation>Aspect Ratio</translation>
+    </message>
+    <message>
+        <source>NODE_POSITION</source>
+        <translation>Position</translation>
+    </message>
+    <message>
+        <source>U_POSITION</source>
+        <translation>U</translation>
+    </message>
+    <message>
+        <source>V_POSITION</source>
+        <translation>V</translation>
+    </message>
+    <message>
+        <source>COL_ALGO_HEADER</source>
+        <translation>Algorithm</translation>
+    </message>
+    <message>
+        <source>COL_ERROR_HEADER</source>
+        <translation>Error</translation>
+    </message>
+    <message>
+        <source>COL_SHAPE_HEADER</source>
+        <translation>Sub-shape</translation>
+    </message>
+    <message>
+        <source>COMPERR_ALGO_FAILED</source>
+        <translation>Algorithm failed</translation>
+    </message>
+    <message>
+        <source>COMPERR_BAD_INPUT_MESH</source>
+        <translation>Invalid input mesh</translation>
+    </message>
+    <message>
+        <source>COMPERR_BAD_SHAPE</source>
+        <translation>Unexpected geometry</translation>
+    </message>
+    <message>
+        <source>COMPERR_EXCEPTION</source>
+        <translation>Unknown exception</translation>
+    </message>
+    <message>
+        <source>COMPERR_MEMORY_PB</source>
+        <translation>Memory allocation problem</translation>
+    </message>
+    <message>
+        <source>COMPERR_OCC_EXCEPTION</source>
+        <translation>OCC exception</translation>
+    </message>
+    <message>
+        <source>COMPERR_OK</source>
+        <translation>No errors</translation>
+    </message>
+    <message>
+        <source>COMPERR_SLM_EXCEPTION</source>
+        <translation>SALOME exception</translation>
+    </message>
+    <message>
+        <source>COMPERR_STD_EXCEPTION</source>
+        <translation>std::exception</translation>
+    </message>
+    <message>
+        <source>COMPERR_UNKNOWN</source>
+        <translation>Unknown error</translation>
+    </message>
+    <message>
+        <source>COMPERR_CANCELED</source>
+        <translation>Computation canceled</translation>
+    </message>
+    <message>
+        <source>SMESH_GEOM</source>
+        <translation>Geometry</translation>
+    </message>
+    <message>
+        <source>DIRECT_GEOM_SELECTION</source>
+        <translation>Direct geometry selection</translation>
+    </message>
+    <message>
+        <source>ELEMENT_ID</source>
+        <translation>Element ID</translation>
+    </message>
+    <message>
+        <source>FREE_BORDERS</source>
+        <translation>Free Borders</translation>
+    </message>
+    <message>
+        <source>GEOMETRY_NAME</source>
+        <translation>Geometry name</translation>
+    </message>
+    <message>
+        <source>GEOM_BY_MESH_ELEM_SELECTION</source>
+        <translation>Find geometry by mesh element selection</translation>
+    </message>
+    <message>
+        <source>GLOBAL_ALGO</source>
+        <translation>Global</translation>
+    </message>
+    <message>
+        <source>INF_SELECT_OBJECT</source>
+        <translation>Select an object</translation>
+    </message>
+    <message>
+        <source>LENGTH2D_EDGES</source>
+        <translation>Length 2D</translation>
+    </message>
+    <message>
+        <source>LENGTH_EDGES</source>
+        <translation>Length</translation>
+    </message>
+    <message>
+        <source>LOCAL_ALGO</source>
+        <translation>Local</translation>
+    </message>
+    <message>
+        <source>MAX_ELEMENT_LENGTH_2D</source>
+        <translation>Element Diameter 2D</translation>
+    </message>
+    <message>
+        <source>MAX_ELEMENT_LENGTH_3D</source>
+        <translation>Element Diameter 3D</translation>
+    </message>
+    <message>
+        <source>MEN_ADD</source>
+        <translation>Add</translation>
+    </message>
+    <message>
+        <source>MEN_ADV_INFO</source>
+        <translation>Mesh Information</translation>
+    </message>
+    <message>
+        <source>MEN_ALL</source>
+        <translation>All</translation>
+    </message>
+    <message>
+        <source>MEN_AREA</source>
+        <translation>Area</translation>
+    </message>
+    <message>
+        <source>MEN_ASPECT</source>
+        <translation>Aspect Ratio</translation>
+    </message>
+    <message>
+        <source>MEN_ASPECT_3D</source>
+        <translation>Aspect Ratio 3D</translation>
+    </message>
+    <message>
+        <source>MEN_AUTO_COLOR</source>
+        <translation>Auto Color</translation>
+    </message>
+    <message>
+        <source>MEN_AUTO_UPD</source>
+        <translation>Automatic Update</translation>
+    </message>
+    <message>
+        <source>MEN_BUILD_COMPOUND</source>
+        <translation>Build Compound</translation>
+    </message>
+    <message>
+        <source>MEN_COPY_MESH</source>
+        <translation>Copy Mesh</translation>
+    </message>
+    <message>
+        <source>MEN_CLIP</source>
+        <translation>Clipping</translation>
+    </message>
+    <message>
+        <source>MEN_COLORS</source>
+        <translation>Properties</translation>
+    </message>
+    <message>
+        <source>MEN_COMPUTE</source>
+        <translation>Compute</translation>
+    </message>
+    <message>
+        <source>MEN_PRECOMPUTE</source>
+        <translation>Preview</translation>
+    </message>
+    <message>
+        <source>MEN_EVALUATE</source>
+        <translation>Evaluate</translation>
+    </message>
+    <message>
+        <source>MEN_CONNECTION</source>
+        <translation>Borders at Multi-Connection</translation>
+    </message>
+    <message>
+        <source>MEN_CONNECTION_2D</source>
+        <translation>Borders at Multi-Connection 2D</translation>
+    </message>
+    <message>
+        <source>MEN_CONSTRUCT_GROUP</source>
+        <translation>Construct Group</translation>
+    </message>
+    <message>
+        <source>MEN_CONV_TO_QUAD</source>
+        <translation>Convert to/from quadratic</translation>
+    </message>
+    <message>
+        <source>MEN_2D_FROM_3D</source>
+        <translation>Create boundary elements</translation>
+    </message>
+    <message>
+        <source>MEN_MESH_ORDER</source>
+        <translation>Change submesh priority</translation>
+    </message>
+    <message>
+        <source>MEN_CREATE_GROUP</source>
+        <translation>Create Group</translation>
+    </message>
+    <message>
+        <source>MEN_CREATE_GEO_GROUP</source>
+        <translation>Create Groups from Geometry</translation>
+    </message>
+    <message>
+        <source>MEN_CREATE_MESH</source>
+        <translation>Create Mesh</translation>
+    </message>
+    <message>
+        <source>MEN_CREATE_SUBMESH</source>
+        <translation>Create Sub-mesh</translation>
+    </message>
+    <message>
+        <source>MEN_CTRL</source>
+        <translation>Controls</translation>
+    </message>
+    <message>
+        <source>MEN_NODE_CTRL</source>
+        <translation>Node Controls</translation>
+    </message>
+    <message>
+        <source>MEN_EDGE_CTRL</source>
+        <translation>Edge Controls</translation>
+    </message>
+    <message>
+        <source>MEN_FACE_CTRL</source>
+        <translation>Face Controls</translation>
+    </message>
+    <message>
+        <source>MEN_VOLUME_CTRL</source>
+        <translation>Volume Controls</translation>
+    </message>
+    <message>
+        <source>MEN_CUT</source>
+        <translation>Cutting of Quadrangles</translation>
+    </message>
+    <message>
+        <source>MEN_CUT_GROUP</source>
+        <translation>Cut Groups</translation>
+    </message>
+    <message>
+        <source>MEN_IMPORT_DAT</source>
+        <translation>DAT File</translation>
+    </message>
+    <message>
+        <source>MEN_DAT</source>
+        <translation>DAT File</translation>
+    </message>
+    <message>
+        <source>MEN_DELETE</source>
+        <translation>Delete</translation>
+    </message>
+    <message>
+        <source>MEN_DEL_GROUP</source>
+        <translation>Delete Groups with Contents</translation>
+    </message>
+    <message>
+        <source>MEN_FACE_ORIENTATION</source>
+        <translation>Orientation of Faces</translation>
+    </message>
+    <message>
+        <source>MEN_DISABLE_AUTO_COLOR</source>
+        <translation>Disable Auto Color</translation>
+    </message>
+    <message>
+        <source>MEN_DISPLAY_ONLY</source>
+        <translation>Show Only</translation>
+    </message>
+    <message>
+        <source>MEN_DISPMODE</source>
+        <translation>Display Mode</translation>
+    </message>
+    <message>
+        <source>MEN_DISP_ENT</source>
+        <translation>Display Entity</translation>
+    </message>
+    <message>
+        <source>MEN_ELEM0D</source>
+        <translation>0D Element</translation>
+    </message>
+    <message>
+        <source>MEN_ELEMS0D</source>
+        <translation>0D Elements</translation>
+    </message>
+    <message>
+        <source>MEN_BALL</source>
+        <translation>Ball</translation>
+    </message>
+    <message>
+        <source>MEN_BALLS</source>
+        <translation>Balls</translation>
+    </message>
+    <message>
+        <source>MEN_EDGE</source>
+        <translation>Edge</translation>
+    </message>
+    <message>
+        <source>MEN_EDGES</source>
+        <translation>Edges</translation>
+    </message>
+    <message>
+        <source>MEN_EDIT</source>
+        <translation>Edit</translation>
+    </message>
+    <message>
+        <source>MEN_EDIT_GROUP</source>
+        <translation>Edit Group</translation>
+    </message>
+    <message>
+        <source>MEN_EDIT_GEOMGROUP_AS_GROUP</source>
+        <translation>Edit Group as Standalone</translation>
+    </message>
+    <message>
+        <source>MEN_EDIT_HYPO</source>
+        <translation>Edit Hypothesis</translation>
+    </message>
+    <message>
+        <source>MEN_EDIT_MESHSUBMESH</source>
+        <translation>Edit Mesh/Sub-mesh</translation>
+    </message>
+    <message>
+        <source>MEN_EXPORT</source>
+        <translation>Export</translation>
+    </message>
+    <message>
+        <source>MEN_EXPORT_DAT</source>
+        <translation>Export to DAT File</translation>
+    </message>
+    <message>
+        <source>MEN_EXPORT_MED</source>
+        <translation>Export to MED File</translation>
+    </message>
+    <message>
+        <source>MEN_EXPORT_CGNS</source>
+        <translation>Export to CGNS File</translation>
+    </message>
+    <message>
+        <source>MEN_EXPORT_SAUV</source>
+        <translation>Export to SAUV file</translation>
+    </message>
+    <message>
+        <source>MEN_EXPORT_STL</source>
+        <translation>Export to STL File</translation>
+    </message>
+    <message>
+        <source>MEN_EXPORT_UNV</source>
+        <translation>Export to UNV File</translation>
+    </message>
+    <message>
+        <source>MEN_EXTRUSION</source>
+        <translation>Extrusion</translation>
+    </message>
+    <message>
+        <source>MEN_EXTRUSION_ALONG</source>
+        <translation>Extrusion Along a Path</translation>
+    </message>
+    <message>
+        <source>MEN_FACES</source>
+        <translation>Faces</translation>
+    </message>
+    <message>
+        <source>MEN_FILE</source>
+        <translation>File</translation>
+    </message>
+    <message>
+        <source>MEN_FIND_ELEM</source>
+        <translation>Find Element by Point</translation>
+    </message>
+    <message>
+        <source>TOP_REORIENT_2D</source>
+        <translation>Reorient faces by vector</translation>
+    </message>
+    <message>
+        <source>MEN_REORIENT_2D</source>
+        <translation>Reorient faces by vector</translation>
+    </message>
+    <message>
+        <source>STB_REORIENT_2D</source>
+        <translation>Reorient faces by vector</translation>
+    </message>
+    <message>
+        <source>TOP_FIND_ELEM</source>
+        <translation>Find Element by Point</translation>
+    </message>
+    <message>
+        <source>STB_FIND_ELEM</source>
+        <translation>Find Element by Point</translation>
+    </message>
+    <message>
+        <source>EQUAL_NODE</source>
+        <translation>Double nodes</translation>
+    </message>
+    <message>
+        <source>MEN_EQUAL_NODE</source>
+        <translation>Double nodes</translation>
+    </message>
+    <message>
+        <source>STB_EQUAL_NODE</source>
+        <translation>Double nodes</translation>
+    </message>
+    <message>
+        <source>TOP_EQUAL_NODE</source>
+        <translation>Double nodes</translation>
+    </message>
+    <message>
+        <source>EQUAL_EDGE</source>
+        <translation>Double edges</translation>
+    </message>
+    <message>
+        <source>MEN_EQUAL_EDGE</source>
+        <translation>Double edges</translation>
+    </message>
+    <message>
+        <source>STB_EQUAL_EDGE</source>
+        <translation>Double edges</translation>
+    </message>
+    <message>
+        <source>TOP_EQUAL_EDGE</source>
+        <translation>Double edges</translation>
+    </message>
+    <message>
+        <source>EQUAL_FACE</source>
+        <translation>Double faces</translation>
+    </message>
+    <message>
+        <source>MEN_EQUAL_FACE</source>
+        <translation>Double faces</translation>
+    </message>
+    <message>
+        <source>STB_EQUAL_FACE</source>
+        <translation>Double faces</translation>
+    </message>
+    <message>
+        <source>TOP_EQUAL_FACE</source>
+        <translation>Double faces</translation>
+    </message>
+    <message>
+        <source>EQUAL_VOLUME</source>
+        <translation>Double volumes</translation>
+    </message>
+    <message>
+        <source>MEN_EQUAL_VOLUME</source>
+        <translation>Double volumes</translation>
+    </message>
+    <message>
+        <source>STB_EQUAL_VOLUME</source>
+        <translation>Double volumes</translation>
+    </message>
+    <message>
+        <source>TOP_EQUAL_VOLUME</source>
+        <translation>Double volumes</translation>
+    </message>
+    <message>
+        <source>MEN_BARE_BORDER_VOLUME</source>
+        <translation>Volumes with bare border</translation>
+    </message>
+    <message>
+        <source>MEN_BARE_BORDER_FACE</source>
+        <translation>Faces with bare border</translation>
+    </message>
+    <message>
+        <source>MEN_OVER_CONSTRAINED_VOLUME</source>
+        <translation>Over-constrained volumes</translation>
+    </message>
+    <message>
+        <source>MEN_OVER_CONSTRAINED_FACE</source>
+        <translation>Over-constrained faces</translation>
+    </message>
+    <message>
+        <source>MEN_FREE_BORDER</source>
+        <translation>Free Borders</translation>
+    </message>
+    <message>
+        <source>MEN_FREE_EDGE</source>
+        <translation>Free Edges</translation>
+    </message>
+    <message>
+        <source>MEN_FREE_NODE</source>
+        <translation>Free Nodes</translation>
+    </message>
+    <message>
+        <source>MEN_FREE_FACES</source>
+        <translation>Free Faces</translation>
+    </message>
+    <message>
+        <source>MEN_GLOBAL_HYPO</source>
+        <translation>Global Hypothesis</translation>
+    </message>
+    <message>
+        <source>MEN_HEXA</source>
+        <translation>Hexahedron</translation>
+    </message>
+    <message>
+        <source>MEN_HIDE</source>
+        <translation>Hide</translation>
+    </message>
+    <message>
+        <source>MEN_HYPO</source>
+        <translation>Hypotheses</translation>
+    </message>
+    <message>
+        <source>MEN_IMPORT</source>
+        <translation>Import</translation>
+    </message>
+    <message>
+        <source>MEN_INT_GROUP</source>
+        <translation>Intersect Groups</translation>
+    </message>
+    <message>
+        <source>MEN_INV</source>
+        <translation>Diagonal Inversion</translation>
+    </message>
+    <message>
+        <source>MEN_LENGTH</source>
+        <translation>Length</translation>
+    </message>
+    <message>
+        <source>MEN_LENGTH_2D</source>
+        <translation>Length 2D</translation>
+    </message>
+    <message>
+        <source>MEN_MAP</source>
+        <translation>Pattern Mapping</translation>
+    </message>
+    <message>
+        <source>MEN_MAX_ELEMENT_LENGTH_2D</source>
+        <translation>Element Diameter 2D</translation>
+    </message>
+    <message>
+        <source>MEN_MAX_ELEMENT_LENGTH_3D</source>
+        <translation>Element Diameter 3D</translation>
+    </message>
+    <message>
+        <source>MEN_IMPORT_MED</source>
+        <translation>MED file</translation>
+    </message>
+    <message>
+        <source>MEN_MED</source>
+        <translation>MED file</translation>
+    </message>
+    <message>
+        <source>MEN_IMPORT_CGNS</source>
+        <translation>CGNS file</translation>
+    </message>
+    <message>
+        <source>MEN_CGNS</source>
+        <translation>CGNS file</translation>
+    </message>
+    <message>
+        <source>MEN_IMPORT_SAUV</source>
+        <translation>SAUV file</translation>
+    </message>
+    <message>
+        <source>MEN_SAUV</source>
+        <translation>SAUV file</translation>
+    </message>
+    <message>
+        <source>MEN_MERGE</source>
+        <translation>Merge Nodes</translation>
+    </message>
+    <message>
+        <source>MEN_MERGE_ELEMENTS</source>
+        <translation>Merge Elements</translation>
+    </message>
+    <message>
+        <source>MEN_MESH</source>
+        <translation>Mesh</translation>
+    </message>
+    <message>
+        <source>MEN_MESH_THROU_POINT</source>
+        <translation>Move Node</translation>
+    </message>
+    <message>
+        <source>MEN_MIN_ANG</source>
+        <translation>Minimum Angle</translation>
+    </message>
+    <message>
+        <source>MEN_MODIFY</source>
+        <translation>Modification</translation>
+    </message>
+    <message>
+        <source>MEN_MEASURE</source>
+        <translation>Measurements</translation>
+    </message>
+    <message>
+        <source>MEN_MEASURE_MIN_DIST</source>
+        <translation>Minimum Distance</translation>
+    </message>
+    <message>
+        <source>STB_MEASURE_MIN_DIST</source>
+        <translation>Calculate minimum distance between two objects</translation>
+    </message>
+    <message>
+        <source>TOP_MEASURE_MIN_DIST</source>
+        <translation>Minimum distance</translation>
+    </message>
+    <message>
+        <source>MEN_MEASURE_BND_BOX</source>
+        <translation>Bounding Box</translation>
+    </message>
+    <message>
+        <source>STB_MEASURE_BND_BOX</source>
+        <translation>Calculate bounding box for the selected object(s)</translation>
+    </message>
+    <message>
+        <source>TOP_MEASURE_BND_BOX</source>
+        <translation>Bounding box</translation>
+    </message>
+    <message>
+        <source>MEN_MOVE</source>
+        <translation>Move Node</translation>
+    </message>
+    <message>
+        <source>MEN_NODE</source>
+        <translation>Node</translation>
+    </message>
+    <message>
+        <source>MEN_NODES</source>
+        <translation>Nodes</translation>
+    </message>
+    <message>
+        <source>MEN_NUM</source>
+        <translation>Numbering</translation>
+    </message>
+    <message>
+        <source>MEN_NUM_ELEMENTS</source>
+        <translation>Display Elements #</translation>
+    </message>
+    <message>
+        <source>MEN_NUM_NODES</source>
+        <translation>Display Nodes #</translation>
+    </message>
+    <message>
+        <source>MEN_ORIENT</source>
+        <translation>Orientation</translation>
+    </message>
+    <message>
+        <source>MEN_POLYGON</source>
+        <translation>Polygon</translation>
+    </message>
+    <message>
+        <source>MEN_POLYHEDRON</source>
+        <translation>Polyhedron</translation>
+    </message>
+    <message>
+        <source>MEN_PRECISION</source>
+        <translation>Precision</translation>
+    </message>
+    <message>
+        <source>MEN_PREF</source>
+        <translation>Preferences</translation>
+    </message>
+    <message>
+        <source>MEN_QUAD</source>
+        <translation>Quadrangle</translation>
+    </message>
+    <message>
+        <source>MEN_QUADRATIC_EDGE</source>
+        <translation>Quadratic Edge</translation>
+    </message>
+    <message>
+        <source>MEN_QUADRATIC_HEXAHEDRON</source>
+        <translation>Quadratic Hexahedron</translation>
+    </message>
+    <message>
+        <source>MEN_QUADRATIC_PENTAHEDRON</source>
+        <translation>Quadratic Pentahedron</translation>
+    </message>
+    <message>
+        <source>MEN_QUADRATIC_PYRAMID</source>
+        <translation>Quadratic Pyramid</translation>
+    </message>
+    <message>
+        <source>MEN_QUADRATIC_QUADRANGLE</source>
+        <translation>Quadratic Quadrangle</translation>
+    </message>
+    <message>
+        <source>MEN_QUADRATIC_TETRAHEDRON</source>
+        <translation>Quadratic Tetrahedron</translation>
+    </message>
+    <message>
+        <source>MEN_QUADRATIC_TRIANGLE</source>
+        <translation>Quadratic Triangle</translation>
+    </message>
+    <message>
+        <source>MEN_QUALITY</source>
+        <translation>Quality Controls</translation>
+    </message>
+    <message>
+        <source>MEN_REMOVE</source>
+        <translation>Remove</translation>
+    </message>
+    <message>
+        <source>MEN_REMOVE_ELEMENTS</source>
+        <translation>Elements</translation>
+    </message>
+    <message>
+        <source>MEN_REMOVE_NODES</source>
+        <translation>Nodes</translation>
+    </message>
+    <message>
+        <source>MEN_REMOVE_ORPHAN_NODES</source>
+        <translation>Orphan Nodes</translation>
+    </message>
+    <message>
+        <source>MEN_RENAME</source>
+        <translation>Rename</translation>
+    </message>
+    <message>
+        <source>MEN_RENUM</source>
+        <translation>Renumbering</translation>
+    </message>
+    <message>
+        <source>MEN_RENUM_ELEMENTS</source>
+        <translation>Elements</translation>
+    </message>
+    <message>
+        <source>MEN_RENUM_NODES</source>
+        <translation>Nodes</translation>
+    </message>
+    <message>
+        <source>MEN_RESET</source>
+        <translation>Reset</translation>
+    </message>
+    <message>
+        <source>MEN_DISTRIBUTION_CTRL</source>
+        <translation>Distribution</translation>
+    </message>
+    <message>
+        <source>MEN_SAVE_DISTRIBUTION</source>
+        <translation>Export ...</translation>
+    </message>
+    <message>
+        <source>MEN_SHOW_DISTRIBUTION</source>
+        <translation>Show</translation>
+    </message>
+    <message>
+        <source>MEN_PLOT_DISTRIBUTION</source>
+        <translation>Plot</translation>
+    </message>
+    <message>
+        <source>DISTRIBUTION_NB_ENT</source>
+        <translation>Number of entities</translation>
+    </message>
+    <message>
+        <source>MEN_REVOLUTION</source>
+        <translation>Revolution</translation>
+    </message>
+    <message>
+        <source>MEN_ROT</source>
+        <translation>Rotation</translation>
+    </message>
+    <message>
+        <source>MEN_SCALAR_BAR</source>
+        <translation>Scalar Bar</translation>
+    </message>
+    <message>
+        <source>MEN_SCALAR_BAR_PROP</source>
+        <translation>Scalar Bar Properties</translation>
+    </message>
+    <message>
+        <source>MEN_SELECTION</source>
+        <translation>Selection</translation>
+    </message>
+    <message>
+        <source>MEN_SEL_FILTER_LIB</source>
+        <translation>Selection Filters Library</translation>
+    </message>
+    <message>
+        <source>MEN_SEW</source>
+        <translation>Sewing</translation>
+    </message>
+    <message>
+        <source>MEN_SHADE</source>
+        <translation>Shading</translation>
+    </message>
+    <message>
+        <source>MEN_QUADRATIC_REPRESENT</source>
+        <translation>2D Quadratic</translation>
+    </message>
+    <message>
+        <source>MEN_LINE_REPRESENTATION</source>
+        <translation>Lines</translation>
+    </message>
+    <message>
+        <source>MEN_ARC_REPRESENTATION</source>
+        <translation>Arcs</translation>
+    </message>
+    <message>
+        <source>MEN_SHOW</source>
+        <translation>Show</translation>
+    </message>
+    <message>
+        <source>MEN_SHRINK</source>
+        <translation>Shrink</translation>
+    </message>
+    <message>
+        <source>MEN_SKEW</source>
+        <translation>Skew</translation>
+    </message>
+    <message>
+        <source>MEN_SMOOTH</source>
+        <translation>Smoothing</translation>
+    </message>
+    <message>
+        <source>MEN_STD_INFO</source>
+        <translation>Standard Mesh Infos</translation>
+    </message>
+    <message>
+        <source>MEN_IMPORT_STL</source>
+        <translation>STL File</translation>
+    </message>
+    <message>
+        <source>MEN_STL</source>
+        <translation>STL File</translation>
+    </message>
+    <message>
+        <source>MEN_SYM</source>
+        <translation>Symmetry</translation>
+    </message>
+    <message>
+        <source>MEN_TAPER</source>
+        <translation>Taper</translation>
+    </message>
+    <message>
+        <source>MEN_TETRA</source>
+        <translation>Tetrahedron</translation>
+    </message>
+    <message>
+        <source>MEN_TOOLS</source>
+        <translation>Tools</translation>
+    </message>
+    <message>
+        <source>MEN_TRANS</source>
+        <translation>Translation</translation>
+    </message>
+    <message>
+        <source>MEN_SCALE</source>
+        <translation>Scale Transform</translation>
+    </message>
+    <message>
+        <source>MEN_DUPLICATE_NODES</source>
+        <translation>Duplicate Nodes</translation>
+    </message>
+    <message>
+        <source>MEN_TRANSF</source>
+        <translation>Transformation</translation>
+    </message>
+    <message>
+        <source>MEN_TRANSP</source>
+        <translation>Transparency</translation>
+    </message>
+    <message>
+        <source>MEN_TRIANGLE</source>
+        <translation>Triangle</translation>
+    </message>
+    <message>
+        <source>MEN_UNASSIGN</source>
+        <translation>Unassign</translation>
+    </message>
+    <message>
+        <source>MEN_UNION</source>
+        <translation>Union of Triangles</translation>
+    </message>
+    <message>
+        <source>MEN_UNION2</source>
+        <translation>Union of Two Triangles</translation>
+    </message>
+    <message>
+        <source>MEN_IMPORT_UNV</source>
+        <translation>UNV File</translation>
+    </message>
+    <message>
+        <source>MEN_UNV</source>
+        <translation>UNV File</translation>
+    </message>
+    <message>
+        <source>MEN_UN_GROUP</source>
+        <translation>Union Groups</translation>
+    </message>
+    <message>
+        <source>MEN_UNDERLYING_ELEMS</source>
+        <translation>Group of underlying entities</translation>
+    </message>
+    <message>
+        <source>MEN_UPDATE</source>
+        <translation>Update</translation>
+    </message>
+    <message>
+        <source>MEN_VIEW</source>
+        <translation>View</translation>
+    </message>
+    <message>
+        <source>MEN_VOLUMES</source>
+        <translation>Volumes</translation>
+    </message>
+    <message>
+        <source>MEN_VOLUME_3D</source>
+        <translation>Volume</translation>
+    </message>
+    <message>
+        <source>MEN_WARP</source>
+        <translation>Warping Angle</translation>
+    </message>
+    <message>
+        <source>MEN_WHAT_IS</source>
+        <translation>Mesh Element Information</translation>
+    </message>
+    <message>
+        <source>MEN_WIRE</source>
+        <translation>Wireframe</translation>
+    </message>
+    <message>
+        <source>MEN_SPLIT_TO_TETRA</source>
+        <translation>Split into Tetrahedra</translation>
+    </message>
+    <message>
+        <source>TOP_SPLIT_TO_TETRA</source>
+        <translation>Split into Tetrahedra</translation>
+    </message>
+    <message>
+        <source>STB_SPLIT_TO_TETRA</source>
+        <translation>Split into Tetrahedra</translation>
+    </message>
+    <message>
+        <source>MESHERS_FILE_CANT_OPEN</source>
+        <translation>Can not open resource file</translation>
+    </message>
+    <message>
+        <source>MESHERS_FILE_CHECK_VARIABLE</source>
+        <translation>Check environment variable SMESH_MeshersList</translation>
+    </message>
+    <message>
+        <source>MESHERS_FILE_NO_VARIABLE</source>
+        <translation>Environment variable SMESH_MeshersList is not defined</translation>
+    </message>
+    <message>
+        <source>MESH_IS_NOT_SELECTED</source>
+        <translation>There is no selected mesh
 Please, select a mesh and try again</translation>
-        </message>
-        <message>
-            <source>MESH_NODE</source>
-            <translation>Node</translation>
-        </message>
-        <message>
-            <source>MESH_NODE_TITLE</source>
-            <translation>Add Node</translation>
-        </message>
-        <message>
-            <source>MINIMUMANGLE_ELEMENTS</source>
-            <translation>Minimum Angle</translation>
-        </message>
-        <message>
-            <source>MULTI2D_BORDERS</source>
-            <translation>Borders at Multi-Connections 2D</translation>
-        </message>
-        <message>
-            <source>MULTI_BORDERS</source>
-            <translation>Borders at Multi-Connections</translation>
-        </message>
-        <message>
-            <source>NODE_ID</source>
-            <translation>Node ID</translation>
-        </message>
-        <message>
-            <source>NON_SMESH_OBJECTS_SELECTED</source>
-            <translation>There are objects selected which do not belong to %1 component.</translation>
-        </message>
-        <message>
-            <source>PREVIEW</source>
-            <translation>Preview</translation>
-        </message>
-        <message>
-            <source>SKEW_ELEMENTS</source>
-            <translation>Skew</translation>
-        </message>
-        <message>
-            <source>SMESHGUI_INVALID_PARAMETERS</source>
-            <translation>Parameters are not correctly specified
+    </message>
+    <message>
+        <source>MESH_NODE</source>
+        <translation>Node</translation>
+    </message>
+    <message>
+        <source>MESH_NODE_TITLE</source>
+        <translation>Add Node</translation>
+    </message>
+    <message>
+        <source>MINIMUMANGLE_ELEMENTS</source>
+        <translation>Minimum Angle</translation>
+    </message>
+    <message>
+        <source>MULTI2D_BORDERS</source>
+        <translation>Borders at Multi-Connections 2D</translation>
+    </message>
+    <message>
+        <source>MULTI_BORDERS</source>
+        <translation>Borders at Multi-Connections</translation>
+    </message>
+    <message>
+        <source>GROUP_NAME_IS_EMPTY</source>
+        <translation>Name of group is not specified.
+Please enter a name of new group to be created or choose an existing one.</translation>
+    </message>
+    <message>
+        <source>MESH_STANDALONE_GRP_CHOSEN</source>
+        <translation>Group on geometry is chosen: %1.
+Do you want to convert it to the standalone group?</translation>
+    </message>
+    <message>
+        <source>NODE_ID</source>
+        <translation>Node ID</translation>
+    </message>
+    <message>
+        <source>NON_SMESH_OBJECTS_SELECTED</source>
+        <translation>There are objects selected which do not belong to %1 component.</translation>
+    </message>
+    <message>
+        <source>PREVIEW</source>
+        <translation>Preview</translation>
+    </message>
+    <message>
+        <source>SKEW_ELEMENTS</source>
+        <translation>Skew</translation>
+    </message>
+    <message>
+        <source>SMESHGUI_INVALID_PARAMETERS</source>
+        <translation>Parameters are not correctly specified
 Please enter correct values and try again</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_ALGORITHM</source>
-            <translation>Algorithms</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_ALGORITHM_TITLE</source>
-            <translation>Algorithms Assignation</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_EDGE</source>
-            <translation>Add Edge</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_EDGE_TITLE</source>
-            <translation>Add Edge</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_HEXAS</source>
-            <translation>Add Hexahedron</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_HEXAS_TITLE</source>
-            <translation>Add Hexahedron</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_HYPOTHESIS</source>
-            <translation>Hypothesis</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_HYPOTHESIS_TITLE</source>
-            <translation>Hypothesis Assignation</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_HYP_WRN</source>
-            <translation>"%1" assigned but:
+    </message>
+    <message>
+        <source>SMESH_ADD_ALGORITHM</source>
+        <translation>Algorithms</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_ALGORITHM_TITLE</source>
+        <translation>Algorithms Assignation</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_ELEM0D</source>
+        <translation>Add 0D Element</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_ELEM0D_TITLE</source>
+        <translation>Add 0D Element</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_BALL</source>
+        <translation>Add Ball Element</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_BALL_TITLE</source>
+        <translation>Add Ball Element</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_EDGE</source>
+        <translation>Add Edge</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_EDGE_TITLE</source>
+        <translation>Add Edge</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_HEXAS</source>
+        <translation>Add Hexahedron</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_HEXAS_TITLE</source>
+        <translation>Add Hexahedron</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_HYPOTHESIS</source>
+        <translation>Hypothesis</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_HYPOTHESIS_TITLE</source>
+        <translation>Hypothesis Assignation</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_HYP_WRN</source>
+        <translation>&quot;%1&quot; assigned but:
+        </translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_OCTA</source>
+        <translation>Add hexagonal prism</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_OCTA_TITLE</source>
+        <translation>Add Hexagonal Prism</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_POLYGON</source>
+        <translation>Add polygon</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_POLYGON_TITLE</source>
+        <translation>Add Polygon</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_PENTA</source>
+        <translation>Add pentahedron</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_PENTA_TITLE</source>
+        <translation>Add Pentahedron</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_PYRAMID</source>
+        <translation>Add pyramid</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_PYRAMID_TITLE</source>
+        <translation>Add Pyramid</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRANGLE</source>
+        <translation>Add Quadrangle</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRANGLE_TITLE</source>
+        <translation>Add Quadrangle</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_EDGE_TITLE</source>
+        <translation>Add Quadratic Edge</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_HEXAHEDRON_TITLE</source>
+        <translation>Add Quadratic Hexahedron</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_TRIQUADRATIC_HEXAHEDRON_TITLE</source>
+        <translation>Add TriQuadratic Hexahedron</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_PENTAHEDRON_TITLE</source>
+        <translation>Add Quadratic Pentahedron</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_PYRAMID_TITLE</source>
+        <translation>Add Quadratic Pyramid</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_BIQUADRATIC_QUADRANGLE_TITLE</source>
+        <translation>Add BiQuadratic Quadrangle</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_QUADRANGLE_TITLE</source>
+        <translation>Add Quadratic Quadrangle</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_TETRAHEDRON_TITLE</source>
+        <translation>Add Quadratic Tetrahedron</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_TRIANGLE_TITLE</source>
+        <translation>Add Quadratic Triangle</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_SUBMESH</source>
+        <translation>SubMesh Construction</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_TETRAS</source>
+        <translation>Add Tetrahedron</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_TETRAS_TITLE</source>
+        <translation>Add Tetrahedron</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_TO_GROUP</source>
+        <translation>Add to group</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_TRIANGLE</source>
+        <translation>Add Triangle</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_TRIANGLE_TITLE</source>
+        <translation>Add Triangle</translation>
+    </message>
+    <message>
+        <source>SMESH_ANGLE</source>
+        <translation>Angle</translation>
+    </message>
+    <message>
+        <source>SMESH_ARGUMENTS</source>
+        <translation>Arguments</translation>
+    </message>
+    <message>
+        <source>SMESH_AUTO_GROUPS</source>
+        <translation>Automatically create groups</translation>
+    </message>
+    <message>
+        <source>SMESH_AVAILABLE</source>
+        <translation>Available</translation>
+    </message>
+    <message>
+        <source>SMESH_AVAILABLE_ALGORITHMS</source>
+        <translation>Available algorithms</translation>
+    </message>
+    <message>
+        <source>SMESH_AVAILABLE_HYPOTHESES</source>
+        <translation>Available hypotheses</translation>
+    </message>
+    <message>
+        <source>SMESH_AXIS</source>
+        <translation>Axis</translation>
+    </message>
+    <message>
+        <source>SMESH_BAD_SELECTION</source>
+        <translation>No valid selection</translation>
+    </message>
+    <message>
+        <source>SMESH_BAD_MESH_SELECTION</source>
+        <translation>No valid mesh selection</translation>
+    </message>
+    <message>
+        <source>SMESH_BOUNDARYEDGES</source>
+        <translation>Boundary Edges</translation>
+    </message>
+    <message>
+        <source>SMESH_BUILD_COMPOUND_TITLE</source>
+        <translation>Create a Compound</translation>
+    </message>
+    <message>
+        <source>SMESH_COPY_MESH_TITLE</source>
+        <translation>Copy Mesh</translation>
+    </message>
+    <message>
+        <source>SMESH_KEEP_IDS</source>
+        <translation>Preserve IDs of elements</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_ADD</source>
+        <translation>A&amp;dd</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_APPLY</source>
+        <translation>&amp;Apply</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_CANCEL</source>
+        <translation>&amp;Cancel</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_CLOSE</source>
+        <translation>&amp;Close</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_CREATE</source>
+        <translation>Create</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_DELETE</source>
+        <translation>Delete</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_FILTER</source>
+        <translation>Set &amp;Filter</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_HELP</source>
+        <translation>&amp;Help</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_NEW</source>
+        <translation>New</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_NO</source>
+        <translation>&amp;No</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_OK</source>
+        <translation>&amp;Ok</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_OVERWRITE</source>
+        <translation>Over&amp;write</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_APPLY_AND_CLOSE</source>
+        <translation>A&amp;pply and Close</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_REMOVE</source>
+        <translation>&amp;Remove</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_SORT</source>
+        <translation>&amp;Sort List</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_YES</source>
+        <translation>&amp;Yes</translation>
+    </message>
+    <message>
+        <source>SMESH_CANT_ADD_HYP</source>
+        <translation>Can not assign &quot;%1&quot;:
 </translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_POLYGON</source>
-            <translation>Add polygon</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_POLYGON_TITLE</source>
-            <translation>Add polygon</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_QUADRANGLE</source>
-            <translation>Add Quadrangle</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_QUADRANGLE_TITLE</source>
-            <translation>Add Quadrangle</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_QUADRATIC_EDGE_TITLE</source>
-            <translation>Add Quadratic Edge</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_QUADRATIC_HEXAHEDRON_TITLE</source>
-            <translation>Add Quadratic Hexahedron</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_QUADRATIC_PENTAHEDRON_TITLE</source>
-            <translation>Add Quadratic Pentahedron</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_QUADRATIC_PYRAMID_TITLE</source>
-            <translation>Add Quadratic Pyramid</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_QUADRATIC_QUADRANGLE_TITLE</source>
-            <translation>Add Quadratic Quadrangle</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_QUADRATIC_TETRAHEDRON_TITLE</source>
-            <translation>Add Quadratic Tetrahedron</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_QUADRATIC_TRIANGLE_TITLE</source>
-            <translation>Add Quadratic Triangle</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_SUBMESH</source>
-            <translation>SubMesh Construction</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_TETRAS</source>
-            <translation>Add Tetrahedron</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_TETRAS_TITLE</source>
-            <translation>Add Tetrahedron</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_TRIANGLE</source>
-            <translation>Add Triangle</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_TRIANGLE_TITLE</source>
-            <translation>Add Triangle</translation>
-        </message>
-        <message>
-            <source>SMESH_ANGLE</source>
-            <translation>Angle</translation>
-        </message>
-        <message>
-            <source>SMESH_ARGUMENTS</source>
-            <translation>Arguments</translation>
-        </message>
-        <message>
-            <source>SMESH_AUTO_GROUPS</source>
-            <translation>Automatically create groups</translation>
-        </message>
-        <message>
-            <source>SMESH_AVAILABLE</source>
-            <translation>Available</translation>
-        </message>
-        <message>
-            <source>SMESH_AVAILABLE_ALGORITHMS</source>
-            <translation>Available algorithms</translation>
-        </message>
-        <message>
-            <source>SMESH_AVAILABLE_HYPOTHESES</source>
-            <translation>Available hypotheses</translation>
-        </message>
-        <message>
-            <source>SMESH_AXIS</source>
-            <translation>Axis</translation>
-        </message>
-        <message>
-            <source>SMESH_BAD_SELECTION</source>
-            <translation>No valid selection</translation>
-        </message>
-        <message>
-            <source>SMESH_BAD_MESH_SELECTION</source>
-            <translation>No valid mesh selection</translation>
-        </message>
-        <message>
-            <source>SMESH_BOUNDARYEDGES</source>
-            <translation>Boundary Edges</translation>
-        </message>
-        <message>
-            <source>SMESH_BUILD_COMPOUND_TITLE</source>
-            <translation>Create a Compound</translation>
-        </message>
-        <message>
-            <source>SMESH_BUT_ADD</source>
-            <translation>A&amp;dd</translation>
-        </message>
-        <message>
-            <source>SMESH_BUT_APPLY</source>
-            <translation>&amp;Apply</translation>
-        </message>
-        <message>
-            <source>SMESH_BUT_CANCEL</source>
-            <translation>&amp;Cancel</translation>
-        </message>
-        <message>
-            <source>SMESH_BUT_CLOSE</source>
-            <translation>&amp;Close</translation>
-        </message>
-        <message>
-            <source>SMESH_BUT_CREATE</source>
-            <translation>Create</translation>
-        </message>
-        <message>
-            <source>SMESH_BUT_DELETE</source>
-            <translation>Delete</translation>
-        </message>
-        <message>
-            <source>SMESH_BUT_FILTER</source>
-            <translation>Set &amp;Filters</translation>
-        </message>
-        <message>
-            <source>SMESH_BUT_HELP</source>
-            <translation>&amp;Help</translation>
-        </message>
-        <message>
-            <source>SMESH_BUT_NEW</source>
-            <translation>New</translation>
-        </message>
-        <message>
-            <source>SMESH_BUT_NO</source>
-            <translation>&amp;No</translation>
-        </message>
-        <message>
-            <source>SMESH_BUT_OK</source>
-            <translation>&amp;Ok</translation>
-        </message>
-        <message>
-            <source>SMESH_BUT_APPLY_AND_CLOSE</source>
-            <translation>A&amp;pply and Close</translation>
-        </message>
-        <message>
-            <source>SMESH_BUT_REMOVE</source>
-            <translation>&amp;Remove</translation>
-        </message>
-        <message>
-            <source>SMESH_BUT_SORT</source>
-            <translation>&amp;Sort List</translation>
-        </message>
-        <message>
-            <source>SMESH_BUT_YES</source>
-            <translation>&amp;Yes</translation>
-        </message>
-        <message>
-            <source>SMESH_CANT_ADD_HYP</source>
-            <translation>Can not assign "%1":
+    </message>
+    <message>
+        <source>SMESH_CANT_RM_HYP</source>
+        <translation>Can not unassign &quot;%1&quot;:
+</translation>
+    </message>
+    <message>
+        <source>SMESH_CHECK_COLOR</source>
+        <translation>Color</translation>
+    </message>
+    <message>
+        <source>SMESH_CLIPPING_FROM</source>
+        <translation>From &lt;---</translation>
+    </message>
+    <message>
+        <source>SMESH_CLIPPING_INTO</source>
+        <translation>---&gt; Into</translation>
+    </message>
+    <message>
+        <source>SMESH_CLIPPING_TITLE</source>
+        <translation>Change Clipping</translation>
+    </message>
+    <message>
+        <source>SMESH_COMPUTE_SUCCEED</source>
+        <translation>Mesh computation succeed</translation>
+    </message>
+    <message>
+        <source>SMESH_EVALUATE_SUCCEED</source>
+        <translation>Mesh evaluation succeed</translation>
+    </message>
+    <message>
+        <source>SMESH_CONTENT</source>
+        <translation>Content</translation>
+    </message>
+    <message>
+        <source>SMESH_CONTINUE_MESH_VISUALIZATION</source>
+        <translation>It seems that there is not enough memory to show the mesh
+so that the application may crash. Do you wish to continue visualization?</translation>
+    </message>
+    <message>
+        <source>SMESH_COORDINATES</source>
+        <translation>Coordinates</translation>
+    </message>
+    <message>
+        <source>SMESH_COPY_ELEMENTS</source>
+        <translation>Copy Elements</translation>
+    </message>
+    <message>
+        <source>SMESH_COPY_GROUPS</source>
+        <translation>Copy groups</translation>
+    </message>
+    <message>
+        <source>SMESH_CREATE_ALGORITHMS</source>
+        <translation>Create algorithms</translation>
+    </message>
+    <message>
+        <source>SMESH_CREATE_COPY</source>
+        <translation>Create a copy</translation>
+    </message>
+    <message>
+        <source>SMESH_CREATE_GROUP_TITLE</source>
+        <translation>Create Group</translation>
+    </message>
+    <message>
+        <source>SMESH_CREATE_GEO_GROUP</source>
+        <translation>Create Groups from Geometry</translation>
+    </message>
+    <message>
+        <source>SMESH_CREATE_HYPOTHESES</source>
+        <translation>Create hypotheses</translation>
+    </message>
+    <message>
+        <source>SMESH_CREATE_MESH</source>
+        <translation>Create a new mesh</translation>
+    </message>
+    <message>
+        <source>SMESH_CREATE_POLYHEDRAL_VOLUME_TITLE</source>
+        <translation>Create polyhedral volume</translation>
+    </message>
+    <message>
+        <source>SMESH_DIAGONAL</source>
+        <translation>Diagonal Inversion</translation>
+    </message>
+    <message>
+        <source>SMESH_DIAGONAL_INVERSION_TITLE</source>
+        <translation>Diagonal Inversion</translation>
+    </message>
+    <message>
+        <source>SMESH_DISTANCE</source>
+        <translation>Distance</translation>
+    </message>
+    <message>
+        <source>SMESH_DRS_1</source>
+        <translation>MED file contains no mesh with the given name</translation>
+    </message>
+    <message>
+        <source>SMESH_DRS_2</source>
+        <translation>MED file has overlapped ranges of element numbers, the numbers from the file are ignored</translation>
+    </message>
+    <message>
+        <source>SMESH_DRS_3</source>
+        <translation>Some elements were skipped due to incorrect file data</translation>
+    </message>
+    <message>
+        <source>SMESH_DRS_4</source>
+        <translation>The file is incorrect, some data is missed</translation>
+    </message>
+    <message>
+        <source>SMESH_DRS_EMPTY</source>
+        <translation>The file is empty, there is nothing to be published</translation>
+    </message>
+    <message>
+        <source>SMESH_DX</source>
+        <translation>dX</translation>
+    </message>
+    <message>
+        <source>SMESH_DY</source>
+        <translation>dY</translation>
+    </message>
+    <message>
+        <source>SMESH_DZ</source>
+        <translation>dZ</translation>
+    </message>
+    <message>
+        <source>SMESH_ELEM0D</source>
+        <translation>0D Element</translation>
+    </message>
+    <message>
+        <source>SMESH_ELEMS0D</source>
+        <translation>0D Elements</translation>
+    </message>
+    <message>
+        <source>SMESH_BALL_ELEM</source>
+        <translation>Ball</translation>
+    </message>
+    <message>
+        <source>SMESH_BALL</source>
+        <translation>Ball</translation>
+    </message>
+    <message>
+        <source>SMESH_BALLS</source>
+        <translation>Balls</translation>
+    </message>
+    <message>
+        <source>SMESH_EDGE</source>
+        <translation>Edge</translation>
+    </message>
+    <message>
+        <source>SMESH_EDGES</source>
+        <translation>Edges</translation>
+    </message>
+    <message>
+        <source>SMESH_EDGES_CONNECTIVITY_TITLE</source>
+        <translation>Edges Connectivity</translation>
+    </message>
+    <message>
+        <source>SMESH_EDIT_GROUP_TITLE</source>
+        <translation>Edit Group</translation>
+    </message>
+    <message>
+        <source>SMESH_EDIT_GEOMGROUP_AS_GROUP_TITLE</source>
+        <translation>Edit Group as Standalone</translation>
+    </message>
+    <message>
+        <source>SMESH_EDIT_HYPOTHESES</source>
+        <translation>Hypotheses Assignation</translation>
+    </message>
+    <message>
+        <source>SMESH_EDIT_USED</source>
+        <translation>Used</translation>
+    </message>
+    <message>
+        <source>SMESH_ELEMENTS</source>
+        <translation>Elements</translation>
+    </message>
+    <message>
+        <source>SMESH_ELEMENTS_COLOR</source>
+        <translation>Mesh Element Color</translation>
+    </message>
+    <message>
+        <source>SMESH_ELEMENTS_TYPE</source>
+        <translation>Elements Type</translation>
+    </message>
+    <message>
+        <source>SMESH_ELEMENT_TYPE</source>
+        <translation>Element Type</translation>
+    </message>
+    <message>
+        <source>SMESH_ERROR</source>
+        <translation>Error</translation>
+    </message>
+    <message>
+        <source>SMESH_ERR_SCALARBAR_PARAMS</source>
+        <translation>Warning! The parameters is incorrect</translation>
+    </message>
+    <message>
+        <source>SMESH_EXPORT_FAILED</source>
+        <translation>Mesh export failed.
+Probably, there is not enough space on disk.</translation>
+    </message>
+    <message>
+        <source>SMESH_EXPORT_MED_DUPLICATED_GRP</source>
+        <translation>There are duplicated group names in mesh &quot;%1&quot;.
+You can cancel exporting and rename them,
+otherwise some group names in the resulting file
+will not match ones in the study.
+Do you want to continue ?</translation>
+    </message>
+    <message>
+        <source>SMESH_EXPORT_MED_DUPLICATED_MESH_NAMES</source>
+        <translation>There are some mesh objects with the same names in the selection.
+The result file may be incorrect.
+Do you want to continue ?</translation>
+    </message>
+    <message>
+        <source>SMESH_EXPORT_MED_V2_1</source>
+        <translation>During export mesh with name - &quot;%1&quot; to MED 2.1
+polygons and polyhedrons elements will be missed
+For correct export use MED 2.2
+Are you sure want to export to MED 2.1 ?</translation>
+    </message>
+    <message>
+        <source>SMESH_EXPORT_MED_VERSION_COLLISION</source>
+        <translation>MED version of the file &quot;%1&quot;
+is unknown or doesn&apos;t match the selected version.
+Overwrite the file?</translation>
+    </message>
+    <message>
+        <source>SMESH_EXPORT_MED_MESH_NAMES_COLLISION</source>
+        <translation>The selected file already contains
+meshes with the following names: %1
+The result file may be incorrect.
+Overwrite the file?</translation>
+    </message>
+    <message>
+        <source>EXPORT_NOT_SUPPORTED</source>
+        <translation>During export mesh with name &quot;%1&quot; to %2
+%3 will be missed.
+Do you want to continue ?</translation>
+    </message>
+    <message>
+        <source>SMESH_EXTRUSION</source>
+        <translation>Extrusion</translation>
+    </message>
+    <message>
+        <source>SMESH_EXTRUSION_TO_DISTANCE</source>
+        <translation>Extrusion To Distance</translation>
+    </message>
+    <message>
+        <source>SMESH_EXTRUSION_ALONG_VECTOR</source>
+        <translation>Extrusion Along Vector</translation>
+    </message>
+    <message>
+        <source>SMESH_FACE</source>
+        <translation>Face</translation>
+    </message>
+    <message>
+        <source>SMESH_FEATUREANGLE</source>
+        <translation>Feature Angle</translation>
+    </message>
+    <message>
+        <source>SMESH_FEATUREEDGES</source>
+        <translation>Feature Edges</translation>
+    </message>
+    <message>
+        <source>SMESH_FILE_EXISTS</source>
+        <translation>The file &quot;%1&quot; already exists.
+Do you want to overwrite it or
+add the exported data to its contents?</translation>
+    </message>
+    <message>
+        <source>SMESH_FONT_ARIAL</source>
+        <translation>Arial</translation>
+    </message>
+    <message>
+        <source>SMESH_FONT_BOLD</source>
+        <translation>Bold</translation>
+    </message>
+    <message>
+        <source>SMESH_FONT_COURIER</source>
+        <translation>Courier</translation>
+    </message>
+    <message>
+        <source>SMESH_FONT_ITALIC</source>
+        <translation>Italic</translation>
+    </message>
+    <message>
+        <source>SMESH_FONT_SCALARBAR</source>
+        <translation>Font</translation>
+    </message>
+    <message>
+        <source>SMESH_FONT_SHADOW</source>
+        <translation>Shadow</translation>
+    </message>
+    <message>
+        <source>SMESH_FONT_TIMES</source>
+        <translation>Times</translation>
+    </message>
+    <message>
+        <source>SMESH_GEOM_GROUP</source>
+        <translation>Geometry group</translation>
+    </message>
+    <message>
+        <source>SMESH_GROUP</source>
+        <translation>Group</translation>
+    </message>
+    <message>
+        <source>SMESH_GROUP_GEOMETRY</source>
+        <translation>Group on geometry</translation>
+    </message>
+    <message>
+        <source>SMESH_GROUP_FILTER</source>
+        <translation>Group on filter</translation>
+    </message>
+    <message>
+        <source>SMESH_GROUP_SELECTED</source>
+        <translation>%1 Groups</translation>
+    </message>
+    <message>
+        <source>SMESH_GROUP_STANDALONE</source>
+        <translation>Standalone group</translation>
+    </message>
+    <message>
+        <source>SMESH_GROUP_TYPE</source>
+        <translation>Group type</translation>
+    </message>
+    <message>
+        <source>SMESH_HEIGHT</source>
+        <translation>Height:</translation>
+    </message>
+    <message>
+        <source>SMESH_HEXAS</source>
+        <translation>Hexahedron</translation>
+    </message>
+    <message>
+        <source>SMESH_HEXAHEDRA</source>
+        <translation>Hexahedrons</translation>
+    </message>
+    <message>
+        <source>SMESH_HILIGHT_COLOR</source>
+        <translation>Highlight Color</translation>
+    </message>
+    <message>
+        <source>SMESH_HORIZONTAL</source>
+        <translation>Horizontal</translation>
+    </message>
+    <message>
+        <source>SMESH_HYPOTHESES</source>
+        <translation>Hypotheses</translation>
+    </message>
+    <message>
+        <source>SMESH_HYP_1</source>
+        <translation>Algorithm misses a hypothesis</translation>
+    </message>
+    <message>
+        <source>SMESH_HYP_10</source>
+        <translation>Hypothesis and submesh dimensions mismatch</translation>
+    </message>
+    <message>
+        <source>SMESH_HYP_11</source>
+        <translation>Shape is neither the main one, nor its sub-shape, nor a valid group</translation>
+    </message>
+    <message>
+        <source>SMESH_HYP_12</source>
+        <translation>Geometry mismatches algorithm&apos;s expectation
+Check algorithm documentation for supported geometry</translation>
+    </message>
+    <message>
+        <source>SMESH_HYP_13</source>
+        <translation>Algorithm can&apos;t work without shape</translation>
+    </message>
+    <message>
+        <source>SMESH_HYP_2</source>
+        <translation>There are concurrent hypotheses on a shape</translation>
+    </message>
+    <message>
+        <source>SMESH_HYP_3</source>
+        <translation>Hypothesis has a bad parameter value</translation>
+    </message>
+    <message>
+        <source>SMESH_HYP_4</source>
+        <translation>Submesh is ignored as there is another algorithm of upper dimension generating %1D elements</translation>
+    </message>
+    <message>
+        <source>SMESH_HYP_5</source>
+        <translation>Algorithm hides algorithm(s) of lower dimension by generating all-dimensions elements</translation>
+    </message>
+    <message>
+        <source>SMESH_HYP_6</source>
+        <translation>Unknown fatal error at hypothesis definition</translation>
+    </message>
+    <message>
+        <source>SMESH_HYP_7</source>
+        <translation>Hypothesis is not suitable in the current context</translation>
+    </message>
+    <message>
+        <source>SMESH_HYP_8</source>
+        <translation>Non-conform mesh is produced using applied hypotheses</translation>
+    </message>
+    <message>
+        <source>SMESH_HYP_9</source>
+        <translation>Such dimention hypothesis is already assigned to the shape</translation>
+    </message>
+    <message>
+        <source>SMESH_ID_DIAGONAL</source>
+        <translation>Id Edges</translation>
+    </message>
+    <message>
+        <source>SMESH_ID_ELEMENTS</source>
+        <translation>Id Elements</translation>
+    </message>
+    <message>
+        <source>SMESH_ID_FACES</source>
+        <translation>Id Faces</translation>
+    </message>
+    <message>
+        <source>SMESH_ID_NODES</source>
+        <translation>Id Nodes</translation>
+    </message>
+    <message>
+        <source>SMESH_INCORRECT_INPUT</source>
+        <translation>Incorrect input data!</translation>
+    </message>
+    <message>
+        <source>SMESH_INFORMATION</source>
+        <translation>Information</translation>
+    </message>
+    <message>
+        <source>SMESH_INIT</source>
+        <translation>Mesh</translation>
+    </message>
+    <message>
+        <source>SMESH_INIT_MESH</source>
+        <translation>Mesh Construction</translation>
+    </message>
+    <message>
+        <source>SMESH_INSUFFICIENT_DATA</source>
+        <translation>Insufficient input value</translation>
+    </message>
+    <message>
+        <source>SMESH_LABELS</source>
+        <translation>Labels:</translation>
+    </message>
+    <message>
+        <source>SMESH_LABELS_COLORS_SCALARBAR</source>
+        <translation>Colors &amp;&amp; Labels</translation>
+    </message>
+    <message>
+        <source>SMESH_LENGTH</source>
+        <translation>Length</translation>
+    </message>
+    <message>
+        <source>SMESH_MAKE_GROUPS</source>
+        <translation>Generate groups</translation>
+    </message>
+    <message>
+        <source>SMESH_MANIFOLDEDGES</source>
+        <translation>Manifold Edges</translation>
+    </message>
+    <message>
+        <source>SMESH_MAX</source>
+        <translation>Max</translation>
+    </message>
+    <message>
+        <source>SMESH_MEN_ALGORITHMS</source>
+        <translation>Algorithms</translation>
+    </message>
+    <message>
+        <source>SMESH_MEN_APPLIED_ALGORIHTMS</source>
+        <translation>Applied Algorithms</translation>
+    </message>
+    <message>
+        <source>SMESH_MEN_APPLIED_HYPOTHESIS</source>
+        <translation>Applied Hypotheses</translation>
+    </message>
+    <message>
+        <source>SMESH_MEN_COMPONENT</source>
+        <translation>SMESH</translation>
+    </message>
+    <message>
+        <source>SMESH_MEN_HYPOTHESIS</source>
+        <translation>Hypotheses</translation>
+    </message>
+    <message>
+        <source>SMESH_MEN_SubMeshesOnCompound</source>
+        <translation>SubMeshes On Compound</translation>
+    </message>
+    <message>
+        <source>SMESH_MEN_SubMeshesOnEdge</source>
+        <translation>SubMeshes On Edge</translation>
+    </message>
+    <message>
+        <source>SMESH_MEN_SubMeshesOnFace</source>
+        <translation>SubMeshes On Face</translation>
+    </message>
+    <message>
+        <source>SMESH_MEN_SubMeshesOnSolid</source>
+        <translation>SubMeshes On Solid</translation>
+    </message>
+    <message>
+        <source>SMESH_MEN_SubMeshesOnVertex</source>
+        <translation>SubMeshes On Vertex</translation>
+    </message>
+    <message>
+        <source>SMESH_AUTOMATIC</source>
+        <translation>Automatic</translation>
+    </message>
+    <message>
+        <source>SMESH_MANUAL</source>
+        <translation>Manual</translation>
+    </message>
+    <message>
+        <source>SMESH_MERGE_ELEMENTS</source>
+        <translation>Merge elements</translation>
+    </message>
+    <message>
+        <source>SMESH_MODE</source>
+        <translation>Mode</translation>
+    </message>
+    <message>
+        <source>SMESH_MERGED_ELEMENTS</source>
+        <translation>%1 elements successfully merged.</translation>
+    </message>
+    <message>
+        <source>SMESH_MERGED_NODES</source>
+        <translation>%1 nodes successfully merged.</translation>
+    </message>
+    <message>
+        <source>SMESH_NO_ELEMENTS_DETECTED</source>
+        <translation>There are no elements to merge.</translation>
+    </message>
+    <message>
+        <source>SMESH_NO_NODES_DETECTED</source>
+        <translation>There are no nodes to merge.</translation>
+    </message>
+    <message>
+        <source>SMESH_MERGE_NODES</source>
+        <translation>Merge nodes</translation>
+    </message>
+    <message>
+        <source>SMESH_MESH</source>
+        <translation>Mesh</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_0DELEMS</source>
+        <translation>0D Elements</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_BALLS</source>
+        <translation>Balls</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_ALL_TYPES</source>
+        <translation>Heterogenous</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_EDGES</source>
+        <translation>Edges</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_ELEMENTS</source>
+        <translation>Elements</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_ENTITIES</source>
+        <translation>Entities</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_FACES</source>
+        <translation>Faces</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_HEXAS</source>
+        <translation>Hexahedrons</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_NAME</source>
+        <translation>Name</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_NODES</source>
+        <translation>Nodes</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_ORDER0</source>
+        <translation>Total</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_ORDER1</source>
+        <translation>Linear</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_ORDER2</source>
+        <translation>Quadratic</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_HEXAPRISM</source>
+        <translation>Hexagonal prisms</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_POLYEDRES</source>
+        <translation>Polyhedrons</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_POLYGONES</source>
+        <translation>Polygons</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_PRISMS</source>
+        <translation>Prisms</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_PYRAS</source>
+        <translation>Pyramids</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_QUADRANGLES</source>
+        <translation>Quadrangles</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_TETRAS</source>
+        <translation>Tetrahedrons</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_TITLE</source>
+        <translation>Mesh Infos</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_TOTAL</source>
+        <translation>Total</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_TRIANGLES</source>
+        <translation>Triangles</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_TYPE</source>
+        <translation>Type</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_VOLUMES</source>
+        <translation>Volumes</translation>
+    </message>
+    <message>
+        <source>SMESH_MIN</source>
+        <translation>Min</translation>
+    </message>
+    <message>
+        <source>SMESH_MOVE</source>
+        <translation>Move</translation>
+    </message>
+    <message>
+        <source>SMESH_MOVE_ELEMENTS</source>
+        <translation>Move Elements</translation>
+    </message>
+    <message>
+        <source>SMESH_MOVE_NODES_TITLE</source>
+        <translation>Move Node</translation>
+    </message>
+    <message>
+        <source>SMESH_NAME</source>
+        <translation>Name</translation>
+    </message>
+    <message>
+        <source>SMESH_NODES</source>
+        <translation>Nodes</translation>
+    </message>
+    <message>
+        <source>SMESH_NONMANIFOLDEDGES</source>
+        <translation>Non Manifold Edges</translation>
+    </message>
+    <message>
+        <source>SMESH_NORMAL</source>
+        <translation>Normal</translation>
+    </message>
+    <message>
+        <source>SMESH_NO_MESH_VISUALIZATION</source>
+        <translation>There is not enough memory to show the mesh</translation>
+    </message>
+    <message>
+        <source>SMESH_NUMBEROFCOLORS</source>
+        <translation>Nb of colors:</translation>
+    </message>
+    <message>
+        <source>SMESH_NUMBEROFLABELS</source>
+        <translation>Nb of labels:</translation>
+    </message>
+    <message>
+        <source>SMESH_NUMBEROFSTEPS</source>
+        <translation>Number of steps:</translation>
+    </message>
+    <message>
+        <source>SMESH_OBJECTS_SELECTED</source>
+        <translation>%1_objects</translation>
+    </message>
+    <message>
+        <source>SMESH_OBJECT_ALGORITHM</source>
+        <translation>Algorithm</translation>
+    </message>
+    <message>
+        <source>SMESH_OBJECT_GEOM</source>
+        <translation>Geometrical Object</translation>
+    </message>
+    <message>
+        <source>SMESH_OBJECT_HYPOTHESIS</source>
+        <translation>Hypothesis</translation>
+    </message>
+    <message>
+        <source>SMESH_OBJECT_MESH</source>
+        <translation>Mesh</translation>
+    </message>
+    <message>
+        <source>SMESH_OBJECT_MESHorSUBMESH</source>
+        <translation>Mesh or SubMesh</translation>
+    </message>
+    <message>
+        <source>SMESH_OPERATION_FAILED</source>
+        <translation>Operation failed</translation>
+    </message>
+    <message>
+        <source>SMESH_OCTA</source>
+        <translation>Octogonal prism</translation>
+    </message>
+    <message>
+        <source>SMESH_OCTAHEDRA</source>
+        <translation>Octogonal prisms</translation>
+    </message>
+    <message>
+        <source>TOP_OCTA</source>
+        <translation>Hexagonal prism</translation>
+    </message>
+    <message>
+        <source>MEN_OCTA</source>
+        <translation>Hexagonal prism</translation>
+    </message>
+    <message>
+        <source>STB_OCTA</source>
+        <translation>Hexagonal prism</translation>
+    </message>
+    <message>
+        <source>SMESH_ORIENTATION</source>
+        <translation>Orientation</translation>
+    </message>
+    <message>
+        <source>SMESH_ORIENTATION_ELEMENTS_TITLE</source>
+        <translation>Change Orientation</translation>
+    </message>
+    <message>
+        <source>SMESH_OUTLINE_COLOR</source>
+        <translation>Mesh Object Color</translation>
+    </message>
+    <message>
+        <source>SMESH_PARAMETERS</source>
+        <translation>Parameters</translation>
+    </message>
+    <message>
+        <source>SMESH_PENTA</source>
+        <translation>Pentahedron</translation>
+    </message>
+    <message>
+        <source>SMESH_PENTAHEDRA</source>
+        <translation>Pentahedrons</translation>
+    </message>
+    <message>
+        <source>TOP_PENTA</source>
+        <translation>Pentahedron</translation>
+    </message>
+    <message>
+        <source>MEN_PENTA</source>
+        <translation>Pentahedron</translation>
+    </message>
+    <message>
+        <source>STB_PENTA</source>
+        <translation>Pentahedron</translation>
+    </message>
+    <message>
+        <source>SMESH_PLANE</source>
+        <translation>Plane</translation>
+    </message>
+    <message>
+        <source>SMESH_POINT</source>
+        <translation>Point</translation>
+    </message>
+    <message>
+        <source>SMESH_POINT_1</source>
+        <translation>Point 1</translation>
+    </message>
+    <message>
+        <source>SMESH_POINT_2</source>
+        <translation>Point 2</translation>
+    </message>
+    <message>
+        <source>SMESH_BASE_POINT</source>
+        <translation>Base Point</translation>
+    </message>
+    <message>
+        <source>SMESH_POLYEDRE_CREATE_ERROR</source>
+        <translation>Polyedron creation error</translation>
+    </message>
+    <message>
+        <source>SMESH_POLYEDRON</source>
+        <translation>Polyhedron</translation>
+    </message>
+    <message>
+        <source>SMESH_POLYEDRONS</source>
+        <translation>Polyhedrons</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_POLYEDRON</source>
+        <translation>Quadratic Polyhedron</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_POLYEDRONS</source>
+        <translation>Quadratic Polyhedrons</translation>
+    </message>
+    <message>
+        <source>SMESH_POLYGON</source>
+        <translation>Polygon</translation>
+    </message>
+    <message>
+        <source>SMESH_POLYGONS</source>
+        <translation>Polygons</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_POLYGON</source>
+        <translation>Quadratic Polygon</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_POLYGONS</source>
+        <translation>Quadratic Polygons</translation>
+    </message>
+    <message>
+        <source>SMESH_POSITION_SIZE_SCALARBAR</source>
+        <translation>Origin &amp;&amp; Size</translation>
+    </message>
+    <message>
+        <source>SMESH_DISTRIBUTION_SCALARBAR</source>
+        <translation>Distribution</translation>
+    </message>
+    <message>
+        <source>SMESH_SHOW_DISTRIBUTION_SCALARBAR</source>
+        <translation>Show Distribution</translation>
+    </message>
+    <message>
+        <source>SMESH_PRECISION</source>
+        <translation>Precision</translation>
+    </message>
+    <message>
+        <source>SMESH_PREFERENCES_SCALARBAR</source>
+        <translation>Scalar Bar Preferences</translation>
+    </message>
+    <message>
+        <source>SMESH_PREF_SELECTION</source>
+        <translation>Preferences - Selection</translation>
+    </message>
+    <message>
+        <source>SMESH_PRESELECTION</source>
+        <translation>Preselection</translation>
+    </message>
+    <message>
+        <source>SMESH_PRISM</source>
+        <translation>Prism</translation>
+    </message>
+    <message>
+        <source>SMESH_PROPERTIES_SCALARBAR</source>
+        <translation>Scalar Bar Properties</translation>
+    </message>
+    <message>
+        <source>SMESH_PYRAMID</source>
+        <translation>Pyramid</translation>
+    </message>
+    <message>
+        <source>SMESH_PYRAMIDS</source>
+        <translation>Pyramids</translation>
+    </message>
+    <message>
+        <source>MEN_PYRAMID</source>
+        <translation>Pyramid</translation>
+    </message>
+    <message>
+        <source>TOP_PYRAMID</source>
+        <translation>Pyramid</translation>
+    </message>
+    <message>
+        <source>STB_PYRAMID</source>
+        <translation>Pyramid</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRANGLE</source>
+        <translation>Quadrangle</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRANGLES</source>
+        <translation>Quadrangles</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_EDGE</source>
+        <translation>Quadratic Edge</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_EDGES</source>
+        <translation>Quadratic Edges</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_HEXAHEDRON</source>
+        <translation>Quadratic Hexahedron</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_HEXAHEDRONS</source>
+        <translation>Quadratic Hexahedrons</translation>
+    </message>
+    <message>
+        <source>SMESH_TRIQUADRATIC_HEXAHEDRON</source>
+        <translation>TriQuadratic Hexahedron</translation>
+    </message>
+    <message>
+        <source>SMESH_TRIQUADRATIC_HEXAHEDRONS</source>
+        <translation>TriQuadratic Hexahedrons</translation>
+    </message>
+    <message>
+        <source>TOP_TRIQUADRATIC_HEXAHEDRON</source>
+        <translation>TriQuadratic Hexahedron</translation>
+    </message>
+    <message>
+        <source>MEN_TRIQUADRATIC_HEXAHEDRON</source>
+        <translation>TriQuadratic Hexahedron</translation>
+    </message>
+    <message>
+        <source>STB_TRIQUADRATIC_HEXAHEDRON</source>
+        <translation>TriQuadratic Hexahedron</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_PENTAHEDRON</source>
+        <translation>Quadratic Pentahedron</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_PENTAHEDRONS</source>
+        <translation>Quadratic Pentahedrons</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_PYRAMID</source>
+        <translation>Quadratic Pyramid</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_PYRAMIDS</source>
+        <translation>Quadratic Pyramids</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_QUADRANGLE</source>
+        <translation>Quadratic Quadrangle</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_QUADRANGLES</source>
+        <translation>Quadratic Quadrangles</translation>
+    </message>
+    <message>
+        <source>SMESH_BIQUADRATIC_QUADRANGLE</source>
+        <translation>BiQuadratic Quadrangle</translation>
+    </message>
+    <message>
+        <source>SMESH_BIQUADRATIC_QUADRANGLES</source>
+        <translation>BiQuadratic Quadrangles</translation>
+    </message>
+    <message>
+        <source>MEN_BIQUADRATIC_QUADRANGLE</source>
+        <translation>BiQuadratic Quadrangle</translation>
+    </message>
+    <message>
+        <source>TOP_BIQUADRATIC_QUADRANGLE</source>
+        <translation>BiQuadratic Quadrangle</translation>
+    </message>
+    <message>
+        <source>STB_BIQUADRATIC_QUADRANGLE</source>
+        <translation>BiQuadratic Quadrangle</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_TETRAHEDRON</source>
+        <translation>Quadratic Tetrahedron</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_TETRAHEDRONS</source>
+        <translation>Quadratic Tetrahedrons</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_TRIANGLE</source>
+        <translation>Quadratic Triangle</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_TRIANGLES</source>
+        <translation>Quadratic Triangles</translation>
+    </message>
+    <message>
+        <source>SMESH_RANGE_MAX</source>
+        <translation>Max value:</translation>
+    </message>
+    <message>
+        <source>SMESH_RANGE_MIN</source>
+        <translation>Min value:</translation>
+    </message>
+    <message>
+        <source>SMESH_RANGE_SCALARBAR</source>
+        <translation>Scalar Range</translation>
+    </message>
+    <message>
+        <source>SMESH_REALLY_DELETE</source>
+        <translation>Do you really want to delete this %1 object(s)? : %2</translation>
+    </message>
+    <message>
+        <source>SMESH_REMOVE</source>
+        <translation>Remove</translation>
+    </message>
+    <message>
+        <source>SMESH_REMOVE_ELEMENTS_TITLE</source>
+        <translation>Remove Elements</translation>
+    </message>
+    <message>
+        <source>SMESH_REMOVE_NODES_TITLE</source>
+        <translation>Remove Nodes</translation>
+    </message>
+    <message>
+        <source>SMESH_RENUMBERING</source>
+        <translation>Renumbering</translation>
+    </message>
+    <message>
+        <source>SMESH_RENUMBERING_ELEMENTS_TITLE</source>
+        <translation>Renumbering elements</translation>
+    </message>
+    <message>
+        <source>SMESH_RENUMBERING_NODES_TITLE</source>
+        <translation>Renumbering nodes</translation>
+    </message>
+    <message>
+        <source>SMESH_REVERSE</source>
+        <translation>Reverse</translation>
+    </message>
+    <message>
+        <source>SMESH_REVOLUTION</source>
+        <translation>Revolution</translation>
+    </message>
+    <message>
+        <source>SMESH_RM_HYP_WRN</source>
+        <translation>&quot;%1&quot; unassigned but:
 </translation>
-        </message>
-        <message>
-            <source>SMESH_CANT_RM_HYP</source>
-            <translation>Can not unassign "%1":
+    </message>
+    <message>
+        <source>SMESH_ROTATION</source>
+        <translation>Rotation</translation>
+    </message>
+    <message>
+        <source>SMESH_ROTATION_TITLE</source>
+        <translation>Rotation about an axis</translation>
+    </message>
+    <message>
+        <source>SMESH_SCALARBAR</source>
+        <translation>Scalar Bar</translation>
+    </message>
+    <message>
+        <source>SMESH_SEGMENTS</source>
+        <translation>Segments</translation>
+    </message>
+    <message>
+        <source>SMESH_SELECTION</source>
+        <translation>Selection</translation>
+    </message>
+    <message>
+        <source>SMESH_SELECT_FROM</source>
+        <translation>Select From</translation>
+    </message>
+    <message>
+        <source>SMESH_SELECT_WHOLE_MESH</source>
+        <translation>Select whole mesh, submesh or group</translation>
+    </message>
+    <message>
+        <source>SMESH_SET_COLOR</source>
+        <translation>Color group</translation>
+    </message>
+    <message>
+        <source>SMESH_SEWING</source>
+        <translation>Sewing</translation>
+    </message>
+    <message>
+        <source>SMESH_SMOOTHING</source>
+        <translation>Smoothing</translation>
+    </message>
+    <message>
+        <source>SMESH_STANDARD_MESHINFO_TITLE</source>
+        <translation>Standard Mesh Infos</translation>
+    </message>
+    <message>
+        <source>SMESH_SUBMESH</source>
+        <translation>SubMesh</translation>
+    </message>
+    <message>
+        <source>SMESH_SUBMESH_SELECTED</source>
+        <translation>%1 SubMeshes</translation>
+    </message>
+    <message>
+        <source>SMESH_SYMMETRY</source>
+        <translation>Symmetry</translation>
+    </message>
+    <message>
+        <source>SMESH_TETRAS</source>
+        <translation>Tetrahedron</translation>
+    </message>
+    <message>
+        <source>SMESH_TETRAHEDRA</source>
+        <translation>Tetrahedrons</translation>
+    </message>
+    <message>
+        <source>SMESH_TITLE</source>
+        <translation>Title:</translation>
+    </message>
+    <message>
+        <source>SMESH_TOLERANCE</source>
+        <translation>Tolerance</translation>
+    </message>
+    <message>
+        <source>SMESH_TRANSLATION</source>
+        <translation>Translation</translation>
+    </message>
+    <message>
+        <source>SMESH_SCALE_TITLE</source>
+        <translation>Scale Transform</translation>
+    </message>
+    <message>
+        <source>SMESH_DUPLICATE_TITLE</source>
+        <translation>Duplicate Nodes</translation>
+    </message>
+    <message>
+        <source>SMESH_SCALE</source>
+        <translation>Scale</translation>
+    </message>
+    <message>
+        <source>SMESH_SCALE_FACTOR</source>
+        <translation>Scale Factor :</translation>
+    </message>
+    <message>
+        <source>SMESH_SCALE_FACTOR_X</source>
+        <translation>Scale Factor X :</translation>
+    </message>
+    <message>
+        <source>SMESH_SCALE_FACTOR_Y</source>
+        <translation>Scale Factor Y :</translation>
+    </message>
+    <message>
+        <source>SMESH_SCALE_FACTOR_Z</source>
+        <translation>Scale Factor Z :</translation>
+    </message>
+    <message>
+        <source>SMESH_TRANSPARENCY_OPAQUE</source>
+        <translation>Opaque</translation>
+    </message>
+    <message>
+        <source>SMESH_TRANSPARENCY_TITLE</source>
+        <translation>Change Transparency</translation>
+    </message>
+    <message>
+        <source>SMESH_TRANSPARENCY_TRANSPARENT</source>
+        <translation>Transparent</translation>
+    </message>
+    <message>
+        <source>SMESH_TRIANGLE</source>
+        <translation>Triangle</translation>
+    </message>
+    <message>
+        <source>SMESH_TRIANGLES</source>
+        <translation>Triangles</translation>
+    </message>
+    <message>
+        <source>SMESH_UPDATEVIEW</source>
+        <translation>Update View</translation>
+    </message>
+    <message>
+        <source>SMESH_VALUE</source>
+        <translation>Value</translation>
+    </message>
+    <message>
+        <source>SMESH_VECTOR</source>
+        <translation>Vector</translation>
+    </message>
+    <message>
+        <source>SMESH_VERTICAL</source>
+        <translation>Vertical</translation>
+    </message>
+    <message>
+        <source>SMESH_DISTRIBUTION_COLORING_TYPE</source>
+        <translation>Coloring Type</translation>
+    </message>
+    <message>
+        <source>SMESH_MONOCOLOR</source>
+        <translation>Monocolor</translation>
+    </message>
+    <message>
+        <source>SMESH_DISTRIBUTION_COLOR</source>
+        <translation>Distribution color:</translation>
+    </message>
+    <message>
+        <source>SMESH_MULTICOLOR</source>
+        <translation>Multicolor</translation>
+    </message>
+    <message>
+        <source>SMESH_VISU_PROBLEM</source>
+        <translation>Mesh visualization failed, probably due to lack of memory</translation>
+    </message>
+    <message>
+        <source>SMESH_VISU_PROBLEM_CLEAR</source>
+        <translation>Mesh visualization failed, no memory even to show a message,
+so all visual data have been removed to let the application live.
+Consider saving your work before application crash</translation>
+    </message>
+    <message>
+        <source>SMESH_VOLUME</source>
+        <translation>Volume</translation>
+    </message>
+    <message>
+        <source>SMESH_WARNING</source>
+        <translation>Warning</translation>
+    </message>
+    <message>
+        <source>SMESH_WHAT_IS_TITLE</source>
+        <translation>Mesh Element Info</translation>
+    </message>
+    <message>
+        <source>SMESH_WIDTH</source>
+        <translation>Width:</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_ALGORITHM_ALREADYEXIST</source>
+        <translation>Algorithm already exists</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_COMPUTE_FAILED</source>
+        <translation>Mesh computation failed</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_EVALUATE_FAILED</source>
+        <translation>Mesh evaluation failed</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_EMPTY_NAME</source>
+        <translation>Empty name is not valid</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_HYPOTHESIS_ALREADYEXIST</source>
+        <translation>Hypothesis already exists</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_HYPOTHESIS_NOTEXIST</source>
+        <translation>Hypothesis or Algorithm not exists</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_MISSING_PARAMETERS</source>
+        <translation>Missing parameters</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_NO_AVAILABLE_DATA</source>
+        <translation>No available data in selection</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_SELECTIONMODE_DIAGONAL</source>
+        <translation>Activate Link Selection Mode</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_SELECTIONMODE_ELEMENTS</source>
+        <translation>Activate Elements Selection Mode</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_SELECTIONMODE_NODES</source>
+        <translation>Activate Nodes Selection Mode</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_VIEWER_VTK</source>
+        <translation>Study frame with VTK Viewer must be activated</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_SIZE_LIMIT_EXCEEDED</source>
+        <translation>No automatic update of the presentation has been done: new mesh size (%1 elements) exceeds current size limit (%2 elements).
+Please check preferences of Mesh module.
 </translation>
-        </message>
-        <message>
-            <source>SMESH_CHECK_COLOR</source>
-            <translation>Color</translation>
-        </message>
-        <message>
-            <source>SMESH_CLIPPING_FROM</source>
-            <translation>From &lt;---</translation>
-        </message>
-        <message>
-            <source>SMESH_CLIPPING_INTO</source>
-            <translation>---> Into</translation>
-        </message>
-        <message>
-            <source>SMESH_CLIPPING_TITLE</source>
-            <translation>Change Clipping</translation>
-        </message>
-        <message>
-            <source>SMESH_COMPUTE_SUCCEED</source>
-            <translation>Mesh computation succeed</translation>
-        </message>
-        <message>
-            <source>SMESH_CONTENT</source>
-            <translation>Content</translation>
-        </message>
-        <message>
-            <source>SMESH_CONTINUE_MESH_VISUALIZATION</source>
-            <translation>It seems that there is not enough memory to show the mesh
-so that the application may crash. Do you wish to continue visualization?</translation>
-        </message>
-        <message>
-            <source>SMESH_COORDINATES</source>
-            <translation>Coordinates</translation>
-        </message>
-        <message>
-            <source>SMESH_COPY_ELEMENTS</source>
-            <translation>Copy Elements</translation>
-        </message>
-        <message>
-            <source>SMESH_COPY_GROUPS</source>
-            <translation>Copy groups</translation>
-        </message>
-        <message>
-            <source>SMESH_CREATE_ALGORITHMS</source>
-            <translation>Create algorithms</translation>
-        </message>
-        <message>
-            <source>SMESH_CREATE_COPY</source>
-            <translation>Create a copy</translation>
-        </message>
-        <message>
-            <source>SMESH_CREATE_GROUP_TITLE</source>
-            <translation>Create Group</translation>
-        </message>
-        <message>
-            <source>SMESH_CREATE_GEO_GROUP</source>
-            <translation>Create Groups from Geometry</translation>
-        </message>
-        <message>
-            <source>SMESH_CREATE_HYPOTHESES</source>
-            <translation>Create hypotheses</translation>
-        </message>
-        <message>
-            <source>SMESH_CREATE_MESH</source>
-            <translation>Create a new mesh</translation>
-        </message>
-        <message>
-            <source>SMESH_CREATE_POLYHEDRAL_VOLUME_TITLE</source>
-            <translation>Create polyhedral volume</translation>
-        </message>
-        <message>
-            <source>SMESH_DIAGONAL</source>
-            <translation>Diagonal Inversion</translation>
-        </message>
-        <message>
-            <source>SMESH_DIAGONAL_INVERSION_TITLE</source>
-            <translation>Diagonal Inversion</translation>
-        </message>
-        <message>
-            <source>SMESH_DISTANCE</source>
-            <translation>Distance</translation>
-        </message>
-        <message>
-            <source>SMESH_DRS_1</source>
-            <translation>MED file contains no mesh with the given name</translation>
-        </message>
-        <message>
-            <source>SMESH_DRS_2</source>
-            <translation>MED file has overlapped ranges of element numbers, the numbers from the file are ignored</translation>
-        </message>
-        <message>
-            <source>SMESH_DRS_3</source>
-            <translation>Some elements were skipped due to incorrect file data</translation>
-        </message>
-        <message>
-            <source>SMESH_DRS_4</source>
-            <translation>The file is incorrect, some data is missed</translation>
-        </message>
-        <message>
-            <source>SMESH_DRS_EMPTY</source>
-            <translation>The file is empty, there is nothing to be published</translation>
-        </message>
-        <message>
-            <source>SMESH_DX</source>
-            <translation>dX</translation>
-        </message>
-        <message>
-            <source>SMESH_DY</source>
-            <translation>dY</translation>
-        </message>
-        <message>
-            <source>SMESH_DZ</source>
-            <translation>dZ</translation>
-        </message>
-        <message>
-            <source>SMESH_EDGE</source>
-            <translation>Edge</translation>
-        </message>
-        <message>
-            <source>SMESH_EDGES_CONNECTIVITY_TITLE</source>
-            <translation>Edges Connectivity</translation>
-        </message>
-        <message>
-            <source>SMESH_EDIT_GROUP_TITLE</source>
-            <translation>Edit Group</translation>
-        </message>
-        <message>
-            <source>SMESH_EDIT_GEOMGROUP_AS_GROUP_TITLE</source>
-            <translation>Edit Group as Standalone</translation>
-        </message>
-        <message>
-            <source>SMESH_EDIT_HYPOTHESES</source>
-            <translation>Hypotheses Assignation</translation>
-        </message>
-        <message>
-            <source>SMESH_EDIT_USED</source>
-            <translation>Used</translation>
-        </message>
-        <message>
-            <source>SMESH_ELEMENTS</source>
-            <translation>Elements</translation>
-        </message>
-        <message>
-            <source>SMESH_ELEMENTS_COLOR</source>
-            <translation>Mesh Element Color</translation>
-        </message>
-        <message>
-            <source>SMESH_ELEMENTS_TYPE</source>
-            <translation>Elements Type</translation>
-        </message>
-        <message>
-            <source>SMESH_ELEMENT_TYPE</source>
-            <translation>Element Type</translation>
-        </message>
-        <message>
-            <source>SMESH_ERROR</source>
-            <translation>Error</translation>
-        </message>
-        <message>
-            <source>SMESH_ERR_SCALARBAR_PARAMS</source>
-            <translation>Warning! The parameters is incorrect</translation>
-        </message>
-        <message>
-            <source>SMESH_EXPORT_FAILED</source>
-            <translation>Mesh export failed.
-Probably, there is not enough space on disk.</translation>
-        </message>
-        <message>
-            <source>SMESH_EXPORT_MED_DUPLICATED_GRP</source>
-            <translation>There are duplicated group names in mesh "%1".
-You can cancel exporting and rename them,
-otherwise some group names in the resulting MED file
-will not match ones in the study.
-Do you want to continue ?</translation>
-        </message>
-        <message>
-            <source>SMESH_EXPORT_MED_V2_1</source>
-            <translation>During export mesh with name - "%1" to MED 2.1
-polygons and polyhedrons elements will be missed
-For correct export use MED 2.2
-Are you sure want to export to MED 2.1 ?</translation>
-        </message>
-        <message>
-            <source>SMESH_EXPORT_STL1</source>
-            <translation>Mesh  - "%1" does not contain triangles</translation>
-        </message>
-        <message>
-            <source>SMESH_EXPORT_STL2</source>
-            <translation>Mesh  - "%1" contains another than triangles elements,     they are ignored during writing to STL</translation>
-        </message>
-        <message>
-            <source>SMESH_EXPORT_UNV</source>
-            <translation>During export mesh with name - "%1" to UNV
-       pyramid's elements will be missed</translation>
-        </message>
-        <message>
-            <source>SMESH_EXTRUSION</source>
-            <translation>Extrusion</translation>
-        </message>
-        <message>
-            <source>SMESH_FACE</source>
-            <translation>Face</translation>
-        </message>
-        <message>
-            <source>SMESH_FEATUREANGLE</source>
-            <translation>Feature Angle</translation>
-        </message>
-        <message>
-            <source>SMESH_FEATUREEDGES</source>
-            <translation>Feature Edges</translation>
-        </message>
-        <message>
-            <source>SMESH_FONT_ARIAL</source>
-            <translation>Arial</translation>
-        </message>
-        <message>
-            <source>SMESH_FONT_BOLD</source>
-            <translation>Bold</translation>
-        </message>
-        <message>
-            <source>SMESH_FONT_COURIER</source>
-            <translation>Courier</translation>
-        </message>
-        <message>
-            <source>SMESH_FONT_ITALIC</source>
-            <translation>Italic</translation>
-        </message>
-        <message>
-            <source>SMESH_FONT_SCALARBAR</source>
-            <translation>Font</translation>
-        </message>
-        <message>
-            <source>SMESH_FONT_SHADOW</source>
-            <translation>Shadow</translation>
-        </message>
-        <message>
-            <source>SMESH_FONT_TIMES</source>
-            <translation>Times</translation>
-        </message>
-        <message>
-            <source>SMESH_GEOM_GROUP</source>
-            <translation>Geometry group</translation>
-        </message>
-        <message>
-            <source>SMESH_GROUP</source>
-            <translation>Group</translation>
-        </message>
-        <message>
-            <source>SMESH_GROUP_GEOMETRY</source>
-            <translation>Group on geometry</translation>
-        </message>
-        <message>
-            <source>SMESH_GROUP_SELECTED</source>
-            <translation>%1 Groups</translation>
-        </message>
-        <message>
-            <source>SMESH_GROUP_STANDALONE</source>
-            <translation>Standalone group</translation>
-        </message>
-        <message>
-            <source>SMESH_GROUP_TYPE</source>
-            <translation>Group type</translation>
-        </message>
-        <message>
-            <source>SMESH_HEIGHT</source>
-            <translation>Height:</translation>
-        </message>
-        <message>
-            <source>SMESH_HEXAS</source>
-            <translation>Hexahedron</translation>
-        </message>
-        <message>
-            <source>SMESH_HILIGHT_COLOR</source>
-            <translation>Highlight Color</translation>
-        </message>
-        <message>
-            <source>SMESH_HORIZONTAL</source>
-            <translation>Horizontal</translation>
-        </message>
-        <message>
-            <source>SMESH_HYPOTHESES</source>
-            <translation>Hypotheses</translation>
-        </message>
-        <message>
-            <source>SMESH_HYP_1</source>
-            <translation>Algorithm misses a hypothesis</translation>
-        </message>
-        <message>
-            <source>SMESH_HYP_10</source>
-            <translation>Hypothesis and submesh dimensions mismatch</translation>
-        </message>
-        <message>
-            <source>SMESH_HYP_11</source>
-            <translation>Shape is neither the main one, nor its subshape, nor a valid group</translation>
-        </message>
-        <message>
-            <source>SMESH_HYP_12</source>
-            <translation>Geomerty mismatches algorithm's expectation</translation>
-        </message>
-        <message>
-            <source>SMESH_HYP_13</source>
-            <translation>Algorithm can't work without shape</translation>
-        </message>
-        <message>
-            <source>SMESH_HYP_2</source>
-            <translation>There are concurrent hypotheses on a shape</translation>
-        </message>
-        <message>
-            <source>SMESH_HYP_3</source>
-            <translation>Hypothesis has a bad parameter value</translation>
-        </message>
-        <message>
-            <source>SMESH_HYP_4</source>
-            <translation>Submesh is ignored as there is another algorithm of upper dimension generating %1D elements</translation>
-        </message>
-        <message>
-            <source>SMESH_HYP_5</source>
-            <translation>Algorithm hides algorithm(s) of lower dimension by generating all-dimensions elements</translation>
-        </message>
-        <message>
-            <source>SMESH_HYP_6</source>
-            <translation>Unknown fatal error at hypothesis definition</translation>
-        </message>
-        <message>
-            <source>SMESH_HYP_7</source>
-            <translation>Hypothesis is not suitable in the current context</translation>
-        </message>
-        <message>
-            <source>SMESH_HYP_8</source>
-            <translation>Non-conform mesh is produced using applied hypotheses</translation>
-        </message>
-        <message>
-            <source>SMESH_HYP_9</source>
-            <translation>Such dimention hypothesis is already assigned to the shape</translation>
-        </message>
-        <message>
-            <source>SMESH_ID_DIAGONAL</source>
-            <translation>Id Edges</translation>
-        </message>
-        <message>
-            <source>SMESH_ID_ELEMENTS</source>
-            <translation>Id Elements</translation>
-        </message>
-        <message>
-            <source>SMESH_ID_FACES</source>
-            <translation>Id Faces</translation>
-        </message>
-        <message>
-            <source>SMESH_ID_NODES</source>
-            <translation>Id Nodes</translation>
-        </message>
-        <message>
-            <source>SMESH_INCORRECT_INPUT</source>
-            <translation>Incorrect input data!</translation>
-        </message>
-        <message>
-            <source>SMESH_INFORMATION</source>
-            <translation>Information</translation>
-        </message>
-        <message>
-            <source>SMESH_INIT</source>
-            <translation>Mesh</translation>
-        </message>
-        <message>
-            <source>SMESH_INIT_MESH</source>
-            <translation>Mesh Construction</translation>
-        </message>
-        <message>
-            <source>SMESH_INSUFFICIENT_DATA</source>
-            <translation>Insufficient input value</translation>
-        </message>
-        <message>
-            <source>SMESH_LABELS</source>
-            <translation>Labels:</translation>
-        </message>
-        <message>
-            <source>SMESH_LABELS_COLORS_SCALARBAR</source>
-            <translation>Colors &amp;&amp; Labels</translation>
-        </message>
-        <message>
-            <source>SMESH_LENGTH</source>
-            <translation>Length</translation>
-        </message>
-        <message>
-            <source>SMESH_MAKE_GROUPS</source>
-            <translation>Generate groups</translation>
-        </message>
-        <message>
-            <source>SMESH_MANIFOLDEDGES</source>
-            <translation>Manifold Edges</translation>
-        </message>
-        <message>
-            <source>SMESH_MAX</source>
-            <translation>Max</translation>
-        </message>
-        <message>
-            <source>SMESH_MEN_ALGORITHMS</source>
-            <translation>Algorithms</translation>
-        </message>
-        <message>
-            <source>SMESH_MEN_APPLIED_ALGORIHTMS</source>
-            <translation>Applied Algorithms</translation>
-        </message>
-        <message>
-            <source>SMESH_MEN_APPLIED_HYPOTHESIS</source>
-            <translation>Applied Hypotheses</translation>
-        </message>
-        <message>
-            <source>SMESH_MEN_COMPONENT</source>
-            <translation>SMESH</translation>
-        </message>
-        <message>
-            <source>SMESH_MEN_HYPOTHESIS</source>
-            <translation>Hypotheses</translation>
-        </message>
-        <message>
-            <source>SMESH_MEN_SubMeshesOnCompound</source>
-            <translation>SubMeshes On Compound</translation>
-        </message>
-        <message>
-            <source>SMESH_MEN_SubMeshesOnEdge</source>
-            <translation>SubMeshes On Edge</translation>
-        </message>
-        <message>
-            <source>SMESH_MEN_SubMeshesOnFace</source>
-            <translation>SubMeshes On Face</translation>
-        </message>
-        <message>
-            <source>SMESH_MEN_SubMeshesOnSolid</source>
-            <translation>SubMeshes On Solid</translation>
-        </message>
-        <message>
-            <source>SMESH_MEN_SubMeshesOnVertex</source>
-            <translation>SubMeshes On Vertex</translation>
-        </message>
-        <message>
-            <source>SMESH_MERGE_ELEMENTS</source>
-            <translation>Merge elements</translation>
-        </message>
-        <message>
-            <source>SMESH_MERGE_NODES</source>
-            <translation>Merge nodes</translation>
-        </message>
-        <message>
-            <source>SMESH_MESH</source>
-            <translation>Mesh</translation>
-        </message>
-        <message>
-            <source>SMESH_MESHINFO_ALL_TYPES</source>
-            <translation>Heterogenous</translation>
-        </message>
-        <message>
-            <source>SMESH_MESHINFO_EDGES</source>
-            <translation>Edges</translation>
-        </message>
-        <message>
-            <source>SMESH_MESHINFO_ELEMENTS</source>
-            <translation>Elements</translation>
-        </message>
-        <message>
-            <source>SMESH_MESHINFO_ENTITIES</source>
-            <translation>Entities</translation>
-        </message>
-        <message>
-            <source>SMESH_MESHINFO_FACES</source>
-            <translation>Faces</translation>
-        </message>
-        <message>
-            <source>SMESH_MESHINFO_HEXAS</source>
-            <translation>Hexahedrons</translation>
-        </message>
-        <message>
-            <source>SMESH_MESHINFO_NAME</source>
-            <translation>Name</translation>
-        </message>
-        <message>
-            <source>SMESH_MESHINFO_NODES</source>
-            <translation>Nodes</translation>
-        </message>
-        <message>
-            <source>SMESH_MESHINFO_ORDER0</source>
-            <translation>Total</translation>
-        </message>
-        <message>
-            <source>SMESH_MESHINFO_ORDER1</source>
-            <translation>Linear</translation>
-        </message>
-        <message>
-            <source>SMESH_MESHINFO_ORDER2</source>
-            <translation>Quadratic</translation>
-        </message>
-        <message>
-            <source>SMESH_MESHINFO_POLYEDRES</source>
-            <translation>Polyhedrons</translation>
-        </message>
-        <message>
-            <source>SMESH_MESHINFO_POLYGONES</source>
-            <translation>Polygons</translation>
-        </message>
-        <message>
-            <source>SMESH_MESHINFO_PRISMS</source>
-            <translation>Prisms</translation>
-        </message>
-        <message>
-            <source>SMESH_MESHINFO_PYRAS</source>
-            <translation>Pyramids</translation>
-        </message>
-        <message>
-            <source>SMESH_MESHINFO_QUADRANGLES</source>
-            <translation>Quadrangles</translation>
-        </message>
-        <message>
-            <source>SMESH_MESHINFO_TETRAS</source>
-            <translation>Tetrahedrons</translation>
-        </message>
-        <message>
-            <source>SMESH_MESHINFO_TITLE</source>
-            <translation>Mesh Infos</translation>
-        </message>
-        <message>
-            <source>SMESH_MESHINFO_TOTAL</source>
-            <translation>Total</translation>
-        </message>
-        <message>
-            <source>SMESH_MESHINFO_TRIANGLES</source>
-            <translation>Triangles</translation>
-        </message>
-        <message>
-            <source>SMESH_MESHINFO_TYPE</source>
-            <translation>Type</translation>
-        </message>
-        <message>
-            <source>SMESH_MESHINFO_VOLUMES</source>
-            <translation>Volumes</translation>
-        </message>
-        <message>
-            <source>SMESH_MIN</source>
-            <translation>Min</translation>
-        </message>
-        <message>
-            <source>SMESH_MOVE</source>
-            <translation>Move</translation>
-        </message>
-        <message>
-            <source>SMESH_MOVE_ELEMENTS</source>
-            <translation>Move Elements</translation>
-        </message>
-        <message>
-            <source>SMESH_MOVE_NODES_TITLE</source>
-            <translation>Move Node</translation>
-        </message>
-        <message>
-            <source>SMESH_NAME</source>
-            <translation>Name</translation>
-        </message>
-        <message>
-            <source>SMESH_NODES</source>
-            <translation>Nodes</translation>
-        </message>
-        <message>
-            <source>SMESH_NONMANIFOLDEDGES</source>
-            <translation>Non Manifold Edges</translation>
-        </message>
-        <message>
-            <source>SMESH_NORMAL</source>
-            <translation>Normal</translation>
-        </message>
-        <message>
-            <source>SMESH_NO_MESH_VISUALIZATION</source>
-            <translation>There is not enough memory to show the mesh</translation>
-        </message>
-        <message>
-            <source>SMESH_NUMBEROFCOLORS</source>
-            <translation>Nb of colors:</translation>
-        </message>
-        <message>
-            <source>SMESH_NUMBEROFLABELS</source>
-            <translation>Nb of labels:</translation>
-        </message>
-        <message>
-            <source>SMESH_NUMBEROFSTEPS</source>
-            <translation>Number of steps:</translation>
-        </message>
-        <message>
-            <source>SMESH_OBJECTS_SELECTED</source>
-            <translation>%1_objects</translation>
-        </message>
-        <message>
-            <source>SMESH_OBJECT_ALGORITHM</source>
-            <translation>Algorithm</translation>
-        </message>
-        <message>
-            <source>SMESH_OBJECT_GEOM</source>
-            <translation>Geometrical Object</translation>
-        </message>
-        <message>
-            <source>SMESH_OBJECT_HYPOTHESIS</source>
-            <translation>Hypothesis</translation>
-        </message>
-        <message>
-            <source>SMESH_OBJECT_MESH</source>
-            <translation>Mesh</translation>
-        </message>
-        <message>
-            <source>SMESH_OBJECT_MESHorSUBMESH</source>
-            <translation>Mesh or SubMesh</translation>
-        </message>
-        <message>
-            <source>SMESH_OPERATION_FAILED</source>
-            <translation>Operation failed</translation>
-        </message>
-        <message>
-            <source>SMESH_ORIENTATION</source>
-            <translation>Orientation</translation>
-        </message>
-        <message>
-            <source>SMESH_ORIENTATION_ELEMENTS_TITLE</source>
-            <translation>Change Orientation</translation>
-        </message>
-        <message>
-            <source>SMESH_OUTLINE_COLOR</source>
-            <translation>Mesh Object Color</translation>
-        </message>
-        <message>
-            <source>SMESH_PARAMETERS</source>
-            <translation>Parameters</translation>
-        </message>
-        <message>
-            <source>SMESH_PLANE</source>
-            <translation>Plane</translation>
-        </message>
-        <message>
-            <source>SMESH_POINT</source>
-            <translation>Point</translation>
-        </message>
-        <message>
-            <source>SMESH_POINT_1</source>
-            <translation>Point 1</translation>
-        </message>
-        <message>
-            <source>SMESH_POINT_2</source>
-            <translation>Point 2</translation>
-        </message>
-        <message>
-            <source>SMESH_POLYEDRE_CREATE_ERROR</source>
-            <translation>Polyedron creation error</translation>
-        </message>
-        <message>
-            <source>SMESH_POLYEDRON</source>
-            <translation>Polyhedron</translation>
-        </message>
-        <message>
-            <source>SMESH_POLYGON</source>
-            <translation>Polygon</translation>
-        </message>
-        <message>
-            <source>SMESH_POSITION_SIZE_SCALARBAR</source>
-            <translation>Origin &amp;&amp; Size</translation>
-        </message>
-        <message>
-            <source>SMESH_PRECISION</source>
-            <translation>Precision</translation>
-        </message>
-        <message>
-            <source>SMESH_PREFERENCES_SCALARBAR</source>
-            <translation>Scalar Bar Preferences</translation>
-        </message>
-        <message>
-            <source>SMESH_PREF_SELECTION</source>
-            <translation>Preferences - Selection</translation>
-        </message>
-        <message>
-            <source>SMESH_PRESELECTION</source>
-            <translation>Preselection</translation>
-        </message>
-        <message>
-            <source>SMESH_PRISM</source>
-            <translation>Prism</translation>
-        </message>
-        <message>
-            <source>SMESH_PROPERTIES_SCALARBAR</source>
-            <translation>Scalar Bar Properties</translation>
-        </message>
-        <message>
-            <source>SMESH_PYRAMID</source>
-            <translation>Pyramid</translation>
-        </message>
-        <message>
-            <source>SMESH_QUADRANGLE</source>
-            <translation>Quadrangle</translation>
-        </message>
-        <message>
-            <source>SMESH_QUADRATIC_EDGE</source>
-            <translation>Quadratic Edge</translation>
-        </message>
-        <message>
-            <source>SMESH_QUADRATIC_HEXAHEDRON</source>
-            <translation>Quadratic Hexahedron</translation>
-        </message>
-        <message>
-            <source>SMESH_QUADRATIC_PENTAHEDRON</source>
-            <translation>Quadratic Pentahedron</translation>
-        </message>
-        <message>
-            <source>SMESH_QUADRATIC_PYRAMID</source>
-            <translation>Quadratic Pyramid</translation>
-        </message>
-        <message>
-            <source>SMESH_QUADRATIC_QUADRANGLE</source>
-            <translation>Quadratic Quadrangle</translation>
-        </message>
-        <message>
-            <source>SMESH_QUADRATIC_TETRAHEDRON</source>
-            <translation>Quadratic Tetrahedron</translation>
-        </message>
-        <message>
-            <source>SMESH_QUADRATIC_TRIANGLE</source>
-            <translation>Quadratic Triangle</translation>
-        </message>
-        <message>
-            <source>SMESH_RANGE_MAX</source>
-            <translation>Max value:</translation>
-        </message>
-        <message>
-            <source>SMESH_RANGE_MIN</source>
-            <translation>Min value:</translation>
-        </message>
-        <message>
-            <source>SMESH_RANGE_SCALARBAR</source>
-            <translation>Scalar Range</translation>
-        </message>
-        <message>
-            <source>SMESH_REALLY_DELETE</source>
-            <translation>Do you really want to delete this %1 object(s)? : %2</translation>
-        </message>
-        <message>
-            <source>SMESH_REMOVE</source>
-            <translation>Remove</translation>
-        </message>
-        <message>
-            <source>SMESH_REMOVE_ELEMENTS_TITLE</source>
-            <translation>Remove Elements</translation>
-        </message>
-        <message>
-            <source>SMESH_REMOVE_NODES_TITLE</source>
-            <translation>Remove Nodes</translation>
-        </message>
-        <message>
-            <source>SMESH_RENUMBERING</source>
-            <translation>Renumbering</translation>
-        </message>
-        <message>
-            <source>SMESH_RENUMBERING_ELEMENTS_TITLE</source>
-            <translation>Renumbering elements</translation>
-        </message>
-        <message>
-            <source>SMESH_RENUMBERING_NODES_TITLE</source>
-            <translation>Renumbering nodes</translation>
-        </message>
-        <message>
-            <source>SMESH_REVERSE</source>
-            <translation>Reverse</translation>
-        </message>
-        <message>
-            <source>SMESH_REVOLUTION</source>
-            <translation>Revolution</translation>
-        </message>
-        <message>
-            <source>SMESH_RM_HYP_WRN</source>
-            <translation>"%1" unassigned but:
+    </message>
+    <message>
+        <source>SMESH_WRN_WARNING</source>
+        <translation>Warning</translation>
+    </message>
+    <message>
+        <source>SMESH_X</source>
+        <translation>X</translation>
+    </message>
+    <message>
+        <source>SMESH_X_SCALARBAR</source>
+        <translation>X:</translation>
+    </message>
+    <message>
+        <source>SMESH_Y</source>
+        <translation>Y</translation>
+    </message>
+    <message>
+        <source>SMESH_Y_SCALARBAR</source>
+        <translation>Y:</translation>
+    </message>
+    <message>
+        <source>SMESH_Z</source>
+        <translation>Z</translation>
+    </message>
+    <message>
+        <source>STATE_ALGO_MISSING</source>
+        <translation>%3 %2D algorithm is missing</translation>
+    </message>
+    <message>
+        <source>STATE_HYP_BAD_GEOMETRY</source>
+        <translation>%3 %2D algorithm &quot;%1&quot; is assigned to geometry mismatching its expectation</translation>
+    </message>
+    <message>
+        <source>STATE_HYP_BAD_PARAMETER</source>
+        <translation>Hypothesis of %3 %2D algorithm &quot;%1&quot; has a bad parameter value</translation>
+    </message>
+    <message>
+        <source>STATE_HYP_MISSING</source>
+        <translation>%3 %2D algorithm &quot;%1&quot; misses %4D hypothesis</translation>
+    </message>
+    <message>
+        <source>STATE_HYP_NOTCONFORM</source>
+        <translation>%3 %2D algorithm &quot;%1&quot; would produce not conform mesh: global &quot;Not Conform Mesh Allowed&quot; hypotesis is missing</translation>
+    </message>
+    <message>
+        <source>STB_ADV_INFO</source>
+        <translation>Show base information about the mesh object</translation>
+    </message>
+    <message>
+        <source>STB_ALL</source>
+        <translation>All</translation>
+    </message>
+    <message>
+        <source>STB_AREA</source>
+        <translation>Area</translation>
+    </message>
+    <message>
+        <source>STB_ASPECT</source>
+        <translation>Aspect Ratio</translation>
+    </message>
+    <message>
+        <source>STB_ASPECT_3D</source>
+        <translation>Aspect Ratio 3D</translation>
+    </message>
+    <message>
+        <source>STB_AUTO_COLOR</source>
+        <translation>Auto color</translation>
+    </message>
+    <message>
+        <source>STB_AUTO_UPD</source>
+        <translation>Automatic update</translation>
+    </message>
+    <message>
+        <source>STB_BUILD_COMPOUND</source>
+        <translation>Build Compound Mesh</translation>
+    </message>
+    <message>
+        <source>STB_COPY_MESH</source>
+        <translation>Copy Mesh</translation>
+    </message>
+    <message>
+        <source>STB_CLIP</source>
+        <translation>Clipping</translation>
+    </message>
+    <message>
+        <source>STB_COLORS</source>
+        <translation>Properties</translation>
+    </message>
+    <message>
+        <source>STB_COMPUTE</source>
+        <translation>Compute</translation>
+    </message>
+    <message>
+        <source>STB_PRECOMPUTE</source>
+        <translation>Preview</translation>
+    </message>
+    <message>
+        <source>STB_EVALUATE</source>
+        <translation>Evaluate</translation>
+    </message>
+    <message>
+        <source>STB_CONNECTION</source>
+        <translation>Borders at Multi-Connection</translation>
+    </message>
+    <message>
+        <source>STB_CONNECTION_2D</source>
+        <translation>Borders at Multi-Connection 2D</translation>
+    </message>
+    <message>
+        <source>STB_CONSTRUCT_GROUP</source>
+        <translation>Construct Group</translation>
+    </message>
+    <message>
+        <source>STB_CONV_TO_QUAD</source>
+        <translation>Convert to/from quadratic</translation>
+    </message>
+    <message>
+        <source>STB_2D_FROM_3D</source>
+        <translation>Create boundary elements</translation>
+    </message>
+    <message>
+        <source>STB_MESH_ORDER</source>
+        <translation>Change submesh priority</translation>
+    </message>
+    <message>
+        <source>STB_CREATE_GROUP</source>
+        <translation>Create Group</translation>
+    </message>
+    <message>
+        <source>STB_CREATE_GEO_GROUP</source>
+        <translation>Create Group from Geometry</translation>
+    </message>
+    <message>
+        <source>STB_CREATE_MESH</source>
+        <translation>Create Mesh</translation>
+    </message>
+    <message>
+        <source>STB_CREATE_SUBMESH</source>
+        <translation>Create Sub-mesh</translation>
+    </message>
+    <message>
+        <source>STB_CUT</source>
+        <translation>Cutting of quadrangles</translation>
+    </message>
+    <message>
+        <source>STB_CUT_GROUP</source>
+        <translation>Cut Groups</translation>
+    </message>
+    <message>
+        <source>STB_DAT</source>
+        <translation>Export DAT file</translation>
+    </message>
+    <message>
+        <source>STB_IMPORT_DAT</source>
+        <translation>Import DAT file</translation>
+    </message>
+    <message>
+        <source>STB_DELETE</source>
+        <translation>Delete</translation>
+    </message>
+    <message>
+        <source>STB_DEL_GROUP</source>
+        <translation>Delete Groups with Contents</translation>
+    </message>
+    <message>
+        <source>STB_FACE_ORIENTATION</source>
+        <translation>Orientation of faces</translation>
+    </message>
+    <message>
+        <source>STB_DISABLE_AUTO_COLOR</source>
+        <translation>Disable auto color</translation>
+    </message>
+    <message>
+        <source>STB_DISPLAY_ONLY</source>
+        <translation>Show only</translation>
+    </message>
+    <message>
+        <source>STB_DISP_ENT</source>
+        <translation>Display entity</translation>
+    </message>
+    <message>
+        <source>STB_ELEM0D</source>
+        <translation>0D Element</translation>
+    </message>
+    <message>
+        <source>STB_ELEMS0D</source>
+        <translation>0D Elements</translation>
+    </message>
+    <message>
+        <source>STB_BALLS</source>
+        <translation>Ball Elements</translation>
+    </message>
+    <message>
+        <source>STB_BALL</source>
+        <translation>Ball Element</translation>
+    </message>
+    <message>
+        <source>STB_EDGE</source>
+        <translation>Edge</translation>
+    </message>
+    <message>
+        <source>STB_EDGES</source>
+        <translation>Edges</translation>
+    </message>
+    <message>
+        <source>STB_EDIT_GROUP</source>
+        <translation>Edit Group</translation>
+    </message>
+    <message>
+        <source>STB_EDIT_GEOMGROUP_AS_GROUP</source>
+        <translation>Edit Group as Standalone</translation>
+    </message>
+    <message>
+        <source>STB_EDIT_HYPO</source>
+        <translation>Edit Hypothesis</translation>
+    </message>
+    <message>
+        <source>STB_EDIT_MESHSUBMESH</source>
+        <translation>Edit Mesh/Sub-mesh</translation>
+    </message>
+    <message>
+        <source>STB_EXPORT_DAT</source>
+        <translation>Export to DAT file</translation>
+    </message>
+    <message>
+        <source>STB_EXPORT_MED</source>
+        <translation>Export to MED file</translation>
+    </message>
+    <message>
+        <source>STB_EXPORT_CGNS</source>
+        <translation>Export to CGNS file</translation>
+    </message>
+    <message>
+        <source>STB_EXPORT_SAUV</source>
+        <translation>Export to SAUV file</translation>
+    </message>
+    <message>
+        <source>STB_EXPORT_STL</source>
+        <translation>Export to STL file</translation>
+    </message>
+    <message>
+        <source>STB_EXPORT_UNV</source>
+        <translation>Export to UNV file</translation>
+    </message>
+    <message>
+        <source>STB_EXTRUSION</source>
+        <translation>Extrusion</translation>
+    </message>
+    <message>
+        <source>STB_EXTRUSION_ALONG</source>
+        <translation>Extrusion along a path</translation>
+    </message>
+    <message>
+        <source>STB_FACES</source>
+        <translation>Faces</translation>
+    </message>
+    <message>
+        <source>STB_BARE_BORDER_VOLUME</source>
+        <translation>Volumes with bare border</translation>
+    </message>
+    <message>
+        <source>STB_BARE_BORDER_FACE</source>
+        <translation>Faces with bare border</translation>
+    </message>
+    <message>
+        <source>STB_OVER_CONSTRAINED_VOLUME</source>
+        <translation>Over-constrained volumes</translation>
+    </message>
+    <message>
+        <source>STB_OVER_CONSTRAINED_FACE</source>
+        <translation>Over-constrained faces</translation>
+    </message>
+    <message>
+        <source>STB_FREE_BORDER</source>
+        <translation>Free Borders</translation>
+    </message>
+    <message>
+        <source>STB_FREE_EDGE</source>
+        <translation>Free Edges</translation>
+    </message>
+    <message>
+        <source>STB_FREE_NODE</source>
+        <translation>Free Nodes</translation>
+    </message>
+    <message>
+        <source>STB_FREE_FACES</source>
+        <translation>Free Faces</translation>
+    </message>
+    <message>
+        <source>STB_GLOBAL_HYPO</source>
+        <translation>Global Hypothesis</translation>
+    </message>
+    <message>
+        <source>STB_HEXA</source>
+        <translation>Hexahedron</translation>
+    </message>
+    <message>
+        <source>STB_HIDE</source>
+        <translation>Hide</translation>
+    </message>
+    <message>
+        <source>STB_INT_GROUP</source>
+        <translation>Intersect Groups</translation>
+    </message>
+    <message>
+        <source>STB_INV</source>
+        <translation>Diagonal Inversion</translation>
+    </message>
+    <message>
+        <source>STB_LENGTH</source>
+        <translation>Length</translation>
+    </message>
+    <message>
+        <source>STB_LENGTH_2D</source>
+        <translation>Length 2D</translation>
+    </message>
+    <message>
+        <source>STB_MAP</source>
+        <translation>Pattern mapping</translation>
+    </message>
+    <message>
+        <source>STB_MAX_ELEMENT_LENGTH_2D</source>
+        <translation>Element Diameter 2D</translation>
+    </message>
+    <message>
+        <source>STB_MAX_ELEMENT_LENGTH_3D</source>
+        <translation>Element Diameter 3D</translation>
+    </message>
+    <message>
+        <source>STB_IMPORT_MED</source>
+        <translation>Import MED file</translation>
+    </message>
+    <message>
+        <source>STB_MED</source>
+        <translation>Export MED file</translation>
+    </message>
+    <message>
+        <source>STB_IMPORT_STL</source>
+        <translation>Import STL file</translation>
+    </message>
+    <message>
+        <source>STB_STL</source>
+        <translation>Export STL file</translation>
+    </message>
+    <message>
+        <source>STB_IMPORT_CGNS</source>
+        <translation>Import CGNS file</translation>
+    </message>
+    <message>
+        <source>STB_CGNS</source>
+        <translation>Export CGNS file</translation>
+    </message>
+    <message>
+        <source>STB_IMPORT_SAUV</source>
+        <translation>Import SAUV file</translation>
+    </message>
+    <message>
+        <source>STB_SAUV</source>
+        <translation>Export SAUV file</translation>
+    </message>
+    <message>
+        <source>STB_MERGE</source>
+        <translation>Merge nodes</translation>
+    </message>
+    <message>
+        <source>STB_MERGE_ELEMENTS</source>
+        <translation>Merge elements</translation>
+    </message>
+    <message>
+        <source>STB_MESH_THROU_POINT</source>
+        <translation>Move Node</translation>
+    </message>
+    <message>
+        <source>STB_MIN_ANG</source>
+        <translation>Minimum Angle</translation>
+    </message>
+    <message>
+        <source>STB_MOVE</source>
+        <translation>Move Node</translation>
+    </message>
+    <message>
+        <source>STB_NODE</source>
+        <translation>Node</translation>
+    </message>
+    <message>
+        <source>STB_NODES</source>
+        <translation>Nodes</translation>
+    </message>
+    <message>
+        <source>STB_NUM_ELEMENTS</source>
+        <translation>Display Elements</translation>
+    </message>
+    <message>
+        <source>STB_NUM_NODES</source>
+        <translation>Display Nodes</translation>
+    </message>
+    <message>
+        <source>STB_ORIENT</source>
+        <translation>Orientation</translation>
+    </message>
+    <message>
+        <source>STB_POLYGON</source>
+        <translation>Polygon</translation>
+    </message>
+    <message>
+        <source>STB_POLYHEDRON</source>
+        <translation>Polyhedron</translation>
+    </message>
+    <message>
+        <source>STB_PRECISION</source>
+        <translation>Precision</translation>
+    </message>
+    <message>
+        <source>STB_QUAD</source>
+        <translation>Quadrangle</translation>
+    </message>
+    <message>
+        <source>STB_QUADRATIC_EDGE</source>
+        <translation>Quadratic Edge</translation>
+    </message>
+    <message>
+        <source>STB_QUADRATIC_HEXAHEDRON</source>
+        <translation>Quadratic Hexahedron</translation>
+    </message>
+    <message>
+        <source>STB_QUADRATIC_PENTAHEDRON</source>
+        <translation>Quadratic Pentahedron</translation>
+    </message>
+    <message>
+        <source>STB_QUADRATIC_PYRAMID</source>
+        <translation>Quadratic Pyramid</translation>
+    </message>
+    <message>
+        <source>STB_QUADRATIC_QUADRANGLE</source>
+        <translation>Quadratic Quadrangle</translation>
+    </message>
+    <message>
+        <source>STB_QUADRATIC_TETRAHEDRON</source>
+        <translation>Quadratic Tetrahedron</translation>
+    </message>
+    <message>
+        <source>STB_QUADRATIC_TRIANGLE</source>
+        <translation>Quadratic Triangle</translation>
+    </message>
+    <message>
+        <source>STB_REMOVE_ELEMENTS</source>
+        <translation>Remove elements</translation>
+    </message>
+    <message>
+        <source>STB_REMOVE_NODES</source>
+        <translation>Remove nodes</translation>
+    </message>
+    <message>
+        <source>STB_REMOVE_ORPHAN_NODES</source>
+        <translation>Remove orphan nodes</translation>
+    </message>
+    <message>
+        <source>STB_RENAME</source>
+        <translation>Rename</translation>
+    </message>
+    <message>
+        <source>STB_RENUM_ELEMENTS</source>
+        <translation>Renumbering elements</translation>
+    </message>
+    <message>
+        <source>STB_RENUM_NODES</source>
+        <translation>Renumbering nodes</translation>
+    </message>
+    <message>
+        <source>STB_RESET</source>
+        <translation>Reset</translation>
+    </message>
+    <message>
+        <source>STB_SAVE_DISTRIBUTION</source>
+        <translation>Save distribution to the file</translation>
+    </message>
+    <message>
+        <source>STB_SHOW_DISTRIBUTION</source>
+        <translation>Show Distribution</translation>
+    </message>
+    <message>
+        <source>STB_REVOLUTION</source>
+        <translation>Revolution</translation>
+    </message>
+    <message>
+        <source>STB_ROT</source>
+        <translation>Rotation</translation>
+    </message>
+    <message>
+        <source>STB_SCALAR_BAR</source>
+        <translation>Scalar bar</translation>
+    </message>
+    <message>
+        <source>STB_SCALAR_BAR_PROP</source>
+        <translation>Scalar bar Properties</translation>
+    </message>
+    <message>
+        <source>STB_SELECTION</source>
+        <translation>Selection</translation>
+    </message>
+    <message>
+        <source>STB_SEL_FILTER_LIB</source>
+        <translation>Selection filters library</translation>
+    </message>
+    <message>
+        <source>STB_SEW</source>
+        <translation>Sewing</translation>
+    </message>
+    <message>
+        <source>STB_SHADE</source>
+        <translation>Shading</translation>
+    </message>
+    <message>
+        <source>STB_SHOW</source>
+        <translation>Show</translation>
+    </message>
+    <message>
+        <source>STB_SHRINK</source>
+        <translation>Shrink</translation>
+    </message>
+    <message>
+        <source>STB_SKEW</source>
+        <translation>Skew</translation>
+    </message>
+    <message>
+        <source>STB_SMOOTH</source>
+        <translation>Smoothing</translation>
+    </message>
+    <message>
+        <source>STB_STD_INFO</source>
+        <translation>Standard Mesh Infos</translation>
+    </message>
+    <message>
+        <source>STB_SYM</source>
+        <translation>Symmetry</translation>
+    </message>
+    <message>
+        <source>STB_TAPER</source>
+        <translation>Taper</translation>
+    </message>
+    <message>
+        <source>STB_TETRA</source>
+        <translation>Tetrahedron</translation>
+    </message>
+    <message>
+        <source>STB_TRANS</source>
+        <translation>Translation</translation>
+    </message>
+    <message>
+        <source>STB_SCALE</source>
+        <translation>Scale Transform</translation>
+    </message>
+    <message>
+        <source>STB_DUPLICATE_NODES</source>
+        <translation>Duplicate Nodes</translation>
+    </message>
+    <message>
+        <source>STB_TRANSP</source>
+        <translation>Transparency</translation>
+    </message>
+    <message>
+        <source>STB_TRIANGLE</source>
+        <translation>Triangle</translation>
+    </message>
+    <message>
+        <source>STB_UNASSIGN</source>
+        <translation>Unassign</translation>
+    </message>
+    <message>
+        <source>STB_UNION</source>
+        <translation>Union of triangles</translation>
+    </message>
+    <message>
+        <source>STB_UNION2</source>
+        <translation>Union of two triangles</translation>
+    </message>
+    <message>
+        <source>STB_IMPORT_UNV</source>
+        <translation>Import UNV file</translation>
+    </message>
+    <message>
+        <source>STB_UNV</source>
+        <translation>Export UNV file</translation>
+    </message>
+    <message>
+        <source>STB_UN_GROUP</source>
+        <translation>Union Groups</translation>
+    </message>
+    <message>
+        <source>STB_UNDERLYING_ELEMS</source>
+        <translation>Create groups of entities from existing groups of superior dimensions</translation>
+    </message>
+    <message>
+        <source>STB_UPDATE</source>
+        <translation>Update</translation>
+    </message>
+    <message>
+        <source>STB_VOLUMES</source>
+        <translation>Volumes</translation>
+    </message>
+    <message>
+        <source>STB_VOLUME_3D</source>
+        <translation>Volume</translation>
+    </message>
+    <message>
+        <source>STB_WARP</source>
+        <translation>Warping angle</translation>
+    </message>
+    <message>
+        <source>STB_WHAT_IS</source>
+        <translation>Show information about the mesh node or element</translation>
+    </message>
+    <message>
+        <source>STB_WIRE</source>
+        <translation>Wireframe</translation>
+    </message>
+    <message>
+        <source>TAPER_ELEMENTS</source>
+        <translation>Taper</translation>
+    </message>
+    <message>
+        <source>TB_ADD_REMOVE</source>
+        <translation>Add/Remove Toolbar</translation>
+    </message>
+    <message>
+        <source>TB_CTRL</source>
+        <translation>Controls Toolbar</translation>
+    </message>
+    <message>
+        <source>TB_DISP_MODE</source>
+        <translation>Display Mode Toolbar</translation>
+    </message>
+    <message>
+        <source>TB_HYPO</source>
+        <translation>Hypotheses Toolbar</translation>
+    </message>
+    <message>
+        <source>TB_MESH</source>
+        <translation>Mesh Toolbar</translation>
+    </message>
+    <message>
+        <source>TB_MODIFY</source>
+        <translation>Modification Toolbar</translation>
+    </message>
+    <message>
+        <source>TOP_ADV_INFO</source>
+        <translation>Mesh Information</translation>
+    </message>
+    <message>
+        <source>TOP_ALL</source>
+        <translation>All</translation>
+    </message>
+    <message>
+        <source>TOP_AREA</source>
+        <translation>Area</translation>
+    </message>
+    <message>
+        <source>TOP_ASPECT</source>
+        <translation>Aspect Ratio</translation>
+    </message>
+    <message>
+        <source>TOP_ASPECT_3D</source>
+        <translation>Aspect Ratio 3D</translation>
+    </message>
+    <message>
+        <source>TOP_AUTO_COLOR</source>
+        <translation>Auto color</translation>
+    </message>
+    <message>
+        <source>TOP_AUTO_UPD</source>
+        <translation>Automatic update</translation>
+    </message>
+    <message>
+        <source>TOP_BUILD_COMPOUND</source>
+        <translation>Build Compound Mesh</translation>
+    </message>
+    <message>
+        <source>TOP_COPY_MESH</source>
+        <translation>Copy Mesh</translation>
+    </message>
+    <message>
+        <source>TOP_CLIP</source>
+        <translation>Clipping</translation>
+    </message>
+    <message>
+        <source>TOP_COLORS</source>
+        <translation>Properties</translation>
+    </message>
+    <message>
+        <source>TOP_COMPUTE</source>
+        <translation>Compute</translation>
+    </message>
+    <message>
+        <source>TOP_PRECOMPUTE</source>
+        <translation>Preview</translation>
+    </message>
+    <message>
+        <source>TOP_EVALUATE</source>
+        <translation>Evaluate</translation>
+    </message>
+    <message>
+        <source>TOP_CONNECTION</source>
+        <translation>Borders at Multi-Connection</translation>
+    </message>
+    <message>
+        <source>TOP_CONNECTION_2D</source>
+        <translation>Borders at Multi-Connection 2D</translation>
+    </message>
+    <message>
+        <source>TOP_CONSTRUCT_GROUP</source>
+        <translation>Construct Group</translation>
+    </message>
+    <message>
+        <source>TOP_CONV_TO_QUAD</source>
+        <translation>Convert to/from quadratic</translation>
+    </message>
+    <message>
+        <source>TOP_2D_FROM_3D</source>
+        <translation>Create boundary elements</translation>
+    </message>
+    <message>
+        <source>TOP_MESH_ORDER</source>
+        <translation>Change submesh priority</translation>
+    </message>
+    <message>
+        <source>TOP_CREATE_GROUP</source>
+        <translation>Create Group</translation>
+    </message>
+    <message>
+        <source>TOP_CREATE_GEO_GROUP</source>
+        <translation>Create Groups from Geometry</translation>
+    </message>
+    <message>
+        <source>TOP_CREATE_MESH</source>
+        <translation>Create Mesh</translation>
+    </message>
+    <message>
+        <source>TOP_CREATE_SUBMESH</source>
+        <translation>Create Sub-mesh</translation>
+    </message>
+    <message>
+        <source>TOP_CUT</source>
+        <translation>Cutting of quadrangles</translation>
+    </message>
+    <message>
+        <source>TOP_CUT_GROUP</source>
+        <translation>Cut Groups</translation>
+    </message>
+    <message>
+        <source>TOP_IMPORT_DAT</source>
+        <translation>Import DAT file</translation>
+    </message>
+    <message>
+        <source>TOP_DAT</source>
+        <translation>Export DAT file</translation>
+    </message>
+    <message>
+        <source>TOP_DELETE</source>
+        <translation>Delete</translation>
+    </message>
+    <message>
+        <source>TOP_DEL_GROUP</source>
+        <translation>Delete Groups with Contents</translation>
+    </message>
+    <message>
+        <source>TOP_FACE_ORIENTATION</source>
+        <translation>Orientation of faces</translation>
+    </message>
+    <message>
+        <source>TOP_DISABLE_AUTO_COLOR</source>
+        <translation>Disable auto color</translation>
+    </message>
+    <message>
+        <source>TOP_DISPLAY_ONLY</source>
+        <translation>Show only</translation>
+    </message>
+    <message>
+        <source>TOP_DISP_ENT</source>
+        <translation>Display entity</translation>
+    </message>
+    <message>
+        <source>TOP_ELEM0D</source>
+        <translation>0D Element</translation>
+    </message>
+    <message>
+        <source>TOP_ELEMS0D</source>
+        <translation>0D Elements</translation>
+    </message>
+    <message>
+        <source>TOP_BALL</source>
+        <translation>Ball</translation>
+    </message>
+    <message>
+        <source>TOP_BALLS</source>
+        <translation>Balls</translation>
+    </message>
+    <message>
+        <source>TOP_EDGE</source>
+        <translation>Edge</translation>
+    </message>
+    <message>
+        <source>TOP_EDGES</source>
+        <translation>Edges</translation>
+    </message>
+    <message>
+        <source>TOP_EDIT_GROUP</source>
+        <translation>Edit Group</translation>
+    </message>
+    <message>
+        <source>TOP_EDIT_GEOMGROUP_AS_GROUP</source>
+        <translation>Edit Group as Standalone</translation>
+    </message>
+    <message>
+        <source>TOP_EDIT_HYPO</source>
+        <translation>Edit Hypothesis</translation>
+    </message>
+    <message>
+        <source>TOP_EDIT_MESHSUBMESH</source>
+        <translation>Edit Mesh/Sub-mesh</translation>
+    </message>
+    <message>
+        <source>TOP_EXPORT_DAT</source>
+        <translation>Export to DAT file</translation>
+    </message>
+    <message>
+        <source>TOP_EXPORT_MED</source>
+        <translation>Export to MED file</translation>
+    </message>
+    <message>
+        <source>TOP_EXPORT_SAUV</source>
+        <translation>Export to SAUV file</translation>
+    </message>
+    <message>
+        <source>TOP_EXPORT_STL</source>
+        <translation>Export to STL file</translation>
+    </message>
+    <message>
+        <source>TOP_EXPORT_UNV</source>
+        <translation>Export to UNV file</translation>
+    </message>
+    <message>
+        <source>TOP_EXTRUSION</source>
+        <translation>Extrusion</translation>
+    </message>
+    <message>
+        <source>TOP_EXTRUSION_ALONG</source>
+        <translation>Extrusion along a path</translation>
+    </message>
+    <message>
+        <source>TOP_FACES</source>
+        <translation>Faces</translation>
+    </message>
+    <message>
+        <source>TOP_BARE_BORDER_VOLUME</source>
+        <translation>Volumes with bare border</translation>
+    </message>
+    <message>
+        <source>TOP_BARE_BORDER_FACE</source>
+        <translation>Faces with bare border</translation>
+    </message>
+    <message>
+        <source>TOP_OVER_CONSTRAINED_VOLUME</source>
+        <translation>Over-constrained volumes</translation>
+    </message>
+    <message>
+        <source>TOP_OVER_CONSTRAINED_FACE</source>
+        <translation>Over-constrained faces</translation>
+    </message>
+    <message>
+        <source>TOP_FREE_BORDER</source>
+        <translation>Free Borders</translation>
+    </message>
+    <message>
+        <source>TOP_FREE_EDGE</source>
+        <translation>Free Edges</translation>
+    </message>
+    <message>
+        <source>TOP_FREE_NODE</source>
+        <translation>Free Nodes</translation>
+    </message>
+    <message>
+        <source>TOP_FREE_FACES</source>
+        <translation>Free Faces</translation>
+    </message>
+    <message>
+        <source>TOP_GLOBAL_HYPO</source>
+        <translation>Global Hypothesis</translation>
+    </message>
+    <message>
+        <source>TOP_HEXA</source>
+        <translation>Hexahedron</translation>
+    </message>
+    <message>
+        <source>TOP_HIDE</source>
+        <translation>Hide</translation>
+    </message>
+    <message>
+        <source>TOP_INT_GROUP</source>
+        <translation>Intersect Groups</translation>
+    </message>
+    <message>
+        <source>TOP_INV</source>
+        <translation>Diagonal Inversion</translation>
+    </message>
+    <message>
+        <source>TOP_LENGTH</source>
+        <translation>Length</translation>
+    </message>
+    <message>
+        <source>TOP_LENGTH_2D</source>
+        <translation>Length 2D</translation>
+    </message>
+    <message>
+        <source>TOP_MAP</source>
+        <translation>Pattern mapping</translation>
+    </message>
+    <message>
+        <source>TOP_MAX_ELEMENT_LENGTH_2D</source>
+        <translation>Element Diameter 2D</translation>
+    </message>
+    <message>
+        <source>TOP_MAX_ELEMENT_LENGTH_3D</source>
+        <translation>Element Diameter 3D</translation>
+    </message>
+    <message>
+        <source>TOP_IMPORT_MED</source>
+        <translation>Import MED file</translation>
+    </message>
+    <message>
+        <source>TOP_MED</source>
+        <translation>Export MED file</translation>
+    </message>
+    <message>
+        <source>TOP_IMPORT_STL</source>
+        <translation>Import STL file</translation>
+    </message>
+    <message>
+        <source>TOP_STL</source>
+        <translation>Export STL file</translation>
+    </message>
+    <message>
+        <source>TOP_IMPORT_CGNS</source>
+        <translation>Import CGNS file</translation>
+    </message>
+    <message>
+        <source>TOP_CGNS</source>
+        <translation>Export CGNS file</translation>
+    </message>
+    <message>
+        <source>TOP_IMPORT_SAUV</source>
+        <translation>Import SAUV file</translation>
+    </message>
+    <message>
+        <source>TOP_SAUV</source>
+        <translation>Export SAUV file</translation>
+    </message>
+    <message>
+        <source>TOP_MERGE</source>
+        <translation>Merge nodes</translation>
+    </message>
+    <message>
+        <source>TOP_MERGE_ELEMENTS</source>
+        <translation>Merge elements</translation>
+    </message>
+    <message>
+        <source>TOP_MESH_THROU_POINT</source>
+        <translation>Move Node</translation>
+    </message>
+    <message>
+        <source>TOP_MIN_ANG</source>
+        <translation>Minimum Angle</translation>
+    </message>
+    <message>
+        <source>TOP_MOVE</source>
+        <translation>Move Node</translation>
+    </message>
+    <message>
+        <source>TOP_NODE</source>
+        <translation>Node</translation>
+    </message>
+    <message>
+        <source>TOP_NODES</source>
+        <translation>Nodes</translation>
+    </message>
+    <message>
+        <source>TOP_NUM_ELEMENTS</source>
+        <translation>Display Elements</translation>
+    </message>
+    <message>
+        <source>TOP_NUM_NODES</source>
+        <translation>Display Nodes</translation>
+    </message>
+    <message>
+        <source>TOP_ORIENT</source>
+        <translation>Orientation</translation>
+    </message>
+    <message>
+        <source>TOP_POLYGON</source>
+        <translation>Polygon</translation>
+    </message>
+    <message>
+        <source>TOP_POLYHEDRON</source>
+        <translation>Polyhedron</translation>
+    </message>
+    <message>
+        <source>TOP_PRECISION</source>
+        <translation>Precision</translation>
+    </message>
+    <message>
+        <source>TOP_QUAD</source>
+        <translation>Quadrangle</translation>
+    </message>
+    <message>
+        <source>TOP_QUADRATIC_EDGE</source>
+        <translation>Quadratic Edge</translation>
+    </message>
+    <message>
+        <source>TOP_QUADRATIC_HEXAHEDRON</source>
+        <translation>Quadratic Hexahedron</translation>
+    </message>
+    <message>
+        <source>TOP_QUADRATIC_PENTAHEDRON</source>
+        <translation>Quadratic Pentahedron</translation>
+    </message>
+    <message>
+        <source>TOP_QUADRATIC_PYRAMID</source>
+        <translation>Quadratic Pyramid</translation>
+    </message>
+    <message>
+        <source>TOP_QUADRATIC_QUADRANGLE</source>
+        <translation>Quadratic Quadrangle</translation>
+    </message>
+    <message>
+        <source>TOP_QUADRATIC_TETRAHEDRON</source>
+        <translation>Quadratic Tetrahedron</translation>
+    </message>
+    <message>
+        <source>TOP_QUADRATIC_TRIANGLE</source>
+        <translation>Quadratic Triangle</translation>
+    </message>
+    <message>
+        <source>TOP_REMOVE_ELEMENTS</source>
+        <translation>Remove elements</translation>
+    </message>
+    <message>
+        <source>TOP_REMOVE_NODES</source>
+        <translation>Remove nodes</translation>
+    </message>
+    <message>
+        <source>TOP_REMOVE_ORPHAN_NODES</source>
+        <translation>Remove orphan nodes</translation>
+    </message>
+    <message>
+        <source>TOP_RENAME</source>
+        <translation>Rename</translation>
+    </message>
+    <message>
+        <source>TOP_RENUM_ELEMENTS</source>
+        <translation>Renumbering elements</translation>
+    </message>
+    <message>
+        <source>TOP_RENUM_NODES</source>
+        <translation>Renumbering nodes</translation>
+    </message>
+    <message>
+        <source>TOP_RESET</source>
+        <translation>Reset</translation>
+    </message>
+    <message>
+        <source>TOP_SAVE_DISTRIBUTION</source>
+        <translation>Export distribution</translation>
+    </message>
+    <message>
+        <source>TOP_SHOW_DISTRIBUTION</source>
+        <translation>Show Distribution</translation>
+    </message>
+    <message>
+        <source>TOP_REVOLUTION</source>
+        <translation>Revolution</translation>
+    </message>
+    <message>
+        <source>TOP_ROT</source>
+        <translation>Rotation</translation>
+    </message>
+    <message>
+        <source>TOP_SCALAR_BAR</source>
+        <translation>Scalar bar</translation>
+    </message>
+    <message>
+        <source>TOP_SCALAR_BAR_PROP</source>
+        <translation>Scalar bar Properties</translation>
+    </message>
+    <message>
+        <source>TOP_SELECTION</source>
+        <translation>Selection</translation>
+    </message>
+    <message>
+        <source>TOP_SEL_FILTER_LIB</source>
+        <translation>Selection filters library</translation>
+    </message>
+    <message>
+        <source>TOP_SEW</source>
+        <translation>Sewing</translation>
+    </message>
+    <message>
+        <source>TOP_SHADE</source>
+        <translation>Shading</translation>
+    </message>
+    <message>
+        <source>TOP_SHOW</source>
+        <translation>Show</translation>
+    </message>
+    <message>
+        <source>TOP_SHRINK</source>
+        <translation>Shrink</translation>
+    </message>
+    <message>
+        <source>TOP_SKEW</source>
+        <translation>Skew</translation>
+    </message>
+    <message>
+        <source>TOP_SMOOTH</source>
+        <translation>Smoothing</translation>
+    </message>
+    <message>
+        <source>TOP_STD_INFO</source>
+        <translation>Standard Mesh Infos</translation>
+    </message>
+    <message>
+        <source>TOP_SYM</source>
+        <translation>Symmetry</translation>
+    </message>
+    <message>
+        <source>TOP_TAPER</source>
+        <translation>Taper</translation>
+    </message>
+    <message>
+        <source>TOP_TETRA</source>
+        <translation>Tetrahedron</translation>
+    </message>
+    <message>
+        <source>TOP_TRANS</source>
+        <translation>Translation</translation>
+    </message>
+    <message>
+        <source>TOP_SCALE</source>
+        <translation>Scale Transform</translation>
+    </message>
+    <message>
+        <source>TOP_DUPLICATE_NODES</source>
+        <translation>Duplicate Nodes</translation>
+    </message>
+    <message>
+        <source>TOP_TRANSP</source>
+        <translation>Transparency</translation>
+    </message>
+    <message>
+        <source>TOP_TRIANGLE</source>
+        <translation>Triangle</translation>
+    </message>
+    <message>
+        <source>TOP_UNASSIGN</source>
+        <translation>Unassign</translation>
+    </message>
+    <message>
+        <source>TOP_UNION</source>
+        <translation>Union of triangles</translation>
+    </message>
+    <message>
+        <source>TOP_UNION2</source>
+        <translation>Union of two triangles</translation>
+    </message>
+    <message>
+        <source>TOP_IMPORT_UNV</source>
+        <translation>Import UNV file</translation>
+    </message>
+    <message>
+        <source>TOP_UNV</source>
+        <translation>Export UNV file</translation>
+    </message>
+    <message>
+        <source>TOP_UN_GROUP</source>
+        <translation>Union Groups</translation>
+    </message>
+    <message>
+        <source>TOP_UNDERLYING_ELEMS</source>
+        <translation>Create groups of entities from existing groups of superior dimensions</translation>
+    </message>
+    <message>
+        <source>TOP_UPDATE</source>
+        <translation>Update</translation>
+    </message>
+    <message>
+        <source>TOP_VOLUMES</source>
+        <translation>Volumes</translation>
+    </message>
+    <message>
+        <source>TOP_VOLUME_3D</source>
+        <translation>Volume</translation>
+    </message>
+    <message>
+        <source>TOP_WARP</source>
+        <translation>Warping angle</translation>
+    </message>
+    <message>
+        <source>TOP_WHAT_IS</source>
+        <translation>Mesh Element Information</translation>
+    </message>
+    <message>
+        <source>TOP_WIRE</source>
+        <translation>Wireframe</translation>
+    </message>
+    <message>
+        <source>UNKNOWN_CONTROL</source>
+        <translation>Unknown</translation>
+    </message>
+    <message>
+        <source>VOLUME_3D_ELEMENTS</source>
+        <translation>Volume</translation>
+    </message>
+    <message>
+        <source>WARP_ELEMENTS</source>
+        <translation>Warping</translation>
+    </message>
+    <message>
+        <source>MEN_FILE_INFO</source>
+        <translation>MED File Information</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_NO_APPROPRIATE_SELECTION</source>
+        <translation>No appropriate objects selected</translation>
+    </message>
+    <message>
+        <source>MEN_CLEAR_MESH</source>
+        <translation>Clear Mesh Data</translation>
+    </message>
+    <message>
+        <source>TOP_CLEAR_MESH</source>
+        <translation>Clear Mesh Data</translation>
+    </message>
+    <message>
+        <source>STB_CLEAR_MESH</source>
+        <translation>Clear Mesh Data</translation>
+    </message>
+    <message>
+        <source>SMESH_IMPORT_MESH</source>
+        <translation>Import mesh data from files</translation>
+    </message>
+    <message>
+        <source>SMESH_ERR_NOT_SUPPORTED_FORMAT</source>
+        <translation>Unsupported file format</translation>
+    </message>
+    <message>
+        <source>SMESH_ERR_UNKNOWN_IMPORT_ERROR</source>
+        <translation>Unknown error</translation>
+    </message>
+    <message>
+        <source>SMESH_IMPORT_ERRORS</source>
+        <translation>Import operation has finished with errors:</translation>
+    </message>
+    <message>
+        <source>SMESH_DRS_SOME_EMPTY</source>
+        <translation>One or more mesh files were empty, data has not been published</translation>
+    </message>
+    <message>
+        <source>NO_MESH_SELECTED</source>
+        <translation>No mesh selected</translation>
+    </message>
+    <message>
+        <source>SMESH_PREF_def_precision</source>
+        <translation>Default precision</translation>
+    </message>
+    <message>
+        <source>SMESH_PREF_length_precision</source>
+        <translation>Length precision</translation>
+    </message>
+    <message>
+        <source>SMESH_PREF_angle_precision</source>
+        <translation>Angular precision</translation>
+    </message>
+    <message>
+        <source>SMESH_PREF_len_tol_precision</source>
+        <translation>Length tolerance precision</translation>
+    </message>
+    <message>
+        <source>SMESH_PREF_parametric_precision</source>
+        <translation>Parametric precision</translation>
+    </message>
+    <message>
+        <source>SMESH_PREF_area_precision</source>
+        <translation>Area precision</translation>
+    </message>
+    <message>
+        <source>FULL_RECOMPUTE_QUESTION</source>
+        <translation>
+The mesh has been edited since a last total re-compute 
+that may prevent successful computation. 
+Do you wish to re-compute the mesh totally to discard the modifications?
 </translation>
-        </message>
-        <message>
-            <source>SMESH_ROTATION</source>
-            <translation>Rotation</translation>
-        </message>
-        <message>
-            <source>SMESH_ROTATION_TITLE</source>
-            <translation>Rotation about an axis</translation>
-        </message>
-        <message>
-            <source>SMESH_SCALARBAR</source>
-            <translation>Scalar Bar</translation>
-        </message>
-        <message>
-            <source>SMESH_SEGMENTS</source>
-            <translation>Segments</translation>
-        </message>
-        <message>
-            <source>SMESH_SELECTION</source>
-            <translation>Selection</translation>
-        </message>
-        <message>
-            <source>SMESH_SELECT_FROM</source>
-            <translation>Select From</translation>
-        </message>
-        <message>
-            <source>SMESH_SELECT_WHOLE_MESH</source>
-            <translation>Select whole mesh, submesh or group</translation>
-        </message>
-        <message>
-            <source>SMESH_SET_COLOR</source>
-            <translation>Color group</translation>
-        </message>
-        <message>
-            <source>SMESH_SEWING</source>
-            <translation>Sewing</translation>
-        </message>
-        <message>
-            <source>SMESH_SMOOTHING</source>
-            <translation>Smoothing</translation>
-        </message>
-        <message>
-            <source>SMESH_STANDARD_MESHINFO_TITLE</source>
-            <translation>Standard Mesh Infos</translation>
-        </message>
-        <message>
-            <source>SMESH_SUBMESH</source>
-            <translation>SubMesh</translation>
-        </message>
-        <message>
-            <source>SMESH_SUBMESH_SELECTED</source>
-            <translation>%1 SubMeshes</translation>
-        </message>
-        <message>
-            <source>SMESH_SYMMETRY</source>
-            <translation>Symmetry</translation>
-        </message>
-        <message>
-            <source>SMESH_TETRAS</source>
-            <translation>Tetrahedron</translation>
-        </message>
-        <message>
-            <source>SMESH_TITLE</source>
-            <translation>Title:</translation>
-        </message>
-        <message>
-            <source>SMESH_TOLERANCE</source>
-            <translation>Tolerance</translation>
-        </message>
-        <message>
-            <source>SMESH_TRANSLATION</source>
-            <translation>Translation</translation>
-        </message>
-        <message>
-            <source>SMESH_TRANSPARENCY_OPAQUE</source>
-            <translation>---> Opaque</translation>
-        </message>
-        <message>
-            <source>SMESH_TRANSPARENCY_TITLE</source>
-            <translation>Change Transparency</translation>
-        </message>
-        <message>
-            <source>SMESH_TRANSPARENCY_TRANSPARENT</source>
-            <translation>Transparent &lt;---</translation>
-        </message>
-        <message>
-            <source>SMESH_TRIANGLE</source>
-            <translation>Triangle</translation>
-        </message>
-        <message>
-            <source>SMESH_UPDATEVIEW</source>
-            <translation>Update View</translation>
-        </message>
-        <message>
-            <source>SMESH_VALUE</source>
-            <translation>Value</translation>
-        </message>
-        <message>
-            <source>SMESH_VECTOR</source>
-            <translation>Vector</translation>
-        </message>
-        <message>
-            <source>SMESH_VERTICAL</source>
-            <translation>Vertical</translation>
-        </message>
-        <message>
-            <source>SMESH_VISU_PROBLEM</source>
-            <translation>Mesh visualization failed, probably due to lack of memory</translation>
-        </message>
-        <message>
-            <source>SMESH_VISU_PROBLEM_CLEAR</source>
-            <translation>Mesh visualization failed, no memory even to show a message,
-so all visual data have been removed to let the application live.
-Consider saving your work before application crash</translation>
-        </message>
-        <message>
-            <source>SMESH_VOLUME</source>
-            <translation>Volume</translation>
-        </message>
-        <message>
-            <source>SMESH_WARNING</source>
-            <translation>Warning</translation>
-        </message>
-        <message>
-            <source>SMESH_WHAT_IS_TITLE</source>
-            <translation>Mesh Element Info</translation>
-        </message>
-        <message>
-            <source>SMESH_WIDTH</source>
-            <translation>Width:</translation>
-        </message>
-        <message>
-            <source>SMESH_WRN_ALGORITHM_ALREADYEXIST</source>
-            <translation>Algorithm already exists</translation>
-        </message>
-        <message>
-            <source>SMESH_WRN_COMPUTE_FAILED</source>
-            <translation>Mesh computation failed</translation>
-        </message>
-        <message>
-            <source>SMESH_WRN_EMPTY_NAME</source>
-            <translation>Empty name is not valid</translation>
-        </message>
-        <message>
-            <source>SMESH_WRN_HYPOTHESIS_ALREADYEXIST</source>
-            <translation>Hypothesis already exists</translation>
-        </message>
-        <message>
-            <source>SMESH_WRN_HYPOTHESIS_NOTEXIST</source>
-            <translation>Hypothesis or Algorithm not exists</translation>
-        </message>
-        <message>
-            <source>SMESH_WRN_MISSING_PARAMETERS</source>
-            <translation>Missing parameters</translation>
-        </message>
-        <message>
-            <source>SMESH_WRN_NO_AVAILABLE_DATA</source>
-            <translation>No available data in selection</translation>
-        </message>
-        <message>
-            <source>SMESH_WRN_SELECTIONMODE_DIAGONAL</source>
-            <translation>Activate Link Selection Mode</translation>
-        </message>
-        <message>
-            <source>SMESH_WRN_SELECTIONMODE_ELEMENTS</source>
-            <translation>Activate Elements Selection Mode</translation>
-        </message>
-        <message>
-            <source>SMESH_WRN_SELECTIONMODE_NODES</source>
-            <translation>Activate Nodes Selection Mode</translation>
-        </message>
-        <message>
-            <source>SMESH_WRN_VIEWER_VTK</source>
-            <translation>Study frame with VTK Viewer must be activated</translation>
-        </message>
-        <message>
-            <source>SMESH_WRN_WARNING</source>
-            <translation>Warning</translation>
-        </message>
-        <message>
-            <source>SMESH_X</source>
-            <translation>X</translation>
-        </message>
-        <message>
-            <source>SMESH_X_SCALARBAR</source>
-            <translation>X:</translation>
-        </message>
-        <message>
-            <source>SMESH_Y</source>
-            <translation>Y</translation>
-        </message>
-        <message>
-            <source>SMESH_Y_SCALARBAR</source>
-            <translation>Y:</translation>
-        </message>
-        <message>
-            <source>SMESH_Z</source>
-            <translation>Z</translation>
-        </message>
-        <message>
-            <source>STATE_ALGO_MISSING</source>
-            <translation>%3 %2D algorithm is missing</translation>
-        </message>
-        <message>
-            <source>STATE_HYP_BAD_GEOMETRY</source>
-            <translation>%3 %2D algorithm "%1" is assigned to geometry mismatching its expectation</translation>
-        </message>
-        <message>
-            <source>STATE_HYP_BAD_PARAMETER</source>
-            <translation>Hypothesis of %3 %2D algorithm "%1" has a bad parameter value</translation>
-        </message>
-        <message>
-            <source>STATE_HYP_MISSING</source>
-            <translation>%3 %2D algorithm "%1" misses %4D hypothesis</translation>
-        </message>
-        <message>
-            <source>STATE_HYP_NOTCONFORM</source>
-            <translation>%3 %2D algorithm "%1" would produce not conform mesh: global "Not Conform Mesh Allowed" hypotesis is missing</translation>
-        </message>
-        <message>
-            <source>STB_ADV_INFO</source>
-            <translation>Advanced Mesh Infos</translation>
-        </message>
-        <message>
-            <source>STB_ALL</source>
-            <translation>All</translation>
-        </message>
-        <message>
-            <source>STB_AREA</source>
-            <translation>Area</translation>
-        </message>
-        <message>
-            <source>STB_ASPECT</source>
-            <translation>Aspect Ratio</translation>
-        </message>
-        <message>
-            <source>STB_ASPECT_3D</source>
-            <translation>Aspect Ratio 3D</translation>
-        </message>
-        <message>
-            <source>STB_AUTO_COLOR</source>
-            <translation>Auto color</translation>
-        </message>
-        <message>
-            <source>STB_AUTO_UPD</source>
-            <translation>Automatic update</translation>
-        </message>
-        <message>
-            <source>STB_BUILD_COMPOUND</source>
-            <translation>Build Compound Mesh</translation>
-        </message>
-        <message>
-            <source>STB_CLIP</source>
-            <translation>Clipping</translation>
-        </message>
-        <message>
-            <source>STB_COLORS</source>
-            <translation>Colors / Size</translation>
-        </message>
-        <message>
-            <source>STB_COMPUTE</source>
-            <translation>Compute</translation>
-        </message>
-        <message>
-            <source>STB_PRECOMPUTE</source>
-            <translation>Preview</translation>
-        </message>
-        <message>
-            <source>STB_CONNECTION</source>
-            <translation>Borders at Multi-Connection</translation>
-        </message>
-        <message>
-            <source>STB_CONNECTION_2D</source>
-            <translation>Borders at Multi-Connection 2D</translation>
-        </message>
-        <message>
-            <source>STB_CONSTRUCT_GROUP</source>
-            <translation>Construct Group</translation>
-        </message>
-        <message>
-            <source>STB_CONV_TO_QUAD</source>
-            <translation>Convert to/from quadratic</translation>
-        </message>
-        <message>
-            <source>STB_CREATE_GROUP</source>
-            <translation>Create Group</translation>
-        </message>
-        <message>
-            <source>STB_CREATE_GEO_GROUP</source>
-            <translation>Create Groups from Geometry</translation>
-        </message>
-        <message>
-            <source>STB_CREATE_MESH</source>
-            <translation>Create Mesh</translation>
-        </message>
-        <message>
-            <source>STB_CREATE_SUBMESH</source>
-            <translation>Create Sub-mesh</translation>
-        </message>
-        <message>
-            <source>STB_CUT</source>
-            <translation>Cutting of quadrangles</translation>
-        </message>
-        <message>
-            <source>STB_CUT_GROUP</source>
-            <translation>Cut Groups</translation>
-        </message>
-        <message>
-            <source>STB_DAT</source>
-            <translation>Import DAT file</translation>
-        </message>
-        <message>
-            <source>STB_DELETE</source>
-            <translation>Delete</translation>
-        </message>
-        <message>
-            <source>STB_DEL_GROUP</source>
-            <translation>Delete Groups</translation>
-        </message>
-        <message>
-            <source>STB_FACE_ORIENTATION</source>
-            <translation>Orientation of faces</translation>
-        </message>
-        <message>
-            <source>STB_DISABLE_AUTO_COLOR</source>
-            <translation>Disable auto color</translation>
-        </message>
-        <message>
-            <source>STB_DISPLAY_ONLY</source>
-            <translation>Show only</translation>
-        </message>
-        <message>
-            <source>STB_DISP_ENT</source>
-            <translation>Display entity</translation>
-        </message>
-        <message>
-            <source>STB_EDGE</source>
-            <translation>Edge</translation>
-        </message>
-        <message>
-            <source>STB_EDGES</source>
-            <translation>Edges</translation>
-        </message>
-        <message>
-            <source>STB_EDIT_GROUP</source>
-            <translation>Edit Group</translation>
-        </message>
-        <message>
-            <source>STB_EDIT_GEOMGROUP_AS_GROUP</source>
-            <translation>Edit Group as Standalone</translation>
-        </message>
-        <message>
-            <source>STB_EDIT_HYPO</source>
-            <translation>Edit Hypothesis</translation>
-        </message>
-        <message>
-            <source>STB_EDIT_MESHSUBMESH</source>
-            <translation>Edit Mesh/Sub-mesh</translation>
-        </message>
-        <message>
-            <source>STB_EXPORT_DAT</source>
-            <translation>Export to DAT file</translation>
-        </message>
-        <message>
-            <source>STB_EXPORT_MED</source>
-            <translation>Export to MED file</translation>
-        </message>
-        <message>
-            <source>STB_EXPORT_STL</source>
-            <translation>Export to STL file</translation>
-        </message>
-        <message>
-            <source>STB_EXPORT_UNV</source>
-            <translation>Export to UNV file</translation>
-        </message>
-        <message>
-            <source>STB_EXTRUSION</source>
-            <translation>Extrusion</translation>
-        </message>
-        <message>
-            <source>STB_EXTRUSION_ALONG</source>
-            <translation>Extrusion along a path</translation>
-        </message>
-        <message>
-            <source>STB_FACES</source>
-            <translation>Faces</translation>
-        </message>
-        <message>
-            <source>STB_FREE_BORDER</source>
-            <translation>Free Borders</translation>
-        </message>
-        <message>
-            <source>STB_FREE_EDGE</source>
-            <translation>Free Edges</translation>
-        </message>
-       <message>
-            <source>STB_FREE_NODE</source>
-            <translation>Free Nodes</translation>
-        </message>
-       
-
-        <message>
-            <source>STB_FREE_FACES</source>
-            <translation>Free Faces</translation>
-        </message>
-        <message>
-            <source>STB_GLOBAL_HYPO</source>
-            <translation>Global Hypothesis</translation>
-        </message>
-        <message>
-            <source>STB_HEXA</source>
-            <translation>Hexahedron</translation>
-        </message>
-        <message>
-            <source>STB_HIDE</source>
-            <translation>Hide</translation>
-        </message>
-        <message>
-            <source>STB_INT_GROUP</source>
-            <translation>Intersect Groups</translation>
-        </message>
-        <message>
-            <source>STB_INV</source>
-            <translation>Diagonal Inversion</translation>
-        </message>
-        <message>
-            <source>STB_LENGTH</source>
-            <translation>Length</translation>
-        </message>
-        <message>
-            <source>STB_LENGTH_2D</source>
-            <translation>Length 2D</translation>
-        </message>
-        <message>
-            <source>STB_MAP</source>
-            <translation>Pattern mapping</translation>
-        </message>
-        <message>
-            <source>STB_MED</source>
-            <translation>Import MED file</translation>
-        </message>
-        <message>
-            <source>STB_MERGE</source>
-            <translation>Merge nodes</translation>
-        </message>
-        <message>
-            <source>STB_MERGE_ELEMENTS</source>
-            <translation>Merge elements</translation>
-        </message>
-        <message>
-            <source>STB_MESH_THROU_POINT</source>
-            <translation>Mesh to pass through a point</translation>
-        </message>
-        <message>
-            <source>STB_MIN_ANG</source>
-            <translation>Minimum Angle</translation>
-        </message>
-        <message>
-            <source>STB_MOVE</source>
-            <translation>Move Node</translation>
-        </message>
-        <message>
-            <source>STB_NODE</source>
-            <translation>Node</translation>
-        </message>
-        <message>
-            <source>STB_NODES</source>
-            <translation>Nodes</translation>
-        </message>
-        <message>
-            <source>STB_NUM_ELEMENTS</source>
-            <translation>Display Elements</translation>
-        </message>
-        <message>
-            <source>STB_NUM_NODES</source>
-            <translation>Display Nodes</translation>
-        </message>
-        <message>
-            <source>STB_ORIENT</source>
-            <translation>Orientation</translation>
-        </message>
-        <message>
-            <source>STB_POLYGON</source>
-            <translation>Polygon</translation>
-        </message>
-        <message>
-            <source>STB_POLYHEDRON</source>
-            <translation>Polyhedron</translation>
-        </message>
-        <message>
-            <source>STB_PRECISION</source>
-            <translation>Precision</translation>
-        </message>
-        <message>
-            <source>STB_QUAD</source>
-            <translation>Quadrangle</translation>
-        </message>
-        <message>
-            <source>STB_QUADRATIC_EDGE</source>
-            <translation>Quadratic Edge</translation>
-        </message>
-        <message>
-            <source>STB_QUADRATIC_HEXAHEDRON</source>
-            <translation>Quadratic Hexahedron</translation>
-        </message>
-        <message>
-            <source>STB_QUADRATIC_PENTAHEDRON</source>
-            <translation>Quadratic Pentahedron</translation>
-        </message>
-        <message>
-            <source>STB_QUADRATIC_PYRAMID</source>
-            <translation>Quadratic Pyramid</translation>
-        </message>
-        <message>
-            <source>STB_QUADRATIC_QUADRANGLE</source>
-            <translation>Quadratic Quadrangle</translation>
-        </message>
-        <message>
-            <source>STB_QUADRATIC_TETRAHEDRON</source>
-            <translation>Quadratic Tetrahedron</translation>
-        </message>
-        <message>
-            <source>STB_QUADRATIC_TRIANGLE</source>
-            <translation>Quadratic Triangle</translation>
-        </message>
-        <message>
-            <source>STB_REMOVE_ELEMENTS</source>
-            <translation>Remove elements</translation>
-        </message>
-        <message>
-            <source>STB_REMOVE_NODES</source>
-            <translation>Remove nodes</translation>
-        </message>
-        <message>
-            <source>STB_RENAME</source>
-            <translation>Rename</translation>
-        </message>
-        <message>
-            <source>STB_RENUM_ELEMENTS</source>
-            <translation>Renumbering elements</translation>
-        </message>
-        <message>
-            <source>STB_RENUM_NODES</source>
-            <translation>Renumbering nodes</translation>
-        </message>
-        <message>
-            <source>STB_RESET</source>
-            <translation>Reset</translation>
-        </message>
-        <message>
-            <source>STB_REVOLUTION</source>
-            <translation>Revolution</translation>
-        </message>
-        <message>
-            <source>STB_ROT</source>
-            <translation>Rotation</translation>
-        </message>
-        <message>
-            <source>STB_SCALAR_BAR</source>
-            <translation>Scalar bar</translation>
-        </message>
-        <message>
-            <source>STB_SCALAR_BAR_PROP</source>
-            <translation>Scalar bar Properties</translation>
-        </message>
-        <message>
-            <source>STB_SELECTION</source>
-            <translation>Selection</translation>
-        </message>
-        <message>
-            <source>STB_SEL_FILTER_LIB</source>
-            <translation>Selection filters library</translation>
-        </message>
-        <message>
-            <source>STB_SEW</source>
-            <translation>Sewing</translation>
-        </message>
-        <message>
-            <source>STB_SHADE</source>
-            <translation>Shading</translation>
-        </message>
-        <message>
-            <source>STB_SHOW</source>
-            <translation>Show</translation>
-        </message>
-        <message>
-            <source>STB_SHRINK</source>
-            <translation>Shrink</translation>
-        </message>
-        <message>
-            <source>STB_SKEW</source>
-            <translation>Skew</translation>
-        </message>
-        <message>
-            <source>STB_SMOOTH</source>
-            <translation>Smoothing</translation>
-        </message>
-        <message>
-            <source>STB_STD_INFO</source>
-            <translation>Standard Mesh Infos</translation>
-        </message>
-        <message>
-            <source>STB_SYM</source>
-            <translation>Symmetry</translation>
-        </message>
-        <message>
-            <source>STB_TAPER</source>
-            <translation>Taper</translation>
-        </message>
-        <message>
-            <source>STB_TETRA</source>
-            <translation>Tetrahedron</translation>
-        </message>
-        <message>
-            <source>STB_TRANS</source>
-            <translation>Translation</translation>
-        </message>
-        <message>
-            <source>STB_TRANSP</source>
-            <translation>Transparency</translation>
-        </message>
-        <message>
-            <source>STB_TRIANGLE</source>
-            <translation>Triangle</translation>
-        </message>
-        <message>
-            <source>STB_UNASSIGN</source>
-            <translation>Unassign</translation>
-        </message>
-        <message>
-            <source>STB_UNION</source>
-            <translation>Union of triangles</translation>
-        </message>
-        <message>
-            <source>STB_UNION2</source>
-            <translation>Union of two triangles</translation>
-        </message>
-        <message>
-            <source>STB_UNV</source>
-            <translation>Import UNV file</translation>
-        </message>
-        <message>
-            <source>STB_UN_GROUP</source>
-            <translation>Union Groups</translation>
-        </message>
-        <message>
-            <source>STB_UNDERLYING_ELEMS</source>
-            <translation>Create groups of entities from existing groups of superior dimensions</translation>
-        </message>
-        <message>
-            <source>STB_UPDATE</source>
-            <translation>Update</translation>
-        </message>
-        <message>
-            <source>STB_VOLUMES</source>
-            <translation>Volumes</translation>
-        </message>
-        <message>
-            <source>STB_VOLUME_3D</source>
-            <translation>Volume</translation>
-        </message>
-        <message>
-            <source>STB_WARP</source>
-            <translation>Warping angle</translation>
-        </message>
-        <message>
-            <source>STB_WHAT_IS</source>
-            <translation>Mesh Element Info</translation>
-        </message>
-        <message>
-            <source>STB_WIRE</source>
-            <translation>Wireframe</translation>
-        </message>
-        <message>
-            <source>TAPER_ELEMENTS</source>
-            <translation>Taper</translation>
-        </message>
-        <message>
-            <source>TB_ADD_REMOVE</source>
-            <translation>Add/Remove Toolbar</translation>
-        </message>
-        <message>
-            <source>TB_CTRL</source>
-            <translation>Controls Toolbar</translation>
-        </message>
-        <message>
-            <source>TB_DISP_MODE</source>
-            <translation>Display Mode Toolbar</translation>
-        </message>
-        <message>
-            <source>TB_HYPO</source>
-            <translation>Hypotheses Toolbar</translation>
-        </message>
-        <message>
-            <source>TB_MESH</source>
-            <translation>Mesh Toolbar</translation>
-        </message>
-        <message>
-            <source>TB_MODIFY</source>
-            <translation>Modification Toolbar</translation>
-        </message>
-        <message>
-            <source>TOP_ADV_INFO</source>
-            <translation>Advanced Mesh Infos</translation>
-        </message>
-        <message>
-            <source>TOP_ALL</source>
-            <translation>All</translation>
-        </message>
-        <message>
-            <source>TOP_AREA</source>
-            <translation>Area</translation>
-        </message>
-        <message>
-            <source>TOP_ASPECT</source>
-            <translation>Aspect Ratio</translation>
-        </message>
-        <message>
-            <source>TOP_ASPECT_3D</source>
-            <translation>Aspect Ratio 3D</translation>
-        </message>
-        <message>
-            <source>TOP_AUTO_COLOR</source>
-            <translation>Auto color</translation>
-        </message>
-        <message>
-            <source>TOP_AUTO_UPD</source>
-            <translation>Automatic update</translation>
-        </message>
-        <message>
-            <source>TOP_BUILD_COMPOUND</source>
-            <translation>Build Compound Mesh</translation>
-        </message>
-        <message>
-            <source>TOP_CLIP</source>
-            <translation>Clipping</translation>
-        </message>
-        <message>
-            <source>TOP_COLORS</source>
-            <translation>Colors / Size</translation>
-        </message>
-        <message>
-            <source>TOP_COMPUTE</source>
-            <translation>Compute</translation>
-        </message>
-        <message>
-            <source>TOP_PRECOMPUTE</source>
-            <translation>Preview</translation>
-        </message>
-        <message>
-            <source>TOP_CONNECTION</source>
-            <translation>Borders at Multi-Connection</translation>
-        </message>
-        <message>
-            <source>TOP_CONNECTION_2D</source>
-            <translation>Borders at Multi-Connection 2D</translation>
-        </message>
-        <message>
-            <source>TOP_CONSTRUCT_GROUP</source>
-            <translation>Construct Group</translation>
-        </message>
-        <message>
-            <source>TOP_CONV_TO_QUAD</source>
-            <translation>Convert to/from quadratic</translation>
-        </message>
-        <message>
-            <source>TOP_CREATE_GROUP</source>
-            <translation>Create Group</translation>
-        </message>
-        <message>
-            <source>TOP_CREATE_GEO_GROUP</source>
-            <translation>Create Groups from Geometry</translation>
-        </message>
-        <message>
-            <source>TOP_CREATE_MESH</source>
-            <translation>Create Mesh</translation>
-        </message>
-        <message>
-            <source>TOP_CREATE_SUBMESH</source>
-            <translation>Create Sub-mesh</translation>
-        </message>
-        <message>
-            <source>TOP_CUT</source>
-            <translation>Cutting of quadrangles</translation>
-        </message>
-        <message>
-            <source>TOP_CUT_GROUP</source>
-            <translation>Cut Groups</translation>
-        </message>
-        <message>
-            <source>TOP_DAT</source>
-            <translation>Import DAT file</translation>
-        </message>
-        <message>
-            <source>TOP_DELETE</source>
-            <translation>Delete</translation>
-        </message>
-        <message>
-            <source>TOP_DEL_GROUP</source>
-            <translation>Delete Groups</translation>
-        </message>
-        <message>
-            <source>TOP_FACE_ORIENTATION</source>
-            <translation>Orientation of faces</translation>
-        </message>
-        <message>
-            <source>TOP_DISABLE_AUTO_COLOR</source>
-            <translation>Disable auto color</translation>
-        </message>
-        <message>
-            <source>TOP_DISPLAY_ONLY</source>
-            <translation>Show only</translation>
-        </message>
-        <message>
-            <source>TOP_DISP_ENT</source>
-            <translation>Display entity</translation>
-        </message>
-        <message>
-            <source>TOP_EDGE</source>
-            <translation>Edge</translation>
-        </message>
-        <message>
-            <source>TOP_EDGES</source>
-            <translation>Edges</translation>
-        </message>
-        <message>
-            <source>TOP_EDIT_GROUP</source>
-            <translation>Edit Group</translation>
-        </message>
-        <message>
-            <source>TOP_EDIT_GEOMGROUP_AS_GROUP</source>
-            <translation>Edit Group as Standalone</translation>
-        </message>
-        <message>
-            <source>TOP_EDIT_HYPO</source>
-            <translation>Edit Hypothesis</translation>
-        </message>
-        <message>
-            <source>TOP_EDIT_MESHSUBMESH</source>
-            <translation>Edit Mesh/Sub-mesh</translation>
-        </message>
-        <message>
-            <source>TOP_EXPORT_DAT</source>
-            <translation>Export to DAT file</translation>
-        </message>
-        <message>
-            <source>TOP_EXPORT_MED</source>
-            <translation>Export to MED file</translation>
-        </message>
-        <message>
-            <source>TOP_EXPORT_STL</source>
-            <translation>Export to STL file</translation>
-        </message>
-        <message>
-            <source>TOP_EXPORT_UNV</source>
-            <translation>Export to UNV file</translation>
-        </message>
-        <message>
-            <source>TOP_EXTRUSION</source>
-            <translation>Extrusion</translation>
-        </message>
-        <message>
-            <source>TOP_EXTRUSION_ALONG</source>
-            <translation>Extrusion along a path</translation>
-        </message>
-        <message>
-            <source>TOP_FACES</source>
-            <translation>Faces</translation>
-        </message>
-        <message>
-            <source>TOP_FREE_BORDER</source>
-            <translation>Free Borders</translation>
-        </message>
-        <message>
-            <source>TOP_FREE_EDGE</source>
-            <translation>Free Edges</translation>
-        </message>
-       <message>
-            <source>TOP_FREE_NODE</source>
-            <translation>Free Nodes</translation>
-        </message>
-       
-
-        <message>
-            <source>TOP_FREE_FACES</source>
-            <translation>Free Faces</translation>
-        </message>
-        <message>
-            <source>TOP_GLOBAL_HYPO</source>
-            <translation>Global Hypothesis</translation>
-        </message>
-        <message>
-            <source>TOP_HEXA</source>
-            <translation>Hexahedron</translation>
-        </message>
-        <message>
-            <source>TOP_HIDE</source>
-            <translation>Hide</translation>
-        </message>
-        <message>
-            <source>TOP_INT_GROUP</source>
-            <translation>Intersect Groups</translation>
-        </message>
-        <message>
-            <source>TOP_INV</source>
-            <translation>Diagonal Inversion</translation>
-        </message>
-        <message>
-            <source>TOP_LENGTH</source>
-            <translation>Length</translation>
-        </message>
-        <message>
-            <source>TOP_LENGTH_2D</source>
-            <translation>Length 2D</translation>
-        </message>
-        <message>
-            <source>TOP_MAP</source>
-            <translation>Pattern mapping</translation>
-        </message>
-        <message>
-            <source>TOP_MED</source>
-            <translation>Import MED file</translation>
-        </message>
-        <message>
-            <source>TOP_MERGE</source>
-            <translation>Merge nodes</translation>
-        </message>
-        <message>
-            <source>TOP_MERGE_ELEMENTS</source>
-            <translation>Merge elements</translation>
-        </message>
-        <message>
-            <source>TOP_MESH_THROU_POINT</source>
-            <translation>Mesh to pass through a point</translation>
-        </message>
-        <message>
-            <source>TOP_MIN_ANG</source>
-            <translation>Minimum Angle</translation>
-        </message>
-        <message>
-            <source>TOP_MOVE</source>
-            <translation>Move Node</translation>
-        </message>
-        <message>
-            <source>TOP_NODE</source>
-            <translation>Node</translation>
-        </message>
-        <message>
-            <source>TOP_NODES</source>
-            <translation>Nodes</translation>
-        </message>
-        <message>
-            <source>TOP_NUM_ELEMENTS</source>
-            <translation>Display Elements</translation>
-        </message>
-        <message>
-            <source>TOP_NUM_NODES</source>
-            <translation>Display Nodes</translation>
-        </message>
-        <message>
-            <source>TOP_ORIENT</source>
-            <translation>Orientation</translation>
-        </message>
-        <message>
-            <source>TOP_POLYGON</source>
-            <translation>Polygon</translation>
-        </message>
-        <message>
-            <source>TOP_POLYHEDRON</source>
-            <translation>Polyhedron</translation>
-        </message>
-        <message>
-            <source>TOP_PRECISION</source>
-            <translation>Precision</translation>
-        </message>
-        <message>
-            <source>TOP_QUAD</source>
-            <translation>Quadrangle</translation>
-        </message>
-        <message>
-            <source>TOP_QUADRATIC_EDGE</source>
-            <translation>Quadratic Edge</translation>
-        </message>
-        <message>
-            <source>TOP_QUADRATIC_HEXAHEDRON</source>
-            <translation>Quadratic Hexahedron</translation>
-        </message>
-        <message>
-            <source>TOP_QUADRATIC_PENTAHEDRON</source>
-            <translation>Quadratic Pentahedron</translation>
-        </message>
-        <message>
-            <source>TOP_QUADRATIC_PYRAMID</source>
-            <translation>Quadratic Pyramid</translation>
-        </message>
-        <message>
-            <source>TOP_QUADRATIC_QUADRANGLE</source>
-            <translation>Quadratic Quadrangle</translation>
-        </message>
-        <message>
-            <source>TOP_QUADRATIC_TETRAHEDRON</source>
-            <translation>Quadratic Tetrahedron</translation>
-        </message>
-        <message>
-            <source>TOP_QUADRATIC_TRIANGLE</source>
-            <translation>Quadratic Triangle</translation>
-        </message>
-        <message>
-            <source>TOP_REMOVE_ELEMENTS</source>
-            <translation>Remove elements</translation>
-        </message>
-        <message>
-            <source>TOP_REMOVE_NODES</source>
-            <translation>Remove nodes</translation>
-        </message>
-        <message>
-            <source>TOP_RENAME</source>
-            <translation>Rename</translation>
-        </message>
-        <message>
-            <source>TOP_RENUM_ELEMENTS</source>
-            <translation>Renumbering elements</translation>
-        </message>
-        <message>
-            <source>TOP_RENUM_NODES</source>
-            <translation>Renumbering nodes</translation>
-        </message>
-        <message>
-            <source>TOP_RESET</source>
-            <translation>Reset</translation>
-        </message>
-        <message>
-            <source>TOP_REVOLUTION</source>
-            <translation>Revolution</translation>
-        </message>
-        <message>
-            <source>TOP_ROT</source>
-            <translation>Rotation</translation>
-        </message>
-        <message>
-            <source>TOP_SCALAR_BAR</source>
-            <translation>Scalar bar</translation>
-        </message>
-        <message>
-            <source>TOP_SCALAR_BAR_PROP</source>
-            <translation>Scalar bar Properties</translation>
-        </message>
-        <message>
-            <source>TOP_SELECTION</source>
-            <translation>Selection</translation>
-        </message>
-        <message>
-            <source>TOP_SEL_FILTER_LIB</source>
-            <translation>Selection filters library</translation>
-        </message>
-        <message>
-            <source>TOP_SEW</source>
-            <translation>Sewing</translation>
-        </message>
-        <message>
-            <source>TOP_SHADE</source>
-            <translation>Shading</translation>
-        </message>
-        <message>
-            <source>TOP_SHOW</source>
-            <translation>Show</translation>
-        </message>
-        <message>
-            <source>TOP_SHRINK</source>
-            <translation>Shrink</translation>
-        </message>
-        <message>
-            <source>TOP_SKEW</source>
-            <translation>Skew</translation>
-        </message>
-        <message>
-            <source>TOP_SMOOTH</source>
-            <translation>Smoothing</translation>
-        </message>
-        <message>
-            <source>TOP_STD_INFO</source>
-            <translation>Standard Mesh Infos</translation>
-        </message>
-        <message>
-            <source>TOP_SYM</source>
-            <translation>Symmetry</translation>
-        </message>
-        <message>
-            <source>TOP_TAPER</source>
-            <translation>Taper</translation>
-        </message>
-        <message>
-            <source>TOP_TETRA</source>
-            <translation>Tetrahedron</translation>
-        </message>
-        <message>
-            <source>TOP_TRANS</source>
-            <translation>Translation</translation>
-        </message>
-        <message>
-            <source>TOP_TRANSP</source>
-            <translation>Transparency</translation>
-        </message>
-        <message>
-            <source>TOP_TRIANGLE</source>
-            <translation>Triangle</translation>
-        </message>
-        <message>
-            <source>TOP_UNASSIGN</source>
-            <translation>Unassign</translation>
-        </message>
-        <message>
-            <source>TOP_UNION</source>
-            <translation>Union of triangles</translation>
-        </message>
-        <message>
-            <source>TOP_UNION2</source>
-            <translation>Union of two triangles</translation>
-        </message>
-        <message>
-            <source>TOP_UNV</source>
-            <translation>Import UNV file</translation>
-        </message>
-        <message>
-            <source>TOP_UN_GROUP</source>
-            <translation>Union Groups</translation>
-        </message>
-        <message>
-            <source>TOP_UNDERLYING_ELEMS</source>
-            <translation>Create groups of entities from existing groups of superior dimensions</translation>
-        </message>
-        <message>
-            <source>TOP_UPDATE</source>
-            <translation>Update</translation>
-        </message>
-        <message>
-            <source>TOP_VOLUMES</source>
-            <translation>Volumes</translation>
-        </message>
-        <message>
-            <source>TOP_VOLUME_3D</source>
-            <translation>Volume</translation>
-        </message>
-        <message>
-            <source>TOP_WARP</source>
-            <translation>Warping angle</translation>
-        </message>
-        <message>
-            <source>TOP_WHAT_IS</source>
-            <translation>Mesh Element Info</translation>
-        </message>
-        <message>
-            <source>TOP_WIRE</source>
-            <translation>Wireframe</translation>
-        </message>
-        <message>
-            <source>VOLUME_3D_ELEMENTS</source>
-            <translation>Area</translation>
-        </message>
-        <message>
-            <source>WARP_ELEMENTS</source>
-            <translation>Warping</translation>
-        </message>
-        <message>
-            <source>MEN_FILE_INFO</source>
-            <translation>MED File Information</translation>
-        </message>
-        <message>
-            <source>SMESH_WRN_NO_APPROPRIATE_SELECTION</source>
-            <translation>No appropriate objects selected</translation>
-        </message>
-        <message>
-            <source>MEN_CLEAR_MESH</source>
-            <translation>Clear Mesh Data</translation>
-        </message>
-        <message>
-            <source>TOP_CLEAR_MESH</source>
-            <translation>Clear Mesh Data</translation>
-        </message>
-        <message>
-            <source>STB_CLEAR_MESH</source>
-            <translation>Clear Mesh Data</translation>
-        </message>
-        <message>
-            <source>SMESH_IMPORT_MESH</source>
-            <translation>Import mesh data from files</translation>
-        </message>
-        <message>
-            <source>SMESH_ERR_NOT_SUPPORTED_FORMAT</source>
-            <translation>Unsupported file format</translation>
-        </message>
-        <message>
-            <source>SMESH_ERR_UNKNOWN_IMPORT_ERROR</source>
-            <translation>Unknown error</translation>
-        </message>
-        <message>
-            <source>SMESH_IMPORT_ERRORS</source>
-            <translation>Import operation has finished with errors:</translation>
-        </message>
-        <message>
-            <source>SMESH_DRS_SOME_EMPTY</source>
-            <translation>One or more mesh files were empty, data has not been published</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI</name>
-        <message>
-            <source>NOT_A_VTK_VIEWER</source>
-            <translation>This command is available in VTK viewer only
+    </message>
+    <message>
+        <source>SMESH_PREF_vol_precision</source>
+        <translation>Volume precision</translation>
+    </message>
+    <message>
+        <source>SMESH_PRECISION_HINT</source>
+        <translation>
+Input value precision can be adjusted using
+&apos;%1&apos; parameter in Mesh module preferences.</translation>
+    </message>
+    <message>
+        <source>REMOVE_ORPHAN_NODES_QUESTION</source>
+        <translation>Do you really want to remove all orphan nodes?</translation>
+    </message>
+    <message>
+        <source>NB_NODES_REMOVED</source>
+        <translation>Removed %1 node(s).</translation>
+    </message>
+    <message>
+        <source>SMESH_SAVE_DISTRIBUTION</source>
+        <translation>Export Distribution</translation>
+    </message>
+    <message>
+        <source>SMESH_PLUGINS_OTHER</source>
+        <translation>SMESH plugins</translation>
+    </message>
+    <message>
+        <source>MESH_LOADING_MSG</source>
+        <translation>Loading mesh %0 in progress, please wait...</translation>
+    </message>
+    <message>
+        <source>MESH_LOADING_MSG_FINISHED</source>
+        <translation>Mesh %0 loading done</translation>
+    </message>
+    <message>
+        <source>BALL_DIAMETER</source>
+        <translation>Diameter</translation>
+    </message>
+    <message>
+        <source>BALL_ELEMENT</source>
+        <translation>Ball</translation>
+    </message>
+    <message>
+        <source>DEP_OBJECT</source>
+        <translation>Selected object has been used to create another one.
+It can&apos;t be deleted </translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_GroupDlg</name>
+    <message>
+        <source>ALLOW_ELEM_LIST_MODIF</source>
+        <translation>Enable manual edition</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI</name>
+    <message>
+        <source>NOT_A_VTK_VIEWER</source>
+        <translation>This command is available in VTK viewer only
 Please, create VTK viewer and try again</translation>
-        </message>
-        <message>
-            <source>PREF_AUTO_GROUPS</source>
-            <translation>Automatically create groups for MED export</translation>
-        </message>
-        <message>
-            <source>PREF_GROUP_SEGMENT_LENGTH</source>
-            <translation>Automatic parameters</translation>
-        </message>
-        <message>
-            <source>PREF_SEGMENT_LENGTH</source>
-            <translation>Ratio Bounding Box Diagonal / Max Size</translation>
-        </message>
-        <message>
-            <source>PREF_NB_SEGMENTS</source>
-            <translation>Default Number of Segments</translation>
-        </message>
-        <message>
-            <source>PREF_AUTO_UPDATE</source>
-            <translation>Automatic update</translation>
-        </message>
-        <message>
-            <source>PREF_BACKFACE</source>
-            <translation>Back face</translation>
-        </message>
-        <message>
-            <source>PREF_COLOR</source>
-            <translation>Color</translation>
-        </message>
-        <message>
-            <source>PREF_ORIENTATION_COLOR</source>
-            <translation>Color</translation>
-        </message>
-        <message>
-            <source>PREF_ORIENTATION_3D_VECTORS</source>
-            <translation>3D vectors</translation>
-        </message>
-        <message>
-            <source>PREF_ORIENTATION_SCALE</source>
-            <translation>Scale</translation>
-        </message>
-        <message>
-            <source>PREF_DISPLAY_ENTITY</source>
-            <translation>Display entity</translation>
-        </message>
-        <message>
-            <source>PREF_DISPLAY_MODE</source>
-            <translation>Display mode</translation>
-        </message>
-        <message>
-            <source>PREF_ELEMENTS</source>
-            <translation>Elements</translation>
-        </message>
-        <message>
-            <source>PREF_ELEMENT_COLOR</source>
-            <translation>Element color</translation>
-        </message>
-        <message>
-            <source>PREF_FILL</source>
-            <translation>Fill</translation>
-        </message>
-        <message>
-            <source>PREF_NOTIFY_MODE</source>
-            <translation>Show a computation result notification</translation>
-        </message>
-        <message>
-            <source>PREF_GROUP_ELEMENTS</source>
-            <translation>Elements</translation>
-        </message>
-        <message>
-            <source>PREF_GROUP_EXPORT</source>
-            <translation>Mesh export</translation>
-        </message>
-        <message>
-            <source>PREF_GROUP_FACES_ORIENTATION</source>
-            <translation>Orientation of faces</translation>
-        </message>
-        <message>
-            <source>PREF_GROUP_COMPUTE</source>
-            <translation>Mesh computation</translation>
-        </message>
-        <message>
-            <source>PREF_GROUP_NODES</source>
-            <translation>Nodes</translation>
-        </message>
-        <message>
-            <source>PREF_GROUP_PRECISION</source>
-            <translation>Precision</translation>
-        </message>
-        <message>
-            <source>PREF_GROUP_PRESELECTION</source>
-            <translation>Preselection</translation>
-        </message>
-        <message>
-            <source>PREF_GROUP_QUALITY</source>
-            <translation>Quality controls</translation>
-        </message>
-        <message>
-            <source>PREF_GROUP_SELECTION</source>
-            <translation>Selection</translation>
-        </message>
-        <message>
-            <source>PREF_GROUP_UPDATE</source>
-            <translation>Update</translation>
-        </message>
-        <message>
-            <source>PREF_HIGHLIGHT_COLOR</source>
-            <translation>Highlight color</translation>
-        </message>
-        <message>
-            <source>PREF_LABELS_COLOR</source>
-            <translation>Labels color</translation>
-        </message>
-        <message>
-            <source>PREF_NODES</source>
-            <translation>Nodes</translation>
-        </message>
-        <message>
-            <source>PREF_OBJECTS</source>
-            <translation>Objects</translation>
-        </message>
-        <message>
-            <source>PREF_OBJECT_COLOR</source>
-            <translation>Object color</translation>
-        </message>
-        <message>
-            <source>PREF_OUTLINE</source>
-            <translation>Outline</translation>
-        </message>
-        <message>
-            <source>PREF_PRECISION_USE</source>
-            <translation>Use precision</translation>
-        </message>
-        <message>
-            <source>PREF_PRECISION_VALUE</source>
-            <translation>Number of digits after point</translation>
-        </message>
-        <message>
-            <source>PREF_RENUMBER</source>
-            <translation>Automatic renumbering</translation>
-        </message>
-        <message>
-            <source>PREF_SHRINK_COEFF</source>
-            <translation>Shrink coef.</translation>
-        </message>
-        <message>
-            <source>PREF_SIZE</source>
-            <translation>Size</translation>
-        </message>
-        <message>
-            <source>PREF_TAB_GENERAL</source>
-            <translation>General</translation>
-        </message>
-        <message>
-            <source>PREF_TAB_MESH</source>
-            <translation>Mesh</translation>
-        </message>
-        <message>
-            <source>PREF_TAB_SELECTION</source>
-            <translation>Selection</translation>
-        </message>
-        <message>
-            <source>PREF_TITLE_COLOR</source>
-            <translation>Title color</translation>
-        </message>
-        <message>
-            <source>PREF_WIDTH</source>
-            <translation>Width</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_AddQuadraticElementDlg</name>
-        <message>
-            <source>SMESH_ADD_QUADRATIC_EDGE</source>
-            <translation>Add Quadratic Edge</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_QUADRATIC_HEXAHEDRON</source>
-            <translation>Add Quadratic Hexahedron</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_QUADRATIC_PENTAHEDRON</source>
-            <translation>Add Quadratic Pentahedron</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_QUADRATIC_PYRAMID</source>
-            <translation>Add Quadratic Pyramid</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_QUADRATIC_QUADRANGLE</source>
-            <translation>Add Quadratic Quadrangle</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_QUADRATIC_TETRAHEDRON</source>
-            <translation>Add Quadratic Tetrahedron</translation>
-        </message>
-        <message>
-            <source>SMESH_ADD_QUADRATIC_TRIANGLE</source>
-            <translation>Add Quadratic Triangle</translation>
-        </message>
-        <message>
-            <source>SMESH_CORNER_NODES</source>
-            <translation>Corner Nodes:</translation>
-        </message>
-        <message>
-            <source>SMESH_FIRST</source>
-            <translation>First</translation>
-        </message>
-        <message>
-            <source>SMESH_LAST</source>
-            <translation>Last</translation>
-        </message>
-        <message>
-            <source>SMESH_MIDDLE</source>
-            <translation>Middle</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_BuildCompoundDlg</name>
-        <message>
-            <source>COMPOUND</source>
-            <translation>Compound</translation>
-        </message>
-        <message>
-            <source>COMPOUND_MESH</source>
-            <translation>Compound_Mesh</translation>
-        </message>
-        <message>
-            <source>CREATE_COMMON_GROUPS</source>
-            <translation>Create common groups for initial meshes</translation>
-        </message>
-        <message>
-            <source>MERGE_NODES_AND_ELEMENTS</source>
-            <translation>Merge coincident nodes and elements</translation>
-        </message>
-        <message>
-            <source>MESHES</source>
-            <translation>Meshes</translation>
-        </message>
-        <message>
-            <source>PROCESSING_IDENTICAL_GROUPS</source>
-            <translation>Processing identical groups</translation>
-        </message>
-        <message>
-            <source>RENAME</source>
-            <translation>Rename</translation>
-        </message>
-        <message>
-            <source>RESULT_NAME</source>
-            <translation>Result name</translation>
-        </message>
-        <message>
-            <source>UNITE</source>
-            <translation>Unite</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_ChangeOrientationDlg</name>
-        <message>
-            <source>CAPTION</source>
-            <translation>Modification of orientation</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_ComputeDlg</name>
-        <message>
-            <source>CAPTION</source>
-            <translation>Compute mesh failed</translation>
-        </message>
-        <message>
-            <source>CONSTRUCTOR</source>
-            <translation>Compute mesh</translation>
-        </message>
-        <message>
-            <source>ERRORS</source>
-            <translation>Errors</translation>
-        </message>
-        <message>
-            <source>MEMORY_LACK</source>
-            <translation>Memory allocation problem</translation>
-        </message>
-        <message>
-            <source>PUBLISH_SHAPE</source>
-            <translation>Publish SubShape</translation>
-        </message>
-        <message>
-            <source>SHOW_SHAPE</source>
-            <translation>Show SubShape</translation>
-        </message>
-        <message>
-            <source>SHOW_BAD_MESH</source>
-            <translation>Show bad Mesh</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_PrecomputeDlg</name>
-        <message>
-            <source>CAPTION</source>
-            <translation>Preview and Compute mesh</translation>
-        </message>
-        <message>
-            <source>PREVIEW</source>
-            <translation>Preview</translation>
-        </message>
-        <message>
-            <source>PREVIEW_1</source>
-            <translation>1D Mesh</translation>
-        </message>
-        <message>
-            <source>PREVIEW_2</source>
-            <translation>2D Mesh</translation>
-        </message>
-        <message>
-            <source>COMPUTE</source>
-            <translation>Compute</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_PrecomputeOp</name>
-        <message>
-            <source>CLEAR_SUBMESH_QUESTION</source>
-            <translation>A temporary submeshes on the selected geometry
- created during preview operation.
- Do you want to remove all this submeshes?</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_ConvToQuadDlg</name>
-        <message>
-            <source>CAPTION</source>
-            <translation>Convert to/from quadratic</translation>
-        </message>
-        <message>
-            <source>MEDIUMNDS</source>
-            <translation>Medium nodes on geometry</translation>
-        </message>
-        <message>
-            <source>MESH</source>
-            <translation>Mesh</translation>
-        </message>
-        <message>
-            <source>RADIOBTN_1</source>
-            <translation>Convert to quadratic</translation>
-        </message>
-        <message>
-            <source>RADIOBTN_2</source>
-            <translation>Convert from quadratic</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_ConvToQuadOp</name>
-        <message>
-            <source>MESH_IS_NOT_SELECTED</source>
-            <translation>Mesh is not selected
+    </message>
+    <message>
+        <source>PREF_AUTO_GROUPS</source>
+        <translation>Automatically create groups for MED export</translation>
+    </message>
+    <message>
+        <source>PREF_GROUP_SEGMENT_LENGTH</source>
+        <translation>Automatic parameters</translation>
+    </message>
+    <message>
+        <source>PREF_SEGMENT_LENGTH</source>
+        <translation>Ratio Bounding Box Diagonal / Max Size</translation>
+    </message>
+    <message>
+        <source>PREF_NB_SEGMENTS</source>
+        <translation>Default Number of Segments</translation>
+    </message>
+    <message>
+        <source>SMESH_PREF_MESH_LOADING</source>
+        <translation>Mesh loading</translation>
+    </message>
+    <message>
+        <source>PREF_FORGET_MESH_AT_HYP_MODIF</source>
+        <translation>No mesh loading from study file at hypothesis modification</translation>
+    </message>
+    <message>
+        <source>PREF_AUTO_UPDATE</source>
+        <translation>Automatic update</translation>
+    </message>
+    <message>
+        <source>PREF_UPDATE_LIMIT</source>
+        <translation>Size limit (elements)</translation>
+    </message>
+    <message>
+        <source>PREF_UPDATE_LIMIT_NOLIMIT</source>
+        <translation>No limit</translation>
+    </message>
+    <message>
+        <source>PREF_BACKFACE</source>
+        <translation>Back surface color</translation>
+    </message>
+    <message>
+        <source>PREF_WIREFRAME</source>
+        <translation>Wireframe color</translation>
+    </message>
+    <message>
+        <source>PREF_SELECTION</source>
+        <translation>Selection color</translation>
+    </message>
+    <message>
+        <source>PREF_PRE_SELECTION</source>
+        <translation>Pre-selection color</translation>
+    </message>    
+    <message>
+        <source>PREF_COLOR</source>
+        <translation>Color</translation>
+    </message>
+    <message>
+        <source>PREF_ORIENTATION_COLOR</source>
+        <translation>Color</translation>
+    </message>
+    <message>
+        <source>PREF_ORIENTATION_3D_VECTORS</source>
+        <translation>3D vectors</translation>
+    </message>
+    <message>
+        <source>PREF_ORIENTATION_SCALE</source>
+        <translation>Scale</translation>
+    </message>
+    <message>
+        <source>PREF_DISPLAY_ENTITY</source>
+        <translation>Display entity</translation>
+    </message>
+    <message>
+        <source>QUADRATIC_REPRESENT_MODE</source>
+        <translation>Representation of the 2D quadratic elements</translation>
+    </message>
+    <message>
+        <source>MAX_ARC_ANGLE</source>
+        <translation>Maximum angle</translation>
+    </message>
+    <message>
+        <source>PREF_DISPLAY_MODE</source>
+        <translation>Display mode</translation>
+    </message>
+    <message>
+        <source>PREF_ELEMENTS</source>
+        <translation>Elements</translation>
+    </message>
+    <message>
+        <source>PREF_ELEMENT_COLOR</source>
+        <translation>Element color</translation>
+    </message>
+    <message>
+        <source>PREF_FILL</source>
+        <translation>Surface color</translation>
+    </message>
+    <message>
+        <source>PREF_NOTIFY_MODE</source>
+        <translation>Show a computation result notification</translation>
+    </message>
+    <message>
+        <source>PREF_NOTIFY_NEVER</source>
+        <translation>Never</translation>
+    </message>
+    <message>
+        <source>PREF_NOTIFY_ERROR</source>
+        <translation>Errors only</translation>
+    </message>
+    <message>
+        <source>PREF_NOTIFY_ALWAYS</source>
+        <translation>Always</translation>
+    </message>
+    <message>
+        <source>PREF_ELEM_INFO</source>
+        <translation>Mesh element information</translation>
+    </message>
+    <message>
+        <source>PREF_ELEM_INFO_SIMPLE</source>
+        <translation>Simple</translation>
+    </message>
+    <message>
+        <source>PREF_ELEM_INFO_TREE</source>
+        <translation>Tree</translation>
+    </message>
+    <message>
+        <source>PREF_GPP_NODES_LIMIT</source>
+        <translation>Automatic nodes compute limit</translation>
+    </message>
+    <message>
+        <source>SMESH_PREF_GROUP_PRECISION</source>
+        <translation>Input fields precision</translation>
+    </message>
+    <message>
+        <source>SMESH_PREF_GROUP_PREVIEW</source>
+        <translation>Preview</translation>
+    </message>
+    <message>
+        <source>PREF_GROUP_ELEMENTS</source>
+        <translation>Elements</translation>
+    </message>
+    <message>
+        <source>PREF_GROUP_EXPORT</source>
+        <translation>Mesh export</translation>
+    </message>
+    <message>
+        <source>PREF_GROUP_FACES_ORIENTATION</source>
+        <translation>Orientation of faces</translation>
+    </message>
+    <message>
+        <source>PREF_GROUP_COMPUTE</source>
+        <translation>Mesh computation</translation>
+    </message>
+    <message>
+        <source>PREF_GROUP_NODES</source>
+        <translation>Nodes</translation>
+    </message>
+    <message>
+        <source>PREF_GROUP_GROUPS</source>
+        <translation>Groups</translation>
+    </message>
+    <message>
+        <source>PREF_GRP_NAMES</source>
+        <translation>Names color</translation>
+    </message>
+    <message>
+        <source>PREF_GROUP_PRECISION</source>
+        <translation>Precision</translation>
+    </message>
+    <message>
+        <source>PREF_GROUP_PRESELECTION</source>
+        <translation>Preselection</translation>
+    </message>
+    <message>
+        <source>PREF_GROUP_QUALITY</source>
+        <translation>Quality controls</translation>
+    </message>
+    <message>
+        <source>PREF_GROUP_SELECTION</source>
+        <translation>Selection</translation>
+    </message>
+    <message>
+        <source>PREF_GROUP_INFO</source>
+        <translation>Mesh information</translation>
+    </message>
+    <message>
+        <source>PREF_HIGHLIGHT_COLOR</source>
+        <translation>Highlight color</translation>
+    </message>
+    <message>
+        <source>PREF_LABELS_COLOR</source>
+        <translation>Labels color</translation>
+    </message>
+    <message>
+        <source>PREF_MARKER_SCALE</source>
+        <translation>Scale of marker</translation>
+    </message>
+    <message>
+        <source>PREF_NODES</source>
+        <translation>Nodes</translation>
+    </message>
+    <message>
+        <source>PREF_OBJECTS</source>
+        <translation>Objects</translation>
+    </message>
+    <message>
+        <source>PREF_OBJECT_COLOR</source>
+        <translation>Object color</translation>
+    </message>
+    <message>
+        <source>PREF_OUTLINE</source>
+        <translation>Outline color</translation>
+    </message>
+    <message>
+        <source>PREF_PRECISION_USE</source>
+        <translation>Use precision</translation>
+    </message>
+    <message>
+        <source>PREF_PRECISION_VALUE</source>
+        <translation>Number of digits after point</translation>
+    </message>
+    <message>
+        <source>PREF_EQUAL_NODES_TOL</source>
+        <translation>Double nodes tolerance</translation>
+    </message>
+    <message>
+        <source>PREF_RENUMBER</source>
+        <translation>Automatic renumbering</translation>
+    </message>
+    <message>
+        <source>PREF_SHRINK_COEFF</source>
+        <translation>Shrink coef.</translation>
+    </message>
+    <message>
+        <source>PREF_PYTHON_DUMP</source>
+        <translation>Python Dump</translation>
+    </message>
+    <message>
+        <source>PREF_HISTORICAL_PYTHON_DUMP</source>
+        <translation>Historical python dump</translation>
+    </message>
+    <message>
+        <source>PREF_TAB_GENERAL</source>
+        <translation>General</translation>
+    </message>
+    <message>
+        <source>PREF_TAB_MESH</source>
+        <translation>Mesh</translation>
+    </message>
+    <message>
+        <source>PREF_TAB_SELECTION</source>
+        <translation>Selection</translation>
+    </message>
+    <message>
+        <source>PREF_TITLE_COLOR</source>
+        <translation>Title color</translation>
+    </message>
+    <message>
+        <source>PREF_TYPE_OF_MARKER</source>
+        <translation>Type of marker</translation>
+    </message>
+    <message>
+        <source>PREF_COLOR_0D</source>
+        <translation>0D elements</translation>
+    </message>
+    <message>
+        <source>PREF_SIZE_0D</source>
+        <translation>Size of 0D elements</translation>
+    </message>
+    <message>
+        <source>PREF_BALL_COLOR</source>
+        <translation>Balls</translation>
+    </message>
+    <message>
+        <source>PREF_BALL_SIZE</source>
+        <translation>Size of ball elements</translation>
+    </message>
+    <message>
+        <source>PREF_WIDTH</source>
+        <translation>Width</translation>
+    </message>
+    <message>
+        <source>PREF_PREVIEW_CHUNK_SIZE</source>
+        <translation>Sub-shapes preview chunk size</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_AddQuadraticElementDlg</name>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_EDGE</source>
+        <translation>Add Quadratic Edge</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_HEXAHEDRON</source>
+        <translation>Add Quadratic Hexahedron</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_TRIQUADRATIC_HEXAHEDRON</source>
+        <translation>Add TriQuadratic Hexahedron</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_PENTAHEDRON</source>
+        <translation>Add Quadratic Pentahedron</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_PYRAMID</source>
+        <translation>Add Quadratic Pyramid</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_QUADRANGLE</source>
+        <translation>Add Quadratic Quadrangle</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_BIQUADRATIC_QUADRANGLE</source>
+        <translation>Add BiQuadratic Quadrangle</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_TETRAHEDRON</source>
+        <translation>Add Quadratic Tetrahedron</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_TRIANGLE</source>
+        <translation>Add Quadratic Triangle</translation>
+    </message>
+    <message>
+        <source>SMESH_CORNER_NODES</source>
+        <translation>Corner Nodes:</translation>
+    </message>
+    <message>
+        <source>SMESH_MIDFACE_NODES</source>
+        <translation>Mid-face Nodes:</translation>
+    </message>
+    <message>
+        <source>SMESH_CENTER_NODE</source>
+        <translation>Center Node:</translation>
+    </message>
+    <message>
+        <source>SMESH_FIRST</source>
+        <translation>First</translation>
+    </message>
+    <message>
+        <source>SMESH_LAST</source>
+        <translation>Last</translation>
+    </message>
+    <message>
+        <source>SMESH_MIDDLE</source>
+        <translation>Middle</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_BuildCompoundDlg</name>
+    <message>
+        <source>COMPOUND</source>
+        <translation>Compound</translation>
+    </message>
+    <message>
+        <source>COMPOUND_MESH</source>
+        <translation>Compound_Mesh</translation>
+    </message>
+    <message>
+        <source>CREATE_COMMON_GROUPS</source>
+        <translation>Create common groups for initial meshes</translation>
+    </message>
+    <message>
+        <source>MERGE_NODES_AND_ELEMENTS</source>
+        <translation>Merge coincident nodes and elements</translation>
+    </message>
+    <message>
+        <source>MESHES</source>
+        <translation>Meshes</translation>
+    </message>
+    <message>
+        <source>PROCESSING_IDENTICAL_GROUPS</source>
+        <translation>Processing identical groups</translation>
+    </message>
+    <message>
+        <source>RENAME</source>
+        <translation>Rename</translation>
+    </message>
+    <message>
+        <source>RESULT_NAME</source>
+        <translation>Result name</translation>
+    </message>
+    <message>
+        <source>UNITE</source>
+        <translation>Unite</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_ChangeOrientationDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Modification of orientation</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_ComputeDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Compute mesh failed</translation>
+    </message>
+    <message>
+        <source>CONSTRUCTOR</source>
+        <translation>Compute mesh</translation>
+    </message>
+    <message>
+        <source>EVAL_DLG</source>
+        <translation>Evaluate mesh</translation>
+    </message>
+    <message>
+        <source>ERRORS</source>
+        <translation>Errors</translation>
+    </message>
+    <message>
+        <source>MEMORY_LACK</source>
+        <translation>Memory allocation problem</translation>
+    </message>
+    <message>
+        <source>COMPUTE_WARNING</source>
+        <translation>The mesh seems to be OK but there are some errors reported</translation>
+    </message>
+    <message>
+        <source>PUBLISH_SHAPE</source>
+        <translation>Publish Sub-shape</translation>
+    </message>
+    <message>
+        <source>SHOW_SHAPE</source>
+        <translation>Show Sub-shape</translation>
+    </message>
+    <message>
+        <source>SHOW_BAD_MESH</source>
+        <translation>Show bad Mesh</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_PrecomputeDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Preview and Compute mesh</translation>
+    </message>
+    <message>
+        <source>PREVIEW</source>
+        <translation>Preview</translation>
+    </message>
+    <message>
+        <source>PREVIEW_1</source>
+        <translation>1D Mesh</translation>
+    </message>
+    <message>
+        <source>PREVIEW_2</source>
+        <translation>2D Mesh</translation>
+    </message>
+    <message>
+        <source>COMPUTE</source>
+        <translation>Compute</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_PrecomputeOp</name>
+    <message>
+        <source>CLEAR_SUBMESH_QUESTION</source>
+        <translation>Temporary submeshes on the selected geometry
+were created during preview operation.
+Do you want to remove all these submeshes?</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_NOTHING_PREVIEW</source>
+        <translation>No mesh preview is available</translation>
+    </message>
+    <message>
+        <source>SMESH_REJECT_MESH_ORDER</source>
+        <translation>The submesh priority changed during preview operation.
+Do you want to restore original submesh priority?</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_ConvToQuadDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Convert to/from quadratic</translation>
+    </message>
+    <message>
+        <source>MEDIUMNDS</source>
+        <translation>Medium nodes on geometry</translation>
+    </message>
+    <message>
+        <source>MESH</source>
+        <translation>Mesh or Sub-mesh</translation>
+    </message>
+    <message>
+        <source>RADIOBTN_1</source>
+        <translation>Convert to quadratic</translation>
+    </message>
+    <message>
+        <source>RADIOBTN_2</source>
+        <translation>Convert from quadratic</translation>
+    </message>
+    <message>
+        <source>NON_CONFORM_WARNING</source>
+        <translation>Warning: mesh can become non-conformal</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_ConvToQuadOp</name>
+    <message>
+        <source>MESH_IS_NOT_SELECTED</source>
+        <translation>Mesh is not selected
+Please specify it and try again</translation>
+    </message>
+    <message>
+        <source>REF_IS_NULL</source>
+        <translation>No valid mesh object selected</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_CreatePatternDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Pattern Creation</translation>
+    </message>
+    <message>
+        <source>DEFAULT_2D</source>
+        <translation>Pattern_2d</translation>
+    </message>
+    <message>
+        <source>DEFAULT_3D</source>
+        <translation>Pattern_3d</translation>
+    </message>
+    <message>
+        <source>ERROR_OF_CREATION</source>
+        <translation>Internal error occurs during pattern creation
+Please verify validity of entered information</translation>
+    </message>
+    <message>
+        <source>ERROR_OF_SAVING</source>
+        <translation>Internal error occurs during pattern saving. Please verify
+\free disk space and your write permission to this file</translation>
+    </message>
+    <message>
+        <source>ERR_LOADF_CANT_PROJECT</source>
+        <translation>Impossible to perform projection of nodes to the face</translation>
+    </message>
+    <message>
+        <source>ERR_LOADF_CLOSED_FACE</source>
+        <translation>It is impossible to create pattern from face having seam edge</translation>
+    </message>
+    <message>
+        <source>ERR_LOADF_NARROW_FACE</source>
+        <translation>It is impossible to create pattern from narrow face</translation>
+    </message>
+    <message>
+        <source>ERR_LOADV_BAD_SHAPE</source>
+        <translation>Pattern can be created from closed shell or solid with 6 faces only</translation>
+    </message>
+    <message>
+        <source>ERR_LOADV_COMPUTE_PARAMS</source>
+        <translation>It is impossible to compute point parameters</translation>
+    </message>
+    <message>
+        <source>ERR_LOAD_EMPTY_SUBMESH</source>
+        <translation>There are no elements to create pattern</translation>
+    </message>
+    <message>
+        <source>MESH_OR_SUBMESH</source>
+        <translation>Mesh or SubMesh</translation>
+    </message>
+    <message>
+        <source>PATTERN</source>
+        <translation>Pattern</translation>
+    </message>
+    <message>
+        <source>PATTERN_FILT</source>
+        <translation>Pattern files(*.smp)</translation>
+    </message>
+    <message>
+        <source>PATTERN_NAME</source>
+        <translation>Pattern name</translation>
+    </message>
+    <message>
+        <source>PATTERN_TYPE</source>
+        <translation>Pattern type</translation>
+    </message>
+    <message>
+        <source>PROJECT</source>
+        <translation>Project nodes on the face</translation>
+    </message>
+    <message>
+        <source>SAVE</source>
+        <translation>Save...</translation>
+    </message>
+    <message>
+        <source>SAVE_PATTERN</source>
+        <translation>Save Pattern</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_CreatePolyhedralVolumeDlg</name>
+    <message>
+        <source>FACES_BY_NODES</source>
+        <translation>Faces by nodes</translation>
+    </message>
+    <message>
+        <source>SMESH_POLYEDRE_CREATE_ERROR</source>
+        <translation>Polyhedron creation error.</translation>
+    </message>
+    <message>
+        <source>SMESH_POLYEDRE_PREVIEW</source>
+        <translation>Polyhedron preview</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_CuttingOfQuadsDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Cutting of quadrangles</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_DeleteGroupDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Delete groups with contents</translation>
+    </message>
+    <message>
+        <source>NO_SELECTED_GROUPS</source>
+        <translation>There are no selected groups
+Please select a group and try again</translation>
+    </message>
+    <message>
+        <source>SELECTED_GROUPS</source>
+        <translation>Selected groups</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MergeDlg</name>
+    <message>
+        <source>COINCIDENT_ELEMENTS</source>
+        <translation>Coincident elements</translation>
+    </message>
+    <message>
+        <source>COINCIDENT_NODES</source>
+        <translation>Coincident nodes</translation>
+    </message>
+    <message>
+        <source>DETECT</source>
+        <translation>Detect</translation>
+    </message>
+    <message>
+        <source>EDIT_SELECTED_GROUP</source>
+        <translation>Edit selected group</translation>
+    </message>
+    <message>
+        <source>SELECT_ALL</source>
+        <translation>Select all</translation>
+    </message>
+    <message>
+        <source>EXCLUDE_GROUPS</source>
+        <translation>Exclude Groups</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_ExtrusionAlongPathDlg</name>
+    <message>
+        <source>BAD_SHAPE_TYPE</source>
+        <translation>The shape selected for the path is not edge</translation>
+    </message>
+    <message>
+        <source>CANT_GET_TANGENT</source>
+        <translation>Can&apos;t get tangent for one of the path nodes</translation>
+    </message>
+    <message>
+        <source>EXTRUSION_0D</source>
+        <translation>Extrusion of 0D elements</translation>
+    </message>
+    <message>
+        <source>EXTRUSION_1D</source>
+        <translation>Extrusion of 1D elements</translation>
+    </message>
+    <message>
+        <source>EXTRUSION_2D</source>
+        <translation>Extrusion of 2D elements</translation>
+    </message>
+    <message>
+        <source>EXTRUSION_ALONG_PATH</source>
+        <translation>Extrusion along a path</translation>
+    </message>
+    <message>
+        <source>EXTR_BAD_STARTING_NODE</source>
+        <translation>Wrong path starting node</translation>
+    </message>
+    <message>
+        <source>LINEAR_ANGLES</source>
+        <translation>Linear variation of the angles</translation>
+    </message>
+    <message>
+        <source>NO_ELEMENTS_SELECTED</source>
+        <translation>No mesh elements are selected for extrusion</translation>
+    </message>
+    <message>
+        <source>SELECTED_PATH_IS_NOT_EDGE</source>
+        <translation>Path mesh should be of edge type</translation>
+    </message>
+    <message>
+        <source>SMESH_ANGLES</source>
+        <translation>Rotation Angles</translation>
+    </message>
+    <message>
+        <source>SMESH_BASE_POINT</source>
+        <translation>Base Point</translation>
+    </message>
+    <message>
+        <source>SMESH_PATH</source>
+        <translation>Path</translation>
+    </message>
+    <message>
+        <source>SMESH_PATH_MESH</source>
+        <translation>Mesh or submesh</translation>
+    </message>
+    <message>
+        <source>SMESH_PATH_SHAPE</source>
+        <translation>Shape (edge)</translation>
+    </message>
+    <message>
+        <source>SMESH_PATH_START</source>
+        <translation>Start node</translation>
+    </message>
+    <message>
+        <source>SMESH_USE_ANGLES</source>
+        <translation>Use Angles</translation>
+    </message>
+    <message>
+        <source>SMESH_USE_BASE_POINT</source>
+        <translation>Use Base Point</translation>
+    </message>
+    <message>
+        <source>WRONG_ANGLES_NUMBER</source>
+        <translation>The number of angles should correspond to the number of path nodes</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_ExtrusionDlg</name>
+    <message>
+        <source>EXTRUSION_0D</source>
+        <translation>Extrusion of nodes</translation>
+    </message>
+    <message>
+        <source>EXTRUSION_1D</source>
+        <translation>Extrusion of 1D elements</translation>
+    </message>
+    <message>
+        <source>EXTRUSION_2D</source>
+        <translation>Extrusion of 2D elements</translation>
+    </message>
+    <message>
+        <source>EXTRUSION_ALONG_LINE</source>
+        <translation>Extrusion along a line</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_FilterDlg</name>
+    <message>
+        <source>BAD_SHAPE_NAME</source>
+        <translation>There is no &quot;%1&quot; geometrical object in the current study
+Please select valid object and try again</translation>
+    </message>
+    <message>
+        <source>CURRENT_DIALOG</source>
+        <translation>Current Group</translation>
+    </message>
+    <message>
+        <source>EDGES_TLT</source>
+        <translation>Filter for Edges</translation>
+    </message>
+    <message>
+        <source>FACES_TLT</source>
+        <translation>Filter for Faces</translation>
+    </message>
+    <message>
+        <source>MESH</source>
+        <translation>Mesh</translation>
+    </message>
+    <message>
+        <source>NODES_TLT</source>
+        <translation>Filter for Nodes</translation>
+    </message>
+    <message>
+        <source>SELECTION</source>
+        <translation>Initial Selection</translation>
+    </message>
+    <message>
+        <source>SET_IN_VIEWER</source>
+        <translation>Insert filter in viewer</translation>
+    </message>
+    <message>
+        <source>SHAPE_IS_NOT_A_CYLINDER</source>
+        <translation>&quot;%1&quot; is not a cylinderical face
+Please select a cylindrical face and try again</translation>
+    </message>
+    <message>
+        <source>SHAPE_IS_NOT_A_FACE</source>
+        <translation>&quot;%1&quot; is not a face
+Please select a face and try again</translation>
+    </message>
+    <message>
+        <source>SHAPE_IS_NOT_A_PLANE</source>
+        <translation>&quot;%1&quot; is not a plane
+Please select a plane and try again</translation>
+    </message>
+    <message>
+        <source>FACE_ID_NOT_SELECTED</source>
+        <translation>Mesh face is not selected
+Please specify it and try again</translation>
+    </message>
+    <message>
+        <source>NOT_FACE_ID</source>
+        <translation>&quot;%1&quot; is not an ID of a mesh face.
+Please select a face and try again</translation>
+    </message>
+    <message>
+        <source>SOURCE</source>
+        <translation>Source</translation>
+    </message>
+    <message>
+        <source>TLT</source>
+        <translation>Selection filter</translation>
+    </message>
+    <message>
+        <source>VOLUMES_TLT</source>
+        <translation>Filter for Volumes</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_FilterLibraryDlg</name>
+    <message>
+        <source>ADD</source>
+        <translation>Add</translation>
+    </message>
+    <message>
+        <source>ADD_TO_TLT</source>
+        <translation>Add selection filter to library</translation>
+    </message>
+    <message>
+        <source>ALL_FILES_FILTER</source>
+        <translation>All Files (*.*)</translation>
+    </message>
+    <message>
+        <source>ASSIGN_NEW_NAME</source>
+        <translation>Library already contains filter with name &quot;%1&quot;
+New name &quot;%2&quot; is assigned to added filter</translation>
+    </message>
+    <message>
+        <source>COPY_FROM_TLT</source>
+        <translation>Copy selection filter from library</translation>
+    </message>
+    <message>
+        <source>DELETE</source>
+        <translation>Delete</translation>
+    </message>
+    <message>
+        <source>EDGE</source>
+        <translation>Edge</translation>
+    </message>
+    <message>
+        <source>EDIT_LIB_TLT</source>
+        <translation>Selection filter library</translation>
+    </message>
+    <message>
+        <source>ELEMENT</source>
+        <translation>Element</translation>
+    </message>
+    <message>
+        <source>EMPTY_FILTER_NAME</source>
+        <translation>Name of the filter is empty
+Please enter a non-empty name</translation>
+    </message>
+    <message>
+        <source>ERROR_FILTER_NAME</source>
+        <translation>Name of the filter is not unique
+Please enter other name</translation>
+    </message>
+    <message>
+        <source>ERROR_LOAD</source>
+        <translation>It is impossible to load library
+Please check library file name and attributes</translation>
+    </message>
+    <message>
+        <source>ERROR_OF_ADDING</source>
+        <translation>Internal error occurs during adiing new filter in library.
+Please verify validity of entered information</translation>
+    </message>
+    <message>
+        <source>ERROR_OF_COPYING</source>
+        <translation>Internal error occurs during copying filter from library.
+Please verify validity of entered information</translation>
+    </message>
+    <message>
+        <source>ERROR_OF_DELETING</source>
+        <translation>Internal error occurs during deleting filter from library.
+Please verify validity of entered information</translation>
+    </message>
+    <message>
+        <source>ERROR_OF_EDITING</source>
+        <translation>Internal error occurs during editing filter library.
+Please verify validity of entered information</translation>
+    </message>
+    <message>
+        <source>ERROR_OF_SAVING</source>
+        <translation>Internal error occurs during saving filter library
+Please check input data and try again</translation>
+    </message>
+    <message>
+        <source>FACE</source>
+        <translation>Face</translation>
+    </message>
+    <message>
+        <source>FILTER</source>
+        <translation>Filter</translation>
+    </message>
+    <message>
+        <source>FILTER_NAME</source>
+        <translation>Filter name</translation>
+    </message>
+    <message>
+        <source>FILTER_NAMES</source>
+        <translation>Names of filters</translation>
+    </message>
+    <message>
+        <source>LIBRARY_FILE</source>
+        <translation>Library file name</translation>
+    </message>
+    <message>
+        <source>LIBRARY_IS_NOT_LOADED</source>
+        <translation>Library is not loaded. Please load library and try again</translation>
+    </message>
+    <message>
+        <source>LIB_NAME</source>
+        <translation>FilterLib.xml</translation>
+    </message>
+    <message>
+        <source>NODE</source>
+        <translation>Node</translation>
+    </message>
+    <message>
+        <source>NO_PERMISSION</source>
+        <translation>You do not have write permission to this file</translation>
+    </message>
+    <message>
+        <source>OPEN_LIBRARY</source>
+        <translation>Open library</translation>
+    </message>
+    <message>
+        <source>SELECTION</source>
+        <translation>Selection</translation>
+    </message>
+    <message>
+        <source>VOLUME</source>
+        <translation>Volume</translation>
+    </message>
+    <message>
+        <source>XML_FILT</source>
+        <translation>XML files(*.xml)</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_FilterTable</name>
+    <message>
+        <source>ADD</source>
+        <translation>Add</translation>
+    </message>
+    <message>
+        <source>ADDITIONAL_PARAMETERS</source>
+        <translation>Additional parameters</translation>
+    </message>
+    <message>
+        <source>ADD_TO</source>
+        <translation>Add to...</translation>
+    </message>
+    <message>
+        <source>AND</source>
+        <translation>And</translation>
+    </message>
+    <message>
+        <source>AREA</source>
+        <translation>Area</translation>
+    </message>
+    <message>
+        <source>ASPECT_RATIO</source>
+        <translation>Aspect ratio</translation>
+    </message>
+    <message>
+        <source>ASPECT_RATIO_3D</source>
+        <translation>Aspect ratio 3D</translation>
+    </message>
+    <message>
+        <source>BAD_ORIENTED_VOLUME</source>
+        <translation>Bad oriented volume</translation>
+    </message>
+    <message>
+        <source>BARE_BORDER_VOLUME</source>
+        <translation>Volumes with bare border</translation>
+    </message>
+    <message>
+        <source>BARE_BORDER_FACE</source>
+        <translation>Faces with bare border</translation>
+    </message>
+    <message>
+        <source>OVER_CONSTRAINED_VOLUME</source>
+        <translation>Over-constrained volumes</translation>
+    </message>
+    <message>
+        <source>OVER_CONSTRAINED_FACE</source>
+        <translation>Over-constrained faces</translation>
+    </message>
+    <message>
+        <source>BELONG_TO_CYLINDER</source>
+        <translation>Belong to Cylinder</translation>
+    </message>
+    <message>
+        <source>BELONG_TO_GENSURFACE</source>
+        <translation>Belong to Surface</translation>
+    </message>
+    <message>
+        <source>BELONG_TO_GEOM</source>
+        <translation>Belong to Geom</translation>
+    </message>
+    <message>
+        <source>BELONG_TO_PLANE</source>
+        <translation>Belong to Plane</translation>
+    </message>
+    <message>
+        <source>BINARY</source>
+        <translation>Binary</translation>
+    </message>
+    <message>
+        <source>CLEAR</source>
+        <translation>Clear</translation>
+    </message>
+    <message>
+        <source>COMPARE</source>
+        <translation>Compare</translation>
+    </message>
+    <message>
+        <source>COPLANAR_FACES</source>
+        <translation>Coplanar faces</translation>
+    </message>
+    <message>
+        <source>COPY_FROM</source>
+        <translation>Copy from...</translation>
+    </message>
+    <message>
+        <source>CRITERION</source>
+        <translation>Criterion</translation>
+    </message>
+    <message>
+        <source>BALLS</source>
+        <translation>Balls</translation>
+    </message>
+    <message>
+        <source>EDGES</source>
+        <translation>Edges</translation>
+    </message>
+    <message>
+        <source>ENTITY_TYPE</source>
+        <translation>Entity type</translation>
+    </message>
+    <message>
+        <source>EQUAL_TO</source>
+        <translation>Equal to</translation>
+    </message>
+    <message>
+        <source>ERROR</source>
+        <translation>Threshold value is not correctly specified
+Please enter correct value and try again</translation>
+    </message>
+    <message>
+        <source>FACES</source>
+        <translation>Faces</translation>
+    </message>
+    <message>
+        <source>FILTER</source>
+        <translation>Filter</translation>
+    </message>
+    <message>
+        <source>FREE_BORDERS</source>
+        <translation>Free borders</translation>
+    </message>
+    <message>
+        <source>FREE_EDGES</source>
+        <translation>Free edges</translation>
+    </message>
+    <message>
+        <source>FREE_NODES</source>
+        <translation>Free nodes</translation>
+    </message>
+    <message>
+        <source>FREE_FACES</source>
+        <translation>Free faces</translation>
+    </message>
+    <message>
+        <source>ID</source>
+        <translation>ID</translation>
+    </message>
+    <message>
+        <source>INSERT</source>
+        <translation>Insert</translation>
+    </message>
+    <message>
+        <source>LENGTH</source>
+        <translation>Length</translation>
+    </message>
+    <message>
+        <source>LENGTH2D</source>
+        <translation>Length 2D</translation>
+    </message>
+    <message>
+        <source>LESS_THAN</source>
+        <translation>Less than</translation>
+    </message>
+    <message>
+        <source>LYING_ON_GEOM</source>
+        <translation>Lying on Geom</translation>
+    </message>
+    <message>
+        <source>MAX_ELEMENT_LENGTH_2D</source>
+        <translation>Element Diameter 2D</translation>
+    </message>
+    <message>
+        <source>MAX_ELEMENT_LENGTH_3D</source>
+        <translation>Element Diameter 3D</translation>
+    </message>
+    <message>
+        <source>MINIMUM_ANGLE</source>
+        <translation>Minimum angle</translation>
+    </message>
+    <message>
+        <source>MORE_THAN</source>
+        <translation>More than</translation>
+    </message>
+    <message>
+        <source>MULTIEDGES_ERROR</source>
+        <translation>Threshold value of borders at multi-connections can not be equal 1
+Please enter correct value and try again</translation>
+    </message>
+    <message>
+        <source>GROUPCOLOR_ERROR</source>
+        <translation>Color of group can not be undefied
+Please enter correct value and try again</translation>
+    </message>
+    <message>
+        <source>MULTI_BORDERS</source>
+        <translation>Borders at multi-connections</translation>
+    </message>
+    <message>
+        <source>NODES</source>
+        <translation>Nodes</translation>
+    </message>
+    <message>
+        <source>NOT</source>
+        <translation>Not</translation>
+    </message>
+    <message>
+        <source>OR</source>
+        <translation>Or</translation>
+    </message>
+    <message>
+        <source>RANGE_OF_IDS</source>
+        <translation>Range of IDs</translation>
+    </message>
+    <message>
+        <source>REMOVE</source>
+        <translation>Remove</translation>
+    </message>
+    <message>
+        <source>SKEW</source>
+        <translation>Skew</translation>
+    </message>
+    <message>
+        <source>TAPER</source>
+        <translation>Taper</translation>
+    </message>
+    <message>
+        <source>THRESHOLD_VALUE</source>
+        <translation>Threshold value</translation>
+    </message>
+    <message>
+        <source>UNARY</source>
+        <translation>Unary</translation>
+    </message>
+    <message>
+        <source>VOLUMES</source>
+        <translation>Volumes</translation>
+    </message>
+    <message>
+        <source>VOLUME_3D</source>
+        <translation>Volume</translation>
+    </message>
+    <message>
+        <source>WARPING</source>
+        <translation>Warping</translation>
+    </message>
+    <message>
+        <source>LINEAR</source>
+        <translation>Linear</translation>
+    </message>
+    <message>
+        <source>GROUP_COLOR</source>
+        <translation>Color of Group</translation>
+    </message>
+    <message>
+        <source>ELEMENTS</source>
+        <translation>Elements</translation>
+    </message>
+    <message>
+        <source>GEOM_TYPE</source>
+        <translation>Geometry type</translation>
+    </message>
+    <message>
+        <source>GEOM_TYPE_0</source>
+        <translation>Point</translation>
+    </message>
+    <message>
+        <source>GEOM_TYPE_1</source>
+        <translation>Edge</translation>
+    </message>
+    <message>
+        <source>GEOM_TYPE_2</source>
+        <translation>Triangle</translation>
+    </message>
+    <message>
+        <source>GEOM_TYPE_3</source>
+        <translation>Quadrangle</translation>
+    </message>
+    <message>
+        <source>GEOM_TYPE_4</source>
+        <translation>Polygon</translation>
+    </message>
+    <message>
+        <source>GEOM_TYPE_5</source>
+        <translation>Tetrahedron</translation>
+    </message>
+    <message>
+        <source>GEOM_TYPE_6</source>
+        <translation>Pyramid</translation>
+    </message>
+    <message>
+        <source>GEOM_TYPE_7</source>
+        <translation>Hexahedron</translation>
+    </message>
+    <message>
+        <source>GEOM_TYPE_8</source>
+        <translation>Pentahedron</translation>
+    </message>
+    <message>
+        <source>GEOM_TYPE_9</source>
+        <translation>Hexagonal prism</translation>
+    </message>
+    <message>
+        <source>GEOM_TYPE_10</source>
+        <translation>Polyhedra</translation>
+    </message>
+    <message>
+        <source>GEOM_TYPE_11</source>
+        <translation>Ball</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_GroupOpDlg</name>
+    <message>
+        <source>ARGUMENTS</source>
+        <translation>Arguments</translation>
+    </message>
+    <message>
+        <source>DIFF_MESHES</source>
+        <translation>Arguments of operation are not correctly specified
+Groups correspond to a different meshes
+Please specify valid arguments and try again</translation>
+    </message>
+    <message>
+        <source>DIFF_TYPES</source>
+        <translation>Arguments of operation are not correctly specified
+Groups contain elements of different types
+Please specify valid arguments and try again</translation>
+    </message>
+    <message>
+        <source>EMPTY_NAME</source>
+        <translation>Name of group to be created is not valid
+Please specify non-empty name and try again</translation>
+    </message>
+    <message>
+        <source>INCORRECT_ARGUMENTS</source>
+        <translation>Arguments of operation are not specified
+Please specify them and try again</translation>
+    </message>
+    <message>
+        <source>NAME</source>
+        <translation>Name</translation>
+    </message>
+    <message>
+        <source>OBJECT_1</source>
+        <translation>Object 1</translation>
+    </message>
+    <message>
+        <source>OBJECT_2</source>
+        <translation>Object 2</translation>
+    </message>
+    <message>
+        <source>RESULT_NAME</source>
+        <translation>Result name</translation>
+    </message>
+    <message>
+        <source>TOOL_OBJECT</source>
+        <translation>Tool object</translation>
+    </message>
+    <message>
+        <source>UNION_OF_TWO_GROUPS</source>
+        <translation>Union of two groups</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_GroupDlg</name>
+    <message>
+        <source>SELECT_ALL</source>
+        <translation>Select All</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_UnionGroupsDlg</name>
+    <message>
+        <source>UNION_OF_GROUPS</source>
+        <translation>Union of groups</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_DimGroupDlg</name>
+    <message>
+        <source>CREATE_GROUP_OF_UNDERLYING_ELEMS</source>
+        <translation>Create group of underlying entities</translation>
+    </message>
+    <message>
+        <source>ELEMENTS_TYPE</source>
+        <translation>Elements type</translation>
+    </message>
+    <message>
+        <source>NODE</source>
+        <translation>Node</translation>
+    </message>
+    <message>
+        <source>EDGE</source>
+        <translation>Edge</translation>
+    </message>
+    <message>
+        <source>FACE</source>
+        <translation>Face</translation>
+    </message>
+    <message>
+        <source>VOLUME</source>
+        <translation>Volume</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_IntersectGroupsDlg</name>
+    <message>
+        <source>INTERSECTION_OF_GROUPS</source>
+        <translation>Intersection of groups</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_CutGroupsDlg</name>
+    <message>
+        <source>CUT_OF_GROUPS</source>
+        <translation>Cut of groups</translation>
+    </message>
+    <message>
+        <source>MAIN_OBJECT</source>
+        <translation>Main object</translation>
+    </message>
+    <message>
+        <source>TOOL_OBJECT</source>
+        <translation>Tool object</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MakeNodeAtPointDlg</name>
+    <message>
+        <source>AUTO_SEARCH</source>
+        <translation>Find closest to destination</translation>
+    </message>
+    <message>
+        <source>CAPTION</source>
+        <translation>Move node</translation>
+    </message>
+    <message>
+        <source>DESTINATION</source>
+        <translation>Destination</translation>
+    </message>
+    <message>
+        <source>MOVE_NODE</source>
+        <translation>Move node</translation>
+    </message>
+    <message>
+        <source>METHOD</source>
+        <translation>Method</translation>
+    </message>
+    <message>
+        <source>NODE_2MOVE</source>
+        <translation>Node to move</translation>
+    </message>
+    <message>
+        <source>NODE_2MOVE_ID</source>
+        <translation>ID</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MakeNodeAtPointOp</name>
+    <message>
+        <source>INVALID_ID</source>
+        <translation>Node ID is invalid</translation>
+    </message>
+    <message>
+        <source>INVALID_MESH</source>
+        <translation>Mesh to modify not selected</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_FindElemByPointDlg</name>
+    <message>
+        <source>MESH_GROUP</source>
+        <translation>Mesh or group</translation>
+    </message>
+    <message>
+        <source>CAPTION</source>
+        <translation>Find Element by Point</translation>
+    </message>
+    <message>
+        <source>CREATE_NEW_METHOD</source>
+        <translation>Create a node</translation>
+    </message>
+    <message>
+        <source>MESH_PASS_THROUGH_POINT</source>
+        <translation>Make a node at point</translation>
+    </message>
+    <message>
+        <source>METHOD</source>
+        <translation>Method</translation>
+    </message>
+    <message>
+        <source>MOVE_EXISTING_METHOD</source>
+        <translation>Move a node</translation>
+    </message>
+    <message>
+        <source>NODE_2MOVE</source>
+        <translation>Node to move</translation>
+    </message>
+    <message>
+        <source>NODE_2MOVE_ID</source>
+        <translation>ID</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MeshDlg</name>
+    <message>
+        <source>CREATE_MESH</source>
+        <translation>Create mesh</translation>
+    </message>
+    <message>
+        <source>CREATE_SUBMESH</source>
+        <translation>Create sub-mesh</translation>
+    </message>
+    <message>
+        <source>DIM_0D</source>
+        <translation>0D</translation>
+    </message>
+    <message>
+        <source>DIM_1D</source>
+        <translation>1D</translation>
+    </message>
+    <message>
+        <source>DIM_2D</source>
+        <translation>2D</translation>
+    </message>
+    <message>
+        <source>DIM_3D</source>
+        <translation>3D</translation>
+    </message>
+    <message>
+        <source>EDIT_MESH_SUBMESH</source>
+        <translation>Edit mesh/sub-mesh</translation>
+    </message>
+    <message>
+        <source>GEOMETRY</source>
+        <translation>Geometry</translation>
+    </message>
+    <message>
+        <source>HYPOTHESES_SETS</source>
+        <translation>Assign a set of hypotheses</translation>
+    </message>
+    <message>
+        <source>MESH</source>
+        <translation>Mesh</translation>
+    </message>
+    <message>
+        <source>NAME</source>
+        <translation>Name</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MeshOp</name>
+    <message>
+        <source>ALGORITHM_WITHOUT_HYPOTHESIS</source>
+        <translation>Algorithm is defined for %1 dimension but hypothesis is not defined</translation>
+    </message>
+    <message>
+        <source>EDIT_SUBMESH_QUESTION</source>
+        <translation>A submesh on the selected geometry already exists.
+ Do you want to edit this submesh?</translation>
+    </message>
+    <message>
+        <source>SUBMESH_NOT_ALLOWED</source>
+        <translation>No sense in creating a submesh ignored by global algorithm &quot;%1&quot;</translation>
+    </message>
+    <message>
+        <source>GEOMETRY_OBJECT_IS_NOT_DEFINED</source>
+        <translation>Geometry object is not defined
 Please specify it and try again</translation>
-        </message>
-        <message>
-            <source>REF_IS_NULL</source>
-            <translation>No valid mesh object selected</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_CreatePatternDlg</name>
-        <message>
-            <source>CAPTION</source>
-            <translation>Pattern Creation</translation>
-        </message>
-        <message>
-            <source>DEFAULT_2D</source>
-            <translation>Pattern_2d</translation>
-        </message>
-        <message>
-            <source>DEFAULT_3D</source>
-            <translation>Pattern_3d</translation>
-        </message>
-        <message>
-            <source>ERROR_OF_CREATION</source>
-            <translation>Internal error occurs during pattern creation
-Please verify validity of entered information</translation>
-        </message>
-        <message>
-            <source>ERROR_OF_SAVING</source>
-            <translation>Internal error occurs during pattern saving. Please verify
-\free disk space and your write permission to this file</translation>
-        </message>
-        <message>
-            <source>ERR_LOADF_CANT_PROJECT</source>
-            <translation>Impossible to perform projection of nodes to the face</translation>
-        </message>
-        <message>
-            <source>ERR_LOADF_CLOSED_FACE</source>
-            <translation>It is impossible to create pattern from face having seam edge</translation>
-        </message>
-        <message>
-            <source>ERR_LOADF_NARROW_FACE</source>
-            <translation>It is impossible to create pattern from narrow face</translation>
-        </message>
-        <message>
-            <source>ERR_LOADV_BAD_SHAPE</source>
-            <translation>Pattern can be created from closed shell or solid with 6 faces only</translation>
-        </message>
-        <message>
-            <source>ERR_LOADV_COMPUTE_PARAMS</source>
-            <translation>It is impossible to compute point parameters</translation>
-        </message>
-        <message>
-            <source>ERR_LOAD_EMPTY_SUBMESH</source>
-            <translation>There are no elements to create pattern</translation>
-        </message>
-        <message>
-            <source>MESH_OR_SUBMESH</source>
-            <translation>Mesh or SubMesh</translation>
-        </message>
-        <message>
-            <source>PATTERN</source>
-            <translation>Pattern</translation>
-        </message>
-        <message>
-            <source>PATTERN_FILT</source>
-            <translation>Pattern files(*.smp)</translation>
-        </message>
-        <message>
-            <source>PATTERN_NAME</source>
-            <translation>Pattern name</translation>
-        </message>
-        <message>
-            <source>PATTERN_TYPE</source>
-            <translation>Pattern type</translation>
-        </message>
-        <message>
-            <source>PROJECT</source>
-            <translation>Project nodes on the face</translation>
-        </message>
-        <message>
-            <source>SAVE</source>
-            <translation>Save...</translation>
-        </message>
-        <message>
-            <source>SAVE_PATTERN</source>
-            <translation>Save Pattern</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_CreatePolyhedralVolumeDlg</name>
-        <message>
-            <source>FACES_BY_NODES</source>
-            <translation>Faces by nodes</translation>
-        </message>
-        <message>
-            <source>SMESH_POLYEDRE_CREATE_ERROR</source>
-            <translation>Polyhedron creation error.</translation>
-        </message>
-        <message>
-            <source>SMESH_POLYEDRE_PREVIEW</source>
-            <translation>Polyhedron preview</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_CuttingOfQuadsDlg</name>
-        <message>
-            <source>CAPTION</source>
-            <translation>Cutting of quadrangles</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_DeleteGroupDlg</name>
-        <message>
-            <source>CAPTION</source>
-            <translation>Delete groups with contents</translation>
-        </message>
-        <message>
-            <source>NO_SELECTED_GROUPS</source>
-            <translation>There are no selected groups
-Please select a groups and try again</translation>
-        </message>
-        <message>
-            <source>SELECTED_GROUPS</source>
-            <translation>Selected groups</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_EditMeshDlg</name>
-        <message>
-            <source>COINCIDENT_ELEMENTS</source>
-            <translation>Coincident elements</translation>
-        </message>
-        <message>
-            <source>COINCIDENT_NODES</source>
-            <translation>Coincident nodes</translation>
-        </message>
-        <message>
-            <source>DETECT</source>
-            <translation>Detect</translation>
-        </message>
-        <message>
-            <source>EDIT_SELECTED_GROUP</source>
-            <translation>Edit selected group</translation>
-        </message>
-        <message>
-            <source>SELECT_ALL</source>
-            <translation>Select all</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_ExtrusionAlongPathDlg</name>
-        <message>
-            <source>BAD_SHAPE_TYPE</source>
-            <translation>The shape selected for the path is not edge</translation>
-        </message>
-        <message>
-            <source>CANT_GET_TANGENT</source>
-            <translation>Can't get tangent for one of the path nodes</translation>
-        </message>
-        <message>
-            <source>EXTRUSION_1D</source>
-            <translation>Extrusion of 1D elements</translation>
-        </message>
-        <message>
-            <source>EXTRUSION_2D</source>
-            <translation>Extrusion of 2D elements</translation>
-        </message>
-        <message>
-            <source>EXTRUSION_ALONG_PATH</source>
-            <translation>Extrusion along a path</translation>
-        </message>
-        <message>
-            <source>EXTR_BAD_STARTING_NODE</source>
-            <translation>Wrong path starting node</translation>
-        </message>
-        <message>
-            <source>LINEAR_ANGLES</source>
-            <translation>Linear variation of the angles</translation>
-        </message>
-        <message>
-            <source>NO_ELEMENTS_SELECTED</source>
-            <translation>No mesh elements are selected for extrusion</translation>
-        </message>
-        <message>
-            <source>SELECTED_PATH_IS_NOT_EDGE</source>
-            <translation>Path mesh should be of edge type</translation>
-        </message>
-        <message>
-            <source>SMESH_ANGLES</source>
-            <translation>Rotation Angles</translation>
-        </message>
-        <message>
-            <source>SMESH_BASE_POINT</source>
-            <translation>Base Point</translation>
-        </message>
-        <message>
-            <source>SMESH_PATH</source>
-            <translation>Path</translation>
-        </message>
-        <message>
-            <source>SMESH_PATH_MESH</source>
-            <translation>Mesh</translation>
-        </message>
-        <message>
-            <source>SMESH_PATH_SHAPE</source>
-            <translation>Shape (edge)</translation>
-        </message>
-        <message>
-            <source>SMESH_PATH_START</source>
-            <translation>Start node</translation>
-        </message>
-        <message>
-            <source>SMESH_USE_ANGLES</source>
-            <translation>Use Angles</translation>
-        </message>
-        <message>
-            <source>SMESH_USE_BASE_POINT</source>
-            <translation>Use Base Point</translation>
-        </message>
-        <message>
-            <source>WRONG_ANGLES_NUMBER</source>
-            <translation>The number of angles should correspond to the number of path nodes</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_ExtrusionDlg</name>
-        <message>
-            <source>EXTRUSION_1D</source>
-            <translation>Extrusion of 1D elements</translation>
-        </message>
-        <message>
-            <source>EXTRUSION_2D</source>
-            <translation>Extrusion of 2D elements</translation>
-        </message>
-        <message>
-            <source>EXTRUSION_ALONG_LINE</source>
-            <translation>Extrusion along a line</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_FilterDlg</name>
-        <message>
-            <source>BAD_SHAPE_NAME</source>
-            <translation>There is no "%1" geometrical object in the current study
-Please select valid object and try again</translation>
-        </message>
-        <message>
-            <source>CURRENT_DIALOG</source>
-            <translation>Current Dialog</translation>
-        </message>
-        <message>
-            <source>EDGES_TLT</source>
-            <translation>Filter for Edges</translation>
-        </message>
-        <message>
-            <source>FACES_TLT</source>
-            <translation>Filter for Faces</translation>
-        </message>
-        <message>
-            <source>MESH</source>
-            <translation>Mesh</translation>
-        </message>
-        <message>
-            <source>NODES_TLT</source>
-            <translation>Filter for Nodes</translation>
-        </message>
-        <message>
-            <source>SELECTION</source>
-            <translation>Initial Selection</translation>
-        </message>
-        <message>
-            <source>SET_IN_VIEWER</source>
-            <translation>Insert filter in viewer</translation>
-        </message>
-        <message>
-            <source>SHAPE_IS_NOT_A_CYLINDER</source>
-            <translation>"%1" is not a cylinderical face
-Please select a cylindrical face and try again</translation>
-        </message>
-        <message>
-            <source>SHAPE_IS_NOT_A_FACE</source>
-            <translation>"%1" is not a face
-Please select a face and try again</translation>
-        </message>
-        <message>
-            <source>SHAPE_IS_NOT_A_PLANE</source>
-            <translation>"%1" is not a plane
-Please select a plane and try again</translation>
-        </message>
-        <message>
-            <source>SOURCE</source>
-            <translation>Source</translation>
-        </message>
-        <message>
-            <source>TLT</source>
-            <translation>Selection filter</translation>
-        </message>
-        <message>
-            <source>VOLUMES_TLT</source>
-            <translation>Filter for Volumes</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_FilterLibraryDlg</name>
-        <message>
-            <source>ADD</source>
-            <translation>Add</translation>
-        </message>
-        <message>
-            <source>ADD_TO_TLT</source>
-            <translation>Add selection filter to library</translation>
-        </message>
-        <message>
-            <source>ALL_FILES_FILTER</source>
-            <translation>All Files (*.*)</translation>
-        </message>
-        <message>
-            <source>ASSIGN_NEW_NAME</source>
-            <translation>Library already contains filter with name "%1"
-New name "%2" is assigned to added filter</translation>
-        </message>
-        <message>
-            <source>COPY_FROM_TLT</source>
-            <translation>Copy selection filter from library</translation>
-        </message>
-        <message>
-            <source>DELETE</source>
-            <translation>Delete</translation>
-        </message>
-        <message>
-            <source>EDGE</source>
-            <translation>Edge</translation>
-        </message>
-        <message>
-            <source>EDIT_LIB_TLT</source>
-            <translation>Selection filter library</translation>
-        </message>
-        <message>
-            <source>ELEMENT</source>
-            <translation>Element</translation>
-        </message>
-        <message>
-            <source>EMPTY_FILTER_NAME</source>
-            <translation>Name of the filter is empty
-Please enter a non-empty name</translation>
-        </message>
-        <message>
-            <source>ERROR_FILTER_NAME</source>
-            <translation>Name of the filter is not unique
-Please enter other name</translation>
-        </message>
-        <message>
-            <source>ERROR_LOAD</source>
-            <translation>It is impossible to load library
-Please check library file name and attributes</translation>
-        </message>
-        <message>
-            <source>ERROR_OF_ADDING</source>
-            <translation>Internal error occurs during adiing new filter in library.
-Please verify validity of entered information</translation>
-        </message>
-        <message>
-            <source>ERROR_OF_COPYING</source>
-            <translation>Internal error occurs during copying filter from library.
-Please verify validity of entered information</translation>
-        </message>
-        <message>
-            <source>ERROR_OF_DELETING</source>
-            <translation>Internal error occurs during deleting filter from library.
-Please verify validity of entered information</translation>
-        </message>
-        <message>
-            <source>ERROR_OF_EDITING</source>
-            <translation>Internal error occurs during editing filter library.
-Please verify validity of entered information</translation>
-        </message>
-        <message>
-            <source>ERROR_OF_SAVING</source>
-            <translation>Internal error occurs during saving filter library
-Please check input data and try again</translation>
-        </message>
-        <message>
-            <source>FACE</source>
-            <translation>Face</translation>
-        </message>
-        <message>
-            <source>FILTER</source>
-            <translation>Filter</translation>
-        </message>
-        <message>
-            <source>FILTER_NAME</source>
-            <translation>Filter name</translation>
-        </message>
-        <message>
-            <source>FILTER_NAMES</source>
-            <translation>Names of filters</translation>
-        </message>
-        <message>
-            <source>LIBRARY_FILE</source>
-            <translation>Library file name</translation>
-        </message>
-        <message>
-            <source>LIBRARY_IS_NOT_LOADED</source>
-            <translation>Library is not loaded. Please load library and try again</translation>
-        </message>
-        <message>
-            <source>LIB_NAME</source>
-            <translation>FilterLib.xml</translation>
-        </message>
-        <message>
-            <source>NODE</source>
-            <translation>Node</translation>
-        </message>
-        <message>
-            <source>NO_PERMISSION</source>
-            <translation>You do not have write permission to this file</translation>
-        </message>
-        <message>
-            <source>OPEN_LIBRARY</source>
-            <translation>Open library</translation>
-        </message>
-        <message>
-            <source>SELECTION</source>
-            <translation>Selection</translation>
-        </message>
-        <message>
-            <source>VOLUME</source>
-            <translation>Volume</translation>
-        </message>
-        <message>
-            <source>XML_FILT</source>
-            <translation>XML files(*.xml)</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_FilterTable</name>
-        <message>
-            <source>ADD</source>
-            <translation>Add</translation>
-        </message>
-        <message>
-            <source>ADDITIONAL_PARAMETERS</source>
-            <translation>Additional parameters</translation>
-        </message>
-        <message>
-            <source>ADD_TO</source>
-            <translation>Add to...</translation>
-        </message>
-        <message>
-            <source>AND</source>
-            <translation>And</translation>
-        </message>
-        <message>
-            <source>AREA</source>
-            <translation>Area</translation>
-        </message>
-        <message>
-            <source>ASPECT_RATIO</source>
-            <translation>Aspect ratio</translation>
-        </message>
-        <message>
-            <source>ASPECT_RATIO_3D</source>
-            <translation>Aspect ratio 3D</translation>
-        </message>
-        <message>
-            <source>BAD_ORIENTED_VOLUME</source>
-            <translation>Bad oriented volume</translation>
-        </message>
-        <message>
-            <source>BELONG_TO_CYLINDER</source>
-            <translation>Belong to Cylinder</translation>
-        </message>
-        <message>
-            <source>BELONG_TO_GENSURFACE</source>
-            <translation>Belong to Surface</translation>
-        </message>
-        <message>
-            <source>BELONG_TO_GEOM</source>
-            <translation>Belong to Geom</translation>
-        </message>
-        <message>
-            <source>BELONG_TO_PLANE</source>
-            <translation>Belong to Plane</translation>
-        </message>
-        <message>
-            <source>BINARY</source>
-            <translation>Binary</translation>
-        </message>
-        <message>
-            <source>CLEAR</source>
-            <translation>Clear</translation>
-        </message>
-        <message>
-            <source>COMPARE</source>
-            <translation>Compare</translation>
-        </message>
-        <message>
-            <source>COPY_FROM</source>
-            <translation>Copy from...</translation>
-        </message>
-        <message>
-            <source>CRITERION</source>
-            <translation>Criterion</translation>
-        </message>
-        <message>
-            <source>EDGES</source>
-            <translation>Edges</translation>
-        </message>
-        <message>
-            <source>ENTITY_TYPE</source>
-            <translation>Entity type</translation>
-        </message>
-        <message>
-            <source>EQUAL_TO</source>
-            <translation>Equal to</translation>
-        </message>
-        <message>
-            <source>ERROR</source>
-            <translation>Threshold value is not correctly specified
-Please enter correct value and try again</translation>
-        </message>
-        <message>
-            <source>FACES</source>
-            <translation>Faces</translation>
-        </message>
-        <message>
-            <source>FILTER</source>
-            <translation>Filter</translation>
-        </message>
-        <message>
-            <source>FREE_BORDERS</source>
-            <translation>Free borders</translation>
-        </message>
-        <message>
-            <source>FREE_EDGES</source>
-            <translation>Free edges</translation>
-        </message>
-       <message>
-            <source>FREE_NODES</source>
-            <translation>Free nodes</translation>
-        </message>
-       
-
-        <message>
-            <source>FREE_FACES</source>
-            <translation>Free faces</translation>
-        </message>
-        <message>
-            <source>ID</source>
-            <translation>ID</translation>
-        </message>
-        <message>
-            <source>INSERT</source>
-            <translation>Insert</translation>
-        </message>
-        <message>
-            <source>LENGTH</source>
-            <translation>Length</translation>
-        </message>
-        <message>
-            <source>LENGTH2D</source>
-            <translation>Length 2D</translation>
-        </message>
-        <message>
-            <source>LESS_THAN</source>
-            <translation>Less than</translation>
-        </message>
-        <message>
-            <source>LYING_ON_GEOM</source>
-            <translation>Lying on Geom</translation>
-        </message>
-        <message>
-            <source>MINIMUM_ANGLE</source>
-            <translation>Minimum angle</translation>
-        </message>
-        <message>
-            <source>MORE_THAN</source>
-            <translation>More than</translation>
-        </message>
-        <message>
-            <source>MULTIEDGES_ERROR</source>
-            <translation>Threshold value of borders at multi-connections can not be equal 1
-Please enter correct value and try again</translation>
-        </message>
-        <message>
-            <source>GROUPCOLOR_ERROR</source>
-            <translation>Color of group can not be undefied
-Please enter correct value and try again</translation>
-        </message>
-        <message>
-            <source>MULTI_BORDERS</source>
-            <translation>Borders at multi-connections</translation>
-        </message>
-        <message>
-            <source>NODES</source>
-            <translation>Nodes</translation>
-        </message>
-        <message>
-            <source>NOT</source>
-            <translation>Not</translation>
-        </message>
-        <message>
-            <source>OR</source>
-            <translation>Or</translation>
-        </message>
-        <message>
-            <source>RANGE_OF_IDS</source>
-            <translation>Range of IDs</translation>
-        </message>
-        <message>
-            <source>REMOVE</source>
-            <translation>Remove</translation>
-        </message>
-        <message>
-            <source>SKEW</source>
-            <translation>Skew</translation>
-        </message>
-        <message>
-            <source>TAPER</source>
-            <translation>Taper</translation>
-        </message>
-        <message>
-            <source>THRESHOLD_VALUE</source>
-            <translation>Threshold value</translation>
-        </message>
-        <message>
-            <source>UNARY</source>
-            <translation>Unary</translation>
-        </message>
-        <message>
-            <source>VOLUMES</source>
-            <translation>Volumes</translation>
-        </message>
-        <message>
-            <source>VOLUME_3D</source>
-            <translation>Volume</translation>
-        </message>
-        <message>
-            <source>WARPING</source>
-            <translation>Warping</translation>
-        </message>
-        <message>
-            <source>LINEAR</source>
-            <translation>Linear</translation>
-        </message>
-        <message>
-            <source>GROUP_COLOR</source>
-            <translation>Color of Group</translation>
-        </message>
-        <message>
-            <source>ELEMENTS</source>
-            <translation>Elements</translation>
-        </message>
-        <message>
-            <source>GEOM_TYPE</source>
-            <translation>Geometry type</translation>
-        </message>
-        <message>
-            <source>GEOM_TYPE_0</source>
-            <translation></translation>
-        </message>
-        <message>
-            <source>GEOM_TYPE_0</source>
-            <translation>Point</translation>
-        </message>
-        <message>
-            <source>GEOM_TYPE_1</source>
-            <translation>Edge</translation>
-        </message>
-        <message>
-            <source>GEOM_TYPE_2</source>
-            <translation>Triangle</translation>
-        </message>
-        <message>
-            <source>GEOM_TYPE_3</source>
-            <translation>Quadrangle</translation>
-        </message>
-        <message>
-            <source>GEOM_TYPE_4</source>
-            <translation>Polygon</translation>
-        </message>
-        <message>
-            <source>GEOM_TYPE_5</source>
-            <translation>Tetrahedron</translation>
-        </message>
-        <message>
-            <source>GEOM_TYPE_6</source>
-            <translation>Pyramid</translation>
-        </message>
-        <message>
-            <source>GEOM_TYPE_7</source>
-            <translation>Hexahedron</translation>
-        </message>
-        <message>
-            <source>GEOM_TYPE_8</source>
-            <translation>Pentahedron</translation>
-        </message>
-        <message>
-            <source>GEOM_TYPE_9</source>
-            <translation>Polyhedra</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_GroupOpDlg</name>
-        <message>
-            <source>ARGUMENTS</source>
-            <translation>Arguments</translation>
-        </message>
-        <message>
-            <source>DIFF_MESHES</source>
-            <translation>Arguments of operation are not correctly specified
-Groups correspond to a different meshes
-Please specify valid arguments and try again</translation>
-        </message>
-        <message>
-            <source>DIFF_TYPES</source>
-            <translation>Arguments of operation are not correctly specified
-Groups contain elements of different types
-Please specify valid arguments and try again</translation>
-        </message>
-        <message>
-            <source>EMPTY_NAME</source>
-            <translation>Name of group to be created is not valid
-Please specify non-empty name and try again</translation>
-        </message>
-        <message>
-            <source>INCORRECT_ARGUMENTS</source>
-            <translation>Arguments of operation are not specified
-Please specify them and try again</translation>
-        </message>
-        <message>
-            <source>NAME</source>
-            <translation>Name</translation>
-        </message>
-        <message>
-            <source>OBJECT_1</source>
-            <translation>Object 1</translation>
-        </message>
-        <message>
-            <source>OBJECT_2</source>
-            <translation>Object 2</translation>
-        </message>
-        <message>
-            <source>RESULT_NAME</source>
-            <translation>Result name</translation>
-        </message>
-        <message>
-            <source>TOOL_OBJECT</source>
-            <translation>Tool object</translation>
-        </message>
-        <message>
-            <source>UNION_OF_TWO_GROUPS</source>
-            <translation>Union of two groups</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_UnionGroupsDlg</name>
-        <message>
-            <source>UNION_OF_GROUPS</source>
-            <translation>Union of groups</translation>
-        </message>
-    </context>    
-    <context>
-        <name>SMESHGUI_DimGroupDlg</name>
-        <message>
-            <source>CREATE_GROUP_OF_UNDERLYING_ELEMS</source>
-            <translation>Create group of underlying entities</translation>
-        </message>
+    </message>
+    <message>
+        <source>GEOMETRY_OBJECT_IS_NULL</source>
+        <translation>Geometry object is null</translation>
+    </message>
+    <message>
+        <source>HYPOTHESES_AND_ALGORITHMS_ARE_NOT_DEFINED</source>
+        <translation>Hypotheses and algorithms are not defined</translation>
+    </message>
+    <message>
+        <source>HYPOTHESIS_WITHOUT_ALGORITHM</source>
+        <translation>Hypothesis is defined for %1 dimension but algorithm is not defined</translation>
+    </message>
+    <message>
+        <source>IMPORTED_MESH</source>
+        <translation>Mesh is not built on geometry</translation>
+    </message>
+    <message>
+        <source>INVALID_SUBSHAPE</source>
+        <translation>Geometry object is not a sub-shape of the shape to mesh</translation>
+    </message>
+    <message>
+        <source>MESH_IS_NOT_DEFINED</source>
+        <translation>Mesh is not defined
+Please specify it and try again</translation>
+    </message>
+    <message>
+        <source>MESH_IS_NULL</source>
+        <translation>Mesh is null</translation>
+    </message>
+    <message>
+        <source>NAME_OF_MESH_IS_EMPTY</source>
+        <translation>Name of mesh is empty
+Please enter valid name and try again</translation>
+    </message>
+    <message>
+        <source>NAME_OF_SUBMESH_IS_EMPTY</source>
+        <translation>Name of submesh is empty
+Please enter valid name and try again</translation>
+    </message>
+    <message>
+        <source>THERE_IS_NO_OBJECT_FOR_EDITING</source>
+        <translation>There is no object for editing. Please
+select mesh or sub-mesh and try again</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MeshPatternDlg</name>
+    <message>
+        <source>3D_BLOCK</source>
+        <translation>3D block</translation>
+    </message>
+    <message>
+        <source>CAPTION</source>
+        <translation>Pattern Mapping</translation>
+    </message>
+    <message>
+        <source>CREATE_POLYEDRS_NEAR_BOUNDARY</source>
+        <translation>Create polyhedrons near boundary</translation>
+    </message>
+    <message>
+        <source>CREATE_POLYGONS_NEAR_BOUNDARY</source>
+        <translation>Create polygons near boundary</translation>
+    </message>
+    <message>
+        <source>ERROR_OF_LOADING</source>
+        <translation>Loading of pattern from file failed. Probably file
+is corrupted or contains pattern of the other type</translation>
+    </message>
+    <message>
+        <source>ERROR_OF_OPENING</source>
+        <translation>It is impossible to open file. Please verify whether
+file exists and your permission to this file</translation>
+    </message>
+    <message>
+        <source>ERROR_OF_READING</source>
+        <translation>It is impossible to load pattern
+Please verify file&apos;s contents</translation>
+    </message>
+    <message>
+        <source>ERR_READ_3D_COORD</source>
+        <translation>It is impossible to load pattern
+Coordinates of 3D points out of [0,1] range</translation>
+    </message>
+    <message>
+        <source>ERR_READ_BAD_INDEX</source>
+        <translation>It is impossible to load pattern
+Invalid index of point detected</translation>
+    </message>
+    <message>
+        <source>ERR_READ_BAD_KEY_POINT</source>
+        <translation>It is impossible to load pattern
+Key-point not on a boundary</translation>
+    </message>
+    <message>
+        <source>ERR_READ_ELEM_POINTS</source>
+        <translation>It is impossible to load pattern
+invalid number of points in element</translation>
+    </message>
+    <message>
+        <source>ERR_READ_NB_POINTS</source>
+        <translation>It is impossible to load pattern
+It is impossible to read number of points from file</translation>
+    </message>
+    <message>
+        <source>ERR_READ_NO_ELEMS</source>
+        <translation>It is impossible to load pattern
+There are no elements in it</translation>
+    </message>
+    <message>
+        <source>ERR_READ_NO_KEYPOINT</source>
+        <translation>It is impossible to load pattern
+There are no key-points in 2D one</translation>
+    </message>
+    <message>
+        <source>ERR_READ_POINT_COORDS</source>
+        <translation>It is impossible to load pattern
+It is impossible to read point coordinates from file</translation>
+    </message>
+    <message>
+        <source>ERR_READ_TOO_FEW_POINTS</source>
+        <translation>It is impossible to load pattern. There are
+ too few points in the file for pattern loading</translation>
+    </message>
+    <message>
+        <source>FACE</source>
+        <translation>Face</translation>
+    </message>
+    <message>
+        <source>LOAD_PATTERN</source>
+        <translation>Load pattern</translation>
+    </message>
+    <message>
+        <source>MESH_FACES</source>
+        <translation>Mesh faces</translation>
+    </message>
+    <message>
+        <source>MESH_VOLUMES</source>
+        <translation>Mesh volumes</translation>
+    </message>
+    <message>
+        <source>NEW</source>
+        <translation>New...</translation>
+    </message>
+    <message>
+        <source>NODE_1</source>
+        <translation>Node 1</translation>
+    </message>
+    <message>
+        <source>NODE_2</source>
+        <translation>Node 2</translation>
+    </message>
+    <message>
+        <source>PATTERN</source>
+        <translation>Pattern</translation>
+    </message>
+    <message>
+        <source>PATTERN_FILT</source>
+        <translation>Pattern files(*.smp)</translation>
+    </message>
+    <message>
+        <source>PATTERN_TYPE</source>
+        <translation>Pattern type</translation>
+    </message>
+    <message>
+        <source>PREVIEW</source>
+        <translation>Preview</translation>
+    </message>
+    <message>
+        <source>REFINE</source>
+        <translation>Refine selected mesh elements</translation>
+    </message>
+    <message>
+        <source>REVERSE</source>
+        <translation>Reverse order of key-points</translation>
+    </message>
+    <message>
+        <source>VERTEX</source>
+        <translation>Vertex   </translation>
+    </message>
+    <message>
+        <source>VERTEX1</source>
+        <translation>Vertex 1</translation>
+    </message>
+    <message>
+        <source>VERTEX2</source>
+        <translation>Vertex 2</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MeshTab</name>
+    <message>
+        <source>ADD_HYPOTHESIS</source>
+        <translation>Add. Hypothesis</translation>
+    </message>
+    <message>
+        <source>ALGORITHM</source>
+        <translation>Algorithm</translation>
+    </message>
+    <message>
+        <source>HYPOTHESIS</source>
+        <translation>Hypothesis</translation>
+    </message>
+    <message>
+        <source>NONE</source>
+        <translation>&lt;None&gt;</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MultiEditDlg</name>
+    <message>
+        <source>ADD</source>
+        <translation>Add</translation>
+    </message>
+    <message>
+        <source>FILTER</source>
+        <translation>Filter</translation>
+    </message>
+    <message>
+        <source>REMOVE</source>
+        <translation>Remove</translation>
+    </message>
+    <message>
+        <source>SELECT_FROM</source>
+        <translation>Select from</translation>
+    </message>
+    <message>
+        <source>SORT_LIST</source>
+        <translation>Sort list</translation>
+    </message>
+    <message>
+        <source>SPLIT_JOIN_CRITERION</source>
+        <translation>Criterion</translation>
+    </message>
+    <message>
+        <source>TO_ALL</source>
+        <translation>Apply to all</translation>
+    </message>
+    <message>
+        <source>USE_DIAGONAL_1_3</source>
+        <translation>Use diagonal 1-3</translation>
+    </message>
+    <message>
+        <source>USE_DIAGONAL_2_4</source>
+        <translation>Use diagonal 2-4</translation>
+    </message>
+    <message>
+        <source>USE_NUMERIC_FUNC</source>
+        <translation>Use numeric functor</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_CuttingIntoTetraDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Splitting volumes into tetrahedra</translation>
+    </message>
+    <message>
+        <source>SPLIT_METHOD</source>
+        <translation>Split hexahedron</translation>
+    </message>
+    <message>
+        <source>SPLIT_HEX_TO_5_TETRA</source>
+        <translation>Into 5 tetrahedra</translation>
+    </message>
+    <message>
+        <source>SPLIT_HEX_TO_6_TETRA</source>
+        <translation>Into 6 tetrahedra</translation>
+    </message>
+    <message>
+        <source>SPLIT_HEX_TO_24_TETRA</source>
+        <translation>Into 24 tetrahedra</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_PrecisionDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Precision for mesh quality controls</translation>
+    </message>
+    <message>
+        <source>NOT_USE</source>
+        <translation>Do not use</translation>
+    </message>
+    <message>
+        <source>PRECISION</source>
+        <translation>Number of digits after point</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_RevolutionDlg</name>
+    <message>
+        <source>ANGLE_BY_STEP</source>
+        <translation>Angle by Step</translation>
+    </message>
+    <message>
+        <source>PREVIEW</source>
+        <translation>Preview</translation>
+    </message>
+    <message>
+        <source>REVOLUTION_1D</source>
+        <translation>Revolution of 1D elements</translation>
+    </message>
+    <message>
+        <source>REVOLUTION_2D</source>
+        <translation>Revolution of 2D elements</translation>
+    </message>
+    <message>
+        <source>REVOLUTION_AROUND_AXIS</source>
+        <translation>Revolution around an axis</translation>
+    </message>
+    <message>
+        <source>TOTAL_ANGLE</source>
+        <translation>Total Angle</translation>
+    </message>
+    <message>
+        <source>MEN_POINT_SELECT</source>
+        <translation>From Origin to selected Point</translation>
+    </message>
+    <message>
+        <source>MEN_FACE_SELECT</source>
+        <translation>Normal to selected Face</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_SewingDlg</name>
+    <message>
+        <source>BORDER</source>
+        <translation>Border</translation>
+    </message>
+    <message>
+        <source>BORDER_1</source>
+        <translation>Border 1</translation>
+    </message>
+    <message>
+        <source>BORDER_2</source>
+        <translation>Border 2</translation>
+    </message>
+    <message>
+        <source>CREATE_POLYEDRS_NEAR_BOUNDARY</source>
+        <translation>Replace affected volumes by polyedres</translation>
+    </message>
+    <message>
+        <source>CREATE_POLYGONS_INSTEAD_SPLITTING</source>
+        <translation>Create polygons instead of splitting</translation>
+    </message>
+    <message>
+        <source>ERROR_1</source>
+        <translation>Free Border1 not found by the selected nodes</translation>
+    </message>
+    <message>
+        <source>ERROR_2</source>
+        <translation>Free Border2 not found by the selected nodes</translation>
+    </message>
+    <message>
+        <source>ERROR_3</source>
+        <translation>Free Border1 and Border2 not found by the selected nodes</translation>
+    </message>
+    <message>
+        <source>ERROR_4</source>
+        <translation>No path from the first side node to the last side node have been found</translation>
+    </message>
+    <message>
+        <source>ERROR_5</source>
+        <translation>Not allowed to splite volumes on the side!</translation>
+    </message>
+    <message>
+        <source>ERROR_6</source>
+        <translation>Different number of elements selected on the sides</translation>
+    </message>
+    <message>
+        <source>ERROR_7</source>
+        <translation>Element sets are topologically different or given nodes are inconvenient</translation>
+    </message>
+    <message>
+        <source>ERROR_8</source>
+        <translation>Nodes on the side 1 are either not linked or not laying on the element set boundary</translation>
+    </message>
+    <message>
+        <source>ERROR_9</source>
+        <translation>Nodes on the side 2 are either not linked or not laying on the element set boundary</translation>
+    </message>
+    <message>
+        <source>FIRST_NODE_ID</source>
+        <translation>First Node ID</translation>
+    </message>
+    <message>
+        <source>LAST_NODE_ID</source>
+        <translation>Last Node ID</translation>
+    </message>
+    <message>
+        <source>MERGE_EQUAL_ELEMENTS</source>
+        <translation>Merge equal elements</translation>
+    </message>
+    <message>
+        <source>NODE1_TO_MERGE</source>
+        <translation>Node 1 To Merge</translation>
+    </message>
+    <message>
+        <source>NODE2_TO_MERGE</source>
+        <translation>Node 2 To Merge</translation>
+    </message>
+    <message>
+        <source>SECOND_NODE_ID</source>
+        <translation>Second Node ID</translation>
+    </message>
+    <message>
+        <source>SEW_BORDER_TO_SIDE</source>
+        <translation>Sew Border To Side</translation>
+    </message>
+    <message>
+        <source>SEW_CONFORM_FREE_BORDERS</source>
+        <translation>Sew Conform Free Borders</translation>
+    </message>
+    <message>
+        <source>SEW_FREE_BORDERS</source>
+        <translation>Sew Free Borders</translation>
+    </message>
+    <message>
+        <source>SEW_SIDE_ELEMENTS</source>
+        <translation>Sew Side Elements</translation>
+    </message>
+    <message>
+        <source>SIDE</source>
+        <translation>Side</translation>
+    </message>
+    <message>
+        <source>SIDE_1</source>
+        <translation>Side 1</translation>
+    </message>
+    <message>
+        <source>SIDE_2</source>
+        <translation>Side 2</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_ShapeByMeshDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Find geometry by mesh element</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_SingleEditDlg</name>
+    <message>
+        <source>EDGE_BETWEEN</source>
+        <translation>Edge between neighboring triangles</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_SmoothingDlg</name>
+    <message>
+        <source>CENTROIDAL</source>
+        <translation>Centroidal</translation>
+    </message>
+    <message>
+        <source>FIXED_NODES_IDS</source>
+        <translation>Fixed nodes ids</translation>
+    </message>
+    <message>
+        <source>IS_PARAMETRIC</source>
+        <translation>in parametric space</translation>
+    </message>
+    <message>
+        <source>ITERATION_LIMIT</source>
+        <translation>Iteration limit</translation>
+    </message>
+    <message>
+        <source>LAPLACIAN</source>
+        <translation>Laplacian</translation>
+    </message>
+    <message>
+        <source>MAX_ASPECT_RATIO</source>
+        <translation>Max. aspect ratio</translation>
+    </message>
+    <message>
+        <source>METHOD</source>
+        <translation>Method</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_TrianglesInversionDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Diagonal inversion</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_UnionOfTrianglesDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Union of triangles</translation>
+    </message>
+    <message>
+        <source>MAXIMUM_ANGLE</source>
+        <translation>Maximum bending angle</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_UnionOfTwoTrianglesDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Union of two triangles</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_FileInfoDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>File information</translation>
+    </message>
+    <message>
+        <source>FILE_NAME</source>
+        <translation>File name</translation>
+    </message>
+    <message>
+        <source>FILE_SIZE</source>
+        <translation>File size (bytes)</translation>
+    </message>
+    <message>
+        <source>MED_VERSION</source>
+        <translation>MED version</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_GroupOnShapeDlg</name>
+    <message>
+        <source>SMESH_CREATE_GROUP_FROM_GEOM</source>
+        <translation>Create Groups from Geometry</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MeshOrderDlg</name>
+    <message>
+        <source>SMESH_MESHORDER_TITLE</source>
+        <translation>Order of submesh in meshing process</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MeshOrderOp</name>
+    <message>
+        <source>SMESH_NO_CONCURENT_MESH</source>
+        <translation>No concurent submeshes detected</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_ClippingDlg</name>
+    <message>
+        <source>CLIP_PLANES</source>
+        <translation>Clipping planes</translation>
+    </message>
+    <message>
+        <source>MESHES_SUBMESHES_GROUPS</source>
+        <translation>Meshes, sub-meshes and groups</translation>
+    </message>
+    <message>
+        <source>SELECT_ALL</source>
+        <translation>Select all</translation>
+    </message>
+    <message>
+        <source>ROTATION_AROUND_X_Y2Z</source>
+        <translation>Rotation around X (Y to Z):</translation>
+    </message>
+    <message>
+        <source>ROTATION_AROUND_Y_X2Z</source>
+        <translation>Rotation around Y (X to Z):</translation>
+    </message>
+    <message>
+        <source>ROTATION_AROUND_Z_Y2X</source>
+        <translation>Rotation around Z (Y to X):</translation>
+    </message>
+    <message>
+        <source>ROTATION_AROUND_X_Z2Y</source>
+        <translation>Rotation around X (Z to Y):</translation>
+    </message>
+    <message>
+        <source>ROTATION_AROUND_Y_Z2X</source>
+        <translation>Rotation around Y (Z to X):</translation>
+    </message>
+    <message>
+        <source>ROTATION_AROUND_Z_X2Y</source>
+        <translation>Rotation around Z (X to Y):</translation>
+    </message>
+    <message>
+        <source>SHOW_PREVIEW</source>
+        <translation>Show preview</translation>
+    </message>
+    <message>
+        <source>AUTO_APPLY</source>
+        <translation>Auto Apply</translation>
+    </message>
+    <message>
+        <source>ALONG_XY</source>
+        <translation>|| X-Y</translation>
+    </message>
+    <message>
+        <source>ALONG_YZ</source>
+        <translation>|| Y-Z</translation>
+    </message>
+    <message>
+        <source>ALONG_ZX</source>
+        <translation>|| Z-X</translation>
+    </message>
+    <message>
+        <source>PLANE_NUM</source>
+        <translation>Plane# %1</translation>
+    </message>
+    <message>
+        <source>NO_PLANES</source>
+        <translation>No planes</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_DuplicateNodesDlg</name>
+    <message>
+        <source>DUPLICATION_MODE</source>
+        <translation>Duplication mode</translation>
+    </message>
+    <message>
+        <source>DUPLICATION_WITHOUT_ELEMS</source>
+        <translation>Without duplication of border elements</translation>
+    </message>
+    <message>
+        <source>GROUP_NODES_TO_DUPLICATE</source>
+        <translation>Group of nodes to duplicate</translation>
+    </message>
+    <message>
+        <source>GROUP_NODES_TO_REPLACE</source>
+        <translation>Group of elements to replace nodes with new ones</translation>
+    </message>
+    <message>
+        <source>DUPLICATION_WITH_ELEMS</source>
+        <translation>With duplication of border elements</translation>
+    </message>
+    <message>
+        <source>GROUP_ELEMS_TO_DUPLICATE</source>
+        <translation>Group of elements to duplicate</translation>
+    </message>
+    <message>
+        <source>GROUP_NODES_NOT_DUPLICATE</source>
+        <translation>Group of nodes not to duplicate</translation>
+    </message>
+    <message>
+        <source>GROUP_ELEMS_TO_REPLACE</source>
+        <translation>Group of elements to replace nodes with new ones</translation>
+    </message>
+    <message>
+        <source>CONSTRUCT_NEW_GROUP_NODES</source>
+        <translation>Construct group with newly created nodes</translation>
+    </message>
+    <message>
+        <source>CONSTRUCT_NEW_GROUP_ELEMENTS</source>
+        <translation>Construct group with newly created elements</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_Make2DFrom3DDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Create boundary elements</translation>
+    </message>
+    <message>
+        <source>Groups</source>
+        <translation>Mesh or groups</translation>
+    </message>
+    <message>
+        <source>MODE</source>
+        <translation>Mode</translation>
+    </message>
+    <message>
+        <source>2D_FROM_3D</source>
+        <translation>2D from 3D</translation>
+    </message>
+    <message>
+        <source>1D_FROM_3D</source>
+        <translation>1D from 2D groups</translation>
+    </message>
+    <message>
+        <source>1D_FROM_2D</source>
+        <translation>1D from 2D</translation>
+    </message>
+    <message>
+        <source>TARGET</source>
+        <translation>Target</translation>
+    </message>
+    <message>
+        <source>THIS_MESH</source>
+        <translation>This mesh</translation>
+    </message>
+    <message>
+        <source>NEW_MESH</source>
+        <translation>New mesh</translation>
+    </message>
+    <message>
+        <source>COPY_SRC</source>
+        <translation>Copy source mesh</translation>
+    </message>
+    <message>
+        <source>MISSING_ONLY</source>
+        <translation>Copy missing elements only</translation>
+    </message>
+    <message>
+        <source>CREATE_GROUP</source>
+        <translation>Create group</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_Make2DFrom3DOp</name>
+    <message>
+        <source>NB_ADDED</source>
+        <translation>%1 boundary elements have been added</translation>
+    </message>
+    <message>
+        <source>WRONG_GROUPS</source>
+        <translation>The following groups have not been processed
+as they are of improper type:
+%1</translation>
+    </message>
+    <message>
+        <source>SMESH_ERR_NO_INPUT_MESH</source>
+        <translation>Source mesh is not specified</translation>
+    </message>
+    <message>
+        <source>SMESH_TOO_MANY_MESHES</source>
+        <translation>Only one mesh can be processed at once</translation>
+    </message>
+    <message>
+        <source>SMESH_NOT_ONLY_GROUPS</source>
+        <translation>Can't process meshes and groups at once</translation>
+    </message>
+    <message>
+        <source>SMESH_ERR_NO_3D_ELEMENTS</source>
+        <translation>The source objects do not contain 3D elements</translation>
+    </message>
+    <message>
+        <source>SMESH_ERR_NO_2D_ELEMENTS</source>
+        <translation>The source objects do not contain 2D elements</translation>
+    </message>
+    <message>
+        <source>SMESH_ERR_MESH_NAME_NOT_SPECIFIED</source>
+        <translation>New mesh name is not specified</translation>
+    </message>
+    <message>
+        <source>SMESH_ERR_GRP_NAME_NOT_SPECIFIED</source>
+        <translation>Group name is not specified</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MeshInfo</name>
+    <message>
+        <source>NAME_LAB</source>
+        <translation>Name:</translation>
+    </message>
+    <message>
+        <source>OBJECT_LAB</source>
+        <translation>Object:</translation>
+    </message>
+    <message>
+        <source>NODES_LAB</source>
+        <translation>Nodes:</translation>
+    </message>
+    <message>
+        <source>ELEMENTS_LAB</source>
+        <translation>Elements:</translation>
+    </message>
+    <message>
+        <source>TOTAL_LAB</source>
+        <translation>Total</translation>
+    </message>
+    <message>
+        <source>LINEAR_LAB</source>
+        <translation>Linear</translation>
+    </message>
+    <message>
+        <source>QUADRATIC_LAB</source>
+        <translation>Quadratic</translation>
+    </message>
+    <message>
+        <source>0D_LAB</source>
+        <translation>0D:</translation>
+    </message>
+    <message>
+        <source>BALL_LAB</source>
+        <translation>Balls:</translation>
+    </message>
+    <message>
+        <source>1D_LAB</source>
+        <translation>1D (edges):</translation>
+    </message>
+    <message>
+        <source>2D_LAB</source>
+        <translation>2D (faces):</translation>
+    </message>
+    <message>
+        <source>TRIANGLES_LAB</source>
+        <translation>Triangles:</translation>
+    </message>
+    <message>
+        <source>QUADRANGLES_LAB</source>
+        <translation>Quadrangles:</translation>
+    </message>
+    <message>
+        <source>POLYGONS_LAB</source>
+        <translation>Polygons:</translation>
+    </message>
+    <message>
+        <source>3D_LAB</source>
+        <translation>3D (volumes):</translation>
+    </message>
+    <message>
+        <source>TETRAHEDRONS_LAB</source>
+        <translation>Tetrahedrons:</translation>
+    </message>
+    <message>
+        <source>HEXAHEDONRS_LAB</source>
+        <translation>Hexahedrons:</translation>
+    </message>
+    <message>
+        <source>PYRAMIDS_LAB</source>
+        <translation>Pyramids:</translation>
+    </message>
+    <message>
+        <source>PRISMS_LAB</source>
+        <translation>Prisms:</translation>
+    </message>
+    <message>
+        <source>HEX_PRISMS_LAB</source>
+        <translation>Hexagonal Prisms:</translation>
+    </message>
+    <message>
+        <source>POLYHEDRONS_LAB</source>
+        <translation>Polyhedrons:</translation>
+    </message>
+    <message>
+        <source>OBJECT_MESH</source>
+        <translation>Mesh</translation>
+    </message>
+    <message>
+        <source>OBJECT_SUBMESH</source>
+        <translation>Sub-mesh</translation>
+    </message>
+    <message>
+        <source>OBJECT_GROUP</source>
+        <translation>Group</translation>
+    </message>
+    <message>
+        <source>OBJECT_GROUP_NODES</source>
+        <translation>Group of nodes</translation>
+    </message>
+    <message>
+        <source>OBJECT_GROUP_EDGES</source>
+        <translation>Group of edges</translation>
+    </message>
+    <message>
+        <source>OBJECT_GROUP_FACES</source>
+        <translation>Group of faces</translation>
+    </message>
+    <message>
+        <source>OBJECT_GROUP_VOLUMES</source>
+        <translation>Group of volumes</translation>
+    </message>
+    <message>
+        <source>OBJECT_GROUP_0DELEMS</source>
+        <translation>Group of 0D elements</translation>
+    </message>
+    <message>
+        <source>OBJECT_GROUP_BALLS</source>
+        <translation>Group of balls</translation>
+    </message>
+    <message>
+        <source>BUT_LOAD_MESH</source>
+        <translation>Load mesh from server</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MeshInfoDlg</name>
+    <message>
+        <source>MESH_INFO</source>
+        <translation>Mesh Information</translation>
+    </message>
+    <message>
+        <source>BASE_INFO</source>
+        <translation>Base Info</translation>
+    </message>
+    <message>
+        <source>ELEM_INFO</source>
+        <translation>Element Info</translation>
+    </message>
+    <message>
+        <source>ADDITIONAL_INFO</source>
+        <translation>Additional Info</translation>
+    </message>
+    <message>
+        <source>NODE_MODE</source>
+        <translation>Node</translation>
+    </message>
+    <message>
+        <source>ELEM_MODE</source>
+        <translation>Element</translation>
+    </message>
+    <message>
+        <source>X_FROM_Y_ITEMS_SHOWN</source>
+        <translation>%1-%2 from %3 items shown</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_ElemInfo</name>
+    <message>
+        <source>COORDINATES</source>
+        <translation>COORDINATES</translation>
+    </message>
+    <message>
+        <source>CONNECTIVITY</source>
+        <translation>CONNECTIVITY</translation>
+    </message>
+    <message>
+        <source>GRAVITY_CENTER</source>
+        <translation>GRAVITY CENTER</translation>
+    </message>
+    <message>
+        <source>NODE</source>
+        <translation>NODE</translation>
+    </message>
+    <message>
+        <source>0D_ELEMENT</source>
+        <translation>0D ELEMENT</translation>
+    </message>
+    <message>
+        <source>0D_ELEMENTS</source>
+        <translation>0D ELEMENTS</translation>
+    </message>
+    <message>
+        <source>BALL_ELEMENT</source>
+        <translation>BALL ELEMENT</translation>
+    </message>
+    <message>
+        <source>BALL_ELEMENTS</source>
+        <translation>BALL ELEMENTS</translation>
+    </message>
+    <message>
+        <source>EDGE</source>
+        <translation>EDGE</translation>
+    </message>
+    <message>
+        <source>EDGES</source>
+        <translation>EDGES</translation>
+    </message>
+    <message>
+        <source>FACE</source>
+        <translation>FACE</translation>
+    </message>
     <message>
-        <source>ELEMENTS_TYPE</source>
-        <translation>Elements type</translation>
-    </message>  
+        <source>FACES</source>
+        <translation>FACES</translation>
+    </message>
+    <message>
+        <source>VOLUME</source>
+        <translation>VOLUME</translation>
+    </message>
+    <message>
+        <source>VOLUMES</source>
+        <translation>VOLUMES</translation>
+    </message>
+    <message>
+        <source>FREE_NODE</source>
+        <translation>Free node (no connectivity)</translation>
+    </message>
+    <message>
+        <source>TYPE</source>
+        <translation>TYPE</translation>
+    </message>
+    <message>
+        <source>TRIANGLE</source>
+        <translation>Triangle</translation>
+    </message>
+    <message>
+        <source>QUADRANGLE</source>
+        <translation>Quadrangle</translation>
+    </message>
+    <message>
+        <source>POLYGON</source>
+        <translation>Polygon</translation>
+    </message>
+    <message>
+        <source>TETRAHEDRON</source>
+        <translation>Tetrahedron</translation>
+    </message>
+    <message>
+        <source>HEXAHEDRON</source>
+        <translation>Hexahedron</translation>
+    </message>
+    <message>
+        <source>PYRAMID</source>
+        <translation>Pyramid</translation>
+    </message>
+    <message>
+        <source>PRISM</source>
+        <translation>Prism</translation>
+    </message>
+    <message>
+        <source>HEX_PRISM</source>
+        <translation>Hexagonal Prism</translation>
+    </message>
+    <message>
+        <source>POLYHEDRON</source>
+        <translation>Polyhedron</translation>
+    </message>
+    <message>
+        <source>QUADRATIC</source>
+        <translation>QUADRATIC</translation>
+    </message>
+    <message>
+        <source>YES</source>
+        <translation>Yes</translation>
+    </message>
+    <message>
+        <source>NO</source>
+        <translation>No</translation>
+    </message>
+    <message>
+        <source>PROPERTY</source>
+        <translation>Property</translation>
+    </message>
+    <message>
+        <source>VALUE</source>
+        <translation>Value</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_AddInfo</name>
+    <message>
+        <source>NAME</source>
+        <translation>Name</translation>
+    </message>
+    <message>
+        <source>GROUPS</source>
+        <translation>Groups</translation>
+    </message>
+    <message>
+        <source>GROUPS_1</source>
+        <translation>Nodes</translation>
+    </message>
+    <message>
+        <source>GROUPS_2</source>
+        <translation>Edges</translation>
+    </message>
+    <message>
+        <source>GROUPS_3</source>
+        <translation>Faces</translation>
+    </message>
+    <message>
+        <source>GROUPS_4</source>
+        <translation>Volumes</translation>
+    </message>
+    <message>
+        <source>GROUPS_5</source>
+        <translation>0D elements</translation>
+    </message>
+    <message>
+        <source>GROUPS_6</source>
+        <translation>Ball elements</translation>
+    </message>
+    <message>
+        <source>PARENT_MESH</source>
+        <translation>Parent mesh</translation>
+    </message>
+    <message>
+        <source>TYPE</source>
+        <translation>Type</translation>
+    </message>
+    <message>
+        <source>STANDALONE_GROUP</source>
+        <translation>Standalone group</translation>
+    </message>
+    <message>
+        <source>GROUP_ON_GEOMETRY</source>
+        <translation>Group on geometry</translation>
+    </message>
+    <message>
+        <source>GROUP_ON_FILTER</source>
+        <translation>Group on filter</translation>
+    </message>
+    <message>
+        <source>GEOM_OBJECT</source>
+        <translation>Shape</translation>
+    </message>
     <message>
         <source>NODE</source>
         <translation>Node</translation>
-    </message>  
+    </message>
     <message>
         <source>EDGE</source>
         <translation>Edge</translation>
@@ -4052,662 +6599,360 @@ Please specify them and try again</translation>
         <source>VOLUME</source>
         <translation>Volume</translation>
     </message>
-    </context>
-    <context>
-        <name>SMESHGUI_IntersectGroupsDlg</name>
-        <message>
-            <source>INTERSECTION_OF_GROUPS</source>
-            <translation>Intersection of groups</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_CutGroupsDlg</name>
-        <message>
-            <source>CUT_OF_GROUPS</source>
-            <translation>Cut of groups</translation>
-        </message>
-        <message>
-            <source>MAIN_OBJECT</source>
-            <translation>Main object</translation>
-        </message>
-        <message>
-            <source>TOOL_OBJECT</source>
-            <translation>Tool object</translation>
-        </message>
-    </context>          
-    <context>
-        <name>SMESHGUI_MakeNodeAtPointDlg</name>
-        <message>
-            <source>AUTO_SEARCH</source>
-            <translation>Automatic search</translation>
-        </message>
-        <message>
-            <source>CAPTION</source>
-            <translation>Mesh to pass through a point</translation>
-        </message>
-        <message>
-            <source>CREATE_NEW_METHOD</source>
-            <translation>Create a node</translation>
-        </message>
-        <message>
-            <source>MESH_PASS_THROUGH_POINT</source>
-            <translation>Make a node at point</translation>
-        </message>
-        <message>
-            <source>METHOD</source>
-            <translation>Method</translation>
-        </message>
-        <message>
-            <source>MOVE_EXISTING_METHOD</source>
-            <translation>Move a node</translation>
-        </message>
-        <message>
-            <source>NODE_2MOVE</source>
-            <translation>Node to move</translation>
-        </message>
-        <message>
-            <source>NODE_2MOVE_ID</source>
-            <translation>ID</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_MakeNodeAtPointOp</name>
-        <message>
-            <source>INVALID_ID</source>
-            <translation>Node ID is invalid</translation>
-        </message>
-        <message>
-            <source>INVALID_MESH</source>
-            <translation>Mesh to modify not selected</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_MeshDlg</name>
-        <message>
-            <source>CREATE_MESH</source>
-            <translation>Create mesh</translation>
-        </message>
-        <message>
-            <source>CREATE_SUBMESH</source>
-            <translation>Create sub-mesh</translation>
-        </message>
-        <message>
-            <source>DIM_0D</source>
-            <translation>0D</translation>
-        </message>
-        <message>
-            <source>DIM_1D</source>
-            <translation>1D</translation>
-        </message>
-        <message>
-            <source>DIM_2D</source>
-            <translation>2D</translation>
-        </message>
-        <message>
-            <source>DIM_3D</source>
-            <translation>3D</translation>
-        </message>
-        <message>
-            <source>EDIT_MESH_SUBMESH</source>
-            <translation>Edit mesh/sub-mesh</translation>
-        </message>
-        <message>
-            <source>GEOMETRY</source>
-            <translation>Geometry</translation>
-        </message>
-        <message>
-            <source>HYPOTHESES_SETS</source>
-            <translation>Assign a set of hypotheses</translation>
-        </message>
-        <message>
-            <source>MESH</source>
-            <translation>Mesh</translation>
-        </message>
-        <message>
-            <source>NAME</source>
-            <translation>Name</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_MeshOp</name>
-        <message>
-            <source>ALGORITHM_WITHOUT_HYPOTHESIS</source>
-            <translation>Algorithm is defined for %1 dimension but hypothesis is not defined</translation>
-        </message>
-        <message>
-            <source>EDIT_SUBMESH_QUESTION</source>
-            <translation>A submesh on the selected geometry already exists.
- Do you want to edit this submesh?</translation>
-        </message>
-        <message>
-            <source>SUBMESH_NOT_ALLOWED</source>
-            <translation>No sense in creating a submesh ignored by global algorithm "%1"</translation>
-        </message>
-        <message>
-            <source>GEOMETRY_OBJECT_IS_NOT_DEFINED</source>
-            <translation>Geometry object is not defined
-Please specify it and try again</translation>
-        </message>
-        <message>
-            <source>GEOMETRY_OBJECT_IS_NULL</source>
-            <translation>Geometry object is null</translation>
-        </message>
-        <message>
-            <source>HYPOTHESES_AND_ALGORITHMS_ARE_NOT_DEFINED</source>
-            <translation>Hypotheses and algorithms are not defined</translation>
-        </message>
-        <message>
-            <source>HYPOTHESIS_WITHOUT_ALGORITHM</source>
-            <translation>Hypothesis is defined for %1 dimension but algorithm is not defined</translation>
-        </message>
-        <message>
-            <source>IMPORTED_MESH</source>
-            <translation>Mesh is not built on geometry</translation>
-        </message>
-        <message>
-            <source>INVALID_SUBSHAPE</source>
-            <translation>Geometry object is not a subshape of the shape to mesh</translation>
-        </message>
-        <message>
-            <source>MESH_IS_NOT_DEFINED</source>
-            <translation>Mesh is not defined
-Please specify it and try again</translation>
-        </message>
-        <message>
-            <source>MESH_IS_NULL</source>
-            <translation>Mesh is null</translation>
-        </message>
-        <message>
-            <source>NAME_OF_MESH_IS_EMPTY</source>
-            <translation>Name of mesh is empty
-Please enter valid name and try again</translation>
-        </message>
-        <message>
-            <source>NAME_OF_SUBMESH_IS_EMPTY</source>
-            <translation>Name of submesh is empty
-Please enter valid name and try again</translation>
-        </message>
-        <message>
-            <source>THERE_IS_NO_OBJECT_FOR_EDITING</source>
-            <translation>There is no object for editing. Please
-select mesh or sub-mesh and try again</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_MeshPatternDlg</name>
-        <message>
-            <source>3D_BLOCK</source>
-            <translation>3D block</translation>
-        </message>
-        <message>
-            <source>CAPTION</source>
-            <translation>Pattern Mapping</translation>
-        </message>
-        <message>
-            <source>CREATE_POLYEDRS_NEAR_BOUNDARY</source>
-            <translation>Create polyhedrons near boundary</translation>
-        </message>
-        <message>
-            <source>CREATE_POLYGONS_NEAR_BOUNDARY</source>
-            <translation>Create polygons near boundary</translation>
-        </message>
-        <message>
-            <source>ERROR_OF_LOADING</source>
-            <translation>Loading of pattern from file failed. Probably file
-is corrupted or contains pattern of the other type</translation>
-        </message>
-        <message>
-            <source>ERROR_OF_OPENING</source>
-            <translation>It is impossible to open file. Please verify whether
-file exists and your permission to this file</translation>
-        </message>
-        <message>
-            <source>ERROR_OF_READING</source>
-            <translation>It is impossible to load pattern
-Please verify file's contents</translation>
-        </message>
-        <message>
-            <source>ERR_READ_3D_COORD</source>
-            <translation>It is impossible to load pattern
-Coordinates of 3D points out of [0,1] range</translation>
-        </message>
-        <message>
-            <source>ERR_READ_BAD_INDEX</source>
-            <translation>It is impossible to load pattern
-Invalid index of point detected</translation>
-        </message>
-        <message>
-            <source>ERR_READ_BAD_KEY_POINT</source>
-            <translation>It is impossible to load pattern
-Key-point not on a boundary</translation>
-        </message>
-        <message>
-            <source>ERR_READ_ELEM_POINTS</source>
-            <translation>It is impossible to load pattern
-invalid number of points in element</translation>
-        </message>
-        <message>
-            <source>ERR_READ_NB_POINTS</source>
-            <translation>It is impossible to load pattern
-It is impossible to read number of points from file</translation>
-        </message>
-        <message>
-            <source>ERR_READ_NO_ELEMS</source>
-            <translation>It is impossible to load pattern
-There are no elements in it</translation>
-        </message>
-        <message>
-            <source>ERR_READ_NO_KEYPOINT</source>
-            <translation>It is impossible to load pattern
-There are no key-points in 2D one</translation>
-        </message>
-        <message>
-            <source>ERR_READ_POINT_COORDS</source>
-            <translation>It is impossible to load pattern
-It is impossible to read point coordinates from file</translation>
-        </message>
-        <message>
-            <source>ERR_READ_TOO_FEW_POINTS</source>
-            <translation>It is impossible to load pattern. There are
- too few points in the file for pattern loading</translation>
-        </message>
-        <message>
-            <source>FACE</source>
-            <translation>Face</translation>
-        </message>
-        <message>
-            <source>LOAD_PATTERN</source>
-            <translation>Load pattern</translation>
-        </message>
-        <message>
-            <source>MESH_FACES</source>
-            <translation>Mesh faces</translation>
-        </message>
-        <message>
-            <source>MESH_VOLUMES</source>
-            <translation>Mesh volumes</translation>
-        </message>
-        <message>
-            <source>NEW</source>
-            <translation>New...</translation>
-        </message>
-        <message>
-            <source>NODE_1</source>
-            <translation>Node 1</translation>
-        </message>
-        <message>
-            <source>NODE_2</source>
-            <translation>Node 2</translation>
-        </message>
-        <message>
-            <source>PATTERN</source>
-            <translation>Pattern</translation>
-        </message>
-        <message>
-            <source>PATTERN_FILT</source>
-            <translation>Pattern files(*.smp)</translation>
-        </message>
-        <message>
-            <source>PATTERN_TYPE</source>
-            <translation>Pattern type</translation>
-        </message>
-        <message>
-            <source>PREVIEW</source>
-            <translation>Preview</translation>
-        </message>
-        <message>
-            <source>REFINE</source>
-            <translation>Refine selected mesh elements</translation>
-        </message>
-        <message>
-            <source>REVERSE</source>
-            <translation>Reverse order of key-points</translation>
-        </message>
-        <message>
-            <source>VERTEX</source>
-            <translation>Vertex   </translation>
-        </message>
-        <message>
-            <source>VERTEX1</source>
-            <translation>Vertex 1</translation>
-        </message>
-        <message>
-            <source>VERTEX2</source>
-            <translation>Vertex 2</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_MeshTab</name>
-        <message>
-            <source>ADD_HYPOTHESIS</source>
-            <translation>Add. Hypothesis</translation>
-        </message>
-        <message>
-            <source>ALGORITHM</source>
-            <translation>Algorithm</translation>
-        </message>
-        <message>
-            <source>HYPOTHESIS</source>
-            <translation>Hypothesis</translation>
-        </message>
-        <message>
-            <source>NONE</source>
-            <translation>&lt;None></translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_MoveNodesDlg</name>
-        <message>
-            <source>CAPTION</source>
-            <translation>Move node</translation>
-        </message>
-        <message>
-            <source>NODE_ID_IS_NOT_DEFINED</source>
-            <translation>Node ID is not defined</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_MultiEditDlg</name>
-        <message>
-            <source>ADD</source>
-            <translation>Add</translation>
-        </message>
-        <message>
-            <source>FILTER</source>
-            <translation>Filter</translation>
-        </message>
-        <message>
-            <source>REMOVE</source>
-            <translation>Remove</translation>
-        </message>
-        <message>
-            <source>SELECT_FROM</source>
-            <translation>Select from</translation>
-        </message>
-        <message>
-            <source>SORT_LIST</source>
-            <translation>Sort list</translation>
-        </message>
-        <message>
-            <source>SPLIT_JOIN_CRITERION</source>
-            <translation>Criterion</translation>
-        </message>
-        <message>
-            <source>TO_ALL</source>
-            <translation>Apply to all</translation>
-        </message>
-        <message>
-            <source>USE_DIAGONAL_1_3</source>
-            <translation>Use diagonal 1-3</translation>
-        </message>
-        <message>
-            <source>USE_DIAGONAL_2_4</source>
-            <translation>Use diagonal 2-4</translation>
-        </message>
-        <message>
-            <source>USE_NUMERIC_FUNC</source>
-            <translation>Use numeric functor</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_PrecisionDlg</name>
-        <message>
-            <source>CAPTION</source>
-            <translation>Precision for mesh quality controls</translation>
-        </message>
-        <message>
-            <source>NOT_USE</source>
-            <translation>Do not use</translation>
-        </message>
-        <message>
-            <source>PRECISION</source>
-            <translation>Number of digits after point</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_RevolutionDlg</name>
-        <message>
-            <source>ANGLE_BY_STEP</source>
-            <translation>Angle by Step</translation>
-        </message>
-        <message>
-            <source>PREVIEW</source>
-            <translation>Preview</translation>
-        </message>
-        <message>
-            <source>REVOLUTION_1D</source>
-            <translation>Revolution of 1D elements</translation>
-        </message>
-        <message>
-            <source>REVOLUTION_2D</source>
-            <translation>Revolution of 2D elements</translation>
-        </message>
-        <message>
-            <source>REVOLUTION_AROUND_AXIS</source>
-            <translation>Revolution around an axis</translation>
-        </message>
-        <message>
-            <source>TOTAL_ANGLE</source>
-            <translation>Total Angle</translation>
-        </message>
-       <message>
-           <source>MEN_POINT_SELECT</source>
-            <translation>From Origin to selected Point</translation>
-        </message>
-       <message>
-           <source>MEN_FACE_SELECT</source>
-            <translation>Normal to selected Face</translation>
-        </message>     
-    </context>
-    <context>
-        <name>SMESHGUI_SewingDlg</name>
-        <message>
-            <source>BORDER</source>
-            <translation>Border</translation>
-        </message>
-        <message>
-            <source>BORDER_1</source>
-            <translation>Border 1</translation>
-        </message>
-        <message>
-            <source>BORDER_2</source>
-            <translation>Border 2</translation>
-        </message>
-        <message>
-            <source>CREATE_POLYEDRS_NEAR_BOUNDARY</source>
-            <translation>Replace affected volumes by polyedres</translation>
-        </message>
-        <message>
-            <source>CREATE_POLYGONS_INSTEAD_SPLITTING</source>
-            <translation>Create polygons instead of splitting</translation>
-        </message>
-        <message>
-            <source>ERROR_1</source>
-            <translation>Free Border1 not found by the selected nodes</translation>
-        </message>
-        <message>
-            <source>ERROR_2</source>
-            <translation>Free Border2 not found by the selected nodes</translation>
-        </message>
-        <message>
-            <source>ERROR_3</source>
-            <translation>Free Border1 and Border2 not found by the selected nodes</translation>
-        </message>
-        <message>
-            <source>ERROR_4</source>
-            <translation>No path from the first side node to the last side node have been found</translation>
-        </message>
-        <message>
-            <source>ERROR_5</source>
-            <translation>Not allowed to splite volumes on the side!</translation>
-        </message>
-        <message>
-            <source>ERROR_6</source>
-            <translation>Different number of elements selected on the sides</translation>
-        </message>
-        <message>
-            <source>ERROR_7</source>
-            <translation>Element sets are topologically different or given nodes are inconvenient</translation>
-        </message>
-        <message>
-            <source>ERROR_8</source>
-            <translation>Nodes on the side 1 are either not linked or not laying on the element set boundary</translation>
-        </message>
-        <message>
-            <source>ERROR_9</source>
-            <translation>Nodes on the side 2 are either not linked or not laying on the element set boundary</translation>
-        </message>
-        <message>
-            <source>FIRST_NODE_ID</source>
-            <translation>First Node ID</translation>
-        </message>
-        <message>
-            <source>LAST_NODE_ID</source>
-            <translation>Last Node ID</translation>
-        </message>
-        <message>
-            <source>MERGE_EQUAL_ELEMENTS</source>
-            <translation>Merge equal elements</translation>
-        </message>
-        <message>
-            <source>NODE1_TO_MERGE</source>
-            <translation>Node 1 To Merge</translation>
-        </message>
-        <message>
-            <source>NODE2_TO_MERGE</source>
-            <translation>Node 2 To Merge</translation>
-        </message>
-        <message>
-            <source>SECOND_NODE_ID</source>
-            <translation>Second Node ID</translation>
-        </message>
-        <message>
-            <source>SEW_BORDER_TO_SIDE</source>
-            <translation>Sew Border To Side</translation>
-        </message>
-        <message>
-            <source>SEW_CONFORM_FREE_BORDERS</source>
-            <translation>Sew Conform Free Borders</translation>
-        </message>
-        <message>
-            <source>SEW_FREE_BORDERS</source>
-            <translation>Sew Free Borders</translation>
-        </message>
-        <message>
-            <source>SEW_SIDE_ELEMENTS</source>
-            <translation>Sew Side Elements</translation>
-        </message>
-        <message>
-            <source>SIDE</source>
-            <translation>Side</translation>
-        </message>
-        <message>
-            <source>SIDE_1</source>
-            <translation>Side 1</translation>
-        </message>
-        <message>
-            <source>SIDE_2</source>
-            <translation>Side 2</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_ShapeByMeshDlg</name>
-        <message>
-            <source>CAPTION</source>
-            <translation>Find geometry by mesh element</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_SingleEditDlg</name>
-        <message>
-            <source>EDGE_BETWEEN</source>
-            <translation>Edge between neighboring triangles</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_SmoothingDlg</name>
-        <message>
-            <source>CENTROIDAL</source>
-            <translation>Centroidal</translation>
-        </message>
-        <message>
-            <source>FIXED_NODES_IDS</source>
-            <translation>Fixed nodes ids</translation>
-        </message>
-        <message>
-            <source>IS_PARAMETRIC</source>
-            <translation>in parametric space</translation>
-        </message>
-        <message>
-            <source>ITERATION_LIMIT</source>
-            <translation>Iteration limit</translation>
-        </message>
-        <message>
-            <source>LAPLACIAN</source>
-            <translation>Laplacian</translation>
-        </message>
-        <message>
-            <source>MAX_ASPECT_RATIO</source>
-            <translation>Max. aspect ratio</translation>
-        </message>
-        <message>
-            <source>METHOD</source>
-            <translation>Method</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_TrianglesInversionDlg</name>
-        <message>
-            <source>CAPTION</source>
-            <translation>Diagonal inversion</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_UnionOfTrianglesDlg</name>
-        <message>
-            <source>CAPTION</source>
-            <translation>Union of triangles</translation>
-        </message>
-        <message>
-            <source>MAXIMUM_ANGLE</source>
-            <translation>Maximum bending angle</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_UnionOfTwoTrianglesDlg</name>
-        <message>
-            <source>CAPTION</source>
-            <translation>Union of two triangles</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_WhatIsDlg</name>
-        <message>
-            <source>ENTITY_TYPE</source>
-            <translation>Element type</translation>
-        </message>
-        <message>
-            <source>GRAVITY_CENTER</source>
-            <translation>Gravity center</translation>
-        </message>
-    </context>
-    <context>
-        <name>SMESHGUI_FileInfoDlg</name>
-        <message>
-            <source>CAPTION</source>
-            <translation>File information</translation>
-        </message>
-        <message>
-            <source>FILE_NAME</source>
-            <translation>File name</translation>
-        </message>
-        <message>
-            <source>FILE_SIZE</source>
-            <translation>File size (bytes)</translation>
-        </message>
-        <message>
-            <source>MED_VERSION</source>
-            <translation>MED version</translation>
-        </message>
-    </context>
+    <message>
+        <source>0DELEM</source>
+        <translation>0D element</translation>
+    </message>
+    <message>
+        <source>BALL_ELEMENT</source>
+        <translation>ball</translation>
+    </message>
+    <message>
+        <source>UNKNOWN</source>
+        <translation>Unknown</translation>
+    </message>
+    <message>
+        <source>ENTITY_TYPE</source>
+        <translation>Entity type</translation>
+    </message>
+    <message>
+        <source>SIZE</source>
+        <translation>Size</translation>
+    </message>
+    <message>
+        <source>COLOR</source>
+        <translation>Color</translation>
+    </message>
+    <message>
+        <source>NB_NODES</source>
+        <translation>Underlying nodes</translation>
+    </message>
+    <message>
+        <source>COMPUTE</source>
+        <translation>Compute</translation>
+    </message>
+    <message>
+        <source>LOAD</source>
+        <translation>Load</translation>
+    </message>
+    <message>
+        <source>MESH_ON_GEOMETRY</source>
+        <translation>Based on geometry</translation>
+    </message>
+    <message>
+        <source>MESH_FROM_FILE</source>
+        <translation>Imported</translation>
+    </message>
+    <message>
+        <source>FILE_NAME</source>
+        <translation>File name</translation>
+    </message>
+    <message>
+        <source>STANDALONE_MESH</source>
+        <translation>Standalone</translation>
+    </message>
+    <message>
+        <source>SUBMESHES</source>
+        <translation>Sub-meshes</translation>
+    </message>
+    <message>
+        <source>SUBMESHES_0</source>
+        <translation>Compound</translation>
+    </message>
+    <message>
+        <source>SUBMESHES_2</source>
+        <translation>Solid</translation>
+    </message>
+    <message>
+        <source>SUBMESHES_3</source>
+        <translation>Shell</translation>
+    </message>
+    <message>
+        <source>SUBMESHES_4</source>
+        <translation>Face</translation>
+    </message>
+    <message>
+        <source>SUBMESHES_5</source>
+        <translation>Wire</translation>
+    </message>
+    <message>
+        <source>SUBMESHES_6</source>
+        <translation>Edge</translation>
+    </message>
+    <message>
+        <source>SUBMESHES_7</source>
+        <translation>Vertex</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MinDistance</name>
+    <message>
+        <source>FIRST_TARGET</source>
+        <translation>First target</translation>
+    </message>
+    <message>
+        <source>SECOND_TARGET</source>
+        <translation>Second target</translation>
+    </message>
+    <message>
+        <source>NODE</source>
+        <translation>Node</translation>
+    </message>
+    <message>
+        <source>ELEMENT</source>
+        <translation>Element</translation>
+    </message>
+    <message>
+        <source>OBJECT</source>
+        <translation>Object</translation>
+    </message>
+    <message>
+        <source>ORIGIN</source>
+        <translation>Origin</translation>
+    </message>
+    <message>
+        <source>COMPUTE</source>
+        <translation>Compute</translation>
+    </message>
+    <message>
+        <source>RESULT</source>
+        <translation>Distance between targets</translation>
+    </message>
+    <message>
+        <source>DISTANCE</source>
+        <translation>Distance</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_CopyMeshDlg</name>
+    <message>
+        <source>OBJECT_NAME</source>
+        <translation>Source Object</translation>
+    </message>
+    <message>
+        <source>ELEM_IDS</source>
+        <translation>Source Element IDs</translation>
+    </message>
+    <message>
+        <source>NEW_NAME</source>
+        <translation>New Mesh Name</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MeasureDlg</name>
+    <message>
+        <source>MEASUREMENTS</source>
+        <translation>Measurements</translation>
+    </message>
+    <message>
+        <source>MIN_DIST</source>
+        <translation>Minimum Distance</translation>
+    </message>
+    <message>
+        <source>BND_BOX</source>
+        <translation>Bounding Box</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_BoundingBox</name>
+    <message>
+        <source>SOURCE</source>
+        <translation>Source</translation>
+    </message>
+    <message>
+        <source>OBJECTS</source>
+        <translation>Objects</translation>
+    </message>
+    <message>
+        <source>NODES</source>
+        <translation>Nodes</translation>
+    </message>
+    <message>
+        <source>ELEMENTS</source>
+        <translation>Elements</translation>
+    </message>
+    <message>
+        <source>COMPUTE</source>
+        <translation>Compute</translation>
+    </message>
+    <message>
+        <source>RESULT</source>
+        <translation>Bounding Box</translation>
+    </message>
+    <message>
+        <source>SELECTED_NB_OBJ</source>
+        <translation>%1 %2 selected</translation>
+    </message>
+    <message>
+        <source>NB_NODES</source>
+        <translation>nodes</translation>
+    </message>
+    <message>
+        <source>NB_ELEMENTS</source>
+        <translation>elements</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MeshLoadingProgress</name>
+    <message>
+        <source>MESH_LOAD_PROGRESS_TITLE</source>
+        <translation>Mesh Loading</translation>
+    </message>
+</context>
+<context>
+    <name>StdMeshersGUI_SubShapeSelectorWdg</name>
+    <message>
+        <source>X_FROM_Y_ITEMS_SHOWN</source>
+        <translation>%1-%2 from %3 items shown</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_Preferences_ColorDlg</name>
+    <message>
+        <source>DIALOG_TITLE</source>
+        <translation>Properties (color, line width, shrink size, ...)</translation>
+    </message>
+    <message>
+        <source>GRP_ELEMENTS</source>
+        <translation>Elements</translation>
+    </message>
+    <message>
+        <source>SURFACE_COLOR_LBL</source>
+        <translation>Surface color</translation>
+    </message>
+    <message>
+        <source>BACKSURFACE_COLOR_LBL</source>
+        <translation>Back surface color</translation>
+    </message>
+    <message>
+        <source>OUTLINE_COLOR_LBL</source>
+        <translation>Outline color</translation>
+    </message>
+    <message>
+        <source>WIREFRAME_COLOR_LBL</source>
+        <translation>Wireframe color</translation>
+    </message>
+    <message>
+        <source>0D_ELEMENTS_COLOR_LBL</source>
+        <translation>0D elements</translation>
+    </message>
+    <message>
+        <source>0D_ELEMENTS_SIZE_LBL</source>
+        <translation>Size of 0D elements</translation>
+    </message>
+    <message>
+        <source>BALL_ELEMENTS_COLOR_LBL</source>
+        <translation>Ball elements</translation>
+    </message>
+    <message>
+        <source>BALL_ELEMENTS_SIZE_LBL</source>
+        <translation>Size of balls</translation>
+    </message>
+    <message>
+        <source>LINE_WIDTH_LBL</source>
+        <translation>Line width</translation>
+    </message>
+    <message>
+        <source>SHRINK_COEF_LBL</source>
+        <translation>Shrink coef.</translation>
+    </message>
+    <message>
+        <source>GRP_NODES</source>
+        <translation>Nodes</translation>
+    </message>
+    <message>
+        <source>NODES_COLOR_LBL</source>
+        <translation>Color</translation>
+    </message>
+    <message>
+        <source>NODES_MARKER_LBL</source>
+        <translation>Marker</translation>
+    </message>
+    <message>
+        <source>GRP_ORIENTATION</source>
+        <translation>Orientation of faces</translation>
+    </message>
+    <message>
+        <source>ORIENTATION_COLOR_LBL</source>
+        <translation>Color</translation>
+    </message>
+    <message>
+        <source>ORIENTATION_SCALE_LBL</source>
+        <translation>Scale</translation>
+    </message>
+    <message>
+        <source>3D_VECTORS_LBL</source>
+        <translation>3D vectors</translation>
+    </message>
+    <message>
+        <source>GRP_SELECTION</source>
+        <translation>Selection</translation>
+    </message>
+    <message>
+        <source>SELECTION_COLOR_LBL</source>
+        <translation>Selection color</translation>
+    </message>
+    <message>
+        <source>PRESELECTION_COLOR_LBL</source>
+        <translation>Pre-selection color</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_ReorientFacesDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Reorient faces by vector</translation>
+    </message>
+    <message>
+        <source>REORIENT_FACES</source>
+        <translation>Reorient</translation>
+    </message>
+    <message>
+        <source>DIRECTION</source>
+        <translation>Direction</translation>
+    </message>
+    <message>
+        <source>OBJECT</source>
+        <translation>Object</translation>
+    </message>
+    <message>
+        <source>POINT</source>
+        <translation>Point</translation>
+    </message>
+    <message>
+        <source>FACE</source>
+        <translation>Face</translation>
+    </message>
+    <message>
+        <source>FACES</source>
+        <translation>Faces source</translation>
+    </message>
+    <message>
+        <source>ORIENTATION</source>
+        <translation>Orientation</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_ReorientFacesOp</name>
+    <message>
+        <source>NO_OBJECT_SELECTED</source>
+        <translation>No object selected</translation>
+    </message>
+    <message>
+        <source>NO_FACES</source>
+        <translation>Object includes no faces</translation>
+    </message>
+    <message>
+        <source>ZERO_SIZE_VECTOR</source>
+        <translation>Zero size vector</translation>
+    </message>
+    <message>
+        <source>INVALID_FACE</source>
+        <translation>Not valid face</translation>
+    </message>
+    <message>
+        <source>NB_REORIENTED</source>
+        <translation>%1 faces reversed</translation>
+    </message>
+</context>
 </TS>
diff --git a/src/SMESHGUI/SMESH_msg_fr.ts b/src/SMESHGUI/SMESH_msg_fr.ts
new file mode 100755 (executable)
index 0000000..1672f6f
--- /dev/null
@@ -0,0 +1,6968 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="fr_FR">
+<context>
+    <name>@default</name>
+    <message>
+        <source>SMESH_EXPORT_MESH</source>
+        <translation>Exporter le maillage</translation>
+    </message>
+    <message>
+        <source>MED_FILES_FILTER</source>
+        <translation>Fichiers MED</translation>
+    </message>
+    <message>
+        <source>IDEAS_FILES_FILTER</source>
+        <translation>Fichiers IDEAS</translation>
+    </message>
+    <message>
+        <source>DAT_FILES_FILTER</source>
+        <translation>Fichiers DAT</translation>
+    </message>
+    <message>
+        <source>TEXT_FILES_FILTER</source>
+        <translation>Fichiers TXT</translation>
+    </message>
+    <message>
+        <source>MED_VX_FILES_FILTER</source>
+        <translation>Fichiers MED %1</translation>
+    </message>
+    <message>
+        <source>STL_ASCII_FILES_FILTER</source>
+        <translation>Fichiers STL ASCII</translation>
+    </message>
+    <message>
+        <source>CGNS_FILES_FILTER</source>
+        <translation>Fichiers CGNS</translation>
+    </message>
+    <message>
+        <source>STL_BIN_FILES_FILTER</source>
+        <translation>Fichiers STL binaires</translation>
+    </message>
+    <message>
+        <source>ALL_FILES_FILTER</source>
+        <translation>Tous les fichiers</translation>
+    </message>
+    <message>
+        <source>SMESH_AND</source>
+        <translation>et</translation>
+    </message>
+    <message>
+        <source>AREA_ELEMENTS</source>
+        <translation>Aire</translation>
+    </message>
+    <message>
+        <source>ASPECTRATIO_3D_ELEMENTS</source>
+        <translation>Rapport de forme 3D</translation>
+    </message>
+    <message>
+        <source>ASPECTRATIO_ELEMENTS</source>
+        <translation>Rapport de forme</translation>
+    </message>
+    <message>
+        <source>NODE_POSITION</source>
+        <translation>Position</translation>
+    </message>
+    <message>
+        <source>U_POSITION</source>
+        <translation>U</translation>
+    </message>
+    <message>
+        <source>V_POSITION</source>
+        <translation>V</translation>
+    </message>
+    <message>
+        <source>COL_ALGO_HEADER</source>
+        <translation>Algorithme</translation>
+    </message>
+    <message>
+        <source>COL_ERROR_HEADER</source>
+        <translation>Erreur</translation>
+    </message>
+    <message>
+        <source>COL_SHAPE_HEADER</source>
+        <translation>SousObjet</translation>
+    </message>
+    <message>
+        <source>COMPERR_ALGO_FAILED</source>
+        <translation>L&apos;algorithme n&apos;a pas abouti</translation>
+    </message>
+    <message>
+        <source>COMPERR_BAD_INPUT_MESH</source>
+        <translation>Le maillage d&apos;entrée est invalide</translation>
+    </message>
+    <message>
+        <source>COMPERR_BAD_SHAPE</source>
+        <translation>Géométrie inattendue</translation>
+    </message>
+    <message>
+        <source>COMPERR_EXCEPTION</source>
+        <translation>Exception inconnue</translation>
+    </message>
+    <message>
+        <source>COMPERR_MEMORY_PB</source>
+        <translation>Problème d&apos;affectation de la mémoire</translation>
+    </message>
+    <message>
+        <source>COMPERR_OCC_EXCEPTION</source>
+        <translation>Exception OCC</translation>
+    </message>
+    <message>
+        <source>COMPERR_OK</source>
+        <translation>Pas d&apos;erreur</translation>
+    </message>
+    <message>
+        <source>COMPERR_SLM_EXCEPTION</source>
+        <translation>Exception SALOME</translation>
+    </message>
+    <message>
+        <source>COMPERR_STD_EXCEPTION</source>
+        <translation>std::exception</translation>
+    </message>
+    <message>
+        <source>COMPERR_UNKNOWN</source>
+        <translation>Erreur inconnue</translation>
+    </message>
+    <message>
+        <source>COMPERR_CANCELED</source>
+        <translation>Calcul annulé</translation>
+    </message>
+    <message>
+        <source>SMESH_GEOM</source>
+        <translation>Géométrie</translation>
+    </message>
+    <message>
+        <source>DIRECT_GEOM_SELECTION</source>
+        <translation>Sélection directe de la géométrie</translation>
+    </message>
+    <message>
+        <source>ELEMENT_ID</source>
+        <translation>ID de l&apos;élément</translation>
+    </message>
+    <message>
+        <source>FREE_BORDERS</source>
+        <translation>Frontières libres</translation>
+    </message>
+    <message>
+        <source>GEOMETRY_NAME</source>
+        <translation>Nom de la géométrie</translation>
+    </message>
+    <message>
+        <source>GEOM_BY_MESH_ELEM_SELECTION</source>
+        <translation>Trouver la géométrie en choisissant l&apos;élément de maillage</translation>
+    </message>
+    <message>
+        <source>GLOBAL_ALGO</source>
+        <translation>Global</translation>
+    </message>
+    <message>
+        <source>INF_SELECT_OBJECT</source>
+        <translation>Choisir un objet</translation>
+    </message>
+    <message>
+        <source>LENGTH2D_EDGES</source>
+        <translation>Longueur 2D</translation>
+    </message>
+    <message>
+        <source>LENGTH_EDGES</source>
+        <translation>Longueur</translation>
+    </message>
+    <message>
+        <source>LOCAL_ALGO</source>
+        <translation>Local</translation>
+    </message>
+    <message>
+        <source>MAX_ELEMENT_LENGTH_2D</source>
+        <translation>Diamètre d&apos;éléments 2D</translation>
+    </message>
+    <message>
+        <source>MAX_ELEMENT_LENGTH_3D</source>
+        <translation>Diamètre d&apos;éléments 3D</translation>
+    </message>
+    <message>
+        <source>MEN_ADD</source>
+        <translation>Ajouter</translation>
+    </message>
+    <message>
+        <source>MEN_ADV_INFO</source>
+        <translation>Informations sur le maillage</translation>
+    </message>
+    <message>
+        <source>MEN_ALL</source>
+        <translation>Tous</translation>
+    </message>
+    <message>
+        <source>MEN_AREA</source>
+        <translation>Aire</translation>
+    </message>
+    <message>
+        <source>MEN_ASPECT</source>
+        <translation>Rapport de forme</translation>
+    </message>
+    <message>
+        <source>MEN_ASPECT_3D</source>
+        <translation>Rapport de forme 3D</translation>
+    </message>
+    <message>
+        <source>MEN_AUTO_COLOR</source>
+        <translation>Couleur automatique</translation>
+    </message>
+    <message>
+        <source>MEN_AUTO_UPD</source>
+        <translation>Mise Ã  jour automatique</translation>
+    </message>
+    <message>
+        <source>MEN_BUILD_COMPOUND</source>
+        <translation>Construire un assemblage</translation>
+    </message>
+    <message>
+        <source>MEN_COPY_MESH</source>
+        <translation>Copier le maillage</translation>
+    </message>
+    <message>
+        <source>MEN_CLIP</source>
+        <translation>Plan de coupe</translation>
+    </message>
+    <message>
+        <source>MEN_COLORS</source>
+        <translation>Paramètres d&apos;affichage</translation>
+    </message>
+    <message>
+        <source>MEN_COMPUTE</source>
+        <translation>Calculer</translation>
+    </message>
+    <message>
+        <source>MEN_PRECOMPUTE</source>
+        <translation>Prévisualiser</translation>
+    </message>
+    <message>
+        <source>MEN_EVALUATE</source>
+        <translation>Evaluer</translation>
+    </message>
+    <message>
+        <source>MEN_CONNECTION</source>
+        <translation>Frontières sur connexions multiples</translation>
+    </message>
+    <message>
+        <source>MEN_CONNECTION_2D</source>
+        <translation>Frontières sur connexions multiples 2D</translation>
+    </message>
+    <message>
+        <source>MEN_CONSTRUCT_GROUP</source>
+        <translation>Construire un groupe</translation>
+    </message>
+    <message>
+        <source>MEN_CONV_TO_QUAD</source>
+        <translation>Convertir vers/de quadratique</translation>
+    </message>
+    <message>
+        <source>MEN_2D_FROM_3D</source>
+        <translation>Créer les Ã©léments de frontière</translation>
+    </message>
+    <message>
+        <source>MEN_MESH_ORDER</source>
+        <translation>Changer la priorité des sous-maillages</translation>
+    </message>
+    <message>
+        <source>MEN_CREATE_GROUP</source>
+        <translation>Créer un groupe</translation>
+    </message>
+    <message>
+        <source>MEN_CREATE_GEO_GROUP</source>
+        <translation>Créer des groupes Ã  partir de la géométrie</translation>
+    </message>
+    <message>
+        <source>MEN_CREATE_MESH</source>
+        <translation>Créer un maillage</translation>
+    </message>
+    <message>
+        <source>MEN_CREATE_SUBMESH</source>
+        <translation>Créer un sous-maillage</translation>
+    </message>
+    <message>
+        <source>MEN_CTRL</source>
+        <translation>Contrôles</translation>
+    </message>
+    <message>
+        <source>MEN_NODE_CTRL</source>
+        <translation>Contrôles des nÅ“uds</translation>
+    </message>
+    <message>
+        <source>MEN_EDGE_CTRL</source>
+        <translation>Contrôles des arêtes</translation>
+    </message>
+    <message>
+        <source>MEN_FACE_CTRL</source>
+        <translation>Contrôles des faces</translation>
+    </message>
+    <message>
+        <source>MEN_VOLUME_CTRL</source>
+        <translation>Contrôles des volumes</translation>
+    </message>
+    <message>
+        <source>MEN_CUT</source>
+        <translation>Découpe des quadrangles</translation>
+    </message>
+    <message>
+        <source>MEN_CUT_GROUP</source>
+        <translation>Découpe des groupes</translation>
+    </message>
+    <message>
+        <source>MEN_IMPORT_DAT</source>
+        <translation>Fichier DAT</translation>
+    </message>
+    <message>
+        <source>MEN_DAT</source>
+        <translation>Fichier DAT</translation>
+    </message>
+    <message>
+        <source>MEN_DELETE</source>
+        <translation>Supprimer</translation>
+    </message>
+    <message>
+        <source>MEN_DEL_GROUP</source>
+        <translation>Supprimer les groupes et leur contenu</translation>
+    </message>
+    <message>
+        <source>MEN_FACE_ORIENTATION</source>
+        <translation>Orientation des faces</translation>
+    </message>
+    <message>
+        <source>MEN_DISABLE_AUTO_COLOR</source>
+        <translation>Désactiver la couleur automatique</translation>
+    </message>
+    <message>
+        <source>MEN_DISPLAY_ONLY</source>
+        <translation>Afficher uniquement</translation>
+    </message>
+    <message>
+        <source>MEN_DISPMODE</source>
+        <translation>Mode de visualisation</translation>
+    </message>
+    <message>
+        <source>MEN_DISP_ENT</source>
+        <translation>Montrer l&apos;entité</translation>
+    </message>
+    <message>
+        <source>MEN_ELEM0D</source>
+        <translation>Elément 0D</translation>
+    </message>
+    <message>
+        <source>MEN_ELEMS0D</source>
+        <translation>Eléments 0D </translation>
+    </message>
+    <message>
+        <source>MEN_BALL</source>
+        <translation>Particulaire</translation>
+    </message>
+    <message>
+        <source>MEN_BALLS</source>
+        <translation>Particulaires</translation>
+    </message>
+    <message>
+        <source>MEN_EDGE</source>
+        <translation>Arête</translation>
+    </message>
+    <message>
+        <source>MEN_EDGES</source>
+        <translation>Arêtes</translation>
+    </message>
+    <message>
+        <source>MEN_EDIT</source>
+        <translation>Edition</translation>
+    </message>
+    <message>
+        <source>MEN_EDIT_GROUP</source>
+        <translation>Editer un groupe</translation>
+    </message>
+    <message>
+        <source>MEN_EDIT_GEOMGROUP_AS_GROUP</source>
+        <translation>Editer un groupe en tant qu&apos;autonome</translation>
+    </message>
+    <message>
+        <source>MEN_EDIT_HYPO</source>
+        <translation>Editer une hypothèse</translation>
+    </message>
+    <message>
+        <source>MEN_EDIT_MESHSUBMESH</source>
+        <translation>Editer un maillage/sous-maillage</translation>
+    </message>
+    <message>
+        <source>MEN_EXPORT</source>
+        <translation>Exporter</translation>
+    </message>
+    <message>
+        <source>MEN_EXPORT_DAT</source>
+        <translation>Exporter au format DAT</translation>
+    </message>
+    <message>
+        <source>MEN_EXPORT_MED</source>
+        <translation>Exporter au format MED</translation>
+    </message>
+    <message>
+        <source>MEN_EXPORT_CGNS</source>
+        <translation>Exporter au format CGNS</translation>
+    </message>
+    <message>
+        <source>MEN_EXPORT_SAUV</source>
+        <translation>Exporter au format SAUV (ASCII)</translation>
+    </message>
+    <message>
+        <source>MEN_EXPORT_STL</source>
+        <translation>Exporter au format STL</translation>
+    </message>
+    <message>
+        <source>MEN_EXPORT_UNV</source>
+        <translation>Exporter au format UNV</translation>
+    </message>
+    <message>
+        <source>MEN_EXTRUSION</source>
+        <translation>Extrusion</translation>
+    </message>
+    <message>
+        <source>MEN_EXTRUSION_ALONG</source>
+        <translation>Extrusion suivant un chemin</translation>
+    </message>
+    <message>
+        <source>MEN_FACES</source>
+        <translation>Faces</translation>
+    </message>
+    <message>
+        <source>MEN_FILE</source>
+        <translation>Fichier</translation>
+    </message>
+    <message>
+        <source>MEN_FIND_ELEM</source>
+        <translation>Trouver un Ã©lément par un point</translation>
+    </message>
+    <message>
+        <source>TOP_REORIENT_2D</source>
+        <translation>Réorienter des faces selon un vecteur</translation>
+    </message>
+    <message>
+        <source>MEN_REORIENT_2D</source>
+        <translation>Réorienter des faces selon un vecteur</translation>
+    </message>
+    <message>
+        <source>STB_REORIENT_2D</source>
+        <translation>Réorienter des faces selon un vecteur</translation>
+    </message>
+    <message>
+        <source>TOP_FIND_ELEM</source>
+        <translation>Trouver un Ã©lément par un point</translation>
+    </message>
+    <message>
+        <source>STB_FIND_ELEM</source>
+        <translation>Trouver un Ã©lément par un point</translation>
+    </message>
+    <message>
+        <source>EQUAL_NODE</source>
+        <translation>NÅ“uds en double</translation>
+    </message>
+    <message>
+        <source>MEN_EQUAL_NODE</source>
+        <translation>NÅ“uds en double</translation>
+    </message>
+    <message>
+        <source>STB_EQUAL_NODE</source>
+        <translation>NÅ“uds en double</translation>
+    </message>
+    <message>
+        <source>TOP_EQUAL_NODE</source>
+        <translation>NÅ“uds en double</translation>
+    </message>
+    <message>
+        <source>EQUAL_EDGE</source>
+        <translation>Arêtes en double</translation>
+    </message>
+    <message>
+        <source>MEN_EQUAL_EDGE</source>
+        <translation>Arêtes en double</translation>
+    </message>
+    <message>
+        <source>STB_EQUAL_EDGE</source>
+        <translation>Arêtes en double</translation>
+    </message>
+    <message>
+        <source>TOP_EQUAL_EDGE</source>
+        <translation>Arêtes en double</translation>
+    </message>
+    <message>
+        <source>EQUAL_FACE</source>
+        <translation>Faces en double</translation>
+    </message>
+    <message>
+        <source>MEN_EQUAL_FACE</source>
+        <translation>Faces en double</translation>
+    </message>
+    <message>
+        <source>STB_EQUAL_FACE</source>
+        <translation>Faces en double</translation>
+    </message>
+    <message>
+        <source>TOP_EQUAL_FACE</source>
+        <translation>Faces en double</translation>
+    </message>
+    <message>
+        <source>EQUAL_VOLUME</source>
+        <translation>Volumes en double</translation>
+    </message>
+    <message>
+        <source>MEN_EQUAL_VOLUME</source>
+        <translation>Volumes en double</translation>
+    </message>
+    <message>
+        <source>STB_EQUAL_VOLUME</source>
+        <translation>Volumes en double</translation>
+    </message>
+    <message>
+        <source>TOP_EQUAL_VOLUME</source>
+        <translation>Volumes en double</translation>
+    </message>
+    <message>
+        <source>MEN_BARE_BORDER_VOLUME</source>
+        <translation>Volumes avec Ã©léments de peau 2D manquants</translation>
+    </message>
+    <message>
+        <source>MEN_BARE_BORDER_FACE</source>
+        <translation>Faces avec Ã©léments de peau 1D manquants</translation>
+    </message>
+    <message>
+        <source>MEN_OVER_CONSTRAINED_VOLUME</source>
+        <translation>Volumes sur-contraints</translation>
+    </message>
+    <message>
+        <source>MEN_OVER_CONSTRAINED_FACE</source>
+        <translation>Faces sur-contraintes</translation>
+    </message>
+    <message>
+        <source>MEN_FREE_BORDER</source>
+        <translation>Frontières libres</translation>
+    </message>
+    <message>
+        <source>MEN_FREE_EDGE</source>
+        <translation>Arêtes libres</translation>
+    </message>
+    <message>
+        <source>MEN_FREE_NODE</source>
+        <translation>NÅ“uds libres</translation>
+    </message>
+    <message>
+        <source>MEN_FREE_FACES</source>
+        <translation>Faces libres</translation>
+    </message>
+    <message>
+        <source>MEN_GLOBAL_HYPO</source>
+        <translation>Hypothèse globale</translation>
+    </message>
+    <message>
+        <source>MEN_HEXA</source>
+        <translation>Hexaèdre</translation>
+    </message>
+    <message>
+        <source>MEN_HIDE</source>
+        <translation>Cacher</translation>
+    </message>
+    <message>
+        <source>MEN_HYPO</source>
+        <translation>Hypothèses</translation>
+    </message>
+    <message>
+        <source>MEN_IMPORT</source>
+        <translation>Importer</translation>
+    </message>
+    <message>
+        <source>MEN_INT_GROUP</source>
+        <translation>Intersection des groupes</translation>
+    </message>
+    <message>
+        <source>MEN_INV</source>
+        <translation>Inversion de diagonale</translation>
+    </message>
+    <message>
+        <source>MEN_LENGTH</source>
+        <translation>Longueur</translation>
+    </message>
+    <message>
+        <source>MEN_LENGTH_2D</source>
+        <translation>Longueur 2D</translation>
+    </message>
+    <message>
+        <source>MEN_MAP</source>
+        <translation>Projection de motif</translation>
+    </message>
+    <message>
+        <source>MEN_MAX_ELEMENT_LENGTH_2D</source>
+        <translation>Diamètre des Ã©léments 2D</translation>
+    </message>
+    <message>
+        <source>MEN_MAX_ELEMENT_LENGTH_3D</source>
+        <translation>Diamètre des Ã©léments 3D</translation>
+    </message>
+    <message>
+        <source>MEN_IMPORT_MED</source>
+        <translation>Fichier MED</translation>
+    </message>
+    <message>
+        <source>MEN_MED</source>
+        <translation>Fichier MED</translation>
+    </message>
+    <message>
+        <source>MEN_IMPORT_CGNS</source>
+        <translation>Fichier CGNS</translation>
+    </message>
+    <message>
+        <source>MEN_CGNS</source>
+        <translation>Fichier CGNS</translation>
+    </message>
+    <message>
+        <source>MEN_IMPORT_SAUV</source>
+        <translation>Fichier SAUV (ASCII)</translation>
+    </message>
+    <message>
+        <source>MEN_SAUV</source>
+        <translation>Fichier SAUV (ASCII)</translation>
+    </message>
+    <message>
+        <source>MEN_MERGE</source>
+        <translation>Fusionner les nÅ“uds</translation>
+    </message>
+    <message>
+        <source>MEN_MERGE_ELEMENTS</source>
+        <translation>Fusionner les Ã©léments</translation>
+    </message>
+    <message>
+        <source>MEN_MESH</source>
+        <translation>Maillage</translation>
+    </message>
+    <message>
+        <source>MEN_MESH_THROU_POINT</source>
+        <translation>Déplacer un nÅ“ud</translation>
+    </message>
+    <message>
+        <source>MEN_MIN_ANG</source>
+        <translation>Angle minimal</translation>
+    </message>
+    <message>
+        <source>MEN_MODIFY</source>
+        <translation>Modification</translation>
+    </message>
+    <message>
+        <source>MEN_MEASURE</source>
+        <translation>Outils de mesure</translation>
+    </message>
+    <message>
+        <source>MEN_MEASURE_MIN_DIST</source>
+        <translation>Distance minimale</translation>
+    </message>
+    <message>
+        <source>STB_MEASURE_MIN_DIST</source>
+        <translation>Calcule la distance minimum entre deux objets</translation>
+    </message>
+    <message>
+        <source>TOP_MEASURE_MIN_DIST</source>
+        <translation>Distance minimum</translation>
+    </message>
+    <message>
+        <source>MEN_MEASURE_BND_BOX</source>
+        <translation>Boîte englobante</translation>
+    </message>
+    <message>
+        <source>STB_MEASURE_BND_BOX</source>
+        <translation>Calcule la boîte englobante pour le(s) objet(s) sélectionné(s)</translation>
+    </message>
+    <message>
+        <source>TOP_MEASURE_BND_BOX</source>
+        <translation>Boîte englobante</translation>
+    </message>
+    <message>
+        <source>MEN_MOVE</source>
+        <translation>Déplacer un nÅ“ud</translation>
+    </message>
+    <message>
+        <source>MEN_NODE</source>
+        <translation>NÅ“ud</translation>
+    </message>
+    <message>
+        <source>MEN_NODES</source>
+        <translation>NÅ“uds</translation>
+    </message>
+    <message>
+        <source>MEN_NUM</source>
+        <translation>Numérotation</translation>
+    </message>
+    <message>
+        <source>MEN_NUM_ELEMENTS</source>
+        <translation>Montrer les n° des Ã©léments</translation>
+    </message>
+    <message>
+        <source>MEN_NUM_NODES</source>
+        <translation>Montrer les n° des nÅ“uds</translation>
+    </message>
+    <message>
+        <source>MEN_ORIENT</source>
+        <translation>Orientation</translation>
+    </message>
+    <message>
+        <source>MEN_POLYGON</source>
+        <translation>Polygone</translation>
+    </message>
+    <message>
+        <source>MEN_POLYHEDRON</source>
+        <translation>Polyèdre</translation>
+    </message>
+    <message>
+        <source>MEN_PRECISION</source>
+        <translation>Précision</translation>
+    </message>
+    <message>
+        <source>MEN_PREF</source>
+        <translation>Préférences</translation>
+    </message>
+    <message>
+        <source>MEN_QUAD</source>
+        <translation>Quadrangle</translation>
+    </message>
+    <message>
+        <source>MEN_QUADRATIC_EDGE</source>
+        <translation>Arête quadratique</translation>
+    </message>
+    <message>
+        <source>MEN_QUADRATIC_HEXAHEDRON</source>
+        <translation>Hexaèdre quadratique</translation>
+    </message>
+    <message>
+        <source>MEN_QUADRATIC_PENTAHEDRON</source>
+        <translation>Pentaèdre quadratique</translation>
+    </message>
+    <message>
+        <source>MEN_QUADRATIC_PYRAMID</source>
+        <translation>Pyramide quadratique</translation>
+    </message>
+    <message>
+        <source>MEN_QUADRATIC_QUADRANGLE</source>
+        <translation>Quadrangle quadratique</translation>
+    </message>
+    <message>
+        <source>MEN_QUADRATIC_TETRAHEDRON</source>
+        <translation>Tétraèdre quadratique</translation>
+    </message>
+    <message>
+        <source>MEN_QUADRATIC_TRIANGLE</source>
+        <translation>Triangle quadratique</translation>
+    </message>
+    <message>
+        <source>MEN_QUALITY</source>
+        <translation>Contrôles de qualité</translation>
+    </message>
+    <message>
+        <source>MEN_REMOVE</source>
+        <translation>Supprimer</translation>
+    </message>
+    <message>
+        <source>MEN_REMOVE_ELEMENTS</source>
+        <translation>Eléments</translation>
+    </message>
+    <message>
+        <source>MEN_REMOVE_NODES</source>
+        <translation>NÅ“uds</translation>
+    </message>
+    <message>
+        <source>MEN_REMOVE_ORPHAN_NODES</source>
+        <translation>NÅ“uds orphelins</translation>
+    </message>
+    <message>
+        <source>MEN_RENAME</source>
+        <translation>Renommer</translation>
+    </message>
+    <message>
+        <source>MEN_RENUM</source>
+        <translation>Renuméroter</translation>
+    </message>
+    <message>
+        <source>MEN_RENUM_ELEMENTS</source>
+        <translation>Eléments</translation>
+    </message>
+    <message>
+        <source>MEN_RENUM_NODES</source>
+        <translation>NÅ“uds</translation>
+    </message>
+    <message>
+        <source>MEN_RESET</source>
+        <translation>Restaurer</translation>
+    </message>
+    <message>
+        <source>MEN_DISTRIBUTION_CTRL</source>
+        <translation>Distribution</translation>
+    </message>
+    <message>
+        <source>MEN_SAVE_DISTRIBUTION</source>
+        <translation>Exporter la distribution...</translation>
+    </message>
+    <message>
+        <source>MEN_SHOW_DISTRIBUTION</source>
+        <translation>Afficher la distribution</translation>
+    </message>
+    <message>
+        <source>MEN_PLOT_DISTRIBUTION</source>
+        <translation>Tracer</translation>
+    </message>
+    <message>
+        <source>DISTRIBUTION_NB_ENT</source>
+        <translation>TODO</translation>
+    </message>
+    <message>
+        <source>MEN_REVOLUTION</source>
+        <translation>Révolution</translation>
+    </message>
+    <message>
+        <source>MEN_ROT</source>
+        <translation>Rotation</translation>
+    </message>
+    <message>
+        <source>MEN_SCALAR_BAR</source>
+        <translation>Barre scalaire</translation>
+    </message>
+    <message>
+        <source>MEN_SCALAR_BAR_PROP</source>
+        <translation>Propriétés de la barre scalaire</translation>
+    </message>
+    <message>
+        <source>MEN_SELECTION</source>
+        <translation>Sélection</translation>
+    </message>
+    <message>
+        <source>MEN_SEL_FILTER_LIB</source>
+        <translation>Librairie des filtres de sélection</translation>
+    </message>
+    <message>
+        <source>MEN_SEW</source>
+        <translation>Couture</translation>
+    </message>
+    <message>
+        <source>MEN_SHADE</source>
+        <translation>Ombrage</translation>
+    </message>
+    <message>
+        <source>MEN_QUADRATIC_REPRESENT</source>
+        <translation>Quadratique 2D</translation>
+    </message>
+    <message>
+        <source>MEN_LINE_REPRESENTATION</source>
+        <translation>Lignes</translation>
+    </message>
+    <message>
+        <source>MEN_ARC_REPRESENTATION</source>
+        <translation>Arcs</translation>
+    </message>
+    <message>
+        <source>MEN_SHOW</source>
+        <translation>Afficher</translation>
+    </message>
+    <message>
+        <source>MEN_SHRINK</source>
+        <translation>Contraction</translation>
+    </message>
+    <message>
+        <source>MEN_SKEW</source>
+        <translation>Inclinaison d&apos;angle</translation>
+    </message>
+    <message>
+        <source>MEN_SMOOTH</source>
+        <translation>Lissage</translation>
+    </message>
+    <message>
+        <source>MEN_STD_INFO</source>
+        <translation>Informations sur le maillage</translation>
+    </message>
+    <message>
+        <source>MEN_IMPORT_STL</source>
+        <translation>Fichier STL</translation>
+    </message>
+    <message>
+        <source>MEN_STL</source>
+        <translation>Fichier STL</translation>
+    </message>
+    <message>
+        <source>MEN_SYM</source>
+        <translation>Symétrie</translation>
+    </message>
+    <message>
+        <source>MEN_TAPER</source>
+        <translation>Cône</translation>
+    </message>
+    <message>
+        <source>MEN_TETRA</source>
+        <translation>Tétraèdre</translation>
+    </message>
+    <message>
+        <source>MEN_TOOLS</source>
+        <translation>Outils</translation>
+    </message>
+    <message>
+        <source>MEN_TRANS</source>
+        <translation>Translation</translation>
+    </message>
+    <message>
+        <source>MEN_SCALE</source>
+        <translation>Transformation d&apos;échelle</translation>
+    </message>
+    <message>
+        <source>MEN_DUPLICATE_NODES</source>
+        <translation>Dupliquer les nÅ“uds</translation>
+    </message>
+    <message>
+        <source>MEN_TRANSF</source>
+        <translation>Transformation</translation>
+    </message>
+    <message>
+        <source>MEN_TRANSP</source>
+        <translation>Transparence</translation>
+    </message>
+    <message>
+        <source>MEN_TRIANGLE</source>
+        <translation>Triangle</translation>
+    </message>
+    <message>
+        <source>MEN_UNASSIGN</source>
+        <translation>Désassocier</translation>
+    </message>
+    <message>
+        <source>MEN_UNION</source>
+        <translation>Union des triangles</translation>
+    </message>
+    <message>
+        <source>MEN_UNION2</source>
+        <translation>Union de deux triangles</translation>
+    </message>
+    <message>
+        <source>MEN_IMPORT_UNV</source>
+        <translation>Fichier UNV</translation>
+    </message>
+    <message>
+        <source>MEN_UNV</source>
+        <translation>Fichier UNV</translation>
+    </message>
+    <message>
+        <source>MEN_UN_GROUP</source>
+        <translation>Union des groupes</translation>
+    </message>
+    <message>
+        <source>MEN_UNDERLYING_ELEMS</source>
+        <translation>Groupe des entités sous-jacentes</translation>
+    </message>
+    <message>
+        <source>MEN_UPDATE</source>
+        <translation>Mettre Ã  jour</translation>
+    </message>
+    <message>
+        <source>MEN_VIEW</source>
+        <translation>Affichage</translation>
+    </message>
+    <message>
+        <source>MEN_VOLUMES</source>
+        <translation>Volumes</translation>
+    </message>
+    <message>
+        <source>MEN_VOLUME_3D</source>
+        <translation>Volume</translation>
+    </message>
+    <message>
+        <source>MEN_WARP</source>
+        <translation>Angle de déformation</translation>
+    </message>
+    <message>
+        <source>MEN_WHAT_IS</source>
+        <translation>Information sur un Ã©lément de maillage</translation>
+    </message>
+    <message>
+        <source>MEN_WIRE</source>
+        <translation>Contours</translation>
+    </message>
+    <message>
+        <source>MEN_SPLIT_TO_TETRA</source>
+        <translation>Explosion en tétraèdres</translation>
+    </message>
+    <message>
+        <source>TOP_SPLIT_TO_TETRA</source>
+        <translation>Eclater en tétraèdres</translation>
+    </message>
+    <message>
+        <source>STB_SPLIT_TO_TETRA</source>
+        <translation>Eclater en tétraèdres</translation>
+    </message>
+    <message>
+        <source>MESHERS_FILE_CANT_OPEN</source>
+        <translation>Impossible d&apos;ouvrir le fichier de ressource</translation>
+    </message>
+    <message>
+        <source>MESHERS_FILE_CHECK_VARIABLE</source>
+        <translation>Vérifier la variable d&apos;environnement SMESH_MeshersList</translation>
+    </message>
+    <message>
+        <source>MESHERS_FILE_NO_VARIABLE</source>
+        <translation>La variable d&apos;environnement  SMESH_MeshersList n&apos;est pas définie</translation>
+    </message>
+    <message>
+        <source>MESH_IS_NOT_SELECTED</source>
+        <translation>Il n&apos;y a pas de maillage sélectionné.
+Choisissez un maillage et essayez de nouveau</translation>
+    </message>
+    <message>
+        <source>MESH_NODE</source>
+        <translation>NÅ“ud</translation>
+    </message>
+    <message>
+        <source>MESH_NODE_TITLE</source>
+        <translation>Ajouter un nÅ“ud</translation>
+    </message>
+    <message>
+        <source>MINIMUMANGLE_ELEMENTS</source>
+        <translation>Angle minimal</translation>
+    </message>
+    <message>
+        <source>MULTI2D_BORDERS</source>
+        <translation>Frontières sur multi-connexions 2D</translation>
+    </message>
+    <message>
+        <source>MULTI_BORDERS</source>
+        <translation>Frontières sur multi-connexions</translation>
+    </message>
+    <message>
+        <source>GROUP_NAME_IS_EMPTY</source>
+        <translation>Le nom du groupe n&apos;est pas indiqué.
+Indiquez le nom d&apos;un nouveau groupe Ã  créer ou choisissez un groupe existant.</translation>
+    </message>
+    <message>
+        <source>MESH_STANDALONE_GRP_CHOSEN</source>
+        <translation>Un groupe lié Ã  la géométrie est choisi: %1.
+Voulez-vous le convertir en un groupe autonome ?</translation>
+    </message>
+    <message>
+        <source>NODE_ID</source>
+        <translation>ID du nÅ“ud</translation>
+    </message>
+    <message>
+        <source>NON_SMESH_OBJECTS_SELECTED</source>
+        <translation>Certains objets sélectionnés n&apos;appartiennent pas au composant %1.</translation>
+    </message>
+    <message>
+        <source>PREVIEW</source>
+        <translation>Prévisualiser</translation>
+    </message>
+    <message>
+        <source>SKEW_ELEMENTS</source>
+        <translation>Inclinaison d&apos;angle</translation>
+    </message>
+    <message>
+        <source>SMESHGUI_INVALID_PARAMETERS</source>
+        <translation>Les paramètres spécifiés ne sont pas corrects.
+Merci de les corriger, puis essayez de nouveau</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_ALGORITHM</source>
+        <translation>Algorithmes</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_ALGORITHM_TITLE</source>
+        <translation>Attribution des algorithmes</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_ELEM0D</source>
+        <translation>Ajouter un Ã©lément 0D</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_ELEM0D_TITLE</source>
+        <translation>Ajouter un Ã©lément 0D</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_BALL</source>
+        <translation>Ajouter un Ã©lément particulaire</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_BALL_TITLE</source>
+        <translation>Ajouter un Ã©lément particulaire</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_EDGE</source>
+        <translation>Ajouter une arête</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_EDGE_TITLE</source>
+        <translation>Ajouter une arête</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_HEXAS</source>
+        <translation>Ajouter un hexaèdre</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_HEXAS_TITLE</source>
+        <translation>Ajouter un hexaèdre</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_HYPOTHESIS</source>
+        <translation>Hypothèse</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_HYPOTHESIS_TITLE</source>
+        <translation>Attribution d&apos;une hypothèse</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_HYP_WRN</source>
+        <translation>&quot;%1&quot; est attribué, mais:
+        </translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_OCTA</source>
+        <translation>Ajouter un prisme hexagonale</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_OCTA_TITLE</source>
+        <translation>Ajouter un prisme hexagonale</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_POLYGON</source>
+        <translation>Ajouter un polygone</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_POLYGON_TITLE</source>
+        <translation>Ajouter un polygone</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_PENTA</source>
+        <translation>Ajouter un pentaèdre</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_PENTA_TITLE</source>
+        <translation>Ajouter un pentaèdre</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_PYRAMID</source>
+        <translation>Ajouter une pyramide</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_PYRAMID_TITLE</source>
+        <translation>Ajouter une pyramide</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRANGLE</source>
+        <translation>Ajouter un quadrangle</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRANGLE_TITLE</source>
+        <translation>Ajouter un quadrangle</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_EDGE_TITLE</source>
+        <translation>Ajouter une arête quadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_HEXAHEDRON_TITLE</source>
+        <translation>Ajouter un hexaèdre quadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_TRIQUADRATIC_HEXAHEDRON_TITLE</source>
+        <translation>Ajouter un hexaèdre triquadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_PENTAHEDRON_TITLE</source>
+        <translation>Ajouter un pentaèdre quadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_PYRAMID_TITLE</source>
+        <translation>Ajouter une pyramide quadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_BIQUADRATIC_QUADRANGLE_TITLE</source>
+        <translation>Ajouter un quadrangle biquadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_QUADRANGLE_TITLE</source>
+        <translation>Ajouter un quadrangle quadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_TETRAHEDRON_TITLE</source>
+        <translation>Ajouter un tétraèdre quadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_TRIANGLE_TITLE</source>
+        <translation>Ajouter un triangle quadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_SUBMESH</source>
+        <translation>Construction d&apos;un sous-maillage</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_TETRAS</source>
+        <translation>Ajouter un tétraèdre</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_TETRAS_TITLE</source>
+        <translation>Ajouter un tétraèdre</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_TO_GROUP</source>
+        <translation>Ajouter Ã  un groupe</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_TRIANGLE</source>
+        <translation>Ajouter un triangle</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_TRIANGLE_TITLE</source>
+        <translation>Ajouter un triangle</translation>
+    </message>
+    <message>
+        <source>SMESH_ANGLE</source>
+        <translation>Angle</translation>
+    </message>
+    <message>
+        <source>SMESH_ARGUMENTS</source>
+        <translation>Arguments</translation>
+    </message>
+    <message>
+        <source>SMESH_AUTO_GROUPS</source>
+        <translation>Créer les groupes automatiquement</translation>
+    </message>
+    <message>
+        <source>SMESH_AVAILABLE</source>
+        <translation>Disponible</translation>
+    </message>
+    <message>
+        <source>SMESH_AVAILABLE_ALGORITHMS</source>
+        <translation>Algorithmes disponibles</translation>
+    </message>
+    <message>
+        <source>SMESH_AVAILABLE_HYPOTHESES</source>
+        <translation>Hypothèses disponibles</translation>
+    </message>
+    <message>
+        <source>SMESH_AXIS</source>
+        <translation>Axe</translation>
+    </message>
+    <message>
+        <source>SMESH_BAD_SELECTION</source>
+        <translation>Pas de sélection valide</translation>
+    </message>
+    <message>
+        <source>SMESH_BAD_MESH_SELECTION</source>
+        <translation>La sélection du maillage n&apos;est pas valide</translation>
+    </message>
+    <message>
+        <source>SMESH_BOUNDARYEDGES</source>
+        <translation>Arêtes frontières</translation>
+    </message>
+    <message>
+        <source>SMESH_BUILD_COMPOUND_TITLE</source>
+        <translation>Créer un assemblage</translation>
+    </message>
+    <message>
+        <source>SMESH_COPY_MESH_TITLE</source>
+        <translation>Copier le maillage</translation>
+    </message>
+    <message>
+        <source>SMESH_KEEP_IDS</source>
+        <translation>Conserver les IDs des Ã©léments</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_ADD</source>
+        <translation>A&amp;jouter</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_APPLY</source>
+        <translation>A&amp;ppliquer</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_CANCEL</source>
+        <translation>A&amp;nnuler</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_CLOSE</source>
+        <translation>&amp;Fermer</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_CREATE</source>
+        <translation>&amp;Créer</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_DELETE</source>
+        <translation>Eff&amp;acer</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_FILTER</source>
+        <translation>Définir les fil&amp;tres</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_HELP</source>
+        <translation>Ai&amp;de</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_NEW</source>
+        <translation>Nou&amp;veau</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_NO</source>
+        <translation>&amp;Non</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_OK</source>
+        <translation>&amp;Ok</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_OVERWRITE</source>
+        <translation>Réécr&amp;ire</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_APPLY_AND_CLOSE</source>
+        <translation>App&amp;liquer et fermer</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_REMOVE</source>
+        <translation>S&amp;upprimer</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_SORT</source>
+        <translation>&amp;Trier la liste</translation>
+    </message>
+    <message>
+        <source>SMESH_BUT_YES</source>
+        <translation>&amp;Oui</translation>
+    </message>
+    <message>
+        <source>SMESH_CANT_ADD_HYP</source>
+        <translation>Impossible d&apos;attribuer &quot;%1&quot;:
+</translation>
+    </message>
+    <message>
+        <source>SMESH_CANT_RM_HYP</source>
+        <translation>Impossible de désassigner &quot;%1&quot;:
+</translation>
+    </message>
+    <message>
+        <source>SMESH_CHECK_COLOR</source>
+        <translation>Couleur</translation>
+    </message>
+    <message>
+        <source>SMESH_CLIPPING_FROM</source>
+        <translation>De &lt;---</translation>
+    </message>
+    <message>
+        <source>SMESH_CLIPPING_INTO</source>
+        <translation>---&gt; En</translation>
+    </message>
+    <message>
+        <source>SMESH_CLIPPING_TITLE</source>
+        <translation>Changer le plan de coupe</translation>
+    </message>
+    <message>
+        <source>SMESH_COMPUTE_SUCCEED</source>
+        <translation>Le calcul du maillage a réussi</translation>
+    </message>
+    <message>
+        <source>SMESH_EVALUATE_SUCCEED</source>
+        <translation>L&apos;évaluation du maillage a réussi</translation>
+    </message>
+    <message>
+        <source>SMESH_CONTENT</source>
+        <translation>Contenu</translation>
+    </message>
+    <message>
+        <source>SMESH_CONTINUE_MESH_VISUALIZATION</source>
+        <translation>La système semble manquer de mémoire pour visualiser le maillage,
+ce qui peut faire planter l&apos;application. Voulez-vous continuer la visualisation ?</translation>
+    </message>
+    <message>
+        <source>SMESH_COORDINATES</source>
+        <translation>Coordonnées</translation>
+    </message>
+    <message>
+        <source>SMESH_COPY_ELEMENTS</source>
+        <translation>Copier les Ã©léments</translation>
+    </message>
+    <message>
+        <source>SMESH_COPY_GROUPS</source>
+        <translation>Copier les groupes</translation>
+    </message>
+    <message>
+        <source>SMESH_CREATE_ALGORITHMS</source>
+        <translation>Créer les algorithmes</translation>
+    </message>
+    <message>
+        <source>SMESH_CREATE_COPY</source>
+        <translation>Créer une copie</translation>
+    </message>
+    <message>
+        <source>SMESH_CREATE_GROUP_TITLE</source>
+        <translation>Créer un groupe</translation>
+    </message>
+    <message>
+        <source>SMESH_CREATE_GEO_GROUP</source>
+        <translation>Créer des groupes liés Ã  la géométrie</translation>
+    </message>
+    <message>
+        <source>SMESH_CREATE_HYPOTHESES</source>
+        <translation>Créer une hypothèse</translation>
+    </message>
+    <message>
+        <source>SMESH_CREATE_MESH</source>
+        <translation>Créer un nouveau maillage</translation>
+    </message>
+    <message>
+        <source>SMESH_CREATE_POLYHEDRAL_VOLUME_TITLE</source>
+        <translation>Créer un volume polyèdrique</translation>
+    </message>
+    <message>
+        <source>SMESH_DIAGONAL</source>
+        <translation>Inversion de diagonale</translation>
+    </message>
+    <message>
+        <source>SMESH_DIAGONAL_INVERSION_TITLE</source>
+        <translation>Inversion de diagonale</translation>
+    </message>
+    <message>
+        <source>SMESH_DISTANCE</source>
+        <translation>Distance</translation>
+    </message>
+    <message>
+        <source>SMESH_DRS_1</source>
+        <translation>Le fichier MED contient pas de maillage avec ce nom</translation>
+    </message>
+    <message>
+        <source>SMESH_DRS_2</source>
+        <translation>Le fichier MED contient des rangées de nombre d&apos;éléments superposées, donc les nombres de ce fichier ne sont pas pris en compte</translation>
+    </message>
+    <message>
+        <source>SMESH_DRS_3</source>
+        <translation>Quelques Ã©léments ont Ã©té omis Ã  cause du fichier de données incorrect</translation>
+    </message>
+    <message>
+        <source>SMESH_DRS_4</source>
+        <translation>Le fichier n&apos;est pas correct, des données sont manquantes</translation>
+    </message>
+    <message>
+        <source>SMESH_DRS_EMPTY</source>
+        <translation>Le fichier est vide, il n&apos;y a rien Ã  publier</translation>
+    </message>
+    <message>
+        <source>SMESH_DX</source>
+        <translation>dX</translation>
+    </message>
+    <message>
+        <source>SMESH_DY</source>
+        <translation>dY</translation>
+    </message>
+    <message>
+        <source>SMESH_DZ</source>
+        <translation>dZ</translation>
+    </message>
+    <message>
+        <source>SMESH_ELEM0D</source>
+        <translation>Elément 0D</translation>
+    </message>
+    <message>
+        <source>SMESH_ELEMS0D</source>
+        <translation>Eléments 0D</translation>
+    </message>
+    <message>
+        <source>SMESH_BALL_ELEM</source>
+        <translation>Particulaire</translation>
+    </message>
+    <message>
+        <source>SMESH_BALL</source>
+        <translation>Particulaire</translation>
+    </message>
+    <message>
+        <source>SMESH_BALLS</source>
+        <translation>Particulaires</translation>
+    </message>
+    <message>
+        <source>SMESH_EDGE</source>
+        <translation>Arête</translation>
+    </message>
+    <message>
+        <source>SMESH_EDGES</source>
+        <translation>Arêtes</translation>
+    </message>
+    <message>
+        <source>SMESH_EDGES_CONNECTIVITY_TITLE</source>
+        <translation>Connectivité des arêtes</translation>
+    </message>
+    <message>
+        <source>SMESH_EDIT_GROUP_TITLE</source>
+        <translation>Editer un groupe</translation>
+    </message>
+    <message>
+        <source>SMESH_EDIT_GEOMGROUP_AS_GROUP_TITLE</source>
+        <translation>Editer un groupe en tant qu&apos;autonome</translation>
+    </message>
+    <message>
+        <source>SMESH_EDIT_HYPOTHESES</source>
+        <translation>Attribuer les hypothèses</translation>
+    </message>
+    <message>
+        <source>SMESH_EDIT_USED</source>
+        <translation>Utilisé</translation>
+    </message>
+    <message>
+        <source>SMESH_ELEMENTS</source>
+        <translation>Eléments</translation>
+    </message>
+    <message>
+        <source>SMESH_ELEMENTS_COLOR</source>
+        <translation>Couleur des Ã©léments du maillage</translation>
+    </message>
+    <message>
+        <source>SMESH_ELEMENTS_TYPE</source>
+        <translation>Type des Ã©léments</translation>
+    </message>
+    <message>
+        <source>SMESH_ELEMENT_TYPE</source>
+        <translation>Type de l&apos;élément</translation>
+    </message>
+    <message>
+        <source>SMESH_ERROR</source>
+        <translation>Erreur</translation>
+    </message>
+    <message>
+        <source>SMESH_ERR_SCALARBAR_PARAMS</source>
+        <translation>Avertissement! Les paramètres ne sont pas corrects</translation>
+    </message>
+    <message>
+        <source>SMESH_EXPORT_FAILED</source>
+        <translation>Impossible d&apos;exporter le maillage.
+Vérifiez l&apos;espace disponible sur le disque.</translation>
+    </message>
+    <message>
+        <source>SMESH_EXPORT_MED_DUPLICATED_GRP</source>
+        <translation>Il y a des noms de groupes dupliqués dans le maillage &quot;%1&quot;.
+Vous pouvez annuler l&apos;exportation et les renommer,
+si non des noms de groupes au fichier MED résultant
+ne correspondront pas aux noms de l&apos;étude.
+Voulez-vous continuer ?</translation>
+    </message>
+    <message>
+        <source>SMESH_EXPORT_MED_DUPLICATED_MESH_NAMES</source>
+        <translation>Il y a des maillages avec les mêmes noms dans la sélection.
+Il est possible que le fichier résultant soit incorrect.
+Voulez-vous continuer ?</translation>
+    </message>
+    <message>
+        <source>SMESH_EXPORT_MED_V2_1</source>
+        <translation>Les Ã©léments polygonaux et polyèdriques seront omis 
+dans le cas d&apos;exportation du maillage &quot;%1&quot; Ã  MED 2.1
+Utilisez MED 2.2 pour l&apos;exportation correcte.
+Voulez-vous effectuer l&apos;exportation Ã  MED 2.1 ?</translation>
+    </message>
+    <message>
+        <source>SMESH_EXPORT_MED_VERSION_COLLISION</source>
+        <translation>La version MED du fichier &quot;%1&quot; n&apos;est pas connue 
+ou ne correspond pas Ã  la version choisie.
+Réécrire le fichier ?</translation>
+    </message>
+    <message>
+        <source>SMESH_EXPORT_MED_MESH_NAMES_COLLISION</source>
+        <translation>Le fichier choisi contient déjà
+les maillages avec les noms suivants: %1
+Il est possible que le fichier résultant ne soit pas correct.
+Réécrire le fichier ?</translation>
+    </message>
+    <message>
+        <source>SMESH_EXPORT_STL1</source>
+        <translation>Le maillage  - &quot;%1&quot; ne contient pas de triangles</translation>
+    </message>
+    <message>
+        <source>SMESH_EXPORT_STL2</source>
+        <translation>Le maillage - &quot;%1&quot; contient d&apos;autres Ã©léments que les triangles, ils ne seront donc pas enregistrés dans le fichier STL</translation>
+    </message>
+    <message>
+        <source>SMESH_EXPORT_UNV</source>
+        <translation>Les Ã©léments pyramides seront omis au cours de l&apos;exportation 
+du maillage &quot;%1&quot; dans le fichier UNV</translation>
+    </message>
+    <message>
+        <source>EXPORT_NOT_SUPPORTED</source>
+        <translation>A l&apos;export du maillage avec le nom &quot;%1&quot; vers %2
+%3 sera ignoré.
+Voulez-vous continuer ?</translation>
+    </message>
+    <message>
+        <source>SMESH_EXTRUSION</source>
+        <translation>Extrusion</translation>
+    </message>
+    <message>
+        <source>SMESH_EXTRUSION_TO_DISTANCE</source>
+        <translation>Distance de l&apos;extrusion</translation>
+    </message>
+    <message>
+        <source>SMESH_EXTRUSION_ALONG_VECTOR</source>
+        <translation>Extrusion le long du vecteur</translation>
+    </message>
+    <message>
+        <source>SMESH_FACE</source>
+        <translation>Face</translation>
+    </message>
+    <message>
+        <source>SMESH_FEATUREANGLE</source>
+        <translation>Montrer l&apos;angle</translation>
+    </message>
+    <message>
+        <source>SMESH_FEATUREEDGES</source>
+        <translation>Montrer les arêtes</translation>
+    </message>
+    <message>
+        <source>SMESH_FILE_EXISTS</source>
+        <translation>Le fichier &quot;%1&quot; existe déjà.
+Voulez-vous le réécrire ou y ajouter 
+les données exportées ?</translation>
+    </message>
+    <message>
+        <source>SMESH_FONT_ARIAL</source>
+        <translation>Arial</translation>
+    </message>
+    <message>
+        <source>SMESH_FONT_BOLD</source>
+        <translation>Gras</translation>
+    </message>
+    <message>
+        <source>SMESH_FONT_COURIER</source>
+        <translation>Courrier</translation>
+    </message>
+    <message>
+        <source>SMESH_FONT_ITALIC</source>
+        <translation>Italique</translation>
+    </message>
+    <message>
+        <source>SMESH_FONT_SCALARBAR</source>
+        <translation>Police</translation>
+    </message>
+    <message>
+        <source>SMESH_FONT_SHADOW</source>
+        <translation>Ombrage</translation>
+    </message>
+    <message>
+        <source>SMESH_FONT_TIMES</source>
+        <translation>Times</translation>
+    </message>
+    <message>
+        <source>SMESH_GEOM_GROUP</source>
+        <translation>Groupe géométrique</translation>
+    </message>
+    <message>
+        <source>SMESH_GROUP</source>
+        <translation>Groupe</translation>
+    </message>
+    <message>
+        <source>SMESH_GROUP_GEOMETRY</source>
+        <translation>Groupe lié Ã  une géométrie</translation>
+    </message>
+    <message>
+        <source>SMESH_GROUP_FILTER</source>
+        <translation>Groupe lié Ã  un filtre</translation>
+    </message>
+    <message>
+        <source>SMESH_GROUP_SELECTED</source>
+        <translation>%1 groupes</translation>
+    </message>
+    <message>
+        <source>SMESH_GROUP_STANDALONE</source>
+        <translation>Groupe autonome</translation>
+    </message>
+    <message>
+        <source>SMESH_GROUP_TYPE</source>
+        <translation>Type du groupe</translation>
+    </message>
+    <message>
+        <source>SMESH_HEIGHT</source>
+        <translation>Hauteur :</translation>
+    </message>
+    <message>
+        <source>SMESH_HEXAS</source>
+        <translation>Hexaèdre</translation>
+    </message>
+    <message>
+        <source>SMESH_HEXAHEDRA</source>
+        <translation>Hexaèdres</translation>
+    </message>
+    <message>
+        <source>SMESH_HILIGHT_COLOR</source>
+        <translation>Couleur de sélection</translation>
+    </message>
+    <message>
+        <source>SMESH_HORIZONTAL</source>
+        <translation>Horizontale</translation>
+    </message>
+    <message>
+        <source>SMESH_HYPOTHESES</source>
+        <translation>Hypothèses</translation>
+    </message>
+    <message>
+        <source>SMESH_HYP_1</source>
+        <translation>Il manque une hypothèse Ã  l&apos;algorithme</translation>
+    </message>
+    <message>
+        <source>SMESH_HYP_10</source>
+        <translation>L&apos;hypothèse ne correspond pas aux dimensions du sous-maillage</translation>
+    </message>
+    <message>
+        <source>SMESH_HYP_11</source>
+        <translation>La géométrie n&apos;est ni la géométrie principale, ni un de ses sous-objets, ni un groupe valide</translation>
+    </message>
+    <message>
+        <source>SMESH_HYP_12</source>
+        <translation>La géométrie ne correspond pas Ã  l&apos;algorithme
+Référez-vous Ã  la documentation sur l&apos;algorithme et la géométrie supportée</translation>
+    </message>
+    <message>
+        <source>SMESH_HYP_13</source>
+        <translation>L&apos;algorithme ne peut pas opérer sans géométrie</translation>
+    </message>
+    <message>
+        <source>SMESH_HYP_2</source>
+        <translation>Il y a des hypothèses concurrentes sur la géométrie</translation>
+    </message>
+    <message>
+        <source>SMESH_HYP_3</source>
+        <translation>L&apos;hypothèse contient une valeur de paramètre incorrecte</translation>
+    </message>
+    <message>
+        <source>SMESH_HYP_4</source>
+        <translation>Le sous-maillage n&apos;est pas pris en compte parce qu&apos;il y a un algorithme de dimension supérieure pour générer les Ã©léments %1D</translation>
+    </message>
+    <message>
+        <source>SMESH_HYP_5</source>
+        <translation>L&apos;algorithme l&apos;emporte sur les algorithme(s) de dimensions inférieures en générant les Ã©léments de toutes les dimensions</translation>
+    </message>
+    <message>
+        <source>SMESH_HYP_6</source>
+        <translation>Erreur critique inconnue lors de la définition de l&apos;hypothèse</translation>
+    </message>
+    <message>
+        <source>SMESH_HYP_7</source>
+        <translation>L&apos;hypothèse ne correspond pas Ã  la situation actuelle</translation>
+    </message>
+    <message>
+        <source>SMESH_HYP_8</source>
+        <translation>Un maillage non-conforme a Ã©té produit avec les hypothèses appliquées</translation>
+    </message>
+    <message>
+        <source>SMESH_HYP_9</source>
+        <translation>L&apos;hypothèse d&apos;une telle dimension est déjà attribuée Ã  la géométrie</translation>
+    </message>
+    <message>
+        <source>SMESH_ID_DIAGONAL</source>
+        <translation>IDs des arêtes</translation>
+    </message>
+    <message>
+        <source>SMESH_ID_ELEMENTS</source>
+        <translation>IDs des Ã©léments</translation>
+    </message>
+    <message>
+        <source>SMESH_ID_FACES</source>
+        <translation>IDs des faces</translation>
+    </message>
+    <message>
+        <source>SMESH_ID_NODES</source>
+        <translation>IDs des nÅ“uds</translation>
+    </message>
+    <message>
+        <source>SMESH_INCORRECT_INPUT</source>
+        <translation>Les données d&apos;entrée ne sont pas correctes</translation>
+    </message>
+    <message>
+        <source>SMESH_INFORMATION</source>
+        <translation>Information</translation>
+    </message>
+    <message>
+        <source>SMESH_INIT</source>
+        <translation>Maillage</translation>
+    </message>
+    <message>
+        <source>SMESH_INIT_MESH</source>
+        <translation>Construction du maillage </translation>
+    </message>
+    <message>
+        <source>SMESH_INSUFFICIENT_DATA</source>
+        <translation>La valeur d&apos;entrée n&apos;est pas suffisante</translation>
+    </message>
+    <message>
+        <source>SMESH_LABELS</source>
+        <translation>Etiquettes :</translation>
+    </message>
+    <message>
+        <source>SMESH_LABELS_COLORS_SCALARBAR</source>
+        <translation>Couleurs &amp;&amp; Ã©tiquettes</translation>
+    </message>
+    <message>
+        <source>SMESH_LENGTH</source>
+        <translation>Longueur</translation>
+    </message>
+    <message>
+        <source>SMESH_MAKE_GROUPS</source>
+        <translation>Générer les groupes</translation>
+    </message>
+    <message>
+        <source>SMESH_MANIFOLDEDGES</source>
+        <translation>Arêtes partagées</translation>
+    </message>
+    <message>
+        <source>SMESH_MAX</source>
+        <translation>Max</translation>
+    </message>
+    <message>
+        <source>SMESH_MEN_ALGORITHMS</source>
+        <translation>Algorithmes</translation>
+    </message>
+    <message>
+        <source>SMESH_MEN_APPLIED_ALGORIHTMS</source>
+        <translation>Algorithmes appliqués</translation>
+    </message>
+    <message>
+        <source>SMESH_MEN_APPLIED_HYPOTHESIS</source>
+        <translation>Hypothèses appliquées</translation>
+    </message>
+    <message>
+        <source>SMESH_MEN_COMPONENT</source>
+        <translation>SMESH</translation>
+    </message>
+    <message>
+        <source>SMESH_MEN_HYPOTHESIS</source>
+        <translation>Hypothèses</translation>
+    </message>
+    <message>
+        <source>SMESH_MEN_SubMeshesOnCompound</source>
+        <translation>Sous-maillages sur un assemblage</translation>
+    </message>
+    <message>
+        <source>SMESH_MEN_SubMeshesOnEdge</source>
+        <translation>Sous-maillages sur une arête</translation>
+    </message>
+    <message>
+        <source>SMESH_MEN_SubMeshesOnFace</source>
+        <translation>Sous-maillages sur une face</translation>
+    </message>
+    <message>
+        <source>SMESH_MEN_SubMeshesOnSolid</source>
+        <translation>Sous-maillages sur un solide</translation>
+    </message>
+    <message>
+        <source>SMESH_MEN_SubMeshesOnVertex</source>
+        <translation>Sous-maillages sur un point</translation>
+    </message>
+    <message>
+        <source>SMESH_AUTOMATIC</source>
+        <translation>Automatique</translation>
+    </message>
+    <message>
+        <source>SMESH_MANUAL</source>
+        <translation>Manuel</translation>
+    </message>
+    <message>
+        <source>SMESH_MERGE_ELEMENTS</source>
+        <translation>Fusionner les Ã©léments</translation>
+    </message>
+    <message>
+        <source>SMESH_MODE</source>
+        <translation>Mode</translation>
+    </message>
+    <message>
+        <source>SMESH_MERGED_ELEMENTS</source>
+        <translation>%1 Ã©léments fusionnés avec succès</translation>
+    </message>
+    <message>
+        <source>SMESH_MERGED_NODES</source>
+        <translation>%1 nÅ“uds fusionnés avec succès</translation>
+    </message>
+    <message>
+        <source>SMESH_NO_ELEMENTS_DETECTED</source>
+        <translation>Il n&apos;y a aucun Ã©lément Ã  fusionner.</translation>
+    </message>
+    <message>
+        <source>SMESH_NO_NODES_DETECTED</source>
+        <translation>Il n&apos;y a aucun nÅ“ud Ã  fusionner</translation>
+    </message>
+    <message>
+        <source>SMESH_MERGE_NODES</source>
+        <translation>Fusionner les nÅ“uds</translation>
+    </message>
+    <message>
+        <source>SMESH_MESH</source>
+        <translation>Maillage</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_0DELEMS</source>
+        <translation>Eléments 0D</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_BALLS</source>
+        <translation>Particulaires</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_ALL_TYPES</source>
+        <translation>Hétérogène</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_EDGES</source>
+        <translation>Arêtes</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_ELEMENTS</source>
+        <translation>Eléments</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_ENTITIES</source>
+        <translation>Entités</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_FACES</source>
+        <translation>Faces</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_HEXAS</source>
+        <translation>Hexaèdres</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_NAME</source>
+        <translation>Nom</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_NODES</source>
+        <translation>NÅ“uds</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_ORDER0</source>
+        <translation>Total</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_ORDER1</source>
+        <translation>Linéaire</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_ORDER2</source>
+        <translation>Quadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_HEXAPRISM</source>
+        <translation>Prismes hexagonaux</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_POLYEDRES</source>
+        <translation>Polyèdres</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_POLYGONES</source>
+        <translation>Polygones</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_PRISMS</source>
+        <translation>Prismes</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_PYRAS</source>
+        <translation>Pyramides</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_QUADRANGLES</source>
+        <translation>Quadrangles</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_TETRAS</source>
+        <translation>Tétraèdres</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_TITLE</source>
+        <translation>Informations sur le maillage</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_TOTAL</source>
+        <translation>Total</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_TRIANGLES</source>
+        <translation>Triangles</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_TYPE</source>
+        <translation>Type</translation>
+    </message>
+    <message>
+        <source>SMESH_MESHINFO_VOLUMES</source>
+        <translation>Volumes</translation>
+    </message>
+    <message>
+        <source>SMESH_MIN</source>
+        <translation>Min</translation>
+    </message>
+    <message>
+        <source>SMESH_MOVE</source>
+        <translation>Déplacer</translation>
+    </message>
+    <message>
+        <source>SMESH_MOVE_ELEMENTS</source>
+        <translation>Déplacer les Ã©léments</translation>
+    </message>
+    <message>
+        <source>SMESH_MOVE_NODES_TITLE</source>
+        <translation>Déplacer un nÅ“ud</translation>
+    </message>
+    <message>
+        <source>SMESH_NAME</source>
+        <translation>Nom</translation>
+    </message>
+    <message>
+        <source>SMESH_NODES</source>
+        <translation>NÅ“uds</translation>
+    </message>
+    <message>
+        <source>SMESH_NONMANIFOLDEDGES</source>
+        <translation>Arêtes non-partagées</translation>
+    </message>
+    <message>
+        <source>SMESH_NORMAL</source>
+        <translation>Normal</translation>
+    </message>
+    <message>
+        <source>SMESH_NO_MESH_VISUALIZATION</source>
+        <translation>Il n&apos;y a pas assez de mémoire pour visualiser le maillage</translation>
+    </message>
+    <message>
+        <source>SMESH_NUMBEROFCOLORS</source>
+        <translation>Nombre de couleurs :</translation>
+    </message>
+    <message>
+        <source>SMESH_NUMBEROFLABELS</source>
+        <translation>Nombre d&apos;étiquettes :</translation>
+    </message>
+    <message>
+        <source>SMESH_NUMBEROFSTEPS</source>
+        <translation>Nombre de pas :</translation>
+    </message>
+    <message>
+        <source>SMESH_OBJECTS_SELECTED</source>
+        <translation>%1_objets</translation>
+    </message>
+    <message>
+        <source>SMESH_OBJECT_ALGORITHM</source>
+        <translation>Algorithme</translation>
+    </message>
+    <message>
+        <source>SMESH_OBJECT_GEOM</source>
+        <translation>Objet géométrique</translation>
+    </message>
+    <message>
+        <source>SMESH_OBJECT_HYPOTHESIS</source>
+        <translation>Hypothèse</translation>
+    </message>
+    <message>
+        <source>SMESH_OBJECT_MESH</source>
+        <translation>Maillage</translation>
+    </message>
+    <message>
+        <source>SMESH_OBJECT_MESHorSUBMESH</source>
+        <translation>Maillage ou sous-maillage</translation>
+    </message>
+    <message>
+        <source>SMESH_OPERATION_FAILED</source>
+        <translation>L&apos;opération n&apos;a pas abouti</translation>
+    </message>
+    <message>
+        <source>SMESH_OCTA</source>
+        <translation>Prisme Octogonal</translation>
+    </message>
+    <message>
+        <source>SMESH_OCTAHEDRA</source>
+        <translation>Prismes octogonaux</translation>
+    </message>
+    <message>
+        <source>TOP_OCTA</source>
+        <translation>Prisme hexagonal</translation>
+    </message>
+    <message>
+        <source>MEN_OCTA</source>
+        <translation>Prisme hexagonal</translation>
+    </message>
+    <message>
+        <source>STB_OCTA</source>
+        <translation>Prisme hexagonal</translation>
+    </message>
+    <message>
+        <source>SMESH_ORIENTATION</source>
+        <translation>Orientation</translation>
+    </message>
+    <message>
+        <source>SMESH_ORIENTATION_ELEMENTS_TITLE</source>
+        <translation>Changer l&apos;orientation</translation>
+    </message>
+    <message>
+        <source>SMESH_OUTLINE_COLOR</source>
+        <translation>Couleur de l&apos;objet maillage</translation>
+    </message>
+    <message>
+        <source>SMESH_PARAMETERS</source>
+        <translation>Paramètres</translation>
+    </message>
+    <message>
+        <source>SMESH_PENTA</source>
+        <translation>Pentaèdre</translation>
+    </message>
+    <message>
+        <source>SMESH_PENTAHEDRA</source>
+        <translation>Pentaèdres</translation>
+    </message>
+    <message>
+        <source>TOP_PENTA</source>
+        <translation>Pentaèdre</translation>
+    </message>
+    <message>
+        <source>MEN_PENTA</source>
+        <translation>Pentaèdre</translation>
+    </message>
+    <message>
+        <source>STB_PENTA</source>
+        <translation>Pentaèdre</translation>
+    </message>
+    <message>
+        <source>SMESH_PLANE</source>
+        <translation>Plan</translation>
+    </message>
+    <message>
+        <source>SMESH_POINT</source>
+        <translation>Point</translation>
+    </message>
+    <message>
+        <source>SMESH_POINT_1</source>
+        <translation>Point 1</translation>
+    </message>
+    <message>
+        <source>SMESH_POINT_2</source>
+        <translation>Point 2</translation>
+    </message>
+    <message>
+        <source>SMESH_BASE_POINT</source>
+        <translation>Point de base</translation>
+    </message>
+    <message>
+        <source>SMESH_POLYEDRE_CREATE_ERROR</source>
+        <translation>Erreur de création du polyèdre</translation>
+    </message>
+    <message>
+        <source>SMESH_POLYEDRON</source>
+        <translation>Polyèdre</translation>
+    </message>
+    <message>
+        <source>SMESH_POLYEDRONS</source>
+        <translation>Polyèdres</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_POLYEDRON</source>
+        <translation>Polyèdre quadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_POLYEDRONS</source>
+        <translation>Polyèdres quadratiques</translation>
+    </message>
+    <message>
+        <source>SMESH_POLYGON</source>
+        <translation>Polygone</translation>
+    </message>
+    <message>
+        <source>SMESH_POLYGONS</source>
+        <translation>Polygones</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_POLYGON</source>
+        <translation>Polygone quadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_POLYGONS</source>
+        <translation>Polygones quadratiques</translation>
+    </message>
+    <message>
+        <source>SMESH_POSITION_SIZE_SCALARBAR</source>
+        <translation>Origine &amp;&amp; Taille</translation>
+    </message>
+    <message>
+        <source>SMESH_DISTRIBUTION_SCALARBAR</source>
+        <translation>Distribution</translation>
+    </message>
+    <message>
+        <source>SMESH_SHOW_DISTRIBUTION_SCALARBAR</source>
+        <translation>Afficher la distribution</translation>
+    </message>
+    <message>
+        <source>SMESH_PRECISION</source>
+        <translation>Précision</translation>
+    </message>
+    <message>
+        <source>SMESH_PREFERENCES_SCALARBAR</source>
+        <translation>Préférences de la barre d&apos;échelle</translation>
+    </message>
+    <message>
+        <source>SMESH_PREF_SELECTION</source>
+        <translation>Préférences - Sélection</translation>
+    </message>
+    <message>
+        <source>SMESH_PRESELECTION</source>
+        <translation>Présélection</translation>
+    </message>
+    <message>
+        <source>SMESH_PRISM</source>
+        <translation>Prisme</translation>
+    </message>
+    <message>
+        <source>SMESH_PROPERTIES_SCALARBAR</source>
+        <translation>Propriétés de la barre d&apos;échelle</translation>
+    </message>
+    <message>
+        <source>SMESH_PYRAMID</source>
+        <translation>Pyramide</translation>
+    </message>
+    <message>
+        <source>SMESH_PYRAMIDS</source>
+        <translation>Pyramides</translation>
+    </message>
+    <message>
+        <source>MEN_PYRAMID</source>
+        <translation>Pyramide</translation>
+    </message>
+    <message>
+        <source>TOP_PYRAMID</source>
+        <translation>Pyramide</translation>
+    </message>
+    <message>
+        <source>STB_PYRAMID</source>
+        <translation>Pyramide</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRANGLE</source>
+        <translation>Quadrangle</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRANGLES</source>
+        <translation>Quadrangles</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_EDGE</source>
+        <translation>Arête quadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_EDGES</source>
+        <translation>Arêtes quadratiques</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_HEXAHEDRON</source>
+        <translation>Hexaèdre quadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_HEXAHEDRONS</source>
+        <translation>Hexaèdres quadratiques</translation>
+    </message>
+    <message>
+        <source>SMESH_TRIQUADRATIC_HEXAHEDRON</source>
+        <translation>Hexaèdre triquadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_TRIQUADRATIC_HEXAHEDRONS</source>
+        <translation>Hexaèdres triquadratiques</translation>
+    </message>
+    <message>
+        <source>TOP_TRIQUADRATIC_HEXAHEDRON</source>
+        <translation>Hexaèdre triquadratique</translation>
+    </message>
+    <message>
+        <source>MEN_TRIQUADRATIC_HEXAHEDRON</source>
+        <translation>Hexaèdre triquadratique</translation>
+    </message>
+    <message>
+        <source>STB_TRIQUADRATIC_HEXAHEDRON</source>
+        <translation>Hexaèdre triquadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_PENTAHEDRON</source>
+        <translation>Pentaèdre quadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_PENTAHEDRONS</source>
+        <translation>Pentaèdres quadratiques</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_PYRAMID</source>
+        <translation>Pyramide quadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_PYRAMIDS</source>
+        <translation>Pyramides quadratiques</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_QUADRANGLE</source>
+        <translation>Quadrangle quadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_QUADRANGLES</source>
+        <translation>Quadrangles quadratiques</translation>
+    </message>
+    <message>
+        <source>SMESH_BIQUADRATIC_QUADRANGLE</source>
+        <translation>Quadrangle biquadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_BIQUADRATIC_QUADRANGLES</source>
+        <translation>Quadrangles biquadratiques</translation>
+    </message>
+    <message>
+        <source>MEN_BIQUADRATIC_QUADRANGLE</source>
+        <translation>Quadrangle biquadratique</translation>
+    </message>
+    <message>
+        <source>TOP_BIQUADRATIC_QUADRANGLE</source>
+        <translation>Quadrangle biquadratique</translation>
+    </message>
+    <message>
+        <source>STB_BIQUADRATIC_QUADRANGLE</source>
+        <translation>Quadrangle biquadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_TETRAHEDRON</source>
+        <translation>Tétraèdre quadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_TETRAHEDRONS</source>
+        <translation>Tétraèdres quadratiques</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_TRIANGLE</source>
+        <translation>Triangle quadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRATIC_TRIANGLES</source>
+        <translation>Triangles quadratiques</translation>
+    </message>
+    <message>
+        <source>SMESH_RANGE_MAX</source>
+        <translation>Valeur maximale :</translation>
+    </message>
+    <message>
+        <source>SMESH_RANGE_MIN</source>
+        <translation>Valeur minimale :</translation>
+    </message>
+    <message>
+        <source>SMESH_RANGE_SCALARBAR</source>
+        <translation>Echelle de valeurs</translation>
+    </message>
+    <message>
+        <source>SMESH_REALLY_DELETE</source>
+        <translation>Voulez-vous vraiment supprimer ces  %1 objets? : %2</translation>
+    </message>
+    <message>
+        <source>SMESH_REMOVE</source>
+        <translation>Supprimer</translation>
+    </message>
+    <message>
+        <source>SMESH_REMOVE_ELEMENTS_TITLE</source>
+        <translation>Supprimer les Ã©léments</translation>
+    </message>
+    <message>
+        <source>SMESH_REMOVE_NODES_TITLE</source>
+        <translation>Supprimer les nÅ“uds</translation>
+    </message>
+    <message>
+        <source>SMESH_RENUMBERING</source>
+        <translation>Renuméroter</translation>
+    </message>
+    <message>
+        <source>SMESH_RENUMBERING_ELEMENTS_TITLE</source>
+        <translation>Renuméroter les Ã©léments</translation>
+    </message>
+    <message>
+        <source>SMESH_RENUMBERING_NODES_TITLE</source>
+        <translation>Renuméroter les nÅ“uds</translation>
+    </message>
+    <message>
+        <source>SMESH_REVERSE</source>
+        <translation>Inverser</translation>
+    </message>
+    <message>
+        <source>SMESH_REVOLUTION</source>
+        <translation>Révolution</translation>
+    </message>
+    <message>
+        <source>SMESH_RM_HYP_WRN</source>
+        <translation>&quot;%1&quot; n&apos;est pas attribué, mais:
+</translation>
+    </message>
+    <message>
+        <source>SMESH_ROTATION</source>
+        <translation>Rotation</translation>
+    </message>
+    <message>
+        <source>SMESH_ROTATION_TITLE</source>
+        <translation>Rotation autour d&apos;un axe</translation>
+    </message>
+    <message>
+        <source>SMESH_SCALARBAR</source>
+        <translation>Barre d&apos;échelle</translation>
+    </message>
+    <message>
+        <source>SMESH_SEGMENTS</source>
+        <translation>Segments</translation>
+    </message>
+    <message>
+        <source>SMESH_SELECTION</source>
+        <translation>Sélection</translation>
+    </message>
+    <message>
+        <source>SMESH_SELECT_FROM</source>
+        <translation>Sélectionner Ã  partir de</translation>
+    </message>
+    <message>
+        <source>SMESH_SELECT_WHOLE_MESH</source>
+        <translation>Choisir un maillage entier, un sous-maillage ou un groupe</translation>
+    </message>
+    <message>
+        <source>SMESH_SET_COLOR</source>
+        <translation>Groupe de couleur</translation>
+    </message>
+    <message>
+        <source>SMESH_SEWING</source>
+        <translation>Couture</translation>
+    </message>
+    <message>
+        <source>SMESH_SMOOTHING</source>
+        <translation>Lissage</translation>
+    </message>
+    <message>
+        <source>SMESH_STANDARD_MESHINFO_TITLE</source>
+        <translation>Information de maillage</translation>
+    </message>
+    <message>
+        <source>SMESH_SUBMESH</source>
+        <translation>Sous-maillage</translation>
+    </message>
+    <message>
+        <source>SMESH_SUBMESH_SELECTED</source>
+        <translation>%1 sous-maillages</translation>
+    </message>
+    <message>
+        <source>SMESH_SYMMETRY</source>
+        <translation>Symétrie</translation>
+    </message>
+    <message>
+        <source>SMESH_TETRAS</source>
+        <translation>Tétraèdre</translation>
+    </message>
+    <message>
+        <source>SMESH_TETRAHEDRA</source>
+        <translation>Tétraèdres</translation>
+    </message>
+    <message>
+        <source>SMESH_TITLE</source>
+        <translation>Titre :</translation>
+    </message>
+    <message>
+        <source>SMESH_TOLERANCE</source>
+        <translation>Tolérance</translation>
+    </message>
+    <message>
+        <source>SMESH_TRANSLATION</source>
+        <translation>Translation</translation>
+    </message>
+    <message>
+        <source>SMESH_SCALE_TITLE</source>
+        <translation>Transformation d&apos;échelle</translation>
+    </message>
+    <message>
+        <source>SMESH_DUPLICATE_TITLE</source>
+        <translation>Dupliquer les nÅ“uds</translation>
+    </message>
+    <message>
+        <source>SMESH_SCALE</source>
+        <translation>Echelle</translation>
+    </message>
+    <message>
+        <source>SMESH_SCALE_FACTOR</source>
+        <translation>Facteur d&apos;échelle :</translation>
+    </message>
+    <message>
+        <source>SMESH_SCALE_FACTOR_X</source>
+        <translation>Facteur d&apos;échelle X :</translation>
+    </message>
+    <message>
+        <source>SMESH_SCALE_FACTOR_Y</source>
+        <translation>Facteur d&apos;échelle Y :</translation>
+    </message>
+    <message>
+        <source>SMESH_SCALE_FACTOR_Z</source>
+        <translation>Facteur d&apos;échelle Z :</translation>
+    </message>
+    <message>
+        <source>SMESH_TRANSPARENCY_OPAQUE</source>
+        <translation>Opaque</translation>
+    </message>
+    <message>
+        <source>SMESH_TRANSPARENCY_TITLE</source>
+        <translation>Changer la transparence</translation>
+    </message>
+    <message>
+        <source>SMESH_TRANSPARENCY_TRANSPARENT</source>
+        <translation>Transparent</translation>
+    </message>
+    <message>
+        <source>SMESH_TRIANGLE</source>
+        <translation>Triangle</translation>
+    </message>
+    <message>
+        <source>SMESH_TRIANGLES</source>
+        <translation>Triangles</translation>
+    </message>
+    <message>
+        <source>SMESH_UPDATEVIEW</source>
+        <translation>Mettre Ã  jour la vue</translation>
+    </message>
+    <message>
+        <source>SMESH_VALUE</source>
+        <translation>Valeur</translation>
+    </message>
+    <message>
+        <source>SMESH_VECTOR</source>
+        <translation>Vecteur</translation>
+    </message>
+    <message>
+        <source>SMESH_VERTICAL</source>
+        <translation>Verticale</translation>
+    </message>
+    <message>
+        <source>SMESH_DISTRIBUTION_COLORING_TYPE</source>
+        <translation>Type de coloration</translation>
+    </message>
+    <message>
+        <source>SMESH_MONOCOLOR</source>
+        <translation>Monocouleur</translation>
+    </message>
+    <message>
+        <source>SMESH_DISTRIBUTION_COLOR</source>
+        <translation>Couleur de la distribution:</translation>
+    </message>
+    <message>
+        <source>SMESH_MULTICOLOR</source>
+        <translation>Multicouleur</translation>
+    </message>
+    <message>
+        <source>SMESH_VISU_PROBLEM</source>
+        <translation>Impossible de visualiser le maillage, probablement Ã  cause d&apos;un manque de mémoire</translation>
+    </message>
+    <message>
+        <source>SMESH_VISU_PROBLEM_CLEAR</source>
+        <translation>Impossible de visualiser le maillage, pas assez de la mémoire pour montrer le message,
+donc toutes les données visuelles ont Ã©té supprimées pour ne pas planter l&apos;application.
+Enregistrez votre travail avant que l&apos;application se plante</translation>
+    </message>
+    <message>
+        <source>SMESH_VOLUME</source>
+        <translation>Volume</translation>
+    </message>
+    <message>
+        <source>SMESH_WARNING</source>
+        <translation>Avertissement</translation>
+    </message>
+    <message>
+        <source>SMESH_WHAT_IS_TITLE</source>
+        <translation>Information sur un Ã©lément de maillage</translation>
+    </message>
+    <message>
+        <source>SMESH_WIDTH</source>
+        <translation>Largeur :</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_ALGORITHM_ALREADYEXIST</source>
+        <translation>L&apos;algorithme existe déjà</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_COMPUTE_FAILED</source>
+        <translation>Impossible de calculer le maillage</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_EVALUATE_FAILED</source>
+        <translation>Impossible d&apos;évaluer le maillage</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_EMPTY_NAME</source>
+        <translation>Un nom vide n&apos;est pas valide</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_HYPOTHESIS_ALREADYEXIST</source>
+        <translation>L&apos;hypothèse existe déjà</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_HYPOTHESIS_NOTEXIST</source>
+        <translation>L&apos;hypothèse ou l&apos;algorithme n&apos;existent pas</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_MISSING_PARAMETERS</source>
+        <translation>Paramètres manquants</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_NO_AVAILABLE_DATA</source>
+        <translation>Pas de données disponibles dans la sélection</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_SELECTIONMODE_DIAGONAL</source>
+        <translation>Activer le mode de sélection des références</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_SELECTIONMODE_ELEMENTS</source>
+        <translation>Activer le mode de sélection des Ã©léments</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_SELECTIONMODE_NODES</source>
+        <translation>Activer le mode de sélection des nÅ“uds</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_VIEWER_VTK</source>
+        <translation>Il faut ouvrir la scène dans le visualisateur VTK</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_SIZE_LIMIT_EXCEEDED</source>
+        <translation>La présentation n&apos;a pas Ã©té mise Ã  jour automatiquement: la nouvelle taille du maillage (%1 Ã©léments) dépasse la limite de taille actuelle (%2 Ã©léments).
+Vérifiez la limite dans les préférences du module Mesh.
+</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_WARNING</source>
+        <translation>Avertissement</translation>
+    </message>
+    <message>
+        <source>SMESH_X</source>
+        <translation>X</translation>
+    </message>
+    <message>
+        <source>SMESH_X_SCALARBAR</source>
+        <translation>X :</translation>
+    </message>
+    <message>
+        <source>SMESH_Y</source>
+        <translation>Y</translation>
+    </message>
+    <message>
+        <source>SMESH_Y_SCALARBAR</source>
+        <translation>Y :</translation>
+    </message>
+    <message>
+        <source>SMESH_Z</source>
+        <translation>Z</translation>
+    </message>
+    <message>
+        <source>STATE_ALGO_MISSING</source>
+        <translation>Il manque l&apos;algorithme %3 %2D</translation>
+    </message>
+    <message>
+        <source>STATE_HYP_BAD_GEOMETRY</source>
+        <translation>L&apos;algorithme %3 %2D  &quot;%1&quot; est attribué Ã  une géométrie qui ne convient pas</translation>
+    </message>
+    <message>
+        <source>STATE_HYP_BAD_PARAMETER</source>
+        <translation>Il y a un paramètre incorrect dans l&apos;hypothèse %3 %2D de l&apos;algorithme &quot;%1&quot; </translation>
+    </message>
+    <message>
+        <source>STATE_HYP_MISSING</source>
+        <translation>L&apos;hypothèse %4D manque Ã  l&apos;algorithme %3 %2D &quot;%1&quot;</translation>
+    </message>
+    <message>
+        <source>STATE_HYP_NOTCONFORM</source>
+        <translation>L&apos;algorithme %3 %2D &quot;%1&quot; produit un maillage non-conforme: l&apos;hypothèse globale &quot;Maillage non conforme autorisé&quot; doit Ãªtre cochée</translation>
+    </message>
+    <message>
+        <source>STB_ADV_INFO</source>
+        <translation>Monter l&apos;information de base sur le maillage</translation>
+    </message>
+    <message>
+        <source>STB_ALL</source>
+        <translation>Tous</translation>
+    </message>
+    <message>
+        <source>STB_AREA</source>
+        <translation>Aire</translation>
+    </message>
+    <message>
+        <source>STB_ASPECT</source>
+        <translation>Rapport de forme</translation>
+    </message>
+    <message>
+        <source>STB_ASPECT_3D</source>
+        <translation>Rapport de forme 3D</translation>
+    </message>
+    <message>
+        <source>STB_AUTO_COLOR</source>
+        <translation>Couleur automatique</translation>
+    </message>
+    <message>
+        <source>STB_AUTO_UPD</source>
+        <translation>Mise Ã  jour automatique</translation>
+    </message>
+    <message>
+        <source>STB_BUILD_COMPOUND</source>
+        <translation>Construire un maillage assemblé</translation>
+    </message>
+    <message>
+        <source>STB_COPY_MESH</source>
+        <translation>Copie le maillage</translation>
+    </message>
+    <message>
+        <source>STB_CLIP</source>
+        <translation>Pan de coupe</translation>
+    </message>
+    <message>
+        <source>STB_COLORS</source>
+        <translation>Paramètres d&apos;affichage</translation>
+    </message>
+    <message>
+        <source>STB_COMPUTE</source>
+        <translation>Calculer</translation>
+    </message>
+    <message>
+        <source>STB_PRECOMPUTE</source>
+        <translation>Prévisualiser</translation>
+    </message>
+    <message>
+        <source>STB_EVALUATE</source>
+        <translation>Evaluer</translation>
+    </message>
+    <message>
+        <source>STB_CONNECTION</source>
+        <translation>Frontières sur connexion multiples</translation>
+    </message>
+    <message>
+        <source>STB_CONNECTION_2D</source>
+        <translation>Frontières sur connexion multiples 2D</translation>
+    </message>
+    <message>
+        <source>STB_CONSTRUCT_GROUP</source>
+        <translation>Construire un groupe</translation>
+    </message>
+    <message>
+        <source>STB_CONV_TO_QUAD</source>
+        <translation>Convertir vers/de quadratique</translation>
+    </message>
+    <message>
+        <source>STB_2D_FROM_3D</source>
+        <translation>Créer les Ã©léments de frontière</translation>
+    </message>
+    <message>
+        <source>STB_MESH_ORDER</source>
+        <translation>Changer la priorité des sous-maillages</translation>
+    </message>
+    <message>
+        <source>STB_CREATE_GROUP</source>
+        <translation>Créer un groupe</translation>
+    </message>
+    <message>
+        <source>STB_CREATE_GEO_GROUP</source>
+        <translation>Créer des groupes Ã  partir de la géométrie</translation>
+    </message>
+    <message>
+        <source>STB_CREATE_MESH</source>
+        <translation>Créer un maillage</translation>
+    </message>
+    <message>
+        <source>STB_CREATE_SUBMESH</source>
+        <translation>Créer un sous-maillage</translation>
+    </message>
+    <message>
+        <source>STB_CUT</source>
+        <translation>Découpe des quadrangles</translation>
+    </message>
+    <message>
+        <source>STB_CUT_GROUP</source>
+        <translation>Découper les groupes</translation>
+    </message>
+    <message>
+        <source>STB_IMPORT_DAT</source>
+        <translation>Importer un fichier DAT</translation>
+    </message>
+    <message>
+        <source>STB_DAT</source>
+        <translation>Exporter un fichier DAT</translation>
+    </message>
+    <message>
+        <source>STB_DELETE</source>
+        <translation>Supprimer</translation>
+    </message>
+    <message>
+        <source>STB_DEL_GROUP</source>
+        <translation>Supprimer les groupes et leur contenu</translation>
+    </message>
+    <message>
+        <source>STB_FACE_ORIENTATION</source>
+        <translation>Orientation des faces</translation>
+    </message>
+    <message>
+        <source>STB_DISABLE_AUTO_COLOR</source>
+        <translation>Désactiver la couleur automatique</translation>
+    </message>
+    <message>
+        <source>STB_DISPLAY_ONLY</source>
+        <translation>Afficher uniquement</translation>
+    </message>
+    <message>
+        <source>STB_DISP_ENT</source>
+        <translation>Visualiser une entité</translation>
+    </message>
+    <message>
+        <source>STB_ELEM0D</source>
+        <translation>Elément 0D</translation>
+    </message>
+    <message>
+        <source>STB_ELEMS0D</source>
+        <translation>Eléments 0D</translation>
+    </message>
+    <message>
+        <source>STB_BALLS</source>
+        <translation>Eléments particulaires</translation>
+    </message>
+    <message>
+        <source>STB_BALL</source>
+        <translation>Elément particulaire</translation>
+    </message>
+    <message>
+        <source>STB_EDGE</source>
+        <translation>Arête</translation>
+    </message>
+    <message>
+        <source>STB_EDGES</source>
+        <translation>Arêtes</translation>
+    </message>
+    <message>
+        <source>STB_EDIT_GROUP</source>
+        <translation>Editer un groupe</translation>
+    </message>
+    <message>
+        <source>STB_EDIT_GEOMGROUP_AS_GROUP</source>
+        <translation>Editer un groupe en tant qu&apos;autonome</translation>
+    </message>
+    <message>
+        <source>STB_EDIT_HYPO</source>
+        <translation>Editer une hypothèse</translation>
+    </message>
+    <message>
+        <source>STB_EDIT_MESHSUBMESH</source>
+        <translation>Editer un maillage/sous-maillage</translation>
+    </message>
+    <message>
+        <source>STB_EXPORT_DAT</source>
+        <translation>Exporter au format DAT</translation>
+    </message>
+    <message>
+        <source>STB_EXPORT_MED</source>
+        <translation>Exporter au format MED</translation>
+    </message>
+    <message>
+        <source>STB_EXPORT_CGNS</source>
+        <translation>Exporter au format CGNS</translation>
+    </message>
+    <message>
+        <source>STB_EXPORT_SAUV</source>
+        <translation>Exporter au format SAUV (ASCII)</translation>
+    </message>
+    <message>
+        <source>STB_EXPORT_STL</source>
+        <translation>Exporter au format STL</translation>
+    </message>
+    <message>
+        <source>STB_EXPORT_UNV</source>
+        <translation>Exporter au format UNV</translation>
+    </message>
+    <message>
+        <source>STB_EXTRUSION</source>
+        <translation>Extrusion</translation>
+    </message>
+    <message>
+        <source>STB_EXTRUSION_ALONG</source>
+        <translation>Extrusion suivant un chemin</translation>
+    </message>
+    <message>
+        <source>STB_FACES</source>
+        <translation>Faces</translation>
+    </message>
+    <message>
+        <source>STB_BARE_BORDER_VOLUME</source>
+        <translation>Volumes avec Ã©léments de peau 2D manquants</translation>
+    </message>
+    <message>
+        <source>STB_BARE_BORDER_FACE</source>
+        <translation>Faces avec Ã©léments de peau 1D manquants</translation>
+    </message>
+    <message>
+        <source>STB_OVER_CONSTRAINED_VOLUME</source>
+        <translation>Volumes sur-contraints</translation>
+    </message>
+    <message>
+        <source>STB_OVER_CONSTRAINED_FACE</source>
+        <translation>Faces sur-contraintes</translation>
+    </message>
+    <message>
+        <source>STB_FREE_BORDER</source>
+        <translation>Frontières libres</translation>
+    </message>
+    <message>
+        <source>STB_FREE_EDGE</source>
+        <translation>Arêtes libres</translation>
+    </message>
+    <message>
+        <source>STB_FREE_NODE</source>
+        <translation>NÅ“uds libres</translation>
+    </message>
+    <message>
+        <source>STB_FREE_FACES</source>
+        <translation>Faces libres</translation>
+    </message>
+    <message>
+        <source>STB_GLOBAL_HYPO</source>
+        <translation>Hypothèse globale</translation>
+    </message>
+    <message>
+        <source>STB_HEXA</source>
+        <translation>Hexaèdre</translation>
+    </message>
+    <message>
+        <source>STB_HIDE</source>
+        <translation>Cacher</translation>
+    </message>
+    <message>
+        <source>STB_INT_GROUP</source>
+        <translation>Intersection des groupes</translation>
+    </message>
+    <message>
+        <source>STB_INV</source>
+        <translation>Inversion de diagonale</translation>
+    </message>
+    <message>
+        <source>STB_LENGTH</source>
+        <translation>Longueur</translation>
+    </message>
+    <message>
+        <source>STB_LENGTH_2D</source>
+        <translation>Longueur 2D</translation>
+    </message>
+    <message>
+        <source>STB_MAP</source>
+        <translation>Projection de motif</translation>
+    </message>
+    <message>
+        <source>STB_MAX_ELEMENT_LENGTH_2D</source>
+        <translation>Diamètre de l&apos;élément 2D</translation>
+    </message>
+    <message>
+        <source>STB_MAX_ELEMENT_LENGTH_3D</source>
+        <translation>Diamètre de l&apos;élément 3D</translation>
+    </message>
+    <message>
+        <source>STB_IMPORT_MED</source>
+        <translation>Importer un fichier MED</translation>
+    </message>
+    <message>
+        <source>STB_MED</source>
+        <translation>Exporter un fichier MED</translation>
+    </message>
+    <message>
+        <source>STB_IMPORT_STL</source>
+        <translation>Importer un fichier STL</translation>
+    </message>
+    <message>
+        <source>STB_STL</source>
+        <translation>Exporter un fichier STL</translation>
+    </message>
+    <message>
+        <source>STB_IMPORT_CGNS</source>
+        <translation>Importer un fichier CGNS</translation>
+    </message>
+    <message>
+        <source>STB_CGNS</source>
+        <translation>Exporter un fichier CGNS</translation>
+    </message>
+    <message>
+        <source>STB_IMPORT_SAUV</source>
+        <translation>Importer un fichier SAUV (ASCII)</translation>
+    </message>
+    <message>
+        <source>STB_SAUV</source>
+        <translation>Exporter un fichier SAUV (ASCII)</translation>
+    </message>
+    <message>
+        <source>STB_MERGE</source>
+        <translation>Fusionner les nÅ“uds</translation>
+    </message>
+    <message>
+        <source>STB_MERGE_ELEMENTS</source>
+        <translation>Fusionner les Ã©léments</translation>
+    </message>
+    <message>
+        <source>STB_MESH_THROU_POINT</source>
+        <translation>Déplacer un nÅ“ud</translation>
+    </message>
+    <message>
+        <source>STB_MIN_ANG</source>
+        <translation>Angle minimal</translation>
+    </message>
+    <message>
+        <source>STB_MOVE</source>
+        <translation>Déplacer un nÅ“ud</translation>
+    </message>
+    <message>
+        <source>STB_NODE</source>
+        <translation>NÅ“ud</translation>
+    </message>
+    <message>
+        <source>STB_NODES</source>
+        <translation>NÅ“uds</translation>
+    </message>
+    <message>
+        <source>STB_NUM_ELEMENTS</source>
+        <translation>Visualiser les Ã©léments</translation>
+    </message>
+    <message>
+        <source>STB_NUM_NODES</source>
+        <translation>Visualiser les nÅ“uds</translation>
+    </message>
+    <message>
+        <source>STB_ORIENT</source>
+        <translation>Orientation</translation>
+    </message>
+    <message>
+        <source>STB_POLYGON</source>
+        <translation>Polygone</translation>
+    </message>
+    <message>
+        <source>STB_POLYHEDRON</source>
+        <translation>Polyèdre</translation>
+    </message>
+    <message>
+        <source>STB_PRECISION</source>
+        <translation>Précision</translation>
+    </message>
+    <message>
+        <source>STB_QUAD</source>
+        <translation>Quadrangle</translation>
+    </message>
+    <message>
+        <source>STB_QUADRATIC_EDGE</source>
+        <translation>Arête quadratique</translation>
+    </message>
+    <message>
+        <source>STB_QUADRATIC_HEXAHEDRON</source>
+        <translation>Hexaèdre quadratique</translation>
+    </message>
+    <message>
+        <source>STB_QUADRATIC_PENTAHEDRON</source>
+        <translation>Pentaèdre quadratique</translation>
+    </message>
+    <message>
+        <source>STB_QUADRATIC_PYRAMID</source>
+        <translation>Pyramide quadratique</translation>
+    </message>
+    <message>
+        <source>STB_QUADRATIC_QUADRANGLE</source>
+        <translation>Quadrangle quadratique</translation>
+    </message>
+    <message>
+        <source>STB_QUADRATIC_TETRAHEDRON</source>
+        <translation>Tétraèdre quadratique</translation>
+    </message>
+    <message>
+        <source>STB_QUADRATIC_TRIANGLE</source>
+        <translation>Triangle quadratique</translation>
+    </message>
+    <message>
+        <source>STB_REMOVE_ELEMENTS</source>
+        <translation>Supprimer les Ã©léments</translation>
+    </message>
+    <message>
+        <source>STB_REMOVE_NODES</source>
+        <translation>Supprimer les nÅ“uds</translation>
+    </message>
+    <message>
+        <source>STB_REMOVE_ORPHAN_NODES</source>
+        <translation>Supprimer les nÅ“uds orphelins</translation>
+    </message>
+    <message>
+        <source>STB_RENAME</source>
+        <translation>Renommer</translation>
+    </message>
+    <message>
+        <source>STB_RENUM_ELEMENTS</source>
+        <translation>Renuméroter les Ã©léments</translation>
+    </message>
+    <message>
+        <source>STB_RENUM_NODES</source>
+        <translation>Renuméroter les nÅ“uds</translation>
+    </message>
+    <message>
+        <source>STB_RESET</source>
+        <translation>Restaurer</translation>
+    </message>
+    <message>
+        <source>STB_SAVE_DISTRIBUTION</source>
+        <translation>Enregistrer la distribution dans un fichier</translation>
+    </message>
+    <message>
+        <source>STB_SHOW_DISTRIBUTION</source>
+        <translation>Afficher la distribution</translation>
+    </message>
+    <message>
+        <source>STB_REVOLUTION</source>
+        <translation>Révolution</translation>
+    </message>
+    <message>
+        <source>STB_ROT</source>
+        <translation>Rotation</translation>
+    </message>
+    <message>
+        <source>STB_SCALAR_BAR</source>
+        <translation>Barre d&apos;échelle</translation>
+    </message>
+    <message>
+        <source>STB_SCALAR_BAR_PROP</source>
+        <translation>Propriétés de la barre d&apos;échelle</translation>
+    </message>
+    <message>
+        <source>STB_SELECTION</source>
+        <translation>Sélection</translation>
+    </message>
+    <message>
+        <source>STB_SEL_FILTER_LIB</source>
+        <translation>Librairie des filtres de sélection</translation>
+    </message>
+    <message>
+        <source>STB_SEW</source>
+        <translation>Couture</translation>
+    </message>
+    <message>
+        <source>STB_SHADE</source>
+        <translation>Ombrage</translation>
+    </message>
+    <message>
+        <source>STB_SHOW</source>
+        <translation>Afficher</translation>
+    </message>
+    <message>
+        <source>STB_SHRINK</source>
+        <translation>Contraction</translation>
+    </message>
+    <message>
+        <source>STB_SKEW</source>
+        <translation>Inclinaison d&apos;angle</translation>
+    </message>
+    <message>
+        <source>STB_SMOOTH</source>
+        <translation>Lissage</translation>
+    </message>
+    <message>
+        <source>STB_STD_INFO</source>
+        <translation>Informations sur le maillage</translation>
+    </message>
+    <message>
+        <source>STB_SYM</source>
+        <translation>Symétrie</translation>
+    </message>
+    <message>
+        <source>STB_TAPER</source>
+        <translation>Cône</translation>
+    </message>
+    <message>
+        <source>STB_TETRA</source>
+        <translation>Tétraèdre</translation>
+    </message>
+    <message>
+        <source>STB_TRANS</source>
+        <translation>Translation</translation>
+    </message>
+    <message>
+        <source>STB_SCALE</source>
+        <translation>Mise Ã  l&apos;échelle</translation>
+    </message>
+    <message>
+        <source>STB_DUPLICATE_NODES</source>
+        <translation>Dupliquer les nÅ“uds</translation>
+    </message>
+    <message>
+        <source>STB_TRANSP</source>
+        <translation>Transparence</translation>
+    </message>
+    <message>
+        <source>STB_TRIANGLE</source>
+        <translation>Triangle</translation>
+    </message>
+    <message>
+        <source>STB_UNASSIGN</source>
+        <translation>Désassocier</translation>
+    </message>
+    <message>
+        <source>STB_UNION</source>
+        <translation>Union des triangles</translation>
+    </message>
+    <message>
+        <source>STB_UNION2</source>
+        <translation>Union de deux triangles</translation>
+    </message>
+    <message>
+        <source>STB_IMPORT_UNV</source>
+        <translation>Importer un fichier UNV</translation>
+    </message>
+    <message>
+        <source>STB_UNV</source>
+        <translation>Exporter un fichier UNV</translation>
+    </message>
+    <message>
+        <source>STB_UN_GROUP</source>
+        <translation>Union des groupes</translation>
+    </message>
+    <message>
+        <source>STB_UNDERLYING_ELEMS</source>
+        <translation>Créer les groupes d&apos;entités Ã  partir des groupes existants de dimensions supérieures</translation>
+    </message>
+    <message>
+        <source>STB_UPDATE</source>
+        <translation>Mettre Ã  jour</translation>
+    </message>
+    <message>
+        <source>STB_VOLUMES</source>
+        <translation>Volumes</translation>
+    </message>
+    <message>
+        <source>STB_VOLUME_3D</source>
+        <translation>Volume</translation>
+    </message>
+    <message>
+        <source>STB_WARP</source>
+        <translation>Angle de déformation</translation>
+    </message>
+    <message>
+        <source>STB_WHAT_IS</source>
+        <translation>Information sur un Ã©lément ou un nÅ“ud de maillage</translation>
+    </message>
+    <message>
+        <source>STB_WIRE</source>
+        <translation>Contour</translation>
+    </message>
+    <message>
+        <source>TAPER_ELEMENTS</source>
+        <translation>Cône</translation>
+    </message>
+    <message>
+        <source>TB_ADD_REMOVE</source>
+        <translation>Ajouter/supprimer la barre d&apos;outils</translation>
+    </message>
+    <message>
+        <source>TB_CTRL</source>
+        <translation>Barre d&apos;outils des contrôles</translation>
+    </message>
+    <message>
+        <source>TB_DISP_MODE</source>
+        <translation>Barre du mode de visualisation</translation>
+    </message>
+    <message>
+        <source>TB_HYPO</source>
+        <translation>Barre d&apos;hypothèses</translation>
+    </message>
+    <message>
+        <source>TB_MESH</source>
+        <translation>Barre de maillage</translation>
+    </message>
+    <message>
+        <source>TB_MODIFY</source>
+        <translation>Barre des modifications</translation>
+    </message>
+    <message>
+        <source>TOP_ADV_INFO</source>
+        <translation>Informations sur le maillage</translation>
+    </message>
+    <message>
+        <source>TOP_ALL</source>
+        <translation>Tous</translation>
+    </message>
+    <message>
+        <source>TOP_AREA</source>
+        <translation>Aire</translation>
+    </message>
+    <message>
+        <source>TOP_ASPECT</source>
+        <translation>Rapport de forme</translation>
+    </message>
+    <message>
+        <source>TOP_ASPECT_3D</source>
+        <translation>Rapport de forme 3D</translation>
+    </message>
+    <message>
+        <source>TOP_AUTO_COLOR</source>
+        <translation>Couleur automatique</translation>
+    </message>
+    <message>
+        <source>TOP_AUTO_UPD</source>
+        <translation>Mise Ã  jour automatique</translation>
+    </message>
+    <message>
+        <source>TOP_BUILD_COMPOUND</source>
+        <translation>Construire un maillage assemblé</translation>
+    </message>
+    <message>
+        <source>TOP_COPY_MESH</source>
+        <translation>Copier le maillage</translation>
+    </message>
+    <message>
+        <source>TOP_CLIP</source>
+        <translation>Plan de coupe</translation>
+    </message>
+    <message>
+        <source>TOP_COLORS</source>
+        <translation>Paramètres d&apos;affichage</translation>
+    </message>
+    <message>
+        <source>TOP_COMPUTE</source>
+        <translation>Calculer</translation>
+    </message>
+    <message>
+        <source>TOP_PRECOMPUTE</source>
+        <translation>Prévisualiser</translation>
+    </message>
+    <message>
+        <source>TOP_EVALUATE</source>
+        <translation>Evaluer</translation>
+    </message>
+    <message>
+        <source>TOP_CONNECTION</source>
+        <translation>Frontières sur connexions multiples</translation>
+    </message>
+    <message>
+        <source>TOP_CONNECTION_2D</source>
+        <translation>Frontières sur connexions multiples 2D</translation>
+    </message>
+    <message>
+        <source>TOP_CONSTRUCT_GROUP</source>
+        <translation>Construire un groupe</translation>
+    </message>
+    <message>
+        <source>TOP_CONV_TO_QUAD</source>
+        <translation>Convertir vers/de quadratique</translation>
+    </message>
+    <message>
+        <source>TOP_2D_FROM_3D</source>
+        <translation>Créer les Ã©léments de frontière</translation>
+    </message>
+    <message>
+        <source>TOP_MESH_ORDER</source>
+        <translation>Changer la priorité des sous-maillages</translation>
+    </message>
+    <message>
+        <source>TOP_CREATE_GROUP</source>
+        <translation>Créer un groupe</translation>
+    </message>
+    <message>
+        <source>TOP_CREATE_GEO_GROUP</source>
+        <translation>Créer des groupes liés Ã  la géométrie</translation>
+    </message>
+    <message>
+        <source>TOP_CREATE_MESH</source>
+        <translation>Créer un maillage</translation>
+    </message>
+    <message>
+        <source>TOP_CREATE_SUBMESH</source>
+        <translation>Créer un sous-maillage</translation>
+    </message>
+    <message>
+        <source>TOP_CUT</source>
+        <translation>Découpe des quadrangles</translation>
+    </message>
+    <message>
+        <source>TOP_CUT_GROUP</source>
+        <translation>Découper les groupes</translation>
+    </message>
+    <message>
+        <source>TOP_IMPORT_DAT</source>
+        <translation>Importer un fichier DAT</translation>
+    </message>
+    <message>
+        <source>TOP_DAT</source>
+        <translation>Exporter un fichier DAT</translation>
+    </message>
+    <message>
+        <source>TOP_DELETE</source>
+        <translation>Supprimer</translation>
+    </message>
+    <message>
+        <source>TOP_DEL_GROUP</source>
+        <translation>Supprimer les groupes et leur contenu</translation>
+    </message>
+    <message>
+        <source>TOP_FACE_ORIENTATION</source>
+        <translation>Orientation des faces</translation>
+    </message>
+    <message>
+        <source>TOP_DISABLE_AUTO_COLOR</source>
+        <translation>Désactiver la couleur automatique</translation>
+    </message>
+    <message>
+        <source>TOP_DISPLAY_ONLY</source>
+        <translation>Afficher uniquement</translation>
+    </message>
+    <message>
+        <source>TOP_DISP_ENT</source>
+        <translation>Visualiser une entité</translation>
+    </message>
+    <message>
+        <source>TOP_ELEM0D</source>
+        <translation>Elément 0D</translation>
+    </message>
+    <message>
+        <source>TOP_ELEMS0D</source>
+        <translation>Eléments 0D</translation>
+    </message>
+    <message>
+        <source>TOP_BALL</source>
+        <translation>Particulaire</translation>
+    </message>
+    <message>
+        <source>TOP_BALLS</source>
+        <translation>Particulaires</translation>
+    </message>
+    <message>
+        <source>TOP_EDGE</source>
+        <translation>Arête</translation>
+    </message>
+    <message>
+        <source>TOP_EDGES</source>
+        <translation>Arêtes</translation>
+    </message>
+    <message>
+        <source>TOP_EDIT_GROUP</source>
+        <translation>Editer un groupe</translation>
+    </message>
+    <message>
+        <source>TOP_EDIT_GEOMGROUP_AS_GROUP</source>
+        <translation>Editer un groupe en tant qu&apos;autonome</translation>
+    </message>
+    <message>
+        <source>TOP_EDIT_HYPO</source>
+        <translation>Editer l&apos;hypothèse</translation>
+    </message>
+    <message>
+        <source>TOP_EDIT_MESHSUBMESH</source>
+        <translation>Editer un maillage/sous-maillage</translation>
+    </message>
+    <message>
+        <source>TOP_EXPORT_DAT</source>
+        <translation>Exporter au format DAT</translation>
+    </message>
+    <message>
+        <source>TOP_EXPORT_MED</source>
+        <translation>Exporter au format MED</translation>
+    </message>
+    <message>
+        <source>TOP_EXPORT_SAUV</source>
+        <translation>Exporter au format SAUV (ASCII)</translation>
+    </message>
+    <message>
+        <source>TOP_EXPORT_STL</source>
+        <translation>Exporter au format STL</translation>
+    </message>
+    <message>
+        <source>TOP_EXPORT_UNV</source>
+        <translation>Exporter au format UNV</translation>
+    </message>
+    <message>
+        <source>TOP_EXTRUSION</source>
+        <translation>Extrusion</translation>
+    </message>
+    <message>
+        <source>TOP_EXTRUSION_ALONG</source>
+        <translation>Extrusion suivant un chemin</translation>
+    </message>
+    <message>
+        <source>TOP_FACES</source>
+        <translation>Faces</translation>
+    </message>
+    <message>
+        <source>TOP_BARE_BORDER_VOLUME</source>
+        <translation>Volumes avec Ã©léments de peau 2D manquants</translation>
+    </message>
+    <message>
+        <source>TOP_BARE_BORDER_FACE</source>
+        <translation>Faces avec Ã©léments de peau 1D manquants</translation>
+    </message>
+    <message>
+        <source>TOP_OVER_CONSTRAINED_VOLUME</source>
+        <translation>Volumes sur-contraints</translation>
+    </message>
+    <message>
+        <source>TOP_OVER_CONSTRAINED_FACE</source>
+        <translation>Faces sur-contraintes</translation>
+    </message>
+    <message>
+        <source>TOP_FREE_BORDER</source>
+        <translation>Frontières libres</translation>
+    </message>
+    <message>
+        <source>TOP_FREE_EDGE</source>
+        <translation>Arêtes libres</translation>
+    </message>
+    <message>
+        <source>TOP_FREE_NODE</source>
+        <translation>NÅ“uds libres</translation>
+    </message>
+    <message>
+        <source>TOP_FREE_FACES</source>
+        <translation>Faces libres</translation>
+    </message>
+    <message>
+        <source>TOP_GLOBAL_HYPO</source>
+        <translation>Hypothèse globale</translation>
+    </message>
+    <message>
+        <source>TOP_HEXA</source>
+        <translation>Hexaèdre</translation>
+    </message>
+    <message>
+        <source>TOP_HIDE</source>
+        <translation>Cacher</translation>
+    </message>
+    <message>
+        <source>TOP_INT_GROUP</source>
+        <translation>Intersection de groupes</translation>
+    </message>
+    <message>
+        <source>TOP_INV</source>
+        <translation>Inversion de diagonale</translation>
+    </message>
+    <message>
+        <source>TOP_LENGTH</source>
+        <translation>Longueur</translation>
+    </message>
+    <message>
+        <source>TOP_LENGTH_2D</source>
+        <translation>Longueur 2D</translation>
+    </message>
+    <message>
+        <source>TOP_MAP</source>
+        <translation>Projection de motif</translation>
+    </message>
+    <message>
+        <source>TOP_MAX_ELEMENT_LENGTH_2D</source>
+        <translation>Diamètre des Ã©léments 2D</translation>
+    </message>
+    <message>
+        <source>TOP_MAX_ELEMENT_LENGTH_3D</source>
+        <translation>Diamètre des Ã©léments 3D</translation>
+    </message>
+    <message>
+        <source>TOP_IMPORT_MED</source>
+        <translation>Importer un fichier MED</translation>
+    </message>
+    <message>
+        <source>TOP_MED</source>
+        <translation>Exporter un fichier MED</translation>
+    </message>
+    <message>
+        <source>TOP_IMPORT_STL</source>
+        <translation>Importer un fichier STL</translation>
+    </message>
+    <message>
+        <source>TOP_STL</source>
+        <translation>Exporter un fichier STL</translation>
+    </message>
+    <message>
+        <source>TOP_IMPORT_CGNS</source>
+        <translation>Importer un fichier CGNS</translation>
+    </message>
+    <message>
+        <source>TOP_CGNS</source>
+        <translation>Exporter un fichier CGNS</translation>
+    </message>
+    <message>
+        <source>TOP_IMPORT_SAUV</source>
+        <translation>Importer un fichier SAUV (ASCII)</translation>
+    </message>
+    <message>
+        <source>TOP_SAUV</source>
+        <translation>Exporter un fichier SAUV (ASCII)</translation>
+    </message>
+    <message>
+        <source>TOP_MERGE</source>
+        <translation>Fusionner les nÅ“uds</translation>
+    </message>
+    <message>
+        <source>TOP_MERGE_ELEMENTS</source>
+        <translation>Fusionner les Ã©léments</translation>
+    </message>
+    <message>
+        <source>TOP_MESH_THROU_POINT</source>
+        <translation>Déplacer un nÅ“ud</translation>
+    </message>
+    <message>
+        <source>TOP_MIN_ANG</source>
+        <translation>Angle minimal</translation>
+    </message>
+    <message>
+        <source>TOP_MOVE</source>
+        <translation>Déplacer un nÅ“ud</translation>
+    </message>
+    <message>
+        <source>TOP_NODE</source>
+        <translation>NÅ“ud</translation>
+    </message>
+    <message>
+        <source>TOP_NODES</source>
+        <translation>NÅ“uds</translation>
+    </message>
+    <message>
+        <source>TOP_NUM_ELEMENTS</source>
+        <translation>Visualiser les Ã©léments</translation>
+    </message>
+    <message>
+        <source>TOP_NUM_NODES</source>
+        <translation>Visualiser les nÅ“uds</translation>
+    </message>
+    <message>
+        <source>TOP_ORIENT</source>
+        <translation>Orientation</translation>
+    </message>
+    <message>
+        <source>TOP_POLYGON</source>
+        <translation>Polygone</translation>
+    </message>
+    <message>
+        <source>TOP_POLYHEDRON</source>
+        <translation>Polyèdre</translation>
+    </message>
+    <message>
+        <source>TOP_PRECISION</source>
+        <translation>Précision</translation>
+    </message>
+    <message>
+        <source>TOP_QUAD</source>
+        <translation>Quadrangle</translation>
+    </message>
+    <message>
+        <source>TOP_QUADRATIC_EDGE</source>
+        <translation>Arête quadratique</translation>
+    </message>
+    <message>
+        <source>TOP_QUADRATIC_HEXAHEDRON</source>
+        <translation>Hexaèdre quadratique</translation>
+    </message>
+    <message>
+        <source>TOP_QUADRATIC_PENTAHEDRON</source>
+        <translation>Pentaèdre quadratique</translation>
+    </message>
+    <message>
+        <source>TOP_QUADRATIC_PYRAMID</source>
+        <translation>Pyramide quadratique</translation>
+    </message>
+    <message>
+        <source>TOP_QUADRATIC_QUADRANGLE</source>
+        <translation>Quadrangle quadratique</translation>
+    </message>
+    <message>
+        <source>TOP_QUADRATIC_TETRAHEDRON</source>
+        <translation>Tétraèdre quadratique</translation>
+    </message>
+    <message>
+        <source>TOP_QUADRATIC_TRIANGLE</source>
+        <translation>Triangle quadratique</translation>
+    </message>
+    <message>
+        <source>TOP_REMOVE_ELEMENTS</source>
+        <translation>Supprimer les Ã©léments</translation>
+    </message>
+    <message>
+        <source>TOP_REMOVE_NODES</source>
+        <translation>Supprimer les nÅ“uds</translation>
+    </message>
+    <message>
+        <source>TOP_REMOVE_ORPHAN_NODES</source>
+        <translation>Supprimer les nÅ“uds orphelins</translation>
+    </message>
+    <message>
+        <source>TOP_RENAME</source>
+        <translation>Renommer</translation>
+    </message>
+    <message>
+        <source>TOP_RENUM_ELEMENTS</source>
+        <translation>Renuméroter les Ã©léments</translation>
+    </message>
+    <message>
+        <source>TOP_RENUM_NODES</source>
+        <translation>Renuméroter les nÅ“uds</translation>
+    </message>
+    <message>
+        <source>TOP_RESET</source>
+        <translation>Restaurer</translation>
+    </message>
+    <message>
+        <source>TOP_SAVE_DISTRIBUTION</source>
+        <translation>Exporter la distribution</translation>
+    </message>
+    <message>
+        <source>TOP_SHOW_DISTRIBUTION</source>
+        <translation>Afficher la distribution</translation>
+    </message>
+    <message>
+        <source>TOP_REVOLUTION</source>
+        <translation>Révolution</translation>
+    </message>
+    <message>
+        <source>TOP_ROT</source>
+        <translation>Rotation</translation>
+    </message>
+    <message>
+        <source>TOP_SCALAR_BAR</source>
+        <translation>Barre d&apos;échelle</translation>
+    </message>
+    <message>
+        <source>TOP_SCALAR_BAR_PROP</source>
+        <translation>Propriétés de la barre d&apos;échelle</translation>
+    </message>
+    <message>
+        <source>TOP_SELECTION</source>
+        <translation>Sélection</translation>
+    </message>
+    <message>
+        <source>TOP_SEL_FILTER_LIB</source>
+        <translation>Librairie des filtres de sélection</translation>
+    </message>
+    <message>
+        <source>TOP_SEW</source>
+        <translation>Couture</translation>
+    </message>
+    <message>
+        <source>TOP_SHADE</source>
+        <translation>Ombrage</translation>
+    </message>
+    <message>
+        <source>TOP_SHOW</source>
+        <translation>Afficher</translation>
+    </message>
+    <message>
+        <source>TOP_SHRINK</source>
+        <translation>Contraction</translation>
+    </message>
+    <message>
+        <source>TOP_SKEW</source>
+        <translation>Inclinaison d&apos;angle</translation>
+    </message>
+    <message>
+        <source>TOP_SMOOTH</source>
+        <translation>Lissage</translation>
+    </message>
+    <message>
+        <source>TOP_STD_INFO</source>
+        <translation>Informations sur le maillage</translation>
+    </message>
+    <message>
+        <source>TOP_SYM</source>
+        <translation>Symétrie</translation>
+    </message>
+    <message>
+        <source>TOP_TAPER</source>
+        <translation>Cône</translation>
+    </message>
+    <message>
+        <source>TOP_TETRA</source>
+        <translation>Tétraèdre</translation>
+    </message>
+    <message>
+        <source>TOP_TRANS</source>
+        <translation>Translation</translation>
+    </message>
+    <message>
+        <source>TOP_SCALE</source>
+        <translation>Mise Ã  l&apos;échelle</translation>
+    </message>
+    <message>
+        <source>TOP_DUPLICATE_NODES</source>
+        <translation>Dupliquer les nÅ“uds</translation>
+    </message>
+    <message>
+        <source>TOP_TRANSP</source>
+        <translation>Transparence</translation>
+    </message>
+    <message>
+        <source>TOP_TRIANGLE</source>
+        <translation>Triangle</translation>
+    </message>
+    <message>
+        <source>TOP_UNASSIGN</source>
+        <translation>Désassocier</translation>
+    </message>
+    <message>
+        <source>TOP_UNION</source>
+        <translation>Union des triangles</translation>
+    </message>
+    <message>
+        <source>TOP_UNION2</source>
+        <translation>Union de deux triangles</translation>
+    </message>
+    <message>
+        <source>TOP_IMPORT_UNV</source>
+        <translation>Importer un fichier UNV</translation>
+    </message>
+    <message>
+        <source>TOP_UNV</source>
+        <translation>Exporter un fichier UNV</translation>
+    </message>
+    <message>
+        <source>TOP_UN_GROUP</source>
+        <translation>Union des groupes</translation>
+    </message>
+    <message>
+        <source>TOP_UNDERLYING_ELEMS</source>
+        <translation>Créer les groupes d&apos;entités Ã  partir des groupes existants de dimensions supérieures</translation>
+    </message>
+    <message>
+        <source>TOP_UPDATE</source>
+        <translation>Mettre Ã  jour</translation>
+    </message>
+    <message>
+        <source>TOP_VOLUMES</source>
+        <translation>Volumes</translation>
+    </message>
+    <message>
+        <source>TOP_VOLUME_3D</source>
+        <translation>Volume</translation>
+    </message>
+    <message>
+        <source>TOP_WARP</source>
+        <translation>Angle de déformation</translation>
+    </message>
+    <message>
+        <source>TOP_WHAT_IS</source>
+        <translation>Information sur l&apos;élément de maillage</translation>
+    </message>
+    <message>
+        <source>TOP_WIRE</source>
+        <translation>Contours</translation>
+    </message>
+    <message>
+        <source>UNKNOWN_CONTROL</source>
+        <translation>Inconnu</translation>
+    </message>
+    <message>
+        <source>VOLUME_3D_ELEMENTS</source>
+        <translation>Volume</translation>
+    </message>
+    <message>
+        <source>WARP_ELEMENTS</source>
+        <translation>Déformation</translation>
+    </message>
+    <message>
+        <source>MEN_FILE_INFO</source>
+        <translation>Information du fichier MED</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_NO_APPROPRIATE_SELECTION</source>
+        <translation>Aucun objet sélectionné ne convient</translation>
+    </message>
+    <message>
+        <source>MEN_CLEAR_MESH</source>
+        <translation>Effacer les données du maillage</translation>
+    </message>
+    <message>
+        <source>TOP_CLEAR_MESH</source>
+        <translation>Effacer les données du maillage</translation>
+    </message>
+    <message>
+        <source>STB_CLEAR_MESH</source>
+        <translation>Effacer les données du maillage</translation>
+    </message>
+    <message>
+        <source>SMESH_IMPORT_MESH</source>
+        <translation>Importer les donnés du maillage Ã  partir des fichiers</translation>
+    </message>
+    <message>
+        <source>SMESH_ERR_NOT_SUPPORTED_FORMAT</source>
+        <translation>Le format de fichier n&apos;est pas supporté</translation>
+    </message>
+    <message>
+        <source>SMESH_ERR_UNKNOWN_IMPORT_ERROR</source>
+        <translation>Erreur inconnue</translation>
+    </message>
+    <message>
+        <source>SMESH_IMPORT_ERRORS</source>
+        <translation>L&apos;importation s&apos;est terminée avec des erreurs</translation>
+    </message>
+    <message>
+        <source>SMESH_DRS_SOME_EMPTY</source>
+        <translation>Un ou plusieurs fichiers de maillage sont vides, les données n&apos;ont pas Ã©té publiées</translation>
+    </message>
+    <message>
+        <source>NO_MESH_SELECTED</source>
+        <translation>Aucun maillage sélectionné</translation>
+    </message>
+    <message>
+        <source>SMESH_PREF_def_precision</source>
+        <translation>Précision par défaut</translation>
+    </message>
+    <message>
+        <source>SMESH_PREF_length_precision</source>
+        <translation>Précision de la longueur</translation>
+    </message>
+    <message>
+        <source>SMESH_PREF_angle_precision</source>
+        <translation>Précision angulaire</translation>
+    </message>
+    <message>
+        <source>SMESH_PREF_len_tol_precision</source>
+        <translation>Précision de tolérance de la longueur</translation>
+    </message>
+    <message>
+        <source>SMESH_PREF_parametric_precision</source>
+        <translation>Précision paramétrique</translation>
+    </message>
+    <message>
+        <source>SMESH_PREF_area_precision</source>
+        <translation>Précision de l&apos;aire</translation>
+    </message>
+    <message>
+        <source>FULL_RECOMPUTE_QUESTION</source>
+        <translation>
+Le maillage a Ã©té Ã©dité après le dernier calcul complet,
+ceci peut empêcher un calcul correct.
+Voulez-vous recalculer le maillage entier pour rejeter les modifications ?
+</translation>
+    </message>
+    <message>
+        <source>SMESH_PREF_vol_precision</source>
+        <translation>Précision du volume</translation>
+    </message>
+    <message>
+        <source>SMESH_PRECISION_HINT</source>
+        <translation>
+Il est possible de modifier la précision de la valeur d&apos;entrée
+avec le paramètre &apos;%1&apos; des préférences du module Mesh.</translation>
+    </message>
+    <message>
+        <source>REMOVE_ORPHAN_NODES_QUESTION</source>
+        <translation>Voulez-vous supprimer tous les nÅ“uds orphelins ?</translation>
+    </message>
+    <message>
+        <source>NB_NODES_REMOVED</source>
+        <translation>%1 nÅ“ud(s) supprimés.</translation>
+    </message>
+    <message>
+        <source>SMESH_SAVE_DISTRIBUTION</source>
+        <translation>Exporter la distribution</translation>
+    </message>
+    <message>
+        <source>SMESH_PLUGINS_OTHER</source>
+        <translation>Extensions SMESH</translation>
+    </message>
+    <message>
+        <source>MESH_LOADING_MSG</source>
+        <translation>Chargement du maillage %0 en cours, veuillez patienter...</translation>
+    </message>
+    <message>
+        <source>MESH_LOADING_MSG_FINISHED</source>
+        <translation>Chargement du maillage %0 terminé</translation>
+    </message>
+    <message>
+        <source>BALL_DIAMETER</source>
+        <translation>Diamètre</translation>
+    </message>
+    <message>
+        <source>BALL_ELEMENT</source>
+        <translation>Particulaire</translation>
+    </message>
+    <message>
+        <source>DEP_OBJECT</source>
+        <translation>L&apos;objet sélectionné a Ã©té utilisé pour en créer un autre.
+Il ne peut pas Ãªtre supprimé.</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_GroupDlg</name>
+    <message>
+        <source>ALLOW_ELEM_LIST_MODIF</source>
+        <translation>Edition manuelle</translation>
+    </message>
+    <message>
+        <source>SELECT_ALL</source>
+        <translation>Sélectionner tout</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI</name>
+    <message>
+        <source>NOT_A_VTK_VIEWER</source>
+        <translation>Cette commande n&apos;est disponible qu&apos;à partir d&apos;une fenêtre VTK.
+Ouvrez une fenêtre VTK et essayez de nouveau</translation>
+    </message>
+    <message>
+        <source>PREF_AUTO_GROUPS</source>
+        <translation>Créer les groupes automatiquement pour l&apos;export MED</translation>
+    </message>
+    <message>
+        <source>PREF_GROUP_SEGMENT_LENGTH</source>
+        <translation>Paramètres automatiques</translation>
+    </message>
+    <message>
+        <source>PREF_SEGMENT_LENGTH</source>
+        <translation>Ratio de la diagonale de la boîte englobante / taille maximale</translation>
+    </message>
+    <message>
+        <source>PREF_NB_SEGMENTS</source>
+        <translation>Nombre de segments par défaut</translation>
+    </message>
+    <message>
+        <source>SMESH_PREF_MESH_LOADING</source>
+        <translation>Chargement de maillage</translation>
+    </message>
+    <message>
+        <source>PREF_FORGET_MESH_AT_HYP_MODIF</source>
+        <translation>Ne pas charger le maillage du fichier d&apos;étude Ã  la modification d&apos;une hypothèse</translation>
+    </message>
+    <message>
+        <source>PREF_AUTO_UPDATE</source>
+        <translation>Mettre Ã  jour automatiquement</translation>
+    </message>
+    <message>
+        <source>PREF_UPDATE_LIMIT</source>
+        <translation>Limite de taille (nombre d&apos;éléments)</translation>
+    </message>
+    <message>
+        <source>PREF_UPDATE_LIMIT_NOLIMIT</source>
+        <translation>Sans limite</translation>
+    </message>
+    <message>
+        <source>PREF_BACKFACE</source>
+        <translation>Face arrière</translation>
+    </message>
+    <message>
+        <source>PREF_WIREFRAME</source>
+        <translation>Couleur de contour</translation>
+    </message>
+    <message>
+        <source>PREF_SELECTION</source>
+        <translation>Couleur de sélection</translation>
+    </message>
+    <message>
+        <source>PREF_PRE_SELECTION</source>
+        <translation>Couleur de pré-sélection</translation>
+    </message>
+    <message>
+        <source>PREF_COLOR</source>
+        <translation>Couleur</translation>
+    </message>
+    <message>
+        <source>PREF_ORIENTATION_COLOR</source>
+        <translation>Couleur</translation>
+    </message>
+    <message>
+        <source>PREF_ORIENTATION_3D_VECTORS</source>
+        <translation>Vecteurs 3D</translation>
+    </message>
+    <message>
+        <source>PREF_ORIENTATION_SCALE</source>
+        <translation>Echelle</translation>
+    </message>
+    <message>
+        <source>PREF_DISPLAY_ENTITY</source>
+        <translation>Eléments Ã  visualiser</translation>
+    </message>
+    <message>
+        <source>QUADRATIC_REPRESENT_MODE</source>
+        <translation>Représentation des Ã©léments quadratiques 2D</translation>
+    </message>
+    <message>
+        <source>MAX_ARC_ANGLE</source>
+        <translation>Angle maximal</translation>
+    </message>
+    <message>
+        <source>PREF_DISPLAY_MODE</source>
+        <translation>Mode de visualisation</translation>
+    </message>
+    <message>
+        <source>PREF_ELEMENTS</source>
+        <translation>Eléments</translation>
+    </message>
+    <message>
+        <source>PREF_ELEMENT_COLOR</source>
+        <translation>Couleur d&apos;élément</translation>
+    </message>
+    <message>
+        <source>PREF_FILL</source>
+        <translation>Remplir</translation>
+    </message>
+    <message>
+        <source>PREF_NOTIFY_MODE</source>
+        <translation>Montrer la notification sur le résultat de calcul</translation>
+    </message>
+    <message>
+        <source>PREF_NOTIFY_NEVER</source>
+        <translation>Jamais</translation>
+    </message>
+    <message>
+        <source>PREF_NOTIFY_ERROR</source>
+        <translation>Erreurs uniquement</translation>
+    </message>
+    <message>
+        <source>PREF_NOTIFY_ALWAYS</source>
+        <translation>Toujours</translation>
+    </message>
+    <message>
+        <source>PREF_ELEM_INFO</source>
+        <translation>Information des Ã©léments du maillage</translation>
+    </message>
+    <message>
+        <source>PREF_ELEM_INFO_SIMPLE</source>
+        <translation>Simple</translation>
+    </message>
+    <message>
+        <source>PREF_ELEM_INFO_TREE</source>
+        <translation>Arbre</translation>
+    </message>
+    <message>
+        <source>PREF_GPP_NODES_LIMIT</source>
+        <translation>Calcul automatique du nombre de nÅ“uds: limite</translation>
+    </message>
+    <message>
+        <source>SMESH_PREF_GROUP_PRECISION</source>
+        <translation>Précision des champs d&apos;entrée</translation>
+    </message>
+    <message>
+        <source>SMESH_PREF_GROUP_PREVIEW</source>
+        <translation>Prévisualisation</translation>
+    </message>
+    <message>
+        <source>PREF_GROUP_ELEMENTS</source>
+        <translation>Eléments</translation>
+    </message>
+    <message>
+        <source>PREF_GROUP_EXPORT</source>
+        <translation>Exporter un maillage</translation>
+    </message>
+    <message>
+        <source>PREF_GROUP_FACES_ORIENTATION</source>
+        <translation>Orientation des faces</translation>
+    </message>
+    <message>
+        <source>PREF_GROUP_COMPUTE</source>
+        <translation>Calculer le maillage</translation>
+    </message>
+    <message>
+        <source>PREF_GROUP_NODES</source>
+        <translation>NÅ“uds</translation>
+    </message>
+    <message>
+        <source>PREF_GROUP_GROUPS</source>
+        <translation>Groupes</translation>
+    </message>
+    <message>
+        <source>PREF_GRP_NAMES</source>
+        <translation>Couleur des noms</translation>
+    </message>
+    <message>
+        <source>PREF_GROUP_PRECISION</source>
+        <translation>Précision</translation>
+    </message>
+    <message>
+        <source>PREF_GROUP_PRESELECTION</source>
+        <translation>Présélection</translation>
+    </message>
+    <message>
+        <source>PREF_GROUP_QUALITY</source>
+        <translation>Contrôles de qualité</translation>
+    </message>
+    <message>
+        <source>PREF_GROUP_SELECTION</source>
+        <translation>Sélection</translation>
+    </message>
+    <message>
+        <source>PREF_GROUP_INFO</source>
+        <translation>Information du maillage</translation>
+    </message>
+    <message>
+        <source>PREF_HIGHLIGHT_COLOR</source>
+        <translation>Couleur de sélection</translation>
+    </message>
+    <message>
+        <source>PREF_LABELS_COLOR</source>
+        <translation>Couleur des Ã©tiquettes</translation>
+    </message>
+    <message>
+        <source>PREF_MARKER_SCALE</source>
+        <translation>Echelle du marqueur</translation>
+    </message>
+    <message>
+        <source>PREF_NODES</source>
+        <translation>NÅ“uds</translation>
+    </message>
+    <message>
+        <source>PREF_OBJECTS</source>
+        <translation>Objets</translation>
+    </message>
+    <message>
+        <source>PREF_OBJECT_COLOR</source>
+        <translation>Couleur d&apos;objet</translation>
+    </message>
+    <message>
+        <source>PREF_OUTLINE</source>
+        <translation>Silhouette</translation>
+    </message>
+    <message>
+        <source>PREF_PRECISION_USE</source>
+        <translation>Utiliser la précision</translation>
+    </message>
+    <message>
+        <source>PREF_PRECISION_VALUE</source>
+        <translation>Nombre de chiffres après la virgule</translation>
+    </message>
+    <message>
+        <source>PREF_EQUAL_NODES_TOL</source>
+        <translation>Tolérance des nÅ“uds doubles</translation>
+    </message>
+    <message>
+        <source>PREF_RENUMBER</source>
+        <translation>Renuméroter automatiquement</translation>
+    </message>
+    <message>
+        <source>PREF_SHRINK_COEFF</source>
+        <translation>Coefficient de contraction</translation>
+    </message>
+    <message>
+        <source>PREF_PYTHON_DUMP</source>
+        <translation>Dump Python</translation>
+    </message>
+    <message>
+        <source>PREF_HISTORICAL_PYTHON_DUMP</source>
+        <translation>Dump Python historique</translation>
+    </message>
+    <message>
+        <source>PREF_TAB_GENERAL</source>
+        <translation>Général</translation>
+    </message>
+    <message>
+        <source>PREF_TAB_MESH</source>
+        <translation>Maillage</translation>
+    </message>
+    <message>
+        <source>PREF_TAB_SELECTION</source>
+        <translation>Sélection</translation>
+    </message>
+    <message>
+        <source>PREF_TITLE_COLOR</source>
+        <translation>Couleur du titre</translation>
+    </message>
+    <message>
+        <source>PREF_TYPE_OF_MARKER</source>
+        <translation>Type de marqueur</translation>
+    </message>
+    <message>
+        <source>PREF_COLOR_0D</source>
+        <translation>Eléments 0D</translation>
+    </message>
+    <message>
+        <source>PREF_SIZE_0D</source>
+        <translation>Taille des Ã©léments 0D</translation>
+    </message>
+    <message>
+        <source>PREF_BALL_COLOR</source>
+        <translation>Particulaires</translation>
+    </message>
+    <message>
+        <source>PREF_BALL_SIZE</source>
+        <translation>Taille des Ã©léments particulaires</translation>
+    </message>
+    <message>
+        <source>PREF_WIDTH</source>
+        <translation>Epaisseur</translation>
+    </message>
+    <message>
+        <source>PREF_PREVIEW_CHUNK_SIZE</source>
+        <translation>Taille des blocs pour la prévisualisation des sous-shapes</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_AddQuadraticElementDlg</name>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_EDGE</source>
+        <translation>Ajouter une arête quadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_HEXAHEDRON</source>
+        <translation>Ajouter un hexaèdre quadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_TRIQUADRATIC_HEXAHEDRON</source>
+        <translation>Ajouter un hexaèdre triquadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_PENTAHEDRON</source>
+        <translation>Ajouter un pentaèdre quadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_PYRAMID</source>
+        <translation>Ajouter une pyramide quadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_QUADRANGLE</source>
+        <translation>Ajouter un quadrangle quadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_BIQUADRATIC_QUADRANGLE</source>
+        <translation>Ajouter un quadrangle biquadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_TETRAHEDRON</source>
+        <translation>Ajouter un tétraèdre quadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_ADD_QUADRATIC_TRIANGLE</source>
+        <translation>Ajouter un triangle quadratique</translation>
+    </message>
+    <message>
+        <source>SMESH_CORNER_NODES</source>
+        <translation>NÅ“uds angulaires:</translation>
+    </message>
+    <message>
+        <source>SMESH_MIDFACE_NODES</source>
+        <translation>NÅ“uds Ã  mi-face :</translation>
+    </message>
+    <message>
+        <source>SMESH_CENTER_NODE</source>
+        <translation>NÅ“ud central:</translation>
+    </message>
+    <message>
+        <source>SMESH_FIRST</source>
+        <translation>Premier</translation>
+    </message>
+    <message>
+        <source>SMESH_LAST</source>
+        <translation>Dernier</translation>
+    </message>
+    <message>
+        <source>SMESH_MIDDLE</source>
+        <translation>Milieu</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_BuildCompoundDlg</name>
+    <message>
+        <source>COMPOUND</source>
+        <translation>Assemblage</translation>
+    </message>
+    <message>
+        <source>COMPOUND_MESH</source>
+        <translation>Maillage d&apos;assemblage</translation>
+    </message>
+    <message>
+        <source>CREATE_COMMON_GROUPS</source>
+        <translation>Créer des groupes communs pour les maillages initiaux</translation>
+    </message>
+    <message>
+        <source>MERGE_NODES_AND_ELEMENTS</source>
+        <translation>Fusionner les nÅ“uds et les Ã©léments coïncidents</translation>
+    </message>
+    <message>
+        <source>MESHES</source>
+        <translation>Maillages</translation>
+    </message>
+    <message>
+        <source>PROCESSING_IDENTICAL_GROUPS</source>
+        <translation>Traitement des groupes identiques</translation>
+    </message>
+    <message>
+        <source>RENAME</source>
+        <translation>Renommer</translation>
+    </message>
+    <message>
+        <source>RESULT_NAME</source>
+        <translation>Nom du résultat</translation>
+    </message>
+    <message>
+        <source>UNITE</source>
+        <translation>Réunir</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_ChangeOrientationDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Modifier l&apos;orientation</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_ComputeDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Le calcul du maillage a Ã©choué</translation>
+    </message>
+    <message>
+        <source>CONSTRUCTOR</source>
+        <translation>Calculer le maillage</translation>
+    </message>
+    <message>
+        <source>EVAL_DLG</source>
+        <translation>Evaluer le maillage</translation>
+    </message>
+    <message>
+        <source>ERRORS</source>
+        <translation>Erreurs</translation>
+    </message>
+    <message>
+        <source>MEMORY_LACK</source>
+        <translation>Problème d&apos;allocation de mémoire</translation>
+    </message>
+    <message>
+        <source>COMPUTE_WARNING</source>
+        <translation>Le maillage semble correct mais des erreurs sont apparues</translation>
+    </message>
+    <message>
+        <source>PUBLISH_SHAPE</source>
+        <translation>Publier un sous-objet</translation>
+    </message>
+    <message>
+        <source>SHOW_SHAPE</source>
+        <translation>Montrer un sous-objet</translation>
+    </message>
+    <message>
+        <source>SHOW_BAD_MESH</source>
+        <translation>Montrer le maillage incorrect</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_PrecomputeDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Prévisualiser et calculer le maillage</translation>
+    </message>
+    <message>
+        <source>PREVIEW</source>
+        <translation>Prévisualiser</translation>
+    </message>
+    <message>
+        <source>PREVIEW_1</source>
+        <translation>Maillage 1D</translation>
+    </message>
+    <message>
+        <source>PREVIEW_2</source>
+        <translation>Maillage 2D</translation>
+    </message>
+    <message>
+        <source>COMPUTE</source>
+        <translation>Calculer</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_PrecomputeOp</name>
+    <message>
+        <source>CLEAR_SUBMESH_QUESTION</source>
+        <translation>Des sous-maillages temporaires ont Ã©té créés sur la géométrie sélectionnée
+au cours de l&apos;opération de prévisualisation.
+Voulez-vous supprimer toutes ces sous-maillages ?</translation>
+    </message>
+    <message>
+        <source>SMESH_WRN_NOTHING_PREVIEW</source>
+        <translation>La prévisualisation du maillage n&apos;est pas disponible</translation>
+    </message>
+    <message>
+        <source>SMESH_REJECT_MESH_ORDER</source>
+        <translation>La priorité des sous-maillages a Ã©té changée au cours de la prévisualisation.
+Voulez-vous restaurer la priorité initiale ?</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_ConvToQuadDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Convertir vers/de quadratique</translation>
+    </message>
+    <message>
+        <source>MEDIUMNDS</source>
+        <translation>NÅ“uds milieux sur la géométrie</translation>
+    </message>
+    <message>
+        <source>MESH</source>
+        <translation>Maillage ou sous-maillage</translation>
+    </message>
+    <message>
+        <source>RADIOBTN_1</source>
+        <translation>Convertir en Ã©léments quadratiques</translation>
+    </message>
+    <message>
+        <source>RADIOBTN_2</source>
+        <translation>Convertir Ã  partir d&apos;éléments quadratiques</translation>
+    </message>
+    <message>
+        <source>NON_CONFORM_WARNING</source>
+        <translation>Attention: le maillage généré sera a priori non-conforme</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_ConvToQuadOp</name>
+    <message>
+        <source>MESH_IS_NOT_SELECTED</source>
+        <translation>Le maillage n&apos;est pas sélectionné
+Indiquez-le et essayez de nouveau</translation>
+    </message>
+    <message>
+        <source>REF_IS_NULL</source>
+        <translation>Aucun maillage valide n&apos;est sélectionné</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_CreatePatternDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Projection de motif</translation>
+    </message>
+    <message>
+        <source>DEFAULT_2D</source>
+        <translation>Motif_2d</translation>
+    </message>
+    <message>
+        <source>DEFAULT_3D</source>
+        <translation>Motif_3d</translation>
+    </message>
+    <message>
+        <source>ERROR_OF_CREATION</source>
+        <translation>Une erreur interne s&apos;est produite au cours de la création du motif
+Vérifiez la validité des informations données</translation>
+    </message>
+    <message>
+        <source>ERROR_OF_SAVING</source>
+        <translation>Une erreur interne s&apos;est produite au cours de l&apos;enregistrement du motif.
+Vérifiez l&apos;espace de disque disponible et vos droits d&apos;écriture dans ce fichier</translation>
+    </message>
+    <message>
+        <source>ERR_LOADF_CANT_PROJECT</source>
+        <translation>Impossible d&apos;appliquer la projection des nÅ“uds vers la face</translation>
+    </message>
+    <message>
+        <source>ERR_LOADF_CLOSED_FACE</source>
+        <translation>Impossible de créer un motif Ã  partir d&apos;une face avec une arête de couture</translation>
+    </message>
+    <message>
+        <source>ERR_LOADF_NARROW_FACE</source>
+        <translation>Impossible de créer un motif Ã  partir d&apos;une face Ã©troite</translation>
+    </message>
+    <message>
+        <source>ERR_LOADV_BAD_SHAPE</source>
+        <translation>Il n&apos;est possible de créer un motif que d&apos;une coque fermée ou d&apos;un solide avec 6 faces</translation>
+    </message>
+    <message>
+        <source>ERR_LOADV_COMPUTE_PARAMS</source>
+        <translation>Il est impossible de calculer les paramètres du point</translation>
+    </message>
+    <message>
+        <source>ERR_LOAD_EMPTY_SUBMESH</source>
+        <translation>Il n&apos;y a pas d&apos;éléments pour créer de motif</translation>
+    </message>
+    <message>
+        <source>MESH_OR_SUBMESH</source>
+        <translation>Maillage ou sous-maillage</translation>
+    </message>
+    <message>
+        <source>PATTERN</source>
+        <translation>Motif</translation>
+    </message>
+    <message>
+        <source>PATTERN_FILT</source>
+        <translation>Fichiers de motif (*.smp)</translation>
+    </message>
+    <message>
+        <source>PATTERN_NAME</source>
+        <translation>Nom du motif</translation>
+    </message>
+    <message>
+        <source>PATTERN_TYPE</source>
+        <translation>Type du motif</translation>
+    </message>
+    <message>
+        <source>PROJECT</source>
+        <translation>Projeter les nÅ“uds sur la face</translation>
+    </message>
+    <message>
+        <source>SAVE</source>
+        <translation>Sauvegarder...</translation>
+    </message>
+    <message>
+        <source>SAVE_PATTERN</source>
+        <translation>Sauvegarder le motif</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_CreatePolyhedralVolumeDlg</name>
+    <message>
+        <source>FACES_BY_NODES</source>
+        <translation>Faces par nÅ“uds</translation>
+    </message>
+    <message>
+        <source>SMESH_POLYEDRE_CREATE_ERROR</source>
+        <translation>Erreur de création du polyèdre.</translation>
+    </message>
+    <message>
+        <source>SMESH_POLYEDRE_PREVIEW</source>
+        <translation>Prévisualiser le polyèdre</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_CuttingOfQuadsDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Découpe des quadrangles</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_DeleteGroupDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Supprimer les groupes et leur contenu</translation>
+    </message>
+    <message>
+        <source>NO_SELECTED_GROUPS</source>
+        <translation>Il n&apos;y a aucun groupe sélectionné
+Choisissez un groupe et essayez de nouveau</translation>
+    </message>
+    <message>
+        <source>SELECTED_GROUPS</source>
+        <translation>Groupes sélectionnés</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MergeDlg</name>
+    <message>
+        <source>COINCIDENT_ELEMENTS</source>
+        <translation>Eléments coïncidents</translation>
+    </message>
+    <message>
+        <source>COINCIDENT_NODES</source>
+        <translation>NÅ“uds coïncidents</translation>
+    </message>
+    <message>
+        <source>DETECT</source>
+        <translation>Détecter</translation>
+    </message>
+    <message>
+        <source>EDIT_SELECTED_GROUP</source>
+        <translation>Editer le groupe sélectionné</translation>
+    </message>
+    <message>
+        <source>SELECT_ALL</source>
+        <translation>Tout sélectionner</translation>
+    </message>
+    <message>
+        <source>EXCLUDE_GROUPS</source>
+        <translation>Exclure les groupes</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_ExtrusionAlongPathDlg</name>
+    <message>
+        <source>BAD_SHAPE_TYPE</source>
+        <translation>La géométrie choisie en tant que chemin n&apos;est pas une arête</translation>
+    </message>
+    <message>
+        <source>CANT_GET_TANGENT</source>
+        <translation>Impossible d&apos;obtenir la tangente pour un des nÅ“uds du chemin</translation>
+    </message>
+    <message>
+        <source>EXTRUSION_0D</source>
+        <translation>Extrusion des Ã©léments 0D</translation>
+    </message>
+    <message>
+        <source>EXTRUSION_1D</source>
+        <translation>Extrusion des Ã©léments 1D</translation>
+    </message>
+    <message>
+        <source>EXTRUSION_2D</source>
+        <translation>Extrusion des Ã©léments 2D</translation>
+    </message>
+    <message>
+        <source>EXTRUSION_ALONG_PATH</source>
+        <translation>Extrusion suivant un chemin</translation>
+    </message>
+    <message>
+        <source>EXTR_BAD_STARTING_NODE</source>
+        <translation>NÅ“ud de départ du chemin incorrect</translation>
+    </message>
+    <message>
+        <source>LINEAR_ANGLES</source>
+        <translation>Variation linéaire des angles</translation>
+    </message>
+    <message>
+        <source>NO_ELEMENTS_SELECTED</source>
+        <translation>Aucun Ã©lément de maillage n&apos;est sélectionné pour l&apos;extrusion</translation>
+    </message>
+    <message>
+        <source>SELECTED_PATH_IS_NOT_EDGE</source>
+        <translation>Le maillage du chemin doit Ãªtre du type arête</translation>
+    </message>
+    <message>
+        <source>SMESH_ANGLES</source>
+        <translation>Angles de rotation</translation>
+    </message>
+    <message>
+        <source>SMESH_BASE_POINT</source>
+        <translation>Point de base</translation>
+    </message>
+    <message>
+        <source>SMESH_PATH</source>
+        <translation>Chemin</translation>
+    </message>
+    <message>
+        <source>SMESH_PATH_MESH</source>
+        <translation>Maillage ou sous-maillage</translation>
+    </message>
+    <message>
+        <source>SMESH_PATH_SHAPE</source>
+        <translation>Géométrie (arête)</translation>
+    </message>
+    <message>
+        <source>SMESH_PATH_START</source>
+        <translation>NÅ“ud de début</translation>
+    </message>
+    <message>
+        <source>SMESH_USE_ANGLES</source>
+        <translation>Utiliser les angles</translation>
+    </message>
+    <message>
+        <source>SMESH_USE_BASE_POINT</source>
+        <translation>Utiliser le point de base</translation>
+    </message>
+    <message>
+        <source>WRONG_ANGLES_NUMBER</source>
+        <translation>Le nombre d&apos;angles doit correspondre au nombre des nÅ“uds du chemin</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_ExtrusionDlg</name>
+    <message>
+        <source>EXTRUSION_0D</source>
+        <translation>Extrusion de noeuds</translation>
+    </message>
+    <message>
+        <source>EXTRUSION_1D</source>
+        <translation>Extrusion des Ã©léments 1D</translation>
+    </message>
+    <message>
+        <source>EXTRUSION_2D</source>
+        <translation>Extrusion des Ã©léments 2D</translation>
+    </message>
+    <message>
+        <source>EXTRUSION_ALONG_LINE</source>
+        <translation>Extrusion suivant une ligne</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_FilterDlg</name>
+    <message>
+        <source>BAD_SHAPE_NAME</source>
+        <translation>Il n&apos;y a pas d&apos;objet géométrique &quot;%1&quot; dans l&apos;étude actuelle
+Sélectionnez un objet valide et essayez de nouveau</translation>
+    </message>
+    <message>
+        <source>CURRENT_DIALOG</source>
+        <translation>Groupe actuel</translation>
+    </message>
+    <message>
+        <source>EDGES_TLT</source>
+        <translation>Filtre d&apos;arêtes</translation>
+    </message>
+    <message>
+        <source>FACES_TLT</source>
+        <translation>Filtre de faces</translation>
+    </message>
+    <message>
+        <source>MESH</source>
+        <translation>Maillage</translation>
+    </message>
+    <message>
+        <source>NODES_TLT</source>
+        <translation>Filtre de nÅ“uds</translation>
+    </message>
+    <message>
+        <source>SELECTION</source>
+        <translation>Sélection initiale</translation>
+    </message>
+    <message>
+        <source>SET_IN_VIEWER</source>
+        <translation>Insérer le filtre dans la fenêtre 3D</translation>
+    </message>
+    <message>
+        <source>SHAPE_IS_NOT_A_CYLINDER</source>
+        <translation>&quot;%1&quot; n&apos;est pas une face cylindrique
+Sélectionnez une face cylindrique et essayez de nouveau</translation>
+    </message>
+    <message>
+        <source>SHAPE_IS_NOT_A_FACE</source>
+        <translation>&quot;%1&quot; n&apos;est pas une face
+Sélectionnez une face et essayez de nouveau</translation>
+    </message>
+    <message>
+        <source>SHAPE_IS_NOT_A_PLANE</source>
+        <translation>&quot;%1&quot; n&apos;est pas un plan
+Sélectionnez un plan et essayez de nouveau</translation>
+    </message>
+    <message>
+        <source>FACE_ID_NOT_SELECTED</source>
+        <translation>Aucune face de maillage n&apos;est sélectionnée.
+Indiquez-la et essayez de nouveau</translation>
+    </message>
+    <message>
+        <source>NOT_FACE_ID</source>
+        <translation>&quot;%1&quot; ne correspond Ã  aucun ID valide d&apos;une face du maillage.
+Sélectionnez une face et essayez de nouveau</translation>
+    </message>
+    <message>
+        <source>SOURCE</source>
+        <translation>Source</translation>
+    </message>
+    <message>
+        <source>TLT</source>
+        <translation>Filtre de sélection</translation>
+    </message>
+    <message>
+        <source>VOLUMES_TLT</source>
+        <translation>Filtre de volumes</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_FilterLibraryDlg</name>
+    <message>
+        <source>ADD</source>
+        <translation>Ajouter</translation>
+    </message>
+    <message>
+        <source>ADD_TO_TLT</source>
+        <translation>Ajouter le filtre de sélection Ã  la librairie</translation>
+    </message>
+    <message>
+        <source>ALL_FILES_FILTER</source>
+        <translation>Tous les fichiers (*.*)</translation>
+    </message>
+    <message>
+        <source>ASSIGN_NEW_NAME</source>
+        <translation>La librairie déjà contient un filtre avec le nom &quot;%1&quot;
+Le nouveau nom &quot;%2&quot; est attribué au filtre ajouté</translation>
+    </message>
+    <message>
+        <source>COPY_FROM_TLT</source>
+        <translation>Copier le filtre de la sélection de la librairie</translation>
+    </message>
+    <message>
+        <source>DELETE</source>
+        <translation>Supprimer</translation>
+    </message>
+    <message>
+        <source>EDGE</source>
+        <translation>Arête</translation>
+    </message>
+    <message>
+        <source>EDIT_LIB_TLT</source>
+        <translation>Librairie des filtres de sélection</translation>
+    </message>
+    <message>
+        <source>ELEMENT</source>
+        <translation>Elément</translation>
+    </message>
+    <message>
+        <source>EMPTY_FILTER_NAME</source>
+        <translation>Le nom du filtre est vide
+Indiquez un nom non-vide</translation>
+    </message>
+    <message>
+        <source>ERROR_FILTER_NAME</source>
+        <translation>Le nom du filtre n&apos;est pas unique
+Indiquez un autre nom</translation>
+    </message>
+    <message>
+        <source>ERROR_LOAD</source>
+        <translation>Il est impossible de charger la librairie
+Vérifiez le nom du fichier de la librairie et ses propriétés</translation>
+    </message>
+    <message>
+        <source>ERROR_OF_ADDING</source>
+        <translation>Une erreur interne s&apos;est produite Ã  l&apos;addition d&apos;un nouveau filtre dans la librairie.
+Vérifiez la validité des informations données</translation>
+    </message>
+    <message>
+        <source>ERROR_OF_COPYING</source>
+        <translation>Une erreur interne s&apos;est produite Ã  la copie d&apos;un filtre depuis la librairie.
+Vérifiez la validité des informations données</translation>
+    </message>
+    <message>
+        <source>ERROR_OF_DELETING</source>
+        <translation>Une erreur interne s&apos;est produite lors de la suppression d&apos;un filtre depuis la librairie.
+Vérifiez la validité des informations données</translation>
+    </message>
+    <message>
+        <source>ERROR_OF_EDITING</source>
+        <translation>Une erreur interne s&apos;est produite Ã  l&apos;édition d&apos;un filtre dans la librairie.
+Vérifiez la validité des informations données</translation>
+    </message>
+    <message>
+        <source>ERROR_OF_SAVING</source>
+        <translation>Une erreur s&apos;est produite Ã  la sauvegarde de la librairie des filtres.
+Vérifiez la validité des informations données</translation>
+    </message>
+    <message>
+        <source>FACE</source>
+        <translation>Face</translation>
+    </message>
+    <message>
+        <source>FILTER</source>
+        <translation>Filtre</translation>
+    </message>
+    <message>
+        <source>FILTER_NAME</source>
+        <translation>Nom du filtre</translation>
+    </message>
+    <message>
+        <source>FILTER_NAMES</source>
+        <translation>Noms des filtres</translation>
+    </message>
+    <message>
+        <source>LIBRARY_FILE</source>
+        <translation>Nom du fichier de librairie </translation>
+    </message>
+    <message>
+        <source>LIBRARY_IS_NOT_LOADED</source>
+        <translation>La librairie n&apos;est pas ouverte. Ouvrez la librairie et essayez de nouveau</translation>
+    </message>
+    <message>
+        <source>LIB_NAME</source>
+        <translation>FilterLib.xml</translation>
+    </message>
+    <message>
+        <source>NODE</source>
+        <translation>NÅ“ud</translation>
+    </message>
+    <message>
+        <source>NO_PERMISSION</source>
+        <translation>Vous n&apos;avez pas la permission d&apos;écrire dans ce fichier</translation>
+    </message>
+    <message>
+        <source>OPEN_LIBRARY</source>
+        <translation>Ouvrir la librairie</translation>
+    </message>
+    <message>
+        <source>SELECTION</source>
+        <translation>Sélection</translation>
+    </message>
+    <message>
+        <source>VOLUME</source>
+        <translation>Volume</translation>
+    </message>
+    <message>
+        <source>XML_FILT</source>
+        <translation>Fichiers XML (*.xml)</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_FilterTable</name>
+    <message>
+        <source>ADD</source>
+        <translation>Ajouter</translation>
+    </message>
+    <message>
+        <source>ADDITIONAL_PARAMETERS</source>
+        <translation>Paramètres supplémentaires</translation>
+    </message>
+    <message>
+        <source>ADD_TO</source>
+        <translation>Ajouter Ã ...</translation>
+    </message>
+    <message>
+        <source>AND</source>
+        <translation>Et</translation>
+    </message>
+    <message>
+        <source>AREA</source>
+        <translation>Aire</translation>
+    </message>
+    <message>
+        <source>ASPECT_RATIO</source>
+        <translation>Rapport de forme</translation>
+    </message>
+    <message>
+        <source>ASPECT_RATIO_3D</source>
+        <translation>Rapport de forme 3D</translation>
+    </message>
+    <message>
+        <source>BAD_ORIENTED_VOLUME</source>
+        <translation>Volume mal orienté</translation>
+    </message>
+    <message>
+        <source>BARE_BORDER_VOLUME</source>
+        <translation>Volumes avec Ã©léments de peau 2D manquants</translation>
+    </message>
+    <message>
+        <source>BARE_BORDER_FACE</source>
+        <translation>Faces avec Ã©léments de peau 1D manquants</translation>
+    </message>
+    <message>
+        <source>OVER_CONSTRAINED_VOLUME</source>
+        <translation>Volumes sur-contraints</translation>
+    </message>
+    <message>
+        <source>OVER_CONSTRAINED_FACE</source>
+        <translation>Faces sur-contraintes</translation>
+    </message>
+    <message>
+        <source>BELONG_TO_CYLINDER</source>
+        <translation>Appartient au cylindre</translation>
+    </message>
+    <message>
+        <source>BELONG_TO_GENSURFACE</source>
+        <translation>Appartient Ã  la surface</translation>
+    </message>
+    <message>
+        <source>BELONG_TO_GEOM</source>
+        <translation>Appartient Ã  la géométrie</translation>
+    </message>
+    <message>
+        <source>BELONG_TO_PLANE</source>
+        <translation>Appartient au plan</translation>
+    </message>
+    <message>
+        <source>BINARY</source>
+        <translation>Opérateur logique</translation>
+    </message>
+    <message>
+        <source>CLEAR</source>
+        <translation>Effacer</translation>
+    </message>
+    <message>
+        <source>COMPARE</source>
+        <translation>Comparer</translation>
+    </message>
+    <message>
+        <source>COPLANAR_FACES</source>
+        <translation>Faces coplanaires</translation>
+    </message>
+    <message>
+        <source>COPY_FROM</source>
+        <translation>Copier de...</translation>
+    </message>
+    <message>
+        <source>CRITERION</source>
+        <translation>Critère</translation>
+    </message>
+    <message>
+        <source>BALLS</source>
+        <translation>Particulaires</translation>
+    </message>
+    <message>
+        <source>EDGES</source>
+        <translation>Arêtes</translation>
+    </message>
+    <message>
+        <source>ENTITY_TYPE</source>
+        <translation>Type de l&apos;entité</translation>
+    </message>
+    <message>
+        <source>EQUAL_TO</source>
+        <translation>Egal Ã </translation>
+    </message>
+    <message>
+        <source>ERROR</source>
+        <translation>La valeur du seuil n&apos;est pas valide.
+Entrez une valeur correcte et essayez de nouveau</translation>
+    </message>
+    <message>
+        <source>FACES</source>
+        <translation>Faces</translation>
+    </message>
+    <message>
+        <source>FILTER</source>
+        <translation>Filtre</translation>
+    </message>
+    <message>
+        <source>FREE_BORDERS</source>
+        <translation>Bords libres</translation>
+    </message>
+    <message>
+        <source>FREE_EDGES</source>
+        <translation>Arêtes libres</translation>
+    </message>
+    <message>
+        <source>FREE_NODES</source>
+        <translation>NÅ“uds isolés</translation>
+    </message>
+    <message>
+        <source>FREE_FACES</source>
+        <translation>Faces libres</translation>
+    </message>
+    <message>
+        <source>ID</source>
+        <translation>ID</translation>
+    </message>
+    <message>
+        <source>INSERT</source>
+        <translation>Insérer</translation>
+    </message>
+    <message>
+        <source>LENGTH</source>
+        <translation>Longueur</translation>
+    </message>
+    <message>
+        <source>LENGTH2D</source>
+        <translation>Longueur 2D</translation>
+    </message>
+    <message>
+        <source>LESS_THAN</source>
+        <translation>Inférieur Ã  ...</translation>
+    </message>
+    <message>
+        <source>LYING_ON_GEOM</source>
+        <translation>Repose sur la géométrie</translation>
+    </message>
+    <message>
+        <source>MAX_ELEMENT_LENGTH_2D</source>
+        <translation>Diamètre d&apos;éléments 2D</translation>
+    </message>
+    <message>
+        <source>MAX_ELEMENT_LENGTH_3D</source>
+        <translation>Diamètre d&apos;éléments 3D</translation>
+    </message>
+    <message>
+        <source>MINIMUM_ANGLE</source>
+        <translation>Angle minimal</translation>
+    </message>
+    <message>
+        <source>MORE_THAN</source>
+        <translation>Supérieur Ã  ...</translation>
+    </message>
+    <message>
+        <source>MULTIEDGES_ERROR</source>
+        <translation>La valeur de seuil des bords multi-connectés ne peut pas Ãªtre Ã©gal Ã  1
+Entrez une valeur correcte et essayez de nouveau</translation>
+    </message>
+    <message>
+        <source>GROUPCOLOR_ERROR</source>
+        <translation>Impossible d&apos;identifier la couleur du groupe
+Entrez une valeur correcte et essayez de nouveau</translation>
+    </message>
+    <message>
+        <source>MULTI_BORDERS</source>
+        <translation>Bords multi-connectés</translation>
+    </message>
+    <message>
+        <source>NODES</source>
+        <translation>NÅ“uds</translation>
+    </message>
+    <message>
+        <source>NOT</source>
+        <translation>Non</translation>
+    </message>
+    <message>
+        <source>OR</source>
+        <translation>Ou</translation>
+    </message>
+    <message>
+        <source>RANGE_OF_IDS</source>
+        <translation>Liste d&apos;IDs</translation>
+    </message>
+    <message>
+        <source>REMOVE</source>
+        <translation>Supprimer</translation>
+    </message>
+    <message>
+        <source>SKEW</source>
+        <translation>Inclinaison </translation>
+    </message>
+    <message>
+        <source>TAPER</source>
+        <translation>Cône</translation>
+    </message>
+    <message>
+        <source>THRESHOLD_VALUE</source>
+        <translation>Valeur du seuil</translation>
+    </message>
+    <message>
+        <source>UNARY</source>
+        <translation>Négation</translation>
+    </message>
+    <message>
+        <source>VOLUMES</source>
+        <translation>Volumes</translation>
+    </message>
+    <message>
+        <source>VOLUME_3D</source>
+        <translation>Volume</translation>
+    </message>
+    <message>
+        <source>WARPING</source>
+        <translation>Déformation</translation>
+    </message>
+    <message>
+        <source>LINEAR</source>
+        <translation>Linéaire</translation>
+    </message>
+    <message>
+        <source>GROUP_COLOR</source>
+        <translation>Couleur du groupe</translation>
+    </message>
+    <message>
+        <source>ELEMENTS</source>
+        <translation>Eléments</translation>
+    </message>
+    <message>
+        <source>GEOM_TYPE</source>
+        <translation>Type de géométrie</translation>
+    </message>
+    <message>
+        <source>GEOM_TYPE_0</source>
+        <translation>Point</translation>
+    </message>
+    <message>
+        <source>GEOM_TYPE_1</source>
+        <translation>Arête</translation>
+    </message>
+    <message>
+        <source>GEOM_TYPE_2</source>
+        <translation>Triangle</translation>
+    </message>
+    <message>
+        <source>GEOM_TYPE_3</source>
+        <translation>Quadrangle</translation>
+    </message>
+    <message>
+        <source>GEOM_TYPE_4</source>
+        <translation>Polygone</translation>
+    </message>
+    <message>
+        <source>GEOM_TYPE_5</source>
+        <translation>Tétraèdre</translation>
+    </message>
+    <message>
+        <source>GEOM_TYPE_6</source>
+        <translation>Pyramide</translation>
+    </message>
+    <message>
+        <source>GEOM_TYPE_7</source>
+        <translation>Hexaèdre</translation>
+    </message>
+    <message>
+        <source>GEOM_TYPE_8</source>
+        <translation>Pentaèdre</translation>
+    </message>
+    <message>
+        <source>GEOM_TYPE_9</source>
+        <translation>Prisme hexagonal</translation>
+    </message>
+    <message>
+        <source>GEOM_TYPE_10</source>
+        <translation>Polyèdre</translation>
+    </message>
+    <message>
+        <source>GEOM_TYPE_11</source>
+        <translation>Particulaire</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_GroupOpDlg</name>
+    <message>
+        <source>ARGUMENTS</source>
+        <translation>Arguments</translation>
+    </message>
+    <message>
+        <source>DIFF_MESHES</source>
+        <translation>Les arguments de l&apos;opération ne sont pas indiqués correctement
+Les groupes correspondent Ã  des maillages différents
+Donnez des arguments valides et essayez de nouveau</translation>
+    </message>
+    <message>
+        <source>DIFF_TYPES</source>
+        <translation>Les arguments de l&apos;opération ne sont pas indiqués correctement
+Les groupes contiennent des Ã©léments de types différents
+Donnez des arguments valides et essayez de nouveau</translation>
+    </message>
+    <message>
+        <source>EMPTY_NAME</source>
+        <translation>Le nom du groupe est invalide
+Indiquez un nom non-vide et essayez de nouveau</translation>
+    </message>
+    <message>
+        <source>INCORRECT_ARGUMENTS</source>
+        <translation>Les arguments de l&apos;opération ne sont pas indiqués
+Indiquez-les et essayez de nouveau</translation>
+    </message>
+    <message>
+        <source>NAME</source>
+        <translation>Nom</translation>
+    </message>
+    <message>
+        <source>OBJECT_1</source>
+        <translation>Objet 1</translation>
+    </message>
+    <message>
+        <source>OBJECT_2</source>
+        <translation>Objet 2</translation>
+    </message>
+    <message>
+        <source>RESULT_NAME</source>
+        <translation>Nom du résultat</translation>
+    </message>
+    <message>
+        <source>TOOL_OBJECT</source>
+        <translation>Outil</translation>
+    </message>
+    <message>
+        <source>UNION_OF_TWO_GROUPS</source>
+        <translation>Union de deux groupes</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_UnionGroupsDlg</name>
+    <message>
+        <source>UNION_OF_GROUPS</source>
+        <translation>Union de groupes</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_DimGroupDlg</name>
+    <message>
+        <source>CREATE_GROUP_OF_UNDERLYING_ELEMS</source>
+        <translation>Créer un groupe d&apos;entités sous-jacentes</translation>
+    </message>
+    <message>
+        <source>ELEMENTS_TYPE</source>
+        <translation>Type d&apos;éléments </translation>
+    </message>
+    <message>
+        <source>NODE</source>
+        <translation>NÅ“ud</translation>
+    </message>
+    <message>
+        <source>EDGE</source>
+        <translation>Arête</translation>
+    </message>
+    <message>
+        <source>FACE</source>
+        <translation>Face</translation>
+    </message>
+    <message>
+        <source>VOLUME</source>
+        <translation>Volume</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_IntersectGroupsDlg</name>
+    <message>
+        <source>INTERSECTION_OF_GROUPS</source>
+        <translation>Intersection de groupes</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_CutGroupsDlg</name>
+    <message>
+        <source>CUT_OF_GROUPS</source>
+        <translation>Différence de groupes</translation>
+    </message>
+    <message>
+        <source>MAIN_OBJECT</source>
+        <translation>Objet principal</translation>
+    </message>
+    <message>
+        <source>TOOL_OBJECT</source>
+        <translation>Objet outil</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MakeNodeAtPointDlg</name>
+    <message>
+        <source>AUTO_SEARCH</source>
+        <translation>Trouver le nÅ“ud le plus proche de la destination</translation>
+    </message>
+    <message>
+        <source>CAPTION</source>
+        <translation>Déplacer un nÅ“ud</translation>
+    </message>
+    <message>
+        <source>DESTINATION</source>
+        <translation>Destination</translation>
+    </message>
+    <message>
+        <source>MOVE_NODE</source>
+        <translation>Déplacer un nÅ“ud</translation>
+    </message>
+    <message>
+        <source>METHOD</source>
+        <translation>Méthode</translation>
+    </message>
+    <message>
+        <source>NODE_2MOVE</source>
+        <translation>NÅ“ud Ã  déplacer</translation>
+    </message>
+    <message>
+        <source>NODE_2MOVE_ID</source>
+        <translation>ID</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MakeNodeAtPointOp</name>
+    <message>
+        <source>INVALID_ID</source>
+        <translation>L&apos;ID du nÅ“ud est invalide</translation>
+    </message>
+    <message>
+        <source>INVALID_MESH</source>
+        <translation>Le maillage Ã  modifier n&apos;est pas sélectionné</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_FindElemByPointDlg</name>
+    <message>
+        <source>MESH_GROUP</source>
+        <translation>Maillage ou groupe</translation>
+    </message>
+    <message>
+        <source>CAPTION</source>
+        <translation>Trouver un Ã©lément par un point</translation>
+    </message>
+    <message>
+        <source>CREATE_NEW_METHOD</source>
+        <translation>Créer un nÅ“ud</translation>
+    </message>
+    <message>
+        <source>MESH_PASS_THROUGH_POINT</source>
+        <translation>Créer un nÅ“ud au point</translation>
+    </message>
+    <message>
+        <source>METHOD</source>
+        <translation>Méthode</translation>
+    </message>
+    <message>
+        <source>MOVE_EXISTING_METHOD</source>
+        <translation>Déplacer un nÅ“ud</translation>
+    </message>
+    <message>
+        <source>NODE_2MOVE</source>
+        <translation>NÅ“ud Ã  déplacer</translation>
+    </message>
+    <message>
+        <source>NODE_2MOVE_ID</source>
+        <translation>ID</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MeshDlg</name>
+    <message>
+        <source>CREATE_MESH</source>
+        <translation>Créer un maillage</translation>
+    </message>
+    <message>
+        <source>CREATE_SUBMESH</source>
+        <translation>Créer un sous-maillage</translation>
+    </message>
+    <message>
+        <source>DIM_0D</source>
+        <translation>0D</translation>
+    </message>
+    <message>
+        <source>DIM_1D</source>
+        <translation>1D</translation>
+    </message>
+    <message>
+        <source>DIM_2D</source>
+        <translation>2D</translation>
+    </message>
+    <message>
+        <source>DIM_3D</source>
+        <translation>3D</translation>
+    </message>
+    <message>
+        <source>EDIT_MESH_SUBMESH</source>
+        <translation>Editer un maillage/sous-maillage</translation>
+    </message>
+    <message>
+        <source>GEOMETRY</source>
+        <translation>Géométrie</translation>
+    </message>
+    <message>
+        <source>HYPOTHESES_SETS</source>
+        <translation>Attribuer un jeu d&apos;hypothèses</translation>
+    </message>
+    <message>
+        <source>MESH</source>
+        <translation>Maillage</translation>
+    </message>
+    <message>
+        <source>NAME</source>
+        <translation>Nom</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MeshOp</name>
+    <message>
+        <source>ALGORITHM_WITHOUT_HYPOTHESIS</source>
+        <translation>L&apos;algorithme pour la dimension %1 est défini mais l&apos;hypothèse ne l&apos;est pas</translation>
+    </message>
+    <message>
+        <source>EDIT_SUBMESH_QUESTION</source>
+        <translation>Un sous-maillage existe déjà sur la géométrie choisie
+Voulez-vous Ã©diter ce sous-maillage?</translation>
+    </message>
+    <message>
+        <source>SUBMESH_NOT_ALLOWED</source>
+        <translation>Créer un sous-maillage ignoré par l&apos;algorithme global n&apos;a pas de sens &quot;%1&quot;</translation>
+    </message>
+    <message>
+        <source>GEOMETRY_OBJECT_IS_NOT_DEFINED</source>
+        <translation>L&apos;objet géométrique n&apos;est pas défini
+Indiquez-le et essayez de nouveau</translation>
+    </message>
+    <message>
+        <source>GEOMETRY_OBJECT_IS_NULL</source>
+        <translation>L&apos;objet géométrique est nul</translation>
+    </message>
+    <message>
+        <source>HYPOTHESES_AND_ALGORITHMS_ARE_NOT_DEFINED</source>
+        <translation>Les hypothèses et les algorithmes ne sont pas définis</translation>
+    </message>
+    <message>
+        <source>HYPOTHESIS_WITHOUT_ALGORITHM</source>
+        <translation>L&apos;hypothèse est définie pour la dimension %1 mais l&apos;algorithme n&apos;est pas défini</translation>
+    </message>
+    <message>
+        <source>IMPORTED_MESH</source>
+        <translation>Le maillage n&apos;est pas construit sur une géométrie</translation>
+    </message>
+    <message>
+        <source>INVALID_SUBSHAPE</source>
+        <translation>L&apos;objet géométrique n&apos;est pas un sous-objet de l&apos;objet maillé</translation>
+    </message>
+    <message>
+        <source>MESH_IS_NOT_DEFINED</source>
+        <translation>Le maillage n&apos;est pas défini
+Spécifiez-le et essayez de nouveau</translation>
+    </message>
+    <message>
+        <source>MESH_IS_NULL</source>
+        <translation>Le maillage est nul</translation>
+    </message>
+    <message>
+        <source>NAME_OF_MESH_IS_EMPTY</source>
+        <translation>Le nom du maillage est vide
+Indiquez un nom valide et essayez de nouveau</translation>
+    </message>
+    <message>
+        <source>NAME_OF_SUBMESH_IS_EMPTY</source>
+        <translation>Le nom du sous-maillage est vide
+Indiquez un nom valide et essayez de nouveau</translation>
+    </message>
+    <message>
+        <source>THERE_IS_NO_OBJECT_FOR_EDITING</source>
+        <translation>Il n&apos;y a pas d&apos;objet Ã  Ã©diter.
+Sélectionnez un maillage ou un sous-maillage et essayez de nouveau</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MeshPatternDlg</name>
+    <message>
+        <source>3D_BLOCK</source>
+        <translation>Bloc 3D</translation>
+    </message>
+    <message>
+        <source>CAPTION</source>
+        <translation>Projection de motif</translation>
+    </message>
+    <message>
+        <source>CREATE_POLYEDRS_NEAR_BOUNDARY</source>
+        <translation>Créer des polyèdres près de la frontière</translation>
+    </message>
+    <message>
+        <source>CREATE_POLYGONS_NEAR_BOUNDARY</source>
+        <translation>Créer des polygones près de la frontière</translation>
+    </message>
+    <message>
+        <source>ERROR_OF_LOADING</source>
+        <translation>Impossible de charger le motif.
+Il est probable que le fichier est corrompu ou contient un autre type de motif</translation>
+    </message>
+    <message>
+        <source>ERROR_OF_OPENING</source>
+        <translation>Il est impossible d&apos;ouvrir le fichier. 
+Vérifiez s&apos;il existe et si vous avez l&apos;autorisation</translation>
+    </message>
+    <message>
+        <source>ERROR_OF_READING</source>
+        <translation>Il est impossible de charger le motif
+Vérifiez le contenu du fichier</translation>
+    </message>
+    <message>
+        <source>ERR_READ_3D_COORD</source>
+        <translation>Il est impossible de charger le motif
+Les coordonnées des points 3D sont en dehors de l&apos;intervalle [0,1]</translation>
+    </message>
+    <message>
+        <source>ERR_READ_BAD_INDEX</source>
+        <translation>Il est impossible de charger le motif
+Un index de point invalide a Ã©té detecté</translation>
+    </message>
+    <message>
+        <source>ERR_READ_BAD_KEY_POINT</source>
+        <translation>Il est impossible de charger le motif
+Le point-clef n&apos;est pas situé sur la frontière</translation>
+    </message>
+    <message>
+        <source>ERR_READ_ELEM_POINTS</source>
+        <translation>Il est impossible de charger le motif
+Le nombre de points de l&apos;élément est invalide</translation>
+    </message>
+    <message>
+        <source>ERR_READ_NB_POINTS</source>
+        <translation>Il est impossible de charger le motif
+Il est impossible de lire le nombre de points dans le fichier</translation>
+    </message>
+    <message>
+        <source>ERR_READ_NO_ELEMS</source>
+        <translation>Il est impossible de charger le motif
+Il ne contient pas d&apos;éléments</translation>
+    </message>
+    <message>
+        <source>ERR_READ_NO_KEYPOINT</source>
+        <translation>Il est impossible de charger le motif
+Le motif 2D n&apos;a pas de point-clef</translation>
+    </message>
+    <message>
+        <source>ERR_READ_POINT_COORDS</source>
+        <translation>Il est impossible de charger le motif
+Il est impossible de lire les coordonnées des points dans le fichier</translation>
+    </message>
+    <message>
+        <source>ERR_READ_TOO_FEW_POINTS</source>
+        <translation>Il est impossible de charger le motif. 
+Il y a trop peu de points dans le fichier </translation>
+    </message>
+    <message>
+        <source>FACE</source>
+        <translation>Face</translation>
+    </message>
+    <message>
+        <source>LOAD_PATTERN</source>
+        <translation>Charger un motif</translation>
+    </message>
+    <message>
+        <source>MESH_FACES</source>
+        <translation>Faces du maillage</translation>
+    </message>
+    <message>
+        <source>MESH_VOLUMES</source>
+        <translation>Volumes du maillage</translation>
+    </message>
+    <message>
+        <source>NEW</source>
+        <translation>Nouveau...</translation>
+    </message>
+    <message>
+        <source>NODE_1</source>
+        <translation>NÅ“ud 1</translation>
+    </message>
+    <message>
+        <source>NODE_2</source>
+        <translation>NÅ“ud 2</translation>
+    </message>
+    <message>
+        <source>PATTERN</source>
+        <translation>Motif</translation>
+    </message>
+    <message>
+        <source>PATTERN_FILT</source>
+        <translation>Fichiers de motif (*.smp)</translation>
+    </message>
+    <message>
+        <source>PATTERN_TYPE</source>
+        <translation>Type de motif</translation>
+    </message>
+    <message>
+        <source>PREVIEW</source>
+        <translation>Prévisualiser</translation>
+    </message>
+    <message>
+        <source>REFINE</source>
+        <translation>Raffiner les Ã©léments de maillage sélectionnés</translation>
+    </message>
+    <message>
+        <source>REVERSE</source>
+        <translation>Inverser l&apos;ordre des points-clefs</translation>
+    </message>
+    <message>
+        <source>VERTEX</source>
+        <translation>Sommet...</translation>
+    </message>
+    <message>
+        <source>VERTEX1</source>
+        <translation>Sommet 1</translation>
+    </message>
+    <message>
+        <source>VERTEX2</source>
+        <translation>Sommet 2</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MeshTab</name>
+    <message>
+        <source>ADD_HYPOTHESIS</source>
+        <translation>Ajouter l&apos;hypothèse</translation>
+    </message>
+    <message>
+        <source>ALGORITHM</source>
+        <translation>Algorithme</translation>
+    </message>
+    <message>
+        <source>HYPOTHESIS</source>
+        <translation>Hypothèse</translation>
+    </message>
+    <message>
+        <source>NONE</source>
+        <translation>&lt;None&gt;</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MultiEditDlg</name>
+    <message>
+        <source>ADD</source>
+        <translation>Ajouter</translation>
+    </message>
+    <message>
+        <source>FILTER</source>
+        <translation>Filtre</translation>
+    </message>
+    <message>
+        <source>REMOVE</source>
+        <translation>Supprimer</translation>
+    </message>
+    <message>
+        <source>SELECT_FROM</source>
+        <translation>Sélectionner Ã  partir de</translation>
+    </message>
+    <message>
+        <source>SORT_LIST</source>
+        <translation>Trier la liste</translation>
+    </message>
+    <message>
+        <source>SPLIT_JOIN_CRITERION</source>
+        <translation>Critère</translation>
+    </message>
+    <message>
+        <source>TO_ALL</source>
+        <translation>Appliquer Ã  tous</translation>
+    </message>
+    <message>
+        <source>USE_DIAGONAL_1_3</source>
+        <translation>Utiliser la diagonale 1-3</translation>
+    </message>
+    <message>
+        <source>USE_DIAGONAL_2_4</source>
+        <translation>Utiliser la diagonale 2-4</translation>
+    </message>
+    <message>
+        <source>USE_NUMERIC_FUNC</source>
+        <translation>Utiliser le facteur numérique</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_CuttingIntoTetraDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Diviser les volumes en tétraèdres</translation>
+    </message>
+    <message>
+        <source>SPLIT_METHOD</source>
+        <translation>Diviser l&apos;hexaèdre</translation>
+    </message>
+    <message>
+        <source>SPLIT_HEX_TO_5_TETRA</source>
+        <translation>En 5 tétraèdres</translation>
+    </message>
+    <message>
+        <source>SPLIT_HEX_TO_6_TETRA</source>
+        <translation>En 6 tétraèdres</translation>
+    </message>
+    <message>
+        <source>SPLIT_HEX_TO_24_TETRA</source>
+        <translation>En 24 tétraèdres</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_PrecisionDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Précision pour les contrôles de qualité du maillage</translation>
+    </message>
+    <message>
+        <source>NOT_USE</source>
+        <translation>Ne pas utiliser!</translation>
+    </message>
+    <message>
+        <source>PRECISION</source>
+        <translation>Nombre de chiffres après la virgule</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_RevolutionDlg</name>
+    <message>
+        <source>ANGLE_BY_STEP</source>
+        <translation>Angle par pas</translation>
+    </message>
+    <message>
+        <source>PREVIEW</source>
+        <translation>Prévisualiser</translation>
+    </message>
+    <message>
+        <source>REVOLUTION_1D</source>
+        <translation>Révolution des Ã©léments 1D</translation>
+    </message>
+    <message>
+        <source>REVOLUTION_2D</source>
+        <translation>Révolution des Ã©léments 2D</translation>
+    </message>
+    <message>
+        <source>REVOLUTION_AROUND_AXIS</source>
+        <translation>Révolution autour d&apos;un axe</translation>
+    </message>
+    <message>
+        <source>TOTAL_ANGLE</source>
+        <translation>Angle total</translation>
+    </message>
+    <message>
+        <source>MEN_POINT_SELECT</source>
+        <translation>De l&apos;origine au point sélectionner</translation>
+    </message>
+    <message>
+        <source>MEN_FACE_SELECT</source>
+        <translation>Normale de la face sélectionnée</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_SewingDlg</name>
+    <message>
+        <source>BORDER</source>
+        <translation>Frontière</translation>
+    </message>
+    <message>
+        <source>BORDER_1</source>
+        <translation>Frontière 1</translation>
+    </message>
+    <message>
+        <source>BORDER_2</source>
+        <translation>Frontière 2</translation>
+    </message>
+    <message>
+        <source>CREATE_POLYEDRS_NEAR_BOUNDARY</source>
+        <translation>Remplacer les volumes concernés par des polyèdres</translation>
+    </message>
+    <message>
+        <source>CREATE_POLYGONS_INSTEAD_SPLITTING</source>
+        <translation>Créer des polygones au lieu de redécouper</translation>
+    </message>
+    <message>
+        <source>ERROR_1</source>
+        <translation>La frontière Libre1 n&apos;est pas trouvée avec les nÅ“uds sélectionnés</translation>
+    </message>
+    <message>
+        <source>ERROR_2</source>
+        <translation>La frontière Libre2 n&apos;est pas trouvée avec les nÅ“uds sélectionnés</translation>
+    </message>
+    <message>
+        <source>ERROR_3</source>
+        <translation>Les frontières Libres 1 et 2 n&apos;ont pas Ã©té trouvées avec les nÅ“uds sélectionnés</translation>
+    </message>
+    <message>
+        <source>ERROR_4</source>
+        <translation>Aucun chemin du premier au dernier nÅ“ud de la frontière n&apos;est trouvé</translation>
+    </message>
+    <message>
+        <source>ERROR_5</source>
+        <translation>Il n&apos;est pas permis de découper les volumes de bord!</translation>
+    </message>
+    <message>
+        <source>ERROR_6</source>
+        <translation>Le nombre d&apos;éléments sélectionnés est différent de chaque côté</translation>
+    </message>
+    <message>
+        <source>ERROR_7</source>
+        <translation>Les jeux d&apos;éléments sont topologiquement différents ou les nÅ“uds ne conviennent pas</translation>
+    </message>
+    <message>
+        <source>ERROR_8</source>
+        <translation>Les nÅ“uds du côté 1 soit ne sont pas connectés soit ne sont pas situés Ã  la frontière du jeu d&apos;éléments</translation>
+    </message>
+    <message>
+        <source>ERROR_9</source>
+        <translation>Les nÅ“uds du côté 2 soit ne sont pas connectés soit ne sont pas situés Ã  la frontière de l&apos;élément</translation>
+    </message>
+    <message>
+        <source>FIRST_NODE_ID</source>
+        <translation>ID du premier nÅ“ud </translation>
+    </message>
+    <message>
+        <source>LAST_NODE_ID</source>
+        <translation>ID du dernier nÅ“ud</translation>
+    </message>
+    <message>
+        <source>MERGE_EQUAL_ELEMENTS</source>
+        <translation>Fusionner les Ã©léments Ã©gaux</translation>
+    </message>
+    <message>
+        <source>NODE1_TO_MERGE</source>
+        <translation>NÅ“ud 1 Ã  fusionner</translation>
+    </message>
+    <message>
+        <source>NODE2_TO_MERGE</source>
+        <translation>NÅ“ud 2 Ã  fusionner</translation>
+    </message>
+    <message>
+        <source>SECOND_NODE_ID</source>
+        <translation>ID du deuxième nÅ“ud</translation>
+    </message>
+    <message>
+        <source>SEW_BORDER_TO_SIDE</source>
+        <translation>Coudre la frontière au côté</translation>
+    </message>
+    <message>
+        <source>SEW_CONFORM_FREE_BORDERS</source>
+        <translation>Coudre les frontières libres conformes</translation>
+    </message>
+    <message>
+        <source>SEW_FREE_BORDERS</source>
+        <translation>Coudre les frontières libres</translation>
+    </message>
+    <message>
+        <source>SEW_SIDE_ELEMENTS</source>
+        <translation>Coudre les Ã©léments de bord</translation>
+    </message>
+    <message>
+        <source>SIDE</source>
+        <translation>Bord</translation>
+    </message>
+    <message>
+        <source>SIDE_1</source>
+        <translation>Bord 1</translation>
+    </message>
+    <message>
+        <source>SIDE_2</source>
+        <translation>Bord 2</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_ShapeByMeshDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Trouver la géométrie par le maillage</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_SingleEditDlg</name>
+    <message>
+        <source>EDGE_BETWEEN</source>
+        <translation>Arête entre des triangles voisins</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_SmoothingDlg</name>
+    <message>
+        <source>CENTROIDAL</source>
+        <translation>Centroïdal</translation>
+    </message>
+    <message>
+        <source>FIXED_NODES_IDS</source>
+        <translation>IDs des nÅ“uds fixes</translation>
+    </message>
+    <message>
+        <source>IS_PARAMETRIC</source>
+        <translation>dans l&apos;espace paramétrique</translation>
+    </message>
+    <message>
+        <source>ITERATION_LIMIT</source>
+        <translation>Limite d&apos;Itération </translation>
+    </message>
+    <message>
+        <source>LAPLACIAN</source>
+        <translation>Laplacien</translation>
+    </message>
+    <message>
+        <source>MAX_ASPECT_RATIO</source>
+        <translation>Rapport de forme maximal</translation>
+    </message>
+    <message>
+        <source>METHOD</source>
+        <translation>Méthode</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_TrianglesInversionDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Inversion de diagonale</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_UnionOfTrianglesDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Union des triangles</translation>
+    </message>
+    <message>
+        <source>MAXIMUM_ANGLE</source>
+        <translation>Angle maximal de pliage</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_UnionOfTwoTrianglesDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Union de deux triangles</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_FileInfoDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Informations sur le fichier</translation>
+    </message>
+    <message>
+        <source>FILE_NAME</source>
+        <translation>Nom du fichier</translation>
+    </message>
+    <message>
+        <source>FILE_SIZE</source>
+        <translation>Taille du fichier (bytes)</translation>
+    </message>
+    <message>
+        <source>MED_VERSION</source>
+        <translation>Version MED</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_GroupOnShapeDlg</name>
+    <message>
+        <source>SMESH_CREATE_GROUP_FROM_GEOM</source>
+        <translation>Créer des groupes Ã  partir de la géométrie</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MeshOrderDlg</name>
+    <message>
+        <source>SMESH_MESHORDER_TITLE</source>
+        <translation>Ordre des sous-maillages dans la procédure de maillage</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MeshOrderOp</name>
+    <message>
+        <source>SMESH_NO_CONCURENT_MESH</source>
+        <translation>Pas de sous-maillages concurrents détectés</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_ClippingDlg</name>
+    <message>
+        <source>CLIP_PLANES</source>
+        <translation>Plans de découpe</translation>
+    </message>
+    <message>
+        <source>MESHES_SUBMESHES_GROUPS</source>
+        <translation>Maillages, sous-maillages et groupes</translation>
+    </message>
+    <message>
+        <source>SELECT_ALL</source>
+        <translation>Tout sélectionner</translation>
+    </message>
+    <message>
+        <source>ROTATION_AROUND_X_Y2Z</source>
+        <translation>Rotation autour de X (Y Ã  Z):</translation>
+    </message>
+    <message>
+        <source>ROTATION_AROUND_Y_X2Z</source>
+        <translation>Rotation autour de Y (X Ã  Z):</translation>
+    </message>
+    <message>
+        <source>ROTATION_AROUND_Z_Y2X</source>
+        <translation>Rotation autour de Z (Y Ã  X):</translation>
+    </message>
+    <message>
+        <source>ROTATION_AROUND_X_Z2Y</source>
+        <translation>Rotation autour de X (Z Ã  Y):</translation>
+    </message>
+    <message>
+        <source>ROTATION_AROUND_Y_Z2X</source>
+        <translation>Rotation autour de Y (Z Ã  X):</translation>
+    </message>
+    <message>
+        <source>ROTATION_AROUND_Z_X2Y</source>
+        <translation>Rotation autour de Z (X Ã  Y):</translation>
+    </message>
+    <message>
+        <source>SHOW_PREVIEW</source>
+        <translation>Prévisualiser</translation>
+    </message>
+    <message>
+        <source>AUTO_APPLY</source>
+        <translation>Appliquer automatiquement</translation>
+    </message>
+    <message>
+        <source>ALONG_XY</source>
+        <translation>|| X-Y</translation>
+    </message>
+    <message>
+        <source>ALONG_YZ</source>
+        <translation>|| Y-Z</translation>
+    </message>
+    <message>
+        <source>ALONG_ZX</source>
+        <translation>|| Z-X</translation>
+    </message>
+    <message>
+        <source>PLANE_NUM</source>
+        <translation>Plan# %1</translation>
+    </message>
+    <message>
+        <source>NO_PLANES</source>
+        <translation>Pas de plans</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_DuplicateNodesDlg</name>
+    <message>
+        <source>DUPLICATION_MODE</source>
+        <translation>Mode de duplication</translation>
+    </message>
+    <message>
+        <source>DUPLICATION_WITHOUT_ELEMS</source>
+        <translation>Sans duplication des Ã©léments de frontière</translation>
+    </message>
+    <message>
+        <source>GROUP_NODES_TO_DUPLICATE</source>
+        <translation>Groupe des nÅ“uds Ã  dupliquer</translation>
+    </message>
+    <message>
+        <source>GROUP_NODES_TO_REPLACE</source>
+        <translation>Groupe des Ã©léments dont les nÅ“uds sont Ã  remplacer</translation>
+    </message>
+    <message>
+        <source>DUPLICATION_WITH_ELEMS</source>
+        <translation>Avec duplication des Ã©léments de frontière</translation>
+    </message>
+    <message>
+        <source>GROUP_ELEMS_TO_DUPLICATE</source>
+        <translation>Groupe des Ã©léments Ã  dupliquer</translation>
+    </message>
+    <message>
+        <source>GROUP_NODES_NOT_DUPLICATE</source>
+        <translation>Groupe des nÅ“uds Ã  ne pas dupliquer</translation>
+    </message>
+    <message>
+        <source>GROUP_ELEMS_TO_REPLACE</source>
+        <translation>Groupe des Ã©léments dont les nÅ“uds sont Ã  remplacer</translation>
+    </message>
+    <message>
+        <source>CONSTRUCT_NEW_GROUP_NODES</source>
+        <translation>Construire un groupe avec les nÅ“uds nouvellement créés</translation>
+    </message>
+    <message>
+        <source>CONSTRUCT_NEW_GROUP_ELEMENTS</source>
+        <translation>Construire un groupe avec les Ã©léments nouvellement créés</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_Make2DFrom3DDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Créer les Ã©léments de frontière</translation>
+    </message>
+    <message>
+        <source>Groups</source>
+        <translation>Groupes 2D</translation>
+    </message>
+    <message>
+        <source>MODE</source>
+        <translation>Mode</translation>
+    </message>
+    <message>
+        <source>2D_FROM_3D</source>
+        <translation>2D Ã  partir de 3D</translation>
+    </message>
+    <message>
+        <source>1D_FROM_3D</source>
+        <translation>1D Ã  partir de groupes 2D</translation>
+    </message>
+    <message>
+        <source>1D_FROM_2D</source>
+        <translation>1D Ã  partir de 2D</translation>
+    </message>
+    <message>
+        <source>TARGET</source>
+        <translation>Cible</translation>
+    </message>
+    <message>
+        <source>THIS_MESH</source>
+        <translation>Ce maillage</translation>
+    </message>
+    <message>
+        <source>NEW_MESH</source>
+        <translation>Nouveau maillage</translation>
+    </message>
+    <message>
+        <source>COPY_SRC</source>
+        <translation>Copier le maillage source</translation>
+    </message>
+    <message>
+        <source>MISSING_ONLY</source>
+        <translation>Copier seulement les Ã©léments manquants</translation>
+    </message>
+    <message>
+        <source>CREATE_GROUP</source>
+        <translation>Créer un groupe</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_Make2DFrom3DOp</name>
+    <message>
+        <source>NB_ADDED</source>
+        <translation>%1 Ã©léments de bord ont Ã©té ajoutés</translation>
+    </message>
+    <message>
+        <source>WRONG_GROUPS</source>
+        <translation>Les groupes suivants n&apos;ont pas Ã©té traités
+en raison de leurs types incompatibles:
+%1</translation>
+    </message>
+    <message>
+        <source>SMESH_ERR_NO_INPUT_MESH</source>
+        <translation>Aucun maillage, sous-maillage ou groupe source n&apos;est indiqué</translation>
+    </message>
+    <message>
+        <source>SMESH_TOO_MANY_MESHES</source>
+        <translation>Un seul maillage Ã  la fois peut Ãªtre traité</translation>
+    </message>
+    <message>
+        <source>SMESH_NOT_ONLY_GROUPS</source>
+        <translation>Impossible de traiter Ã  la fois des maillages et des groupes</translation>
+    </message>
+    <message>
+        <source>SMESH_ERR_NO_3D_ELEMENTS</source>
+        <translation>L&apos;objet source ne contient pas d&apos;éléments 3D</translation>
+    </message>
+    <message>
+        <source>SMESH_ERR_NO_2D_ELEMENTS</source>
+        <translation>L&apos;objet source ne contient pas d&apos;éléments 2D</translation>
+    </message>
+    <message>
+        <source>SMESH_ERR_MESH_NAME_NOT_SPECIFIED</source>
+        <translation>Le nom du nouveau maillage n&apos;est pas indiqué</translation>
+    </message>
+    <message>
+        <source>SMESH_ERR_GRP_NAME_NOT_SPECIFIED</source>
+        <translation>Le nom du groupe n&apos;est pas indiqué</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MeshInfo</name>
+    <message>
+        <source>NAME_LAB</source>
+        <translation>Nom:</translation>
+    </message>
+    <message>
+        <source>OBJECT_LAB</source>
+        <translation>Objet:</translation>
+    </message>
+    <message>
+        <source>NODES_LAB</source>
+        <translation>NÅ“uds:</translation>
+    </message>
+    <message>
+        <source>ELEMENTS_LAB</source>
+        <translation>Eléments:</translation>
+    </message>
+    <message>
+        <source>TOTAL_LAB</source>
+        <translation>Total</translation>
+    </message>
+    <message>
+        <source>LINEAR_LAB</source>
+        <translation>Linéaire</translation>
+    </message>
+    <message>
+        <source>QUADRATIC_LAB</source>
+        <translation>Quadratique</translation>
+    </message>
+    <message>
+        <source>0D_LAB</source>
+        <translation>0D:</translation>
+    </message>
+    <message>
+        <source>BALL_LAB</source>
+        <translation>Particulaires:</translation>
+    </message>
+    <message>
+        <source>1D_LAB</source>
+        <translation>1D (arêtes):</translation>
+    </message>
+    <message>
+        <source>2D_LAB</source>
+        <translation>2D (faces):</translation>
+    </message>
+    <message>
+        <source>TRIANGLES_LAB</source>
+        <translation>Triangles:</translation>
+    </message>
+    <message>
+        <source>QUADRANGLES_LAB</source>
+        <translation>Quadrangles:</translation>
+    </message>
+    <message>
+        <source>POLYGONS_LAB</source>
+        <translation>Polygones:</translation>
+    </message>
+    <message>
+        <source>3D_LAB</source>
+        <translation>3D (volumes):</translation>
+    </message>
+    <message>
+        <source>TETRAHEDRONS_LAB</source>
+        <translation>Tétraèdres:</translation>
+    </message>
+    <message>
+        <source>HEXAHEDONRS_LAB</source>
+        <translation>Hexaèdres:</translation>
+    </message>
+    <message>
+        <source>PYRAMIDS_LAB</source>
+        <translation>Pyramides:</translation>
+    </message>
+    <message>
+        <source>PRISMS_LAB</source>
+        <translation>Prismes:</translation>
+    </message>
+    <message>
+        <source>HEX_PRISMS_LAB</source>
+        <translation>Prismes hexagonaux:</translation>
+    </message>
+    <message>
+        <source>POLYHEDRONS_LAB</source>
+        <translation>Polyèdres:</translation>
+    </message>
+    <message>
+        <source>OBJECT_MESH</source>
+        <translation>Maillage</translation>
+    </message>
+    <message>
+        <source>OBJECT_SUBMESH</source>
+        <translation>Sous-maillage</translation>
+    </message>
+    <message>
+        <source>OBJECT_GROUP</source>
+        <translation>Groupe</translation>
+    </message>
+    <message>
+        <source>OBJECT_GROUP_NODES</source>
+        <translation>Groupe de nÅ“uds</translation>
+    </message>
+    <message>
+        <source>OBJECT_GROUP_EDGES</source>
+        <translation>Groupe d&apos;arêtes</translation>
+    </message>
+    <message>
+        <source>OBJECT_GROUP_FACES</source>
+        <translation>Groupe de faces</translation>
+    </message>
+    <message>
+        <source>OBJECT_GROUP_VOLUMES</source>
+        <translation>Groupe de volumes</translation>
+    </message>
+    <message>
+        <source>OBJECT_GROUP_0DELEMS</source>
+        <translation>Groupe d&apos;éléments 0D</translation>
+    </message>
+    <message>
+        <source>OBJECT_GROUP_BALLS</source>
+        <translation>Groupe d&apos;éléments particulaires</translation>
+    </message>
+    <message>
+        <source>BUT_LOAD_MESH</source>
+        <translation>Charger un maillage depuis un serveur</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MeshInfoDlg</name>
+    <message>
+        <source>MESH_INFO</source>
+        <translation>Informations de maillage</translation>
+    </message>
+    <message>
+        <source>BASE_INFO</source>
+        <translation>Informations de base</translation>
+    </message>
+    <message>
+        <source>ELEM_INFO</source>
+        <translation>Infos sur les Ã©léments</translation>
+    </message>
+    <message>
+        <source>ADDITIONAL_INFO</source>
+        <translation>Infos détaillées</translation>
+    </message>
+    <message>
+        <source>NODE_MODE</source>
+        <translation>NÅ“ud</translation>
+    </message>
+    <message>
+        <source>ELEM_MODE</source>
+        <translation>Elément</translation>
+    </message>
+    <message>
+        <source>X_FROM_Y_ITEMS_SHOWN</source>
+        <translation>%1-%2 sur %3 Ã©léments affichés</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_ElemInfo</name>
+    <message>
+        <source>COORDINATES</source>
+        <translation>COORDONNÉES</translation>
+    </message>
+    <message>
+        <source>CONNECTIVITY</source>
+        <translation>CONNECTIVITÉ</translation>
+    </message>
+    <message>
+        <source>GRAVITY_CENTER</source>
+        <translation>CENTRE DE GRAVITÉ</translation>
+    </message>
+    <message>
+        <source>NODE</source>
+        <translation>NÅ“ud</translation>
+    </message>
+    <message>
+        <source>0D_ELEMENT</source>
+        <translation>ELÉMENTS 0D</translation>
+    </message>
+    <message>
+        <source>0D_ELEMENTS</source>
+        <translation>ELÉMENTS 0D</translation>
+    </message>
+    <message>
+        <source>BALL_ELEMENT</source>
+        <translation>ELEMENT PARTICULAIRE</translation>
+    </message>
+    <message>
+        <source>BALL_ELEMENTS</source>
+        <translation>ELEMENTS PARTICULAIRES</translation>
+    </message>
+    <message>
+        <source>EDGE</source>
+        <translation>ARÊTE</translation>
+    </message>
+    <message>
+        <source>EDGES</source>
+        <translation>ARÊTES</translation>
+    </message>
+    <message>
+        <source>FACE</source>
+        <translation>FACE</translation>
+    </message>
+    <message>
+        <source>FACES</source>
+        <translation>FACES</translation>
+    </message>
+    <message>
+        <source>VOLUME</source>
+        <translation>VOLUME</translation>
+    </message>
+    <message>
+        <source>VOLUMES</source>
+        <translation>VOLUMES</translation>
+    </message>
+    <message>
+        <source>FREE_NODE</source>
+        <translation>NÅ“ud libre (pas de connectivité)</translation>
+    </message>
+    <message>
+        <source>TYPE</source>
+        <translation>TYPE</translation>
+    </message>
+    <message>
+        <source>TRIANGLE</source>
+        <translation>Triangle</translation>
+    </message>
+    <message>
+        <source>QUADRANGLE</source>
+        <translation>Quadrangle</translation>
+    </message>
+    <message>
+        <source>POLYGON</source>
+        <translation>Polygone</translation>
+    </message>
+    <message>
+        <source>TETRAHEDRON</source>
+        <translation>Tétraèdre</translation>
+    </message>
+    <message>
+        <source>HEXAHEDRON</source>
+        <translation>Hexaèdre</translation>
+    </message>
+    <message>
+        <source>PYRAMID</source>
+        <translation>Pyramide</translation>
+    </message>
+    <message>
+        <source>PRISM</source>
+        <translation>Prisme</translation>
+    </message>
+    <message>
+        <source>HEX_PRISM</source>
+        <translation>Prisme hexagonal</translation>
+    </message>
+    <message>
+        <source>POLYHEDRON</source>
+        <translation>Polyèdre</translation>
+    </message>
+    <message>
+        <source>QUADRATIC</source>
+        <translation>QUADRATIQUE</translation>
+    </message>
+    <message>
+        <source>YES</source>
+        <translation>Oui</translation>
+    </message>
+    <message>
+        <source>NO</source>
+        <translation>Non</translation>
+    </message>
+    <message>
+        <source>PROPERTY</source>
+        <translation>Propriété</translation>
+    </message>
+    <message>
+        <source>VALUE</source>
+        <translation>Valeur</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_AddInfo</name>
+    <message>
+        <source>NAME</source>
+        <translation>Nom</translation>
+    </message>
+    <message>
+        <source>GROUPS</source>
+        <translation>Groupes</translation>
+    </message>
+    <message>
+        <source>GROUPS_1</source>
+        <translation>NÅ“uds</translation>
+    </message>
+    <message>
+        <source>GROUPS_2</source>
+        <translation>Arêtes</translation>
+    </message>
+    <message>
+        <source>GROUPS_3</source>
+        <translation>Faces</translation>
+    </message>
+    <message>
+        <source>GROUPS_4</source>
+        <translation>Volumes</translation>
+    </message>
+    <message>
+        <source>GROUPS_5</source>
+        <translation>Eléments 0D</translation>
+    </message>
+    <message>
+        <source>GROUPS_6</source>
+        <translation>Eléments particulaires</translation>
+    </message>
+    <message>
+        <source>PARENT_MESH</source>
+        <translation>Maillage parent</translation>
+    </message>
+    <message>
+        <source>TYPE</source>
+        <translation>Type</translation>
+    </message>
+    <message>
+        <source>STANDALONE_GROUP</source>
+        <translation>Groupe autonome</translation>
+    </message>
+    <message>
+        <source>GROUP_ON_GEOMETRY</source>
+        <translation>Groupe lié Ã  une géométrie</translation>
+    </message>
+    <message>
+        <source>GROUP_ON_FILTER</source>
+        <translation>Groupe lié Ã  un filtre</translation>
+    </message>
+    <message>
+        <source>GEOM_OBJECT</source>
+        <translation>Shape</translation>
+    </message>
+    <message>
+        <source>NODE</source>
+        <translation>NÅ“ud</translation>
+    </message>
+    <message>
+        <source>EDGE</source>
+        <translation>Arête</translation>
+    </message>
+    <message>
+        <source>FACE</source>
+        <translation>Face</translation>
+    </message>
+    <message>
+        <source>VOLUME</source>
+        <translation>Volume</translation>
+    </message>
+    <message>
+        <source>0DELEM</source>
+        <translation>Elément 0D</translation>
+    </message>
+    <message>
+        <source>BALL_ELEMENT</source>
+        <translation>Elément particulaire</translation>
+    </message>
+    <message>
+        <source>UNKNOWN</source>
+        <translation>Inconnu</translation>
+    </message>
+    <message>
+        <source>ENTITY_TYPE</source>
+        <translation>Type de maille</translation>
+    </message>
+    <message>
+        <source>SIZE</source>
+        <translation>Taille</translation>
+    </message>
+    <message>
+        <source>COLOR</source>
+        <translation>Couleur</translation>
+    </message>
+    <message>
+        <source>NB_NODES</source>
+        <translation>NÅ“uds sous-jacents</translation>
+    </message>
+    <message>
+        <source>COMPUTE</source>
+        <translation>Calculer</translation>
+    </message>
+    <message>
+        <source>LOAD</source>
+        <translation>Charger</translation>
+    </message>
+    <message>
+        <source>MESH_ON_GEOMETRY</source>
+        <translation>Lié Ã  une géométrie</translation>
+    </message>
+    <message>
+        <source>MESH_FROM_FILE</source>
+        <translation>Importé</translation>
+    </message>
+    <message>
+        <source>FILE_NAME</source>
+        <translation>Nom du fichier</translation>
+    </message>
+    <message>
+        <source>STANDALONE_MESH</source>
+        <translation>Autonome</translation>
+    </message>
+    <message>
+        <source>SUBMESHES</source>
+        <translation>Sous-maillages</translation>
+    </message>
+    <message>
+        <source>SUBMESHES_0</source>
+        <translation>Assemblage</translation>
+    </message>
+    <message>
+        <source>SUBMESHES_2</source>
+        <translation>Solide</translation>
+    </message>
+    <message>
+        <source>SUBMESHES_3</source>
+        <translation>Coque</translation>
+    </message>
+    <message>
+        <source>SUBMESHES_4</source>
+        <translation>Face</translation>
+    </message>
+    <message>
+        <source>SUBMESHES_5</source>
+        <translation>Contour</translation>
+    </message>
+    <message>
+        <source>SUBMESHES_6</source>
+        <translation>Arêtes</translation>
+    </message>
+    <message>
+        <source>SUBMESHES_7</source>
+        <translation>Point</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MinDistance</name>
+    <message>
+        <source>FIRST_TARGET</source>
+        <translation>Premier Ã©lément</translation>
+    </message>
+    <message>
+        <source>SECOND_TARGET</source>
+        <translation>Deuxième Ã©lément</translation>
+    </message>
+    <message>
+        <source>NODE</source>
+        <translation>NÅ“ud</translation>
+    </message>
+    <message>
+        <source>ELEMENT</source>
+        <translation>Elément</translation>
+    </message>
+    <message>
+        <source>OBJECT</source>
+        <translation>Objet</translation>
+    </message>
+    <message>
+        <source>ORIGIN</source>
+        <translation>Origine</translation>
+    </message>
+    <message>
+        <source>COMPUTE</source>
+        <translation>Calculer</translation>
+    </message>
+    <message>
+        <source>RESULT</source>
+        <translation>Distance entre les Ã©léments</translation>
+    </message>
+    <message>
+        <source>DISTANCE</source>
+        <translation>Distance</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_CopyMeshDlg</name>
+    <message>
+        <source>OBJECT_NAME</source>
+        <translation>Objet source</translation>
+    </message>
+    <message>
+        <source>ELEM_IDS</source>
+        <translation>IDs des Ã©léments sources</translation>
+    </message>
+    <message>
+        <source>NEW_NAME</source>
+        <translation>Nom du nouveau maillage</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MeasureDlg</name>
+    <message>
+        <source>MEASUREMENTS</source>
+        <translation>Outils de mesure</translation>
+    </message>
+    <message>
+        <source>MIN_DIST</source>
+        <translation>Distance minimale</translation>
+    </message>
+    <message>
+        <source>BND_BOX</source>
+        <translation>Boîte englobante</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_BoundingBox</name>
+    <message>
+        <source>SOURCE</source>
+        <translation>Source</translation>
+    </message>
+    <message>
+        <source>OBJECTS</source>
+        <translation>Objets</translation>
+    </message>
+    <message>
+        <source>NODES</source>
+        <translation>NÅ“uds</translation>
+    </message>
+    <message>
+        <source>ELEMENTS</source>
+        <translation>Eléments</translation>
+    </message>
+    <message>
+        <source>COMPUTE</source>
+        <translation>Calculer</translation>
+    </message>
+    <message>
+        <source>RESULT</source>
+        <translation>Boîte englobante</translation>
+    </message>
+    <message>
+        <source>SELECTED_NB_OBJ</source>
+        <translation>%1 %2 sélectionnés</translation>
+    </message>
+    <message>
+        <source>NB_NODES</source>
+        <translation>nÅ“uds</translation>
+    </message>
+    <message>
+        <source>NB_ELEMENTS</source>
+        <translation>éléments</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MeshLoadingProgress</name>
+    <message>
+        <source>MESH_LOAD_PROGRESS_TITLE</source>
+        <translation>Chargement du maillage en cours</translation>
+    </message>
+</context>
+<context>
+    <name>StdMeshersGUI_SubShapeSelectorWdg</name>
+    <message>
+        <source>X_FROM_Y_ITEMS_SHOWN</source>
+        <translation>%1-%2 sur %3 Ã©léments affichés</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_Preferences_ColorDlg</name>
+    <message>
+        <source>DIALOG_TITLE</source>
+        <translation>Propriétés (couleur, Ã©paisseur des traits, taille des Ã©léments réduits, ...)</translation>
+    </message>
+    <message>
+        <source>GRP_ELEMENTS</source>
+        <translation>Eléments</translation>
+    </message>
+    <message>
+        <source>SURFACE_COLOR_LBL</source>
+        <translation>Couleur de surface</translation>
+    </message>
+    <message>
+        <source>BACKSURFACE_COLOR_LBL</source>
+        <translation>Couleur arrière</translation>
+    </message>
+    <message>
+        <source>OUTLINE_COLOR_LBL</source>
+        <translation>Couleur de contour</translation>
+    </message>
+    <message>
+        <source>WIREFRAME_COLOR_LBL</source>
+        <translation>Couleur en mode fil de fer</translation>
+    </message>
+    <message>
+        <source>0D_ELEMENTS_COLOR_LBL</source>
+        <translation>Eléments 0D</translation>
+    </message>
+    <message>
+        <source>0D_ELEMENTS_SIZE_LBL</source>
+        <translation>Taille des Ã©léments 0D</translation>
+    </message>
+    <message>
+        <source>BALL_ELEMENTS_COLOR_LBL</source>
+        <translation>Eléments particulaires</translation>
+    </message>
+    <message>
+        <source>BALL_ELEMENTS_SIZE_LBL</source>
+        <translation>Taille des Ã©léments particulaires</translation>
+    </message>
+    <message>
+        <source>LINE_WIDTH_LBL</source>
+        <translation>Epaisseur des traits</translation>
+    </message>
+    <message>
+        <source>SHRINK_COEF_LBL</source>
+        <translation>Coef. de contraction</translation>
+    </message>
+    <message>
+        <source>GRP_NODES</source>
+        <translation>NÅ“uds</translation>
+    </message>
+    <message>
+        <source>NODES_COLOR_LBL</source>
+        <translation>Couleur</translation>
+    </message>
+    <message>
+        <source>NODES_MARKER_LBL</source>
+        <translation>Marqueur</translation>
+    </message>
+    <message>
+        <source>GRP_ORIENTATION</source>
+        <translation>Orientation des faces</translation>
+    </message>
+    <message>
+        <source>ORIENTATION_COLOR_LBL</source>
+        <translation>Couleur</translation>
+    </message>
+    <message>
+        <source>ORIENTATION_SCALE_LBL</source>
+        <translation>Facteur d&apos;échelle</translation>
+    </message>
+    <message>
+        <source>3D_VECTORS_LBL</source>
+        <translation>Vecteurs 3D</translation>
+    </message>
+    <message>
+        <source>GRP_SELECTION</source>
+        <translation>Sélection</translation>
+    </message>
+    <message>
+        <source>SELECTION_COLOR_LBL</source>
+        <translation>Couleur de sélection</translation>
+    </message>
+    <message>
+        <source>PRESELECTION_COLOR_LBL</source>
+        <translation>Couleur de pré-sélection</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_ReorientFacesDlg</name>
+    <message>
+        <source>CAPTION</source>
+        <translation>Réorienter des faces selon un vector</translation>
+    </message>
+    <message>
+        <source>REORIENT_FACES</source>
+        <translation>Réorienter</translation>
+    </message>
+    <message>
+        <source>DIRECTION</source>
+        <translation>Direction</translation>
+    </message>
+    <message>
+        <source>OBJECT</source>
+        <translation>Objet</translation>
+    </message>
+    <message>
+        <source>POINT</source>
+        <translation>Point</translation>
+    </message>
+    <message>
+        <source>FACE</source>
+        <translation>Face</translation>
+    </message>
+    <message>
+        <source>FACES</source>
+        <translation>Source des faces</translation>
+    </message>
+    <message>
+        <source>ORIENTATION</source>
+        <translation>Orientation</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_ReorientFacesOp</name>
+    <message>
+        <source>NO_OBJECT_SELECTED</source>
+        <translation>Aucun objet sélectionné</translation>
+    </message>
+    <message>
+        <source>NO_FACES</source>
+        <translation>L&apos;objet ne contient pas de faces</translation>
+    </message>
+    <message>
+        <source>ZERO_SIZE_VECTOR</source>
+        <translation>Vecteur de taille nulle</translation>
+    </message>
+    <message>
+        <source>INVALID_FACE</source>
+        <translation>Face non valide</translation>
+    </message>
+    <message>
+        <source>NB_REORIENTED</source>
+        <translation>%1 face(s) inversée(s)</translation>
+    </message>
+</context>
+</TS>
diff --git a/src/SMESHUtils/Makefile.am b/src/SMESHUtils/Makefile.am
new file mode 100644 (file)
index 0000000..0e5f876
--- /dev/null
@@ -0,0 +1,57 @@
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# 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.com
+#
+
+#  File   : Makefile.in
+#  Module : SMESH
+#
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+# header files 
+salomeinclude_HEADERS = \
+       SMESH_Block.hxx \
+       SMESH_TypeDefs.hxx \
+       SMESH_Octree.hxx \
+       SMESH_OctreeNode.hxx \
+       SMESH_Comment.hxx \
+       SMESH_ComputeError.hxx \
+       SMESH_File.hxx \
+       SMESH_Utils.hxx
+
+# Libraries targets
+
+lib_LTLIBRARIES = libSMESHUtils.la
+
+dist_libSMESHUtils_la_SOURCES = \
+       SMESH_Block.cxx \
+       SMESH_Octree.cxx \
+       SMESH_OctreeNode.cxx \
+       SMESH_File.cxx
+
+# additionnal information to compile and link file
+libSMESHUtils_la_CPPFLAGS = \
+       $(KERNEL_CXXFLAGS) \
+       $(CAS_CPPFLAGS) \
+        $(VTK_INCLUDES) \
+       $(BOOST_CPPFLAGS) \
+       -I$(srcdir)/../SMDS \
+       -I$(srcdir)/../SMESHDS
+
+libSMESHUtils_la_LDFLAGS = \
+       ../SMESHDS/libSMESHDS.la \
+       $(CAS_LDPATH) -lTKShHealing -lTKPrim -lTKG2d -lTKG3d -lTKGeomBase
diff --git a/src/SMESHUtils/SMESH_Block.cxx b/src/SMESHUtils/SMESH_Block.cxx
new file mode 100644 (file)
index 0000000..b28dc7d
--- /dev/null
@@ -0,0 +1,1737 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+// File      : SMESH_Pattern.hxx
+// Created   : Mon Aug  2 10:30:00 2004
+// Author    : Edward AGAPOV (eap)
+//
+#include "SMESH_Block.hxx"
+
+#include <BRepAdaptor_Curve.hxx>
+#include <BRepAdaptor_Curve2d.hxx>
+#include <BRepAdaptor_Surface.hxx>
+#include <BRepTools.hxx>
+#include <BRepTools_WireExplorer.hxx>
+#include <BRep_Builder.hxx>
+#include <BRep_Tool.hxx>
+#include <Bnd_Box.hxx>
+#include <Extrema_ExtPC.hxx>
+#include <Extrema_POnCurv.hxx>
+#include <Geom2d_Curve.hxx>
+#include <ShapeAnalysis.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Compound.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS_Wire.hxx>
+#include <gp_Trsf.hxx>
+#include <gp_Vec.hxx>
+#include <math_FunctionSetRoot.hxx>
+#include <math_Matrix.hxx>
+#include <math_Vector.hxx>
+
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_MeshVolume.hxx"
+#include "SMDS_VolumeTool.hxx"
+#include "utilities.h"
+
+#include <list>
+
+using namespace std;
+
+//#define DEBUG_PARAM_COMPUTE
+
+//================================================================================
+/*!
+ * \brief Set edge data
+  * \param edgeID - block sub-shape ID
+  * \param curve - edge geometry
+  * \param isForward - is curve orientation coincides with edge orientation in the block
+ */
+//================================================================================
+
+void SMESH_Block::TEdge::Set( const int edgeID, Adaptor3d_Curve* curve, const bool isForward )
+{
+  myCoordInd = SMESH_Block::GetCoordIndOnEdge( edgeID );
+  if ( myC3d ) delete myC3d;
+  myC3d = curve;
+  myFirst = curve->FirstParameter();
+  myLast = curve->LastParameter();
+  if ( !isForward )
+    std::swap( myFirst, myLast );
+}
+
+//================================================================================
+/*!
+ * \brief Set coordinates of nodes at edge ends to work with mesh block
+  * \param edgeID - block sub-shape ID
+  * \param node1 - coordinates of node with lower ID
+  * \param node2 - coordinates of node with upper ID
+ */
+//================================================================================
+
+void SMESH_Block::TEdge::Set( const int edgeID, const gp_XYZ& node1, const gp_XYZ& node2 )
+{
+  myCoordInd = SMESH_Block::GetCoordIndOnEdge( edgeID );
+  myNodes[ 0 ] = node1;
+  myNodes[ 1 ] = node2;
+
+  if ( myC3d ) delete myC3d;
+  myC3d = 0;
+}
+
+//=======================================================================
+//function : SMESH_Block::TEdge::GetU
+//purpose  : 
+//=======================================================================
+
+double SMESH_Block::TEdge::GetU( const gp_XYZ& theParams ) const
+{
+  double u = theParams.Coord( myCoordInd );
+  if ( !myC3d ) // if mesh block
+    return u;
+  return ( 1 - u ) * myFirst + u * myLast;
+}
+
+//=======================================================================
+//function : SMESH_Block::TEdge::Point
+//purpose  : 
+//=======================================================================
+
+gp_XYZ SMESH_Block::TEdge::Point( const gp_XYZ& theParams ) const
+{
+  double u = GetU( theParams );
+  if ( myC3d ) return myC3d->Value( u ).XYZ();
+  // mesh block
+  return myNodes[0] * ( 1 - u ) + myNodes[1] * u;
+}
+
+//================================================================================
+/*!
+ * \brief Destructor
+ */
+//================================================================================
+
+SMESH_Block::TEdge::~TEdge()
+{
+  if ( myC3d ) delete myC3d;
+}
+
+//================================================================================
+/*!
+ * \brief Set face data
+  * \param faceID - block sub-shape ID
+  * \param S - face surface geometry
+  * \param c2d - 4 pcurves in the order as returned by GetFaceEdgesIDs(faceID)
+  * \param isForward - orientation of pcurves comparing with block edge direction
+ */
+//================================================================================
+
+void SMESH_Block::TFace::Set( const int          faceID,
+                              Adaptor3d_Surface* S,
+                              Adaptor2d_Curve2d* c2D[4],
+                              const bool         isForward[4] )
+{
+  if ( myS ) delete myS;
+  myS = S;
+  // pcurves
+  vector< int > edgeIdVec;
+  GetFaceEdgesIDs( faceID, edgeIdVec );
+  for ( int iE = 0; iE < edgeIdVec.size(); iE++ ) // loop on 4 edges
+  {
+    myCoordInd[ iE ] = GetCoordIndOnEdge( edgeIdVec[ iE ] );
+    if ( myC2d[ iE ]) delete myC2d[ iE ];
+    myC2d[ iE ] = c2D[ iE ];
+    myFirst[ iE ] = myC2d[ iE ]->FirstParameter();
+    myLast [ iE ] = myC2d[ iE ]->LastParameter();
+    if ( !isForward[ iE ])
+      std::swap( myFirst[ iE ], myLast[ iE ] );
+  }
+  // 2d corners
+  myCorner[ 0 ] = myC2d[ 0 ]->Value( myFirst[0] ).XY();
+  myCorner[ 1 ] = myC2d[ 0 ]->Value( myLast[0] ).XY();
+  myCorner[ 2 ] = myC2d[ 1 ]->Value( myLast[1] ).XY();
+  myCorner[ 3 ] = myC2d[ 1 ]->Value( myFirst[1] ).XY();
+}
+
+//================================================================================
+/*!
+ * \brief Set face data to work with mesh block
+  * \param faceID - block sub-shape ID
+  * \param edgeU0 - filled data of edge u0 = GetFaceEdgesIDs(faceID)[ 0 ]
+  * \param edgeU1 - filled data of edge u1 = GetFaceEdgesIDs(faceID)[ 1 ]
+ */
+//================================================================================
+
+void SMESH_Block::TFace::Set( const int faceID, const TEdge& edgeU0, const TEdge& edgeU1 )
+{
+  vector< int > edgeIdVec;
+  GetFaceEdgesIDs( faceID, edgeIdVec );
+  myNodes[ 0 ] = edgeU0.NodeXYZ( 1 );
+  myNodes[ 1 ] = edgeU0.NodeXYZ( 0 );
+  myNodes[ 2 ] = edgeU1.NodeXYZ( 0 );
+  myNodes[ 3 ] = edgeU1.NodeXYZ( 1 );
+  myCoordInd[ 0 ] = GetCoordIndOnEdge( edgeIdVec[ 0 ] );
+  myCoordInd[ 1 ] = GetCoordIndOnEdge( edgeIdVec[ 1 ] );
+  myCoordInd[ 2 ] = GetCoordIndOnEdge( edgeIdVec[ 2 ] );
+  myCoordInd[ 3 ] = GetCoordIndOnEdge( edgeIdVec[ 3 ] );
+  if ( myS ) delete myS;
+  myS = 0;
+}
+
+//================================================================================
+/*!
+ * \brief Destructor
+ */
+//================================================================================
+
+SMESH_Block::TFace::~TFace()
+{
+  if ( myS ) delete myS;
+  for ( int i = 0 ; i < 4; ++i )
+    if ( myC2d[ i ]) delete myC2d[ i ];
+}
+
+//=======================================================================
+//function : SMESH_Block::TFace::GetCoefs
+//purpose  : return coefficients for addition of [0-3]-th edge and vertex
+//=======================================================================
+
+void SMESH_Block::TFace::GetCoefs(int           iE,
+                                  const gp_XYZ& theParams,
+                                  double&       Ecoef,
+                                  double&       Vcoef ) const
+{
+  double dU = theParams.Coord( GetUInd() );
+  double dV = theParams.Coord( GetVInd() );
+  switch ( iE ) {
+  case 0:
+    Ecoef = ( 1 - dV ); // u0
+    Vcoef = ( 1 - dU ) * ( 1 - dV ); break; // 00
+  case 1:
+    Ecoef = dV; // u1
+    Vcoef = dU * ( 1 - dV ); break; // 10
+  case 2:
+    Ecoef = ( 1 - dU ); // 0v
+    Vcoef = dU * dV  ; break; // 11
+  case 3:
+    Ecoef = dU  ; // 1v
+    Vcoef = ( 1 - dU ) * dV  ; break; // 01
+  default: ASSERT(0);
+  }
+}
+
+//=======================================================================
+//function : SMESH_Block::TFace::GetUV
+//purpose  : 
+//=======================================================================
+
+gp_XY SMESH_Block::TFace::GetUV( const gp_XYZ& theParams ) const
+{
+  gp_XY uv(0.,0.);
+  for ( int iE = 0; iE < 4; iE++ ) // loop on 4 edges
+  {
+    double Ecoef = 0, Vcoef = 0;
+    GetCoefs( iE, theParams, Ecoef, Vcoef );
+    // edge addition
+    double u = theParams.Coord( myCoordInd[ iE ] );
+    u = ( 1 - u ) * myFirst[ iE ] + u * myLast[ iE ];
+    uv += Ecoef * myC2d[ iE ]->Value( u ).XY();
+    // corner addition
+    uv -= Vcoef * myCorner[ iE ];
+  }
+  return uv;
+}
+
+//=======================================================================
+//function : SMESH_Block::TFace::Point
+//purpose  : 
+//=======================================================================
+
+gp_XYZ SMESH_Block::TFace::Point( const gp_XYZ& theParams ) const
+{
+  gp_XYZ p(0.,0.,0.);
+  if ( !myS ) // if mesh block
+  {
+    for ( int iE = 0; iE < 4; iE++ ) // loop on 4 edges
+    {
+      double Ecoef = 0, Vcoef = 0;
+      GetCoefs( iE, theParams, Ecoef, Vcoef );
+      // edge addition
+      double u = theParams.Coord( myCoordInd[ iE ] );
+      int i1 = 0, i2 = 1;
+      switch ( iE ) {
+      case 1: i1 = 3; i2 = 2; break;
+      case 2: i1 = 1; i2 = 2; break;
+      case 3: i1 = 0; i2 = 3; break;
+      }
+      p += Ecoef * ( myNodes[ i1 ] * ( 1 - u ) + myNodes[ i2 ] * u );
+      // corner addition
+      p -= Vcoef * myNodes[ iE ];
+    }
+    
+  }
+  else // shape block
+  {
+    gp_XY uv = GetUV( theParams );
+    p = myS->Value( uv.X(), uv.Y() ).XYZ();
+  }
+  return p;
+}
+
+//=======================================================================
+//function : GetShapeCoef
+//purpose  : 
+//=======================================================================
+
+double* SMESH_Block::GetShapeCoef (const int theShapeID)
+{
+  static double shapeCoef[][3] = {
+    //    V000,        V100,        V010,         V110
+    { -1,-1,-1 }, {  1,-1,-1 }, { -1, 1,-1 }, {  1, 1,-1 },
+    //    V001,        V101,        V011,         V111,
+    { -1,-1, 1 }, {  1,-1, 1 }, { -1, 1, 1 }, {  1, 1, 1 },
+    //    Ex00,        Ex10,        Ex01,         Ex11,
+    {  0,-1,-1 }, {  0, 1,-1 }, {  0,-1, 1 }, {  0, 1, 1 },
+    //    E0y0,        E1y0,        E0y1,         E1y1,
+    { -1, 0,-1 }, {  1, 0,-1 }, { -1, 0, 1 }, {  1, 0, 1 },
+    //    E00z,        E10z,        E01z,         E11z,
+    { -1,-1, 0 }, {  1,-1, 0 }, { -1, 1, 0 }, {  1, 1, 0 },
+    //    Fxy0,        Fxy1,        Fx0z,         Fx1z,         F0yz,           F1yz,
+    {  0, 0,-1 }, {  0, 0, 1 }, {  0,-1, 0 }, {  0, 1, 0 }, { -1, 0, 0 }, {  1, 0, 0 },
+    // ID_Shell
+    {  0, 0, 0 }
+  };
+  if ( theShapeID < ID_V000 || theShapeID > ID_F1yz )
+    return shapeCoef[ ID_Shell - 1 ];
+
+  return shapeCoef[ theShapeID - 1 ];
+}
+
+//=======================================================================
+//function : ShellPoint
+//purpose  : return coordinates of a point in shell
+//=======================================================================
+
+bool SMESH_Block::ShellPoint( const gp_XYZ& theParams, gp_XYZ& thePoint ) const
+{
+  thePoint.SetCoord( 0., 0., 0. );
+  for ( int shapeID = ID_V000; shapeID < ID_Shell; shapeID++ )
+  {
+    // coef
+    double* coefs = GetShapeCoef( shapeID );
+    double k = 1;
+    for ( int iCoef = 0; iCoef < 3; iCoef++ ) {
+      if ( coefs[ iCoef ] != 0 ) {
+        if ( coefs[ iCoef ] < 0 )
+          k *= ( 1. - theParams.Coord( iCoef + 1 ));
+        else
+          k *= theParams.Coord( iCoef + 1 );
+      }
+    }
+    // add point on a shape
+    if ( fabs( k ) > DBL_MIN )
+    {
+      gp_XYZ Ps;
+      if ( shapeID < ID_Ex00 ) // vertex
+        VertexPoint( shapeID, Ps );
+      else if ( shapeID < ID_Fxy0 ) { // edge
+        EdgePoint( shapeID, theParams, Ps );
+        k = -k;
+      } else // face
+        FacePoint( shapeID, theParams, Ps );
+
+      thePoint += k * Ps;
+    }
+  }
+  return true;
+}
+
+//=======================================================================
+//function : ShellPoint
+//purpose  : computes coordinates of a point in shell by points on sub-shapes;
+//           thePointOnShape[ subShapeID ] must be a point on a sub-shape
+//=======================================================================
+
+bool SMESH_Block::ShellPoint(const gp_XYZ&         theParams,
+                             const vector<gp_XYZ>& thePointOnShape,
+                             gp_XYZ&               thePoint )
+{
+  if ( thePointOnShape.size() < ID_F1yz )
+    return false;
+
+  const double x = theParams.X(), y = theParams.Y(), z = theParams.Z();
+  const double x1 = 1. - x,       y1 = 1. - y,       z1 = 1. - z;
+  const vector<gp_XYZ>& p = thePointOnShape;
+
+  thePoint = 
+    x1 * p[ID_F0yz] + x * p[ID_F1yz] +
+    y1 * p[ID_Fx0z] + y * p[ID_Fx1z] +
+    z1 * p[ID_Fxy0] + z * p[ID_Fxy1] +
+    x1 * (y1 * (z1 * p[ID_V000] + z * p[ID_V001])  +
+          y  * (z1 * p[ID_V010] + z * p[ID_V011])) +
+    x  * (y1 * (z1 * p[ID_V100] + z * p[ID_V101])  +
+          y  * (z1 * p[ID_V110] + z * p[ID_V111]));
+  thePoint -=
+    x1 * (y1 * p[ID_E00z] + y * p[ID_E01z]) + 
+    x  * (y1 * p[ID_E10z] + y * p[ID_E11z]) + 
+    y1 * (z1 * p[ID_Ex00] + z * p[ID_Ex01]) + 
+    y  * (z1 * p[ID_Ex10] + z * p[ID_Ex11]) + 
+    z1 * (x1 * p[ID_E0y0] + x * p[ID_E1y0]) + 
+    z  * (x1 * p[ID_E0y1] + x * p[ID_E1y1]);
+
+  return true;
+}
+
+//=======================================================================
+//function : Constructor
+//purpose  : 
+//=======================================================================
+
+SMESH_Block::SMESH_Block():
+  myNbIterations(0),
+  mySumDist(0.),
+  myTolerance(-1.) // to be re-initialized
+{
+}
+
+
+//=======================================================================
+//function : NbVariables
+//purpose  : 
+//=======================================================================
+
+Standard_Integer SMESH_Block::NbVariables() const
+{
+  return 3;
+}
+
+//=======================================================================
+//function : NbEquations
+//purpose  : 
+//=======================================================================
+
+Standard_Integer SMESH_Block::NbEquations() const
+{
+  return 1;
+}
+
+//=======================================================================
+//function : Value
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean SMESH_Block::Value(const math_Vector& theXYZ, math_Vector& theFxyz) 
+{
+  gp_XYZ P, params( theXYZ(1), theXYZ(2), theXYZ(3) );
+  if ( params.IsEqual( myParam, DBL_MIN )) { // same param
+    theFxyz( 1 ) = funcValue( myValues[ SQUARE_DIST ]);
+  }
+  else {
+    ShellPoint( params, P );
+    gp_Vec dP( P - myPoint );
+    theFxyz(1) = funcValue( dP.SquareMagnitude() );
+  }
+  return true;
+}
+
+//=======================================================================
+//function : Derivatives
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean SMESH_Block::Derivatives(const math_Vector& XYZ,math_Matrix& Df) 
+{
+  math_Vector F(1,3);
+  return Values(XYZ,F,Df);
+}
+
+//=======================================================================
+//function : GetStateNumber
+//purpose  : 
+//=======================================================================
+
+Standard_Integer SMESH_Block::GetStateNumber ()
+{
+  return 0; //myValues[0] < 1e-1;
+}
+
+//=======================================================================
+//function : Values
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean SMESH_Block::Values(const math_Vector& theXYZ,
+                                     math_Vector&       theFxyz,
+                                     math_Matrix&       theDf) 
+{
+  gp_XYZ P, params( theXYZ(1), theXYZ(2), theXYZ(3) );
+  if ( params.IsEqual( myParam, DBL_MIN )) { // same param
+    theFxyz( 1 )      = funcValue( myValues[ SQUARE_DIST ] );
+    theDf( 1, DRV_1 ) = myValues[ DRV_1 ];
+    theDf( 1, DRV_2 ) = myValues[ DRV_2 ];
+    theDf( 1, DRV_3 ) = myValues[ DRV_3 ];
+    return true;
+  }
+#ifdef DEBUG_PARAM_COMPUTE
+  MESSAGE ( "PARAM GUESS: " << params.X() << " "<< params.Y() << " "<< params.X() );
+  myNbIterations++; // how many times call ShellPoint()
+#endif
+  ShellPoint( params, P );
+
+  gp_Vec dP( myPoint, P );
+  double sqDist = dP.SquareMagnitude();
+  theFxyz(1) = funcValue( sqDist );
+
+  if ( sqDist < myTolerance * myTolerance ) { // a solution found
+    myParam = params;
+    myValues[ SQUARE_DIST ] = sqDist;
+    theFxyz(1)  = theDf( 1,1 ) = theDf( 1,2 ) = theDf( 1,3 ) = 0;
+    return true;
+  }
+
+  if ( sqDist < myValues[ SQUARE_DIST ] ) // a better guess
+  {
+    // 3 partial derivatives
+    gp_Vec drv[ 3 ]; // where we move with a small step in each direction
+    for ( int iP = 1; iP <= 3; iP++ ) {
+      if ( iP == myFaceIndex ) {
+        drv[ iP - 1 ] = gp_Vec(0,0,0);
+        continue;
+      }
+      gp_XYZ Pi;
+      bool onEdge = ( theXYZ( iP ) + 0.001 > 1. );
+      if ( onEdge )
+        params.SetCoord( iP, theXYZ( iP ) - 0.001 );
+      else
+        params.SetCoord( iP, theXYZ( iP ) + 0.001 );
+      ShellPoint( params, Pi );
+      params.SetCoord( iP, theXYZ( iP ) ); // restore params
+      gp_Vec dPi ( P, Pi );
+      if ( onEdge ) dPi *= -1.;
+      double mag = dPi.Magnitude();
+      if ( mag > DBL_MIN )
+        dPi /= mag;
+      drv[ iP - 1 ] = dPi;
+    }
+    for ( int iP = 0; iP < 3; iP++ ) {
+#if 1
+      theDf( 1, iP + 1 ) = dP * drv[iP];
+#else
+      // Distance from P to plane passing through myPoint and defined
+      // by the 2 other derivative directions:
+      // like IntAna_IntConicQuad::Perform (const gp_Lin& L, const gp_Pln& P)
+      // where L is (P -> myPoint), P is defined by the 2 other derivative direction
+      int iPrev = ( iP ? iP - 1 : 2 );
+      int iNext = ( iP == 2 ? 0 : iP + 1 );
+      gp_Vec plnNorm = drv[ iPrev ].Crossed( drv [ iNext ] );
+      double Direc = plnNorm * drv[ iP ];
+      if ( Abs(Direc) <= DBL_MIN )
+        theDf( 1, iP + 1 ) = dP * drv[ iP ];
+      else {
+        double Dis = plnNorm * P - plnNorm * myPoint;
+        theDf( 1, iP + 1 ) = Dis/Direc;
+      }
+#endif
+    }
+#ifdef DEBUG_PARAM_COMPUTE
+    MESSAGE ( "F = " << theFxyz(1) << " DRV: " << theDf(1,1) << " " << theDf(1,2) << " " << theDf(1,3) );
+    myNbIterations +=3; // how many times call ShellPoint()
+#endif
+
+    // store better values
+    myParam              = params;
+    myValues[SQUARE_DIST]= sqDist;
+    myValues[DRV_1]      = theDf(1,DRV_1);
+    myValues[DRV_2]      = theDf(1,DRV_2);
+    myValues[DRV_3]      = theDf(1,DRV_3);
+  }
+
+  return true;
+}
+
+//============================================================================
+//function : computeParameters
+//purpose  : compute point parameters in the block using math_FunctionSetRoot
+//============================================================================
+
+bool SMESH_Block::computeParameters(const gp_Pnt& thePoint,
+                                    gp_XYZ&       theParams,
+                                    const gp_XYZ& theParamsHint)
+{
+  myPoint = thePoint.XYZ();
+
+  myParam.SetCoord( -1,-1,-1 );
+  myValues[ SQUARE_DIST ] = 1e100;
+
+  math_Vector low  ( 1, 3, 0.0 );
+  math_Vector up   ( 1, 3, 1.0 );
+  math_Vector tol  ( 1, 3, 1e-4 );
+  math_Vector start( 1, 3, 0.0 );
+  start( 1 ) = theParamsHint.X();
+  start( 2 ) = theParamsHint.Y();
+  start( 3 ) = theParamsHint.Z();
+
+  math_FunctionSetRoot paramSearch( *this, tol );
+
+  mySquareFunc = 0; // large approaching steps
+  //if ( hasHint ) mySquareFunc = 1; // small approaching steps
+
+  double loopTol = 10 * myTolerance;
+  int nbLoops = 0;
+  while ( distance() > loopTol && nbLoops <= 3 )
+  {
+    paramSearch.Perform ( *static_cast<math_FunctionSetWithDerivatives*>(this),
+                          start, low, up );
+    start( 1 ) = myParam.X();
+    start( 2 ) = myParam.Y();
+    start( 3 ) = myParam.Z();
+    mySquareFunc = !mySquareFunc;
+    nbLoops++;
+  }
+#ifdef DEBUG_PARAM_COMPUTE
+  mySumDist += distance();
+  MESSAGE ( " ------ SOLUTION: ( "<< myParam.X() <<" "<< myParam.Y() <<" "<< myParam.Z() <<" )"<<endl
+         << " ------ DIST : " << distance() << "\t Tol=" << myTolerance << "\t Nb LOOPS=" << nbLoops << endl
+         << " ------ NB IT: " << myNbIterations << ",  SUM DIST: " << mySumDist );
+#endif
+
+  theParams = myParam;
+
+  if ( myFaceIndex > 0 )
+    theParams.SetCoord( myFaceIndex, myFaceParam );
+
+  return true;
+}
+
+//=======================================================================
+//function : ComputeParameters
+//purpose  : compute point parameters in the block
+//=======================================================================
+
+bool SMESH_Block::ComputeParameters(const gp_Pnt& thePoint,
+                                    gp_XYZ&       theParams,
+                                    const int     theShapeID,
+                                    const gp_XYZ& theParamsHint)
+{
+  if ( VertexParameters( theShapeID, theParams ))
+    return true;
+
+  if ( IsEdgeID( theShapeID )) {
+    TEdge& e = myEdge[ theShapeID - ID_FirstE ];
+    Adaptor3d_Curve* curve = e.GetCurve();
+    Extrema_ExtPC anExtPC( thePoint, *curve, curve->FirstParameter(), curve->LastParameter() );
+    int i, nb = anExtPC.IsDone() ? anExtPC.NbExt() : 0;
+    for ( i = 1; i <= nb; i++ ) {
+      if ( anExtPC.IsMin( i ))
+        return EdgeParameters( theShapeID, anExtPC.Point( i ).Parameter(), theParams );
+    }
+    return false;
+  }
+
+  const bool isOnFace = IsFaceID( theShapeID );
+  double * coef = GetShapeCoef( theShapeID );
+
+  // Find the first guess paremeters
+
+  gp_XYZ start(0, 0, 0);
+
+  bool hasHint = ( 0 <= theParamsHint.X() && theParamsHint.X() <= 1 &&
+                   0 <= theParamsHint.Y() && theParamsHint.Y() <= 1 &&
+                   0 <= theParamsHint.Y() && theParamsHint.Y() <= 1 );
+  if ( !hasHint && !myGridComputed )
+  {
+    // define the first guess by thePoint projection on lines
+    // connecting vertices
+    bool needGrid = false;
+    gp_XYZ par000( 0, 0, 0 ), par111( 1, 1, 1 );
+    double zero = DBL_MIN * DBL_MIN;
+    for ( int iEdge = 0, iParam = 1; iParam <= 3 && !needGrid; iParam++ )
+    {
+      if ( isOnFace && coef[ iParam - 1 ] != 0 ) {
+        iEdge += 4;
+        continue;
+      }
+      double sumParam = 0;
+      for ( int iE = 0; iE < 4; iE++, iEdge++ ) { // loop on 4 parallel edges
+        gp_Pnt p0 = myEdge[ iEdge ].Point( par000 );
+        gp_Pnt p1 = myEdge[ iEdge ].Point( par111 );
+        gp_Vec v01( p0, p1 ), v0P( p0, thePoint );
+        double len2 = v01.SquareMagnitude();
+        double par = 0;
+        if ( len2 > zero ) {
+          par = v0P.Dot( v01 ) / len2;
+          if ( par < 0 || par > 1 ) { // projection falls out of line ends => needGrid
+            needGrid = true;
+            break;
+          }
+        }
+        sumParam += par;
+      }
+      start.SetCoord( iParam, sumParam / 4.);
+    }
+    if ( needGrid ) {
+      // compute nodes of 3 x 3 x 3 grid
+      int iNode = 0;
+      Bnd_Box box;
+      for ( double x = 0.25; x < 0.9; x += 0.25 )
+        for ( double y = 0.25; y < 0.9; y += 0.25 )
+          for ( double z = 0.25; z < 0.9; z += 0.25 ) {
+            TxyzPair & prmPtn = my3x3x3GridNodes[ iNode++ ];
+            prmPtn.first.SetCoord( x, y, z );
+            ShellPoint( prmPtn.first, prmPtn.second );
+            box.Add( gp_Pnt( prmPtn.second ));
+          }
+      myGridComputed = true;
+      myTolerance = sqrt( box.SquareExtent() ) * 1e-5;
+    }
+  }
+
+  if ( hasHint )
+  {
+    start = theParamsHint;
+  }
+  else if ( myGridComputed )
+  {
+    double minDist = DBL_MAX;
+    gp_XYZ* bestParam = 0;
+    for ( int iNode = 0; iNode < 27; iNode++ ) {
+      TxyzPair & prmPtn = my3x3x3GridNodes[ iNode ];
+      double dist = ( thePoint.XYZ() - prmPtn.second ).SquareModulus();
+      if ( dist < minDist ) {
+        minDist = dist;
+        bestParam = & prmPtn.first;
+      }
+    }
+    start = *bestParam;
+  }
+
+  myFaceIndex = -1;
+  myFaceParam = 0.;
+  if ( isOnFace ) {
+    // put a point on the face
+    for ( int iCoord = 0; iCoord < 3; iCoord++ )
+      if ( coef[ iCoord ] ) {
+        myFaceIndex = iCoord + 1;
+        myFaceParam = ( coef[ iCoord ] < 0.5 ) ? 0.0 : 1.0;
+        start.SetCoord( myFaceIndex, myFaceParam );
+      }
+  }
+
+#ifdef DEBUG_PARAM_COMPUTE
+  MESSAGE ( " #### POINT " <<thePoint.X()<<" "<<thePoint.Y()<<" "<<thePoint.Z()<<" ####" );
+#endif
+
+  if ( myTolerance < 0 ) myTolerance = 1e-6;
+
+  const double parDelta = 1e-4;
+  const double sqTolerance = myTolerance * myTolerance;
+
+  gp_XYZ solution = start, params = start;
+  double sqDistance = 1e100; 
+  int nbLoops = 0, nbGetWorst = 0;
+
+  while ( nbLoops <= 100 )
+  {
+    gp_XYZ P, Pi;
+    ShellPoint( params, P );
+
+    gp_Vec dP( thePoint, P );
+    double sqDist = dP.SquareMagnitude();
+
+    if ( sqDist > sqDistance ) { // solution get worse
+      if ( ++nbGetWorst > 2 )
+        return computeParameters( thePoint, theParams, solution );
+    }
+#ifdef DEBUG_PARAM_COMPUTE
+    MESSAGE ( "PARAMS: ( " << params.X() <<" "<< params.Y() <<" "<< params.Z() <<" )" );
+    MESSAGE ( "DIST: " << sqrt( sqDist ) );
+#endif
+
+    if ( sqDist < sqDistance ) { // get better
+      sqDistance = sqDist;
+      solution   = params;
+      nbGetWorst = 0;
+      if ( sqDistance < sqTolerance ) // a solution found
+        break;
+    }
+
+        // look for a next better solution
+    for ( int iP = 1; iP <= 3; iP++ ) {
+      if ( iP == myFaceIndex )
+        continue;
+      // see where we move with a small (=parDelta) step in this direction
+      gp_XYZ nearParams = params;
+      bool onEdge = ( params.Coord( iP ) + parDelta > 1. );
+      if ( onEdge )
+        nearParams.SetCoord( iP, params.Coord( iP ) - parDelta );
+      else
+        nearParams.SetCoord( iP, params.Coord( iP ) + parDelta );
+      ShellPoint( nearParams, Pi );
+      gp_Vec dPi ( P, Pi );
+      if ( onEdge ) dPi *= -1.;
+      // modify a parameter
+      double mag = dPi.Magnitude();
+      if ( mag < DBL_MIN )
+        continue;
+      gp_Vec dir = dPi / mag; // dir we move modifying the parameter
+      double dist = dir * dP; // where we should get to
+      double dPar = dist / mag * parDelta; // predict parameter change
+      double curPar = params.Coord( iP );
+      double par = curPar - dPar; // new parameter value
+      while ( par > 1 || par < 0 ) {
+        dPar /= 2.;
+        par = curPar - dPar;
+      }
+      params.SetCoord( iP, par );
+    }
+
+    nbLoops++;
+  }
+#ifdef DEBUG_PARAM_COMPUTE
+  myNbIterations += nbLoops*4; // how many times ShellPoint called
+  mySumDist += sqrt( sqDistance );
+  MESSAGE ( " ------ SOLUTION: ( "<<solution.X()<<" "<<solution.Y()<<" "<<solution.Z()<<" )"<< std::endl
+         << " ------ DIST : " << sqrt( sqDistance ) << "\t Tol=" << myTolerance << "\t Nb LOOPS=" << nbLoops << std::endl
+         << " ------ NB IT: " << myNbIterations << ",  SUM DIST: " << mySumDist );
+#endif
+
+  theParams = solution;
+
+  if ( myFaceIndex > 0 )
+    theParams.SetCoord( myFaceIndex, myFaceParam );
+
+  return true;
+}
+
+//=======================================================================
+//function : VertexParameters
+//purpose  : return parameters of a vertex given by TShapeID
+//=======================================================================
+
+bool SMESH_Block::VertexParameters(const int theVertexID, gp_XYZ& theParams)
+{
+  switch ( theVertexID ) {
+  case ID_V000: theParams.SetCoord(0., 0., 0.); return true;
+  case ID_V100: theParams.SetCoord(1., 0., 0.); return true;
+  case ID_V110: theParams.SetCoord(1., 1., 0.); return true;
+  case ID_V010: theParams.SetCoord(0., 1., 0.); return true;
+  default:;
+  }
+  return false;
+}
+
+//=======================================================================
+//function : EdgeParameters
+//purpose  : return parameters of a point given by theU on edge
+//=======================================================================
+
+bool SMESH_Block::EdgeParameters(const int theEdgeID, const double theU, gp_XYZ& theParams)
+{
+  if ( IsEdgeID( theEdgeID )) {
+    vector< int > vertexVec;
+    GetEdgeVertexIDs( theEdgeID, vertexVec );
+    VertexParameters( vertexVec[0], theParams );
+    TEdge& e = myEdge[ theEdgeID - ID_Ex00 ];
+    double param = ( theU - e.EndParam(0) ) / ( e.EndParam(1) - e.EndParam(0) );
+    theParams.SetCoord( e.CoordInd(), param );
+    return true;
+  }
+  return false;
+}
+
+//=======================================================================
+//function : DumpShapeID
+//purpose  : debug an id of a block sub-shape
+//=======================================================================
+
+#define CASEDUMP(id,strm) case id: strm << #id; break;
+
+ostream& SMESH_Block::DumpShapeID (const int id, ostream& stream)
+{
+  switch ( id ) {
+  CASEDUMP( ID_V000, stream );
+  CASEDUMP( ID_V100, stream );
+  CASEDUMP( ID_V010, stream );
+  CASEDUMP( ID_V110, stream );
+  CASEDUMP( ID_V001, stream );
+  CASEDUMP( ID_V101, stream );
+  CASEDUMP( ID_V011, stream );
+  CASEDUMP( ID_V111, stream );
+  CASEDUMP( ID_Ex00, stream );
+  CASEDUMP( ID_Ex10, stream );
+  CASEDUMP( ID_Ex01, stream );
+  CASEDUMP( ID_Ex11, stream );
+  CASEDUMP( ID_E0y0, stream );
+  CASEDUMP( ID_E1y0, stream );
+  CASEDUMP( ID_E0y1, stream );
+  CASEDUMP( ID_E1y1, stream );
+  CASEDUMP( ID_E00z, stream );
+  CASEDUMP( ID_E10z, stream );
+  CASEDUMP( ID_E01z, stream );
+  CASEDUMP( ID_E11z, stream );
+  CASEDUMP( ID_Fxy0, stream );
+  CASEDUMP( ID_Fxy1, stream );
+  CASEDUMP( ID_Fx0z, stream );
+  CASEDUMP( ID_Fx1z, stream );
+  CASEDUMP( ID_F0yz, stream );
+  CASEDUMP( ID_F1yz, stream );
+  CASEDUMP( ID_Shell, stream );
+  default: stream << "ID_INVALID";
+  }
+  return stream;
+}
+
+//=======================================================================
+//function : GetShapeIDByParams
+//purpose  : define an id of the block sub-shape by normlized point coord
+//=======================================================================
+
+int SMESH_Block::GetShapeIDByParams ( const gp_XYZ& theCoord )
+{
+  //   id ( 0 - 26 ) computation:
+
+  //   vertex     ( 0 - 7 )  : id = 1*x + 2*y + 4*z
+
+  //   edge || X  ( 8 - 11 ) : id = 8   + 1*y + 2*z
+  //   edge || Y  ( 12 - 15 ): id = 1*x + 12  + 2*z
+  //   edge || Z  ( 16 - 19 ): id = 1*x + 2*y + 16 
+
+  //   face || XY ( 20 - 21 ): id = 8   + 12  + 1*z - 0
+  //   face || XZ ( 22 - 23 ): id = 8   + 1*y + 16  - 2
+  //   face || YZ ( 24 - 25 ): id = 1*x + 12  + 16  - 4
+
+  static int iAddBnd[]    = { 1, 2, 4 };
+  static int iAddNotBnd[] = { 8, 12, 16 };
+  static int iFaceSubst[] = { 0, 2, 4 };
+
+  int id = 0;
+  int iOnBoundary = 0;
+  for ( int iCoord = 0; iCoord < 3; iCoord++ )
+  {
+    double val = theCoord.Coord( iCoord + 1 );
+    if ( val == 0.0 )
+      iOnBoundary++;
+    else if ( val == 1.0 )
+      id += iAddBnd[ iOnBoundary++ ];
+    else
+      id += iAddNotBnd[ iCoord ];
+  }
+  if ( iOnBoundary == 1 ) // face
+    id -= iFaceSubst[ (id - 20) / 4 ];
+  else if ( iOnBoundary == 0 ) // shell
+    id = 26;
+
+  if ( id > 26 || id < 0 ) {
+    MESSAGE( "GetShapeIDByParams() = " << id
+            <<" "<< theCoord.X() <<" "<< theCoord.Y() <<" "<< theCoord.Z() );
+  }
+
+  return id + 1; // shape ids start at 1
+}
+
+//================================================================================
+/*!
+ * \brief Return number of wires and a list of oredered edges.
+ *  \param theFace - the face to process
+ *  \param theFirstVertex - the vertex of the outer wire to set first in the returned
+ *         list ( theFirstVertex may be NULL )
+ *  \param theEdges - all ordered edges of theFace (outer edges goes first).
+ *  \param theNbEdgesInWires - nb of edges (== nb of vertices in closed wire) in each wire
+ *  \param theShapeAnalysisAlgo - if true, ShapeAnalysis::OuterWire() is used to find
+ *         the outer wire else BRepTools::OuterWire() is used.
+ *  \retval int - nb of wires
+ * 
+ * Always try to set a seam edge first.
+ * BRepTools::OuterWire() fails e.g. in the case of issue 0020184,
+ * ShapeAnalysis::OuterWire() fails in the case of issue 0020452
+ */
+//================================================================================
+
+int SMESH_Block::GetOrderedEdges (const TopoDS_Face&   theFace,
+                                  TopoDS_Vertex        theFirstVertex,
+                                  list< TopoDS_Edge >& theEdges,
+                                  list< int >  &       theNbEdgesInWires,
+                                  const bool           theShapeAnalysisAlgo)
+{
+  // put wires in a list, so that an outer wire comes first
+  list<TopoDS_Wire> aWireList;
+  TopoDS_Wire anOuterWire =
+    theShapeAnalysisAlgo ? ShapeAnalysis::OuterWire( theFace ) : BRepTools::OuterWire( theFace );
+  for ( TopoDS_Iterator wIt (theFace); wIt.More(); wIt.Next() )
+    if ( wIt.Value().ShapeType() == TopAbs_WIRE ) // it can be internal vertex!
+    {
+      if ( !anOuterWire.IsSame( wIt.Value() ))
+        aWireList.push_back( TopoDS::Wire( wIt.Value() ));
+      else
+        aWireList.push_front( TopoDS::Wire( wIt.Value() ));
+    }
+
+  // loop on edges of wires
+  theNbEdgesInWires.clear();
+  list<TopoDS_Wire>::iterator wlIt = aWireList.begin();
+  for ( ; wlIt != aWireList.end(); wlIt++ )
+  {
+    int iE;
+    BRepTools_WireExplorer wExp( *wlIt, theFace );
+    for ( iE = 0; wExp.More(); wExp.Next(), iE++ )
+    {
+      TopoDS_Edge edge = wExp.Current();
+      // commented for issue 0020557, other related ones: 0020526, PAL19080
+      // edge = TopoDS::Edge( edge.Oriented( wExp.Orientation() ));
+      theEdges.push_back( edge );
+    }
+    if ( iE == 0 ) // wExp returns nothing if e.g. the wire contains one internal edge
+    { // Issue 0020676
+      for ( TopoDS_Iterator e( *wlIt ); e.More(); e.Next(), ++iE )
+        theEdges.push_back( TopoDS::Edge( e.Value() ));
+    }
+    theNbEdgesInWires.push_back( iE );
+    iE = 0;
+    if ( wlIt == aWireList.begin() && theEdges.size() > 1 ) { // the outer wire
+      // orient closed edges
+      list< TopoDS_Edge >::iterator eIt, eIt2;
+      for ( eIt = theEdges.begin(); eIt != theEdges.end(); eIt++ )
+      {
+        TopoDS_Edge& edge = *eIt;
+        if ( TopExp::FirstVertex( edge ).IsSame( TopExp::LastVertex( edge ) ))
+        {
+          eIt2 = eIt;
+          bool isNext = ( eIt2 == theEdges.begin() );
+          TopoDS_Edge edge2 = isNext ? *(++eIt2) : *(--eIt2);
+          double f1,l1,f2,l2;
+          Handle(Geom2d_Curve) c1 = BRep_Tool::CurveOnSurface( edge, theFace, f1,l1 );
+          Handle(Geom2d_Curve) c2 = BRep_Tool::CurveOnSurface( edge2, theFace, f2,l2 );
+          gp_Pnt2d pf = c1->Value( edge.Orientation() == TopAbs_FORWARD ? f1 : l1 );
+          gp_Pnt2d pl = c1->Value( edge.Orientation() == TopAbs_FORWARD ? l1 : f1 );
+          bool isFirst = ( edge2.Orientation() == TopAbs_FORWARD ? isNext : !isNext );
+          gp_Pnt2d p2 = c2->Value( isFirst ? f2 : l2 );
+          isFirst = ( p2.SquareDistance( pf ) < p2.SquareDistance( pl ));
+          if ( isNext ? isFirst : !isFirst )
+            edge.Reverse();
+          // to make a seam go first
+          if ( theFirstVertex.IsNull() )
+            theFirstVertex = TopExp::FirstVertex( edge, true );
+        }
+      }
+      // rotate theEdges until it begins from theFirstVertex
+      if ( ! theFirstVertex.IsNull() ) {
+        TopoDS_Vertex vv[2];
+        TopExp::Vertices( theEdges.front(), vv[0], vv[1], true );
+        // on closed face, make seam edge the first in the list
+        while ( !vv[0].IsSame( theFirstVertex ) || vv[0].IsSame( vv[1] ))
+        {
+          theEdges.splice(theEdges.end(), theEdges,
+                          theEdges.begin(), ++theEdges.begin());
+          TopExp::Vertices( theEdges.front(), vv[0], vv[1], true );
+          if ( iE++ > theNbEdgesInWires.back() ) {
+#ifdef _DEBUG_
+            gp_Pnt p = BRep_Tool::Pnt( theFirstVertex );
+            MESSAGE ( " : Warning : vertex "<< theFirstVertex.TShape().operator->()
+                   << " ( " << p.X() << " " << p.Y() << " " << p.Z() << " )" 
+                   << " not found in outer wire of face "<< theFace.TShape().operator->()
+                   << " with vertices: " );
+            wExp.Init( *wlIt, theFace );
+            for ( int i = 0; wExp.More(); wExp.Next(), i++ )
+            {
+              TopoDS_Edge edge = wExp.Current();
+              edge = TopoDS::Edge( edge.Oriented( wExp.Orientation() ));
+              TopoDS_Vertex v = TopExp::FirstVertex( edge, true );
+              gp_Pnt p = BRep_Tool::Pnt( v );
+              MESSAGE_ADD ( i << " " << v.TShape().operator->() << " "
+                            << p.X() << " " << p.Y() << " " << p.Z() << " " << std::endl );
+            }
+#endif
+            break; // break infinite loop
+          }
+        }
+      }
+    } // end outer wire
+  }
+
+  return aWireList.size();
+}
+//================================================================================
+/*!
+ * \brief Call it after geometry initialisation
+ */
+//================================================================================
+
+void SMESH_Block::init()
+{
+  myNbIterations = 0;
+  mySumDist = 0;
+  myGridComputed = false;
+}
+
+//=======================================================================
+//function : LoadMeshBlock
+//purpose  : prepare to work with theVolume
+//=======================================================================
+
+#define gpXYZ(n) gp_XYZ(n->X(),n->Y(),n->Z())
+
+bool SMESH_Block::LoadMeshBlock(const SMDS_MeshVolume*        theVolume,
+                                const int                     theNode000Index,
+                                const int                     theNode001Index,
+                                vector<const SMDS_MeshNode*>& theOrderedNodes)
+{
+  MESSAGE(" ::LoadMeshBlock()");
+  init();
+
+  SMDS_VolumeTool vTool;
+  if (!vTool.Set( theVolume ) || vTool.NbNodes() != 8 ||
+      !vTool.IsLinked( theNode000Index, theNode001Index )) {
+    MESSAGE(" Bad arguments ");
+    return false;
+  }
+  vTool.SetExternalNormal();
+  // In terms of indices used for access to nodes and faces in SMDS_VolumeTool:
+  int V000, V100, V010, V110, V001, V101, V011, V111; // 8 vertices
+  int Fxy0, Fxy1; // bottom and top faces
+  // vertices of faces
+  vector<int> vFxy0, vFxy1;
+
+  V000 = theNode000Index;
+  V001 = theNode001Index;
+
+  // get faces sharing V000 and V001
+  list<int> fV000, fV001;
+  int i, iF, iE, iN;
+  for ( iF = 0; iF < vTool.NbFaces(); ++iF ) {
+    const int* nid = vTool.GetFaceNodesIndices( iF );
+    for ( iN = 0; iN < 4; ++iN )
+      if ( nid[ iN ] == V000 ) {
+        fV000.push_back( iF );
+      } else if ( nid[ iN ] == V001 ) {
+        fV001.push_back( iF );
+      }
+  }
+
+  // find the bottom (Fxy0), the top (Fxy1) faces
+  list<int>::iterator fIt1, fIt2, Fxy0Pos;
+  for ( fIt1 = fV000.begin(); fIt1 != fV000.end(); fIt1++) {
+    fIt2 = std::find( fV001.begin(), fV001.end(), *fIt1 );
+    if ( fIt2 != fV001.end() ) { // *fIt1 is in the both lists
+      fV001.erase( fIt2 ); // erase Fx0z or F0yz from fV001
+    } else { // *fIt1 is in fV000 only
+      Fxy0Pos = fIt1; // points to Fxy0
+    }
+  }
+  Fxy0 = *Fxy0Pos;
+  Fxy1 = fV001.front();
+  const SMDS_MeshNode** nn = vTool.GetNodes();
+
+  // find bottom veritices, their order is that a face normal is external
+  vFxy0.resize(4);
+  const int* nid = vTool.GetFaceNodesIndices( Fxy0 );
+  for ( i = 0; i < 4; ++i )
+    if ( nid[ i ] == V000 )
+      break;
+  for ( iN = 0; iN < 4; ++iN, ++i ) {
+    if ( i == 4 ) i = 0;
+    vFxy0[ iN ] = nid[ i ];
+  }
+  // find top veritices, their order is that a face normal is external
+  vFxy1.resize(4);
+  nid = vTool.GetFaceNodesIndices( Fxy1 );
+  for ( i = 0; i < 4; ++i )
+    if ( nid[ i ] == V001 )
+      break;
+  for ( iN = 0; iN < 4; ++iN, ++i ) {
+    if ( i == 4 ) i = 0;
+    vFxy1[ iN ] = nid[ i ];
+  }
+  // find indices of the rest veritices 
+  V100 = vFxy0[3];
+  V010 = vFxy0[1];
+  V110 = vFxy0[2];
+  V101 = vFxy1[1];
+  V011 = vFxy1[3];
+  V111 = vFxy1[2];
+
+  // set points coordinates
+  myPnt[ ID_V000 - 1 ] = gpXYZ( nn[ V000 ] );
+  myPnt[ ID_V100 - 1 ] = gpXYZ( nn[ V100 ] );
+  myPnt[ ID_V010 - 1 ] = gpXYZ( nn[ V010 ] );
+  myPnt[ ID_V110 - 1 ] = gpXYZ( nn[ V110 ] );
+  myPnt[ ID_V001 - 1 ] = gpXYZ( nn[ V001 ] );
+  myPnt[ ID_V101 - 1 ] = gpXYZ( nn[ V101 ] );
+  myPnt[ ID_V011 - 1 ] = gpXYZ( nn[ V011 ] );
+  myPnt[ ID_V111 - 1 ] = gpXYZ( nn[ V111 ] );
+
+  // fill theOrderedNodes
+  theOrderedNodes.resize( 8 );
+  theOrderedNodes[ 0 ] = nn[ V000 ];
+  theOrderedNodes[ 1 ] = nn[ V100 ];
+  theOrderedNodes[ 2 ] = nn[ V010 ];
+  theOrderedNodes[ 3 ] = nn[ V110 ];
+  theOrderedNodes[ 4 ] = nn[ V001 ];
+  theOrderedNodes[ 5 ] = nn[ V101 ];
+  theOrderedNodes[ 6 ] = nn[ V011 ];
+  theOrderedNodes[ 7 ] = nn[ V111 ];
+  
+  // fill edges
+  vector< int > vertexVec;
+  for ( iE = 0; iE < NbEdges(); ++iE ) {
+    GetEdgeVertexIDs(( iE + ID_FirstE ), vertexVec );
+    myEdge[ iE ].Set(( iE + ID_FirstE ),
+                     myPnt[ vertexVec[0] - 1 ],
+                     myPnt[ vertexVec[1] - 1 ]);
+  }
+
+  // fill faces' corners
+  for ( iF = ID_Fxy0; iF < ID_Shell; ++iF )
+  {
+    TFace& tFace = myFace[ iF - ID_FirstF ];
+    vector< int > edgeIdVec(4, -1);
+    GetFaceEdgesIDs( iF, edgeIdVec );
+    tFace.Set( iF, myEdge[ edgeIdVec [ 0 ] - ID_Ex00], myEdge[ edgeIdVec [ 1 ] - ID_Ex00]);
+  }
+
+  return true;
+}
+
+//=======================================================================
+//function : LoadBlockShapes
+//purpose  : Initialize block geometry with theShell,
+//           add sub-shapes of theBlock to theShapeIDMap so that they get
+//           IDs acoording to enum TShapeID
+//=======================================================================
+
+bool SMESH_Block::LoadBlockShapes(const TopoDS_Shell&         theShell,
+                                  const TopoDS_Vertex&        theVertex000,
+                                  const TopoDS_Vertex&        theVertex001,
+                                  TopTools_IndexedMapOfOrientedShape& theShapeIDMap )
+{
+  MESSAGE(" ::LoadBlockShapes()");
+  return ( FindBlockShapes( theShell, theVertex000, theVertex001, theShapeIDMap ) &&
+           LoadBlockShapes( theShapeIDMap ));
+}
+
+//=======================================================================
+//function : LoadBlockShapes
+//purpose  : add sub-shapes of theBlock to theShapeIDMap so that they get
+//           IDs acoording to enum TShapeID
+//=======================================================================
+
+bool SMESH_Block::FindBlockShapes(const TopoDS_Shell&         theShell,
+                                  const TopoDS_Vertex&        theVertex000,
+                                  const TopoDS_Vertex&        theVertex001,
+                                  TopTools_IndexedMapOfOrientedShape& theShapeIDMap )
+{
+  MESSAGE(" ::FindBlockShapes()");
+
+  // 8 vertices
+  TopoDS_Shape V000, V100, V010, V110, V001, V101, V011, V111;
+  // 12 edges
+  TopoDS_Shape Ex00, Ex10, Ex01, Ex11;
+  TopoDS_Shape E0y0, E1y0, E0y1, E1y1;
+  TopoDS_Shape E00z, E10z, E01z, E11z;
+  // 6 faces
+  TopoDS_Shape Fxy0, Fx0z, F0yz, Fxy1, Fx1z, F1yz;
+
+  // nb of faces bound to a vertex in TopTools_IndexedDataMapOfShapeListOfShape
+  // filled by TopExp::MapShapesAndAncestors()
+  const int NB_FACES_BY_VERTEX = 6;
+
+  TopTools_IndexedDataMapOfShapeListOfShape vfMap;
+  TopExp::MapShapesAndAncestors( theShell, TopAbs_VERTEX, TopAbs_FACE, vfMap );
+  if ( vfMap.Extent() != 8 ) {
+    MESSAGE(" Wrong nb of vertices in the block: " << vfMap.Extent() );
+    return false;
+  }
+
+  V000 = theVertex000;
+  V001 = theVertex001;
+
+  if ( V000.IsNull() ) {
+    // find vertex 000 - the one with smallest coordinates
+    double minVal = DBL_MAX, minX, val;
+    for ( int i = 1; i <= 8; i++ ) {
+      const TopoDS_Vertex& v = TopoDS::Vertex( vfMap.FindKey( i ));
+      gp_Pnt P = BRep_Tool::Pnt( v );
+      val = P.X() + P.Y() + P.Z();
+      if ( val < minVal || ( val == minVal && P.X() < minX )) {
+        V000 = v;
+        minVal = val;
+        minX = P.X();
+      }
+    }
+    // find vertex 001 - the one on the most vertical edge passing through V000
+    TopTools_IndexedDataMapOfShapeListOfShape veMap;
+    TopExp::MapShapesAndAncestors( theShell, TopAbs_VERTEX, TopAbs_EDGE, veMap );
+    gp_Vec dir001 = gp::DZ();
+    gp_Pnt p000 = BRep_Tool::Pnt( TopoDS::Vertex( V000 ));
+    double maxVal = -DBL_MAX;
+    TopTools_ListIteratorOfListOfShape eIt ( veMap.FindFromKey( V000 ));
+    for (  ; eIt.More(); eIt.Next() ) {
+      const TopoDS_Edge& e = TopoDS::Edge( eIt.Value() );
+      TopoDS_Vertex v = TopExp::FirstVertex( e );
+      if ( v.IsSame( V000 ))
+        v = TopExp::LastVertex( e );
+      val = dir001 * gp_Vec( p000, BRep_Tool::Pnt( v )).Normalized();
+      if ( val > maxVal ) {
+        V001 = v;
+        maxVal = val;
+      }
+    }
+  }
+
+  // find the bottom (Fxy0), Fx0z and F0yz faces
+
+  const TopTools_ListOfShape& f000List = vfMap.FindFromKey( V000 );
+  const TopTools_ListOfShape& f001List = vfMap.FindFromKey( V001 );
+  if (f000List.Extent() != NB_FACES_BY_VERTEX ||
+      f001List.Extent() != NB_FACES_BY_VERTEX ) {
+    MESSAGE(" LoadBlockShapes() " << f000List.Extent() << " " << f001List.Extent());
+    return false;
+  }
+  TopTools_ListIteratorOfListOfShape f001It, f000It ( f000List );
+  int i, j, iFound1, iFound2;
+  for ( j = 0; f000It.More(); f000It.Next(), j++ )
+  {
+    if ( NB_FACES_BY_VERTEX == 6 && j % 2 ) continue; // each face encounters twice
+    const TopoDS_Shape& F = f000It.Value();
+    for ( i = 0, f001It.Initialize( f001List ); f001It.More(); f001It.Next(), i++ ) {
+      if ( NB_FACES_BY_VERTEX == 6 && i % 2 ) continue; // each face encounters twice
+      if ( F.IsSame( f001It.Value() ))
+        break;
+    }
+    if ( f001It.More() ) // Fx0z or F0yz found
+      if ( Fx0z.IsNull() ) {
+        Fx0z = F;
+        iFound1 = i;
+      } else {
+        F0yz = F;
+        iFound2 = i;
+      }
+    else // F is the bottom face
+      Fxy0 = F;
+  }
+  if ( Fxy0.IsNull() || Fx0z.IsNull() || F0yz.IsNull() ) {
+    MESSAGE( Fxy0.IsNull() <<" "<< Fx0z.IsNull() <<" "<< F0yz.IsNull() );
+    return false;
+  }
+
+  // choose the top face (Fxy1)
+  for ( i = 0, f001It.Initialize( f001List ); f001It.More(); f001It.Next(), i++ ) {
+    if ( NB_FACES_BY_VERTEX == 6 && i % 2 ) continue; // each face encounters twice
+    if ( i != iFound1 && i != iFound2 )
+      break;
+  }
+  Fxy1 = f001It.Value();
+  if ( Fxy1.IsNull() ) {
+    MESSAGE(" LoadBlockShapes() error ");
+    return false;
+  }
+
+  // find bottom edges and veritices
+  list< TopoDS_Edge > eList;
+  list< int >         nbVertexInWires;
+  GetOrderedEdges( TopoDS::Face( Fxy0 ), TopoDS::Vertex( V000 ), eList, nbVertexInWires );
+  if ( nbVertexInWires.size() != 1 || nbVertexInWires.front() != 4 ) {
+    MESSAGE(" LoadBlockShapes() error ");
+    return false;
+  }
+  list< TopoDS_Edge >::iterator elIt = eList.begin();
+  for ( i = 0; elIt != eList.end(); elIt++, i++ )
+    switch ( i ) {
+    case 0: E0y0 = *elIt; V010 = TopExp::LastVertex( *elIt, true ); break;
+    case 1: Ex10 = *elIt; V110 = TopExp::LastVertex( *elIt, true ); break;
+    case 2: E1y0 = *elIt; V100 = TopExp::LastVertex( *elIt, true ); break;
+    case 3: Ex00 = *elIt; break;
+    default:;
+    }
+  if ( i != 4 || E0y0.IsNull() || Ex10.IsNull() || E1y0.IsNull() || Ex00.IsNull() ) {
+    MESSAGE(" LoadBlockShapes() error, eList.size()=" << eList.size());
+    return false;
+  }
+
+
+  // find top edges and veritices
+  eList.clear();
+  GetOrderedEdges( TopoDS::Face( Fxy1 ), TopoDS::Vertex( V001 ), eList, nbVertexInWires );
+  if ( nbVertexInWires.size() != 1 || nbVertexInWires.front() != 4 ) {
+    MESSAGE(" LoadBlockShapes() error ");
+    return false;
+  }
+  for ( i = 0, elIt = eList.begin(); elIt != eList.end(); elIt++, i++ )
+    switch ( i ) {
+    case 0: Ex01 = *elIt; V101 = TopExp::LastVertex( *elIt, true ); break;
+    case 1: E1y1 = *elIt; V111 = TopExp::LastVertex( *elIt, true ); break;
+    case 2: Ex11 = *elIt; V011 = TopExp::LastVertex( *elIt, true ); break;
+    case 3: E0y1 = *elIt; break;
+    default:;
+    }
+  if ( i != 4 || Ex01.IsNull() || E1y1.IsNull() || Ex11.IsNull() || E0y1.IsNull() ) {
+    MESSAGE(" LoadBlockShapes() error, eList.size()=" << eList.size());
+    return false;
+  }
+
+  // swap Fx0z and F0yz if necessary
+  TopExp_Explorer exp( Fx0z, TopAbs_VERTEX );
+  for ( ; exp.More(); exp.Next() ) // Fx0z shares V101 and V100
+    if ( V101.IsSame( exp.Current() ) || V100.IsSame( exp.Current() ))
+      break; // V101 or V100 found
+  if ( !exp.More() ) { // not found
+    std::swap( Fx0z, F0yz);
+  }
+
+  // find Fx1z and F1yz faces
+  const TopTools_ListOfShape& f111List = vfMap.FindFromKey( V111 );
+  const TopTools_ListOfShape& f110List = vfMap.FindFromKey( V110 );
+  if (f111List.Extent() != NB_FACES_BY_VERTEX ||
+      f110List.Extent() != NB_FACES_BY_VERTEX ) {
+    MESSAGE(" LoadBlockShapes() " << f111List.Extent() << " " << f110List.Extent());
+    return false;
+  }
+  TopTools_ListIteratorOfListOfShape f111It, f110It ( f110List);
+  for ( j = 0 ; f110It.More(); f110It.Next(), j++ ) {
+    if ( NB_FACES_BY_VERTEX == 6 && j % 2 ) continue; // each face encounters twice
+    const TopoDS_Shape& F = f110It.Value();
+    for ( i = 0, f111It.Initialize( f111List ); f111It.More(); f111It.Next(), i++ ) {
+      if ( NB_FACES_BY_VERTEX == 6 && i % 2 ) continue; // each face encounters twice
+      if ( F.IsSame( f111It.Value() )) { // Fx1z or F1yz found
+        if ( Fx1z.IsNull() )
+          Fx1z = F;
+        else
+          F1yz = F;
+      }
+    }
+  }
+  if ( Fx1z.IsNull() || F1yz.IsNull() ) {
+    MESSAGE(" LoadBlockShapes() error ");
+    return false;
+  }
+
+  // swap Fx1z and F1yz if necessary
+  for ( exp.Init( Fx1z, TopAbs_VERTEX ); exp.More(); exp.Next() )
+    if ( V010.IsSame( exp.Current() ) || V011.IsSame( exp.Current() ))
+      break;
+  if ( !exp.More() ) {
+    std::swap( Fx1z, F1yz);
+  }
+
+  // find vertical edges
+  for ( exp.Init( Fx0z, TopAbs_EDGE ); exp.More(); exp.Next() ) {
+    const TopoDS_Edge& edge = TopoDS::Edge( exp.Current() );
+    const TopoDS_Shape& vFirst = TopExp::FirstVertex( edge, true );
+    if ( vFirst.IsSame( V001 ))
+      E00z = edge;
+    else if ( vFirst.IsSame( V100 ))
+      E10z = edge;
+  }
+  if ( E00z.IsNull() || E10z.IsNull() ) {
+    MESSAGE(" LoadBlockShapes() error ");
+    return false;
+  }
+  for ( exp.Init( Fx1z, TopAbs_EDGE ); exp.More(); exp.Next() ) {
+    const TopoDS_Edge& edge = TopoDS::Edge( exp.Current() );
+    const TopoDS_Shape& vFirst = TopExp::FirstVertex( edge, true );
+    if ( vFirst.IsSame( V111 ))
+      E11z = edge;
+    else if ( vFirst.IsSame( V010 ))
+      E01z = edge;
+  }
+  if ( E01z.IsNull() || E11z.IsNull() ) {
+    MESSAGE(" LoadBlockShapes() error ");
+    return false;
+  }
+
+  // load shapes in theShapeIDMap
+
+  theShapeIDMap.Clear();
+  
+  theShapeIDMap.Add(V000.Oriented( TopAbs_FORWARD ));
+  theShapeIDMap.Add(V100.Oriented( TopAbs_FORWARD ));
+  theShapeIDMap.Add(V010.Oriented( TopAbs_FORWARD ));
+  theShapeIDMap.Add(V110.Oriented( TopAbs_FORWARD ));
+  theShapeIDMap.Add(V001.Oriented( TopAbs_FORWARD ));
+  theShapeIDMap.Add(V101.Oriented( TopAbs_FORWARD ));
+  theShapeIDMap.Add(V011.Oriented( TopAbs_FORWARD ));
+  theShapeIDMap.Add(V111.Oriented( TopAbs_FORWARD ));
+
+  theShapeIDMap.Add(Ex00);
+  theShapeIDMap.Add(Ex10);
+  theShapeIDMap.Add(Ex01);
+  theShapeIDMap.Add(Ex11);
+
+  theShapeIDMap.Add(E0y0);
+  theShapeIDMap.Add(E1y0);
+  theShapeIDMap.Add(E0y1);
+  theShapeIDMap.Add(E1y1);
+
+  theShapeIDMap.Add(E00z);
+  theShapeIDMap.Add(E10z);
+  theShapeIDMap.Add(E01z);
+  theShapeIDMap.Add(E11z);
+
+  theShapeIDMap.Add(Fxy0);
+  theShapeIDMap.Add(Fxy1);
+  theShapeIDMap.Add(Fx0z);
+  theShapeIDMap.Add(Fx1z);
+  theShapeIDMap.Add(F0yz);
+  theShapeIDMap.Add(F1yz);
+  
+  theShapeIDMap.Add(theShell);
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Initialize block geometry with shapes from theShapeIDMap
+  * \param theShapeIDMap - map of block sub-shapes
+  * \retval bool - is a success
+ */
+//================================================================================
+
+bool SMESH_Block::LoadBlockShapes(const TopTools_IndexedMapOfOrientedShape& theShapeIDMap)
+{
+  init();
+
+  // store shapes geometry
+  for ( int shapeID = 1; shapeID < theShapeIDMap.Extent(); shapeID++ )
+  {
+    const TopoDS_Shape& S = theShapeIDMap( shapeID );
+    switch ( S.ShapeType() )
+    {
+    case TopAbs_VERTEX: {
+
+      if ( !IsVertexID( ID_V111 )) return false;
+      myPnt[ shapeID - ID_V000 ] = BRep_Tool::Pnt( TopoDS::Vertex( S )).XYZ();
+      break;
+    }
+    case TopAbs_EDGE: {
+
+      if ( !IsEdgeID( shapeID )) return false;
+      const TopoDS_Edge& edge = TopoDS::Edge( S );
+      TEdge& tEdge = myEdge[ shapeID - ID_FirstE ];
+      tEdge.Set( shapeID,
+                 new BRepAdaptor_Curve( edge ),
+                 IsForwardEdge( edge, theShapeIDMap ));
+      break;
+    }
+    case TopAbs_FACE: {
+
+      if ( !LoadFace( TopoDS::Face( S ), shapeID, theShapeIDMap ))
+        return false;
+      break;
+    }
+    default: break;
+    }
+  } // loop on shapes in theShapeIDMap
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Load face geometry
+  * \param theFace - face
+  * \param theFaceID - face in-block ID
+  * \param theShapeIDMap - map of block sub-shapes
+  * \retval bool - is a success
+ * 
+ * It is enough to compute params or coordinates on the face.
+ * Face sub-shapes must be loaded into theShapeIDMap before
+ */
+//================================================================================
+
+bool SMESH_Block::LoadFace(const TopoDS_Face& theFace,
+                           const int          theFaceID,
+                           const TopTools_IndexedMapOfOrientedShape& theShapeIDMap)
+{
+  if ( !IsFaceID( theFaceID ) ) return false;
+  // pcurves
+  Adaptor2d_Curve2d* c2d[4];
+  bool isForward[4];
+  vector< int > edgeIdVec;
+  GetFaceEdgesIDs( theFaceID, edgeIdVec );
+  for ( int iE = 0; iE < edgeIdVec.size(); iE++ ) // loop on 4 edges
+  {
+    if ( edgeIdVec[ iE ] > theShapeIDMap.Extent() )
+      return false;
+    const TopoDS_Edge& edge = TopoDS::Edge( theShapeIDMap( edgeIdVec[ iE ]));
+    c2d[ iE ] = new BRepAdaptor_Curve2d( edge, theFace );
+    isForward[ iE ] = IsForwardEdge( edge, theShapeIDMap );
+  }
+  TFace& tFace = myFace[ theFaceID - ID_FirstF ];
+  tFace.Set( theFaceID, new BRepAdaptor_Surface( theFace ), c2d, isForward );
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief/ Insert theShape into theShapeIDMap with theShapeID
+  * \param theShape - shape to insert
+  * \param theShapeID - shape in-block ID
+  * \param theShapeIDMap - map of block sub-shapes
+ */
+//================================================================================
+
+bool SMESH_Block::Insert(const TopoDS_Shape& theShape,
+                         const int           theShapeID,
+                         TopTools_IndexedMapOfOrientedShape& theShapeIDMap)
+{
+  if ( !theShape.IsNull() && theShapeID > 0 )
+  {
+    if ( theShapeIDMap.Contains( theShape ))
+      return ( theShapeIDMap.FindIndex( theShape ) == theShapeID );
+
+    if ( theShapeID <= theShapeIDMap.Extent() ) {
+        theShapeIDMap.Substitute( theShapeID, theShape );
+    }
+    else {
+      while ( theShapeIDMap.Extent() < theShapeID - 1 ) {
+        TopoDS_Compound comp;
+        BRep_Builder().MakeCompound( comp );
+        theShapeIDMap.Add( comp );
+      }
+      theShapeIDMap.Add( theShape );
+    }
+    return true;
+  }
+  return false;
+}
+
+//=======================================================================
+//function : GetFaceEdgesIDs
+//purpose  : return edges IDs in the order u0, u1, 0v, 1v
+//           u0 means "|| u, v == 0"
+//=======================================================================
+
+void SMESH_Block::GetFaceEdgesIDs (const int faceID, vector< int >& edgeVec )
+{
+  edgeVec.resize( 4 );
+  switch ( faceID ) {
+  case ID_Fxy0:
+    edgeVec[ 0 ] = ID_Ex00;
+    edgeVec[ 1 ] = ID_Ex10;
+    edgeVec[ 2 ] = ID_E0y0;
+    edgeVec[ 3 ] = ID_E1y0;
+    break;
+  case ID_Fxy1:
+    edgeVec[ 0 ] = ID_Ex01;
+    edgeVec[ 1 ] = ID_Ex11;
+    edgeVec[ 2 ] = ID_E0y1;
+    edgeVec[ 3 ] = ID_E1y1;
+    break;
+  case ID_Fx0z:
+    edgeVec[ 0 ] = ID_Ex00;
+    edgeVec[ 1 ] = ID_Ex01;
+    edgeVec[ 2 ] = ID_E00z;
+    edgeVec[ 3 ] = ID_E10z;
+    break;
+  case ID_Fx1z:
+    edgeVec[ 0 ] = ID_Ex10;
+    edgeVec[ 1 ] = ID_Ex11;
+    edgeVec[ 2 ] = ID_E01z;
+    edgeVec[ 3 ] = ID_E11z;
+    break;
+  case ID_F0yz:
+    edgeVec[ 0 ] = ID_E0y0;
+    edgeVec[ 1 ] = ID_E0y1;
+    edgeVec[ 2 ] = ID_E00z;
+    edgeVec[ 3 ] = ID_E01z;
+    break;
+  case ID_F1yz:
+    edgeVec[ 0 ] = ID_E1y0;
+    edgeVec[ 1 ] = ID_E1y1;
+    edgeVec[ 2 ] = ID_E10z;
+    edgeVec[ 3 ] = ID_E11z;
+    break;
+  default:
+    MESSAGE(" GetFaceEdgesIDs(), wrong face ID: " << faceID );
+  }
+}
+
+//=======================================================================
+//function : GetEdgeVertexIDs
+//purpose  : return vertex IDs of an edge
+//=======================================================================
+
+void SMESH_Block::GetEdgeVertexIDs (const int edgeID, vector< int >& vertexVec )
+{
+  vertexVec.resize( 2 );
+  switch ( edgeID ) {
+
+  case ID_Ex00:
+    vertexVec[ 0 ] = ID_V000;
+    vertexVec[ 1 ] = ID_V100;
+    break;
+  case ID_Ex10:
+    vertexVec[ 0 ] = ID_V010;
+    vertexVec[ 1 ] = ID_V110;
+    break;
+  case ID_Ex01:
+    vertexVec[ 0 ] = ID_V001;
+    vertexVec[ 1 ] = ID_V101;
+    break;
+  case ID_Ex11:
+    vertexVec[ 0 ] = ID_V011;
+    vertexVec[ 1 ] = ID_V111;
+    break;
+
+  case ID_E0y0:
+    vertexVec[ 0 ] = ID_V000;
+    vertexVec[ 1 ] = ID_V010;
+    break;
+  case ID_E1y0:
+    vertexVec[ 0 ] = ID_V100;
+    vertexVec[ 1 ] = ID_V110;
+    break;
+  case ID_E0y1:
+    vertexVec[ 0 ] = ID_V001;
+    vertexVec[ 1 ] = ID_V011;
+    break;
+  case ID_E1y1:
+    vertexVec[ 0 ] = ID_V101;
+    vertexVec[ 1 ] = ID_V111;
+    break;
+
+  case ID_E00z:
+    vertexVec[ 0 ] = ID_V000;
+    vertexVec[ 1 ] = ID_V001;
+    break;
+  case ID_E10z:
+    vertexVec[ 0 ] = ID_V100;
+    vertexVec[ 1 ] = ID_V101;
+    break;
+  case ID_E01z:
+    vertexVec[ 0 ] = ID_V010;
+    vertexVec[ 1 ] = ID_V011;
+    break;
+  case ID_E11z:
+    vertexVec[ 0 ] = ID_V110;
+    vertexVec[ 1 ] = ID_V111;
+    break;
+  default:
+    vertexVec.resize(0);
+    MESSAGE(" GetEdgeVertexIDs(), wrong edge ID: " << edgeID );
+  }
+}
diff --git a/src/SMESHUtils/SMESH_Block.hxx b/src/SMESHUtils/SMESH_Block.hxx
new file mode 100644 (file)
index 0000000..4971db9
--- /dev/null
@@ -0,0 +1,391 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+// File      : SMESH_Block.hxx
+// Created   : Tue Nov 30 12:42:18 2004
+// Author    : Edward AGAPOV (eap)
+//
+#ifndef SMESH_Block_HeaderFile
+#define SMESH_Block_HeaderFile
+
+#include "SMESH_Utils.hxx"
+
+//#include <Geom2d_Curve.hxx>
+//#include <Geom_Curve.hxx>
+//#include <Geom_Surface.hxx>
+
+#include <TopExp.hxx>
+#include <TopTools_IndexedMapOfOrientedShape.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Shell.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <gp_XY.hxx>
+#include <gp_XYZ.hxx>
+#include <math_FunctionSetWithDerivatives.hxx>
+
+#include <ostream>
+#include <vector>
+#include <list>
+
+class SMDS_MeshVolume;
+class SMDS_MeshNode;
+class Adaptor3d_Surface;
+class Adaptor2d_Curve2d;
+class Adaptor3d_Curve;
+class gp_Pnt;
+
+// =========================================================
+// class calculating coordinates of 3D points by normalized
+// parameters inside the block and vice versa
+// =========================================================
+
+class SMESHUtils_EXPORT SMESH_Block: public math_FunctionSetWithDerivatives
+{
+ public:
+  enum TShapeID {
+    // ----------------------------
+    // Ids of the block sub-shapes
+    // ----------------------------
+    ID_NONE = 0,
+
+    ID_V000 = 1, ID_V100, ID_V010, ID_V110, ID_V001, ID_V101, ID_V011, ID_V111,
+
+    ID_Ex00, ID_Ex10, ID_Ex01, ID_Ex11,
+    ID_E0y0, ID_E1y0, ID_E0y1, ID_E1y1,
+    ID_E00z, ID_E10z, ID_E01z, ID_E11z,
+
+    ID_Fxy0, ID_Fxy1, ID_Fx0z, ID_Fx1z, ID_F0yz, ID_F1yz,
+
+    ID_Shell
+    };
+  enum { // to use TShapeID for indexing certain type subshapes
+
+    ID_FirstV = ID_V000, ID_FirstE = ID_Ex00, ID_FirstF = ID_Fxy0
+
+  };
+
+
+ public:
+  // -------------------------------------------------
+  // Block topology in terms of block sub-shapes' ids
+  // -------------------------------------------------
+
+  static int NbVertices()  { return  8; }
+  static int NbEdges()     { return 12; }
+  static int NbFaces()     { return  6; }
+  static int NbSubShapes() { return ID_Shell; }
+  // to avoid magic numbers when allocating memory for subshapes
+
+  static inline bool IsVertexID( int theShapeID )
+  { return ( theShapeID >= ID_V000 && theShapeID <= ID_V111 ); }
+
+  static inline bool IsEdgeID( int theShapeID )
+  { return ( theShapeID >= ID_Ex00 && theShapeID <= ID_E11z ); }
+
+  static inline bool IsFaceID( int theShapeID )
+  { return ( theShapeID >= ID_Fxy0 && theShapeID <= ID_F1yz ); }
+
+  static int ShapeIndex( int theShapeID )
+  {
+    if ( IsVertexID( theShapeID )) return theShapeID - ID_V000;
+    if ( IsEdgeID( theShapeID ))   return theShapeID - ID_Ex00;
+    if ( IsFaceID( theShapeID ))   return theShapeID - ID_Fxy0;
+    return 0;
+  }
+  // return index [0-...] for each type of sub-shapes,
+  // for example :
+  // ShapeIndex( ID_Ex00 ) == 0
+  // ShapeIndex( ID_Ex10 ) == 1
+
+  static void GetFaceEdgesIDs (const int faceID, std::vector< int >& edgeVec );
+  // return edges IDs of a face in the order u0, u1, 0v, 1v
+
+  static void GetEdgeVertexIDs (const int edgeID, std::vector< int >& vertexVec );
+  // return vertex IDs of an edge
+
+  static int GetCoordIndOnEdge (const int theEdgeID)
+  { return (theEdgeID < ID_E0y0) ? 1 : (theEdgeID < ID_E00z) ? 2 : 3; }
+  // return an index of a coordinate which varies along the edge
+
+  static double* GetShapeCoef (const int theShapeID);
+  // for theShapeID( TShapeID ), returns 3 coefficients used
+  // to compute an addition of an on-theShape point to coordinates
+  // of an in-shell point. If an in-shell point has parameters (Px,Py,Pz),
+  // then the addition of a point P is computed as P*kx*ky*kz and ki is
+  // defined by the returned coef like this:
+  // ki = (coef[i] == 0) ? 1 : (coef[i] < 0) ? 1 - Pi : Pi
+
+  static int GetShapeIDByParams ( const gp_XYZ& theParams );
+  // define an id of the block sub-shape by point parameters
+
+  static std::ostream& DumpShapeID (const int theBlockShapeID, std::ostream& stream);
+  // DEBUG: dump an id of a block sub-shape
+
+
+ public:
+  // ---------------
+  // Initialization
+  // ---------------
+
+  SMESH_Block();
+
+  bool LoadBlockShapes(const TopoDS_Shell&         theShell,
+                       const TopoDS_Vertex&        theVertex000,
+                       const TopoDS_Vertex&        theVertex001,
+                       TopTools_IndexedMapOfOrientedShape& theShapeIDMap );
+  // Initialize block geometry with theShell,
+  // add sub-shapes of theBlock to theShapeIDMap so that they get
+  // IDs acoording to enum TShapeID
+
+  bool LoadBlockShapes(const TopTools_IndexedMapOfOrientedShape& theShapeIDMap);
+  // Initialize block geometry with shapes from theShapeIDMap
+
+  bool LoadMeshBlock(const SMDS_MeshVolume*        theVolume,
+                     const int                     theNode000Index,
+                     const int                     theNode001Index,
+                     std::vector<const SMDS_MeshNode*>& theOrderedNodes);
+  // prepare to work with theVolume and
+  // return nodes in theVolume corners in the order of TShapeID enum
+
+  bool LoadFace(const TopoDS_Face& theFace,
+                const int          theFaceID,
+                const TopTools_IndexedMapOfOrientedShape& theShapeIDMap);
+  // Load face geometry.
+  // It is enough to compute params or coordinates on the face.
+  // Face subshapes must be loaded into theShapeIDMap before
+
+  static bool Insert(const TopoDS_Shape& theShape,
+                     const int           theShapeID,
+                     TopTools_IndexedMapOfOrientedShape& theShapeIDMap);
+  // Insert theShape into theShapeIDMap with theShapeID,
+  // Not yet set shapes preceding theShapeID are filled with compounds
+  // Return true if theShape was successfully bound to theShapeID
+
+  static bool FindBlockShapes(const TopoDS_Shell&         theShell,
+                              const TopoDS_Vertex&        theVertex000,
+                              const TopoDS_Vertex&        theVertex001,
+                              TopTools_IndexedMapOfOrientedShape& theShapeIDMap );
+  // add sub-shapes of theBlock to theShapeIDMap so that they get
+  // IDs acoording to enum TShapeID
+
+public:
+  // ---------------------------------
+  // Define coordinates by parameters
+  // ---------------------------------
+
+  bool VertexPoint( const int theVertexID, gp_XYZ& thePoint ) const {
+    if ( !IsVertexID( theVertexID ))           return false;
+    thePoint = myPnt[ theVertexID - ID_FirstV ]; return true;
+  }
+  // return vertex coordinates, parameters are defined by theVertexID
+
+  bool EdgePoint( const int theEdgeID, const gp_XYZ& theParams, gp_XYZ& thePoint ) const {
+    if ( !IsEdgeID( theEdgeID ))                                 return false;
+    thePoint = myEdge[ theEdgeID - ID_FirstE ].Point( theParams ); return true;
+  }
+  // return coordinates of a point on edge
+
+  bool EdgeU( const int theEdgeID, const gp_XYZ& theParams, double& theU ) const {
+    if ( !IsEdgeID( theEdgeID ))                              return false;
+    theU = myEdge[ theEdgeID - ID_FirstE ].GetU( theParams ); return true;
+  }
+  // return parameter on edge by in-block parameters
+
+  bool FacePoint( const int theFaceID, const gp_XYZ& theParams, gp_XYZ& thePoint ) const {
+    if ( !IsFaceID ( theFaceID ))                                return false;
+    thePoint = myFace[ theFaceID - ID_FirstF ].Point( theParams ); return true;
+  }
+  // return coordinates of a point on face
+
+  bool FaceUV( const int theFaceID, const gp_XYZ& theParams, gp_XY& theUV ) const {
+    if ( !IsFaceID ( theFaceID ))                               return false;
+    theUV = myFace[ theFaceID - ID_FirstF ].GetUV( theParams ); return true;
+  }
+  // return UV coordinates on a face by in-block parameters
+
+  bool ShellPoint( const gp_XYZ& theParams, gp_XYZ& thePoint ) const;
+  // return coordinates of a point in shell
+
+  static bool ShellPoint(const gp_XYZ&         theParams,
+                         const std::vector<gp_XYZ>& thePointOnShape,
+                         gp_XYZ&               thePoint );
+  // computes coordinates of a point in shell by points on sub-shapes
+  // and point parameters.
+  // thePointOnShape[ subShapeID ] must be a point on a subShape;
+  // thePointOnShape.size() == ID_Shell, thePointOnShape[0] not used
+
+
+ public:
+  // ---------------------------------
+  // Define parameters by coordinates
+  // ---------------------------------
+
+  bool ComputeParameters (const gp_Pnt& thePoint,
+                          gp_XYZ&       theParams,
+                          const int     theShapeID    = ID_Shell,
+                          const gp_XYZ& theParamsHint = gp_XYZ(-1,-1,-1));
+  // compute point parameters in the block.
+  // Note: for edges, it is better to use EdgeParameters()
+
+  bool VertexParameters(const int theVertexID, gp_XYZ& theParams);
+  // return parameters of a vertex given by TShapeID
+
+  bool EdgeParameters(const int theEdgeID, const double theU, gp_XYZ& theParams);
+  // return parameters of a point given by theU on edge
+
+
+ public:
+  // ---------------
+  // Block geomerty
+  // ---------------
+
+  
+  
+ public:
+  // ---------
+  // Services
+  // ---------
+
+  static bool IsForwardEdge (const TopoDS_Edge &                       theEdge,
+                             const TopTools_IndexedMapOfOrientedShape& theShapeIDMap) {
+    int v1ID = theShapeIDMap.FindIndex( TopExp::FirstVertex( theEdge ).Oriented( TopAbs_FORWARD ));
+    int v2ID = theShapeIDMap.FindIndex( TopExp::LastVertex( theEdge ).Oriented( TopAbs_FORWARD ));
+    return ( v1ID < v2ID );
+  }
+  // Return true if an in-block parameter increases along theEdge curve
+
+  static int GetOrderedEdges (const TopoDS_Face&        theFace,
+                              TopoDS_Vertex             theFirstVertex,
+                              std::list< TopoDS_Edge >& theEdges,
+                              std::list< int >  &       theNbEdgesInWires,
+                              const bool                theShapeAnalysisAlgo=false);
+  // Return nb wires and a list of oredered edges.
+  // It is used to assign indices to subshapes.
+  // theFirstVertex may be NULL.
+  // Always try to set a seam edge first
+  // if (theShapeAnalysisAlgo) then ShapeAnalysis::OuterWire() is used to find the outer
+  // wire else BRepTools::OuterWire() is used
+
+ public:
+  // -----------------------------------------------------------
+  // Methods of math_FunctionSetWithDerivatives used internally
+  // to define parameters by coordinates
+  // -----------------------------------------------------------
+  Standard_Integer NbVariables() const;
+  Standard_Integer NbEquations() const;
+  Standard_Boolean Value(const math_Vector& X,math_Vector& F) ;
+  Standard_Boolean Derivatives(const math_Vector& X,math_Matrix& D) ;
+  Standard_Boolean Values(const math_Vector& X,math_Vector& F,math_Matrix& D) ;
+  Standard_Integer GetStateNumber ();
+
+ protected:
+
+  /*!
+   * \brief Call it after geometry initialisation
+   */
+  void init();
+
+  // Note: to compute params of a point on a face, it is enough to set
+  // TFace, TEdge's and points for that face only
+
+  // Note 2: curve adaptors need to have only Value(double), FirstParameter() and
+  // LastParameter() defined to be used by Block algoritms
+
+  class SMESHUtils_EXPORT TEdge {
+    int                myCoordInd;
+    double             myFirst;
+    double             myLast;
+    Adaptor3d_Curve*   myC3d;
+    // if mesh volume
+    gp_XYZ             myNodes[2];
+  public:
+    void Set( const int edgeID, Adaptor3d_Curve* curve, const bool isForward );
+    void Set( const int edgeID, const gp_XYZ& node1, const gp_XYZ& node2 );
+    Adaptor3d_Curve* GetCurve() const { return myC3d; }
+    double EndParam(int i) const { return i ? myLast : myFirst; }
+    int CoordInd() const { return myCoordInd; }
+    const gp_XYZ& NodeXYZ(int i) const { return i ? myNodes[1] : myNodes[0]; }
+    gp_XYZ Point( const gp_XYZ& theParams ) const; // Return coord by params
+    double GetU( const gp_XYZ& theParams ) const;  // Return U by params
+    TEdge(): myC3d(0) {}
+    ~TEdge();
+  };
+
+  class SMESHUtils_EXPORT TFace {
+    // 4 edges in the order u0, u1, 0v, 1v
+    int                  myCoordInd[ 4 ];
+    double               myFirst   [ 4 ];
+    double               myLast    [ 4 ];
+    Adaptor2d_Curve2d*   myC2d     [ 4 ];
+    // 4 corner points in the order 00, 10, 11, 01
+    gp_XY                myCorner  [ 4 ];
+    // surface
+    Adaptor3d_Surface*   myS;
+    // if mesh volume
+    gp_XYZ               myNodes[4];
+  public:
+    void Set( const int faceID, Adaptor3d_Surface* S, // must be in GetFaceEdgesIDs() order:
+              Adaptor2d_Curve2d* c2d[4], const bool isForward[4] );
+    void Set( const int faceID, const TEdge& edgeU0, const TEdge& edgeU1 );
+    gp_XY  GetUV( const gp_XYZ& theParams ) const;
+    gp_XYZ Point( const gp_XYZ& theParams ) const;
+    int GetUInd() const { return myCoordInd[ 0 ]; }
+    int GetVInd() const { return myCoordInd[ 2 ]; }
+    void GetCoefs( int i, const gp_XYZ& theParams, double& eCoef, double& vCoef ) const;
+    TFace(): myS(0) { myC2d[0]=myC2d[1]=myC2d[2]=myC2d[3]=0; }
+    ~TFace();
+  };
+
+  // geometry in the order as in TShapeID:
+  // 8 vertices
+  gp_XYZ myPnt[ 8 ];
+  // 12 edges
+  TEdge  myEdge[ 12 ];
+  // 6 faces
+  TFace  myFace[ 6 ];
+
+  // for param computation
+
+  enum { SQUARE_DIST = 0, DRV_1, DRV_2, DRV_3 };
+  double distance () const { return sqrt( myValues[ SQUARE_DIST ]); }
+  double funcValue(double sqDist) const { return mySquareFunc ? sqDist : sqrt(sqDist); }
+  bool computeParameters(const gp_Pnt& thePoint, gp_XYZ& theParams, const gp_XYZ& theParamsHint);
+
+  int      myFaceIndex;
+  double   myFaceParam;
+  int      myNbIterations;
+  double   mySumDist;
+  double   myTolerance;
+  bool     mySquareFunc;
+
+  gp_XYZ   myPoint; // the given point
+  gp_XYZ   myParam; // the best parameters guess
+  double   myValues[ 4 ]; // values computed at myParam: square distance and 3 derivatives
+
+  typedef std::pair<gp_XYZ,gp_XYZ> TxyzPair;
+  TxyzPair my3x3x3GridNodes[ 27 ]; // to compute the first param guess
+  bool     myGridComputed;
+};
+
+
+#endif
diff --git a/src/SMESHUtils/SMESH_Comment.hxx b/src/SMESHUtils/SMESH_Comment.hxx
new file mode 100644 (file)
index 0000000..0aa1565
--- /dev/null
@@ -0,0 +1,76 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+// File      : SMESH_Comment.hxx
+// Created   : Wed Mar 14 18:28:45 2007
+// Author    : Edward AGAPOV (eap)
+// Module    : SMESH
+// $Header: 
+//
+#ifndef SMESH_Comment_HeaderFile
+#define SMESH_Comment_HeaderFile
+
+# include <string>
+# include <sstream>
+
+using namespace std;
+
+/*!
+ * \brief Class to generate string from any type
+ */
+class SMESH_Comment : public string
+{
+  ostringstream _s ;
+
+public :
+
+  SMESH_Comment():string("") {}
+
+  SMESH_Comment(const SMESH_Comment& c):string() {
+    _s << c.c_str() ;
+    this->string::operator=( _s.str() );
+  }
+
+  SMESH_Comment & operator=(const SMESH_Comment& c) {
+    _s << c.c_str() ;
+    this->string::operator=( _s.str() );
+    return *this;
+  }
+
+  template <class T>
+  SMESH_Comment( const T &anything ) {
+    _s << anything ;
+    this->string::operator=( _s.str() );
+  }
+
+  template <class T>
+  SMESH_Comment & operator<<( const T &anything ) {
+    _s << anything ;
+    this->string::operator=( _s.str() );
+    return *this ;
+  }
+
+  operator char*() const {
+    return (char*)c_str();
+  }
+};
+
+
+#endif
diff --git a/src/SMESHUtils/SMESH_ComputeError.hxx b/src/SMESHUtils/SMESH_ComputeError.hxx
new file mode 100644 (file)
index 0000000..204427f
--- /dev/null
@@ -0,0 +1,108 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+//  File   : SMESH_Hypothesis.hxx
+//  Author : Edward AGAPOV (eap)
+//  Module : SMESH
+//
+#ifndef SMESH_ComputeError_HeaderFile
+#define SMESH_ComputeError_HeaderFile
+
+#include <string>
+#include <list>
+#include <boost/shared_ptr.hpp>
+
+class SMESH_Algo;
+class SMDS_MeshElement;
+struct SMESH_ComputeError;
+
+typedef boost::shared_ptr<SMESH_ComputeError> SMESH_ComputeErrorPtr;
+
+// =============================================================
+
+enum SMESH_ComputeErrorName
+{
+  // If you modify it, pls update SMESH_ComputeError::CommonName() below.
+  // Positive values are for algo specific errors
+  COMPERR_OK             = -1,
+  COMPERR_BAD_INPUT_MESH = -2,  //!< wrong mesh on lower submesh
+  COMPERR_STD_EXCEPTION  = -3,  //!< some std exception raised
+  COMPERR_OCC_EXCEPTION  = -4,  //!< OCC exception raised
+  COMPERR_SLM_EXCEPTION  = -5,  //!< SALOME exception raised
+  COMPERR_EXCEPTION      = -6,  //!< other exception raised
+  COMPERR_MEMORY_PB      = -7,  //!< std::bad_alloc exception
+  COMPERR_ALGO_FAILED    = -8,  //!< algo failed for some reason
+  COMPERR_BAD_SHAPE      = -9,  //!< bad geometry
+  COMPERR_WARNING        = -10, //!< algo reports error but sub-mesh is computed anyway
+  COMPERR_CANCELED       = -11  //!< compute canceled
+};
+
+// =============================================================
+/*!
+ * \brief Contains an algorithm and description of an occured error
+ */
+// =============================================================
+
+struct SMESH_ComputeError
+{
+  int               myName; //!< SMESH_ComputeErrorName or anything algo specific
+  std::string       myComment;
+  const SMESH_Algo* myAlgo;
+
+  std::list<const SMDS_MeshElement*> myBadElements; //!< to explain COMPERR_BAD_INPUT_MESH
+
+  static SMESH_ComputeErrorPtr New( int               error   = COMPERR_OK,
+                                    std::string       comment = "",
+                                    const SMESH_Algo* algo    = 0)
+  { return SMESH_ComputeErrorPtr( new SMESH_ComputeError( error, comment, algo )); }
+
+  SMESH_ComputeError(int               error   = COMPERR_OK,
+                     std::string       comment = "",
+                     const SMESH_Algo* algo    = 0)
+    :myName(error),myComment(comment),myAlgo(algo) {}
+
+  bool IsOK()     { return myName == COMPERR_OK; }
+  bool IsKO()     { return myName != COMPERR_OK && myName != COMPERR_WARNING; }
+  bool IsCommon() { return myName < 0; }
+  inline std::string CommonName() const;
+
+};
+
+#define _case2char(err) case err: return #err;
+
+std::string SMESH_ComputeError::CommonName() const
+{
+  switch( myName ) {
+  _case2char(COMPERR_OK            );
+  _case2char(COMPERR_BAD_INPUT_MESH);
+  _case2char(COMPERR_STD_EXCEPTION );
+  _case2char(COMPERR_OCC_EXCEPTION );
+  _case2char(COMPERR_SLM_EXCEPTION );
+  _case2char(COMPERR_EXCEPTION     );
+  _case2char(COMPERR_MEMORY_PB     );
+  _case2char(COMPERR_ALGO_FAILED   );
+  _case2char(COMPERR_BAD_SHAPE     );
+  _case2char(COMPERR_WARNING       );
+  _case2char(COMPERR_CANCELED      );
+  default:;
+  }
+  return "";
+}
+
+#endif
diff --git a/src/SMESHUtils/SMESH_File.cxx b/src/SMESHUtils/SMESH_File.cxx
new file mode 100644 (file)
index 0000000..8a69d1c
--- /dev/null
@@ -0,0 +1,240 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+// File      : SMESH_File.cxx
+// Created   : Wed Mar 10 11:23:25 2010
+// Author    : Edward AGAPOV (eap)
+//
+#include "SMESH_File.hxx"
+#include "utilities.h"
+
+#include <OSD_File.hxx>
+#include <OSD_Path.hxx>
+#include <Standard_ProgramError.hxx>
+#include <Standard_ErrorHandler.hxx>
+#include <Standard_Failure.hxx>
+
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#ifdef WIN32
+#include <io.h>
+#else
+#include <unistd.h>
+#include <sys/mman.h>
+#endif
+
+//================================================================================
+/*!
+ * \brief Creator opening the file for reading by default
+ */
+//================================================================================
+
+SMESH_File::SMESH_File(const std::string& name, bool open)
+  :_name(name), _size(-1), _file(0), _map(0), _pos(0), _end(0)
+{
+  if ( open ) this->open();
+}
+
+//================================================================================
+/*!
+ * \brief Destructor closing the file
+ */
+//================================================================================
+
+SMESH_File::~SMESH_File()
+{
+  close();
+}
+
+//================================================================================
+/*!
+ * \brief Open file for reading. Return true if there is something to read
+ */
+//================================================================================
+
+bool SMESH_File::open()
+{
+  int length = size();
+  if ( !_map && length > 0 )
+  {
+#ifdef WNT
+    _file = CreateFile(_name.data(), GENERIC_READ, FILE_SHARE_READ,
+                       NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+    bool ok = ( _file != INVALID_HANDLE_VALUE );
+#else
+    _file = ::open(_name.data(), O_RDONLY );
+    bool ok = ( _file > 0 );
+#endif
+    if ( ok )
+    {
+#ifdef WNT
+      _mapObj = CreateFileMapping(_file, NULL, PAGE_READONLY, 0, (DWORD)length, NULL);
+      _map = (void*) MapViewOfFile( _mapObj, FILE_MAP_READ, 0, 0, 0 );
+#else
+      _map = ::mmap(0,length,PROT_READ,MAP_PRIVATE,_file,0);
+      if ( _map == MAP_FAILED ) _map = NULL;
+#endif
+      if ( _map != NULL )
+      {
+        _size = length;
+        _pos = (char*) _map;
+        _end = _pos + _size;
+      }
+      else
+      {
+#ifdef WNT
+        CloseHandle(_mapObj);
+        CloseHandle(_file);
+#else
+        ::close(_file);
+#endif
+      }
+    }
+  }
+  return _pos;
+}
+
+//================================================================================
+/*!
+ * \brief Close the file
+ */
+//================================================================================
+
+void SMESH_File::close()
+{
+  if ( _map != NULL )
+  {
+#ifdef WNT
+    UnmapViewOfFile(_map);
+    CloseHandle(_mapObj);
+    CloseHandle(_file);
+#else
+    ::munmap(_map, _size);
+    ::close(_file);
+#endif
+    _map = NULL;
+    _pos = _end = 0;
+    _size = -1;
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Remove the file
+ */
+//================================================================================
+
+bool SMESH_File::remove()
+{
+  close();
+  try {
+    OSD_Path filePath(TCollection_AsciiString((char*)_name.data()));
+    OSD_File(filePath).Remove();
+  }
+  catch ( Standard_ProgramError ) {
+    MESSAGE("Can't remove file: " << _name << " ; file does not exist or permission denied");
+    return false;
+  }
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Return file size
+ */
+//================================================================================
+
+int SMESH_File::size() const
+{
+  if ( _size >= 0 ) return _size; // size of open file
+
+  int size = -1;
+  int file = ::open( _name.data(), O_RDONLY );
+  if ( file > 0 )
+  {
+    struct stat status;
+    int err = fstat( file, &status);
+    if ( !err )
+      size = status.st_size;
+    ::close( file );
+  }
+  return size;
+}
+
+//================================================================================
+/*!
+ * \brief Set cursor to the given position
+ */
+//================================================================================
+
+void SMESH_File::setPos(const char* pos)
+{
+  if ( pos > (const char*)_map && pos < _end )
+    _pos = (char*) pos;
+}
+
+//================================================================================
+/*!
+ * \brief Skip till current line end and return the skipped string
+ */
+//================================================================================
+
+std::string SMESH_File::getLine()
+{
+  std::string line;
+  const char* p = _pos;
+  while ( !eof() )
+    if ( *(++_pos) == '\n' )
+      break;
+  line.append( p, _pos );
+  if ( !eof() ) _pos++;
+  return line;
+}
+
+//================================================================================
+/*!
+ * \brief Move cursor to the file beginning
+ */
+//================================================================================
+
+void SMESH_File::rewind()
+{
+  _pos = (char*) _map;
+}
+
+//================================================================================
+/*!
+ * \brief Fill vector by reading out integers from file. Vector size gives number
+ * of integers to read
+ */
+//================================================================================
+
+bool SMESH_File::getInts(std::vector<int>& ints)
+{
+  int i = 0;
+  while ( i < ints.size() )
+  {
+    while ( !isdigit( *_pos ) && !eof()) ++_pos;
+    if ( eof() ) break;
+    if ( _pos[-1] == '-' ) --_pos;
+    ints[ i++ ] = strtol( _pos, (char**)&_pos, 10 );
+  }
+  return ( i == ints.size() );
+}
diff --git a/src/SMESHUtils/SMESH_File.hxx b/src/SMESHUtils/SMESH_File.hxx
new file mode 100644 (file)
index 0000000..3734e96
--- /dev/null
@@ -0,0 +1,95 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+// File      : SMESH_File.hxx
+// Created   : Wed Mar 10 10:33:04 2010
+// Author    : Edward AGAPOV (eap)
+//
+#ifndef __SMESH_File_HXX__
+#define __SMESH_File_HXX__
+
+#include "SMESH_Utils.hxx"
+
+#include <string>
+#include <vector>
+
+#ifdef WNT
+#include <windows.h>
+#else
+#include <dlfcn.h>
+#endif
+
+/*!
+ * \brief High level util for effective file reading and other file operations
+ */
+class SMESHUtils_EXPORT SMESH_File
+{
+public:
+
+  SMESH_File(const std::string& name, bool open=true);
+
+  ~SMESH_File();
+
+  std::string getName() const { return _name; }
+
+  bool open();
+
+  void close();
+
+  bool remove();
+
+  int size() const;
+
+  // ------------------------
+  // Access to file contents
+  // ------------------------
+
+  operator const char*() const { return _pos; }
+
+  bool operator++() { return ++_pos < _end; }
+
+  void operator +=(int posDelta) { _pos+=posDelta; }
+
+  bool eof() const { return _pos >= _end; }
+
+  const char* getPos() const { return _pos; }
+
+  void setPos(const char* pos);
+
+  std::string getLine();
+
+  void rewind();
+
+  bool getInts(std::vector<int>& ids);
+
+private:
+
+  std::string _name; //!< file name
+  int         _size; //!< file size
+#ifdef WNT
+  HANDLE      _file, _mapObj;
+#else
+  int         _file;
+#endif
+  void*       _map;
+  const char* _pos; //!< current position
+  const char* _end; //!< position after file end
+};
+
+#endif
diff --git a/src/SMESHUtils/SMESH_Octree.cxx b/src/SMESHUtils/SMESH_Octree.cxx
new file mode 100644 (file)
index 0000000..00778a7
--- /dev/null
@@ -0,0 +1,211 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+//  SMESH  SMESH_Octree : global Octree implementation
+//  File      : SMESH_Octree.cxx
+//  Created   : Tue Jan 16 16:00:00 2007
+//  Author    : Nicolas Geimer & Aurélien Motteux(OCC)
+//  Module    : SMESH
+//
+#include "SMESH_Octree.hxx"
+
+//===========================================================================
+/*!
+ * Constructor. limit must be provided at tree root construction.
+ * limit will be deleted by SMESH_Octree.
+ */
+//===========================================================================
+
+SMESH_Octree::SMESH_Octree (SMESH_Octree::Limit* limit):
+  myChildren(NULL),
+  myFather(NULL),
+  myIsLeaf( false ),
+  myLimit( limit ),
+  myLevel(0),
+  myBox(NULL)
+{
+}
+
+//================================================================================
+/*!
+ * \brief Compute the Octree
+ */
+//================================================================================
+
+void SMESH_Octree::compute()
+{
+  if ( myLevel==0 )
+  {
+    myBox = buildRootBox();
+    if ( myLimit->myMinBoxSize > 0. && maxSize() <= myLimit->myMinBoxSize )
+      myIsLeaf = true;
+    else
+      buildChildren();
+  }
+}
+
+//======================================
+/*!
+ * \brief SMESH_Octree Destructor
+ */
+//======================================
+
+SMESH_Octree::~SMESH_Octree ()
+{
+  if(myChildren != NULL)
+  {
+    if(!isLeaf())
+    {
+      for(int i = 0; i<8; i++)
+        delete myChildren[i];
+      delete[] myChildren;
+      myChildren = 0;
+    }
+  }
+  if ( myBox )
+    delete myBox;
+  myBox = 0;
+  if ( level() == 0 )
+    delete myLimit;
+  myLimit = 0;
+}
+
+//=================================================================
+/*!
+ * \brief Build the 8 children boxes and call buildChildrenData()
+ */
+//=================================================================
+
+void SMESH_Octree::buildChildren()
+{
+  if ( isLeaf() ) return;
+
+  myChildren = new SMESH_Octree*[8];
+
+  gp_XYZ min = myBox->CornerMin();
+  gp_XYZ max = myBox->CornerMax();
+  gp_XYZ HSize = (max - min)/2.;
+  gp_XYZ mid = min + HSize;
+  gp_XYZ childHsize = HSize/2.;
+
+  // get the whole model size
+  double rootSize = 0;
+  {
+    SMESH_Octree* root = this;
+    while ( root->myLevel > 0 )
+      root = root->myFather;
+    rootSize = root->maxSize();
+  }
+  Standard_Real XminChild, YminChild, ZminChild;
+  gp_XYZ minChild;
+  for (int i = 0; i < 8; i++)
+  {
+    // We build the eight boxes, we need 2 points to do that:
+    // Min and Mid
+    // In binary, we can write i from 0 to 7
+    // For instance :
+    // 5 is 101, it corresponds here in coordinates to ZYX
+    // If coordinate is 0 in Y-> box from Ymin to Ymid
+    // If coordinate is 1 in Y-> box from Ymid to Ymax
+    // Same scheme for X and Z
+    // I need the minChild to build the Bnd_B3d box.
+
+    XminChild = (i%2==0)?min.X():mid.X();
+    YminChild = ((i%4)/2==0)?min.Y():mid.Y();
+    ZminChild = (i<4)?min.Z():mid.Z();
+    minChild.SetCoord(XminChild, YminChild, ZminChild);
+
+    // The child is of the same type than its father (For instance, a SMESH_OctreeNode)
+    // We allocate the memory we need for the child
+    myChildren[i] = allocateOctreeChild();
+    // and we assign to him its box.
+    myChildren[i]->myFather = this;
+    myChildren[i]->myLimit = myLimit;
+    myChildren[i]->myLevel = myLevel + 1;
+    myChildren[i]->myBox = new Bnd_B3d(minChild+childHsize,childHsize);
+    myChildren[i]->myBox->Enlarge( rootSize * 1e-10 );
+    if ( myLimit->myMinBoxSize > 0. && myChildren[i]->maxSize() <= myLimit->myMinBoxSize )
+      myChildren[i]->myIsLeaf = true;
+  }
+
+  // After building the 8 boxes, we put the data into the children.
+  buildChildrenData();
+
+  //After we pass to the next level of the Octree
+  for (int i = 0; i<8; i++)
+    myChildren[i]->buildChildren();
+}
+
+//================================================================================
+/*!
+ * \brief Tell if Octree is a leaf or not
+ *        An inheriting class can influence it via myIsLeaf protected field
+ */
+//================================================================================
+
+bool SMESH_Octree::isLeaf() const
+{
+  return myIsLeaf || ((myLimit->myMaxLevel > 0) ? (level() >= myLimit->myMaxLevel) : false );
+}
+
+//===========================================================================
+/*!
+ * \brief Compute the bigger dimension of my box
+ */
+//===========================================================================
+
+double SMESH_Octree::maxSize() const
+{
+  if ( myBox && !myBox->IsVoid() )
+  {
+    gp_XYZ min = myBox->CornerMin();
+    gp_XYZ max = myBox->CornerMax();
+    gp_XYZ Size = (max - min);
+    double returnVal = (Size.X()>Size.Y())?Size.X():Size.Y();
+    return (returnVal>Size.Z())?returnVal:Size.Z();
+  }
+  return 0.;
+}
+
+//================================================================================
+/*!
+ * \brief Return height of the tree, full or from this level to topest leaf
+ */
+//================================================================================
+
+int SMESH_Octree::getHeight(const bool full) const
+{
+  if ( full && myFather )
+    return myFather->getHeight( true );
+
+  if ( isLeaf() )
+    return 1;
+
+  int heigth = 0;
+  for (int i = 0; i<8; i++)
+  {
+    int h = myChildren[i]->getHeight( false );
+    if ( h > heigth )
+      heigth = h;
+  }
+  return heigth + 1;
+}
diff --git a/src/SMESHUtils/SMESH_Octree.hxx b/src/SMESHUtils/SMESH_Octree.hxx
new file mode 100644 (file)
index 0000000..97d767a
--- /dev/null
@@ -0,0 +1,127 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+//  SMESH SMESH_Octree : global Octree implementation
+//  File      : SMESH_Octree.hxx
+//  Created   : Tue Jan 16 16:00:00 2007
+//  Author    : Nicolas Geimer & Aurélien Motteux (OCC)
+//  Module    : SMESH
+//
+#ifndef _SMESH_OCTREE_HXX_
+#define _SMESH_OCTREE_HXX_
+
+#include "SMESH_Utils.hxx"
+#include <Bnd_B3d.hxx>
+
+class SMESHUtils_EXPORT SMESH_Octree {
+
+public:
+
+  // Data limiting the tree height
+  struct Limit {
+    // MaxLevel of the Octree
+    int    myMaxLevel;
+    // Minimal size of the Box
+    double myMinBoxSize;
+
+    // Default:
+    // maxLevel-> 8^8 = 16777216 terminal trees
+    // minSize -> box size not checked
+    Limit(int maxLevel=8, double minSize=0.):myMaxLevel(maxLevel),myMinBoxSize(minSize) {}
+    virtual ~Limit() {} // it can be inherited
+  };
+
+  // Constructor. limit must be provided at tree root construction.
+  // limit will be deleted by SMESH_Octree
+  SMESH_Octree (Limit* limit=0);
+
+  // Destructor
+  virtual ~SMESH_Octree ();
+
+  // Compute the Octree. Must be called by constructor of inheriting class
+  void                   compute();
+
+  // Tell if Octree is a leaf or not.
+  // An inheriting class can influence it via myIsLeaf protected field
+  bool                   isLeaf() const;
+
+  // Return its level
+  int                    level() const { return myLevel; }
+
+  // Get box to the 3d Bounding Box of the Octree
+  const Bnd_B3d&         getBox() const { return *myBox; }
+
+  // Compute the bigger dimension of my box
+  double                 maxSize() const;
+
+  // Return index of a child the given point is in
+  inline int             getChildIndex(double x, double y, double z, const gp_XYZ& boxMiddle)const;
+
+  // Return height of the tree, full or from this level to topest leaf
+  int                    getHeight(const bool full=true) const;
+
+protected:
+  // Return box of the whole tree
+  virtual Bnd_B3d*       buildRootBox() = 0;
+
+  // Constructor for children
+  virtual SMESH_Octree*  allocateOctreeChild() const = 0;
+
+  // Build the data in the 8 children
+  virtual void           buildChildrenData() = 0;
+
+  // members
+
+  // Array of 8 Octree children
+  SMESH_Octree** myChildren;
+
+  // Point the father, set to NULL for the level 0
+  SMESH_Octree*  myFather;
+
+  // Tell us if the Octree is a leaf or not
+  bool           myIsLeaf;
+
+  // Tree limit
+  const Limit*   myLimit;
+
+private:
+  // Build the 8 children boxes recursively
+  void                   buildChildren();
+
+  // Level of the Octree
+  int            myLevel;
+
+  Bnd_B3d*       myBox;
+};
+
+//================================================================================
+/*!
+ * \brief Return index of a child the given point is in
+ */
+//================================================================================
+
+inline int SMESH_Octree::getChildIndex(double x, double y, double z, const gp_XYZ& mid) const
+{
+  return (x > mid.X()) + ( y > mid.Y())*2 + (z > mid.Z())*4;
+}
+
+#endif
diff --git a/src/SMESHUtils/SMESH_OctreeNode.cxx b/src/SMESHUtils/SMESH_OctreeNode.cxx
new file mode 100644 (file)
index 0000000..d14a50a
--- /dev/null
@@ -0,0 +1,437 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+//  SMESH SMESH_OctreeNode : Octree with Nodes set
+//  inherites global class SMESH_Octree
+//  File      : SMESH_OctreeNode.cxx
+//  Created   : Tue Jan 16 16:00:00 2007
+//  Author    : Nicolas Geimer & Aurelien Motteux (OCC)
+//  Module    : SMESH
+//
+#include "SMESH_OctreeNode.hxx"
+
+#include "SMDS_SetIterator.hxx"
+#include <gp_Pnt.hxx>
+
+using namespace std;
+
+//===============================================================
+/*!
+ * \brief Constructor : Build all the Octree using Compute()
+ * \param theNodes - Set of nodes, the Octree is built from this nodes
+ * \param maxLevel - Maximum level for the leaves
+ * \param maxNbNodes - Maximum number of nodes, a leaf can contain
+ * \param minBoxSize - Minimal size of the Octree Box
+ */
+//================================================================
+SMESH_OctreeNode::SMESH_OctreeNode (const TIDSortedNodeSet & theNodes, const int maxLevel,
+                                    const int maxNbNodes , const double minBoxSize )
+  :SMESH_Octree( new SMESH_Octree::Limit( maxLevel,minBoxSize)),
+  myMaxNbNodes(maxNbNodes),
+  myNodes(theNodes)
+{
+  compute();
+}
+
+//================================================================================
+/*!
+ * \brief Constructor used to allocate a child
+ */
+//================================================================================
+
+SMESH_OctreeNode::SMESH_OctreeNode (int maxNbNodes):
+  SMESH_Octree(), myMaxNbNodes(maxNbNodes)
+{
+}
+
+//==================================================================================
+/*!
+ * \brief Construct an empty SMESH_OctreeNode used by SMESH_Octree::buildChildren()
+ */
+//==================================================================================
+
+SMESH_Octree* SMESH_OctreeNode::allocateOctreeChild() const
+{
+  return new SMESH_OctreeNode(myMaxNbNodes);
+}
+
+//======================================
+/*!
+ * \brief Compute the first bounding box
+ *
+ * We take the max/min coord of the nodes
+ */
+//======================================
+
+Bnd_B3d* SMESH_OctreeNode::buildRootBox()
+{
+  Bnd_B3d* box = new Bnd_B3d;
+  TIDSortedNodeSet::iterator it = myNodes.begin();
+  for (; it != myNodes.end(); it++) {
+    const SMDS_MeshNode* n1 = *it;
+    gp_XYZ p1( n1->X(), n1->Y(), n1->Z() );
+    box->Add(p1);
+  }
+  if ( myNodes.size() <= myMaxNbNodes )
+    myIsLeaf = true;
+
+  return box;
+}
+
+//====================================================================================
+/*!
+ * \brief Tells us if Node is inside the current box with the precision "precision"
+ * \param Node - Node
+ * \param precision - The box is enlarged with this precision
+ * \retval bool - True if Node is in the box within precision
+ */
+//====================================================================================
+
+const bool SMESH_OctreeNode::isInside (const gp_XYZ& p, const double precision)
+{
+  if (precision <= 0.)
+    return !(getBox().IsOut(p));
+  Bnd_B3d BoxWithPrecision = getBox();
+  BoxWithPrecision.Enlarge(precision);
+  return ! BoxWithPrecision.IsOut(p);
+}
+
+//================================================
+/*!
+ * \brief Set the data of the children
+ * Shares the father's data with each of his child
+ */
+//================================================
+void SMESH_OctreeNode::buildChildrenData()
+{
+  gp_XYZ min = getBox().CornerMin();
+  gp_XYZ max = getBox().CornerMax();
+  gp_XYZ mid = (min + max)/2.;
+
+  TIDSortedNodeSet::iterator it = myNodes.begin();
+  while (it != myNodes.end())
+  {
+    const SMDS_MeshNode* n1 = *it;
+    int ChildBoxNum = getChildIndex( n1->X(), n1->Y(), n1->Z(), mid );
+    SMESH_OctreeNode* myChild = dynamic_cast<SMESH_OctreeNode*> (myChildren[ChildBoxNum]);
+    myChild->myNodes.insert(myChild->myNodes.end(),n1);
+    myNodes.erase( it );
+    it = myNodes.begin();
+  }
+  for (int i = 0; i < 8; i++)
+  {
+    SMESH_OctreeNode* myChild = dynamic_cast<SMESH_OctreeNode*> (myChildren[i]);
+    if ( myChild->myNodes.size() <= myMaxNbNodes )
+      myChild->myIsLeaf = true;
+  }
+}
+
+//===================================================================
+/*!
+ * \brief Return in Result a list of Nodes potentials to be near Node
+ * \param Node - Node
+ * \param precision - precision used
+ * \param Result - list of Nodes potentials to be near Node
+ */
+//====================================================================
+void SMESH_OctreeNode::NodesAround (const SMDS_MeshNode * Node,
+                                    list<const SMDS_MeshNode*>* Result,
+                                    const double precision)
+{
+  gp_XYZ p(Node->X(), Node->Y(), Node->Z());
+  if (isInside(p, precision))
+  {
+    if (isLeaf())
+    {
+      Result->insert(Result->end(), myNodes.begin(), myNodes.end());
+    }
+    else
+    {
+      for (int i = 0; i < 8; i++)
+      {
+        SMESH_OctreeNode* myChild = dynamic_cast<SMESH_OctreeNode*> (myChildren[i]);
+        myChild->NodesAround(Node, Result, precision);
+      }
+    }
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Return in dist2Nodes nodes mapped to their square distance from Node
+ *  \param node - node to find nodes closest to
+ *  \param dist2Nodes - map of found nodes and their distances
+ *  \param precision - radius of a sphere to check nodes inside
+ *  \retval bool - true if an exact overlapping found
+ */
+//================================================================================
+
+bool SMESH_OctreeNode::NodesAround(const gp_XYZ &node,
+                                   map<double, const SMDS_MeshNode*>& dist2Nodes,
+                                   double                             precision)
+{
+  if ( !dist2Nodes.empty() )
+    precision = min ( precision, sqrt( dist2Nodes.begin()->first ));
+  else if ( precision == 0. )
+    precision = maxSize() / 2;
+
+  //gp_XYZ p(node->X(), node->Y(), node->Z());
+  if (isInside(node, precision))
+  {
+    if (!isLeaf())
+    {
+      // first check a child containing node
+      gp_XYZ mid = (getBox().CornerMin() + getBox().CornerMax()) / 2.;
+      int nodeChild  = getChildIndex( node.X(), node.Y(), node.Z(), mid );
+      if ( ((SMESH_OctreeNode*) myChildren[nodeChild])->NodesAround(node, dist2Nodes, precision))
+        return true;
+      
+      for (int i = 0; i < 8; i++)
+        if ( i != nodeChild )
+          if (((SMESH_OctreeNode*) myChildren[i])->NodesAround(node, dist2Nodes, precision))
+            return true;
+    }
+    else if ( NbNodes() > 0 )
+    {
+      double minDist = precision * precision;
+      gp_Pnt p1 ( node.X(), node.Y(), node.Z() );
+      TIDSortedNodeSet::iterator nIt = myNodes.begin();
+      for ( ; nIt != myNodes.end(); ++nIt )
+      {
+        gp_Pnt p2 ( (*nIt)->X(), (*nIt)->Y(), (*nIt)->Z() );
+        double dist2 = p1.SquareDistance( p2 );
+        if ( dist2 < minDist )
+          dist2Nodes.insert( make_pair( minDist = dist2, *nIt ));
+      }
+//       if ( dist2Nodes.size() > 1 ) // leave only closest node in dist2Nodes
+//         dist2Nodes.erase( ++dist2Nodes.begin(), dist2Nodes.end());
+
+      return ( sqrt( minDist) <= precision * 1e-12 );
+    }
+  }
+  return false;
+}
+
+//=============================
+/*!
+ * \brief  Return in theGroupsOfNodes a list of group of nodes close to each other within theTolerance
+ * Search for all the nodes in theSetOfNodes
+ * Static Method : no need to create an SMESH_OctreeNode
+ * \param theSetOfNodes - set of nodes we look at, modified during research
+ * \param theGroupsOfNodes - list of nodes closed to each other returned
+ * \param theTolerance - Precision used, default value is 0.00001
+ * \param maxLevel - Maximum level for SMESH_OctreeNode constructed, default value is -1 (Infinite)
+ * \param maxNbNodes - maximum Nodes in a Leaf of the SMESH_OctreeNode constructed, default value is 5
+ */
+//=============================
+void SMESH_OctreeNode::FindCoincidentNodes (TIDSortedNodeSet& theSetOfNodes,
+                                            list< list< const SMDS_MeshNode*> >* theGroupsOfNodes,
+                                            const double theTolerance,
+                                            const int maxLevel,
+                                            const int maxNbNodes)
+{
+  // VSR 14/10/2011: limit max number of the levels in order to avoid endless recursing
+  const int MAX_LEVEL = 10;
+  SMESH_OctreeNode theOctreeNode(theSetOfNodes, maxLevel < 0 ? MAX_LEVEL : maxLevel, maxNbNodes, theTolerance);
+  theOctreeNode.FindCoincidentNodes (&theSetOfNodes, theTolerance, theGroupsOfNodes);
+}
+
+//=============================
+/*!
+ * \brief  Return in theGroupsOfNodes a list of group of nodes close to each other within theTolerance
+ * Search for all the nodes in theSetOfNodes
+ * \note  The Octree itself is also modified by this method
+ * \param theSetOfNodes - set of nodes we look at, modified during research
+ * \param theTolerance - Precision used
+ * \param theGroupsOfNodes - list of nodes closed to each other returned
+ */
+//=============================
+void SMESH_OctreeNode::FindCoincidentNodes ( TIDSortedNodeSet* theSetOfNodes,
+                                             const double               theTolerance,
+                                             list< list< const SMDS_MeshNode*> >* theGroupsOfNodes)
+{
+  TIDSortedNodeSet::iterator it1 = theSetOfNodes->begin();
+  list<const SMDS_MeshNode*>::iterator it2;
+
+  while (it1 != theSetOfNodes->end())
+  {
+    const SMDS_MeshNode * n1 = *it1;
+
+    list<const SMDS_MeshNode*> ListOfCoincidentNodes;// Initialize the lists via a declaration, it's enough
+
+    list<const SMDS_MeshNode*> * groupPtr = 0;
+
+    // Searching for Nodes around n1 and put them in ListofCoincidentNodes.
+    // Found nodes are also erased from theSetOfNodes
+    FindCoincidentNodes(n1, theSetOfNodes, &ListOfCoincidentNodes, theTolerance);
+
+    // We build a list {n1 + his neigbours} and add this list in theGroupsOfNodes
+    for (it2 = ListOfCoincidentNodes.begin(); it2 != ListOfCoincidentNodes.end(); it2++)
+    {
+      const SMDS_MeshNode* n2 = *it2;
+      if ( !groupPtr )
+      {
+        theGroupsOfNodes->push_back( list<const SMDS_MeshNode*>() );
+        groupPtr = & theGroupsOfNodes->back();
+        groupPtr->push_back( n1 );
+      }
+      if (groupPtr->front() > n2)
+        groupPtr->push_front( n2 );
+      else
+        groupPtr->push_back( n2 );
+    }
+    if (groupPtr != 0)
+      groupPtr->sort();
+
+    theSetOfNodes->erase(it1);
+    it1 = theSetOfNodes->begin();
+  }
+}
+
+//======================================================================================
+/*!
+ * \brief Return a list of nodes closed to Node and remove it from SetOfNodes
+ * \note  The Octree itself is also modified by this method
+ * \param Node - We're searching the nodes next to him.
+ * \param SetOfNodes - set of nodes in which we erase the found nodes
+ * \param Result - list of nodes closed to Node
+ * \param precision - Precision used
+ */
+//======================================================================================
+void SMESH_OctreeNode::FindCoincidentNodes (const SMDS_MeshNode * Node,
+                                            TIDSortedNodeSet* SetOfNodes,
+                                            list<const SMDS_MeshNode*>* Result,
+                                            const double precision)
+{
+  gp_XYZ p(Node->X(), Node->Y(), Node->Z());
+  bool isInsideBool = isInside(p, precision);
+
+  if (isInsideBool)
+  {
+    // I'm only looking in the leaves, since all the nodes are stored there.
+    if (isLeaf())
+    {
+      gp_Pnt p1 (Node->X(), Node->Y(), Node->Z());
+
+      TIDSortedNodeSet myNodesCopy = myNodes;
+      TIDSortedNodeSet::iterator it = myNodesCopy.begin();
+      double tol2 = precision * precision;
+      bool squareBool;
+
+      while (it != myNodesCopy.end())
+      {
+        const SMDS_MeshNode* n2 = *it;
+        // We're only looking at nodes with a superior Id.
+        // JFA: Why?
+        //if (Node->GetID() < n2->GetID())
+        if (Node->GetID() != n2->GetID()) // JFA: for bug 0020185
+        {
+          gp_Pnt p2 (n2->X(), n2->Y(), n2->Z());
+          // Distance optimized computation
+          squareBool = (p1.SquareDistance( p2 ) <= tol2);
+
+          // If n2 inside the SquareDistance, we add it in Result and remove it from SetOfNodes and myNodes
+          if (squareBool)
+          {
+            Result->insert(Result->begin(), n2);
+            SetOfNodes->erase( n2 );
+            myNodes.erase( n2 );
+          }
+        }
+        //myNodesCopy.erase( it );
+        //it = myNodesCopy.begin();
+        it++;
+      }
+      if (Result->size() > 0)
+        myNodes.erase(Node); // JFA: for bug 0020185
+    }
+    else
+    {
+      // If I'm not a leaf, I'm going to see my children !
+      for (int i = 0; i < 8; i++)
+      {
+        SMESH_OctreeNode* myChild = dynamic_cast<SMESH_OctreeNode*> (myChildren[i]);
+        myChild->FindCoincidentNodes(Node, SetOfNodes, Result, precision);
+      }
+    }
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Update data according to node movement
+ */
+//================================================================================
+
+void SMESH_OctreeNode::UpdateByMoveNode( const SMDS_MeshNode* node, const gp_Pnt& toPnt )
+{
+  if ( isLeaf() )
+  {
+    TIDSortedNodeSet::iterator pNode = myNodes.find( node );
+    bool nodeInMe = ( pNode != myNodes.end() );
+
+    bool pointInMe = isInside( toPnt.Coord(), 1e-10 );
+
+    if ( pointInMe != nodeInMe )
+    {
+      if ( pointInMe )
+        myNodes.insert( node );
+      else
+        myNodes.erase( node );
+    }
+  }
+  else if ( myChildren )
+  {
+    gp_XYZ mid = (getBox().CornerMin() + getBox().CornerMax()) / 2.;
+    int nodeChild  = getChildIndex( node->X(), node->Y(), node->Z(), mid );
+    int pointChild = getChildIndex( toPnt.X(), toPnt.Y(), toPnt.Z(), mid );
+    if ( nodeChild != pointChild )
+    {
+      ((SMESH_OctreeNode*) myChildren[ nodeChild  ])->UpdateByMoveNode( node, toPnt );
+      ((SMESH_OctreeNode*) myChildren[ pointChild ])->UpdateByMoveNode( node, toPnt );
+    }
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Return iterator over children
+ */
+//================================================================================
+SMESH_OctreeNodeIteratorPtr SMESH_OctreeNode::GetChildrenIterator()
+{
+  return SMESH_OctreeNodeIteratorPtr
+    ( new SMDS_SetIterator< SMESH_OctreeNode*, SMESH_Octree** >
+      ( myChildren, (( isLeaf() || !myChildren ) ? myChildren : &myChildren[ 8 ] )));
+}
+
+//================================================================================
+/*!
+ * \brief Return nodes iterator
+ */
+//================================================================================
+SMDS_NodeIteratorPtr SMESH_OctreeNode::GetNodeIterator()
+{
+  return SMDS_NodeIteratorPtr
+    ( new SMDS_SetIterator< SMDS_pNode, TIDSortedNodeSet::const_iterator >
+      ( myNodes.begin(), myNodes.size() ? myNodes.end() : myNodes.begin()));
+}
diff --git a/src/SMESHUtils/SMESH_OctreeNode.hxx b/src/SMESHUtils/SMESH_OctreeNode.hxx
new file mode 100644 (file)
index 0000000..cc66a27
--- /dev/null
@@ -0,0 +1,137 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+//  SMESH SMESH_OctreeNode : Octree with Nodes set
+//  inherites global class SMESH_Octree
+//  File      : SMESH_OctreeNode.hxx
+//  Created   : Tue Jan 16 16:00:00 2007
+//  Author    : Nicolas Geimer & Aurelien Motteux  (OCC)
+//  Module    : SMESH
+//
+#ifndef _SMESH_OCTREENODE_HXX_
+#define _SMESH_OCTREENODE_HXX_
+
+#include "SMESH_Utils.hxx"
+#include "SMESH_Octree.hxx"
+#include <gp_Pnt.hxx>
+#include "SMDS_MeshNode.hxx"
+
+#include <list>
+#include <set>
+#include <map>
+
+#include "SMDS_ElemIterator.hxx"
+
+//forward declaration
+class SMDS_MeshNode;
+class SMESH_OctreeNode;
+
+typedef SMDS_Iterator<SMESH_OctreeNode*>              SMESH_OctreeNodeIterator;
+typedef boost::shared_ptr<SMESH_OctreeNodeIterator>   SMESH_OctreeNodeIteratorPtr;
+typedef std::set< const SMDS_MeshNode*, TIDCompare >  TIDSortedNodeSet;
+
+class SMESHUtils_EXPORT SMESH_OctreeNode : public SMESH_Octree {
+
+public:
+
+  // Constructor
+  SMESH_OctreeNode (const TIDSortedNodeSet& theNodes, const int maxLevel = 8,
+                    const int maxNbNodes = 5, const double minBoxSize = 0.);
+
+//=============================
+/*!
+ * \brief Empty destructor
+ */
+//=============================
+  virtual ~SMESH_OctreeNode () {};
+
+  // Tells us if Node is inside the current box with the precision "precision"
+  virtual const bool isInside(const gp_XYZ& p, const double precision = 0.);
+
+  // Return in Result a list of Nodes potentials to be near Node
+  void               NodesAround(const SMDS_MeshNode *            Node,
+                                 std::list<const SMDS_MeshNode*>* Result,
+                                 const double                     precision = 0.);
+
+  // Return in dist2Nodes nodes mapped to their square distance from Node
+  bool               NodesAround(const gp_XYZ& node,
+                                 std::map<double, const SMDS_MeshNode*>& dist2Nodes,
+                                 double                                  precision);
+
+  // Return in theGroupsOfNodes a list of group of nodes close to each other within theTolerance
+  // Search for all the nodes in nodes
+  void               FindCoincidentNodes ( TIDSortedNodeSet*           nodes,
+                                           const double                theTolerance,
+                                           std::list< std::list< const SMDS_MeshNode*> >* theGroupsOfNodes);
+
+  // Static method that return in theGroupsOfNodes a list of group of nodes close to each other within
+  // theTolerance search for all the nodes in nodes
+  static void        FindCoincidentNodes ( TIDSortedNodeSet&                              nodes,
+                                           std::list< std::list< const SMDS_MeshNode*> >* theGroupsOfNodes,
+                                           const double theTolerance = 0.00001,
+                                           const int maxLevel = -1,
+                                           const int maxNbNodes = 5);
+  /*!
+   * \brief Update data according to node movement
+   */
+  void                        UpdateByMoveNode( const SMDS_MeshNode* node, const gp_Pnt& toPnt );
+  /*!
+   * \brief Return iterator over children
+   */
+  SMESH_OctreeNodeIteratorPtr GetChildrenIterator();
+  /*!
+   * \brief Return nodes iterator
+   */
+  SMDS_NodeIteratorPtr        GetNodeIterator();
+  /*!
+   * \brief Return nb nodes in a tree
+   */
+  int                         NbNodes() const { return myNodes.size(); }
+
+protected:
+
+  SMESH_OctreeNode (int maxNbNodes );
+
+  // Compute the bounding box of the whole set of nodes myNodes
+  virtual Bnd_B3d*      buildRootBox();
+
+  // Shares the father's data with each of his child
+  virtual void          buildChildrenData();
+
+  // Construct an empty SMESH_OctreeNode used by SMESH_Octree::buildChildren()
+  virtual SMESH_Octree* allocateOctreeChild() const;
+
+  // Return in result a list of nodes closed to Node and remove it from SetOfNodes
+  void                  FindCoincidentNodes( const SMDS_MeshNode *            Node,
+                                             TIDSortedNodeSet*                SetOfNodes,
+                                             std::list<const SMDS_MeshNode*>* Result,
+                                             const double                     precision);
+
+  // The max number of nodes a leaf box can contain
+  int                myMaxNbNodes;
+
+  // The set of nodes inside the box of the Octree (Empty if Octree is not a leaf)
+  TIDSortedNodeSet   myNodes;
+
+};
+
+#endif
diff --git a/src/SMESHUtils/SMESH_TypeDefs.hxx b/src/SMESHUtils/SMESH_TypeDefs.hxx
new file mode 100644 (file)
index 0000000..edb0f24
--- /dev/null
@@ -0,0 +1,184 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+// File      : SMESH_TypeDefs.hxx
+// Created   : Thu Jan 27 18:38:33 2011
+// Author    : Edward AGAPOV (eap)
+
+
+#ifndef __SMESH_TypeDefs_HXX__
+#define __SMESH_TypeDefs_HXX__
+
+#include "SMESH_Utils.hxx"
+
+#include <SMDS_MeshNode.hxx>
+
+#include <gp_XYZ.hxx>
+
+#include <map>
+#include <list>
+#include <set>
+#include <cassert>
+
+typedef std::map<const SMDS_MeshElement*,
+                 std::list<const SMDS_MeshElement*> >        TElemOfElemListMap;
+typedef std::map<const SMDS_MeshNode*, const SMDS_MeshNode*> TNodeNodeMap;
+
+//!< Set of elements sorted by ID, to be used to assure predictability of edition
+typedef std::set< const SMDS_MeshElement*, TIDCompare >      TIDSortedElemSet;
+typedef std::set< const SMDS_MeshNode*,    TIDCompare >      TIDSortedNodeSet;
+
+typedef std::pair< const SMDS_MeshNode*, const SMDS_MeshNode* >   NLink;
+
+
+namespace SMESHUtils
+{
+  /*!
+   * \brief Enforce freeing memory allocated by std::vector
+   */
+  template <class TVECTOR>
+  void FreeVector(TVECTOR& vec)
+  {
+    TVECTOR v2;
+    vec.swap( v2 );
+  }
+  template <class TVECTOR>
+  void CompactVector(TVECTOR& vec)
+  {
+    TVECTOR v2( vec );
+    vec.swap( v2 );
+  }
+}
+
+//=======================================================================
+/*!
+ * \brief A sorted pair of nodes
+ */
+//=======================================================================
+
+struct SMESH_TLink: public NLink
+{
+  SMESH_TLink(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2 ):NLink( n1, n2 )
+  { if ( n1->GetID() < n2->GetID() ) std::swap( first, second ); }
+  SMESH_TLink(const NLink& link ):NLink( link )
+  { if ( first->GetID() < second->GetID() ) std::swap( first, second ); }
+  const SMDS_MeshNode* node1() const { return first; }
+  const SMDS_MeshNode* node2() const { return second; }
+};
+
+//=======================================================================
+/*!
+ * \brief SMESH_TLink knowing its orientation
+ */
+//=======================================================================
+
+struct SMESH_OrientedLink: public SMESH_TLink
+{
+  bool _reversed;
+  SMESH_OrientedLink(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2 )
+    : SMESH_TLink( n1, n2 ), _reversed( n1 != node1() ) {}
+};
+
+//------------------------------------------
+/*!
+ * \brief SMDS_MeshNode -> gp_XYZ convertor
+ */
+//------------------------------------------
+struct SMESH_TNodeXYZ : public gp_XYZ
+{
+  const SMDS_MeshNode* _node;
+  double               _xyz[3];
+  SMESH_TNodeXYZ( const SMDS_MeshElement* e):gp_XYZ(0,0,0),_node(0) {
+    if (e) {
+      assert( e->GetType() == SMDSAbs_Node );
+      _node = static_cast<const SMDS_MeshNode*>(e);
+      _node->GetXYZ(_xyz); // - thread safe getting coords
+      SetCoord( _xyz[0], _xyz[1], _xyz[2] );
+    }
+  }
+  double Distance(const SMDS_MeshNode* n)       const { return (SMESH_TNodeXYZ( n )-*this).Modulus(); }
+  double SquareDistance(const SMDS_MeshNode* n) const { return (SMESH_TNodeXYZ( n )-*this).SquareModulus(); }
+  bool operator==(const SMESH_TNodeXYZ& other) const { return _node == other._node; }
+};
+
+// --------------------------------------------------------------------------------
+// class SMESH_SequenceOfElemPtr
+#include <NCollection_DefineSequence.hxx>
+
+class SMDS_MeshElement;
+
+typedef const SMDS_MeshElement* SMDS_MeshElementPtr;
+
+DEFINE_BASECOLLECTION (SMESH_BaseCollectionElemPtr, SMDS_MeshElementPtr)
+DEFINE_SEQUENCE (SMESH_SequenceOfElemPtr, SMESH_BaseCollectionElemPtr, SMDS_MeshElementPtr)
+
+
+// --------------------------------------------------------------------------------
+// class SMESH_SequenceOfNode
+typedef const SMDS_MeshNode* SMDS_MeshNodePtr;
+
+DEFINE_BASECOLLECTION (SMESH_BaseCollectionNodePtr, SMDS_MeshNodePtr)
+DEFINE_SEQUENCE(SMESH_SequenceOfNode,
+                SMESH_BaseCollectionNodePtr, SMDS_MeshNodePtr)
+
+// --------------------------------------------------------------------------------
+// #include "SMESHDS_DataMapOfShape.hxx"
+
+// #include <NCollection_DefineIndexedMap.hxx>
+
+// #include <TopoDS_Shape.hxx>
+
+///  Class SMESH_IndexedMapOfShape
+
+// DEFINE_BASECOLLECTION (SMESH_BaseCollectionShape, TopoDS_Shape)
+// DEFINE_INDEXEDMAP (SMESH_IndexedMapOfShape, SMESH_BaseCollectionShape, TopoDS_Shape)
+
+///  Class SMESH_IndexedDataMapOfShapeIndexedMapOfShape
+
+// DEFINE_BASECOLLECTION (SMESH_BaseCollectionIndexedMapOfShape, SMESH_IndexedMapOfShape)
+// DEFINE_INDEXEDDATAMAP (SMESH_IndexedDataMapOfShapeIndexedMapOfShape,
+//                        SMESH_BaseCollectionIndexedMapOfShape, TopoDS_Shape,
+//                        SMESH_IndexedMapOfShape)
+
+// --------------------------------------------------------------------------------
+// class SMESH_DataMapOfElemPtrSequenceOfElemPtr
+
+// SMESHUtils_EXPORT 
+// inline Standard_Integer HashCode(SMDS_MeshElementPtr theElem,
+//                                  const Standard_Integer theUpper)
+// {
+//   void* anElem = (void*) theElem;
+//   return HashCode(anElem,theUpper);
+// }
+
+// SMESHUtils_EXPORT 
+// inline Standard_Boolean IsEqual(SMDS_MeshElementPtr theOne,
+//                                 SMDS_MeshElementPtr theTwo)
+// {
+//   return theOne == theTwo;
+// }
+
+// DEFINE_BASECOLLECTION (SMESH_BaseCollectionSequenceOfElemPtr, SMESH_SequenceOfElemPtr)
+// DEFINE_DATAMAP (SMESH_DataMapOfElemPtrSequenceOfElemPtr,
+//                 SMESH_BaseCollectionSequenceOfElemPtr,
+//                 SMDS_MeshElementPtr, SMESH_SequenceOfElemPtr)
+
+#endif
diff --git a/src/SMESHUtils/SMESH_Utils.hxx b/src/SMESHUtils/SMESH_Utils.hxx
new file mode 100755 (executable)
index 0000000..45c4a2c
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+//  File   : SMESH_Utils.hxx
+//  Author : Alexander A. BORODIN
+//  Module : SMESH
+//
+#ifndef _SMESH_Utils_hxx_
+#define _SMESH_Utils_hxx_
+
+#ifdef WNT
+ #if defined SMESHUtils_EXPORTS
+  #define SMESHUtils_EXPORT __declspec( dllexport )
+ #else
+  #define SMESHUtils_EXPORT __declspec( dllimport )
+ #endif
+#else
+ #define SMESHUtils_EXPORT
+#endif
+
+#endif
index 2a15a44df935ab6b5d9607c143783dd28a744204..2f748f7da54ee59b964aba2b309a37ce182a0ad2 100644 (file)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 #  File   : Makefile.in
 #  Author : Paul RASCLE, EDF
@@ -48,6 +46,8 @@ salomeinclude_HEADERS = \
        SMESH_Pattern_i.hxx \
        SMESH_2smeshpy.hxx \
        SMESH_NoteBook.hxx \
+       SMESH_Measurements_i.hxx \
+       SMESH_PreMeshInfo.hxx \
        SMESH.hxx
 
 # Scripts to be installed.
@@ -78,7 +78,9 @@ dist_libSMESHEngine_la_SOURCES = \
        SMESH_Group_i.cxx \
        SMESH_Pattern_i.cxx \
        SMESH_2smeshpy.cxx \
-       SMESH_NoteBook.cxx 
+       SMESH_NoteBook.cxx \
+       SMESH_Measurements_i.cxx \
+       SMESH_PreMeshInfo.cxx
 
 # Executables targets
 bin_PROGRAMS = SMESHEngine
@@ -92,6 +94,7 @@ libSMESHEngine_la_CPPFLAGS = \
        $(CORBA_INCLUDES) \
        $(CAS_CPPFLAGS) \
        @HDF5_INCLUDES@ \
+        $(VTK_INCLUDES) \
        $(BOOST_CPPFLAGS) \
        $(KERNEL_CXXFLAGS) \
        $(GUI_CXXFLAGS) \
@@ -102,14 +105,16 @@ libSMESHEngine_la_CPPFLAGS = \
        -I$(srcdir)/../SMESHDS \
        -I$(srcdir)/../Driver \
        -I$(srcdir)/../DriverMED \
+       -I$(srcdir)/../DriverCGNS \
        -I$(srcdir)/../SMESH \
-       -I$(top_builddir)/idl \
-       -I$(top_builddir)/salome_adm/unix
-
+       -I$(srcdir)/../SMESHUtils \
+       -I$(top_builddir)/idl
 
 libSMESHEngine_la_LDFLAGS  = \
        ../../idl/libSalomeIDLSMESH.la \
        ../SMESH/libSMESHimpl.la \
+       ../SMDS/libSMDS.la \
+       ../SMESHDS/libSMESHDS.la \
        ../Controls/libSMESHControls.la \
        $(KERNEL_LDFLAGS) \
        -lSalomeContainer \
@@ -119,7 +124,10 @@ libSMESHEngine_la_LDFLAGS  = \
        -lSalomeLifeCycleCORBA \
        -lTOOLSDS \
        -lSalomeGenericObj \
+       -lSalomeIDLKernel \
+       -lSALOMELocalTrace \
        $(MED_LDFLAGS) \
+       -lMEDWrapper \
        -lMEDWrapper_V2_2 \
         -lSalomeIDLMED \
        $(CAS_LDPATH) \
@@ -127,7 +135,8 @@ libSMESHEngine_la_LDFLAGS  = \
        -lTKBO \
        -lTKShHealing \
        $(GEOM_LDFLAGS) \
-       -lGEOMClient
+       -lGEOMClient \
+       -lSalomeIDLGEOM
 
 SMESHEngine_CPPFLAGS = \
        $(libSMESHEngine_la_CPPFLAGS)
index 0bd99b69286cf38aefd387bc253ac1d869639314..579ae91275450a3a2a83b5a7184dd9b4110df18f 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I :
 //  File   : SMESH.hxx
 //  Author : Michael ZORIN
@@ -29,7 +30,7 @@
 #define _SMESH_I_SMESH_HXX_
 
 #ifdef WNT
- #if defined SMESH_I_EXPORTS
+ #if defined SMESH_I_EXPORTS || defined SMESHEngine_EXPORTS
   #define SMESH_I_EXPORT __declspec( dllexport )
  #else
   #define SMESH_I_EXPORT __declspec( dllimport )
index 0c8d3bd601eeb152a3b0392b824c842e7a095574..5034d2cdd481edd7c2fd114d32ac5940710f0aff 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 int main(int argc, char** argv)
 {
   return 1;
index cd8247ba95adc4b41c906b7345c7234e894afa05..84f9067d521c6d8f12125bced7c75351bbadad15 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : SMESH_0D_Algo_i.cxx
 //  Author : Paul RASCLE, EDF
index 401feed17ffcf17b6fe5bf7038f66404e3e24cc0..dd23a1c1c21e584e49753acdcdc6b1deae398b06 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : SMESH_0D_Algo_i.hxx
 //  Module : SMESH
index e5da53f7955244af63809ac8ca5d69322ce1f346..9dcf746ac99eba675e9062e191a429b958f4d59d 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : SMESH_1D_Algo_i.cxx
 //  Author : Paul RASCLE, EDF
index 4ae7b0ea59b4065f283b1489e4b2dd3c22c91cd1..b8c912e62de3b85d5f4e26ff058c0193c1cabf10 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : SMESH_1D_Algo_i.hxx
 //  Author : Paul RASCLE, EDF
index 7fcf5a86dd686f8faec6dd58fb54b6429772efcb..37d228f763934b0d099eca571a51c7b1b364e9a0 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : SMESH_2D_Algo_i.cxx
 //  Author : Paul RASCLE, EDF
index 2579278fbe09ac76b316d3f6d37f41bbaa2f3da3..43277ccf53a5bccb7ed4cda3de74be96ed42da65 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : SMESH_2D_Algo_i.hxx
 //  Author : Paul RASCLE, EDF
index be494755b28c174179b200e69b054300767cd71a..88e7ba18279e2439925598ce20d8c95def973ef5 100644 (file)
@@ -1,26 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
-//
-//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File      : SMESH_2smeshpy.cxx
 // Created   : Fri Nov 18 13:20:10 2005
 // Author    : Edward AGAPOV (eap)
 #include "utilities.h"
 #include "SMESH_PythonDump.hxx"
 #include "SMESH_NoteBook.hxx"
-#include "Resource_DataMapOfAsciiStringAsciiString.hxx"
+#include "SMESH_Filter_i.hxx"
+
+#include <Resource_DataMapOfAsciiStringAsciiString.hxx>
+#include <Resource_DataMapIteratorOfDataMapOfAsciiStringAsciiString.hxx>
 
 #include "SMESH_Gen_i.hxx"
-/* SALOME headers that include CORBA headers that include windows.h 
+/* SALOME headers that include CORBA headers that include windows.h
  * that defines GetObject symbol as GetObjectA should stand before SALOME headers
  * that declare methods named GetObject - to apply the same rules of GetObject renaming
  * and thus to avoid mess with GetObject symbol on Windows */
 
+#include <LDOMParser.hxx>
+
+#ifdef WNT
+#include <windows.h>
+#else
+#include <unistd.h>
+#endif
+
+
 IMPLEMENT_STANDARD_HANDLE (_pyObject          ,Standard_Transient);
 IMPLEMENT_STANDARD_HANDLE (_pyCommand         ,Standard_Transient);
+IMPLEMENT_STANDARD_HANDLE (_pyHypothesisReader,Standard_Transient);
 IMPLEMENT_STANDARD_HANDLE (_pyGen             ,_pyObject);
 IMPLEMENT_STANDARD_HANDLE (_pyMesh            ,_pyObject);
 IMPLEMENT_STANDARD_HANDLE (_pySubMesh         ,_pyObject);
 IMPLEMENT_STANDARD_HANDLE (_pyMeshEditor      ,_pyObject);
 IMPLEMENT_STANDARD_HANDLE (_pyHypothesis      ,_pyObject);
-IMPLEMENT_STANDARD_HANDLE (_pyFilterManager   ,_pyObject);
+IMPLEMENT_STANDARD_HANDLE (_pySelfEraser      ,_pyObject);
+IMPLEMENT_STANDARD_HANDLE (_pyGroup           ,_pyObject);
+IMPLEMENT_STANDARD_HANDLE (_pyFilter          ,_pyObject);
 IMPLEMENT_STANDARD_HANDLE (_pyAlgorithm       ,_pyHypothesis);
 IMPLEMENT_STANDARD_HANDLE (_pyComplexParamHypo,_pyHypothesis);
 IMPLEMENT_STANDARD_HANDLE (_pyNumberOfSegmentsHyp,_pyHypothesis);
 
 IMPLEMENT_STANDARD_RTTIEXT(_pyObject          ,Standard_Transient);
 IMPLEMENT_STANDARD_RTTIEXT(_pyCommand         ,Standard_Transient);
+IMPLEMENT_STANDARD_RTTIEXT(_pyHypothesisReader,Standard_Transient);
 IMPLEMENT_STANDARD_RTTIEXT(_pyGen             ,_pyObject);
 IMPLEMENT_STANDARD_RTTIEXT(_pyMesh            ,_pyObject);
 IMPLEMENT_STANDARD_RTTIEXT(_pySubMesh         ,_pyObject);
 IMPLEMENT_STANDARD_RTTIEXT(_pyMeshEditor      ,_pyObject);
 IMPLEMENT_STANDARD_RTTIEXT(_pyHypothesis      ,_pyObject);
-IMPLEMENT_STANDARD_RTTIEXT(_pyFilterManager   ,_pyObject);
+IMPLEMENT_STANDARD_RTTIEXT(_pySelfEraser      ,_pyObject);
+IMPLEMENT_STANDARD_RTTIEXT(_pyGroup           ,_pyObject);
+IMPLEMENT_STANDARD_RTTIEXT(_pyFilter          ,_pyObject);
 IMPLEMENT_STANDARD_RTTIEXT(_pyAlgorithm       ,_pyHypothesis);
 IMPLEMENT_STANDARD_RTTIEXT(_pyComplexParamHypo,_pyHypothesis);
 IMPLEMENT_STANDARD_RTTIEXT(_pyNumberOfSegmentsHyp,_pyHypothesis);
@@ -106,6 +123,166 @@ namespace {
       return find( name ) != end();
     }
   };
+
+  //================================================================================
+  /*!
+   * \brief Returns a mesh by object
+   */
+  //================================================================================
+
+  Handle(_pyMesh) ObjectToMesh( const Handle( _pyObject )& obj )
+  {
+    if ( !obj.IsNull() )
+    {
+      if ( obj->IsKind( STANDARD_TYPE( _pyMesh )))
+        return Handle(_pyMesh)::DownCast( obj );
+      else if ( obj->IsKind( STANDARD_TYPE( _pySubMesh )))
+        return Handle(_pySubMesh)::DownCast( obj )->GetMesh();
+      else if ( obj->IsKind( STANDARD_TYPE( _pyGroup )))
+        return Handle(_pyGroup)::DownCast( obj )->GetMesh();
+    }
+    return Handle(_pyMesh)();
+  }
+
+  //================================================================================
+  /*!
+   * \brief Check if objects used as args have been created by previous commands
+   */
+  //================================================================================
+
+  void CheckObjectPresence( const Handle(_pyCommand)& cmd, set<_pyID> & presentObjects)
+  {
+    for ( int iArg = cmd->GetNbArgs(); iArg; --iArg )
+    {
+      const _pyID& arg = cmd->GetArg( iArg );
+      if ( arg.IsEmpty() || arg.Value( 1 ) == '"' || arg.Value( 1 ) == '\'' )
+        continue;
+      list< _pyID > idList = cmd->GetStudyEntries( arg );
+      list< _pyID >::iterator id = idList.begin();
+      for ( ; id != idList.end(); ++id )
+        if ( !theGen->IsGeomObject( *id ) && !presentObjects.count( *id ))
+        {
+          cmd->Comment();
+          cmd->GetString() += " ### " ;
+          cmd->GetString() += *id + " has not been yet created";
+          return;
+        }
+    }
+    const _pyID& obj = cmd->GetObject();
+    if ( !obj.IsEmpty() && cmd->IsStudyEntry( obj ) && !presentObjects.count( obj ))
+    {
+      cmd->Comment();
+      cmd->GetString() += " ### not created object" ;
+    }
+    const _pyID& result = cmd->GetResultValue();
+    if ( result.IsEmpty() || result.Value( 1 ) == '"' || result.Value( 1 ) == '\'' )
+      return;
+    list< _pyID > idList = cmd->GetStudyEntries( result );
+    list< _pyID >::iterator id = idList.begin();
+    for ( ; id != idList.end(); ++id )
+      presentObjects.insert( *id );
+  }
+
+  //================================================================================
+  /*!
+   * \brief Fix SMESH::FunctorType arguments of SMESH::Filter::Criterion()
+   */
+  //================================================================================
+
+  void fixFunctorType( TCollection_AsciiString& Type,
+                       TCollection_AsciiString& Compare,
+                       TCollection_AsciiString& UnaryOp,
+                       TCollection_AsciiString& BinaryOp )
+  {
+    // The problem is that dumps of old studies created using filters becomes invalid
+    // when new items are inserted in the enum SMESH::FunctorType since values
+    // of this enum are dumped as integer values.
+    // This function corrects enum values of old studies given as args (Type,Compare,...)
+    // We can find out how to correct them by value of BinaryOp which can have only two
+    // values: FT_Undefined or FT_LogicalNOT.
+    // Hereafter is the history of the enum SMESH::FunctorType since v3.0.0
+    // where PythonDump appeared
+    // v 3.0.0: FT_Undefined == 25
+    // v 3.1.0: FT_Undefined == 26, new items:
+    //   - FT_Volume3D              = 7
+    // v 4.1.2: FT_Undefined == 27, new items:
+    //   - FT_BelongToGenSurface    = 17
+    // v 5.1.1: FT_Undefined == 32, new items:
+    //   - FT_FreeNodes             = 10
+    //   - FT_FreeFaces             = 11
+    //   - FT_LinearOrQuadratic     = 23
+    //   - FT_GroupColor            = 24
+    //   - FT_ElemGeomType          = 25
+    // v 5.1.5: FT_Undefined == 33, new items:
+    //   - FT_CoplanarFaces         = 26
+    // v 6.2.0: FT_Undefined == 39, new items:
+    //   - FT_MaxElementLength2D    = 8
+    //   - FT_MaxElementLength3D    = 9
+    //   - FT_BareBorderVolume      = 25
+    //   - FT_BareBorderFace        = 26
+    //   - FT_OverConstrainedVolume = 27
+    //   - FT_OverConstrainedFace   = 28
+    // v 6.5.0: FT_Undefined == 43, new items:
+    //   - FT_EqualNodes            = 14
+    //   - FT_EqualEdges            = 15
+    //   - FT_EqualFaces            = 16
+    //   - FT_EqualVolumes          = 17
+    // v 6.6.0: FT_Undefined == 44, new items:
+    //   - FT_BallDiameter          = 37
+    //
+    // It's necessary to continue recording this history and to fill
+    // undef2newItems (see below) accordingly.
+
+    typedef map< int, vector< int > > TUndef2newItems;
+    static TUndef2newItems undef2newItems;
+    if ( undef2newItems.empty() )
+    {
+      undef2newItems[ 26 ].push_back( 7 );
+      undef2newItems[ 27 ].push_back( 17 );
+      { int items[] = { 10, 11, 23, 24, 25 };
+        undef2newItems[ 32 ].assign( items, items+5 ); }
+      undef2newItems[ 33 ].push_back( 26 );
+      { int items[] = { 8, 9, 25, 26, 27, 28 };
+        undef2newItems[ 39 ].assign( items, items+6 ); }
+      { int items[] = { 14, 15, 16, 17 };
+        undef2newItems[ 43 ].assign( items, items+4 ); }
+      { int items[] = { 37 };
+        undef2newItems[ 44 ].assign( items, items+1 ); }
+    }
+
+    int iType     = Type.IntegerValue();
+    int iCompare  = Compare.IntegerValue();
+    int iUnaryOp  = UnaryOp.IntegerValue();
+    int iBinaryOp = BinaryOp.IntegerValue();
+
+    // find out integer value of FT_Undefined at the moment of dump
+    int oldUndefined = iBinaryOp;
+    if ( iBinaryOp < iUnaryOp ) // BinaryOp was FT_LogicalNOT
+      oldUndefined += 3;
+
+    // apply history to args
+    TUndef2newItems::const_iterator undef_items =
+      undef2newItems.upper_bound( oldUndefined );
+    if ( undef_items != undef2newItems.end() )
+    {
+      int* pArg[4] = { &iType, &iCompare, &iUnaryOp, &iBinaryOp };
+      for ( ; undef_items != undef2newItems.end(); ++undef_items )
+      {
+        const vector< int > & addedItems = undef_items->second;
+        for ( size_t i = 0; i < addedItems.size(); ++i )
+          for ( int iArg = 0; iArg < 4; ++iArg )
+          {
+            int& arg = *pArg[iArg];
+            if ( arg >= addedItems[i] )
+              arg++;
+          }
+      }
+      Type     = TCollection_AsciiString( iType     );
+      Compare  = TCollection_AsciiString( iCompare  );
+      UnaryOp  = TCollection_AsciiString( iUnaryOp  );
+      BinaryOp = TCollection_AsciiString( iBinaryOp );
+    }
+  }
 }
 
 //================================================================================
@@ -113,22 +290,26 @@ namespace {
  * \brief Convert python script using commands of smesh.py
   * \param theScript - Input script
   * \retval TCollection_AsciiString - Convertion result
+  * \param theToKeepAllCommands - to keep all commands or
+  *        to exclude commands relating to objects removed from study
   *
   * Class SMESH_2smeshpy declared in SMESH_PythonDump.hxx
  */
 //================================================================================
 
 TCollection_AsciiString
-SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString& theScript,
+SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString&            theScript,
                               Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod,
-                             Resource_DataMapOfAsciiStringAsciiString& theObjectNames)
+                              Resource_DataMapOfAsciiStringAsciiString& theObjectNames,
+                              SALOMEDS::Study_ptr&                      theStudy,
+                              const bool                                theToKeepAllCommands)
 {
-  theGen = new _pyGen( theEntry2AccessorMethod, theObjectNames );
+  theGen = new _pyGen( theEntry2AccessorMethod, theObjectNames, theStudy, theToKeepAllCommands );
 
   // split theScript into separate commands
 
   SMESH_NoteBook * aNoteBook = new SMESH_NoteBook();
-  
+
   int from = 1, end = theScript.Length(), to;
   while ( from < end && ( to = theScript.Location( "\n", from, end )))
   {
@@ -137,13 +318,13 @@ SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString& theScript,
         aNoteBook->AddCommand( theScript.SubString( from, to - 1 ));
       from = to + 1;
   }
-  
+
   aNoteBook->ReplaceVariables();
 
   TCollection_AsciiString aNoteScript = aNoteBook->GetResultScript();
   delete aNoteBook;
   aNoteBook = 0;
-  
+
   // split theScript into separate commands
   from = 1, end = aNoteScript.Length();
   while ( from < end && ( to = aNoteScript.Location( "\n", from, end )))
@@ -160,6 +341,9 @@ SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString& theScript,
   MESSAGE_BEGIN ( std::endl << " ######## RESULT ######## " << std::endl<< std::endl );
 #endif
 
+  // clean commmands of removed objects depending on myIsPublished flag
+  theGen->ClearCommands();
+
   // reorder commands after conversion
   list< Handle(_pyCommand) >::iterator cmd;
   bool orderChanges;
@@ -169,21 +353,25 @@ SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString& theScript,
       if ( (*cmd)->SetDependentCmdsAfter() )
         orderChanges = true;
   } while ( orderChanges );
-  
+
   // concat commands back into a script
-  TCollection_AsciiString aScript;
+  TCollection_AsciiString aScript, aPrevCmd;
+  set<_pyID> createdObjects;
   for ( cmd = theGen->GetCommands().begin(); cmd != theGen->GetCommands().end(); ++cmd )
   {
 #ifdef DUMP_CONVERSION
     MESSAGE_ADD ( "## COM " << (*cmd)->GetOrderNb() << ": "<< (*cmd)->GetString() << std::endl );
 #endif
-    if ( !(*cmd)->IsEmpty() ) {
+    if ( !(*cmd)->IsEmpty() && aPrevCmd != (*cmd)->GetString()) {
+      CheckObjectPresence( *cmd, createdObjects );
+      aPrevCmd = (*cmd)->GetString();
       aScript += "\n";
-      aScript += (*cmd)->GetString();
+      aScript += aPrevCmd;
     }
   }
   aScript += "\n";
 
+  theGen->Free();
   theGen.Nullify();
 
   return aScript;
@@ -196,15 +384,49 @@ SMESH_2smeshpy::ConvertScript(const TCollection_AsciiString& theScript,
 //================================================================================
 
 _pyGen::_pyGen(Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod,
-              Resource_DataMapOfAsciiStringAsciiString& theObjectNames)
-  : _pyObject( new _pyCommand( TPythonDump::SMESHGenName(), 0 )),
+               Resource_DataMapOfAsciiStringAsciiString& theObjectNames,
+               SALOMEDS::Study_ptr&                      theStudy,
+               const bool                                theToKeepAllCommands)
+  : _pyObject( new _pyCommand( "", 0 )),
+    myNbCommands( 0 ),
     myID2AccessorMethod( theEntry2AccessorMethod ),
-    myObjectNames( theObjectNames )
+    myObjectNames( theObjectNames ),
+    myNbFilters( 0 ),
+    myToKeepAllCommands( theToKeepAllCommands ),
+    myStudy( SALOMEDS::Study::_duplicate( theStudy )),
+    myGeomIDNb(0), myGeomIDIndex(-1)
 {
-  myNbCommands = 0;
-  myHasPattern = false;
   // make that GetID() to return TPythonDump::SMESHGenName()
+  GetCreationCmd()->Clear();
+  GetCreationCmd()->GetString() = TPythonDump::SMESHGenName();
   GetCreationCmd()->GetString() += "=";
+
+  // Find 1st digit of study entry by which a GEOM object differs from a SMESH object
+  if ( !theObjectNames.IsEmpty() && !CORBA::is_nil( theStudy ))
+  {
+    // find a GEOM entry
+    _pyID geomID;
+    SALOMEDS::SComponent_var geomComp = theStudy->FindComponent("GEOM");
+    if ( geomComp->_is_nil() ) return;
+    CORBA::String_var entry = geomComp->GetID();
+    geomID = entry.in();
+
+    // find a SMESH entry
+    _pyID smeshID;
+    Resource_DataMapIteratorOfDataMapOfAsciiStringAsciiString e2n( theObjectNames );
+    for ( ; e2n.More() && smeshID.IsEmpty(); e2n.Next() )
+      if ( _pyCommand::IsStudyEntry( e2n.Key() ))
+        smeshID = e2n.Key();
+
+    // find 1st difference between smeshID and geomID
+    if ( !geomID.IsEmpty() && !smeshID.IsEmpty() )
+      for ( int i = 1; i <= geomID.Length() && i <= smeshID.Length(); ++i )
+        if ( geomID.Value( i ) != smeshID.Value( i ))
+        {
+          myGeomIDNb = geomID.Value( i );
+          myGeomIDIndex = i;
+        }
+  }
 }
 
 //================================================================================
@@ -235,74 +457,146 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
   MESSAGE ( "## COM " << myNbCommands << ": "<< aCommand->GetString() );
 #endif
 
-  _pyID objID = aCommand->GetObject();
+  const _pyID& objID = aCommand->GetObject();
 
   if ( objID.IsEmpty() )
     return aCommand;
 
+  // Prevent moving a command creating a sub-mesh to the end of the script
+  // if the sub-mesh is used in theCommand as argument
+  if ( _pySubMesh::CanBeArgOfMethod( aCommand->GetMethod() ))
+  {
+    PlaceSubmeshAfterItsCreation( aCommand );
+  }
+
+  // Find an object to process theCommand
+
   // SMESH_Gen method?
-  if ( objID == this->GetID() ) {
+  if ( objID == this->GetID() || objID == SMESH_2smeshpy::GenName())
+  {
     this->Process( aCommand );
     return aCommand;
   }
-  
-  // SMESH_subMesh method?
-  map< _pyID, Handle(_pySubMesh) >::iterator id_subMesh = mySubMeshes.find( objID );
-  if ( id_subMesh != mySubMeshes.end() ) {
-    id_subMesh->second->Process( aCommand );
-    return aCommand;
-  }
 
   // SMESH_Mesh method?
   map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.find( objID );
-  if ( id_mesh != myMeshes.end() ) {
+  if ( id_mesh != myMeshes.end() )
+  {
+    //id_mesh->second->AddProcessedCmd( aCommand );
+
     // check for mesh editor object
     if ( aCommand->GetMethod() == "GetMeshEditor" ) { // MeshEditor creation
       _pyID editorID = aCommand->GetResultValue();
       Handle(_pyMeshEditor) editor = new _pyMeshEditor( aCommand );
       myMeshEditors.insert( make_pair( editorID, editor ));
       return aCommand;
-    } 
+    }
     // check for SubMesh objects
     else if ( aCommand->GetMethod() == "GetSubMesh" ) { // SubMesh creation
       _pyID subMeshID = aCommand->GetResultValue();
       Handle(_pySubMesh) subMesh = new _pySubMesh( aCommand );
-      mySubMeshes.insert( make_pair( subMeshID, subMesh ));
+      myObjects.insert( make_pair( subMeshID, subMesh ));
     }
-    id_mesh->second->Process( aCommand );
-    return aCommand;
-  }
 
-  //SMESH_FilterManager method?
-  if ( theCommand.Search( "aFilterManager" ) != -1 ) {
-    if ( theCommand.Search( "CreateFilterManager" ) != -1 )
-      myFilterManager = new _pyFilterManager( aCommand );
-    else if ( !myFilterManager.IsNull() )
-      myFilterManager->Process( aCommand );
+    id_mesh->second->Process( aCommand );
+    id_mesh->second->AddProcessedCmd( aCommand );
     return aCommand;
   }
 
   // SMESH_MeshEditor method?
   map< _pyID, Handle(_pyMeshEditor) >::iterator id_editor = myMeshEditors.find( objID );
-  if ( id_editor != myMeshEditors.end() ) {
+  if ( id_editor != myMeshEditors.end() )
+  {
+    const TCollection_AsciiString& method = aCommand->GetMethod();
+
+    // some commands of SMESH_MeshEditor create meshes and groups
+    _pyID meshID, groups;
+    if ( method.Search("MakeMesh") != -1 )
+      meshID = aCommand->GetResultValue();
+    else if ( method == "MakeBoundaryMesh")
+      meshID = aCommand->GetResultValue(1);
+    else if ( method == "MakeBoundaryElements")
+      meshID = aCommand->GetResultValue(2);
+
+    if ( method.Search("MakeGroups") != -1  ||
+         method == "ExtrusionAlongPathX"    ||
+         method == "ExtrusionAlongPathObjX" ||
+         method == "DoubleNodeGroupNew"     ||
+         method == "DoubleNodeGroupsNew"    ||
+         method == "DoubleNodeElemGroupNew" ||
+         method == "DoubleNodeElemGroupsNew"||
+         method == "DoubleNodeElemGroup2New"||
+         method == "DoubleNodeElemGroups2New"
+         )
+      groups = aCommand->GetResultValue();
+    else if ( method == "MakeBoundaryMesh" )
+      groups = aCommand->GetResultValue(2);
+    else if ( method == "MakeBoundaryElements")
+      groups = aCommand->GetResultValue(3);
+
     id_editor->second->Process( aCommand );
-    TCollection_AsciiString processedCommand = aCommand->GetString();
-    // some commands of SMESH_MeshEditor create meshes
-    if ( aCommand->GetMethod().Search("MakeMesh") != -1 ) {
-      Handle(_pyMesh) mesh = new _pyMesh( aCommand, aCommand->GetResultValue() );
+    id_editor->second->AddProcessedCmd( aCommand );
+
+    if ( !meshID.IsEmpty() &&
+         !myMeshes.count( meshID ) &&
+         aCommand->IsStudyEntry( meshID ))
+    {
+      TCollection_AsciiString processedCommand = aCommand->GetString();
+      Handle(_pyMesh) mesh = new _pyMesh( aCommand, meshID );
+      myMeshes.insert( make_pair( meshID, mesh ));
+      aCommand->Clear();
       aCommand->GetString() = processedCommand; // discard changes made by _pyMesh
-      myMeshes.insert( make_pair( mesh->GetID(), mesh ));
+    }
+    if ( !groups.IsEmpty() )
+    {
+      if ( !aCommand->IsStudyEntry( meshID ))
+        meshID = id_editor->second->GetMesh();
+      Handle(_pyMesh) mesh = myMeshes[ meshID ];
+
+      list< _pyID > idList = aCommand->GetStudyEntries( groups );
+      list< _pyID >::iterator grID = idList.begin();
+      for ( ; grID != idList.end(); ++grID )
+        if ( !myObjects.count( *grID ))
+        {
+          Handle(_pyGroup) group = new _pyGroup( aCommand, *grID );
+          AddObject( group );
+          if ( !mesh.IsNull() ) mesh->AddGroup( group );
+        }
     }
     return aCommand;
-  }
+  } // SMESH_MeshEditor methods
+
   // SMESH_Hypothesis method?
   list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin();
   for ( ; hyp != myHypos.end(); ++hyp )
     if ( !(*hyp)->IsAlgo() && objID == (*hyp)->GetID() ) {
       (*hyp)->Process( aCommand );
+      (*hyp)->AddProcessedCmd( aCommand );
       return aCommand;
     }
 
+  // aFilterManager.CreateFilter() ?
+  if ( aCommand->GetMethod() == "CreateFilter" )
+  {
+    // Set a more human readable name to a filter
+    // aFilter0x7fbf6c71cfb0 -> aFilter_nb
+    _pyID newID, filterID = aCommand->GetResultValue();
+    int pos = filterID.Search( "0x" );
+    if ( pos > 1 )
+      newID = (filterID.SubString(1,pos-1) + "_") + _pyID( ++myNbFilters );
+
+    Handle(_pyObject) filter( new _pyFilter( aCommand, newID ));
+    AddObject( filter );
+  }
+
+  // other object method?
+  map< _pyID, Handle(_pyObject) >::iterator id_obj = myObjects.find( objID );
+  if ( id_obj != myObjects.end() ) {
+    id_obj->second->Process( aCommand );
+    id_obj->second->AddProcessedCmd( aCommand );
+    return aCommand;
+  }
+
   // Add access to a wrapped mesh
   AddMeshAccessorMethod( aCommand );
 
@@ -312,7 +606,7 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
   // PAL12227. PythonDump was not updated at proper time; result is
   //     aCriteria.append(SMESH.Filter.Criterion(17,26,0,'L1',26,25,1e-07,SMESH.EDGE,-1))
   // TypeError: __init__() takes exactly 11 arguments (10 given)
-  char wrongCommand[] = "SMESH.Filter.Criterion(";
+  const char wrongCommand[] = "SMESH.Filter.Criterion(";
   if ( int beg = theCommand.Location( wrongCommand, 1, theCommand.Length() ))
   {
     _pyCommand tmpCmd( theCommand.SubString( beg, theCommand.Length() ), -1);
@@ -326,13 +620,86 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
       aCommand->GetString().Trunc( beg - 1 );
       aCommand->GetString() += tmpCmd.GetString();
     }
+    // IMP issue 0021014
+    // set GetCriterion(elementType,CritType,Compare,Treshold,UnaryOp,BinaryOp,Tolerance)
+    //                  1           2        3       4        5       6        7
+    // instead of "SMESH.Filter.Criterion(
+    // Type,Compare,Threshold,ThresholdStr,ThresholdID,UnaryOp,BinaryOp,Tolerance,TypeOfElement,Precision)
+    // 1    2       3         4            5           6       7        8         9             10
+    // in order to avoid the problem of type mismatch of long and FunctorType
+    const TCollection_AsciiString
+      SMESH("SMESH."), dfltFunctor = "SMESH.FT_Undefined", dftlTol = "1e-07", dftlPreci = "-1";
+    TCollection_AsciiString
+      Type          = aCommand->GetArg(1),  // long
+      Compare       = aCommand->GetArg(2),  // long
+      Threshold     = aCommand->GetArg(3),  // double
+      ThresholdStr  = aCommand->GetArg(4),  // string
+      ThresholdID   = aCommand->GetArg(5),  // string
+      UnaryOp       = aCommand->GetArg(6),  // long
+      BinaryOp      = aCommand->GetArg(7),  // long
+      Tolerance     = aCommand->GetArg(8),  // double
+      TypeOfElement = aCommand->GetArg(9),  // ElementType
+      Precision     = aCommand->GetArg(10); // long
+    fixFunctorType( Type, Compare, UnaryOp, BinaryOp );
+    Type     = SMESH + SMESH::FunctorTypeToString( SMESH::FunctorType( Type.IntegerValue() ));
+    Compare  = SMESH + SMESH::FunctorTypeToString( SMESH::FunctorType( Compare.IntegerValue() ));
+    UnaryOp  = SMESH + SMESH::FunctorTypeToString( SMESH::FunctorType( UnaryOp.IntegerValue() ));
+    BinaryOp = SMESH + SMESH::FunctorTypeToString( SMESH::FunctorType( BinaryOp.IntegerValue() ));
+
+    aCommand->RemoveArgs();
+    aCommand->SetObject( SMESH_2smeshpy::GenName() );
+    aCommand->SetMethod( "GetCriterion" );
+
+    aCommand->SetArg( 1, TypeOfElement );
+    aCommand->SetArg( 2, Type );
+    aCommand->SetArg( 3, Compare );
+
+    if ( Type == "SMESH.FT_ElemGeomType" && Threshold.IsIntegerValue() )
+    {
+      // set SMESH.GeometryType instead of a numerical Threshold
+      const char* types[SMESH::Geom_BALL+1] = {
+        "Geom_POINT", "Geom_EDGE", "Geom_TRIANGLE", "Geom_QUADRANGLE", "Geom_POLYGON",
+        "Geom_TETRA", "Geom_PYRAMID", "Geom_HEXA", "Geom_PENTA", "Geom_HEXAGONAL_PRISM",
+        "Geom_POLYHEDRA", "Geom_BALL"
+      };
+      int iGeom = Threshold.IntegerValue();
+      if ( -1 < iGeom && iGeom < SMESH::Geom_POLYHEDRA+1 )
+        Threshold = SMESH + types[ iGeom ];
+    }
+    if ( ThresholdID.Length() != 2 && ThresholdStr.Length() != 2) // not '' or ""
+      aCommand->SetArg( 4, ThresholdID.SubString( 2, ThresholdID.Length()-1 )); // shape entry
+    else if ( ThresholdStr.Length() != 2 )
+      aCommand->SetArg( 4, ThresholdStr );
+    else if ( ThresholdID.Length() != 2 )
+      aCommand->SetArg( 4, ThresholdID );
+    else
+      aCommand->SetArg( 4, Threshold );
+    // find the last not default arg
+    int lastDefault = 8;
+    if ( Tolerance == dftlTol ) {
+      lastDefault = 7;
+      if ( BinaryOp == dfltFunctor ) {
+        lastDefault = 6;
+        if ( UnaryOp == dfltFunctor )
+          lastDefault = 5;
+      }
+    }
+    if ( 5 < lastDefault ) aCommand->SetArg( 5, UnaryOp );
+    if ( 6 < lastDefault ) aCommand->SetArg( 6, BinaryOp );
+    if ( 7 < lastDefault ) aCommand->SetArg( 7, Tolerance );
+    if ( Precision != dftlPreci )
+    {
+      TCollection_AsciiString crit = aCommand->GetResultValue();
+      aCommand->GetString() += "; ";
+      aCommand->GetString() += crit + ".Precision = " + Precision;
+    }
   }
   return aCommand;
 }
 
 //================================================================================
 /*!
- * \brief Convert the command or remember it for later conversion 
+ * \brief Convert the command or remember it for later conversion
   * \param theCommand - The python command calling a method of SMESH_Gen
  */
 //================================================================================
@@ -344,6 +711,7 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
   // Concatenate( [mesh1, ...], ... )
   // CreateHypothesis( theHypType, theLibName )
   // Compute( mesh, geom )
+  // Evaluate( mesh, geom )
   // mesh creation
   TCollection_AsciiString method = theCommand->GetMethod();
 
@@ -353,18 +721,23 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
     myMeshes.insert( make_pair( mesh->GetID(), mesh ));
     return;
   }
-  if ( method == "CreateMeshesFromUNV" || method == "CreateMeshesFromSTL")
+  if ( method == "CreateMeshesFromUNV" ||
+       method == "CreateMeshesFromSTL" ||
+       method == "CreateMeshesFromCGNS" ||
+       method == "CopyMesh" )
   {
     Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue() );
     myMeshes.insert( make_pair( mesh->GetID(), mesh ));
     return;
   }
-  if( method == "CreateMeshesFromMED")
+  if( method == "CreateMeshesFromMED" || method == "CreateMeshesFromSAUV")
   {
     for(int ind = 0;ind<theCommand->GetNbResultValues();ind++)
     {
-      Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue(ind));
-      myMeshes.insert( make_pair( theCommand->GetResultValue(ind), mesh ));     
+      _pyID meshID = theCommand->GetResultValue(ind+1);
+      if ( !theCommand->IsStudyEntry( meshID ) ) continue;
+      Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue(ind+1));
+      myMeshes.insert( make_pair( mesh->GetID(), mesh ));
     }
   }
 
@@ -392,22 +765,38 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
     if ( id_mesh != myMeshes.end() ) {
       theCommand->SetObject( meshID );
       theCommand->RemoveArgs();
-      id_mesh->second->Flush();
+      id_mesh->second->Process( theCommand );
+      id_mesh->second->AddProcessedCmd( theCommand );
       return;
     }
   }
 
-  // leave only one smeshgen.GetPattern() in the script
-  if ( method == "GetPattern" ) {
-    if ( myHasPattern ) {
-      theCommand->Clear();
+  // smeshgen.Evaluate( mesh, geom ) --> mesh.Evaluate(geom)
+  if ( method == "Evaluate" )
+  {
+    const _pyID& meshID = theCommand->GetArg( 1 );
+    map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.find( meshID );
+    if ( id_mesh != myMeshes.end() ) {
+      theCommand->SetObject( meshID );
+      _pyID geom = theCommand->GetArg( 2 );
+      theCommand->RemoveArgs();
+      theCommand->SetArg( 1, geom );
+      id_mesh->second->AddProcessedCmd( theCommand );
       return;
     }
-    myHasPattern = true;
   }
 
+  // objects erasing creation command if no more it's commands invoked:
+  // SMESH_Pattern, FilterManager
+  if ( method == "GetPattern" ||
+       method == "CreateFilterManager" ||
+       method == "CreateMeasurements" ) {
+    Handle(_pyObject) obj = new _pySelfEraser( theCommand );
+    if ( !myObjects.insert( make_pair( obj->GetID(), obj )).second )
+      theCommand->Clear(); // already created
+  }
   // Concatenate( [mesh1, ...], ... )
-  if ( method == "Concatenate" || method == "ConcatenateWithGroups")
+  else if ( method == "Concatenate" || method == "ConcatenateWithGroups")
   {
     if ( method == "ConcatenateWithGroups" ) {
       theCommand->SetMethod( "Concatenate" );
@@ -417,6 +806,14 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
     myMeshes.insert( make_pair( mesh->GetID(), mesh ));
     AddMeshAccessorMethod( theCommand );
   }
+  else if ( method == "SetName" ) // SetName(obj,name)
+  {
+    // store theCommand as one of object commands to erase it along with the object
+    const _pyID& objID = theCommand->GetArg( 1 );
+    Handle(_pyObject) obj = FindObject( objID );
+    if ( !obj.IsNull() )
+      obj->AddProcessedCmd( theCommand );
+  }
 
   // Replace name of SMESH_Gen
 
@@ -445,19 +842,45 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
 
 void _pyGen::Flush()
 {
-  // create empty command
+  // create an empty command
   myLastCommand = new _pyCommand();
 
-  if ( !myFilterManager.IsNull() )
-    myFilterManager->Flush();
+  map< _pyID, Handle(_pyMesh) >::iterator id_mesh;
+  map< _pyID, Handle(_pyObject) >::iterator id_obj;
+  list< Handle(_pyHypothesis) >::iterator hyp;
 
-  map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.begin();
-  for ( ; id_mesh != myMeshes.end(); ++id_mesh )
+  if ( IsToKeepAllCommands() ) // historical dump
+  {
+    // set myIsPublished = true to all objects
+    for ( id_mesh = myMeshes.begin(); id_mesh != myMeshes.end(); ++id_mesh )
+      id_mesh->second->SetRemovedFromStudy( false );
+    for ( hyp = myHypos.begin(); hyp != myHypos.end(); ++hyp )
+      (*hyp)->SetRemovedFromStudy( false );
+    for ( id_obj = myObjects.begin(); id_obj != myObjects.end(); ++id_obj )
+      id_obj->second->SetRemovedFromStudy( false );
+  }
+  else
+  {
+    // let hypotheses find referred objects in order to prevent clearing
+    // not published referred hyps (it's needed for hyps like "LayerDistribution")
+    list< Handle(_pyMesh) > fatherMeshes;
+    for ( hyp = myHypos.begin(); hyp != myHypos.end(); ++hyp )
+      if ( !hyp->IsNull() )
+        (*hyp)->GetReferredMeshesAndGeom( fatherMeshes );
+  }
+  // set myIsPublished = false to all objects depending on
+  // meshes built on a removed geometry
+  for ( id_mesh = myMeshes.begin(); id_mesh != myMeshes.end(); ++id_mesh )
+    if ( id_mesh->second->IsNotGeomPublished() )
+      id_mesh->second->SetRemovedFromStudy( true );
+
+  // Flush meshes
+  for ( id_mesh = myMeshes.begin(); id_mesh != myMeshes.end(); ++id_mesh )
     if ( ! id_mesh->second.IsNull() )
       id_mesh->second->Flush();
 
-  list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin();
-  for ( ; hyp != myHypos.end(); ++hyp )
+  // Flush hyps
+  for ( hyp = myHypos.begin(); hyp != myHypos.end(); ++hyp )
     if ( !hyp->IsNull() ) {
       (*hyp)->Flush();
       // smeshgen.CreateHypothesis() --> smesh.smesh.CreateHypothesis()
@@ -465,15 +888,97 @@ void _pyGen::Flush()
         (*hyp)->GetCreationCmd()->SetObject( SMESH_2smeshpy::GenName() );
     }
 
-  map< _pyID, Handle(_pySubMesh) >::iterator id_subMesh = mySubMeshes.begin();
-  for ( ; id_subMesh != mySubMeshes.end(); ++id_subMesh )
-    if ( ! id_subMesh->second.IsNull() )
-      id_subMesh->second->Flush();
+  // Flush other objects
+  for ( id_obj = myObjects.begin(); id_obj != myObjects.end(); ++id_obj )
+    if ( ! id_obj->second.IsNull() )
+      id_obj->second->Flush();
 
   myLastCommand->SetOrderNb( ++myNbCommands );
   myCommands.push_back( myLastCommand );
 }
 
+//================================================================================
+/*!
+ * \brief Prevent moving a command creating a sub-mesh to the end of the script
+ *        if the sub-mesh is used in theCmdUsingSubmesh as argument
+ */
+//================================================================================
+
+void _pyGen::PlaceSubmeshAfterItsCreation( Handle(_pyCommand) theCmdUsingSubmesh ) const
+{
+  map< _pyID, Handle(_pyObject) >::const_iterator id_obj = myObjects.begin();
+  for ( ; id_obj != myObjects.end(); ++id_obj )
+  {
+    if ( !id_obj->second->IsKind( STANDARD_TYPE( _pySubMesh ))) continue;
+    for ( int iArg = theCmdUsingSubmesh->GetNbArgs(); iArg; --iArg )
+    {
+      const _pyID& arg = theCmdUsingSubmesh->GetArg( iArg );
+      if ( arg.IsEmpty() || arg.Value( 1 ) == '"' || arg.Value( 1 ) == '\'' )
+        continue;
+      list< _pyID > idList = theCmdUsingSubmesh->GetStudyEntries( arg );
+      list< _pyID >::iterator id = idList.begin();
+      for ( ; id != idList.end(); ++id )
+        if ( id_obj->first == *id )
+          // _pySubMesh::Process() does what we need
+          Handle(_pySubMesh)::DownCast( id_obj->second )->Process( theCmdUsingSubmesh );
+    }
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Clean commmands of removed objects depending on myIsPublished flag
+ */
+//================================================================================
+
+void _pyGen::ClearCommands()
+{
+  map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.begin();
+  for ( ; id_mesh != myMeshes.end(); ++id_mesh )
+    id_mesh->second->ClearCommands();
+
+  list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin();
+  for ( ; hyp != myHypos.end(); ++hyp )
+    if ( !hyp->IsNull() )
+      (*hyp)->ClearCommands();
+
+  map< _pyID, Handle(_pyObject) >::iterator id_obj = myObjects.begin();
+  for ( ; id_obj != myObjects.end(); ++id_obj )
+    id_obj->second->ClearCommands();
+}
+
+//================================================================================
+/*!
+ * \brief Release mutual handles of objects
+ */
+//================================================================================
+
+void _pyGen::Free()
+{
+  map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.begin();
+  for ( ; id_mesh != myMeshes.end(); ++id_mesh )
+    id_mesh->second->Free();
+  myMeshes.clear();
+
+  map< _pyID, Handle(_pyMeshEditor) >::iterator id_ed = myMeshEditors.begin();
+  for ( ; id_ed != myMeshEditors.end(); ++id_ed )
+    id_ed->second->Free();
+  myMeshEditors.clear();
+
+  map< _pyID, Handle(_pyObject) >::iterator id_obj = myObjects.begin();
+  for ( ; id_obj != myObjects.end(); ++id_obj )
+    id_obj->second->Free();
+  myObjects.clear();
+
+  list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin();
+  for ( ; hyp != myHypos.end(); ++hyp )
+    if ( !hyp->IsNull() )
+      (*hyp)->Free();
+  myHypos.clear();
+
+  myFile2ExportedMesh.clear();
+}
+
 //================================================================================
 /*!
  * \brief Add access method to mesh that is an argument
@@ -548,7 +1053,7 @@ Handle(_pyHypothesis) _pyGen::FindAlgo( const _pyID& theGeom, const _pyID& theMe
     if ( !hyp->IsNull() &&
          (*hyp)->IsAlgo() &&
          theHypothesis->CanBeCreatedBy( (*hyp)->GetAlgoType() ) &&
-        (*hyp)->GetGeom() == theGeom &&
+         (*hyp)->GetGeom() == theGeom &&
          (*hyp)->GetMesh() == theMesh )
       return *hyp;
   return 0;
@@ -564,12 +1069,9 @@ Handle(_pyHypothesis) _pyGen::FindAlgo( const _pyID& theGeom, const _pyID& theMe
 
 Handle(_pySubMesh) _pyGen::FindSubMesh( const _pyID& theSubMeshID )
 {
-  map< _pyID, Handle(_pySubMesh) >::iterator id_subMesh = mySubMeshes.begin();
-  for ( ; id_subMesh != mySubMeshes.end(); ++id_subMesh ) {
-    Handle(_pySubMesh) sm = id_subMesh->second;
-    if ( !id_subMesh->second.IsNull() && theSubMeshID == id_subMesh->second->GetID() )
-      return sm;
-  }
+  map< _pyID, Handle(_pyObject) >::iterator id_subMesh = myObjects.find(theSubMeshID);
+  if ( id_subMesh != myObjects.end() )
+    return Handle(_pySubMesh)::DownCast( id_subMesh->second );
   return Handle(_pySubMesh)();
 }
 
@@ -634,8 +1136,8 @@ void _pyGen::SetCommandBefore( Handle(_pyCommand) theCmd, Handle(_pyCommand) the
 //================================================================================
 
 void _pyGen::setNeighbourCommand( Handle(_pyCommand)& theCmd,
-                                 Handle(_pyCommand)& theOtherCmd,
-                                 const bool theIsAfter )
+                                  Handle(_pyCommand)& theOtherCmd,
+                                  const bool theIsAfter )
 {
   list< Handle(_pyCommand) >::iterator pos;
   pos = find( myCommands.begin(), myCommands.end(), theCmd );
@@ -688,114 +1190,216 @@ _pyID _pyGen::GenerateNewID( const _pyID& theID )
     aNewID = theID + _pyID( ":" ) + _pyID( index++ );
   }
   while ( myObjectNames.IsBound( aNewID ) );
-    
-  myObjectNames.Bind( aNewID, myObjectNames.IsBound( theID ) 
-                     ? (myObjectNames.Find( theID ) + _pyID( "_" ) + _pyID( index-1 ))
-                     : _pyID( "A" ) + aNewID );
+
+  myObjectNames.Bind( aNewID, myObjectNames.IsBound( theID )
+                      ? (myObjectNames.Find( theID ) + _pyID( "_" ) + _pyID( index-1 ))
+                      : _pyID( "A" ) + aNewID );
   return aNewID;
 }
 
 //================================================================================
 /*!
- * \brief Find out type of geom group
-  * \param grpID - The geom group entry
-  * \retval int - The type
- */
-//================================================================================
-
-static bool sameGroupType( const _pyID&                   grpID,
-                           const TCollection_AsciiString& theType)
-{
-  // define group type as smesh.Mesh.Group() does
-  int type = -1;
-  SALOMEDS::Study_var study = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy();
-  SALOMEDS::SObject_var aSObj = study->FindObjectID( grpID.ToCString() );
-  if ( !aSObj->_is_nil() ) {
-    GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow( aSObj->GetObject() );
-    if ( !aGeomObj->_is_nil() ) {
-      switch ( aGeomObj->GetShapeType() ) {
-      case GEOM::VERTEX: type = SMESH::NODE; break;
-      case GEOM::EDGE:   type = SMESH::EDGE; break;
-      case GEOM::FACE:   type = SMESH::FACE; break;
-      case GEOM::SOLID:
-      case GEOM::SHELL:  type = SMESH::VOLUME; break;
-      case GEOM::COMPOUND: {
-        GEOM::GEOM_Gen_ptr aGeomGen = SMESH_Gen_i::GetSMESHGen()->GetGeomEngine();
-        if ( !aGeomGen->_is_nil() ) {
-          GEOM::GEOM_IGroupOperations_var aGrpOp =
-            aGeomGen->GetIGroupOperations( study->StudyId() );
-          if ( !aGrpOp->_is_nil() ) {
-            switch ( aGrpOp->GetType( aGeomObj )) {
-            case TopAbs_VERTEX: type = SMESH::NODE; break;
-            case TopAbs_EDGE:   type = SMESH::EDGE; break;
-            case TopAbs_FACE:   type = SMESH::FACE; break;
-            case TopAbs_SOLID:  type = SMESH::VOLUME; break;
-            default:;
-            }
-          }
-        }
-      }
-      default:;
-      }
-    }
+ * \brief Stores theObj in myObjects
+ */
+//================================================================================
+
+void _pyGen::AddObject( Handle(_pyObject)& theObj )
+{
+  if ( theObj.IsNull() ) return;
+
+  if ( theObj->IsKind( STANDARD_TYPE( _pyMesh )))
+    myMeshes.insert( make_pair( theObj->GetID(), Handle(_pyMesh)::DownCast( theObj )));
+
+  else if ( theObj->IsKind( STANDARD_TYPE( _pyMeshEditor )))
+    myMeshEditors.insert( make_pair( theObj->GetID(), Handle(_pyMeshEditor)::DownCast( theObj )));
+
+  else
+    myObjects.insert( make_pair( theObj->GetID(), theObj ));
+}
+
+//================================================================================
+/*!
+ * \brief Re-register an object with other ID to make it Process() commands of
+ * other object having this ID
+ */
+//================================================================================
+
+void _pyGen::SetProxyObject( const _pyID& theID, Handle(_pyObject)& theObj )
+{
+  if ( theObj.IsNull() ) return;
+
+  if ( theObj->IsKind( STANDARD_TYPE( _pyMesh )))
+    myMeshes.insert( make_pair( theID, Handle(_pyMesh)::DownCast( theObj )));
+
+  else if ( theObj->IsKind( STANDARD_TYPE( _pyMeshEditor )))
+    myMeshEditors.insert( make_pair( theID, Handle(_pyMeshEditor)::DownCast( theObj )));
+
+  else
+    myObjects.insert( make_pair( theID, theObj ));
+}
+
+//================================================================================
+/*!
+ * \brief Finds a _pyObject by ID
+ */
+//================================================================================
+
+Handle(_pyObject) _pyGen::FindObject( const _pyID& theObjID )  const
+{
+  {
+    map< _pyID, Handle(_pyObject) >::const_iterator id_obj = myObjects.find( theObjID );
+    if ( id_obj != myObjects.end() )
+      return id_obj->second;
   }
-  if ( type < 0 ) {
-    MESSAGE("Type of the group " << grpID << " not found");
-    return false;
+  {
+    map< _pyID, Handle(_pyMesh) >::const_iterator id_obj = myMeshes.find( theObjID );
+    if ( id_obj != myMeshes.end() )
+      return id_obj->second;
   }
-  if ( theType.IsIntegerValue() )
-    return type == theType.IntegerValue();
+  // {
+  //   map< _pyID, Handle(_pyMeshEditor) >::const_iterator id_obj = myMeshEditors.find( theObjID );
+  //   if ( id_obj != myMeshEditors.end() )
+  //     return id_obj->second;
+  // }
+  return Handle(_pyObject)();
+}
+
+//================================================================================
+/*!
+ * \brief Check if a study entry is under GEOM component
+ */
+//================================================================================
 
-  switch ( type ) {
-  case SMESH::NODE:   return theType.Location( "NODE", 1, theType.Length() );
-  case SMESH::EDGE:   return theType.Location( "EDGE", 1, theType.Length() );
-  case SMESH::FACE:   return theType.Location( "FACE", 1, theType.Length() );
-  case SMESH::VOLUME: return theType.Location( "VOLUME", 1, theType.Length() );
-  default:;
+bool _pyGen::IsGeomObject(const _pyID& theObjID) const
+{
+  if ( myGeomIDNb )
+  {
+    return ( myGeomIDIndex <= theObjID.Length() &&
+             int( theObjID.Value( myGeomIDIndex )) == myGeomIDNb &&
+             _pyCommand::IsStudyEntry( theObjID ));
   }
   return false;
 }
 
 //================================================================================
 /*!
- * \brief 
-  * \param theCreationCmd - 
+ * \brief Returns true if an object is not present in a study
+ */
+//================================================================================
+
+bool _pyGen::IsNotPublished(const _pyID& theObjID) const
+{
+  if ( theObjID.IsEmpty() ) return false;
+
+  if ( myObjectNames.IsBound( theObjID ))
+    return false; // SMESH object is in study
+
+  // either the SMESH object is not in study or it is a GEOM object
+  if ( IsGeomObject( theObjID ))
+  {
+    SALOMEDS::SObject_var so = myStudy->FindObjectID( theObjID.ToCString() );
+    if ( so->_is_nil() ) return true;
+    CORBA::Object_var obj = so->GetObject();
+    return CORBA::is_nil( obj );
+  }
+  return true; // SMESH object not in study
+}
+
+//================================================================================
+/*!
+ * \brief Return reader of  hypotheses of plugins
+ */
+//================================================================================
+
+Handle( _pyHypothesisReader ) _pyGen::GetHypothesisReader() const
+{
+  if (myHypReader.IsNull() )
+    ((_pyGen*) this)->myHypReader = new _pyHypothesisReader;
+
+  return myHypReader;
+}
+
+
+//================================================================================
+/*!
+ * \brief Mesh created by SMESH_Gen
  */
 //================================================================================
 
 _pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd)
-  : _pyObject(theCreationCmd), myHasEditor(false)
+  : _pyObject( theCreationCmd ), myGeomNotInStudy( false )
 {
-  // convert my creation command
+  if ( theCreationCmd->GetMethod() == "CreateMesh" && theGen->IsNotPublished( GetGeom() ))
+    myGeomNotInStudy = true;
+
+  // convert my creation command --> smeshpy.Mesh(...)
   Handle(_pyCommand) creationCmd = GetCreationCmd();
-  //TCollection_AsciiString str = creationCmd->GetMethod();
-//   if(str != "CreateMeshesFromUNV" &&
-//      str != "CreateMeshesFromMED" &&
-//      str != "CreateMeshesFromSTL")
-  creationCmd->SetObject( SMESH_2smeshpy::SmeshpyName() ); 
+  creationCmd->SetObject( SMESH_2smeshpy::SmeshpyName() );
   creationCmd->SetMethod( "Mesh" );
-
-  theGen->SetAccessorMethod( GetID(), "GetMesh()" );
+  theGen->SetAccessorMethod( GetID(), _pyMesh::AccessorMethod() );
 }
 
 //================================================================================
 /*!
- * \brief 
-  * \param theCreationCmd - 
+ * \brief Mesh created by SMESH_MeshEditor
  */
 //================================================================================
-_pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd, const TCollection_AsciiString& id):
-  _pyObject(theCreationCmd), myHasEditor(false)
+
+_pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd, const _pyID& meshId):
+  _pyObject(theCreationCmd,meshId), myGeomNotInStudy(false )
 {
+  if ( theCreationCmd->MethodStartsFrom( "CreateMeshesFrom" ))
+  {
+    // this mesh depends on the exported mesh
+    const TCollection_AsciiString& file = theCreationCmd->GetArg( 1 );
+    if ( !file.IsEmpty() )
+    {
+      ExportedMeshData& exportData = theGen->FindExportedMesh( file );
+      addFatherMesh( exportData.myMesh );
+      if ( !exportData.myLastComputeCmd.IsNull() )
+      {
+        // restore cleared Compute() by which the exported mesh was generated
+        exportData.myLastComputeCmd->GetString() = exportData.myLastComputeCmdString;
+        // protect that Compute() cmd from clearing
+        if ( exportData.myMesh->myLastComputeCmd == exportData.myLastComputeCmd )
+          exportData.myMesh->myLastComputeCmd.Nullify();
+      }
+    }
+  }
+  else if ( theCreationCmd->MethodStartsFrom( "Concatenate" ))
+  {
+    // this mesh depends on concatenated meshes
+    const TCollection_AsciiString& meshIDs = theCreationCmd->GetArg( 1 );
+    list< _pyID > idList = theCreationCmd->GetStudyEntries( meshIDs );
+    list< _pyID >::iterator meshID = idList.begin();
+    for ( ; meshID != idList.end(); ++meshID )
+      addFatherMesh( *meshID );
+  }
+  else if ( theCreationCmd->GetMethod() == "CopyMesh" )
+  {
+    // this mesh depends on a copied IdSource
+    const _pyID& objID = theCreationCmd->GetArg( 1 );
+    addFatherMesh( objID );
+  }
+  else if ( theCreationCmd->GetMethod().Search("MakeMesh") != -1 ||
+            theCreationCmd->GetMethod() == "MakeBoundaryMesh" ||
+            theCreationCmd->GetMethod() == "MakeBoundaryElements" )
+  {
+    // this mesh depends on a source mesh
+    // (theCreationCmd is already Process()ed by _pyMeshEditor)
+    const _pyID& meshID = theCreationCmd->GetObject();
+    addFatherMesh( meshID );
+  }
+    
   // convert my creation command
   Handle(_pyCommand) creationCmd = GetCreationCmd();
-  creationCmd->SetObject( SMESH_2smeshpy::SmeshpyName() ); 
-  theGen->SetAccessorMethod( id, "GetMesh()" );
+  creationCmd->SetObject( SMESH_2smeshpy::SmeshpyName() );
+  theGen->SetAccessorMethod( meshId, _pyMesh::AccessorMethod() );
 }
 
 //================================================================================
 /*!
- * \brief Convert a IDL API command of SMESH::Mesh to a method call of python Mesh
+ * \brief Convert an IDL API command of SMESH::SMESH_Mesh to a method call of python Mesh
   * \param theCommand - Engine method called for this mesh
  */
 //================================================================================
@@ -815,15 +1419,69 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
   //     --> in Mesh.ExportMED( f, auto_groups, version )
   // 5. etc
 
-  const TCollection_AsciiString method = theCommand->GetMethod();
-  // ----------------------------------------------------------------------
-  if ( method == "GetSubMesh" ) {
-    Handle(_pySubMesh) subMesh = theGen->FindSubMesh( theCommand->GetResultValue() );
-    if ( !subMesh.IsNull() ) {
-      subMesh->SetCreator( this );
-      mySubmeshes.push_back( subMesh );
-    }
-  }
+  const TCollection_AsciiString& method = theCommand->GetMethod();
+  // ----------------------------------------------------------------------
+  if ( method == "Compute" ) // in snapshot mode, clear the previous Compute()
+  {
+    if ( !theGen->IsToKeepAllCommands() ) // !historical
+    {
+      list< Handle(_pyHypothesis) >::iterator hyp;
+      if ( !myLastComputeCmd.IsNull() )
+      {
+        for ( hyp = myHypos.begin(); hyp != myHypos.end(); ++hyp )
+          (*hyp)->ComputeDiscarded( myLastComputeCmd );
+
+        myLastComputeCmd->Clear();
+      }
+      myLastComputeCmd = theCommand;
+
+      for ( hyp = myHypos.begin(); hyp != myHypos.end(); ++hyp )
+        (*hyp)->MeshComputed( myLastComputeCmd );
+    }
+    Flush();
+  }
+  // ----------------------------------------------------------------------
+  else if ( method == "Clear" ) // in snapshot mode, clear all previous commands
+  {
+    if ( !theGen->IsToKeepAllCommands() ) // !historical
+    {
+      int untilCmdNb =
+        myChildMeshes.empty() ? 0 : myChildMeshes.back()->GetCreationCmd()->GetOrderNb();
+      // list< Handle(_pyCommand) >::reverse_iterator cmd = myProcessedCmds.rbegin();
+      // for ( ; cmd != myProcessedCmds.rend() && (*cmd)->GetOrderNb() > untilCmdNb; ++cmd )
+      //   (*cmd)->Clear();
+      if ( !myLastComputeCmd.IsNull() )
+      {
+        list< Handle(_pyHypothesis) >::iterator hyp;
+        for ( hyp = myHypos.begin(); hyp != myHypos.end(); ++hyp )
+          (*hyp)->ComputeDiscarded( myLastComputeCmd );
+
+        myLastComputeCmd->Clear();
+      }
+
+      list< Handle(_pyMeshEditor)>::iterator e = myEditors.begin();
+      for ( ; e != myEditors.end(); ++e )
+      {
+        list< Handle(_pyCommand)>& cmds = (*e)->GetProcessedCmds();
+        list< Handle(_pyCommand) >::reverse_iterator cmd = cmds.rbegin();
+        for ( ; cmd != cmds.rend() && (*cmd)->GetOrderNb() > untilCmdNb; ++cmd )
+          if ( !(*cmd)->IsEmpty() )
+          {
+            if ( (*cmd)->GetStudyEntries( (*cmd)->GetResultValue() ).empty() ) // no object created
+              (*cmd)->Clear();
+          }
+      }
+      myLastComputeCmd = theCommand; // to clear Clear() the same way as Compute()
+    }
+  }
+  // ----------------------------------------------------------------------
+  else if ( method == "GetSubMesh" ) { // collect submeshes of the mesh
+    Handle(_pySubMesh) subMesh = theGen->FindSubMesh( theCommand->GetResultValue() );
+    if ( !subMesh.IsNull() ) {
+      subMesh->SetCreator( this );
+      mySubmeshes.push_back( subMesh );
+    }
+  }
   // ----------------------------------------------------------------------
   else if ( method == "AddHypothesis" ) { // mesh.AddHypothesis(geom, HYPO )
     myAddHypCmds.push_back( theCommand );
@@ -837,30 +1495,46 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
     }
   }
   // ----------------------------------------------------------------------
-  else if ( method == "CreateGroupFromGEOM" ) {// (type, name, grp)
-    _pyID grp = theCommand->GetArg( 3 );
-    if ( sameGroupType( grp, theCommand->GetArg( 1 )) ) { // --> Group(grp)
-      theCommand->SetMethod( "Group" );
-      theCommand->RemoveArgs();
-      theCommand->SetArg( 1, grp );
-    }
-    else {
-      _pyID type = theCommand->GetArg( 1 );
-      _pyID name = theCommand->GetArg( 2 );
-      theCommand->SetMethod( "GroupOnGeom" );
-      theCommand->RemoveArgs();
-      theCommand->SetArg( 1, grp );
-      theCommand->SetArg( 2, name );
-      theCommand->SetArg( 3, type );
-    }
-  }
-  // ----------------------------------------------------------------------
-  else if ( method == "ExportToMED" ) { // ExportToMED() --> ExportMED()
-    theCommand->SetMethod( "ExportMED" );
+  else if ( method == "CreateGroup" ||
+            method == "CreateGroupFromGEOM" ||
+            method == "CreateGroupFromFilter" )
+  {
+    Handle(_pyGroup) group = new _pyGroup( theCommand );
+    myGroups.push_back( group );
+    theGen->AddObject( group );
   }
   // ----------------------------------------------------------------------
-  else if ( method == "CreateGroup" ) { // CreateGroup() --> CreateEmptyGroup()
-    theCommand->SetMethod( "CreateEmptyGroup" );
+  else if ( theCommand->MethodStartsFrom( "Export" ))
+  {
+    if ( method == "ExportToMED" ||   // ExportToMED()  --> ExportMED()
+         method == "ExportToMEDX" ) { // ExportToMEDX() --> ExportMED()
+      theCommand->SetMethod( "ExportMED" );
+    }
+    else if ( method == "ExportCGNS" )
+    { // ExportCGNS(part, ...) -> ExportCGNS(..., part)
+      _pyID partID = theCommand->GetArg( 1 );
+      int nbArgs = theCommand->GetNbArgs();
+      for ( int i = 2; i <= nbArgs; ++i )
+        theCommand->SetArg( i-1, theCommand->GetArg( i ));
+      theCommand->SetArg( nbArgs, partID );
+    }
+    else if ( theCommand->MethodStartsFrom( "ExportPartTo" ))
+    { // ExportPartTo*(part, ...) -> Export*(..., part)
+      //
+      // remove "PartTo" from the method
+      TCollection_AsciiString newMethod = method;
+      newMethod.Remove( 7, 6 );
+      theCommand->SetMethod( newMethod );
+      // make the 1st arg be the last one
+      _pyID partID = theCommand->GetArg( 1 );
+      int nbArgs = theCommand->GetNbArgs();
+      for ( int i = 2; i <= nbArgs; ++i )
+        theCommand->SetArg( i-1, theCommand->GetArg( i ));
+      theCommand->SetArg( nbArgs, partID );
+    }
+    // remember file name
+    theGen->AddExportedMesh( theCommand->GetArg( 1 ),
+                             ExportedMeshData( this, myLastComputeCmd ));
   }
   // ----------------------------------------------------------------------
   else if ( method == "RemoveHypothesis" ) // (geom, hyp)
@@ -895,6 +1569,40 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
     // remove hyp from myHypos
     myHypos.remove( hyp );
   }
+  // check for SubMesh order commands
+  else if ( method == "GetMeshOrder" || method == "SetMeshOrder" )
+  {
+    // make commands GetSubMesh() returning sub-meshes be before using sub-meshes
+    // by GetMeshOrder() and SetMeshOrder(), since by defalut GetSubMesh()
+    // commands are moved at the end of the script
+    TCollection_AsciiString subIDs =
+      ( method == "SetMeshOrder" ) ? theCommand->GetArg(1) : theCommand->GetResultValue();
+    list< _pyID > idList = theCommand->GetStudyEntries( subIDs );
+    list< _pyID >::iterator subID = idList.begin();
+    for ( ; subID != idList.end(); ++subID )
+    {
+      Handle(_pySubMesh) subMesh = theGen->FindSubMesh( *subID );
+      if ( !subMesh.IsNull() )
+        subMesh->Process( theCommand ); // it moves GetSubMesh() before theCommand
+    }
+  }
+  // update list of groups
+  else if ( method == "GetGroups" )
+  {
+    TCollection_AsciiString grIDs = theCommand->GetResultValue();
+    list< _pyID > idList = theCommand->GetStudyEntries( grIDs );
+    list< _pyID >::iterator grID = idList.begin();
+    for ( ; grID != idList.end(); ++grID )
+    {
+      Handle(_pyObject) obj = theGen->FindObject( *grID );
+      if ( obj.IsNull() )
+      {
+        Handle(_pyGroup) group = new _pyGroup( theCommand, *grID );
+        theGen->AddObject( group );
+        myGroups.push_back( group );
+      }
+    }
+  }
   // add accessor method if necessary
   else
   {
@@ -912,12 +1620,12 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
 
 bool _pyMesh::NeedMeshAccess( const Handle(_pyCommand)& theCommand )
 {
-  // names of SMESH_Mesh methods fully equal to methods of class Mesh, so
-  // no conversion is needed for them at all:
+  // names of SMESH_Mesh methods fully equal to methods of python class Mesh,
+  // so no conversion is needed for them at all:
   static TStringSet sameMethods;
   if ( sameMethods.empty() ) {
     const char * names[] =
-      { "ExportDAT","ExportUNV","ExportSTL", "RemoveGroup","RemoveGroupWithContents",
+      { "ExportDAT","ExportUNV","ExportSTL","ExportSAUV", "RemoveGroup","RemoveGroupWithContents",
         "GetGroups","UnionGroups","IntersectGroups","CutGroups","GetLog","GetId","ClearLog",
         "GetStudyId","HasDuplicatedGroupNamesMED","GetMEDMesh","NbNodes","NbElements",
         "NbEdges","NbEdgesOfOrder","NbFaces","NbFacesOfOrder","NbTriangles",
@@ -929,7 +1637,7 @@ bool _pyMesh::NeedMeshAccess( const Handle(_pyCommand)& theCommand )
         "GetNodeInverseElements","GetShapeID","GetShapeIDForElem","GetElemNbNodes",
         "GetElemNode","IsMediumNode","IsMediumNodeOfAnyElem","ElemNbEdges","ElemNbFaces",
         "IsPoly","IsQuadratic","BaryCenter","GetHypothesisList", "SetAutoColor", "GetAutoColor",
-        "Clear", "ConvertToStandalone"
+        "Clear", "ConvertToStandalone", "GetMeshOrder", "SetMeshOrder"
         ,"" }; // <- mark of end
     sameMethods.Insert( names );
   }
@@ -945,6 +1653,23 @@ bool _pyMesh::NeedMeshAccess( const Handle(_pyCommand)& theCommand )
 
 void _pyMesh::Flush()
 {
+  {
+    // get the meshes this mesh depends on via hypotheses
+    list< Handle(_pyMesh) > fatherMeshes;
+    list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin();
+    for ( ; hyp != myHypos.end(); ++hyp )
+      if ( ! (*hyp)->GetReferredMeshesAndGeom( fatherMeshes ))
+        myGeomNotInStudy = true;
+
+    list< Handle(_pyMesh) >::iterator m = fatherMeshes.begin();
+    for ( ; m != fatherMeshes.end(); ++m )
+      addFatherMesh( *m );
+    // if ( removedGeom )
+    //     SetRemovedFromStudy(); // as reffered geometry not in study
+  }
+  if ( myGeomNotInStudy )
+    return;
+
   list < Handle(_pyCommand) >::iterator cmd;
 
   // try to convert algo addition like this:
@@ -961,30 +1686,34 @@ void _pyMesh::Flush()
     // check and create new algorithm instance if it is already wrapped
     if ( algo->IsWrapped() ) {
       _pyID localAlgoID = theGen->GenerateNewID( algoID );
-      TCollection_AsciiString aNewCmdStr = localAlgoID +
-       TCollection_AsciiString( " = " ) + theGen->GetID() +
-       TCollection_AsciiString( ".CreateHypothesis( \"" ) + algo->GetAlgoType() +
-       TCollection_AsciiString( "\" )" );
-      
+      TCollection_AsciiString aNewCmdStr = addCmd->GetIndentation() + localAlgoID +
+        TCollection_AsciiString( " = " ) + theGen->GetID() +
+        TCollection_AsciiString( ".CreateHypothesis( \"" ) + algo->GetAlgoType() +
+        TCollection_AsciiString( "\" )" );
+
       Handle(_pyCommand) newCmd = theGen->AddCommand( aNewCmdStr );
       Handle(_pyAlgorithm) newAlgo = Handle(_pyAlgorithm)::DownCast(theGen->FindHyp( localAlgoID ));
       if ( !newAlgo.IsNull() ) {
-       newAlgo->Assign( algo, this->GetID() );
-       newAlgo->SetCreationCmd( newCmd );
-       algo = newAlgo;
-       // set algorithm creation
-       theGen->SetCommandBefore( newCmd, addCmd );
+        newAlgo->Assign( algo, this->GetID() );
+        newAlgo->SetCreationCmd( newCmd );
+        algo = newAlgo;
+        // set algorithm creation
+        theGen->SetCommandBefore( newCmd, addCmd );
+        myHypos.push_back( newAlgo );
+        if ( !myLastComputeCmd.IsNull() &&
+             newCmd->GetOrderNb() == myLastComputeCmd->GetOrderNb() + 1)
+          newAlgo->MeshComputed( myLastComputeCmd );
       }
       else
-       newCmd->Clear();
+        newCmd->Clear();
     }
     _pyID geom = addCmd->GetArg( 1 );
     bool isLocalAlgo = ( geom != GetGeom() );
-    
+
     // try to convert
     if ( algo->Addition2Creation( addCmd, this->GetID() )) // OK
     {
-      // wrapped algo is created atfer mesh creation
+      // wrapped algo is created after mesh creation
       GetCreationCmd()->AddDependantCmd( addCmd );
 
       if ( isLocalAlgo ) {
@@ -992,14 +1721,14 @@ void _pyMesh::Flush()
         addCmd->SetArg( addCmd->GetNbArgs() + 1,
                         TCollection_AsciiString( "geom=" ) + geom );
         // sm = mesh.GetSubMesh(geom, name) --> sm = ALGO.GetSubMesh()
-       list < Handle(_pySubMesh) >::iterator smIt;
+        list < Handle(_pySubMesh) >::iterator smIt;
         for ( smIt = mySubmeshes.begin(); smIt != mySubmeshes.end(); ++smIt ) {
-         Handle(_pySubMesh) subMesh = *smIt;
+          Handle(_pySubMesh) subMesh = *smIt;
           Handle(_pyCommand) subCmd = subMesh->GetCreationCmd();
           if ( geom == subCmd->GetArg( 1 )) {
             subCmd->SetObject( algo->GetID() );
             subCmd->RemoveArgs();
-           subMesh->SetCreator( algo );
+            subMesh->SetCreator( algo );
           }
         }
       }
@@ -1034,21 +1763,126 @@ void _pyMesh::Flush()
     }
   }
 
-  // sm = mesh.GetSubMesh(geom, name) --> sm = mesh.GetMesh().GetSubMesh(geom, name)
-//   for ( cmd = mySubmeshes.begin(); cmd != mySubmeshes.end(); ++cmd ) {
-//     Handle(_pyCommand) subCmd = *cmd;
-//     if ( subCmd->GetNbArgs() > 0 )
-//       AddMeshAccess( subCmd );
-//   }
   myAddHypCmds.clear();
   mySubmeshes.clear();
 
   // flush hypotheses
   list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin();
-  for ( ; hyp != myHypos.end(); ++hyp )
+  for ( hyp = myHypos.begin(); hyp != myHypos.end(); ++hyp )
     (*hyp)->Flush();
 }
 
+//================================================================================
+/*!
+ * \brief Sets myIsPublished of me and of all objects depending on me.
+ */
+//================================================================================
+
+void _pyMesh::SetRemovedFromStudy(const bool isRemoved)
+{
+  _pyObject::SetRemovedFromStudy(isRemoved);
+
+  list< Handle(_pySubMesh) >::iterator sm = mySubmeshes.begin();
+  for ( ; sm != mySubmeshes.end(); ++sm )
+    (*sm)->SetRemovedFromStudy(isRemoved);
+
+  list< Handle(_pyGroup) >::iterator gr = myGroups.begin();
+  for ( ; gr != myGroups.end(); ++gr )
+    (*gr)->SetRemovedFromStudy(isRemoved);
+
+  list< Handle(_pyMesh) >::iterator m = myChildMeshes.begin();
+  for ( ; m != myChildMeshes.end(); ++m )
+    (*m)->SetRemovedFromStudy(isRemoved);
+
+  list< Handle(_pyMeshEditor)>::iterator e = myEditors.begin();
+  for ( ; e != myEditors.end(); ++e )
+    (*e)->SetRemovedFromStudy(isRemoved);
+}
+
+//================================================================================
+/*!
+ * \brief Return true if none of myChildMeshes is in study
+ */
+//================================================================================
+
+bool _pyMesh::CanClear()
+{
+  if ( IsInStudy() )
+    return false;
+
+  list< Handle(_pyMesh) >::iterator m = myChildMeshes.begin();
+  for ( ; m != myChildMeshes.end(); ++m )
+    if ( !(*m)->CanClear() )
+      return false;
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Clear my commands and commands of mesh editor
+ */
+//================================================================================
+
+void _pyMesh::ClearCommands()
+{
+  if ( !CanClear() )
+  {
+    if ( !IsInStudy() )
+    {
+      // mark all sub-objects as not removed, except child meshes
+      list< Handle(_pyMesh) > children;
+      children.swap( myChildMeshes );
+      SetRemovedFromStudy( false );
+      children.swap( myChildMeshes );
+    }
+    return;
+  }
+  _pyObject::ClearCommands();
+
+  list< Handle(_pySubMesh) >::iterator sm = mySubmeshes.begin();
+  for ( ; sm != mySubmeshes.end(); ++sm )
+    (*sm)->ClearCommands();
+  
+  list< Handle(_pyGroup) >::iterator gr = myGroups.begin();
+  for ( ; gr != myGroups.end(); ++gr )
+    (*gr)->ClearCommands();
+
+  list< Handle(_pyMeshEditor)>::iterator e = myEditors.begin();
+  for ( ; e != myEditors.end(); ++e )
+    (*e)->ClearCommands();
+}
+
+//================================================================================
+/*!
+ * \brief Add a father mesh by ID
+ */
+//================================================================================
+
+void _pyMesh::addFatherMesh( const _pyID& meshID )
+{
+  if ( !meshID.IsEmpty() )
+    addFatherMesh( Handle(_pyMesh)::DownCast( theGen->FindObject( meshID )));
+}
+
+//================================================================================
+/*!
+ * \brief Add a father mesh
+ */
+//================================================================================
+
+void _pyMesh::addFatherMesh( const Handle(_pyMesh)& mesh )
+{
+  if ( !mesh.IsNull() )
+  {
+    //myFatherMeshes.push_back( mesh );
+    mesh->myChildMeshes.push_back( this );
+
+    // protect last Compute() from clearing by the next Compute()
+    mesh->myLastComputeCmd.Nullify();
+  }
+}
+
 //================================================================================
 /*!
  * \brief MeshEditor convert its commands to ones of mesh
@@ -1061,6 +1895,10 @@ _pyMeshEditor::_pyMeshEditor(const Handle(_pyCommand)& theCreationCmd):
   myMesh = theCreationCmd->GetObject();
   myCreationCmdStr = theCreationCmd->GetString();
   theCreationCmd->Clear();
+
+  Handle(_pyMesh) mesh = ObjectToMesh( theGen->FindObject( myMesh ));
+  if ( !mesh.IsNull() )
+    mesh->AddEditor( this );
 }
 
 //================================================================================
@@ -1071,34 +1909,36 @@ _pyMeshEditor::_pyMeshEditor(const Handle(_pyCommand)& theCreationCmd):
 
 void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
 {
-  // names of SMESH_MeshEditor methods fully equal to methods of class Mesh, so
+  // names of SMESH_MeshEditor methods fully equal to methods of python class Mesh, so
   // commands calling this methods are converted to calls of methods of Mesh
   static TStringSet sameMethods;
   if ( sameMethods.empty() ) {
     const char * names[] = {
-      "RemoveElements","RemoveNodes","AddNode","AddEdge","AddFace","AddPolygonalFace",
+      "RemoveElements","RemoveNodes","RemoveOrphanNodes","AddNode","Add0DElement","AddEdge","AddFace","AddPolygonalFace","AddBall",
       "AddVolume","AddPolyhedralVolume","AddPolyhedralVolumeByFaces","MoveNode", "MoveClosestNodeToPoint",
       "InverseDiag","DeleteDiag","Reorient","ReorientObject","TriToQuad","SplitQuad","SplitQuadObject",
       "BestSplit","Smooth","SmoothObject","SmoothParametric","SmoothParametricObject",
       "ConvertToQuadratic","ConvertFromQuadratic","RenumberNodes","RenumberElements",
       "RotationSweep","RotationSweepObject","RotationSweepObject1D","RotationSweepObject2D",
       "ExtrusionSweep","AdvancedExtrusion","ExtrusionSweepObject","ExtrusionSweepObject1D","ExtrusionSweepObject2D",
-      "ExtrusionAlongPath","ExtrusionAlongPathObject","ExtrusionAlongPathObject1D","ExtrusionAlongPathObject2D",
+      "ExtrusionAlongPath","ExtrusionAlongPathObject","ExtrusionAlongPathX",
+      "ExtrusionAlongPathObject1D","ExtrusionAlongPathObject2D",
       "Mirror","MirrorObject","Translate","TranslateObject","Rotate","RotateObject",
-      "FindCoincidentNodes","FindCoincidentNodesOnPart","MergeNodes","FindEqualElements",
+      "FindCoincidentNodes",/*"FindCoincidentNodesOnPart",*/"MergeNodes","FindEqualElements",
       "MergeElements","MergeEqualElements","SewFreeBorders","SewConformFreeBorders",
       "SewBorderToSide","SewSideElements","ChangeElemNodes","GetLastCreatedNodes",
       "GetLastCreatedElems",
       "MirrorMakeMesh","MirrorObjectMakeMesh","TranslateMakeMesh",
-      "TranslateObjectMakeMesh","RotateMakeMesh","RotateObjectMakeMesh"
+      "TranslateObjectMakeMesh","RotateMakeMesh","RotateObjectMakeMesh","MakeBoundaryMesh",
+      "MakeBoundaryElements", "SplitVolumesIntoTetra"
       ,"" }; // <- mark of the end
     sameMethods.Insert( names );
   }
 
   // names of SMESH_MeshEditor methods which differ from methods of class Mesh
-  // only last two arguments
+  // only by last two arguments
   static TStringSet diffLastTwoArgsMethods;
-  if (diffLastTwoArgsMethods.empty() ){
+  if (diffLastTwoArgsMethods.empty() ) {
     const char * names[] = {
       "MirrorMakeGroups","MirrorObjectMakeGroups",
       "TranslateMakeGroups","TranslateObjectMakeGroups",
@@ -1107,54 +1947,162 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
     diffLastTwoArgsMethods.Insert( names );
   }
 
-  if ( sameMethods.Contains( theCommand->GetMethod() )) {
-    theCommand->SetObject( myMesh );
-
-    // meshes made by *MakeMesh() methods are not wrapped by _pyMesh,
-    // so let _pyMesh care of it (TMP?)
-//     if ( theCommand->GetMethod().Search("MakeMesh") != -1 )
-//       _pyMesh( new _pyCommand( theCommand->GetString(), 0 )); // for theGen->SetAccessorMethod()
-  }
-  else {
-    
-    //Replace SMESH_MeshEditor "MakeGroups" functions on the Mesh 
+  const TCollection_AsciiString & method = theCommand->GetMethod();
+  bool isPyMeshMethod = sameMethods.Contains( method );
+  if ( !isPyMeshMethod )
+  {
+    //Replace SMESH_MeshEditor "MakeGroups" functions by the Mesh
     //functions with the flag "theMakeGroups = True" like:
     //SMESH_MeshEditor.CmdMakeGroups => Mesh.Cmd(...,True)
-    int pos = theCommand->GetMethod().Search("MakeGroups");
-    if( pos != -1) {  
+    int pos = method.Search("MakeGroups");
+    if( pos != -1)
+    {
+      isPyMeshMethod = true;
+      bool is0DmethId  = ( method == "ExtrusionSweepMakeGroups0D" );
+      bool is0DmethObj = ( method == "ExtrusionSweepObject0DMakeGroups");
+
       // 1. Remove "MakeGroups" from the Command
       TCollection_AsciiString aMethod = theCommand->GetMethod();
       int nbArgsToAdd = diffLastTwoArgsMethods.Contains(aMethod) ? 2 : 1;
+      
+      if(is0DmethObj)
+        pos = pos-2;  //Remove "0D" from the Command too
       aMethod.Trunc(pos-1);
       theCommand->SetMethod(aMethod);
 
-      // 2. Set Mesh object instead of SMESH_MeshEditor
-      theCommand->SetObject( myMesh );
-
-      // 3. And add last "True" argument
+      // 2. And add last "True" argument(s)
       while(nbArgsToAdd--)
-        theCommand->SetArg(theCommand->GetNbArgs()+1,"True ");
+        theCommand->SetArg(theCommand->GetNbArgs()+1,"True");
+      if( is0DmethId || is0DmethObj )
+        theCommand->SetArg(theCommand->GetNbArgs()+1,"True");
     }
-    else {
-      // editor creation command is needed only if any editor function is called
-      theGen->AddMeshAccessorMethod( theCommand ); // for *Object()
-      if ( !myCreationCmdStr.IsEmpty() ) {
-        GetCreationCmd()->GetString() = myCreationCmdStr;
-        myCreationCmdStr.Clear();
-      }
+  }
+
+  // ExtrusionSweep0D() -> ExtrusionSweep()
+  // ExtrusionSweepObject0D() -> ExtrusionSweepObject()
+  if ( !isPyMeshMethod && ( method == "ExtrusionSweep0D"  ||
+                            method == "ExtrusionSweepObject0D" ))
+  {
+    isPyMeshMethod = true;
+    theCommand->SetMethod( method.SubString( 1, method.Length()-2));
+    theCommand->SetArg(theCommand->GetNbArgs()+1,"False");  //sets flag "MakeGroups = False"
+    theCommand->SetArg(theCommand->GetNbArgs()+1,"True");  //sets flag "IsNode = True"
+  }
+  // set "ExtrusionAlongPathX()" instead of "ExtrusionAlongPathObjX()"
+  if ( !isPyMeshMethod && method == "ExtrusionAlongPathObjX")
+  {
+    isPyMeshMethod = true;
+    theCommand->SetMethod("ExtrusionAlongPathX");
+  }
+
+  // set "FindCoincidentNodesOnPart()" instead of "FindCoincidentNodesOnPartBut()"
+  if ( !isPyMeshMethod && method == "FindCoincidentNodesOnPartBut")
+  {
+    isPyMeshMethod = true;
+    theCommand->SetMethod("FindCoincidentNodesOnPart");
+  }
+  // DoubleNode...New(...) -> DoubleNode...(...,True)
+  if ( !isPyMeshMethod && ( method == "DoubleNodeElemGroupNew"  ||
+                            method == "DoubleNodeElemGroupsNew" ||
+                            method == "DoubleNodeGroupNew"      ||
+                            method == "DoubleNodeGroupsNew"     ||
+                            method == "DoubleNodeElemGroup2New" ||
+                            method == "DoubleNodeElemGroups2New"))
+  {
+    isPyMeshMethod = true;
+    const int excessLen = 3 + int( method.Value( method.Length()-3 ) == '2' );
+    theCommand->SetMethod( method.SubString( 1, method.Length()-excessLen));
+    if ( excessLen == 3 )
+    {
+      theCommand->SetArg(theCommand->GetNbArgs()+1,"True");
+    }
+    else if ( theCommand->GetArg(4) == "0" ||
+              theCommand->GetArg(5) == "0" )
+    {
+      // [ nothing, Group ] = DoubleNodeGroup2New(,,,False, True) ->
+      // Group = DoubleNodeGroup2New(,,,False, True)
+      _pyID groupID = theCommand->GetResultValue( 1 + int( theCommand->GetArg(4) == "0"));
+      theCommand->SetResultValue( groupID );
+    }
+  }
+  // ConvertToQuadraticObject(bool,obj) -> ConvertToQuadratic(bool,obj)
+  // ConvertFromQuadraticObject(obj) -> ConvertFromQuadratic(obj)
+  if ( !isPyMeshMethod && ( method == "ConvertToQuadraticObject" ||
+                            method == "ConvertFromQuadraticObject" ))
+  {
+    isPyMeshMethod = true;
+    theCommand->SetMethod( method.SubString( 1, method.Length()-6));
+  }
+  // FindAmongElementsByPoint(meshPart, x, y, z, elementType) ->
+  // FindElementsByPoint(x, y, z, elementType, meshPart)
+  if ( !isPyMeshMethod && method == "FindAmongElementsByPoint" )
+  {
+    isPyMeshMethod = true;
+    theCommand->SetMethod( "FindElementsByPoint" );
+    // make the 1st arg be the last one
+    _pyID partID = theCommand->GetArg( 1 );
+    int nbArgs = theCommand->GetNbArgs();
+    for ( int i = 2; i <= nbArgs; ++i )
+      theCommand->SetArg( i-1, theCommand->GetArg( i ));
+    theCommand->SetArg( nbArgs, partID );
+  }
+  // Reorient2D( mesh, dir, face, point ) -> Reorient2D( mesh, dir, faceORpoint )
+  if ( !isPyMeshMethod && method == "Reorient2D" )
+  {
+    isPyMeshMethod = true;
+    _AString mesh  = theCommand->GetArg( 1 );
+    _AString dir   = theCommand->GetArg( 2 );
+    _AString face  = theCommand->GetArg( 3 );
+    _AString point = theCommand->GetArg( 4 );
+    theCommand->RemoveArgs();
+    theCommand->SetArg( 1, mesh );
+    theCommand->SetArg( 2, dir );
+    if ( face.Value(1) == '-' || face.Value(1) == '0' ) // invalid: face <= 0
+      theCommand->SetArg( 3, point );
+    else
+      theCommand->SetArg( 3, face );
+  }
+
+  // meshes made by *MakeMesh() methods are not wrapped by _pyMesh,
+  // so let _pyMesh care of it (TMP?)
+  //     if ( theCommand->GetMethod().Search("MakeMesh") != -1 )
+  //       _pyMesh( new _pyCommand( theCommand->GetString(), 0 )); // for theGen->SetAccessorMethod()
+  if ( isPyMeshMethod )
+  {
+    theCommand->SetObject( myMesh );
+  }
+  else
+  {
+    // editor creation command is needed only if any editor function is called
+    theGen->AddMeshAccessorMethod( theCommand ); // for *Object()
+    if ( !myCreationCmdStr.IsEmpty() ) {
+      GetCreationCmd()->GetString() = myCreationCmdStr;
+      myCreationCmdStr.Clear();
     }
   }
 }
 
+//================================================================================
+/*!
+ * \brief Return true if my mesh can be removed
+ */
+//================================================================================
+
+bool _pyMeshEditor::CanClear()
+{
+  Handle(_pyMesh) mesh = ObjectToMesh( theGen->FindObject( myMesh ));
+  return mesh.IsNull() ? true : mesh->CanClear();
+}
+
 //================================================================================
 /*!
  * \brief _pyHypothesis constructor
-  * \param theCreationCmd - 
+  * \param theCreationCmd -
  */
 //================================================================================
 
 _pyHypothesis::_pyHypothesis(const Handle(_pyCommand)& theCreationCmd):
-  _pyObject( theCreationCmd )
+  _pyObject( theCreationCmd ), myCurCrMethod(0)
 {
   myIsAlgo = myIsWrapped = /*myIsConverted = myIsLocal = myDim = */false;
 }
@@ -1185,178 +2133,66 @@ Handle(_pyHypothesis) _pyHypothesis::NewHypothesis( const Handle(_pyCommand)& th
   algo = new _pyAlgorithm( theCreationCmd );
   hyp  = new _pyHypothesis( theCreationCmd );
 
-  // 1D Regular_1D ----------
-  if ( hypType == "Regular_1D" ) {
-    // set mesh's method creating algo,
-    // i.e. convertion result will be "regular1d = Mesh.Segment()",
-    // and set hypType by which algo creating a hypothesis is searched for
-    algo->SetConvMethodAndType("Segment", hypType.ToCString());
-  }
-  else if ( hypType == "CompositeSegment_1D" ) {
-    algo->SetConvMethodAndType("Segment", "Regular_1D");
-    algo->myArgs.Append( "algo=smesh.COMPOSITE");
-  }
-  else if ( hypType == "LocalLength" ) {
-    // set algo's method creating hyp, and algo type
-    hyp->SetConvMethodAndType( "LocalLength", "Regular_1D");
-    // set method whose 1 arg will become the 1-st arg of hyp creation command
-    // i.e. convertion result will be "locallength = regular1d.LocalLength(<arg of SetLength()>)"
-    hyp->AddArgMethod( "SetLength" );
-  }
-  else if ( hypType == "MaxLength" ) {
-    // set algo's method creating hyp, and algo type
-    hyp->SetConvMethodAndType( "MaxSize", "Regular_1D");
-    // set method whose 1 arg will become the 1-st arg of hyp creation command
-    // i.e. convertion result will be "maxsize = regular1d.MaxSize(<arg of SetLength()>)"
-    hyp->AddArgMethod( "SetLength" );
-  }
-  else if ( hypType == "NumberOfSegments" ) {
+  if ( hypType == "NumberOfSegments" ) {
     hyp = new _pyNumberOfSegmentsHyp( theCreationCmd );
     hyp->SetConvMethodAndType( "NumberOfSegments", "Regular_1D");
     // arg of SetNumberOfSegments() will become the 1-st arg of hyp creation command
     hyp->AddArgMethod( "SetNumberOfSegments" );
     // arg of SetScaleFactor() will become the 2-nd arg of hyp creation command
     hyp->AddArgMethod( "SetScaleFactor" );
-  }
-  else if ( hypType == "Arithmetic1D" ) {
-    hyp = new _pyComplexParamHypo( theCreationCmd );
-    hyp->SetConvMethodAndType( "Arithmetic1D", "Regular_1D");
-  }
-  else if ( hypType == "StartEndLength" ) {
-    hyp = new _pyComplexParamHypo( theCreationCmd );
-    hyp->SetConvMethodAndType( "StartEndLength", "Regular_1D");
-  }
-  else if ( hypType == "Deflection1D" ) {
-    hyp->SetConvMethodAndType( "Deflection1D", "Regular_1D");
-    hyp->AddArgMethod( "SetDeflection" );
-  }
-  else if ( hypType == "Propagation" ) {
-    hyp->SetConvMethodAndType( "Propagation", "Regular_1D");
-  }
-  else if ( hypType == "QuadraticMesh" ) {
-    hyp->SetConvMethodAndType( "QuadraticMesh", "Regular_1D");
-  }
-  else if ( hypType == "AutomaticLength" ) {
-    hyp->SetConvMethodAndType( "AutomaticLength", "Regular_1D");
-    hyp->AddArgMethod( "SetFineness");
+    hyp->AddArgMethod( "SetReversedEdges" );
+    // same for ""CompositeSegment_1D:
+    hyp->SetConvMethodAndType( "NumberOfSegments", "CompositeSegment_1D");
+    hyp->AddArgMethod( "SetNumberOfSegments" );
+    hyp->AddArgMethod( "SetScaleFactor" );
+    hyp->AddArgMethod( "SetReversedEdges" );
   }
   else if ( hypType == "SegmentLengthAroundVertex" ) {
     hyp = new _pySegmentLengthAroundVertexHyp( theCreationCmd );
     hyp->SetConvMethodAndType( "LengthNearVertex", "Regular_1D" );
     hyp->AddArgMethod( "SetLength" );
+    // same for ""CompositeSegment_1D:
+    hyp->SetConvMethodAndType( "LengthNearVertex", "CompositeSegment_1D");
+    hyp->AddArgMethod( "SetLength" );
   }
-  // 1D Python_1D ----------
-  else if ( hypType == "Python_1D" ) {
-    algo->SetConvMethodAndType( "Segment", hypType.ToCString());
-    algo->myArgs.Append( "algo=smesh.PYTHON");
-  }
-  else if ( hypType == "PythonSplit1D" ) {
-    hyp->SetConvMethodAndType( "PythonSplit1D", "Python_1D");
-    hyp->AddArgMethod( "SetNumberOfSegments");
-    hyp->AddArgMethod( "SetPythonLog10RatioFunction");
-  }
-  // MEFISTO_2D ----------
-  else if ( hypType == "MEFISTO_2D" ) { // MEFISTO_2D
-    algo->SetConvMethodAndType( "Triangle", hypType.ToCString());
-  }
-  else if ( hypType == "MaxElementArea" ) {
-    hyp->SetConvMethodAndType( "MaxElementArea", "MEFISTO_2D");
-    hyp->SetConvMethodAndType( "MaxElementArea", "NETGEN_2D_ONLY");
-    hyp->AddArgMethod( "SetMaxElementArea");
-  }
-  else if ( hypType == "LengthFromEdges" ) {
-    hyp->SetConvMethodAndType( "LengthFromEdges", "MEFISTO_2D");
-    hyp->SetConvMethodAndType( "LengthFromEdges", "NETGEN_2D_ONLY");
-  }
-  // Quadrangle_2D ----------
-  else if ( hypType == "Quadrangle_2D" ) {
-    algo->SetConvMethodAndType( "Quadrangle" , hypType.ToCString());
-  }
-  else if ( hypType == "QuadranglePreference" ) {
-    hyp->SetConvMethodAndType( "QuadranglePreference", "Quadrangle_2D");
-    hyp->SetConvMethodAndType( "QuadranglePreference", "NETGEN_2D_ONLY");
-  }
-  else if ( hypType == "TrianglePreference" ) {
-    hyp->SetConvMethodAndType( "TrianglePreference", "Quadrangle_2D");
-  }    
-  // NETGEN ----------
-//   else if ( hypType == "NETGEN_2D") { // 1D-2D
-//     algo->SetConvMethodAndType( "Triangle" , hypType.ToCString());
-//     algo->myArgs.Append( "algo=smesh.NETGEN" );
-//   }
-  else if ( hypType == "NETGEN_2D_ONLY") { // 2D
-    algo->SetConvMethodAndType( "Triangle" , hypType.ToCString());
-    algo->myArgs.Append( "algo=smesh.NETGEN_2D" );
-  }
-  else if ( hypType == "NETGEN_3D") { // 3D
-    algo->SetConvMethodAndType( "Tetrahedron" , hypType.ToCString());
-    algo->myArgs.Append( "algo=smesh.NETGEN" );
-  }
-  else if ( hypType == "MaxElementVolume") {
-    hyp->SetConvMethodAndType( "MaxElementVolume", "NETGEN_3D");
-    hyp->AddArgMethod( "SetMaxElementVolume" );
-  }
-  // GHS3D_3D ----------
-  else if ( hypType == "GHS3D_3D" ) {
-    algo->SetConvMethodAndType( "Tetrahedron", hypType.ToCString());
-    algo->myArgs.Append( "algo=smesh.GHS3D" );
-  }
-  // Hexa_3D ---------
-  else if ( hypType == "Hexa_3D" ) {
-    algo->SetConvMethodAndType( "Hexahedron", hypType.ToCString());
-  }
-  // Repetitive Projection_1D ---------
-  else if ( hypType == "Projection_1D" ) {
-    algo->SetConvMethodAndType( "Projection1D", hypType.ToCString());
-  }
-  else if ( hypType == "ProjectionSource1D" ) {
-    hyp->SetConvMethodAndType( "SourceEdge", "Projection_1D");
-    hyp->AddArgMethod( "SetSourceEdge");
-    hyp->AddArgMethod( "SetSourceMesh");
-    // 2 args of SetVertexAssociation() will become the 3-th and 4-th args of hyp creation command
-    hyp->AddArgMethod( "SetVertexAssociation", 2 );
-  }
-  // Projection_2D ---------
-  else if ( hypType == "Projection_2D" ) {
-    algo->SetConvMethodAndType( "Projection2D", hypType.ToCString());
-  }
-  else if ( hypType == "ProjectionSource2D" ) {
-    hyp->SetConvMethodAndType( "SourceFace", "Projection_2D");
-    hyp->AddArgMethod( "SetSourceFace");
-    hyp->AddArgMethod( "SetSourceMesh");
-    hyp->AddArgMethod( "SetVertexAssociation", 4 );
-  }
-  // Projection_3D ---------
-  else if ( hypType == "Projection_3D" ) {
-    algo->SetConvMethodAndType( "Projection3D", hypType.ToCString());
-  }
-  else if ( hypType == "ProjectionSource3D" ) {
-    hyp->SetConvMethodAndType( "SourceShape3D", "Projection_3D");
-    hyp->AddArgMethod( "SetSource3DShape");
-    hyp->AddArgMethod( "SetSourceMesh");
-    hyp->AddArgMethod( "SetVertexAssociation", 4 );
-  }
-  // Prism_3D ---------
-  else if ( hypType == "Prism_3D" ) {
-    algo->SetConvMethodAndType( "Prism", hypType.ToCString());
-  }
-  // RadialPrism_3D ---------
-  else if ( hypType == "RadialPrism_3D" ) {
-    algo->SetConvMethodAndType( "Prism", hypType.ToCString());
-  }
-  else if ( hypType == "NumberOfLayers" ) {
-    hyp->SetConvMethodAndType( "NumberOfLayers", "RadialPrism_3D");
-    hyp->AddArgMethod( "SetNumberOfLayers" );
+  else if ( hypType == "LayerDistribution2D" ) {
+    hyp = new _pyLayerDistributionHypo( theCreationCmd, "Get2DHypothesis" );
+    hyp->SetConvMethodAndType( "LayerDistribution", "RadialQuadrangle_1D2D");
   }
   else if ( hypType == "LayerDistribution" ) {
-    hyp = new _pyLayerDistributionHypo( theCreationCmd );
+    hyp = new _pyLayerDistributionHypo( theCreationCmd, "Get3DHypothesis" );
     hyp->SetConvMethodAndType( "LayerDistribution", "RadialPrism_3D");
   }
+  else if ( hypType == "CartesianParameters3D" ) {
+    hyp = new _pyComplexParamHypo( theCreationCmd );
+    hyp->SetConvMethodAndType( "SetGrid", "Cartesian_3D");
+    for ( int iArg = 0; iArg < 4; ++iArg )
+      hyp->setCreationArg( iArg+1, "[]");
+  }
+  else
+  {
+    hyp = theGen->GetHypothesisReader()->GetHypothesis( hypType, theCreationCmd );
+  }
+
+  return algo->IsValid() ? algo : hyp;
+}
 
-  if ( algo->IsValid() ) {
-    return algo;
+//================================================================================
+/*!
+ * \brief Returns true if addition of this hypothesis to a given mesh can be
+ *        wrapped into hypothesis creation
+ */
+//================================================================================
+
+bool _pyHypothesis::IsWrappable(const _pyID& theMesh) const
+{
+  if ( !myIsWrapped && myMesh == theMesh && IsInStudy() )
+  {
+    Handle(_pyObject) pyMesh = theGen->FindObject( myMesh );
+    if ( !pyMesh.IsNull() && pyMesh->IsInStudy() )
+      return true;
   }
-  return hyp;
+  return false;
 }
 
 //================================================================================
@@ -1394,20 +2230,20 @@ bool _pyHypothesis::Addition2Creation( const Handle(_pyCommand)& theCmd,
   theCmd->SetResultValue( GetID() );
   theCmd->SetObject( IsAlgo() ? theMesh : algo->GetID());
   theCmd->SetMethod( IsAlgo() ? GetAlgoCreationMethod() : GetCreationMethod( algo->GetAlgoType() ));
-  // set args
+  // set args (geom will be set by _pyMesh calling this method)
   theCmd->RemoveArgs();
-  for ( int i = 1; i <= myArgs.Length(); ++i ) {
-    if ( !myArgs( i ).IsEmpty() )
-      theCmd->SetArg( i, myArgs( i ));
+  for ( size_t i = 0; i < myCurCrMethod->myArgs.size(); ++i ) {
+    if ( !myCurCrMethod->myArgs[ i ].IsEmpty() )
+      theCmd->SetArg( i+1, myCurCrMethod->myArgs[ i ]);
     else
-      theCmd->SetArg( i, "[]");
+      theCmd->SetArg( i+1, "[]");
   }
   // set a new creation command
   GetCreationCmd()->Clear();
   // replace creation command by wrapped instance
   // please note, that hypothesis attaches to algo creation command (see upper)
   SetCreationCmd( theCmd );
-  
+
 
   // clear commands setting arg values
   list < Handle(_pyCommand) >::iterator argCmd = myArgCommands.begin();
@@ -1416,8 +2252,8 @@ bool _pyHypothesis::Addition2Creation( const Handle(_pyCommand)& theCmd,
 
   // set unknown arg commands after hypo creation
   Handle(_pyCommand) afterCmd = myIsWrapped ? theCmd : GetCreationCmd();
-  list<Handle(_pyCommand)>::iterator cmd = myUnknownCommands.begin();
-  for ( ; cmd != myUnknownCommands.end(); ++cmd ) {
+  list<Handle(_pyCommand)>::iterator cmd = myUnusedCommands.begin();
+  for ( ; cmd != myUnusedCommands.end(); ++cmd ) {
     afterCmd->AddDependantCmd( *cmd );
   }
 
@@ -1434,20 +2270,27 @@ bool _pyHypothesis::Addition2Creation( const Handle(_pyCommand)& theCmd,
 void _pyHypothesis::Process( const Handle(_pyCommand)& theCommand)
 {
   ASSERT( !myIsAlgo );
+  if ( !theGen->IsToKeepAllCommands() )
+    rememberCmdOfParameter( theCommand );
   // set args
-  int nbArgs = 0;
-  for ( int i = 1; i <= myArgMethods.Length(); ++i ) {
-    if ( myArgMethods( i ) == theCommand->GetMethod() ) {
-      while ( myArgs.Length() < nbArgs + myNbArgsByMethod( i ))
-        myArgs.Append( "[]" );
-      for ( int iArg = 1; iArg <= myNbArgsByMethod( i ); ++iArg )
-        myArgs( nbArgs + iArg ) = theCommand->GetArg( iArg ); // arg value
-      myArgCommands.push_back( theCommand );
-      return;
+  bool usedCommand = false;
+  TType2CrMethod::iterator type2meth = myAlgoType2CreationMethod.begin();
+  for ( ; type2meth != myAlgoType2CreationMethod.end(); ++type2meth )
+  {
+    CreationMethod& crMethod = type2meth->second;
+    for ( size_t i = 0; i < crMethod.myArgMethods.size(); ++i ) {
+      if ( crMethod.myArgMethods[ i ] == theCommand->GetMethod() ) {
+        if ( !usedCommand )
+          myArgCommands.push_back( theCommand );
+        usedCommand = true;
+        while ( crMethod.myArgs.size() < i+1 )
+          crMethod.myArgs.push_back( "[]" );
+        crMethod.myArgs[ i ] = theCommand->GetArg( crMethod.myArgNb[i] );
+      }
     }
-    nbArgs += myNbArgsByMethod( i );
   }
-  myUnknownCommands.push_back( theCommand );
+  if ( !usedCommand )
+    myUnusedCommands.push_back( theCommand );
 }
 
 //================================================================================
@@ -1458,9 +2301,8 @@ void _pyHypothesis::Process( const Handle(_pyCommand)& theCommand)
 
 void _pyHypothesis::Flush()
 {
-  if ( IsWrapped() ) {
-  }
-  else {
+  if ( !IsAlgo() )
+  {
     list < Handle(_pyCommand) >::iterator cmd = myArgCommands.begin();
     for ( ; cmd != myArgCommands.end(); ++cmd ) {
       // Add access to a wrapped mesh
@@ -1468,8 +2310,8 @@ void _pyHypothesis::Flush()
       // Add access to a wrapped algorithm
       theGen->AddAlgoAccessorMethod( *cmd );
     }
-    cmd = myUnknownCommands.begin();
-    for ( ; cmd != myUnknownCommands.end(); ++cmd ) {
+    cmd = myUnusedCommands.begin();
+    for ( ; cmd != myUnusedCommands.end(); ++cmd ) {
       // Add access to a wrapped mesh
       theGen->AddMeshAccessorMethod( *cmd );
       // Add access to a wrapped algorithm
@@ -1478,7 +2320,7 @@ void _pyHypothesis::Flush()
   }
   // forget previous hypothesis modifications
   myArgCommands.clear();
-  myUnknownCommands.clear();
+  myUnusedCommands.clear();
 }
 
 //================================================================================
@@ -1493,8 +2335,8 @@ void _pyHypothesis::ClearAllCommands()
   list<Handle(_pyCommand)>::iterator cmd = myArgCommands.begin();
   for ( ; cmd != myArgCommands.end(); ++cmd )
     ( *cmd )->Clear();
-  cmd = myUnknownCommands.begin();
-  for ( ; cmd != myUnknownCommands.end(); ++cmd )
+  cmd = myUnusedCommands.begin();
+  for ( ; cmd != myUnusedCommands.end(); ++cmd )
     ( *cmd )->Clear();
 }
 
@@ -1506,144 +2348,426 @@ void _pyHypothesis::ClearAllCommands()
 //================================================================================
 
 void _pyHypothesis::Assign( const Handle(_pyHypothesis)& theOther,
-                           const _pyID&                 theMesh )
+                            const _pyID&                 theMesh )
 {
-  myIsWrapped = false;
-  myMesh = theMesh;
-
   // myCreationCmd = theOther->myCreationCmd;
-  myIsAlgo = theOther->myIsAlgo;
-  myGeom = theOther->myGeom;
-  myType2CreationMethod = theOther->myType2CreationMethod;
-  myArgs = theOther->myArgs;
-  myArgMethods = theOther->myArgMethods;
-  myNbArgsByMethod = theOther->myNbArgsByMethod;
-  myArgCommands = theOther->myArgCommands;
-  myUnknownCommands = theOther->myUnknownCommands;
+  myIsAlgo                  = theOther->myIsAlgo;
+  myIsWrapped               = false;
+  myGeom                    = theOther->myGeom;
+  myMesh                    = theMesh;
+  myAlgoType2CreationMethod = theOther->myAlgoType2CreationMethod;
+  //myArgCommands             = theOther->myArgCommands;
+  //myUnusedCommands          = theOther->myUnusedCommands;
+  // init myCurCrMethod
+  GetCreationMethod( theOther->GetAlgoType() );
 }
 
 //================================================================================
 /*!
- * \brief Remember hypothesis parameter values
-  * \param theCommand - The called hypothesis method
+ * \brief Analyze my erasability depending on myReferredObjs
  */
 //================================================================================
 
-void _pyComplexParamHypo::Process( const Handle(_pyCommand)& theCommand)
+bool _pyHypothesis::CanClear()
 {
-  // ex: hyp.SetLength(start, 1)
-  //     hyp.SetLength(end,   0)
-  ASSERT(( theCommand->GetMethod() == "SetLength" ));
-  ASSERT(( theCommand->GetArg( 2 ).IsIntegerValue() ));
-  int i = 2 - theCommand->GetArg( 2 ).IntegerValue();
-  while ( myArgs.Length() < i )
-    myArgs.Append( "[]" );
-  myArgs( i ) = theCommand->GetArg( 1 ); // arg value
-  myArgCommands.push_back( theCommand );
+  if ( IsInStudy() )
+  {
+    list< Handle(_pyObject) >::iterator obj = myReferredObjs.begin();
+    for ( ; obj != myReferredObjs.end(); ++obj )
+      if ( (*obj)->CanClear() )
+        return true;
+    return false;
+  }
+  return true;
 }
 
 //================================================================================
 /*!
- * \brief Convert methods of 1D hypotheses to my own methods
-  * \param theCommand - The called hypothesis method
+ * \brief Clear my commands depending on usage by meshes
  */
 //================================================================================
 
-void _pyLayerDistributionHypo::Process( const Handle(_pyCommand)& theCommand)
+void _pyHypothesis::ClearCommands()
 {
-  if ( theCommand->GetMethod() != "SetLayerDistribution" )
-    return;
+  // if ( !theGen->IsToKeepAllCommands() )
+  // {
+  //   bool isUsed = false;
+  //   int lastComputeOrder = 0;
+  //   list<Handle(_pyCommand) >::iterator cmd = myComputeCmds.begin();
+  //   for ( ; cmd != myComputeCmds.end(); ++cmd )
+  //     if ( ! (*cmd)->IsEmpty() )
+  //     {
+  //       isUsed = true;
+  //       if ( (*cmd)->GetOrderNb() > lastComputeOrder )
+  //         lastComputeOrder = (*cmd)->GetOrderNb();
+  //     }
+  //   if ( !isUsed )
+  //   {
+  //     SetRemovedFromStudy( true );
+  //   }
+  //   else
+  //   {
+  //     // clear my commands invoked after lastComputeOrder
+  //     // map<TCollection_AsciiString, list< Handle(_pyCommand) > >::iterator m2c;
+  //     // for ( m2c = myMeth2Commands.begin(); m2c != myMeth2Commands.end(); ++m2c )
+  //     // {
+  //     //   list< Handle(_pyCommand)> & cmds = m2c->second;
+  //     //   if ( !cmds.empty() && cmds.back()->GetOrderNb() > lastComputeOrder )
+  //     //     cmds.back()->Clear();
+  //     // }
+  //   }
+  // }
+  _pyObject::ClearCommands();
+}
 
-  _pyID newName; // name for 1D hyp = "HypType" + "_Distribution"
+//================================================================================
+/*!
+ * \brief Find arguments that are objects like mesh, group, geometry
+ *  \param meshes - referred meshes (directly or indirrectly)
+ *  \retval bool - false if a referred geometry is not in the study
+ */
+//================================================================================
 
-  const _pyID& hyp1dID = theCommand->GetArg( 1 );
-  Handle(_pyHypothesis) hyp1d = theGen->FindHyp( hyp1dID );
-  if ( hyp1d.IsNull() ) // apparently hypId changed at study restoration
-    hyp1d = my1dHyp;
-  else if ( !my1dHyp.IsNull() && hyp1dID != my1dHyp->GetID() ) {
-    // 1D hypo is already set, so distribution changes and the old
-    // 1D hypo is thrown away
-    my1dHyp->ClearAllCommands();
-  }
-  my1dHyp = hyp1d;
-  if ( my1dHyp.IsNull() )
-    return; // something wrong :(
+bool _pyHypothesis::GetReferredMeshesAndGeom( list< Handle(_pyMesh) >& meshes )
+{
+  if ( IsAlgo() ) return true;
 
-  // make a new name for 1D hyp = "HypType" + "_Distribution"
-  if ( my1dHyp->GetCreationCmd()->GetMethod() == "CreateHypothesis" ) {
-    // not yet converted creation cmd
-    TCollection_AsciiString hypTypeQuoted = my1dHyp->GetCreationCmd()->GetArg(1);
-    TCollection_AsciiString hypType = hypTypeQuoted.SubString( 2, hypTypeQuoted.Length() - 1 );
-    newName = hypType + "_Distribution";
-    my1dHyp->GetCreationCmd()->SetResultValue( newName );
+  bool geomPublished = true;
+  vector< _AString > args;
+  TType2CrMethod::iterator type2meth = myAlgoType2CreationMethod.begin();
+  for ( ; type2meth != myAlgoType2CreationMethod.end(); ++type2meth )
+  {
+    CreationMethod& crMethod = type2meth->second;
+    args.insert( args.end(), crMethod.myArgs.begin(), crMethod.myArgs.end());
   }
-  else {
-    // already converted creation cmd
-    newName = my1dHyp->GetCreationCmd()->GetResultValue();
+  list<Handle(_pyCommand)>::iterator cmd = myUnusedCommands.begin();
+  for ( ; cmd != myUnusedCommands.end(); ++cmd ) {
+    for ( int nb = (*cmd)->GetNbArgs(); nb; --nb )
+      args.push_back( (*cmd)->GetArg( nb ));
   }
 
-  // as creation of 1D hyp was written later then it's edition,
-  // we need to find all it's edition calls and process them
-  list< Handle(_pyCommand) >& cmds = theGen->GetCommands();
-  list< Handle(_pyCommand) >::iterator cmdIt = cmds.begin();
-  for ( ; cmdIt != cmds.end(); ++cmdIt ) {
-    const _pyID& objID = (*cmdIt)->GetObject();
-    if ( objID == hyp1dID ) {
-      my1dHyp->Process( *cmdIt );
-      my1dHyp->GetCreationCmd()->AddDependantCmd( *cmdIt );
-      ( *cmdIt )->SetObject( newName );
-    }
-  }
-  if ( !myArgCommands.empty() )
-    myArgCommands.front()->Clear();
-  theCommand->SetArg( 1, newName );
-  myArgCommands.push_back( theCommand );
-  // copy hyp1d's creation method and args
-//   myCreationMethod = hyp1d->GetCreationMethod();
-//   myArgs           = hyp1d->GetArgs();
-//   // make them cleared at conversion
-//   myArgCommands = hyp1d->GetArgCommands();
-
-//   // to be cleared at convertion only
-//   myArgCommands.push_back( theCommand );
+  for ( size_t i = 0; i < args.size(); ++i )
+  {
+    list< _pyID > idList = _pyCommand::GetStudyEntries( args[ i ]);
+    if ( idList.empty() && !args[ i ].IsEmpty() )
+      idList.push_back( args[ i ]);
+    list< _pyID >::iterator id = idList.begin();
+    for ( ; id != idList.end(); ++id )
+    {
+      Handle(_pyObject)   obj = theGen->FindObject( *id );
+      if ( obj.IsNull() ) obj = theGen->FindHyp( *id );
+      if ( obj.IsNull() )
+      {
+        if ( theGen->IsGeomObject( *id ) && theGen->IsNotPublished( *id ))
+          geomPublished = false;
+      }
+      else
+      {
+        myReferredObjs.push_back( obj );
+        Handle(_pyMesh) mesh = ObjectToMesh( obj );
+        if ( !mesh.IsNull() )
+          meshes.push_back( mesh );
+        // prevent clearing not published hyps referred e.g. by "LayerDistribution"
+        else if ( obj->IsKind( STANDARD_TYPE( _pyHypothesis )) && this->IsInStudy() )
+          obj->SetRemovedFromStudy( false );
+      }
+    }
+  }
+  return geomPublished;
 }
 
 //================================================================================
 /*!
- * \brief 
-  * \param theAdditionCmd - command to be converted
-  * \param theMesh - mesh instance
-  * \retval bool - status
+ * \brief Remember theCommand setting a parameter
  */
 //================================================================================
 
-bool _pyLayerDistributionHypo::Addition2Creation( const Handle(_pyCommand)& theAdditionCmd,
-                                                  const _pyID&              theMesh)
+void _pyHypothesis::rememberCmdOfParameter( const Handle(_pyCommand) & theCommand )
 {
-  myIsWrapped = false;
+  // parameters are discriminated by method name
+  TCollection_AsciiString method = theCommand->GetMethod();
 
-  if ( my1dHyp.IsNull() )
-    return false;
+  // discriminate commands setting different parameters via one method
+  // by passing parameter names like e.g. SetOption("size", "0.2")
+  if ( theCommand->GetString().FirstLocationInSet( "'\"", 1, theCommand->Length() ) &&
+       theCommand->GetNbArgs() > 1 )
+  {
+    // mangle method by appending a 1st textual arg
+    for ( int iArg = 1; iArg <= theCommand->GetNbArgs(); ++iArg )
+    {
+      const TCollection_AsciiString& arg = theCommand->GetArg( iArg );
+      if ( arg.Value(1) != '\"' && arg.Value(1) != '\'' ) continue;
+      if ( !isalpha( arg.Value(2))) continue;
+      method += arg;
+      break;
+    }
+  }
+  // parameters are discriminated by method name
+  list< Handle(_pyCommand)>& cmds = myMeth2Commands[ theCommand->GetMethod() ];
+  if ( !cmds.empty() && !isCmdUsedForCompute( cmds.back() ))
+  {
+    cmds.back()->Clear(); // previous parameter value has not been used
+    cmds.back() = theCommand;
+  }
+  else
+  {
+    cmds.push_back( theCommand );
+  }
+}
 
-  // set "SetLayerDistribution()" after addition cmd
-  theAdditionCmd->AddDependantCmd( myArgCommands.front() );
+//================================================================================
+/*!
+ * \brief Return true if a setting parameter command ha been used to compute mesh
+ */
+//================================================================================
 
-  _pyID geom = theAdditionCmd->GetArg( 1 );
+bool _pyHypothesis::isCmdUsedForCompute( const Handle(_pyCommand) & cmd,
+                                         _pyCommand::TAddr          avoidComputeAddr ) const
+{
+  bool isUsed = false;
+  map< _pyCommand::TAddr, list<Handle(_pyCommand) > >::const_iterator addr2cmds =
+    myComputeAddr2Cmds.begin();
+  for ( ; addr2cmds != myComputeAddr2Cmds.end() && !isUsed; ++addr2cmds )
+  {
+    if ( addr2cmds->first == avoidComputeAddr ) continue;
+    const list<Handle(_pyCommand)> & cmds = addr2cmds->second;
+    isUsed = ( std::find( cmds.begin(), cmds.end(), cmd ) != cmds.end() );
+  }
+  return isUsed;
+}
+
+//================================================================================
+/*!
+ * \brief Save commands setting parameters as they are used for a mesh computation
+ */
+//================================================================================
+
+void _pyHypothesis::MeshComputed( const Handle(_pyCommand)& theComputeCmd )
+{
+  myComputeCmds.push_back( theComputeCmd );
+  list<Handle(_pyCommand)>& savedCmds = myComputeAddr2Cmds[ theComputeCmd->GetAddress() ];
+
+  map<TCollection_AsciiString, list< Handle(_pyCommand) > >::iterator m2c;
+  for ( m2c = myMeth2Commands.begin(); m2c != myMeth2Commands.end(); ++m2c )
+    savedCmds.push_back( m2c->second.back() );
+}
+
+//================================================================================
+/*!
+ * \brief Clear commands setting parameters as a mesh computed using them is cleared
+ */
+//================================================================================
+
+void _pyHypothesis::ComputeDiscarded( const Handle(_pyCommand)& theComputeCmd )
+{
+  list<Handle(_pyCommand)>& savedCmds = myComputeAddr2Cmds[ theComputeCmd->GetAddress() ];
+
+  list<Handle(_pyCommand)>::iterator cmd = savedCmds.begin();
+  for ( ; cmd != savedCmds.end(); ++cmd )
+  {
+    // check if a cmd has been used to compute another mesh
+    if ( isCmdUsedForCompute( *cmd, theComputeCmd->GetAddress() ))
+      continue;
+    // check if a cmd is a sole command setting its parameter;
+    // don't use method name for search as it can change
+    map<TCollection_AsciiString, list<Handle(_pyCommand)> >::iterator
+      m2cmds = myMeth2Commands.begin();
+    for ( ; m2cmds != myMeth2Commands.end(); ++m2cmds )
+    {
+      list< Handle(_pyCommand)>& cmds = m2cmds->second;
+      list< Handle(_pyCommand)>::iterator cmdIt = std::find( cmds.begin(), cmds.end(), *cmd );
+      if ( cmdIt != cmds.end() )
+      {
+        if ( cmds.back() != *cmd )
+        {
+          cmds.erase( cmdIt );
+          (*cmd)->Clear();
+        }
+        break;
+      }
+    }
+  }
+  myComputeAddr2Cmds.erase( theComputeCmd->GetAddress() );
+}
+
+//================================================================================
+/*!
+ * \brief Sets an argNb-th argument of current creation command
+ *  \param argNb - argument index countered from 1
+ */
+//================================================================================
+
+void _pyHypothesis::setCreationArg( const int argNb, const _AString& arg )
+{
+  if ( myCurCrMethod )
+  {
+    while ( myCurCrMethod->myArgs.size() < argNb )
+      myCurCrMethod->myArgs.push_back( "None" );
+    if ( arg.IsEmpty() )
+      myCurCrMethod->myArgs[ argNb-1 ] = "None";
+    else
+      myCurCrMethod->myArgs[ argNb-1 ] = arg;
+  }
+}
+
+
+//================================================================================
+/*!
+ * \brief Remember hypothesis parameter values
+ * \param theCommand - The called hypothesis method
+ */
+//================================================================================
+
+void _pyComplexParamHypo::Process( const Handle(_pyCommand)& theCommand)
+{
+  if ( GetAlgoType() == "Cartesian_3D" )
+  {
+    // CartesianParameters3D hyp
+
+    if ( theCommand->GetMethod() == "SetSizeThreshold" )
+    {
+      setCreationArg( 4, theCommand->GetArg( 1 ));
+      myArgCommands.push_back( theCommand );
+      return;
+    }
+    if ( theCommand->GetMethod() == "SetGrid" ||
+         theCommand->GetMethod() == "SetGridSpacing" )
+    {
+      TCollection_AsciiString axis = theCommand->GetArg( theCommand->GetNbArgs() );
+      int iArg = axis.Value(1) - '0';
+      if ( theCommand->GetMethod() == "SetGrid" )
+      {
+        setCreationArg( 1+iArg, theCommand->GetArg( 1 ));
+      }
+      else
+      {
+        myCurCrMethod->myArgs[ iArg ] = "[ ";
+        myCurCrMethod->myArgs[ iArg ] += theCommand->GetArg( 1 );
+        myCurCrMethod->myArgs[ iArg ] += ", ";
+        myCurCrMethod->myArgs[ iArg ] += theCommand->GetArg( 2 );
+        myCurCrMethod->myArgs[ iArg ] += "]";
+      }
+      myArgCommands.push_back( theCommand );
+      rememberCmdOfParameter( theCommand );
+      return;
+    }
+  }
+
+  if( theCommand->GetMethod() == "SetLength" )
+  {
+    // NOW it is OBSOLETE
+    // ex: hyp.SetLength(start, 1)
+    //     hyp.SetLength(end,   0)
+    ASSERT(( theCommand->GetArg( 2 ).IsIntegerValue() ));
+    int i = 1 - theCommand->GetArg( 2 ).IntegerValue();
+    TType2CrMethod::iterator type2meth = myAlgoType2CreationMethod.begin();
+    for ( ; type2meth != myAlgoType2CreationMethod.end(); ++type2meth )
+    {
+      CreationMethod& crMethod = type2meth->second;
+        while ( crMethod.myArgs.size() < i+1 )
+          crMethod.myArgs.push_back( "[]" );
+        crMethod.myArgs[ i ] = theCommand->GetArg( 1 ); // arg value
+    }
+    myArgCommands.push_back( theCommand );
+  }
+  else
+  {
+    _pyHypothesis::Process( theCommand );
+  }
+}
+//================================================================================
+/*!
+ * \brief Clear SetObjectEntry() as it is called by methods of Mesh_Segment
+ */
+//================================================================================
+
+void _pyComplexParamHypo::Flush()
+{
+  if ( IsWrapped() )
+  {
+    list < Handle(_pyCommand) >::iterator cmd = myUnusedCommands.begin();
+    for ( ; cmd != myUnusedCommands.end(); ++cmd )
+      if ((*cmd)->GetMethod() == "SetObjectEntry" )
+        (*cmd)->Clear();
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Convert methods of 1D hypotheses to my own methods
+  * \param theCommand - The called hypothesis method
+ */
+//================================================================================
+
+void _pyLayerDistributionHypo::Process( const Handle(_pyCommand)& theCommand)
+{
+  if ( theCommand->GetMethod() != "SetLayerDistribution" )
+    return;
+
+  const _pyID& hyp1dID = theCommand->GetArg( 1 );
+  // Handle(_pyHypothesis) hyp1d = theGen->FindHyp( hyp1dID );
+  // if ( hyp1d.IsNull() && ! my1dHyp.IsNull()) // apparently hypId changed at study restoration
+  // {
+  //   TCollection_AsciiString cmd =
+  //     my1dHyp->GetCreationCmd()->GetIndentation() + hyp1dID + " = " + my1dHyp->GetID();
+  //   Handle(_pyCommand) newCmd = theGen->AddCommand( cmd );
+  //   theGen->SetCommandAfter( newCmd, my1dHyp->GetCreationCmd() );
+  //   hyp1d = my1dHyp;
+  // }
+  // else if ( !my1dHyp.IsNull() && hyp1dID != my1dHyp->GetID() )
+  // {
+  //   // 1D hypo is already set, so distribution changes and the old
+  //   // 1D hypo is thrown away
+  //   my1dHyp->ClearAllCommands();
+  // }
+  // my1dHyp = hyp1d;
+  // //my1dHyp->SetRemovedFromStudy( false );
+
+  // if ( !myArgCommands.empty() )
+  //   myArgCommands.back()->Clear();
+  myCurCrMethod->myArgs.push_back( hyp1dID );
+  myArgCommands.push_back( theCommand );
+}
+
+//================================================================================
+/*!
+ * \brief
+  * \param theAdditionCmd - command to be converted
+  * \param theMesh - mesh instance
+  * \retval bool - status
+ */
+//================================================================================
 
-  my1dHyp->SetMesh( theMesh );
-  if ( !my1dHyp->Addition2Creation( theAdditionCmd, theMesh ))
+bool _pyLayerDistributionHypo::Addition2Creation( const Handle(_pyCommand)& theAdditionCmd,
+                                                  const _pyID&              theMesh)
+{
+  myIsWrapped = false;
+
+  if ( my1dHyp.IsNull() )
     return false;
 
-  // clear "SetLayerDistribution()" cmd
-  myArgCommands.front()->Clear();
+  // set "SetLayerDistribution()" after addition cmd
+  theAdditionCmd->AddDependantCmd( myArgCommands.front() );
 
-  // Convert my creation => me = RadialPrismAlgo.Get3DHypothesis()
+  _pyID geom = theAdditionCmd->GetArg( 1 );
 
-  // find RadialPrism algo created on <geom> for theMesh
   Handle(_pyHypothesis) algo = theGen->FindAlgo( geom, theMesh, this );
-  if ( !algo.IsNull() ) {
+  if ( !algo.IsNull() )
+  {
+    my1dHyp->SetMesh( theMesh );
+    my1dHyp->SetConvMethodAndType(my1dHyp->GetAlgoCreationMethod().ToCString(),
+                                  algo->GetAlgoType().ToCString());
+    if ( !my1dHyp->Addition2Creation( theAdditionCmd, theMesh ))
+      return false;
+
+    // clear "SetLayerDistribution()" cmd
+    myArgCommands.back()->Clear();
+
+    // Convert my creation => me = RadialPrismAlgo.Get3DHypothesis()
+
+    // find RadialPrism algo created on <geom> for theMesh
     GetCreationCmd()->SetObject( algo->GetID() );
-    GetCreationCmd()->SetMethod( "Get3DHypothesis" );
+    GetCreationCmd()->SetMethod( myAlgoMethod );
     GetCreationCmd()->RemoveArgs();
     theAdditionCmd->AddDependantCmd( GetCreationCmd() );
     myIsWrapped = true;
@@ -1653,14 +2777,60 @@ bool _pyLayerDistributionHypo::Addition2Creation( const Handle(_pyCommand)& theA
 
 //================================================================================
 /*!
- * \brief 
+ * \brief
  */
 //================================================================================
 
 void _pyLayerDistributionHypo::Flush()
 {
-  //my1dHyp.Nullify();
-  //_pyHypothesis::Flush();
+  // as creation of 1D hyp was written later then it's edition,
+  // we need to find all it's edition calls and process them
+  list< Handle(_pyCommand) >::iterator cmd = myArgCommands.begin();
+  _pyID prevNewName;
+  for ( cmd = myArgCommands.begin(); cmd != myArgCommands.end(); ++cmd )
+  {    
+    const _pyID& hyp1dID = (*cmd)->GetArg( 1 );
+    if ( hyp1dID.IsEmpty() ) continue;
+
+    Handle(_pyHypothesis) hyp1d = theGen->FindHyp( hyp1dID );
+
+    // make a new name for 1D hyp = "HypType" + "_Distribution"
+    _pyID newName;
+    if ( hyp1d.IsNull() ) // apparently hypId changed at study restoration
+    {
+      if ( prevNewName.IsEmpty() ) continue;
+      newName = prevNewName;
+    }
+    else
+    {
+      if ( hyp1d->IsWrapped() ) {
+        newName = hyp1d->GetCreationCmd()->GetMethod();
+      }
+      else {
+        TCollection_AsciiString hypTypeQuoted = hyp1d->GetCreationCmd()->GetArg(1);
+        newName = hypTypeQuoted.SubString( 2, hypTypeQuoted.Length() - 1 );
+      }
+      newName += "_Distribution";
+      prevNewName = newName;
+    
+      hyp1d->GetCreationCmd()->SetResultValue( newName );
+    }
+    list< Handle(_pyCommand) >& cmds = theGen->GetCommands();
+    list< Handle(_pyCommand) >::iterator cmdIt = cmds.begin();
+    for ( ; cmdIt != cmds.end(); ++cmdIt ) {
+      const _pyID& objID = (*cmdIt)->GetObject();
+      if ( objID == hyp1dID ) {
+        if ( !hyp1d.IsNull() )
+        {
+          hyp1d->Process( *cmdIt );
+          hyp1d->GetCreationCmd()->AddDependantCmd( *cmdIt );
+        }
+        ( *cmdIt )->SetObject( newName );
+      }
+    }
+    // Set new hyp name to SetLayerDistribution(hyp1dID) cmd
+    (*cmd)->SetArg( 1, newName );
+  }
 }
 
 //================================================================================
@@ -1675,11 +2845,11 @@ void _pyLayerDistributionHypo::Flush()
 bool _pyNumberOfSegmentsHyp::Addition2Creation( const Handle(_pyCommand)& theCmd,
                                                 const _pyID&              theMesh)
 {
-  if ( IsWrappable( theMesh ) && myArgs.Length() > 1 ) {
+  if ( IsWrappable( theMesh ) && myCurCrMethod->myArgs.size() > 1 ) {
     // scale factor (2-nd arg) is provided: clear SetDistrType(1) command
     bool scaleDistrType = false;
-    list<Handle(_pyCommand)>::reverse_iterator cmd = myUnknownCommands.rbegin();
-    for ( ; cmd != myUnknownCommands.rend(); ++cmd ) {
+    list<Handle(_pyCommand)>::reverse_iterator cmd = myUnusedCommands.rbegin();
+    for ( ; cmd != myUnusedCommands.rend(); ++cmd ) {
       if ( (*cmd)->GetMethod() == "SetDistrType" ) {
         if ( (*cmd)->GetArg( 1 ) == "1" ) {
           scaleDistrType = true;
@@ -1687,7 +2857,13 @@ bool _pyNumberOfSegmentsHyp::Addition2Creation( const Handle(_pyCommand)& theCmd
         }
         else if ( !scaleDistrType ) {
           // distribution type changed: remove scale factor from args
-          myArgs.Remove( 2, myArgs.Length() );
+          TType2CrMethod::iterator type2meth = myAlgoType2CreationMethod.begin();
+          for ( ; type2meth != myAlgoType2CreationMethod.end(); ++type2meth )
+          {
+            CreationMethod& crMethod = type2meth->second;
+            if ( crMethod.myArgs.size() == 2 )
+              crMethod.myArgs.pop_back();
+          }
           break;
         }
       }
@@ -1705,14 +2881,16 @@ bool _pyNumberOfSegmentsHyp::Addition2Creation( const Handle(_pyCommand)& theCmd
 void _pyNumberOfSegmentsHyp::Flush()
 {
   // find number of the last SetDistrType() command
-  list<Handle(_pyCommand)>::reverse_iterator cmd = myUnknownCommands.rbegin();
+  list<Handle(_pyCommand)>::reverse_iterator cmd = myUnusedCommands.rbegin();
   int distrTypeNb = 0;
-  for ( ; !distrTypeNb && cmd != myUnknownCommands.rend(); ++cmd )
+  for ( ; !distrTypeNb && cmd != myUnusedCommands.rend(); ++cmd )
     if ( (*cmd)->GetMethod() == "SetDistrType" )
       distrTypeNb = (*cmd)->GetOrderNb();
+    else if (IsWrapped() && (*cmd)->GetMethod() == "SetObjectEntry" )
+      (*cmd)->Clear();
 
   // clear commands before the last SetDistrType()
-  list<Handle(_pyCommand)> * cmds[2] = { &myArgCommands, &myUnknownCommands };
+  list<Handle(_pyCommand)> * cmds[2] = { &myArgCommands, &myUnusedCommands };
   for ( int i = 0; i < 2; ++i ) {
     set<TCollection_AsciiString> uniqueMethods;
     list<Handle(_pyCommand)> & cmdList = *cmds[i];
@@ -1740,7 +2918,7 @@ void _pyNumberOfSegmentsHyp::Flush()
   * \retval bool - false if the command cant be converted
  */
 //================================================================================
-  
+
 bool _pySegmentLengthAroundVertexHyp::Addition2Creation( const Handle(_pyCommand)& theCmd,
                                                          const _pyID&              theMeshID)
 {
@@ -1764,8 +2942,8 @@ bool _pySegmentLengthAroundVertexHyp::Addition2Creation( const Handle(_pyCommand
     theCmd->SetArg( 1, geom );
 
     // set vertex as a second arg
-    if ( myArgs.Length() < 1) myArgs.Append( "1" ); // :(
-    myArgs.Append( vertex );
+    if ( myCurCrMethod->myArgs.size() < 1) setCreationArg( 1, "1" ); // :(
+    setCreationArg( 2, vertex );
 
     // mesh.AddHypothesis(vertex, SegmentLengthAroundVertex) -->
     // theMeshID.LengthNearVertex( length, vertex )
@@ -1791,11 +2969,11 @@ _pyAlgorithm::_pyAlgorithm(const Handle(_pyCommand)& theCreationCmd)
 /*!
  * \brief Convert the command adding an algorithm to mesh
   * \param theCmd - The command like mesh.AddHypothesis( geom, algo )
-  * \param theMesh - The mesh needing this algo 
+  * \param theMesh - The mesh needing this algo
   * \retval bool - false if the command cant be converted
  */
 //================================================================================
-  
+
 bool _pyAlgorithm::Addition2Creation( const Handle(_pyCommand)& theCmd,
                                       const _pyID&              theMeshID)
 {
@@ -1867,12 +3045,20 @@ const TCollection_AsciiString & _pyCommand::GetResultValue()
 {
   if ( GetBegPos( RESULT_IND ) == UNKNOWN )
   {
-    int begPos = myString.Location( "=", 1, Length() );
-    if ( begPos )
-      myRes = GetWord( myString, begPos, false );
-    else
-      begPos = EMPTY;
-    SetBegPos( RESULT_IND, begPos );
+    SetBegPos( RESULT_IND, EMPTY );
+    int begPos, endPos = myString.Location( "=", 1, Length() );
+    if ( endPos )
+    {
+      begPos = 1;
+      while ( begPos < endPos && isspace( myString.Value( begPos ))) ++begPos;
+      if ( begPos < endPos )
+      {
+        SetBegPos( RESULT_IND, begPos );
+        --endPos;
+        while ( begPos < endPos && isspace( myString.Value( endPos ))) --endPos;
+        myRes = myString.SubString( begPos, endPos );
+      }
+    }
   }
   return myRes;
 }
@@ -1902,22 +3088,25 @@ const int _pyCommand::GetNbResultValues()
 //================================================================================
 /*!
  * \brief Return substring of python command looking like
- *  ResultValue1 , ResultValue1,... = Obj.Meth() with res index
+ *  ResultValue1 , ResultValue2,... = Obj.Meth() with res index
  * \retval const TCollection_AsciiString & - ResultValue with res index substring
  */
 //================================================================================
-const TCollection_AsciiString & _pyCommand::GetResultValue(int res)
+TCollection_AsciiString _pyCommand::GetResultValue(int res)
 {
   int begPos = 1;
-  int Nb=0;
+  if ( SkipSpaces( myString, begPos ) && myString.Value( begPos ) == '[' )
+    ++begPos; // skip [, else the whole list is returned
   int endPos = myString.Location( "=", 1, Length() );
+  int Nb=0;
   while ( begPos < endPos) {
-    myRes = GetWord( myString, begPos, true );
-    begPos = begPos + myRes.Length();
+    _AString result = GetWord( myString, begPos, true );
+    begPos = begPos + result.Length();
     Nb++;
-    if(res == Nb){
-      myRes.RemoveAll('[');myRes.RemoveAll(']');
-      return myRes;
+    if(res == Nb) {
+      result.RemoveAll('[');
+      result.RemoveAll(']');
+      return result;
     }
     if(Nb>res)
       break;
@@ -1944,18 +3133,38 @@ const TCollection_AsciiString & _pyCommand::GetObject()
       int nb1 = 0; // number of ' character at the left of =
       int nb2 = 0; // number of " character at the left of =
       for ( int i = 1; i < begPos-1; i++ ) {
-       if ( IsEqual(myString.Value( i ), "'" ) )
-         nb1 += 1;
-       else if ( IsEqual( myString.Value( i ), '"' ) )
-         nb2 += 1;
+        if ( myString.Value( i )=='\'' )
+          nb1 += 1;
+        else if ( myString.Value( i )=='"' )
+          nb2 += 1;
       }
       // if number of ' or " is not divisible by 2,
       // then get an object at the start of the command
       if ( nb1 % 2 != 0 || nb2 % 2 != 0 )
-       begPos = 1;
+        begPos = 1;
     }
-    // store
     myObj = GetWord( myString, begPos, true );
+    // check if object is complex,
+    // so far consider case like "smesh.smesh.Method()"
+    if ( int bracketPos = myString.Location( "(", begPos, Length() )) {
+      //if ( bracketPos==0 ) bracketPos = Length();
+      int dotPos = begPos+myObj.Length();
+      while ( dotPos+1 < bracketPos ) {
+        if ( int pos = myString.Location( ".", dotPos+1, bracketPos ))
+          dotPos = pos;
+        else
+          break;
+      }
+      if ( dotPos > begPos+myObj.Length() )
+        myObj = myString.SubString( begPos, dotPos-1 );
+    }
+    // 1st word after '=' is an object
+    // else // no method -> no object
+    // {
+    //   myObj.Clear();
+    //   begPos = EMPTY;
+    // }
+    // store
     SetBegPos( OBJECT_IND, begPos );
   }
   //SCRUTE(myObj);
@@ -1999,32 +3208,71 @@ const TCollection_AsciiString & _pyCommand::GetArg( int index )
 {
   if ( GetBegPos( ARG1_IND ) == UNKNOWN )
   {
-    // find all args
-    int begPos = GetBegPos( METHOD_IND ) + myMeth.Length();
-    if ( begPos < 1 )
-      begPos = myString.Location( "(", 1, Length() ) + 1;
-
-    int i = 0, prevLen = 0, nbNestings = 0;
-    while ( begPos != EMPTY ) {
-      begPos += prevLen;
-      if( myString.Value( begPos ) == '(' )
-       nbNestings++;
-      // check if we are looking at the closing parenthesis
-      while ( begPos <= Length() && isspace( myString.Value( begPos )))
-        ++begPos;
-      if ( begPos > Length() )
-        break;
-      if ( myString.Value( begPos ) == ')' ) {
-       nbNestings--;
-       if( nbNestings == 0 )
-         break;
+    // Find all args
+
+    int pos = GetBegPos( METHOD_IND ) + myMeth.Length();
+    if ( pos < 1 )
+      pos = myString.Location( "(", 1, Length() );
+    else
+      --pos;
+
+    // we are at or before '(', skip it if present
+    if ( pos > 0 ) {
+      while ( pos <= Length() && myString.Value( pos ) != '(' ) ++pos;
+      if ( pos > Length() )
+        pos = 0;
+    }
+    if ( pos < 1 ) {
+      SetBegPos( ARG1_IND, 0 ); // even no '('
+      return theEmptyString;
+    }
+    ++pos;
+
+    list< TCollection_AsciiString > separatorStack( 1, ",)");
+    bool ignoreNesting = false;
+    int prevPos = pos;
+    while ( pos <= Length() )
+    {
+      const char chr = myString.Value( pos );
+
+      if ( separatorStack.back().Location( chr, 1, separatorStack.back().Length()))
+      {
+        if ( separatorStack.size() == 1 ) // a comma dividing args or a terminal ')' found
+        {
+          while ( pos-1 >= prevPos && isspace( myString.Value( prevPos )))
+            ++prevPos;
+          TCollection_AsciiString arg;
+          if ( pos-1 >= prevPos ) {
+            arg = myString.SubString( prevPos, pos-1 );
+            arg.RightAdjust(); // remove spaces
+            arg.LeftAdjust();
+          }
+          if ( !arg.IsEmpty() || chr == ',' )
+          {
+            SetBegPos( ARG1_IND + myArgs.Length(), prevPos );
+            myArgs.Append( arg );
+          }
+          if ( chr == ')' )
+            break;
+          prevPos = pos+1;
+        }
+        else // end of nesting args found
+        {
+          separatorStack.pop_back();
+          ignoreNesting = false;
+        }
       }
-      myArgs.Append( GetWord( myString, begPos, true, true ));
-      SetBegPos( ARG1_IND + i, begPos );
-      prevLen = myArgs.Last().Length();
-      if ( prevLen == 0 )
-        myArgs.Remove( myArgs.Length() ); // no more args
-      i++;
+      else if ( !ignoreNesting )
+      {
+        switch ( chr ) {
+        case '(' : separatorStack.push_back(")"); break;
+        case '[' : separatorStack.push_back("]"); break;
+        case '\'': separatorStack.push_back("'");  ignoreNesting=true; break;
+        case '"' : separatorStack.push_back("\""); ignoreNesting=true; break;
+        default:;
+        }
+      }
+      ++pos;
     }
   }
   if ( myArgs.Length() < index )
@@ -2074,9 +3322,19 @@ TCollection_AsciiString _pyCommand::GetWord( const TCollection_AsciiString & the
       return theEmptyString; // no word found
     // end
     end = beg + 1;
-    while ( end <= theString.Length() && isWord( theString.Value( end ), dotIsWord))
-      ++end;
-    --end;
+    char begChar = theString.Value( beg );
+    if ( begChar == '"' || begChar == '\'' || begChar == '[') {
+      char endChar = ( begChar == '[' ) ? ']' : begChar;
+      // end is at the corresponding quoting mark or bracket
+      while ( end < theString.Length() &&
+              ( theString.Value( end ) != endChar || theString.Value( end-1 ) == '\\'))
+        ++end;
+    }
+    else {
+      while ( end <= theString.Length() && isWord( theString.Value( end ), dotIsWord))
+        ++end;
+      --end;
+    }
   }
   else {  // search backward
     // end
@@ -2085,23 +3343,77 @@ TCollection_AsciiString _pyCommand::GetWord( const TCollection_AsciiString & the
     if ( end == 0 )
       return theEmptyString; // no word found
     beg = end - 1;
-    while ( beg > 0 && isWord( theString.Value( beg ), dotIsWord))
-      --beg;
-    ++beg;
+    char endChar = theString.Value( end );
+    if ( endChar == '"' || endChar == '\'' || endChar == ']') {
+      char begChar = ( endChar == ']' ) ? '[' : endChar;
+      // beg is at the corresponding quoting mark
+      while ( beg > 1 &&
+              ( theString.Value( beg ) != begChar || theString.Value( beg-1 ) == '\\'))
+        --beg;
+    }
+    else {
+      while ( beg > 0 && isWord( theString.Value( beg ), dotIsWord))
+        --beg;
+      ++beg;
+    }
   }
   theStartPos = beg;
   //cout << theString << " ---- " << beg << " - " << end << endl;
   return theString.SubString( beg, end );
 }
 
+//================================================================================
+/*!
+ * \brief Returns true if the string looks like a study entry
+ */
+//================================================================================
+
+bool _pyCommand::IsStudyEntry( const TCollection_AsciiString& str )
+{
+  if ( str.Length() < 5 ) return false;
+
+  int nbColons = 0, isColon;
+  for ( int i = 1; i <= str.Length(); ++i )
+  {
+    char c = str.Value(i);
+    if (!( isColon = (c == ':')) && ( c < '0' || c > '9' ))
+      return false;
+    nbColons += isColon;
+  }
+  return nbColons > 2 && str.Length()-nbColons > 2;
+}
+
+//================================================================================
+/*!
+ * \brief Finds entries in a sting
+ */
+//================================================================================
+
+std::list< _pyID > _pyCommand::GetStudyEntries( const TCollection_AsciiString& str )
+{
+  std::list< _pyID > resList;
+  int pos = 0;
+  while ( ++pos <= str.Length() )
+  {
+    if ( !isdigit( str.Value( pos ))) continue;
+    if ( pos != 1 && ( isalpha( str.Value( pos-1 ) || str.Value( pos-1 ) == ':'))) continue;
+
+    int end = pos;
+    while ( ++end <= str.Length() && ( isdigit( str.Value( end )) || str.Value( end ) == ':' ));
+    _pyID entry = str.SubString( pos, end-1 );
+    pos = end;
+    if ( IsStudyEntry( entry ))
+      resList.push_back( entry );
+  }
+  return resList;
+}
+
 //================================================================================
 /*!
  * \brief Look for position where not space char is
-  * \param theString - The string 
+  * \param theString - The string
   * \param thePos - The position to search from and which returns result
   * \retval bool - false if there are only space after thePos in theString
- * 
- * 
  */
 //================================================================================
 
@@ -2141,7 +3453,7 @@ void _pyCommand::SetPart(int thePartIndex, const TCollection_AsciiString& thePar
       case METHOD_IND: seperator = "()"; break;
       default:;
       }
-    }      
+    }
     myString.Remove( pos, theOldPart.Length() );
     if ( !seperator.IsEmpty() )
       myString.Insert( pos , seperator );
@@ -2215,6 +3527,30 @@ void _pyCommand::RemoveArgs()
     myBegPos.Remove( ARG1_IND, myBegPos.Length() );
 }
 
+//================================================================================
+/*!
+ * \brief Comment a python command
+ */
+//================================================================================
+
+void _pyCommand::Comment()
+{
+  if ( IsEmpty() ) return;
+
+  int i = 1;
+  while ( i <= Length() && isspace( myString.Value(i) )) ++i;
+  if ( i <= Length() )
+  {
+    myString.Insert( i, "#" );
+    for ( int iPart = 0; iPart < myBegPos.Length(); ++iPart )
+    {
+      int begPos = GetBegPos( iPart );
+      if ( begPos != UNKNOWN )
+        SetBegPos( iPart, begPos + 1 );
+    }
+  }
+}
+
 //================================================================================
 /*!
  * \brief Set dependent commands after this one
@@ -2280,6 +3616,49 @@ bool _pyCommand::AddAccessorMethod( _pyID theObjectID, const char* theAcsMethod
   return added;
 }
 
+//================================================================================
+/*!
+ * \brief Creates pyObject
+ */
+//================================================================================
+
+_pyObject::_pyObject(const Handle(_pyCommand)& theCreationCmd, const _pyID& theID)
+  : myID(theID), myCreationCmd(theCreationCmd), myIsPublished(false)
+{
+  setID( theID );
+}
+
+//================================================================================
+/*!
+ * \brief Set up myID and myIsPublished
+ */
+//================================================================================
+
+void _pyObject::setID(const _pyID& theID)
+{
+  myID = theID;
+  myIsPublished = !theGen->IsNotPublished( GetID() );
+}
+
+//================================================================================
+/*!
+ * \brief Clear myCreationCmd and myProcessedCmds
+ */
+//================================================================================
+
+void _pyObject::ClearCommands()
+{
+  if ( !CanClear() )
+    return;
+
+  if ( !myCreationCmd.IsNull() )
+    myCreationCmd->Clear();
+
+  list< Handle(_pyCommand) >::iterator cmd = myProcessedCmds.begin();
+  for ( ; cmd != myProcessedCmds.end(); ++cmd )
+    (*cmd)->Clear();
+}
+
 //================================================================================
 /*!
  * \brief Return method name giving access to an interaface object wrapped by python class
@@ -2307,14 +3686,69 @@ _pyID _pyObject::FatherID(const _pyID & childID)
 
 //================================================================================
 /*!
- * \brief FilterManager creates only if at least one command invoked
+ * \brief SelfEraser erases creation command if no more it's commands invoked
  */
 //================================================================================
 
-_pyFilterManager::_pyFilterManager(const Handle(_pyCommand)& theCreationCmd):
-  _pyObject( theCreationCmd ),
-  myCmdCount( 0 )
+void _pySelfEraser::Flush()
 {
+  if ( GetNbCalls() == 0 )
+    GetCreationCmd()->Clear();
+}
+
+//================================================================================
+/*!
+ * \brief _pySubMesh constructor
+ */
+//================================================================================
+
+_pySubMesh::_pySubMesh(const Handle(_pyCommand)& theCreationCmd):
+  _pyObject(theCreationCmd)
+{
+  myMesh = ObjectToMesh( theGen->FindObject( theCreationCmd->GetObject() ));
+}
+
+//================================================================================
+/*!
+ * \brief Return true if a sub-mesh can be used as argument of the given method
+ */
+//================================================================================
+
+bool _pySubMesh::CanBeArgOfMethod(const _AString& theMethodName)
+{
+  // names of all methods where a sub-mesh can be used as argument
+  static TStringSet methods;
+  if ( methods.empty() ) {
+    const char * names[] = {
+      // methods of SMESH_Gen
+      "CopyMesh",
+      // methods of SMESH_Group
+      "AddFrom",
+      // methods of SMESH_Measurements
+      "MinDistance",
+      // methods of SMESH_Mesh
+      "ExportPartToMED","ExportCGNS","ExportPartToDAT","ExportPartToUNV","ExportPartToSTL",
+      "RemoveSubMesh",
+      // methods of SMESH_MeshEditor
+      "ReorientObject","Reorient2D","TriToQuadObject","QuadToTriObject","SplitQuadObject",
+      "SplitVolumesIntoTetra","SmoothObject","SmoothParametricObject","ConvertFromQuadraticObject",
+      "RotationSweepObject","RotationSweepObjectMakeGroups","RotationSweepObject1D",
+      "RotationSweepObject1DMakeGroups","RotationSweepObject2D","RotationSweepObject2DMakeGroups",
+      "ExtrusionSweepObject","ExtrusionSweepObjectMakeGroups","ExtrusionSweepObject0D",
+      "ExtrusionSweepObject0DMakeGroups","ExtrusionSweepObject1D","ExtrusionSweepObject2D",
+      "ExtrusionSweepObject1DMakeGroups","ExtrusionSweepObject2DMakeGroups",
+      "ExtrusionAlongPathObjX","ExtrusionAlongPathObject","ExtrusionAlongPathObjectMakeGroups",
+      "ExtrusionAlongPathObject1D","ExtrusionAlongPathObject1DMakeGroups",
+      "ExtrusionAlongPathObject2D","ExtrusionAlongPathObject2DMakeGroups","MirrorObject",
+      "MirrorObjectMakeGroups","MirrorObjectMakeMesh","TranslateObject","Scale",
+      "TranslateObjectMakeGroups","TranslateObjectMakeMesh","ScaleMakeGroups","ScaleMakeMesh",
+      "RotateObject","RotateObjectMakeGroups","RotateObjectMakeMesh","FindCoincidentNodesOnPart",
+      "FindCoincidentNodesOnPartBut","FindEqualElements","FindAmongElementsByPoint",
+      "MakeBoundaryMesh",
+      "" }; // <- mark of end
+    methods.Insert( names );
+  }
+  return methods.Contains( theMethodName );
 }
 
 //================================================================================
@@ -2323,59 +3757,452 @@ _pyFilterManager::_pyFilterManager(const Handle(_pyCommand)& theCreationCmd):
  */
 //================================================================================
 
-void _pyFilterManager::Process( const Handle(_pyCommand)& /*theCommand*/)
+void _pySubMesh::Process( const Handle(_pyCommand)& theCommand )
+{
+  _pyObject::Process(theCommand); // count calls of Process()
+  GetCreationCmd()->AddDependantCmd( theCommand );
+}
+
+//================================================================================
+/*!
+ * \brief Move creation command depending on invoked commands
+ */
+//================================================================================
+
+void _pySubMesh::Flush()
+{
+  if ( GetNbCalls() == 0 ) // move to the end of all commands
+    theGen->GetLastCommand()->AddDependantCmd( GetCreationCmd() );
+  else if ( !myCreator.IsNull() )
+    // move to be just after creator
+    myCreator->GetCreationCmd()->AddDependantCmd( GetCreationCmd() );
+}
+
+//================================================================================
+/*!
+ * \brief Creates _pyGroup
+ */
+//================================================================================
+
+_pyGroup::_pyGroup(const Handle(_pyCommand)& theCreationCmd, const _pyID & id)
+  :_pySubMesh(theCreationCmd)
 {
-  myCmdCount++;
+  if ( !id.IsEmpty() )
+    setID( id );
+
+  myCanClearCreationCmd = true;
+
+  const _AString& method = theCreationCmd->GetMethod();
+  if ( method == "CreateGroup" ) // CreateGroup() --> CreateEmptyGroup()
+  {
+    theCreationCmd->SetMethod( "CreateEmptyGroup" );
+  }
+  // ----------------------------------------------------------------------
+  else if ( method == "CreateGroupFromGEOM" ) // (type, name, grp)
+  {
+    _pyID geom = theCreationCmd->GetArg( 3 );
+    // VSR 24/12/2010. PAL21106: always use GroupOnGeom() function on dump
+    // next if(){...} section is commented
+    //if ( sameGroupType( geom, theCreationCmd->GetArg( 1 )) ) { // --> Group(geom)
+    //  theCreationCmd->SetMethod( "Group" );
+    //  theCreationCmd->RemoveArgs();
+    //  theCreationCmd->SetArg( 1, geom );
+    //}
+    //else {
+    // ------------------------->>>>> GroupOnGeom( geom, name, typ )
+      _pyID type = theCreationCmd->GetArg( 1 );
+      _pyID name = theCreationCmd->GetArg( 2 );
+      theCreationCmd->SetMethod( "GroupOnGeom" );
+      theCreationCmd->RemoveArgs();
+      theCreationCmd->SetArg( 1, geom );
+      theCreationCmd->SetArg( 2, name );
+      theCreationCmd->SetArg( 3, type );
+    //}
+  }
+  else if ( method == "CreateGroupFromFilter" )
+  {
+    // -> GroupOnFilter(typ, name, aFilter0x4743dc0 -> aFilter_1)
+    theCreationCmd->SetMethod( "GroupOnFilter" );
+
+    _pyID filterID = theCreationCmd->GetArg(3);
+    Handle(_pyFilter) filter = Handle(_pyFilter)::DownCast( theGen->FindObject( filterID ));
+    if ( !filter.IsNull())
+    {
+      if ( !filter->GetNewID().IsEmpty() )
+        theCreationCmd->SetArg( 3, filter->GetNewID() );
+      filter->AddUser( this );
+    }
+    myFilter = filter;
+  }
+  else
+  {
+    // theCreationCmd does something else apart from creation of this group
+    // and thus it can't be cleared if this group is removed
+    myCanClearCreationCmd = false;
+  }
 }
 
 //================================================================================
 /*!
- * \brief Clear creatin command if no commands invoked
+ * \brief To convert creation of a group by filter
  */
 //================================================================================
 
-void _pyFilterManager::Flush()
+void _pyGroup::Process( const Handle(_pyCommand)& theCommand)
 {
-  if ( !myCmdCount )
+  // Convert the following set of commands into mesh.MakeGroupByFilter(groupName, theFilter)
+  // group = mesh.CreateEmptyGroup( elemType, groupName )
+  // aFilter.SetMesh(mesh)
+  // nbAdd = group.AddFrom( aFilter )
+  Handle(_pyFilter) filter;
+  if ( theCommand->GetMethod() == "AddFrom" )
+  {
+    _pyID idSource = theCommand->GetArg(1);
+    // check if idSource is a filter
+    filter = Handle(_pyFilter)::DownCast( theGen->FindObject( idSource ));
+    if ( !filter.IsNull() )
+    {
+      // find aFilter.SetMesh(mesh) to clear it, it should be just before theCommand
+      list< Handle(_pyCommand) >::reverse_iterator cmdIt = theGen->GetCommands().rbegin();
+      while ( *cmdIt != theCommand ) ++cmdIt;
+      while ( (*cmdIt)->GetOrderNb() != 1 )
+      {
+        const Handle(_pyCommand)& setMeshCmd = *(++cmdIt);
+        if ((setMeshCmd->GetObject() == idSource ||
+             setMeshCmd->GetObject() == filter->GetNewID() )
+            &&
+            setMeshCmd->GetMethod() == "SetMesh")
+        {
+          setMeshCmd->Clear();
+          break;
+        }
+      }
+      // replace 3 commands by one
+      theCommand->Clear();
+      const Handle(_pyCommand)& makeGroupCmd = GetCreationCmd();
+      TCollection_AsciiString name = makeGroupCmd->GetArg( 2 );
+      if ( !filter->GetNewID().IsEmpty() )
+        idSource = filter->GetNewID();
+      makeGroupCmd->SetMethod( "MakeGroupByFilter" );
+      makeGroupCmd->SetArg( 1, name );
+      makeGroupCmd->SetArg( 2, idSource );
+    }
+  }
+  else if ( theCommand->GetMethod() == "SetFilter" )
+  {
+    // set new name of a filter or clear the command if the same filter is set
+    _pyID filterID = theCommand->GetArg(1);
+    filter = Handle(_pyFilter)::DownCast( theGen->FindObject( filterID ));
+    if ( !myFilter.IsNull() && filter == myFilter )
+      theCommand->Clear();
+    else if ( !filter.IsNull() && !filter->GetNewID().IsEmpty() )
+      theCommand->SetArg( 1, filter->GetNewID() );
+    myFilter = filter;
+  }
+  else if ( theCommand->GetMethod() == "GetFilter" )
+  {
+    // GetFilter() returns a filter with other ID, make myFilter process
+    // calls of the returned filter
+    if ( !myFilter.IsNull() )
+    {
+      theGen->SetProxyObject( theCommand->GetResultValue(), myFilter );
+      theCommand->Clear();
+    }
+  }
+
+  if ( !filter.IsNull() )
+    filter->AddUser( this );
+
+  theGen->AddMeshAccessorMethod( theCommand );
+}
+
+//================================================================================
+/*!
+ * \brief Prevent clearing "DoubleNode...() command if a group created by it is removed
+ * 
+ * 
+ */
+//================================================================================
+
+void _pyGroup::Flush()
+{
+  if ( !theGen->IsToKeepAllCommands() &&
+       myCreationCmd && !myCanClearCreationCmd )
+  {
+    myCreationCmd.Nullify(); // this way myCreationCmd won't be cleared
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Constructor of _pyFilter
+ */
+//================================================================================
+
+_pyFilter::_pyFilter(const Handle(_pyCommand)& theCreationCmd, const _pyID& newID/*=""*/)
+  :_pyObject(theCreationCmd), myNewID( newID )
+{
+}
+
+//================================================================================
+/*!
+ * \brief To convert creation of a filter by criteria and
+ * to replace an old name by a new one
+ */
+//================================================================================
+
+void _pyFilter::Process( const Handle(_pyCommand)& theCommand)
+{
+  if ( theCommand->GetObject() == GetID() )
+    _pyObject::Process(theCommand); // count commands
+
+  if ( !myNewID.IsEmpty() )
+    theCommand->SetObject( myNewID );
+    
+  // Convert the following set of commands into smesh.GetFilterFromCriteria(criteria)
+  // aFilter0x2aaab0487080 = aFilterManager.CreateFilter()
+  // aFilter0x2aaab0487080.SetCriteria(aCriteria)
+  if ( GetNbCalls() == 1 && // none method was called before this SetCriteria() call
+       theCommand->GetMethod() == "SetCriteria")
+  {
+    // aFilter.SetCriteria(aCriteria) ->
+    // aFilter = smesh.GetFilterFromCriteria(criteria)
+    if ( myNewID.IsEmpty() )
+      theCommand->SetResultValue( GetID() );
+    else
+      theCommand->SetResultValue( myNewID );
+    theCommand->SetObject( SMESH_2smeshpy::GenName() );
+    theCommand->SetMethod( "GetFilterFromCriteria" );
+
+    // Clear aFilterManager.CreateFilter()
     GetCreationCmd()->Clear();
+  }
+  else if ( theCommand->GetMethod() == "SetMesh" )
+  {
+    if ( myMesh == theCommand->GetArg( 1 ))
+      theCommand->Clear();
+    else
+      myMesh = theCommand->GetArg( 1 );
+    theGen->AddMeshAccessorMethod( theCommand );
+  }
 }
 
+//================================================================================
+/*!
+ * \brief Set new filter name to the creation command
+ */
+//================================================================================
+
+void _pyFilter::Flush()
+{
+  if ( !myNewID.IsEmpty() && !GetCreationCmd()->IsEmpty() )
+    GetCreationCmd()->SetResultValue( myNewID );
+}
 
 //================================================================================
 /*!
- * \brief SubMesh creation can be moved to the end of engine commands
+ * \brief Return true if all my users can be cleared
  */
 //================================================================================
 
-_pySubMesh::_pySubMesh(const Handle(_pyCommand)& theCreationCmd):
-  _pyObject( theCreationCmd ),
-  myCmdCount( 0 )
+bool _pyFilter::CanClear()
 {
+  list< Handle(_pyObject) >::iterator obj = myUsers.begin();
+  for ( ; obj != myUsers.end(); ++obj )
+    if ( !(*obj)->CanClear() )
+      return false;
+
+  return true;
 }
 
 //================================================================================
 /*!
- * \brief count invoked commands
+ * \brief Reads _pyHypothesis'es from resource files of mesher Plugins
  */
 //================================================================================
 
-void _pySubMesh::Process( const Handle(_pyCommand)& theCommand )
+_pyHypothesisReader::_pyHypothesisReader()
 {
-  myCmdCount++;
-  GetCreationCmd()->AddDependantCmd( theCommand );
+  // Get paths to xml files of plugins
+  vector< string > xmlPaths;
+  string sep;
+  if ( const char* meshersList = getenv("SMESH_MeshersList") )
+  {
+    string meshers = meshersList, plugin;
+    string::size_type from = 0, pos;
+    while ( from < meshers.size() )
+    {
+      // cut off plugin name
+      pos = meshers.find( ':', from );
+      if ( pos != string::npos )
+        plugin = meshers.substr( from, pos-from );
+      else
+        plugin = meshers.substr( from ), pos = meshers.size();
+      from = pos + 1;
+
+      // get PLUGIN_ROOT_DIR path
+      string rootDirVar, pluginSubDir = plugin;
+      if ( plugin == "StdMeshers" )
+        rootDirVar = "SMESH", pluginSubDir = "smesh";
+      else
+        for ( pos = 0; pos < plugin.size(); ++pos )
+          rootDirVar += toupper( plugin[pos] );
+      rootDirVar += "_ROOT_DIR";
+
+      const char* rootDir = getenv( rootDirVar.c_str() );
+      if ( !rootDir || strlen(rootDir) == 0 )
+      {
+        rootDirVar = plugin + "_ROOT_DIR"; // HexoticPLUGIN_ROOT_DIR
+        rootDir = getenv( rootDirVar.c_str() );
+        if ( !rootDir || strlen(rootDir) == 0 ) continue;
+      }
+
+      // get a separator from rootDir
+      for ( pos = strlen( rootDir )-1; pos >= 0 && sep.empty(); --pos )
+        if ( rootDir[pos] == '/' || rootDir[pos] == '\\' )
+        {
+          sep = rootDir[pos];
+          break;
+        }
+#ifdef WNT
+      if (sep.empty() ) sep = "\\";
+#else
+      if (sep.empty() ) sep = "/";
+#endif
+
+      // get a path to resource file
+      string xmlPath = rootDir;
+      if ( xmlPath[ xmlPath.size()-1 ] != sep[0] )
+        xmlPath += sep;
+      xmlPath += "share" + sep + "salome" + sep + "resources" + sep;
+      for ( pos = 0; pos < pluginSubDir.size(); ++pos )
+        xmlPath += tolower( pluginSubDir[pos] );
+      xmlPath += sep + plugin + ".xml";
+      bool fileOK;
+#ifdef WNT
+      fileOK = (GetFileAttributes(xmlPath.c_str()) != INVALID_FILE_ATTRIBUTES);
+#else
+      fileOK = (access(xmlPath.c_str(), F_OK) == 0);
+#endif
+      if ( fileOK )
+        xmlPaths.push_back( xmlPath );
+    }
+  }
+
+  // Read xml files
+  LDOMParser xmlParser;
+  for ( size_t i = 0; i < xmlPaths.size(); ++i )
+  {
+    bool error = xmlParser.parse( xmlPaths[i].c_str() );
+    if ( error )
+    {
+      _AString data;
+      INFOS( xmlParser.GetError(data) );
+      continue;
+    }
+    // <algorithm type="Regular_1D"
+    //            label-id="Wire discretisation"
+    //            ...>
+    //   <python-wrap>
+    //     <algo>Regular_1D=Segment()</algo>
+    //     <hypo>LocalLength=LocalLength(SetLength(1),,SetPrecision(1))</hypo>
+    //
+    LDOM_Document xmlDoc = xmlParser.getDocument();
+    LDOM_NodeList algoNodeList = xmlDoc.getElementsByTagName( "algorithm" );
+    for ( int i = 0; i < algoNodeList.getLength(); ++i )
+    {
+      LDOM_Node algoNode = algoNodeList.item( i );
+      LDOM_Element& algoElem = (LDOM_Element&) algoNode;
+      LDOM_NodeList pyAlgoNodeList = algoElem.getElementsByTagName( "algo" );
+      if ( pyAlgoNodeList.getLength() < 1 ) continue;
+
+      _AString text, algoType, method, arg;
+      for ( int iA = 0; iA < pyAlgoNodeList.getLength(); ++iA )
+      {
+        LDOM_Node pyAlgoNode = pyAlgoNodeList.item( iA );
+        LDOM_Node textNode   = pyAlgoNode.getFirstChild();
+        text = textNode.getNodeValue();
+        Handle(_pyCommand) algoCmd = new _pyCommand( text );
+        algoType = algoCmd->GetResultValue();
+        method   = algoCmd->GetMethod();
+        arg      = algoCmd->GetArg(1);
+        if ( !algoType.IsEmpty() && !method.IsEmpty() )
+        {
+          Handle(_pyAlgorithm) algo = new _pyAlgorithm( algoCmd );
+          algo->SetConvMethodAndType( method, algoType );
+          if ( !arg.IsEmpty() )
+            algo->setCreationArg( 1, arg );
+
+          myType2Hyp[ algoType ] = algo;
+          break;
+        }
+      }
+      if ( algoType.IsEmpty() ) continue;
+
+      LDOM_NodeList pyHypoNodeList = algoElem.getElementsByTagName( "hypo" );
+      _AString hypType;
+      Handle( _pyHypothesis ) hyp;
+      for ( int iH = 0; iH < pyHypoNodeList.getLength(); ++iH )
+      {
+        LDOM_Node pyHypoNode = pyHypoNodeList.item( iH );
+        LDOM_Node textNode   = pyHypoNode.getFirstChild();
+        text = textNode.getNodeValue();
+        Handle(_pyCommand) hypoCmd = new _pyCommand( text );
+        hypType = hypoCmd->GetResultValue();
+        method  = hypoCmd->GetMethod();
+        if ( !hypType.IsEmpty() && !method.IsEmpty() )
+        {
+          map<_AString, Handle(_pyHypothesis)>::iterator type2hyp = myType2Hyp.find( hypType );
+          if ( type2hyp == myType2Hyp.end() )
+            hyp = new _pyHypothesis( hypoCmd );
+          else
+            hyp = type2hyp->second;
+          hyp->SetConvMethodAndType( method, algoType );
+          for ( int iArg = 1; iArg <= hypoCmd->GetNbArgs(); ++iArg )
+          {
+            _pyCommand argCmd( hypoCmd->GetArg( iArg ));
+            _AString argMethod = argCmd.GetMethod();
+            _AString argNbText = argCmd.GetArg( 1 );
+            if ( argMethod.IsEmpty() && !argCmd.IsEmpty() )
+              hyp->setCreationArg( 1, argCmd.GetString() ); // e.g. Parameters(smesh.SIMPLE)
+            else
+              hyp->AddArgMethod( argMethod,
+                                 argNbText.IsIntegerValue() ? argNbText.IntegerValue() : 1 );
+          }
+          myType2Hyp[ hypType ] = hyp;
+        }
+      }
+    }
+  }
 }
 
 //================================================================================
 /*!
- * \brief Clear creatin command if no commands invoked
+ * \brief Returns a new hypothesis initialized according to the read information
  */
 //================================================================================
 
-void _pySubMesh::Flush()
+Handle(_pyHypothesis)
+_pyHypothesisReader::GetHypothesis(const _AString&           hypType,
+                                   const Handle(_pyCommand)& creationCmd) const
 {
-  if ( !myCmdCount ) // move to the end of all commands
-    theGen->GetLastCommand()->AddDependantCmd( GetCreationCmd() );
-  else if ( !myCreator.IsNull() )
-    // move to be just after creator
-    myCreator->GetCreationCmd()->AddDependantCmd( GetCreationCmd() );
+  Handle(_pyHypothesis) resHyp, sampleHyp;
+
+  map<_AString, Handle(_pyHypothesis)>::const_iterator type2hyp = myType2Hyp.find( hypType );
+  if ( type2hyp != myType2Hyp.end() )
+    sampleHyp = type2hyp->second;
+
+  if ( sampleHyp.IsNull() )
+  {
+    resHyp = new _pyHypothesis(creationCmd);
+  }
+  else
+  {
+    if ( sampleHyp->IsAlgo() )
+      resHyp = new _pyAlgorithm( creationCmd );
+    else
+      resHyp = new _pyHypothesis(creationCmd);
+    resHyp->Assign( sampleHyp, _pyID() );
+  }
+  return resHyp;
 }
index eac87decaab8d716d9b78e498aef6e6f99dce446..f92c285b4c4176cf3463c4afe671db5b35fc7e4a 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File      : SMESH_smesh.hxx
 // Created   : Fri Nov 18 12:05:18 2005
 // Author    : Edward AGAPOV (eap)
 
 #include <list>
 #include <map>
+#include <vector>
+
+#include <SALOMEconfig.h>
+#include CORBA_CLIENT_HEADER(SALOMEDS)
 
 // ===========================================================================================
 /*!
@@ -47,9 +52,6 @@
  * 
  * Everything here is for internal usage by SMESH_2smeshpy::ConvertScript()
  * declared in SMESH_PythonDump.hxx
- *
- * See comments to _pyHypothesis class to know how to assure convertion of a new
- * type of hypothesis
  */
 // ===========================================================================================
 
@@ -68,19 +70,21 @@ class _pyMesh;
 class _pySubMesh;
 class _pyHypothesis;
 class _pyAlgorithm;
-class _pyFilterManager;
-
-DEFINE_STANDARD_HANDLE (_pyCommand   ,Standard_Transient);
-DEFINE_STANDARD_HANDLE (_pyObject    ,Standard_Transient);
-DEFINE_STANDARD_HANDLE (_pyGen       ,_pyObject);
-DEFINE_STANDARD_HANDLE (_pyMesh      ,_pyObject);
-DEFINE_STANDARD_HANDLE (_pySubMesh   ,_pyObject);
-DEFINE_STANDARD_HANDLE (_pyMeshEditor,_pyObject);
-DEFINE_STANDARD_HANDLE (_pyHypothesis,_pyObject);
-DEFINE_STANDARD_HANDLE (_pyFilterManager,_pyObject);
-DEFINE_STANDARD_HANDLE (_pyAlgorithm ,_pyHypothesis);
+class _pyHypothesisReader;
+
+DEFINE_STANDARD_HANDLE (_pyCommand         ,Standard_Transient);
+DEFINE_STANDARD_HANDLE (_pyObject          ,Standard_Transient);
+DEFINE_STANDARD_HANDLE (_pyHypothesisReader,Standard_Transient);
+DEFINE_STANDARD_HANDLE (_pyGen             ,_pyObject);
+DEFINE_STANDARD_HANDLE (_pyMesh            ,_pyObject);
+DEFINE_STANDARD_HANDLE (_pySubMesh         ,_pyObject);
+DEFINE_STANDARD_HANDLE (_pyGroup           ,_pySubMesh);
+DEFINE_STANDARD_HANDLE (_pyMeshEditor      ,_pyObject);
+DEFINE_STANDARD_HANDLE (_pyHypothesis      ,_pyObject);
+DEFINE_STANDARD_HANDLE (_pyAlgorithm       ,_pyHypothesis);
 
 typedef TCollection_AsciiString _pyID;
+typedef TCollection_AsciiString _AString;
 
 // ===========================================================
 /*!
@@ -92,50 +96,54 @@ typedef TCollection_AsciiString _pyID;
 class _pyCommand: public Standard_Transient
 {
   int                             myOrderNb;            //!< position within the script
-  TCollection_AsciiString         myString;             //!< command text
-  TCollection_AsciiString         myRes, myObj, myMeth; //!< found parts of command
+  _AString                        myString;             //!< command text
+  _AString                        myRes, myObj, myMeth; //!< found parts of command
   TColStd_SequenceOfAsciiString   myArgs;               //!< found arguments
   TColStd_SequenceOfInteger       myBegPos;             //!< where myRes, myObj, ... begin
   std::list< Handle(_pyCommand) > myDependentCmds; //!< commands that sould follow me in the script
 
   enum { UNKNOWN=-1, EMPTY=0, RESULT_IND, OBJECT_IND, METHOD_IND, ARG1_IND };
-  int GetBegPos( int thePartIndex );
+  int  GetBegPos( int thePartIndex );
   void SetBegPos( int thePartIndex, int thePosition );
-  void SetPart( int thePartIndex, const TCollection_AsciiString& theNewPart,
-                TCollection_AsciiString& theOldPart);
+  void SetPart( int thePartIndex, const _AString& theNewPart, _AString& theOldPart);
   void FindAllArgs() { GetArg(1); }
 
 public:
   _pyCommand() {};
-  _pyCommand( const TCollection_AsciiString& theString, int theNb )
+  _pyCommand( const _AString& theString, int theNb=-1 )
     : myString( theString ), myOrderNb( theNb ) {};
-  TCollection_AsciiString & GetString() { return myString; }
+  _AString & GetString() { return myString; }
   int GetOrderNb() const { return myOrderNb; }
   void SetOrderNb( int theNb ) { myOrderNb = theNb; }
+  typedef void* TAddr;
+  TAddr GetAddress() const { return (void*) this; }
   int Length() { return myString.Length(); }
-  void Clear() { myString.Clear(); myBegPos.Clear(); }
+  void Clear() { myString.Clear(); myBegPos.Clear(); myArgs.Clear(); }
   bool IsEmpty() const { return myString.IsEmpty(); }
-  TCollection_AsciiString GetIndentation();
-  const TCollection_AsciiString & GetResultValue();
+  _AString GetIndentation();
+  const _AString & GetResultValue();
   const int GetNbResultValues();
-  const TCollection_AsciiString & GetResultValue(int res);
-  const TCollection_AsciiString & GetObject();
-  const TCollection_AsciiString & GetMethod();
-  const TCollection_AsciiString & GetArg( int index );
+  _AString GetResultValue(int res);
+  const _AString & GetObject();
+  const _AString & GetMethod();
+  const _AString & GetArg( int index );
   int GetNbArgs() { FindAllArgs(); return myArgs.Length(); }
-  //Handle(TColStd_HSequenceOfAsciiString) GetArgs();
-  void SetResultValue( const TCollection_AsciiString& theResult )
+  bool MethodStartsFrom(const _AString& beg)
+  { GetMethod(); return ( myMeth.Location( beg, 1, myMeth.Length() ) == 1 ); }
+  void SetResultValue( const _AString& theResult )
   { GetResultValue(); SetPart( RESULT_IND, theResult, myRes ); }
-  void SetObject(const TCollection_AsciiString& theObject)
+  void SetObject(const _AString& theObject)
   { GetObject(); SetPart( OBJECT_IND, theObject, myObj ); }
-  void SetMethod(const TCollection_AsciiString& theMethod)
+  void SetMethod(const _AString& theMethod)
   { GetMethod(); SetPart( METHOD_IND, theMethod, myMeth ); }
-  void SetArg( int index, const TCollection_AsciiString& theArg);
+  void SetArg( int index, const _AString& theArg);
   void RemoveArgs();
-  static bool SkipSpaces( const TCollection_AsciiString & theSring, int & thePos );
-  static TCollection_AsciiString GetWord( const TCollection_AsciiString & theSring,
-                                          int & theStartPos, const bool theForward,
-                                          const bool dotIsWord = false);
+  void Comment();
+  static bool SkipSpaces( const _AString & theSring, int & thePos );
+  static _AString GetWord( const _AString & theSring, int & theStartPos,
+                           const bool theForward, const bool dotIsWord = false);
+  static bool IsStudyEntry( const _AString& str );
+  static std::list< _pyID > GetStudyEntries( const _AString& str );
   void AddDependantCmd( Handle(_pyCommand) cmd, bool prepend = false)
   { if (prepend) myDependentCmds.push_front( cmd ); else myDependentCmds.push_back( cmd ); }
   bool SetDependentCmdsAfter() const;
@@ -147,27 +155,62 @@ public:
 
 // -------------------------------------------------------------------------------------
 /*!
- * \brief Root of all objects
+ * \brief Root of all objects. It counts calls of Process()
  */
 // -------------------------------------------------------------------------------------
 
 class _pyObject: public Standard_Transient
 {
+protected:
+  _pyID                           myID;
   Handle(_pyCommand)              myCreationCmd;
+  std::list< Handle(_pyCommand) > myProcessedCmds;
+  bool                            myIsPublished;
+
+  void setID(const _pyID& theID);
 public:
-  _pyObject(const Handle(_pyCommand)& theCreationCmd): myCreationCmd(theCreationCmd) {}
-  const _pyID& GetID() { return myCreationCmd->GetResultValue(); }
+  _pyObject(const Handle(_pyCommand)& theCreationCmd, const _pyID& theID=_pyID());
+  const _pyID& GetID() { return myID.IsEmpty() ? myCreationCmd->GetResultValue() : myID; }
   static _pyID FatherID(const _pyID & childID);
   const Handle(_pyCommand)& GetCreationCmd() { return myCreationCmd; }
-  void  SetCreationCmd( Handle(_pyCommand) cmd ) { myCreationCmd = cmd; }
+  int GetNbCalls() const { return myProcessedCmds.size(); }
+  bool IsInStudy() const { return myIsPublished; }
+  virtual void SetRemovedFromStudy(const bool isRemoved) { myIsPublished = !isRemoved; }
+  void SetCreationCmd( Handle(_pyCommand) cmd ) { myCreationCmd = cmd; }
   int GetCommandNb() { return myCreationCmd->GetOrderNb(); }
-  virtual void Process(const Handle(_pyCommand) & theCommand) = 0;
+  void AddProcessedCmd( const Handle(_pyCommand) & cmd )
+  { if (myProcessedCmds.empty() || myProcessedCmds.back()!=cmd) myProcessedCmds.push_back( cmd );}
+  std::list< Handle(_pyCommand) >& GetProcessedCmds() { return myProcessedCmds; }
+  virtual void Process(const Handle(_pyCommand) & cmd) { AddProcessedCmd(cmd); }
   virtual void Flush() = 0;
   virtual const char* AccessorMethod() const;
+  virtual bool CanClear() { return !myIsPublished; }
+  virtual void ClearCommands();
+  virtual void Free() {}
 
   DEFINE_STANDARD_RTTI (_pyObject)
 };
 
+// -------------------------------------------------------------------------------------
+/*!
+ * \brief Data used to restore cleared Compute() command of an exported mesh
+ * when an imported mesh is created
+ */
+// -------------------------------------------------------------------------------------
+struct ExportedMeshData
+{
+  Handle(_pyMesh)    myMesh;
+  Handle(_pyCommand) myLastComputeCmd;
+  _AString           myLastComputeCmdString;
+  ExportedMeshData() {}
+  ExportedMeshData( const Handle(_pyMesh)& mesh, Handle(_pyCommand) computeCmd):
+    myMesh( mesh ), myLastComputeCmd( computeCmd )
+  {
+    if ( !myLastComputeCmd.IsNull())
+      myLastComputeCmdString = myLastComputeCmd->GetString();
+  }
+};
+
 // -------------------------------------------------------------------------------------
 /*!
  * \brief Class corresponding to SMESH_Gen. It holds info on existing
@@ -178,25 +221,45 @@ class _pyGen: public _pyObject
 {
 public:
   _pyGen(Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod,
-         Resource_DataMapOfAsciiStringAsciiString& theObjectNames);
-  //~_pyGen();
-  Handle(_pyCommand) AddCommand( const TCollection_AsciiString& theCommand );
-  void Process( const Handle(_pyCommand)& theCommand );
-  void Flush();
-  Handle(_pyHypothesis) FindHyp( const _pyID& theHypID );
-  Handle(_pyHypothesis) FindAlgo( const _pyID& theGeom, const _pyID& theMesh,
-                                  const Handle(_pyHypothesis)& theHypothesis);
-  Handle(_pySubMesh) FindSubMesh( const _pyID& theSubMeshID );
+         Resource_DataMapOfAsciiStringAsciiString& theObjectNames,
+         SALOMEDS::Study_ptr&                      theStudy,
+         const bool                                theToKeepAllCommands);
+  Handle(_pyCommand) AddCommand( const _AString& theCommand );
   void ExchangeCommands( Handle(_pyCommand) theCmd1, Handle(_pyCommand) theCmd2 );
   void SetCommandAfter( Handle(_pyCommand) theCmd, Handle(_pyCommand) theAfterCmd );
   void SetCommandBefore( Handle(_pyCommand) theCmd, Handle(_pyCommand) theBeforeCmd );
   Handle(_pyCommand)& GetLastCommand();
   std::list< Handle(_pyCommand) >& GetCommands() { return myCommands; }
+  void PlaceSubmeshAfterItsCreation( Handle(_pyCommand) theCmdUsingSubmesh ) const;
+
+  _pyID GenerateNewID( const _pyID& theID );
+  void AddObject( Handle(_pyObject)& theObj );
+  void SetProxyObject( const _pyID& theID, Handle(_pyObject)& theObj );
+  Handle(_pyObject) FindObject( const _pyID& theObjID ) const;
+  Handle(_pySubMesh) FindSubMesh( const _pyID& theSubMeshID );
+  Handle(_pyHypothesis) FindHyp( const _pyID& theHypID );
+  Handle(_pyHypothesis) FindAlgo( const _pyID& theGeom, const _pyID& theMesh,
+                                  const Handle(_pyHypothesis)& theHypothesis);
+
   void SetAccessorMethod(const _pyID& theID, const char* theMethod );
   bool AddMeshAccessorMethod( Handle(_pyCommand) theCmd ) const;
   bool AddAlgoAccessorMethod( Handle(_pyCommand) theCmd ) const;
-  const char* AccessorMethod() const;
-  _pyID GenerateNewID( const _pyID& theID );
+  virtual const char* AccessorMethod() const;
+
+  bool IsGeomObject(const _pyID& theObjID) const;
+  bool IsNotPublished(const _pyID& theObjID) const;
+  bool IsToKeepAllCommands() const { return myToKeepAllCommands; }
+  void AddExportedMesh(const _AString& file, const ExportedMeshData& mesh )
+  { myFile2ExportedMesh[ file ] = mesh; }
+  ExportedMeshData& FindExportedMesh( const _AString& file )
+  { return myFile2ExportedMesh[ file ]; }
+
+  virtual void Process( const Handle(_pyCommand)& theCommand );
+  virtual void Flush();
+  virtual void ClearCommands();
+  virtual void Free();
+
+  Handle( _pyHypothesisReader ) GetHypothesisReader() const;
 
 private:
   void setNeighbourCommand( Handle(_pyCommand)& theCmd,
@@ -205,16 +268,20 @@ private:
   
 private:
   std::map< _pyID, Handle(_pyMesh) >       myMeshes;
-  std::map< _pyID, Handle(_pySubMesh) >    mySubMeshes;
   std::map< _pyID, Handle(_pyMeshEditor) > myMeshEditors;
+  std::map< _pyID, Handle(_pyObject) >     myObjects;
   std::list< Handle(_pyHypothesis) >       myHypos;
   std::list< Handle(_pyCommand) >          myCommands;
   int                                      myNbCommands;
-  bool                                     myHasPattern;
   Resource_DataMapOfAsciiStringAsciiString& myID2AccessorMethod;
   Resource_DataMapOfAsciiStringAsciiString& myObjectNames;
   Handle(_pyCommand)                       myLastCommand;
-  Handle(_pyFilterManager)                 myFilterManager;
+  int                                      myNbFilters;
+  bool                                     myToKeepAllCommands;
+  SALOMEDS::Study_var                      myStudy;
+  int                                      myGeomIDNb, myGeomIDIndex;
+  std::map< _AString, ExportedMeshData >   myFile2ExportedMesh;
+  Handle( _pyHypothesisReader )            myHypReader;
 
   DEFINE_STANDARD_RTTI (_pyGen)
 };
@@ -228,22 +295,35 @@ private:
 class _pyMesh: public _pyObject
 {
   std::list< Handle(_pyHypothesis) > myHypos;
-  std::list< Handle(_pyCommand) > myAddHypCmds;
-  std::list< Handle(_pySubMesh) > mySubmeshes;
-  bool                            myHasEditor;
+  std::list< Handle(_pyCommand) >    myAddHypCmds;
+  std::list< Handle(_pySubMesh) >    mySubmeshes;
+  std::list< Handle(_pyGroup) >      myGroups;
+  std::list< Handle(_pyMeshEditor)>  myEditors;
+  //d::list< Handle(_pyMesh) >       myFatherMeshes; // this mesh depends on
+  std::list< Handle(_pyMesh) >       myChildMeshes; // depending on me
+  bool                               myGeomNotInStudy;
+  Handle(_pyCommand)                 myLastComputeCmd;
 public:
   _pyMesh(const Handle(_pyCommand) creationCmd);
-  _pyMesh(const Handle(_pyCommand) theCreationCmd, const TCollection_AsciiString & id);
+  _pyMesh(const Handle(_pyCommand) theCreationCmd, const _pyID & id);
   const _pyID& GetGeom() { return GetCreationCmd()->GetArg(1); }
-  void Process( const Handle(_pyCommand)& theCommand);
-  void Flush();
-  const char* AccessorMethod() const { return _pyMesh_ACCESS_METHOD; }
+  void AddGroup( const Handle(_pyGroup)& g ) { myGroups.push_back( g ); }
+  void AddEditor( const Handle(_pyMeshEditor)& e ) { myEditors.push_back( e ); }
+  bool IsNotGeomPublished() { return myGeomNotInStudy; }
+  virtual void Process( const Handle(_pyCommand)& theCommand);
+  virtual void Flush();
+  virtual void SetRemovedFromStudy(const bool isRemoved);
+  virtual bool CanClear();
+  virtual void ClearCommands();
+  virtual void Free() { /*myFatherMeshes.clear();*/ myChildMeshes.clear(); }
+  virtual const char* AccessorMethod() const { return _pyMesh_ACCESS_METHOD; }
 private:
+  void addFatherMesh( const Handle(_pyMesh)& mesh );
+  void addFatherMesh( const _pyID& meshID );
   static bool NeedMeshAccess( const Handle(_pyCommand)& theCommand );
   static void AddMeshAccess( const Handle(_pyCommand)& theCommand )
   { theCommand->SetObject( theCommand->GetObject() + "." _pyMesh_ACCESS_METHOD ); }
 
-  //friend class _pyMeshEditor;
   DEFINE_STANDARD_RTTI (_pyMesh)
 };
 #undef _pyMesh_ACCESS_METHOD 
@@ -255,12 +335,14 @@ private:
 // -------------------------------------------------------------------------------------
 class _pyMeshEditor: public _pyObject
 {
-  _pyID myMesh;
-  TCollection_AsciiString myCreationCmdStr;
+  _pyID    myMesh;
+  _AString myCreationCmdStr;
 public:
   _pyMeshEditor(const Handle(_pyCommand)& theCreationCmd);
-  void Process( const Handle(_pyCommand)& theCommand);
+  _pyID GetMesh() const { return myMesh; }
+  virtual void Process( const Handle(_pyCommand)& theCommand);
   virtual void Flush() {}
+  virtual bool CanClear();
 
   DEFINE_STANDARD_RTTI (_pyMesh)
 };
@@ -268,64 +350,80 @@ public:
 // -------------------------------------------------------------------------------------
 /*!
  * \brief Root class for hypothesis
- *
- * HOWTO assure convertion of a new type of hypothesis
- * In _pyHypothesis::NewHypothesis():
- * 1. add a case for the name of the new hypothesis
- * 2. use SetConvMethodAndType() to set
- *    . for algo: algorithm name and method of Mesh creating the algo
- *    . for hypo: name of the algorithm and method creating the hypothesis
- * 3. append to myArgMethods interface methods setting param values in the
- *    order they are used when creation method is called. If arguments of
- *    the creation method can't be easily got from calls of hypothesis methods, you are
- *    to derive a specific class from _pyHypothesis that would redefine Process(),
- *    see _pyComplexParamHypo for example
  */
 // -------------------------------------------------------------------------------------
 class _pyHypothesis: public _pyObject
 {
+  friend class _pyHypothesisReader;
 protected:
   bool    myIsAlgo, myIsWrapped;
   _pyID   myGeom,   myMesh;
-  // a hypothesis can be used and created by different algos by different methods
-  std::map<TCollection_AsciiString, TCollection_AsciiString > myType2CreationMethod;
-  //TCollection_AsciiString       myCreationMethod, myType;
-  TColStd_SequenceOfAsciiString myArgs;           // creation arguments
-  TColStd_SequenceOfAsciiString myArgMethods;     // hypo methods setting myArgs
-  TColStd_SequenceOfInteger     myNbArgsByMethod; // nb args set by each method
-  std::list<Handle(_pyCommand)>  myArgCommands;
-  std::list<Handle(_pyCommand)>  myUnknownCommands;
+  struct CreationMethod {
+    _AString              myMethod; // method of algo or mesh creating a hyp
+    // myArgNb(i)-th arg of myArgMethods(i) of hyp becomes an i-th arg of myAlgoMethod
+    std::vector<_AString> myArgMethods;
+    std::vector<int>      myArgNb; // arg nb countered from 1
+    std::vector<_AString> myArgs; // creation arguments
+  };
+  void setCreationArg( const int argNb, const _AString& arg );
+  // a hypothesis can be created by different algos by different methods
+  typedef std::map<_AString, CreationMethod > TType2CrMethod;
+  TType2CrMethod                myAlgoType2CreationMethod;
+  CreationMethod*               myCurCrMethod; // used for adding to myAlgoType2CreationMethod
+  std::list<Handle(_pyCommand)> myArgCommands;
+  std::list<Handle(_pyCommand)> myUnusedCommands;
+  std::list<Handle(_pyObject) > myReferredObjs;
+  // maps used to clear commands setting parameters if result of setting is
+  // discared (e.g. by mesh.Clear())
+  std::map<_AString, std::list<Handle(_pyCommand)> >            myMeth2Commands;
+  std::map< _pyCommand::TAddr, std::list<Handle(_pyCommand) > > myComputeAddr2Cmds;
+  std::list<Handle(_pyCommand) >                                myComputeCmds;
+  void rememberCmdOfParameter( const Handle(_pyCommand) & cmd );
+  bool isCmdUsedForCompute( const Handle(_pyCommand) & cmd,
+                            _pyCommand::TAddr avoidComputeAddr=NULL ) const;
 public:
   _pyHypothesis(const Handle(_pyCommand)& theCreationCmd);
-  void SetConvMethodAndType(const char* creationMethod, const char* type)
-  { myType2CreationMethod[ (char*)type ] = (char*)creationMethod; }
-  void AddArgMethod(const char* method, const int nbArgs = 1)
-  { myArgMethods.Append( (char*)method ); myNbArgsByMethod.Append( nbArgs ); }
-  const TColStd_SequenceOfAsciiString& GetArgs() const { return myArgs; }
+  void SetConvMethodAndType(const _AString& creationMethod, const _AString& type)
+  { myCurCrMethod = &myAlgoType2CreationMethod[ type ];
+    myCurCrMethod->myMethod = creationMethod; }
+  void AddArgMethod(const _AString& method, const int argNb = 1)
+  { myCurCrMethod->myArgMethods.push_back( method );
+    myCurCrMethod->myArgNb.push_back( argNb ); }
+  //const TColStd_SequenceOfAsciiString& GetArgs() const { return myArgs; }
   const std::list<Handle(_pyCommand)>& GetArgCommands() const { return myArgCommands; }
   void ClearAllCommands();
   virtual bool IsAlgo() const { return myIsAlgo; }
-  bool IsValid() const { return !myType2CreationMethod.empty(); }
+  bool IsValid() const { return !myAlgoType2CreationMethod.empty(); }
   bool IsWrapped() const { return myIsWrapped; }
   const _pyID & GetGeom() const { return myGeom; }
   void SetMesh( const _pyID& theMeshId) { if ( myMesh.IsEmpty() ) myMesh = theMeshId; }
   const _pyID & GetMesh() const { return myMesh; }
-  const TCollection_AsciiString& GetAlgoType() const
-  { return myType2CreationMethod.begin()->first; }
-  const TCollection_AsciiString& GetAlgoCreationMethod() const
-  { return myType2CreationMethod.begin()->second; }
-  bool CanBeCreatedBy(const TCollection_AsciiString& algoType ) const
-  { return myType2CreationMethod.find( algoType ) != myType2CreationMethod.end(); }
-  const TCollection_AsciiString& GetCreationMethod(const TCollection_AsciiString& algoType) const
-  { return myType2CreationMethod.find( algoType )->second; }
-  virtual bool IsWrappable(const _pyID& theMesh) { return !myIsWrapped && myMesh == theMesh; }
+  const _AString& GetAlgoType() const
+  { return myAlgoType2CreationMethod.begin()->first; }
+  const _AString& GetAlgoCreationMethod() const
+  { return myAlgoType2CreationMethod.begin()->second.myMethod; }
+  bool CanBeCreatedBy(const _AString& algoType ) const
+  { return myAlgoType2CreationMethod.find( algoType ) != myAlgoType2CreationMethod.end(); }
+  const _AString& GetCreationMethod(const _AString& algoType)
+  { return ( myCurCrMethod = & myAlgoType2CreationMethod[ algoType ])->myMethod; }
+  static Handle(_pyHypothesis) NewHypothesis( const Handle(_pyCommand)& theCreationCmd);
+
+  virtual bool IsWrappable(const _pyID& theMesh) const;
   virtual bool Addition2Creation( const Handle(_pyCommand)& theAdditionCmd,
                                   const _pyID&              theMesh);
-  static Handle(_pyHypothesis) NewHypothesis( const Handle(_pyCommand)& theCreationCmd);
-  void Process( const Handle(_pyCommand)& theCommand);
-  void Flush();
+  virtual void Process( const Handle(_pyCommand)& theCommand);
+  virtual void Flush();
+  virtual void Free() { myReferredObjs.clear(); }
   virtual void Assign( const Handle(_pyHypothesis)& theOther,
-                      const _pyID&                 theMesh );
+                       const _pyID&                 theMesh );
+  virtual bool CanClear();
+  virtual void ClearCommands();
+  virtual bool GetReferredMeshesAndGeom( std::list< Handle(_pyMesh) >& meshes );
+
+  void MeshComputed    ( const Handle(_pyCommand)& theComputeCommand );
+  void ComputeDiscarded( const Handle(_pyCommand)& theComputeCommand );
+  //void ComputeSaved    ( const Handle(_pyCommand)& theComputeCommand );
+
 
   DEFINE_STANDARD_RTTI (_pyHypothesis)
 };
@@ -341,7 +439,7 @@ public:
   _pyAlgorithm(const Handle(_pyCommand)& theCreationCmd);
   virtual bool Addition2Creation( const Handle(_pyCommand)& theAdditionCmd,
                                   const _pyID&              theMesh);
-  const char* AccessorMethod() const { return "GetAlgorithm()"; }
+  virtual const char* AccessorMethod() const { return "GetAlgorithm()"; }
   virtual bool IsWrappable(const _pyID& theMesh) { return !myIsWrapped; }
 
   DEFINE_STANDARD_RTTI (_pyAlgorithm)
@@ -356,7 +454,8 @@ class _pyComplexParamHypo: public _pyHypothesis
 {
 public:
   _pyComplexParamHypo(const Handle(_pyCommand)& theCreationCmd): _pyHypothesis(theCreationCmd) {}
-  void Process( const Handle(_pyCommand)& theCommand);
+  virtual void Process( const Handle(_pyCommand)& theCommand);
+  virtual void Flush();
 
   DEFINE_STANDARD_RTTI (_pyComplexParamHypo)
 };
@@ -370,13 +469,15 @@ DEFINE_STANDARD_HANDLE (_pyComplexParamHypo, _pyHypothesis);
 class _pyLayerDistributionHypo: public _pyHypothesis
 {
   Handle(_pyHypothesis) my1dHyp;
+  _AString              myAlgoMethod;
 public:
-  _pyLayerDistributionHypo(const Handle(_pyCommand)& theCreationCmd):
-    _pyHypothesis(theCreationCmd) {}
-  void Process( const Handle(_pyCommand)& theCommand);
-  void Flush();
-  bool Addition2Creation( const Handle(_pyCommand)& theAdditionCmd,
-                          const _pyID&              theMesh);
+  _pyLayerDistributionHypo(const Handle(_pyCommand)& theCreationCmd, const char* algoMethod):
+    _pyHypothesis(theCreationCmd), myAlgoMethod((char*)algoMethod) {}
+  virtual void Process( const Handle(_pyCommand)& theCommand);
+  virtual void Flush();
+  virtual bool Addition2Creation( const Handle(_pyCommand)& theAdditionCmd,
+                                  const _pyID&              theMesh);
+  virtual void Free() { my1dHyp.Nullify(); }
 
   DEFINE_STANDARD_RTTI (_pyLayerDistributionHypo)
 };
@@ -416,20 +517,19 @@ DEFINE_STANDARD_HANDLE (_pySegmentLengthAroundVertexHyp, _pyHypothesis);
 
 // -------------------------------------------------------------------------------------
 /*!
- * \brief FilterManager creates only if at least one command invoked
+ * \brief SelfEraser erases creation command if no more it's commands invoked
  */
 // -------------------------------------------------------------------------------------
-class _pyFilterManager: public _pyObject
+class _pySelfEraser: public _pyObject
 {
 public:
-  _pyFilterManager(const Handle(_pyCommand)& theCreationCmd);
-  void Process( const Handle(_pyCommand)& theCommand);
+  _pySelfEraser(const Handle(_pyCommand)& theCreationCmd)
+    :_pyObject(theCreationCmd) { myIsPublished = true; }
   virtual void Flush();
 
-  DEFINE_STANDARD_RTTI (_pyFilterManager)
-private:
-  int myCmdCount;
+  DEFINE_STANDARD_RTTI (_pySelfEraser)
 };
+DEFINE_STANDARD_HANDLE (_pySelfEraser, _pyObject);
 
 // -------------------------------------------------------------------------------------
 /*!
@@ -438,16 +538,72 @@ private:
 // -------------------------------------------------------------------------------------
 class _pySubMesh:  public _pyObject
 {
+  Handle(_pyObject) myCreator;
+  Handle(_pyMesh) myMesh;
 public:
   _pySubMesh(const Handle(_pyCommand)& theCreationCmd);
-  void Process( const Handle(_pyCommand)& theCommand);
+  virtual void Process( const Handle(_pyCommand)& theCommand);
   virtual void Flush();
+  virtual Handle(_pyMesh) GetMesh() { return myMesh; }
+  virtual void Free() { myCreator.Nullify(); myMesh.Nullify(); }
   void SetCreator( const Handle(_pyObject)& theCreator ) { myCreator = theCreator; }
+  static bool CanBeArgOfMethod(const _AString& theMethodName);
 
-  DEFINE_STANDARD_RTTI (_pyFilterManager)
-private:
-  int               myCmdCount;
-  Handle(_pyObject) myCreator;
+  DEFINE_STANDARD_RTTI (_pySubMesh)
+};
+// -------------------------------------------------------------------------------------
+/*!
+ * \brief A filter sets a human readable name to self
+ */
+// -------------------------------------------------------------------------------------
+class _pyFilter:  public _pyObject
+{
+  _pyID myNewID, myMesh;
+  std::list< Handle(_pyObject) > myUsers;
+public:
+  _pyFilter(const Handle(_pyCommand)& theCreationCmd, const _pyID& newID="");
+  void AddUser( const Handle(_pyObject)& user) { myUsers.push_back( user ); }
+  virtual void Process( const Handle(_pyCommand)& theCommand);
+  virtual void Flush();
+  virtual bool CanClear();
+  virtual void Free() { myUsers.clear(); }
+  const _pyID& GetNewID() const { return myNewID; }
+
+  DEFINE_STANDARD_RTTI (_pyFilter)
+};
+DEFINE_STANDARD_HANDLE (_pyFilter, _pyObject);
+
+// -------------------------------------------------------------------------------------
+/*!
+ * \brief To convert creation of a group by filter
+ */
+// -------------------------------------------------------------------------------------
+class _pyGroup:  public _pySubMesh
+{
+  Handle(_pyFilter) myFilter;
+  bool              myCanClearCreationCmd;
+public:
+  _pyGroup(const Handle(_pyCommand)& theCreationCmd, const _pyID & id=_pyID());
+  virtual void Process( const Handle(_pyCommand)& theCommand);
+  virtual void Flush();
+  virtual void Free() { myFilter.Nullify(); }
+
+  DEFINE_STANDARD_RTTI (_pyGroup)
+};
+
+// -------------------------------------------------------------------------------------
+/*!
+ * \brief Class reading _pyHypothesis'es from resource files of mesher Plugins
+ */
+// -------------------------------------------------------------------------------------
+class _pyHypothesisReader: public Standard_Transient
+{
+  std::map<_AString, Handle(_pyHypothesis)> myType2Hyp;
+public:
+  _pyHypothesisReader();
+  Handle(_pyHypothesis) GetHypothesis(const _AString&           hypType,
+                                      const Handle(_pyCommand)& creationCmd) const;
+  DEFINE_STANDARD_RTTI (_pyHypothesisReader)
 };
 
 #endif
index 8aa242ba6e11f4e8a8e88b475f49524f6eda769f..9a73a538fc1f2b628abdb8195541618b346cdb57 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : SMESH_3D_Algo_i.cxx
 //  Author : Paul RASCLE, EDF
index 4352e7296a555511c2a642b57091a327012bdaaf..d798b9e4143009414600769d0b30a9664036aee9 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : SMESH_3D_Algo_i.hxx
 //  Author : Paul RASCLE, EDF
index e567a15d62ab8ad0d70acda5ff7ea66764e27d15..13caf98e0c2b54275bd82503d8fa20259fe550a6 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : SMESH_Algo_i.cxx
 //  Author : Paul RASCLE, EDF
index cfcfc53472c3e98ebc5e9049c58b428b30dd595f..34491582d94365717ef5377ed865bc2a732c2f67 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : SMESH_Algo_i.hxx
 //  Author : Paul RASCLE, EDF
index ad409b786361820fdeee672c71dc1fbaae27c42b..0544cb091f48852dcc670d7e6c29895f10e7f24b 100644 (file)
@@ -1,30 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
-//
-// File    : SMESH_Gen_i_DumpPython.cxx
-// Created : Thu Mar 24 17:17:59 2005
-// Author  : Julia DOROVSKIKH
-// Module  : SMESH
-// $Header : $
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+//  File    : SMESH_DumpPython.cxx
+//  Created : Thu Mar 24 17:17:59 2005
+//  Author  : Julia DOROVSKIKH
+//  Module  : SMESH
+
 #include "SMESH_PythonDump.hxx"
 #include "SMESH_Gen_i.hxx"
 #include "SMESH_Filter_i.hxx"
@@ -33,6 +32,7 @@
 
 #include <TColStd_HSequenceOfInteger.hxx>
 #include <TCollection_AsciiString.hxx>
+#include <SMESH_Comment.hxx>
 
 
 #ifdef _DEBUG_
@@ -51,8 +51,17 @@ namespace SMESH
 
   size_t TPythonDump::myCounter = 0;
 
+  TVar::TVar(CORBA::Double value):myVals(1) { myVals[0] = SMESH_Comment(value); }
+  TVar::TVar(CORBA::Long   value):myVals(1) { myVals[0] = SMESH_Comment(value); }
+  TVar::TVar(CORBA::Short  value):myVals(1) { myVals[0] = SMESH_Comment(value); }
+  TVar::TVar(const SMESH::double_array& value):myVals(value.length())
+  {
+    for ( size_t i = 0; i < value.length(); i++)
+      myVals[i] = SMESH_Comment(value[i]);
+  }
+
   TPythonDump::
-  TPythonDump()
+  TPythonDump():myVarsCounter(0)
   {
     ++myCounter;
   }
@@ -65,48 +74,82 @@ namespace SMESH
       TCollection_AsciiString aCollection(Standard_CString(aString.c_str()));
       SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy();
       if(!aStudy->_is_nil() && !aCollection.IsEmpty()){
-       aSMESHGen->AddToPythonScript(aStudy->StudyId(),aCollection);
-       if(MYDEBUG) MESSAGE(aString);
+        aSMESHGen->AddToPythonScript(aStudy->StudyId(),aCollection);
+        if(MYDEBUG) MESSAGE(aString);
+        aSMESHGen->UpdateParameters(""); // prevent misuse of already treated variables
       }
     }
   }
 
-  TPythonDump& 
+  TPythonDump& //!< to store a variable value
+  TPythonDump::
+  operator<<(const TVar& theVarValue)
+  {
+    if ( theVarValue.myVals.empty() ) return *this;
+
+    const std::vector< std::string >& varNames = SMESH_Gen_i::GetSMESHGen()->GetLastParameters();
+    if ( theVarValue.myVals.size() > 1 )
+    {
+      myStream << "[ ";
+      for ( size_t i = 1; i <= theVarValue.myVals.size(); ++i )
+      {
+        if ( myVarsCounter < varNames.size() && !varNames[ myVarsCounter ].empty() )
+          myStream << TVar::Quote() << varNames[ myVarsCounter ] << TVar::Quote();
+        else
+          myStream << theVarValue.myVals[i-1];
+        if ( i < theVarValue.myVals.size() )
+          myStream << ", ";
+        ++myVarsCounter;
+      }
+      myStream << " ]";
+    }
+    else
+    {
+      if ( myVarsCounter < varNames.size() && !varNames[ myVarsCounter ].empty() )
+        myStream << TVar::Quote() << varNames[ myVarsCounter ] << TVar::Quote();
+      else
+        myStream << theVarValue.myVals[0];
+      ++myVarsCounter;
+    }
+    return *this;
+  }
+
+  TPythonDump&
   TPythonDump::
   operator<<(long int theArg){
     myStream<<theArg;
     return *this;
   }
 
-  TPythonDump& 
+  TPythonDump&
   TPythonDump::
   operator<<(int theArg){
     myStream<<theArg;
     return *this;
   }
 
-  TPythonDump& 
+  TPythonDump&
   TPythonDump::
   operator<<(double theArg){
     myStream<<theArg;
     return *this;
   }
 
-  TPythonDump& 
+  TPythonDump&
   TPythonDump::
   operator<<(float theArg){
     myStream<<theArg;
     return *this;
   }
 
-  TPythonDump& 
+  TPythonDump&
   TPythonDump::
   operator<<(const void* theArg){
     myStream<<theArg;
     return *this;
   }
 
-  TPythonDump& 
+  TPythonDump&
   TPythonDump::
   operator<<(const char* theArg){
     if ( theArg )
@@ -114,23 +157,48 @@ namespace SMESH
     return *this;
   }
 
-  TPythonDump& 
+  TPythonDump&
   TPythonDump::
   operator<<(const SMESH::ElementType& theArg)
   {
     myStream<<"SMESH.";
     switch(theArg){
-    case ALL:   myStream<<"ALL";break;
-    case NODE:  myStream<<"NODE";break;
-    case EDGE:  myStream<<"EDGE";break;
-    case FACE:  myStream<<"FACE";break;
-    case VOLUME:myStream<<"VOLUME";break;
+    case ALL:    myStream<<"ALL";    break;
+    case NODE:   myStream<<"NODE";   break;
+    case EDGE:   myStream<<"EDGE";   break;
+    case FACE:   myStream<<"FACE";   break;
+    case VOLUME: myStream<<"VOLUME"; break;
+    case ELEM0D: myStream<<"ELEM0D"; break;
+    case BALL:   myStream<<"BALL";   break;
+    default:     myStream<<"__UNKNOWN__ElementType: " << theArg;
+    }
+    return *this;
+  }
+
+  TPythonDump&
+  TPythonDump::
+  operator<<(const SMESH::GeometryType& theArg)
+  {
+    myStream<<"SMESH.";
+    switch(theArg){
+    case Geom_POINT:      myStream<<"Geom_POINT";      break;
+    case Geom_EDGE:       myStream<<"Geom_EDGE";       break;
+    case Geom_TRIANGLE:   myStream<<"Geom_TRIANGLE";   break;
+    case Geom_QUADRANGLE: myStream<<"Geom_QUADRANGLE"; break;
+    case Geom_POLYGON:    myStream<<"Geom_POLYGON";    break;
+    case Geom_TETRA:      myStream<<"Geom_TETRA";      break;
+    case Geom_PYRAMID:    myStream<<"Geom_PYRAMID";    break;
+    case Geom_HEXA:       myStream<<"Geom_HEXA";       break;
+    case Geom_PENTA:      myStream<<"Geom_PENTA";      break;
+    case Geom_POLYHEDRA:  myStream<<"Geom_POLYHEDRA";  break;
+    case Geom_BALL:       myStream<<"Geom_BALL";       break;
+    default:    myStream<<"__UNKNOWN__GeometryType: " << theArg;
     }
     return *this;
   }
 
   template<class TArray>
-  void DumpArray(const TArray& theArray, std::ostringstream & theStream)
+  void DumpArray(const TArray& theArray, TPythonDump & theStream)
   {
     theStream << "[ ";
     for (int i = 1; i <= theArray.length(); i++) {
@@ -141,21 +209,34 @@ namespace SMESH
     theStream << " ]";
   }
 
-  TPythonDump& 
+  TPythonDump&
   TPythonDump::operator<<(const SMESH::long_array& theArg)
   {
-    DumpArray( theArg, myStream );
+    DumpArray( theArg, *this );
     return *this;
   }
 
-  TPythonDump& 
+  TPythonDump&
   TPythonDump::operator<<(const SMESH::double_array& theArg)
   {
-    DumpArray( theArg, myStream );
+    DumpArray( theArg, *this );
     return *this;
   }
 
-  TPythonDump& 
+  TPythonDump&
+  TPythonDump::operator<<(const SMESH::string_array& theArray)
+  {
+    myStream << "[ ";
+    for (int i = 1; i <= theArray.length(); i++) {
+      myStream << "'" << theArray[i-1] << "'";
+      if ( i < theArray.length() )
+        myStream << ", ";
+    }
+    myStream << " ]";
+    return *this;
+  }
+
+  TPythonDump&
   TPythonDump::
   operator<<(SALOMEDS::SObject_ptr aSObject)
   {
@@ -166,15 +247,16 @@ namespace SMESH
     return *this;
   }
 
-  TPythonDump& 
+  TPythonDump&
   TPythonDump::
   operator<<(CORBA::Object_ptr theArg)
   {
     SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
-    SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy();
+    SALOMEDS::Study_var aStudy = aSMESHGen->GetCurrentStudy();
     SALOMEDS::SObject_var aSObject = SMESH_Gen_i::ObjectToSObject(aStudy,theArg);
     if(!aSObject->_is_nil()) {
-      myStream << aSObject->GetID();
+      CORBA::String_var id = aSObject->GetID();
+      myStream << id;
     } else if ( !CORBA::is_nil(theArg)) {
       if ( aSMESHGen->CanPublishInStudy( theArg )) // not published SMESH object
         myStream << "smeshObj_" << size_t(theArg);
@@ -186,7 +268,44 @@ namespace SMESH
     return *this;
   }
 
-  TPythonDump& 
+  TPythonDump&
+  TPythonDump::
+  operator<<(SMESH::SMESH_Hypothesis_ptr theArg)
+  {
+    SALOMEDS::Study_var aStudy = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy();
+    SALOMEDS::SObject_var aSObject = SMESH_Gen_i::ObjectToSObject(aStudy,theArg);
+    if(aSObject->_is_nil() && !CORBA::is_nil(theArg))
+      myStream << "hyp_" << theArg->GetId();
+    else
+      *this << CORBA::Object_ptr( theArg );
+    return *this;
+  }
+
+  TPythonDump&
+  TPythonDump::
+  operator<<(SMESH::SMESH_IDSource_ptr theArg)
+  {
+    if ( CORBA::is_nil( theArg ) )
+      return *this << "None";
+    SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
+    SALOMEDS::Study_var aStudy = aSMESHGen->GetCurrentStudy();
+    SALOMEDS::SObject_var aSObject = SMESH_Gen_i::ObjectToSObject(aStudy,theArg);
+    if(!aSObject->_is_nil())
+      return *this << aSObject;
+    if ( SMESH::Filter_i* filter = SMESH::DownCast<SMESH::Filter_i*>( theArg ))
+      return *this << filter;
+    SMESH::SMESH_Mesh_var mesh = theArg->GetMesh();
+    if ( !theArg->_is_equivalent( mesh ))
+    {
+      SMESH::long_array_var anElementsId = theArg->GetIDs();
+      SMESH::array_of_ElementType_var types =  theArg->GetTypes();
+      SMESH::ElementType type = types->length() ? types[0] : SMESH::ALL;
+      return *this << mesh << ".GetIDSource(" << anElementsId << ", " << type << ")";
+    }
+    return *this;
+  }
+
+  TPythonDump&
   TPythonDump::
   operator<<(SMESH::FilterLibrary_i* theArg)
   {
@@ -194,7 +313,7 @@ namespace SMESH
     return *this;
   }
 
-  TPythonDump& 
+  TPythonDump&
   TPythonDump::
   operator<<(SMESH::FilterManager_i* theArg)
   {
@@ -202,7 +321,7 @@ namespace SMESH
     return *this;
   }
 
-  TPythonDump& 
+  TPythonDump&
   TPythonDump::
   operator<<(SMESH::Filter_i* theArg)
   {
@@ -210,47 +329,69 @@ namespace SMESH
     return *this;
   }
 
-  TPythonDump& 
+  TPythonDump&
   TPythonDump::
   operator<<(SMESH::Functor_i* theArg)
   {
     if ( theArg ) {
       FunctorType aFunctorType = theArg->GetFunctorType();
       switch(aFunctorType){
-      case FT_AspectRatio:      myStream<< "anAspectRatio";     break;
-      case FT_AspectRatio3D:    myStream<< "anAspectRatio3D";   break;
-      case FT_Warping:          myStream<< "aWarping";          break;
-      case FT_MinimumAngle:     myStream<< "aMinimumAngle";     break;
-      case FT_Taper:            myStream<< "aTaper";            break;
-      case FT_Skew:             myStream<< "aSkew";             break;
-      case FT_Area:             myStream<< "aArea";             break;
-      case FT_FreeBorders:      myStream<< "aFreeBorders";      break;
-      case FT_FreeEdges:        myStream<< "aFreeEdges";        break;
-      case FT_FreeNodes:        myStream<< "aFreeNodes";        break;
-      case FT_MultiConnection:  myStream<< "aMultiConnection";  break;
-      case FT_MultiConnection2D:myStream<< "aMultiConnection2D";break;
-      case FT_Length:           myStream<< "aLength";           break;
-      case FT_Length2D:         myStream<< "aLength";           break;
-      case FT_BelongToGeom:     myStream<< "aBelongToGeom";     break;
-      case FT_BelongToPlane:    myStream<< "aBelongToPlane";    break;
-      case FT_BelongToCylinder: myStream<< "aBelongToCylinder"; break;
-      case FT_BelongToGenSurface:myStream<<"aBelongToGenSurface";break;
-      case FT_LyingOnGeom:      myStream<< "aLyingOnGeom";      break;
-      case FT_RangeOfIds:       myStream<< "aRangeOfIds";       break;
-      case FT_BadOrientedVolume:myStream<< "aBadOrientedVolume";break;
-      case FT_LessThan:         myStream<< "aLessThan";         break;
-      case FT_MoreThan:         myStream<< "aMoreThan";         break;
-      case FT_EqualTo:          myStream<< "anEqualTo";         break;
-      case FT_LogicalNOT:       myStream<< "aLogicalNOT";       break;
-      case FT_LogicalAND:       myStream<< "aLogicalAND";       break;
-      case FT_LogicalOR:        myStream<< "aLogicalOR";        break;
-      case FT_Undefined:        myStream<< "anUndefined";       break;
+      case FT_AspectRatio:           myStream<< "anAspectRatio";          break;
+      case FT_AspectRatio3D:         myStream<< "anAspectRatio3D";        break;
+      case FT_Warping:               myStream<< "aWarping";               break;
+      case FT_MinimumAngle:          myStream<< "aMinimumAngle";          break;
+      case FT_Taper:                 myStream<< "aTaper";                 break;
+      case FT_Skew:                  myStream<< "aSkew";                  break;
+      case FT_Area:                  myStream<< "aArea";                  break;
+      case FT_Volume3D:              myStream<< "aVolume3D";              break;
+      case FT_MaxElementLength2D:    myStream<< "aMaxElementLength2D";    break;
+      case FT_MaxElementLength3D:    myStream<< "aMaxElementLength3D";    break;
+      case FT_FreeBorders:           myStream<< "aFreeBorders";           break;
+      case FT_FreeEdges:             myStream<< "aFreeEdges";             break;
+      case FT_FreeNodes:             myStream<< "aFreeNodes";             break;
+      case FT_FreeFaces:             myStream<< "aFreeFaces";             break;
+      case FT_MultiConnection:       myStream<< "aMultiConnection";       break;
+      case FT_MultiConnection2D:     myStream<< "aMultiConnection2D";     break;
+      case FT_Length:                myStream<< "aLength";                break;
+      case FT_Length2D:              myStream<< "aLength2D";              break;
+      case FT_BelongToGeom:          myStream<< "aBelongToGeom";          break;
+      case FT_BelongToPlane:         myStream<< "aBelongToPlane";         break;
+      case FT_BelongToCylinder:      myStream<< "aBelongToCylinder";      break;
+      case FT_BelongToGenSurface:    myStream<< "aBelongToGenSurface";    break;
+      case FT_LyingOnGeom:           myStream<< "aLyingOnGeom";           break;
+      case FT_CoplanarFaces:         myStream<< "aCoplanarFaces";         break;
+      case FT_RangeOfIds:            myStream<< "aRangeOfIds";            break;
+      case FT_BadOrientedVolume:     myStream<< "aBadOrientedVolume";     break;
+      case FT_BareBorderVolume:      myStream<< "aBareBorderVolume";      break;
+      case FT_BareBorderFace:        myStream<< "aBareBorderFace";        break;
+      case FT_OverConstrainedVolume: myStream<< "aOverConstrainedVolume"; break;
+      case FT_OverConstrainedFace:   myStream<< "aOverConstrainedFace";   break;
+      case FT_LinearOrQuadratic:     myStream<< "aLinearOrQuadratic";     break;
+      case FT_GroupColor:            myStream<< "aGroupColor";            break;
+      case FT_ElemGeomType:          myStream<< "anElemGeomType";         break;
+      case FT_LessThan:              myStream<< "aLessThan";              break;
+      case FT_MoreThan:              myStream<< "aMoreThan";              break;
+      case FT_EqualTo:               myStream<< "anEqualTo";              break;
+      case FT_LogicalNOT:            myStream<< "aLogicalNOT";            break;
+      case FT_LogicalAND:            myStream<< "aLogicalAND";            break;
+      case FT_LogicalOR:             myStream<< "aLogicalOR";             break;
+      case FT_Undefined:
+      default:                       myStream<< "anUndefined";            break;
       }
       myStream<<theArg;
     }
     return *this;
   }
 
+  TPythonDump&
+  TPythonDump::
+  operator<<(SMESH::Measurements_i* theArg)
+  {
+    myStream<<"aMeasurements";
+    return *this;
+  }
+
+
   TPythonDump& TPythonDump:: operator<<(SMESH_Gen_i* theArg)
   {
     myStream << SMESHGenName(); return *this;
@@ -279,41 +420,48 @@ namespace SMESH
 
   TPythonDump& TPythonDump::operator<<(const SMESH::AxisStruct & theAxis)
   {
-    myStream << "SMESH.AxisStruct( "
-             << theAxis.x  << ", "
-             << theAxis.y  << ", "
-             << theAxis.z  << ", "
-             << theAxis.vx << ", "
-             << theAxis.vy << ", "
-             << theAxis.vz << " )";
+    *this << "SMESH.AxisStruct( "
+          << TVar( theAxis.x  ) << ", "
+          << TVar( theAxis.y  ) << ", "
+          << TVar( theAxis.z  ) << ", "
+          << TVar( theAxis.vx ) << ", "
+          << TVar( theAxis.vy ) << ", "
+          << TVar( theAxis.vz ) << " )";
     return *this;
   }
 
   TPythonDump& TPythonDump::operator<<(const SMESH::DirStruct & theDir)
   {
     const SMESH::PointStruct & P = theDir.PS;
-    myStream << "SMESH.DirStruct( SMESH.PointStruct ( "
-             << P.x  << ", "
-             << P.y  << ", "
-             << P.z  << " ))";
+    *this << "SMESH.DirStruct( SMESH.PointStruct ( "
+          << TVar( P.x ) << ", "
+          << TVar( P.y ) << ", "
+          << TVar( P.z ) << " ))";
     return *this;
   }
 
-  TPythonDump& TPythonDump::operator<<(const SMESH::ListOfGroups * theList){
-    if(theList && theList->length() > 0 ) {
-      SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
-      SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy();
-      myStream << "[";
-      int aListLen = theList->length();
-      for(int i = 0 ; i < aListLen; i++){
-        SALOMEDS::SObject_var aSObject = SMESH_Gen_i::ObjectToSObject(aStudy,(*theList)[i]);
-        if(!aSObject->_is_nil()) {
-          myStream << aSObject->GetID();
-          i < (aListLen - 1) ? myStream<<", " : myStream<<"]";
-        }
-        
-      }
-    }
+  TPythonDump& TPythonDump::operator<<(const SMESH::PointStruct & P)
+  {
+    *this << "SMESH.PointStruct ( "
+          << TVar( P.x ) << ", "
+          << TVar( P.y ) << ", "
+          << TVar( P.z ) << " )";
+    return *this;
+  }
+
+  TPythonDump& TPythonDump::operator<<(const SMESH::ListOfGroups& theList)
+  {
+    DumpArray( theList, *this );
+    return *this;
+  }
+  TPythonDump& TPythonDump::operator<<(const SMESH::ListOfGroups * theList)
+  {
+    DumpArray( *theList, *this );
+    return *this;
+  }
+  TPythonDump& TPythonDump::operator<<(const SMESH::ListOfIDSources& theList)
+  {
+    DumpArray( theList, *this );
     return *this;
   }
 
@@ -322,10 +470,10 @@ namespace SMESH
 
   //================================================================================
   /*!
-     * \brief Return marker of long string literal beginning
-      * \param type - a name of functionality producing the string literal 
-      * \retval TCollection_AsciiString - the marker string to be written into
-      * a raw python script
+   * \brief Return marker of long string literal beginning
+   * \param type - a name of functionality producing the string literal
+   * \retval TCollection_AsciiString - the marker string to be written into
+   * a raw python script
    */
   //================================================================================
 
@@ -359,7 +507,7 @@ namespace SMESH
       * \param theLongString - the retrieved literal
       * \param theStringType - a name of functionality produced the literal
       * \retval bool - true if a string literal found
-     * 
+     *
      * The literal is removed from theText; theFrom points position right after
      * the removed literal
    */
@@ -413,11 +561,31 @@ namespace SMESH
 }
 
 //=======================================================================
-//function : DumpPython
+//function : RemoveTabulation
 //purpose  : 
 //=======================================================================
+void RemoveTabulation( TCollection_AsciiString& theScript )
+{
+  std::string aString( theScript.ToCString() );
+  std::string::size_type aPos = 0;
+  while( aPos < aString.length() )
+  {
+    aPos = aString.find( "\n\t", aPos );
+    if( aPos == std::string::npos )
+      break;
+    aString.replace( aPos, 2, "\n" );
+    aPos++;
+  }
+  theScript = aString.c_str();
+}
+
+//=======================================================================
+//function : DumpPython
+//purpose  :
+//=======================================================================
 Engines::TMPFile* SMESH_Gen_i::DumpPython (CORBA::Object_ptr theStudy,
                                            CORBA::Boolean isPublished,
+                                           CORBA::Boolean isMultiFile,
                                            CORBA::Boolean& isValidScript)
 {
   SALOMEDS::Study_var aStudy = SALOMEDS::Study::_narrow(theStudy);
@@ -456,22 +624,21 @@ Engines::TMPFile* SMESH_Gen_i::DumpPython (CORBA::Object_ptr theStudy,
   TCollection_AsciiString aSavedTrace (oldValue);
 
   // Add trace of API methods calls and replace study entries by names
-  TCollection_AsciiString aScript =
-    "### This file is generated by SALOME automatically by dump python functionality of SMESH component\n\n";
-  aScript += DumpPython_impl(aStudy, aMap, aMapNames,
-                             isPublished, isValidScript, aSavedTrace);
+  TCollection_AsciiString aScript;
+  aScript += DumpPython_impl(aStudy, aMap, aMapNames, isPublished, isMultiFile,
+                             myIsHistoricalPythonDump, isValidScript, aSavedTrace);
 
-  int aLen = aScript.Length(); 
+  int aLen = aScript.Length();
   unsigned char* aBuffer = new unsigned char[aLen+1];
   strcpy((char*)aBuffer, aScript.ToCString());
 
   CORBA::Octet* anOctetBuf =  (CORBA::Octet*)aBuffer;
-  Engines::TMPFile_var aStreamFile = new Engines::TMPFile(aLen+1, aLen+1, anOctetBuf, 1); 
+  Engines::TMPFile_var aStreamFile = new Engines::TMPFile(aLen+1, aLen+1, anOctetBuf, 1);
 
   bool hasNotPublishedObjects = aScript.Location( NotPublishedObjectName(), 1, aLen);
   isValidScript = isValidScript && !hasNotPublishedObjects;
 
-  return aStreamFile._retn(); 
+  return aStreamFile._retn();
 }
 
 //=============================================================================
@@ -502,7 +669,7 @@ void SMESH_Gen_i::RemoveLastFromPythonScript (int theStudyID)
 
 //=======================================================================
 //function : SavePython
-//purpose  : 
+//purpose  :
 //=======================================================================
 void SMESH_Gen_i::SavePython (SALOMEDS::Study_ptr theStudy)
 {
@@ -555,11 +722,11 @@ Handle(TColStd_HSequenceOfInteger) FindEntries (TCollection_AsciiString& theStri
     int c = (int)arr[i];
     j = i+1;
     if ( isdigit( c )) { //Is digit?
+
       isFound = Standard_False;
       while((j < aLen) && ( isdigit(c) || c == ':' )) { //Check if it is an entry
-       c = (int)arr[j++];  
-       if(c == ':') isFound = Standard_True;
+        c = (int)arr[j++];
+        if(c == ':') isFound = Standard_True;
       }
 
       if (isFound) {
@@ -595,20 +762,28 @@ namespace {
     const TCollection_AsciiString allowedChars =
       "qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM0987654321_";
     bool isValidName = true;
-    int p=1; // replace not allowed chars with underscore
+    int nbUnderscore = 0;
+    int p=1; // replace not allowed chars by underscore
     while (p <= aName.Length() &&
            (p = aName.FirstLocationNotInSet(allowedChars, p, aName.Length())))
     {
       if ( p == 1 || p == aName.Length() || aName.Value(p-1) == '_')
-        aName.Remove( p, 1 ); // remove double _ and from the start and the end
+        aName.Remove( p, 1 ); // remove double _ from the start and the end
       else
-        aName.SetValue(p, '_');
+        aName.SetValue(p, '_'), nbUnderscore++;
       isValidName = false;
     }
     if ( aName.IsIntegerValue() ) { // aName must not start with a digit
       aName.Insert( 1, 'a' );
       isValidName = false;
     }
+    // shorten names like CartesianParameters3D_400_400_400_1000000_1
+    if ( aName.Length() > 20 && nbUnderscore > 2 )
+    {
+      p = aName.Location( "_", 20, aName.Length());
+      if ( p > 1 )
+        aName.Trunc( p-1 );
+    }
     return isValidName;
   }
 }
@@ -619,10 +794,12 @@ namespace {
  */
 //=============================================================================
 TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
-                        (SALOMEDS::Study_ptr theStudy, 
+                        (SALOMEDS::Study_ptr theStudy,
                          Resource_DataMapOfAsciiStringAsciiString& theObjectNames,
                          Resource_DataMapOfAsciiStringAsciiString& theNames,
-                         bool isPublished, 
+                         bool isPublished,
+                         bool isMultiFile,
+                         bool isHistoricalDump,
                          bool& aValidScript,
                          const TCollection_AsciiString& theSavedTrace)
 {
@@ -634,8 +811,11 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
   TCollection_AsciiString anOldGen( SMESH::TPythonDump::SMESHGenName() );
 
   TCollection_AsciiString aScript;
-  aScript = "def RebuildData(theStudy):\n\t";
+  if( isMultiFile )
+    aScript += "def RebuildData(theStudy):";
+  aScript += "\n\t";
   aScript += helper + "aFilterManager = " + aSMESHGen + ".CreateFilterManager()\n\t";
+  aScript += helper + "aMeasurements = " + aSMESHGen + ".CreateMeasurements()\n\t";
   if ( isPublished )
     aScript += aSMESHGen + ".SetCurrentStudy(theStudy)";
   else
@@ -687,13 +867,22 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
   // Some objects are wrapped with python classes and
   // Resource_DataMapOfAsciiStringAsciiString holds methods returning wrapped objects
   Resource_DataMapOfAsciiStringAsciiString anEntry2AccessorMethod;
-  aScript = SMESH_2smeshpy::ConvertScript( aScript, anEntry2AccessorMethod, theObjectNames );
+  if ( !getenv("NO_2smeshpy_conversion"))
+    aScript = SMESH_2smeshpy::ConvertScript( aScript, anEntry2AccessorMethod,
+                                             theObjectNames, theStudy, isHistoricalDump );
+
+  // Replace characters used instead of quote marks to quote notebook variables
+  {
+    int pos = 1;
+    while (( pos = aScript.Location( 1, SMESH::TVar::Quote(), pos, aScript.Length() )))
+      aScript.SetValue( pos, '"' );
+  }
 
   // Find entries to be replaced by names
   Handle(TColStd_HSequenceOfInteger) aSeq = FindEntries(aScript);
   Standard_Integer aLen = aSeq->Length();
 
-  if (aLen == 0)
+  if (aLen == 0 && isMultiFile)
     return aScript;
 
   // Replace entries by the names
@@ -703,7 +892,7 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
   Standard_Integer objectCounter = 0, aStart = 1, aScriptLength = aScript.Length();
   TCollection_AsciiString anUpdatedScript, anEntry, aName, aBaseName("smeshObj_");
 
-  // Collect names of GEOM objects to exclude same names for SMESH objects
+  // Collect names of GEOM objects to exclude same names of SMESH objects
   GEOM::string_array_var aGeomNames = geom->GetAllDumpNames();
   int ign = 0, nbgn = aGeomNames->length();
   for (; ign < nbgn; ign++) {
@@ -757,67 +946,23 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
   }
 
   // set initial part of aSript
-  TCollection_AsciiString initPart = "import salome, SMESH\n";
-  initPart += helper + "import " + aSmeshpy + "\n\n";
-  if ( importGeom )
+  TCollection_AsciiString initPart = "import ";
+  if ( isMultiFile )
+    initPart += helper + "salome, ";
+  initPart += aSmeshpy + ", SMESH, SALOMEDS\n";
+  if ( importGeom && isMultiFile )
   {
-    initPart += ("## import GEOM dump file ## \n"
+    initPart += ("\n## import GEOM dump file ## \n"
                  "import string, os, sys, re\n"
                  "sys.path.insert( 0, os.path.dirname(__file__) )\n"
-                 "exec(\"from \"+re.sub(\"SMESH$\",\"GEOM\",__name__)+\" import *\")\n\n");
+                 "exec(\"from \"+re.sub(\"SMESH$\",\"GEOM\",__name__)+\" import *\")\n");
   }
   anUpdatedScript.Insert ( 1, initPart );
 
   // add final part of aScript
-  if (aSeq->Value(aLen) < aScriptLength)
+  if (aLen && aSeq->Value(aLen) < aScriptLength)
     anUpdatedScript += aScript.SubString(aSeq->Value(aLen) + 1, aScriptLength);
 
-
-  //SMESH_Gen_i* aSMESHGenI = SMESH_Gen_i::GetSMESHGen();
-  if( !CORBA::is_nil(theStudy) )
-  {
-    SALOMEDS::SObject_var aComp = theStudy->FindComponent(ComponentDataType());
-    if( !CORBA::is_nil(aComp) )
-    {
-      SALOMEDS::ChildIterator_var Itr = theStudy->NewChildIterator(aComp);
-      for( Itr->InitEx(true); Itr->More(); Itr->Next() )
-      {
-       SALOMEDS::SObject_var aSObj = Itr->Value();
-       CORBA::String_var aName = aSObj->GetName();
-
-       SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( SMESH_Gen_i::SObjectToObject( aSObj ) );
-       if( !CORBA::is_nil(aMesh) )
-       {
-         bool isAutoColor = aMesh->GetAutoColor();
-         if( isAutoColor )
-         {
-           anUpdatedScript += "\n\t";
-           anUpdatedScript += (char*)aName.in();
-           anUpdatedScript += ".SetAutoColor(1)";
-         }
-       }
-       SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( SMESH_Gen_i::SObjectToObject( aSObj ) );
-       if( !CORBA::is_nil(aGroup) )
-       {
-         SALOMEDS::Color aColor = aGroup->GetColor();
-         if ( aColor.R > 0 || aColor.G > 0 || aColor.B > 0 )
-         {
-           anUpdatedScript += "\n\t";
-           anUpdatedScript += (char*)aName.in();
-           anUpdatedScript += ".SetColor(SALOMEDS.Color(";
-           anUpdatedScript += aColor.R;
-           anUpdatedScript += ",";
-           anUpdatedScript += aColor.G;
-           anUpdatedScript += ",";
-           anUpdatedScript += aColor.B;
-           anUpdatedScript += "))";
-         }
-       }
-      }
-    }
-  }
-
   // Remove removed objects
   if ( seqRemoved.Length() > 0 ) {
     anUpdatedScript += "\n\t## some objects were removed";
@@ -859,8 +1004,10 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
       anUpdatedScript += helper + ", '" + aGUIName + "')";
     }
   }
-  anUpdatedScript += "\n\tif salome.sg.hasDesktop():";
-  anUpdatedScript += "\n\t\tsalome.sg.updateObjBrowser(0)";
+
+  // Issue 0021249: removed (a similar block is dumped by SALOMEDSImpl_Study)
+  //anUpdatedScript += "\n\tif salome.sg.hasDesktop():";
+  //anUpdatedScript += "\n\t\tsalome.sg.updateObjBrowser(0)";
 
   // -----------------------------------------------------------------
   // store visual properties of displayed objects
@@ -876,7 +1023,13 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
       CORBA::string_free(script);
     }
   }
-  anUpdatedScript += "\n\n\tpass\n";
+
+  if( isMultiFile )
+    anUpdatedScript += "\n\tpass";
+  anUpdatedScript += "\n";
+
+  if( !isMultiFile ) // remove unnecessary tabulation
+    RemoveTabulation( anUpdatedScript );
 
   // -----------------------------------------------------------------
   // put string literals describing patterns into separate functions
@@ -916,7 +1069,18 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl
       do functionName = aFunctionType + "_" + ( nb++ ) + "()";
       while ( !functionNameSet.insert( functionName.ToCString() ).second );
 
-      anUpdatedScript += helper + "\n\ndef " + functionName + aLongString; // define function
+      // define function
+      TCollection_AsciiString funDef = helper + "def " + functionName + aLongString;
+      if ( isMultiFile )
+      {
+        anUpdatedScript += helper + "\n\n" + funDef;
+      }
+      else
+      {
+        funDef += "\n\n";
+        anUpdatedScript.Insert( 1, funDef);
+        where += funDef.Length();
+      }
     }
     anUpdatedScript.InsertBefore( where, functionName ); // call function
   }
index 189e6cbcc193c6e6c80b811b3957c6cea0870f68..fc5314b8cbf339ae8721f9bd3ab80bd492256889 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : SMESH_Filter_i.cxx
 //  Author : Alexey Petrov, OCC
@@ -32,6 +33,7 @@
 #include "SMDS_Mesh.hxx"
 #include "SMDS_MeshNode.hxx"
 #include "SMDS_MeshElement.hxx"
+#include "SMDS_ElemIterator.hxx"
 
 #include "SMESHDS_Mesh.hxx"
 
@@ -122,7 +124,7 @@ void Controls::BelongToGeom::init()
 {
   if (!myMeshDS || myShape.IsNull()) return;
 
-  // is subshape of main shape?
+  // is sub-shape of main shape?
   TopoDS_Shape aMainShape = myMeshDS->ShapeToMesh();
   if (aMainShape.IsNull()) {
     myIsSubshape = false;
@@ -278,7 +280,7 @@ void Controls::LyingOnGeom::init()
 {
   if (!myMeshDS || myShape.IsNull()) return;
 
-  // is subshape of main shape?
+  // is sub-shape of main shape?
   TopoDS_Shape aMainShape = myMeshDS->ShapeToMesh();
   if (aMainShape.IsNull()) {
     myIsSubshape = false;
@@ -485,21 +487,16 @@ static TopoDS_Shape getShapeByName( const char* theName )
 {
   if ( theName != 0 )
   {
-    SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
-    SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy();
-    if (!CORBA::is_nil(aStudy))
+    SMESH_Gen_i* aSMESHGen     = SMESH_Gen_i::GetSMESHGen();
+    SALOMEDS::Study_var aStudy = aSMESHGen->GetCurrentStudy();
+    if ( !aStudy->_is_nil() )
     {
-      SALOMEDS::Study::ListOfSObject_var aList =
-        aStudy->FindObjectByName( theName, "GEOM" );
+      SALOMEDS::Study::ListOfSObject_var aList = aStudy->FindObjectByName( theName, "GEOM" );
       if ( aList->length() > 0 )
       {
-        GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow( aList[ 0 ]->GetObject() );
-        if ( !aGeomObj->_is_nil() )
-        {
-          GEOM::GEOM_Gen_ptr aGEOMGen = SMESH_Gen_i::GetGeomEngine();
-          TopoDS_Shape aLocShape = aSMESHGen->GetShapeReader()->GetShape( aGEOMGen, aGeomObj );
-          return aLocShape;
-        }
+        CORBA::Object_var        anObj = aList[ 0 ]->GetObject();
+        GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow( anObj );
+        return aSMESHGen->GeomObjectToShape( aGeomObj );
       }
     }
   }
@@ -508,48 +505,35 @@ static TopoDS_Shape getShapeByName( const char* theName )
 
 static TopoDS_Shape getShapeByID (const char* theID)
 {
-  if (theID != 0 && theID != "") {
-    SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
-    SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy();
-    if (aStudy != 0) {
+  if ( theID && strlen( theID ) > 0 ) {
+    SMESH_Gen_i*     aSMESHGen = SMESH_Gen_i::GetSMESHGen();
+    SALOMEDS::Study_var aStudy = aSMESHGen->GetCurrentStudy();
+    if ( !aStudy->_is_nil() ) {
       SALOMEDS::SObject_var aSObj = aStudy->FindObjectID(theID);
-      SALOMEDS::GenericAttribute_var anAttr;
-      if (!aSObj->_is_nil() && aSObj->FindAttribute(anAttr, "AttributeIOR")) {
-        SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
-        CORBA::String_var aVal = anIOR->Value();
-        CORBA::Object_var obj = aStudy->ConvertIORToObject(aVal);
+      if ( !aSObj->_is_nil() ) {
+        CORBA::Object_var          obj = aSObj->GetObject();
         GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(obj);
-      
-        if (!aGeomObj->_is_nil()) {
-          GEOM::GEOM_Gen_ptr aGEOMGen = SMESH_Gen_i::GetGeomEngine();
-          TopoDS_Shape aLocShape = aSMESHGen->GetShapeReader()->GetShape( aGEOMGen, aGeomObj );
-          return aLocShape;
-        }
+        return aSMESHGen->GeomObjectToShape( aGeomObj );
       }
     }
   }
   return TopoDS_Shape();
 }
 
-static char* getShapeNameByID (const char* theID)
+static std::string getShapeNameByID (const char* theID)
 {
-  char* aName = "";
-
-  if (theID != 0 && theID != "") {
-    SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
-    SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy();
-    if (aStudy != 0) {
-      //SALOMEDS::SObject_var aSObj = aStudy->FindObjectIOR( theID );
+  if ( theID && strlen( theID ) > 0 ) {
+    SMESH_Gen_i*     aSMESHGen = SMESH_Gen_i::GetSMESHGen();
+    SALOMEDS::Study_var aStudy = aSMESHGen->GetCurrentStudy();
+    if ( !aStudy->_is_nil() ) {
       SALOMEDS::SObject_var aSObj = aStudy->FindObjectID(theID);
-      SALOMEDS::GenericAttribute_var anAttr;
-      if (!aSObj->_is_nil() && aSObj->FindAttribute(anAttr, "AttributeName")) {
-        SALOMEDS::AttributeName_var aNameAttr = SALOMEDS::AttributeName::_narrow(anAttr);
-        aName = aNameAttr->Value();
+      if ( !aSObj->_is_nil() ) {
+        CORBA::String_var name = aSObj->GetName();
+        return name.in();
       }
     }
   }
-
-  return aName;
+  return "";
 }
 
 /*
@@ -570,7 +554,7 @@ Functor_i::Functor_i():
 
 Functor_i::~Functor_i()
 {
-  //TPythonDump()<<this<<".Destroy()";
+  //TPythonDump()<<this<<".UnRegister()";
 }
 
 void Functor_i::SetMesh( SMESH_Mesh_ptr theMesh )
@@ -594,6 +578,33 @@ CORBA::Double NumericalFunctor_i::GetValue( CORBA::Long theId )
   return myNumericalFunctorPtr->GetValue( theId );
 }
 
+SMESH::Histogram* NumericalFunctor_i::GetHistogram(CORBA::Short nbIntervals)
+{
+  std::vector<int> nbEvents;
+  std::vector<double> funValues;
+  std::vector<int> elements;
+  myNumericalFunctorPtr->GetHistogram(nbIntervals,nbEvents,funValues,elements);
+
+#ifdef WIN32
+  nbIntervals = CORBA::Short( min( nbEvents.size(), funValues.size() - 1));
+#else
+  nbIntervals = CORBA::Short( std::min( nbEvents.size(), funValues.size() - 1));
+#endif
+  SMESH::Histogram_var histogram = new SMESH::Histogram;
+  if ( nbIntervals > 0 )
+  {
+    histogram->length( nbIntervals );
+    for ( int i = 0; i < nbIntervals; ++i )
+    {
+      HistogramRectangle& rect = histogram[i];
+      rect.nbEvents = nbEvents[i];
+      rect.min = funValues[i];
+      rect.max = funValues[i+1];
+    }
+  }
+  return histogram._retn();
+}
+
 void NumericalFunctor_i::SetPrecision( CORBA::Long thePrecision )
 {
   myNumericalFunctorPtr->SetPrecision( thePrecision );
@@ -736,6 +747,36 @@ FunctorType Volume3D_i::GetFunctorType()
   return SMESH::FT_Volume3D;
 }
 
+/*
+  Class       : MaxElementLength2D_i
+  Description : Functor for calculating maximum length of 2D element
+*/
+MaxElementLength2D_i::MaxElementLength2D_i()
+{
+  myNumericalFunctorPtr.reset( new Controls::MaxElementLength2D() );
+  myFunctorPtr = myNumericalFunctorPtr;
+}
+
+FunctorType MaxElementLength2D_i::GetFunctorType()
+{
+  return SMESH::FT_MaxElementLength2D;
+}
+
+/*
+  Class       : MaxElementLength3D_i
+  Description : Functor for calculating maximum length of 3D element
+*/
+MaxElementLength3D_i::MaxElementLength3D_i()
+{
+  myNumericalFunctorPtr.reset( new Controls::MaxElementLength3D() );
+  myFunctorPtr = myNumericalFunctorPtr;
+}
+
+FunctorType MaxElementLength3D_i::GetFunctorType()
+{
+  return SMESH::FT_MaxElementLength3D;
+}
+
 /*
   Class       : Length_i
   Description : Functor for calculating length off edge
@@ -770,11 +811,12 @@ SMESH::Length2D::Values* Length2D_i::GetValues()
 {
   INFOS("Length2D_i::GetValues");
   SMESH::Controls::Length2D::TValues aValues;
-  myLength2DPtr->GetValues( aValues );
+  (dynamic_cast<SMESH::Controls::Length2D*>(myFunctorPtr.get()))->GetValues( aValues );
 
   long i = 0, iEnd = aValues.size();
 
   SMESH::Length2D::Values_var aResult = new SMESH::Length2D::Values(iEnd);
+  aResult->length(iEnd);
 
   SMESH::Controls::Length2D::TValues::const_iterator anIter;
   for ( anIter = aValues.begin() ; anIter != aValues.end(); anIter++, i++ )
@@ -806,6 +848,21 @@ FunctorType MultiConnection_i::GetFunctorType()
   return SMESH::FT_MultiConnection;
 }
 
+/*
+  Class       : BallDiameter_i
+  Description : Functor returning diameter of a ball element
+*/
+BallDiameter_i::BallDiameter_i()
+{
+  myNumericalFunctorPtr.reset( new Controls::BallDiameter() );
+  myFunctorPtr = myNumericalFunctorPtr;
+}
+
+FunctorType BallDiameter_i::GetFunctorType()
+{
+  return SMESH::FT_BallDiameter;
+}
+
 /*
   Class       : MultiConnection2D_i
   Description : Functor for calculating number of faces conneted to the edge
@@ -825,11 +882,12 @@ SMESH::MultiConnection2D::Values* MultiConnection2D_i::GetValues()
 {
   INFOS("MultiConnection2D_i::GetValues");
   SMESH::Controls::MultiConnection2D::MValues aValues;
-  myMulticonnection2DPtr->GetValues( aValues );
-
+  (dynamic_cast<SMESH::Controls::MultiConnection2D*>(myFunctorPtr.get()))->GetValues( aValues );
+  
   long i = 0, iEnd = aValues.size();
 
   SMESH::MultiConnection2D::Values_var aResult = new SMESH::MultiConnection2D::Values(iEnd);
+  aResult->length(iEnd);
 
   SMESH::Controls::MultiConnection2D::MValues::const_iterator anIter;
   for ( anIter = aValues.begin() ; anIter != aValues.end(); anIter++, i++ )
@@ -881,6 +939,66 @@ FunctorType BadOrientedVolume_i::GetFunctorType()
   return SMESH::FT_BadOrientedVolume;
 }
 
+/*
+  Class       : BareBorderVolume_i
+  Description : Verify whether a mesh volume has a free facet without a face on it
+*/
+BareBorderVolume_i::BareBorderVolume_i()
+{
+  Controls::PredicatePtr control( new Controls::BareBorderVolume() );
+  myFunctorPtr = myPredicatePtr = control;
+};
+
+FunctorType BareBorderVolume_i::GetFunctorType()
+{
+  return SMESH::FT_BareBorderVolume;
+}
+
+/*
+  Class       : BareBorderFace_i
+  Description : Verify whether a mesh face has a free border without an edge on it
+*/
+BareBorderFace_i::BareBorderFace_i()
+{
+  Controls::PredicatePtr control( new Controls::BareBorderFace() );
+  myFunctorPtr = myPredicatePtr = control;
+};
+
+FunctorType BareBorderFace_i::GetFunctorType()
+{
+  return SMESH::FT_BareBorderFace;
+}
+
+/*
+  Class       : OverConstrainedVolume_i
+  Description : Verify whether a mesh volume has only one facet shared with other volumes
+*/
+OverConstrainedVolume_i::OverConstrainedVolume_i()
+{
+  Controls::PredicatePtr control( new Controls::OverConstrainedVolume() );
+  myFunctorPtr = myPredicatePtr = control;
+};
+
+FunctorType OverConstrainedVolume_i::GetFunctorType()
+{
+  return SMESH::FT_OverConstrainedVolume;
+}
+
+/*
+  Class       : OverConstrainedFace_i
+  Description : Verify whether a mesh face has only one border shared with other faces
+*/
+OverConstrainedFace_i::OverConstrainedFace_i()
+{
+  Controls::PredicatePtr control( new Controls::OverConstrainedFace() );
+  myFunctorPtr = myPredicatePtr = control;
+};
+
+FunctorType OverConstrainedFace_i::GetFunctorType()
+{
+  return SMESH::FT_OverConstrainedFace;
+}
+
 /*
   Class       : BelongToGeom_i
   Description : Predicate for selection on geometrical support
@@ -943,7 +1061,7 @@ void BelongToGeom_i::SetShape( const char* theID, const char* theName )
   else
     myShapeID = 0;
 
-  if ( myShapeID && strcmp(myShapeName, getShapeNameByID(myShapeID)) == 0 )
+  if ( myShapeID && myShapeName == getShapeNameByID(myShapeID))
     myBelongToGeomPtr->SetGeom( getShapeByID(myShapeID) );
   else
     myBelongToGeomPtr->SetGeom( getShapeByName( myShapeName ) );
@@ -1028,7 +1146,7 @@ void BelongToSurface_i::SetShape( const char* theID,  const char* theName, Eleme
   else
     myShapeID = 0;
   
-  if ( myShapeID && strcmp(myShapeName, getShapeNameByID(myShapeID)) == 0 )
+  if ( myShapeID && myShapeName == getShapeNameByID(myShapeID))
     myElementsOnSurfacePtr->SetSurface( getShapeByID(myShapeID), (SMDSAbs_ElementType)theType );
   else
     myElementsOnSurfacePtr->SetSurface( getShapeByName( myShapeName ), (SMDSAbs_ElementType)theType );
@@ -1198,7 +1316,7 @@ void LyingOnGeom_i::SetShape( const char* theID, const char* theName )
   else
     myShapeID = 0;
   
-  if ( myShapeID && strcmp(myShapeName, getShapeNameByID(myShapeID)) == 0 )
+  if ( myShapeID && myShapeName == getShapeNameByID(myShapeID))
     myLyingOnGeomPtr->SetGeom( getShapeByID(myShapeID) );
   else
     myLyingOnGeomPtr->SetGeom( getShapeByName( myShapeName ) );
@@ -1311,6 +1429,77 @@ FunctorType FreeNodes_i::GetFunctorType()
   return SMESH::FT_FreeNodes;
 }
 
+/*
+  Class       : EqualNodes_i
+  Description : Predicate for Equal nodes
+*/
+EqualNodes_i::EqualNodes_i()
+{
+  myCoincidentNodesPtr.reset(new Controls::CoincidentNodes());
+  myFunctorPtr = myPredicatePtr = myCoincidentNodesPtr;
+}
+
+FunctorType EqualNodes_i::GetFunctorType()
+{
+  return SMESH::FT_EqualNodes;
+}
+
+void EqualNodes_i::SetTolerance( double tol )
+{
+  myCoincidentNodesPtr->SetTolerance( tol );
+}
+
+double EqualNodes_i::GetTolerance()
+{
+  return myCoincidentNodesPtr->GetTolerance();
+}
+
+/*
+  Class       : EqualEdges_i
+  Description : Predicate for Equal Edges
+*/
+EqualEdges_i::EqualEdges_i()
+{
+  myPredicatePtr.reset(new Controls::CoincidentElements1D());
+  myFunctorPtr = myPredicatePtr;
+}
+
+FunctorType EqualEdges_i::GetFunctorType()
+{
+  return SMESH::FT_EqualEdges;
+}
+
+/*
+  Class       : EqualFaces_i
+  Description : Predicate for Equal Faces
+*/
+EqualFaces_i::EqualFaces_i()
+{
+  myPredicatePtr.reset(new Controls::CoincidentElements2D());
+  myFunctorPtr = myPredicatePtr;
+}
+
+FunctorType EqualFaces_i::GetFunctorType()
+{
+  return SMESH::FT_EqualFaces;
+}
+
+/*
+  Class       : EqualVolumes_i
+  Description : Predicate for Equal Volumes
+*/
+EqualVolumes_i::EqualVolumes_i()
+{
+  myPredicatePtr.reset(new Controls::CoincidentElements3D());
+  myFunctorPtr = myPredicatePtr;
+}
+
+FunctorType EqualVolumes_i::GetFunctorType()
+{
+  return SMESH::FT_EqualVolumes;
+}
+
+
 /*
   Class       : RangeOfIds_i
   Description : Predicate for Range of Ids.
@@ -1439,7 +1628,7 @@ void ElemGeomType_i::SetGeometryType(GeometryType theType)
 
 GeometryType ElemGeomType_i::GetGeometryType() const
 {
-  return (GeometryType)myElemGeomTypePtr->GetGeomType();;
+  return (GeometryType)myElemGeomTypePtr->GetGeomType();
 }
 
 FunctorType ElemGeomType_i::GetFunctorType()
@@ -1447,6 +1636,49 @@ FunctorType ElemGeomType_i::GetFunctorType()
   return SMESH::FT_ElemGeomType;
 }
 
+/*
+  Class       : CoplanarFaces_i
+  Description : Returns true if a mesh face is a coplanar neighbour to a given one
+*/
+CoplanarFaces_i::CoplanarFaces_i()
+{
+  myCoplanarFacesPtr.reset(new Controls::CoplanarFaces());
+  myFunctorPtr = myPredicatePtr = myCoplanarFacesPtr;
+}
+
+void CoplanarFaces_i::SetFace ( CORBA::Long theFaceID )
+{
+  myCoplanarFacesPtr->SetFace(theFaceID);
+  TPythonDump()<<this<<".SetFace("<<theFaceID<<")";
+}
+
+void CoplanarFaces_i::SetTolerance( CORBA::Double theToler )
+{
+  myCoplanarFacesPtr->SetTolerance(theToler);
+  TPythonDump()<<this<<".SetTolerance("<<theToler<<")";
+}
+
+CORBA::Long CoplanarFaces_i::GetFace () const
+{
+  return myCoplanarFacesPtr->GetFace();
+}
+
+char* CoplanarFaces_i::GetFaceAsString () const
+{
+  TCollection_AsciiString str(Standard_Integer(myCoplanarFacesPtr->GetFace()));
+  return CORBA::string_dup( str.ToCString() );
+}
+
+CORBA::Double CoplanarFaces_i::GetTolerance() const
+{
+  return myCoplanarFacesPtr->GetTolerance();
+}
+
+FunctorType CoplanarFaces_i::GetFunctorType()
+{
+  return SMESH::FT_CoplanarFaces;
+}
+
 /*
   Class       : Comparator_i
   Description : Base class for comparators
@@ -1458,7 +1690,7 @@ Comparator_i::Comparator_i():
 Comparator_i::~Comparator_i()
 {
   if ( myNumericalFunctor )
-    myNumericalFunctor->Destroy();
+    myNumericalFunctor->UnRegister();
 }
 
 void Comparator_i::SetMargin( CORBA::Double theValue )
@@ -1475,7 +1707,7 @@ CORBA::Double Comparator_i::GetMargin()
 void Comparator_i::SetNumFunctor( NumericalFunctor_ptr theFunct )
 {
   if ( myNumericalFunctor )
-    myNumericalFunctor->Destroy();
+    myNumericalFunctor->UnRegister();
 
   myNumericalFunctor = DownCast<NumericalFunctor_i*>(theFunct);
 
@@ -1570,13 +1802,13 @@ LogicalNOT_i::LogicalNOT_i()
 LogicalNOT_i::~LogicalNOT_i()
 {
   if ( myPredicate )
-    myPredicate->Destroy();
+    myPredicate->UnRegister();
 }
 
 void LogicalNOT_i::SetPredicate( Predicate_ptr thePredicate )
 {
   if ( myPredicate )
-    myPredicate->Destroy();
+    myPredicate->UnRegister();
 
   myPredicate = SMESH::GetPredicate(thePredicate);
 
@@ -1610,10 +1842,10 @@ LogicalBinary_i::LogicalBinary_i()
 LogicalBinary_i::~LogicalBinary_i()
 {
   if ( myPredicate1 )
-    myPredicate1->Destroy();
+    myPredicate1->UnRegister();
 
   if ( myPredicate2 )
-    myPredicate2->Destroy();
+    myPredicate2->UnRegister();
 }
 
 void LogicalBinary_i::SetMesh( SMESH_Mesh_ptr theMesh )
@@ -1628,7 +1860,7 @@ void LogicalBinary_i::SetMesh( SMESH_Mesh_ptr theMesh )
 void LogicalBinary_i::SetPredicate1( Predicate_ptr thePredicate )
 {
   if ( myPredicate1 )
-    myPredicate1->Destroy();
+    myPredicate1->UnRegister();
 
   myPredicate1 = SMESH::GetPredicate(thePredicate);
 
@@ -1642,7 +1874,7 @@ void LogicalBinary_i::SetPredicate1( Predicate_ptr thePredicate )
 void LogicalBinary_i::SetPredicate2( Predicate_ptr thePredicate )
 {
   if ( myPredicate2 )
-    myPredicate2->Destroy();
+    myPredicate2->UnRegister();
 
   myPredicate2 = SMESH::GetPredicate(thePredicate);
 
@@ -1715,7 +1947,7 @@ FilterManager_i::FilterManager_i()
 
 FilterManager_i::~FilterManager_i()
 {
-  //TPythonDump()<<this<<".Destroy()";
+  //TPythonDump()<<this<<".UnRegister()";
 }
 
 
@@ -1791,6 +2023,24 @@ Volume3D_ptr FilterManager_i::CreateVolume3D()
 }
 
 
+MaxElementLength2D_ptr FilterManager_i::CreateMaxElementLength2D()
+{
+  SMESH::MaxElementLength2D_i* aServant = new SMESH::MaxElementLength2D_i();
+  SMESH::MaxElementLength2D_var anObj = aServant->_this();
+  TPythonDump()<<aServant<<" = "<<this<<".CreateMaxElementLength2D()";
+  return anObj._retn();
+}
+
+
+MaxElementLength3D_ptr FilterManager_i::CreateMaxElementLength3D()
+{
+  SMESH::MaxElementLength3D_i* aServant = new SMESH::MaxElementLength3D_i();
+  SMESH::MaxElementLength3D_var anObj = aServant->_this();
+  TPythonDump()<<aServant<<" = "<<this<<".CreateMaxElementLength3D()";
+  return anObj._retn();
+}
+
+
 Length_ptr FilterManager_i::CreateLength()
 {
   SMESH::Length_i* aServant = new SMESH::Length_i();
@@ -1823,6 +2073,14 @@ MultiConnection2D_ptr FilterManager_i::CreateMultiConnection2D()
   return anObj._retn();
 }
 
+BallDiameter_ptr FilterManager_i::CreateBallDiameter()
+{
+  SMESH::BallDiameter_i* aServant = new SMESH::BallDiameter_i();
+  SMESH::BallDiameter_var anObj = aServant->_this();
+  TPythonDump()<<aServant<<" = "<<this<<".CreateBallDiameter()";
+  return anObj._retn();
+}
+
 BelongToGeom_ptr FilterManager_i::CreateBelongToGeom()
 {
   SMESH::BelongToGeom_i* aServant = new SMESH::BelongToGeom_i();
@@ -1863,6 +2121,14 @@ LyingOnGeom_ptr FilterManager_i::CreateLyingOnGeom()
   return anObj._retn();
 }
 
+CoplanarFaces_ptr FilterManager_i::CreateCoplanarFaces()
+{
+  SMESH::CoplanarFaces_i* aServant = new SMESH::CoplanarFaces_i();
+  SMESH::CoplanarFaces_var anObj = aServant->_this();
+  TPythonDump()<<aServant<<" = "<<this<<".CreateCoplanarFaces()";
+  return anObj._retn();
+}
+
 FreeBorders_ptr FilterManager_i::CreateFreeBorders()
 {
   SMESH::FreeBorders_i* aServant = new SMESH::FreeBorders_i();
@@ -1895,6 +2161,36 @@ FreeNodes_ptr FilterManager_i::CreateFreeNodes()
   return anObj._retn();
 }
 
+EqualNodes_ptr FilterManager_i::CreateEqualNodes()
+{
+  SMESH::EqualNodes_i* aServant = new SMESH::EqualNodes_i();
+  SMESH::EqualNodes_var anObj = aServant->_this();
+  TPythonDump()<<aServant<<" = "<<this<<".CreateEqualNodes()";
+  return anObj._retn();
+}
+
+EqualEdges_ptr FilterManager_i::CreateEqualEdges()
+{
+  SMESH::EqualEdges_i* aServant = new SMESH::EqualEdges_i();
+  SMESH::EqualEdges_var anObj = aServant->_this();
+  TPythonDump()<<aServant<<" = "<<this<<".CreateEqualEdges()";
+  return anObj._retn();
+}
+EqualFaces_ptr FilterManager_i::CreateEqualFaces()
+{
+  SMESH::EqualFaces_i* aServant = new SMESH::EqualFaces_i();
+  SMESH::EqualFaces_var anObj = aServant->_this();
+  TPythonDump()<<aServant<<" = "<<this<<".CreateEqualFaces()";
+  return anObj._retn();
+}
+EqualVolumes_ptr FilterManager_i::CreateEqualVolumes()
+{
+  SMESH::EqualVolumes_i* aServant = new SMESH::EqualVolumes_i();
+  SMESH::EqualVolumes_var anObj = aServant->_this();
+  TPythonDump()<<aServant<<" = "<<this<<".CreateEqualVolumes()";
+  return anObj._retn();
+}
+
 RangeOfIds_ptr FilterManager_i::CreateRangeOfIds()
 {
   SMESH::RangeOfIds_i* aServant = new SMESH::RangeOfIds_i();
@@ -1911,6 +2207,38 @@ BadOrientedVolume_ptr FilterManager_i::CreateBadOrientedVolume()
   return anObj._retn();
 }
 
+BareBorderVolume_ptr FilterManager_i::CreateBareBorderVolume()
+{
+  SMESH::BareBorderVolume_i* aServant = new SMESH::BareBorderVolume_i();
+  SMESH::BareBorderVolume_var anObj = aServant->_this();
+  TPythonDump()<<aServant<<" = "<<this<<".CreateBareBorderVolume()";
+  return anObj._retn();
+}
+
+BareBorderFace_ptr FilterManager_i::CreateBareBorderFace()
+{
+  SMESH::BareBorderFace_i* aServant = new SMESH::BareBorderFace_i();
+  SMESH::BareBorderFace_var anObj = aServant->_this();
+  TPythonDump()<<aServant<<" = "<<this<<".CreateBareBorderFace()";
+  return anObj._retn();
+}
+
+OverConstrainedVolume_ptr FilterManager_i::CreateOverConstrainedVolume()
+{
+  SMESH::OverConstrainedVolume_i* aServant = new SMESH::OverConstrainedVolume_i();
+  SMESH::OverConstrainedVolume_var anObj = aServant->_this();
+  TPythonDump()<<aServant<<" = "<<this<<".CreateOverConstrainedVolume()";
+  return anObj._retn();
+}
+
+OverConstrainedFace_ptr FilterManager_i::CreateOverConstrainedFace()
+{
+  SMESH::OverConstrainedFace_i* aServant = new SMESH::OverConstrainedFace_i();
+  SMESH::OverConstrainedFace_var anObj = aServant->_this();
+  TPythonDump()<<aServant<<" = "<<this<<".CreateOverConstrainedFace()";
+  return anObj._retn();
+}
+
 LessThan_ptr FilterManager_i::CreateLessThan()
 {
   SMESH::LessThan_i* aServant = new SMESH::LessThan_i();
@@ -1995,7 +2323,7 @@ FilterLibrary_ptr FilterManager_i::LoadLibrary( const char* aFileName )
 {
   SMESH::FilterLibrary_i* aServant = new SMESH::FilterLibrary_i( aFileName );
   SMESH::FilterLibrary_var anObj = aServant->_this();
-  TPythonDump()<<aServant<<" = "<<this<<".LoadLibrary("<<aFileName<<")";
+  TPythonDump()<<aServant<<" = "<<this<<".LoadLibrary('"<<aFileName<<"')";
   return anObj._retn();
 }
 
@@ -2048,12 +2376,12 @@ Filter_i::Filter_i()
 Filter_i::~Filter_i()
 {
   if ( myPredicate )
-    myPredicate->Destroy();
+    myPredicate->UnRegister();
 
   if(!CORBA::is_nil(myMesh))
-    myMesh->Destroy();
+    myMesh->UnRegister();
 
-  //TPythonDump()<<this<<".Destroy()";
+  //TPythonDump()<<this<<".UnRegister()";
 }
 
 //=======================================================================
@@ -2063,7 +2391,7 @@ Filter_i::~Filter_i()
 void Filter_i::SetPredicate( Predicate_ptr thePredicate )
 {
   if ( myPredicate )
-    myPredicate->Destroy();
+    myPredicate->UnRegister();
 
   myPredicate = SMESH::GetPredicate(thePredicate);
 
@@ -2071,8 +2399,13 @@ void Filter_i::SetPredicate( Predicate_ptr thePredicate )
   {
     myFilter.SetPredicate( myPredicate->GetPredicate() );
     myPredicate->Register();
+    if ( const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(myMesh))
+      myPredicate->GetPredicate()->SetMesh( aMesh );
     TPythonDump()<<this<<".SetPredicate("<<myPredicate<<")";
   }
+  std::list<TPredicateChangeWaiter*>::iterator i = myWaiters.begin();
+  for ( ; i != myWaiters.end(); ++i )
+    (*i)->PredicateChanged();
 }
 
 //=======================================================================
@@ -2096,10 +2429,14 @@ SetMesh( SMESH_Mesh_ptr theMesh )
     theMesh->Register();
 
   if(!CORBA::is_nil(myMesh))
-    myMesh->Destroy();
+    myMesh->UnRegister();
 
-  myMesh = theMesh;
+  myMesh = SMESH_Mesh::_duplicate( theMesh );
   TPythonDump()<<this<<".SetMesh("<<theMesh<<")";
+
+  if ( myPredicate )
+    if ( const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(theMesh))
+      myPredicate->GetPredicate()->SetMesh( aMesh );
 }
 
 SMESH::long_array*
@@ -2150,6 +2487,119 @@ GetElementsId( SMESH_Mesh_ptr theMesh )
   return anArray._retn();
 }
 
+template<class TElement, class TIterator, class TPredicate>
+static void collectMeshInfo(const TIterator& theItr,
+                            TPredicate& thePred,
+                            SMESH::long_array& theRes)
+{         
+  if (!theItr)
+    return;
+  while (theItr->more()) {
+    const SMDS_MeshElement* anElem = theItr->next();
+    if ( thePred->IsSatisfy( anElem->GetID() ) )
+      theRes[ anElem->GetEntityType() ]++;
+  }
+}
+
+//=============================================================================
+/*!
+ * \brief Returns statistic of mesh elements
+ */
+//=============================================================================
+SMESH::long_array* ::Filter_i::GetMeshInfo()
+{
+  SMESH::long_array_var aRes = new SMESH::long_array();
+  aRes->length(SMESH::Entity_Last);
+  for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
+    aRes[i] = 0;
+
+  if(!CORBA::is_nil(myMesh) && myPredicate) {
+    const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(myMesh);
+    SMDS_ElemIteratorPtr it;
+    switch( GetElementType() )
+    {
+    case SMDSAbs_Node:
+      collectMeshInfo<const SMDS_MeshNode*>(aMesh->nodesIterator(),myPredicate,aRes);
+      break;
+    case SMDSAbs_Edge:
+      collectMeshInfo<const SMDS_MeshElement*>(aMesh->edgesIterator(),myPredicate,aRes);
+      break;
+    case SMDSAbs_Face:
+      collectMeshInfo<const SMDS_MeshElement*>(aMesh->facesIterator(),myPredicate,aRes);
+      break;
+    case SMDSAbs_Volume:
+      collectMeshInfo<const SMDS_MeshElement*>(aMesh->volumesIterator(),myPredicate,aRes);
+      break;
+    case SMDSAbs_All:
+    default:
+      collectMeshInfo<const SMDS_MeshElement*>(aMesh->elementsIterator(),myPredicate,aRes);
+      break;
+    }
+  }
+
+  return aRes._retn();  
+}
+
+//================================================================================
+/*!
+ * \brief Return GetElementType() within an array
+ * Implement SMESH_IDSource interface
+ */
+//================================================================================
+
+SMESH::array_of_ElementType* Filter_i::GetTypes()
+{
+  SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
+
+  // check if any element passes through the filter
+  if ( !CORBA::is_nil(myMesh) && myPredicate )
+  {
+    const SMDS_Mesh* aMesh = MeshPtr2SMDSMesh(myMesh);
+    SMDS_ElemIteratorPtr it = aMesh->elementsIterator( SMDSAbs_ElementType( GetElementType() ));
+    bool satisfies = false;
+    while ( !satisfies && it->more() )
+      satisfies = myPredicate->IsSatisfy( it->next()->GetID() );
+    if ( satisfies ) {
+      types->length( 1 );
+      types[0] = GetElementType();
+    }
+  }
+  return types._retn();
+}
+
+//=======================================================================
+//function : GetMesh
+//purpose  : Returns mesh
+//=======================================================================
+
+SMESH::SMESH_Mesh_ptr Filter_i::GetMesh()
+{
+  return SMESH_Mesh::_duplicate( myMesh );
+}
+
+//================================================================================
+/*!
+ * \brief Stores an object to be notified on change of predicate
+ */
+//================================================================================
+
+void Filter_i::AddWaiter( TPredicateChangeWaiter* waiter )
+{
+  if ( waiter )
+    myWaiters.push_back( waiter );
+}
+
+//================================================================================
+/*!
+ * \brief Removes an object to be notified on change of predicate
+ */
+//================================================================================
+
+void Filter_i::RemoveWaiter( TPredicateChangeWaiter* waiter )
+{
+  myWaiters.remove( waiter );
+}
+
 //=======================================================================
 // name    : getCriteria
 // Purpose : Retrieve criterions from predicate
@@ -2166,6 +2616,14 @@ static inline bool getCriteria( Predicate_i*                thePred,
   case FT_FreeFaces:
   case FT_LinearOrQuadratic:
   case FT_FreeNodes:
+  case FT_EqualEdges:
+  case FT_EqualFaces:
+  case FT_EqualVolumes:
+  case FT_BadOrientedVolume:
+  case FT_BareBorderVolume:
+  case FT_BareBorderFace:
+  case FT_OverConstrainedVolume:
+  case FT_OverConstrainedFace:
     {
       CORBA::ULong i = theCriteria->length();
       theCriteria->length( i + 1 );
@@ -2189,6 +2647,7 @@ static inline bool getCriteria( Predicate_i*                thePred,
       theCriteria[ i ].ThresholdStr  = aPred->GetShapeName();
       theCriteria[ i ].ThresholdID   = aPred->GetShapeID();
       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
+      theCriteria[ i ].Tolerance     = aPred->GetTolerance();
 
       return true;
     }
@@ -2224,34 +2683,51 @@ static inline bool getCriteria( Predicate_i*                thePred,
       theCriteria[ i ].ThresholdStr  = aPred->GetShapeName();
       theCriteria[ i ].ThresholdID   = aPred->GetShapeID();
       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
+      theCriteria[ i ].Tolerance     = aPred->GetTolerance();
 
       return true;
     }
-  case FT_RangeOfIds:
+   case FT_CoplanarFaces:
     {
-      RangeOfIds_i* aPred = dynamic_cast<RangeOfIds_i*>( thePred );
+      CoplanarFaces_i* aPred = dynamic_cast<CoplanarFaces_i*>( thePred );
 
       CORBA::ULong i = theCriteria->length();
       theCriteria->length( i + 1 );
 
       theCriteria[ i ] = createCriterion();
+      CORBA::String_var faceId = aPred->GetFaceAsString();
 
-      theCriteria[ i ].Type          = FT_RangeOfIds;
-      theCriteria[ i ].ThresholdStr  = aPred->GetRangeStr();
-      theCriteria[ i ].TypeOfElement = aPred->GetElementType();
+      theCriteria[ i ].Type          = FT_CoplanarFaces;
+      theCriteria[ i ].ThresholdID   = faceId;
+      theCriteria[ i ].Tolerance     = aPred->GetTolerance();
 
       return true;
     }
-  case FT_BadOrientedVolume:
+  case FT_EqualNodes:
+    {
+      EqualNodes_i* aPred = dynamic_cast<EqualNodes_i*>( thePred );
+
+      CORBA::ULong i = theCriteria->length();
+      theCriteria->length( i + 1 );
+
+      theCriteria[ i ] = createCriterion();
+
+      theCriteria[ i ].Type          = FT_EqualNodes;
+      theCriteria[ i ].Tolerance     = aPred->GetTolerance();
+
+      return true;
+    }
+  case FT_RangeOfIds:
     {
-      BadOrientedVolume_i* aPred = dynamic_cast<BadOrientedVolume_i*>( thePred );
+      RangeOfIds_i* aPred = dynamic_cast<RangeOfIds_i*>( thePred );
 
       CORBA::ULong i = theCriteria->length();
       theCriteria->length( i + 1 );
 
       theCriteria[ i ] = createCriterion();
 
-      theCriteria[ i ].Type          = FT_BadOrientedVolume;
+      theCriteria[ i ].Type          = FT_RangeOfIds;
+      theCriteria[ i ].ThresholdStr  = aPred->GetRangeStr();
       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
 
       return true;
@@ -2350,7 +2826,7 @@ CORBA::Boolean Filter_i::GetCriteria( SMESH::Filter::Criteria_out theCriteria )
 CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria )
 {
   if ( myPredicate != 0 )
-    myPredicate->Destroy();
+    myPredicate->UnRegister();
 
   SMESH::FilterManager_i* aFilter = new SMESH::FilterManager_i();
   FilterManager_ptr aFilterMgr = aFilter->_this();
@@ -2376,16 +2852,20 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria
 
     {
       TPythonDump pd;
-      pd << "aCriterion = SMESH.Filter.Criterion(" << aCriterion << "," << aCompare
-         << "," << aThreshold << ",'" << aThresholdStr;
-      if (aThresholdID)
-       pd << "',salome.ObjectToID(" << aThresholdID
-          << ")," << aUnary << "," << aBinary << "," << aTolerance
-          << "," << aTypeOfElem << "," << aPrecision << ")";
-      else
-       pd << "',''," << aUnary << "," << aBinary << "," << aTolerance
-          << "," << aTypeOfElem << "," << aPrecision << ")";
+      pd << "aCriterion = SMESH.Filter.Criterion("
+         << aCriterion    << ", "
+         << aCompare      << ", "
+         << aThreshold    << ", '"
+         << aThresholdStr << "', '";
+      if (aThresholdID) pd << aThresholdID;
+      pd                  << "', "
+         << aUnary        << ", "
+         << aBinary       << ", "
+         << aTolerance    << ", "
+         << aTypeOfElem   << ", "
+         << aPrecision    << ")";
     }
+    TPythonDump pd;
 
     SMESH::Predicate_ptr aPredicate = SMESH::Predicate::_nil();
     SMESH::NumericalFunctor_ptr aFunctor = SMESH::NumericalFunctor::_nil();
@@ -2430,6 +2910,15 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria
       case SMESH::FT_Volume3D:
         aFunctor = aFilterMgr->CreateVolume3D();
         break;
+      case SMESH::FT_MaxElementLength2D:
+        aFunctor = aFilterMgr->CreateMaxElementLength2D();
+        break;
+      case SMESH::FT_MaxElementLength3D:
+        aFunctor = aFilterMgr->CreateMaxElementLength3D();
+        break;
+      case SMESH::FT_BallDiameter:
+        aFunctor = aFilterMgr->CreateBallDiameter();
+        break;
 
       // Predicates
 
@@ -2445,11 +2934,28 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria
       case SMESH::FT_FreeNodes:
         aPredicate = aFilterMgr->CreateFreeNodes();
         break;
+      case SMESH::FT_EqualNodes:
+        {
+          SMESH::EqualNodes_ptr pred = aFilterMgr->CreateEqualNodes();
+          pred->SetTolerance( aTolerance );
+          aPredicate = pred;
+          break;
+        }
+      case SMESH::FT_EqualEdges:
+        aPredicate = aFilterMgr->CreateEqualEdges();
+        break;
+      case SMESH::FT_EqualFaces:
+        aPredicate = aFilterMgr->CreateEqualFaces();
+        break;
+      case SMESH::FT_EqualVolumes:
+        aPredicate = aFilterMgr->CreateEqualVolumes();
+        break;
       case SMESH::FT_BelongToGeom:
         {
           SMESH::BelongToGeom_ptr tmpPred = aFilterMgr->CreateBelongToGeom();
           tmpPred->SetElementType( aTypeOfElem );
           tmpPred->SetShape( aThresholdID, aThresholdStr );
+          tmpPred->SetTolerance( aTolerance );
           aPredicate = tmpPred;
         }
         break;
@@ -2475,7 +2981,8 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria
         {
           SMESH::LyingOnGeom_ptr tmpPred = aFilterMgr->CreateLyingOnGeom();
           tmpPred->SetElementType( aTypeOfElem );
-         tmpPred->SetShape( aThresholdID, aThresholdStr );
+          tmpPred->SetShape( aThresholdID, aThresholdStr );
+          tmpPred->SetTolerance( aTolerance );
           aPredicate = tmpPred;
         }
         break;
@@ -2492,6 +2999,26 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria
           aPredicate = aFilterMgr->CreateBadOrientedVolume();
         }
         break;
+      case SMESH::FT_BareBorderVolume:
+        {
+          aPredicate = aFilterMgr->CreateBareBorderVolume();
+        }
+        break;
+      case SMESH::FT_BareBorderFace:
+        {
+          aPredicate = aFilterMgr->CreateBareBorderFace();
+        }
+        break;
+      case SMESH::FT_OverConstrainedVolume:
+        {
+          aPredicate = aFilterMgr->CreateOverConstrainedVolume();
+        }
+        break;
+      case SMESH::FT_OverConstrainedFace:
+        {
+          aPredicate = aFilterMgr->CreateOverConstrainedFace();
+        }
+        break;
       case SMESH::FT_LinearOrQuadratic:
         {
           SMESH::LinearOrQuadratic_ptr tmpPred = aFilterMgr->CreateLinearOrQuadratic();
@@ -2511,7 +3038,15 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria
         {
           SMESH::ElemGeomType_ptr tmpPred = aFilterMgr->CreateElemGeomType();
           tmpPred->SetElementType( aTypeOfElem );
-          tmpPred->SetGeometryType( (GeometryType)(aThreshold + 0.5) );
+          tmpPred->SetGeometryType( (GeometryType)(int)(aThreshold + 0.5) );
+          aPredicate = tmpPred;
+          break;
+        }
+      case SMESH::FT_CoplanarFaces:
+        {
+          SMESH::CoplanarFaces_ptr tmpPred = aFilterMgr->CreateCoplanarFaces();
+          tmpPred->SetFace( atol (aThresholdID ));
+          tmpPred->SetTolerance( aTolerance );
           aPredicate = tmpPred;
           break;
         }
@@ -2559,10 +3094,10 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria
     // logical op
     aPredicates.push_back( aPredicate );
     aBinaries.push_back( aBinary );
-    TPythonDump()<<"aCriteria.append(aCriterion)";
+    pd <<"aCriteria.append(aCriterion)";
 
   } // end of for
-  TPythonDump()<<this<<".SetCriteria(aCriteria)";
+  TPythonDump pd; pd<<this<<".SetCriteria(aCriteria)";
 
   // CREATE ONE PREDICATE FROM PREVIOUSLY CREATED MAP
 
@@ -2647,6 +3182,8 @@ Predicate_ptr Filter_i::GetPredicate()
   else
   {
     SMESH::Predicate_var anObj = myPredicate->_this();
+    // if ( SMESH::Functor_i* fun = SMESH::DownCast<SMESH::Functor_i*>( anObj ))
+    //   TPythonDump() << fun << " = " << this << ".GetPredicate()";
     return anObj._retn();
   }
 }
@@ -2717,19 +3254,29 @@ static inline LDOMString toString( CORBA::Long theType )
     case FT_Skew            : return "Skew";
     case FT_Area            : return "Area";
     case FT_Volume3D        : return "Volume3D";
+    case FT_MaxElementLength2D: return "Max element length 2D";
+    case FT_MaxElementLength3D: return "Max element length 3D";
     case FT_BelongToGeom    : return "Belong to Geom";
     case FT_BelongToPlane   : return "Belong to Plane";
     case FT_BelongToCylinder: return "Belong to Cylinder";
     case FT_BelongToGenSurface: return "Belong to Generic Surface";
     case FT_LyingOnGeom     : return "Lying on Geom";
-    case FT_BadOrientedVolume: return "Bad Oriented Volume";
+    case FT_BadOrientedVolume:return "Bad Oriented Volume";
+    case FT_BareBorderVolume: return "Volumes with bare border";
+    case FT_BareBorderFace  : return "Faces with bare border";
+    case FT_OverConstrainedVolume: return "Over-constrained Volumes";
+    case FT_OverConstrainedFace  : return "Over-constrained Faces";
     case FT_RangeOfIds      : return "Range of IDs";
     case FT_FreeBorders     : return "Free borders";
     case FT_FreeEdges       : return "Free edges";
     case FT_FreeFaces       : return "Free faces";
     case FT_FreeNodes       : return "Free nodes";
+    case FT_EqualNodes      : return "Equal nodes";
+    case FT_EqualEdges      : return "Equal edges";
+    case FT_EqualFaces      : return "Equal faces";
+    case FT_EqualVolumes    : return "Equal volumes";
     case FT_MultiConnection : return "Borders at multi-connections";
-    case FT_MultiConnection2D: return "Borders at multi-connections 2D";
+    case FT_MultiConnection2D:return "Borders at multi-connections 2D";
     case FT_Length          : return "Length";
     case FT_Length2D        : return "Length 2D";
     case FT_LessThan        : return "Less than";
@@ -2759,6 +3306,8 @@ static inline SMESH::FunctorType toFunctorType( const LDOMString& theStr )
   else if ( theStr.equals( "Skew"                         ) ) return FT_Skew;
   else if ( theStr.equals( "Area"                         ) ) return FT_Area;
   else if ( theStr.equals( "Volume3D"                     ) ) return FT_Volume3D;
+  else if ( theStr.equals( "Max element length 2D"        ) ) return FT_MaxElementLength2D;
+  else if ( theStr.equals( "Max element length 3D"        ) ) return FT_MaxElementLength3D;
   else if ( theStr.equals( "Belong to Geom"               ) ) return FT_BelongToGeom;
   else if ( theStr.equals( "Belong to Plane"              ) ) return FT_BelongToPlane;
   else if ( theStr.equals( "Belong to Cylinder"           ) ) return FT_BelongToCylinder;
@@ -2768,12 +3317,20 @@ static inline SMESH::FunctorType toFunctorType( const LDOMString& theStr )
   else if ( theStr.equals( "Free edges"                   ) ) return FT_FreeEdges;
   else if ( theStr.equals( "Free faces"                   ) ) return FT_FreeFaces;
   else if ( theStr.equals( "Free nodes"                   ) ) return FT_FreeNodes;
+  else if ( theStr.equals( "Equal nodes"                  ) ) return FT_EqualNodes;
+  else if ( theStr.equals( "Equal edges"                  ) ) return FT_EqualEdges;
+  else if ( theStr.equals( "Equal faces"                  ) ) return FT_EqualFaces;
+  else if ( theStr.equals( "Equal volumes"                ) ) return FT_EqualVolumes;
   else if ( theStr.equals( "Borders at multi-connections" ) ) return FT_MultiConnection;
   //  else if ( theStr.equals( "Borders at multi-connections 2D" ) ) return FT_MultiConnection2D;
   else if ( theStr.equals( "Length"                       ) ) return FT_Length;
   //  else if ( theStr.equals( "Length2D"                     ) ) return FT_Length2D;
   else if ( theStr.equals( "Range of IDs"                 ) ) return FT_RangeOfIds;
   else if ( theStr.equals( "Bad Oriented Volume"          ) ) return FT_BadOrientedVolume;
+  else if ( theStr.equals( "Volumes with bare border"     ) ) return FT_BareBorderVolume;
+  else if ( theStr.equals( "Faces with bare border"       ) ) return FT_BareBorderFace;
+  else if ( theStr.equals( "Over-constrained Volumes"     ) ) return FT_OverConstrainedVolume;
+  else if ( theStr.equals( "Over-constrained Faces"       ) ) return FT_OverConstrainedFace;
   else if ( theStr.equals( "Less than"                    ) ) return FT_LessThan;
   else if ( theStr.equals( "More than"                    ) ) return FT_MoreThan;
   else if ( theStr.equals( "Equal to"                     ) ) return FT_EqualTo;
@@ -3000,7 +3557,7 @@ FilterLibrary_i::FilterLibrary_i()
 FilterLibrary_i::~FilterLibrary_i()
 {
   delete myFileName;
-  //TPythonDump()<<this<<".Destroy()";
+  //TPythonDump()<<this<<".UnRegister()";
 }
 
 //=======================================================================
@@ -3192,7 +3749,7 @@ CORBA::Boolean FilterLibrary_i::Replace( const char* theFilterName,
   {
     aFilterItem.ReplaceElement( aNewItem );
     if(Filter_i* aFilter = DownCast<Filter_i*>(theFilter))
-      TPythonDump()<<this<<".Replace('"<<theFilterName<<"',"<<theNewName<<"',"<<aFilter<<")";
+      TPythonDump()<<this<<".Replace('"<<theFilterName<<"','"<<theNewName<<"',"<<aFilter<<")";
     return true;
   }
 }
@@ -3297,3 +3854,95 @@ string_array* FilterLibrary_i::GetAllNames()
 
   return aResArray._retn();
 }
+
+//================================================================================
+/*!
+ * \brief Return an array of strings corresponding to items of enum FunctorType
+ */
+//================================================================================
+
+static const char** getFunctNames()
+{
+  static const char* functName[ SMESH::FT_Undefined + 1 ] = {
+    // IT's necessary to update this array according to enum FunctorType (SMESH_Filter.idl)
+    // The order is IMPORTANT !!!
+    "FT_AspectRatio",
+    "FT_AspectRatio3D",
+    "FT_Warping",
+    "FT_MinimumAngle",
+    "FT_Taper",
+    "FT_Skew",
+    "FT_Area",
+    "FT_Volume3D",
+    "FT_MaxElementLength2D",
+    "FT_MaxElementLength3D",
+    "FT_FreeBorders",
+    "FT_FreeEdges",
+    "FT_FreeNodes",
+    "FT_FreeFaces",
+    "FT_EqualNodes",
+    "FT_EqualEdges",
+    "FT_EqualFaces",
+    "FT_EqualVolumes",
+    "FT_MultiConnection",
+    "FT_MultiConnection2D",
+    "FT_Length",
+    "FT_Length2D",
+    "FT_BelongToGeom",
+    "FT_BelongToPlane",
+    "FT_BelongToCylinder",
+    "FT_BelongToGenSurface",
+    "FT_LyingOnGeom",
+    "FT_RangeOfIds",
+    "FT_BadOrientedVolume",
+    "FT_BareBorderVolume",
+    "FT_BareBorderFace",
+    "FT_OverConstrainedVolume",
+    "FT_OverConstrainedFace",
+    "FT_LinearOrQuadratic",
+    "FT_GroupColor",
+    "FT_ElemGeomType",
+    "FT_CoplanarFaces",
+    "FT_BallDiameter",
+    "FT_LessThan",
+    "FT_MoreThan",
+    "FT_EqualTo",
+    "FT_LogicalNOT",
+    "FT_LogicalAND",
+    "FT_LogicalOR",
+    "FT_Undefined" };
+  return functName;
+}
+
+//================================================================================
+/*!
+ * \brief Return a string corresponding to an item of enum FunctorType
+ */
+//================================================================================
+
+const char* SMESH::FunctorTypeToString(SMESH::FunctorType ft)
+{
+  if ( ft < 0 || ft > SMESH::FT_Undefined )
+    return "FT_Undefined";
+  return getFunctNames()[ ft ];
+}
+
+//================================================================================
+/*!
+ * \brief Converts a string to FunctorType. This is reverse of FunctorTypeToString()
+ */
+//================================================================================
+
+SMESH::FunctorType SMESH::StringToFunctorType(const char* str)
+{
+  std::string name( str + 3 ); // skip "FT_"
+  const char** functNames = getFunctNames();
+  int ft = 0;
+  for ( ; ft < SMESH::FT_Undefined; ++ft )
+    if ( name == ( functNames[ft] + 3 ))
+      break;
+
+  //ASSERT( strcmp( str, FunctorTypeToString( SMESH::FunctorType( ft ))) == 0 );
+
+  return SMESH::FunctorType( ft );
+}
index 3b654e8809658c008950ddd88a0cee166388d755..cb82aa6d5637d0448f017525c07789acd44ed5d5 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : SMESH_Filter_i.hxx
 //  Author : Alexey Petrov, OCC
 #include "SALOME_GenericObj_i.hh"
 #include "SMESH_ControlsDef.hxx"
 
+#include <list>
+
 class SMESHDS_Mesh;
 
 namespace SMESH
 {
 
+  // ================================================================================
   namespace Controls
   {
 
@@ -107,10 +111,10 @@ namespace SMESH
       double                          GetTolerance();
       
       virtual bool                    Contains( const SMESHDS_Mesh*     theMeshDS,
-                                               const TopoDS_Shape&     theShape,
-                                               const SMDS_MeshElement* theElem,
-                                               TopAbs_ShapeEnum        theFindShapeEnum,
-                                               TopAbs_ShapeEnum        theAvoidShapeEnum = TopAbs_SHAPE );
+                                                const TopoDS_Shape&     theShape,
+                                                const SMDS_MeshElement* theElem,
+                                                TopAbs_ShapeEnum        theFindShapeEnum,
+                                                TopAbs_ShapeEnum        theAvoidShapeEnum = TopAbs_SHAPE );
     private:
       virtual void                    init();
 
@@ -122,8 +126,10 @@ namespace SMESH
       Controls::ElementsOnShapePtr    myElementsOnShapePtr; // only if myIsSubshape == false
     };
     typedef boost::shared_ptr<LyingOnGeom> LyingOnGeomPtr;
-  }
-  
+
+  } // namespace Controls
+
+  // ================================================================================
   /*
     FUNCTORS
   */
@@ -133,7 +139,7 @@ namespace SMESH
     Description : An abstact class for all functors 
   */
   class SMESH_I_EXPORT Functor_i: public virtual POA_SMESH::Functor,
-                  public virtual SALOME::GenericObj_i
+                                  public virtual SALOME::GenericObj_i
   {
   public:
     void                            SetMesh( SMESH_Mesh_ptr theMesh );
@@ -152,10 +158,11 @@ namespace SMESH
     Description : Base class for numerical functors 
   */
   class SMESH_I_EXPORT NumericalFunctor_i: public virtual POA_SMESH::NumericalFunctor,
-                           public virtual Functor_i
+                                           public virtual Functor_i
   {
   public:
     CORBA::Double                   GetValue( CORBA::Long theElementId );
+    SMESH::Histogram*               GetHistogram(CORBA::Short nbIntervals);
     void                            SetPrecision( CORBA::Long thePrecision );
     CORBA::Long                     GetPrecision();
     Controls::NumericalFunctorPtr   GetNumericalFunctor();
@@ -170,7 +177,7 @@ namespace SMESH
     Description : Functor for calculation of minimum angle
   */
   class SMESH_I_EXPORT MinimumAngle_i: public virtual POA_SMESH::MinimumAngle,
-                       public virtual NumericalFunctor_i
+                                       public virtual NumericalFunctor_i
   {
   public:
     MinimumAngle_i();
@@ -183,7 +190,7 @@ namespace SMESH
     Description : Functor for calculating aspect ratio
   */
   class SMESH_I_EXPORT AspectRatio_i: public virtual POA_SMESH::AspectRatio,
-                      public virtual NumericalFunctor_i
+                                      public virtual NumericalFunctor_i
   {
   public:
     AspectRatio_i();
@@ -196,7 +203,7 @@ namespace SMESH
     Description : Functor for calculating aspect ratio for 3D
   */
   class SMESH_I_EXPORT AspectRatio3D_i: public virtual POA_SMESH::AspectRatio3D,
-                        public virtual NumericalFunctor_i
+                                        public virtual NumericalFunctor_i
   {
   public:
     AspectRatio3D_i();
@@ -209,7 +216,7 @@ namespace SMESH
     Description : Functor for calculating warping
   */
   class SMESH_I_EXPORT Warping_i: public virtual POA_SMESH::Warping,
-                  public virtual NumericalFunctor_i
+                                  public virtual NumericalFunctor_i
   {
   public:
     Warping_i();
@@ -222,7 +229,7 @@ namespace SMESH
     Description : Functor for calculating taper
   */
   class SMESH_I_EXPORT Taper_i: public virtual POA_SMESH::Taper,
-                public virtual NumericalFunctor_i
+                                public virtual NumericalFunctor_i
   {
   public:
     Taper_i();
@@ -235,7 +242,7 @@ namespace SMESH
     Description : Functor for calculating skew in degrees
   */
   class SMESH_I_EXPORT Skew_i: public virtual POA_SMESH::Skew,
-               public virtual NumericalFunctor_i
+                               public virtual NumericalFunctor_i
   {
   public:
     Skew_i();
@@ -248,7 +255,7 @@ namespace SMESH
     Description : Functor for calculating area
   */
   class SMESH_I_EXPORT Area_i: public virtual POA_SMESH::Area,
-               public virtual NumericalFunctor_i
+                               public virtual NumericalFunctor_i
   {
   public:
     Area_i();
@@ -261,7 +268,7 @@ namespace SMESH
     Description : Functor for calculating volume of 3D element
   */
   class SMESH_I_EXPORT Volume3D_i: public virtual POA_SMESH::Volume3D,
-                    public virtual NumericalFunctor_i
+                                   public virtual NumericalFunctor_i
   {
   public:
     Volume3D_i();
@@ -269,12 +276,38 @@ namespace SMESH
   };
   
   
+  /*
+    Class       : MaxElementLength2D_i
+    Description : Functor for calculating maximum length of 2D element
+  */
+  class SMESH_I_EXPORT MaxElementLength2D_i: public virtual POA_SMESH::MaxElementLength2D,
+                                             public virtual NumericalFunctor_i
+  {
+  public:
+    MaxElementLength2D_i();
+    FunctorType                     GetFunctorType();
+  };
+  
+  
+  /*
+    Class       : MaxElementLength3D_i
+    Description : Functor for calculating maximum length of 3D element
+  */
+  class SMESH_I_EXPORT MaxElementLength3D_i: public virtual POA_SMESH::MaxElementLength3D,
+                                             public virtual NumericalFunctor_i
+  {
+  public:
+    MaxElementLength3D_i();
+    FunctorType                     GetFunctorType();
+  };
+  
+  
   /*
     Class       : Length_i
     Description : Functor for calculating length of edge
   */
   class SMESH_I_EXPORT Length_i: public virtual POA_SMESH::Length,
-                 public virtual NumericalFunctor_i
+                                 public virtual NumericalFunctor_i
   {
   public:
     Length_i();
@@ -286,7 +319,7 @@ namespace SMESH
     Description : Functor for calculating length of edge
   */
   class SMESH_I_EXPORT Length2D_i: public virtual POA_SMESH::Length2D,
-                   public virtual NumericalFunctor_i
+                                   public virtual NumericalFunctor_i
   {
   public:
     Length2D_i();
@@ -303,7 +336,7 @@ namespace SMESH
     Description : Functor for calculating number of faces conneted to the edge
   */
   class SMESH_I_EXPORT MultiConnection_i: public virtual POA_SMESH::MultiConnection,
-                          public virtual NumericalFunctor_i
+                                          public virtual NumericalFunctor_i
   {
   public:
     MultiConnection_i();
@@ -315,7 +348,7 @@ namespace SMESH
     Description : Functor for calculating number of faces conneted to the edge
   */
   class SMESH_I_EXPORT MultiConnection2D_i: public virtual POA_SMESH::MultiConnection2D,
-                            public virtual NumericalFunctor_i
+                                            public virtual NumericalFunctor_i
   {
   public:
     MultiConnection2D_i();
@@ -326,6 +359,18 @@ namespace SMESH
     Controls::MultiConnection2DPtr     myMulticonnection2DPtr;
   };
   
+  /*
+    Class       : BallDiameter_i
+    Description : Functor returning diameter of a ball element
+  */
+  class SMESH_I_EXPORT BallDiameter_i: public virtual POA_SMESH::BallDiameter,
+                                       public virtual NumericalFunctor_i
+  {
+  public:
+    BallDiameter_i();
+    FunctorType                     GetFunctorType();
+  };
+  
   
   /*
     PREDICATES
@@ -335,7 +380,7 @@ namespace SMESH
     Description : Base class for all predicates
   */
   class SMESH_I_EXPORT Predicate_i: public virtual POA_SMESH::Predicate,
-                    public virtual Functor_i
+                                    public virtual Functor_i
   {
   public:
     CORBA::Boolean                  IsSatisfy( CORBA::Long theElementId );
@@ -352,19 +397,67 @@ namespace SMESH
     the point of view of MED convention
   */
   class SMESH_I_EXPORT BadOrientedVolume_i: public virtual POA_SMESH::BadOrientedVolume,
-                            public virtual Predicate_i
+                                            public virtual Predicate_i
   {
   public:
     BadOrientedVolume_i();
     FunctorType                     GetFunctorType();
   };
   
+  /*
+    Class       : BareBorderVolume_i
+    Description : Verify whether a mesh volume has a free facet without a face on it
+  */
+  class SMESH_I_EXPORT BareBorderVolume_i: public virtual POA_SMESH::BareBorderVolume,
+                                           public virtual Predicate_i
+  {
+  public:
+    BareBorderVolume_i();
+    FunctorType                     GetFunctorType();
+  };
+  
+  /*
+    Class       : BareBorderFace_i
+    Description : Verify whether a mesh face has a free border without an edge on it
+  */
+  class SMESH_I_EXPORT BareBorderFace_i: public virtual POA_SMESH::BareBorderFace,
+                                         public virtual Predicate_i
+  {
+  public:
+    BareBorderFace_i();
+    FunctorType                     GetFunctorType();
+  };
+  
+  /*
+    Class       : OverConstrainedVolume_i
+    Description : Verify whether a mesh volume has only one facet shared with other volumes
+  */
+  class SMESH_I_EXPORT OverConstrainedVolume_i: public virtual POA_SMESH::OverConstrainedVolume,
+                                                public virtual Predicate_i
+  {
+  public:
+    OverConstrainedVolume_i();
+    FunctorType                     GetFunctorType();
+  };
+  
+  /*
+    Class       : OverConstrainedFace_i
+    Description : Verify whether a mesh face has only one border shared with other faces
+  */
+  class SMESH_I_EXPORT OverConstrainedFace_i: public virtual POA_SMESH::OverConstrainedFace,
+                                              public virtual Predicate_i
+  {
+  public:
+    OverConstrainedFace_i();
+    FunctorType                     GetFunctorType();
+  };
+  
   /*
     Class       : BelongToGeom_i
     Description : Predicate for selection on geometrical support
   */
   class SMESH_I_EXPORT BelongToGeom_i: public virtual POA_SMESH::BelongToGeom,
-                       public virtual Predicate_i
+                                       public virtual Predicate_i
   {
   public:
     BelongToGeom_i();
@@ -395,7 +488,7 @@ namespace SMESH
     Description : Verify whether mesh element lie in pointed Geom planar object
   */
   class SMESH_I_EXPORT BelongToSurface_i: public virtual POA_SMESH::BelongToSurface,
-                          public virtual Predicate_i
+                                          public virtual Predicate_i
   {
   public:
     BelongToSurface_i( const Handle(Standard_Type)& );
@@ -426,7 +519,7 @@ namespace SMESH
     Description : Verify whether mesh element lie in pointed Geom planar object
   */
   class SMESH_I_EXPORT BelongToPlane_i: public virtual POA_SMESH::BelongToPlane,
-                        public virtual BelongToSurface_i
+                                        public virtual BelongToSurface_i
   {
   public:
     BelongToPlane_i();
@@ -439,7 +532,7 @@ namespace SMESH
     Description : Verify whether mesh element lie in pointed Geom cylindrical object
   */
   class SMESH_I_EXPORT BelongToCylinder_i: public virtual POA_SMESH::BelongToCylinder,
-                           public virtual BelongToSurface_i
+                                           public virtual BelongToSurface_i
   {
   public:
     BelongToCylinder_i();
@@ -465,7 +558,7 @@ namespace SMESH
     Description : Predicate for selection on geometrical support(lying or partially lying)
   */
   class SMESH_I_EXPORT LyingOnGeom_i: public virtual POA_SMESH::LyingOnGeom,
-                      public virtual Predicate_i
+                                      public virtual Predicate_i
   {
   public:
     LyingOnGeom_i();
@@ -496,7 +589,7 @@ namespace SMESH
     Description : Predicate for free borders
   */
   class SMESH_I_EXPORT FreeBorders_i: public virtual POA_SMESH::FreeBorders,
-                      public virtual Predicate_i
+                                      public virtual Predicate_i
   {
   public:
     FreeBorders_i();
@@ -509,7 +602,7 @@ namespace SMESH
     Description : Predicate for free edges
   */
   class SMESH_I_EXPORT FreeEdges_i: public virtual POA_SMESH::FreeEdges,
-                    public virtual Predicate_i
+                                    public virtual Predicate_i
   {
   public:
     FreeEdges_i();
@@ -526,7 +619,7 @@ namespace SMESH
     Description : Predicate for free faces
   */
   class SMESH_I_EXPORT FreeFaces_i: public virtual POA_SMESH::FreeFaces,
-                      public virtual Predicate_i
+                                    public virtual Predicate_i
   {
   public:
     FreeFaces_i();
@@ -539,7 +632,7 @@ namespace SMESH
     Description : Predicate for free nodes
   */
   class SMESH_I_EXPORT FreeNodes_i: public virtual POA_SMESH::FreeNodes,
-                      public virtual Predicate_i
+                                    public virtual Predicate_i
   {
   public:
     FreeNodes_i();
@@ -547,12 +640,63 @@ namespace SMESH
   };
   
   
+  /*
+    Class       : EqualNodes_i
+    Description : Predicate for equal nodes
+  */
+  class SMESH_I_EXPORT EqualNodes_i: public virtual POA_SMESH::EqualNodes,
+                                     public virtual Predicate_i
+  {
+  public:
+    EqualNodes_i();
+    FunctorType                     GetFunctorType();
+    void                            SetTolerance( double );
+    double                          GetTolerance();
+
+  private:
+    Controls::CoincidentNodesPtr myCoincidentNodesPtr;
+  };
+  /*
+    Class       : EqualEdges_i
+    Description : Predicate for equal edges
+  */
+  class SMESH_I_EXPORT EqualEdges_i: public virtual POA_SMESH::EqualEdges,
+                                     public virtual Predicate_i
+  {
+  public:
+    EqualEdges_i();
+    FunctorType                     GetFunctorType();
+  };
+  /*
+    Class       : EqualFaces_i
+    Description : Predicate for equal Faces
+  */
+  class SMESH_I_EXPORT EqualFaces_i: public virtual POA_SMESH::EqualFaces,
+                                     public virtual Predicate_i
+  {
+  public:
+    EqualFaces_i();
+    FunctorType                     GetFunctorType();
+  };
+  /*
+    Class       : EqualVolumes_i
+    Description : Predicate for equal Volumes
+  */
+  class SMESH_I_EXPORT EqualVolumes_i: public virtual POA_SMESH::EqualVolumes,
+                                       public virtual Predicate_i
+  {
+  public:
+    EqualVolumes_i();
+    FunctorType                     GetFunctorType();
+  };
+  
+  
   /*
     Class       : RangeOfIds_i
     Description : Predicate for Range of Ids
   */
   class SMESH_I_EXPORT RangeOfIds_i: public virtual POA_SMESH::RangeOfIds,
-                     public virtual Predicate_i
+                                     public virtual Predicate_i
   {
   public:
     RangeOfIds_i();
@@ -572,7 +716,7 @@ namespace SMESH
     Description : Verify whether a mesh element is linear
   */
   class SMESH_I_EXPORT LinearOrQuadratic_i: public virtual POA_SMESH::LinearOrQuadratic,
-                            public virtual Predicate_i
+                                            public virtual Predicate_i
   {
   public:
     LinearOrQuadratic_i();
@@ -588,7 +732,7 @@ namespace SMESH
     Description : Functor for check color of group to whic mesh element belongs to
   */
   class SMESH_I_EXPORT GroupColor_i: public virtual POA_SMESH::GroupColor,
-                 public virtual Predicate_i
+                                     public virtual Predicate_i
   {
   public:
     GroupColor_i();
@@ -607,7 +751,7 @@ namespace SMESH
     Description : Functor for check element geometry type
   */
   class SMESH_I_EXPORT ElemGeomType_i: public virtual POA_SMESH::ElemGeomType,
-                 public virtual Predicate_i
+                                       public virtual Predicate_i
   {
   public:
     ElemGeomType_i();
@@ -621,12 +765,32 @@ namespace SMESH
     Controls::ElemGeomTypePtr myElemGeomTypePtr;
   };
   
+  /*
+    Class       : CoplanarFaces_i
+    Description : Returns true if a mesh face is a coplanar neighbour to a given one
+  */
+  class SMESH_I_EXPORT CoplanarFaces_i: public virtual POA_SMESH::CoplanarFaces,
+                                        public virtual Predicate_i
+  {
+  public:
+    CoplanarFaces_i();
+    FunctorType             GetFunctorType();
+
+    void                    SetFace ( CORBA::Long theFaceID );
+    void                    SetTolerance( CORBA::Double theToler );
+    char*                   GetFaceAsString () const;
+    CORBA::Long             GetFace () const;
+    CORBA::Double           GetTolerance () const;
+  private:
+    Controls::CoplanarFacesPtr myCoplanarFacesPtr;
+  };
+  
   /*
     Class       : Comparator_i
     Description : Base class for comparators
   */
   class SMESH_I_EXPORT Comparator_i: public virtual POA_SMESH::Comparator,
-                     public virtual Predicate_i
+                                     public virtual Predicate_i
   {
   public:
     virtual                         ~Comparator_i();
@@ -651,7 +815,7 @@ namespace SMESH
     Description : Comparator "<"
   */
   class SMESH_I_EXPORT LessThan_i: public virtual POA_SMESH::LessThan,
-                   public virtual Comparator_i
+                                   public virtual Comparator_i
   {
   public:
     LessThan_i();
@@ -664,7 +828,7 @@ namespace SMESH
     Description : Comparator ">"
   */
   class SMESH_I_EXPORT MoreThan_i: public virtual POA_SMESH::MoreThan,
-                   public virtual Comparator_i
+                                   public virtual Comparator_i
   {
   public:
     MoreThan_i();
@@ -677,7 +841,7 @@ namespace SMESH
     Description : Comparator "="
   */
   class SMESH_I_EXPORT EqualTo_i: public virtual POA_SMESH::EqualTo,
-                  public virtual Comparator_i
+                                  public virtual Comparator_i
   {
   public:
     EqualTo_i();
@@ -695,7 +859,7 @@ namespace SMESH
     Description : Logical NOT predicate
   */
   class SMESH_I_EXPORT LogicalNOT_i: public virtual POA_SMESH::LogicalNOT,
-                     public virtual Predicate_i
+                                     public virtual Predicate_i
   {
   public:
     LogicalNOT_i();
@@ -716,7 +880,7 @@ namespace SMESH
     Description : Base class for binary logical predicate
   */
   class SMESH_I_EXPORT LogicalBinary_i: public virtual POA_SMESH::LogicalBinary,
-                        public virtual Predicate_i
+                                        public virtual Predicate_i
   {
   public:
     virtual                         ~LogicalBinary_i();
@@ -742,7 +906,7 @@ namespace SMESH
     Description : Logical AND
   */
   class SMESH_I_EXPORT LogicalAND_i: public virtual POA_SMESH::LogicalAND,
-                     public virtual LogicalBinary_i
+                                     public virtual LogicalBinary_i
   {
   public:
     LogicalAND_i();
@@ -755,7 +919,7 @@ namespace SMESH
     Description : Logical OR
   */
   class SMESH_I_EXPORT LogicalOR_i: public virtual POA_SMESH::LogicalOR,
-                    public virtual LogicalBinary_i
+                                    public virtual LogicalBinary_i
   {
   public:
     LogicalOR_i();
@@ -767,7 +931,7 @@ namespace SMESH
     FILTER
   */
   class SMESH_I_EXPORT Filter_i: public virtual POA_SMESH::Filter,
-                 public virtual SALOME::GenericObj_i
+                                 public virtual SALOME::GenericObj_i
   {
   public:
     Filter_i();
@@ -781,20 +945,16 @@ namespace SMESH
     void
     SetMesh( SMESH_Mesh_ptr );
 
-    virtual
-    SMESH::long_array* 
-    GetIDs();
-    
     static
     void
     GetElementsId( Predicate_i*,
-                  const SMDS_Mesh*,
-                  Controls::Filter::TIdSequence& );
+                   const SMDS_Mesh*,
+                   Controls::Filter::TIdSequence& );
     static
     void           
     GetElementsId( Predicate_i*,
-                  SMESH_Mesh_ptr,
-                  Controls::Filter::TIdSequence& );
+                   SMESH_Mesh_ptr,
+                   Controls::Filter::TIdSequence& );
     
     virtual
     long_array*      
@@ -818,10 +978,31 @@ namespace SMESH
 
     Predicate_i*     GetPredicate_i();
 
+    // =========================
+    // SMESH_IDSource interface
+    // =========================
+    virtual SMESH::long_array*           GetIDs();
+    virtual SMESH::long_array*           GetMeshInfo();
+    virtual SMESH::array_of_ElementType* GetTypes();
+    virtual SMESH::SMESH_Mesh_ptr        GetMesh();
+    virtual bool                         IsMeshInfoCorrect() { return true; }
+
+    /*!
+     * \brief Object notified on change of predicate
+     */
+    struct TPredicateChangeWaiter
+    {
+      virtual void PredicateChanged() = 0;
+    };
+    void AddWaiter( TPredicateChangeWaiter* waiter );
+    void RemoveWaiter( TPredicateChangeWaiter* waiter );
+
   private:
     Controls::Filter myFilter;
     Predicate_i*     myPredicate;
     SMESH_Mesh_var   myMesh;
+
+    std::list<TPredicateChangeWaiter*> myWaiters;
   };
   
   
@@ -829,7 +1010,7 @@ namespace SMESH
     FILTER LIBRARY
   */
   class SMESH_I_EXPORT FilterLibrary_i: public virtual POA_SMESH::FilterLibrary,
-                        public virtual SALOME::GenericObj_i
+                                        public virtual SALOME::GenericObj_i
   {
   public:
     FilterLibrary_i( const char* theFileName );
@@ -842,8 +1023,8 @@ namespace SMESH
     CORBA::Boolean          AddEmpty( const char* theFilterName, ElementType theType );
     CORBA::Boolean          Delete  ( const char* theFilterName );
     CORBA::Boolean          Replace ( const char* theFilterName, 
-                                     const char* theNewName, 
-                                     Filter_ptr  theFilter );
+                                      const char* theNewName, 
+                                      Filter_ptr  theFilter );
     
     CORBA::Boolean          Save();
     CORBA::Boolean          SaveAs( const char* aFileName );
@@ -867,7 +1048,7 @@ namespace SMESH
   */
   
   class SMESH_I_EXPORT FilterManager_i: public virtual POA_SMESH::FilterManager,
-                        public virtual SALOME::GenericObj_i
+                                        public virtual SALOME::GenericObj_i
   {
   public:
     FilterManager_i();
@@ -881,10 +1062,13 @@ namespace SMESH
     Skew_ptr                  CreateSkew();
     Area_ptr                  CreateArea();
     Volume3D_ptr              CreateVolume3D();
+    MaxElementLength2D_ptr    CreateMaxElementLength2D();
+    MaxElementLength3D_ptr    CreateMaxElementLength3D();
     Length_ptr                CreateLength();
     Length2D_ptr              CreateLength2D();
     MultiConnection_ptr       CreateMultiConnection();
     MultiConnection2D_ptr     CreateMultiConnection2D();
+    BallDiameter_ptr          CreateBallDiameter();
     
     BelongToGeom_ptr          CreateBelongToGeom();
     BelongToPlane_ptr         CreateBelongToPlane();
@@ -897,15 +1081,22 @@ namespace SMESH
     FreeEdges_ptr             CreateFreeEdges();
     FreeNodes_ptr             CreateFreeNodes();
     FreeFaces_ptr             CreateFreeFaces();
-    
+
+    EqualNodes_ptr            CreateEqualNodes();
+    EqualEdges_ptr            CreateEqualEdges();
+    EqualFaces_ptr            CreateEqualFaces();
+    EqualVolumes_ptr          CreateEqualVolumes();
+
     RangeOfIds_ptr            CreateRangeOfIds();
-    
     BadOrientedVolume_ptr     CreateBadOrientedVolume();
+    BareBorderFace_ptr        CreateBareBorderFace();
+    BareBorderVolume_ptr      CreateBareBorderVolume();
+    OverConstrainedFace_ptr   CreateOverConstrainedFace();
+    OverConstrainedVolume_ptr CreateOverConstrainedVolume();
     LinearOrQuadratic_ptr     CreateLinearOrQuadratic();
-    
     GroupColor_ptr            CreateGroupColor();
-
     ElemGeomType_ptr          CreateElemGeomType();
+    CoplanarFaces_ptr         CreateCoplanarFaces();
 
     LessThan_ptr              CreateLessThan();
     MoreThan_ptr              CreateMoreThan();
@@ -925,6 +1116,9 @@ namespace SMESH
   
   Predicate_i* 
   GetPredicate( SMESH::Predicate_ptr thePredicate );
+
+  const char*        FunctorTypeToString(SMESH::FunctorType ft);
+  SMESH::FunctorType StringToFunctorType(const char*       str);
 }
 
 
index e90e690f759e238dc86f9f8847267c5f93d74fbe..24b30bb62e2c5013e60b976dd36db43ebd79da1c 100644 (file)
@@ -1,29 +1,28 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : SMESH_Gen_i.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//
+
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopoDS.hxx>
 #include <TCollection_AsciiString.hxx>
 #include <OSD.hxx>
 
-#include "Utils_CorbaException.hxx"
-
-#include "utilities.h"
-#include <fstream>
-#include <stdio.h>
-
 #ifdef WNT
  #include <windows.h>
+ #include <process.h>
 #else
  #include <dlfcn.h>
 #endif
  #define UnLoadLib( handle ) dlclose( handle );
 #endif
 
-#include <HDFOI.hxx>
-
 #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 "SMESH_PythonDump.hxx"
 
+#include "SMDS_EdgePosition.hxx"
+#include "SMDS_FacePosition.hxx"
+#include "SMDS_PolyhedralVolumeOfNodes.hxx"
+#include "SMDS_SetIterator.hxx"
+#include "SMDS_SpacePosition.hxx"
+#include "SMDS_VertexPosition.hxx"
 #include "SMESHDS_Document.hxx"
 #include "SMESHDS_Group.hxx"
 #include "SMESHDS_GroupOnGeom.hxx"
-#include "SMESH_Mesh.hxx"
-#include "SMESH_Hypothesis.hxx"
+#include "SMESH_Algo_i.hxx"
+#include "SMESH_File.hxx"
 #include "SMESH_Group.hxx"
+#include "SMESH_Group_i.hxx"
+#include "SMESH_Hypothesis.hxx"
+#include "SMESH_Hypothesis_i.hxx"
+#include "SMESH_Mesh.hxx"
 #include "SMESH_MeshEditor.hxx"
-
-#include "SMDS_EdgePosition.hxx"
-#include "SMDS_FacePosition.hxx"
-#include "SMDS_VertexPosition.hxx"
-#include "SMDS_SpacePosition.hxx"
-#include "SMDS_PolyhedralVolumeOfNodes.hxx"
+#include "SMESH_Mesh_i.hxx"
+#include "SMESH_PreMeshInfo.hxx"
+#include "SMESH_PythonDump.hxx"
 
 #include CORBA_SERVER_HEADER(SMESH_Group)
 #include CORBA_SERVER_HEADER(SMESH_Filter)
 
 #include "DriverMED_W_SMESHDS_Mesh.h"
 #include "DriverMED_R_SMESHDS_Mesh.h"
+#ifdef WITH_CGNS
+#include "DriverCGNS_Read.hxx"
+#endif
+#include "memoire.h"
 
-#include "SALOMEDS_Tool.hxx"
-#include "SALOME_NamingService.hxx"
-#include "SALOME_LifeCycleCORBA.hxx"
-#include "Utils_SINGLETON.hxx"
-#include "OpUtil.hxx"
+#include <GEOM_Client.hxx>
 
-#include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
+#include <Basics_Utils.hxx>
+#include <HDFOI.hxx>
+#include <OpUtil.hxx>
+#include <SALOMEDS_Tool.hxx>
+#include <SALOME_Container_i.hxx>
+#include <SALOME_LifeCycleCORBA.hxx>
+#include <SALOME_NamingService.hxx>
+#include <Utils_CorbaException.hxx>
+#include <Utils_ExceptHandlers.hxx>
+#include <Utils_SINGLETON.hxx>
+#include <utilities.h>
 
-#include "GEOM_Client.hxx"
-#include "Utils_ExceptHandlers.hxx"
+#include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
+#include CORBA_CLIENT_HEADER(SALOME_Session)
 
 #include <map>
+#include <fstream>
+#include <cstdio>
 
 using namespace std;
 using SMESH::TPythonDump;
+using SMESH::TVar;
 
 #define NUM_TMP_FILES 2
 
@@ -150,9 +157,9 @@ PortableServer::ServantBase_var SMESH_Gen_i::GetServant( CORBA::Object_ptr theOb
   try {
     PortableServer::Servant aServant = GetPOA()->reference_to_servant( theObject );
     return aServant;
-  } 
+  }
   catch (...) {
-    INFOS( "GetServant - Unknown exception was caught!!!" ); 
+    INFOS( "GetServant - Unknown exception was caught!!!" );
     return NULL;
   }
 }
@@ -172,11 +179,11 @@ CORBA::Object_var SMESH_Gen_i::SObjectToObject( SALOMEDS::SObject_ptr theSObject
   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 );
-       }
+        SALOMEDS::AttributeIOR_var anIOR  = SALOMEDS::AttributeIOR::_narrow( anAttr );
+        CORBA::String_var aValue = anIOR->Value();
+        if( strcmp( aValue, "" ) != 0 )
+          anObj = GetORB()->string_to_object( aValue );
+        }
     }
     catch( ... ) {
       INFOS( "SObjectToObject - Unknown exception was caught!!!" );
@@ -189,7 +196,7 @@ CORBA::Object_var SMESH_Gen_i::SObjectToObject( SALOMEDS::SObject_ptr theSObject
 /*!
  *  GetNS [ static ]
  *
- *  Get SALOME_NamingService object 
+ *  Get SALOME_NamingService object
  */
 //=============================================================================
 
@@ -209,7 +216,7 @@ SALOME_NamingService* SMESH_Gen_i::GetNS()
  *
  *  Get SALOME_LifeCycleCORBA object
  */
-//=============================================================================     
+//=============================================================================
 SALOME_LifeCycleCORBA*  SMESH_Gen_i::GetLCC() {
   if ( myLCC == NULL ) {
     myLCC = new SALOME_LifeCycleCORBA( GetNS() );
@@ -224,14 +231,14 @@ SALOME_LifeCycleCORBA*  SMESH_Gen_i::GetLCC() {
  *
  *  Get GEOM::GEOM_Gen reference
  */
-//=============================================================================     
+//=============================================================================
 GEOM::GEOM_Gen_ptr SMESH_Gen_i::GetGeomEngine() {
   //CCRT GEOM::GEOM_Gen_var aGeomEngine =
   //CCRT   GEOM::GEOM_Gen::_narrow( GetLCC()->FindOrLoad_Component("FactoryServer","GEOM") );
   //CCRT return aGeomEngine._retn();
   if(CORBA::is_nil(myGeomGen))
   {
-    Engines::Component_ptr temp=GetLCC()->FindOrLoad_Component("FactoryServer","GEOM");
+    Engines::EngineComponent_ptr temp=GetLCC()->FindOrLoad_Component("FactoryServer","GEOM");
     myGeomGen=GEOM::GEOM_Gen::_narrow(temp);
   }
   return myGeomGen;
@@ -252,16 +259,16 @@ SMESH_Gen_i::SMESH_Gen_i()
 
 //=============================================================================
 /*!
- *  SMESH_Gen_i::SMESH_Gen_i 
+ *  SMESH_Gen_i::SMESH_Gen_i
  *
  *  Standard constructor, used with Container
  */
 //=============================================================================
 
 SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr            orb,
-                         PortableServer::POA_ptr   poa,
-                         PortableServer::ObjectId* contId, 
-                         const char*               instanceName, 
+                          PortableServer::POA_ptr   poa,
+                          PortableServer::ObjectId* contId,
+                          const char*               instanceName,
                           const char*               interfaceName )
      : Engines_Component_i( orb, poa, contId, instanceName, interfaceName )
 {
@@ -269,16 +276,40 @@ SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr            orb,
 
   myOrb = CORBA::ORB::_duplicate(orb);
   myPoa = PortableServer::POA::_duplicate(poa);
-  
+
   _thisObj = this ;
   _id = myPoa->activate_object( _thisObj );
-  
+
   myIsEmbeddedMode = false;
   myShapeReader = NULL;  // shape reader
   mySMESHGen = this;
+  myIsHistoricalPythonDump = true;
+  myToForgetMeshDataOnHypModif = false;
 
   // set it in standalone mode only
   //OSD::SetSignal( true );
+
+  // 0020605: EDF 1190 SMESH: Display performance. 80 seconds for 52000 cells.
+  // find out mode (embedded or standalone) here else
+  // meshes created before calling SMESH_Client::GetSMESHGen(), which calls
+  // SMESH_Gen_i::SetEmbeddedMode(), have wrong IsEmbeddedMode flag
+  if ( SALOME_NamingService* ns = GetNS() )
+  {
+    CORBA::Object_var obj = ns->Resolve( "/Kernel/Session" );
+    SALOME::Session_var session = SALOME::Session::_narrow( obj ) ;
+    if ( !session->_is_nil() )
+    {
+      CORBA::String_var str_host = session->getHostname();
+      CORBA::Long        s_pid = session->getPID();
+      string my_host = Kernel_Utils::GetHostname();
+#ifdef WNT
+      long    my_pid = (long)_getpid();
+#else
+      long    my_pid = (long) getpid();
+#endif
+      SetEmbeddedMode( s_pid == my_pid && my_host == str_host.in() );
+    }
+  }
 }
 
 //=============================================================================
@@ -291,7 +322,7 @@ SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr            orb,
 
 SMESH_Gen_i::~SMESH_Gen_i()
 {
-  INFOS( "SMESH_Gen_i::~SMESH_Gen_i" );
+  MESSAGE( "SMESH_Gen_i::~SMESH_Gen_i" );
 
   // delete hypothesis creators
   map<string, GenericHypothesisCreator_i*>::iterator itHyp;
@@ -308,10 +339,10 @@ SMESH_Gen_i::~SMESH_Gen_i()
   }
   myStudyContextMap.clear();
   // delete shape reader
-  if ( !myShapeReader ) 
+  if ( !myShapeReader )
     delete myShapeReader;
 }
-  
+
 //=============================================================================
 /*!
  *  SMESH_Gen_i::createHypothesis
@@ -349,7 +380,7 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::createHypothesis(const char* theHypName
     }
     else
     {
-      //try to use new format 
+      //try to use new format
 #ifdef WNT
       aPlatformLibName = new char[ libNameLen + 5 ];
       aPlatformLibName[0] = '\0';
@@ -435,7 +466,7 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::createHypothesis(const char* theHypName
   // activate the CORBA servant of hypothesis
   hypothesis_i = SMESH::SMESH_Hypothesis::_narrow( myHypothesis_i->_this() );
   int nextId = RegisterObject( hypothesis_i );
-  if(MYDEBUG) MESSAGE( "Add hypo to map with id = "<< nextId );  
+  if(MYDEBUG) MESSAGE( "Add hypo to map with id = "<< nextId );
 
   return hypothesis_i._retn();
 }
@@ -458,6 +489,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh()
     // create a new mesh object servant, store it in a map in study context
     SMESH_Mesh_i* meshServant = new SMESH_Mesh_i( GetPOA(), this, GetCurrentStudyID() );
     // create a new mesh object
+    MESSAGE("myIsEmbeddedMode " << myIsEmbeddedMode);
     meshServant->SetImpl( myGen.CreateMesh( GetCurrentStudyID(), myIsEmbeddedMode ));
 
     // activate the CORBA servant of Mesh
@@ -482,7 +514,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh()
 GEOM_Client* SMESH_Gen_i::GetShapeReader()
 {
   // create shape reader if necessary
-  if ( !myShapeReader ) 
+  if ( !myShapeReader )
     myShapeReader = new GEOM_Client(GetContainerRef());
   ASSERT( myShapeReader );
   return myShapeReader;
@@ -515,6 +547,7 @@ void SMESH_Gen_i::SetGeomEngine( GEOM::GEOM_Gen_ptr geomcompo )
 void SMESH_Gen_i::SetEmbeddedMode( CORBA::Boolean theMode )
 {
   myIsEmbeddedMode = theMode;
+  MESSAGE("myIsEmbeddedMode " << myIsEmbeddedMode);
 
   if ( !myIsEmbeddedMode ) {
     //PAL10867: disable signals catching with "noexcepthandler" option
@@ -559,25 +592,43 @@ CORBA::Boolean SMESH_Gen_i::IsEmbeddedMode()
 
 void SMESH_Gen_i::SetCurrentStudy( SALOMEDS::Study_ptr theStudy )
 {
-  //if(MYDEBUG)
-  //MESSAGE( "SMESH_Gen_i::SetCurrentStudy" );
+  setCurrentStudy( theStudy );
+}
+
+void SMESH_Gen_i::setCurrentStudy( SALOMEDS::Study_ptr theStudy,
+                                   bool                theStudyIsBeingClosed)
+{
+  int curStudyId = GetCurrentStudyID();
   myCurrentStudy = SALOMEDS::Study::_duplicate( theStudy );
   // create study context, if it doesn't exist and set current study
   int studyId = GetCurrentStudyID();
-  if(MYDEBUG) MESSAGE( "SMESH_Gen_i::SetCurrentStudy: study Id = " << studyId );
   if ( myStudyContextMap.find( studyId ) == myStudyContextMap.end() ) {
-    myStudyContextMap[ studyId ] = new StudyContext;      
+    myStudyContextMap[ studyId ] = new StudyContext;
   }
 
   // myCurrentStudy may be nil
-  if ( !CORBA::is_nil( myCurrentStudy ) ) {
-    SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); 
+  if ( !theStudyIsBeingClosed && !CORBA::is_nil( myCurrentStudy ) ) {
+    SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
     if( !myCurrentStudy->FindComponent( "GEOM" )->_is_nil() )
       aStudyBuilder->LoadWith( myCurrentStudy->FindComponent( "GEOM" ), GetGeomEngine() );
 
-  // set current study for geom engine
-  //if ( !CORBA::is_nil( GetGeomEngine() ) )
-  //  GetGeomEngine()->GetCurrentStudy( myCurrentStudy->StudyId() );
+    // NPAL16168, issue 0020210
+    // Let meshes update their data depending on GEOM groups that could change
+    if ( curStudyId != studyId )
+    {
+      //SALOMEDS::SComponent_var me =  PublishComponent( myCurrentStudy );
+      SALOMEDS::SComponent_var me = SALOMEDS::SComponent::_narrow
+        ( myCurrentStudy->FindComponent( ComponentDataType() ) );
+      if ( !me->_is_nil() ) {
+        SALOMEDS::ChildIterator_var anIter = myCurrentStudy->NewChildIterator( me );
+        for ( ; anIter->More(); anIter->Next() ) {
+          SALOMEDS::SObject_var so = anIter->Value();
+          CORBA::Object_var    ior = SObjectToObject( so );
+          if ( SMESH_Mesh_i*  mesh = SMESH::DownCast<SMESH_Mesh_i*>( ior ))
+            mesh->CheckGeomGroupModif();
+        }
+      }
+    }
   }
 }
 
@@ -597,7 +648,7 @@ SALOMEDS::Study_ptr SMESH_Gen_i::GetCurrentStudy()
 
 //=============================================================================
 /*!
- *  SMESH_Gen_i::GetCurrentStudyContext 
+ *  SMESH_Gen_i::GetCurrentStudyContext
  *
  *  Get current study context
  */
@@ -613,7 +664,7 @@ StudyContext* SMESH_Gen_i::GetCurrentStudyContext()
 
 //=============================================================================
 /*!
- *  SMESH_Gen_i::CreateHypothesis 
+ *  SMESH_Gen_i::CreateHypothesis
  *
  *  Create hypothesis/algorothm of given type and publish it in the study
  */
@@ -711,7 +762,7 @@ SMESH_Gen_i::GetHypothesisParameterValues (const char*           theHypType,
       }
     }
 
-    // let the temporary hypothesis find out some how parameter values by mesh
+    // let the temporary hypothesis find out somehow parameter values by mesh
     if ( hyp->SetParametersByMesh( mesh, shape ))
       return SMESH::SMESH_Hypothesis::_duplicate( tmpHyp );
   }
@@ -724,6 +775,7 @@ SMESH_Gen_i::GetHypothesisParameterValues (const char*           theHypType,
     ::SMESH_Hypothesis::TDefaults dflts;
     dflts._elemLength = diagonal / myGen.GetBoundaryBoxSegmentation();
     dflts._nbSegments = myGen.GetDefaultNbSegments();
+    dflts._shape      = &shape;
     // let the temporary hypothesis initialize it's values
     if ( hyp->SetParametersByDefaults( dflts, mesh ))
       return SMESH::SMESH_Hypothesis::_duplicate( tmpHyp );
@@ -755,12 +807,69 @@ void SMESH_Gen_i::SetBoundaryBoxSegmentation( CORBA::Long theNbSegments )
 void SMESH_Gen_i::SetDefaultNbSegments(CORBA::Long theNbSegments)
   throw ( SALOME::SALOME_Exception )
 {
-  if ( theNbSegments )
+  if ( theNbSegments > 0 )
     myGen.SetDefaultNbSegments( int(theNbSegments) );
   else
     THROW_SALOME_CORBA_EXCEPTION( "non-positive number of segments", SALOME::BAD_PARAM );
 }
 
+//=============================================================================
+/*!
+  Set an option value
+*/
+//=============================================================================
+
+void SMESH_Gen_i::SetOption(const char* name, const char* value)
+{
+  if ( name && value && strlen( value ) > 0 )
+  {
+    string msgToGUI; 
+    if ( strcmp(name, "historical_python_dump") == 0 )
+    {
+      myIsHistoricalPythonDump = ( value[0] == '1' || toupper(value[0]) == 'T' ); // 1 || true
+      msgToGUI = "preferences/SMESH/historical_python_dump/";
+      msgToGUI += myIsHistoricalPythonDump ? "true" : "false";
+    }
+    else if ( strcmp(name, "forget_mesh_on_hyp_modif") == 0 )
+    {
+      myToForgetMeshDataOnHypModif = ( value[0] == '1' || toupper(value[0]) == 'T' ); // 1 || true
+      msgToGUI = "preferences/SMESH/forget_mesh_on_hyp_modif/";
+      msgToGUI += myToForgetMeshDataOnHypModif ? "true" : "false";
+    }
+
+    // update preferences in case if SetOption() is invoked from python console
+    if ( !msgToGUI.empty() )
+    {
+      CORBA::Object_var obj = SMESH_Gen_i::GetNS()->Resolve( "/Kernel/Session" );
+      SALOME::Session_var session = SALOME::Session::_narrow( obj );
+      if ( !CORBA::is_nil( session ) )
+        session->emitMessageOneWay(msgToGUI.c_str());
+    }
+  }
+}
+
+//=============================================================================
+/*!
+  Return an option value
+*/
+//=============================================================================
+
+char* SMESH_Gen_i::GetOption(const char* name)
+{
+  if ( name )
+  {
+    if ( strcmp(name, "historical_python_dump") == 0 )
+    {
+      return CORBA::string_dup( myIsHistoricalPythonDump ? "true" : "false" );
+    }
+    if ( strcmp(name, "forget_mesh_on_hyp_modif") == 0 )
+    {
+      return CORBA::string_dup( myToForgetMeshDataOnHypModif ? "true" : "false" );
+    }
+  }
+  return CORBA::string_dup( "" );
+}
+
 //=============================================================================
 /*!
  *  SMESH_Gen_i::CreateMesh
@@ -851,7 +960,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName
     aStudyBuilder->CommitCommand();
     if ( !aSO->_is_nil() ) {
       // Update Python script
-      TPythonDump() << aSO << " = smeshgen.CreateMeshesFromUNV('" << theFileName << "')";
+      TPythonDump() << aSO << " = smeshgen.CreateMeshesFromUNV(r'" << theFileName << "')";
     }
   }
 
@@ -860,8 +969,9 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName
   aServant->ImportUNVFile( theFileName );
 
   // Dump creation of groups
-  aServant->GetGroups();
+  SMESH::ListOfGroups_var groups = aServant->GetGroups();
 
+  aServant->GetImpl().GetMeshDS()->Modified();
   return aMesh._retn();
 }
 
@@ -873,13 +983,11 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName
  */
 //=============================================================================
 
-SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName,
-                                                     SMESH::DriverMED_ReadStatus& theStatus)
-     throw ( SALOME::SALOME_Exception )
+SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMEDorSAUV( const char* theFileName,
+                                                           SMESH::DriverMED_ReadStatus& theStatus,
+                                                           const char* theCommandNameForPython,
+                                                           const char* theFileNameForPython)
 {
-  Unexpect aCatch(SALOME_SalomeException);
-  if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMeshFromMED" );
-
   // Retrieve mesh names from the file
   DriverMED_R_SMESHDS_Mesh myReader;
   myReader.SetFile( theFileName );
@@ -894,23 +1002,21 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName,
   // Python Dump
   TPythonDump aPythonDump;
   aPythonDump << "([";
-  //TCollection_AsciiString aStr ("([");
 
   if (theStatus == SMESH::DRS_OK) {
     SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
     aStudyBuilder->NewCommand();  // There is a transaction
     aResult->length( aNames.size() );
     int i = 0;
-    
+
     // Iterate through all meshes and create mesh objects
     for ( list<string>::iterator it = aNames.begin(); it != aNames.end(); it++ ) {
       // Python Dump
-      //if (i > 0) aStr += ", ";
       if (i > 0) aPythonDump << ", ";
 
       // create mesh
       SMESH::SMESH_Mesh_var mesh = createMesh();
-      
+
       // publish mesh in the study
       SALOMEDS::SObject_var aSO;
       if ( CanPublishInStudy( mesh ) )
@@ -918,37 +1024,85 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName,
       if ( !aSO->_is_nil() ) {
         // Python Dump
         aPythonDump << aSO;
-        //aStr += aSO->GetID();
       } else {
         // Python Dump
         aPythonDump << "mesh_" << i;
-//         aStr += "mesh_";
-//         aStr += TCollection_AsciiString(i);
       }
 
       // Read mesh data (groups are published automatically by ImportMEDFile())
       SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( mesh ).in() );
       ASSERT( meshServant );
       SMESH::DriverMED_ReadStatus status1 =
-       meshServant->ImportMEDFile( theFileName, (*it).c_str() );
+        meshServant->ImportMEDFile( theFileName, (*it).c_str() );
       if (status1 > theStatus)
-       theStatus = status1;
+        theStatus = status1;
 
       aResult[i++] = SMESH::SMESH_Mesh::_duplicate( mesh );
+      meshServant->GetImpl().GetMeshDS()->Modified();
     }
     aStudyBuilder->CommitCommand();
   }
 
   // Update Python script
-  aPythonDump << "], status) = " << this << ".CreateMeshesFromMED('" << theFileName << "')";
+  aPythonDump << "], status) = " << this << "." << theCommandNameForPython << "(r'" << theFileNameForPython << "')";
   }
   // Dump creation of groups
   for ( int i = 0; i < aResult->length(); ++i )
-    aResult[ i ]->GetGroups();
+    SMESH::ListOfGroups_var groups = aResult[ i ]->GetGroups();
 
   return aResult._retn();
 }
 
+SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName,
+                                                     SMESH::DriverMED_ReadStatus& theStatus)
+     throw ( SALOME::SALOME_Exception )
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMeshFromMED" );
+  SMESH::mesh_array* result = CreateMeshesFromMEDorSAUV(theFileName, theStatus, "CreateMeshesFromMED", theFileName);
+  return result;
+}
+
+//=============================================================================
+/*!
+ *  SMESH_Gen_i::CreateMeshFromSAUV
+ *
+ *  Create mesh and import data from SAUV file
+ */
+//=============================================================================
+
+SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromSAUV( const char* theFileName,
+                                                      SMESH::DriverMED_ReadStatus& theStatus)
+     throw ( SALOME::SALOME_Exception )
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMeshFromSAUV" );
+  std::string sauvfilename(theFileName);
+  std::string medfilename(theFileName);
+  medfilename += ".med";
+  std::string cmd;
+#ifdef WNT
+  cmd = "%PYTHONBIN% ";
+#else
+  cmd = "python ";
+#endif
+  cmd += "-c \"";
+  cmd += "from medutilities import convert ; convert(r'" + sauvfilename + "', 'GIBI', 'MED', 1, r'" + medfilename + "')";
+  cmd += "\"";
+  system(cmd.c_str());
+  SMESH::mesh_array* result = CreateMeshesFromMEDorSAUV(medfilename.c_str(), theStatus, "CreateMeshesFromSAUV", sauvfilename.c_str());
+#ifdef WNT
+  cmd = "%PYTHONBIN% ";
+#else
+  cmd = "python ";
+#endif
+  cmd += "-c \"";
+  cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')";
+  cmd += "\"";
+  system(cmd.c_str());
+  return result;
+}
+
 //=============================================================================
 /*!
  *  SMESH_Gen_i::CreateMeshFromSTL
@@ -974,16 +1128,100 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromSTL( const char* theFileName
     aStudyBuilder->CommitCommand();
     if ( !aSO->_is_nil() ) {
       // Update Python script
-      TPythonDump() << aSO << " = " << this << ".CreateMeshesFromSTL('" << theFileName << "')";
+      TPythonDump() << aSO << " = " << this << ".CreateMeshesFromSTL(r'" << theFileName << "')";
     }
   }
 
   SMESH_Mesh_i* aServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( aMesh ).in() );
   ASSERT( aServant );
   aServant->ImportSTLFile( theFileName );
+  aServant->GetImpl().GetMeshDS()->Modified();
   return aMesh._retn();
 }
 
+//================================================================================
+/*!
+ * \brief Create meshes and import data from the CGSN file
+ */
+//================================================================================
+
+SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromCGNS( const char* theFileName,
+                                                      SMESH::DriverMED_ReadStatus& theStatus)
+  throw ( SALOME::SALOME_Exception )
+{
+  Unexpect aCatch(SALOME_SalomeException);
+
+  SMESH::mesh_array_var aResult = new SMESH::mesh_array();
+
+#ifdef WITH_CGNS
+  // Retrieve nb meshes from the file
+  DriverCGNS_Read myReader;
+  myReader.SetFile( theFileName );
+  Driver_Mesh::Status aStatus;
+  int nbMeshes = myReader.GetNbMeshes(aStatus);
+  theStatus = (SMESH::DriverMED_ReadStatus)aStatus;
+
+  aResult->length( nbMeshes );
+
+  { // open a new scope to make aPythonDump die before PythonDump in SMESH_Mesh::GetGroups()
+
+    // Python Dump
+    TPythonDump aPythonDump;
+    aPythonDump << "([";
+
+    if (theStatus == SMESH::DRS_OK)
+    {
+      SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
+      aStudyBuilder->NewCommand();  // There is a transaction
+
+      int i = 0;
+
+      // Iterate through all meshes and create mesh objects
+      for ( ; i < nbMeshes; ++i )
+      {
+        // Python Dump
+        if (i > 0) aPythonDump << ", ";
+
+        // create mesh
+        SMESH::SMESH_Mesh_var mesh = createMesh();
+        aResult[i] = SMESH::SMESH_Mesh::_duplicate( mesh );
+
+        // Read mesh data (groups are published automatically by ImportMEDFile())
+        SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( mesh ).in() );
+        ASSERT( meshServant );
+        string meshName;
+        SMESH::DriverMED_ReadStatus status1 =
+          meshServant->ImportCGNSFile( theFileName, i, meshName );
+        if (status1 > theStatus)
+          theStatus = status1;
+
+        meshServant->GetImpl().GetMeshDS()->Modified();
+        // publish mesh in the study
+        SALOMEDS::SObject_var aSO;
+        if ( CanPublishInStudy( mesh ) )
+          aSO = PublishMesh( myCurrentStudy, mesh.in(), meshName.c_str() );
+
+        // Python Dump
+        if ( !aSO->_is_nil() )
+          aPythonDump << aSO;
+        else
+          aPythonDump << "mesh_" << i;
+      }
+      aStudyBuilder->CommitCommand();
+    }
+
+    aPythonDump << "], status) = " << this << ".CreateMeshesFromCGNS(r'" << theFileName << "')";
+  }
+  // Dump creation of groups
+  for ( int i = 0; i < aResult->length(); ++i )
+    SMESH::ListOfGroups_var groups = aResult[ i ]->GetGroups();
+#else
+  THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
+#endif
+
+  return aResult._retn();
+}
+
 //=============================================================================
 /*!
  *  SMESH_Gen_i::IsReadyToCompute
@@ -1000,7 +1238,7 @@ CORBA::Boolean SMESH_Gen_i::IsReadyToCompute( SMESH::SMESH_Mesh_ptr theMesh,
   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::IsReadyToCompute" );
 
   if ( CORBA::is_nil( theShapeObject ) )
-    THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", 
+    THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference",
                                   SALOME::BAD_PARAM );
 
   if ( CORBA::is_nil( theMesh ) )
@@ -1068,7 +1306,7 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::GetAlgoSO(const ::SMESH_Algo* algo)
  */
 //================================================================================
 
-SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr theMesh, 
+SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr theMesh,
                                                            GEOM::GEOM_Object_ptr theSubObject )
   throw ( SALOME::SALOME_Exception )
 {
@@ -1090,7 +1328,7 @@ SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr
         shape = GeomObjectToShape( theSubObject );
       else
         shape = SMESH_Mesh::PseudoShape();
-      
+
       ::SMESH_Mesh& mesh = meshServant->GetImpl();
 
       error_array->length( mesh.GetMeshDS()->MaxShapeIndex() );
@@ -1130,7 +1368,7 @@ SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr
   return error_array._retn();
 }
 
-// 
+//
 //================================================================================
 /*!
  * \brief Return mesh elements preventing computation of a subshape
@@ -1225,7 +1463,7 @@ SMESH_Gen_i::GetBadInputElements( SMESH::SMESH_Mesh_ptr theMesh,
  */
 //================================================================================
 
-SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMesh, 
+SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMesh,
                                                     GEOM::GEOM_Object_ptr theSubObject )
       throw ( SALOME::SALOME_Exception )
 {
@@ -1248,7 +1486,7 @@ SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMes
         myLocShape = GeomObjectToShape( theSubObject );
       else
         myLocShape = SMESH_Mesh::PseudoShape();
-      
+
       ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
       list< ::SMESH_Gen::TAlgoStateError > error_list;
       list< ::SMESH_Gen::TAlgoStateError >::iterator error;
@@ -1285,7 +1523,7 @@ SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMes
 //=============================================================================
 
 SMESH::long_array* SMESH_Gen_i::GetSubShapesId( GEOM::GEOM_Object_ptr theMainShapeObject,
-                                           const SMESH::object_array& theListOfSubShapeObject )
+                                            const SMESH::object_array& theListOfSubShapeObject )
      throw ( SALOME::SALOME_Exception )
 {
   Unexpect aCatch(SALOME_SalomeException);
@@ -1301,47 +1539,47 @@ SMESH::long_array* SMESH_Gen_i::GetSubShapesId( GEOM::GEOM_Object_ptr theMainSha
   try
     {
       TopoDS_Shape myMainShape = GeomObjectToShape(theMainShapeObject);
-      TopTools_IndexedMapOfShape myIndexToShape;      
+      TopTools_IndexedMapOfShape myIndexToShape;
       TopExp::MapShapes(myMainShape,myIndexToShape);
 
       for ( int i = 0; i < theListOfSubShapeObject.length(); i++ )
-       {
-         GEOM::GEOM_Object_var aShapeObject
-           = GEOM::GEOM_Object::_narrow(theListOfSubShapeObject[i]);
-         if ( CORBA::is_nil( aShapeObject ) )
-           THROW_SALOME_CORBA_EXCEPTION ("bad shape object reference", \
-                                       SALOME::BAD_PARAM );
-
-         TopoDS_Shape locShape  = GeomObjectToShape(aShapeObject);
-         for (TopExp_Explorer exp(locShape,TopAbs_FACE); exp.More(); exp.Next())
-           {
-             const TopoDS_Face& F = TopoDS::Face(exp.Current());
-             setId.insert(myIndexToShape.FindIndex(F));
-             if(MYDEBUG) 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));
-             if(MYDEBUG) 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));
-             if(MYDEBUG) SCRUTE(myIndexToShape.FindIndex(V));
-           }
-       }
+        {
+          GEOM::GEOM_Object_var aShapeObject
+            = GEOM::GEOM_Object::_narrow(theListOfSubShapeObject[i]);
+          if ( CORBA::is_nil( aShapeObject ) )
+            THROW_SALOME_CORBA_EXCEPTION ("bad shape object reference", \
+                                        SALOME::BAD_PARAM );
+
+          TopoDS_Shape locShape  = GeomObjectToShape(aShapeObject);
+          for (TopExp_Explorer exp(locShape,TopAbs_FACE); exp.More(); exp.Next())
+            {
+              const TopoDS_Face& F = TopoDS::Face(exp.Current());
+              setId.insert(myIndexToShape.FindIndex(F));
+              if(MYDEBUG) 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));
+              if(MYDEBUG) 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));
+              if(MYDEBUG) SCRUTE(myIndexToShape.FindIndex(V));
+            }
+        }
       shapesId->length(setId.size());
       set<int>::iterator iind;
       int i=0;
       for (iind = setId.begin(); iind != setId.end(); iind++)
-       {
-         if(MYDEBUG) SCRUTE((*iind));
-         shapesId[i] = (*iind);
-         if(MYDEBUG) SCRUTE(shapesId[i]);
-         i++;
-       }
+        {
+          if(MYDEBUG) SCRUTE((*iind));
+          shapesId[i] = (*iind);
+          if(MYDEBUG) SCRUTE(shapesId[i]);
+          i++;
+        }
     }
   catch (SALOME_Exception& S_ex)
     {
@@ -1363,11 +1601,12 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
                                      GEOM::GEOM_Object_ptr theShapeObject )
      throw ( SALOME::SALOME_Exception )
 {
+  MEMOSTAT;
   Unexpect aCatch(SALOME_SalomeException);
   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Compute" );
 
   if ( CORBA::is_nil( theShapeObject ) && theMesh->HasShapeToMesh())
-    THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", 
+    THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference",
                                   SALOME::BAD_PARAM );
 
   if ( CORBA::is_nil( theMesh ) )
@@ -1381,6 +1620,7 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
   try {
     // get mesh servant
     SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
+    meshServant->Load();
     ASSERT( meshServant );
     if ( meshServant ) {
       // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation"
@@ -1393,7 +1633,13 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
         myLocShape = SMESH_Mesh::PseudoShape();
       // call implementation compute
       ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
-      return myGen.Compute( myLocMesh, myLocShape);
+#ifdef WITH_SMESH_CANCEL_COMPUTE
+      myGen.PrepareCompute( myLocMesh, myLocShape);
+#endif
+      bool ok = myGen.Compute( myLocMesh, myLocShape);
+      meshServant->CreateGroupServants(); // algos can create groups (issue 0020918)
+      myLocMesh.GetMeshDS()->Modified();
+      return ok;
     }
   }
   catch ( std::bad_alloc ) {
@@ -1408,6 +1654,29 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
   return false;
 }
 
+//=============================================================================
+/*!
+ *  SMESH_Gen_i::CancelCompute
+ *
+ *  Cancel Compute mesh on a shape
+ */
+//=============================================================================
+
+void SMESH_Gen_i::CancelCompute( SMESH::SMESH_Mesh_ptr theMesh,
+                                 GEOM::GEOM_Object_ptr theShapeObject )
+{
+#ifdef WITH_SMESH_CANCEL_COMPUTE
+  SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
+  ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
+  TopoDS_Shape myLocShape;
+  if(theMesh->HasShapeToMesh())
+    myLocShape = GeomObjectToShape( theShapeObject );
+  else
+    myLocShape = SMESH_Mesh::PseudoShape();
+  myGen.CancelCompute( myLocMesh, myLocShape);
+#endif
+}
+
 //=============================================================================
 /*!
  *  SMESH_Gen_i::Precompute
@@ -1417,16 +1686,16 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
 //=============================================================================
 
 SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh,
-                                                  GEOM::GEOM_Object_ptr theShapeObject,
-                                                  SMESH::Dimension      theDimension,
-                                                  SMESH::long_array&    theShapesId)
+                                                   GEOM::GEOM_Object_ptr theShapeObject,
+                                                   SMESH::Dimension      theDimension,
+                                                   SMESH::long_array&    theShapesId)
      throw ( SALOME::SALOME_Exception )
 {
   Unexpect aCatch(SALOME_SalomeException);
   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Precompute" );
 
   if ( CORBA::is_nil( theShapeObject ) && theMesh->HasShapeToMesh())
-    THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", 
+    THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference",
                                   SALOME::BAD_PARAM );
 
   if ( CORBA::is_nil( theMesh ) )
@@ -1437,6 +1706,7 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh
   try {
     // get mesh servant
     SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
+    meshServant->Load();
     ASSERT( meshServant );
     if ( meshServant ) {
       // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation"
@@ -1446,7 +1716,7 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh
       if(theMesh->HasShapeToMesh())
         myLocShape = GeomObjectToShape( theShapeObject );
       else
-       return result._retn();;
+        return result._retn();;
 
       // call implementation compute
       ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
@@ -1454,132 +1724,132 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh
       ::MeshDimension aDim = (MeshDimension)theDimension;
       if ( myGen.Compute( myLocMesh, myLocShape, false, aDim, &shapeIds ) )
       {
-       int nbShapeId = shapeIds.size();
-       theShapesId.length( nbShapeId );
-       // iterates on shapes and collect mesh entities into mesh preview
-       TSetOfInt::const_iterator idIt = shapeIds.begin();
-       TSetOfInt::const_iterator idEnd = shapeIds.end();
-       std::map< int, int > mapOfShIdNb;
-       std::set< SMESH_TLink > setOfEdge;
-       std::list< SMDSAbs_ElementType > listOfElemType;
-       typedef map<const SMDS_MeshElement*, int > TNode2LocalIDMap;
-       typedef TNode2LocalIDMap::iterator         TNodeLocalID;
-       TNode2LocalIDMap mapNode2LocalID;
-       list< TNodeLocalID > connectivity;
-       int i, nbConnNodes = 0;
-       std::set< const SMESH_subMesh* > setOfVSubMesh;
-       // iterates on shapes
-       for ( ; idIt != idEnd; idIt++ )
-       {
-         if ( mapOfShIdNb.find( *idIt ) != mapOfShIdNb.end() )
-           continue;
-         SMESH_subMesh* sm = myLocMesh.GetSubMeshContaining(*idIt);
-         if ( !sm || !sm->IsMeshComputed() )
-           continue;
-         
-         const TopoDS_Shape& aSh = sm->GetSubShape();
-         const int shDim = myGen.GetShapeDim( aSh );
-         if ( shDim < 1 || shDim > theDimension )
-           continue;
-
-         mapOfShIdNb[ *idIt ] = 0;
-         theShapesId[ mapOfShIdNb.size() - 1 ] = *idIt;
-
-         SMESHDS_SubMesh* smDS = sm->GetSubMeshDS();
-         if ( !smDS ) continue;
-
-         if ( theDimension == SMESH::DIM_2D )
-         {
-           SMDS_ElemIteratorPtr faceIt = smDS->GetElements();
-           while ( faceIt->more() )
-           {
-             const SMDS_MeshElement* face = faceIt->next();
-             int aNbNode = face->NbNodes();
-             if ( aNbNode > 4 )
-               aNbNode /= 2; // do not take into account additional middle nodes
-
-             SMDS_MeshNode* node1 = (SMDS_MeshNode*)face->GetNode( 1 );
-             for ( int nIndx = 1; nIndx <= aNbNode; nIndx++ )
-             {
-               SMDS_MeshNode* node2 = (SMDS_MeshNode*)face->GetNode( nIndx < aNbNode ? nIndx+1 : 1 );
-               if ( setOfEdge.insert( SMESH_TLink ( node1, node2 ) ).second )
-               {
-                 listOfElemType.push_back( SMDSAbs_Edge );
-                 connectivity.push_back
-                   ( mapNode2LocalID.insert( make_pair( node1, ++nbConnNodes)).first );
-                 connectivity.push_back
-                   ( mapNode2LocalID.insert( make_pair( node2, ++nbConnNodes)).first );
-               }
-               node1 = node2;
-             }
-           }
-         }
-         else if ( theDimension == SMESH::DIM_1D )
-         {
-           SMDS_NodeIteratorPtr nodeIt = smDS->GetNodes();
-           while ( nodeIt->more() )
-           {
-             listOfElemType.push_back( SMDSAbs_Node );
-             connectivity.push_back
-               ( mapNode2LocalID.insert( make_pair( nodeIt->next(), ++nbConnNodes)).first );
-           }
-           // add corner nodes by first vertex from edge
-           SMESH_subMeshIteratorPtr edgeSmIt =
-             sm->getDependsOnIterator(/*includeSelf*/false,
-                                      /*complexShapeFirst*/false);
-           while ( edgeSmIt->more() )
-           {
-             SMESH_subMesh* vertexSM = edgeSmIt->next();
-             // check that vertex is not already treated
-             if ( !setOfVSubMesh.insert( vertexSM ).second )
-               continue;
-             if ( vertexSM->GetSubShape().ShapeType() != TopAbs_VERTEX )
-               continue;
-
-             const SMESHDS_SubMesh* vertexSmDS = vertexSM->GetSubMeshDS();
-             SMDS_NodeIteratorPtr nodeIt = vertexSmDS->GetNodes();
-             while ( nodeIt->more() )
-             {
-               listOfElemType.push_back( SMDSAbs_Node );
-               connectivity.push_back
-                 ( mapNode2LocalID.insert( make_pair( nodeIt->next(), ++nbConnNodes)).first );
-             }
-           }
-         }
-       }
-
-       // fill node coords and assign local ids to the nodes
-       int nbNodes = mapNode2LocalID.size();
-       result->nodesXYZ.length( nbNodes );
-       TNodeLocalID node2ID = mapNode2LocalID.begin();
-       for ( i = 0; i < nbNodes; ++i, ++node2ID ) {
-         node2ID->second = i;
-         const SMDS_MeshNode* node = (const SMDS_MeshNode*) node2ID->first;
-         result->nodesXYZ[i].x = node->X();
-         result->nodesXYZ[i].y = node->Y();
-         result->nodesXYZ[i].z = node->Z();
-       }
-       // fill connectivity
-       result->elementConnectivities.length( nbConnNodes );
-       list< TNodeLocalID >::iterator connIt = connectivity.begin();
-       for ( i = 0; i < nbConnNodes; ++i, ++connIt ) {
-         result->elementConnectivities[i] = (*connIt)->second;
-       }
-
-       // fill element types
-       result->elementTypes.length( listOfElemType.size() );
-       std::list< SMDSAbs_ElementType >::const_iterator typeIt = listOfElemType.begin();
-       std::list< SMDSAbs_ElementType >::const_iterator typeEnd = listOfElemType.end();
-       for ( i = 0; typeIt != typeEnd; ++i, ++typeIt )
+        int nbShapeId = shapeIds.size();
+        theShapesId.length( nbShapeId );
+        // iterates on shapes and collect mesh entities into mesh preview
+        TSetOfInt::const_iterator idIt = shapeIds.begin();
+        TSetOfInt::const_iterator idEnd = shapeIds.end();
+        std::map< int, int > mapOfShIdNb;
+        std::set< SMESH_TLink > setOfEdge;
+        std::list< SMDSAbs_ElementType > listOfElemType;
+        typedef map<const SMDS_MeshElement*, int > TNode2LocalIDMap;
+        typedef TNode2LocalIDMap::iterator         TNodeLocalID;
+        TNode2LocalIDMap mapNode2LocalID;
+        list< TNodeLocalID > connectivity;
+        int i, nbConnNodes = 0;
+        std::set< const SMESH_subMesh* > setOfVSubMesh;
+        // iterates on shapes
+        for ( ; idIt != idEnd; idIt++ )
+        {
+          if ( mapOfShIdNb.find( *idIt ) != mapOfShIdNb.end() )
+            continue;
+          SMESH_subMesh* sm = myLocMesh.GetSubMeshContaining(*idIt);
+          if ( !sm || !sm->IsMeshComputed() )
+            continue;
+
+          const TopoDS_Shape& aSh = sm->GetSubShape();
+          const int shDim = myGen.GetShapeDim( aSh );
+          if ( shDim < 1 || shDim > theDimension )
+            continue;
+
+          mapOfShIdNb[ *idIt ] = 0;
+          theShapesId[ mapOfShIdNb.size() - 1 ] = *idIt;
+
+          SMESHDS_SubMesh* smDS = sm->GetSubMeshDS();
+          if ( !smDS ) continue;
+
+          if ( theDimension == SMESH::DIM_2D )
+          {
+            SMDS_ElemIteratorPtr faceIt = smDS->GetElements();
+            while ( faceIt->more() )
+            {
+              const SMDS_MeshElement* face = faceIt->next();
+              int aNbNode = face->NbNodes();
+              if ( aNbNode > 4 )
+                aNbNode /= 2; // do not take into account additional middle nodes
+
+              SMDS_MeshNode* node1 = (SMDS_MeshNode*)face->GetNode( 0 );
+              for ( int nIndx = 0; nIndx < aNbNode; nIndx++ )
+              {
+                SMDS_MeshNode* node2 = (SMDS_MeshNode*)face->GetNode( nIndx+1 < aNbNode ? nIndx+1 : 0 );
+                if ( setOfEdge.insert( SMESH_TLink ( node1, node2 ) ).second )
+                {
+                  listOfElemType.push_back( SMDSAbs_Edge );
+                  connectivity.push_back
+                    ( mapNode2LocalID.insert( make_pair( node1, ++nbConnNodes)).first );
+                  connectivity.push_back
+                    ( mapNode2LocalID.insert( make_pair( node2, ++nbConnNodes)).first );
+                }
+                node1 = node2;
+              }
+            }
+          }
+          else if ( theDimension == SMESH::DIM_1D )
+          {
+            SMDS_NodeIteratorPtr nodeIt = smDS->GetNodes();
+            while ( nodeIt->more() )
+            {
+              listOfElemType.push_back( SMDSAbs_Node );
+              connectivity.push_back
+                ( mapNode2LocalID.insert( make_pair( nodeIt->next(), ++nbConnNodes)).first );
+            }
+            // add corner nodes by first vertex from edge
+            SMESH_subMeshIteratorPtr edgeSmIt =
+              sm->getDependsOnIterator(/*includeSelf*/false,
+                                       /*complexShapeFirst*/false);
+            while ( edgeSmIt->more() )
+            {
+              SMESH_subMesh* vertexSM = edgeSmIt->next();
+              // check that vertex is not already treated
+              if ( !setOfVSubMesh.insert( vertexSM ).second )
+                continue;
+              if ( vertexSM->GetSubShape().ShapeType() != TopAbs_VERTEX )
+                continue;
+
+              const SMESHDS_SubMesh* vertexSmDS = vertexSM->GetSubMeshDS();
+              SMDS_NodeIteratorPtr nodeIt = vertexSmDS->GetNodes();
+              while ( nodeIt->more() )
+              {
+                listOfElemType.push_back( SMDSAbs_Node );
+                connectivity.push_back
+                  ( mapNode2LocalID.insert( make_pair( nodeIt->next(), ++nbConnNodes)).first );
+              }
+            }
+          }
+        }
+
+        // fill node coords and assign local ids to the nodes
+        int nbNodes = mapNode2LocalID.size();
+        result->nodesXYZ.length( nbNodes );
+        TNodeLocalID node2ID = mapNode2LocalID.begin();
+        for ( i = 0; i < nbNodes; ++i, ++node2ID ) {
+          node2ID->second = i;
+          const SMDS_MeshNode* node = (const SMDS_MeshNode*) node2ID->first;
+          result->nodesXYZ[i].x = node->X();
+          result->nodesXYZ[i].y = node->Y();
+          result->nodesXYZ[i].z = node->Z();
+        }
+        // fill connectivity
+        result->elementConnectivities.length( nbConnNodes );
+        list< TNodeLocalID >::iterator connIt = connectivity.begin();
+        for ( i = 0; i < nbConnNodes; ++i, ++connIt ) {
+          result->elementConnectivities[i] = (*connIt)->second;
+        }
+
+        // fill element types
+        result->elementTypes.length( listOfElemType.size() );
+        std::list< SMDSAbs_ElementType >::const_iterator typeIt = listOfElemType.begin();
+        std::list< SMDSAbs_ElementType >::const_iterator typeEnd = listOfElemType.end();
+        for ( i = 0; typeIt != typeEnd; ++i, ++typeIt )
         {
-         SMDSAbs_ElementType elemType = *typeIt;
-         result->elementTypes[i].SMDS_ElementType = (SMESH::ElementType)elemType;
-         result->elementTypes[i].isPoly           = false;
-         result->elementTypes[i].nbNodesInElement = elemType == SMDSAbs_Edge ? 2 : 1;
-       }
-
-       // correct number of shapes
-       theShapesId.length( mapOfShIdNb.size() );
+          SMDSAbs_ElementType elemType = *typeIt;
+          result->elementTypes[i].SMDS_ElementType = (SMESH::ElementType)elemType;
+          result->elementTypes[i].isPoly           = false;
+          result->elementTypes[i].nbNodesInElement = elemType == SMDSAbs_Edge ? 2 : 1;
+        }
+
+        // correct number of shapes
+        theShapesId.length( mapOfShIdNb.size() );
       }
     }
   }
@@ -1595,38 +1865,125 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh
   return result._retn();
 }
 
-//================================================================================
+
+//=============================================================================
 /*!
- * \brief Return geometrical object the given element is built on
- *  \param theMesh - the mesh the element is in
- *  \param theElementID - the element ID
- *  \param theGeomName - the name of the result geom object if it is not yet published
- *  \retval GEOM::GEOM_Object_ptr - the found or just published geom object
+ *  SMESH_Gen_i::Evaluate
+ *
+ *  Evaluate mesh on a shape
  */
-//================================================================================
+//=============================================================================
 
-GEOM::GEOM_Object_ptr
-SMESH_Gen_i::GetGeometryByMeshElement( SMESH::SMESH_Mesh_ptr  theMesh,
-                                       CORBA::Long            theElementID,
-                                       const char*            theGeomName)
-  throw ( SALOME::SALOME_Exception )
+SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh,
+                                         GEOM::GEOM_Object_ptr theShapeObject)
+//                                     SMESH::long_array& theNbElems)
+     throw ( SALOME::SALOME_Exception )
 {
   Unexpect aCatch(SALOME_SalomeException);
-  GEOM::GEOM_Object_var geom = FindGeometryByMeshElement(theMesh, theElementID);
-  if ( !geom->_is_nil() ) {
-    GEOM::GEOM_Object_var mainShape = theMesh->GetShapeToMesh();
-    GEOM::GEOM_Gen_ptr    geomGen   = GetGeomEngine();
+  if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Evaluate" );
 
-    // try to find the corresponding SObject
-    SALOMEDS::SObject_var SObj = ObjectToSObject( myCurrentStudy, geom.in() );
-    if ( SObj->_is_nil() ) // submesh can be not found even if published
-    {
-      // try to find published submesh
-      GEOM::ListOfLong_var list = geom->GetSubShapeIndices();
-      if ( !geom->IsMainShape() && list->length() == 1 ) {
-        SALOMEDS::SObject_var mainSO = ObjectToSObject( myCurrentStudy, mainShape );
-        SALOMEDS::ChildIterator_var it;
+  if ( CORBA::is_nil( theShapeObject ) && theMesh->HasShapeToMesh())
+    THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference",
+                                  SALOME::BAD_PARAM );
+
+  if ( CORBA::is_nil( theMesh ) )
+    THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",
+                                  SALOME::BAD_PARAM );
+
+  SMESH::long_array_var nbels = new SMESH::long_array;
+  nbels->length(SMESH::Entity_Last);
+  int i = SMESH::Entity_Node;
+  for (; i < SMESH::Entity_Last; i++)
+    nbels[i] = 0;
+
+  // Update Python script
+  TPythonDump() << "theNbElems = " << this << ".Evaluate( "
+                << theMesh << ", " << theShapeObject << ")";
+
+  try {
+    // get mesh servant
+    SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
+    ASSERT( meshServant );
+    if ( meshServant ) {
+      // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation"
+      meshServant->CheckGeomGroupModif();
+      // get local TopoDS_Shape
+      TopoDS_Shape myLocShape;
+      if(theMesh->HasShapeToMesh())
+        myLocShape = GeomObjectToShape( theShapeObject );
+      else
+        myLocShape = SMESH_Mesh::PseudoShape();
+      // call implementation compute
+      ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
+      MapShapeNbElems aResMap;
+      /*CORBA::Boolean ret =*/ myGen.Evaluate( myLocMesh, myLocShape, aResMap);
+      MapShapeNbElemsItr anIt = aResMap.begin();
+      for(; anIt!=aResMap.end(); anIt++) {
+        const vector<int>& aVec = (*anIt).second;
+        for(i = SMESH::Entity_Node; i < aVec.size(); i++) {
+          int nbElem = aVec[i];
+          if ( nbElem < 0 ) // algo failed, check that it has reported a message
+          {
+            SMESH_subMesh* sm = anIt->first;
+            SMESH_ComputeErrorPtr& error = sm->GetComputeError();
+            const SMESH_Algo* algo = myGen.GetAlgo( myLocMesh, sm->GetSubShape());
+            if ( (algo && !error.get()) || error->IsOK() )
+              error.reset( new SMESH_ComputeError( COMPERR_ALGO_FAILED,"Failed to evaluate",algo));
+          }
+          else
+          {
+            nbels[i] += aVec[i];
+          }
+        }
+      }
+      return nbels._retn();
+    }
+  }
+  catch ( std::bad_alloc ) {
+    INFOS( "Evaluate(): lack of memory" );
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    INFOS( "Evaluate(): catch exception "<< S_ex.what() );
+  }
+  catch ( ... ) {
+    INFOS( "Evaluate(): unknown exception " );
+  }
+
+  return nbels._retn();
+}
+
+//================================================================================
+/*!
+ * \brief Return geometrical object the given element is built on
+ *  \param theMesh - the mesh the element is in
+ *  \param theElementID - the element ID
+ *  \param theGeomName - the name of the result geom object if it is not yet published
+ *  \retval GEOM::GEOM_Object_ptr - the found or just published geom object
+ */
+//================================================================================
+
+GEOM::GEOM_Object_ptr
+SMESH_Gen_i::GetGeometryByMeshElement( SMESH::SMESH_Mesh_ptr  theMesh,
+                                       CORBA::Long            theElementID,
+                                       const char*            theGeomName)
+  throw ( SALOME::SALOME_Exception )
+{
+  Unexpect aCatch(SALOME_SalomeException);
+
+  GEOM::GEOM_Object_var geom = FindGeometryByMeshElement(theMesh, theElementID);
+  if ( !geom->_is_nil() ) {
+    GEOM::GEOM_Object_var mainShape = theMesh->GetShapeToMesh();
+    GEOM::GEOM_Gen_ptr    geomGen   = GetGeomEngine();
+
+    // try to find the corresponding SObject
+    SALOMEDS::SObject_var SObj = ObjectToSObject( myCurrentStudy, geom.in() );
+    if ( SObj->_is_nil() ) // submesh can be not found even if published
+    {
+      // try to find published submesh
+      GEOM::ListOfLong_var list = geom->GetSubShapeIndices();
+      if ( !geom->IsMainShape() && list->length() == 1 ) {
+        SALOMEDS::SObject_var mainSO = ObjectToSObject( myCurrentStudy, mainShape );
+        SALOMEDS::ChildIterator_var it;
         if ( !mainSO->_is_nil() )
           it = myCurrentStudy->NewChildIterator( mainSO );
         if ( !it->_is_nil() ) {
@@ -1716,7 +2073,7 @@ SMESH_Gen_i::FindGeometryByMeshElement( SMESH::SMESH_Mesh_ptr  theMesh,
         }
         if ( !geom->_is_nil() ) {
           GeomObjectToShape( geom ); // let geom client remember the found shape
-         return geom._retn();
+          return geom._retn();
         }
       }
     }
@@ -1733,16 +2090,16 @@ SMESH_Gen_i::FindGeometryByMeshElement( SMESH::SMESH_Mesh_ptr  theMesh,
 //================================================================================
 
 SMESH::SMESH_Mesh_ptr SMESH_Gen_i::Concatenate(const SMESH::mesh_array& theMeshesArray,
-                                              CORBA::Boolean           theUniteIdenticalGroups, 
-                                              CORBA::Boolean           theMergeNodesAndElements, 
-                                              CORBA::Double            theMergeTolerance)
+                                               CORBA::Boolean           theUniteIdenticalGroups,
+                                               CORBA::Boolean           theMergeNodesAndElements,
+                                               CORBA::Double            theMergeTolerance)
   throw ( SALOME::SALOME_Exception )
 {
   return ConcatenateCommon(theMeshesArray,
-                          theUniteIdenticalGroups,
-                          theMergeNodesAndElements,
-                          theMergeTolerance,
-                          false);
+                           theUniteIdenticalGroups,
+                           theMergeNodesAndElements,
+                           theMergeTolerance,
+                           false);
 }
 
 //================================================================================
@@ -1756,8 +2113,8 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::Concatenate(const SMESH::mesh_array& theMeshe
 
 SMESH::SMESH_Mesh_ptr
 SMESH_Gen_i::ConcatenateWithGroups(const SMESH::mesh_array& theMeshesArray,
-                                  CORBA::Boolean           theUniteIdenticalGroups, 
-                                   CORBA::Boolean           theMergeNodesAndElements, 
+                                   CORBA::Boolean           theUniteIdenticalGroups,
+                                   CORBA::Boolean           theMergeNodesAndElements,
                                    CORBA::Double            theMergeTolerance)
   throw ( SALOME::SALOME_Exception )
 {
@@ -1765,7 +2122,7 @@ SMESH_Gen_i::ConcatenateWithGroups(const SMESH::mesh_array& theMeshesArray,
                            theUniteIdenticalGroups,
                            theMergeNodesAndElements,
                            theMergeTolerance,
-                          true);
+                           true);
 }
 
 //================================================================================
@@ -1778,10 +2135,10 @@ SMESH_Gen_i::ConcatenateWithGroups(const SMESH::mesh_array& theMeshesArray,
 
 SMESH::SMESH_Mesh_ptr
 SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
-                              CORBA::Boolean           theUniteIdenticalGroups, 
-                               CORBA::Boolean           theMergeNodesAndElements, 
+                               CORBA::Boolean           theUniteIdenticalGroups,
+                               CORBA::Boolean           theMergeNodesAndElements,
                                CORBA::Double            theMergeTolerance,
-                              CORBA::Boolean           theCommonGroups)
+                               CORBA::Boolean           theCommonGroups)
   throw ( SALOME::SALOME_Exception )
 {
   typedef map<int, int> TIDsMap;
@@ -1789,16 +2146,18 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
   typedef map< pair<string, SMESH::ElementType>, TListOfNewGroups > TGroupsMap;
   typedef std::set<SMESHDS_GroupBase*> TGroups;
 
-  TPythonDump aPythonDump; // prevent dump of called methods
+  TPythonDump* pPythonDump = new TPythonDump;
+  TPythonDump& aPythonDump = *pPythonDump; // prevent dump of called methods
 
   // create mesh
   SMESH::SMESH_Mesh_var aNewMesh = CreateEmptyMesh();
-  
+
+  SMESHDS_Mesh* aNewMeshDS = 0;
   if ( !aNewMesh->_is_nil() ) {
     SMESH_Mesh_i* aNewImpl = dynamic_cast<SMESH_Mesh_i*>( GetServant( aNewMesh ).in() );
     if ( aNewImpl ) {
       ::SMESH_Mesh& aLocMesh = aNewImpl->GetImpl();
-      SMESHDS_Mesh* aNewMeshDS = aLocMesh.GetMeshDS();
+      aNewMeshDS = aLocMesh.GetMeshDS();
 
       TGroupsMap aGroupsMap;
       TListOfNewGroups aListOfNewGroups;
@@ -1807,240 +2166,280 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
 
       // loop on meshes
       for ( int i = 0; i < theMeshesArray.length(); i++) {
-       SMESH::SMESH_Mesh_var anInitMesh = theMeshesArray[i];
-       if ( !anInitMesh->_is_nil() ) {
-         SMESH_Mesh_i* anInitImpl = dynamic_cast<SMESH_Mesh_i*>( GetServant( anInitMesh ).in() );
-         if ( anInitImpl ) {
-           ::SMESH_Mesh& aInitLocMesh = anInitImpl->GetImpl();
-           SMESHDS_Mesh* anInitMeshDS = aInitLocMesh.GetMeshDS();
-
-           TIDsMap nodesMap;
-           TIDsMap elemsMap;
-
-           // loop on elements of mesh
-           SMDS_ElemIteratorPtr itElems = anInitMeshDS->elementsIterator();
-           const SMDS_MeshElement* anElem = 0;
-           const SMDS_MeshElement* aNewElem = 0;
-           int anElemNbNodes = 0;
-
-           int anNbNodes   = 0;
-           int anNbEdges   = 0;
-           int anNbFaces   = 0;
-           int anNbVolumes = 0;
-
-           SMESH::long_array_var anIDsNodes   = new SMESH::long_array();
-           SMESH::long_array_var anIDsEdges   = new SMESH::long_array();
-           SMESH::long_array_var anIDsFaces   = new SMESH::long_array();
-           SMESH::long_array_var anIDsVolumes = new SMESH::long_array();
-
-           if( theCommonGroups ) {
-             anIDsNodes->length(   anInitMeshDS->NbNodes()   );
-             anIDsEdges->length(   anInitMeshDS->NbEdges()   );
-             anIDsFaces->length(   anInitMeshDS->NbFaces()   );
-             anIDsVolumes->length( anInitMeshDS->NbVolumes() );
-           }
-
-           for ( int j = 0; itElems->more(); j++) {
-             anElem = itElems->next();
-             SMDSAbs_ElementType anElemType = anElem->GetType();
-             anElemNbNodes = anElem->NbNodes();
-             std::vector<const SMDS_MeshNode*> aNodesArray (anElemNbNodes);
-
-             // loop on nodes of element
-             const SMDS_MeshNode* aNode = 0;
-             const SMDS_MeshNode* aNewNode = 0;
-             SMDS_ElemIteratorPtr itNodes = anElem->nodesIterator();
-
-             for ( int k = 0; itNodes->more(); k++) {
-               aNode = static_cast<const SMDS_MeshNode*>(itNodes->next());
-               if ( nodesMap.find(aNode->GetID()) == nodesMap.end() ) {
-                 aNewNode = aNewMeshDS->AddNode(aNode->X(), aNode->Y(), aNode->Z());
-                 nodesMap.insert( make_pair(aNode->GetID(), aNewNode->GetID()) );
-                 if( theCommonGroups )
-                   anIDsNodes[anNbNodes++] = aNewNode->GetID();
-               }
-               else
-                 aNewNode = aNewMeshDS->FindNode( nodesMap.find(aNode->GetID())->second );
-               aNodesArray[k] = aNewNode;
-             }//nodes loop
-
-             // creates a corresponding element on existent nodes in new mesh
-             if ( anElem->IsPoly() && anElemType == SMDSAbs_Volume )
-               {
-                 const SMDS_PolyhedralVolumeOfNodes* aVolume =
-                   dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem);
-                 if ( aVolume ) {
-                   aNewElem = aNewMeshDS->AddPolyhedralVolume(aNodesArray, 
-                                                              aVolume->GetQuanities());
-                   elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID()));
-                   if( theCommonGroups )
-                     anIDsVolumes[anNbVolumes++] = aNewElem->GetID();
-                 }
-               }
-             else {
-               
-               aNewElem = aNewEditor.AddElement(aNodesArray,
-                                                anElemType,
-                                                anElem->IsPoly());
-               elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID()));
-               if( theCommonGroups ) {
-                 if( anElemType == SMDSAbs_Edge )
-                   anIDsEdges[anNbEdges++] = aNewElem->GetID();
-                 else if( anElemType == SMDSAbs_Face )
-                   anIDsFaces[anNbFaces++] = aNewElem->GetID();
-                 else if( anElemType == SMDSAbs_Volume )
-                   anIDsVolumes[anNbVolumes++] = aNewElem->GetID();
-               }
-             } 
-           }//elems loop
-           
-           aListOfGroups = anInitImpl->GetGroups();
-           SMESH::SMESH_GroupBase_ptr aGroup;
-
-           // loop on groups of mesh
-           SMESH::long_array_var anInitIDs = new SMESH::long_array();
-           SMESH::long_array_var anNewIDs = new SMESH::long_array();
-           SMESH::SMESH_Group_var aNewGroup;
-
-           SMESH::ElementType aGroupType;
-           CORBA::String_var aGroupName;
-           if ( theCommonGroups ) {
-             for(aGroupType=SMESH::NODE;aGroupType<=SMESH::VOLUME;aGroupType=(SMESH::ElementType)(aGroupType+1)) {
-               string str = "Gr";
-               SALOMEDS::SObject_var aMeshSObj = ObjectToSObject( myCurrentStudy, anInitMesh );
-               if(aMeshSObj)
-                 str += aMeshSObj->GetName();
-               str += "_";
-
-               int anLen = 0;
-
-               switch(aGroupType) {
-               case SMESH::NODE:
-                 str += "Nodes";
-                 anIDsNodes->length(anNbNodes);
-                 anLen = anNbNodes;
-                 break;
-               case SMESH::EDGE:
-                 str += "Edges";
-                 anIDsEdges->length(anNbEdges);
-                 anLen = anNbEdges;
-                 break;
-               case SMESH::FACE:
-                 str += "Faces";
-                 anIDsFaces->length(anNbFaces);
-                 anLen = anNbFaces;
-                 break;
-               case SMESH::VOLUME:
-                 str += "Volumes";
-                 anIDsVolumes->length(anNbVolumes);
-                 anLen = anNbVolumes;
-                 break;
-               default:
-                 break;
-               }
-
-               if(anLen) {
-                 aGroupName = str.c_str();
-
-                 // add a new group in the mesh
-                 aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName);
-
-                 switch(aGroupType) {
-                 case SMESH::NODE:
-                   aNewGroup->Add( anIDsNodes );
-                   break;
-                 case SMESH::EDGE:
-                   aNewGroup->Add( anIDsEdges );
-                   break;
-                 case SMESH::FACE:
-                   aNewGroup->Add( anIDsFaces );
-                   break;
-                 case SMESH::VOLUME:
-                   aNewGroup->Add( anIDsVolumes );
-                   break;
-                 default:
-                   break;
-                 }
-               
-                 aListOfNewGroups.clear();
-                 aListOfNewGroups.push_back(aNewGroup);
-                 aGroupsMap.insert(make_pair( make_pair(aGroupName, aGroupType), aListOfNewGroups ));
-               }
-             }
-           }
-
-           // check that current group name and type don't have identical ones in union mesh
-           for (int i = 0; i < aListOfGroups->length(); i++) {
-             aGroup = aListOfGroups[i];
-             aListOfNewGroups.clear();
-             aGroupType = aGroup->GetType();
-             aGroupName = aGroup->GetName();
-
-             TGroupsMap::iterator anIter = aGroupsMap.find(make_pair(aGroupName, aGroupType));
-
-             // convert a list of IDs
-             anInitIDs = aGroup->GetListOfID();
-             anNewIDs->length(anInitIDs->length());
-             if ( aGroupType == SMESH::NODE )
-               for (int j = 0; j < anInitIDs->length(); j++) {
-                 anNewIDs[j] = nodesMap.find(anInitIDs[j])->second;
-               }
-             else
-               for (int j = 0; j < anInitIDs->length(); j++) {
-                 anNewIDs[j] = elemsMap.find(anInitIDs[j])->second;
-               }
-             
-             // check that current group name and type don't have identical ones in union mesh
-             if ( anIter == aGroupsMap.end() ) {
-               // add a new group in the mesh
-               aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName);
-               // add elements into new group
-               aNewGroup->Add( anNewIDs );
-               
-               aListOfNewGroups.push_back(aNewGroup);
-               aGroupsMap.insert(make_pair( make_pair(aGroupName, aGroupType), aListOfNewGroups ));
-             }
-
-             else if ( theUniteIdenticalGroups ) {
-               // unite identical groups
-               TListOfNewGroups& aNewGroups = anIter->second;
-               aNewGroups.front()->Add( anNewIDs );
-             }
-
-             else {
-               // rename identical groups
-               aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName);
-               aNewGroup->Add( anNewIDs );
-               
-               TListOfNewGroups& aNewGroups = anIter->second;
-               string aNewGroupName;
-               if (aNewGroups.size() == 1) {
-                 aNewGroupName = string(aGroupName) + "_1";
-                 aNewGroups.front()->SetName(aNewGroupName.c_str());
-               }
-               char aGroupNum[128];
-               sprintf(aGroupNum, "%u", aNewGroups.size()+1);
-               aNewGroupName = string(aGroupName) + "_" + string(aGroupNum);
-               aNewGroup->SetName(aNewGroupName.c_str());
-               aNewGroups.push_back(aNewGroup);
-             }
-           }//groups loop
-         }
-       }
+        SMESH::SMESH_Mesh_var anInitMesh = theMeshesArray[i];
+        if ( !anInitMesh->_is_nil() ) {
+          SMESH_Mesh_i* anInitImpl = dynamic_cast<SMESH_Mesh_i*>( GetServant( anInitMesh ).in() );
+          if ( anInitImpl ) {
+            ::SMESH_Mesh& aInitLocMesh = anInitImpl->GetImpl();
+            SMESHDS_Mesh* anInitMeshDS = aInitLocMesh.GetMeshDS();
+
+            TIDsMap nodesMap;
+            TIDsMap elemsMap;
+
+            // loop on elements of mesh
+            SMDS_ElemIteratorPtr itElems = anInitMeshDS->elementsIterator();
+            const SMDS_MeshElement* anElem = 0;
+            const SMDS_MeshElement* aNewElem = 0;
+            int anElemNbNodes = 0;
+
+            int anNbNodes   = 0;
+            int anNbEdges   = 0;
+            int anNbFaces   = 0;
+            int anNbVolumes = 0;
+            int aNbBalls    = 0;
+
+            SMESH::long_array_var anIDsNodes   = new SMESH::long_array();
+            SMESH::long_array_var anIDsEdges   = new SMESH::long_array();
+            SMESH::long_array_var anIDsFaces   = new SMESH::long_array();
+            SMESH::long_array_var anIDsVolumes = new SMESH::long_array();
+            SMESH::long_array_var anIDsBalls   = new SMESH::long_array();
+
+            if( theCommonGroups ) {
+              anIDsNodes->length(   anInitMeshDS->NbNodes()   );
+              anIDsEdges->length(   anInitMeshDS->NbEdges()   );
+              anIDsFaces->length(   anInitMeshDS->NbFaces()   );
+              anIDsVolumes->length( anInitMeshDS->NbVolumes() );
+              anIDsBalls->length(   anInitMeshDS->NbBalls() );
+            }
+
+            for ( int j = 0; itElems->more(); j++) {
+              anElem = itElems->next();
+              SMDSAbs_ElementType anElemType = anElem->GetType();
+              anElemNbNodes = anElem->NbNodes();
+              std::vector<const SMDS_MeshNode*> aNodesArray (anElemNbNodes);
+
+              // loop on nodes of element
+              const SMDS_MeshNode* aNode = 0;
+              const SMDS_MeshNode* aNewNode = 0;
+              SMDS_ElemIteratorPtr itNodes = anElem->nodesIterator();
+
+              for ( int k = 0; itNodes->more(); k++) {
+                aNode = static_cast<const SMDS_MeshNode*>(itNodes->next());
+                if ( nodesMap.find(aNode->GetID()) == nodesMap.end() ) {
+                  aNewNode = aNewMeshDS->AddNode(aNode->X(), aNode->Y(), aNode->Z());
+                  nodesMap.insert( make_pair(aNode->GetID(), aNewNode->GetID()) );
+                  if( theCommonGroups )
+                    anIDsNodes[anNbNodes++] = aNewNode->GetID();
+                }
+                else
+                  aNewNode = aNewMeshDS->FindNode( nodesMap.find(aNode->GetID())->second );
+                aNodesArray[k] = aNewNode;
+              }//nodes loop
+
+              // creates a corresponding element on existent nodes in new mesh
+              switch ( anElem->GetEntityType() ) {
+              case SMDSEntity_Polyhedra:
+                if ( const SMDS_VtkVolume* aVolume =
+                     dynamic_cast<const SMDS_VtkVolume*> (anElem))
+                {
+                  aNewElem = aNewMeshDS->AddPolyhedralVolume(aNodesArray,
+                                                             aVolume->GetQuantities());
+                  elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID()));
+                  if( theCommonGroups )
+                    anIDsVolumes[anNbVolumes++] = aNewElem->GetID();
+                }
+                break;
+              case SMDSEntity_Ball:
+                if ( const SMDS_BallElement* aBall =
+                     dynamic_cast<const SMDS_BallElement*> (anElem))
+                {
+                  aNewElem = aNewEditor.AddElement(aNodesArray, SMDSAbs_Ball,
+                                                   /*isPoly=*/false, /*id=*/0,
+                                                   aBall->GetDiameter() );
+                  elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID()));
+                  if( theCommonGroups )
+                    anIDsBalls[aNbBalls++] = aNewElem->GetID();
+                }
+                break;
+              default:
+                {
+                  aNewElem = aNewEditor.AddElement(aNodesArray,
+                                                   anElemType,
+                                                   anElem->IsPoly());
+                  elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID()));
+                  if( theCommonGroups ) {
+                    if( anElemType == SMDSAbs_Edge )
+                      anIDsEdges[anNbEdges++] = aNewElem->GetID();
+                    else if( anElemType == SMDSAbs_Face )
+                      anIDsFaces[anNbFaces++] = aNewElem->GetID();
+                    else if( anElemType == SMDSAbs_Volume )
+                      anIDsVolumes[anNbVolumes++] = aNewElem->GetID();
+                  }
+                }
+              }
+            }//elems loop
+
+            // copy orphan nodes
+            SMDS_NodeIteratorPtr  itNodes = anInitMeshDS->nodesIterator();
+            while ( itNodes->more() )
+            {
+              const SMDS_MeshNode* aNode = itNodes->next();
+              if ( aNode->NbInverseElements() == 0 )
+              {
+                const SMDS_MeshNode* aNewNode =
+                  aNewMeshDS->AddNode(aNode->X(), aNode->Y(), aNode->Z());
+                nodesMap.insert( make_pair(aNode->GetID(), aNewNode->GetID()) );
+                if( theCommonGroups )
+                  anIDsNodes[anNbNodes++] = aNewNode->GetID();
+              }
+            }
+
+
+            aListOfGroups = anInitImpl->GetGroups();
+            SMESH::SMESH_GroupBase_ptr aGroup;
+
+            // loop on groups of mesh
+            SMESH::long_array_var anInitIDs = new SMESH::long_array();
+            SMESH::long_array_var anNewIDs = new SMESH::long_array();
+            SMESH::SMESH_Group_var aNewGroup;
+
+            SMESH::ElementType aGroupType;
+            CORBA::String_var aGroupName;
+            if ( theCommonGroups ) {
+              for(aGroupType=SMESH::NODE;aGroupType<=SMESH::BALL;aGroupType=(SMESH::ElementType)(aGroupType+1)) {
+                string str = "Gr";
+                SALOMEDS::SObject_var aMeshSObj = ObjectToSObject( myCurrentStudy, anInitMesh );
+                if(aMeshSObj)
+                  str += aMeshSObj->GetName();
+                str += "_";
+
+                int anLen = 0;
+
+                switch(aGroupType) {
+                case SMESH::NODE:
+                  str += "Nodes";
+                  anIDsNodes->length(anNbNodes);
+                  anLen = anNbNodes;
+                  break;
+                case SMESH::EDGE:
+                  str += "Edges";
+                  anIDsEdges->length(anNbEdges);
+                  anLen = anNbEdges;
+                  break;
+                case SMESH::FACE:
+                  str += "Faces";
+                  anIDsFaces->length(anNbFaces);
+                  anLen = anNbFaces;
+                  break;
+                case SMESH::VOLUME:
+                  str += "Volumes";
+                  anIDsVolumes->length(anNbVolumes);
+                  anLen = anNbVolumes;
+                  break;
+                case SMESH::BALL:
+                  str += "Balls";
+                  anIDsBalls->length(aNbBalls);
+                  anLen = aNbBalls;
+                  break;
+                default:
+                  break;
+                }
+
+                if(anLen) {
+                  aGroupName = str.c_str();
+
+                  // add a new group in the mesh
+                  aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName);
+
+                  switch(aGroupType) {
+                  case SMESH::NODE:
+                    aNewGroup->Add( anIDsNodes );
+                    break;
+                  case SMESH::EDGE:
+                    aNewGroup->Add( anIDsEdges );
+                    break;
+                  case SMESH::FACE:
+                    aNewGroup->Add( anIDsFaces );
+                    break;
+                  case SMESH::VOLUME:
+                    aNewGroup->Add( anIDsVolumes );
+                    break;
+                  case SMESH::BALL:
+                    aNewGroup->Add( anIDsBalls );
+                    break;
+                  default:
+                    break;
+                  }
+
+                  aListOfNewGroups.clear();
+                  aListOfNewGroups.push_back(aNewGroup);
+                  aGroupsMap.insert(make_pair( make_pair(aGroupName, aGroupType), aListOfNewGroups ));
+                }
+              }
+            }
+
+            // check that current group name and type don't have identical ones in union mesh
+            for (int i = 0; i < aListOfGroups->length(); i++) {
+              aGroup = aListOfGroups[i];
+              aListOfNewGroups.clear();
+              aGroupType = aGroup->GetType();
+              aGroupName = aGroup->GetName();
+
+              TGroupsMap::iterator anIter = aGroupsMap.find(make_pair(aGroupName, aGroupType));
+
+              // convert a list of IDs
+              anInitIDs = aGroup->GetListOfID();
+              anNewIDs->length(anInitIDs->length());
+              if ( aGroupType == SMESH::NODE )
+                for (int j = 0; j < anInitIDs->length(); j++) {
+                  anNewIDs[j] = nodesMap.find(anInitIDs[j])->second;
+                }
+              else
+                for (int j = 0; j < anInitIDs->length(); j++) {
+                  anNewIDs[j] = elemsMap.find(anInitIDs[j])->second;
+                }
+
+              // check that current group name and type don't have identical ones in union mesh
+              if ( anIter == aGroupsMap.end() ) {
+                // add a new group in the mesh
+                aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName);
+                // add elements into new group
+                aNewGroup->Add( anNewIDs );
+
+                aListOfNewGroups.push_back(aNewGroup);
+                aGroupsMap.insert(make_pair( make_pair(aGroupName, aGroupType), aListOfNewGroups ));
+              }
+
+              else if ( theUniteIdenticalGroups ) {
+                // unite identical groups
+                TListOfNewGroups& aNewGroups = anIter->second;
+                aNewGroups.front()->Add( anNewIDs );
+              }
+
+              else {
+                // rename identical groups
+                aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName);
+                aNewGroup->Add( anNewIDs );
+
+                TListOfNewGroups& aNewGroups = anIter->second;
+                string aNewGroupName;
+                if (aNewGroups.size() == 1) {
+                  aNewGroupName = string(aGroupName) + "_1";
+                  aNewGroups.front()->SetName(aNewGroupName.c_str());
+                }
+                char aGroupNum[128];
+                sprintf(aGroupNum, "%u", aNewGroups.size()+1);
+                aNewGroupName = string(aGroupName) + "_" + string(aGroupNum);
+                aNewGroup->SetName(aNewGroupName.c_str());
+                aNewGroups.push_back(aNewGroup);
+              }
+            }//groups loop
+          }
+        }
       }//meshes loop
 
       if (theMergeNodesAndElements) {
-       // merge nodes
-       set<const SMDS_MeshNode*> aMeshNodes; // no input nodes
-       SMESH_MeshEditor::TListOfListOfNodes aGroupsOfNodes;
-       aNewEditor.FindCoincidentNodes( aMeshNodes, theMergeTolerance, aGroupsOfNodes );
-       aNewEditor.MergeNodes( aGroupsOfNodes );
-       // merge elements
-       aNewEditor.MergeEqualElements();
+        // merge nodes
+        TIDSortedNodeSet aMeshNodes; // no input nodes
+        SMESH_MeshEditor::TListOfListOfNodes aGroupsOfNodes;
+        aNewEditor.FindCoincidentNodes( aMeshNodes, theMergeTolerance, aGroupsOfNodes );
+        aNewEditor.MergeNodes( aGroupsOfNodes );
+        // merge elements
+        aNewEditor.MergeEqualElements();
       }
     }
   }
-  
+
   // Update Python script
   aPythonDump << aNewMesh << " = " << this;
   if( !theCommonGroups )
@@ -2054,12 +2453,309 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
   }
   aPythonDump << "], ";
   aPythonDump << theUniteIdenticalGroups << ", "
-             << theMergeNodesAndElements << ", "
-              << theMergeTolerance << ")";
+              << theMergeNodesAndElements << ", "
+              << TVar( theMergeTolerance ) << ")";
+
+  delete pPythonDump; // enable python dump from GetGroups()
+
+  // 0020577: EDF 1164 SMESH: Bad dump of concatenate with create common groups
+  if ( !aNewMesh->_is_nil() )
+  {
+    SMESH::ListOfGroups_var groups = aNewMesh->GetGroups();
+  }
 
+  // IPAL21468 Change icon of compound because it need not be computed.
+  SALOMEDS::SObject_var aMeshSObj = ObjectToSObject( myCurrentStudy, aNewMesh );
+  SetPixMap( aMeshSObj, "ICON_SMESH_TREE_MESH" );
+
+  if (aNewMeshDS)
+    aNewMeshDS->Modified();
   return aNewMesh._retn();
 }
 
+//================================================================================
+/*!
+ * \brief Create a mesh by copying a part of another mesh
+ *  \param meshPart - a part of mesh to copy
+ *  \param toCopyGroups - to create in the new mesh groups
+ *                        the copied elements belongs to
+ *  \param toKeepIDs - to preserve IDs of the copied elements or not
+ *  \retval SMESH::SMESH_Mesh_ptr - the new mesh
+ */
+//================================================================================
+
+SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart,
+                                            const char*               meshName,
+                                            CORBA::Boolean            toCopyGroups,
+                                            CORBA::Boolean            toKeepIDs)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+
+  TPythonDump* pyDump = new TPythonDump; // prevent dump from CreateMesh()
+
+  // 1. Get source mesh
+
+  if ( CORBA::is_nil( meshPart ))
+    THROW_SALOME_CORBA_EXCEPTION( "bad IDSource", SALOME::BAD_PARAM );
+
+  SMESH::SMESH_Mesh_var srcMesh = meshPart->GetMesh();
+  SMESH_Mesh_i*       srcMesh_i = SMESH::DownCast<SMESH_Mesh_i*>( srcMesh );
+  if ( !srcMesh_i )
+    THROW_SALOME_CORBA_EXCEPTION( "bad mesh of IDSource", SALOME::BAD_PARAM );
+
+  SMESHDS_Mesh* srcMeshDS = srcMesh_i->GetImpl().GetMeshDS();
+
+  // 2. Make a new mesh
+
+  SMESH::SMESH_Mesh_var newMesh = CreateMesh(GEOM::GEOM_Object::_nil());
+  SMESH_Mesh_i*       newMesh_i = SMESH::DownCast<SMESH_Mesh_i*>( newMesh );
+  if ( !newMesh_i )
+    THROW_SALOME_CORBA_EXCEPTION( "can't create a mesh", SALOME::INTERNAL_ERROR );
+  SALOMEDS::SObject_var meshSO = ObjectToSObject(myCurrentStudy, newMesh );
+  if ( !meshSO->_is_nil() )
+  {
+    SetName( meshSO, meshName, "Mesh" );
+    SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
+  }
+  SMESHDS_Mesh* newMeshDS = newMesh_i->GetImpl().GetMeshDS();
+  ::SMESH_MeshEditor editor( &newMesh_i->GetImpl() );
+
+  // 3. Get elements to copy
+
+  SMDS_ElemIteratorPtr srcElemIt; SMDS_NodeIteratorPtr srcNodeIt;
+  TIDSortedElemSet srcElems;
+  SMESH::array_of_ElementType_var srcElemTypes = meshPart->GetTypes();
+  if ( SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
+  {
+    srcElemIt = srcMeshDS->elementsIterator();
+    srcNodeIt = srcMeshDS->nodesIterator();
+  }
+  else
+  {
+    SMESH::long_array_var ids = meshPart->GetIDs();
+    if ( srcElemTypes->length() == 1 && srcElemTypes[0] == SMESH::NODE ) // group of nodes
+    {
+      for (int i=0; i < ids->length(); i++)
+        if ( const SMDS_MeshElement * elem = srcMeshDS->FindNode( ids[i] ))
+          srcElems.insert( elem );
+    }
+    else
+    {
+      for (int i=0; i < ids->length(); i++)
+        if ( const SMDS_MeshElement * elem = srcMeshDS->FindElement( ids[i] ))
+          srcElems.insert( elem );
+    }
+    if ( srcElems.empty() )
+      return newMesh._retn();
+
+    typedef SMDS_SetIterator< SMDS_pElement, TIDSortedElemSet::const_iterator > ElIter;
+    srcElemIt = SMDS_ElemIteratorPtr( new ElIter( srcElems.begin(), srcElems.end() ));
+  }
+
+  // 4. Copy elements
+
+  typedef map<SMDS_pElement, SMDS_pElement, TIDCompare> TE2EMap;
+  TE2EMap e2eMapByType[ SMDSAbs_NbElementTypes ];
+  TE2EMap& n2nMap = e2eMapByType[ SMDSAbs_Node ];
+  int iN;
+  const SMDS_MeshNode *nSrc, *nTgt;
+  vector< const SMDS_MeshNode* > nodes;
+  while ( srcElemIt->more() )
+  {
+    const SMDS_MeshElement * elem = srcElemIt->next();
+    // find / add nodes
+    nodes.resize( elem->NbNodes());
+    SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
+    if ( toKeepIDs ) {
+      for ( iN = 0; nIt->more(); ++iN )
+      {
+        nSrc = static_cast<const SMDS_MeshNode*>( nIt->next() );
+        nTgt = newMeshDS->FindNode( nSrc->GetID());
+        if ( !nTgt )
+          nTgt = newMeshDS->AddNodeWithID( nSrc->X(), nSrc->Y(), nSrc->Z(), nSrc->GetID());
+        nodes[ iN ] = nTgt;
+      }
+    }
+    else {
+      for ( iN = 0; nIt->more(); ++iN )
+      {
+        nSrc = static_cast<const SMDS_MeshNode*>( nIt->next() );
+        TE2EMap::iterator n2n = n2nMap.insert( make_pair( nSrc, SMDS_pNode(0) )).first;
+        if ( !n2n->second )
+          n2n->second = newMeshDS->AddNode( nSrc->X(), nSrc->Y(), nSrc->Z() );
+        nodes[ iN ] = (const SMDS_MeshNode*) n2n->second;
+      }
+    }
+    // add elements
+    if ( elem->GetType() != SMDSAbs_Node )
+    {
+      int ID = toKeepIDs ? elem->GetID() : 0;
+      const SMDS_MeshElement * newElem;
+      switch ( elem->GetEntityType() ) {
+      case SMDSEntity_Polyhedra:
+        newElem = editor.GetMeshDS()->
+          AddPolyhedralVolumeWithID( nodes,
+                                     static_cast<const SMDS_VtkVolume*>(elem)->GetQuantities(),
+                                     ID);
+        break;
+      case SMDSEntity_Ball:
+        newElem = editor.AddElement( nodes, SMDSAbs_Ball, false, ID,
+                                     static_cast<const SMDS_BallElement*>(elem)->GetDiameter());
+        break;
+      default:
+        newElem = editor.AddElement( nodes,elem->GetType(),elem->IsPoly(),ID);
+
+      if ( toCopyGroups && !toKeepIDs )
+        e2eMapByType[ elem->GetType() ].insert( make_pair( elem, newElem ));
+      }
+    }
+  } // while ( srcElemIt->more() )
+
+  // 4(b). Copy free nodes
+
+  if ( srcNodeIt && srcMeshDS->NbNodes() != newMeshDS->NbNodes() )
+  {
+    while ( srcNodeIt->more() )
+    {
+      nSrc = srcNodeIt->next();
+      if ( nSrc->NbInverseElements() == 0 )
+      {
+        if ( toKeepIDs )
+          nTgt = newMeshDS->AddNodeWithID( nSrc->X(), nSrc->Y(), nSrc->Z(), nSrc->GetID());
+        else
+          n2nMap[ nSrc ] = newMeshDS->AddNode( nSrc->X(), nSrc->Y(), nSrc->Z() );
+      }
+    }
+  }
+
+  // 5. Copy groups
+
+  int nbNewGroups = 0;
+  if ( toCopyGroups )
+  {
+    SMESH_Mesh::GroupIteratorPtr gIt = srcMesh_i->GetImpl().GetGroups();
+    while ( gIt->more() )
+    {
+      SMESH_Group* group = gIt->next();
+      const SMESHDS_GroupBase* groupDS = group->GetGroupDS();
+
+      // Check group type. We copy nodal groups containing nodes of copied element
+      SMDSAbs_ElementType groupType = groupDS->GetType();
+      if ( groupType != SMDSAbs_Node &&
+           newMeshDS->GetMeshInfo().NbElements( groupType ) == 0 )
+        continue; // group type differs from types of meshPart
+
+      // Find copied elements in the group
+      vector< const SMDS_MeshElement* > groupElems;
+      SMDS_ElemIteratorPtr eIt = groupDS->GetElements();
+      if ( toKeepIDs )
+      {
+        const SMDS_MeshElement* foundElem;
+        if ( groupType == SMDSAbs_Node )
+        {
+          while ( eIt->more() )
+            if (( foundElem = newMeshDS->FindNode( eIt->next()->GetID() )))
+              groupElems.push_back( foundElem );
+        }
+        else
+        {
+          while ( eIt->more() )
+            if (( foundElem = newMeshDS->FindElement( eIt->next()->GetID() )))
+              groupElems.push_back( foundElem );
+        }
+      }
+      else
+      {
+        TE2EMap & e2eMap = e2eMapByType[ groupDS->GetType() ];
+        if ( e2eMap.empty() ) continue;
+        int minID = e2eMap.begin()->first->GetID();
+        int maxID = e2eMap.rbegin()->first->GetID();
+        TE2EMap::iterator e2e;
+        while ( eIt->more() && groupElems.size() < e2eMap.size())
+        {
+          const SMDS_MeshElement* e = eIt->next();
+          if ( e->GetID() < minID || e->GetID() > maxID ) continue;
+          if ((e2e = e2eMap.find( e )) != e2eMap.end())
+            groupElems.push_back( e2e->second );
+        }
+      }
+      // Make a new group
+      if ( !groupElems.empty() )
+      {
+        SMESH::SMESH_Group_var newGroupObj =
+          newMesh->CreateGroup( SMESH::ElementType(groupType), group->GetName() );
+        if ( SMESH_GroupBase_i* newGroup_i = SMESH::DownCast<SMESH_GroupBase_i*>( newGroupObj))
+        {
+          SMESHDS_GroupBase * newGroupDS = newGroup_i->GetGroupDS();
+          SMDS_MeshGroup& smdsGroup = ((SMESHDS_Group*)newGroupDS)->SMDSGroup();
+          for ( unsigned i = 0; i < groupElems.size(); ++i )
+            smdsGroup.Add( groupElems[i] );
+
+          nbNewGroups++;
+        }
+      }
+    }
+  }
+
+  newMeshDS->Modified();
+
+  *pyDump << newMesh << " = " << this
+          << ".CopyMesh( " << meshPart << ", "
+          << "'" << meshName << "', "
+          << toCopyGroups << ", "
+          << toKeepIDs << ")";
+
+  delete pyDump; pyDump = 0; // allow dump in GetGroups()
+
+  if ( nbNewGroups > 0 ) // dump created groups
+    SMESH::ListOfGroups_var groups = newMesh->GetGroups();
+
+  return newMesh._retn();
+}
+
+//================================================================================
+/*!
+ *  SMESH_Gen_i::GetMEDVersion
+ *
+ *  Get MED version of the file by its name
+ */
+//================================================================================
+CORBA::Boolean SMESH_Gen_i::GetMEDVersion(const char* theFileName,
+                                          SMESH::MED_VERSION& theVersion)
+{
+  theVersion = SMESH::MED_V2_1;
+  MED::EVersion aVersion = MED::GetVersionId( theFileName );
+  switch( aVersion ) {
+    case MED::eV2_1     : theVersion = SMESH::MED_V2_1; return true;
+    case MED::eV2_2     : theVersion = SMESH::MED_V2_2; return true;
+    case MED::eVUnknown : return false;
+  }
+  return false;
+}
+
+//================================================================================
+/*!
+ *  SMESH_Gen_i::GetMeshNames
+ *
+ *  Get names of meshes defined in file with the specified name
+ */
+//================================================================================
+SMESH::string_array* SMESH_Gen_i::GetMeshNames(const char* theFileName)
+{
+  SMESH::string_array_var aResult = new SMESH::string_array();
+  MED::PWrapper aMed = MED::CrWrapper( theFileName );
+  MED::TErr anErr;
+  MED::TInt aNbMeshes = aMed->GetNbMeshes( &anErr );
+  if( anErr >= 0 ) {
+    aResult->length( aNbMeshes );
+    for( MED::TInt i = 0; i < aNbMeshes; i++ ) {
+      MED::PMeshInfo aMeshInfo = aMed->GetPMeshInfo( i+1 );
+      aResult[i] = CORBA::string_dup( aMeshInfo->GetName().c_str() );
+    }
+  }
+  return aResult._retn();
+}
+
 //=============================================================================
 /*!
  *  SMESH_Gen_i::Save
@@ -2076,7 +2772,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
   //  ASSERT( theComponent->GetStudy()->StudyId() == myCurrentStudy->StudyId() )
   // san -- in case <myCurrentStudy> differs from theComponent's study,
   // use that of the component
-  if ( myCurrentStudy->_is_nil() || 
+  if ( myCurrentStudy->_is_nil() ||
     theComponent->GetStudy()->StudyId() != myCurrentStudy->StudyId() )
     SetCurrentStudy( theComponent->GetStudy() );
 
@@ -2097,7 +2793,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
   aFileSeq->length( NUM_TMP_FILES );
 
   TCollection_AsciiString aStudyName( "" );
-  if ( isMultiFile ) 
+  if ( isMultiFile )
     aStudyName = ( (char*)SALOMEDS_Tool::GetNameFromPath( myCurrentStudy->URL() ).c_str() );
 
   // Set names of temporary files
@@ -2136,6 +2832,41 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
   DriverMED_W_SMESHDS_Mesh myWriter;
   myWriter.SetFile( meshfile.ToCString() );
 
+  // IMP issue 20918
+  // SetStoreName() to groups before storing hypotheses to let them refer to
+  // groups using "store name", which is "Group <group_persistent_id>"
+  {
+    SALOMEDS::ChildIterator_var itBig = myCurrentStudy->NewChildIterator( theComponent );
+    for ( ; itBig->More(); itBig->Next() ) {
+      SALOMEDS::SObject_var gotBranch = itBig->Value();
+      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() ) {
+            myMesh->Load(); // load from study file if not yet done
+            TPythonDump pd; // not to dump GetGroups()
+            SMESH::ListOfGroups_var groups = myMesh->GetGroups();
+            pd << ""; // to avoid optimizing pd out
+            for ( int i = 0; i < groups->length(); ++i )
+            {
+              SMESH_GroupBase_i* grImpl = SMESH::DownCast<SMESH_GroupBase_i*>( groups[i]);
+              if ( grImpl )
+              {
+                CORBA::String_var objStr = GetORB()->object_to_string( grImpl->_this() );
+                int anId = myStudyContext->findId( string( objStr.in() ) );
+                char grpName[ 30 ];
+                sprintf( grpName, "Group %d", anId );
+                SMESHDS_GroupBase* aGrpBaseDS = grImpl->GetGroupDS();
+                aGrpBaseDS->SetStoreName( grpName );
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
   // Write data
   // ---> create HDF file
   aFile = new HDFfile( (char*) filename.ToCString() );
@@ -2319,17 +3050,33 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
             aDataset->WriteOnDisk( ( char* )( strHasData.c_str() ) );
             aDataset->CloseOnDisk();
 
-           // ouv : NPAL12872
+            // ouv : NPAL12872
             // for each mesh open the HDF group basing on its auto color parameter
-           char meshAutoColorName[ 30 ];
-           sprintf( meshAutoColorName, "AutoColorMesh %d", id );
-           int anAutoColor[1];
-           anAutoColor[0] = myImpl->GetAutoColor();
-           aSize[ 0 ] = 1;
-           aDataset = new HDFdataset( meshAutoColorName, aTopGroup, HDF_INT32, aSize, 1 );
-           aDataset->CreateOnDisk();
-           aDataset->WriteOnDisk( anAutoColor );
-           aDataset->CloseOnDisk();
+            char meshAutoColorName[ 30 ];
+            sprintf( meshAutoColorName, "AutoColorMesh %d", id );
+            int anAutoColor[1];
+            anAutoColor[0] = myImpl->GetAutoColor();
+            aSize[ 0 ] = 1;
+            aDataset = new HDFdataset( meshAutoColorName, aTopGroup, HDF_INT32, aSize, 1 );
+            aDataset->CreateOnDisk();
+            aDataset->WriteOnDisk( anAutoColor );
+            aDataset->CloseOnDisk();
+
+            // issue 0020693. Store _isModified flag
+            int isModified = myLocMesh.GetIsModified();
+            aSize[ 0 ] = 1;
+            aDataset = new HDFdataset( "_isModified", aTopGroup, HDF_INT32, aSize, 1 );
+            aDataset->CreateOnDisk();
+            aDataset->WriteOnDisk( &isModified );
+            aDataset->CloseOnDisk();
+
+            // issue 20918. Store Persistent Id of SMESHDS_Mesh
+            int meshPersistentId = mySMESHDSMesh->GetPersistentId();
+            aSize[ 0 ] = 1;
+            aDataset = new HDFdataset( "meshPersistentId", aTopGroup, HDF_INT32, aSize, 1 );
+            aDataset->CreateOnDisk();
+            aDataset->WriteOnDisk( &meshPersistentId );
+            aDataset->CloseOnDisk();
 
             // write reference on a shape if exists
             SALOMEDS::SObject_var myRef;
@@ -2370,7 +3117,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                 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. 
+                  // 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();
@@ -2413,7 +3160,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                 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. 
+                  // 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();
@@ -2563,382 +3310,430 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                           //}
                         }
                       }
-                      aSubSubGroup->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 );
+                          CORBA::String_var objStr = GetORB()->object_to_string( anObject );
+                          int id = myStudyContext->findId( string( objStr.in() ) );
+                          //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
+            // .. will NOT (PAL 12992)
+            //if ( shapeRefFound )
+            //myWriter.AddAllSubMeshes();
+
+            // store submesh order if any
+            const TListOfListOfInt& theOrderIds = myLocMesh.GetMeshOrder();
+            if ( theOrderIds.size() ) {
+              char order_list[ 30 ];
+              strcpy( order_list, "Mesh Order" );
+              // count number of submesh ids
+              int nbIDs = 0;
+              TListOfListOfInt::const_iterator idIt = theOrderIds.begin();
+              for ( ; idIt != theOrderIds.end(); idIt++ )
+                nbIDs += (*idIt).size();
+              // number of values = number of IDs +
+              //                    number of lists (for separators) - 1
+              int* smIDs = new int [ nbIDs + theOrderIds.size() - 1 ];
+              idIt = theOrderIds.begin();
+              for ( int i = 0; idIt != theOrderIds.end(); idIt++ ) {
+                const TListOfInt& idList = *idIt;
+                if (idIt != theOrderIds.begin()) // not first list
+                  smIDs[ i++ ] = -1/* *idList.size()*/; // separator between lists
+                // dump submesh ids from current list
+                TListOfInt::const_iterator id_smId = idList.begin();
+                for( ; id_smId != idList.end(); id_smId++ )
+                  smIDs[ i++ ] = *id_smId;
+              }
+              // write HDF group
+              aSize[ 0 ] = nbIDs + theOrderIds.size() - 1;
+
+              aDataset = new HDFdataset( order_list, aTopGroup, HDF_INT32, aSize, 1 );
+              aDataset->CreateOnDisk();
+              aDataset->WriteOnDisk( smIDs );
+              aDataset->CloseOnDisk();
+              //
+              delete[] smIDs;
+            }
+
+            // groups root sub-branch
+            SALOMEDS::SObject_var myGroupsBranch;
+            for ( int i = GetNodeGroupsTag(); i <= GetBallElementsGroupsTag(); 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" );
+                else if ( i == Get0DElementsGroupsTag() )
+                  strcpy( name_group, "Groups of 0D Elements" );
+                else if ( i == GetBallElementsGroupsTag() )
+                  strcpy( name_group, "Groups of Balls" );
+
+                aGroup = new HDFgroup( name_group, aTopGroup );
+                aGroup->CreateOnDisk();
+
+                SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( myGroupsBranch );
+                for ( ; it->More(); it->Next() ) {
+                  SALOMEDS::SObject_var mySObject = it->Value();
+                  CORBA::Object_var aSubObject = SObjectToObject( mySObject );
+                  if ( !CORBA::is_nil( aSubObject ) ) {
+                    SMESH_GroupBase_i* myGroupImpl =
+                      dynamic_cast<SMESH_GroupBase_i*>( GetServant( aSubObject ).in() );
+                    if ( !myGroupImpl )
+                      continue;
+                    SMESHDS_GroupBase* aGrpBaseDS = myGroupImpl->GetGroupDS();
+                    if ( !aGrpBaseDS )
+                      continue;
+
+                    CORBA::String_var objStr = GetORB()->object_to_string( aSubObject );
+                    int anId = myStudyContext->findId( string( objStr.in() ) );
+
+                    // For each group, create a dataset named "Group <group_persistent_id>"
+                    // and store the group's user name into it
+                    const char* grpName = aGrpBaseDS->GetStoreName();
+                    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();
+
+                    // ouv : NPAL12872
+                    // For each group, create a dataset named "Group <group_persistent_id> Color"
+                    // and store the group's color into it
+                    char grpColorName[ 30 ];
+                    sprintf( grpColorName, "ColorGroup %d", anId );
+                    SALOMEDS::Color aColor = myGroupImpl->GetColor();
+                    double anRGB[3];
+                    anRGB[ 0 ] = aColor.R;
+                    anRGB[ 1 ] = aColor.G;
+                    anRGB[ 2 ] = aColor.B;
+                    aSize[ 0 ] = 3;
+                    aDataset = new HDFdataset( grpColorName, aGroup, HDF_FLOAT64, aSize, 1 );
+                    aDataset->CreateOnDisk();
+                    aDataset->WriteOnDisk( anRGB );
+                    aDataset->CloseOnDisk();
+
+                    // Pass SMESHDS_Group to MED writer
+                    SMESHDS_Group* aGrpDS = dynamic_cast<SMESHDS_Group*>( aGrpBaseDS );
+                    if ( aGrpDS )
+                      myWriter.AddGroup( aGrpDS );
+
+                    // write reference on a shape if exists
+                    SMESHDS_GroupOnGeom* aGeomGrp =
+                      dynamic_cast<SMESHDS_GroupOnGeom*>( aGrpBaseDS );
+                    if ( aGeomGrp ) {
+                      SALOMEDS::SObject_var mySubRef, myShape;
+                      if (mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef ) &&
+                          mySubRef->ReferencedObject( myShape ) &&
+                          !CORBA::is_nil( myShape->GetObject() ))
+                      {
+                        string myRefOnObject = myShape->GetID();
+                        if ( myRefOnObject.length() > 0 ) {
+                          char aRefName[ 30 ];
+                          sprintf( aRefName, "Ref on shape %d", anId);
+                          aSize[ 0 ] = myRefOnObject.length() + 1;
+                          aDataset = new HDFdataset(aRefName, aGroup, HDF_STRING, aSize, 1);
+                          aDataset->CreateOnDisk();
+                          aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) );
+                          aDataset->CloseOnDisk();
+                        }
+                      }
+                      else // shape ref is invalid:
+                      {
+                        // save a group on geometry as ordinary group
+                        myWriter.AddGroup( aGeomGrp );
+                      }
+                    }
+                    else if ( SMESH_GroupOnFilter_i* aFilterGrp_i = 
+                              dynamic_cast<SMESH_GroupOnFilter_i*>( myGroupImpl ))
+                    {
+                      std::string str = aFilterGrp_i->FilterToString();
+                      std::string hdfGrpName = "Filter " + SMESH_Comment(anId);
+                      aSize[ 0 ] = str.length() + 1;
+                      aDataset = new HDFdataset( hdfGrpName.c_str(), aGroup, HDF_STRING, aSize, 1);
+                      aDataset->CreateOnDisk();
+                      aDataset->WriteOnDisk( ( char* )( str.c_str() ) );
+                      aDataset->CloseOnDisk();
+                    }
+                  }
+                }
+                aGroup->CloseOnDisk();
+              }
+            } // loop on groups
+
+            if ( strcmp( strHasData.c_str(), "1" ) == 0 )
+            {
+              // Flush current mesh information into MED file
+              myWriter.Perform();
+
+              // save info on nb of elements
+              SMESH_PreMeshInfo::SaveToFile( myImpl, id, aFile );
+
+              // maybe a shape was deleted in the study
+              if ( !shapeRefFound && !mySMESHDSMesh->ShapeToMesh().IsNull() && hasShape) {
+                TopoDS_Shape nullShape;
+                myLocMesh.ShapeToMesh( nullShape ); // remove shape referring data
+              }
+
+              if ( !mySMESHDSMesh->SubMeshes().empty() )
+              {
+                // Store submeshes
+                // ----------------
+                aGroup = new HDFgroup( "Submeshes", aTopGroup );
+                aGroup->CreateOnDisk();
+
+                // each element belongs to one or none submesh,
+                // so for each node/element, we store a submesh ID
+
+                // Make maps of submesh IDs of elements sorted by element IDs
+                typedef int TElemID;
+                typedef int TSubMID;
+                map< TElemID, TSubMID > eId2smId, nId2smId;
+                map< TElemID, TSubMID >::iterator hint; // insertion to map is done before hint
+                const map<int,SMESHDS_SubMesh*>& aSubMeshes = mySMESHDSMesh->SubMeshes();
+                map<int,SMESHDS_SubMesh*>::const_iterator itSubM ( aSubMeshes.begin() );
+                SMDS_NodeIteratorPtr itNode;
+                SMDS_ElemIteratorPtr itElem;
+                for ( itSubM = aSubMeshes.begin(); itSubM != aSubMeshes.end() ; itSubM++ )
+                {
+                  TSubMID          aSubMeID = itSubM->first;
+                  SMESHDS_SubMesh* aSubMesh = itSubM->second;
+                  if ( aSubMesh->IsComplexSubmesh() )
+                    continue; // submesh containing other submeshs
+                  // nodes
+                  hint = nId2smId.begin(); // optimize insertion basing on increasing order of elem Ids in submesh
+                  for ( itNode = aSubMesh->GetNodes(); itNode->more(); ++hint)
+                    hint = nId2smId.insert( hint, make_pair( itNode->next()->GetID(), aSubMeID ));
+                  // elements
+                  hint = eId2smId.begin();
+                  for ( itElem = aSubMesh->GetElements(); itElem->more(); ++hint)
+                    hint = eId2smId.insert( hint, make_pair( itElem->next()->GetID(), aSubMeID ));
+                }
+
+                // Care of elements that are not on submeshes
+                if ( mySMESHDSMesh->NbNodes() != nId2smId.size() ) {
+                  for ( itNode = mySMESHDSMesh->nodesIterator(); itNode->more(); )
+                    /*  --- stl_map.h says : */
+                    /*  A %map relies on unique keys and thus a %pair is only inserted if its */
+                    /*  first element (the key) is not already present in the %map.           */
+                    nId2smId.insert( make_pair( itNode->next()->GetID(), 0 ));
+                }
+                int nbElems = mySMESHDSMesh->NbEdges() + mySMESHDSMesh->NbFaces() + mySMESHDSMesh->NbVolumes();
+                if ( nbElems != eId2smId.size() ) {
+                  for ( itElem = mySMESHDSMesh->elementsIterator(); itElem->more(); )
+                    eId2smId.insert( make_pair( itElem->next()->GetID(), 0 ));
+                }
+
+                // Store submesh IDs
+                for ( int isNode = 0; isNode < 2; ++isNode )
+                {
+                  map< TElemID, TSubMID >& id2smId = isNode ? nId2smId : eId2smId;
+                  if ( id2smId.empty() ) continue;
+                  map< TElemID, TSubMID >::const_iterator id_smId = id2smId.begin();
+                  // make and fill array of submesh IDs
+                  int* smIDs = new int [ id2smId.size() ];
+                  for ( int i = 0; id_smId != id2smId.end(); ++id_smId, ++i )
+                    smIDs[ i ] = id_smId->second;
+                  // write HDF group
+                  aSize[ 0 ] = id2smId.size();
+                  string aDSName( isNode ? "Node Submeshes" : "Element Submeshes");
+                  aDataset = new HDFdataset( (char*)aDSName.c_str(), aGroup, HDF_INT32, aSize, 1 );
+                  aDataset->CreateOnDisk();
+                  aDataset->WriteOnDisk( smIDs );
+                  aDataset->CloseOnDisk();
+                  //
+                  delete[] smIDs;
+                }
+
+                aGroup->CloseOnDisk();
+
+                // Store node positions on sub-shapes (SMDS_Position):
+                // ----------------------------------------------------
+
+                aGroup = new HDFgroup( "Node Positions", aTopGroup );
+                aGroup->CreateOnDisk();
+
+                // in aGroup, create 5 datasets to contain:
+                // "Nodes on Edges" - ID of node on edge
+                // "Edge positions" - U parameter on node on edge
+                // "Nodes on Faces" - ID of node on face
+                // "Face U positions" - U parameter of node on face
+                // "Face V positions" - V parameter of node on face
+
+                // Find out nb of nodes on edges and faces
+                // Collect corresponing sub-meshes
+                int nbEdgeNodes = 0, nbFaceNodes = 0;
+                list<SMESHDS_SubMesh*> aEdgeSM, aFaceSM;
+                // loop on SMESHDS_SubMesh'es
+                for ( itSubM = aSubMeshes.begin(); itSubM != aSubMeshes.end() ; itSubM++ )
+                {
+                  SMESHDS_SubMesh* aSubMesh = (*itSubM).second;
+                  if ( aSubMesh->IsComplexSubmesh() )
+                    continue; // submesh containing other submeshs
+                  int nbNodes = aSubMesh->NbNodes();
+                  if ( nbNodes == 0 ) continue;
+
+                  int aShapeID = (*itSubM).first;
+                  if ( aShapeID < 1 || aShapeID > mySMESHDSMesh->MaxShapeIndex() )
+                    continue;
+                  int aShapeType = mySMESHDSMesh->IndexToShape( aShapeID ).ShapeType();
+                  // write only SMDS_FacePosition and SMDS_EdgePosition
+                  switch ( aShapeType ) {
+                  case TopAbs_FACE:
+                    nbFaceNodes += nbNodes;
+                    aFaceSM.push_back( aSubMesh );
+                    break;
+                  case TopAbs_EDGE:
+                    nbEdgeNodes += nbNodes;
+                    aEdgeSM.push_back( aSubMesh );
+                    break;
+                  default:
+                    continue;
+                  }
+                }
+                // Treat positions on edges or faces
+                for ( int onFace = 0; onFace < 2; onFace++ )
+                {
+                  // Create arrays to store in datasets
+                  int iNode = 0, nbNodes = ( onFace ? nbFaceNodes : nbEdgeNodes );
+                  if (!nbNodes) continue;
+                  int* aNodeIDs = new int [ nbNodes ];
+                  double* aUPos = new double [ nbNodes ];
+                  double* aVPos = ( onFace ? new double[ nbNodes ] : 0 );
+
+                  // Fill arrays
+                  // loop on sub-meshes
+                  list<SMESHDS_SubMesh*> * pListSM = ( onFace ? &aFaceSM : &aEdgeSM );
+                  list<SMESHDS_SubMesh*>::iterator itSM = pListSM->begin();
+                  for ( ; itSM != pListSM->end(); itSM++ )
+                  {
+                    SMESHDS_SubMesh* aSubMesh = (*itSM);
+
+                    SMDS_NodeIteratorPtr itNode = aSubMesh->GetNodes();
+                    // loop on nodes in aSubMesh
+                    while ( itNode->more() )
+                    {
+                      //node ID
+                      const SMDS_MeshNode* node = itNode->next();
+                      aNodeIDs [ iNode ] = node->GetID();
+
+                      // Position
+                      const SMDS_PositionPtr pos = node->GetPosition();
+                      if ( onFace ) { // on FACE
+                        const SMDS_FacePosition* fPos =
+                          dynamic_cast<const SMDS_FacePosition*>( pos );
+                        if ( fPos ) {
+                          aUPos[ iNode ] = fPos->GetUParameter();
+                          aVPos[ iNode ] = fPos->GetVParameter();
+                          iNode++;
+                        }
+                        else
+                          nbNodes--;
+                      }
+                      else { // on EDGE
+                        const SMDS_EdgePosition* ePos =
+                          dynamic_cast<const SMDS_EdgePosition*>( pos );
+                        if ( ePos ) {
+                          aUPos[ iNode ] = ePos->GetUParameter();
+                          iNode++;
+                        }
+                        else
+                          nbNodes--;
+                      }
+                    } // loop on nodes in aSubMesh
+                  } // loop on sub-meshes
 
-                    // write applied algorithms if exist
-                    SALOMEDS::SObject_var mySubAlgoBranch;
-                    found = mySObject->FindSubObject( GetRefOnAppliedAlgorithmsTag(), mySubAlgoBranch );
-                    if ( found ) {
-                      aSubSubGroup = new HDFgroup( "Applied Algorithms", aSubGroup );
-                      aSubSubGroup->CreateOnDisk();
+                  // Write datasets
+                  if ( nbNodes )
+                  {
+                    aSize[ 0 ] = nbNodes;
+                    // IDS
+                    string aDSName( onFace ? "Nodes on Faces" : "Nodes on Edges");
+                    aDataset = new HDFdataset( (char*)aDSName.c_str(), aGroup, HDF_INT32, aSize, 1 );
+                    aDataset->CreateOnDisk();
+                    aDataset->WriteOnDisk( aNodeIDs );
+                    aDataset->CloseOnDisk();
 
-                      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 );
-                          CORBA::String_var objStr = GetORB()->object_to_string( anObject );
-                          int id = myStudyContext->findId( string( objStr.in() ) );
-                          //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();
+                    // U Positions
+                    aDSName = ( onFace ? "Face U positions" : "Edge positions");
+                    aDataset = new HDFdataset( (char*)aDSName.c_str(), aGroup, HDF_FLOAT64, aSize, 1);
+                    aDataset->CreateOnDisk();
+                    aDataset->WriteOnDisk( aUPos );
+                    aDataset->CloseOnDisk();
+                    // V Positions
+                    if ( onFace ) {
+                      aDataset = new HDFdataset( "Face V positions", aGroup, HDF_FLOAT64, aSize, 1);
+                      aDataset->CreateOnDisk();
+                      aDataset->WriteOnDisk( aVPos );
+                      aDataset->CloseOnDisk();
                     }
-                    // close submesh HDF group
-                    aSubGroup->CloseOnDisk();
                   }
-                }
-                // close container of submeshes by type HDF group
+                  delete [] aNodeIDs;
+                  delete [] aUPos;
+                  if ( aVPos ) delete [] aVPos;
+
+                } // treat positions on edges or faces
+
+                // close "Node Positions" group
                 aGroup->CloseOnDisk();
-              }
-            }
-            // All sub-meshes will be stored in MED file
-            // .. will NOT (PAL 12992)
-            //if ( shapeRefFound )
-            //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 );
-               for ( ; it->More(); it->Next() ) {
-                 SALOMEDS::SObject_var mySObject = it->Value();
-                 CORBA::Object_var aSubObject = SObjectToObject( mySObject );
-                 if ( !CORBA::is_nil( aSubObject ) ) {
-                   SMESH_GroupBase_i* myGroupImpl =
-                     dynamic_cast<SMESH_GroupBase_i*>( GetServant( aSubObject ).in() );
-                   if ( !myGroupImpl )
-                     continue;
-                   
-                   CORBA::String_var objStr = GetORB()->object_to_string( aSubObject );
-                   int anId = myStudyContext->findId( string( objStr.in() ) );
-                   
-                   // For each group, create a dataset named "Group <group_persistent_id>"
-                   // 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();
-
-                   // ouv : NPAL12872
-                   // For each group, create a dataset named "Group <group_persistent_id> Color"
-                   // and store the group's color into it
-                   char grpColorName[ 30 ];
-                   sprintf( grpColorName, "ColorGroup %d", anId );
-                   SALOMEDS::Color aColor = myGroupImpl->GetColor();
-                   double anRGB[3];
-                   anRGB[ 0 ] = aColor.R;
-                   anRGB[ 1 ] = aColor.G;
-                   anRGB[ 2 ] = aColor.B;
-                   aSize[ 0 ] = 3;
-                   aDataset = new HDFdataset( grpColorName, aGroup, HDF_FLOAT64, aSize, 1 );
-                   aDataset->CreateOnDisk();
-                   aDataset->WriteOnDisk( anRGB );
-                   aDataset->CloseOnDisk();
-
-                   // Store the group contents into MED file
-                   if ( myLocMesh.GetGroup( myGroupImpl->GetLocalID() ) ) {
-                     
-                     if(MYDEBUG) MESSAGE( "VSR - SMESH_Gen_i::Save(): saving group with StoreName = "
-                                         << grpName << " to MED file" );
-                     SMESHDS_GroupBase* aGrpBaseDS =
-                       myLocMesh.GetGroup( myGroupImpl->GetLocalID() )->GetGroupDS();
-                     aGrpBaseDS->SetStoreName( grpName );
-
-                     // Pass SMESHDS_Group to MED writer 
-                     SMESHDS_Group* aGrpDS = dynamic_cast<SMESHDS_Group*>( aGrpBaseDS );
-                     if ( aGrpDS )
-                       myWriter.AddGroup( aGrpDS );
-                     
-                     // write reference on a shape if exists
-                     SMESHDS_GroupOnGeom* aGeomGrp =
-                       dynamic_cast<SMESHDS_GroupOnGeom*>( aGrpBaseDS );
-                     if ( aGeomGrp ) {
-                       SALOMEDS::SObject_var mySubRef, myShape;
-                       if (mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef ) &&
-                           mySubRef->ReferencedObject( myShape ) &&
-                           !CORBA::is_nil( myShape->GetObject() ))
-                       {
-                         string myRefOnObject = myShape->GetID();
-                         if ( myRefOnObject.length() > 0 ) {
-                           char aRefName[ 30 ];
-                           sprintf( aRefName, "Ref on shape %d", anId);
-                           aSize[ 0 ] = myRefOnObject.length() + 1;
-                           aDataset = new HDFdataset(aRefName, aGroup, HDF_STRING, aSize, 1);
-                           aDataset->CreateOnDisk();
-                           aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) );
-                           aDataset->CloseOnDisk();
-                         }
-                       }
-                       else // shape ref is invalid:
-                       {
-                         // save a group on geometry as ordinary group
-                         myWriter.AddGroup( aGeomGrp );
-                       }
-                     }
-                   }
-                 }
-               }
-               aGroup->CloseOnDisk();
-             }
-           } // loop on groups 
-           
-           if ( strcmp( strHasData.c_str(), "1" ) == 0 )
-           {
-             // Flush current mesh information into MED file
-             myWriter.Perform();
-             
-             // maybe a shape was deleted in the study
-             if ( !shapeRefFound && !mySMESHDSMesh->ShapeToMesh().IsNull() && hasShape) {
-               TopoDS_Shape nullShape;
-               myLocMesh.ShapeToMesh( nullShape ); // remove shape referring data
-             }
-             
-             if ( !mySMESHDSMesh->SubMeshes().empty() )
-             {
-               // Store submeshes
-               // ----------------
-               aGroup = new HDFgroup( "Submeshes", aTopGroup );
-               aGroup->CreateOnDisk();
-               
-               // each element belongs to one or none submesh,
-               // so for each node/element, we store a submesh ID
-               
-               // Make maps of submesh IDs of elements sorted by element IDs
-               typedef int TElemID;
-               typedef int TSubMID;
-               map< TElemID, TSubMID > eId2smId, nId2smId;
-               map< TElemID, TSubMID >::iterator hint; // insertion to map is done before hint
-               const map<int,SMESHDS_SubMesh*>& aSubMeshes = mySMESHDSMesh->SubMeshes();
-               map<int,SMESHDS_SubMesh*>::const_iterator itSubM ( aSubMeshes.begin() );
-               SMDS_NodeIteratorPtr itNode;
-               SMDS_ElemIteratorPtr itElem;
-               for ( itSubM = aSubMeshes.begin(); itSubM != aSubMeshes.end() ; itSubM++ )
-               {
-                 TSubMID          aSubMeID = itSubM->first;
-                 SMESHDS_SubMesh* aSubMesh = itSubM->second;
-                 if ( aSubMesh->IsComplexSubmesh() )
-                   continue; // submesh containing other submeshs
-                 // nodes
-                 hint = nId2smId.begin(); // optimize insertion basing on increasing order of elem Ids in submesh
-                 for ( itNode = aSubMesh->GetNodes(); itNode->more(); ++hint)
-                   hint = nId2smId.insert( hint, make_pair( itNode->next()->GetID(), aSubMeID ));
-                  // elements
-                 hint = eId2smId.begin();
-                 for ( itElem = aSubMesh->GetElements(); itElem->more(); ++hint)
-                   hint = eId2smId.insert( hint, make_pair( itElem->next()->GetID(), aSubMeID ));
-               }
-               
-               // Care of elements that are not on submeshes
-               if ( mySMESHDSMesh->NbNodes() != nId2smId.size() ) {
-                 for ( itNode = mySMESHDSMesh->nodesIterator(); itNode->more(); )
-                   /*  --- stl_map.h says : */
-                   /*  A %map relies on unique keys and thus a %pair is only inserted if its */
-                   /*  first element (the key) is not already present in the %map.           */
-                   nId2smId.insert( make_pair( itNode->next()->GetID(), 0 ));
-               }
-               int nbElems = mySMESHDSMesh->NbEdges() + mySMESHDSMesh->NbFaces() + mySMESHDSMesh->NbVolumes();
-               if ( nbElems != eId2smId.size() ) {
-                 for ( itElem = mySMESHDSMesh->elementsIterator(); itElem->more(); )
-                   eId2smId.insert( make_pair( itElem->next()->GetID(), 0 ));
-               }
-               
-               // Store submesh IDs
-               for ( int isNode = 0; isNode < 2; ++isNode )
-               {
-                 map< TElemID, TSubMID >& id2smId = isNode ? nId2smId : eId2smId;
-                 if ( id2smId.empty() ) continue;
-                 map< TElemID, TSubMID >::const_iterator id_smId = id2smId.begin();
-                 // make and fill array of submesh IDs
-                 int* smIDs = new int [ id2smId.size() ];
-                 for ( int i = 0; id_smId != id2smId.end(); ++id_smId, ++i )
-                   smIDs[ i ] = id_smId->second;
-                 // write HDF group
-                 aSize[ 0 ] = id2smId.size();
-                 string aDSName( isNode ? "Node Submeshes" : "Element Submeshes");
-                 aDataset = new HDFdataset( (char*)aDSName.c_str(), aGroup, HDF_INT32, aSize, 1 );
-                 aDataset->CreateOnDisk();
-                 aDataset->WriteOnDisk( smIDs );
-                 aDataset->CloseOnDisk();
-                 //
-                 delete smIDs;
-               }
-                
-               // Store node positions on sub-shapes (SMDS_Position):
-               // ----------------------------------------------------
-               
-               aGroup = new HDFgroup( "Node Positions", aTopGroup );
-               aGroup->CreateOnDisk();
-               
-               // in aGroup, create 5 datasets to contain:
-               // "Nodes on Edges" - ID of node on edge
-               // "Edge positions" - U parameter on node on edge
-               // "Nodes on Faces" - ID of node on face
-               // "Face U positions" - U parameter of node on face
-               // "Face V positions" - V parameter of node on face
-               
-               // Find out nb of nodes on edges and faces
-               // Collect corresponing sub-meshes
-               int nbEdgeNodes = 0, nbFaceNodes = 0;
-               list<SMESHDS_SubMesh*> aEdgeSM, aFaceSM;
-               // loop on SMESHDS_SubMesh'es
-               for ( itSubM = aSubMeshes.begin(); itSubM != aSubMeshes.end() ; itSubM++ )
-               {
-                 SMESHDS_SubMesh* aSubMesh = (*itSubM).second;
-                 if ( aSubMesh->IsComplexSubmesh() )
-                   continue; // submesh containing other submeshs
-                 int nbNodes = aSubMesh->NbNodes();
-                 if ( nbNodes == 0 ) continue;
-                 
-                 int aShapeID = (*itSubM).first;
-                 int aShapeType = mySMESHDSMesh->IndexToShape( aShapeID ).ShapeType();
-                 // write only SMDS_FacePosition and SMDS_EdgePosition
-                 switch ( aShapeType ) {
-                 case TopAbs_FACE:
-                   nbFaceNodes += nbNodes;
-                   aFaceSM.push_back( aSubMesh );
-                   break;
-                 case TopAbs_EDGE:
-                   nbEdgeNodes += nbNodes;
-                   aEdgeSM.push_back( aSubMesh );
-                   break;
-                 default:
-                   continue;
-                 }
-               }
-               // Treat positions on edges or faces
-               for ( int onFace = 0; onFace < 2; onFace++ )
-               {
-                 // Create arrays to store in datasets
-                 int iNode = 0, nbNodes = ( onFace ? nbFaceNodes : nbEdgeNodes );
-                 if (!nbNodes) continue;
-                 int* aNodeIDs = new int [ nbNodes ];
-                 double* aUPos = new double [ nbNodes ];
-                 double* aVPos = ( onFace ? new double[ nbNodes ] : 0 );
-                 
-                 // Fill arrays
-                 // loop on sub-meshes
-                 list<SMESHDS_SubMesh*> * pListSM = ( onFace ? &aFaceSM : &aEdgeSM );
-                 list<SMESHDS_SubMesh*>::iterator itSM = pListSM->begin();
-                 for ( ; itSM != pListSM->end(); itSM++ )
-                 {
-                   SMESHDS_SubMesh* aSubMesh = (*itSM);
-                   
-                   SMDS_NodeIteratorPtr itNode = aSubMesh->GetNodes();
-                   // loop on nodes in aSubMesh
-                   while ( itNode->more() )
-                   {
-                     //node ID
-                     const SMDS_MeshNode* node = itNode->next();
-                     aNodeIDs [ iNode ] = node->GetID();
-                     
-                     // Position
-                     const SMDS_PositionPtr pos = node->GetPosition();
-                     if ( onFace ) { // on FACE
-                       const SMDS_FacePosition* fPos =
-                         dynamic_cast<const SMDS_FacePosition*>( pos.get() );
-                       if ( fPos ) {
-                         aUPos[ iNode ] = fPos->GetUParameter();
-                         aVPos[ iNode ] = fPos->GetVParameter();
-                         iNode++;
-                       }
-                       else
-                         nbNodes--;
-                     }
-                     else { // on EDGE
-                       const SMDS_EdgePosition* ePos =
-                         dynamic_cast<const SMDS_EdgePosition*>( pos.get() );
-                       if ( ePos ) {
-                         aUPos[ iNode ] = ePos->GetUParameter();
-                         iNode++;
-                       }
-                       else
-                         nbNodes--;
-                     }
-                   } // loop on nodes in aSubMesh
-                 } // loop on sub-meshes
-                 
-                 // Write datasets
-                 if ( nbNodes )
-                 {
-                   aSize[ 0 ] = nbNodes;
-                   // IDS
-                   string aDSName( onFace ? "Nodes on Faces" : "Nodes on Edges");
-                   aDataset = new HDFdataset( (char*)aDSName.c_str(), aGroup, HDF_INT32, aSize, 1 );
-                   aDataset->CreateOnDisk();
-                   aDataset->WriteOnDisk( aNodeIDs );
-                   aDataset->CloseOnDisk();
-               
-                   // U Positions
-                   aDSName = ( onFace ? "Face U positions" : "Edge positions");
-                   aDataset = new HDFdataset( (char*)aDSName.c_str(), aGroup, HDF_FLOAT64, aSize, 1);
-                   aDataset->CreateOnDisk();
-                   aDataset->WriteOnDisk( aUPos );
-                   aDataset->CloseOnDisk();
-                   // V Positions
-                   if ( onFace ) {
-                     aDataset = new HDFdataset( "Face V positions", aGroup, HDF_FLOAT64, aSize, 1);
-                     aDataset->CreateOnDisk();
-                     aDataset->WriteOnDisk( aVPos );
-                     aDataset->CloseOnDisk();
-                   }
-                 }
-                 delete [] aNodeIDs;
-                 delete [] aUPos;
-                 if ( aVPos ) delete [] aVPos;
-                 
-               } // treat positions on edges or faces
-               
-               // close "Node Positions" group
-               aGroup->CloseOnDisk(); 
-               
-             } // if ( there are submeshes in SMESHDS_Mesh )
-           } // if ( hasData )
-           
-           // close mesh HDF group
-           aTopGroup->CloseOnDisk();
-         }
-       }
+              } // if ( there are submeshes in SMESHDS_Mesh )
+            } // if ( hasData )
+
+            // close mesh HDF group
+            aTopGroup->CloseOnDisk();
+          }
+        }
       }
     }
   }
-  
+
   // close HDF file
   aFile->CloseOnDisk();
   delete aFile;
@@ -2947,7 +3742,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
   aStreamFile = SALOMEDS_Tool::PutFilesToStream( tmpDir.ToCString(), aFileSeq.in(), isMultiFile );
 
   // Remove temporary files and directory
-  if ( !isMultiFile ) 
+  if ( !isMultiFile )
     SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true );
 
   INFOS( "SMESH_Gen_i::Save() completed" );
@@ -2963,8 +3758,8 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
 //=============================================================================
 
 SALOMEDS::TMPFile* SMESH_Gen_i::SaveASCII( SALOMEDS::SComponent_ptr theComponent,
-                                          const char*              theURL,
-                                          bool                     isMultiFile ) {
+                                           const char*              theURL,
+                                           bool                     isMultiFile ) {
   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::SaveASCII" );
   SALOMEDS::TMPFile_var aStreamFile = Save( theComponent, theURL, isMultiFile );
   return aStreamFile._retn();
@@ -2974,12 +3769,12 @@ SALOMEDS::TMPFile* SMESH_Gen_i::SaveASCII( SALOMEDS::SComponent_ptr theComponent
   int size = aStreamFile.in().length();
   _CORBA_Octet* buffer = new _CORBA_Octet[size*3+1];
   for ( int i = 0; i < size; i++ )
-    sprintf( (char*)&(buffer[i*3]), "|%02x", (char*)(aStreamFile[i]) );
+    sprintf( (char*)&(buffer[i*3]), "|%02x", aStreamFile[i] );
 
   buffer[size * 3] = '\0';
 
   SALOMEDS::TMPFile_var anAsciiStreamFile = new SALOMEDS::TMPFile(size*3, size*3, buffer, 1);
-  
+
   return anAsciiStreamFile._retn();
 }
 
@@ -3000,34 +3795,9 @@ void SMESH_Gen_i::loadGeomData( SALOMEDS::SComponent_ptr theCompRoot )
   if ( aStudy->_is_nil() )
     return;
 
-  SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder(); 
+  SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
   aStudyBuilder->LoadWith( theCompRoot, GetGeomEngine() );
 }
-//=============================================================================
-/*!
- * \brief Creates SMDS_Position according to shape type
- */
-//=============================================================================
-
-class PositionCreator {
-public:
-  SMDS_PositionPtr MakePosition(const TopAbs_ShapeEnum type) {
-    return (this->*myFuncTable[ type ])();
-  }
-  PositionCreator() {
-    myFuncTable.resize( (size_t) TopAbs_SHAPE, & PositionCreator::defaultPosition );
-    myFuncTable[ TopAbs_FACE ] = & PositionCreator::facePosition;
-    myFuncTable[ TopAbs_EDGE ] = & PositionCreator::edgePosition;
-    myFuncTable[ TopAbs_VERTEX ] = & PositionCreator::vertexPosition;
-  }
-private:
-  SMDS_PositionPtr edgePosition()    const { return SMDS_PositionPtr( new SMDS_EdgePosition  ); }
-  SMDS_PositionPtr facePosition()    const { return SMDS_PositionPtr( new SMDS_FacePosition  ); }
-  SMDS_PositionPtr vertexPosition()  const { return SMDS_PositionPtr( new SMDS_VertexPosition); }
-  SMDS_PositionPtr defaultPosition() const { return SMDS_SpacePosition::originSpacePosition();  }
-  typedef SMDS_PositionPtr (PositionCreator:: * FmakePos)() const;
-  vector<FmakePos> myFuncTable;
-};
 
 //=============================================================================
 /*!
@@ -3038,13 +3808,13 @@ private:
 //=============================================================================
 
 bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
-                       const SALOMEDS::TMPFile& theStream,
-                       const char*              theURL,
-                       bool                     isMultiFile )
+                        const SALOMEDS::TMPFile& theStream,
+                        const char*              theURL,
+                        bool                     isMultiFile )
 {
   INFOS( "SMESH_Gen_i::Load" );
 
-  if ( myCurrentStudy->_is_nil() || 
+  if ( myCurrentStudy->_is_nil() ||
        theComponent->GetStudy()->StudyId() != myCurrentStudy->StudyId() )
     SetCurrentStudy( theComponent->GetStudy() );
 
@@ -3060,7 +3830,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
   // Get temporary files location
   TCollection_AsciiString tmpDir =
     isMultiFile ? TCollection_AsciiString( ( char* )theURL ) : ( char* )SALOMEDS_Tool::GetTmpDir().c_str();
-    
+
     INFOS( "THE URL++++++++++++++" )
     INFOS( theURL );
     INFOS( "THE TMP PATH+++++++++" );
@@ -3069,9 +3839,9 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
   // Convert the stream into sequence of files to process
   SALOMEDS::ListOfFileNames_var aFileSeq = SALOMEDS_Tool::PutStreamToFiles( theStream,
                                                                             tmpDir.ToCString(),
-                                                                           isMultiFile );
+                                                                            isMultiFile );
   TCollection_AsciiString aStudyName( "" );
-  if ( isMultiFile ) 
+  if ( isMultiFile )
     aStudyName = ( (char*)SALOMEDS_Tool::GetNameFromPath( myCurrentStudy->URL() ).c_str() );
 
   // Set names of temporary files
@@ -3097,8 +3867,10 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
     return false;
   }
 
-  DriverMED_R_SMESHDS_Mesh myReader;
-  myReader.SetFile( meshfile.ToCString() );
+  TPythonDump pd; // prevent dump during loading
+
+  // DriverMED_R_SMESHDS_Mesh myReader;
+  // myReader.SetFile( meshfile.ToCString() );
 
   // For PAL13473 ("Repetitive mesh") implementation.
   // New dependencies between SMESH objects are established:
@@ -3114,99 +3886,99 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
   list< pair< SMESH_Mesh_i*,       HDFgroup* > > meshGroupList;
 
   // get total number of top-level groups
-  int aNbGroups = aFile->nInternalObjects(); 
+  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 = new HDFgroup( "Hypotheses", aFile );
       aTopGroup->OpenOnDisk();
 
       // get number of hypotheses
-      int aNbObjects = aTopGroup->nInternalObjects(); 
+      int aNbObjects = aTopGroup->nInternalObjects();
       for ( int j = 0; j < aNbObjects; j++ ) {
-       // try to identify hypothesis
-       char hypGrpName[ HDF_NAME_MAX_LEN+1 ];
+        // 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 );
-             if(MYDEBUG) 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
-           if(MYDEBUG) MESSAGE("VSR - load hypothesis : id = " << id <<
+        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 );
+              if(MYDEBUG) 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
+            if(MYDEBUG) 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 (...) {
-             INFOS( "Exception during hypothesis creation" );
-           }
+            try { // protect persistence mechanism against exceptions
+              myHyp = this->createHypothesis( hypname.c_str(), libname.c_str() );
+            }
+            catch (...) {
+              INFOS( "Exception during hypothesis creation" );
+            }
 
-           SMESH_Hypothesis_i* myImpl = dynamic_cast<SMESH_Hypothesis_i*>( GetServant( myHyp ).in() );
-           if ( myImpl ) {
-             // myImpl->LoadFrom( hypdata.c_str() );
+            SMESH_Hypothesis_i* myImpl = dynamic_cast<SMESH_Hypothesis_i*>( GetServant( myHyp ).in() );
+            if ( myImpl ) {
+              // myImpl->LoadFrom( hypdata.c_str() );
               hypDataList.push_back( make_pair( myImpl, hypdata ));
-             string iorString = GetORB()->object_to_string( myHyp );
-             int newId = myStudyContext->findId( iorString );
-             myStudyContext->mapOldToNew( id, newId );
-           }
-           else
-             if(MYDEBUG) MESSAGE( "VSR - SMESH_Gen::Load - can't get servant" );
+              string iorString = GetORB()->object_to_string( myHyp );
+              int newId = myStudyContext->findId( iorString );
+              myStudyContext->mapOldToNew( id, newId );
+            }
+            else
+              if(MYDEBUG) MESSAGE( "VSR - SMESH_Gen::Load - can't get servant" );
           }
         }
       }
@@ -3218,95 +3990,95 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
     // --> then we should read&create algorithms
     if ( aFile->ExistInternalObject( "Algorithms" ) ) {
       // open algorithms root HDF group
-      aTopGroup = new HDFgroup( "Algorithms", aFile ); 
+      aTopGroup = new HDFgroup( "Algorithms", aFile );
       aTopGroup->OpenOnDisk();
 
       // get number of algorithms
-      int aNbObjects = aTopGroup->nInternalObjects(); 
+      int aNbObjects = aTopGroup->nInternalObjects();
       for ( int j = 0; j < aNbObjects; j++ ) {
-       // try to identify algorithm
-       char hypGrpName[ HDF_NAME_MAX_LEN+1 ];
+        // 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 );
-             if(MYDEBUG) 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 );
-             if(MYDEBUG) 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
-           if(MYDEBUG) MESSAGE("VSR - load algo : id = " << id <<
+        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 );
+              if(MYDEBUG) 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 );
+              if(MYDEBUG) 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
+            if(MYDEBUG) 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 (...) {
-             INFOS( "Exception during hypothesis creation" );
-           }
+            try { // protect persistence mechanism against exceptions
+              myHyp = this->createHypothesis( hypname.c_str(), libname.c_str() );
+            }
+            catch (...) {
+              INFOS( "Exception during hypothesis creation" );
+            }
 
-           SMESH_Hypothesis_i* myImpl = dynamic_cast<SMESH_Hypothesis_i*>( GetServant( myHyp ).in() );
-           if ( myImpl ) {
-             //myImpl->LoadFrom( hypdata.c_str() );
+            SMESH_Hypothesis_i* myImpl = dynamic_cast<SMESH_Hypothesis_i*>( GetServant( myHyp ).in() );
+            if ( myImpl ) {
+              //myImpl->LoadFrom( hypdata.c_str() );
               hypDataList.push_back( make_pair( myImpl, hypdata ));
-             string iorString = GetORB()->object_to_string( myHyp );
-             int newId = myStudyContext->findId( iorString );
-             myStudyContext->mapOldToNew( id, newId );
-           }
-           else
-             if(MYDEBUG) MESSAGE( "VSR - SMESH_Gen::Load - can't get servant" );
+              string iorString = GetORB()->object_to_string( myHyp );
+              int newId = myStudyContext->findId( iorString );
+              myStudyContext->mapOldToNew( id, newId );
+            }
+            else
+              if(MYDEBUG) MESSAGE( "VSR - SMESH_Gen::Load - can't get servant" );
           }
         }
       }
@@ -3322,44 +4094,44 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
       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;
-
-       // 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
-         if(MYDEBUG) MESSAGE( "VSR - load mesh : id = " << id );
-         SMESH::SMESH_Mesh_var myNewMesh = this->createMesh();
-         SMESH_Mesh_i* myNewMeshImpl = dynamic_cast<SMESH_Mesh_i*>( GetServant( myNewMesh ).in() );
+        // --> get mesh id
+        int id = atoi( string( meshName ).substr( 4 ).c_str() );
+        if ( id <= 0 )
+          continue;
+
+        // 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
+          if(MYDEBUG) MESSAGE( "VSR - load mesh : id = " << id );
+          SMESH::SMESH_Mesh_var myNewMesh = this->createMesh();
+          SMESH_Mesh_i* myNewMeshImpl = dynamic_cast<SMESH_Mesh_i*>( GetServant( myNewMesh ).in() );
           if ( !myNewMeshImpl )
-           continue;
+            continue;
           meshGroupList.push_back( make_pair( myNewMeshImpl, aTopGroup ));
 
-         string iorString = GetORB()->object_to_string( myNewMesh );
-         int newId = myStudyContext->findId( iorString );
-         myStudyContext->mapOldToNew( id, newId );
-
-         // ouv : NPAL12872
-         // try to read and set auto color flag
-         char aMeshAutoColorName[ 30 ];
-         sprintf( aMeshAutoColorName, "AutoColorMesh %d", id);
-         if( aTopGroup->ExistInternalObject( aMeshAutoColorName ) )
-         {
-           aDataset = new HDFdataset( aMeshAutoColorName, aTopGroup );
-           aDataset->OpenOnDisk();
-           size = aDataset->GetSize();
-           int* anAutoColor = new int[ size ];
-           aDataset->ReadFromDisk( anAutoColor );
-           aDataset->CloseOnDisk();
-           myNewMeshImpl->SetAutoColor( (bool)anAutoColor[0] );
-         }
+          string iorString = GetORB()->object_to_string( myNewMesh );
+          int newId = myStudyContext->findId( iorString );
+          myStudyContext->mapOldToNew( id, newId );
+
+          // ouv : NPAL12872
+          // try to read and set auto color flag
+          char aMeshAutoColorName[ 30 ];
+          sprintf( aMeshAutoColorName, "AutoColorMesh %d", id);
+          if( aTopGroup->ExistInternalObject( aMeshAutoColorName ) )
+          {
+            aDataset = new HDFdataset( aMeshAutoColorName, aTopGroup );
+            aDataset->OpenOnDisk();
+            size = aDataset->GetSize();
+            int* anAutoColor = new int[ size ];
+            aDataset->ReadFromDisk( anAutoColor );
+            aDataset->CloseOnDisk();
+            myNewMeshImpl->GetImpl().SetAutoColor( (bool)anAutoColor[0] );
+          }
 
           // try to read and set reference to shape
           GEOM::GEOM_Object_var aShapeObject;
@@ -3386,9 +4158,32 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
             }
           }
 
+          // issue 0020693. Restore _isModified flag
+          if( aTopGroup->ExistInternalObject( "_isModified" ) )
+          {
+            aDataset = new HDFdataset( "_isModified", aTopGroup );
+            aDataset->OpenOnDisk();
+            size = aDataset->GetSize();
+            int* isModified = new int[ size ];
+            aDataset->ReadFromDisk( isModified );
+            aDataset->CloseOnDisk();
+            myNewMeshImpl->GetImpl().SetIsModified( bool(*isModified));
+          }
+
+          // issue 20918. Restore Persistent Id of SMESHDS_Mesh
+          if( aTopGroup->ExistInternalObject( "meshPersistentId" ) )
+          {
+            aDataset = new HDFdataset( "meshPersistentId", aTopGroup );
+            aDataset->OpenOnDisk();
+            size = aDataset->GetSize();
+            int* meshPersistentId = new int[ size ];
+            aDataset->ReadFromDisk( meshPersistentId );
+            aDataset->CloseOnDisk();
+            myNewMeshImpl->GetImpl().GetMeshDS()->SetPersistentId( *meshPersistentId );
+          }
         }
       }
-    }
+    } // reading MESHes
 
     // As all object that can be referred by hypothesis are created,
     // we can restore hypothesis data
@@ -3408,8 +4203,8 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
     {
       aTopGroup                   = meshi_group->second;
       SMESH_Mesh_i* myNewMeshImpl = meshi_group->first;
-      ::SMESH_Mesh& myLocMesh     = myNewMeshImpl->GetImpl();
-      SMESHDS_Mesh* mySMESHDSMesh = myLocMesh.GetMeshDS();
+      //::SMESH_Mesh& myLocMesh     = myNewMeshImpl->GetImpl();
+      //SMESHDS_Mesh* mySMESHDSMesh = myLocMesh.GetMeshDS();
 
       GEOM::GEOM_Object_var aShapeObject = myNewMeshImpl->GetShapeToMesh();
       bool hasData = false;
@@ -3430,19 +4225,20 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
         aDataset->CloseOnDisk();
         if ( strcmp( strHasData, "1") == 0 ) {
           // read mesh data from MED file
-          myReader.SetMesh( mySMESHDSMesh );
-          myReader.SetMeshId( id );
-          myReader.Perform();
+          // myReader.SetMesh( mySMESHDSMesh );
+          // myReader.SetMeshId( id );
+          // myReader.Perform();
           hasData = true;
         }
       }
 
-      // try to get applied algorithms
+      // Try to get applied ALGORITHMS (mesh is not cleared by algo addition because
+      // nodes and elements are not yet put into sub-meshes)
       if ( aTopGroup->ExistInternalObject( "Applied Algorithms" ) ) {
         aGroup = new HDFgroup( "Applied Algorithms", aTopGroup );
         aGroup->OpenOnDisk();
         // get number of applied algorithms
-        int aNbSubObjects = aGroup->nInternalObjects(); 
+        int aNbSubObjects = aGroup->nInternalObjects();
         if(MYDEBUG) MESSAGE( "VSR - number of applied algos " << aNbSubObjects );
         for ( int j = 0; j < aNbSubObjects; j++ ) {
           char name_dataset[ HDF_NAME_MAX_LEN+1 ];
@@ -3455,9 +4251,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
             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 );
@@ -3481,7 +4275,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
         aGroup = new HDFgroup( "Applied Hypotheses", aTopGroup );
         aGroup->OpenOnDisk();
         // get number of applied hypotheses
-        int aNbSubObjects = aGroup->nInternalObjects(); 
+        int aNbSubObjects = aGroup->nInternalObjects();
         for ( int j = 0; j < aNbSubObjects; j++ ) {
           char name_dataset[ HDF_NAME_MAX_LEN+1 ];
           aGroup->InternalObjectIndentify( j, name_dataset );
@@ -3493,9 +4287,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
             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 );
@@ -3514,7 +4306,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
         aGroup->CloseOnDisk();
       }
 
-      // --> try to find submeshes containers for each type of submesh
+      // --> try to find SUB-MESHES containers for each type of submesh
       for ( int j = GetSubMeshOnVertexTag(); j <= GetSubMeshOnCompoundTag(); j++ ) {
         char name_meshgroup[ 30 ];
         if ( j == GetSubMeshOnVertexTag() )
@@ -3539,7 +4331,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
           aGroup->OpenOnDisk();
 
           // get number of submeshes
-          int aNbSubMeshes = aGroup->nInternalObjects(); 
+          int aNbSubMeshes = aGroup->nInternalObjects();
           for ( int k = 0; k < aNbSubMeshes; k++ ) {
             // identify submesh
             char name_submeshgroup[ HDF_NAME_MAX_LEN+1 ];
@@ -3585,28 +4377,13 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
               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()) {
-              //                    if(MYDEBUG) 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 ) {
-              //                      if(MYDEBUG) 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 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(); 
+                int aNbSubObjects = aSubSubGroup->nInternalObjects();
                 for ( int l = 0; l < aNbSubObjects; l++ ) {
                   char name_dataset[ HDF_NAME_MAX_LEN+1 ];
                   aSubSubGroup->InternalObjectIndentify( l, name_dataset );
@@ -3619,8 +4396,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
                     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() ) {
@@ -3643,7 +4418,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
                 aSubSubGroup = new HDFgroup( "Applied Hypotheses", aSubGroup );
                 aSubSubGroup->OpenOnDisk();
                 // get number of applied hypotheses
-                int aNbSubObjects = aSubSubGroup->nInternalObjects(); 
+                int aNbSubObjects = aSubSubGroup->nInternalObjects();
                 for ( int l = 0; l < aNbSubObjects; l++ ) {
                   char name_dataset[ HDF_NAME_MAX_LEN+1 ];
                   aSubSubGroup->InternalObjectIndentify( l, name_dataset );
@@ -3656,8 +4431,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
                     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() ) {
@@ -3670,222 +4443,21 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
                     }
                   }
                 }
-                // close "applied hypotheses" HDF group
+                // close "APPLIED HYPOTHESES" hdf group
                 aSubSubGroup->CloseOnDisk();
               }
 
-              // close submesh HDF group
+              // close SUB-MESH hdf group
               aSubGroup->CloseOnDisk();
             }
           }
-          // close submeshes containers HDF group
+          // close SUB-MESHES containers hdf group
           aGroup->CloseOnDisk();
         }
       }
 
-      if(hasData) {
-
-        // Read sub-meshes from MED
-        // -------------------------
-        if(MYDEBUG) MESSAGE("Create all sub-meshes");
-        bool submeshesInFamilies = ( ! aTopGroup->ExistInternalObject( "Submeshes" ));
-        if ( submeshesInFamilies )
-        {
-          // old way working before fix of PAL 12992
-          myReader.CreateAllSubMeshes();
-        }
-        else
-        {
-          // open a group
-          aGroup = new HDFgroup( "Submeshes", aTopGroup ); 
-          aGroup->OpenOnDisk();
-
-          int maxID = mySMESHDSMesh->MaxShapeIndex();
-          vector< SMESHDS_SubMesh * > subMeshes( maxID + 1, (SMESHDS_SubMesh*) 0 );
-          vector< TopAbs_ShapeEnum  > smType   ( maxID + 1, TopAbs_SHAPE ); 
-
-          PositionCreator aPositionCreator;
-
-          SMDS_NodeIteratorPtr nIt = mySMESHDSMesh->nodesIterator();
-          SMDS_ElemIteratorPtr eIt = mySMESHDSMesh->elementsIterator();
-          for ( int isNode = 0; isNode < 2; ++isNode )
-          {
-            string aDSName( isNode ? "Node Submeshes" : "Element Submeshes");
-            if ( aGroup->ExistInternalObject( (char*) aDSName.c_str() ))
-            {
-              aDataset = new HDFdataset( (char*) aDSName.c_str(), aGroup );
-              aDataset->OpenOnDisk();
-              // read submesh IDs for all elements sorted by ID
-              int nbElems = aDataset->GetSize();
-              int* smIDs = new int [ nbElems ];
-              aDataset->ReadFromDisk( smIDs );
-              aDataset->CloseOnDisk();
-
-              // get elements sorted by ID
-              TIDSortedElemSet elemSet;
-              if ( isNode )
-                while ( nIt->more() ) elemSet.insert( nIt->next() );
-              else
-                while ( eIt->more() ) elemSet.insert( eIt->next() );
-              ASSERT( elemSet.size() == nbElems );
-
-              // add elements to submeshes
-              TIDSortedElemSet::iterator iE = elemSet.begin();
-              for ( int i = 0; i < nbElems; ++i, ++iE )
-              {
-                int smID = smIDs[ i ];
-                if ( smID == 0 ) continue;
-                ASSERT( smID <= maxID );
-                const SMDS_MeshElement* elem = *iE;
-                // get or create submesh
-                SMESHDS_SubMesh* & sm = subMeshes[ smID ];
-                if ( ! sm ) {
-                  sm = mySMESHDSMesh->NewSubMesh( smID );
-                  smType[ smID ] = mySMESHDSMesh->IndexToShape( smID ).ShapeType();
-                }
-                // add
-                if ( isNode ) {
-                  SMDS_PositionPtr pos = aPositionCreator.MakePosition( smType[ smID ]);
-                  pos->SetShapeId( smID );
-                  SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( static_cast<const SMDS_MeshNode*>( elem ));
-                  node->SetPosition( pos );
-                  sm->AddNode( node );
-                } else {
-                  sm->AddElement( elem );
-                }
-              }
-              delete [] smIDs;
-            }
-          }
-        } // end reading submeshes
-
-        // Read node positions on sub-shapes (SMDS_Position)
-
-        if ( aTopGroup->ExistInternalObject( "Node Positions" ))
-        {
-          // There are 5 datasets to read:
-          // "Nodes on Edges" - ID of node on edge
-          // "Edge positions" - U parameter on node on edge
-          // "Nodes on Faces" - ID of node on face
-          // "Face U positions" - U parameter of node on face
-          // "Face V positions" - V parameter of node on face
-          const char* aEid_DSName = "Nodes on Edges";
-          const char* aEu_DSName  = "Edge positions";
-          const char* aFu_DSName  = "Face U positions";
-          //char* aFid_DSName = "Nodes on Faces";
-          //char* aFv_DSName  = "Face V positions";
-
-          // data to retrieve
-          int nbEids = 0, nbFids = 0;
-          int *aEids = 0, *aFids  = 0;
-          double *aEpos = 0, *aFupos = 0, *aFvpos = 0;
-
-          // open a group
-          aGroup = new HDFgroup( "Node Positions", aTopGroup ); 
-          aGroup->OpenOnDisk();
-
-          // loop on 5 data sets
-          int aNbObjects = aGroup->nInternalObjects();
-          for ( int i = 0; i < aNbObjects; i++ )
-          {
-            // identify dataset
-            char aDSName[ HDF_NAME_MAX_LEN+1 ];
-            aGroup->InternalObjectIndentify( i, aDSName );
-            // read data
-            aDataset = new HDFdataset( aDSName, aGroup );
-            aDataset->OpenOnDisk();
-            if ( aDataset->GetType() == HDF_FLOAT64 ) // Positions
-            {
-              double* pos = new double [ aDataset->GetSize() ];
-              aDataset->ReadFromDisk( pos );
-              // which one?
-              if ( strncmp( aDSName, aEu_DSName, strlen( aEu_DSName )) == 0 )
-                aEpos = pos;
-              else if ( strncmp( aDSName, aFu_DSName, strlen( aFu_DSName )) == 0 )
-                aFupos = pos;
-              else
-                aFvpos = pos;
-            }
-            else // NODE IDS
-            {
-              int aSize = aDataset->GetSize();
-
-              // for reading files, created from 18.07.2005 till 10.10.2005
-              if (aDataset->GetType() == HDF_STRING)
-                aSize /= sizeof(int);
-
-              int* ids = new int [aSize];
-              aDataset->ReadFromDisk( ids );
-              // on face or nodes?
-              if ( strncmp( aDSName, aEid_DSName, strlen( aEid_DSName )) == 0 ) {
-                aEids = ids;
-                nbEids = aSize;
-              }
-              else {
-                aFids = ids;
-                nbFids = aSize;
-              }
-            }
-            aDataset->CloseOnDisk();
-          } // loop on 5 datasets
-
-          // Set node positions on edges or faces
-          for ( int onFace = 0; onFace < 2; onFace++ )
-          {
-            int nbNodes = ( onFace ? nbFids : nbEids );
-            if ( nbNodes == 0 ) continue;
-            int* aNodeIDs = ( onFace ? aFids : aEids );
-            double* aUPos = ( onFace ? aFupos : aEpos );
-            double* aVPos = ( onFace ? aFvpos : 0 );
-            // loop on node IDs
-            for ( int iNode = 0; iNode < nbNodes; iNode++ )
-            {
-              const SMDS_MeshNode* node = mySMESHDSMesh->FindNode( aNodeIDs[ iNode ]);
-              ASSERT( node );
-              SMDS_PositionPtr aPos = node->GetPosition();
-              ASSERT( aPos )
-                if ( onFace ) {
-                  ASSERT( aPos->GetTypeOfPosition() == SMDS_TOP_FACE );
-                  SMDS_FacePosition* fPos = const_cast<SMDS_FacePosition*>
-                    ( static_cast<const SMDS_FacePosition*>( aPos.get() ));
-                  fPos->SetUParameter( aUPos[ iNode ]);
-                  fPos->SetVParameter( aVPos[ iNode ]);
-                }
-                else {
-                  ASSERT( aPos->GetTypeOfPosition() == SMDS_TOP_EDGE );
-                  SMDS_EdgePosition* fPos = const_cast<SMDS_EdgePosition*>
-                    ( static_cast<const SMDS_EdgePosition*>( aPos.get() ));
-                  fPos->SetUParameter( aUPos[ iNode ]);
-                }
-            }
-          }
-          if ( aEids ) delete [] aEids;
-          if ( aFids ) delete [] aFids;
-          if ( aEpos ) delete [] aEpos;
-          if ( aFupos ) delete [] aFupos;
-          if ( aFvpos ) delete [] aFvpos;
-
-          aGroup->CloseOnDisk();
-
-        } // if ( aTopGroup->ExistInternalObject( "Node Positions" ) )
-      } // if ( hasData )
-
-      // Recompute State (as computed sub-meshes are restored from MED)
-      if ( !aShapeObject->_is_nil() || !myNewMeshImpl->HasShapeToMesh()) {
-        MESSAGE("Compute State Engine ...");
-        TopoDS_Shape myLocShape;
-        if(myNewMeshImpl->HasShapeToMesh())
-          myLocShape = GeomObjectToShape( aShapeObject );
-        else
-          myLocShape = SMESH_Mesh::PseudoShape();
-        
-        myNewMeshImpl->GetImpl().GetSubMesh(myLocShape)->ComputeStateEngine
-          (SMESH_subMesh::SUBMESH_RESTORED);
-        MESSAGE("Compute State Engine finished");
-      }
-
-      // try to get groups
-      for ( int ii = GetNodeGroupsTag(); ii <= GetVolumeGroupsTag(); ii++ ) {
+      // try to get GROUPS
+      for ( int ii = GetNodeGroupsTag(); ii <= GetBallElementsGroupsTag(); ii++ ) {
         char name_group[ 30 ];
         if ( ii == GetNodeGroupsTag() )
           strcpy( name_group, "Groups of Nodes" );
@@ -3895,12 +4467,16 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
           strcpy( name_group, "Groups of Faces" );
         else if ( ii == GetVolumeGroupsTag() )
           strcpy( name_group, "Groups of Volumes" );
+        else if ( ii == Get0DElementsGroupsTag() )
+          strcpy( name_group, "Groups of 0D Elements" );
+        else if ( ii == GetBallElementsGroupsTag() )
+          strcpy( name_group, "Groups of Balls" );
 
         if ( aTopGroup->ExistInternalObject( name_group ) ) {
           aGroup = new HDFgroup( name_group, aTopGroup );
           aGroup->OpenOnDisk();
           // get number of groups
-          int aNbSubObjects = aGroup->nInternalObjects(); 
+          int aNbSubObjects = aGroup->nInternalObjects();
           for ( int j = 0; j < aNbSubObjects; j++ ) {
             char name_dataset[ HDF_NAME_MAX_LEN+1 ];
             aGroup->InternalObjectIndentify( j, name_dataset );
@@ -3941,11 +4517,29 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
                   }
                 }
               }
+              // Try to read a filter of SMESH_GroupOnFilter
+              SMESH::Filter_var filter;
+              SMESH_PredicatePtr predicate;
+              std::string hdfGrpName = "Filter " + SMESH_Comment(subid);
+              if ( aGroup->ExistInternalObject( hdfGrpName.c_str() ))
+              {
+                aDataset = new HDFdataset( hdfGrpName.c_str(), aGroup );
+                aDataset->OpenOnDisk();
+                size = aDataset->GetSize();
+                char* persistStr = new char[ size ];
+                aDataset->ReadFromDisk( persistStr );
+                aDataset->CloseOnDisk();
+                if ( strlen( persistStr ) > 0 ) {
+                  filter = SMESH_GroupOnFilter_i::StringToFilter( persistStr );
+                  predicate = SMESH_GroupOnFilter_i::GetPredicate( filter );
+                }
+              }
+
               // Create group servant
               SMESH::ElementType type = (SMESH::ElementType)(ii - GetNodeGroupsTag() + 1);
               SMESH::SMESH_GroupBase_var aNewGroup = SMESH::SMESH_GroupBase::_duplicate
-                ( myNewMeshImpl->createGroup( type, nameFromFile, aShape ) );
-              // Obtain a SMESHDS_Group object 
+                ( myNewMeshImpl->createGroup( type, nameFromFile, aShape, predicate ) );
+              // Obtain a SMESHDS_Group object
               if ( aNewGroup->_is_nil() )
                 continue;
 
@@ -3953,55 +4547,126 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
               int newSubId = myStudyContext->findId( iorSubString );
               myStudyContext->mapOldToNew( subid, newSubId );
 
-              SMESH_GroupBase_i* aGroupImpl =
-                dynamic_cast<SMESH_GroupBase_i*>( GetServant( aNewGroup ).in() );
+              SMESH_GroupBase_i* aGroupImpl = SMESH::DownCast< SMESH_GroupBase_i*>( aNewGroup );
               if ( !aGroupImpl )
                 continue;
 
-              SMESH_Group* aLocalGroup  = myLocMesh.GetGroup( aGroupImpl->GetLocalID() );
-              if ( !aLocalGroup )
+              if ( SMESH_GroupOnFilter_i* aFilterGroup =
+                   dynamic_cast< SMESH_GroupOnFilter_i*>( aGroupImpl ))
+                aFilterGroup->SetFilter( filter );
+
+              SMESHDS_GroupBase* aGroupBaseDS = aGroupImpl->GetGroupDS();
+              if ( !aGroupBaseDS )
                 continue;
 
-              SMESHDS_GroupBase* aGroupBaseDS = aLocalGroup->GetGroupDS();
               aGroupBaseDS->SetStoreName( name_dataset );
 
-             // ouv : NPAL12872
-             // Read color of the group
+              // ouv : NPAL12872
+              // Read color of the group
               char aGroupColorName[ 30 ];
               sprintf( aGroupColorName, "ColorGroup %d", subid);
               if ( aGroup->ExistInternalObject( aGroupColorName ) )
-             {
-               aDataset = new HDFdataset( aGroupColorName, aGroup );
-               aDataset->OpenOnDisk();
-               size = aDataset->GetSize();
-               double* anRGB = new double[ size ];
-               aDataset->ReadFromDisk( anRGB );
-               aDataset->CloseOnDisk();
-               Quantity_Color aColor( anRGB[0], anRGB[1], anRGB[2], Quantity_TOC_RGB );
-               aGroupBaseDS->SetColor( aColor );
-             }
+              {
+                aDataset = new HDFdataset( aGroupColorName, aGroup );
+                aDataset->OpenOnDisk();
+                size = aDataset->GetSize();
+                double* anRGB = new double[ size ];
+                aDataset->ReadFromDisk( anRGB );
+                aDataset->CloseOnDisk();
+                Quantity_Color aColor( anRGB[0], anRGB[1], anRGB[2], Quantity_TOC_RGB );
+                aGroupBaseDS->SetColor( aColor );
+              }
 
               // Fill group with contents from MED file
-              SMESHDS_Group* aGrp = dynamic_cast<SMESHDS_Group*>( aGroupBaseDS );
-              if ( aGrp )
-                myReader.GetGroup( aGrp );
+              // SMESHDS_Group* aGrp = dynamic_cast<SMESHDS_Group*>( aGroupBaseDS );
+              // if ( aGrp )
+              //   myReader.GetGroup( aGrp );
             }
           }
           aGroup->CloseOnDisk();
         }
+      } // reading GROUPs
+
+      // instead of reading mesh data, we read only brief information of all
+      // objects: mesh, groups, sub-meshes (issue 0021208 )
+      if ( hasData )
+      {
+        SMESH_PreMeshInfo::LoadFromFile( myNewMeshImpl, id,
+                                         meshfile.ToCString(), filename.ToCString(),
+                                         !isMultiFile );
+      }
+
+      // read Sub-Mesh ORDER if any
+      if( aTopGroup->ExistInternalObject( "Mesh Order" ) ) {
+        aDataset = new HDFdataset( "Mesh Order", aTopGroup );
+        aDataset->OpenOnDisk();
+        size = aDataset->GetSize();
+        int* smIDs = new int[ size ];
+        aDataset->ReadFromDisk( smIDs );
+        aDataset->CloseOnDisk();
+        TListOfListOfInt anOrderIds;
+        anOrderIds.push_back( TListOfInt() );
+        for ( int i = 0; i < size; i++ )
+          if ( smIDs[ i ] < 0 ) // is separator
+            anOrderIds.push_back( TListOfInt() );
+          else
+            anOrderIds.back().push_back(smIDs[ i ]);
+
+        myNewMeshImpl->GetImpl().SetMeshOrder( anOrderIds );
       }
+    } // loop on meshes
+
+    // update hyps needing full mesh data restored (issue 20918)
+    for ( hyp_data = hypDataList.begin(); hyp_data != hypDataList.end(); ++hyp_data )
+    {
+      SMESH_Hypothesis_i* hyp  = hyp_data->first;
+      hyp->UpdateAsMeshesRestored();
+    }
+
+    // notify algos on completed restoration to set sub-mesh event listeners
+    for ( meshi_group = meshGroupList.begin(); meshi_group != meshGroupList.end(); ++meshi_group )
+    {
+      SMESH_Mesh_i* myNewMeshImpl = meshi_group->first;
+      ::SMESH_Mesh& myLocMesh     = myNewMeshImpl->GetImpl();
+
+      TopoDS_Shape myLocShape;
+      if(myLocMesh.HasShapeToMesh())
+        myLocShape = myLocMesh.GetShapeToMesh();
+      else
+        myLocShape = SMESH_Mesh::PseudoShape();
+
+      myLocMesh.GetSubMesh(myLocShape)->
+        ComputeStateEngine (SMESH_subMesh::SUBMESH_RESTORED);
     }
+
     // close mesh group
     if(aTopGroup)
-      aTopGroup->CloseOnDisk();   
+      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 );
+  if ( !isMultiFile )
+  {
+    SMESH_File meshFile( meshfile.ToCString() );
+    if ( !meshFile ) // no meshfile exists
+    {
+      SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true );
+    }
+    else
+    {
+      Engines::Container_var container = GetContainerRef();
+      if ( Engines_Container_i* container_i = SMESH::DownCast<Engines_Container_i*>( container ))
+      {
+        container_i->registerTemporaryFile( filename.ToCString() );
+        container_i->registerTemporaryFile( meshfile.ToCString() );
+        container_i->registerTemporaryFile( tmpDir.ToCString() );
+      }
+    }
+  }
+  pd << ""; // prevent optimizing pd out
 
   INFOS( "SMESH_Gen_i::Load completed" );
   return true;
@@ -4016,9 +4681,9 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
 //=============================================================================
 
 bool SMESH_Gen_i::LoadASCII( SALOMEDS::SComponent_ptr theComponent,
-                            const SALOMEDS::TMPFile& theStream,
-                            const char*              theURL,
-                            bool                     isMultiFile ) {
+                             const SALOMEDS::TMPFile& theStream,
+                             const char*              theURL,
+                             bool                     isMultiFile ) {
   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::LoadASCII" );
   return Load( theComponent, theStream, theURL, isMultiFile );
 
@@ -4042,7 +4707,7 @@ bool SMESH_Gen_i::LoadASCII( SALOMEDS::SComponent_ptr theComponent,
   }
 
   SALOMEDS::TMPFile_var aRealStreamFile = new SALOMEDS::TMPFile(real_size, real_size, buffer, 1);
-  
+
   return Load( theComponent, *(aRealStreamFile._retn()), theURL, isMultiFile );
 }
 
@@ -4059,8 +4724,9 @@ void SMESH_Gen_i::Close( SALOMEDS::SComponent_ptr theComponent )
   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Close" );
 
   // set correct current study
-  if (theComponent->GetStudy()->StudyId() != GetCurrentStudyID())
-    SetCurrentStudy(theComponent->GetStudy());
+  SALOMEDS::Study_var study = theComponent->GetStudy();
+  if ( study->StudyId() != GetCurrentStudyID())
+    setCurrentStudy( study, /*IsBeingClosed=*/true );
 
   // Clear study contexts data
   int studyId = GetCurrentStudyID();
@@ -4078,7 +4744,7 @@ void SMESH_Gen_i::Close( SALOMEDS::SComponent_ptr theComponent )
 //     printf( "--------------------------- SMESH_Gen_i::Close, delete aGroup = %p \n", i_mesh->second );
 //     delete i_mesh->second;
 //   }
-  
+
 
   // delete SMESHDS_Mesh's
   // it's too long on big meshes
@@ -4086,14 +4752,18 @@ void SMESH_Gen_i::Close( SALOMEDS::SComponent_ptr theComponent )
 //     delete context->myDocument;
 //     context->myDocument = 0;
 //   }
-  
+
+  // remove the tmp files meshes are loaded from
+  SMESH_PreMeshInfo::RemoveStudyFiles_TMP_METHOD( theComponent );
+
+  myCurrentStudy = SALOMEDS::Study::_nil();
   return;
 }
 
 //=============================================================================
 /*!
  *  SMESH_Gen_i::ComponentDataType
- * 
+ *
  *  Get component data type
  */
 //=============================================================================
@@ -4104,23 +4774,23 @@ char* SMESH_Gen_i::ComponentDataType()
   return CORBA::string_dup( "SMESH" );
 }
 
-    
+
 //=============================================================================
 /*!
  *  SMESH_Gen_i::IORToLocalPersistentID
- *  
+ *
  *  Transform data from transient form to persistent
  */
 //=============================================================================
 
 char* SMESH_Gen_i::IORToLocalPersistentID( SALOMEDS::SObject_ptr /*theSObject*/,
-                                          const char*           IORString,
-                                          CORBA::Boolean        /*isMultiFile*/,
-                                          CORBA::Boolean        /*isASCII*/ )
+                                           const char*           IORString,
+                                           CORBA::Boolean        /*isMultiFile*/,
+                                           CORBA::Boolean        /*isASCII*/ )
 {
   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::IORToLocalPersistentID" );
   StudyContext* myStudyContext = GetCurrentStudyContext();
-  
+
   if ( myStudyContext && strcmp( IORString, "" ) != 0 ) {
     int anId = myStudyContext->findId( IORString );
     if ( anId ) {
@@ -4142,9 +4812,9 @@ char* SMESH_Gen_i::IORToLocalPersistentID( SALOMEDS::SObject_ptr /*theSObject*/,
 //=============================================================================
 
 char* SMESH_Gen_i::LocalPersistentIDToIOR( SALOMEDS::SObject_ptr /*theSObject*/,
-                                          const char*           aLocalPersistentID,
-                                          CORBA::Boolean        /*isMultiFile*/,
-                                          CORBA::Boolean        /*isASCII*/ )
+                                           const char*           aLocalPersistentID,
+                                           CORBA::Boolean        /*isMultiFile*/,
+                                           CORBA::Boolean        /*isASCII*/ )
 {
   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::LocalPersistentIDToIOR(): id = " << aLocalPersistentID );
   StudyContext* myStudyContext = GetCurrentStudyContext();
@@ -4158,7 +4828,7 @@ char* SMESH_Gen_i::LocalPersistentIDToIOR( SALOMEDS::SObject_ptr /*theSObject*/,
 
 //=======================================================================
 //function : RegisterObject
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 int SMESH_Gen_i::RegisterObject(CORBA::Object_ptr theObject)
@@ -4208,21 +4878,26 @@ void SMESH_Gen_i::SetName(const char* theIOR,
   }
 }
 
+int SMESH_Gen_i::GetCurrentStudyID()
+{
+  return myCurrentStudy->_is_nil() || myCurrentStudy->_non_existent() ? -1 : myCurrentStudy->StudyId();
+}
+
 //=============================================================================
-/*! 
+/*!
  *  SMESHEngine_factory
  *
- *  C factory, accessible with dlsym, after dlopen  
+ *  C factory, accessible with dlsym, after dlopen
  */
 //=============================================================================
 
 extern "C"
 { SMESH_I_EXPORT
   PortableServer::ObjectId* SMESHEngine_factory( CORBA::ORB_ptr            orb,
-                                                PortableServer::POA_ptr   poa, 
-                                                PortableServer::ObjectId* contId,
-                                                const char*               instanceName, 
-                                                const char*               interfaceName )
+                                                 PortableServer::POA_ptr   poa,
+                                                 PortableServer::ObjectId* contId,
+                                                 const char*               instanceName,
+                                                 const char*               interfaceName )
   {
     if(MYDEBUG) MESSAGE( "PortableServer::ObjectId* SMESHEngine_factory()" );
     if(MYDEBUG) SCRUTE(interfaceName);
index 836e585c70004c0409cf23974689043074ae50d4..a72c466f31c9f97daff0038896330d1ced30e95f 100644 (file)
@@ -1,29 +1,28 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : SMESH_Gen_i.hxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//
+
 #ifndef _SMESH_GEN_I_HXX_
 #define _SMESH_GEN_I_HXX_
 
@@ -64,8 +63,8 @@ public:
   // constructor
   StudyContext() {}
   // destructor
-  ~StudyContext() 
-  { 
+  ~StudyContext()
+  {
     mapIdToIOR.clear();
     mapIdToId.clear();
   }
@@ -113,7 +112,7 @@ public:
     }
     return 0;
   }
-    
+
 private:
   // get next free object identifier
   int getNextId()
@@ -133,7 +132,7 @@ private:
 // ==========================================================
 class SMESH_I_EXPORT SMESH_Gen_i:
   public virtual POA_SMESH::SMESH_Gen,
-  public virtual Engines_Component_i 
+  public virtual Engines_Component_i
 {
 public:
   // Get last created instance of the class
@@ -159,14 +158,14 @@ public:
   GEOM::GEOM_Object_ptr ShapeToGeomObject (const TopoDS_Shape& theShape );
   // Get TopoDS_Shape correspoding to GEOM_Object
   TopoDS_Shape GeomObjectToShape(GEOM::GEOM_Object_ptr theGeomObject);
-  
+
   // Default constructor
   SMESH_Gen_i();
   // Standard constructor
   SMESH_Gen_i( CORBA::ORB_ptr            orb,
                PortableServer::POA_ptr   poa,
-               PortableServer::ObjectId* contId, 
-               const char*               instanceName, 
+               PortableServer::ObjectId* contId,
+               const char*               instanceName,
                const char*               interfaceName );
   // Destructor
   virtual ~SMESH_Gen_i();
@@ -176,7 +175,7 @@ public:
   // *****************************************
   // Set a new Mesh object name
   void SetName(const char* theIOR,
-              const char* theName);
+               const char* theName);
 
   //GEOM::GEOM_Gen_ptr SetGeomEngine( const char* containerLoc );
   void SetGeomEngine( GEOM::GEOM_Gen_ptr geomcompo );
@@ -195,7 +194,7 @@ public:
   SMESH::SMESH_Hypothesis_ptr CreateHypothesis (const char* theHypType,
                                                 const char* theLibName)
     throw ( SALOME::SALOME_Exception );
-  
+
   // Return hypothesis of given type holding parameter values of the existing mesh
   SMESH::SMESH_Hypothesis_ptr GetHypothesisParameterValues (const char*           theHypType,
                                                             const char*           theLibName,
@@ -203,7 +202,9 @@ public:
                                                             GEOM::GEOM_Object_ptr theGeom,
                                                             CORBA::Boolean        byMesh)
     throw ( SALOME::SALOME_Exception );
-  
+
+  // Preferences
+  // ------------
   /*!
    * Sets number of segments per diagonal of boundary box of geometry by which
    * default segment length of appropriate 1D hypotheses is defined
@@ -214,6 +215,21 @@ public:
    */
   void SetDefaultNbSegments(CORBA::Long theNbSegments) throw ( SALOME::SALOME_Exception );
 
+  /*!
+    Set an option value
+  */
+  virtual void  SetOption(const char*, const char*);
+  /*!
+    Return an option value
+  */
+  virtual char* GetOption(const char*);
+
+  /*!
+   * To load full mesh data from study at hyp modification or not
+   */
+  bool ToForgetMeshDataOnHypModif() const { return myToForgetMeshDataOnHypModif; }
+
+
   // Create empty mesh on a shape
   SMESH::SMESH_Mesh_ptr CreateMesh( GEOM::GEOM_Object_ptr theShapeObject )
     throw ( SALOME::SALOME_Exception );
@@ -222,7 +238,7 @@ public:
   SMESH::SMESH_Mesh_ptr CreateEmptyMesh()
     throw ( SALOME::SALOME_Exception );
 
-  //  Create mesh(es) and import data from UNV file
+  //  Create mesh(es) and import data from UNV fileter
   SMESH::SMESH_Mesh_ptr CreateMeshesFromUNV( const char* theFileName )
     throw ( SALOME::SALOME_Exception );
 
@@ -231,14 +247,35 @@ public:
                                           SMESH::DriverMED_ReadStatus& theStatus )
     throw ( SALOME::SALOME_Exception );
 
+  //  Create mesh(es) and import data from MED file
+  SMESH::mesh_array* CreateMeshesFromSAUV( const char* theFileName,
+                                           SMESH::DriverMED_ReadStatus& theStatus )
+    throw ( SALOME::SALOME_Exception );
+
   //  Create mesh(es) and import data from STL file
   SMESH::SMESH_Mesh_ptr CreateMeshesFromSTL( const char* theFileName )
     throw ( SALOME::SALOME_Exception );
 
+  //  Create mesh(es) and import data from CGNS file
+  SMESH::mesh_array* CreateMeshesFromCGNS( const char* theFileName,
+                                           SMESH::DriverMED_ReadStatus& theStatus )
+    throw ( SALOME::SALOME_Exception );
+
+  // Copy a part of mesh
+  SMESH::SMESH_Mesh_ptr CopyMesh(SMESH::SMESH_IDSource_ptr meshPart,
+                                 const char*               meshName,
+                                 CORBA::Boolean            toCopyGroups,
+                                 CORBA::Boolean            toKeepIDs);
+
   // Compute mesh on a shape
   CORBA::Boolean Compute( SMESH::SMESH_Mesh_ptr theMesh,
                           GEOM::GEOM_Object_ptr theShapeObject )
     throw ( SALOME::SALOME_Exception );
+
+  // Cancel Compute mesh on a shape
+  void CancelCompute( SMESH::SMESH_Mesh_ptr theMesh,
+                      GEOM::GEOM_Object_ptr theShapeObject );
+
   /*!
    * \brief Return errors of mesh computation
    */
@@ -246,24 +283,33 @@ public:
                                                GEOM::GEOM_Object_ptr  theShapeObject )
     throw ( SALOME::SALOME_Exception );
 
+  /*!
+   * Evaluate mesh on a shape and
+   *  returns statistic of mesh elements
+   * Result array of number enityties
+   */
+  SMESH::long_array* Evaluate(SMESH::SMESH_Mesh_ptr theMesh,
+                              GEOM::GEOM_Object_ptr theShapeObject)
+    throw ( SALOME::SALOME_Exception );
+
   // Returns true if mesh contains enough data to be computed
   CORBA::Boolean IsReadyToCompute( SMESH::SMESH_Mesh_ptr theMesh,
                                    GEOM::GEOM_Object_ptr theShapeObject )
     throw ( SALOME::SALOME_Exception );
-  
+
   /*!
    * Calculate Mesh as preview till indicated dimension on shape
    * First, verify list of hypothesis associated with the subShape.
    * Return mesh preview structure
    */
   SMESH::MeshPreviewStruct* Precompute( SMESH::SMESH_Mesh_ptr theMesh,
-                                       GEOM::GEOM_Object_ptr theSubObject,
-                                       SMESH::Dimension      theDimension,
-                                       SMESH::long_array&    theShapesId )
+                                        GEOM::GEOM_Object_ptr theSubObject,
+                                        SMESH::Dimension      theDimension,
+                                        SMESH::long_array&    theShapesId )
     throw ( SALOME::SALOME_Exception );
 
   // Returns errors of hypotheses definintion
-  SMESH::algo_error_array* GetAlgoState( SMESH::SMESH_Mesh_ptr theMesh, 
+  SMESH::algo_error_array* GetAlgoState( SMESH::SMESH_Mesh_ptr theMesh,
                                          GEOM::GEOM_Object_ptr theSubObject )
       throw ( SALOME::SALOME_Exception );
 
@@ -285,54 +331,61 @@ public:
 
   // Return geometrical object the given element is built on. Don't publish it in study.
   GEOM::GEOM_Object_ptr FindGeometryByMeshElement( SMESH::SMESH_Mesh_ptr  theMesh,
-                                                  CORBA::Long            theElementID)
+                                                   CORBA::Long            theElementID)
     throw ( SALOME::SALOME_Exception );
 
   // Concatenate the given meshes into one mesh
-  SMESH::SMESH_Mesh_ptr ConcatenateCommon(const SMESH::mesh_array& theMeshesArray, 
-                                         CORBA::Boolean           theUniteIdenticalGroups, 
-                                         CORBA::Boolean           theMergeNodesAndElements, 
-                                         CORBA::Double            theMergeTolerance,
-                                         CORBA::Boolean           theCommonGroups)
+  SMESH::SMESH_Mesh_ptr ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
+                                          CORBA::Boolean           theUniteIdenticalGroups,
+                                          CORBA::Boolean           theMergeNodesAndElements,
+                                          CORBA::Double            theMergeTolerance,
+                                          CORBA::Boolean           theCommonGroups)
     throw ( SALOME::SALOME_Exception );
 
   // Concatenate the given meshes into one mesh
-  SMESH::SMESH_Mesh_ptr Concatenate(const SMESH::mesh_array& theMeshesArray, 
-                                   CORBA::Boolean           theUniteIdenticalGroups, 
-                                   CORBA::Boolean           theMergeNodesAndElements, 
-                                   CORBA::Double            theMergeTolerance)
+  SMESH::SMESH_Mesh_ptr Concatenate(const SMESH::mesh_array& theMeshesArray,
+                                    CORBA::Boolean           theUniteIdenticalGroups,
+                                    CORBA::Boolean           theMergeNodesAndElements,
+                                    CORBA::Double            theMergeTolerance)
     throw ( SALOME::SALOME_Exception );
 
   // Concatenate the given meshes into one mesh
   // Create the groups of all elements from initial meshes
-  SMESH::SMESH_Mesh_ptr ConcatenateWithGroups(const SMESH::mesh_array& theMeshesArray, 
-                                             CORBA::Boolean           theUniteIdenticalGroups, 
-                                             CORBA::Boolean           theMergeNodesAndElements, 
-                                             CORBA::Double            theMergeTolerance)
+  SMESH::SMESH_Mesh_ptr ConcatenateWithGroups(const SMESH::mesh_array& theMeshesArray,
+                                              CORBA::Boolean           theUniteIdenticalGroups,
+                                              CORBA::Boolean           theMergeNodesAndElements,
+                                              CORBA::Double            theMergeTolerance)
     throw ( SALOME::SALOME_Exception );
 
+  // Get MED version of the file by its name
+  CORBA::Boolean GetMEDVersion(const char* theFileName,
+                               SMESH::MED_VERSION& theVersion);
+
+  // Get names of meshes defined in file with the specified name
+  SMESH::string_array* GetMeshNames(const char* theFileName);
+
   // ****************************************************
   // Interface inherited methods (from SALOMEDS::Driver)
   // ****************************************************
 
   // Save SMESH data
   SALOMEDS::TMPFile* Save( SALOMEDS::SComponent_ptr theComponent,
-                        const char*              theURL,
-                        bool                     isMultiFile );
+                         const char*              theURL,
+                         bool                     isMultiFile );
   // Load SMESH data
   bool Load( SALOMEDS::SComponent_ptr theComponent,
-            const SALOMEDS::TMPFile& theStream,
-            const char*              theURL,
-            bool                     isMultiFile );
+             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 );
+                                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 );
+                  const SALOMEDS::TMPFile& theStream,
+                  const char*              theURL,
+                  bool                     isMultiFile );
 
   // Create filter manager
   SMESH::FilterManager_ptr CreateFilterManager();
@@ -340,30 +393,33 @@ public:
   // Return a pattern mesher
   SMESH::SMESH_Pattern_ptr GetPattern();
 
+  // Create measurement instance
+  SMESH::Measurements_ptr  CreateMeasurements();
+
   // Clears study-connected data when it is closed
   void Close( SALOMEDS::SComponent_ptr theComponent );
-  
+
   // Get component data type
   char* ComponentDataType();
-    
+
   // Transform data from transient form to persistent
   char* IORToLocalPersistentID( SALOMEDS::SObject_ptr theSObject,
-                               const char*           IORString,
-                               CORBA::Boolean        isMultiFile,
-                               CORBA::Boolean        isASCII );
+                                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 );
+                                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 ) 
+                                        SALOMEDS::SObject_ptr theSObject,
+                                        CORBA::Object_ptr     theObject,
+                                        const char*           theName )
     throw ( SALOME::SALOME_Exception );
 
   // Copy-paste methods - returns true if object can be copied to the clipboard
@@ -374,8 +430,8 @@ public:
   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 ) {
+                                   CORBA::Long              theObjectID,
+                                   SALOMEDS::SObject_ptr    theObject ) {
     SALOMEDS::SObject_var aResultSO;
     return aResultSO._retn();
   }
@@ -384,9 +440,10 @@ public:
   // Dump python
   // ============
 
-  virtual Engines::TMPFile* DumpPython(CORBA::Object_ptr theStudy, 
-                                      CORBA::Boolean isPublished, 
-                                      CORBA::Boolean& isValidScript);
+  virtual Engines::TMPFile* DumpPython(CORBA::Object_ptr theStudy,
+                                       CORBA::Boolean isPublished,
+                                       CORBA::Boolean isMultiFile,
+                                       CORBA::Boolean& isValidScript);
 
   void AddToPythonScript (int theStudyID, const TCollection_AsciiString& theString);
 
@@ -394,10 +451,12 @@ public:
 
   void SavePython (SALOMEDS::Study_ptr theStudy);
 
-  TCollection_AsciiString DumpPython_impl (SALOMEDS::Study_ptr theStudy, 
+  TCollection_AsciiString DumpPython_impl (SALOMEDS::Study_ptr theStudy,
                                            Resource_DataMapOfAsciiStringAsciiString& theObjectNames,
                                            Resource_DataMapOfAsciiStringAsciiString& theNames,
-                                           bool isPublished, 
+                                           bool isPublished,
+                                           bool isMultiFile,
+                                           bool isHistoricalDump,
                                            bool& aValidScript,
                                            const TCollection_AsciiString& theSavedTrace);
 
@@ -413,7 +472,7 @@ public:
   // Get shape reader
   GEOM_Client* GetShapeReader();
 
-  // Tags definition 
+  // Tags definition
   static long GetHypothesisRootTag();
   static long GetAlgorithmsRootTag();
   static long GetRefOnShapeTag();
@@ -430,6 +489,8 @@ public:
   static long GetEdgeGroupsTag();
   static long GetFaceGroupsTag();
   static long GetVolumeGroupsTag();
+  static long Get0DElementsGroupsTag();
+  static long GetBallElementsGroupsTag();
 
   // publishing methods
   SALOMEDS::SComponent_ptr PublishComponent(SALOMEDS::Study_ptr theStudy);
@@ -443,7 +504,7 @@ public:
                                         SMESH::SMESH_Mesh_ptr    theMesh,
                                         SMESH::SMESH_subMesh_ptr theSubMesh,
                                         GEOM::GEOM_Object_ptr    theShapeObject,
-                                       const char*              theName = 0);
+                                        const char*              theName = 0);
   SALOMEDS::SObject_ptr PublishGroup (SALOMEDS::Study_ptr    theStudy,
                                       SMESH::SMESH_Mesh_ptr  theMesh,
                                       SMESH::SMESH_GroupBase_ptr theGroup,
@@ -464,6 +525,9 @@ public:
                       const char*           theName,
                       const char*           theDefaultName = 0);
 
+  static void SetPixMap(SALOMEDS::SObject_ptr theSObject,
+                        const char*           thePixMap);
+
   //  Get study context
   StudyContext* GetCurrentStudyContext();
 
@@ -474,7 +538,7 @@ public:
   CORBA::Long GetObjectId(CORBA::Object_ptr theObject);
 
   // Return an object that previously had an oldID
-  template<class TInterface> 
+  template<class TInterface>
   typename TInterface::_var_type GetObjectByOldId( const int oldID )
   {
     if ( StudyContext* myStudyContext = GetCurrentStudyContext() ) {
@@ -486,31 +550,38 @@ public:
   }
 
   // Get current study ID
-  int GetCurrentStudyID()
-  { return myCurrentStudy->_is_nil() ? -1 : myCurrentStudy->StudyId(); }
+  int GetCurrentStudyID();
 
   /*!
    * \brief Find SObject for an algo
    */
   SALOMEDS::SObject_ptr GetAlgoSO(const ::SMESH_Algo* algo);
 
-  void UpdateParameters(CORBA::Object_ptr theObject, const char* theParameters);
+  void UpdateParameters(/*CORBA::Object_ptr theObject,*/ const char* theParameters);
   char* GetParameters(CORBA::Object_ptr theObject);
   char* ParseParameters(const char* theParameters);
-  
+  const std::vector< std::string >& GetLastParameters() const { return myLastParameters; }
+
 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 );
-  
+
+  SMESH::mesh_array* CreateMeshesFromMEDorSAUV( const char* theFileName,
+                                                SMESH::DriverMED_ReadStatus& theStatus,
+                                                const char* theCommandNameForPython,
+                                                const char* theFileNameForPython);
+
+  void setCurrentStudy( SALOMEDS::Study_ptr theStudy,
+                        bool                theStudyIsBeingClosed=false);
+
 private:
   static GEOM::GEOM_Gen_var      myGeomGen;
   static CORBA::ORB_var          myOrb;         // ORB reference
@@ -518,7 +589,7 @@ private:
   static SALOME_NamingService*   myNS;          // Naming Service
   static SALOME_LifeCycleCORBA*  myLCC;         // Life Cycle CORBA
   static SMESH_Gen_i*            mySMESHGen;    // Point to last created instance of the class
-  ::SMESH_Gen               myGen;              // SMESH_Gen local implementation
+  ::SMESH_Gen                    myGen;         // SMESH_Gen local implementation
 
   // hypotheses managing
   map<string, GenericHypothesisCreator_i*> myHypCreatorMap;
@@ -529,8 +600,13 @@ private:
   SALOMEDS::Study_var       myCurrentStudy;     // Current study
   CORBA::Boolean            myIsEmbeddedMode;   // Current mode
 
+  // To load full mesh data from study at hyp modification or not
+  bool myToForgetMeshDataOnHypModif;
+
   // Dump Python: trace of API methods calls
   std::map < int, Handle(TColStd_HSequenceOfAsciiString) > myPythonScripts;
+  bool                                                     myIsHistoricalPythonDump;
+  std::vector< std::string >                               myLastParameters;
 };
 
 
index b0701ea596b22275ba4b38fcc0def7b32aea948f..1638083b5869b129580b36225e97542b924cff39 100644 (file)
@@ -1,31 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
-//
-//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
-// File      : SMESH_Gen_i_1.cxx
-// Created   : Thu Oct 21 17:24:06 2004
-// Author    : Edward AGAPOV (eap)
-// Module    : SMESH
-// $Header: 
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+//  File      : SMESH_Gen_i_1.cxx
+//  Created   : Thu Oct 21 17:24:06 2004
+//  Author    : Edward AGAPOV (eap)
+//  Module    : SMESH
+
 #include "SMESH_Gen_i.hxx"
 
 #include "SMESH_Mesh_i.hxx"
 #include "Utils_ExceptHandlers.hxx"
 
 #include <TCollection_AsciiString.hxx>
+#include <TopoDS_Solid.hxx>
 
 #ifdef _DEBUG_
 static int MYDEBUG = 0;
-static int VARIABLE_DEBUG = 0;
+//static int VARIABLE_DEBUG = 0;
 #else
 static int MYDEBUG = 0;
-static int VARIABLE_DEBUG = 0;
+//static int VARIABLE_DEBUG = 0;
 #endif
 
 //=============================================================================
@@ -137,6 +136,16 @@ long SMESH_Gen_i::GetVolumeGroupsTag()
   return SMESH::Tag_VolumeGroups;
 }
 
+long SMESH_Gen_i::Get0DElementsGroupsTag()
+{
+  return SMESH::Tag_0DElementsGroups;
+}
+
+long SMESH_Gen_i::GetBallElementsGroupsTag()
+{
+  return SMESH::Tag_BallElementsGroups;
+}
+
 //=============================================================================
 /*!
  *  SMESH_Gen_i::CanPublishInStudy
@@ -210,8 +219,10 @@ GEOM::GEOM_Object_ptr SMESH_Gen_i::ShapeToGeomObject (const TopoDS_Shape& theSha
     GEOM_Client* aClient = GetShapeReader();
     TCollection_AsciiString IOR;
     if ( aClient && aClient->Find( theShape, IOR ))
-      aShapeObj = GEOM::GEOM_Object::_narrow
-        ( GetORB()->string_to_object( IOR.ToCString() ) );
+    {
+      CORBA::Object_var obj = GetORB()->string_to_object( IOR.ToCString() );
+      aShapeObj = GEOM::GEOM_Object::_narrow ( obj );
+    }
   }
   return aShapeObj._retn();
 }
@@ -262,7 +273,8 @@ static SALOMEDS::SObject_ptr publish(SALOMEDS::Study_ptr   theStudy,
   }
   if ( thePixMap ) {
     anAttr  = aStudyBuilder->FindOrCreateAttribute( SO, "AttributePixMap" );
-    SALOMEDS::AttributePixMap::_narrow( anAttr )->SetPixMap( thePixMap );
+    SALOMEDS::AttributePixMap_var pm = SALOMEDS::AttributePixMap::_narrow( anAttr );
+    pm->SetPixMap( thePixMap );
   }
   if ( !theSelectable ) {
     anAttr   = aStudyBuilder->FindOrCreateAttribute( SO, "AttributeSelectable" );
@@ -298,6 +310,25 @@ void SMESH_Gen_i::SetName(SALOMEDS::SObject_ptr theSObject,
   }
 }
 
+//=======================================================================
+//function : SetPixMap
+//purpose  : 
+//=======================================================================
+
+void SMESH_Gen_i::SetPixMap(SALOMEDS::SObject_ptr theSObject,
+                            const char*           thePixMap)
+{
+  if ( !theSObject->_is_nil() && thePixMap && strlen( thePixMap ))
+  {
+    SALOMEDS::Study_var aStudy = theSObject->GetStudy();
+    SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
+    SALOMEDS::GenericAttribute_var anAttr =
+      aStudyBuilder->FindOrCreateAttribute( theSObject, "AttributePixMap" );
+    SALOMEDS::AttributePixMap_var aPMAttr = SALOMEDS::AttributePixMap::_narrow( anAttr );
+    aPMAttr->SetPixMap( thePixMap );
+  }
+}
+
 //=======================================================================
 //function : addReference
 //purpose  : 
@@ -349,9 +380,9 @@ static void addReference (SALOMEDS::Study_ptr   theStudy,
 //=============================================================================
 
 SALOMEDS::SObject_ptr SMESH_Gen_i::PublishInStudy(SALOMEDS::Study_ptr   theStudy,
-                                                 SALOMEDS::SObject_ptr theSObject,
-                                                 CORBA::Object_ptr     theIOR,
-                                                 const char*           theName)
+                                                  SALOMEDS::SObject_ptr theSObject,
+                                                  CORBA::Object_ptr     theIOR,
+                                                  const char*           theName)
      throw (SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
@@ -446,9 +477,9 @@ static long findMaxChildTag( SALOMEDS::SObject_ptr theSObject )
     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;
+        long nTag = anIter->Value()->Tag();
+        if ( nTag > aTag )
+          aTag = nTag;
       }
     }
   }
@@ -499,13 +530,12 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishMesh (SALOMEDS::Study_ptr   theStudy,
 
     // Publish global hypotheses
 
-    SMESH::ListOfHypothesis * hypList = theMesh->GetHypothesisList( aShapeObject );
-    if ( hypList )
-      for ( int i = 0; i < hypList->length(); i++ ) {
-        SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( (*hypList)[ i ]);
-        PublishHypothesis( theStudy, aHyp );
-        AddHypothesisToShape( theStudy, theMesh, aShapeObject, aHyp );
-      }
+    SMESH::ListOfHypothesis_var hypList = theMesh->GetHypothesisList( aShapeObject );
+    for ( int i = 0; i < hypList->length(); i++ ) {
+      SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( hypList[ i ]);
+      PublishHypothesis( theStudy, aHyp );
+      AddHypothesisToShape( theStudy, theMesh, aShapeObject, aHyp );
+    }
   }
 
   // Publish submeshes
@@ -569,7 +599,7 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishSubMesh (SALOMEDS::Study_ptr      theS
     }
     // Find submesh sub-tree tag
     long aRootTag;
-    char* aRootName = "";
+    const char* aRootName = "";
     switch ( theShapeObject->GetShapeType() ) {
     case GEOM::VERTEX:
       aRootTag  = GetSubMeshOnVertexTag();
@@ -607,7 +637,10 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishSubMesh (SALOMEDS::Study_ptr      theS
     SetName( aRootSO, aRootName );
 
     // Add new submesh to corresponding sub-tree
-    aSubMeshSO = publish (theStudy, theSubMesh, aRootSO, 0, "ICON_SMESH_TREE_MESH_WARN");
+    SMESH::array_of_ElementType_var elemTypes = theSubMesh->GetTypes();
+    const int isEmpty = ( elemTypes->length() == 0 );
+    const char* pm[2] = { "ICON_SMESH_TREE_MESH", "ICON_SMESH_TREE_MESH_WARN" };
+    aSubMeshSO = publish (theStudy, theSubMesh, aRootSO, 0, pm[isEmpty] );
     if ( aSubMeshSO->_is_nil() )
       return aSubMeshSO._retn();
   }
@@ -655,21 +688,36 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::PublishGroup (SALOMEDS::Study_ptr    theStudy
     }
     int aType = (int)theGroup->GetType();
     const char* aRootNames[] = {
-      "Compound Groups", "Groups of Nodes",
-      "Groups of Edges", "Groups of Faces", "Groups of Volumes" };
+      "Compound Groups", "Groups of Nodes", "Groups of Edges",
+      "Groups of Faces", "Groups of Volumes", "Groups of 0D Elements",
+      "Groups of Balls" };
 
     // Currently, groups with heterogenous content are not supported
-    if ( aType != SMESH::ALL ) {
+    if ( aType != SMESH::ALL )
+    {
       long aRootTag = GetNodeGroupsTag() + aType - 1;
 
       // Find or create groups root
       SALOMEDS::SObject_var aRootSO = publish (theStudy, CORBA::Object::_nil(),
                                                aMeshSO, aRootTag, 0, false );
-      if ( aType < 5 )
+      if ( aType < sizeof(aRootNames)/sizeof(char*) )
         SetName( aRootSO, aRootNames[aType] );
 
       // Add new group to corresponding sub-tree
-      aGroupSO = publish (theStudy, theGroup, aRootSO, 0, "ICON_SMESH_TREE_GROUP" );
+      SMESH::array_of_ElementType_var elemTypes = theGroup->GetTypes();
+      int isEmpty = ( elemTypes->length() == 0 );
+      std::string pm[2] = { "ICON_SMESH_TREE_GROUP", "ICON_SMESH_TREE_MESH_WARN" };
+      if ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ))
+      {
+        pm[0] = "ICON_SMESH_TREE_GROUP_ON_FILTER";
+      }
+      else if ( SMESH::DownCast< SMESH_Group_i* > ( theGroup ))
+      {
+        SMESH::array_of_ElementType_var allElemTypes = theMesh->GetTypes();
+        for ( size_t i =0; i < allElemTypes->length() && isEmpty; ++i )
+          isEmpty = ( allElemTypes[i] != theGroup->GetType() );
+      }
+      aGroupSO = publish (theStudy, theGroup, aRootSO, 0, pm[isEmpty].c_str() );
     }
     if ( aGroupSO->_is_nil() )
       return aGroupSO._retn();
@@ -869,71 +917,146 @@ bool SMESH_Gen_i::RemoveHypothesisFromShape(SALOMEDS::Study_ptr         theStudy
 //function : UpdateParameters
 //purpose  : 
 //=======================================================================
-void SMESH_Gen_i::UpdateParameters(CORBA::Object_ptr theObject, const char* theParameters)
+void SMESH_Gen_i::UpdateParameters(/*CORBA::Object_ptr theObject,*/ const char* theParameters)
 {
-
-  if(VARIABLE_DEBUG)
-    cout<<"UpdateParameters : "<<theParameters<<endl;
   SALOMEDS::Study_ptr aStudy = GetCurrentStudy();
-  if(aStudy->_is_nil() || CORBA::is_nil(theObject)) 
-    return;
-
-  SALOMEDS::SObject_var aSObj =  ObjectToSObject(aStudy,theObject);
-  if(aSObj->_is_nil())  
+  if ( aStudy->_is_nil() )
     return;
-  
-  SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
-  
-  SALOMEDS::GenericAttribute_var aFindAttr;
-  bool hasAttr = aSObj->FindAttribute(aFindAttr, "AttributeString");
-  if(VARIABLE_DEBUG)
-    cout<<"Find Attribute "<<hasAttr<<endl;
-
-  SALOMEDS::GenericAttribute_var anAttr;
-  anAttr = aStudyBuilder->FindOrCreateAttribute( aSObj, "AttributeString");
-  SALOMEDS::AttributeString_var aStringAttr = SALOMEDS::AttributeString::_narrow(anAttr);
-
-  TCollection_AsciiString aNewParams;
-  TCollection_AsciiString aOldParameters(aStringAttr->Value());
-  TCollection_AsciiString anInputParams(ParseParameters(theParameters));
-  
-  if(!hasAttr)
-    aNewParams = anInputParams;
-  else 
-    aNewParams = aOldParameters+"|"+anInputParams;
-
-  if(VARIABLE_DEBUG)
+  myLastParameters.clear();
+  int pos = 0, prevPos = 0, len = strlen( theParameters );
+  if ( len == 0 ) return;
+  while ( pos <= len )
+  {
+    if ( pos == len || theParameters[pos] == ':' )
     {
-      cout<<"Input Parameters : "<<anInputParams<<endl;
-      cout<<"Old Parameters : "<<aOldParameters<<endl;
-      cout<<"New Parameters : "<<aNewParams<<endl;
+      if ( prevPos < pos )
+      {
+        string val(theParameters + prevPos, theParameters + pos );
+        if ( !aStudy->IsVariable( val.c_str() ))
+          val.clear();
+        myLastParameters.push_back( val );
+      }
+      else
+      {
+        myLastParameters.push_back("");
+      }
+      prevPos = pos+1;
     }
-  
-  
-  aStringAttr->SetValue( aNewParams.ToCString() );
+    ++pos;
+  }
+  return;
+
+  // OLD VARIANT
+
+  // if(VARIABLE_DEBUG)
+  //   cout<<"UpdateParameters : "<<theParameters<<endl;
+  // //SALOMEDS::Study_ptr aStudy = GetCurrentStudy();
+  // if(aStudy->_is_nil() || CORBA::is_nil(theObject)) 
+  //   return;
+
+  // SALOMEDS::SObject_var aSObj =  ObjectToSObject(aStudy,theObject);
+  // if(aSObj->_is_nil())  
+  //   return;
+
+  // SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
+
+  // SALOMEDS::GenericAttribute_var aFindAttr;
+  // bool hasAttr = aSObj->FindAttribute(aFindAttr, "AttributeString");
+  // if(VARIABLE_DEBUG)
+  //   cout<<"Find Attribute "<<hasAttr<<endl;
+
+  // SALOMEDS::GenericAttribute_var anAttr;
+  // anAttr = aStudyBuilder->FindOrCreateAttribute( aSObj, "AttributeString");
+  // SALOMEDS::AttributeString_var aStringAttr = SALOMEDS::AttributeString::_narrow(anAttr);
+
+  // CORBA::String_var oldparVar = aStringAttr->Value();
+  // CORBA::String_var inpparVar = ParseParameters(theParameters);
+  // TCollection_AsciiString aNewParams;
+  // TCollection_AsciiString aOldParameters(oldparVar.inout());
+  // TCollection_AsciiString anInputParams(inpparVar.inout());
+  // if(!hasAttr)
+  //   aNewParams = anInputParams;
+  // else 
+  //   {
+  //     int pos = aOldParameters.SearchFromEnd("|");
+  //     if(pos==-1) pos = 0;
+  //     TCollection_AsciiString previousParamFull(aOldParameters.Split(pos));
+  //     TCollection_AsciiString previousParam(previousParamFull);
+  //     TCollection_AsciiString theRepet("1");
+  //     pos = previousParam.SearchFromEnd(";*=");
+  //     if(pos >= 0)
+  //       {
+  //         theRepet = previousParam.Split(pos+2);
+  //         pos = pos-1;
+  //         if(pos==-1) pos = 0;
+  //         previousParam.Split(pos);
+  //       }
+  //     if(previousParam == anInputParams)
+  //       {
+  //         theRepet = theRepet.IntegerValue()+1;
+  //         aNewParams = aOldParameters + previousParam + ";*=" + theRepet;
+  //       }
+  //     else
+  //       {
+  //         aNewParams = aOldParameters + previousParamFull + "|" + anInputParams;
+  //       }
+  //   }
+
+  // if(VARIABLE_DEBUG)
+  // {
+  //   cout<<"Input Parameters : "<<anInputParams<<endl;
+  //   cout<<"Old Parameters : "<<aOldParameters<<endl;
+  //   cout<<"New Parameters : "<<aNewParams<<endl;
+  // }
+
+  // aStringAttr->SetValue( aNewParams.ToCString() );
 }
 
 //=======================================================================
 //function : ParseParameters
-//purpose  : 
+//purpose  : Replace variables by their values
 //=======================================================================
 char* SMESH_Gen_i::ParseParameters(const char* theParameters)
 {
-  const char* aParameters = CORBA::string_dup(theParameters);
+  //const char* aParameters = theParameters;
+//   const char* aParameters = CORBA::string_dup(theParameters);
   TCollection_AsciiString anInputParams;
-  SALOMEDS::Study_ptr aStudy = GetCurrentStudy();
+  SALOMEDS::Study_var aStudy = GetCurrentStudy();
   if( !aStudy->_is_nil() ) {
-    SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
-    for(int j=0;j<aSections->length();j++) {
-      SALOMEDS::ListOfStrings aVars= aSections[j];
-      for(int i=0;i<aVars.length();i++ ) {
-        anInputParams += aStudy->IsVariable(aVars[i].in()) ? 
-          TCollection_AsciiString(aVars[i].in()) : TCollection_AsciiString("");
-        if(i != aVars.length()-1)
-          anInputParams+=":";
+//     SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(theParameters);
+//     for(int j=0;j<aSections->length();j++) {
+//       SALOMEDS::ListOfStrings aVars= aSections[j];
+//       for(int i=0;i<aVars.length();i++ ) {
+//         anInputParams += aStudy->IsVariable(aVars[i].in()) ? 
+//           TCollection_AsciiString(aVars[i].in()) : TCollection_AsciiString("");
+//         if(i != aVars.length()-1)
+//           anInputParams+=":";
+//       }
+//       if(j!=aSections->length()-1)
+//         anInputParams+="|";
+//     }
+    TCollection_AsciiString paramStr( theParameters );
+    static TCollection_AsciiString separators(":|");
+    int beg = 0, end;
+    char sep, *pParams = (char*)paramStr.ToCString();
+    while ( beg < paramStr.Length() )
+    {
+      end = beg-1;
+      while ( ++end < paramStr.Length() )
+        if ( pParams[end] == ':' || pParams[end] == '|')
+          break;
+      if ( end < paramStr.Length())
+      {
+        sep = pParams[end];
+        pParams[end] = '\0';
       }
-      if(j!=aSections->length()-1)
-        anInputParams+="|";
+      if ( aStudy->IsVariable( pParams+beg ))
+        anInputParams += pParams+beg;
+      if ( end < paramStr.Length() )
+        anInputParams += sep;
+      else
+        break;
+      beg = end + 1;
     }
   }
   return CORBA::string_dup(anInputParams.ToCString());
index 045e691b9c79315a0a32e7c1125b73fa8661fe18..1b99653c62b603bf02ac844ca10080faba71b668 100644 (file)
@@ -1,39 +1,45 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes
 //  File   : SMESH_Group_i.cxx
 //  Author : Sergey ANIKIN, OCC
 //  Module : SMESH
 //
 #include "SMESH_Group_i.hxx"
-#include "SMESH_Mesh_i.hxx"
-#include "SMESH_Gen_i.hxx"
-#include "SMESH_Group.hxx"
+
+#include "SMDSAbs_ElementType.hxx"
 #include "SMESHDS_Group.hxx"
+#include "SMESHDS_GroupOnFilter.hxx"
 #include "SMESHDS_GroupOnGeom.hxx"
-#include "SMDSAbs_ElementType.hxx"
-
+#include "SMESH_Comment.hxx"
 #include "SMESH_Filter_i.hxx"
+#include "SMESH_Gen_i.hxx"
+#include "SMESH_Group.hxx"
+#include "SMESH_Mesh_i.hxx"
 #include "SMESH_PythonDump.hxx"
+#include "SMESH_PreMeshInfo.hxx"
+
+#include CORBA_SERVER_HEADER(SMESH_Filter)
 
 #include "utilities.h"
 
@@ -45,30 +51,48 @@ using namespace SMESH;
  */
 //=============================================================================
 
-SMESH_GroupBase_i::SMESH_GroupBase_i( PortableServer::POA_ptr thePOA, SMESH_Mesh_i* theMeshServant, const int theLocalID )
+SMESH_GroupBase_i::SMESH_GroupBase_i( PortableServer::POA_ptr thePOA,
+                                      SMESH_Mesh_i*           theMeshServant,
+                                      const int               theLocalID )
 : SALOME::GenericObj_i( thePOA ),
   myMeshServant( theMeshServant ), 
-  myLocalID( theLocalID )
+  myLocalID( theLocalID ),
+  myNbNodes(-1),
+  myGroupDSTic(0),
+  myPreMeshInfo(NULL)
 {
   // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i,
   // servant activation is performed by SMESH_Mesh_i::createGroup()
   // thePOA->activate_object( this );
 }
 
-SMESH_Group_i::SMESH_Group_i( PortableServer::POA_ptr thePOA, SMESH_Mesh_i* theMeshServant, const int theLocalID )
+SMESH_Group_i::SMESH_Group_i( PortableServer::POA_ptr thePOA,
+                              SMESH_Mesh_i*           theMeshServant,
+                              const int               theLocalID )
      : SALOME::GenericObj_i( thePOA ),
        SMESH_GroupBase_i( thePOA, theMeshServant, theLocalID )
 {
   //MESSAGE("SMESH_Group_i; this = "<<this );
 }
 
-SMESH_GroupOnGeom_i::SMESH_GroupOnGeom_i( PortableServer::POA_ptr thePOA, SMESH_Mesh_i* theMeshServant, const int theLocalID )
+SMESH_GroupOnGeom_i::SMESH_GroupOnGeom_i( PortableServer::POA_ptr thePOA,
+                                          SMESH_Mesh_i*           theMeshServant,
+                                          const int               theLocalID )
      : SALOME::GenericObj_i( thePOA ),
        SMESH_GroupBase_i( thePOA, theMeshServant, theLocalID )
 {
   //MESSAGE("SMESH_GroupOnGeom_i; this = "<<this );
 }
 
+SMESH_GroupOnFilter_i::SMESH_GroupOnFilter_i( PortableServer::POA_ptr thePOA,
+                                              SMESH_Mesh_i*           theMeshServant,
+                                              const int               theLocalID )
+  : SALOME::GenericObj_i( thePOA ),
+    SMESH_GroupBase_i( thePOA, theMeshServant, theLocalID )
+{
+  //MESSAGE("SMESH_GroupOnGeom_i; this = "<<this );
+}
+
 //=============================================================================
 /*!
  *  
@@ -80,6 +104,8 @@ SMESH_GroupBase_i::~SMESH_GroupBase_i()
   MESSAGE("~SMESH_GroupBase_i; this = "<<this );
   if ( myMeshServant )
     myMeshServant->removeGroup(myLocalID);
+
+  if ( myPreMeshInfo ) delete myPreMeshInfo; myPreMeshInfo = NULL;
 }
 
 //=======================================================================
@@ -165,11 +191,13 @@ SMESH::ElementType SMESH_GroupBase_i::GetType()
     SMDSAbs_ElementType aSMDSType = aGroupDS->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;
+    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;
+    case SMDSAbs_0DElement: aType = SMESH::ELEM0D; break;
+    case SMDSAbs_Ball:      aType = SMESH::BALL;   break;
+    default:                aType = SMESH::ALL;    break;
     }
     return aType;
   }
@@ -186,6 +214,9 @@ SMESH::ElementType SMESH_GroupBase_i::GetType()
 
 CORBA::Long SMESH_GroupBase_i::Size()
 {
+  if ( myPreMeshInfo )
+    return GetType() == SMESH::NODE ? myPreMeshInfo->NbNodes() : myPreMeshInfo->NbElements();
+
   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
   if (aGroupDS)
     return aGroupDS->Extent();
@@ -201,6 +232,9 @@ CORBA::Long SMESH_GroupBase_i::Size()
 
 CORBA::Boolean SMESH_GroupBase_i::IsEmpty()
 {
+  if ( myPreMeshInfo )
+    return Size() == 0;
+
   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
   if (aGroupDS)
     return aGroupDS->IsEmpty();
@@ -216,6 +250,9 @@ CORBA::Boolean SMESH_GroupBase_i::IsEmpty()
 
 void SMESH_Group_i::Clear()
 {
+  if ( myPreMeshInfo )
+    myPreMeshInfo->FullLoadFromFile();
+
   // Update Python script
   TPythonDump() << _this() << ".Clear()";
 
@@ -236,6 +273,9 @@ void SMESH_Group_i::Clear()
 
 CORBA::Boolean SMESH_GroupBase_i::Contains( CORBA::Long theID )
 {
+  if ( myPreMeshInfo )
+    myPreMeshInfo->FullLoadFromFile();
+
   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
   if (aGroupDS)
     return aGroupDS->Contains(theID);
@@ -251,6 +291,9 @@ CORBA::Boolean SMESH_GroupBase_i::Contains( CORBA::Long theID )
 
 CORBA::Long SMESH_Group_i::Add( const SMESH::long_array& theIDs )
 {
+  if ( myPreMeshInfo )
+    myPreMeshInfo->FullLoadFromFile();
+
   // Update Python script
   TPythonDump() << "nbAdd = " << _this() << ".Add( " << theIDs << " )";
 
@@ -277,6 +320,9 @@ CORBA::Long SMESH_Group_i::Add( const SMESH::long_array& theIDs )
 
 CORBA::Long SMESH_Group_i::Remove( const SMESH::long_array& theIDs )
 {
+  if ( myPreMeshInfo )
+    myPreMeshInfo->FullLoadFromFile();
+
   // Update Python script
   TPythonDump() << "nbDel = " << _this() << ".Remove( " << theIDs << " )";
 
@@ -305,8 +351,8 @@ typedef bool (SMESHDS_Group::*TFunChangeGroup)(const int);
 
 CORBA::Long 
 ChangeByPredicate( SMESH::Predicate_i* thePredicate,
-                  SMESHDS_GroupBase* theGroupBase,
-                  TFunChangeGroup theFun)
+                   SMESHDS_GroupBase*  theGroupBase,
+                   TFunChangeGroup     theFun)
 {
   CORBA::Long aNb = 0;
   if(SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>(theGroupBase)){
@@ -317,7 +363,7 @@ ChangeByPredicate( SMESH::Predicate_i* thePredicate,
     CORBA::Long i = 0, iEnd = aSequence.size();
     for(; i < iEnd; i++)
       if((aGroupDS->*theFun)(aSequence[i]))
-       aNb++;
+        aNb++;
     return aNb;
   }
   return aNb;
@@ -327,6 +373,9 @@ CORBA::Long
 SMESH_Group_i::
 AddByPredicate( SMESH::Predicate_ptr thePredicate )
 {
+  if ( myPreMeshInfo )
+    myPreMeshInfo->FullLoadFromFile();
+
   if(SMESH::Predicate_i* aPredicate = SMESH::GetPredicate(thePredicate)){
     TPythonDump()<<_this()<<".AddByPredicate("<<aPredicate<<")";
     return ChangeByPredicate(aPredicate,GetGroupDS(),&SMESHDS_Group::Add);
@@ -338,6 +387,9 @@ CORBA::Long
 SMESH_Group_i::
 RemoveByPredicate( SMESH::Predicate_ptr thePredicate )
 {
+  if ( myPreMeshInfo )
+    myPreMeshInfo->FullLoadFromFile();
+
   if(SMESH::Predicate_i* aPredicate = SMESH::GetPredicate(thePredicate)){
     TPythonDump()<<_this()<<".RemoveByPredicate("<<aPredicate<<")";
     return ChangeByPredicate(aPredicate,GetGroupDS(),&SMESHDS_Group::Remove);
@@ -345,6 +397,43 @@ RemoveByPredicate( SMESH::Predicate_ptr thePredicate )
   return 0;
 }
 
+CORBA::Long SMESH_Group_i::AddFrom( SMESH::SMESH_IDSource_ptr theSource )
+{
+  if ( myPreMeshInfo )
+    myPreMeshInfo->FullLoadFromFile();
+
+  TPythonDump pd;
+  long nbAdd = 0;
+  SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( GetGroupDS() );
+  if (aGroupDS) {
+    SMESH::long_array_var anIds;
+    SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theSource);
+    SMESH::SMESH_Mesh_var mesh       = SMESH::SMESH_Mesh::_narrow(theSource);
+    SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow(theSource);
+    SMESH::Filter_var filter         = SMESH::Filter::_narrow(theSource);
+    if ( !group->_is_nil())
+      anIds = group->GetType()==GetType() ? theSource->GetIDs() :  new SMESH::long_array();
+    else if ( !mesh->_is_nil() )
+      anIds = mesh->GetElementsByType( GetType() );
+    else if ( !submesh->_is_nil())
+      anIds = submesh->GetElementsByType( GetType() );
+    else if ( !filter->_is_nil() ) {
+      filter->SetMesh( GetMeshServant()->_this() );
+      anIds = filter->GetElementType()==GetType() ? theSource->GetIDs() : new SMESH::long_array();
+    }
+    else 
+      anIds = theSource->GetIDs();
+    for ( int i = 0, total = anIds->length(); i < total; i++ ) {
+      if ( aGroupDS->Add((int)anIds[i]) ) nbAdd++;
+    }
+  }
+
+  // Update Python script
+  pd << "nbAdd = " << _this() << ".AddFrom( " << theSource << " )";
+
+  return nbAdd;
+}
+
 //=============================================================================
 /*!
  *  
@@ -353,6 +442,9 @@ RemoveByPredicate( SMESH::Predicate_ptr thePredicate )
 
 CORBA::Long SMESH_GroupBase_i::GetID( CORBA::Long theIndex )
 {
+  if ( myPreMeshInfo )
+    myPreMeshInfo->FullLoadFromFile();
+
   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
   if (aGroupDS)
     return aGroupDS->GetID(theIndex);
@@ -368,30 +460,113 @@ CORBA::Long SMESH_GroupBase_i::GetID( CORBA::Long theIndex )
 
 SMESH::long_array* SMESH_GroupBase_i::GetListOfID()
 {
+  if ( myPreMeshInfo )
+    myPreMeshInfo->FullLoadFromFile();
+
   SMESH::long_array_var aRes = new SMESH::long_array();
   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
-  if (aGroupDS) {
+  if (aGroupDS)
+  {
     int aSize = aGroupDS->Extent();
     aRes->length(aSize);
     for (int i = 0; i < aSize; i++)
       aRes[i] = aGroupDS->GetID(i+1);
-    return aRes._retn();
+
+    if ( 0 < aSize && aSize < 100 ) // for comfortable testing ;)
+      std::sort( &aRes[0], &aRes[0]+aSize );
   }
   MESSAGE("get list of IDs of a vague group");
   return aRes._retn();
 }
 
-//=============================================================================
+namespace
+{
+  //================================================================================
+  /*!
+   * \brief return nodes of elements pointered by iterator
+   */
+  //================================================================================
+
+  void getNodesOfElements(SMDS_ElemIteratorPtr        elemIt,
+                          set<const SMDS_MeshNode* >& nodes)
+  {
+    while ( elemIt->more() )
+    {
+      const SMDS_MeshElement* e = elemIt->next();
+      nodes.insert( e->begin_nodes(), e->end_nodes() );
+    }
+  }
+}
+  
+//================================================================================
 /*!
- *  
+ * \brief return the number of nodes of cells included to the group
  */
-//=============================================================================
-SMESH::SMESH_Mesh_ptr SMESH_GroupBase_i::GetMesh()
+//================================================================================
+
+CORBA::Long SMESH_GroupBase_i::GetNumberOfNodes()
 {
-  SMESH::SMESH_Mesh_var aMesh;
-  if ( myMeshServant )
-    aMesh = SMESH::SMESH_Mesh::_narrow( myMeshServant->_this() );
-  return aMesh._retn();
+  if ( GetType() == SMESH::NODE )
+    return Size();
+
+  if ( myPreMeshInfo )
+    myPreMeshInfo->FullLoadFromFile();
+
+  if ( SMESHDS_GroupBase* g = GetGroupDS())
+  {
+    if ( myNbNodes < 0 || g->GetTic() != myGroupDSTic )
+    {      
+      set<const SMDS_MeshNode* > nodes;
+      getNodesOfElements( g->GetElements(), nodes );
+      myNbNodes = nodes.size();
+      myGroupDSTic = g->GetTic();
+    }
+  }
+  return myNbNodes;
+}
+
+//================================================================================
+/*!
+ * \brief Return true if GetNumberOfNodes() won't take a long time for computation
+ */
+//================================================================================
+
+CORBA::Boolean SMESH_GroupBase_i::IsNodeInfoAvailable()
+{
+  if ( GetType() == SMESH::NODE/* || Size() < 100000 */)
+    return true;
+  if ( myPreMeshInfo )
+    return false;
+  if ( SMESHDS_GroupBase* g = GetGroupDS())
+    return ( myNbNodes > -1 && g->GetTic() == myGroupDSTic);
+  return false;
+}
+
+//================================================================================
+/*!
+ * \brief Return IDs of nodes of cells included to the group
+ */
+//================================================================================
+
+SMESH::long_array* SMESH_GroupBase_i::GetNodeIDs()
+{
+  if ( GetType() == SMESH::NODE )
+    return GetListOfID();
+
+  if ( myPreMeshInfo )
+    myPreMeshInfo->FullLoadFromFile();
+
+  SMESH::long_array_var aRes = new SMESH::long_array();
+  if ( SMESHDS_GroupBase* g = GetGroupDS())
+  {
+    set<const SMDS_MeshNode* > nodes;
+    getNodesOfElements( g->GetElements(), nodes );
+    aRes->length( nodes.size() );
+    set<const SMDS_MeshNode*>::iterator nIt = nodes.begin(), nEnd = nodes.end();
+    for ( int i = 0; nIt != nEnd; ++nIt, ++i )
+      aRes[i] = (*nIt)->GetID();
+  }
+  return aRes._retn();
 }
 
 //=============================================================================
@@ -399,10 +574,12 @@ SMESH::SMESH_Mesh_ptr SMESH_GroupBase_i::GetMesh()
  *  
  */
 //=============================================================================
-SMESH::long_array* SMESH_GroupBase_i::GetIDs()
+SMESH::SMESH_Mesh_ptr SMESH_GroupBase_i::GetMesh()
 {
-  SMESH::long_array_var aResult = GetListOfID();
-  return aResult._retn();
+  SMESH::SMESH_Mesh_var aMesh;
+  if ( myMeshServant )
+    aMesh = SMESH::SMESH_Mesh::_narrow( myMeshServant->_this() );
+  return aMesh._retn();
 }
 
 //=======================================================================
@@ -454,10 +631,13 @@ void SMESH_GroupBase_i::SetColor(const SALOMEDS::Color& color)
   if (aGroupDS)
   {
     Quantity_Color aQColor( color.R, color.G, color.B, Quantity_TOC_RGB );
-    return aGroupDS->SetColor(aQColor);
+    Quantity_Color oldColor = aGroupDS->GetColor();
+    if ( oldColor != aQColor )
+    {
+      aGroupDS->SetColor(aQColor);
+      TPythonDump()<<_this()<<".SetColor( SALOMEDS.Color( "<<color.R<<", "<<color.G<<", "<<color.B<<" ))";
+    }
   }
-  MESSAGE("set color of a group");
-  return ;
 }
 
 //=============================================================================
@@ -483,7 +663,258 @@ void SMESH_GroupBase_i::SetColorNumber(CORBA::Long color)
 {
   SMESHDS_GroupBase* aGroupDS = GetGroupDS();
   if (aGroupDS)
-    return aGroupDS->SetColorGroup(color);
+  {
+    aGroupDS->SetColorGroup(color);
+    TPythonDump()<<_this()<<".SetColorNumber( "<<color<<" )";
+  }
   MESSAGE("set color number of a group");
   return ;
 }
+
+//=============================================================================
+/*!
+ * Returns statistic of mesh elements
+ * Result array of number enityties
+ * Inherited from SMESH_IDSource
+ */
+//=============================================================================
+SMESH::long_array* SMESH_GroupBase_i::GetMeshInfo()
+{
+  if ( myPreMeshInfo )
+    return myPreMeshInfo->GetMeshInfo();
+
+  SMESH::long_array_var aRes = new SMESH::long_array();
+  aRes->length(SMESH::Entity_Last);
+  for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
+    aRes[i] = 0;
+
+  if ( SMESHDS_GroupBase* g = GetGroupDS())
+  {
+    if ( g->GetType() == SMDSAbs_Node || ( myNbNodes > -1 && g->GetTic() == myGroupDSTic))
+      aRes[ SMDSEntity_Node ] = GetNumberOfNodes();
+
+    if ( g->GetType() != SMDSAbs_Node )
+      SMESH_Mesh_i::CollectMeshInfo( g->GetElements(), aRes);
+  }
+
+  return aRes._retn();
+}
+
+//=======================================================================
+//function : GetIDs
+//purpose  : Returns ids of members
+//=======================================================================
+
+SMESH::long_array* SMESH_GroupBase_i::GetIDs()
+{
+  return GetListOfID();
+}
+
+//=======================================================================
+//function : GetTypes
+//purpose  : Returns types of elements it contains
+//=======================================================================
+
+SMESH::array_of_ElementType* SMESH_GroupBase_i::GetTypes()
+{
+  SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
+  if ( !IsEmpty() )
+  {
+    types->length( 1 );
+    types[0] = GetType();
+  }
+  return types._retn();
+}
+
+//=======================================================================
+//function : IsMeshInfoCorrect
+//purpose  : * Returns false if GetMeshInfo() returns incorrect information that may
+//           * happen if mesh data is not yet fully loaded from the file of study.
+//=======================================================================
+
+bool SMESH_GroupBase_i::IsMeshInfoCorrect()
+{
+  return myPreMeshInfo ? myPreMeshInfo->IsMeshInfoCorrect() : true;
+}
+
+//================================================================================
+/*!
+ * \brief Retrieves the predicate from the filter
+ */
+//================================================================================
+
+SMESH_PredicatePtr SMESH_GroupOnFilter_i::GetPredicate( SMESH::Filter_ptr filter )
+{
+  SMESH_PredicatePtr predicate;
+
+  if ( SMESH::Filter_i* filt_i = SMESH::DownCast< SMESH::Filter_i* >( filter ))
+    if ( SMESH::Predicate_i* predic_i= filt_i->GetPredicate_i() )
+      predicate = predic_i->GetPredicate();
+
+  return predicate;
+}
+
+//================================================================================
+/*!
+ * \brief Sets the filter defining group contents
+ */
+//================================================================================
+
+void SMESH_GroupOnFilter_i::SetFilter(SMESH::Filter_ptr theFilter)
+{
+  if ( myPreMeshInfo )
+    myPreMeshInfo->FullLoadFromFile();
+
+  if ( ! myFilter->_is_nil() )
+    myFilter->UnRegister();
+
+  myFilter = SMESH::Filter::_duplicate( theFilter );
+
+  if ( SMESHDS_GroupOnFilter* grDS = dynamic_cast< SMESHDS_GroupOnFilter*>( GetGroupDS() ))
+    grDS->SetPredicate( GetPredicate( myFilter ));
+
+  TPythonDump()<< _this() <<".SetFilter( "<<theFilter<<" )";
+
+  if ( myFilter )
+  {
+    myFilter->Register();
+    SMESH::DownCast< SMESH::Filter_i* >( myFilter )->AddWaiter( this );
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Returns the filter defining group contents
+ */
+//================================================================================
+
+SMESH::Filter_ptr SMESH_GroupOnFilter_i::GetFilter()
+{
+  SMESH::Filter_var f = myFilter;
+  TPythonDump() << f << " = " << _this() << ".GetFilter()";
+  return f._retn();
+}
+
+#define SEPAR '^'
+
+//================================================================================
+/*!
+ * \brief Return a string to be used to store group definition in the study
+ */
+//================================================================================
+
+std::string SMESH_GroupOnFilter_i::FilterToString() const
+{
+  SMESH_Comment result;
+  SMESH::Filter::Criteria_var criteria;
+  if ( !myFilter->_is_nil() && myFilter->GetCriteria( criteria.out() ))
+  {
+    result << criteria->length() << SEPAR;
+    for ( unsigned i = 0; i < criteria->length(); ++i )
+    {
+      // write FunctorType as string but not as number to assure correct
+      // persistence if enum FunctorType is modified by insertion in the middle
+      SMESH::Filter::Criterion& crit = criteria[ i ];
+      result << SMESH::FunctorTypeToString( SMESH::FunctorType( crit.Type ))    << SEPAR;
+      result << SMESH::FunctorTypeToString( SMESH::FunctorType( crit.Compare )) << SEPAR;
+      result << crit.Threshold                                                  << SEPAR;
+      result << crit.ThresholdStr                                               << SEPAR;
+      result << crit.ThresholdID                                                << SEPAR;
+      result << SMESH::FunctorTypeToString( SMESH::FunctorType( crit.UnaryOp )) << SEPAR;
+      result << SMESH::FunctorTypeToString( SMESH::FunctorType( crit.BinaryOp ))<< SEPAR;
+      result << crit.Tolerance                                                  << SEPAR;
+      result << crit.TypeOfElement                                              << SEPAR;
+      result << crit.Precision                                                  << SEPAR;
+    }
+  }
+  return result;
+}
+
+//================================================================================
+/*!
+ * \brief Restore the filter by the persistent string
+ */
+//================================================================================
+
+SMESH::Filter_ptr SMESH_GroupOnFilter_i::StringToFilter(const std::string& thePersistStr )
+{
+  SMESH::Filter_var filter;
+
+  // divide thePersistStr into sub-strings
+  std::vector< std::string > strVec;
+  std::string::size_type from = 0, to;
+  while ( from < thePersistStr.size() )
+  {
+    to = thePersistStr.find( SEPAR, from );
+    if ( to == std::string::npos )
+      break;
+    strVec.push_back( thePersistStr.substr( from, to-from ));
+    from = to+1;
+  }
+  if ( strVec.empty() || strVec[0] == "0" )
+    return filter._retn();
+#undef SEPAR
+
+  // create Criteria
+  int nbCrit = atoi( strVec[0].c_str() );
+  SMESH::Filter::Criteria_var criteria = new SMESH::Filter::Criteria;
+  criteria->length( nbCrit );
+  int nbStrPerCrit = ( strVec.size() - 1 ) / nbCrit;
+  for ( int i = 0; i < nbCrit; ++i )
+  {
+    SMESH::Filter::Criterion& crit = criteria[ i ];
+    int iStr = 1 + i * nbStrPerCrit;
+    crit.Type         = SMESH::StringToFunctorType( strVec[ iStr++ ].c_str() );
+    crit.Compare      = SMESH::StringToFunctorType( strVec[ iStr++ ].c_str() );
+    crit.Threshold    = atof(                       strVec[ iStr++ ].c_str() );
+    crit.ThresholdStr =                             strVec[ iStr++ ].c_str();
+    crit.ThresholdID  =                             strVec[ iStr++ ].c_str();
+    crit.UnaryOp      = SMESH::StringToFunctorType( strVec[ iStr++ ].c_str() );
+    crit.BinaryOp     = SMESH::StringToFunctorType( strVec[ iStr++ ].c_str() );
+    crit.Tolerance    = atof(                       strVec[ iStr++ ].c_str() );
+    crit.TypeOfElement= SMESH::ElementType( atoi(   strVec[ iStr++ ].c_str() ));
+    crit.Precision    = atoi(                       strVec[ iStr++ ].c_str() );
+  }
+
+  // create a filter
+  TPythonDump pd;
+  SMESH::FilterManager_i* aFilterMgr = new SMESH::FilterManager_i();
+  filter = aFilterMgr->CreateFilter();
+  filter->SetCriteria( criteria.inout() );
+  
+  aFilterMgr->UnRegister();
+
+  pd << ""; // to avoid optimizing pd out
+
+  return filter._retn();
+}
+
+//================================================================================
+/*!
+ * \brief Destructor of SMESH_GroupOnFilter_i
+ */
+//================================================================================
+
+SMESH_GroupOnFilter_i::~SMESH_GroupOnFilter_i()
+{
+  if ( ! myFilter->_is_nil() )
+  {
+    SMESH::DownCast< SMESH::Filter_i* >( myFilter )->RemoveWaiter( this );
+    myFilter->UnRegister();
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Method calleds when a predicate of myFilter changes
+ */
+//================================================================================
+
+void SMESH_GroupOnFilter_i::PredicateChanged()
+{
+  if ( myPreMeshInfo )
+    myPreMeshInfo->FullLoadFromFile();
+
+  if ( SMESHDS_GroupOnFilter* grDS = dynamic_cast< SMESHDS_GroupOnFilter*>( GetGroupDS() ))
+    grDS->SetPredicate( GetPredicate( myFilter ));
+}
index 8e6e33f9f679c8d360134c20123e1d872137fccc..dcb441057e0399e8978bae67fc1392c0474c78c4 100644 (file)
@@ -1,34 +1,36 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes
 //  File   : SMESH_Group_i.hxx
 //  Author : Sergey ANIKIN, OCC
 //  Module : SMESH
-//  $Header$
 //
 #ifndef SMESH_Group_i_HeaderFile
 #define SMESH_Group_i_HeaderFile
 
 #include "SMESH.hxx"
+#include "SMESH_Mesh_i.hxx"
+#include "SMESH_Filter_i.hxx"
 
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Group)
@@ -37,9 +39,9 @@
 
 #include "SALOME_GenericObj_i.hh"
 
-class SMESH_Mesh_i;
 class SMESH_Group;
 class SMESHDS_GroupBase;
+class SMESH_PreMeshInfo;
 
 // ===========
 // Group Base
@@ -50,8 +52,8 @@ class SMESH_I_EXPORT SMESH_GroupBase_i:
 {
  public:
   SMESH_GroupBase_i(PortableServer::POA_ptr thePOA,
-                    SMESH_Mesh_i* theMeshServant,
-                    const int theLocalID );
+                    SMESH_Mesh_i*           theMeshServant,
+                    const int               theLocalID );
   virtual ~SMESH_GroupBase_i();
 
   // CORBA interface implementation
@@ -63,11 +65,33 @@ class SMESH_I_EXPORT SMESH_GroupBase_i:
   CORBA::Boolean Contains(CORBA::Long elem_id);
   CORBA::Long GetID(CORBA::Long elem_index);
   SMESH::long_array* GetListOfID();
-  SMESH::SMESH_Mesh_ptr GetMesh();
+  SMESH::long_array* GetNodeIDs();
+  CORBA::Long GetNumberOfNodes();
+  CORBA::Boolean IsNodeInfoAvailable(); // for gui
+
+  virtual SMESH::SMESH_Mesh_ptr GetMesh();
+
+  /*!
+   * Returns statistic of mesh elements
+   * Result array of number enityties
+   * Inherited from SMESH_IDSource
+   */
+  virtual SMESH::long_array* GetMeshInfo();
 
   // Inherited from SMESH_IDSource interface
   virtual SMESH::long_array* GetIDs();
 
+  /*!
+   * Returns types of elements it contains
+   * Inherited from SMESH_IDSource interface
+   */
+  virtual SMESH::array_of_ElementType* GetTypes();
+  /*!
+   * Returns false if GetMeshInfo() returns incorrect information that may
+   * happen if mesh data is not yet fully loaded from the file of study.
+   */
+  virtual bool IsMeshInfoCorrect();
+
   // Internal C++ interface
   int GetLocalID() const { return myLocalID; }
   SMESH_Mesh_i* GetMeshServant() const { return myMeshServant; }
@@ -80,9 +104,20 @@ class SMESH_I_EXPORT SMESH_GroupBase_i:
   void SetColorNumber(CORBA::Long color);
   CORBA::Long GetColorNumber();
 
+protected:
+
+  SMESH_PreMeshInfo* & changePreMeshInfo() { return myPreMeshInfo; }
+  SMESH_PreMeshInfo* myPreMeshInfo; // mesh info before full loading from study file
+  friend class SMESH_PreMeshInfo;
+
 private:
   SMESH_Mesh_i* myMeshServant;
   int myLocalID;
+
+  void changeLocalId(int localId) { myLocalID = localId; }
+  friend class SMESH_Mesh_i;
+
+  int myNbNodes, myGroupDSTic;
 };
 
 // ======
@@ -94,8 +129,9 @@ class SMESH_I_EXPORT SMESH_Group_i:
   public SMESH_GroupBase_i
 {
  public:
-  SMESH_Group_i( PortableServer::POA_ptr thePOA, SMESH_Mesh_i* theMeshServant, const int theLocalID );
-
+  SMESH_Group_i( PortableServer::POA_ptr thePOA,
+                 SMESH_Mesh_i*           theMeshServant,
+                 const int               theLocalID );
   // CORBA interface implementation
   void Clear();
   CORBA::Long Add( const SMESH::long_array& theIDs );
@@ -103,6 +139,8 @@ class SMESH_I_EXPORT SMESH_Group_i:
 
   CORBA::Long AddByPredicate( SMESH::Predicate_ptr thePredicate );
   CORBA::Long RemoveByPredicate( SMESH::Predicate_ptr thePredicate );
+
+  CORBA::Long AddFrom( SMESH::SMESH_IDSource_ptr theSource );
 };
 
 // =========================
@@ -114,9 +152,42 @@ class SMESH_I_EXPORT SMESH_GroupOnGeom_i:
   public SMESH_GroupBase_i
 {
  public:
-  SMESH_GroupOnGeom_i( PortableServer::POA_ptr thePOA, SMESH_Mesh_i* theMeshServant, const int theLocalID );
-
+  SMESH_GroupOnGeom_i( PortableServer::POA_ptr thePOA,
+                       SMESH_Mesh_i*           theMeshServant,
+                       const int               theLocalID );
   // CORBA interface implementation
   GEOM::GEOM_Object_ptr GetShape();
 };
+
+// =========================
+// Group deined by filter
+// =========================
+
+class SMESH_I_EXPORT SMESH_GroupOnFilter_i:
+  public virtual POA_SMESH::SMESH_GroupOnFilter,
+  public SMESH_GroupBase_i,
+  public SMESH::Filter_i::TPredicateChangeWaiter
+{
+ public:
+  SMESH_GroupOnFilter_i( PortableServer::POA_ptr thePOA,
+                         SMESH_Mesh_i*           theMeshServant,
+                         const int               theLocalID );
+  ~SMESH_GroupOnFilter_i();
+
+  // Persistence
+  static SMESH::Filter_ptr StringToFilter(const std::string& thePersistentString );
+  std::string FilterToString() const;
+
+  static SMESH_PredicatePtr GetPredicate( SMESH::Filter_ptr );
+
+  // CORBA interface implementation
+  void SetFilter(SMESH::Filter_ptr theFilter);
+  SMESH::Filter_ptr GetFilter();
+
+  // method of SMESH::Filter_i::TPredicateChangeWaiter
+  virtual void PredicateChanged();
+
+ private:
+  SMESH::Filter_var myFilter;
+};
 #endif
index b677e647b13c6dca7222d71f0206c2be16008342..96131044beb93cb8c40a7c0687703a91cca6e87a 100644 (file)
@@ -1,29 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : SMESH_Hypothesis_i.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//  $Header$
 //
 #include <iostream>
 #include <sstream>
@@ -138,6 +138,78 @@ bool SMESH_Hypothesis_i::IsPublished(){
   return res;
 }
 
+//================================================================================
+/*!
+ * \brief Set the pramIndex-th parameter
+ */
+//================================================================================
+
+void SMESH_Hypothesis_i::SetVarParameter (const char* theParameter,
+                                          const char* theMethod)
+{
+  if ( SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen() )
+  {
+    gen->UpdateParameters(theParameter);
+
+    const std::vector< std::string >& pars = gen->GetLastParameters();
+    if ( !pars.empty() )
+      myMethod2VarParams[ theMethod ] = pars[0];
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Return the pramIndex-th variable parameter used for Hypothesis creation
+ */
+//================================================================================
+
+char* SMESH_Hypothesis_i::GetVarParameter (const char* theMethod)
+{
+  if ( myMethod2VarParams.count("needs update by old study"))
+  {
+    // restore myMethod2VarParams by old study
+    myMethod2VarParams.clear();
+    if ( SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen() )
+    {
+      CORBA::String_var oldparVar = gen->GetParameters( _this() );
+      setOldParameters( oldparVar.in() );
+    }
+  }
+  std::map< std::string, std::string >::iterator meth_param = myMethod2VarParams.find( theMethod );
+  if ( meth_param != myMethod2VarParams.end() )
+    return CORBA::string_dup( meth_param->second.c_str() );
+
+  return CORBA::string_dup("");
+}
+
+//================================================================================
+/*!
+ * \brief Restore myMethod2VarParams by parameters stored in an old study
+ */
+//================================================================================
+
+void SMESH_Hypothesis_i::setOldParameters (const char* theParameters)
+{
+  if ( SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen() )
+  {
+    TCollection_AsciiString aOldParameters(theParameters);
+    int pos = aOldParameters.SearchFromEnd("|");
+    if ( pos >= 0 ) aOldParameters = aOldParameters.Split(pos);
+    pos = aOldParameters.SearchFromEnd(";*=");
+    if ( pos >= 0 ) aOldParameters.Split(pos-1);
+    gen->UpdateParameters( aOldParameters.ToCString() );
+
+    myMethod2VarParams.clear();
+    const std::vector< std::string >& pars = gen->GetLastParameters();
+    for ( size_t i = 0; i < pars.size(); ++i )
+    {
+      std::string meth = getMethodOfParameter( i, pars.size() );
+      myMethod2VarParams[ meth ] = pars[i];
+    }
+    gen->UpdateParameters(""); // clear params
+  }
+}
+
 //=============================================================================
 /*!
  *  SMESH_Hypothesis_i::SetParameters()
@@ -147,14 +219,15 @@ bool SMESH_Hypothesis_i::IsPublished(){
 void SMESH_Hypothesis_i::SetParameters(const char* theParameters)
 {
   SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
-  char * aParameters = CORBA::string_dup(theParameters);
+  //char * aParameters = CORBA::string_dup(theParameters);
   if(gen){
-    if(IsPublished()) {
-      SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Hypothesis::_narrow(_this()),aParameters);
-    }
-    else {
-      myBaseImpl->SetParameters(gen->ParseParameters(aParameters));
-    }
+    gen->UpdateParameters(theParameters);
+    // if(IsPublished()) {
+    //   SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Hypothesis::_narrow(_this()),aParameters);
+    // }
+    // else {
+    //   myBaseImpl->SetParameters(gen->ParseParameters(aParameters));
+    // }
   }
 }
 
@@ -230,9 +303,10 @@ void SMESH_Hypothesis_i::SetLastParameters(const char* theParameters)
 //=============================================================================
 void SMESH_Hypothesis_i::ClearParameters()
 {
-  if(!IsPublished()) {
-    myBaseImpl->ClearParameters();
-  }
+  myMethod2VarParams.clear();
+  // if(!IsPublished()) {
+  //   myBaseImpl->ClearParameters();
+  // }
 }
 
 //=============================================================================
@@ -245,7 +319,6 @@ void SMESH_Hypothesis_i::ClearParameters()
 
 ::SMESH_Hypothesis* SMESH_Hypothesis_i::GetImpl()
 {
-  //MESSAGE( "SMESH_Hypothesis_i::GetImpl" );
   return myBaseImpl;
 }
 
@@ -259,8 +332,18 @@ void SMESH_Hypothesis_i::ClearParameters()
 
 char* SMESH_Hypothesis_i::SaveTo()
 {
-  MESSAGE( "SMESH_Hypothesis_i::SaveTo" );
   std::ostringstream os;
+
+  // assure that parameters are loaded from an old study
+  CORBA::String_var p = GetVarParameter("");
+
+  os << "VARS " << myMethod2VarParams.size()  << " ";
+  std::map< std::string, std::string >::iterator meth_param = myMethod2VarParams.begin();
+  for ( ; meth_param != myMethod2VarParams.end(); ++meth_param )
+    os << meth_param->first << " "
+       << meth_param->second.size() << " "
+       << meth_param->second << " ";
+
   myBaseImpl->SaveTo( os );
   return CORBA::string_dup( os.str().c_str() );
 }
@@ -275,7 +358,44 @@ char* SMESH_Hypothesis_i::SaveTo()
 
 void SMESH_Hypothesis_i::LoadFrom( const char* theStream )
 {
-  MESSAGE( "SMESH_Hypothesis_i::LoadFrom" );
   std::istringstream is( theStream );
+  if ( strncmp( theStream, "VARS", 4 ) == 0 )
+  {
+    int nbVars, len;
+    char str[256];
+    std::string meth;
+    is >> str >> nbVars;
+    for ( int i = 0; i < nbVars; ++i )
+    {
+      is >> meth >> len;
+      if ( len < 256 )
+      {
+        is.get( str, len + 2 ); // 2 - to read at least 1 white space
+        if ( len > 0 )
+          myMethod2VarParams[ meth ] = std::string( str+1, len );
+      }
+    }
+  }
+  else
+  {
+    // we can't restore myMethod2VarParams by old study here because SObject
+    // isn't yet bound to _this()
+    myMethod2VarParams["needs update by old study"] = "yes";
+  }
+
   myBaseImpl->LoadFrom( is );
+
+  // let listeners know about loading (issue 0020918)
+  myBaseImpl->NotifySubMeshesHypothesisModification();
+}
+
+//================================================================================
+/*!
+ * \brief This mesthod is called after completion of loading a study 
+ */
+//================================================================================
+
+void SMESH_Hypothesis_i::UpdateAsMeshesRestored()
+{
+  // for hyps needing full data restored
 }
index 13bd7742fd3b07ecdc9faf4447c8a89bc9053762..593ed85cab9928ab3020c9c36ceb6705347fc179 100644 (file)
@@ -1,29 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : SMESH_Hypothesis_i.hxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//  $Header$
 //
 #ifndef _SMESH_HYPOTHESIS_I_HXX_
 #define _SMESH_HYPOTHESIS_I_HXX_
 
 #include "SMESH_Gen.hxx"
 
+#include <map>
+#include <string>
+
+class TCollection_AsciiString;
+
 // ======================================================
 // Generic hypothesis
 // ======================================================
@@ -65,6 +70,14 @@ public:
   // Get unique id of hypothesis
   CORBA::Long GetId();
   
+  // Set the variable parameter; method is a name of method setting this parameter.
+  // This method must be called by the hypothesis creator just before calling hyp->method()
+  void SetVarParameter (const char* parameter, const char* method);
+
+  // Return the variable parameter used for Hypothesis creation by name of method
+  // setting this parameter
+  char* GetVarParameter (const char* methodName);
+
   // Set list of parameters  separated by ":" symbol, used for Hypothesis creation
   void SetParameters (const char* theParameters);
   
@@ -90,9 +103,27 @@ public:
   // Persistence
   virtual char* SaveTo();
   virtual void  LoadFrom( const char* theStream );
-  
+  virtual void  UpdateAsMeshesRestored(); // for hyps needing full data restored
+
 protected:
-  ::SMESH_Hypothesis* myBaseImpl;    // base hypothesis implementation
+  ::SMESH_Hypothesis*          myBaseImpl;    // base hypothesis implementation
+
+  std::map< std::string, std::string > myMethod2VarParams; // variable parameters
+
+
+ public:
+  // Methods for backward compatibility of notebook variables
+  
+  // restore myMethod2VarParams by parameters stored in an old study
+  virtual void setOldParameters (const char* theParameters);
+
+  // method used to convert variable parameters stored in an old study
+  // into myMethod2VarParams. It should return a method name for an index of
+  // variable parameters. Index is countered from zero
+  virtual std::string getMethodOfParameter(const int paramIndex, int nbVars) const { return ""; }
+
+  // method intended to remove explicit treatment of Netgen hypotheses from SMESH_NoteBook
+  virtual int getParamIndex(const TCollection_AsciiString& method, int nbVars) const { return -1; }
 };
 
 // ======================================================
index 35bacddc328c692b912f73e19ef173150217c900..3218fd48637099409d401bdb1ef5a7168b1935e0 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : SMESH_MEDFamily_i.cxx
 //  Module : SMESH
@@ -77,7 +78,7 @@ SMESH_MEDFamily_i::~SMESH_MEDFamily_i()
  */
 //=============================================================================
 SMESH_MEDFamily_i::SMESH_MEDFamily_i(int identifier, SMESH_subMesh_i* sm,
-                                    string name, string description, SALOME_MED::medEntityMesh entity): 
+                                     string name, string description, SALOME_MED::medEntityMesh entity): 
   SMESH_MEDSupport_i( sm, name, description, entity ),
   
   _subMesh_i(sm),
@@ -101,9 +102,9 @@ SMESH_MEDFamily_i::SMESH_MEDFamily_i(int identifier, SMESH_subMesh_i* sm,
 CORBA::Long SMESH_MEDFamily_i::getIdentifier()      
 throw (SALOME::SALOME_Exception)
 {
-  if (_subMeshDS==NULL)
+  if (_subMesh==NULL)
     THROW_SALOME_CORBA_EXCEPTION("No associated Family",\
-                                SALOME::INTERNAL_ERROR); 
+                                 SALOME::INTERNAL_ERROR); 
   return _identifier;
   
 }
@@ -115,9 +116,9 @@ throw (SALOME::SALOME_Exception)
 CORBA::Long SMESH_MEDFamily_i::getNumberOfAttributes() 
 throw (SALOME::SALOME_Exception)
 {
-  if (_subMeshDS==NULL)
+  if (_subMesh==NULL)
     THROW_SALOME_CORBA_EXCEPTION("No associated Family",\
-                                SALOME::INTERNAL_ERROR);
+                                 SALOME::INTERNAL_ERROR);
   return _numberOfAttribute;
 }
 //=============================================================================
@@ -125,20 +126,20 @@ throw (SALOME::SALOME_Exception)
  * CORBA: Accessor for attributes identifiers
  */
 //=============================================================================
-SALOME_MED::long_array*  SMESH_MEDFamily_i::getAttributesIdentifiers() 
+SALOME_TYPES::ListOfLong*  SMESH_MEDFamily_i::getAttributesIdentifiers() 
 throw (SALOME::SALOME_Exception)
 {
-  if (_subMeshDS==NULL)
+  if (_subMesh==NULL)
     THROW_SALOME_CORBA_EXCEPTION("No associated Family",\
-                                SALOME::INTERNAL_ERROR);
+                                 SALOME::INTERNAL_ERROR);
   if (_numberOfAttribute == 0)
     {
       MESSAGE("Les familles SMESH n ont pas d attribut");
       THROW_SALOME_CORBA_EXCEPTION("No attributes"\
-                                  ,SALOME::BAD_PARAM);
+                                   ,SALOME::BAD_PARAM);
     };
   
-  SALOME_MED::long_array_var myseq= new SALOME_MED::long_array;
+  SALOME_TYPES::ListOfLong_var myseq= new SALOME_TYPES::ListOfLong;
   myseq->length(_numberOfAttribute);
   for (int i=0;i<_numberOfAttribute;i++)
     {
@@ -155,17 +156,17 @@ throw (SALOME::SALOME_Exception)
 CORBA::Long SMESH_MEDFamily_i::getAttributeIdentifier(CORBA::Long i) 
   throw (SALOME::SALOME_Exception)
 {    
-  if (_subMeshDS==NULL)
+  if (_subMesh==NULL)
     THROW_SALOME_CORBA_EXCEPTION("No associated Family",\
-                                SALOME::INTERNAL_ERROR);
+                                 SALOME::INTERNAL_ERROR);
   MESSAGE("Les familles SMESH n ont pas d attribut");
   THROW_SALOME_CORBA_EXCEPTION("No attributes"\
-                              ,SALOME::BAD_PARAM);
+                               ,SALOME::BAD_PARAM);
   if (_numberOfAttribute == 0)
     {
       MESSAGE("Les familles SMESH n ont pas d attribut");
       THROW_SALOME_CORBA_EXCEPTION("No attributes"\
-                                  ,SALOME::BAD_PARAM);
+                                   ,SALOME::BAD_PARAM);
     };
   ASSERT (i <= _numberOfAttribute);
   return _attributeIdentifier[i];
@@ -175,21 +176,21 @@ CORBA::Long SMESH_MEDFamily_i::getAttributeIdentifier(CORBA::Long i)
  * CORBA: Accessor for attributes values
  */
 //=============================================================================
-SALOME_MED::long_array*  SMESH_MEDFamily_i::getAttributesValues() 
+SALOME_TYPES::ListOfLong*  SMESH_MEDFamily_i::getAttributesValues() 
   throw (SALOME::SALOME_Exception)
 {
-  if (_subMeshDS==NULL)
+  if (_subMesh==NULL)
     THROW_SALOME_CORBA_EXCEPTION("No associated Family",\
-                                SALOME::INTERNAL_ERROR);
+                                 SALOME::INTERNAL_ERROR);
 
   if (_numberOfAttribute == 0)
     {
       MESSAGE("Les familles SMESH n ont pas d attribut");
       THROW_SALOME_CORBA_EXCEPTION("No attributes"\
-                                  ,SALOME::BAD_PARAM);
+                                   ,SALOME::BAD_PARAM);
     };
 
-  SALOME_MED::long_array_var myseq= new SALOME_MED::long_array;
+  SALOME_TYPES::ListOfLong_var myseq= new SALOME_TYPES::ListOfLong;
   myseq->length(_numberOfAttribute);
   for (int i=0;i<_numberOfAttribute;i++)
     {
@@ -205,14 +206,14 @@ SALOME_MED::long_array*  SMESH_MEDFamily_i::getAttributesValues()
 CORBA::Long  SMESH_MEDFamily_i::getAttributeValue(CORBA::Long i) 
   throw (SALOME::SALOME_Exception)
 {   
-  if (_subMeshDS==NULL)
+  if (_subMesh==NULL)
     THROW_SALOME_CORBA_EXCEPTION("No associated Family",\
-                                SALOME::INTERNAL_ERROR);
+                                 SALOME::INTERNAL_ERROR);
   if (_numberOfAttribute == 0)
     {
       MESSAGE("Les familles SMESH n ont pas d attribut");
       THROW_SALOME_CORBA_EXCEPTION("No attributes"\
-                                  ,SALOME::BAD_PARAM);
+                                   ,SALOME::BAD_PARAM);
     }
 
   ASSERT (i <= _numberOfAttribute);
@@ -223,19 +224,19 @@ CORBA::Long  SMESH_MEDFamily_i::getAttributeValue(CORBA::Long i)
  * CORBA: Accessor for attributes desriptions
  */
 //=============================================================================
-SALOME_MED::string_array * SMESH_MEDFamily_i::getAttributesDescriptions() 
+SALOME_TYPES::ListOfString * SMESH_MEDFamily_i::getAttributesDescriptions() 
   throw (SALOME::SALOME_Exception)
 {
-  if (_subMeshDS==NULL)
+  if (_subMesh==NULL)
     THROW_SALOME_CORBA_EXCEPTION("No associated Family",\
-                                SALOME::INTERNAL_ERROR);
+                                 SALOME::INTERNAL_ERROR);
   if (_numberOfAttribute == 0)
     {
       MESSAGE("Les familles SMESH n ont pas d attribut");
       THROW_SALOME_CORBA_EXCEPTION("No attributes"\
-                                  ,SALOME::BAD_PARAM);
+                                   ,SALOME::BAD_PARAM);
     }
-  SALOME_MED::string_array_var myseq = new SALOME_MED::string_array;
+  SALOME_TYPES::ListOfString_var myseq = new SALOME_TYPES::ListOfString;
   for (int i=0;i<_numberOfAttribute;i++)
     {
       myseq[i]=CORBA::string_dup(_attributeDescription[i].c_str());
@@ -250,14 +251,14 @@ SALOME_MED::string_array * SMESH_MEDFamily_i::getAttributesDescriptions()
 char *  SMESH_MEDFamily_i::getAttributeDescription( CORBA::Long i) 
   throw (SALOME::SALOME_Exception)
 {   
-  if (_subMeshDS==NULL)
+  if (_subMesh==NULL)
     THROW_SALOME_CORBA_EXCEPTION("No associated Family",\
-                                SALOME::INTERNAL_ERROR);
+                                 SALOME::INTERNAL_ERROR);
   if (_numberOfAttribute == 0)
     {
       MESSAGE("Les familles SMESH n ont pas d attribut");
       THROW_SALOME_CORBA_EXCEPTION("No attributes"\
-                                  ,SALOME::BAD_PARAM);
+                                   ,SALOME::BAD_PARAM);
     }
   ASSERT (i <= _numberOfAttribute);
   return CORBA::string_dup(_attributeDescription[i].c_str());
@@ -291,7 +292,7 @@ char * SMESH_MEDFamily_i::getGroupName( CORBA::Long i)
  * CORBA: Accessor for all the groups name
  */
 //=============================================================================
-SALOME_MED::string_array* SMESH_MEDFamily_i::getGroupsNames()
+SALOME_TYPES::ListOfString* SMESH_MEDFamily_i::getGroupsNames()
   throw (SALOME::SALOME_Exception)
 {
   MESSAGE("!!! NOT YET IMPLEMENTED !!!!");
index 2b850fc8a5bca3818b26d9aa580e6a117286702d..c96df39c0ffa26a5c0c49b6d4c3e3f458e68ebf7 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : SMESH_MEDFamily_i.hxx
 //  Module : SMESH
@@ -56,7 +57,7 @@ public :
   
   // Constructors and associated internal methods
   SMESH_MEDFamily_i(int identifier, SMESH_subMesh_i* sm,
-                   std::string name, std::string description, SALOME_MED::medEntityMesh entity );
+                    std::string name, std::string description, SALOME_MED::medEntityMesh entity );
   SMESH_MEDFamily_i(const SMESH_MEDFamily_i & f);
   
   // IDL Methods
@@ -69,15 +70,15 @@ public :
     throw (SALOME::SALOME_Exception);
   CORBA::Long            getNumberOfAttributes() 
     throw (SALOME::SALOME_Exception);
-  SALOME_MED::long_array*   getAttributesIdentifiers() 
+  SALOME_TYPES::ListOfLong*   getAttributesIdentifiers() 
     throw (SALOME::SALOME_Exception);
   CORBA::Long            getAttributeIdentifier(CORBA::Long i) 
     throw (SALOME::SALOME_Exception);
-  SALOME_MED::long_array*   getAttributesValues() 
+  SALOME_TYPES::ListOfLong*   getAttributesValues() 
     throw (SALOME::SALOME_Exception);
   CORBA::Long            getAttributeValue(CORBA::Long i) 
     throw (SALOME::SALOME_Exception);
-  SALOME_MED::string_array* getAttributesDescriptions() 
+  SALOME_TYPES::ListOfString* getAttributesDescriptions() 
     throw (SALOME::SALOME_Exception);
   char*                  getAttributeDescription( CORBA::Long i) 
     throw (SALOME::SALOME_Exception);
@@ -85,7 +86,7 @@ public :
     throw (SALOME::SALOME_Exception);
   char *                    getGroupName( CORBA::Long i)
     throw (SALOME::SALOME_Exception);
-  SALOME_MED::string_array* getGroupsNames()
+  SALOME_TYPES::ListOfString* getGroupsNames()
     throw (SALOME::SALOME_Exception);  
 };
 #endif /* MED_FAMILY_I_HXX_ */
index 9ee46fda3c0c8b9b17b6e94f1e037aaed5c7c42c..823c8a037057165e95fc78d76e8bc43e8b4f76bd 100644 (file)
@@ -1,29 +1,31 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : SMESH_MEDMesh_i.cxx
 //  Module : SMESH
 //
 #include "SMESH_MEDMesh_i.hxx"
+#include "SMESH_Gen_i.hxx"
 #include "SMESH_Mesh_i.hxx"
 
 #include "SMESHDS_Mesh.hxx"
@@ -69,8 +71,8 @@ using namespace std;
 // PN Est-ce un const ?
 SMESH_MEDMesh_i::SMESH_MEDMesh_i()
 {
-       BEGIN_OF("Default Constructor SMESH_MEDMesh_i");
-       END_OF("Default Constructor SMESH_MEDMesh_i");
+  BEGIN_OF("Default Constructor SMESH_MEDMesh_i");
+  END_OF("Default Constructor SMESH_MEDMesh_i");
 }
 
 //=============================================================================
@@ -88,18 +90,18 @@ SMESH_MEDMesh_i::~SMESH_MEDMesh_i()
  */
 //=============================================================================
 SMESH_MEDMesh_i::SMESH_MEDMesh_i(::SMESH_Mesh_i * m_i):_meshId(""),
-                                                      _compte(false),
-                                                      _creeFamily(false),
-                                                      _famIdent(0),
-                                                      _indexElts(0),
-                                                      _indexEnts(0)
+                                                       _compte(false),
+                                                       _creeFamily(false),
+                                                       _famIdent(0),
+                                                       _indexElts(0),
+                                                       _indexEnts(0)
 {
-       BEGIN_OF("Constructor SMESH_MEDMesh_i");
+  BEGIN_OF("Constructor SMESH_MEDMesh_i");
 
-       _mesh_i = m_i;
-       _meshDS = _mesh_i->GetImpl().GetMeshDS();
+  _mesh_i = m_i;
+  _meshDS = _mesh_i->GetImpl().GetMeshDS();
 
-       END_OF("Constructor SMESH_MEDMesh_i");
+  END_OF("Constructor SMESH_MEDMesh_i");
 }
 
 //=============================================================================
@@ -109,22 +111,28 @@ SMESH_MEDMesh_i::SMESH_MEDMesh_i(::SMESH_Mesh_i * m_i):_meshId(""),
 //=============================================================================
 char *SMESH_MEDMesh_i::getName() throw(SALOME::SALOME_Exception)
 {
-       if (_meshDS == NULL)
-               THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
-                       SALOME::INTERNAL_ERROR);
-
-       try
-       {
-               // A COMPLETER PAR LE NOM DU MAILLAGE
-               //return CORBA::string_dup(_mesh_i->getName().c_str());
-               return CORBA::string_dup("toto");
-       }
-       catch(...)
-       {
-               MESSAGE("Exception en accedant au nom");
-               THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object",
-                       SALOME::INTERNAL_ERROR);
-       }
+  if (_meshDS == NULL)
+    THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
+                                 SALOME::INTERNAL_ERROR);
+
+  try
+  {
+    SMESH_Gen_i*             gen = SMESH_Gen_i::GetSMESHGen();
+    SALOMEDS::Study_var    study = gen->GetCurrentStudy();
+    SALOMEDS::SObject_var meshSO = gen->ObjectToSObject( study, _mesh_i->_this());
+    if ( meshSO->_is_nil() )
+      return CORBA::string_dup("toto");
+
+    CORBA::String_var name = meshSO->GetName();
+    return CORBA::string_dup( name.in() );
+  }
+  catch(...)
+  {
+    MESSAGE("Exception en accedant au nom");
+    THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object",
+                                 SALOME::INTERNAL_ERROR);
+  }
+  return 0;
 }
 
 //=============================================================================
@@ -134,8 +142,8 @@ char *SMESH_MEDMesh_i::getName() throw(SALOME::SALOME_Exception)
 //=============================================================================
 CORBA::Long SMESH_MEDMesh_i::getCorbaIndex()throw(SALOME::SALOME_Exception)
 {
-       MESSAGE("Non Implemente");
-       THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
+  MESSAGE("Non Implemente");
+  THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
 }
 
 //=============================================================================
@@ -145,11 +153,11 @@ CORBA::Long SMESH_MEDMesh_i::getCorbaIndex()throw(SALOME::SALOME_Exception)
 //=============================================================================
 CORBA::Long SMESH_MEDMesh_i::getSpaceDimension()throw(SALOME::SALOME_Exception)
 {
-       // PN : Il semblerait que la dimension soit fixee a 3
-       if (_mesh_i == 0)
-               THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
-                       SALOME::INTERNAL_ERROR);
-       return 3;
+  // PN : Il semblerait que la dimension soit fixee a 3
+  if (_mesh_i == 0)
+    THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
+                                 SALOME::INTERNAL_ERROR);
+  return 3;
 }
 
 //=============================================================================
@@ -159,14 +167,14 @@ CORBA::Long SMESH_MEDMesh_i::getSpaceDimension()throw(SALOME::SALOME_Exception)
 //=============================================================================
 CORBA::Long SMESH_MEDMesh_i::getMeshDimension()throw(SALOME::SALOME_Exception)
 {
-       if (_mesh_i == 0)
-               THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
-                       SALOME::INTERNAL_ERROR);
-       // PN : Il semblerait que la dimension soit fixee a 3
-       if (_mesh_i == 0)
-               THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
-                       SALOME::INTERNAL_ERROR);
-       return 3;
+  if (_mesh_i == 0)
+    THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
+                                 SALOME::INTERNAL_ERROR);
+  // PN : Il semblerait que la dimension soit fixee a 3
+  if (_mesh_i == 0)
+    THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
+                                 SALOME::INTERNAL_ERROR);
+  return 3;
 }
 //=============================================================================
 /*!
@@ -188,7 +196,7 @@ CORBA::Boolean SMESH_MEDMesh_i::getIsAGrid() throw (SALOME::SALOME_Exception)
 //=============================================================================
 CORBA::Boolean
 SMESH_MEDMesh_i::existConnectivity(SALOME_MED::medConnectivity connectivityType,
-                                  SALOME_MED::medEntityMesh entity)
+                                   SALOME_MED::medEntityMesh entity)
   throw (SALOME::SALOME_Exception)
 {
   MESSAGE("!!!!!! IMPLEMENTED BUT ONLY PARTIALLY !!!!!!");
@@ -218,21 +226,21 @@ CORBA::Double SMESH_MEDMesh_i::getCoordinate(CORBA::Long Number, CORBA::Long Axi
 //=============================================================================
 char *SMESH_MEDMesh_i::getCoordinatesSystem() throw(SALOME::SALOME_Exception)
 {
-       if (_mesh_i == 0)
-               THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
-                       SALOME::INTERNAL_ERROR);
-       // PN : En dur. Non encore prevu
-       try
-       {
-               string systcoo = "CARTESIEN";
-               return CORBA::string_dup(systcoo.c_str());
-       }
-       catch(...)
-       {
-               MESSAGE("Exception en accedant au maillage");
-               THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object",
-                       SALOME::INTERNAL_ERROR);
-       }
+  if (_mesh_i == 0)
+    THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
+                                 SALOME::INTERNAL_ERROR);
+  // PN : En dur. Non encore prevu
+  try
+  {
+    string systcoo = "CARTESIEN";
+    return CORBA::string_dup(systcoo.c_str());
+  }
+  catch(...)
+  {
+    MESSAGE("Exception en accedant au maillage");
+    THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object",
+                                 SALOME::INTERNAL_ERROR);
+  }
 }
 
 //=============================================================================
@@ -240,56 +248,56 @@ char *SMESH_MEDMesh_i::getCoordinatesSystem() throw(SALOME::SALOME_Exception)
  * CORBA: Accessor for Coordinates
  */
 //=============================================================================
-SALOME_MED::double_array * SMESH_MEDMesh_i::getCoordinates(
-       SALOME_MED::medModeSwitch typeSwitch) throw(SALOME::SALOME_Exception)
+SALOME_TYPES::ListOfDouble * SMESH_MEDMesh_i::getCoordinates
+(SALOME_MED::medModeSwitch typeSwitch) throw(SALOME::SALOME_Exception)
 {
-       if (_mesh_i == 0)
-               THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
-                       SALOME::INTERNAL_ERROR);
-       SALOME_MED::double_array_var myseq = new SALOME_MED::double_array;
-       try
-       {
-               // PN  : En dur
-               int spaceDimension = 3;
-               int nbNodes = _meshDS->NbNodes();
-               SCRUTE(nbNodes);
-               myseq->length(nbNodes * spaceDimension);
-               int i = 0;
-
-               SMDS_NodeIteratorPtr itNodes=_meshDS->nodesIterator();
-               while(itNodes->more())
-               {
-                       const SMDS_MeshNode* node = itNodes->next();
-
-                       if (typeSwitch == SALOME_MED::MED_FULL_INTERLACE)
-                       {
-                               myseq[i * 3] = node->X();
-                               myseq[i * 3 + 1] = node->Y();
-                               myseq[i * 3 + 2] = node->Z();
-                               SCRUTE(myseq[i * 3]);
-                               SCRUTE(myseq[i * 3 + 1]);
-                               SCRUTE(myseq[i * 3 + 2]);
-                       }
-                       else
-                       {
-                               ASSERT(typeSwitch == SALOME_MED::MED_NO_INTERLACE);
-                               myseq[i] = node->X();
-                               myseq[i + nbNodes] = node->Y();
-                               myseq[i + (nbNodes * 2)] = node->Z();
-                               SCRUTE(myseq[i]);
-                               SCRUTE(myseq[i + nbNodes]);
-                               SCRUTE(myseq[i + (nbNodes * 2)]);
-                       }
-                       i++;
-               }
-       }
-       catch(...)
-       {
-               MESSAGE("Exception en accedant aux coordonnees");
-               THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object",
-                       SALOME::INTERNAL_ERROR);
-       }
-       return myseq._retn();
+  if (_mesh_i == 0)
+    THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
+                                 SALOME::INTERNAL_ERROR);
+  SALOME_TYPES::ListOfDouble_var myseq = new SALOME_TYPES::ListOfDouble;
+  try
+  {
+    // PN  : En dur
+    int spaceDimension = 3;
+    int nbNodes = _meshDS->NbNodes();
+    SCRUTE(nbNodes);
+    myseq->length(nbNodes * spaceDimension);
+    int i = 0;
+
+    SMDS_NodeIteratorPtr itNodes=_meshDS->nodesIterator();
+    while(itNodes->more())
+    {
+      const SMDS_MeshNode* node = itNodes->next();
+
+      if (typeSwitch == SALOME_MED::MED_FULL_INTERLACE)
+      {
+        myseq[i * 3] = node->X();
+        myseq[i * 3 + 1] = node->Y();
+        myseq[i * 3 + 2] = node->Z();
+        SCRUTE(myseq[i * 3]);
+        SCRUTE(myseq[i * 3 + 1]);
+        SCRUTE(myseq[i * 3 + 2]);
+      }
+      else
+      {
+        ASSERT(typeSwitch == SALOME_MED::MED_NO_INTERLACE);
+        myseq[i] = node->X();
+        myseq[i + nbNodes] = node->Y();
+        myseq[i + (nbNodes * 2)] = node->Z();
+        SCRUTE(myseq[i]);
+        SCRUTE(myseq[i + nbNodes]);
+        SCRUTE(myseq[i + (nbNodes * 2)]);
+      }
+      i++;
+    }
+  }
+  catch(...)
+  {
+    MESSAGE("Exception en accedant aux coordonnees");
+    THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object",
+                                 SALOME::INTERNAL_ERROR);
+  }
+  return myseq._retn();
 }
 
 //=============================================================================
@@ -297,29 +305,29 @@ SALOME_MED::double_array * SMESH_MEDMesh_i::getCoordinates(
  * CORBA: Accessor for Coordinates Names
  */
 //=============================================================================
-SALOME_MED::string_array *
-       SMESH_MEDMesh_i::getCoordinatesNames()throw(SALOME::SALOME_Exception)
+SALOME_TYPES::ListOfString *
+SMESH_MEDMesh_i::getCoordinatesNames()throw(SALOME::SALOME_Exception)
 {
-       if (_mesh_i == 0)
-               THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
-                       SALOME::INTERNAL_ERROR);
-       SALOME_MED::string_array_var myseq = new SALOME_MED::string_array;
-       try
-       {
-               // PN : en dur
-               int spaceDimension = 3;
-               myseq->length(spaceDimension);
-               myseq[0] = CORBA::string_dup("x");
-               myseq[1] = CORBA::string_dup("y");
-               myseq[2] = CORBA::string_dup("z");
-       }
-       catch(...)
-       {
-               MESSAGE("Exception en accedant aux noms des coordonnees");
-               THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object",
-                       SALOME::INTERNAL_ERROR);
-       }
-       return myseq._retn();
+  if (_mesh_i == 0)
+    THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
+                                 SALOME::INTERNAL_ERROR);
+  SALOME_TYPES::ListOfString_var myseq = new SALOME_TYPES::ListOfString;
+  try
+  {
+    // PN : en dur
+    int spaceDimension = 3;
+    myseq->length(spaceDimension);
+    myseq[0] = CORBA::string_dup("x");
+    myseq[1] = CORBA::string_dup("y");
+    myseq[2] = CORBA::string_dup("z");
+  }
+  catch(...)
+  {
+    MESSAGE("Exception en accedant aux noms des coordonnees");
+    THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object",
+                                 SALOME::INTERNAL_ERROR);
+  }
+  return myseq._retn();
 
 }
 
@@ -328,29 +336,29 @@ SALOME_MED::string_array *
  * CORBA: Accessor for Coordinates Units
  */
 //=============================================================================
-SALOME_MED::string_array *
-       SMESH_MEDMesh_i::getCoordinatesUnits()throw(SALOME::SALOME_Exception)
+SALOME_TYPES::ListOfString *
+SMESH_MEDMesh_i::getCoordinatesUnits()throw(SALOME::SALOME_Exception)
 {
-       if (_mesh_i == 0)
-               THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
-                       SALOME::INTERNAL_ERROR);
-       SALOME_MED::string_array_var myseq = new SALOME_MED::string_array;
-       try
-       {
-               // PN : en dur
-               int spaceDimension = 3;
-               myseq->length(spaceDimension);
-               myseq[0] = CORBA::string_dup("m");
-               myseq[1] = CORBA::string_dup("m");
-               myseq[2] = CORBA::string_dup("m");
-       }
-       catch(...)
-       {
-               MESSAGE("Exception en accedant aux unites des coordonnees");
-               THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object",
-                       SALOME::INTERNAL_ERROR);
-       }
-       return myseq._retn();
+  if (_mesh_i == 0)
+    THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
+                                 SALOME::INTERNAL_ERROR);
+  SALOME_TYPES::ListOfString_var myseq = new SALOME_TYPES::ListOfString;
+  try
+  {
+    // PN : en dur
+    int spaceDimension = 3;
+    myseq->length(spaceDimension);
+    myseq[0] = CORBA::string_dup("m");
+    myseq[1] = CORBA::string_dup("m");
+    myseq[2] = CORBA::string_dup("m");
+  }
+  catch(...)
+  {
+    MESSAGE("Exception en accedant aux unites des coordonnees");
+    THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object",
+                                 SALOME::INTERNAL_ERROR);
+  }
+  return myseq._retn();
 }
 
 //=============================================================================
@@ -360,19 +368,19 @@ SALOME_MED::string_array *
 //=============================================================================
 CORBA::Long SMESH_MEDMesh_i::getNumberOfNodes()throw(SALOME::SALOME_Exception)
 {
-       if (_mesh_i == 0)
-               THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
-                       SALOME::INTERNAL_ERROR);
-       try
-       {
-               return _meshDS->NbNodes();
-       }
-       catch(...)
-       {
-               MESSAGE("Exception en accedant au nombre de noeuds");
-               THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object",
-                       SALOME::INTERNAL_ERROR);
-       }
+  if (_mesh_i == 0)
+    THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
+                                 SALOME::INTERNAL_ERROR);
+  try
+  {
+    return _meshDS->NbNodes();
+  }
+  catch(...)
+  {
+    MESSAGE("Exception en accedant au nombre de noeuds");
+    THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object",
+                                 SALOME::INTERNAL_ERROR);
+  }
 }
 
 //=============================================================================
@@ -381,119 +389,119 @@ CORBA::Long SMESH_MEDMesh_i::getNumberOfNodes()throw(SALOME::SALOME_Exception)
  */
 //=============================================================================
 CORBA::Long SMESH_MEDMesh_i::getNumberOfTypes(SALOME_MED::medEntityMesh entity)
-throw(SALOME::SALOME_Exception)
+  throw(SALOME::SALOME_Exception)
 {
-       if (_mesh_i == 0)
-               THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
-                       SALOME::INTERNAL_ERROR);
-       try
-       {
-               if (!_compte)
-                       calculeNbElts();
-               int retour = 0;
-               if (_mapNbTypes.find(entity) != _mapNbTypes.end())
-                       retour = _mapNbTypes[entity];
-               return retour;
-       }
-       catch(...)
-       {
-               MESSAGE("Exception en accedant au nombre de Types");
-               THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object",
-                       SALOME::INTERNAL_ERROR);
-       }
+  if (_mesh_i == 0)
+    THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
+                                 SALOME::INTERNAL_ERROR);
+  try
+  {
+    if (!_compte)
+      calculeNbElts();
+    int retour = 0;
+    if (_mapNbTypes.find(entity) != _mapNbTypes.end())
+      retour = _mapNbTypes[entity];
+    return retour;
+  }
+  catch(...)
+  {
+    MESSAGE("Exception en accedant au nombre de Types");
+    THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object",
+                                 SALOME::INTERNAL_ERROR);
+  }
 }
 
 //=============================================================================
 /*!
  * CORBA: Accessor for existing geometry element types 
- *       Not implemented for MED_ALL_ENTITIES
+ *        Not implemented for MED_ALL_ENTITIES
  */
 //=============================================================================
 SALOME_MED::medGeometryElement_array *
-       SMESH_MEDMesh_i::getTypes(SALOME_MED::medEntityMesh entity) throw(SALOME::
-       SALOME_Exception)
+SMESH_MEDMesh_i::getTypes(SALOME_MED::medEntityMesh entity) throw(SALOME::
+                                                                  SALOME_Exception)
 {
-       if (_mesh_i == 0)
-               THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
-                       SALOME::INTERNAL_ERROR);
-       if (entity == SALOME_MED::MED_ALL_ENTITIES)
-               THROW_SALOME_CORBA_EXCEPTION("Not implemented for MED_ALL_ENTITIES",
-                       SALOME::BAD_PARAM);
-       if (!_compte)
-               calculeNbElts();
-       SALOME_MED::medGeometryElement_array_var myseq =
-               new SALOME_MED::medGeometryElement_array;
-       try
-       {
-               if (_mapNbTypes.find(entity) == _mapNbTypes.end())
-                       THROW_SALOME_CORBA_EXCEPTION("No Such Entity in the mesh",
-                               SALOME::BAD_PARAM);
-               int nbTypes = _mapNbTypes[entity];
-
-               myseq->length(nbTypes);
-
-               if (_mapIndToVectTypes.find(entity) == _mapIndToVectTypes.end())
-                       THROW_SALOME_CORBA_EXCEPTION("No Such Entity in the mesh",
-                               SALOME::INTERNAL_ERROR);
-
-               int index = _mapIndToVectTypes[entity];
-               ASSERT(_TypesId[index].size() != 0);
-               int i = 0;
-               vector < SALOME_MED::medGeometryElement >::iterator it;
-               for (it = _TypesId[index].begin(); it != _TypesId[index].end(); it++)
-               {
-                       myseq[i++] = *it;
-               };
-       }
-       catch(...)
-       {
-               MESSAGE("Exception en accedant aux differents types");
-               THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object",
-                       SALOME::INTERNAL_ERROR);
-       }
-       return myseq._retn();
+  if (_mesh_i == 0)
+    THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
+                                 SALOME::INTERNAL_ERROR);
+  if (entity == SALOME_MED::MED_ALL_ENTITIES)
+    THROW_SALOME_CORBA_EXCEPTION("Not implemented for MED_ALL_ENTITIES",
+                                 SALOME::BAD_PARAM);
+  if (!_compte)
+    calculeNbElts();
+  SALOME_MED::medGeometryElement_array_var myseq =
+    new SALOME_MED::medGeometryElement_array;
+  try
+  {
+    if (_mapNbTypes.find(entity) == _mapNbTypes.end())
+      THROW_SALOME_CORBA_EXCEPTION("No Such Entity in the mesh",
+                                   SALOME::BAD_PARAM);
+    int nbTypes = _mapNbTypes[entity];
+
+    myseq->length(nbTypes);
+
+    if (_mapIndToVectTypes.find(entity) == _mapIndToVectTypes.end())
+      THROW_SALOME_CORBA_EXCEPTION("No Such Entity in the mesh",
+                                   SALOME::INTERNAL_ERROR);
+
+    int index = _mapIndToVectTypes[entity];
+    ASSERT(_TypesId[index].size() != 0);
+    int i = 0;
+    vector < SALOME_MED::medGeometryElement >::iterator it;
+    for (it = _TypesId[index].begin(); it != _TypesId[index].end(); it++)
+    {
+      myseq[i++] = *it;
+    };
+  }
+  catch(...)
+  {
+    MESSAGE("Exception en accedant aux differents types");
+    THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object",
+                                 SALOME::INTERNAL_ERROR);
+  }
+  return myseq._retn();
 }
 
 //=============================================================================
 /*!
  * CORBA: Returns number of elements of type medGeometryElement
- *       Not implemented for MED_ALL_ELEMENTS 
- *       implemented for MED_ALL_ENTITIES
+ *        Not implemented for MED_ALL_ELEMENTS 
+ *        implemented for MED_ALL_ENTITIES
  *
  * Dans cette implementation, il n est pas prevu de tenir compte du entity
  * qui ne doit pas pouvoir avoir deux valeurs differentes pour un geomElement 
  */
 //=============================================================================
 CORBA::Long SMESH_MEDMesh_i::getNumberOfElements(SALOME_MED::
-       medEntityMesh entity,
-       SALOME_MED::medGeometryElement geomElement) throw(SALOME::SALOME_Exception)
+                                                 medEntityMesh entity,
+                                                 SALOME_MED::medGeometryElement geomElement) throw(SALOME::SALOME_Exception)
 {
-       if (_mesh_i == 0)
-               THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
-                       SALOME::INTERNAL_ERROR);
-       if (geomElement == SALOME_MED::MED_ALL_ELEMENTS)
-               THROW_SALOME_CORBA_EXCEPTION("Not implemented for MED_ALL_ELEMENTS",
-                       SALOME::BAD_PARAM);
-       if (!_compte)
-               calculeNbElts();
-
-       try
-       {
-               int retour = 0;
-               if (_mapIndToSeqElts.find(geomElement) != _mapIndToSeqElts.end())
-               {
-                       int index = _mapIndToSeqElts[geomElement];
-
-                       retour = _seq_elemId[index]->length();
-               }
-               return retour;
-       }
-       catch(...)
-       {
-               MESSAGE("Exception en accedant au nombre d Ã©lements");
-               THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object",
-                       SALOME::INTERNAL_ERROR);
-       }
+  if (_mesh_i == 0)
+    THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
+                                 SALOME::INTERNAL_ERROR);
+  if (geomElement == SALOME_MED::MED_ALL_ELEMENTS)
+    THROW_SALOME_CORBA_EXCEPTION("Not implemented for MED_ALL_ELEMENTS",
+                                 SALOME::BAD_PARAM);
+  if (!_compte)
+    calculeNbElts();
+
+  try
+  {
+    int retour = 0;
+    if (_mapIndToSeqElts.find(geomElement) != _mapIndToSeqElts.end())
+    {
+      int index = _mapIndToSeqElts[geomElement];
+
+      retour = _seq_elemId[index]->length();
+    }
+    return retour;
+  }
+  catch(...)
+  {
+    MESSAGE("Exception en accedant au nombre d Ã©lements");
+    THROW_SALOME_CORBA_EXCEPTION("Unable to acces Mesh C++ Object",
+                                 SALOME::INTERNAL_ERROR);
+  }
 }
 
 //=============================================================================
@@ -501,31 +509,30 @@ CORBA::Long SMESH_MEDMesh_i::getNumberOfElements(SALOME_MED::
  * CORBA: Accessor for connectivities
  */
 //=============================================================================
-SALOME_MED::long_array *
-SMESH_MEDMesh_i::getConnectivity(SALOME_MED::medModeSwitch typeSwitch,
-                                SALOME_MED::medConnectivity mode,
-                                SALOME_MED::medEntityMesh entity,
-                                SALOME_MED::medGeometryElement geomElement)
+SALOME_TYPES::ListOfLong *
+SMESH_MEDMesh_i::getConnectivity(SALOME_MED::medConnectivity mode,
+                                 SALOME_MED::medEntityMesh entity,
+                                 SALOME_MED::medGeometryElement geomElement)
   throw(SALOME::SALOME_Exception)
 {
-       if (_mesh_i == 0)
-               THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
-                       SALOME::INTERNAL_ERROR);
-       if (mode != SALOME_MED::MED_NODAL)
-               THROW_SALOME_CORBA_EXCEPTION("Not Implemented", SALOME::BAD_PARAM);
-       if (typeSwitch == SALOME_MED::MED_NO_INTERLACE)
-               THROW_SALOME_CORBA_EXCEPTION("Not Yet Implemented", SALOME::BAD_PARAM);
-       if (!_compte)
-               calculeNbElts();
-
-       // Faut-il renvoyer un pointeur vide ???
-       if (_mapIndToSeqElts.find(geomElement) != _mapIndToSeqElts.end())
-               THROW_SALOME_CORBA_EXCEPTION("No Such Element in the mesh",
-                       SALOME::BAD_PARAM);
-
-       int index = _mapIndToSeqElts[geomElement];
-
-       return _seq_elemId[index]._retn();
+  if (_mesh_i == 0)
+    THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
+                                 SALOME::INTERNAL_ERROR);
+  if (mode != SALOME_MED::MED_NODAL)
+    THROW_SALOME_CORBA_EXCEPTION("Not Implemented", SALOME::BAD_PARAM);
+  /*if (typeSwitch == SALOME_MED::MED_NO_INTERLACE)
+    THROW_SALOME_CORBA_EXCEPTION("Not Yet Implemented", SALOME::BAD_PARAM);*/
+  if (!_compte)
+    calculeNbElts();
+
+  // Faut-il renvoyer un pointeur vide ???
+  if (_mapIndToSeqElts.find(geomElement) != _mapIndToSeqElts.end())
+    THROW_SALOME_CORBA_EXCEPTION("No Such Element in the mesh",
+                                 SALOME::BAD_PARAM);
+
+  int index = _mapIndToSeqElts[geomElement];
+
+  return _seq_elemId[index]._retn();
 }
 
 //=============================================================================
@@ -533,14 +540,14 @@ SMESH_MEDMesh_i::getConnectivity(SALOME_MED::medModeSwitch typeSwitch,
  * CORBA: Accessor for connectivities
  */
 //=============================================================================
-SALOME_MED::long_array *
+SALOME_TYPES::ListOfLong *
 SMESH_MEDMesh_i::getConnectivityIndex(SALOME_MED::medConnectivity mode,
-                                     SALOME_MED::medEntityMesh entity)
+                                      SALOME_MED::medEntityMesh entity)
   throw(SALOME::SALOME_Exception)
 {
-       MESSAGE("Pas Implemente dans SMESH");
-       THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
-       return 0;
+  MESSAGE("Pas Implemente dans SMESH");
+  THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
+  return 0;
 }
 
 //=============================================================================
@@ -550,15 +557,15 @@ SMESH_MEDMesh_i::getConnectivityIndex(SALOME_MED::medConnectivity mode,
 //=============================================================================
 CORBA::Long
 SMESH_MEDMesh_i::getElementNumber(SALOME_MED::medConnectivity mode,
-                                 SALOME_MED::medEntityMesh entity,
-                                 SALOME_MED::medGeometryElement type,
-                                 const SALOME_MED::long_array & connectivity)
+                                  SALOME_MED::medEntityMesh entity,
+                                  SALOME_MED::medGeometryElement type,
+                                  const SALOME_TYPES::ListOfLong & connectivity)
   throw(SALOME::SALOME_Exception)
 {
-       const char *LOC = "getElementNumber ";
-       MESSAGE(LOC << "Pas Implemente dans SMESH");
-       THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
-       return -1;
+  const char *LOC = "getElementNumber ";
+  MESSAGE(LOC << "Pas Implemente dans SMESH");
+  THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
+  return -1;
 }
 
 //=============================================================================
@@ -567,13 +574,13 @@ SMESH_MEDMesh_i::getElementNumber(SALOME_MED::medConnectivity mode,
  * not implemented for MED_ALL_ENTITIES and MED_MAILLE
  */
 //=============================================================================
-SALOME_MED::long_array *
-       SMESH_MEDMesh_i::getReverseConnectivity(SALOME_MED::
-       medConnectivity mode) throw(SALOME::SALOME_Exception)
+SALOME_TYPES::ListOfLong *
+SMESH_MEDMesh_i::getReverseConnectivity(SALOME_MED::
+                                        medConnectivity mode) throw(SALOME::SALOME_Exception)
 {
-       MESSAGE("Pas Implemente dans SMESH");
-       THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
-       return 0;
+  MESSAGE("Pas Implemente dans SMESH");
+  THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
+  return 0;
 }
 
 //=============================================================================
@@ -581,13 +588,13 @@ SALOME_MED::long_array *
  * CORBA: Accessor for connectivities
  */
 //=============================================================================
-SALOME_MED::long_array *
-       SMESH_MEDMesh_i::getReverseConnectivityIndex(SALOME_MED::
-       medConnectivity mode) throw(SALOME::SALOME_Exception)
+SALOME_TYPES::ListOfLong *
+SMESH_MEDMesh_i::getReverseConnectivityIndex(SALOME_MED::
+                                             medConnectivity mode) throw(SALOME::SALOME_Exception)
 {
-       MESSAGE("Pas Implemente dans SMESH");
-       THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
-       return 0;
+  MESSAGE("Pas Implemente dans SMESH");
+  THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
+  return 0;
 }
 
 //=============================================================================
@@ -596,14 +603,14 @@ SALOME_MED::long_array *
  */
 //=============================================================================
 CORBA::Long SMESH_MEDMesh_i::getNumberOfFamilies(SALOME_MED::
-       medEntityMesh entity) throw(SALOME::SALOME_Exception)
+                                                 medEntityMesh entity) throw(SALOME::SALOME_Exception)
 {
-       if (_creeFamily == false)
-               createFamilies();
-       if (_mesh_i == 0)
-               THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
-                       SALOME::INTERNAL_ERROR);
-       return _families.size();
+  if (_creeFamily == false)
+    createFamilies();
+  if (_mesh_i == 0)
+    THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
+                                 SALOME::INTERNAL_ERROR);
+  return _families.size();
 }
 
 //=============================================================================
@@ -612,13 +619,13 @@ CORBA::Long SMESH_MEDMesh_i::getNumberOfFamilies(SALOME_MED::
  */
 //=============================================================================
 CORBA::Long SMESH_MEDMesh_i::getNumberOfGroups(SALOME_MED::medEntityMesh entity)
-throw(SALOME::SALOME_Exception)
+  throw(SALOME::SALOME_Exception)
 {
-       if (_mesh_i == 0)
-               THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
-                       SALOME::INTERNAL_ERROR);
-       MESSAGE(" Pas d implementation des groupes dans SMESH");
-       return 0;
+  if (_mesh_i == 0)
+    THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
+                                 SALOME::INTERNAL_ERROR);
+  MESSAGE(" Pas d implementation des groupes dans SMESH");
+  return 0;
 }
 
 //=============================================================================
@@ -627,24 +634,24 @@ throw(SALOME::SALOME_Exception)
  */
 //=============================================================================
 SALOME_MED::Family_array *
-       SMESH_MEDMesh_i::getFamilies(SALOME_MED::
-       medEntityMesh entity) throw(SALOME::SALOME_Exception)
+SMESH_MEDMesh_i::getFamilies(SALOME_MED::
+                             medEntityMesh entity) throw(SALOME::SALOME_Exception)
 {
-       if (_creeFamily == false)
-               createFamilies();
-       if (_mesh_i == 0)
-               THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
-                       SALOME::INTERNAL_ERROR);
-       SALOME_MED::Family_array_var myseq = new SALOME_MED::Family_array;
-       int nbfam = _families.size();
-       myseq->length(nbfam);
-       int i = 0;
-       vector < SALOME_MED::FAMILY_ptr >::iterator it;
-       for (it = _families.begin(); it != _families.end(); it++)
-       {
-               myseq[i++] = *it;
-       };
-       return myseq._retn();
+  if (_creeFamily == false)
+    createFamilies();
+  if (_mesh_i == 0)
+    THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
+                                 SALOME::INTERNAL_ERROR);
+  SALOME_MED::Family_array_var myseq = new SALOME_MED::Family_array;
+  int nbfam = _families.size();
+  myseq->length(nbfam);
+  int i = 0;
+  vector < SALOME_MED::FAMILY_ptr >::iterator it;
+  for (it = _families.begin(); it != _families.end(); it++)
+  {
+    myseq[i++] = *it;
+  };
+  return myseq._retn();
 }
 
 //=============================================================================
@@ -653,16 +660,16 @@ SALOME_MED::Family_array *
  */
 //=============================================================================
 SALOME_MED::FAMILY_ptr SMESH_MEDMesh_i::getFamily(SALOME_MED::
-       medEntityMesh entity, CORBA::Long i) throw(SALOME::SALOME_Exception)
+                                                  medEntityMesh entity, CORBA::Long i) throw(SALOME::SALOME_Exception)
 {
-       if (_creeFamily == false)
-               createFamilies();
-       if (_mesh_i == 0)
-               THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
-                       SALOME::INTERNAL_ERROR);
-
-       SCRUTE(_families[i]->getName());
-       MESSAGE(" SMESH_MEDMesh_i::getFamily " << i) return _families[i];
+  if (_creeFamily == false)
+    createFamilies();
+  if (_mesh_i == 0)
+    THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
+                                 SALOME::INTERNAL_ERROR);
+
+  SCRUTE(_families[i]->getName());
+  MESSAGE(" SMESH_MEDMesh_i::getFamily " << i) return _families[i];
 }
 
 //=============================================================================
@@ -671,14 +678,14 @@ SALOME_MED::FAMILY_ptr SMESH_MEDMesh_i::getFamily(SALOME_MED::
  */
 //=============================================================================
 SALOME_MED::Group_array *
-       SMESH_MEDMesh_i::getGroups(SALOME_MED::medEntityMesh entity) throw(SALOME::
-       SALOME_Exception)
+SMESH_MEDMesh_i::getGroups(SALOME_MED::medEntityMesh entity) throw(SALOME::
+                                                                   SALOME_Exception)
 {
-       if (_mesh_i == 0)
-               THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
-                       SALOME::INTERNAL_ERROR);
-       MESSAGE(" Pas d implementation des groupes dans SMESH");
-       THROW_SALOME_CORBA_EXCEPTION("No group implementation", SALOME::BAD_PARAM);
+  if (_mesh_i == 0)
+    THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
+                                 SALOME::INTERNAL_ERROR);
+  MESSAGE(" Pas d implementation des groupes dans SMESH");
+  THROW_SALOME_CORBA_EXCEPTION("No group implementation", SALOME::BAD_PARAM);
 }
 
 //=============================================================================
@@ -687,20 +694,20 @@ SALOME_MED::Group_array *
  */
 //=============================================================================
 SALOME_MED::GROUP_ptr SMESH_MEDMesh_i::getGroup(SALOME_MED::
-       medEntityMesh entity, CORBA::Long i) throw(SALOME::SALOME_Exception)
+                                                medEntityMesh entity, CORBA::Long i) throw(SALOME::SALOME_Exception)
 {
-       if (_mesh_i == 0)
-               THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
-                       SALOME::INTERNAL_ERROR);
-       MESSAGE(" Pas d implementation des groupes dans SMESH");
-       THROW_SALOME_CORBA_EXCEPTION("No group implementation", SALOME::BAD_PARAM);
+  if (_mesh_i == 0)
+    THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
+                                 SALOME::INTERNAL_ERROR);
+  MESSAGE(" Pas d implementation des groupes dans SMESH");
+  THROW_SALOME_CORBA_EXCEPTION("No group implementation", SALOME::BAD_PARAM);
 }
 //=============================================================================
 /*!
  * CORBA: Returns references for the global numbering index
  */
 //=============================================================================
-SALOME_MED::long_array*
+SALOME_TYPES::ListOfLong*
 SMESH_MEDMesh_i::getGlobalNumberingIndex(SALOME_MED::medEntityMesh entity)
   throw (SALOME::SALOME_Exception)
 {
@@ -764,11 +771,11 @@ SMESH_MEDMesh_i::getSkin(SALOME_MED::SUPPORT_ptr mySupport3D)
  */
 //=============================================================================
 SALOME_MED::FIELD_ptr SMESH_MEDMesh_i::getVolume(SALOME_MED::
-       SUPPORT_ptr mySupport) throw(SALOME::SALOME_Exception)
+                                                 SUPPORT_ptr mySupport) throw(SALOME::SALOME_Exception)
 {
-       MESSAGE("Pas Implemente dans SMESH");
-       THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
-       return 0;
+  MESSAGE("Pas Implemente dans SMESH");
+  THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
+  return 0;
 }
 
 //=============================================================================
@@ -777,11 +784,11 @@ SALOME_MED::FIELD_ptr SMESH_MEDMesh_i::getVolume(SALOME_MED::
  */
 //=============================================================================
 SALOME_MED::FIELD_ptr SMESH_MEDMesh_i::getArea(SALOME_MED::
-       SUPPORT_ptr mySupport) throw(SALOME::SALOME_Exception)
+                                               SUPPORT_ptr mySupport) throw(SALOME::SALOME_Exception)
 {
-       MESSAGE("Pas Implemente dans SMESH");
-       THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
-       return 0;
+  MESSAGE("Pas Implemente dans SMESH");
+  THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
+  return 0;
 }
 
 //=============================================================================
@@ -790,11 +797,11 @@ SALOME_MED::FIELD_ptr SMESH_MEDMesh_i::getArea(SALOME_MED::
  */
 //=============================================================================
 SALOME_MED::FIELD_ptr SMESH_MEDMesh_i::getLength(SALOME_MED::
-       SUPPORT_ptr mySupport) throw(SALOME::SALOME_Exception)
+                                                 SUPPORT_ptr mySupport) throw(SALOME::SALOME_Exception)
 {
-       MESSAGE("Pas Implemente dans SMESH");
-       THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
-       return 0;
+  MESSAGE("Pas Implemente dans SMESH");
+  THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
+  return 0;
 }
 
 //=============================================================================
@@ -803,11 +810,11 @@ SALOME_MED::FIELD_ptr SMESH_MEDMesh_i::getLength(SALOME_MED::
  */
 //=============================================================================
 SALOME_MED::FIELD_ptr SMESH_MEDMesh_i::getNormal(SALOME_MED::
-       SUPPORT_ptr mySupport) throw(SALOME::SALOME_Exception)
+                                                 SUPPORT_ptr mySupport) throw(SALOME::SALOME_Exception)
 {
-       MESSAGE("Pas Implemente dans SMESH");
-       THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
-       return 0;
+  MESSAGE("Pas Implemente dans SMESH");
+  THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
+  return 0;
 }
 
 //=============================================================================
@@ -816,11 +823,11 @@ SALOME_MED::FIELD_ptr SMESH_MEDMesh_i::getNormal(SALOME_MED::
  */
 //=============================================================================
 SALOME_MED::FIELD_ptr SMESH_MEDMesh_i::getBarycenter(SALOME_MED::
-       SUPPORT_ptr mySupport) throw(SALOME::SALOME_Exception)
+                                                     SUPPORT_ptr mySupport) throw(SALOME::SALOME_Exception)
 {
-       MESSAGE("Pas Implemente dans SMESH");
-       THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
-       return 0;
+  MESSAGE("Pas Implemente dans SMESH");
+  THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
+  return 0;
 }
 
 //=============================================================================
@@ -829,11 +836,11 @@ SALOME_MED::FIELD_ptr SMESH_MEDMesh_i::getBarycenter(SALOME_MED::
  */
 //=============================================================================
 SALOME_MED::FIELD_ptr SMESH_MEDMesh_i::getNeighbourhood(SALOME_MED::
-       SUPPORT_ptr mySupport) throw(SALOME::SALOME_Exception)
+                                                        SUPPORT_ptr mySupport) throw(SALOME::SALOME_Exception)
 {
-       MESSAGE("Non Implemente");
-       THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
-       return 0;
+  MESSAGE("Non Implemente");
+  THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
+  return 0;
 }
 
 //=============================================================================
@@ -843,57 +850,57 @@ SALOME_MED::FIELD_ptr SMESH_MEDMesh_i::getNeighbourhood(SALOME_MED::
  */
 //=============================================================================
 void SMESH_MEDMesh_i::addInStudy(SALOMEDS::Study_ptr myStudy,
-       SALOME_MED::MESH_ptr myIor) throw(SALOME::SALOME_Exception)
+                                 SALOME_MED::GMESH_ptr myIor) throw(SALOME::SALOME_Exception)
 {
-       BEGIN_OF("MED_Mesh_i::addInStudy");
-       if (_meshId != "")
-       {
-               MESSAGE("Mesh already in Study");
-               THROW_SALOME_CORBA_EXCEPTION("Mesh already in Study",
-                       SALOME::BAD_PARAM);
-       };
-
-       /*
-        * SALOMEDS::StudyBuilder_var myBuilder = myStudy->NewBuilder();
-        
-        * // Create SComponent labelled 'MED' if it doesn't already exit
-        * SALOMEDS::SComponent_var medfather = myStudy->FindComponent("MED");
-        * if ( CORBA::is_nil(medfather) ) 
-        * {
-        * MESSAGE("Add Component MED");
-        * medfather = myBuilder->NewComponent("MED");
-        * //myBuilder->AddAttribute (medfather,SALOMEDS::Name,"MED");
-        * SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(
-        * myBuilder->FindOrCreateAttribute(medfather, "AttributeName"));
-        * aName->SetValue("MED");
-        
-        * myBuilder->DefineComponentInstance(medfather,myIor);
-        
-        * } ;
-        
-        * MESSAGE("Add a mesh Object under MED");
-        * myBuilder->NewCommand();
-        * SALOMEDS::SObject_var newObj = myBuilder->NewObject(medfather);
-        
-        * ORB_INIT &init = *SINGLETON_<ORB_INIT>::Instance() ;
-        * ASSERT(SINGLETON_<ORB_INIT>::IsAlreadyExisting()) ;
-        * CORBA::ORB_var &orb = init(0,0);
-        * CORBA::String_var iorStr = orb->object_to_string(myIor);
-        * //myBuilder->AddAttribute(newObj,SALOMEDS::IOR,iorStr.in());
-        * SALOMEDS::AttributeIOR_var aIOR = SALOMEDS::AttributeIOR::_narrow(
-        * myBuilder->FindOrCreateAttribute(newObj, "AttributeIOR"));
-        * aIOR->SetValue(iorStr.c_str());
-        
-        * //myBuilder->AddAttribute(newObj,SALOMEDS::Name,_mesh_i->getName().c_str());
-        * SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(
-        * myBuilder->FindOrCreateAttribute(newObj, "AttributeName"));
-        * aName->SetValue(_mesh_i->getName().c_str());
-        
-        * _meshId = newObj->GetID();
-        * myBuilder->CommitCommand();
-        
-        */
-       END_OF("Mesh_i::addInStudy(SALOMEDS::Study_ptr myStudy)");
+  BEGIN_OF("MED_Mesh_i::addInStudy");
+  if (_meshId != "")
+  {
+    MESSAGE("Mesh already in Study");
+    THROW_SALOME_CORBA_EXCEPTION("Mesh already in Study",
+                                 SALOME::BAD_PARAM);
+  };
+
+  /*
+   * SALOMEDS::StudyBuilder_var myBuilder = myStudy->NewBuilder();
+   * 
+   * // Create SComponent labelled 'MED' if it doesn't already exit
+   * SALOMEDS::SComponent_var medfather = myStudy->FindComponent("MED");
+   * if ( CORBA::is_nil(medfather) ) 
+   * {
+   * MESSAGE("Add Component MED");
+   * medfather = myBuilder->NewComponent("MED");
+   * //myBuilder->AddAttribute (medfather,SALOMEDS::Name,"MED");
+   * SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(
+   * myBuilder->FindOrCreateAttribute(medfather, "AttributeName"));
+   * aName->SetValue("MED");
+   * 
+   * myBuilder->DefineComponentInstance(medfather,myIor);
+   * 
+   * } ;
+   * 
+   * MESSAGE("Add a mesh Object under MED");
+   * myBuilder->NewCommand();
+   * SALOMEDS::SObject_var newObj = myBuilder->NewObject(medfather);
+   * 
+   * ORB_INIT &init = *SINGLETON_<ORB_INIT>::Instance() ;
+   * ASSERT(SINGLETON_<ORB_INIT>::IsAlreadyExisting()) ;
+   * CORBA::ORB_var &orb = init(0,0);
+   * CORBA::String_var iorStr = orb->object_to_string(myIor);
+   * //myBuilder->AddAttribute(newObj,SALOMEDS::IOR,iorStr.in());
+   * SALOMEDS::AttributeIOR_var aIOR = SALOMEDS::AttributeIOR::_narrow(
+   * myBuilder->FindOrCreateAttribute(newObj, "AttributeIOR"));
+   * aIOR->SetValue(iorStr.c_str());
+   * 
+   * //myBuilder->AddAttribute(newObj,SALOMEDS::Name,_mesh_i->getName().c_str());
+   * SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(
+   * myBuilder->FindOrCreateAttribute(newObj, "AttributeName"));
+   * aName->SetValue(_mesh_i->getName().c_str());
+   * 
+   * _meshId = newObj->GetID();
+   * myBuilder->CommitCommand();
+   * 
+   */
+  END_OF("Mesh_i::addInStudy(SALOMEDS::Study_ptr myStudy)");
 }
 
 //=============================================================================
@@ -902,10 +909,10 @@ void SMESH_MEDMesh_i::addInStudy(SALOMEDS::Study_ptr myStudy,
  */
 //=============================================================================
 void SMESH_MEDMesh_i::write(CORBA::Long i, const char *driverMeshName)
-throw(SALOME::SALOME_Exception)
+  throw(SALOME::SALOME_Exception)
 {
-       MESSAGE("Non Implemente");
-       THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
+  MESSAGE("Non Implemente");
+  THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
 }
 
 //=============================================================================
@@ -915,8 +922,8 @@ throw(SALOME::SALOME_Exception)
 //=============================================================================
 void SMESH_MEDMesh_i::read(CORBA::Long i) throw(SALOME::SALOME_Exception)
 {
-       MESSAGE("Non Implemente");
-       THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
+  MESSAGE("Non Implemente");
+  THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
 }
 
 //=============================================================================
@@ -926,8 +933,8 @@ void SMESH_MEDMesh_i::read(CORBA::Long i) throw(SALOME::SALOME_Exception)
 //=============================================================================
 void SMESH_MEDMesh_i::rmDriver(CORBA::Long i) throw(SALOME::SALOME_Exception)
 {
-       MESSAGE("Non Implemente");
-       THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
+  MESSAGE("Non Implemente");
+  THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
 }
 
 //=============================================================================
@@ -936,11 +943,11 @@ void SMESH_MEDMesh_i::rmDriver(CORBA::Long i) throw(SALOME::SALOME_Exception)
  */
 //=============================================================================
 CORBA::Long SMESH_MEDMesh_i::addDriver(SALOME_MED::medDriverTypes driverType,
-       const char *fileName, const char *meshName) throw(SALOME::SALOME_Exception)
+                                       const char *fileName, const char *meshName) throw(SALOME::SALOME_Exception)
 {
-       MESSAGE("Non Implemente");
-       THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
-       return 0;
+  MESSAGE("Non Implemente");
+  THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
+  return 0;
 }
 
 //=============================================================================
@@ -950,174 +957,174 @@ CORBA::Long SMESH_MEDMesh_i::addDriver(SALOME_MED::medDriverTypes driverType,
 //=============================================================================
 void SMESH_MEDMesh_i::calculeNbElts() throw(SALOME::SALOME_Exception)
 {
-       if (!_compte)
-       {
-               _compte = true;
-
-               _mapNbTypes[SALOME_MED::MED_NODE] = 1;
-               // On compte les aretes MED_SEG2 ou MED_SEG3
-               // On range les elements dans  les vecteurs correspondants 
-
-               _mapIndToSeqElts[SALOME_MED::MED_SEG2] = _indexElts++;
-               _mapIndToSeqElts[SALOME_MED::MED_SEG3] = _indexElts++;
-               _mapIndToVectTypes[SALOME_MED::MED_EDGE] = _indexEnts++;
-
-               int trouveSeg2 = 0;
-               int trouveSeg3 = 0;
-               SALOME_MED::medGeometryElement medElement;
-
-               SMDS_EdgeIteratorPtr itEdges=_meshDS->edgesIterator();
-               while(itEdges->more())
-               {
-                       const SMDS_MeshEdge* elem = itEdges->next();
-                       int nb_of_nodes = elem->NbNodes();
-
-                       switch (nb_of_nodes)
-                       {
-                       case 2:
-                       {
-                               medElement = SALOME_MED::MED_SEG2;
-                               if (trouveSeg2 == 0)
-                               {
-                                       trouveSeg2 = 1;
-                                       _TypesId[SALOME_MED::MED_EDGE].
-                                               push_back(SALOME_MED::MED_SEG2);
-                               }
-                               break;
-                       }
-                       case 3:
-                       {
-                               medElement = SALOME_MED::MED_SEG3;
-                               if (trouveSeg3 == 0)
-                               {
-                                       trouveSeg3 = 1;
-                                       _TypesId[SALOME_MED::MED_EDGE].
-                                               push_back(SALOME_MED::MED_SEG3);
-                               }
-                               break;
-                       }
-                       }
-                       int index = _mapIndToSeqElts[medElement];
-                       SCRUTE(index);
-                       // Traitement de l arete
-
-                       int longueur = _seq_elemId[index]->length();
-                       _seq_elemId[index]->length(longueur + nb_of_nodes);
-
-                       SMDS_NodeIteratorPtr itn=_meshDS->nodesIterator();
-
-                       for(int k=0; itn->more(); k++)
-                               _seq_elemId[index][longueur + k] = itn->next()->GetID()+1;
-               }
-
-               _mapNbTypes[SALOME_MED::MED_EDGE] = trouveSeg2 + trouveSeg3;
-
-               // On compte les faces MED_TRIA3, MED_HEXA8, MED_TRIA6
-               // On range les elements dans  les vecteurs correspondants 
-               int trouveTria3 = 0;
-               int trouveTria6 = 0;
-               int trouveQuad4 = 0;
-
-               _mapIndToSeqElts[SALOME_MED::MED_TRIA3] = _indexElts++;
-               _mapIndToSeqElts[SALOME_MED::MED_TRIA6] = _indexElts++;
-               _mapIndToSeqElts[SALOME_MED::MED_QUAD4] = _indexElts++;
-               _mapIndToVectTypes[SALOME_MED::MED_FACE] = _indexEnts++;
-
-               SMDS_FaceIteratorPtr itFaces=_meshDS->facesIterator();
-               while(itFaces->more())
-               {
-                       const SMDS_MeshFace * elem = itFaces->next();
-                       int nb_of_nodes = elem->NbNodes();
-
-                       switch (nb_of_nodes)
-                       {
-                       case 3:
-                       {
-                               medElement = SALOME_MED::MED_TRIA3;
-                               if (trouveTria3 == 0)
-                               {
-                                       trouveTria3 = 1;
-                                       _TypesId[SALOME_MED::MED_FACE].
-                                               push_back(SALOME_MED::MED_TRIA3);
-                               }
-                               break;
-                       }
-                       case 4:
-                       {
-                               medElement = SALOME_MED::MED_QUAD4;
-                               if (trouveQuad4 == 0)
-                               {
-                                       trouveQuad4 = 1;
-                                       _TypesId[SALOME_MED::MED_FACE].
-                                               push_back(SALOME_MED::MED_QUAD4);
-                               }
-                               break;
-                       }
-                       case 6:
-                       {
-                               medElement = SALOME_MED::MED_TRIA6;
-                               if (trouveTria6 == 0)
-                               {
-                                       trouveTria6 = 1;
-                                       _TypesId[SALOME_MED::MED_FACE].
-                                               push_back(SALOME_MED::MED_TRIA6);
-                               }
-                               break;
-                       }
-                       }
-                       int index = _mapIndToSeqElts[medElement];
-                       SCRUTE(index);
-
-                       // Traitement de la face
-                       // Attention La numérotation des noeuds Med commence a 1
-
-                       int longueur = _seq_elemId[index]->length();
-                       _seq_elemId[index]->length(longueur + nb_of_nodes);
-
-                       SMDS_NodeIteratorPtr itn=_meshDS->nodesIterator();
-
-                       for(int k=0; itn->more(); k++)
-                               _seq_elemId[index][longueur + k] = itn->next()->GetID()+1;
-               } //itFaces
-
-               _mapNbTypes[SALOME_MED::MED_FACE] =
-                       trouveTria3 + trouveTria6 + trouveQuad4;
-
-               _mapIndToSeqElts[SALOME_MED::MED_HEXA8] = _indexElts++;
-               _mapIndToVectTypes[SALOME_MED::MED_CELL] = _indexEnts++;
-               int index = _mapIndToSeqElts[medElement];
-
-               int trouveHexa8 = 0;
-
-               SMDS_VolumeIteratorPtr itVolumes=_meshDS->volumesIterator();
-               while(itVolumes->more())
-               {
-                       const SMDS_MeshVolume * elem = itVolumes->next();
-
-                       int nb_of_nodes = elem->NbNodes();
-                       medElement = SALOME_MED::MED_HEXA8;
-                       ASSERT(nb_of_nodes == 8);
-
-                       if (trouveHexa8 == 0)
-                       {
-                               trouveHexa8 = 1;
-                               _TypesId[SALOME_MED::MED_CELL].push_back(SALOME_MED::MED_HEXA8);
-                       };
-                       // Traitement de la maille
-                       int longueur = _seq_elemId[index]->length();
-                       _seq_elemId[index]->length(longueur + nb_of_nodes);
-
-                       SMDS_NodeIteratorPtr itn=_meshDS->nodesIterator();
-                       for(int k=0; itn->more(); k++)
-                               _seq_elemId[index][longueur + k] = itn->next()->GetID()+1;
-               }
-
-               _mapNbTypes[SALOME_MED::MED_CELL] = trouveHexa8;
-               _mapNbTypes[SALOME_MED::MED_ALL_ENTITIES]
-                       =
-                       trouveHexa8 + trouveTria3 + trouveTria6 + trouveQuad4 + trouveSeg2 +
-                       trouveSeg3;
-       }// fin du _compte
+  if (!_compte)
+  {
+    _compte = true;
+
+    _mapNbTypes[SALOME_MED::MED_NODE] = 1;
+    // On compte les aretes MED_SEG2 ou MED_SEG3
+    // On range les elements dans  les vecteurs correspondants 
+
+    _mapIndToSeqElts[SALOME_MED::MED_SEG2] = _indexElts++;
+    _mapIndToSeqElts[SALOME_MED::MED_SEG3] = _indexElts++;
+    _mapIndToVectTypes[SALOME_MED::MED_EDGE] = _indexEnts++;
+
+    int trouveSeg2 = 0;
+    int trouveSeg3 = 0;
+    SALOME_MED::medGeometryElement medElement;
+
+    SMDS_EdgeIteratorPtr itEdges=_meshDS->edgesIterator();
+    while(itEdges->more())
+    {
+      const SMDS_MeshEdge* elem = itEdges->next();
+      int nb_of_nodes = elem->NbNodes();
+
+      switch (nb_of_nodes)
+      {
+      case 2:
+        {
+          medElement = SALOME_MED::MED_SEG2;
+          if (trouveSeg2 == 0)
+          {
+            trouveSeg2 = 1;
+            _TypesId[SALOME_MED::MED_EDGE].
+              push_back(SALOME_MED::MED_SEG2);
+          }
+          break;
+        }
+      case 3:
+        {
+          medElement = SALOME_MED::MED_SEG3;
+          if (trouveSeg3 == 0)
+          {
+            trouveSeg3 = 1;
+            _TypesId[SALOME_MED::MED_EDGE].
+              push_back(SALOME_MED::MED_SEG3);
+          }
+          break;
+        }
+      }
+      int index = _mapIndToSeqElts[medElement];
+      SCRUTE(index);
+      // Traitement de l arete
+
+      int longueur = _seq_elemId[index]->length();
+      _seq_elemId[index]->length(longueur + nb_of_nodes);
+
+      SMDS_NodeIteratorPtr itn=_meshDS->nodesIterator();
+
+      for(int k=0; itn->more(); k++)
+        _seq_elemId[index][longueur + k] = itn->next()->GetID()+1;
+    }
+
+    _mapNbTypes[SALOME_MED::MED_EDGE] = trouveSeg2 + trouveSeg3;
+
+    // On compte les faces MED_TRIA3, MED_HEXA8, MED_TRIA6
+    // On range les elements dans  les vecteurs correspondants 
+    int trouveTria3 = 0;
+    int trouveTria6 = 0;
+    int trouveQuad4 = 0;
+
+    _mapIndToSeqElts[SALOME_MED::MED_TRIA3] = _indexElts++;
+    _mapIndToSeqElts[SALOME_MED::MED_TRIA6] = _indexElts++;
+    _mapIndToSeqElts[SALOME_MED::MED_QUAD4] = _indexElts++;
+    _mapIndToVectTypes[SALOME_MED::MED_FACE] = _indexEnts++;
+
+    SMDS_FaceIteratorPtr itFaces=_meshDS->facesIterator();
+    while(itFaces->more())
+    {
+      const SMDS_MeshFace * elem = itFaces->next();
+      int nb_of_nodes = elem->NbNodes();
+
+      switch (nb_of_nodes)
+      {
+      case 3:
+        {
+          medElement = SALOME_MED::MED_TRIA3;
+          if (trouveTria3 == 0)
+          {
+            trouveTria3 = 1;
+            _TypesId[SALOME_MED::MED_FACE].
+              push_back(SALOME_MED::MED_TRIA3);
+          }
+          break;
+        }
+      case 4:
+        {
+          medElement = SALOME_MED::MED_QUAD4;
+          if (trouveQuad4 == 0)
+          {
+            trouveQuad4 = 1;
+            _TypesId[SALOME_MED::MED_FACE].
+              push_back(SALOME_MED::MED_QUAD4);
+          }
+          break;
+        }
+      case 6:
+        {
+          medElement = SALOME_MED::MED_TRIA6;
+          if (trouveTria6 == 0)
+          {
+            trouveTria6 = 1;
+            _TypesId[SALOME_MED::MED_FACE].
+              push_back(SALOME_MED::MED_TRIA6);
+          }
+          break;
+        }
+      }
+      int index = _mapIndToSeqElts[medElement];
+      SCRUTE(index);
+
+      // Traitement de la face
+      // Attention La numérotation des noeuds Med commence a 1
+
+      int longueur = _seq_elemId[index]->length();
+      _seq_elemId[index]->length(longueur + nb_of_nodes);
+
+      SMDS_NodeIteratorPtr itn=_meshDS->nodesIterator();
+
+      for(int k=0; itn->more(); k++)
+        _seq_elemId[index][longueur + k] = itn->next()->GetID()+1;
+    } //itFaces
+
+    _mapNbTypes[SALOME_MED::MED_FACE] =
+      trouveTria3 + trouveTria6 + trouveQuad4;
+
+    _mapIndToSeqElts[SALOME_MED::MED_HEXA8] = _indexElts++;
+    _mapIndToVectTypes[SALOME_MED::MED_CELL] = _indexEnts++;
+    int index = _mapIndToSeqElts[medElement];
+
+    int trouveHexa8 = 0;
+
+    SMDS_VolumeIteratorPtr itVolumes=_meshDS->volumesIterator();
+    while(itVolumes->more())
+    {
+      const SMDS_MeshVolume * elem = itVolumes->next();
+
+      int nb_of_nodes = elem->NbNodes();
+      medElement = SALOME_MED::MED_HEXA8;
+      ASSERT(nb_of_nodes == 8);
+
+      if (trouveHexa8 == 0)
+      {
+        trouveHexa8 = 1;
+        _TypesId[SALOME_MED::MED_CELL].push_back(SALOME_MED::MED_HEXA8);
+      };
+      // Traitement de la maille
+      int longueur = _seq_elemId[index]->length();
+      _seq_elemId[index]->length(longueur + nb_of_nodes);
+
+      SMDS_NodeIteratorPtr itn=_meshDS->nodesIterator();
+      for(int k=0; itn->more(); k++)
+        _seq_elemId[index][longueur + k] = itn->next()->GetID()+1;
+    }
+
+    _mapNbTypes[SALOME_MED::MED_CELL] = trouveHexa8;
+    _mapNbTypes[SALOME_MED::MED_ALL_ENTITIES]
+      =
+      trouveHexa8 + trouveTria3 + trouveTria6 + trouveQuad4 + trouveSeg2 +
+      trouveSeg3;
+  }// fin du _compte
 };
 
 //=============================================================================
@@ -1128,49 +1135,49 @@ 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;
-       char numero[10];
-
-       if (_creeFamily == false)
-       {
-               _creeFamily = true;
-               //SMESH_subMesh_i *subMeshServant;
-
-               map < int, SMESH_subMesh_i * >::iterator it;
-               for (it = _mesh_i->_mapSubMesh_i.begin();
-                       it != _mesh_i->_mapSubMesh_i.end(); it++)
-               {
-                       SMESH_subMesh_i *submesh_i = (*it).second;
-                       int famIdent = (*it).first;
-
-                       ASSERT(famIdent < 999999999);
-                       sprintf(numero, "%d\n", famIdent);
-                       famName = famName0 + numero;
-
-                       SMESH_MEDFamily_i *famservant =
-                               new SMESH_MEDFamily_i(famIdent, submesh_i,
-                               famName, famDes, SALOME_MED::MED_NODE);
+  string famDes = ("Je ne sais pas");
+  string famName0 = "Famille_";
+  string famName;
+  char numero[10];
+
+  if (_creeFamily == false)
+  {
+    _creeFamily = true;
+    //SMESH_subMesh_i *subMeshServant;
+
+    map < int, SMESH_subMesh_i * >::iterator it;
+    for (it = _mesh_i->_mapSubMesh_i.begin();
+         it != _mesh_i->_mapSubMesh_i.end(); it++)
+    {
+      SMESH_subMesh_i *submesh_i = (*it).second;
+      int famIdent = (*it).first;
+
+      ASSERT(famIdent < 999999999);
+      sprintf(numero, "%d\n", famIdent);
+      famName = famName0 + numero;
+
+      SMESH_MEDFamily_i *famservant =
+        new SMESH_MEDFamily_i(famIdent, submesh_i,
+                              famName, famDes, SALOME_MED::MED_NODE);
 #ifdef WNT
       SALOME_MED::FAMILY_ptr famille = SALOME_MED::FAMILY::_nil();
       POA_SALOME_MED::FAMILY* servantbase = dynamic_cast<POA_SALOME_MED::FAMILY*>(famservant);
       if ( servantbase )
         famille = SALOME_MED::FAMILY::_narrow( servantbase->_this() );
 #else 
-               SALOME_MED::FAMILY_ptr famille = 
+      SALOME_MED::FAMILY_ptr famille = 
         SALOME_MED::FAMILY::_narrow( famservant->POA_SALOME_MED::FAMILY::_this() );
 #endif
-                       _families.push_back(famille);
-               }
-       }
+      _families.push_back(famille);
+    }
+  }
 };
 //=============================================================================
 /*!
  * Gives informations of the considered mesh.
  */
 //=============================================================================
-SALOME_MED::MESH::meshInfos * SMESH_MEDMesh_i::getMeshGlobal()
+SALOME_MED::GMESH::meshInfos * SMESH_MEDMesh_i::getMeshGlobal()
   throw (SALOME::SALOME_Exception)
 {
   MESSAGE("!!!! NOT YET IMPLEMENTED !!!!!");
@@ -1179,12 +1186,28 @@ SALOME_MED::MESH::meshInfos * SMESH_MEDMesh_i::getMeshGlobal()
 
   return NULL;
 }
+
+//================================================================================
+/*!
+ * \brief Converts this GMESH into MESH
+ */
+//================================================================================
+
+SALOME_MED::MESH_ptr SMESH_MEDMesh_i::convertInMESH() throw (SALOME::SALOME_Exception)
+{
+  MESSAGE("!!!! NOT YET IMPLEMENTED !!!!!");
+
+  THROW_SALOME_CORBA_EXCEPTION("Unimplemented Method", SALOME::BAD_PARAM);
+
+  return NULL;
+}
+
 //=============================================================================
 /*!
  * Gives informations on coordinates of the considered mesh.
  */
 //=============================================================================
-SALOME_MED::MESH::coordinateInfos * SMESH_MEDMesh_i::getCoordGlobal()
+SALOME_MED::GMESH::coordinateInfos * SMESH_MEDMesh_i::getCoordGlobal()
   throw (SALOME::SALOME_Exception)
 {
   MESSAGE("!!!! NOT YET IMPLEMENTED !!!!!");
@@ -1216,7 +1239,7 @@ SMESH_MEDMesh_i::getConnectGlobal(SALOME_MED::medEntityMesh entity)
 //=============================================================================
 SALOME_MED::medGeometryElement
 SMESH_MEDMesh_i::getElementType(SALOME_MED::medEntityMesh entity,
-                               CORBA::Long number)
+                                CORBA::Long number)
   throw (SALOME::SALOME_Exception)
 {
   MESSAGE("!!!! NOT YET IMPLEMENTED !!!!!");
index 8e56e0e796f41b9ecabf9cc5b883268e1d10ca40..6541939af0482ccf2c90da4ba5703b2fe06d25bb 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : SMESH_MEDMesh_i.hxx
 //  Module : SMESH
@@ -62,7 +63,7 @@ protected:
   int _famIdent;
   
   std::map < SALOME_MED::medGeometryElement, int >_mapIndToSeqElts;
-  SALOME_MED::long_array_var _seq_elemId[MED_NBR_GEOMETRIE_MAILLE];
+  SALOME_TYPES::ListOfLong_var _seq_elemId[MED_NBR_GEOMETRIE_MAILLE];
   
   std::map < SALOME_MED::medEntityMesh, int >_mapNbTypes;
   std::map < SALOME_MED::medEntityMesh, int >_mapIndToVectTypes;
@@ -81,13 +82,18 @@ public:
   void setProtocol(SALOME::TypeOfCommunication typ) {}
   void release() {}
   SALOME::SenderDouble_ptr getSenderForCoordinates(SALOME_MED::medModeSwitch) {return SALOME::SenderDouble::_nil();}
-  SALOME::SenderInt_ptr getSenderForConnectivity(SALOME_MED::medModeSwitch, 
-                                                SALOME_MED::medConnectivity, 
-                                                SALOME_MED::medEntityMesh, 
-                                                SALOME_MED::medGeometryElement) 
+  SALOME::SenderInt_ptr getSenderForConnectivity(SALOME_MED::medConnectivity, 
+                                                 SALOME_MED::medEntityMesh, 
+                                                 SALOME_MED::medGeometryElement) 
+  {
+    return SALOME::SenderInt::_nil();
+  }  
+  SALOME::SenderInt_ptr getSenderForConnectivityIndex(SALOME_MED::medConnectivity,
+                                                      SALOME_MED::medEntityMesh,
+                                                      SALOME_MED::medGeometryElement)
   {
     return SALOME::SenderInt::_nil();
-  }
+  }  
   SALOME::SenderInt_ptr getSenderForPolygonsConnectivity(SALOME_MED::medConnectivity, SALOME_MED::medEntityMesh) {return SALOME::SenderInt::_nil();}
   SALOME::SenderInt_ptr getSenderForPolygonsConnectivityIndex(SALOME_MED::medConnectivity, SALOME_MED::medEntityMesh) {return SALOME::SenderInt::_nil();}
   SALOME::SenderInt_ptr getSenderForPolyhedronConnectivity(SALOME_MED::medConnectivity) {return SALOME::SenderInt::_nil();}
@@ -103,7 +109,7 @@ public:
   
   CORBA::Boolean
   existConnectivity(SALOME_MED::medConnectivity connectivityType,
-                   SALOME_MED::medEntityMesh entity)
+                    SALOME_MED::medEntityMesh entity)
     throw (SALOME::SALOME_Exception);
   
   char *getCoordinatesSystem() throw(SALOME::SALOME_Exception);
@@ -111,13 +117,13 @@ public:
   CORBA::Double getCoordinate(CORBA::Long Number, CORBA::Long Axis)
     throw (SALOME::SALOME_Exception);
   
-  SALOME_MED::double_array * getCoordinates(SALOME_MED::medModeSwitch typeSwitch)
+  SALOME_TYPES::ListOfDouble * getCoordinates(SALOME_MED::medModeSwitch typeSwitch)
     throw(SALOME::SALOME_Exception);
 
-  SALOME_MED::string_array * getCoordinatesNames()
+  SALOME_TYPES::ListOfString * getCoordinatesNames()
     throw(SALOME::SALOME_Exception);
   
-  SALOME_MED::string_array * getCoordinatesUnits()
+  SALOME_TYPES::ListOfString * getCoordinatesUnits()
     throw(SALOME::SALOME_Exception);
   
   CORBA::Long getNumberOfNodes() throw(SALOME::SALOME_Exception);
@@ -127,44 +133,43 @@ public:
   
   SALOME_MED::medGeometryElement_array *
   getTypes(SALOME_MED::medEntityMesh entity) throw(SALOME::
-                                                  SALOME_Exception);
+                                                   SALOME_Exception);
   
   SALOME_MED::medGeometryElement
   getElementType(SALOME_MED::medEntityMesh entity,
-                CORBA::Long number)
+                 CORBA::Long number)
     throw   (SALOME::SALOME_Exception);
   
   CORBA::Long getNumberOfElements(SALOME_MED::medEntityMesh entity,
-                                 SALOME_MED::medGeometryElement geomElement)
+                                  SALOME_MED::medGeometryElement geomElement)
     throw(SALOME::SALOME_Exception);
   
-  SALOME_MED::long_array *
-  getConnectivity(SALOME_MED::medModeSwitch typeSwitch,
-                 SALOME_MED::medConnectivity mode,
-                 SALOME_MED::medEntityMesh entity,
-                 SALOME_MED::medGeometryElement geomElement)
+  SALOME_TYPES::ListOfLong *
+  getConnectivity(SALOME_MED::medConnectivity mode,
+                  SALOME_MED::medEntityMesh entity,
+                  SALOME_MED::medGeometryElement geomElement)
     throw(SALOME::SALOME_Exception);
   
-  SALOME_MED::long_array *
+  SALOME_TYPES::ListOfLong *
   getConnectivityIndex(SALOME_MED::medConnectivity mode,
-                      SALOME_MED::medEntityMesh entity)
+                       SALOME_MED::medEntityMesh entity)
     throw(SALOME::SALOME_Exception);
   
-  SALOME_MED::long_array*
+  SALOME_TYPES::ListOfLong*
   getGlobalNumberingIndex(SALOME_MED::medEntityMesh entity)
     throw (SALOME::SALOME_Exception);
   
   CORBA::Long getElementNumber(SALOME_MED::medConnectivity mode,
-                              SALOME_MED::medEntityMesh entity,
-                              SALOME_MED::medGeometryElement type,
-                              const SALOME_MED::long_array & connectivity)
+                               SALOME_MED::medEntityMesh entity,
+                               SALOME_MED::medGeometryElement type,
+                               const SALOME_TYPES::ListOfLong & connectivity)
     throw(SALOME::SALOME_Exception);
   
-  SALOME_MED::long_array *
+  SALOME_TYPES::ListOfLong *
   getReverseConnectivity(SALOME_MED::medConnectivity mode)
     throw(SALOME::SALOME_Exception);
   
-  SALOME_MED::long_array *
+  SALOME_TYPES::ListOfLong *
   getReverseConnectivityIndex(SALOME_MED::medConnectivity mode) 
     throw(SALOME::SALOME_Exception);
   
@@ -180,14 +185,14 @@ public:
     throw(SALOME::SALOME_Exception);
   
   SALOME_MED::FAMILY_ptr getFamily(SALOME_MED::medEntityMesh entity,
-                                  CORBA::Long i) 
+                                   CORBA::Long i) 
     throw(SALOME::SALOME_Exception);
   
   SALOME_MED::Group_array * getGroups(SALOME_MED::medEntityMesh entity)
     throw(SALOME::SALOME_Exception);
   
   SALOME_MED::GROUP_ptr getGroup(SALOME_MED::medEntityMesh entity,
-                                CORBA::Long i) 
+                                 CORBA::Long i) 
     throw(SALOME::SALOME_Exception);
   
   SALOME_MED::SUPPORT_ptr
@@ -221,10 +226,10 @@ public:
   
   // Others
   void addInStudy(SALOMEDS::Study_ptr myStudy,
-                 SALOME_MED::MESH_ptr myIor) 
+                  SALOME_MED::GMESH_ptr myIor) 
     throw(SALOME::SALOME_Exception);
   CORBA::Long addDriver(SALOME_MED::medDriverTypes driverType,
-                       const char *fileName, const char *meshName)
+                        const char *fileName, const char *meshName)
     throw(SALOME::SALOME_Exception);
   void rmDriver(CORBA::Long i) throw(SALOME::SALOME_Exception);
   void read(CORBA::Long i) throw(SALOME::SALOME_Exception);
@@ -235,12 +240,14 @@ public:
   CORBA::Long getCorbaIndex() 
     throw(SALOME::SALOME_Exception);
   
-  SALOME_MED::MESH::meshInfos * getMeshGlobal()
+  SALOME_MED::GMESH::meshInfos * getMeshGlobal()
     throw (SALOME::SALOME_Exception);
   
-  bool areEquals(SALOME_MED::MESH_ptr other) { return false;};
+  bool areEquals(SALOME_MED::GMESH_ptr other) { return false;};
+  
+  SALOME_MED::MESH_ptr convertInMESH() throw (SALOME::SALOME_Exception);
   
-  SALOME_MED::MESH::coordinateInfos * getCoordGlobal()
+  SALOME_MED::GMESH::coordinateInfos * getCoordGlobal()
     throw (SALOME::SALOME_Exception);
   
   SALOME_MED::MESH::connectivityInfos *
index 56f3b73ebeec67e8f97815a7594bdc38580703bc..23dd941442916ea63cd15bd6046fb0fcbbeb94f6 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : SMESH_MEDSupport_i.cxx
 //  Module : SMESH
 #include "Utils_CorbaException.hxx"
 #include "Utils_ExceptHandlers.hxx"
 
-#include <TopoDS_Iterator.hxx>
 #include "SMESHDS_Mesh.hxx"
 
 #include "SMESH_subMesh.hxx"
 #include "SMESH_Mesh_i.hxx"
 #include "SMESH_subMesh_i.hxx"
+#include "SMESH_Gen_i.hxx"
+
+#include <TopoDS_Iterator.hxx>
 
 using namespace std;
 
@@ -45,8 +48,8 @@ using namespace std;
 //=============================================================================
 SMESH_MEDSupport_i::SMESH_MEDSupport_i()
 {
-       BEGIN_OF("Default Constructor SMESH_MEDSupport_i");
-       END_OF("Default Constructor SMESH_MEDSupport_i");
+        BEGIN_OF("Default Constructor SMESH_MEDSupport_i");
+        END_OF("Default Constructor SMESH_MEDSupport_i");
 }
 
 //=============================================================================
@@ -55,40 +58,34 @@ SMESH_MEDSupport_i::SMESH_MEDSupport_i()
  */
 //=============================================================================
 SMESH_MEDSupport_i::SMESH_MEDSupport_i(SMESH_subMesh_i * sm, string name,
-       string description, SALOME_MED::medEntityMesh entity)
-       :_subMesh_i(sm), _name(name), _description(description), _entity(entity),
-       _seqNumber(false), _seqLength(0)
+        string description, SALOME_MED::medEntityMesh entity)
+  :_subMesh_i(sm), _name(name), _description(description), _entity(entity),
+   _seqNumber(false), _seqLength(0)
 {
-       BEGIN_OF("Constructor SMESH_MEDSupport_i");
-
-       _meshDS = _subMesh_i->_mesh_i->GetImpl().GetMeshDS();
-
-       int subMeshId = _subMesh_i->GetId();
-
-       MESSAGE(" subMeshId " << subMeshId)
-
-       if (_subMesh_i->_mesh_i->_mapSubMesh.find(subMeshId) !=
-               _subMesh_i->_mesh_i->_mapSubMesh.end())
-       {
-               ::SMESH_subMesh * subMesh = _subMesh_i->_mesh_i->_mapSubMesh[subMeshId];
-               _subMeshDS = subMesh->GetSubMeshDS();
-       }
-
-       if (_entity == SALOME_MED::MED_NODE)
-       {
-               _numberOfGeometricType = 1;
-               _geometricType = new SALOME_MED::medGeometryElement[1];
-               _geometricType[0] = SALOME_MED::MED_NONE;
-       }
-       else
-       {
-               MESSAGE("Pas implemente dans cette version");
-               THROW_SALOME_CORBA_EXCEPTION
-                       ("Seules les familles de noeuds sont implementees ",
-                       SALOME::BAD_PARAM);
-       }
-
-       END_OF("Constructor SMESH_MEDSupport_i");
+        BEGIN_OF("Constructor SMESH_MEDSupport_i");
+
+        int subMeshId = sm->GetId();
+
+        MESSAGE(" subMeshId " << subMeshId);
+
+        SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( sm->GetMesh() );
+        _subMesh = mesh_i->GetImpl().GetSubMeshContaining( subMeshId );
+
+        if (_entity == SALOME_MED::MED_NODE)
+        {
+                _numberOfGeometricType = 1;
+                _geometricType = new SALOME_MED::medGeometryElement[1];
+                _geometricType[0] = SALOME_MED::MED_NONE;
+        }
+        else
+        {
+                MESSAGE("Pas implemente dans cette version");
+                THROW_SALOME_CORBA_EXCEPTION
+                        ("Seules les familles de noeuds sont implementees ",
+                        SALOME::BAD_PARAM);
+        }
+
+        END_OF("Constructor SMESH_MEDSupport_i");
 }
 
 //=============================================================================
@@ -97,23 +94,13 @@ SMESH_MEDSupport_i::SMESH_MEDSupport_i(SMESH_subMesh_i * sm, string name,
  */
 //=============================================================================
 SMESH_MEDSupport_i::
-SMESH_MEDSupport_i(const SMESH_MEDSupport_i & s):_subMesh_i(s._subMesh_i),
+SMESH_MEDSupport_i(const SMESH_MEDSupport_i & s):_subMesh(s._subMesh),
 _name(s._name), _description(s._description), _entity(s._entity),
 _seqNumber(false), _seqLength(0)
 {
-       BEGIN_OF("Constructor SMESH_MEDSupport_i");
-
-       _meshDS = _subMesh_i->_mesh_i->GetImpl().GetMeshDS();
-
-       int subMeshId = _subMesh_i->GetId();
-       if (_subMesh_i->_mesh_i->_mapSubMesh.find(subMeshId) !=
-               _subMesh_i->_mesh_i->_mapSubMesh.end())
-       {
-               ::SMESH_subMesh * subMesh = _subMesh_i->_mesh_i->_mapSubMesh[subMeshId];
-               _subMeshDS = subMesh->GetSubMeshDS();
-       }
+        BEGIN_OF("Constructor SMESH_MEDSupport_i");
 
-       END_OF("Constructor SMESH_MEDSupport_i");
+        END_OF("Constructor SMESH_MEDSupport_i");
 }
 
 //=============================================================================
@@ -134,11 +121,11 @@ SMESH_MEDSupport_i::~SMESH_MEDSupport_i()
 
 CORBA::Long SMESH_MEDSupport_i::getCorbaIndex()throw(SALOME::SALOME_Exception)
 {
-       if (_subMeshDS == NULL)
-               THROW_SALOME_CORBA_EXCEPTION("No associated Support",
-                       SALOME::INTERNAL_ERROR);
-       MESSAGE("Not implemented for SMESH_i");
-       THROW_SALOME_CORBA_EXCEPTION("Not Implemented ", SALOME::BAD_PARAM);
+        if (_subMesh == NULL)
+                THROW_SALOME_CORBA_EXCEPTION("No associated Support",
+                        SALOME::INTERNAL_ERROR);
+        MESSAGE("Not implemented for SMESH_i");
+        THROW_SALOME_CORBA_EXCEPTION("Not Implemented ", SALOME::BAD_PARAM);
 
 }
 
@@ -150,10 +137,10 @@ CORBA::Long SMESH_MEDSupport_i::getCorbaIndex()throw(SALOME::SALOME_Exception)
 
 char *SMESH_MEDSupport_i::getName() throw(SALOME::SALOME_Exception)
 {
-       if (_subMeshDS==NULL)
-               THROW_SALOME_CORBA_EXCEPTION("No associated Support",
-                       SALOME::INTERNAL_ERROR);
-       return CORBA::string_dup(_name.c_str());
+        if (_subMesh==NULL)
+                THROW_SALOME_CORBA_EXCEPTION("No associated Support",
+                        SALOME::INTERNAL_ERROR);
+        return CORBA::string_dup(_name.c_str());
 
 }
 
@@ -165,10 +152,10 @@ char *SMESH_MEDSupport_i::getName() throw(SALOME::SALOME_Exception)
 
 char *SMESH_MEDSupport_i::getDescription() throw(SALOME::SALOME_Exception)
 {
-       if (_subMeshDS==NULL)
-               THROW_SALOME_CORBA_EXCEPTION("No associated Support",
-                       SALOME::INTERNAL_ERROR);
-       return CORBA::string_dup(_description.c_str());
+        if (_subMesh==NULL)
+                THROW_SALOME_CORBA_EXCEPTION("No associated Support",
+                        SALOME::INTERNAL_ERROR);
+        return CORBA::string_dup(_description.c_str());
 }
 
 //=============================================================================
@@ -177,14 +164,14 @@ char *SMESH_MEDSupport_i::getDescription() throw(SALOME::SALOME_Exception)
  */
 //=============================================================================
 
-SALOME_MED::MESH_ptr SMESH_MEDSupport_i::getMesh()throw(SALOME::
-       SALOME_Exception)
+SALOME_MED::GMESH_ptr SMESH_MEDSupport_i::getMesh()throw(SALOME::
+        SALOME_Exception)
 {
-       if (_subMeshDS==NULL)
-               THROW_SALOME_CORBA_EXCEPTION("No associated Support",
-                       SALOME::INTERNAL_ERROR);
+        if (_subMesh==NULL)
+                THROW_SALOME_CORBA_EXCEPTION("No associated Support",
+                        SALOME::INTERNAL_ERROR);
 
-       return _subMesh_i->_mesh_i->GetMEDMesh();
+        return _subMesh_i->GetMesh()->GetMEDMesh();
 }
 
 //=============================================================================
@@ -194,36 +181,36 @@ SALOME_MED::MESH_ptr SMESH_MEDSupport_i::getMesh()throw(SALOME::
 //=============================================================================
 
 CORBA::Boolean SMESH_MEDSupport_i::isOnAllElements()throw(SALOME::
-       SALOME_Exception)
+        SALOME_Exception)
 {
-       if (_subMeshDS==NULL)
-               THROW_SALOME_CORBA_EXCEPTION("No associated Support",
-                       SALOME::INTERNAL_ERROR);
-       if (_seqNumber == false)
-       {
-               if (_entity != SALOME_MED::MED_NONE)
-               {
-                       _seqLength = _subMeshDS->NbNodes();
-                       _seqNumber = true;
-               }
-               else
-               {
-                       MESSAGE("Only Node Families are implemented ");
-                       THROW_SALOME_CORBA_EXCEPTION("Not implemented Yet ",
-                               SALOME::BAD_PARAM);
-               }
-       }
-       try
-       {
-               _isOnAllElements = (_seqLength == _meshDS->NbNodes());
-       }
-       catch(...)
-       {
-               MESSAGE("unable to acces related Mesh");
-               THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
-                       SALOME::INTERNAL_ERROR);
-       };
-       return _isOnAllElements;
+        if (_subMesh==NULL)
+                THROW_SALOME_CORBA_EXCEPTION("No associated Support",
+                        SALOME::INTERNAL_ERROR);
+        if (_seqNumber == false)
+        {
+                if (_entity != SALOME_MED::MED_NONE)
+                {
+                        _seqLength = _subMesh_i->GetNumberOfNodes(/*all=*/false);
+                        _seqNumber = true;
+                }
+                else
+                {
+                        MESSAGE("Only Node Families are implemented ");
+                        THROW_SALOME_CORBA_EXCEPTION("Not implemented Yet ",
+                                SALOME::BAD_PARAM);
+                }
+        }
+        try
+        {
+          _isOnAllElements = (_seqLength == _subMesh->GetFather()->NbNodes());
+        }
+        catch(...)
+        {
+                MESSAGE("unable to acces related Mesh");
+                THROW_SALOME_CORBA_EXCEPTION("No associated Mesh",
+                        SALOME::INTERNAL_ERROR);
+        };
+        return _isOnAllElements;
 }
 
 //=============================================================================
@@ -233,12 +220,12 @@ CORBA::Boolean SMESH_MEDSupport_i::isOnAllElements()throw(SALOME::
 //=============================================================================
 
 SALOME_MED::medEntityMesh SMESH_MEDSupport_i::getEntity()throw(SALOME::
-       SALOME_Exception)
+        SALOME_Exception)
 {
-       if (_subMeshDS==NULL)
-               THROW_SALOME_CORBA_EXCEPTION("No associated Support",
-                       SALOME::INTERNAL_ERROR);
-       return _entity;
+        if (_subMesh==NULL)
+                THROW_SALOME_CORBA_EXCEPTION("No associated Support",
+                        SALOME::INTERNAL_ERROR);
+        return _entity;
 }
 
 //=============================================================================
@@ -248,29 +235,29 @@ SALOME_MED::medEntityMesh SMESH_MEDSupport_i::getEntity()throw(SALOME::
 //=============================================================================
 
 SALOME_MED::medGeometryElement_array *
-       SMESH_MEDSupport_i::getTypes()throw(SALOME::SALOME_Exception)
+        SMESH_MEDSupport_i::getTypes()throw(SALOME::SALOME_Exception)
 {
-       if (_subMeshDS==NULL)
-               THROW_SALOME_CORBA_EXCEPTION("No associated Support",
-                       SALOME::INTERNAL_ERROR);
-       SALOME_MED::medGeometryElement_array_var myseq =
-               new SALOME_MED::medGeometryElement_array;
-       try
-       {
-               int mySeqLength = _numberOfGeometricType;
-               myseq->length(mySeqLength);
-               for (int i = 0; i < mySeqLength; i++)
-               {
-                       myseq[i] = _geometricType[i];
-               }
-       }
-       catch(...)
-       {
-               MESSAGE("Exception lors de la recherche des differents types");
-               THROW_SALOME_CORBA_EXCEPTION("Unable to acces Support Types",
-                       SALOME::INTERNAL_ERROR);
-       }
-       return myseq._retn();
+        if (_subMesh==NULL)
+                THROW_SALOME_CORBA_EXCEPTION("No associated Support",
+                        SALOME::INTERNAL_ERROR);
+        SALOME_MED::medGeometryElement_array_var myseq =
+                new SALOME_MED::medGeometryElement_array;
+        try
+        {
+                int mySeqLength = _numberOfGeometricType;
+                myseq->length(mySeqLength);
+                for (int i = 0; i < mySeqLength; i++)
+                {
+                        myseq[i] = _geometricType[i];
+                }
+        }
+        catch(...)
+        {
+                MESSAGE("Exception lors de la recherche des differents types");
+                THROW_SALOME_CORBA_EXCEPTION("Unable to acces Support Types",
+                        SALOME::INTERNAL_ERROR);
+        }
+        return myseq._retn();
 }
 
 //=============================================================================
@@ -280,12 +267,12 @@ SALOME_MED::medGeometryElement_array *
  */
 //=============================================================================
 CORBA::Long SMESH_MEDSupport_i::getNumberOfElements(SALOME_MED::
-       medGeometryElement geomElement) throw(SALOME::SALOME_Exception)
+        medGeometryElement geomElement) throw(SALOME::SALOME_Exception)
 {
-       if (_subMeshDS==NULL)
-               THROW_SALOME_CORBA_EXCEPTION("No associated Support",
-                       SALOME::INTERNAL_ERROR);
-       return _numberOfGeometricType;
+        if (_subMesh==NULL)
+                THROW_SALOME_CORBA_EXCEPTION("No associated Support",
+                        SALOME::INTERNAL_ERROR);
+        return _numberOfGeometricType;
 
 }
 
@@ -295,33 +282,36 @@ CORBA::Long SMESH_MEDSupport_i::getNumberOfElements(SALOME_MED::
  */
 //=============================================================================
 
-SALOME_MED::long_array * SMESH_MEDSupport_i::getNumber(
-       SALOME_MED::medGeometryElement geomElement) throw(SALOME::SALOME_Exception)
+SALOME_TYPES::ListOfLong * 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);
+        if (_subMesh==NULL)
+                THROW_SALOME_CORBA_EXCEPTION("No associated Support",
+                        SALOME::INTERNAL_ERROR);
 
-       // A changer s'il ne s agit plus seulement de famille de noeuds
-       if (geomElement != SALOME_MED::MED_NONE)
-               THROW_SALOME_CORBA_EXCEPTION("Not implemented", SALOME::BAD_PARAM);
+        // A changer s'il ne s agit plus seulement de famille de noeuds
+        if (geomElement != SALOME_MED::MED_NONE)
+                THROW_SALOME_CORBA_EXCEPTION("Not implemented", SALOME::BAD_PARAM);
 
-       SALOME_MED::long_array_var myseq = new SALOME_MED::long_array;
+        SALOME_TYPES::ListOfLong_var myseq = new SALOME_TYPES::ListOfLong;
 
-       int i = 0;
-       myseq->length(_subMeshDS->NbNodes());
+        int i = 0;
+        myseq->length(_subMesh_i->GetNumberOfNodes(/*all=*/false));
 
-       SMDS_NodeIteratorPtr it = _subMeshDS->GetNodes();
-       while(it->more())
-       {
-               myseq[i] = it->next()->GetID();
-               i++;
-       };
+        if ( _subMesh->GetSubMeshDS() )
+        {
+          SMDS_NodeIteratorPtr it = _subMesh->GetSubMeshDS()->GetNodes();
+          while(it->more())
+          {
+            myseq[i] = it->next()->GetID();
+            i++;
+          };
+        }
 
-       SCRUTE(myseq->length());
-       MESSAGE("End of SMESH_MEDSupport_i::getNumber");
-       return myseq._retn();
+        SCRUTE(myseq->length());
+        MESSAGE("End of SMESH_MEDSupport_i::getNumber");
+        return myseq._retn();
 
 }
 
@@ -331,8 +321,8 @@ SALOME_MED::long_array * SMESH_MEDSupport_i::getNumber(
  */
 //=============================================================================
 
-SALOME_MED::long_array * SMESH_MEDSupport_i::getNumberFromFile(
-       SALOME_MED::medGeometryElement geomElement) throw(SALOME::SALOME_Exception)
+SALOME_TYPES::ListOfLong * SMESH_MEDSupport_i::getNumberFromFile(
+        SALOME_MED::medGeometryElement geomElement) throw(SALOME::SALOME_Exception)
 {
   return getNumber(geomElement);
 }
@@ -344,12 +334,12 @@ SALOME_MED::long_array * SMESH_MEDSupport_i::getNumberFromFile(
  */
 //=============================================================================
 
-SALOME_MED::long_array *
-       SMESH_MEDSupport_i::getNumberIndex()throw(SALOME::SALOME_Exception)
+SALOME_TYPES::ListOfLong *
+        SMESH_MEDSupport_i::getNumberIndex()throw(SALOME::SALOME_Exception)
 {
-       MESSAGE("Not implemented for SMESH_i");
-       THROW_SALOME_CORBA_EXCEPTION("Not Implemented", SALOME::BAD_PARAM);
-       return NULL;
+        MESSAGE("Not implemented for SMESH_i");
+        THROW_SALOME_CORBA_EXCEPTION("Not Implemented", SALOME::BAD_PARAM);
+        return NULL;
 }
 //=============================================================================
 /*!
@@ -358,10 +348,10 @@ SALOME_MED::long_array *
 //=============================================================================
 
 CORBA::Long SMESH_MEDSupport_i::getNumberOfGaussPoint(SALOME_MED::
-       medGeometryElement geomElement) throw(SALOME::SALOME_Exception)
+        medGeometryElement geomElement) throw(SALOME::SALOME_Exception)
 {
-       MESSAGE("Not implemented for SMESH_i");
-       return 0;
+        MESSAGE("Not implemented for SMESH_i");
+        return 0;
 }
 //=============================================================================
 /*!
@@ -381,7 +371,7 @@ CORBA::Long SMESH_MEDSupport_i::getNumberOfTypes()
  * included in the support 
  */
 //=============================================================================
-SALOME_MED::long_array* SMESH_MEDSupport_i::getNumbersOfGaussPoint()
+SALOME_TYPES::ListOfLong* SMESH_MEDSupport_i::getNumbersOfGaussPoint()
   throw (SALOME::SALOME_Exception)
 {
   MESSAGE("!!! NOT YET IMPLEMENTED !!!!");
index 15cf3b8f4fa8ce0e021d98ccb22aae14114c4ed6..67761e2e810525c8e66a4e9e32961923b60cba38 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 // File : SMESH_MEDSupport_i.hxx
 // Module : SMESH
 
 #include "SMESH_MEDSupport_i.hxx"
 #include "SALOME_GenericObj_i.hh"
+class SMESH_subMesh;
 class SMESH_subMesh_i;
 
 class SMESH_I_EXPORT SMESH_MEDSupport_i:
-       public virtual POA_SALOME_MED::SUPPORT, public virtual SALOME::GenericObj_i
+        public virtual POA_SALOME_MED::SUPPORT, public virtual SALOME::GenericObj_i
 {
   public:
 
 // Constructors and associated internal methods
-       SMESH_MEDSupport_i(SMESH_subMesh_i * sm,
-               std::string name, std::string description, SALOME_MED::medEntityMesh entity);
-       SMESH_MEDSupport_i(const SMESH_MEDSupport_i & s);
+        SMESH_MEDSupport_i(SMESH_subMesh_i * sm,
+                std::string name, std::string description, SALOME_MED::medEntityMesh entity);
+        SMESH_MEDSupport_i(const SMESH_MEDSupport_i & s);
 
 // IDL Methods
-       char *getName() throw(SALOME::SALOME_Exception);
-       char *getDescription() throw(SALOME::SALOME_Exception);
-       SALOME_MED::MESH_ptr getMesh() throw(SALOME::SALOME_Exception);
-       CORBA::Boolean isOnAllElements() throw(SALOME::SALOME_Exception);
-       SALOME_MED::medEntityMesh getEntity() throw(SALOME::SALOME_Exception);
+        char *getName() throw(SALOME::SALOME_Exception);
+        char *getDescription() throw(SALOME::SALOME_Exception);
+        SALOME_MED::GMESH_ptr getMesh() throw(SALOME::SALOME_Exception);
+        CORBA::Boolean isOnAllElements() throw(SALOME::SALOME_Exception);
+        SALOME_MED::medEntityMesh getEntity() throw(SALOME::SALOME_Exception);
         CORBA::Long
-       getNumberOfElements(SALOME_MED::medGeometryElement geomElement)
-         throw(SALOME::SALOME_Exception);
+        getNumberOfElements(SALOME_MED::medGeometryElement geomElement)
+          throw(SALOME::SALOME_Exception);
 
         CORBA::Long getNumberOfTypes() throw (SALOME::SALOME_Exception);
 
-       SALOME_MED::long_array *
-       getNumber(SALOME_MED::medGeometryElement geomElement)
-         throw(SALOME::SALOME_Exception);
+        SALOME_TYPES::ListOfLong *
+        getNumber(SALOME_MED::medGeometryElement geomElement)
+          throw(SALOME::SALOME_Exception);
 
   /*!
    * Same function as getNumber.
    */
-       SALOME_MED::long_array *
-       getNumberFromFile(SALOME_MED::medGeometryElement geomElement)
-         throw(SALOME::SALOME_Exception);
+        SALOME_TYPES::ListOfLong *
+        getNumberFromFile(SALOME_MED::medGeometryElement geomElement)
+          throw(SALOME::SALOME_Exception);
 
-       SALOME_MED::long_array * getNumberIndex()
-         throw(SALOME::SALOME_Exception);
+        SALOME_TYPES::ListOfLong * getNumberIndex()
+          throw(SALOME::SALOME_Exception);
 
         CORBA::Long
-       getNumberOfGaussPoint(SALOME_MED::medGeometryElement geomElement)
-         throw(SALOME::SALOME_Exception);
+        getNumberOfGaussPoint(SALOME_MED::medGeometryElement geomElement)
+          throw(SALOME::SALOME_Exception);
 
-        SALOME_MED::long_array* getNumbersOfGaussPoint()
-         throw (SALOME::SALOME_Exception);
+        SALOME_TYPES::ListOfLong* getNumbersOfGaussPoint()
+          throw (SALOME::SALOME_Exception);
 
-       SALOME_MED::medGeometryElement_array *getTypes()
-         throw(SALOME::SALOME_Exception);
+        SALOME_MED::medGeometryElement_array *getTypes()
+          throw(SALOME::SALOME_Exception);
 
         void getBoundaryElements() throw (SALOME::SALOME_Exception);
 
-       CORBA::Long getCorbaIndex() throw(SALOME::SALOME_Exception);
+        CORBA::Long getCorbaIndex() throw(SALOME::SALOME_Exception);
 
         SALOME_MED::SUPPORT::supportInfos * getSupportGlobal()
-         throw (SALOME::SALOME_Exception);
+          throw (SALOME::SALOME_Exception);
 
-       void createSeq() throw(SALOME::SALOME_Exception);
+        void createSeq() throw(SALOME::SALOME_Exception);
 
   public: //public field
-       const SMESHDS_SubMesh * _subMeshDS;
-       ::SMESH_subMesh_i * _subMesh_i;
+        SMESH_subMesh_i * _subMesh_i;
+        ::SMESH_subMesh * _subMesh;
 
-       SMESHDS_Mesh * _meshDS;
-       std::string _name;
+        std::string _name;
         std::string _description;
-       bool _isOnAllElements;
-       bool _seqNumber;
-       int _seqLength;
+        bool _isOnAllElements;
+        bool _seqNumber;
+        int _seqLength;
 
-       SALOME_MED::medEntityMesh _entity;
-       SALOME_MED::medGeometryElement * _geometricType;
-       int _numberOfGeometricType;
+        SALOME_MED::medEntityMesh _entity;
+        SALOME_MED::medGeometryElement * _geometricType;
+        int _numberOfGeometricType;
 
   protected:
-       SMESH_MEDSupport_i();
-       ~SMESH_MEDSupport_i();
+        SMESH_MEDSupport_i();
+        ~SMESH_MEDSupport_i();
 };
 
 #endif /* _MED_MEDSUPPORT_I_HXX_ */
diff --git a/src/SMESH_I/SMESH_Measurements_i.cxx b/src/SMESH_I/SMESH_Measurements_i.cxx
new file mode 100644 (file)
index 0000000..48572a3
--- /dev/null
@@ -0,0 +1,259 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+//  File   : SMESH_Measurements_i.cxx
+//  Author : Pavel TELKOV, Open CASCADE S.A.S. (pavel.telkov@opencascade.com)
+
+#include "SMESH_Measurements_i.hxx"
+
+#include "SMESH_Gen_i.hxx"
+#include "SMESH_PythonDump.hxx"
+
+#include "SMDS_Mesh.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_ElemIterator.hxx"
+
+#include "SMESHDS_Mesh.hxx"
+
+
+using namespace SMESH;
+
+/**
+ * this local function to avoid uninitialized fields
+ */
+static void initMeasure( SMESH::Measure& theMeasure)
+{
+
+  theMeasure.minX = theMeasure.minY = theMeasure.minZ = 0.;
+  theMeasure.maxX = theMeasure.maxY = theMeasure.maxZ = 0.;
+  theMeasure.node1 = theMeasure.node2 = -1;
+  theMeasure.elem1 = theMeasure.elem2 = -1;
+  theMeasure.value = 0.;
+}
+
+//=============================================================================
+/*!
+ *  SMESH_Gen_i::CreateMeasurements
+ *
+ *  Create measurement instance
+ */
+//=============================================================================
+
+SMESH::Measurements_ptr SMESH_Gen_i::CreateMeasurements()
+{
+  SMESH::Measurements_i* aMeasure = new SMESH::Measurements_i();
+  SMESH::Measurements_var anObj = aMeasure->_this();
+  return anObj._retn();
+}
+
+  
+/*
+  Class       : Measurements
+  Description : make measure of mesh qunatities
+*/
+
+//=======================================================================
+// name    : Measurements_i
+// Purpose : Constructor
+//=======================================================================
+Measurements_i::Measurements_i()
+: SALOME::GenericObj_i( SMESH_Gen_i::GetPOA() )
+{
+  //Base class Salome_GenericObject do it inmplicitly by overriding PortableServer::POA_ptr _default_POA() method
+  //PortableServer::ObjectId_var anObjectId =
+  //  SMESH_Gen_i::GetPOA()->activate_object( this );
+}
+
+//=======================================================================
+// name    : ~Measurements_i
+// Purpose : Destructor
+//=======================================================================
+Measurements_i::~Measurements_i()
+{
+  //TPythonDump()<<this<<".UnRegister()";
+}
+
+static bool getNodeNodeDistance (SMESH::Measure& theMeasure,
+                                 const SMDS_MeshNode* theNode1,
+                                 const SMDS_MeshNode* theNode2 = 0)
+{
+  double dist = 0., dd = 0.;
+
+  if (!theNode1)
+    return false;
+
+  dd = theNode1->X(); if (theNode2) dd -= theNode2->X(); theMeasure.minX = dd; dd *= dd; dist += dd;
+  dd = theNode1->Y(); if (theNode2) dd -= theNode2->Y(); theMeasure.minY = dd; dd *= dd; dist += dd;
+  dd = theNode1->Z(); if (theNode2) dd -= theNode2->Z(); theMeasure.minZ = dd; dd *= dd; dist += dd;
+
+  if (dist < 0)
+    return false;
+  
+  theMeasure.value = sqrt(dist);
+  theMeasure.node1 = theNode1->GetID();
+  theMeasure.node2 = theNode2 ? theNode2->GetID() : 0;
+
+  return true;
+}
+
+static SMESHDS_Mesh* getMesh(SMESH::SMESH_IDSource_ptr theSource)
+{
+  if (!CORBA::is_nil( theSource ))
+  {
+    SMESH_Mesh_i* anImplPtr = DownCast<SMESH_Mesh_i*>(theSource->GetMesh());
+    if (anImplPtr)
+      return anImplPtr->GetImpl().GetMeshDS();
+  }
+  return 0;
+}
+
+static bool isNodeType (SMESH::array_of_ElementType_var theTypes)
+{
+  return theTypes->length() > 0 && theTypes[0] == SMESH::NODE;
+}
+
+//=======================================================================
+// name    : MinDistance
+// Purpose : minimal distance between two given entities
+//=======================================================================
+SMESH::Measure Measurements_i::MinDistance
+ (SMESH::SMESH_IDSource_ptr theSource1,
+  SMESH::SMESH_IDSource_ptr theSource2)
+{
+  SMESH::Measure aMeasure;
+  initMeasure(aMeasure);
+
+  if (CORBA::is_nil( theSource1 ))
+    return aMeasure;
+  
+  // if second source is null, min distance from theSource1 to the origin is calculated
+  bool isOrigin =  CORBA::is_nil( theSource2 );
+
+  // calculate minimal distance between two mesh entities
+  SMESH::array_of_ElementType_var types1 = theSource1->GetTypes();
+  SMESH::array_of_ElementType_var types2;
+  if ( !isOrigin ) types2 = theSource2->GetTypes();
+
+  // here we assume that type of all IDs defined by first type in array
+  bool isNode1 = isNodeType(types1);
+  bool isNode2 = isOrigin || isNodeType(types2);
+
+  SMESH::long_array_var aElementsId1 = theSource1->GetIDs();
+  SMESH::long_array_var aElementsId2;
+  if ( !isOrigin ) aElementsId2 = theSource2->GetIDs();
+
+  // compute distance between two entities
+  /* NOTE: currently only node-to-node case is implemented
+   * all other cases will be implemented later
+   * below IF should be replaced by complete switch
+   * on mesh entities types
+   */
+  if (isNode1 && isNode2)
+  {
+    // node - node
+    const SMESHDS_Mesh* aMesh1 = getMesh( theSource1 );
+    const SMESHDS_Mesh* aMesh2 = isOrigin ? 0 : getMesh( theSource2 );
+    const SMDS_MeshNode* theNode1 = aMesh1 ? aMesh1->FindNode( aElementsId1[0] ) : 0;
+    const SMDS_MeshNode* theNode2 = aMesh2 ? aMesh2->FindNode( aElementsId2[0] ) : 0;
+    getNodeNodeDistance( aMeasure, theNode1, theNode2 );
+  }
+  else
+  {
+    // NOT_IMPLEMENTED
+  }
+
+  return aMeasure;
+}
+
+//=======================================================================
+// name    : enlargeBoundingBox
+// Purpose : 
+//=======================================================================
+static void enlargeBoundingBox(const SMDS_MeshNode* theNode,
+                               SMESH::Measure&      theMeasure)
+{
+  if (!theNode)
+    return;
+  if ( theMeasure.node1 == -1 ) {
+    // we use this attribute as a flag that it is the first node added to the bnd box 
+    theMeasure.minX = theMeasure.maxX = theNode->X();
+    theMeasure.minY = theMeasure.maxY = theNode->Y();
+    theMeasure.minZ = theMeasure.maxZ = theNode->Z();
+    theMeasure.node1 = theNode->GetID();
+  }
+  else {
+    theMeasure.minX = min( theMeasure.minX, theNode->X() );
+    theMeasure.maxX = max( theMeasure.maxX, theNode->X() );
+    theMeasure.minY = min( theMeasure.minY, theNode->Y() );
+    theMeasure.maxY = max( theMeasure.maxY, theNode->Y() );
+    theMeasure.minZ = min( theMeasure.minZ, theNode->Z() );
+    theMeasure.maxZ = max( theMeasure.maxZ, theNode->Z() );
+  }
+}
+
+//=======================================================================
+// name    : enlargeBoundingBox
+// Purpose : 
+//=======================================================================
+static void enlargeBoundingBox(const SMESH::SMESH_IDSource_ptr theObject,
+                               SMESH::Measure&                 theMeasure)
+{
+  if ( CORBA::is_nil( theObject ) )
+    return;
+  const SMESHDS_Mesh* aMesh = getMesh( theObject );
+  if ( !aMesh )
+    return;
+  SMESH::array_of_ElementType_var types = theObject->GetTypes();
+  SMESH::long_array_var     aElementsId = theObject->GetIDs();
+  // here we assume that type of all IDs defined by first type in array
+  const bool isNode = isNodeType( types );
+  for(int i = 0, n = aElementsId->length(); i < n; i++)
+  {
+    if (isNode)
+      enlargeBoundingBox( aMesh->FindNode( aElementsId[i] ), theMeasure);
+    else
+    {
+      const SMDS_MeshElement* elem = aMesh->FindElement( aElementsId[i] );
+      if (!elem)
+        continue;
+      SMDS_ElemIteratorPtr aNodeIter = elem->nodesIterator();
+      while( aNodeIter->more() )
+        enlargeBoundingBox( dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() ), theMeasure);
+    }
+  }
+}
+                               
+//=======================================================================
+// name    : BoundingBox
+// Purpose : compute common bounding box of entities
+//=======================================================================
+SMESH::Measure Measurements_i::BoundingBox (const SMESH::ListOfIDSources& theSources)
+{
+  SMESH::Measure aMeasure;
+  initMeasure(aMeasure);
+
+  // calculate bounding box on sources
+  for ( int i = 0, n = theSources.length(); i < n ; ++i )
+    enlargeBoundingBox( theSources[i], aMeasure );
+
+  return aMeasure;
+}
diff --git a/src/SMESH_I/SMESH_Measurements_i.hxx b/src/SMESH_I/SMESH_Measurements_i.hxx
new file mode 100644 (file)
index 0000000..df380ab
--- /dev/null
@@ -0,0 +1,63 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+//  File   : SMESH_Measurements_i.hxx
+//  Author : Pavel TELKOV, Open CASCADE S.A.S. (pavel.telkov@opencascade.com)
+
+#ifndef _SMESH_MEASUREMENTS_I_HXX_
+#define _SMESH_MEASUREMENTS_I_HXX_
+
+#include "SMESH.hxx"
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Measurements)
+
+#include "SALOME_GenericObj_i.hh"
+
+class SMESHDS_Mesh;
+
+namespace SMESH
+{
+
+  /*
+    Measurements
+  */
+  class SMESH_I_EXPORT Measurements_i: public virtual POA_SMESH::Measurements,
+                                       public virtual SALOME::GenericObj_i
+  {
+  public:
+    Measurements_i();
+    ~Measurements_i();
+
+    /*!
+     * minimal distance between two given entities
+     */
+    SMESH::Measure MinDistance(SMESH::SMESH_IDSource_ptr theSource1,
+                               SMESH::SMESH_IDSource_ptr theSource2);
+
+    /*!
+     * common bounding box of entities
+     */
+    SMESH::Measure BoundingBox(const SMESH::ListOfIDSources& theSources);
+  };
+}
+
+#endif
index 8fb61b896e89eafb46c63975dcc108759f014239..026eed079f2ac031ff0f0e4236db2b5e8091bc20 100644 (file)
@@ -1,40 +1,48 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : SMESH_MeshEditor_i.cxx
 //  Author : Nicolas REJNERI
 //  Module : SMESH
 
+#ifdef WNT
+#define NOMINMAX
+#endif
+
 #include "SMESH_MeshEditor_i.hxx"
 
-#include "SMDS_MeshEdge.hxx"
+#include "SMDS_LinearEdge.hxx"
+#include "SMDS_Mesh0DElement.hxx"
 #include "SMDS_MeshFace.hxx"
 #include "SMDS_MeshVolume.hxx"
 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
-#include "SMESH_MeshEditor.hxx"
-#include "SMESH_subMeshEventListener.hxx"
-#include "SMESH_Gen_i.hxx"
+#include "SMDS_SetIterator.hxx"
+#include "SMESHDS_Group.hxx"
+#include "SMESH_ControlsDef.hxx"
 #include "SMESH_Filter_i.hxx"
+#include "SMESH_Gen_i.hxx"
+#include "SMESH_Group_i.hxx"
 #include "SMESH_PythonDump.hxx"
+#include "SMESH_subMeshEventListener.hxx"
+#include "SMESH_subMesh_i.hxx"
 
 #include "utilities.h"
 #include "Utils_ExceptHandlers.hxx"
 #endif
 
 #include <sstream>
+#include <limits>
 
 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
 
 using namespace std;
 using SMESH::TPythonDump;
+using SMESH::TVar;
 
 namespace {
 
@@ -80,12 +90,12 @@ namespace {
     SMDSAbs_ElementType myPreviewType; // type to show
     //!< Constructor
     TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
-      _isShapeToMesh = _id =_studyId =_idDoc = 0;
+      _isShapeToMesh = (_id =_studyId =_idDoc = 0);
       _myMeshDS  = new SMESHDS_Mesh( _id, true );
       myPreviewType = previewElements;
     }
     //!< Destructor
-    virtual ~TPreviewMesh() { delete _myMeshDS; }
+    virtual ~TPreviewMesh() { delete _myMeshDS; _myMeshDS = 0; }
     //!< Copy a set of elements
     void Copy(const TIDSortedElemSet & theElements,
               TIDSortedElemSet&        theCopyElements,
@@ -102,8 +112,12 @@ namespace {
         if ( type == theAvoidType ||
              ( theSelectType != SMDSAbs_All && type != theSelectType ))
           continue;
-
-        if ( const SMDS_MeshElement* anElemCopy = Copy( anElem ))
+        const SMDS_MeshElement* anElemCopy;
+        if ( type == SMDSAbs_Node)
+          anElemCopy = Copy( cast2Node(anElem) );
+        else
+          anElemCopy = Copy( anElem );
+        if ( anElemCopy )
           theCopyElements.insert( theCopyElements.end(), anElemCopy );
       }
     }
@@ -125,11 +139,11 @@ namespace {
       SMDS_MeshElement* anElemCopy = 0;
       if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
       {
-        const SMDS_PolyhedralVolumeOfNodes* ph =
-          dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem);
+        const SMDS_VtkVolume* ph =
+          dynamic_cast<const SMDS_VtkVolume*> (anElem);
         if ( ph )
           anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
-            (anElemNodesID, ph->GetQuanities(),anElem->GetID());
+            (anElemNodesID, ph->GetQuantities(),anElem->GetID());
       }
       else {
         anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
@@ -141,29 +155,33 @@ namespace {
     //!< Copy a node
     SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
     {
-      return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(), 
+      return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(),
                                       anElemNode->GetID());
     }
   };// struct TPreviewMesh
 
-  static SMESH_NodeSearcher * myNodeSearcher = 0;
+  static SMESH_NodeSearcher *    theNodeSearcher    = 0;
+  static SMESH_ElementSearcher * theElementSearcher = 0;
 
   //=============================================================================
   /*!
-   * \brief Deleter of myNodeSearcher at any compute event occured
+   * \brief Deleter of theNodeSearcher at any compute event occured
    */
   //=============================================================================
 
-  struct TNodeSearcherDeleter : public SMESH_subMeshEventListener
+  struct TSearchersDeleter : public SMESH_subMeshEventListener
   {
     SMESH_Mesh* myMesh;
+    string      myMeshPartIOR;
     //!< Constructor
-    TNodeSearcherDeleter(): SMESH_subMeshEventListener( false ), // won't be deleted by submesh
-    myMesh(0) {}
-    //!< Delete myNodeSearcher
+    TSearchersDeleter(): SMESH_subMeshEventListener( false, // won't be deleted by submesh
+                                                     "SMESH_MeshEditor_i::TSearchersDeleter"),
+                         myMesh(0) {}
+    //!< Delete theNodeSearcher
     static void Delete()
     {
-      if ( myNodeSearcher ) { delete myNodeSearcher; myNodeSearcher = 0; }
+      if ( theNodeSearcher )    delete theNodeSearcher;    theNodeSearcher    = 0;
+      if ( theElementSearcher ) delete theElementSearcher; theElementSearcher = 0;
     }
     typedef map < int, SMESH_subMesh * > TDependsOnMap;
     //!< The meshod called by submesh: do my main job
@@ -175,19 +193,23 @@ namespace {
         Unset( sm->GetFather() );
       }
     }
-    //!< set self on all submeshes and delete myNodeSearcher if other mesh is set
-    void Set(SMESH_Mesh* mesh)
+    //!< set self on all submeshes and delete theNodeSearcher if other mesh is set
+    void Set(SMESH_Mesh* mesh, const string& meshPartIOR = string())
     {
-      if ( myMesh && myMesh != mesh ) {
-        Delete();
-        Unset( myMesh );
-      }
-      myMesh = mesh;
-      if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
-        const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
-        TDependsOnMap::const_iterator sm;
-        for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
-          sm->second->SetEventListener( this, 0, sm->second );
+      if ( myMesh != mesh || myMeshPartIOR != meshPartIOR)
+      {
+        if ( myMesh ) {
+          Delete();
+          Unset( myMesh );
+        }
+        myMesh = mesh;
+        myMeshPartIOR = meshPartIOR;
+        if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
+          const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
+          TDependsOnMap::const_iterator sm;
+          for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
+            sm->second->SetEventListener( this, 0, sm->second );
+        }
       }
     }
     //!<  delete self from all submeshes
@@ -199,8 +221,10 @@ namespace {
         for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
           sm->second->DeleteEventListener( this );
       }
+      myMesh = 0;
     }
-  };
+
+  } theSearchersDeleter;
 
   TCollection_AsciiString mirrorTypeName( SMESH::SMESH_MeshEditor::MirrorType theMirrorType )
   {
@@ -217,6 +241,162 @@ namespace {
     }
     return typeStr;
   }
+  //================================================================================
+  /*!
+   * \brief function for conversion of long_array to TIDSortedElemSet
+   * \param IDs - array of IDs
+   * \param aMesh - mesh
+   * \param aMap - collection to fill
+   * \param aType - element type
+   */
+  //================================================================================
+
+  void arrayToSet(const SMESH::long_array & IDs,
+                  const SMESHDS_Mesh*       aMesh,
+                  TIDSortedElemSet&         aMap,
+                  const SMDSAbs_ElementType aType = SMDSAbs_All )
+  {
+    for (int i=0; i<IDs.length(); i++) {
+      CORBA::Long ind = IDs[i];
+      const SMDS_MeshElement * elem =
+        (aType == SMDSAbs_Node ? aMesh->FindNode(ind) : aMesh->FindElement(ind));
+      if ( elem && ( aType == SMDSAbs_All || elem->GetType() == aType ))
+        aMap.insert( elem );
+    }
+  }
+  //================================================================================
+  /*!
+   * \brief Retrieve elements of given type from SMESH_IDSource
+   */
+  //================================================================================
+
+  bool idSourceToSet(SMESH::SMESH_IDSource_ptr  theIDSource,
+                     const SMESHDS_Mesh*        theMeshDS,
+                     TIDSortedElemSet&          theElemSet,
+                     const SMDSAbs_ElementType  theType,
+                     const bool                 emptyIfIsMesh=false)
+
+  {
+    if ( CORBA::is_nil( theIDSource ) )
+      return false;
+    if ( emptyIfIsMesh && SMESH::DownCast<SMESH_Mesh_i*>( theIDSource ))
+      return true;
+
+    SMESH::long_array_var anIDs = theIDSource->GetIDs();
+    if ( anIDs->length() == 0 )
+      return false;
+    SMESH::array_of_ElementType_var types = theIDSource->GetTypes();
+    if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
+    {
+      if ( theType == SMDSAbs_All || theType == SMDSAbs_Node )
+        arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node );
+      else
+        return false;
+    }
+    else
+    {
+      arrayToSet( anIDs, theMeshDS, theElemSet, theType);
+      return bool(anIDs->length()) == bool(theElemSet.size());
+    }
+    return true;
+  }
+  //================================================================================
+  /*!
+   * \brief Retrieve nodes from SMESH_IDSource
+   */
+  //================================================================================
+
+  void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr  theObject,
+                         const SMESHDS_Mesh*        theMeshDS,
+                         TIDSortedNodeSet&          theNodeSet)
+
+  {
+    if ( CORBA::is_nil( theObject ) )
+      return;
+    SMESH::array_of_ElementType_var types = theObject->GetTypes();
+    SMESH::long_array_var     aElementsId = theObject->GetIDs();
+    if ( types->length() == 1 && types[0] == SMESH::NODE)
+    {
+      for(int i = 0; i < aElementsId->length(); i++)
+        if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
+          theNodeSet.insert( theNodeSet.end(), n);
+    }
+    else if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
+    {
+      SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
+      while ( nIt->more( ))
+        if( const SMDS_MeshElement * elem = nIt->next() )
+          theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
+    }
+    else
+    {
+      for(int i = 0; i < aElementsId->length(); i++)
+        if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
+          theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
+    }
+  }
+
+  //================================================================================
+  /*!
+   * \brief Returns elements connected to the given elements
+   */
+  //================================================================================
+
+  void getElementsAround(const TIDSortedElemSet& theElements,
+                         const SMESHDS_Mesh*     theMeshDS,
+                         TIDSortedElemSet&       theElementsAround)
+  {
+    if ( theElements.empty() ) return;
+
+    SMDSAbs_ElementType elemType    = (*theElements.begin())->GetType();
+    bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
+    if ( sameElemType &&
+         theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
+      return; // all the elements are in theElements
+
+    if ( !sameElemType )
+      elemType = SMDSAbs_All;
+
+    TIDSortedElemSet visitedNodes;
+    TIDSortedElemSet::const_iterator elemIt = theElements.begin();
+    for ( ; elemIt != theElements.end(); ++elemIt )
+    {
+      const SMDS_MeshElement* e = *elemIt;
+      int i = e->NbCornerNodes();
+      while ( --i != -1 )
+      {
+        const SMDS_MeshNode* n = e->GetNode( i );
+        if ( visitedNodes.insert( n ).second )
+        {
+          SMDS_ElemIteratorPtr invIt = n->GetInverseElementIterator(elemType);
+          while ( invIt->more() )
+          {
+            const SMDS_MeshElement* elemAround = invIt->next();
+            if ( !theElements.count( elemAround ))
+              theElementsAround.insert( elemAround );
+          }
+        }
+      }
+    }
+  }
+
+  //================================================================================
+  /*!
+   * \brief Return a string used to detect change of mesh part on which theElementSearcher
+   * is going to be used
+   */
+  //================================================================================
+
+  string getPartIOR( SMESH::SMESH_IDSource_ptr theMeshPart, SMESH::ElementType type)
+  {
+    string partIOR = SMESH_Gen_i::GetORB()->object_to_string( theMeshPart );
+    if ( SMESH_Group_i* group_i = SMESH::DownCast<SMESH_Group_i*>( theMeshPart ))
+      // take into account passible group modification
+      partIOR += SMESH_Comment( ((SMESHDS_Group*)group_i->GetGroupDS())->SMDSGroup().Tic() );
+    partIOR += SMESH_Comment( type );
+    return partIOR;
+  }
+
 }
 
 //=============================================================================
@@ -225,11 +405,12 @@ namespace {
  */
 //=============================================================================
 
-SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview)
+SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh_i* theMesh, bool isPreview):
+  myMesh_i( theMesh ),
+  myMesh( &theMesh->GetImpl() ),
+  myEditor( myMesh ),
+  myPreviewMode ( isPreview )
 {
-  myMesh_i = theMesh;
-  myMesh = & theMesh->GetImpl();
-  myPreviewMode = isPreview;
 }
 
 //================================================================================
@@ -248,16 +429,173 @@ SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
  */
 //================================================================================
 
-void SMESH_MeshEditor_i::initData()
+void SMESH_MeshEditor_i::initData(bool deleteSearchers)
 {
   if ( myPreviewMode ) {
-    myPreviewData = new SMESH::MeshPreviewStruct();
+    //myPreviewData = new SMESH::MeshPreviewStruct();
   }
   else {
-    myLastCreatedElems = new SMESH::long_array();
-    myLastCreatedNodes = new SMESH::long_array();
-    TNodeSearcherDeleter::Delete();
+    if ( deleteSearchers )
+      TSearchersDeleter::Delete();
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Now does nothing
+ */
+//================================================================================
+
+void SMESH_MeshEditor_i::storeResult(::SMESH_MeshEditor& )
+{
+}
+
+//================================================================================
+/*!
+ * Return data of mesh edition preview
+ */
+//================================================================================
+
+SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
+{
+  if ( myPreviewMode ) { // --- MeshPreviewStruct filling ---
+
+    list<int> aNodesConnectivity;
+    typedef map<int, int> TNodesMap;
+    TNodesMap nodesMap;
+
+    TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( myEditor.GetMesh() );
+    SMDSAbs_ElementType previewType = aPreviewMesh->myPreviewType;
+
+    SMESHDS_Mesh* aMeshDS = myEditor.GetMeshDS();
+    int nbEdges = aMeshDS->NbEdges();
+    int nbFaces = aMeshDS->NbFaces();
+    int nbVolum = aMeshDS->NbVolumes();
+    switch ( previewType ) {
+    case SMDSAbs_Edge  : nbFaces = nbVolum = 0; break;
+    case SMDSAbs_Face  : nbEdges = nbVolum = 0; break;
+    case SMDSAbs_Volume: nbEdges = nbFaces = 0; break;
+    default:;
+    }
+    myPreviewData = new SMESH::MeshPreviewStruct();
+    myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
+    myPreviewData->elementTypes.length(nbEdges + nbFaces + nbVolum);
+    int i = 0, j = 0;
+    SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator();
+
+    while ( itMeshElems->more() ) {
+      const SMDS_MeshElement* aMeshElem = itMeshElems->next();
+      if ( previewType != SMDSAbs_All && aMeshElem->GetType() != previewType )
+        continue;
+
+      SMDS_ElemIteratorPtr itElemNodes = aMeshElem->nodesIterator();
+      while ( itElemNodes->more() ) {
+        const SMDS_MeshNode* aMeshNode =
+          static_cast<const SMDS_MeshNode*>( itElemNodes->next() );
+        int aNodeID = aMeshNode->GetID();
+        TNodesMap::iterator anIter = nodesMap.find(aNodeID);
+        if ( anIter == nodesMap.end() ) {
+          // filling the nodes coordinates
+          myPreviewData->nodesXYZ[j].x = aMeshNode->X();
+          myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
+          myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
+          anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
+          j++;
+        }
+        aNodesConnectivity.push_back(anIter->second);
+      }
+
+      // filling the elements types
+      SMDSAbs_ElementType aType = aMeshElem->GetType();
+      bool               isPoly = aMeshElem->IsPoly();
+
+      myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
+      myPreviewData->elementTypes[i].isPoly = isPoly;
+      myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
+      i++;
+
+    }
+    myPreviewData->nodesXYZ.length( j );
+
+    // filling the elements connectivities
+    list<int>::iterator aConnIter = aNodesConnectivity.begin();
+    myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
+    for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
+      myPreviewData->elementConnectivities[i] = *aConnIter;
+  }
+
+  return myPreviewData._retn();
+}
+
+//================================================================================
+/*!
+ * \brief Returns list of it's IDs of created nodes
+ * \retval SMESH::long_array* - list of node ID
+ */
+//================================================================================
+
+SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
+{
+  SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
+  const SMESH_SequenceOfElemPtr& aSeq = myEditor.GetLastCreatedNodes();
+  myLastCreatedNodes->length( aSeq.Length() );
+  for (int i = 1; i <= aSeq.Length(); i++)
+    myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID();
+  return myLastCreatedNodes._retn();
+}
+
+//================================================================================
+/*!
+ * \brief Returns list of it's IDs of created elements
+ * \retval SMESH::long_array* - list of elements' ID
+ */
+//================================================================================
+
+SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
+{
+  SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
+  const SMESH_SequenceOfElemPtr& aSeq = myEditor.GetLastCreatedElems();
+  myLastCreatedElems->length( aSeq.Length() );
+  for ( int i = 1; i <= aSeq.Length(); i++ )
+    myLastCreatedElems[i-1] = aSeq.Value(i)->GetID();
+  return myLastCreatedElems._retn();
+}
+
+//=======================================================================
+//function : MakeIDSource
+//purpose  : Wrap a sequence of ids in a SMESH_IDSource
+//=======================================================================
+
+struct _IDSource : public POA_SMESH::SMESH_IDSource
+{
+  SMESH::long_array     _ids;
+  SMESH::ElementType    _type;
+  SMESH::SMESH_Mesh_ptr _mesh;
+  SMESH::long_array* GetIDs()      { return new SMESH::long_array( _ids ); }
+  SMESH::long_array* GetMeshInfo() { return 0; }
+  SMESH::SMESH_Mesh_ptr GetMesh()  { return SMESH::SMESH_Mesh::_duplicate( _mesh ); }
+  bool IsMeshInfoCorrect()         { return true; }
+  SMESH::array_of_ElementType* GetTypes()
+  {
+    SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
+    if ( _ids.length() > 0 ) {
+      types->length( 1 );
+      types[0] = _type;
+    }
+    return types._retn();
   }
+};
+
+SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids,
+                                                           SMESH::ElementType       type)
+{
+  _IDSource* anIDSource = new _IDSource;
+  anIDSource->_ids = ids;
+  anIDSource->_type = type;
+  anIDSource->_mesh = myMesh_i->_this();
+  SMESH::SMESH_IDSource_var anIDSourceVar = anIDSource->_this();
+
+  return anIDSourceVar._retn();
 }
 
 //=============================================================================
@@ -267,11 +605,10 @@ void SMESH_MeshEditor_i::initData()
 //=============================================================================
 
 CORBA::Boolean
-  SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
+SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
 {
   initData();
 
-  ::SMESH_MeshEditor anEditor( myMesh );
   list< int > IdList;
 
   for (int i = 0; i < IDsOfElements.length(); i++)
@@ -279,11 +616,13 @@ CORBA::Boolean
 
   // Update Python script
   TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
-#ifdef _DEBUG_
-  TPythonDump() << "print 'RemoveElements: ', isDone";
-#endif
+
   // Remove Elements
-  return anEditor.Remove( IdList, false );
+  bool ret = myEditor.Remove( IdList, false );
+  myMesh->GetMeshDS()->Modified();
+  if ( IDsOfElements.length() )
+    myMesh->SetIsModified( true ); // issue 0020693
+  return ret;
 }
 
 //=============================================================================
@@ -296,18 +635,18 @@ CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNo
 {
   initData();
 
-  ::SMESH_MeshEditor anEditor( myMesh );
   list< int > IdList;
   for (int i = 0; i < IDsOfNodes.length(); i++)
     IdList.push_back( IDsOfNodes[i] );
 
   // Update Python script
   TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
-#ifdef _DEBUG_
-  TPythonDump() << "print 'RemoveNodes: ', isDone";
-#endif
 
-  return anEditor.Remove( IdList, true );
+  bool ret = myEditor.Remove( IdList, true );
+  myMesh->GetMeshDS()->Modified();
+  if ( IDsOfNodes.length() )
+    myMesh->SetIsModified( true ); // issue 0020693
+  return ret;
 }
 
 //=============================================================================
@@ -316,43 +655,37 @@ CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNo
  */
 //=============================================================================
 
-CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
+CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes()
 {
   initData();
 
-  int NbNodes = IDsOfNodes.length();
-  SMDS_MeshElement* elem = 0;
-  if (NbNodes == 2)
-  {
-    CORBA::Long index1 = IDsOfNodes[0];
-    CORBA::Long index2 = IDsOfNodes[1];
-    elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(index1), GetMeshDS()->FindNode(index2));
 
-    // Update Python script
-    TPythonDump() << "edge = " << this << ".AddEdge([ "
-                  << index1 << ", " << index2 <<" ])";
-  }
-  if (NbNodes == 3) {
-    CORBA::Long n1 = IDsOfNodes[0];
-    CORBA::Long n2 = IDsOfNodes[1];
-    CORBA::Long n12 = IDsOfNodes[2];
-    elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(n1),
-                                GetMeshDS()->FindNode(n2),
-                                GetMeshDS()->FindNode(n12));
-    // Update Python script
-    TPythonDump() << "edgeID = " << this << ".AddEdge([ "
-                  <<n1<<", "<<n2<<", "<<n12<<" ])";
-  }
+  // Update Python script
+  TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()";
 
-  if(elem)
-    return elem->GetID();
+  // Create filter to find all orphan nodes
+  SMESH::Controls::Filter::TIdSequence seq;
+  SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() );
+  SMESH::Controls::Filter::GetElementsId( GetMeshDS(), predicate, seq );
 
-  return 0;
+  // remove orphan nodes (if there are any)
+  list< int > IdList;
+  for ( int i = 0; i < seq.size(); i++ )
+    IdList.push_back( seq[i] );
+
+  int nbNodesBefore = myMesh->NbNodes();
+  myEditor.Remove( IdList, true );
+  myMesh->GetMeshDS()->Modified();
+  if ( IdList.size() )
+    myMesh->SetIsModified( true );
+  int nbNodesAfter = myMesh->NbNodes();
+
+  return nbNodesBefore - nbNodesAfter;
 }
 
 //=============================================================================
 /*!
- *
+ * Add a new node.
  */
 //=============================================================================
 
@@ -365,37 +698,136 @@ CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
 
   // Update Python script
   TPythonDump() << "nodeID = " << this << ".AddNode( "
-                << x << ", " << y << ", " << z << " )";
+                << TVar( x ) << ", " << TVar( y ) << ", " << TVar( z )<< " )";
 
+  myMesh->GetMeshDS()->Modified();
+  myMesh->SetIsModified( true ); // issue 0020693
   return N->GetID();
 }
 
 //=============================================================================
 /*!
- *  AddFace
+ * Create 0D element on the given node.
  */
 //=============================================================================
 
-CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
+CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
 {
   initData();
 
-  int NbNodes = IDsOfNodes.length();
-  if (NbNodes < 3)
-  {
-    return 0;
-  }
+  const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDOfNode);
+  SMDS_MeshElement* elem = GetMeshDS()->Add0DElement(aNode);
 
-  std::vector<const SMDS_MeshNode*> nodes (NbNodes);
-  for (int i = 0; i < NbNodes; i++)
-    nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
+  // Update Python script
+  TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
 
-  SMDS_MeshElement* elem = 0;
-  if (NbNodes == 3) {
-    elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]);
-  }
-  else if (NbNodes == 4) {
-    elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]);
+  myMesh->GetMeshDS()->Modified();
+  myMesh->SetIsModified( true ); // issue 0020693
+
+  if (elem)
+    return elem->GetID();
+
+  return 0;
+}
+
+//=============================================================================
+/*!
+ * Create a ball element on the given node.
+ */
+//=============================================================================
+
+CORBA::Long SMESH_MeshEditor_i::AddBall(CORBA::Long IDOfNode, CORBA::Double diameter)
+  throw (SALOME::SALOME_Exception)
+{
+  initData();
+
+  if ( diameter < std::numeric_limits<double>::min() )
+    THROW_SALOME_CORBA_EXCEPTION("Invalid diameter", SALOME::BAD_PARAM);
+
+  const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDOfNode);
+  SMDS_MeshElement* elem = GetMeshDS()->AddBall(aNode, diameter);
+
+  // Update Python script
+  TPythonDump() << "ballElem = "
+                << this << ".AddBall( " << IDOfNode << ", " << diameter <<" )";
+
+  myMesh->GetMeshDS()->Modified();
+  myMesh->SetIsModified( true ); // issue 0020693
+
+  if (elem)
+    return elem->GetID();
+
+  return 0;
+}
+
+//=============================================================================
+/*!
+ * Create an edge, either linear and quadratic (this is determed
+ *  by number of given nodes, two or three)
+ */
+//=============================================================================
+
+CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
+{
+  initData();
+
+  int NbNodes = IDsOfNodes.length();
+  SMDS_MeshElement* elem = 0;
+  if (NbNodes == 2)
+  {
+    CORBA::Long index1 = IDsOfNodes[0];
+    CORBA::Long index2 = IDsOfNodes[1];
+    elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(index1), GetMeshDS()->FindNode(index2));
+
+    // Update Python script
+    TPythonDump() << "edge = " << this << ".AddEdge([ "
+                  << index1 << ", " << index2 <<" ])";
+  }
+  if (NbNodes == 3) {
+    CORBA::Long n1 = IDsOfNodes[0];
+    CORBA::Long n2 = IDsOfNodes[1];
+    CORBA::Long n12 = IDsOfNodes[2];
+    elem = GetMeshDS()->AddEdge(GetMeshDS()->FindNode(n1),
+                                GetMeshDS()->FindNode(n2),
+                                GetMeshDS()->FindNode(n12));
+    // Update Python script
+    TPythonDump() << "edgeID = " << this << ".AddEdge([ "
+                  <<n1<<", "<<n2<<", "<<n12<<" ])";
+  }
+
+  myMesh->GetMeshDS()->Modified();
+  if(elem)
+    return myMesh->SetIsModified( true ), elem->GetID();
+
+  return 0;
+}
+
+//=============================================================================
+/*!
+ *  AddFace
+ */
+//=============================================================================
+
+CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
+{
+  initData();
+
+  int NbNodes = IDsOfNodes.length();
+  if (NbNodes < 3)
+  {
+    return 0;
+  }
+
+  std::vector<const SMDS_MeshNode*> nodes (NbNodes);
+  for (int i = 0; i < NbNodes; i++)
+    nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
+
+  SMDS_MeshElement* elem = 0;
+  if (NbNodes == 3) {
+    elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2]);
+  }
+  else if (NbNodes == 4) {
+    elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3]);
   }
   else if (NbNodes == 6) {
     elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
@@ -405,12 +837,20 @@ CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
     elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
                                 nodes[4], nodes[5], nodes[6], nodes[7]);
   }
+  else if (NbNodes == 9) {
+    elem = GetMeshDS()->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
+                                nodes[4], nodes[5], nodes[6], nodes[7], nodes[8] );
+  }
+  else if (NbNodes > 2) {
+    elem = GetMeshDS()->AddPolygonalFace(nodes);
+  }
 
   // Update Python script
   TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
 
+  myMesh->GetMeshDS()->Modified();
   if(elem)
-    return elem->GetID();
+    return myMesh->SetIsModified( true ), elem->GetID();
 
   return 0;
 }
@@ -420,8 +860,7 @@ CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
  *  AddPolygonalFace
  */
 //=============================================================================
-CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace
-                                   (const SMESH::long_array & IDsOfNodes)
+CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
 {
   initData();
 
@@ -431,22 +870,18 @@ CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace
     nodes[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
 
   const SMDS_MeshElement* elem = GetMeshDS()->AddPolygonalFace(nodes);
-  
+
   // Update Python script
   TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
-#ifdef _DEBUG_
-  TPythonDump() << "print 'AddPolygonalFace: ', faceID";
-#endif
-
-  if(elem)
-    return elem->GetID();
 
-  return 0;
+  myMesh->GetMeshDS()->Modified();
+  return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
 }
 
 //=============================================================================
 /*!
- *
+ * Create volume, either linear and quadratic (this is determed
+ *  by number of given nodes)
  */
 //=============================================================================
 
@@ -469,6 +904,9 @@ CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
   case 10:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
                                         n[6],n[7],n[8],n[9]);
     break;
+  case 12:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],
+                                        n[6],n[7],n[8],n[9],n[10],n[11]);
+    break;
   case 13:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],
                                         n[7],n[8],n[9],n[10],n[11],n[12]);
     break;
@@ -479,16 +917,19 @@ CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
                                         n[8],n[9],n[10],n[11],n[12],n[13],n[14],
                                         n[15],n[16],n[17],n[18],n[19]);
     break;
+  case 27:elem = GetMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
+                                        n[8],n[9],n[10],n[11],n[12],n[13],n[14],
+                                        n[15],n[16],n[17],n[18],n[19],
+                                        n[20],n[21],n[22],n[23],n[24],n[25],n[26]);
+    break;
   }
 
   // Update Python script
   TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
-#ifdef _DEBUG_
-  TPythonDump() << "print 'AddVolume: ', volID";
-#endif
 
+  myMesh->GetMeshDS()->Modified();
   if(elem)
-    return elem->GetID();
+    return myMesh->SetIsModified( true ), elem->GetID();
 
   return 0;
 }
@@ -498,16 +939,19 @@ CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
  *  AddPolyhedralVolume
  */
 //=============================================================================
-CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume
-                                   (const SMESH::long_array & IDsOfNodes,
-                                    const SMESH::long_array & Quantities)
+CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & IDsOfNodes,
+                                                     const SMESH::long_array & Quantities)
 {
   initData();
 
   int NbNodes = IDsOfNodes.length();
   std::vector<const SMDS_MeshNode*> n (NbNodes);
   for (int i = 0; i < NbNodes; i++)
-    n[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
+    {
+      const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDsOfNodes[i]);
+      if (!aNode) return 0;
+      n[i] = aNode;
+    }
 
   int NbFaces = Quantities.length();
   std::vector<int> q (NbFaces);
@@ -519,14 +963,9 @@ CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume
   // Update Python script
   TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
                 << IDsOfNodes << ", " << Quantities << " )";
-#ifdef _DEBUG_
-  TPythonDump() << "print 'AddPolyhedralVolume: ', volID";
-#endif
+  myMesh->GetMeshDS()->Modified();
 
-  if(elem)
-    return elem->GetID();
-
-  return 0;
+  return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
 }
 
 //=============================================================================
@@ -534,8 +973,7 @@ CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume
  *  AddPolyhedralVolumeByFaces
  */
 //=============================================================================
-CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces
-                                   (const SMESH::long_array & IdsOfFaces)
+CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces)
 {
   initData();
 
@@ -558,14 +996,9 @@ CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces
   // Update Python script
   TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
                 << IdsOfFaces << " )";
-#ifdef _DEBUG_
-  TPythonDump() << "print 'AddPolyhedralVolume: ', volID";
-#endif
-
-  if(elem)
-    return elem->GetID();
+  myMesh->GetMeshDS()->Modified();
 
-  return 0;
+  return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
 }
 
 //=============================================================================
@@ -595,6 +1028,8 @@ void SMESH_MeshEditor_i::SetNodeOnVertex(CORBA::Long NodeID, CORBA::Long VertexI
     THROW_SALOME_CORBA_EXCEPTION("Invalid VertexID", SALOME::BAD_PARAM);
 
   mesh->SetNodeOnVertex( node, VertexID );
+
+  myMesh->SetIsModified( true );
 }
 
 //=============================================================================
@@ -631,6 +1066,8 @@ void SMESH_MeshEditor_i::SetNodeOnEdge(CORBA::Long NodeID, CORBA::Long EdgeID,
     THROW_SALOME_CORBA_EXCEPTION("Invalid paramOnEdge", SALOME::BAD_PARAM);
 
   mesh->SetNodeOnEdge( node, EdgeID, paramOnEdge );
+
+  myMesh->SetIsModified( true );
 }
 
 //=============================================================================
@@ -671,15 +1108,16 @@ void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
   if ( isOut ) {
 #ifdef _DEBUG_
     MESSAGE ( "FACE " << FaceID << " (" << u << "," << v << ") out of "
-           << " u( " <<  surf.FirstUParameter() 
-           << "," <<  surf.LastUParameter()  
-           << ") v( " <<  surf.FirstVParameter() 
-           << "," <<  surf.LastVParameter() << ")" );
-#endif    
+              << " u( " <<  surf.FirstUParameter()
+              << "," <<  surf.LastUParameter()
+              << ") v( " <<  surf.FirstVParameter()
+              << "," <<  surf.LastVParameter() << ")" );
+#endif
     THROW_SALOME_CORBA_EXCEPTION("Invalid UV", SALOME::BAD_PARAM);
   }
 
   mesh->SetNodeOnFace( node, FaceID, u, v );
+  myMesh->SetIsModified( true );
 }
 
 //=============================================================================
@@ -710,6 +1148,8 @@ void SMESH_MeshEditor_i::SetNodeInVolume(CORBA::Long NodeID, CORBA::Long SolidID
     THROW_SALOME_CORBA_EXCEPTION("Invalid SolidID", SALOME::BAD_PARAM);
 
   mesh->SetNodeInVolume( node, SolidID );
+
+  // myMesh->SetIsModified( true ); - SetNodeInVolume() can't prevent re-compute, I believe
 }
 
 //=============================================================================
@@ -743,33 +1183,8 @@ void SMESH_MeshEditor_i::SetMeshElementOnShape(CORBA::Long ElementID,
     THROW_SALOME_CORBA_EXCEPTION("Invalid shape type", SALOME::BAD_PARAM);
 
   mesh->SetMeshElementOnShape( elem, ShapeID );
-}
-
 
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-
-CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long   NodeID,
-                                            CORBA::Double x,
-                                            CORBA::Double y,
-                                            CORBA::Double z)
-{
-  initData();
-
-  const SMDS_MeshNode * node = GetMeshDS()->FindNode( NodeID );
-  if ( !node )
-    return false;
-
-  GetMeshDS()->MoveNode(node, x, y, z);
-
-  // Update Python script
-  TPythonDump() << "isDone = " << this << ".MoveNode( "
-                << NodeID << ", " << x << ", " << y << ", " << z << " )";
-
-  return true;
+  myMesh->SetIsModified( true );
 }
 
 //=============================================================================
@@ -792,8 +1207,11 @@ CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
   TPythonDump() << "isDone = " << this << ".InverseDiag( "
                 << NodeID1 << ", " << NodeID2 << " )";
 
-  ::SMESH_MeshEditor aMeshEditor( myMesh );
-  return aMeshEditor.InverseDiag ( n1, n2 );
+
+  int ret =  myEditor.InverseDiag ( n1, n2 );
+  myMesh->GetMeshDS()->Modified();
+  myMesh->SetIsModified( true );
+  return ret;
 }
 
 //=============================================================================
@@ -816,11 +1234,14 @@ CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
   TPythonDump() << "isDone = " << this << ".DeleteDiag( "
                 << NodeID1 << ", " << NodeID2 <<  " )";
 
-  ::SMESH_MeshEditor aMeshEditor( myMesh );
 
-  bool stat = aMeshEditor.DeleteDiag ( n1, n2 );
+  bool stat = myEditor.DeleteDiag ( n1, n2 );
 
-  storeResult(aMeshEditor);
+  myMesh->GetMeshDS()->Modified();
+  if ( stat )
+    myMesh->SetIsModified( true ); // issue 0020693
+
+  storeResult(myEditor);
 
   return stat;
 }
@@ -835,17 +1256,20 @@ CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfEleme
 {
   initData();
 
-  ::SMESH_MeshEditor anEditor( myMesh );
   for (int i = 0; i < IDsOfElements.length(); i++)
   {
     CORBA::Long index = IDsOfElements[i];
     const SMDS_MeshElement * elem = GetMeshDS()->FindElement(index);
     if ( elem )
-      anEditor.Reorient( elem );
+      myEditor.Reorient( elem );
   }
   // Update Python script
   TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
 
+  myMesh->GetMeshDS()->Modified();
+  if ( IDsOfElements.length() )
+    myMesh->SetIsModified( true ); // issue 0020693
+
   return true;
 }
 
@@ -860,43 +1284,102 @@ CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theO
 {
   initData();
 
+  TPythonDump aTPythonDump; // suppress dump in Reorient()
+
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   CORBA::Boolean isDone = Reorient(anElementsId);
 
-  // Clear python line, created by Reorient()
-  SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
-  aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
-
   // Update Python script
-  TPythonDump() << "isDone = " << this << ".ReorientObject( " << theObject << " )";
+  aTPythonDump << "isDone = " << this << ".ReorientObject( " << theObject << " )";
 
   return isDone;
 }
 
-namespace
+//=======================================================================
+//function : Reorient2D
+//purpose  : Reorient faces contained in \a the2Dgroup.
+//           the2Dgroup   - the mesh or its part to reorient
+//           theDirection - desired direction of normal of \a theFace
+//           theFace      - ID of face whose orientation is checked.
+//           It can be < 1 then \a thePoint is used to find a face.
+//           thePoint     - is used to find a face if \a theFace < 1.
+//           return number of reoriented elements.
+//=======================================================================
+
+CORBA::Long SMESH_MeshEditor_i::Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
+                                           const SMESH::DirStruct&   theDirection,
+                                           CORBA::Long               theFace,
+                                           const SMESH::PointStruct& thePoint)
+  throw (SALOME::SALOME_Exception)
 {
-  //================================================================================
-  /*!
-   * \brief function for conversion long_array to TIDSortedElemSet
-    * \param IDs - array of IDs
-    * \param aMesh - mesh
-    * \param aMap - collection to fill
-    * \param aType - element type
-   */
-  //================================================================================
+  Unexpect aCatch(SALOME_SalomeException);
 
-  void arrayToSet(const SMESH::long_array & IDs,
-                  const SMESHDS_Mesh*       aMesh,
-                  TIDSortedElemSet&         aMap,
-                  const SMDSAbs_ElementType aType = SMDSAbs_All )
-  { 
-    for (int i=0; i<IDs.length(); i++) {
-      CORBA::Long ind = IDs[i];
-      const SMDS_MeshElement * elem = aMesh->FindElement(ind);
-      if ( elem && ( aType == SMDSAbs_All || elem->GetType() == aType ))
-        aMap.insert( elem );
+  initData(/*deleteSearchers=*/false);
+
+  TIDSortedElemSet elements;
+  if ( !idSourceToSet( the2Dgroup, GetMeshDS(), elements, SMDSAbs_Face, /*emptyIfIsMesh=*/1))
+    THROW_SALOME_CORBA_EXCEPTION("No faces in given group", SALOME::BAD_PARAM);
+
+
+  const SMDS_MeshElement* face = 0;
+  if ( theFace > 0 )
+  {
+    face = GetMeshDS()->FindElement( theFace );
+    if ( !face )
+      THROW_SALOME_CORBA_EXCEPTION("Inexistent face given", SALOME::BAD_PARAM);
+    if ( face->GetType() != SMDSAbs_Face )
+      THROW_SALOME_CORBA_EXCEPTION("Wrong element type", SALOME::BAD_PARAM);
+  }
+  else
+  {
+    // create theElementSearcher if needed
+    theSearchersDeleter.Set( myMesh, getPartIOR( the2Dgroup, SMESH::FACE ));
+    if ( !theElementSearcher )
+    {
+      if ( elements.empty() ) // search in the whole mesh
+      {
+        if ( myMesh->NbFaces() == 0 )
+          THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM);
+
+        theElementSearcher = myEditor.GetElementSearcher();
+      }
+      else
+      {
+        typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
+        SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
+
+        theElementSearcher = myEditor.GetElementSearcher(elemsIt);
+      }
     }
+    // find a face
+    gp_Pnt p( thePoint.x, thePoint.y, thePoint.z );
+    face = theElementSearcher->FindClosestTo( p, SMDSAbs_Face );
+
+    if ( !face )
+      THROW_SALOME_CORBA_EXCEPTION("No face found by point", SALOME::INTERNAL_ERROR );
+    if ( !elements.empty() && !elements.count( face ))
+      THROW_SALOME_CORBA_EXCEPTION("Found face is not in the group", SALOME::BAD_PARAM );
+  }
+
+  const SMESH::PointStruct * P = &theDirection.PS;
+  gp_Vec dirVec( P->x, P->y, P->z );
+  if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
+    THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
+
+  int nbReori = myEditor.Reorient2D( elements, dirVec, face );
+  storeResult(myEditor);
+
+  if ( nbReori ) {
+    myMesh->SetIsModified( true );
+    myMesh->GetMeshDS()->Modified();
   }
+  TPythonDump() << this << ".Reorient2D( "
+                << the2Dgroup << ", "
+                << theDirection << ", "
+                << theFace << ", "
+                << thePoint << " )";
+
+  return nbReori;
 }
 
 //=============================================================================
@@ -924,16 +1407,15 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array &   IDsOfE
 
   // Update Python script
   TPythonDump() << "isDone = " << this << ".TriToQuad( "
-                << IDsOfElements << ", " << aNumericalFunctor << ", " << MaxAngle << " )";
-#ifdef _DEBUG_
-  TPythonDump() << "print 'TriToQuad: ', isDone";
-#endif
+                << IDsOfElements << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
 
-  ::SMESH_MeshEditor anEditor( myMesh );
 
-  bool stat = anEditor.TriToQuad( faces, aCrit, MaxAngle );
+  bool stat = myEditor.TriToQuad( faces, aCrit, MaxAngle );
+  myMesh->GetMeshDS()->Modified();
+  if ( stat )
+    myMesh->SetIsModified( true ); // issue 0020693
 
-  storeResult(anEditor);
+  storeResult(myEditor);
 
   return stat;
 }
@@ -950,25 +1432,16 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr
 {
   initData();
 
+  TPythonDump aTPythonDump;  // suppress dump in TriToQuad()
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
 
-  // Clear python line(s), created by TriToQuad()
-  SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
-  aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
-#ifdef _DEBUG_
-  aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
-#endif
-
   SMESH::NumericalFunctor_i* aNumericalFunctor =
     SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
 
   // Update Python script
-  TPythonDump() << "isDone = " << this << ".TriToQuadObject("
-                << theObject << ", " << aNumericalFunctor << ", " << MaxAngle << " )";
-#ifdef _DEBUG_
-  TPythonDump() << "print 'TriToQuadObject: ', isDone";
-#endif
+  aTPythonDump << "isDone = " << this << ".TriToQuadObject("
+               << theObject << ", " << aNumericalFunctor << ", " << TVar( MaxAngle ) << " )";
 
   return isDone;
 }
@@ -999,14 +1472,13 @@ CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array &   IDsOfE
 
   // Update Python script
   TPythonDump() << "isDone = " << this << ".QuadToTri( " << IDsOfElements << ", " << aNumericalFunctor << " )";
-#ifdef _DEBUG_
-  TPythonDump() << "print 'QuadToTri: ', isDone";
-#endif
 
-  ::SMESH_MeshEditor anEditor( myMesh );
-  CORBA::Boolean stat = anEditor.QuadToTri( faces, aCrit );
+  CORBA::Boolean stat = myEditor.QuadToTri( faces, aCrit );
+  myMesh->GetMeshDS()->Modified();
+  if ( stat )
+    myMesh->SetIsModified( true ); // issue 0020693
 
-  storeResult(anEditor);
+  storeResult(myEditor);
 
   return stat;
 }
@@ -1022,24 +1494,16 @@ CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr
 {
   initData();
 
+  TPythonDump aTPythonDump;  // suppress dump in QuadToTri()
+
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
 
-  // Clear python line(s), created by QuadToTri()
-  SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
-  aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
-#ifdef _DEBUG_
-  aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
-#endif
-
   SMESH::NumericalFunctor_i* aNumericalFunctor =
     SMESH::DownCast<SMESH::NumericalFunctor_i*>( Criterion );
 
   // Update Python script
-  TPythonDump() << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
-#ifdef _DEBUG_
-  TPythonDump() << "print 'QuadToTriObject: ', isDone";
-#endif
+  aTPythonDump << "isDone = " << this << ".QuadToTriObject( " << theObject << ", " << aNumericalFunctor << " )";
 
   return isDone;
 }
@@ -1062,14 +1526,14 @@ CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfEle
   // Update Python script
   TPythonDump() << "isDone = " << this << ".SplitQuad( "
                 << IDsOfElements << ", " << Diag13 << " )";
-#ifdef _DEBUG_
-  TPythonDump() << "print 'SplitQuad: ', isDone";
-#endif
 
-  ::SMESH_MeshEditor anEditor( myMesh );
-  CORBA::Boolean stat = anEditor.QuadToTri( faces, Diag13 );
+  CORBA::Boolean stat = myEditor.QuadToTri( faces, Diag13 );
+  myMesh->GetMeshDS()->Modified();
+  if ( stat )
+    myMesh->SetIsModified( true ); // issue 0020693
 
-  storeResult(anEditor);
+
+  storeResult(myEditor);
 
   return stat;
 }
@@ -1085,22 +1549,14 @@ CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr th
 {
   initData();
 
+  TPythonDump aTPythonDump;  // suppress dump in SplitQuad()
+
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
 
-  // Clear python line(s), created by SplitQuad()
-  SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
-  aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
-#ifdef _DEBUG_
-  aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
-#endif
-
   // Update Python script
-  TPythonDump() << "isDone = " << this << ".SplitQuadObject( "
-                << theObject << ", " << Diag13 << " )";
-#ifdef _DEBUG_
-  TPythonDump() << "print 'SplitQuadObject: ', isDone";
-#endif
+  aTPythonDump << "isDone = " << this << ".SplitQuadObject( "
+               << theObject << ", " << Diag13 << " )";
 
   return isDone;
 }
@@ -1114,6 +1570,8 @@ CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr th
 CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long                 IDOfQuad,
                                            SMESH::NumericalFunctor_ptr Criterion)
 {
+  initData();
+
   const SMDS_MeshElement* quad = GetMeshDS()->FindElement(IDOfQuad);
   if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4)
   {
@@ -1125,12 +1583,40 @@ CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long                 IDOfQuad,
     else
       aCrit.reset(new SMESH::Controls::AspectRatio());
 
-    ::SMESH_MeshEditor anEditor (myMesh);
-    return anEditor.BestSplit(quad, aCrit);
+    return myEditor.BestSplit(quad, aCrit);
   }
   return -1;
 }
 
+//================================================================================
+/*!
+ * \brief Split volumic elements into tetrahedrons
+ */
+//================================================================================
+
+void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
+                                                CORBA::Short              methodFlags)
+  throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+
+  initData();
+
+  SMESH::long_array_var anElementsId = elems->GetIDs();
+  TIDSortedElemSet elemSet;
+  arrayToSet( anElementsId, GetMeshDS(), elemSet, SMDSAbs_Volume );
+
+  myEditor.SplitVolumesIntoTetra( elemSet, int( methodFlags ));
+  myMesh->GetMeshDS()->Modified();
+
+  storeResult(myEditor);
+
+//   if ( myLastCreatedElems.length() ) - it does not influence Compute()
+//     myMesh->SetIsModified( true ); // issue 0020693
+
+  TPythonDump() << this << ".SplitVolumesIntoTetra( "
+                << elems << ", " << methodFlags << " )";
+}
 
 //=======================================================================
 //function : Smooth
@@ -1138,14 +1624,14 @@ CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long                 IDOfQuad,
 //=======================================================================
 
 CORBA::Boolean
-  SMESH_MeshEditor_i::Smooth(const SMESH::long_array &              IDsOfElements,
-                             const SMESH::long_array &              IDsOfFixedNodes,
-                             CORBA::Long                            MaxNbOfIterations,
-                             CORBA::Double                          MaxAspectRatio,
-                             SMESH::SMESH_MeshEditor::Smooth_Method Method)
+SMESH_MeshEditor_i::Smooth(const SMESH::long_array &              IDsOfElements,
+                           const SMESH::long_array &              IDsOfFixedNodes,
+                           CORBA::Long                            MaxNbOfIterations,
+                           CORBA::Double                          MaxAspectRatio,
+                           SMESH::SMESH_MeshEditor::Smooth_Method Method)
 {
   return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
-                MaxAspectRatio, Method, false );
+                 MaxAspectRatio, Method, false );
 }
 
 
@@ -1155,14 +1641,14 @@ CORBA::Boolean
 //=======================================================================
 
 CORBA::Boolean
-  SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array &              IDsOfElements,
-                                       const SMESH::long_array &              IDsOfFixedNodes,
-                                       CORBA::Long                            MaxNbOfIterations,
-                                       CORBA::Double                          MaxAspectRatio,
-                                       SMESH::SMESH_MeshEditor::Smooth_Method Method)
+SMESH_MeshEditor_i::SmoothParametric(const SMESH::long_array &              IDsOfElements,
+                                     const SMESH::long_array &              IDsOfFixedNodes,
+                                     CORBA::Long                            MaxNbOfIterations,
+                                     CORBA::Double                          MaxAspectRatio,
+                                     SMESH::SMESH_MeshEditor::Smooth_Method Method)
 {
   return smooth( IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations,
-                MaxAspectRatio, Method, true );
+                 MaxAspectRatio, Method, true );
 }
 
 
@@ -1172,11 +1658,11 @@ CORBA::Boolean
 //=======================================================================
 
 CORBA::Boolean
-  SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr              theObject,
-                                  const SMESH::long_array &              IDsOfFixedNodes,
-                                  CORBA::Long                            MaxNbOfIterations,
-                                  CORBA::Double                          MaxAspectRatio,
-                                  SMESH::SMESH_MeshEditor::Smooth_Method Method)
+SMESH_MeshEditor_i::SmoothObject(SMESH::SMESH_IDSource_ptr              theObject,
+                                 const SMESH::long_array &              IDsOfFixedNodes,
+                                 CORBA::Long                            MaxNbOfIterations,
+                                 CORBA::Double                          MaxAspectRatio,
+                                 SMESH::SMESH_MeshEditor::Smooth_Method Method)
 {
   return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
                        MaxAspectRatio, Method, false);
@@ -1189,11 +1675,11 @@ CORBA::Boolean
 //=======================================================================
 
 CORBA::Boolean
-  SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr              theObject,
-                                  const SMESH::long_array &              IDsOfFixedNodes,
-                                  CORBA::Long                            MaxNbOfIterations,
-                                  CORBA::Double                          MaxAspectRatio,
-                                  SMESH::SMESH_MeshEditor::Smooth_Method Method)
+SMESH_MeshEditor_i::SmoothParametricObject(SMESH::SMESH_IDSource_ptr              theObject,
+                                           const SMESH::long_array &              IDsOfFixedNodes,
+                                           CORBA::Long                            MaxNbOfIterations,
+                                           CORBA::Double                          MaxAspectRatio,
+                                           SMESH::SMESH_MeshEditor::Smooth_Method Method)
 {
   return smoothObject (theObject, IDsOfFixedNodes, MaxNbOfIterations,
                        MaxAspectRatio, Method, true);
@@ -1207,12 +1693,12 @@ CORBA::Boolean
 //=============================================================================
 
 CORBA::Boolean
-  SMESH_MeshEditor_i::smooth(const SMESH::long_array &              IDsOfElements,
-                             const SMESH::long_array &              IDsOfFixedNodes,
-                             CORBA::Long                            MaxNbOfIterations,
-                             CORBA::Double                          MaxAspectRatio,
-                             SMESH::SMESH_MeshEditor::Smooth_Method Method,
-                             bool                                   IsParametric)
+SMESH_MeshEditor_i::smooth(const SMESH::long_array &              IDsOfElements,
+                           const SMESH::long_array &              IDsOfFixedNodes,
+                           CORBA::Long                            MaxNbOfIterations,
+                           CORBA::Double                          MaxAspectRatio,
+                           SMESH::SMESH_MeshEditor::Smooth_Method Method,
+                           bool                                   IsParametric)
 {
   initData();
 
@@ -1232,23 +1718,22 @@ CORBA::Boolean
   if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
     method = ::SMESH_MeshEditor::CENTROIDAL;
 
-  ::SMESH_MeshEditor anEditor( myMesh );
-  anEditor.Smooth(elements, fixedNodes, method,
+  myEditor.Smooth(elements, fixedNodes, method,
                   MaxNbOfIterations, MaxAspectRatio, IsParametric );
 
-  storeResult(anEditor);
+  myMesh->GetMeshDS()->Modified();
+  myMesh->SetIsModified( true ); // issue 0020693
+
+  storeResult(myEditor);
 
   // Update Python script
   TPythonDump() << "isDone = " << this << "."
                 << (IsParametric ? "SmoothParametric( " : "Smooth( ")
                 << IDsOfElements << ", "     << IDsOfFixedNodes << ", "
-                << MaxNbOfIterations << ", " << MaxAspectRatio << ", "
+                << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
                 << "SMESH.SMESH_MeshEditor."
                 << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
                      "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
-#ifdef _DEBUG_
-  TPythonDump() << "print 'Smooth: ', isDone";
-#endif
 
   return true;
 }
@@ -1270,28 +1755,20 @@ SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr              theObjec
 {
   initData();
 
+  TPythonDump aTPythonDump;  // suppress dump in smooth()
+
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
                                   MaxAspectRatio, Method, IsParametric);
 
-  // Clear python line(s), created by Smooth()
-  SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
-  aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
-#ifdef _DEBUG_
-  aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
-#endif
-
   // Update Python script
-  TPythonDump() << "isDone = " << this << "."
-                << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
-                << theObject << ", " << IDsOfFixedNodes << ", "
-                << MaxNbOfIterations << ", " << MaxAspectRatio << ", "
-                << "SMESH.SMESH_MeshEditor."
-                << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
-                     "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
-#ifdef _DEBUG_
-  TPythonDump() << "print 'SmoothObject: ', isDone";
-#endif
+  aTPythonDump << "isDone = " << this << "."
+               << (IsParametric ? "SmoothParametricObject( " : "SmoothObject( ")
+               << theObject << ", " << IDsOfFixedNodes << ", "
+               << TVar( MaxNbOfIterations ) << ", " << TVar( MaxAspectRatio ) << ", "
+               << "SMESH.SMESH_MeshEditor."
+               << ( Method == SMESH::SMESH_MeshEditor::CENTROIDAL_SMOOTH ?
+                    "CENTROIDAL_SMOOTH )" : "LAPLACIAN_SMOOTH )");
 
   return isDone;
 }
@@ -1327,9 +1804,9 @@ void SMESH_MeshEditor_i::RenumberElements()
 }
 
 //=======================================================================
-  /*!
  * \brief Return groups by their IDs
  */
+/*!
+ * \brief Return groups by their IDs
+ */
 //=======================================================================
 
 SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupIDs)
@@ -1342,7 +1819,7 @@ SMESH::ListOfGroups* SMESH_MeshEditor_i::getGroups(const std::list<int>* groupID
 
 //=======================================================================
 //function : rotationSweep
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SMESH::ListOfGroups*
@@ -1352,7 +1829,7 @@ SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
                                   CORBA::Long               theNbOfSteps,
                                   CORBA::Double             theTolerance,
                                   const bool                theMakeGroups,
-                                 const SMDSAbs_ElementType theElementType)
+                                  const SMDSAbs_ElementType theElementType)
 {
   initData();
 
@@ -1379,11 +1856,13 @@ SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
   gp_Ax1 Ax1 (gp_Pnt( theAxis.x,  theAxis.y,  theAxis.z ),
               gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
 
-  ::SMESH_MeshEditor anEditor( mesh );
   ::SMESH_MeshEditor::PGroupIDs groupIds =
-    anEditor.RotationSweep (*workElements, Ax1, theAngleInRadians,
-                            theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
-  storeResult(anEditor);
+      myEditor.RotationSweep (*workElements, Ax1, theAngleInRadians,
+                              theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
+  storeResult(myEditor);
+  myMesh->GetMeshDS()->Modified();
+
+  //  myMesh->SetIsModified( true ); -- it does not influence Compute()
 
   return theMakeGroups ? getGroups(groupIds.get()) : 0;
 }
@@ -1401,11 +1880,11 @@ void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElement
 {
   if ( !myPreviewMode ) {
     TPythonDump() << this << ".RotationSweep( "
-                  << theIDsOfElements << ", "
-                  << theAxis << ", "
-                  << theAngleInRadians << ", "
-                  << theNbOfSteps << ", "
-                  << theTolerance << " )";
+                  << theIDsOfElements          << ", "
+                  << theAxis                   << ", "
+                  << TVar( theAngleInRadians ) << ", "
+                  << TVar( theNbOfSteps      ) << ", "
+                  << TVar( theTolerance      ) << " )";
   }
   rotationSweep(theIDsOfElements,
                 theAxis,
@@ -1417,7 +1896,7 @@ void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElement
 
 //=======================================================================
 //function : RotationSweepMakeGroups
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SMESH::ListOfGroups*
@@ -1427,21 +1906,22 @@ SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfEle
                                             CORBA::Long              theNbOfSteps,
                                             CORBA::Double            theTolerance)
 {
+  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+
   SMESH::ListOfGroups *aGroups = rotationSweep(theIDsOfElements,
                                                theAxis,
                                                theAngleInRadians,
                                                theNbOfSteps,
                                                theTolerance,
                                                true);
-  if ( !myPreviewMode ) {
-    TPythonDump aPythonDump;
-    DumpGroupsList(aPythonDump,aGroups);
-    aPythonDump<< this << ".RotationSweepMakeGroups( "
-               << theIDsOfElements << ", "
-               << theAxis << ", "
-               << theAngleInRadians << ", "
-               << theNbOfSteps << ", "
-               << theTolerance << " )";
+  if (!myPreviewMode) {
+    DumpGroupsList(aPythonDump, aGroups);
+    aPythonDump << this << ".RotationSweepMakeGroups( "
+                << theIDsOfElements        << ", "
+                << theAxis                   << ", "
+                << TVar( theAngleInRadians ) << ", "
+                << TVar( theNbOfSteps      ) << ", "
+                << TVar( theTolerance      ) << " )";
   }
   return aGroups;
 }
@@ -1452,10 +1932,10 @@ SMESH_MeshEditor_i::RotationSweepMakeGroups(const SMESH::long_array& theIDsOfEle
 //=======================================================================
 
 void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
-                                            const SMESH::AxisStruct & theAxis,
-                                            CORBA::Double             theAngleInRadians,
-                                            CORBA::Long               theNbOfSteps,
-                                            CORBA::Double             theTolerance)
+                                             const SMESH::AxisStruct & theAxis,
+                                             CORBA::Double             theAngleInRadians,
+                                             CORBA::Long               theNbOfSteps,
+                                             CORBA::Double             theTolerance)
 {
   if ( !myPreviewMode ) {
     TPythonDump() << this << ".RotationSweepObject( "
@@ -1480,18 +1960,18 @@ void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject
 //=======================================================================
 
 void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
-                                              const SMESH::AxisStruct & theAxis,
-                                              CORBA::Double             theAngleInRadians,
-                                              CORBA::Long               theNbOfSteps,
-                                              CORBA::Double             theTolerance)
+                                               const SMESH::AxisStruct & theAxis,
+                                               CORBA::Double             theAngleInRadians,
+                                               CORBA::Long               theNbOfSteps,
+                                               CORBA::Double             theTolerance)
 {
   if ( !myPreviewMode ) {
     TPythonDump() << this << ".RotationSweepObject1D( "
-                  << theObject << ", "
-                  << theAxis << ", "
-                  << theAngleInRadians << ", "
-                  << theNbOfSteps << ", "
-                  << theTolerance << " )";
+                  << theObject                 << ", "
+                  << theAxis                   << ", "
+                  << TVar( theAngleInRadians ) << ", "
+                  << TVar( theNbOfSteps      ) << ", "
+                  << TVar( theTolerance      ) << " )";
   }
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   rotationSweep(anElementsId,
@@ -1500,7 +1980,7 @@ void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObje
                 theNbOfSteps,
                 theTolerance,
                 false,
-               SMDSAbs_Edge);
+                SMDSAbs_Edge);
 }
 
 //=======================================================================
@@ -1509,18 +1989,18 @@ void SMESH_MeshEditor_i::RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObje
 //=======================================================================
 
 void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
-                                              const SMESH::AxisStruct & theAxis,
-                                              CORBA::Double             theAngleInRadians,
-                                              CORBA::Long               theNbOfSteps,
-                                              CORBA::Double             theTolerance)
+                                               const SMESH::AxisStruct & theAxis,
+                                               CORBA::Double             theAngleInRadians,
+                                               CORBA::Long               theNbOfSteps,
+                                               CORBA::Double             theTolerance)
 {
   if ( !myPreviewMode ) {
     TPythonDump() << this << ".RotationSweepObject2D( "
-                  << theObject << ", "
-                  << theAxis << ", "
-                  << theAngleInRadians << ", "
-                  << theNbOfSteps << ", "
-                  << theTolerance << " )";
+                  << theObject                 << ", "
+                  << theAxis                   << ", "
+                  << TVar( theAngleInRadians ) << ", "
+                  << TVar( theNbOfSteps      ) << ", "
+                  << TVar( theTolerance      ) << " )";
   }
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   rotationSweep(anElementsId,
@@ -1529,12 +2009,12 @@ void SMESH_MeshEditor_i::RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObje
                 theNbOfSteps,
                 theTolerance,
                 false,
-               SMDSAbs_Face);
+                SMDSAbs_Face);
 }
 
 //=======================================================================
 //function : RotationSweepObjectMakeGroups
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SMESH::ListOfGroups*
@@ -1544,6 +2024,8 @@ SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theO
                                                   CORBA::Long               theNbOfSteps,
                                                   CORBA::Double             theTolerance)
 {
+  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
                                                theAxis,
@@ -1551,31 +2033,32 @@ SMESH_MeshEditor_i::RotationSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr theO
                                                theNbOfSteps,
                                                theTolerance,
                                                true);
-  if ( !myPreviewMode ) {
-    TPythonDump aPythonDump;
-    DumpGroupsList(aPythonDump,aGroups);
-    aPythonDump<< this << ".RotationSweepObjectMakeGroups( "
-               << theObject << ", "
-              << theAxis << ", "
-               << theAngleInRadians << ", "
-               << theNbOfSteps << ", "
-               << theTolerance << " )";
+  if (!myPreviewMode) {
+    DumpGroupsList(aPythonDump, aGroups);
+    aPythonDump << this << ".RotationSweepObjectMakeGroups( "
+                << theObject << ", "
+                << theAxis << ", "
+                << theAngleInRadians << ", "
+                << theNbOfSteps << ", "
+                << theTolerance << " )";
   }
   return aGroups;
 }
 
 //=======================================================================
 //function : RotationSweepObject1DMakeGroups
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SMESH::ListOfGroups*
 SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
-                                                   const SMESH::AxisStruct&  theAxis,
-                                                   CORBA::Double             theAngleInRadians,
-                                                   CORBA::Long               theNbOfSteps,
-                                                   CORBA::Double             theTolerance)
+                                                    const SMESH::AxisStruct&  theAxis,
+                                                    CORBA::Double             theAngleInRadians,
+                                                    CORBA::Long               theNbOfSteps,
+                                                    CORBA::Double             theTolerance)
 {
+  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
                                                theAxis,
@@ -1583,32 +2066,33 @@ SMESH_MeshEditor_i::RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr th
                                                theNbOfSteps,
                                                theTolerance,
                                                true,
-                                              SMDSAbs_Edge);
-  if ( !myPreviewMode ) {
-    TPythonDump aPythonDump;
-    DumpGroupsList(aPythonDump,aGroups);
-    aPythonDump<< this << ".RotationSweepObject1DMakeGroups( "
-               << theObject << ", "
-              << theAxis << ", "
-               << theAngleInRadians << ", "
-               << theNbOfSteps << ", "
-               << theTolerance << " )";
+                                               SMDSAbs_Edge);
+  if (!myPreviewMode) {
+    DumpGroupsList(aPythonDump, aGroups);
+    aPythonDump << this << ".RotationSweepObject1DMakeGroups( "
+                << theObject                 << ", "
+                << theAxis                   << ", "
+                << TVar( theAngleInRadians ) << ", "
+                << TVar( theNbOfSteps )      << ", "
+                << TVar( theTolerance )      << " )";
   }
   return aGroups;
 }
 
 //=======================================================================
 //function : RotationSweepObject2DMakeGroups
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SMESH::ListOfGroups*
 SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
-                                                   const SMESH::AxisStruct&  theAxis,
-                                                   CORBA::Double             theAngleInRadians,
-                                                   CORBA::Long               theNbOfSteps,
-                                                   CORBA::Double             theTolerance)
+                                                    const SMESH::AxisStruct&  theAxis,
+                                                    CORBA::Double             theAngleInRadians,
+                                                    CORBA::Long               theNbOfSteps,
+                                                    CORBA::Double             theTolerance)
 {
+  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   SMESH::ListOfGroups *aGroups = rotationSweep(anElementsId,
                                                theAxis,
@@ -1616,16 +2100,15 @@ SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr th
                                                theNbOfSteps,
                                                theTolerance,
                                                true,
-                                              SMDSAbs_Face);
-  if ( !myPreviewMode ) {
-    TPythonDump aPythonDump;
-    DumpGroupsList(aPythonDump,aGroups);
-    aPythonDump<< this << ".RotationSweepObject2DMakeGroups( "
-               << theObject << ", "
-              << theAxis << ", "
-               << theAngleInRadians << ", "
-               << theNbOfSteps << ", "
-               << theTolerance << " )";
+                                               SMDSAbs_Face);
+  if (!myPreviewMode) {
+    DumpGroupsList(aPythonDump, aGroups);
+    aPythonDump << this << ".RotationSweepObject2DMakeGroups( "
+                << theObject                 << ", "
+                << theAxis                   << ", "
+                << TVar( theAngleInRadians ) << ", "
+                << TVar( theNbOfSteps      ) << ", "
+                << TVar( theTolerance      ) << " )";
   }
   return aGroups;
 }
@@ -1633,39 +2116,59 @@ SMESH_MeshEditor_i::RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr th
 
 //=======================================================================
 //function : extrusionSweep
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SMESH::ListOfGroups*
 SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
                                    const SMESH::DirStruct &  theStepVector,
                                    CORBA::Long               theNbOfSteps,
-                                   const bool                theMakeGroups,
+                                   bool                      theMakeGroups,
                                    const SMDSAbs_ElementType theElementType)
 {
   initData();
 
-  try {   
+  try {
 #ifdef NO_CAS_CATCH
     OCC_CATCH_SIGNALS;
 #endif
-    TIDSortedElemSet elements;
+    TIDSortedElemSet elements, copyElements;
     arrayToSet(theIDsOfElements, GetMeshDS(), elements, theElementType);
 
     const SMESH::PointStruct * P = &theStepVector.PS;
     gp_Vec stepVec( P->x, P->y, P->z );
 
+    TIDSortedElemSet* workElements = & elements;
+
+    SMDSAbs_ElementType aType = SMDSAbs_Face;
+    //::SMESH_MeshEditor::ExtrusionFlags aFlag = ::SMESH_MeshEditor::ExtrusionFlags::EXTRUSION_FLAG_BOUNDARY;
+    if (theElementType == SMDSAbs_Node)
+    {
+      aType = SMDSAbs_Edge;
+      //aFlag = ::SMESH_MeshEditor::ExtrusionFlags::EXTRUSION_FLAG_SEW;
+    }
+    TPreviewMesh      tmpMesh( aType );
+    SMESH_Mesh* mesh = myMesh;
+
+    if ( myPreviewMode ) {
+      SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
+      tmpMesh.Copy( elements, copyElements, select, avoid );
+      mesh = &tmpMesh;
+      workElements = & copyElements;
+      theMakeGroups = false;
+    }
+
     TElemOfElemListMap aHystory;
-    ::SMESH_MeshEditor anEditor( myMesh );
-    ::SMESH_MeshEditor::PGroupIDs groupIds =
-        anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
+    ::SMESH_MeshEditor::PGroupIDs groupIds = 
+        myEditor.ExtrusionSweep (*workElements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
 
-    storeResult(anEditor);
+    myMesh->GetMeshDS()->Modified();
+    storeResult(myEditor);
 
     return theMakeGroups ? getGroups(groupIds.get()) : 0;
 
   } catch(Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();          
+    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
     INFOS( "SMESH_MeshEditor_i::ExtrusionSweep fails - "<< aFail->GetMessageString() );
   }
   return 0;
@@ -1681,12 +2184,27 @@ void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElemen
                                         CORBA::Long               theNbOfSteps)
 {
   extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false );
-  if ( !myPreviewMode ) {
+  if (!myPreviewMode) {
     TPythonDump() << this << ".ExtrusionSweep( "
-                  << theIDsOfElements << ", " << theStepVector <<", " << theNbOfSteps << " )";
+                  << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps) << " )";
   }
 }
 
+//=======================================================================
+//function : ExtrusionSweep0D
+//purpose  :
+//=======================================================================
+
+void SMESH_MeshEditor_i::ExtrusionSweep0D(const SMESH::long_array & theIDsOfElements,
+                                          const SMESH::DirStruct &  theStepVector,
+                                          CORBA::Long               theNbOfSteps)
+{
+  extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
+  if (!myPreviewMode) {
+    TPythonDump() << this << ".ExtrusionSweep0D( "
+                  << theIDsOfElements << ", " << theStepVector <<", " << TVar(theNbOfSteps)<< " )";
+  }
+}
 
 //=======================================================================
 //function : ExtrusionSweepObject
@@ -1694,17 +2212,34 @@ void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElemen
 //=======================================================================
 
 void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
-                                             const SMESH::DirStruct &  theStepVector,
-                                             CORBA::Long               theNbOfSteps)
+                                              const SMESH::DirStruct &  theStepVector,
+                                              CORBA::Long               theNbOfSteps)
 {
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false );
-  if ( !myPreviewMode ) {
+  if (!myPreviewMode) {
     TPythonDump() << this << ".ExtrusionSweepObject( "
                   << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
   }
 }
 
+//=======================================================================
+//function : ExtrusionSweepObject0D
+//purpose  :
+//=======================================================================
+
+void SMESH_MeshEditor_i::ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
+                                                const SMESH::DirStruct &  theStepVector,
+                                                CORBA::Long               theNbOfSteps)
+{
+  SMESH::long_array_var anElementsId = theObject->GetIDs();
+  extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Node );
+  if ( !myPreviewMode ) {
+    TPythonDump() << this << ".ExtrusionSweepObject0D( "
+                  << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
+  }
+}
+
 //=======================================================================
 //function : ExtrusionSweepObject1D
 //purpose  :
@@ -1718,7 +2253,7 @@ void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObj
   extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Edge );
   if ( !myPreviewMode ) {
     TPythonDump() << this << ".ExtrusionSweepObject1D( "
-                  << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
+                  << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
   }
 }
 
@@ -1735,13 +2270,13 @@ void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObj
   extrusionSweep (anElementsId, theStepVector, theNbOfSteps, false, SMDSAbs_Face );
   if ( !myPreviewMode ) {
     TPythonDump() << this << ".ExtrusionSweepObject2D( "
-                  << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
+                  << theObject << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
   }
 }
 
 //=======================================================================
 //function : ExtrusionSweepMakeGroups
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SMESH::ListOfGroups*
@@ -1749,19 +2284,43 @@ SMESH_MeshEditor_i::ExtrusionSweepMakeGroups(const SMESH::long_array& theIDsOfEl
                                              const SMESH::DirStruct&  theStepVector,
                                              CORBA::Long              theNbOfSteps)
 {
-  SMESH::ListOfGroups* aGroups = extrusionSweep (theIDsOfElements, theStepVector, theNbOfSteps, true );
-    
-  if ( !myPreviewMode ) {
-    TPythonDump aPythonDump;
-    DumpGroupsList(aPythonDump,aGroups);
-    aPythonDump  << this << ".ExtrusionSweepMakeGroups( "
-                 << theIDsOfElements << ", " << theStepVector <<", " << theNbOfSteps << " )";
+  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+
+  SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true);
+
+  if (!myPreviewMode) {
+    DumpGroupsList(aPythonDump, aGroups);
+    aPythonDump << this << ".ExtrusionSweepMakeGroups( " << theIDsOfElements
+                << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
+  }
+  return aGroups;
+}
+
+//=======================================================================
+//function : ExtrusionSweepMakeGroups0D
+//purpose  :
+//=======================================================================
+
+SMESH::ListOfGroups*
+SMESH_MeshEditor_i::ExtrusionSweepMakeGroups0D(const SMESH::long_array& theIDsOfElements,
+                                               const SMESH::DirStruct&  theStepVector,
+                                               CORBA::Long              theNbOfSteps)
+{
+  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+
+  SMESH::ListOfGroups* aGroups = extrusionSweep(theIDsOfElements, theStepVector, theNbOfSteps, true,SMDSAbs_Node);
+
+  if (!myPreviewMode) {
+    DumpGroupsList(aPythonDump, aGroups);
+    aPythonDump << this << ".ExtrusionSweepMakeGroups0D( " << theIDsOfElements
+                << ", " << theStepVector <<", " << TVar( theNbOfSteps ) << " )";
   }
   return aGroups;
 }
+
 //=======================================================================
 //function : ExtrusionSweepObjectMakeGroups
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SMESH::ListOfGroups*
@@ -1769,21 +2328,45 @@ SMESH_MeshEditor_i::ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr the
                                                    const SMESH::DirStruct&   theStepVector,
                                                    CORBA::Long               theNbOfSteps)
 {
+  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+
   SMESH::long_array_var anElementsId = theObject->GetIDs();
-  SMESH::ListOfGroups * aGroups = extrusionSweep (anElementsId, theStepVector, theNbOfSteps, true );
-  
-  if ( !myPreviewMode ) {
-    TPythonDump aPythonDump;
-    DumpGroupsList(aPythonDump,aGroups);
-    aPythonDump<< this << ".ExtrusionSweepObjectMakeGroups( "
-               << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
+  SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector, theNbOfSteps, true);
+
+  if (!myPreviewMode) {
+    DumpGroupsList(aPythonDump, aGroups);
+    aPythonDump << this << ".ExtrusionSweepObjectMakeGroups( " << theObject
+                << ", " << theStepVector << ", " << theNbOfSteps << " )";
+  }
+  return aGroups;
+}
+
+//=======================================================================
+//function : ExtrusionSweepObject0DMakeGroups
+//purpose  :
+//=======================================================================
+
+SMESH::ListOfGroups*
+SMESH_MeshEditor_i::ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
+                                                     const SMESH::DirStruct&   theStepVector,
+                                                     CORBA::Long               theNbOfSteps)
+{
+  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+
+  SMESH::long_array_var anElementsId = theObject->GetIDs();
+  SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
+                                                 theNbOfSteps, true, SMDSAbs_Node);
+  if (!myPreviewMode) {
+    DumpGroupsList(aPythonDump, aGroups);
+    aPythonDump << this << ".ExtrusionSweepObject0DMakeGroups( " << theObject
+                << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
   }
   return aGroups;
 }
 
 //=======================================================================
 //function : ExtrusionSweepObject1DMakeGroups
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SMESH::ListOfGroups*
@@ -1791,20 +2374,22 @@ SMESH_MeshEditor_i::ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr t
                                                      const SMESH::DirStruct&   theStepVector,
                                                      CORBA::Long               theNbOfSteps)
 {
+  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+
   SMESH::long_array_var anElementsId = theObject->GetIDs();
-  SMESH::ListOfGroups * aGroups = extrusionSweep (anElementsId, theStepVector, theNbOfSteps, true, SMDSAbs_Edge );
-  if ( !myPreviewMode ) {
-    TPythonDump aPythonDump;
-    DumpGroupsList(aPythonDump,aGroups);
-    aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( "
-               << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
+  SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
+                                                 theNbOfSteps, true, SMDSAbs_Edge);
+  if (!myPreviewMode) {
+    DumpGroupsList(aPythonDump, aGroups);
+    aPythonDump << this << ".ExtrusionSweepObject1DMakeGroups( " << theObject
+                << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
   }
   return aGroups;
 }
 
 //=======================================================================
 //function : ExtrusionSweepObject2DMakeGroups
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SMESH::ListOfGroups*
@@ -1812,13 +2397,15 @@ SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr t
                                                      const SMESH::DirStruct&   theStepVector,
                                                      CORBA::Long               theNbOfSteps)
 {
+  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+
   SMESH::long_array_var anElementsId = theObject->GetIDs();
-  SMESH::ListOfGroups * aGroups = extrusionSweep (anElementsId, theStepVector, theNbOfSteps, true, SMDSAbs_Face );
-  if ( !myPreviewMode ) {
-    TPythonDump aPythonDump;
-    DumpGroupsList(aPythonDump,aGroups);
-    aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( "
-               << theObject << ", " << theStepVector << ", " << theNbOfSteps << " )";
+  SMESH::ListOfGroups * aGroups = extrusionSweep(anElementsId, theStepVector,
+                                                 theNbOfSteps, true, SMDSAbs_Face);
+  if (!myPreviewMode) {
+    DumpGroupsList(aPythonDump, aGroups);
+    aPythonDump << this << ".ExtrusionSweepObject2DMakeGroups( " << theObject
+                << ", " << theStepVector << ", " << TVar( theNbOfSteps ) << " )";
   }
   return aGroups;
 }
@@ -1826,7 +2413,7 @@ SMESH_MeshEditor_i::ExtrusionSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr t
 
 //=======================================================================
 //function : advancedExtrusion
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SMESH::ListOfGroups*
@@ -1845,12 +2432,11 @@ SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements
   const SMESH::PointStruct * P = &theStepVector.PS;
   gp_Vec stepVec( P->x, P->y, P->z );
 
-  ::SMESH_MeshEditor anEditor( myMesh );
   TElemOfElemListMap aHystory;
   ::SMESH_MeshEditor::PGroupIDs groupIds =
-      anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
+      myEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
                                theMakeGroups, theExtrFlags, theSewTolerance);
-  storeResult(anEditor);
+  storeResult(myEditor);
 
   return theMakeGroups ? getGroups(groupIds.get()) : 0;
 }
@@ -1861,10 +2447,10 @@ SMESH_MeshEditor_i::advancedExtrusion(const SMESH::long_array & theIDsOfElements
 //=======================================================================
 
 void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
-                                          const SMESH::DirStruct &  theStepVector,
-                                          CORBA::Long               theNbOfSteps,
-                                          CORBA::Long               theExtrFlags,
-                                          CORBA::Double             theSewTolerance)
+                                           const SMESH::DirStruct &  theStepVector,
+                                           CORBA::Long               theNbOfSteps,
+                                           CORBA::Long               theExtrFlags,
+                                           CORBA::Double             theSewTolerance)
 {
   if ( !myPreviewMode ) {
     TPythonDump() << "stepVector = " << theStepVector;
@@ -1885,9 +2471,8 @@ void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfEle
 
 //=======================================================================
 //function : AdvancedExtrusionMakeGroups
-//purpose  : 
+//purpose  :
 //=======================================================================
-
 SMESH::ListOfGroups*
 SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsOfElements,
                                                 const SMESH::DirStruct&  theStepVector,
@@ -1895,17 +2480,20 @@ SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsO
                                                 CORBA::Long              theExtrFlags,
                                                 CORBA::Double            theSewTolerance)
 {
-  SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
-                                                    theStepVector,
-                                                    theNbOfSteps,
-                                                    theExtrFlags,
-                                                    theSewTolerance,
-                                                    true);
-  
-  if ( !myPreviewMode ) {
+  if (!myPreviewMode) {
     TPythonDump() << "stepVector = " << theStepVector;
-    TPythonDump aPythonDump;
-    DumpGroupsList(aPythonDump,aGroups);
+  }
+  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+
+  SMESH::ListOfGroups * aGroups = advancedExtrusion( theIDsOfElements,
+                                                     theStepVector,
+                                                     theNbOfSteps,
+                                                     theExtrFlags,
+                                                     theSewTolerance,
+                                                     true);
+
+  if (!myPreviewMode) {
+    DumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".AdvancedExtrusionMakeGroups("
                 << theIDsOfElements
                 << ", stepVector, "
@@ -1928,13 +2516,13 @@ SMESH_MeshEditor_i::AdvancedExtrusionMakeGroups(const SMESH::long_array& theIDsO
 static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_MeshEditor::Extrusion_Error e )
 {
   switch ( e ) {
-  RETCASE( EXTR_OK );
-  RETCASE( EXTR_NO_ELEMENTS );
-  RETCASE( EXTR_PATH_NOT_EDGE );
-  RETCASE( EXTR_BAD_PATH_SHAPE );
-  RETCASE( EXTR_BAD_STARTING_NODE );
-  RETCASE( EXTR_BAD_ANGLES_NUMBER );
-  RETCASE( EXTR_CANT_GET_TANGENT );
+    RETCASE( EXTR_OK );
+    RETCASE( EXTR_NO_ELEMENTS );
+    RETCASE( EXTR_PATH_NOT_EDGE );
+    RETCASE( EXTR_BAD_PATH_SHAPE );
+    RETCASE( EXTR_BAD_STARTING_NODE );
+    RETCASE( EXTR_BAD_ANGLES_NUMBER );
+    RETCASE( EXTR_CANT_GET_TANGENT );
   }
   return SMESH::SMESH_MeshEditor::EXTR_OK;
 }
@@ -1942,9 +2530,8 @@ static SMESH::SMESH_MeshEditor::Extrusion_Error convExtrError( const::SMESH_Mesh
 
 //=======================================================================
 //function : extrusionAlongPath
-//purpose  : 
+//purpose  :
 //=======================================================================
-
 SMESH::ListOfGroups*
 SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array &   theIDsOfElements,
                                        SMESH::SMESH_Mesh_ptr       thePathMesh,
@@ -1956,8 +2543,9 @@ SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array &   theIDsOfEleme
                                        const SMESH::PointStruct &  theRefPoint,
                                        const bool                  theMakeGroups,
                                        SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
-                                      const SMDSAbs_ElementType   theElementType)
+                                       const SMDSAbs_ElementType   theElementType)
 {
+  MESSAGE("extrusionAlongPath");
   initData();
 
   if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
@@ -1992,12 +2580,12 @@ SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array &   theIDsOfEleme
 
   int nbOldGroups = myMesh->NbGroup();
 
-  ::SMESH_MeshEditor anEditor( myMesh );
   ::SMESH_MeshEditor::Extrusion_Error error =
-      anEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
-                                    theHasAngles, angles,
+      myEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
+                                    theHasAngles, angles, false,
                                     theHasRefPoint, refPnt, theMakeGroups );
-  storeResult(anEditor);
+  myMesh->GetMeshDS()->Modified();
+  storeResult(myEditor);
   theError = convExtrError( error );
 
   if ( theMakeGroups ) {
@@ -2010,21 +2598,131 @@ SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array &   theIDsOfEleme
   return 0;
 }
 
+
 //=======================================================================
-//function : ExtrusionAlongPath
+//function : extrusionAlongPathX
 //purpose  :
 //=======================================================================
+SMESH::ListOfGroups*
+SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array &  IDsOfElements,
+                                        SMESH::SMESH_IDSource_ptr  Path,
+                                        CORBA::Long                NodeStart,
+                                        CORBA::Boolean             HasAngles,
+                                        const SMESH::double_array& Angles,
+                                        CORBA::Boolean             LinearVariation,
+                                        CORBA::Boolean             HasRefPoint,
+                                        const SMESH::PointStruct&  RefPoint,
+                                        bool                       MakeGroups,
+                                        const SMDSAbs_ElementType  ElementType,
+                                        SMESH::SMESH_MeshEditor::Extrusion_Error & Error)
+{
+  SMESH::ListOfGroups* EmptyGr = new SMESH::ListOfGroups;
+
+  initData();
+
+  list<double> angles;
+  for (int i = 0; i < Angles.length(); i++) {
+    angles.push_back( Angles[i] );
+  }
+  gp_Pnt refPnt( RefPoint.x, RefPoint.y, RefPoint.z );
+  int nbOldGroups = myMesh->NbGroup();
+
+  if ( Path->_is_nil() ) {
+    Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
+    return EmptyGr;
+  }
+
+  TIDSortedElemSet elements, copyElements;
+  arrayToSet(IDsOfElements, GetMeshDS(), elements, ElementType);
+
+  TIDSortedElemSet* workElements = &elements;
+  TPreviewMesh      tmpMesh( SMDSAbs_Face );
+  SMESH_Mesh*       mesh = myMesh;
+
+  if ( myPreviewMode )
+  {
+    SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
+    tmpMesh.Copy( elements, copyElements, select, avoid );
+    mesh = &tmpMesh;
+    workElements = & copyElements;
+    MakeGroups = false;
+  }
+
+  ::SMESH_MeshEditor::Extrusion_Error error;
+
+  if ( SMESH_Mesh_i* aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( Path ))
+  {
+    // path as mesh
+    SMDS_MeshNode* aNodeStart =
+      (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
+    if ( !aNodeStart ) {
+      Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
+      return EmptyGr;
+    }
+    error = myEditor.ExtrusionAlongTrack( *workElements, &(aMeshImp->GetImpl()), aNodeStart,
+                                          HasAngles, angles, LinearVariation,
+                                          HasRefPoint, refPnt, MakeGroups );
+    myMesh->GetMeshDS()->Modified();
+  }
+  else if ( SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path ))
+  {
+    // path as submesh
+    SMESH::SMESH_Mesh_ptr aPathMesh = aSubMeshImp->GetFather();
+    aMeshImp = SMESH::DownCast<SMESH_Mesh_i*>( aPathMesh );
+    SMDS_MeshNode* aNodeStart =
+      (SMDS_MeshNode*)aMeshImp->GetImpl().GetMeshDS()->FindNode(NodeStart);
+    if ( !aNodeStart ) {
+      Error = SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
+      return EmptyGr;
+    }
+    SMESH_subMesh* aSubMesh =
+      aMeshImp->GetImpl().GetSubMeshContaining(aSubMeshImp->GetId());
+    error = myEditor.ExtrusionAlongTrack( *workElements, aSubMesh, aNodeStart,
+                                          HasAngles, angles, LinearVariation,
+                                          HasRefPoint, refPnt, MakeGroups );
+    myMesh->GetMeshDS()->Modified();
+  }
+  else if ( SMESH::DownCast<SMESH_Group_i*>( Path ))
+  {
+    // path as group of 1D elements
+    // ????????
+  }
+  else
+  {
+    // invalid path
+    Error = SMESH::SMESH_MeshEditor::EXTR_BAD_PATH_SHAPE;
+    return EmptyGr;
+  }
+
+  storeResult(myEditor);
+  Error = convExtrError( error );
+
+  if ( MakeGroups ) {
+    list<int> groupIDs = myMesh->GetGroupIds();
+    list<int>::iterator newBegin = groupIDs.begin();
+    std::advance( newBegin, nbOldGroups ); // skip old groups
+    groupIDs.erase( groupIDs.begin(), newBegin );
+    return getGroups( & groupIDs );
+  }
+  return EmptyGr;
+}
 
+
+//=======================================================================
+//function : ExtrusionAlongPath
+//purpose  :
+//=======================================================================
 SMESH::SMESH_MeshEditor::Extrusion_Error
-  SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array &   theIDsOfElements,
-                                        SMESH::SMESH_Mesh_ptr       thePathMesh,
-                                        GEOM::GEOM_Object_ptr       thePathShape,
-                                        CORBA::Long                 theNodeStart,
-                                        CORBA::Boolean              theHasAngles,
-                                        const SMESH::double_array & theAngles,
-                                        CORBA::Boolean              theHasRefPoint,
-                                        const SMESH::PointStruct &  theRefPoint)
+SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array &   theIDsOfElements,
+                                       SMESH::SMESH_Mesh_ptr       thePathMesh,
+                                       GEOM::GEOM_Object_ptr       thePathShape,
+                                       CORBA::Long                 theNodeStart,
+                                       CORBA::Boolean              theHasAngles,
+                                       const SMESH::double_array & theAngles,
+                                       CORBA::Boolean              theHasRefPoint,
+                                       const SMESH::PointStruct &  theRefPoint)
 {
+  MESSAGE("ExtrusionAlongPath");
   if ( !myPreviewMode ) {
     TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
                   << theIDsOfElements << ", "
@@ -2057,7 +2755,6 @@ SMESH::SMESH_MeshEditor::Extrusion_Error
 //function : ExtrusionAlongPathObject
 //purpose  :
 //=======================================================================
-
 SMESH::SMESH_MeshEditor::Extrusion_Error
 SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr   theObject,
                                              SMESH::SMESH_Mesh_ptr       thePathMesh,
@@ -2101,16 +2798,15 @@ SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr   theObje
 //function : ExtrusionAlongPathObject1D
 //purpose  :
 //=======================================================================
-
 SMESH::SMESH_MeshEditor::Extrusion_Error
 SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr   theObject,
-                                              SMESH::SMESH_Mesh_ptr       thePathMesh,
-                                              GEOM::GEOM_Object_ptr       thePathShape,
-                                              CORBA::Long                 theNodeStart,
-                                              CORBA::Boolean              theHasAngles,
-                                              const SMESH::double_array & theAngles,
-                                              CORBA::Boolean              theHasRefPoint,
-                                              const SMESH::PointStruct &  theRefPoint)
+                                               SMESH::SMESH_Mesh_ptr       thePathMesh,
+                                               GEOM::GEOM_Object_ptr       thePathShape,
+                                               CORBA::Long                 theNodeStart,
+                                               CORBA::Boolean              theHasAngles,
+                                               const SMESH::double_array & theAngles,
+                                               CORBA::Boolean              theHasRefPoint,
+                                               const SMESH::PointStruct &  theRefPoint)
 {
   if ( !myPreviewMode ) {
     TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject1D( "
@@ -2138,7 +2834,7 @@ SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr   theOb
                       theRefPoint,
                       false,
                       anError,
-                     SMDSAbs_Edge);
+                      SMDSAbs_Edge);
   return anError;
 }
 
@@ -2146,16 +2842,15 @@ SMESH_MeshEditor_i::ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr   theOb
 //function : ExtrusionAlongPathObject2D
 //purpose  :
 //=======================================================================
-
 SMESH::SMESH_MeshEditor::Extrusion_Error
 SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr   theObject,
-                                              SMESH::SMESH_Mesh_ptr       thePathMesh,
-                                              GEOM::GEOM_Object_ptr       thePathShape,
-                                              CORBA::Long                 theNodeStart,
-                                              CORBA::Boolean              theHasAngles,
-                                              const SMESH::double_array & theAngles,
-                                              CORBA::Boolean              theHasRefPoint,
-                                              const SMESH::PointStruct &  theRefPoint)
+                                               SMESH::SMESH_Mesh_ptr       thePathMesh,
+                                               GEOM::GEOM_Object_ptr       thePathShape,
+                                               CORBA::Long                 theNodeStart,
+                                               CORBA::Boolean              theHasAngles,
+                                               const SMESH::double_array & theAngles,
+                                               CORBA::Boolean              theHasRefPoint,
+                                               const SMESH::PointStruct &  theRefPoint)
 {
   if ( !myPreviewMode ) {
     TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject2D( "
@@ -2183,16 +2878,15 @@ SMESH_MeshEditor_i::ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr   theOb
                       theRefPoint,
                       false,
                       anError,
-                     SMDSAbs_Face);
+                      SMDSAbs_Face);
   return anError;
 }
 
 
 //=======================================================================
 //function : ExtrusionAlongPathMakeGroups
-//purpose  : 
+//purpose  :
 //=======================================================================
-
 SMESH::ListOfGroups*
 SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array&   theIDsOfElements,
                                                  SMESH::SMESH_Mesh_ptr      thePathMesh,
@@ -2204,27 +2898,25 @@ SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array&   theI
                                                  const SMESH::PointStruct&  theRefPoint,
                                                  SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
 {
-    SMESH::ListOfGroups * aGroups =  extrusionAlongPath( theIDsOfElements,
-                                                         thePathMesh,
-                                                         thePathShape,
-                                                         theNodeStart,
-                                                         theHasAngles,
-                                                         theAngles,
-                                                         theHasRefPoint,
-                                                         theRefPoint,
-                                                         true,
-                                                         Error);
-  if ( !myPreviewMode ) {
+  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+
+  SMESH::ListOfGroups * aGroups =  extrusionAlongPath( theIDsOfElements,
+                                                       thePathMesh,
+                                                       thePathShape,
+                                                       theNodeStart,
+                                                       theHasAngles,
+                                                       theAngles,
+                                                       theHasRefPoint,
+                                                       theRefPoint,
+                                                       true,
+                                                       Error);
+  if (!myPreviewMode) {
     bool isDumpGroups = aGroups && aGroups->length() > 0;
-    TPythonDump aPythonDump;
-    if(isDumpGroups) {
-      aPythonDump << "("<<aGroups;
-    }
-    if(isDumpGroups)
-      aPythonDump << ", error)";
+    if (isDumpGroups)
+      aPythonDump << "(" << aGroups << ", error)";
     else
       aPythonDump <<"error";
-    
+
     aPythonDump<<" = "<< this << ".ExtrusionAlongPathMakeGroups( "
                << theIDsOfElements << ", "
                << thePathMesh      << ", "
@@ -2243,9 +2935,8 @@ SMESH_MeshEditor_i::ExtrusionAlongPathMakeGroups(const SMESH::long_array&   theI
 
 //=======================================================================
 //function : ExtrusionAlongPathObjectMakeGroups
-//purpose  : 
+//purpose  :
 //=======================================================================
-
 SMESH::ListOfGroups* SMESH_MeshEditor_i::
 ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
                                    SMESH::SMESH_Mesh_ptr      thePathMesh,
@@ -2257,6 +2948,8 @@ ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
                                    const SMESH::PointStruct&  theRefPoint,
                                    SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
 {
+  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
                                                       thePathMesh,
@@ -2268,15 +2961,11 @@ ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
                                                       theRefPoint,
                                                       true,
                                                       Error);
-  
-  if ( !myPreviewMode ) {
+
+  if (!myPreviewMode) {
     bool isDumpGroups = aGroups && aGroups->length() > 0;
-    TPythonDump aPythonDump;
-    if(isDumpGroups) {
-      aPythonDump << "("<<aGroups;
-    }
-    if(isDumpGroups)
-      aPythonDump << ", error)";
+    if (isDumpGroups)
+      aPythonDump << "(" << aGroups << ", error)";
     else
       aPythonDump <<"error";
 
@@ -2287,31 +2976,32 @@ ExtrusionAlongPathObjectMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
                 << theNodeStart     << ", "
                 << theHasAngles     << ", "
                 << theAngles        << ", "
-               << theHasRefPoint   << ", "
-               << "SMESH.PointStruct( "
-               << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
-               << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
-               << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
+                << theHasRefPoint   << ", "
+                << "SMESH.PointStruct( "
+                << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
+                << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
+                << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
   }
   return aGroups;
 }
 
 //=======================================================================
 //function : ExtrusionAlongPathObject1DMakeGroups
-//purpose  : 
+//purpose  :
 //=======================================================================
-
 SMESH::ListOfGroups* SMESH_MeshEditor_i::
 ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
-                                    SMESH::SMESH_Mesh_ptr      thePathMesh,
-                                    GEOM::GEOM_Object_ptr      thePathShape,
-                                    CORBA::Long                theNodeStart,
-                                    CORBA::Boolean             theHasAngles,
-                                    const SMESH::double_array& theAngles,
-                                    CORBA::Boolean             theHasRefPoint,
-                                    const SMESH::PointStruct&  theRefPoint,
-                                    SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
+                                     SMESH::SMESH_Mesh_ptr      thePathMesh,
+                                     GEOM::GEOM_Object_ptr      thePathShape,
+                                     CORBA::Long                theNodeStart,
+                                     CORBA::Boolean             theHasAngles,
+                                     const SMESH::double_array& theAngles,
+                                     CORBA::Boolean             theHasRefPoint,
+                                     const SMESH::PointStruct&  theRefPoint,
+                                     SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
 {
+  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
                                                       thePathMesh,
@@ -2323,18 +3013,14 @@ ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
                                                       theRefPoint,
                                                       true,
                                                       Error,
-                                                     SMDSAbs_Edge);
-  
-  if ( !myPreviewMode ) {
+                                                      SMDSAbs_Edge);
+
+  if (!myPreviewMode) {
     bool isDumpGroups = aGroups && aGroups->length() > 0;
-    TPythonDump aPythonDump;
-    if(isDumpGroups) {
-      aPythonDump << "("<<aGroups;
-    }
-    if(isDumpGroups)
-      aPythonDump << ", error)";
+    if (isDumpGroups)
+      aPythonDump << "(" << aGroups << ", error)";
     else
-      aPythonDump <<"error";
+      aPythonDump << "error";
 
     aPythonDump << " = " << this << ".ExtrusionAlongPathObject1DMakeGroups( "
                 << theObject << ", "
@@ -2343,31 +3029,32 @@ ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
                 << theNodeStart     << ", "
                 << theHasAngles     << ", "
                 << theAngles        << ", "
-               << theHasRefPoint   << ", "
-               << "SMESH.PointStruct( "
-               << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
-               << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
-               << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
+                << theHasRefPoint   << ", "
+                << "SMESH.PointStruct( "
+                << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
+                << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
+                << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
   }
   return aGroups;
 }
 
 //=======================================================================
 //function : ExtrusionAlongPathObject2DMakeGroups
-//purpose  : 
+//purpose  :
 //=======================================================================
-
 SMESH::ListOfGroups* SMESH_MeshEditor_i::
 ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
-                                    SMESH::SMESH_Mesh_ptr      thePathMesh,
-                                    GEOM::GEOM_Object_ptr      thePathShape,
-                                    CORBA::Long                theNodeStart,
-                                    CORBA::Boolean             theHasAngles,
-                                    const SMESH::double_array& theAngles,
-                                    CORBA::Boolean             theHasRefPoint,
-                                    const SMESH::PointStruct&  theRefPoint,
-                                    SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
+                                     SMESH::SMESH_Mesh_ptr      thePathMesh,
+                                     GEOM::GEOM_Object_ptr      thePathShape,
+                                     CORBA::Long                theNodeStart,
+                                     CORBA::Boolean             theHasAngles,
+                                     const SMESH::double_array& theAngles,
+                                     CORBA::Boolean             theHasRefPoint,
+                                     const SMESH::PointStruct&  theRefPoint,
+                                     SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
 {
+  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   SMESH::ListOfGroups * aGroups = extrusionAlongPath( anElementsId,
                                                       thePathMesh,
@@ -2379,18 +3066,14 @@ ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
                                                       theRefPoint,
                                                       true,
                                                       Error,
-                                                     SMDSAbs_Face);
-  
-  if ( !myPreviewMode ) {
+                                                      SMDSAbs_Face);
+
+  if (!myPreviewMode) {
     bool isDumpGroups = aGroups && aGroups->length() > 0;
-    TPythonDump aPythonDump;
-    if(isDumpGroups) {
-      aPythonDump << "("<<aGroups;
-    }
-    if(isDumpGroups)
-      aPythonDump << ", error)";
+    if (isDumpGroups)
+      aPythonDump << "(" << aGroups << ", error)";
     else
-      aPythonDump <<"error";
+      aPythonDump << "error";
 
     aPythonDump << " = " << this << ".ExtrusionAlongPathObject2DMakeGroups( "
                 << theObject << ", "
@@ -2399,23 +3082,139 @@ ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
                 << theNodeStart     << ", "
                 << theHasAngles     << ", "
                 << theAngles        << ", "
-               << theHasRefPoint   << ", "
-               << "SMESH.PointStruct( "
-               << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
-               << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
-               << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
+                << theHasRefPoint   << ", "
+                << "SMESH.PointStruct( "
+                << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
+                << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
+                << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ) )";
+  }
+  return aGroups;
+}
+
+
+//=======================================================================
+//function : ExtrusionAlongPathObjX
+//purpose  :
+//=======================================================================
+SMESH::ListOfGroups* SMESH_MeshEditor_i::
+ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr  Object,
+                       SMESH::SMESH_IDSource_ptr  Path,
+                       CORBA::Long                NodeStart,
+                       CORBA::Boolean             HasAngles,
+                       const SMESH::double_array& Angles,
+                       CORBA::Boolean             LinearVariation,
+                       CORBA::Boolean             HasRefPoint,
+                       const SMESH::PointStruct&  RefPoint,
+                       CORBA::Boolean             MakeGroups,
+                       SMESH::ElementType         ElemType,
+                       SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
+{
+  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+
+  SMESH::long_array_var anElementsId = Object->GetIDs();
+  SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
+                                                      Path,
+                                                      NodeStart,
+                                                      HasAngles,
+                                                      Angles,
+                                                      LinearVariation,
+                                                      HasRefPoint,
+                                                      RefPoint,
+                                                      MakeGroups,
+                                                      (SMDSAbs_ElementType)ElemType,
+                                                      Error);
+
+  if (!myPreviewMode) {
+    bool isDumpGroups = aGroups && aGroups->length() > 0;
+    if (isDumpGroups)
+      aPythonDump << "(" << *aGroups << ", error)";
+    else
+      aPythonDump << "error";
+
+    aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
+                << Object          << ", "
+                << Path            << ", "
+                << NodeStart       << ", "
+                << HasAngles       << ", "
+                << TVar( Angles )  << ", "
+                << LinearVariation << ", "
+                << HasRefPoint     << ", "
+                << "SMESH.PointStruct( "
+                << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
+                << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
+                << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
+                << MakeGroups << ", "
+                << ElemType << " )";
+  }
+  return aGroups;
+}
+
+
+//=======================================================================
+//function : ExtrusionAlongPathX
+//purpose  :
+//=======================================================================
+SMESH::ListOfGroups* SMESH_MeshEditor_i::
+ExtrusionAlongPathX(const SMESH::long_array&   IDsOfElements,
+                    SMESH::SMESH_IDSource_ptr  Path,
+                    CORBA::Long                NodeStart,
+                    CORBA::Boolean             HasAngles,
+                    const SMESH::double_array& Angles,
+                    CORBA::Boolean             LinearVariation,
+                    CORBA::Boolean             HasRefPoint,
+                    const SMESH::PointStruct&  RefPoint,
+                    CORBA::Boolean             MakeGroups,
+                    SMESH::ElementType         ElemType,
+                    SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
+{
+  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+
+  SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
+                                                      Path,
+                                                      NodeStart,
+                                                      HasAngles,
+                                                      Angles,
+                                                      LinearVariation,
+                                                      HasRefPoint,
+                                                      RefPoint,
+                                                      MakeGroups,
+                                                      (SMDSAbs_ElementType)ElemType,
+                                                      Error);
+
+  if (!myPreviewMode) {
+    bool isDumpGroups = aGroups && aGroups->length() > 0;
+    if (isDumpGroups)
+      aPythonDump << "(" << *aGroups << ", error)";
+    else
+      aPythonDump <<"error";
+
+    aPythonDump << " = " << this << ".ExtrusionAlongPathX( "
+                << IDsOfElements   << ", "
+                << Path            << ", "
+                << NodeStart       << ", "
+                << HasAngles       << ", "
+                << TVar( Angles )  << ", "
+                << LinearVariation << ", "
+                << HasRefPoint     << ", "
+                << "SMESH.PointStruct( "
+                << TVar( HasRefPoint ? RefPoint.x : 0 ) << ", "
+                << TVar( HasRefPoint ? RefPoint.y : 0 ) << ", "
+                << TVar( HasRefPoint ? RefPoint.z : 0 ) << " ), "
+                << MakeGroups << ", "
+                << ElemType << " )";
   }
   return aGroups;
 }
 
+
 //================================================================================
 /*!
  * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
  * of given angles along path steps
-  * \param PathMesh mesh containing a 1D sub-mesh on the edge, along 
 *                which proceeds the extrusion
-  * \param PathShape is shape(edge); as the mesh can be complex, the edge 
 *                 is used to define the sub-mesh for the path
+ * \param PathMesh mesh containing a 1D sub-mesh on the edge, along
+ *                which proceeds the extrusion
+ * \param PathShape is shape(edge); as the mesh can be complex, the edge
+ *                 is used to define the sub-mesh for the path
  */
 //================================================================================
 
@@ -2455,7 +3254,7 @@ SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr       thePathMes
           int iP = int( angPrevFloor );
           double angPrevCeil = ceil(angPrev);
           angle = ( angPrevCeil - angPrev ) * theAngles[ iP ];
-          
+
           int iC = int( angCurFloor );
           if ( iC < nbAngles )
             angle += ( angCur - angCurFloor ) * theAngles[ iC ];
@@ -2482,25 +3281,25 @@ SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr       thePathMes
 
 //=======================================================================
 //function : mirror
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SMESH::ListOfGroups*
-SMESH_MeshEditor_i::mirror(const SMESH::long_array &           theIDsOfElements,
+SMESH_MeshEditor_i::mirror(TIDSortedElemSet &                  theElements,
                            const SMESH::AxisStruct &           theAxis,
                            SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
                            CORBA::Boolean                      theCopy,
-                           const bool                          theMakeGroups,
+                           bool                                theMakeGroups,
                            ::SMESH_Mesh*                       theTargetMesh)
 {
   initData();
 
-  TIDSortedElemSet elements;
-  arrayToSet(theIDsOfElements, GetMeshDS(), elements);
-
   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
   gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
 
+  if ( theTargetMesh )
+    theCopy = false;
+
   gp_Trsf aTrsf;
   switch ( theMirrorType ) {
   case  SMESH::SMESH_MeshEditor::POINT:
@@ -2513,20 +3312,50 @@ SMESH_MeshEditor_i::mirror(const SMESH::long_array &           theIDsOfElements,
     aTrsf.SetMirror( gp_Ax2( P, V ));
   }
 
-  ::SMESH_MeshEditor anEditor( myMesh );
-  ::SMESH_MeshEditor::PGroupIDs groupIds =
-      anEditor.Transform (elements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
+  TIDSortedElemSet  copyElements;
+  TPreviewMesh      tmpMesh;
+  TIDSortedElemSet* workElements = & theElements;
+  SMESH_Mesh*       mesh = myMesh;
 
-  if(theCopy) {
-    storeResult(anEditor);
+  if ( myPreviewMode )
+  {
+    tmpMesh.Copy( theElements, copyElements);
+    if ( !theCopy && !theTargetMesh )
+    {
+      TIDSortedElemSet elemsAround, elemsAroundCopy;
+      getElementsAround( theElements, GetMeshDS(), elemsAround );
+      tmpMesh.Copy( elemsAround, elemsAroundCopy);
+    }
+    mesh = &tmpMesh;
+    workElements = & copyElements;
+    theMakeGroups = false;
   }
-  return theMakeGroups ? getGroups(groupIds.get()) : 0;
-}
 
-//=======================================================================
-//function : Mirror
-//purpose  :
-//=======================================================================
+  ::SMESH_MeshEditor::PGroupIDs groupIds =
+      myEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
+
+  if(theCopy || myPreviewMode)
+    storeResult(myEditor); // store preview data or new elements
+
+  if ( !myPreviewMode )
+  {
+    if ( theTargetMesh )
+    {
+      theTargetMesh->GetMeshDS()->Modified();
+    }
+    else
+    {
+      myMesh->GetMeshDS()->Modified();
+      myMesh->SetIsModified( true );
+    }
+  }
+  return theMakeGroups ? getGroups(groupIds.get()) : 0;
+}
+
+//=======================================================================
+//function : Mirror
+//purpose  :
+//=======================================================================
 
 void SMESH_MeshEditor_i::Mirror(const SMESH::long_array &           theIDsOfElements,
                                 const SMESH::AxisStruct &           theAxis,
@@ -2535,12 +3364,17 @@ void SMESH_MeshEditor_i::Mirror(const SMESH::long_array &           theIDsOfElem
 {
   if ( !myPreviewMode ) {
     TPythonDump() << this << ".Mirror( "
-                  << theIDsOfElements << ", "
-                  << theAxis          << ", "
+                  << theIDsOfElements              << ", "
+                  << theAxis                       << ", "
                   << mirrorTypeName(theMirrorType) << ", "
-                  << theCopy          << " )";
+                  << theCopy                       << " )";
+  }
+  if ( theIDsOfElements.length() > 0 )
+  {
+    TIDSortedElemSet elements;
+    arrayToSet(theIDsOfElements, GetMeshDS(), elements);
+    mirror(elements, theAxis, theMirrorType, theCopy, false);
   }
-  mirror(theIDsOfElements, theAxis, theMirrorType, theCopy, false);
 }
 
 
@@ -2550,24 +3384,28 @@ void SMESH_MeshEditor_i::Mirror(const SMESH::long_array &           theIDsOfElem
 //=======================================================================
 
 void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr           theObject,
-                                     const SMESH::AxisStruct &           theAxis,
-                                     SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
-                                     CORBA::Boolean                      theCopy)
+                                      const SMESH::AxisStruct &           theAxis,
+                                      SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
+                                      CORBA::Boolean                      theCopy)
 {
   if ( !myPreviewMode ) {
     TPythonDump() << this << ".MirrorObject( "
-                  << theObject << ", "
-                  << theAxis   << ", "
+                  << theObject                     << ", "
+                  << theAxis                       << ", "
                   << mirrorTypeName(theMirrorType) << ", "
-                  << theCopy   << " )";
+                  << theCopy                       << " )";
   }
-  SMESH::long_array_var anElementsId = theObject->GetIDs();
-  mirror(anElementsId, theAxis, theMirrorType, theCopy, false);
+  TIDSortedElemSet elements;
+
+  bool emptyIfIsMesh = myPreviewMode ? false : true;
+
+  if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
+    mirror(elements, theAxis, theMirrorType, theCopy, false);
 }
 
 //=======================================================================
 //function : MirrorMakeGroups
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SMESH::ListOfGroups*
@@ -2575,13 +3413,20 @@ SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array&            theIDsO
                                      const SMESH::AxisStruct&            theMirror,
                                      SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
 {
-  SMESH::ListOfGroups * aGroups = mirror(theIDsOfElements, theMirror, theMirrorType, true, true);
-  if ( !myPreviewMode ) {
-    TPythonDump aPythonDump;
-    DumpGroupsList(aPythonDump,aGroups);
+  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+
+  SMESH::ListOfGroups * aGroups = 0;
+  if ( theIDsOfElements.length() > 0 )
+  {
+    TIDSortedElemSet elements;
+    arrayToSet(theIDsOfElements, GetMeshDS(), elements);
+    aGroups = mirror(elements, theMirror, theMirrorType, true, true);
+  }
+  if (!myPreviewMode) {
+    DumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".MirrorMakeGroups( "
-                << theIDsOfElements << ", "
-                << theMirror << ", "
+                << theIDsOfElements              << ", "
+                << theMirror                     << ", "
                 << mirrorTypeName(theMirrorType) << " )";
   }
   return aGroups;
@@ -2589,7 +3434,7 @@ SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array&            theIDsO
 
 //=======================================================================
 //function : MirrorObjectMakeGroups
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SMESH::ListOfGroups*
@@ -2597,14 +3442,19 @@ SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr           t
                                            const SMESH::AxisStruct&            theMirror,
                                            SMESH::SMESH_MeshEditor::MirrorType theMirrorType)
 {
-  SMESH::long_array_var anElementsId = theObject->GetIDs();
-  SMESH::ListOfGroups * aGroups = mirror(anElementsId, theMirror, theMirrorType, true, true);
-  if ( !myPreviewMode ) {
-    TPythonDump aPythonDump;
+  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+
+  SMESH::ListOfGroups * aGroups = 0;
+  TIDSortedElemSet elements;
+  if ( idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
+    aGroups = mirror(elements, theMirror, theMirrorType, true, true);
+
+  if (!myPreviewMode)
+  {
     DumpGroupsList(aPythonDump,aGroups);
     aPythonDump << this << ".MirrorObjectMakeGroups( "
-                << theObject << ", "
-                << theMirror << ", "
+                << theObject                     << ", "
+                << theMirror                     << ", "
                 << mirrorTypeName(theMirrorType) << " )";
   }
   return aGroups;
@@ -2612,7 +3462,7 @@ SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr           t
 
 //=======================================================================
 //function : MirrorMakeMesh
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SMESH::SMESH_Mesh_ptr
@@ -2626,37 +3476,40 @@ SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array&            theIDsOfE
   SMESH::SMESH_Mesh_var mesh;
   { // open new scope to dump "MakeMesh" command
     // and then "GetGroups" using SMESH_Mesh::GetGroups()
-    
+
     TPythonDump pydump; // to prevent dump at mesh creation
 
     mesh = makeMesh( theMeshName );
     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
-    if (mesh_i) {
-      mirror(theIDsOfElements, theMirror, theMirrorType,
+    if (mesh_i && theIDsOfElements.length() > 0 )
+    {
+      TIDSortedElemSet elements;
+      arrayToSet(theIDsOfElements, GetMeshDS(), elements);
+      mirror(elements, theMirror, theMirrorType,
              false, theCopyGroups, & mesh_i->GetImpl());
       mesh_i->CreateGroupServants();
     }
-    
-    if ( !myPreviewMode ) {
+
+    if (!myPreviewMode) {
       pydump << mesh << " = " << this << ".MirrorMakeMesh( "
-             << theIDsOfElements << ", "
-             << theMirror   << ", "
+             << theIDsOfElements              << ", "
+             << theMirror                     << ", "
              << mirrorTypeName(theMirrorType) << ", "
-             << theCopyGroups << ", '"
-             << theMeshName << "' )";
+             << theCopyGroups                 << ", '"
+             << theMeshName                   << "' )";
     }
   }
 
   //dump "GetGroups"
-  if(!myPreviewMode && mesh_i)
+  if (!myPreviewMode && mesh_i)
     mesh_i->GetGroups();
-  
+
   return mesh._retn();
 }
 
 //=======================================================================
 //function : MirrorObjectMakeMesh
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SMESH::SMESH_Mesh_ptr
@@ -2670,62 +3523,94 @@ SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr           the
   SMESH::SMESH_Mesh_var mesh;
   { // open new scope to dump "MakeMesh" command
     // and then "GetGroups" using SMESH_Mesh::GetGroups()
-    
+
     TPythonDump pydump; // to prevent dump at mesh creation
 
     mesh = makeMesh( theMeshName );
     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
-    if ( mesh_i ) {
-      SMESH::long_array_var anElementsId = theObject->GetIDs();
-      mirror(anElementsId, theMirror, theMirrorType,
+    TIDSortedElemSet elements;
+    if ( mesh_i &&
+         idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
+    {
+      mirror(elements, theMirror, theMirrorType,
              false, theCopyGroups, & mesh_i->GetImpl());
       mesh_i->CreateGroupServants();
     }
-
-    if ( !myPreviewMode ) {
+    if (!myPreviewMode) {
       pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( "
-             << theObject << ", "
-             << theMirror   << ", "
+             << theObject                     << ", "
+             << theMirror                     << ", "
              << mirrorTypeName(theMirrorType) << ", "
-             << theCopyGroups << ", '"
-             << theMeshName << "' )";
+             << theCopyGroups                 << ", '"
+             << theMeshName                   << "' )";
     }
-  } 
+  }
 
   //dump "GetGroups"
-  if(!myPreviewMode && mesh_i)
+  if (!myPreviewMode && mesh_i)
     mesh_i->GetGroups();
-  
+
   return mesh._retn();
 }
 
 //=======================================================================
 //function : translate
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SMESH::ListOfGroups*
-SMESH_MeshEditor_i::translate(const SMESH::long_array & theIDsOfElements,
+SMESH_MeshEditor_i::translate(TIDSortedElemSet        & theElements,
                               const SMESH::DirStruct &  theVector,
                               CORBA::Boolean            theCopy,
-                              const bool                theMakeGroups,
+                              bool                      theMakeGroups,
                               ::SMESH_Mesh*             theTargetMesh)
 {
   initData();
 
-  TIDSortedElemSet elements;
-  arrayToSet(theIDsOfElements, GetMeshDS(), elements);
+  if ( theTargetMesh )
+    theCopy = false;
 
   gp_Trsf aTrsf;
   const SMESH::PointStruct * P = &theVector.PS;
   aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
 
-  ::SMESH_MeshEditor anEditor( myMesh );
+  TIDSortedElemSet  copyElements;
+  TIDSortedElemSet* workElements = &theElements;
+  TPreviewMesh      tmpMesh;
+  SMESH_Mesh*       mesh = myMesh;
+
+  if ( myPreviewMode )
+  {
+    tmpMesh.Copy( theElements, copyElements);
+    if ( !theCopy && !theTargetMesh )
+    {
+      TIDSortedElemSet elemsAround, elemsAroundCopy;
+      getElementsAround( theElements, GetMeshDS(), elemsAround );
+      tmpMesh.Copy( elemsAround, elemsAroundCopy);
+    }
+    mesh = &tmpMesh;
+    workElements = & copyElements;
+    theMakeGroups = false;
+  }
+
   ::SMESH_MeshEditor::PGroupIDs groupIds =
-      anEditor.Transform (elements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
+      myEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
 
-  if(theCopy)
-    storeResult(anEditor);
+  if(theCopy || myPreviewMode)
+    storeResult(myEditor);
+
+  if ( !myPreviewMode )
+  {
+    if ( theTargetMesh )
+    {
+      theTargetMesh->GetMeshDS()->Modified();
+    }
+    else
+    {
+      myMesh->GetMeshDS()->Modified();
+      myMesh->SetIsModified( true );
+    }
+  }
 
   return theMakeGroups ? getGroups(groupIds.get()) : 0;
 }
@@ -2739,16 +3624,17 @@ void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
                                    const SMESH::DirStruct &  theVector,
                                    CORBA::Boolean            theCopy)
 {
-  if ( !myPreviewMode ) {
+  if (!myPreviewMode) {
     TPythonDump() << this << ".Translate( "
                   << theIDsOfElements << ", "
-                  << theVector << ", "
-                  << theCopy << " )";
+                  << theVector        << ", "
+                  << theCopy          << " )";
+  }
+  if (theIDsOfElements.length()) {
+    TIDSortedElemSet elements;
+    arrayToSet(theIDsOfElements, GetMeshDS(), elements);
+    translate(elements, theVector, theCopy, false);
   }
-  translate(theIDsOfElements,
-            theVector,
-            theCopy,
-            false);
 }
 
 //=======================================================================
@@ -2757,58 +3643,67 @@ void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
 //=======================================================================
 
 void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
-                                        const SMESH::DirStruct &  theVector,
-                                        CORBA::Boolean            theCopy)
+                                         const SMESH::DirStruct &  theVector,
+                                         CORBA::Boolean            theCopy)
 {
-  if ( !myPreviewMode ) {
+  if (!myPreviewMode) {
     TPythonDump() << this << ".TranslateObject( "
                   << theObject << ", "
                   << theVector << ", "
-                  << theCopy << " )";
+                  << theCopy   << " )";
   }
-  SMESH::long_array_var anElementsId = theObject->GetIDs();
-  translate(anElementsId,
-            theVector,
-            theCopy,
-            false);
+  TIDSortedElemSet elements;
+
+  bool emptyIfIsMesh = myPreviewMode ? false : true;
+  
+  if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
+    translate(elements, theVector, theCopy, false);
 }
 
 //=======================================================================
 //function : TranslateMakeGroups
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SMESH::ListOfGroups*
 SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements,
                                         const SMESH::DirStruct&  theVector)
 {
-  SMESH::ListOfGroups * aGroups = translate(theIDsOfElements,theVector,true,true);
-  if ( !myPreviewMode ) {
-    TPythonDump aPythonDump;
-    DumpGroupsList(aPythonDump,aGroups);
+  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+
+  SMESH::ListOfGroups * aGroups = 0;
+  if (theIDsOfElements.length()) {
+    TIDSortedElemSet elements;
+    arrayToSet(theIDsOfElements, GetMeshDS(), elements);
+    aGroups = translate(elements,theVector,true,true);
+  }
+  if (!myPreviewMode) {
+    DumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".TranslateMakeGroups( "
                 << theIDsOfElements << ", "
-                << theVector << " )";
+                << theVector        << " )";
   }
   return aGroups;
 }
 
 //=======================================================================
 //function : TranslateObjectMakeGroups
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SMESH::ListOfGroups*
 SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
                                               const SMESH::DirStruct&   theVector)
 {
-  SMESH::long_array_var anElementsId = theObject->GetIDs();
-  SMESH::ListOfGroups * aGroups = translate(anElementsId, theVector, true, true);
-  
-  if ( !myPreviewMode ) {
+  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
 
-    TPythonDump aPythonDump;
-    DumpGroupsList(aPythonDump,aGroups);
+  SMESH::ListOfGroups * aGroups = 0;
+  TIDSortedElemSet elements;
+  if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
+    aGroups = translate(elements, theVector, true, true);
+
+  if (!myPreviewMode) {
+    DumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".TranslateObjectMakeGroups( "
                 << theObject << ", "
                 << theVector << " )";
@@ -2818,7 +3713,7 @@ SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObjec
 
 //=======================================================================
 //function : TranslateMakeMesh
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SMESH::SMESH_Mesh_ptr
@@ -2829,40 +3724,42 @@ SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements,
 {
   SMESH_Mesh_i* mesh_i;
   SMESH::SMESH_Mesh_var mesh;
-  
+
   { // open new scope to dump "MakeMesh" command
     // and then "GetGroups" using SMESH_Mesh::GetGroups()
 
     TPythonDump pydump; // to prevent dump at mesh creation
-    
+
     mesh = makeMesh( theMeshName );
     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
-    
-    if ( mesh_i ) {
-      translate(theIDsOfElements, theVector,
-                false, theCopyGroups, & mesh_i->GetImpl());
+
+    if ( mesh_i && theIDsOfElements.length() )
+    {
+      TIDSortedElemSet elements;
+      arrayToSet(theIDsOfElements, GetMeshDS(), elements);
+      translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl());
       mesh_i->CreateGroupServants();
     }
-    
+
     if ( !myPreviewMode ) {
       pydump << mesh << " = " << this << ".TranslateMakeMesh( "
              << theIDsOfElements << ", "
-             << theVector   << ", "
-             << theCopyGroups << ", '"
-             << theMeshName << "' )";
+             << theVector        << ", "
+             << theCopyGroups    << ", '"
+             << theMeshName      << "' )";
     }
   }
-  
+
   //dump "GetGroups"
-  if(!myPreviewMode && mesh_i)
+  if (!myPreviewMode && mesh_i)
     mesh_i->GetGroups();
-  
+
   return mesh._retn();
 }
 
 //=======================================================================
 //function : TranslateObjectMakeMesh
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SMESH::SMESH_Mesh_ptr
@@ -2875,50 +3772,51 @@ SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
   SMESH::SMESH_Mesh_var mesh;
   { // open new scope to dump "MakeMesh" command
     // and then "GetGroups" using SMESH_Mesh::GetGroups()
-    
+
     TPythonDump pydump; // to prevent dump at mesh creation
     mesh = makeMesh( theMeshName );
     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
-    
-    if ( mesh_i ) {
-      SMESH::long_array_var anElementsId = theObject->GetIDs();
-      translate(anElementsId, theVector,
-                false, theCopyGroups, & mesh_i->GetImpl());
+
+    TIDSortedElemSet elements;
+    if ( mesh_i &&
+      idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
+    {
+      translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl());
       mesh_i->CreateGroupServants();
     }
     if ( !myPreviewMode ) {
       pydump << mesh << " = " << this << ".TranslateObjectMakeMesh( "
-             << theObject << ", "
-             << theVector   << ", "
+             << theObject     << ", "
+             << theVector     << ", "
              << theCopyGroups << ", '"
-             << theMeshName << "' )";
+             << theMeshName   << "' )";
     }
   }
-  
-  //dump "GetGroups"
-  if(!myPreviewMode && mesh_i)
+
+  // dump "GetGroups"
+  if (!myPreviewMode && mesh_i)
     mesh_i->GetGroups();
-  
+
   return mesh._retn();
 }
 
 //=======================================================================
 //function : rotate
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SMESH::ListOfGroups*
-SMESH_MeshEditor_i::rotate(const SMESH::long_array & theIDsOfElements,
+SMESH_MeshEditor_i::rotate(TIDSortedElemSet &        theElements,
                            const SMESH::AxisStruct & theAxis,
                            CORBA::Double             theAngle,
                            CORBA::Boolean            theCopy,
-                           const bool                theMakeGroups,
+                           bool                      theMakeGroups,
                            ::SMESH_Mesh*             theTargetMesh)
 {
   initData();
 
-  TIDSortedElemSet elements;
-  arrayToSet(theIDsOfElements, GetMeshDS(), elements);
+  if ( theTargetMesh )
+    theCopy = false;
 
   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
   gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz );
@@ -2926,13 +3824,43 @@ SMESH_MeshEditor_i::rotate(const SMESH::long_array & theIDsOfElements,
   gp_Trsf aTrsf;
   aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
 
-  ::SMESH_MeshEditor anEditor( myMesh );
+  TIDSortedElemSet  copyElements;
+  TIDSortedElemSet* workElements = &theElements;
+  TPreviewMesh      tmpMesh;
+  SMESH_Mesh*       mesh = myMesh;
+
+  if ( myPreviewMode ) {
+    tmpMesh.Copy( theElements, copyElements );
+    if ( !theCopy && !theTargetMesh )
+    {
+      TIDSortedElemSet elemsAround, elemsAroundCopy;
+      getElementsAround( theElements, GetMeshDS(), elemsAround );
+      tmpMesh.Copy( elemsAround, elemsAroundCopy);
+    }
+    mesh = &tmpMesh;
+    workElements = &copyElements;
+    theMakeGroups = false;
+  }
+
   ::SMESH_MeshEditor::PGroupIDs groupIds =
-      anEditor.Transform (elements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
+      myEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
+
+  if(theCopy || myPreviewMode)
+    storeResult(myEditor);
 
-  if(theCopy) {
-    storeResult(anEditor);
+  if ( !myPreviewMode )
+  {
+    if ( theTargetMesh )
+    {
+      theTargetMesh->GetMeshDS()->Modified();
+    }
+    else
+    {
+      myMesh->GetMeshDS()->Modified();
+      myMesh->SetIsModified( true );
+    }
   }
+
   return theMakeGroups ? getGroups(groupIds.get()) : 0;
 }
 
@@ -2946,18 +3874,19 @@ void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
                                 CORBA::Double             theAngle,
                                 CORBA::Boolean            theCopy)
 {
-  if ( !myPreviewMode ) {
+  if (!myPreviewMode) {
     TPythonDump() << this << ".Rotate( "
                   << theIDsOfElements << ", "
-                  << theAxis << ", "
-                  << theAngle << ", "
-                  << theCopy << " )";
+                  << theAxis          << ", "
+                  << TVar( theAngle ) << ", "
+                  << theCopy          << " )";
+  }
+  if (theIDsOfElements.length() > 0)
+  {
+    TIDSortedElemSet elements;
+    arrayToSet(theIDsOfElements, GetMeshDS(), elements);
+    rotate(elements,theAxis,theAngle,theCopy,false);
   }
-  rotate(theIDsOfElements,
-         theAxis,
-         theAngle,
-         theCopy,
-         false);
 }
 
 //=======================================================================
@@ -2966,28 +3895,26 @@ void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
 //=======================================================================
 
 void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
-                                     const SMESH::AxisStruct & theAxis,
-                                     CORBA::Double             theAngle,
-                                     CORBA::Boolean            theCopy)
+                                      const SMESH::AxisStruct & theAxis,
+                                      CORBA::Double             theAngle,
+                                      CORBA::Boolean            theCopy)
 {
   if ( !myPreviewMode ) {
     TPythonDump() << this << ".RotateObject( "
-                  << theObject << ", "
-                  << theAxis << ", "
-                  << theAngle << ", "
-                  << theCopy << " )";
+                  << theObject        << ", "
+                  << theAxis          << ", "
+                  << TVar( theAngle ) << ", "
+                  << theCopy          << " )";
   }
-  SMESH::long_array_var anElementsId = theObject->GetIDs();
-  rotate(anElementsId,
-         theAxis,
-         theAngle,
-         theCopy,
-         false);
+  TIDSortedElemSet elements;
+  bool emptyIfIsMesh = myPreviewMode ? false : true;
+  if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
+    rotate(elements,theAxis,theAngle,theCopy,false);
 }
 
 //=======================================================================
 //function : RotateMakeGroups
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SMESH::ListOfGroups*
@@ -2995,21 +3922,28 @@ SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements,
                                      const SMESH::AxisStruct& theAxis,
                                      CORBA::Double            theAngle)
 {
-  SMESH::ListOfGroups * aGroups =  rotate(theIDsOfElements,theAxis,theAngle,true,true);
-  if ( !myPreviewMode ) {
-    TPythonDump aPythonDump;
-    DumpGroupsList(aPythonDump,aGroups);
+  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+
+  SMESH::ListOfGroups * aGroups = 0;
+  if (theIDsOfElements.length() > 0)
+  {
+    TIDSortedElemSet elements;
+    arrayToSet(theIDsOfElements, GetMeshDS(), elements);
+    aGroups = rotate(elements,theAxis,theAngle,true,true);
+  }
+  if (!myPreviewMode) {
+    DumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".RotateMakeGroups( "
                 << theIDsOfElements << ", "
-               << theAxis << ", "
-                << theAngle << " )";
+                << theAxis          << ", "
+                << TVar( theAngle ) << " )";
   }
   return aGroups;
 }
 
 //=======================================================================
 //function : RotateObjectMakeGroups
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SMESH::ListOfGroups*
@@ -3017,26 +3951,29 @@ SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject,
                                            const SMESH::AxisStruct&  theAxis,
                                            CORBA::Double             theAngle)
 {
-  SMESH::long_array_var anElementsId = theObject->GetIDs();
-  SMESH::ListOfGroups * aGroups =  rotate(anElementsId,theAxis,theAngle,true,true);
-  if ( !myPreviewMode ) {
-    TPythonDump aPythonDump;
-    DumpGroupsList(aPythonDump,aGroups);
+  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+
+  SMESH::ListOfGroups * aGroups = 0;
+  TIDSortedElemSet elements;
+  if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
+    aGroups = rotate(elements, theAxis, theAngle, true, true);
+
+  if (!myPreviewMode) {
+    DumpGroupsList(aPythonDump, aGroups);
     aPythonDump << this << ".RotateObjectMakeGroups( "
-               << theObject << ", "
-               << theAxis << ", "
-               << theAngle << " )";
+                << theObject        << ", "
+                << theAxis          << ", "
+                << TVar( theAngle ) << " )";
   }
   return aGroups;
 }
 
 //=======================================================================
 //function : RotateMakeMesh
-//purpose  : 
+//purpose  :
 //=======================================================================
 
-SMESH::SMESH_Mesh_ptr 
+SMESH::SMESH_Mesh_ptr
 SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
                                    const SMESH::AxisStruct& theAxis,
                                    CORBA::Double            theAngleInRadians,
@@ -3048,40 +3985,43 @@ SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements,
 
   { // open new scope to dump "MakeMesh" command
     // and then "GetGroups" using SMESH_Mesh::GetGroups()
-    
+
     TPythonDump pydump; // to prevent dump at mesh creation
 
     mesh = makeMesh( theMeshName );
     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
-    
-    if ( mesh_i ) {
-      rotate(theIDsOfElements, theAxis, theAngleInRadians,
+
+    if ( mesh_i && theIDsOfElements.length() > 0 )
+    {
+      TIDSortedElemSet elements;
+      arrayToSet(theIDsOfElements, GetMeshDS(), elements);
+      rotate(elements, theAxis, theAngleInRadians,
              false, theCopyGroups, & mesh_i->GetImpl());
       mesh_i->CreateGroupServants();
     }
     if ( !myPreviewMode ) {
       pydump << mesh << " = " << this << ".RotateMakeMesh( "
-             << theIDsOfElements << ", "
-             << theAxis << ", "
-             << theAngleInRadians   << ", "
-             << theCopyGroups << ", '"
-             << theMeshName << "' )";
+             << theIDsOfElements          << ", "
+             << theAxis                   << ", "
+             << TVar( theAngleInRadians ) << ", "
+             << theCopyGroups             << ", '"
+             << theMeshName               << "' )";
     }
   }
-  
-  //dump "GetGroups"
-  if(!myPreviewMode && mesh_i)
+
+  // dump "GetGroups"
+  if (!myPreviewMode && mesh_i && theIDsOfElements.length() > 0 )
     mesh_i->GetGroups();
-  
+
   return mesh._retn();
 }
 
 //=======================================================================
 //function : RotateObjectMakeMesh
-//purpose  : 
+//purpose  :
 //=======================================================================
 
-SMESH::SMESH_Mesh_ptr 
+SMESH::SMESH_Mesh_ptr
 SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
                                          const SMESH::AxisStruct&  theAxis,
                                          CORBA::Double             theAngleInRadians,
@@ -3090,108 +4030,220 @@ SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject,
 {
   SMESH::SMESH_Mesh_var mesh;
   SMESH_Mesh_i* mesh_i;
-  
+
   {// open new scope to dump "MakeMesh" command
    // and then "GetGroups" using SMESH_Mesh::GetGroups()
-    
+
     TPythonDump pydump; // to prevent dump at mesh creation
     mesh = makeMesh( theMeshName );
     mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
-    
-    if (mesh_i ) {
-      SMESH::long_array_var anElementsId = theObject->GetIDs();
-      rotate(anElementsId, theAxis, theAngleInRadians,
+
+    TIDSortedElemSet elements;
+    if (mesh_i &&
+        idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
+    {
+      rotate(elements, theAxis, theAngleInRadians,
              false, theCopyGroups, & mesh_i->GetImpl());
       mesh_i->CreateGroupServants();
     }
     if ( !myPreviewMode ) {
       pydump << mesh << " = " << this << ".RotateObjectMakeMesh( "
-             << theObject << ", "
-             << theAxis << ", "
-             << theAngleInRadians   << ", "
-             << theCopyGroups << ", '"
-             << theMeshName << "' )";
+             << theObject                 << ", "
+             << theAxis                   << ", "
+             << TVar( theAngleInRadians ) << ", "
+             << theCopyGroups             << ", '"
+             << theMeshName               << "' )";
     }
   }
-  
-  //dump "GetGroups"
-  if(!myPreviewMode && mesh_i)
+
+  // dump "GetGroups"
+  if (!myPreviewMode && mesh_i)
     mesh_i->GetGroups();
-  
+
   return mesh._retn();
 }
 
 //=======================================================================
-//function : FindCoincidentNodes
+//function : scale
 //purpose  :
 //=======================================================================
 
-void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double                  Tolerance,
-                                              SMESH::array_of_long_array_out GroupsOfNodes)
+SMESH::ListOfGroups*
+SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr  theObject,
+                          const SMESH::PointStruct&  thePoint,
+                          const SMESH::double_array& theScaleFact,
+                          CORBA::Boolean             theCopy,
+                          bool                       theMakeGroups,
+                          ::SMESH_Mesh*              theTargetMesh)
 {
   initData();
+  if ( theScaleFact.length() < 1 )
+    THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM);
+  if ( theScaleFact.length() == 2 )
+    THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM);
 
-  ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
-  ::SMESH_MeshEditor anEditor( myMesh );
-  set<const SMDS_MeshNode*> nodes; // no input nodes
-  anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
+  if ( theTargetMesh )
+    theCopy = false;
 
-  GroupsOfNodes = new SMESH::array_of_long_array;
-  GroupsOfNodes->length( aListOfListOfNodes.size() );
-  ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
-  for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
-    list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
-    list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
-    SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
-    aGroup.length( aListOfNodes.size() );
-    for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
-      aGroup[ j ] = (*lIt)->GetID();
+  TIDSortedElemSet elements;
+  bool emptyIfIsMesh = myPreviewMode ? false : true;
+  if ( !idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, emptyIfIsMesh))
+    return 0;
+
+  double S[3] = {
+    theScaleFact[0],
+    (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1],
+    (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2],
+  };
+  double tol = std::numeric_limits<double>::max();
+  gp_Trsf aTrsf;
+  aTrsf.SetValues( S[0], 0,    0,    thePoint.x * (1-S[0]),
+                   0,    S[1], 0,    thePoint.y * (1-S[1]),
+                   0,    0,    S[2], thePoint.z * (1-S[2]),   tol, tol);
+
+  TIDSortedElemSet  copyElements;
+  TPreviewMesh      tmpMesh;
+  TIDSortedElemSet* workElements = &elements;
+  SMESH_Mesh*       mesh = myMesh;
+  
+  if ( myPreviewMode )
+  {
+    tmpMesh.Copy( elements, copyElements);
+    if ( !theCopy && !theTargetMesh )
+    {
+      TIDSortedElemSet elemsAround, elemsAroundCopy;
+      getElementsAround( elements, GetMeshDS(), elemsAround );
+      tmpMesh.Copy( elemsAround, elemsAroundCopy);
+    }
+    mesh = &tmpMesh;
+    workElements = & copyElements;
+    theMakeGroups = false;
   }
-  TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
-                << Tolerance << " )";
+
+  ::SMESH_MeshEditor::PGroupIDs groupIds =
+      myEditor.Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
+
+  if(theCopy || myPreviewMode )
+    storeResult(myEditor);
+
+  if ( !myPreviewMode )
+  {
+    if ( theTargetMesh )
+    {
+      theTargetMesh->GetMeshDS()->Modified();
+    }
+    else
+    {
+      myMesh->GetMeshDS()->Modified();
+      myMesh->SetIsModified( true );
+    }
+  }
+
+  return theMakeGroups ? getGroups(groupIds.get()) : 0;
 }
 
 //=======================================================================
-//function : FindCoincidentNodesOnPart
+//function : Scale
 //purpose  :
 //=======================================================================
-void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr      theObject,
-                                                   CORBA::Double                  Tolerance,
-                                                   SMESH::array_of_long_array_out GroupsOfNodes)
+
+void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr  theObject,
+                               const SMESH::PointStruct&  thePoint,
+                               const SMESH::double_array& theScaleFact,
+                               CORBA::Boolean             theCopy)
 {
-  initData();
-  SMESH::long_array_var aElementsId = theObject->GetIDs();
+  if ( !myPreviewMode ) {
+    TPythonDump() << this << ".Scale( "
+                  << theObject            << ", "
+                  << thePoint             << ", "
+                  << TVar( theScaleFact ) << ", "
+                  << theCopy              << " )";
+  }
+  scale(theObject, thePoint, theScaleFact, theCopy, false);
+}
 
-  SMESHDS_Mesh* aMesh = GetMeshDS();
-  set<const SMDS_MeshNode*> nodes;
 
-  if ( !CORBA::is_nil(SMESH::SMESH_GroupBase::_narrow(theObject)) &&
-      SMESH::SMESH_GroupBase::_narrow(theObject)->GetType() == SMESH::NODE) {
-    for(int i = 0; i < aElementsId->length(); i++) {
-      CORBA::Long ind = aElementsId[i];
-      const SMDS_MeshNode * elem = aMesh->FindNode(ind);
-      if(elem)
-        nodes.insert(elem);
-    }
+//=======================================================================
+//function : ScaleMakeGroups
+//purpose  :
+//=======================================================================
+
+SMESH::ListOfGroups*
+SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
+                                    const SMESH::PointStruct&  thePoint,
+                                    const SMESH::double_array& theScaleFact)
+{
+  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+
+  SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true);
+  if (!myPreviewMode) {
+    DumpGroupsList(aPythonDump, aGroups);
+    aPythonDump << this << ".Scale("
+                << theObject            << ","
+                << thePoint             << ","
+                << TVar( theScaleFact ) << ",True,True)";
   }
-  else {
-    for(int i = 0; i < aElementsId->length(); i++) {
-      CORBA::Long ind = aElementsId[i];
-      const SMDS_MeshElement * elem = aMesh->FindElement(ind);
-      if(elem) {
-        SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
-        while ( nIt->more() )
-          nodes.insert( nodes.end(),static_cast<const SMDS_MeshNode*>(nIt->next()));
-      }
+  return aGroups;
+}
+
+
+//=======================================================================
+//function : ScaleMakeMesh
+//purpose  :
+//=======================================================================
+
+SMESH::SMESH_Mesh_ptr
+SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr  theObject,
+                                  const SMESH::PointStruct&  thePoint,
+                                  const SMESH::double_array& theScaleFact,
+                                  CORBA::Boolean             theCopyGroups,
+                                  const char*                theMeshName)
+{
+  SMESH_Mesh_i* mesh_i;
+  SMESH::SMESH_Mesh_var mesh;
+  { // open new scope to dump "MakeMesh" command
+    // and then "GetGroups" using SMESH_Mesh::GetGroups()
+
+    TPythonDump pydump; // to prevent dump at mesh creation
+    mesh = makeMesh( theMeshName );
+    mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
+
+    if ( mesh_i )
+    {
+      scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl());
+      mesh_i->CreateGroupServants();
     }
+    if ( !myPreviewMode )
+      pydump << mesh << " = " << this << ".ScaleMakeMesh( "
+             << theObject            << ", "
+             << thePoint             << ", "
+             << TVar( theScaleFact ) << ", "
+             << theCopyGroups        << ", '"
+             << theMeshName          << "' )";
   }
-    
-  
+
+  // dump "GetGroups"
+  if (!myPreviewMode && mesh_i)
+    mesh_i->GetGroups();
+
+  return mesh._retn();
+}
+
+
+//=======================================================================
+//function : FindCoincidentNodes
+//purpose  :
+//=======================================================================
+
+void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double                  Tolerance,
+                                              SMESH::array_of_long_array_out GroupsOfNodes)
+{
+  initData();
+
   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
-  ::SMESH_MeshEditor anEditor( myMesh );
-  if(!nodes.empty())
-    anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
-  
+  TIDSortedNodeSet nodes; // no input nodes
+  myEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
+
   GroupsOfNodes = new SMESH::array_of_long_array;
   GroupsOfNodes->length( aListOfListOfNodes.size() );
   ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
@@ -3203,11 +4255,92 @@ void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr
     for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
       aGroup[ j ] = (*lIt)->GetID();
   }
+  TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
+                << Tolerance << " )";
+}
+
+//=======================================================================
+//function : FindCoincidentNodesOnPart
+//purpose  :
+//=======================================================================
+void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr      theObject,
+                                                   CORBA::Double                  Tolerance,
+                                                   SMESH::array_of_long_array_out GroupsOfNodes)
+{
+  initData();
+
+  TIDSortedNodeSet nodes;
+  idSourceToNodeSet( theObject, GetMeshDS(), nodes );
+
+  ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
+  if(!nodes.empty())
+    myEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
+
+  GroupsOfNodes = new SMESH::array_of_long_array;
+  GroupsOfNodes->length( aListOfListOfNodes.size() );
+  ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
+  for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
+  {
+    list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
+    list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
+    SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
+    aGroup.length( aListOfNodes.size() );
+    for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
+      aGroup[ j ] = (*lIt)->GetID();
+  }
   TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
                 <<theObject<<", "
                 << Tolerance << " )";
 }
 
+//================================================================================
+/*!
+ * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within
+ *        ExceptSubMeshOrGroups
+ */
+//================================================================================
+
+void SMESH_MeshEditor_i::
+FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr      theObject,
+                             CORBA::Double                  theTolerance,
+                             SMESH::array_of_long_array_out theGroupsOfNodes,
+                             const SMESH::ListOfIDSources&  theExceptSubMeshOrGroups)
+{
+  initData();
+
+  TIDSortedNodeSet nodes;
+  idSourceToNodeSet( theObject, GetMeshDS(), nodes );
+
+  for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
+  {
+    TIDSortedNodeSet exceptNodes;
+    idSourceToNodeSet( theExceptSubMeshOrGroups[i], GetMeshDS(), exceptNodes );
+    TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
+    for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
+      nodes.erase( *avoidNode );
+  }
+  ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
+  if(!nodes.empty())
+    myEditor.FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
+
+  theGroupsOfNodes = new SMESH::array_of_long_array;
+  theGroupsOfNodes->length( aListOfListOfNodes.size() );
+  ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
+  for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
+  {
+    list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
+    list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
+    SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
+    aGroup.length( aListOfNodes.size() );
+    for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
+      aGroup[ j ] = (*lIt)->GetID();
+  }
+  TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
+                << theObject<<", "
+                << theTolerance << ", "
+                << theExceptSubMeshOrGroups << " )";
+}
+
 //=======================================================================
 //function : MergeNodes
 //purpose  :
@@ -3240,10 +4373,11 @@ void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfN
     if ( i > 0 ) aTPythonDump << ", ";
     aTPythonDump << aNodeGroup;
   }
-  ::SMESH_MeshEditor anEditor( myMesh );
-  anEditor.MergeNodes( aListOfListOfNodes );
+  myEditor.MergeNodes( aListOfListOfNodes );
 
   aTPythonDump <<  "])";
+  myMesh->GetMeshDS()->Modified();
+  myMesh->SetIsModified( true );
 }
 
 //=======================================================================
@@ -3251,11 +4385,13 @@ void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfN
 //purpose  :
 //=======================================================================
 void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr      theObject,
-                                          SMESH::array_of_long_array_out GroupsOfElementsID)
+                                           SMESH::array_of_long_array_out GroupsOfElementsID)
 {
   initData();
-  if ( !(!CORBA::is_nil(SMESH::SMESH_GroupBase::_narrow(theObject)) &&
-        SMESH::SMESH_GroupBase::_narrow(theObject)->GetType() == SMESH::NODE) ) {
+
+  SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject);
+  if ( !(!group->_is_nil() && group->GetType() == SMESH::NODE) )
+  {
     typedef list<int> TListOfIDs;
     set<const SMDS_MeshElement*> elems;
     SMESH::long_array_var aElementsId = theObject->GetIDs();
@@ -3265,13 +4401,12 @@ void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr      theObj
       CORBA::Long anID = aElementsId[i];
       const SMDS_MeshElement * elem = aMesh->FindElement(anID);
       if (elem) {
-       elems.insert(elem);
+        elems.insert(elem);
       }
     }
 
     ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
-    ::SMESH_MeshEditor anEditor( myMesh );
-    anEditor.FindEqualElements( elems, aListOfListOfElementsID );
+    myEditor.FindEqualElements( elems, aListOfListOfElementsID );
 
     GroupsOfElementsID = new SMESH::array_of_long_array;
     GroupsOfElementsID->length( aListOfListOfElementsID.size() );
@@ -3283,12 +4418,12 @@ void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr      theObj
       aGroup.length( listOfIDs.size() );
       TListOfIDs::iterator idIt = listOfIDs.begin();
       for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k ) {
-       aGroup[ k ] = *idIt;
+        aGroup[ k ] = *idIt;
       }
     }
 
-  TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
-                <<theObject<<" )";
+    TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
+                  <<theObject<<" )";
   }
 }
 
@@ -3320,8 +4455,9 @@ void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsO
     aTPythonDump << anElemsIDGroup;
   }
 
-  ::SMESH_MeshEditor anEditor( myMesh );
-  anEditor.MergeElements(aListOfListOfElementsID);
+  myEditor.MergeElements(aListOfListOfElementsID);
+  myMesh->GetMeshDS()->Modified();
+  myMesh->SetIsModified( true );
 
   aTPythonDump << "] )";
 }
@@ -3335,12 +4471,91 @@ void SMESH_MeshEditor_i::MergeEqualElements()
 {
   initData();
 
-  ::SMESH_MeshEditor anEditor( myMesh );
-  anEditor.MergeEqualElements();
+  myEditor.MergeEqualElements();
+
+  myMesh->GetMeshDS()->Modified();
 
   TPythonDump() << this << ".MergeEqualElements()";
 }
 
+//=============================================================================
+/*!
+ * Move the node to a given point
+ */
+//=============================================================================
+
+CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long   NodeID,
+                                            CORBA::Double x,
+                                            CORBA::Double y,
+                                            CORBA::Double z)
+{
+  initData(/*deleteSearchers=*/false);
+
+  const SMDS_MeshNode * node = GetMeshDS()->FindNode( NodeID );
+  if ( !node )
+    return false;
+
+  if ( theNodeSearcher )
+    theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
+
+  if ( myPreviewMode ) // make preview data
+  {
+    // in a preview mesh, make edges linked to a node
+    TPreviewMesh tmpMesh;
+    TIDSortedElemSet linkedNodes;
+    ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
+    TIDSortedElemSet::iterator nIt = linkedNodes.begin();
+    SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
+    for ( ; nIt != linkedNodes.end(); ++nIt )
+    {
+      SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
+      tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
+    }
+    // move copied node
+    if ( nodeCpy1 )
+      tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
+    // fill preview data
+    storeResult( myEditor );
+  }
+  else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
+    theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
+  else
+    GetMeshDS()->MoveNode(node, x, y, z);
+
+  if ( !myPreviewMode )
+  {
+    // Update Python script
+    TPythonDump() << "isDone = " << this << ".MoveNode( "
+                  << NodeID << ", " << TVar(x) << ", " << TVar(y) << ", " << TVar(z) << " )";
+    myMesh->GetMeshDS()->Modified();
+    myMesh->SetIsModified( true );
+  }
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Return ID of node closest to a given point
+ */
+//================================================================================
+
+CORBA::Long SMESH_MeshEditor_i::FindNodeClosestTo(CORBA::Double x,
+                                                  CORBA::Double y,
+                                                  CORBA::Double z)
+{
+  theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
+
+  if ( !theNodeSearcher ) {
+    theNodeSearcher = myEditor.GetNodeSearcher();
+  }
+  gp_Pnt p( x,y,z );
+  if ( const SMDS_MeshNode* node = theNodeSearcher->FindClosestTo( p ))
+    return node->GetID();
+
+  return 0;
+}
+
 //================================================================================
 /*!
  * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
@@ -3353,24 +4568,23 @@ CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
                                                        CORBA::Double z,
                                                        CORBA::Long   theNodeID)
 {
-  // We keep myNodeSearcher until any mesh modification:
-  // 1) initData() deletes myNodeSearcher at any edition,
-  // 2) TNodeSearcherDeleter - at any mesh compute event and mesh change
+  // We keep theNodeSearcher until any mesh modification:
+  // 1) initData() deletes theNodeSearcher at any edition,
+  // 2) TSearchersDeleter - at any mesh compute event and mesh change
 
-  initData();
+  initData(/*deleteSearchers=*/false);
+
+  theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other
 
   int nodeID = theNodeID;
   const SMDS_MeshNode* node = GetMeshDS()->FindNode( nodeID );
-  if ( !node )
+  if ( !node ) // preview moving node
   {
-    static TNodeSearcherDeleter deleter;
-    deleter.Set( myMesh );
-    if ( !myNodeSearcher ) {
-      ::SMESH_MeshEditor anEditor( myMesh );
-      myNodeSearcher = anEditor.GetNodeSearcher();
+    if ( !theNodeSearcher ) {
+      theNodeSearcher = myEditor.GetNodeSearcher();
     }
     gp_Pnt p( x,y,z );
-    node = myNodeSearcher->FindClosestTo( p );
+    node = theNodeSearcher->FindClosestTo( p );
   }
   if ( node ) {
     nodeID = node->GetID();
@@ -3383,7 +4597,7 @@ CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
       TIDSortedElemSet::iterator nIt = linkedNodes.begin();
       for ( ; nIt != linkedNodes.end(); ++nIt )
       {
-        SMDS_MeshEdge edge( node, cast2Node( *nIt ));
+        SMDS_LinearEdge edge( node, cast2Node( *nIt ));
         tmpMesh.Copy( &edge );
       }
       // move copied node
@@ -3391,8 +4605,11 @@ CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
       if ( node )
         tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
       // fill preview data
-      ::SMESH_MeshEditor anEditor( & tmpMesh );
-      storeResult( anEditor );
+      storeResult( myEditor );
+    }
+    else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly
+    {
+      theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z ));
     }
     else
     {
@@ -3400,15 +4617,137 @@ CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
     }
   }
 
-  if ( !myPreviewMode ) {
+  if ( !myPreviewMode )
+  {
     TPythonDump() << "nodeID = " << this
                   << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
                   << ", " << nodeID << " )";
+
+    myMesh->GetMeshDS()->Modified();
+    myMesh->SetIsModified( true );
   }
 
   return nodeID;
 }
 
+//=======================================================================
+/*!
+ * Return elements of given type where the given point is IN or ON.
+ *
+ * 'ALL' type means elements of any type excluding nodes
+ */
+//=======================================================================
+
+SMESH::long_array* SMESH_MeshEditor_i::FindElementsByPoint(CORBA::Double      x,
+                                                           CORBA::Double      y,
+                                                           CORBA::Double      z,
+                                                           SMESH::ElementType type)
+{
+  SMESH::long_array_var res = new SMESH::long_array;
+  vector< const SMDS_MeshElement* > foundElems;
+
+  theSearchersDeleter.Set( myMesh );
+  if ( !theElementSearcher ) {
+    theElementSearcher = myEditor.GetElementSearcher();
+  }
+  theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
+                                           SMDSAbs_ElementType( type ),
+                                           foundElems);
+  res->length( foundElems.size() );
+  for ( int i = 0; i < foundElems.size(); ++i )
+    res[i] = foundElems[i]->GetID();
+
+  if ( !myPreviewMode ) // call from tui
+    TPythonDump() << "res = " << this << ".FindElementsByPoint( "
+                  << x << ", "
+                  << y << ", "
+                  << z << ", "
+                  << type << " )";
+
+  return res._retn();
+}
+
+//=======================================================================
+//function : FindAmongElementsByPoint
+//purpose  : Searching among the given elements, return elements of given type 
+//           where the given point is IN or ON.
+//           'ALL' type means elements of any type excluding nodes
+//=======================================================================
+
+SMESH::long_array*
+SMESH_MeshEditor_i::FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elementIDs,
+                                             CORBA::Double             x,
+                                             CORBA::Double             y,
+                                             CORBA::Double             z,
+                                             SMESH::ElementType        type)
+{
+  SMESH::long_array_var res = new SMESH::long_array;
+  
+  SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
+  if ( types->length() == 1 && // a part contains only nodes or 0D elements
+       ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
+       type != types[0] ) // but search of elements of dim > 0
+    return res._retn();
+
+  if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh 
+    return FindElementsByPoint( x,y,z, type );
+
+  TIDSortedElemSet elements; // elems should live until FindElementsByPoint() finishes
+
+  theSearchersDeleter.Set( myMesh, getPartIOR( elementIDs, type ));
+  if ( !theElementSearcher )
+  {
+    // create a searcher from elementIDs
+    SMESH::SMESH_Mesh_var mesh = elementIDs->GetMesh();
+    SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
+
+    if ( !idSourceToSet( elementIDs, meshDS, elements,
+                         SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
+      return res._retn();
+
+    typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
+    SMDS_ElemIteratorPtr elemsIt( new TIter( elements.begin(), elements.end() ));
+
+    theElementSearcher = myEditor.GetElementSearcher(elemsIt);
+  }
+
+  vector< const SMDS_MeshElement* > foundElems;
+
+  theElementSearcher->FindElementsByPoint( gp_Pnt( x,y,z ),
+                                           SMDSAbs_ElementType( type ),
+                                           foundElems);
+  res->length( foundElems.size() );
+  for ( int i = 0; i < foundElems.size(); ++i )
+    res[i] = foundElems[i]->GetID();
+
+  if ( !myPreviewMode ) // call from tui
+    TPythonDump() << "res = " << this << ".FindAmongElementsByPoint( "
+                  << elementIDs << ", "
+                  << x << ", "
+                  << y << ", "
+                  << z << ", "
+                  << type << " )";
+
+  return res._retn();
+  
+}
+//=======================================================================
+//function : GetPointState
+//purpose  : Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
+//           TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
+//=======================================================================
+
+CORBA::Short SMESH_MeshEditor_i::GetPointState(CORBA::Double x,
+                                               CORBA::Double y,
+                                               CORBA::Double z)
+{
+  theSearchersDeleter.Set( myMesh );
+  if ( !theElementSearcher ) {
+    theElementSearcher = myEditor.GetElementSearcher();
+  }
+  return CORBA::Short( theElementSearcher->GetPointState( gp_Pnt( x,y,z )));
+}
+
 //=======================================================================
 //function : convError
 //purpose  :
@@ -3419,16 +4758,16 @@ CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
 static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Sew_Error e )
 {
   switch ( e ) {
-  RETCASE( SEW_OK );
-  RETCASE( SEW_BORDER1_NOT_FOUND );
-  RETCASE( SEW_BORDER2_NOT_FOUND );
-  RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
-  RETCASE( SEW_BAD_SIDE_NODES );
-  RETCASE( SEW_VOLUMES_TO_SPLIT );
-  RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
-  RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
-  RETCASE( SEW_BAD_SIDE1_NODES );
-  RETCASE( SEW_BAD_SIDE2_NODES );
+    RETCASE( SEW_OK );
+    RETCASE( SEW_BORDER1_NOT_FOUND );
+    RETCASE( SEW_BORDER2_NOT_FOUND );
+    RETCASE( SEW_BOTH_BORDERS_NOT_FOUND );
+    RETCASE( SEW_BAD_SIDE_NODES );
+    RETCASE( SEW_VOLUMES_TO_SPLIT );
+    RETCASE( SEW_DIFF_NB_OF_ELEMENTS );
+    RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
+    RETCASE( SEW_BAD_SIDE1_NODES );
+    RETCASE( SEW_BAD_SIDE2_NODES );
   }
   return SMESH::SMESH_MeshEditor::SEW_OK;
 }
@@ -3439,14 +4778,14 @@ static SMESH::SMESH_MeshEditor::Sew_Error convError( const::SMESH_MeshEditor::Se
 //=======================================================================
 
 SMESH::SMESH_MeshEditor::Sew_Error
-  SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
-                                     CORBA::Long SecondNodeID1,
-                                     CORBA::Long LastNodeID1,
-                                     CORBA::Long FirstNodeID2,
-                                     CORBA::Long SecondNodeID2,
-                                     CORBA::Long LastNodeID2,
-                                     CORBA::Boolean CreatePolygons,
-                                     CORBA::Boolean CreatePolyedrs)
+SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
+                                   CORBA::Long SecondNodeID1,
+                                   CORBA::Long LastNodeID1,
+                                   CORBA::Long FirstNodeID2,
+                                   CORBA::Long SecondNodeID2,
+                                   CORBA::Long LastNodeID2,
+                                   CORBA::Boolean CreatePolygons,
+                                   CORBA::Boolean CreatePolyedrs)
 {
   initData();
 
@@ -3478,9 +4817,8 @@ SMESH::SMESH_MeshEditor::Sew_Error
                 << CreatePolygons<< ", "
                 << CreatePolyedrs<< " )";
 
-  ::SMESH_MeshEditor anEditor( myMesh );
   SMESH::SMESH_MeshEditor::Sew_Error error =
-    convError( anEditor.SewFreeBorder (aBorderFirstNode,
+    convError( myEditor.SewFreeBorder (aBorderFirstNode,
                                        aBorderSecondNode,
                                        aBorderLastNode,
                                        aSide2FirstNode,
@@ -3490,7 +4828,10 @@ SMESH::SMESH_MeshEditor::Sew_Error
                                        CreatePolygons,
                                        CreatePolyedrs) );
 
-  storeResult(anEditor);
+  storeResult(myEditor);
+
+  myMesh->GetMeshDS()->Modified();
+  myMesh->SetIsModified( true );
 
   return error;
 }
@@ -3534,9 +4875,8 @@ SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
                 << FirstNodeID2  << ", "
                 << SecondNodeID2 << " )";
 
-  ::SMESH_MeshEditor anEditor( myMesh );
   SMESH::SMESH_MeshEditor::Sew_Error error =
-    convError( anEditor.SewFreeBorder (aBorderFirstNode,
+    convError( myEditor.SewFreeBorder (aBorderFirstNode,
                                        aBorderSecondNode,
                                        aBorderLastNode,
                                        aSide2FirstNode,
@@ -3545,7 +4885,10 @@ SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
                                        true,
                                        false, false) );
 
-  storeResult(anEditor);
+  storeResult(myEditor);
+
+  myMesh->GetMeshDS()->Modified();
+  myMesh->SetIsModified( true );
 
   return error;
 }
@@ -3593,9 +4936,8 @@ SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
                 << CreatePolygons           << ", "
                 << CreatePolyedrs           << ") ";
 
-  ::SMESH_MeshEditor anEditor( myMesh );
   SMESH::SMESH_MeshEditor::Sew_Error error =
-    convError( anEditor.SewFreeBorder (aBorderFirstNode,
+    convError( myEditor.SewFreeBorder (aBorderFirstNode,
                                        aBorderSecondNode,
                                        aBorderLastNode,
                                        aSide2FirstNode,
@@ -3605,7 +4947,10 @@ SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
                                        CreatePolygons,
                                        CreatePolyedrs) );
 
-  storeResult(anEditor);
+  storeResult(myEditor);
+
+  myMesh->GetMeshDS()->Modified();
+  myMesh->SetIsModified( true );
 
   return error;
 }
@@ -3652,15 +4997,17 @@ SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
                 << NodeID2OfSide1ToMerge << ", "
                 << NodeID2OfSide2ToMerge << ")";
 
-  ::SMESH_MeshEditor anEditor( myMesh );
   SMESH::SMESH_MeshEditor::Sew_Error error =
-    convError( anEditor.SewSideElements (aSide1Elems, aSide2Elems,
+    convError( myEditor.SewSideElements (aSide1Elems, aSide2Elems,
                                          aFirstNode1ToMerge,
                                          aFirstNode2ToMerge,
                                          aSecondNode1ToMerge,
                                          aSecondNode2ToMerge));
 
-  storeResult(anEditor);
+  storeResult(myEditor);
+
+  myMesh->GetMeshDS()->Modified();
+  myMesh->SetIsModified( true );
 
   return error;
 }
@@ -3668,9 +5015,9 @@ SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
 //================================================================================
 /*!
  * \brief Set new nodes for given element
 * \param ide - element id
 * \param newIDs - new node ids
 * \retval CORBA::Boolean - true if result is OK
+ * \param ide - element id
+ * \param newIDs - new node ids
+ * \retval CORBA::Boolean - true if result is OK
  */
 //================================================================================
 
@@ -3695,176 +5042,114 @@ CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
   }
   TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
                 << ide << ", " << newIDs << " )";
-#ifdef _DEBUG_
-  TPythonDump() << "print 'ChangeElemNodes: ', isDone";
-#endif
 
-  return GetMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
+  MESSAGE("ChangeElementNodes");
+  bool res = GetMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
+
+  myMesh->GetMeshDS()->Modified();
+  if ( res )
+    myMesh->SetIsModified( true );
+
+  return res;
+}
+
+//=======================================================================
+//function : ConvertToQuadratic
+//purpose  :
+//=======================================================================
+
+void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
+{
+  myEditor.ConvertToQuadratic(theForce3d);
+  TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
+  myMesh->GetMeshDS()->Modified();
+  myMesh->SetIsModified( true );
+}
+
+//=======================================================================
+//function : ConvertFromQuadratic
+//purpose  :
+//=======================================================================
+
+CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
+{
+  CORBA::Boolean isDone = myEditor.ConvertFromQuadratic();
+  TPythonDump() << this << ".ConvertFromQuadratic()";
+  myMesh->GetMeshDS()->Modified();
+  if ( isDone )
+    myMesh->SetIsModified( true );
+  return isDone;
 }
-  
 //================================================================================
 /*!
- * \brief Update myLastCreated* or myPreviewData
-  * \param anEditor - it contains last modification results
+ * \brief Makes a part of the mesh quadratic
  */
 //================================================================================
 
-void SMESH_MeshEditor_i::storeResult(::SMESH_MeshEditor& anEditor)
+void SMESH_MeshEditor_i::ConvertToQuadraticObject(CORBA::Boolean            theForce3d,
+                                                  SMESH::SMESH_IDSource_ptr theObject)
+  throw (SALOME::SALOME_Exception)
 {
-  if ( myPreviewMode ) { // --- MeshPreviewStruct filling --- 
+  Unexpect aCatch(SALOME_SalomeException);
+  TPythonDump pyDump;
+  TIDSortedElemSet elems;
+  if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
+  {
+    if ( elems.empty() )
+    {
+      ConvertToQuadratic( theForce3d );
+    }
+    else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
+    {
+      THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
+    }
+    else
+    {
+      myEditor.ConvertToQuadratic(theForce3d, elems);
+    }
+  }
+  myMesh->GetMeshDS()->Modified();
+  myMesh->SetIsModified( true );
 
-    list<int> aNodesConnectivity;
-    typedef map<int, int> TNodesMap;
-    TNodesMap nodesMap;
+  pyDump << this << ".ConvertToQuadraticObject( "<<theForce3d<<", "<<theObject<<" )";
+}
 
-    TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( anEditor.GetMesh() );
-    SMDSAbs_ElementType previewType = aPreviewMesh->myPreviewType;
-
-    SMESHDS_Mesh* aMeshDS = anEditor.GetMeshDS();
-    int nbEdges = aMeshDS->NbEdges();
-    int nbFaces = aMeshDS->NbFaces();
-    int nbVolum = aMeshDS->NbVolumes();
-    switch ( previewType ) {
-    case SMDSAbs_Edge  : nbFaces = nbVolum = 0; break;
-    case SMDSAbs_Face  : nbEdges = nbVolum = 0; break;
-    case SMDSAbs_Volume: nbEdges = nbFaces = 0; break;
-    default:;
-    }
-    myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
-    myPreviewData->elementTypes.length(nbEdges + nbFaces + nbVolum);
-    int i = 0, j = 0;
-    SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator();
-
-    while ( itMeshElems->more() ) {
-      const SMDS_MeshElement* aMeshElem = itMeshElems->next();
-      if ( previewType != SMDSAbs_All && aMeshElem->GetType() != previewType )
-        continue;
-
-      SMDS_ElemIteratorPtr itElemNodes = aMeshElem->nodesIterator();
-      while ( itElemNodes->more() ) {
-        const SMDS_MeshNode* aMeshNode = 
-          static_cast<const SMDS_MeshNode*>( itElemNodes->next() );
-        int aNodeID = aMeshNode->GetID();
-        TNodesMap::iterator anIter = nodesMap.find(aNodeID);
-        if ( anIter == nodesMap.end() ) {
-          // filling the nodes coordinates
-          myPreviewData->nodesXYZ[j].x = aMeshNode->X();
-          myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
-          myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
-          anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
-          j++;
-        }
-        aNodesConnectivity.push_back(anIter->second);
-      }
-
-      // filling the elements types
-      SMDSAbs_ElementType aType;
-      bool isPoly;
-      /*if (aMeshElem->GetType() == SMDSAbs_Volume) {
-        aType = SMDSAbs_Node;
-        isPoly = false;
-      }
-      else*/ {
-        aType = aMeshElem->GetType();
-        isPoly = aMeshElem->IsPoly();
-      }
-
-      myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
-      myPreviewData->elementTypes[i].isPoly = isPoly;
-      myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
-      i++;
+//================================================================================
+/*!
+ * \brief Makes a part of the mesh linear
+ */
+//================================================================================
 
+void SMESH_MeshEditor_i::ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
+  throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  TPythonDump pyDump;
+  TIDSortedElemSet elems;
+  if ( idSourceToSet( theObject, GetMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true ))
+  {
+    if ( elems.empty() )
+    {
+      ConvertFromQuadratic();
+    }
+    else if ( (*elems.begin())->GetType() == SMDSAbs_Node )
+    {
+      THROW_SALOME_CORBA_EXCEPTION("Group of nodes is not allowed", SALOME::BAD_PARAM);
+    }
+    else
+    {
+      myEditor.ConvertFromQuadratic(elems);
     }
-    myPreviewData->nodesXYZ.length( j );
-
-    // filling the elements connectivities
-    list<int>::iterator aConnIter = aNodesConnectivity.begin();
-    myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
-    for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
-      myPreviewData->elementConnectivities[i] = *aConnIter;
-    
-    return;
   }
+  myMesh->GetMeshDS()->Modified();
+  myMesh->SetIsModified( true );
 
-  {
-    // add new nodes into myLastCreatedNodes
-    const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedNodes();
-    myLastCreatedNodes->length(aSeq.Length());
-    for(int i=0; i<aSeq.Length(); i++)
-      myLastCreatedNodes[i] = aSeq.Value(i+1)->GetID();
-  }
-  {
-    // add new elements into myLastCreatedElems
-    const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedElems();
-    myLastCreatedElems->length(aSeq.Length());
-    for(int i=0; i<aSeq.Length(); i++)
-      myLastCreatedElems[i] = aSeq.Value(i+1)->GetID();
-  }
-}
-
-//================================================================================
-/*!
- * Return data of mesh edition preview
- */
-//================================================================================
-
-SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
-{
-  return myPreviewData._retn();
-}
-
-//================================================================================
-/*!
- * \brief Returns list of it's IDs of created nodes
-  * \retval SMESH::long_array* - list of node ID
- */
-//================================================================================
-
-SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
-{
-  return myLastCreatedNodes._retn();
-}
-
-//================================================================================
-/*!
- * \brief Returns list of it's IDs of created elements
-  * \retval SMESH::long_array* - list of elements' ID
- */
-//================================================================================
-
-SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
-{
-  return myLastCreatedElems._retn();
-}
-
-//=======================================================================
-//function : ConvertToQuadratic
-//purpose  :
-//=======================================================================
-
-void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
-{
-  ::SMESH_MeshEditor anEditor( myMesh );
-  anEditor.ConvertToQuadratic(theForce3d);
-  TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
-}
-
-//=======================================================================
-//function : ConvertFromQuadratic
-//purpose  : 
-//=======================================================================
-
-CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
-{
-  ::SMESH_MeshEditor anEditor( myMesh );
-  CORBA::Boolean isDone = anEditor.ConvertFromQuadratic();
-  TPythonDump() << this << ".ConvertFromQuadratic()";
-  return isDone;
+  pyDump << this << ".ConvertFromQuadraticObject( "<<theObject<<" )";
 }
 
 //=======================================================================
 //function : makeMesh
-//purpose  : create a named imported mesh 
+//purpose  : create a named imported mesh
 //=======================================================================
 
 SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
@@ -3874,11 +5159,7 @@ SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
   SALOMEDS::Study_var study = gen->GetCurrentStudy();
   SALOMEDS::SObject_var meshSO = gen->ObjectToSObject( study, mesh );
   gen->SetName( meshSO, theMeshName, "Mesh" );
-
-  SALOMEDS::StudyBuilder_var builder = study->NewBuilder();
-  SALOMEDS::GenericAttribute_var anAttr
-    = builder->FindOrCreateAttribute( meshSO, "AttributePixMap" );
-  SALOMEDS::AttributePixMap::_narrow( anAttr )->SetPixMap( "ICON_SMESH_TREE_MESH_IMPORTED" );
+  gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
 
   return mesh._retn();
 }
@@ -3887,7 +5168,7 @@ SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::makeMesh(const char* theMeshName)
 //function : DumpGroupsList
 //purpose  :
 //=======================================================================
-void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump &               theDumpPython, 
+void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump &               theDumpPython,
                                         const SMESH::ListOfGroups * theGroupList)
 {
   bool isDumpGroupList = theGroupList && theGroupList->length() > 0;
@@ -3896,24 +5177,63 @@ void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump &               theDumpPytho
   }
 }
 
+//================================================================================
+/*!
+  \brief Generates the unique group name.
+  \param thePrefix name prefix
+  \return unique name
+*/
+//================================================================================
+string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
+{
+  SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
+  set<string> groupNames;
+
+  // Get existing group names
+  for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
+    SMESH::SMESH_GroupBase_var aGroup = groups[i];
+    if (CORBA::is_nil(aGroup))
+      continue;
+
+    groupNames.insert(aGroup->GetName());
+  }
+
+  // Find new name
+  string name = thePrefix;
+  int index = 0;
+
+  while (!groupNames.insert(name).second) {
+    if (index == 0) {
+      name += "_1";
+    }
+    else {
+      TCollection_AsciiString nbStr(index+1);
+      name.resize( name.rfind('_')+1 );
+      name += nbStr.ToCString();
+    }
+    ++index;
+  }
+
+  return name;
+}
+
 //================================================================================
 /*!
   \brief Creates a hole in a mesh by doubling the nodes of some particular elements
   \param theNodes - identifiers of nodes to be doubled
-  \param theModifiedElems - identifiers of elements to be updated by the new (doubled) 
-         nodes. If list of element identifiers is empty then nodes are doubled but 
+  \param theModifiedElems - identifiers of elements to be updated by the new (doubled)
+         nodes. If list of element identifiers is empty then nodes are doubled but
          they not assigned to elements
   \return TRUE if operation has been completed successfully, FALSE otherwise
   \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
 */
 //================================================================================
 
-CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes, 
+CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNodes,
                                                 const SMESH::long_array& theModifiedElems )
 {
   initData();
 
-  ::SMESH_MeshEditor aMeshEditor( myMesh );
   list< int > aListOfNodes;
   int i, n;
   for ( i = 0, n = theNodes.length(); i < n; i++ )
@@ -3923,9 +5243,15 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNode
   for ( i = 0, n = theModifiedElems.length(); i < n; i++ )
     aListOfElems.push_back( theModifiedElems[ i ] );
 
-  bool aResult = aMeshEditor.DoubleNodes( aListOfNodes, aListOfElems );
+  bool aResult = myEditor.DoubleNodes( aListOfNodes, aListOfElems );
 
-  storeResult( aMeshEditor) ;
+  myMesh->GetMeshDS()->Modified();
+  storeResult( myEditor) ;
+  if ( aResult )
+    myMesh->SetIsModified( true );
+
+  // Update Python script
+  TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )";
 
   return aResult;
 }
@@ -3941,13 +5267,20 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNode
 */
 //================================================================================
 
-CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long              theNodeId, 
+CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long              theNodeId,
                                                const SMESH::long_array& theModifiedElems )
 {
   SMESH::long_array_var aNodes = new SMESH::long_array;
   aNodes->length( 1 );
   aNodes[ 0 ] = theNodeId;
-  return DoubleNodes( aNodes, theModifiedElems );
+
+  TPythonDump pyDump; // suppress dump by the next line
+
+  CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems );
+
+  pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )";
+
+  return done;
 }
 
 //================================================================================
@@ -3961,9 +5294,8 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long              theNodeI
 */
 //================================================================================
 
-CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup( 
-  SMESH::SMESH_GroupBase_ptr theNodes,
-  SMESH::SMESH_GroupBase_ptr theModifiedElems )
+CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes,
+                                                   SMESH::SMESH_GroupBase_ptr theModifiedElems )
 {
   if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
     return false;
@@ -3972,13 +5304,68 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(
   SMESH::long_array_var aModifiedElems;
   if ( !CORBA::is_nil( theModifiedElems ) )
     aModifiedElems = theModifiedElems->GetListOfID();
-  else 
+  else
   {
     aModifiedElems = new SMESH::long_array;
     aModifiedElems->length( 0 );
   }
 
-  return DoubleNodes( aNodes, aModifiedElems );
+  TPythonDump pyDump; // suppress dump by the next line
+
+  bool done = DoubleNodes( aNodes, aModifiedElems );
+
+  pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )";
+
+  return done;
+}
+
+/*!
+ * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
+ * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
+ * \param theNodes - group of nodes to be doubled.
+ * \param theModifiedElems - group of elements to be updated.
+ * \return a new group with newly created nodes
+ * \sa DoubleNodeGroup()
+ */
+SMESH::SMESH_Group_ptr
+SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
+                                        SMESH::SMESH_GroupBase_ptr theModifiedElems )
+{
+  SMESH::SMESH_Group_var aNewGroup;
+
+  if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE )
+    return aNewGroup._retn();
+
+  // Duplicate nodes
+  SMESH::long_array_var aNodes = theNodes->GetListOfID();
+  SMESH::long_array_var aModifiedElems;
+  if ( !CORBA::is_nil( theModifiedElems ) )
+    aModifiedElems = theModifiedElems->GetListOfID();
+  else {
+    aModifiedElems = new SMESH::long_array;
+    aModifiedElems->length( 0 );
+  }
+
+  TPythonDump pyDump; // suppress dump by the next line
+
+  bool aResult = DoubleNodes( aNodes, aModifiedElems );
+  if ( aResult )
+  {
+    // Create group with newly created nodes
+    SMESH::long_array_var anIds = GetLastCreatedNodes();
+    if (anIds->length() > 0) {
+      string anUnindexedName (theNodes->GetName());
+      string aNewName = generateGroupName(anUnindexedName + "_double");
+      aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
+      aNewGroup->Add(anIds);
+      pyDump << aNewGroup << " = ";
+    }
+  }
+
+  pyDump << this << ".DoubleNodeGroupNew( " << theNodes << ", "
+         << theModifiedElems << " )";
+
+  return aNewGroup._retn();
 }
 
 //================================================================================
@@ -3992,13 +5379,11 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(
 */
 //================================================================================
 
-CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups( 
-  const SMESH::ListOfGroups& theNodes,
-  const SMESH::ListOfGroups& theModifiedElems )
+CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes,
+                                                    const SMESH::ListOfGroups& theModifiedElems )
 {
   initData();
 
-  ::SMESH_MeshEditor aMeshEditor( myMesh );
 
   std::list< int > aNodes;
   int i, n, j, m;
@@ -4025,9 +5410,899 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(
     }
   }
 
-  bool aResult = aMeshEditor.DoubleNodes( aNodes, anElems );
+  bool aResult = myEditor.DoubleNodes( aNodes, anElems );
+
+  storeResult( myEditor) ;
+
+  myMesh->GetMeshDS()->Modified();
+  if ( aResult )
+    myMesh->SetIsModified( true );
+
+
+  TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )";
+
+  return aResult;
+}
+
+//================================================================================
+/*!
+ * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
+ * Works as DoubleNodeGroups(), but returns a new group with newly created nodes.
+ * \param theNodes - group of nodes to be doubled.
+ * \param theModifiedElems - group of elements to be updated.
+ * \return a new group with newly created nodes
+ * \sa DoubleNodeGroups()
+ */
+//================================================================================
+
+SMESH::SMESH_Group_ptr
+SMESH_MeshEditor_i::DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
+                                         const SMESH::ListOfGroups& theModifiedElems )
+{
+  SMESH::SMESH_Group_var aNewGroup;
+
+  TPythonDump pyDump; // suppress dump by the next line
+
+  bool aResult = DoubleNodeGroups( theNodes, theModifiedElems );
+
+  if ( aResult )
+  {
+    // Create group with newly created nodes
+    SMESH::long_array_var anIds = GetLastCreatedNodes();
+    if (anIds->length() > 0) {
+      string anUnindexedName (theNodes[0]->GetName());
+      string aNewName = generateGroupName(anUnindexedName + "_double");
+      aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
+      aNewGroup->Add(anIds);
+      pyDump << aNewGroup << " = ";
+    }
+  }
+
+  pyDump << this << ".DoubleNodeGroupsNew( " << theNodes << ", "
+         << theModifiedElems << " )";
+
+  return aNewGroup._retn();
+}
+
+
+//================================================================================
+/*!
+  \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+  \param theElems - the list of elements (edges or faces) to be replicated
+  The nodes for duplication could be found from these elements
+  \param theNodesNot - list of nodes to NOT replicate
+  \param theAffectedElems - the list of elements (cells and edges) to which the
+  replicated nodes should be associated to.
+  \return TRUE if operation has been completed successfully, FALSE otherwise
+  \sa DoubleNodeGroup(), DoubleNodeGroups()
+*/
+//================================================================================
+
+CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theElems,
+                                                   const SMESH::long_array& theNodesNot,
+                                                   const SMESH::long_array& theAffectedElems )
+
+{
+  initData();
+
+
+  SMESHDS_Mesh* aMeshDS = GetMeshDS();
+  TIDSortedElemSet anElems, aNodes, anAffected;
+  arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
+  arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
+  arrayToSet(theAffectedElems, aMeshDS, anAffected, SMDSAbs_All);
+
+  bool aResult = myEditor.DoubleNodes( anElems, aNodes, anAffected );
+
+  storeResult( myEditor) ;
+
+  myMesh->GetMeshDS()->Modified();
+  if ( aResult )
+    myMesh->SetIsModified( true );
+
+  // Update Python script
+  TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", "
+                << theNodesNot << ", " << theAffectedElems << " )";
+  return aResult;
+}
+
+//================================================================================
+/*!
+  \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+  \param theElems - the list of elements (edges or faces) to be replicated
+  The nodes for duplication could be found from these elements
+  \param theNodesNot - list of nodes to NOT replicate
+  \param theShape - shape to detect affected elements (element which geometric center
+  located on or inside shape).
+  The replicated nodes should be associated to affected elements.
+  \return TRUE if operation has been completed successfully, FALSE otherwise
+  \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
+*/
+//================================================================================
+
+CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems,
+                                                            const SMESH::long_array& theNodesNot,
+                                                            GEOM::GEOM_Object_ptr    theShape )
+
+{
+  initData();
+
+
+  SMESHDS_Mesh* aMeshDS = GetMeshDS();
+  TIDSortedElemSet anElems, aNodes;
+  arrayToSet(theElems, aMeshDS, anElems, SMDSAbs_All);
+  arrayToSet(theNodesNot, aMeshDS, aNodes, SMDSAbs_Node);
+
+  TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
+  bool aResult = myEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
+
+  storeResult( myEditor) ;
+
+  myMesh->GetMeshDS()->Modified();
+  if ( aResult )
+    myMesh->SetIsModified( true );
+
+  // Update Python script
+  TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", "
+                << theNodesNot << ", " << theShape << " )";
+  return aResult;
+}
+
+//================================================================================
+/*!
+  \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+  \param theElems - group of of elements (edges or faces) to be replicated
+  \param theNodesNot - group of nodes not to replicated
+  \param theAffectedElems - group of elements to which the replicated nodes
+  should be associated to.
+  \return TRUE if operation has been completed successfully, FALSE otherwise
+  \sa DoubleNodes(), DoubleNodeGroups()
+*/
+//================================================================================
+
+CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems,
+                                                       SMESH::SMESH_GroupBase_ptr theNodesNot,
+                                                       SMESH::SMESH_GroupBase_ptr theAffectedElems)
+{
+  if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
+    return false;
+
+  initData();
+
+
+  SMESHDS_Mesh* aMeshDS = GetMeshDS();
+  TIDSortedElemSet anElems, aNodes, anAffected;
+  idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
+  idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
+  idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
+
+  bool aResult = myEditor.DoubleNodes( anElems, aNodes, anAffected );
+
+  storeResult( myEditor) ;
+
+  myMesh->GetMeshDS()->Modified();
+  if ( aResult )
+    myMesh->SetIsModified( true );
+
+  // Update Python script
+  TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", "
+                << theNodesNot << ", " << theAffectedElems << " )";
+  return aResult;
+}
+
+/*!
+ * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+ * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
+ * \param theElems - group of of elements (edges or faces) to be replicated
+ * \param theNodesNot - group of nodes not to replicated
+ * \param theAffectedElems - group of elements to which the replicated nodes
+ *        should be associated to.
+ * \return a new group with newly created elements
+ * \sa DoubleNodeElemGroup()
+ */
+SMESH::SMESH_Group_ptr
+SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems,
+                                           SMESH::SMESH_GroupBase_ptr theNodesNot,
+                                           SMESH::SMESH_GroupBase_ptr theAffectedElems)
+{
+  TPythonDump pyDump;
+  SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroup2New( theElems,
+                                                               theNodesNot,
+                                                               theAffectedElems,
+                                                               true, false );
+  SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
+  SMESH::SMESH_Group_var     elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
+
+  pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupNew( "
+         << theElems         << ", "
+         << theNodesNot      << ", "
+         << theAffectedElems << " )";
+
+  return elemGroup._retn();
+}
+
+SMESH::ListOfGroups*
+SMESH_MeshEditor_i::DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
+                                            SMESH::SMESH_GroupBase_ptr theNodesNot,
+                                            SMESH::SMESH_GroupBase_ptr theAffectedElems,
+                                            CORBA::Boolean             theElemGroupNeeded,
+                                            CORBA::Boolean             theNodeGroupNeeded)
+{
+  SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
+  SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
+  aTwoGroups->length( 2 );
+
+  if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
+    return aTwoGroups._retn();
+
+  initData();
+
+
+  SMESHDS_Mesh* aMeshDS = GetMeshDS();
+  TIDSortedElemSet anElems, aNodes, anAffected;
+  idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
+  idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
+  idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All );
+
+
+  bool aResult = myEditor.DoubleNodes( anElems, aNodes, anAffected );
+
+  storeResult( myEditor) ;
+  myMesh->GetMeshDS()->Modified();
+
+  TPythonDump pyDump;
+
+  if ( aResult )
+  {
+    myMesh->SetIsModified( true );
+
+    // Create group with newly created elements
+    CORBA::String_var elemGroupName = theElems->GetName();
+    string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
+    if ( !myEditor.GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
+    {
+      SMESH::long_array_var anIds = GetLastCreatedElems();
+      SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
+      aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
+      aNewElemGroup->Add(anIds);
+    }
+    if ( !myEditor.GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
+    {
+      SMESH::long_array_var anIds = GetLastCreatedNodes();
+      aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
+      aNewNodeGroup->Add(anIds);
+    }
+  }
+
+  // Update Python script
+
+  pyDump << "[ ";
+  if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
+  else                            pyDump << aNewElemGroup << ", ";
+  if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
+  else                            pyDump << aNewNodeGroup << " ] = ";
+
+  pyDump << this << ".DoubleNodeElemGroup2New( " << theElems << ", "
+         << theNodesNot        << ", "
+         << theAffectedElems   << ", "
+         << theElemGroupNeeded << ", "
+         << theNodeGroupNeeded <<" )";
+
+  aTwoGroups[0] = aNewElemGroup._retn();
+  aTwoGroups[1] = aNewNodeGroup._retn();
+  return aTwoGroups._retn();
+}
+
+//================================================================================
+/*!
+  \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+  \param theElems - group of of elements (edges or faces) to be replicated
+  \param theNodesNot - group of nodes not to replicated
+  \param theShape - shape to detect affected elements (element which geometric center
+  located on or inside shape).
+  The replicated nodes should be associated to affected elements.
+  \return TRUE if operation has been completed successfully, FALSE otherwise
+  \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
+*/
+//================================================================================
+
+CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems,
+                                                               SMESH::SMESH_GroupBase_ptr theNodesNot,
+                                                               GEOM::GEOM_Object_ptr      theShape )
+
+{
+  if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE )
+    return false;
+
+  initData();
+
+
+  SMESHDS_Mesh* aMeshDS = GetMeshDS();
+  TIDSortedElemSet anElems, aNodes, anAffected;
+  idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All );
+  idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node );
+
+  TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
+  bool aResult = myEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
+
+  storeResult( myEditor) ;
+
+  myMesh->GetMeshDS()->Modified();
+  if ( aResult )
+    myMesh->SetIsModified( true );
+
+  // Update Python script
+  TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", "
+                << theNodesNot << ", " << theShape << " )";
+  return aResult;
+}
+
+//================================================================================
+/*!
+  \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+  This method provided for convenience works as DoubleNodes() described above.
+  \param theElems - list of groups of elements (edges or faces) to be replicated
+  \param theNodesNot - list of groups of nodes not to replicated
+  \param theAffectedElems - group of elements to which the replicated nodes
+  should be associated to.
+  \return TRUE if operation has been completed successfully, FALSE otherwise
+  \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
+*/
+//================================================================================
+
+static void listOfGroupToSet(const SMESH::ListOfGroups& theGrpList,
+                             SMESHDS_Mesh*              theMeshDS,
+                             TIDSortedElemSet&          theElemSet,
+                             const bool                 theIsNodeGrp)
+{
+  for ( int i = 0, n = theGrpList.length(); i < n; i++ )
+  {
+    SMESH::SMESH_GroupBase_var aGrp = theGrpList[ i ];
+    if ( !CORBA::is_nil( aGrp ) && (theIsNodeGrp ? aGrp->GetType() == SMESH::NODE
+                                    : aGrp->GetType() != SMESH::NODE ) )
+    {
+      SMESH::long_array_var anIDs = aGrp->GetIDs();
+      arrayToSet( anIDs, theMeshDS, theElemSet, theIsNodeGrp ? SMDSAbs_Node : SMDSAbs_All );
+    }
+  }
+}
+
+CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroups& theElems,
+                                                        const SMESH::ListOfGroups& theNodesNot,
+                                                        const SMESH::ListOfGroups& theAffectedElems)
+{
+  initData();
+
+
+  SMESHDS_Mesh* aMeshDS = GetMeshDS();
+  TIDSortedElemSet anElems, aNodes, anAffected;
+  listOfGroupToSet(theElems, aMeshDS, anElems, false );
+  listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
+  listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
+
+  bool aResult = myEditor.DoubleNodes( anElems, aNodes, anAffected );
+
+  storeResult( myEditor) ;
+
+  myMesh->GetMeshDS()->Modified();
+  if ( aResult )
+    myMesh->SetIsModified( true );
+
+  // Update Python script
+  TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", "
+                << &theNodesNot << ", " << &theAffectedElems << " )";
+  return aResult;
+}
+
+//================================================================================
+/*!
+ * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+ * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
+  \param theElems - list of groups of elements (edges or faces) to be replicated
+  \param theNodesNot - list of groups of nodes not to replicated
+  \param theAffectedElems - group of elements to which the replicated nodes
+  should be associated to.
+ * \return a new group with newly created elements
+ * \sa DoubleNodeElemGroups()
+ */
+//================================================================================
+
+SMESH::SMESH_Group_ptr
+SMESH_MeshEditor_i::DoubleNodeElemGroupsNew(const SMESH::ListOfGroups& theElems,
+                                            const SMESH::ListOfGroups& theNodesNot,
+                                            const SMESH::ListOfGroups& theAffectedElems)
+{
+  TPythonDump pyDump;
+  SMESH::ListOfGroups_var twoGroups = DoubleNodeElemGroups2New( theElems,
+                                                                theNodesNot,
+                                                                theAffectedElems,
+                                                                true, false );
+  SMESH::SMESH_GroupBase_var baseGroup = twoGroups[0].in();
+  SMESH::SMESH_Group_var     elemGroup = SMESH::SMESH_Group::_narrow( baseGroup );
+
+  pyDump << elemGroup << " = " << this << ".DoubleNodeElemGroupsNew( "
+         << theElems         << ", "
+         << theNodesNot      << ", "
+         << theAffectedElems << " )";
+
+  return elemGroup._retn();
+}
+
+SMESH::ListOfGroups*
+SMESH_MeshEditor_i::DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
+                                             const SMESH::ListOfGroups& theNodesNot,
+                                             const SMESH::ListOfGroups& theAffectedElems,
+                                             CORBA::Boolean             theElemGroupNeeded,
+                                             CORBA::Boolean             theNodeGroupNeeded)
+{
+  SMESH::SMESH_Group_var aNewElemGroup, aNewNodeGroup;
+  SMESH::ListOfGroups_var aTwoGroups = new SMESH::ListOfGroups();
+  aTwoGroups->length( 2 );
+  
+  initData();
+
+
+  SMESHDS_Mesh* aMeshDS = GetMeshDS();
+  TIDSortedElemSet anElems, aNodes, anAffected;
+  listOfGroupToSet(theElems, aMeshDS, anElems, false );
+  listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
+  listOfGroupToSet(theAffectedElems, aMeshDS, anAffected, false );
+
+  bool aResult = myEditor.DoubleNodes( anElems, aNodes, anAffected );
+
+  storeResult( myEditor) ;
+
+  myMesh->GetMeshDS()->Modified();
+  TPythonDump pyDump;
+  if ( aResult )
+  {
+    myMesh->SetIsModified( true );
+
+    // Create group with newly created elements
+    CORBA::String_var elemGroupName = theElems[0]->GetName();
+    string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
+    if ( !myEditor.GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
+    {
+      SMESH::long_array_var anIds = GetLastCreatedElems();
+      SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
+      aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
+      aNewElemGroup->Add(anIds);
+    }
+    if ( !myEditor.GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
+    {
+      SMESH::long_array_var anIds = GetLastCreatedNodes();
+      aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
+      aNewNodeGroup->Add(anIds);
+    }
+  }
+
+  // Update Python script
+
+  pyDump << "[ ";
+  if ( aNewElemGroup->_is_nil() ) pyDump << "nothing, ";
+  else                            pyDump << aNewElemGroup << ", ";
+  if ( aNewNodeGroup->_is_nil() ) pyDump << "nothing ] = ";
+  else                            pyDump << aNewNodeGroup << " ] = ";
+
+  pyDump << this << ".DoubleNodeElemGroups2New( " << &theElems << ", "
+         << &theNodesNot       << ", "
+         << &theAffectedElems  << ", "
+         << theElemGroupNeeded << ", "
+         << theNodeGroupNeeded << " )";
+
+  aTwoGroups[0] = aNewElemGroup._retn();
+  aTwoGroups[1] = aNewNodeGroup._retn();
+  return aTwoGroups._retn();
+}
+
+//================================================================================
+/*!
+  \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+  This method provided for convenience works as DoubleNodes() described above.
+  \param theElems - list of groups of elements (edges or faces) to be replicated
+  \param theNodesNot - list of groups of nodes not to replicated
+  \param theShape - shape to detect affected elements (element which geometric center
+  located on or inside shape).
+  The replicated nodes should be associated to affected elements.
+  \return TRUE if operation has been completed successfully, FALSE otherwise
+  \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
+*/
+//================================================================================
+
+CORBA::Boolean
+SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theElems,
+                                                 const SMESH::ListOfGroups& theNodesNot,
+                                                 GEOM::GEOM_Object_ptr      theShape )
+{
+  initData();
+
+
+  SMESHDS_Mesh* aMeshDS = GetMeshDS();
+  TIDSortedElemSet anElems, aNodes;
+  listOfGroupToSet(theElems, aMeshDS, anElems,false );
+  listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true );
+
+  TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape );
+  bool aResult = myEditor.DoubleNodesInRegion( anElems, aNodes, aShape );
+
+  storeResult( myEditor) ;
+
+  myMesh->GetMeshDS()->Modified();
+  if ( aResult )
+    myMesh->SetIsModified( true );
+
+  // Update Python script
+  TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", "
+                << &theNodesNot << ", " << theShape << " )";
+  return aResult;
+}
+
+//================================================================================
+/*!
+  \brief Generated skin mesh (containing 2D cells) from 3D mesh
+   The created 2D mesh elements based on nodes of free faces of boundary volumes
+  \return TRUE if operation has been completed successfully, FALSE otherwise
+*/
+//================================================================================
+
+CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
+{
+  initData();
+
+  bool aResult = myEditor.Make2DMeshFrom3D();
+  storeResult( myEditor) ;
+  myMesh->GetMeshDS()->Modified();
+  TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
+  return aResult;
+}
+
+//================================================================================
+/*!
+ * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
+ * The list of groups must describe a partition of the mesh volumes.
+ * The nodes of the internal faces at the boundaries of the groups are doubled.
+ * In option, the internal faces are replaced by flat elements.
+ * Triangles are transformed in prisms, and quadrangles in hexahedrons.
+ * The flat elements are stored in groups of volumes.
+ * @param theDomains - list of groups of volumes
+ * @param createJointElems - if TRUE, create the elements
+ * @return TRUE if operation has been completed successfully, FALSE otherwise
+ */
+//================================================================================
+
+CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
+                                                                 CORBA::Boolean createJointElems )
+  throw (SALOME::SALOME_Exception)
+{
+  initData();
+
+
+  SMESHDS_Mesh* aMeshDS = GetMeshDS();
+
+  vector<TIDSortedElemSet> domains;
+  domains.clear();
+
+  for ( int i = 0, n = theDomains.length(); i < n; i++ )
+  {
+    SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
+    if ( !CORBA::is_nil( aGrp ) /*&& ( aGrp->GetType() != SMESH::NODE )*/ )
+    {
+//      if ( aGrp->GetType() != SMESH::VOLUME )
+//        THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
+      TIDSortedElemSet domain;
+      domain.clear();
+      domains.push_back(domain);
+      SMESH::long_array_var anIDs = aGrp->GetIDs();
+      arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
+    }
+  }
+
+  bool aResult = myEditor.DoubleNodesOnGroupBoundaries( domains, createJointElems );
+  // TODO publish the groups of flat elements in study
+
+  storeResult( myEditor) ;
+  myMesh->GetMeshDS()->Modified();
+
+  // Update Python script
+  TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
+      << ", " << createJointElems << " )";
+  return aResult;
+}
+
+//================================================================================
+/*!
+ * \brief Double nodes on some external faces and create flat elements.
+ * Flat elements are mainly used by some types of mechanic calculations.
+ *
+ * Each group of the list must be constituted of faces.
+ * Triangles are transformed in prisms, and quadrangles in hexahedrons.
+ * @param theGroupsOfFaces - list of groups of faces
+ * @return TRUE if operation has been completed successfully, FALSE otherwise
+ */
+//================================================================================
+
+CORBA::Boolean SMESH_MeshEditor_i::CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces )
+{
+  initData();
+
+
+  SMESHDS_Mesh* aMeshDS = GetMeshDS();
+
+  vector<TIDSortedElemSet> faceGroups;
+  faceGroups.clear();
+
+  for ( int i = 0, n = theGroupsOfFaces.length(); i < n; i++ )
+  {
+    SMESH::SMESH_GroupBase_var aGrp = theGroupsOfFaces[ i ];
+    if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
+    {
+      TIDSortedElemSet faceGroup;
+      faceGroup.clear();
+      faceGroups.push_back(faceGroup);
+      SMESH::long_array_var anIDs = aGrp->GetIDs();
+      arrayToSet( anIDs, aMeshDS, faceGroups[ i ], SMDSAbs_All );
+    }
+  }
+
+  bool aResult = myEditor.CreateFlatElementsOnFacesGroups( faceGroups );
+  // TODO publish the groups of flat elements in study
 
-  storeResult( aMeshEditor) ;
+  storeResult( myEditor) ;
+  myMesh->GetMeshDS()->Modified();
 
+  // Update Python script
+  TPythonDump() << "isDone = " << this << ".CreateFlatElementsOnFacesGroups( " << &theGroupsOfFaces << " )";
   return aResult;
 }
+
+// issue 20749 ===================================================================
+/*!
+ * \brief Creates missing boundary elements
+ *  \param elements - elements whose boundary is to be checked
+ *  \param dimension - defines type of boundary elements to create
+ *  \param groupName - a name of group to store created boundary elements in,
+ *                     "" means not to create the group
+ *  \param meshName - a name of new mesh to store created boundary elements in,
+ *                     "" means not to create the new mesh
+ *  \param toCopyElements - if true, the checked elements will be copied into the new mesh
+ *  \param toCopyExistingBondary - if true, not only new but also pre-existing
+ *                                boundary elements will be copied into the new mesh
+ *  \param group - returns the create group, if any
+ *  \retval SMESH::SMESH_Mesh - the mesh where elements were added to
+ */
+// ================================================================================
+
+SMESH::SMESH_Mesh_ptr
+SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
+                                     SMESH::Bnd_Dimension      dim,
+                                     const char*               groupName,
+                                     const char*               meshName,
+                                     CORBA::Boolean            toCopyElements,
+                                     CORBA::Boolean            toCopyExistingBondary,
+                                     SMESH::SMESH_Group_out    group)
+{
+  initData();
+
+  if ( dim > SMESH::BND_1DFROM2D )
+    THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
+
+  SMESHDS_Mesh* aMeshDS = GetMeshDS();
+
+  SMESH::SMESH_Mesh_var mesh_var;
+  SMESH::SMESH_Group_var group_var;
+
+  TPythonDump pyDump;
+
+  TIDSortedElemSet elements;
+  SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
+  if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true ))
+  {
+    // mesh to fill in
+    mesh_var =
+      strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this());
+    SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
+    // other mesh
+    SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl();
+
+    // group of new boundary elements
+    SMESH_Group* smesh_group = 0;
+    if ( strlen(groupName) )
+    {
+      group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
+      if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
+        smesh_group = group_i->GetSmeshGroup();
+    }
+
+    // do it
+    myEditor.MakeBoundaryMesh( elements,
+                                  ::SMESH_MeshEditor::Bnd_Dimension(dim),
+                                  smesh_group,
+                                  smesh_mesh,
+                                  toCopyElements,
+                                  toCopyExistingBondary);
+    storeResult( myEditor );
+
+    if ( smesh_mesh )
+      smesh_mesh->GetMeshDS()->Modified();
+  }
+
+  const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
+
+  // result of MakeBoundaryMesh() is a tuple (mesh, group)
+  if ( mesh_var->_is_nil() )
+    pyDump << myMesh_i->_this() << ", ";
+  else
+    pyDump << mesh_var << ", ";
+  if ( group_var->_is_nil() )
+    pyDump << "_NoneGroup = "; // assignment to None is forbiden
+  else
+    pyDump << group_var << " = ";
+  pyDump << this << ".MakeBoundaryMesh( "
+         << idSource << ", "
+         << "SMESH." << dimName[int(dim)] << ", "
+         << "'" << groupName << "', "
+         << "'" << meshName<< "', "
+         << toCopyElements << ", "
+         << toCopyExistingBondary << ")";
+
+  group = group_var._retn();
+  return mesh_var._retn();
+}
+
+//================================================================================
+/*!
+ * \brief Creates missing boundary elements
+ *  \param dimension - defines type of boundary elements to create
+ *  \param groupName - a name of group to store all boundary elements in,
+ *    "" means not to create the group
+ *  \param meshName - a name of a new mesh, which is a copy of the initial 
+ *    mesh + created boundary elements; "" means not to create the new mesh
+ *  \param toCopyAll - if true, the whole initial mesh will be copied into
+ *    the new mesh else only boundary elements will be copied into the new mesh
+ *  \param groups - optional groups of elements to make boundary around
+ *  \param mesh - returns the mesh where elements were added to
+ *  \param group - returns the created group, if any
+ *  \retval long - number of added boundary elements
+ */
+//================================================================================
+
+CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
+                                                     const char* groupName,
+                                                     const char* meshName,
+                                                     CORBA::Boolean toCopyAll,
+                                                     const SMESH::ListOfIDSources& groups,
+                                                     SMESH::SMESH_Mesh_out mesh,
+                                                     SMESH::SMESH_Group_out group)
+  throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+
+  initData();
+
+  if ( dim > SMESH::BND_1DFROM2D )
+    THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
+
+  // separate groups belonging to this and other mesh
+  SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
+  SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
+  groupsOfThisMesh->length( groups.length() );
+  groupsOfOtherMesh->length( groups.length() );
+  int nbGroups = 0, nbGroupsOfOtherMesh = 0;
+  for ( int i = 0; i < groups.length(); ++i )
+  {
+    SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
+    if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
+      groupsOfOtherMesh[ nbGroupsOfOtherMesh++ ] = groups[i];
+    else
+      groupsOfThisMesh[ nbGroups++ ] = groups[i];
+    if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
+      THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
+  }
+  groupsOfThisMesh->length( nbGroups );
+  groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
+
+  int nbAdded = 0;
+  TPythonDump pyDump;
+
+  if ( nbGroupsOfOtherMesh > 0 )
+  {
+    // process groups belonging to another mesh
+    SMESH::SMESH_Mesh_var    otherMesh = groupsOfOtherMesh[0]->GetMesh();
+    SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
+    nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
+                                             groupsOfOtherMesh, mesh, group );
+  }
+
+  SMESH::SMESH_Mesh_var mesh_var;
+  SMESH::SMESH_Group_var group_var;
+
+  // get mesh to fill
+  mesh_var = SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
+  const bool toCopyMesh = ( strlen( meshName ) > 0 );
+  if ( toCopyMesh )
+  {
+    if ( toCopyAll )
+      mesh_var = SMESH_Gen_i::GetSMESHGen()->CopyMesh(mesh_var,
+                                                      meshName,
+                                                      /*toCopyGroups=*/false,
+                                                      /*toKeepIDs=*/true);
+    else
+      mesh_var = makeMesh(meshName);
+  }
+  SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
+  SMESH_Mesh*  tgtMesh = &mesh_i->GetImpl();
+
+  // source mesh
+  SMESH_Mesh*     srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
+  SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
+
+  // group of boundary elements
+  SMESH_Group* smesh_group = 0;
+  SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
+  if ( strlen(groupName) )
+  {
+    SMESH::ElementType groupType = SMESH::ElementType( int(elemType)-1 );
+    group_var = mesh_i->CreateGroup( groupType, groupName );
+    if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
+      smesh_group = group_i->GetSmeshGroup();
+  }
+
+  TIDSortedElemSet elements;
+
+  if ( groups.length() > 0 )
+  {
+    for ( int i = 0; i < nbGroups; ++i )
+    {
+      elements.clear();
+      if ( idSourceToSet( groupsOfThisMesh[i], srcMeshDS, elements, elemType,/*emptyIfIsMesh=*/0 ))
+      {
+        SMESH::Bnd_Dimension bdim = 
+          ( elemType == SMDSAbs_Volume ) ? SMESH::BND_2DFROM3D : SMESH::BND_1DFROM2D;
+        nbAdded += myEditor.MakeBoundaryMesh( elements,
+                                                 ::SMESH_MeshEditor::Bnd_Dimension(bdim),
+                                                 smesh_group,
+                                                 tgtMesh,
+                                                 /*toCopyElements=*/false,
+                                                 /*toCopyExistingBondary=*/srcMesh != tgtMesh,
+                                                 /*toAddExistingBondary=*/true,
+                                                 /*aroundElements=*/true);
+        storeResult( myEditor );
+      }
+    }
+  }
+  else
+  {
+    nbAdded += myEditor.MakeBoundaryMesh( elements,
+                                             ::SMESH_MeshEditor::Bnd_Dimension(dim),
+                                             smesh_group,
+                                             tgtMesh,
+                                             /*toCopyElements=*/false,
+                                             /*toCopyExistingBondary=*/srcMesh != tgtMesh,
+                                             /*toAddExistingBondary=*/true);
+    storeResult( myEditor );
+  }
+  tgtMesh->GetMeshDS()->Modified();
+
+  const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
+
+  // result of MakeBoundaryElements() is a tuple (nb, mesh, group)
+  pyDump << "nbAdded, ";
+  if ( mesh_var->_is_nil() )
+    pyDump << myMesh_i->_this() << ", ";
+  else
+    pyDump << mesh_var << ", ";
+  if ( group_var->_is_nil() )
+    pyDump << "_NoneGroup = "; // assignment to None is forbiden
+  else
+    pyDump << group_var << " = ";
+  pyDump << this << ".MakeBoundaryElements( "
+         << "SMESH." << dimName[int(dim)] << ", "
+         << "'" << groupName << "', "
+         << "'" << meshName<< "', "
+         << toCopyAll << ", "
+         << groups << ")";
+
+  mesh  = mesh_var._retn();
+  group = group_var._retn();
+  return nbAdded;
+}
index b127f2f895ba3de638ae435a89ed95adafbe21fa..15233798bb907aad3d7f598c4d1a0de3ae4b997b 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : SMESH_MeshEditor_i.hxx
 //  Author : Nicolas REJNERI
@@ -34,6 +35,7 @@
 
 #include "SMESH_Mesh.hxx"
 #include "SMESH_PythonDump.hxx"
+#include "SMESH_MeshEditor.hxx"
 #include <list>
 
 class SMESH_MeshEditor;
@@ -41,20 +43,30 @@ class SMESH_Mesh_i;
 
 class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
 {
- public:
+public:
   SMESH_MeshEditor_i(SMESH_Mesh_i * theMesh, bool isPreview);
 
   virtual ~ SMESH_MeshEditor_i();
 
   // --- CORBA
+
+  /*!
+   * \brief Wrap a sequence of ids in a SMESH_IDSource
+   */
+  SMESH::SMESH_IDSource_ptr MakeIDSource(const SMESH::long_array& IDsOfElements,
+                                         SMESH::ElementType       type);
   CORBA::Boolean RemoveElements(const SMESH::long_array & IDsOfElements);
   CORBA::Boolean RemoveNodes(const SMESH::long_array & IDsOfNodes);
+  CORBA::Long    RemoveOrphanNodes();
 
   /*!
    * Methods for creation new elements.
    * Returns ID of created element or 0 if element not created
    */
   CORBA::Long AddNode(CORBA::Double x, CORBA::Double y, CORBA::Double z);
+  CORBA::Long Add0DElement(CORBA::Long IDOfNode);
+  CORBA::Long AddBall(CORBA::Long IDOfNodem, CORBA::Double diameter)
+    throw (SALOME::SALOME_Exception);
   CORBA::Long AddEdge(const SMESH::long_array & IDsOfNodes);
   CORBA::Long AddFace(const SMESH::long_array & IDsOfNodes);
   CORBA::Long AddPolygonalFace(const SMESH::long_array & IDsOfNodes);
@@ -112,6 +124,19 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
   CORBA::Boolean DeleteDiag(CORBA::Long NodeID1, CORBA::Long NodeID2);
   CORBA::Boolean Reorient(const SMESH::long_array & IDsOfElements);
   CORBA::Boolean ReorientObject(SMESH::SMESH_IDSource_ptr theObject);
+  /*!
+   * \brief Reorient faces contained in \a the2Dgroup.
+   * \param the2Dgroup - the mesh or its part to reorient
+   * \param theDirection - desired direction of normal of \a theFace
+   * \param theFace - ID of face whose orientation is checked.
+   *        It can be < 1 then \a thePoint is used to find a face.
+   * \param thePoint - is used to find a face if \a theFace < 1.
+   * \return number of reoriented elements.
+   */
+  CORBA::Long Reorient2D(SMESH::SMESH_IDSource_ptr the2Dgroup,
+                         const SMESH::DirStruct&   theDirection,
+                         CORBA::Long               theFace,
+                         const SMESH::PointStruct& thePoint) throw (SALOME::SALOME_Exception);
 
   // Split/Join faces
   CORBA::Boolean TriToQuad       (const SMESH::long_array &   IDsOfElements,
@@ -130,6 +155,8 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
                                   CORBA::Boolean              Diag13);
   CORBA::Long    BestSplit       (CORBA::Long                 IDOfQuad,
                                   SMESH::NumericalFunctor_ptr Criterion);
+  void SplitVolumesIntoTetra     (SMESH::SMESH_IDSource_ptr elems,
+                                  CORBA::Short methodFlags) throw (SALOME::SALOME_Exception);
 
   CORBA::Boolean Smooth(const SMESH::long_array &              IDsOfElements,
                         const SMESH::long_array &              IDsOfFixedNodes,
@@ -137,10 +164,10 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
                         CORBA::Double                          MaxAspectRatio,
                         SMESH::SMESH_MeshEditor::Smooth_Method Method);
   CORBA::Boolean SmoothObject(SMESH::SMESH_IDSource_ptr              theObject,
-                             const SMESH::long_array &              IDsOfFixedNodes,
-                             CORBA::Long                            MaxNbOfIterations,
-                             CORBA::Double                          MaxAspectRatio,
-                             SMESH::SMESH_MeshEditor::Smooth_Method Method);
+                              const SMESH::long_array &              IDsOfFixedNodes,
+                              CORBA::Long                            MaxNbOfIterations,
+                              CORBA::Double                          MaxAspectRatio,
+                              SMESH::SMESH_MeshEditor::Smooth_Method Method);
   CORBA::Boolean SmoothParametric(const SMESH::long_array &              IDsOfElements,
                                   const SMESH::long_array &              IDsOfFixedNodes,
                                   CORBA::Long                            MaxNbOfIterations,
@@ -158,15 +185,20 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
                         SMESH::SMESH_MeshEditor::Smooth_Method Method,
                         bool                                   IsParametric);
   CORBA::Boolean smoothObject(SMESH::SMESH_IDSource_ptr              theObject,
-                             const SMESH::long_array &              IDsOfFixedNodes,
-                             CORBA::Long                            MaxNbOfIterations,
-                             CORBA::Double                          MaxAspectRatio,
-                             SMESH::SMESH_MeshEditor::Smooth_Method Method,
+                              const SMESH::long_array &              IDsOfFixedNodes,
+                              CORBA::Long                            MaxNbOfIterations,
+                              CORBA::Double                          MaxAspectRatio,
+                              SMESH::SMESH_MeshEditor::Smooth_Method Method,
                               bool                                   IsParametric);
 
 
   void ConvertToQuadratic(CORBA::Boolean Force3d);
   CORBA::Boolean ConvertFromQuadratic();
+  void ConvertToQuadraticObject(CORBA::Boolean            theForce3d,
+                                SMESH::SMESH_IDSource_ptr theObject)
+    throw (SALOME::SALOME_Exception);
+  void ConvertFromQuadraticObject(SMESH::SMESH_IDSource_ptr theObject)
+    throw (SALOME::SALOME_Exception);
 
   void RenumberNodes();
   void RenumberElements();
@@ -177,27 +209,35 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
                      CORBA::Long               NbOfSteps,
                      CORBA::Double             Tolerance);
   void RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject,
-                          const SMESH::AxisStruct & Axis,
-                          CORBA::Double             AngleInRadians,
-                          CORBA::Long               NbOfSteps,
-                          CORBA::Double             Tolerance);
+                           const SMESH::AxisStruct & Axis,
+                           CORBA::Double             AngleInRadians,
+                           CORBA::Long               NbOfSteps,
+                           CORBA::Double             Tolerance);
   void RotationSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
-                            const SMESH::AxisStruct & Axis,
-                            CORBA::Double             AngleInRadians,
-                            CORBA::Long               NbOfSteps,
-                            CORBA::Double             Tolerance);
+                             const SMESH::AxisStruct & Axis,
+                             CORBA::Double             AngleInRadians,
+                             CORBA::Long               NbOfSteps,
+                             CORBA::Double             Tolerance);
   void RotationSweepObject2D(SMESH::SMESH_IDSource_ptr theObject,
-                            const SMESH::AxisStruct & Axis,
-                            CORBA::Double             AngleInRadians,
-                            CORBA::Long               NbOfSteps,
-                            CORBA::Double             Tolerance);
+                             const SMESH::AxisStruct & Axis,
+                             CORBA::Double             AngleInRadians,
+                             CORBA::Long               NbOfSteps,
+                             CORBA::Double             Tolerance);
 
   void ExtrusionSweep(const SMESH::long_array & IDsOfElements,
                       const SMESH::DirStruct &  StepVector,
                       CORBA::Long               NbOfSteps);
+  void ExtrusionSweep0D(const SMESH::long_array & IDsOfElements,
+                      const SMESH::DirStruct &  StepVector,
+                      CORBA::Long               NbOfSteps);
+
   void ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObject,
-                           const SMESH::DirStruct &  StepVector,
-                           CORBA::Long               NbOfSteps);
+                            const SMESH::DirStruct &  StepVector,
+                            CORBA::Long               NbOfSteps);
+
+  void ExtrusionSweepObject0D(SMESH::SMESH_IDSource_ptr theObject,
+                              const SMESH::DirStruct &  StepVector,
+                              CORBA::Long               NbOfSteps);
   void ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObject,
                               const SMESH::DirStruct &  StepVector,
                               CORBA::Long               NbOfSteps);
@@ -205,23 +245,32 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
                               const SMESH::DirStruct &  StepVector,
                               CORBA::Long               NbOfSteps);
   void AdvancedExtrusion(const SMESH::long_array & theIDsOfElements,
-                        const SMESH::DirStruct &  theStepVector,
-                        CORBA::Long               theNbOfSteps,
-                        CORBA::Long               theExtrFlags,
-                        CORBA::Double             theSewTolerance);
+                         const SMESH::DirStruct &  theStepVector,
+                         CORBA::Long               theNbOfSteps,
+                         CORBA::Long               theExtrFlags,
+                         CORBA::Double             theSewTolerance);
 
   SMESH::SMESH_MeshEditor::Extrusion_Error
-    ExtrusionAlongPath(const SMESH::long_array &   IDsOfElements,
-                       SMESH::SMESH_Mesh_ptr       PathMesh,
-                       GEOM::GEOM_Object_ptr       PathShape,
-                       CORBA::Long                 NodeStart,
-                       CORBA::Boolean              HasAngles,
-                       const SMESH::double_array & Angles,
-                       CORBA::Boolean              HasRefPoint,
-                       const SMESH::PointStruct &  RefPoint);
+  ExtrusionAlongPath(const SMESH::long_array &   IDsOfElements,
+                     SMESH::SMESH_Mesh_ptr       PathMesh,
+                     GEOM::GEOM_Object_ptr       PathShape,
+                     CORBA::Long                 NodeStart,
+                     CORBA::Boolean              HasAngles,
+                     const SMESH::double_array & Angles,
+                     CORBA::Boolean              HasRefPoint,
+                     const SMESH::PointStruct &  RefPoint);
 
   SMESH::SMESH_MeshEditor::Extrusion_Error
-    ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr   theObject,
+  ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr   theObject,
+                           SMESH::SMESH_Mesh_ptr       PathMesh,
+                           GEOM::GEOM_Object_ptr       PathShape,
+                           CORBA::Long                 NodeStart,
+                           CORBA::Boolean              HasAngles,
+                           const SMESH::double_array & Angles,
+                           CORBA::Boolean              HasRefPoint,
+                           const SMESH::PointStruct &  RefPoint);
+  SMESH::SMESH_MeshEditor::Extrusion_Error
+  ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr   theObject,
                              SMESH::SMESH_Mesh_ptr       PathMesh,
                              GEOM::GEOM_Object_ptr       PathShape,
                              CORBA::Long                 NodeStart,
@@ -230,23 +279,14 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
                              CORBA::Boolean              HasRefPoint,
                              const SMESH::PointStruct &  RefPoint);
   SMESH::SMESH_MeshEditor::Extrusion_Error
-    ExtrusionAlongPathObject1D(SMESH::SMESH_IDSource_ptr   theObject,
-                              SMESH::SMESH_Mesh_ptr       PathMesh,
-                              GEOM::GEOM_Object_ptr       PathShape,
-                              CORBA::Long                 NodeStart,
-                              CORBA::Boolean              HasAngles,
-                              const SMESH::double_array & Angles,
-                              CORBA::Boolean              HasRefPoint,
-                              const SMESH::PointStruct &  RefPoint);
-  SMESH::SMESH_MeshEditor::Extrusion_Error
-    ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr   theObject,
-                              SMESH::SMESH_Mesh_ptr       PathMesh,
-                              GEOM::GEOM_Object_ptr       PathShape,
-                              CORBA::Long                 NodeStart,
-                              CORBA::Boolean              HasAngles,
-                              const SMESH::double_array & Angles,
-                              CORBA::Boolean              HasRefPoint,
-                              const SMESH::PointStruct &  RefPoint);
+  ExtrusionAlongPathObject2D(SMESH::SMESH_IDSource_ptr   theObject,
+                             SMESH::SMESH_Mesh_ptr       PathMesh,
+                             GEOM::GEOM_Object_ptr       PathShape,
+                             CORBA::Long                 NodeStart,
+                             CORBA::Boolean              HasAngles,
+                             const SMESH::double_array & Angles,
+                             CORBA::Boolean              HasRefPoint,
+                             const SMESH::PointStruct &  RefPoint);
 
   SMESH::double_array* LinearAnglesVariation(SMESH::SMESH_Mesh_ptr       PathMesh,
                                              GEOM::GEOM_Object_ptr       PathShape,
@@ -257,23 +297,23 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
               SMESH::SMESH_MeshEditor::MirrorType MirrorType,
               CORBA::Boolean                      Copy);
   void MirrorObject(SMESH::SMESH_IDSource_ptr           theObject,
-                   const SMESH::AxisStruct &           Axis,
-                   SMESH::SMESH_MeshEditor::MirrorType MirrorType,
-                   CORBA::Boolean                      Copy);
+                    const SMESH::AxisStruct &           Axis,
+                    SMESH::SMESH_MeshEditor::MirrorType MirrorType,
+                    CORBA::Boolean                      Copy);
   void Translate(const SMESH::long_array & IDsOfElements,
                  const SMESH::DirStruct &   Vector,
                  CORBA::Boolean            Copy);
   void TranslateObject(SMESH::SMESH_IDSource_ptr  theObject,
-                      const SMESH::DirStruct &   Vector,
-                      CORBA::Boolean             Copy);
+                       const SMESH::DirStruct &   Vector,
+                       CORBA::Boolean             Copy);
   void Rotate(const SMESH::long_array & IDsOfElements,
               const SMESH::AxisStruct &  Axis,
               CORBA::Double             Angle,
               CORBA::Boolean            Copy);
   void RotateObject(SMESH::SMESH_IDSource_ptr  theObject,
-                   const SMESH::AxisStruct &  Axis,
-                   CORBA::Double              Angle,
-                   CORBA::Boolean             Copy);
+                    const SMESH::AxisStruct &  Axis,
+                    CORBA::Double              Angle,
+                    CORBA::Boolean             Copy);
 
   SMESH::ListOfGroups* RotationSweepMakeGroups(const SMESH::long_array& IDsOfElements,
                                                const SMESH::AxisStruct& Axix,
@@ -286,18 +326,22 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
                                                      CORBA::Long               NbOfSteps,
                                                      CORBA::Double             Tolerance);
   SMESH::ListOfGroups* RotationSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr Object,
-                                                      const SMESH::AxisStruct&  Axix,
-                                                      CORBA::Double             AngleInRadians,
-                                                      CORBA::Long               NbOfSteps,
-                                                      CORBA::Double             Tolerance);
+                                                       const SMESH::AxisStruct&  Axix,
+                                                       CORBA::Double             AngleInRadians,
+                                                       CORBA::Long               NbOfSteps,
+                                                       CORBA::Double             Tolerance);
   SMESH::ListOfGroups* RotationSweepObject2DMakeGroups(SMESH::SMESH_IDSource_ptr Object,
-                                                      const SMESH::AxisStruct&  Axix,
-                                                      CORBA::Double             AngleInRadians,
-                                                      CORBA::Long               NbOfSteps,
-                                                      CORBA::Double             Tolerance);
+                                                       const SMESH::AxisStruct&  Axix,
+                                                       CORBA::Double             AngleInRadians,
+                                                       CORBA::Long               NbOfSteps,
+                                                       CORBA::Double             Tolerance);
   SMESH::ListOfGroups* ExtrusionSweepMakeGroups(const SMESH::long_array& IDsOfElements,
                                                 const SMESH::DirStruct&  StepVector,
                                                 CORBA::Long              NbOfSteps);
+  SMESH::ListOfGroups* ExtrusionSweepMakeGroups0D(const SMESH::long_array& IDsOfElements,
+                                                const SMESH::DirStruct&  StepVector,
+                                                CORBA::Long              NbOfSteps);
+
   SMESH::ListOfGroups* AdvancedExtrusionMakeGroups(const SMESH::long_array& IDsOfElements,
                                                    const SMESH::DirStruct&  StepVector,
                                                    CORBA::Long              NbOfSteps,
@@ -306,6 +350,9 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
   SMESH::ListOfGroups* ExtrusionSweepObjectMakeGroups(SMESH::SMESH_IDSource_ptr Object,
                                                       const SMESH::DirStruct&   StepVector,
                                                       CORBA::Long               NbOfSteps);
+  SMESH::ListOfGroups* ExtrusionSweepObject0DMakeGroups(SMESH::SMESH_IDSource_ptr Object,
+                                                        const SMESH::DirStruct&   StepVector,
+                                                        CORBA::Long               NbOfSteps);
   SMESH::ListOfGroups* ExtrusionSweepObject1DMakeGroups(SMESH::SMESH_IDSource_ptr Object,
                                                         const SMESH::DirStruct&   StepVector,
                                                         CORBA::Long               NbOfSteps);
@@ -331,23 +378,48 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
                                                           const SMESH::PointStruct&  RefPoint,
                                                           SMESH::SMESH_MeshEditor::Extrusion_Error& Error);
   SMESH::ListOfGroups* ExtrusionAlongPathObject1DMakeGroups(SMESH::SMESH_IDSource_ptr  Object,
-                                                           SMESH::SMESH_Mesh_ptr      PathMesh,
-                                                           GEOM::GEOM_Object_ptr      PathShape,
-                                                           CORBA::Long                NodeStart,
-                                                           CORBA::Boolean             HasAngles,
-                                                           const SMESH::double_array& Angles,
-                                                           CORBA::Boolean             HasRefPoint,
-                                                           const SMESH::PointStruct&  RefPoint,
-                                                           SMESH::SMESH_MeshEditor::Extrusion_Error& Error);
+                                                            SMESH::SMESH_Mesh_ptr      PathMesh,
+                                                            GEOM::GEOM_Object_ptr      PathShape,
+                                                            CORBA::Long                NodeStart,
+                                                            CORBA::Boolean             HasAngles,
+                                                            const SMESH::double_array& Angles,
+                                                            CORBA::Boolean             HasRefPoint,
+                                                            const SMESH::PointStruct&  RefPoint,
+                                                            SMESH::SMESH_MeshEditor::Extrusion_Error& Error);
   SMESH::ListOfGroups* ExtrusionAlongPathObject2DMakeGroups(SMESH::SMESH_IDSource_ptr  Object,
-                                                           SMESH::SMESH_Mesh_ptr      PathMesh,
-                                                           GEOM::GEOM_Object_ptr      PathShape,
-                                                           CORBA::Long                NodeStart,
-                                                           CORBA::Boolean             HasAngles,
-                                                           const SMESH::double_array& Angles,
-                                                           CORBA::Boolean             HasRefPoint,
-                                                           const SMESH::PointStruct&  RefPoint,
-                                                           SMESH::SMESH_MeshEditor::Extrusion_Error& Error);
+                                                            SMESH::SMESH_Mesh_ptr      PathMesh,
+                                                            GEOM::GEOM_Object_ptr      PathShape,
+                                                            CORBA::Long                NodeStart,
+                                                            CORBA::Boolean             HasAngles,
+                                                            const SMESH::double_array& Angles,
+                                                            CORBA::Boolean             HasRefPoint,
+                                                            const SMESH::PointStruct&  RefPoint,
+                                                            SMESH::SMESH_MeshEditor::Extrusion_Error& Error);
+
+  // skl 04.06.2009 
+  SMESH::ListOfGroups* ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr  Object,
+                                              SMESH::SMESH_IDSource_ptr  Path,
+                                              CORBA::Long                NodeStart,
+                                              CORBA::Boolean             HasAngles,
+                                              const SMESH::double_array& Angles,
+                                              CORBA::Boolean             LinearVariation,
+                                              CORBA::Boolean             HasRefPoint,
+                                              const SMESH::PointStruct&  RefPoint,
+                                              CORBA::Boolean             MakeGroups,
+                                              SMESH::ElementType         ElemType,
+                                              SMESH::SMESH_MeshEditor::Extrusion_Error& Error);
+  SMESH::ListOfGroups* ExtrusionAlongPathX(const SMESH::long_array&   IDsOfElements,
+                                           SMESH::SMESH_IDSource_ptr  Path,
+                                           CORBA::Long                NodeStart,
+                                           CORBA::Boolean             HasAngles,
+                                           const SMESH::double_array& Angles,
+                                           CORBA::Boolean             LinearVariation,
+                                           CORBA::Boolean             HasRefPoint,
+                                           const SMESH::PointStruct&  RefPoint,
+                                           CORBA::Boolean             MakeGroups,
+                                           SMESH::ElementType         ElemType,
+                                           SMESH::SMESH_MeshEditor::Extrusion_Error& Error);
+
   SMESH::ListOfGroups* MirrorMakeGroups(const SMESH::long_array&            IDsOfElements,
                                         const SMESH::AxisStruct&            Mirror,
                                         SMESH::SMESH_MeshEditor::MirrorType MirrorType);
@@ -394,11 +466,30 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
                                              CORBA::Boolean            CopyGroups,
                                              const char*               MeshName);
 
+  void Scale(SMESH::SMESH_IDSource_ptr  theObject,
+             const SMESH::PointStruct&  thePoint,
+             const SMESH::double_array& theScaleFact,
+             CORBA::Boolean             theCopy);
+
+  SMESH::ListOfGroups* ScaleMakeGroups(SMESH::SMESH_IDSource_ptr  theObject,
+                                       const SMESH::PointStruct&  thePoint,
+                                       const SMESH::double_array& theScaleFact);
+
+  SMESH::SMESH_Mesh_ptr ScaleMakeMesh(SMESH::SMESH_IDSource_ptr Object,
+                                      const SMESH::PointStruct& Point,
+                                      const SMESH::double_array& theScaleFact,
+                                      CORBA::Boolean            CopyGroups,
+                                      const char*               MeshName);
+
   void FindCoincidentNodes (CORBA::Double                  Tolerance,
                             SMESH::array_of_long_array_out GroupsOfNodes);
   void FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr      Object,
                                  CORBA::Double                  Tolerance,
                                  SMESH::array_of_long_array_out GroupsOfNodes);
+  void FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr      Object,
+                                    CORBA::Double                  Tolerance,
+                                    SMESH::array_of_long_array_out GroupsOfNodes,
+                                    const SMESH::ListOfIDSources&  ExceptSubMeshOrGroups);
   void MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes);
   void FindEqualElements(SMESH::SMESH_IDSource_ptr      Object,
                          SMESH::array_of_long_array_out GroupsOfElementsID);
@@ -408,8 +499,36 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
                                      CORBA::Double y,
                                      CORBA::Double z,
                                      CORBA::Long   nodeID);
+  /*!
+   * \brief Return ID of node closest to a given point
+   */
+  CORBA::Long FindNodeClosestTo(CORBA::Double x,
+                                CORBA::Double y,
+                                CORBA::Double z);
+  /*!
+   * Return elements of given type where the given point is IN or ON.
+   * 'ALL' type means elements of any type excluding nodes
+   */
+  SMESH::long_array* FindElementsByPoint(CORBA::Double      x,
+                                         CORBA::Double      y,
+                                         CORBA::Double      z,
+                                         SMESH::ElementType type);
+  /*!
+   * Searching among the given elements, return elements of given type 
+   * where the given point is IN or ON.
+   * 'ALL' type means elements of any type excluding nodes
+   */
+  SMESH::long_array* FindAmongElementsByPoint(SMESH::SMESH_IDSource_ptr elements,
+                                              CORBA::Double             x,
+                                              CORBA::Double             y,
+                                              CORBA::Double             z,
+                                              SMESH::ElementType        type);
 
-
+  /*!
+   * Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
+   * TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
+   */
+  CORBA::Short GetPointState(CORBA::Double x, CORBA::Double y, CORBA::Double z);
 
   SMESH::SMESH_MeshEditor::Sew_Error
   SewFreeBorders(CORBA::Long FirstNodeID1,
@@ -448,7 +567,7 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
    * element - returns false
    */
   CORBA::Boolean ChangeElemNodes(CORBA::Long ide, const SMESH::long_array& newIDs);
-  
+
   /*!
    * Return data of mesh edition preview
    */
@@ -470,10 +589,10 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
 
   /*!
    * \brief Return edited mesh ID
-    * \retval int - mesh ID
+   * \retval int - mesh ID
    */
   int GetMeshId() const { return myMesh->GetId(); }
-  
+
   CORBA::Boolean DoubleNodes( const SMESH::long_array& theNodes,
                               const SMESH::long_array& theModifiedElems );
 
@@ -483,8 +602,194 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
   CORBA::Boolean DoubleNodeGroup( SMESH::SMESH_GroupBase_ptr theNodes,
                                   SMESH::SMESH_GroupBase_ptr theModifiedElems );
 
+  /*!
+   * \brief Creates a hole in a mesh by doubling the nodes of some particular elements.
+   * Works as DoubleNodeGroup(), but returns a new group with newly created nodes.
+   * \param theNodes - group of nodes to be doubled.
+   * \param theModifiedElems - group of elements to be updated.
+   * \return a new group with newly created nodes
+   * \sa DoubleNodeGroup()
+   */
+  SMESH::SMESH_Group_ptr DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes,
+                                             SMESH::SMESH_GroupBase_ptr theModifiedElems );
+
   CORBA::Boolean DoubleNodeGroups( const SMESH::ListOfGroups& theNodes,
-                                   const SMESH::ListOfGroups& theModifiedElems);
+                                   const SMESH::ListOfGroups& theModifiedElems );
+
+  SMESH::SMESH_Group_ptr DoubleNodeGroupsNew( const SMESH::ListOfGroups& theNodes,
+                                              const SMESH::ListOfGroups& theModifiedElems );
+
+  /*!
+   * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+   * \param theElems - the list of elements (edges or faces) to be replicated
+   *       The nodes for duplication could be found from these elements
+   * \param theNodesNot - list of nodes to NOT replicate
+   * \param theAffectedElems - the list of elements (cells and edges) to which the 
+   *       replicated nodes should be associated to.
+   * \return TRUE if operation has been completed successfully, FALSE otherwise
+   * \sa DoubleNodeGroup(), DoubleNodeGroups()
+   */
+  CORBA::Boolean DoubleNodeElem( const SMESH::long_array& theElems, 
+                                 const SMESH::long_array& theNodesNot,
+                                 const SMESH::long_array& theAffectedElems );
+
+  /*!
+   * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+   * \param theElems - the list of elements (edges or faces) to be replicated
+   *        The nodes for duplication could be found from these elements
+   * \param theNodesNot - list of nodes to NOT replicate
+   * \param theShape - shape to detect affected elements (element which geometric center
+   *        located on or inside shape).
+   *        The replicated nodes should be associated to affected elements.
+   * \return TRUE if operation has been completed successfully, FALSE otherwise
+   * \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
+   */
+  CORBA::Boolean DoubleNodeElemInRegion( const SMESH::long_array& theElems, 
+                                         const SMESH::long_array& theNodesNot,
+                                         GEOM::GEOM_Object_ptr    theShape );
+
+  /*!
+   * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+   * \param theElems - group of of elements (edges or faces) to be replicated
+   * \param theNodesNot - group of nodes not to replicated
+   * \param theAffectedElems - group of elements to which the replicated nodes
+   *        should be associated to.
+   * \return TRUE if operation has been completed successfully, FALSE otherwise
+   * \sa DoubleNodes(), DoubleNodeGroups(), DoubleNodeElemGroupNew()
+   */
+  CORBA::Boolean DoubleNodeElemGroup( SMESH::SMESH_GroupBase_ptr theElems,
+                                      SMESH::SMESH_GroupBase_ptr theNodesNot,
+                                      SMESH::SMESH_GroupBase_ptr theAffectedElems );
+
+  /*!
+   * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+   * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements.
+   * \param theElems - group of of elements (edges or faces) to be replicated
+   * \param theNodesNot - group of nodes not to replicated
+   * \param theAffectedElems - group of elements to which the replicated nodes
+   *        should be associated to.
+   * \return a new group with newly created elements
+   * \sa DoubleNodeElemGroup()
+   */
+  SMESH::SMESH_Group_ptr DoubleNodeElemGroupNew( SMESH::SMESH_GroupBase_ptr theElems,
+                                                 SMESH::SMESH_GroupBase_ptr theNodesNot,
+                                                 SMESH::SMESH_GroupBase_ptr theAffectedElems );
+
+  SMESH::ListOfGroups*   DoubleNodeElemGroup2New(SMESH::SMESH_GroupBase_ptr theElems,
+                                                 SMESH::SMESH_GroupBase_ptr theNodesNot,
+                                                 SMESH::SMESH_GroupBase_ptr theAffectedElems,
+                                                 CORBA::Boolean             theElemGroupNeeded,
+                                                 CORBA::Boolean             theNodeGroupNeeded);
+  
+  /*!
+   * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+   * \param theElems - group of of elements (edges or faces) to be replicated
+   * \param theNodesNot - group of nodes not to replicated
+   * \param theShape - shape to detect affected elements (element which geometric center
+   *        located on or inside shape).
+   *        The replicated nodes should be associated to affected elements.
+   * \return TRUE if operation has been completed successfully, FALSE otherwise
+   * \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
+   */
+  CORBA::Boolean DoubleNodeElemGroupInRegion( SMESH::SMESH_GroupBase_ptr theElems,
+                                              SMESH::SMESH_GroupBase_ptr theNodesNot,
+                                              GEOM::GEOM_Object_ptr      theShape );
+
+  /*!
+   * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+   * This method provided for convenience works as DoubleNodes() described above.
+   * \param theElems - list of groups of elements (edges or faces) to be replicated
+   * \param theNodesNot - list of groups of nodes not to replicated
+   * \param theAffectedElems - group of elements to which the replicated nodes
+   *        should be associated to.
+   * \return TRUE if operation has been completed successfully, FALSE otherwise
+   * \sa DoubleNodeGroup(), DoubleNodes(), DoubleNodeElemGroupsNew()
+   */
+  CORBA::Boolean DoubleNodeElemGroups( const SMESH::ListOfGroups& theElems,
+                                       const SMESH::ListOfGroups& theNodesNot,
+                                       const SMESH::ListOfGroups& theAffectedElems );
+
+  /*!
+   * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+   * Works as DoubleNodeElemGroups(), but returns a new group with newly created elements.
+   * \param theElems - list of groups of elements (edges or faces) to be replicated
+   * \param theNodesNot - list of groups of nodes not to replicated
+   * \param theAffectedElems - group of elements to which the replicated nodes
+   *        should be associated to.
+   * \return a new group with newly created elements
+   * \sa DoubleNodeElemGroups()
+   */
+  SMESH::SMESH_Group_ptr DoubleNodeElemGroupsNew( const SMESH::ListOfGroups& theElems,
+                                                  const SMESH::ListOfGroups& theNodesNot,
+                                                  const SMESH::ListOfGroups& theAffectedElems );
+
+  SMESH::ListOfGroups*   DoubleNodeElemGroups2New(const SMESH::ListOfGroups& theElems,
+                                                  const SMESH::ListOfGroups& theNodesNot,
+                                                  const SMESH::ListOfGroups& theAffectedElems,
+                                                  CORBA::Boolean             theElemGroupNeeded,
+                                                  CORBA::Boolean             theNodeGroupNeeded);
+
+  /*!
+   * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
+   * This method provided for convenience works as DoubleNodes() described above.
+   * \param theElems - list of groups of elements (edges or faces) to be replicated
+   * \param theNodesNot - list of groups of nodes not to replicated
+   * \param theShape - shape to detect affected elements (element which geometric center
+   *        located on or inside shape).
+   *        The replicated nodes should be associated to affected elements.
+   * \return TRUE if operation has been completed successfully, FALSE otherwise
+   * \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
+   */
+  CORBA::Boolean DoubleNodeElemGroupsInRegion( const SMESH::ListOfGroups& theElems,
+                                               const SMESH::ListOfGroups& theNodesNot,
+                                               GEOM::GEOM_Object_ptr      theShape );
+  /*!
+   * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
+   * The list of groups must describe a partition of the mesh volumes.
+   * The nodes of the internal faces at the boundaries of the groups are doubled.
+   * In option, the internal faces are replaced by flat elements.
+   * Triangles are transformed in prisms, and quadrangles in hexahedrons.
+   * @param theDomains - list of groups of volumes
+   * @param createJointElems - if TRUE, create the elements
+   * @return TRUE if operation has been completed successfully, FALSE otherwise
+   */
+  CORBA::Boolean DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
+                                               CORBA::Boolean createJointElems )
+    throw (SALOME::SALOME_Exception);
+  /*!
+   * \brief Double nodes on some external faces and create flat elements.
+   * Flat elements are mainly used by some types of mechanic calculations.
+   *
+   * Each group of the list must be constituted of faces.
+   * Triangles are transformed in prisms, and quadrangles in hexahedrons.
+   * @param theGroupsOfFaces - list of groups of faces
+   * @return TRUE if operation has been completed successfully, FALSE otherwise
+   */
+  CORBA::Boolean CreateFlatElementsOnFacesGroups( const SMESH::ListOfGroups& theGroupsOfFaces );
+
+  /*!
+   * \brief Generated skin mesh (containing 2D cells) from 3D mesh
+   * The created 2D mesh elements based on nodes of free faces of boundary volumes
+   * \return TRUE if operation has been completed successfully, FALSE otherwise
+   */
+  CORBA::Boolean Make2DMeshFrom3D();
+
+  SMESH::SMESH_Mesh_ptr MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr elements,
+                                         SMESH::Bnd_Dimension      dimension,
+                                         const char*               groupName,
+                                         const char*               meshName,
+                                         CORBA::Boolean            toCopyElements,
+                                         CORBA::Boolean            toCopyMissingBondary,
+                                         SMESH::SMESH_Group_out    group);
+
+  CORBA::Long MakeBoundaryElements(SMESH::Bnd_Dimension dimension,
+                                   const char* groupName,
+                                   const char* meshName,
+                                   CORBA::Boolean toCopyAll,
+                                   const SMESH::ListOfIDSources& groups,
+                                   SMESH::SMESH_Mesh_out mesh,
+                                   SMESH::SMESH_Group_out group)
+    throw (SALOME::SALOME_Exception);
 
 private: //!< private methods
 
@@ -492,13 +797,13 @@ private: //!< private methods
 
   /*!
    * \brief Update myLastCreated* or myPreviewData
-    * \param anEditor - it contains edition results
+   * \param anEditor - it contains edition results
    */
   void storeResult(::SMESH_MeshEditor& anEditor);
   /*!
    * \brief Clear myLastCreated* or myPreviewData
    */
-  void initData();
+  void initData(bool deleteSearchers=true);
 
   /*!
    * \brief Return groups by their IDs
@@ -511,11 +816,11 @@ private: //!< private methods
                                      CORBA::Long               NbOfSteps,
                                      CORBA::Double             Tolerance,
                                      const bool                MakeGroups,
-                                    const SMDSAbs_ElementType ElementType=SMDSAbs_All);
+                                     const SMDSAbs_ElementType ElementType=SMDSAbs_All);
   SMESH::ListOfGroups* extrusionSweep(const SMESH::long_array & IDsOfElements,
                                       const SMESH::DirStruct &  StepVector,
                                       CORBA::Long               NbOfSteps,
-                                      const bool                MakeGroups,
+                                      bool                      MakeGroups,
                                       const SMDSAbs_ElementType ElementType=SMDSAbs_All);
   SMESH::ListOfGroups* advancedExtrusion(const SMESH::long_array & theIDsOfElements,
                                          const SMESH::DirStruct &  theStepVector,
@@ -533,37 +838,55 @@ private: //!< private methods
                                           const SMESH::PointStruct &  RefPoint,
                                           const bool                  MakeGroups,
                                           SMESH::SMESH_MeshEditor::Extrusion_Error & Error,
-                                         const SMDSAbs_ElementType   ElementType=SMDSAbs_All);
-  SMESH::ListOfGroups* mirror(const SMESH::long_array &           IDsOfElements,
+                                          const SMDSAbs_ElementType   ElementType=SMDSAbs_All);
+  SMESH::ListOfGroups* extrusionAlongPathX(const SMESH::long_array &  IDsOfElements,
+                                           SMESH::SMESH_IDSource_ptr  Path,
+                                           CORBA::Long                NodeStart,
+                                           CORBA::Boolean             HasAngles,
+                                           const SMESH::double_array& Angles,
+                                           CORBA::Boolean             LinearVariation,
+                                           CORBA::Boolean             HasRefPoint,
+                                           const SMESH::PointStruct&  RefPoint,
+                                           bool                       MakeGroups,
+                                           const SMDSAbs_ElementType  ElementType,
+                                           SMESH::SMESH_MeshEditor::Extrusion_Error & theError);
+  SMESH::ListOfGroups* mirror(TIDSortedElemSet &                  IDsOfElements,
                               const SMESH::AxisStruct &           Axis,
                               SMESH::SMESH_MeshEditor::MirrorType MirrorType,
                               CORBA::Boolean                      Copy,
-                              const bool                          MakeGroups,
+                              bool                                MakeGroups,
                               ::SMESH_Mesh*                       TargetMesh=0);
-  SMESH::ListOfGroups* translate(const SMESH::long_array & IDsOfElements,
+  SMESH::ListOfGroups* translate(TIDSortedElemSet        & IDsOfElements,
                                  const SMESH::DirStruct &  Vector,
                                  CORBA::Boolean            Copy,
-                                 const bool                MakeGroups,
+                                 bool                      MakeGroups,
                                  ::SMESH_Mesh*             TargetMesh=0);
-  SMESH::ListOfGroups* rotate(const SMESH::long_array & IDsOfElements,
+  SMESH::ListOfGroups* rotate(TIDSortedElemSet &           IDsOfElements,
                               const SMESH::AxisStruct &  Axis,
                               CORBA::Double             Angle,
                               CORBA::Boolean            Copy,
-                              const bool                MakeGroups,
+                              bool                      MakeGroups,
                               ::SMESH_Mesh*             TargetMesh=0);
 
+  SMESH::ListOfGroups* scale(SMESH::SMESH_IDSource_ptr   theObject,
+                             const SMESH::PointStruct&   thePoint,
+                             const SMESH::double_array&  theScaleFact,
+                             CORBA::Boolean              theCopy,
+                             bool                        theMakeGroups,
+                             ::SMESH_Mesh*               theTargetMesh=0);
+
   SMESH::SMESH_Mesh_ptr makeMesh(const char* theMeshName);
-  
+
   void DumpGroupsList(SMESH::TPythonDump & theDumpPython, 
                       const SMESH::ListOfGroups * theGroupList);
 
-private: //!< fields
+  string generateGroupName(const string& thePrefix);
 
-  SMESH_Mesh_i*         myMesh_i;
-  SMESH_Mesh *          myMesh;
+private: //!< fields
 
-  SMESH::long_array_var myLastCreatedElems;
-  SMESH::long_array_var myLastCreatedNodes;
+  SMESH_Mesh_i*      myMesh_i;
+  SMESH_Mesh *       myMesh;
+  ::SMESH_MeshEditor myEditor;
 
   SMESH::MeshPreviewStruct_var myPreviewData;
   bool                         myPreviewMode;
index 8371ccf2f28b34df70397330b2d982b4343012b9..2e4d1772c2a1bd5c01ea74c750e27528eda85aeb 100644 (file)
@@ -1,57 +1,60 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : SMESH_Mesh_i.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//
-#include "SMESH_Mesh_i.hxx"
 
-#include "SMESH_Filter_i.hxx"
-#include "SMESH_Gen_i.hxx"
-#include "SMESH_Group_i.hxx"
-#include "SMESH_MEDMesh_i.hxx"
-#include "SMESH_MeshEditor_i.hxx"
-#include "SMESH_PythonDump.hxx"
-#include "SMESH_subMesh_i.hxx"
+#include "SMESH_Mesh_i.hxx"
 
 #include "DriverMED_R_SMESHDS_Mesh.h"
 #include "DriverMED_W_SMESHDS_Mesh.h"
+#include "SMDS_EdgePosition.hxx"
+#include "SMDS_ElemIterator.hxx"
+#include "SMDS_FacePosition.hxx"
+#include "SMDS_IteratorOnIterators.hxx"
+#include "SMDS_SetIterator.hxx"
 #include "SMDS_VolumeTool.hxx"
 #include "SMESHDS_Command.hxx"
 #include "SMESHDS_CommandType.hxx"
 #include "SMESHDS_GroupOnGeom.hxx"
+#include "SMESH_Filter_i.hxx"
+#include "SMESH_Gen_i.hxx"
 #include "SMESH_Group.hxx"
+#include "SMESH_Group_i.hxx"
+#include "SMESH_MEDMesh_i.hxx"
 #include "SMESH_MeshEditor.hxx"
+#include "SMESH_MeshEditor_i.hxx"
 #include "SMESH_MesherHelper.hxx"
-#include "SMDS_EdgePosition.hxx"
-#include "SMDS_FacePosition.hxx"
+#include "SMESH_PreMeshInfo.hxx"
+#include "SMESH_PythonDump.hxx"
+#include "SMESH_subMesh_i.hxx"
 
-#include "OpUtil.hxx"
-#include "SALOME_NamingService.hxx"
-#include "Utils_CorbaException.hxx"
-#include "Utils_ExceptHandlers.hxx"
-#include "Utils_SINGLETON.hxx"
-#include "utilities.h"
+#include <OpUtil.hxx>
+#include <SALOME_NamingService.hxx>
+#include <Utils_CorbaException.hxx>
+#include <Utils_ExceptHandlers.hxx>
+#include <Utils_SINGLETON.hxx>
+#include <utilities.h>
+#include <GEOMImpl_Types.hxx>
 
 // OCCT Includes
 #include <BRep_Builder.hxx>
 #include <TColStd_MapOfInteger.hxx>
 #include <TColStd_SequenceOfInteger.hxx>
 #include <TCollection_AsciiString.hxx>
+#include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopoDS_Compound.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <TopTools_MapIteratorOfMapOfShape.hxx>
 
 // STL Includes
+#include <algorithm>
 #include <string>
 #include <iostream>
 #include <sstream>
@@ -81,9 +88,11 @@ static int MYDEBUG = 0;
 using namespace std;
 using SMESH::TPythonDump;
 
-int SMESH_Mesh_i::myIdGenerator = 0;
-
+int SMESH_Mesh_i::_idGenerator = 0;
 
+//To disable automatic genericobj management, the following line should be commented.
+//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
+#define WITHGENERICOBJ
 
 //=============================================================================
 /*!
@@ -92,15 +101,16 @@ int SMESH_Mesh_i::myIdGenerator = 0;
 //=============================================================================
 
 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
-                           SMESH_Gen_i*            gen_i,
-                           CORBA::Long studyId )
+                            SMESH_Gen_i*            gen_i,
+                            CORBA::Long studyId )
 : SALOME::GenericObj_i( thePOA )
 {
   MESSAGE("SMESH_Mesh_i");
   _impl = NULL;
   _gen_i = gen_i;
-  _id = myIdGenerator++;
+  _id = _idGenerator++;
   _studyId = studyId;
+  _preMeshInfo = NULL;
 }
 
 //=============================================================================
@@ -111,19 +121,52 @@ SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
 
 SMESH_Mesh_i::~SMESH_Mesh_i()
 {
-  INFOS("~SMESH_Mesh_i");
-  map<int, SMESH::SMESH_GroupBase_ptr>::iterator it;
-  for ( it = _mapGroups.begin(); it != _mapGroups.end(); it++ ) {
-    SMESH_GroupBase_i* aGroup = dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( it->second ).in() );
-    if ( aGroup ) {
-      // this method is colled from destructor of group (PAL6331)
+  MESSAGE("~SMESH_Mesh_i");
+
+#ifdef WITHGENERICOBJ
+  // destroy groups
+  map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
+  for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++) {
+    if ( CORBA::is_nil( itGr->second ))
+      continue;
+    SMESH_GroupBase_i* aGroup = dynamic_cast<SMESH_GroupBase_i*>(SMESH_Gen_i::GetServant(itGr->second).in());
+    if (aGroup) {
+      // this method is called from destructor of group (PAL6331)
       //_impl->RemoveGroup( aGroup->GetLocalID() );
-      
-      aGroup->Destroy();
+      aGroup->myMeshServant = 0;
+      aGroup->UnRegister();
     }
   }
   _mapGroups.clear();
-  delete _impl;
+
+  // destroy submeshes
+  map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
+  for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ ) {
+    if ( CORBA::is_nil( itSM->second ))
+      continue;
+    SMESH_subMesh_i* aSubMesh = dynamic_cast<SMESH_subMesh_i*>(SMESH_Gen_i::GetServant(itSM->second).in());
+    if (aSubMesh) {
+      aSubMesh->UnRegister();
+    }
+  }
+  _mapSubMeshIor.clear();
+
+  // destroy hypotheses
+  map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
+  for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
+    if ( CORBA::is_nil( itH->second ))
+      continue;
+    SMESH_Hypothesis_i* aHypo = dynamic_cast<SMESH_Hypothesis_i*>(SMESH_Gen_i::GetServant(itH->second).in());
+    if (aHypo) {
+      aHypo->UnRegister();
+    }
+  }
+  _mapHypo.clear();
+#endif
+
+  delete _impl; _impl = NULL;
+
+  if ( _preMeshInfo ) delete _preMeshInfo; _preMeshInfo = NULL;
 }
 
 //=============================================================================
@@ -146,6 +189,8 @@ void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
   catch(SALOME_Exception & S_ex) {
     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
   }
+  // to track changes of GEOM groups
+  addGeomGroupData( theShapeObject, _this() );
 }
 
 //================================================================================
@@ -189,6 +234,31 @@ GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
   return aShapeObj._retn();
 }
 
+//================================================================================
+/*!
+ * \brief Return false if the mesh is not yet fully loaded from the study file
+ */
+//================================================================================
+
+CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  return !_preMeshInfo;
+}
+
+//================================================================================
+/*!
+ * \brief Load full mesh data from the study file
+ */
+//================================================================================
+
+void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+}
+
 //================================================================================
 /*!
  * \brief Remove all nodes and elements
@@ -198,8 +268,12 @@ GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->ForgetAllData();
+
   try {
     _impl->Clear();
+    CheckGeomGroupModif(); // issue 20145
   }
   catch(SALOME_Exception & S_ex) {
     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
@@ -217,6 +291,9 @@ void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
   throw (SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   try {
     _impl->ClearSubMesh( ShapeID );
   }
@@ -280,9 +357,9 @@ SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
   int major, minor, release;
   if( !MED::getMEDVersion( theFileName, major, minor, release ) )
     major = minor = release = -1;
-  myFileInfo           = new SALOME_MED::MedFileInfo();
-  myFileInfo->fileName = theFileName;
-  myFileInfo->fileSize = 0;
+  _medFileInfo           = new SALOME_MED::MedFileInfo();
+  _medFileInfo->fileName = theFileName;
+  _medFileInfo->fileSize = 0;
 #ifdef WIN32
   struct _stati64 d;
   if ( ::_stati64( theFileName, &d ) != -1 )
@@ -290,10 +367,38 @@ SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
   struct stat64 d;
   if ( ::stat64( theFileName, &d ) != -1 )
 #endif
-    myFileInfo->fileSize = d.st_size;
-  myFileInfo->major    = major;
-  myFileInfo->minor    = minor;
-  myFileInfo->release  = release;
+    _medFileInfo->fileSize = d.st_size;
+  _medFileInfo->major    = major;
+  _medFileInfo->minor    = minor;
+  _medFileInfo->release  = release;
+
+  return ConvertDriverMEDReadStatus(status);
+}
+
+//================================================================================
+/*!
+ * \brief Imports mesh data from the CGNS file
+ */
+//================================================================================
+
+SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char*  theFileName,
+                                                          const int    theMeshIndex,
+                                                          std::string& theMeshName )
+  throw ( SALOME::SALOME_Exception )
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  int status;
+  try {
+    status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
+  }
+  catch( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+  }
+  catch ( ... ) {
+    THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
+  }
+
+  CreateGroupServants();
 
   return ConvertDriverMEDReadStatus(status);
 }
@@ -306,7 +411,7 @@ SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
 
 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
 {
-  std::string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
+  string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
                                                                nbDigits);
   return CORBA::string_dup( ver.c_str() );
 }
@@ -346,23 +451,6 @@ int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
   return 1;
 }
 
-//=============================================================================
-/*!
- *  importMEDFile
- *
- *  Imports mesh data from MED file
- */
-//=============================================================================
-
-// int SMESH_Mesh_i::importMEDFile( const char* theFileName, const char* theMeshName )
-// {
-//   // Read mesh with name = <theMeshName> and all its groups into SMESH_Mesh
-//   int status = _impl->MEDToMesh( theFileName, theMeshName );
-//   CreateGroupServants();
-
-//   return status;
-// }
-
 //=============================================================================
 /*!
  *
@@ -404,11 +492,14 @@ SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
  */
 //=============================================================================
 
-SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
+SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr       aSubShapeObject,
                                                      SMESH::SMESH_Hypothesis_ptr anHyp)
   throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->ForgetOrLoad();
+
   SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
 
   if ( !SMESH_Hypothesis::IsStatusFatal(status) )
@@ -442,7 +533,7 @@ SMESH_Hypothesis::Hypothesis_Status
   if(MYDEBUG) MESSAGE("addHypothesis");
 
   if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
-    THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
+    THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",
                                  SALOME::BAD_PARAM);
 
   SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
@@ -464,6 +555,9 @@ SMESH_Hypothesis::Hypothesis_Status
     status = _impl->AddHypothesis(myLocSubShape, hypId);
     if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
       _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
+#ifdef WITHGENERICOBJ
+      _mapHypo[hypId]->Register();
+#endif
       // assure there is a corresponding submesh
       if ( !_impl->IsMainShape( myLocSubShape )) {
         int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
@@ -490,6 +584,9 @@ SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aS
      throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->ForgetOrLoad();
+
   SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
 
   if ( !SMESH_Hypothesis::IsStatusFatal(status) )
@@ -516,41 +613,40 @@ SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aS
  */
 //=============================================================================
 
-SMESH_Hypothesis::Hypothesis_Status SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
-                                 SMESH::SMESH_Hypothesis_ptr anHyp)
+SMESH_Hypothesis::Hypothesis_Status
+SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr       aSubShapeObject,
+                               SMESH::SMESH_Hypothesis_ptr anHyp)
 {
-       if(MYDEBUG) MESSAGE("removeHypothesis()");
-       // **** proposer liste de subShape (selection multiple)
+  if(MYDEBUG) MESSAGE("removeHypothesis()");
+  // **** proposer liste de sub-shape (selection multiple)
+
+  if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
+    THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
 
-       if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
-               THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
-                       SALOME::BAD_PARAM);
+  SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
+  if (CORBA::is_nil(myHyp))
+    THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
 
-       SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
-       if (CORBA::is_nil(myHyp))
-         THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
-                       SALOME::BAD_PARAM);
+  SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
+  try
+  {
+    TopoDS_Shape myLocSubShape;
+    //use PseudoShape in case if mesh has no shape
+    if(HasShapeToMesh())
+      myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
+    else
+      myLocSubShape = _impl->GetShapeToMesh();
 
-       SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
-       try
-       {
-                TopoDS_Shape myLocSubShape;
-                //use PseudoShape in case if mesh has no shape
-                if(HasShapeToMesh())
-                  myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
-                else
-                  myLocSubShape = _impl->GetShapeToMesh();
-                
-                int hypId = myHyp->GetId();
-               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 status;
+    int hypId = myHyp->GetId();
+    status = _impl->RemoveHypothesis(myLocSubShape, hypId);
+//     if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many sub-shapes
+//       _mapHypo.erase( hypId );
+  }
+  catch(SALOME_Exception & S_ex)
+  {
+    THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+  }
+  return status;
 }
 
 //=============================================================================
@@ -560,19 +656,20 @@ SMESH_Hypothesis::Hypothesis_Status SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Ob
 //=============================================================================
 
 SMESH::ListOfHypothesis *
-       SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
+        SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
 throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
   if (MYDEBUG) MESSAGE("GetHypothesisList");
-  if (CORBA::is_nil(aSubShapeObject))
-    THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
-                                SALOME::BAD_PARAM);
+  if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
+    THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
 
   SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
 
   try {
     TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
+    if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
+      myLocSubShape = _impl->GetShapeToMesh();
     const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
     int i = 0, n = aLocalList.size();
     aList->length( n );
@@ -580,7 +677,7 @@ throw(SALOME::SALOME_Exception)
     for ( list<const SMESHDS_Hypothesis*>::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[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
     }
 
     aList->length( i );
@@ -592,20 +689,56 @@ throw(SALOME::SALOME_Exception)
   return aList._retn();
 }
 
+SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  if (MYDEBUG) MESSAGE("GetSubMeshes");
+
+  SMESH::submesh_array_var aList = new SMESH::submesh_array();
+
+  // Python Dump
+  TPythonDump aPythonDump;
+  if ( !_mapSubMeshIor.empty() )
+    aPythonDump << "[ ";
+
+  try {
+    aList->length( _mapSubMeshIor.size() );
+    int i = 0;
+    map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
+    for ( ; it != _mapSubMeshIor.end(); it++ ) {
+      if ( CORBA::is_nil( it->second )) continue;
+      aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
+      // Python Dump
+      if (i > 1) aPythonDump << ", ";
+      aPythonDump << it->second;
+    }
+    aList->length( i );
+  }
+  catch(SALOME_Exception & S_ex) {
+    THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+  }
+
+  // Update Python script
+  if ( !_mapSubMeshIor.empty() )
+    aPythonDump << " ] = " << _this() << ".GetSubMeshes()";
+
+  return aList._retn();
+}
+
 //=============================================================================
 /*!
  *
  */
 //=============================================================================
 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
-                                                 const char*           theName )
+                                                  const char*           theName )
      throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
   MESSAGE("SMESH_Mesh_i::GetSubMesh");
   if (CORBA::is_nil(aSubShapeObject))
-    THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
-                                SALOME::BAD_PARAM);
+    THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",
+                                 SALOME::BAD_PARAM);
 
   SMESH::SMESH_subMesh_var subMesh;
   SMESH::SMESH_Mesh_var    aMesh = SMESH::SMESH_Mesh::_narrow(_this());
@@ -615,12 +748,18 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShap
     //Get or Create the SMESH_subMesh object implementation
 
     int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
+
+    if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
+    {
+      TopoDS_Iterator it( myLocSubShape );
+      if ( it.More() )
+        THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
+    }
     subMesh = getSubMesh( subMeshId );
 
     // create a new subMesh object servant if there is none for the shape
     if ( subMesh->_is_nil() )
       subMesh = createSubMesh( aSubShapeObject );
-
     if ( _gen_i->CanPublishInStudy( subMesh )) {
       SALOMEDS::SObject_var aSO =
         _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
@@ -660,7 +799,10 @@ void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
       long aTag = SMESH_Gen_i::GetRefOnShapeTag();
       SALOMEDS::SObject_var anObj, aRef;
       if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
-       aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
+        aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
+
+//       if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
+//         aSubShapeObject = theSubMesh->GetSubShape();
 
       aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
 
@@ -669,26 +811,9 @@ void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
     }
   }
 
-  removeSubMesh( theSubMesh, aSubShapeObject.in() );
-}
-
-//=============================================================================
-/*!
- *  ElementTypeString
- */
-//=============================================================================
-#define CASE2STRING(enum) case SMESH::enum: return "SMESH."#enum;
-inline TCollection_AsciiString ElementTypeString (SMESH::ElementType theElemType)
-{
-  switch (theElemType) {
-    CASE2STRING( ALL );
-    CASE2STRING( NODE );
-    CASE2STRING( EDGE );
-    CASE2STRING( FACE );
-    CASE2STRING( VOLUME );
-  default:;
-  }
-  return "";
+  if ( removeSubMesh( theSubMesh, aSubShapeObject.in() ))
+    if ( _preMeshInfo )
+      _preMeshInfo->ForgetOrLoad();
 }
 
 //=============================================================================
@@ -698,10 +823,13 @@ inline TCollection_AsciiString ElementTypeString (SMESH::ElementType theElemType
 //=============================================================================
 
 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
-                                                 const char*         theName )
+                                                  const char*        theName )
      throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH::SMESH_Group_var aNewGroup =
     SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
 
@@ -712,7 +840,7 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType
     if ( !aSO->_is_nil()) {
       // Update Python script
       TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
-                    << ElementTypeString(theElemType) << ", '" << theName << "' )";
+                    << theElemType << ", '" << theName << "' )";
     }
   }
   return aNewGroup._retn();
@@ -724,18 +852,24 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType
  *
  */
 //=============================================================================
-SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType    theElemType,
-                                                                const char*           theName,
-                                                                GEOM::GEOM_Object_ptr theGeomObj)
+SMESH::SMESH_GroupOnGeom_ptr
+SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType    theElemType,
+                                   const char*           theName,
+                                   GEOM::GEOM_Object_ptr theGeomObj)
      throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH::SMESH_GroupOnGeom_var aNewGroup;
 
   TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
-  if ( !aShape.IsNull() ) {
+  if ( !aShape.IsNull() )
+  {
     aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
       ( createGroup( theElemType, theName, aShape ));
+
     if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
       SALOMEDS::SObject_var aSO =
         _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
@@ -743,8 +877,7 @@ SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementTy
       if ( !aSO->_is_nil()) {
         // Update Python script
         TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
-                      << ElementTypeString(theElemType) << ", '" << theName << "', "
-                      << theGeomObj << " )";
+                      << theElemType << ", '" << theName << "', " << theGeomObj << " )";
       }
     }
   }
@@ -752,6 +885,55 @@ SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementTy
   return aNewGroup._retn();
 }
 
+//================================================================================
+/*!
+ * \brief Creates a group whose contents is defined by filter
+ *  \param theElemType - group type
+ *  \param theName - group name
+ *  \param theFilter - the filter
+ *  \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
+ */
+//================================================================================
+
+SMESH::SMESH_GroupOnFilter_ptr
+SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
+                                    const char*        theName,
+                                    SMESH::Filter_ptr  theFilter )
+    throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
+  if ( CORBA::is_nil( theFilter ))
+    THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
+
+  SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
+  if ( !predicate )
+    THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
+
+  SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
+    ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
+
+  TPythonDump pd;
+  if ( !aNewGroup->_is_nil() )
+    aNewGroup->SetFilter( theFilter );
+
+  if ( _gen_i->CanPublishInStudy( aNewGroup ) )
+  {
+    SALOMEDS::SObject_var aSO =
+      _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), aNewGroup,
+                           GEOM::GEOM_Object::_nil(), theName);
+    if ( !aSO->_is_nil()) {
+      // Update Python script
+      pd << aSO << " = " << _this() << ".CreateGroupFromFilter("
+         << theElemType << ", '" << theName << "', " << theFilter << " )";
+    }
+  }
+
+  return aNewGroup._retn();
+}
+
 //=============================================================================
 /*!
  *
@@ -787,13 +969,17 @@ void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
 }
 
 //=============================================================================
-/*! RemoveGroupWithContents
+/*!
  *  Remove group with its contents
  */
 //=============================================================================
+
 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
   throw (SALOME::SALOME_Exception)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   if ( theGroup->_is_nil() )
     return;
 
@@ -805,8 +991,7 @@ void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup
   SMESH::long_array_var anIds = aGroup->GetListOfID();
   SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
 
-  // Update Python script
-  TPythonDump() << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
+  TPythonDump pyDump; // Supress dump from RemoveNodes/Elements() and RemoveGroup()
 
   // Remove contents
   if ( aGroup->GetType() == SMESH::NODE )
@@ -817,12 +1002,10 @@ void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup
   // Remove group
   RemoveGroup( theGroup );
 
-  // Clear python lines, created by RemoveNodes/Elements() and RemoveGroup()
-  _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
-  _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
+  // Update Python script
+  pyDump << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
 }
 
-
 //================================================================================
 /*!
  * \brief Get the list of groups existing in the mesh
@@ -865,6 +1048,7 @@ SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
 
   return aList._retn();
 }
+
 //=============================================================================
 /*!
  *  Get number of groups existing in the mesh
@@ -888,6 +1072,9 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr the
                                                   const char* theName )
   throw (SALOME::SALOME_Exception)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   try
   {
     if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
@@ -951,12 +1138,15 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups
                                                        const char*                theName )
 throw (SALOME::SALOME_Exception)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   if ( !theName )
     return SMESH::SMESH_Group::_nil();
 
   try
   {
-    NCollection_Map< int > anIds;
+    vector< int > anIds;
     SMESH::ElementType aType = SMESH::ALL;
     for ( int g = 0, n = theGroups.length(); g < n; g++ )
     {
@@ -979,7 +1169,7 @@ throw (SALOME::SALOME_Exception)
       for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
       {
         int aCurrId = aCurrIds[ i ];
-        anIds.Add( aCurrId );
+        anIds.push_back( aCurrId );
       }
     }
 
@@ -990,12 +1180,12 @@ throw (SALOME::SALOME_Exception)
     
     // Create array of identifiers
     SMESH::long_array_var aResIds = new SMESH::long_array;
-    aResIds->length( anIds.Extent() );
+    aResIds->length( anIds.size() );
     
-    NCollection_Map< int >::Iterator anIter( anIds );
-    for ( int i = 0; anIter.More(); anIter.Next(), i++ )
+    //NCollection_Map< int >::Iterator anIter( anIds );
+    for ( int i = 0; i<anIds.size(); i++ )
     {
-      aResIds[ i ] = anIter.Value();
+      aResIds[ i ] = anIds[i];
     }
     aResGrp->Add( aResIds );
 
@@ -1028,6 +1218,9 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr
                                                       const char* theName )
   throw (SALOME::SALOME_Exception)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
        theGroup1->GetType() != theGroup2->GetType() )
     return SMESH::SMESH_Group::_nil();
@@ -1080,10 +1273,14 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr
   \return pointer on the group
 */
 //=============================================================================
-SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectListOfGroups( 
-  const SMESH::ListOfGroups& theGroups, const char* theName )
-throw (SALOME::SALOME_Exception)
+SMESH::SMESH_Group_ptr
+SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
+                                    const char*                theName )
+  throw (SALOME::SALOME_Exception)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   if ( !theName )
     return SMESH::SMESH_Group::_nil();
 
@@ -1121,14 +1318,14 @@ throw (SALOME::SALOME_Exception)
     
     // create map of ids
     int nbGrp = theGroups.length();
-    NCollection_Map< int > anIds;
+    vector< int > anIds;
     NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
     for ( ; anIter.More(); anIter.Next() )
     {
       int aCurrId = anIter.Key();
       int aCurrNb = anIter.Value();
       if ( aCurrNb == nbGrp )
-        anIds.Add( aCurrId );
+        anIds.push_back( aCurrId );
     }
 
     // Create group
@@ -1138,12 +1335,12 @@ throw (SALOME::SALOME_Exception)
     
     // Create array of identifiers
     SMESH::long_array_var aResIds = new SMESH::long_array;
-    aResIds->length( anIds.Extent() );
+    aResIds->length( anIds.size() );
     
-    NCollection_Map< int >::Iterator aListIter( anIds );
-    for ( int i = 0; aListIter.More(); aListIter.Next(), i++ )
+    //NCollection_Map< int >::Iterator aListIter( anIds );
+    for ( int i = 0; i<anIds.size(); i++ )
     {
-      aResIds[ i ] = aListIter.Value();
+      aResIds[ i ] = anIds[i];
     }
     aResGrp->Add( aResIds );
 
@@ -1173,9 +1370,12 @@ throw (SALOME::SALOME_Exception)
 //=============================================================================
 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
                                                 SMESH::SMESH_GroupBase_ptr theGroup2,
-                                                const char* theName )
+                                                const char*                theName )
   throw (SALOME::SALOME_Exception)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
        theGroup1->GetType() != theGroup2->GetType() )
     return SMESH::SMESH_Group::_nil();
@@ -1229,18 +1429,21 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGr
   \return pointer on the group
 */
 //=============================================================================
-SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups( 
-  const SMESH::ListOfGroups& theMainGroups, 
-  const SMESH::ListOfGroups& theToolGroups, 
-  const char* theName )
+SMESH::SMESH_Group_ptr
+SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups, 
+                              const SMESH::ListOfGroups& theToolGroups, 
+                              const char*                theName )
   throw (SALOME::SALOME_Exception)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   if ( !theName )
     return SMESH::SMESH_Group::_nil();
 
   try
   {
-    NCollection_Map< int > aToolIds;
+    set< int > aToolIds;
     SMESH::ElementType aType = SMESH::ALL;
     int g, n;
     // iterate through tool groups
@@ -1265,11 +1468,11 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups(
       for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
       {
         int aCurrId = aCurrIds[ i ];
-        aToolIds.Add( aCurrId );
+        aToolIds.insert( aCurrId );
       }
     }
 
-    NCollection_Map< int > anIds; // result
+    vector< int > anIds; // result
 
     // Iterate through main group 
     for ( g = 0, n = theMainGroups.length(); g < n; g++ )
@@ -1293,8 +1496,8 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups(
       for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
       {
         int aCurrId = aCurrIds[ i ];
-        if ( !aToolIds.Contains( aCurrId ) )
-          anIds.Add( aCurrId );
+        if ( !aToolIds.count( aCurrId ) )
+          anIds.push_back( aCurrId );
       }
     }
 
@@ -1305,12 +1508,11 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups(
     
     // Create array of identifiers
     SMESH::long_array_var aResIds = new SMESH::long_array;
-    aResIds->length( anIds.Extent() );
+    aResIds->length( anIds.size() );
     
-    NCollection_Map< int >::Iterator anIter( anIds );
-    for ( int i = 0; anIter.More(); anIter.Next(), i++ )
+    for (int i=0; i<anIds.size(); i++ )
     {
-      aResIds[ i ] = anIter.Value();
+      aResIds[ i ] = anIds[i];
     }
     aResGrp->Add( aResIds );
 
@@ -1345,12 +1547,15 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups(
   \return pointer on new group
 */
 //=============================================================================
-SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup( 
-  const SMESH::ListOfGroups& theGroups, 
-  SMESH::ElementType         theElemType, 
-  const char*                theName )
+SMESH::SMESH_Group_ptr
+SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups, 
+                             SMESH::ElementType         theElemType, 
+                             const char*                theName )
   throw (SALOME::SALOME_Exception)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
 
   if ( !theName || !aMeshDS )
@@ -1362,7 +1567,7 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
   {
     // Create map of nodes from all groups 
 
-    NCollection_Map< int > aNodeMap;
+    set< int > aNodeMap;
     
     for ( int g = 0, n = theGroups.length(); g < n; g++ )
     {
@@ -1381,7 +1586,7 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
           int aCurrId = aCurrIds[ i ];
           const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
           if ( aNode )
-            aNodeMap.Add( aNode->GetID() );
+            aNodeMap.insert( aNode->GetID() );
         }
       }
       else 
@@ -1399,7 +1604,7 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
             const SMDS_MeshNode* aNode = 
               dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
             if ( aNode )
-              aNodeMap.Add( aNode->GetID() );
+              aNodeMap.insert( aNode->GetID() );
           }
         }
       }
@@ -1407,22 +1612,25 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
 
     // Get result identifiers 
 
-    NCollection_Map< int > aResultIds;
+    vector< int > aResultIds;
     if ( theElemType == SMESH::NODE )
     {
-      NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
-      for ( ; aNodeIter.More(); aNodeIter.Next() )
-        aResultIds.Add( aNodeIter.Value() );
+      //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
+      set<int>::iterator iter = aNodeMap.begin();
+      for ( ; iter != aNodeMap.end(); iter++ )
+        aResultIds.push_back( *iter);
     }
     else
     {
       // Create list of elements of given dimension constructed on the nodes
-      NCollection_Map< int > anElemList;
-      NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
-      for ( ; aNodeIter.More(); aNodeIter.Next() )
+      vector< int > anElemList;
+      //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
+      //for ( ; aNodeIter.More(); aNodeIter.Next() )
+      set<int>::iterator iter = aNodeMap.begin();
+      for ( ; iter != aNodeMap.end(); iter++ )
       {
         const SMDS_MeshElement* aNode = 
-          dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( aNodeIter.Value() ) );
+          dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( *iter ) );
         if ( !aNode )
           continue;
 
@@ -1432,15 +1640,14 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
           const SMDS_MeshElement* anElem = 
             dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
           if ( anElem && anElem->GetType() == anElemType )
-            anElemList.Add( anElem->GetID() );
+            anElemList.push_back( anElem->GetID() );
         }
       }
 
       // check whether all nodes of elements are present in nodes map
-      NCollection_Map< int >::Iterator anIter( anElemList );
-      for ( ; anIter.More(); anIter.Next() )
+      for (int i=0; i< anElemList.size(); i++)
       {
-        const SMDS_MeshElement* anElem = aMeshDS->FindElement( anIter.Value() );
+        const SMDS_MeshElement* anElem = aMeshDS->FindElement( anElemList[i] );
         if ( !anElem )
           continue;
 
@@ -1450,14 +1657,14 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
         {
           const SMDS_MeshNode* aNode = 
             dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
-          if ( !aNode || !aNodeMap.Contains( aNode->GetID() ) )
+          if ( !aNode || !aNodeMap.count( aNode->GetID() ) )
           {
             isOk = false;
             break;
           }
         } 
         if ( isOk )
-          aResultIds.Add( anElem->GetID() );
+          aResultIds.push_back( anElem->GetID() );
       }
     }
 
@@ -1469,11 +1676,10 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
     
     // Create array of identifiers
     SMESH::long_array_var aResIds = new SMESH::long_array;
-    aResIds->length( aResultIds.Extent() );
+    aResIds->length( aResultIds.size() );
     
-    NCollection_Map< int >::Iterator aResIter( aResultIds );
-    for ( int i = 0; aResIter.More(); aResIter.Next(), i++ )
-      aResIds[ i ] = aResIter.Value();
+    for (int i=0; i< aResultIds.size(); i++)
+      aResIds[ i ] = aResultIds[i];
     aResGrp->Add( aResIds );
 
     // Remove strings corresponding to group creation
@@ -1496,61 +1702,128 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
 
 //================================================================================
 /*!
- * \brief Return group items of a group present in a study
+ * \brief Remember GEOM group data
  */
 //================================================================================
 
-static GEOM::GEOM_Object_ptr getGroupItemsFromStudy(CORBA::Object_ptr    theMesh,
-                                                    SMESH_Gen_i*         theGen,
-                                                    list<TopoDS_Shape> & theItems)
+void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
+                                    CORBA::Object_ptr     theSmeshObj)
 {
-  GEOM::GEOM_Object_var groupObj;
-  SALOMEDS::Study_var  study = theGen->GetCurrentStudy();
-  GEOM::GEOM_Gen_var geomGen = theGen->GetGeomEngine();
-  if ( study->_is_nil() || geomGen->_is_nil() )
-    return groupObj._retn();
-  
+  if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
+    return;
+  // group SO
+  SALOMEDS::Study_var   study  = _gen_i->GetCurrentStudy();
+  SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
+  if ( groupSO->_is_nil() )
+    return;
+  // group indices
+  GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
   GEOM::GEOM_IGroupOperations_var groupOp =
-    geomGen->GetIGroupOperations( theGen->GetCurrentStudyID() );
-  GEOM::GEOM_IShapesOperations_var shapeOp =
-    geomGen->GetIShapesOperations( theGen->GetCurrentStudyID() );
-
-  SALOMEDS::SObject_var meshOS = theGen->ObjectToSObject(study, theMesh);
-  if ( meshOS->_is_nil() || groupOp->_is_nil() || shapeOp->_is_nil() )
-    return groupObj._retn();
-  SALOMEDS::SObject_var fatherSO = meshOS->GetFather();
-  if ( fatherSO->_is_nil() || fatherSO->Tag() != theGen->GetSubMeshOnCompoundTag() )
-    return groupObj._retn(); // keep only submeshes on groups
-
-  SALOMEDS::ChildIterator_var anIter = study->NewChildIterator(meshOS);
-  if ( anIter->_is_nil() ) return groupObj._retn();
-  for ( ; anIter->More(); anIter->Next())
-  {
-    SALOMEDS::SObject_var aSObject = anIter->Value();
-    SALOMEDS::SObject_var aRefSO;
-    if ( !aSObject->_is_nil() && aSObject->ReferencedObject(aRefSO) )
-    {
-      groupObj = GEOM::GEOM_Object::_narrow(aRefSO->GetObject());
-      if ( groupObj->_is_nil() ) break;
-      GEOM::ListOfLong_var  ids = groupOp->GetObjects( groupObj );
-      GEOM::GEOM_Object_var mainShape = groupObj->GetMainShape();
-      for ( int i = 0; i < ids->length(); ++i ) {
-        GEOM::GEOM_Object_var subShape = shapeOp->GetSubShape( mainShape, ids[i] );
-        TopoDS_Shape S = theGen->GeomObjectToShape( subShape );
-        if ( !S.IsNull() )
-          theItems.push_back( S );
-      }
-      break;
+    geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
+  GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
+
+  // store data
+  _geomGroupData.push_back( TGeomGroupData() );
+  TGeomGroupData & groupData = _geomGroupData.back();
+  // entry
+  CORBA::String_var entry = groupSO->GetID();
+  groupData._groupEntry = entry.in();
+  // indices
+  for ( int i = 0; i < ids->length(); ++i )
+    groupData._indices.insert( ids[i] );
+  // SMESH object
+  groupData._smeshObject = theSmeshObj;
+}
+
+//================================================================================
+/*!
+ * Remove GEOM group data relating to removed smesh object
+ */
+//================================================================================
+
+void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
+{
+  list<TGeomGroupData>::iterator
+    data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
+  for ( ; data != dataEnd; ++data ) {
+    if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
+      _geomGroupData.erase( data );
+      return;
     }
   }
-  return groupObj._retn();
 }
 
+//================================================================================
+/*!
+ * \brief Return new group contents if it has been changed and update group data
+ */
+//================================================================================
+
+TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
+{
+  TopoDS_Shape newShape;
+
+  // get geom group
+  SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
+  if ( study->_is_nil() ) return newShape; // means "not changed"
+  SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
+  if ( !groupSO->_is_nil() )
+  {
+    CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
+    if ( CORBA::is_nil( groupObj )) return newShape;
+    GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
+
+    // get indices of group items
+    set<int> curIndices;
+    GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
+    GEOM::GEOM_IGroupOperations_var groupOp =
+      geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
+    GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
+    for ( int i = 0; i < ids->length(); ++i )
+      curIndices.insert( ids[i] );
+
+    if ( groupData._indices == curIndices )
+      return newShape; // group not changed
+
+    // update data
+    groupData._indices = curIndices;
+
+    GEOM_Client* geomClient = _gen_i->GetShapeReader();
+    if ( !geomClient ) return newShape;
+    TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
+    geomClient->RemoveShapeFromBuffer( groupIOR );
+    newShape = _gen_i->GeomObjectToShape( geomGroup );
+  }    
+
+  if ( newShape.IsNull() ) {
+    // geom group becomes empty - return empty compound
+    TopoDS_Compound compound;
+    BRep_Builder().MakeCompound(compound);
+    newShape = compound;
+  }
+  return newShape;
+}
+
+namespace
+{
+  //=============================================================================
+  /*!
+   * \brief Storage of shape and index used in CheckGeomGroupModif()
+   */
+  //=============================================================================
+  struct TIndexedShape
+  {
+    int          _index;
+    TopoDS_Shape _shape;
+    TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
+  };
+}
 //=============================================================================
 /*!
- * \brief Update hypotheses assigned to geom groups if the latter change
+ * \brief Update objects depending on changed geom groups
  * 
- * NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation"
+ * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
+ * issue 0020210: Update of a smesh group after modification of the associated geom group
  */
 //=============================================================================
 
@@ -1561,83 +1834,240 @@ void SMESH_Mesh_i::CheckGeomGroupModif()
   SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
   if ( study->_is_nil() ) return;
 
-  // check if items of groups changed
-  map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
-  for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
-  {
-    const TopoDS_Shape & oldGroupShape = i_sm->second->GetSubShape();
-    SMESHDS_SubMesh * oldDS = i_sm->second->GetSubMeshDS();
-    if ( !oldDS /*|| !oldDS->IsComplexSubmesh()*/ )
-      continue;
-    int oldID = i_sm->first;
-    map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldID );
-    if ( i_smIor == _mapSubMeshIor.end() )
-      continue;
-    list< TopoDS_Shape> newItems;
-    GEOM::GEOM_Object_var groupObj = getGroupItemsFromStudy ( i_smIor->second, _gen_i, newItems );
-    if ( groupObj->_is_nil() )
-      continue;
+  CORBA::Long nbEntities = NbNodes() + NbElements();
 
-    int nbOldItems = oldDS->IsComplexSubmesh() ? oldDS->NbSubMeshes() : 1;
-    int nbNewItems = newItems.size();
-    bool groupChanged = ( nbOldItems != nbNewItems);
-    if ( !groupChanged ) {
-      if ( !oldDS->IsComplexSubmesh() ) { // old group has one item
-        groupChanged = ( oldGroupShape != newItems.front() );
-      }
-      else {
-        list<TopoDS_Shape>::iterator item = newItems.begin();
-        for ( ; item != newItems.end() && !groupChanged; ++item )
-        {
-          SMESHDS_SubMesh * itemDS = _impl->GetMeshDS()->MeshElements( *item );
-          groupChanged = ( !itemDS || !oldDS->ContainsSubMesh( itemDS ));
-        }
-      }
+  // Check if group contents changed
+
+  typedef map< string, TopoDS_Shape > TEntry2Geom;
+  TEntry2Geom newGroupContents;
+
+  list<TGeomGroupData>::iterator
+    data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
+  for ( ; data != dataEnd; ++data )
+  {
+    pair< TEntry2Geom::iterator, bool > it_new =
+      newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
+    bool processedGroup    = !it_new.second;
+    TopoDS_Shape& newShape = it_new.first->second;
+    if ( !processedGroup )
+      newShape = newGroupShape( *data );
+    if ( newShape.IsNull() )
+      continue; // no changes
+
+    if ( _preMeshInfo )
+      _preMeshInfo->ForgetOrLoad();
+
+    if ( processedGroup ) { // update group indices
+      list<TGeomGroupData>::iterator data2 = data;
+      for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
+      data->_indices = data2->_indices;
     }
-    // update hypotheses and submeshes if necessary
-    if ( groupChanged )
+
+    // Update SMESH objects according to new GEOM group contents
+
+    SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
+    if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
     {
-      // get a new group shape
-      GEOM_Client* geomClient = _gen_i->GetShapeReader();
-      if ( !geomClient ) continue;
-      TCollection_AsciiString groupIOR = _gen_i->GetGeomEngine()->GetStringFromIOR( groupObj );
-      geomClient->RemoveShapeFromBuffer( groupIOR );
-      TopoDS_Shape newGroupShape = _gen_i->GeomObjectToShape( groupObj );
+      int oldID = submesh->GetId();
+      if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
+        continue;
+      TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
+
       // update hypotheses
-      list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldGroupShape);
+      list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
       list <const SMESHDS_Hypothesis * >::iterator hypIt;
       for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
       {
-        _impl->RemoveHypothesis( oldGroupShape, (*hypIt)->GetID());
-        _impl->AddHypothesis   ( newGroupShape, (*hypIt)->GetID());
+        _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
+        _impl->AddHypothesis   ( newShape, (*hypIt)->GetID());
       }
       // care of submeshes
-      SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newGroupShape );
+      SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
       int newID = newSubmesh->GetId();
       if ( newID != oldID ) {
         _mapSubMesh   [ newID ] = newSubmesh;
         _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
         _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
-        _mapSubMesh.erase   (oldID);
-        _mapSubMesh_i.erase (oldID);
+        _mapSubMesh.   erase(oldID);
+        _mapSubMesh_i. erase(oldID);
         _mapSubMeshIor.erase(oldID);
         _mapSubMesh_i [ newID ]->changeLocalId( newID );
       }
+      continue;
     }
-  }
-}
 
-//=============================================================================
-/*!
- * \brief Create standalone group instead if group on geometry
- * 
- */
-//=============================================================================
+    SMESH::SMESH_GroupOnGeom_var smeshGroup =
+      SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
+    if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
+    {
+      SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
+      if ( group_i ) {
+        ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
+        SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
+        ds->SetShape( newShape );
+      }
+      continue;
+    }
 
-SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGeom_ptr theGroup )
-{
-  SMESH::SMESH_Group_var aGroup;
-  if ( theGroup->_is_nil() )
+    SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
+    if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
+    {
+      // Remove groups and submeshes basing on removed sub-shapes
+
+      TopTools_MapOfShape newShapeMap;
+      TopoDS_Iterator shapeIt( newShape );
+      for ( ; shapeIt.More(); shapeIt.Next() )
+        newShapeMap.Add( shapeIt.Value() );
+
+      SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
+      for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
+      {
+        if ( newShapeMap.Contains( shapeIt.Value() ))
+          continue;
+        TopTools_IndexedMapOfShape oldShapeMap;
+        TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
+        for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
+        {
+          const TopoDS_Shape& oldShape = oldShapeMap(i);
+          int oldInd = meshDS->ShapeToIndex( oldShape );
+          // -- submeshes --
+          map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
+          if ( i_smIor != _mapSubMeshIor.end() ) {
+            RemoveSubMesh( i_smIor->second ); // one submesh per shape index
+          }
+          // --- groups ---
+          map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
+          for ( ; i_grp != _mapGroups.end(); ++i_grp )
+          {
+            // check if a group bases on oldInd shape
+            SMESHDS_GroupOnGeom* grpOnGeom = 0;
+            if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
+              grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
+            if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
+            { // remove
+              RemoveGroup( i_grp->second ); // several groups can base on same shape
+              i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
+            }
+          }
+        }
+      }
+      // Reassign hypotheses and update groups after setting the new shape to mesh
+
+      // collect anassigned hypotheses
+      typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
+      list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
+      TShapeHypList assignedHyps;
+      for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
+      {
+        const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
+        list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
+        if ( !hyps.empty() ) {
+          assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
+          for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
+            _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
+        }
+      }
+      // collect shapes supporting groups
+      typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
+      TShapeTypeList groupData;
+      const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
+      set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
+      for ( ; grIt != groups.end(); ++grIt )
+      {
+        if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
+          groupData.push_back
+            ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
+      }
+      // set new shape to mesh -> DS of submeshes and geom groups is deleted
+      _impl->ShapeToMesh( newShape );
+      
+      // reassign hypotheses
+      TShapeHypList::iterator indS_hyps = assignedHyps.begin();
+      for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
+      {
+        TIndexedShape&                   geom = indS_hyps->first;
+        list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
+        int oldID = geom._index;
+        int newID = meshDS->ShapeToIndex( geom._shape );
+        if ( !newID )
+          continue;
+        if ( oldID == 1 ) { // main shape
+          newID = 1;
+          geom._shape = newShape;
+        }
+        for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
+          _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
+        // care of submeshes
+        SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
+        if ( newID != oldID ) {
+          _mapSubMesh   [ newID ] = newSubmesh;
+          _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
+          _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
+          _mapSubMesh.   erase(oldID);
+          _mapSubMesh_i. erase(oldID);
+          _mapSubMeshIor.erase(oldID);
+          _mapSubMesh_i [ newID ]->changeLocalId( newID );
+        }
+      }
+      // recreate groups
+      TShapeTypeList::iterator geomType = groupData.begin();
+      for ( ; geomType != groupData.end(); ++geomType )
+      {
+        const TIndexedShape& geom = geomType->first;
+        int oldID = geom._index;
+        if ( _mapGroups.find( oldID ) == _mapGroups.end() )
+          continue;
+        // get group name
+        SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
+        CORBA::String_var     name    = groupSO->GetName();
+        // update
+        SMESH_GroupBase_i* group_i    = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
+        int newID;
+        if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
+          group_i->changeLocalId( newID );
+      }
+
+      break; // everything has been updated
+
+    } // update mesh
+  } // loop on group data
+
+  // Update icons
+
+  CORBA::Long newNbEntities = NbNodes() + NbElements();
+  list< SALOMEDS::SObject_var > soToUpdateIcons;
+  if ( newNbEntities != nbEntities )
+  {
+    // Add all SObjects with icons to soToUpdateIcons
+    soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
+
+    for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
+         i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
+      soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
+
+    for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
+          i_gr != _mapGroups.end(); ++i_gr ) // groups
+      soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
+  }
+
+  list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin();
+  for ( ; so != soToUpdateIcons.end(); ++so )
+    _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
+}
+
+//=============================================================================
+/*!
+ * \brief Create standalone group from a group on geometry or filter
+ */
+//=============================================================================
+
+SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
+{
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
+  SMESH::SMESH_Group_var aGroup;
+  if ( theGroup->_is_nil() )
     return aGroup._retn();
 
   Unexpect aCatch(SALOME_SalomeException);
@@ -1647,13 +2077,14 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGe
   if ( !aGroupToRem )
     return aGroup._retn();
 
+  const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
+
   int anId = aGroupToRem->GetLocalID();
   if ( !_impl->ConvertToStandalone( anId ) )
     return aGroup._retn();
+  removeGeomGroupData( theGroup );
 
-    SMESH_GroupBase_i* aGroupImpl;
-      aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
-
+  SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
 
   // remove old instance of group from own map
   _mapGroups.erase( anId );
@@ -1666,15 +2097,29 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGe
     aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
     if ( !aGroupSO->_is_nil() ) {
 
-    // remove reference to geometry
-    SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
-    for ( ; chItr->More(); chItr->Next() )
-      // Remove group's child SObject
-      builder->RemoveObject( chItr->Value() );
+      // remove reference to geometry
+      SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
+      for ( ; chItr->More(); chItr->Next() )
+        // Remove group's child SObject
+        builder->RemoveObject( chItr->Value() );
 
       // Update Python script
       TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
                     << aGroupSO << " )";
+
+      // change icon of Group on Filter
+      if ( isOnFilter )
+      {
+        SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
+        const int isEmpty = ( elemTypes->length() == 0 );
+        if ( !isEmpty )
+        {
+          SALOMEDS::GenericAttribute_var anAttr =
+            builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
+          SALOMEDS::AttributePixMap_var pm = SALOMEDS::AttributePixMap::_narrow( anAttr );
+          pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
+        }
+      }
     }
   }
 
@@ -1688,8 +2133,8 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGe
   _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
 
   // register CORBA object for persistence
-  //int nextId = _gen_i->RegisterObject( aGroup );
-  //if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
+  /*int nextId =*/ _gen_i->RegisterObject( aGroup );
+
   builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
 
   return aGroup._retn();
@@ -1720,6 +2165,9 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theS
   int nextId = _gen_i->RegisterObject( subMesh );
   if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
 
+  // to track changes of GEOM groups
+  addGeomGroupData( theSubShapeObject, subMesh );
+
   return subMesh._retn();
 }
 
@@ -1744,29 +2192,50 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
  */
 //=============================================================================
 
-void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
+bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
                                   GEOM::GEOM_Object_ptr    theSubShapeObject )
 {
-  MESSAGE("SMESH_Mesh_i::removeSubMesh()");
-  if ( theSubMesh->_is_nil() || theSubShapeObject->_is_nil() )
-    return;
+  bool isHypChanged = false;
+  if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
+    return isHypChanged;
 
-  try {
-    SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
-    for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
-      removeHypothesis( theSubShapeObject, aHypList[i] );
+  if ( theSubShapeObject->_is_nil() )  // not published shape (IPAL13617)
+  {
+    CORBA::Long shapeId = theSubMesh->GetId();
+    if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
+    {
+      TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
+      if ( !S.IsNull() )
+      {
+        list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
+        isHypChanged = !hyps.empty();
+        list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
+        for ( ; hyp != hyps.end(); ++hyp )
+          _impl->RemoveHypothesis(S, (*hyp)->GetID());
+      }
     }
   }
-  catch( const SALOME::SALOME_Exception& ) {
-    INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
+  else
+  {
+    try {
+      SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
+      isHypChanged = ( aHypList->length() > 0 );
+      for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
+        removeHypothesis( theSubShapeObject, aHypList[i] );
+      }
+    }
+    catch( const SALOME::SALOME_Exception& ) {
+      INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
+    }
+    removeGeomGroupData( theSubShapeObject );
   }
-
   int subMeshId = theSubMesh->GetId();
 
   _mapSubMesh.erase(subMeshId);
   _mapSubMesh_i.erase(subMeshId);
   _mapSubMeshIor.erase(subMeshId);
-  if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
+
+  return isHypChanged;
 }
 
 //=============================================================================
@@ -1775,16 +2244,32 @@ void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
  */
 //=============================================================================
 
-SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
-                                                      const char*         theName,
-                                                      const TopoDS_Shape& theShape )
+SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType        theElemType,
+                                                      const char*               theName,
+                                                      const TopoDS_Shape&       theShape,
+                                                      const SMESH_PredicatePtr& thePredicate )
 {
+  std::string newName;
+  if ( !theName || strlen( theName ) == 0 )
+  {
+    std::set< std::string > presentNames;
+    std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
+    for ( ; i_gr != _mapGroups.end(); ++i_gr )
+      presentNames.insert( i_gr->second->GetName() );
+    do {
+      newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
+    } while ( !presentNames.insert( newName ).second );
+    theName = newName.c_str();
+  }
   int anId;
   SMESH::SMESH_GroupBase_var aGroup;
-  if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape )) {
+  if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
+  {
     SMESH_GroupBase_i* aGroupImpl;
     if ( !theShape.IsNull() )
       aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
+    else if ( thePredicate )
+      aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
     else
       aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
 
@@ -1799,6 +2284,12 @@ SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElem
     // register CORBA object for persistence
     int nextId = _gen_i->RegisterObject( aGroup );
     if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
+
+    // to track changes of GEOM groups
+    if ( !theShape.IsNull() ) {
+      GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
+      addGeomGroupData( geom, aGroup );
+    }
   }
   return aGroup._retn();
 }
@@ -1815,12 +2306,17 @@ void SMESH_Mesh_i::removeGroup( const int theId )
 {
   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
   if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
+    SMESH::SMESH_GroupBase_ptr group = _mapGroups[theId];
     _mapGroups.erase( theId );
-    _impl->RemoveGroup( theId );
+    removeGeomGroupData( group );
+    if (! _impl->RemoveGroup( theId ))
+    {
+      // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
+      RemoveGroup( group );
+    }
   }
 }
 
-
 //=============================================================================
 /*!
  *
@@ -1830,7 +2326,8 @@ void SMESH_Mesh_i::removeGroup( const int theId )
 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
 throw(SALOME::SALOME_Exception)
 {
-  if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
 
   SMESH::log_array_var aLog;
   try{
@@ -1860,14 +2357,14 @@ throw(SALOME::SALOME_Exception)
       aLog[indexLog].coords.length(rnum);
       aLog[indexLog].indexes.length(inum);
       for(int i = 0; i < rnum; i++){
-       aLog[indexLog].coords[i] = *ir;
-       //MESSAGE(" "<<i<<" "<<ir.Value());
-       ir++;
+        aLog[indexLog].coords[i] = *ir;
+        //MESSAGE(" "<<i<<" "<<ir.Value());
+        ir++;
       }
       for(int i = 0; i < inum; i++){
-       aLog[indexLog].indexes[i] = *ii;
-       //MESSAGE(" "<<i<<" "<<ii.Value());
-       ii++;
+        aLog[indexLog].indexes[i] = *ii;
+        //MESSAGE(" "<<i<<" "<<ii.Value());
+        ii++;
       }
       indexLog++;
       its++;
@@ -1891,7 +2388,7 @@ throw(SALOME::SALOME_Exception)
 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
 {
   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
-  // ****
+  _impl->ClearLog();
 }
 
 //=============================================================================
@@ -1917,6 +2414,34 @@ CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
   return _studyId;
 }
 
+//=============================================================================
+namespace
+{
+  //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
+  // issue 0020918: groups removal is caused by hyp modification
+  // issue 0021208: to forget not loaded mesh data at hyp modification
+  struct TCallUp_i : public SMESH_Mesh::TCallUp
+  {
+    SMESH_Mesh_i* _mesh;
+    TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
+    virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
+    virtual void HypothesisModified ()              { _mesh->onHypothesisModified(); }
+    virtual void Load ()                            { _mesh->Load(); }
+  };
+}
+
+//================================================================================
+/*!
+ * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
+ */
+//================================================================================
+
+void SMESH_Mesh_i::onHypothesisModified()
+{
+  if ( _preMeshInfo )
+    _preMeshInfo->ForgetOrLoad();
+}
+
 //=============================================================================
 /*!
  *
@@ -1927,6 +2452,8 @@ void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
 {
   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
   _impl = impl;
+  if ( _impl )
+    _impl->SetCallUp( new TCallUp_i(this));
 }
 
 //=============================================================================
@@ -1949,6 +2476,9 @@ void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
 
 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   // Create MeshEditor
   SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
   SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
@@ -1967,37 +2497,102 @@ SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
 
 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
   SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
   return aMesh._retn();
 }
 
+//================================================================================
+/*!
+ * \brief Return true if the mesh has been edited since a last total re-compute
+ *        and those modifications may prevent successful partial re-compute
+ */
+//================================================================================
+
+CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  return _impl->HasModificationsToDiscard();
+}
+
+//================================================================================
+/*!
+ * \brief Returns a random unique color
+ */
+//================================================================================
+
+static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
+{
+  const int MAX_ATTEMPTS = 100;
+  int cnt = 0;
+  double tolerance = 0.5;
+  SALOMEDS::Color col;
+
+  bool ok = false;
+  while ( !ok ) {
+    // generate random color
+    double red    = (double)rand() / RAND_MAX;
+    double green  = (double)rand() / RAND_MAX;
+    double blue   = (double)rand() / RAND_MAX;
+    // check existence in the list of the existing colors
+    bool matched = false;
+    std::list<SALOMEDS::Color>::const_iterator it;
+    for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
+      SALOMEDS::Color color = *it;
+      double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B  - blue  );
+      matched = tol < tolerance;
+    }
+    if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
+    ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
+    col.R = red;
+    col.G = green;
+    col.B = blue;
+  }
+  return col;
+}
+
 //=============================================================================
 /*!
- *
+ * Sets auto-color mode. If it is on, groups get unique random colors
  */
 //=============================================================================
+
 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
   _impl->SetAutoColor(theAutoColor);
+
+  TPythonDump pyDump; // not to dump group->SetColor() from below code
+  pyDump<<_this()<<".SetAutoColor( "<<theAutoColor<<" )";
+
+  std::list<SALOMEDS::Color> aReservedColors;
+  map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
+  for ( ; it != _mapGroups.end(); it++ ) {
+    if ( CORBA::is_nil( it->second )) continue;
+    SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
+    it->second->SetColor( aColor );
+    aReservedColors.push_back( aColor );
+  }
 }
 
 //=============================================================================
 /*!
- *
+ * Returns true if auto-color mode is on
  */
 //=============================================================================
+
 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
   return _impl->GetAutoColor();
 }
 
-
 //=============================================================================
 /*!
- *  Export in different formats
+ *  Checks if there are groups with equal names
  */
 //=============================================================================
 
@@ -2006,7 +2601,13 @@ CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
   return _impl->HasDuplicatedGroupNamesMED();
 }
 
-void SMESH_Mesh_i::PrepareForWriting (const char* file)
+//================================================================================
+/*!
+ * \brief Care of a file before exporting mesh into it
+ */
+//================================================================================
+
+void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
 {
   TCollection_AsciiString aFullName ((char*)file);
   OSD_Path aPath (aFullName);
@@ -2015,8 +2616,10 @@ void SMESH_Mesh_i::PrepareForWriting (const char* file)
     // existing filesystem node
     if (aFile.KindOfFile() == OSD_FILE) {
       if (aFile.IsWriteable()) {
-        aFile.Reset();
-        aFile.Remove();
+        if (overwrite) {
+          aFile.Reset();
+          aFile.Remove();
+        }
         if (aFile.Failed()) {
           TCollection_AsciiString msg ("File ");
           msg += aFullName + " cannot be replaced.";
@@ -2047,98 +2650,188 @@ void SMESH_Mesh_i::PrepareForWriting (const char* file)
   }
 }
 
-void SMESH_Mesh_i::ExportToMED (const char* file,
-                               CORBA::Boolean auto_groups,
-                               SMESH::MED_VERSION theVersion)
-  throw(SALOME::SALOME_Exception)
-{
-  Unexpect aCatch(SALOME_SalomeException);
+//================================================================================
+/*!
+ * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
+ *  \param file - file name
+ *  \param overwrite - to erase the file or not
+ *  \retval string - mesh name
+ */
+//================================================================================
 
+string SMESH_Mesh_i::prepareMeshNameAndGroups(const char*    file,
+                                              CORBA::Boolean overwrite)
+{
   // Perform Export
-  PrepareForWriting(file);
-  const char* aMeshName = "Mesh";
+  PrepareForWriting(file, overwrite);
+  string aMeshName = "Mesh";
   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
   if ( !aStudy->_is_nil() ) {
     SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
     if ( !aMeshSO->_is_nil() ) {
-      aMeshName = aMeshSO->GetName();
+      CORBA::String_var name = aMeshSO->GetName();
+      aMeshName = name;
       // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
       if ( !aStudy->GetProperties()->IsLocked() )
-       {
-       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());
+      {
+        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");
-       }
+      }
     }
   }
   // Update Python script
   // set name of mesh before export
-  TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName << "')";
-  
+  TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName.c_str() << "')";
+
   // check names of groups
   checkGroupNames();
 
-  TPythonDump() << _this() << ".ExportToMED( '"
-                << file << "', " << auto_groups << ", " << theVersion << " )";
+  return aMeshName;
+}
+
+//================================================================================
+/*!
+ * \brief Export to med file
+ */
+//================================================================================
+
+void SMESH_Mesh_i::ExportToMEDX (const char*        file,
+                                 CORBA::Boolean     auto_groups,
+                                 SMESH::MED_VERSION theVersion,
+                                 CORBA::Boolean     overwrite)
+  throw(SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
+  string aMeshName = prepareMeshNameAndGroups(file, overwrite);
+  TPythonDump() << _this() << ".ExportToMEDX( r'"
+                << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
+
+  _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion );
+}
+
+//================================================================================
+/*!
+ * \brief Export a mesh to a med file
+ */
+//================================================================================
 
-  _impl->ExportMED( file, aMeshName, auto_groups, theVersion );
+void SMESH_Mesh_i::ExportToMED (const char*        file,
+                                CORBA::Boolean     auto_groups,
+                                SMESH::MED_VERSION theVersion)
+  throw(SALOME::SALOME_Exception)
+{
+  ExportToMEDX(file,auto_groups,theVersion,true);
 }
 
+//================================================================================
+/*!
+ * \brief Export a mesh to a med file
+ */
+//================================================================================
+
 void SMESH_Mesh_i::ExportMED (const char* file,
-                             CORBA::Boolean auto_groups)
+                              CORBA::Boolean auto_groups)
+  throw(SALOME::SALOME_Exception)
+{
+  ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
+}
+
+//================================================================================
+/*!
+ * \brief Export a mesh to a SAUV file
+ */
+//================================================================================
+
+void SMESH_Mesh_i::ExportSAUV (const char* file,
+                               CORBA::Boolean auto_groups)
   throw(SALOME::SALOME_Exception)
 {
-  ExportToMED(file,auto_groups,SMESH::MED_V2_1);
+  Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
+  string aMeshName = prepareMeshNameAndGroups(file, true);
+  TPythonDump() << _this() << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
+  _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
 }
 
+
+//================================================================================
+/*!
+ * \brief Export a mesh to a DAT file
+ */
+//================================================================================
+
 void SMESH_Mesh_i::ExportDAT (const char *file)
   throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
 
   // Update Python script
   // check names of groups
   checkGroupNames();
-  TPythonDump() << _this() << ".ExportDAT( '" << file << "' )";
+  TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
 
   // Perform Export
   PrepareForWriting(file);
   _impl->ExportDAT(file);
 }
 
+//================================================================================
+/*!
+ * \brief Export a mesh to an UNV file
+ */
+//================================================================================
+
 void SMESH_Mesh_i::ExportUNV (const char *file)
   throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
 
   // Update Python script
   // check names of groups
   checkGroupNames();
-  TPythonDump() << _this() << ".ExportUNV( '" << file << "' )";
+  TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
 
   // Perform Export
   PrepareForWriting(file);
   _impl->ExportUNV(file);
 }
 
+//================================================================================
+/*!
+ * \brief Export a mesh to an STL file
+ */
+//================================================================================
+
 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
   throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
 
   // Update Python script
   // check names of groups
   checkGroupNames();
-  TPythonDump() << _this() << ".ExportSTL( '" << file << "', " << isascii << " )";
+  TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
 
   // Perform Export
   PrepareForWriting(file);
@@ -2147,84 +2840,282 @@ void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
 
 //=============================================================================
 /*!
- *
+ * \brief Class providing SMESHDS_Mesh API to SMESH_IDSource. 
+ *        It is used to export a part of mesh as a whole mesh.
  */
-//=============================================================================
-
-SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
+class SMESH_MeshPartDS : public SMESHDS_Mesh
 {
-  Unexpect aCatch(SALOME_SalomeException);
-  SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
-  SALOME_MED::MESH_var aMesh = aMedMesh->_this();
-  return aMesh._retn();
-}
+public:
+  SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart);
+
+  virtual SMDS_NodeIteratorPtr   nodesIterator     (bool idInceasingOrder=false) const;
+  virtual SMDS_EdgeIteratorPtr   edgesIterator     (bool idInceasingOrder=false) const;
+  virtual SMDS_FaceIteratorPtr   facesIterator     (bool idInceasingOrder=false) const;
+  virtual SMDS_VolumeIteratorPtr volumesIterator   (bool idInceasingOrder=false) const;
+
+  virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type=SMDSAbs_All) const;
+  virtual SMDS_ElemIteratorPtr elementGeomIterator(SMDSAbs_GeometryType type) const;
+  virtual SMDS_ElemIteratorPtr elementEntityIterator(SMDSAbs_EntityType type) const;
+
+private:
+  TIDSortedElemSet _elements[ SMDSAbs_NbElementTypes ];
+  SMESHDS_Mesh*    _meshDS;
+  /*!
+   * \brief Class used to access to protected data of SMDS_MeshInfo
+   */
+  struct TMeshInfo : public SMDS_MeshInfo
+  {
+    void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
+  };
+};
 
-//=============================================================================
+//================================================================================
 /*!
- *
+ * \brief Export a part of mesh to a med file
  */
-//=============================================================================
-CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
+//================================================================================
+
+void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart,
+                                   const char*                 file,
+                                   CORBA::Boolean              auto_groups,
+                                   ::SMESH::MED_VERSION        version,
+                                   ::CORBA::Boolean            overwrite)
+  throw (SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
-  return _impl->NbNodes();
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
+  PrepareForWriting(file, overwrite);
+
+  string aMeshName = "Mesh";
+  SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
+  if ( !aStudy->_is_nil() ) {
+    SALOMEDS::SObject_var SO = _gen_i->ObjectToSObject( aStudy, meshPart );
+    if ( !SO->_is_nil() ) {
+      CORBA::String_var name = SO->GetName();
+      aMeshName = name;
+    }
+  }
+  SMESH_MeshPartDS partDS( meshPart );
+  _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS );
+
+  TPythonDump() << _this() << ".ExportPartToMED( " << meshPart << ", r'" << file << "', "
+                << auto_groups << ", " << version << ", " << overwrite << " )";
 }
 
-//=============================================================================
+//================================================================================
 /*!
- *
+ * \brief Export a part of mesh to a DAT file
  */
-//=============================================================================
-CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
+//================================================================================
+
+void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
+                                   const char*                 file)
+  throw (SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
-  return NbEdges() + NbFaces() + NbVolumes();
-}
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
 
-//=============================================================================
+  PrepareForWriting(file);
+
+  SMESH_MeshPartDS partDS( meshPart );
+  _impl->ExportDAT(file,&partDS);
+
+  TPythonDump() << _this() << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
+}
+//================================================================================
 /*!
- *
+ * \brief Export a part of mesh to an UNV file
  */
-//=============================================================================
-CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
+//================================================================================
+
+void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
+                                   const char*                 file)
+  throw (SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
-  return _impl->NbEdges();
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
+  PrepareForWriting(file);
+
+  SMESH_MeshPartDS partDS( meshPart );
+  _impl->ExportUNV(file, &partDS);
+
+  TPythonDump() << _this() << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
 }
+//================================================================================
+/*!
+ * \brief Export a part of mesh to an STL file
+ */
+//================================================================================
 
-CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
-  throw(SALOME::SALOME_Exception)
+void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
+                                   const char*                 file,
+                                   ::CORBA::Boolean            isascii)
+  throw (SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
-  return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
+  PrepareForWriting(file);
+
+  SMESH_MeshPartDS partDS( meshPart );
+  _impl->ExportSTL(file, isascii, &partDS);
+
+  TPythonDump() << _this() << ".ExportPartToSTL( "
+                << meshPart<< ", r'" << file << "', " << isascii << ")";
 }
 
-//=============================================================================
+//================================================================================
 /*!
- *
+ * \brief Export a part of mesh to an STL file
+ */
+//================================================================================
+
+void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
+                              const char*                 file,
+                              CORBA::Boolean              overwrite)
+  throw (SALOME::SALOME_Exception)
+{
+#ifdef WITH_CGNS
+  Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
+  PrepareForWriting(file,overwrite);
+
+  SMESH_MeshPartDS partDS( meshPart );
+  _impl->ExportCGNS(file, &partDS);
+
+  TPythonDump() << _this() << ".ExportCGNS( "
+                << meshPart<< ", r'" << file << "', " << overwrite << ")";
+#else
+  THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
+#endif
+}
+
+//=============================================================================
+/*!
+ * Return implementation of SALOME_MED::MESH interfaces
  */
 //=============================================================================
+
+SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
+  SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
+  SALOME_MED::MESH_var aMesh = aMedMesh->_this();
+  return aMesh._retn();
+}
+
+//=============================================================================
+
+CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbNodes();
+
+  return _impl->NbNodes();
+}
+
+CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbElements();
+
+  return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
+}
+
+CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->Nb0DElements();
+
+  return _impl->Nb0DElements();
+}
+
+CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbBalls();
+
+  return _impl->NbBalls();
+}
+
+CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbEdges();
+
+  return _impl->NbEdges();
+}
+
+CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
+  throw(SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
+
+  return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
+}
+
+//=============================================================================
+
 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbFaces();
+
   return _impl->NbFaces();
 }
 
 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbTriangles();
+
   return _impl->NbTriangles();
 }
 
 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbQuadrangles();
+
   return _impl->NbQuadrangles();
 }
 
+CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbBiQuadQuadrangles();
+
+  return _impl->NbBiQuadQuadrangles();
+}
+
 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbPolygons();
+
   return _impl->NbPolygons();
 }
 
@@ -2232,6 +3123,9 @@ CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
   throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
+
   return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
 }
 
@@ -2239,6 +3133,9 @@ CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
   throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
+
   return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
 }
 
@@ -2246,47 +3143,83 @@ CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
   throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
+
   return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
 }
 
 //=============================================================================
-/*!
- *
- */
-//=============================================================================
+
 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbVolumes();
+
   return _impl->NbVolumes();
 }
 
 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbTetras();
+
   return _impl->NbTetras();
 }
 
 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbHexas();
+
   return _impl->NbHexas();
 }
 
+CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbTriQuadHexas();
+
+  return _impl->NbTriQuadraticHexas();
+}
+
 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbPyramids();
+
   return _impl->NbPyramids();
 }
 
 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbPrisms();
+
   return _impl->NbPrisms();
 }
 
+CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbHexPrisms();
+
+  return _impl->NbHexagonalPrisms();
+}
+
 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbPolyhedrons();
+
   return _impl->NbPolyhedrons();
 }
 
@@ -2294,6 +3227,9 @@ CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
   throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
+
   return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
 }
 
@@ -2301,6 +3237,9 @@ CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
   throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
+
   return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
 }
 
@@ -2308,6 +3247,9 @@ CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
   throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
+
   return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
 }
 
@@ -2315,6 +3257,9 @@ CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
   throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
+
   return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
 }
 
@@ -2322,14 +3267,18 @@ CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
   throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
+
   return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
 }
 
 //=============================================================================
 /*!
- *
+ * Returns nb of published sub-meshes
  */
 //=============================================================================
+
 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
@@ -2338,41 +3287,31 @@ CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
 
 //=============================================================================
 /*!
- *
+ * Dumps mesh into a string
  */
 //=============================================================================
+
 char* SMESH_Mesh_i::Dump()
 {
-  std::ostringstream os;
+  ostringstream os;
   _impl->Dump( os );
   return CORBA::string_dup( os.str().c_str() );
 }
 
 //=============================================================================
 /*!
- *
+ * Method of SMESH_IDSource interface
  */
 //=============================================================================
+
 SMESH::long_array* SMESH_Mesh_i::GetIDs()
 {
-//   SMESH::long_array_var aResult = new SMESH::long_array();
-//   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
-//   int aMinId = aSMESHDS_Mesh->MinElementID();
-//   int aMaxId =  aSMESHDS_Mesh->MaxElementID();
-
-//   aResult->length(aMaxId - aMinId + 1);
-
-//   for (int i = 0, id = aMinId; id <= aMaxId; id++  )
-//     aResult[i++] = id;
-
-//   return aResult._retn();
-  // PAL12398
   return GetElementsId();
 }
 
 //=============================================================================
 /*!
- *
+ * Returns ids of all elements
  */
 //=============================================================================
 
@@ -2380,7 +3319,9 @@ SMESH::long_array* SMESH_Mesh_i::GetElementsId()
      throw (SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
-  MESSAGE("SMESH_Mesh_i::GetElementsId");
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH::long_array_var aResult = new SMESH::long_array();
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
 
@@ -2399,7 +3340,7 @@ SMESH::long_array* SMESH_Mesh_i::GetElementsId()
 
 //=============================================================================
 /*!
- *
+ * Returns ids of all elements of given type
  */
 //=============================================================================
 
@@ -2407,7 +3348,9 @@ SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemTy
     throw (SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
-  MESSAGE("SMESH_subMesh_i::GetElementsByType");
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH::long_array_var aResult = new SMESH::long_array();
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
 
@@ -2419,7 +3362,7 @@ SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemTy
   // No sense in returning ids of elements along with ids of nodes:
   // when theElemType == SMESH::ALL, return node ids only if
   // there are no elements
-  if ( theElemType == SMESH::NODE || theElemType == SMESH::ALL && nbElements == 0 )
+  if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
     return GetNodesId();
 
   aResult->length( nbElements );
@@ -2440,7 +3383,7 @@ SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemTy
 
 //=============================================================================
 /*!
- *
+ * Returns ids of all nodes
  */
 //=============================================================================
 
@@ -2448,7 +3391,9 @@ SMESH::long_array* SMESH_Mesh_i::GetNodesId()
   throw (SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
-  MESSAGE("SMESH_subMesh_i::GetNodesId");
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH::long_array_var aResult = new SMESH::long_array();
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
 
@@ -2457,7 +3402,7 @@ SMESH::long_array* SMESH_Mesh_i::GetNodesId()
 
   long nbNodes = NbNodes();
   aResult->length( nbNodes );
-  SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator();
+  SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
   for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
     aResult[i] = anIt->next()->GetID();
 
@@ -2473,9 +3418,30 @@ SMESH::long_array* SMESH_Mesh_i::GetNodesId()
 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
   throw (SALOME::SALOME_Exception)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
 }
 
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
+  throw (SALOME::SALOME_Exception)
+{
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
+  const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
+  if ( !e )
+    THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
+
+  return ( SMESH::EntityType ) e->GetEntityType();
+}
 
 //=============================================================================
 /*!
@@ -2485,6 +3451,9 @@ SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const boo
 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
      throw (SALOME::SALOME_Exception)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH::long_array_var aResult = new SMESH::long_array();
 
   SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
@@ -2512,9 +3481,13 @@ SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
  * returns only nodes on shapes.
  */
 //=============================================================================
-SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
-     throw (SALOME::SALOME_Exception)
+SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
+                                                   CORBA::Boolean    all)
+  throw (SALOME::SALOME_Exception)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH::long_array_var aResult = new SMESH::long_array();
 
   SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
@@ -2552,15 +3525,18 @@ SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CO
   return aResult._retn();
 }
   
-
 //=============================================================================
 /*!
  * Returns type of elements for given submesh
  */
 //=============================================================================
+
 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
-     throw (SALOME::SALOME_Exception)
+  throw (SALOME::SALOME_Exception)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
   if(!SM) return SMESH::ALL;
 
@@ -2578,12 +3554,15 @@ SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID
 
 //=============================================================================
 /*!
- *
+ * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
  */
 //=============================================================================
 
 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   CORBA::LongLong pointeur = CORBA::LongLong(_impl);
   if ( MYDEBUG )
     MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
@@ -2600,6 +3579,9 @@ CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
 
 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH::double_array_var aResult = new SMESH::double_array();
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
   if ( aSMESHDS_Mesh == NULL )
@@ -2628,6 +3610,9 @@ SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
 
 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH::long_array_var aResult = new SMESH::long_array();
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
   if ( aSMESHDS_Mesh == NULL )
@@ -2663,6 +3648,9 @@ SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
 
 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
   aNodePosition->shapeID = 0;
   aNodePosition->shapeType = GEOM::SHAPE;
@@ -2674,21 +3662,21 @@ SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
   {
     if ( SMDS_PositionPtr pos = aNode->GetPosition() )
     {
-      aNodePosition->shapeID = pos->GetShapeId();
+      aNodePosition->shapeID = aNode->getshapeId();
       switch ( pos->GetTypeOfPosition() ) {
       case SMDS_TOP_EDGE:
         aNodePosition->shapeType = GEOM::EDGE;
         aNodePosition->params.length(1);
         aNodePosition->params[0] =
-          static_cast<SMDS_EdgePosition*>( pos.get() )->GetUParameter();
+          static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
         break;
       case SMDS_TOP_FACE:
         aNodePosition->shapeType = GEOM::FACE;
         aNodePosition->params.length(2);
         aNodePosition->params[0] =
-          static_cast<SMDS_FacePosition*>( pos.get() )->GetUParameter();
+          static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
         aNodePosition->params[1] =
-          static_cast<SMDS_FacePosition*>( pos.get() )->GetVParameter();
+          static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
         break;
       case SMDS_TOP_VERTEX:
         aNodePosition->shapeType = GEOM::VERTEX;
@@ -2715,6 +3703,9 @@ SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
 
 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
   if ( aSMESHDS_Mesh == NULL )
     return -1;
@@ -2722,11 +3713,7 @@ CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
   // try to find node
   const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
   if(aNode) {
-    SMDS_PositionPtr pos = aNode->GetPosition();
-    if(!pos)
-      return -1;
-    else
-      return pos->GetShapeId();
+    return aNode->getshapeId();
   }
 
   return -1;
@@ -2743,6 +3730,9 @@ CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
 
 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
   if ( aSMESHDS_Mesh == NULL )
     return -1;
@@ -2771,6 +3761,9 @@ CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
 
 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
   if ( aSMESHDS_Mesh == NULL ) return -1;
   // try to find element
@@ -2790,6 +3783,9 @@ CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
 
 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
   if ( aSMESHDS_Mesh == NULL ) return -1;
   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
@@ -2806,6 +3802,9 @@ CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long in
 
 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH::long_array_var aResult = new SMESH::long_array();
   if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
   {
@@ -2828,6 +3827,9 @@ SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
 
 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
   if ( aSMESHDS_Mesh == NULL ) return false;
   // try to find node
@@ -2851,6 +3853,9 @@ CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Lo
 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
                                                    SMESH::ElementType theElemType)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
   if ( aSMESHDS_Mesh == NULL ) return false;
 
@@ -2878,6 +3883,9 @@ CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
 
 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
   if ( aSMESHDS_Mesh == NULL ) return -1;
   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
@@ -2894,6 +3902,9 @@ CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
 
 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
   if ( aSMESHDS_Mesh == NULL ) return -1;
   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
@@ -2901,6 +3912,63 @@ CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
   return elem->NbFaces();
 }
 
+//=======================================================================
+//function : GetElemFaceNodes
+//purpose  : Returns nodes of given face (counted from zero) for given element.
+//=======================================================================
+
+SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long  elemId,
+                                                  CORBA::Short faceIndex)
+{
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
+  SMESH::long_array_var aResult = new SMESH::long_array();
+  if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
+  {
+    if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
+    {
+      SMDS_VolumeTool vtool( elem );
+      if ( faceIndex < vtool.NbFaces() )
+      {
+        aResult->length( vtool.NbFaceNodes( faceIndex ));
+        const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
+        for ( int i = 0; i < aResult->length(); ++i )
+          aResult[ i ] = nn[ i ]->GetID();
+      }
+    }
+  }
+  return aResult._retn();
+}
+
+//=======================================================================
+//function : FindElementByNodes
+//purpose  : Returns an element based on all given nodes.
+//=======================================================================
+
+CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
+{
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
+  CORBA::Long elemID(0);
+  if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
+  {
+    vector< const SMDS_MeshNode * > nn( nodes.length() );
+    for ( int i = 0; i < nodes.length(); ++i )
+      if ( !( nn[i] = mesh->FindNode( nodes[i] )))
+        return elemID;
+
+    const SMDS_MeshElement* elem = mesh->FindElement( nn );
+    if ( !elem && ( _impl->NbEdges  ( ORDER_QUADRATIC ) ||
+                    _impl->NbFaces  ( ORDER_QUADRATIC ) ||
+                    _impl->NbVolumes( ORDER_QUADRATIC )))
+      elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
+
+    if ( elem ) elemID = CORBA::Long( elem->GetID() );
+  }
+  return elemID;
+}
 
 //=============================================================================
 /*!
@@ -2910,6 +3978,9 @@ CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
 
 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
   if ( aSMESHDS_Mesh == NULL ) return false;
   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
@@ -2926,6 +3997,9 @@ CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
 
 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
   if ( aSMESHDS_Mesh == NULL ) return false;
   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
@@ -2933,6 +4007,23 @@ CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
   return elem->IsQuadratic();
 }
 
+//=============================================================================
+/*!
+ * Returns diameter of ball discrete element or zero in case of an invalid \a id
+ */
+//=============================================================================
+
+CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
+{
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
+  if ( const SMDS_BallElement* ball =
+       dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
+    return ball->GetDiameter();
+
+  return 0;
+}
 
 //=============================================================================
 /*!
@@ -2942,6 +4033,9 @@ CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
 
 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH::double_array_var aResult = new SMESH::double_array();
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
   if ( aSMESHDS_Mesh == NULL )
@@ -2993,6 +4087,7 @@ void SMESH_Mesh_i::CreateGroupServants()
 {
   SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
 
+  set<int> addedIDs;
   ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
   while ( groupIt->more() )
   {
@@ -3002,6 +4097,7 @@ void SMESH_Mesh_i::CreateGroupServants()
     map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
     if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
       continue;
+    addedIDs.insert( anId );
 
     SMESH_GroupBase_i* aGroupImpl;
     TopoDS_Shape       shape;
@@ -3027,12 +4123,23 @@ void SMESH_Mesh_i::CreateGroupServants()
     int nextId = _gen_i->RegisterObject( groupVar );
     if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
 
-    // publishing of the groups in the study
+    // publishing the groups in the study
     if ( !aStudy->_is_nil() ) {
       GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
       _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
     }
   }
+  if ( !addedIDs.empty() )
+  {
+    // python dump
+    set<int>::iterator id = addedIDs.begin();
+    for ( ; id != addedIDs.end(); ++id )
+    {
+      map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
+      int i = std::distance( _mapGroups.begin(), it );
+      TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]";
+    }
+  }
 }
 
 //=============================================================================
@@ -3066,7 +4173,7 @@ SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
 
 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
 {
-  SALOME_MED::MedFileInfo_var res( myFileInfo );
+  SALOME_MED::MedFileInfo_var res( _medFileInfo );
   if ( !res.operator->() ) {
     res = new SALOME_MED::MedFileInfo;
     res->fileName = "";
@@ -3077,7 +4184,7 @@ SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
 
 //=============================================================================
 /*!
- * \brief Check and correct names of mesh groups
+ * \brief Pass names of mesh groups from study to mesh DS
  */
 //=============================================================================
 
@@ -3120,8 +4227,9 @@ void SMESH_Mesh_i::checkGroupNames()
 //=============================================================================
 void SMESH_Mesh_i::SetParameters(const char* theParameters)
 {
-  SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
-                                               CORBA::string_dup(theParameters));
+  // SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
+  //                                              CORBA::string_dup(theParameters));
+  SMESH_Gen_i::GetSMESHGen()->UpdateParameters(theParameters);
 }
 
 //=============================================================================
@@ -3159,3 +4267,653 @@ SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
   }
   return aResult._retn();
 }
+
+//=======================================================================
+//function : GetTypes
+//purpose  : Returns types of elements it contains
+//=======================================================================
+
+SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
+{
+  if ( _preMeshInfo )
+    return _preMeshInfo->GetTypes();
+
+  SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
+
+  types->length( 5 );
+  int nbTypes = 0;
+  if (_impl->NbEdges())      types[nbTypes++] = SMESH::EDGE;
+  if (_impl->NbFaces())      types[nbTypes++] = SMESH::FACE;
+  if (_impl->NbVolumes())    types[nbTypes++] = SMESH::VOLUME;
+  if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
+  if (_impl->NbBalls())      types[nbTypes++] = SMESH::BALL;
+  types->length( nbTypes );
+
+  return types._retn();
+}
+
+//=======================================================================
+//function : GetMesh
+//purpose  : Returns self
+//=======================================================================
+
+SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
+{
+  return SMESH::SMESH_Mesh::_duplicate( _this() );
+}
+
+//=======================================================================
+//function : IsMeshInfoCorrect
+//purpose  : * Returns false if GetMeshInfo() returns incorrect information that may
+//           * happen if mesh data is not yet fully loaded from the file of study.
+//=======================================================================
+
+bool SMESH_Mesh_i::IsMeshInfoCorrect()
+{
+  return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
+}
+
+//=============================================================================
+/*!
+ * \brief Returns statistic of mesh elements
+ */
+//=============================================================================
+
+SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
+{
+  if ( _preMeshInfo )
+    return _preMeshInfo->GetMeshInfo();
+
+  SMESH::long_array_var aRes = new SMESH::long_array();
+  aRes->length(SMESH::Entity_Last);
+  for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
+    aRes[i] = 0;
+  SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
+  if (!aMeshDS)
+    return aRes._retn();
+  const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
+  for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
+    aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
+  return aRes._retn();
+}
+
+//=============================================================================
+/*!
+ * \brief Collect statistic of mesh elements given by iterator
+ */
+//=============================================================================
+
+void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
+                                   SMESH::long_array&         theInfo)
+{
+  if (!theItr) return;
+  while (theItr->more())
+    theInfo[ theItr->next()->GetEntityType() ]++;
+}
+
+//=============================================================================
+/*!
+ * \brief mapping of mesh dimension into shape type
+ */
+//=============================================================================
+
+static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
+{
+  TopAbs_ShapeEnum aType = TopAbs_SOLID;
+  switch ( theDim ) {
+  case 0: aType = TopAbs_VERTEX; break;
+  case 1: aType = TopAbs_EDGE; break;
+  case 2: aType = TopAbs_FACE; break;
+  case 3:
+  default:aType = TopAbs_SOLID; break;
+  }
+  return aType;
+}
+
+//=============================================================================
+/*!
+ * \brief Internal structure used to find concurent submeshes
+ *
+ * It represents a pair < submesh, concurent dimension >, where
+ * 'concurrent dimension' is dimension of shape where the submesh can concurent
+ *  with another submesh. In other words, it is dimension of a hypothesis assigned
+ *  to submesh.
+ */
+//=============================================================================
+
+class SMESH_DimHyp
+{
+ public:
+  //! fileds
+  int _dim;    //!< a dimension the algo can build (concurrent dimension)
+  int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
+  TopTools_MapOfShape _shapeMap;
+  SMESH_subMesh*      _subMesh;
+  list<const SMESHDS_Hypothesis*> _hypothesises; //!< algo is first, then its parameters
+
+  //! Constructors
+  SMESH_DimHyp(const SMESH_subMesh*  theSubMesh,
+               const int             theDim,
+               const TopoDS_Shape&   theShape)
+  {
+    _subMesh = (SMESH_subMesh*)theSubMesh;
+    SetShape( theDim, theShape );
+  }
+
+  //! set shape
+  void SetShape(const int           theDim,
+                const TopoDS_Shape& theShape)
+  {
+    _dim = theDim;
+    _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
+    if (_dim >= _ownDim)
+      _shapeMap.Add( theShape );
+    else {
+      TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
+      for( ; anExp.More(); anExp.Next() )
+        _shapeMap.Add( anExp.Current() );
+    }
+  }
+
+  //! Check sharing of sub-shapes
+  static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
+                               const TopTools_MapOfShape& theToFind,
+                               const TopAbs_ShapeEnum     theType)
+  {
+    bool isShared = false;
+    TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
+    for (; !isShared && anItr.More(); anItr.Next() )
+    {
+      const TopoDS_Shape aSubSh = anItr.Key();
+      // check for case when concurrent dimensions are same
+      isShared = theToFind.Contains( aSubSh );
+      // check for sub-shape with concurrent dimension
+      TopExp_Explorer anExp( aSubSh, theType );
+      for ( ; !isShared && anExp.More(); anExp.Next() )
+        isShared = theToFind.Contains( anExp.Current() );
+    }
+    return isShared;
+  }
+  
+  //! check algorithms
+  static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
+                        const SMESHDS_Hypothesis* theA2)
+  {
+    if ( theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
+         theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
+      return false; // one of the hypothesis is not algorithm
+    // check algorithm names (should be equal)
+    return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
+  }
+
+  
+  //! Check if sub-shape hypotheses are concurrent
+  bool IsConcurrent(const SMESH_DimHyp* theOther) const
+  {
+    if ( _subMesh == theOther->_subMesh )
+      return false; // same sub-shape - should not be
+
+    // if ( <own dim of either of submeshes> == <concurrent dim> &&
+    //      any of the two submeshes is not on COMPOUND shape )
+    //  -> no concurrency
+    bool meIsCompound = (_subMesh->GetSubMeshDS() && _subMesh->GetSubMeshDS()->IsComplexSubmesh());
+    bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() && theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
+    if ( (_ownDim == _dim  || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
+      return false;
+
+//     bool checkSubShape = ( _dim >= theOther->_dim )
+//       ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
+//       : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
+    bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
+    if ( !checkSubShape )
+        return false;
+
+    // check algorithms to be same
+    if (!checkAlgo( _hypothesises.front(), theOther->_hypothesises.front() ))
+      return true; // different algorithms
+    
+    // check hypothesises for concurrence (skip first as algorithm)
+    int nbSame = 0;
+    // pointers should be same, becase it is referenes from mesh hypothesis partition
+    list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypothesises.begin();
+    list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypothesises.end();
+    for ( hypIt++ /*skip first as algo*/; hypIt != _hypothesises.end(); hypIt++ )
+      if ( find( theOther->_hypothesises.begin(), otheEndIt, *hypIt ) != otheEndIt )
+        nbSame++;
+    // the submeshes are concurrent if their algorithms has different parameters
+    return nbSame != theOther->_hypothesises.size() - 1;
+  }
+  
+}; // end of SMESH_DimHyp
+
+typedef list<SMESH_DimHyp*> TDimHypList;
+
+static void addDimHypInstance(const int               theDim, 
+                              const TopoDS_Shape&     theShape,
+                              const SMESH_Algo*       theAlgo,
+                              const SMESH_subMesh*    theSubMesh,
+                              const list <const SMESHDS_Hypothesis*>& theHypList,
+                              TDimHypList*            theDimHypListArr )
+{
+  TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
+  if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
+    SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
+    listOfdimHyp.push_back( dimHyp );
+  }
+  
+  SMESH_DimHyp* dimHyp = listOfdimHyp.back();
+  dimHyp->_hypothesises.push_front(theAlgo);
+  list <const SMESHDS_Hypothesis*>::const_iterator hypIt = theHypList.begin();
+  for( ; hypIt != theHypList.end(); hypIt++ )
+    dimHyp->_hypothesises.push_back( *hypIt );
+}
+
+static void findConcurrents(const SMESH_DimHyp* theDimHyp,
+                            const TDimHypList&  theListOfDimHyp,
+                            TListOfInt&         theListOfConcurr )
+{
+  TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
+  for ( ; rIt != theListOfDimHyp.rend(); rIt++ ) {
+    const SMESH_DimHyp* curDimHyp = *rIt;
+    if ( curDimHyp == theDimHyp )
+      break; // meet own dimHyp pointer in same dimension
+    else if ( theDimHyp->IsConcurrent( curDimHyp ) )
+      if ( find( theListOfConcurr.begin(),
+                 theListOfConcurr.end(),
+                 curDimHyp->_subMesh->GetId() ) == theListOfConcurr.end() )
+        theListOfConcurr.push_back( curDimHyp->_subMesh->GetId() );
+  }
+}
+
+static void unionLists(TListOfInt&       theListOfId,
+                       TListOfListOfInt& theListOfListOfId,
+                       const int         theIndx )
+{
+  TListOfListOfInt::iterator it = theListOfListOfId.begin();
+  for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
+    if ( i < theIndx )
+      continue; //skip already treated lists
+    // check if other list has any same submesh object
+    TListOfInt& otherListOfId = *it;
+    if ( find_first_of( theListOfId.begin(), theListOfId.end(),
+                        otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
+      continue;
+         
+    // union two lists (from source into target)
+    TListOfInt::iterator it2 = otherListOfId.begin();
+    for ( ; it2 != otherListOfId.end(); it2++ ) {
+      if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
+        theListOfId.push_back(*it2);
+    }
+    // clear source list
+    otherListOfId.clear();
+  }
+}
+
+//! free memory allocated for dimension-hypothesis objects
+static void removeDimHyps( TDimHypList* theArrOfList )
+{
+  for (int i = 0; i < 4; i++ ) {
+    TDimHypList& listOfdimHyp = theArrOfList[i];
+    TDimHypList::const_iterator it = listOfdimHyp.begin();
+    for ( ; it != listOfdimHyp.end(); it++ )
+      delete (*it);
+  }
+}
+
+//=============================================================================
+/*!
+ * \brief Return submesh objects list in meshing order
+ */
+//=============================================================================
+
+SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
+{
+  SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
+
+  SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
+  if ( !aMeshDS )
+    return aResult._retn();
+  
+  ::SMESH_Mesh& mesh = GetImpl();
+  TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
+  if ( !anOrder.size() ) {
+
+    // collect submeshes detecting concurrent algorithms and hypothesises
+    TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
+    
+    map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
+    for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
+      ::SMESH_subMesh* sm = (*i_sm).second;
+      // shape of submesh
+      const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
+      
+      // list of assigned hypothesises
+      const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
+      // Find out dimensions where the submesh can be concurrent.
+      // We define the dimensions by algo of each of hypotheses in hypList
+      list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
+      for( ; hypIt != hypList.end(); hypIt++ ) {
+        SMESH_Algo* anAlgo = 0;
+        const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
+        if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
+          // hyp it-self is algo
+          anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
+        else {
+          // try to find algorithm with help of sub-shapes
+          TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
+          for ( ; !anAlgo && anExp.More(); anExp.Next() )
+            anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
+        }
+        if (!anAlgo)
+          continue; // no assigned algorithm to current submesh
+
+        int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
+        // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
+
+        // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
+        for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
+          addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
+      }
+    } // end iterations on submesh
+    
+    // iterate on created dimension-hypotheses and check for concurrents
+    for ( int i = 0; i < 4; i++ ) {
+      const list<SMESH_DimHyp*>& listOfDimHyp = dimHypListArr[i];
+      // check for concurrents in own and other dimensions (step-by-step)
+      TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
+      for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
+        const SMESH_DimHyp* dimHyp = *dhIt;
+        TListOfInt listOfConcurr;
+        // looking for concurrents and collect into own list
+        for ( int j = i; j < 4; j++ )
+          findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr );
+        // check if any concurrents found
+        if ( listOfConcurr.size() > 0 ) {
+          // add own submesh to list of concurrent
+          listOfConcurr.push_front( dimHyp->_subMesh->GetId() );
+          anOrder.push_back( listOfConcurr );
+        }
+      }
+    }
+    
+    removeDimHyps(dimHypListArr);
+    
+    // now, minimise the number of concurrent groups
+    // Here we assume that lists of submeshes can have same submesh
+    // in case of multi-dimension algorithms, as result
+    //  list with common submesh has to be united into one list
+    int listIndx = 0;
+    TListOfListOfInt::iterator listIt = anOrder.begin();
+    for(; listIt != anOrder.end(); listIt++, listIndx++ )
+      unionLists( *listIt,  anOrder, listIndx + 1 );
+  }
+  // convert submesh ids into interface instances
+  //  and dump command into python
+  convertMeshOrder( anOrder, aResult, false );
+
+  return aResult._retn();
+}
+
+//=============================================================================
+/*!
+ * \brief find common submeshes with given submesh
+ * \param theSubMeshList list of already collected submesh to check
+ * \param theSubMesh given submesh to intersect with other
+ * \param theCommonSubMeshes collected common submeshes
+ */
+//=============================================================================
+
+static void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
+                               const SMESH_subMesh*        theSubMesh,
+                               set<const SMESH_subMesh*>&  theCommon )
+{
+  if ( !theSubMesh )
+    return;
+  list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
+  for ( ; it != theSubMeshList.end(); it++ )
+    theSubMesh->FindIntersection( *it, theCommon );
+  theSubMeshList.push_back( theSubMesh );
+  //theCommon.insert( theSubMesh );
+}
+
+//=============================================================================
+/*!
+ * \brief Set submesh object order
+ * \param theSubMeshArray submesh array order
+ */
+//=============================================================================
+
+::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
+{
+  if ( _preMeshInfo )
+    _preMeshInfo->ForgetOrLoad();
+
+  bool res = false;
+  ::SMESH_Mesh& mesh = GetImpl();
+
+  TPythonDump aPythonDump; // prevent dump of called methods
+  aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
+
+  TListOfListOfInt subMeshOrder;
+  for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
+  {
+    const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
+    TListOfInt subMeshIds;
+    aPythonDump << "[ ";
+    // Collect subMeshes which should be clear
+    //  do it list-by-list, because modification of submesh order
+    //  take effect between concurrent submeshes only
+    set<const SMESH_subMesh*> subMeshToClear;
+    list<const SMESH_subMesh*> subMeshList;
+    for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
+    {
+      const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
+      if ( j > 0 )
+        aPythonDump << ", ";
+      aPythonDump << subMesh;
+      subMeshIds.push_back( subMesh->GetId() );
+      // detect common parts of submeshes
+      if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
+        findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
+    }
+    aPythonDump << " ]";
+    subMeshOrder.push_back( subMeshIds );
+
+    // clear collected submeshes
+    set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
+    for ( ; clrIt != subMeshToClear.end(); clrIt++ )
+      if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
+        sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
+  }
+  aPythonDump << " ])";
+
+  mesh.SetMeshOrder( subMeshOrder );
+  res = true;
+  
+  return res;
+}
+
+//=============================================================================
+/*!
+ * \brief Convert submesh ids into submesh interfaces
+ */
+//=============================================================================
+
+void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt&     theIdsOrder,
+                                     SMESH::submesh_array_array& theResOrder,
+                                     const bool                  theIsDump)
+{
+  int nbSet = theIdsOrder.size();
+  TPythonDump aPythonDump; // prevent dump of called methods
+  if ( theIsDump )
+    aPythonDump << "[ ";
+  theResOrder.length(nbSet);
+  TListOfListOfInt::const_iterator it = theIdsOrder.begin();
+  int listIndx = 0;
+  for( ; it != theIdsOrder.end(); it++ ) {
+    // translate submesh identificators into submesh objects
+    //  takeing into account real number of concurrent lists
+    const TListOfInt& aSubOrder = (*it);
+    if (!aSubOrder.size())
+      continue;
+    if ( theIsDump )
+      aPythonDump << "[ ";
+    // convert shape indeces into interfaces
+    SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
+    aResSubSet->length(aSubOrder.size());
+    TListOfInt::const_iterator subIt = aSubOrder.begin();
+    for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
+      if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
+        continue;
+      SMESH::SMESH_subMesh_var subMesh =
+        SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
+      if ( theIsDump ) {
+        if ( j > 0 )
+          aPythonDump << ", ";
+        aPythonDump << subMesh;
+      }
+      aResSubSet[ j++ ] = subMesh;
+    }
+    if ( theIsDump )
+      aPythonDump << " ]";
+    theResOrder[ listIndx++ ] = aResSubSet;
+  }
+  // correct number of lists
+  theResOrder.length( listIndx );
+
+  if ( theIsDump ) {
+    // finilise python dump
+    aPythonDump << " ]";
+    aPythonDump << " = " << _this() << ".GetMeshOrder()";
+  }
+}
+
+//================================================================================
+//
+// Implementation of SMESH_MeshPartDS
+//
+SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
+  SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
+{
+  SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
+  SMESH_Mesh_i*       mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
+
+  _meshDS = mesh_i->GetImpl().GetMeshDS();
+
+  SetPersistentId( _meshDS->GetPersistentId() );
+
+  if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
+  {
+    // <meshPart> is the whole mesh
+    myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
+    // copy groups
+    set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
+    myGroupSet = _meshDS->GetGroups();
+  }
+  else
+  {
+    TMeshInfo tmpInfo;
+    SMESH::long_array_var           anIDs = meshPart->GetIDs();
+    SMESH::array_of_ElementType_var types = meshPart->GetTypes();
+    if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
+    {
+      for (int i=0; i < anIDs->length(); i++)
+        if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
+          if ( _elements[ SMDSAbs_Node ].insert( n ).second )
+            tmpInfo.Add( n );
+    }
+    else
+    {
+      for (int i=0; i < anIDs->length(); i++)
+        if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
+          if ( _elements[ e->GetType() ].insert( e ).second )
+          {
+            tmpInfo.Add( e );
+            SMDS_ElemIteratorPtr nIt = e->nodesIterator();
+            while ( nIt->more() )
+            {
+              const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
+              if ( _elements[ SMDSAbs_Node ].insert( n ).second )
+                tmpInfo.Add( n );
+            }
+          }
+    }
+    myInfo = tmpInfo;
+
+    _meshDS = 0; // to enforce iteration on _elements and _nodes
+  }
+}
+// -------------------------------------------------------------------------------------
+SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
+{
+  if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
+
+  typedef SMDS_SetIterator
+    <const SMDS_MeshElement*,
+    TIDSortedElemSet::const_iterator,
+    SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
+    SMDS_MeshElement::GeomFilter
+    > TIter;
+
+  SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
+
+  return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
+                                          _elements[type].end(),
+                                          SMDS_MeshElement::GeomFilter( geomType )));
+}
+// -------------------------------------------------------------------------------------
+SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
+{
+  if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
+
+  typedef SMDS_SetIterator
+    <const SMDS_MeshElement*,
+    TIDSortedElemSet::const_iterator,
+    SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
+    SMDS_MeshElement::EntityFilter
+    > TIter;
+
+  SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
+
+  return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
+                                          _elements[type].end(),
+                                          SMDS_MeshElement::EntityFilter( entity )));
+}
+// -------------------------------------------------------------------------------------
+SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
+{
+  typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
+  if ( type == SMDSAbs_All && !_meshDS )
+  {
+    typedef vector< SMDS_ElemIteratorPtr > TIterVec;
+    TIterVec iterVec;
+    for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
+      if ( !_elements[i].empty() && i != SMDSAbs_Node )
+        iterVec.push_back
+          ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
+
+    typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
+    return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
+  }
+  return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
+      ( new TIter( _elements[type].begin(), _elements[type].end() ));
+}
+// -------------------------------------------------------------------------------------
+#define _GET_ITER_DEFINE( iterType, methName, elem, elemType)                       \
+  iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const                 \
+  {                                                                                 \
+    typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
+    return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType                 \
+      ( new TIter( _elements[elemType].begin(), _elements[elemType].end() ));       \
+  }
+// -------------------------------------------------------------------------------------
+_GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
+_GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
+_GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
+_GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
+#undef _GET_ITER_DEFINE
+//
+// END Implementation of SMESH_MeshPartDS
+//
+//================================================================================
index 32fe2153dbdfeeca1f3d7836b835f05bd04cdd6b..3c13916a4592e4b26ccf628b28be849c1b2f7961 100644 (file)
@@ -1,29 +1,28 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : SMESH_Mesh_i.hxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//
+
 #ifndef _SMESH_MESH_I_HXX_
 #define _SMESH_MESH_I_HXX_
 
@@ -46,6 +45,7 @@
 class SMESH_Gen_i;
 class SMESH_GroupBase_i;
 class SMESH_subMesh_i;
+class SMESH_PreMeshInfo;
 
 #include <map>
 
@@ -58,7 +58,7 @@ class SMESH_I_EXPORT SMESH_Mesh_i:
 public:
   SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
                 SMESH_Gen_i*            myGen_i,
-               CORBA::Long             studyId );
+                CORBA::Long             studyId );
 
   virtual ~SMESH_Mesh_i();
 
@@ -72,6 +72,12 @@ public:
   GEOM::GEOM_Object_ptr GetShapeToMesh()
     throw (SALOME::SALOME_Exception);
 
+  CORBA::Boolean IsLoaded()
+    throw (SALOME::SALOME_Exception);
+
+  void Load()
+    throw (SALOME::SALOME_Exception);
+
   void Clear()
     throw (SALOME::SALOME_Exception);
 
@@ -89,6 +95,9 @@ public:
   SMESH::ListOfHypothesis* GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
     throw (SALOME::SALOME_Exception);
 
+  SMESH::submesh_array* GetSubMeshes()
+    throw (SALOME::SALOME_Exception);
+
   SMESH::SMESH_subMesh_ptr GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject, const char* theName)
     throw (SALOME::SALOME_Exception);
 
@@ -97,59 +106,64 @@ public:
 
   SMESH::SMESH_Group_ptr CreateGroup( SMESH::ElementType theElemType, const char* theName )
     throw (SALOME::SALOME_Exception);
-  
+
   SMESH::SMESH_GroupOnGeom_ptr CreateGroupFromGEOM(SMESH::ElementType    theElemType,
                                                    const char*           theName,
                                                    GEOM::GEOM_Object_ptr theGeomObj )
     throw (SALOME::SALOME_Exception);
 
+  SMESH::SMESH_GroupOnFilter_ptr CreateGroupFromFilter(SMESH::ElementType theElemType,
+                                                       const char*        theName,
+                                                       SMESH::Filter_ptr  theFilter )
+    throw (SALOME::SALOME_Exception);
+
   void RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
     throw (SALOME::SALOME_Exception);
-  
+
   void RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
     throw (SALOME::SALOME_Exception);
-  
+
   SMESH::ListOfGroups* GetGroups()
     throw (SALOME::SALOME_Exception);
 
   CORBA::Long NbGroups()
     throw (SALOME::SALOME_Exception);
 
-  SMESH::SMESH_Group_ptr UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1, 
-                                      SMESH::SMESH_GroupBase_ptr theGroup2, 
+  SMESH::SMESH_Group_ptr UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
+                                      SMESH::SMESH_GroupBase_ptr theGroup2,
                                       const char* theName )
     throw (SALOME::SALOME_Exception);
 
-  SMESH::SMESH_Group_ptr UnionListOfGroups( const SMESH::ListOfGroups& theGroups, 
+  SMESH::SMESH_Group_ptr UnionListOfGroups( const SMESH::ListOfGroups& theGroups,
                                             const char* theName)
     throw (SALOME::SALOME_Exception);
-  
-  SMESH::SMESH_Group_ptr IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1, 
-                                          SMESH::SMESH_GroupBase_ptr theGroup2, 
+
+  SMESH::SMESH_Group_ptr IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
+                                          SMESH::SMESH_GroupBase_ptr theGroup2,
                                           const char* theName )
     throw (SALOME::SALOME_Exception);
 
-  SMESH::SMESH_Group_ptr IntersectListOfGroups( const SMESH::ListOfGroups&  theGroups, 
+  SMESH::SMESH_Group_ptr IntersectListOfGroups( const SMESH::ListOfGroups&  theGroups,
                                                 const char* theName )
     throw (SALOME::SALOME_Exception);
-  
-  SMESH::SMESH_Group_ptr CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1, 
-                                    SMESH::SMESH_GroupBase_ptr theGroup2, 
+
+  SMESH::SMESH_Group_ptr CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
+                                    SMESH::SMESH_GroupBase_ptr theGroup2,
                                     const char* theName )
     throw (SALOME::SALOME_Exception);
 
-  SMESH::SMESH_Group_ptr CutListOfGroups( const SMESH::ListOfGroups& theMainGroups, 
-                                          const SMESH::ListOfGroups& theToolGroups, 
+  SMESH::SMESH_Group_ptr CutListOfGroups( const SMESH::ListOfGroups& theMainGroups,
+                                          const SMESH::ListOfGroups& theToolGroups,
                                           const char* theName )
   throw (SALOME::SALOME_Exception);
 
-  SMESH::SMESH_Group_ptr CreateDimGroup( const SMESH::ListOfGroups& theGroups, 
-                                         SMESH::ElementType theElemType, 
+  SMESH::SMESH_Group_ptr CreateDimGroup( const SMESH::ListOfGroups& theGroups,
+                                         SMESH::ElementType theElemType,
                                          const char* theName )
   throw (SALOME::SALOME_Exception);
-  
 
-  SMESH::SMESH_Group_ptr ConvertToStandalone( SMESH::SMESH_GroupOnGeom_ptr theGeomGroup );
+
+  SMESH::SMESH_Group_ptr ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroupOn );
 
 //    SMESH::string_array* GetLog(CORBA::Boolean clearAfterGet)
 //      throw (SALOME::SALOME_Exception);
@@ -161,6 +175,8 @@ public:
 
   SMESH::SMESH_MeshEditor_ptr GetMeshEditPreviewer();
 
+  CORBA::Boolean HasModificationsToDiscard() throw (SALOME::SALOME_Exception);
+
   void ClearLog()
     throw (SALOME::SALOME_Exception);
 
@@ -188,6 +204,11 @@ public:
   SMESH::DriverMED_ReadStatus ImportMEDFile( const char* theFileName, const char* theMeshName )
     throw (SALOME::SALOME_Exception);
 
+  SMESH::DriverMED_ReadStatus ImportCGNSFile( const char*  theFileName,
+                                              const int    theMeshIndex,
+                                              std::string& theMeshName)
+    throw (SALOME::SALOME_Exception);
+
   /*!
    *  Auto color
    */
@@ -206,17 +227,37 @@ public:
    */
   char* GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits);
 
-  void ExportToMED( const char* file, CORBA::Boolean auto_groups, SMESH::MED_VERSION theVersion )
-    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);
-  void ExportSTL( const char* file, bool isascii )
-    throw (SALOME::SALOME_Exception);
+  void ExportToMEDX( const char*        file,
+                     CORBA::Boolean     auto_groups,
+                     SMESH::MED_VERSION version,
+                     CORBA::Boolean     overwrite ) throw (SALOME::SALOME_Exception);
+  void ExportToMED ( const char*        file,
+                     CORBA::Boolean     auto_groups,
+                     SMESH::MED_VERSION version ) throw (SALOME::SALOME_Exception);
+  void ExportMED   ( const char*        file,
+                     CORBA::Boolean     auto_groups ) throw (SALOME::SALOME_Exception);
+
+  void ExportSAUV( 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);
+  void ExportSTL( const char* file, bool isascii ) throw (SALOME::SALOME_Exception);
+  void ExportCGNS(SMESH::SMESH_IDSource_ptr meshPart,
+                  const char*               file,
+                  CORBA::Boolean            overwrite) throw (SALOME::SALOME_Exception);
+
+  void ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
+                       const char*               file,
+                       CORBA::Boolean            auto_groups,
+                       SMESH::MED_VERSION        version,
+                       CORBA::Boolean            overwrite) throw (SALOME::SALOME_Exception);
+  void ExportPartToDAT(SMESH::SMESH_IDSource_ptr meshPart,
+                       const char*               file) throw (SALOME::SALOME_Exception);
+  void ExportPartToUNV(SMESH::SMESH_IDSource_ptr meshPart,
+                       const char*               file) throw (SALOME::SALOME_Exception);
+  void ExportPartToSTL(SMESH::SMESH_IDSource_ptr meshPart,
+                       const char*               file,
+                       CORBA::Boolean            isascii) throw (SALOME::SALOME_Exception);
 
   SALOME_MED::MESH_ptr GetMEDMesh()
     throw (SALOME::SALOME_Exception);
@@ -227,6 +268,12 @@ public:
   CORBA::Long NbElements()
     throw (SALOME::SALOME_Exception);
 
+  CORBA::Long Nb0DElements()
+    throw (SALOME::SALOME_Exception);
+
+  CORBA::Long NbBalls()
+    throw (SALOME::SALOME_Exception);
+
   CORBA::Long NbEdges()
     throw (SALOME::SALOME_Exception);
 
@@ -251,6 +298,9 @@ public:
   CORBA::Long NbQuadranglesOfOrder(SMESH::ElementOrder order)
     throw (SALOME::SALOME_Exception);
 
+  CORBA::Long NbBiQuadQuadrangles()
+    throw (SALOME::SALOME_Exception);
+
   CORBA::Long NbPolygons()
     throw (SALOME::SALOME_Exception);
 
@@ -272,6 +322,9 @@ public:
   CORBA::Long NbHexasOfOrder(SMESH::ElementOrder order)
     throw (SALOME::SALOME_Exception);
 
+  CORBA::Long NbTriQuadraticHexas()
+    throw (SALOME::SALOME_Exception);
+
   CORBA::Long NbPyramids()
     throw (SALOME::SALOME_Exception);
 
@@ -284,6 +337,9 @@ public:
   CORBA::Long NbPrismsOfOrder(SMESH::ElementOrder order)
     throw (SALOME::SALOME_Exception);
 
+  CORBA::Long NbHexagonalPrisms()
+    throw (SALOME::SALOME_Exception);
+
   CORBA::Long NbPolyhedrons()
     throw (SALOME::SALOME_Exception);
 
@@ -295,13 +351,16 @@ public:
 
   SMESH::long_array* GetElementsByType( SMESH::ElementType theElemType )
     throw (SALOME::SALOME_Exception);
-  
+
   SMESH::long_array* GetNodesId()
     throw (SALOME::SALOME_Exception);
-  
+
   SMESH::ElementType GetElementType( CORBA::Long id, bool iselem )
     throw (SALOME::SALOME_Exception);
-  
+
+  SMESH::EntityType GetElementGeomType( CORBA::Long id )
+    throw (SALOME::SALOME_Exception);
+
   /*!
    * Returns ID of elements for given submesh
    */
@@ -315,15 +374,15 @@ public:
    */
   SMESH::long_array* GetSubMeshNodesId(CORBA::Long ShapeID, CORBA::Boolean all)
     throw (SALOME::SALOME_Exception);
-  
+
   /*!
    * Returns type of elements for given submesh
    */
   SMESH::ElementType GetSubMeshElementType(CORBA::Long ShapeID)
     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_Object_ptr aSubShapeObject,
@@ -331,22 +390,23 @@ public:
 
   SMESH_Hypothesis::Hypothesis_Status removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
                                                        SMESH::SMESH_Hypothesis_ptr anHyp);
-  
+
   static SMESH::Hypothesis_Status
   ConvertHypothesisStatus (SMESH_Hypothesis::Hypothesis_Status theStatus);
 
-  static void PrepareForWriting (const char* file);
+  static void PrepareForWriting (const char* file, bool overwrite = true);
 
   //int importMEDFile( const char* theFileName, const char* theMeshName );
 
   SMESH::SMESH_subMesh_ptr createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject );
 
-  void removeSubMesh(SMESH::SMESH_subMesh_ptr theSubMesh,
+  bool removeSubMesh(SMESH::SMESH_subMesh_ptr theSubMesh,
                      GEOM::GEOM_Object_ptr theSubShapeObject );
 
-  SMESH::SMESH_GroupBase_ptr createGroup(SMESH::ElementType  theElemType,
-                                         const char*         theName,
-                                         const TopoDS_Shape& theShape = TopoDS_Shape());
+  SMESH::SMESH_GroupBase_ptr createGroup(SMESH::ElementType        theElemType,
+                                         const char*               theName,
+                                         const TopoDS_Shape&       theShape = TopoDS_Shape(),
+                                         const SMESH_PredicatePtr& thePred = SMESH_PredicatePtr());
 
   void removeGroup( const int theId );
 
@@ -356,15 +416,18 @@ public:
   const std::map<int, SMESH::SMESH_GroupBase_ptr>& getGroups() { return _mapGroups; }
   // return an existing group object.
 
+  void onHypothesisModified();
+  // callback from _impl to forget not loaded mesh data (issue 0021208)
+
+  void checkMeshLoaded();
+
   /*!
    * \brief Update hypotheses assigned to geom groups if the latter change
-   * 
+   *
    * NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation"
    */
   void CheckGeomGroupModif();
 
-  virtual SMESH::long_array* GetIDs();
-
   CORBA::LongLong GetMeshPtr();
 
   /*!
@@ -382,7 +445,7 @@ public:
    * If there is not node for given ID - returns empty list
    */
   SMESH::double_array* GetNodeXYZ(CORBA::Long id);
-  
+
   /*!
    * For given node returns list of IDs of inverse elements
    * If there is not node for given ID - returns empty list
@@ -401,7 +464,7 @@ public:
   CORBA::Long GetShapeID(CORBA::Long id);
 
   /*!
-   * For given element returns ID of result shape after 
+   * For given element returns ID of result shape after
    * ::FindShape() from SMESH_MeshEditor
    * If there is not element for given ID - returns -1
    */
@@ -424,40 +487,54 @@ public:
    * If there is not node for given index - returns -2
    */
   CORBA::Long GetElemNode(CORBA::Long id, CORBA::Long index);
-  
+
   /*!
    * Returns true if given node is medium node
    * in given quadratic element
    */
   CORBA::Boolean IsMediumNode(CORBA::Long ide, CORBA::Long idn);
-  
+
   /*!
    * Returns true if given node is medium node
    * in one of quadratic elements
    */
   CORBA::Boolean IsMediumNodeOfAnyElem(CORBA::Long idn,
                                        SMESH::ElementType theElemType);
-  
+
   /*!
    * Returns number of edges for given element
    */
   CORBA::Long ElemNbEdges(CORBA::Long id);
-  
+
   /*!
    * Returns number of faces for given element
    */
   CORBA::Long ElemNbFaces(CORBA::Long id);
-  
+  /*!
+   * Returns nodes of given face (counted from zero) for given element.
+   */
+  SMESH::long_array* GetElemFaceNodes(CORBA::Long elemId, CORBA::Short faceIndex);
+
+  /*!
+   * Returns an element based on all given nodes.
+   */
+  CORBA::Long FindElementByNodes(const SMESH::long_array& nodes);
+
   /*!
    * Returns true if given element is polygon
    */
   CORBA::Boolean IsPoly(CORBA::Long id);
-  
+
   /*!
    * Returns true if given element is quadratic
    */
   CORBA::Boolean IsQuadratic(CORBA::Long id);
-  
+
+  /*!
+   * Returns diameter of ball discrete element or zero in case of an invalid \a id
+   */
+  CORBA::Double GetBallDiameter(CORBA::Long id);
+
   /*!
    * Returns bary center for given element
    */
@@ -472,7 +549,7 @@ public:
    * Sets list of notebook variables used for Mesh operations separated by ":" symbol
    */
   void SetParameters (const char* theParameters);
-  
+
   /*!
    * Returns list of notebook variables used for Mesh operations separated by ":" symbol
    */
@@ -482,28 +559,108 @@ public:
    * Returns list of notebook variables used for last Mesh operation
    */
   SMESH::string_array* GetLastParameters();
-  
+
+  /*!
+   * Collect statistic of mesh elements given by iterator
+   */
+  static void CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
+                              SMESH::long_array&         theInfo);
+
+  /*!
+   * \brief Return submesh objects list in meshing order
+   */
+  virtual SMESH::submesh_array_array* GetMeshOrder();
+  /*!
+   * \brief Set submesh object order
+   */
+  virtual ::CORBA::Boolean SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray);
+
+
+  // =========================
+  // SMESH_IDSource interface
+  // =========================
+
+  virtual SMESH::long_array* GetIDs();
+  /*!
+   * Returns statistic of mesh elements
+   * Result array of number enityties
+   * Inherited from SMESH_IDSource
+   */
+  virtual SMESH::long_array* GetMeshInfo();
+  /*!
+   * Returns types of elements it contains
+   */
+  virtual SMESH::array_of_ElementType* GetTypes();
+  /*!
+   * Returns self
+   */
+  virtual SMESH::SMESH_Mesh_ptr GetMesh();
+  /*!
+   * Returns false if GetMeshInfo() returns incorrect information that may
+   * happen if mesh data is not yet fully loaded from the file of study.
+   */
+  bool IsMeshInfoCorrect();
+
   std::map<int, SMESH_subMesh_i*> _mapSubMesh_i; //NRI
   std::map<int, ::SMESH_subMesh*> _mapSubMesh;   //NRI
 
 private:
+  std::string prepareMeshNameAndGroups( const char* file, CORBA::Boolean overwrite );
+
   /*!
    * Check and correct names of mesh groups
    */
   void checkGroupNames();
 
+  /*!
+   * Convert submesh ids into submesh interfaces
+   */
+  void convertMeshOrder(const TListOfListOfInt&     theIdsOrder,
+                        SMESH::submesh_array_array& theSubMeshOrder,
+                        const bool                  theIsDump);
+
 private:
 
-  static int myIdGenerator;
-  ::SMESH_Mesh* _impl;  // :: force no namespace here
-  SMESH_Gen_i* _gen_i;
-  int _id;          // id given by creator (unique within the creator instance)
-  int _studyId;
+  static int    _idGenerator;
+  ::SMESH_Mesh* _impl;        // :: force no namespace here
+  SMESH_Gen_i*  _gen_i;
+  int           _id;          // id given by creator (unique within the creator instance)
+  int           _studyId;
   std::map<int, SMESH::SMESH_subMesh_ptr>    _mapSubMeshIor;
   std::map<int, SMESH::SMESH_GroupBase_ptr>  _mapGroups;
   std::map<int, SMESH::SMESH_Hypothesis_ptr> _mapHypo;
-  SALOME_MED::MedFileInfo_var myFileInfo;
+  SALOME_MED::MedFileInfo_var _medFileInfo;
+  SMESH_PreMeshInfo*          _preMeshInfo; // mesh info before full loading from study file
+
+  SMESH_PreMeshInfo* & changePreMeshInfo() { return _preMeshInfo; }
+  friend class SMESH_PreMeshInfo;
+
+private:
+
+  // Data used to track changes of GEOM groups
+  struct TGeomGroupData {
+    // keep study entry but not ior because GEOM_Object actually changes if
+    // number of items in a group varies (1) <-> (>1)
+    std::string       _groupEntry;
+    std::set<int>     _indices; // indices of group items within group's main shape
+    CORBA::Object_ptr _smeshObject; // SMESH object depending on GEOM group
+  };
+  std::list<TGeomGroupData> _geomGroupData;
+
+  /*!
+   * Remember GEOM group data
+   */
+  void addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
+                        CORBA::Object_ptr     theSmeshObj);
+  /*!
+   * Remove GEOM group data relating to removed smesh object
+   */
+  void removeGeomGroupData(CORBA::Object_ptr theSmeshObj);
+  /*!
+   * \brief Return new group contents if it has been changed and update group data
+   */
+  TopoDS_Shape newGroupShape( TGeomGroupData & groupData);
+
 };
 
 #endif
-
index bd7268049430ef85fee519a2b0f295ed32ce01ac..7ecbe082382a2b20eb9677cdae5093d6a59c5810 100644 (file)
@@ -1,12 +1,11 @@
-// Copyright (C) 2008  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // 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
+// 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.
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File      : SMESH_NoteBook.cxx
 // Author    : Roman NIKOLAEV
-
+//
 #include "SMESH_2smeshpy.hxx"
 #include "SMESH_NoteBook.hxx"
 #include "SMESH_Gen_i.hxx"
 #include "SMESH_PythonDump.hxx"
+#include "SMESH_Hypothesis_i.hxx"
 
 #include <Resource_DataMapOfAsciiStringAsciiString.hxx>
 #include <TColStd_SequenceOfAsciiString.hxx>
@@ -41,14 +42,28 @@ static int MYDEBUG = 0;
 using namespace std;
 
 
-void SetVariable(Handle(_pyCommand) theCommand,const ObjectStates* theStates, int position, int theArgNb);
+namespace
+{
+  /*!
+   *  Set variable of the SMESH_ObjectStates from position to the _pyCommand
+   *  method as nbArg argument
+   */
+  void SetVariable(Handle(_pyCommand) theCommand,
+                   const SMESH_ObjectStates* theStates,
+                   int position, int theArgNb)
+  {
+    if(theStates->GetCurrectState().size() > position)
+      if(!theStates->GetCurrectState().at(position).IsEmpty())
+        theCommand->SetArg(theArgNb,theStates->GetCurrectState().at(position));
+  }
+}
 
 //================================================================================
 /*!
  * \brief Constructor
  */
 //================================================================================
-ObjectStates::ObjectStates(TCollection_AsciiString theType)
+SMESH_ObjectStates::SMESH_ObjectStates(TCollection_AsciiString theType)
 {
   _type = theType;
   _dumpstate = 0;
@@ -59,7 +74,7 @@ ObjectStates::ObjectStates(TCollection_AsciiString theType)
  * \brief Destructor
  */
 //================================================================================
-ObjectStates::~ObjectStates()
+SMESH_ObjectStates::~SMESH_ObjectStates()
 {
 }
 
@@ -69,7 +84,7 @@ ObjectStates::~ObjectStates()
  * \param theState - Object state (vector of notebook variable)
  */
 //================================================================================
-void ObjectStates::AddState(const TState &theState)
+void SMESH_ObjectStates::AddState(const TState &theState)
 {
   _states.push_back(theState);
 }
@@ -80,7 +95,7 @@ void ObjectStates::AddState(const TState &theState)
  * \\retval state - Object state (vector of notebook variable)
  */
 //================================================================================
-TState ObjectStates::GetCurrectState() const
+TState SMESH_ObjectStates::GetCurrectState() const
 {
   if(_states.size() > _dumpstate)
     return _states[_dumpstate];
@@ -94,7 +109,7 @@ TState ObjectStates::GetCurrectState() const
  *
  */
 //================================================================================
-TAllStates ObjectStates::GetAllStates() const
+TAllStates SMESH_ObjectStates::GetAllStates() const
 {
   return _states;
 }
@@ -104,7 +119,7 @@ TAllStates ObjectStates::GetAllStates() const
  *
  */
 //================================================================================
-void ObjectStates::IncrementState()
+void SMESH_ObjectStates::IncrementState()
 {
   _dumpstate++;
 }
@@ -114,7 +129,7 @@ void ObjectStates::IncrementState()
  *
  */
 //================================================================================
-TCollection_AsciiString ObjectStates::GetObjectType() const{
+TCollection_AsciiString SMESH_ObjectStates::GetObjectType() const{
   return _type;
 }
 
@@ -125,7 +140,7 @@ TCollection_AsciiString ObjectStates::GetObjectType() const{
  */
 //================================================================================
 LayerDistributionStates::LayerDistributionStates():
-  ObjectStates("LayerDistribution")
+  SMESH_ObjectStates("LayerDistribution")
 {
 }
 //================================================================================
@@ -229,7 +244,7 @@ void SMESH_NoteBook::ReplaceVariables()
       cout<<"Object : "<< aObject<<endl;
       cout<<"Result : "<< aResultValue<<endl;
     }
-    
+
     // check if method modifies the object itself
     TVariablesMap::const_iterator it = _objectMap.find(aObject);
     if(it == _objectMap.end()) // check if method returns a new object
@@ -239,22 +254,23 @@ void SMESH_NoteBook::ReplaceVariables()
       TMeshEditorMap::const_iterator meIt = myMeshEditors.find(aObject);
       if(meIt != myMeshEditors.end()) {
         TCollection_AsciiString aMesh = (*meIt).second;
-       it = _objectMap.find(aMesh);
+        it = _objectMap.find(aMesh);
       }
     }
     
     if(it == _objectMap.end()) { // additional check for pattern mapping
       if(aMethod.IsEqual("ApplyToMeshFaces") ||
-        aMethod.IsEqual("ApplyToHexahedrons"))
-       it = _objectMap.find(aCmd->GetArg(1));
+         aMethod.IsEqual("ApplyToHexahedrons"))
+        it = _objectMap.find(aCmd->GetArg(1));
     }
-    
+
     if(it != _objectMap.end()) {
       if(MYDEBUG)
-       cout << "Found object : " << (*it).first << endl;
-      ObjectStates *aStates = (*it).second;
+        cout << "Found object : " << (*it).first << endl;
+      SMESH_ObjectStates *aStates = (*it).second;
       // Case for LocalLength hypothesis
-      if(aStates->GetObjectType().IsEqual("LocalLength") && aStates->GetCurrectState().size() >= 2) {
+      if(aStates->GetObjectType().IsEqual("LocalLength") && aStates->GetCurrectState().size() >= 2)
+      {
         if(aMethod.IsEqual("SetLength")) {
           if(!aStates->GetCurrectState().at(0).IsEmpty() )
             aCmd->SetArg(1,aStates->GetCurrectState().at(0));
@@ -326,57 +342,6 @@ void SMESH_NoteBook::ReplaceVariables()
           aStates->IncrementState();
         }
       }
-
-      // Case for NETGEN_Parameters_2D or NETGEN_Parameters_2D hypothesis
-      else if(aStates->GetObjectType().IsEqual("NETGEN_Parameters_2D") ||
-              aStates->GetObjectType().IsEqual("NETGEN_Parameters")){
-        if(aMethod == "SetMaxSize" && aStates->GetCurrectState().size() >= 1) {
-          if(!aStates->GetCurrectState().at(0).IsEmpty() )
-            aCmd->SetArg(1,aStates->GetCurrectState().at(0));
-          aStates->IncrementState();
-        }
-        else if(aMethod == "SetGrowthRate" && aStates->GetCurrectState().size() >= 2) {
-          if(!aStates->GetCurrectState().at(1).IsEmpty() )
-            aCmd->SetArg(1,aStates->GetCurrectState().at(1));
-          aStates->IncrementState();
-        }
-        else if(aMethod == "SetNbSegPerEdge" && aStates->GetCurrectState().size() >= 3) {
-          if(!aStates->GetCurrectState().at(2).IsEmpty() )
-            aCmd->SetArg(1,aStates->GetCurrectState().at(2));
-          aStates->IncrementState();
-        } 
-        else if(aMethod == "SetNbSegPerRadius" && aStates->GetCurrectState().size() >= 4) {
-          if(!aStates->GetCurrectState().at(3).IsEmpty() )
-            aCmd->SetArg(1,aStates->GetCurrectState().at(3));
-          aStates->IncrementState();
-        } 
-      }
-
-      // Case for NETGEN_SimpleParameters_3D or NETGEN_SimpleParameters_2D hypothesis
-      else if(aStates->GetObjectType().IsEqual("NETGEN_SimpleParameters_3D") ||
-              aStates->GetObjectType().IsEqual("NETGEN_SimpleParameters_2D")){
-
-        if((aMethod == "SetNumberOfSegments" || aMethod == "SetLocalLength") && 
-           aStates->GetCurrectState().size() >= 1) {
-          if(!aStates->GetCurrectState().at(0).IsEmpty() )
-            aCmd->SetArg(1,aStates->GetCurrectState().at(0));
-          aStates->IncrementState();
-        }
-        else if(aMethod == "SetMaxElementArea" && aStates->GetCurrectState().size() >= 2) {
-          if(!aStates->GetCurrectState().at(1).IsEmpty() )
-            aCmd->SetArg(1,aStates->GetCurrectState().at(1));
-          aStates->IncrementState();
-        }
-        else if(aMethod == "SetMaxElementVolume" && aStates->GetCurrectState().size() >= 3) {
-          if(!aStates->GetCurrectState().at(2).IsEmpty() )
-            aCmd->SetArg(1,aStates->GetCurrectState().at(2));
-          aStates->IncrementState();
-        }
-        else if(aMethod == "LengthFromEdges" || aMethod == "LengthFromFaces"){
-          aStates->IncrementState();
-        }
-      }
-      
       // Case for NumberOfLayers hypothesis
       else if(aStates->GetObjectType().IsEqual("NumberOfLayers")){
         if(aMethod == "SetNumberOfLayers" && aStates->GetCurrectState().size() >= 1) {
@@ -402,9 +367,9 @@ void SMESH_NoteBook::ReplaceVariables()
       }
       
       else if(aStates->GetObjectType().IsEqual("Mesh")) {
-       TState aCurrentState = aStates->GetCurrectState();
+        TState aCurrentState = aStates->GetCurrectState();
         int aCurrentStateSize = aCurrentState.size();
-       if(aMethod.IsEqual("Translate")                  ||
+        if(aMethod.IsEqual("Translate")                  ||
            aMethod.IsEqual("TranslateMakeGroups")        ||
            aMethod.IsEqual("TranslateMakeMesh")          ||
            aMethod.IsEqual("TranslateObject")            ||
@@ -419,211 +384,284 @@ void SMESH_NoteBook::ReplaceVariables()
             }
           }
           if(anArgIndex > 0) {
-           if(aCurrentStateSize == 3) { // translation by dx, dy, dz
-             for(int j = 0; j < aCurrentStateSize; j++) {
-               if(!aCurrentState.at(j).IsEmpty()) {
-                 isVariableFound = true;
-                 aCmd->SetArg(anArgIndex+j, aCurrentState.at(j));
-               }
-             }
-           }
-           else if(aCurrentStateSize == 6) { // translation by x1, x2, y1, y2, z1, z2
-             // TODO: limitation until operations on the variables will be introduced
-             /*
-             isVariableFound = true;
-             for(int j = 0; j < 3; j++) {
-               TCollection_AsciiString anArg = aCmd->GetArg(anArgIndex+j);
-               TCollection_AsciiString aValue1 = aCurrentState.at(2*j), aValue2 = aCurrentState.at(2*j+1);
-               bool aV1 = !aValue1.IsEmpty();
-               bool aV2 = !aValue2.IsEmpty();
-               double aValue, aCurrentValue = anArg.IsRealValue() ? anArg.RealValue() : 0;
-               if(aV1 && !aV2) {
-                 if(!GetReal(aValue1, aValue))
-                   aValue = 0;
-                 aValue2 = TCollection_AsciiString( aValue + aCurrentValue );
-               }
-               else if(!aV1 && aV2) {
-                 if(!GetReal(aValue2, aValue))
-                   aValue = 0;
-                 aValue1 = TCollection_AsciiString( aValue - aCurrentValue );
-               }
-               else if(!aV1 && !aV2) {
-                 aValue1 = TCollection_AsciiString( 0 );
-                 aValue2 = TCollection_AsciiString( aCurrentValue );
-               }
-               aCmd->SetArg(anArgIndex+j, aValue1 + ", " + aValue2 );
-             }
-             */
-           }
+            if(aCurrentStateSize == 3) { // translation by dx, dy, dz
+              for(int j = 0; j < aCurrentStateSize; j++) {
+                if(!aCurrentState.at(j).IsEmpty()) {
+                  isVariableFound = true;
+                  aCmd->SetArg(anArgIndex+j, aCurrentState.at(j));
+                }
+              }
+            }
+            else if(aCurrentStateSize == 6) { // translation by x1, x2, y1, y2, z1, z2
+              // TODO: limitation until operations on the variables will be introduced
+              /*
+              isVariableFound = true;
+              for(int j = 0; j < 3; j++) {
+                TCollection_AsciiString anArg = aCmd->GetArg(anArgIndex+j);
+                TCollection_AsciiString aValue1 = aCurrentState.at(2*j), aValue2 = aCurrentState.at(2*j+1);
+                bool aV1 = !aValue1.IsEmpty();
+                bool aV2 = !aValue2.IsEmpty();
+                double aValue, aCurrentValue = anArg.IsRealValue() ? anArg.RealValue() : 0;
+                if(aV1 && !aV2) {
+                  if(!GetReal(aValue1, aValue))
+                    aValue = 0;
+                  aValue2 = TCollection_AsciiString( aValue + aCurrentValue );
+                }
+                else if(!aV1 && aV2) {
+                  if(!GetReal(aValue2, aValue))
+                    aValue = 0;
+                  aValue1 = TCollection_AsciiString( aValue - aCurrentValue );
+                }
+                else if(!aV1 && !aV2) {
+                  aValue1 = TCollection_AsciiString( 0 );
+                  aValue2 = TCollection_AsciiString( aCurrentValue );
+                }
+                aCmd->SetArg(anArgIndex+j, aValue1 + ", " + aValue2 );
+              }
+              */
+            }
           }
           if(isVariableFound) {
             TCollection_AsciiString aDim;
-           if(aCurrentStateSize == 6)
-             aDim = "6";
+            if(aCurrentStateSize == 6)
+              aDim = "6";
             aCmd->SetArg(anArgIndex - 1, TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".PointStructStr"+aDim);
             aCmd->SetArg(anArgIndex - 2, TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".DirStructStr");
           }
           aStates->IncrementState();
         }
-       else if(aMethod.IsEqual("Rotate")                  ||
-               aMethod.IsEqual("RotateMakeGroups")        ||
-               aMethod.IsEqual("RotateMakeMesh")          ||
+        else if(aMethod.IsEqual("Rotate")                  ||
+                aMethod.IsEqual("RotateMakeGroups")        ||
+                aMethod.IsEqual("RotateMakeMesh")          ||
                 aMethod.IsEqual("RotateObject")            ||
                 aMethod.IsEqual("RotateObjectMakeGroups")  ||
                 aMethod.IsEqual("RotateObjectMakeMesh")    ||
-               aMethod.IsEqual("RotationSweep")           ||
-               aMethod.IsEqual("RotationSweepObject")     ||
-               aMethod.IsEqual("RotationSweepObject1D")   ||
-               aMethod.IsEqual("RotationSweepObject2D")   ||
-               aMethod.IsEqual("RotationSweepMakeGroups") ||
-               aMethod.IsEqual("RotationSweepObjectMakeGroups") ||
-               aMethod.IsEqual("RotationSweepObject1DMakeGroups") ||
-               aMethod.IsEqual("RotationSweepObject2DMakeGroups") ||
-               aMethod.IsEqual("Mirror")                  ||
-               aMethod.IsEqual("MirrorMakeMesh")          ||
+                aMethod.IsEqual("RotationSweep")           ||
+                aMethod.IsEqual("RotationSweepObject")     ||
+                aMethod.IsEqual("RotationSweepObject1D")   ||
+                aMethod.IsEqual("RotationSweepObject2D")   ||
+                aMethod.IsEqual("RotationSweepMakeGroups") ||
+                aMethod.IsEqual("RotationSweepObjectMakeGroups") ||
+                aMethod.IsEqual("RotationSweepObject1DMakeGroups") ||
+                aMethod.IsEqual("RotationSweepObject2DMakeGroups") ||
+                aMethod.IsEqual("Mirror")                  ||
+                aMethod.IsEqual("MirrorMakeMesh")          ||
                 aMethod.IsEqual("MirrorMakeGroups")        ||
                 aMethod.IsEqual("MirrorObject")            || 
                 aMethod.IsEqual("MirrorObjectMakeMesh")    ||
                 aMethod.IsEqual("MirrorObjectMakeGroups")) {
-         bool isSubstitute = false;
-         int anArgIndex = 0;
-         for(int i = 1, n = aCmd->GetNbArgs(); i <= n; i++) {
-           if(aCmd->GetArg(i).IsEqual("SMESH.AxisStruct")) {
-             anArgIndex = i+1;
-             break;
-           }
-         }
-         if(anArgIndex > 0) {
-           for(int j = 0; j < aCurrentStateSize; j++) {
-             if(!aCurrentState.at(j).IsEmpty()) {
-               if(j < 6) // 0-5 - axis struct, 6 - angle (rotation & sweep), 7-8 - nbSteps and tolerance (sweep)
-                 isSubstitute = true;
-               aCmd->SetArg(anArgIndex+j, aCurrentState.at(j));
-             }
-           }
-         }
-         if(isSubstitute)
-           aCmd->SetArg(anArgIndex - 1, TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".AxisStructStr");
-         aStates->IncrementState();
-       }
-       else if(aMethod.IsEqual("AddNode") ||
-               aMethod.IsEqual("MoveClosestNodeToPoint")) {
-         for(int j = 0; j < aCurrentStateSize; j++) {
-           if(!aCurrentState.at(j).IsEmpty())
-             aCmd->SetArg(j+1, aCurrentState.at(j));
-         }
-         aStates->IncrementState();
-       }
-       else if(aMethod.IsEqual("MoveNode")) {
-         for(int j = 0; j < aCurrentStateSize; j++) {
-           if(!aCurrentState.at(j).IsEmpty())
-             aCmd->SetArg(j+2, aCurrentState.at(j));
-         }
-         aStates->IncrementState();
-       }
-       else if(aMethod.IsEqual("ExtrusionSweep") ||
-               aMethod.IsEqual("ExtrusionSweepObject") ||
-               aMethod.IsEqual("ExtrusionSweepObject1D") ||
-               aMethod.IsEqual("ExtrusionSweepObject2D") ||
-               aMethod.IsEqual("ExtrusionSweepMakeGroups") ||
-               aMethod.IsEqual("ExtrusionSweepObjectMakeGroups") ||
-               aMethod.IsEqual("ExtrusionSweepObject1DMakeGroups") ||
-               aMethod.IsEqual("ExtrusionSweepObject2DMakeGroups")) {
-         bool isSubstitute = false;
-         int anArgIndex = 0;
-         for(int i = 1, n = aCmd->GetNbArgs(); i <= n; i++) {
-           if(aCmd->GetArg(i).IsEqual("SMESH.PointStruct")) {
-             anArgIndex = i+1;
-             break;
-           }
-         }
-         if(anArgIndex > 0) {
-           for(int j = 0; j < aCurrentStateSize; j++) {
-             if(!aCurrentState.at(j).IsEmpty()) {
-               if(j < 3) // 0-2 - dir struct, 3 - number of steps
-                 isSubstitute = true;
-               aCmd->SetArg(anArgIndex+j, aCurrentState.at(j));
-             }
-           }
-         }
-         if(isSubstitute) {
+          bool isSubstitute = false;
+          int anArgIndex = 0;
+          for(int i = 1, n = aCmd->GetNbArgs(); i <= n; i++) {
+            if(aCmd->GetArg(i).IsEqual("SMESH.AxisStruct")) {
+              anArgIndex = i+1;
+              break;
+            }
+          }
+          if(anArgIndex > 0) {
+            for(int j = 0; j < aCurrentStateSize; j++) {
+              if(!aCurrentState.at(j).IsEmpty()) {
+                if(j < 6) // 0-5 - axis struct, 6 - angle (rotation & sweep), 7-8 - nbSteps and tolerance (sweep)
+                  isSubstitute = true;
+                aCmd->SetArg(anArgIndex+j, aCurrentState.at(j));
+              }
+            }
+          }
+          if(isSubstitute)
+            aCmd->SetArg(anArgIndex - 1, TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".AxisStructStr");
+          aStates->IncrementState();
+        }
+        else if(aMethod.IsEqual("AddNode") ||
+                aMethod.IsEqual("MoveClosestNodeToPoint")) {
+          for(int j = 0; j < aCurrentStateSize; j++) {
+            if(!aCurrentState.at(j).IsEmpty())
+              aCmd->SetArg(j+1, aCurrentState.at(j));
+          }
+          aStates->IncrementState();
+        }
+        else if(aMethod.IsEqual("MoveNode")) {
+          for(int j = 0; j < aCurrentStateSize; j++) {
+            if(!aCurrentState.at(j).IsEmpty())
+              aCmd->SetArg(j+2, aCurrentState.at(j));
+          }
+          aStates->IncrementState();
+        }
+        else if(aMethod.IsEqual("ExtrusionSweep") ||
+                aMethod.IsEqual("ExtrusionSweepObject") ||
+                aMethod.IsEqual("ExtrusionSweepObject1D") ||
+                aMethod.IsEqual("ExtrusionSweepObject2D") ||
+                aMethod.IsEqual("ExtrusionSweepMakeGroups") ||
+                aMethod.IsEqual("ExtrusionSweepObjectMakeGroups") ||
+                aMethod.IsEqual("ExtrusionSweepObject1DMakeGroups") ||
+                aMethod.IsEqual("ExtrusionSweepObject2DMakeGroups")) {
+          bool isSubstitute = false;
+          int anArgIndex = 0;
+          for(int i = 1, n = aCmd->GetNbArgs(); i <= n; i++) {
+            if(aCmd->GetArg(i).IsEqual("SMESH.PointStruct")) {
+              anArgIndex = i+1;
+              break;
+            }
+          }
+          if(anArgIndex > 0) {
+            for(int j = 0; j < aCurrentStateSize; j++) {
+              if(!aCurrentState.at(j).IsEmpty()) {
+                if(j < 3) // 0-2 - dir struct, 3 - number of steps
+                  isSubstitute = true;
+                aCmd->SetArg(anArgIndex+j, aCurrentState.at(j));
+              }
+            }
+          }
+          if(isSubstitute) {
             aCmd->SetArg(anArgIndex - 1, TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".PointStructStr");
             aCmd->SetArg(anArgIndex - 2, TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".DirStructStr");
-         }
-         aStates->IncrementState();
-       }
-       else if(aMethod.IsEqual("ExtrusionAlongPath") ||
-               aMethod.IsEqual("ExtrusionAlongPathObject") ||
-               aMethod.IsEqual("ExtrusionAlongPathObject1D") ||
-               aMethod.IsEqual("ExtrusionAlongPathObject2D") ||
-               aMethod.IsEqual("ExtrusionAlongPathMakeGroups") ||
-               aMethod.IsEqual("ExtrusionAlongPathObjectMakeGroups") ||
-               aMethod.IsEqual("ExtrusionAlongPathObject1DMakeGroups") ||
-               aMethod.IsEqual("ExtrusionAlongPathObject2DMakeGroups") ||
-               /* workaround for a bug in the command parsing algorithm */
-               aCmd->GetString().Search("ExtrusionAlongPathMakeGroups") != -1 ||
-               aCmd->GetString().Search("ExtrusionAlongPathObjectMakeGroups") != -1 ||
-               aCmd->GetString().Search("ExtrusionAlongPathObject1DMakeGroups") != -1 ||
-               aCmd->GetString().Search("ExtrusionAlongPathObject2DMakeGroups") != -1 ) {
-         int aNbAngles = aCurrentStateSize-3; // State looks like "Angle1:...:AngleN:X:Y:Z"
-         bool isSubstitute = false;
-         int anArgIndex = 0;
-         for(int i = 1, n = aCmd->GetNbArgs(); i <= n; i++) {
-           if(aCmd->GetArg(i).IsEqual("SMESH.PointStruct")) {
-             anArgIndex = i-1-aNbAngles;
-             break;
-           }
-         }
-         if(anArgIndex > 0) {
-           int j = 0;
-           for(; j < aNbAngles; j++) {
-             if(!aCurrentState.at(j).IsEmpty()) {
-               aCmd->SetArg(anArgIndex+j-1, aCurrentState.at(j));
-             }
-           }
-           for(; j < aNbAngles+3; j++) {
-             if(!aCurrentState.at(j).IsEmpty()) {
-               isSubstitute = true;
-               aCmd->SetArg(anArgIndex+j+2, aCurrentState.at(j));
-             }
-           }
-         }
-         if(isSubstitute)
-           aCmd->SetArg(anArgIndex + aNbAngles + 1,
-                        TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".PointStructStr");
-         aStates->IncrementState();
-       }
-       else if(aMethod.IsEqual("TriToQuad") ||
-               aMethod.IsEqual("Concatenate") ||
-               aMethod.IsEqual("ConcatenateWithGroups")) {
-         if(aCurrentStateSize && !aCurrentState.at(0).IsEmpty())
-           aCmd->SetArg(aCmd->GetNbArgs(), aCurrentState.at(0));
-         aStates->IncrementState();
-       }
-       else if(aMethod.IsEqual("Smooth") ||
-               aMethod.IsEqual("SmoothObject") ||
-               aMethod.IsEqual("SmoothParametric") ||
-               aMethod.IsEqual("SmoothParametricObject")) {
-         int anArgIndex = aCmd->GetNbArgs() - 2;
-         for(int j = 0; j < aCurrentStateSize; j++) {
-           if(!aCurrentState.at(j).IsEmpty())
-             aCmd->SetArg(anArgIndex+j, aCurrentState.at(j));
-         }
-         aStates->IncrementState();
-       }
-       else if(aMethod.IsEqual("ApplyToMeshFaces") ||
-               aMethod.IsEqual("ApplyToHexahedrons")) {
-         int anArgIndex = aCmd->GetNbArgs()-1;
-         for(int j = 0; j < aCurrentStateSize; j++)
-           if(!aCurrentState.at(j).IsEmpty())
-             aCmd->SetArg(anArgIndex+j, aCurrentState.at(j));
-         aStates->IncrementState();
-       }
+          }
+          aStates->IncrementState();
+        }
+        else if(aMethod.IsEqual("ExtrusionAlongPath") ||
+                aMethod.IsEqual("ExtrusionAlongPathObject") ||
+                aMethod.IsEqual("ExtrusionAlongPathObject1D") ||
+                aMethod.IsEqual("ExtrusionAlongPathObject2D") ||
+                aMethod.IsEqual("ExtrusionAlongPathMakeGroups") ||
+                aMethod.IsEqual("ExtrusionAlongPathObjectMakeGroups") ||
+                aMethod.IsEqual("ExtrusionAlongPathObject1DMakeGroups") ||
+                aMethod.IsEqual("ExtrusionAlongPathObject2DMakeGroups") ||
+                /* workaround for a bug in the command parsing algorithm */
+                aCmd->GetString().Search("ExtrusionAlongPathMakeGroups") != -1 ||
+                aCmd->GetString().Search("ExtrusionAlongPathObjectMakeGroups") != -1 ||
+                aCmd->GetString().Search("ExtrusionAlongPathObject1DMakeGroups") != -1 ||
+                aCmd->GetString().Search("ExtrusionAlongPathObject2DMakeGroups") != -1 ) {
+          int aNbAngles = aCurrentStateSize-3; // State looks like "Angle1:...:AngleN:X:Y:Z"
+          bool isSubstitute = false;
+          int anArgIndex = 0;
+          for(int i = 1, n = aCmd->GetNbArgs(); i <= n; i++) {
+            if(aCmd->GetArg(i).IsEqual("SMESH.PointStruct")) {
+              anArgIndex = i-1-aNbAngles;
+              break;
+            }
+          }
+          if(anArgIndex > 0) {
+            int j = 0;
+            for(; j < aNbAngles; j++) {
+              if(!aCurrentState.at(j).IsEmpty()) {
+                aCmd->SetArg(anArgIndex+j-1, aCurrentState.at(j));
+              }
+            }
+            for(; j < aNbAngles+3; j++) {
+              if(!aCurrentState.at(j).IsEmpty()) {
+                isSubstitute = true;
+                aCmd->SetArg(anArgIndex+j+2, aCurrentState.at(j));
+              }
+            }
+          }
+          if(isSubstitute)
+            aCmd->SetArg(anArgIndex + aNbAngles + 1,
+                         TCollection_AsciiString(SMESH_2smeshpy::SmeshpyName())+".PointStructStr");
+          aStates->IncrementState();
+        }
+        else if(aMethod.IsEqual("TriToQuad") ||
+                aMethod.IsEqual("Concatenate") ||
+                aMethod.IsEqual("ConcatenateWithGroups")) {
+          if(aCurrentStateSize && !aCurrentState.at(0).IsEmpty())
+            aCmd->SetArg(aCmd->GetNbArgs(), aCurrentState.at(0));
+          aStates->IncrementState();
+        }
+        else if(aMethod.IsEqual("Smooth") ||
+                aMethod.IsEqual("SmoothObject") ||
+                aMethod.IsEqual("SmoothParametric") ||
+                aMethod.IsEqual("SmoothParametricObject")) {
+          int anArgIndex = aCmd->GetNbArgs() - 2;
+          for(int j = 0; j < aCurrentStateSize; j++) {
+            if(!aCurrentState.at(j).IsEmpty())
+              aCmd->SetArg(anArgIndex+j, aCurrentState.at(j));
+          }
+          aStates->IncrementState();
+        }
+        else if(aMethod.IsEqual("ApplyToMeshFaces") ||
+                aMethod.IsEqual("ApplyToHexahedrons")) {
+          int anArgIndex = aCmd->GetNbArgs()-1;
+          for(int j = 0; j < aCurrentStateSize; j++)
+            if(!aCurrentState.at(j).IsEmpty())
+              aCmd->SetArg(anArgIndex+j, aCurrentState.at(j));
+          aStates->IncrementState();
+        }
+      } // if ( aStates->GetObjectType().IsEqual("Mesh"))
+
+      // Case for NETGEN_Parameters_2D or NETGEN_Parameters_2D hypothesis
+      // else if(aStates->GetObjectType().IsEqual("NETGEN_Parameters_2D") ||
+      //         aStates->GetObjectType().IsEqual("NETGEN_Parameters")){
+      //   if(aMethod == "SetMaxSize" && aStates->GetCurrectState().size() >= 1) {
+      //     if(!aStates->GetCurrectState().at(0).IsEmpty() )
+      //       aCmd->SetArg(1,aStates->GetCurrectState().at(0));
+      //     aStates->IncrementState();
+      //   }
+      //   else if(aMethod == "SetGrowthRate" && aStates->GetCurrectState().size() >= 2) {
+      //     if(!aStates->GetCurrectState().at(1).IsEmpty() )
+      //       aCmd->SetArg(1,aStates->GetCurrectState().at(1));
+      //     aStates->IncrementState();
+      //   }
+      //   else if(aMethod == "SetNbSegPerEdge" && aStates->GetCurrectState().size() >= 3) {
+      //     if(!aStates->GetCurrectState().at(2).IsEmpty() )
+      //       aCmd->SetArg(1,aStates->GetCurrectState().at(2));
+      //     aStates->IncrementState();
+      //   }
+      //   else if(aMethod == "SetNbSegPerRadius" && aStates->GetCurrectState().size() >= 4) {
+      //     if(!aStates->GetCurrectState().at(3).IsEmpty() )
+      //       aCmd->SetArg(1,aStates->GetCurrectState().at(3));
+      //     aStates->IncrementState();
+      //   }
+      // }
+
+      // // Case for NETGEN_SimpleParameters_3D or NETGEN_SimpleParameters_2D hypothesis
+      // else if(aStates->GetObjectType().IsEqual("NETGEN_SimpleParameters_3D") ||
+      //         aStates->GetObjectType().IsEqual("NETGEN_SimpleParameters_2D")) {
+
+      //   if((aMethod == "SetNumberOfSegments" || aMethod == "SetLocalLength") && 
+      //      aStates->GetCurrectState().size() >= 1) {
+      //     if(!aStates->GetCurrectState().at(0).IsEmpty() )
+      //       aCmd->SetArg(1,aStates->GetCurrectState().at(0));
+      //     aStates->IncrementState();
+      //   }
+      //   else if(aMethod == "SetMaxElementArea" && aStates->GetCurrectState().size() >= 2) {
+      //     if(!aStates->GetCurrectState().at(1).IsEmpty() )
+      //       aCmd->SetArg(1,aStates->GetCurrectState().at(1));
+      //     aStates->IncrementState();
+      //   }
+      //   else if(aMethod == "SetMaxElementVolume" && aStates->GetCurrectState().size() >= 3) {
+      //     if(!aStates->GetCurrectState().at(2).IsEmpty() )
+      //       aCmd->SetArg(1,aStates->GetCurrectState().at(2));
+      //     aStates->IncrementState();
+      //   }
+      //   else if(aMethod == "LengthFromEdges" || aMethod == "LengthFromFaces"){
+      //     aStates->IncrementState();
+      //   }
+      // }
+
+      else
+      {
+        // treat Netgen hypotheses;
+        // this (and above) code can work wrong since nb of states can differ from nb of
+        // dumped calls due to the fix of
+        // issue 0021364:: Dump of netgen parameters has duplicate lines
+        SMESH_Gen_i *aGen = SMESH_Gen_i::GetSMESHGen();
+        SALOMEDS::Study_ptr aStudy = aGen->GetCurrentStudy();
+        SALOMEDS::SObject_var sobj = aStudy->FindObjectID( (*it).first.ToCString() );
+        CORBA::Object_var      obj = aGen->SObjectToObject( sobj );
+        if ( SMESH_Hypothesis_i* h = SMESH::DownCast< SMESH_Hypothesis_i*>( obj ))
+        {
+          TState aCurrentState = aStates->GetCurrectState();
+          int argIndex = h->getParamIndex( aMethod, aCurrentState.size() );
+          if ( 0 <= argIndex && argIndex < aCurrentState.size() &&
+               !aCurrentState[argIndex].IsEmpty() )
+            aCmd->SetArg( 1, aCurrentState[argIndex] );
+
+          if ( argIndex >= 0 )
+            aStates->IncrementState();
+        }
       }
     }
     else {
       if(MYDEBUG)
-       cout << "Object not found" << endl;
+        cout << "Object not found" << endl;
     }
     if(MYDEBUG) {
       cout<<"Command after: "<< aCmd->GetString()<<endl;
@@ -664,31 +702,32 @@ void SMESH_NoteBook::InitObjectMap()
         cout<<"aParameters : "<<aParameters<<endl;
       }      
       TCollection_AsciiString anObjType;
-      CORBA::Object_var anObject = SMESH_Gen_i::SObjectToObject(aSObject);
+      CORBA::Object_var       anObject = SMESH_Gen_i::SObjectToObject(aSObject);
       SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow(anObject);
+      SMESH::SMESH_Mesh_var      aMesh = SMESH::SMESH_Mesh::_narrow(anObject);
       if(!aHyp->_is_nil()) {
-        anObjType = TCollection_AsciiString(aHyp->GetName());
+        CORBA::String_var hypName = aHyp->GetName();
+        anObjType = hypName.in();
       }
-      else if(SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(anObject)) {
-        anObjType = TCollection_AsciiString("Mesh");
+      else if (!aMesh->_is_nil() ) {
+        anObjType = "Mesh";
       }
       if(MYDEBUG)
         cout<<"The object Type : "<<anObjType<<endl;
-      ObjectStates *aState = NULL;
-      if(anObjType == "LayerDistribution") {
+      SMESH_ObjectStates *aState = NULL;
+      if(anObjType == "LayerDistribution")
         aState = new LayerDistributionStates();
-      }
       else
-        aState = new  ObjectStates(anObjType);
-      
+        aState = new  SMESH_ObjectStates(anObjType);
+
       for(int i = 0; i < aSections->length(); i++) {
         TState aVars;
         SALOMEDS::ListOfStrings aListOfVars = aSections[i];
         for(int j = 0;j<aListOfVars.length();j++) {
           TCollection_AsciiString aVar(aListOfVars[j].in());
           if(!aVar.IsEmpty() && aStudy->IsVariable(aVar.ToCString())) {
-            aVar.InsertBefore(1,"\"");
-            aVar.InsertAfter(aVar.Length(),"\"");
+            aVar.InsertBefore(1,            SMESH::TVar::Quote() );
+            aVar.InsertAfter(aVar.Length(), SMESH::TVar::Quote() );
           }
           aVars.push_back(aVar);
           if(MYDEBUG) {
@@ -697,7 +736,15 @@ void SMESH_NoteBook::InitObjectMap()
         }
         aState->AddState(aVars);
       }
-      _objectMap.insert(pair<TCollection_AsciiString,ObjectStates*>(TCollection_AsciiString(aSObject->GetID()),aState));
+      if ( aState->GetAllStates().empty() )
+      {
+        delete aState;
+      }
+      else
+      {
+        CORBA::String_var objID = aSObject->GetID();
+        _objectMap.insert( make_pair(TCollection_AsciiString( objID.in() ), aState ));
+      }
     }
   }
 }
@@ -716,7 +763,7 @@ void SMESH_NoteBook::AddCommand(const TCollection_AsciiString& theString)
 
   if ( aCommand->GetMethod() == "GetMeshEditor" ) { // MeshEditor creation
     myMeshEditors.insert( make_pair( aCommand->GetResultValue(),
-                                    aCommand->GetObject() ) );
+                                     aCommand->GetObject() ) );
   }
 }
 
@@ -848,14 +895,3 @@ bool SMESH_NoteBook::GetReal(const TCollection_AsciiString& theVarName, double&
   return ok;
 }
 
-
-/*!
- *  Set variable of the ObjectStates from position to the _pyCommand
- *  method as nbArg argument
- */
-void SetVariable(Handle(_pyCommand) theCommand, const ObjectStates* theStates, int position, int theArgNb)
-{
-  if(theStates->GetCurrectState().size() > position)
-    if(!theStates->GetCurrectState().at(position).IsEmpty())
-      theCommand->SetArg(theArgNb,theStates->GetCurrectState().at(position));
-}
index dfeb3b50a23123e704fce386104e7b1b8b6bf0c0..661f42f496a41b24e9abb7dfbb7f5f11000de7d5 100644 (file)
@@ -1,12 +1,11 @@
-// Copyright (C) 2008  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // 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
+// 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.
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File      : SMESH_NoteBook.hxx
 // Author    : Roman NIKOLAEV ()
-
-
+//
 #ifndef SMESH_NoteBook_HeaderFile
 #define SMESH_NoteBook_HeaderFile
 
+// All this stuff is obsolete since issue 0021308:
+// "Remove hard-coded dependency of the external mesh plugins from the SMESH module"
+// is implemented (Mar 2012). It is kept for backward compatibility only.
+
 #include <TCollection_AsciiString.hxx>
 #include <Resource_DataMapOfAsciiStringAsciiString.hxx>
  
@@ -34,14 +37,14 @@ class _pyCommand;
 
 typedef std::vector<TCollection_AsciiString>  TState;
 typedef std::vector<TState>                   TAllStates;
-typedef TCollection_AsciiString _pyID;
+typedef TCollection_AsciiString               _pyID;
 
-class ObjectStates{
+class SMESH_ObjectStates{
   
 public:
   
-  ObjectStates(TCollection_AsciiString theType);
-  virtual ~ObjectStates();
+  SMESH_ObjectStates(TCollection_AsciiString theType);
+  virtual ~SMESH_ObjectStates();
 
   void AddState(const TState &theState);
 
@@ -58,7 +61,7 @@ private:
   int                                       _dumpstate;
 };
 
-class LayerDistributionStates : public ObjectStates
+class LayerDistributionStates : public SMESH_ObjectStates
 {
 public:
   typedef std::map<TCollection_AsciiString,TCollection_AsciiString> TDistributionMap;
@@ -81,7 +84,7 @@ private:
 class SMESH_NoteBook
 {
 public:
-  typedef std::map<TCollection_AsciiString,ObjectStates*> TVariablesMap;
+  typedef std::map<TCollection_AsciiString,SMESH_ObjectStates*> TVariablesMap;
   typedef std::map<TCollection_AsciiString,TCollection_AsciiString> TMeshEditorMap;
   SMESH_NoteBook();
   ~SMESH_NoteBook();
index b96a8d95452d8dffb8af233911ac17ebe72f6a84..b1a3d0c354e15d84a384a152403004a092fa7f5d 100644 (file)
@@ -1,29 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 // File      : SMESH_Pattern_i.cxx
 // Created   : Fri Aug 20 16:15:49 2004
 // Author    : Edward AGAPOV (eap)
-//  $Header: 
 //
 #include "SMESH_Pattern_i.hxx"
 
@@ -46,6 +46,7 @@
 #include <set>
 
 using SMESH::TPythonDump;
+using SMESH::TVar;
 
 //=======================================================================
 //function : dumpErrorCode
@@ -149,7 +150,7 @@ CORBA::Boolean SMESH_Pattern_i::LoadFromFace(SMESH::SMESH_Mesh_ptr theMesh,
     return false;
 
   // Update Python script
-  TPythonDump() << "isDone = pattern.LoadFromFace( " << theMesh << ", "
+  TPythonDump() << "isDone = pattern.LoadFromFace( " << theMesh << ".GetMesh(), "
                 << theFace << ", " << theProject << " )";
   addErrorCode( "LoadFromFace" );
 
@@ -180,7 +181,7 @@ CORBA::Boolean SMESH_Pattern_i::LoadFrom3DBlock(SMESH::SMESH_Mesh_ptr theMesh,
     return false;
 
   // Update Python script
-  TPythonDump() << "isDone = pattern.LoadFrom3DBlock( " << theMesh << ", " << theBlock << " )";
+  TPythonDump() << "isDone = pattern.LoadFrom3DBlock( " << theMesh << ".GetMesh(), " << theBlock << " )";
   addErrorCode( "LoadFrom3DBlock" );
 
   return myPattern.Load( aMesh, TopoDS::Shell( exp.Current() ));
@@ -214,7 +215,6 @@ SMESH::point_array* SMESH_Pattern_i::ApplyToFace(GEOM::GEOM_Object_ptr theFace,
       (*xyzIt)->Coord( p.x, p.y, p.z );
     }
   }
-
   // Update Python script
   TPythonDump() << "pattern.ApplyToFace( " << theFace << ", "
                 << theVertexOnKeyPoint1 << ", " << theReverse << " )";
@@ -316,9 +316,9 @@ SMESH::point_array*
   }
 
   // Update Python script
-  TPythonDump() << "pattern.ApplyToMeshFaces( " << theMesh << ", "
+  TPythonDump() << "pattern.ApplyToMeshFaces( " << theMesh << ".GetMesh(), "
                 << theFacesIDs << ", "
-                << theNodeIndexOnKeyPoint1 << ", " << theReverse << " )";
+                << TVar( theNodeIndexOnKeyPoint1 ) << ", " << theReverse << " )";
 
   return points._retn();
 }
@@ -361,9 +361,9 @@ SMESH::point_array*
   }
 
   // Update Python script
-  TPythonDump() << "pattern.ApplyToHexahedrons( " << theMesh << ", "
+  TPythonDump() << "pattern.ApplyToHexahedrons( " << theMesh << ".GetMesh(), "
                 << theVolumesIDs << ", "
-                << theNode000Index << ", " << theNode001Index << " )";
+                << TVar(theNode000Index) << ", " << TVar(theNode001Index) << " )";
 
   return points._retn();
 }
@@ -382,11 +382,20 @@ CORBA::Boolean SMESH_Pattern_i::MakeMesh (SMESH::SMESH_Mesh_ptr theMesh,
     return false;
 
   // Update Python script
-  TPythonDump() << "isDone = pattern.MakeMesh( " << theMesh << ", "
+  TPythonDump() << "isDone = pattern.MakeMesh( " << theMesh << ".GetMesh(), "
                 << CreatePolygons << ", " << CreatePolyedrs << " )";
   addErrorCode( "MakeMesh" );
 
-  return myPattern.MakeMesh( aMesh, CreatePolygons, CreatePolyedrs );
+  int nb = aMesh->NbNodes() + aMesh->NbEdges() + aMesh->NbFaces() + aMesh->NbVolumes();
+
+  bool res = myPattern.MakeMesh( aMesh, CreatePolygons, CreatePolyedrs );
+
+  if ( nb > 0 && nb != aMesh->NbNodes() + aMesh->NbEdges() + aMesh->NbFaces() + aMesh->NbVolumes())
+    {
+      aMesh->SetIsModified(true);
+      aMesh->GetMeshDS()->Modified();
+    }
+  return res;
 }
 
 //=======================================================================
index 8526ef9ad405d4e5b61043b1af675ea70605ad79..b363ac10d075d707b0adbbe9278ccbbc5e895d20 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 // File      : SMESH_Pattern_i.hxx
 // Created   : Fri Aug 20 16:03:15 2004
diff --git a/src/SMESH_I/SMESH_PreMeshInfo.cxx b/src/SMESH_I/SMESH_PreMeshInfo.cxx
new file mode 100644 (file)
index 0000000..e56adfa
--- /dev/null
@@ -0,0 +1,1278 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+// File      : SMESH_PreMeshInfo.cxx
+// Created   : Fri Feb 10 17:36:39 2012
+// Author    : Edward AGAPOV (eap)
+//
+
+#include "SMESH_PreMeshInfo.hxx"
+
+#include "DriverMED_R_SMESHDS_Mesh.h"
+#include "SMDS_EdgePosition.hxx"
+#include "SMDS_FacePosition.hxx"
+#include "SMDS_SpacePosition.hxx"
+#include "SMDS_VertexPosition.hxx"
+#include "SMESHDS_Group.hxx"
+#include "SMESHDS_GroupOnFilter.hxx"
+#include "SMESH_Gen_i.hxx"
+#include "SMESH_Group_i.hxx"
+#include "SMESH_Mesh_i.hxx"
+#include "SMESH_subMesh_i.hxx"
+
+#include <HDFarray.hxx>
+#include <HDFdataset.hxx>
+#include <HDFfile.hxx>
+#include <HDFgroup.hxx>
+#include <MED_Factory.hxx>
+#include <SALOMEDS_Tool.hxx>
+
+#include <Standard_ErrorHandler.hxx>
+#include <Standard_Failure.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS_Shape.hxx>
+
+#include CORBA_SERVER_HEADER(SALOME_Session)
+
+#define MYDEBUGOUT(msg) //std::cout << msg << std::endl;
+
+//================================================================================
+#define PreMeshInfo_TRY \
+  try { OCC_CATCH_SIGNALS
+//================================================================================
+#define PreMeshInfo_CATCH }                                             \
+  catch (Standard_Failure& ex) {                                        \
+    onExceptionCaught(SMESH_Comment("OCC Exception caught: \t")<<ex.GetMessageString()); \
+  }                                                                     \
+  catch ( const std::exception& ex) {                                   \
+    onExceptionCaught(SMESH_Comment("Exception caught: \t")<<ex.what()); \
+  }                                                                     \
+  catch (...) {                                                         \
+    onExceptionCaught("Unknown Exception caught");                      \
+  }
+//================================================================================
+
+namespace
+{
+  enum {  GroupOnFilter_OutOfDate = -1 };
+
+  // a map to count not yet loaded meshes 
+  static map< int, int > theStudyIDToMeshCounter;
+
+  //================================================================================
+  /*!
+   * \brief Counts not fully loaded meshes
+   */
+  //================================================================================
+
+  void meshInfoLoaded( SMESH_Mesh_i* mesh )
+  {
+    map< int, int >::iterator id2counter =
+      theStudyIDToMeshCounter.insert( make_pair( (int) mesh->GetStudyId(), 0 )).first;
+    id2counter->second++;
+  }
+  //================================================================================
+  /*!
+   * \brief Removes temporary files if none of meshes needs them
+   */
+  //================================================================================
+
+  void filesNoMoreNeeded(SMESH_Mesh_i* mesh,
+                         std::string   medFile,
+                         std::string   hdfFile)
+  {
+    if ( --theStudyIDToMeshCounter[ (int) mesh->GetStudyId() ] == 0 )
+    {
+      string tmpDir = SALOMEDS_Tool::GetDirFromPath( hdfFile );
+
+      SALOMEDS::ListOfFileNames_var aFiles = new SALOMEDS::ListOfFileNames;
+      aFiles->length(2);
+      medFile = SALOMEDS_Tool::GetNameFromPath( medFile ) + ".med";
+      hdfFile = SALOMEDS_Tool::GetNameFromPath( hdfFile ) + ".hdf";
+      aFiles[0] = medFile.c_str();
+      aFiles[1] = hdfFile.c_str();
+
+      SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.c_str(), aFiles.in(), true );
+    }
+  }
+
+  //================================================================================
+  /*!
+   * \brief Method useful only to set a breakpoint to debug in case of exception
+   */
+  //================================================================================
+
+  void onExceptionCaught(const string& msg)
+  {
+    INFOS( msg );
+    MYDEBUGOUT( msg );
+  }
+
+  //=============================================================================
+  /*!
+   * \brief Class sending signals on start and finish of loading
+   */
+  //=============================================================================
+
+  class SignalToGUI
+  {
+    string              _messagePrefix;
+    SALOME::Session_var _session;
+  public:
+    SignalToGUI( SMESH_Mesh_i* mesh )
+    {
+      SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
+      SALOMEDS::Study_var study = gen->GetCurrentStudy();
+      if ( !study->_is_nil() && study->StudyId() == mesh->GetStudyId() )
+      {
+        SALOMEDS::SObject_var meshSO = gen->ObjectToSObject(study, mesh->_this() );
+        CORBA::Object_var obj = gen->GetNS()->Resolve( "/Kernel/Session" );
+        _session = SALOME::Session::_narrow( obj );
+        if ( !meshSO->_is_nil() && !_session->_is_nil() )
+        {
+          CORBA::String_var meshEntry = meshSO->GetID();
+          _messagePrefix = "SMESH/mesh_loading/";
+          _messagePrefix += meshEntry.in();
+
+          string msgToGUI = _messagePrefix + "/";
+          msgToGUI += SMESH_Comment( mesh->NbNodes() );
+          msgToGUI += "/";
+          msgToGUI += SMESH_Comment( mesh->NbElements() );
+
+          _session->emitMessageOneWay( msgToGUI.c_str());
+        }
+      }
+    }
+    void sendStop()
+    {
+      if ( !_messagePrefix.empty() )
+      {
+        string msgToGUI = _messagePrefix + "/stop";
+        _session->emitMessageOneWay( msgToGUI.c_str());
+        _messagePrefix.clear();
+      }
+    }
+    ~SignalToGUI() { sendStop(); }
+  };
+
+  //=============================================================================
+  /*!
+   * \brief Creates SMDS_Position according to shape type
+   */
+  //=============================================================================
+
+  class PositionCreator {
+  public:
+    SMDS_PositionPtr MakePosition(const TopAbs_ShapeEnum type) {
+      return (this->*myFuncTable[ type ])();
+    }
+    PositionCreator() {
+      myFuncTable.resize( (size_t) TopAbs_SHAPE, & PositionCreator::defaultPosition );
+      myFuncTable[ TopAbs_SOLID  ] = & PositionCreator::volumePosition;
+      myFuncTable[ TopAbs_FACE   ] = & PositionCreator::facePosition;
+      myFuncTable[ TopAbs_EDGE   ] = & PositionCreator::edgePosition;
+      myFuncTable[ TopAbs_VERTEX ] = & PositionCreator::vertexPosition;
+    }
+  private:
+    SMDS_PositionPtr edgePosition()    const { return SMDS_PositionPtr( new SMDS_EdgePosition  ); }
+    SMDS_PositionPtr facePosition()    const { return SMDS_PositionPtr( new SMDS_FacePosition  ); }
+    SMDS_PositionPtr volumePosition()  const { return SMDS_PositionPtr( new SMDS_SpacePosition ); }
+    SMDS_PositionPtr vertexPosition()  const { return SMDS_PositionPtr( new SMDS_VertexPosition); }
+    SMDS_PositionPtr defaultPosition() const { return SMDS_SpacePosition::originSpacePosition();  }
+    typedef SMDS_PositionPtr (PositionCreator:: * FmakePos)() const;
+    vector<FmakePos> myFuncTable;
+  };
+
+  //================================================================================
+  /*!
+   * \brief Returns ids of simple shapes composing a complex one
+   */
+  //================================================================================
+
+  vector<int> getSimpleSubMeshIds( SMESHDS_Mesh* meshDS, int shapeId )
+  {
+    vector<int> ids;
+
+    list<TopoDS_Shape> shapeQueue( 1, meshDS->IndexToShape( shapeId ));
+    list<TopoDS_Shape>::iterator shape = shapeQueue.begin();
+    for ( ; shape != shapeQueue.end(); ++shape )
+    {
+      if ( shape->IsNull() ) continue;
+      if ( shape->ShapeType() == TopAbs_COMPOUND ||
+           shape->ShapeType() == TopAbs_COMPSOLID )
+      {
+        for ( TopoDS_Iterator it( *shape ); it.More(); it.Next() )
+          shapeQueue.push_back( it.Value() );
+      }
+      else
+      {
+        ids.push_back( meshDS->ShapeToIndex( *shape ));
+      }
+    }
+    return ids;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Return EEntiteMaillage by EGeometrieElement
+   */
+  //================================================================================
+
+  MED::EEntiteMaillage entityByGeom(const MED::EGeometrieElement geom )
+  {
+    return geom == MED::eBALL ? MED::eSTRUCT_ELEMENT : MED::eMAILLE;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Return a map< EGeometrieElement, SMDSAbs_EntityType >
+   */
+  //================================================================================
+
+  typedef map< MED::EGeometrieElement, SMDSAbs_EntityType > Tmed2smeshElemTypeMap;
+  const Tmed2smeshElemTypeMap& med2smeshElemTypeMap()
+  {
+    static map< MED::EGeometrieElement, SMDSAbs_EntityType> med2smeshTypes;
+    if ( med2smeshTypes.empty() )
+    {
+      med2smeshTypes[ MED::ePOINT1   ] = SMDSEntity_0D                ;
+      med2smeshTypes[ MED::eSEG2     ] = SMDSEntity_Edge              ;
+      med2smeshTypes[ MED::eSEG3     ] = SMDSEntity_Quad_Edge         ;
+      med2smeshTypes[ MED::eTRIA3    ] = SMDSEntity_Triangle          ;
+      med2smeshTypes[ MED::eTRIA6    ] = SMDSEntity_Quad_Triangle     ;
+      med2smeshTypes[ MED::eQUAD4    ] = SMDSEntity_Quadrangle        ;
+      med2smeshTypes[ MED::eQUAD8    ] = SMDSEntity_Quad_Quadrangle   ;
+      med2smeshTypes[ MED::eQUAD9    ] = SMDSEntity_BiQuad_Quadrangle ;
+      med2smeshTypes[ MED::eTETRA4   ] = SMDSEntity_Tetra             ;
+      med2smeshTypes[ MED::ePYRA5    ] = SMDSEntity_Pyramid           ;
+      med2smeshTypes[ MED::ePENTA6   ] = SMDSEntity_Penta             ;
+      med2smeshTypes[ MED::eHEXA8    ] = SMDSEntity_Hexa              ;
+      med2smeshTypes[ MED::eOCTA12   ] = SMDSEntity_Hexagonal_Prism   ;
+      med2smeshTypes[ MED::eTETRA10  ] = SMDSEntity_Quad_Tetra        ;
+      med2smeshTypes[ MED::ePYRA13   ] = SMDSEntity_Quad_Pyramid      ;
+      med2smeshTypes[ MED::ePENTA15  ] = SMDSEntity_Quad_Penta        ;
+      med2smeshTypes[ MED::eHEXA20   ] = SMDSEntity_Quad_Hexa         ;
+      med2smeshTypes[ MED::eHEXA27   ] = SMDSEntity_TriQuad_Hexa      ;
+      med2smeshTypes[ MED::ePOLYGONE ] = SMDSEntity_Polygon           ;
+      med2smeshTypes[ MED::ePOLYEDRE ] = SMDSEntity_Polyhedra         ;
+      med2smeshTypes[ MED::eNONE     ] = SMDSEntity_Node              ;
+      med2smeshTypes[ MED::eBALL     ] = SMDSEntity_Ball              ;
+    }
+    return med2smeshTypes;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Return a vector<MED::EGeometrieElement> intended to retrieve
+   *        MED::EGeometrieElement by SMDSAbs_EntityType
+   */
+  //================================================================================
+
+  const vector<MED::EGeometrieElement>& mesh2medElemType()
+  {
+    static vector<MED::EGeometrieElement> mesh2medElemTypes;
+    if ( mesh2medElemTypes.empty() )
+    {
+      mesh2medElemTypes.resize( SMDSEntity_Last + 1 );
+      Tmed2smeshElemTypeMap::const_iterator me2sme    = med2smeshElemTypeMap().begin();
+      Tmed2smeshElemTypeMap::const_iterator me2smeEnd = med2smeshElemTypeMap().end();
+      for ( ; me2sme != me2smeEnd; ++me2sme )
+        mesh2medElemTypes[ me2sme->second ] = me2sme->first;
+    }
+    return mesh2medElemTypes;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Writes meshInfo into a HDF file
+   */
+  //================================================================================
+
+  void meshInfo2hdf( SMESH::long_array_var meshInfo,
+                     const std::string&    name,
+                     HDFgroup*             hdfGroup)
+  {
+    // we use med identification of element (MED::EGeometrieElement>) types
+    // but not enum SMDSAbs_EntityType because values of SMDSAbs_EntityType may
+    // change at insertion of new items in the middle.
+    const vector<MED::EGeometrieElement>& medTypes = mesh2medElemType();
+
+    vector<int> data;
+
+    for ( size_t i = 0; i < meshInfo->length(); ++i )
+      if ( meshInfo[i] > 0 )
+      {
+        data.push_back( medTypes[ i ] );
+        data.push_back( meshInfo[ i ] );
+      }
+
+    if ( !data.empty() )
+    {
+      hdf_size datasetSize[] = { data.size() };
+      HDFarray* anArray = new HDFarray(0, HDF_INT32, 1, datasetSize);
+      anArray->CreateOnDisk();
+      datasetSize[0] = 1;
+      HDFdataset* dataset = new HDFdataset( name.c_str(), hdfGroup, HDF_ARRAY, datasetSize, 1 );
+      dataset->SetArrayId(anArray->GetId());
+      dataset->CreateOnDisk();
+      dataset->WriteOnDisk( & data[0]  );
+      dataset->CloseOnDisk();
+      anArray->CloseOnDisk();
+    }
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Reads meshInfo from a HDF file
+ */
+//================================================================================
+
+void SMESH_PreMeshInfo::hdf2meshInfo( const std::string& name,
+                                      HDFgroup*          hdfGroup)
+{
+  if ( hdfGroup->ExistInternalObject( name.c_str()) )
+  {
+    HDFdataset* dataset = new HDFdataset( name.c_str(), hdfGroup );
+    dataset->OpenOnDisk();
+
+    // // hdf_size datasetSize[ 1 ];
+    // // HDFarray *array = new HDFarray(dataset);
+    // // array->GetDim( datasetSize );
+    // int size = dataset->GetSize();
+
+    vector<int> info( SMDSEntity_Last * 2, 0 );
+    dataset->ReadFromDisk( &info[0] );
+    dataset->CloseOnDisk();
+
+    const Tmed2smeshElemTypeMap& med2smesh = med2smeshElemTypeMap();
+    Tmed2smeshElemTypeMap::const_iterator me2sme, me2smeEnd = med2smesh.end();
+    for ( size_t i = 0; i < info.size(); )
+    {
+      int medType = info[i++];
+      int nbElems = info[i++];
+      if ( !nbElems ) break;
+      me2sme = med2smesh.find( (MED::EGeometrieElement) medType );
+      if ( me2sme != me2smeEnd )
+        setNb( me2sme->second, nbElems );
+    }
+  }
+  _isInfoOk = true;
+
+  if ( NbNodes() == GroupOnFilter_OutOfDate ) // case of !SMESHDS_GroupOnFilter::IsUpToDate()
+  {
+    _isInfoOk = false;
+    setNb( SMDSEntity_Node, 0 );
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Constructor callable by SMESH_PreMeshInfo only
+ */
+//================================================================================
+
+SMESH_PreMeshInfo::SMESH_PreMeshInfo(SMESH_Mesh_i*      mesh,
+                                     const int          meshID,
+                                     const std::string& medFile,
+                                     const std::string& hdfFile)
+  : _medFileName( medFile ),
+    _hdfFileName( hdfFile ),
+    _toRemoveFiles( false ),
+    _meshID( meshID ),
+    _mesh( mesh ),
+    _isInfoOk( false ),
+    _elemCounter( 0 )
+{
+}
+
+//================================================================================
+/*!
+ * \brief Release temporary files
+ */
+//================================================================================
+
+SMESH_PreMeshInfo::~SMESH_PreMeshInfo()
+{
+  if ( _toRemoveFiles ) // it can be true only for SMESH_PreMeshInfo of the mesh
+    filesNoMoreNeeded( _mesh, _medFileName, _hdfFileName );
+
+  _toRemoveFiles = false;
+}
+
+//================================================================================
+/*!
+ * \brief fills SMESH_PreMeshInfo field of all objects of mesh
+ */
+//================================================================================
+
+void SMESH_PreMeshInfo::LoadFromFile( SMESH_Mesh_i*      mesh,
+                                      const int          meshID,
+                                      const std::string& medFile,
+                                      const std::string& hdfFile,
+                                      const bool         toRemoveFiles)
+{
+  PreMeshInfo_TRY;
+
+  SMESH_PreMeshInfo* meshPreInfo = new SMESH_PreMeshInfo( mesh,meshID,medFile,hdfFile );
+  mesh->changePreMeshInfo() = meshPreInfo;
+
+  meshPreInfo->_toRemoveFiles = toRemoveFiles;
+  if ( toRemoveFiles )
+    meshInfoLoaded( mesh );
+
+  if ( meshPreInfo->readPreInfoFromHDF() )
+    // all SMESH_PreMeshInfo's are stored in HDF file (written after
+    // implementing SMESH_PreMeshInfo)
+    return;
+
+  // try to read SMESH_PreMeshInfo from med file (as study is older than SMESH_PreMeshInfo)
+  if ( meshPreInfo->readMeshInfo() )
+  {
+    meshPreInfo->readGroupInfo();
+    meshPreInfo->readSubMeshInfo();
+  }
+  else
+  {
+    meshPreInfo->FullLoadFromFile();
+  }
+  PreMeshInfo_CATCH;
+}
+
+//================================================================================
+/*!
+ * \brief Tries to read all SMESH_PreMeshInfo from a HDF file
+ *  \retval bool - true if succeeded
+ *
+ * This method is symmetrical to SaveToFile()
+ */
+//================================================================================
+
+bool SMESH_PreMeshInfo::readPreInfoFromHDF()
+{
+  HDFfile* aFile = new HDFfile( (char*) _hdfFileName.c_str() );
+  aFile->OpenOnDisk( HDF_RDONLY );
+
+  SMESH_Comment hdfGroupName("SMESH_PreMeshInfo"); hdfGroupName << _meshID;
+  const bool infoAvailable = aFile->ExistInternalObject( hdfGroupName );
+  if ( infoAvailable )
+  {
+    HDFgroup* infoHdfGroup = new HDFgroup( hdfGroupName, aFile );
+    infoHdfGroup->OpenOnDisk();
+
+    _mesh->changePreMeshInfo()->hdf2meshInfo( "Mesh", infoHdfGroup );
+
+    // read SMESH_PreMeshInfo of groups
+    map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i2group = _mesh->_mapGroups.begin();
+    for ( ; i2group != _mesh->_mapGroups.end(); ++i2group )
+    {
+      if ( SMESH_GroupBase_i* group_i =
+           SMESH::DownCast<SMESH_GroupBase_i*>( i2group->second ))
+      {
+        group_i->changePreMeshInfo() = newInstance();
+        if ( SMESHDS_GroupBase* group = group_i->GetGroupDS() )
+        {
+          const string name = group->GetStoreName();
+          group_i->changePreMeshInfo()->hdf2meshInfo( name, infoHdfGroup );
+        }
+      }
+    }
+
+    // read SMESH_PreMeshInfo of sub-meshes
+    map<int, SMESH::SMESH_subMesh_ptr>::iterator id2sm = _mesh->_mapSubMeshIor.begin();
+    for ( ; id2sm != _mesh->_mapSubMeshIor.end(); ++id2sm )
+    {
+      if ( SMESH_subMesh_i* sm = SMESH::DownCast<SMESH_subMesh_i*>( id2sm->second ))
+      {
+        sm->changePreMeshInfo() = newInstance();
+        sm->changePreMeshInfo()->hdf2meshInfo( SMESH_Comment( sm->GetId()), infoHdfGroup );
+      }
+    }
+  }
+
+  aFile->CloseOnDisk();
+  delete aFile;
+
+  return infoAvailable;
+}
+
+//================================================================================
+/*!
+ * \brief Reads mesh info of mesh from the med file
+ */
+//================================================================================
+
+bool SMESH_PreMeshInfo::readMeshInfo()
+{
+  _isInfoOk = true;
+
+  MED::PWrapper aMed = MED::CrWrapper(_medFileName,true);
+  // if ( aMed->GetVersion() != MED::eV2_2 )
+  //   return false;
+
+  MED::PMeshInfo medMeshInfo = aMed->CrMeshInfo(3,3,SMESH_Comment( _meshID ));
+
+  // read nb nodes
+  int nbNodes = std::max( 0, aMed->GetNbNodes( medMeshInfo ));
+  if ( nbNodes > 0 )
+  {
+    setNb( SMDSEntity_Node, nbNodes);
+
+    // read nb of elements
+    Tmed2smeshElemTypeMap::const_iterator me2sme    = med2smeshElemTypeMap().begin();
+    Tmed2smeshElemTypeMap::const_iterator me2smeEnd = med2smeshElemTypeMap().end();
+    for ( ; me2sme != me2smeEnd; ++me2sme )
+    {
+      int nbElems = aMed->GetNbCells( medMeshInfo, entityByGeom(me2sme->first), me2sme->first );
+      if ( nbElems > 0 )
+        setNb( me2sme->second, nbElems );
+    }
+  }
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Reads info of groups from the med file
+ */
+//================================================================================
+
+void SMESH_PreMeshInfo::readGroupInfo()
+{
+  if ( _mesh->_mapGroups.empty() ) return;
+
+  // make SMESH_PreMeshInfo of groups
+  map< string, SMESH_PreMeshInfo* > name2GroupInfo;
+  map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i2group = _mesh->_mapGroups.begin();
+  for ( ; i2group != _mesh->_mapGroups.end(); ++i2group )
+  {
+    if ( SMESH_GroupBase_i* group_i =
+         SMESH::DownCast<SMESH_GroupBase_i*>( i2group->second ))
+    {
+      SMESH_PreMeshInfo* info = newInstance();
+      group_i->changePreMeshInfo() = info;
+      if ( SMESHDS_Group* group = dynamic_cast< SMESHDS_Group* >( group_i->GetGroupDS() ))
+      {
+        string name = group->GetStoreName();
+        name2GroupInfo.insert( make_pair( name, info ));
+        info->_isInfoOk = true;
+      }
+    }
+  }
+
+  map< int, vector< SMESH_PreMeshInfo* > > famId2grInfo;
+
+  MED::PWrapper aMed = MED::CrWrapper(_medFileName,false);
+  MED::PMeshInfo medMeshInfo = aMed->CrMeshInfo(3,3,SMESH_Comment( _meshID ));
+
+  // read families to fill in famId2grInfo
+  int nbFams = aMed->GetNbFamilies( medMeshInfo );
+  if ( nbFams <= 1 ) return; // zero family is always present
+  for ( int iF = 0; iF <= nbFams; ++iF )
+  {
+    int nbGroups = aMed->GetNbFamGroup( iF, medMeshInfo );
+    if ( nbGroups < 1 ) continue;
+    MED::PFamilyInfo medFamInfo = aMed->CrFamilyInfo( medMeshInfo, nbGroups, nbGroups );
+    aMed->GetFamilyInfo( iF, medFamInfo ); // read groups of a family
+    vector< SMESH_PreMeshInfo* >& grInfoVec = famId2grInfo[ medFamInfo->GetId() ];
+    for ( int iG = 0; iG < nbGroups; ++iG )
+    {
+      const string grName = medFamInfo->GetGroupName( iG );
+      map< string, SMESH_PreMeshInfo* >::iterator n2i = name2GroupInfo.find( grName );
+      if ( n2i != name2GroupInfo.end() )
+        grInfoVec.push_back( n2i->second );
+    }
+  }
+
+  // read family numbers of elements
+  Tmed2smeshElemTypeMap::const_iterator me2sme    = med2smeshElemTypeMap().begin();
+  Tmed2smeshElemTypeMap::const_iterator me2smeEnd = med2smeshElemTypeMap().end();
+  MED::PElemInfo medElemInfo = aMed->CrElemInfo( medMeshInfo, 0 );
+  MED::TIntVector& famNums = medElemInfo->myFamNum;
+  for ( ; me2sme != me2smeEnd; ++me2sme ) // loop on elem types
+  {
+    famNums.resize( NbEntities( me2sme->second ));
+    if ( famNums.empty() ) continue;
+    aMed->GetFamilies( medElemInfo, famNums.size(), entityByGeom(me2sme->first), me2sme->first );
+    // distribute elements of a type among groups
+    map< int, vector< SMESH_PreMeshInfo* > >::iterator f2infos = famId2grInfo.begin();
+    for ( size_t i = 0; i < famNums.size(); ++i )
+    {
+      if ( famNums[i] != f2infos->first )
+      {
+        f2infos = famId2grInfo.find( famNums[i] );
+        if ( f2infos == famId2grInfo.end() )
+          f2infos = famId2grInfo.insert
+            ( make_pair( famNums[i], vector< SMESH_PreMeshInfo*>())).first;
+      }
+      vector< SMESH_PreMeshInfo* >& infoVec = f2infos->second ;
+      for ( size_t j = 0; j < infoVec.size(); ++j )
+        infoVec[j]->_elemCounter++;
+    }
+    // pass _elemCounter to a real elem type
+    map< string, SMESH_PreMeshInfo* >::iterator n2i = name2GroupInfo.begin();
+    for ( ; n2i != name2GroupInfo.end(); ++n2i )
+    {
+      SMESH_PreMeshInfo* info = n2i->second;
+      info->setNb( me2sme->second, info->_elemCounter );
+      info->_elemCounter = 0;
+    }
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Reads info of sub-meshes from hdf file of old study
+ */
+//================================================================================
+
+void SMESH_PreMeshInfo::readSubMeshInfo()
+{
+  if ( _mesh->_mapSubMeshIor.empty() ) return;
+
+  // create SMESH_PreMeshInfo of sub-meshes
+  map<int, SMESH::SMESH_subMesh_ptr>::iterator id2sm = _mesh->_mapSubMeshIor.begin();
+  for ( ; id2sm != _mesh->_mapSubMeshIor.end(); ++id2sm )
+  {
+    if ( SMESH_subMesh_i* sm = SMESH::DownCast<SMESH_subMesh_i*>( id2sm->second ))
+    {
+      sm->changePreMeshInfo() = newInstance();
+      sm->changePreMeshInfo()->_isInfoOk = true;
+    }
+  }
+
+  // try to read 
+  HDFfile* aFile = new HDFfile( (char*) _hdfFileName.c_str() );
+  aFile->OpenOnDisk( HDF_RDONLY );
+
+  char meshGrpName[ 30 ];
+  sprintf( meshGrpName, "Mesh %d", _meshID );
+  if ( aFile->ExistInternalObject( meshGrpName ) )
+  {
+    HDFgroup* aTopGroup = new HDFgroup( meshGrpName, aFile );
+    aTopGroup->OpenOnDisk();
+    if ( aTopGroup->ExistInternalObject( "Submeshes" ))
+    {
+      HDFgroup* aGroup = new HDFgroup( "Submeshes", aTopGroup );
+      aGroup->OpenOnDisk();
+
+      SMESHDS_Mesh* meshDS = _mesh->GetImpl().GetMeshDS();
+      int maxSmId = Max( meshDS->MaxSubMeshIndex(), meshDS->MaxShapeIndex() );
+
+      for ( int isNode = 0; isNode < 2; ++isNode )
+      {
+        string aDSName( isNode ? "Node Submeshes" : "Element Submeshes");
+        if ( aGroup->ExistInternalObject( (char*) aDSName.c_str() ))
+        {
+          // read sub-mesh id of all nodes or elems
+          HDFdataset* aDataset = new HDFdataset( (char*) aDSName.c_str(), aGroup );
+          aDataset->OpenOnDisk();
+          int nbElems = aDataset->GetSize();
+          int* smIDs = new int [ nbElems ];
+          aDataset->ReadFromDisk( smIDs );
+          aDataset->CloseOnDisk();
+          // count nb elems in each sub-mesh
+          vector<int> nbBySubmeshId( maxSmId + 1, 0 );
+          for ( int i = 0; i < nbElems; ++i )
+          {
+            const int smID = smIDs[ i ];
+            if ( smID < (int) nbBySubmeshId.size() )
+              nbBySubmeshId[ smID ]++;
+          }
+          delete [] smIDs;
+
+          // store nb elems in SMESH_PreMeshInfo of sub-meshes
+          map<int, SMESH::SMESH_subMesh_ptr>::iterator id2sm = _mesh->_mapSubMeshIor.begin();
+          for ( ; id2sm != _mesh->_mapSubMeshIor.end(); ++id2sm )
+          {
+            if ( SMESH_subMesh_i* sm = SMESH::DownCast<SMESH_subMesh_i*>( id2sm->second ))
+            {
+              SMESH_PreMeshInfo* & info = sm->changePreMeshInfo();
+
+              vector<int> smIds = getSimpleSubMeshIds( meshDS, id2sm->first );
+              for ( size_t i = 0; i < smIds.size(); ++i )
+                info->_elemCounter += nbBySubmeshId[ smIds[i] ];
+
+              SMDSAbs_EntityType elemType;
+              if ( isNode )
+              {
+                elemType = SMDSEntity_Node;
+              }
+              else
+              {
+                bool koElemType = false;
+                const TopoDS_Shape& shape = meshDS->IndexToShape( smIds[0] );
+                elemType = getElemType( shape.ShapeType(), info->_elemCounter, koElemType );
+                info->_isInfoOk = !koElemType;
+              }
+              info->setNb( elemType, info->_elemCounter );
+            }
+          }
+        } // if ( aGroup->ExistInternalObject( aDSName ))
+      } // for ( int isNode = 0; isNode < 2; ++isNode )
+
+      aGroup->CloseOnDisk();
+    } // if ( aTopGroup->ExistInternalObject( "Submeshes" ))
+
+    aTopGroup->CloseOnDisk();
+  } // if ( aFile->ExistInternalObject( meshGrpName ) )
+
+  aFile->CloseOnDisk();
+  delete aFile;
+}
+
+//================================================================================
+/*!
+ * \brief Return type of element for sub-mesh on a shape of given type
+ */
+//================================================================================
+
+SMDSAbs_EntityType SMESH_PreMeshInfo::getElemType( const TopAbs_ShapeEnum shapeType,
+                                                   const int              nbElemsInSubMesh,
+                                                   bool&                  isKoType) const
+{
+  isKoType = false;
+  int type, typeEnd;
+  SMESH_PreMeshInfo* meshInfo = _mesh->changePreMeshInfo();
+
+  switch ( shapeType )
+  {
+  case TopAbs_SOLID:
+    type = SMDSEntity_Tetra;
+    typeEnd = SMDSEntity_Last;
+    isKoType = ( meshInfo->NbVolumes() != nbElemsInSubMesh );
+    break;
+  case TopAbs_FACE:
+  case TopAbs_SHELL:  
+    type = SMDSEntity_Triangle;
+    typeEnd = SMDSEntity_Tetra;
+    isKoType = ( meshInfo->NbFaces() != nbElemsInSubMesh );
+    break;
+  case TopAbs_WIRE:
+  case TopAbs_EDGE:   return SMDSEntity_Edge;
+  case TopAbs_VERTEX: return SMDSEntity_0D;
+  default:            return SMDSEntity_Last;
+  }
+
+  if ( !isKoType )
+  {
+    for ( int t = type; t < typeEnd; ++t )
+      if ( nbElemsInSubMesh == meshInfo->NbEntities( SMDSAbs_EntityType( t )))
+        return SMDSAbs_EntityType( t );
+  }
+  isKoType = true;
+  return SMDSAbs_EntityType( type );
+}
+
+//================================================================================
+/*!
+ * \brief Saves SMESH_PreMeshInfo to the study file
+ */
+//================================================================================
+
+void SMESH_PreMeshInfo::SaveToFile( SMESH_Mesh_i* mesh,
+                                    const int     meshID,
+                                    HDFfile*      hdfFile)
+{
+  // create a HDF group for SMESH_PreMeshInfo of this mesh
+  SMESH_Comment hdfGroupName("SMESH_PreMeshInfo"); hdfGroupName << meshID;
+  HDFgroup* infoHdfGroup = new HDFgroup( hdfGroupName, hdfFile );
+  infoHdfGroup->CreateOnDisk();
+
+  PreMeshInfo_TRY;
+
+  // info of mesh
+  meshInfo2hdf( mesh->GetMeshInfo(), "Mesh", infoHdfGroup );
+  
+  // info of groups
+  SMESH_PreMeshInfo incompleteInfo( 0,0,"","");
+  incompleteInfo.setNb( SMDSEntity_Node, GroupOnFilter_OutOfDate );
+  SMESHDS_Mesh* meshDS = mesh->GetImpl().GetMeshDS();
+
+  map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i2group = mesh->_mapGroups.begin();
+  for ( ; i2group != mesh->_mapGroups.end(); ++i2group )
+  {
+    if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2group->second ))
+    {
+      SMESHDS_GroupBase * group = group_i->GetGroupDS();
+      if ( SMESHDS_GroupOnFilter* gof = dynamic_cast<SMESHDS_GroupOnFilter*>(group))
+      {
+        // prevent too long storage time due to applying filter to many elements
+        if ( !gof->IsUpToDate() && meshDS->GetMeshInfo().NbElements( gof->GetType() ) > 1e5 )
+        {
+          meshInfo2hdf( incompleteInfo.GetMeshInfo(),
+                        group->GetStoreName(),
+                        infoHdfGroup);
+          continue;
+        }
+      }
+      meshInfo2hdf( group_i->GetMeshInfo(), group->GetStoreName(), infoHdfGroup);
+    }
+  }
+
+  // info of sub-meshes
+  map<int, SMESH::SMESH_subMesh_ptr>::iterator id2sm = mesh->_mapSubMeshIor.begin();
+  for ( ; id2sm != mesh->_mapSubMeshIor.end(); ++id2sm )
+  {
+    if ( SMESH_subMesh_i* sm = SMESH::DownCast<SMESH_subMesh_i*>( id2sm->second ))
+    {
+      meshInfo2hdf( sm->GetMeshInfo(),
+                    SMESH_Comment( sm->GetId() ),
+                    infoHdfGroup);
+    }
+  }
+
+  PreMeshInfo_CATCH;
+
+  infoHdfGroup->CloseOnDisk();
+}
+
+//================================================================================
+/*!
+ * \brief Reads all data and remove all SMESH_PreMeshInfo fields from objects
+ */
+//================================================================================
+
+void SMESH_PreMeshInfo::FullLoadFromFile() const
+{
+  SignalToGUI signalOnLoading( _mesh );
+
+  SMESH_PreMeshInfo* meshInfo = _mesh->changePreMeshInfo();
+  _mesh->changePreMeshInfo() = NULL; // to allow GUI accessing to real info
+
+  ::SMESH_Mesh& mesh = _mesh->GetImpl();
+  SMESHDS_Mesh* meshDS = mesh.GetMeshDS();
+
+  PreMeshInfo_TRY;
+
+  MYDEBUGOUT( "BEG FullLoadFromFile() " << _meshID );
+
+  // load mesh
+  DriverMED_R_SMESHDS_Mesh myReader;
+  myReader.SetFile( _medFileName.c_str() );
+  myReader.SetMesh( meshDS );
+  myReader.SetMeshId( _meshID );
+  myReader.Perform();
+
+  // load groups
+  const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
+  set<SMESHDS_GroupBase*>::const_iterator groupIt = groups.begin();
+  for ( ; groupIt != groups.end(); ++groupIt )
+    if ( SMESHDS_Group* aGrp = dynamic_cast<SMESHDS_Group*>( *groupIt ))
+      myReader.GetGroup( aGrp );
+
+  // load sub-meshes
+  readSubMeshes( &myReader );
+
+  PreMeshInfo_CATCH;
+
+  _mesh->changePreMeshInfo() = meshInfo;
+
+  ForgetAllData();
+
+  signalOnLoading.sendStop();
+
+  meshDS->Modified();
+
+  // load dependent meshes referring/referred via hypotheses
+  mesh.GetSubMesh( mesh.GetShapeToMesh() )->
+    ComputeStateEngine (SMESH_subMesh::SUBMESH_LOADED);
+
+  MYDEBUGOUT( "END FullLoadFromFile()" );
+}
+
+//================================================================================
+/*!
+ * \brief Reads full data of sub-meshes
+ */
+//================================================================================
+
+void SMESH_PreMeshInfo::readSubMeshes(DriverMED_R_SMESHDS_Mesh* reader) const
+{
+  HDFfile* aFile = new HDFfile( (char*) _hdfFileName.c_str() );
+  aFile->OpenOnDisk( HDF_RDONLY );
+
+  char meshGrpName[ 30 ];
+  sprintf( meshGrpName, "Mesh %d", _meshID );
+  if ( aFile->ExistInternalObject( meshGrpName ) )
+  {
+    HDFgroup* aTopGroup = new HDFgroup( meshGrpName, aFile );
+    aTopGroup->OpenOnDisk();
+
+    SMESHDS_Mesh* meshDS = _mesh->GetImpl().GetMeshDS();
+
+    bool submeshesInFamilies = ( ! aTopGroup->ExistInternalObject( "Submeshes" ));
+    if ( submeshesInFamilies ) // from MED
+    {
+      // old way working before fix of PAL 12992
+      reader->CreateAllSubMeshes();
+    }
+    else
+    {
+      // open a group
+      HDFgroup* aGroup = new HDFgroup( "Submeshes", aTopGroup );
+      aGroup->OpenOnDisk();
+
+      int maxID = Max( meshDS->MaxSubMeshIndex(), meshDS->MaxShapeIndex() );
+      vector< SMESHDS_SubMesh * > subMeshes( maxID + 1, (SMESHDS_SubMesh*) 0 );
+      vector< TopAbs_ShapeEnum  > smType   ( maxID + 1, TopAbs_SHAPE );
+
+      PositionCreator aPositionCreator;
+
+      SMDS_NodeIteratorPtr nIt = meshDS->nodesIterator();
+      SMDS_ElemIteratorPtr eIt = meshDS->elementsIterator();
+      for ( int isNode = 0; isNode < 2; ++isNode )
+      {
+        string aDSName( isNode ? "Node Submeshes" : "Element Submeshes");
+        if ( aGroup->ExistInternalObject( (char*) aDSName.c_str() ))
+        {
+          HDFdataset* aDataset = new HDFdataset( (char*) aDSName.c_str(), aGroup );
+          aDataset->OpenOnDisk();
+          // read submesh IDs for all elements sorted by ID
+          int nbElems = aDataset->GetSize();
+          int* smIDs = new int [ nbElems ];
+          aDataset->ReadFromDisk( smIDs );
+          aDataset->CloseOnDisk();
+
+          // get elements sorted by ID
+          TIDSortedElemSet elemSet;
+          if ( isNode )
+            while ( nIt->more() ) elemSet.insert( elemSet.end(), nIt->next() );
+          else
+            while ( eIt->more() ) elemSet.insert( elemSet.end(), eIt->next() );
+          //ASSERT( elemSet.size() == nbElems ); -- issue 20182
+          // -- Most probably a bad study was saved when there were
+          // not fixed bugs in SMDS_MeshInfo
+          if ( elemSet.size() < nbElems ) {
+#ifdef _DEBUG_
+            cout << "SMESH_Gen_i::Load(), warning: Node position data is invalid" << endl;
+#endif
+            nbElems = elemSet.size();
+          }
+          // add elements to submeshes
+          TIDSortedElemSet::iterator iE = elemSet.begin();
+          for ( int i = 0; i < nbElems; ++i, ++iE )
+          {
+            int smID = smIDs[ i ];
+            if ( smID == 0 ) continue;
+            const SMDS_MeshElement* elem = *iE;
+            if ( smID > maxID ) {
+              // corresponding subshape no longer exists: maybe geom group has been edited
+              if ( _mesh->GetImpl().HasShapeToMesh() )
+                meshDS->RemoveElement( elem );
+              continue;
+            }
+            // get or create submesh
+            SMESHDS_SubMesh* & sm = subMeshes[ smID ];
+            if ( ! sm ) {
+              sm = meshDS->NewSubMesh( smID );
+              smType[ smID ] = meshDS->IndexToShape( smID ).ShapeType();
+            }
+            // add
+            if ( isNode ) {
+              SMDS_PositionPtr pos = aPositionCreator.MakePosition( smType[ smID ]);
+              SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( static_cast<const SMDS_MeshNode*>( elem ));
+              node->SetPosition( pos );
+              sm->AddNode( node );
+            } else {
+              sm->AddElement( elem );
+            }
+          }
+          delete [] smIDs;
+        }
+      }
+    } // end reading submeshes
+
+    // Read node positions on sub-shapes (SMDS_Position)
+
+    if ( aTopGroup->ExistInternalObject( "Node Positions" ))
+    {
+      // There are 5 datasets to read:
+      // "Nodes on Edges" - ID of node on edge
+      // "Edge positions" - U parameter on node on edge
+      // "Nodes on Faces" - ID of node on face
+      // "Face U positions" - U parameter of node on face
+      // "Face V positions" - V parameter of node on face
+      const char* aEid_DSName = "Nodes on Edges";
+      const char* aEu_DSName  = "Edge positions";
+      const char* aFu_DSName  = "Face U positions";
+      //char* aFid_DSName = "Nodes on Faces";
+      //char* aFv_DSName  = "Face V positions";
+
+      // data to retrieve
+      int nbEids = 0, nbFids = 0;
+      int *aEids = 0, *aFids  = 0;
+      double *aEpos = 0, *aFupos = 0, *aFvpos = 0;
+
+      // open a group
+      HDFgroup* aGroup = new HDFgroup( "Node Positions", aTopGroup );
+      aGroup->OpenOnDisk();
+
+      // loop on 5 data sets
+      int aNbObjects = aGroup->nInternalObjects();
+      for ( int i = 0; i < aNbObjects; i++ )
+      {
+        // identify dataset
+        char aDSName[ HDF_NAME_MAX_LEN+1 ];
+        aGroup->InternalObjectIndentify( i, aDSName );
+        // read data
+        HDFdataset* aDataset = new HDFdataset( aDSName, aGroup );
+        aDataset->OpenOnDisk();
+        if ( aDataset->GetType() == HDF_FLOAT64 ) // Positions
+        {
+          double* pos = new double [ aDataset->GetSize() ];
+          aDataset->ReadFromDisk( pos );
+          // which one?
+          if ( strncmp( aDSName, aEu_DSName, strlen( aEu_DSName )) == 0 )
+            aEpos = pos;
+          else if ( strncmp( aDSName, aFu_DSName, strlen( aFu_DSName )) == 0 )
+            aFupos = pos;
+          else
+            aFvpos = pos;
+        }
+        else // NODE IDS
+        {
+          int aSize = aDataset->GetSize();
+
+          // for reading files, created from 18.07.2005 till 10.10.2005
+          if (aDataset->GetType() == HDF_STRING)
+            aSize /= sizeof(int);
+
+          int* ids = new int [aSize];
+          aDataset->ReadFromDisk( ids );
+          // on face or nodes?
+          if ( strncmp( aDSName, aEid_DSName, strlen( aEid_DSName )) == 0 ) {
+            aEids = ids;
+            nbEids = aSize;
+          }
+          else {
+            aFids = ids;
+            nbFids = aSize;
+          }
+        }
+        aDataset->CloseOnDisk();
+      } // loop on 5 datasets
+
+      // Set node positions on edges or faces
+      for ( int onFace = 0; onFace < 2; onFace++ )
+      {
+        int nbNodes = ( onFace ? nbFids : nbEids );
+        if ( nbNodes == 0 ) continue;
+        int* aNodeIDs = ( onFace ? aFids : aEids );
+        double* aUPos = ( onFace ? aFupos : aEpos );
+        double* aVPos = ( onFace ? aFvpos : 0 );
+        // loop on node IDs
+        for ( int iNode = 0; iNode < nbNodes; iNode++ )
+        {
+          const SMDS_MeshNode* node = meshDS->FindNode( aNodeIDs[ iNode ]);
+          if ( !node ) continue; // maybe removed while Loading() if geometry changed
+          SMDS_PositionPtr aPos = node->GetPosition();
+          ASSERT( aPos );
+          if ( onFace ) {
+            // ASSERT( aPos->GetTypeOfPosition() == SMDS_TOP_FACE );-- issue 20182
+            // -- Most probably a bad study was saved when there were
+            // not fixed bugs in SMDS_MeshInfo
+            if ( aPos->GetTypeOfPosition() == SMDS_TOP_FACE ) {
+              SMDS_FacePosition* fPos = const_cast<SMDS_FacePosition*>
+                ( static_cast<const SMDS_FacePosition*>( aPos ));
+              fPos->SetUParameter( aUPos[ iNode ]);
+              fPos->SetVParameter( aVPos[ iNode ]);
+            }
+          }
+          else {
+            // ASSERT( aPos->GetTypeOfPosition() == SMDS_TOP_EDGE );-- issue 20182
+            if ( aPos->GetTypeOfPosition() == SMDS_TOP_EDGE ) {
+              SMDS_EdgePosition* fPos = const_cast<SMDS_EdgePosition*>
+                ( static_cast<const SMDS_EdgePosition*>( aPos ));
+              fPos->SetUParameter( aUPos[ iNode ]);
+            }
+          }
+        }
+      }
+      if ( aEids ) delete [] aEids;
+      if ( aFids ) delete [] aFids;
+      if ( aEpos ) delete [] aEpos;
+      if ( aFupos ) delete [] aFupos;
+      if ( aFvpos ) delete [] aFvpos;
+
+      aGroup->CloseOnDisk();
+
+    } // if ( aTopGroup->ExistInternalObject( "Node Positions" ) )
+
+    aTopGroup->CloseOnDisk();
+  } // if ( aFile->ExistInternalObject( meshGrpName ) )
+  
+  aFile->CloseOnDisk();
+  delete aFile;
+}
+
+//================================================================================
+/*!
+ * \brief Remove all SMESH_PreMeshInfo fields from objects w/o data loading
+ */
+//================================================================================
+
+void SMESH_PreMeshInfo::ForgetAllData() const
+{
+  PreMeshInfo_TRY;
+
+  if ( _mesh->changePreMeshInfo() != this )
+    return _mesh->changePreMeshInfo()->ForgetAllData();
+
+  // remove SMESH_PreMeshInfo from groups
+  map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i2group = _mesh->_mapGroups.begin();
+  for ( ; i2group != _mesh->_mapGroups.end(); ++i2group )
+  {
+    if ( SMESH_GroupBase_i* group_i =
+         SMESH::DownCast<SMESH_GroupBase_i*>( i2group->second ))
+    {
+      SMESH_PreMeshInfo* & info = group_i->changePreMeshInfo();
+      delete info;
+      info = NULL;
+    }
+  }
+  // remove SMESH_PreMeshInfo from sub-meshes
+  map<int, SMESH::SMESH_subMesh_ptr>::iterator id2sm = _mesh->_mapSubMeshIor.begin();
+  for ( ; id2sm != _mesh->_mapSubMeshIor.end(); ++id2sm )
+  {
+    if ( SMESH_subMesh_i* sm = SMESH::DownCast<SMESH_subMesh_i*>( id2sm->second ))
+    {
+      SMESH_PreMeshInfo* & info = sm->changePreMeshInfo();
+      delete info;
+      info = NULL;
+    }
+  }
+  // remove SMESH_PreMeshInfo from the mesh
+  _mesh->changePreMeshInfo() = NULL;
+  delete this;
+
+  PreMeshInfo_CATCH;
+
+
+  // Finalize loading
+
+  // PreMeshInfo_TRY;
+
+  // ::SMESH_Mesh& mesh = _mesh->GetImpl();
+
+  // // update hyps needing full mesh data restored (issue 20918)
+  // // map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id2hyp= _mesh->_mapHypo.begin();
+  // // for ( ; id2hyp != _mesh->_mapHypo.end(); ++id2hyp )
+  // //   if ( SMESH_Hypothesis_i* hyp = SMESH::DownCast<SMESH_Hypothesis_i*>( id2hyp->second ))
+  // //     hyp->UpdateAsMeshesRestored();
+
+
+  // PreMeshInfo_CATCH;
+}
+
+//================================================================================
+/*!
+ * \brief Calls either FullLoadFromFile() or ForgetAllData() depending on preferences
+ */
+//================================================================================
+
+void SMESH_PreMeshInfo::ForgetOrLoad() const
+{
+  if ( SMESH_Gen_i::GetSMESHGen()->ToForgetMeshDataOnHypModif() &&
+       _mesh->HasShapeToMesh())
+    ForgetAllData();
+  else
+    FullLoadFromFile();
+}
+
+//================================================================================
+/*!
+ * \brief Method of SMESH_IDSource interface
+ */
+//================================================================================
+
+SMESH::array_of_ElementType* SMESH_PreMeshInfo::GetTypes() const
+{
+  SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
+
+  types->length( 4 );
+  int nbTypes = 0;
+  if (NbEdges())      types[nbTypes++] = SMESH::EDGE;
+  if (NbFaces())      types[nbTypes++] = SMESH::FACE;
+  if (NbVolumes())    types[nbTypes++] = SMESH::VOLUME;
+  if (Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
+  if (NbBalls())      types[nbTypes++] = SMESH::BALL;
+  types->length( nbTypes );
+
+  return types._retn();
+}
+
+//================================================================================
+/*!
+ * \brief Method of SMESH_IDSource interface returning nb elements by element type
+ */
+//================================================================================
+
+SMESH::long_array* SMESH_PreMeshInfo::GetMeshInfo() const
+{
+  SMESH::long_array_var aRes = new SMESH::long_array();
+  aRes->length(SMESH::Entity_Last);
+  for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
+    aRes[i] = 0;
+
+  for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
+    aRes[i] = NbEntities((SMDSAbs_EntityType)i);
+  return aRes._retn();
+}
+
+//================================================================================
+/*!
+ * Returns false if GetMeshInfo() returns incorrect information that may
+ * happen if mesh data is not yet fully loaded from the file of study.
+ */
+//================================================================================
+
+bool SMESH_PreMeshInfo::IsMeshInfoCorrect() const
+{
+  return _isInfoOk;
+}
+
+//================================================================================
+/*!
+ * \brief TEMPORARY method to remove study files on closing study;
+ * RIGHT WAY: study files are remove automatically when meshes are destroyed
+ */
+//================================================================================
+
+void SMESH_PreMeshInfo::RemoveStudyFiles_TMP_METHOD(SALOMEDS::SComponent_ptr smeshComp)
+{
+  SALOMEDS::Study_var study = smeshComp->GetStudy();
+  if ( theStudyIDToMeshCounter[ (int) study->StudyId() ] > 0 )
+  {
+    SALOMEDS::ChildIterator_var itBig = study->NewChildIterator( smeshComp );
+    for ( ; itBig->More(); itBig->Next() ) {
+      SALOMEDS::SObject_var gotBranch = itBig->Value();
+      CORBA::Object_var anObject = SMESH_Gen_i::SObjectToObject( gotBranch );
+      if ( SMESH_Mesh_i* mesh = SMESH::DownCast<SMESH_Mesh_i*>( anObject ))
+      {
+        if ( mesh->changePreMeshInfo() )
+        {
+          mesh->changePreMeshInfo()->ForgetAllData();
+        }
+      }
+    }
+  }
+}
diff --git a/src/SMESH_I/SMESH_PreMeshInfo.hxx b/src/SMESH_I/SMESH_PreMeshInfo.hxx
new file mode 100644 (file)
index 0000000..38b15a2
--- /dev/null
@@ -0,0 +1,125 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+// File      : SMESH_PreMeshInfo.hxx
+// Created   : Fri Feb 10 13:25:02 2012
+// Author    : Edward AGAPOV (eap)
+
+
+#ifndef __SMESH_PreMeshInfo_HXX__
+#define __SMESH_PreMeshInfo_HXX__
+
+#include "SMDS_MeshInfo.hxx"
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SALOMEDS)
+
+#include <TopAbs_ShapeEnum.hxx>
+
+class DriverMED_R_SMESHDS_Mesh;
+class HDFfile;
+class HDFgroup;
+class SMESH_Mesh_i;
+
+/*!
+ * \brief Class loading and holding information of a mesh object (mesh, group, submesh)
+ *        not yet loaded from HDF file of study.
+ *
+ * Usage scenario:
+ * - SMESH_PreMeshInfo::LoadFromFile() // reads info of all objects
+ * - if ( myPreInfo ) myPreInfo->NbElements() // access to info by objects
+ * - myPreInfo->FullLoadFromFile() // reads all mesh data and resets myPreInfo=NULL
+ */
+
+class SMESH_PreMeshInfo : public SMDS_MeshInfo
+{
+public:
+  // fills SMESH_PreMeshInfo field of all objects of mesh
+  static void LoadFromFile( SMESH_Mesh_i*      mesh,
+                            const int          meshID,
+                            const std::string& medFile,
+                            const std::string& hdfFile,
+                            const bool         toRemoveFiles);
+
+  // saves SMESH_PreMeshInfo to the study file
+  static void SaveToFile( SMESH_Mesh_i* mesh,
+                          const int     meshID,
+                          HDFfile*      hdfFile);
+
+  // reads all data and remove all SMESH_PreMeshInfo fields from objects
+  void FullLoadFromFile() const;
+
+  // remove all SMESH_PreMeshInfo fields from objects w/o data loading
+  void ForgetAllData() const;
+
+  // calls either FullLoadFromFile() or ForgetAllData() depending on preferences;
+  // is called on hypothesis modification
+  void ForgetOrLoad() const;
+
+  // meshods of SMESH_IDSource interface
+  SMESH::array_of_ElementType* GetTypes() const;
+  SMESH::long_array*           GetMeshInfo() const;
+  bool                         IsMeshInfoCorrect() const;
+
+  ~SMESH_PreMeshInfo();
+
+  // TEMPORARY method to remove study files on closing study;
+  // RIGHT WAY: study files are remove automatically when meshes are destroyed
+  static void RemoveStudyFiles_TMP_METHOD(SALOMEDS::SComponent_ptr smeshComp);
+
+private:
+
+  // creation by LoadFromFile() only
+  SMESH_PreMeshInfo(SMESH_Mesh_i*      mesh,
+                    const int          meshID,
+                    const std::string& medFile,
+                    const std::string& hdfFile);
+
+  SMESH_PreMeshInfo* newInstance()
+  { return new SMESH_PreMeshInfo( _mesh,_meshID,_medFileName,_hdfFileName ); }
+
+  // reading from the new study, for which SaveToFile() was called
+  bool readPreInfoFromHDF();
+  void hdf2meshInfo( const std::string& dataSetName, HDFgroup* infoHdfGroup );
+
+  // reading from the old study, for which SaveToFile() was not called
+  bool readMeshInfo();
+  void readGroupInfo();
+  void readSubMeshInfo();
+  SMDSAbs_EntityType getElemType( const TopAbs_ShapeEnum shapeType,
+                                  const int              nbElemsInSubMesh,
+                                  bool&                  isKoType) const;
+
+  void readSubMeshes(DriverMED_R_SMESHDS_Mesh* reader) const;
+
+  // general data
+  std::string   _medFileName, _hdfFileName;
+  bool          _toRemoveFiles;
+  int           _meshID;
+  SMESH_Mesh_i* _mesh;
+  bool          _isInfoOk;
+
+  int _elemCounter; /* used as a counter while mesh info reading and
+                       as a signal that mesh info is incorrect after reading
+                     */
+};
+
+#endif
index 1ea9f59ff7bc9e1d204a63f6f3a2dab8fe5276ab..29c5443132a4a8c4d8d596032a9fbd99d258ba51 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #ifndef _SMESH_PYTHONDUMP_HXX_
 #define _SMESH_PYTHONDUMP_HXX_
 
@@ -29,6 +30,7 @@
 #include CORBA_SERVER_HEADER(SALOMEDS)
 
 #include <sstream>
+#include <vector>
 
 class SMESH_Gen_i;
 class SMESH_MeshEditor_i;
@@ -37,7 +39,7 @@ class Resource_DataMapOfAsciiStringAsciiString;
 
 // ===========================================================================================
 /*!
- * \brief Tool converting SMESH engine calls into commands defined in smesh.py
+ * \brief Tool converting SMESH engine calls into commands defined in smeshDC.py
  *
  * Implementation is in SMESH_2smeshpy.cxx
  */
@@ -51,19 +53,23 @@ public:
    * \param theScript - Input script
    * \param theEntry2AccessorMethod - The returning method names to access to
    *        objects wrapped with python class
+   * \param theHistoricalDump - true means to keep all commands, false means
+   *        to exclude commands relating to objects removed from study
    * \retval TCollection_AsciiString - Convertion result
    */
   static TCollection_AsciiString
-  ConvertScript(const TCollection_AsciiString& theScript,
+  ConvertScript(const TCollection_AsciiString&            theScript,
                 Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod,
-               Resource_DataMapOfAsciiStringAsciiString& theObjectNames);
+                Resource_DataMapOfAsciiStringAsciiString& theObjectNames,
+                SALOMEDS::Study_ptr&                      theStudy,
+                const bool                                theHistoricalDump);
 
   /*!
    * \brief Return the name of the python file wrapping IDL API
-    * \retval TCollection_AsciiString - The file name
+    * \retval const char* - the file name
    */
   static const char* SmeshpyName() { return "smesh"; }
-  static const char* GenName() { return "smesh.smesh"; }
+  static const char* GenName() { return "smesh"; }
 };
 
 namespace SMESH
@@ -72,73 +78,113 @@ namespace SMESH
   class FilterManager_i;
   class Filter_i;
   class Functor_i;
+  class Measurements_i;
 
-// ===========================================================================================
-/*!
- * \brief Utility helping in storing SMESH engine calls as python commands
- */
-// ===========================================================================================
+  // ===========================================================================================
+  /*!
+   * \brief Object used to make TPythonDump know that its held value can be a varible
+   *
+   * TPythonDump substitute TVar with names of notebook variables if any.
+   */
+  // ===========================================================================================
+
+  struct SMESH_I_EXPORT TVar
+  {
+    std::vector< std::string > myVals;
+    TVar(CORBA::Double value);
+    TVar(CORBA::Long   value);
+    TVar(CORBA::Short  value);
+    TVar(const SMESH::double_array& value);
+    // string used to temporary quote variable names in order
+    // not to confuse variables with string arguments
+    static char Quote() { return '$'; }
+  };
+
+  // ===========================================================================================
+  /*!
+   * \brief Utility helping in storing SMESH engine calls as python commands
+   */
+  // ===========================================================================================
 
   class SMESH_I_EXPORT TPythonDump
   {
     std::ostringstream myStream;
-    static size_t myCounter;
+    static size_t      myCounter;
+    int                myVarsCounter; // counts stored TVar's
   public:
     TPythonDump();
     virtual ~TPythonDump();
-    
-    TPythonDump& 
+
+    TPythonDump&
+    operator<<(const TVar& theVariableValue);
+
+    TPythonDump&
     operator<<(long int theArg);
 
-    TPythonDump& 
+    TPythonDump&
     operator<<(int theArg);
 
-    TPythonDump& 
+    TPythonDump&
     operator<<(double theArg);
 
-    TPythonDump& 
+    TPythonDump&
     operator<<(float theArg);
 
-    TPythonDump& 
+    TPythonDump&
     operator<<(const void* theArg);
 
-    TPythonDump& 
+    TPythonDump&
     operator<<(const char* theArg);
 
-    TPythonDump& 
+    TPythonDump&
     operator<<(const SMESH::ElementType& theArg);
 
-    TPythonDump& 
+    TPythonDump&
+    operator<<(const SMESH::GeometryType& theArg);
+
+    TPythonDump&
     operator<<(const SMESH::long_array& theArg);
 
-    TPythonDump& 
+    TPythonDump&
     operator<<(const SMESH::double_array& theArg);
 
-    TPythonDump& 
+    TPythonDump&
+    operator<<(const SMESH::string_array& theArg);
+
+    TPythonDump&
+    operator<<(SMESH::SMESH_Hypothesis_ptr theArg);
+
+    TPythonDump&
+    operator<<(SMESH::SMESH_IDSource_ptr theArg);
+
+    TPythonDump&
     operator<<(SALOMEDS::SObject_ptr theArg);
 
-    TPythonDump& 
+    TPythonDump&
     operator<<(CORBA::Object_ptr theArg);
 
-    TPythonDump& 
+    TPythonDump&
     operator<<(SMESH::FilterLibrary_i* theArg);
 
-    TPythonDump& 
+    TPythonDump&
     operator<<(SMESH::FilterManager_i* theArg);
 
-    TPythonDump& 
+    TPythonDump&
     operator<<(SMESH::Filter_i* theArg);
 
-    TPythonDump& 
+    TPythonDump&
     operator<<(SMESH::Functor_i* theArg);
 
-    TPythonDump& 
+    TPythonDump&
+    operator<<(SMESH::Measurements_i* theArg);
+
+    TPythonDump&
     operator<<(SMESH_Gen_i* theArg);
 
-    TPythonDump& 
+    TPythonDump&
     operator<<(SMESH_MeshEditor_i* theArg);
 
-    TPythonDump& 
+    TPythonDump&
     operator<<(SMESH::MED_VERSION theArg);
 
     TPythonDump&
@@ -147,18 +193,27 @@ namespace SMESH
     TPythonDump&
     operator<<(const SMESH::DirStruct & theDir);
 
+    TPythonDump&
+    operator<<(const SMESH::PointStruct & P);
+
     TPythonDump&
     operator<<(const TCollection_AsciiString & theArg);
 
+    TPythonDump&
+    operator<<(const SMESH::ListOfGroups& theList);
+
     TPythonDump&
     operator<<(const SMESH::ListOfGroups * theList);
 
+    TPythonDump&
+    operator<<(const SMESH::ListOfIDSources& theList);
+
     static const char* SMESHGenName() { return "smeshgen"; }
     static const char* MeshEditorName() { return "mesh_editor"; }
 
     /*!
      * \brief Return marker of long string literal beginning
-      * \param type - a name of functionality producing the string literal 
+      * \param type - a name of functionality producing the string literal
       * \retval TCollection_AsciiString - the marker string to be written into
       * a raw python script
      */
@@ -176,7 +231,7 @@ namespace SMESH
       * \param theLongString - the retrieved literal
       * \param theStringType - a name of functionality produced the literal
       * \retval bool - true if a string literal found
-     * 
+     *
      * The literal is removed from theText; theFrom points position right after
      * the removed literal
      */
index f90cb300a536a2729e311d12c34e06dd89955bbc..fd7fc3d80839ddad56455721cf4bcdb33c522f52 100644 (file)
@@ -1,33 +1,34 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : SMESH_subMesh_i.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//  $Header$
 //
 #include "SMESH_subMesh_i.hxx"
 #include "SMESH_Gen_i.hxx"
 #include "SMESH_Mesh_i.hxx"
+#include "SMESH_PreMeshInfo.hxx"
 
 #include "Utils_CorbaException.hxx"
 #include "utilities.h"
@@ -49,7 +50,7 @@ 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);
+  ASSERT(0);
 }
 
 //=============================================================================
@@ -59,16 +60,15 @@ SMESH_subMesh_i::SMESH_subMesh_i()
 //=============================================================================
 
 SMESH_subMesh_i::SMESH_subMesh_i( PortableServer::POA_ptr thePOA,
-                                 SMESH_Gen_i*            gen_i,
-                                 SMESH_Mesh_i*           mesh_i,
-                                 int                     localId )
+                                  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;
-  // ****
+  _preMeshInfo = NULL;
 }
 //=============================================================================
 /*!
@@ -79,7 +79,8 @@ SMESH_subMesh_i::SMESH_subMesh_i( PortableServer::POA_ptr thePOA,
 SMESH_subMesh_i::~SMESH_subMesh_i()
 {
   MESSAGE("SMESH_subMesh_i::~SMESH_subMesh_i");
-  // ****
+  if ( _preMeshInfo ) delete _preMeshInfo;
+  _preMeshInfo = NULL;
 }
 
 //=======================================================================
@@ -161,7 +162,10 @@ CORBA::Long SMESH_subMesh_i::GetNumberOfElements()
   throw (SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
-  MESSAGE("SMESH_subMesh_i::GetNumberOfElements");
+
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbElements();
+
   if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
     return 0;
 
@@ -191,10 +195,15 @@ CORBA::Long SMESH_subMesh_i::GetNumberOfNodes(CORBA::Boolean all)
   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;
 
+  if ( _preMeshInfo )
+  {
+    if ( all ) return _preMeshInfo->NbNodes();
+    else _preMeshInfo->FullLoadFromFile();
+  }
   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
   SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
 
@@ -257,12 +266,15 @@ 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();
 
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
   SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
 
@@ -304,12 +316,15 @@ SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theEle
     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();
 
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
   SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
 
@@ -412,7 +427,7 @@ 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 = GetElementsByType( SMESH::NODE );
   return aResult._retn();
 }
@@ -427,7 +442,6 @@ SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetFather()
   throw (SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
-  MESSAGE("SMESH_subMesh_i::GetFather");
   return _mesh_i->_this();
 }
 
@@ -439,7 +453,6 @@ SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetFather()
   
 CORBA::Long SMESH_subMesh_i::GetId()
 {
-  MESSAGE("SMESH_subMesh_i::GetId");
   return _localId;
 }
 
@@ -458,11 +471,11 @@ GEOM::GEOM_Object_ptr SMESH_subMesh_i::GetSubShape()
       TopoDS_Shape S = _mesh_i->_mapSubMesh[ _localId ]->GetSubShape();
       if ( !S.IsNull() ) {
         aShapeObj = _gen_i->ShapeToGeomObject( S );
-       //mzn: N7PAL16232, N7PAL16233
-       //In some cases it's possible that GEOM_Client contains the shape same to S, but
-       //with another orientation.
-       if (aShapeObj->_is_nil())
-         aShapeObj = _gen_i->ShapeToGeomObject( S.Reversed() );
+        //mzn: N7PAL16232, N7PAL16233
+        //In some cases it's possible that GEOM_Client contains the shape same to S, but
+        //with another orientation.
+        if (aShapeObj->_is_nil())
+          aShapeObj = _gen_i->ShapeToGeomObject( S.Reversed() );
       }
     }
   }
@@ -481,6 +494,8 @@ SALOME_MED::FAMILY_ptr SMESH_subMesh_i::GetFamily()
   throw (SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
   SALOME_MED::MESH_var MEDMesh = GetFather()->GetMEDMesh();
 
   SALOME_MED::Family_array_var families = 
@@ -501,8 +516,7 @@ SALOME_MED::FAMILY_ptr SMESH_subMesh_i::GetFamily()
 //=============================================================================
 SMESH::long_array* SMESH_subMesh_i::GetIDs()
 {
-  SMESH::long_array_var aResult = GetElementsId();
-  return aResult._retn();
+  return GetElementsId();
 }
 
 //=============================================================================
@@ -513,5 +527,100 @@ SMESH::long_array* SMESH_subMesh_i::GetIDs()
 SMESH::ElementType SMESH_subMesh_i::GetElementType( const CORBA::Long id, const bool iselem )
   throw (SALOME::SALOME_Exception)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
   return GetFather()->GetElementType( id, iselem );
 }
+
+
+//=============================================================================
+/*!
+ * Returns statistic of mesh elements
+ * Result array of number enityties
+ * Inherited from SMESH_IDSource
+ */
+//=============================================================================
+SMESH::long_array* SMESH_subMesh_i::GetMeshInfo()
+{
+  if ( _preMeshInfo )
+    return _preMeshInfo->GetMeshInfo();
+
+  SMESH::long_array_var aRes = new SMESH::long_array();
+  aRes->length(SMESH::Entity_Last);
+  for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
+    aRes[i] = 0;
+  
+  // get number of nodes
+  aRes[ SMESH::Entity_Node ] = GetNumberOfNodes(true);
+  ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
+
+  // get statistic from child sub-meshes
+  TListOfSubMeshes smList;
+  if ( getSubMeshes( aSubMesh, smList ) )
+    for ( TListOfSubMeshes::iterator sm = smList.begin(); sm != smList.end(); ++sm )
+      SMESH_Mesh_i::CollectMeshInfo( (*sm)->GetElements(), aRes );
+
+  return aRes._retn();
+}
+
+
+//=======================================================================
+//function : GetTypes
+//purpose  : Returns types of elements it contains
+//=======================================================================
+
+SMESH::array_of_ElementType* SMESH_subMesh_i::GetTypes()
+{
+  if ( _preMeshInfo )
+    return _preMeshInfo->GetTypes();
+
+  SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
+
+  ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
+  if ( SMESHDS_SubMesh* smDS = aSubMesh->GetSubMeshDS() )
+  {
+    SMDS_ElemIteratorPtr eIt = smDS->GetElements();
+    if ( eIt->more() )
+    {
+      types->length( 1 );
+      types[0] = SMESH::ElementType( eIt->next()->GetType());
+    }
+    else if ( smDS->GetNodes()->more() )
+    {
+      TopoDS_Shape shape = aSubMesh->GetSubShape();
+      while ( !shape.IsNull() && shape.ShapeType() == TopAbs_COMPOUND )
+      {
+        TopoDS_Iterator it( shape );
+        shape = it.More() ? it.Value() : TopoDS_Shape();
+      }
+      if ( !shape.IsNull() && shape.ShapeType() == TopAbs_VERTEX )
+      {
+        types->length( 1 );
+        types[0] = SMESH::NODE;
+      }
+    }
+  }
+  return types._retn();
+}
+
+//=======================================================================
+//function : GetMesh
+//purpose  : interface SMESH_IDSource
+//=======================================================================
+
+SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetMesh()
+{
+  return GetFather();
+}
+
+//=======================================================================
+//function : IsMeshInfoCorrect
+//purpose  : * Returns false if GetMeshInfo() returns incorrect information that may
+//           * happen if mesh data is not yet fully loaded from the file of study.
+//=======================================================================
+
+bool SMESH_subMesh_i::IsMeshInfoCorrect()
+{
+  return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
+}
index fcfc5673b2c0585175e6458793f1078af79b4d9d..d9cf053a695c46dea1383a06738c46a63c5acd3f 100644 (file)
@@ -1,29 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : SMESH_subMesh_i.hxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//  $Header$
 //
 #ifndef _SMESH_SUBMESH_I_HXX_
 #define _SMESH_SUBMESH_I_HXX_
@@ -40,7 +40,7 @@
 #include "SMESH_Mesh_i.hxx"
 
 class SMESH_Gen_i;
-class SMESH_Mesh_i;
+class SMESH_PreMeshInfo;
 
 class SMESH_I_EXPORT SMESH_subMesh_i:
   public virtual POA_SMESH::SMESH_subMesh,
@@ -50,8 +50,8 @@ public:
   SMESH_subMesh_i();
   SMESH_subMesh_i( PortableServer::POA_ptr thePOA,
                    SMESH_Gen_i*            gen_i,
-                  SMESH_Mesh_i*           mesh_i,
-                  int                     localId );
+                   SMESH_Mesh_i*           mesh_i,
+                   int                     localId );
   ~SMESH_subMesh_i();
 
   CORBA::Long GetNumberOfElements()
@@ -66,9 +66,6 @@ public:
   SMESH::long_array* GetElementsByType( SMESH::ElementType theElemType )
     throw (SALOME::SALOME_Exception);
   
-  //for omniORB conflict compilation
-  /*SMESH::ElementType GetElementType( const CORBA::Long id, const bool iselem )
-    throw (SALOME::SALOME_Exception);*/
   SMESH::ElementType GetElementType( CORBA::Long id, bool iselem )
     throw (SALOME::SALOME_Exception);
   
@@ -81,21 +78,53 @@ public:
   GEOM::GEOM_Object_ptr GetSubShape()
     throw (SALOME::SALOME_Exception);
 
-  CORBA::Long GetId();   
+  CORBA::Long GetId();
 
   SALOME_MED::FAMILY_ptr GetFamily()
     throw (SALOME::SALOME_Exception);
 
+
+  // =========================
+  // interface SMESH_IDSource
+  // =========================
+  /*!
+   * Returns a sequence of all element IDs
+   */
   virtual SMESH::long_array* GetIDs();
+  /*!
+   * Returns statistic of mesh elements
+   * Result array of number enityties
+   * Inherited from SMESH_IDSource
+   */
+  virtual SMESH::long_array* GetMeshInfo();
+  /*!
+   * Returns types of elements it contains
+   */
+  virtual SMESH::array_of_ElementType* GetTypes();
+  /*!
+   * Returns the mesh
+   */
+  virtual SMESH::SMESH_Mesh_ptr GetMesh();
+  /*!
+   * Returns false if GetMeshInfo() returns incorrect information that may
+   * happen if mesh data is not yet fully loaded from the file of study.
+   */
+  virtual bool IsMeshInfoCorrect();
 
-  SMESH_Mesh_i* _mesh_i; //NRI
 
 protected:
-  void changeLocalId(int localId) { _localId = localId; }
-  SMESH_Gen_i* _gen_i;
-  int _localId;
 
+  SMESH_Gen_i*  _gen_i;
+  int           _localId;
+  SMESH_Mesh_i* _mesh_i; //NRI
+
+  void changeLocalId(int localId) { _localId = localId; }
   friend void SMESH_Mesh_i::CheckGeomGroupModif();
+
+  SMESH_PreMeshInfo* _preMeshInfo; // mesh info before full loading from study file
+
+  SMESH_PreMeshInfo* & changePreMeshInfo() { return _preMeshInfo; }
+  friend class SMESH_PreMeshInfo;
 };
 
 #endif
index 869ea8108e40298aa184cb2ced887e8d8e2d6912..fa01ce28fe1bd21a42899120ac7308913d99659f 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 #  File   : smeshpy.py
 #  Module : SMESH
diff --git a/src/SMESH_PY/Makefile.am b/src/SMESH_PY/Makefile.am
new file mode 100644 (file)
index 0000000..3219c85
--- /dev/null
@@ -0,0 +1,25 @@
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# 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.com
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+salomepypkgdir = $(smeshpypkgdir)
+salomepypkg_PYTHON = \
+       __init__.py        \
+       smeshstudytools.py
diff --git a/src/SMESH_PY/__init__.py b/src/SMESH_PY/__init__.py
new file mode 100644 (file)
index 0000000..f333c92
--- /dev/null
@@ -0,0 +1,19 @@
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2010-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# 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.com
+#
diff --git a/src/SMESH_PY/smeshstudytools.py b/src/SMESH_PY/smeshstudytools.py
new file mode 100644 (file)
index 0000000..7281fe5
--- /dev/null
@@ -0,0 +1,214 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# 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.com
+#
+"""
+This module provides a new class :class:`SMeshStudyTools` to facilitate the
+use of mesh objects in Salome study.
+"""
+
+import salome
+SMESH = None    # SMESH module is loaded only when needed
+
+from salome.kernel.studyedit import getStudyEditor
+try:
+    from salome.gui import helper
+except ImportError:
+    pass
+
+class SMeshStudyTools:
+    """
+    This class provides several methods to manipulate mesh objects in Salome
+    study. The parameter `studyEditor` defines a
+    :class:`~salome.kernel.studyedit.StudyEditor` object used to access the study. If
+    :const:`None`, the method returns a :class:`~salome.kernel.studyedit.StudyEditor`
+    object on the current study.
+
+    .. attribute:: editor
+    
+       This instance attribute contains the underlying
+       :class:`~salome.kernel.studyedit.StudyEditor` object. It can be used to access
+       the study but the attribute itself should not be modified.
+
+    """
+
+    def __init__(self, studyEditor = None):
+        global SMESH
+        if SMESH is None:
+            SMESH = __import__("SMESH")
+        if studyEditor is None:
+            studyEditor = getStudyEditor()
+        self.editor = studyEditor
+        self.smeshGui = None
+
+    def updateStudy(self, studyId=None):
+        """
+        This function updates the tools so that it works on the
+        specified study.
+        """
+        self.editor = getStudyEditor(studyId)
+        
+    def getMeshFromGroup(self, meshGroupItem):
+        """
+        Get the mesh item owning the mesh group `meshGroupItem`.
+
+        :type   meshGroupItem: SObject
+        :param  meshGroupItem: Mesh group belonging to the searched mesh.
+        
+        :return: The SObject corresponding to the mesh, or None if it was not
+                 found.
+        """
+        meshItem = None
+        obj = self.editor.getOrLoadObject(meshGroupItem)
+        group = obj._narrow(SMESH.SMESH_GroupBase)
+        if group is not None: # The type of the object is ok
+            meshObj = group.GetMesh()
+            meshItem = salome.ObjectToSObject(meshObj)
+        return meshItem
+
+
+    def getMeshObjectSelected(self):
+        '''
+        Returns the MESH object currently selected in the active study.
+        '''
+        sobject, entry = helper.getSObjectSelected()
+        meshObject = self.getMeshObjectFromEntry(entry)
+        return meshObject
+
+    def getMeshObjectFromEntry(self, entry):
+        '''
+        Returns the MESH object associated to the specified entry,
+        (the entry is the identifier of an item in the objects browser).
+        '''
+        if entry is None:
+            return None
+        import smesh
+        smesh.SetCurrentStudy(self.editor.study)
+        meshObject=smesh.IDToObject(entry)
+        return meshObject
+
+    def getMeshObjectFromSObject(self, sobject):
+        '''
+        Returns the SMESH object associated to the specified SObject,
+        (the SObject is an item in the objects browser).
+        '''
+        if sobject is None:
+            return None
+        
+        obj = self.editor.getOrLoadObject(sobject)
+        meshObject = obj._narrow(SMESH.SMESH_Mesh)
+        return meshObject
+
+    def displayMeshObjectFromEntry(self,entry):
+        '''
+        Display the SMESH object associated to the specified entry
+        (the entry is the identifier of an item in the objects browser).    
+        '''
+        if self.smeshGui is None:
+            self.smeshGui = salome.ImportComponentGUI("SMESH")
+
+        if not helper.SalomeGUI.hasDesktop():
+            print "displayMeshObject: no desktop available"
+            return
+        self.smeshGui.CreateAndDisplayActor(entry)
+
+#
+# ==================================================================
+# Use cases and demo functions
+# ==================================================================
+#
+
+# CAUTION: Before running this test functions, you first have to
+# create (or import) an smesh object and select this object in the
+# objects browser. You can run the box mesh creation procedure below
+# instead.
+
+# How to test?
+# 1. Run a SALOME application including GEOM and SMESH, and create a new study
+# 2. In the console, enter:
+#    >>> from salome.smesh import smeshstudytools
+#    >>> smeshstudytools.TEST_createBoxMesh()
+# 3. Select the object named "boxmesh" in the browser
+# 4. In the console, enter:
+#    >>> smeshstudytools.TEST_selectAndExport_01()
+#    >>> smeshstudytools.TEST_selectAndExport_02()
+#    >>> smeshstudytools.TEST_display()
+
+
+def TEST_createBoxMesh():
+    theStudy = helper.getActiveStudy()
+    
+    import geompy
+    geompy.init_geom(theStudy)
+    box = geompy.MakeBoxDXDYDZ(200, 200, 200)
+
+    import smesh, SMESH, SALOMEDS    
+    smesh.SetCurrentStudy(theStudy)
+    import StdMeshers
+    boxmesh = smesh.Mesh(box)
+    Regular_1D = boxmesh.Segment()
+    Nb_Segments_1 = Regular_1D.NumberOfSegments(15)
+    Nb_Segments_1.SetDistrType( 0 )
+    Quadrangle_2D = boxmesh.Quadrangle()
+    Hexa_3D = smesh.CreateHypothesis('Hexa_3D')
+    status = boxmesh.AddHypothesis(Hexa_3D)
+    isDone = boxmesh.Compute()
+
+    smesh.SetName(boxmesh.GetMesh(), 'boxmesh')
+    if salome.sg.hasDesktop():
+        salome.sg.updateObjBrowser(1)
+
+#
+# Definitions:
+# - the SObject is an item in the study (Study Object).
+# - the entry is the identifier of an item.
+# - the object (geom object or smesh object) is a CORBA servant
+#   embedded in the SALOME component container and with a reference in
+#   the SALOME study, so that it can be retrieved.
+#
+
+def TEST_selectAndExport_01():
+    tool = SMeshStudyTools()
+    myMesh = tool.getMeshObjectSelected()
+    myMesh.ExportUNV("/tmp/myMesh.unv")
+
+def TEST_selectAndExport_02():
+    # In this case, we want to retrieve the name of the mesh in the
+    # object browser. Note that in SALOME, a mesh object has no
+    # name. Only the SObject in the object browser has a name
+    # attribute.
+    tool = SMeshStudyTools()
+
+    mySObject, myEntry = helper.getSObjectSelected()
+    myName = mySObject.GetName()
+
+    myMesh = tool.getMeshObjectFromEntry(myEntry)
+    exportFileName = "/tmp/"+myName+".unv"
+    myMesh.ExportUNV(exportFileName)
+
+def TEST_display():
+    mySObject, myEntry = helper.getSObjectSelected()
+
+    tool = SMeshStudyTools()
+    tool.displayMeshObjectFromEntry(myEntry)
+
+if __name__ == "__main__":
+    TEST_selectAndExport_01()
+    TEST_selectAndExport_02()
+    TEST_display()
index 7b6ef9fe4f8c416a4aeca70ee4ebe176a109bb95..ab94f663c9f46ef3cbabaf6c711c7a442cc9c94f 100644 (file)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  File   : Makefile.in
 #  Author : Nicolas REJNERI, Paul RASCLE
 #  Modified by : Alexander BORODIN (OCN) - autotools usage
@@ -31,6 +29,7 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am
 dist_salomescript_DATA= \
        smesh.py \
        smeshDC.py \
+       StdMeshersDC.py \
        batchmode_smesh.py \
        batchmode_mefisto.py \
        ex00_all.py \
index c1138f9be01c9f62e5f8556d4d62adc9c5854daa..bbfdd1abf6612c0ecb4009ec9055ecce9ee2999a 100755 (executable)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 import salome
 import geompy
 import smesh
@@ -53,7 +55,7 @@ Id_face1 = geompy.addToStudy(face1,"Face1")
 
 
 #-----------------------------SMESH-------------------------------------------
-
+smesh.SetCurrentStudy(salome.myStudy)
 
 # -- Init mesh --
 plane_mesh = salome.IDToObject( Id_face1)
index 678f6db30eb84edd5d21f439c04e87f0ed5b45de..8db9bf12ffb375d018fdbb37fa64e85643bcbd2c 100755 (executable)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  File        : SMESH_testExtrusion2D.py
 #  Module      : SMESH
 #  Description : Create meshes to test extrusion of mesh elements along path
@@ -51,6 +53,7 @@ id_ellipse2 = geompy.addToStudy(ellipse2, "Ellips 2")
 
 
 #---------------------------------SMESH
+smesh.SetCurrentStudy(salome.myStudy)
 
 # create the path mesh
 mesh1 = smesh.Mesh(ellipse1, "Path Mesh")
index e40854bbe46a149c42d35031c97889cf064c498d..9607f9bb7f410abae4e4f041c0b0c1bda887553d 100755 (executable)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  File        : SMESH_testExtrusion3D.py
 #  Module      : SMESH
 #  Description : Create meshes to test extrusion of mesh elements along path
@@ -49,6 +51,7 @@ idcircle = geompy.addToStudy(circle, "Circle")
 idface   = geompy.addToStudy(face,   "Circular face")
 
 
+smesh.SetCurrentStudy(salome.myStudy)
 
 # init a Mesh with the circular face
 mesh1 = smesh.Mesh(face, "Mesh on circular face")
index 86e8ce1f023fbd51dd59f70b907da1e72bc3617e..958dba283651ccf56b05c4e05a87ea083fe27504 100644 (file)
@@ -1,27 +1,32 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# -*- coding: utf-8 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
+import salome
 import smesh
 import math
 
+salome.salome_init()
+
 def GetNewNodes(mesh,Elems,OldNodes):
     """
     Auxilary function, which return list of nodes from
@@ -50,7 +55,8 @@ def GetNewNodes(mesh,Elems,OldNodes):
         pass
     return newnodes
             
-    
+smesh.SetCurrentStudy(salome.myStudy)
+
 # create empty mesh
 mesh = smesh.Mesh()
 
index b66986067fb1048d67e57b6f34f184995594bdd9..d1ef60872d3cea477148cd5f6f1653cdd70842f5 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 from SMESH_test1 import *
 
 ## Old style
@@ -38,6 +40,7 @@ def CheckBelongToGeomFilterOld(theMeshGen, theMesh, theShape, theSubShape, theEl
     aBelongToGeom.SetElementType(theElemType)
     
     aFilter.SetPredicate(aBelongToGeom)
+    aFilterMgr.UnRegister()
     return aFilter.GetElementsId(theMesh)
 
 ## Current style
index 87c7e47cab36b1d5eb2bd1259d61070980c356f0..0c1a9126d21c7d08d261d537adac78f676023a83 100644 (file)
@@ -1,24 +1,23 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  File   : SMESH_BuildCompound.py
 #  Author : Alexander KOVALEV
 #  Module : SMESH
@@ -28,6 +27,7 @@
 # ! as some sequences of symbols from this example are used during
 # ! documentation generation to identify certain places of this file
 #
+import salome
 import geompy
 import smesh
 
@@ -60,6 +60,8 @@ geompy.addToStudy(Box_sup, "Box_sup")
 geompy.addToStudyInFather(Box_sup, Fsup2, "Fsup")
 geompy.addToStudyInFather(Box_sup, Finf2, "Finf")
 
+smesh.SetCurrentStudy(salome.myStudy)
+
 ## create a bottom mesh
 Mesh_inf = smesh.Mesh(Box_inf, "Mesh_inf")
 algo1D_1=Mesh_inf.Segment()
@@ -93,6 +95,6 @@ Compound1 = smesh.smesh.Concatenate([Mesh_inf.GetMesh(), Mesh_sup.GetMesh()], 0,
 smesh.SetName(Compound1, 'Compound_with_RenamedGrps_and_MergeElems')
 # create a compound of two meshes with uniting groups with the same names and
 # creating groups of all elements
-Compound2 = smesh.smesh.ConcatenateWithGroups([Mesh_inf.GetMesh(), Mesh_sup.GetMesh()], 1, 0, 1e-05)
+Compound2 = smesh.smesh.Concatenate([Mesh_inf.GetMesh(), Mesh_sup.GetMesh()], 1, 0, 1e-05, True)
 smesh.SetName(Compound2, 'Compound_with_UniteGrps_and_GrpsOfAllElems')
 #end
index 1bc88014bc125f89e79e1f8ecdbf33c77eda4bd4..8c746d15ed91b06adccbe0b24ae5e4868a6c169e 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  File   : SMESH_GroupFromGeom.py
 #  Module : SMESH
 #
index 0b15ecbac335c8bdefc03c8f52fb6f033c1e677a..02ec044feabfb1200bc8f84b1569fb94ebdc2d38 100755 (executable)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #==============================================================================
 #  Info.
 #  Bug (from script, bug)   : SMESH_GroupFromGeom.py, PAL6945
index 67d498fad333f5ea22399b4528b415b28745b6f7..03978e0d50ef3b82dd55e3bb5ae1ad2b3f42a44c 100644 (file)
@@ -1,26 +1,31 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
+import salome
 import smesh
 
+smesh.SetCurrentStudy(salome.myStudy)
+
 def BuildGroupLyingOn(theMesh, theElemType, theName, theShape):
     aFilterMgr = smesh.smesh.CreateFilterManager()
     aFilter = aFilterMgr.CreateFilter()
@@ -31,6 +36,7 @@ def BuildGroupLyingOn(theMesh, theElemType, theName, theShape):
     
     aFilter.SetPredicate(aLyingOnGeom)
     anIds = aFilter.GetElementsId(theMesh)
+    aFilterMgr.UnRegister()
 
     aGroup = theMesh.CreateGroup(theElemType, theName)
     aGroup.Add(anIds)
index 6d2ac9e867a78c6c2b6bc7a1731605b5932f2b93..e292cbc2a73d4f1600926636ca4e3dfca3195a81 100755 (executable)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #####################################################################
 #Created                :17/02/2005
 #Auhtor                 :MASLOV Eugeny, KOVALTCHUK Alexey 
@@ -72,7 +74,7 @@ for i in range(0, len(CommonExplodedListEdges)):
 
 #Fillet applying
 print "Fillet creation..."
-Fillet_1 = geompy.MakeFillet(Common_1, 10, geompy.ShapeType["EDGE"], [6])
+Fillet_1 = geompy.MakeFillet(Common_1, 10, geompy.ShapeType["EDGE"], [5])
 geompy.addToStudy(Fillet_1, "Fillet_1")
 
 #Chamfer applying
@@ -85,7 +87,7 @@ geompy.addToStudy(Chamfer_2, "Chamfer_2")
 #Import of the shape from "slots.brep"
 print "Import multi-rotation from the DATA_DIR/Shapes/Brep/slots.brep"
 thePath = os.getenv("DATA_DIR")
-theFileName = thePath + "/Shapes/Brep/slots.brep"
+theFileName = os.path.join( thePath,"Shapes","Brep","slots.brep")
 theShapeForCut = geompy.ImportBREP(theFileName)
 geompy.addToStudy(theShapeForCut, "slot.brep_1")
 
@@ -96,6 +98,8 @@ Cut_1_ID = geompy.addToStudy(Cut_1, "Cut_1")
 
 #Mesh creation
 
+smesh.SetCurrentStudy(salome.myStudy)
+
 # -- Init --
 shape_mesh = salome.IDToObject( Cut_1_ID )
 
index 11a68dfa4cb1779214499b02c71544212c68c91b..ddd5bb16ec139d3d0a5be5498319ce79f4f15c2d 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # Tetrahedrization of the geometry generated by the Python script GEOM_Partition1.py
 # Hypothesis and algorithms for the mesh generation are global
 # -- Rayon de la bariere
@@ -86,7 +88,7 @@ print "number of Edges  in alveole : ", len(subEdgeList)
 
 subshapes = geompy.SubShapeAll(alveole, geompy.ShapeType["SHAPE"])
 
-## there are 9 subshapes
+## there are 9 sub-shapes
 
 comp1 = geompy.MakeCompound( [ subshapes[0], subshapes[1] ] )
 comp2 = geompy.MakeCompound( [ subshapes[2], subshapes[3] ] )
@@ -118,6 +120,7 @@ status = geompy.CheckShape(alveole)
 print " check status ", status
 
 # ---- launch SMESH
+smesh.SetCurrentStudy(salome.myStudy)
 
 # ---- init a Mesh with the alveole
 shape_mesh = salome.IDToObject( idalveole )
index b399178191e07c7ca6eb4b0f23de6e29c72f23fb..64a3907523040b0433711d9fff4b4152a4cdfb4a 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  GEOM GEOM_SWIG : binding of C++ omplementaion with Python
 #  File   : GEOM_Sphere.py
 #  Author : Damien COQUERET, Open CASCADE
@@ -77,8 +79,8 @@ Cube  = MakeHexa2Faces(Face1, Face3)
 Common1 = MakeBoolean(Sphere, Block, 1)
 Common2 = MakeRotation(Common1, VZ, Angle90)
 
-MultiBlock1 = MakeMultiTransformation1D(Common1, 21, -1, 3)
-MultiBlock2 = MakeMultiTransformation1D(Common2, 31, -1, 3)
+MultiBlock1 = MakeMultiTransformation1D(Common1, 20, -1, 3)
+MultiBlock2 = MakeMultiTransformation1D(Common2, 30, -1, 3)
 
 #Reconstruct sphere from several blocks
 ShapesList.append(Cube)
@@ -102,6 +104,7 @@ Id_Result      = addToStudy(Result, "Result")
 
 #-----------------------------------------------------------------------
 #Meshing
+smesh.SetCurrentStudy(salome.myStudy)
 my_hexa = smesh.Mesh(Result, "Sphere_Mesh")
 algo = my_hexa.Segment()
 algo.NumberOfSegments(NbSeg)
index e61ce50f21c11301b783d9c1b1b599e1fcd5bc86..2de2a408f0458e54324754baf8fa4eb58a37c0e9 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  SMESH SMESH_SWIG : binding of C++ implementaion with Python
 #  File   : SMESH_blocks.py
 #  Author : Julia DOROVSKIKH
@@ -35,6 +37,7 @@ import GEOM_Spanner
 isBlocksTest = 0 # False
 isMeshTest   = 1 # True
 
+smesh.SetCurrentStudy(salome.myStudy)
 
 GEOM_Spanner.MakeSpanner(geompy, math, isBlocksTest, isMeshTest, smesh)
 
index b57138a1c5aa3ba04bd2f1891a6c0eecd4b439a3..8680208cb4a5b4bf150cc4a76f34e43016314d7f 100755 (executable)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #==============================================================================
 #  Info.
 #  Bug (from script, bug)   : box.py, PAL5223
@@ -46,6 +48,7 @@ box    = geompy.MakeBox(0.,0.,0.,1.,1.,1.)
 boxId  = geompy.addToStudy(box,"box")
 
 # ---- SMESH
+smesh.SetCurrentStudy(salome.myStudy)
 
 # ---- init a Mesh
 
index c77f1f00142ea3667db881d68201bfb60c123270..0aaa8cbab14417ccf62a6d7dd7ea31991098d072 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # Tetrahedrization of the geometry union of 2 boxes having a face in common
 # Hypothesis and algorithms for the mesh generation are global
 #
@@ -72,6 +74,7 @@ print "number of Edges  in shell : ", len(subEdgeList)
 
 
 ### ---------------------------- SMESH --------------------------------------
+smesh.SetCurrentStudy(salome.myStudy)
 
 # ---- init a Mesh with the shell
 
index e13fd86590c6211849b9957bb25449879f472782..503ff4f878fa94bdf278e1da253d5e743c5e69b7 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # Tetrahedrization of the geometry union of 3 boxes aligned where the middle
 # one has a race in common with the two others.
 # Hypothesis and algorithms for the mesh generation are global
@@ -83,7 +85,7 @@ print "number of Edges  in shell : ", len(subEdgeList)
 
 
 ### ---------------------------- SMESH --------------------------------------
-
+smesh.SetCurrentStudy(salome.myStudy)
 
 # ---- init a Mesh with the shell
 
index 39dd1db2debcec10a933a77018e0c9a0edf3f15d..4aff584117fe799cca484443b2dd9b8a34a9c8e4 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # Tetrahedrization of a simple box. Hypothesis and algorithms for
 # the mesh generation are global
 #
@@ -44,6 +46,7 @@ print "number of Edges  in box : ", len(subEdgeList)
 
 
 ### ---------------------------- SMESH --------------------------------------
+smesh.SetCurrentStudy(salome.myStudy)
 
 # ---- init a Mesh with the boxe
 
index 18cdb4a4cc940d4ce59413d7802e746c57f9280e..d7f533cab41766d84e3afd6279050193e78d2443 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  File   : SMESH_control.py
 #  Author : Sergey LITONIN
 #  Module : SMESH
@@ -126,4 +128,16 @@ print "Criterion: Borders at multi-connections = 2 Nb = ", len( anIds )
   #print anIds[ i ]
 
 
+# Criterion : Element Diameter 2D > 10
+
+# create group
+aGroup = mesh.MakeGroup("Element Diameter 2D > 10", smesh.FACE, smesh.FT_MaxElementLength2D, smesh.FT_MoreThan, 10 )
+
+# print result
+anIds = aGroup.GetIDs()
+print "Criterion: Element Diameter 2D > 10 Nb = ", len( anIds )
+#for i in range( len( anIds ) ):
+  #print anIds[ i ]
+
+
 salome.sg.updateObjBrowser(1)
index 245fccec4b652631dff625b1484dcb6d67e0c855..555ad5b088ba5e9c6f7950d4a02e46020b52f2ab 100755 (executable)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #==============================================================================
 #  Info.
 #  Bug (from script, bug)   : SMESH_demo_hexa2_upd.py, PAL6781
@@ -123,6 +125,7 @@ for i in range(8):
     idEdgeZ.append(geompy.addToStudyInFather(vol,edgeZ[i],"EdgeZ"+str(i+1)))
 
 ### ---------------------------- SMESH --------------------------------------
+smesh.SetCurrentStudy(salome.myStudy)
 
 # ---- init a Mesh with the volume
 
index 597b1d0eae861da9d0beb7fcbe72665ebe9d3e5e..e5a68fdecb82afa8e42e673f01ef66f4a54be143 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  File   : SMESH_fix_volute.py
 #  Author : Paul RASCLE, EDF
 #  Module : SMESH
index 5195cc9ae07d78606ce6ae9a82fd232feaf69275..3110f003ae823a2b96a85dfe5a5499986212def4 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # Hexahedrization of the geometry generated by the Python script
 # SMESH_fixation.py
 # Hypothesis and algorithms for the mesh generation are global
@@ -44,6 +46,7 @@ status = geompy.CheckShape(compshell)
 print " check status ", status
 
 ### ---------------------------- SMESH --------------------------------------
+smesh.SetCurrentStudy(salome.myStudy)
 
 # ---- init a Mesh with the compshell
 shape_mesh = salome.IDToObject( idcomp  )
index ae003973525063341437aa047333bdccec98af19..f3374b7bf61857cc283d4b9bfd89e89ede370909 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # Tetrahedrization of the geometry generated by the Python script
 # SMESH_fixation.py
 # The new Netgen algorithm is used that discretizes baoundaries itself
@@ -44,6 +46,7 @@ status = geompy.CheckShape(compshell)
 print " check status ", status
 
 ### ---------------------------- SMESH --------------------------------------
+smesh.SetCurrentStudy(salome.myStudy)
 
 print "-------------------------- create Mesh, algorithm, hypothesis"
 
index bb190b30f4d66179687d56684fb309ffbd7ba2be..b94c354a33961569521d43276835d6bb19eb5be7 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # Tetrahedrization of the geometry generated by the Python script
 # SMESH_fixation.py
 # Hypothesis and algorithms for the mesh generation are global
@@ -44,6 +46,7 @@ status = geompy.CheckShape(compshell)
 print " check status ", status
 
 ### ---------------------------- SMESH --------------------------------------
+smesh.SetCurrentStudy(salome.myStudy)
 
 # ---- init a Mesh with the compshell
 
index 6aa8d37164882540d00beb59c1df2dd2351cc1de..2d5206194e2f6632d05de74c098122ca68527386 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # Triangulation of the skin of the geometry from a Brep representing a plane
 # Hypothesis and algorithms for the mesh generation are global
 #
@@ -54,6 +56,7 @@ print "number of Edges  in flight : ", len(subEdgeList)
 
 
 ### ---------------------------- SMESH --------------------------------------
+smesh.SetCurrentStudy(salome.myStudy)
 
 # ---- init a Mesh with the shell
 shape_mesh = salome.IDToObject( idShape )
index b1c1e8b9b7c521144491aca287d4282b69f551ad..56b3fe13fe0f434094d061c8058f9dae30022f0f 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 import salome
 import geompy
 import smesh
@@ -40,6 +42,7 @@ idbox = geompy.addToStudy( aBox, "box" )
 aBox  = salome.IDToObject( idbox )
 
 # Create mesh
+smesh.SetCurrentStudy(salome.myStudy)
 
 mesh = smesh.Mesh(aBox, "Mesh_freebord")
 
index d32e9b0bd1012101f445f6c4708bd39df041be28..4159ded6494812302579385cc24b897daea8c803 100755 (executable)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #==============================================================================
 #  Info.
 #  Bug (from script, bug)   : hexaedre_modified.py, PAL6194, PAL7153
@@ -94,6 +96,7 @@ salome.sg.updateObjBrowser(1)
 # -----------------------------------------------------------------------------
 
 print "-------------------------- mesh"
+smesh.SetCurrentStudy(salome.myStudy)
 
 # ---- init a Mesh with the geom shape
 shape_mesh = blob
index f1b02854d7676a819c6c0738351cd160f36a7ece..5411c8dfdf2e48f9464839b19631ae0c8b3a691e 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  File   : SMESH_withHole.py
 #  Author : Lucien PIGNOLONI
 #  Module : SMESH
@@ -94,31 +96,32 @@ Id_mechanic = geompy.addToStudy( mechanic, "mechanic" )
 # ---- explode on faces
 SubFaceL = geompy.SubShapeAllSorted(mechanic, geompy.ShapeType["FACE"])
 
-# ---- add a face sub shape in study to be meshed different
+# ---- add a face sub-shape in study to be meshed different
 sub_face1 = SubFaceL[0]
 name      = geompy.SubShapeName( sub_face1, mechanic )
 
 Id_SubFace1 = geompy.addToStudyInFather( mechanic, sub_face1, name )
 
-# ---- add a face sub shape in study to be meshed different
+# ---- add a face sub-shape in study to be meshed different
 sub_face2 = SubFaceL[4]
 name      = geompy.SubShapeName( sub_face2, mechanic )
 
 Id_SubFace2 = geompy.addToStudyInFather( mechanic, sub_face2, name )
 
-# ---- add a face sub shape in study to be meshed different
+# ---- add a face sub-shape in study to be meshed different
 sub_face3 = SubFaceL[5]
 name      = geompy.SubShapeName( sub_face3, mechanic )
 
 Id_SubFace3 = geompy.addToStudyInFather( mechanic, sub_face3, name )
 
-# ---- add a face sub shape in study to be meshed different
+# ---- add a face sub-shape in study to be meshed different
 sub_face4 = SubFaceL[10]
 name      = geompy.SubShapeName( sub_face4, mechanic )
 
 Id_SubFace4 = geompy.addToStudyInFather( mechanic, sub_face4, name )
 
 # ---------------------------- SMESH --------------------------------------
+smesh.SetCurrentStudy(salome.myStudy)
 
 # -- Init --
 shape_mesh = salome.IDToObject( Id_mechanic )
index 80780ca63c8fe64f781829757b0d37bb69280591..f754354a942b4f6bc9f83e352d4d983618f95295 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# -*- coding: utf-8 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  File   : SMESH_withHole.py
 #  Author : Lucien PIGNOLONI
 #  Module : SMESH
@@ -29,6 +31,7 @@ import salome
 import geompy
 import smesh
 
+salome.salome_init()
 # ---------------------------- GEOM --------------------------------------
 
 # ---- define contigous arcs and segment to define a closed wire
@@ -92,31 +95,32 @@ Id_mechanic = geompy.addToStudy( mechanic, "mechanic" )
 # ---- explode on faces
 SubFaceL = geompy.SubShapeAllSorted(mechanic, geompy.ShapeType["FACE"])
 
-# ---- add a face sub shape in study to be meshed different
+# ---- add a face sub-shape in study to be meshed different
 sub_face1 = SubFaceL[0]
 name      = geompy.SubShapeName( sub_face1, mechanic )
 
 Id_SubFace1 = geompy.addToStudyInFather( mechanic, sub_face1, name )
 
-# ---- add a face sub shape in study to be meshed different
+# ---- add a face sub-shape in study to be meshed different
 sub_face2 = SubFaceL[4]
 name      = geompy.SubShapeName( sub_face2, mechanic )
 
 Id_SubFace2 = geompy.addToStudyInFather( mechanic, sub_face2, name )
 
-# ---- add a face sub shape in study to be meshed different
+# ---- add a face sub-shape in study to be meshed different
 sub_face3 = SubFaceL[5]
 name      = geompy.SubShapeName( sub_face3, mechanic )
 
 Id_SubFace3 = geompy.addToStudyInFather( mechanic, sub_face3, name )
 
-# ---- add a face sub shape in study to be meshed different
+# ---- add a face sub-shape in study to be meshed different
 sub_face4 = SubFaceL[10]
 name      = geompy.SubShapeName( sub_face4, mechanic )
 
 Id_SubFace4 = geompy.addToStudyInFather( mechanic, sub_face4, name )
 
 # ---------------------------- SMESH --------------------------------------
+smesh.SetCurrentStudy(salome.myStudy)
 
 # -- Init --
 shape_mesh = salome.IDToObject( Id_mechanic )
@@ -189,9 +193,9 @@ print "Number of tetrahedrons: ", mesh.NbTetras()
 mesh.SplitQuadObject(submesh2, 1)
 
 #2 cutting of triangles of the group
-FacesTriToQuad = [2381, 2382, 2383, 2384, 2385, 2386, 2387, 2388, 2389, 2390, 2391, 2392, 2393, 2394, 2395, 2396, 2397, 2398, 2399, 2400, 2401, 2402, 2403, 2404, 2405, 2406, 2407, 2408, 2409, 2410, 2411, 2412, 2413, 2414, 2415, 2416, 2417, 2418, 2419, 2420, 2421, 2422]
+FacesTriToQuad = [ 2391, 2824, 2825, 2826, 2827, 2828, 2832, 2833, 2834, 2835, 2836, 2837, 2838, 2839, 2841, 2844, 2845, 2847, 2854, 2861, 2863, 2922, 2923, 2924, 2925, 2926, 2927, 2928, 2929, 2930, 2931, 2932, 2933, 2934, 2935, 2936, 2937, 2938, 2940, 2941, 2946, 2951, 2970, 2971, 2972, 2973, 2974, 2975, 2976, 2977, 2978, 2979, 2980, 2981, 2982, 2983, 2984, 2985 ]
 GroupTriToQuad = mesh.MakeGroupByIds("Group of faces (quad)", smesh.FACE, FacesTriToQuad)
-mesh.TriToQuadObject(GroupTriToQuad, None , 1.57)
+mesh.TriToQuadObject(GroupTriToQuad, smesh.FT_AspectRatio , 1.57)
 
 #3 extrusion of the group
 point = smesh.PointStruct(0, 0, 5)
index e296eaed15c7ceae9a1435364dcc76ae39dd1485..f5088378bf2fc05bb280564c1d3a6e2d65e63145 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # Quadrangulation of the geometry generated by the Python script
 # SMESH_mechanic.py
 # The new Netgen algorithm is used that discretizes baoundaries itself
@@ -103,6 +105,7 @@ print "number of Faces in mechanic : ",len(subFaceList)
 print "number of Edges in mechanic : ",len(subEdgeList)
 
 ### ---------------------------- SMESH --------------------------------------
+smesh.SetCurrentStudy(salome.myStudy)
 
 print "-------------------------- create Mesh, algorithm, hypothesis"
 
index ff2f421f73dddbf017a804941aab82eeca378b09..135d5d152e9cfe666163c7c06c79470a3d0abfdf 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  File   : SMESH_withHole.py
 #  Author : Lucien PIGNOLONI
 #  Module : SMESH
@@ -103,6 +105,7 @@ print "number of Faces in mechanic : ",len(subFaceList)
 print "number of Edges in mechanic : ",len(subEdgeList)
 
 ### ---------------------------- SMESH --------------------------------------
+smesh.SetCurrentStudy(salome.myStudy)
 
 shape_mesh = salome.IDToObject( Id_mechanic  )
 
index 8a0ec7cfcf4d554714a383296a1a2c285b2d5975..afd2a0a7c7cb2bd69d7ba81798e7aa1b09918302 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  File   : SMESH_reg.py
 #  Module : SMESH
 #
@@ -57,7 +59,7 @@ salome.sg.updateObjBrowser(1);
 # ---- launch SMESH
 smeshgui = salome.ImportComponentGUI("SMESH")
 smeshgui.Init(salome.myStudyId)
-
+smesh.SetCurrentStudy(salome.myStudy)
 
 # ---- Creating meshes
 
index 01286ea65f733eba8b26797cbff23986b3369166..e0021db8927445b28fe91ee89b559e6a803154fe 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 """
 
 """
index bc98e1c5c3a8453187f6434c93d1a33983b77fa5..7b2bbbcac4058763e5ca716ee49a8cb30e82a329 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 #  File   : SMESH_test.py
 #  Module : SMESH
@@ -55,6 +57,7 @@ ide = geompy.addToStudyInFather(face, edge, name)
 
 # ---- SMESH
 
+smesh.SetCurrentStudy(salome.myStudy)
 box = salome.IDToObject(idb)
 mesh = smesh.Mesh(box, "Meshbox")
 
@@ -123,11 +126,17 @@ for a in log:
     elif comType == 2:
         for i in range(a.number):
             ind = a.indexes[ii]
+           print ind
             ii = ii+1
+           print ii
             i1 = a.indexes[ii]
             ii = ii+1
             i2 = a.indexes[ii]
+           print i2
             ii = ii+1
+           print "ii", ii
             i3 = a.indexes[ii]
+           print i3
+            #ii = ii+1
             ii = ii+1
             print "AddTriangle %i - %i %i %i" % (ind, i1, i2, i3)
index 421acc1ed2308502c4c4b29a93b8c81523fb7937..10fd4ab4b05a6fc09c9e8e79875948af6680fb60 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  File   : SMESH_test0.py
 #  Module : SMESH
 #
index 25ce49704e3d5f6da65db3b06abec6a0d01b6ac4..a739dc9b91801fc3f246856f4970e8e44474cc2f 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  File   : SMESH_test1.py
 #  Module : SMESH
 #
@@ -26,7 +28,6 @@ import salome
 import geompy
 import smesh
 
-
 # ---- define a box
 
 box = geompy.MakeBox(0., 0., 0., 100., 200., 300.)
@@ -59,6 +60,8 @@ idedge = geompy.addToStudyInFather(face, edge, name)
 
 # ---- SMESH
 
+smesh.SetCurrentStudy(salome.myStudy)
+
 # ---- Init a Mesh with the box
 
 mesh = smesh.Mesh(box, "Meshbox")
index e529d2c13c4573c0b3fc6455bb227aef8aca6e1d..9c1578404c6e3ea8766b3bab40805d34dd229b33 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  File   : SMESH_test1.py
 #  Module : SMESH
 #
@@ -59,6 +61,8 @@ idedge = geompy.addToStudyInFather(face, edge, name)
 
 # ---- SMESH
 
+smesh.SetCurrentStudy(salome.myStudy)
+
 # ---- Init a Mesh with the box
 
 mesh = smesh.Mesh(box, "Meshbox")
index fe38b2da4fc1a06c1cae15cf1286f018f9ed4e7f..89e4e8f11e3c6863f126ba377fab57967eb0511d 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  File   : SMESH_test2.py
 #  Module : SMESH
 #
index 59c853a46bc02f3edaaf241dce9a2f83f81cec34..04455050b183d64020eff6d54eea055db6cded35 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  File   : SMESH_test3.py
 #  Module : SMESH
 #import salome
index dd86094d51c11552ffe66684c389e1b07428fb88..230b1f3fb7724ec0fd60dfb0ab1925418954c105 100755 (executable)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 import salome
 import geompy
 import smesh
@@ -39,6 +41,7 @@ face = salome.IDToObject(idface)
 
 # ---- SMESH
 
+smesh.SetCurrentStudy(salome.myStudy)
 mesh = smesh.Mesh(box, "Meshbox")
 
 # Set 1D algorithm/hypotheses to mesh
index 03a380ca653dc88e68e70c05b3eeb895815243e5..749c9d9d91e031bf7588781dcc7b3c54892794f1 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  File   : SMESH_test5.py
 #  Module : SMESH
 #
@@ -29,6 +31,8 @@ import CORBA
 import os
 import os.path
 
+smesh.SetCurrentStudy(salome.myStudy)
+
 def SetSObjName(theSObj,theName) :
     ok, anAttr = theSObj.FindAttribute("AttributeName")
     if ok:
diff --git a/src/SMESH_SWIG/StdMeshersDC.py b/src/SMESH_SWIG/StdMeshersDC.py
new file mode 100644 (file)
index 0000000..af20cb4
--- /dev/null
@@ -0,0 +1,1126 @@
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# 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.com
+#
+
+from smesh import Mesh_Algorithm, AssureGeomPublished, IsEqual, ParseParameters
+from smesh import GetName, TreatHypoStatus
+from smeshDC import Mesh
+
+import StdMeshers
+
+# Types of algorithms
+REGULAR     = "Regular_1D"
+PYTHON      = "Python_1D"
+COMPOSITE   = "CompositeSegment_1D"
+MEFISTO     = "MEFISTO_2D"
+Hexa        = "Hexa_3D"
+QUADRANGLE  = "Quadrangle_2D"
+RADIAL_QUAD = "RadialQuadrangle_1D2D"
+
+
+# import items of enum QuadType
+for e in StdMeshers.QuadType._items: exec('%s = StdMeshers.%s'%(e,e))
+
+
+# Public class: Mesh_Segment
+# --------------------------
+
+## Class to define a REGULAR 1D algorithm for discretization. It is created by
+#  calling Mesh.Segment(geom=0)
+#
+#  @ingroup l3_algos_basic
+class StdMeshersDC_Segment(Mesh_Algorithm):
+
+    ## Name of method of class Mesh creating an instance of this class
+    meshMethod = "Segment"
+    ## Name of algorithm type
+    algoType   = REGULAR
+    isDefault  = True
+
+    ## Private constructor.
+    def __init__(self, mesh, geom=0):
+        Mesh_Algorithm.__init__(self)
+        self.Create(mesh, geom, self.algoType)
+
+    ## Defines "LocalLength" hypothesis to cut an edge in several segments with the same length
+    #  @param l for the length of segments that cut an edge
+    #  @param UseExisting if ==true - searches for an  existing hypothesis created with
+    #                    the same parameters, else (default) - creates a new one
+    #  @param p precision, used for calculation of the number of segments.
+    #           The precision should be a positive, meaningful value within the range [0,1].
+    #           In general, the number of segments is calculated with the formula:
+    #           nb = ceil((edge_length / l) - p)
+    #           Function ceil rounds its argument to the higher integer.
+    #           So, p=0 means rounding of (edge_length / l) to the higher integer,
+    #               p=0.5 means rounding of (edge_length / l) to the nearest integer,
+    #               p=1 means rounding of (edge_length / l) to the lower integer.
+    #           Default value is 1e-07.
+    #  @return an instance of StdMeshers_LocalLength hypothesis
+    #  @ingroup l3_hypos_1dhyps
+    def LocalLength(self, l, UseExisting=0, p=1e-07):
+        comFun=lambda hyp, args: IsEqual(hyp.GetLength(), args[0]) and IsEqual(hyp.GetPrecision(), args[1])
+        hyp = self.Hypothesis("LocalLength", [l,p], UseExisting=UseExisting, CompareMethod=comFun)
+        hyp.SetLength(l)
+        hyp.SetPrecision(p)
+        return hyp
+
+    ## Defines "MaxSize" hypothesis to cut an edge into segments not longer than given value
+    #  @param length is optional maximal allowed length of segment, if it is omitted
+    #                the preestimated length is used that depends on geometry size
+    #  @param UseExisting if ==true - searches for an existing hypothesis created with
+    #                     the same parameters, else (default) - creates a new one
+    #  @return an instance of StdMeshers_MaxLength hypothesis
+    #  @ingroup l3_hypos_1dhyps
+    def MaxSize(self, length=0.0, UseExisting=0):
+        hyp = self.Hypothesis("MaxLength", [length], UseExisting=UseExisting)
+        if length > 0.0:
+            # set given length
+            hyp.SetLength(length)
+        if not UseExisting:
+            # set preestimated length
+            gen = self.mesh.smeshpyD
+            initHyp = gen.GetHypothesisParameterValues("MaxLength", "libStdMeshersEngine.so",
+                                                       self.mesh.GetMesh(), self.mesh.GetShape(),
+                                                       False) # <- byMesh
+            preHyp = initHyp._narrow(StdMeshers.StdMeshers_MaxLength)
+            if preHyp:
+                hyp.SetPreestimatedLength( preHyp.GetPreestimatedLength() )
+                pass
+            pass
+        hyp.SetUsePreestimatedLength( length == 0.0 )
+        return hyp
+
+    ## Defines "NumberOfSegments" hypothesis to cut an edge in a fixed number of segments
+    #  @param n for the number of segments that cut an edge
+    #  @param s for the scale factor (optional)
+    #  @param reversedEdges is a list of edges to mesh using reversed orientation.
+    #                       A list item can also be a tuple (edge, 1st_vertex_of_edge)
+    #  @param UseExisting if ==true - searches for an existing hypothesis created with
+    #                     the same parameters, else (default) - create a new one
+    #  @return an instance of StdMeshers_NumberOfSegments hypothesis
+    #  @ingroup l3_hypos_1dhyps
+    def NumberOfSegments(self, n, s=[], reversedEdges=[], UseExisting=0):
+        if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges
+            reversedEdges, UseExisting = [], reversedEdges
+        entry = self.MainShapeEntry()
+        reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges)
+        if s == []:
+            hyp = self.Hypothesis("NumberOfSegments", [n, reversedEdgeInd, entry],
+                                  UseExisting=UseExisting,
+                                  CompareMethod=self._compareNumberOfSegments)
+        else:
+            hyp = self.Hypothesis("NumberOfSegments", [n,s, reversedEdgeInd, entry],
+                                  UseExisting=UseExisting,
+                                  CompareMethod=self._compareNumberOfSegments)
+            hyp.SetDistrType( 1 )
+            hyp.SetScaleFactor(s)
+        hyp.SetNumberOfSegments(n)
+        hyp.SetReversedEdges( reversedEdgeInd )
+        hyp.SetObjectEntry( entry )
+        return hyp
+
+    ## Private method
+    ## Checks if the given "NumberOfSegments" hypothesis has the same parameters as the given arguments
+    def _compareNumberOfSegments(self, hyp, args):
+        if hyp.GetNumberOfSegments() == args[0]:
+            if len(args) == 3:
+                if hyp.GetReversedEdges() == args[1]:
+                    if not args[1] or hyp.GetObjectEntry() == args[2]:
+                        return True
+            else:
+                if hyp.GetReversedEdges() == args[2]:
+                    if not args[2] or hyp.GetObjectEntry() == args[3]:
+                        if hyp.GetDistrType() == 1:
+                            if IsEqual(hyp.GetScaleFactor(), args[1]):
+                                return True
+        return False
+
+    ## Defines "Arithmetic1D" hypothesis to cut an edge in several segments with increasing arithmetic length
+    #  @param start defines the length of the first segment
+    #  @param end   defines the length of the last  segment
+    #  @param reversedEdges is a list of edges to mesh using reversed orientation.
+    #                       A list item can also be a tuple (edge, 1st_vertex_of_edge)
+    #  @param UseExisting if ==true - searches for an existing hypothesis created with
+    #                     the same parameters, else (default) - creates a new one
+    #  @return an instance of StdMeshers_Arithmetic1D hypothesis
+    #  @ingroup l3_hypos_1dhyps
+    def Arithmetic1D(self, start, end, reversedEdges=[], UseExisting=0):
+        if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges
+            reversedEdges, UseExisting = [], reversedEdges
+        reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges)
+        entry = self.MainShapeEntry()
+        compFun = lambda hyp, args: ( IsEqual(hyp.GetLength(1), args[0]) and \
+                                      IsEqual(hyp.GetLength(0), args[1]) and \
+                                      hyp.GetReversedEdges() == args[2]  and \
+                                      (not args[2] or hyp.GetObjectEntry() == args[3]))
+        hyp = self.Hypothesis("Arithmetic1D", [start, end, reversedEdgeInd, entry],
+                              UseExisting=UseExisting, CompareMethod=compFun)
+        hyp.SetStartLength(start)
+        hyp.SetEndLength(end)
+        hyp.SetReversedEdges( reversedEdgeInd )
+        hyp.SetObjectEntry( entry )
+        return hyp
+
+    ## Defines "FixedPoints1D" hypothesis to cut an edge using parameter
+    # on curve from 0 to 1 (additionally it is neecessary to check
+    # orientation of edges and create list of reversed edges if it is
+    # needed) and sets numbers of segments between given points (default
+    # values are equals 1
+    #  @param points defines the list of parameters on curve
+    #  @param nbSegs defines the list of numbers of segments
+    #  @param reversedEdges is a list of edges to mesh using reversed orientation.
+    #                       A list item can also be a tuple (edge, 1st_vertex_of_edge)
+    #  @param UseExisting if ==true - searches for an existing hypothesis created with
+    #                     the same parameters, else (default) - creates a new one
+    #  @return an instance of StdMeshers_Arithmetic1D hypothesis
+    #  @ingroup l3_hypos_1dhyps
+    def FixedPoints1D(self, points, nbSegs=[1], reversedEdges=[], UseExisting=0):
+        if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges
+            reversedEdges, UseExisting = [], reversedEdges
+        reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges)
+        entry = self.MainShapeEntry()
+        compFun = lambda hyp, args: ( hyp.GetPoints() == args[0] and \
+                                      hyp.GetNbSegments() == args[1] and \
+                                      hyp.GetReversedEdges() == args[2] and \
+                                      (not args[2] or hyp.GetObjectEntry() == args[3]))
+        hyp = self.Hypothesis("FixedPoints1D", [points, nbSegs, reversedEdgeInd, entry],
+                              UseExisting=UseExisting, CompareMethod=compFun)
+        hyp.SetPoints(points)
+        hyp.SetNbSegments(nbSegs)
+        hyp.SetReversedEdges(reversedEdgeInd)
+        hyp.SetObjectEntry(entry)
+        return hyp
+
+    ## Defines "StartEndLength" hypothesis to cut an edge in several segments with increasing geometric length
+    #  @param start defines the length of the first segment
+    #  @param end   defines the length of the last  segment
+    #  @param reversedEdges is a list of edges to mesh using reversed orientation.
+    #                       A list item can also be a tuple (edge, 1st_vertex_of_edge)
+    #  @param UseExisting if ==true - searches for an existing hypothesis created with
+    #                     the same parameters, else (default) - creates a new one
+    #  @return an instance of StdMeshers_StartEndLength hypothesis
+    #  @ingroup l3_hypos_1dhyps
+    def StartEndLength(self, start, end, reversedEdges=[], UseExisting=0):
+        if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges
+            reversedEdges, UseExisting = [], reversedEdges
+        reversedEdgeInd = self.ReversedEdgeIndices(reversedEdges)
+        entry = self.MainShapeEntry()
+        compFun = lambda hyp, args: ( IsEqual(hyp.GetLength(1), args[0]) and \
+                                      IsEqual(hyp.GetLength(0), args[1]) and \
+                                      hyp.GetReversedEdges() == args[2]  and \
+                                      (not args[2] or hyp.GetObjectEntry() == args[3]))
+        hyp = self.Hypothesis("StartEndLength", [start, end, reversedEdgeInd, entry],
+                              UseExisting=UseExisting, CompareMethod=compFun)
+        hyp.SetStartLength(start)
+        hyp.SetEndLength(end)
+        hyp.SetReversedEdges( reversedEdgeInd )
+        hyp.SetObjectEntry( entry )
+        return hyp
+
+    ## Defines "Deflection1D" hypothesis
+    #  @param d for the deflection
+    #  @param UseExisting if ==true - searches for an existing hypothesis created with
+    #                     the same parameters, else (default) - create a new one
+    #  @ingroup l3_hypos_1dhyps
+    def Deflection1D(self, d, UseExisting=0):
+        compFun = lambda hyp, args: IsEqual(hyp.GetDeflection(), args[0])
+        hyp = self.Hypothesis("Deflection1D", [d], UseExisting=UseExisting, CompareMethod=compFun)
+        hyp.SetDeflection(d)
+        return hyp
+
+    ## Defines "Propagation" hypothesis that propagates all other hypotheses on all other edges that are at
+    #  the opposite side in case of quadrangular faces
+    #  @ingroup l3_hypos_additi
+    def Propagation(self):
+        return self.Hypothesis("Propagation", UseExisting=1, CompareMethod=self.CompareEqualHyp)
+
+    ## Defines "AutomaticLength" hypothesis
+    #  @param fineness for the fineness [0-1]
+    #  @param UseExisting if ==true - searches for an existing hypothesis created with the
+    #                     same parameters, else (default) - create a new one
+    #  @ingroup l3_hypos_1dhyps
+    def AutomaticLength(self, fineness=0, UseExisting=0):
+        compFun = lambda hyp, args: IsEqual(hyp.GetFineness(), args[0])
+        hyp = self.Hypothesis("AutomaticLength",[fineness],UseExisting=UseExisting,
+                              CompareMethod=compFun)
+        hyp.SetFineness( fineness )
+        return hyp
+
+    ## Defines "SegmentLengthAroundVertex" hypothesis
+    #  @param length for the segment length
+    #  @param vertex for the length localization: the vertex index [0,1] | vertex object.
+    #         Any other integer value means that the hypothesis will be set on the
+    #         whole 1D shape, where Mesh_Segment algorithm is assigned.
+    #  @param UseExisting if ==true - searches for an  existing hypothesis created with
+    #                   the same parameters, else (default) - creates a new one
+    #  @ingroup l3_algos_segmarv
+    def LengthNearVertex(self, length, vertex=0, UseExisting=0):
+        import types
+        store_geom = self.geom
+        if type(vertex) is types.IntType:
+            if vertex == 0 or vertex == 1:
+                import geompyDC
+                vertex = self.mesh.geompyD.ExtractShapes(self.geom, geompyDC.ShapeType["VERTEX"],True)[vertex]
+                self.geom = vertex
+                pass
+            pass
+        else:
+            self.geom = vertex
+            pass
+        ### 0D algorithm
+        if self.geom is None:
+            raise RuntimeError, "Attemp to create SegmentAroundVertex_0D algoritm on None shape"
+        AssureGeomPublished( self.mesh, self.geom )
+        name = GetName(self.geom)
+
+        algo = self.FindAlgorithm("SegmentAroundVertex_0D", self.mesh.smeshpyD)
+        if algo is None:
+            algo = self.mesh.smeshpyD.CreateHypothesis("SegmentAroundVertex_0D", "libStdMeshersEngine.so")
+            pass
+        status = self.mesh.mesh.AddHypothesis(self.geom, algo)
+        TreatHypoStatus(status, "SegmentAroundVertex_0D", name, True)
+        ###
+        comFun = lambda hyp, args: IsEqual(hyp.GetLength(), args[0])
+        hyp = self.Hypothesis("SegmentLengthAroundVertex", [length], UseExisting=UseExisting,
+                              CompareMethod=comFun)
+        self.geom = store_geom
+        hyp.SetLength( length )
+        return hyp
+
+    ## Defines "QuadraticMesh" hypothesis, forcing construction of quadratic edges.
+    #  If the 2D mesher sees that all boundary edges are quadratic,
+    #  it generates quadratic faces, else it generates linear faces using
+    #  medium nodes as if they are vertices.
+    #  The 3D mesher generates quadratic volumes only if all boundary faces
+    #  are quadratic, else it fails.
+    #
+    #  @ingroup l3_hypos_additi
+    def QuadraticMesh(self):
+        hyp = self.Hypothesis("QuadraticMesh", UseExisting=1, CompareMethod=self.CompareEqualHyp)
+        return hyp
+
+# Public class: Mesh_CompositeSegment
+# --------------------------
+
+## A regular 1D algorithm for discretization of a set of adjacent edges as one.
+#  It is created by calling Mesh.Segment(COMPOSITE,geom=0)
+#
+#  @ingroup l3_algos_basic
+class StdMeshersDC_CompositeSegment(StdMeshersDC_Segment):
+
+    ## Name of method of class Mesh creating an instance of this class
+    meshMethod = "Segment"
+    ## Name of algorithm type
+    algoType   = COMPOSITE
+    isDefault  = False
+
+    ## Private constructor.
+    def __init__(self, mesh, geom=0):
+        self.Create(mesh, geom, self.algoType)
+
+
+# Public class: Mesh_Segment_Python
+# ---------------------------------
+
+## Defines a segment 1D algorithm for discretization with python function
+#  It is created by calling Mesh.Segment(PYTHON,geom=0)
+#
+#  @ingroup l3_algos_basic
+class StdMeshersDC_Segment_Python(Mesh_Algorithm):
+
+    ## Name of method of class Mesh creating an instance of this class
+    meshMethod = "Segment"
+    ## Name of algorithm type
+    algoType   = PYTHON
+
+    ## Private constructor.
+    def __init__(self, mesh, geom=0):
+        import Python1dPlugin
+        self.Create(mesh, geom, self.algoType, "libPython1dEngine.so")
+
+    ## Defines "PythonSplit1D" hypothesis
+    #  @param n for the number of segments that cut an edge
+    #  @param func for the python function that calculates the length of all segments
+    #  @param UseExisting if ==true - searches for the existing hypothesis created with
+    #                     the same parameters, else (default) - creates a new one
+    #  @ingroup l3_hypos_1dhyps
+    def PythonSplit1D(self, n, func, UseExisting=0):
+        compFun = lambda hyp, args: False
+        hyp = self.Hypothesis("PythonSplit1D", [n], "libPython1dEngine.so",
+                              UseExisting=UseExisting, CompareMethod=compFun)
+        hyp.SetNumberOfSegments(n)
+        hyp.SetPythonLog10RatioFunction(func)
+        return hyp
+
+# Public class: Mesh_Triangle_MEFISTO
+# -----------------------------------
+
+## Triangle MEFISTO 2D algorithm
+#  It is created by calling Mesh.Triangle(MEFISTO,geom=0)
+#
+#  @ingroup l3_algos_basic
+class StdMeshersDC_Triangle_MEFISTO(Mesh_Algorithm):
+
+    ## Name of method of class Mesh creating an instance of this class
+    meshMethod = "Triangle"
+    ## Name of algorithm type
+    algoType   = MEFISTO
+    isDefault  = True
+
+    ## Private constructor.
+    def __init__(self, mesh, geom=0):
+        Mesh_Algorithm.__init__(self)
+        self.Create(mesh, geom, self.algoType)
+
+    ## Defines "MaxElementArea" hypothesis basing on the definition of the maximum area of each triangle
+    #  @param area for the maximum area of each triangle
+    #  @param UseExisting if ==true - searches for an  existing hypothesis created with the
+    #                     same parameters, else (default) - creates a new one
+    #
+    #  @ingroup l3_hypos_2dhyps
+    def MaxElementArea(self, area, UseExisting=0):
+        comparator = lambda hyp, args: IsEqual(hyp.GetMaxElementArea(), args[0])
+        hyp = self.Hypothesis("MaxElementArea", [area], UseExisting=UseExisting,
+                              CompareMethod=comparator)
+        hyp.SetMaxElementArea(area)
+        return hyp
+
+    ## Defines "LengthFromEdges" hypothesis to build triangles
+    #  based on the length of the edges taken from the wire
+    #
+    #  @ingroup l3_hypos_2dhyps
+    def LengthFromEdges(self):
+        hyp = self.Hypothesis("LengthFromEdges", UseExisting=1, CompareMethod=self.CompareEqualHyp)
+        return hyp
+
+# Public class: Mesh_Quadrangle
+# -----------------------------
+
+## Defines a quadrangle 2D algorithm
+#  It is created by calling Mesh.Quadrangle(geom=0)
+#
+#  @ingroup l3_algos_basic
+class StdMeshersDC_Quadrangle(Mesh_Algorithm):
+
+    ## Name of method of class Mesh creating an instance of this class
+    meshMethod = "Quadrangle"
+    ## Name of algorithm type
+    algoType   = QUADRANGLE
+    isDefault  = True
+
+    params=0
+
+    ## Private constructor.
+    def __init__(self, mesh, geom=0):
+        Mesh_Algorithm.__init__(self)
+        self.Create(mesh, geom, self.algoType)
+        return
+
+    ## Defines "QuadrangleParameters" hypothesis
+    #  @param quadType defines the algorithm of transition between differently descretized
+    #                  sides of a geometrical face:
+    #  - QUAD_STANDARD - both triangles and quadrangles are possible in the transition
+    #                    area along the finer meshed sides.
+    #  - QUAD_TRIANGLE_PREF - only triangles are built in the transition area along the
+    #                    finer meshed sides.
+    #  - QUAD_QUADRANGLE_PREF - only quadrangles are built in the transition area along
+    #                    the finer meshed sides, iff the total quantity of segments on
+    #                    all four sides of the face is even (divisible by 2).
+    #  - QUAD_QUADRANGLE_PREF_REVERSED - same as QUAD_QUADRANGLE_PREF but the transition
+    #                    area is located along the coarser meshed sides.
+    #  - QUAD_REDUCED - only quadrangles are built and the transition between the sides
+    #                    is made gradually, layer by layer. This type has a limitation on
+    #                    the number of segments: one pair of opposite sides must have the
+    #                    same number of segments, the other pair must have an even difference
+    #                    between the numbers of segments on the sides.
+    #  @param triangleVertex: vertex of a trilateral geometrical face, around which triangles
+    #                  will be created while other elements will be quadrangles.
+    #                  Vertex can be either a GEOM_Object or a vertex ID within the
+    #                  shape to mesh
+    #  @param UseExisting: if ==true - searches for the existing hypothesis created with
+    #                  the same parameters, else (default) - creates a new one
+    #  @ingroup l3_hypos_quad
+    def QuadrangleParameters(self, quadType=StdMeshers.QUAD_STANDARD, triangleVertex=0, UseExisting=0):
+        import GEOM
+        vertexID = triangleVertex
+        if isinstance( triangleVertex, GEOM._objref_GEOM_Object ):
+            vertexID = self.mesh.geompyD.GetSubShapeID( self.mesh.geom, triangleVertex )
+        if not self.params:
+            compFun = lambda hyp,args: \
+                      hyp.GetQuadType() == args[0] and \
+                      ( hyp.GetTriaVertex()==args[1] or ( hyp.GetTriaVertex()<1 and args[1]<1))
+            self.params = self.Hypothesis("QuadrangleParams", [quadType,vertexID],
+                                          UseExisting = UseExisting, CompareMethod=compFun)
+            pass
+        if self.params.GetQuadType() != quadType:
+            self.params.SetQuadType(quadType)
+        if vertexID > 0:
+            self.params.SetTriaVertex( vertexID )
+        return self.params
+
+    ## Defines "QuadrangleParams" hypothesis with a type of quadrangulation that only
+    #   quadrangles are built in the transition area along the finer meshed sides,
+    #   iff the total quantity of segments on all four sides of the face is even.
+    #  @param reversed if True, transition area is located along the coarser meshed sides.
+    #  @param UseExisting: if ==true - searches for the existing hypothesis created with
+    #                  the same parameters, else (default) - creates a new one
+    #  @ingroup l3_hypos_quad
+    def QuadranglePreference(self, reversed=False, UseExisting=0):
+        if reversed:
+            return self.QuadrangleParameters(QUAD_QUADRANGLE_PREF_REVERSED,UseExisting=UseExisting)
+        return self.QuadrangleParameters(QUAD_QUADRANGLE_PREF,UseExisting=UseExisting)
+
+    ## Defines "QuadrangleParams" hypothesis with a type of quadrangulation that only
+    #   triangles are built in the transition area along the finer meshed sides.
+    #  @param UseExisting: if ==true - searches for the existing hypothesis created with
+    #                  the same parameters, else (default) - creates a new one
+    #  @ingroup l3_hypos_quad
+    def TrianglePreference(self, UseExisting=0):
+        return self.QuadrangleParameters(QUAD_TRIANGLE_PREF,UseExisting=UseExisting)
+
+    ## Defines "QuadrangleParams" hypothesis with a type of quadrangulation that only
+    #   quadrangles are built and the transition between the sides is made gradually,
+    #   layer by layer. This type has a limitation on the number of segments: one pair
+    #   of opposite sides must have the same number of segments, the other pair must
+    #   have an even difference between the numbers of segments on the sides.
+    #  @param UseExisting: if ==true - searches for the existing hypothesis created with
+    #                  the same parameters, else (default) - creates a new one
+    #  @ingroup l3_hypos_quad
+    def Reduced(self, UseExisting=0):
+        return self.QuadrangleParameters(QUAD_REDUCED,UseExisting=UseExisting)
+
+    ## Defines "QuadrangleParams" hypothesis with QUAD_STANDARD type of quadrangulation
+    #  @param vertex: vertex of a trilateral geometrical face, around which triangles
+    #                 will be created while other elements will be quadrangles.
+    #                 Vertex can be either a GEOM_Object or a vertex ID within the
+    #                 shape to mesh
+    #  @param UseExisting: if ==true - searches for the existing hypothesis created with
+    #                   the same parameters, else (default) - creates a new one
+    #  @ingroup l3_hypos_quad
+    def TriangleVertex(self, vertex, UseExisting=0):
+        return self.QuadrangleParameters(QUAD_STANDARD,vertex,UseExisting)
+
+
+# Public class: Mesh_Hexahedron
+# ------------------------------
+
+## Defines a hexahedron 3D algorithm
+#  It is created by calling Mesh.Hexahedron(geom=0)
+#
+#  @ingroup l3_algos_basic
+class StdMeshersDC_Hexahedron(Mesh_Algorithm):
+
+    ## Name of method of class Mesh creating an instance of this class
+    meshMethod = "Hexahedron"
+    ## Name of algorithm type
+    algoType   = Hexa
+    isDefault  = True
+
+    ## Private constructor.
+    def __init__(self, mesh, geom=0):
+        Mesh_Algorithm.__init__(self)
+        self.Create(mesh, geom, Hexa)
+        pass
+
+# Public class: Mesh_Projection1D
+# -------------------------------
+
+## Defines a projection 1D algorithm
+#  It is created by calling Mesh.Projection1D(geom=0)
+#  @ingroup l3_algos_proj
+#
+class StdMeshersDC_Projection1D(Mesh_Algorithm):
+
+    ## Name of method of class Mesh creating an instance of this class
+    meshMethod = "Projection1D"
+    ## Name of algorithm type
+    algoType   = "Projection_1D"
+    isDefault  = True
+
+    ## Private constructor.
+    def __init__(self, mesh, geom=0):
+        Mesh_Algorithm.__init__(self)
+        self.Create(mesh, geom, self.algoType)
+
+    ## Defines "Source Edge" hypothesis, specifying a meshed edge, from where
+    #  a mesh pattern is taken, and, optionally, the association of vertices
+    #  between the source edge and a target edge (to which a hypothesis is assigned)
+    #  @param edge from which nodes distribution is taken
+    #  @param mesh from which nodes distribution is taken (optional)
+    #  @param srcV a vertex of \a edge to associate with \a tgtV (optional)
+    #  @param tgtV a vertex of \a the edge to which the algorithm is assigned,
+    #  to associate with \a srcV (optional)
+    #  @param UseExisting if ==true - searches for the existing hypothesis created with
+    #                     the same parameters, else (default) - creates a new one
+    def SourceEdge(self, edge, mesh=None, srcV=None, tgtV=None, UseExisting=0):
+        AssureGeomPublished( self.mesh, edge )
+        AssureGeomPublished( self.mesh, srcV )
+        AssureGeomPublished( self.mesh, tgtV )
+        hyp = self.Hypothesis("ProjectionSource1D", [edge,mesh,srcV,tgtV],
+                              UseExisting=0)
+        # it does not seem to be useful to reuse the existing "SourceEdge" hypothesis
+                              #UseExisting=UseExisting, CompareMethod=self.CompareSourceEdge)
+        hyp.SetSourceEdge( edge )
+        if not mesh is None and isinstance(mesh, Mesh):
+            mesh = mesh.GetMesh()
+        hyp.SetSourceMesh( mesh )
+        hyp.SetVertexAssociation( srcV, tgtV )
+        return hyp
+
+
+# Public class: Mesh_Projection2D
+# ------------------------------
+
+## Defines a projection 2D algorithm
+#  It is created by calling Mesh.Projection2D(geom=0)
+#  @ingroup l3_algos_proj
+#
+class StdMeshersDC_Projection2D(Mesh_Algorithm):
+
+    ## Name of method of class Mesh creating an instance of this class
+    meshMethod = "Projection2D"
+    ## Name of algorithm type
+    algoType   = "Projection_2D"
+    isDefault  = True
+
+    ## Private constructor.
+    def __init__(self, mesh, geom=0):
+        Mesh_Algorithm.__init__(self)
+        self.Create(mesh, geom, self.algoType)
+
+    ## Defines "Source Face" hypothesis, specifying a meshed face, from where
+    #  a mesh pattern is taken, and, optionally, the association of vertices
+    #  between the source face and the target face (to which a hypothesis is assigned)
+    #  @param face from which the mesh pattern is taken
+    #  @param mesh from which the mesh pattern is taken (optional)
+    #  @param srcV1 a vertex of \a face to associate with \a tgtV1 (optional)
+    #  @param tgtV1 a vertex of \a the face to which the algorithm is assigned,
+    #               to associate with \a srcV1 (optional)
+    #  @param srcV2 a vertex of \a face to associate with \a tgtV1 (optional)
+    #  @param tgtV2 a vertex of \a the face to which the algorithm is assigned,
+    #               to associate with \a srcV2 (optional)
+    #  @param UseExisting if ==true - forces the search for the existing hypothesis created with
+    #                     the same parameters, else (default) - forces the creation a new one
+    #
+    #  Note: all association vertices must belong to one edge of a face
+    def SourceFace(self, face, mesh=None, srcV1=None, tgtV1=None,
+                   srcV2=None, tgtV2=None, UseExisting=0):
+        from smeshDC import Mesh
+        if isinstance(mesh, Mesh):
+            mesh = mesh.GetMesh()
+        for geom in [ face, srcV1, tgtV1, srcV2, tgtV2 ]:
+            AssureGeomPublished( self.mesh, geom )
+        hyp = self.Hypothesis("ProjectionSource2D", [face,mesh,srcV1,tgtV1,srcV2,tgtV2],
+                              UseExisting=0)
+        # it does not seem to be useful to reuse the existing "SourceFace" hypothesis
+                              #UseExisting=UseExisting, CompareMethod=self.CompareSourceFace)
+        hyp.SetSourceFace( face )
+        hyp.SetSourceMesh( mesh )
+        hyp.SetVertexAssociation( srcV1, srcV2, tgtV1, tgtV2 )
+        return hyp
+
+# Public class: Mesh_Projection1D2D
+# ---------------------------------
+
+## Defines a projection 1D-2D algorithm
+#  It is created by calling Mesh.Projection1D2D(geom=0)
+#
+#  @ingroup l3_algos_proj
+
+class StdMeshersDC_Projection1D2D(StdMeshersDC_Projection2D):
+
+    ## Name of method of class Mesh creating an instance of this class
+    meshMethod = "Projection1D2D"
+    ## Name of algorithm type
+    algoType   = "Projection_1D2D"
+
+    ## Private constructor.
+    def __init__(self, mesh, geom=0):
+        StdMeshersDC_Projection2D.__init__(self, mesh, geom)
+
+# Public class: Mesh_Projection3D
+# ------------------------------
+
+## Defines a projection 3D algorithm
+#  It is created by calling Mesh.Projection3D(COMPOSITE)
+#
+#  @ingroup l3_algos_proj
+#
+class StdMeshersDC_Projection3D(Mesh_Algorithm):
+
+    ## Name of method of class Mesh creating an instance of this class
+    meshMethod = "Projection3D"
+    ## Name of algorithm type
+    algoType   = "Projection_3D"
+
+    ## Private constructor.
+    def __init__(self, mesh, geom=0):
+        Mesh_Algorithm.__init__(self)
+        self.Create(mesh, geom, self.algoType)
+
+    ## Defines the "Source Shape 3D" hypothesis, specifying a meshed solid, from where
+    #  the mesh pattern is taken, and, optionally, the  association of vertices
+    #  between the source and the target solid  (to which a hipothesis is assigned)
+    #  @param solid from where the mesh pattern is taken
+    #  @param mesh from where the mesh pattern is taken (optional)
+    #  @param srcV1 a vertex of \a solid to associate with \a tgtV1 (optional)
+    #  @param tgtV1 a vertex of \a the solid where the algorithm is assigned,
+    #  to associate with \a srcV1 (optional)
+    #  @param srcV2 a vertex of \a solid to associate with \a tgtV1 (optional)
+    #  @param tgtV2 a vertex of \a the solid to which the algorithm is assigned,
+    #  to associate with \a srcV2 (optional)
+    #  @param UseExisting - if ==true - searches for the existing hypothesis created with
+    #                     the same parameters, else (default) - creates a new one
+    #
+    #  Note: association vertices must belong to one edge of a solid
+    def SourceShape3D(self, solid, mesh=0, srcV1=0, tgtV1=0,
+                      srcV2=0, tgtV2=0, UseExisting=0):
+        for geom in [ solid, srcV1, tgtV1, srcV2, tgtV2 ]:
+            AssureGeomPublished( self.mesh, geom )
+        hyp = self.Hypothesis("ProjectionSource3D",
+                              [solid,mesh,srcV1,tgtV1,srcV2,tgtV2],
+                              UseExisting=0)
+        # seems to be not really useful to reuse existing "SourceShape3D" hypothesis
+                              #UseExisting=UseExisting, CompareMethod=self.CompareSourceShape3D)
+        hyp.SetSource3DShape( solid )
+        if isinstance(mesh, Mesh):
+            mesh = mesh.GetMesh()
+        if mesh:
+            hyp.SetSourceMesh( mesh )
+        if srcV1 and srcV2 and tgtV1 and tgtV2:
+            hyp.SetVertexAssociation( srcV1, srcV2, tgtV1, tgtV2 )
+        #elif srcV1 or srcV2 or tgtV1 or tgtV2:
+        return hyp
+
+# Public class: Mesh_Prism
+# ------------------------
+
+## Defines a Prism 3D algorithm, which is either "Extrusion 3D" or "Radial Prism"
+#  depending on geometry
+#  It is created by calling Mesh.Prism(geom=0)
+#
+#  @ingroup l3_algos_3dextr
+#
+class StdMeshersDC_Prism3D(Mesh_Algorithm):
+
+    ## Name of method of class Mesh creating an instance of this class
+    meshMethod = "Prism"
+    ## Name of algorithm type
+    algoType   = "Prism_3D"
+
+    ## Private constructor.
+    def __init__(self, mesh, geom=0):
+        Mesh_Algorithm.__init__(self)
+        
+        shape = geom
+        if not shape:
+            shape = mesh.geom
+        from geompy import SubShapeAll, ShapeType
+        nbSolids = len( SubShapeAll( shape, ShapeType["SOLID"] ))
+        nbShells = len( SubShapeAll( shape, ShapeType["SHELL"] ))
+        if nbSolids == 0 or nbSolids == nbShells:
+            self.Create(mesh, geom, "Prism_3D")
+        else:
+            self.algoType = "RadialPrism_3D"
+            self.Create(mesh, geom, "RadialPrism_3D")
+            self.distribHyp = self.Hypothesis("LayerDistribution", UseExisting=0)
+            self.nbLayers = None
+
+    ## Return 3D hypothesis holding the 1D one
+    def Get3DHypothesis(self):
+        if self.algoType != "RadialPrism_3D":
+            print "Prism_3D algorith doesn't support any hyposesis"
+            return None
+        return self.distribHyp
+
+    ## Private method creating a 1D hypothesis and storing it in the LayerDistribution
+    #  hypothesis. Returns the created hypothesis
+    def OwnHypothesis(self, hypType, args=[], so="libStdMeshersEngine.so"):
+        if self.algoType != "RadialPrism_3D":
+            print "Prism_3D algorith doesn't support any hyposesis"
+            return None
+        if not self.nbLayers is None:
+            self.mesh.GetMesh().RemoveHypothesis( self.geom, self.nbLayers )
+            self.mesh.GetMesh().AddHypothesis( self.geom, self.distribHyp )
+        study = self.mesh.smeshpyD.GetCurrentStudy() # prevents publishing own 1D hypothesis
+        self.mesh.smeshpyD.SetCurrentStudy( None )
+        hyp = self.mesh.smeshpyD.CreateHypothesis(hypType, so)
+        self.mesh.smeshpyD.SetCurrentStudy( study ) # enables publishing
+        self.distribHyp.SetLayerDistribution( hyp )
+        return hyp
+
+    ## Defines "NumberOfLayers" hypothesis, specifying the number of layers of
+    #  prisms to build between the inner and outer shells
+    #  @param n number of layers
+    #  @param UseExisting if ==true - searches for the existing hypothesis created with
+    #                     the same parameters, else (default) - creates a new one
+    def NumberOfLayers(self, n, UseExisting=0):
+        if self.algoType != "RadialPrism_3D":
+            print "Prism_3D algorith doesn't support any hyposesis"
+            return None
+        self.mesh.RemoveHypothesis( self.distribHyp, self.geom )
+        compFun = lambda hyp, args: IsEqual(hyp.GetNumberOfLayers(), args[0])
+        self.nbLayers = self.Hypothesis("NumberOfLayers", [n], UseExisting=UseExisting,
+                                        CompareMethod=compFun)
+        self.nbLayers.SetNumberOfLayers( n )
+        return self.nbLayers
+
+    ## Defines "LocalLength" hypothesis, specifying the segment length
+    #  to build between the inner and the outer shells
+    #  @param l the length of segments
+    #  @param p the precision of rounding
+    def LocalLength(self, l, p=1e-07):
+        if self.algoType != "RadialPrism_3D":
+            print "Prism_3D algorith doesn't support any hyposesis"
+            return None
+        hyp = self.OwnHypothesis("LocalLength", [l,p])
+        hyp.SetLength(l)
+        hyp.SetPrecision(p)
+        return hyp
+
+    ## Defines "NumberOfSegments" hypothesis, specifying the number of layers of
+    #  prisms to build between the inner and the outer shells.
+    #  @param n the number of layers
+    #  @param s the scale factor (optional)
+    def NumberOfSegments(self, n, s=[]):
+        if self.algoType != "RadialPrism_3D":
+            print "Prism_3D algorith doesn't support any hyposesis"
+            return None
+        if s == []:
+            hyp = self.OwnHypothesis("NumberOfSegments", [n])
+        else:
+            hyp = self.OwnHypothesis("NumberOfSegments", [n,s])
+            hyp.SetDistrType( 1 )
+            hyp.SetScaleFactor(s)
+        hyp.SetNumberOfSegments(n)
+        return hyp
+
+    ## Defines "Arithmetic1D" hypothesis, specifying the distribution of segments
+    #  to build between the inner and the outer shells with a length that changes in arithmetic progression
+    #  @param start  the length of the first segment
+    #  @param end    the length of the last  segment
+    def Arithmetic1D(self, start, end ):
+        if self.algoType != "RadialPrism_3D":
+            print "Prism_3D algorith doesn't support any hyposesis"
+            return None
+        hyp = self.OwnHypothesis("Arithmetic1D", [start, end])
+        hyp.SetLength(start, 1)
+        hyp.SetLength(end  , 0)
+        return hyp
+
+    ## Defines "StartEndLength" hypothesis, specifying distribution of segments
+    #  to build between the inner and the outer shells as geometric length increasing
+    #  @param start for the length of the first segment
+    #  @param end   for the length of the last  segment
+    def StartEndLength(self, start, end):
+        if self.algoType != "RadialPrism_3D":
+            print "Prism_3D algorith doesn't support any hyposesis"
+            return None
+        hyp = self.OwnHypothesis("StartEndLength", [start, end])
+        hyp.SetLength(start, 1)
+        hyp.SetLength(end  , 0)
+        return hyp
+
+    ## Defines "AutomaticLength" hypothesis, specifying the number of segments
+    #  to build between the inner and outer shells
+    #  @param fineness defines the quality of the mesh within the range [0-1]
+    def AutomaticLength(self, fineness=0):
+        if self.algoType != "RadialPrism_3D":
+            print "Prism_3D algorith doesn't support any hyposesis"
+            return None
+        hyp = self.OwnHypothesis("AutomaticLength")
+        hyp.SetFineness( fineness )
+        return hyp
+
+
+# Public class: Mesh_RadialQuadrangle1D2D
+# -------------------------------
+
+## Defines a Radial Quadrangle 1D2D algorithm
+#  It is created by calling Mesh.Quadrangle(RADIAL_QUAD,geom=0)
+#
+#  @ingroup l2_algos_radialq
+class StdMeshersDC_RadialQuadrangle1D2D(Mesh_Algorithm):
+
+    ## Name of method of class Mesh creating an instance of this class
+    meshMethod = "Quadrangle"
+    ## Name of algorithm type
+    algoType   = RADIAL_QUAD
+
+    ## Private constructor.
+    def __init__(self, mesh, geom=0):
+        Mesh_Algorithm.__init__(self)
+        self.Create(mesh, geom, self.algoType)
+
+        self.distribHyp = None #self.Hypothesis("LayerDistribution2D", UseExisting=0)
+        self.nbLayers = None
+
+    ## Return 2D hypothesis holding the 1D one
+    def Get2DHypothesis(self):
+        if not self.distribHyp:
+            self.distribHyp = self.Hypothesis("LayerDistribution2D", UseExisting=0)
+        return self.distribHyp
+
+    ## Private method creating a 1D hypothesis and storing it in the LayerDistribution
+    #  hypothesis. Returns the created hypothesis
+    def OwnHypothesis(self, hypType, args=[], so="libStdMeshersEngine.so"):
+        if self.nbLayers:
+            self.mesh.GetMesh().RemoveHypothesis( self.geom, self.nbLayers )
+        if self.distribHyp is None:
+            self.distribHyp = self.Hypothesis("LayerDistribution2D", UseExisting=0)
+        else:
+            self.mesh.GetMesh().AddHypothesis( self.geom, self.distribHyp )
+        study = self.mesh.smeshpyD.GetCurrentStudy() # prevents publishing own 1D hypothesis
+        self.mesh.smeshpyD.SetCurrentStudy( None )
+        hyp = self.mesh.smeshpyD.CreateHypothesis(hypType, so)
+        self.mesh.smeshpyD.SetCurrentStudy( study ) # enables publishing
+        self.distribHyp.SetLayerDistribution( hyp )
+        return hyp
+
+    ## Defines "NumberOfLayers" hypothesis, specifying the number of layers
+    #  @param n number of layers
+    #  @param UseExisting if ==true - searches for the existing hypothesis created with
+    #                     the same parameters, else (default) - creates a new one
+    def NumberOfLayers(self, n, UseExisting=0):
+        if self.distribHyp:
+            self.mesh.GetMesh().RemoveHypothesis( self.geom, self.distribHyp )
+        compFun = lambda hyp, args: IsEqual(hyp.GetNumberOfLayers(), args[0])
+        self.nbLayers = self.Hypothesis("NumberOfLayers2D", [n], UseExisting=UseExisting,
+                                        CompareMethod=compFun)
+        self.nbLayers.SetNumberOfLayers( n )
+        return self.nbLayers
+
+    ## Defines "LocalLength" hypothesis, specifying the segment length
+    #  @param l the length of segments
+    #  @param p the precision of rounding
+    def LocalLength(self, l, p=1e-07):
+        hyp = self.OwnHypothesis("LocalLength", [l,p])
+        hyp.SetLength(l)
+        hyp.SetPrecision(p)
+        return hyp
+
+    ## Defines "NumberOfSegments" hypothesis, specifying the number of layers
+    #  @param n the number of layers
+    #  @param s the scale factor (optional)
+    def NumberOfSegments(self, n, s=[]):
+        if s == []:
+            hyp = self.OwnHypothesis("NumberOfSegments", [n])
+        else:
+            hyp = self.OwnHypothesis("NumberOfSegments", [n,s])
+            hyp.SetDistrType( 1 )
+            hyp.SetScaleFactor(s)
+        hyp.SetNumberOfSegments(n)
+        return hyp
+
+    ## Defines "Arithmetic1D" hypothesis, specifying the distribution of segments
+    #  with a length that changes in arithmetic progression
+    #  @param start  the length of the first segment
+    #  @param end    the length of the last  segment
+    def Arithmetic1D(self, start, end ):
+        hyp = self.OwnHypothesis("Arithmetic1D", [start, end])
+        hyp.SetLength(start, 1)
+        hyp.SetLength(end  , 0)
+        return hyp
+
+    ## Defines "StartEndLength" hypothesis, specifying distribution of segments
+    #  as geometric length increasing
+    #  @param start for the length of the first segment
+    #  @param end   for the length of the last  segment
+    def StartEndLength(self, start, end):
+        hyp = self.OwnHypothesis("StartEndLength", [start, end])
+        hyp.SetLength(start, 1)
+        hyp.SetLength(end  , 0)
+        return hyp
+
+    ## Defines "AutomaticLength" hypothesis, specifying the number of segments
+    #  @param fineness defines the quality of the mesh within the range [0-1]
+    def AutomaticLength(self, fineness=0):
+        hyp = self.OwnHypothesis("AutomaticLength")
+        hyp.SetFineness( fineness )
+        return hyp
+
+
+# Public class: Mesh_UseExistingElements
+# --------------------------------------
+## Defines a Radial Quadrangle 1D2D algorithm
+#  It is created by calling Mesh.UseExisting1DElements(geom=0)
+#
+#  @ingroup l3_algos_basic
+class StdMeshersDC_UseExistingElements_1D(Mesh_Algorithm):
+
+    ## Name of method of class Mesh creating an instance of this class
+    meshMethod = "UseExisting1DElements"
+    ## Name of algorithm type
+    algoType   = "Import_1D"
+    isDefault  = True
+
+    def __init__(self, mesh, geom=0):
+        Mesh_Algorithm.__init__(self)
+        self.Create(mesh, geom, self.algoType)
+        return
+
+    ## Defines "Source edges" hypothesis, specifying groups of edges to import
+    #  @param groups list of groups of edges
+    #  @param toCopyMesh if True, the whole mesh \a groups belong to is imported
+    #  @param toCopyGroups if True, all groups of the mesh \a groups belong to are imported
+    #  @param UseExisting if ==true - searches for the existing hypothesis created with
+    #                     the same parameters, else (default) - creates a new one
+    def SourceEdges(self, groups, toCopyMesh=False, toCopyGroups=False, UseExisting=False):
+        for group in groups:
+            AssureGeomPublished( self.mesh, group )
+        compFun = lambda hyp, args: ( hyp.GetSourceEdges() == args[0] and \
+                                      hyp.GetCopySourceMesh() == args[1], args[2] )
+        hyp = self.Hypothesis("ImportSource1D", [groups, toCopyMesh, toCopyGroups],
+                              UseExisting=UseExisting, CompareMethod=compFun)
+        hyp.SetSourceEdges(groups)
+        hyp.SetCopySourceMesh(toCopyMesh, toCopyGroups)
+        return hyp
+
+# Public class: Mesh_UseExistingElements
+# --------------------------------------
+## Defines a Radial Quadrangle 1D2D algorithm
+#  It is created by calling Mesh.UseExisting2DElements(geom=0)
+#
+#  @ingroup l3_algos_basic
+class StdMeshersDC_UseExistingElements_1D2D(Mesh_Algorithm):
+
+    ## Name of method of class Mesh creating an instance of this class
+    meshMethod = "UseExisting2DElements"
+    ## Name of algorithm type
+    algoType   = "Import_1D2D"
+    isDefault  = True
+
+    def __init__(self, mesh, geom=0):
+        Mesh_Algorithm.__init__(self)
+        self.Create(mesh, geom, self.algoType)
+        return
+
+    ## Defines "Source faces" hypothesis, specifying groups of faces to import
+    #  @param groups list of groups of faces
+    #  @param toCopyMesh if True, the whole mesh \a groups belong to is imported
+    #  @param toCopyGroups if True, all groups of the mesh \a groups belong to are imported
+    #  @param UseExisting if ==true - searches for the existing hypothesis created with
+    #                     the same parameters, else (default) - creates a new one
+    def SourceFaces(self, groups, toCopyMesh=False, toCopyGroups=False, UseExisting=False):
+        for group in groups:
+            AssureGeomPublished( self.mesh, group )
+        compFun = lambda hyp, args: ( hyp.GetSourceFaces() == args[0] and \
+                                      hyp.GetCopySourceMesh() == args[1], args[2] )
+        hyp = self.Hypothesis("ImportSource2D", [groups, toCopyMesh, toCopyGroups],
+                              UseExisting=UseExisting, CompareMethod=compFun)
+        hyp.SetSourceFaces(groups)
+        hyp.SetCopySourceMesh(toCopyMesh, toCopyGroups)
+        return hyp
+
+
+# Public class: Mesh_Cartesian_3D
+# --------------------------------------
+## Defines a Body Fitting 3D algorithm
+#  It is created by calling Mesh.BodyFitted(geom=0)
+#
+#  @ingroup l3_algos_basic
+class StdMeshersDC_Cartesian_3D(Mesh_Algorithm):
+
+    ## Name of method of class Mesh creating an instance of this class
+    meshMethod = "BodyFitted"
+    ## Name of algorithm type
+    algoType   = "Cartesian_3D"
+    isDefault  = True
+
+    def __init__(self, mesh, geom=0):
+        self.Create(mesh, geom, self.algoType)
+        self.hyp = None
+        return
+
+    ## Defines "Body Fitting parameters" hypothesis
+    #  @param xGridDef is definition of the grid along the X asix.
+    #  It can be in either of two following forms:
+    #  - Explicit coordinates of nodes, e.g. [-1.5, 0.0, 3.1] or range( -100,200,10)
+    #  - Functions f(t) defining grid spacing at each point on grid axis. If there are
+    #    several functions, they must be accompanied by relative coordinates of
+    #    points dividing the whole shape into ranges where the functions apply; points
+    #    coodrinates should vary within (0.0, 1.0) range. Parameter \a t of the spacing
+    #    function f(t) varies from 0.0 to 1.0 witin a shape range. 
+    #    Examples:
+    #    - "10.5" - defines a grid with a constant spacing
+    #    - [["1", "1+10*t", "11"] [0.1, 0.6]] - defines different spacing in 3 ranges.
+    #  @param yGridDef defines the grid along the Y asix the same way as \a xGridDef does
+    #  @param zGridDef defines the grid along the Z asix the same way as \a xGridDef does
+    #  @param sizeThreshold (> 1.0) defines a minimal size of a polyhedron so that
+    #         a polyhedron of size less than hexSize/sizeThreshold is not created
+    #  @param UseExisting if ==true - searches for the existing hypothesis created with
+    #                     the same parameters, else (default) - creates a new one
+    def SetGrid(self, xGridDef, yGridDef, zGridDef, sizeThreshold=4.0, UseExisting=False):
+        if not self.hyp:
+            compFun = lambda hyp, args: False
+            self.hyp = self.Hypothesis("CartesianParameters3D",
+                                       [xGridDef, yGridDef, zGridDef, sizeThreshold],
+                                       UseExisting=UseExisting, CompareMethod=compFun)
+        if not self.mesh.IsUsedHypothesis( self.hyp, self.geom ):
+            self.mesh.AddHypothesis( self.hyp, self.geom )
+
+        for axis, gridDef in enumerate( [xGridDef, yGridDef, zGridDef]):
+            if not gridDef: raise ValueError, "Empty grid definition"
+            if isinstance( gridDef, str ):
+                self.hyp.SetGridSpacing( [gridDef], [], axis )
+            elif isinstance( gridDef[0], str ):
+                self.hyp.SetGridSpacing( gridDef, [], axis )
+            elif isinstance( gridDef[0], int ) or \
+                 isinstance( gridDef[0], float ):
+                self.hyp.SetGrid(gridDef, axis )
+            else:
+                self.hyp.SetGridSpacing( gridDef[0], gridDef[1], axis )
+        self.hyp.SetSizeThreshold( sizeThreshold )
+        return self.hyp
+
+# Public class: Mesh_UseExisting_1D
+# ---------------------------------
+## Defines a stub 1D algorithm, which enables "manual" creation of nodes and
+#  segments usable by 2D algoritms
+#  It is created by calling Mesh.UseExistingSegments(geom=0)
+#
+#  @ingroup l3_algos_basic
+
+class StdMeshersDC_UseExisting_1D(Mesh_Algorithm):
+
+    ## Name of method of class Mesh creating an instance of this class
+    meshMethod = "UseExistingSegments"
+    ## Name of algorithm type
+    algoType   = "UseExisting_1D"
+
+    def __init__(self, mesh, geom=0):
+        self.Create(mesh, geom, self.algoType)
+
+
+# Public class: Mesh_UseExisting
+# -------------------------------
+## Defines a stub 2D algorithm, which enables "manual" creation of nodes and
+#  faces usable by 3D algoritms
+#  It is created by calling Mesh.UseExistingFaces(geom=0)
+#
+#  @ingroup l3_algos_basic
+
+class StdMeshersDC_UseExisting_2D(Mesh_Algorithm):
+
+    ## Name of method of class Mesh creating an instance of this class
+    meshMethod = "UseExistingFaces"
+    ## Name of algorithm type
+    algoType   = "UseExisting_2D"
+
+    def __init__(self, mesh, geom=0):
+        self.Create(mesh, geom, self.algoType)
index 7750233704156310cc963ea305800c58468191f6..fb888795a09a3349fea787d03956f92392809a9b 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 import os
 import re
 
index d6688362ddff587d09c609b49de396f8dbbed1fd..6daa0e9468be35fcb8e86d02f1e853f1b8311f20 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  File   : batchmode_smesh.py
 #  Author : Oksana TCHEBANOVA
 #  Module : SMESH
@@ -32,6 +34,7 @@ import SMESH
 modulecatalog = naming_service.Resolve("/Kernel/ModulCatalog")
 
 smesh = lcc.FindOrLoadComponent("FactoryServer", "SMESH")
+smesh.SetCurrentStudy(myStudy)
 myStudyBuilder = myStudy.NewBuilder()
 
 if myStudyBuilder is None:
index e4159ebdbd997fad640a110f5d757be66caae06a..381b9ae3c563238d03854466126cd0302c0e264e 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # ==================================
 # Load all examples
 # -----------------
index fbc8c5f231c325f44547c921a13d1752d96d707f..10ba3f33ac9f8bf536b11fe472540169df4fa24b 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # =======================================
 #
 from geompy import *
@@ -286,6 +288,8 @@ piece_id = addToStudy(piece, "ex01_cube2build")
 # Meshing
 # =======
 
+smesh.SetCurrentStudy(salome.myStudy)
+
 # Create hexahedrical mesh on piece
 # ---------------------------------
 
index 732b579b722d7b6b48b541681cfbefc5e662cff9..9350199ebf17b1e1ce973d5ab095df5446b6ab8b 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # =======================================
 #
 from geompy import *
@@ -97,6 +99,8 @@ piece_id = addToStudy(piece, "ex02_cube2primitive")
 # Meshing
 # =======
 
+smesh.SetCurrentStudy(salome.myStudy)
+
 # Create hexahedrical mesh on piece
 # ---------------------------------
 
index e3447c37da10fc2bf4c7ba13ed165da696210bc3..1849895fe6e2519aedbc6cd120e436a07523d4f3 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # =======================================
 #
 from geompy import *
@@ -84,6 +86,8 @@ piece_id = addToStudy(piece, "ex03_cube2partition")
 # Meshing
 # =======
 
+smesh.SetCurrentStudy(salome.myStudy)
+
 # Create hexahedrical mesh on piece
 # ---------------------------------
 
index 18d4900ffb7f9521ff35d404681743a7a7531e45..773aca145e6ee22e52ca6288646a8390385a6d47 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # =======================================
 #
 from geompy import *
@@ -65,6 +67,8 @@ piece_id = addToStudy(piece, "ex04_cube5tetraHexa")
 # Meshing
 # =======
 
+smesh.SetCurrentStudy(salome.myStudy)
+
 # Create a hexahedral mesh
 # ------------------------
 
index 050509e29f70618bd815c1fa3bbf4ed36ecc7d3f..231c3f1d47fb7007125c4a4f43d066af53d6b952 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # =======================================
 #
 from geompy import *
@@ -123,6 +125,8 @@ piece_id = addToStudy(piece, "ex05_hole1build")
 # Meshing
 # =======
 
+smesh.SetCurrentStudy(salome.myStudy)
+
 # Create a hexahedral mesh
 # ------------------------
 
index 3f2c6893d84418d6bb43df2382bf015b0e3838d1..0335c3357b7ff4320884614663064e80ee6a1d6f 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # =======================================
 #
 from geompy import *
@@ -107,7 +109,7 @@ c_l.append(baseHexa4)
 
 c_cpd = MakeCompound(c_l)
 c_glu = MakeGlueFaces(c_cpd, 1.e-5)
-piece = RemoveExtraEdges(c_glu)
+piece = RemoveExtraEdges(c_glu, doUnionFaces=True)
 
 # Add in study
 # ------------
@@ -117,6 +119,8 @@ piece_id = addToStudy(piece, "ex06_hole1boolean")
 # Meshing
 # =======
 
+smesh.SetCurrentStudy(salome.myStudy)
+
 # Create a hexahedral mesh
 # ------------------------
 
index c46864c2d5c325c3e53ae422ffe3a0fc4abf9439..84a4326d6046aac3f81b0c21bb5af4ef4d67d6fc 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # =======================================
 #
 from geompy import *
@@ -70,7 +72,7 @@ p_tools.append(MakePlane(p_centre, MakeVectorDXDYDZ(-g_largeur, 0, g_longueur),
 
 p_part = MakePartition([c_piece], p_tools, [], [], ShapeType["SOLID"])
 
-p_blocs = RemoveExtraEdges(p_part)
+p_blocs = RemoveExtraEdges(p_part, doUnionFaces=True)
 piece   = MakeGlueFaces(p_blocs, 1.e-5)
 
 # Add in study
@@ -81,6 +83,8 @@ piece_id = addToStudy(piece, "ex07_hole1partition")
 # Meshing
 # =======
 
+smesh.SetCurrentStudy(salome.myStudy)
+
 # Create a hexahedral mesh
 # ------------------------
 
index 6ccb77d41e83dfb3cc5042b085374de701452802..0bc58f133afcb51afc60070ceb93c932f2d07966 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # =======================================
 #
 from geompy import *
@@ -114,6 +116,8 @@ piece_id = addToStudy(piece, "ex08_hole2build")
 # Meshing
 # =======
 
+smesh.SetCurrentStudy(salome.myStudy)
+
 # Create a hexahedral mesh
 # ------------------------
 
index d0e0fb72a4a5e7f44fe165ae7b9d9d3bf556bdda..cbbec434cbc23fdc70b390dd0bdfef2ccc5df23d 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # =======================================
 #
 from geompy import *
@@ -117,6 +119,8 @@ piece_id = addToStudy(piece, "ex09_grid4build")
 # Meshing
 # =======
 
+smesh.SetCurrentStudy(salome.myStudy)
+
 # Create a hexahedral mesh
 # ------------------------
 
index 8f63e031d52080997ef807c81584a372d39c10e3..1679e4b5f3c23273b9571057cc111140ed271958 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # =======================================
 #
 from geompy import *
@@ -79,6 +81,8 @@ piece_id = addToStudy(piece, "ex10_grid4geometry")
 # Meshing
 # =======
 
+smesh.SetCurrentStudy(salome.myStudy)
+
 # Create a hexahedral mesh
 # ------------------------
 
index 3369074d2873babb00f92f550c28fb2819b91af5..252aa5563c2ffba920ae8f1626069c51c2777e7a 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # =======================================
 #
 from geompy import *
@@ -83,7 +85,7 @@ p_tools.append(MakePlane(e_centre, MakeVectorDXDYDZ(-1, 0, 1), g_trim))
 
 p_part = MakePartition([e_blo1, e_blo2, e_blo3], p_tools, [], [], ShapeType["SOLID"])
 
-p_element = RemoveExtraEdges(p_part)
+p_element = RemoveExtraEdges(p_part, doUnionFaces=True)
 
 # Grid and glue
 # -------------
@@ -100,6 +102,8 @@ piece_id = addToStudy(piece, "ex11_grid3partition")
 # Meshing
 # =======
 
+smesh.SetCurrentStudy(salome.myStudy)
+
 # Create a hexahedral mesh
 # ------------------------
 
index 2f41e3beef6288528be0106c5c61a7ce5953f811..bf6593b991e16ea6271827b4fa5d506eb7ec7347 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # =======================================
 #
 from geompy import *
@@ -115,6 +117,8 @@ piece_id = addToStudy(piece, "ex12_grid17partition")
 # Meshing
 # =======
 
+smesh.SetCurrentStudy(salome.myStudy)
+
 # Create a hexahedral mesh
 # ------------------------
 
index 0b3ff6baf81abd2833d67ee003d5e8ef3faedc69..a54fd6266f9d30d88a31f5d277a4cd56c71f742a 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # ==================================
 #
 from geompy import *
@@ -204,7 +206,7 @@ blocks.append(full_parts)
 
 piece_cpd = MakeCompound(blocks)
 
-piece_ok = RemoveExtraEdges(piece_cpd)
+piece_ok = RemoveExtraEdges(piece_cpd, doUnionFaces=True)
 
 piece = MakeGlueFaces(piece_ok, 1.e-3)
 
@@ -213,6 +215,8 @@ piece_id = addToStudy(piece, "ex13_hole1partial")
 # Meshing
 # =======
 
+smesh.SetCurrentStudy(salome.myStudy)
+
 # Create a mesh
 # -------------
 
index 42d460b93965ececf89e2dc43d9cba0b4b73c7a5..0f058c098a3713d3c641918f6f14c6b510792876 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # =======================================
 #
 from geompy import *
@@ -98,6 +100,8 @@ piece_id = addToStudy(piece, "ex14_cyl1holed")
 # Maillage
 # ========
 
+smesh.SetCurrentStudy(salome.myStudy)
+
 # Creer un maillage hexahedrique
 # ------------------------------
 
index ffd3395c68a83fc328e3efda79232389e9d91ca0..5322e9ef5fd113b7349c6e4c73fc368f502fac7c 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # =======================================
 #
 from geompy import *
@@ -167,7 +169,7 @@ cpd = cpd + r_element
 # Compound
 # --------
 
-piece = RemoveExtraEdges(MakeCompound(cpd))
+piece = RemoveExtraEdges(MakeCompound(cpd), True)
 
 # Ajouter la piece dans l'etude
 # -----------------------------
@@ -177,6 +179,8 @@ piece_id = addToStudy(piece, "ex15_cyl2geometry")
 # Meshing
 # =======
 
+smesh.SetCurrentStudy(salome.myStudy)
+
 # Create a hexahedral mesh
 # ------------------------
 
index 774cc5f7d08dabfe65ced71bc5b1e9218b4cda5e..f644c22a7dec62c4f79c363b353bae6fff45e466 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # =======================================
 #
 from geompy import *
@@ -98,6 +100,7 @@ d_element[10] = MakeCut(d_element[10], c_cyl)
 # --------
 
 piece = RemoveExtraEdges(MakeCompound(d_element))
+piece = MakeGlueFaces(piece, 1e-07)
 
 # Add piece in study
 # ------------------
@@ -107,6 +110,8 @@ piece_id = addToStudy(piece, "ex16_cyl2complementary")
 # Meshing
 # =======
 
+smesh.SetCurrentStudy(salome.myStudy)
+
 # Create a hexahedral mesh
 # ------------------------
 
index a25de9627f7257e1c652996a0fd3682f9fca6f8b..2626431f0eb9d7c92bd511578b58c71b611a87c4 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # =======================================
 #
 from geompy import *
@@ -80,6 +82,8 @@ piece_id = addToStudy(piece, "ex17_dome1")
 # Maillage
 # ========
 
+smesh.SetCurrentStudy(salome.myStudy)
+
 # Maillage hexahedrique
 # ---------------------
 
index f56015619e7fa68efd29cf553d01fc8b3889b2cb..dc31fe8f8d2a879bfa64ae85c8d115e989d8844e 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # =======================================
 #
 from geompy import *
@@ -117,6 +119,8 @@ piece_id = addToStudy(piece, "ex18_dome2")
 # Maillage
 # ========
 
+smesh.SetCurrentStudy(salome.myStudy)
+
 # Maillage hexahedrique
 # ---------------------
 
index 510adf8002c363c5094f77abbe3abc915c2033c6..87959634899fefbab29747b75aa6e8f9e139cb5c 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # ==================================
 #
 from geompy import *
@@ -74,17 +76,13 @@ f4 = MakePlane(sphere_centre, MakeVectorDXDYDZ( 1, 0, -1), plan_trim)
 
 
 #sphere_decoupee = MakePartition(solids, sphere_outils, [], [], ShapeType["SOLID"])
-solids = geompy.SubShapeAll(sphere_troue,geompy.ShapeType["SOLID"])
-sphere_decoupee = MakePartition(solids, [f1], [], [], ShapeType["SOLID"])
-solids = geompy.SubShapeAll(sphere_decoupee,geompy.ShapeType["SOLID"])
-sphere_decoupee = MakePartition(solids, [f2], [], [], ShapeType["SOLID"])
-solids = geompy.SubShapeAll(sphere_decoupee,geompy.ShapeType["SOLID"])
-sphere_decoupee = MakePartition(solids, [f3], [], [], ShapeType["SOLID"])
-solids = geompy.SubShapeAll(sphere_decoupee,geompy.ShapeType["SOLID"])
-sphere_decoupee = MakePartition(solids, [f4], [], [], ShapeType["SOLID"])
-solids = geompy.SubShapeAll(sphere_decoupee,geompy.ShapeType["SOLID"])
-
-sphere_partie = geompy.MakeCompound(solids)
+
+sphere_decoupee = MakePartition([sphere_troue],    [f1], [], [], ShapeType["SOLID"])
+sphere_decoupee = MakePartition([sphere_decoupee], [f2], [], [], ShapeType["SOLID"])
+sphere_decoupee = MakePartition([sphere_decoupee], [f3], [], [], ShapeType["SOLID"])
+sphere_decoupee = MakePartition([sphere_decoupee], [f4], [], [], ShapeType["SOLID"])
+
+sphere_partie = geompy.MakeCompound([sphere_decoupee])
 
 sphere_partie   = GetBlockNearPoint(sphere_decoupee, MakeVertex(-sphere_rayon, 0, 0))
 sphere_bloc     = RemoveExtraEdges(sphere_partie)
@@ -111,17 +109,12 @@ cube_plein   = MakeBox(-cube_cote, -cube_cote, -cube_cote,  +cube_cote, +cube_co
 cube_trou    = MakeCut(cube_plein, sphere_pleine)
 #cube_decoupe = MakePartition([cube_trou], sphere_outils, [], [], ShapeType["SOLID"])
 
-solids = geompy.SubShapeAll(cube_trou,geompy.ShapeType["SOLID"])
-cube_decoupe = MakePartition(solids, [f1], [], [], ShapeType["SOLID"])
-solids = geompy.SubShapeAll(cube_decoupe,geompy.ShapeType["SOLID"])
-cube_decoupe = MakePartition(solids, [f2], [], [], ShapeType["SOLID"])
-solids = geompy.SubShapeAll(cube_decoupe,geompy.ShapeType["SOLID"])
-cube_decoupe = MakePartition(solids, [f3], [], [], ShapeType["SOLID"])
-solids = geompy.SubShapeAll(cube_decoupe,geompy.ShapeType["SOLID"])
-cube_decoupe = MakePartition(solids, [f4], [], [], ShapeType["SOLID"])
-solids = geompy.SubShapeAll(cube_decoupe,geompy.ShapeType["SOLID"])
+cube_decoupe = MakePartition([cube_trou],    [f1], [], [], ShapeType["SOLID"])
+cube_decoupe = MakePartition([cube_decoupe], [f2], [], [], ShapeType["SOLID"])
+cube_decoupe = MakePartition([cube_decoupe], [f3], [], [], ShapeType["SOLID"])
+cube_decoupe = MakePartition([cube_decoupe], [f4], [], [], ShapeType["SOLID"])
 
-cube_decoupe = geompy.MakeCompound(solids)
+cube_decoupe = geompy.MakeCompound([cube_decoupe])
 
 
 cube_partie  = GetBlockNearPoint(cube_decoupe, MakeVertex(-cube_cote, 0, 0))
@@ -167,6 +160,8 @@ UnionList(groupe, groupe_sphere)
 # Meshing
 # =======
 
+smesh.SetCurrentStudy(salome.myStudy)
+
 # Create a hexahedral mesh
 # ------------------------
 
index f6c3c3789f923e69f9efa0ba7b505ec56efa7d20..befd0e1d8bc638fcd7be663b7c162f6c797f10fd 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # ==================================
 #
 from geompy import *
@@ -92,6 +94,8 @@ UnionIDs(group, faces)
 # Create a mesh
 # =============
 
+smesh.SetCurrentStudy(salome.myStudy)
+
 # Define a mesh on a geometry
 # ---------------------------
 
index 6d9f3077dac394051f92470e79350e97c96a7614..91100376b998373439b9e78ed2489be00d6e7413 100644 (file)
@@ -1,31 +1,30 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # ==================================
 #
 import math
 
 import geompy
 import smesh
-
+import salome
 geo = geompy
 
 # Parameters
@@ -97,6 +96,8 @@ geo.DifferenceList(group_1, [group_1_box])
 # Mesh the blocks with hexahedral
 # -------------------------------
 
+smesh.SetCurrentStudy(salome.myStudy)
+
 def discretize(x, y, z,  n, s=blocks):
     p = geo.MakeVertex(x, y, z)
     e = geo.GetEdgeNearPoint(s, p)
index 1e218a8fa90e28bb71b1eec4e66d1f3c3f8ca26b..8363ea81af0c46b54e4a1da98dd0470d2226fcaa 100644 (file)
@@ -1,24 +1,23 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # =======================================
 # Procedure that take a triangulation and split all triangles in 4 others triangles
 #
index af892e7ff7b2b59af6a9a5bea6c94f329a90ee3e..5bab3082321ab0471cf74e27c1a15123d96a2acf 100755 (executable)
@@ -1,73 +1,92 @@
-\r
-import sys\r
-import salome\r
-import geompy\r
-import math\r
-import SALOMEDS\r
-import SMESH\r
-import smesh\r
-\r
-salome.salome_init()\r
-aStudyId = salome.myStudy._get_StudyId()\r
-\r
-geompy.init_geom(salome.myStudy)\r
-global Face_1\r
-Face_1 = geompy.MakeFaceHW(100, 100, 1)\r
-geompy.addToStudy( Face_1, "Face_1" )\r
-\r
-#smesh.smesh.SetCurrentStudy(aStudyId)\r
-import StdMeshers\r
-pattern = smesh.GetPattern()\r
-Mesh_1 = smesh.Mesh(Face_1)\r
-Regular_1D = Mesh_1.Segment()\r
-Nb_Segments_1 = Regular_1D.NumberOfSegments(10)\r
-Nb_Segments_1.SetDistrType( 0 )\r
-Quadrangle_2D = Mesh_1.Quadrangle()\r
-isDone = Mesh_1.Compute()\r
-\r
-# groups creation\r
-\r
-aListOfElems = [ 52, 53, 54, 55, 56, 57,\r
-                 62, 63, 64, 65, 66, 67,\r
-                 72, 73, 74, 75, 76, 77,\r
-                 82, 83, 84, 85, 86, 87 ]\r
-                 \r
-aRedGroup = Mesh_1.GetMesh().CreateGroup( smesh.FACE, "Red" )\r
-aRedGroup.Add( aListOfElems );\r
-aRedGroup.SetColor( SALOMEDS.Color( 1, 0, 0 ) )\r
-\r
-aListOfElems = [ 55, 56, 57, 58, 59,\r
-                 65, 66, 67, 68, 69,\r
-                 75, 76, 77, 78, 79,\r
-                 85, 86, 87, 88, 89,\r
-                 95, 96, 97, 98, 99,\r
-                 105, 106, 107, 108, 109,\r
-                 115, 116, 117, 118, 119,\r
-                 125, 126, 127, 128, 129 ]\r
-                 \r
-aGreenGroup = Mesh_1.GetMesh().CreateGroup( smesh.FACE, "Green" )\r
-aGreenGroup.Add( aListOfElems );\r
-aGreenGroup.SetColor( SALOMEDS.Color( 0, 1, 0 ) )\r
-\r
-aListOfElems = [ 63, 64, 65, 66, 67, 68, \r
-                 73, 74, 75, 76, 77, 78,\r
-                 83, 84, 85, 86, 87, 88, \r
-                 93, 94, 95, 96, 97, 98, \r
-                 103, 104, 105, 106, 107, 108, \r
-                 113, 114, 115, 116, 117, 118 ]\r
-                 \r
-aBlueGroup = Mesh_1.GetMesh().CreateGroup( smesh.FACE, "Blue" )\r
-aBlueGroup.Add( aListOfElems );\r
-aBlueGroup.SetColor( SALOMEDS.Color( 0, 0, 1 ) )\r
-\r
-# UnionListOfGroups()\r
-aUnGrp = Mesh_1.UnionListOfGroups([aRedGroup, aGreenGroup, aBlueGroup], "UnionGrp" )\r
-\r
-# IntersectListOfGroups()\r
-aIntGrp=Mesh_1.IntersectListOfGroups([aRedGroup, aGreenGroup, aBlueGroup], "IntGrp" )\r
-\r
-# CutListOfGroups()\r
-aCutGrp=Mesh_1.CutListOfGroups([aRedGroup],[aGreenGroup,aBlueGroup],"CutGrp")\r
-\r
-salome.sg.updateObjBrowser( 1 )\r
-\r
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# 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.com
+#
+
+import sys
+import salome
+import geompy
+import math
+import SALOMEDS
+import SMESH
+import smesh
+
+salome.salome_init()
+aStudyId = salome.myStudy._get_StudyId()
+
+geompy.init_geom(salome.myStudy)
+global Face_1
+Face_1 = geompy.MakeFaceHW(100, 100, 1)
+geompy.addToStudy( Face_1, "Face_1" )
+
+smesh.SetCurrentStudy(salome.myStudy)
+import StdMeshers
+pattern = smesh.GetPattern()
+Mesh_1 = smesh.Mesh(Face_1)
+Regular_1D = Mesh_1.Segment()
+Nb_Segments_1 = Regular_1D.NumberOfSegments(10)
+Nb_Segments_1.SetDistrType( 0 )
+Quadrangle_2D = Mesh_1.Quadrangle()
+isDone = Mesh_1.Compute()
+
+# groups creation
+
+aListOfElems = [ 52, 53, 54, 55, 56, 57,
+                 62, 63, 64, 65, 66, 67,
+                 72, 73, 74, 75, 76, 77,
+                 82, 83, 84, 85, 86, 87 ]
+                 
+aRedGroup = Mesh_1.GetMesh().CreateGroup( smesh.FACE, "Red" )
+aRedGroup.Add( aListOfElems );
+aRedGroup.SetColor( SALOMEDS.Color( 1, 0, 0 ) )
+
+aListOfElems = [ 55, 56, 57, 58, 59,
+                 65, 66, 67, 68, 69,
+                 75, 76, 77, 78, 79,
+                 85, 86, 87, 88, 89,
+                 95, 96, 97, 98, 99,
+                 105, 106, 107, 108, 109,
+                 115, 116, 117, 118, 119,
+                 125, 126, 127, 128, 129 ]
+                 
+aGreenGroup = Mesh_1.GetMesh().CreateGroup( smesh.FACE, "Green" )
+aGreenGroup.Add( aListOfElems );
+aGreenGroup.SetColor( SALOMEDS.Color( 0, 1, 0 ) )
+
+aListOfElems = [ 63, 64, 65, 66, 67, 68, 
+                 73, 74, 75, 76, 77, 78,
+                 83, 84, 85, 86, 87, 88, 
+                 93, 94, 95, 96, 97, 98, 
+                 103, 104, 105, 106, 107, 108, 
+                 113, 114, 115, 116, 117, 118 ]
+                 
+aBlueGroup = Mesh_1.GetMesh().CreateGroup( smesh.FACE, "Blue" )
+aBlueGroup.Add( aListOfElems );
+aBlueGroup.SetColor( SALOMEDS.Color( 0, 0, 1 ) )
+
+# UnionListOfGroups()
+aUnGrp = Mesh_1.UnionListOfGroups([aRedGroup, aGreenGroup, aBlueGroup], "UnionGrp" )
+
+# IntersectListOfGroups()
+aIntGrp=Mesh_1.IntersectListOfGroups([aRedGroup, aGreenGroup, aBlueGroup], "IntGrp" )
+
+# CutListOfGroups()
+aCutGrp=Mesh_1.CutListOfGroups([aRedGroup],[aGreenGroup,aBlueGroup],"CutGrp")
+
+salome.sg.updateObjBrowser( 1 )
+
index c73dc872dfcbe03c37035b99c1130afd68cbeaec..ece87736daf7fd58ec5040b0b50368a3564ebe5e 100644 (file)
@@ -1,6 +1,25 @@
-# CEA/LGLS 2008, Christian Van Wambeke (CEA/LGLS), Francis KLOSS (OCC)
-# ====================================================================
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# 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.com
+#
 
+# ====================================================================
+#
 import os
 
 import geompy
@@ -27,6 +46,8 @@ geompy.addToStudy(cylinder, "Cylinder")
 # Define a mesh on a geometry
 # ---------------------------
 
+smesh.SetCurrentStudy(salome.myStudy)
+
 m = smesh.Mesh(cylinder)
 
 # 2D mesh with BLSURF
index 13cd9cf2625460a556a15b3fa05698273802454e..ae8daeb0cfe3979aa972a44038a0b145aba273fc 100755 (executable)
@@ -1,47 +1,67 @@
-import sys\r
-import salome\r
-import geompy\r
-import math\r
-import SALOMEDS\r
-import SMESH\r
-import smesh\r
-\r
-salome.salome_init()\r
-aStudyId = salome.myStudy._get_StudyId()\r
-\r
-geompy.init_geom(salome.myStudy)\r
-\r
-geompy.init_geom(salome.myStudy)\r
-global Box_1\r
-Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)\r
-geompy.addToStudy( Box_1, "Box_1" )\r
-\r
-#smesh.smesh.SetCurrentStudy(theStudy)\r
-import StdMeshers\r
-Mesh_1 = smesh.Mesh(Box_1)\r
-Regular_1D = Mesh_1.Segment()\r
-Nb_Segments_1 = Regular_1D.NumberOfSegments(10)\r
-Nb_Segments_1.SetDistrType( 0 )\r
-Quadrangle_2D = Mesh_1.Quadrangle()\r
-Hexa_3D = Mesh_1.Hexahedron()\r
-isDone = Mesh_1.Compute()\r
-\r
-### CreateDimGroup()\r
-\r
-aListOf3d_1=range(721,821)\r
-\r
-aGrp3D_1=Mesh_1.GetMesh().CreateGroup( smesh.VOLUME, "Src 3D 1" )\r
-aGrp3D_1.Add( aListOf3d_1 )\r
-\r
-aListOf3d_2=range(821, 921)\r
-aGrp3D_2=Mesh_1.GetMesh().CreateGroup( smesh.VOLUME, "Src 3D 2" )\r
-aGrp3D_2.Add( aListOf3d_2 )\r
-\r
-aGrp2D = Mesh_1.CreateDimGroup( [aGrp3D_1, aGrp3D_2], smesh.FACE, "Faces" )\r
-\r
-aGrp1D = Mesh_1.CreateDimGroup( [aGrp3D_1, aGrp3D_2], smesh.EDGE, "Edges" )\r
-\r
-aGrp0D = Mesh_1.CreateDimGroup( [aGrp3D_1, aGrp3D_2], smesh.NODE, "Nodes" )\r
-\r
-salome.sg.updateObjBrowser( 1 )\r
-\r
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# 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.com
+#
+
+import sys
+import salome
+import geompy
+import math
+import SALOMEDS
+import SMESH
+import smesh
+
+salome.salome_init()
+aStudyId = salome.myStudy._get_StudyId()
+
+geompy.init_geom(salome.myStudy)
+
+geompy.init_geom(salome.myStudy)
+global Box_1
+Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
+geompy.addToStudy( Box_1, "Box_1" )
+
+smesh.SetCurrentStudy(salome.myStudy)
+import StdMeshers
+Mesh_1 = smesh.Mesh(Box_1)
+Regular_1D = Mesh_1.Segment()
+Nb_Segments_1 = Regular_1D.NumberOfSegments(10)
+Nb_Segments_1.SetDistrType( 0 )
+Quadrangle_2D = Mesh_1.Quadrangle()
+Hexa_3D = Mesh_1.Hexahedron()
+isDone = Mesh_1.Compute()
+
+### CreateDimGroup()
+
+aListOf3d_1=range(721,821)
+
+aGrp3D_1=Mesh_1.GetMesh().CreateGroup( smesh.VOLUME, "Src 3D 1" )
+aGrp3D_1.Add( aListOf3d_1 )
+
+aListOf3d_2=range(821, 921)
+aGrp3D_2=Mesh_1.GetMesh().CreateGroup( smesh.VOLUME, "Src 3D 2" )
+aGrp3D_2.Add( aListOf3d_2 )
+
+aGrp2D = Mesh_1.CreateDimGroup( [aGrp3D_1, aGrp3D_2], smesh.FACE, "Faces" )
+
+aGrp1D = Mesh_1.CreateDimGroup( [aGrp3D_1, aGrp3D_2], smesh.EDGE, "Edges" )
+
+aGrp0D = Mesh_1.CreateDimGroup( [aGrp3D_1, aGrp3D_2], smesh.NODE, "Nodes" )
+
+salome.sg.updateObjBrowser( 1 )
+
index dc22bc389d3ca1b078d48737e865a738ad4735e3..c13a57e8e4c414f784445f560a6898df85bbc23f 100644 (file)
@@ -1,24 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+#  -*- coding: iso-8859-1 -*-
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2003-2007  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 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.
+# 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
+# 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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  File   : smesh.py
 #  Author : Francis KLOSS, OCC
 #  Module : SMESH
@@ -34,12 +36,34 @@ import geompy
 import smeshDC
 from smeshDC import *
 
+# get instance of class smeshDC
 smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH")
 smesh.init_smesh(salome.myStudy,geompy.geom)
 
-# Export the methods of smeshD
+# load plugins
+from smeshDC import Mesh, algoCreator
+for pluginName in os.environ["SMESH_MeshersList"].split(":"):
+
+  pluginName += "DC"
+  try:
+    exec("from %s import *" % pluginName )
+  except Exception, e:
+    print "Exception while loading %s: %s" % ( pluginName, e )
+    continue
+  exec("import %s" % pluginName )
+  plugin = eval(pluginName)
+
+  # add methods creating algorithms to Mesh
+  for k in dir(plugin):
+    if k[0] == '_':continue
+    algo = getattr(plugin,k)
+    if type( algo ).__name__ == 'classobj' and hasattr( algo, "meshMethod"):
+      if not hasattr( Mesh, algo.meshMethod ):
+        setattr( Mesh, algo.meshMethod, algoCreator())
+      getattr( Mesh, algo.meshMethod ).add( algo )
+
+# Export the methods of smeshDC
 for k in dir(smesh):
   if k[0] == '_':continue
   globals()[k]=getattr(smesh,k)
 del k
-
index 7b81262a0248edb6125b559758e54653ec3bed97..9780503a12d00e5de5007cae0a40a29b8638fcd1 100644 (file)
@@ -1,28 +1,25 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 #  File   : smesh.py
 #  Author : Francis KLOSS, OCC
 #  Module : SMESH
-#
+
 """
  \namespace smesh
  \brief Module smesh
 ##     @defgroup l3_hypos_1dhyps 1D Meshing Hypotheses
 ##     @defgroup l3_hypos_2dhyps 2D Meshing Hypotheses
 ##     @defgroup l3_hypos_maxvol Max Element Volume hypothesis
-##     @defgroup l3_hypos_netgen Netgen 2D and 3D hypotheses
-##     @defgroup l3_hypos_ghs3dh GHS3D Parameters hypothesis
-##     @defgroup l3_hypos_blsurf BLSURF Parameters hypothesis
-##     @defgroup l3_hypos_hexotic Hexotic Parameters hypothesis
+##     @defgroup l3_hypos_quad Quadrangle Parameters hypothesis
 ##     @defgroup l3_hypos_additi Additional Hypotheses
 
 ##   @}
@@ -88,6 +82,7 @@
 ##   @defgroup l2_modif_tofromqu Convert to/from Quadratic Mesh
 
 ## @}
+## @defgroup l1_measurements Measurements
 
 import salome
 import geompyDC
@@ -95,41 +90,12 @@ import geompyDC
 import SMESH # This is necessary for back compatibility
 from   SMESH import *
 
-import StdMeshers
-
 import SALOME
-
-# import NETGENPlugin module if possible
-noNETGENPlugin = 0
-try:
-    import NETGENPlugin
-except ImportError:
-    noNETGENPlugin = 1
-    pass
+import SALOMEDS
 
 ## @addtogroup l1_auxiliary
 ## @{
 
-# Types of algorithms
-REGULAR    = 1
-PYTHON     = 2
-COMPOSITE  = 3
-SOLE       = 0
-SIMPLE     = 1
-
-MEFISTO       = 3
-NETGEN        = 4
-GHS3D         = 5
-FULL_NETGEN   = 6
-NETGEN_2D     = 7
-NETGEN_1D2D   = NETGEN
-NETGEN_1D2D3D = FULL_NETGEN
-NETGEN_FULL   = FULL_NETGEN
-Hexa    = 8
-Hexotic = 9
-BLSURF  = 10
-GHS3DPRL = 11
-
 # MirrorType enumeration
 POINT = SMESH_MeshEditor.POINT
 AXIS =  SMESH_MeshEditor.AXIS
@@ -139,213 +105,74 @@ PLANE = SMESH_MeshEditor.PLANE
 LAPLACIAN_SMOOTH = SMESH_MeshEditor.LAPLACIAN_SMOOTH
 CENTROIDAL_SMOOTH = SMESH_MeshEditor.CENTROIDAL_SMOOTH
 
-# Fineness enumeration (for NETGEN)
-VeryCoarse = 0
-Coarse     = 1
-Moderate   = 2
-Fine       = 3
-VeryFine   = 4
-Custom     = 5
-
-# Optimization level of GHS3D
-None_Optimization, Light_Optimization, Medium_Optimization, Strong_Optimization = 0,1,2,3
-
-# Topology treatment way of BLSURF
-FromCAD, PreProcess, PreProcessPlus = 0,1,2
+PrecisionConfusion = 1e-07
 
-# Element size flag of BLSURF
-DefaultSize, DefaultGeom, Custom = 0,0,1
+# TopAbs_State enumeration
+[TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN] = range(4)
 
-PrecisionConfusion = 1e-07
+# Methods of splitting a hexahedron into tetrahedra
+Hex_5Tet, Hex_6Tet, Hex_24Tet = 1, 2, 3
 
 ## Converts an angle from degrees to radians
 def DegreesToRadians(AngleInDegrees):
     from math import pi
     return AngleInDegrees * pi / 180.0
 
+import salome_notebook
+notebook = salome_notebook.notebook
 # Salome notebook variable separator
 var_separator = ":"
 
-# Parametrized substitute for PointStruct
-class PointStructStr:
-
-    x = 0
-    y = 0
-    z = 0
-    xStr = ""
-    yStr = ""
-    zStr = ""
-
-    def __init__(self, xStr, yStr, zStr):
-        self.xStr = xStr
-        self.yStr = yStr
-        self.zStr = zStr
-        if isinstance(xStr, str) and notebook.isVariable(xStr):
-            self.x = notebook.get(xStr)
-        else:
-            self.x = xStr
-        if isinstance(yStr, str) and notebook.isVariable(yStr):
-            self.y = notebook.get(yStr)
-        else:
-            self.y = yStr
-        if isinstance(zStr, str) and notebook.isVariable(zStr):
-            self.z = notebook.get(zStr)
-        else:
-            self.z = zStr
-
-# Parametrized substitute for PointStruct (with 6 parameters)
-class PointStructStr6:
-
-    x1 = 0
-    y1 = 0
-    z1 = 0
-    x2 = 0
-    y2 = 0
-    z2 = 0
-    xStr1 = ""
-    yStr1 = ""
-    zStr1 = ""
-    xStr2 = ""
-    yStr2 = ""
-    zStr2 = ""
-
-    def __init__(self, x1Str, x2Str, y1Str, y2Str, z1Str, z2Str):
-        self.x1Str = x1Str
-        self.x2Str = x2Str
-        self.y1Str = y1Str
-        self.y2Str = y2Str
-        self.z1Str = z1Str
-        self.z2Str = z2Str
-        if isinstance(x1Str, str) and notebook.isVariable(x1Str):
-            self.x1 = notebook.get(x1Str)
-        else:
-            self.x1 = x1Str
-        if isinstance(x2Str, str) and notebook.isVariable(x2Str):
-            self.x2 = notebook.get(x2Str)
-        else:
-            self.x2 = x2Str
-        if isinstance(y1Str, str) and notebook.isVariable(y1Str):
-            self.y1 = notebook.get(y1Str)
-        else:
-            self.y1 = y1Str
-        if isinstance(y2Str, str) and notebook.isVariable(y2Str):
-            self.y2 = notebook.get(y2Str)
-        else:
-            self.y2 = y2Str
-        if isinstance(z1Str, str) and notebook.isVariable(z1Str):
-            self.z1 = notebook.get(z1Str)
-        else:
-            self.z1 = z1Str
-        if isinstance(z2Str, str) and notebook.isVariable(z2Str):
-            self.z2 = notebook.get(z2Str)
-        else:
-            self.z2 = z2Str
-
-# Parametrized substitute for AxisStruct
-class AxisStructStr:
-
-    x = 0
-    y = 0
-    z = 0
-    dx = 0
-    dy = 0
-    dz = 0
-    xStr = ""
-    yStr = ""
-    zStr = ""
-    dxStr = ""
-    dyStr = ""
-    dzStr = ""
-
-    def __init__(self, xStr, yStr, zStr, dxStr, dyStr, dzStr):
-        self.xStr = xStr
-        self.yStr = yStr
-        self.zStr = zStr
-        self.dxStr = dxStr
-        self.dyStr = dyStr
-        self.dzStr = dzStr
-        if isinstance(xStr, str) and notebook.isVariable(xStr):
-            self.x = notebook.get(xStr)
-        else:
-            self.x = xStr
-        if isinstance(yStr, str) and notebook.isVariable(yStr):
-            self.y = notebook.get(yStr)
-        else:
-            self.y = yStr
-        if isinstance(zStr, str) and notebook.isVariable(zStr):
-            self.z = notebook.get(zStr)
-        else:
-            self.z = zStr
-        if isinstance(dxStr, str) and notebook.isVariable(dxStr):
-            self.dx = notebook.get(dxStr)
-        else:
-            self.dx = dxStr
-        if isinstance(dyStr, str) and notebook.isVariable(dyStr):
-            self.dy = notebook.get(dyStr)
-        else:
-            self.dy = dyStr
-        if isinstance(dzStr, str) and notebook.isVariable(dzStr):
-            self.dz = notebook.get(dzStr)
-        else:
-            self.dz = dzStr
-
-# Parametrized substitute for DirStruct
-class DirStructStr:
-
-    def __init__(self, pointStruct):
-        self.pointStruct = pointStruct
-
-# Returns list of variable values from salome notebook
-def ParsePointStruct(Point):
-    Parameters = 2*var_separator
-    if isinstance(Point, PointStructStr):
-        Parameters = str(Point.xStr) + var_separator + str(Point.yStr) + var_separator + str(Point.zStr)
-        Point = PointStruct(Point.x, Point.y, Point.z)
-    return Point, Parameters
-
-# Returns list of variable values from salome notebook
-def ParseDirStruct(Dir):
-    Parameters = 2*var_separator
-    if isinstance(Dir, DirStructStr):
-        pntStr = Dir.pointStruct
-        if isinstance(pntStr, PointStructStr6):
-            Parameters = str(pntStr.x1Str) + var_separator + str(pntStr.x2Str) + var_separator
-            Parameters += str(pntStr.y1Str) + var_separator + str(pntStr.y2Str) + var_separator 
-            Parameters += str(pntStr.z1Str) + var_separator + str(pntStr.z2Str)
-            Point = PointStruct(pntStr.x2 - pntStr.x1, pntStr.y2 - pntStr.y1, pntStr.z2 - pntStr.z1)
-        else:
-            Parameters = str(pntStr.xStr) + var_separator + str(pntStr.yStr) + var_separator + str(pntStr.zStr)
-            Point = PointStruct(pntStr.x, pntStr.y, pntStr.z)
-        Dir = DirStruct(Point)
-    return Dir, Parameters
-
-# Returns list of variable values from salome notebook
-def ParseAxisStruct(Axis):
-    Parameters = 5*var_separator
-    if isinstance(Axis, AxisStructStr):
-        Parameters = str(Axis.xStr) + var_separator + str(Axis.yStr) + var_separator + str(Axis.zStr) + var_separator
-        Parameters += str(Axis.dxStr) + var_separator + str(Axis.dyStr) + var_separator + str(Axis.dzStr)
-        Axis = AxisStruct(Axis.x, Axis.y, Axis.z, Axis.dx, Axis.dy, Axis.dz)
-    return Axis, Parameters
-
-## Return list of variable values from salome notebook
-def ParseAngles(list):
+## Return list of variable values from salome notebook.
+#  The last argument, if is callable, is used to modify values got from notebook
+def ParseParameters(*args):
     Result = []
     Parameters = ""
-    for parameter in list:
-        if isinstance(parameter,str) and notebook.isVariable(parameter):
-            Result.append(DegreesToRadians(notebook.get(parameter)))
-            pass
-        else:
-            Result.append(parameter)
+    hasVariables = False
+    varModifFun=None
+    if args and callable( args[-1] ):
+        args, varModifFun = args[:-1], args[-1]
+    for parameter in args:
+
+        Parameters += str(parameter) + var_separator
+
+        if isinstance(parameter,str):
+            # check if there is an inexistent variable name
+            if not notebook.isVariable(parameter):
+                raise ValueError, "Variable with name '" + parameter + "' doesn't exist!!!"
+            parameter = notebook.get(parameter)
+            hasVariables = True
+            if varModifFun:
+                parameter = varModifFun(parameter)
+                pass
             pass
-        
-        Parameters = Parameters + str(parameter)
-        Parameters = Parameters + var_separator
+        Result.append(parameter)
+
         pass
-    Parameters = Parameters[:len(Parameters)-1]
-    return Result, Parameters
-    
+    Parameters = Parameters[:-1]
+    Result.append( Parameters )
+    Result.append( hasVariables )
+    return Result
+
+# Parse parameters converting variables to radians
+def ParseAngles(*args):
+    return ParseParameters( *( args + (DegreesToRadians, )))
+
+# Substitute PointStruct.__init__() to create SMESH.PointStruct using notebook variables.
+# Parameters are stored in PointStruct.parameters attribute
+def __initPointStruct(point,*args):
+    point.x, point.y, point.z, point.parameters,hasVars = ParseParameters(*args)
+    pass
+SMESH.PointStruct.__init__ = __initPointStruct
+
+# Substitute AxisStruct.__init__() to create SMESH.AxisStruct using notebook variables.
+# Parameters are stored in AxisStruct.parameters attribute
+def __initAxisStruct(ax,*args):
+    ax.x, ax.y, ax.z, ax.vx, ax.vy, ax.vz, ax.parameters,hasVars = ParseParameters(*args)
+    pass
+SMESH.AxisStruct.__init__ = __initAxisStruct
+
+
 def IsEqual(val1, val2, tol=PrecisionConfusion):
     if abs(val1 - val2) < tol:
         return True
@@ -355,13 +182,33 @@ NO_NAME = "NoName"
 
 ## Gets object name
 def GetName(obj):
-    ior  = salome.orb.object_to_string(obj)
-    sobj = salome.myStudy.FindObjectIOR(ior)
-    if sobj is None:
-        return NO_NAME
-    else:
-        attr = sobj.FindAttribute("AttributeName")[1]
-        return attr.Value()
+    if obj:
+        # object not null
+        if isinstance(obj, SALOMEDS._objref_SObject):
+            # study object
+            return obj.GetName()
+        ior  = salome.orb.object_to_string(obj)
+        if ior:
+            # CORBA object
+            studies = salome.myStudyManager.GetOpenStudies()
+            for sname in studies:
+                s = salome.myStudyManager.GetStudyByName(sname)
+                if not s: continue
+                sobj = s.FindObjectIOR(ior)
+                if not sobj: continue
+                return sobj.GetName()
+            if hasattr(obj, "GetName"):
+                # unknown CORBA object, having GetName() method
+                return obj.GetName()
+            else:
+                # unknown CORBA object, no GetName() method
+                return NO_NAME
+            pass
+        if hasattr(obj, "GetName"):
+            # unknown non-CORBA object, having GetName() method
+            return obj.GetName()
+        pass
+    raise RuntimeError, "Null or invalid object"
 
 ## Prints error message if a hypothesis was not assigned.
 def TreatHypoStatus(status, hypName, geomName, isAlgo):
@@ -377,13 +224,14 @@ def TreatHypoStatus(status, hypName, geomName, isAlgo):
     elif status == HYP_NOTCONFORM :
         reason = "a non-conform mesh would be built"
     elif status == HYP_ALREADY_EXIST :
+        if isAlgo: return # it does not influence anything
         reason = hypType + " of the same dimension is already assigned to this shape"
     elif status == HYP_BAD_DIM :
         reason = hypType + " mismatches the shape"
     elif status == HYP_CONCURENT :
         reason = "there are concurrent hypotheses on sub-shapes"
     elif status == HYP_BAD_SUBSHAPE :
-        reason = "the shape is neither the main one, nor its subshape, nor a valid group"
+        reason = "the shape is neither the main one, nor its sub-shape, nor a valid group"
     elif status == HYP_BAD_GEOMETRY:
         reason = "geometry mismatches the expectation of the algorithm"
     elif status == HYP_HIDDEN_ALGO:
@@ -396,18 +244,76 @@ def TreatHypoStatus(status, hypName, geomName, isAlgo):
         return
     hypName = '"' + hypName + '"'
     geomName= '"' + geomName+ '"'
-    if status < HYP_UNKNOWN_FATAL:
+    if status < HYP_UNKNOWN_FATAL and not geomName =='""':
         print hypName, "was assigned to",    geomName,"but", reason
-    else:
+    elif not geomName == '""':
         print hypName, "was not assigned to",geomName,":", reason
+    else:
+        print hypName, "was not assigned:", reason
         pass
 
+## Private method. Add geom (sub-shape of the main shape) into the study if not yet there
+def AssureGeomPublished(mesh, geom, name=''):
+    if not isinstance( geom, geompyDC.GEOM._objref_GEOM_Object ):
+        return
+    if not geom.IsSame( mesh.geom ) and \
+           not geom.GetStudyEntry() and \
+           mesh.smeshpyD.GetCurrentStudy():
+        ## set the study
+        studyID = mesh.smeshpyD.GetCurrentStudy()._get_StudyId()
+        if studyID != mesh.geompyD.myStudyId:
+            mesh.geompyD.init_geom( mesh.smeshpyD.GetCurrentStudy())
+        ## get a name
+        if not name and geom.GetShapeType() != geompyDC.GEOM.COMPOUND:
+            # for all groups SubShapeName() returns "Compound_-1"
+            name = mesh.geompyD.SubShapeName(geom, mesh.geom)
+        if not name:
+            name = "%s_%s"%(geom.GetShapeType(), id(geom)%10000)
+        ## publish
+        mesh.geompyD.addToStudyInFather( mesh.geom, geom, name )
+    return
+
+## Return the first vertex of a geomertical edge by ignoring orienation
+def FirstVertexOnCurve(edge):
+    from geompy import SubShapeAll, ShapeType, KindOfShape, PointCoordinates
+    vv = SubShapeAll( edge, ShapeType["VERTEX"])
+    if not vv:
+        raise TypeError, "Given object has no vertices"
+    if len( vv ) == 1: return vv[0]
+    info = KindOfShape(edge)
+    xyz = info[1:4] # coords of the first vertex
+    xyz1  = PointCoordinates( vv[0] )
+    xyz2  = PointCoordinates( vv[1] )
+    dist1, dist2 = 0,0
+    for i in range(3):
+        dist1 += abs( xyz[i] - xyz1[i] )
+        dist2 += abs( xyz[i] - xyz2[i] )
+    if dist1 < dist2:
+        return vv[0]
+    else:
+        return vv[1]
+
 # end of l1_auxiliary
 ## @}
 
 # All methods of this class are accessible directly from the smesh.py package.
 class smeshDC(SMESH._objref_SMESH_Gen):
 
+    ## Dump component to the Python script
+    #  This method overrides IDL function to allow default values for the parameters.
+    def DumpPython(self, theStudy, theIsPublished=True, theIsMultiFile=True):
+        return SMESH._objref_SMESH_Gen.DumpPython(self, theStudy, theIsPublished, theIsMultiFile)
+
+    ## Set mode of DumpPython(), \a historical or \a snapshot.
+    # In the \a historical mode, the Python Dump script includes all commands
+    # performed by SMESH engine. In the \a snapshot mode, commands
+    # relating to objects removed from the Study are excluded from the script
+    # as well as commands not influencing the current state of meshes
+    def SetDumpPythonHistorical(self, isHistorical):
+        if isHistorical: val = "true"
+        else:            val = "false"
+        SMESH._objref_SMESH_Gen.SetOption(self, "historical_python_dump", val)
+
     ## Sets the current study and Geometry component
     #  @ingroup l1_auxiliary
     def init_smesh(self,theStudy,geompyD):
@@ -420,7 +326,9 @@ class smeshDC(SMESH._objref_SMESH_Gen):
     #  @return an instance of Mesh class.
     #  @ingroup l2_construct
     def Mesh(self, obj=0, name=0):
-      return Mesh(self,self.geompyD,obj,name)
+        if isinstance(obj,str):
+            obj,name = name,obj
+        return Mesh(self,self.geompyD,obj,name)
 
     ## Returns a long value from enumeration
     #  Should be used for SMESH.FunctorType enumeration
@@ -428,6 +336,20 @@ class smeshDC(SMESH._objref_SMESH_Gen):
     def EnumToLong(self,theItem):
         return theItem._v
 
+    ## Returns a string representation of the color.
+    #  To be used with filters.
+    #  @param c color value (SALOMEDS.Color)
+    #  @ingroup l1_controls
+    def ColorToString(self,c):
+        val = ""
+        if isinstance(c, SALOMEDS.Color):
+            val = "%s;%s;%s" % (c.R, c.G, c.B)
+        elif isinstance(c, str):
+            val = c
+        else:
+            raise ValueError, "Color value should be of string or SALOMEDS.Color type"
+        return val
+
     ## Gets PointStruct from vertex
     #  @param theVertex a GEOM object(vertex)
     #  @return SMESH.PointStruct
@@ -493,7 +415,6 @@ class smeshDC(SMESH._objref_SMESH_Gen):
     #  @param name a new object name
     #  @ingroup l1_auxiliary
     def SetName(self, obj, name):
-        print "obj_name = ", name
         if isinstance( obj, Mesh ):
             obj = obj.GetMesh()
         elif isinstance( obj, Mesh_Algorithm ):
@@ -524,6 +445,11 @@ class smeshDC(SMESH._objref_SMESH_Gen):
         self.geompyD=geompyD
         self.SetGeomEngine(geompyD)
         SMESH._objref_SMESH_Gen.SetCurrentStudy(self,theStudy)
+        global notebook
+        if theStudy:
+            notebook = salome_notebook.NoteBook( theStudy )
+        else:
+            notebook = salome_notebook.NoteBook( salome_notebook.PseudoStudyForNoteBook() )
 
     ## Gets the current study
     #  @ingroup l1_auxiliary
@@ -550,6 +476,17 @@ class smeshDC(SMESH._objref_SMESH_Gen):
             aMeshes.append(aMesh)
         return aMeshes, aStatus
 
+    ## Creates a Mesh object(s) importing data from the given SAUV file
+    #  @return a list of Mesh class instances
+    #  @ingroup l2_impexp
+    def CreateMeshesFromSAUV( self,theFileName ):
+        aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromSAUV(self,theFileName)
+        aMeshes = []
+        for iMesh in range(len(aSmeshMeshes)) :
+            aMesh = Mesh(self, self.geompyD, aSmeshMeshes[iMesh])
+            aMeshes.append(aMesh)
+        return aMeshes, aStatus
+
     ## Creates a Mesh object importing data from the given STL file
     #  @return an instance of Mesh class
     #  @ingroup l2_impexp
@@ -558,6 +495,17 @@ class smeshDC(SMESH._objref_SMESH_Gen):
         aMesh = Mesh(self, self.geompyD, aSmeshMesh)
         return aMesh
 
+    ## Creates Mesh objects importing data from the given CGNS file
+    #  @return an instance of Mesh class
+    #  @ingroup l2_impexp
+    def CreateMeshesFromCGNS( self, theFileName ):
+        aSmeshMeshes, aStatus = SMESH._objref_SMESH_Gen.CreateMeshesFromCGNS(self,theFileName)
+        aMeshes = []
+        for iMesh in range(len(aSmeshMeshes)) :
+            aMesh = Mesh(self, self.geompyD, aSmeshMeshes[iMesh])
+            aMeshes.append(aMesh)
+        return aMeshes, aStatus
+
     ## Concatenate the given meshes into one mesh.
     #  @return an instance of Mesh class
     #  @param meshes the meshes to combine into one mesh
@@ -567,6 +515,12 @@ class smeshDC(SMESH._objref_SMESH_Gen):
     #  @param allGroups forces creation of groups of all elements
     def Concatenate( self, meshes, uniteIdenticalGroups,
                      mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
+        if not meshes: return None
+        for i,m in enumerate(meshes):
+            if isinstance(m, Mesh):
+                meshes[i] = m.GetMesh()
+        mergeTolerance,Parameters,hasVars = ParseParameters(mergeTolerance)
+        meshes[0].SetParameters(Parameters)
         if allGroups:
             aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
                 self,meshes,uniteIdenticalGroups,mergeNodesAndElements,mergeTolerance)
@@ -576,6 +530,20 @@ class smeshDC(SMESH._objref_SMESH_Gen):
         aMesh = Mesh(self, self.geompyD, aSmeshMesh)
         return aMesh
 
+    ## Create a mesh by copying a part of another mesh.
+    #  @param meshPart a part of mesh to copy, either a Mesh, a sub-mesh or a group;
+    #                  to copy nodes or elements not contained in any mesh object,
+    #                  pass result of Mesh.GetIDSource( list_of_ids, type ) as meshPart
+    #  @param meshName a name of the new mesh
+    #  @param toCopyGroups to create in the new mesh groups the copied elements belongs to
+    #  @param toKeepIDs to preserve IDs of the copied elements or not
+    #  @return an instance of Mesh class
+    def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
+        if (isinstance( meshPart, Mesh )):
+            meshPart = meshPart.GetMesh()
+        mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
+        return Mesh(self, self.geompyD, mesh)
+
     ## From SMESH_Gen interface
     #  @return the list of integer values
     #  @ingroup l1_auxiliary
@@ -597,26 +565,6 @@ class smeshDC(SMESH._objref_SMESH_Gen):
     def SetBoundaryBoxSegmentation(self, nbSegments):
         SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
 
-    ## Concatenate the given meshes into one mesh.
-    #  @return an instance of Mesh class
-    #  @param meshes the meshes to combine into one mesh
-    #  @param uniteIdenticalGroups if true, groups with same names are united, else they are renamed
-    #  @param mergeNodesAndElements if true, equal nodes and elements aremerged
-    #  @param mergeTolerance tolerance for merging nodes
-    #  @param allGroups forces creation of groups of all elements
-    def Concatenate( self, meshes, uniteIdenticalGroups,
-                     mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False):
-        mergeTolerance,Parameters = geompyDC.ParseParameters(mergeTolerance)
-        if allGroups:
-            aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups(
-                self,meshes,uniteIdenticalGroups,mergeNodesAndElements,mergeTolerance)
-        else:
-            aSmeshMesh = SMESH._objref_SMESH_Gen.Concatenate(
-                self,meshes,uniteIdenticalGroups,mergeNodesAndElements,mergeTolerance)
-        aSmeshMesh.SetParameters(Parameters)
-        aMesh = Mesh(self, self.geompyD, aSmeshMesh)
-        return aMesh
-
     # Filtering. Auxiliary functions:
     # ------------------------------
 
@@ -638,26 +586,35 @@ class smeshDC(SMESH._objref_SMESH_Gen):
                                 UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision)
 
     ## Creates a criterion by the given parameters
+    #  \n Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below)
     #  @param elementType the type of elements(NODE, EDGE, FACE, VOLUME)
     #  @param CritType the type of criterion (FT_Taper, FT_Area, FT_RangeOfIds, FT_LyingOnGeom etc.)
     #  @param Compare  belongs to {FT_LessThan, FT_MoreThan, FT_EqualTo}
-    #  @param Treshold the threshold value (range of ids as string, shape, numeric)
+    #  @param Threshold the threshold value (range of ids as string, shape, numeric)
     #  @param UnaryOp  FT_LogicalNOT or FT_Undefined
     #  @param BinaryOp a binary logical operation FT_LogicalAND, FT_LogicalOR or
     #                  FT_Undefined (must be for the last criterion of all criteria)
+    #  @param Tolerance the tolerance used by FT_BelongToGeom, FT_BelongToSurface,
+    #         FT_LyingOnGeom, FT_CoplanarFaces criteria
     #  @return SMESH.Filter.Criterion
+    #
+    #  <a href="../tui_filters_page.html#combining_filters">Example of Criteria usage</a>
     #  @ingroup l1_controls
     def GetCriterion(self,elementType,
                      CritType,
                      Compare = FT_EqualTo,
-                     Treshold="",
+                     Threshold="",
                      UnaryOp=FT_Undefined,
-                     BinaryOp=FT_Undefined):
+                     BinaryOp=FT_Undefined,
+                     Tolerance=1e-07):
+        if not CritType in SMESH.FunctorType._items:
+            raise TypeError, "CritType should be of SMESH.FunctorType"
         aCriterion = self.GetEmptyCriterion()
         aCriterion.TypeOfElement = elementType
         aCriterion.Type = self.EnumToLong(CritType)
+        aCriterion.Tolerance = Tolerance
 
-        aTreshold = Treshold
+        aThreshold = Threshold
 
         if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
             aCriterion.Compare = self.EnumToLong(Compare)
@@ -667,47 +624,89 @@ class smeshDC(SMESH._objref_SMESH_Gen):
             aCriterion.Compare = self.EnumToLong(FT_LessThan)
         elif Compare == ">":
             aCriterion.Compare = self.EnumToLong(FT_MoreThan)
-        else:
+        elif Compare != FT_Undefined:
             aCriterion.Compare = self.EnumToLong(FT_EqualTo)
-            aTreshold = Compare
+            aThreshold = Compare
 
         if CritType in [FT_BelongToGeom,     FT_BelongToPlane, FT_BelongToGenSurface,
                         FT_BelongToCylinder, FT_LyingOnGeom]:
-            # Checks the treshold
-            if isinstance(aTreshold, geompyDC.GEOM._objref_GEOM_Object):
-                aCriterion.ThresholdStr = GetName(aTreshold)
-                aCriterion.ThresholdID = salome.ObjectToID(aTreshold)
+            # Checks that Threshold is GEOM object
+            if isinstance(aThreshold, geompyDC.GEOM._objref_GEOM_Object):
+                aCriterion.ThresholdStr = GetName(aThreshold)
+                aCriterion.ThresholdID = aThreshold.GetStudyEntry()
+                if not aCriterion.ThresholdID:
+                    raise RuntimeError, "Threshold shape must be published"
             else:
-                print "Error: The treshold should be a shape."
+                print "Error: The Threshold should be a shape."
                 return None
+            if isinstance(UnaryOp,float):
+                aCriterion.Tolerance = UnaryOp
+                UnaryOp = FT_Undefined
+                pass
         elif CritType == FT_RangeOfIds:
-            # Checks the treshold
-            if isinstance(aTreshold, str):
-                aCriterion.ThresholdStr = aTreshold
+            # Checks that Threshold is string
+            if isinstance(aThreshold, str):
+                aCriterion.ThresholdStr = aThreshold
             else:
-                print "Error: The treshold should be a string."
+                print "Error: The Threshold should be a string."
+                return None
+        elif CritType == FT_CoplanarFaces:
+            # Checks the Threshold
+            if isinstance(aThreshold, int):
+                aCriterion.ThresholdID = str(aThreshold)
+            elif isinstance(aThreshold, str):
+                ID = int(aThreshold)
+                if ID < 1:
+                    raise ValueError, "Invalid ID of mesh face: '%s'"%aThreshold
+                aCriterion.ThresholdID = aThreshold
+            else:
+                raise ValueError,\
+                      "The Threshold should be an ID of mesh face and not '%s'"%aThreshold
+        elif CritType == FT_ElemGeomType:
+            # Checks the Threshold
+            try:
+                aCriterion.Threshold = self.EnumToLong(aThreshold)
+                assert( aThreshold in SMESH.GeometryType._items )
+            except:
+                if isinstance(aThreshold, int):
+                    aCriterion.Threshold = aThreshold
+                else:
+                    print "Error: The Threshold should be an integer or SMESH.GeometryType."
+                    return None
+                pass
+            pass
+        elif CritType == FT_GroupColor:
+            # Checks the Threshold
+            try:
+                aCriterion.ThresholdStr = self.ColorToString(aThreshold)
+            except:
+                print "Error: The threshold value should be of SALOMEDS.Color type"
                 return None
-        elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_BadOrientedVolume, FT_FreeNodes,
-                          FT_FreeFaces, FT_ElemGeomType, FT_GroupColor]:
-            # At this point the treshold is unnecessary
-            if aTreshold ==  FT_LogicalNOT:
+            pass
+        elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
+                          FT_LinearOrQuadratic, FT_BadOrientedVolume,
+                          FT_BareBorderFace, FT_BareBorderVolume,
+                          FT_OverConstrainedFace, FT_OverConstrainedVolume,
+                          FT_EqualNodes,FT_EqualEdges,FT_EqualFaces,FT_EqualVolumes ]:
+            # At this point the Threshold is unnecessary
+            if aThreshold ==  FT_LogicalNOT:
                 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
-            elif aTreshold in [FT_LogicalAND, FT_LogicalOR]:
-                aCriterion.BinaryOp = aTreshold
+            elif aThreshold in [FT_LogicalAND, FT_LogicalOR]:
+                aCriterion.BinaryOp = aThreshold
         else:
-            # Check treshold
+            # Check Threshold
             try:
-                aTreshold = float(aTreshold)
-                aCriterion.Threshold = aTreshold
+                aThreshold = float(aThreshold)
+                aCriterion.Threshold = aThreshold
             except:
-                print "Error: The treshold should be a number."
+                print "Error: The Threshold should be a number."
                 return None
 
-        if Treshold ==  FT_LogicalNOT or UnaryOp ==  FT_LogicalNOT:
+        if Threshold ==  FT_LogicalNOT or UnaryOp ==  FT_LogicalNOT:
             aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
 
-        if Treshold in [FT_LogicalAND, FT_LogicalOR]:
-            aCriterion.BinaryOp = self.EnumToLong(Treshold)
+        if Threshold in [FT_LogicalAND, FT_LogicalOR]:
+            aCriterion.BinaryOp = self.EnumToLong(Threshold)
 
         if UnaryOp in [FT_LogicalAND, FT_LogicalOR]:
             aCriterion.BinaryOp = self.EnumToLong(UnaryOp)
@@ -721,21 +720,40 @@ class smeshDC(SMESH._objref_SMESH_Gen):
     #  @param elementType the type of elements in the group
     #  @param CritType the type of criterion ( FT_Taper, FT_Area, FT_RangeOfIds, FT_LyingOnGeom etc. )
     #  @param Compare  belongs to {FT_LessThan, FT_MoreThan, FT_EqualTo}
-    #  @param Treshold the threshold value (range of id ids as string, shape, numeric)
+    #  @param Threshold the threshold value (range of id ids as string, shape, numeric)
     #  @param UnaryOp  FT_LogicalNOT or FT_Undefined
+    #  @param Tolerance the tolerance used by FT_BelongToGeom, FT_BelongToSurface,
+    #         FT_LyingOnGeom, FT_CoplanarFaces and FT_EqualNodes criteria
     #  @return SMESH_Filter
+    #
+    #  <a href="../tui_filters_page.html#tui_filters">Example of Filters usage</a>
     #  @ingroup l1_controls
     def GetFilter(self,elementType,
                   CritType=FT_Undefined,
                   Compare=FT_EqualTo,
-                  Treshold="",
-                  UnaryOp=FT_Undefined):
-        aCriterion = self.GetCriterion(elementType, CritType, Compare, Treshold, UnaryOp, FT_Undefined)
+                  Threshold="",
+                  UnaryOp=FT_Undefined,
+                  Tolerance=1e-07):
+        aCriterion = self.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
         aFilterMgr = self.CreateFilterManager()
         aFilter = aFilterMgr.CreateFilter()
         aCriteria = []
         aCriteria.append(aCriterion)
         aFilter.SetCriteria(aCriteria)
+        aFilterMgr.UnRegister()
+        return aFilter
+
+    ## Creates a filter from criteria
+    #  @param criteria a list of criteria
+    #  @return SMESH_Filter
+    #
+    #  <a href="../tui_filters_page.html#tui_filters">Example of Filters usage</a>
+    #  @ingroup l1_controls
+    def GetFilterFromCriteria(self,criteria):
+        aFilterMgr = self.CreateFilterManager()
+        aFilter = aFilterMgr.CreateFilter()
+        aFilter.SetCriteria(criteria)
+        aFilterMgr.UnRegister()
         return aFilter
 
     ## Creates a numerical functor by its type
@@ -760,6 +778,10 @@ class smeshDC(SMESH._objref_SMESH_Gen):
             return aFilterMgr.CreateArea()
         elif theCriterion == FT_Volume3D:
             return aFilterMgr.CreateVolume3D()
+        elif theCriterion == FT_MaxElementLength2D:
+            return aFilterMgr.CreateMaxElementLength2D()
+        elif theCriterion == FT_MaxElementLength3D:
+            return aFilterMgr.CreateMaxElementLength3D()
         elif theCriterion == FT_MultiConnection:
             return aFilterMgr.CreateMultiConnection()
         elif theCriterion == FT_MultiConnection2D:
@@ -769,14 +791,146 @@ class smeshDC(SMESH._objref_SMESH_Gen):
         elif theCriterion == FT_Length2D:
             return aFilterMgr.CreateLength2D()
         else:
-            print "Error: given parameter is not numerucal functor type."
+            print "Error: given parameter is not numerical functor type."
 
     ## Creates hypothesis
-    #  @param 
-    #  @param 
+    #  @param theHType mesh hypothesis type (string)
+    #  @param theLibName mesh plug-in library name
     #  @return created hypothesis instance
     def CreateHypothesis(self, theHType, theLibName="libStdMeshersEngine.so"):
-        return SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
+        hyp = SMESH._objref_SMESH_Gen.CreateHypothesis(self, theHType, theLibName )
+
+        if isinstance( hyp, SMESH._objref_SMESH_Algo ):
+            return hyp
+
+        # wrap hypothesis methods
+        #print "HYPOTHESIS", theHType
+        for meth_name in dir( hyp.__class__ ):
+            if not meth_name.startswith("Get") and \
+               not meth_name in dir ( SMESH._objref_SMESH_Hypothesis ):
+                method = getattr ( hyp.__class__, meth_name )
+                if callable(method):
+                    setattr( hyp, meth_name, hypMethodWrapper( hyp, method ))
+
+        return hyp
+
+    ## Gets the mesh statistic
+    #  @return dictionary "element type" - "count of elements"
+    #  @ingroup l1_meshinfo
+    def GetMeshInfo(self, obj):
+        if isinstance( obj, Mesh ):
+            obj = obj.GetMesh()
+        d = {}
+        if hasattr(obj, "GetMeshInfo"):
+            values = obj.GetMeshInfo()
+            for i in range(SMESH.Entity_Last._v):
+                if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
+            pass
+        return d
+
+    ## Get minimum distance between two objects
+    #
+    #  If @a src2 is None, and @a id2 = 0, distance from @a src1 / @a id1 to the origin is computed.
+    #  If @a src2 is None, and @a id2 != 0, it is assumed that both @a id1 and @a id2 belong to @a src1.
+    #
+    #  @param src1 first source object
+    #  @param src2 second source object
+    #  @param id1 node/element id from the first source
+    #  @param id2 node/element id from the second (or first) source
+    #  @param isElem1 @c True if @a id1 is element id, @c False if it is node id
+    #  @param isElem2 @c True if @a id2 is element id, @c False if it is node id
+    #  @return minimum distance value
+    #  @sa GetMinDistance()
+    #  @ingroup l1_measurements
+    def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
+        result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2)
+        if result is None:
+            result = 0.0
+        else:
+            result = result.value
+        return result
+
+    ## Get measure structure specifying minimum distance data between two objects
+    #
+    #  If @a src2 is None, and @a id2 = 0, distance from @a src1 / @a id1 to the origin is computed.
+    #  If @a src2 is None, and @a id2 != 0, it is assumed that both @a id1 and @a id2 belong to @a src1.
+    #
+    #  @param src1 first source object
+    #  @param src2 second source object
+    #  @param id1 node/element id from the first source
+    #  @param id2 node/element id from the second (or first) source
+    #  @param isElem1 @c True if @a id1 is element id, @c False if it is node id
+    #  @param isElem2 @c True if @a id2 is element id, @c False if it is node id
+    #  @return Measure structure or None if input data is invalid
+    #  @sa MinDistance()
+    #  @ingroup l1_measurements
+    def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False):
+        if isinstance(src1, Mesh): src1 = src1.mesh
+        if isinstance(src2, Mesh): src2 = src2.mesh
+        if src2 is None and id2 != 0: src2 = src1
+        if not hasattr(src1, "_narrow"): return None
+        src1 = src1._narrow(SMESH.SMESH_IDSource)
+        if not src1: return None
+        if id1 != 0:
+            m = src1.GetMesh()
+            e = m.GetMeshEditor()
+            if isElem1:
+                src1 = e.MakeIDSource([id1], SMESH.FACE)
+            else:
+                src1 = e.MakeIDSource([id1], SMESH.NODE)
+            pass
+        if hasattr(src2, "_narrow"):
+            src2 = src2._narrow(SMESH.SMESH_IDSource)
+            if src2 and id2 != 0:
+                m = src2.GetMesh()
+                e = m.GetMeshEditor()
+                if isElem2:
+                    src2 = e.MakeIDSource([id2], SMESH.FACE)
+                else:
+                    src2 = e.MakeIDSource([id2], SMESH.NODE)
+                pass
+            pass
+        aMeasurements = self.CreateMeasurements()
+        result = aMeasurements.MinDistance(src1, src2)
+        aMeasurements.UnRegister()
+        return result
+
+    ## Get bounding box of the specified object(s)
+    #  @param objects single source object or list of source objects
+    #  @return tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
+    #  @sa GetBoundingBox()
+    #  @ingroup l1_measurements
+    def BoundingBox(self, objects):
+        result = self.GetBoundingBox(objects)
+        if result is None:
+            result = (0.0,)*6
+        else:
+            result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
+        return result
+
+    ## Get measure structure specifying bounding box data of the specified object(s)
+    #  @param objects single source object or list of source objects
+    #  @return Measure structure
+    #  @sa BoundingBox()
+    #  @ingroup l1_measurements
+    def GetBoundingBox(self, objects):
+        if isinstance(objects, tuple):
+            objects = list(objects)
+        if not isinstance(objects, list):
+            objects = [objects]
+        srclist = []
+        for o in objects:
+            if isinstance(o, Mesh):
+                srclist.append(o.mesh)
+            elif hasattr(o, "_narrow"):
+                src = o._narrow(SMESH.SMESH_IDSource)
+                if src: srclist.append(src)
+                pass
+            pass
+        aMeasurements = self.CreateMeasurements()
+        result = aMeasurements.BoundingBox(srclist)
+        aMeasurements.UnRegister()
+        return result
 
 import omniORB
 #Registering the new proxy for SMESH_Gen
@@ -812,16 +966,27 @@ class Mesh:
         if obj is None:
             obj = 0
         if obj != 0:
+            objHasName = True
             if isinstance(obj, geompyDC.GEOM._objref_GEOM_Object):
                 self.geom = obj
+                # publish geom of mesh (issue 0021122)
+                if not self.geom.GetStudyEntry() and smeshpyD.GetCurrentStudy():
+                    objHasName = False
+                    studyID = smeshpyD.GetCurrentStudy()._get_StudyId()
+                    if studyID != geompyD.myStudyId:
+                        geompyD.init_geom( smeshpyD.GetCurrentStudy())
+                        pass
+                    geo_name = "%s_%s_for_meshing"%(self.geom.GetShapeType(), id(self.geom)%100)
+                    geompyD.addToStudy( self.geom, geo_name )
                 self.mesh = self.smeshpyD.CreateMesh(self.geom)
+
             elif isinstance(obj, SMESH._objref_SMESH_Mesh):
                 self.SetMesh(obj)
         else:
             self.mesh = self.smeshpyD.CreateEmptyMesh()
         if name != 0:
             self.smeshpyD.SetName(self.mesh, name)
-        elif obj != 0:
+        elif obj != 0 and objHasName:
             self.smeshpyD.SetName(self.mesh, GetName(obj))
 
         if not self.geom:
@@ -829,6 +994,12 @@ class Mesh:
 
         self.editor = self.mesh.GetMeshEditor()
 
+        # set self to algoCreator's
+        for attrName in dir(self):
+            attr = getattr( self, attrName )
+            if isinstance( attr, algoCreator ):
+                setattr( self, attrName, attr.copy( self ))
+
     ## Initializes the Mesh object from an instance of SMESH_Mesh interface
     #  @param theMesh a SMESH_Mesh object
     #  @ingroup l2_construct
@@ -857,12 +1028,13 @@ class Mesh:
 
     ## Gets the subMesh object associated to a \a theSubObject geometrical object.
     #  The subMesh object gives access to the IDs of nodes and elements.
-    #  @param theSubObject a geometrical object (shape)
-    #  @param theName a name for the submesh
+    #  @param geom a geometrical object (shape)
+    #  @param name a name for the submesh
     #  @return an object of type SMESH_SubMesh, representing a part of mesh, which lies on the given shape
     #  @ingroup l2_submeshes
-    def GetSubMesh(self, theSubObject, theName):
-        submesh = self.mesh.GetSubMesh(theSubObject, theName)
+    def GetSubMesh(self, geom, name):
+        AssureGeomPublished( self, geom, name )
+        submesh = self.mesh.GetSubMesh( geom, name )
         return submesh
 
     ## Returns the shape associated to the mesh
@@ -877,8 +1049,12 @@ class Mesh:
     def SetShape(self, geom):
         self.mesh = self.smeshpyD.CreateMesh(geom)
 
+    ## Loads mesh from the study after opening the study
+    def Load(self):
+        self.mesh.Load()
+
     ## Returns true if the hypotheses are defined well
-    #  @param theSubObject a subshape of a mesh shape
+    #  @param theSubObject a sub-shape of a mesh shape
     #  @return True or False
     #  @ingroup l2_construct
     def IsReadyToCompute(self, theSubObject):
@@ -886,7 +1062,7 @@ class Mesh:
 
     ## Returns errors of hypotheses definition.
     #  The list of errors is empty if everything is OK.
-    #  @param theSubObject a subshape of a mesh shape
+    #  @param theSubObject a sub-shape of a mesh shape
     #  @return a list of errors
     #  @ingroup l2_construct
     def GetAlgoState(self, theSubObject):
@@ -917,163 +1093,27 @@ class Mesh:
             return 0;
         pass
 
-    ## Creates a segment discretization 1D algorithm.
-    #  If the optional \a algo parameter is not set, this algorithm is REGULAR.
-    #  \n If the optional \a geom parameter is not set, this algorithm is global.
-    #  Otherwise, this algorithm defines a submesh based on \a geom subshape.
-    #  @param algo the type of the required algorithm. Possible values are:
-    #     - smesh.REGULAR,
-    #     - smesh.PYTHON for discretization via a python function,
-    #     - smesh.COMPOSITE for meshing a set of edges on one face side as a whole.
-    #  @param geom If defined is the subshape to be meshed
-    #  @return an instance of Mesh_Segment or Mesh_Segment_Python, or Mesh_CompositeSegment class
-    #  @ingroup l3_algos_basic
-    def Segment(self, algo=REGULAR, geom=0):
-        ## if Segment(geom) is called by mistake
-        if isinstance( algo, geompyDC.GEOM._objref_GEOM_Object):
-            algo, geom = geom, algo
-            if not algo: algo = REGULAR
-            pass
-        if algo == REGULAR:
-            return Mesh_Segment(self,  geom)
-        elif algo == PYTHON:
-            return Mesh_Segment_Python(self, geom)
-        elif algo == COMPOSITE:
-            return Mesh_CompositeSegment(self, geom)
-        else:
-            return Mesh_Segment(self, geom)
-
-    ## Enables creation of nodes and segments usable by 2D algoritms.
-    #  The added nodes and segments must be bound to edges and vertices by
-    #  SetNodeOnVertex(), SetNodeOnEdge() and SetMeshElementOnShape()
-    #  If the optional \a geom parameter is not set, this algorithm is global.
-    #  \n Otherwise, this algorithm defines a submesh based on \a geom subshape.
-    #  @param geom the subshape to be manually meshed
-    #  @return StdMeshers_UseExisting_1D algorithm that generates nothing
-    #  @ingroup l3_algos_basic
-    def UseExistingSegments(self, geom=0):
-        algo = Mesh_UseExisting(1,self,geom)
-        return algo.GetAlgorithm()
-
-    ## Enables creation of nodes and faces usable by 3D algoritms.
-    #  The added nodes and faces must be bound to geom faces by SetNodeOnFace()
-    #  and SetMeshElementOnShape()
-    #  If the optional \a geom parameter is not set, this algorithm is global.
-    #  \n Otherwise, this algorithm defines a submesh based on \a geom subshape.
-    #  @param geom the subshape to be manually meshed
-    #  @return StdMeshers_UseExisting_2D algorithm that generates nothing
-    #  @ingroup l3_algos_basic
-    def UseExistingFaces(self, geom=0):
-        algo = Mesh_UseExisting(2,self,geom)
-        return algo.GetAlgorithm()
-
-    ## Creates a triangle 2D algorithm for faces.
-    #  If the optional \a geom parameter is not set, this algorithm is global.
-    #  \n Otherwise, this algorithm defines a submesh based on \a geom subshape.
-    #  @param algo values are: smesh.MEFISTO || smesh.NETGEN_1D2D || smesh.NETGEN_2D || smesh.BLSURF
-    #  @param geom If defined, the subshape to be meshed (GEOM_Object)
-    #  @return an instance of Mesh_Triangle algorithm
-    #  @ingroup l3_algos_basic
-    def Triangle(self, algo=MEFISTO, geom=0):
-        ## if Triangle(geom) is called by mistake
-        if (isinstance(algo, geompyDC.GEOM._objref_GEOM_Object)):
-            geom = algo
-            algo = MEFISTO
-
-        return Mesh_Triangle(self, algo, geom)
-
-    ## Creates a quadrangle 2D algorithm for faces.
-    #  If the optional \a geom parameter is not set, this algorithm is global.
-    #  \n Otherwise, this algorithm defines a submesh based on \a geom subshape.
-    #  @param geom If defined, the subshape to be meshed (GEOM_Object)
-    #  @return an instance of Mesh_Quadrangle algorithm
-    #  @ingroup l3_algos_basic
-    def Quadrangle(self, geom=0):
-        return Mesh_Quadrangle(self,  geom)
-
-    ## Creates a tetrahedron 3D algorithm for solids.
-    #  The parameter \a algo permits to choose the algorithm: NETGEN or GHS3D
-    #  If the optional \a geom parameter is not set, this algorithm is global.
-    #  \n Otherwise, this algorithm defines a submesh based on \a geom subshape.
-    #  @param algo values are: smesh.NETGEN, smesh.GHS3D, smesh.GHS3DPRL, smesh.FULL_NETGEN
-    #  @param geom If defined, the subshape to be meshed (GEOM_Object)
-    #  @return an instance of Mesh_Tetrahedron algorithm
-    #  @ingroup l3_algos_basic
-    def Tetrahedron(self, algo=NETGEN, geom=0):
-        ## if Tetrahedron(geom) is called by mistake
-        if ( isinstance( algo, geompyDC.GEOM._objref_GEOM_Object)):
-            algo, geom = geom, algo
-            if not algo: algo = NETGEN
-            pass
-        return Mesh_Tetrahedron(self,  algo, geom)
-
-    ## Creates a hexahedron 3D algorithm for solids.
-    #  If the optional \a geom parameter is not set, this algorithm is global.
-    #  \n Otherwise, this algorithm defines a submesh based on \a geom subshape.
-    #  @param algo possible values are: smesh.Hexa, smesh.Hexotic
-    #  @param geom If defined, the subshape to be meshed (GEOM_Object)
-    #  @return an instance of Mesh_Hexahedron algorithm
-    #  @ingroup l3_algos_basic
-    def Hexahedron(self, algo=Hexa, geom=0):
-        ## if Hexahedron(geom, algo) or Hexahedron(geom) is called by mistake
-        if ( isinstance(algo, geompyDC.GEOM._objref_GEOM_Object) ):
-            if   geom in [Hexa, Hexotic]: algo, geom = geom, algo
-            elif geom == 0:               algo, geom = Hexa, algo
-        return Mesh_Hexahedron(self, algo, geom)
-
-    ## Deprecated, used only for compatibility!
-    #  @return an instance of Mesh_Netgen algorithm
-    #  @ingroup l3_algos_basic
-    def Netgen(self, is3D, geom=0):
-        return Mesh_Netgen(self,  is3D, geom)
-
-    ## Creates a projection 1D algorithm for edges.
-    #  If the optional \a geom parameter is not set, this algorithm is global.
-    #  Otherwise, this algorithm defines a submesh based on \a geom subshape.
-    #  @param geom If defined, the subshape to be meshed
-    #  @return an instance of Mesh_Projection1D algorithm
-    #  @ingroup l3_algos_proj
-    def Projection1D(self, geom=0):
-        return Mesh_Projection1D(self,  geom)
-
-    ## Creates a projection 2D algorithm for faces.
-    #  If the optional \a geom parameter is not set, this algorithm is global.
-    #  Otherwise, this algorithm defines a submesh based on \a geom subshape.
-    #  @param geom If defined, the subshape to be meshed
-    #  @return an instance of Mesh_Projection2D algorithm
-    #  @ingroup l3_algos_proj
-    def Projection2D(self, geom=0):
-        return Mesh_Projection2D(self,  geom)
-
-    ## Creates a projection 3D algorithm for solids.
-    #  If the optional \a geom parameter is not set, this algorithm is global.
-    #  Otherwise, this algorithm defines a submesh based on \a geom subshape.
-    #  @param geom If defined, the subshape to be meshed
-    #  @return an instance of Mesh_Projection3D algorithm
-    #  @ingroup l3_algos_proj
-    def Projection3D(self, geom=0):
-        return Mesh_Projection3D(self,  geom)
-
-    ## Creates a 3D extrusion (Prism 3D) or RadialPrism 3D algorithm for solids.
-    #  If the optional \a geom parameter is not set, this algorithm is global.
-    #  Otherwise, this algorithm defines a submesh based on \a geom subshape.
-    #  @param geom If defined, the subshape to be meshed
-    #  @return an instance of Mesh_Prism3D or Mesh_RadialPrism3D algorithm
-    #  @ingroup l3_algos_radialp l3_algos_3dextr
-    def Prism(self, geom=0):
-        shape = geom
-        if shape==0:
-            shape = self.geom
-        nbSolids = len( self.geompyD.SubShapeAll( shape, geompyDC.ShapeType["SOLID"] ))
-        nbShells = len( self.geompyD.SubShapeAll( shape, geompyDC.ShapeType["SHELL"] ))
-        if nbSolids == 0 or nbSolids == nbShells:
-            return Mesh_Prism3D(self,  geom)
-        return Mesh_RadialPrism3D(self,  geom)
+    ## Evaluates size of prospective mesh on a shape
+    #  @return a list where i-th element is a number of elements of i-th SMESH.EntityType
+    #  To know predicted number of e.g. edges, inquire it this way
+    #  Evaluate()[ EnumToLong( Entity_Edge )]
+    def Evaluate(self, geom=0):
+        if geom == 0 or not isinstance(geom, geompyDC.GEOM._objref_GEOM_Object):
+            if self.geom == 0:
+                geom = self.mesh.GetShapeToMesh()
+            else:
+                geom = self.geom
+        return self.smeshpyD.Evaluate(self.mesh, geom)
+
 
     ## Computes the mesh and returns the status of the computation
+    #  @param geom geomtrical shape on which mesh data should be computed
+    #  @param discardModifs if True and the mesh has been edited since
+    #         a last total re-compute and that may prevent successful partial re-compute,
+    #         then the mesh is cleaned before Compute()
     #  @return True or False
     #  @ingroup l2_construct
-    def Compute(self, geom=0):
+    def Compute(self, geom=0, discardModifs=False):
         if geom == 0 or not isinstance(geom, geompyDC.GEOM._objref_GEOM_Object):
             if self.geom == 0:
                 geom = self.mesh.GetShapeToMesh()
@@ -1081,6 +1121,8 @@ class Mesh:
                 geom = self.geom
         ok = False
         try:
+            if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
+                self.mesh.Clear()
             ok = self.smeshpyD.Compute(self.mesh, geom)
         except SALOME.SALOME_Exception, ex:
             print "Mesh computation failed, exception caught:"
@@ -1090,8 +1132,64 @@ class Mesh:
             print "Mesh computation failed, exception caught:"
             traceback.print_exc()
         if True:#not ok:
-            errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
             allReasons = ""
+
+            # Treat compute errors
+            computeErrors = self.smeshpyD.GetComputeErrors( self.mesh, geom )
+            for err in computeErrors:
+                shapeText = ""
+                if self.mesh.HasShapeToMesh():
+                    try:
+                        mainIOR  = salome.orb.object_to_string(geom)
+                        for sname in salome.myStudyManager.GetOpenStudies():
+                            s = salome.myStudyManager.GetStudyByName(sname)
+                            if not s: continue
+                            mainSO = s.FindObjectIOR(mainIOR)
+                            if not mainSO: continue
+                            if err.subShapeID == 1:
+                                shapeText = ' on "%s"' % mainSO.GetName()
+                            subIt = s.NewChildIterator(mainSO)
+                            while subIt.More():
+                                subSO = subIt.Value()
+                                subIt.Next()
+                                obj = subSO.GetObject()
+                                if not obj: continue
+                                go = obj._narrow( geompyDC.GEOM._objref_GEOM_Object )
+                                if not go: continue
+                                ids = go.GetSubShapeIndices()
+                                if len(ids) == 1 and ids[0] == err.subShapeID:
+                                    shapeText = ' on "%s"' % subSO.GetName()
+                                    break
+                        if not shapeText:
+                            shape = self.geompyD.GetSubShape( geom, [err.subShapeID])
+                            if shape:
+                                shapeText = " on %s #%s" % (shape.GetShapeType(), err.subShapeID)
+                            else:
+                                shapeText = " on subshape #%s" % (err.subShapeID)
+                    except:
+                        shapeText = " on subshape #%s" % (err.subShapeID)
+                errText = ""
+                stdErrors = ["OK",                 #COMPERR_OK
+                             "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
+                             "std::exception",     #COMPERR_STD_EXCEPTION
+                             "OCC exception",      #COMPERR_OCC_EXCEPTION
+                             "SALOME exception",   #COMPERR_SLM_EXCEPTION
+                             "Unknown exception",  #COMPERR_EXCEPTION
+                             "Memory allocation problem", #COMPERR_MEMORY_PB
+                             "Algorithm failed",   #COMPERR_ALGO_FAILED
+                             "Unexpected geometry"]#COMPERR_BAD_SHAPE
+                if err.code > 0:
+                    if err.code < len(stdErrors): errText = stdErrors[err.code]
+                else:
+                    errText = "code %s" % -err.code
+                if errText: errText += ". "
+                errText += err.comment
+                if allReasons != "":allReasons += "\n"
+                allReasons += '-  "%s" failed%s. Error: %s' %(err.algoName, shapeText, errText)
+                pass
+
+            # Treat hyp errors
+            errors = self.smeshpyD.GetAlgoState( self.mesh, geom )
             for err in errors:
                 if err.isGlobalAlgo:
                     glob = "global"
@@ -1117,34 +1215,45 @@ class Mesh:
                     reason = "For unknown reason."+\
                              " Revise Mesh.Compute() implementation in smeshDC.py!"
                     pass
-                if allReasons != "":
-                    allReasons += "\n"
-                    pass
-                allReasons += reason
+                if allReasons != "":allReasons += "\n"
+                allReasons += "-  " + reason
                 pass
-            if allReasons != "":
-                print '"' + GetName(self.mesh) + '"',"has not been computed:"
+            if not ok or allReasons != "":
+                msg = '"' + GetName(self.mesh) + '"'
+                if ok: msg += " has been computed with warnings"
+                else:  msg += " has not been computed"
+                if allReasons != "": msg += ":"
+                else:                msg += "."
+                print msg
                 print allReasons
-                ok = False
-            elif not ok:
-                print '"' + GetName(self.mesh) + '"',"has not been computed."
-                pass
             pass
-        if salome.sg.hasDesktop():
+        if salome.sg.hasDesktop() and self.mesh.GetStudyId() >= 0:
             smeshgui = salome.ImportComponentGUI("SMESH")
-            smeshgui.Init(salome.myStudyId)
+            smeshgui.Init(self.mesh.GetStudyId())
             smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), ok, (self.NbNodes()==0) )
             salome.sg.updateObjBrowser(1)
             pass
         return ok
 
+    ## Return submesh objects list in meshing order
+    #  @return list of list of submesh objects
+    #  @ingroup l2_construct
+    def GetMeshOrder(self):
+        return self.mesh.GetMeshOrder()
+
+    ## Return submesh objects list in meshing order
+    #  @return list of list of submesh objects
+    #  @ingroup l2_construct
+    def SetMeshOrder(self, submeshes):
+        return self.mesh.SetMeshOrder(submeshes)
+
     ## Removes all nodes and elements
     #  @ingroup l2_construct
     def Clear(self):
         self.mesh.Clear()
         if salome.sg.hasDesktop():
             smeshgui = salome.ImportComponentGUI("SMESH")
-            smeshgui.Init(salome.myStudyId)
+            smeshgui.Init(self.mesh.GetStudyId())
             smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), False, True )
             salome.sg.updateObjBrowser(1)
 
@@ -1154,12 +1263,12 @@ class Mesh:
         self.mesh.ClearSubMesh(geomId)
         if salome.sg.hasDesktop():
             smeshgui = salome.ImportComponentGUI("SMESH")
-            smeshgui.Init(salome.myStudyId)
+            smeshgui.Init(self.mesh.GetStudyId())
             smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), False, True )
             salome.sg.updateObjBrowser(1)
 
     ## Computes a tetrahedral mesh using AutomaticLength + MEFISTO + NETGEN
-    #  @param fineness [0,-1] defines mesh fineness
+    #  @param fineness [0.0,1.0] defines mesh fineness
     #  @return True or False
     #  @ingroup l3_algos_basic
     def AutomaticTetrahedralization(self, fineness=0):
@@ -1171,12 +1280,13 @@ class Mesh:
             self.Triangle().LengthFromEdges()
             pass
         if dim > 2 :
+            from NETGENPluginDC import NETGEN
             self.Tetrahedron(NETGEN)
             pass
         return self.Compute()
 
     ## Computes an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron
-    #  @param fineness [0,-1] defines mesh fineness
+    #  @param fineness [0.0, 1.0] defines mesh fineness
     #  @return True or False
     #  @ingroup l3_algos_basic
     def AutomaticHexahedralization(self, fineness=0):
@@ -1206,14 +1316,36 @@ class Mesh:
             if not geom:
                 geom = self.mesh.GetShapeToMesh()
             pass
+        AssureGeomPublished( self, geom, "shape for %s" % hyp.GetName())
         status = self.mesh.AddHypothesis(geom, hyp)
         isAlgo = hyp._narrow( SMESH_Algo )
-        TreatHypoStatus( status, GetName( hyp ), GetName( geom ), isAlgo )
+        hyp_name = GetName( hyp )
+        geom_name = ""
+        if geom:
+            geom_name = GetName( geom )
+        TreatHypoStatus( status, hyp_name, geom_name, isAlgo )
         return status
 
+    ## Return True if an algorithm of hypothesis is assigned to a given shape
+    #  @param hyp a hypothesis to check
+    #  @param geom a subhape of mesh geometry
+    #  @return True of False
+    #  @ingroup l2_hypotheses
+    def IsUsedHypothesis(self, hyp, geom):
+        if not hyp or not geom:
+            return False
+        if isinstance( hyp, Mesh_Algorithm ):
+            hyp = hyp.GetAlgorithm()
+            pass
+        hyps = self.GetHypothesisList(geom)
+        for h in hyps:
+            if h.GetId() == hyp.GetId():
+                return True
+        return False
+
     ## Unassigns a hypothesis
     #  @param hyp a hypothesis to unassign
-    #  @param geom a subshape of mesh geometry
+    #  @param geom a sub-shape of mesh geometry
     #  @return SMESH.Hypothesis_Status
     #  @ingroup l2_hypotheses
     def RemoveHypothesis(self, hyp, geom=0):
@@ -1227,7 +1359,7 @@ class Mesh:
         return status
 
     ## Gets the list of hypotheses added on a geometry
-    #  @param geom a subshape of mesh geometry
+    #  @param geom a sub-shape of mesh geometry
     #  @return the sequence of SMESH_Hypothesis
     #  @ingroup l2_hypotheses
     def GetHypothesisList(self, geom):
@@ -1242,54 +1374,95 @@ class Mesh:
             pass
         pass
 
-    ## Creates a mesh group based on the geometric object \a grp
-    #  and gives a \a name, \n if this parameter is not defined
-    #  the name is the same as the geometric group name \n
-    #  Note: Works like GroupOnGeom().
-    #  @param grp  a geometric group, a vertex, an edge, a face or a solid
-    #  @param name the name of the mesh group
-    #  @return SMESH_GroupOnGeom
-    #  @ingroup l2_grps_create
-    def Group(self, grp, name=""):
-        return self.GroupOnGeom(grp, name)
-
-    ## Deprecated, used only for compatibility! Please, use ExportMED() method instead.
-    #  Exports the mesh in a file in MED format and chooses the \a version of MED format
-    #  @param f the file name
-    #  @param version values are SMESH.MED_V2_1, SMESH.MED_V2_2
+   ## Exports the mesh in a file in MED format and chooses the \a version of MED format
+    ## allowing to overwrite the file if it exists or add the exported data to its contents
+    #  @param f is the file name
+    #  @param auto_groups boolean parameter for creating/not creating
+    #  the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
+    #  the typical use is auto_groups=false.
+    #  @param version MED format version(MED_V2_1 or MED_V2_2)
+    #  @param overwrite boolean parameter for overwriting/not overwriting the file
+    #  @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh
     #  @ingroup l2_impexp
-    def ExportToMED(self, f, version, opt=0):
-        self.mesh.ExportToMED(f, opt, version)
+    def ExportMED(self, f, auto_groups=0, version=MED_V2_2, overwrite=1, meshPart=None):
+        if meshPart:
+            if isinstance( meshPart, list ):
+                meshPart = self.GetIDSource( meshPart, SMESH.ALL )
+            self.mesh.ExportPartToMED( meshPart, f, auto_groups, version, overwrite )
+        else:
+            self.mesh.ExportToMEDX(f, auto_groups, version, overwrite)
 
-    ## Exports the mesh in a file in MED format
+    ## Exports the mesh in a file in SAUV format
     #  @param f is the file name
     #  @param auto_groups boolean parameter for creating/not creating
     #  the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
     #  the typical use is auto_groups=false.
-    #  @param version MED format version(MED_V2_1 or MED_V2_2)
     #  @ingroup l2_impexp
-    def ExportMED(self, f, auto_groups=0, version=MED_V2_2):
-        self.mesh.ExportToMED(f, auto_groups, version)
+    def ExportSAUV(self, f, auto_groups=0):
+        self.mesh.ExportSAUV(f, auto_groups)
 
     ## Exports the mesh in a file in DAT format
     #  @param f the file name
+    #  @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh
     #  @ingroup l2_impexp
-    def ExportDAT(self, f):
-        self.mesh.ExportDAT(f)
+    def ExportDAT(self, f, meshPart=None):
+        if meshPart:
+            if isinstance( meshPart, list ):
+                meshPart = self.GetIDSource( meshPart, SMESH.ALL )
+            self.mesh.ExportPartToDAT( meshPart, f )
+        else:
+            self.mesh.ExportDAT(f)
 
     ## Exports the mesh in a file in UNV format
     #  @param f the file name
+    #  @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh
     #  @ingroup l2_impexp
-    def ExportUNV(self, f):
-        self.mesh.ExportUNV(f)
+    def ExportUNV(self, f, meshPart=None):
+        if meshPart:
+            if isinstance( meshPart, list ):
+                meshPart = self.GetIDSource( meshPart, SMESH.ALL )
+            self.mesh.ExportPartToUNV( meshPart, f )
+        else:
+            self.mesh.ExportUNV(f)
 
     ## Export the mesh in a file in STL format
     #  @param f the file name
     #  @param ascii defines the file encoding
+    #  @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh
     #  @ingroup l2_impexp
-    def ExportSTL(self, f, ascii=1):
-        self.mesh.ExportSTL(f, ascii)
+    def ExportSTL(self, f, ascii=1, meshPart=None):
+        if meshPart:
+            if isinstance( meshPart, list ):
+                meshPart = self.GetIDSource( meshPart, SMESH.ALL )
+            self.mesh.ExportPartToSTL( meshPart, f, ascii )
+        else:
+            self.mesh.ExportSTL(f, ascii)
 
+    ## Exports the mesh in a file in CGNS format
+    #  @param f is the file name
+    #  @param overwrite boolean parameter for overwriting/not overwriting the file
+    #  @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh
+    #  @ingroup l2_impexp
+    def ExportCGNS(self, f, overwrite=1, meshPart=None):
+        if isinstance( meshPart, list ):
+            meshPart = self.GetIDSource( meshPart, SMESH.ALL )
+        if isinstance( meshPart, Mesh ):
+            meshPart = meshPart.mesh
+        elif not meshPart:
+            meshPart = self.mesh
+        self.mesh.ExportCGNS(meshPart, f, overwrite)
+
+    ## Deprecated, used only for compatibility! Please, use ExportToMEDX() method instead.
+    #  Exports the mesh in a file in MED format and chooses the \a version of MED format
+    ## allowing to overwrite the file if it exists or add the exported data to its contents
+    #  @param f the file name
+    #  @param version values are SMESH.MED_V2_1, SMESH.MED_V2_2
+    #  @param opt boolean parameter for creating/not creating
+    #         the groups Group_On_All_Nodes, Group_On_All_Faces, ...
+    #  @param overwrite boolean parameter for overwriting/not overwriting the file
+    #  @ingroup l2_impexp
+    def ExportToMED(self, f, version, opt=0, overwrite=1):
+        self.mesh.ExportToMEDX(f, opt, version, overwrite)
 
     # Operations with groups:
     # ----------------------
@@ -1302,6 +1475,17 @@ class Mesh:
     def CreateEmptyGroup(self, elementType, name):
         return self.mesh.CreateGroup(elementType, name)
 
+    ## Creates a mesh group based on the geometric object \a grp
+    #  and gives a \a name, \n if this parameter is not defined
+    #  the name is the same as the geometric group name \n
+    #  Note: Works like GroupOnGeom().
+    #  @param grp  a geometric group, a vertex, an edge, a face or a solid
+    #  @param name the name of the mesh group
+    #  @return SMESH_GroupOnGeom
+    #  @ingroup l2_grps_create
+    def Group(self, grp, name=""):
+        return self.GroupOnGeom(grp, name)
+
     ## Creates a mesh group based on the geometrical object \a grp
     #  and gives a \a name, \n if this parameter is not defined
     #  the name is the same as the geometrical group name
@@ -1312,40 +1496,44 @@ class Mesh:
     #  @return SMESH_GroupOnGeom
     #  @ingroup l2_grps_create
     def GroupOnGeom(self, grp, name="", typ=None):
+        AssureGeomPublished( self, grp, name )
         if name == "":
             name = grp.GetName()
-
-        if typ == None:
-            tgeo = str(grp.GetShapeType())
-            if tgeo == "VERTEX":
-                typ = NODE
-            elif tgeo == "EDGE":
-                typ = EDGE
-            elif tgeo == "FACE":
-                typ = FACE
-            elif tgeo == "SOLID":
-                typ = VOLUME
-            elif tgeo == "SHELL":
-                typ = VOLUME
-            elif tgeo == "COMPOUND":
-                if len( self.geompyD.GetObjectIDs( grp )) == 0:
-                    print "Mesh.Group: empty geometric group", GetName( grp )
-                    return 0
-                tgeo = self.geompyD.GetType(grp)
-                if tgeo == geompyDC.ShapeType["VERTEX"]:
-                    typ = NODE
-                elif tgeo == geompyDC.ShapeType["EDGE"]:
-                    typ = EDGE
-                elif tgeo == geompyDC.ShapeType["FACE"]:
-                    typ = FACE
-                elif tgeo == geompyDC.ShapeType["SOLID"]:
-                    typ = VOLUME
-
-        if typ == None:
-            print "Mesh.Group: bad first argument: expected a group, a vertex, an edge, a face or a solid"
-            return 0
+        if not typ:
+            typ = self._groupTypeFromShape( grp )
+        return self.mesh.CreateGroupFromGEOM(typ, name, grp)
+
+    ## Pivate method to get a type of group on geometry
+    def _groupTypeFromShape( self, shape ):
+        tgeo = str(shape.GetShapeType())
+        if tgeo == "VERTEX":
+            typ = NODE
+        elif tgeo == "EDGE":
+            typ = EDGE
+        elif tgeo == "FACE" or tgeo == "SHELL":
+            typ = FACE
+        elif tgeo == "SOLID" or tgeo == "COMPSOLID":
+            typ = VOLUME
+        elif tgeo == "COMPOUND":
+            sub = self.geompyD.SubShapeAll( shape, geompyDC.ShapeType["SHAPE"])
+            if not sub:
+                raise ValueError,"_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape)
+            return self._groupTypeFromShape( sub[0] )
         else:
-            return self.mesh.CreateGroupFromGEOM(typ, name, grp)
+            raise ValueError, \
+                  "_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape)
+        return typ
+
+    ## Creates a mesh group with given \a name based on the \a filter which
+    ## is a special type of group dynamically updating it's contents during
+    ## mesh modification
+    #  @param typ  the type of elements in the group
+    #  @param name the name of the mesh group
+    #  @param filter the filter defining group contents
+    #  @return SMESH_GroupOnFilter
+    #  @ingroup l2_grps_create
+    def GroupOnFilter(self, typ, name, filter):
+        return self.mesh.CreateGroupFromFilter(typ, name, filter)
 
     ## Creates a mesh group by the given ids of elements
     #  @param groupName the name of the mesh group
@@ -1363,8 +1551,10 @@ class Mesh:
     #  @param elementType the type of elements in the group
     #  @param CritType the type of criterion( FT_Taper, FT_Area, FT_RangeOfIds, FT_LyingOnGeom etc. )
     #  @param Compare belongs to {FT_LessThan, FT_MoreThan, FT_EqualTo}
-    #  @param Treshold the threshold value (range of id ids as string, shape, numeric)
+    #  @param Threshold the threshold value (range of id ids as string, shape, numeric)
     #  @param UnaryOp FT_LogicalNOT or FT_Undefined
+    #  @param Tolerance the tolerance used by FT_BelongToGeom, FT_BelongToSurface,
+    #         FT_LyingOnGeom, FT_CoplanarFaces criteria
     #  @return SMESH_Group
     #  @ingroup l2_grps_create
     def MakeGroup(self,
@@ -1372,9 +1562,10 @@ class Mesh:
                   elementType,
                   CritType=FT_Undefined,
                   Compare=FT_EqualTo,
-                  Treshold="",
-                  UnaryOp=FT_Undefined):
-        aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Treshold, UnaryOp, FT_Undefined)
+                  Threshold="",
+                  UnaryOp=FT_Undefined,
+                  Tolerance=1e-07):
+        aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Threshold, UnaryOp, FT_Undefined,Tolerance)
         group = self.MakeGroupByCriterion(groupName, aCriterion)
         return group
 
@@ -1390,6 +1581,7 @@ class Mesh:
         aCriteria.append(Criterion)
         aFilter.SetCriteria(aCriteria)
         group = self.MakeGroupByFilter(groupName, aFilter)
+        aFilterMgr.UnRegister()
         return group
 
     ## Creates a mesh group by the given criteria (list of criteria)
@@ -1402,6 +1594,7 @@ class Mesh:
         aFilter = aFilterMgr.CreateFilter()
         aFilter.SetCriteria(theCriteria)
         group = self.MakeGroupByFilter(groupName, aFilter)
+        aFilterMgr.UnRegister()
         return group
 
     ## Creates a mesh group by the given filter
@@ -1410,29 +1603,11 @@ class Mesh:
     #  @return SMESH_Group
     #  @ingroup l2_grps_create
     def MakeGroupByFilter(self, groupName, theFilter):
-        anIds = theFilter.GetElementsId(self.mesh)
-        anElemType = theFilter.GetElementType()
-        group = self.MakeGroupByIds(groupName, anElemType, anIds)
+        group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName)
+        theFilter.SetMesh( self.mesh )
+        group.AddFrom( theFilter )
         return group
 
-    ## Passes mesh elements through the given filter and return IDs of fitting elements
-    #  @param theFilter SMESH_Filter
-    #  @return a list of ids
-    #  @ingroup l1_controls
-    def GetIdsFromFilter(self, theFilter):
-        return theFilter.GetElementsId(self.mesh)
-
-    ## Verifies whether a 2D mesh element has free edges (edges connected to one face only)\n
-    #  Returns a list of special structures (borders).
-    #  @return a list of SMESH.FreeEdges.Border structure: edge id and ids of two its nodes.
-    #  @ingroup l1_controls
-    def GetFreeBorders(self):
-        aFilterMgr = self.smeshpyD.CreateFilterManager()
-        aPredicate = aFilterMgr.CreateFreeEdges()
-        aPredicate.SetMesh(self.mesh)
-        aBorders = aPredicate.GetBorders()
-        return aBorders
-
     ## Removes a group
     #  @ingroup l2_grps_delete
     def RemoveGroup(self, group):
@@ -1472,15 +1647,15 @@ class Mesh:
     #  @ingroup l2_grps_operon
     def UnionGroups(self, group1, group2, name):
         return self.mesh.UnionGroups(group1, group2, name)
-        
+
     ## Produces a union list of groups
-    #  New group is created. All mesh elements that are present in 
+    #  New group is created. All mesh elements that are present in
     #  initial groups are added to the new one
     #  @return an instance of SMESH_Group
     #  @ingroup l2_grps_operon
     def UnionListOfGroups(self, groups, name):
       return self.mesh.UnionListOfGroups(groups, name)
-      
+
     ## Prodices an intersection of two groups
     #  A new group is created. All mesh elements that are common
     #  for the two initial groups are added to the new one.
@@ -1488,9 +1663,9 @@ class Mesh:
     #  @ingroup l2_grps_operon
     def IntersectGroups(self, group1, group2, name):
         return self.mesh.IntersectGroups(group1, group2, name)
-        
+
     ## Produces an intersection of groups
-    #  New group is created. All mesh elements that are present in all 
+    #  New group is created. All mesh elements that are present in all
     #  initial groups simultaneously are added to the new one
     #  @return an instance of SMESH_Group
     #  @ingroup l2_grps_operon
@@ -1504,19 +1679,19 @@ class Mesh:
     #  @ingroup l2_grps_operon
     def CutGroups(self, main_group, tool_group, name):
         return self.mesh.CutGroups(main_group, tool_group, name)
-        
+
     ## Produces a cut of groups
-    #  A new group is created. All mesh elements that are present in main groups 
+    #  A new group is created. All mesh elements that are present in main groups
     #  but do not present in tool groups are added to the new one
     #  @return an instance of SMESH_Group
     #  @ingroup l2_grps_operon
     def CutListOfGroups(self, main_groups, tool_groups, name):
       return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
-      
-    ## Produces a group of elements with specified element type using list of existing groups
-    #  A new group is created. System 
-    #  1) extract all nodes on which groups elements are built
-    #  2) combine all elements of specified dimension laying on these nodes
+
+    ## Produces a group of elements of specified type using list of existing groups
+    #  A new group is created. System
+    #  1) extracts all nodes on which groups elements are built
+    #  2) combines all elements of specified dimension laying on these nodes
     #  @return an instance of SMESH_Group
     #  @ingroup l2_grps_operon
     def CreateDimGroup(self, groups, elem_type, name):
@@ -1586,6 +1761,13 @@ class Mesh:
     def GetMeshEditor(self):
         return self.mesh.GetMeshEditor()
 
+    ## Wrap a list of IDs of elements or nodes into SMESH_IDSource which
+    #  can be passed as argument to a method accepting mesh, group or sub-mesh
+    #  @return an instance of SMESH_IDSource
+    #  @ingroup l1_auxiliary
+    def GetIDSource(self, ids, elemType):
+        return self.GetMeshEditor().MakeIDSource(ids, elemType)
+
     ## Gets MED Mesh
     #  @return an instance of SALOME_MED::MESH
     #  @ingroup l1_auxiliary
@@ -1596,6 +1778,13 @@ class Mesh:
     # Get informations about mesh contents:
     # ------------------------------------
 
+    ## Gets the mesh stattistic
+    #  @return dictionary type element - count of elements
+    #  @ingroup l1_meshinfo
+    def GetMeshInfo(self, obj = None):
+        if not obj: obj = self.mesh
+        return self.smeshpyD.GetMeshInfo(obj)
+
     ## Returns the number of nodes in the mesh
     #  @return an integer value
     #  @ingroup l1_meshinfo
@@ -1608,6 +1797,18 @@ class Mesh:
     def NbElements(self):
         return self.mesh.NbElements()
 
+    ## Returns the number of 0d elements in the mesh
+    #  @return an integer value
+    #  @ingroup l1_meshinfo
+    def Nb0DElements(self):
+        return self.mesh.Nb0DElements()
+
+    ## Returns the number of ball discrete elements in the mesh
+    #  @return an integer value
+    #  @ingroup l1_meshinfo
+    def NbBalls(self):
+        return self.mesh.NbBalls()
+
     ## Returns the number of edges in the mesh
     #  @return an integer value
     #  @ingroup l1_meshinfo
@@ -1664,6 +1865,12 @@ class Mesh:
     def NbQuadranglesOfOrder(self, elementOrder):
         return self.mesh.NbQuadranglesOfOrder(elementOrder)
 
+    ## Returns the number of biquadratic quadrangles in the mesh
+    #  @return an integer value
+    #  @ingroup l1_meshinfo
+    def NbBiQuadQuadrangles(self):
+        return self.mesh.NbBiQuadQuadrangles()
+
     ## Returns the number of polygons in the mesh
     #  @return an integer value
     #  @ingroup l1_meshinfo
@@ -1712,6 +1919,12 @@ class Mesh:
     def NbHexasOfOrder(self, elementOrder):
         return self.mesh.NbHexasOfOrder(elementOrder)
 
+    ## Returns the number of triquadratic hexahedrons in the mesh
+    #  @return an integer value
+    #  @ingroup l1_meshinfo
+    def NbTriQuadraticHexas(self):
+        return self.mesh.NbTriQuadraticHexas()
+
     ## Returns the number of pyramids in the mesh
     #  @return an integer value
     #  @ingroup l1_meshinfo
@@ -1740,6 +1953,12 @@ class Mesh:
     def NbPrismsOfOrder(self, elementOrder):
         return self.mesh.NbPrismsOfOrder(elementOrder)
 
+    ## Returns the number of hexagonal prisms in the mesh
+    #  @return an integer value
+    #  @ingroup l1_meshinfo
+    def NbHexagonalPrisms(self):
+        return self.mesh.NbHexagonalPrisms()
+
     ## Returns the number of polyhedrons in the mesh
     #  @return an integer value
     #  @ingroup l1_meshinfo
@@ -1759,7 +1978,7 @@ class Mesh:
         return self.mesh.GetElementsId()
 
     ## Returns the list of IDs of mesh elements with the given type
-    #  @param elementType  the required type of elements
+    #  @param elementType  the required type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME)
     #  @return list of integer values
     #  @ingroup l1_meshinfo
     def GetElementsByType(self, elementType):
@@ -1780,9 +1999,15 @@ class Mesh:
     def GetElementType(self, id, iselem):
         return self.mesh.GetElementType(id, iselem)
 
+    ## Returns the geometric type of mesh element
+    #  @return the value from SMESH::EntityType enumeration
+    #  @ingroup l1_meshinfo
+    def GetElementGeomType(self, id):
+        return self.mesh.GetElementGeomType(id)
+
     ## Returns the list of submesh elements IDs
-    #  @param Shape a geom object(subshape) IOR
-    #         Shape must be the subshape of a ShapeToMesh()
+    #  @param Shape a geom object(sub-shape) IOR
+    #         Shape must be the sub-shape of a ShapeToMesh()
     #  @return the list of integer values
     #  @ingroup l1_meshinfo
     def GetSubMeshElementsId(self, Shape):
@@ -1793,22 +2018,22 @@ class Mesh:
         return self.mesh.GetSubMeshElementsId(ShapeID)
 
     ## Returns the list of submesh nodes IDs
-    #  @param Shape a geom object(subshape) IOR
-    #         Shape must be the subshape of a ShapeToMesh()
+    #  @param Shape a geom object(sub-shape) IOR
+    #         Shape must be the sub-shape of a ShapeToMesh()
     #  @param all If true, gives all nodes of submesh elements, otherwise gives only submesh nodes
     #  @return the list of integer values
     #  @ingroup l1_meshinfo
     def GetSubMeshNodesId(self, Shape, all):
         if ( isinstance( Shape, geompyDC.GEOM._objref_GEOM_Object)):
-            ShapeID = Shape.GetSubShapeIndices()[0]
+            ShapeID = self.geompyD.GetSubShapeID( self.geom, Shape )
         else:
             ShapeID = Shape
         return self.mesh.GetSubMeshNodesId(ShapeID, all)
 
-    ## Returns the list of IDs of submesh elements with the given type
-    #  @param Shape a geom object(subshape) IOR
-    #         Shape must be a subshape of a ShapeToMesh()
-    #  @return the list of integer values
+    ## Returns type of elements on given shape
+    #  @param Shape a geom object(sub-shape) IOR
+    #         Shape must be a sub-shape of a ShapeToMesh()
+    #  @return element type
     #  @ingroup l1_meshinfo
     def GetSubMeshElementType(self, Shape):
         if ( isinstance( Shape, geompyDC.GEOM._objref_GEOM_Object)):
@@ -1903,6 +2128,16 @@ class Mesh:
     def ElemNbFaces(self, id):
         return self.mesh.ElemNbFaces(id)
 
+    ## Returns nodes of given face (counted from zero) for given volumic element.
+    #  @ingroup l1_meshinfo
+    def GetElemFaceNodes(self,elemId, faceIndex):
+        return self.mesh.GetElemFaceNodes(elemId, faceIndex)
+
+    ## Returns an element based on all given nodes.
+    #  @ingroup l1_meshinfo
+    def FindElementByNodes(self,nodes):
+        return self.mesh.FindElementByNodes(nodes)
+
     ## Returns true if the given element is a polygon
     #  @ingroup l1_meshinfo
     def IsPoly(self, id):
@@ -1913,6 +2148,11 @@ class Mesh:
     def IsQuadratic(self, id):
         return self.mesh.IsQuadratic(id)
 
+    ## Returns diameter of a ball discrete element or zero in case of an invalid \a id
+    #  @ingroup l1_meshinfo
+    def GetBallDiameter(self, id):
+        return self.mesh.GetBallDiameter(id)
+
     ## Returns XYZ coordinates of the barycenter of the given element
     #  \n If there is no element for the given ID - returns an empty list
     #  @return a list of three double values
@@ -1920,6 +2160,115 @@ class Mesh:
     def BaryCenter(self, id):
         return self.mesh.BaryCenter(id)
 
+    ## Passes mesh elements through the given filter and return IDs of fitting elements
+    #  @param theFilter SMESH_Filter
+    #  @return a list of ids
+    #  @ingroup l1_controls
+    def GetIdsFromFilter(self, theFilter):
+        theFilter.SetMesh( self.mesh )
+        return theFilter.GetIDs()
+
+    ## Verifies whether a 2D mesh element has free edges (edges connected to one face only)\n
+    #  Returns a list of special structures (borders).
+    #  @return a list of SMESH.FreeEdges.Border structure: edge id and ids of two its nodes.
+    #  @ingroup l1_controls
+    def GetFreeBorders(self):
+        aFilterMgr = self.smeshpyD.CreateFilterManager()
+        aPredicate = aFilterMgr.CreateFreeEdges()
+        aPredicate.SetMesh(self.mesh)
+        aBorders = aPredicate.GetBorders()
+        aFilterMgr.UnRegister()
+        return aBorders
+
+
+    # Get mesh measurements information:
+    # ------------------------------------
+
+    ## Get minimum distance between two nodes, elements or distance to the origin
+    #  @param id1 first node/element id
+    #  @param id2 second node/element id (if 0, distance from @a id1 to the origin is computed)
+    #  @param isElem1 @c True if @a id1 is element id, @c False if it is node id
+    #  @param isElem2 @c True if @a id2 is element id, @c False if it is node id
+    #  @return minimum distance value
+    #  @sa GetMinDistance()
+    def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
+        aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
+        return aMeasure.value
+
+    ## Get measure structure specifying minimum distance data between two objects
+    #  @param id1 first node/element id
+    #  @param id2 second node/element id (if 0, distance from @a id1 to the origin is computed)
+    #  @param isElem1 @c True if @a id1 is element id, @c False if it is node id
+    #  @param isElem2 @c True if @a id2 is element id, @c False if it is node id
+    #  @return Measure structure
+    #  @sa MinDistance()
+    def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
+        if isElem1:
+            id1 = self.editor.MakeIDSource([id1], SMESH.FACE)
+        else:
+            id1 = self.editor.MakeIDSource([id1], SMESH.NODE)
+        if id2 != 0:
+            if isElem2:
+                id2 = self.editor.MakeIDSource([id2], SMESH.FACE)
+            else:
+                id2 = self.editor.MakeIDSource([id2], SMESH.NODE)
+            pass
+        else:
+            id2 = None
+
+        aMeasurements = self.smeshpyD.CreateMeasurements()
+        aMeasure = aMeasurements.MinDistance(id1, id2)
+        aMeasurements.UnRegister()
+        return aMeasure
+
+    ## Get bounding box of the specified object(s)
+    #  @param objects single source object or list of source objects or list of nodes/elements IDs
+    #  @param isElem if @a objects is a list of IDs, @c True value in this parameters specifies that @a objects are elements,
+    #  @c False specifies that @a objects are nodes
+    #  @return tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
+    #  @sa GetBoundingBox()
+    def BoundingBox(self, objects=None, isElem=False):
+        result = self.GetBoundingBox(objects, isElem)
+        if result is None:
+            result = (0.0,)*6
+        else:
+            result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ)
+        return result
+
+    ## Get measure structure specifying bounding box data of the specified object(s)
+    #  @param IDs single source object or list of source objects or list of nodes/elements IDs
+    #  @param isElem if @a objects is a list of IDs, @c True value in this parameters specifies that @a objects are elements,
+    #  @c False specifies that @a objects are nodes
+    #  @return Measure structure
+    #  @sa BoundingBox()
+    def GetBoundingBox(self, IDs=None, isElem=False):
+        if IDs is None:
+            IDs = [self.mesh]
+        elif isinstance(IDs, tuple):
+            IDs = list(IDs)
+        if not isinstance(IDs, list):
+            IDs = [IDs]
+        if len(IDs) > 0 and isinstance(IDs[0], int):
+            IDs = [IDs]
+        srclist = []
+        for o in IDs:
+            if isinstance(o, Mesh):
+                srclist.append(o.mesh)
+            elif hasattr(o, "_narrow"):
+                src = o._narrow(SMESH.SMESH_IDSource)
+                if src: srclist.append(src)
+                pass
+            elif isinstance(o, list):
+                if isElem:
+                    srclist.append(self.editor.MakeIDSource(o, SMESH.FACE))
+                else:
+                    srclist.append(self.editor.MakeIDSource(o, SMESH.NODE))
+                pass
+            pass
+        aMeasurements = self.smeshpyD.CreateMeasurements()
+        aMeasure = aMeasurements.BoundingBox(srclist)
+        aMeasurements.UnRegister()
+        return aMeasure
 
     # Mesh edition (SMESH_MeshEditor functionality):
     # ---------------------------------------------
@@ -1938,20 +2287,41 @@ class Mesh:
     def RemoveNodes(self, IDsOfNodes):
         return self.editor.RemoveNodes(IDsOfNodes)
 
+    ## Removes all orphan (free) nodes from mesh
+    #  @return number of the removed nodes
+    #  @ingroup l2_modif_del
+    def RemoveOrphanNodes(self):
+        return self.editor.RemoveOrphanNodes()
+
     ## Add a node to the mesh by coordinates
     #  @return Id of the new node
     #  @ingroup l2_modif_add
     def AddNode(self, x, y, z):
-        x,y,z,Parameters = geompyDC.ParseParameters(x,y,z)
-        self.mesh.SetParameters(Parameters)
+        x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
+        if hasVars: self.mesh.SetParameters(Parameters)
         return self.editor.AddNode( x, y, z)
 
+    ## Creates a 0D element on a node with given number.
+    #  @param IDOfNode the ID of node for creation of the element.
+    #  @return the Id of the new 0D element
+    #  @ingroup l2_modif_add
+    def Add0DElement(self, IDOfNode):
+        return self.editor.Add0DElement(IDOfNode)
+
+    ## Creates a ball element on a node with given ID.
+    #  @param IDOfNode the ID of node for creation of the element.
+    #  @param diameter the bal diameter.
+    #  @return the Id of the new ball element
+    #  @ingroup l2_modif_add
+    def AddBall(self, IDOfNode, diameter):
+        return self.editor.AddBall( IDOfNode, diameter )
+
     ## Creates a linear or quadratic edge (this is determined
     #  by the number of given nodes).
     #  @param IDsOfNodes the list of node IDs for creation of the element.
     #  The order of nodes in this list should correspond to the description
     #  of MED. \n This description is located by the following link:
-    #  http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3.
+    #  http://www.code-aster.org/outils/med/html/modele_de_donnees.html#3.
     #  @return the Id of the new edge
     #  @ingroup l2_modif_add
     def AddEdge(self, IDsOfNodes):
@@ -1962,7 +2332,7 @@ class Mesh:
     #  @param IDsOfNodes the list of node IDs for creation of the element.
     #  The order of nodes in this list should correspond to the description
     #  of MED. \n This description is located by the following link:
-    #  http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3.
+    #  http://www.code-aster.org/outils/med/html/modele_de_donnees.html#3.
     #  @return the Id of the new face
     #  @ingroup l2_modif_add
     def AddFace(self, IDsOfNodes):
@@ -1980,7 +2350,7 @@ class Mesh:
     #  @param IDsOfNodes the list of node IDs for creation of the element.
     #  The order of nodes in this list should correspond to the description
     #  of MED. \n This description is located by the following link:
-    #  http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3.
+    #  http://www.code-aster.org/outils/med/html/modele_de_donnees.html#3.
     #  @return the Id of the new volumic element
     #  @ingroup l2_modif_add
     def AddVolume(self, IDsOfNodes):
@@ -2099,19 +2469,21 @@ class Mesh:
     #  @return True if succeed else False
     #  @ingroup l2_modif_movenode
     def MoveNode(self, NodeID, x, y, z):
-        x,y,z,Parameters = geompyDC.ParseParameters(x,y,z)
-        self.mesh.SetParameters(Parameters)
+        x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
+        if hasVars: self.mesh.SetParameters(Parameters)
         return self.editor.MoveNode(NodeID, x, y, z)
 
     ## Finds the node closest to a point and moves it to a point location
     #  @param x  the X coordinate of a point
     #  @param y  the Y coordinate of a point
     #  @param z  the Z coordinate of a point
+    #  @param NodeID if specified (>0), the node with this ID is moved,
+    #  otherwise, the node closest to point (@a x,@a y,@a z) is moved
     #  @return the ID of a node
     #  @ingroup l2_modif_throughp
     def MoveClosestNodeToPoint(self, x, y, z, NodeID):
-        x,y,z,Parameters = geompyDC.ParseParameters(x,y,z)
-        self.mesh.SetParameters(Parameters)
+        x,y,z,Parameters,hasVars = ParseParameters(x,y,z)
+        if hasVars: self.mesh.SetParameters(Parameters)
         return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID)
 
     ## Finds the node closest to a point
@@ -2121,8 +2493,31 @@ class Mesh:
     #  @return the ID of a node
     #  @ingroup l2_modif_throughp
     def FindNodeClosestTo(self, x, y, z):
-        preview = self.mesh.GetMeshEditPreviewer()
-        return preview.MoveClosestNodeToPoint(x, y, z, -1)
+        #preview = self.mesh.GetMeshEditPreviewer()
+        #return preview.MoveClosestNodeToPoint(x, y, z, -1)
+        return self.editor.FindNodeClosestTo(x, y, z)
+
+    ## Finds the elements where a point lays IN or ON
+    #  @param x  the X coordinate of a point
+    #  @param y  the Y coordinate of a point
+    #  @param z  the Z coordinate of a point
+    #  @param elementType type of elements to find (SMESH.ALL type
+    #         means elements of any type excluding nodes, discrete and 0D elements)
+    #  @param meshPart a part of mesh (group, sub-mesh) to search within
+    #  @return list of IDs of found elements
+    #  @ingroup l2_modif_throughp
+    def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None):
+        if meshPart:
+            return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType );
+        else:
+            return self.editor.FindElementsByPoint(x, y, z, elementType)
+
+    # Return point state in a closed 2D mesh in terms of TopAbs_State enumeration:
+    # 0-IN, 1-OUT, 2-ON, 3-UNKNOWN
+    # TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
+
+    def GetPointState(self, x, y, z):
+        return self.editor.GetPointState(x, y, z)
 
     ## Finds the node closest to a point and moves it to a point location
     #  @param x  the X coordinate of a point
@@ -2169,6 +2564,41 @@ class Mesh:
             theObject = theObject.GetMesh()
         return self.editor.ReorientObject(theObject)
 
+    ## Reorient faces contained in \a the2DObject.
+    #  @param the2DObject is a mesh, sub-mesh, group or list of IDs of 2D elements
+    #  @param theDirection is a desired direction of normal of \a theFace.
+    #         It can be either a GEOM vector or a list of coordinates [x,y,z].
+    #  @param theFaceOrPoint defines a face of \a the2DObject whose normal will be
+    #         compared with theDirection. It can be either ID of face or a point
+    #         by which the face will be found. The point can be given as either
+    #         a GEOM vertex or a list of point coordinates.
+    #  @return number of reoriented faces
+    #  @ingroup l2_modif_changori
+    def Reorient2D(self, the2DObject, theDirection, theFaceOrPoint ):
+        # check the2DObject
+        if isinstance( the2DObject, Mesh ):
+            the2DObject = the2DObject.GetMesh()
+        if isinstance( the2DObject, list ):
+            the2DObject = self.GetIDSource( the2DObject, SMESH.FACE )
+        # check theDirection
+        if isinstance( theDirection, geompyDC.GEOM._objref_GEOM_Object):
+            theDirection = self.smeshpyD.GetDirStruct( theDirection )
+        if isinstance( theDirection, list ):
+            theDirection = self.smeshpyD.MakeDirStruct( *theDirection  )
+        # prepare theFace and thePoint
+        theFace = theFaceOrPoint
+        thePoint = PointStruct(0,0,0)
+        if isinstance( theFaceOrPoint, geompyDC.GEOM._objref_GEOM_Object):
+            thePoint = self.smeshpyD.GetPointStruct( theFaceOrPoint )
+            theFace = -1
+        if isinstance( theFaceOrPoint, list ):
+            thePoint = PointStruct( *theFaceOrPoint )
+            theFace = -1
+        if isinstance( theFaceOrPoint, PointStruct ):
+            thePoint = theFaceOrPoint
+            theFace = -1
+        return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
+
     ## Fuses the neighbouring triangles into quadrangles.
     #  @param IDsOfElements The triangles to be fused,
     #  @param theCriterion  is FT_...; used to choose a neighbour to fuse with.
@@ -2181,14 +2611,12 @@ class Mesh:
         flag = False
         if isinstance(MaxAngle,str):
             flag = True
-        MaxAngle,Parameters = geompyDC.ParseParameters(MaxAngle)
-        if flag:
-            MaxAngle = DegreesToRadians(MaxAngle)
-        if IDsOfElements == []:
-            IDsOfElements = self.GetElementsId()
+        MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
         self.mesh.SetParameters(Parameters)
+        if not IDsOfElements:
+            IDsOfElements = self.GetElementsId()
         Functor = 0
-       if ( isinstance( theCriterion, SMESH._objref_NumericalFunctor ) ):
+        if ( isinstance( theCriterion, SMESH._objref_NumericalFunctor ) ):
             Functor = theCriterion
         else:
             Functor = self.smeshpyD.GetFunctor(theCriterion)
@@ -2202,6 +2630,8 @@ class Mesh:
     #  @return TRUE in case of success, FALSE otherwise.
     #  @ingroup l2_modif_unitetri
     def TriToQuadObject (self, theObject, theCriterion, MaxAngle):
+        MaxAngle,Parameters,hasVars = ParseAngles(MaxAngle)
+        self.mesh.SetParameters(Parameters)
         if ( isinstance( theObject, Mesh )):
             theObject = theObject.GetMesh()
         return self.editor.TriToQuadObject(theObject, self.smeshpyD.GetFunctor(theCriterion), MaxAngle)
@@ -2255,6 +2685,18 @@ class Mesh:
     def BestSplit (self, IDOfQuad, theCriterion):
         return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion))
 
+    ## Splits volumic elements into tetrahedrons
+    #  @param elemIDs either list of elements or mesh or group or submesh
+    #  @param method  flags passing splitting method: Hex_5Tet, Hex_6Tet, Hex_24Tet
+    #         Hex_5Tet - split the hexahedron into 5 tetrahedrons, etc
+    #  @ingroup l2_modif_cutquadr
+    def SplitVolumesIntoTetra(self, elemIDs, method=Hex_5Tet ):
+        if isinstance( elemIDs, Mesh ):
+            elemIDs = elemIDs.GetMesh()
+        if ( isinstance( elemIDs, list )):
+            elemIDs = self.editor.MakeIDSource(elemIDs, SMESH.VOLUME)
+        self.editor.SplitVolumesIntoTetra(elemIDs, method)
+
     ## Splits quadrangle faces near triangular facets of volumes
     #
     #  @ingroup l1_auxiliary
@@ -2410,7 +2852,7 @@ class Mesh:
                MaxNbOfIterations, MaxAspectRatio, Method):
         if IDsOfElements == []:
             IDsOfElements = self.GetElementsId()
-        MaxNbOfIterations,MaxAspectRatio,Parameters = geompyDC.ParseParameters(MaxNbOfIterations,MaxAspectRatio)
+        MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
         self.mesh.SetParameters(Parameters)
         return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes,
                                   MaxNbOfIterations, MaxAspectRatio, Method)
@@ -2444,7 +2886,7 @@ class Mesh:
                          MaxNbOfIterations, MaxAspectRatio, Method):
         if IDsOfElements == []:
             IDsOfElements = self.GetElementsId()
-        MaxNbOfIterations,MaxAspectRatio,Parameters = geompyDC.ParseParameters(MaxNbOfIterations,MaxAspectRatio)
+        MaxNbOfIterations,MaxAspectRatio,Parameters,hasVars = ParseParameters(MaxNbOfIterations,MaxAspectRatio)
         self.mesh.SetParameters(Parameters)
         return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes,
                                             MaxNbOfIterations, MaxAspectRatio, Method)
@@ -2467,17 +2909,86 @@ class Mesh:
 
     ## Converts the mesh to quadratic, deletes old elements, replacing
     #  them with quadratic with the same id.
+    #  @param theForce3d new node creation method:
+    #         0 - the medium node lies at the geometrical entity from which the mesh element is built
+    #         1 - the medium node lies at the middle of the line segments connecting start and end node of a mesh element
+    #  @param theSubMesh a group or a sub-mesh to convert; WARNING: in this case the mesh can become not conformal
     #  @ingroup l2_modif_tofromqu
-    def ConvertToQuadratic(self, theForce3d):
-        self.editor.ConvertToQuadratic(theForce3d)
+    def ConvertToQuadratic(self, theForce3d, theSubMesh=None):
+        if theSubMesh:
+            self.editor.ConvertToQuadraticObject(theForce3d,theSubMesh)
+        else:
+            self.editor.ConvertToQuadratic(theForce3d)
 
     ## Converts the mesh from quadratic to ordinary,
     #  deletes old quadratic elements, \n replacing
     #  them with ordinary mesh elements with the same id.
-    #  @return TRUE in case of success, FALSE otherwise.
+    #  @param theSubMesh a group or a sub-mesh to convert; WARNING: in this case the mesh can become not conformal
     #  @ingroup l2_modif_tofromqu
-    def ConvertFromQuadratic(self):
-        return self.editor.ConvertFromQuadratic()
+    def ConvertFromQuadratic(self, theSubMesh=None):
+        if theSubMesh:
+            self.editor.ConvertFromQuadraticObject(theSubMesh)
+        else:
+            return self.editor.ConvertFromQuadratic()
+
+    ## Creates 2D mesh as skin on boundary faces of a 3D mesh
+    #  @return TRUE if operation has been completed successfully, FALSE otherwise
+    #  @ingroup l2_modif_edit
+    def  Make2DMeshFrom3D(self):
+        return self.editor. Make2DMeshFrom3D()
+
+    ## Creates missing boundary elements
+    #  @param elements - elements whose boundary is to be checked:
+    #                    mesh, group, sub-mesh or list of elements
+    #   if elements is mesh, it must be the mesh whose MakeBoundaryMesh() is called
+    #  @param dimension - defines type of boundary elements to create:
+    #                     SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D
+    #    SMESH.BND_1DFROM3D creates mesh edges on all borders of free facets of 3D cells
+    #  @param groupName - a name of group to store created boundary elements in,
+    #                     "" means not to create the group
+    #  @param meshName - a name of new mesh to store created boundary elements in,
+    #                     "" means not to create the new mesh
+    #  @param toCopyElements - if true, the checked elements will be copied into
+    #     the new mesh else only boundary elements will be copied into the new mesh
+    #  @param toCopyExistingBondary - if true, not only new but also pre-existing
+    #     boundary elements will be copied into the new mesh
+    #  @return tuple (mesh, group) where bondary elements were added to
+    #  @ingroup l2_modif_edit
+    def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
+                         toCopyElements=False, toCopyExistingBondary=False):
+        if isinstance( elements, Mesh ):
+            elements = elements.GetMesh()
+        if ( isinstance( elements, list )):
+            elemType = SMESH.ALL
+            if elements: elemType = self.GetElementType( elements[0], iselem=True)
+            elements = self.editor.MakeIDSource(elements, elemType)
+        mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName,
+                                                   toCopyElements,toCopyExistingBondary)
+        if mesh: mesh = self.smeshpyD.Mesh(mesh)
+        return mesh, group
+
+    ##
+    # @brief Creates missing boundary elements around either the whole mesh or 
+    #    groups of 2D elements
+    #  @param dimension - defines type of boundary elements to create
+    #  @param groupName - a name of group to store all boundary elements in,
+    #    "" means not to create the group
+    #  @param meshName - a name of a new mesh, which is a copy of the initial 
+    #    mesh + created boundary elements; "" means not to create the new mesh
+    #  @param toCopyAll - if true, the whole initial mesh will be copied into
+    #    the new mesh else only boundary elements will be copied into the new mesh
+    #  @param groups - groups of 2D elements to make boundary around
+    #  @retval tuple( long, mesh, groups )
+    #                 long - number of added boundary elements
+    #                 mesh - the mesh where elements were added to
+    #                 group - the group of boundary elements or None
+    #
+    def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
+                             toCopyAll=False, groups=[]):
+        nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
+                                                           toCopyAll,groups)
+        if mesh: mesh = self.smeshpyD.Mesh(mesh)
+        return nb, mesh, group
 
     ## Renumber mesh nodes
     #  @ingroup l2_modif_renumber
@@ -2502,22 +3013,16 @@ class Mesh:
     #  @ingroup l2_modif_extrurev
     def RotationSweep(self, IDsOfElements, Axis, AngleInRadians, NbOfSteps, Tolerance,
                       MakeGroups=False, TotalAngle=False):
-        flag = False
-        if isinstance(AngleInRadians,str):
-            flag = True
-        AngleInRadians,AngleParameters = geompyDC.ParseParameters(AngleInRadians)
-        if flag:
-            AngleInRadians = DegreesToRadians(AngleInRadians)
         if IDsOfElements == []:
             IDsOfElements = self.GetElementsId()
         if ( isinstance( Axis, geompyDC.GEOM._objref_GEOM_Object)):
             Axis = self.smeshpyD.GetAxisStruct(Axis)
-        Axis,AxisParameters = ParseAxisStruct(Axis)
+        AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
+        NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
+        Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
+        self.mesh.SetParameters(Parameters)
         if TotalAngle and NbOfSteps:
             AngleInRadians /= NbOfSteps
-        NbOfSteps,Tolerance,Parameters = geompyDC.ParseParameters(NbOfSteps,Tolerance)
-        Parameters = AxisParameters + var_separator + AngleParameters + var_separator + Parameters
-        self.mesh.SetParameters(Parameters)
         if MakeGroups:
             return self.editor.RotationSweepMakeGroups(IDsOfElements, Axis,
                                                        AngleInRadians, NbOfSteps, Tolerance)
@@ -2525,7 +3030,8 @@ class Mesh:
         return []
 
     ## Generates new elements by rotation of the elements of object around the axis
-    #  @param theObject object which elements should be sweeped
+    #  @param theObject object which elements should be sweeped.
+    #                   It can be a mesh, a sub mesh or a group.
     #  @param Axis the axis of rotation, AxisStruct or line(geom object)
     #  @param AngleInRadians the angle of Rotation
     #  @param NbOfSteps number of steps
@@ -2537,22 +3043,16 @@ class Mesh:
     #  @ingroup l2_modif_extrurev
     def RotationSweepObject(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
                             MakeGroups=False, TotalAngle=False):
-        flag = False
-        if isinstance(AngleInRadians,str):
-            flag = True
-        AngleInRadians,AngleParameters = geompyDC.ParseParameters(AngleInRadians)
-        if flag:
-            AngleInRadians = DegreesToRadians(AngleInRadians)
         if ( isinstance( theObject, Mesh )):
             theObject = theObject.GetMesh()
         if ( isinstance( Axis, geompyDC.GEOM._objref_GEOM_Object)):
             Axis = self.smeshpyD.GetAxisStruct(Axis)
-        Axis,AxisParameters = ParseAxisStruct(Axis)
+        AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
+        NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
+        Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
+        self.mesh.SetParameters(Parameters)
         if TotalAngle and NbOfSteps:
             AngleInRadians /= NbOfSteps
-        NbOfSteps,Tolerance,Parameters = geompyDC.ParseParameters(NbOfSteps,Tolerance)
-        Parameters = AxisParameters + var_separator + AngleParameters + var_separator + Parameters
-        self.mesh.SetParameters(Parameters)
         if MakeGroups:
             return self.editor.RotationSweepObjectMakeGroups(theObject, Axis, AngleInRadians,
                                                              NbOfSteps, Tolerance)
@@ -2560,7 +3060,8 @@ class Mesh:
         return []
 
     ## Generates new elements by rotation of the elements of object around the axis
-    #  @param theObject object which elements should be sweeped
+    #  @param theObject object which elements should be sweeped.
+    #                   It can be a mesh, a sub mesh or a group.
     #  @param Axis the axis of rotation, AxisStruct or line(geom object)
     #  @param AngleInRadians the angle of Rotation
     #  @param NbOfSteps number of steps
@@ -2572,22 +3073,16 @@ class Mesh:
     #  @ingroup l2_modif_extrurev
     def RotationSweepObject1D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
                               MakeGroups=False, TotalAngle=False):
-        flag = False
-        if isinstance(AngleInRadians,str):
-            flag = True
-        AngleInRadians,AngleParameters = geompyDC.ParseParameters(AngleInRadians)
-        if flag:
-            AngleInRadians = DegreesToRadians(AngleInRadians)
         if ( isinstance( theObject, Mesh )):
             theObject = theObject.GetMesh()
         if ( isinstance( Axis, geompyDC.GEOM._objref_GEOM_Object)):
             Axis = self.smeshpyD.GetAxisStruct(Axis)
-        Axis,AxisParameters = ParseAxisStruct(Axis)
+        AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
+        NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
+        Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
+        self.mesh.SetParameters(Parameters)
         if TotalAngle and NbOfSteps:
             AngleInRadians /= NbOfSteps
-        NbOfSteps,Tolerance,Parameters = geompyDC.ParseParameters(NbOfSteps,Tolerance)
-        Parameters = AxisParameters + var_separator + AngleParameters + var_separator + Parameters
-        self.mesh.SetParameters(Parameters)
         if MakeGroups:
             return self.editor.RotationSweepObject1DMakeGroups(theObject, Axis, AngleInRadians,
                                                                NbOfSteps, Tolerance)
@@ -2595,7 +3090,8 @@ class Mesh:
         return []
 
     ## Generates new elements by rotation of the elements of object around the axis
-    #  @param theObject object which elements should be sweeped
+    #  @param theObject object which elements should be sweeped.
+    #                   It can be a mesh, a sub mesh or a group.
     #  @param Axis the axis of rotation, AxisStruct or line(geom object)
     #  @param AngleInRadians the angle of Rotation
     #  @param NbOfSteps number of steps
@@ -2607,22 +3103,16 @@ class Mesh:
     #  @ingroup l2_modif_extrurev
     def RotationSweepObject2D(self, theObject, Axis, AngleInRadians, NbOfSteps, Tolerance,
                               MakeGroups=False, TotalAngle=False):
-        flag = False
-        if isinstance(AngleInRadians,str):
-            flag = True
-        AngleInRadians,AngleParameters = geompyDC.ParseParameters(AngleInRadians)
-        if flag:
-            AngleInRadians = DegreesToRadians(AngleInRadians)
         if ( isinstance( theObject, Mesh )):
             theObject = theObject.GetMesh()
         if ( isinstance( Axis, geompyDC.GEOM._objref_GEOM_Object)):
             Axis = self.smeshpyD.GetAxisStruct(Axis)
-        Axis,AxisParameters = ParseAxisStruct(Axis)
+        AngleInRadians,AngleParameters,hasVars = ParseAngles(AngleInRadians)
+        NbOfSteps,Tolerance,Parameters,hasVars = ParseParameters(NbOfSteps,Tolerance)
+        Parameters = Axis.parameters + var_separator + AngleParameters + var_separator + Parameters
+        self.mesh.SetParameters(Parameters)
         if TotalAngle and NbOfSteps:
             AngleInRadians /= NbOfSteps
-        NbOfSteps,Tolerance,Parameters = geompyDC.ParseParameters(NbOfSteps,Tolerance)
-        Parameters = AxisParameters + var_separator + AngleParameters + var_separator + Parameters
-        self.mesh.SetParameters(Parameters)
         if MakeGroups:
             return self.editor.RotationSweepObject2DMakeGroups(theObject, Axis, AngleInRadians,
                                                              NbOfSteps, Tolerance)
@@ -2631,23 +3121,29 @@ class Mesh:
 
     ## Generates new elements by extrusion of the elements with given ids
     #  @param IDsOfElements the list of elements ids for extrusion
-    #  @param StepVector vector, defining the direction and value of extrusion
+    #  @param StepVector vector or DirStruct, defining the direction and value of extrusion for one step (the total extrusion length will be NbOfSteps * ||StepVector||)
     #  @param NbOfSteps the number of steps
     #  @param MakeGroups forces the generation of new groups from existing ones
+    #  @param IsNodes is True if elements with given ids are nodes
     #  @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
     #  @ingroup l2_modif_extrurev
-    def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False):
+    def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
         if IDsOfElements == []:
             IDsOfElements = self.GetElementsId()
         if ( isinstance( StepVector, geompyDC.GEOM._objref_GEOM_Object)):
             StepVector = self.smeshpyD.GetDirStruct(StepVector)
-        StepVector,StepVectorParameters = ParseDirStruct(StepVector)
-        NbOfSteps,Parameters = geompyDC.ParseParameters(NbOfSteps)
-        Parameters = StepVectorParameters + var_separator + Parameters
+        NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
+        Parameters = StepVector.PS.parameters + var_separator + Parameters
         self.mesh.SetParameters(Parameters)
         if MakeGroups:
-            return self.editor.ExtrusionSweepMakeGroups(IDsOfElements, StepVector, NbOfSteps)
-        self.editor.ExtrusionSweep(IDsOfElements, StepVector, NbOfSteps)
+            if(IsNodes):
+                return self.editor.ExtrusionSweepMakeGroups0D(IDsOfElements, StepVector, NbOfSteps)
+            else:
+                return self.editor.ExtrusionSweepMakeGroups(IDsOfElements, StepVector, NbOfSteps)
+        if(IsNodes):
+            self.editor.ExtrusionSweep0D(IDsOfElements, StepVector, NbOfSteps)
+        else:
+            self.editor.ExtrusionSweep(IDsOfElements, StepVector, NbOfSteps)
         return []
 
     ## Generates new elements by extrusion of the elements with given ids
@@ -2672,29 +3168,37 @@ class Mesh:
         return []
 
     ## Generates new elements by extrusion of the elements which belong to the object
-    #  @param theObject the object which elements should be processed
-    #  @param StepVector vector, defining the direction and value of extrusion
+    #  @param theObject the object which elements should be processed.
+    #                   It can be a mesh, a sub mesh or a group.
+    #  @param StepVector vector, defining the direction and value of extrusion for one step (the total extrusion length will be NbOfSteps * ||StepVector||)
     #  @param NbOfSteps the number of steps
     #  @param MakeGroups forces the generation of new groups from existing ones
+    #  @param  IsNodes is True if elements which belong to the object are nodes
     #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
     #  @ingroup l2_modif_extrurev
-    def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
+    def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
         if ( isinstance( theObject, Mesh )):
             theObject = theObject.GetMesh()
         if ( isinstance( StepVector, geompyDC.GEOM._objref_GEOM_Object)):
             StepVector = self.smeshpyD.GetDirStruct(StepVector)
-        StepVector,StepVectorParameters = ParseDirStruct(StepVector)
-        NbOfSteps,Parameters = geompyDC.ParseParameters(NbOfSteps)
-        Parameters = StepVectorParameters + var_separator + Parameters
+        NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
+        Parameters = StepVector.PS.parameters + var_separator + Parameters
         self.mesh.SetParameters(Parameters)
         if MakeGroups:
-            return self.editor.ExtrusionSweepObjectMakeGroups(theObject, StepVector, NbOfSteps)
-        self.editor.ExtrusionSweepObject(theObject, StepVector, NbOfSteps)
+            if(IsNodes):
+                return self.editor.ExtrusionSweepObject0DMakeGroups(theObject, StepVector, NbOfSteps)
+            else:
+                return self.editor.ExtrusionSweepObjectMakeGroups(theObject, StepVector, NbOfSteps)
+        if(IsNodes):
+            self.editor.ExtrusionSweepObject0D(theObject, StepVector, NbOfSteps)
+        else:
+            self.editor.ExtrusionSweepObject(theObject, StepVector, NbOfSteps)
         return []
 
     ## Generates new elements by extrusion of the elements which belong to the object
-    #  @param theObject object which elements should be processed
-    #  @param StepVector vector, defining the direction and value of extrusion
+    #  @param theObject object which elements should be processed.
+    #                   It can be a mesh, a sub mesh or a group.
+    #  @param StepVector vector, defining the direction and value of extrusion for one step (the total extrusion length will be NbOfSteps * ||StepVector||)
     #  @param NbOfSteps the number of steps
     #  @param MakeGroups to generate new groups from existing ones
     #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
@@ -2704,9 +3208,8 @@ class Mesh:
             theObject = theObject.GetMesh()
         if ( isinstance( StepVector, geompyDC.GEOM._objref_GEOM_Object)):
             StepVector = self.smeshpyD.GetDirStruct(StepVector)
-        StepVector,StepVectorParameters = ParseDirStruct(StepVector)
-        NbOfSteps,Parameters = geompyDC.ParseParameters(NbOfSteps)
-        Parameters = StepVectorParameters + var_separator + Parameters
+        NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
+        Parameters = StepVector.PS.parameters + var_separator + Parameters
         self.mesh.SetParameters(Parameters)
         if MakeGroups:
             return self.editor.ExtrusionSweepObject1DMakeGroups(theObject, StepVector, NbOfSteps)
@@ -2714,8 +3217,9 @@ class Mesh:
         return []
 
     ## Generates new elements by extrusion of the elements which belong to the object
-    #  @param theObject object which elements should be processed
-    #  @param StepVector vector, defining the direction and value of extrusion
+    #  @param theObject object which elements should be processed.
+    #                   It can be a mesh, a sub mesh or a group.
+    #  @param StepVector vector, defining the direction and value of extrusion for one step (the total extrusion length will be NbOfSteps * ||StepVector||)
     #  @param NbOfSteps the number of steps
     #  @param MakeGroups forces the generation of new groups from existing ones
     #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
@@ -2725,15 +3229,63 @@ class Mesh:
             theObject = theObject.GetMesh()
         if ( isinstance( StepVector, geompyDC.GEOM._objref_GEOM_Object)):
             StepVector = self.smeshpyD.GetDirStruct(StepVector)
-        StepVector,StepVectorParameters = ParseDirStruct(StepVector)
-        NbOfSteps,Parameters = geompyDC.ParseParameters(NbOfSteps)
-        Parameters = StepVectorParameters + var_separator + Parameters
+        NbOfSteps,Parameters,hasVars = ParseParameters(NbOfSteps)
+        Parameters = StepVector.PS.parameters + var_separator + Parameters
         self.mesh.SetParameters(Parameters)
         if MakeGroups:
             return self.editor.ExtrusionSweepObject2DMakeGroups(theObject, StepVector, NbOfSteps)
         self.editor.ExtrusionSweepObject2D(theObject, StepVector, NbOfSteps)
         return []
 
+
+
+    ## Generates new elements by extrusion of the given elements
+    #  The path of extrusion must be a meshed edge.
+    #  @param Base mesh or group, or submesh, or list of ids of elements for extrusion
+    #  @param Path - 1D mesh or 1D sub-mesh, along which proceeds the extrusion
+    #  @param NodeStart the start node from Path. Defines the direction of extrusion
+    #  @param HasAngles allows the shape to be rotated around the path
+    #                   to get the resulting mesh in a helical fashion
+    #  @param Angles list of angles in radians
+    #  @param LinearVariation forces the computation of rotation angles as linear
+    #                         variation of the given Angles along path steps
+    #  @param HasRefPoint allows using the reference point
+    #  @param RefPoint the point around which the shape is rotated (the mass center of the shape by default).
+    #         The User can specify any point as the Reference Point.
+    #  @param MakeGroups forces the generation of new groups from existing ones
+    #  @param ElemType type of elements for extrusion (if param Base is a mesh)
+    #  @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
+    #          only SMESH::Extrusion_Error otherwise
+    #  @ingroup l2_modif_extrurev
+    def ExtrusionAlongPathX(self, Base, Path, NodeStart,
+                            HasAngles, Angles, LinearVariation,
+                            HasRefPoint, RefPoint, MakeGroups, ElemType):
+        if ( isinstance( RefPoint, geompyDC.GEOM._objref_GEOM_Object)):
+            RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
+            pass
+        Angles,AnglesParameters,hasVars = ParseAngles(Angles)
+        Parameters = AnglesParameters + var_separator + RefPoint.parameters
+        self.mesh.SetParameters(Parameters)
+
+        if (isinstance(Path, Mesh)): Path = Path.GetMesh()
+
+        if isinstance(Base, list):
+            IDsOfElements = []
+            if Base == []: IDsOfElements = self.GetElementsId()
+            else: IDsOfElements = Base
+            return self.editor.ExtrusionAlongPathX(IDsOfElements, Path, NodeStart,
+                                                   HasAngles, Angles, LinearVariation,
+                                                   HasRefPoint, RefPoint, MakeGroups, ElemType)
+        else:
+            if isinstance(Base, Mesh): Base = Base.GetMesh()
+            if isinstance(Base, SMESH._objref_SMESH_Mesh) or isinstance(Base, SMESH._objref_SMESH_Group) or isinstance(Base, SMESH._objref_SMESH_subMesh):
+                return self.editor.ExtrusionAlongPathObjX(Base, Path, NodeStart,
+                                                          HasAngles, Angles, LinearVariation,
+                                                          HasRefPoint, RefPoint, MakeGroups, ElemType)
+            else:
+                raise RuntimeError, "Invalid Base for ExtrusionAlongPathX"
+
+
     ## Generates new elements by extrusion of the given elements
     #  The path of extrusion must be a meshed edge.
     #  @param IDsOfElements ids of elements
@@ -2742,7 +3294,7 @@ class Mesh:
     #  @param NodeStart the first or the last node on the edge. Defines the direction of extrusion
     #  @param HasAngles allows the shape to be rotated around the path
     #                   to get the resulting mesh in a helical fashion
-    #  @param Angles list of angles
+    #  @param Angles list of angles in radians
     #  @param HasRefPoint allows using the reference point
     #  @param RefPoint the point around which the shape is rotated (the mass center of the shape by default).
     #         The User can specify any point as the Reference Point.
@@ -2755,8 +3307,6 @@ class Mesh:
     def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
                            HasAngles, Angles, HasRefPoint, RefPoint,
                            MakeGroups=False, LinearVariation=False):
-        Angles,AnglesParameters = ParseAngles(Angles)
-        RefPoint,RefPointParameters = ParsePointStruct(RefPoint)
         if IDsOfElements == []:
             IDsOfElements = self.GetElementsId()
         if ( isinstance( RefPoint, geompyDC.GEOM._objref_GEOM_Object)):
@@ -2764,11 +3314,12 @@ class Mesh:
             pass
         if ( isinstance( PathMesh, Mesh )):
             PathMesh = PathMesh.GetMesh()
+        Angles,AnglesParameters,hasVars = ParseAngles(Angles)
+        Parameters = AnglesParameters + var_separator + RefPoint.parameters
+        self.mesh.SetParameters(Parameters)
         if HasAngles and Angles and LinearVariation:
             Angles = self.editor.LinearAnglesVariation( PathMesh, PathShape, Angles )
             pass
-        Parameters = AnglesParameters + var_separator + RefPointParameters
-        self.mesh.SetParameters(Parameters)
         if MakeGroups:
             return self.editor.ExtrusionAlongPathMakeGroups(IDsOfElements, PathMesh,
                                                             PathShape, NodeStart, HasAngles,
@@ -2778,7 +3329,8 @@ class Mesh:
 
     ## Generates new elements by extrusion of the elements which belong to the object
     #  The path of extrusion must be a meshed edge.
-    #  @param theObject the object which elements should be processed
+    #  @param theObject the object which elements should be processed.
+    #                   It can be a mesh, a sub mesh or a group.
     #  @param PathMesh mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
     #  @param PathShape shape(edge) defines the sub-mesh for the path
     #  @param NodeStart the first or the last node on the edge. Defines the direction of extrusion
@@ -2797,19 +3349,18 @@ class Mesh:
     def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
                                  HasAngles, Angles, HasRefPoint, RefPoint,
                                  MakeGroups=False, LinearVariation=False):
-        Angles,AnglesParameters = ParseAngles(Angles)
-        RefPoint,RefPointParameters = ParsePointStruct(RefPoint)
         if ( isinstance( theObject, Mesh )):
             theObject = theObject.GetMesh()
         if ( isinstance( RefPoint, geompyDC.GEOM._objref_GEOM_Object)):
             RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
         if ( isinstance( PathMesh, Mesh )):
             PathMesh = PathMesh.GetMesh()
+        Angles,AnglesParameters,hasVars = ParseAngles(Angles)
+        Parameters = AnglesParameters + var_separator + RefPoint.parameters
+        self.mesh.SetParameters(Parameters)
         if HasAngles and Angles and LinearVariation:
             Angles = self.editor.LinearAnglesVariation( PathMesh, PathShape, Angles )
             pass
-        Parameters = AnglesParameters + var_separator + RefPointParameters
-        self.mesh.SetParameters(Parameters)
         if MakeGroups:
             return self.editor.ExtrusionAlongPathObjectMakeGroups(theObject, PathMesh,
                                                                   PathShape, NodeStart, HasAngles,
@@ -2820,7 +3371,8 @@ class Mesh:
 
     ## Generates new elements by extrusion of the elements which belong to the object
     #  The path of extrusion must be a meshed edge.
-    #  @param theObject the object which elements should be processed
+    #  @param theObject the object which elements should be processed.
+    #                   It can be a mesh, a sub mesh or a group.
     #  @param PathMesh mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
     #  @param PathShape shape(edge) defines the sub-mesh for the path
     #  @param NodeStart the first or the last node on the edge. Defines the direction of extrusion
@@ -2839,19 +3391,18 @@ class Mesh:
     def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
                                    HasAngles, Angles, HasRefPoint, RefPoint,
                                    MakeGroups=False, LinearVariation=False):
-        Angles,AnglesParameters = ParseAngles(Angles)
-        RefPoint,RefPointParameters = ParsePointStruct(RefPoint)
         if ( isinstance( theObject, Mesh )):
             theObject = theObject.GetMesh()
         if ( isinstance( RefPoint, geompyDC.GEOM._objref_GEOM_Object)):
             RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
         if ( isinstance( PathMesh, Mesh )):
             PathMesh = PathMesh.GetMesh()
+        Angles,AnglesParameters,hasVars = ParseAngles(Angles)
+        Parameters = AnglesParameters + var_separator + RefPoint.parameters
+        self.mesh.SetParameters(Parameters)
         if HasAngles and Angles and LinearVariation:
             Angles = self.editor.LinearAnglesVariation( PathMesh, PathShape, Angles )
             pass
-        Parameters = AnglesParameters + var_separator + RefPointParameters
-        self.mesh.SetParameters(Parameters)
         if MakeGroups:
             return self.editor.ExtrusionAlongPathObject1DMakeGroups(theObject, PathMesh,
                                                                     PathShape, NodeStart, HasAngles,
@@ -2862,7 +3413,8 @@ class Mesh:
 
     ## Generates new elements by extrusion of the elements which belong to the object
     #  The path of extrusion must be a meshed edge.
-    #  @param theObject the object which elements should be processed
+    #  @param theObject the object which elements should be processed.
+    #                   It can be a mesh, a sub mesh or a group.
     #  @param PathMesh mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
     #  @param PathShape shape(edge) defines the sub-mesh for the path
     #  @param NodeStart the first or the last node on the edge. Defines the direction of extrusion
@@ -2881,19 +3433,18 @@ class Mesh:
     def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
                                    HasAngles, Angles, HasRefPoint, RefPoint,
                                    MakeGroups=False, LinearVariation=False):
-        Angles,AnglesParameters = ParseAngles(Angles)
-        RefPoint,RefPointParameters = ParsePointStruct(RefPoint)
         if ( isinstance( theObject, Mesh )):
             theObject = theObject.GetMesh()
         if ( isinstance( RefPoint, geompyDC.GEOM._objref_GEOM_Object)):
             RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
         if ( isinstance( PathMesh, Mesh )):
             PathMesh = PathMesh.GetMesh()
+        Angles,AnglesParameters,hasVars = ParseAngles(Angles)
+        Parameters = AnglesParameters + var_separator + RefPoint.parameters
+        self.mesh.SetParameters(Parameters)
         if HasAngles and Angles and LinearVariation:
             Angles = self.editor.LinearAnglesVariation( PathMesh, PathShape, Angles )
             pass
-        Parameters = AnglesParameters + var_separator + RefPointParameters
-        self.mesh.SetParameters(Parameters)
         if MakeGroups:
             return self.editor.ExtrusionAlongPathObject2DMakeGroups(theObject, PathMesh,
                                                                     PathShape, NodeStart, HasAngles,
@@ -2916,8 +3467,7 @@ class Mesh:
             IDsOfElements = self.GetElementsId()
         if ( isinstance( Mirror, geompyDC.GEOM._objref_GEOM_Object)):
             Mirror = self.smeshpyD.GetAxisStruct(Mirror)
-        Mirror,Parameters = ParseAxisStruct(Mirror)
-        self.mesh.SetParameters(Parameters)
+        self.mesh.SetParameters(Mirror.parameters)
         if Copy and MakeGroups:
             return self.editor.MirrorMakeGroups(IDsOfElements, Mirror, theMirrorType)
         self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy)
@@ -2937,10 +3487,9 @@ class Mesh:
             IDsOfElements = self.GetElementsId()
         if ( isinstance( Mirror, geompyDC.GEOM._objref_GEOM_Object)):
             Mirror = self.smeshpyD.GetAxisStruct(Mirror)
-        Mirror,Parameters = ParseAxisStruct(Mirror)
+        self.mesh.SetParameters(Mirror.parameters)
         mesh = self.editor.MirrorMakeMesh(IDsOfElements, Mirror, theMirrorType,
                                           MakeGroups, NewMeshName)
-        mesh.SetParameters(Parameters)
         return Mesh(self.smeshpyD,self.geompyD,mesh)
 
     ## Creates a symmetrical copy of the object
@@ -2957,8 +3506,7 @@ class Mesh:
             theObject = theObject.GetMesh()
         if ( isinstance( Mirror, geompyDC.GEOM._objref_GEOM_Object)):
             Mirror = self.smeshpyD.GetAxisStruct(Mirror)
-        Mirror,Parameters = ParseAxisStruct(Mirror)
-        self.mesh.SetParameters(Parameters)
+        self.mesh.SetParameters(Mirror.parameters)
         if Copy and MakeGroups:
             return self.editor.MirrorObjectMakeGroups(theObject, Mirror, theMirrorType)
         self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy)
@@ -2978,10 +3526,9 @@ class Mesh:
             theObject = theObject.GetMesh()
         if (isinstance(Mirror, geompyDC.GEOM._objref_GEOM_Object)):
             Mirror = self.smeshpyD.GetAxisStruct(Mirror)
-        Mirror,Parameters = ParseAxisStruct(Mirror)
+        self.mesh.SetParameters(Mirror.parameters)
         mesh = self.editor.MirrorObjectMakeMesh(theObject, Mirror, theMirrorType,
                                                 MakeGroups, NewMeshName)
-        mesh.SetParameters(Parameters)
         return Mesh( self.smeshpyD,self.geompyD,mesh )
 
     ## Translates the elements
@@ -2996,8 +3543,7 @@ class Mesh:
             IDsOfElements = self.GetElementsId()
         if ( isinstance( Vector, geompyDC.GEOM._objref_GEOM_Object)):
             Vector = self.smeshpyD.GetDirStruct(Vector)
-        Vector,Parameters = ParseDirStruct(Vector)
-        self.mesh.SetParameters(Parameters)
+        self.mesh.SetParameters(Vector.PS.parameters)
         if Copy and MakeGroups:
             return self.editor.TranslateMakeGroups(IDsOfElements, Vector)
         self.editor.Translate(IDsOfElements, Vector, Copy)
@@ -3015,9 +3561,8 @@ class Mesh:
             IDsOfElements = self.GetElementsId()
         if ( isinstance( Vector, geompyDC.GEOM._objref_GEOM_Object)):
             Vector = self.smeshpyD.GetDirStruct(Vector)
-        Vector,Parameters = ParseDirStruct(Vector)
+        self.mesh.SetParameters(Vector.PS.parameters)
         mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName)
-        mesh.SetParameters(Parameters)
         return Mesh ( self.smeshpyD, self.geompyD, mesh )
 
     ## Translates the object
@@ -3032,8 +3577,7 @@ class Mesh:
             theObject = theObject.GetMesh()
         if ( isinstance( Vector, geompyDC.GEOM._objref_GEOM_Object)):
             Vector = self.smeshpyD.GetDirStruct(Vector)
-        Vector,Parameters = ParseDirStruct(Vector)
-        self.mesh.SetParameters(Parameters)
+        self.mesh.SetParameters(Vector.PS.parameters)
         if Copy and MakeGroups:
             return self.editor.TranslateObjectMakeGroups(theObject, Vector)
         self.editor.TranslateObject(theObject, Vector, Copy)
@@ -3051,11 +3595,54 @@ class Mesh:
             theObject = theObject.GetMesh()
         if (isinstance(Vector, geompyDC.GEOM._objref_GEOM_Object)):
             Vector = self.smeshpyD.GetDirStruct(Vector)
-        Vector,Parameters = ParseDirStruct(Vector)
+        self.mesh.SetParameters(Vector.PS.parameters)
         mesh = self.editor.TranslateObjectMakeMesh(theObject, Vector, MakeGroups, NewMeshName)
-        mesh.SetParameters(Parameters)
         return Mesh( self.smeshpyD, self.geompyD, mesh )
 
+
+
+    ## Scales the object
+    #  @param theObject - the object to translate (mesh, submesh, or group)
+    #  @param thePoint - base point for scale
+    #  @param theScaleFact - list of 1-3 scale factors for axises
+    #  @param Copy - allows copying the translated elements
+    #  @param MakeGroups - forces the generation of new groups from existing
+    #                      ones (if Copy)
+    #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True,
+    #          empty list otherwise
+    def Scale(self, theObject, thePoint, theScaleFact, Copy, MakeGroups=False):
+        if ( isinstance( theObject, Mesh )):
+            theObject = theObject.GetMesh()
+        if ( isinstance( theObject, list )):
+            theObject = self.GetIDSource(theObject, SMESH.ALL)
+
+        self.mesh.SetParameters(thePoint.parameters)
+
+        if Copy and MakeGroups:
+            return self.editor.ScaleMakeGroups(theObject, thePoint, theScaleFact)
+        self.editor.Scale(theObject, thePoint, theScaleFact, Copy)
+        return []
+
+    ## Creates a new mesh from the translated object
+    #  @param theObject - the object to translate (mesh, submesh, or group)
+    #  @param thePoint - base point for scale
+    #  @param theScaleFact - list of 1-3 scale factors for axises
+    #  @param MakeGroups - forces the generation of new groups from existing ones
+    #  @param NewMeshName - the name of the newly created mesh
+    #  @return instance of Mesh class
+    def ScaleMakeMesh(self, theObject, thePoint, theScaleFact, MakeGroups=False, NewMeshName=""):
+        if (isinstance(theObject, Mesh)):
+            theObject = theObject.GetMesh()
+        if ( isinstance( theObject, list )):
+            theObject = self.GetIDSource(theObject,SMESH.ALL)
+
+        self.mesh.SetParameters(thePoint.parameters)
+        mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
+                                         MakeGroups, NewMeshName)
+        return Mesh( self.smeshpyD, self.geompyD, mesh )
+
+
+
     ## Rotates the elements
     #  @param IDsOfElements list of elements ids
     #  @param Axis the axis of rotation (AxisStruct or geom line)
@@ -3065,18 +3652,12 @@ class Mesh:
     #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
     #  @ingroup l2_modif_trsf
     def Rotate (self, IDsOfElements, Axis, AngleInRadians, Copy, MakeGroups=False):
-        flag = False
-        if isinstance(AngleInRadians,str):
-            flag = True
-        AngleInRadians,Parameters = geompyDC.ParseParameters(AngleInRadians)
-        if flag:
-            AngleInRadians = DegreesToRadians(AngleInRadians)
         if IDsOfElements == []:
             IDsOfElements = self.GetElementsId()
         if ( isinstance( Axis, geompyDC.GEOM._objref_GEOM_Object)):
             Axis = self.smeshpyD.GetAxisStruct(Axis)
-        Axis,AxisParameters = ParseAxisStruct(Axis)
-        Parameters = AxisParameters + var_separator + Parameters
+        AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
+        Parameters = Axis.parameters + var_separator + Parameters
         self.mesh.SetParameters(Parameters)
         if Copy and MakeGroups:
             return self.editor.RotateMakeGroups(IDsOfElements, Axis, AngleInRadians)
@@ -3092,21 +3673,15 @@ class Mesh:
     #  @return instance of Mesh class
     #  @ingroup l2_modif_trsf
     def RotateMakeMesh (self, IDsOfElements, Axis, AngleInRadians, MakeGroups=0, NewMeshName=""):
-        flag = False
-        if isinstance(AngleInRadians,str):
-            flag = True
-        AngleInRadians,Parameters = geompyDC.ParseParameters(AngleInRadians)
-        if flag:
-            AngleInRadians = DegreesToRadians(AngleInRadians)
         if IDsOfElements == []:
             IDsOfElements = self.GetElementsId()
         if ( isinstance( Axis, geompyDC.GEOM._objref_GEOM_Object)):
             Axis = self.smeshpyD.GetAxisStruct(Axis)
-        Axis,AxisParameters = ParseAxisStruct(Axis)
-        Parameters = AxisParameters + var_separator + Parameters
+        AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
+        Parameters = Axis.parameters + var_separator + Parameters
+        self.mesh.SetParameters(Parameters)
         mesh = self.editor.RotateMakeMesh(IDsOfElements, Axis, AngleInRadians,
                                           MakeGroups, NewMeshName)
-        mesh.SetParameters(Parameters)
         return Mesh( self.smeshpyD, self.geompyD, mesh )
 
     ## Rotates the object
@@ -3118,18 +3693,12 @@ class Mesh:
     #  @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
     #  @ingroup l2_modif_trsf
     def RotateObject (self, theObject, Axis, AngleInRadians, Copy, MakeGroups=False):
-        flag = False
-        if isinstance(AngleInRadians,str):
-            flag = True
-        AngleInRadians,Parameters = geompyDC.ParseParameters(AngleInRadians)
-        if flag:
-            AngleInRadians = DegreesToRadians(AngleInRadians)
         if (isinstance(theObject, Mesh)):
             theObject = theObject.GetMesh()
         if (isinstance(Axis, geompyDC.GEOM._objref_GEOM_Object)):
             Axis = self.smeshpyD.GetAxisStruct(Axis)
-        Axis,AxisParameters = ParseAxisStruct(Axis)
-        Parameters = AxisParameters + ":" + Parameters
+        AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
+        Parameters = Axis.parameters + ":" + Parameters
         self.mesh.SetParameters(Parameters)
         if Copy and MakeGroups:
             return self.editor.RotateObjectMakeGroups(theObject, Axis, AngleInRadians)
@@ -3145,21 +3714,15 @@ class Mesh:
     #  @return instance of Mesh class
     #  @ingroup l2_modif_trsf
     def RotateObjectMakeMesh(self, theObject, Axis, AngleInRadians, MakeGroups=0,NewMeshName=""):
-        flag = False
-        if isinstance(AngleInRadians,str):
-            flag = True
-        AngleInRadians,Parameters = geompyDC.ParseParameters(AngleInRadians)
-        if flag:
-            AngleInRadians = DegreesToRadians(AngleInRadians)
         if (isinstance( theObject, Mesh )):
             theObject = theObject.GetMesh()
         if (isinstance(Axis, geompyDC.GEOM._objref_GEOM_Object)):
             Axis = self.smeshpyD.GetAxisStruct(Axis)
-        Axis,AxisParameters = ParseAxisStruct(Axis)
-        Parameters = AxisParameters + ":" + Parameters
+        AngleInRadians,Parameters,hasVars = ParseAngles(AngleInRadians)
+        Parameters = Axis.parameters + ":" + Parameters
         mesh = self.editor.RotateObjectMakeMesh(theObject, Axis, AngleInRadians,
                                                        MakeGroups, NewMeshName)
-        mesh.SetParameters(Parameters)
+        self.mesh.SetParameters(Parameters)
         return Mesh( self.smeshpyD, self.geompyD, mesh )
 
     ## Finds groups of ajacent nodes within Tolerance.
@@ -3172,10 +3735,17 @@ class Mesh:
     ## Finds groups of ajacent nodes within Tolerance.
     #  @param Tolerance the value of tolerance
     #  @param SubMeshOrGroup SubMesh or Group
+    #  @param exceptNodes list of either SubMeshes, Groups or node IDs to exclude from search
     #  @return the list of groups of nodes
     #  @ingroup l2_modif_trsf
-    def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance):
-        return self.editor.FindCoincidentNodesOnPart(SubMeshOrGroup, Tolerance)
+    def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance, exceptNodes=[]):
+        if (isinstance( SubMeshOrGroup, Mesh )):
+            SubMeshOrGroup = SubMeshOrGroup.GetMesh()
+        if not isinstance( exceptNodes, list):
+            exceptNodes = [ exceptNodes ]
+        if exceptNodes and isinstance( exceptNodes[0], int):
+            exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE)]
+        return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,exceptNodes)
 
     ## Merges nodes
     #  @param GroupsOfNodes the list of groups of nodes
@@ -3188,6 +3758,8 @@ class Mesh:
     #  @return a list of groups of equal elements
     #  @ingroup l2_modif_trsf
     def FindEqualElements (self, MeshOrSubMeshOrGroup):
+        if ( isinstance( MeshOrSubMeshOrGroup, Mesh )):
+            MeshOrSubMeshOrGroup = MeshOrSubMeshOrGroup.GetMesh()
         return self.editor.FindEqualElements(MeshOrSubMeshOrGroup)
 
     ## Merges elements in each given group.
@@ -3265,47 +3837,257 @@ class Mesh:
     #  @ingroup l1_auxiliary
     def GetLastCreatedElems(self):
         return self.editor.GetLastCreatedElems()
-    
-    ## Creates a hole in a mesh by doubling the nodes of some particular elements
+
+     ## Creates a hole in a mesh by doubling the nodes of some particular elements
     #  @param theNodes identifiers of nodes to be doubled
-    #  @param theModifiedElems identifiers of elements to be updated by the new (doubled) 
-    #         nodes. If list of element identifiers is empty then nodes are doubled but 
+    #  @param theModifiedElems identifiers of elements to be updated by the new (doubled)
+    #         nodes. If list of element identifiers is empty then nodes are doubled but
     #         they not assigned to elements
     #  @return TRUE if operation has been completed successfully, FALSE otherwise
     #  @ingroup l2_modif_edit
     def DoubleNodes(self, theNodes, theModifiedElems):
         return self.editor.DoubleNodes(theNodes, theModifiedElems)
-        
+
     ## Creates a hole in a mesh by doubling the nodes of some particular elements
     #  This method provided for convenience works as DoubleNodes() described above.
-    #  @param theNodes identifiers of node to be doubled
+    #  @param theNodeId identifiers of node to be doubled
     #  @param theModifiedElems identifiers of elements to be updated
     #  @return TRUE if operation has been completed successfully, FALSE otherwise
     #  @ingroup l2_modif_edit
     def DoubleNode(self, theNodeId, theModifiedElems):
         return self.editor.DoubleNode(theNodeId, theModifiedElems)
-        
+
     ## Creates a hole in a mesh by doubling the nodes of some particular elements
     #  This method provided for convenience works as DoubleNodes() described above.
     #  @param theNodes group of nodes to be doubled
     #  @param theModifiedElems group of elements to be updated.
-    #  @return TRUE if operation has been completed successfully, FALSE otherwise
+    #  @param theMakeGroup forces the generation of a group containing new nodes.
+    #  @return TRUE or a created group if operation has been completed successfully,
+    #          FALSE or None otherwise
     #  @ingroup l2_modif_edit
-    def DoubleNodeGroup(self, theNodes, theModifiedElems):
+    def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False):
+        if theMakeGroup:
+            return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems)
         return self.editor.DoubleNodeGroup(theNodes, theModifiedElems)
-        
+
     ## Creates a hole in a mesh by doubling the nodes of some particular elements
     #  This method provided for convenience works as DoubleNodes() described above.
     #  @param theNodes list of groups of nodes to be doubled
     #  @param theModifiedElems list of groups of elements to be updated.
+    #  @param theMakeGroup forces the generation of a group containing new nodes.
     #  @return TRUE if operation has been completed successfully, FALSE otherwise
     #  @ingroup l2_modif_edit
-    def DoubleNodeGroups(self, theNodes, theModifiedElems):
+    def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False):
+        if theMakeGroup:
+            return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems)
         return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
 
+    ## Creates a hole in a mesh by doubling the nodes of some particular elements
+    #  @param theElems - the list of elements (edges or faces) to be replicated
+    #         The nodes for duplication could be found from these elements
+    #  @param theNodesNot - list of nodes to NOT replicate
+    #  @param theAffectedElems - the list of elements (cells and edges) to which the
+    #         replicated nodes should be associated to.
+    #  @return TRUE if operation has been completed successfully, FALSE otherwise
+    #  @ingroup l2_modif_edit
+    def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
+        return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
+
+    ## Creates a hole in a mesh by doubling the nodes of some particular elements
+    #  @param theElems - the list of elements (edges or faces) to be replicated
+    #         The nodes for duplication could be found from these elements
+    #  @param theNodesNot - list of nodes to NOT replicate
+    #  @param theShape - shape to detect affected elements (element which geometric center
+    #         located on or inside shape).
+    #         The replicated nodes should be associated to affected elements.
+    #  @return TRUE if operation has been completed successfully, FALSE otherwise
+    #  @ingroup l2_modif_edit
+    def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
+        return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
+
+    ## Creates a hole in a mesh by doubling the nodes of some particular elements
+    #  This method provided for convenience works as DoubleNodes() described above.
+    #  @param theElems - group of of elements (edges or faces) to be replicated
+    #  @param theNodesNot - group of nodes not to replicated
+    #  @param theAffectedElems - group of elements to which the replicated nodes
+    #         should be associated to.
+    #  @param theMakeGroup forces the generation of a group containing new elements.
+    #  @param theMakeNodeGroup forces the generation of a group containing new nodes.
+    #  @return TRUE or created groups (one or two) if operation has been completed successfully,
+    #          FALSE or None otherwise
+    #  @ingroup l2_modif_edit
+    def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems,
+                             theMakeGroup=False, theMakeNodeGroup=False):
+        if theMakeGroup or theMakeNodeGroup:
+            twoGroups = self.editor.DoubleNodeElemGroup2New(theElems, theNodesNot,
+                                                            theAffectedElems,
+                                                            theMakeGroup, theMakeNodeGroup)
+            if theMakeGroup and theMakeNodeGroup:
+                return twoGroups
+            else:
+                return twoGroups[ int(theMakeNodeGroup) ]
+        return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems)
+
+    ## Creates a hole in a mesh by doubling the nodes of some particular elements
+    #  This method provided for convenience works as DoubleNodes() described above.
+    #  @param theElems - group of of elements (edges or faces) to be replicated
+    #  @param theNodesNot - group of nodes not to replicated
+    #  @param theShape - shape to detect affected elements (element which geometric center
+    #         located on or inside shape).
+    #         The replicated nodes should be associated to affected elements.
+    #  @ingroup l2_modif_edit
+    def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
+        return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
+
+    ## Creates a hole in a mesh by doubling the nodes of some particular elements
+    #  This method provided for convenience works as DoubleNodes() described above.
+    #  @param theElems - list of groups of elements (edges or faces) to be replicated
+    #  @param theNodesNot - list of groups of nodes not to replicated
+    #  @param theAffectedElems - group of elements to which the replicated nodes
+    #         should be associated to.
+    #  @param theMakeGroup forces the generation of a group containing new elements.
+    #  @param theMakeNodeGroup forces the generation of a group containing new nodes.
+    #  @return TRUE or created groups (one or two) if operation has been completed successfully,
+    #          FALSE or None otherwise
+    #  @ingroup l2_modif_edit
+    def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems,
+                             theMakeGroup=False, theMakeNodeGroup=False):
+        if theMakeGroup or theMakeNodeGroup:
+            twoGroups = self.editor.DoubleNodeElemGroups2New(theElems, theNodesNot,
+                                                             theAffectedElems,
+                                                             theMakeGroup, theMakeNodeGroup)
+            if theMakeGroup and theMakeNodeGroup:
+                return twoGroups
+            else:
+                return twoGroups[ int(theMakeNodeGroup) ]
+        return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems)
+
+    ## Creates a hole in a mesh by doubling the nodes of some particular elements
+    #  This method provided for convenience works as DoubleNodes() described above.
+    #  @param theElems - list of groups of elements (edges or faces) to be replicated
+    #  @param theNodesNot - list of groups of nodes not to replicated
+    #  @param theShape - shape to detect affected elements (element which geometric center
+    #         located on or inside shape).
+    #         The replicated nodes should be associated to affected elements.
+    #  @return TRUE if operation has been completed successfully, FALSE otherwise
+    #  @ingroup l2_modif_edit
+    def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
+        return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
+
+    ## Double nodes on shared faces between groups of volumes and create flat elements on demand.
+    # The list of groups must describe a partition of the mesh volumes.
+    # The nodes of the internal faces at the boundaries of the groups are doubled.
+    # In option, the internal faces are replaced by flat elements.
+    # Triangles are transformed in prisms, and quadrangles in hexahedrons.
+    # @param theDomains - list of groups of volumes
+    # @param createJointElems - if TRUE, create the elements
+    # @return TRUE if operation has been completed successfully, FALSE otherwise
+    def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems ):
+       return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems )
+
+    ## Double nodes on some external faces and create flat elements.
+    # Flat elements are mainly used by some types of mechanic calculations.
+    #
+    # Each group of the list must be constituted of faces.
+    # Triangles are transformed in prisms, and quadrangles in hexahedrons.
+    # @param theGroupsOfFaces - list of groups of faces
+    # @return TRUE if operation has been completed successfully, FALSE otherwise
+    def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ):
+        return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces )
+
+    def _valueFromFunctor(self, funcType, elemId):
+        fn = self.smeshpyD.GetFunctor(funcType)
+        fn.SetMesh(self.mesh)
+        if fn.GetElementType() == self.GetElementType(elemId, True):
+            val = fn.GetValue(elemId)
+        else:
+            val = 0
+        return val
+
+    ## Get length of 1D element.
+    #  @param elemId mesh element ID
+    #  @return element's length value
+    #  @ingroup l1_measurements
+    def GetLength(self, elemId):
+        return self._valueFromFunctor(SMESH.FT_Length, elemId)
+
+    ## Get area of 2D element.
+    #  @param elemId mesh element ID
+    #  @return element's area value
+    #  @ingroup l1_measurements
+    def GetArea(self, elemId):
+        return self._valueFromFunctor(SMESH.FT_Area, elemId)
+
+    ## Get volume of 3D element.
+    #  @param elemId mesh element ID
+    #  @return element's volume value
+    #  @ingroup l1_measurements
+    def GetVolume(self, elemId):
+        return self._valueFromFunctor(SMESH.FT_Volume3D, elemId)
+
+    ## Get maximum element length.
+    #  @param elemId mesh element ID
+    #  @return element's maximum length value
+    #  @ingroup l1_measurements
+    def GetMaxElementLength(self, elemId):
+        if self.GetElementType(elemId, True) == SMESH.VOLUME:
+            ftype = SMESH.FT_MaxElementLength3D
+        else:
+            ftype = SMESH.FT_MaxElementLength2D
+        return self._valueFromFunctor(ftype, elemId)
+
+    ## Get aspect ratio of 2D or 3D element.
+    #  @param elemId mesh element ID
+    #  @return element's aspect ratio value
+    #  @ingroup l1_measurements
+    def GetAspectRatio(self, elemId):
+        if self.GetElementType(elemId, True) == SMESH.VOLUME:
+            ftype = SMESH.FT_AspectRatio3D
+        else:
+            ftype = SMESH.FT_AspectRatio
+        return self._valueFromFunctor(ftype, elemId)
+
+    ## Get warping angle of 2D element.
+    #  @param elemId mesh element ID
+    #  @return element's warping angle value
+    #  @ingroup l1_measurements
+    def GetWarping(self, elemId):
+        return self._valueFromFunctor(SMESH.FT_Warping, elemId)
+
+    ## Get minimum angle of 2D element.
+    #  @param elemId mesh element ID
+    #  @return element's minimum angle value
+    #  @ingroup l1_measurements
+    def GetMinimumAngle(self, elemId):
+        return self._valueFromFunctor(SMESH.FT_MinimumAngle, elemId)
+
+    ## Get taper of 2D element.
+    #  @param elemId mesh element ID
+    #  @return element's taper value
+    #  @ingroup l1_measurements
+    def GetTaper(self, elemId):
+        return self._valueFromFunctor(SMESH.FT_Taper, elemId)
+
+    ## Get skew of 2D element.
+    #  @param elemId mesh element ID
+    #  @return element's skew value
+    #  @ingroup l1_measurements
+    def GetSkew(self, elemId):
+        return self._valueFromFunctor(SMESH.FT_Skew, elemId)
+
 ## The mother class to define algorithm, it is not recommended to use it directly.
 #
-#  More details.
+#  For each meshing algorithm, a python class inheriting from class Mesh_Algorithm
+#  should be defined. This descendant class sould have two attributes defining the way
+# it is created by class Mesh (see e.g. class StdMeshersDC_Segment in StdMeshersDC.py).
+# - meshMethod attribute defines name of method of class Mesh by calling which the
+#   python class of algorithm is created. E.g. if in class MyPlugin_Algorithm
+#   meshMethod = "MyAlgorithm", then an instance of MyPlugin_Algorithm is created
+#   by the following code: my_algo = mesh.MyAlgorithm()
+# - algoType defines name of algorithm type and is used mostly to discriminate
+#   algorithms that are created by the same method of class Mesh. E.g. if
+#   MyPlugin_Algorithm.algoType = "MyPLUGIN" then it's creation code can be:
+#   my_algo = mesh.MyAlgorithm(algo="MyPLUGIN")
 #  @ingroup l2_algorithms
 class Mesh_Algorithm:
     #  @class Mesh_Algorithm
@@ -3366,6 +4148,7 @@ class Mesh_Algorithm:
     #  @return SMESH.SMESH_Algo
     def FindAlgorithm (self, algoname, smeshpyD):
         study = smeshpyD.GetCurrentStudy()
+        if not study: return None
         #to do: find component by smeshpyD object, not by its data type
         scomp = study.FindComponent(smeshpyD.ComponentDataType())
         if scomp is not None:
@@ -3444,20 +4227,22 @@ class Mesh_Algorithm:
         if geom is None:
             raise RuntimeError, "Attemp to create " + algo + " algoritm on None shape"
         self.mesh = mesh
-        piece = mesh.geom
+        name = ""
         if not geom:
-            self.geom = piece
+            self.geom = mesh.geom
         else:
             self.geom = geom
-            name = GetName(geom)
-            if name==NO_NAME:
-                name = mesh.geompyD.SubShapeName(geom, piece)
-                mesh.geompyD.addToStudyInFather(piece, geom, name)
+            AssureGeomPublished( mesh, geom )
+            try:
+                name = GetName(geom)
+                pass
+            except:
+                pass
             self.subm = mesh.mesh.GetSubMesh(geom, algo.GetName())
-
         self.algo = algo
         status = mesh.mesh.AddHypothesis(self.geom, self.algo)
-        TreatHypoStatus( status, algo.GetName(), GetName(self.geom), True )
+        TreatHypoStatus( status, algo.GetName(), name, True )
+        return
 
     def CompareHyp (self, hyp, args):
         print "CompareHyp is not implemented for ", self.__class__.__name__, ":", hyp.GetName()
@@ -3478,1521 +4263,183 @@ class Mesh_Algorithm:
             hypo = self.mesh.smeshpyD.CreateHypothesis(hyp, so)
             a = ""
             s = "="
-            i = 0
-            n = len(args)
-            while i<n:
-                a = a + s + str(args[i])
+            for arg in args:
+                argStr = str(arg)
+                if isinstance( arg, geompyDC.GEOM._objref_GEOM_Object ):
+                    argStr = arg.GetStudyEntry()
+                    if not argStr: argStr = "GEOM_Obj_%s", arg.GetEntry()
+                if len( argStr ) > 10:
+                    argStr = argStr[:7]+"..."
+                    if argStr[0] == '[': argStr += ']'
+                a = a + s + argStr
                 s = ","
-                i = i + 1
                 pass
+            if len(a) > 50:
+                a = a[:47]+"..."
             self.mesh.smeshpyD.SetName(hypo, hyp + a)
             pass
+        geomName=""
+        if self.geom:
+            geomName = GetName(self.geom)
         status = self.mesh.mesh.AddHypothesis(self.geom, hypo)
-        TreatHypoStatus( status, GetName(hypo), GetName(self.geom), 0 )
+        TreatHypoStatus( status, GetName(hypo), geomName, 0 )
         return hypo
 
-
-# Public class: Mesh_Segment
-# --------------------------
-
-## Class to define a segment 1D algorithm for discretization
-#
-#  More details.
-#  @ingroup l3_algos_basic
-class Mesh_Segment(Mesh_Algorithm):
-
-    ## Private constructor.
-    def __init__(self, mesh, geom=0):
-        Mesh_Algorithm.__init__(self)
-        self.Create(mesh, geom, "Regular_1D")
-
-    ## Defines "LocalLength" hypothesis to cut an edge in several segments with the same length
-    #  @param l for the length of segments that cut an edge
-    #  @param UseExisting if ==true - searches for an  existing hypothesis created with
-    #                    the same parameters, else (default) - creates a new one
-    #  @param p precision, used for calculation of the number of segments.
-    #           The precision should be a positive, meaningful value within the range [0,1].
-    #           In general, the number of segments is calculated with the formula:
-    #           nb = ceil((edge_length / l) - p)
-    #           Function ceil rounds its argument to the higher integer.
-    #           So, p=0 means rounding of (edge_length / l) to the higher integer,
-    #               p=0.5 means rounding of (edge_length / l) to the nearest integer,
-    #               p=1 means rounding of (edge_length / l) to the lower integer.
-    #           Default value is 1e-07.
-    #  @return an instance of StdMeshers_LocalLength hypothesis
-    #  @ingroup l3_hypos_1dhyps
-    def LocalLength(self, l, UseExisting=0, p=1e-07):
-        hyp = self.Hypothesis("LocalLength", [l,p], UseExisting=UseExisting,
-                              CompareMethod=self.CompareLocalLength)
-        hyp.SetLength(l)
-        hyp.SetPrecision(p)
-        return hyp
-
-    ## Private method
-    ## Checks if the given "LocalLength" hypothesis has the same parameters as the given arguments
-    def CompareLocalLength(self, hyp, args):
-        if IsEqual(hyp.GetLength(), args[0]):
-            return IsEqual(hyp.GetPrecision(), args[1])
-        return False
-
-    ## Defines "MaxSize" hypothesis to cut an edge into segments not longer than given value
-    #  @param length is optional maximal allowed length of segment, if it is omitted
-    #                the preestimated length is used that depends on geometry size
-    #  @param UseExisting if ==true - searches for an existing hypothesis created with
-    #                     the same parameters, else (default) - create a new one
-    #  @return an instance of StdMeshers_MaxLength hypothesis
-    #  @ingroup l3_hypos_1dhyps
-    def MaxSize(self, length=0.0, UseExisting=0):
-        hyp = self.Hypothesis("MaxLength", [length], UseExisting=UseExisting)
-        if length > 0.0:
-            # set given length
-            hyp.SetLength(length)
-        if not UseExisting:
-            # set preestimated length
-            gen = self.mesh.smeshpyD
-            initHyp = gen.GetHypothesisParameterValues("MaxLength", "libStdMeshersEngine.so",
-                                                       self.mesh.GetMesh(), self.mesh.GetShape(),
-                                                       False) # <- byMesh
-            preHyp = initHyp._narrow(StdMeshers.StdMeshers_MaxLength)
-            if preHyp:
-                hyp.SetPreestimatedLength( preHyp.GetPreestimatedLength() )
-                pass
-            pass
-        hyp.SetUsePreestimatedLength( length == 0.0 )
-        return hyp
-        
-    ## Defines "NumberOfSegments" hypothesis to cut an edge in a fixed number of segments
-    #  @param n for the number of segments that cut an edge
-    #  @param s for the scale factor (optional)
-    #  @param UseExisting if ==true - searches for an existing hypothesis created with
-    #                     the same parameters, else (default) - create a new one
-    #  @return an instance of StdMeshers_NumberOfSegments hypothesis
-    #  @ingroup l3_hypos_1dhyps
-    def NumberOfSegments(self, n, s=[], UseExisting=0):
-        if s == []:
-            hyp = self.Hypothesis("NumberOfSegments", [n], UseExisting=UseExisting,
-                                  CompareMethod=self.CompareNumberOfSegments)
-        else:
-            hyp = self.Hypothesis("NumberOfSegments", [n,s], UseExisting=UseExisting,
-                                  CompareMethod=self.CompareNumberOfSegments)
-            hyp.SetDistrType( 1 )
-            hyp.SetScaleFactor(s)
-        hyp.SetNumberOfSegments(n)
-        return hyp
-
-    ## Private method
-    ## Checks if the given "NumberOfSegments" hypothesis has the same parameters as the given arguments
-    def CompareNumberOfSegments(self, hyp, args):
-        if hyp.GetNumberOfSegments() == args[0]:
-            if len(args) == 1:
-                return True
-            else:
-                if hyp.GetDistrType() == 1:
-                    if IsEqual(hyp.GetScaleFactor(), args[1]):
-                        return True
-        return False
-
-    ## Defines "Arithmetic1D" hypothesis to cut an edge in several segments with increasing arithmetic length
-    #  @param start defines the length of the first segment
-    #  @param end   defines the length of the last  segment
-    #  @param UseExisting if ==true - searches for an existing hypothesis created with
-    #                     the same parameters, else (default) - creates a new one
-    #  @return an instance of StdMeshers_Arithmetic1D hypothesis
-    #  @ingroup l3_hypos_1dhyps
-    def Arithmetic1D(self, start, end, UseExisting=0):
-        hyp = self.Hypothesis("Arithmetic1D", [start, end], UseExisting=UseExisting,
-                              CompareMethod=self.CompareArithmetic1D)
-        hyp.SetLength(start, 1)
-        hyp.SetLength(end  , 0)
-        return hyp
-
-    ## Private method
-    ## Check if the given "Arithmetic1D" hypothesis has the same parameters as the given arguments
-    def CompareArithmetic1D(self, hyp, args):
-        if IsEqual(hyp.GetLength(1), args[0]):
-            if IsEqual(hyp.GetLength(0), args[1]):
-                return True
-        return False
-
-    ## Defines "StartEndLength" hypothesis to cut an edge in several segments with increasing geometric length
-    #  @param start defines the length of the first segment
-    #  @param end   defines the length of the last  segment
-    #  @param UseExisting if ==true - searches for an existing hypothesis created with
-    #                     the same parameters, else (default) - creates a new one
-    #  @return an instance of StdMeshers_StartEndLength hypothesis
-    #  @ingroup l3_hypos_1dhyps
-    def StartEndLength(self, start, end, UseExisting=0):
-        hyp = self.Hypothesis("StartEndLength", [start, end], UseExisting=UseExisting,
-                              CompareMethod=self.CompareStartEndLength)
-        hyp.SetLength(start, 1)
-        hyp.SetLength(end  , 0)
-        return hyp
-
-    ## Check if the given "StartEndLength" hypothesis has the same parameters as the given arguments
-    def CompareStartEndLength(self, hyp, args):
-        if IsEqual(hyp.GetLength(1), args[0]):
-            if IsEqual(hyp.GetLength(0), args[1]):
-                return True
-        return False
-
-    ## Defines "Deflection1D" hypothesis
-    #  @param d for the deflection
-    #  @param UseExisting if ==true - searches for an existing hypothesis created with
-    #                     the same parameters, else (default) - create a new one
-    #  @ingroup l3_hypos_1dhyps
-    def Deflection1D(self, d, UseExisting=0):
-        hyp = self.Hypothesis("Deflection1D", [d], UseExisting=UseExisting,
-                              CompareMethod=self.CompareDeflection1D)
-        hyp.SetDeflection(d)
-        return hyp
-
-    ## Check if the given "Deflection1D" hypothesis has the same parameters as the given arguments
-    def CompareDeflection1D(self, hyp, args):
-        return IsEqual(hyp.GetDeflection(), args[0])
-
-    ## Defines "Propagation" hypothesis that propagates all other hypotheses on all other edges that are at
-    #  the opposite side in case of quadrangular faces
-    #  @ingroup l3_hypos_additi
-    def Propagation(self):
-        return self.Hypothesis("Propagation", UseExisting=1, CompareMethod=self.CompareEqualHyp)
-
-    ## Defines "AutomaticLength" hypothesis
-    #  @param fineness for the fineness [0-1]
-    #  @param UseExisting if ==true - searches for an existing hypothesis created with the
-    #                     same parameters, else (default) - create a new one
-    #  @ingroup l3_hypos_1dhyps
-    def AutomaticLength(self, fineness=0, UseExisting=0):
-        hyp = self.Hypothesis("AutomaticLength",[fineness],UseExisting=UseExisting,
-                              CompareMethod=self.CompareAutomaticLength)
-        hyp.SetFineness( fineness )
-        return hyp
-
-    ## Checks if the given "AutomaticLength" hypothesis has the same parameters as the given arguments
-    def CompareAutomaticLength(self, hyp, args):
-        return IsEqual(hyp.GetFineness(), args[0])
-
-    ## Defines "SegmentLengthAroundVertex" hypothesis
-    #  @param length for the segment length
-    #  @param vertex for the length localization: the vertex index [0,1] | vertex object.
-    #         Any other integer value means that the hypothesis will be set on the
-    #         whole 1D shape, where Mesh_Segment algorithm is assigned.
-    #  @param UseExisting if ==true - searches for an  existing hypothesis created with
-    #                   the same parameters, else (default) - creates a new one
-    #  @ingroup l3_algos_segmarv
-    def LengthNearVertex(self, length, vertex=0, UseExisting=0):
-        import types
-        store_geom = self.geom
-        if type(vertex) is types.IntType:
-            if vertex == 0 or vertex == 1:
-                vertex = self.mesh.geompyD.SubShapeAllSorted(self.geom, geompyDC.ShapeType["VERTEX"])[vertex]
-                self.geom = vertex
-                pass
-            pass
-        else:
-            self.geom = vertex
-            pass
-        ### 0D algorithm
-        if self.geom is None:
-            raise RuntimeError, "Attemp to create SegmentAroundVertex_0D algoritm on None shape"
-        name = GetName(self.geom)
-        if name == NO_NAME:
-            piece = self.mesh.geom
-            name = self.mesh.geompyD.SubShapeName(self.geom, piece)
-            self.mesh.geompyD.addToStudyInFather(piece, self.geom, name)
-        algo = self.FindAlgorithm("SegmentAroundVertex_0D", self.mesh.smeshpyD)
-        if algo is None:
-            algo = self.mesh.smeshpyD.CreateHypothesis("SegmentAroundVertex_0D", "libStdMeshersEngine.so")
-            pass
-        status = self.mesh.mesh.AddHypothesis(self.geom, algo)
-        TreatHypoStatus(status, "SegmentAroundVertex_0D", name, True)
-        ###
-        hyp = self.Hypothesis("SegmentLengthAroundVertex", [length], UseExisting=UseExisting,
-                              CompareMethod=self.CompareLengthNearVertex)
-        self.geom = store_geom
-        hyp.SetLength( length )
-        return hyp
-
-    ## Checks if the given "LengthNearVertex" hypothesis has the same parameters as the given arguments
-    #  @ingroup l3_algos_segmarv
-    def CompareLengthNearVertex(self, hyp, args):
-        return IsEqual(hyp.GetLength(), args[0])
-
-    ## Defines "QuadraticMesh" hypothesis, forcing construction of quadratic edges.
-    #  If the 2D mesher sees that all boundary edges are quadratic,
-    #  it generates quadratic faces, else it generates linear faces using
-    #  medium nodes as if they are vertices.
-    #  The 3D mesher generates quadratic volumes only if all boundary faces
-    #  are quadratic, else it fails.
-    #
+    ## Returns entry of the shape to mesh in the study
+    def MainShapeEntry(self):
+        if not self.mesh or not self.mesh.GetMesh(): return ""
+        if not self.mesh.GetMesh().HasShapeToMesh(): return ""
+        shape = self.mesh.GetShape()
+        return shape.GetStudyEntry()
+
+    ## Defines "ViscousLayers" hypothesis to give parameters of layers of prisms to build
+    #  near mesh boundary. This hypothesis can be used by several 3D algorithms:
+    #  NETGEN 3D, GHS3D, Hexahedron(i,j,k)
+    #  @param thickness total thickness of layers of prisms
+    #  @param numberOfLayers number of layers of prisms
+    #  @param stretchFactor factor (>1.0) of growth of layer thickness towards inside of mesh
+    #  @param ignoreFaces list of geometrical faces (or their ids) not to generate layers on
     #  @ingroup l3_hypos_additi
-    def QuadraticMesh(self):
-        hyp = self.Hypothesis("QuadraticMesh", UseExisting=1, CompareMethod=self.CompareEqualHyp)
+    def ViscousLayers(self, thickness, numberOfLayers, stretchFactor, ignoreFaces=[]):
+        if not isinstance(self.algo, SMESH._objref_SMESH_3D_Algo):
+            raise TypeError, "ViscousLayers are supported by 3D algorithms only"
+        if not "ViscousLayers" in self.GetCompatibleHypothesis():
+            raise TypeError, "ViscousLayers are not supported by %s"%self.algo.GetName()
+        if ignoreFaces and isinstance( ignoreFaces[0], geompyDC.GEOM._objref_GEOM_Object ):
+            ignoreFaces = [ self.mesh.geompyD.GetSubShapeID(self.mesh.geom, f) for f in ignoreFaces ]
+        hyp = self.Hypothesis("ViscousLayers",
+                              [thickness, numberOfLayers, stretchFactor, ignoreFaces])
+        hyp.SetTotalThickness(thickness)
+        hyp.SetNumberLayers(numberOfLayers)
+        hyp.SetStretchFactor(stretchFactor)
+        hyp.SetIgnoreFaces(ignoreFaces)
         return hyp
 
-# Public class: Mesh_CompositeSegment
-# --------------------------
-
-## Defines a segment 1D algorithm for discretization
-#
-#  @ingroup l3_algos_basic
-class Mesh_CompositeSegment(Mesh_Segment):
-
-    ## Private constructor.
-    def __init__(self, mesh, geom=0):
-        self.Create(mesh, geom, "CompositeSegment_1D")
-
-
-# Public class: Mesh_Segment_Python
-# ---------------------------------
-
-## Defines a segment 1D algorithm for discretization with python function
-#
-#  @ingroup l3_algos_basic
-class Mesh_Segment_Python(Mesh_Segment):
-
-    ## Private constructor.
-    def __init__(self, mesh, geom=0):
-        import Python1dPlugin
-        self.Create(mesh, geom, "Python_1D", "libPython1dEngine.so")
-
-    ## Defines "PythonSplit1D" hypothesis
-    #  @param n for the number of segments that cut an edge
-    #  @param func for the python function that calculates the length of all segments
-    #  @param UseExisting if ==true - searches for the existing hypothesis created with
-    #                     the same parameters, else (default) - creates a new one
+    ## Transform a list of ether edges or tuples (edge, 1st_vertex_of_edge)
+    #  into a list acceptable to SetReversedEdges() of some 1D hypotheses
     #  @ingroup l3_hypos_1dhyps
-    def PythonSplit1D(self, n, func, UseExisting=0):
-        hyp = self.Hypothesis("PythonSplit1D", [n], "libPython1dEngine.so",
-                              UseExisting=UseExisting, CompareMethod=self.ComparePythonSplit1D)
-        hyp.SetNumberOfSegments(n)
-        hyp.SetPythonLog10RatioFunction(func)
-        return hyp
-
-    ## Checks if the given "PythonSplit1D" hypothesis has the same parameters as the given arguments
-    def ComparePythonSplit1D(self, hyp, args):
-        #if hyp.GetNumberOfSegments() == args[0]:
-        #    if hyp.GetPythonLog10RatioFunction() == args[1]:
-        #        return True
-        return False
-
-# Public class: Mesh_Triangle
-# ---------------------------
-
-## Defines a triangle 2D algorithm
-#
-#  @ingroup l3_algos_basic
-class Mesh_Triangle(Mesh_Algorithm):
-
-    # default values
-    algoType = 0
-    params = 0
-
-    _angleMeshS = 8
-    _gradation  = 1.1
-
-    ## Private constructor.
-    def __init__(self, mesh, algoType, geom=0):
-        Mesh_Algorithm.__init__(self)
-
-        self.algoType = algoType
-        if algoType == MEFISTO:
-            self.Create(mesh, geom, "MEFISTO_2D")
-            pass
-        elif algoType == BLSURF:
-            import BLSURFPlugin
-            self.Create(mesh, geom, "BLSURF", "libBLSURFEngine.so")
-            #self.SetPhysicalMesh() - PAL19680
-        elif algoType == NETGEN:
-            if noNETGENPlugin:
-                print "Warning: NETGENPlugin module unavailable"
-                pass
-            self.Create(mesh, geom, "NETGEN_2D", "libNETGENEngine.so")
-            pass
-        elif algoType == NETGEN_2D:
-            if noNETGENPlugin:
-                print "Warning: NETGENPlugin module unavailable"
-                pass
-            self.Create(mesh, geom, "NETGEN_2D_ONLY", "libNETGENEngine.so")
-            pass
-
-    ## Defines "MaxElementArea" hypothesis basing on the definition of the maximum area of each triangle
-    #  @param area for the maximum area of each triangle
-    #  @param UseExisting if ==true - searches for an  existing hypothesis created with the
-    #                     same parameters, else (default) - creates a new one
-    #
-    #  Only for algoType == MEFISTO || NETGEN_2D
-    #  @ingroup l3_hypos_2dhyps
-    def MaxElementArea(self, area, UseExisting=0):
-        if self.algoType == MEFISTO or self.algoType == NETGEN_2D:
-            hyp = self.Hypothesis("MaxElementArea", [area], UseExisting=UseExisting,
-                                  CompareMethod=self.CompareMaxElementArea)
-        elif self.algoType == NETGEN:
-            hyp = self.Parameters(SIMPLE)
-        hyp.SetMaxElementArea(area)
-        return hyp
-
-    ## Checks if the given "MaxElementArea" hypothesis has the same parameters as the given arguments
-    def CompareMaxElementArea(self, hyp, args):
-        return IsEqual(hyp.GetMaxElementArea(), args[0])
-
-    ## Defines "LengthFromEdges" hypothesis to build triangles
-    #  based on the length of the edges taken from the wire
-    #
-    #  Only for algoType == MEFISTO || NETGEN_2D
-    #  @ingroup l3_hypos_2dhyps
-    def LengthFromEdges(self):
-        if self.algoType == MEFISTO or self.algoType == NETGEN_2D:
-            hyp = self.Hypothesis("LengthFromEdges", UseExisting=1, CompareMethod=self.CompareEqualHyp)
-            return hyp
-        elif self.algoType == NETGEN:
-            hyp = self.Parameters(SIMPLE)
-            hyp.LengthFromEdges()
-            return hyp
-
-    ## Sets a way to define size of mesh elements to generate.
-    #  @param thePhysicalMesh is: DefaultSize or Custom.
-    #  @ingroup l3_hypos_blsurf
-    def SetPhysicalMesh(self, thePhysicalMesh=DefaultSize):
-        # Parameter of BLSURF algo
-        self.Parameters().SetPhysicalMesh(thePhysicalMesh)
-
-    ## Sets size of mesh elements to generate.
-    #  @ingroup l3_hypos_blsurf
-    def SetPhySize(self, theVal):
-        # Parameter of BLSURF algo
-        self.Parameters().SetPhySize(theVal)
-
-    ## Sets lower boundary of mesh element size (PhySize).
-    #  @ingroup l3_hypos_blsurf
-    def SetPhyMin(self, theVal=-1):
-        #  Parameter of BLSURF algo
-        self.Parameters().SetPhyMin(theVal)
-
-    ## Sets upper boundary of mesh element size (PhySize).
-    #  @ingroup l3_hypos_blsurf
-    def SetPhyMax(self, theVal=-1):
-        #  Parameter of BLSURF algo
-        self.Parameters().SetPhyMax(theVal)
-
-    ## Sets a way to define maximum angular deflection of mesh from CAD model.
-    #  @param theGeometricMesh is: DefaultGeom or Custom
-    #  @ingroup l3_hypos_blsurf
-    def SetGeometricMesh(self, theGeometricMesh=0):
-        #  Parameter of BLSURF algo
-        if self.Parameters().GetPhysicalMesh() == 0: theGeometricMesh = 1
-        self.params.SetGeometricMesh(theGeometricMesh)
-
-    ## Sets angular deflection (in degrees) of a mesh face from CAD surface.
-    #  @ingroup l3_hypos_blsurf
-    def SetAngleMeshS(self, theVal=_angleMeshS):
-        #  Parameter of BLSURF algo
-        if self.Parameters().GetGeometricMesh() == 0: theVal = self._angleMeshS
-        self.params.SetAngleMeshS(theVal)
-
-    ## Sets angular deflection (in degrees) of a mesh edge from CAD curve.
-    #  @ingroup l3_hypos_blsurf
-    def SetAngleMeshC(self, theVal=_angleMeshS):
-        #  Parameter of BLSURF algo
-        if self.Parameters().GetGeometricMesh() == 0: theVal = self._angleMeshS
-        self.params.SetAngleMeshC(theVal)
-
-    ## Sets lower boundary of mesh element size computed to respect angular deflection.
-    #  @ingroup l3_hypos_blsurf
-    def SetGeoMin(self, theVal=-1):
-        #  Parameter of BLSURF algo
-        self.Parameters().SetGeoMin(theVal)
-
-    ## Sets upper boundary of mesh element size computed to respect angular deflection.
-    #  @ingroup l3_hypos_blsurf
-    def SetGeoMax(self, theVal=-1):
-        #  Parameter of BLSURF algo
-        self.Parameters().SetGeoMax(theVal)
-
-    ## Sets maximal allowed ratio between the lengths of two adjacent edges.
-    #  @ingroup l3_hypos_blsurf
-    def SetGradation(self, theVal=_gradation):
-        #  Parameter of BLSURF algo
-        if self.Parameters().GetGeometricMesh() == 0: theVal = self._gradation
-        self.params.SetGradation(theVal)
-
-    ## Sets topology usage way.
-    # @param way defines how mesh conformity is assured <ul>
-    # <li>FromCAD - mesh conformity is assured by conformity of a shape</li>
-    # <li>PreProcess or PreProcessPlus - by pre-processing a CAD model</li></ul>
-    #  @ingroup l3_hypos_blsurf
-    def SetTopology(self, way):
-        #  Parameter of BLSURF algo
-        self.Parameters().SetTopology(way)
-
-    ## To respect geometrical edges or not.
-    #  @ingroup l3_hypos_blsurf
-    def SetDecimesh(self, toIgnoreEdges=False):
-        #  Parameter of BLSURF algo
-        self.Parameters().SetDecimesh(toIgnoreEdges)
-
-    ## Sets verbosity level in the range 0 to 100.
-    #  @ingroup l3_hypos_blsurf
-    def SetVerbosity(self, level):
-        #  Parameter of BLSURF algo
-        self.Parameters().SetVerbosity(level)
-
-    ## Sets advanced option value.
-    #  @ingroup l3_hypos_blsurf
-    def SetOptionValue(self, optionName, level):
-        #  Parameter of BLSURF algo
-        self.Parameters().SetOptionValue(optionName,level)
-
-    ## Sets QuadAllowed flag.
-    #  Only for algoType == NETGEN || NETGEN_2D || BLSURF
-    #  @ingroup l3_hypos_netgen l3_hypos_blsurf
-    def SetQuadAllowed(self, toAllow=True):
-        if self.algoType == NETGEN_2D:
-            if toAllow: # add QuadranglePreference
-                self.Hypothesis("QuadranglePreference", UseExisting=1, CompareMethod=self.CompareEqualHyp)
-            else:       # remove QuadranglePreference
-                for hyp in self.mesh.GetHypothesisList( self.geom ):
-                    if hyp.GetName() == "QuadranglePreference":
-                        self.mesh.RemoveHypothesis( self.geom, hyp )
-                        pass
-                    pass
-                pass
-            return
-        if self.Parameters():
-            self.params.SetQuadAllowed(toAllow)
-            return
-
-    ## Defines hypothesis having several parameters
-    #
-    #  @ingroup l3_hypos_netgen
-    def Parameters(self, which=SOLE):
-        if self.params:
-            return self.params
-        if self.algoType == NETGEN:
-            if which == SIMPLE:
-                self.params = self.Hypothesis("NETGEN_SimpleParameters_2D", [],
-                                              "libNETGENEngine.so", UseExisting=0)
+    def ReversedEdgeIndices(self, reverseList):
+        resList = []
+        geompy = self.mesh.geompyD
+        for i in reverseList:
+            if isinstance( i, int ):
+                s = geompy.SubShapes(self.mesh.geom, [i])[0]
+                if s.GetShapeType() != geompyDC.GEOM.EDGE:
+                    raise TypeError, "Not EDGE index given"
+                resList.append( i )
+            elif isinstance( i, geompyDC.GEOM._objref_GEOM_Object ):
+                if i.GetShapeType() != geompyDC.GEOM.EDGE:
+                    raise TypeError, "Not an EDGE given"
+                resList.append( geompy.GetSubShapeID(self.mesh.geom, i ))
+            elif len( i ) > 1:
+                e = i[0]
+                v = i[1]
+                if not isinstance( e, geompyDC.GEOM._objref_GEOM_Object ) or \
+                   not isinstance( v, geompyDC.GEOM._objref_GEOM_Object ):
+                    raise TypeError, "A list item must be a tuple (edge, 1st_vertex_of_edge)"
+                if v.GetShapeType() == geompyDC.GEOM.EDGE and \
+                   e.GetShapeType() == geompyDC.GEOM.VERTEX:
+                    v,e = e,v
+                if e.GetShapeType() != geompyDC.GEOM.EDGE or \
+                   v.GetShapeType() != geompyDC.GEOM.VERTEX:
+                    raise TypeError, "A list item must be a tuple (edge, 1st_vertex_of_edge)"
+                vFirst = FirstVertexOnCurve( e )
+                tol    = geompy.Tolerance( vFirst )[-1]
+                if geompy.MinDistance( v, vFirst ) > 1.5*tol:
+                    resList.append( geompy.GetSubShapeID(self.mesh.geom, e ))
             else:
-                self.params = self.Hypothesis("NETGEN_Parameters_2D", [],
-                                              "libNETGENEngine.so", UseExisting=0)
-            return self.params
-        elif self.algoType == MEFISTO:
-            print "Mefisto algo support no multi-parameter hypothesis"
-            return None
-        elif self.algoType == NETGEN_2D:
-            print "NETGEN_2D_ONLY algo support no multi-parameter hypothesis"
-            print "NETGEN_2D_ONLY uses 'MaxElementArea' and 'LengthFromEdges' ones"
-            return None
-        elif self.algoType == BLSURF:
-            self.params = self.Hypothesis("BLSURF_Parameters", [],
-                                          "libBLSURFEngine.so", UseExisting=0)
-            return self.params
-        else:
-            print "Mesh_Triangle with algo type %s does not have such a parameter, check algo type"%self.algoType
-        return None
-
-    ## Sets MaxSize
-    #
-    #  Only for algoType == NETGEN
-    #  @ingroup l3_hypos_netgen
-    def SetMaxSize(self, theSize):
-        if self.Parameters():
-            self.params.SetMaxSize(theSize)
-
-    ## Sets SecondOrder flag
-    #
-    #  Only for algoType == NETGEN
-    #  @ingroup l3_hypos_netgen
-    def SetSecondOrder(self, theVal):
-        if self.Parameters():
-            self.params.SetSecondOrder(theVal)
+                raise TypeError, "Item must be either an edge or tuple (edge, 1st_vertex_of_edge)"
+        return resList
 
-    ## Sets Optimize flag
-    #
-    #  Only for algoType == NETGEN
-    #  @ingroup l3_hypos_netgen
-    def SetOptimize(self, theVal):
-        if self.Parameters():
-            self.params.SetOptimize(theVal)
-
-    ## Sets Fineness
-    #  @param theFineness is:
-    #  VeryCoarse, Coarse, Moderate, Fine, VeryFine or Custom
-    #
-    #  Only for algoType == NETGEN
-    #  @ingroup l3_hypos_netgen
-    def SetFineness(self, theFineness):
-        if self.Parameters():
-            self.params.SetFineness(theFineness)
-
-    ## Sets GrowthRate
-    #
-    #  Only for algoType == NETGEN
-    #  @ingroup l3_hypos_netgen
-    def SetGrowthRate(self, theRate):
-        if self.Parameters():
-            self.params.SetGrowthRate(theRate)
-
-    ## Sets NbSegPerEdge
-    #
-    #  Only for algoType == NETGEN
-    #  @ingroup l3_hypos_netgen
-    def SetNbSegPerEdge(self, theVal):
-        if self.Parameters():
-            self.params.SetNbSegPerEdge(theVal)
-
-    ## Sets NbSegPerRadius
-    #
-    #  Only for algoType == NETGEN
-    #  @ingroup l3_hypos_netgen
-    def SetNbSegPerRadius(self, theVal):
-        if self.Parameters():
-            self.params.SetNbSegPerRadius(theVal)
-
-    ## Sets number of segments overriding value set by SetLocalLength()
-    #
-    #  Only for algoType == NETGEN
-    #  @ingroup l3_hypos_netgen
-    def SetNumberOfSegments(self, theVal):
-        self.Parameters(SIMPLE).SetNumberOfSegments(theVal)
 
-    ## Sets number of segments overriding value set by SetNumberOfSegments()
-    #
-    #  Only for algoType == NETGEN
-    #  @ingroup l3_hypos_netgen
-    def SetLocalLength(self, theVal):
-        self.Parameters(SIMPLE).SetLocalLength(theVal)
-
-    pass
+class Pattern(SMESH._objref_SMESH_Pattern):
 
+    def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
+        decrFun = lambda i: i-1
+        theNodeIndexOnKeyPoint1,Parameters,hasVars = ParseParameters(theNodeIndexOnKeyPoint1, decrFun)
+        theMesh.SetParameters(Parameters)
+        return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
 
-# Public class: Mesh_Quadrangle
-# -----------------------------
+    def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
+        decrFun = lambda i: i-1
+        theNode000Index,theNode001Index,Parameters,hasVars = ParseParameters(theNode000Index,theNode001Index, decrFun)
+        theMesh.SetParameters(Parameters)
+        return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
 
-## Defines a quadrangle 2D algorithm
-#
-#  @ingroup l3_algos_basic
-class Mesh_Quadrangle(Mesh_Algorithm):
+#Registering the new proxy for Pattern
+omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
 
-    ## Private constructor.
-    def __init__(self, mesh, geom=0):
-        Mesh_Algorithm.__init__(self)
-        self.Create(mesh, geom, "Quadrangle_2D")
 
-    ## Defines "QuadranglePreference" hypothesis, forcing construction
-    #  of quadrangles if the number of nodes on the opposite edges is not the same
-    #  while the total number of nodes on edges is even
-    #
-    #  @ingroup l3_hypos_additi
-    def QuadranglePreference(self):
-        hyp = self.Hypothesis("QuadranglePreference", UseExisting=1,
-                              CompareMethod=self.CompareEqualHyp)
-        return hyp
 
-    ## Defines "TrianglePreference" hypothesis, forcing construction
-    #  of triangles in the refinement area if the number of nodes
-    #  on the opposite edges is not the same
-    #
-    #  @ingroup l3_hypos_additi
-    def TrianglePreference(self):
-        hyp = self.Hypothesis("TrianglePreference", UseExisting=1,
-                              CompareMethod=self.CompareEqualHyp)
-        return hyp
 
-# Public class: Mesh_Tetrahedron
-# ------------------------------
 
-## Defines a tetrahedron 3D algorithm
+## Private class used to bind methods creating algorithms to the class Mesh
 #
-#  @ingroup l3_algos_basic
-class Mesh_Tetrahedron(Mesh_Algorithm):
-
-    params = 0
-    algoType = 0
-
-    ## Private constructor.
-    def __init__(self, mesh, algoType, geom=0):
-        Mesh_Algorithm.__init__(self)
-
-        if algoType == NETGEN:
-            self.Create(mesh, geom, "NETGEN_3D", "libNETGENEngine.so")
-            pass
-
-        elif algoType == FULL_NETGEN:
-            if noNETGENPlugin:
-                print "Warning: NETGENPlugin module has not been imported."
-            self.Create(mesh, geom, "NETGEN_2D3D", "libNETGENEngine.so")
-            pass
-
-        elif algoType == GHS3D:
-            import GHS3DPlugin
-            self.Create(mesh, geom, "GHS3D_3D" , "libGHS3DEngine.so")
-            pass
-
-        elif algoType == GHS3DPRL:
-            import GHS3DPRLPlugin
-            self.Create(mesh, geom, "GHS3DPRL_3D" , "libGHS3DPRLEngine.so")
-            pass
-
-        self.algoType = algoType
-
-    ## Defines "MaxElementVolume" hypothesis to give the maximun volume of each tetrahedron
-    #  @param vol for the maximum volume of each tetrahedron
-    #  @param UseExisting if ==true - searches for the existing hypothesis created with
-    #                   the same parameters, else (default) - creates a new one
-    #  @ingroup l3_hypos_maxvol
-    def MaxElementVolume(self, vol, UseExisting=0):
-        if self.algoType == NETGEN:
-            hyp = self.Hypothesis("MaxElementVolume", [vol], UseExisting=UseExisting,
-                                  CompareMethod=self.CompareMaxElementVolume)
-            hyp.SetMaxElementVolume(vol)
-            return hyp
-        elif self.algoType == FULL_NETGEN:
-            self.Parameters(SIMPLE).SetMaxElementVolume(vol)
-        return None
-
-    ## Checks if the given "MaxElementVolume" hypothesis has the same parameters as the given arguments
-    def CompareMaxElementVolume(self, hyp, args):
-        return IsEqual(hyp.GetMaxElementVolume(), args[0])
-
-    ## Defines hypothesis having several parameters
-    #
-    #  @ingroup l3_hypos_netgen
-    def Parameters(self, which=SOLE):
-        if self.params:
-            return self.params
-
-        if self.algoType == FULL_NETGEN:
-            if which == SIMPLE:
-                self.params = self.Hypothesis("NETGEN_SimpleParameters_3D", [],
-                                              "libNETGENEngine.so", UseExisting=0)
-            else:
-                self.params = self.Hypothesis("NETGEN_Parameters", [],
-                                              "libNETGENEngine.so", UseExisting=0)
-            return self.params
-
-        if self.algoType == GHS3D:
-            self.params = self.Hypothesis("GHS3D_Parameters", [],
-                                          "libGHS3DEngine.so", UseExisting=0)
-            return self.params
-
-        if self.algoType == GHS3DPRL:
-            self.params = self.Hypothesis("GHS3DPRL_Parameters", [],
-                                          "libGHS3DPRLEngine.so", UseExisting=0)
-            return self.params
-
-        print "Algo supports no multi-parameter hypothesis"
+class algoCreator:
+    def __init__(self):
+        self.mesh = None
+        self.defaultAlgoType = ""
+        self.algoTypeToClass = {}
+
+    # Stores a python class of algorithm
+    def add(self, algoClass):
+        if type( algoClass ).__name__ == 'classobj' and \
+           hasattr( algoClass, "algoType"):
+            self.algoTypeToClass[ algoClass.algoType ] = algoClass
+            if not self.defaultAlgoType and \
+               hasattr( algoClass, "isDefault") and algoClass.isDefault:
+                self.defaultAlgoType = algoClass.algoType
+            #print "Add",algoClass.algoType, "dflt",self.defaultAlgoType
+
+    # creates a copy of self and assign mesh to the copy
+    def copy(self, mesh):
+        other = algoCreator()
+        other.defaultAlgoType = self.defaultAlgoType
+        other.algoTypeToClass  = self.algoTypeToClass
+        other.mesh = mesh
+        return other
+
+    # creates an instance of algorithm
+    def __call__(self,algo="",geom=0,*args):
+        algoType = self.defaultAlgoType
+        for arg in args + (algo,geom):
+            if isinstance( arg, geompyDC.GEOM._objref_GEOM_Object ):
+                geom = arg
+            if isinstance( arg, str ) and arg:
+                algoType = arg
+        if not algoType and self.algoTypeToClass:
+            algoType = self.algoTypeToClass.keys()[0]
+        if self.algoTypeToClass.has_key( algoType ):
+            #print "Create algo",algoType
+            return self.algoTypeToClass[ algoType ]( self.mesh, geom )
+        raise RuntimeError, "No class found for algo type %s" % algoType
         return None
 
-    ## Sets MaxSize
-    #  Parameter of FULL_NETGEN
-    #  @ingroup l3_hypos_netgen
-    def SetMaxSize(self, theSize):
-        self.Parameters().SetMaxSize(theSize)
-
-    ## Sets SecondOrder flag
-    #  Parameter of FULL_NETGEN
-    #  @ingroup l3_hypos_netgen
-    def SetSecondOrder(self, theVal):
-        self.Parameters().SetSecondOrder(theVal)
-
-    ## Sets Optimize flag
-    #  Parameter of FULL_NETGEN
-    #  @ingroup l3_hypos_netgen
-    def SetOptimize(self, theVal):
-        self.Parameters().SetOptimize(theVal)
-
-    ## Sets Fineness
-    #  @param theFineness is:
-    #  VeryCoarse, Coarse, Moderate, Fine, VeryFine or Custom
-    #  Parameter of FULL_NETGEN
-    #  @ingroup l3_hypos_netgen
-    def SetFineness(self, theFineness):
-        self.Parameters().SetFineness(theFineness)
-
-    ## Sets GrowthRate
-    #  Parameter of FULL_NETGEN
-    #  @ingroup l3_hypos_netgen
-    def SetGrowthRate(self, theRate):
-        self.Parameters().SetGrowthRate(theRate)
-
-    ## Sets NbSegPerEdge
-    #  Parameter of FULL_NETGEN
-    #  @ingroup l3_hypos_netgen
-    def SetNbSegPerEdge(self, theVal):
-        self.Parameters().SetNbSegPerEdge(theVal)
-
-    ## Sets NbSegPerRadius
-    #  Parameter of FULL_NETGEN
-    #  @ingroup l3_hypos_netgen
-    def SetNbSegPerRadius(self, theVal):
-        self.Parameters().SetNbSegPerRadius(theVal)
-
-    ## Sets number of segments overriding value set by SetLocalLength()
-    #  Only for algoType == NETGEN_FULL
-    #  @ingroup l3_hypos_netgen
-    def SetNumberOfSegments(self, theVal):
-        self.Parameters(SIMPLE).SetNumberOfSegments(theVal)
-
-    ## Sets number of segments overriding value set by SetNumberOfSegments()
-    #  Only for algoType == NETGEN_FULL
-    #  @ingroup l3_hypos_netgen
-    def SetLocalLength(self, theVal):
-        self.Parameters(SIMPLE).SetLocalLength(theVal)
-
-    ## Defines "MaxElementArea" parameter of NETGEN_SimpleParameters_3D hypothesis.
-    #  Overrides value set by LengthFromEdges()
-    #  Only for algoType == NETGEN_FULL
-    #  @ingroup l3_hypos_netgen
-    def MaxElementArea(self, area):
-        self.Parameters(SIMPLE).SetMaxElementArea(area)
-
-    ## Defines "LengthFromEdges" parameter of NETGEN_SimpleParameters_3D hypothesis
-    #  Overrides value set by MaxElementArea()
-    #  Only for algoType == NETGEN_FULL
-    #  @ingroup l3_hypos_netgen
-    def LengthFromEdges(self):
-        self.Parameters(SIMPLE).LengthFromEdges()
-
-    ## Defines "LengthFromFaces" parameter of NETGEN_SimpleParameters_3D hypothesis
-    #  Overrides value set by MaxElementVolume()
-    #  Only for algoType == NETGEN_FULL
-    #  @ingroup l3_hypos_netgen
-    def LengthFromFaces(self):
-        self.Parameters(SIMPLE).LengthFromFaces()
-
-    ## To mesh "holes" in a solid or not. Default is to mesh.
-    #  @ingroup l3_hypos_ghs3dh
-    def SetToMeshHoles(self, toMesh):
-        #  Parameter of GHS3D
-        self.Parameters().SetToMeshHoles(toMesh)
-
-    ## Set Optimization level:
-    #   None_Optimization, Light_Optimization, Medium_Optimization, Strong_Optimization.
-    #  Default is Medium_Optimization
-    #  @ingroup l3_hypos_ghs3dh
-    def SetOptimizationLevel(self, level):
-        #  Parameter of GHS3D
-        self.Parameters().SetOptimizationLevel(level)
-
-    ## Maximal size of memory to be used by the algorithm (in Megabytes).
-    #  @ingroup l3_hypos_ghs3dh
-    def SetMaximumMemory(self, MB):
-        #  Advanced parameter of GHS3D
-        self.Parameters().SetMaximumMemory(MB)
-
-    ## Initial size of memory to be used by the algorithm (in Megabytes) in
-    #  automatic memory adjustment mode.
-    #  @ingroup l3_hypos_ghs3dh
-    def SetInitialMemory(self, MB):
-        #  Advanced parameter of GHS3D
-        self.Parameters().SetInitialMemory(MB)
-
-    ## Path to working directory.
-    #  @ingroup l3_hypos_ghs3dh
-    def SetWorkingDirectory(self, path):
-        #  Advanced parameter of GHS3D
-        self.Parameters().SetWorkingDirectory(path)
-
-    ## To keep working files or remove them. Log file remains in case of errors anyway.
-    #  @ingroup l3_hypos_ghs3dh
-    def SetKeepFiles(self, toKeep):
-        #  Advanced parameter of GHS3D and GHS3DPRL
-        self.Parameters().SetKeepFiles(toKeep)
-
-    ## To set verbose level [0-10]. <ul>
-    #<li> 0 - no standard output,
-    #<li> 2 - prints the data, quality statistics of the skin and final meshes and
-    #     indicates when the final mesh is being saved. In addition the software
-    #     gives indication regarding the CPU time.
-    #<li>10 - same as 2 plus the main steps in the computation, quality statistics
-    #     histogram of the skin mesh, quality statistics histogram together with
-    #     the characteristics of the final mesh.</ul>
-    #  @ingroup l3_hypos_ghs3dh
-    def SetVerboseLevel(self, level):
-        #  Advanced parameter of GHS3D
-        self.Parameters().SetVerboseLevel(level)
-
-    ## To create new nodes.
-    #  @ingroup l3_hypos_ghs3dh
-    def SetToCreateNewNodes(self, toCreate):
-        #  Advanced parameter of GHS3D
-        self.Parameters().SetToCreateNewNodes(toCreate)
-
-    ## To use boundary recovery version which tries to create mesh on a very poor
-    #  quality surface mesh.
-    #  @ingroup l3_hypos_ghs3dh
-    def SetToUseBoundaryRecoveryVersion(self, toUse):
-        #  Advanced parameter of GHS3D
-        self.Parameters().SetToUseBoundaryRecoveryVersion(toUse)
-
-    ## Sets command line option as text.
-    #  @ingroup l3_hypos_ghs3dh
-    def SetTextOption(self, option):
-        #  Advanced parameter of GHS3D
-        self.Parameters().SetTextOption(option)
-
-    ## Sets MED files name and path.
-    def SetMEDName(self, value):
-        self.Parameters().SetMEDName(value)
-
-    ## Sets the number of partition of the initial mesh
-    def SetNbPart(self, value):
-        self.Parameters().SetNbPart(value)
-
-    ## When big mesh, start tepal in background
-    def SetBackground(self, value):
-        self.Parameters().SetBackground(value)
-
-# Public class: Mesh_Hexahedron
-# ------------------------------
-
-## Defines a hexahedron 3D algorithm
-#
-#  @ingroup l3_algos_basic
-class Mesh_Hexahedron(Mesh_Algorithm):
-
-    params = 0
-    algoType = 0
-
-    ## Private constructor.
-    def __init__(self, mesh, algoType=Hexa, geom=0):
-        Mesh_Algorithm.__init__(self)
-
-        self.algoType = algoType
-
-        if algoType == Hexa:
-            self.Create(mesh, geom, "Hexa_3D")
-            pass
-
-        elif algoType == Hexotic:
-            import HexoticPlugin
-            self.Create(mesh, geom, "Hexotic_3D", "libHexoticEngine.so")
-            pass
-
-    ## Defines "MinMaxQuad" hypothesis to give three hexotic parameters
-    #  @ingroup l3_hypos_hexotic
-    def MinMaxQuad(self, min=3, max=8, quad=True):
-        self.params = self.Hypothesis("Hexotic_Parameters", [], "libHexoticEngine.so",
-                                      UseExisting=0)
-        self.params.SetHexesMinLevel(min)
-        self.params.SetHexesMaxLevel(max)
-        self.params.SetHexoticQuadrangles(quad)
-        return self.params
-
-# Deprecated, only for compatibility!
-# Public class: Mesh_Netgen
-# ------------------------------
-
-## Defines a NETGEN-based 2D or 3D algorithm
-#  that needs no discrete boundary (i.e. independent)
-#
-#  This class is deprecated, only for compatibility!
-#
-#  More details.
-#  @ingroup l3_algos_basic
-class Mesh_Netgen(Mesh_Algorithm):
-
-    is3D = 0
-
-    ## Private constructor.
-    def __init__(self, mesh, is3D, geom=0):
-        Mesh_Algorithm.__init__(self)
-
-        if noNETGENPlugin:
-            print "Warning: NETGENPlugin module has not been imported."
-
-        self.is3D = is3D
-        if is3D:
-            self.Create(mesh, geom, "NETGEN_2D3D", "libNETGENEngine.so")
-            pass
-
-        else:
-            self.Create(mesh, geom, "NETGEN_2D", "libNETGENEngine.so")
-            pass
-
-    ## Defines the hypothesis containing parameters of the algorithm
-    def Parameters(self):
-        if self.is3D:
-            hyp = self.Hypothesis("NETGEN_Parameters", [],
-                                  "libNETGENEngine.so", UseExisting=0)
-        else:
-            hyp = self.Hypothesis("NETGEN_Parameters_2D", [],
-                                  "libNETGENEngine.so", UseExisting=0)
-        return hyp
-
-# Public class: Mesh_Projection1D
-# ------------------------------
-
-## Defines a projection 1D algorithm
-#  @ingroup l3_algos_proj
-#
-class Mesh_Projection1D(Mesh_Algorithm):
-
-    ## Private constructor.
-    def __init__(self, mesh, geom=0):
-        Mesh_Algorithm.__init__(self)
-        self.Create(mesh, geom, "Projection_1D")
-
-    ## Defines "Source Edge" hypothesis, specifying a meshed edge, from where
-    #  a mesh pattern is taken, and, optionally, the association of vertices
-    #  between the source edge and a target edge (to which a hypothesis is assigned)
-    #  @param edge from which nodes distribution is taken
-    #  @param mesh from which nodes distribution is taken (optional)
-    #  @param srcV a vertex of \a edge to associate with \a tgtV (optional)
-    #  @param tgtV a vertex of \a the edge to which the algorithm is assigned,
-    #  to associate with \a srcV (optional)
-    #  @param UseExisting if ==true - searches for the existing hypothesis created with
-    #                     the same parameters, else (default) - creates a new one
-    def SourceEdge(self, edge, mesh=None, srcV=None, tgtV=None, UseExisting=0):
-        hyp = self.Hypothesis("ProjectionSource1D", [edge,mesh,srcV,tgtV],
-                              UseExisting=0)
-                              #UseExisting=UseExisting, CompareMethod=self.CompareSourceEdge)
-        hyp.SetSourceEdge( edge )
-        if not mesh is None and isinstance(mesh, Mesh):
-            mesh = mesh.GetMesh()
-        hyp.SetSourceMesh( mesh )
-        hyp.SetVertexAssociation( srcV, tgtV )
-        return hyp
-
-    ## Checks if the given "SourceEdge" hypothesis has the same parameters as the given arguments
-    #def CompareSourceEdge(self, hyp, args):
-    #    # it does not seem to be useful to reuse the existing "SourceEdge" hypothesis
-    #    return False
-
-
-# Public class: Mesh_Projection2D
-# ------------------------------
-
-## Defines a projection 2D algorithm
-#  @ingroup l3_algos_proj
-#
-class Mesh_Projection2D(Mesh_Algorithm):
-
-    ## Private constructor.
-    def __init__(self, mesh, geom=0):
-        Mesh_Algorithm.__init__(self)
-        self.Create(mesh, geom, "Projection_2D")
-
-    ## Defines "Source Face" hypothesis, specifying a meshed face, from where
-    #  a mesh pattern is taken, and, optionally, the association of vertices
-    #  between the source face and the target face (to which a hypothesis is assigned)
-    #  @param face from which the mesh pattern is taken
-    #  @param mesh from which the mesh pattern is taken (optional)
-    #  @param srcV1 a vertex of \a face to associate with \a tgtV1 (optional)
-    #  @param tgtV1 a vertex of \a the face to which the algorithm is assigned,
-    #               to associate with \a srcV1 (optional)
-    #  @param srcV2 a vertex of \a face to associate with \a tgtV1 (optional)
-    #  @param tgtV2 a vertex of \a the face to which the algorithm is assigned,
-    #               to associate with \a srcV2 (optional)
-    #  @param UseExisting if ==true - forces the search for the existing hypothesis created with
-    #                     the same parameters, else (default) - forces the creation a new one
-    #
-    #  Note: all association vertices must belong to one edge of a face
-    def SourceFace(self, face, mesh=None, srcV1=None, tgtV1=None,
-                   srcV2=None, tgtV2=None, UseExisting=0):
-        hyp = self.Hypothesis("ProjectionSource2D", [face,mesh,srcV1,tgtV1,srcV2,tgtV2],
-                              UseExisting=0)
-                              #UseExisting=UseExisting, CompareMethod=self.CompareSourceFace)
-        hyp.SetSourceFace( face )
-        if not mesh is None and isinstance(mesh, Mesh):
-            mesh = mesh.GetMesh()
-        hyp.SetSourceMesh( mesh )
-        hyp.SetVertexAssociation( srcV1, srcV2, tgtV1, tgtV2 )
-        return hyp
-
-    ## Checks if the given "SourceFace" hypothesis has the same parameters as the given arguments
-    #def CompareSourceFace(self, hyp, args):
-    #    # it does not seem to be useful to reuse the existing "SourceFace" hypothesis
-    #    return False
-
-# Public class: Mesh_Projection3D
-# ------------------------------
-
-## Defines a projection 3D algorithm
-#  @ingroup l3_algos_proj
-#
-class Mesh_Projection3D(Mesh_Algorithm):
-
-    ## Private constructor.
-    def __init__(self, mesh, geom=0):
-        Mesh_Algorithm.__init__(self)
-        self.Create(mesh, geom, "Projection_3D")
-
-    ## Defines the "Source Shape 3D" hypothesis, specifying a meshed solid, from where
-    #  the mesh pattern is taken, and, optionally, the  association of vertices
-    #  between the source and the target solid  (to which a hipothesis is assigned)
-    #  @param solid from where the mesh pattern is taken
-    #  @param mesh from where the mesh pattern is taken (optional)
-    #  @param srcV1 a vertex of \a solid to associate with \a tgtV1 (optional)
-    #  @param tgtV1 a vertex of \a the solid where the algorithm is assigned,
-    #  to associate with \a srcV1 (optional)
-    #  @param srcV2 a vertex of \a solid to associate with \a tgtV1 (optional)
-    #  @param tgtV2 a vertex of \a the solid to which the algorithm is assigned,
-    #  to associate with \a srcV2 (optional)
-    #  @param UseExisting - if ==true - searches for the existing hypothesis created with
-    #                     the same parameters, else (default) - creates a new one
-    #
-    #  Note: association vertices must belong to one edge of a solid
-    def SourceShape3D(self, solid, mesh=0, srcV1=0, tgtV1=0,
-                      srcV2=0, tgtV2=0, UseExisting=0):
-        hyp = self.Hypothesis("ProjectionSource3D",
-                              [solid,mesh,srcV1,tgtV1,srcV2,tgtV2],
-                              UseExisting=0)
-                              #UseExisting=UseExisting, CompareMethod=self.CompareSourceShape3D)
-        hyp.SetSource3DShape( solid )
-        if not mesh is None and isinstance(mesh, Mesh):
-            mesh = mesh.GetMesh()
-        hyp.SetSourceMesh( mesh )
-        hyp.SetVertexAssociation( srcV1, srcV2, tgtV1, tgtV2 )
-        return hyp
-
-    ## Checks if the given "SourceShape3D" hypothesis has the same parameters as given arguments
-    #def CompareSourceShape3D(self, hyp, args):
-    #    # seems to be not really useful to reuse existing "SourceShape3D" hypothesis
-    #    return False
-
-
-# Public class: Mesh_Prism
-# ------------------------
-
-## Defines a 3D extrusion algorithm
-#  @ingroup l3_algos_3dextr
-#
-class Mesh_Prism3D(Mesh_Algorithm):
-
-    ## Private constructor.
-    def __init__(self, mesh, geom=0):
-        Mesh_Algorithm.__init__(self)
-        self.Create(mesh, geom, "Prism_3D")
-
-# Public class: Mesh_RadialPrism
-# -------------------------------
-
-## Defines a Radial Prism 3D algorithm
-#  @ingroup l3_algos_radialp
-#
-class Mesh_RadialPrism3D(Mesh_Algorithm):
-
-    ## Private constructor.
-    def __init__(self, mesh, geom=0):
-        Mesh_Algorithm.__init__(self)
-        self.Create(mesh, geom, "RadialPrism_3D")
-
-        self.distribHyp = self.Hypothesis("LayerDistribution", UseExisting=0)
-        self.nbLayers = None
-
-    ## Return 3D hypothesis holding the 1D one
-    def Get3DHypothesis(self):
-        return self.distribHyp
-
-    ## Private method creating a 1D hypothesis and storing it in the LayerDistribution
-    #  hypothesis. Returns the created hypothesis
-    def OwnHypothesis(self, hypType, args=[], so="libStdMeshersEngine.so"):
-        #print "OwnHypothesis",hypType
-        if not self.nbLayers is None:
-            self.mesh.GetMesh().RemoveHypothesis( self.geom, self.nbLayers )
-            self.mesh.GetMesh().AddHypothesis( self.geom, self.distribHyp )
-        study = self.mesh.smeshpyD.GetCurrentStudy() # prevents publishing own 1D hypothesis
-        hyp = self.mesh.smeshpyD.CreateHypothesis(hypType, so)
-        self.mesh.smeshpyD.SetCurrentStudy( study ) # enables publishing
-        self.distribHyp.SetLayerDistribution( hyp )
-        return hyp
-
-    ## Defines "NumberOfLayers" hypothesis, specifying the number of layers of
-    #  prisms to build between the inner and outer shells
-    #  @param n number of layers
-    #  @param UseExisting if ==true - searches for the existing hypothesis created with
-    #                     the same parameters, else (default) - creates a new one
-    def NumberOfLayers(self, n, UseExisting=0):
-        self.mesh.GetMesh().RemoveHypothesis( self.geom, self.distribHyp )
-        self.nbLayers = self.Hypothesis("NumberOfLayers", [n], UseExisting=UseExisting,
-                                        CompareMethod=self.CompareNumberOfLayers)
-        self.nbLayers.SetNumberOfLayers( n )
-        return self.nbLayers
-
-    ## Checks if the given "NumberOfLayers" hypothesis has the same parameters as the given arguments
-    def CompareNumberOfLayers(self, hyp, args):
-        return IsEqual(hyp.GetNumberOfLayers(), args[0])
-
-    ## Defines "LocalLength" hypothesis, specifying the segment length
-    #  to build between the inner and the outer shells
-    #  @param l the length of segments
-    #  @param p the precision of rounding
-    def LocalLength(self, l, p=1e-07):
-        hyp = self.OwnHypothesis("LocalLength", [l,p])
-        hyp.SetLength(l)
-        hyp.SetPrecision(p)
-        return hyp
-
-    ## Defines "NumberOfSegments" hypothesis, specifying the number of layers of
-    #  prisms to build between the inner and the outer shells.
-    #  @param n the number of layers
-    #  @param s the scale factor (optional)
-    def NumberOfSegments(self, n, s=[]):
-        if s == []:
-            hyp = self.OwnHypothesis("NumberOfSegments", [n])
-        else:
-            hyp = self.OwnHypothesis("NumberOfSegments", [n,s])
-            hyp.SetDistrType( 1 )
-            hyp.SetScaleFactor(s)
-        hyp.SetNumberOfSegments(n)
-        return hyp
-
-    ## Defines "Arithmetic1D" hypothesis, specifying the distribution of segments
-    #  to build between the inner and the outer shells with a length that changes in arithmetic progression
-    #  @param start  the length of the first segment
-    #  @param end    the length of the last  segment
-    def Arithmetic1D(self, start, end ):
-        hyp = self.OwnHypothesis("Arithmetic1D", [start, end])
-        hyp.SetLength(start, 1)
-        hyp.SetLength(end  , 0)
-        return hyp
-
-    ## Defines "StartEndLength" hypothesis, specifying distribution of segments
-    #  to build between the inner and the outer shells as geometric length increasing
-    #  @param start for the length of the first segment
-    #  @param end   for the length of the last  segment
-    def StartEndLength(self, start, end):
-        hyp = self.OwnHypothesis("StartEndLength", [start, end])
-        hyp.SetLength(start, 1)
-        hyp.SetLength(end  , 0)
-        return hyp
-
-    ## Defines "AutomaticLength" hypothesis, specifying the number of segments
-    #  to build between the inner and outer shells
-    #  @param fineness defines the quality of the mesh within the range [0-1]
-    def AutomaticLength(self, fineness=0):
-        hyp = self.OwnHypothesis("AutomaticLength")
-        hyp.SetFineness( fineness )
-        return hyp
-
-# Private class: Mesh_UseExisting
-# -------------------------------
-class Mesh_UseExisting(Mesh_Algorithm):
-
-    def __init__(self, dim, mesh, geom=0):
-        if dim == 1:
-            self.Create(mesh, geom, "UseExisting_1D")
-        else:
-            self.Create(mesh, geom, "UseExisting_2D")
-
-
-import salome_notebook
-notebook = salome_notebook.notebook
-
-##Return values of the notebook variables
-def ParseParameters(last, nbParams,nbParam, value):
-    result = None
-    strResult = ""
-    counter = 0
-    listSize = len(last)
-    for n in range(0,nbParams):
-        if n+1 != nbParam:
-            if counter < listSize:
-                strResult = strResult + last[counter]
-            else:
-                strResult = strResult + ""
-        else:
-            if isinstance(value, str):
-                if notebook.isVariable(value):
-                    result = notebook.get(value)
-                    strResult=strResult+value
-                else:
-                    raise RuntimeError, "Variable with name '" + value + "' doesn't exist!!!"
-            else:
-                strResult=strResult+str(value)
-                result = value
-        if nbParams - 1 != counter:
-            strResult=strResult+var_separator #":"
-        counter = counter+1
-    return result, strResult
-
-#Wrapper class for StdMeshers_LocalLength hypothesis
-class LocalLength(StdMeshers._objref_StdMeshers_LocalLength):
-
-    ## Set Length parameter value
-    #  @param length numerical value or name of variable from notebook
-    def SetLength(self, length):
-        length,parameters = ParseParameters(StdMeshers._objref_StdMeshers_LocalLength.GetLastParameters(self),2,1,length)
-        StdMeshers._objref_StdMeshers_LocalLength.SetParameters(self,parameters)
-        StdMeshers._objref_StdMeshers_LocalLength.SetLength(self,length)
-
-   ## Set Precision parameter value
-   #  @param precision numerical value or name of variable from notebook
-    def SetPrecision(self, precision):
-        precision,parameters = ParseParameters(StdMeshers._objref_StdMeshers_LocalLength.GetLastParameters(self),2,2,precision)
-        StdMeshers._objref_StdMeshers_LocalLength.SetParameters(self,parameters)
-        StdMeshers._objref_StdMeshers_LocalLength.SetPrecision(self, precision)
-
-#Registering the new proxy for LocalLength
-omniORB.registerObjref(StdMeshers._objref_StdMeshers_LocalLength._NP_RepositoryId, LocalLength)
-
-
-#Wrapper class for StdMeshers_LayerDistribution hypothesis
-class LayerDistribution(StdMeshers._objref_StdMeshers_LayerDistribution):
-    
-    def SetLayerDistribution(self, hypo):
-        StdMeshers._objref_StdMeshers_LayerDistribution.SetParameters(self,hypo.GetParameters())
-        hypo.ClearParameters();
-        StdMeshers._objref_StdMeshers_LayerDistribution.SetLayerDistribution(self,hypo)
-
-#Registering the new proxy for LayerDistribution
-omniORB.registerObjref(StdMeshers._objref_StdMeshers_LayerDistribution._NP_RepositoryId, LayerDistribution)
-
-#Wrapper class for StdMeshers_SegmentLengthAroundVertex hypothesis
-class SegmentLengthAroundVertex(StdMeshers._objref_StdMeshers_SegmentLengthAroundVertex):
-    
-    ## Set Length parameter value
-    #  @param length numerical value or name of variable from notebook    
-    def SetLength(self, length):
-        length,parameters = ParseParameters(StdMeshers._objref_StdMeshers_SegmentLengthAroundVertex.GetLastParameters(self),1,1,length)
-        StdMeshers._objref_StdMeshers_SegmentLengthAroundVertex.SetParameters(self,parameters)
-        StdMeshers._objref_StdMeshers_SegmentLengthAroundVertex.SetLength(self,length)
-
-#Registering the new proxy for SegmentLengthAroundVertex
-omniORB.registerObjref(StdMeshers._objref_StdMeshers_SegmentLengthAroundVertex._NP_RepositoryId, SegmentLengthAroundVertex)
-
-
-#Wrapper class for StdMeshers_Arithmetic1D hypothesis
-class Arithmetic1D(StdMeshers._objref_StdMeshers_Arithmetic1D):
-    
-    ## Set Length parameter value
-    #  @param length   numerical value or name of variable from notebook
-    #  @param isStart  true is length is Start Length, otherwise false
-    def SetLength(self, length, isStart):
-        nb = 2
-        if isStart:
-            nb = 1
-        length,parameters = ParseParameters(StdMeshers._objref_StdMeshers_Arithmetic1D.GetLastParameters(self),2,nb,length)
-        StdMeshers._objref_StdMeshers_Arithmetic1D.SetParameters(self,parameters)
-        StdMeshers._objref_StdMeshers_Arithmetic1D.SetLength(self,length,isStart)
-        
-#Registering the new proxy for Arithmetic1D
-omniORB.registerObjref(StdMeshers._objref_StdMeshers_Arithmetic1D._NP_RepositoryId, Arithmetic1D)
-
-#Wrapper class for StdMeshers_Deflection1D hypothesis
-class Deflection1D(StdMeshers._objref_StdMeshers_Deflection1D):
-    
-    ## Set Deflection parameter value
-    #  @param deflection numerical value or name of variable from notebook    
-    def SetDeflection(self, deflection):
-        deflection,parameters = ParseParameters(StdMeshers._objref_StdMeshers_Deflection1D.GetLastParameters(self),1,1,deflection)
-        StdMeshers._objref_StdMeshers_Deflection1D.SetParameters(self,parameters)
-        StdMeshers._objref_StdMeshers_Deflection1D.SetDeflection(self,deflection)
-
-#Registering the new proxy for Deflection1D
-omniORB.registerObjref(StdMeshers._objref_StdMeshers_Deflection1D._NP_RepositoryId, Deflection1D)
-
-#Wrapper class for StdMeshers_StartEndLength hypothesis
-class StartEndLength(StdMeshers._objref_StdMeshers_StartEndLength):
-    
-    ## Set Length parameter value
-    #  @param length  numerical value or name of variable from notebook
-    #  @param isStart true is length is Start Length, otherwise false
-    def SetLength(self, length, isStart):
-        nb = 2
-        if isStart:
-            nb = 1
-        length,parameters = ParseParameters(StdMeshers._objref_StdMeshers_StartEndLength.GetLastParameters(self),2,nb,length)
-        StdMeshers._objref_StdMeshers_StartEndLength.SetParameters(self,parameters)
-        StdMeshers._objref_StdMeshers_StartEndLength.SetLength(self,length,isStart)
-        
-#Registering the new proxy for StartEndLength
-omniORB.registerObjref(StdMeshers._objref_StdMeshers_StartEndLength._NP_RepositoryId, StartEndLength)
-
-#Wrapper class for StdMeshers_MaxElementArea hypothesis
-class MaxElementArea(StdMeshers._objref_StdMeshers_MaxElementArea):
-    
-    ## Set Max Element Area parameter value
-    #  @param area  numerical value or name of variable from notebook
-    def SetMaxElementArea(self, area):
-        area ,parameters = ParseParameters(StdMeshers._objref_StdMeshers_MaxElementArea.GetLastParameters(self),1,1,area)
-        StdMeshers._objref_StdMeshers_MaxElementArea.SetParameters(self,parameters)
-        StdMeshers._objref_StdMeshers_MaxElementArea.SetMaxElementArea(self,area)
-        
-#Registering the new proxy for MaxElementArea
-omniORB.registerObjref(StdMeshers._objref_StdMeshers_MaxElementArea._NP_RepositoryId, MaxElementArea)
-
-
-#Wrapper class for StdMeshers_MaxElementVolume hypothesis
-class MaxElementVolume(StdMeshers._objref_StdMeshers_MaxElementVolume):
-    
-    ## Set Max Element Volume parameter value
-    #  @param area  numerical value or name of variable from notebook
-    def SetMaxElementVolume(self, volume):
-        volume ,parameters = ParseParameters(StdMeshers._objref_StdMeshers_MaxElementVolume.GetLastParameters(self),1,1,volume)
-        StdMeshers._objref_StdMeshers_MaxElementVolume.SetParameters(self,parameters)
-        StdMeshers._objref_StdMeshers_MaxElementVolume.SetMaxElementVolume(self,volume)
-        
-#Registering the new proxy for MaxElementVolume
-omniORB.registerObjref(StdMeshers._objref_StdMeshers_MaxElementVolume._NP_RepositoryId, MaxElementVolume)
-
-
-#Wrapper class for StdMeshers_NumberOfLayers hypothesis
-class NumberOfLayers(StdMeshers._objref_StdMeshers_NumberOfLayers):
-    
-    ## Set Number Of Layers parameter value
-    #  @param nbLayers  numerical value or name of variable from notebook
-    def SetNumberOfLayers(self, nbLayers):
-        nbLayers ,parameters = ParseParameters(StdMeshers._objref_StdMeshers_NumberOfLayers.GetLastParameters(self),1,1,nbLayers)
-        StdMeshers._objref_StdMeshers_NumberOfLayers.SetParameters(self,parameters)
-        StdMeshers._objref_StdMeshers_NumberOfLayers.SetNumberOfLayers(self,nbLayers)
-        
-#Registering the new proxy for NumberOfLayers
-omniORB.registerObjref(StdMeshers._objref_StdMeshers_NumberOfLayers._NP_RepositoryId, NumberOfLayers)
-
-#Wrapper class for StdMeshers_NumberOfSegments hypothesis
-class NumberOfSegments(StdMeshers._objref_StdMeshers_NumberOfSegments):
-    
-    ## Set Number Of Segments parameter value
-    #  @param nbSeg numerical value or name of variable from notebook
-    def SetNumberOfSegments(self, nbSeg):
-        lastParameters = StdMeshers._objref_StdMeshers_NumberOfSegments.GetLastParameters(self)
-        nbSeg , parameters = ParseParameters(lastParameters,1,1,nbSeg)
-        StdMeshers._objref_StdMeshers_NumberOfSegments.SetParameters(self,parameters)
-        StdMeshers._objref_StdMeshers_NumberOfSegments.SetNumberOfSegments(self,nbSeg)
-        
-    ## Set Scale Factor parameter value
-    #  @param factor numerical value or name of variable from notebook
-    def SetScaleFactor(self, factor):
-        factor, parameters = ParseParameters(StdMeshers._objref_StdMeshers_NumberOfSegments.GetLastParameters(self),2,2,factor)
-        StdMeshers._objref_StdMeshers_NumberOfSegments.SetParameters(self,parameters)
-        StdMeshers._objref_StdMeshers_NumberOfSegments.SetScaleFactor(self,factor)
-        
-#Registering the new proxy for NumberOfSegments
-omniORB.registerObjref(StdMeshers._objref_StdMeshers_NumberOfSegments._NP_RepositoryId, NumberOfSegments)
-
-
-#Wrapper class for NETGENPlugin_Hypothesis hypothesis
-class NETGENPlugin_Hypothesis(NETGENPlugin._objref_NETGENPlugin_Hypothesis):
-
-    ## Set Max Size parameter value
-    #  @param maxsize numerical value or name of variable from notebook
-    def SetMaxSize(self, maxsize):
-        lastParameters = NETGENPlugin._objref_NETGENPlugin_Hypothesis.GetLastParameters(self)
-        maxsize, parameters = ParseParameters(lastParameters,4,1,maxsize)
-        NETGENPlugin._objref_NETGENPlugin_Hypothesis.SetParameters(self,parameters)
-        NETGENPlugin._objref_NETGENPlugin_Hypothesis.SetMaxSize(self,maxsize)
-        
-    ## Set Growth Rate parameter value
-    #  @param value  numerical value or name of variable from notebook
-    def SetGrowthRate(self, value):
-        lastParameters = NETGENPlugin._objref_NETGENPlugin_Hypothesis.GetLastParameters(self)
-        value, parameters = ParseParameters(lastParameters,4,2,value)
-        NETGENPlugin._objref_NETGENPlugin_Hypothesis.SetParameters(self,parameters)
-        NETGENPlugin._objref_NETGENPlugin_Hypothesis.SetGrowthRate(self,value)
-        
-    ## Set Number of Segments per Edge parameter value
-    #  @param value  numerical value or name of variable from notebook
-    def SetNbSegPerEdge(self, value):
-        lastParameters = NETGENPlugin._objref_NETGENPlugin_Hypothesis.GetLastParameters(self)
-        value, parameters = ParseParameters(lastParameters,4,3,value)
-        NETGENPlugin._objref_NETGENPlugin_Hypothesis.SetParameters(self,parameters)
-        NETGENPlugin._objref_NETGENPlugin_Hypothesis.SetNbSegPerEdge(self,value)
-        
-    ## Set Number of Segments per Radius parameter value
-    #  @param value  numerical value or name of variable from notebook
-    def SetNbSegPerRadius(self, value):
-        lastParameters = NETGENPlugin._objref_NETGENPlugin_Hypothesis.GetLastParameters(self)
-        value, parameters = ParseParameters(lastParameters,4,4,value)
-        NETGENPlugin._objref_NETGENPlugin_Hypothesis.SetParameters(self,parameters)
-        NETGENPlugin._objref_NETGENPlugin_Hypothesis.SetNbSegPerRadius(self,value)
-        
-#Registering the new proxy for NETGENPlugin_Hypothesis
-omniORB.registerObjref(NETGENPlugin._objref_NETGENPlugin_Hypothesis._NP_RepositoryId, NETGENPlugin_Hypothesis)
-
-
-#Wrapper class for NETGENPlugin_Hypothesis_2D hypothesis
-class NETGENPlugin_Hypothesis_2D(NETGENPlugin_Hypothesis,NETGENPlugin._objref_NETGENPlugin_Hypothesis_2D):
-    pass
-
-#Registering the new proxy for NETGENPlugin_Hypothesis_2D
-omniORB.registerObjref(NETGENPlugin._objref_NETGENPlugin_Hypothesis_2D._NP_RepositoryId, NETGENPlugin_Hypothesis_2D)
-
-#Wrapper class for NETGENPlugin_SimpleHypothesis_2D hypothesis
-class NETGEN_SimpleParameters_2D(NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D):
-    
-    ## Set Number of Segments parameter value
-    #  @param nbSeg numerical value or name of variable from notebook
-    def SetNumberOfSegments(self, nbSeg):
-        lastParameters = NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D.GetLastParameters(self)
-        nbSeg, parameters = ParseParameters(lastParameters,2,1,nbSeg)
-        NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D.SetParameters(self,parameters)
-        NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D.SetNumberOfSegments(self, nbSeg)
-
-    ## Set Local Length parameter value
-    #  @param length numerical value or name of variable from notebook
-    def SetLocalLength(self, length):
-        lastParameters = NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D.GetLastParameters(self)
-        length, parameters = ParseParameters(lastParameters,2,1,length)
-        NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D.SetParameters(self,parameters)
-        NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D.SetLocalLength(self, length)
-
-    ## Set Max Element Area parameter value
-    #  @param area numerical value or name of variable from notebook    
-    def SetMaxElementArea(self, area):
-        lastParameters = NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D.GetLastParameters(self)
-        area, parameters = ParseParameters(lastParameters,2,2,area)
-        NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D.SetParameters(self,parameters)
-        NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D.SetMaxElementArea(self, area)
-
-    def LengthFromEdges(self):
-        lastParameters = NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D.GetLastParameters(self)
-        value = 0;
-        value, parameters = ParseParameters(lastParameters,2,2,value)
-        NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D.SetParameters(self,parameters)
-        NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D.LengthFromEdges(self)
-        
-#Registering the new proxy for NETGEN_SimpleParameters_2D
-omniORB.registerObjref(NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D._NP_RepositoryId, NETGEN_SimpleParameters_2D)
-
-
-#Wrapper class for NETGENPlugin_SimpleHypothesis_3D hypothesis
-class NETGEN_SimpleParameters_3D(NETGEN_SimpleParameters_2D,NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_3D):
-    ## Set Max Element Volume parameter value
-    #  @param volume numerical value or name of variable from notebook    
-    def SetMaxElementVolume(self, volume):
-        lastParameters = NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_3D.GetLastParameters(self)
-        volume, parameters = ParseParameters(lastParameters,3,3,volume)
-        NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_3D.SetParameters(self,parameters)
-        NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_3D.SetMaxElementVolume(self, volume)
-
-    def LengthFromFaces(self):
-        lastParameters = NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_3D.GetLastParameters(self)
-        value = 0;
-        value, parameters = ParseParameters(lastParameters,3,3,value)
-        NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_3D.SetParameters(self,parameters)
-        NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_3D.LengthFromFaces(self)
-        
-#Registering the new proxy for NETGEN_SimpleParameters_3D
-omniORB.registerObjref(NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_3D._NP_RepositoryId, NETGEN_SimpleParameters_3D)
-
-class Pattern(SMESH._objref_SMESH_Pattern):
+# Private class used to substitute and store variable parameters of hypotheses.
+class hypMethodWrapper:
+    def __init__(self, hyp, method):
+        self.hyp    = hyp
+        self.method = method
+        #print "REBIND:", method.__name__
+        return
 
-    def ApplyToMeshFaces(self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse):
-        flag = False
-        if isinstance(theNodeIndexOnKeyPoint1,str):
-            flag = True
-        theNodeIndexOnKeyPoint1,Parameters = geompyDC.ParseParameters(theNodeIndexOnKeyPoint1)
-        if flag:
-            theNodeIndexOnKeyPoint1 -= 1
-        theMesh.SetParameters(Parameters)
-        return SMESH._objref_SMESH_Pattern.ApplyToMeshFaces( self, theMesh, theFacesIDs, theNodeIndexOnKeyPoint1, theReverse )
+    # call a method of hypothesis with calling SetVarParameter() before
+    def __call__(self,*args):
+        if not args:
+            return self.method( self.hyp, *args ) # hypothesis method with no args
 
-    def ApplyToHexahedrons(self, theMesh, theVolumesIDs, theNode000Index, theNode001Index):
-        flag0 = False
-        flag1 = False
-        if isinstance(theNode000Index,str):
-            flag0 = True
-        if isinstance(theNode001Index,str):
-            flag1 = True
-        theNode000Index,theNode001Index,Parameters = geompyDC.ParseParameters(theNode000Index,theNode001Index)
-        if flag0:
-            theNode000Index -= 1
-        if flag1:
-            theNode001Index -= 1
-        theMesh.SetParameters(Parameters)
-        return SMESH._objref_SMESH_Pattern.ApplyToHexahedrons( self, theMesh, theVolumesIDs, theNode000Index, theNode001Index )
+        #print "MethWrapper.__call__",self.method.__name__, args
+        try:
+            parsed = ParseParameters(*args)     # replace variables with their values
+            self.hyp.SetVarParameter( parsed[-2], self.method.__name__ )
+            result = self.method( self.hyp, *parsed[:-2] ) # call hypothesis method
+        except omniORB.CORBA.BAD_PARAM: # raised by hypothesis method call
+            # maybe there is a replaced string arg which is not variable
+            result = self.method( self.hyp, *args )
+        except ValueError, detail: # raised by ParseParameters()
+            try:
+                result = self.method( self.hyp, *args )
+            except omniORB.CORBA.BAD_PARAM:
+                raise ValueError, detail # wrong variable name
 
-#Registering the new proxy for Pattern
-omniORB.registerObjref(SMESH._objref_SMESH_Pattern._NP_RepositoryId, Pattern)
+        return result
index 69ae00da9e2199edeaeb9edbbc3ffaa0cc9f50bb..ee0248ac14a0d6887a58f0fc2ca79a0d9fddc1a8 100644 (file)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 # SMESH SMESHGUI : GUI for SMESH component
 # File   : Makefile.am
 # Author : Alexander BORODIN, Open CASCADE S.A.S.
@@ -71,9 +69,9 @@ _libSMESH_Swig_la_CPPFLAGS =  \
        $(CORBA_CXXFLAGS)       \
        $(CORBA_INCLUDES)       \
        $(BOOST_CPPFLAGS)       \
+       -I$(srcdir)             \
        -I$(srcdir)/../SMESHGUI \
-       -I$(top_builddir)/idl   \
-       -I$(top_builddir)/salome_adm/unix
+       -I$(top_builddir)/idl
 
 _libSMESH_Swig_la_LDFLAGS  = -module
 _libSMESH_Swig_la_LIBADD   = ../SMESHGUI/libSMESH.la                   \
index 4766864a27e0fffd3c71fac78915af192519b1e7..eca22e91e77323f0d982a7df4b755de0010658b3 100644 (file)
@@ -1,24 +1,22 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  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 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.
 //
-//  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
 //
-//  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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESH : GUI for SMESH component
 // File   : libSMESH_Swig.cxx
 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
@@ -71,10 +69,10 @@ namespace
   inline
   SALOMEDS::SObject_var
   GetDomainRoot(const SALOMEDS::SComponent_var& theSComponentMesh,
-               const SALOMEDS::StudyBuilder_var& theStudyBuilder,
-               CORBA::Long theDomainRootTag,
-               const QString& theName,
-               const QString& thePixmap)
+                const SALOMEDS::StudyBuilder_var& theStudyBuilder,
+                CORBA::Long theDomainRootTag,
+                const QString& theName,
+                const QString& thePixmap)
   {
     SALOMEDS::SObject_var aDomainRoot;
     if (!theSComponentMesh->FindSubObject(theDomainRootTag,aDomainRoot)) {
@@ -98,13 +96,13 @@ namespace
   inline
   SALOMEDS::SObject_var
   GetHypothesisRoot(const SALOMEDS::SComponent_var& theSComponentMesh,
-                   const SALOMEDS::StudyBuilder_var& theStudyBuilder)
+                    const SALOMEDS::StudyBuilder_var& theStudyBuilder)
   {
     return GetDomainRoot(theSComponentMesh,
-                        theStudyBuilder,
-                        SMESH::Tag_HypothesisRoot,
-                        QObject::tr("SMESH_MEN_HYPOTHESIS"),
-                        "ICON_SMESH_TREE_HYPO");
+                         theStudyBuilder,
+                         SMESH::Tag_HypothesisRoot,
+                         QObject::tr("SMESH_MEN_HYPOTHESIS"),
+                         "ICON_SMESH_TREE_HYPO");
   }
 
 
@@ -112,13 +110,13 @@ namespace
   inline
   SALOMEDS::SObject_var
   GetAlgorithmsRoot(const SALOMEDS::SComponent_var& theSComponentMesh,
-                   const SALOMEDS::StudyBuilder_var& theStudyBuilder)
+                    const SALOMEDS::StudyBuilder_var& theStudyBuilder)
   {
     return GetDomainRoot(theSComponentMesh,
-                        theStudyBuilder,
-                        SMESH::Tag_AlgorithmsRoot,
-                        QObject::tr("SMESH_MEN_ALGORITHMS"),
-                        "ICON_SMESH_TREE_ALGO");
+                         theStudyBuilder,
+                         SMESH::Tag_AlgorithmsRoot,
+                         QObject::tr("SMESH_MEN_ALGORITHMS"),
+                         "ICON_SMESH_TREE_ALGO");
   }
 
 
@@ -126,17 +124,17 @@ namespace
   inline
   SALOMEDS::SObject_var
   AddToDomain(const std::string& theIOR,
-             const SALOMEDS::SComponent_var& theSComponentMesh,
-             const SALOMEDS::StudyBuilder_var& theStudyBuilder,
-             CORBA::Long theDomainRootTag,
-             const QString& theDomainName,
-             const QString& theDomainPixmap)
+              const SALOMEDS::SComponent_var& theSComponentMesh,
+              const SALOMEDS::StudyBuilder_var& theStudyBuilder,
+              CORBA::Long theDomainRootTag,
+              const QString& theDomainName,
+              const QString& theDomainPixmap)
   {
     SALOMEDS::SObject_var aDomain = GetDomainRoot(theSComponentMesh,
-                                                 theStudyBuilder,
-                                                 SMESH::Tag_AlgorithmsRoot,
-                                                 theDomainName,
-                                                 theDomainPixmap);
+                                                  theStudyBuilder,
+                                                  SMESH::Tag_AlgorithmsRoot,
+                                                  theDomainName,
+                                                  theDomainPixmap);
     // Add New Hypothesis
     SALOMEDS::SObject_var aSObject = theStudyBuilder->NewObject(aDomain);
     SALOMEDS::GenericAttribute_var anAttr = theStudyBuilder->FindOrCreateAttribute(aSObject,"AttributePixMap");
@@ -157,42 +155,42 @@ namespace
   //---------------------------------------------------------------
   SALOMEDS::SObject_var
   AddHypothesis(const std::string& theIOR,
-               const SALOMEDS::SComponent_var& theSComponentMesh,
-               const SALOMEDS::StudyBuilder_var& theStudyBuilder)
+                const SALOMEDS::SComponent_var& theSComponentMesh,
+                const SALOMEDS::StudyBuilder_var& theStudyBuilder)
   {
     return AddToDomain(theIOR,
-                      theSComponentMesh,
-                      theStudyBuilder,
-                      SMESH::Tag_HypothesisRoot,
-                      QObject::tr("SMESH_MEN_HYPOTHESIS"),
-                      "ICON_SMESH_TREE_HYPO");
+                       theSComponentMesh,
+                       theStudyBuilder,
+                       SMESH::Tag_HypothesisRoot,
+                       QObject::tr("SMESH_MEN_HYPOTHESIS"),
+                       "ICON_SMESH_TREE_HYPO");
   }
 
 
   //---------------------------------------------------------------
   SALOMEDS::SObject_var
   AddAlgorithms(const std::string& theIOR,
-               const SALOMEDS::SComponent_var& theSComponentMesh,
-               const SALOMEDS::StudyBuilder_var& theStudyBuilder)
+                const SALOMEDS::SComponent_var& theSComponentMesh,
+                const SALOMEDS::StudyBuilder_var& theStudyBuilder)
   {
     return AddToDomain(theIOR,
-                      theSComponentMesh,
-                      theStudyBuilder,
-                      SMESH::Tag_AlgorithmsRoot,
-                      QObject::tr("SMESH_MEN_ALGORITHMS"),
-                      "ICON_SMESH_TREE_ALGO");
+                       theSComponentMesh,
+                       theStudyBuilder,
+                       SMESH::Tag_AlgorithmsRoot,
+                       QObject::tr("SMESH_MEN_ALGORITHMS"),
+                       "ICON_SMESH_TREE_ALGO");
   }
 
 
   //---------------------------------------------------------------
   void
   SetDomain(const char* theMeshOrSubMeshEntry,
-           const char* theDomainEntry,
-           const SALOMEDS::Study_var& theStudy,
-           const SALOMEDS::StudyBuilder_var& theStudyBuilder,
-           long theRefOnAppliedDomainTag,
-           const QString& theAppliedDomainMEN,
-           const QString& theAppliedDomainICON)
+            const char* theDomainEntry,
+            const SALOMEDS::Study_var& theStudy,
+            const SALOMEDS::StudyBuilder_var& theStudyBuilder,
+            long theRefOnAppliedDomainTag,
+            const QString& theAppliedDomainMEN,
+            const QString& theAppliedDomainICON)
   {
     SALOMEDS::SObject_var aMeshOrSubMeshSO = theStudy->FindObjectID(theMeshOrSubMeshEntry);
     SALOMEDS::SObject_var aHypothesisSO = theStudy->FindObjectID(theDomainEntry);
@@ -201,17 +199,17 @@ namespace
       //Find or Create Applied Hypothesis root
       SALOMEDS::SObject_var anAppliedDomainSO;
       if(!aMeshOrSubMeshSO->FindSubObject(theRefOnAppliedDomainTag,anAppliedDomainSO)){
-       anAppliedDomainSO = theStudyBuilder->NewObjectToTag(aMeshOrSubMeshSO,theRefOnAppliedDomainTag);
-       SALOMEDS::GenericAttribute_var anAttr =
-         theStudyBuilder->FindOrCreateAttribute(anAppliedDomainSO,"AttributeName");
-       SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
-       aName->SetValue(theAppliedDomainMEN.toLatin1().data());
-       anAttr = theStudyBuilder->FindOrCreateAttribute(anAppliedDomainSO,"AttributeSelectable");
-       SALOMEDS::AttributeSelectable_var aSelAttr = SALOMEDS::AttributeSelectable::_narrow(anAttr);
-       aSelAttr->SetSelectable(false);
-       anAttr = theStudyBuilder->FindOrCreateAttribute(anAppliedDomainSO,"AttributePixMap");
-       SALOMEDS::AttributePixMap_var aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr);
-       aPixmap->SetPixMap(theAppliedDomainICON.toLatin1().data());
+        anAppliedDomainSO = theStudyBuilder->NewObjectToTag(aMeshOrSubMeshSO,theRefOnAppliedDomainTag);
+        SALOMEDS::GenericAttribute_var anAttr =
+          theStudyBuilder->FindOrCreateAttribute(anAppliedDomainSO,"AttributeName");
+        SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
+        aName->SetValue(theAppliedDomainMEN.toLatin1().data());
+        anAttr = theStudyBuilder->FindOrCreateAttribute(anAppliedDomainSO,"AttributeSelectable");
+        SALOMEDS::AttributeSelectable_var aSelAttr = SALOMEDS::AttributeSelectable::_narrow(anAttr);
+        aSelAttr->SetSelectable(false);
+        anAttr = theStudyBuilder->FindOrCreateAttribute(anAppliedDomainSO,"AttributePixMap");
+        SALOMEDS::AttributePixMap_var aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr);
+        aPixmap->SetPixMap(theAppliedDomainICON.toLatin1().data());
       }
       SALOMEDS::SObject_var aSObject = theStudyBuilder->NewObject(anAppliedDomainSO);
       theStudyBuilder->Addreference(aSObject,aHypothesisSO);
@@ -222,34 +220,34 @@ namespace
   //---------------------------------------------------------------
   void
   SetHypothesis(const char* theMeshOrSubMeshEntry,
-               const char* theDomainEntry,
-               const SALOMEDS::Study_var& theStudy,
-               const SALOMEDS::StudyBuilder_var& theStudyBuilder)
+                const char* theDomainEntry,
+                const SALOMEDS::Study_var& theStudy,
+                const SALOMEDS::StudyBuilder_var& theStudyBuilder)
   {
     SetDomain(theMeshOrSubMeshEntry,
-             theDomainEntry,
-             theStudy,
-             theStudyBuilder,
-             SMESH::Tag_RefOnAppliedHypothesis,
-             QObject::tr("SMESH_MEN_APPLIED_HYPOTHESIS"),
-             "ICON_SMESH_TREE_HYPO");
+              theDomainEntry,
+              theStudy,
+              theStudyBuilder,
+              SMESH::Tag_RefOnAppliedHypothesis,
+              QObject::tr("SMESH_MEN_APPLIED_HYPOTHESIS"),
+              "ICON_SMESH_TREE_HYPO");
   }
 
 
   //---------------------------------------------------------------
   void
   SetAlgorithms(const char* theMeshOrSubMeshEntry,
-               const char* theDomainEntry,
-               const SALOMEDS::Study_var& theStudy,
-               const SALOMEDS::StudyBuilder_var& theStudyBuilder)
+                const char* theDomainEntry,
+                const SALOMEDS::Study_var& theStudy,
+                const SALOMEDS::StudyBuilder_var& theStudyBuilder)
   {
     SetDomain(theMeshOrSubMeshEntry,
-             theDomainEntry,
-             theStudy,
-             theStudyBuilder,
-             SMESH::Tag_RefOnAppliedAlgorithms,
-             QObject::tr("SMESH_MEN_APPLIED_ALGORIHTMS"),
-             "ICON_SMESH_TREE_ALGO");
+              theDomainEntry,
+              theStudy,
+              theStudyBuilder,
+              SMESH::Tag_RefOnAppliedAlgorithms,
+              QObject::tr("SMESH_MEN_APPLIED_ALGORIHTMS"),
+              "ICON_SMESH_TREE_ALGO");
   }
 }
 
@@ -271,11 +269,11 @@ SMESH_Swig::SMESH_Swig()
     Execute()
     {
       try {
-       ORB_INIT &anORBInit = *SINGLETON_<ORB_INIT>::Instance();
-       ASSERT(SINGLETON_<ORB_INIT>::IsAlreadyExisting());
-       myORB = anORBInit( 0, 0 );
+        ORB_INIT &anORBInit = *SINGLETON_<ORB_INIT>::Instance();
+        ASSERT(SINGLETON_<ORB_INIT>::IsAlreadyExisting());
+        myORB = anORBInit( 0, 0 );
       } catch (...) {
-       INFOS("internal error : orb not found");
+        INFOS("internal error : orb not found");
       }
     }
   };
@@ -301,9 +299,9 @@ SMESH_Swig::Init(int theStudyID)
     SALOMEDS::SComponent_var& mySComponentMesh;
   public:
     TEvent(int theStudyID,
-          SALOMEDS::Study_var& theStudy,
-          SALOMEDS::StudyBuilder_var& theStudyBuilder,
-          SALOMEDS::SComponent_var& theSComponentMesh):
+           SALOMEDS::Study_var& theStudy,
+           SALOMEDS::StudyBuilder_var& theStudyBuilder,
+           SALOMEDS::SComponent_var& theSComponentMesh):
       myStudyID(theStudyID),
       myStudy(theStudy),
       myStudyBuilder(theStudyBuilder),
@@ -334,28 +332,28 @@ SMESH_Swig::Init(int theStudyID)
 
       SALOMEDS::SComponent_var aSComponent = myStudy->FindComponent("SMESH");
       if(aSComponent->_is_nil()){
-       bool aLocked = myStudy->GetProperties()->IsLocked();
-       if (aLocked)
-         myStudy->GetProperties()->SetLocked(false);
-       
-       aSComponent = myStudyBuilder->NewComponent("SMESH");
-       anAttr = myStudyBuilder->FindOrCreateAttribute(aSComponent,"AttributeName");
-       aName = SALOMEDS::AttributeName::_narrow(anAttr);
-
-       SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI(); //SRN: BugID IPAL9186, load a SMESH gui if it hasn't been loaded
-       if (!aSMESHGUI){
-         CAM_Module* aModule = anApp->module("Mesh");
-         if(!aModule)
-             aModule = anApp->loadModule("Mesh");
-         aSMESHGUI = dynamic_cast<SMESHGUI*>(aModule);
-       } //SRN: BugID IPAL9186: end of a fix
-       aName->SetValue(aSMESHGUI->moduleName().toLatin1().data());
-       anAttr = myStudyBuilder->FindOrCreateAttribute(aSComponent,"AttributePixMap");
-       aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr);
-       aPixmap->SetPixMap( "ICON_OBJBROWSER_SMESH" );
-       myStudyBuilder->DefineComponentInstance(aSComponent,aSMESHGen);
-       if (aLocked)
-         myStudy->GetProperties()->SetLocked(true);
+        bool aLocked = myStudy->GetProperties()->IsLocked();
+        if (aLocked)
+          myStudy->GetProperties()->SetLocked(false);
+        
+        aSComponent = myStudyBuilder->NewComponent("SMESH");
+        anAttr = myStudyBuilder->FindOrCreateAttribute(aSComponent,"AttributeName");
+        aName = SALOMEDS::AttributeName::_narrow(anAttr);
+
+        SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI(); //SRN: BugID IPAL9186, load a SMESH gui if it hasn't been loaded
+        if (!aSMESHGUI){
+          CAM_Module* aModule = anApp->module("Mesh");
+          if(!aModule)
+              aModule = anApp->loadModule("Mesh");
+          aSMESHGUI = dynamic_cast<SMESHGUI*>(aModule);
+        } //SRN: BugID IPAL9186: end of a fix
+        aName->SetValue(aSMESHGUI->moduleName().toLatin1().data());
+        anAttr = myStudyBuilder->FindOrCreateAttribute(aSComponent,"AttributePixMap");
+        aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr);
+        aPixmap->SetPixMap( "ICON_OBJBROWSER_SMESH" );
+        myStudyBuilder->DefineComponentInstance(aSComponent,aSMESHGen);
+        if (aLocked)
+          myStudy->GetProperties()->SetLocked(true);
       }
 
       mySComponentMesh = SALOMEDS::SComponent::_narrow(aSComponent);
@@ -367,9 +365,9 @@ SMESH_Swig::Init(int theStudyID)
   MESSAGE("Init");
 
   ProcessVoidEvent(new TEvent(theStudyID,
-                             myStudy,
-                             myStudyBuilder,
-                             mySComponentMesh));
+                              myStudy,
+                              myStudyBuilder,
+                              mySComponentMesh));
 }
 
 
@@ -414,8 +412,8 @@ const char* SMESH_Swig::AddNewHypothesis(const char* theIOR)
   MESSAGE("AddNewHypothesis");
 
   SALOMEDS::SObject_var aSObject = ::AddHypothesis(theIOR,
-                                                  mySComponentMesh,
-                                                  myStudyBuilder);
+                                                   mySComponentMesh,
+                                                   myStudyBuilder);
   CORBA::String_var anEntry = aSObject->GetID();
   return anEntry._retn();
 }
@@ -427,8 +425,8 @@ const char* SMESH_Swig::AddNewAlgorithms(const char* theIOR)
   MESSAGE("AddNewAlgorithms");
 
   SALOMEDS::SObject_var aSObject = ::AddAlgorithms(theIOR,
-                                                  mySComponentMesh,
-                                                  myStudyBuilder);
+                                                   mySComponentMesh,
+                                                   myStudyBuilder);
   CORBA::String_var anEntry = aSObject->GetID();
   return anEntry._retn();
 }
@@ -453,9 +451,9 @@ void SMESH_Swig::SetHypothesis(const char* theMeshOrSubMeshEntry,
                                const char* theDomainEntry)
 {
   ::SetHypothesis(theMeshOrSubMeshEntry,
-                 theDomainEntry,
-                 myStudy,
-                 myStudyBuilder);
+                  theDomainEntry,
+                  myStudy,
+                  myStudyBuilder);
 }
 
 
@@ -464,9 +462,9 @@ void SMESH_Swig::SetAlgorithms(const char* theMeshOrSubMeshEntry,
                                const char* theDomainEntry)
 {
   ::SetAlgorithms(theMeshOrSubMeshEntry,
-                 theDomainEntry,
-                 myStudy,
-                 myStudyBuilder);
+                  theDomainEntry,
+                  myStudy,
+                  myStudyBuilder);
 }
 
 
@@ -599,7 +597,7 @@ void SMESH_Swig::SetName(const char* theEntry,
 //================================================================================
 
 void SMESH_Swig::SetMeshIcon(const char* theMeshEntry,
-                            const bool theIsComputed,
+                             const bool theIsComputed,
                              const bool isEmpty)
 {
   class TEvent: public SALOME_Event
@@ -609,8 +607,8 @@ void SMESH_Swig::SetMeshIcon(const char* theMeshEntry,
     bool myIsComputed, myIsEmpty;
   public:
     TEvent(const SALOMEDS::Study_var& theStudy,
-          const std::string& theMeshEntry,
-          const bool theIsComputed,
+           const std::string& theMeshEntry,
+           const bool theIsComputed,
            const bool isEmpty):
       myStudy(theStudy),
       myMeshEntry(theMeshEntry),
@@ -624,13 +622,13 @@ void SMESH_Swig::SetMeshIcon(const char* theMeshEntry,
     {
       SALOMEDS::SObject_var aMeshSO = myStudy->FindObjectID(myMeshEntry.c_str());
       if(!aMeshSO->_is_nil())
-       if(_PTR(SObject) aMesh = ClientFactory::SObject(aMeshSO))
-         SMESH::ModifiedMesh(aMesh,myIsComputed,myIsEmpty);
+        if(_PTR(SObject) aMesh = ClientFactory::SObject(aMeshSO))
+          SMESH::ModifiedMesh(aMesh,myIsComputed,myIsEmpty);
     }
   };
 
   ProcessVoidEvent(new TEvent(myStudy,
-                             theMeshEntry,
-                             theIsComputed,
+                              theMeshEntry,
+                              theIsComputed,
                               isEmpty));
 }
index a288506a1b499431ef7a67393ff7cec3d840714d..4a7b8e719a8e2e949c5a4bcfff223fdd9ec3febd 100644 (file)
@@ -1,24 +1,22 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  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 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.
 //
-//  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
 //
-//  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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESH : GUI for SMESH component
 // File   : libSMESH_Swig.h
 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
@@ -27,7 +25,7 @@
 #define LIBSMESH_SWIG_H
 
 #ifdef WNT
-#if defined SMESH_SWIG_EXPORTS
+#if defined SMESH_SWIG_EXPORTS || defined _libSMESH_Swig_EXPORTS
   #define SMESH_SWIG_EXPORT __declspec( dllexport )
  #else
   #define SMESH_SWIG_EXPORT __declspec( dllimport )
index a865a8e95da0a084f014e27c0c0952e7a8db5ae0..52d2bb87fa4aab38309d362f30de565b0ed4f809 100644 (file)
@@ -1,24 +1,22 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  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 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.
 //
-//  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
 //
-//  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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : libSMESH_Swig.i
 // Author : Nicolas REJNERI, Open CASCADE S.A.S.
index 8b86e09585b936e2d7f716f3799875343ed189e6..e831115fa0fa62d2afc4bc91b6ae74b182accc67 100644 (file)
@@ -1,24 +1,22 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  SMESH StdMeshers : implementaion of SMESH idl descriptions
 #  File   : Makefile.in
 #  Author : Julia DOROVSKIKH
@@ -32,6 +30,7 @@ salomeinclude_HEADERS = \
        StdMeshers_LocalLength.hxx \
        StdMeshers_StartEndLength.hxx \
        StdMeshers_Arithmetic1D.hxx \
+       StdMeshers_FixedPoints1D.hxx \
        StdMeshers_NumberOfSegments.hxx \
        StdMeshers_Deflection1D.hxx \
        StdMeshers_Propagation.hxx \
@@ -49,6 +48,7 @@ salomeinclude_HEADERS = \
        StdMeshers_QuadranglePreference.hxx \
        StdMeshers_QuadraticMesh.hxx \
        StdMeshers_NumberOfLayers.hxx \
+       StdMeshers_NumberOfLayers2D.hxx \
        StdMeshers_Prism_3D.hxx \
        StdMeshers_ProjectionSource1D.hxx \
        StdMeshers_ProjectionSource2D.hxx \
@@ -59,6 +59,7 @@ salomeinclude_HEADERS = \
        StdMeshers_RadialPrism_3D.hxx  \
        StdMeshers_ProjectionUtils.hxx \
        StdMeshers_LayerDistribution.hxx \
+       StdMeshers_LayerDistribution2D.hxx \
        StdMeshers_SegmentAroundVertex_0D.hxx \
        StdMeshers_SegmentLengthAroundVertex.hxx \
        StdMeshers_FaceSide.hxx \
@@ -66,9 +67,18 @@ salomeinclude_HEADERS = \
        StdMeshers_UseExisting_1D2D.hxx \
        StdMeshers_QuadToTriaAdaptor.hxx \
        SMESH_StdMeshers.hxx \
-       StdMeshers_TrianglePreference.hxx \
        StdMeshers_CompositeHexa_3D.hxx \
-       StdMeshers_MaxLength.hxx
+       StdMeshers_MaxLength.hxx \
+       StdMeshers_QuadrangleParams.hxx \
+       StdMeshers_RadialQuadrangle_1D2D.hxx \
+       StdMeshers_HexaFromSkin_3D.hxx \
+       StdMeshers_ImportSource.hxx \
+       StdMeshers_Import_1D.hxx \
+       StdMeshers_Import_1D2D.hxx \
+       StdMeshers_ViscousLayers.hxx \
+       StdMeshers_Projection_1D2D.hxx \
+       StdMeshers_CartesianParameters3D.hxx \
+       StdMeshers_Cartesian_3D.hxx
 
 # Libraries targets
 
@@ -78,6 +88,7 @@ dist_libStdMeshers_la_SOURCES = \
        StdMeshers_LocalLength.cxx \
        StdMeshers_StartEndLength.cxx \
        StdMeshers_Arithmetic1D.cxx \
+       StdMeshers_FixedPoints1D.cxx \
        StdMeshers_NumberOfSegments.cxx \
        StdMeshers_Deflection1D.cxx \
        StdMeshers_Propagation.cxx \
@@ -95,6 +106,7 @@ dist_libStdMeshers_la_SOURCES = \
        StdMeshers_QuadranglePreference.cxx \
        StdMeshers_QuadraticMesh.cxx \
        StdMeshers_NumberOfLayers.cxx \
+       StdMeshers_NumberOfLayers2D.cxx \
        StdMeshers_Prism_3D.cxx \
        StdMeshers_ProjectionSource1D.cxx \
        StdMeshers_ProjectionSource2D.cxx \
@@ -105,25 +117,35 @@ dist_libStdMeshers_la_SOURCES = \
        StdMeshers_RadialPrism_3D.cxx \
        StdMeshers_ProjectionUtils.cxx \
        StdMeshers_LayerDistribution.cxx \
+       StdMeshers_LayerDistribution2D.cxx \
        StdMeshers_SegmentAroundVertex_0D.cxx \
        StdMeshers_SegmentLengthAroundVertex.cxx \
        StdMeshers_FaceSide.cxx \
        StdMeshers_CompositeSegment_1D.cxx \
        StdMeshers_UseExisting_1D2D.cxx \
        StdMeshers_QuadToTriaAdaptor.cxx \
-       StdMeshers_TrianglePreference.cxx \
        StdMeshers_CompositeHexa_3D.cxx \
-       StdMeshers_MaxLength.cxx
-
+       StdMeshers_MaxLength.cxx \
+       StdMeshers_QuadrangleParams.cxx \
+       StdMeshers_RadialQuadrangle_1D2D.cxx \
+       StdMeshers_HexaFromSkin_3D.cxx \
+       StdMeshers_ImportSource.cxx \
+       StdMeshers_Import_1D.cxx \
+       StdMeshers_Import_1D2D.cxx \
+       StdMeshers_ViscousLayers.cxx \
+       StdMeshers_Projection_1D2D.cxx \
+       StdMeshers_CartesianParameters3D.cxx \
+       StdMeshers_Cartesian_3D.cxx
 
 # additionnal information to compil and link file
 libStdMeshers_la_CPPFLAGS = \
        $(CAS_CPPFLAGS) \
        $(BOOST_CPPFLAGS) \
+        $(VTK_INCLUDES) \
        $(KERNEL_CXXFLAGS) \
        $(GUI_CXXFLAGS) \
-       -I$(srcdir)/../SMESHImpl \
        -I$(srcdir)/../MEFISTO2 \
+       -I$(srcdir)/../SMESHUtils \
        -I$(srcdir)/../SMESH \
        -I$(srcdir)/../SMESHDS \
        -I$(srcdir)/../SMDS \
@@ -132,8 +154,12 @@ libStdMeshers_la_CPPFLAGS = \
 
 libStdMeshers_la_LDFLAGS  = \
        ../SMESH/libSMESHimpl.la \
-       ../SMESH_I/libSMESHEngine.la \
        ../SMESHDS/libSMESHDS.la \
        ../MEFISTO2/libMEFISTO2D.la \
        $(KERNEL_LDFLAGS) -lSALOMELocalTrace -lOpUtil \
        $(CAS_LDPATH) -lTKAdvTools -lTKTopAlgo -lTKG3d
+
+if WITH_TBB
+  libStdMeshers_la_CPPFLAGS += $(TBB_INCLUDES)
+  libStdMeshers_la_LDFLAGS  += $(TBB_LIBS)
+endif
index be440c1bd35ad57acc7e8528da10e51ac55fffbd..50e53acddd7c2023bbf6152f568a6d7a5bda4461 100755 (executable)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  File   : SMESH_StdMeshers.hxx
 //  Author : Alexander BORODIN
 //  Module : SMESH
@@ -28,7 +29,7 @@
 #define _SMESH_StdMeshers_HXX_
 
 #ifdef WNT
- #if defined STDMESHERS_EXPORTS
+ #if defined STDMESHERS_EXPORTS || defined StdMeshers_EXPORTS
   #define STDMESHERS_EXPORT __declspec( dllexport )
  #else
   #define STDMESHERS_EXPORT __declspec( dllimport )
index f5ac03c5e640768c33f23e64e9313e0212f44353..589972c8b08833a06255df467396f16a82ad75ee 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_Arithmetic1D.cxx
 //  Author : Damien COQUERET, OCC
@@ -104,9 +105,32 @@ double StdMeshers_Arithmetic1D::GetLength(bool isStartLength) const
  */
 //=============================================================================
 
+void StdMeshers_Arithmetic1D::SetReversedEdges( std::vector<int>& ids )
+{
+  if ( ids != _edgeIDs ) {
+    _edgeIDs = ids;
+
+    NotifySubMeshesHypothesisModification();
+  }
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
 ostream & StdMeshers_Arithmetic1D::SaveTo(ostream & save)
 {
-  save << _begLength << " " << _endLength;
+  int listSize = _edgeIDs.size();
+  save << _begLength << " " << _endLength << " " << listSize;
+
+  if ( listSize > 0 ) {
+    for ( int i = 0; i < listSize; i++)
+      save << " " << _edgeIDs[i];
+    save << " " << _objEntry;
+  }
+
   return save;
 }
 
@@ -119,12 +143,25 @@ ostream & StdMeshers_Arithmetic1D::SaveTo(ostream & save)
 istream & StdMeshers_Arithmetic1D::LoadFrom(istream & load)
 {
   bool isOK = true;
+  int intVal;
   isOK = (load >> _begLength);
   if (!isOK)
     load.clear(ios::badbit | load.rdstate());
   isOK = (load >> _endLength);
+
   if (!isOK)
     load.clear(ios::badbit | load.rdstate());
+
+  isOK = (load >> intVal);
+  if (isOK && intVal > 0) {
+    _edgeIDs.reserve( intVal );
+    for (int i = 0; i < _edgeIDs.capacity() && isOK; i++) {
+      isOK = (load >> intVal);
+      if ( isOK ) _edgeIDs.push_back( intVal );
+    }
+    isOK = (load >> _objEntry);
+  }
+
   return load;
 }
 
@@ -177,7 +214,7 @@ bool StdMeshers_Arithmetic1D::SetParametersByMesh(const SMESH_Mesh*   theMesh,
   {
     const TopoDS_Edge& edge = TopoDS::Edge( edgeMap( i ));
     Handle(Geom_Curve) C = BRep_Tool::Curve(edge, L, UMin, UMax);
-    GeomAdaptor_Curve AdaptCurve(C);
+    GeomAdaptor_Curve AdaptCurve(C, UMin, UMax);
 
     vector< double > params;
     SMESHDS_Mesh* aMeshDS = const_cast< SMESH_Mesh* >( theMesh )->GetMeshDS();
@@ -206,6 +243,6 @@ bool StdMeshers_Arithmetic1D::SetParametersByMesh(const SMESH_Mesh*   theMesh,
 bool StdMeshers_Arithmetic1D::SetParametersByDefaults(const TDefaults&  dflts,
                                                       const SMESH_Mesh* /*mesh*/)
 {
-  return bool( _begLength = _endLength = dflts._elemLength );
+  return ( _begLength = _endLength = dflts._elemLength );
 }
 
index 94952b774da39110650b247447f60b0b348e2479..168b6b657ff10b944e3f5fa574e4e0c7121a512c 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_Arithmetic1D.hxx
 //  Author : Damien COQUERET, OCC
 #ifndef _SMESH_ARITHMETIC1D_HXX_
 #define _SMESH_ARITHMETIC1D_HXX_
 
+
+
 #include "SMESH_StdMeshers.hxx"
 
 #include "SMESH_Hypothesis.hxx"
 #include "Utils_SALOME_Exception.hxx"
 
+#include <vector>
+
 class STDMESHERS_EXPORT StdMeshers_Arithmetic1D:
   public SMESH_Hypothesis
 {
@@ -43,6 +48,14 @@ public:
 
   double GetLength(bool isStartLength) const;
 
+  void SetReversedEdges( std::vector<int>& ids);
+
+  void SetObjectEntry( const char* entry ) { _objEntry = entry; }
+
+  const char* GetObjectEntry() { return _objEntry.c_str(); }
+
+  const std::vector<int>& GetReversedEdges() const { return _edgeIDs; }
+
   virtual std::ostream & SaveTo(std::ostream & save);
   virtual std::istream & LoadFrom(std::istream & load);
   friend std::ostream& operator << (std::ostream & save, StdMeshers_Arithmetic1D & hyp);
@@ -64,6 +77,8 @@ public:
 
 protected:
   double _begLength, _endLength;
+  std::vector<int>   _edgeIDs;
+  std::string        _objEntry;
 };
 
 #endif
index 95710c94eb9768299be9e522472eea143f38140e..d12f51a3413861e3d88b1191ade95b0288b7691f 100644 (file)
@@ -1,29 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_AutomaticLength.cxx
 //  Author : Edward AGAPOV, OCC
 //  Module : SMESH
-//
+
 #include "StdMeshers_AutomaticLength.hxx"
 
 #include "SMESH_Mesh.hxx"
@@ -116,7 +117,7 @@ namespace {
    */
   //================================================================================
 
-  const double a14divPI = 14. / PI;
+  const double a14divPI = 14. / M_PI;
 
   inline double segLength(double S0, double edgeLen, double minLen )
   {
@@ -398,5 +399,3 @@ bool StdMeshers_AutomaticLength::SetParametersByDefaults(const TDefaults&  /*the
 
 //   return true;
 }
-
-
index 627003aa608b4ffba44250961c4ce7eef8576567..089b935acabcf8d24ad026ded476bb0b13988a96 100644 (file)
@@ -1,29 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_AutomaticLength.hxx
 //  Author : Edward AGAPOV, OCC
 //  Module : SMESH
-
+//
 #ifndef _SMESH_AutomaticLength_HXX_
 #define _SMESH_AutomaticLength_HXX_
 
diff --git a/src/StdMeshers/StdMeshers_CartesianParameters3D.cxx b/src/StdMeshers/StdMeshers_CartesianParameters3D.cxx
new file mode 100644 (file)
index 0000000..9446e12
--- /dev/null
@@ -0,0 +1,453 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+//  File   : StdMeshers_CartesianParameters3D.cxx
+//  Author : Edward AGAPOV
+//  Module : SMESH
+//
+#include "StdMeshers_CartesianParameters3D.hxx"
+
+#include "StdMeshers_NumberOfSegments.hxx"
+#include "StdMeshers_Distribution.hxx"
+#include "SMESH_Gen.hxx"
+
+#include "utilities.h"
+
+#include <Precision.hxx>
+#include <Bnd_Box.hxx>
+
+#include <limits>
+
+using namespace std;
+
+//=======================================================================
+//function : StdMeshers_CartesianParameters3D
+//purpose  : Constructor
+//=======================================================================
+
+StdMeshers_CartesianParameters3D::StdMeshers_CartesianParameters3D(int         hypId,
+                                                                   int         studyId,
+                                                                   SMESH_Gen * gen)
+  : SMESH_Hypothesis(hypId, studyId, gen),
+    _sizeThreshold( 4.0 ) // default according to the customer specification
+{
+  _name = "CartesianParameters3D"; // used by "Cartesian_3D"
+  _param_algo_dim = 3; // 3D
+}
+
+
+namespace
+{
+  const char* axisName[3] = { "X", "Y", "Z" };
+
+  //================================================================================
+  /*!
+   * \brief Checks validity of an axis index, throws in case of invalidity
+   */
+  //================================================================================
+
+  void checkAxis(const int axis)
+  {
+    if ( axis < 0 || axis > 2 )
+      throw SALOME_Exception(SMESH_Comment("Invalid axis index ") << axis <<
+                             ". Valid axis indices are 0, 1 and 2");
+  }
+
+  //================================================================================
+  /*!
+   * \brief Checks validity of spacing data, throws in case of invalidity
+   */
+  //================================================================================
+
+  void checkGridSpacing(std::vector<std::string>& spaceFunctions,
+                        std::vector<double>&      internalPoints,
+                        const std::string&        axis)
+    throw ( SALOME_Exception )
+  {
+    if ( spaceFunctions.empty() )
+      throw SALOME_Exception(SMESH_Comment("Empty space function for ") << axis );
+
+    for ( size_t i = 1; i < internalPoints.size(); ++i )
+      if ( internalPoints[i] - internalPoints[i-1] < 0 )
+        throw SALOME_Exception(SMESH_Comment("Wrong order of internal points along ") << axis);
+      else if ( internalPoints[i] - internalPoints[i-1] < 1e-3 )
+        throw SALOME_Exception(SMESH_Comment("Too close internal points along ") << axis );
+
+    const double tol = Precision::Confusion();
+    if ( !internalPoints.empty() &&
+         ( internalPoints.front() < -tol || internalPoints.back() > 1 + tol ))
+      throw SALOME_Exception(SMESH_Comment("Invalid internal points along ") << axis);
+
+    if ( internalPoints.empty() || internalPoints.front() > tol )
+      internalPoints.insert( internalPoints.begin(), 0. );
+    if ( internalPoints.size() < 2 || internalPoints.back() < 1 - tol )
+      internalPoints.push_back( 1. );
+
+    if ( internalPoints.size() != spaceFunctions.size() + 1 )
+      throw SALOME_Exception
+        (SMESH_Comment("Numbre of internal points mismatch number of functions for ") << axis);
+
+    for ( size_t i = 0; i < spaceFunctions.size(); ++i )
+      spaceFunctions[i] =
+        StdMeshers_NumberOfSegments::CheckExpressionFunction( spaceFunctions[i], -1 );
+  }
+}
+
+//=======================================================================
+//function : SetGrid
+//purpose  : Sets coordinates of node positions along an axes
+//=======================================================================
+
+void StdMeshers_CartesianParameters3D::SetGrid(std::vector<double>& coords, int axis)
+  throw ( SALOME_Exception )
+{
+  checkAxis( axis );
+
+  if ( coords.size() < 2 )
+    throw SALOME_Exception(LOCALIZED("Wrong number of grid coordinates"));
+
+  std::sort( coords.begin(), coords.end() );
+
+  bool changed = ( _coords[axis] != coords );
+  if ( changed )
+  {
+    _coords[axis] = coords;
+    NotifySubMeshesHypothesisModification();
+  }
+
+  _spaceFunctions[axis].clear();
+  _internalPoints[axis].clear();
+}
+
+//=======================================================================
+//function : SetGridSpacing
+//purpose  : Set grid spacing along the three axes
+//=======================================================================
+
+void StdMeshers_CartesianParameters3D::SetGridSpacing(std::vector<string>& xSpaceFuns,
+                                                      std::vector<double>& xInternalPoints,
+                                                      const int            axis)
+  throw ( SALOME_Exception )
+{
+  checkAxis( axis );
+
+  checkGridSpacing( xSpaceFuns, xInternalPoints, axisName[axis] );
+
+  bool changed = ( xSpaceFuns      != _spaceFunctions[axis] ||
+                   xInternalPoints != _internalPoints[axis] );
+
+  _spaceFunctions[axis] = xSpaceFuns;
+  _internalPoints[axis] = xInternalPoints;
+  _coords[axis].clear();
+
+  if ( changed )
+    NotifySubMeshesHypothesisModification();
+}
+
+//=======================================================================
+//function : SetSizeThreshold
+//purpose  : Set size threshold
+//=======================================================================
+
+void StdMeshers_CartesianParameters3D::SetSizeThreshold(const double threshold)
+  throw ( SALOME_Exception )
+{
+  if ( threshold <= 1.0 )
+    throw SALOME_Exception(LOCALIZED("threshold must be > 1.0"));
+
+  bool changed = fabs( _sizeThreshold - threshold ) > 1e-6;
+  _sizeThreshold = threshold;
+
+  if ( changed )
+    NotifySubMeshesHypothesisModification();
+}
+
+//=======================================================================
+//function : GetGridSpacing
+//purpose  : return spacing
+//=======================================================================
+
+void StdMeshers_CartesianParameters3D::GetGridSpacing(std::vector<std::string>& spaceFunctions,
+                                                      std::vector<double>&      internalPoints,
+                                                      const int                 axis) const
+  throw ( SALOME_Exception )
+{
+  if ( !IsGridBySpacing(axis) )
+    throw SALOME_Exception(LOCALIZED("The grid is defined by coordinates and not by spacing"));
+
+  spaceFunctions = _spaceFunctions[axis];
+  internalPoints = _internalPoints[axis];
+}
+
+//=======================================================================
+//function : IsGridBySpacing
+//=======================================================================
+
+bool StdMeshers_CartesianParameters3D::IsGridBySpacing(const int axis) const
+  throw ( SALOME_Exception )
+{
+  checkAxis(axis);
+  return !_spaceFunctions[axis].empty();
+}
+
+
+//=======================================================================
+//function : ComputeCoordinates
+//purpose  : Computes node coordinates by spacing functions
+//=======================================================================
+
+void StdMeshers_CartesianParameters3D::ComputeCoordinates(const double         x0,
+                                                          const double         x1,
+                                                          vector<std::string>& spaceFuns,
+                                                          vector<double>&      points,
+                                                          vector<double>&      coords,
+                                                          const std::string&   axis )
+  throw ( SALOME_Exception )
+{
+  checkGridSpacing( spaceFuns, points, axis );
+
+  coords.clear();
+  for ( size_t i = 0; i < spaceFuns.size(); ++i )
+  {
+    FunctionExpr fun( spaceFuns[i].c_str(), /*convMode=*/-1 );
+
+    const double p0 = x0 * ( 1. - points[i])   + x1 * points[i];
+    const double p1 = x0 * ( 1. - points[i+1]) + x1 * points[i+1];
+    const double length = p1 - p0;
+
+    const size_t nbSections = 1000;
+    const double sectionLen = ( p1 - p0 ) / nbSections;
+    vector< double > nbSegments( nbSections + 1 );
+    nbSegments[ 0 ] = 0.;
+
+    double t, spacing = 0;
+    for ( size_t i = 1; i <= nbSections; ++i )
+    {
+      t = double( i ) / nbSections;
+      if ( !fun.value( t, spacing ) || spacing < std::numeric_limits<double>::min() )
+        throw SALOME_Exception(LOCALIZED("Invalid spacing function"));
+      nbSegments[ i ] = nbSegments[ i-1 ] + std::min( 1., sectionLen / spacing );
+    }
+
+    const int nbCells = max (1, int(floor(nbSegments.back()+0.5)));
+    const double corr = nbCells / nbSegments.back();
+
+    if ( coords.empty() ) coords.push_back( p0 );
+
+    for ( size_t iCell = 1, i = 1; i <= nbSections; ++i )
+    {
+      if ( nbSegments[i]*corr >= iCell )
+      {
+        t = (i - ( nbSegments[i] - iCell/corr )/( nbSegments[i] - nbSegments[i-1] )) / nbSections;
+        coords.push_back( p0 + t * length );
+        ++iCell;
+      }
+    }
+    const double lastCellLen = coords.back() - coords[ coords.size() - 2 ];
+    if ( fabs( coords.back() - p1 ) > 0.5 * lastCellLen )
+      coords.push_back ( p1 );
+  }
+}
+
+//=======================================================================
+//function : GetCoordinates
+//purpose  : Return coordinates of node positions along the three axes.
+//           If the grid is defined by spacing functions, the coordinates are computed
+//=======================================================================
+
+void StdMeshers_CartesianParameters3D::GetCoordinates(std::vector<double>& xNodes,
+                                                      std::vector<double>& yNodes,
+                                                      std::vector<double>& zNodes,
+                                                      const Bnd_Box&       bndBox) const
+  throw ( SALOME_Exception )
+{
+  double x0,y0,z0, x1,y1,z1;
+  if ( IsGridBySpacing(0) || IsGridBySpacing(1) || IsGridBySpacing(2))
+  {
+    if ( bndBox.IsVoid() ||
+         bndBox.IsXThin( Precision::Confusion() ) ||
+         bndBox.IsYThin( Precision::Confusion() ) ||
+         bndBox.IsZThin( Precision::Confusion() ) )
+      throw SALOME_Exception(LOCALIZED("Invalid bounding box"));
+    bndBox.Get(x0,y0,z0, x1,y1,z1);
+  }
+
+  StdMeshers_CartesianParameters3D* me = const_cast<StdMeshers_CartesianParameters3D*>(this);
+  if ( IsGridBySpacing(0) )
+    ComputeCoordinates( x0, x1, me->_spaceFunctions[0], me->_internalPoints[0], xNodes, "X" );
+  else
+    xNodes = _coords[0];
+
+  if ( IsGridBySpacing(1) )
+    ComputeCoordinates( y0, y1, me->_spaceFunctions[1], me->_internalPoints[1], yNodes, "Y" );
+  else
+    yNodes = _coords[1];
+
+  if ( IsGridBySpacing(2) )
+    ComputeCoordinates( z0, z1, me->_spaceFunctions[2], me->_internalPoints[2], zNodes, "Z" );
+  else
+    zNodes = _coords[2];
+}
+
+//=======================================================================
+//function : GetGrid
+//purpose  : Return coordinates of node positions along the three axes
+//=======================================================================
+
+void StdMeshers_CartesianParameters3D::GetGrid(std::vector<double>& coords, int axis) const
+  throw ( SALOME_Exception )
+{
+  if ( IsGridBySpacing(axis) )
+    throw SALOME_Exception(LOCALIZED("The grid is defined by spacing and not by coordinates"));
+
+  coords = _coords[axis];
+}
+
+//=======================================================================
+//function : GetSizeThreshold
+//purpose  : Return size threshold
+//=======================================================================
+
+double StdMeshers_CartesianParameters3D::GetSizeThreshold() const
+{
+  return _sizeThreshold;
+}
+
+//=======================================================================
+//function : IsDefined
+//purpose  : Return true if parameters are well defined
+//=======================================================================
+
+bool StdMeshers_CartesianParameters3D::IsDefined() const
+{
+  for ( int i = 0; i < 3; ++i )
+    if (_coords[i].empty() && (_spaceFunctions[i].empty() || _internalPoints[i].empty()))
+      return false;
+
+  return ( _sizeThreshold > 1.0 );
+}
+
+//=======================================================================
+//function : SaveTo
+//purpose  : store my parameters into a stream
+//=======================================================================
+
+std::ostream & StdMeshers_CartesianParameters3D::SaveTo(std::ostream & save)
+{
+  save << _sizeThreshold << " ";
+
+  for ( int i = 0; i < 3; ++i )
+  {
+    save << _coords[i].size() << " ";
+    for ( size_t j = 0; j < _coords[i].size(); ++j )
+      save << _coords[i][j] << " ";
+
+    save << _internalPoints[i].size() << " ";
+    for ( size_t j = 0; j < _internalPoints[i].size(); ++j )
+      save << _internalPoints[i][j] << " ";
+
+    save << _spaceFunctions[i].size() << " ";
+    for ( size_t j = 0; j < _spaceFunctions[i].size(); ++j )
+      save << _spaceFunctions[i][j] << " ";
+  }
+
+  return save;
+}
+
+//=======================================================================
+//function : LoadFrom
+//purpose  : resore my parameters from a stream
+//=======================================================================
+
+std::istream & StdMeshers_CartesianParameters3D::LoadFrom(std::istream & load)
+{
+  bool ok;
+
+  ok = (load >> _sizeThreshold  );
+  for ( int ax = 0; ax < 3; ++ax )
+  {
+    if (ok)
+    {
+      size_t i = 0;
+      ok = (load >> i  );
+      if ( i > 0 && ok )
+      {
+        _coords[ax].resize( i );
+        for ( i = 0; i < _coords[ax].size() && ok; ++i )
+          ok = (load >> _coords[ax][i]  );
+      }
+    }
+    if (ok)
+    {
+      size_t i = 0;
+      ok = (load >> i  );
+      if ( i > 0 && ok )
+      {
+        _internalPoints[ax].resize( i );
+        for ( i = 0; i < _internalPoints[ax].size() && ok; ++i )
+          ok = (load >> _internalPoints[ax][i]  );
+      }
+    }
+    if (ok)
+    {
+      size_t i = 0;
+      ok = (load >> i  );
+      if ( i > 0 && ok )
+      {
+        _spaceFunctions[ax].resize( i );
+        for ( i = 0; i < _spaceFunctions[ax].size() && ok; ++i )
+          ok = (load >> _spaceFunctions[ax][i]  );
+      }
+    }
+  }
+  return load;
+}
+
+//=======================================================================
+//function : SetParametersByMesh
+//=======================================================================
+
+bool StdMeshers_CartesianParameters3D::SetParametersByMesh(const SMESH_Mesh*   ,
+                                                           const TopoDS_Shape& )
+{
+  return false;
+}
+
+//=======================================================================
+//function : SetParametersByDefaults
+//=======================================================================
+
+bool StdMeshers_CartesianParameters3D::SetParametersByDefaults(const TDefaults&  dflts,
+                                                               const SMESH_Mesh* /*theMesh*/)
+{
+  if ( dflts._elemLength > 1e-100 )
+  {
+    vector<string> spacing( 1, SMESH_Comment(dflts._elemLength));
+    vector<double> intPnts;
+    SetGridSpacing( spacing, intPnts, 0 );
+    SetGridSpacing( spacing, intPnts, 1 );
+    SetGridSpacing( spacing, intPnts, 2 );
+    return true;
+  }
+  return false;
+}
+
diff --git a/src/StdMeshers/StdMeshers_CartesianParameters3D.hxx b/src/StdMeshers/StdMeshers_CartesianParameters3D.hxx
new file mode 100644 (file)
index 0000000..682ce4c
--- /dev/null
@@ -0,0 +1,145 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+//  File   : StdMeshers_CartesianParameters3D.hxx
+//  Author : Edward AGAPOV
+//  Module : SMESH
+//
+#ifndef _SMESH_CartesianParameters3D_HXX_
+#define _SMESH_CartesianParameters3D_HXX_
+
+#include "SMESH_StdMeshers.hxx"
+
+#include "SMESH_Hypothesis.hxx"
+#include "Utils_SALOME_Exception.hxx"
+
+#include <vector>
+
+class SMESH_Gen;
+class Bnd_Box;
+
+// =========================================================
+/*!
+ * This hypothesis specifies
+ * - Definition of the Cartesian grid
+ * - Size threshold
+ */
+// =========================================================
+
+class STDMESHERS_EXPORT StdMeshers_CartesianParameters3D:  public SMESH_Hypothesis
+{
+public:
+  // Constructor
+  StdMeshers_CartesianParameters3D( int hypId, int studyId, SMESH_Gen * gen );
+
+  /*!
+   * Sets coordinates of node positions along an axis (countered from 0)
+   */
+  void SetGrid(std::vector<double>& xNodes, int axis) throw ( SALOME_Exception );
+  /*!
+   * Return coordinates of node positions along the three axes
+   */
+  void GetGrid(std::vector<double>& xNodes, int axis) const throw ( SALOME_Exception );
+
+  /*!
+   * \brief Set grid spacing along the three axes
+   *  \param spaceFunctions - functions defining spacing values at given point on axis
+   *  \param internalPoints - points dividing a grid into parts along each direction
+   *
+   * Parameter t of spaceFunction f(t) is a position [0,1] withing bounding box of
+   * the shape to mesh
+   */
+  void SetGridSpacing(std::vector<std::string>& spaceFunctions,
+                      std::vector<double>&      internalPoints,
+                      const int                 axis) throw ( SALOME_Exception );
+
+  void GetGridSpacing(std::vector<std::string>& spaceFunctions,
+                      std::vector<double>&      internalPoints,
+                      const int                 axis) const throw ( SALOME_Exception );
+
+  bool IsGridBySpacing(const int axis) const throw ( SALOME_Exception );
+
+  /*!
+   * \brief Computes node coordinates by spacing functions
+   *  \param x0 - lower coordinate
+   *  \param x1 - upper coordinate
+   *  \param spaceFuns - space functions
+   *  \param points - internal points
+   *  \param coords - the computed coordinates
+   */
+  static void ComputeCoordinates(const double              x0,
+                                 const double              x1,
+                                 std::vector<std::string>& spaceFuns,
+                                 std::vector<double>&      points,
+                                 std::vector<double>&      coords,
+                                 const std::string&        axis ) throw (SALOME_Exception);
+  /*!
+   * Return coordinates of node positions along the three axes.
+   * If the grid is defined by spacing functions, the coordinates are computed
+   */
+  void GetCoordinates(std::vector<double>& xNodes,
+                      std::vector<double>& yNodes,
+                      std::vector<double>& zNodes,
+                      const Bnd_Box&       bndBox) const throw ( SALOME_Exception );
+  /*!
+   * Set size threshold. A polyhedral cell got by cutting an initial
+   * hexahedron by geometry boundary is considered small and is removed if
+   * it's size is \athreshold times less than the size of the initial hexahedron. 
+   */
+  void SetSizeThreshold(const double threshold) throw ( SALOME_Exception );
+  /*!
+   * \brief Return size threshold
+   */
+  double GetSizeThreshold() const;
+
+  /*!
+   * \brief Return true if parameters are well defined
+   */
+  bool IsDefined() const;
+
+  /*!
+   * \brief Persistence methods
+   */
+  virtual std::ostream & SaveTo(std::ostream & save);
+  virtual std::istream & LoadFrom(std::istream & load);
+
+  /*!
+   * \brief Initialize my parameter values by the mesh built on the geometry
+   */
+  virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape);
+
+  /*!
+   * \brief Initialize my parameter values by default parameters.
+   */
+  virtual bool SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh=0);
+
+ protected:
+
+  std::vector<double>      _coords[3];
+  std::vector<std::string> _spaceFunctions[3];
+  std::vector<double>      _internalPoints[3];
+
+  double _sizeThreshold;
+};
+
+#endif
+
diff --git a/src/StdMeshers/StdMeshers_Cartesian_3D.cxx b/src/StdMeshers/StdMeshers_Cartesian_3D.cxx
new file mode 100644 (file)
index 0000000..c1e5719
--- /dev/null
@@ -0,0 +1,2185 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+//  File   : StdMeshers_Cartesian_3D.cxx
+//  Module : SMESH
+//
+#include "StdMeshers_Cartesian_3D.hxx"
+
+#include "SMDS_MeshNode.hxx"
+#include "SMESH_Block.hxx"
+#include "SMESH_Comment.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_MesherHelper.hxx"
+#include "SMESH_subMesh.hxx"
+#include "SMESH_subMeshEventListener.hxx"
+#include "StdMeshers_CartesianParameters3D.hxx"
+
+#include "utilities.h"
+#include "Utils_ExceptHandlers.hxx"
+
+#include <BRepAdaptor_Surface.hxx>
+#include <BRepBndLib.hxx>
+#include <BRepBuilderAPI_Copy.hxx>
+#include <BRepTools.hxx>
+#include <BRep_Tool.hxx>
+#include <Bnd_Box.hxx>
+#include <ElSLib.hxx>
+#include <Geom2d_BSplineCurve.hxx>
+#include <Geom2d_BezierCurve.hxx>
+#include <Geom2d_TrimmedCurve.hxx>
+#include <Geom_BSplineCurve.hxx>
+#include <Geom_BSplineSurface.hxx>
+#include <Geom_BezierCurve.hxx>
+#include <Geom_BezierSurface.hxx>
+#include <Geom_RectangularTrimmedSurface.hxx>
+#include <Geom_TrimmedCurve.hxx>
+#include <IntAna_IntConicQuad.hxx>
+#include <IntAna_IntLinTorus.hxx>
+#include <IntAna_Quadric.hxx>
+#include <IntCurveSurface_TransitionOnCurve.hxx>
+#include <IntCurvesFace_Intersector.hxx>
+#include <Poly_Triangulation.hxx>
+#include <Precision.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopLoc_Location.hxx>
+#include <TopTools_MapIteratorOfMapOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_TShape.hxx>
+#include <gp_Cone.hxx>
+#include <gp_Cylinder.hxx>
+#include <gp_Lin.hxx>
+#include <gp_Pln.hxx>
+#include <gp_Pnt2d.hxx>
+#include <gp_Sphere.hxx>
+#include <gp_Torus.hxx>
+
+//#undef WITH_TBB
+#ifdef WITH_TBB
+#include <tbb/parallel_for.h>
+//#include <tbb/enumerable_thread_specific.h>
+#endif
+
+using namespace std;
+
+//#define _MY_DEBUG_
+
+#define ELLIPSOLID_WORKAROUND // remove it as soon as http://tracker.dev.opencascade.org/view.php?id=22809 is solved
+
+#ifdef ELLIPSOLID_WORKAROUND
+#include <BRepIntCurveSurface_Inter.hxx>
+#include <BRepTopAdaptor_TopolTool.hxx>
+#include <BRepAdaptor_HSurface.hxx>
+#endif
+
+//=============================================================================
+/*!
+ * Constructor
+ */
+//=============================================================================
+
+StdMeshers_Cartesian_3D::StdMeshers_Cartesian_3D(int hypId, int studyId, SMESH_Gen * gen)
+  :SMESH_3D_Algo(hypId, studyId, gen)
+{
+  _name = "Cartesian_3D";
+  _shapeType = (1 << TopAbs_SOLID);       // 1 bit /shape type
+  _compatibleHypothesis.push_back("CartesianParameters3D");
+
+  _onlyUnaryInput = false;          // to mesh all SOLIDs at once
+  _requireDiscreteBoundary = false; // 2D mesh not needed
+  _supportSubmeshes = false;        // do not use any existing mesh
+}
+
+//=============================================================================
+/*!
+ * Check presence of a hypothesis
+ */
+//=============================================================================
+
+bool StdMeshers_Cartesian_3D::CheckHypothesis (SMESH_Mesh&          aMesh,
+                                               const TopoDS_Shape&  aShape,
+                                               Hypothesis_Status&   aStatus)
+{
+  aStatus = SMESH_Hypothesis::HYP_MISSING;
+
+  const list<const SMESHDS_Hypothesis*>& hyps = GetUsedHypothesis(aMesh, aShape);
+  list <const SMESHDS_Hypothesis* >::const_iterator h = hyps.begin();
+  if ( h == hyps.end())
+  {
+    return false;
+  }
+
+  for ( ; h != hyps.end(); ++h )
+  {
+    if (( _hyp = dynamic_cast<const StdMeshers_CartesianParameters3D*>( *h )))
+    {
+      aStatus = _hyp->IsDefined() ? HYP_OK : HYP_BAD_PARAMETER;
+      break;
+    }
+  }
+
+  return aStatus == HYP_OK;
+}
+
+namespace
+{
+  //=============================================================================
+  // Definitions of internal utils
+  // --------------------------------------------------------------------------
+  enum Transition {
+    Trans_TANGENT = IntCurveSurface_Tangent,
+    Trans_IN      = IntCurveSurface_In,
+    Trans_OUT     = IntCurveSurface_Out,
+    Trans_APEX
+  };
+  // --------------------------------------------------------------------------
+  /*!
+   * \brief Data of intersection between a GridLine and a TopoDS_Face
+   */
+  struct IntersectionPoint
+  {
+    double                       _paramOnLine;
+    mutable Transition           _transition;
+    mutable const SMDS_MeshNode* _node;
+    mutable size_t               _indexOnLine;
+
+    IntersectionPoint(): _node(0) {}
+    bool operator< ( const IntersectionPoint& o ) const { return _paramOnLine < o._paramOnLine; }
+  };
+  // --------------------------------------------------------------------------
+  /*!
+   * \brief A line of the grid and its intersections with 2D geometry
+   */
+  struct GridLine
+  {
+    gp_Lin _line;
+    double _length; // line length
+    multiset< IntersectionPoint > _intPoints;
+
+    void RemoveExcessIntPoints( const double tol );
+    bool GetIsOutBefore( multiset< IntersectionPoint >::iterator ip, bool prevIsOut );
+  };
+  // --------------------------------------------------------------------------
+  /*!
+   * \brief Iterator on the parallel grid lines of one direction
+   */
+  struct LineIndexer
+  {
+    size_t _size  [3];
+    size_t _curInd[3];
+    size_t _iVar1, _iVar2, _iConst;
+    string _name1, _name2, _nameConst;
+    LineIndexer() {}
+    LineIndexer( size_t sz1, size_t sz2, size_t sz3,
+                 size_t iv1, size_t iv2, size_t iConst,
+                 const string& nv1, const string& nv2, const string& nConst )
+    {
+      _size[0] = sz1; _size[1] = sz2; _size[2] = sz3;
+      _curInd[0] = _curInd[1] = _curInd[2] = 0;
+      _iVar1 = iv1; _iVar2 = iv2; _iConst = iConst; 
+      _name1 = nv1; _name2 = nv2; _nameConst = nConst;
+    }
+
+    size_t I() const { return _curInd[0]; }
+    size_t J() const { return _curInd[1]; }
+    size_t K() const { return _curInd[2]; }
+    void SetIJK( size_t i, size_t j, size_t k )
+    {
+      _curInd[0] = i; _curInd[1] = j; _curInd[2] = k;
+    }
+    void operator++()
+    {
+      if ( ++_curInd[_iVar1] == _size[_iVar1] )
+        _curInd[_iVar1] = 0, ++_curInd[_iVar2];
+    }
+    bool More() const { return _curInd[_iVar2] < _size[_iVar2]; }
+    size_t LineIndex   () const { return _curInd[_iVar1] + _curInd[_iVar2]* _size[_iVar1]; }
+    size_t LineIndex10 () const { return (_curInd[_iVar1] + 1 ) + _curInd[_iVar2]* _size[_iVar1]; }
+    size_t LineIndex01 () const { return _curInd[_iVar1] + (_curInd[_iVar2] + 1 )* _size[_iVar1]; }
+    size_t LineIndex11 () const { return (_curInd[_iVar1] + 1 ) + (_curInd[_iVar2] + 1 )* _size[_iVar1]; }
+    void SetIndexOnLine (size_t i)  { _curInd[ _iConst ] = i; }
+    size_t NbLines() const { return _size[_iVar1] * _size[_iVar2]; }
+  };
+  // --------------------------------------------------------------------------
+  /*!
+   * \brief Container of GridLine's
+   */
+  struct Grid
+  {
+    vector< double >   _coords[3]; // coordinates of grid nodes
+    vector< GridLine > _lines [3]; //  in 3 directions
+    double             _tol, _minCellSize;
+
+    vector< const SMDS_MeshNode* > _nodes; // mesh nodes at grid nodes
+    vector< bool >                 _isBndNode; // is mesh node at intersection with geometry
+
+    size_t CellIndex( size_t i, size_t j, size_t k ) const
+    {
+      return i + j*(_coords[0].size()-1) + k*(_coords[0].size()-1)*(_coords[1].size()-1);
+    }
+    size_t NodeIndex( size_t i, size_t j, size_t k ) const
+    {
+      return i + j*_coords[0].size() + k*_coords[0].size()*_coords[1].size();
+    }
+    size_t NodeIndexDX() const { return 1; }
+    size_t NodeIndexDY() const { return _coords[0].size(); }
+    size_t NodeIndexDZ() const { return _coords[0].size() * _coords[1].size(); }
+
+    LineIndexer GetLineIndexer(size_t iDir) const;
+
+    void SetCoordinates(const vector<double>& xCoords,
+                        const vector<double>& yCoords,
+                        const vector<double>& zCoords,
+                        const TopoDS_Shape&   shape );
+    void ComputeNodes(SMESH_MesherHelper& helper);
+  };
+#ifdef ELLIPSOLID_WORKAROUND
+  // --------------------------------------------------------------------------
+  /*!
+   * \brief struct temporary replacing IntCurvesFace_Intersector until
+   *        OCCT bug 0022809 is fixed
+   *        http://tracker.dev.opencascade.org/view.php?id=22809
+   */
+  struct TMP_IntCurvesFace_Intersector
+  {
+    BRepAdaptor_Surface                       _surf;
+    double                                    _tol;
+    BRepIntCurveSurface_Inter                 _intcs;
+    vector<IntCurveSurface_IntersectionPoint> _points;
+    BRepTopAdaptor_TopolTool                  _clsf;
+
+    TMP_IntCurvesFace_Intersector(const TopoDS_Face& face, const double tol)
+      :_surf( face ), _tol( tol ), _clsf( new BRepAdaptor_HSurface(_surf) ) {}
+    Bnd_Box Bounding() const { Bnd_Box b; BRepBndLib::Add (_surf.Face(), b); return b; }
+    void Perform( const gp_Lin& line, const double w0, const double w1 )
+    {
+      _points.clear();
+      for ( _intcs.Init( _surf.Face(), line, _tol ); _intcs.More(); _intcs.Next() )
+        if ( w0 <= _intcs.W() && _intcs.W() <= w1 )
+          _points.push_back( _intcs.Point() );
+    }
+    bool IsDone() const { return true; }
+    int  NbPnt()  const { return _points.size(); }
+    IntCurveSurface_TransitionOnCurve Transition( const int i ) const { return _points[ i-1 ].Transition(); }
+    double       WParameter( const int i ) const { return _points[ i-1 ].W(); }
+    TopAbs_State ClassifyUVPoint(const gp_Pnt2d& p) { return _clsf.Classify( p, _tol ); }
+  };
+#define __IntCurvesFace_Intersector TMP_IntCurvesFace_Intersector
+#else
+#define __IntCurvesFace_Intersector IntCurvesFace_Intersector
+#endif
+  // --------------------------------------------------------------------------
+  /*!
+   * \brief Intersector of TopoDS_Face with all GridLine's
+   */
+  struct FaceGridIntersector
+  {
+    TopoDS_Face _face;
+    Grid*       _grid;
+    Bnd_Box     _bndBox;
+    __IntCurvesFace_Intersector* _surfaceInt;
+    vector< std::pair< GridLine*, IntersectionPoint > > _intersections;
+
+    FaceGridIntersector(): _grid(0), _surfaceInt(0) {}
+    void Intersect();
+    bool IsInGrid(const Bnd_Box& gridBox);
+
+    void StoreIntersections()
+    {
+      for ( size_t i = 0; i < _intersections.size(); ++i )
+        _intersections[i].first->_intPoints.insert( _intersections[i].second );
+    }
+    const Bnd_Box& GetFaceBndBox()
+    {
+      GetCurveFaceIntersector();
+      return _bndBox;
+    }
+    __IntCurvesFace_Intersector* GetCurveFaceIntersector()
+    {
+      if ( !_surfaceInt )
+      {
+        _surfaceInt = new __IntCurvesFace_Intersector( _face, Precision::PConfusion() );
+        _bndBox     = _surfaceInt->Bounding();
+        if ( _bndBox.IsVoid() )
+          BRepBndLib::Add (_face, _bndBox);
+      }
+      return _surfaceInt;
+    }
+    bool IsThreadSafe(set< const Standard_Transient* >& noSafeTShapes) const;
+  };
+  // --------------------------------------------------------------------------
+  /*!
+   * \brief Intersector of a surface with a GridLine
+   */
+  struct FaceLineIntersector
+  {
+    double      _tol;
+    double      _u, _v, _w; // params on the face and the line
+    Transition  _transition; // transition of at intersection (see IntCurveSurface.cdl)
+    Transition  _transIn, _transOut; // IN and OUT transitions depending of face orientation
+
+    gp_Pln      _plane;
+    gp_Cylinder _cylinder;
+    gp_Cone     _cone;
+    gp_Sphere   _sphere;
+    gp_Torus    _torus;
+    __IntCurvesFace_Intersector* _surfaceInt;
+
+    vector< IntersectionPoint > _intPoints;
+
+    void IntersectWithPlane   (const GridLine& gridLine);
+    void IntersectWithCylinder(const GridLine& gridLine);
+    void IntersectWithCone    (const GridLine& gridLine);
+    void IntersectWithSphere  (const GridLine& gridLine);
+    void IntersectWithTorus   (const GridLine& gridLine);
+    void IntersectWithSurface (const GridLine& gridLine);
+
+    bool UVIsOnFace() const;
+    void addIntPoint(const bool toClassify=true);
+    bool isParamOnLineOK( const double linLength )
+    {
+      return -_tol < _w && _w < linLength + _tol;
+    }
+    FaceLineIntersector():_surfaceInt(0) {}
+    ~FaceLineIntersector() { if (_surfaceInt ) delete _surfaceInt; _surfaceInt = 0; }
+  };
+  // --------------------------------------------------------------------------
+  /*!
+   * \brief Class representing topology of the hexahedron and creating a mesh
+   *        volume basing on analysis of hexahedron intersection with geometry
+   */
+  class Hexahedron
+  {
+    // --------------------------------------------------------------------------------
+    struct _Face;
+    struct _Link;
+    // --------------------------------------------------------------------------------
+    struct _Node //!< node either at a hexahedron corner or at GridLine intersection
+    {
+      const SMDS_MeshNode*     _node; // mesh node at hexahedron corner
+      const IntersectionPoint* _intPoint;
+
+      _Node(const SMDS_MeshNode* n=0, const IntersectionPoint* ip=0):_node(n), _intPoint(ip) {} 
+      const SMDS_MeshNode* Node() const { return _intPoint ? _intPoint->_node : _node; }
+      //bool IsCorner() const { return _node; }
+    };
+    // --------------------------------------------------------------------------------
+    struct _Link // link connecting two _Node's
+    {
+      _Node* _nodes[2];
+      vector< _Node>  _intNodes; // _Node's at GridLine intersections
+      vector< _Link > _splits;
+      vector< _Face*> _faces;
+    };
+    // --------------------------------------------------------------------------------
+    struct _OrientedLink
+    {
+      _Link* _link;
+      bool   _reverse;
+      _OrientedLink( _Link* link=0, bool reverse=false ): _link(link), _reverse(reverse) {}
+      void Reverse() { _reverse = !_reverse; }
+      int NbResultLinks() const { return _link->_splits.size(); }
+      _OrientedLink ResultLink(int i) const
+      {
+        return _OrientedLink(&_link->_splits[_reverse ? NbResultLinks()-i-1 : i],_reverse);
+      }
+      _Node* FirstNode() const { return _link->_nodes[ _reverse ]; }
+      _Node* LastNode() const { return _link->_nodes[ !_reverse ]; }
+    };
+    // --------------------------------------------------------------------------------
+    struct _Face
+    {
+      vector< _OrientedLink > _links;
+      vector< _Link >         _polyLinks; // links added to close a polygonal face
+    };
+    // --------------------------------------------------------------------------------
+    struct _volumeDef // holder of nodes of a volume mesh element
+    {
+      vector< const SMDS_MeshNode* > _nodes;
+      vector< int >                  _quantities;
+      typedef boost::shared_ptr<_volumeDef> Ptr;
+      void set( const vector< const SMDS_MeshNode* >& nodes,
+                const vector< int > quant = vector< int >() )
+      { _nodes = nodes; _quantities = quant; }
+      // static Ptr New( const vector< const SMDS_MeshNode* >& nodes,
+      //                 const vector< int > quant = vector< int >() )
+      // {
+      //   _volumeDef* def = new _volumeDef;
+      //   def->_nodes = nodes;
+      //   def->_quantities = quant;
+      //   return Ptr( def );
+      // }
+    };
+
+    // topology of a hexahedron
+    int   _nodeShift[8];
+    _Node _hexNodes[8];
+    _Link _hexLinks[12];
+    _Face _hexQuads[6];
+
+    // faces resulted from hexahedron intersection
+    vector< _Face > _polygons;
+
+    // computed volume elements
+    //vector< _volumeDef::Ptr > _volumeDefs;
+    _volumeDef _volumeDefs;
+
+    Grid*       _grid;
+    double      _sizeThreshold, _sideLength[3];
+    int         _nbCornerNodes, _nbIntNodes, _nbBndNodes;
+    int         _origNodeInd; // index of _hexNodes[0] node within the _grid
+    size_t      _i,_j,_k;
+
+  public:
+    Hexahedron(const double sizeThreshold, Grid* grid);
+    int MakeElements(SMESH_MesherHelper& helper);
+    void ComputeElements();
+    void Init() { init( _i, _j, _k ); }
+
+  private:
+    Hexahedron(const Hexahedron& other );
+    void init( size_t i, size_t j, size_t k );
+    void init( size_t i );
+    int  addElements(SMESH_MesherHelper& helper);
+    bool isInHole() const;
+    bool checkPolyhedronSize() const;
+    bool addHexa ();
+    bool addTetra();
+    bool addPenta();
+    bool addPyra ();
+  };
+#ifdef WITH_TBB
+  // --------------------------------------------------------------------------
+  /*!
+   * \brief Hexahedron computing volumes in one thread
+   */
+  struct ParallelHexahedron
+  {
+    vector< Hexahedron* >& _hexVec;
+    vector<int>&           _index;
+    ParallelHexahedron( vector< Hexahedron* >& hv, vector<int>& ind): _hexVec(hv), _index(ind) {}
+    void operator() ( const tbb::blocked_range<size_t>& r ) const
+    {
+      for ( size_t i = r.begin(); i != r.end(); ++i )
+        if ( Hexahedron* hex = _hexVec[ _index[i]] )
+          hex->ComputeElements();
+    }
+  };
+  // --------------------------------------------------------------------------
+  /*!
+   * \brief Structure intersecting certain nb of faces with GridLine's in one thread
+   */
+  struct ParallelIntersector
+  {
+    vector< FaceGridIntersector >& _faceVec;
+    ParallelIntersector( vector< FaceGridIntersector >& faceVec): _faceVec(faceVec){}
+    void operator() ( const tbb::blocked_range<size_t>& r ) const
+    {
+      for ( size_t i = r.begin(); i != r.end(); ++i )
+        _faceVec[i].Intersect();
+    }
+  };
+
+#endif
+  //=============================================================================
+  // Implementation of internal utils
+  //=============================================================================
+  /*
+   * Remove coincident intersection points
+   */
+  void GridLine::RemoveExcessIntPoints( const double tol )
+  {
+    if ( _intPoints.size() < 2 ) return;
+
+    set< Transition > tranSet;
+    multiset< IntersectionPoint >::iterator ip1, ip2 = _intPoints.begin();
+    while ( ip2 != _intPoints.end() )
+    {
+      tranSet.clear();
+      ip1 = ip2++;
+      while ( ip2->_paramOnLine - ip1->_paramOnLine <= tol  && ip2 != _intPoints.end())
+      {
+        tranSet.insert( ip1->_transition );
+        tranSet.insert( ip2->_transition );
+        _intPoints.erase( ip1 );
+        ip1 = ip2++;
+      }
+      if ( tranSet.size() > 1 ) // points with different transition coincide
+      {
+        bool isIN  = tranSet.count( Trans_IN );
+        bool isOUT = tranSet.count( Trans_OUT );
+        if ( isIN && isOUT )
+          (*ip1)._transition = Trans_TANGENT;
+        else
+          (*ip1)._transition = isIN ? Trans_IN : Trans_OUT;
+      }
+    }
+  }
+  //================================================================================
+  /*
+   * Return "is OUT" state for nodes before the given intersection point
+   */
+  bool GridLine::GetIsOutBefore( multiset< IntersectionPoint >::iterator ip, bool prevIsOut )
+  {
+    if ( ip->_transition == Trans_IN )
+      return true;
+    if ( ip->_transition == Trans_OUT )
+      return false;
+    if ( ip->_transition == Trans_APEX )
+    {
+      // singularity point (apex of a cone)
+      if ( _intPoints.size() == 1 || ip == _intPoints.begin() )
+        return true;
+      multiset< IntersectionPoint >::iterator ipBef = ip, ipAft = ++ip;
+      if ( ipAft == _intPoints.end() )
+        return false;
+      --ipBef;
+      if ( ipBef->_transition != ipAft->_transition )
+        return ( ipBef->_transition == Trans_OUT );
+      return ( ipBef->_transition != Trans_OUT );
+    }
+    return prevIsOut; // _transition == Trans_TANGENT
+  }
+  //================================================================================
+  /*
+   * Return an iterator on GridLine's in a given direction
+   */
+  LineIndexer Grid::GetLineIndexer(size_t iDir) const
+  {
+    const size_t indices[] = { 1,2,0, 0,2,1, 0,1,2 };
+    const string s[] = { "X", "Y", "Z" };
+    LineIndexer li( _coords[0].size(),  _coords[1].size(),    _coords[2].size(),
+                    indices[iDir*3],    indices[iDir*3+1],    indices[iDir*3+2],
+                    s[indices[iDir*3]], s[indices[iDir*3+1]], s[indices[iDir*3+2]]);
+    return li;
+  }
+  //=============================================================================
+  /*
+   * Creates GridLine's of the grid
+   */
+  void Grid::SetCoordinates(const vector<double>& xCoords,
+                            const vector<double>& yCoords,
+                            const vector<double>& zCoords,
+                            const TopoDS_Shape&   shape)
+  {
+    _coords[0] = xCoords;
+    _coords[1] = yCoords;
+    _coords[2] = zCoords;
+
+    // compute tolerance
+    _minCellSize = Precision::Infinite();
+    for ( int iDir = 0; iDir < 3; ++iDir ) // loop on 3 line directions
+    {
+      for ( size_t i = 1; i < _coords[ iDir ].size(); ++i )
+      {
+        double cellLen = _coords[ iDir ][ i ] - _coords[ iDir ][ i-1 ];
+        if ( cellLen < _minCellSize )
+          _minCellSize = cellLen;
+      }
+    }
+    if ( _minCellSize < Precision::Confusion() )
+      throw SMESH_ComputeError (COMPERR_ALGO_FAILED,
+                                SMESH_Comment("Too small cell size: ") << _tol );
+    _tol = _minCellSize / 1000.;
+
+    // attune grid extremities to shape bounding box computed by vertices
+    Bnd_Box shapeBox;
+    for ( TopExp_Explorer vExp( shape, TopAbs_VERTEX ); vExp.More(); vExp.Next() )
+      shapeBox.Add( BRep_Tool::Pnt( TopoDS::Vertex( vExp.Current() )));
+    
+    double sP[6]; // aXmin, aYmin, aZmin, aXmax, aYmax, aZmax
+    shapeBox.Get(sP[0],sP[1],sP[2],sP[3],sP[4],sP[5]);
+    double* cP[6] = { &_coords[0].front(), &_coords[1].front(), &_coords[2].front(),
+                      &_coords[0].back(),  &_coords[1].back(),  &_coords[2].back() };
+    for ( int i = 0; i < 6; ++i )
+      if ( fabs( sP[i] - *cP[i] ) < _tol )
+        *cP[i] = sP[i] + _tol/1000. * ( i < 3 ? +1 : -1 );
+
+    // create lines
+    for ( int iDir = 0; iDir < 3; ++iDir ) // loop on 3 line directions
+    {
+      LineIndexer li = GetLineIndexer( iDir );
+      _lines[iDir].resize( li.NbLines() );
+      double len = _coords[ iDir ].back() - _coords[iDir].front();
+      gp_Vec dir( iDir==0, iDir==1, iDir==2 );
+      for ( ; li.More(); ++li )
+      {
+        GridLine& gl = _lines[iDir][ li.LineIndex() ];
+        gl._line.SetLocation(gp_Pnt(_coords[0][li.I()], _coords[1][li.J()], _coords[2][li.K()])); 
+        gl._line.SetDirection( dir );
+        gl._length = len;
+      }
+    }
+  }
+  //================================================================================
+  /*
+   * Creates all nodes
+   */
+  void Grid::ComputeNodes(SMESH_MesherHelper& helper)
+  {
+    // state of each node of the grid relative to the geomerty
+    const size_t nbGridNodes = _coords[0].size() * _coords[1].size() * _coords[2].size();
+    vector< bool > isNodeOut( nbGridNodes, false );
+    _nodes.resize( nbGridNodes, 0 );
+    _isBndNode.resize( nbGridNodes, false );
+
+    for ( int iDir = 0; iDir < 3; ++iDir ) // loop on 3 line directions
+    {
+      LineIndexer li = GetLineIndexer( iDir );
+
+      // find out a shift of node index while walking along a GridLine in this direction
+      li.SetIndexOnLine( 0 );
+      size_t nIndex0 = NodeIndex( li.I(), li.J(), li.K() );
+      li.SetIndexOnLine( 1 );
+      const size_t nShift = NodeIndex( li.I(), li.J(), li.K() ) - nIndex0;
+      
+      const vector<double> & coords = _coords[ iDir ];
+      for ( ; li.More(); ++li ) // loop on lines in iDir
+      {
+        li.SetIndexOnLine( 0 );
+        nIndex0 = NodeIndex( li.I(), li.J(), li.K() );
+
+        GridLine& line = _lines[ iDir ][ li.LineIndex() ];
+        line.RemoveExcessIntPoints( _tol );
+        multiset< IntersectionPoint >& intPnts = _lines[ iDir ][ li.LineIndex() ]._intPoints;
+        multiset< IntersectionPoint >::iterator ip = intPnts.begin();
+
+        bool isOut = true;
+        const double* nodeCoord = & coords[0], *coord0 = nodeCoord, *coordEnd = coord0 + coords.size();
+        double nodeParam = 0;
+        for ( ; ip != intPnts.end(); ++ip )
+        {
+          // set OUT state or just skip IN nodes before ip
+          if ( nodeParam < ip->_paramOnLine - _tol )
+          {
+            isOut = line.GetIsOutBefore( ip, isOut );
+
+            while ( nodeParam < ip->_paramOnLine - _tol )
+            {
+              if ( isOut )
+                isNodeOut[ nIndex0 + nShift * ( nodeCoord-coord0 ) ] = isOut;
+              if ( ++nodeCoord <  coordEnd )
+                nodeParam = *nodeCoord - *coord0;
+              else
+                break;
+            }
+            if ( nodeCoord == coordEnd ) break;
+          }
+          // create a mesh node on a GridLine at ip if it does not coincide with a grid node
+          if ( nodeParam > ip->_paramOnLine + _tol )
+          {
+            li.SetIndexOnLine( 0 );
+            double xyz[3] = { _coords[0][ li.I() ], _coords[1][ li.J() ], _coords[2][ li.K() ]};
+            xyz[ li._iConst ] += ip->_paramOnLine;
+            ip->_node = helper.AddNode( xyz[0], xyz[1], xyz[2] );
+            ip->_indexOnLine = nodeCoord-coord0-1;
+          }
+          // create a mesh node at ip concident with a grid node
+          else
+          {
+            int nodeIndex = nIndex0 + nShift * ( nodeCoord-coord0 );
+            if ( ! _nodes[ nodeIndex ] )
+            {
+              li.SetIndexOnLine( nodeCoord-coord0 );
+              double xyz[3] = { _coords[0][ li.I() ], _coords[1][ li.J() ], _coords[2][ li.K() ]};
+              _nodes[ nodeIndex ] = helper.AddNode( xyz[0], xyz[1], xyz[2] );
+              _isBndNode[ nodeIndex ] = true;
+            }
+            //ip->_node = _nodes[ nodeIndex ];
+            ip->_indexOnLine = nodeCoord-coord0;
+            if ( ++nodeCoord < coordEnd )
+              nodeParam = *nodeCoord - *coord0;
+          }
+        }
+        // set OUT state to nodes after the last ip
+        for ( ; nodeCoord < coordEnd; ++nodeCoord )
+          isNodeOut[ nIndex0 + nShift * ( nodeCoord-coord0 ) ] = true;
+      }
+    }
+
+    // Create mesh nodes at !OUT nodes of the grid
+
+    for ( size_t z = 0; z < _coords[2].size(); ++z )
+      for ( size_t y = 0; y < _coords[1].size(); ++y )
+        for ( size_t x = 0; x < _coords[0].size(); ++x )
+        {
+          size_t nodeIndex = NodeIndex( x, y, z );
+          if ( !isNodeOut[ nodeIndex ] && !_nodes[ nodeIndex] )
+            _nodes[ nodeIndex ] = helper.AddNode( _coords[0][x], _coords[1][y], _coords[2][z] );
+        }
+
+#ifdef _MY_DEBUG_
+    // check validity of transitions
+    const char* trName[] = { "TANGENT", "IN", "OUT", "APEX" };
+    for ( int iDir = 0; iDir < 3; ++iDir ) // loop on 3 line directions
+    {
+      LineIndexer li = GetLineIndexer( iDir );
+      for ( ; li.More(); ++li )
+      {
+        multiset< IntersectionPoint >& intPnts = _lines[ iDir ][ li.LineIndex() ]._intPoints;
+        if ( intPnts.empty() ) continue;
+        if ( intPnts.size() == 1 )
+        {
+          if ( intPnts.begin()->_transition != Trans_TANGENT &&
+               intPnts.begin()->_transition != Trans_APEX )
+          throw SMESH_ComputeError (COMPERR_ALGO_FAILED,
+                                    SMESH_Comment("Wrong SOLE transition of GridLine (")
+                                    << li._curInd[li._iVar1] << ", " << li._curInd[li._iVar2]
+                                    << ") along " << li._nameConst
+                                    << ": " << trName[ intPnts.begin()->_transition] );
+        }
+        else
+        {
+          if ( intPnts.begin()->_transition == Trans_OUT )
+            throw SMESH_ComputeError (COMPERR_ALGO_FAILED,
+                                      SMESH_Comment("Wrong START transition of GridLine (")
+                                      << li._curInd[li._iVar1] << ", " << li._curInd[li._iVar2]
+                                      << ") along " << li._nameConst
+                                      << ": " << trName[ intPnts.begin()->_transition ]);
+          if ( intPnts.rbegin()->_transition == Trans_IN )
+            throw SMESH_ComputeError (COMPERR_ALGO_FAILED,
+                                      SMESH_Comment("Wrong END transition of GridLine (")
+                                      << li._curInd[li._iVar1] << ", " << li._curInd[li._iVar2]
+                                      << ") along " << li._nameConst
+                                    << ": " << trName[ intPnts.rbegin()->_transition ]);
+        }
+      }
+    }
+#endif
+  }
+
+  //=============================================================================
+  /*
+   * Checks if the face is encosed by the grid
+   */
+  bool FaceGridIntersector::IsInGrid(const Bnd_Box& gridBox)
+  {
+    double x0,y0,z0, x1,y1,z1;
+    const Bnd_Box& faceBox = GetFaceBndBox();
+    faceBox.Get(x0,y0,z0, x1,y1,z1);
+
+    if ( !gridBox.IsOut( gp_Pnt( x0,y0,z0 )) &&
+         !gridBox.IsOut( gp_Pnt( x1,y1,z1 )))
+      return true;
+
+    double X0,Y0,Z0, X1,Y1,Z1;
+    gridBox.Get(X0,Y0,Z0, X1,Y1,Z1);
+    double faceP[6] = { x0,y0,z0, x1,y1,z1 };
+    double gridP[6] = { X0,Y0,Z0, X1,Y1,Z1 };
+    gp_Dir axes[3]  = { gp::DX(), gp::DY(), gp::DZ() };
+    for ( int iDir = 0; iDir < 6; ++iDir )
+    {
+      if ( iDir < 3  && gridP[ iDir ] <= faceP[ iDir ] ) continue;
+      if ( iDir >= 3 && gridP[ iDir ] >= faceP[ iDir ] ) continue;
+
+      // check if the face intersects a side of a gridBox
+
+      gp_Pnt p = iDir < 3 ? gp_Pnt( X0,Y0,Z0 ) : gp_Pnt( X1,Y1,Z1 );
+      gp_Ax1 norm( p, axes[ iDir % 3 ] );
+      if ( iDir < 3 ) norm.Reverse();
+
+      gp_XYZ O = norm.Location().XYZ(), N = norm.Direction().XYZ();
+
+      TopLoc_Location loc = _face.Location();
+      Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(_face,loc);
+      if ( !aPoly.IsNull() )
+      {
+        if ( !loc.IsIdentity() )
+        {
+          norm.Transform( loc.Transformation().Inverted() );
+          O = norm.Location().XYZ(), N = norm.Direction().XYZ();
+        }
+        const double deflection = aPoly->Deflection();
+
+        const TColgp_Array1OfPnt& nodes = aPoly->Nodes();
+        for ( int i = nodes.Lower(); i <= nodes.Upper(); ++i )
+          if (( nodes( i ).XYZ() - O ) * N > _grid->_tol + deflection )
+            return false;
+      }
+      else
+      {
+        BRepAdaptor_Surface surf( _face );
+        double u0, u1, v0, v1, du, dv, u, v;
+        BRepTools::UVBounds( _face, u0, u1, v0, v1);
+        if ( surf.GetType() == GeomAbs_Plane ) {
+          du = u1 - u0, dv = v1 - v0;
+        }
+        else {
+          du = surf.UResolution( _grid->_minCellSize / 10. );
+          dv = surf.VResolution( _grid->_minCellSize / 10. );
+        }
+        for ( u = u0, v = v0; u <= u1 && v <= v1; u += du, v += dv )
+        {
+          gp_Pnt p = surf.Value( u, v );
+          if (( p.XYZ() - O ) * N > _grid->_tol )
+          {
+            TopAbs_State state = GetCurveFaceIntersector()->ClassifyUVPoint(gp_Pnt2d( u, v ));
+            if ( state == TopAbs_IN || state == TopAbs_ON )
+              return false;
+          }
+        }
+      }
+    }
+    return true;
+  }
+  //=============================================================================
+  /*
+   * Intersects TopoDS_Face with all GridLine's
+   */
+  void FaceGridIntersector::Intersect()
+  {
+    FaceLineIntersector intersector;
+    intersector._surfaceInt = GetCurveFaceIntersector();
+    intersector._tol        = _grid->_tol;
+    intersector._transOut   = _face.Orientation() == TopAbs_REVERSED ? Trans_IN : Trans_OUT;
+    intersector._transIn    = _face.Orientation() == TopAbs_REVERSED ? Trans_OUT : Trans_IN;
+
+    typedef void (FaceLineIntersector::* PIntFun )(const GridLine& gridLine);
+    PIntFun interFunction;
+
+    BRepAdaptor_Surface surf( _face );
+    switch ( surf.GetType() ) {
+    case GeomAbs_Plane:
+      intersector._plane = surf.Plane();
+      interFunction = &FaceLineIntersector::IntersectWithPlane;
+      break;
+    case GeomAbs_Cylinder:
+      intersector._cylinder = surf.Cylinder();
+      interFunction = &FaceLineIntersector::IntersectWithCylinder;
+      break;
+    case GeomAbs_Cone:
+      intersector._cone = surf.Cone();
+      interFunction = &FaceLineIntersector::IntersectWithCone;
+      break;
+    case GeomAbs_Sphere:
+      intersector._sphere = surf.Sphere();
+      interFunction = &FaceLineIntersector::IntersectWithSphere;
+      break;
+    case GeomAbs_Torus:
+      intersector._torus = surf.Torus();
+      interFunction = &FaceLineIntersector::IntersectWithTorus;
+      break;
+    default:
+      interFunction = &FaceLineIntersector::IntersectWithSurface;
+    }
+
+    _intersections.clear();
+    for ( int iDir = 0; iDir < 3; ++iDir ) // loop on 3 line directions
+    {
+      if ( surf.GetType() == GeomAbs_Plane )
+      {
+        // check if all lines in this direction are parallel to a plane
+        if ( intersector._plane.Axis().IsNormal( _grid->_lines[iDir][0]._line.Position(),
+                                                 Precision::Angular()))
+          continue;
+        // find out a transition, that is the same for all lines of a direction
+        gp_Dir plnNorm = intersector._plane.Axis().Direction();
+        gp_Dir lineDir = _grid->_lines[iDir][0]._line.Direction();
+        intersector._transition =
+          ( plnNorm * lineDir < 0 ) ? intersector._transIn : intersector._transOut;
+      }
+      if ( surf.GetType() == GeomAbs_Cylinder )
+      {
+        // check if all lines in this direction are parallel to a cylinder
+        if ( intersector._cylinder.Axis().IsParallel( _grid->_lines[iDir][0]._line.Position(),
+                                                      Precision::Angular()))
+          continue;
+      }
+
+      // intersect the grid lines with the face
+      for ( size_t iL = 0; iL < _grid->_lines[iDir].size(); ++iL )
+      {
+        GridLine& gridLine = _grid->_lines[iDir][iL];
+        if ( _bndBox.IsOut( gridLine._line )) continue;
+
+        intersector._intPoints.clear();
+        (intersector.*interFunction)( gridLine );
+        for ( size_t i = 0; i < intersector._intPoints.size(); ++i )
+          _intersections.push_back( make_pair( &gridLine, intersector._intPoints[i] ));
+      }
+    }
+  }
+  //================================================================================
+  /*
+   * Return true if (_u,_v) is on the face
+   */
+  bool FaceLineIntersector::UVIsOnFace() const
+  {
+    TopAbs_State state = _surfaceInt->ClassifyUVPoint(gp_Pnt2d( _u,_v ));
+    return ( state == TopAbs_IN || state == TopAbs_ON );
+  }
+  //================================================================================
+  /*
+   * Store an intersection if it is IN or ON the face
+   */
+  void FaceLineIntersector::addIntPoint(const bool toClassify)
+  {
+    if ( !toClassify || UVIsOnFace() )
+    {
+      IntersectionPoint p;
+      p._paramOnLine = _w;
+      p._transition  = _transition;
+      _intPoints.push_back( p );
+    }
+  }
+  //================================================================================
+  /*
+   * Intersect a line with a plane
+   */
+  void FaceLineIntersector::IntersectWithPlane   (const GridLine& gridLine)
+  {
+    IntAna_IntConicQuad linPlane( gridLine._line, _plane, Precision::Angular());
+    _w = linPlane.ParamOnConic(1);
+    if ( isParamOnLineOK( gridLine._length ))
+    {
+      ElSLib::Parameters(_plane, linPlane.Point(1) ,_u,_v);
+      addIntPoint();
+    }
+  }
+  //================================================================================
+  /*
+   * Intersect a line with a cylinder
+   */
+  void FaceLineIntersector::IntersectWithCylinder(const GridLine& gridLine)
+  {
+    IntAna_IntConicQuad linCylinder( gridLine._line,_cylinder);
+    if ( linCylinder.IsDone() && linCylinder.NbPoints() > 0 )
+    {
+      _w = linCylinder.ParamOnConic(1);
+      if ( linCylinder.NbPoints() == 1 )
+        _transition = Trans_TANGENT;
+      else
+        _transition = _w < linCylinder.ParamOnConic(2) ? _transIn : _transOut;
+      if ( isParamOnLineOK( gridLine._length ))
+      {
+        ElSLib::Parameters(_cylinder, linCylinder.Point(1) ,_u,_v);
+        addIntPoint();
+      }
+      if ( linCylinder.NbPoints() > 1 )
+      {
+        _w = linCylinder.ParamOnConic(2);
+        if ( isParamOnLineOK( gridLine._length ))
+        {
+          ElSLib::Parameters(_cylinder, linCylinder.Point(2) ,_u,_v);
+          _transition = ( _transition == Trans_OUT ) ? Trans_IN : Trans_OUT;
+          addIntPoint();
+        }
+      }
+    }
+  }
+  //================================================================================
+  /*
+   * Intersect a line with a cone
+   */
+  void FaceLineIntersector::IntersectWithCone (const GridLine& gridLine)
+  {
+    IntAna_IntConicQuad linCone(gridLine._line,_cone);
+    if ( !linCone.IsDone() ) return;
+    gp_Pnt P;
+    gp_Vec du, dv, norm;
+    for ( int i = 1; i <= linCone.NbPoints(); ++i )
+    {
+      _w = linCone.ParamOnConic( i );
+      if ( !isParamOnLineOK( gridLine._length )) continue;
+      ElSLib::Parameters(_cone, linCone.Point(i) ,_u,_v);
+      if ( UVIsOnFace() )
+      {
+        ElSLib::D1( _u, _v, _cone, P, du, dv );
+        norm = du ^ dv;
+        double normSize2 = norm.SquareMagnitude();
+        if ( normSize2 > Precision::Angular() * Precision::Angular() )
+        {
+          double cos = norm.XYZ() * gridLine._line.Direction().XYZ();
+          cos /= sqrt( normSize2 );
+          if ( cos < -Precision::Angular() )
+            _transition = _transIn;
+          else if ( cos > Precision::Angular() )
+            _transition = _transOut;
+          else
+            _transition = Trans_TANGENT;
+        }
+        else
+        {
+          _transition = Trans_APEX;
+        }
+        addIntPoint( /*toClassify=*/false);
+      }
+    }
+  }
+  //================================================================================
+  /*
+   * Intersect a line with a sphere
+   */
+  void FaceLineIntersector::IntersectWithSphere  (const GridLine& gridLine)
+  {
+    IntAna_IntConicQuad linSphere(gridLine._line,_sphere);
+    if ( linSphere.IsDone() && linSphere.NbPoints() > 0 )
+    {
+      _w = linSphere.ParamOnConic(1);
+      if ( linSphere.NbPoints() == 1 )
+        _transition = Trans_TANGENT;
+      else
+        _transition = _w < linSphere.ParamOnConic(2) ? _transIn : _transOut;
+      if ( isParamOnLineOK( gridLine._length ))
+      {
+        ElSLib::Parameters(_sphere, linSphere.Point(1) ,_u,_v);
+        addIntPoint();
+      }
+      if ( linSphere.NbPoints() > 1 )
+      {
+        _w = linSphere.ParamOnConic(2);
+        if ( isParamOnLineOK( gridLine._length ))
+        {
+          ElSLib::Parameters(_sphere, linSphere.Point(2) ,_u,_v);
+          _transition = ( _transition == Trans_OUT ) ? Trans_IN : Trans_OUT;
+          addIntPoint();
+        }
+      }
+    }
+  }
+  //================================================================================
+  /*
+   * Intersect a line with a torus
+   */
+  void FaceLineIntersector::IntersectWithTorus   (const GridLine& gridLine)
+  {
+    IntAna_IntLinTorus linTorus(gridLine._line,_torus);
+    if ( !linTorus.IsDone()) return;
+    gp_Pnt P;
+    gp_Vec du, dv, norm;
+    for ( int i = 1; i <= linTorus.NbPoints(); ++i )
+    {
+      _w = linTorus.ParamOnLine( i );
+      if ( !isParamOnLineOK( gridLine._length )) continue;
+      linTorus.ParamOnTorus( i, _u,_v );
+      if ( UVIsOnFace() )
+      {
+        ElSLib::D1( _u, _v, _torus, P, du, dv );
+        norm = du ^ dv;
+        double normSize = norm.Magnitude();
+        double cos = norm.XYZ() * gridLine._line.Direction().XYZ();
+        cos /= normSize;
+        if ( cos < -Precision::Angular() )
+          _transition = _transIn;
+        else if ( cos > Precision::Angular() )
+          _transition = _transOut;
+        else
+          _transition = Trans_TANGENT;
+        addIntPoint( /*toClassify=*/false);
+      }
+    }
+  }
+  //================================================================================
+  /*
+   * Intersect a line with a non-analytical surface
+   */
+  void FaceLineIntersector::IntersectWithSurface (const GridLine& gridLine)
+  {
+    _surfaceInt->Perform( gridLine._line, 0.0, gridLine._length );
+    if ( !_surfaceInt->IsDone() ) return;
+    for ( int i = 1; i <= _surfaceInt->NbPnt(); ++i )
+    {
+      _transition = Transition( _surfaceInt->Transition( i ) );
+      _w = _surfaceInt->WParameter( i );
+      addIntPoint(/*toClassify=*/false);
+    }
+  }
+  //================================================================================
+  /*
+   * check if its face can be safely intersected in a thread
+   */
+  bool FaceGridIntersector::IsThreadSafe(set< const Standard_Transient* >& noSafeTShapes) const
+  {
+    bool isSafe = true;
+
+    // check surface
+    TopLoc_Location loc;
+    Handle(Geom_Surface) surf = BRep_Tool::Surface( _face, loc );
+    Handle(Geom_RectangularTrimmedSurface) ts =
+      Handle(Geom_RectangularTrimmedSurface)::DownCast( surf );
+    while( !ts.IsNull() ) {
+      surf = ts->BasisSurface();
+      ts = Handle(Geom_RectangularTrimmedSurface)::DownCast(surf);
+    }
+    if ( surf->IsKind( STANDARD_TYPE(Geom_BSplineSurface )) ||
+         surf->IsKind( STANDARD_TYPE(Geom_BezierSurface )))
+      if ( !noSafeTShapes.insert((const Standard_Transient*) _face.TShape() ).second )
+        isSafe = false;
+
+    double f, l;
+    TopExp_Explorer exp( _face, TopAbs_EDGE );
+    for ( ; exp.More(); exp.Next() )
+    {
+      bool edgeIsSafe = true;
+      const TopoDS_Edge& e = TopoDS::Edge( exp.Current() );
+      // check 3d curve
+      {
+        Handle(Geom_Curve) c = BRep_Tool::Curve( e, loc, f, l);
+        if ( !c.IsNull() )
+        {
+          Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(c);
+          while( !tc.IsNull() ) {
+            c = tc->BasisCurve();
+            tc = Handle(Geom_TrimmedCurve)::DownCast(c);
+          }
+          if ( c->IsKind( STANDARD_TYPE(Geom_BSplineCurve )) ||
+               c->IsKind( STANDARD_TYPE(Geom_BezierCurve )))
+            edgeIsSafe = false;
+        }
+      }
+      // check 2d curve
+      if ( edgeIsSafe )
+      {
+        Handle(Geom2d_Curve) c2 = BRep_Tool::CurveOnSurface( e, surf, loc, f, l);
+        if ( !c2.IsNull() )
+        {
+          Handle(Geom2d_TrimmedCurve) tc = Handle(Geom2d_TrimmedCurve)::DownCast(c2);
+          while( !tc.IsNull() ) {
+            c2 = tc->BasisCurve();
+            tc = Handle(Geom2d_TrimmedCurve)::DownCast(c2);
+          }
+          if ( c2->IsKind( STANDARD_TYPE(Geom2d_BSplineCurve )) ||
+               c2->IsKind( STANDARD_TYPE(Geom2d_BezierCurve )))
+            edgeIsSafe = false;
+        }
+      }
+      if ( !edgeIsSafe && !noSafeTShapes.insert((const Standard_Transient*) e.TShape() ).second )
+        isSafe = false;
+    }
+    return isSafe;
+  }
+  //================================================================================
+  /*!
+   * \brief Creates topology of the hexahedron
+   */
+  Hexahedron::Hexahedron(const double sizeThreshold, Grid* grid)
+    : _grid( grid ), _sizeThreshold( sizeThreshold ), _nbIntNodes(0)
+  {
+    _polygons.reserve(100); // to avoid reallocation;
+
+    //set nodes shift within grid->_nodes from the node 000 
+    size_t dx = _grid->NodeIndexDX();
+    size_t dy = _grid->NodeIndexDY();
+    size_t dz = _grid->NodeIndexDZ();
+    size_t i000 = 0;
+    size_t i100 = i000 + dx;
+    size_t i010 = i000 + dy;
+    size_t i110 = i010 + dx;
+    size_t i001 = i000 + dz;
+    size_t i101 = i100 + dz;
+    size_t i011 = i010 + dz;
+    size_t i111 = i110 + dz;
+    _nodeShift[ SMESH_Block::ShapeIndex( SMESH_Block::ID_V000 )] = i000;
+    _nodeShift[ SMESH_Block::ShapeIndex( SMESH_Block::ID_V100 )] = i100;
+    _nodeShift[ SMESH_Block::ShapeIndex( SMESH_Block::ID_V010 )] = i010;
+    _nodeShift[ SMESH_Block::ShapeIndex( SMESH_Block::ID_V110 )] = i110;
+    _nodeShift[ SMESH_Block::ShapeIndex( SMESH_Block::ID_V001 )] = i001;
+    _nodeShift[ SMESH_Block::ShapeIndex( SMESH_Block::ID_V101 )] = i101;
+    _nodeShift[ SMESH_Block::ShapeIndex( SMESH_Block::ID_V011 )] = i011;
+    _nodeShift[ SMESH_Block::ShapeIndex( SMESH_Block::ID_V111 )] = i111;
+
+    vector< int > idVec;
+    // set nodes to links
+    for ( int linkID = SMESH_Block::ID_Ex00; linkID <= SMESH_Block::ID_E11z; ++linkID )
+    {
+      SMESH_Block::GetEdgeVertexIDs( linkID, idVec );
+      _Link& link = _hexLinks[ SMESH_Block::ShapeIndex( linkID )];
+      link._nodes[0] = &_hexNodes[ SMESH_Block::ShapeIndex( idVec[0] )];
+      link._nodes[1] = &_hexNodes[ SMESH_Block::ShapeIndex( idVec[1] )];
+      link._intNodes.reserve( 10 ); // to avoid reallocation
+      link._splits.reserve( 10 );
+    }
+
+    // set links to faces
+    int interlace[4] = { 0, 3, 1, 2 }; // to walk by links around a face: { u0, 1v, u1, 0v }
+    for ( int faceID = SMESH_Block::ID_Fxy0; faceID <= SMESH_Block::ID_F1yz; ++faceID )
+    {
+      SMESH_Block::GetFaceEdgesIDs( faceID, idVec );
+      _Face& quad = _hexQuads[ SMESH_Block::ShapeIndex( faceID )];
+      bool revFace = ( faceID == SMESH_Block::ID_Fxy0 ||
+                       faceID == SMESH_Block::ID_Fx1z ||
+                       faceID == SMESH_Block::ID_F0yz );
+      quad._links.resize(4);
+      vector<_OrientedLink>::iterator         frwLinkIt = quad._links.begin();
+      vector<_OrientedLink>::reverse_iterator revLinkIt = quad._links.rbegin();
+      for ( int i = 0; i < 4; ++i )
+      {
+        bool revLink = revFace;
+        if ( i > 1 ) // reverse links u1 and v0
+          revLink = !revLink;
+        _OrientedLink& link = revFace ? *revLinkIt++ : *frwLinkIt++;
+        link = _OrientedLink( & _hexLinks[ SMESH_Block::ShapeIndex( idVec[interlace[i]] )],
+                              revLink );
+      }
+    }
+  }
+  //================================================================================
+  /*!
+   * \brief Copy constructor
+   */
+  Hexahedron::Hexahedron( const Hexahedron& other )
+    :_grid( other._grid ), _sizeThreshold( other._sizeThreshold ), _nbIntNodes(0)
+  {
+    _polygons.reserve(100); // to avoid reallocation;
+
+    for ( int i = 0; i < 8; ++i )
+      _nodeShift[i] = other._nodeShift[i];
+
+    for ( int i = 0; i < 12; ++i )
+    {
+      const _Link& srcLink = other._hexLinks[ i ];
+      _Link&       tgtLink = this->_hexLinks[ i ];
+      tgtLink._nodes[0] = _hexNodes + ( srcLink._nodes[0] - other._hexNodes );
+      tgtLink._nodes[1] = _hexNodes + ( srcLink._nodes[1] - other._hexNodes );
+      tgtLink._intNodes.reserve( 10 ); // to avoid reallocation
+      tgtLink._splits.reserve( 10 );
+    }
+
+    for ( int i = 0; i < 6; ++i )
+    {
+      const _Face& srcQuad = other._hexQuads[ i ];
+      _Face&       tgtQuad = this->_hexQuads[ i ];
+      tgtQuad._links.resize(4);
+      for ( int j = 0; j < 4; ++j )
+      {
+        const _OrientedLink& srcLink = srcQuad._links[ j ];
+        _OrientedLink&       tgtLink = tgtQuad._links[ j ];
+        tgtLink._reverse = srcLink._reverse;
+        tgtLink._link    = _hexLinks + ( srcLink._link - other._hexLinks );
+      }
+    }
+  }
+  
+  //================================================================================
+  /*!
+   * \brief Initializes its data by given grid cell
+   */
+  void Hexahedron::init( size_t i, size_t j, size_t k )
+  {
+    _i = i; _j = j; _k = k;
+    // set nodes of grid to nodes of the hexahedron and
+    // count nodes at hexahedron corners located IN and ON geometry
+    _nbCornerNodes = _nbBndNodes = 0;
+    _origNodeInd   = _grid->NodeIndex( i,j,k );
+    for ( int iN = 0; iN < 8; ++iN )
+    {
+      _hexNodes[iN]._node = _grid->_nodes[ _origNodeInd + _nodeShift[iN] ];
+      _nbCornerNodes += bool( _hexNodes[iN]._node );
+      _nbBndNodes    += _grid->_isBndNode[ _origNodeInd + _nodeShift[iN] ];
+    }
+
+    _sideLength[0] = _grid->_coords[0][i+1] - _grid->_coords[0][i];
+    _sideLength[1] = _grid->_coords[1][j+1] - _grid->_coords[1][j];
+    _sideLength[2] = _grid->_coords[2][k+1] - _grid->_coords[2][k];
+
+    if ( _nbCornerNodes < 8 && _nbIntNodes + _nbCornerNodes > 3)
+    {
+      _Link split;
+      // create sub-links (_splits) by splitting links with _intNodes
+      for ( int iLink = 0; iLink < 12; ++iLink )
+      {
+        _Link& link = _hexLinks[ iLink ];
+        link._splits.clear();
+        split._nodes[ 0 ] = link._nodes[0];
+        for ( size_t i = 0; i < link._intNodes.size(); ++ i )
+        {
+          if ( split._nodes[ 0 ]->Node() )
+          {
+            split._nodes[ 1 ] = &link._intNodes[i];
+            link._splits.push_back( split );
+          }
+          split._nodes[ 0 ] = &link._intNodes[i];
+        }
+        if ( link._nodes[ 1 ]->Node() && split._nodes[ 0 ]->Node() )
+        {
+          split._nodes[ 1 ] = link._nodes[1];
+          link._splits.push_back( split );
+        }
+      }
+    }
+  }
+  //================================================================================
+  /*!
+   * \brief Initializes its data by given grid cell (countered from zero)
+   */
+  void Hexahedron::init( size_t iCell )
+  {
+    size_t iNbCell = _grid->_coords[0].size() - 1;
+    size_t jNbCell = _grid->_coords[1].size() - 1;
+    _i = iCell % iNbCell;
+    _j = ( iCell % ( iNbCell * jNbCell )) / iNbCell;
+    _k = iCell / iNbCell / jNbCell;
+    init( _i, _j, _k );
+  }
+
+  //================================================================================
+  /*!
+   * \brief Compute mesh volumes resulted from intersection of the Hexahedron
+   */
+  void Hexahedron::ComputeElements()
+  {
+    Init();
+
+    if ( _nbCornerNodes + _nbIntNodes < 4 )
+      return;
+
+    if ( _nbBndNodes == _nbCornerNodes && isInHole() )
+      return;
+
+    _polygons.clear();
+
+    vector<const SMDS_MeshNode* > polyhedraNodes;
+    vector<int>                   quantities;
+
+    // create polygons from quadrangles and get their nodes
+
+    vector<_Node*> nodes;
+    nodes.reserve( _nbCornerNodes + _nbIntNodes );
+
+    _Link polyLink;
+    polyLink._faces.reserve( 1 );
+
+    for ( int iF = 0; iF < 6; ++iF ) // loop on 6 sides of a hexahedron
+    {
+      const _Face& quad = _hexQuads[ iF ] ;
+
+      _polygons.resize( _polygons.size() + 1 );
+      _Face& polygon = _polygons.back();
+      polygon._links.clear();
+      polygon._polyLinks.clear(); polygon._polyLinks.reserve( 10 );
+
+      // add splits of a link to a polygon and collect info on nodes
+      //int nbIn = 0, nbOut = 0, nbCorners = 0;
+      nodes.clear();
+      for ( int iE = 0; iE < 4; ++iE ) // loop on 4 sides of a quadrangle
+      {
+        int nbSpits = quad._links[ iE ].NbResultLinks();
+        for ( int iS = 0; iS < nbSpits; ++iS )
+        {
+          _OrientedLink split = quad._links[ iE ].ResultLink( iS );
+          _Node* n = split.FirstNode();
+          if ( !polygon._links.empty() )
+          {
+            _Node* nPrev = polygon._links.back().LastNode();
+            if ( nPrev != n )
+            {
+              polyLink._nodes[0] = nPrev;
+              polyLink._nodes[1] = n;
+              polygon._polyLinks.push_back( polyLink );
+              polygon._links.push_back( _OrientedLink( &polygon._polyLinks.back() ));
+              nodes.push_back( nPrev );
+            }
+          }
+          polygon._links.push_back( split );
+          nodes.push_back( n );
+        }
+      }
+      if ( polygon._links.size() > 1 )
+      {
+        _Node* n1 = polygon._links.back().LastNode();
+        _Node* n2 = polygon._links.front().FirstNode();
+        if ( n1 != n2 )
+        {
+          polyLink._nodes[0] = n1;
+          polyLink._nodes[1] = n2;
+          polygon._polyLinks.push_back( polyLink );
+          polygon._links.push_back( _OrientedLink( &polygon._polyLinks.back() ));
+          nodes.push_back( n1 );
+        }
+        // add polygon to its links
+        for ( size_t iL = 0; iL < polygon._links.size(); ++iL )
+          polygon._links[ iL ]._link->_faces.push_back( &polygon );
+        // store polygon nodes
+        quantities.push_back( nodes.size() );
+        for ( size_t i = 0; i < nodes.size(); ++i )
+          polyhedraNodes.push_back( nodes[i]->Node() );
+      }
+      else
+      {
+        _polygons.resize( _polygons.size() - 1 );
+      }
+    }
+
+    // create polygons closing holes in a polyhedron
+
+    // find free links
+    vector< _OrientedLink* > freeLinks;
+    for ( size_t iP = 0; iP < _polygons.size(); ++iP )
+    {
+      _Face& polygon = _polygons[ iP ];
+      for ( size_t iL = 0; iL < polygon._links.size(); ++iL )
+        if ( polygon._links[ iL ]._link->_faces.size() < 2 )
+          freeLinks.push_back( & polygon._links[ iL ]);
+    }
+    // make closed chains of free links
+    int nbFreeLinks = freeLinks.size();
+    if ( 0 < nbFreeLinks && nbFreeLinks < 3 ) return;
+    while ( nbFreeLinks > 0 )
+    {
+      nodes.clear();
+      _polygons.resize( _polygons.size() + 1 );
+      _Face& polygon = _polygons.back();
+      polygon._links.clear();
+
+      // get a remaining link to start from
+      _OrientedLink* curLink = 0;
+      for ( size_t iL = 0; iL < freeLinks.size() && !curLink; ++iL )
+        if (( curLink = freeLinks[ iL ] ))
+          freeLinks[ iL ] = 0;
+      nodes.push_back( curLink->LastNode() );
+      polygon._links.push_back( *curLink );
+
+      // find all links connected to curLink
+      _Node* curNode = 0;
+      do
+      {
+        curNode = curLink->FirstNode();
+        curLink = 0;
+        for ( size_t iL = 0; iL < freeLinks.size() && !curLink; ++iL )
+          if ( freeLinks[ iL ] && freeLinks[ iL ]->LastNode() == curNode )
+          {
+            curLink = freeLinks[ iL ];
+            freeLinks[ iL ] = 0;
+            nodes.push_back( curNode );
+            polygon._links.push_back( *curLink );
+          }
+      } while ( curLink );
+
+      nbFreeLinks -= polygon._links.size();
+
+      if ( curNode != nodes.front() || polygon._links.size() < 3 )
+        return; // closed polygon not found -> invalid polyhedron
+
+      quantities.push_back( nodes.size() );
+      for ( size_t i = 0; i < nodes.size(); ++i )
+        polyhedraNodes.push_back( nodes[i]->Node() );
+
+      // add polygon to its links and reverse links
+      for ( size_t i = 0; i < polygon._links.size(); ++i )
+      {
+        polygon._links[i].Reverse();
+        polygon._links[i]._link->_faces.push_back( &polygon );
+      }
+
+      //const size_t firstPoly = _polygons.size();
+    }
+
+    if ( ! checkPolyhedronSize() )
+    {
+      return;
+    }
+
+    // create a classic cell if possible
+    const int nbNodes = _nbCornerNodes + _nbIntNodes;
+    bool isClassicElem = false;
+    if (      nbNodes == 8 && _polygons.size() == 6 ) isClassicElem = addHexa();
+    else if ( nbNodes == 4 && _polygons.size() == 4 ) isClassicElem = addTetra();
+    else if ( nbNodes == 6 && _polygons.size() == 5 ) isClassicElem = addPenta();
+    else if ( nbNodes == 5 && _polygons.size() == 5 ) isClassicElem = addPyra ();
+    if ( !isClassicElem )
+      _volumeDefs.set( polyhedraNodes, quantities );
+  }
+  //================================================================================
+  /*!
+   * \brief Create elements in the mesh
+   */
+  int Hexahedron::MakeElements(SMESH_MesherHelper& helper)
+  {
+    SMESHDS_Mesh* mesh = helper.GetMeshDS();
+
+    size_t nbCells[3] = { _grid->_coords[0].size() - 1,
+                          _grid->_coords[1].size() - 1,
+                          _grid->_coords[2].size() - 1 };
+    const size_t nbGridCells = nbCells[0] *nbCells [1] * nbCells[2];
+    vector< Hexahedron* > intersectedHex( nbGridCells, 0 );
+    int nbIntHex = 0;
+
+    // set intersection nodes from GridLine's to links of intersectedHex
+    int i,j,k, iDirOther[3][2] = {{ 1,2 },{ 0,2 },{ 0,1 }};
+    for ( int iDir = 0; iDir < 3; ++iDir )
+    {
+      int dInd[4][3] = { {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0} };
+      dInd[1][ iDirOther[iDir][0] ] = -1;
+      dInd[2][ iDirOther[iDir][1] ] = -1;
+      dInd[3][ iDirOther[iDir][0] ] = -1; dInd[3][ iDirOther[iDir][1] ] = -1;
+      // loop on GridLine's parallel to iDir
+      LineIndexer lineInd = _grid->GetLineIndexer( iDir );
+      for ( ; lineInd.More(); ++lineInd )
+      {
+        GridLine& line = _grid->_lines[ iDir ][ lineInd.LineIndex() ];
+        multiset< IntersectionPoint >::const_iterator ip = line._intPoints.begin();
+        for ( ; ip != line._intPoints.end(); ++ip )
+        {
+          if ( !ip->_node ) continue;
+          lineInd.SetIndexOnLine( ip->_indexOnLine );
+          for ( int iL = 0; iL < 4; ++iL ) // loop on 4 cells sharing a link
+          {
+            i = int(lineInd.I()) + dInd[iL][0];
+            j = int(lineInd.J()) + dInd[iL][1];
+            k = int(lineInd.K()) + dInd[iL][2];
+            if ( i < 0 || i >= nbCells[0] ||
+                 j < 0 || j >= nbCells[1] ||
+                 k < 0 || k >= nbCells[2] ) continue;
+
+            const size_t hexIndex = _grid->CellIndex( i,j,k );
+            Hexahedron *& hex = intersectedHex[ hexIndex ];
+            if ( !hex)
+            {
+              hex = new Hexahedron( *this );
+              hex->_i = i;
+              hex->_j = j;
+              hex->_k = k;
+              ++nbIntHex;
+            }
+            const int iLink = iL + iDir * 4;
+            hex->_hexLinks[iLink]._intNodes.push_back( _Node( 0, &(*ip) ));
+            hex->_nbIntNodes++;
+          }
+        }
+      }
+    }
+
+    // add not split hexadrons to the mesh
+    int nbAdded = 0;
+    vector<int> intHexInd( nbIntHex );
+    nbIntHex = 0;
+    for ( size_t i = 0; i < intersectedHex.size(); ++i )
+    {
+      Hexahedron * & hex = intersectedHex[ i ];
+      if ( hex )
+      {
+        intHexInd[ nbIntHex++ ] = i;
+        if ( hex->_nbIntNodes > 0 ) continue;
+        init( hex->_i, hex->_j, hex->_k );
+      }
+      else
+      {    
+        init( i );
+      }
+      if ( _nbCornerNodes == 8 && ( _nbBndNodes < _nbCornerNodes || !isInHole() ))
+      {
+        // order of _hexNodes is defined by enum SMESH_Block::TShapeID
+        SMDS_MeshElement* el =
+          mesh->AddVolume( _hexNodes[0].Node(), _hexNodes[2].Node(),
+                           _hexNodes[3].Node(), _hexNodes[1].Node(),
+                           _hexNodes[4].Node(), _hexNodes[6].Node(),
+                           _hexNodes[7].Node(), _hexNodes[5].Node() );
+        mesh->SetMeshElementOnShape( el, helper.GetSubShapeID() );
+        ++nbAdded;
+        if ( hex )
+        {
+          delete hex;
+          intersectedHex[ i ] = 0;
+          --nbIntHex;
+        }
+      }
+      else if ( _nbCornerNodes > 3  && !hex )
+      {
+        // all intersection of hex with geometry are at grid nodes
+        hex = new Hexahedron( *this );
+        hex->init( i );
+        intHexInd.push_back(0);
+        intHexInd[ nbIntHex++ ] = i;
+      }
+    }
+
+    // add elements resulted from hexadron intersection
+#ifdef WITH_TBB
+    intHexInd.resize( nbIntHex );
+    tbb::parallel_for ( tbb::blocked_range<size_t>( 0, nbIntHex ),
+                        ParallelHexahedron( intersectedHex, intHexInd ),
+                        tbb::simple_partitioner()); // ComputeElements() is called here
+    for ( size_t i = 0; i < intHexInd.size(); ++i )
+      if ( Hexahedron * hex = intersectedHex[ intHexInd[ i ]] )
+        nbAdded += hex->addElements( helper );
+#else
+    for ( size_t i = 0; i < intHexInd.size(); ++i )
+      if ( Hexahedron * hex = intersectedHex[ intHexInd[ i ]] )
+      {
+        hex->ComputeElements();
+        nbAdded += hex->addElements( helper );
+      }
+#endif
+
+    for ( size_t i = 0; i < intersectedHex.size(); ++i )
+      if ( intersectedHex[ i ] )
+        delete intersectedHex[ i ];
+
+    return nbAdded;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Adds computed elements to the mesh
+   */
+  int Hexahedron::addElements(SMESH_MesherHelper& helper)
+  {
+    int nbAdded = 0;
+    // add elements resulted from hexahedron intersection
+    //for ( size_t i = 0; i < _volumeDefs.size(); ++i )
+    {
+      vector< const SMDS_MeshNode* >& nodes = _volumeDefs._nodes;
+      
+      if ( !_volumeDefs._quantities.empty() )
+      {
+        helper.AddPolyhedralVolume( nodes, _volumeDefs._quantities );
+      }
+      else
+      {
+        switch ( nodes.size() )
+        {
+        case 8: helper.AddVolume( nodes[0],nodes[1],nodes[2],nodes[3],
+                                  nodes[4],nodes[5],nodes[6],nodes[7] );
+          break;
+        case 4: helper.AddVolume( nodes[0],nodes[1],nodes[2],nodes[3] );
+          break;
+        case 6: helper.AddVolume( nodes[0],nodes[1],nodes[2],nodes[3], nodes[4],nodes[5] );
+          break;
+        case 5:
+          helper.AddVolume( nodes[0],nodes[1],nodes[2],nodes[3],nodes[4] );
+          break;
+        }
+      }
+      nbAdded += int ( _volumeDefs._nodes.size() > 0 );
+    }
+
+    return nbAdded;
+  }
+  //================================================================================
+  /*!
+   * \brief Return true if the element is in a hole
+   */
+  bool Hexahedron::isInHole() const
+  {
+    const int ijk[3] = { _i, _j, _k };
+    IntersectionPoint curIntPnt;
+
+    // consider a cell to be in a hole if all links in any direction
+    // comes OUT of geometry
+    for ( int iDir = 0; iDir < 3; ++iDir )
+    {
+      const vector<double>& coords = _grid->_coords[ iDir ];
+      LineIndexer               li = _grid->GetLineIndexer( iDir );
+      li.SetIJK( _i,_j,_k );
+      size_t lineIndex[4] = { li.LineIndex  (),
+                              li.LineIndex10(),
+                              li.LineIndex01(),
+                              li.LineIndex11() };
+      bool allLinksOut = true, hasLinks = false;
+      for ( int iL = 0; iL < 4 && allLinksOut; ++iL ) // loop on 4 links parallel to iDir
+      {
+        const _Link& link = _hexLinks[ iL + 4*iDir ];
+        // check transition of the first node of a link
+        const IntersectionPoint* firstIntPnt = 0;
+        if ( link._nodes[0]->Node() ) // 1st node is a hexa corner
+        {
+          curIntPnt._paramOnLine = coords[ ijk[ iDir ]] - coords[0];
+          const GridLine& line = _grid->_lines[ iDir ][ lineIndex[ iL ]];
+          multiset< IntersectionPoint >::const_iterator ip =
+            line._intPoints.upper_bound( curIntPnt );
+          --ip;
+          firstIntPnt = &(*ip);
+        }
+        else if ( !link._intNodes.empty() )
+        {
+          firstIntPnt = link._intNodes[0]._intPoint;
+        }
+
+        if ( firstIntPnt )
+        {
+          hasLinks = true;
+          allLinksOut = ( firstIntPnt->_transition == Trans_OUT );
+        }
+      }
+      if ( hasLinks && allLinksOut )
+        return true;
+    }
+    return false;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Return true if a polyhedron passes _sizeThreshold criterion
+   */
+  bool Hexahedron::checkPolyhedronSize() const
+  {
+    double volume = 0;
+    for ( size_t iP = 0; iP < _polygons.size(); ++iP )
+    {
+      const _Face& polygon = _polygons[iP];
+      gp_XYZ area (0,0,0);
+      SMESH_TNodeXYZ p1 ( polygon._links[ 0 ].FirstNode()->Node() );
+      for ( size_t iL = 0; iL < polygon._links.size(); ++iL )
+      {
+        SMESH_TNodeXYZ p2 ( polygon._links[ iL ].LastNode()->Node() );
+        area += p1 ^ p2;
+        p1 = p2;
+      }
+      volume += p1 * area;
+    }
+    volume /= 6;
+
+    double initVolume = _sideLength[0] * _sideLength[1] * _sideLength[2];
+
+    return volume > initVolume / _sizeThreshold;
+  }
+  //================================================================================
+  /*!
+   * \brief Tries to create a hexahedron
+   */
+  bool Hexahedron::addHexa()
+  {
+    if ( _polygons[0]._links.size() != 4 ||
+         _polygons[1]._links.size() != 4 ||
+         _polygons[2]._links.size() != 4 ||
+         _polygons[3]._links.size() != 4 ||
+         _polygons[4]._links.size() != 4 ||
+         _polygons[5]._links.size() != 4   )
+      return false;
+    const SMDS_MeshNode* nodes[8];
+    int nbN = 0;
+    for ( int iL = 0; iL < 4; ++iL )
+    {
+      // a base node
+      nodes[iL] = _polygons[0]._links[iL].FirstNode()->Node();
+      ++nbN;
+
+      // find a top node above the base node
+      _Link* link = _polygons[0]._links[iL]._link;
+      ASSERT( link->_faces.size() > 1 );
+      // a quadrangle sharing <link> with _polygons[0]
+      _Face* quad = link->_faces[ bool( link->_faces[0] == & _polygons[0] )];
+      for ( int i = 0; i < 4; ++i )
+        if ( quad->_links[i]._link == link )
+        {
+          // 1st node of a link opposite to <link> in <quad>
+          nodes[iL+4] = quad->_links[(i+2)%4].FirstNode()->Node();
+          ++nbN;
+          break;
+        }
+    }
+    if ( nbN == 8 )
+      _volumeDefs.set( vector< const SMDS_MeshNode* >( nodes, nodes+8 ));
+
+    return nbN == 8;
+  }
+  //================================================================================
+  /*!
+   * \brief Tries to create a tetrahedron
+   */
+  bool Hexahedron::addTetra()
+  {
+    const SMDS_MeshNode* nodes[4];
+    nodes[0] = _polygons[0]._links[0].FirstNode()->Node();
+    nodes[1] = _polygons[0]._links[1].FirstNode()->Node();
+    nodes[2] = _polygons[0]._links[2].FirstNode()->Node();
+
+    _Link* link = _polygons[0]._links[0]._link;
+    ASSERT( link->_faces.size() > 1 );
+
+    // a triangle sharing <link> with _polygons[0]
+    _Face* tria = link->_faces[ bool( link->_faces[0] == & _polygons[0] )];
+    for ( int i = 0; i < 3; ++i )
+      if ( tria->_links[i]._link == link )
+      {
+        nodes[3] = tria->_links[(i+1)%3].LastNode()->Node();
+        _volumeDefs.set( vector< const SMDS_MeshNode* >( nodes, nodes+4 ));
+        return true;
+      }
+
+    return false;
+  }
+  //================================================================================
+  /*!
+   * \brief Tries to create a pentahedron
+   */
+  bool Hexahedron::addPenta()
+  {
+    // find a base triangular face
+    int iTri = -1;
+    for ( int iF = 0; iF < 5 && iTri < 0; ++iF )
+      if ( _polygons[ iF ]._links.size() == 3 )
+        iTri = iF;
+    if ( iTri < 0 ) return false;
+
+    // find nodes
+    const SMDS_MeshNode* nodes[6];
+    int nbN = 0;
+    for ( int iL = 0; iL < 3; ++iL )
+    {
+      // a base node
+      nodes[iL] = _polygons[ iTri ]._links[iL].FirstNode()->Node();
+      ++nbN;
+
+      // find a top node above the base node
+      _Link* link = _polygons[ iTri ]._links[iL]._link;
+      ASSERT( link->_faces.size() > 1 );
+      // a quadrangle sharing <link> with a base triangle
+      _Face* quad = link->_faces[ bool( link->_faces[0] == & _polygons[ iTri ] )];
+      if ( quad->_links.size() != 4 ) return false;
+      for ( int i = 0; i < 4; ++i )
+        if ( quad->_links[i]._link == link )
+        {
+          // 1st node of a link opposite to <link> in <quad>
+          nodes[iL+3] = quad->_links[(i+2)%4].FirstNode()->Node();
+          ++nbN;
+          break;
+        }
+    }
+    if ( nbN == 6 )
+      _volumeDefs.set( vector< const SMDS_MeshNode* >( nodes, nodes+6 ));
+
+    return ( nbN == 6 );
+  }
+  //================================================================================
+  /*!
+   * \brief Tries to create a pyramid
+   */
+  bool Hexahedron::addPyra()
+  {
+    // find a base quadrangle
+    int iQuad = -1;
+    for ( int iF = 0; iF < 5 && iQuad < 0; ++iF )
+      if ( _polygons[ iF ]._links.size() == 4 )
+        iQuad = iF;
+    if ( iQuad < 0 ) return false;
+
+    // find nodes
+    const SMDS_MeshNode* nodes[5];
+    nodes[0] = _polygons[iQuad]._links[0].FirstNode()->Node();
+    nodes[1] = _polygons[iQuad]._links[1].FirstNode()->Node();
+    nodes[2] = _polygons[iQuad]._links[2].FirstNode()->Node();
+    nodes[3] = _polygons[iQuad]._links[3].FirstNode()->Node();
+
+    _Link* link = _polygons[iQuad]._links[0]._link;
+    ASSERT( link->_faces.size() > 1 );
+
+    // a triangle sharing <link> with a base quadrangle
+    _Face* tria = link->_faces[ bool( link->_faces[0] == & _polygons[ iQuad ] )];
+    if ( tria->_links.size() != 3 ) return false;
+    for ( int i = 0; i < 3; ++i )
+      if ( tria->_links[i]._link == link )
+      {
+        nodes[4] = tria->_links[(i+1)%3].LastNode()->Node();
+        _volumeDefs.set( vector< const SMDS_MeshNode* >( nodes, nodes+5 ));
+        return true;
+      }
+
+    return false;
+  }
+
+} // namespace
+
+//=============================================================================
+/*!
+ * \brief Generates 3D structured Cartesian mesh in the internal part of
+ * solid shapes and polyhedral volumes near the shape boundary.
+ *  \param theMesh - mesh to fill in
+ *  \param theShape - a compound of all SOLIDs to mesh
+ *  \retval bool - true in case of success
+ */
+//=============================================================================
+
+bool StdMeshers_Cartesian_3D::Compute(SMESH_Mesh &         theMesh,
+                                      const TopoDS_Shape & theShape)
+{
+  // The algorithm generates the mesh in following steps:
+
+  // 1) Intersection of grid lines with the geometry boundary.
+  // This step allows to find out if a given node of the initial grid is
+  // inside or outside the geometry.
+
+  // 2) For each cell of the grid, check how many of it's nodes are outside
+  // of the geometry boundary. Depending on a result of this check
+  // - skip a cell, if all it's nodes are outside
+  // - skip a cell, if it is too small according to the size threshold
+  // - add a hexahedron in the mesh, if all nodes are inside
+  // - add a polyhedron in the mesh, if some nodes are inside and some outside
+
+  _computeCanceled = false;
+
+  try
+  {
+    Grid grid;
+
+    TopTools_MapOfShape faceMap;
+    for ( TopExp_Explorer fExp( theShape, TopAbs_FACE ); fExp.More(); fExp.Next() )
+      if ( !faceMap.Add( fExp.Current() ))
+        faceMap.Remove( fExp.Current() ); // remove a face shared by two solids
+
+    Bnd_Box shapeBox;
+    vector<FaceGridIntersector> facesItersectors( faceMap.Extent() );
+    TopTools_MapIteratorOfMapOfShape faceMppIt( faceMap );
+    for ( int i = 0; faceMppIt.More(); faceMppIt.Next(), ++i )
+    {
+      facesItersectors[i]._face = TopoDS::Face( faceMppIt.Key() );
+      facesItersectors[i]._grid = &grid;
+      shapeBox.Add( facesItersectors[i].GetFaceBndBox() );
+    }
+
+    vector<double> xCoords, yCoords, zCoords;
+    _hyp->GetCoordinates( xCoords, yCoords, zCoords, shapeBox );
+
+    grid.SetCoordinates( xCoords, yCoords, zCoords, theShape );
+
+    // check if the grid encloses the shape
+    if ( !_hyp->IsGridBySpacing(0) ||
+         !_hyp->IsGridBySpacing(1) ||
+         !_hyp->IsGridBySpacing(2) )
+    {
+      Bnd_Box gridBox;
+      gridBox.Add( gp_Pnt( xCoords[0], yCoords[0], zCoords[0] ));
+      gridBox.Add( gp_Pnt( xCoords.back(), yCoords.back(), zCoords.back() ));
+      double x0,y0,z0, x1,y1,z1;
+      shapeBox.Get(x0,y0,z0, x1,y1,z1);
+      if ( gridBox.IsOut( gp_Pnt( x0,y0,z0 )) ||
+           gridBox.IsOut( gp_Pnt( x1,y1,z1 )))
+        for ( size_t i = 0; i < facesItersectors.size(); ++i )
+        {
+          if ( !facesItersectors[i].IsInGrid( gridBox ))
+            return error("The grid doesn't enclose the geometry");
+#ifdef ELLIPSOLID_WORKAROUND
+          delete facesItersectors[i]._surfaceInt, facesItersectors[i]._surfaceInt = 0;
+#endif
+        }
+    }
+    if ( _computeCanceled ) return false;
+
+#ifdef WITH_TBB
+    { // copy partner faces and curves of not thread-safe types
+      set< const Standard_Transient* > tshapes;
+      BRepBuilderAPI_Copy copier;
+      for ( size_t i = 0; i < facesItersectors.size(); ++i )
+      {
+        if ( !facesItersectors[i].IsThreadSafe(tshapes) )
+        {
+          copier.Perform( facesItersectors[i]._face );
+          facesItersectors[i]._face = TopoDS::Face( copier );
+        }
+      }
+    }
+    // Intersection of grid lines with the geometry boundary.
+    tbb::parallel_for ( tbb::blocked_range<size_t>( 0, facesItersectors.size() ),
+                        ParallelIntersector( facesItersectors ),
+                        tbb::simple_partitioner());
+#else
+    for ( size_t i = 0; i < facesItersectors.size(); ++i )
+      facesItersectors[i].Intersect();
+#endif
+
+    // put interesection points onto the GridLine's; this is done after intersection
+    // to avoid contention of facesItersectors for writing into the same GridLine
+    // in case of parallel work of facesItersectors
+    for ( size_t i = 0; i < facesItersectors.size(); ++i )
+      facesItersectors[i].StoreIntersections();
+
+    SMESH_MesherHelper helper( theMesh );
+    TopExp_Explorer solidExp (theShape, TopAbs_SOLID);
+    helper.SetSubShape( solidExp.Current() );
+    helper.SetElementsOnShape( true );
+
+    if ( _computeCanceled ) return false;
+
+    // create nodes on the geometry
+    grid.ComputeNodes(helper);
+
+    if ( _computeCanceled ) return false;
+
+    // create volume elements
+    Hexahedron hex( _hyp->GetSizeThreshold(), &grid );
+    int nbAdded = hex.MakeElements( helper );
+
+    SMESHDS_Mesh* meshDS = theMesh.GetMeshDS();
+    if ( nbAdded > 0 )
+    {
+      // make all SOLIDS computed
+      if ( SMESHDS_SubMesh* sm1 = meshDS->MeshElements( solidExp.Current()) )
+      {
+        SMDS_ElemIteratorPtr volIt = sm1->GetElements();
+        for ( ; solidExp.More() && volIt->more(); solidExp.Next() )
+        {
+          const SMDS_MeshElement* vol = volIt->next();
+          sm1->RemoveElement( vol, /*isElemDeleted=*/false );
+          meshDS->SetMeshElementOnShape( vol, solidExp.Current() );
+        }
+      }
+      // make other sub-shapes computed
+      setSubmeshesComputed( theMesh, theShape );
+    }
+
+    // remove free nodes
+    if ( SMESHDS_SubMesh * smDS = meshDS->MeshElements( helper.GetSubShapeID() ))
+    {
+      // intersection nodes
+      for ( int iDir = 0; iDir < 3; ++iDir )
+      {
+        vector< GridLine >& lines = grid._lines[ iDir ];
+        for ( size_t i = 0; i < lines.size(); ++i )
+        {
+          multiset< IntersectionPoint >::iterator ip = lines[i]._intPoints.begin();
+          for ( ; ip != lines[i]._intPoints.end(); ++ip )
+            if ( ip->_node && ip->_node->NbInverseElements() == 0 )
+              meshDS->RemoveFreeNode( ip->_node, smDS, /*fromGroups=*/false );
+        }
+      }
+      // grid nodes
+      for ( size_t i = 0; i < grid._nodes.size(); ++i )
+        if ( !grid._isBndNode[i] ) // nodes on boundary are already removed
+          if ( grid._nodes[i] && grid._nodes[i]->NbInverseElements() == 0 )
+            meshDS->RemoveFreeNode( grid._nodes[i], smDS, /*fromGroups=*/false );
+    }
+
+    return nbAdded;
+
+  }
+  // SMESH_ComputeError is not caught at SMESH_submesh level for an unknown reason
+  catch ( SMESH_ComputeError& e)
+  {
+    return error( SMESH_ComputeErrorPtr( new SMESH_ComputeError( e )));
+  }
+  return false;
+}
+
+//=============================================================================
+/*!
+ *  Evaluate
+ */
+//=============================================================================
+
+bool StdMeshers_Cartesian_3D::Evaluate(SMESH_Mesh &         theMesh,
+                                       const TopoDS_Shape & theShape,
+                                       MapShapeNbElems&     theResMap)
+{
+  // TODO
+//   std::vector<int> aResVec(SMDSEntity_Last);
+//   for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
+//   if(IsQuadratic) {
+//     aResVec[SMDSEntity_Quad_Cartesian] = nb2d_face0 * ( nb2d/nb1d );
+//     int nb1d_face0_int = ( nb2d_face0*4 - nb1d ) / 2;
+//     aResVec[SMDSEntity_Node] = nb0d_face0 * ( 2*nb2d/nb1d - 1 ) - nb1d_face0_int * nb2d/nb1d;
+//   }
+//   else {
+//     aResVec[SMDSEntity_Node] = nb0d_face0 * ( nb2d/nb1d - 1 );
+//     aResVec[SMDSEntity_Cartesian] = nb2d_face0 * ( nb2d/nb1d );
+//   }
+//   SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+//   aResMap.insert(std::make_pair(sm,aResVec));
+
+  return true;
+}
+
+//=============================================================================
+namespace
+{
+  /*!
+   * \brief Event listener setting/unsetting _alwaysComputed flag to
+   *        submeshes of inferior levels to prevent their computing
+   */
+  struct _EventListener : public SMESH_subMeshEventListener
+  {
+    string _algoName;
+
+    _EventListener(const string& algoName):
+      SMESH_subMeshEventListener(/*isDeletable=*/true,"StdMeshers_Cartesian_3D::_EventListener"),
+      _algoName(algoName)
+    {}
+    // --------------------------------------------------------------------------------
+    // setting/unsetting _alwaysComputed flag to submeshes of inferior levels
+    //
+    static void setAlwaysComputed( const bool     isComputed,
+                                   SMESH_subMesh* subMeshOfSolid)
+    {
+      SMESH_subMeshIteratorPtr smIt =
+        subMeshOfSolid->getDependsOnIterator(/*includeSelf=*/false, /*complexShapeFirst=*/false);
+      while ( smIt->more() )
+      {
+        SMESH_subMesh* sm = smIt->next();
+        sm->SetIsAlwaysComputed( isComputed );
+      }
+    }
+
+    // --------------------------------------------------------------------------------
+    // unsetting _alwaysComputed flag if "Cartesian_3D" was removed
+    //
+    virtual void ProcessEvent(const int          event,
+                              const int          eventType,
+                              SMESH_subMesh*     subMeshOfSolid,
+                              SMESH_subMeshEventListenerData* data,
+                              const SMESH_Hypothesis*         hyp = 0)
+    {
+      if ( eventType == SMESH_subMesh::COMPUTE_EVENT )
+      {
+        setAlwaysComputed( subMeshOfSolid->GetComputeState() == SMESH_subMesh::COMPUTE_OK,
+                           subMeshOfSolid );
+      }
+      else
+      {
+        SMESH_Algo* algo3D = subMeshOfSolid->GetAlgo();
+        if ( !algo3D || _algoName != algo3D->GetName() )
+          setAlwaysComputed( false, subMeshOfSolid );
+      }
+    }
+
+    // --------------------------------------------------------------------------------
+    // set the event listener
+    //
+    static void SetOn( SMESH_subMesh* subMeshOfSolid, const string& algoName )
+    {
+      subMeshOfSolid->SetEventListener( new _EventListener( algoName ),
+                                        /*data=*/0,
+                                        subMeshOfSolid );
+    }
+
+  }; // struct _EventListener
+
+} // namespace
+
+//================================================================================
+/*!
+ * \brief Sets event listener to submeshes if necessary
+ *  \param subMesh - submesh where algo is set
+ * This method is called when a submesh gets HYP_OK algo_state.
+ * After being set, event listener is notified on each event of a submesh.
+ */
+//================================================================================
+
+void StdMeshers_Cartesian_3D::SetEventListener(SMESH_subMesh* subMesh)
+{
+  _EventListener::SetOn( subMesh, GetName() );
+}
+
+//================================================================================
+/*!
+ * \brief Set _alwaysComputed flag to submeshes of inferior levels to avoid their computing
+ */
+//================================================================================
+
+void StdMeshers_Cartesian_3D::setSubmeshesComputed(SMESH_Mesh&         theMesh,
+                                                   const TopoDS_Shape& theShape)
+{
+  for ( TopExp_Explorer soExp( theShape, TopAbs_SOLID ); soExp.More(); soExp.Next() )
+    _EventListener::setAlwaysComputed( true, theMesh.GetSubMesh( soExp.Current() ));
+}
+
diff --git a/src/StdMeshers/StdMeshers_Cartesian_3D.hxx b/src/StdMeshers/StdMeshers_Cartesian_3D.hxx
new file mode 100644 (file)
index 0000000..4aefa32
--- /dev/null
@@ -0,0 +1,64 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+//  File   : StdMeshers_Cartesian_3D.hxx
+//  Module : SMESH
+//
+#ifndef _SMESH_Cartesian_3D_HXX_
+#define _SMESH_Cartesian_3D_HXX_
+
+#include "SMESH_StdMeshers.hxx"
+
+#include "SMESH_3D_Algo.hxx"
+
+/*!
+ * \brief A 3D algorithm generating 3D structured Cartesian mesh in the
+ * internal part of a solid shape and polyhedral volumes near the shape boundary.
+ *
+ * Issue 0021336
+ */
+class StdMeshers_CartesianParameters3D;
+
+class STDMESHERS_EXPORT StdMeshers_Cartesian_3D : public SMESH_3D_Algo
+{
+public:
+  StdMeshers_Cartesian_3D(int hypId, int studyId, SMESH_Gen* gen);
+
+  virtual bool CheckHypothesis(SMESH_Mesh&         aMesh,
+                               const TopoDS_Shape& aShape,
+                               Hypothesis_Status&  aStatus);
+
+  virtual bool Compute(SMESH_Mesh& aMesh,  const TopoDS_Shape& aShape);
+
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
+
+  virtual void SetEventListener(SMESH_subMesh* subMesh);
+
+ private:
+
+  void setSubmeshesComputed(SMESH_Mesh& aMesh, const TopoDS_Shape& theShape );
+
+  const StdMeshers_CartesianParameters3D* _hyp;
+};
+
+#endif
index 42acee19ef87647e07c4c15b2cd38d153a9b7920..11a3cc57ad510770b043a8c13b3690cd43b38d70 100644 (file)
@@ -1,24 +1,23 @@
-//  SMESH SMESH : implementaion of SMESH idl descriptions
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
 //
-//  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.com
 //
+
+//  SMESH SMESH : implementaion of SMESH idl descriptions
 // File      : StdMeshers_CompositeHexa_3D.cxx
 // Module    : SMESH
 // Created   : Tue Nov 25 11:04:59 2008
@@ -33,7 +32,6 @@
 #include "SMESH_Comment.hxx"
 #include "SMESH_ComputeError.hxx"
 #include "SMESH_Mesh.hxx"
-#include "SMESH_MeshEditor.hxx"
 #include "SMESH_MesherHelper.hxx"
 #include "SMESH_subMesh.hxx"
 
@@ -44,6 +42,7 @@
 #include <TopExp_Explorer.hxx>
 #include <TopTools_MapIteratorOfMapOfShape.hxx>
 #include <TopTools_MapOfShape.hxx>
+#include <TopTools_SequenceOfShape.hxx>
 #include <TopoDS.hxx>
 #include <TopoDS_Edge.hxx>
 #include <TopoDS_Face.hxx>
@@ -60,8 +59,8 @@
 
 #ifdef _DEBUG_
 
-// #define DEB_FACES
-// #define DEB_GRID
+//#define DEB_FACES
+//#define DEB_GRID
 #define DUMP_VERT(msg,V) \
 // { TopoDS_Vertex v = V; gp_Pnt p = BRep_Tool::Pnt(v);\
 //   cout << msg << "( "<< p.X()<<", "<<p.Y()<<", "<<p.Z()<<" )"<<endl;}
@@ -105,11 +104,12 @@ public:
   _FaceSide(const list<TopoDS_Edge>& edges);
   _FaceSide* GetSide(const int i);
   const _FaceSide* GetSide(const int i) const;
-  int size() { return myChildren.size(); }
+  int size() const { return myChildren.size(); }
   int NbVertices() const;
   TopoDS_Vertex FirstVertex() const;
   TopoDS_Vertex LastVertex() const;
   TopoDS_Vertex Vertex(int i) const;
+  TopoDS_Edge   Edge(int i) const;
   bool Contain( const _FaceSide& side, int* which=0 ) const;
   bool Contain( const TopoDS_Vertex& vertex ) const;
   void AppendSide( const _FaceSide& side );
@@ -128,7 +128,6 @@ private:
   list< _FaceSide > myChildren;
   int               myNbChildren;
 
-  //set<const TopoDS_TShape*> myVertices;
   TopTools_MapOfShape myVertices;
 
   EQuadSides        myID; // debug
@@ -155,15 +154,21 @@ public: //** Methods to find and orient faces of 6 sides of the box **//
   //!< Try to set the side as bottom hirizontal side
   bool SetBottomSide(const _FaceSide& side, int* sideIndex=0);
 
-  //!< Return face adjacent to i-th side of this face
-  _QuadFaceGrid* FindAdjacentForSide(int i, vector<_QuadFaceGrid>& faces) const; // (0<i<4)
+  //!< Return face adjacent to zero-based i-th side of this face
+  _QuadFaceGrid* FindAdjacentForSide(int i, list<_QuadFaceGrid>& faces, EBoxSides id) const;
 
   //!< Reverse edges in order to have the bottom edge going along axes of the unit box
   void ReverseEdges(/*int e1, int e2*/);
 
   bool IsComplex() const { return !myChildren.empty(); }
 
-  typedef SMDS_SetIterator< const _QuadFaceGrid&, TChildren::const_iterator > TChildIterator;
+  int NbChildren() const { return myChildren.size(); }
+
+  typedef SMDS_SetIterator< const _QuadFaceGrid&,
+                            TChildren::const_iterator,
+                            SMDS::SimpleAccessor<const _QuadFaceGrid&,TChildren::const_iterator>,
+                            SMDS::PassAllValueFilter<_QuadFaceGrid> >
+    TChildIterator;
 
   TChildIterator GetChildren() const
   { return TChildIterator( myChildren.begin(), myChildren.end()); }
@@ -179,6 +184,9 @@ public: //** Loading and access to mesh **//
   //!< Return number of segments on the vertical sides
   int GetNbVertSegments(SMESH_Mesh& mesh, bool withBrothers=false) const;
 
+  //!< Return edge on the hirizontal bottom sides
+  int GetHoriEdges(vector<TopoDS_Edge> & edges) const;
+
   //!< Return a node by its position
   const SMDS_MeshNode* GetNode(int iHori, int iVert) const;
 
@@ -206,7 +214,7 @@ public: //** Access to member fields **//
 
 private:
 
-  bool error(std::string& text, int code = COMPERR_ALGO_FAILED)
+  bool error(const std::string& text, int code = COMPERR_ALGO_FAILED)
   { myError = SMESH_ComputeError::New( code, text ); return false; }
 
   bool error(const SMESH_ComputeErrorPtr& err)
@@ -252,7 +260,7 @@ StdMeshers_CompositeHexa_3D::StdMeshers_CompositeHexa_3D(int hypId, int studyId,
   :SMESH_3D_Algo(hypId, studyId, gen)
 {
   _name = "CompositeHexa_3D";
-  _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);      // 1 bit /shape type
+  _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);       // 1 bit /shape type
 }
 
 //================================================================================
@@ -271,35 +279,42 @@ bool StdMeshers_CompositeHexa_3D::CheckHypothesis(SMESH_Mesh&         aMesh,
 
 //================================================================================
 /*!
- * \brief Computes hexahedral mesh on a box with composite sides
- *  \param aMesh - mesh to compute
- *  \param aShape - shape to mesh
- *  \retval bool - succes sign
+ * \brief Tries to find 6 sides of a box
  */
 //================================================================================
 
-bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh&         theMesh,
-                                          const TopoDS_Shape& theShape)
+bool StdMeshers_CompositeHexa_3D::findBoxFaces( const TopoDS_Shape&    shape,
+                                                list< _QuadFaceGrid >& boxFaces,
+                                                _QuadFaceGrid * &      fBottom,
+                                                _QuadFaceGrid * &      fTop,
+                                                _QuadFaceGrid * &      fFront,
+                                                _QuadFaceGrid * &      fBack,
+                                                _QuadFaceGrid * &      fLeft,
+                                                _QuadFaceGrid * &      fRight)
 {
-  SMESH_MesherHelper helper( theMesh );
-  _quadraticMesh = helper.IsQuadraticSubMesh( theShape );
-  helper.SetElementsOnShape( true );
-
-  // -------------------------
-  // Try to find 6 side faces
-  // -------------------------
-  vector< _QuadFaceGrid > boxFaces; boxFaces.reserve( 6 );
+  list< _QuadFaceGrid >::iterator boxFace;
   TopExp_Explorer exp;
-  int iFace, nbFaces = 0;
-  for ( exp.Init(theShape, TopAbs_FACE); exp.More(); exp.Next(), ++nbFaces )
+  int nbFaces = 0;
+  for ( exp.Init( shape, TopAbs_FACE); exp.More(); exp.Next(), ++nbFaces )
   {
     _QuadFaceGrid f;
     if ( !f.Init( TopoDS::Face( exp.Current() )))
       return error (COMPERR_BAD_SHAPE);
-    bool isContinuous = false;
-    for ( int i=0; i < boxFaces.size() && !isContinuous; ++i )
-      isContinuous = boxFaces[ i ].AddContinuousFace( f );
-    if ( !isContinuous )
+
+    _QuadFaceGrid* prevContinuous = 0; 
+    for ( boxFace = boxFaces.begin(); boxFace != boxFaces.end(); ++boxFace )
+    {
+      if ( prevContinuous )
+      {
+        if ( prevContinuous->AddContinuousFace( *boxFace ))
+          boxFace = --boxFaces.erase( boxFace );
+      }
+      else if ( boxFace->AddContinuousFace( f ))
+      {
+        prevContinuous = & (*boxFace);
+      }   
+    }
+    if ( !prevContinuous )
       boxFaces.push_back( f );
   }
   // Check what we have
@@ -310,29 +325,30 @@ bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh&         theMesh,
 
   if ( boxFaces.size() != 6 && nbFaces == 6 ) { // strange ordinary box with continuous faces
     boxFaces.resize( 6 );
-    iFace = 0;
-    for ( exp.Init(theShape, TopAbs_FACE); exp.More(); exp.Next(), ++iFace )
-      boxFaces[ iFace ].Init( TopoDS::Face( exp.Current() ) );
+    boxFace = boxFaces.begin();
+    for ( exp.Init( shape, TopAbs_FACE); exp.More(); exp.Next(), ++boxFace )
+      boxFace->Init( TopoDS::Face( exp.Current() ) );
   }
   // ----------------------------------------
   // Find out position of faces within a box
   // ----------------------------------------
-
-  _QuadFaceGrid *fBottom, *fTop, *fFront, *fBack, *fLeft, *fRight;
   // start from a bottom face
-  fBottom = &boxFaces[0];
+  fBottom = &boxFaces.front();
+  fBottom->SetID( B_BOTTOM );
   // find vertical faces
-  fFront = fBottom->FindAdjacentForSide( Q_BOTTOM, boxFaces );
-  fLeft  = fBottom->FindAdjacentForSide( Q_RIGHT, boxFaces );
-  fBack  = fBottom->FindAdjacentForSide( Q_TOP, boxFaces );
-  fRight = fBottom->FindAdjacentForSide( Q_LEFT, boxFaces );
+  fFront = fBottom->FindAdjacentForSide( Q_BOTTOM, boxFaces, B_FRONT );
+  fLeft  = fBottom->FindAdjacentForSide( Q_RIGHT,  boxFaces, B_LEFT  );
+  fBack  = fBottom->FindAdjacentForSide( Q_TOP,    boxFaces, B_BACK  );
+  fRight = fBottom->FindAdjacentForSide( Q_LEFT,   boxFaces, B_RIGHT );
   // check the found
   if ( !fFront || !fBack || !fLeft || !fRight )
     return error(COMPERR_BAD_SHAPE);
-  // top face
+  // find a top face
   fTop = 0;
-  for ( int i=1; i < boxFaces.size() && !fTop; ++i ) {
-    fTop = & boxFaces[ i ];
+  for ( boxFace = ++boxFaces.begin(); boxFace != boxFaces.end() && !fTop; ++boxFace )
+  {
+    fTop = & (*boxFace);
+    fTop->SetID( B_TOP );
     if ( fTop==fFront || fTop==fLeft || fTop==fBack || fTop==fRight )
       fTop = 0;
   }
@@ -352,18 +368,39 @@ bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh&         theMesh,
   if ( !fTop )
     return error(COMPERR_BAD_SHAPE);
 
-  fBottom->SetID( B_BOTTOM );
-  fBack  ->SetID( B_BACK );
-  fLeft  ->SetID( B_LEFT );
-  fFront ->SetID( B_FRONT );
-  fRight ->SetID( B_RIGHT );
-  fTop   ->SetID( B_TOP );
-
   // orient bottom egde of faces along axes of the unit box
   fBottom->ReverseEdges();
   fBack  ->ReverseEdges();
   fLeft  ->ReverseEdges();
 
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Computes hexahedral mesh on a box with composite sides
+ *  \param aMesh - mesh to compute
+ *  \param aShape - shape to mesh
+ *  \retval bool - succes sign
+ */
+//================================================================================
+
+bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh&         theMesh,
+                                          const TopoDS_Shape& theShape)
+{
+  SMESH_MesherHelper helper( theMesh );
+  _quadraticMesh = helper.IsQuadraticSubMesh( theShape );
+  helper.SetElementsOnShape( true );
+
+  // -------------------------
+  // Try to find 6 side faces
+  // -------------------------
+  list< _QuadFaceGrid > boxFaceContainer;
+  _QuadFaceGrid *fBottom, *fTop, *fFront, *fBack, *fLeft, *fRight;
+  if ( ! findBoxFaces( theShape, boxFaceContainer,
+                       fBottom, fTop, fFront, fBack, fLeft, fRight))
+    return false;
+
   // ------------------------------------------
   // Fill columns of nodes with existing nodes
   // ------------------------------------------
@@ -417,7 +454,7 @@ bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh&         theMesh,
   // ----------------------------
   // Add internal nodes of a box
   // ----------------------------
-  // projection points of internal nodes on box subshapes by which
+  // projection points of internal nodes on box sub-shapes by which
   // coordinates of internal nodes are computed
   vector<gp_XYZ> pointsOnShapes( SMESH_Block::ID_Shell );
 
@@ -486,7 +523,7 @@ bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh&         theMesh,
     }
   }
   // faces no more needed, free memory
-  boxFaces.clear();
+  boxFaceContainer.clear();
 
   // ----------------
   // Add hexahedrons
@@ -508,6 +545,90 @@ bool StdMeshers_CompositeHexa_3D::Compute(SMESH_Mesh&         theMesh,
   return true;
 }
 
+//================================================================================
+/*!
+ *  Evaluate
+ */
+//================================================================================
+
+bool StdMeshers_CompositeHexa_3D::Evaluate(SMESH_Mesh&         theMesh,
+                                           const TopoDS_Shape& theShape,
+                                           MapShapeNbElems&    aResMap)
+{
+  // -------------------------
+  // Try to find 6 side faces
+  // -------------------------
+  list< _QuadFaceGrid > boxFaceContainer;
+  _QuadFaceGrid *fBottom, *fTop, *fFront, *fBack, *fLeft, *fRight;
+  if ( ! findBoxFaces( theShape, boxFaceContainer,
+                       fBottom, fTop, fFront, fBack, fLeft, fRight))
+    return false;
+
+  // Find a less complex side
+  _QuadFaceGrid * lessComplexSide = & boxFaceContainer.front();
+  list< _QuadFaceGrid >::iterator face = boxFaceContainer.begin();
+  for ( ++face; face != boxFaceContainer.end() && lessComplexSide->IsComplex(); ++face )
+    if ( face->NbChildren() < lessComplexSide->NbChildren() )
+      lessComplexSide = & *face;
+
+  // Get an 1D size of lessComplexSide
+  int nbSeg1 = 0;
+  vector<TopoDS_Edge> edges;
+  if ( !lessComplexSide->GetHoriEdges(edges) )
+    return false;
+  for ( size_t i = 0; i < edges.size(); ++i )
+  {
+    const vector<int>& nbElems = aResMap[ theMesh.GetSubMesh( edges[i] )];
+    if ( !nbElems.empty() )
+      nbSeg1 += Max( nbElems[ SMDSEntity_Edge ], nbElems[ SMDSEntity_Quad_Edge ]);
+  }
+
+  // Get an 1D size of a box side ortogonal to lessComplexSide
+  int nbSeg2 = 0;
+  _QuadFaceGrid* ortoSide =
+    lessComplexSide->FindAdjacentForSide( Q_LEFT, boxFaceContainer, B_UNDEFINED );
+  edges.clear();
+  if ( !ortoSide || !ortoSide->GetHoriEdges(edges) ) return false;
+  for ( size_t i = 0; i < edges.size(); ++i )
+  {
+    const vector<int>& nbElems = aResMap[ theMesh.GetSubMesh( edges[i] )];
+    if ( !nbElems.empty() )
+      nbSeg2 += Max( nbElems[ SMDSEntity_Edge ], nbElems[ SMDSEntity_Quad_Edge ]);
+  }
+
+  // Get an 2D size of a box side ortogonal to lessComplexSide
+  int nbFaces = 0, nbQuadFace = 0;
+  list< TopoDS_Face > sideFaces;
+  if ( ortoSide->IsComplex() )
+    for ( _QuadFaceGrid::TChildIterator child = ortoSide->GetChildren(); child.more(); )
+      sideFaces.push_back( child.next().GetFace() );
+  else
+    sideFaces.push_back( ortoSide->GetFace() );
+  //
+  list< TopoDS_Face >::iterator f = sideFaces.begin();
+  for ( ; f != sideFaces.end(); ++f )
+  {
+    const vector<int>& nbElems = aResMap[ theMesh.GetSubMesh( *f )];
+    if ( !nbElems.empty() )
+    {
+      nbFaces    = nbElems[ SMDSEntity_Quadrangle ];
+      nbQuadFace = nbElems[ SMDSEntity_Quad_Quadrangle ];
+    }
+  }
+
+  // Fill nb of elements
+  vector<int> aResVec(SMDSEntity_Last,0);
+  int nbSeg3 = ( nbFaces + nbQuadFace ) / nbSeg2;
+  aResVec[SMDSEntity_Node]       = (nbSeg1-1) * (nbSeg2-1) * (nbSeg3-1);
+  aResVec[SMDSEntity_Hexa]       = nbSeg1 * nbFaces;
+  aResVec[SMDSEntity_Quad_Hexa]  = nbSeg1 * nbQuadFace;
+
+  aResMap.insert( make_pair( theMesh.GetSubMesh(theShape), aResVec ));
+
+  return true;
+}
+
+
 //================================================================================
 /*!
  * \brief constructor of non-initialized _QuadFaceGrid
@@ -589,12 +710,13 @@ bool _QuadFaceGrid::Init(const TopoDS_Face& f)
 
 bool _QuadFaceGrid::AddContinuousFace( const _QuadFaceGrid& other )
 {
-  for ( int i = 0; i < 4; ++i ) {
+  for ( int i = 0; i < 4; ++i )
+  {
     const _FaceSide& otherSide = other.GetSide( i );
     int iMyCommon;
     if ( mySides.Contain( otherSide, &iMyCommon ) ) {
       // check if normals of two faces are collinear at all vertices of a otherSide
-      const double angleTol = PI / 180 / 2;
+      const double angleTol = M_PI / 180. / 2.;
       int iV, nbV = otherSide.NbVertices(), nbCollinear = 0;
       for ( iV = 0; iV < nbV; ++iV )
       {
@@ -618,14 +740,28 @@ bool _QuadFaceGrid::AddContinuousFace( const _QuadFaceGrid& other )
           myChildren.push_back( *this );
           myFace.Nullify();
         }
-        myChildren.push_back( other );
-        int otherBottomIndex = ( 4 + i - iMyCommon + 2 ) % 4;
-        myChildren.back().SetBottomSide( other.GetSide( otherBottomIndex ));
+        if ( other.IsComplex() )
+          for ( TChildIterator children = other.GetChildren(); children.more(); )
+            myChildren.push_back( children.next() );
+        else
+          myChildren.push_back( other );
+
+        myLeftBottomChild = 0;
+        //int otherBottomIndex = ( 4 + i - iMyCommon + 2 ) % 4;
+        //myChildren.back().SetBottomSide( other.GetSide( otherBottomIndex ));
+
         // collect vertices in mySides
-        mySides.AppendSide( other.GetSide(0) );
-        mySides.AppendSide( other.GetSide(1) );
-        mySides.AppendSide( other.GetSide(2) );
-        mySides.AppendSide( other.GetSide(3) );
+        if ( other.IsComplex() )
+          for ( TChildIterator children = other.GetChildren(); children.more(); )
+          {
+            const _QuadFaceGrid& child =  children.next();
+            for ( int i = 0; i < 4; ++i )
+              mySides.AppendSide( child.GetSide(i) );
+          }
+        else
+          for ( int i = 0; i < 4; ++i )
+            mySides.AppendSide( other.GetSide(i) );
+
         return true;
       }
     }
@@ -680,12 +816,17 @@ bool _QuadFaceGrid::SetBottomSide(const _FaceSide& bottom, int* sideIndex)
  */
 //================================================================================
 
-_QuadFaceGrid* _QuadFaceGrid::FindAdjacentForSide(int i, vector<_QuadFaceGrid>& faces) const
+_QuadFaceGrid* _QuadFaceGrid::FindAdjacentForSide(int                  i,
+                                                  list<_QuadFaceGrid>& faces,
+                                                  EBoxSides            id) const
 {
-  for ( int iF = 0; iF < faces.size(); ++iF ) {
-    _QuadFaceGrid* f  = &faces[ iF ];
-    if ( f != this && f->SetBottomSide( GetSide( i )))
-      return f;
+  const _FaceSide & iSide = GetSide( i );
+  list< _QuadFaceGrid >::iterator boxFace = faces.begin();
+  for ( ; boxFace != faces.end(); ++boxFace )
+  {
+    _QuadFaceGrid* f  = & (*boxFace);
+    if ( f != this && f->SetBottomSide( iSide ))
+      return f->SetID( id ), f;
   }
   return (_QuadFaceGrid*) 0;
 }
@@ -781,6 +922,13 @@ bool _QuadFaceGrid::LoadGrid( SMESH_Mesh& mesh )
   if ( !myGrid.empty() )
     return true;
 
+  SMESHDS_SubMesh* faceSubMesh = mesh.GetSubMesh( myFace )->GetSubMeshDS();
+  // check that all faces are quadrangular
+  SMDS_ElemIteratorPtr fIt = faceSubMesh->GetElements();
+  while ( fIt->more() )
+    if ( fIt->next()->NbNodes() % 4 > 0 )
+      return error("Non-quadrangular mesh faces are not allowed on sides of a composite block");
+  
   myIndexer._xSize = 1 + mySides.GetSide( Q_BOTTOM )->GetNbSegments( mesh );
   myIndexer._ySize = 1 + mySides.GetSide( Q_LEFT   )->GetNbSegments( mesh );
 
@@ -791,10 +939,8 @@ bool _QuadFaceGrid::LoadGrid( SMESH_Mesh& mesh )
 
   // store the rest nodes row by row
 
-  SMESHDS_SubMesh* faceSubMesh = mesh.GetSubMesh( myFace )->GetSubMeshDS();
-
-  SMDS_MeshNode dummy(0,0,0);
-  const SMDS_MeshElement* firstQuad = &dummy;// most left face above the last row of found nodes
+  const SMDS_MeshNode* dummy = mesh.GetMeshDS()->AddNode(0,0,0);
+  const SMDS_MeshElement* firstQuad = dummy; // most left face above the last row of found nodes
   
   int nbFoundNodes = myIndexer._xSize;
   while ( nbFoundNodes != myGrid.size() )
@@ -815,7 +961,7 @@ bool _QuadFaceGrid::LoadGrid( SMESH_Mesh& mesh )
     TIDSortedElemSet emptySet, avoidSet;
     avoidSet.insert( firstQuad );
     firstQuad = SMESH_MeshEditor::FindFaceInSet( n1down, n2down, emptySet, avoidSet);
-    if ( firstQuad && !faceSubMesh->Contains( firstQuad )) {
+    while ( firstQuad && !faceSubMesh->Contains( firstQuad )) {
       avoidSet.insert( firstQuad );
       firstQuad = SMESH_MeshEditor::FindFaceInSet( n1down, n2down, emptySet, avoidSet);
     }
@@ -861,7 +1007,7 @@ bool _QuadFaceGrid::LoadGrid( SMESH_Mesh& mesh )
       n1up   = n2up;
     }
   }
-
+  mesh.GetMeshDS()->RemoveNode(dummy);
   DumpGrid(); // debug
 
   return true;
@@ -954,21 +1100,22 @@ void _QuadFaceGrid::setBrothers( set< _QuadFaceGrid* >& notLocatedBrothers )
     TopoDS_Vertex rightVertex = GetSide( Q_BOTTOM ).LastVertex();
     DUMP_VERT("1 right bottom Vertex: ",rightVertex );
     set< _QuadFaceGrid* >::iterator brIt, brEnd = notLocatedBrothers.end();
-    for ( brIt = notLocatedBrothers.begin(); !myRightBrother && brIt != brEnd; ++brIt )
+    for ( brIt = notLocatedBrothers.begin(); brIt != brEnd; ++brIt )
     {
       _QuadFaceGrid* brother = *brIt;
       TopoDS_Vertex brotherLeftVertex = brother->GetSide( Q_BOTTOM ).FirstVertex();
       DUMP_VERT( "brother left bottom: ", brotherLeftVertex );
       if ( rightVertex.IsSame( brotherLeftVertex )) {
         myRightBrother = brother;
-        notLocatedBrothers.erase( myRightBrother );
+        notLocatedBrothers.erase( brIt );
+        break;
       }
     }
     // find upper brother
     TopoDS_Vertex upVertex = GetSide( Q_LEFT ).FirstVertex();
     DUMP_VERT("1 left up Vertex: ",upVertex);
     brIt = notLocatedBrothers.begin(), brEnd = notLocatedBrothers.end();
-    for ( ; !myUpBrother && brIt != brEnd; ++brIt )
+    for ( ; brIt != brEnd; ++brIt )
     {
       _QuadFaceGrid* brother = *brIt;
       TopoDS_Vertex brotherLeftVertex = brother->GetSide( Q_BOTTOM ).FirstVertex();
@@ -976,6 +1123,7 @@ void _QuadFaceGrid::setBrothers( set< _QuadFaceGrid* >& notLocatedBrothers )
       if ( upVertex.IsSame( brotherLeftVertex )) {
         myUpBrother = brother;
         notLocatedBrothers.erase( myUpBrother );
+        break;
       }
     }
     // recursive call
@@ -1073,6 +1221,35 @@ int _QuadFaceGrid::GetNbVertSegments(SMESH_Mesh& mesh, bool withBrothers) const
   return nbSegs;
 }
 
+//================================================================================
+/*!
+ * \brief Return edge on the hirizontal bottom sides
+ */
+//================================================================================
+
+int _QuadFaceGrid::GetHoriEdges(vector<TopoDS_Edge> & edges) const
+{
+  if ( myLeftBottomChild )
+  {
+    return myLeftBottomChild->GetHoriEdges( edges );
+  }
+  else
+  {
+    const _FaceSide* bottom  = mySides.GetSide( Q_BOTTOM );
+    int i = 0;
+    while ( true ) {
+      TopoDS_Edge e = bottom->Edge( i++ );
+      if ( e.IsNull() )
+        break;
+      else
+        edges.push_back( e );
+    }
+    if ( myRightBrother )
+      myRightBrother->GetHoriEdges( edges );
+  }
+  return edges.size();
+}
+
 //================================================================================
 /*!
  * \brief Return a node by its position
@@ -1287,7 +1464,6 @@ int _FaceSide::NbVertices() const
 {
   if ( myChildren.empty() )
     return myVertices.Extent();
-//     return myVertices.size();
 
   return myNbChildren + 1;
 }
@@ -1334,6 +1510,23 @@ TopoDS_Vertex _FaceSide::Vertex(int i) const
   return GetSide(i)->FirstVertex();
 }
 
+//================================================================================
+/*!
+ * \brief Return i-the zero-based edge of the side
+ */
+//================================================================================
+
+TopoDS_Edge _FaceSide::Edge(int i) const
+{
+  if ( i == 0 && !myEdge.IsNull() )
+    return myEdge;
+
+  if ( const _FaceSide* iSide = GetSide( i ))
+    return iSide->myEdge;
+
+  return TopoDS_Edge();
+}
+
 //=======================================================================
 //function : Contain
 //purpose  : 
@@ -1346,9 +1539,6 @@ bool _FaceSide::Contain( const _FaceSide& side, int* which ) const
     if ( which )
       *which = 0;
     int nbCommon = 0;
-//     set<const TopoDS_TShape*>::iterator v, vEnd = side.myVertices.end();
-//     for ( v = side.myVertices.begin(); v != vEnd; ++v )
-//       nbCommon += ( myVertices.find( *v ) != myVertices.end() );
     TopTools_MapIteratorOfMapOfShape vIt ( side.myVertices );
     for ( ; vIt.More(); vIt.Next() )
       nbCommon += ( myVertices.Contains( vIt.Key() ));
@@ -1372,7 +1562,6 @@ bool _FaceSide::Contain( const _FaceSide& side, int* which ) const
 bool _FaceSide::Contain( const TopoDS_Vertex& vertex ) const
 {
   return myVertices.Contains( vertex );
-//   return myVertices.find( ptr( vertex )) != myVertices.end();
 }
 
 //=======================================================================
@@ -1390,7 +1579,6 @@ void _FaceSide::AppendSide( const _FaceSide& side )
   }
   myChildren.push_back( side );
   myNbChildren++;
-  //myVertices.insert( side.myVertices.begin(), side.myVertices.end() );
   TopTools_MapIteratorOfMapOfShape vIt ( side.myVertices );
   for ( ; vIt.More(); vIt.Next() )
     myVertices.Add( vIt.Key() );
index 09b687fc17f9c0815f9c00221d0c95add6f3a766..d5b9f8b4e30eb5aeb1f92ea77d7e76361c8ce5ee 100644 (file)
@@ -1,29 +1,26 @@
-//  SMESH SMESH : implementaion of SMESH idl descriptions
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  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.com
+// 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.com
+//
+
+//  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_CompositeBlock_3D.hxx
 //  Module : SMESH
-
+//
 #ifndef _SMESH_CompositeSegment_1D_HXX_
 #define _SMESH_CompositeSegment_1D_HXX_
 
@@ -34,6 +31,7 @@ class SMESH_Mesh;
 class StdMeshers_FaceSide;
 class TopoDS_Edge;
 class TopoDS_Face;
+struct _QuadFaceGrid;
 
 /*!
  * \brief Computes hexahedral mesh on a box with composite sides
@@ -48,14 +46,25 @@ public:
   //virtual ~StdMeshers_CompositeHexa_3D();
 
   virtual bool Compute(SMESH_Mesh&         aMesh,
-                      const TopoDS_Shape& aShape);
+                       const TopoDS_Shape& aShape);
+
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
 
   virtual bool CheckHypothesis(SMESH_Mesh&         aMesh,
                                const TopoDS_Shape& aShape,
                                Hypothesis_Status&  aStatus);
 
 private:
-  // private fields
+
+  bool findBoxFaces( const TopoDS_Shape&    shape,
+                     list< _QuadFaceGrid >& boxFaceContainer,
+                     _QuadFaceGrid * &      fBottom,
+                     _QuadFaceGrid * &      fTop,
+                     _QuadFaceGrid * &      fFront,
+                     _QuadFaceGrid * &      fBack,
+                     _QuadFaceGrid * &      fLeft,
+                     _QuadFaceGrid * &      fRight);
 };
 
 #endif
index f5cf86cd995241069a87ca3aab7f50d36d4010e9..2b584703861133bc1b9f99f76dc8efcda615adc7 100644 (file)
@@ -1,30 +1,28 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
-//  File   : StdMeshers_Regular_1D.cxx
-//           Moved here from SMESH_Regular_1D.cxx
-//  Author : Paul RASCLE, EDF
+//  File   : StdMeshers_CompositeSegment_1D.cxx
 //  Module : SMESH
-//  $Header$
 //
 #include "StdMeshers_CompositeSegment_1D.hxx"
 #include "StdMeshers_FaceSide.hxx"
@@ -73,15 +71,16 @@ namespace {
    */
   //================================================================================
 
-  TopoDS_Edge nextC1Edge(const TopoDS_Edge&  edge,
-                         SMESH_Mesh &        aMesh,
-                         const bool          forward)
+  TopoDS_Edge nextC1Edge(TopoDS_Edge  edge,
+                         SMESH_Mesh & aMesh,
+                         const bool   forward)
   {
+    if (edge.Orientation() > TopAbs_REVERSED) // INTERNAL
+      edge.Orientation( TopAbs_FORWARD );
     TopoDS_Edge eNext;
     TopTools_MapOfShape edgeCounter;
     edgeCounter.Add( edge );
-    TopoDS_Vertex v;
-    v = forward ? TopExp::LastVertex( edge,1 ) : TopExp::FirstVertex( edge,1 );
+    TopoDS_Vertex v = forward ? TopExp::LastVertex(edge,true) : TopExp::FirstVertex(edge,true);
     TopTools_ListIteratorOfListOfShape ancestIt = aMesh.GetAncestors( v );
     for ( ; ancestIt.More(); ancestIt.Next() )
     {
@@ -92,11 +91,11 @@ namespace {
     if ( edgeCounter.Extent() < 3 && !eNext.IsNull() ) {
       if ( SMESH_Algo::IsContinuous( edge, eNext )) {
         // care of orientation
-        bool reverse;
-        if ( forward )
-          reverse = ( !v.IsSame( TopExp::FirstVertex( eNext, true )));
-        else
-          reverse = ( !v.IsSame( TopExp::LastVertex( eNext, true )));
+        if (eNext.Orientation() > TopAbs_REVERSED) // INTERNAL
+          eNext.Orientation( TopAbs_FORWARD );
+        TopoDS_Vertex vn =
+          forward ? TopExp::FirstVertex(eNext,true) : TopExp::LastVertex(eNext,true);
+        bool reverse = (!v.IsSame(vn));
         if ( reverse )
           eNext.Reverse();
         return eNext;
@@ -151,7 +150,9 @@ namespace {
 
   struct VertexNodesRestoringListener : public SMESH_subMeshEventListener
   {
-    VertexNodesRestoringListener():SMESH_subMeshEventListener(0) // won't be deleted by submesh
+    VertexNodesRestoringListener():
+      SMESH_subMeshEventListener(0, // won't be deleted by submesh
+                                 "StdMeshers_CompositeSegment_1D::VertexNodesRestoringListener")
     {}
   /*!
    * \brief Restore nodes on internal vertices of a complex side
@@ -167,17 +168,23 @@ namespace {
                       EventListenerData* data,
                       const SMESH_Hypothesis*  /*hyp*/)
     {
-      bool hypRemoved = ( eventType == SMESH_subMesh::ALGO_EVENT &&
-                          subMesh->GetAlgoState() != SMESH_subMesh::HYP_OK );
-      if ( hypRemoved && data )
+      if ( data && eventType == SMESH_subMesh::ALGO_EVENT )
       {
-        list<SMESH_subMesh*>::iterator smIt = data->mySubMeshes.begin();
-        for ( ; smIt != data->mySubMeshes.end(); ++smIt )
+        bool hypRemoved;
+        if ( subMesh->GetAlgoState() != SMESH_subMesh::HYP_OK )
+          hypRemoved = true;
+        else {
+          SMESH_Algo* algo = subMesh->GetAlgo();
+          hypRemoved = ( string( algo->GetName() ) != StdMeshers_CompositeSegment_1D::AlgoName());
+        }
+        if ( hypRemoved )
         {
-          if ( SMESH_subMesh* sm = *smIt ) {
-            sm->SetIsAlwaysComputed( false );
-            sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
-          }
+          list<SMESH_subMesh*>::iterator smIt = data->mySubMeshes.begin();
+          for ( ; smIt != data->mySubMeshes.end(); ++smIt )
+            if ( SMESH_subMesh* sm = *smIt ) {
+              sm->SetIsAlwaysComputed( false );
+              sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+            }
         }
       }
       // at study restoration:
@@ -224,10 +231,19 @@ StdMeshers_CompositeSegment_1D::StdMeshers_CompositeSegment_1D(int         hypId
   :StdMeshers_Regular_1D(hypId, studyId, gen)
 {
   MESSAGE("StdMeshers_CompositeSegment_1D::StdMeshers_CompositeSegment_1D");
-  _name = "CompositeSegment_1D";
+  _name = AlgoName();
   _EventListener = new VertexNodesRestoringListener();
 }
 
+//=======================================================================
+//function : AlgoName
+//purpose  : Returns algo type name
+//=======================================================================
+
+std::string StdMeshers_CompositeSegment_1D::AlgoName()
+{
+  return "CompositeSegment_1D";
+}
 //=============================================================================
 /*!
  *  
@@ -251,6 +267,35 @@ StdMeshers_CompositeSegment_1D::~StdMeshers_CompositeSegment_1D()
 
 void StdMeshers_CompositeSegment_1D::SetEventListener(SMESH_subMesh* subMesh)
 {
+  // issue 0020279. Set "_alwaysComputed" flag to the submeshes of internal
+  // vertices of composite edge in order to avoid creation of vertices on
+  // them for the sake of stability.
+
+  // check if "_alwaysComputed" is not yet set
+  bool isAlwaysComputed = false;
+  SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false);
+  while ( !isAlwaysComputed && smIt->more() )
+    isAlwaysComputed = smIt->next()->IsAlwaysComputed();
+
+  if ( !isAlwaysComputed )
+  {
+    // check if an edge is a part of a complex side
+    TopoDS_Face face;
+    TopoDS_Edge edge = TopoDS::Edge( subMesh->GetSubShape() );
+    auto_ptr< StdMeshers_FaceSide > side
+      ( StdMeshers_CompositeSegment_1D::GetFaceSide(*subMesh->GetFather(),edge, face, false ));
+    if ( side->NbEdges() > 1 ) { // complex
+
+      // set _alwaysComputed to vertices
+      for ( int iE = 1; iE < side->NbEdges(); ++iE )
+      {
+        TopoDS_Vertex V = side->FirstVertex( iE );
+        SMESH_subMesh* sm = side->GetMesh()->GetSubMesh( V );
+        sm->SetIsAlwaysComputed( true );
+      }
+    }
+  }
+  // set listener that will remove _alwaysComputed from submeshes at algorithm change
   subMesh->SetEventListener( _EventListener, 0, subMesh);
   StdMeshers_Regular_1D::SetEventListener( subMesh );
 }
@@ -268,14 +313,17 @@ StdMeshers_CompositeSegment_1D::GetFaceSide(SMESH_Mesh&        aMesh,
                                             const bool         ignoreMeshed)
 {
   list< TopoDS_Edge > edges;
-  edges.push_back( anEdge );
+  if ( anEdge.Orientation() <= TopAbs_REVERSED )
+    edges.push_back( anEdge );
+  else
+    edges.push_back( TopoDS::Edge( anEdge.Oriented( TopAbs_FORWARD ))); // PAL21718
 
   list <const SMESHDS_Hypothesis *> hypList;
   SMESH_Algo* theAlgo = aMesh.GetGen()->GetAlgo( aMesh, anEdge );
   if ( theAlgo ) hypList = theAlgo->GetUsedHypothesis(aMesh, anEdge, false);
   for ( int forward = 0; forward < 2; ++forward )
   {
-    TopoDS_Edge eNext = nextC1Edge( anEdge, aMesh, forward );
+    TopoDS_Edge eNext = nextC1Edge( edges.back(), aMesh, forward );
     while ( !eNext.IsNull() ) {
       if ( ignoreMeshed ) {
         // eNext must not have computed mesh
@@ -289,6 +337,8 @@ StdMeshers_CompositeSegment_1D::GetFaceSide(SMESH_Mesh&        aMesh,
            string(theAlgo->GetName()) != algo->GetName() ||
            hypList != algo->GetUsedHypothesis(aMesh, eNext, false))
         break;
+      if ( std::find( edges.begin(), edges.end(), eNext ) != edges.end() )
+        break;
       if ( forward )
         edges.push_back( eNext );
       else
index 1ec16033536ceada8969f039607090a21d497321..c1beab20604c09ca46d19fae3584158e17564751 100644 (file)
@@ -1,28 +1,28 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_CompositeSegment_1D.hxx
 //  Module : SMESH
-//  $Header$
 //
 #ifndef _SMESH_CompositeSegment_1D_HXX_
 #define _SMESH_CompositeSegment_1D_HXX_
@@ -43,7 +43,7 @@ public:
   virtual ~StdMeshers_CompositeSegment_1D();
 
   virtual bool Compute(SMESH_Mesh&         aMesh,
-                      const TopoDS_Shape& aShape);
+                       const TopoDS_Shape& aShape);
   /*!
    * \brief Sets event listener to submeshes if necessary
     * \param subMesh - submesh where algo is set
@@ -61,6 +61,11 @@ public:
                                            const TopoDS_Face& aFace,
                                            const bool         ignoreMeshed);
 
+  /*!
+   * \brief Returns algo type name
+   */
+  static std::string AlgoName();
+
 protected:
   SMESH_subMeshEventListener* _EventListener;
 };
index 42ad9219a50bcf938bc4f67114b088df717d6f5f..92e8589e70f8e575a2e1f94a5abe1e15d4b0244a 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH StdMeshers_Deflection1D : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_Deflection1D.cxx
 //  Module : SMESH
@@ -203,7 +204,7 @@ bool StdMeshers_Deflection1D::SetParametersByMesh(const SMESH_Mesh*   theMesh,
   {
     const TopoDS_Edge& edge = TopoDS::Edge( edgeMap( iE ));
     Handle(Geom_Curve) C = BRep_Tool::Curve( edge, L, UMin, UMax );
-    GeomAdaptor_Curve AdaptCurve(C);
+    GeomAdaptor_Curve AdaptCurve(C, UMin, UMax);
     if ( AdaptCurve.GetType() != GeomAbs_Line )
     {
       vector< double > params;
index a3cf19b70607c0e55fae27e9f82a3f3fb4f8f8b8..4f7ea0975f8c2ee7c75b55d4ba15e2ccf56a6acc 100644 (file)
@@ -1,29 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH StdMeshers : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_Deflection1D.hxx
 //  Module : SMESH
 //
-
 #ifndef _StdMeshers_Deflection1D_HXX_
 #define _StdMeshers_Deflection1D_HXX_
 
index f2e591f342928e4b2cb4d414d94a0a1f88956e8c..fca2976f7311b413bfa0cbc3f5f3d902bb0d42df 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH StdMeshers : implementaion of point distribution algorithm
 //  File   : StdMeshers_Distribution.cxx
 //  Author : Alexandre SOLOVYOV
@@ -303,21 +304,21 @@ double dihotomySolve( Function& f, const double val, const double _start, const
 }
 
 bool buildDistribution( const TCollection_AsciiString& f, const int conv, const double start, const double end,
-                       const int nbSeg, vector<double>& data, const double eps )
+                        const int nbSeg, vector<double>& data, const double eps )
 {
   FunctionExpr F( f.ToCString(), conv );
   return buildDistribution( F, start, end, nbSeg, data, eps );
 }
 
 bool buildDistribution( const std::vector<double>& f, const int conv, const double start, const double end,
-                       const int nbSeg, vector<double>& data, const double eps )
+                        const int nbSeg, vector<double>& data, const double eps )
 {
   FunctionTable F( f, conv );
   return buildDistribution( F, start, end, nbSeg, data, eps );
 }
 
 bool buildDistribution( const Function& func, const double start, const double end, const int nbSeg,
-                       vector<double>& data, const double eps )
+                        vector<double>& data, const double eps )
 {
   if( nbSeg<=0 )
     return false;
index 373305b6320cadd3677c00ef1c5b998efe960ef4..10ba4cde81324f5a1387c53685a4d88bc55e26e6 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH StdMeshers : implementaion of point distribution algorithm
 //  File   : StdMeshers_Distribution.hxx
 //  Author : Alexandre SOLOVYOV
@@ -102,16 +103,16 @@ private:
 
 STDMESHERS_EXPORT
 bool buildDistribution( const Function& f,
-                       const double start, const double end,
-                       const int nbSeg,
-                       std::vector<double>& data,
-                       const double eps );
+                        const double start, const double end,
+                        const int nbSeg,
+                        std::vector<double>& data,
+                        const double eps );
 
 STDMESHERS_EXPORT
 bool buildDistribution( const TCollection_AsciiString& f, const int conv, const double start, const double end,
-                       const int nbSeg, std::vector<double>& data, const double eps );
+                        const int nbSeg, std::vector<double>& data, const double eps );
 STDMESHERS_EXPORT
 bool buildDistribution( const std::vector<double>& f, const int conv, const double start, const double end,
-                       const int nbSeg, std::vector<double>& data, const double eps );
+                        const int nbSeg, std::vector<double>& data, const double eps );
 
 #endif
index 7719b4f6e799628d4678b0d3d5f9110e835e3ced..13c2d626316a46f1d5098e4912b2bffc1e8b5d4a 100644 (file)
@@ -1,25 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-//  SMESH SMESH : implementaion of SMESH idl descriptions
+
 // File      : StdMeshers_FaceSide.hxx
 // Created   : Wed Jan 31 18:41:25 2007
 // Author    : Edward AGAPOV (eap)
 #include "SMDS_MeshNode.hxx"
 #include "SMESHDS_Mesh.hxx"
 #include "SMESHDS_SubMesh.hxx"
-//#include "SMESH_Algo.hxx"
+#include "SMESH_Algo.hxx"
 #include "SMESH_Mesh.hxx"
-#include "SMESH_MeshEditor.hxx"
+#include "SMESH_MesherHelper.hxx"
 #include "SMESH_ComputeError.hxx"
 #include "SMESH_Block.hxx"
 
 #include <Adaptor2d_Curve2d.hxx>
 #include <BRepAdaptor_CompCurve.hxx>
-#include <BRepAdaptor_Curve.hxx>
 #include <BRep_Builder.hxx>
 #include <BRep_Tool.hxx>
+#include <GCPnts_AbscissaPoint.hxx>
+#include <Geom2dAdaptor_Curve.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
 #include <TopoDS_Face.hxx>
 #include <TopoDS_Vertex.hxx>
 #include <TopoDS_Wire.hxx>
@@ -85,30 +87,36 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace,
                                          const bool         theIgnoreMediumNodes)
 {
   int nbEdges = theEdges.size();
-  myEdge.resize( nbEdges );
-  myC2d.resize( nbEdges );
-  myFirst.resize( nbEdges );
-  myLast.resize( nbEdges );
-  myNormPar.resize( nbEdges );
-  myLength = 0;
-  myNbPonits = myNbSegments = 0;
-  myMesh = theMesh;
+  myEdge.resize      ( nbEdges );
+  myEdgeID.resize    ( nbEdges );
+  myC2d.resize       ( nbEdges );
+  myC3dAdaptor.resize( nbEdges );
+  myFirst.resize     ( nbEdges );
+  myLast.resize      ( nbEdges );
+  myNormPar.resize   ( nbEdges );
+  myEdgeLength.resize( nbEdges );
+  myIsUniform.resize ( nbEdges, true );
+  myLength             = 0;
+  myNbPonits           = myNbSegments = 0;
+  myMesh               = theMesh;
   myMissingVertexNodes = false;
-  myIgnoreMediumNodes = theIgnoreMediumNodes;
+  myIgnoreMediumNodes  = theIgnoreMediumNodes;
+  myDefaultPnt2d       = gp_Pnt2d( 1e+100, 1e+100 );
   if ( nbEdges == 0 ) return;
 
   SMESHDS_Mesh* meshDS = theMesh->GetMeshDS();
-  vector<double> len( nbEdges );
 
   int nbDegen = 0;
   list<TopoDS_Edge>::iterator edge = theEdges.begin();
+  TopoDS_Iterator vExp;
   for ( int index = 0; edge != theEdges.end(); ++index, ++edge )
   {
-    int i = theIsForward ? index : nbEdges - index - 1;
-    len[i] = SMESH_Algo::EdgeLength( *edge );
-    if ( len[i] < DBL_MIN ) nbDegen++;
-    myLength += len[i];
+    int i = theIsForward ? index : nbEdges-index-1;
+    myEdgeLength[i] = SMESH_Algo::EdgeLength( *edge );
+    if ( myEdgeLength[i] < DBL_MIN ) nbDegen++;
+    myLength += myEdgeLength[i];
     myEdge[i] = *edge;
+    myEdgeID[i] = meshDS->ShapeToIndex( *edge );
     if ( !theIsForward ) myEdge[i].Reverse();
 
     if ( theFace.IsNull() )
@@ -128,16 +136,43 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace,
       myNbPonits += nbN;
       myNbSegments += sm->NbElements();
     }
-    if ( SMESH_Algo::VertexNode( TopExp::FirstVertex( *edge, 1), meshDS ))
+    // TopExp::FirstVertex() and TopExp::LastVertex() return NULL from INTERNAL edge
+    vExp.Initialize( *edge );
+    if ( vExp.Value().Orientation() == TopAbs_REVERSED ) vExp.Next();
+    if ( SMESH_Algo::VertexNode( TopoDS::Vertex( vExp.Value()), meshDS ))
       myNbPonits += 1; // for the first end
     else
       myMissingVertexNodes = true;
-  }
-  if ( SMESH_Algo::VertexNode( TopExp::LastVertex( theEdges.back(), 1), meshDS ))
-    myNbPonits++; // for the last end
-  else
-    myMissingVertexNodes = true;
 
+    // check if edge has non-uniform parametrization (issue 0020705)
+    if ( !myC2d[i].IsNull() && myEdgeLength[i] > DBL_MIN)
+    {
+      Geom2dAdaptor_Curve A2dC( myC2d[i],
+                                std::min( myFirst[i], myLast[i] ),
+                                std::max( myFirst[i], myLast[i] ));
+      double p2 = myFirst[i]+(myLast[i]-myFirst[i])/2., p4 = myFirst[i]+(myLast[i]-myFirst[i])/4.;
+      double d2 = GCPnts_AbscissaPoint::Length( A2dC, myFirst[i], p2 );
+      double d4 = GCPnts_AbscissaPoint::Length( A2dC, myFirst[i], p4 );
+      //cout<<"len = "<<len<<"  d2 = "<<d2<<"  fabs(2*d2/len-1.0) = "<<fabs(2*d2/len-1.0)<<endl;
+      myIsUniform[i] = !( fabs(2*d2/myEdgeLength[i]-1.0) > 0.01 || fabs(2*d4/d2-1.0) > 0.01 );
+      if ( !myIsUniform[i] )
+      {
+        double fp,lp;
+        TopLoc_Location L;
+        Handle(Geom_Curve) C3d = BRep_Tool::Curve(myEdge[i],L,fp,lp);
+        myC3dAdaptor[i].Load( C3d, fp,lp );
+      }
+    }
+  }
+  vExp.Initialize( theEdges.back() );
+  if ( vExp.Value().Orientation() != TopAbs_REVERSED ) vExp.Next();
+  if ( vExp.More() )
+  {
+    if ( SMESH_Algo::VertexNode( TopoDS::Vertex( vExp.Value()), meshDS ))
+      myNbPonits++; // for the last end
+    else
+      myMissingVertexNodes = true;
+  }
   if ( nbEdges > 1 && myLength > DBL_MIN ) {
     const double degenNormLen = 1.e-5;
     double totLength = myLength;
@@ -145,9 +180,9 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace,
       totLength += myLength * degenNormLen * nbDegen;
     double prevNormPar = 0;
     for ( int i = 0; i < nbEdges; ++i ) {
-      if ( len[ i ] < DBL_MIN )
-        len[ i ] = myLength * degenNormLen;
-      myNormPar[ i ] = prevNormPar + len[i]/totLength;
+      if ( myEdgeLength[ i ] < DBL_MIN )
+        myEdgeLength[ i ] = myLength * degenNormLen;
+      myNormPar[ i ] = prevNormPar + myEdgeLength[i]/totLength;
       prevNormPar = myNormPar[ i ];
     }
   }
@@ -155,6 +190,34 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace,
   //dump();
 }
 
+//================================================================================
+/*!
+ * \brief Constructor of a side for vertex using data from other FaceSide
+  * \param theVertex - the vertex
+  * \param theSide - the side
+ */
+//================================================================================
+
+StdMeshers_FaceSide::StdMeshers_FaceSide(const SMDS_MeshNode* theNode,
+                                         const gp_Pnt2d thePnt2d,
+                                         const StdMeshers_FaceSide* theSide)
+{
+  myC2d.resize(1);
+  myLength = 0;
+  myMesh = theSide->GetMesh();
+  myDefaultPnt2d = thePnt2d;
+
+  myPoints = theSide->GetUVPtStruct();
+  myNbPonits = myNbSegments = myPoints.size();
+  std::vector<uvPtStruct>::iterator it = myPoints.begin();
+  for(; it!=myPoints.end(); it++) {
+    (*it).u = thePnt2d.X();
+    (*it).v = thePnt2d.Y();
+    (*it).y = 0.0;
+    (*it).node = theNode;
+  }
+}
+
 //================================================================================
 /*!
  * \brief Return info on nodes on the side
@@ -170,6 +233,8 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool   isXConst,
     if ( NbEdges() == 0 ) return myPoints;
 
     SMESHDS_Mesh* meshDS = myMesh->GetMeshDS();
+    SMESH_MesherHelper helper(*myMesh);
+    bool paramOK;
 
     // sort nodes of all edges putting them into a map
 
@@ -177,51 +242,72 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool   isXConst,
     //int nbOnDegen = 0;
     for ( int i = 0; i < myEdge.size(); ++i )
     {
-      // put 1st vertex node
-      TopoDS_Vertex VFirst, VLast;
-      TopExp::Vertices( myEdge[i], VFirst, VLast, true);
-      const SMDS_MeshNode* node = SMESH_Algo::VertexNode( VFirst, meshDS );
+      // Put 1st vertex node of a current edge
+      TopoDS_Vertex VV[2]; // TopExp::FirstVertex() returns NULL for INTERNAL edge
+      VV[0] = SMESH_MesherHelper::IthVertex( 0, myEdge[i]);
+      VV[1] = SMESH_MesherHelper::IthVertex( 1, myEdge[i]);
+      const SMDS_MeshNode* node = SMESH_Algo::VertexNode( VV[0], meshDS );
       double prevNormPar = ( i == 0 ? 0 : myNormPar[ i-1 ]); // normalized param
-      if ( node ) { // internal nodes may be missing
-        u2node.insert( make_pair( prevNormPar, node ));
-      } else if ( i == 0 ) {
+      if ( node ) { // nodes on internal vertices may be missing
+        u2node.insert( u2node.end(), make_pair( prevNormPar, node ));
+      }
+      else if ( i == 0 ) {
         MESSAGE(" NO NODE on VERTEX" );
         return myPoints;
       }
 
-      // put 2nd vertex node for a last edge
+      // Put internal nodes
+      if ( SMESHDS_SubMesh* sm = meshDS->MeshElements( myEdge[i] ))
+      {
+        vector< pair< double, const SMDS_MeshNode*> > u2nodeVec;
+        u2nodeVec.reserve( sm->NbNodes() );
+        SMDS_NodeIteratorPtr nItr = sm->GetNodes();
+        double paramSize = myLast[i] - myFirst[i];
+        double r         = myNormPar[i] - prevNormPar;
+        helper.SetSubShape( myEdge[i] );
+        helper.ToFixNodeParameters( true );
+        if ( !myIsUniform[i] )
+          while ( nItr->more() )
+          {
+            const SMDS_MeshNode* node = nItr->next();
+            if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge ))
+              continue;
+            double u = helper.GetNodeU( myEdge[i], node, 0, &paramOK );
+            double aLenU = GCPnts_AbscissaPoint::Length
+              ( const_cast<GeomAdaptor_Curve&>( myC3dAdaptor[i]), myFirst[i], u );
+            if ( myEdgeLength[i] < aLenU ) // nonregression test "3D_mesh_NETGEN/G6"
+            {
+              u2nodeVec.clear();
+              break;
+            }
+            double normPar = prevNormPar + r*aLenU/myEdgeLength[i];
+            u2nodeVec.push_back( make_pair( normPar, node ));
+          }
+        nItr = sm->GetNodes();
+        if ( u2nodeVec.empty() )
+          while ( nItr->more() )
+          {
+            const SMDS_MeshNode* node = nItr->next();
+            if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge ))
+              continue;
+            double u = helper.GetNodeU( myEdge[i], node, 0, &paramOK );
+
+            // paramSize is signed so orientation is taken into account
+            double normPar = prevNormPar + r * ( u - myFirst[i] ) / paramSize;
+            u2nodeVec.push_back( make_pair( normPar, node ));
+          }
+        for ( size_t j = 0; j < u2nodeVec.size(); ++j )
+        u2node.insert( u2node.end(), u2nodeVec[j] );
+      }
+
+      // Put 2nd vertex node for a last edge
       if ( i+1 == myEdge.size() ) {
-        node = SMESH_Algo::VertexNode( VLast, meshDS );
+        node = SMESH_Algo::VertexNode( VV[1], meshDS );
         if ( !node ) {
           MESSAGE(" NO NODE on VERTEX" );
           return myPoints;
         }
-        u2node.insert( make_pair( 1., node ));
-      }
-
-      // put internal nodes
-      SMESHDS_SubMesh* sm = meshDS->MeshElements( myEdge[i] );
-      if ( !sm ) continue;
-      SMDS_NodeIteratorPtr nItr = sm->GetNodes();
-      double paramSize = myLast[i] - myFirst[i], r = myNormPar[i] - prevNormPar;
-      while ( nItr->more() ) {
-        const SMDS_MeshNode* node = nItr->next();
-        if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge ))
-          continue;
-        const SMDS_EdgePosition* epos =
-          static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
-        double u = epos->GetUParameter();
-        // paramSize is signed so orientation is taken into account
-        double normPar = prevNormPar + r * ( u - myFirst[i] ) / paramSize;
-#ifdef _DEBUG_
-        if ( normPar > 1 || normPar < 0) {
-          dump("DEBUG");
-          MESSAGE ( "WRONG normPar: "<<normPar<< " prevNormPar="<<prevNormPar
-                    << " u="<<u << " myFirst[i]="<<myFirst[i]<< " myLast[i]="<<myLast[i]
-                    << " paramSize="<<paramSize );
-        }
-#endif
-        u2node.insert( make_pair( normPar, node ));
+        u2node.insert( u2node.end(), make_pair( 1., node ));
       }
     }
     if ( u2node.size() != myNbPonits ) {
@@ -244,7 +330,11 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool   isXConst,
       uvPt.x = uvPt.y = uvPt.normParam = u_node->first;
       if ( isXConst ) uvPt.x = constValue;
       else            uvPt.y = constValue;
-      if ( myNormPar[ EdgeIndex ] < uvPt.normParam ) {
+      const SMDS_EdgePosition* epos =
+        dynamic_cast<const SMDS_EdgePosition*>(uvPt.node->GetPosition());
+      if (( myNormPar[ EdgeIndex ] < uvPt.normParam ) ||
+          ( epos && uvPt.node->getshapeId() != myEdgeID[ EdgeIndex ])) // for myMissingVertexNodes
+      {
         prevNormPar = myNormPar[ EdgeIndex ];
         ++EdgeIndex;
 #ifdef _DEBUG_
@@ -258,8 +348,6 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool   isXConst,
 #endif
         paramSize = myNormPar[ EdgeIndex ] - prevNormPar;
       }
-      const SMDS_EdgePosition* epos =
-        dynamic_cast<const SMDS_EdgePosition*>(uvPt.node->GetPosition().get());
       if ( epos ) {
         uvPt.param = epos->GetUParameter();
       }
@@ -328,9 +416,92 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::SimulateUVPtStruct(int    nbSeg,
   }
   return myFalsePoints;
 }
-// gp_Pnt StdMeshers_FaceSide::Value(double U) const
-// {
-// }
+
+//=======================================================================
+//function : GetOrderedNodes
+//purpose  : Return nodes in the order they encounter while walking along the side
+//=======================================================================
+
+std::vector<const SMDS_MeshNode*> StdMeshers_FaceSide::GetOrderedNodes() const
+{
+  vector<const SMDS_MeshNode*> resultNodes;
+  if ( myPoints.empty() )
+  {
+    if ( NbEdges() == 0 ) return resultNodes;
+
+    SMESHDS_Mesh* meshDS = myMesh->GetMeshDS();
+    SMESH_MesherHelper helper(*myMesh);
+    bool paramOK;
+
+    // Sort nodes of all edges putting them into a map
+
+    map< double, const SMDS_MeshNode*> u2node;
+    for ( int i = 0; i < myEdge.size(); ++i )
+    {
+      // Put 1st vertex node of a current edge
+      TopoDS_Vertex VV[2]; // TopExp::FirstVertex() returns NULL for INTERNAL edge
+      VV[0] = SMESH_MesherHelper::IthVertex( 0, myEdge[i]);
+      VV[1] = SMESH_MesherHelper::IthVertex( 1, myEdge[i]);
+      const SMDS_MeshNode* node = SMESH_Algo::VertexNode( VV[0], meshDS );
+      double prevNormPar = ( i == 0 ? 0 : myNormPar[ i-1 ]); // normalized param
+      if ( node ) { // nodes on internal vertices may be missing
+        u2node.insert( make_pair( prevNormPar, node ));
+      }
+      else if ( i == 0 ) {
+        MESSAGE(" NO NODE on VERTEX" );
+        return resultNodes;
+      }
+
+      // Put internal nodes
+      if ( SMESHDS_SubMesh* sm = meshDS->MeshElements( myEdge[i] ))
+      {
+        SMDS_NodeIteratorPtr nItr = sm->GetNodes();
+        double paramSize = myLast[i] - myFirst[i];
+        double r         = myNormPar[i] - prevNormPar;
+        helper.SetSubShape( myEdge[i] );
+        helper.ToFixNodeParameters( true );
+        while ( nItr->more() )
+        {
+          const SMDS_MeshNode* node = nItr->next();
+          if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge ))
+            continue;
+          double u = helper.GetNodeU( myEdge[i], node, 0, &paramOK );
+
+          // paramSize is signed so orientation is taken into account
+          double normPar = prevNormPar + r * ( u - myFirst[i] ) / paramSize;
+          u2node.insert( u2node.end(), make_pair( normPar, node ));
+        }
+      }
+
+      // Put 2nd vertex node for a last edge
+      if ( i+1 == myEdge.size() ) {
+        node = SMESH_Algo::VertexNode( VV[1], meshDS );
+        if ( !node ) {
+          return resultNodes;
+        }
+        u2node.insert( u2node.end(), make_pair( 1., node ));
+      }
+    }
+
+    // Fill the result vector
+
+    if ( u2node.size() == myNbPonits )
+    {
+      resultNodes.reserve( u2node.size() );
+      map< double, const SMDS_MeshNode*>::iterator u2n = u2node.begin();
+      for ( ; u2n != u2node.end(); ++u2n )
+        resultNodes.push_back( u2n->second );
+    }
+  }
+  else
+  {
+    resultNodes.resize( myPoints.size() );
+    for ( size_t i = 0; i < myPoints.size(); ++i )
+      resultNodes[i] = myPoints[i].node;
+  }
+
+  return resultNodes;
+}
 
 //================================================================================
 /*!
@@ -362,14 +533,21 @@ void StdMeshers_FaceSide::Reverse()
   }
   if ( nbEdges > 1 ) {
     reverse( myEdge );
+    reverse( myEdgeID );
     reverse( myC2d );
+    reverse( myC3dAdaptor );
     reverse( myFirst );
     reverse( myLast );
     reverse( myNormPar );
+    reverse( myEdgeLength );
+    reverse( myIsUniform );
+  }
+  if ( nbEdges > 0 )
+  {
+    myNormPar[nbEdges-1]=1.;
+    myPoints.clear();
+    myFalsePoints.clear();
   }
-  myNormPar[nbEdges-1]=1.;
-  myPoints.clear();
-  myFalsePoints.clear();
 }
 
 //================================================================================
@@ -443,17 +621,19 @@ BRepAdaptor_CompCurve* StdMeshers_FaceSide::GetCurve3d() const
   if ( myEdge.empty() )
     return 0;
 
-//   if ( myEdge.size() == 1 )
-//     return new BRepAdaptor_Curve( myEdge[0] );
-
   TopoDS_Wire aWire;
   BRep_Builder aBuilder;
   aBuilder.MakeWire(aWire);
   for ( int i=0; i<myEdge.size(); ++i )
     aBuilder.Add( aWire, myEdge[i] );
+
+  if ( myEdge.size() == 2 && FirstVertex().IsSame( LastVertex() ))
+    aWire.Closed(true); // issue 0021141
+
   return new BRepAdaptor_CompCurve( aWire );
 }
 
+
 //================================================================================
 /*!
  * \brief Return 2D point by normalized parameter
@@ -468,9 +648,23 @@ gp_Pnt2d StdMeshers_FaceSide::Value2d(double U) const
     int i = EdgeIndex( U );
     double prevU = i ? myNormPar[ i-1 ] : 0;
     double r = ( U - prevU )/ ( myNormPar[ i ] - prevU );
-    return myC2d[ i ]->Value( myFirst[i] * ( 1 - r ) + myLast[i] * r );
+
+    double par = myFirst[i] * ( 1 - r ) + myLast[i] * r;
+    
+    // check parametrization of curve
+    if( !myIsUniform[i] )
+    {
+      double aLen3dU = r * myEdgeLength[i] * ( myFirst[i]>myLast[i] ? -1. : 1.);
+      GCPnts_AbscissaPoint AbPnt
+        ( const_cast<GeomAdaptor_Curve&>( myC3dAdaptor[i]), aLen3dU, myFirst[i] );
+      if( AbPnt.IsDone() ) {
+        par = AbPnt.Parameter();
+      }
+    }
+    return myC2d[ i ]->Value(par);
+
   }
-  return gp_Pnt2d( 1e+100, 1e+100 );
+  return myDefaultPnt2d;
 }
 
 //================================================================================
@@ -485,46 +679,97 @@ TSideVector StdMeshers_FaceSide::GetFaceWires(const TopoDS_Face& theFace,
                                               TError &           theError)
 {
   TopoDS_Vertex V1;
-  list< TopoDS_Edge > edges;
+  list< TopoDS_Edge > edges, internalEdges;
   list< int > nbEdgesInWires;
   int nbWires = SMESH_Block::GetOrderedEdges (theFace, V1, edges, nbEdgesInWires);
 
   // split list of all edges into separate wires
   TSideVector wires( nbWires );
   list< int >::iterator nbE = nbEdgesInWires.begin();
-  list< TopoDS_Edge >::iterator from, to;
-  from = to = edges.begin();
-  for ( int iW = 0; iW < nbWires; ++iW )
+  list< TopoDS_Edge >::iterator from = edges.begin(), to = from;
+  for ( int iW = 0; iW < nbWires; ++iW, ++nbE )
   {
-    std::advance( to, *nbE++ );
+    std::advance( to, *nbE );
+    if ( *nbE == 0 ) // Issue 0020676
+    {
+      --nbWires;
+      --iW;
+      wires.resize( nbWires );
+      continue;
+    }
     list< TopoDS_Edge > wireEdges( from, to );
     // assure that there is a node on the first vertex
     // as StdMeshers_FaceSide::GetUVPtStruct() requires
-    while ( !SMESH_Algo::VertexNode( TopExp::FirstVertex( wireEdges.front(), true),
-                                     theMesh.GetMeshDS()))
+    if ( wireEdges.front().Orientation() != TopAbs_INTERNAL ) // Issue 0020676
     {
-      wireEdges.splice(wireEdges.end(), wireEdges,
-                       wireEdges.begin(), ++wireEdges.begin());
-      if ( from->IsSame( wireEdges.front() )) {
-        theError = TError
-          ( new SMESH_ComputeError(COMPERR_BAD_INPUT_MESH,"No nodes on vertices"));
-        return TSideVector(0);
+      while ( !SMESH_Algo::VertexNode( TopExp::FirstVertex( wireEdges.front(), true),
+                                       theMesh.GetMeshDS()))
+      {
+        wireEdges.splice(wireEdges.end(), wireEdges,
+                         wireEdges.begin(), ++wireEdges.begin());
+        if ( from->IsSame( wireEdges.front() )) {
+          theError = TError
+            ( new SMESH_ComputeError(COMPERR_BAD_INPUT_MESH,"No nodes on vertices"));
+          return TSideVector(0);
+        }
       }
     }
-    // find out side orientation, which is important if there are several wires (PAL19080) 
-    bool isForward = true;
-    if ( nbWires > 1 ) {
-      TopExp_Explorer e( theFace, TopAbs_EDGE );
-      while ( ! e.Current().IsSame( wireEdges.back() ))
-        e.Next();
-      isForward = ( e.Current().Orientation() == wireEdges.back().Orientation() );
+    else if ( *nbE > 1 ) // Issue 0020676 (Face_pb_netgen.brep) - several internal edges in a wire
+    {
+      internalEdges.splice( internalEdges.end(), wireEdges, ++wireEdges.begin(), wireEdges.end());
     }
 
     StdMeshers_FaceSide* wire = new StdMeshers_FaceSide( theFace, wireEdges, &theMesh,
-                                                         isForward, theIgnoreMediumNodes);
+                                                         /*isForward=*/true, theIgnoreMediumNodes);
     wires[ iW ] = StdMeshers_FaceSidePtr( wire );
     from = to;
   }
+  while ( !internalEdges.empty() )
+  {
+    StdMeshers_FaceSide* wire = new StdMeshers_FaceSide( theFace, internalEdges.back(), &theMesh,
+                                                         /*isForward=*/true, theIgnoreMediumNodes);
+    wires.push_back( StdMeshers_FaceSidePtr( wire ));
+    internalEdges.pop_back();
+  }
   return wires;
 }
 
+//================================================================================
+/*!
+ * \brief Return 1st vertex of the i-the edge
+ */
+//================================================================================
+
+TopoDS_Vertex StdMeshers_FaceSide::FirstVertex(int i) const
+{
+  TopoDS_Vertex v;
+  if ( i < NbEdges() )
+  {
+    v = myEdge[i].Orientation() <= TopAbs_REVERSED ? // FORWARD || REVERSED
+        TopExp::FirstVertex( myEdge[i], 1 )        :
+        TopoDS::Vertex( TopoDS_Iterator( myEdge[i] ).Value() );
+  }
+  return v;
+}
+
+//================================================================================
+/*!
+ * \brief Return last vertex of the i-the edge
+ */
+//================================================================================
+
+TopoDS_Vertex StdMeshers_FaceSide::LastVertex(int i) const
+{
+  TopoDS_Vertex v;
+  if ( i < NbEdges() )
+  {
+    const TopoDS_Edge& edge = i<0 ? myEdge[ NbEdges() + i ] : myEdge[i];
+    if ( edge.Orientation() <= TopAbs_REVERSED ) // FORWARD || REVERSED
+      v = TopExp::LastVertex( edge, 1 );
+    else
+      for ( TopoDS_Iterator vIt( edge ); vIt.More(); vIt.Next() )
+        v = TopoDS::Vertex( vIt.Value() );
+  }
+  return v;
+}
+
index 202b6a6d4de3845a201c74cd661f72e38638ac3e..4a119ed848e7ebb7e5a4619dab2b25155389f974 100644 (file)
@@ -1,25 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-//  SMESH SMESH : implementaion of SMESH idl descriptions
+
 // File      : StdMeshers_FaceSide.hxx
 // Created   : Wed Jan 31 18:41:25 2007
 // Author    : Edward AGAPOV (eap)
 #ifndef StdMeshers_FaceSide_HeaderFile
 #define StdMeshers_FaceSide_HeaderFile
 
-#include <gp_Pnt2d.hxx>
+#include "SMESH_StdMeshers.hxx"
+
+#include <Geom2d_Curve.hxx>
+#include <GeomAdaptor_Curve.hxx>
 #include <TopoDS_Edge.hxx>
 #include <TopoDS_Vertex.hxx>
-#include <Geom2d_Curve.hxx>
-#include <TopExp.hxx>
-
-#include "SMESH_StdMeshers.hxx"
-#include "SMESH_Algo.hxx"
+#include <gp_Pnt2d.hxx>
 
 #include <vector>
 #include <list>
@@ -47,7 +46,7 @@ class Adaptor2d_Curve2d;
 class Adaptor3d_Curve;
 class BRepAdaptor_CompCurve;
 class TopoDS_Face;
-class SMESH_ComputeError;
+struct SMESH_ComputeError;
 
 typedef struct uvPtStruct
 {
@@ -63,9 +62,8 @@ typedef struct uvPtStruct
 
 class StdMeshers_FaceSide;
 typedef boost::shared_ptr< StdMeshers_FaceSide > StdMeshers_FaceSidePtr;
-typedef boost::shared_ptr< uvPtStruct > UVPtStructPtr;
-typedef std::vector< StdMeshers_FaceSidePtr > TSideVector;
-typedef boost::shared_ptr< SMESH_ComputeError > TError;
+typedef std::vector< StdMeshers_FaceSidePtr >    TSideVector;
+typedef boost::shared_ptr< SMESH_ComputeError >  TError;
 
 //================================================================================
 /*!
@@ -88,12 +86,17 @@ public:
   /*!
    * \brief Wrap several edges. Edges must be properly ordered and oriented.
    */
-  StdMeshers_FaceSide(const TopoDS_Face& theFace,
+  StdMeshers_FaceSide(const TopoDS_Face&      theFace,
                       std::list<TopoDS_Edge>& theEdges,
-                      SMESH_Mesh*        theMesh,
-                      const bool         theIsForward,
-                      const bool         theIgnoreMediumNodes);
-
+                      SMESH_Mesh*             theMesh,
+                      const bool              theIsForward,
+                      const bool              theIgnoreMediumNodes);
+  /*!
+   * \brief Simulate a side from a vertex using data from other FaceSide
+   */
+  StdMeshers_FaceSide(const SMDS_MeshNode*       theNode,
+                      const gp_Pnt2d             thePnt2d,
+                      const StdMeshers_FaceSide* theSide);
   /*!
    * \brief Return wires of a face as StdMeshers_FaceSide's
    */
@@ -119,7 +122,7 @@ public:
    */
   SMESH_Mesh* GetMesh() const { return myMesh; }
   /*!
-   * \brief Return true if there vertices without nodes
+   * \brief Return true if there are vertices without nodes
    */
   bool MissVertexNode() const { return myMissingVertexNodes; }
   /*!
@@ -127,7 +130,8 @@ public:
     * \param isXConst - true if normalized parameter X is constant
     * \param constValue - constant parameter value
     *
-    * Missing nodes are allowed only on internal vertices
+    * Missing nodes are allowed only on internal vertices.
+    * For a closed side, the 1st point repeats at end
    */
   const std::vector<UVPtStruct>& GetUVPtStruct(bool isXConst =0, double constValue =0) const;
   /*!
@@ -136,8 +140,13 @@ public:
     * \param constValue - constant parameter value
    */
   const std::vector<UVPtStruct>& SimulateUVPtStruct(int    nbSeg,
-                                               bool   isXConst   = 0,
-                                               double constValue = 0) const;
+                                                    bool   isXConst   = 0,
+                                                    double constValue = 0) const;
+  /*!
+   * \brief Return nodes in the order they encounter while walking along the side.
+    * For a closed side, the 1st point repeats at end
+   */
+  std::vector<const SMDS_MeshNode*> GetOrderedNodes() const;
   /*!
    * \brief Return edge and parameter on edge by normalized parameter
    */
@@ -162,14 +171,18 @@ public:
    * \brief Return i-th wrapped edge (count starts from zero)
    */
   const TopoDS_Edge& Edge(int i) const { return myEdge[i]; }
+  /*!
+   * \brief Return all edges
+   */
+  const std::vector<TopoDS_Edge>& Edges() const { return myEdge; }
   /*!
    * \brief Return 1st vertex of the i-the edge (count starts from zero)
    */
-  inline TopoDS_Vertex FirstVertex(int i=0) const;
+  TopoDS_Vertex FirstVertex(int i=0) const;
   /*!
    * \brief Return last vertex of the i-the edge (count starts from zero)
    */
-  inline TopoDS_Vertex LastVertex(int i=-1) const;
+  TopoDS_Vertex LastVertex(int i=-1) const;
   /*!
    * \brief Return first normalized parameter of the i-the edge (count starts from zero)
    */
@@ -193,15 +206,22 @@ public:
   
 
 protected:
+
+  // DON't FORGET to update Reverse() when adding one more vector!
   std::vector<uvPtStruct>           myPoints, myFalsePoints;
   std::vector<TopoDS_Edge>          myEdge;
+  std::vector<int>                  myEdgeID;
   std::vector<Handle(Geom2d_Curve)> myC2d;
+  std::vector<GeomAdaptor_Curve>    myC3dAdaptor;
   std::vector<double>               myFirst, myLast;
   std::vector<double>               myNormPar;
+  std::vector<double>               myEdgeLength;
+  std::vector<double>               myIsUniform;
   double                            myLength;
   int                               myNbPonits, myNbSegments;
   SMESH_Mesh*                       myMesh;
   bool                              myMissingVertexNodes, myIgnoreMediumNodes;
+  gp_Pnt2d                          myDefaultPnt2d;
 };
 
 
@@ -237,28 +257,6 @@ inline double StdMeshers_FaceSide::Parameter(double U, TopoDS_Edge & edge) const
   return myFirst[i] * ( 1 - r ) + myLast[i] * r;
 }
 
-//================================================================================
-/*!
- * \brief Return 1st vertex of the i-the edge
- */
-//================================================================================
-
-inline TopoDS_Vertex StdMeshers_FaceSide::FirstVertex(int i) const
-{
-  return i < myEdge.size() ? TopExp::FirstVertex( myEdge[i], 1 ) : TopoDS_Vertex();
-}
-
-//================================================================================
-/*!
- * \brief Return last vertex of the i-the edge
- */
-//================================================================================
-
-inline TopoDS_Vertex StdMeshers_FaceSide::LastVertex(int i) const
-{
-  return i<0 ? TopExp::LastVertex( myEdge.back(), 1) : i<myEdge.size() ? TopExp::LastVertex( myEdge[i], 1 ) : TopoDS_Vertex();
-}
-
 //================================================================================
 /*!
  * \brief Return first normalized parameter of the i-the edge
diff --git a/src/StdMeshers/StdMeshers_FixedPoints1D.cxx b/src/StdMeshers/StdMeshers_FixedPoints1D.cxx
new file mode 100644 (file)
index 0000000..86c3f53
--- /dev/null
@@ -0,0 +1,244 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+//  File   : StdMeshers_FixedPoints1D.cxx
+//  Author : Damien COQUERET, OCC
+//  Module : SMESH
+//
+#include "StdMeshers_FixedPoints1D.hxx"
+
+#include "SMESH_Algo.hxx"
+#include "SMESH_Mesh.hxx"
+
+//#include <BRep_Tool.hxx>
+//#include <GCPnts_AbscissaPoint.hxx>
+//#include <GeomAdaptor_Curve.hxx>
+//#include <Geom_Curve.hxx>
+//#include <TopExp.hxx>
+//#include <TopLoc_Location.hxx>
+//#include <TopTools_IndexedMapOfShape.hxx>
+//#include <TopoDS.hxx>
+//#include <TopoDS_Edge.hxx>
+
+using namespace std;
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+StdMeshers_FixedPoints1D::StdMeshers_FixedPoints1D(int hypId, int studyId,
+                                                   SMESH_Gen * gen)
+  :SMESH_Hypothesis(hypId, studyId, gen)
+{
+  _name = "FixedPoints1D";
+  _param_algo_dim = 1; 
+  _nbsegs.reserve( 1 );
+  _nbsegs.push_back( 1 );
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+StdMeshers_FixedPoints1D::~StdMeshers_FixedPoints1D()
+{
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+void StdMeshers_FixedPoints1D::SetPoints(std::vector<double>& listParams)
+                              throw(SALOME_Exception)
+{
+  _params = listParams;
+  NotifySubMeshesHypothesisModification();
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+void StdMeshers_FixedPoints1D::SetNbSegments(std::vector<int>& listNbSeg) 
+                              throw(SALOME_Exception)
+{
+  _nbsegs = listNbSeg;
+  NotifySubMeshesHypothesisModification();
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+void StdMeshers_FixedPoints1D::SetReversedEdges( std::vector<int>& ids )
+{
+  if ( ids != _edgeIDs ) {
+    _edgeIDs = ids;
+
+    NotifySubMeshesHypothesisModification();
+  }
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+ostream & StdMeshers_FixedPoints1D::SaveTo(ostream & save)
+{
+  int listSize = _params.size();
+  save << listSize;
+  if ( listSize > 0 ) {
+    for ( int i = 0; i < listSize; i++) save << " " << _params[i];
+  }
+
+  listSize = _nbsegs.size();
+  save << " " << listSize;
+  if ( listSize > 0 ) {
+    for ( int i = 0; i < listSize; i++) save << " " << _nbsegs[i];
+  }
+
+  listSize = _edgeIDs.size();
+  save << " " << listSize;
+  if ( listSize > 0 ) {
+    for ( int i = 0; i < listSize; i++)
+      save << " " << _edgeIDs[i];
+  }
+
+  save << " " << _objEntry;
+
+  return save;
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+istream & StdMeshers_FixedPoints1D::LoadFrom(istream & load)
+{
+  bool isOK = true;
+  int intVal;
+  double dblVal;
+
+  isOK = (load >> intVal);
+  if (isOK && intVal > 0) {
+    _params.clear();
+    _params.reserve( intVal );
+    for (int i = 0; i < _params.capacity() && isOK; i++) {
+      isOK = (load >> dblVal);
+      if ( isOK ) _params.push_back( dblVal );
+    }
+  }
+
+  isOK = (load >> intVal);
+  if (isOK && intVal > 0) {
+    _nbsegs.clear();
+    _nbsegs.reserve( intVal );
+    for (int i = 0; i < _nbsegs.capacity() && isOK; i++) {
+      isOK = (load >> intVal);
+      if ( isOK ) _nbsegs.push_back( intVal );
+    }
+  }
+
+  isOK = (load >> intVal);
+  if (isOK && intVal > 0) {
+    _edgeIDs.clear();
+    _edgeIDs.reserve( intVal );
+    for (int i = 0; i < _edgeIDs.capacity() && isOK; i++) {
+      isOK = (load >> intVal);
+      if ( isOK ) _edgeIDs.push_back( intVal );
+    }
+  }
+
+  isOK = (load >> _objEntry);
+
+  return load;
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+ostream & operator <<(ostream & save, StdMeshers_FixedPoints1D & hyp)
+{
+  return hyp.SaveTo( save );
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+istream & operator >>(istream & load, StdMeshers_FixedPoints1D & hyp)
+{
+  return hyp.LoadFrom( load );
+}
+
+//================================================================================
+/*!
+ * \brief Initialize start and end length by the mesh built on the geometry
+ * \param theMesh - the built mesh
+ * \param theShape - the geometry of interest
+ * \retval bool - true if parameter values have been successfully defined
+ */
+//================================================================================
+
+bool StdMeshers_FixedPoints1D::SetParametersByMesh(const SMESH_Mesh*   theMesh,
+                                                   const TopoDS_Shape& theShape)
+{
+  if ( !theMesh || theShape.IsNull() )
+    return false;
+
+  _nbsegs.reserve( 1 );
+  _nbsegs.push_back( 1 );
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Initialize my parameter values by default parameters.
+ *  \retval bool - true if parameter values have been successfully defined
+ */
+//================================================================================
+
+bool StdMeshers_FixedPoints1D::SetParametersByDefaults(const TDefaults&  dflts,
+                                                       const SMESH_Mesh* /*mesh*/)
+{
+  _nbsegs.reserve( 1 );
+  _nbsegs.push_back( 1 );
+  return true;
+}
+
diff --git a/src/StdMeshers/StdMeshers_FixedPoints1D.hxx b/src/StdMeshers/StdMeshers_FixedPoints1D.hxx
new file mode 100644 (file)
index 0000000..384ad9c
--- /dev/null
@@ -0,0 +1,88 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+//  File   : StdMeshers_FixedPoints1D.hxx
+//  Author : Damien COQUERET, OCC
+//  Module : SMESH
+//
+#ifndef _SMESH_FIXEDPOINTS1D_HXX_
+#define _SMESH_FIXEDPOINTS1D_HXX_
+
+
+
+#include "SMESH_StdMeshers.hxx"
+
+#include "SMESH_Hypothesis.hxx"
+#include "Utils_SALOME_Exception.hxx"
+
+#include <vector>
+
+class STDMESHERS_EXPORT StdMeshers_FixedPoints1D:
+  public SMESH_Hypothesis
+{
+public:
+  StdMeshers_FixedPoints1D(int hypId, int studyId, SMESH_Gen* gen);
+  virtual ~StdMeshers_FixedPoints1D();
+
+  void SetPoints(std::vector<double>& listParams)
+    throw(SALOME_Exception);
+
+  void SetNbSegments(std::vector<int>& listNbSeg) 
+    throw(SALOME_Exception);
+
+  const std::vector<double>& GetPoints() const { return _params; }
+
+  const std::vector<int>& GetNbSegments() const { return _nbsegs; }
+
+  void SetReversedEdges( std::vector<int>& ids);
+
+  void SetObjectEntry( const char* entry ) { _objEntry = entry; }
+
+  const char* GetObjectEntry() { return _objEntry.c_str(); }
+
+  const std::vector<int>& GetReversedEdges() const { return _edgeIDs; }
+
+  virtual std::ostream & SaveTo(std::ostream & save);
+  virtual std::istream & LoadFrom(std::istream & load);
+  friend std::ostream& operator << (std::ostream & save, StdMeshers_FixedPoints1D & hyp);
+  friend std::istream& operator >> (std::istream & load, StdMeshers_FixedPoints1D & hyp);
+
+  /*!
+   * \brief Initialize start and end length by the mesh built on the geometry
+    * \param theMesh - the built mesh
+    * \param theShape - the geometry of interest
+    * \retval bool - true if parameter values have been successfully defined
+   */
+  virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape);
+
+  /*!
+   * \brief Initialize my parameter values by default parameters.
+   *  \retval bool - true if parameter values have been successfully defined
+   */
+  virtual bool SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh=0);
+
+protected:
+  std::vector<double> _params;
+  std::vector<int>    _nbsegs;
+  std::vector<int>    _edgeIDs;
+  std::string         _objEntry;
+};
+
+#endif
diff --git a/src/StdMeshers/StdMeshers_HexaFromSkin_3D.cxx b/src/StdMeshers/StdMeshers_HexaFromSkin_3D.cxx
new file mode 100644 (file)
index 0000000..58a9093
--- /dev/null
@@ -0,0 +1,1303 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+// File      : StdMeshers_HexaFromSkin_3D.cxx
+// Created   : Wed Jan 27 12:28:07 2010
+// Author    : Edward AGAPOV (eap)
+
+#include "StdMeshers_HexaFromSkin_3D.hxx"
+
+#include "SMDS_VolumeOfNodes.hxx"
+#include "SMDS_VolumeTool.hxx"
+#include "SMESH_Block.hxx"
+#include "SMESH_MesherHelper.hxx"
+
+#include <gp_Ax2.hxx>
+
+//#include "utilities.h"
+#include <limits>
+
+// Define error message and _MYDEBUG_ if needed
+#ifdef _DEBUG_
+#define BAD_MESH_ERR \
+  error(SMESH_Comment("Can't detect block-wise structure of the input 2D mesh.\n" \
+                      __FILE__ ":" )<<__LINE__)
+//#define _MYDEBUG_
+#else
+#define BAD_MESH_ERR \
+  error(SMESH_Comment("Can't detect block-wise structure of the input 2D mesh"))
+#endif
+
+
+// Debug output
+#ifdef _MYDEBUG_
+#define _DUMP_(msg) cout << msg << endl
+#else
+#define _DUMP_(msg)
+#endif
+
+
+namespace
+{
+  enum EBoxSides //!< sides of the block
+    {
+      B_BOTTOM=0, B_RIGHT, B_TOP, B_LEFT, B_FRONT, B_BACK, NB_BLOCK_SIDES
+    };
+#ifdef _MYDEBUG_
+  const char* SBoxSides[] = //!< names of block sides -- needed for DEBUG only
+    {
+      "BOTTOM", "RIGHT", "TOP", "LEFT", "FRONT", "BACK", "UNDEFINED"
+    };
+#endif
+  enum EQuadEdge //!< edges of quadrangle side
+    {
+      Q_BOTTOM = 0, Q_RIGHT, Q_TOP, Q_LEFT, NB_QUAD_SIDES
+    };
+
+
+  //================================================================================
+  /*!
+   * \brief return logical coordinates (i.e. min or max) of ends of edge
+   */
+  //================================================================================
+
+  bool getEdgeEnds(EQuadEdge edge, bool& xMax1, bool& yMax1, bool& xMax2, bool& yMax2 )
+  {
+    xMax1=0, yMax1=0, xMax2=1, yMax2=1;
+    switch( edge )
+    {
+    case Q_BOTTOM: yMax2 = 0; break;
+    case Q_RIGHT:  xMax1 = 1; break;
+    case Q_TOP:    yMax1 = 1; break;
+    case Q_LEFT:   xMax2 = 0; break;
+    default:
+      return false;
+    }
+    return true;
+  }
+
+  //================================================================================
+  /*!
+   * \brief return true if a node is at block corner
+   *
+   * This check is valid for simple cases only
+   */
+  //================================================================================
+
+  bool isCornerNode( const SMDS_MeshNode* n )
+  {
+    int nbF = n ? n->NbInverseElements( SMDSAbs_Face ) : 1;
+    if ( nbF % 2 )
+      return true;
+
+    set<const SMDS_MeshNode*> nodesInInverseFaces;
+    SMDS_ElemIteratorPtr fIt = n->GetInverseElementIterator(SMDSAbs_Face );
+    while ( fIt->more() )
+    {
+      const SMDS_MeshElement* face = fIt->next();
+      nodesInInverseFaces.insert( face->begin_nodes(), face->end_nodes() );
+    }
+
+    return nodesInInverseFaces.size() != ( 6 + (nbF/2-1)*3 );
+  }
+
+  //================================================================================
+  /*!
+   * \brief check element type
+   */
+  //================================================================================
+
+  bool isQuadrangle(const SMDS_MeshElement* e)
+  {
+    return ( e && e->NbCornerNodes() == 4 );
+  }
+
+  //================================================================================
+  /*!
+   * \brief return opposite node of a quadrangle face
+   */
+  //================================================================================
+
+  const SMDS_MeshNode* oppositeNode(const SMDS_MeshElement* quad, int iNode)
+  {
+    return quad->GetNode( (iNode+2) % 4 );
+  }
+
+  //================================================================================
+  /*!
+   * \brief Convertor of a pair of integers to a sole index
+   */
+  struct _Indexer
+  {
+    int _xSize, _ySize;
+    _Indexer( int xSize=0, int ySize=0 ): _xSize(xSize), _ySize(ySize) {}
+    int size() const { return _xSize * _ySize; }
+    int operator()(int x, int y) const { return y * _xSize + x; }
+  };
+  //================================================================================
+  /*!
+   * \brief Oriented convertor of a pair of integers to a sole index 
+   */
+  class _OrientedIndexer : public _Indexer
+  {
+  public:
+    enum OriFlags //!< types of block side orientation
+      {
+        REV_X = 1, REV_Y = 2, SWAP_XY = 4, MAX_ORI = REV_X|REV_Y|SWAP_XY
+      };
+    _OrientedIndexer( const _Indexer& indexer, const int oriFlags ):
+      _Indexer( indexer._xSize, indexer._ySize ),
+      _xSize (indexer._xSize), _ySize(indexer._ySize),
+      _xRevFun((oriFlags & REV_X) ? & reverse : & lazy),
+      _yRevFun((oriFlags & REV_Y) ? & reverse : & lazy),
+      _swapFun((oriFlags & SWAP_XY ) ? & swap : & lazy)
+    {
+      (*_swapFun)( _xSize, _ySize );
+    }
+    //!< Return index by XY
+    int operator()(int x, int y) const
+    {
+      (*_xRevFun)( x, const_cast<int&>( _xSize ));
+      (*_yRevFun)( y, const_cast<int&>( _ySize ));
+      (*_swapFun)( x, y );
+      return _Indexer::operator()(x,y);
+    }
+    //!< Return index for a corner
+    int corner(bool xMax, bool yMax) const
+    {
+      int x = xMax, y = yMax, size = 2;
+      (*_xRevFun)( x, size );
+      (*_yRevFun)( y, size );
+      (*_swapFun)( x, y );
+      return _Indexer::operator()(x ? _Indexer::_xSize-1 : 0 , y ? _Indexer::_ySize-1 : 0);
+    }
+    int xSize() const { return _xSize; }
+    int ySize() const { return _ySize; }
+  private:
+    _Indexer _indexer;
+    int _xSize, _ySize;
+
+    typedef void (*TFun)(int& x, int& y);
+    TFun _xRevFun, _yRevFun, _swapFun;
+    
+    static void lazy   (int&, int&) {}
+    static void reverse(int& x, int& size) { x = size - x - 1; }
+    static void swap   (int& x, int& y) { std::swap(x,y); }
+  };
+  //================================================================================
+  /*!
+   * \brief Structure corresponding to the meshed side of block
+   */
+  struct _BlockSide
+  {
+    vector<const SMDS_MeshNode*> _grid;
+    _Indexer                     _index;
+    int                          _nbBlocksExpected;
+    int                          _nbBlocksFound;
+
+#ifdef _DEBUG_ // want to get SIGSEGV in case of invalid index
+#define _grid_access_(pobj, i) pobj->_grid[ ((i) < pobj->_grid.size()) ? i : int(1e100)]
+#else
+#define _grid_access_(pobj, i) pobj->_grid[ i ]
+#endif
+    //!< Return node at XY
+    const SMDS_MeshNode* getNode(int x, int y) const { return _grid_access_(this, _index( x,y ));}
+    //!< Set node at XY
+    void setNode(int x, int y, const SMDS_MeshNode* n) { _grid_access_(this, _index( x,y )) = n; }
+    //!< Return an edge
+    SMESH_OrientedLink getEdge(EQuadEdge edge) const
+    {
+      bool x1, y1, x2, y2; getEdgeEnds( edge, x1, y1, x2, y2 );
+      return SMESH_OrientedLink( getCornerNode ( x1, y1 ), getCornerNode( x2, y2 ));
+    }
+    //!< Return a corner node
+    const SMDS_MeshNode* getCornerNode(bool isXMax, bool isYMax) const
+    {
+      return getNode( isXMax ? _index._xSize-1 : 0 , isYMax ? _index._ySize-1 : 0 );
+    }
+    const SMDS_MeshElement* getCornerFace(const SMDS_MeshNode* cornerNode) const;
+    //!< True if all blocks this side belongs to have been found
+    bool isBound() const { return _nbBlocksExpected <= _nbBlocksFound; }
+    //!< Return coordinates of node at XY
+    gp_XYZ getXYZ(int x, int y) const { return SMESH_TNodeXYZ( getNode( x, y )); }
+    //!< Return gravity center of the four corners and the middle node
+    gp_XYZ getGC() const
+    {
+      gp_XYZ xyz =
+        getXYZ( 0, 0 ) +
+        getXYZ( _index._xSize-1, 0 ) +
+        getXYZ( 0, _index._ySize-1 ) +
+        getXYZ( _index._xSize-1, _index._ySize-1 ) +
+        getXYZ( _index._xSize/2, _index._ySize/2 );
+      return xyz / 5;
+    }
+    //!< Return number of mesh faces
+    int getNbFaces() const { return (_index._xSize-1) * (_index._ySize-1); }
+  };
+  //================================================================================
+  /*!
+   * \brief _BlockSide with changed orientation
+   */
+  struct _OrientedBlockSide
+  {
+    _BlockSide*       _side;
+    _OrientedIndexer  _index;
+
+    _OrientedBlockSide( _BlockSide* side=0, const int oriFlags=0 ):
+      _side(side), _index(side ? side->_index : _Indexer(), oriFlags ) {}
+    //!< return coordinates by XY
+    gp_XYZ xyz(int x, int y) const
+    {
+      return SMESH_TNodeXYZ( _grid_access_(_side, _index( x, y )) );
+    }
+    //!< safely return a node by XY
+    const SMDS_MeshNode* node(int x, int y) const
+    {
+      int i = _index( x, y );
+      return ( i < 0 || i >= _side->_grid.size()) ? 0 : _side->_grid[i];
+    }
+    //!< Return an edge
+    SMESH_OrientedLink edge(EQuadEdge edge) const
+    {
+      bool x1, y1, x2, y2; getEdgeEnds( edge, x1, y1, x2, y2 );
+      return SMESH_OrientedLink( cornerNode ( x1, y1 ), cornerNode( x2, y2 ));
+    }
+    //!< Return a corner node
+    const SMDS_MeshNode* cornerNode(bool isXMax, bool isYMax) const
+    {
+      return _grid_access_(_side, _index.corner( isXMax, isYMax ));
+    }
+    //!< return its size in nodes
+    int getHoriSize() const { return _index.xSize(); }
+    int getVertSize() const  { return _index.ySize(); }
+    //!< True if _side has been initialized
+    operator bool() const { return _side; }
+    //! Direct access to _side
+    const _BlockSide* operator->() const { return _side; }
+    _BlockSide* operator->() { return _side; }
+  };
+  //================================================================================
+  /*!
+   * \brief Meshed skin of block
+   */
+  struct _Block
+  {
+    _OrientedBlockSide        _side[6]; // 6 sides of a sub-block
+    set<const SMDS_MeshNode*> _corners;
+
+    const _OrientedBlockSide& getSide(int i) const { return _side[i]; }
+    bool setSide( int i, const _OrientedBlockSide& s)
+    {
+      if (( _side[i] = s ))
+      {
+        _corners.insert( s.cornerNode(0,0));
+        _corners.insert( s.cornerNode(1,0));
+        _corners.insert( s.cornerNode(0,1));
+        _corners.insert( s.cornerNode(1,1));
+      }
+      return s;
+    }
+    void clear() { for (int i=0;i<6;++i) _side[i]=0; _corners.clear(); }
+    bool hasSide( const _OrientedBlockSide& s) const
+    {
+      if ( s ) for (int i=0;i<6;++i) if ( _side[i] && _side[i]._side == s._side ) return true;
+      return false;
+    }
+    int nbSides() const { int n=0; for (int i=0;i<6;++i) if ( _side[i] ) ++n; return n; }
+    bool isValid() const;
+  };
+  //================================================================================
+  /*!
+   * \brief Skin mesh possibly containing several meshed blocks
+   */
+  class _Skin
+  {
+  public:
+
+    int findBlocks(SMESH_Mesh& mesh);
+    //!< return i-th block
+    const _Block& getBlock(int i) const { return _blocks[i]; }
+    //!< return error description
+    const SMESH_Comment& error() const { return _error; }
+
+  private:
+    bool fillSide( _BlockSide&             side,
+                   const SMDS_MeshElement* cornerQuad,
+                   const SMDS_MeshNode*    cornerNode);
+    bool fillRowsUntilCorner(const SMDS_MeshElement* quad,
+                             const SMDS_MeshNode*    n1,
+                             const SMDS_MeshNode*    n2,
+                             vector<const SMDS_MeshNode*>& verRow1,
+                             vector<const SMDS_MeshNode*>& verRow2,
+                             bool alongN1N2 );
+    _OrientedBlockSide findBlockSide( EBoxSides           startBlockSide,
+                                      EQuadEdge           sharedSideEdge1,
+                                      EQuadEdge           sharedSideEdge2,
+                                      bool                withGeometricAnalysis,
+                                      set< _BlockSide* >& sidesAround);
+    //!< update own data and data of the side bound to block
+    void setSideBoundToBlock( _BlockSide& side )
+    {
+      if ( side._nbBlocksFound++, side.isBound() )
+        for ( int e = 0; e < int(NB_QUAD_SIDES); ++e )
+          _edge2sides[ side.getEdge( (EQuadEdge) e ) ].erase( &side );
+    }
+    //!< store reason of error
+    int error(const SMESH_Comment& reason) { _error = reason; return 0; }
+
+    SMESH_Comment      _error;
+
+    list< _BlockSide > _allSides;
+    vector< _Block >   _blocks;
+
+    //map< const SMDS_MeshNode*, set< _BlockSide* > > _corner2sides;
+    map< SMESH_OrientedLink, set< _BlockSide* > > _edge2sides;
+  };
+
+  //================================================================================
+  /*!
+   * \brief Find and return number of submeshes corresponding to blocks
+   */
+  //================================================================================
+
+  int _Skin::findBlocks(SMESH_Mesh& mesh)
+  {
+    SMESHDS_Mesh* meshDS = mesh.GetMeshDS();
+
+    // Find a node at any block corner
+
+    SMDS_NodeIteratorPtr nIt = meshDS->nodesIterator(/*idInceasingOrder=*/true);
+    if ( !nIt->more() ) return error("Empty mesh");
+
+    const SMDS_MeshNode* nCorner = 0;
+    while ( nIt->more() )
+    {
+      nCorner = nIt->next();
+      if ( isCornerNode( nCorner ))
+        break;
+      else
+        nCorner = 0;
+    }
+    if ( !nCorner )
+      return BAD_MESH_ERR;
+
+    // --------------------------------------------------------------------
+    // Find all block sides starting from mesh faces sharing the corner node
+    // --------------------------------------------------------------------
+
+    int nbFacesOnSides = 0;
+    TIDSortedElemSet cornerFaces; // corner faces of found _BlockSide's
+    list< const SMDS_MeshNode* > corners( 1, nCorner );
+    list< const SMDS_MeshNode* >::iterator corner = corners.begin();
+    while ( corner != corners.end() )
+    {
+      SMDS_ElemIteratorPtr faceIt = (*corner)->GetInverseElementIterator( SMDSAbs_Face );
+      while ( faceIt->more() )
+      {
+        const SMDS_MeshElement* face = faceIt->next();
+        if ( !cornerFaces.insert( face ).second )
+          continue; // already loaded block side
+
+        if ( !isQuadrangle( face ))
+          return error("Non-quadrangle elements in the input mesh");
+
+        if ( _allSides.empty() || !_allSides.back()._grid.empty() )
+          _allSides.push_back( _BlockSide() );
+
+        _BlockSide& side = _allSides.back();
+        if ( !fillSide( side, face, *corner ) )
+        {
+          if ( !_error.empty() )
+            return false;
+        }
+        else
+        {
+          for ( int isXMax = 0; isXMax < 2; ++isXMax )
+            for ( int isYMax = 0; isYMax < 2; ++isYMax )
+            {
+              const SMDS_MeshNode* nCorner = side.getCornerNode(isXMax,isYMax );
+              corners.push_back( nCorner );
+              cornerFaces.insert( side.getCornerFace( nCorner ));
+            }
+          for ( int e = 0; e < int(NB_QUAD_SIDES); ++e )
+            _edge2sides[ side.getEdge( (EQuadEdge) e ) ].insert( &side );
+
+          nbFacesOnSides += side.getNbFaces();
+        }
+      }
+      ++corner;
+
+      // find block sides of other domains if any
+      if ( corner == corners.end() && nbFacesOnSides < mesh.NbQuadrangles() )
+      {
+        while ( nIt->more() )
+        {
+          nCorner = nIt->next();
+          if ( isCornerNode( nCorner ))
+            corner = corners.insert( corner, nCorner );
+        }
+        nbFacesOnSides = mesh.NbQuadrangles();
+      }
+    }
+    
+    if ( _allSides.empty() )
+      return BAD_MESH_ERR;
+    if ( _allSides.back()._grid.empty() )
+      _allSides.pop_back();
+    _DUMP_("Nb detected sides "<< _allSides.size());
+
+    // ---------------------------
+    // Organize sides into blocks
+    // ---------------------------
+
+    // analyse sharing of sides by blocks and sort sides by nb of adjacent sides
+    int nbBlockSides = 0; // total nb of block sides taking into account their sharing
+    multimap<int, _BlockSide* > sortedSides;
+    {
+      list < _BlockSide >::iterator sideIt = _allSides.begin();
+      for ( ; sideIt != _allSides.end(); ++sideIt )
+      {
+        _BlockSide& side = *sideIt;
+        bool isSharedSide = true;
+        int nbAdjacent = 0;
+        for ( int e = 0; e < int(NB_QUAD_SIDES) && isSharedSide; ++e )
+        {
+          int nbAdj = _edge2sides[ side.getEdge( (EQuadEdge) e ) ].size();
+          nbAdjacent += nbAdj;
+          isSharedSide = ( nbAdj > 2 );
+        }
+        side._nbBlocksFound = 0;
+        side._nbBlocksExpected = isSharedSide ? 2 : 1;
+        nbBlockSides += side._nbBlocksExpected;
+        sortedSides.insert( make_pair( nbAdjacent, & side ));
+      }
+    }
+
+    // find sides of each block
+    int nbBlocks = 0;
+    while ( nbBlockSides >= 6 )
+    {
+      // get any side not bound to all blocks it belongs to
+      multimap<int, _BlockSide*>::iterator i_side = sortedSides.begin();
+      while ( i_side != sortedSides.end() && i_side->second->isBound())
+        ++i_side;
+
+      // start searching for block sides from the got side
+      bool ok = true;
+      if ( _blocks.empty() || _blocks.back()._side[B_FRONT] )
+        _blocks.resize( _blocks.size() + 1 );
+
+      _Block& block = _blocks.back();
+      block.setSide( B_FRONT, i_side->second );
+      setSideBoundToBlock( *i_side->second );
+      nbBlockSides--;
+
+      // edges of adjacent sides of B_FRONT corresponding to front's edges
+      EQuadEdge edgeOfFront[4] = { Q_BOTTOM, Q_RIGHT, Q_TOP, Q_LEFT };
+      EQuadEdge edgeOfAdj  [4] = { Q_BOTTOM, Q_LEFT, Q_BOTTOM, Q_LEFT };
+      // first find all sides detectable w/o advanced analysis,
+      // then repeat the search, which then may pass without advanced analysis
+      set< _BlockSide* > sidesAround;
+      for ( int advAnalys = 0; advAnalys < 2; ++advAnalys )
+      {
+        // try to find 4 sides adjacent to a FRONT side
+        for ( int i = 0; (ok || !advAnalys) && i < NB_QUAD_SIDES; ++i )
+          if ( !block._side[i] )
+            ok = block.setSide( i, findBlockSide( B_FRONT, edgeOfFront[i], edgeOfAdj[i],
+                                                  advAnalys, sidesAround));
+        // try to find a BACK side by a TOP one
+        if ( ok || !advAnalys)
+          if ( !block._side[B_BACK] && block._side[B_TOP] )
+            ok = block.setSide( B_BACK, findBlockSide( B_TOP, Q_TOP, Q_TOP,
+                                                       advAnalys, sidesAround ));
+        if ( !advAnalys ) ok = true;
+      }
+      ok = block.isValid();
+      if ( ok )
+      {
+        // check if just found block is same as one of previously found blocks
+        bool isSame = false;
+        for ( int i = 1; i < _blocks.size() && !isSame; ++i )
+          isSame = ( block._corners == _blocks[i-1]._corners );
+        ok = !isSame;
+      }
+
+      // count the found sides
+      _DUMP_(endl << "** Block " << _blocks.size() << " valid: " << block.isValid());
+      for (int i = 0; i < NB_BLOCK_SIDES; ++i )
+      {
+        _DUMP_("\tSide "<< SBoxSides[i] <<" "<< block._side[ i ]._side);
+        if ( block._side[ i ] )
+        {
+          if ( ok && i != B_FRONT)
+          {
+            setSideBoundToBlock( *block._side[ i ]._side );
+            nbBlockSides--;
+          }
+          _DUMP_("\t corners "<<
+                 block._side[ i ].cornerNode(0,0)->GetID() << ", " <<
+                 block._side[ i ].cornerNode(1,0)->GetID() << ", " <<
+                 block._side[ i ].cornerNode(1,1)->GetID() << ", " <<
+                 block._side[ i ].cornerNode(0,1)->GetID() << ", "<<endl);
+        }
+        else
+        {
+          _DUMP_("\t not found"<<endl);
+        }
+      }
+      if ( !ok )
+        block.clear();
+      else
+        nbBlocks++;
+    }
+    _DUMP_("Nb found blocks "<< nbBlocks <<endl);
+
+    if ( nbBlocks == 0 && _error.empty() )
+      return BAD_MESH_ERR;
+
+    return nbBlocks;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Fill block side data starting from its corner quadrangle
+   */
+  //================================================================================
+
+  bool _Skin::fillSide( _BlockSide&             side,
+                        const SMDS_MeshElement* cornerQuad,
+                        const SMDS_MeshNode*    nCorner)
+  {
+    // Find out size of block side mesured in nodes and by the way find two rows
+    // of nodes in two directions.
+
+    int x, y, nbX, nbY;
+    const SMDS_MeshElement* firstQuad = cornerQuad;
+    {
+      // get a node on block edge
+      int iCorner = firstQuad->GetNodeIndex( nCorner );
+      const SMDS_MeshNode* nOnEdge = firstQuad->GetNode( (iCorner+1) % 4);
+
+      // find out size of block side
+      vector<const SMDS_MeshNode*> horRow1, horRow2, verRow1, verRow2;
+      if ( !fillRowsUntilCorner( firstQuad, nCorner, nOnEdge, horRow1, horRow2, true ) ||
+           !fillRowsUntilCorner( firstQuad, nCorner, nOnEdge, verRow1, verRow2, false ))
+        return false;
+      nbX = horRow1.size(), nbY = verRow1.size();
+
+      // store found nodes
+      side._index._xSize = horRow1.size();
+      side._index._ySize = verRow1.size();
+      side._grid.resize( side._index.size(), NULL );
+
+      for ( x = 0; x < horRow1.size(); ++x )
+      {
+        side.setNode( x, 0, horRow1[x] );
+        side.setNode( x, 1, horRow2[x] );
+      }
+      for ( y = 0; y < verRow1.size(); ++y )
+      {
+        side.setNode( 0, y, verRow1[y] );
+        side.setNode( 1, y, verRow2[y] );
+      }
+    }
+    // Find the rest nodes
+
+    y = 1; // y of the row to fill
+    TIDSortedElemSet emptySet, avoidSet;
+    while ( ++y < nbY )
+    {
+      // get next firstQuad in the next row of quadrangles
+      //
+      //          n2up
+      //     o---o               <- y row
+      //     |   |
+      //     o---o  o  o  o  o   <- found nodes
+      //n1down    n2down       
+      //
+      int i1down, i2down, i2up;
+      const SMDS_MeshNode* n1down = side.getNode( 0, y-1 );
+      const SMDS_MeshNode* n2down = side.getNode( 1, y-1 );
+      avoidSet.clear(); avoidSet.insert( firstQuad );
+      firstQuad = SMESH_MeshEditor::FindFaceInSet( n1down, n2down, emptySet, avoidSet,
+                                                   &i1down, &i2down);
+      if ( !isQuadrangle( firstQuad ))
+        return BAD_MESH_ERR;
+
+      const SMDS_MeshNode* n2up = oppositeNode( firstQuad, i1down );
+      avoidSet.clear(); avoidSet.insert( firstQuad );
+
+      // find the rest nodes in the y-th row by faces in the row
+
+      x = 1; 
+      while ( ++x < nbX )
+      {
+        const SMDS_MeshElement* quad = SMESH_MeshEditor::FindFaceInSet( n2up, n2down, emptySet,
+                                                                        avoidSet, &i2up, &i2down);
+        if ( !isQuadrangle( quad ))
+          return BAD_MESH_ERR;
+
+        n2up   = oppositeNode( quad, i2down );
+        n2down = oppositeNode( quad, i2up );
+        avoidSet.clear(); avoidSet.insert( quad );
+
+        side.setNode( x, y, n2up );
+      }
+    }
+
+    // check side validity
+    bool ok =
+      side.getCornerFace( side.getCornerNode( 0, 0 )) &&
+      side.getCornerFace( side.getCornerNode( 1, 0 )) &&
+      side.getCornerFace( side.getCornerNode( 0, 1 )) &&
+      side.getCornerFace( side.getCornerNode( 1, 1 ));
+
+    return ok;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Return true if it's possible to make a loop over corner2Sides starting
+   * from the startSide
+   */
+  //================================================================================
+
+  bool isClosedChainOfSides( _BlockSide*                                        startSide,
+                             map< const SMDS_MeshNode*, list< _BlockSide* > > & corner2Sides )
+  {
+    // get start and end nodes
+    const SMDS_MeshNode *n1 = 0, *n2 = 0, *n;
+    for ( int y = 0; y < 2; ++y )
+      for ( int x = 0; x < 2; ++x )
+      {
+        n = startSide->getCornerNode(x,y);
+        if ( !corner2Sides.count( n )) continue;
+        if ( n1 )
+          n2 = n;
+        else
+          n1 = n;
+      }
+    if ( !n2 ) return false;
+
+    map< const SMDS_MeshNode*, list< _BlockSide* > >::iterator
+      c2sides = corner2Sides.find( n1 );
+    if ( c2sides == corner2Sides.end() ) return false;
+
+    int nbChainLinks = 1;
+    n = n1;
+    _BlockSide* prevSide = startSide;
+    while ( n != n2 )
+    {
+      // get the next side sharing n
+      list< _BlockSide* > & sides = c2sides->second;
+      _BlockSide* nextSide = ( sides.back() == prevSide ? sides.front() : sides.back() );
+      if ( nextSide == prevSide ) return false;
+
+      // find the next corner of the nextSide being in corner2Sides
+      n1 = n;
+      n = 0;
+      for ( int y = 0; y < 2 && !n; ++y )
+        for ( int x = 0; x < 2; ++x )
+        {
+          n = nextSide->getCornerNode(x,y);
+          c2sides = corner2Sides.find( n );
+          if ( n == n1 || c2sides == corner2Sides.end() )
+            n = 0;
+          else
+            break;
+        }
+      if ( !n ) return false;
+
+      prevSide = nextSide;
+      nbChainLinks++;
+    }
+
+    return ( n == n2 && nbChainLinks == NB_QUAD_SIDES );
+  }
+
+  //================================================================================
+  /*!
+   * \brief Try to find a block side adjacent to the given side by given edge
+   */
+  //================================================================================
+
+  _OrientedBlockSide _Skin::findBlockSide( EBoxSides           startBlockSide,
+                                           EQuadEdge           sharedSideEdge1,
+                                           EQuadEdge           sharedSideEdge2,
+                                           bool                withGeometricAnalysis,
+                                           set< _BlockSide* >& sidesAround)
+  {
+    _Block& block = _blocks.back();
+    _OrientedBlockSide& side1 = block._side[ startBlockSide ];
+
+    // get corner nodes of the given block edge
+    SMESH_OrientedLink edge = side1.edge( sharedSideEdge1 );
+    const SMDS_MeshNode* n1 = edge.node1();
+    const SMDS_MeshNode* n2 = edge.node2();
+    if ( edge._reversed ) swap( n1, n2 );
+
+    // find all sides sharing both nodes n1 and n2
+    set< _BlockSide* > sidesOnEdge = _edge2sides[ edge ]; // copy a set
+
+    // exclude loaded sides of block from sidesOnEdge
+    for (int i = 0; i < NB_BLOCK_SIDES; ++i )
+      if ( block._side[ i ] )
+        sidesOnEdge.erase( block._side[ i ]._side );
+
+    int nbSidesOnEdge = sidesOnEdge.size();
+    _DUMP_("nbSidesOnEdge "<< nbSidesOnEdge << " " << n1->GetID() << "-" << n2->GetID() );
+    if ( nbSidesOnEdge == 0 )
+      return 0;
+
+    _BlockSide* foundSide = 0;
+    if ( nbSidesOnEdge == 1 )
+    {
+      foundSide = *sidesOnEdge.begin();
+    }
+    else
+    {
+      set< _BlockSide* >::iterator sideIt = sidesOnEdge.begin();
+      int nbLoadedSides = block.nbSides();
+      if ( nbLoadedSides > 1 )
+      {
+        // Find the side having more than 2 corners common with already loaded sides
+        for (; !foundSide && sideIt != sidesOnEdge.end(); ++sideIt )
+        {
+          _BlockSide* sideI = *sideIt;
+          int nbCommonCorners =
+            block._corners.count( sideI->getCornerNode(0,0)) +
+            block._corners.count( sideI->getCornerNode(1,0)) +
+            block._corners.count( sideI->getCornerNode(0,1)) +
+            block._corners.count( sideI->getCornerNode(1,1));
+          if ( nbCommonCorners > 2 )
+            foundSide = sideI;
+        }
+      }
+
+      if ( !foundSide )
+      {
+        if ( !withGeometricAnalysis )
+        {
+          sidesAround.insert( sidesOnEdge.begin(), sidesOnEdge.end() );
+          return 0;
+        }
+        if ( nbLoadedSides == 1 )
+        {
+          // Issue 0021529. There are at least 2 sides by each edge and
+          // position of block gravity center is undefined.
+          // Find a side starting from which we can walk around the startBlockSide
+
+          // fill in corner2Sides
+          map< const SMDS_MeshNode*, list< _BlockSide* > > corner2Sides;
+          for ( sideIt = sidesAround.begin(); sideIt != sidesAround.end(); ++sideIt )
+          {
+            _BlockSide* sideI = *sideIt;
+            corner2Sides[ sideI->getCornerNode(0,0) ].push_back( sideI );
+            corner2Sides[ sideI->getCornerNode(1,0) ].push_back( sideI );
+            corner2Sides[ sideI->getCornerNode(0,1) ].push_back( sideI );
+            corner2Sides[ sideI->getCornerNode(1,1) ].push_back( sideI );
+          }
+          // remove corners of startBlockSide from corner2Sides
+          set<const SMDS_MeshNode*>::iterator nIt = block._corners.begin();
+          for ( ; nIt != block._corners.end(); ++nIt )
+            corner2Sides.erase( *nIt );
+
+          // select a side
+          for ( sideIt = sidesOnEdge.begin(); sideIt != sidesOnEdge.end(); ++sideIt )
+          {
+            if ( isClosedChainOfSides( *sideIt, corner2Sides ))
+            {
+              foundSide = *sideIt;
+              break;
+            }
+          }
+          if ( !foundSide )
+            return 0;
+        }
+        else
+        {
+          // Select one of found sides most close to startBlockSide
+
+          gp_XYZ p1 ( n1->X(),n1->Y(),n1->Z()),  p2 (n2->X(),n2->Y(),n2->Z());
+          gp_Vec p1p2( p1, p2 );
+
+          const SMDS_MeshElement* face1 = side1->getCornerFace( n1 );
+          gp_XYZ p1Op = SMESH_TNodeXYZ( oppositeNode( face1, face1->GetNodeIndex(n1)));
+          gp_Vec side1Dir( p1, p1Op );
+          gp_Ax2 pln( p1, p1p2, side1Dir ); // plane with normal p1p2 and X dir side1Dir
+          _DUMP_("  Select adjacent for "<< side1._side << " - side dir ("
+                 << side1Dir.X() << ", " << side1Dir.Y() << ", " << side1Dir.Z() << ")" );
+
+          map < double , _BlockSide* > angleOfSide;
+          for (sideIt = sidesOnEdge.begin(); sideIt != sidesOnEdge.end(); ++sideIt )
+          {
+            _BlockSide* sideI = *sideIt;
+            const SMDS_MeshElement* faceI = sideI->getCornerFace( n1 );
+            gp_XYZ p1Op = SMESH_TNodeXYZ( oppositeNode( faceI, faceI->GetNodeIndex(n1)));
+            gp_Vec sideIDir( p1, p1Op );
+            // compute angle of (sideIDir projection to pln) and (X dir of pln)
+            gp_Vec2d sideIDirProj( sideIDir * pln.XDirection(), sideIDir * pln.YDirection());
+            double angle = sideIDirProj.Angle( gp::DX2d() );
+            if ( angle < 0 ) angle += 2. * M_PI; // angle [0-2*PI]
+            angleOfSide.insert( make_pair( angle, sideI ));
+            _DUMP_("  "<< sideI << " - side dir ("
+                   << sideIDir.X() << ", " << sideIDir.Y() << ", " << sideIDir.Z() << ")"
+                   << " angle " << angle);
+          }
+
+          gp_XYZ gc(0,0,0); // gravity center of already loaded block sides
+          for (int i = 0; i < NB_BLOCK_SIDES; ++i )
+            if ( block._side[ i ] )
+              gc += block._side[ i ]._side->getGC();
+          gc /= nbLoadedSides;
+
+          gp_Vec gcDir( p1, gc );
+          gp_Vec2d gcDirProj( gcDir * pln.XDirection(), gcDir * pln.YDirection());
+          double gcAngle = gcDirProj.Angle( gp::DX2d() );
+          foundSide = gcAngle < 0 ? angleOfSide.rbegin()->second : angleOfSide.begin()->second;
+        }
+      }
+      _DUMP_("  selected "<< foundSide );
+    }
+
+    // Orient the found side correctly
+
+    // corners of found side corresponding to nodes n1 and n2
+    bool xMax1, yMax1, xMax2, yMax2;
+    if ( !getEdgeEnds( sharedSideEdge2, xMax1, yMax1, xMax2, yMax2 ))
+      return error(SMESH_Comment("Internal error at ")<<__FILE__<<":"<<__LINE__),
+        _OrientedBlockSide(0);
+
+    for ( int ori = 0; ori < _OrientedIndexer::MAX_ORI+1; ++ori )
+    {
+      _OrientedBlockSide orientedSide( foundSide, ori );
+      const SMDS_MeshNode* n12 = orientedSide.cornerNode( xMax1, yMax1);
+      const SMDS_MeshNode* n22 = orientedSide.cornerNode( xMax2, yMax2);
+      if ( n1 == n12 && n2 == n22 )
+        return orientedSide;
+    }
+    error(SMESH_Comment("Failed to orient a block side found by edge ")<<sharedSideEdge1
+          << " of side " << startBlockSide
+          << " of block " << _blocks.size());
+    return 0;
+  }
+
+  //================================================================================
+  /*!
+   * \brief: Fill rows (which are actually columns,if !alongN1N2) of nodes starting
+   * from the given quadrangle until another block corner encounters.
+   *  n1 and n2 are at bottom of quad, n1 is at block corner.
+   */
+  //================================================================================
+
+  bool _Skin::fillRowsUntilCorner(const SMDS_MeshElement*       quad,
+                                  const SMDS_MeshNode*          n1,
+                                  const SMDS_MeshNode*          n2,
+                                  vector<const SMDS_MeshNode*>& row1,
+                                  vector<const SMDS_MeshNode*>& row2,
+                                  const bool                    alongN1N2 )
+  {
+    const SMDS_MeshNode* corner1 = n1;
+
+    // Store nodes of quad in the rows and find new n1 and n2 to get
+    // the next face so that new n2 is on block edge
+    int i1 = quad->GetNodeIndex( n1 );
+    int i2 = quad->GetNodeIndex( n2 );
+    row1.clear(); row2.clear();
+    row1.push_back( n1 );
+    if ( alongN1N2 )
+    {
+      row1.push_back( n2 );
+      row2.push_back( oppositeNode( quad, i2 ));
+      row2.push_back( n1 = oppositeNode( quad, i1 ));
+    }
+    else
+    {
+      row2.push_back( n2 );
+      row1.push_back( n2 = oppositeNode( quad, i2 ));
+      row2.push_back( n1 = oppositeNode( quad, i1 ));
+    }
+
+    if ( isCornerNode( row1[1] ))
+      return true;
+
+    // Find the rest nodes
+    TIDSortedElemSet emptySet, avoidSet;
+    while ( !isCornerNode( n2 ) )
+    {
+      avoidSet.clear(); avoidSet.insert( quad );
+      quad = SMESH_MeshEditor::FindFaceInSet( n1, n2, emptySet, avoidSet, &i1, &i2 );
+      if ( !isQuadrangle( quad ))
+        return BAD_MESH_ERR;
+
+      row1.push_back( n2 = oppositeNode( quad, i1 ));
+      row2.push_back( n1 = oppositeNode( quad, i2 ));
+    }
+    return n1 != corner1;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Return a corner face by a corner node
+   */
+  //================================================================================
+
+  const SMDS_MeshElement* _BlockSide::getCornerFace(const SMDS_MeshNode* cornerNode) const
+  {
+    int x, y, isXMax, isYMax, found = 0;
+    for ( isXMax = 0; isXMax < 2; ++isXMax )
+    {
+      for ( isYMax = 0; isYMax < 2; ++isYMax )
+      {
+        x = isXMax ? _index._xSize-1 : 0;
+        y = isYMax ? _index._ySize-1 : 0;
+        found = ( getNode(x,y) == cornerNode );
+        if ( found ) break;
+      }
+      if ( found ) break;
+    }
+    if ( !found ) return 0;
+    int dx = isXMax ? -1 : +1;
+    int dy = isYMax ? -1 : +1;
+    const SMDS_MeshNode* n1 = getNode(x,y);
+    const SMDS_MeshNode* n2 = getNode(x+dx,y);
+    const SMDS_MeshNode* n3 = getNode(x,y+dy);
+    const SMDS_MeshNode* n4 = getNode(x+dx,y+dy);
+    return SMDS_Mesh::FindFace(n1, n2, n3, n4 );
+  }
+
+  //================================================================================
+  /*!
+   * \brief Checks own validity
+   */
+  //================================================================================
+
+  bool _Block::isValid() const
+  {
+    bool ok = ( nbSides() == 6 );
+
+    // check only corners depending on side selection
+    EBoxSides adjacent[4] = { B_BOTTOM, B_RIGHT, B_TOP, B_LEFT };
+    EQuadEdge edgeAdj [4] = { Q_TOP,    Q_RIGHT, Q_TOP, Q_RIGHT };
+    EQuadEdge edgeBack[4] = { Q_BOTTOM, Q_RIGHT, Q_TOP, Q_LEFT };
+
+    for ( int i=0; ok && i < NB_QUAD_SIDES; ++i )
+    { 
+      SMESH_OrientedLink eBack = _side[ B_BACK      ].edge( edgeBack[i] );
+      SMESH_OrientedLink eAdja = _side[ adjacent[i] ].edge( edgeAdj[i] );
+      ok = ( eBack == eAdja );
+    }
+    return ok;
+  }
+
+} // namespace
+
+//=======================================================================
+//function : StdMeshers_HexaFromSkin_3D
+//purpose  : 
+//=======================================================================
+
+StdMeshers_HexaFromSkin_3D::StdMeshers_HexaFromSkin_3D(int hypId, int studyId, SMESH_Gen* gen)
+  :SMESH_3D_Algo(hypId, studyId, gen)
+{
+  MESSAGE("StdMeshers_HexaFromSkin_3D::StdMeshers_HexaFromSkin_3D");
+  _name = "HexaFromSkin_3D";
+}
+
+StdMeshers_HexaFromSkin_3D::~StdMeshers_HexaFromSkin_3D()
+{
+  MESSAGE("StdMeshers_HexaFromSkin_3D::~StdMeshers_HexaFromSkin_3D");
+}
+
+//================================================================================
+/*!
+ * \brief Main method, which generates hexaheda
+ */
+//================================================================================
+
+bool StdMeshers_HexaFromSkin_3D::Compute(SMESH_Mesh & aMesh, SMESH_MesherHelper* aHelper)
+{
+  _Skin skin;
+  int nbBlocks = skin.findBlocks(aMesh);
+  if ( nbBlocks == 0 )
+    return error( skin.error());
+
+  vector< vector< const SMDS_MeshNode* > > columns;
+  int x, xSize, y, ySize, z, zSize;
+  _Indexer colIndex;
+
+  for ( int i = 0; i < nbBlocks; ++i )
+  {
+    const _Block& block = skin.getBlock( i );
+
+    // ------------------------------------------
+    // Fill columns of nodes with existing nodes
+    // ------------------------------------------
+
+    xSize = block.getSide(B_BOTTOM).getHoriSize();
+    ySize = block.getSide(B_BOTTOM).getVertSize();
+    zSize = block.getSide(B_FRONT ).getVertSize();
+    int X = xSize - 1, Y = ySize - 1, Z = zSize - 1;
+    colIndex = _Indexer( xSize, ySize );
+    columns.resize( colIndex.size() );
+
+    // fill node columns by front and back box sides
+    for ( x = 0; x < xSize; ++x ) {
+      vector< const SMDS_MeshNode* >& column0 = columns[ colIndex( x, 0 )];
+      vector< const SMDS_MeshNode* >& column1 = columns[ colIndex( x, Y )];
+      column0.resize( zSize );
+      column1.resize( zSize );
+      for ( z = 0; z < zSize; ++z ) {
+        column0[ z ] = block.getSide(B_FRONT).node( x, z );
+        column1[ z ] = block.getSide(B_BACK) .node( x, z );
+      }
+    }
+    // fill node columns by left and right box sides
+    for ( y = 1; y < ySize-1; ++y ) {
+      vector< const SMDS_MeshNode* >& column0 = columns[ colIndex( 0, y )];
+      vector< const SMDS_MeshNode* >& column1 = columns[ colIndex( X, y )];
+      column0.resize( zSize );
+      column1.resize( zSize );
+      for ( z = 0; z < zSize; ++z ) {
+        column0[ z ] = block.getSide(B_LEFT) .node( y, z );
+        column1[ z ] = block.getSide(B_RIGHT).node( y, z );
+      }
+    }
+    // get nodes from top and bottom box sides
+    for ( x = 1; x < xSize-1; ++x ) {
+      for ( y = 1; y < ySize-1; ++y ) {
+        vector< const SMDS_MeshNode* >& column = columns[ colIndex( x, y )];
+        column.resize( zSize );
+        column.front() = block.getSide(B_BOTTOM).node( x, y );
+        column.back()  = block.getSide(B_TOP)   .node( x, y );
+      }
+    }
+
+    // ----------------------------
+    // Add internal nodes of a box
+    // ----------------------------
+    // projection points of internal nodes on box sub-shapes by which
+    // coordinates of internal nodes are computed
+    vector<gp_XYZ> pointOnShape( SMESH_Block::ID_Shell );
+
+    // projections on vertices are constant
+    pointOnShape[ SMESH_Block::ID_V000 ] = block.getSide(B_BOTTOM).xyz( 0, 0 );
+    pointOnShape[ SMESH_Block::ID_V100 ] = block.getSide(B_BOTTOM).xyz( X, 0 );
+    pointOnShape[ SMESH_Block::ID_V010 ] = block.getSide(B_BOTTOM).xyz( 0, Y );
+    pointOnShape[ SMESH_Block::ID_V110 ] = block.getSide(B_BOTTOM).xyz( X, Y );
+    pointOnShape[ SMESH_Block::ID_V001 ] = block.getSide(B_TOP).xyz( 0, 0 );
+    pointOnShape[ SMESH_Block::ID_V101 ] = block.getSide(B_TOP).xyz( X, 0 );
+    pointOnShape[ SMESH_Block::ID_V011 ] = block.getSide(B_TOP).xyz( 0, Y );
+    pointOnShape[ SMESH_Block::ID_V111 ] = block.getSide(B_TOP).xyz( X, Y );
+
+    for ( x = 1; x < xSize-1; ++x )
+    {
+      gp_XYZ params; // normalized parameters of internal node within a unit box
+      params.SetCoord( 1, x / double(X) );
+      for ( y = 1; y < ySize-1; ++y )
+      {
+        params.SetCoord( 2, y / double(Y) );
+        // column to fill during z loop
+        vector< const SMDS_MeshNode* >& column = columns[ colIndex( x, y )];
+        // projections on horizontal edges
+        pointOnShape[ SMESH_Block::ID_Ex00 ] = block.getSide(B_BOTTOM).xyz( x, 0 );
+        pointOnShape[ SMESH_Block::ID_Ex10 ] = block.getSide(B_BOTTOM).xyz( x, Y );
+        pointOnShape[ SMESH_Block::ID_E0y0 ] = block.getSide(B_BOTTOM).xyz( 0, y );
+        pointOnShape[ SMESH_Block::ID_E1y0 ] = block.getSide(B_BOTTOM).xyz( X, y );
+        pointOnShape[ SMESH_Block::ID_Ex01 ] = block.getSide(B_TOP).xyz( x, 0 );
+        pointOnShape[ SMESH_Block::ID_Ex11 ] = block.getSide(B_TOP).xyz( x, Y );
+        pointOnShape[ SMESH_Block::ID_E0y1 ] = block.getSide(B_TOP).xyz( 0, y );
+        pointOnShape[ SMESH_Block::ID_E1y1 ] = block.getSide(B_TOP).xyz( X, y );
+        // projections on horizontal sides
+        pointOnShape[ SMESH_Block::ID_Fxy0 ] = block.getSide(B_BOTTOM).xyz( x, y );
+        pointOnShape[ SMESH_Block::ID_Fxy1 ] = block.getSide(B_TOP)   .xyz( x, y );
+        for ( z = 1; z < zSize-1; ++z ) // z loop
+        {
+          params.SetCoord( 3, z / double(Z) );
+          // projections on vertical edges
+          pointOnShape[ SMESH_Block::ID_E00z ] = block.getSide(B_FRONT).xyz( 0, z );    
+          pointOnShape[ SMESH_Block::ID_E10z ] = block.getSide(B_FRONT).xyz( X, z );    
+          pointOnShape[ SMESH_Block::ID_E01z ] = block.getSide(B_BACK).xyz( 0, z );    
+          pointOnShape[ SMESH_Block::ID_E11z ] = block.getSide(B_BACK).xyz( X, z );
+          // projections on vertical sides
+          pointOnShape[ SMESH_Block::ID_Fx0z ] = block.getSide(B_FRONT).xyz( x, z );    
+          pointOnShape[ SMESH_Block::ID_Fx1z ] = block.getSide(B_BACK) .xyz( x, z );    
+          pointOnShape[ SMESH_Block::ID_F0yz ] = block.getSide(B_LEFT) .xyz( y, z );    
+          pointOnShape[ SMESH_Block::ID_F1yz ] = block.getSide(B_RIGHT).xyz( y, z );
+
+          // compute internal node coordinates
+          gp_XYZ coords;
+          SMESH_Block::ShellPoint( params, pointOnShape, coords );
+          column[ z ] = aHelper->AddNode( coords.X(), coords.Y(), coords.Z() );
+
+#ifdef DEB_GRID
+          // debug
+          //cout << "----------------------------------------------------------------------"<<endl;
+          //for ( int id = SMESH_Block::ID_V000; id < SMESH_Block::ID_Shell; ++id)
+          //{
+          //  gp_XYZ p = pointOnShape[ id ];
+          //  SMESH_Block::DumpShapeID( id,cout)<<" ( "<<p.X()<<", "<<p.Y()<<", "<<p.Z()<<" )"<<endl;
+          //}
+          //cout << "Params: ( "<< params.X()<<", "<<params.Y()<<", "<<params.Z()<<" )"<<endl;
+          //cout << "coords: ( "<< coords.X()<<", "<<coords.Y()<<", "<<coords.Z()<<" )"<<endl;
+#endif
+        }
+      }
+    }
+    // ----------------
+    // Add hexahedrons
+    // ----------------
+
+    // find out orientation by a least distorted hexahedron (issue 0020855);
+    // the last is defined by evaluating sum of face normals of 8 corner hexahedrons
+    double badness = numeric_limits<double>::max();
+    bool isForw = true;
+    for ( int xMax = 0; xMax < 2; ++xMax )
+      for ( int yMax = 0; yMax < 2; ++yMax )
+        for ( int zMax = 0; zMax < 2; ++zMax )
+        {
+          x = xMax ? xSize-1 : 1;
+          y = yMax ? ySize-1 : 1;
+          z = zMax ? zSize-1 : 1;
+          vector< const SMDS_MeshNode* >& col00 = columns[ colIndex( x-1, y-1 )];
+          vector< const SMDS_MeshNode* >& col10 = columns[ colIndex( x  , y-1 )];
+          vector< const SMDS_MeshNode* >& col01 = columns[ colIndex( x-1, y   )];
+          vector< const SMDS_MeshNode* >& col11 = columns[ colIndex( x  , y )];
+          
+          const SMDS_MeshNode* n000 = col00[z-1];
+          const SMDS_MeshNode* n100 = col10[z-1];
+          const SMDS_MeshNode* n010 = col01[z-1];
+          const SMDS_MeshNode* n110 = col11[z-1];
+          const SMDS_MeshNode* n001 = col00[z];
+          const SMDS_MeshNode* n101 = col10[z];
+          const SMDS_MeshNode* n011 = col01[z];
+          const SMDS_MeshNode* n111 = col11[z];
+          SMDS_VolumeOfNodes probeVolume (n000,n010,n110,n100,
+                                          n001,n011,n111,n101);
+          SMDS_VolumeTool volTool( &probeVolume );
+          double Nx=0.,Ny=0.,Nz=0.;
+          for ( int iFace = 0; iFace < volTool.NbFaces(); ++iFace )
+          {
+            double nx,ny,nz;
+            volTool.GetFaceNormal( iFace, nx,ny,nz );
+            Nx += nx;
+            Ny += ny;
+            Nz += nz;
+          }
+          double quality = Nx*Nx + Ny*Ny + Nz*Nz;
+          if ( quality < badness )
+          {
+            badness = quality;
+            isForw = volTool.IsForward();
+          }
+        }
+
+    // add elements
+    for ( x = 0; x < xSize-1; ++x ) {
+      for ( y = 0; y < ySize-1; ++y ) {
+        vector< const SMDS_MeshNode* >& col00 = columns[ colIndex( x, y )];
+        vector< const SMDS_MeshNode* >& col10 = columns[ colIndex( x+1, y )];
+        vector< const SMDS_MeshNode* >& col01 = columns[ colIndex( x, y+1 )];
+        vector< const SMDS_MeshNode* >& col11 = columns[ colIndex( x+1, y+1 )];
+        // bottom face normal of a hexa mush point outside the volume
+        if ( isForw )
+          for ( z = 0; z < zSize-1; ++z )
+            aHelper->AddVolume(col00[z],   col01[z],   col11[z],   col10[z],
+                               col00[z+1], col01[z+1], col11[z+1], col10[z+1]);
+        else
+          for ( z = 0; z < zSize-1; ++z )
+            aHelper->AddVolume(col00[z],   col10[z],   col11[z],   col01[z],
+                               col00[z+1], col10[z+1], col11[z+1], col01[z+1]);
+      }
+    }
+  } // loop on blocks
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Evaluate nb of hexa
+ */
+//================================================================================
+
+bool StdMeshers_HexaFromSkin_3D::Evaluate(SMESH_Mesh &         aMesh,
+                                          const TopoDS_Shape & aShape,
+                                          MapShapeNbElems&     aResMap)
+{
+  _Skin skin;
+  int nbBlocks = skin.findBlocks(aMesh);
+  if ( nbBlocks == 0 )
+    return error( skin.error());
+
+  bool secondOrder = aMesh.NbFaces( ORDER_QUADRATIC );
+
+  int entity = secondOrder ? SMDSEntity_Quad_Hexa : SMDSEntity_Hexa;
+  vector<int>& nbByType = aResMap[ aMesh.GetSubMesh( aShape )];
+  if ( entity >= nbByType.size() )
+    nbByType.resize( SMDSEntity_Last, 0 );
+
+  for ( int i = 0; i < nbBlocks; ++i )
+  {
+    const _Block& block = skin.getBlock( i );
+
+    int nbX = block.getSide(B_BOTTOM).getHoriSize();
+    int nbY = block.getSide(B_BOTTOM).getVertSize();
+    int nbZ = block.getSide(B_FRONT ).getVertSize();
+
+    int nbHexa  = (nbX-1) * (nbY-1) * (nbZ-1);
+    int nbNodes = (nbX-2) * (nbY-2) * (nbZ-2);
+    if ( secondOrder )
+      nbNodes +=
+        (nbX-2) * (nbY-2) * (nbZ-1) +
+        (nbX-2) * (nbY-1) * (nbZ-2) +
+        (nbX-1) * (nbY-2) * (nbZ-2);
+
+
+    nbByType[ entity ] += nbHexa;
+    nbByType[ SMDSEntity_Node ] += nbNodes;
+  }
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Abstract method must be defined but does nothing
+ */
+//================================================================================
+
+bool StdMeshers_HexaFromSkin_3D::CheckHypothesis(SMESH_Mesh&, const TopoDS_Shape&,
+                                                 Hypothesis_Status& aStatus)
+{
+  aStatus = SMESH_Hypothesis::HYP_OK;
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Abstract method must be defined but just reports an error as this
+ *  algo is not intended to work with shapes
+ */
+//================================================================================
+
+bool StdMeshers_HexaFromSkin_3D::Compute(SMESH_Mesh&, const TopoDS_Shape&)
+{
+  return error("Algorithm can't work with geometrical shapes");
+}
diff --git a/src/StdMeshers/StdMeshers_HexaFromSkin_3D.hxx b/src/StdMeshers/StdMeshers_HexaFromSkin_3D.hxx
new file mode 100644 (file)
index 0000000..0912a4d
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+// File      : StdMeshers_HexaFromSkin_3D.hxx
+// Created   : Wed Jan 27 12:23:21 2010
+// Author    : Edward AGAPOV (eap)
+//
+#ifndef __StdMeshers_HexaFromSkin_3D_HXX__
+#define __StdMeshers_HexaFromSkin_3D_HXX__
+
+#include "SMESH_StdMeshers.hxx"
+#include "SMESH_3D_Algo.hxx"
+
+/*!
+ * \brief Alorithm generating hexahedral mesh from 2D skin of block
+ */
+
+class STDMESHERS_EXPORT StdMeshers_HexaFromSkin_3D : public SMESH_3D_Algo
+{
+public:
+  StdMeshers_HexaFromSkin_3D(int hypId, int studyId, SMESH_Gen* gen);
+  virtual ~StdMeshers_HexaFromSkin_3D();
+
+  virtual bool Compute(SMESH_Mesh & aMesh, SMESH_MesherHelper* aHelper);
+
+  virtual bool CheckHypothesis(SMESH_Mesh& aMesh,
+                               const TopoDS_Shape& aShape,
+                               Hypothesis_Status& aStatus);
+
+  virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
+
+  virtual bool Evaluate(SMESH_Mesh &         aMesh,
+                        const TopoDS_Shape & aShape,
+                        MapShapeNbElems&     aResMap);
+  
+};
+
+#endif
index b36acde9aad097e763c315f4ecdfdc8fe858e7f8..92f00af3a8e73c604addc0deffc5afcd4ca9bcb0 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_Hexa_3D.cxx
 //           Moved here from SMESH_Hexa_3D.cxx
 //  Module : SMESH
 //
 #include "StdMeshers_Hexa_3D.hxx"
+
 #include "StdMeshers_CompositeHexa_3D.hxx"
 #include "StdMeshers_FaceSide.hxx"
+#include "StdMeshers_HexaFromSkin_3D.hxx"
 #include "StdMeshers_Penta_3D.hxx"
 #include "StdMeshers_Prism_3D.hxx"
 #include "StdMeshers_Quadrangle_2D.hxx"
+#include "StdMeshers_ViscousLayers.hxx"
 
+#include "SMESH_Comment.hxx"
 #include "SMESH_Gen.hxx"
 #include "SMESH_Mesh.hxx"
+#include "SMESH_MesherHelper.hxx"
 #include "SMESH_subMesh.hxx"
-#include "SMESH_Comment.hxx"
 
-#include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
-#include "SMDS_FacePosition.hxx"
-#include "SMDS_VolumeTool.hxx"
-#include "SMDS_VolumeOfNodes.hxx"
 
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
-#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
-#include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <TopTools_ListOfShape.hxx>
+#include <TopTools_SequenceOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
 #include <TopoDS.hxx>
-#include <gp_Pnt2d.hxx>
 
 #include "utilities.h"
 #include "Utils_ExceptHandlers.hxx"
@@ -58,11 +57,16 @@ typedef SMESH_Comment TComm;
 
 using namespace std;
 
-static SMESH_ComputeErrorPtr ComputePentahedralMesh(SMESH_Mesh &, const TopoDS_Shape &);
+static SMESH_ComputeErrorPtr ComputePentahedralMesh(SMESH_Mesh &,
+                                                    const TopoDS_Shape &,
+                                                    SMESH_ProxyMesh* proxyMesh=0);
+
+static bool EvaluatePentahedralMesh(SMESH_Mesh &, const TopoDS_Shape &,
+                                    MapShapeNbElems &);
 
 //=============================================================================
 /*!
- *  
+ * Constructor
  */
 //=============================================================================
 
@@ -71,12 +75,14 @@ StdMeshers_Hexa_3D::StdMeshers_Hexa_3D(int hypId, int studyId, SMESH_Gen * gen)
 {
   MESSAGE("StdMeshers_Hexa_3D::StdMeshers_Hexa_3D");
   _name = "Hexa_3D";
-  _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);      // 1 bit /shape type
+  _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);       // 1 bit /shape type
+  _requireShape = false;
+  _compatibleHypothesis.push_back("ViscousLayers");
 }
 
 //=============================================================================
 /*!
- *  
+ * Destructor
  */
 //=============================================================================
 
@@ -85,27 +91,9 @@ StdMeshers_Hexa_3D::~StdMeshers_Hexa_3D()
   MESSAGE("StdMeshers_Hexa_3D::~StdMeshers_Hexa_3D");
 }
 
-//================================================================================
-/*!
- * \brief Clear fields and return the argument
-  * \param res - the value to return
-  * \retval bool - the argument value
- */
-//================================================================================
-
-bool StdMeshers_Hexa_3D::ClearAndReturn(FaceQuadStruct* theQuads[6], const bool res)
-{
-  for (int i = 0; i < 6; i++) {
-    delete theQuads[i];
-    theQuads[i] = NULL;
-  }
-  return res;
-}
-
-
 //=============================================================================
 /*!
- *  
+ * Retrieves defined hypotheses
  */
 //=============================================================================
 
@@ -124,82 +112,181 @@ bool StdMeshers_Hexa_3D::CheckHypothesis
   if ( nbFaces != 6 )
     return false;
 */
-  aStatus = SMESH_Hypothesis::HYP_OK;
-  return true;
-}
 
-//=======================================================================
-//function : isCloser
-//purpose  : 
-//=======================================================================
+  _viscousLayersHyp = NULL;
 
-inline bool isCloser(const int i, const int j, const int nbhoriz,
-                     const FaceQuadStruct* quad, const gp_Pnt2d uv,
-                     double & minDist)
-{
-  int ij = j * nbhoriz + i;
-  gp_Pnt2d uv2( quad->uv_grid[ij].u, quad->uv_grid[ij].v );
-  double dist = uv.SquareDistance( uv2 );
-  if ( dist < minDist ) {
-    minDist = dist;
+  const list<const SMESHDS_Hypothesis*>& hyps =
+    GetUsedHypothesis(aMesh, aShape, /*ignoreAuxiliary=*/false);
+  list <const SMESHDS_Hypothesis* >::const_iterator h = hyps.begin();
+  if ( h == hyps.end())
+  {
+    aStatus = SMESH_Hypothesis::HYP_OK;
     return true;
   }
-  return false;
-}
 
-//=======================================================================
-//function : findIJ
-//purpose  : return i,j of the node
-//=======================================================================
+  aStatus = HYP_OK;
+  for ( ; h != hyps.end(); ++h )
+  {
+    string hypName = (*h)->GetName();
+    if ( find( _compatibleHypothesis.begin(),_compatibleHypothesis.end(),hypName )
+         != _compatibleHypothesis.end() )
+    {
+      _viscousLayersHyp = dynamic_cast< const StdMeshers_ViscousLayers*> ( *h );
+    }
+    else
+    {
+      aStatus = HYP_INCOMPATIBLE;
+    }
+  }
 
-static bool findIJ (const SMDS_MeshNode* node, const FaceQuadStruct * quad, int& I, int& J)
+  if ( !_viscousLayersHyp )
+    aStatus = HYP_INCOMPATIBLE;
+
+  return aStatus == HYP_OK;
+}
+
+namespace
 {
-  const SMDS_FacePosition* fpos =
-    static_cast<const SMDS_FacePosition*>(node->GetPosition().get());
-  if ( ! fpos ) return false;
-  gp_Pnt2d uv( fpos->GetUParameter(), fpos->GetVParameter() );
-
-  double minDist = DBL_MAX;
-  const int nbhoriz  = quad->side[0]->NbPoints();
-  const int nbvertic = quad->side[1]->NbPoints();
-  I = nbhoriz/2; J = nbvertic/2;
-  int oldI, oldJ;
-  do {
-    oldI = I; oldJ = J;
-    while ( I + 2 < nbhoriz &&  isCloser( I + 1, J, nbhoriz, quad, uv, minDist ))
-      I += 1;
-    if ( I == oldI )
-      while ( I - 1 > 0     &&  isCloser( I - 1, J, nbhoriz, quad, uv, minDist ))
-        I -= 1;
-    if ( minDist < DBL_MIN )
-      break;
+  //=============================================================================
 
-    while ( J + 2 < nbvertic && isCloser( I, J + 1, nbhoriz, quad, uv, minDist ))
-      J += 1;
-    if ( J == oldJ )
-      while ( J - 1 > 0      && isCloser( I, J - 1, nbhoriz, quad, uv, minDist ))
-        J -= 1;
-    if ( minDist < DBL_MIN )
-      break;
+  typedef boost::shared_ptr< FaceQuadStruct > FaceQuadStructPtr;
+
+  // symbolic names of box sides
+  enum EBoxSides{ B_BOTTOM=0, B_RIGHT, B_TOP, B_LEFT, B_FRONT, B_BACK, B_NB_SIDES };
+
+  // symbolic names of sides of quadrangle
+  enum EQuadSides{ Q_BOTTOM=0, Q_RIGHT, Q_TOP, Q_LEFT, Q_NB_SIDES };
+
+  //=============================================================================
+  /*!
+   * \brief Container of nodes of structured mesh on a qudrangular geom FACE
+   */
+  struct _FaceGrid
+  {
+    // face sides
+    FaceQuadStructPtr _quad;
+
+    // map of (node parameter on EDGE) to (column (vector) of nodes)
+    TParam2ColumnMap _u2nodesMap;
+
+    // node column's taken form _u2nodesMap taking into account sub-shape orientation
+    vector<TNodeColumn> _columns;
+
+    // geometry of a cube side
+    TopoDS_Face _sideF;
+
+    const SMDS_MeshNode* GetNode(int iCol, int iRow) const
+    {
+      return _columns[iCol][iRow];
+    }
+    gp_XYZ GetXYZ(int iCol, int iRow) const
+    {
+      return SMESH_TNodeXYZ( GetNode( iCol, iRow ));
+    }
+  };
 
-  } while ( I != oldI || J != oldJ );
+  //================================================================================
+  /*!
+   * \brief Convertor of a pair of integers to a sole index
+   */
+  struct _Indexer
+  {
+    int _xSize, _ySize;
+    _Indexer( int xSize, int ySize ): _xSize(xSize), _ySize(ySize) {}
+    int size() const { return _xSize * _ySize; }
+    int operator()(const int x, const int y) const { return y * _xSize + x; }
+  };
+
+  //================================================================================
+  /*!
+   * \brief Appends a range of node columns from a map to another map
+   */
+  template< class TMapIterator >
+  void append( TParam2ColumnMap& toMap, TMapIterator from, TMapIterator to )
+  {
+    const SMDS_MeshNode* lastNode = toMap.rbegin()->second[0];
+    const SMDS_MeshNode* firstNode = from->second[0];
+    if ( lastNode == firstNode )
+      from++;
+    double u = toMap.rbegin()->first;
+    for (; from != to; ++from )
+    {
+      u += 1;
+      TParam2ColumnMap::iterator u2nn = toMap.insert( toMap.end(), make_pair ( u, TNodeColumn()));
+      u2nn->second.swap( from->second );
+    }
+  }
 
-  if ( minDist > DBL_MIN ) {
-    for (int i = 1; i < nbhoriz - 1; i++)
-      for (int j = 1; j < nbvertic - 1; j++)
-        if ( isCloser( i, j, nbhoriz, quad, uv, minDist ))
-          I = i, J = j;
+  //================================================================================
+  /*!
+   * \brief Finds FaceQuadStruct having a side equal to a given one and rearranges
+   *  the found FaceQuadStruct::side to have the given side at a Q_BOTTOM place
+   */
+  FaceQuadStructPtr getQuadWithBottom( StdMeshers_FaceSide* side,
+                                       FaceQuadStructPtr    quad[ 6 ])
+  {
+    FaceQuadStructPtr foundQuad;
+    for ( int i = 1; i < 6; ++i )
+    {
+      if ( !quad[i] ) continue;
+      for ( unsigned iS = 0; iS < quad[i]->side.size(); ++iS )
+      {
+        const StdMeshers_FaceSide* side2 = quad[i]->side[iS];
+        if (( side->FirstVertex().IsSame( side2->FirstVertex() ) ||
+              side->FirstVertex().IsSame( side2->LastVertex() ))
+            &&
+            ( side->LastVertex().IsSame( side2->FirstVertex() ) ||
+              side->LastVertex().IsSame( side2->LastVertex() ))
+            )
+        {
+          if ( iS != Q_BOTTOM )
+          {
+            vector< StdMeshers_FaceSide*> newSides;
+            for ( unsigned j = iS; j < quad[i]->side.size(); ++j )
+              newSides.push_back( quad[i]->side[j] );
+            for ( unsigned j = 0; j < iS; ++j )
+              newSides.push_back( quad[i]->side[j] );
+            quad[i]->side.swap( newSides );
+          }
+          foundQuad.swap(quad[i]);
+          return foundQuad;
+        }
+      }
+    }
+    return foundQuad;
+  }
+  //================================================================================
+  /*!
+   * \brief Returns true if the 1st base node of sideGrid1 belongs to sideGrid2
+   */
+  //================================================================================
+
+  bool beginsAtSide( const _FaceGrid&     sideGrid1,
+                     const _FaceGrid&     sideGrid2,
+                     SMESH_ProxyMesh::Ptr proxymesh )
+  {
+    const TNodeColumn& col0  = sideGrid2._u2nodesMap.begin()->second;
+    const TNodeColumn& col1  = sideGrid2._u2nodesMap.rbegin()->second;
+    const SMDS_MeshNode* n00 = col0.front();
+    const SMDS_MeshNode* n01 = col0.back();
+    const SMDS_MeshNode* n10 = col1.front();
+    const SMDS_MeshNode* n11 = col1.back();
+    const SMDS_MeshNode* n = (sideGrid1._u2nodesMap.begin()->second)[0];
+    if ( proxymesh )
+    {
+      n00 = proxymesh->GetProxyNode( n00 );
+      n10 = proxymesh->GetProxyNode( n10 );
+      n01 = proxymesh->GetProxyNode( n01 );
+      n11 = proxymesh->GetProxyNode( n11 );
+      n   = proxymesh->GetProxyNode( n );
+    }
+    return ( n == n00 || n == n01 || n == n10 || n == n11 );
   }
-  return true;
 }
 
-
 //=============================================================================
 /*!
- * Hexahedron mesh on hexaedron like form
- * -0.  - shape and face mesh verification
- * -1.  - identify faces and vertices of the "cube"
- * -2.  - Algorithm from:
+ * Generates hexahedron mesh on hexaedron like form using 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."
@@ -215,823 +302,470 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh &         aMesh,
   MESSAGE("StdMeshers_Hexa_3D::Compute");
   SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
 
-  // 0.  - shape and face mesh verification
-  // 0.1 - shape must be a solid (or a shell) with 6 faces
+  // Shape verification
+  // ----------------------
 
-  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) {
-    //return error(COMPERR_BAD_SHAPE, TComm(meshFaces.size())<<" instead of 6 faces in a block");
-    static StdMeshers_CompositeHexa_3D compositeHexa(-10, 0, aMesh.GetGen());
+  // shape must be a solid (or a shell) with 6 faces
+  TopExp_Explorer exp(aShape,TopAbs_SHELL);
+  if ( !exp.More() )
+    return error(COMPERR_BAD_SHAPE, "No SHELL in the geometry");
+  if ( exp.Next(), exp.More() )
+    return error(COMPERR_BAD_SHAPE, "More than one SHELL in the geometry");
+
+  TopTools_IndexedMapOfShape FF;
+  TopExp::MapShapes( aShape, TopAbs_FACE, FF);
+  if ( FF.Extent() != 6)
+  {
+    static StdMeshers_CompositeHexa_3D compositeHexa(_gen->GetANewId(), 0, _gen);
     if ( !compositeHexa.Compute( aMesh, aShape ))
       return error( compositeHexa.GetComputeError() );
     return true;
   }
 
-  // 0.2 - is each face meshed with Quadrangle_2D? (so, with a wire of 4 edges)
-
-  // tool for working with quadratic elements
-  SMESH_MesherHelper aTool (aMesh);
-  _quadraticMesh = aTool.IsQuadraticSubMesh(aShape);
-
-  // cube structure
-  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;
-
-  CubeStruct aCube;
-
-  // bounding faces
-  FaceQuadStruct* aQuads[6];
-  for (int i = 0; i < 6; i++)
-    aQuads[i] = 0;
-
-  for (int i = 0; i < 6; i++)
+  // Find sides of a cube
+  // ---------------------
+  
+  FaceQuadStructPtr quad[ 6 ];
+  StdMeshers_Quadrangle_2D quadAlgo( _gen->GetANewId(), GetStudyId(), _gen);
+  for ( int i = 0; i < 6; ++i )
   {
-    TopoDS_Shape aFace = meshFaces[i]->GetSubShape();
-    SMESH_Algo *algo = _gen->GetAlgo(aMesh, aFace);
-    string algoName = algo->GetName();
-    bool isAllQuad = false;
-    if (algoName == "Quadrangle_2D") {
-      SMESHDS_SubMesh * sm = meshDS->MeshElements( aFace );
-      if ( sm ) {
-        isAllQuad = true;
-        SMDS_ElemIteratorPtr eIt = sm->GetElements();
-        while ( isAllQuad && eIt->more() ) {
-          const SMDS_MeshElement* elem =  eIt->next();
-          isAllQuad = ( elem->NbNodes()==4 ||(_quadraticMesh && elem->NbNodes()==8) );
-        }
-      }
-    }
-    if ( ! isAllQuad ) {
-      SMESH_ComputeErrorPtr err = ComputePentahedralMesh(aMesh, aShape);
-      return ClearAndReturn( aQuads, error(err));
-    }
-    StdMeshers_Quadrangle_2D *quadAlgo =
-      dynamic_cast < StdMeshers_Quadrangle_2D * >(algo);
-    ASSERT(quadAlgo);
-    try {
-      aQuads[i] = quadAlgo->CheckAnd2Dcompute(aMesh, aFace, _quadraticMesh);
-      if(!aQuads[i]) {
-       return error( quadAlgo->GetComputeError());
-      }
-    }
-    catch(SALOME_Exception & S_ex) {
-      return ClearAndReturn( aQuads, error(COMPERR_SLM_EXCEPTION,TComm(S_ex.what()) <<
-                                           " Raised by StdMeshers_Quadrangle_2D "
-                                           " on face #" << meshDS->ShapeToIndex( aFace )));
-    }
-
-    // 0.2.1 - number of points on the opposite edges must be the same
-    if (aQuads[i]->side[0]->NbPoints() != aQuads[i]->side[2]->NbPoints() ||
-        aQuads[i]->side[1]->NbPoints() != aQuads[i]->side[3]->NbPoints()
-        /*aQuads[i]->side[0]->NbEdges() != 1 ||
-        aQuads[i]->side[1]->NbEdges() != 1 ||
-        aQuads[i]->side[2]->NbEdges() != 1 ||
-        aQuads[i]->side[3]->NbEdges() != 1*/) {
-      MESSAGE("different number of points on the opposite edges of face " << i);
-      // Try to go into penta algorithm 'cause it has been improved.
-      SMESH_ComputeErrorPtr err = ComputePentahedralMesh(aMesh, aShape);
-      return ClearAndReturn( aQuads, error(err));
-    }
+    if ( !( quad[i] = FaceQuadStructPtr( quadAlgo.CheckNbEdges( aMesh, FF( i+1 )))))
+      return error( quadAlgo.GetComputeError() );
+    if ( quad[i]->side.size() != 4 )
+      return error( COMPERR_BAD_SHAPE, "Not a quadrangular box side" );
   }
 
-  // 1.  - identify faces and vertices of the "cube"
-  // 1.1 - ancestor maps vertex->edges in the cube
-
-  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
-
-  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
-
-  aCube.V000 = aQuads[0]->side[0]->FirstVertex(); // will be (0,0,0) on the unit cube
-  aCube.V100 = aQuads[0]->side[0]->LastVertex();  // will be (1,0,0) on the unit cube
-  aCube.V001 = aQuads[0]->side[2]->FirstVertex(); // will be (0,0,1) on the unit cube
-  aCube.V101 = aQuads[0]->side[2]->LastVertex();  // will be (1,0,1) on the unit cube
-
-  TopTools_IndexedMapOfShape MV0;
-  TopExp::MapShapes(F, TopAbs_VERTEX, MV0);
-
-  aCube.V010 = OppositeVertex( aCube.V000, MV0, aQuads);
-  aCube.V110 = OppositeVertex( aCube.V100, MV0, aQuads);
-  aCube.V011 = OppositeVertex( aCube.V001, MV0, aQuads);
-  aCube.V111 = OppositeVertex( aCube.V101, MV0, aQuads);
-
-  // 1.6 - find remaining faces given 4 vertices
-
-  int _indY0 = 0;
-  aCube.quad_Y0 = aQuads[_indY0];
-
-  int _indY1 = GetFaceIndex(aMesh, aShape, meshFaces,
-                            aCube.V010, aCube.V011, aCube.V110, aCube.V111);
-  aCube.quad_Y1 = aQuads[_indY1];
-
-  int _indZ0 = GetFaceIndex(aMesh, aShape, meshFaces,
-                            aCube.V000, aCube.V010, aCube.V100, aCube.V110);
-  aCube.quad_Z0 = aQuads[_indZ0];
-
-  int _indZ1 = GetFaceIndex(aMesh, aShape, meshFaces,
-                            aCube.V001, aCube.V011, aCube.V101, aCube.V111);
-  aCube.quad_Z1 = aQuads[_indZ1];
-
-  int _indX0 = GetFaceIndex(aMesh, aShape, meshFaces,
-                            aCube.V000, aCube.V001, aCube.V010, aCube.V011);
-  aCube.quad_X0 = aQuads[_indX0];
+  _FaceGrid aCubeSide[ 6 ];
 
-  int _indX1 = GetFaceIndex(aMesh, aShape, meshFaces,
-                            aCube.V100, aCube.V101, aCube.V110, aCube.V111);
-  aCube.quad_X1 = aQuads[_indX1];
+  swap( aCubeSide[B_BOTTOM]._quad, quad[0] );
+  swap( aCubeSide[B_BOTTOM]._quad->side[ Q_RIGHT],// direct the normal of bottom quad inside cube
+        aCubeSide[B_BOTTOM]._quad->side[ Q_LEFT ] );
 
-  // 1.7 - get convertion coefs from face 2D normalized to 3D normalized
+  aCubeSide[B_FRONT]._quad = getQuadWithBottom( aCubeSide[B_BOTTOM]._quad->side[Q_BOTTOM], quad );
+  aCubeSide[B_RIGHT]._quad = getQuadWithBottom( aCubeSide[B_BOTTOM]._quad->side[Q_RIGHT ], quad );
+  aCubeSide[B_BACK ]._quad = getQuadWithBottom( aCubeSide[B_BOTTOM]._quad->side[Q_TOP   ], quad );
+  aCubeSide[B_LEFT ]._quad = getQuadWithBottom( aCubeSide[B_BOTTOM]._quad->side[Q_LEFT  ], quad );
+  if ( aCubeSide[B_FRONT ]._quad )
+    aCubeSide[B_TOP]._quad = getQuadWithBottom( aCubeSide[B_FRONT ]._quad->side[Q_TOP ], quad );
 
-  Conv2DStruct cx0;                    // for face X=0
-  Conv2DStruct cx1;                    // for face X=1
-  Conv2DStruct cy0;
-  Conv2DStruct cy1;
-  Conv2DStruct cz0;
-  Conv2DStruct cz1;
+  for ( int i = 1; i < 6; ++i )
+    if ( !aCubeSide[i]._quad )
+      return error( COMPERR_BAD_SHAPE );
 
-  GetConv2DCoefs(*aCube.quad_X0, meshFaces[_indX0]->GetSubShape(),
-                 aCube.V000, aCube.V010, aCube.V011, aCube.V001, cx0);
-  GetConv2DCoefs(*aCube.quad_X1, meshFaces[_indX1]->GetSubShape(),
-                 aCube.V100, aCube.V110, aCube.V111, aCube.V101, cx1);
-  GetConv2DCoefs(*aCube.quad_Y0, meshFaces[_indY0]->GetSubShape(),
-                 aCube.V000, aCube.V100, aCube.V101, aCube.V001, cy0);
-  GetConv2DCoefs(*aCube.quad_Y1, meshFaces[_indY1]->GetSubShape(),
-                 aCube.V010, aCube.V110, aCube.V111, aCube.V011, cy1);
-  GetConv2DCoefs(*aCube.quad_Z0, meshFaces[_indZ0]->GetSubShape(),
-                 aCube.V000, aCube.V100, aCube.V110, aCube.V010, cz0);
-  GetConv2DCoefs(*aCube.quad_Z1, meshFaces[_indZ1]->GetSubShape(),
-                 aCube.V001, aCube.V101, aCube.V111, aCube.V011, cz1);
+  // Make viscous layers
+  // --------------------
 
-  // 1.8 - create a 3D structure for normalized values
-  
-  int nbx = aCube.quad_Z0->side[0]->NbPoints();
-  if (cz0.a1 == 0.) nbx = aCube.quad_Z0->side[1]->NbPoints();
-  int nby = aCube.quad_X0->side[0]->NbPoints();
-  if (cx0.a1 == 0.) nby = aCube.quad_X0->side[1]->NbPoints();
-  int nbz = aCube.quad_Y0->side[0]->NbPoints();
-  if (cy0.a1 != 0.) nbz = aCube.quad_Y0->side[1]->NbPoints();
-
-  int i1, j1, nbxyz = nbx * nby * nbz;
-  Point3DStruct *np = new Point3DStruct[nbxyz];
+  SMESH_ProxyMesh::Ptr proxymesh;
+  if ( _viscousLayersHyp )
+  {
+    proxymesh = _viscousLayersHyp->Compute( aMesh, aShape, /*makeN2NMap=*/ true );
+    if ( !proxymesh )
+      return false;
+  }
 
-  // 1.9 - store node indexes of faces
+  // Check if there are triangles on cube sides
+  // -------------------------------------------
 
+  if ( aMesh.NbTriangles() > 0 )
   {
-    const TopoDS_Face & F = TopoDS::Face(meshFaces[_indX0]->GetSubShape());
-
-    faceQuadStruct *quad = aCube.quad_X0;
-    int i = 0;                         // j = x/face , k = y/face
-    int nbdown = quad->side[0]->NbPoints();
-    int nbright = quad->side[1]->NbPoints();
-
-    SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
-                       
-    while(itf->more()) {
-      const SMDS_MeshNode * node = itf->next();
-      if(aTool.IsMedium(node))
-        continue;
-      if ( !findIJ( node, quad, i1, j1 ))
-        return ClearAndReturn( aQuads, false );
-      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(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
-        np[ijk].node = quad->uv_grid[ij1].node;
-        //SCRUTE(np[ijk].nodeId);
+    for ( int i = 0; i < 6; ++i )
+    {
+      const TopoDS_Face& sideF = aCubeSide[i]._quad->face;
+      if ( SMESHDS_SubMesh* smDS = meshDS->MeshElements( sideF ))
+      {
+        bool isAllQuad = true;
+        SMDS_ElemIteratorPtr fIt = smDS->GetElements();
+        while ( fIt->more() && isAllQuad )
+        {
+          const SMDS_MeshElement* f = fIt->next();
+          isAllQuad = ( f->NbCornerNodes() == 4 );
+        }
+        if ( !isAllQuad )
+        {
+          SMESH_ComputeErrorPtr err = ComputePentahedralMesh(aMesh, aShape, proxymesh.get());
+          return error( err );
+        }
       }
+    }
   }
 
-  {
-    const TopoDS_Face & F = TopoDS::Face(meshFaces[_indX1]->GetSubShape());
-
-    SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
-
-    faceQuadStruct *quad = aCube.quad_X1;
-    int i = nbx - 1;           // j = x/face , k = y/face
-    int nbdown = quad->side[0]->NbPoints();
-    int nbright = quad->side[1]->NbPoints();
-
-    while(itf->more()) {
-      const SMDS_MeshNode * node = itf->next();
-      if(aTool.IsMedium(node))
-        continue;
-      if ( !findIJ( node, quad, i1, j1 ))
-        return ClearAndReturn( aQuads, false );
-      int ij1 = j1 * nbdown + i1;
-      quad->uv_grid[ij1].node = node;
-    }
+  // Check presence of regular grid mesh on FACEs of the cube
+  // ------------------------------------------------------------
 
-    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(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
-        np[ijk].node = quad->uv_grid[ij1].node;
-        //SCRUTE(np[ijk].nodeId);
-      }
-  }
+  // tool creating quadratic elements if needed
+  SMESH_MesherHelper helper (aMesh);
+  _quadraticMesh = helper.IsQuadraticSubMesh(aShape);
 
+  for ( int i = 0; i < 6; ++i )
   {
-    const TopoDS_Face & F = TopoDS::Face(meshFaces[_indY0]->GetSubShape());
-
-    SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
-
-    faceQuadStruct *quad = aCube.quad_Y0;
-    int j = 0;                         // i = x/face , k = y/face
-    int nbdown = quad->side[0]->NbPoints();
-    int nbright = quad->side[1]->NbPoints();
-
-    while(itf->more()) {
-      const SMDS_MeshNode * node = itf->next();
-      if(aTool.IsMedium(node))
-        continue;
-      if ( !findIJ( node, quad, i1, j1 ))
-        return ClearAndReturn( aQuads, false );
-      int ij1 = j1 * nbdown + i1;
-      quad->uv_grid[ij1].node = node;
+    const TopoDS_Face& F = aCubeSide[i]._quad->face;
+    StdMeshers_FaceSide* baseQuadSide = aCubeSide[i]._quad->side[ Q_BOTTOM ];
+    list<TopoDS_Edge> baseEdges( baseQuadSide->Edges().begin(), baseQuadSide->Edges().end() );
+
+    // assure correctness of node positions on baseE:
+    // helper.GetNodeU() will fix positions if they are wrong
+    helper.ToFixNodeParameters( true );
+    for ( int iE = 0; iE < baseQuadSide->NbEdges(); ++iE )
+    {
+      const TopoDS_Edge& baseE = baseQuadSide->Edge( iE );
+      if ( SMESHDS_SubMesh* smDS = meshDS->MeshElements( baseE ))
+      {
+        bool ok;
+        helper.SetSubShape( baseE );
+        SMDS_ElemIteratorPtr eIt = smDS->GetElements();
+        while ( eIt->more() )
+        {
+          const SMDS_MeshElement* e = eIt->next();
+          // expect problems on a composite side
+          try { helper.GetNodeU( baseE, e->GetNode(0), e->GetNode(1), &ok); }
+          catch (...) {}
+          try { helper.GetNodeU( baseE, e->GetNode(1), e->GetNode(0), &ok); }
+          catch (...) {}
+        }
+      }
     }
 
-    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(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
-        np[ijk].node = quad->uv_grid[ij1].node;
-        //SCRUTE(np[ijk].nodeId);
-      }
+    // load grid
+    bool ok =
+      helper.LoadNodeColumns( aCubeSide[i]._u2nodesMap, F, baseEdges, meshDS, proxymesh.get());
+    if ( ok )
+    {
+      // check if the loaded grid corresponds to nb of quadrangles on the FACE
+      const SMESHDS_SubMesh* faceSubMesh =
+        proxymesh ? proxymesh->GetSubMesh( F ) : meshDS->MeshElements( F );
+      const int nbQuads = faceSubMesh->NbElements();
+      const int nbHor = aCubeSide[i]._u2nodesMap.size() - 1;
+      const int nbVer = aCubeSide[i]._u2nodesMap.begin()->second.size() - 1;
+      ok = ( nbQuads == nbHor * nbVer );
+    }
+    if ( !ok )
+    {
+      SMESH_ComputeErrorPtr err = ComputePentahedralMesh(aMesh, aShape, proxymesh.get());
+      return error( err );
+    }
   }
 
+  // Orient loaded grids of cube sides along axis of the unitary cube coord system
+  bool isReverse[6];
+  isReverse[B_BOTTOM] = beginsAtSide( aCubeSide[B_BOTTOM], aCubeSide[B_RIGHT ], proxymesh );
+  isReverse[B_TOP   ] = beginsAtSide( aCubeSide[B_TOP   ], aCubeSide[B_RIGHT ], proxymesh );
+  isReverse[B_FRONT ] = beginsAtSide( aCubeSide[B_FRONT ], aCubeSide[B_RIGHT ], proxymesh );
+  isReverse[B_BACK  ] = beginsAtSide( aCubeSide[B_BACK  ], aCubeSide[B_RIGHT ], proxymesh );
+  isReverse[B_LEFT  ] = beginsAtSide( aCubeSide[B_LEFT  ], aCubeSide[B_BACK  ], proxymesh );
+  isReverse[B_RIGHT ] = beginsAtSide( aCubeSide[B_RIGHT ], aCubeSide[B_BACK  ], proxymesh );
+  for ( int i = 0; i < 6; ++i )
   {
-    const TopoDS_Face & F = TopoDS::Face(meshFaces[_indY1]->GetSubShape());
-
-    SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
-
-    faceQuadStruct *quad = aCube.quad_Y1;
-    int j = nby - 1;           // i = x/face , k = y/face
-    int nbdown = quad->side[0]->NbPoints();
-    int nbright = quad->side[1]->NbPoints();
-
-    while(itf->more()) {
-      const SMDS_MeshNode * node = itf->next();
-      if(aTool.IsMedium(node))
-        continue;
-      if ( !findIJ( node, quad, i1, j1 ))
-        return ClearAndReturn( aQuads, false );
-      int ij1 = j1 * nbdown + i1;
-      quad->uv_grid[ij1].node = node;
-    }
+    aCubeSide[i]._columns.resize( aCubeSide[i]._u2nodesMap.size() );
 
-    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(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
-        np[ijk].node = quad->uv_grid[ij1].node;
-        //SCRUTE(np[ijk].nodeId);
-      }
+    int iFwd = 0, iRev = aCubeSide[i]._columns.size()-1;
+    int* pi = isReverse[i] ? &iRev : &iFwd;
+    TParam2ColumnMap::iterator u2nn = aCubeSide[i]._u2nodesMap.begin();
+    for ( ; iFwd < aCubeSide[i]._columns.size(); --iRev, ++iFwd, ++u2nn )
+      aCubeSide[i]._columns[ *pi ].swap( u2nn->second );
+
+    aCubeSide[i]._u2nodesMap.clear();
   }
+  
+  if ( proxymesh )
+    for ( int i = 0; i < 6; ++i )
+      for ( unsigned j = 0; j < aCubeSide[i]._columns.size(); ++j)
+        for ( unsigned k = 0; k < aCubeSide[i]._columns[j].size(); ++k)
+        {
+          const SMDS_MeshNode* & n = aCubeSide[i]._columns[j][k];
+          n = proxymesh->GetProxyNode( n );
+        }
 
-  {
-    const TopoDS_Face & F = TopoDS::Face(meshFaces[_indZ0]->GetSubShape());
-
-    SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
-
-    faceQuadStruct *quad = aCube.quad_Z0;
-    int k = 0;                         // i = x/face , j = y/face
-    int nbdown = quad->side[0]->NbPoints();
-    int nbright = quad->side[1]->NbPoints();
-
-    while(itf->more()) {
-      const SMDS_MeshNode * node = itf->next();
-      if(aTool.IsMedium(node))
-        continue;
-      if ( !findIJ( node, quad, i1, j1 ))
-        return ClearAndReturn( aQuads, false );
-      int ij1 = j1 * nbdown + i1;
-      quad->uv_grid[ij1].node = node;
+  // 4) Create internal nodes of the cube
+  // -------------------------------------
+
+  helper.SetSubShape( aShape );
+  helper.SetElementsOnShape(true);
+
+  // shortcuts to sides
+  _FaceGrid* fBottom = & aCubeSide[ B_BOTTOM ];
+  _FaceGrid* fRight  = & aCubeSide[ B_RIGHT  ];
+  _FaceGrid* fTop    = & aCubeSide[ B_TOP    ];
+  _FaceGrid* fLeft   = & aCubeSide[ B_LEFT   ];
+  _FaceGrid* fFront  = & aCubeSide[ B_FRONT  ];
+  _FaceGrid* fBack   = & aCubeSide[ B_BACK   ];
+
+  // cube size measured in nb of nodes
+  int x, xSize = fBottom->_columns.size() , X = xSize - 1;
+  int y, ySize = fLeft->_columns.size()   , Y = ySize - 1;
+  int z, zSize = fLeft->_columns[0].size(), Z = zSize - 1;
+
+  // columns of internal nodes "rising" from nodes of fBottom
+  _Indexer colIndex( xSize, ySize );
+  vector< vector< const SMDS_MeshNode* > > columns( colIndex.size() );
+
+  // fill node columns by front and back box sides
+  for ( x = 0; x < xSize; ++x ) {
+    vector< const SMDS_MeshNode* >& column0 = columns[ colIndex( x, 0 )];
+    vector< const SMDS_MeshNode* >& column1 = columns[ colIndex( x, Y )];
+    column0.resize( zSize );
+    column1.resize( zSize );
+    for ( z = 0; z < zSize; ++z ) {
+      column0[ z ] = fFront->GetNode( x, z );
+      column1[ z ] = fBack ->GetNode( x, z );
     }
-
-    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(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
-        np[ijk].node = quad->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 = aCube.quad_Z1;
-    int k = nbz - 1;           // i = x/face , j = y/face
-    int nbdown = quad->side[0]->NbPoints();
-    int nbright = quad->side[1]->NbPoints();
-    
-    while(itf->more()) {
-      const SMDS_MeshNode * node = itf->next();
-      if(aTool.IsMedium(node))
-        continue;
-      if ( !findIJ( node, quad, i1, j1 ))
-        return ClearAndReturn( aQuads, false );
-      int ij1 = j1 * nbdown + i1;
-      quad->uv_grid[ij1].node = node;
+  // fill node columns by left and right box sides
+  for ( y = 1; y < ySize-1; ++y ) {
+    vector< const SMDS_MeshNode* >& column0 = columns[ colIndex( 0, y )];
+    vector< const SMDS_MeshNode* >& column1 = columns[ colIndex( X, y )];
+    column0.resize( zSize );
+    column1.resize( zSize );
+    for ( z = 0; z < zSize; ++z ) {
+      column0[ z ] = fLeft ->GetNode( y, z );
+      column1[ z ] = fRight->GetNode( y, z );
     }
-
-    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(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
-        np[ijk].node = quad->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
-
-  int shapeID = meshDS->ShapeToIndex( aShape );
-
-  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, shapeID);
-      }
+  // get nodes from top and bottom box sides
+  for ( x = 1; x < xSize-1; ++x ) {
+    for ( y = 1; y < ySize-1; ++y ) {
+      vector< const SMDS_MeshNode* >& column = columns[ colIndex( x, y )];
+      column.resize( zSize );
+      column.front() = fBottom->GetNode( x, y );
+      column.back()  = fTop   ->GetNode( x, y );
     }
   }
 
-  // find orientation of furute volumes according to MED convention
-  vector< bool > forward( nbx * nby );
-  SMDS_VolumeTool vTool;
-  for (int i = 0; i < nbx - 1; i++) {
-    for (int j = 0; j < nby - 1; j++) {
-      int n1 = j * nbx + i;
-      int n2 = j * nbx + i + 1;
-      int n3 = (j + 1) * nbx + i + 1;
-      int n4 = (j + 1) * nbx + i;
-      int n5 = nbx * nby + j * nbx + i;
-      int n6 = nbx * nby + j * nbx + i + 1;
-      int n7 = nbx * nby + (j + 1) * nbx + i + 1;
-      int n8 = nbx * nby + (j + 1) * nbx + i;
-
-      SMDS_VolumeOfNodes tmpVol (np[n1].node,np[n2].node,np[n3].node,np[n4].node,
-                                 np[n5].node,np[n6].node,np[n7].node,np[n8].node);
-      vTool.Set( &tmpVol );
-      forward[ n1 ] = vTool.IsForward();
+  // projection points of the internal node on cube sub-shapes by which
+  // coordinates of the internal node are computed
+  vector<gp_XYZ> pointsOnShapes( SMESH_Block::ID_Shell );
+
+  // projections on vertices are constant
+  pointsOnShapes[ SMESH_Block::ID_V000 ] = fBottom->GetXYZ( 0, 0 );
+  pointsOnShapes[ SMESH_Block::ID_V100 ] = fBottom->GetXYZ( X, 0 );
+  pointsOnShapes[ SMESH_Block::ID_V010 ] = fBottom->GetXYZ( 0, Y );
+  pointsOnShapes[ SMESH_Block::ID_V110 ] = fBottom->GetXYZ( X, Y );
+  pointsOnShapes[ SMESH_Block::ID_V001 ] = fTop->GetXYZ( 0, 0 );
+  pointsOnShapes[ SMESH_Block::ID_V101 ] = fTop->GetXYZ( X, 0 );
+  pointsOnShapes[ SMESH_Block::ID_V011 ] = fTop->GetXYZ( 0, Y );
+  pointsOnShapes[ SMESH_Block::ID_V111 ] = fTop->GetXYZ( X, Y );
+
+  for ( x = 1; x < xSize-1; ++x )
+  {
+    gp_XYZ params; // normalized parameters of internal node within a unit box
+    params.SetCoord( 1, x / double(X) );
+    for ( y = 1; y < ySize-1; ++y )
+    {
+      params.SetCoord( 2, y / double(Y) );
+      // a column to fill in during z loop
+      vector< const SMDS_MeshNode* >& column = columns[ colIndex( x, y )];
+      // projection points on horizontal edges
+      pointsOnShapes[ SMESH_Block::ID_Ex00 ] = fBottom->GetXYZ( x, 0 );
+      pointsOnShapes[ SMESH_Block::ID_Ex10 ] = fBottom->GetXYZ( x, Y );
+      pointsOnShapes[ SMESH_Block::ID_E0y0 ] = fBottom->GetXYZ( 0, y );
+      pointsOnShapes[ SMESH_Block::ID_E1y0 ] = fBottom->GetXYZ( X, y );
+      pointsOnShapes[ SMESH_Block::ID_Ex01 ] = fTop->GetXYZ( x, 0 );
+      pointsOnShapes[ SMESH_Block::ID_Ex11 ] = fTop->GetXYZ( x, Y );
+      pointsOnShapes[ SMESH_Block::ID_E0y1 ] = fTop->GetXYZ( 0, y );
+      pointsOnShapes[ SMESH_Block::ID_E1y1 ] = fTop->GetXYZ( X, y );
+      // projection points on horizontal faces
+      pointsOnShapes[ SMESH_Block::ID_Fxy0 ] = fBottom->GetXYZ( x, y );
+      pointsOnShapes[ SMESH_Block::ID_Fxy1 ] = fTop   ->GetXYZ( x, y );
+      for ( z = 1; z < zSize-1; ++z ) // z loop
+      {
+        params.SetCoord( 3, z / double(Z) );
+        // projection points on vertical edges
+        pointsOnShapes[ SMESH_Block::ID_E00z ] = fFront->GetXYZ( 0, z );    
+        pointsOnShapes[ SMESH_Block::ID_E10z ] = fFront->GetXYZ( X, z );    
+        pointsOnShapes[ SMESH_Block::ID_E01z ] = fBack->GetXYZ( 0, z );    
+        pointsOnShapes[ SMESH_Block::ID_E11z ] = fBack->GetXYZ( X, z );
+        // projection points on vertical faces
+        pointsOnShapes[ SMESH_Block::ID_Fx0z ] = fFront->GetXYZ( x, z );    
+        pointsOnShapes[ SMESH_Block::ID_Fx1z ] = fBack ->GetXYZ( x, z );    
+        pointsOnShapes[ SMESH_Block::ID_F0yz ] = fLeft ->GetXYZ( y, z );    
+        pointsOnShapes[ SMESH_Block::ID_F1yz ] = fRight->GetXYZ( y, z );
+
+        // compute internal node coordinates
+        gp_XYZ coords;
+        SMESH_Block::ShellPoint( params, pointsOnShapes, coords );
+        column[ z ] = helper.AddNode( coords.X(), coords.Y(), coords.Z() );
+
+      }
     }
   }
 
-  //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++) {
-      bool isForw = forward.at( j * nbx + i );
-      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;
-
-        SMDS_MeshVolume * elt;
-        if ( isForw ) {
-          elt = aTool.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);
-        }
-        else {
-          elt = aTool.AddVolume(np[n1].node, np[n4].node,
-                                np[n3].node, np[n2].node,
-                                np[n5].node, np[n8].node,
-                                np[n7].node, np[n6].node);
-        }
-        
-        meshDS->SetMeshElementOnShape(elt, shapeID);
+  // side data no more needed, free memory
+  for ( int i = 0; i < 6; ++i )
+    aCubeSide[i]._columns.clear();
+
+  // 5) Create hexahedrons
+  // ---------------------
+
+  for ( x = 0; x < xSize-1; ++x ) {
+    for ( y = 0; y < ySize-1; ++y ) {
+      vector< const SMDS_MeshNode* >& col00 = columns[ colIndex( x, y )];
+      vector< const SMDS_MeshNode* >& col10 = columns[ colIndex( x+1, y )];
+      vector< const SMDS_MeshNode* >& col01 = columns[ colIndex( x, y+1 )];
+      vector< const SMDS_MeshNode* >& col11 = columns[ colIndex( x+1, y+1 )];
+      for ( z = 0; z < zSize-1; ++z )
+      {
+        // bottom face normal of a hexa mush point outside the volume
+        helper.AddVolume(col00[z],   col01[z],   col11[z],   col10[z],
+                         col00[z+1], col01[z+1], col11[z+1], col10[z+1]);
       }
     }
   }
-  if ( np ) delete [] np;
-  return ClearAndReturn( aQuads, 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(" "<<i<<" "<<j<<" "<<k<<" "<<p[0]<<" "<<p[1]<<" "<<p[2]);
-}
-
-//=============================================================================
-/*!
- *  
- */
-//=============================================================================
-
-int StdMeshers_Hexa_3D::GetFaceIndex(SMESH_Mesh & aMesh,
-       const TopoDS_Shape & aShape,
-       const vector < SMESH_subMesh * >&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;
+  return true;
 }
 
 //=============================================================================
 /*!
- *  
+ *  Evaluate
  */
 //=============================================================================
 
-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)
+bool StdMeshers_Hexa_3D::Evaluate(SMESH_Mesh & aMesh,
+                                  const TopoDS_Shape & aShape,
+                                  MapShapeNbElems& aResMap)
 {
-//     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;
-//     }
-  VA = quad.side[0]->FirstVertex();
-  VB = quad.side[0]->LastVertex();
+  vector < SMESH_subMesh * >meshFaces;
+  TopTools_SequenceOfShape aFaces;
+  for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
+    aFaces.Append(exp.Current());
+    SMESH_subMesh *aSubMesh = aMesh.GetSubMeshContaining(exp.Current());
+    ASSERT(aSubMesh);
+    meshFaces.push_back(aSubMesh);
+  }
+  if (meshFaces.size() != 6) {
+    //return error(COMPERR_BAD_SHAPE, TComm(meshFaces.size())<<" instead of 6 faces in a block");
+    static StdMeshers_CompositeHexa_3D compositeHexa(-10, 0, aMesh.GetGen());
+    return compositeHexa.Evaluate(aMesh, aShape, aResMap);
+  }
+  
+  int i = 0;
+  for(; i<6; i++) {
+    //TopoDS_Shape aFace = meshFaces[i]->GetSubShape();
+    TopoDS_Shape aFace = aFaces.Value(i+1);
+    SMESH_Algo *algo = _gen->GetAlgo(aMesh, aFace);
+    if( !algo ) {
+      std::vector<int> aResVec(SMDSEntity_Last);
+      for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
+      SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+      aResMap.insert(std::make_pair(sm,aResVec));
+      SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+      smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
+      return false;
+    }
+    string algoName = algo->GetName();
+    bool isAllQuad = false;
+    if (algoName == "Quadrangle_2D") {
+      MapShapeNbElemsItr anIt = aResMap.find(meshFaces[i]);
+      if( anIt == aResMap.end() ) continue;
+      std::vector<int> aVec = (*anIt).second;
+      int nbtri = Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]);
+      if( nbtri == 0 )
+        isAllQuad = true;
+    }
+    if ( ! isAllQuad ) {
+      return EvaluatePentahedralMesh(aMesh, aShape, aResMap);
+    }
+  }
   
-       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.side[0]->NbPoints();
-       int nbright = quad.side[1]->NbPoints();
-       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);
+  // find number of 1d elems for 1 face
+  int nb1d = 0;
+  TopTools_MapOfShape Edges1;
+  bool IsQuadratic = false;
+  bool IsFirst = true;
+  for (TopExp_Explorer exp(aFaces.Value(1), TopAbs_EDGE); exp.More(); exp.Next()) {
+    Edges1.Add(exp.Current());
+    SMESH_subMesh *sm = aMesh.GetSubMesh(exp.Current());
+    if( sm ) {
+      MapShapeNbElemsItr anIt = aResMap.find(sm);
+      if( anIt == aResMap.end() ) continue;
+      std::vector<int> aVec = (*anIt).second;
+      nb1d += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]);
+      if(IsFirst) {
+        IsQuadratic = (aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge]);
+        IsFirst = false;
+      }
+    }
+  }
+  // find face opposite to 1 face
+  int OppNum = 0;
+  for(i=2; i<=6; i++) {
+    bool IsOpposite = true;
+    for(TopExp_Explorer exp(aFaces.Value(i), TopAbs_EDGE); exp.More(); exp.Next()) {
+      if( Edges1.Contains(exp.Current()) ) {
+        IsOpposite = false;
+        break;
+      }
+    }
+    if(IsOpposite) {
+      OppNum = i;
+      break;
+    }
+  }
+  // find number of 2d elems on side faces
+  int nb2d = 0;
+  for(i=2; i<=6; i++) {
+    if( i == OppNum ) continue;
+    MapShapeNbElemsItr anIt = aResMap.find( meshFaces[i-1] );
+    if( anIt == aResMap.end() ) continue;
+    std::vector<int> aVec = (*anIt).second;
+    nb2d += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]);
+  }
+  
+  MapShapeNbElemsItr anIt = aResMap.find( meshFaces[0] );
+  std::vector<int> aVec = (*anIt).second;
+  int nb2d_face0 = Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]);
+  int nb0d_face0 = aVec[SMDSEntity_Node];
+
+  std::vector<int> aResVec(SMDSEntity_Last);
+  for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
+  if(IsQuadratic) {
+    aResVec[SMDSEntity_Quad_Hexa] = nb2d_face0 * ( nb2d/nb1d );
+    int nb1d_face0_int = ( nb2d_face0*4 - nb1d ) / 2;
+    aResVec[SMDSEntity_Node] = nb0d_face0 * ( 2*nb2d/nb1d - 1 ) - nb1d_face0_int * nb2d/nb1d;
+  }
+  else {
+    aResVec[SMDSEntity_Node] = nb0d_face0 * ( nb2d/nb1d - 1 );
+    aResVec[SMDSEntity_Hexa] = nb2d_face0 * ( nb2d/nb1d );
+  }
+  SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+  aResMap.insert(std::make_pair(sm,aResVec));
+
+  return true;
 }
 
 //================================================================================
 /*!
- * \brief Find a vertex opposite to the given vertex of aQuads[0]
-  * \param aVertex - the vertex
-  * \param aFace - the face aVertex belongs to
-  * \param aQuads - quads
-  * \retval TopoDS_Vertex - found vertex
+ * \brief Computes hexahedral mesh from 2D mesh of block
  */
 //================================================================================
 
-TopoDS_Vertex StdMeshers_Hexa_3D::OppositeVertex(const TopoDS_Vertex& aVertex,
-                                                 const TopTools_IndexedMapOfShape& aQuads0Vertices,
-                                                 FaceQuadStruct* aQuads[6])
+bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, SMESH_MesherHelper* aHelper)
 {
-  int i, j;
-  for ( i = 1; i < 6; ++i )
-  {
-    TopoDS_Vertex VV[] = { aQuads[i]->side[0]->FirstVertex(),
-                           aQuads[i]->side[0]->LastVertex() , 
-                           aQuads[i]->side[2]->LastVertex() ,
-                           aQuads[i]->side[2]->FirstVertex() };
-    for ( j = 0; j < 4; ++j )
-      if ( aVertex.IsSame( VV[ j ]))
-        break;
-    if ( j < 4 ) {
-      int jPrev = j ? j - 1 : 3;
-      int jNext = (j + 1) % 4;
-      if ( aQuads0Vertices.Contains( VV[ jPrev ] ))
-        return VV[ jNext ];
-      else
-        return VV[ jPrev ];
-    }
+  static StdMeshers_HexaFromSkin_3D * algo = 0;
+  if ( !algo ) {
+    SMESH_Gen* gen = aMesh.GetGen();
+    algo = new StdMeshers_HexaFromSkin_3D( gen->GetANewId(), 0, gen );
   }
-  return TopoDS_Vertex();
+  algo->InitComputeError();
+  algo->Compute( aMesh, aHelper );
+  return error( algo->GetComputeError());
 }
 
-//modified by NIZNHY-PKV Wed Nov 17 15:34:13 2004 f
-///////////////////////////////////////////////////////////////////////////////
-//ZZ
-//#include <stdio.h>
-
 //=======================================================================
 //function : ComputePentahedralMesh
 //purpose  : 
 //=======================================================================
 
-SMESH_ComputeErrorPtr ComputePentahedralMesh(SMESH_Mesh &         aMesh,
-                                             const TopoDS_Shape & aShape)
+SMESH_ComputeErrorPtr ComputePentahedralMesh(SMESH_Mesh &          aMesh,
+                                             const TopoDS_Shape &  aShape,
+                                             SMESH_ProxyMesh*      proxyMesh)
 {
-  //printf(" ComputePentahedralMesh HERE\n");
-  //
-  bool bOK;
   SMESH_ComputeErrorPtr err = SMESH_ComputeError::New();
-  //int iErr;
+  if ( proxyMesh )
+  {
+    err->myName = COMPERR_BAD_INPUT_MESH;
+    err->myComment = "Can't build pentahedral mesh on viscous layers";
+    return err;
+  }
+  bool bOK;
   StdMeshers_Penta_3D anAlgo;
   //
   bOK=anAlgo.Compute(aMesh, aShape);
@@ -1047,6 +781,7 @@ SMESH_ComputeErrorPtr ComputePentahedralMesh(SMESH_Mesh &         aMesh,
     }
     SMESH_Hypothesis::Hypothesis_Status aStatus;
     if ( aPrism3D->CheckHypothesis( aMesh, aShape, aStatus ) ) {
+      aPrism3D->InitComputeError();
       bOK = aPrism3D->Compute( aMesh, aShape );
       err = aPrism3D->GetComputeError();
     }
@@ -1055,3 +790,31 @@ SMESH_ComputeErrorPtr ComputePentahedralMesh(SMESH_Mesh &         aMesh,
 }
 
 
+//=======================================================================
+//function : EvaluatePentahedralMesh
+//purpose  : 
+//=======================================================================
+
+bool EvaluatePentahedralMesh(SMESH_Mesh & aMesh,
+                             const TopoDS_Shape & aShape,
+                             MapShapeNbElems& aResMap)
+{
+  StdMeshers_Penta_3D anAlgo;
+  bool bOK = anAlgo.Evaluate(aMesh, aShape, aResMap);
+
+  //err = anAlgo.GetComputeError();
+  //if ( !bOK && anAlgo.ErrorStatus() == 5 )
+  if( !bOK ) {
+    static StdMeshers_Prism_3D * aPrism3D = 0;
+    if ( !aPrism3D ) {
+      SMESH_Gen* gen = aMesh.GetGen();
+      aPrism3D = new StdMeshers_Prism_3D( gen->GetANewId(), 0, gen );
+    }
+    SMESH_Hypothesis::Hypothesis_Status aStatus;
+    if ( aPrism3D->CheckHypothesis( aMesh, aShape, aStatus ) ) {
+      return aPrism3D->Evaluate(aMesh, aShape, aResMap);
+    }
+  }
+
+  return bOK;
+}
index 24927ef5ae273c1f14cbee8b8cf62fd92b1c77cb..48f1eebbe8b08949ab2ef66ebf3e15a3373442c0 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_Hexa_3D.hxx
 //           Moved here from SMESH_Hexa_3D.hxx
 #include "SMESH_StdMeshers.hxx"
 
 #include "SMESH_3D_Algo.hxx"
-#include "SMESH_Mesh.hxx"
-#include "StdMeshers_Quadrangle_2D.hxx"
-#include "Utils_SALOME_Exception.hxx"
-
-#include "SMESH_MesherHelper.hxx"
-
-class TopTools_IndexedMapOfShape;
-
-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;
+class StdMeshers_ViscousLayers;
+class SMESH_MesherHelper;
 
-class STDMESHERS_EXPORT StdMeshers_Hexa_3D:
-  public SMESH_3D_Algo
+class STDMESHERS_EXPORT StdMeshers_Hexa_3D : public SMESH_3D_Algo
 {
 public:
   StdMeshers_Hexa_3D(int hypId, int studyId, SMESH_Gen* gen);
@@ -73,45 +47,16 @@ public:
                                const TopoDS_Shape& aShape,
                                SMESH_Hypothesis::Hypothesis_Status& aStatus);
 
-  virtual bool Compute(SMESH_Mesh& aMesh,
-                      const TopoDS_Shape& aShape)
-    /*throw (SALOME_Exception)*/;
-
-  static TopoDS_Vertex OppositeVertex(const TopoDS_Vertex& aVertex,
-                                      const TopTools_IndexedMapOfShape& aQuads0Vertices,
-                                      FaceQuadStruct* aQuads[6]);
+  virtual bool Compute(SMESH_Mesh& aMesh,  const TopoDS_Shape& aShape);
 
-protected:
-  TopoDS_Edge
-  EdgeNotInFace(SMESH_Mesh& aMesh,
-               const TopoDS_Shape& aShape,
-               const TopoDS_Face& aFace,
-               const TopoDS_Vertex& aVertex,
-               const TopTools_IndexedDataMapOfShapeListOfShape& MS);
+  virtual bool Compute(SMESH_Mesh & aMesh, SMESH_MesherHelper* aHelper);
 
-  int GetFaceIndex(SMESH_Mesh& aMesh,
-                  const TopoDS_Shape& aShape,
-                  const std::vector<SMESH_subMesh*>& meshFaces,
-                  const TopoDS_Vertex& V0,
-                  const TopoDS_Vertex& V1,
-                  const TopoDS_Vertex& V2,
-                  const TopoDS_Vertex& V3);
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
 
-  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);
+protected:
 
-  bool ClearAndReturn(FaceQuadStruct* theQuads[6], const bool res);
+  const StdMeshers_ViscousLayers* _viscousLayersHyp;
 };
 
 #endif
diff --git a/src/StdMeshers/StdMeshers_ImportSource.cxx b/src/StdMeshers/StdMeshers_ImportSource.cxx
new file mode 100644 (file)
index 0000000..e93b83a
--- /dev/null
@@ -0,0 +1,490 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+//  SMESH StdMeshers_ImportSource1D : implementaion of SMESH idl descriptions
+//  File   : StdMeshers_ImportSource1D.cxx
+//  Module : SMESH
+//
+#include "StdMeshers_ImportSource.hxx"
+
+#include "SMESHDS_GroupOnGeom.hxx"
+#include "SMESHDS_Mesh.hxx"
+#include "SMESH_Algo.hxx"
+#include "SMESH_Gen.hxx"
+#include "SMESH_Group.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_subMeshEventListener.hxx"
+
+#include "utilities.h"
+
+#include <Standard_ErrorHandler.hxx>
+
+#include <boost/shared_ptr.hpp>
+
+using namespace std;
+
+//=============================================================================
+/*!
+ * Creates StdMeshers_ImportSource1D
+ */
+//=============================================================================
+
+StdMeshers_ImportSource1D::StdMeshers_ImportSource1D(int         hypId,
+                                                     int         studyId,
+                                                     SMESH_Gen * gen)
+  :SMESH_Hypothesis(hypId, studyId, gen),
+   _toCopyMesh(false),
+   _toCopyGroups(false)
+{
+  _name = "ImportSource1D";
+  _param_algo_dim = 1; // is used by StdMeshers_Import_1D;
+}
+
+//=============================================================================
+/*!
+ * Creates StdMeshers_ImportSource2D
+ */
+//=============================================================================
+
+StdMeshers_ImportSource2D::StdMeshers_ImportSource2D(int         hypId,
+                                                     int         studyId,
+                                                     SMESH_Gen * gen)
+  :StdMeshers_ImportSource1D(hypId, studyId, gen)
+{
+  _name = "ImportSource2D";
+  _param_algo_dim = 2; // is used by StdMeshers_Import_2D;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+
+StdMeshers_ImportSource1D::~StdMeshers_ImportSource1D()
+{
+}
+//=============================================================================
+/*!
+ *  Sets groups to import elements from
+ */
+//=============================================================================
+
+void StdMeshers_ImportSource1D::SetGroups(const std::vector<SMESH_Group*>& groups)
+{
+  if (_groups != groups)
+  {
+    _groups = groups;
+    NotifySubMeshesHypothesisModification();
+  }
+}
+
+void StdMeshers_ImportSource1D::SetCopySourceMesh(bool toCopyMesh, bool toCopyGroups)
+{
+  if ( !toCopyMesh ) toCopyGroups = false;
+  if ( _toCopyMesh != toCopyMesh || _toCopyGroups != toCopyGroups )
+  {
+    _toCopyMesh = toCopyMesh; _toCopyGroups = toCopyGroups;
+    NotifySubMeshesHypothesisModification();
+  }
+}
+void StdMeshers_ImportSource1D::GetCopySourceMesh(bool& toCopyMesh, bool& toCopyGroups) const
+{
+  toCopyMesh = _toCopyMesh; toCopyGroups = _toCopyGroups;
+}
+  
+namespace
+{
+  //================================================================================
+  /*!
+   * \brief Return only alive groups
+   */
+  //================================================================================
+
+  vector<SMESH_Group*> getValidGroups(const vector<SMESH_Group*>& groups,
+                                      StudyContextStruct*         studyContext)
+  {
+    vector<SMESH_Group*> okGroups;
+    for ( int i = 0; i < groups.size(); ++i )
+    {
+      try
+      {
+        // we expect SIGSEGV on a dead group
+        OCC_CATCH_SIGNALS;
+        SMESH_Group* okGroup = 0;
+        map<int, SMESH_Mesh*>::iterator itm = itm = studyContext->mapMesh.begin();
+        for ( ; !okGroup && itm != studyContext->mapMesh.end(); itm++)
+        {
+          SMESH_Mesh::GroupIteratorPtr gIt = itm->second->GetGroups();
+          while ( gIt->more() && !okGroup )
+            if ( gIt->next() == groups[i] )
+              okGroup = groups[i];
+        }
+        if ( okGroup )
+          okGroups.push_back( okGroup );
+      }
+      catch(...)
+      {
+      }
+    }
+    return okGroups;
+  }
+  //================================================================================
+  /*!
+   * \brief Pack meshes into a pair of ints
+   */
+  //================================================================================
+
+  pair<int, int> getResMapKey(const SMESHDS_Mesh& srcMesh, const SMESHDS_Mesh& tgtMesh)
+  {
+    return make_pair( srcMesh.GetPersistentId() , tgtMesh.GetPersistentId() );
+  }
+  //================================================================================
+  /*!
+   * \brief Return a target mesh by a pair of ints
+   */
+  //================================================================================
+
+  SMESH_Mesh* getTgtMeshByKey( const pair<int, int> & resMapKey,
+                               StudyContextStruct*    studyContext)
+  {
+    int tgtID = resMapKey.second;
+    SMESH_Mesh* tgtMesh = 0;
+    map<int, SMESH_Mesh*>::iterator itm = itm = studyContext->mapMesh.begin();
+    for ( ; !tgtMesh && itm != studyContext->mapMesh.end(); itm++)
+    {
+      tgtMesh = (*itm).second;
+      if ( tgtMesh->GetMeshDS()->GetPersistentId() != tgtID )
+        tgtMesh = 0;
+    }
+    return tgtMesh;
+  }
+  //================================================================================
+  /*!
+   * \brief Return a target mesh by a pair of ints
+   */
+  //================================================================================
+
+  int getSrcMeshID( const pair<int, int> & resMapKey )
+  {
+    return resMapKey.first;
+  }
+}
+
+//=============================================================================
+/*!
+ *  Returns groups to import elements from
+ */
+//=============================================================================
+
+const std::vector<SMESH_Group*>&  StdMeshers_ImportSource1D::GetGroups() const
+{
+  // filter off deleted groups
+  vector<SMESH_Group*> okGroups = getValidGroups( _groups,
+                                                  _gen->GetStudyContext(_studyId) );
+  if ( okGroups.size() != _groups.size() )
+    ((StdMeshers_ImportSource1D*)this)->_groups = okGroups;
+
+  return _groups;
+}
+
+//================================================================================
+/*!
+ * \brief Return source meshes
+ */
+//================================================================================
+
+std::vector<SMESH_Mesh*> StdMeshers_ImportSource1D::GetSourceMeshes() const
+{
+  // GetPersistentId()'s of meshes
+  set<int> meshIDs;
+  const vector<SMESH_Group*>& groups = GetGroups();
+  if ( !groups.empty() )
+  {
+    for ( unsigned i = 0; i < groups.size(); ++i )
+    {
+      const SMESHDS_GroupBase* gDS = groups[i]->GetGroupDS();
+      int id = gDS->GetMesh()->GetPersistentId();
+      meshIDs.insert( id );
+    }
+  }
+  else
+  {
+    if ( _resultGroups.empty() )
+      ((StdMeshers_ImportSource1D*)this)->RestoreGroups(_groups);
+    TResGroupMap::const_iterator key_groups = _resultGroups.begin();
+    for ( ; key_groups != _resultGroups.end(); ++key_groups )
+      meshIDs.insert( getSrcMeshID( key_groups->first ));
+  }
+
+  // Find corresponding meshes
+  vector<SMESH_Mesh*> meshes;
+  if ( !meshIDs.empty() )
+  {
+    StudyContextStruct* studyContext = _gen->GetStudyContext(_studyId);
+    for ( set<int>::iterator id = meshIDs.begin(); id != meshIDs.end(); ++id )
+    {
+      map<int, SMESH_Mesh*>::iterator itm = itm = studyContext->mapMesh.begin();
+      for ( ; itm != studyContext->mapMesh.end(); itm++)
+      {
+        SMESH_Mesh* mesh = (*itm).second;
+        if ( mesh->GetMeshDS()->GetPersistentId() == *id )
+        {
+          meshes.push_back( mesh );
+          break;
+        }
+      }
+    }
+  }
+  return meshes;
+}
+
+//================================================================================
+/*!
+ * \brief Return submeshes whose events affect the target mesh
+ */
+//================================================================================
+
+std::vector<SMESH_subMesh*>
+StdMeshers_ImportSource1D::GetSourceSubMeshes(const SMESH_Mesh* srcMesh) const
+{
+  if ( !srcMesh->HasShapeToMesh() )
+  {
+    SMESH_Mesh* srcM = const_cast< SMESH_Mesh* >( srcMesh );
+    return vector<SMESH_subMesh*>(1, srcM->GetSubMesh( srcM->GetShapeToMesh()));
+  }
+  set<int> shapeIDs;
+  const vector<SMESH_Group*>& groups = GetGroups();
+  const SMESHDS_Mesh * srcMeshDS = srcMesh->GetMeshDS();
+  for ( size_t i = 0; i < groups.size(); ++i )
+  {
+    SMESHDS_GroupBase * grDS = groups[i]->GetGroupDS();
+    if ( grDS->GetMesh() != srcMeshDS )
+      continue;
+    if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( grDS ))
+    {
+      shapeIDs.insert( srcMeshDS->ShapeToIndex( gog->GetShape() ));
+    }
+    else
+    {
+      SMDS_ElemIteratorPtr elIt = grDS->GetElements();
+      while ( elIt->more() )
+        shapeIDs.insert( elIt->next()->getshapeId() );
+    }
+  }
+  if ( !shapeIDs.empty() && *shapeIDs.begin() < 1 )
+  {
+    shapeIDs.erase( shapeIDs.begin() );
+    shapeIDs.insert( 1 );
+  }
+
+  vector<SMESH_subMesh*> smVec( shapeIDs.size());
+  set<int>::iterator sID = shapeIDs.begin();
+  for ( int i = 0; sID != shapeIDs.end(); ++sID, ++i )
+    smVec[i] = srcMesh->GetSubMeshContaining( *sID );
+
+  return smVec;
+}
+
+//=============================================================================
+/*!
+ * Save _toCopyMesh and _toCopyGroups to a stream
+ */
+//=============================================================================
+
+ostream & StdMeshers_ImportSource1D::SaveTo(ostream & save)
+{
+  resultGroupsToIntVec();
+
+  save << " " << _toCopyMesh << " " << _toCopyGroups;
+  save << " " << _resultGroupsStorage.size();
+  for ( unsigned i = 0; i < _resultGroupsStorage.size(); ++i )
+    save << " " << _resultGroupsStorage[i];
+
+  return save;
+}
+
+//=============================================================================
+/*!
+ * Load _toCopyMesh and _toCopyGroups from a stream
+ */
+//=============================================================================
+
+istream & StdMeshers_ImportSource1D::LoadFrom(istream & load)
+{
+  load >> _toCopyMesh >> _toCopyGroups;
+
+  _resultGroupsStorage.clear();
+  int val;
+  if ( load >> val )
+  {
+    _resultGroupsStorage.reserve(val);
+    while ( _resultGroupsStorage.size() < _resultGroupsStorage.capacity() && load >> val )
+      _resultGroupsStorage.push_back( val );
+  }
+  return load;
+}
+
+//================================================================================
+/*!
+ * \brief Convert result groups into _resultGroupsStorage
+ */
+//================================================================================
+
+void StdMeshers_ImportSource1D::resultGroupsToIntVec()
+{
+  _resultGroupsStorage.clear();
+  
+  // store result groups
+  TResGroupMap::iterator key2groups = _resultGroups.begin();
+  for ( ; key2groups != _resultGroups.end(); ++key2groups )
+  {
+    const pair<int, int>&          key = key2groups->first;
+    const vector<SMESH_Group*>& groups = key2groups->second;
+    // mesh ids, nb groups
+    _resultGroupsStorage.push_back( key.first );
+    _resultGroupsStorage.push_back( key.second );
+    _resultGroupsStorage.push_back( groups.size() );
+    for ( unsigned i = 0; i < groups.size(); ++i )
+    {
+      // store group names as sequence of ints each standing for a char
+      // of a name; that is to avoid pb with names containing white spaces
+      string name = groups[i]->GetGroupDS()->GetStoreName();
+      _resultGroupsStorage.push_back( name.size() );
+      for ( unsigned j = 0; j < name.size(); ++j )
+        _resultGroupsStorage.push_back( name[j] );
+    }
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Restore source groups and result groups by _resultGroupsStorage
+ */
+//================================================================================
+
+void StdMeshers_ImportSource1D::RestoreGroups(const std::vector<SMESH_Group*>& groups)
+{
+  _groups = groups;
+
+  _resultGroups.clear();
+  int i = 0;
+  while ( i < _resultGroupsStorage.size() )
+  {
+    int key1 = _resultGroupsStorage[i++];
+    int key2 = _resultGroupsStorage[i++];
+    pair<int, int> resMapKey( key1, key2 );
+    SMESH_Mesh* mesh = getTgtMeshByKey( resMapKey, _gen->GetStudyContext(_studyId));
+    // restore mesh ids at least
+    _resultGroups.insert( make_pair (resMapKey,vector<SMESH_Group*>() )); 
+
+    int nbGroups = _resultGroupsStorage[i++];
+    for ( int j = 0; j < nbGroups; ++j )
+    {
+      string::size_type nameSize = _resultGroupsStorage[i++];
+      string groupName(nameSize, '\0');
+      for ( unsigned k = 0; k < nameSize; ++k )
+        groupName[k] = (char) _resultGroupsStorage[i++];
+
+      // find a group by name
+      if ( mesh )
+      {
+        SMESH_Group* group = 0;
+        SMESH_Mesh::GroupIteratorPtr gIt = mesh->GetGroups();
+        while ( !group && gIt->more() )
+        {
+          group = gIt->next();
+          if ( !group->GetGroupDS() || groupName != group->GetGroupDS()->GetStoreName() )
+            group = 0;
+        }
+        if ( group )
+          _resultGroups[ resMapKey ].push_back( group );
+      }
+    }
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Remember groups imported from other mesh
+ *  \param groups - result groups
+ *  \param srcMesh - source mesh
+ *  \param tgtMesh - destination mesh
+ */
+//================================================================================
+
+void StdMeshers_ImportSource1D::StoreResultGroups(const std::vector<SMESH_Group*>& groups,
+                                                  const SMESHDS_Mesh&              srcMesh,
+                                                  const SMESHDS_Mesh&              tgtMesh)
+{
+  _resultGroups[ getResMapKey(srcMesh,tgtMesh) ] = groups;
+}
+
+//================================================================================
+/*!
+ * \brief Return groups imported from other mesh
+ *  \param srcMesh - source mesh
+ *  \param tgtMesh - destination mesh
+ *  \retval const std::vector<SMESH_Group*>& - groups
+ */
+//================================================================================
+
+std::vector<SMESH_Group*>*
+StdMeshers_ImportSource1D::GetResultGroups(const SMESHDS_Mesh& srcMesh,
+                                           const SMESHDS_Mesh& tgtMesh) 
+{
+  TResGroupMap::iterator key2groups = _resultGroups.find( getResMapKey(srcMesh,tgtMesh ));
+  if ( key2groups == _resultGroups.end() )
+    return 0;
+  vector<SMESH_Group*> vec = getValidGroups((*key2groups).second,
+                                            _gen->GetStudyContext(_studyId) );
+  if ( vec.size() != key2groups->second.size())
+    key2groups->second = vec;
+
+  return & key2groups->second;
+}
+
+//================================================================================
+/*!
+ * \brief Initialize ImportSource value by the mesh built on the geometry
+ * \param theMesh - the built mesh
+ * \param theShape - the geometry of interest
+ * \retval bool - true if parameter values have been successfully defined
+ */
+//================================================================================
+
+bool StdMeshers_ImportSource1D::SetParametersByMesh(const SMESH_Mesh*, const TopoDS_Shape&)
+{
+  return false;
+}
+
+//================================================================================
+/*!
+ * \brief Initialize my parameter values by default parameters.
+ *  \retval bool - true if parameter values have been successfully defined
+ */
+//================================================================================
+
+bool StdMeshers_ImportSource1D::SetParametersByDefaults(const TDefaults&, const SMESH_Mesh* )
+{
+  return false;
+}
diff --git a/src/StdMeshers/StdMeshers_ImportSource.hxx b/src/StdMeshers/StdMeshers_ImportSource.hxx
new file mode 100644 (file)
index 0000000..d3347de
--- /dev/null
@@ -0,0 +1,99 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+//  SMESH StdMeshers : implementaion of SMESH idl descriptions
+//  File   : StdMeshers_ImportSource1D.hxx
+//  Module : SMESH
+//
+#ifndef _StdMeshers_ImportSource_HXX_
+#define _StdMeshers_ImportSource_HXX_
+
+#include "SMESH_StdMeshers.hxx"
+
+#include "SMESH_Hypothesis.hxx"
+#include "Utils_SALOME_Exception.hxx"
+
+#include <vector>
+#include <map>
+
+class SMESH_Group;
+class SMESHDS_Mesh;
+class SMESH_subMesh;
+
+//==============================================================================
+/*!
+ * \brief Stores groups to import elements from
+ */
+//==============================================================================
+
+class STDMESHERS_EXPORT StdMeshers_ImportSource1D : public SMESH_Hypothesis
+{
+ public:
+  StdMeshers_ImportSource1D(int hypId, int studyId, SMESH_Gen * gen);
+  virtual ~ StdMeshers_ImportSource1D();
+
+  void SetGroups(const std::vector<SMESH_Group*>& groups);
+  const std::vector<SMESH_Group*>& GetGroups() const;
+
+  void SetCopySourceMesh(bool toCopyMesh, bool toCopyGroups);
+  void GetCopySourceMesh(bool& toCopyMesh, bool& toCopyGroups) const;
+  
+  virtual std::ostream & SaveTo(std::ostream & save);
+  virtual std::istream & LoadFrom(std::istream & load);
+  virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape);
+  virtual bool SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh=0);
+  void RestoreGroups(const std::vector<SMESH_Group*>& groups);
+
+  void StoreResultGroups(const std::vector<SMESH_Group*>& groups,
+                         const SMESHDS_Mesh&              srcMesh,
+                         const SMESHDS_Mesh&              tgtMesh);
+  std::vector<SMESH_Group*>* GetResultGroups(const SMESHDS_Mesh& srcMesh,
+                                             const SMESHDS_Mesh& tgtMesh);
+
+  std::vector<SMESH_Mesh*> GetSourceMeshes() const;
+  std::vector<SMESH_subMesh*> GetSourceSubMeshes(const SMESH_Mesh* srcMesh) const;
+
+private:
+
+  std::vector<SMESH_Group*> _groups;
+  bool _toCopyMesh, _toCopyGroups;
+
+  // groups imported using this hypothesis
+  typedef std::map< std::pair<int, int>, std::vector<SMESH_Group*> > TResGroupMap;
+  TResGroupMap      _resultGroups;
+  std::vector<int>  _resultGroupsStorage; // persistent representation of _resultGroups
+
+  void resultGroupsToIntVec();
+};
+
+//==============================================================================
+/*!
+ * \brief Redefines name and dimension of inherited StdMeshers_ImportSource1D
+ */
+//==============================================================================
+
+class STDMESHERS_EXPORT StdMeshers_ImportSource2D : public StdMeshers_ImportSource1D
+{
+ public:
+  StdMeshers_ImportSource2D(int hypId, int studyId, SMESH_Gen * gen);
+};
+#endif
diff --git a/src/StdMeshers/StdMeshers_Import_1D.cxx b/src/StdMeshers/StdMeshers_Import_1D.cxx
new file mode 100644 (file)
index 0000000..b8a5076
--- /dev/null
@@ -0,0 +1,1055 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+//  File   : StdMeshers_Import_1D.cxx
+//  Module : SMESH
+//
+#include "StdMeshers_Import_1D.hxx"
+#include "StdMeshers_ImportSource.hxx"
+
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMESHDS_Group.hxx"
+#include "SMESHDS_Mesh.hxx"
+#include "SMESH_Comment.hxx"
+#include "SMESH_Gen.hxx"
+#include "SMESH_Group.hxx"
+#include "SMESH_HypoFilter.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_MesherHelper.hxx"
+#include "SMESH_subMesh.hxx"
+#include "SMESH_subMeshEventListener.hxx"
+
+#include "Utils_SALOME_Exception.hxx"
+#include "utilities.h"
+
+#include <BRep_Builder.hxx>
+#include <BRep_Tool.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Compound.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Vertex.hxx>
+
+using namespace std;
+
+//=============================================================================
+/*!
+ * Creates StdMeshers_Import_1D
+ */
+//=============================================================================
+
+StdMeshers_Import_1D::StdMeshers_Import_1D(int hypId, int studyId, SMESH_Gen * gen)
+  :SMESH_1D_Algo(hypId, studyId, gen), _sourceHyp(0)
+{
+  MESSAGE("StdMeshers_Import_1D::StdMeshers_Import_1D");
+  _name = "Import_1D";
+  _shapeType = (1 << TopAbs_EDGE);
+
+  _compatibleHypothesis.push_back("ImportSource1D");
+}
+
+//=============================================================================
+/*!
+ * Check presence of a hypothesis
+ */
+//=============================================================================
+
+bool StdMeshers_Import_1D::CheckHypothesis
+                         (SMESH_Mesh&                          aMesh,
+                          const TopoDS_Shape&                  aShape,
+                          SMESH_Hypothesis::Hypothesis_Status& aStatus)
+{
+  _sourceHyp = 0;
+
+  const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
+  if ( hyps.size() == 0 )
+  {
+    aStatus = SMESH_Hypothesis::HYP_MISSING;
+    return false;  // can't work with no hypothesis
+  }
+
+  if ( hyps.size() > 1 )
+  {
+    aStatus = SMESH_Hypothesis::HYP_ALREADY_EXIST;
+    return false;
+  }
+
+  const SMESHDS_Hypothesis *theHyp = hyps.front();
+
+  string hypName = theHyp->GetName();
+
+  if (hypName == _compatibleHypothesis.front())
+  {
+    _sourceHyp = (StdMeshers_ImportSource1D *)theHyp;
+    aStatus = SMESH_Hypothesis::HYP_OK;
+    return true;
+  }
+
+  aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
+  return true;
+}
+
+//================================================================================
+namespace // INTERNAL STUFF
+//================================================================================
+{
+  int getSubmeshIDForCopiedMesh(const SMESHDS_Mesh* srcMeshDS, SMESH_Mesh* tgtMesh);
+
+  enum _ListenerDataType
+    {
+      WAIT_HYP_MODIF=1, // data indicating awaiting for valid parameters of src hyp
+      LISTEN_SRC_MESH, // data storing submesh depending on source mesh state
+      SRC_HYP // data storing ImportSource hyp
+    };
+  //================================================================================
+  /*!
+   * \brief _ListenerData holding ImportSource hyp holding in its turn
+   *  imported groups
+   */
+  struct _ListenerData : public SMESH_subMeshEventListenerData
+  {
+    const StdMeshers_ImportSource1D* _srcHyp;
+    _ListenerData(const StdMeshers_ImportSource1D* h, _ListenerDataType type=SRC_HYP):
+      SMESH_subMeshEventListenerData(/*isDeletable=*/true), _srcHyp(h)
+    {
+      myType = type; 
+    }
+  };
+  //================================================================================
+  /*!
+   * \brief Comparator of sub-meshes
+   */
+  struct _SubLess
+  {
+    bool operator()(const SMESH_subMesh* sm1, const SMESH_subMesh* sm2 ) const
+    {
+      if ( sm1 == sm2 ) return false;
+      if ( !sm1 || !sm2 ) return sm1 < sm2;
+      const TopoDS_Shape& s1 = sm1->GetSubShape();
+      const TopoDS_Shape& s2 = sm2->GetSubShape();
+      TopAbs_ShapeEnum t1 = s1.IsNull() ? TopAbs_SHAPE : s1.ShapeType();
+      TopAbs_ShapeEnum t2 = s2.IsNull() ? TopAbs_SHAPE : s2.ShapeType();
+      if ( t1 == t2)
+        return (sm1 < sm2);
+      return t1 < t2; // to have: face < edge
+    }
+  };
+  //================================================================================
+  /*!
+   * \brief Container of data dedicated to one source mesh
+   */
+  struct _ImportData
+  {
+    const SMESH_Mesh* _srcMesh;
+    StdMeshers_Import_1D::TNodeNodeMap _n2n;
+    StdMeshers_Import_1D::TElemElemMap _e2e;
+
+    set< SMESH_subMesh*, _SubLess > _subM; // submeshes relating to this srcMesh
+    set< SMESH_subMesh*, _SubLess > _copyMeshSubM; // submeshes requesting mesh copying
+    set< SMESH_subMesh*, _SubLess > _copyGroupSubM; // submeshes requesting group copying
+    set< SMESH_subMesh*, _SubLess > _computedSubM;
+
+    SMESHDS_SubMesh*     _importMeshSubDS; // submesh storing a copy of _srcMesh
+    int                  _importMeshSubID; // id of _importMeshSubDS
+
+    _ImportData(const SMESH_Mesh* srcMesh=0):
+      _srcMesh(srcMesh), _importMeshSubDS(0),_importMeshSubID(-1) {}
+
+    void removeImportedMesh( SMESHDS_Mesh* meshDS )
+    {
+      if ( !_importMeshSubDS ) return;
+      SMDS_ElemIteratorPtr eIt = _importMeshSubDS->GetElements();
+      while ( eIt->more() )
+        meshDS->RemoveFreeElement( eIt->next(), _importMeshSubDS, /*fromGroups=*/false );
+      SMDS_NodeIteratorPtr nIt = _importMeshSubDS->GetNodes();
+      while ( nIt->more() )
+        meshDS->RemoveFreeNode( nIt->next(), _importMeshSubDS, /*fromGroups=*/false );
+      _n2n.clear();
+      _e2e.clear();
+    }
+    void removeGroups( SMESH_subMesh* subM, const StdMeshers_ImportSource1D* srcHyp )
+    {
+      if ( !srcHyp ) return;
+      SMESH_Mesh*           tgtMesh = subM->GetFather();
+      const SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS();
+      const SMESHDS_Mesh* srcMeshDS = _srcMesh->GetMeshDS();
+      vector<SMESH_Group*>*  groups =
+        const_cast<StdMeshers_ImportSource1D*>(srcHyp)->GetResultGroups(*srcMeshDS,*tgtMeshDS);
+      if ( groups )
+      {
+        for ( unsigned i = 0; i < groups->size(); ++i )
+          tgtMesh->RemoveGroup( groups->at(i)->GetGroupDS()->GetID() );
+        groups->clear();
+      }
+    }
+    void trackHypParams( SMESH_subMesh* sm, const StdMeshers_ImportSource1D* srcHyp )
+    {
+      if ( !srcHyp ) return;
+      bool toCopyMesh, toCopyGroups;
+      srcHyp->GetCopySourceMesh(toCopyMesh, toCopyGroups);
+
+      if ( toCopyMesh )_copyMeshSubM.insert( sm );
+      else             _copyMeshSubM.erase( sm );
+
+      if ( toCopyGroups ) _copyGroupSubM.insert( sm );
+      else                _copyGroupSubM.erase( sm );
+    }
+    void addComputed( SMESH_subMesh* sm )
+    {
+      SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true,
+                                                               /*complexShapeFirst=*/true);
+      while ( smIt->more() )
+      {
+        sm = smIt->next();
+        switch ( sm->GetSubShape().ShapeType() )
+        {
+        case TopAbs_EDGE:
+        case TopAbs_FACE:
+          _subM.insert( sm );
+          if ( !sm->IsEmpty() )
+            _computedSubM.insert( sm );
+        case TopAbs_VERTEX:
+          break;
+        default:;
+        }
+      }
+    }
+  };
+  //================================================================================
+  /*!
+   * Listener notified on events relating to imported submesh
+   */
+  class _Listener : public SMESH_subMeshEventListener
+  {
+    typedef map< SMESH_Mesh*, list< _ImportData > > TMesh2ImpData;
+    TMesh2ImpData _tgtMesh2ImportData;
+
+    _Listener():SMESH_subMeshEventListener(/*isDeletable=*/false,
+                                           "StdMeshers_Import_1D::_Listener") {}
+
+  public:
+    // return poiter to a static listener
+    static _Listener* get() { static _Listener theListener; return &theListener; }
+
+    static _ImportData* getImportData(const SMESH_Mesh* srcMesh, SMESH_Mesh* tgtMesh);
+
+    static void storeImportSubmesh(SMESH_subMesh*                   importSub,
+                                   const SMESH_Mesh*                srcMesh,
+                                   const StdMeshers_ImportSource1D* srcHyp);
+
+    virtual void ProcessEvent(const int                       event,
+                              const int                       eventType,
+                              SMESH_subMesh*                  subMesh,
+                              SMESH_subMeshEventListenerData* data,
+                              const SMESH_Hypothesis*         hyp);
+    void removeSubmesh( SMESH_subMesh* sm, _ListenerData* data );
+    void clearSubmesh ( SMESH_subMesh* sm, _ListenerData* data, bool clearAllSub );
+
+    // mark sm as missing src hyp with valid groups
+    static void waitHypModification(SMESH_subMesh* sm)
+    {
+      sm->SetEventListener
+        (get(), SMESH_subMeshEventListenerData::MakeData( sm, WAIT_HYP_MODIF ), sm);
+    }
+  };
+  //--------------------------------------------------------------------------------
+  /*!
+   * \brief Find or create ImportData for given meshes
+   */
+  _ImportData* _Listener::getImportData(const SMESH_Mesh* srcMesh,
+                                        SMESH_Mesh*       tgtMesh)
+  {
+    list< _ImportData >& dList = get()->_tgtMesh2ImportData[tgtMesh];
+    list< _ImportData >::iterator d = dList.begin();
+    for ( ; d != dList.end(); ++d )
+      if ( d->_srcMesh == srcMesh )
+        return &*d;
+    dList.push_back(_ImportData(srcMesh));
+    return &dList.back();
+  }
+
+  //--------------------------------------------------------------------------------
+  /*!
+   * \brief Remember an imported sub-mesh and set needed even listeners
+   *  \param importSub - submesh computed by Import algo
+   *  \param srcMesh - source mesh
+   *  \param srcHyp - ImportSource hypothesis
+   */
+  void _Listener::storeImportSubmesh(SMESH_subMesh*                   importSub,
+                                     const SMESH_Mesh*                srcMesh,
+                                     const StdMeshers_ImportSource1D* srcHyp)
+  {
+    // set listener to hear events of the submesh computed by "Import" algo
+    importSub->SetEventListener( get(), new _ListenerData(srcHyp), importSub );
+
+    // set listeners to hear events of the source mesh
+    SMESH_subMesh* smToNotify = importSub;
+    vector<SMESH_subMesh*> smToListen = srcHyp->GetSourceSubMeshes( srcMesh );
+    for ( size_t i = 0; i < smToListen.size(); ++i )
+    {
+      SMESH_subMeshEventListenerData* data = new _ListenerData(srcHyp, LISTEN_SRC_MESH);
+      data->mySubMeshes.push_back( smToNotify );
+      importSub->SetEventListener( get(), data, smToListen[i] );
+    }
+    // remember the submesh importSub and its sub-submeshes
+    _ImportData* iData = _Listener::getImportData( srcMesh, importSub->GetFather());
+    iData->trackHypParams( importSub, srcHyp );
+    iData->addComputed( importSub );
+    if ( !iData->_copyMeshSubM.empty() && iData->_importMeshSubID < 1 )
+    {
+      SMESH_Mesh* tgtMesh = importSub->GetFather();
+      iData->_importMeshSubID = getSubmeshIDForCopiedMesh( srcMesh->GetMeshDS(),tgtMesh);
+      iData->_importMeshSubDS = tgtMesh->GetMeshDS()->NewSubMesh( iData->_importMeshSubID );
+    }
+  }
+  //--------------------------------------------------------------------------------
+  /*!
+   * \brief Remove imported mesh and/or groups if needed
+   *  \param sm - submesh loosing Import algo
+   *  \param data - data holding imported groups
+   */
+  void _Listener::removeSubmesh( SMESH_subMesh* sm, _ListenerData* data )
+  {
+    list< _ImportData > &  dList = _tgtMesh2ImportData[ sm->GetFather() ];
+    list< _ImportData >::iterator d = dList.begin();
+    for ( ; d != dList.end(); ++d )
+      if ( (*d)._subM.erase( sm ))
+      {
+        d->_computedSubM.erase( sm );
+        bool rmMesh   = d->_copyMeshSubM.erase( sm ) && d->_copyMeshSubM.empty();
+        bool rmGroups = (d->_copyGroupSubM.erase( sm ) && d->_copyGroupSubM.empty()) || rmMesh;
+        if ( rmMesh )
+          d->removeImportedMesh( sm->GetFather()->GetMeshDS() );
+        if ( rmGroups && data )
+          d->removeGroups( sm, data->_srcHyp );
+      }
+  }
+  //--------------------------------------------------------------------------------
+  /*!
+   * \brief Clear submeshes and remove imported mesh and/or groups if necessary
+   *  \param sm - cleared submesh
+   *  \param data - data holding imported groups
+   */
+  void _Listener::clearSubmesh(SMESH_subMesh* sm, _ListenerData* data, bool clearAllSub)
+  {
+    list< _ImportData > &  dList = _tgtMesh2ImportData[ sm->GetFather() ];
+    list< _ImportData >::iterator d = dList.begin();
+    for ( ; d != dList.end(); ++d )
+    {
+      if ( !d->_subM.count( sm )) continue;
+      if ( (*d)._computedSubM.erase( sm ) )
+      {
+        bool copyMesh = !d->_copyMeshSubM.empty();
+        if ( copyMesh || clearAllSub )
+        {
+          // remove imported mesh and groups
+          d->removeImportedMesh( sm->GetFather()->GetMeshDS() );
+
+          if ( data )
+            d->removeGroups( sm, data->_srcHyp );
+
+          // clear the rest submeshes
+          if ( !d->_computedSubM.empty() )
+          {
+            d->_computedSubM.clear();
+            set< SMESH_subMesh*, _SubLess>::iterator sub = d->_subM.begin();
+            for ( ; sub != d->_subM.end(); ++sub )
+            {
+              SMESH_subMesh* subM = *sub;
+              _ListenerData* hypData = (_ListenerData*) subM->GetEventListenerData( get() );
+              if ( hypData )
+                d->removeGroups( sm, hypData->_srcHyp );
+
+              subM->ComputeStateEngine( SMESH_subMesh::CLEAN );
+              if ( subM->GetSubShape().ShapeType() == TopAbs_FACE )
+                subM->ComputeSubMeshStateEngine( SMESH_subMesh::CLEAN );
+            }
+          }
+        }
+        sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
+        if ( sm->GetSubShape().ShapeType() == TopAbs_FACE )
+          sm->ComputeSubMeshStateEngine( SMESH_subMesh::CLEAN );
+      }
+      if ( data )
+        d->trackHypParams( sm, data->_srcHyp );
+      d->_n2n.clear();
+      d->_e2e.clear();
+    }
+  }
+  //--------------------------------------------------------------------------------
+  /*!
+   * \brief Remove imported mesh and/or groups
+   */
+  void _Listener::ProcessEvent(const int                       event,
+                               const int                       eventType,
+                               SMESH_subMesh*                  subMesh,
+                               SMESH_subMeshEventListenerData* data,
+                               const SMESH_Hypothesis*         /*hyp*/)
+  {
+    if ( data && data->myType == WAIT_HYP_MODIF )
+    {
+      // event of Import submesh
+      if ( SMESH_subMesh::MODIF_HYP  == event &&
+           SMESH_subMesh::ALGO_EVENT == eventType )
+      {
+        // re-call SetEventListener() to take into account valid parameters
+        // of ImportSource hypothesis
+        if ( SMESH_Algo* algo = subMesh->GetAlgo() )
+          algo->SetEventListener( subMesh );
+      }
+    }
+    else if ( data && data->myType == LISTEN_SRC_MESH )
+    {
+      // event of source mesh
+      if ( SMESH_subMesh::COMPUTE_EVENT == eventType )
+      {
+        switch ( event ) {
+        case SMESH_subMesh::CLEAN:
+          // source mesh cleaned -> clean target mesh
+          clearSubmesh( data->mySubMeshes.front(), (_ListenerData*) data, /*all=*/true );
+          break;
+        case SMESH_subMesh::SUBMESH_COMPUTED: {
+          // source mesh computed -> reset FAILED state of Import submeshes to
+          // READY_TO_COMPUTE
+          SMESH_Mesh* srcMesh = subMesh->GetFather();
+          if ( srcMesh->NbEdges() > 0 || srcMesh->NbFaces() > 0 )
+          {
+            SMESH_Mesh* m = data->mySubMeshes.front()->GetFather();
+            if ( SMESH_subMesh* sm1 = m->GetSubMeshContaining(1))
+            {
+              sm1->ComputeStateEngine(SMESH_subMesh::SUBMESH_COMPUTED );
+              sm1->ComputeSubMeshStateEngine( SMESH_subMesh::SUBMESH_COMPUTED );
+            }
+          }
+          break;
+        }
+        default:;
+        }
+      }
+    }
+    else // event of Import submesh
+    {
+      // find out what happens: import hyp modified or removed
+      bool removeImport = false, modifHyp = false;
+      if ( SMESH_subMesh::ALGO_EVENT == eventType )
+        modifHyp = true;
+      if ( subMesh->GetAlgoState() != SMESH_subMesh::HYP_OK )
+      {
+        removeImport = true;
+      }
+      else if (( SMESH_subMesh::REMOVE_ALGO == event ||
+                 SMESH_subMesh::REMOVE_FATHER_ALGO == event ) &&
+               SMESH_subMesh::ALGO_EVENT == eventType )
+      {
+        SMESH_Algo* algo = subMesh->GetAlgo();
+        removeImport = ( strncmp( "Import", algo->GetName(), 6 ) != 0 );
+      }
+
+      if ( removeImport )
+      {
+        // treate removal of Import algo from subMesh
+        removeSubmesh( subMesh, (_ListenerData*) data );
+      }
+      else if ( modifHyp ||
+                ( SMESH_subMesh::CLEAN         == event &&
+                  SMESH_subMesh::COMPUTE_EVENT == eventType))
+      {
+        // treate modification of ImportSource hypothesis
+        clearSubmesh( subMesh, (_ListenerData*) data, /*all=*/false );
+      }
+      else if ( SMESH_subMesh::CHECK_COMPUTE_STATE == event &&
+                SMESH_subMesh::COMPUTE_EVENT       == eventType )
+      {
+        // check compute state of all submeshes impoting from same src mesh;
+        // this is to take into account 1D computed submeshes hidden by 2D import algo;
+        // else source mesh is not copied as _subM.size != _computedSubM.size()
+        list< _ImportData > &  dList = _tgtMesh2ImportData[ subMesh->GetFather() ];
+        list< _ImportData >::iterator d = dList.begin();
+        for ( ; d != dList.end(); ++d )
+          if ( d->_subM.count( subMesh ))
+          {
+            set<SMESH_subMesh*,_SubLess>::iterator smIt = d->_subM.begin();
+            for( ; smIt != d->_subM.end(); ++smIt )
+              if ( (*smIt)->IsMeshComputed() )
+                d->_computedSubM.insert( *smIt);
+          }
+      }
+    }
+  }
+
+  //================================================================================
+  /*!
+   * \brief Return an ID of submesh to store nodes and elements of a copied mesh
+   */
+  //================================================================================
+
+  int getSubmeshIDForCopiedMesh(const SMESHDS_Mesh* srcMeshDS,
+                                SMESH_Mesh*         tgtMesh)
+  {
+    // To get SMESH_subMesh corresponding to srcMeshDS we need to have a shape
+    // for which SMESHDS_Mesh::IsGroupOfSubShapes() returns true.
+    // And this shape must be different from sub-shapes of the main shape.
+    // So we create a compound containing
+    // 1) some sub-shapes of SMESH_Mesh::PseudoShape() corresponding to
+    //    srcMeshDS->GetPersistentId()
+    // 2) the 1-st vertex of the main shape to assure
+    //    SMESHDS_Mesh::IsGroupOfSubShapes(shape)==true
+    TopoDS_Shape shapeForSrcMesh;
+    TopTools_IndexedMapOfShape pseudoSubShapes;
+    TopExp::MapShapes( SMESH_Mesh::PseudoShape(), pseudoSubShapes );
+
+    // index of pseudoSubShapes corresponding to srcMeshDS
+    int subIndex = srcMeshDS->GetPersistentId() % pseudoSubShapes.Extent();
+    int nbSubShapes = 1 + srcMeshDS->GetPersistentId() / pseudoSubShapes.Extent();
+
+    // try to find already present shapeForSrcMesh
+    SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS();
+    for ( int i = tgtMeshDS->MaxShapeIndex(); i > 0 && shapeForSrcMesh.IsNull(); --i )
+    {
+      const TopoDS_Shape& s = tgtMeshDS->IndexToShape(i);
+      if ( s.ShapeType() != TopAbs_COMPOUND ) break;
+      TopoDS_Iterator sSubIt( s );
+      for ( int iSub = 0; iSub < nbSubShapes && sSubIt.More(); ++iSub, sSubIt.Next() )
+        if ( pseudoSubShapes( subIndex+iSub ).IsSame( sSubIt.Value()))
+          if ( iSub+1 == nbSubShapes )
+          {
+            shapeForSrcMesh = s;
+            break;
+          }
+    }
+    if ( shapeForSrcMesh.IsNull() )
+    {
+      // make a new shapeForSrcMesh
+      BRep_Builder aBuilder;
+      TopoDS_Compound comp;
+      aBuilder.MakeCompound( comp );
+      shapeForSrcMesh = comp;
+      for ( int iSub = 0; iSub < nbSubShapes; ++iSub )
+        aBuilder.Add( comp, pseudoSubShapes( subIndex+iSub ));
+      TopExp_Explorer vExp( tgtMeshDS->ShapeToMesh(), TopAbs_VERTEX );
+      aBuilder.Add( comp, vExp.Current() );
+    }
+    SMESH_subMesh* sm = tgtMesh->GetSubMesh( shapeForSrcMesh );
+    SMESHDS_SubMesh* smDS = sm->GetSubMeshDS();
+    if ( !smDS )
+      smDS = tgtMeshDS->NewSubMesh( sm->GetId() );
+
+    // make ordinary submesh from a complex one
+    if ( smDS->IsComplexSubmesh() )
+    {
+      list< const SMESHDS_SubMesh* > subSM;
+      SMESHDS_SubMeshIteratorPtr smIt = smDS->GetSubMeshIterator();
+      while ( smIt->more() ) subSM.push_back( smIt->next() );
+      list< const SMESHDS_SubMesh* >::iterator sub = subSM.begin();
+      for ( ; sub != subSM.end(); ++sub)
+        smDS->RemoveSubMesh( *sub );
+    }
+    return sm->GetId();
+  }
+
+  //================================================================================
+  /*!
+   * \brief Return a submesh to store nodes and elements of a copied mesh
+   * and set event listeners in order to clear
+   * imported mesh and groups as soon as submesh state requires it
+   */
+  //================================================================================
+
+  SMESHDS_SubMesh* getSubmeshForCopiedMesh(const SMESH_Mesh*                    srcMesh,
+                                           SMESH_Mesh*                          tgtMesh,
+                                           const TopoDS_Shape&                  tgtShape,
+                                           StdMeshers_Import_1D::TNodeNodeMap*& n2n,
+                                           StdMeshers_Import_1D::TElemElemMap*& e2e,
+                                           bool &                               toCopyGroups)
+  {
+    StdMeshers_Import_1D::getMaps( srcMesh, tgtMesh, n2n,e2e );
+
+    _ImportData* iData = _Listener::getImportData(srcMesh,tgtMesh);
+
+    SMESH_subMesh* importedSM = tgtMesh->GetSubMesh( tgtShape );
+    iData->addComputed( importedSM );
+    if ( iData->_computedSubM.size() != iData->_subM.size() )
+      return 0; // not all submeshes computed yet
+
+    toCopyGroups = !iData->_copyGroupSubM.empty();
+
+    if ( !iData->_copyMeshSubM.empty())
+    {
+      // make submesh to store a copied mesh
+      int smID = getSubmeshIDForCopiedMesh( srcMesh->GetMeshDS(), tgtMesh );
+      SMESHDS_SubMesh* subDS = tgtMesh->GetMeshDS()->NewSubMesh( smID );
+
+      iData->_importMeshSubID = smID;
+      iData->_importMeshSubDS = subDS;
+      return subDS;
+    }
+    return 0;
+  }
+
+} // namespace
+
+
+//=============================================================================
+/*!
+ * Import elements from the other mesh 
+ */
+//=============================================================================
+
+bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & theShape)
+{
+  if ( !_sourceHyp ) return false;
+
+  const vector<SMESH_Group*>& srcGroups = _sourceHyp->GetGroups();
+  if ( srcGroups.empty() )
+    return error("Invalid source groups");
+
+  SMESH_MesherHelper helper(theMesh);
+  helper.SetSubShape(theShape);
+  SMESHDS_Mesh* tgtMesh = theMesh.GetMeshDS();
+
+  const TopoDS_Edge& geomEdge = TopoDS::Edge( theShape );
+  const double edgeTol = BRep_Tool::Tolerance( geomEdge );
+  const int shapeID = tgtMesh->ShapeToIndex( geomEdge );
+
+  set<int> subShapeIDs;
+  subShapeIDs.insert( shapeID );
+
+  // get nodes on vertices
+  list < SMESH_TNodeXYZ > vertexNodes; 
+ list < SMESH_TNodeXYZ >::iterator vNIt;
+  TopExp_Explorer vExp( theShape, TopAbs_VERTEX );
+  for ( ; vExp.More(); vExp.Next() )
+  {
+    const TopoDS_Vertex& v = TopoDS::Vertex( vExp.Current() );
+    if ( !subShapeIDs.insert( tgtMesh->ShapeToIndex( v )).second )
+      continue; // closed edge
+    const SMDS_MeshNode* n = SMESH_Algo::VertexNode( v, tgtMesh );
+    if ( !n )
+    {
+      _gen->Compute(theMesh,v,/*anUpward=*/true);
+      n = SMESH_Algo::VertexNode( v, tgtMesh );
+      if ( !n ) return false; // very strange
+    }
+    vertexNodes.push_back( SMESH_TNodeXYZ( n ));
+  }
+
+  // import edges from groups
+  TNodeNodeMap* n2n;
+  TElemElemMap* e2e;
+  for ( int iG = 0; iG < srcGroups.size(); ++iG )
+  {
+    const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS();
+
+    const int meshID = srcGroup->GetMesh()->GetPersistentId();
+    const SMESH_Mesh* srcMesh = GetMeshByPersistentID( meshID );
+    if ( !srcMesh ) continue;
+    getMaps( srcMesh, &theMesh, n2n, e2e );
+
+    SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
+    vector<const SMDS_MeshNode*> newNodes;
+    SMDS_MeshNode *tmpNode = helper.AddNode(0,0,0);
+    double u;
+    while ( srcElems->more() ) // loop on group contents
+    {
+      const SMDS_MeshElement* edge = srcElems->next();
+      // find or create nodes of a new edge
+      newNodes.resize( edge->NbNodes() );
+      newNodes.back() = 0;
+      SMDS_MeshElement::iterator node = edge->begin_nodes();
+      for ( unsigned i = 0; i < newNodes.size(); ++i, ++node )
+      {
+        TNodeNodeMap::iterator n2nIt = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )).first;
+        if ( n2nIt->second )
+        {
+          if ( !subShapeIDs.count( n2nIt->second->getshapeId() ))
+            break;
+        }
+        else
+        {
+          // find an existing vertex node
+          for ( vNIt = vertexNodes.begin(); vNIt != vertexNodes.end(); ++vNIt)
+            if ( vNIt->SquareDistance( *node ) < 10 * edgeTol * edgeTol)
+            {
+              (*n2nIt).second = vNIt->_node;
+              vertexNodes.erase( vNIt );
+              break;
+            }
+        }
+        if ( !n2nIt->second )
+        {
+          // find out if node lies on theShape
+          tmpNode->setXYZ( (*node)->X(), (*node)->Y(), (*node)->Z());
+          if ( helper.CheckNodeU( geomEdge, tmpNode, u, 10 * edgeTol, /*force=*/true ))
+          {
+            SMDS_MeshNode* newNode = tgtMesh->AddNode( (*node)->X(), (*node)->Y(), (*node)->Z());
+            n2nIt->second = newNode;
+            tgtMesh->SetNodeOnEdge( newNode, shapeID, u );
+          }
+        }
+        if ( !(newNodes[i] = n2nIt->second ))
+          break;
+      }
+      if ( !newNodes.back() )
+        continue; // not all nodes of edge lie on theShape
+
+      // make a new edge
+      SMDS_MeshElement * newEdge;
+      if ( newNodes.size() == 3 )
+        newEdge = tgtMesh->AddEdge( newNodes[0], newNodes[1], newNodes[2] );
+      else
+        newEdge = tgtMesh->AddEdge( newNodes[0], newNodes[1]);
+      tgtMesh->SetMeshElementOnShape( newEdge, shapeID );
+      e2e->insert( make_pair( edge, newEdge ));
+    }
+    helper.GetMeshDS()->RemoveNode(tmpNode);
+  }
+  if ( n2n->empty())
+    return error("Empty source groups");
+
+  // check if the whole geom edge is covered by imported segments;
+  // the check consist in passing by segments from one vetrex node to another
+  bool isEdgeMeshed = false;
+  if ( SMESHDS_SubMesh* tgtSM = tgtMesh->MeshElements( theShape ))
+  {
+    const TopoDS_Vertex& v = ( vExp.ReInit(), TopoDS::Vertex( vExp.Current() ));
+    const SMDS_MeshNode* n = SMESH_Algo::VertexNode( v, tgtMesh );
+    const SMDS_MeshElement* seg = 0;
+    SMDS_ElemIteratorPtr segIt = n->GetInverseElementIterator(SMDSAbs_Edge);
+    while ( segIt->more() && !seg )
+      if ( !tgtSM->Contains( seg = segIt->next()))
+        seg = 0;
+    int nbPassedSegs = 0;
+    while ( seg )
+    {
+      ++nbPassedSegs;
+      const SMDS_MeshNode* n2 = seg->GetNode(0);
+      n = ( n2 == n ? seg->GetNode(1) : n2 );
+      if ( n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX )
+        break;
+      const SMDS_MeshElement* seg2 = 0;
+      segIt = n->GetInverseElementIterator(SMDSAbs_Edge);
+      while ( segIt->more() && !seg2 )
+        if ( seg == ( seg2 = segIt->next()))
+          seg2 = 0;
+      seg = seg2;
+    }
+    if (nbPassedSegs > 0 && tgtSM->NbElements() > nbPassedSegs )
+      return error( "Source elements overlap one another");
+
+    isEdgeMeshed = ( tgtSM->NbElements() == nbPassedSegs &&
+                     n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX );
+  }
+  if ( !isEdgeMeshed )
+    return error( "Source elements don't cover totally the geometrical edge" );
+
+  // copy meshes
+  vector<SMESH_Mesh*> srcMeshes = _sourceHyp->GetSourceMeshes();
+  for ( unsigned i = 0; i < srcMeshes.size(); ++i )
+    importMesh( srcMeshes[i], theMesh, _sourceHyp, theShape );
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Copy mesh and groups
+ */
+//================================================================================
+
+void StdMeshers_Import_1D::importMesh(const SMESH_Mesh*          srcMesh,
+                                      SMESH_Mesh &               tgtMesh,
+                                      StdMeshers_ImportSource1D* srcHyp,
+                                      const TopoDS_Shape&        tgtShape)
+{
+  // get submesh to store the imported mesh
+  TNodeNodeMap* n2n;
+  TElemElemMap* e2e;
+  bool toCopyGroups;
+  SMESHDS_SubMesh* tgtSubMesh =
+    getSubmeshForCopiedMesh( srcMesh, &tgtMesh, tgtShape, n2n, e2e, toCopyGroups );
+  if ( !tgtSubMesh || tgtSubMesh->NbNodes() + tgtSubMesh->NbElements() > 0 )
+    return; // not to copy srcMeshDS twice
+
+  SMESHDS_Mesh* tgtMeshDS = tgtMesh.GetMeshDS();
+  SMESH_MeshEditor additor( &tgtMesh );
+
+  // 1. Copy mesh
+
+  vector<const SMDS_MeshNode*> newNodes;
+  const SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
+  SMDS_ElemIteratorPtr eIt = srcMeshDS->elementsIterator();
+  while ( eIt->more() )
+  {
+    const SMDS_MeshElement* elem = eIt->next();
+    TElemElemMap::iterator e2eIt = e2e->insert( make_pair( elem, (SMDS_MeshElement*)0 )).first;
+    if ( e2eIt->second ) continue; // already copied by Compute()
+    newNodes.resize( elem->NbNodes() );
+    SMDS_MeshElement::iterator node = elem->begin_nodes();
+    for ( unsigned i = 0; i < newNodes.size(); ++i, ++node )
+    {
+      TNodeNodeMap::iterator n2nIt = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )).first;
+      if ( !n2nIt->second )
+      {
+        (*n2nIt).second = tgtMeshDS->AddNode( (*node)->X(), (*node)->Y(), (*node)->Z());
+        tgtSubMesh->AddNode( n2nIt->second );
+      }
+      newNodes[i] = n2nIt->second;
+    }
+    const SMDS_MeshElement* newElem =
+      tgtMeshDS->FindElement( newNodes, elem->GetType(), /*noMedium=*/false );
+    if ( !newElem )
+    {
+      newElem = additor.AddElement( newNodes, elem->GetType(), elem->IsPoly());
+      tgtSubMesh->AddElement( newElem );
+    }
+    if ( toCopyGroups )
+      (*e2eIt).second = newElem;
+  }
+  // copy free nodes
+  if ( srcMeshDS->NbNodes() > n2n->size() )
+  {
+    SMDS_NodeIteratorPtr nIt = srcMeshDS->nodesIterator();
+    while( nIt->more() )
+    {
+      const SMDS_MeshNode* node = nIt->next();
+      if ( node->NbInverseElements() == 0 )
+      {
+        const SMDS_MeshNode* newNode = tgtMeshDS->AddNode( node->X(), node->Y(), node->Z());
+        n2n->insert( make_pair( node, newNode ));
+        tgtSubMesh->AddNode( newNode );
+      }
+    }
+  }
+
+  // 2. Copy groups
+
+  vector<SMESH_Group*> resultGroups;
+  if ( toCopyGroups )
+  {
+    // collect names of existing groups to assure uniqueness of group names within a type
+    map< SMDSAbs_ElementType, set<string> > namesByType;
+    SMESH_Mesh::GroupIteratorPtr groupIt = tgtMesh.GetGroups();
+    while ( groupIt->more() )
+    {
+      SMESH_Group* tgtGroup = groupIt->next();
+      namesByType[ tgtGroup->GetGroupDS()->GetType() ].insert( tgtGroup->GetName() );
+    }
+    if (srcMesh)
+    {
+      SMESH_Mesh::GroupIteratorPtr groupIt = srcMesh->GetGroups();
+      while ( groupIt->more() )
+      {
+        SMESH_Group* srcGroup = groupIt->next();
+        SMESHDS_GroupBase* srcGroupDS = srcGroup->GetGroupDS();
+        string name = srcGroup->GetName();
+        int nb = 1;
+        while ( !namesByType[ srcGroupDS->GetType() ].insert( name ).second )
+          name = SMESH_Comment(srcGroup->GetName()) << "_imported_" << nb++;
+        SMESH_Group* newGroup = tgtMesh.AddGroup( srcGroupDS->GetType(), name.c_str(), nb );
+        SMESHDS_Group* newGroupDS = (SMESHDS_Group*)newGroup->GetGroupDS();
+        resultGroups.push_back( newGroup );
+
+        eIt = srcGroupDS->GetElements();
+        if ( srcGroupDS->GetType() == SMDSAbs_Node )
+          while (eIt->more())
+          {
+            TNodeNodeMap::iterator n2nIt = n2n->find((const SMDS_MeshNode*) eIt->next() );
+            if ( n2nIt != n2n->end() && n2nIt->second )
+              newGroupDS->SMDSGroup().Add((*n2nIt).second );
+          }
+        else
+          while (eIt->more())
+          {
+            TElemElemMap::iterator e2eIt = e2e->find( eIt->next() );
+            if ( e2eIt != e2e->end() && e2eIt->second )
+              newGroupDS->SMDSGroup().Add((*e2eIt).second );
+          }
+      }
+    }
+  }
+  n2n->clear();
+  e2e->clear();
+
+  // Remember created groups in order to remove them as soon as the srcHyp is
+  // modified or something other similar happens. This imformation must be persistent,
+  // for that store them in a hypothesis as it stores its values in the file anyway
+  srcHyp->StoreResultGroups( resultGroups, *srcMeshDS, *tgtMeshDS );
+}
+
+//=============================================================================
+/*!
+ * \brief Set needed event listeners and create a submesh for a copied mesh
+ *
+ * This method is called only if a submesh has HYP_OK algo_state.
+ */
+//=============================================================================
+
+void StdMeshers_Import_1D::setEventListener(SMESH_subMesh*             subMesh, 
+                                            StdMeshers_ImportSource1D* sourceHyp)
+{
+  if ( sourceHyp )
+  {
+    vector<SMESH_Mesh*> srcMeshes = sourceHyp->GetSourceMeshes();
+    if ( srcMeshes.empty() )
+      _Listener::waitHypModification( subMesh );
+    for ( unsigned i = 0; i < srcMeshes.size(); ++i )
+      // set a listener to remove the imported mesh and groups
+      _Listener::storeImportSubmesh( subMesh, srcMeshes[i], sourceHyp );
+  }
+}
+void StdMeshers_Import_1D::SetEventListener(SMESH_subMesh* subMesh)
+{
+  if ( !_sourceHyp )
+  {
+    const TopoDS_Shape& tgtShape = subMesh->GetSubShape();
+    SMESH_Mesh*         tgtMesh  = subMesh->GetFather();
+    Hypothesis_Status aStatus;
+    CheckHypothesis( *tgtMesh, tgtShape, aStatus );
+  }
+  setEventListener( subMesh, _sourceHyp );
+}
+
+void StdMeshers_Import_1D::SubmeshRestored(SMESH_subMesh* subMesh)
+{
+  SetEventListener(subMesh);
+}
+
+//=============================================================================
+/*!
+ * Predict nb of mesh entities created by Compute()
+ */
+//=============================================================================
+
+bool StdMeshers_Import_1D::Evaluate(SMESH_Mesh &         theMesh,
+                                    const TopoDS_Shape & theShape,
+                                    MapShapeNbElems&     aResMap)
+{
+  if ( !_sourceHyp ) return false;
+
+  const vector<SMESH_Group*>& srcGroups = _sourceHyp->GetGroups();
+  if ( srcGroups.empty() )
+    return error("Invalid source groups");
+
+  vector<int> aVec(SMDSEntity_Last,0);
+
+  bool toCopyMesh, toCopyGroups;
+  _sourceHyp->GetCopySourceMesh(toCopyMesh, toCopyGroups);
+  if ( toCopyMesh ) // the whole mesh is copied
+  {
+    vector<SMESH_Mesh*> srcMeshes = _sourceHyp->GetSourceMeshes();
+    for ( unsigned i = 0; i < srcMeshes.size(); ++i )
+    {
+      SMESH_subMesh* sm = getSubMeshOfCopiedMesh( theMesh, *srcMeshes[i]);
+      if ( !sm || aResMap.count( sm )) continue; // already counted
+      aVec.assign( SMDSEntity_Last, 0);
+      const SMDS_MeshInfo& aMeshInfo = srcMeshes[i]->GetMeshDS()->GetMeshInfo();
+      for (int i = 0; i < SMDSEntity_Last; i++)
+        aVec[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
+    }
+  }
+  else
+  {
+    SMESH_MesherHelper helper(theMesh);
+
+    const TopoDS_Edge& geomEdge = TopoDS::Edge( theShape );
+    const double edgeTol = helper.MaxTolerance( geomEdge );
+
+    // take into account nodes on vertices
+    TopExp_Explorer vExp( theShape, TopAbs_VERTEX );
+    for ( ; vExp.More(); vExp.Next() )
+      theMesh.GetSubMesh( vExp.Current())->Evaluate( aResMap );
+
+    // count edges imported from groups
+    int nbEdges = 0, nbQuadEdges = 0;
+    for ( int iG = 0; iG < srcGroups.size(); ++iG )
+    {
+      const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS();
+      SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
+      SMDS_MeshNode *tmpNode = helper.AddNode(0,0,0);
+      while ( srcElems->more() ) // loop on group contents
+      {
+        const SMDS_MeshElement* edge = srcElems->next();
+        // find out if edge is located on geomEdge by projecting
+        // a middle of edge to geomEdge
+        SMESH_TNodeXYZ p1( edge->GetNode(0));
+        SMESH_TNodeXYZ p2( edge->GetNode(1));
+        gp_XYZ middle = ( p1 + p2 ) / 2.;
+        tmpNode->setXYZ( middle.X(), middle.Y(), middle.Z());
+        double u = 0;
+        if ( helper.CheckNodeU( geomEdge, tmpNode, u, 10 * edgeTol, /*force=*/true ))
+          ++( edge->IsQuadratic() ? nbQuadEdges : nbEdges);
+      }
+      helper.GetMeshDS()->RemoveNode(tmpNode);
+    }
+
+    int nbNodes = nbEdges + 2 * nbQuadEdges - 1;
+
+    aVec[SMDSEntity_Node     ] = nbNodes;
+    aVec[SMDSEntity_Edge     ] = nbEdges;
+    aVec[SMDSEntity_Quad_Edge] = nbQuadEdges;
+  }
+
+  SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
+  aResMap.insert(make_pair(sm,aVec));
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Return node-node and element-element maps for import of geiven source mesh
+ */
+//================================================================================
+
+void StdMeshers_Import_1D::getMaps(const SMESH_Mesh* srcMesh,
+                                   SMESH_Mesh*       tgtMesh,
+                                   TNodeNodeMap*&    n2n,
+                                   TElemElemMap*&    e2e)
+{
+  _ImportData* iData = _Listener::getImportData(srcMesh,tgtMesh);
+  n2n = &iData->_n2n;
+  e2e = &iData->_e2e;
+  if ( iData->_copyMeshSubM.empty() )
+  {
+    n2n->clear();
+    e2e->clear();
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Return submesh corresponding to the copied mesh
+ */
+//================================================================================
+
+SMESH_subMesh* StdMeshers_Import_1D::getSubMeshOfCopiedMesh( SMESH_Mesh& tgtMesh,
+                                                             SMESH_Mesh& srcMesh )
+{
+  _ImportData* iData = _Listener::getImportData(&srcMesh,&tgtMesh);
+  if ( iData->_copyMeshSubM.empty() ) return 0;
+  SMESH_subMesh* sm = tgtMesh.GetSubMeshContaining( iData->_importMeshSubID );
+  return sm;
+}
+
diff --git a/src/StdMeshers/StdMeshers_Import_1D.hxx b/src/StdMeshers/StdMeshers_Import_1D.hxx
new file mode 100644 (file)
index 0000000..b71b905
--- /dev/null
@@ -0,0 +1,81 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+//  Module : SMESH
+//
+#ifndef _SMESH_Import_1D_HXX_
+#define _SMESH_Import_1D_HXX_
+
+#include "SMESH_StdMeshers.hxx"
+
+#include "SMESH_1D_Algo.hxx"
+#include "SMDS_MeshElement.hxx"
+
+class StdMeshers_ImportSource1D;
+
+/*!
+ * \brief Copy elements from other the mesh
+ */
+class STDMESHERS_EXPORT StdMeshers_Import_1D: public SMESH_1D_Algo
+{
+public:
+  StdMeshers_Import_1D(int hypId, int studyId, SMESH_Gen* gen);
+
+  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);
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
+
+  virtual void SetEventListener(SMESH_subMesh* subMesh);
+  virtual void SubmeshRestored(SMESH_subMesh* subMesh);
+
+  // internal utilities
+
+  typedef std::map<const SMDS_MeshNode*,   const SMDS_MeshNode*,   TIDCompare> TNodeNodeMap;
+  typedef std::map<const SMDS_MeshElement*,const SMDS_MeshElement*,TIDCompare> TElemElemMap;
+
+  static void getMaps(const SMESH_Mesh* srcMesh,
+                      SMESH_Mesh*       tgtMesh,
+                      TNodeNodeMap*&    n2n,
+                      TElemElemMap*&    e2e);
+
+  static void importMesh(const SMESH_Mesh*          srcMesh,
+                         SMESH_Mesh &               tgtMesh,
+                         StdMeshers_ImportSource1D* srcHyp,
+                         const TopoDS_Shape&        tgtShape);
+
+  static void setEventListener( SMESH_subMesh*             subMesh,
+                                StdMeshers_ImportSource1D* sourceHyp );
+
+  static SMESH_subMesh* getSubMeshOfCopiedMesh( SMESH_Mesh& tgtMesh,
+                                                SMESH_Mesh& srcMesh );
+
+ private:
+  
+  StdMeshers_ImportSource1D* _sourceHyp;
+};
+
+#endif
diff --git a/src/StdMeshers/StdMeshers_Import_1D2D.cxx b/src/StdMeshers/StdMeshers_Import_1D2D.cxx
new file mode 100644 (file)
index 0000000..8180f0a
--- /dev/null
@@ -0,0 +1,778 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+//  File   : StdMeshers_Import_1D2D.cxx
+//  Module : SMESH
+//
+#include "StdMeshers_Import_1D2D.hxx"
+
+#include "StdMeshers_Import_1D.hxx"
+#include "StdMeshers_ImportSource.hxx"
+
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMESHDS_Group.hxx"
+#include "SMESHDS_Mesh.hxx"
+#include "SMESH_Comment.hxx"
+#include "SMESH_Gen.hxx"
+#include "SMESH_Group.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_MesherHelper.hxx"
+#include "SMESH_subMesh.hxx"
+
+#include "Utils_SALOME_Exception.hxx"
+#include "utilities.h"
+
+#include <BRep_Builder.hxx>
+#include <BRep_Tool.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Compound.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <Precision.hxx>
+
+#include <numeric>
+
+using namespace std;
+
+namespace
+{
+  double getMinElemSize2( const SMESHDS_GroupBase* srcGroup )
+  {
+    double minSize2 = 1e100;
+    SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
+    while ( srcElems->more() ) // loop on group contents
+    {
+      const SMDS_MeshElement* face = srcElems->next();
+      int nbN = face->NbCornerNodes();
+
+      SMESH_TNodeXYZ prevN( face->GetNode( nbN-1 ));
+      for ( int i = 0; i < nbN; ++i )
+      {
+        SMESH_TNodeXYZ n( face->GetNode( i ) );
+        double size2 = ( n - prevN ).SquareModulus();
+        minSize2 = std::min( minSize2, size2 );
+        prevN = n;
+      }
+    }
+    return minSize2;
+  }
+}
+
+//=============================================================================
+/*!
+ * Creates StdMeshers_Import_1D2D
+ */
+//=============================================================================
+
+StdMeshers_Import_1D2D::StdMeshers_Import_1D2D(int hypId, int studyId, SMESH_Gen * gen)
+  :SMESH_2D_Algo(hypId, studyId, gen), _sourceHyp(0)
+{
+  MESSAGE("StdMeshers_Import_1D2D::StdMeshers_Import_1D2D");
+  _name = "Import_1D2D";
+  _shapeType = (1 << TopAbs_FACE);
+
+  _compatibleHypothesis.push_back("ImportSource2D");
+  _requireDiscreteBoundary = false;
+}
+
+//=============================================================================
+/*!
+ * Check presence of a hypothesis
+ */
+//=============================================================================
+
+bool StdMeshers_Import_1D2D::CheckHypothesis
+                         (SMESH_Mesh&                          aMesh,
+                          const TopoDS_Shape&                  aShape,
+                          SMESH_Hypothesis::Hypothesis_Status& aStatus)
+{
+  _sourceHyp = 0;
+
+  const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
+  if ( hyps.size() == 0 )
+  {
+    aStatus = SMESH_Hypothesis::HYP_MISSING;
+    return false;  // can't work with no hypothesis
+  }
+
+  if ( hyps.size() > 1 )
+  {
+    aStatus = SMESH_Hypothesis::HYP_ALREADY_EXIST;
+    return false;
+  }
+
+  const SMESHDS_Hypothesis *theHyp = hyps.front();
+
+  string hypName = theHyp->GetName();
+
+  if (hypName == _compatibleHypothesis.front())
+  {
+    _sourceHyp = (StdMeshers_ImportSource1D *)theHyp;
+    aStatus = SMESH_Hypothesis::HYP_OK;
+    return true;
+  }
+
+  aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
+  return true;
+}
+
+namespace
+{
+  /*!
+   * \brief OrientedLink additionally storing a medium node
+   */
+  struct TLink : public SMESH_OrientedLink
+  {
+    const SMDS_MeshNode* _medium;
+    TLink( const SMDS_MeshNode* n1,
+           const SMDS_MeshNode* n2,
+           const SMDS_MeshNode* medium=0)
+      : SMESH_OrientedLink( n1,n2 ), _medium( medium ) {}
+  };
+}
+
+//=============================================================================
+/*!
+ * Import elements from the other mesh 
+ */
+//=============================================================================
+
+bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & theShape)
+{
+  if ( !_sourceHyp ) return false;
+
+  const vector<SMESH_Group*>& srcGroups = _sourceHyp->GetGroups();
+  if ( srcGroups.empty() )
+    return error("Invalid source groups");
+
+  bool allGroupsEmpty = true;
+  for ( size_t iG = 0; iG < srcGroups.size() && allGroupsEmpty; ++iG )
+    allGroupsEmpty = srcGroups[iG]->GetGroupDS()->IsEmpty();
+  if ( allGroupsEmpty )
+    return error("No faces in source groups");
+
+  SMESH_MesherHelper helper(theMesh);
+  helper.SetSubShape(theShape);
+  SMESHDS_Mesh* tgtMesh = theMesh.GetMeshDS();
+
+  const TopoDS_Face& geomFace = TopoDS::Face( theShape );
+  const double faceTol = helper.MaxTolerance( geomFace );
+  const int shapeID = tgtMesh->ShapeToIndex( geomFace );
+  const bool toCheckOri = (helper.NbAncestors( geomFace, theMesh, TopAbs_SOLID ) == 1 );
+
+  Handle(Geom_Surface) surface = BRep_Tool::Surface( geomFace );
+  const bool reverse = 
+    ( helper.GetSubShapeOri( tgtMesh->ShapeToMesh(), geomFace) == TopAbs_REVERSED );
+  gp_Pnt p; gp_Vec du, dv;
+
+  set<int> subShapeIDs;
+  subShapeIDs.insert( shapeID );
+
+  // get nodes on vertices
+  list < SMESH_TNodeXYZ > vertexNodes;
+  list < SMESH_TNodeXYZ >::iterator vNIt;
+  TopExp_Explorer exp( theShape, TopAbs_VERTEX );
+  for ( ; exp.More(); exp.Next() )
+  {
+    const TopoDS_Vertex& v = TopoDS::Vertex( exp.Current() );
+    if ( !subShapeIDs.insert( tgtMesh->ShapeToIndex( v )).second )
+      continue;
+    const SMDS_MeshNode* n = SMESH_Algo::VertexNode( v, tgtMesh );
+    if ( !n )
+    {
+      _gen->Compute(theMesh,v,/*anUpward=*/true);
+      n = SMESH_Algo::VertexNode( v, tgtMesh );
+      if ( !n ) return false; // very strange
+    }
+    vertexNodes.push_back( SMESH_TNodeXYZ( n ));
+  }
+
+  // to count now many times a link between nodes encounters
+  map<TLink, int> linkCount;
+  map<TLink, int>::iterator link2Nb;
+  double minGroupTol = Precision::Infinite();
+
+  // =========================
+  // Import faces from groups
+  // =========================
+
+  StdMeshers_Import_1D::TNodeNodeMap* n2n;
+  StdMeshers_Import_1D::TElemElemMap* e2e;
+  vector<const SMDS_MeshNode*> newNodes;
+  for ( size_t iG = 0; iG < srcGroups.size(); ++iG )
+  {
+    const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS();
+
+    const int meshID = srcGroup->GetMesh()->GetPersistentId();
+    const SMESH_Mesh* srcMesh = GetMeshByPersistentID( meshID );
+    if ( !srcMesh ) continue;
+    StdMeshers_Import_1D::getMaps( srcMesh, &theMesh, n2n, e2e );
+
+    const double groupTol = 0.5 * sqrt( getMinElemSize2( srcGroup ));
+    minGroupTol = std::min( groupTol, minGroupTol );
+
+    SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
+    SMDS_MeshNode *tmpNode = helper.AddNode(0,0,0);
+    gp_XY uv( Precision::Infinite(), Precision::Infinite() );
+    while ( srcElems->more() ) // loop on group contents
+    {
+      const SMDS_MeshElement* face = srcElems->next();
+      // find or create nodes of a new face
+      newNodes.resize( face->NbNodes() );
+      newNodes.back() = 0;
+      int nbCreatedNodes = 0;
+      SMDS_MeshElement::iterator node = face->begin_nodes();
+      for ( size_t i = 0; i < newNodes.size(); ++i, ++node )
+      {
+        StdMeshers_Import_1D::TNodeNodeMap::iterator n2nIt = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )).first;
+        if ( n2nIt->second )
+        {
+          if ( !subShapeIDs.count( n2nIt->second->getshapeId() ))
+            break;
+        }
+        else
+        {
+          // find an existing vertex node
+          for ( vNIt = vertexNodes.begin(); vNIt != vertexNodes.end(); ++vNIt)
+            if ( vNIt->SquareDistance( *node ) < groupTol * groupTol)
+            {
+              (*n2nIt).second = vNIt->_node;
+              vertexNodes.erase( vNIt );
+              break;
+            }
+        }
+        if ( !n2nIt->second )
+        {
+          // find out if node lies on theShape
+          tmpNode->setXYZ( (*node)->X(), (*node)->Y(), (*node)->Z());
+          uv.SetCoord( Precision::Infinite(), Precision::Infinite() );
+          if ( helper.CheckNodeUV( geomFace, tmpNode, uv, groupTol, /*force=*/true ))
+          {
+            SMDS_MeshNode* newNode = tgtMesh->AddNode( (*node)->X(), (*node)->Y(), (*node)->Z());
+            n2nIt->second = newNode;
+            tgtMesh->SetNodeOnFace( newNode, shapeID, uv.X(), uv.Y() );
+            nbCreatedNodes++;
+          }
+        }
+        if ( !(newNodes[i] = n2nIt->second ))
+          break;
+      }
+      if ( !newNodes.back() )
+        continue; // not all nodes of the face lie on theShape
+
+      // try to find already created face
+      SMDS_MeshElement * newFace = 0;
+      if ( nbCreatedNodes == 0 &&
+           tgtMesh->FindElement(newNodes, SMDSAbs_Face, /*noMedium=*/false))
+        continue; // repeated face in source groups already created 
+
+      // check future face orientation
+      if ( toCheckOri )
+      {
+        int iNode = -1;
+        gp_Vec geomNorm;
+        do
+        {
+          uv = helper.GetNodeUV( geomFace, newNodes[++iNode] );
+          surface->D1( uv.X(),uv.Y(), p, du,dv );
+          geomNorm = reverse ? dv^du : du^dv;
+        }
+        while ( geomNorm.SquareMagnitude() < 1e-6 && iNode+1 < face->NbCornerNodes());
+
+        int iNext = helper.WrapIndex( iNode+1, face->NbCornerNodes() );
+        int iPrev = helper.WrapIndex( iNode-1, face->NbCornerNodes() );
+
+        SMESH_TNodeXYZ prevNode( newNodes[iPrev] );
+        SMESH_TNodeXYZ curNode ( newNodes[iNode] );
+        SMESH_TNodeXYZ nextNode( newNodes[iNext] );
+        gp_Vec n1n0( prevNode - curNode);
+        gp_Vec n1n2( nextNode - curNode );
+        gp_Vec meshNorm = n1n2 ^ n1n0;
+
+        if ( geomNorm * meshNorm < 0 )
+          std::reverse( newNodes.begin(), newNodes.end() );
+      }
+
+      // make a new face
+      switch ( newNodes.size() )
+      {
+      case 3:
+        newFace = tgtMesh->AddFace( newNodes[0], newNodes[1], newNodes[2] );
+        break;
+      case 4:
+        newFace = tgtMesh->AddFace( newNodes[0], newNodes[1], newNodes[2], newNodes[3] );
+        break;
+      case 6:
+        newFace = tgtMesh->AddFace( newNodes[0], newNodes[1], newNodes[2],
+                                    newNodes[3], newNodes[4], newNodes[5]);
+        break;
+      case 8:
+        newFace = tgtMesh->AddFace( newNodes[0], newNodes[1], newNodes[2], newNodes[3],
+                                    newNodes[4], newNodes[5], newNodes[6], newNodes[7]);
+        break;
+      default: continue;
+      }
+      tgtMesh->SetMeshElementOnShape( newFace, shapeID );
+      e2e->insert( make_pair( face, newFace ));
+
+      // collect links
+      int nbNodes = face->NbCornerNodes();
+      const SMDS_MeshNode* medium = 0;
+      for ( int i = 0; i < nbNodes; ++i )
+      {
+        const SMDS_MeshNode* n1 = newNodes[i];
+        const SMDS_MeshNode* n2 = newNodes[ (i+1)%nbNodes ];
+        if ( newFace->IsQuadratic() )
+          medium = newNodes[i+nbNodes];
+        link2Nb = linkCount.insert( make_pair( TLink( n1, n2, medium ), 0)).first;
+        ++link2Nb->second;
+        // if ( link2Nb->second == 1 )
+        // {
+        //   // measure link length
+        //   double len2 = SMESH_TNodeXYZ( n1 ).SquareDistance( n2 );
+        //   if ( len2 < minGroupTol )
+        //     minGroupTol = len2;
+        // }
+      }
+    }
+    helper.GetMeshDS()->RemoveNode(tmpNode);
+  }
+
+  // ==========================================================
+  // Put nodes on geom edges and create edges on them;
+  // check if the whole geom face is covered by imported faces
+  // ==========================================================
+
+  vector< TopoDS_Edge > edges;
+  for ( exp.Init( theShape, TopAbs_EDGE ); exp.More(); exp.Next() )
+    if ( subShapeIDs.insert( tgtMesh->ShapeToIndex( exp.Current() )).second )
+      edges.push_back( TopoDS::Edge( exp.Current() ));
+
+  // use large tolerance for projection of nodes to edges because of
+  // BLSURF mesher specifics (issue 0020918, Study2.hdf)
+  const double projTol = minGroupTol;
+
+  bool isFaceMeshed = false;
+  SMESHDS_SubMesh* tgtFaceSM = tgtMesh->MeshElements( theShape );
+  if ( tgtFaceSM )
+  {
+    // the imported mesh is valid if all external links (encountered once)
+    // lie on geom edges
+    subShapeIDs.erase( shapeID ); // to contain edges and vertices only
+    double u, f, l;
+    for ( link2Nb = linkCount.begin(); link2Nb != linkCount.end(); ++link2Nb)
+    {
+      const TLink& link = (*link2Nb).first;
+      int nbFaces = link2Nb->second;
+      if ( nbFaces == 1 )
+      {
+        // check if a not shared link lies on face boundary
+        bool nodesOnBoundary = true;
+        list< TopoDS_Shape > bndShapes;
+        for ( int is1stN = 0; is1stN < 2 && nodesOnBoundary; ++is1stN )
+        {
+          const SMDS_MeshNode* n = is1stN ? link.node1() : link.node2();
+          if ( !subShapeIDs.count( n->getshapeId() ))
+          {
+            for ( size_t iE = 0; iE < edges.size(); ++iE )
+              if ( helper.CheckNodeU( edges[iE], n, u=0, projTol, /*force=*/true ))
+              {
+                BRep_Tool::Range(edges[iE],f,l);
+                if ( Abs(u-f) < 2 * faceTol || Abs(u-l) < 2 * faceTol )
+                  // duplicated node on vertex
+                  return error("Source elements overlap one another");
+                tgtFaceSM->RemoveNode( n, /*isNodeDeleted=*/false );
+                tgtMesh->SetNodeOnEdge( (SMDS_MeshNode*)n, edges[iE], u );
+                break;
+              }
+            nodesOnBoundary = subShapeIDs.count( n->getshapeId());
+          }
+          if ( nodesOnBoundary )
+          {
+            TopoDS_Shape s = helper.GetSubShapeByNode( n, tgtMesh );
+            if ( s.ShapeType() == TopAbs_VERTEX )
+              bndShapes.push_front( s ); // vertex first
+            else
+              bndShapes.push_back( s ); // edges last
+          }
+        }
+        if ( !nodesOnBoundary )
+        {
+          error("free internal link"); // just for an easier debug
+          break;
+        }
+        if ( bndShapes.front().ShapeType() == TopAbs_EDGE &&
+             bndShapes.front() != bndShapes.back() )
+          // link nodes on different geom edges
+          return error(COMPERR_BAD_INPUT_MESH, "Source nodes mismatch target vertices");
+
+        // find geom edge the link is on
+        if ( bndShapes.back().ShapeType() != TopAbs_EDGE )
+        {
+          // find geom edge by two vertices
+          TopoDS_Shape geomEdge = helper.GetCommonAncestor( bndShapes.back(),
+                                                            bndShapes.front(),
+                                                            theMesh, TopAbs_EDGE );
+          if ( geomEdge.IsNull() )
+          {
+            error("free internal link");
+            break; // vertices belong to different edges
+          }
+          bndShapes.push_back( geomEdge );
+        }
+
+        // create an edge if not yet exists
+        newNodes.resize(2);
+        newNodes[0] = link.node1(), newNodes[1] = link.node2();
+        const SMDS_MeshElement* edge = tgtMesh->FindElement( newNodes, SMDSAbs_Edge );
+        if ( edge ) continue;
+
+        if ( link._reversed ) std::swap( newNodes[0], newNodes[1] );
+        if ( link._medium )
+        {
+          newNodes.push_back( link._medium );
+          edge = tgtMesh->AddEdge( newNodes[0], newNodes[1], newNodes[2] );
+
+          TopoDS_Edge geomEdge = TopoDS::Edge(bndShapes.back());
+          helper.CheckNodeU( geomEdge, link._medium, u, projTol, /*force=*/true );
+          tgtFaceSM->RemoveNode( link._medium, /*isNodeDeleted=*/false );
+          tgtMesh->SetNodeOnEdge( (SMDS_MeshNode*)link._medium, geomEdge, u );
+        }
+        else
+        {
+          edge = tgtMesh->AddEdge( newNodes[0], newNodes[1]);
+        }
+        if ( !edge )
+          return false;
+
+        tgtMesh->SetMeshElementOnShape( edge, bndShapes.back() );
+      }
+      else if ( nbFaces > 2 )
+      {
+        return error( COMPERR_BAD_INPUT_MESH, "Non-manifold source mesh");
+      }
+    }
+    isFaceMeshed = ( link2Nb == linkCount.end() && !linkCount.empty());
+    if ( isFaceMeshed )
+    {
+      // check that source faces do not overlap:
+      // there must be only two edges sharing each vertex and bound to sub-edges of theShape
+      SMESH_MeshEditor editor( &theMesh );
+      set<int>::iterator subID = subShapeIDs.begin();
+      for ( ; subID != subShapeIDs.end(); ++subID )
+      {
+        const TopoDS_Shape& s = tgtMesh->IndexToShape( *subID );
+        if ( s.ShapeType() != TopAbs_VERTEX ) continue;
+        const SMDS_MeshNode* n = SMESH_Algo::VertexNode( TopoDS::Vertex(s), tgtMesh );
+        SMDS_ElemIteratorPtr eIt = n->GetInverseElementIterator(SMDSAbs_Edge);
+        int nbEdges = 0;
+        while ( eIt->more() )
+        {
+          const SMDS_MeshElement* edge = eIt->next();
+          int sId = editor.FindShape( edge );
+          nbEdges += subShapeIDs.count( sId );
+        }
+        if ( nbEdges < 2 )
+          return false; // weird
+        if ( nbEdges > 2 )
+          return error( COMPERR_BAD_INPUT_MESH, "Source elements overlap one another");
+      }
+    }
+  }
+  if ( !isFaceMeshed )
+    return error( COMPERR_BAD_INPUT_MESH,
+                  "Source elements don't cover totally the geometrical face" );
+
+  if ( helper.HasSeam() )
+  {
+    // links on seam edges are shared by two faces, so no edges were created on them
+    // by the previous detection of 2D mesh boundary
+    for ( size_t iE = 0; iE < edges.size(); ++iE )
+    {
+      if ( !helper.IsRealSeam( edges[iE] )) continue;
+      const TopoDS_Edge& seamEdge = edges[iE];
+      // to find nodes lying on the seamEdge we check nodes of mesh faces sharing a node on one
+      // of its vertices; after finding another node on seamEdge we continue the same way
+      // until finding all nodes.
+      TopoDS_Vertex      seamVertex = helper.IthVertex( 0, seamEdge );
+      const SMDS_MeshNode* vertNode = SMESH_Algo::VertexNode( seamVertex, tgtMesh );
+      set< const SMDS_MeshNode* > checkedNodes; checkedNodes.insert( vertNode );
+      set< const SMDS_MeshElement* > checkedFaces;
+      // as a face can have more than one node on the seamEdge, there is a difficulty in selecting
+      // one of those nodes to treat next; so we simply find all nodes on the seamEdge and
+      // then sort them by U on edge
+      typedef list< pair< double, const SMDS_MeshNode* > > TUNodeList;
+      TUNodeList nodesOnSeam;
+      double u = helper.GetNodeU( seamEdge, vertNode );
+      nodesOnSeam.push_back( make_pair( u, vertNode ));
+      TUNodeList::iterator u2nIt = nodesOnSeam.begin();
+      for ( ; u2nIt != nodesOnSeam.end(); ++u2nIt )
+      {
+        const SMDS_MeshNode* startNode = (*u2nIt).second;
+        SMDS_ElemIteratorPtr faceIt = startNode->GetInverseElementIterator( SMDSAbs_Face );
+        while ( faceIt->more() )
+        {
+          const SMDS_MeshElement* face = faceIt->next();
+          if ( !checkedFaces.insert( face ).second ) continue;
+          for ( int i = 0, nbNodes = face->NbCornerNodes(); i < nbNodes; ++i )
+          {
+            const SMDS_MeshNode* n = face->GetNode( i );
+            if ( n == startNode || !checkedNodes.insert( n ).second ) continue;
+            if ( helper.CheckNodeU( seamEdge, n, u=0, projTol, /*force=*/true ))
+              nodesOnSeam.push_back( make_pair( u, n ));
+          }
+        }
+      }
+      // sort the found nodes by U on the seamEdge; most probably they are in a good order,
+      // so we can use the hint to spead-up map filling
+      map< double, const SMDS_MeshNode* > u2nodeMap;
+      for ( u2nIt = nodesOnSeam.begin(); u2nIt != nodesOnSeam.end(); ++u2nIt )
+        u2nodeMap.insert( u2nodeMap.end(), *u2nIt );
+
+      // create edges
+      {
+        SMESH_MesherHelper seamHelper( theMesh );
+        seamHelper.SetSubShape( edges[ iE ]);
+        seamHelper.SetElementsOnShape( true );
+
+        if ( (*checkedFaces.begin())->IsQuadratic() )
+          for ( set< const SMDS_MeshElement* >::iterator fIt = checkedFaces.begin();
+                fIt != checkedFaces.end(); ++fIt )
+            seamHelper.AddTLinks( static_cast<const SMDS_MeshFace*>( *fIt ));
+
+        map< double, const SMDS_MeshNode* >::iterator n1, n2, u2nEnd = u2nodeMap.end();
+        for ( n2 = u2nodeMap.begin(), n1 = n2++; n2 != u2nEnd; ++n1, ++n2 )
+        {
+          const SMDS_MeshNode* node1 = n1->second;
+          const SMDS_MeshNode* node2 = n2->second;
+          seamHelper.AddEdge( node1, node2 );
+          if ( node2->getshapeId() == helper.GetSubShapeID() )
+          {
+            tgtFaceSM->RemoveNode( node2, /*isNodeDeleted=*/false );
+            tgtMesh->SetNodeOnEdge( const_cast<SMDS_MeshNode*>( node2 ), seamEdge, n2->first );
+          }
+        }
+      }
+    } // loop on edges to find seam ones
+  } // if ( helper.HasSeam() )
+
+  // notify sub-meshes of edges on computation
+  for ( size_t iE = 0; iE < edges.size(); ++iE )
+  {
+    SMESH_subMesh * sm = theMesh.GetSubMesh( edges[iE] );
+    if ( BRep_Tool::Degenerated( edges[iE] ))
+      sm->SetIsAlwaysComputed( true );
+    sm->ComputeStateEngine(SMESH_subMesh::CHECK_COMPUTE_STATE);
+    if ( sm->GetComputeState() != SMESH_subMesh::COMPUTE_OK )
+      return error(SMESH_Comment("Failed to create segments on the edge ")
+                   << tgtMesh->ShapeToIndex( edges[iE ]));
+  }
+
+  // ============
+  // Copy meshes
+  // ============
+
+  vector<SMESH_Mesh*> srcMeshes = _sourceHyp->GetSourceMeshes();
+  for ( size_t i = 0; i < srcMeshes.size(); ++i )
+    StdMeshers_Import_1D::importMesh( srcMeshes[i], theMesh, _sourceHyp, theShape );
+
+  return true;
+}
+
+//=============================================================================
+/*!
+ * \brief Set needed event listeners and create a submesh for a copied mesh
+ *
+ * This method is called only if a submesh has HYP_OK algo_state.
+ */
+//=============================================================================
+
+void StdMeshers_Import_1D2D::SetEventListener(SMESH_subMesh* subMesh)
+{
+  if ( !_sourceHyp )
+  {
+    const TopoDS_Shape& tgtShape = subMesh->GetSubShape();
+    SMESH_Mesh*         tgtMesh  = subMesh->GetFather();
+    Hypothesis_Status aStatus;
+    CheckHypothesis( *tgtMesh, tgtShape, aStatus );
+  }
+  StdMeshers_Import_1D::setEventListener( subMesh, _sourceHyp );
+}
+void StdMeshers_Import_1D2D::SubmeshRestored(SMESH_subMesh* subMesh)
+{
+  SetEventListener(subMesh);
+}
+
+//=============================================================================
+/*!
+ * Predict nb of mesh entities created by Compute()
+ */
+//=============================================================================
+
+bool StdMeshers_Import_1D2D::Evaluate(SMESH_Mesh &         theMesh,
+                                      const TopoDS_Shape & theShape,
+                                      MapShapeNbElems&     aResMap)
+{
+  if ( !_sourceHyp ) return false;
+
+  const vector<SMESH_Group*>& srcGroups = _sourceHyp->GetGroups();
+  if ( srcGroups.empty() )
+    return error("Invalid source groups");
+
+  vector<int> aVec(SMDSEntity_Last,0);
+
+  bool toCopyMesh, toCopyGroups;
+  _sourceHyp->GetCopySourceMesh(toCopyMesh, toCopyGroups);
+  if ( toCopyMesh ) // the whole mesh is copied
+  {
+    vector<SMESH_Mesh*> srcMeshes = _sourceHyp->GetSourceMeshes();
+    for ( unsigned i = 0; i < srcMeshes.size(); ++i )
+    {
+      SMESH_subMesh* sm = StdMeshers_Import_1D::getSubMeshOfCopiedMesh( theMesh, *srcMeshes[i]);
+      if ( !sm || aResMap.count( sm )) continue; // already counted
+      const SMDS_MeshInfo& aMeshInfo = srcMeshes[i]->GetMeshDS()->GetMeshInfo();
+      for (int i = 0; i < SMDSEntity_Last; i++)
+        aVec[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
+    }
+  }
+  else
+  {
+    // std-like iterator used to get coordinates of nodes of mesh element
+    typedef SMDS_StdIterator< SMESH_TNodeXYZ, SMDS_ElemIteratorPtr > TXyzIterator;
+
+    SMESH_MesherHelper helper(theMesh);
+    helper.SetSubShape(theShape);
+
+    const TopoDS_Face& geomFace = TopoDS::Face( theShape );
+
+    // take into account nodes on vertices
+    TopExp_Explorer exp( theShape, TopAbs_VERTEX );
+    for ( ; exp.More(); exp.Next() )
+      theMesh.GetSubMesh( exp.Current())->Evaluate( aResMap );
+
+    // to count now many times a link between nodes encounters,
+    // negative nb additionally means that a link is quadratic
+    map<SMESH_TLink, int> linkCount;
+    map<SMESH_TLink, int>::iterator link2Nb;
+
+    // count faces and nodes imported from groups
+    set<const SMDS_MeshNode* > allNodes;
+    gp_XY uv;
+    double minGroupTol = 1e100;
+    for ( int iG = 0; iG < srcGroups.size(); ++iG )
+    {
+      const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS();
+      const double groupTol = 0.5 * sqrt( getMinElemSize2( srcGroup ));
+      minGroupTol = std::min( groupTol, minGroupTol );
+      SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
+      SMDS_MeshNode *tmpNode =helper.AddNode(0,0,0);
+      while ( srcElems->more() ) // loop on group contents
+      {
+        const SMDS_MeshElement* face = srcElems->next();
+        // find out if face is located on geomEdge by projecting
+        // a gravity center of face to geomFace
+        gp_XYZ gc(0,0,0);
+        gc = accumulate( TXyzIterator(face->nodesIterator()), TXyzIterator(), gc)/face->NbNodes();
+        tmpNode->setXYZ( gc.X(), gc.Y(), gc.Z());
+        if ( helper.CheckNodeUV( geomFace, tmpNode, uv, groupTol, /*force=*/true ))
+        {
+          ++aVec[ face->GetEntityType() ];
+
+          // collect links
+          int nbConers = face->NbCornerNodes();
+          for ( int i = 0; i < face->NbNodes(); ++i )
+          {
+            const SMDS_MeshNode* n1 = face->GetNode(i);
+            allNodes.insert( n1 );
+            if ( i < nbConers )
+            {
+              const SMDS_MeshNode* n2 = face->GetNode( (i+1)%nbConers );
+              link2Nb = linkCount.insert( make_pair( SMESH_TLink( n1, n2 ), 0)).first;
+              if ( (*link2Nb).second )
+                link2Nb->second += (link2Nb->second < 0 ) ? -1 : 1;
+              else
+                link2Nb->second += ( face->IsQuadratic() ) ? -1 : 1;
+            }
+          }
+        }
+      }
+      helper.GetMeshDS()->RemoveNode(tmpNode);
+    }
+
+    int nbNodes = allNodes.size();
+    allNodes.clear();
+
+    // count nodes and edges on geom edges
+
+    double u;
+    for ( exp.Init(theShape, TopAbs_EDGE); exp.More(); exp.Next() )
+    {
+      TopoDS_Edge geomEdge = TopoDS::Edge( exp.Current() );
+      SMESH_subMesh* sm = theMesh.GetSubMesh( geomEdge );
+      vector<int>& edgeVec = aResMap[sm];
+      if ( edgeVec.empty() )
+      {
+        edgeVec.resize(SMDSEntity_Last,0);
+        for ( link2Nb = linkCount.begin(); link2Nb != linkCount.end(); )
+        {
+          const SMESH_TLink& link = (*link2Nb).first;
+          int nbFacesOfLink = Abs( link2Nb->second );
+          bool eraseLink = ( nbFacesOfLink != 1 );
+          if ( nbFacesOfLink == 1 )
+          {
+            if ( helper.CheckNodeU( geomEdge, link.node1(), u, minGroupTol, /*force=*/true )&&
+                 helper.CheckNodeU( geomEdge, link.node2(), u, minGroupTol, /*force=*/true ))
+            {
+              bool isQuadratic = ( link2Nb->second < 0 );
+              ++edgeVec[ isQuadratic ? SMDSEntity_Quad_Edge : SMDSEntity_Edge ];
+              ++edgeVec[ SMDSEntity_Node ];
+              --nbNodes;
+              eraseLink = true;
+            }
+          }
+          if ( eraseLink )
+            linkCount.erase(link2Nb++);
+          else
+            link2Nb++;
+        }
+        if ( edgeVec[ SMDSEntity_Node] > 0 )
+          --edgeVec[ SMDSEntity_Node ]; // for one node on vertex
+      }
+      else if ( !helper.IsSeamShape( geomEdge ) ||
+                geomEdge.Orientation() == TopAbs_FORWARD )
+      {
+        nbNodes -= 1+edgeVec[ SMDSEntity_Node ];
+      }
+    }
+
+    aVec[SMDSEntity_Node] = nbNodes;
+  }
+
+  SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
+  aResMap.insert(make_pair(sm,aVec));
+
+  return true;
+}
diff --git a/src/StdMeshers/StdMeshers_Import_1D2D.hxx b/src/StdMeshers/StdMeshers_Import_1D2D.hxx
new file mode 100644 (file)
index 0000000..fc3a89d
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+//  Module : SMESH
+//
+#ifndef _SMESH_Import_2D_HXX_
+#define _SMESH_Import_2D_HXX_
+
+#include "SMESH_StdMeshers.hxx"
+
+#include "SMESH_2D_Algo.hxx"
+#include "SMDS_MeshElement.hxx"
+
+class StdMeshers_ImportSource1D;
+
+/*!
+ * \brief Copy elements from other the mesh
+ */
+class STDMESHERS_EXPORT StdMeshers_Import_1D2D: public SMESH_2D_Algo
+{
+public:
+  StdMeshers_Import_1D2D(int hypId, int studyId, SMESH_Gen* gen);
+
+  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);
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
+
+  virtual void SetEventListener(SMESH_subMesh* subMesh);
+  virtual void SubmeshRestored(SMESH_subMesh* subMesh);
+
+ private:
+  
+  StdMeshers_ImportSource1D* _sourceHyp;
+};
+
+#endif
index 8e5987e6b5059ffddeba6ab4a37ed894fec24c38..06693566b0370c273deb030505304e3cf187130d 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : idl implementation based on 'SMESH' unit's classes
 //  File   : StdMeshers_LayerDistribution.cxx
 //  Author : Edward AGAPOV
index aca054d4fb93e93e769ecfa1688808361a75638a..921d06bd3f30ff403cd86e412c1c9987a86b3557 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_LayerDistribution.hxx
 //  Author : Edward AGAPOV
diff --git a/src/StdMeshers/StdMeshers_LayerDistribution2D.cxx b/src/StdMeshers/StdMeshers_LayerDistribution2D.cxx
new file mode 100644 (file)
index 0000000..581e436
--- /dev/null
@@ -0,0 +1,59 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+//  SMESH SMESH : idl implementation based on 'SMESH' unit's classes
+//  File   : StdMeshers_LayerDistribution2D.cxx
+//  Author : Edward AGAPOV
+//  Module : SMESH
+//
+#include "StdMeshers_LayerDistribution2D.hxx"
+
+#include "utilities.h"
+
+
+//=============================================================================
+/*!
+ *  StdMeshers_LayerDistribution2D::StdMeshers_LayerDistribution2D
+ *
+ *  Constructor
+ */
+//=============================================================================
+
+StdMeshers_LayerDistribution2D::StdMeshers_LayerDistribution2D(int hypId,
+                                                               int studyId,
+                                                               SMESH_Gen * gen)
+  : StdMeshers_LayerDistribution(hypId, studyId, gen)
+{
+  _name = "LayerDistribution2D"; // used by RadialQuadrangle_1D2D
+  _param_algo_dim = 2; // 2D
+  myHyp = 0;
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_LayerDistribution2D::~StdMeshers_LayerDistribution2D
+ *
+ *  Destructor
+ */
+//=============================================================================
+
+StdMeshers_LayerDistribution2D::~StdMeshers_LayerDistribution2D()
+{
+  MESSAGE( "StdMeshers_LayerDistribution2D::~StdMeshers_LayerDistribution2D" );
+}
diff --git a/src/StdMeshers/StdMeshers_LayerDistribution2D.hxx b/src/StdMeshers/StdMeshers_LayerDistribution2D.hxx
new file mode 100644 (file)
index 0000000..f3ae9b2
--- /dev/null
@@ -0,0 +1,53 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+//  SMESH SMESH : idl implementation based on 'SMESH' unit's calsses
+//  File   : StdMeshers_LayerDistribution2D.hxx
+//  Author : Edward AGAPOV
+//  Module : SMESH
+//
+#ifndef _SMESH_LayerDistribution2D_HXX_
+#define _SMESH_LayerDistribution2D_HXX_
+
+#include "StdMeshers_LayerDistribution.hxx"
+
+
+// =========================================================
+// =========================================================
+/*!
+ * This hypothesis is used by "Radial quadrangle" algorithm.
+ * It specifies 1D hypothesis defining distribution of segments
+ * between the internal and the external surfaces.
+ */
+// =========================================================
+// =========================================================
+
+class STDMESHERS_EXPORT StdMeshers_LayerDistribution2D
+                        :public StdMeshers_LayerDistribution
+{
+public:
+  // Constructor
+  StdMeshers_LayerDistribution2D(int hypId, int studyId, SMESH_Gen* gen);
+  // Destructor
+  virtual ~StdMeshers_LayerDistribution2D();
+
+};
+
+#endif
+
index cad6e91869e790a5a637f6ef3a63b4e47ee50745..317b43d053a1cec6ce0a941b5a951b616ec28f20 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_LengthFromEdges.cxx
 //           Moved here from SMESH_LengthFromEdges.cxx
index cb52638e573025c5182055e7f7a330635dd4964d..a80a1e72ca643a793d1f3cb444345c44f4aa3bee 100644 (file)
@@ -1,31 +1,31 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_LengthFromEdges.hxx
 //           Moved here from SMESH_LengthFromEdges.hxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
 //
-
 #ifndef _SMESH_LENGTHFROMEDGES_HXX_
 #define _SMESH_LENGTHFROMEDGES_HXX_
 
index d74abe9fd2c89aa5700b558ff9dfe079d5ab47e5..0706f9ef24e19dd31ca08fde18282ddddb2ae363 100644 (file)
@@ -1,31 +1,31 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_LocalLength.cxx
 //           Moved here from SMESH_LocalLength.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
 //
-
 #include "StdMeshers_LocalLength.hxx"
 
 #include "SMESH_Mesh.hxx"
@@ -216,7 +216,7 @@ bool StdMeshers_LocalLength::SetParametersByMesh(const SMESH_Mesh*   theMesh,
   {
     const TopoDS_Edge& edge = TopoDS::Edge( edgeMap( iE ));
     Handle(Geom_Curve) C = BRep_Tool::Curve( edge, L, UMin, UMax );
-    GeomAdaptor_Curve AdaptCurve(C);
+    GeomAdaptor_Curve AdaptCurve(C, UMin, UMax);
 
     vector< double > params;
     SMESHDS_Mesh* aMeshDS = const_cast< SMESH_Mesh* >( theMesh )->GetMeshDS();
@@ -244,6 +244,6 @@ bool StdMeshers_LocalLength::SetParametersByMesh(const SMESH_Mesh*   theMesh,
 bool StdMeshers_LocalLength::SetParametersByDefaults(const TDefaults&  dflts,
                                                      const SMESH_Mesh* /*theMesh*/)
 {
-  return bool( _length = dflts._elemLength );
+  return ( _length = dflts._elemLength );
 }
 
index 1c8d72b2784a93aa020165f741487f3e2f6fdd89..6232e127c84ffd3b25ee80ad8645692e7bb1f22a 100644 (file)
@@ -1,31 +1,31 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_LocalLength.hxx
 //           Moved here from SMESH_LocalLength.hxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
 //
-
 #ifndef _SMESH_LOCALLENGTH_HXX_
 #define _SMESH_LOCALLENGTH_HXX_
 
index 45339814920fe3c24fee71cd55e7541bb88bd41e..fe637c65a1e82c2e345d8edde45da2a4f8b8e8b9 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_MEFISTO_2D.cxx
 //           Moved here from SMESH_MEFISTO_2D.cxx
 
 #include <BRepTools.hxx>
 #include <BRep_Tool.hxx>
+#include <Geom_Curve.hxx>
 #include <Geom2d_Curve.hxx>
 #include <Geom_Surface.hxx>
+#include <Precision.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopoDS_Iterator.hxx>
 #include <gp_Pnt2d.hxx>
 
+#include <BRep_Tool.hxx>
+#include <GProp_GProps.hxx>
+#include <BRepGProp.hxx>
+
 using namespace std;
 
 //=============================================================================
@@ -230,6 +237,8 @@ bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh
   Z nutysu = 1;           // 1: il existe un fonction areteideale_()
   // Z  nutysu=0;         // 0: on utilise aretmx
   R aretmx = _edgeLength; // longueur max aretes future triangulation
+  if ( _hypMaxElementArea )
+    aretmx *= 1.5;
   
   nblf = nbWires;
   
@@ -282,6 +291,90 @@ bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh
   return isOk;
 }
 
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+bool StdMeshers_MEFISTO_2D::Evaluate(SMESH_Mesh & aMesh,
+                                     const TopoDS_Shape & aShape,
+                                     MapShapeNbElems& aResMap)
+{
+  MESSAGE("StdMeshers_MEFISTO_2D::Evaluate");
+
+  TopoDS_Face F = TopoDS::Face(aShape.Oriented(TopAbs_FORWARD));
+
+  double aLen = 0.0;
+  int NbSeg = 0;
+  bool IsQuadratic = false;
+  bool IsFirst = true;
+  TopExp_Explorer exp(F,TopAbs_EDGE);
+  for(; exp.More(); exp.Next()) {
+    TopoDS_Edge E = TopoDS::Edge(exp.Current());
+    MapShapeNbElemsItr anIt = aResMap.find( aMesh.GetSubMesh(E) );
+    if( anIt == aResMap.end() ) continue;
+    std::vector<int> aVec = (*anIt).second;
+    int nbe = Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]);
+    NbSeg += nbe;
+    if(IsFirst) {
+      IsQuadratic = ( aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge] );
+      IsFirst = false;
+    }
+    double a,b;
+    TopLoc_Location L;
+    Handle(Geom_Curve) C = BRep_Tool::Curve(E,L,a,b);
+    gp_Pnt P1;
+    C->D0(a,P1);
+    double dp = (b-a)/nbe;
+    for(int i=1; i<=nbe; i++) {
+      gp_Pnt P2;
+      C->D0(a+i*dp,P2);
+      aLen += P1.Distance(P2);
+      P1 = P2;
+    }
+  }
+  if(NbSeg<1) {
+    std::vector<int> aResVec(SMDSEntity_Last);
+    for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
+    SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+    aResMap.insert(std::make_pair(sm,aResVec));
+    SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+    smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,
+                                          "Submesh can not be evaluated",this));
+    return false;
+  }
+  aLen = aLen/NbSeg; // middle length
+
+  _edgeLength = Precision::Infinite();
+  double tmpLength = Min( _edgeLength, aLen );
+
+  GProp_GProps G;
+  BRepGProp::SurfaceProperties(aShape,G);
+  double anArea = G.Mass();
+
+  int nbFaces = Precision::IsInfinite( tmpLength ) ? 0 :
+    (int)( anArea/(tmpLength*tmpLength*sqrt(3.)/4) );
+  int nbNodes = (int) ( nbFaces*3 - (NbSeg-1)*2 ) / 6;
+
+  std::vector<int> aVec(SMDSEntity_Last);
+  for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aVec[i] = 0;
+  if(IsQuadratic) {
+    aVec[SMDSEntity_Quad_Triangle] = nbFaces;
+    aVec[SMDSEntity_Node] = (int)( nbNodes + nbFaces*3 - (NbSeg-1) );
+  }
+  else {
+    aVec[SMDSEntity_Node] = nbNodes;
+    aVec[SMDSEntity_Triangle] = nbFaces;
+  }
+  SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+  aResMap.insert(std::make_pair(sm,aVec));
+
+  return true;
+}
+
+
 //=======================================================================
 //function : fixOverlappedLinkUV
 //purpose  : prevent failure due to overlapped adjacent links
@@ -421,7 +514,7 @@ static bool fixCommonVertexUV (R2 &                 theUV,
         if ( theCreateQuadratic && SMESH_MesherHelper::IsMedium( node, SMDSAbs_Edge ))
           continue;
         const SMDS_EdgePosition* epos =
-          static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+          static_cast<const SMDS_EdgePosition*>(node->GetPosition());
         double u = epos->GetUParameter();
         if ( u < umin )
           umin = u;
@@ -514,8 +607,31 @@ bool StdMeshers_MEFISTO_2D::LoadPoints(TWireVector &                 wires,
       // set UV
       uvslf[m].x = uvPt->u * scalex;
       uvslf[m].y = uvPt->v * scaley;
-      if ( uvPt->node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX )
+      switch ( uvPt->node->GetPosition()->GetTypeOfPosition())
+      {
+      case SMDS_TOP_VERTEX:
         mOnVertex.push_back( m );
+        break;
+      case SMDS_TOP_EDGE:
+        // In order to detect degenerated faces easily, we replace
+        // nodes on a degenerated edge by node on the vertex of that edge
+        if ( myTool->IsDegenShape( uvPt->node->getshapeId() ))
+        {
+          int edgeID = uvPt->node->getshapeId();
+          SMESH_subMesh* edgeSM = myTool->GetMesh()->GetSubMeshContaining( edgeID );
+          SMESH_subMeshIteratorPtr smIt = edgeSM->getDependsOnIterator( /*includeSelf=*/0,
+                                                                        /*complexShapeFirst=*/0);
+          if ( smIt->more() )
+          {
+            SMESH_subMesh* vertexSM = smIt->next();
+            SMDS_NodeIteratorPtr nIt = vertexSM->GetSubMeshDS()->GetNodes();
+            if ( nIt->more() )
+              mefistoToDS[m] = nIt->next();
+          }
+        }
+        break;
+      default:;
+      }
       m++;
     }
 
@@ -526,7 +642,7 @@ bool StdMeshers_MEFISTO_2D::LoadPoints(TWireVector &                 wires,
       int m = *mIt;
       if ( iW && !VWMap.IsEmpty()) { // except outer wire
         // avoid passing same uv point for a vertex common to 2 wires
-        int vID = mefistoToDS[m]->GetPosition()->GetShapeId();
+        int vID = mefistoToDS[m]->getshapeId();
         TopoDS_Vertex V = TopoDS::Vertex( myTool->GetMeshDS()->IndexToShape( vID ));
         if ( fixCommonVertexUV( uvslf[m], V, F, VWMap, *myTool->GetMesh(),
                                 scalex, scaley, _quadraticMesh )) {
@@ -542,6 +658,9 @@ bool StdMeshers_MEFISTO_2D::LoadPoints(TWireVector &                 wires,
       fixOverlappedLinkUV (uvslf[ mB ], uvslf[ m ], uvslf[ mA ]);
     }
   }
+//   cout << "MEFISTO INPUT************" << endl;
+//   for ( int i =0; i < m; ++i )
+//     cout << i << ": \t" << uvslf[i].x << ", " << uvslf[i].y << " Node " << mefistoToDS[i]->GetID()<< endl;
 
   return true;
 }
@@ -688,13 +807,17 @@ void StdMeshers_MEFISTO_2D::StoreResult(Z nbst, R2 * uvst, Z nbt, Z * nust,
     const SMDS_MeshNode * n2 = mefistoToDS[ nust[m++] - 1 ];
     const SMDS_MeshNode * n3 = mefistoToDS[ nust[m++] - 1 ];
 
-    SMDS_MeshElement * elt;
-    if (triangleIsWellOriented)
-      elt = myTool->AddFace(n1, n2, n3);
-    else
-      elt = myTool->AddFace(n1, n3, n2);
-
-    meshDS->SetMeshElementOnShape(elt, faceID);
+    // avoid creating degenetrated faces
+    bool isDegen = ( myTool->HasDegeneratedEdges() && ( n1 == n2 || n1 == n3 || n2 == n3 ));
+    if ( !isDegen )
+    {
+      SMDS_MeshElement * elt;
+      if (triangleIsWellOriented)
+        elt = myTool->AddFace(n1, n2, n3);
+      else
+        elt = myTool->AddFace(n1, n3, n2);
+      meshDS->SetMeshElementOnShape(elt, faceID);
+    }
     m++;
   }
 
index fba4b2d3480daf6099a4011f57802cf70f80317e..0dce86135ef9018c64a336dab7ec6f2ca6a87430 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_MEFISTO_2D.hxx
 //           Moved here from SMESH_MEFISTO_2D.hxx
@@ -55,25 +56,28 @@ public:
                                SMESH_Hypothesis::Hypothesis_Status& aStatus);
 
   virtual bool Compute(SMESH_Mesh& aMesh,
-                      const TopoDS_Shape& aShape);
+                       const TopoDS_Shape& aShape);
+
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
 
   typedef boost::shared_ptr< StdMeshers_FaceSide> StdMeshers_FaceSidePtr;
   typedef std::vector< StdMeshers_FaceSidePtr > TWireVector;
 
   bool LoadPoints(TWireVector &                       wires,
-                 R2*                                 uvslf, 
-                 std::vector< const SMDS_MeshNode*>& mefistoToDS,
+                  R2*                                 uvslf, 
+                  std::vector< const SMDS_MeshNode*>& mefistoToDS,
                   double scalex, double               scaley);
 
   void ComputeScaleOnFace(SMESH_Mesh& aMesh,
-                         const TopoDS_Face& aFace,
-                         double& scalex,
-                         double& scaley);
+                          const TopoDS_Face& aFace,
+                          double& scalex,
+                          double& scaley);
 
   void StoreResult (Z nbst, R2* uvst, Z nbt, Z* nust, 
-                   std::vector< const SMDS_MeshNode*>& mefistoToDS,
+                    std::vector< const SMDS_MeshNode*>& mefistoToDS,
                     double scalex, double scaley);
-                                         
+                                          
 protected:
   double                            _edgeLength;
   double                            _maxElementArea;
index 36e40e172e37cc81bf53cbd8456ce536516aa932..e42dd783c5b83d6aec72b8322432cbdb6b2a5bd4 100644 (file)
@@ -1,31 +1,31 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_MaxElementArea.cxx
 //           Moved here from SMESH_MaxElementArea.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
 //
-
 #include "StdMeshers_MaxElementArea.hxx"
 
 #include "SMESH_ControlsDef.hxx"
@@ -195,6 +195,6 @@ bool StdMeshers_MaxElementArea::SetParametersByMesh(const SMESH_Mesh*   theMesh,
 bool StdMeshers_MaxElementArea::SetParametersByDefaults(const TDefaults&  dflts,
                                                         const SMESH_Mesh* /*theMesh*/)
 {
-  return bool( _maxArea = dflts._elemLength*dflts._elemLength );
+  return ( _maxArea = dflts._elemLength*dflts._elemLength );
 }
 
index 09506736393c557bff7387efc14c6823a7d25c15..f7ea305ad187b9f33c4a463db54070e9b8f0720f 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_MaxElementArea.hxx
 //           Moved here from SMESH_MaxElementArea.hxx
index 435213aad535435f7df24d8c33b5a9d84b05c412..b70bdfa52391bef9dd4474e3346f0551eb0bf86d 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_MaxElementVolume.cxx
 //           Moved here from SMESH_MaxElementVolume.cxx
@@ -206,6 +207,6 @@ bool StdMeshers_MaxElementVolume::SetParametersByMesh(const SMESH_Mesh*   theMes
 bool StdMeshers_MaxElementVolume::SetParametersByDefaults(const TDefaults&  dflts,
                                                           const SMESH_Mesh* /*theMesh*/)
 {
-  return bool( _maxVolume = dflts._elemLength*dflts._elemLength*dflts._elemLength );
+  return ( _maxVolume = dflts._elemLength*dflts._elemLength*dflts._elemLength );
 }
 
index 6395fd419e30149eaabb88a0436199d3a9b1b07e..27d332b32e4cc8c0eb60ce958f632152589d0cd5 100644 (file)
@@ -1,30 +1,31 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_MaxElementVolume.hxx
 //           Moved here from SMESH_MaxElementVolume.hxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-
+//
 #ifndef _SMESH_MAXELEMENTVOLUME_HXX_
 #define _SMESH_MAXELEMENTVOLUME_HXX_
 
index 475e56ae5aa94c9c0448a673dcd503838c89d9e0..9597001f505b75a707b2e940d6a72c7e2dcb925f 100644 (file)
@@ -1,27 +1,26 @@
-//  SMESH SMESH : implementaion of SMESH idl descriptions
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
 //
-//  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.com
 //
+
+//  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_MaxLength.cxx
 //  Module : SMESH
-
+//
 #include "StdMeshers_MaxLength.hxx"
 
 #include "SMESH_Mesh.hxx"
@@ -208,7 +207,7 @@ bool StdMeshers_MaxLength::SetParametersByMesh(const SMESH_Mesh*   theMesh,
   {
     const TopoDS_Edge& edge = TopoDS::Edge( edgeMap( iE ));
     Handle(Geom_Curve) C = BRep_Tool::Curve( edge, L, UMin, UMax );
-    GeomAdaptor_Curve AdaptCurve(C);
+    GeomAdaptor_Curve AdaptCurve(C, UMin, UMax);
 
     vector< double > params;
     SMESHDS_Mesh* aMeshDS = const_cast< SMESH_Mesh* >( theMesh )->GetMeshDS();
@@ -237,6 +236,6 @@ bool StdMeshers_MaxLength::SetParametersByDefaults(const TDefaults&  dflts,
   //_preestimation = ( dflts._elemLength > 0.);
   if ( dflts._elemLength > 0. )
     _preestimated = dflts._elemLength;
-  return bool( _length = dflts._elemLength );
+  return ( _length = dflts._elemLength );
 }
 
index 23d94a9f286f2ad1828adaa93b5bdf1539d6f13e..7ea21e110b45072e52a57c8d5bd2c54e4e2a900e 100644 (file)
@@ -1,27 +1,26 @@
-//  SMESH SMESH : implementaion of SMESH idl descriptions
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
 //
-//  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.com
+//
 
+//  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_MaxLength.hxx
 //  Module : SMESH
-
+//
 #ifndef _SMESH_MaxLength_HXX_
 #define _SMESH_MaxLength_HXX_
 
index 66c58f13cc7915cbc59d91fa7b8ee15d7f1977bf..54a986b063059a9aa2ae82b90e2222e1a449a554 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH StdMeshers : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_NotConformAllowed.cxx
 //  Author : Paul RASCLE, EDF
index ddcfcb445d4b463046638a26a49e955539fba651..d52574b592d62d6a0bc32db2acf6e860e2eef577 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH StdMeshers : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_NotConformAllowed.hxx
 //  Author : Paul RASCLE, EDF
index 604ee185aa8683eedb2d9c5e0312ec7113f7ce89..9026f22521d8dd7badd8154453a854f581ab1885 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : idl implementation based on 'SMESH' unit's classes
 //  File   : StdMeshers_NumberOfLayers.cxx
 //  Author : Edward AGAPOV
@@ -171,7 +172,7 @@ bool StdMeshers_NumberOfLayers::SetParametersByDefaults(const TDefaults&  dflts,
                                                         const SMESH_Mesh* theMesh)
 {
   if ( dflts._elemLength )
-    return bool( theMesh ? _nbLayers = int( theMesh->GetShapeDiagonalSize() / dflts._elemLength/ 2.) : 0);
+    return theMesh ? (_nbLayers = int( theMesh->GetShapeDiagonalSize() / dflts._elemLength/ 2.)) : 0;
   return false;
 }
 
index ebaae84a918cca3d7c56b64fa4b63de249743064..dc7d60cde1f02b59a42ce8adb3c8b6c4e1251294 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_NumberOfLayers.hxx
 //  Author : Edward AGAPOV
diff --git a/src/StdMeshers/StdMeshers_NumberOfLayers2D.cxx b/src/StdMeshers/StdMeshers_NumberOfLayers2D.cxx
new file mode 100644 (file)
index 0000000..776c42f
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+//  SMESH SMESH : idl implementation based on 'SMESH' unit's classes
+//  File   : StdMeshers_NumberOfLayers2D.cxx
+//  Author : Edward AGAPOV
+//  Module : SMESH
+//
+#include "StdMeshers_NumberOfLayers2D.hxx"
+
+#include "utilities.h"
+
+
+//=============================================================================
+/*!
+ *  StdMeshers_NumberOfLayers2D::StdMeshers_NumberOfLayers2D
+ *
+ *  Constructor
+ */
+//=============================================================================
+
+StdMeshers_NumberOfLayers2D::StdMeshers_NumberOfLayers2D(int hypId,
+                                                         int studyId,
+                                                         SMESH_Gen * gen)
+  : StdMeshers_NumberOfLayers(hypId, studyId, gen)
+{
+  _name = "NumberOfLayers2D"; // used by RadialQuadrangle_1D2D
+  _param_algo_dim = 2; // 2D
+  _nbLayers = 1;
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_NumberOfLayers2D::~StdMeshers_NumberOfLayers2D
+ *
+ *  Destructor
+ */
+//=============================================================================
+
+StdMeshers_NumberOfLayers2D::~StdMeshers_NumberOfLayers2D()
+{
+  MESSAGE( "StdMeshers_NumberOfLayers2D::~StdMeshers_NumberOfLayers2D" );
+}
+
diff --git a/src/StdMeshers/StdMeshers_NumberOfLayers2D.hxx b/src/StdMeshers/StdMeshers_NumberOfLayers2D.hxx
new file mode 100644 (file)
index 0000000..eef7395
--- /dev/null
@@ -0,0 +1,52 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+//  SMESH SMESH : idl implementation based on 'SMESH' unit's calsses
+//  File   : StdMeshers_NumberOfLayers2D.hxx
+//  Author : Edward AGAPOV
+//  Module : SMESH
+//
+#ifndef _SMESH_NumberOfLayers2D_HXX_
+#define _SMESH_NumberOfLayers2D_HXX_
+
+#include "StdMeshers_NumberOfLayers.hxx"
+
+
+// =========================================================
+// =========================================================
+/*!
+ * This hypothesis is used by "Radial quadrangle" algorithm.
+ * It specifies number of segments between the internal 
+ * and the external surfaces.
+ */
+// =========================================================
+// =========================================================
+
+class STDMESHERS_EXPORT StdMeshers_NumberOfLayers2D
+                          : public StdMeshers_NumberOfLayers
+{
+public:
+  // Constructor
+  StdMeshers_NumberOfLayers2D(int hypId, int studyId, SMESH_Gen* gen);
+  // Destructor
+  virtual ~StdMeshers_NumberOfLayers2D();
+};
+
+#endif
+
index 90c50a0bb4c8aa16747131e7810d24f9422b3949..d9d1362d046184be57b39db0c8b867d327951ab0 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_NumberOfSegments.cxx
 //           Moved here from SMESH_NumberOfSegments.cxx
@@ -30,6 +31,7 @@
 #include "StdMeshers_Distribution.hxx"
 #include "SMESHDS_SubMesh.hxx"
 #include "SMESH_Mesh.hxx"
+#include "SMESH_Comment.hxx"
 
 #include <ExprIntrp_GenExp.hxx>
 #include <Expr_Array1OfNamedUnknown.hxx>
@@ -49,6 +51,8 @@
 #include <Standard_ErrorHandler.hxx>
 #endif
 
+#include <Basics_Utils.hxx>
+
 using namespace std;
 
 const double PRECISION = 1e-7;
@@ -233,11 +237,11 @@ void StdMeshers_NumberOfSegments::SetTableFunction(const vector<double>& table)
 #ifdef NO_CAS_CATCH
         OCC_CATCH_SIGNALS;
 #endif
-       val = pow( 10.0, val );
+        val = pow( 10.0, val );
       } catch(Standard_Failure) {
-       Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-       throw SALOME_Exception( LOCALIZED( "invalid value"));
-       return;
+        Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+        throw SALOME_Exception( LOCALIZED( "invalid value"));
+        return;
       }
     }
     else if( _convMode==1 && val<0.0 )
@@ -303,7 +307,7 @@ bool isCorrectArg( const Handle( Expr_GeneralExpression )& expr )
     if( !name.IsNull() )
     {
       if( name->GetName()!="t" )
-       res = false;
+        res = false;
     }
     else
       res = isCorrectArg( sub );
@@ -317,10 +321,12 @@ bool isCorrectArg( const Handle( Expr_GeneralExpression )& expr )
  */
 //================================================================================
 bool process( const TCollection_AsciiString& str, int convMode,
-             bool& syntax, bool& args,
-             bool& non_neg, bool& non_zero,
-             bool& singulars, double& sing_point )
+              bool& syntax, bool& args,
+              bool& non_neg, bool& non_zero,
+              bool& singulars, double& sing_point )
 {
+  Kernel_Utils::Localizer loc;
+
   bool parsed_ok = true;
   Handle( ExprIntrp_GenExp ) myExpr;
   try {
@@ -359,19 +365,20 @@ bool process( const TCollection_AsciiString& str, int convMode,
       double t = double(i)/double(max), val;
       if( !f.value( t, val ) )
       {
-       sing_point = t;
-       singulars = true;
-       break;
+        sing_point = t;
+        singulars = true;
+        break;
       }
       if( val<0 )
       {
-       non_neg = false;
-       break;
+        non_neg = false;
+        break;
       }
       if( val>PRECISION )
-       non_zero = true;
+        non_zero = true;
     }
   }
+
   return res && non_neg && non_zero && ( !singulars );
 }
 
@@ -388,8 +395,27 @@ void StdMeshers_NumberOfSegments::SetExpressionFunction(const char* expr)
     _distrType = DT_ExprFunc;
     //throw SALOME_Exception(LOCALIZED("not an expression function distribution"));
 
+  string func = CheckExpressionFunction( expr, _convMode );
+  if( _func != func )
+  {
+    _func = func;
+    NotifySubMeshesHypothesisModification();
+  }
+}
+
+//=======================================================================
+//function : CheckExpressionFunction
+//purpose  : Checks validity of  the expression of the function f(t), e.g. "sin(t)".
+//           In case of validity returns a cleaned expression
+//=======================================================================
+
+std::string
+StdMeshers_NumberOfSegments::CheckExpressionFunction( const std::string& expr,
+                                                      const int          convMode)
+    throw (SALOME_Exception)
+{
   // remove white spaces
-  TCollection_AsciiString str((Standard_CString)expr);
+  TCollection_AsciiString str((Standard_CString)expr.c_str());
   str.RemoveAll(' ');
   str.RemoveAll('\t');
   str.RemoveAll('\r');
@@ -397,15 +423,15 @@ void StdMeshers_NumberOfSegments::SetExpressionFunction(const char* expr)
 
   bool syntax, args, non_neg, singulars, non_zero;
   double sing_point;
-  bool res = process( str, _convMode, syntax, args, non_neg, non_zero, singulars, sing_point );
+  bool res = process( str, convMode, syntax, args, non_neg, non_zero, singulars, sing_point );
   if( !res )
   {
     if( !syntax )
-      throw SALOME_Exception(LOCALIZED("invalid expression syntax"));
+      throw SALOME_Exception(SMESH_Comment("invalid expression syntax: ") << str );
     if( !args )
       throw SALOME_Exception(LOCALIZED("only 't' may be used as function argument"));
     if( !non_neg )
-      throw SALOME_Exception(LOCALIZED("only non-negative function can be used as density"));
+      throw SALOME_Exception(LOCALIZED("only non-negative function can be used"));
     if( singulars )
     {
       char buf[1024];
@@ -413,17 +439,10 @@ void StdMeshers_NumberOfSegments::SetExpressionFunction(const char* expr)
       throw SALOME_Exception( buf );
     }
     if( !non_zero )
-      throw SALOME_Exception(LOCALIZED("f(t)=0 cannot be used as density"));
-
-    return;
-  }
-  
-  string func = expr;
-  if( _func != func )
-  {
-    _func = func;
-    NotifySubMeshesHypothesisModification();
+      throw SALOME_Exception(LOCALIZED("f(t)=0 cannot be used"));
   }
+  return str.ToCString();
 }
 
 //================================================================================
@@ -481,6 +500,7 @@ int StdMeshers_NumberOfSegments::ConversionMode() const
 
 ostream & StdMeshers_NumberOfSegments::SaveTo(ostream & save)
 {
+  int listSize = _edgeIDs.size();
   save << _numberOfSegments << " " << (int)_distrType;
   switch (_distrType)
   {
@@ -503,6 +523,13 @@ ostream & StdMeshers_NumberOfSegments::SaveTo(ostream & save)
 
   if (_distrType == DT_TabFunc || _distrType == DT_ExprFunc)
     save << " " << _convMode;
+
+  if ( _distrType != DT_Regular && listSize > 0 ) {
+    save << " " << listSize;
+    for ( int i = 0; i < listSize; i++ )
+      save << " " << _edgeIDs[i];
+    save << " " << _objEntry;
+  }
   
   return save;
 }
@@ -619,6 +646,18 @@ istream & StdMeshers_NumberOfSegments::LoadFrom(istream & load)
       load.clear(ios::badbit | load.rdstate());
   }
 
+  // load reversed edges IDs
+  int intVal;
+  isOK = (load >> intVal);
+  if ( isOK && _distrType != DT_Regular && intVal > 0 ) {
+    _edgeIDs.reserve( intVal );
+    for (int i = 0; i < _edgeIDs.capacity() && isOK; i++) {
+      isOK = (load >> intVal);
+      if ( isOK ) _edgeIDs.push_back( intVal );
+    }
+    isOK = (load >> _objEntry);
+  }
+
   return load;
 }
 
@@ -692,6 +731,21 @@ bool StdMeshers_NumberOfSegments::SetParametersByMesh(const SMESH_Mesh*   theMes
 bool StdMeshers_NumberOfSegments::SetParametersByDefaults(const TDefaults&  dflts,
                                                           const SMESH_Mesh* /*theMesh*/)
 {
-  return bool(_numberOfSegments = dflts._nbSegments );
+  return (_numberOfSegments = dflts._nbSegments );
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+void StdMeshers_NumberOfSegments::SetReversedEdges( std::vector<int>& ids )
+{
+  if ( ids != _edgeIDs ) {
+    _edgeIDs = ids;
+
+    NotifySubMeshesHypothesisModification();
+  }
 }
 
index 1be5b9176f61929055bdee75e90807b0f9d56e1f..a232c5871e49ac4172754249bf3ab65b6ab1fffd 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_NumberOfSegments.hxx
 //           Moved here from SMESH_NumberOfSegments.hxx
@@ -141,6 +142,15 @@ public:
   const char* GetExpressionFunction() const
     throw (SALOME_Exception);
 
+  /*!
+   * \brief Checks validity of  the expression of the function f(t), e.g. "sin(t)".
+   *        In case of validity returns a cleaned expression
+   *  \param convMode - 0 for "Exponent mode", 1 for "Cut negative mode"
+   */
+  static std::string CheckExpressionFunction( const std::string& expr,
+                                              const int          convMode)
+    throw (SALOME_Exception);
+
   /*!
    * \brief Set conversion mode. When it is 0, it means "exponent mode":
    * the function of distribution of density is used as an exponent of 10, i,e, 10^f(t).
@@ -161,6 +171,13 @@ public:
   int ConversionMode() const
     throw (SALOME_Exception);
 
+  void SetReversedEdges( std::vector<int>& ids);
+
+  void SetObjectEntry( const char* entry ) { _objEntry = entry; }
+
+  const char* GetObjectEntry() { return _objEntry.c_str(); }
+
+  const std::vector<int>& GetReversedEdges() const { return _edgeIDs; }
 
   /*!
    * \brief Initialize number of segments by the mesh built on the geometry
@@ -188,6 +205,8 @@ protected:
   std::vector<double> _table, _distr;    //!< the table for DT_TabFunc, a sequence of pairs of numbers
   std::string         _func;             //!< the expression of the function for DT_ExprFunc
   int                 _convMode;         //!< flag of conversion mode: 0=exponent, 1=cut negative
+  std::vector<int>    _edgeIDs;          //!< list of reversed edges ids
+  std::string         _objEntry;          //!< Entry of the main object to reverse edges
 };
 
 #endif
index 93bb7fd5c8560e8cb764f34b65f559ac94d06d9b..29c935a64042f4f12735af016e75e944de6bfba5 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH StdMeshers_Penta_3D implementaion of SMESH idl descriptions
 //  File   : StdMeshers_Penta_3D.cxx
 //  Module : SMESH
@@ -34,7 +35,7 @@
 #include "SMDS_VolumeTool.hxx"
 #include "SMESHDS_SubMesh.hxx"
 #include "SMESH_Mesh.hxx"
-#include "SMESH_MeshEditor.hxx"
+#include "SMESH_MesherHelper.hxx"
 #include "SMESH_subMesh.hxx"
 #include "SMESH_subMeshEventListener.hxx"
 #include "SMESH_Comment.hxx"
@@ -46,6 +47,8 @@
 #include <TopTools_IndexedMapOfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopTools_ListOfShape.hxx>
+#include <TopTools_SequenceOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
 #include <TopoDS.hxx>
 #include <TopoDS_Edge.hxx>
 #include <TopoDS_Shell.hxx>
@@ -67,7 +70,7 @@ enum { NB_WALL_FACES = 4 };
 //purpose  : 
 //=======================================================================
 StdMeshers_Penta_3D::StdMeshers_Penta_3D()
-: myErrorStatus(SMESH_ComputeError::New())
+  : myErrorStatus(SMESH_ComputeError::New())
 {
   myTol3D=0.1;
   myWallNodesMaps.resize( SMESH_Block::NbFaces() );
@@ -89,7 +92,7 @@ StdMeshers_Penta_3D::~StdMeshers_Penta_3D()
 //purpose  : 
 //=======================================================================
 bool StdMeshers_Penta_3D::Compute(SMESH_Mesh& aMesh, 
-                                 const TopoDS_Shape& aShape)
+                                  const TopoDS_Shape& aShape)
 {
   MESSAGE("StdMeshers_Penta_3D::Compute()");
   //
@@ -103,10 +106,6 @@ bool StdMeshers_Penta_3D::Compute(SMESH_Mesh& aMesh,
     return bOK;
   }
 
-  SMESH_MesherHelper helper(aMesh);
-  myTool = &helper;
-  myCreateQuadratic = myTool->IsQuadraticSubMesh(aShape);
-
   //
   MakeBlock();
   if (!myErrorStatus->IsOK()) {
@@ -117,6 +116,12 @@ bool StdMeshers_Penta_3D::Compute(SMESH_Mesh& aMesh,
   if (!myErrorStatus->IsOK()) {
     return bOK;
   }
+
+  // now unnecessary faces removed, we can load medium nodes
+  SMESH_MesherHelper helper(aMesh);
+  myTool = &helper;
+  myCreateQuadratic = myTool->IsQuadraticSubMesh(aShape);
+
   //
   MakeNodes();
   if (!myErrorStatus->IsOK()) {
@@ -230,7 +235,7 @@ void StdMeshers_Penta_3D::MakeNodes()
       //
       if ( SMESH_Block::IsEdgeID (aSID)) {
         const SMDS_EdgePosition* epos =
-          static_cast<const SMDS_EdgePosition*>(aNode->GetPosition().get());
+          static_cast<const SMDS_EdgePosition*>(aNode->GetPosition());
         myBlock.ComputeParameters( epos->GetUParameter(), aS, aCoords );
       }
       else {
@@ -258,11 +263,11 @@ void StdMeshers_Penta_3D::MakeNodes()
   SMESH_Block::TShapeID wallFaceID[ NB_WALL_FACES ] = {
     SMESH_Block::ID_Fx0z, SMESH_Block::ID_Fx1z,
     SMESH_Block::ID_F0yz, SMESH_Block::ID_F1yz
-    };
+  };
   SMESH_Block::TShapeID baseEdgeID[ NB_WALL_FACES ] = {
     SMESH_Block::ID_Ex00, SMESH_Block::ID_Ex10,
     SMESH_Block::ID_E0y0, SMESH_Block::ID_E1y0
-    };
+  };
   for ( i = 0; i < NB_WALL_FACES ; ++i ) {
     int fIndex = SMESH_Block::ShapeIndex( wallFaceID[ i ]);
     bool ok = LoadIJNodes (myWallNodesMaps[ fIndex ],
@@ -420,7 +425,7 @@ void StdMeshers_Penta_3D::MakeNodes()
       ShapeSupportID(bIsUpperLayer, aBNSSID, aSSID);
       if (!myErrorStatus->IsOK()) {
         MESSAGE("StdMeshers_Penta_3D::MakeNodes() ");
-       return;
+        return;
       }
       //
       aTN.SetShapeSupportID(aSSID);
@@ -428,13 +433,13 @@ void StdMeshers_Penta_3D::MakeNodes()
       aTN.SetBaseNodeID(iBNID);
       //
       if (aSSID!=SMESH_Block::ID_NONE){
-       // try to find the node
-       const TopoDS_Shape& aS=myBlock.Shape((int)aSSID);
-       FindNodeOnShape(aS, aCoords, i, aTN);
+        // try to find the node
+        const TopoDS_Shape& aS=myBlock.Shape((int)aSSID);
+        FindNodeOnShape(aS, aCoords, i, aTN);
       }
       else{
-       // create node and get it id
-       CreateNode (bIsUpperLayer, aCoords, aTN);
+        // create node and get its id
+        CreateNode (bIsUpperLayer, aCoords, aTN);
         //
         if ( bIsUpperLayer ) {
           const SMDS_MeshNode* n = aTN.Node();
@@ -467,39 +472,12 @@ void StdMeshers_Penta_3D::MakeNodes()
       }
       if (!myErrorStatus->IsOK()) {
         MESSAGE("StdMeshers_Penta_3D::MakeNodes() ");
-       return;
+        return;
       }
       //
       myTNodes[ij]=aTN;
     }
   }
-  //DEB
-  /*
-  {
-    int iSSID, iBNID, aID;
-    //
-    for (i=0; i<myISize; ++i) {
-      printf(" Layer# %d\n", i);
-      for (j=0; j<myJSize; ++j) {
-       ij=i*myJSize+j; 
-       const StdMeshers_TNode& aTN=myTNodes[ij];
-       //const StdMeshers_TNode& aTN=aTNodes[ij];
-       const gp_XYZ& aXYZ=aTN.NormCoord();
-       iSSID=aTN.ShapeSupportID();
-       iBNID=aTN.BaseNodeID();
-       //
-       const SMDS_MeshNode* aNode=aTN.Node();
-       aID=aNode->GetID(); 
-       aX=aNode->X();
-       aY=aNode->Y();
-       aZ=aNode->Z();
-       printf("*** j:%d BNID#%d iSSID:%d ID:%d { %lf %lf %lf },  { %lf %lf %lf }\n",
-              j,  iBNID, iSSID, aID, aXYZ.X(),  aXYZ.Y(), aXYZ.Z(), aX, aY, aZ);
-      }
-    }
-  }
-  */
-  //DEB t
 }
 
 
@@ -509,9 +487,9 @@ void StdMeshers_Penta_3D::MakeNodes()
 //=======================================================================
 
 void StdMeshers_Penta_3D::FindNodeOnShape(const TopoDS_Shape& aS,
-                                         const gp_XYZ&       aParams,
+                                          const gp_XYZ&       aParams,
                                           const int           z,
-                                         StdMeshers_TNode&   aTN)
+                                          StdMeshers_TNode&   aTN)
 {
   double aX, aY, aZ, aD, aTol2, minD;
   gp_Pnt aP1, aP2;
@@ -630,16 +608,16 @@ double StdMeshers_Penta_3D::SetHorizEdgeXYZ(const gp_XYZ&                  aBase
   }
   else {
     // this variant is better for other cases
-//   SMESH_MesherHelper helper( *GetMesh() );
-//   const TopoDS_Edge & edge = TopoDS::Edge( myBlock.Shape( edgeVec[ TOP ]));
-//   double u1 = helper.GetNodeU( edge, n1 );
-//   double u2 = helper.GetNodeU( edge, n2 );
-//   double u = ( 1. - r ) * u1 + r * u2;
-//   gp_XYZ topNodeParams;
-//   myBlock.Block().EdgeParameters( edgeVec[ TOP ], u, topNodeParams );
-//   myBlock.Block().EdgePoint( edgeVec[ TOP ],
-//                              topNodeParams,
-//                              myShapeXYZ[ edgeVec[ TOP ]]);
+    //   SMESH_MesherHelper helper( *GetMesh() );
+    //   const TopoDS_Edge & edge = TopoDS::Edge( myBlock.Shape( edgeVec[ TOP ]));
+    //   double u1 = helper.GetNodeU( edge, n1 );
+    //   double u2 = helper.GetNodeU( edge, n2 );
+    //   double u = ( 1. - r ) * u1 + r * u2;
+    //   gp_XYZ topNodeParams;
+    //   myBlock.Block().EdgeParameters( edgeVec[ TOP ], u, topNodeParams );
+    //   myBlock.Block().EdgePoint( edgeVec[ TOP ],
+    //                              topNodeParams,
+    //                              myShapeXYZ[ edgeVec[ TOP ]]);
   }
 
   // base edge
@@ -671,8 +649,8 @@ void StdMeshers_Penta_3D::MakeVolumeMesh()
       const StdMeshers_TNode& aTN = myTNodes[ij];
       aSSID=aTN.ShapeSupportID();
       if (aSSID==SMESH_Block::ID_NONE) {
-       SMDS_MeshNode* aNode = (SMDS_MeshNode*)aTN.Node();
-       meshDS->SetNodeInVolume(aNode, shapeID);
+        SMDS_MeshNode* aNode = (SMDS_MeshNode*)aTN.Node();
+        meshDS->SetNodeInVolume(aNode, shapeID);
       }
     }
   }
@@ -698,22 +676,16 @@ void StdMeshers_Penta_3D::MakeVolumeMesh()
     if ( aN.size() < nbFaceNodes * 2 )
       aN.resize( nbFaceNodes * 2 );
     //
-    k=0;
-    aItNodes=pE0->nodesIterator();
-    while (aItNodes->more()) {
-      //const SMDS_MeshElement* pNode = aItNodes->next();
-      const SMDS_MeshNode* pNode =
-        static_cast<const SMDS_MeshNode*> (aItNodes->next());
-      if(myTool->IsMedium(pNode))
-        continue;
+    for ( k=0; k<nbFaceNodes; ++k ) {
+      const SMDS_MeshNode* pNode = pE0->GetNode(k);
+//       if(myTool->IsMedium(pNode))
+//         continue;
       aID0 = pNode->GetID();
       aJ[k] = GetIndexOnLayer(aID0);
       if (!myErrorStatus->IsOK()) {
         MESSAGE("StdMeshers_Penta_3D::MakeVolumeMesh");
-       return;
+        return;
       }
-      //
-      ++k;
     }
     //
     bool forward = true;
@@ -721,15 +693,15 @@ void StdMeshers_Penta_3D::MakeVolumeMesh()
       i1=i;
       i2=i+1;
       for(j=0; j<nbFaceNodes; ++j) {
-       ij = i1*myJSize+aJ[j];
-       const StdMeshers_TNode& aTN1 = myTNodes[ij];
-       const SMDS_MeshNode* aN1 = aTN1.Node();
-       aN[j]=aN1;
-       //
-       ij=i2*myJSize+aJ[j];
-       const StdMeshers_TNode& aTN2 = myTNodes[ij];
-       const SMDS_MeshNode* aN2 = aTN2.Node();
-       aN[j+nbFaceNodes] = aN2;
+        ij = i1*myJSize+aJ[j];
+        const StdMeshers_TNode& aTN1 = myTNodes[ij];
+        const SMDS_MeshNode* aN1 = aTN1.Node();
+        aN[j]=aN1;
+        //
+        ij=i2*myJSize+aJ[j];
+        const StdMeshers_TNode& aTN2 = myTNodes[ij];
+        const SMDS_MeshNode* aN2 = aTN2.Node();
+        aN[j+nbFaceNodes] = aN2;
       }
       // check if volume orientation will be ok
       if ( i == 0 ) {
@@ -805,8 +777,6 @@ void StdMeshers_Penta_3D::MakeMeshOnFxy1()
     TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy0));
   const TopoDS_Face& aFxy1=
     TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy1));
-  SMESH_MesherHelper faceHelper( *GetMesh() );
-  faceHelper.IsQuadraticSubMesh(aFxy1);
   //
   SMESH_Mesh* pMesh = GetMesh();
   SMESHDS_Mesh * meshDS = pMesh->GetMeshDS();
@@ -820,7 +790,7 @@ void StdMeshers_Penta_3D::MakeMeshOnFxy1()
   itn = aSM0->GetNodes();
   aNbNodes = aSM0->NbNodes();
   //printf("** aNbNodes=%d\n", aNbNodes);
-
+  myTool->SetSubShape( aFxy1 ); // to set medium nodes to aFxy1
   //
   // set elements on aFxy1
   vector<const SMDS_MeshNode*> aNodes1;
@@ -849,7 +819,7 @@ void StdMeshers_Penta_3D::MakeMeshOnFxy1()
       aJ = GetIndexOnLayer(aID0);
       if (!myErrorStatus->IsOK()) {
         MESSAGE("StdMeshers_Penta_3D::MakeMeshOnFxy1() ");
-       return;
+        return;
       }
       //
       ij = aLevel*myJSize + aJ;
@@ -861,16 +831,17 @@ void StdMeshers_Penta_3D::MakeMeshOnFxy1()
     SMDS_MeshFace * face = 0;
     switch ( aNbNodes ) {
     case 3:
-      face = faceHelper.AddFace(aNodes1[0], aNodes1[1], aNodes1[2]);
+      face = myTool->AddFace(aNodes1[0], aNodes1[1], aNodes1[2]);
       break;
     case 4:
-      face = faceHelper.AddFace(aNodes1[0], aNodes1[1], aNodes1[2], aNodes1[3]);
+      face = myTool->AddFace(aNodes1[0], aNodes1[1], aNodes1[2], aNodes1[3]);
       break;
     default:
       continue;
     }
     meshDS->SetMeshElementOnShape(face, aFxy1);
   }
+  myTool->SetSubShape( myShape );
 
   // update compute state of top face submesh
   aSubMesh1->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
@@ -878,7 +849,8 @@ void StdMeshers_Penta_3D::MakeMeshOnFxy1()
   // assure that mesh on the top face will be cleaned when it is cleaned
   // on the bottom face
   SMESH_subMesh* volSM = pMesh->GetSubMesh( myTool->GetSubShape() );
-  volSM->SetEventListener( new SMESH_subMeshEventListener(true),
+  volSM->SetEventListener( new SMESH_subMeshEventListener(true, // deletable by SMESH_subMesh
+                                                          "StdMeshers_Penta_3D"),
                            SMESH_subMeshEventListenerData::MakeData( aSubMesh1 ),
                            aSubMesh0 ); // translate CLEAN event of aSubMesh0 to aSubMesh1
 }
@@ -937,8 +909,8 @@ void StdMeshers_Penta_3D::MakeConnectingMap()
 //purpose  : 
 //=======================================================================
 void StdMeshers_Penta_3D::CreateNode(const bool bIsUpperLayer,
-                                    const gp_XYZ& aParams,
-                                    StdMeshers_TNode& aTN)
+                                     const gp_XYZ& aParams,
+                                     StdMeshers_TNode& aTN)
 {
   double aX, aY, aZ;
   //
@@ -947,15 +919,15 @@ void StdMeshers_Penta_3D::CreateNode(const bool bIsUpperLayer,
   SMDS_MeshNode* pNode=NULL; 
   aTN.SetNode(pNode);  
   //
-//   if (bIsUpperLayer) {
-//     // point on face Fxy1
-//     const TopoDS_Shape& aS=myBlock.Shape(SMESH_Block::ID_Fxy1);
-//     myBlock.Point(aParams, aS, aP);
-//   }
-//   else {
-//     // point inside solid
-//     myBlock.Point(aParams, aP);
-//   }
+  //   if (bIsUpperLayer) {
+  //     // point on face Fxy1
+  //     const TopoDS_Shape& aS=myBlock.Shape(SMESH_Block::ID_Fxy1);
+  //     myBlock.Point(aParams, aS, aP);
+  //   }
+  //   else {
+  //     // point inside solid
+  //     myBlock.Point(aParams, aP);
+  //   }
   if (bIsUpperLayer) {
     double u = aParams.X(), v = aParams.Y();
     double u1 = ( 1. - u ), v1 = ( 1. - v );
@@ -973,11 +945,11 @@ void StdMeshers_Penta_3D::CreateNode(const bool bIsUpperLayer,
     SMESH_Block::ShellPoint( aParams, myShapeXYZ, aP.ChangeCoord() );
   }
   //
-//   iErr=myBlock.ErrorStatus();
-//   if (iErr) {
-//     myErrorStatus=12; // can not find the node point;
-//     return;
-//   }
+  //   iErr=myBlock.ErrorStatus();
+  //   if (iErr) {
+  //     myErrorStatus=12; // can not find the node point;
+  //     return;
+  //   }
   //
   aX=aP.X(); aY=aP.Y(); aZ=aP.Z(); 
   //
@@ -985,7 +957,7 @@ void StdMeshers_Penta_3D::CreateNode(const bool bIsUpperLayer,
   SMESHDS_Mesh* pMeshDS = pMesh->GetMeshDS();
   //
   pNode = pMeshDS->AddNode(aX, aY, aZ);
-  
+
   aTN.SetNode(pNode);
 }
 
@@ -994,42 +966,42 @@ void StdMeshers_Penta_3D::CreateNode(const bool bIsUpperLayer,
 //purpose  : 
 //=======================================================================
 void StdMeshers_Penta_3D::ShapeSupportID(const bool bIsUpperLayer,
-                                        const SMESH_Block::TShapeID aBNSSID,
-                                        SMESH_Block::TShapeID& aSSID)
+                                         const SMESH_Block::TShapeID aBNSSID,
+                                         SMESH_Block::TShapeID& aSSID)
 {
   switch (aBNSSID) {
-    case SMESH_Block::ID_V000:
-      aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_V001 : SMESH_Block::ID_E00z;
-      break;
-    case SMESH_Block::ID_V100:
-      aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_V101 : SMESH_Block::ID_E10z;
-      break; 
-    case SMESH_Block::ID_V110:
-      aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_V111 : SMESH_Block::ID_E11z;
-      break;
-    case SMESH_Block::ID_V010:
-      aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_V011 : SMESH_Block::ID_E01z;
-      break;
-    case SMESH_Block::ID_Ex00:
-      aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_Ex01 : SMESH_Block::ID_Fx0z;
-      break;
-    case SMESH_Block::ID_Ex10:
-      aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_Ex11 : SMESH_Block::ID_Fx1z;
-      break; 
-    case SMESH_Block::ID_E0y0:
-      aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_E0y1 : SMESH_Block::ID_F0yz;
-      break; 
-    case SMESH_Block::ID_E1y0:
-      aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_E1y1 : SMESH_Block::ID_F1yz;
-      break; 
-    case SMESH_Block::ID_Fxy0:
-      aSSID=SMESH_Block::ID_NONE;//(bIsUpperLayer) ?  Shape_ID_Fxy1 : Shape_ID_NONE;
-      break;   
-    default:
-      aSSID=SMESH_Block::ID_NONE;
-      myErrorStatus->myName=10; // Can not find supporting shape ID
-      myErrorStatus->myComment = "Internal error of StdMeshers_Penta_3D";
-      break;
+  case SMESH_Block::ID_V000:
+    aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_V001 : SMESH_Block::ID_E00z;
+    break;
+  case SMESH_Block::ID_V100:
+    aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_V101 : SMESH_Block::ID_E10z;
+    break; 
+  case SMESH_Block::ID_V110:
+    aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_V111 : SMESH_Block::ID_E11z;
+    break;
+  case SMESH_Block::ID_V010:
+    aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_V011 : SMESH_Block::ID_E01z;
+    break;
+  case SMESH_Block::ID_Ex00:
+    aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_Ex01 : SMESH_Block::ID_Fx0z;
+    break;
+  case SMESH_Block::ID_Ex10:
+    aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_Ex11 : SMESH_Block::ID_Fx1z;
+    break; 
+  case SMESH_Block::ID_E0y0:
+    aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_E0y1 : SMESH_Block::ID_F0yz;
+    break; 
+  case SMESH_Block::ID_E1y0:
+    aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_E1y1 : SMESH_Block::ID_F1yz;
+    break; 
+  case SMESH_Block::ID_Fxy0:
+    aSSID=SMESH_Block::ID_NONE;//(bIsUpperLayer) ?  Shape_ID_Fxy1 : Shape_ID_NONE;
+    break;   
+  default:
+    aSSID=SMESH_Block::ID_NONE;
+    myErrorStatus->myName=10; // Can not find supporting shape ID
+    myErrorStatus->myComment = "Internal error of StdMeshers_Penta_3D";
+    break;
   }
   return;
 }
@@ -1066,25 +1038,25 @@ void StdMeshers_Penta_3D::MakeBlock()
       const SMDS_MeshElement * pElement = itf->next();
       aElementType = pElement->GetType();
       if (aElementType==SMDSAbs_Face) {
-       iNbNodes = pElement->NbNodes();
-       if ( iNbNodes==3 || (myCreateQuadratic && iNbNodes==6) ) {
-         aFTr = aF;
-         ++iCnt;
-         if (iCnt>1) {
-           // \begin{E.A.}
-           // The current algorithm fails if there is more that one
-           // face wich contains triangles ...
-           // In that case, replace return by break to try another
-           // method (coded in "if (iCnt != 1) { ... }")
-           //
+        iNbNodes = pElement->NbNodes();
+        if ( iNbNodes==3 || (pElement->IsQuadratic() && iNbNodes==6) ) {
+          aFTr = aF;
+          ++iCnt;
+          if (iCnt>1) {
+            // \begin{E.A.}
+            // The current algorithm fails if there is more that one
+            // face wich contains triangles ...
+            // In that case, replace return by break to try another
+            // method (coded in "if (iCnt != 1) { ... }")
+            //
             // MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
-           // myErrorStatus=5; // more than one face has triangulation
-           // return;
-           break;
-           // \end{E.A.}
-         }
-         break; // next face
-       }
+            // myErrorStatus=5; // more than one face has triangulation
+            // return;
+            break;
+            // \end{E.A.}
+          }
+          break; // next face
+        }
       }
     }
   }
@@ -1153,85 +1125,85 @@ void StdMeshers_Penta_3D::MakeBlock()
       int has_only_quad_f6 = 1;
       //
       for (i=1; i<=iNbF; ++i) {
-       int ok = 1;
-       const TopoDS_Shape& aF = aM(i);
-       SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aF);
-       SMESHDS_SubMesh *aSM = aSubMesh->GetSubMeshDS();
-       SMDS_ElemIteratorPtr itf = aSM->GetElements();
-       while(itf->more()) {
-         const SMDS_MeshElement * pElement = itf->next();
-         aElementType = pElement->GetType();
-         if (aElementType==SMDSAbs_Face) {
-           iNbNodes = pElement->NbNodes();
-           if ( iNbNodes!=4 ) {
-             ok = 0;
-             break ;
-           }
-         }
-       }
-       if (i==1) has_only_quad_f1 = ok ;
-       if (i==2) has_only_quad_f2 = ok ;
-       if (i==3) has_only_quad_f3 = ok ;
-       if (i==4) has_only_quad_f4 = ok ;
-       if (i==5) has_only_quad_f5 = ok ;
-       if (i==6) has_only_quad_f6 = ok ;
+        int ok = 1;
+        const TopoDS_Shape& aF = aM(i);
+        SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aF);
+        SMESHDS_SubMesh *aSM = aSubMesh->GetSubMeshDS();
+        SMDS_ElemIteratorPtr itf = aSM->GetElements();
+        while(itf->more()) {
+          const SMDS_MeshElement * pElement = itf->next();
+          aElementType = pElement->GetType();
+          if (aElementType==SMDSAbs_Face) {
+            iNbNodes = pElement->NbNodes();
+            if ( iNbNodes!=4 ) {
+              ok = 0;
+              break ;
+            }
+          }
+        }
+        if (i==1) has_only_quad_f1 = ok ;
+        if (i==2) has_only_quad_f2 = ok ;
+        if (i==3) has_only_quad_f3 = ok ;
+        if (i==4) has_only_quad_f4 = ok ;
+        if (i==5) has_only_quad_f5 = ok ;
+        if (i==6) has_only_quad_f6 = ok ;
       }
       //
       TopTools_IndexedMapOfShape aE;
       TopExp::MapShapes(myShape, TopAbs_EDGE, aE);
       int iNbE = aE.Extent();
       if (iNbE == 12) {
-       //
-       int nb_e01 = pMesh->GetSubMeshContaining(aE(1))->GetSubMeshDS()->NbElements();
-       int nb_e02 = pMesh->GetSubMeshContaining(aE(2))->GetSubMeshDS()->NbElements();
-       int nb_e03 = pMesh->GetSubMeshContaining(aE(3))->GetSubMeshDS()->NbElements();
-       int nb_e04 = pMesh->GetSubMeshContaining(aE(4))->GetSubMeshDS()->NbElements();
-       int nb_e05 = pMesh->GetSubMeshContaining(aE(5))->GetSubMeshDS()->NbElements();
-       int nb_e06 = pMesh->GetSubMeshContaining(aE(6))->GetSubMeshDS()->NbElements();
-       int nb_e07 = pMesh->GetSubMeshContaining(aE(7))->GetSubMeshDS()->NbElements();
-       int nb_e08 = pMesh->GetSubMeshContaining(aE(8))->GetSubMeshDS()->NbElements();
-       int nb_e09 = pMesh->GetSubMeshContaining(aE(9))->GetSubMeshDS()->NbElements();
-       int nb_e10 = pMesh->GetSubMeshContaining(aE(10))->GetSubMeshDS()->NbElements();
-       int nb_e11 = pMesh->GetSubMeshContaining(aE(11))->GetSubMeshDS()->NbElements();
-       int nb_e12 = pMesh->GetSubMeshContaining(aE(12))->GetSubMeshDS()->NbElements();
-       //
-       int nb_ok = 0 ;
-       //
-       if ( (nb_e01==nb_e03) && (nb_e03==nb_e05) && (nb_e05==nb_e07) ) {
-         if ( has_only_quad_f1 && has_only_quad_f2 && has_only_quad_f3 && has_only_quad_f4 ) {
-           if ( (nb_e09==nb_e10) && (nb_e08==nb_e06) && (nb_e11==nb_e12) && (nb_e04==nb_e02) ) {
-             if (nb_f5==nb_f6) {
-               nb_ok += 1;
-               aFTr = aM(5);
-             }
-           }
-         }
-       }
-       if ( (nb_e02==nb_e04) && (nb_e04==nb_e06) && (nb_e06==nb_e08) ) {
-         if ( has_only_quad_f1 && has_only_quad_f2 && has_only_quad_f5 && has_only_quad_f6 ) {
-           if ( (nb_e01==nb_e03) && (nb_e10==nb_e12) && (nb_e05==nb_e07) && (nb_e09==nb_e11) ) {
-             if (nb_f3==nb_f4) {
-               nb_ok += 1;
-               aFTr = aM(3);
-             }
-           }
-         }
-       }
-       if ( (nb_e09==nb_e10) && (nb_e10==nb_e11) && (nb_e11==nb_e12) ) {
-         if ( has_only_quad_f3 && has_only_quad_f4 && has_only_quad_f5 && has_only_quad_f6 ) {
-           if ( (nb_e01==nb_e05) && (nb_e02==nb_e06) && (nb_e03==nb_e07) && (nb_e04==nb_e08) ) {
-             if (nb_f1==nb_f2) {
-               nb_ok += 1;
-               aFTr = aM(1);
-             }
-           }
-         }
-       }
-       //
-       if ( nb_ok == 1 ) {
-         isOK = 1;
-       }
-       //
+        //
+        int nb_e01 = pMesh->GetSubMeshContaining(aE(1))->GetSubMeshDS()->NbElements();
+        int nb_e02 = pMesh->GetSubMeshContaining(aE(2))->GetSubMeshDS()->NbElements();
+        int nb_e03 = pMesh->GetSubMeshContaining(aE(3))->GetSubMeshDS()->NbElements();
+        int nb_e04 = pMesh->GetSubMeshContaining(aE(4))->GetSubMeshDS()->NbElements();
+        int nb_e05 = pMesh->GetSubMeshContaining(aE(5))->GetSubMeshDS()->NbElements();
+        int nb_e06 = pMesh->GetSubMeshContaining(aE(6))->GetSubMeshDS()->NbElements();
+        int nb_e07 = pMesh->GetSubMeshContaining(aE(7))->GetSubMeshDS()->NbElements();
+        int nb_e08 = pMesh->GetSubMeshContaining(aE(8))->GetSubMeshDS()->NbElements();
+        int nb_e09 = pMesh->GetSubMeshContaining(aE(9))->GetSubMeshDS()->NbElements();
+        int nb_e10 = pMesh->GetSubMeshContaining(aE(10))->GetSubMeshDS()->NbElements();
+        int nb_e11 = pMesh->GetSubMeshContaining(aE(11))->GetSubMeshDS()->NbElements();
+        int nb_e12 = pMesh->GetSubMeshContaining(aE(12))->GetSubMeshDS()->NbElements();
+        //
+        int nb_ok = 0 ;
+        //
+        if ( (nb_e01==nb_e03) && (nb_e03==nb_e05) && (nb_e05==nb_e07) ) {
+          if ( has_only_quad_f1 && has_only_quad_f2 && has_only_quad_f3 && has_only_quad_f4 ) {
+            if ( (nb_e09==nb_e10) && (nb_e08==nb_e06) && (nb_e11==nb_e12) && (nb_e04==nb_e02) ) {
+              if (nb_f5==nb_f6) {
+                nb_ok += 1;
+                aFTr = aM(5);
+              }
+            }
+          }
+        }
+        if ( (nb_e02==nb_e04) && (nb_e04==nb_e06) && (nb_e06==nb_e08) ) {
+          if ( has_only_quad_f1 && has_only_quad_f2 && has_only_quad_f5 && has_only_quad_f6 ) {
+            if ( (nb_e01==nb_e03) && (nb_e10==nb_e12) && (nb_e05==nb_e07) && (nb_e09==nb_e11) ) {
+              if (nb_f3==nb_f4) {
+                nb_ok += 1;
+                aFTr = aM(3);
+              }
+            }
+          }
+        }
+        if ( (nb_e09==nb_e10) && (nb_e10==nb_e11) && (nb_e11==nb_e12) ) {
+          if ( has_only_quad_f3 && has_only_quad_f4 && has_only_quad_f5 && has_only_quad_f6 ) {
+            if ( (nb_e01==nb_e05) && (nb_e02==nb_e06) && (nb_e03==nb_e07) && (nb_e04==nb_e08) ) {
+              if (nb_f1==nb_f2) {
+                nb_ok += 1;
+                aFTr = aM(1);
+              }
+            }
+          }
+        }
+        //
+        if ( nb_ok == 1 ) {
+          isOK = 1;
+        }
+        //
       }
     }
     if (!isOK) {
@@ -1284,11 +1256,11 @@ void StdMeshers_Penta_3D::MakeBlock()
       const TopoDS_Edge& aE=TopoDS::Edge(aEx);
       TopExp::Vertices(aE, aV[0], aV[1]);
       for (i=0; i<2; ++i) {
-       if (!aV[i].IsSame(aV000)) {
-         aV001=aV[i];
-         bFound=!bFound;
-         break;
-       }
+        if (!aV[i].IsSame(aV000)) {
+          aV001=aV[i];
+          bFound=!bFound;
+          break;
+        }
       }
     }
   }
@@ -1365,8 +1337,8 @@ void StdMeshers_Penta_3D::CheckData()
     iNb=aM.Extent();
     if (iNb!=iNbEx[i]){
       MESSAGE("StdMeshers_Penta_3D::CheckData() ");
-      myErrorStatus->myName=4; // number of subshape is not compatible
-      myErrorStatus->myComment="Wrong number of subshapes of a block";
+      myErrorStatus->myName=4; // number of sub-shape is not compatible
+      myErrorStatus->myComment="Wrong number of sub-shapes of a block";
       return;
     }
   }
@@ -1432,7 +1404,7 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes,
   SMESHDS_SubMesh* smVft = theMesh->MeshElements( vft );
   if (!smFace || !smb || !smt || !sm1 || !sm2 || !smVfb || !smVlb || !smVft ) {
     MESSAGE( "NULL submesh " <<smFace<<" "<<smb<<" "<<smt<<" "<<
-            sm1<<" "<<sm2<<" "<<smVfb<<" "<<smVlb<<" "<<smVft);
+             sm1<<" "<<sm2<<" "<<smVfb<<" "<<smVlb<<" "<<smVft);
     return false;
   }
   if ( smb->NbNodes() != smt->NbNodes() || sm1->NbNodes() != sm2->NbNodes() ) {
@@ -1453,13 +1425,13 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes,
       int nf = sm1->NbNodes()*smb->NbNodes() - n3*n4;
       if( nf != smFace->NbNodes() ) {
         MESSAGE( "Wrong nb face nodes: " <<
-                sm1->NbNodes()<<" "<<smb->NbNodes()<<" "<<smFace->NbNodes());
+                 sm1->NbNodes()<<" "<<smb->NbNodes()<<" "<<smFace->NbNodes());
         return false;
       }
     }
     else {
       MESSAGE( "Wrong nb face nodes: " <<
-              sm1->NbNodes()<<" "<<smb->NbNodes()<<" "<<smFace->NbNodes());
+               sm1->NbNodes()<<" "<<smb->NbNodes()<<" "<<smFace->NbNodes());
       return false;
     }
   }
@@ -1494,7 +1466,7 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes,
     if(myTool->IsMedium(node))
       continue;
     const SMDS_EdgePosition* pos =
-      dynamic_cast<const SMDS_EdgePosition*>( node->GetPosition().get() );
+      dynamic_cast<const SMDS_EdgePosition*>( node->GetPosition() );
     if ( !pos ) {
       return false;
     }
@@ -1517,7 +1489,7 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes,
     if(myTool->IsMedium(node))
       continue;
     const SMDS_EdgePosition* pos =
-      dynamic_cast<const SMDS_EdgePosition*>( node->GetPosition().get() );
+      dynamic_cast<const SMDS_EdgePosition*>( node->GetPosition() );
     if ( !pos ) {
       return false;
     }
@@ -1594,7 +1566,7 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes,
           }
         }
         else if ( (nbFaceNodes==3 || (myCreateQuadratic && nbFaceNodes==6) )  &&
-                 n3 == par_nVec_1->second[ row ] ) {
+                  n3 == par_nVec_1->second[ row ] ) {
           n1 = n3;
         }
         else {
@@ -1678,7 +1650,7 @@ SMESH_ComputeErrorPtr StdMeshers_SMESHBlock::GetError() const
   case 3: text = "Internal error of StdMeshers_Penta_3D"; break; 
   case 4: text = "Can't compute normalized parameters of a point inside a block"; break;
   case 5: text = "Can't compute coordinates by normalized parameters inside a block"; break;
-  case 6: text = "Can't detect block subshapes. Not a block?"; break;
+  case 6: text = "Can't detect block sub-shapes. Not a block?"; break;
   }
   if (!text.empty())
     err->myName = myErrorStatus;
@@ -1701,8 +1673,8 @@ void StdMeshers_SMESHBlock::Load(const TopoDS_Shell& theShell)
 //purpose  : 
 //=======================================================================
 void StdMeshers_SMESHBlock::Load(const TopoDS_Shell& theShell,
-                                const TopoDS_Vertex& theV000,
-                                const TopoDS_Vertex& theV001)
+                                 const TopoDS_Vertex& theV000,
+                                 const TopoDS_Vertex& theV001)
 {
   myErrorStatus=0;
   //
@@ -1723,7 +1695,7 @@ void StdMeshers_SMESHBlock::Load(const TopoDS_Shell& theShell,
 //purpose  : 
 //=======================================================================
 void StdMeshers_SMESHBlock::ComputeParameters(const gp_Pnt& thePnt, 
-                                             gp_XYZ& theXYZ)
+                                              gp_XYZ& theXYZ)
 {
   ComputeParameters(thePnt, myShell, theXYZ);
 }
@@ -1733,7 +1705,7 @@ void StdMeshers_SMESHBlock::ComputeParameters(const gp_Pnt& thePnt,
 //purpose  : 
 //=======================================================================
 void StdMeshers_SMESHBlock::ComputeParameters(const gp_Pnt& thePnt,
-                                             const TopoDS_Shape& theShape,
+                                              const TopoDS_Shape& theShape,
                                               gp_XYZ& theXYZ)
 {
   myErrorStatus=0;
@@ -1771,7 +1743,7 @@ void StdMeshers_SMESHBlock::ComputeParameters(const double& theU,
     return;
   }
   if ( SMESH_Block::IsEdgeID( aID ))
-      bOk = myTBlock.EdgeParameters( aID, theU, theXYZ );
+    bOk = myTBlock.EdgeParameters( aID, theU, theXYZ );
   if (!bOk) {
     myErrorStatus=4; // problems with computation Parameters 
     return;
@@ -1782,8 +1754,7 @@ void StdMeshers_SMESHBlock::ComputeParameters(const double& theU,
 //function : Point
 //purpose  : 
 //=======================================================================
- void StdMeshers_SMESHBlock::Point(const gp_XYZ& theParams,
-                                  gp_Pnt& aP3D)
+void StdMeshers_SMESHBlock::Point(const gp_XYZ& theParams, gp_Pnt& aP3D)
 {
   TopoDS_Shape aS;
   //
@@ -1794,9 +1765,9 @@ void StdMeshers_SMESHBlock::ComputeParameters(const double& theU,
 //function : Point
 //purpose  : 
 //=======================================================================
- void StdMeshers_SMESHBlock::Point(const gp_XYZ& theParams,
-                                  const TopoDS_Shape& theShape,
-                                  gp_Pnt& aP3D)
+void StdMeshers_SMESHBlock::Point(const gp_XYZ& theParams,
+                                  const TopoDS_Shape& theShape,
+                                  gp_Pnt& aP3D)
 {
   myErrorStatus = 0;
   //
@@ -1882,3 +1853,112 @@ const TopoDS_Shape& StdMeshers_SMESHBlock::Shape(const int theID)
 }
 
 
+//=======================================================================
+//function : Evaluate
+//purpose  : 
+//=======================================================================
+bool StdMeshers_Penta_3D::Evaluate(SMESH_Mesh& aMesh, 
+                                   const TopoDS_Shape& aShape,
+                                   MapShapeNbElems& aResMap)
+{
+  MESSAGE("StdMeshers_Penta_3D::Evaluate()");
+
+  // find face contains only triangles
+  vector < SMESH_subMesh * >meshFaces;
+  TopTools_SequenceOfShape aFaces;
+  int NumBase = 0, i = 0;
+  for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
+    i++;
+    aFaces.Append(exp.Current());
+    SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current());
+    meshFaces.push_back(aSubMesh);
+    MapShapeNbElemsItr anIt = aResMap.find(meshFaces[i]);
+    if( anIt == aResMap.end() ) {
+      NumBase = 0;
+      break;
+    }
+    std::vector<int> aVec = (*anIt).second;
+    int nbtri = Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]);
+    int nbqua = Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]);
+    if( nbtri>0 && nbqua==0 ) {
+      NumBase = i;
+    }
+  }
+
+  if(NumBase==0) {
+    std::vector<int> aResVec(SMDSEntity_Last);
+    for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
+    SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+    aResMap.insert(std::make_pair(sm,aResVec));
+    myErrorStatus->myName    = COMPERR_ALGO_FAILED;
+    myErrorStatus->myComment = "Submesh can not be evaluated";
+    return false;
+  }
+
+  // find number of 1d elems for base face
+  int nb1d = 0;
+  TopTools_MapOfShape Edges1;
+  for (TopExp_Explorer exp(aFaces.Value(NumBase), TopAbs_EDGE); exp.More(); exp.Next()) {
+    Edges1.Add(exp.Current());
+    SMESH_subMesh *sm = aMesh.GetSubMesh(exp.Current());
+    if( sm ) {
+      MapShapeNbElemsItr anIt = aResMap.find(sm);
+      if( anIt == aResMap.end() ) continue;
+      std::vector<int> aVec = (*anIt).second;
+      nb1d += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]);
+    }
+  }
+  // find face opposite to base face
+  int OppNum = 0;
+  for(i=1; i<=6; i++) {
+    if(i==NumBase) continue;
+    bool IsOpposite = true;
+    for(TopExp_Explorer exp(aFaces.Value(i), TopAbs_EDGE); exp.More(); exp.Next()) {
+      if( Edges1.Contains(exp.Current()) ) {
+        IsOpposite = false;
+        break;
+      }
+    }
+    if(IsOpposite) {
+      OppNum = i;
+      break;
+    }
+  }
+  // find number of 2d elems on side faces
+  int nb2d = 0;
+  for(i=1; i<=6; i++) {
+    if( i==OppNum || i==NumBase ) continue;
+    MapShapeNbElemsItr anIt = aResMap.find( meshFaces[i-1] );
+    if( anIt == aResMap.end() ) continue;
+    std::vector<int> aVec = (*anIt).second;
+    nb2d += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]);
+  }
+
+  MapShapeNbElemsItr anIt = aResMap.find( meshFaces[NumBase-1] );
+  std::vector<int> aVec = (*anIt).second;
+  int nb2d_face0 = Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]);
+  int nb0d_face0 = aVec[SMDSEntity_Node];
+
+  anIt = aResMap.find( meshFaces[OppNum-1] );
+  for(i=SMDSEntity_Node; i<SMDSEntity_Last; i++)
+    (*anIt).second[i] = aVec[i];
+
+  SMESH_MesherHelper aTool (aMesh);
+  bool _quadraticMesh = aTool.IsQuadraticSubMesh(aShape);
+
+  std::vector<int> aResVec(SMDSEntity_Last);
+  for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
+  if(_quadraticMesh) {
+    aResVec[SMDSEntity_Quad_Penta] = nb2d_face0 * ( nb2d/nb1d );
+    aResVec[SMDSEntity_Node] = nb0d_face0 * ( 2*nb2d/nb1d - 1 );
+  }
+  else {
+    aResVec[SMDSEntity_Node] = nb0d_face0 * ( nb2d/nb1d - 1 );
+    aResVec[SMDSEntity_Penta] = nb2d_face0 * ( nb2d/nb1d );
+  }
+  SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+  aResMap.insert(std::make_pair(sm,aResVec));
+
+  return true;
+}
+
index f061f81443a5f2e8b21c9e1ba93d3c0e000bbaba..5d23368cc5f6a2659d59d6775e9c53817f5f927d 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH StdMeshers : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_Penta_3D.hxx
 //  Module : SMESH
@@ -45,6 +46,7 @@
 #include "SMESH_Block.hxx"
 #include "SMESH_ComputeError.hxx"
 #include "SMESH_MesherHelper.hxx"
+#include "SMESH_3D_Algo.hxx"
 
 typedef std::map< double, std::vector<const SMDS_MeshNode*> > StdMeshers_IJNodeMap;
 
@@ -57,26 +59,26 @@ public:
   void Load (const TopoDS_Shell& theShell);
   
   void Load (const TopoDS_Shell& theShell,
-            const TopoDS_Vertex& theV000,
-            const TopoDS_Vertex& theV001);
+             const TopoDS_Vertex& theV000,
+             const TopoDS_Vertex& theV001);
   
   void ComputeParameters(const gp_Pnt& thePnt, 
-                        gp_XYZ& theXYZ);
+                         gp_XYZ& theXYZ);
   
   void ComputeParameters(const gp_Pnt& thePnt,
-                        const TopoDS_Shape& theShape,
-                        gp_XYZ& theXYZ);
+                         const TopoDS_Shape& theShape,
+                         gp_XYZ& theXYZ);
   
   void ComputeParameters(const double& theU,
-                        const TopoDS_Shape& theShape,
-                        gp_XYZ& theXYZ);
+                         const TopoDS_Shape& theShape,
+                         gp_XYZ& theXYZ);
   
   void Point(const gp_XYZ& theParams, 
-            gp_Pnt& thePnt);
+             gp_Pnt& thePnt);
   
   void Point(const gp_XYZ& theParams,
-            const TopoDS_Shape& theShape, 
-            gp_Pnt& thePnt);
+             const TopoDS_Shape& theShape, 
+             gp_Pnt& thePnt);
   
   int ShapeID(const TopoDS_Shape& theShape); 
   
@@ -204,6 +206,9 @@ class STDMESHERS_EXPORT StdMeshers_Penta_3D {
     // The key of theIJNodes map is a normalized parameter of each
     // 0-the node on theBaseEdge.
 
+    bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                  MapShapeNbElems& aResMap);
+
 
   protected: // methods
     
@@ -219,17 +224,17 @@ class STDMESHERS_EXPORT StdMeshers_Penta_3D {
                            std::vector<const SMDS_MeshNode*>*& aCol2);
 
     void ShapeSupportID(const bool theIsUpperLayer,
-                       const SMESH_Block::TShapeID theBNSSID,
-                       SMESH_Block::TShapeID& theSSID);
+                        const SMESH_Block::TShapeID theBNSSID,
+                        SMESH_Block::TShapeID& theSSID);
 
     void FindNodeOnShape(const TopoDS_Shape& aS,
-                        const gp_XYZ& aParams,
+                         const gp_XYZ& aParams,
                          const int z,
-                        StdMeshers_TNode& aTN);
+                         StdMeshers_TNode& aTN);
 
     void CreateNode(const bool theIsUpperLayer,
-                   const gp_XYZ& aParams,
-                   StdMeshers_TNode& aTN);
+                    const gp_XYZ& aParams,
+                    StdMeshers_TNode& aTN);
 
     void ClearMeshOnFxy1();
 
index 2ab01d917da4b265b2bd05658db1a9acc0ecdb04..c4c421c80f307aa0d1519d342eef174dfd097a03 100644 (file)
@@ -1,25 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-//  SMESH SMESH : implementaion of SMESH idl descriptions
+
 // File      : StdMeshers_Prism_3D.cxx
 // Module    : SMESH
 // Created   : Fri Oct 20 11:37:07 2006
@@ -28,7 +28,7 @@
 #include "StdMeshers_Prism_3D.hxx"
 
 #include "StdMeshers_ProjectionUtils.hxx"
-#include "SMESH_MeshEditor.hxx"
+#include "SMESH_MesherHelper.hxx"
 #include "SMDS_VolumeTool.hxx"
 #include "SMDS_VolumeOfNodes.hxx"
 #include "SMDS_EdgePosition.hxx"
 #include "utilities.h"
 
 #include <BRep_Tool.hxx>
+#include <Bnd_B3d.hxx>
 #include <Geom2dAdaptor_Curve.hxx>
 #include <Geom2d_Line.hxx>
+#include <Geom_Curve.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <TopTools_SequenceOfShape.hxx>
 #include <TopoDS.hxx>
+#include <gp_Ax2.hxx>
+#include <gp_Ax3.hxx>
 
 using namespace std;
 
@@ -149,6 +155,152 @@ namespace {
     }
     params.push_back( parLast ); // 1.
   }
+
+  //================================================================================
+  /*!
+   * \brief Return coordinate system for z-th layer of nodes
+   */
+  //================================================================================
+
+  gp_Ax2 getLayerCoordSys(const int                           z,
+                          const vector< const TNodeColumn* >& columns,
+                          int&                                xColumn)
+  {
+    // gravity center of a layer
+    gp_XYZ O(0,0,0);
+    int vertexCol = -1;
+    for ( int i = 0; i < columns.size(); ++i )
+    {
+      O += gpXYZ( (*columns[ i ])[ z ]);
+      if ( vertexCol < 0 &&
+           columns[ i ]->front()->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX )
+        vertexCol = i;
+    }
+    O /= columns.size();
+
+    // Z axis
+    gp_Vec Z(0,0,0);
+    int iPrev = columns.size()-1;
+    for ( int i = 0; i < columns.size(); ++i )
+    {
+      gp_Vec v1( O, gpXYZ( (*columns[ iPrev ])[ z ]));
+      gp_Vec v2( O, gpXYZ( (*columns[ i ]    )[ z ]));
+      Z += v1 ^ v2;
+      iPrev = i;
+    }
+
+    if ( vertexCol >= 0 )
+    {
+      O = gpXYZ( (*columns[ vertexCol ])[ z ]);
+    }
+    if ( xColumn < 0 || xColumn >= columns.size() )
+    {
+      // select a column for X dir
+      double maxDist = 0;
+      for ( int i = 0; i < columns.size(); ++i )
+      {
+        double dist = ( O - gpXYZ((*columns[ i ])[ z ])).SquareModulus();
+        if ( dist > maxDist )
+        {
+          xColumn = i;
+          maxDist = dist;
+        }
+      }
+    }
+
+    // X axis
+    gp_Vec X( O, gpXYZ( (*columns[ xColumn ])[ z ]));
+
+    return gp_Ax2( O, Z, X);
+  }
+
+  //================================================================================
+  /*!
+   * \brief Removes submeshes meshed with regular grid from given list
+   *  \retval int - nb of removed submeshes
+   */
+  //================================================================================
+
+  int removeQuasiQuads(list< SMESH_subMesh* >& notQuadSubMesh)
+  {
+    int oldNbSM = notQuadSubMesh.size();
+    SMESHDS_Mesh* mesh = notQuadSubMesh.front()->GetFather()->GetMeshDS();
+    list< SMESH_subMesh* >::iterator smIt = notQuadSubMesh.begin();
+#define __NEXT_SM { ++smIt; continue; }
+    while ( smIt != notQuadSubMesh.end() )
+    {
+      SMESH_subMesh* faceSm = *smIt;
+      SMESHDS_SubMesh* faceSmDS = faceSm->GetSubMeshDS();
+      int nbQuads = faceSmDS->NbElements();
+      if ( nbQuads == 0 ) __NEXT_SM;
+
+      // get oredered edges
+      list< TopoDS_Edge > orderedEdges;
+      list< int >         nbEdgesInWires;
+      TopoDS_Vertex       V000;
+      int nbWires = SMESH_Block::GetOrderedEdges( TopoDS::Face( faceSm->GetSubShape() ),
+                                                  V000, orderedEdges, nbEdgesInWires );
+      if ( nbWires != 1 || nbEdgesInWires.front() <= 4 )
+        __NEXT_SM;
+
+      // get nb of segements on edges
+      list<int> nbSegOnEdge;
+      list< TopoDS_Edge >::iterator edge = orderedEdges.begin();
+      for ( ; edge != orderedEdges.end(); ++edge )
+      {
+        if ( SMESHDS_SubMesh* edgeSmDS = mesh->MeshElements( *edge ))
+          nbSegOnEdge.push_back( edgeSmDS->NbElements() );
+        else
+          nbSegOnEdge.push_back(0);
+      }
+
+      // unite nbSegOnEdge of continues edges
+      int nbEdges = nbEdgesInWires.front();
+      list<int>::iterator nbSegIt = nbSegOnEdge.begin();
+      for ( edge = orderedEdges.begin(); edge != orderedEdges.end(); )
+      {
+        const TopoDS_Edge& e1 = *edge++;
+        const TopoDS_Edge& e2 = ( edge == orderedEdges.end() ? orderedEdges.front() : *edge );
+        if ( SMESH_Algo::IsContinuous( e1, e2 ))
+        {
+          // common vertex of continues edges must be shared by two 2D mesh elems of geom face
+          TopoDS_Vertex vCommon = TopExp::LastVertex( e1, true );
+          const SMDS_MeshNode* vNode = SMESH_Algo::VertexNode( vCommon, mesh );
+          int nbF = 0;
+          if ( vNode )
+          {
+            SMDS_ElemIteratorPtr fIt = vNode->GetInverseElementIterator(SMDSAbs_Face);
+            while ( fIt->more() )
+              nbF += faceSmDS->Contains( fIt->next() );
+          }
+          list<int>::iterator nbSegIt1 = nbSegIt++;
+          if ( !vNode || nbF == 2 ) // !vNode - two edges can be meshed as one
+          {
+            // unite
+            if ( nbSegIt == nbSegOnEdge.end() ) nbSegIt = nbSegOnEdge.begin();
+            *nbSegIt += *nbSegIt1;
+            nbSegOnEdge.erase( nbSegIt1 );
+            --nbEdges;
+          }
+        }
+        else
+        {
+          ++nbSegIt;
+        }
+      }
+      vector<int> nbSegVec( nbSegOnEdge.begin(), nbSegOnEdge.end());
+      if ( nbSegVec.size() == 4 &&
+           nbSegVec[0] == nbSegVec[2] &&
+           nbSegVec[1] == nbSegVec[3] &&
+           nbSegVec[0] * nbSegVec[1] == nbQuads
+           )
+        smIt = notQuadSubMesh.erase( smIt );
+      else
+        __NEXT_SM;
+    }
+
+    return oldNbSM - notQuadSubMesh.size();
+  }
 }
 
 //=======================================================================
@@ -160,7 +312,7 @@ StdMeshers_Prism_3D::StdMeshers_Prism_3D(int hypId, int studyId, SMESH_Gen* gen)
   :SMESH_3D_Algo(hypId, studyId, gen)
 {
   _name = "Prism_3D";
-  _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);      // 1 bit per shape type
+  _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);       // 1 bit per shape type
   myProjectTriangles = false;
 }
 
@@ -232,7 +384,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
 
   myHelper->IsQuadraticSubMesh( theShape );
 
-  // Analyse mesh and geomerty to find block subshapes and submeshes
+  // Analyse mesh and geomerty to find block sub-shapes and submeshes
   if ( !myBlock.Init( myHelper, theShape ))
     return error( myBlock.GetError());
 
@@ -255,75 +407,115 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
   // Projections on the top and bottom faces are taken from nodes existing
   // on these faces; find correspondence between bottom and top nodes
   myBotToColumnMap.clear();
-  if ( !assocOrProjBottom2Top() ) // it also fill myBotToColumnMap
+  if ( !assocOrProjBottom2Top() ) // it also fills myBotToColumnMap
     return false;
 
 
   // Create nodes inside the block
 
-  // loop on nodes inside the bottom face
-  TNode2ColumnMap::iterator bot_column = myBotToColumnMap.begin();
-  for ( ; bot_column != myBotToColumnMap.end(); ++bot_column )
+  // try to use transformation (issue 0020680)
+  vector<gp_Trsf> trsf;
+  if ( myBlock.GetLayersTransformation(trsf))
   {
-    const TNode& tBotNode = bot_column->first; // bottom TNode
-    if ( tBotNode.GetPositionType() != SMDS_TOP_FACE )
-      continue; // node is not inside face 
-
-    // column nodes; middle part of the column are zero pointers
-    TNodeColumn& column = bot_column->second;
-
-    // bottom node parameters and coords
-    myShapeXYZ[ ID_BOT_FACE ] = tBotNode.GetCoords();
-    gp_XYZ botParams          = tBotNode.GetParams();
-
-    // compute top node parameters
-    myShapeXYZ[ ID_TOP_FACE ] = gpXYZ( column.back() );
-    gp_XYZ topParams = botParams;
-    topParams.SetZ( 1 );
-    if ( column.size() > 2 ) {
-      gp_Pnt topCoords = myShapeXYZ[ ID_TOP_FACE ];
-      if ( !myBlock.ComputeParameters( topCoords, topParams, ID_TOP_FACE, topParams ))
-        return error(TCom("Can't compute normalized parameters ")
-                     << "for node " << column.back()->GetID()
-                     << " on the face #"<< column.back()->GetPosition()->GetShapeId() );
-    }
+    // loop on nodes inside the bottom face
+    TNode2ColumnMap::iterator bot_column = myBotToColumnMap.begin();
+    for ( ; bot_column != myBotToColumnMap.end(); ++bot_column )
+    {
+      const TNode& tBotNode = bot_column->first; // bottom TNode
+      if ( tBotNode.GetPositionType() != SMDS_TOP_FACE )
+        continue; // node is not inside face 
+
+      // column nodes; middle part of the column are zero pointers
+      TNodeColumn& column = bot_column->second;
+      TNodeColumn::iterator columnNodes = column.begin();
+      for ( int z = 0; columnNodes != column.end(); ++columnNodes, ++z)
+      {
+        const SMDS_MeshNode* & node = *columnNodes;
+        if ( node ) continue; // skip bottom or top node
 
-    // vertical loop
-    TNodeColumn::iterator columnNodes = column.begin();
-    for ( int z = 0; columnNodes != column.end(); ++columnNodes, ++z)
+        gp_XYZ coords = tBotNode.GetCoords();
+        trsf[z-1].Transforms( coords );
+        node = meshDS->AddNode( coords.X(), coords.Y(), coords.Z() );
+        meshDS->SetNodeInVolume( node, volumeID );
+      }
+    } // loop on bottom nodes
+  }
+  else // use block approach
+  {
+    // loop on nodes inside the bottom face
+    TNode prevBNode;
+    TNode2ColumnMap::iterator bot_column = myBotToColumnMap.begin();
+    for ( ; bot_column != myBotToColumnMap.end(); ++bot_column )
     {
-      const SMDS_MeshNode* & node = *columnNodes;
-      if ( node ) continue; // skip bottom or top node
-
-      // params of a node to create
-      double rz = (double) z / (double) ( column.size() - 1 );
-      gp_XYZ params = botParams * ( 1 - rz ) + topParams * rz;
-
-      // set coords on all faces and nodes
-      const int nbSideFaces = 4;
-      int sideFaceIDs[nbSideFaces] = { SMESH_Block::ID_Fx0z,
-                                       SMESH_Block::ID_Fx1z,
-                                       SMESH_Block::ID_F0yz,
-                                       SMESH_Block::ID_F1yz };
-      for ( int iF = 0; iF < nbSideFaces; ++iF )
-        if ( !setFaceAndEdgesXYZ( sideFaceIDs[ iF ], params, z ))
-          return false;
-
-      // compute coords for a new node
-      gp_XYZ coords;
-      if ( !SMESH_Block::ShellPoint( params, myShapeXYZ, coords ))
-        return error("Can't compute coordinates by normalized parameters");
-
-      SHOWYXZ("TOPFacePoint ",myShapeXYZ[ ID_TOP_FACE]);
-      SHOWYXZ("BOT Node "<< tBotNode.myNode->GetID(),gpXYZ(tBotNode.myNode));
-      SHOWYXZ("ShellPoint ",coords);
-
-      // create a node
-      node = meshDS->AddNode( coords.X(), coords.Y(), coords.Z() );
-      meshDS->SetNodeInVolume( node, volumeID );
-    }
-  } // loop on bottom nodes
+      const TNode& tBotNode = bot_column->first; // bottom TNode
+      if ( tBotNode.GetPositionType() != SMDS_TOP_FACE )
+        continue; // node is not inside face 
+
+      // column nodes; middle part of the column are zero pointers
+      TNodeColumn& column = bot_column->second;
+
+      // compute bottom node parameters
+      gp_XYZ paramHint(-1,-1,-1);
+      if ( prevBNode.IsNeighbor( tBotNode ))
+        paramHint = prevBNode.GetParams();
+      if ( !myBlock.ComputeParameters( tBotNode.GetCoords(), tBotNode.ChangeParams(),
+                                       ID_BOT_FACE, paramHint ))
+        return error(TCom("Can't compute normalized parameters for node ")
+                     << tBotNode.myNode->GetID() << " on the face #"
+                     << myBlock.SubMesh( ID_BOT_FACE )->GetId() );
+      prevBNode = tBotNode;
+
+      myShapeXYZ[ ID_BOT_FACE ] = tBotNode.GetCoords();
+      gp_XYZ botParams          = tBotNode.GetParams();
+
+      // compute top node parameters
+      myShapeXYZ[ ID_TOP_FACE ] = gpXYZ( column.back() );
+      gp_XYZ topParams = botParams;
+      topParams.SetZ( 1 );
+      if ( column.size() > 2 ) {
+        gp_Pnt topCoords = myShapeXYZ[ ID_TOP_FACE ];
+        if ( !myBlock.ComputeParameters( topCoords, topParams, ID_TOP_FACE, topParams ))
+          return error(TCom("Can't compute normalized parameters ")
+                       << "for node " << column.back()->GetID()
+                       << " on the face #"<< column.back()->getshapeId() );
+      }
 
+      // vertical loop
+      TNodeColumn::iterator columnNodes = column.begin();
+      for ( int z = 0; columnNodes != column.end(); ++columnNodes, ++z)
+      {
+        const SMDS_MeshNode* & node = *columnNodes;
+        if ( node ) continue; // skip bottom or top node
+
+        // params of a node to create
+        double rz = (double) z / (double) ( column.size() - 1 );
+        gp_XYZ params = botParams * ( 1 - rz ) + topParams * rz;
+
+        // set coords on all faces and nodes
+        const int nbSideFaces = 4;
+        int sideFaceIDs[nbSideFaces] = { SMESH_Block::ID_Fx0z,
+                                         SMESH_Block::ID_Fx1z,
+                                         SMESH_Block::ID_F0yz,
+                                         SMESH_Block::ID_F1yz };
+        for ( int iF = 0; iF < nbSideFaces; ++iF )
+          if ( !setFaceAndEdgesXYZ( sideFaceIDs[ iF ], params, z ))
+            return false;
+
+        // compute coords for a new node
+        gp_XYZ coords;
+        if ( !SMESH_Block::ShellPoint( params, myShapeXYZ, coords ))
+          return error("Can't compute coordinates by normalized parameters");
+
+        SHOWYXZ("TOPFacePoint ",myShapeXYZ[ ID_TOP_FACE]);
+        SHOWYXZ("BOT Node "<< tBotNode.myNode->GetID(),gpXYZ(tBotNode.myNode));
+        SHOWYXZ("ShellPoint ",coords);
+
+        // create a node
+        node = meshDS->AddNode( coords.X(), coords.Y(), coords.Z() );
+        meshDS->SetNodeInVolume( node, volumeID );
+      }
+    } // loop on bottom nodes
+  }
 
   // Create volumes
 
@@ -347,7 +539,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
     {
       const SMDS_MeshNode* n = face->GetNode( i );
       if ( n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ) {
-        bot_column = myBotToColumnMap.find( n );
+        TNode2ColumnMap::iterator bot_column = myBotToColumnMap.find( n );
         if ( bot_column == myBotToColumnMap.end() )
           return error(TCom("No nodes found above node ") << n->GetID() );
         columns[ i ] = & bot_column->second;
@@ -362,10 +554,129 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
     AddPrisms( columns, myHelper );
 
   } // loop on bottom mesh faces
+
+  // clear data
+  myBotToColumnMap.clear();
+  myBlock.Clear();
         
   return true;
 }
 
+
+//=======================================================================
+//function : Evaluate
+//purpose  : 
+//=======================================================================
+
+bool StdMeshers_Prism_3D::Evaluate(SMESH_Mesh& theMesh,
+                                   const TopoDS_Shape& theShape,
+                                   MapShapeNbElems& aResMap)
+{
+  // find face contains only triangles
+  vector < SMESH_subMesh * >meshFaces;
+  TopTools_SequenceOfShape aFaces;
+  int NumBase = 0, i = 0, NbQFs = 0;
+  for (TopExp_Explorer exp(theShape, TopAbs_FACE); exp.More(); exp.Next()) {
+    i++;
+    aFaces.Append(exp.Current());
+    SMESH_subMesh *aSubMesh = theMesh.GetSubMesh(exp.Current());
+    meshFaces.push_back(aSubMesh);
+    MapShapeNbElemsItr anIt = aResMap.find(meshFaces[i-1]);
+    if( anIt==aResMap.end() ) {
+      SMESH_ComputeErrorPtr& smError = aSubMesh->GetComputeError();
+      smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
+      return false;
+    }
+    std::vector<int> aVec = (*anIt).second;
+    int nbtri = Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]);
+    int nbqua = Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]);
+    if( nbtri==0 && nbqua>0 ) {
+      NbQFs++;
+    }
+    if( nbtri>0 ) {
+      NumBase = i;
+    }
+  }
+
+  if(NbQFs<4) {
+    std::vector<int> aResVec(SMDSEntity_Last);
+    for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
+    SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
+    aResMap.insert(std::make_pair(sm,aResVec));
+    SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+    smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
+    return false;
+  }
+
+  if(NumBase==0) NumBase = 1; // only quads => set 1 faces as base
+
+  // find number of 1d elems for base face
+  int nb1d = 0;
+  TopTools_MapOfShape Edges1;
+  for (TopExp_Explorer exp(aFaces.Value(NumBase), TopAbs_EDGE); exp.More(); exp.Next()) {
+    Edges1.Add(exp.Current());
+    SMESH_subMesh *sm = theMesh.GetSubMesh(exp.Current());
+    if( sm ) {
+      MapShapeNbElemsItr anIt = aResMap.find(sm);
+      if( anIt == aResMap.end() ) continue;
+      std::vector<int> aVec = (*anIt).second;
+      nb1d += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]);
+    }
+  }
+  // find face opposite to base face
+  int OppNum = 0;
+  for(i=1; i<=6; i++) {
+    if(i==NumBase) continue;
+    bool IsOpposite = true;
+    for(TopExp_Explorer exp(aFaces.Value(i), TopAbs_EDGE); exp.More(); exp.Next()) {
+      if( Edges1.Contains(exp.Current()) ) {
+        IsOpposite = false;
+        break;
+      }
+    }
+    if(IsOpposite) {
+      OppNum = i;
+      break;
+    }
+  }
+  // find number of 2d elems on side faces
+  int nb2d = 0;
+  for(i=1; i<=6; i++) {
+    if( i==OppNum || i==NumBase ) continue;
+    MapShapeNbElemsItr anIt = aResMap.find( meshFaces[i-1] );
+    if( anIt == aResMap.end() ) continue;
+    std::vector<int> aVec = (*anIt).second;
+    nb2d += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]);
+  }
+  
+  MapShapeNbElemsItr anIt = aResMap.find( meshFaces[NumBase-1] );
+  std::vector<int> aVec = (*anIt).second;
+  bool IsQuadratic = (aVec[SMDSEntity_Quad_Triangle]>aVec[SMDSEntity_Triangle]) ||
+                     (aVec[SMDSEntity_Quad_Quadrangle]>aVec[SMDSEntity_Quadrangle]);
+  int nb2d_face0_3 = Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]);
+  int nb2d_face0_4 = Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]);
+  int nb0d_face0 = aVec[SMDSEntity_Node];
+  int nb1d_face0_int = ( nb2d_face0_3*3 + nb2d_face0_4*4 - nb1d ) / 2;
+
+  std::vector<int> aResVec(SMDSEntity_Last);
+  for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
+  if(IsQuadratic) {
+    aResVec[SMDSEntity_Quad_Penta] = nb2d_face0_3 * ( nb2d/nb1d );
+    aResVec[SMDSEntity_Quad_Hexa] = nb2d_face0_4 * ( nb2d/nb1d );
+    aResVec[SMDSEntity_Node] = nb0d_face0 * ( 2*nb2d/nb1d - 1 ) - nb1d_face0_int * nb2d/nb1d;
+  }
+  else {
+    aResVec[SMDSEntity_Node] = nb0d_face0 * ( nb2d/nb1d - 1 );
+    aResVec[SMDSEntity_Penta] = nb2d_face0_3 * ( nb2d/nb1d );
+    aResVec[SMDSEntity_Hexa] = nb2d_face0_4 * ( nb2d/nb1d );
+  }
+  SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
+  aResMap.insert(std::make_pair(sm,aResVec));
+
+  return true;
+}
+
+
 //================================================================================
 /*!
  * \brief Create prisms
@@ -377,9 +688,6 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
 void StdMeshers_Prism_3D::AddPrisms( vector<const TNodeColumn*> & columns,
                                      SMESH_MesherHelper*          helper)
 {
-  SMESHDS_Mesh * meshDS = helper->GetMeshDS();
-  int shapeID = helper->GetSubShapeID();
-
   int nbNodes = columns.size();
   int nbZ     = columns[0]->size();
   if ( nbZ < 2 ) return;
@@ -390,87 +698,103 @@ void StdMeshers_Prism_3D::AddPrisms( vector<const TNodeColumn*> & columns,
   int z = 1;
   switch ( nbNodes ) {
   case 3: {
-    const SMDS_MeshNode* botNodes[3] = { (*columns[0])[z-1],
-                                         (*columns[1])[z-1],
-                                         (*columns[2])[z-1] };
-    const SMDS_MeshNode* topNodes[3] = { (*columns[0])[z],
-                                         (*columns[1])[z],
-                                         (*columns[2])[z] };
-    SMDS_VolumeOfNodes tmpVol ( botNodes[0], botNodes[1], botNodes[2],
-                                topNodes[0], topNodes[1], topNodes[2]);
-    vTool.Set( &tmpVol );
+    SMDS_VolumeOfNodes tmpPenta ( (*columns[0])[z-1], // bottom
+                                  (*columns[1])[z-1],
+                                  (*columns[2])[z-1],
+                                  (*columns[0])[z],   // top
+                                  (*columns[1])[z],
+                                  (*columns[2])[z] );
+    vTool.Set( &tmpPenta );
     isForward  = vTool.IsForward();
     break;
   }
   case 4: {
-    const SMDS_MeshNode* botNodes[4] = { (*columns[0])[z-1], (*columns[1])[z-1],
-                                         (*columns[2])[z-1], (*columns[3])[z-1] };
-    const SMDS_MeshNode* topNodes[4] = { (*columns[0])[z], (*columns[1])[z],
-                                         (*columns[2])[z], (*columns[3])[z] };
-    SMDS_VolumeOfNodes tmpVol ( botNodes[0], botNodes[1], botNodes[2], botNodes[3],
-                                topNodes[0], topNodes[1], topNodes[2], topNodes[3]);
-    vTool.Set( &tmpVol );
+    SMDS_VolumeOfNodes tmpHex( (*columns[0])[z-1], (*columns[1])[z-1], // bottom
+                               (*columns[2])[z-1], (*columns[3])[z-1],
+                               (*columns[0])[z],   (*columns[1])[z],   // top
+                               (*columns[2])[z],   (*columns[3])[z] );
+    vTool.Set( &tmpHex );
     isForward  = vTool.IsForward();
     break;
   }
+  default:
+    const int di = (nbNodes+1) / 3;
+    SMDS_VolumeOfNodes tmpVol ( (*columns[0]   )[z-1],
+                                (*columns[di]  )[z-1],
+                                (*columns[2*di])[z-1],
+                                (*columns[0]   )[z],
+                                (*columns[di]  )[z],
+                                (*columns[2*di])[z] );
+    vTool.Set( &tmpVol );
+    isForward  = vTool.IsForward();
   }
 
   // vertical loop on columns
-  for ( z = 1; z < nbZ; ++z )
-  {
-    SMDS_MeshElement* vol = 0;
-    switch ( nbNodes ) {
 
-    case 3: {
-      const SMDS_MeshNode* botNodes[3] = { (*columns[0])[z-1],
-                                           (*columns[1])[z-1],
-                                           (*columns[2])[z-1] };
-      const SMDS_MeshNode* topNodes[3] = { (*columns[0])[z],
-                                           (*columns[1])[z],
-                                           (*columns[2])[z] };
-      if ( isForward )
-        vol = helper->AddVolume( botNodes[0], botNodes[1], botNodes[2],
-                                 topNodes[0], topNodes[1], topNodes[2]);
-      else
-        vol = helper->AddVolume( topNodes[0], topNodes[1], topNodes[2],
-                                 botNodes[0], botNodes[1], botNodes[2]);
-      break;
-      }
-    case 4: {
-      const SMDS_MeshNode* botNodes[4] = { (*columns[0])[z-1], (*columns[1])[z-1],
-                                           (*columns[2])[z-1], (*columns[3])[z-1] };
-      const SMDS_MeshNode* topNodes[4] = { (*columns[0])[z], (*columns[1])[z],
-                                           (*columns[2])[z], (*columns[3])[z] };
-      if ( isForward )
-        vol = helper->AddVolume( botNodes[0], botNodes[1], botNodes[2], botNodes[3],
-                                 topNodes[0], topNodes[1], topNodes[2], topNodes[3]);
-      else
-        vol = helper->AddVolume( topNodes[0], topNodes[1], topNodes[2], topNodes[3],
-                                 botNodes[0], botNodes[1], botNodes[2], botNodes[3]);
-      break;
-      }
-    default:
-      // polyhedron
-      vector<const SMDS_MeshNode*> nodes( 2*nbNodes + 4*nbNodes);
-      vector<int> quantities( 2 + nbNodes, 4 );
-      quantities[0] = quantities[1] = nbNodes;
-      columns.resize( nbNodes + 1 );
-      columns[ nbNodes ] = columns[ 0 ];
+  helper->SetElementsOnShape( true );
+
+  switch ( nbNodes ) {
+
+  case 3: { // ---------- pentahedra
+    const int i1 = isForward ? 1 : 2;
+    const int i2 = isForward ? 2 : 1;
+    for ( z = 1; z < nbZ; ++z )
+      helper->AddVolume( (*columns[0 ])[z-1], // bottom
+                         (*columns[i1])[z-1],
+                         (*columns[i2])[z-1],
+                         (*columns[0 ])[z],   // top
+                         (*columns[i1])[z],
+                         (*columns[i2])[z] );
+    break;
+  }
+  case 4: { // ---------- hexahedra
+    const int i1 = isForward ? 1 : 3;
+    const int i3 = isForward ? 3 : 1;
+    for ( z = 1; z < nbZ; ++z )
+      helper->AddVolume( (*columns[0])[z-1], (*columns[i1])[z-1], // bottom
+                         (*columns[2])[z-1], (*columns[i3])[z-1],
+                         (*columns[0])[z],   (*columns[i1])[z],     // top
+                         (*columns[2])[z],   (*columns[i3])[z] );
+    break;
+  }
+  case 6: { // ---------- octahedra
+    const int iBase1 = isForward ? -1 : 0;
+    const int iBase2 = isForward ?  0 :-1;
+    for ( z = 1; z < nbZ; ++z )
+      helper->AddVolume( (*columns[0])[z+iBase1], (*columns[1])[z+iBase1], // bottom or top
+                         (*columns[2])[z+iBase1], (*columns[3])[z+iBase1],
+                         (*columns[4])[z+iBase1], (*columns[5])[z+iBase1],
+                         (*columns[0])[z+iBase2], (*columns[1])[z+iBase2], // top or bottom
+                         (*columns[2])[z+iBase2], (*columns[3])[z+iBase2],
+                         (*columns[4])[z+iBase2], (*columns[5])[z+iBase2] );
+    break;
+  }
+  default: // ---------- polyhedra
+    vector<int> quantities( 2 + nbNodes, 4 );
+    quantities[0] = quantities[1] = nbNodes;
+    columns.resize( nbNodes + 1 );
+    columns[ nbNodes ] = columns[ 0 ];
+    const int i1 = isForward ? 1 : 3;
+    const int i3 = isForward ? 3 : 1;
+    const int iBase1 = isForward ? -1 : 0;
+    const int iBase2 = isForward ?  0 :-1;
+    vector<const SMDS_MeshNode*> nodes( 2*nbNodes + 4*nbNodes);
+    for ( z = 1; z < nbZ; ++z )
+    {
       for ( int i = 0; i < nbNodes; ++i ) {
-        nodes[ i         ] = (*columns[ i ])[z-1]; // bottom
-        nodes[ i+nbNodes ] = (*columns[ i ])[z  ]; // top
+        nodes[ i             ] = (*columns[ i ])[z+iBase1]; // bottom or top
+        nodes[ 2*nbNodes-i-1 ] = (*columns[ i ])[z+iBase2]; // top or bottom
         // side
-        int di = 2*nbNodes + 4*i - 1;
-        nodes[ di   ] = (*columns[i  ])[z-1];
-        nodes[ di+1 ] = (*columns[i+1])[z-1];
-        nodes[ di+2 ] = (*columns[i+1])[z  ];
-        nodes[ di+3 ] = (*columns[i  ])[z  ];
+        int di = 2*nbNodes + 4*i;
+        nodes[ di+0 ] = (*columns[i  ])[z  ];
+        nodes[ di+i1] = (*columns[i+1])[z  ];
+        nodes[ di+2 ] = (*columns[i+1])[z-1];
+        nodes[ di+i3] = (*columns[i  ])[z-1];
       }
-      vol = meshDS->AddPolyhedralVolume( nodes, quantities );
+      helper->AddPolyhedralVolume( nodes, quantities );
     }
-    if ( vol && shapeID > 0 )
-      meshDS->SetMeshElementOnShape( vol, shapeID );
-  }
+
+  } // switch ( nbNodes )
 }
 
 //================================================================================
@@ -498,6 +822,8 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top()
        botSMDS->NbElements() != topSMDS->NbElements() ||
        botSMDS->NbNodes()    != topSMDS->NbNodes())
   {
+    MESSAGE("nb elem bot " << botSMDS->NbElements() << " top " << topSMDS->NbElements());
+    MESSAGE("nb node bot " << botSMDS->NbNodes() << " top " << topSMDS->NbNodes());
     if ( myBlock.HasNotQuadElemOnTop() )
       return error(TCom("Mesh on faces #") << botSM->GetId()
                    <<" and #"<< topSM->GetId() << " seems different" );
@@ -535,7 +861,7 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top()
   // Fill myBotToColumnMap
 
   int zSize = myBlock.VerticalSize();
-  TNode prevTNode;
+  //TNode prevTNode;
   TNodeNodeMap::iterator bN_tN = n2nMap.begin();
   for ( ; bN_tN != n2nMap.end(); ++bN_tN )
   {
@@ -543,19 +869,8 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top()
     const SMDS_MeshNode* topNode = bN_tN->second;
     if ( botNode->GetPosition()->GetTypeOfPosition() != SMDS_TOP_FACE )
       continue; // wall columns are contained in myBlock
-    // compute bottom node params
-    TNode bN( botNode );
-    if ( zSize > 2 ) {
-      gp_XYZ paramHint(-1,-1,-1);
-      if ( prevTNode.IsNeighbor( bN ))
-        paramHint = prevTNode.GetParams();
-      if ( !myBlock.ComputeParameters( bN.GetCoords(), bN.ChangeParams(),
-                                       ID_BOT_FACE, paramHint ))
-        return error(TCom("Can't compute normalized parameters for node ")
-                     << botNode->GetID() << " on the face #"<< botSM->GetId() );
-      prevTNode = bN;
-    }
     // create node column
+    TNode bN( botNode );
     TNode2ColumnMap::iterator bN_col = 
       myBotToColumnMap.insert( make_pair ( bN, TNodeColumn() )).first;
     TNodeColumn & column = bN_col->second;
@@ -681,7 +996,7 @@ bool StdMeshers_Prism_3D::projectBottomToTop()
 
 //================================================================================
 /*!
- * \brief Set projection coordinates of a node to a face and it's subshapes
+ * \brief Set projection coordinates of a node to a face and it's sub-shapes
  * \param faceID - the face given by in-block ID
  * \param params - node normalized parameters
  * \retval bool - is a success
@@ -696,10 +1011,10 @@ bool StdMeshers_Prism_3D::setFaceAndEdgesXYZ( const int faceID, const gp_XYZ& pa
   SMESH_Block::GetFaceEdgesIDs( faceID, edgeVec );
 
   myBlock.EdgePoint( edgeVec[ BASE ], params, myShapeXYZ[ edgeVec[ BASE ]]);
-  myBlock.EdgePoint( edgeVec[ TOP ], params, myShapeXYZ[ edgeVec[ TOP ]]);
+  myBlock.EdgePoint( edgeVec[ TOP  ], params, myShapeXYZ[ edgeVec[ TOP ]]);
 
   SHOWYXZ("\nparams ", params);
-  SHOWYXZ("TOP is "<<edgeVec[ TOP], myShapeXYZ[ edgeVec[ TOP]]);
+  SHOWYXZ("TOP is " <<edgeVec[ TOP ], myShapeXYZ[ edgeVec[ TOP]]);
   SHOWYXZ("BASE is "<<edgeVec[ BASE], myShapeXYZ[ edgeVec[ BASE]]);
 
   if ( faceID == SMESH_Block::ID_Fx0z || faceID == SMESH_Block::ID_Fx1z )
@@ -746,9 +1061,19 @@ StdMeshers_PrismAsBlock::StdMeshers_PrismAsBlock()
 
 StdMeshers_PrismAsBlock::~StdMeshers_PrismAsBlock()
 {
+  Clear();
+}
+void StdMeshers_PrismAsBlock::Clear()
+{
+  myHelper = 0;
+  myShapeIDMap.Clear();
+  myError.reset();
+
   if ( mySide ) {
     delete mySide; mySide = 0;
   }
+  myParam2ColumnMaps.clear();
+  myShapeIndex2ColumnMap.clear();
 }
 
 //================================================================================
@@ -858,7 +1183,7 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
   }
 
   // ----------------------------------------------------------------------
-  // Analyse faces mesh and topology: choose the bottom submesh.
+  // Analyse mesh and topology of faces: choose the bottom submesh.
   // If there are not quadrangle geom faces, they are top and bottom ones.
   // Not quadrangle geom faces must be only on top and bottom.
   // ----------------------------------------------------------------------
@@ -871,14 +1196,24 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
   bool hasNotQuad = ( nbNotQuad || nbNotQuadMeshed );
 
   // detect bad cases
-  if ( nbNotQuad > 0 && nbNotQuad != 2 )
-    return error(COMPERR_BAD_SHAPE,
-                 TCom("More than 2 not quadrilateral faces: ")
-                 <<nbNotQuad);
   if ( nbNotQuadMeshed > 2 )
+  {
     return error(COMPERR_BAD_INPUT_MESH,
                  TCom("More than 2 faces with not quadrangle elements: ")
                  <<nbNotQuadMeshed);
+  }
+  int nbQuasiQuads = 0;
+  if ( nbNotQuad > 0 && nbNotQuad != 2 )
+  {
+    // Issue 0020843 - one of side faces is quasi-quadrilateral.
+    // Remove from notQuadGeomSubMesh faces meshed with regular grid
+    nbQuasiQuads = removeQuasiQuads( notQuadGeomSubMesh );
+    nbNotQuad -= nbQuasiQuads;
+    if ( nbNotQuad > 0 && nbNotQuad != 2 )
+      return error(COMPERR_BAD_SHAPE,
+                   TCom("More than 2 not quadrilateral faces: ")
+                   <<nbNotQuad);
+  }
 
   // get found submeshes
   if ( hasNotQuad )
@@ -901,6 +1236,7 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
   }
 
   myNotQuadOnTop = ( nbNotQuadMeshed > 1 );
+  MESSAGE("myNotQuadOnTop " << myNotQuadOnTop << " nbNotQuadMeshed " << nbNotQuadMeshed);
  
   // ----------------------------------------------------------
 
@@ -994,24 +1330,47 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
 
   // Get ordered bottom edges
   list< TopoDS_Edge > orderedEdges;
-  list< int >         nbVertexInWires;
+  list< int >         nbEInW;
   SMESH_Block::GetOrderedEdges( TopoDS::Face( botSM->GetSubShape().Reversed() ),
-                                V000, orderedEdges, nbVertexInWires );
-//   if ( nbVertexInWires.size() != 1 )
+                                V000, orderedEdges, nbEInW );
+//   if ( nbEInW.size() != 1 )
 //     RETURN_BAD_RESULT("Wrong prism geometry");
 
   // Get Wall faces corresponding to the ordered bottom edges
   list< TopoDS_Face > wallFaces;
-  if ( !GetWallFaces( Mesh(), shape3D, botSM->GetSubShape(), orderedEdges, wallFaces))
+  if ( !GetWallFaces( Mesh(), shape3D, botSM->GetSubShape(), orderedEdges, nbEInW, wallFaces))
     return error(COMPERR_BAD_SHAPE, "Can't find side faces");
 
+  // check that the found top and bottom faces are opposite
+  {
+    for (TopExp_Explorer edge(botSM->GetSubShape(), TopAbs_EDGE); edge.More(); edge.Next())
+      if ( helper->IsSubShape( edge.Current(), topSM->GetSubShape() ))
+        return error(notQuadGeomSubMesh.empty() ? COMPERR_BAD_INPUT_MESH : COMPERR_BAD_SHAPE,
+                     "Non-quadrilateral faces are not opposite");
+  }
+
+  // Protect from a distorted block (test 3D_mesh_HEXA3D/B7 on 32bit platform)
+  // check that all wall faces have an edge common with the top face
+  {
+    list< TopoDS_Face >::iterator faceIt = wallFaces.begin();
+    for ( ; faceIt != wallFaces.end(); ++faceIt )
+    {
+      bool hasCommon = false;
+      for (TopExp_Explorer edge(*faceIt, TopAbs_EDGE); !hasCommon && edge.More(); edge.Next())
+        if ( helper->IsSubShape( edge.Current(), topSM->GetSubShape() ))
+          hasCommon = true;
+      if ( !hasCommon )
+        return error(COMPERR_BAD_SHAPE);
+    }
+  }
+
   // Find columns of wall nodes and calculate edges' lengths
   // --------------------------------------------------------
 
   myParam2ColumnMaps.clear();
   myParam2ColumnMaps.resize( orderedEdges.size() ); // total nb edges
 
-  int iE, nbEdges = nbVertexInWires.front(); // nb outer edges
+  int iE, nbEdges = nbEInW.front(); // nb outer edges
   vector< double > edgeLength( nbEdges );
   map< double, int > len2edgeMap;
 
@@ -1057,11 +1416,11 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
     // columns for vertices
     // 1
     const SMDS_MeshNode* n0 = faceColumns.begin()->second.front();
-    id = n0->GetPosition()->GetShapeId();
+    id = n0->getshapeId();
     myShapeIndex2ColumnMap[ id ] = make_pair( & faceColumns, isForward );
     // 2
     const SMDS_MeshNode* n1 = faceColumns.rbegin()->second.front();
-    id = n1->GetPosition()->GetShapeId();
+    id = n1->getshapeId();
     myShapeIndex2ColumnMap[ id ] = make_pair( & faceColumns, isForward );
 //     SHOWYXZ("\np1 F "<<iE, gpXYZ(faceColumns.begin()->second.front() ));
 //     SHOWYXZ("p2 F "<<iE, gpXYZ(faceColumns.rbegin()->second.front() ));
@@ -1113,9 +1472,12 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
         int nbSplit = i_nb->second;
         vector< double > params;
         splitParams( nbSplit, &myParam2ColumnMaps[ iE ], params );
-        bool isForward = ( edgeIt->Orientation() == TopAbs_FORWARD );
+        const bool isForward =
+          StdMeshers_PrismAsBlock::IsForwardEdge( myHelper->GetMeshDS(),
+                                                  myParam2ColumnMaps[iE],
+                                                  *edgeIt, SMESH_Block::ID_Fx0z );
         for ( int i = 0; i < nbSplit; ++i ) {
-          double f = ( isForward ? params[ i ] : params[ nbSplit - i-1 ]);
+          double f = ( isForward ? params[ i ]   : params[ nbSplit - i-1 ]);
           double l = ( isForward ? params[ i+1 ] : params[ nbSplit - i ]);
           TSideFace* comp = new TSideFace( myHelper, wallFaceIds[ iSide ],
                                            *faceIt, *edgeIt,
@@ -1236,6 +1598,7 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
         break;
       }
     }
+    //sideFace->dumpNodes( 4 ); // debug
   }
   // horizontal faces geometry
   {
@@ -1270,11 +1633,11 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
 
       // columns for vertices
       const SMDS_MeshNode* n0 = cols->begin()->second.front();
-      id = n0->GetPosition()->GetShapeId();
+      id = n0->getshapeId();
       myShapeIndex2ColumnMap[ id ] = make_pair( cols, isForward );
 
       const SMDS_MeshNode* n1 = cols->rbegin()->second.front();
-      id = n1->GetPosition()->GetShapeId();
+      id = n1->getshapeId();
       myShapeIndex2ColumnMap[ id ] = make_pair( cols, !isForward );
     }
   }
@@ -1301,7 +1664,7 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
 
 const TNodeColumn* StdMeshers_PrismAsBlock::GetNodeColumn(const SMDS_MeshNode* node) const
 {
-  int sID = node->GetPosition()->GetShapeId();
+  int sID = node->getshapeId();
 
   map<int, pair< TParam2ColumnMap*, bool > >::const_iterator col_frw =
     myShapeIndex2ColumnMap.find( sID );
@@ -1315,6 +1678,89 @@ const TNodeColumn* StdMeshers_PrismAsBlock::GetNodeColumn(const SMDS_MeshNode* n
   return 0;
 }
 
+//=======================================================================
+//function : GetLayersTransformation
+//purpose  : Return transformations to get coordinates of nodes of each layer
+//           by nodes of the bottom. Layer is a set of nodes at a certain step
+//           from bottom to top.
+//=======================================================================
+
+bool StdMeshers_PrismAsBlock::GetLayersTransformation(vector<gp_Trsf> & trsf) const
+{
+  const int zSize = VerticalSize();
+  if ( zSize < 3 ) return true;
+  trsf.resize( zSize - 2 );
+
+  // Select some node columns by which we will define coordinate system of layers
+
+  vector< const TNodeColumn* > columns;
+  {
+    const TopoDS_Shape& baseFace = Shape(ID_BOT_FACE);
+    list< TopoDS_Edge > orderedEdges;
+    list< int >         nbEdgesInWires;
+    GetOrderedEdges( TopoDS::Face( baseFace ), TopoDS_Vertex(), orderedEdges, nbEdgesInWires );
+    bool isReverse;
+    list< TopoDS_Edge >::iterator edgeIt = orderedEdges.begin();
+    for ( int iE = 0; iE < nbEdgesInWires.front(); ++iE, ++edgeIt )
+    {
+      if ( BRep_Tool::Degenerated( *edgeIt )) continue;
+      const TParam2ColumnMap* u2colMap =
+        GetParam2ColumnMap( myHelper->GetMeshDS()->ShapeToIndex( *edgeIt ), isReverse );
+      if ( !u2colMap ) return false;
+      isReverse = ( edgeIt->Orientation() == TopAbs_REVERSED );
+      double f = u2colMap->begin()->first, l = u2colMap->rbegin()->first;
+      if ( isReverse ) swap ( f, l );
+      const int nbCol = 5;
+      for ( int i = 0; i < nbCol; ++i )
+      {
+        double u = f + i/double(nbCol) * ( l - f );
+        const TNodeColumn* col = & getColumn( u2colMap, u )->second;
+        if ( columns.empty() || col != columns.back() )
+          columns.push_back( col );
+      }
+    }
+  }
+
+  // Find tolerance to check transformations
+
+  double tol2;
+  {
+    Bnd_B3d bndBox;
+    for ( int i = 0; i < columns.size(); ++i )
+      bndBox.Add( gpXYZ( columns[i]->front() ));
+    tol2 = bndBox.SquareExtent() * 1e-5;
+  }
+
+  // Compute transformations
+
+  int xCol = -1;
+  gp_Trsf fromCsZ, toCs0;
+  gp_Ax3 cs0 = getLayerCoordSys(0, columns, xCol );
+  //double dist0 = cs0.Location().Distance( gpXYZ( (*columns[0])[0]));
+  toCs0.SetTransformation( cs0 );
+  for ( int z = 1; z < zSize-1; ++z )
+  {
+    gp_Ax3 csZ = getLayerCoordSys(z, columns, xCol );
+    //double distZ = csZ.Location().Distance( gpXYZ( (*columns[0])[z]));
+    fromCsZ.SetTransformation( csZ );
+    fromCsZ.Invert();
+    gp_Trsf& t = trsf[ z-1 ];
+    t = fromCsZ * toCs0;
+    //t.SetScaleFactor( distZ/dist0 ); - it does not work properly, wrong base point
+
+    // check a transformation
+    for ( int i = 0; i < columns.size(); ++i )
+    {
+      gp_Pnt p0 = gpXYZ( (*columns[i])[0] );
+      gp_Pnt pz = gpXYZ( (*columns[i])[z] );
+      t.Transforms( p0.ChangeCoord() );
+      if ( p0.SquareDistance( pz ) > tol2 )
+        return false;
+    }
+  }
+  return true;
+}
+
 //================================================================================
 /*!
  * \brief Check curve orientation of a bootom edge
@@ -1322,7 +1768,7 @@ const TNodeColumn* StdMeshers_PrismAsBlock::GetNodeColumn(const SMDS_MeshNode* n
   * \param columnsMap - node columns map of side face
   * \param bottomEdge - the bootom edge
   * \param sideFaceID - side face in-block ID
-  * \retval bool - true if orientation coinside with in-block froward orientation
+  * \retval bool - true if orientation coinside with in-block forward orientation
  */
 //================================================================================
 
@@ -1332,7 +1778,7 @@ bool StdMeshers_PrismAsBlock::IsForwardEdge(SMESHDS_Mesh*           meshDS,
                                             const int               sideFaceID)
 {
   bool isForward = false;
-  if ( TAssocTool::IsClosedEdge( bottomEdge ))
+  if ( SMESH_MesherHelper::IsClosedEdge( bottomEdge ))
   {
     isForward = ( bottomEdge.Orientation() == TopAbs_FORWARD );
   }
@@ -1350,41 +1796,59 @@ bool StdMeshers_PrismAsBlock::IsForwardEdge(SMESHDS_Mesh*           meshDS,
 }
 
 //================================================================================
-  /*!
  * \brief Find wall faces by bottom edges
   * \param mesh - the mesh
   * \param mainShape - the prism
   * \param bottomFace - the bottom face
   * \param bottomEdges - edges bounding the bottom face
   * \param wallFaces - faces list to fill in
  */
+/*!
+ * \brief Find wall faces by bottom edges
+ * \param mesh - the mesh
+ * \param mainShape - the prism
+ * \param bottomFace - the bottom face
+ * \param bottomEdges - edges bounding the bottom face
+ * \param wallFaces - faces list to fill in
+ */
 //================================================================================
 
-bool StdMeshers_PrismAsBlock::GetWallFaces( SMESH_Mesh*                     mesh,
-                                            const TopoDS_Shape &            mainShape,
-                                            const TopoDS_Shape &            bottomFace,
-                                            const std::list< TopoDS_Edge >& bottomEdges,
-                                            std::list< TopoDS_Face >&       wallFaces)
+bool StdMeshers_PrismAsBlock::GetWallFaces( SMESH_Mesh*               mesh,
+                                            const TopoDS_Shape &      mainShape,
+                                            const TopoDS_Shape &      bottomFace,
+                                            std::list< TopoDS_Edge >& bottomEdges,
+                                            std::list< int > &        nbEInW,
+                                            std::list< TopoDS_Face >& wallFaces)
 {
   wallFaces.clear();
 
   TopTools_IndexedMapOfShape faceMap;
   TopExp::MapShapes( mainShape, TopAbs_FACE, faceMap );
 
-  list< TopoDS_Edge >::const_iterator edge = bottomEdges.begin();
-  for ( ; edge != bottomEdges.end(); ++edge )
+  list< TopoDS_Edge >::iterator edge = bottomEdges.begin();
+  std::list< int >::iterator nbE = nbEInW.begin();
+  int iE = 0;
+  while ( edge != bottomEdges.end() )
   {
-    TopTools_ListIteratorOfListOfShape ancestIt = mesh->GetAncestors( *edge );
-    for ( ; ancestIt.More(); ancestIt.Next() )
+    ++iE;
+    if ( BRep_Tool::Degenerated( *edge ))
     {
-      const TopoDS_Shape& ancestor = ancestIt.Value();
-      if ( ancestor.ShapeType() == TopAbs_FACE && // face
-           !bottomFace.IsSame( ancestor ) &&      // not bottom
-           faceMap.FindIndex( ancestor ))         // belongs to the prism
+      edge = bottomEdges.erase( edge );
+      --iE;
+      --(*nbE);
+    }
+    else
+    {
+      PShapeIteratorPtr fIt = myHelper->GetAncestors( *edge, *mesh, TopAbs_FACE );
+      while ( fIt->more() )
       {
-        wallFaces.push_back( TopoDS::Face( ancestor ));
-        break;
+        const TopoDS_Shape* face = fIt->next();
+        if ( !bottomFace.IsSame( *face ) &&      // not bottom
+             faceMap.FindIndex( *face ))         // belongs to the prism
+        {
+          wallFaces.push_back( TopoDS::Face( *face ));
+          break;
+        }
       }
+      ++edge;
+    }
+    if ( iE == *nbE )
+    {
+      iE = 0;
+      ++nbE;
     }
   }
   return ( wallFaces.size() == bottomEdges.size() );
@@ -1610,8 +2074,6 @@ double StdMeshers_PrismAsBlock::TSideFace::GetColumns(const double      U,
     r = 0.5;
   }
   else {
-//     if ( !myIsForward )
-//       std::swap( col1, col2 );
     double uf = col1->first;
     double ul = col2->first;
     r = ( u - uf ) / ( ul - uf );
@@ -1631,8 +2093,8 @@ double StdMeshers_PrismAsBlock::TSideFace::GetColumns(const double      U,
 gp_Pnt StdMeshers_PrismAsBlock::TSideFace::Value(const Standard_Real U,
                                                  const Standard_Real V) const
 {
-  double u;
   if ( !myComponents.empty() ) {
+    double u;
     TSideFace * comp = GetComponent(U,u);
     return comp->Value( u, V );
   }
@@ -1644,7 +2106,41 @@ gp_Pnt StdMeshers_PrismAsBlock::TSideFace::Value(const Standard_Real U,
   const SMDS_MeshNode* n2 = 0;
   const SMDS_MeshNode* n3 = 0;
   const SMDS_MeshNode* n4 = 0;
-  gp_XYZ pnt;
+
+  // BEGIN issue 0020680: EDF 1252 SMESH: Bad cell created by Radial prism in center of torus
+  // Workaround for a wrongly located point returned by mySurface.Value() for
+  // UV located near boundary of BSpline surface.
+  // To bypass the problem, we take point from 3D curve of edge.
+  // It solves pb of the bloc_fiss_new.py
+  const double tol = 1e-3;
+  if ( V < tol || V+tol >= 1. )
+  {
+    n1 = V < tol ? u_col1->second.front() : u_col1->second.back();
+    n3 = V < tol ? u_col2->second.front() : u_col2->second.back();
+    TopoDS_Edge edge;
+    if ( V < tol )
+    {
+      edge = myBaseEdge;
+    }
+    else
+    {
+      TopoDS_Shape s = myHelper->GetSubShapeByNode( n1, myHelper->GetMeshDS() );
+      if ( s.ShapeType() != TopAbs_EDGE )
+        s = myHelper->GetSubShapeByNode( n3, myHelper->GetMeshDS() );
+      if ( s.ShapeType() == TopAbs_EDGE )
+        edge = TopoDS::Edge( s );
+    }
+    if ( !edge.IsNull() )
+    {
+      double u1 = myHelper->GetNodeU( edge, n1 );
+      double u3 = myHelper->GetNodeU( edge, n3 );
+      double u = u1 * ( 1 - hR ) + u3 * hR;
+      TopLoc_Location loc; double f,l;
+      Handle(Geom_Curve) curve = BRep_Tool::Curve( edge,loc,f,l );
+      return curve->Value( u ).Transformed( loc );
+    }
+  }
+  // END issue 0020680: EDF 1252 SMESH: Bad cell created by Radial prism in center of torus
 
   vR = getRAndNodes( & u_col1->second, V, n1, n2 );
   vR = getRAndNodes( & u_col2->second, V, n3, n4 );
@@ -1658,8 +2154,9 @@ gp_Pnt StdMeshers_PrismAsBlock::TSideFace::Value(const Standard_Real U,
   gp_XY uv34 = uv3 * ( 1 - vR ) + uv4 * vR;
 
   gp_XY uv = uv12 * ( 1 - hR ) + uv34 * hR;
-  
-  return mySurface.Value( uv.X(), uv.Y() );
+
+  gp_Pnt p = mySurface.Value( uv.X(), uv.Y() );
+  return p;
 }
 
 
@@ -1720,25 +2217,18 @@ TopoDS_Edge StdMeshers_PrismAsBlock::TSideFace::GetEdge(const int iEdge) const
   TopoDS_Shape V2 = myHelper->GetSubShapeByNode( node, meshDS );
   if ( V2.ShapeType() == TopAbs_VERTEX && !V2.IsSame( V1 ))
   {
-    TopTools_ListIteratorOfListOfShape ancestIt =
-      myHelper->GetMesh()->GetAncestors( V1 );
-    for ( ; ancestIt.More(); ancestIt.Next() )
-    {
-      const TopoDS_Shape & ancestor = ancestIt.Value();
-      if ( ancestor.ShapeType() == TopAbs_EDGE )
-        for ( TopExp_Explorer e( ancestor, TopAbs_VERTEX ); e.More(); e.Next() )
-          if ( V2.IsSame( e.Current() ))
-            return TopoDS::Edge( ancestor );
-    }
+    TopoDS_Shape ancestor = myHelper->GetCommonAncestor( V1, V2, *myHelper->GetMesh(), TopAbs_EDGE);
+    if ( !ancestor.IsNull() )
+      return TopoDS::Edge( ancestor );
   }
   return TopoDS_Edge();
 }
 
 //================================================================================
 /*!
- * \brief Fill block subshapes
+ * \brief Fill block sub-shapes
   * \param shapeMap - map to fill in
-  * \retval int - nb inserted subshapes
+  * \retval int - nb inserted sub-shapes
  */
 //================================================================================
 
@@ -1837,6 +2327,28 @@ int StdMeshers_PrismAsBlock::TSideFace::InsertSubShapes(TBlockShapes& shapeMap)
   return nbInserted;
 }
 
+//================================================================================
+/*!
+ * \brief Dump ids of nodes of sides
+ */
+//================================================================================
+
+void StdMeshers_PrismAsBlock::TSideFace::dumpNodes(int nbNodes) const
+{
+#ifdef _DEBUG_
+  cout << endl << "NODES OF FACE "; SMESH_Block::DumpShapeID( myID, cout ) << endl;
+  THorizontalEdgeAdaptor* hSize0 = (THorizontalEdgeAdaptor*) HorizCurve(0);
+  cout << "Horiz side 0: "; hSize0->dumpNodes(nbNodes); cout << endl;
+  THorizontalEdgeAdaptor* hSize1 = (THorizontalEdgeAdaptor*) HorizCurve(1);
+  cout << "Horiz side 1: "; hSize1->dumpNodes(nbNodes); cout << endl;
+  TVerticalEdgeAdaptor* vSide0 = (TVerticalEdgeAdaptor*) VertiCurve(0);
+  cout << "Verti side 0: "; vSide0->dumpNodes(nbNodes); cout << endl;
+  TVerticalEdgeAdaptor* vSide1 = (TVerticalEdgeAdaptor*) VertiCurve(1);
+  cout << "Verti side 1: "; vSide1->dumpNodes(nbNodes); cout << endl;
+  delete hSize0; delete hSize1; delete vSide0; delete vSide1;
+#endif
+}
+
 //================================================================================
 /*!
  * \brief Creates TVerticalEdgeAdaptor 
@@ -1867,6 +2379,22 @@ gp_Pnt StdMeshers_PrismAsBlock::TVerticalEdgeAdaptor::Value(const Standard_Real
   return gpXYZ(n1) * ( 1 - r ) + gpXYZ(n2) * r;
 }
 
+//================================================================================
+/*!
+ * \brief Dump ids of nodes
+ */
+//================================================================================
+
+void StdMeshers_PrismAsBlock::TVerticalEdgeAdaptor::dumpNodes(int nbNodes) const
+{
+#ifdef _DEBUG_
+  for ( int i = 0; i < nbNodes && i < myNodeColumn->size(); ++i )
+    cout << (*myNodeColumn)[i]->GetID() << " ";
+  if ( nbNodes < myNodeColumn->size() )
+    cout << myNodeColumn->back()->GetID();
+#endif
+}
+
 //================================================================================
 /*!
  * \brief Return coordinates for the given normalized parameter
@@ -1880,6 +2408,50 @@ gp_Pnt StdMeshers_PrismAsBlock::THorizontalEdgeAdaptor::Value(const Standard_Rea
   return mySide->TSideFace::Value( U, myV );
 }
 
+//================================================================================
+/*!
+ * \brief Dump ids of <nbNodes> first nodes and the last one
+ */
+//================================================================================
+
+void StdMeshers_PrismAsBlock::THorizontalEdgeAdaptor::dumpNodes(int nbNodes) const
+{
+#ifdef _DEBUG_
+  // Not bedugged code. Last node is sometimes incorrect
+  const TSideFace* side = mySide;
+  double u = 0;
+  if ( mySide->IsComplex() )
+    side = mySide->GetComponent(0,u);
+
+  TParam2ColumnIt col, col2;
+  TParam2ColumnMap* u2cols = side->GetColumns();
+  side->GetColumns( u , col, col2 );
+  
+  int j, i = myV ? mySide->ColumnHeight()-1 : 0;
+
+  const SMDS_MeshNode* n = 0;
+  const SMDS_MeshNode* lastN
+    = side->IsForward() ? u2cols->rbegin()->second[ i ] : u2cols->begin()->second[ i ];
+  for ( j = 0; j < nbNodes && n != lastN; ++j )
+  {
+    n = col->second[ i ];
+    cout << n->GetID() << " ";
+    if ( side->IsForward() )
+      ++col;
+    else
+      --col;
+  }
+
+  // last node
+  u = 1;
+  if ( mySide->IsComplex() )
+    side = mySide->GetComponent(1,u);
+
+  side->GetColumns( u , col, col2 );
+  if ( n != col->second[ i ] )
+    cout << col->second[ i ]->GetID();
+#endif
+}
 //================================================================================
 /*!
  * \brief Return UV on pcurve for the given normalized parameter
index 0eb4db1d0a4985704c0a83fafa7bf35b32392f29..8c1e6fa78fe629b3b29764f688def0a1ea0f2fd4 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_Prism_3D.hxx
 //  Module : SMESH
@@ -46,6 +47,7 @@
 #include <BRepAdaptor_Surface.hxx>
 #include <TopTools_IndexedMapOfOrientedShape.hxx>
 #include <gp_XYZ.hxx>
+#include <gp_Trsf.hxx>
 
 
 class SMESHDS_SubMesh;
@@ -58,7 +60,7 @@ typedef std::vector<const SMDS_MeshNode* > TNodeColumn;
 
 // map of bottom nodes to the column of nodes above them
 // (the column includes the bottom nodes)
-typedef std::map< TNode, TNodeColumn > TNode2ColumnMap;
+typedef std::map< TNode, TNodeColumn >  TNode2ColumnMap;
 typedef std::map< double, TNodeColumn > TParam2ColumnMap;
 typedef std::map< double, TNodeColumn >::const_iterator TParam2ColumnIt;
 
@@ -73,18 +75,18 @@ typedef TopTools_IndexedMapOfOrientedShape TBlockShapes;
 struct TNode
 {
   const SMDS_MeshNode* myNode;
-  gp_XYZ               myParams;
+  mutable gp_XYZ       myParams;
 
   gp_XYZ GetCoords() const { return gp_XYZ( myNode->X(), myNode->Y(), myNode->Z() ); }
   gp_XYZ GetParams() const { return myParams; }
-  gp_XYZ& ChangeParams() { return myParams; }
+  gp_XYZ& ChangeParams() const { return myParams; }
   bool HasParams() const { return myParams.X() >= 0.0; }
   SMDS_TypeOfPosition GetPositionType() const
   { return myNode ? myNode->GetPosition()->GetTypeOfPosition() : SMDS_TOP_UNSPEC; }
   bool IsNeighbor( const TNode& other ) const;
 
   TNode(const SMDS_MeshNode* node = 0): myNode(node), myParams(-1,-1,-1) {}
-  bool operator < (const TNode& other) const { return myNode < other.myNode; }
+  bool operator < (const TNode& other) const { return myNode->GetID() < other.myNode->GetID(); }
 };
 
 // ===============================================================
@@ -92,7 +94,7 @@ struct TNode
  * \brief Tool analyzing and giving access to a prism geometry 
  *  treating it like a block, i.e. the four side faces are
  *  emulated by division/uniting of missing/excess faces.
- *  It also manage associations between block subshapes and a mesh.
+ *  It also manage associations between block sub-shapes and a mesh.
  */
 // ===============================================================
 
@@ -122,6 +124,11 @@ public:
    */
   SMESH_ComputeErrorPtr GetError() const { return myError; }
 
+  /*!
+   * \brief Free allocated memory
+   */
+  void Clear();
+
   /*!
    * \brief Return number of nodes on every vertical edge
     * \retval int - number of nodes including end nodes
@@ -141,16 +148,26 @@ public:
    * \brief Return TParam2ColumnMap for a base edge
     * \param baseEdgeID - base edge SMESHDS Index
     * \param isReverse - columns in-block orientation
-    * \retval const TParam2ColumnMap& - map
+    * \retval const TParam2ColumnMap* - map
    */
-  const TParam2ColumnMap& GetParam2ColumnMap(const int baseEdgeID,
-                                             bool &    isReverse)
+  const TParam2ColumnMap* GetParam2ColumnMap(const int baseEdgeID,
+                                             bool &    isReverse) const
   {
-    std::pair< TParam2ColumnMap*, bool > & col_frw =
-      myShapeIndex2ColumnMap[ baseEdgeID ];
+    std::map< int, std::pair< TParam2ColumnMap*, bool > >::const_iterator i_mo =
+      myShapeIndex2ColumnMap.find( baseEdgeID );
+    if ( i_mo == myShapeIndex2ColumnMap.end() ) return 0;
+
+    const std::pair< TParam2ColumnMap*, bool >& col_frw = i_mo->second;
     isReverse = !col_frw.second;
-    return col_frw.first;
+    return col_frw.first;
   }
+
+  /*!
+   * \brief Return transformations to get coordinates of nodes of each internal layer
+   *        by nodes of the bottom. Layer is a set of nodes at a certain step
+   *        from bottom to top.
+   */
+  bool GetLayersTransformation(std::vector<gp_Trsf> & trsf) const;
   
   /*!
    * \brief Return pointer to mesh
@@ -190,7 +207,7 @@ public:
 
   /*!
    * \brief Return in-block ID of a shape
-    * \param shape - block subshape
+    * \param shape - block sub-shape
     * \retval int - ID or zero if the shape has no ID
    */
   int ShapeID(const TopoDS_Shape& shape) const
@@ -216,11 +233,12 @@ public:
     * \param bottomEdges - edges bounding the bottom face
     * \param wallFaces - faces list to fill in
    */
-  static bool GetWallFaces( SMESH_Mesh*                     mesh,
-                            const TopoDS_Shape &            mainShape,
-                            const TopoDS_Shape &            bottomFace,
-                            const std::list< TopoDS_Edge >& bottomEdges,
-                            std::list< TopoDS_Face >&       wallFaces);
+  bool GetWallFaces( SMESH_Mesh*               mesh,
+                     const TopoDS_Shape &      mainShape,
+                     const TopoDS_Shape &      bottomFace,
+                     std::list< TopoDS_Edge >& bottomEdges,
+                     std::list< int > &        nbEInW,
+                     std::list< TopoDS_Face >& wallFaces);
 
 private:
 
@@ -284,6 +302,8 @@ private:
     int InsertSubShapes( TBlockShapes& shapeMap ) const;
     // redefine Adaptor methods
     gp_Pnt Value(const Standard_Real U,const Standard_Real V) const;
+    // debug
+    void dumpNodes(int nbNodes) const;
   };
 
   // --------------------------------------------------------------------
@@ -299,6 +319,8 @@ private:
     gp_Pnt Value(const Standard_Real U) const;
     Standard_Real FirstParameter() const { return 0; }
     Standard_Real LastParameter() const { return 1; }
+    // debug
+    void dumpNodes(int nbNodes) const;
   };
 
   // --------------------------------------------------------------------
@@ -316,6 +338,8 @@ private:
     gp_Pnt Value(const Standard_Real U) const;
     Standard_Real FirstParameter() const { return 0; }
     Standard_Real LastParameter() const { return 1; }
+    // debug
+    void dumpNodes(int nbNodes) const;
   };
 
   // --------------------------------------------------------------------
@@ -337,20 +361,19 @@ private:
     Standard_Real FirstParameter() const { return 0; }
     Standard_Real LastParameter() const { return 1; }
   };
-  // --------------------------------------------------------------------
 
-  bool myNotQuadOnTop;
-  SMESH_MesherHelper* myHelper;
-  TBlockShapes myShapeIDMap;
+  bool                  myNotQuadOnTop;
+  SMESH_MesherHelper*   myHelper;
+  TBlockShapes          myShapeIDMap;
+  SMESH_ComputeErrorPtr myError;
 
   // container of 4 side faces
-  TSideFace*                 mySide; 
+  TSideFace*            mySide; 
   // node columns for each base edge
-  std::vector< TParam2ColumnMap > myParam2ColumnMaps;
+  std::vector< TParam2ColumnMap >                       myParam2ColumnMaps;
   // to find a column for a node by edge SMESHDS Index
   std::map< int, std::pair< TParam2ColumnMap*, bool > > myShapeIndex2ColumnMap;
 
-  SMESH_ComputeErrorPtr myError;
   /*!
    * \brief store error and comment and then return ( error == COMPERR_OK )
    */
@@ -358,7 +381,6 @@ private:
     myError = SMESH_ComputeError::New(error,comment);
     return myError->IsOK();
   }
-  //std::vector< SMESH_subMesh* >           mySubMeshesVec; // submesh by in-block id
 };
 
 // =============================================
@@ -379,6 +401,9 @@ public:
 
   virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
 
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
+
   /*!
    * \brief Enable removal of quadrangles from the bottom face and
    * triangles creation there by projection from the top
@@ -415,7 +440,7 @@ private:
   bool projectBottomToTop();
 
   /*!
-   * \brief Set projection coordinates of a node to a face and it's subshapes
+   * \brief Set projection coordinates of a node to a face and it's sub-shapes
     * \param faceID - the face given by in-block ID
     * \param params - node normalized parameters
     * \retval bool - is a success
@@ -429,12 +454,11 @@ private:
   StdMeshers_PrismAsBlock myBlock;
   SMESH_MesherHelper*     myHelper;
 
-  std::vector<gp_XYZ>            myShapeXYZ; // point on each sub-shape
+  std::vector<gp_XYZ>     myShapeXYZ; // point on each sub-shape of the block
 
   // map of bottom nodes to the column of nodes above them
   // (the column includes the bottom node)
-  typedef std::map< TNode, TNodeColumn > TNode2ColumnMap;
-  TNode2ColumnMap  myBotToColumnMap;
+  TNode2ColumnMap         myBotToColumnMap;
 };
 
 #endif
index 8a2052071360bd2af2be3ec034401f028f4ba937..cf1a41ee3697f7c6a6fa6b36f8b3e1d9e7ac920c 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : idl implementation based on 'SMESH' unit's classes
 //  File   : StdMeshers_ProjectionSource1D.cxx
 //  Author : Edward AGAPOV
@@ -126,9 +127,10 @@ void StdMeshers_ProjectionSource1D::SetVertexAssociation(const TopoDS_Shape& sou
 
 void StdMeshers_ProjectionSource1D::SetSourceMesh(SMESH_Mesh* mesh)
 {
-  if ( _sourceMesh != mesh )
+  if ( _sourceMesh != mesh ) {
+    _sourceMesh = mesh;
     NotifySubMeshesHypothesisModification();
-  _sourceMesh = mesh;
+  }
 }
 
 //=============================================================================
index 301dedf304b1bf947e84a67f4716b7d1460626bd..ddd82f6733fb3bd2f73c32a6853cfa251e0c4f53 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_ProjectionSource1D.hxx
 //  Author : Edward AGAPOV
index a1393fc79e8007923b98b2fc696dba6dc206bf97..479bdd6eca6f29bf8d70aec89f7ab05fd2d926e5 100644 (file)
@@ -1,32 +1,34 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : idl implementation based on 'SMESH' unit's classes
 //  File   : StdMeshers_ProjectionSource2D.cxx
 //  Author : Edward AGAPOV
 //  Module : SMESH
-
+//
 #include "StdMeshers_ProjectionSource2D.hxx"
 
 #include "SMESH_Mesh.hxx"
+#include "StdMeshers_ProjectionUtils.hxx"
 
 #include "utilities.h"
 
@@ -102,17 +104,27 @@ void StdMeshers_ProjectionSource2D::SetVertexAssociation(const TopoDS_Shape& sou
   throw ( SALOME_Exception )
 {
   if ( sourceVertex1.IsNull() != targetVertex1.IsNull() ||
-       sourceVertex2.IsNull() != targetVertex2.IsNull() ||
-       sourceVertex1.IsNull() != targetVertex2.IsNull() )
-    throw SALOME_Exception(LOCALIZED("Two or none pairs of vertices must be provided"));
+       sourceVertex2.IsNull() != targetVertex2.IsNull() )
+    throw SALOME_Exception(LOCALIZED("Vertices must be provided in couples"));
+
+  if ( sourceVertex1.IsNull() != sourceVertex2.IsNull() )
+  {
+    // possibly there is only 1 vertex in the face
+    if ( !_sourceFace.IsNull() &&
+         StdMeshers_ProjectionUtils::Count( _sourceFace, TopAbs_VERTEX, /*ignoreSame=*/true) != 1 )
+      throw SALOME_Exception(LOCALIZED("Two or none pairs of vertices must be provided"));
+  }
 
-  if ( !sourceVertex1.IsNull() ) {
+  if ( !sourceVertex1.IsNull() )
     if ( sourceVertex1.ShapeType() != TopAbs_VERTEX ||
-         sourceVertex2.ShapeType() != TopAbs_VERTEX ||
-         targetVertex1.ShapeType() != TopAbs_VERTEX ||
+         targetVertex1.ShapeType() != TopAbs_VERTEX )
+      throw SALOME_Exception(LOCALIZED("Wrong shape type"));
+
+  if ( !sourceVertex2.IsNull() )
+    if ( sourceVertex2.ShapeType() != TopAbs_VERTEX ||
          targetVertex2.ShapeType() != TopAbs_VERTEX )
       throw SALOME_Exception(LOCALIZED("Wrong shape type"));
-  }
+
 
   if ( !_sourceVertex1.IsSame( sourceVertex1 ) ||
        !_sourceVertex2.IsSame( sourceVertex2 ) ||
@@ -136,9 +148,10 @@ void StdMeshers_ProjectionSource2D::SetVertexAssociation(const TopoDS_Shape& sou
 
 void StdMeshers_ProjectionSource2D::SetSourceMesh(SMESH_Mesh* mesh)
 {
-  if ( _sourceMesh != mesh )
+  if ( _sourceMesh != mesh ) {
+    _sourceMesh = mesh;
     NotifySubMeshesHypothesisModification();
-  _sourceMesh = mesh;
+  }
 }
 
 //=============================================================================
index a23d4c4948639db476b6ceab675ca7f18c047f12..9783211479ecca4d09dd5dc78a54cd0a0db88461 100644 (file)
@@ -1,29 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_ProjectionSource2D.hxx
 //  Author : Edward AGAPOV
 //  Module : SMESH
-
+//
 #ifndef _SMESH_ProjectionSource2D_HXX_
 #define _SMESH_ProjectionSource2D_HXX_
 
index b77808f3606941ee6bfb2d483150822667035f8a..f90b4eed3b43f7ec79ac3fe9a133535182009a20 100644 (file)
@@ -1,29 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : idl implementation based on 'SMESH' unit's classes
 //  File   : StdMeshers_ProjectionSource3D.cxx
 //  Author : Edward AGAPOV
 //  Module : SMESH
-
+//
 #include "StdMeshers_ProjectionSource3D.hxx"
 
 #include "utilities.h"
@@ -135,9 +136,10 @@ void StdMeshers_ProjectionSource3D::SetVertexAssociation(const TopoDS_Shape& sou
 
 void StdMeshers_ProjectionSource3D::SetSourceMesh(SMESH_Mesh* mesh)
 {
-  if ( _sourceMesh != mesh )
+  if ( _sourceMesh != mesh ) {
+    _sourceMesh = mesh;
     NotifySubMeshesHypothesisModification();
-  _sourceMesh = mesh;
+  }
 }
 
 //=============================================================================
index fd6848aec658b5552db101f12c7135448a075488..6098f1816e761d714bd7d7665dec35cae9448e9a 100644 (file)
@@ -1,29 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_ProjectionSource3D.hxx
 //  Author : Edward AGAPOV
 //  Module : SMESH
-
+//
 #ifndef _SMESH_ProjectionSource3D_HXX_
 #define _SMESH_ProjectionSource3D_HXX_
 
index 2bf6ac4be03b1dc46868342214f9d810e67dbcb9..3053be90d22bce6d95db37e677127ed460366d0f 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : idl implementation based on 'SMESH' unit's calsses
 // File      : StdMeshers_ProjectionUtils.cxx
 // Created   : Fri Oct 27 10:24:28 2006
 #include "SMESH_Block.hxx"
 #include "SMESH_Gen.hxx"
 #include "SMESH_Hypothesis.hxx"
-#include "SMESH_IndexedDataMapOfShapeIndexedMapOfShape.hxx"
 #include "SMESH_Mesh.hxx"
-#include "SMESH_MeshEditor.hxx"
+#include "SMESH_MesherHelper.hxx"
 #include "SMESH_subMesh.hxx"
 #include "SMESH_subMeshEventListener.hxx"
 #include "SMDS_EdgePosition.hxx"
 
 #include "utilities.h"
 
+#include <BRepAdaptor_Surface.hxx>
 #include <BRepTools.hxx>
 #include <BRepTools_WireExplorer.hxx>
 #include <BRep_Builder.hxx>
@@ -52,6 +53,9 @@
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopTools_Array1OfShape.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopTools_ListOfShape.hxx>
 #include <TopTools_MapOfShape.hxx>
 #include <TopoDS_Shape.hxx>
 #include <gp_Pnt.hxx>
 #include <gp_Vec.hxx>
-#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
-#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
+
+#include <numeric>
 
 using namespace std;
 
 
 #define RETURN_BAD_RESULT(msg) { MESSAGE(")-: Error: " << msg); return false; }
-#define SHOW_VERTEX(v,msg) // { \
-//  if ( v.IsNull() ) cout << msg << " NULL SHAPE" << endl; \
-// else if (v.ShapeType() == TopAbs_VERTEX) {\
-//   gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( v ));\
-//   cout << msg << (v).TShape().operator->()<<" ( " <<p.X()<<", "<<p.Y()<<", "<<p.Z()<<" )"<<endl;}\
+#define CONT_BAD_RESULT(msg) { MESSAGE(")-: Error: " << msg); continue; }
+#define SHOW_SHAPE(v,msg) \
+// { \
+//  if ( (v).IsNull() ) cout << msg << " NULL SHAPE" << endl; \
+// else if ((v).ShapeType() == TopAbs_VERTEX) {\
+//   gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( (v) ));\
+//   cout<<msg<<" "<<shapeIndex((v))<<" ( "<<p.X()<<", "<<p.Y()<<", "<<p.Z()<<" )"<<endl;} \
 // else {\
-// cout << msg << " "; TopAbs::Print(v.ShapeType(),cout) <<" "<<(v).TShape().operator->()<<endl;}\
+// cout << msg << " "; TopAbs::Print((v).ShapeType(),cout) <<" "<<shapeIndex((v))<<endl;}\
 // }
 #define SHOW_LIST(msg,l) \
 // { \
@@ -85,7 +91,34 @@ using namespace std;
 //     cout << endl;\
 //   }
 
+#define HERE StdMeshers_ProjectionUtils
+
 namespace {
+
+  static SMESHDS_Mesh* theMeshDS[2] = { 0, 0 }; // used to debug only
+  long shapeIndex(const TopoDS_Shape& S)
+  {
+    if ( theMeshDS[0] && theMeshDS[1] )
+      return max(theMeshDS[0]->ShapeToIndex(S), theMeshDS[1]->ShapeToIndex(S) );
+    return long(S.TShape().operator->());
+  }
+
+  //================================================================================
+  /*!
+   * \brief Write shape for debug purposes
+   */
+  //================================================================================
+
+  bool _StoreBadShape(const TopoDS_Shape& shape)
+  {
+#ifdef _DEBUG_
+    const char* type[] ={"COMPOUND","COMPSOLID","SOLID","SHELL","FACE","WIRE","EDGE","VERTEX"};
+    BRepTools::Write( shape, SMESH_Comment("/tmp/") << type[shape.ShapeType()] << "_"
+                      << shape.TShape().operator->() << ".brep");
+#endif
+    return false;
+  }
+  
   //================================================================================
   /*!
    * \brief Reverse order of edges in a list and their orientation
@@ -94,31 +127,24 @@ namespace {
    */
   //================================================================================
 
-  void Reverse( list< TopoDS_Edge > & edges, const int nbEdges )
+  void Reverse( list< TopoDS_Edge > & edges, const int nbEdges, const int firstEdge=0)
   {
     SHOW_LIST("BEFORE REVERSE", edges);
 
     list< TopoDS_Edge >::iterator eIt = edges.begin();
-    if ( edges.size() == nbEdges )
-    {
-      edges.reverse();
-    }
-    else  // reverse only the given nb of edges
+    std::advance( eIt, firstEdge );
+    list< TopoDS_Edge >::iterator eBackIt = eIt;
+    for ( int i = 0; i < nbEdges; ++i, ++eBackIt )
+      eBackIt->Reverse(); // reverse edge
+    // reverse list
+    --eBackIt;
+    while ( eIt != eBackIt )
     {
-      // look for the last edge to be reversed
-      list< TopoDS_Edge >::iterator eBackIt = edges.begin();
-      for ( int i = 1; i < nbEdges; ++i )
-        ++eBackIt;
-      // reverse
-      while ( eIt != eBackIt ) {
-        std::swap( *eIt, *eBackIt );
-        SHOW_LIST("# AFTER SWAP", edges)
+      std::swap( *eIt, *eBackIt );
+      SHOW_LIST("# AFTER SWAP", edges)
         if ( (++eIt) != eBackIt )
           --eBackIt;
-      }
     }
-    for ( eIt = edges.begin(); eIt != edges.end(); ++eIt )
-      eIt->Reverse();
     SHOW_LIST("ATFER REVERSE", edges)
   }
 
@@ -162,8 +188,7 @@ namespace {
     if ( nbEdges == 2 && IsPropagationPossible( theMesh1, theMesh2 ) )
     {
       list< TopoDS_Edge >::iterator eIt2 = ++edges2.begin(); // 2nd edge of the 2nd face
-      TopoDS_Edge edge2 =
-        StdMeshers_ProjectionUtils::GetPropagationEdge( theMesh1, *eIt2, edges1.front() ).second;
+      TopoDS_Edge edge2 = HERE::GetPropagationEdge( theMesh1, *eIt2, edges1.front() ).second;
       if ( !edge2.IsNull() ) { // propagation found for the second edge
         Reverse( edges2, nbEdges );
         return true;
@@ -202,14 +227,200 @@ namespace {
     }
     return TopoDS_Shape();
   }
-}
+
+  //================================================================================
+  /*!
+   * \brief Find association of groups at top and bottom of prism
+   */
+  //================================================================================
+
+  bool AssocGroupsByPropagation(const TopoDS_Shape&   theGroup1,
+                                const TopoDS_Shape&   theGroup2,
+                                SMESH_Mesh&           theMesh,
+                                HERE::TShapeShapeMap& theMap)
+  {
+    // If groups are on top and bottom of prism then we can associate
+    // them using "vertical" (or "side") edges and faces of prism since
+    // they connect corresponding vertices and edges of groups.
+
+    TopTools_IndexedMapOfShape subshapes1, subshapes2;
+    TopExp::MapShapes( theGroup1, subshapes1 );
+    TopExp::MapShapes( theGroup2, subshapes2 );
+    TopTools_ListIteratorOfListOfShape ancestIt;
+
+    // Iterate on vertices of group1 to find corresponding vertices in group2
+    // and associate adjacent edges and faces
+
+    TopTools_MapOfShape verticShapes;
+    TopExp_Explorer vExp1( theGroup1, TopAbs_VERTEX );
+    for ( ; vExp1.More(); vExp1.Next() )
+    {
+      const TopoDS_Vertex& v1 = TopoDS::Vertex( vExp1.Current() );
+      if ( theMap.IsBound( v1 )) continue; // already processed
+
+      // Find "vertical" edge ending in v1 and whose other vertex belongs to group2
+      TopoDS_Shape verticEdge, v2;
+      ancestIt.Initialize( theMesh.GetAncestors( v1 ));
+      for ( ; verticEdge.IsNull() && ancestIt.More(); ancestIt.Next() )
+      {
+        if ( ancestIt.Value().ShapeType() != TopAbs_EDGE ) continue;
+        v2 = HERE::GetNextVertex( TopoDS::Edge( ancestIt.Value() ), v1 );
+        if ( subshapes2.Contains( v2 ))
+          verticEdge = ancestIt.Value();
+      }
+      if ( verticEdge.IsNull() )
+        return false;
+
+      HERE::InsertAssociation( v1, v2, theMap);
+
+      // Associate edges by vertical faces sharing the found vertical edge
+      ancestIt.Initialize( theMesh.GetAncestors( verticEdge ) );
+      for ( ; ancestIt.More(); ancestIt.Next() )
+      {
+        if ( ancestIt.Value().ShapeType() != TopAbs_FACE ) continue;
+        if ( !verticShapes.Add( ancestIt.Value() )) continue;
+        const TopoDS_Face& face = TopoDS::Face( ancestIt.Value() );
+
+        // get edges of the face
+        TopoDS_Edge edgeGr1, edgeGr2, verticEdge2;
+        list< TopoDS_Edge > edges;    list< int > nbEdgesInWire;
+        SMESH_Block::GetOrderedEdges( face, v1, edges, nbEdgesInWire);
+        if ( nbEdgesInWire.front() != 4 )
+          return _StoreBadShape( face );
+        list< TopoDS_Edge >::iterator edge = edges.begin();
+        if ( verticEdge.IsSame( *edge )) {
+          edgeGr2     = *(++edge);
+          verticEdge2 = *(++edge);
+          edgeGr1     = *(++edge);
+        } else {
+          edgeGr1     = *(edge++);
+          verticEdge2 = *(edge++);
+          edgeGr2     = *(edge++);
+        }
+
+        HERE::InsertAssociation( edgeGr1, edgeGr2.Reversed(), theMap);
+      }
+    }
+
+    // Associate faces
+    TopoDS_Iterator gr1It( theGroup1 );
+    if ( gr1It.Value().ShapeType() == TopAbs_FACE )
+    {
+      // find a boundary edge of group1 to start from
+      TopoDS_Shape bndEdge = StdMeshers_ProjectionUtils::GetBoundaryEdge( theGroup1, theMesh );
+      if ( bndEdge.IsNull() )
+        return false;
+
+      list< TopoDS_Shape > edges(1, bndEdge);
+      list< TopoDS_Shape >::iterator edge1 = edges.begin();
+      for ( ; edge1 != edges.end(); ++edge1 )
+      {
+        // there must be one or zero not associated faces between ancestors of edge
+        // belonging to theGroup1
+        TopoDS_Shape face1;
+        ancestIt.Initialize( theMesh.GetAncestors( *edge1 ) );
+        for ( ; ancestIt.More() && face1.IsNull(); ancestIt.Next() ) {
+          if ( ancestIt.Value().ShapeType() == TopAbs_FACE &&
+               !theMap.IsBound( ancestIt.Value() ) &&
+               subshapes1.Contains( ancestIt.Value() ))
+            face1 = ancestIt.Value();
+
+          // add edges of face1 to start searching for adjacent faces from
+          for ( TopExp_Explorer e(face1, TopAbs_EDGE); e.More(); e.Next())
+            if ( !edge1->IsSame( e.Current() ))
+              edges.push_back( e.Current() );
+        }
+        if ( !face1.IsNull() ) {
+          // find the corresponding face of theGroup2
+          TopoDS_Shape edge2 = theMap( *edge1 );
+          TopoDS_Shape face2;
+          ancestIt.Initialize( theMesh.GetAncestors( edge2 ) );
+          for ( ; ancestIt.More() && face2.IsNull(); ancestIt.Next() ) {
+            if ( ancestIt.Value().ShapeType() == TopAbs_FACE &&
+                 !theMap.IsBound( ancestIt.Value(), /*is2nd=*/true ) &&
+                 subshapes2.Contains( ancestIt.Value() ))
+              face2 = ancestIt.Value();
+          }
+          if ( face2.IsNull() )
+            return false;
+
+          HERE::InsertAssociation( face1, face2, theMap);
+        }
+      }
+    }
+    return true;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Return true if uv position of the vIndex-th vertex of edge on face is close
+   * enough to given uv 
+   */
+  //================================================================================
+
+  bool sameVertexUV( const TopoDS_Edge& edge,
+                     const TopoDS_Face& face,
+                     const int&         vIndex,
+                     const gp_Pnt2d&    uv,
+                     const double&      tol2d )
+  {
+    TopoDS_Vertex VV[2];
+    TopExp::Vertices( edge, VV[0], VV[1], true);
+    gp_Pnt2d v1UV = BRep_Tool::Parameters( VV[vIndex], face);
+    double dist2d = v1UV.Distance( uv );
+    return dist2d < tol2d;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Returns an EDGE suitable for search of initial vertex association
+   */
+  //================================================================================
+
+  TopoDS_Shape getOuterEdge( const TopoDS_Shape theShape1, SMESH_Mesh& mesh )
+  {
+    TopoDS_Shape edge;
+    if ( theShape1.ShapeType() == TopAbs_COMPOUND )
+    {
+      TopoDS_Iterator it( theShape1 );
+      if ( it.Value().ShapeType() == TopAbs_FACE ) // group of FACEs
+      {
+        // look for a boundary EDGE of a group
+        edge = StdMeshers_ProjectionUtils::GetBoundaryEdge( theShape1, mesh );
+        if ( !edge.IsNull() )
+          return edge;
+      }
+    }
+    edge = theShape1;
+    TopExp_Explorer expF( theShape1, TopAbs_FACE ), expE;
+    if ( expF.More() ) {
+      for ( ; expF.More(); expF.Next() ) {
+        edge.Nullify();
+        TopoDS_Shape wire =
+          StdMeshers_ProjectionUtils::OuterShape( TopoDS::Face( expF.Current() ), TopAbs_WIRE );
+        for ( expE.Init( wire, TopAbs_EDGE ); edge.IsNull() && expE.More(); expE.Next() )
+          if ( !SMESH_MesherHelper::IsClosedEdge( TopoDS::Edge( expE.Current() )))
+            edge = expE.Current();
+        if ( !edge.IsNull() )
+          break;
+      }
+    } else if (edge.ShapeType() != TopAbs_EDGE) { // no faces
+      edge.Nullify();
+      for ( expE.Init( theShape1, TopAbs_EDGE ); edge.IsNull() && expE.More(); expE.Next() )
+        if ( !SMESH_MesherHelper::IsClosedEdge( TopoDS::Edge( expE.Current() )))
+          edge = expE.Current();
+    }
+    return edge;
+  }
+
+} // namespace
 
 //=======================================================================
 /*!
- * \brief Looks for association of all subshapes of two shapes
- * \param theShape1 - shape 1
+ * \brief Looks for association of all sub-shapes of two shapes
+ * \param theShape1 - target shape
  * \param theMesh1 - mesh built on shape 1
- * \param theShape2 - shape 2
+ * \param theShape2 - source shape
  * \param theMesh2 - mesh built on shape 2
  * \param theAssociation - association map to be filled that may
  *                         contain association of one or two pairs of vertices
@@ -223,8 +434,31 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
                                                          SMESH_Mesh*         theMesh2,
                                                          TShapeShapeMap &    theMap)
 {
+  // Structure of this long function is following
+  // 1) Group->group projection: theShape1 is a group member,
+  //    theShape2 is a group. We find a group theShape1 is in and recall self.
+  // 2) Accosiate same shapes with different location (partners).
+  // 3) If vertex association is given, perform accosiation according to shape type:
+  //       switch ( ShapeType ) {
+  //         case TopAbs_EDGE:
+  //         case ...:
+  //       }
+  // 4) else try to accosiate in different ways:
+  //       a) accosiate shapes by propagation and other simple cases
+  //            switch ( ShapeType ) {
+  //            case TopAbs_EDGE:
+  //            case ...:
+  //            }
+  //       b) find association of a couple of vertices and recall self.
+  //
+
+  theMeshDS[0] = theMesh1->GetMeshDS(); // debug
+  theMeshDS[1] = theMesh2->GetMeshDS();
+
+  // =================================================================================
+  // 1) Is it the case of associating a group member -> another group? (PAL16202, 16203)
+  // =================================================================================
   if ( theShape1.ShapeType() != theShape2.ShapeType() ) {
-    // is it the case of a group member -> another group? (PAL16202, 16203)
     TopoDS_Shape group1, group2;
     if ( theShape1.ShapeType() == TopAbs_COMPOUND ) {
       group1 = theShape1;
@@ -240,11 +474,34 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
     return FindSubShapeAssociation(group1, theMesh1, group2, theMesh2, theMap );
   }
 
-  bool bidirect = ( !theShape1.IsSame( theShape2 ));
+  // ============
+  // 2) Is partner?
+  // ============
+  bool partner = theShape1.IsPartner( theShape2 );
+  TopTools_DataMapIteratorOfDataMapOfShapeShape vvIt( theMap._map1to2 );
+  for ( ; partner && vvIt.More(); vvIt.Next() )
+    partner = vvIt.Key().IsPartner( vvIt.Value() );
+
+  if ( partner ) // Same shape with different location
+  {
+    // recursively associate all sub-shapes of theShape1 and theShape2
+    typedef list< pair< TopoDS_Shape, TopoDS_Shape > > TShapePairsList;
+    TShapePairsList shapesQueue( 1, make_pair( theShape1, theShape2 ));
+    TShapePairsList::iterator s1_s2 = shapesQueue.begin();
+    for ( ; s1_s2 != shapesQueue.end(); ++s1_s2 )
+    {
+      InsertAssociation( s1_s2->first, s1_s2->second, theMap );
+      TopoDS_Iterator s1It( s1_s2->first), s2It( s1_s2->second );
+      for ( ; s1It.More(); s1It.Next(), s2It.Next() )
+        shapesQueue.push_back( make_pair( s1It.Value(), s2It.Value() ));
+    }
+    return true;
+  }
+
   if ( !theMap.IsEmpty() )
   {
     //======================================================================
-    // HAS initial vertex association
+    // 3) HAS initial vertex association
     //======================================================================
     switch ( theShape1.ShapeType() ) {
       // ----------------------------------------------------------------------
@@ -254,14 +511,16 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
         RETURN_BAD_RESULT("Wrong map extent " << theMap.Extent() );
       TopoDS_Edge edge1 = TopoDS::Edge( theShape1 );
       TopoDS_Edge edge2 = TopoDS::Edge( theShape2 );
+      if ( edge1.Orientation() >= TopAbs_INTERNAL ) edge1.Orientation( TopAbs_FORWARD );
+      if ( edge2.Orientation() >= TopAbs_INTERNAL ) edge2.Orientation( TopAbs_FORWARD );
       TopoDS_Vertex VV1[2], VV2[2];
       TopExp::Vertices( edge1, VV1[0], VV1[1] );
       TopExp::Vertices( edge2, VV2[0], VV2[1] );
       int i1 = 0, i2 = 0;
       if ( theMap.IsBound( VV1[ i1 ] )) i1 = 1;
       if ( theMap.IsBound( VV2[ i2 ] )) i2 = 1;
-      InsertAssociation( VV1[ i1 ], VV2[ i2 ], theMap, bidirect);
-      InsertAssociation( theShape1, theShape2, theMap, bidirect );
+      InsertAssociation( VV1[ i1 ], VV2[ i2 ], theMap );
+      InsertAssociation( theShape1, theShape2, theMap );
       return true;
     }
       // ----------------------------------------------------------------------
@@ -269,6 +528,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
       // ----------------------------------------------------------------------
       TopoDS_Face face1 = TopoDS::Face( theShape1 );
       TopoDS_Face face2 = TopoDS::Face( theShape2 );
+      if ( face1.Orientation() >= TopAbs_INTERNAL ) face1.Orientation( TopAbs_FORWARD );
+      if ( face2.Orientation() >= TopAbs_INTERNAL ) face2.Orientation( TopAbs_FORWARD );
 
       TopoDS_Vertex VV1[2], VV2[2];
       // find a not closed edge of face1 both vertices of which are associated
@@ -298,12 +559,12 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
       list< TopoDS_Edge >::iterator eIt2 = edges2.begin();
       for ( ; eIt1 != edges1.end(); ++eIt1, ++eIt2 )
       {
-        InsertAssociation( *eIt1, *eIt2, theMap, bidirect);
+        InsertAssociation( *eIt1, *eIt2, theMap );
         VV1[0] = TopExp::FirstVertex( *eIt1, true );
         VV2[0] = TopExp::FirstVertex( *eIt2, true );
-        InsertAssociation( VV1[0], VV2[0], theMap, bidirect);
+        InsertAssociation( VV1[0], VV2[0], theMap );
       }
-      InsertAssociation( theShape1, theShape2, theMap, bidirect );
+      InsertAssociation( theShape1, theShape2, theMap );
       return true;
     }
       // ----------------------------------------------------------------------
@@ -311,11 +572,12 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
     case TopAbs_SOLID: {
       // ----------------------------------------------------------------------
       TopoDS_Vertex VV1[2], VV2[2];
-      // find a not closed edge of shape1 both vertices of which are associated
+      // try to find a not closed edge of shape1 both vertices of which are associated
       TopoDS_Edge edge1;
       TopExp_Explorer exp ( theShape1, TopAbs_EDGE );
       for ( ; VV2[ 1 ].IsNull() && exp.More(); exp.Next() ) {
         edge1 = TopoDS::Edge( exp.Current() );
+        if ( edge1.Orientation() >= TopAbs_INTERNAL ) edge1.Orientation( TopAbs_FORWARD );
         TopExp::Vertices( edge1 , VV1[0], VV1[1] );
         if ( theMap.IsBound( VV1[0] )) {
           VV2[ 0 ] = TopoDS::Vertex( theMap( VV1[0] ));
@@ -325,11 +587,12 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
       }
       if ( VV2[ 1 ].IsNull() ) // 2 bound vertices not found
         RETURN_BAD_RESULT("2 bound vertices not found" );
+      // get an edge2 of theShape2 corresponding to edge1
       TopoDS_Edge edge2 = GetEdgeByVertices( theMesh2, VV2[ 0 ], VV2[ 1 ]);
       if ( edge2.IsNull() )
         RETURN_BAD_RESULT("GetEdgeByVertices() failed");
 
-      // build map of edge to faces if shapes are not subshapes of main ones
+      // build map of edge to faces if shapes are not sub-shapes of main ones
       bool isSubOfMain = false;
       if ( SMESHDS_SubMesh * sm = theMesh1->GetMeshDS()->MeshElements( theShape1 ))
         isSubOfMain = !sm->IsComplexSubmesh();
@@ -382,7 +645,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
       TopExp::Vertices( edge1, VV1[0], VV1[1], true );
       TopExp::Vertices( edge2, VV2[0], VV2[1], true );
       F2 = FF2[ 0 ]; // (F2 !)
-      if ( !VV1[ 0 ].IsSame( theMap( VV2[ 0 ]))) {
+      if ( !VV1[ 0 ].IsSame( theMap( VV2[ 0 ], /*is2=*/true))) {
         edge2.Reverse();
         if ( FF2[ 1 ].IsNull() )
           F2.Reverse();
@@ -392,7 +655,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
 
       TopTools_MapOfShape boundEdges;
 
-      // association of face subshapes and neighbour faces
+      // association of face sub-shapes and neighbour faces
       list< pair < TopoDS_Face, TopoDS_Edge > > FE1, FE2;
       list< pair < TopoDS_Face, TopoDS_Edge > >::iterator fe1, fe2;
       FE1.push_back( make_pair( TopoDS::Face( F1 ), edge1 ));
@@ -409,7 +672,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
         list< TopoDS_Edge > edges1, edges2;
         int nbE = FindFaceAssociation( face1, VV1, face2, VV2, edges1, edges2 );
         if ( !nbE ) RETURN_BAD_RESULT("FindFaceAssociation() failed");
-        InsertAssociation( face1, face2, theMap, bidirect); // assoc faces
+        InsertAssociation( face1, face2, theMap ); // assoc faces
         MESSAGE("Assoc FACE " << theMesh1->GetMeshDS()->ShapeToIndex( face1 )<<
                 " to "        << theMesh2->GetMeshDS()->ShapeToIndex( face2 ));
         if ( nbE == 2 && (edge1.IsSame( edges1.front())) != (edge2.IsSame( edges2.front())))
@@ -421,12 +684,12 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
         for ( ; eIt1 != edges1.end(); ++eIt1, ++eIt2 )
         {
           if ( !boundEdges.Add( *eIt1 )) continue; // already associated
-          InsertAssociation( *eIt1, *eIt2, theMap, bidirect);  // assoc edges
+          InsertAssociation( *eIt1, *eIt2, theMap );  // assoc edges
           MESSAGE("Assoc edge " << theMesh1->GetMeshDS()->ShapeToIndex( *eIt1 )<<
                   " to "        << theMesh2->GetMeshDS()->ShapeToIndex( *eIt2 ));
           VV1[0] = TopExp::FirstVertex( *eIt1, true );
           VV2[0] = TopExp::FirstVertex( *eIt2, true );
-          InsertAssociation( VV1[0], VV2[0], theMap, bidirect); // assoc vertices
+          InsertAssociation( VV1[0], VV2[0], theMap ); // assoc vertices
           MESSAGE("Assoc vertex " << theMesh1->GetMeshDS()->ShapeToIndex( VV1[0] )<<
                   " to "          << theMesh2->GetMeshDS()->ShapeToIndex( VV2[0] ));
 
@@ -439,7 +702,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
           }
         }
       }
-      InsertAssociation( theShape1, theShape2, theMap, bidirect );
+      InsertAssociation( theShape1, theShape2, theMap );
       return true;
     }
       // ----------------------------------------------------------------------
@@ -478,7 +741,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
           if ( !initAssocOK ) {
             // for shell association there must be an edge with both vertices bound
             TopoDS_Vertex v1, v2;
-            TopExp::Vertices( TopoDS::Edge( it1.Value()), v1, v2 );
+            TopExp::Vertices( TopoDS::Edge( it1.Value().Oriented(TopAbs_FORWARD)), v1, v2 );
             initAssocOK = ( theMap.IsBound( v1 ) && theMap.IsBound( v2 ));
           }
         }
@@ -561,7 +824,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
               TShapeShapeMap tmpMap;
               ok = FindSubShapeAssociation( comp[0], theMesh1, comp[1], theMesh2, tmpMap );
               if ( ok ) {
-                TopTools_DataMapIteratorOfDataMapOfShapeShape mapIt( tmpMap );
+                TopTools_DataMapIteratorOfDataMapOfShapeShape mapIt( tmpMap._map1to2 );
                 for ( ; mapIt.More(); mapIt.Next() )
                   theMap.Bind( mapIt.Key(), mapIt.Value());
               }
@@ -620,13 +883,13 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
             TopoDS_Edge e1 = TopoDS::Edge( edges1.First() );
             v2e[0].UnBind( V[0] );
             v2e[1].UnBind( V[1] );
-            InsertAssociation( e0, e1, theMap, bidirect );
+            InsertAssociation( e0, e1, theMap );
             MESSAGE("Assoc edge " << theMesh1->GetMeshDS()->ShapeToIndex( e0 )<<
                     " to "        << theMesh2->GetMeshDS()->ShapeToIndex( e1 ));
             V[0] = GetNextVertex( e0, V[0] );
             V[1] = GetNextVertex( e1, V[1] );
             if ( !V[0].IsNull() ) {
-              InsertAssociation( V[0], V[1], theMap, bidirect );
+              InsertAssociation( V[0], V[1], theMap );
               MESSAGE("Assoc vertex " << theMesh1->GetMeshDS()->ShapeToIndex( V[0] )<<
                       " to "          << theMesh2->GetMeshDS()->ShapeToIndex( V[1] ));
             }
@@ -652,9 +915,9 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
             } else {
               v1n = v1e1; e1b = edges1.First(); e1n = edges1.Last();
             }
-            InsertAssociation( e0b, e1b, theMap, bidirect );
-            InsertAssociation( e0n, e1n, theMap, bidirect );
-            InsertAssociation( v0n, v1n, theMap, bidirect );
+            InsertAssociation( e0b, e1b, theMap );
+            InsertAssociation( e0n, e1n, theMap );
+            InsertAssociation( v0n, v1n, theMap );
             MESSAGE("Assoc edge " << theMesh1->GetMeshDS()->ShapeToIndex( e0b )<<
                     " to "        << theMesh2->GetMeshDS()->ShapeToIndex( e1b ));
             MESSAGE("Assoc edge " << theMesh1->GetMeshDS()->ShapeToIndex( e0n )<<
@@ -681,7 +944,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
   } // end case of available initial vertex association
 
   //======================================================================
-  // NO INITIAL VERTEX ASSOCIATION
+  // 4) NO INITIAL VERTEX ASSOCIATION
   //======================================================================
 
   switch ( theShape1.ShapeType() ) {
@@ -698,24 +961,25 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
         TopoDS_Vertex VV1[2], VV2[2];
         TopExp::Vertices( edge1,   VV1[0], VV1[1], true );
         TopExp::Vertices( prpEdge, VV2[0], VV2[1], true );
-        InsertAssociation( VV1[ 0 ], VV2[ 0 ], theMap, bidirect);
-        InsertAssociation( VV1[ 1 ], VV2[ 1 ], theMap, bidirect);
+        InsertAssociation( VV1[ 0 ], VV2[ 0 ], theMap );
+        InsertAssociation( VV1[ 1 ], VV2[ 1 ], theMap );
         if ( VV1[0].IsSame( VV1[1] ) || // one of edges is closed
              VV2[0].IsSame( VV2[1] ) )
         {
-          InsertAssociation( edge1, prpEdge, theMap, bidirect); // insert with a proper orientation
+          InsertAssociation( edge1, prpEdge, theMap ); // insert with a proper orientation
         }
-        InsertAssociation( theShape1, theShape2, theMap, bidirect );
+        InsertAssociation( theShape1, theShape2, theMap );
         return true; // done
       }
     }
-    if ( IsClosedEdge( edge1 ) && IsClosedEdge( edge2 ))
+    if ( SMESH_MesherHelper::IsClosedEdge( edge1 ) &&
+         SMESH_MesherHelper::IsClosedEdge( edge2 ))
     {
       // TODO: find out a proper orientation (is it possible?)
-      InsertAssociation( edge1, edge2, theMap, bidirect); // insert with a proper orientation
+      InsertAssociation( edge1, edge2, theMap ); // insert with a proper orientation
       InsertAssociation( TopExp::FirstVertex(edge1), TopExp::FirstVertex(edge2),
-                         theMap, bidirect);
-      InsertAssociation( theShape1, theShape2, theMap, bidirect );
+                         theMap );
+      InsertAssociation( theShape1, theShape2, theMap );
       return true; // done
     }
     break; // try by vertex closeness
@@ -727,6 +991,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
     {
       TopoDS_Face face1 = TopoDS::Face(theShape1);
       TopoDS_Face face2 = TopoDS::Face(theShape2);
+      if ( face1.Orientation() >= TopAbs_INTERNAL ) face1.Orientation( TopAbs_FORWARD );
+      if ( face2.Orientation() >= TopAbs_INTERNAL ) face2.Orientation( TopAbs_FORWARD );
       TopoDS_Edge edge1, edge2;
       // get outer edge of theShape1
       edge1 = TopoDS::Edge( OuterShape( face1, TopAbs_EDGE ));
@@ -737,6 +1003,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
         pair<int,TopoDS_Edge> step_edge = GetPropagationEdge( theMesh1, edge2, edge1 );
         if ( !step_edge.second.IsNull() ) { // propagation found
           propag_edges.insert( step_edge );
+          if ( step_edge.first == 1 ) break; // most close found
         }
       }
       if ( !propag_edges.empty() ) // propagation found
@@ -748,25 +1015,26 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
         list< TopoDS_Edge > edges1, edges2;
         int nbE = FindFaceAssociation( face1, VV1, face2, VV2, edges1, edges2 );
         if ( !nbE ) RETURN_BAD_RESULT("FindFaceAssociation() failed");
-        if ( nbE == 2 ) // only 2 edges
+        // take care of proper association of propagated edges
+        bool same1 = edge1.IsSame( edges1.front() );
+        bool same2 = edge2.IsSame( edges2.front() );
+        if ( same1 != same2 )
         {
-          // take care of proper association of propagated edges
-          bool same1 = edge1.IsSame( edges1.front() );
-          bool same2 = edge2.IsSame( edges2.front() );
-          if ( same1 != same2 )
-            Reverse(edges2, nbE);
+          Reverse(edges2, nbE);
+          if ( nbE != 2 ) // 2 degen edges of 4 (issue 0021144)
+            edges2.splice( edges2.end(), edges2, edges2.begin());
         }
         // store association
         list< TopoDS_Edge >::iterator eIt1 = edges1.begin();
         list< TopoDS_Edge >::iterator eIt2 = edges2.begin();
         for ( ; eIt1 != edges1.end(); ++eIt1, ++eIt2 )
         {
-          InsertAssociation( *eIt1, *eIt2, theMap, bidirect);
+          InsertAssociation( *eIt1, *eIt2, theMap );
           VV1[0] = TopExp::FirstVertex( *eIt1, true );
           VV2[0] = TopExp::FirstVertex( *eIt2, true );
-          InsertAssociation( VV1[0], VV2[0], theMap, bidirect);
+          InsertAssociation( VV1[0], VV2[0], theMap );
         }
-        InsertAssociation( theShape1, theShape2, theMap, bidirect );
+        InsertAssociation( theShape1, theShape2, theMap );
         return true;
       }
     }
@@ -775,25 +1043,16 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
   case TopAbs_COMPOUND: {
     // ----------------------------------------------------------------------
     if ( IsPropagationPossible( theMesh1, theMesh2 )) {
-      // find a boundary edge for theShape1
-      TopoDS_Edge E;
-      for(TopExp_Explorer exp(theShape1, TopAbs_EDGE); exp.More(); exp.Next() ) {
-        E = TopoDS::Edge( exp.Current() );
-        int NbFacesFromShape1 = 0;
-        const TopTools_ListOfShape& EAncestors = theMesh1->GetAncestors(E);
-        TopTools_ListIteratorOfListOfShape itea(EAncestors);
-        for(; itea.More(); itea.Next()) {
-          if( itea.Value().ShapeType() != TopAbs_FACE ) continue;
-          TopoDS_Face face = TopoDS::Face(itea.Value());
-          for(TopExp_Explorer expf(theShape1, TopAbs_FACE); expf.More(); expf.Next() ) {
-            if(face.IsSame(expf.Current())) {
-              NbFacesFromShape1++;
-              break;
-            }
-          }
-        }
-        if(NbFacesFromShape1==1) break;
-      }
+
+      // try to accosiate all using propagation
+      if ( AssocGroupsByPropagation( theShape1, theShape2, *theMesh1, theMap ))
+        return true;
+
+      // find a boundary edge of theShape1
+      TopoDS_Edge E = GetBoundaryEdge( theShape1, *theMesh1 );
+      if ( E.IsNull() )
+        break; // try by vertex closeness
+
       // find association for vertices of edge E
       TopoDS_Vertex VV1[2], VV2[2];
       for(TopExp_Explorer eexp(E, TopAbs_VERTEX); eexp.More(); eexp.Next()) {
@@ -838,8 +1097,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
         }
       }
       if ( !VV1[1].IsNull() ) {
-        InsertAssociation( VV1[0], VV2[0], theMap, bidirect);
-        InsertAssociation( VV1[1], VV2[1], theMap, bidirect);
+        InsertAssociation( VV1[0], VV2[0], theMap );
+        InsertAssociation( VV1[1], VV2[1], theMap );
         return FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap);
       }
     }
@@ -848,25 +1107,52 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
   default:;
   }
 
-  // Find association by closeness of vertices
-  // ------------------------------------------
+  // 4.b) Find association by closeness of vertices
+  // ----------------------------------------------
 
   TopTools_IndexedMapOfShape vMap1, vMap2;
   TopExp::MapShapes( theShape1, TopAbs_VERTEX, vMap1 );
   TopExp::MapShapes( theShape2, TopAbs_VERTEX, vMap2 );
+  TopoDS_Vertex VV1[2], VV2[2];
 
   if ( vMap1.Extent() != vMap2.Extent() )
     RETURN_BAD_RESULT("Different nb of vertices");
 
   if ( vMap1.Extent() == 1 ) {
-    InsertAssociation( vMap1(1), vMap2(1), theMap, bidirect);
+    InsertAssociation( vMap1(1), vMap2(1), theMap );
     if ( theShape1.ShapeType() == TopAbs_EDGE ) {
-      InsertAssociation( theShape1, theShape2, theMap, bidirect );
+      InsertAssociation( theShape1, theShape2, theMap );
       return true;
     }
     return FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap);
   }
 
+  // Try to associate by common vertices of an edge
+  for ( int i = 1; i <= vMap1.Extent(); ++i )
+  {
+    const TopoDS_Shape& v1 = vMap1(i);
+    if ( vMap2.Contains( v1 ))
+    {
+      // find an egde sharing v1 and sharing at the same time another common vertex
+      PShapeIteratorPtr edgeIt = SMESH_MesherHelper::GetAncestors( v1, *theMesh1, TopAbs_EDGE);
+      bool edgeFound = false;
+      while ( edgeIt->more() && !edgeFound )
+      {
+        TopoDS_Edge edge = TopoDS::Edge( edgeIt->next()->Oriented(TopAbs_FORWARD));
+        TopExp::Vertices(edge, VV1[0], VV1[1]);
+        if ( !VV1[0].IsSame( VV1[1] ))
+          edgeFound = ( vMap2.Contains( VV1[ v1.IsSame(VV1[0]) ? 1:0]));
+      }
+      if ( edgeFound )
+      {
+        InsertAssociation( VV1[0], VV1[0], theMap );
+        InsertAssociation( VV1[1], VV1[1], theMap );
+        if (FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap ))
+          return true;
+      }
+    }
+  }
+
   // Find transformation to make the shapes be of similar size at same location
 
   Bnd_Box box[2];
@@ -888,30 +1174,12 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
 
   // Find 2 closest vertices
 
-  TopoDS_Vertex VV1[2], VV2[2];
   // get 2 linked vertices of shape 1 not belonging to an inner wire of a face
-  TopoDS_Shape edge = theShape1;
-  TopExp_Explorer expF( theShape1, TopAbs_FACE ), expE;
-  if ( expF.More() ) {
-    for ( ; expF.More(); expF.Next() ) {
-      edge.Nullify();
-      TopoDS_Shape wire = OuterShape( TopoDS::Face( expF.Current() ), TopAbs_WIRE );
-      for ( expE.Init( wire, TopAbs_EDGE ); edge.IsNull() && expE.More(); expE.Next() )
-        if ( !IsClosedEdge( TopoDS::Edge( expE.Current() )))
-          edge = expE.Current();
-      if ( !edge.IsNull() )
-        break;
-    }
-  } else if (edge.ShapeType() != TopAbs_EDGE) { // no faces
-    edge.Nullify();
-    for ( expE.Init( theShape1, TopAbs_EDGE ); edge.IsNull() && expE.More(); expE.Next() )
-      if ( !IsClosedEdge( TopoDS::Edge( expE.Current() )))
-        edge = expE.Current();
-  }
+  TopoDS_Shape edge = getOuterEdge( theShape1, *theMesh1 );
   if ( edge.IsNull() || edge.ShapeType() != TopAbs_EDGE )
     RETURN_BAD_RESULT("Edge not found");
 
-  TopExp::Vertices( TopoDS::Edge( edge ), VV1[0], VV1[1]);
+  TopExp::Vertices( TopoDS::Edge( edge.Oriented(TopAbs_FORWARD)), VV1[0], VV1[1]);
   if ( VV1[0].IsSame( VV1[1] ))
     RETURN_BAD_RESULT("Only closed edges");
 
@@ -933,14 +1201,14 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
     }
   }
 
-  InsertAssociation( VV1[ 0 ], VV2[ 0 ], theMap, bidirect);
-  InsertAssociation( VV1[ 1 ], VV2[ 1 ], theMap, bidirect);
+  InsertAssociation( VV1[ 0 ], VV2[ 0 ], theMap );
+  InsertAssociation( VV1[ 1 ], VV2[ 1 ], theMap );
   MESSAGE("Initial assoc VERT " << theMesh1->GetMeshDS()->ShapeToIndex( VV1[ 0 ] )<<
           " to "                << theMesh2->GetMeshDS()->ShapeToIndex( VV2[ 0 ] )<<
           "\nand         VERT " << theMesh1->GetMeshDS()->ShapeToIndex( VV1[ 1 ] )<<
           " to "                << theMesh2->GetMeshDS()->ShapeToIndex( VV2[ 1 ] ));
   if ( theShape1.ShapeType() == TopAbs_EDGE ) {
-    InsertAssociation( theShape1, theShape2, theMap, bidirect );
+    InsertAssociation( theShape1, theShape2, theMap );
     return true;
   }
 
@@ -953,75 +1221,153 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
  * \param face1 - face 1
  * \param VV1 - vertices of face 1
  * \param face2 - face 2
- * \param VV2 - vertices of face 2 associated with oned of face 1
+ * \param VV2 - vertices of face 2 associated with ones of face 1
  * \param edges1 - out list of edges of face 1
  * \param edges2 - out list of edges of face 2
  * \retval int - nb of edges in an outer wire in a success case, else zero
  */
 //================================================================================
 
-int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1,
-                                                    TopoDS_Vertex      VV1[2],
-                                                    const TopoDS_Face& face2,
-                                                    TopoDS_Vertex      VV2[2],
+int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face&    face1,
+                                                    TopoDS_Vertex         VV1[2],
+                                                    const TopoDS_Face&    face2,
+                                                    TopoDS_Vertex         VV2[2],
                                                     list< TopoDS_Edge > & edges1,
                                                     list< TopoDS_Edge > & edges2)
 {
-  edges1.clear();
-  edges2.clear();
-
-  list< int > nbVInW1, nbVInW2;
-  if ( SMESH_Block::GetOrderedEdges( face1, VV1[0], edges1, nbVInW1) !=
-       SMESH_Block::GetOrderedEdges( face2, VV2[0], edges2, nbVInW2) )
-    RETURN_BAD_RESULT("Different number of wires in faces ");
-
-  if ( nbVInW1.front() != nbVInW2.front() )
-    RETURN_BAD_RESULT("Different number of edges in faces: " <<
-                      nbVInW1.front() << " != " << nbVInW2.front());
-
-  // Define if we need to reverse one of wires to make edges in lists match each other
-
-  bool reverse = false;
-
-  list< TopoDS_Edge >::iterator eBackIt;
-  if ( !VV1[1].IsSame( TopExp::LastVertex( edges1.front(), true ))) {
-    reverse = true;
-    eBackIt = --edges1.end();
-    // check if the second vertex belongs to the first or last edge in the wire
-    if ( !VV1[1].IsSame( TopExp::FirstVertex( *eBackIt, true ))) {
-      bool KO = true; // belongs to none
-      if ( nbVInW1.size() > 1 ) { // several wires
-        eBackIt = edges1.begin();
-        for ( int i = 1; i < nbVInW1.front(); ++i ) ++eBackIt;
-        KO = !VV1[1].IsSame( TopExp::FirstVertex( *eBackIt, true ));
+  bool OK = false;
+  list< int > nbEInW1, nbEInW2;
+  int i_ok_wire_algo = -1;
+  for ( int outer_wire_algo = 0; outer_wire_algo < 2 && !OK; ++outer_wire_algo )
+  {
+    edges1.clear();
+    edges2.clear();
+
+    if ( SMESH_Block::GetOrderedEdges( face1, VV1[0], edges1, nbEInW1, outer_wire_algo) !=
+         SMESH_Block::GetOrderedEdges( face2, VV2[0], edges2, nbEInW2, outer_wire_algo) )
+      CONT_BAD_RESULT("Different number of wires in faces ");
+
+    if ( nbEInW1 != nbEInW2 )
+      CONT_BAD_RESULT("Different number of edges in faces: " <<
+                      nbEInW1.front() << " != " << nbEInW2.front());
+
+    i_ok_wire_algo = outer_wire_algo;
+
+    // Define if we need to reverse one of wires to make edges in lists match each other
+
+    bool reverse = false;
+
+    list< TopoDS_Edge >::iterator edgeIt;
+    if ( !VV1[1].IsSame( TopExp::LastVertex( edges1.front(), true ))) {
+      reverse = true;
+      edgeIt = --edges1.end();
+      // check if the second vertex belongs to the first or last edge in the wire
+      if ( !VV1[1].IsSame( TopExp::FirstVertex( *edgeIt, true ))) {
+        bool KO = true; // belongs to none
+        if ( nbEInW1.size() > 1 ) { // several wires
+          edgeIt = edges1.begin();
+          std::advance( edgeIt, nbEInW1.front()-1 );
+          KO = !VV1[1].IsSame( TopExp::FirstVertex( *edgeIt, true ));
+        }
+        if ( KO )
+          CONT_BAD_RESULT("GetOrderedEdges() failed");
       }
-      if ( KO )
-        RETURN_BAD_RESULT("GetOrderedEdges() failed");
     }
-  }
-  eBackIt = --edges2.end();
-  if ( !VV2[1].IsSame( TopExp::LastVertex( edges2.front(), true ))) {
-    reverse = !reverse;
-    // check if the second vertex belongs to the first or last edge in the wire
-    if ( !VV2[1].IsSame( TopExp::FirstVertex( *eBackIt, true ))) {
-      bool KO = true; // belongs to none
-      if ( nbVInW2.size() > 1 ) { // several wires
-        eBackIt = edges2.begin();
-        for ( int i = 1; i < nbVInW2.front(); ++i ) ++eBackIt;
-        KO = !VV2[1].IsSame( TopExp::FirstVertex( *eBackIt, true ));
+    edgeIt = --edges2.end();
+    if ( !VV2[1].IsSame( TopExp::LastVertex( edges2.front(), true ))) {
+      reverse = !reverse;
+      // check if the second vertex belongs to the first or last edge in the wire
+      if ( !VV2[1].IsSame( TopExp::FirstVertex( *edgeIt, true ))) {
+        bool KO = true; // belongs to none
+        if ( nbEInW2.size() > 1 ) { // several wires
+          edgeIt = edges2.begin();
+          std::advance( edgeIt, nbEInW2.front()-1 );
+          KO = !VV2[1].IsSame( TopExp::FirstVertex( *edgeIt, true ));
+        }
+        if ( KO )
+          CONT_BAD_RESULT("GetOrderedEdges() failed");
       }
-      if ( KO )
-        RETURN_BAD_RESULT("GetOrderedEdges() failed");
     }
-  }
-  if ( reverse )
+    if ( reverse )
+    {
+      Reverse( edges2 , nbEInW2.front());
+      if (( VV1[1].IsSame( TopExp::LastVertex( edges1.front(), true ))) !=
+          ( VV2[1].IsSame( TopExp::LastVertex( edges2.front(), true ))))
+        CONT_BAD_RESULT("GetOrderedEdges() failed");
+    }
+    OK = true;
+
+  } // loop algos getting an outer wire
+  
+  // Try to orient all (if !OK) or only internal wires (issue 0020996) by UV similarity
+  if (( !OK || nbEInW1.size() > 1 ) && i_ok_wire_algo > -1 )
   {
-    Reverse( edges2 , nbVInW2.front());
-    if (( VV1[1].IsSame( TopExp::LastVertex( edges1.front(), true ))) !=
-        ( VV2[1].IsSame( TopExp::LastVertex( edges2.front(), true ))))
-      RETURN_BAD_RESULT("GetOrderedEdges() failed");
+    // Check that Vec(VV1[0],VV1[1]) in 2D on face1 is the same
+    // as Vec(VV2[0],VV2[1]) on face2
+    double vTol = BRep_Tool::Tolerance( VV1[0] );
+    BRepAdaptor_Surface surface1( face1, false );
+    double vTolUV =
+      surface1.UResolution( vTol ) + surface1.VResolution( vTol ); // let's be tolerant
+    gp_Pnt2d v0f1UV = BRep_Tool::Parameters( VV1[0], face1 );
+    gp_Pnt2d v0f2UV = BRep_Tool::Parameters( VV2[0], face2 );
+    gp_Pnt2d v1f1UV = BRep_Tool::Parameters( VV1[1], face1 );
+    gp_Pnt2d v1f2UV = BRep_Tool::Parameters( VV2[1], face2 );
+    gp_Vec2d v01f1Vec( v0f1UV, v1f1UV );
+    gp_Vec2d v01f2Vec( v0f2UV, v1f2UV );
+    if ( Abs( v01f1Vec.X()-v01f2Vec.X()) < vTolUV &&
+         Abs( v01f1Vec.Y()-v01f2Vec.Y()) < vTolUV )
+    {
+      if ( !OK /*i_ok_wire_algo != 1*/ )
+      {
+        edges1.clear();
+        edges2.clear();
+        SMESH_Block::GetOrderedEdges( face1, VV1[0], edges1, nbEInW1, i_ok_wire_algo);
+        SMESH_Block::GetOrderedEdges( face2, VV2[0], edges2, nbEInW2, i_ok_wire_algo);
+      }
+      gp_XY dUV = v0f2UV.XY() - v0f1UV.XY(); // UV shift between 2 faces
+      // skip edges of the outer wire (if the outer wire is OK)
+      list< int >::iterator nbEInW = nbEInW1.begin();
+      list< TopoDS_Edge >::iterator edge1Beg = edges1.begin(), edge2Beg = edges2.begin();
+      if ( OK )
+      {
+        for ( int i = 0; i < *nbEInW; ++i )
+          ++edge1Beg, ++edge2Beg;
+        ++nbEInW;
+      }
+      for ( ; nbEInW != nbEInW1.end(); ++nbEInW ) // loop on wires
+      {
+        // reach an end of edges of a current wire
+        list< TopoDS_Edge >::iterator edge1End = edge1Beg, edge2End = edge2Beg;
+        for ( int i = 0; i < *nbEInW; ++i )
+          ++edge1End, ++edge2End;
+        // rotate edges2 untill coincident with edges1 in 2D
+        v0f1UV = BRep_Tool::Parameters( TopExp::FirstVertex(*edge1Beg,true), face1 );
+        v1f1UV = BRep_Tool::Parameters( TopExp::LastVertex (*edge1Beg,true), face1 );
+        v0f1UV.ChangeCoord() += dUV;
+        v1f1UV.ChangeCoord() += dUV;
+        int i = *nbEInW;
+        while ( --i > 0 && !sameVertexUV( *edge2Beg, face2, 0, v0f1UV, vTolUV ))
+          edges2.splice( edge2End, edges2, edge2Beg++ ); // move edge2Beg to place before edge2End
+        if ( sameVertexUV( *edge2Beg, face2, 0, v0f1UV, vTolUV ))
+        {
+          if ( nbEInW == nbEInW1.begin() )
+            OK = true; // OK is for the first wire
+          // reverse edges2 if needed
+          if ( !sameVertexUV( *edge2Beg, face2, 1, v1f1UV, vTolUV ))
+          {
+            Reverse( edges2 , *nbEInW, distance( edges2.begin(),edge2Beg ));
+            // set correct edge2End
+            edge2End = edges2.begin();
+            std::advance( edge2End, std::accumulate( nbEInW1.begin(), nbEInW, *nbEInW));
+          }
+        }
+        // prepare to the next wire loop
+        edge1Beg = edge1End, edge2Beg = edge2End;
+      }
+    }
   }
-  return nbVInW2.front();
+
+  return OK ? nbEInW1.front() : 0;
 }
 
 //=======================================================================
@@ -1030,30 +1376,29 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1,
 //=======================================================================
 
 void StdMeshers_ProjectionUtils::InitVertexAssociation( const SMESH_Hypothesis* theHyp,
-                                                        TShapeShapeMap &        theAssociationMap,
-                                                        const TopoDS_Shape&     theTargetShape)
+                                                        TShapeShapeMap &        theAssociationMap)
 {
   string hypName = theHyp->GetName();
   if ( hypName == "ProjectionSource1D" ) {
     const StdMeshers_ProjectionSource1D * hyp =
       static_cast<const StdMeshers_ProjectionSource1D*>( theHyp );
     if ( hyp->HasVertexAssociation() )
-      InsertAssociation( hyp->GetSourceVertex(),hyp->GetTargetVertex(),theAssociationMap);
+      InsertAssociation( hyp->GetTargetVertex(),hyp->GetSourceVertex(),theAssociationMap );
   }
   else if ( hypName == "ProjectionSource2D" ) {
     const StdMeshers_ProjectionSource2D * hyp =
       static_cast<const StdMeshers_ProjectionSource2D*>( theHyp );
     if ( hyp->HasVertexAssociation() ) {
-      InsertAssociation( hyp->GetSourceVertex(1),hyp->GetTargetVertex(1),theAssociationMap);
-      InsertAssociation( hyp->GetSourceVertex(2),hyp->GetTargetVertex(2),theAssociationMap);
+      InsertAssociation( hyp->GetTargetVertex(1),hyp->GetSourceVertex(1),theAssociationMap);
+      InsertAssociation( hyp->GetTargetVertex(2),hyp->GetSourceVertex(2),theAssociationMap);
     }
   }
   else if ( hypName == "ProjectionSource3D" ) {
     const StdMeshers_ProjectionSource3D * hyp =
       static_cast<const StdMeshers_ProjectionSource3D*>( theHyp );
     if ( hyp->HasVertexAssociation() ) {
-      InsertAssociation( hyp->GetSourceVertex(1),hyp->GetTargetVertex(1),theAssociationMap);
-      InsertAssociation( hyp->GetSourceVertex(2),hyp->GetTargetVertex(2),theAssociationMap);
+      InsertAssociation( hyp->GetTargetVertex(1),hyp->GetSourceVertex(1),theAssociationMap);
+      InsertAssociation( hyp->GetTargetVertex(2),hyp->GetSourceVertex(2),theAssociationMap);
     }
   }
 }
@@ -1061,24 +1406,21 @@ void StdMeshers_ProjectionUtils::InitVertexAssociation( const SMESH_Hypothesis*
 //=======================================================================
 /*!
  * \brief Inserts association theShape1 <-> theShape2 to TShapeShapeMap
- * \param theShape1 - shape 1
- * \param theShape2 - shape 2
+ * \param theShape1 - target shape
+ * \param theShape2 - source shape
  * \param theAssociationMap - association map 
  * \retval bool - true if there was no association for these shapes before
  */
 //=======================================================================
 
-bool StdMeshers_ProjectionUtils::InsertAssociation( const TopoDS_Shape& theShape1,
-                                                    const TopoDS_Shape& theShape2,
-                                                    TShapeShapeMap &    theAssociationMap,
-                                                    const bool          theBidirectional)
+bool StdMeshers_ProjectionUtils::InsertAssociation( const TopoDS_Shape& theShape1, // tgt
+                                                    const TopoDS_Shape& theShape2, // src
+                                                    TShapeShapeMap &    theAssociationMap)
 {
   if ( !theShape1.IsNull() && !theShape2.IsNull() ) {
-    SHOW_VERTEX(theShape1,"Assoc ");
-    SHOW_VERTEX(theShape2," to ");
+    SHOW_SHAPE(theShape1,"Assoc ");
+    SHOW_SHAPE(theShape2," to ");
     bool isNew = ( theAssociationMap.Bind( theShape1, theShape2 ));
-    if ( theBidirectional )
-      theAssociationMap.Bind( theShape2, theShape1 );
     return isNew;
   }
   else {
@@ -1087,44 +1429,6 @@ bool StdMeshers_ProjectionUtils::InsertAssociation( const TopoDS_Shape& theShape
   return false;
 }
 
-//=======================================================================
-//function : IsSubShape
-//purpose  : 
-//=======================================================================
-
-bool StdMeshers_ProjectionUtils::IsSubShape( const TopoDS_Shape& shape,
-                                             SMESH_Mesh*         aMesh )
-{
-  if ( shape.IsNull() || !aMesh )
-    return false;
-  return
-    aMesh->GetMeshDS()->ShapeToIndex( shape ) ||
-    // PAL16202
-    shape.ShapeType() == TopAbs_COMPOUND && aMesh->GetMeshDS()->IsGroupOfSubShapes( shape );
-}
-
-//=======================================================================
-//function : IsSubShape
-//purpose  : 
-//=======================================================================
-
-bool StdMeshers_ProjectionUtils::IsSubShape( const TopoDS_Shape& shape,
-                                             const TopoDS_Shape& mainShape )
-{
-  if ( !shape.IsNull() && !mainShape.IsNull() )
-  {
-    for ( TopExp_Explorer exp( mainShape, shape.ShapeType());
-          exp.More();
-          exp.Next() )
-      if ( shape.IsSame( exp.Current() ))
-        return true;
-  }
-  SCRUTE((shape.IsNull()));
-  SCRUTE((mainShape.IsNull()));
-  return false;
-}
-
-
 //=======================================================================
 /*!
  * \brief Finds an edge by its vertices in a main shape of the mesh
@@ -1210,7 +1514,7 @@ StdMeshers_ProjectionUtils::GetPropagationEdge( SMESH_Mesh*        aMesh,
                                                 const TopoDS_Edge& theEdge,
                                                 const TopoDS_Edge& fromEdge)
 {
-  SMESH_IndexedMapOfShape aChain;
+  TopTools_IndexedMapOfShape aChain;
   int step = 0;
 
   // List of edges, added to chain on the previous cycle pass
@@ -1286,7 +1590,7 @@ StdMeshers_ProjectionUtils::GetPropagationEdge( SMESH_Mesh*        aMesh,
     * \param mesh1 - mesh containing elements on the first face
     * \param face2 - the second face
     * \param mesh2 - mesh containing elements on the second face
-    * \param assocMap - map associating subshapes of the faces
+    * \param assocMap - map associating sub-shapes of the faces
     * \param node1To2Map - map containing found matching nodes
     * \retval bool - is a success
    */
@@ -1330,24 +1634,25 @@ FindMatchingNodesOnFaces( const TopoDS_Face&     face1,
   // 1. Nodes of corresponding links:
 
   // get 2 matching edges, try to find not seam ones
-  TopoDS_Edge edge1, edge2, seam1, seam2;
+  TopoDS_Edge edge1, edge2, seam1, seam2, anyEdge1, anyEdge2;
   TopExp_Explorer eE( OuterShape( face2, TopAbs_WIRE ), TopAbs_EDGE );
   do {
     // edge 2
     TopoDS_Edge e2 = TopoDS::Edge( eE.Current() );
     eE.Next();
     // edge 1
-    if ( !assocMap.IsBound( e2 ))
+    if ( !assocMap.IsBound( e2, /*is2nd=*/true ))
       RETURN_BAD_RESULT("Association not found for edge " << meshDS2->ShapeToIndex( e2 ));
-    TopoDS_Edge e1 = TopoDS::Edge( assocMap( e2 ));
-    if ( !IsSubShape( e1, face1 ))
+    TopoDS_Edge e1 = TopoDS::Edge( assocMap( e2, /*is2nd=*/true ));
+    if ( !helper1.IsSubShape( e1, face1 ))
       RETURN_BAD_RESULT("Wrong association, edge " << meshDS1->ShapeToIndex( e1 ) <<
-                        " isn't a subshape of face " << meshDS1->ShapeToIndex( face1 ));
+                        " isn't a sub-shape of face " << meshDS1->ShapeToIndex( face1 ));
     // check that there are nodes on edges
     SMESHDS_SubMesh * eSM1 = meshDS1->MeshElements( e1 );
     SMESHDS_SubMesh * eSM2 = meshDS2->MeshElements( e2 );
     bool nodesOnEdges = ( eSM1 && eSM2 && eSM1->NbNodes() && eSM2->NbNodes() );
     // check that the nodes on edges belong to faces
+    // (as NETGEN ignores nodes on the degenerated geom edge)
     bool nodesOfFaces = false;
     if ( nodesOnEdges ) {
       const SMDS_MeshNode* n1 = eSM1->GetNodes()->next();
@@ -1364,18 +1669,25 @@ FindMatchingNodesOnFaces( const TopoDS_Face&     face1,
         edge1 = e1; edge2 = e2;
       }
     }
+    else {
+      anyEdge1 = e1; anyEdge2 = e2;
+    }
   } while ( edge2.IsNull() && eE.More() );
   //
   if ( edge2.IsNull() ) {
     edge1 = seam1; edge2 = seam2;
   }
-  if ( edge2.IsNull() ) RETURN_BAD_RESULT("No matching edges with nodes found");
+  bool hasNodesOnEdge = (! edge2.IsNull() );
+  if ( !hasNodesOnEdge ) {
+    // 0020338 - nb segments == 1
+    edge1 = anyEdge1; edge2 = anyEdge2;
+  }
 
   // get 2 matching vertices
   TopoDS_Vertex V2 = TopExp::FirstVertex( TopoDS::Edge( edge2 ));
-  if ( !assocMap.IsBound( V2 ))
+  if ( !assocMap.IsBound( V2, /*is2nd=*/true ))
     RETURN_BAD_RESULT("Association not found for vertex " << meshDS2->ShapeToIndex( V2 ));
-  TopoDS_Vertex V1 = TopoDS::Vertex( assocMap( V2 ));
+  TopoDS_Vertex V1 = TopoDS::Vertex( assocMap( V2, /*is2nd=*/true ));
 
   // nodes on vertices
   const SMDS_MeshNode* vNode1 = SMESH_Algo::VertexNode( V1, meshDS1 );
@@ -1387,35 +1699,52 @@ FindMatchingNodesOnFaces( const TopoDS_Face&     face1,
   const SMDS_MeshNode* nullNode = 0;
   vector< const SMDS_MeshNode*> eNode1( 2, nullNode );
   vector< const SMDS_MeshNode*> eNode2( 2, nullNode );
-  int nbNodeToGet = 1;
-  if ( IsClosedEdge( edge1 ) || IsClosedEdge( edge2 ) )
-    nbNodeToGet = 2;
-  for ( int is2 = 0; is2 < 2; ++is2 )
+  if ( hasNodesOnEdge )
   {
-    TopoDS_Edge &     edge  = is2 ? edge2 : edge1;
-    SMESHDS_Mesh *    smDS  = is2 ? meshDS2 : meshDS1;
-    SMESHDS_SubMesh* edgeSM = smDS->MeshElements( edge );
-    // nodes linked with ones on vertices
-    const SMDS_MeshNode*           vNode = is2 ? vNode2 : vNode1;
-    vector< const SMDS_MeshNode*>& eNode = is2 ? eNode2 : eNode1;
-    int nbGotNode = 0;
-    SMDS_ElemIteratorPtr vElem = vNode->GetInverseElementIterator();
-    while ( vElem->more() && nbGotNode != nbNodeToGet ) {
-      const SMDS_MeshElement* elem = vElem->next();
-      if ( elem->GetType() == SMDSAbs_Edge && edgeSM->Contains( elem ))
-        eNode[ nbGotNode++ ] = 
-          ( elem->GetNode(0) == vNode ) ? elem->GetNode(1) : elem->GetNode(0);
-    }
-    if ( nbGotNode > 1 ) // sort found nodes by param on edge
+    int nbNodeToGet = 1;
+    if ( helper1.IsClosedEdge( edge1 ) || helper2.IsClosedEdge( edge2 ) )
+      nbNodeToGet = 2;
+    for ( int is2 = 0; is2 < 2; ++is2 )
     {
-      SMESH_MesherHelper* helper = is2 ? &helper2 : &helper1;
-      double u0 = helper->GetNodeU( edge, eNode[ 0 ]);
-      double u1 = helper->GetNodeU( edge, eNode[ 1 ]);
-      if ( u0 > u1 ) std::swap( eNode[ 0 ], eNode[ 1 ]);
+      TopoDS_Edge &     edge  = is2 ? edge2 : edge1;
+      SMESHDS_Mesh *    smDS  = is2 ? meshDS2 : meshDS1;
+      SMESHDS_SubMesh* edgeSM = smDS->MeshElements( edge );
+      // nodes linked with ones on vertices
+      const SMDS_MeshNode*           vNode = is2 ? vNode2 : vNode1;
+      vector< const SMDS_MeshNode*>& eNode = is2 ? eNode2 : eNode1;
+      int nbGotNode = 0;
+      SMDS_ElemIteratorPtr vElem = vNode->GetInverseElementIterator(SMDSAbs_Edge);
+      while ( vElem->more() && nbGotNode != nbNodeToGet ) {
+        const SMDS_MeshElement* elem = vElem->next();
+        if ( edgeSM->Contains( elem ))
+          eNode[ nbGotNode++ ] = 
+            ( elem->GetNode(0) == vNode ) ? elem->GetNode(1) : elem->GetNode(0);
+      }
+      if ( nbGotNode > 1 ) // sort found nodes by param on edge
+      {
+        SMESH_MesherHelper* helper = is2 ? &helper2 : &helper1;
+        double u0 = helper->GetNodeU( edge, eNode[ 0 ]);
+        double u1 = helper->GetNodeU( edge, eNode[ 1 ]);
+        if ( u0 > u1 ) std::swap( eNode[ 0 ], eNode[ 1 ]);
+      }
+      if ( nbGotNode == 0 )
+        RETURN_BAD_RESULT("Found no nodes on edge " << smDS->ShapeToIndex( edge ) <<
+                          " linked to " << vNode );
     }
-    if ( nbGotNode == 0 )
-      RETURN_BAD_RESULT("Found no nodes on edge " << smDS->ShapeToIndex( edge ) <<
-                        " linked to " << vNode );
+  }
+  else // 0020338 - nb segments == 1
+  {
+    // get 2 other matching vertices
+    V2 = TopExp::LastVertex( TopoDS::Edge( edge2 ));
+    if ( !assocMap.IsBound( V2, /*is2nd=*/true ))
+      RETURN_BAD_RESULT("Association not found for vertex " << meshDS2->ShapeToIndex( V2 ));
+    V1 = TopoDS::Vertex( assocMap( V2, /*is2nd=*/true ));
+
+    // nodes on vertices
+    eNode1[0] = SMESH_Algo::VertexNode( V1, meshDS1 );
+    eNode2[0] = SMESH_Algo::VertexNode( V2, meshDS2 );
+    if ( !eNode1[0] ) RETURN_BAD_RESULT("No node on vertex #" << meshDS1->ShapeToIndex( V1 ));
+    if ( !eNode2[0] ) RETURN_BAD_RESULT("No node on vertex #" << meshDS2->ShapeToIndex( V2 ));
   }
 
   // 2. face sets
@@ -1461,7 +1790,7 @@ FindMatchingNodesOnFaces( const TopoDS_Face&     face1,
         const SMDS_MeshElement* f = ( iF ? f2 : f1 );
         for ( int i = 0; !notSeamNode[ iF ] && i < f->NbNodes(); ++i ) {
           const SMDS_MeshNode* node = f->GetNode( i );
-          if ( !helper->IsSeamShape( node->GetPosition()->GetShapeId() ))
+          if ( !helper->IsSeamShape( node->getshapeId() ))
             notSeamNode[ iF ] = node;
         }
       }
@@ -1494,7 +1823,7 @@ FindMatchingNodesOnFaces( const TopoDS_Face&     face1,
       notInSet.insert( f2 );
       for ( int i = 0; i < nbNodes; ++i ) {
         const SMDS_MeshNode* n1 = faceToKeep->GetNode( i );
-        const SMDS_MeshNode* n2 = faceToKeep->GetNode( i+1 );
+        const SMDS_MeshNode* n2 = faceToKeep->GetNode(( i+1 ) % nbNodes );
         f1 = SMESH_MeshEditor::FindFaceInSet( n1, n2, inSet, notInSet );
         if ( f1 )
           elems.insert( f1 );
@@ -1529,7 +1858,7 @@ FindMatchingNodesOnFaces( const TopoDS_Face&     face1,
       while ( nIt->more() ) {
         const SMDS_MeshNode* node = nIt->next();
         const SMDS_EdgePosition* pos =
-          static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+          static_cast<const SMDS_EdgePosition*>(node->GetPosition());
         pos2nodes.insert( make_pair( pos->GetUParameter(), node ));
       }
       if ( pos2nodes.size() != edgeSM->NbNodes() )
@@ -1561,9 +1890,9 @@ FindMatchingNodesOnFaces( const TopoDS_Face&     face1,
 
     // associate matching nodes on the last vertices
     V2 = TopExp::LastVertex( TopoDS::Edge( edge2 ));
-    if ( !assocMap.IsBound( V2 ))
+    if ( !assocMap.IsBound( V2, /*is2nd=*/true ))
       RETURN_BAD_RESULT("Association not found for vertex " << meshDS2->ShapeToIndex( V2 ));
-    V1 = TopoDS::Vertex( assocMap( V2 ));
+    V1 = TopoDS::Vertex( assocMap( V2, /*is2nd=*/true ));
     vNode1 = SMESH_Algo::VertexNode( V1, meshDS1 );
     vNode2 = SMESH_Algo::VertexNode( V2, meshDS2 );
     if ( !vNode1 ) RETURN_BAD_RESULT("No node on vertex #" << meshDS1->ShapeToIndex( V1 ));
@@ -1581,25 +1910,12 @@ FindMatchingNodesOnFaces( const TopoDS_Face&     face1,
   return true;
 }
 
-//================================================================================
-/*!
- * \brief Check if the first and last vertices of an edge are the same
- * \param anEdge - the edge to check
- * \retval bool - true if same
- */
-//================================================================================
-
-bool StdMeshers_ProjectionUtils::IsClosedEdge( const TopoDS_Edge& anEdge )
-{
-  return TopExp::FirstVertex( anEdge ).IsSame( TopExp::LastVertex( anEdge ));
-}
-
 //================================================================================
   /*!
-   * \brief Return any subshape of a face belonging to the outer wire
+   * \brief Return any sub-shape of a face belonging to the outer wire
     * \param face - the face
-    * \param type - type of subshape to return
-    * \retval TopoDS_Shape - the found subshape
+    * \param type - type of sub-shape to return
+    * \retval TopoDS_Shape - the found sub-shape
    */
 //================================================================================
 
@@ -1632,7 +1948,7 @@ bool StdMeshers_ProjectionUtils::MakeComputed(SMESH_subMesh * sm, const int iter
 
   SMESH_Mesh* mesh = sm->GetFather();
   SMESH_Gen* gen   = mesh->GetGen();
-  SMESH_Algo* algo = gen->GetAlgo( *mesh, sm->GetSubShape() );
+  SMESH_Algo* algo = sm->GetAlgo();
   if ( !algo )
   {
     if ( sm->GetSubShape().ShapeType() != TopAbs_COMPOUND )
@@ -1695,12 +2011,12 @@ bool StdMeshers_ProjectionUtils::MakeComputed(SMESH_subMesh * sm, const int iter
 }
 
 //================================================================================
-  /*!
  * \brief Count nb of subshapes
   * \param shape - the shape
   * \param type - the type of subshapes to count
   * \retval int - the calculated number
  */
+/*!
* \brief Count nb of sub-shapes
+ * \param shape - the shape
* \param type - the type of sub-shapes to count
+ * \retval int - the calculated number
+ */
 //================================================================================
 
 int StdMeshers_ProjectionUtils::Count(const TopoDS_Shape&    shape,
@@ -1720,7 +2036,37 @@ int StdMeshers_ProjectionUtils::Count(const TopoDS_Shape&    shape,
   }
 }
 
-namespace {
+//================================================================================
+/*!
+ * \brief Return a boundary EDGE of edgeContainer
+ */
+//================================================================================
+
+TopoDS_Edge StdMeshers_ProjectionUtils::GetBoundaryEdge(const TopoDS_Shape& edgeContainer,
+                                                        const SMESH_Mesh&   mesh)
+{
+  TopTools_IndexedMapOfShape facesOfEdgeContainer, facesNearEdge;
+  TopExp::MapShapes( edgeContainer, TopAbs_FACE, facesOfEdgeContainer );
+
+  if ( !facesOfEdgeContainer.IsEmpty() ) 
+    for ( TopExp_Explorer exp(edgeContainer, TopAbs_EDGE); exp.More(); exp.Next() )
+    {
+      const TopoDS_Edge& edge = TopoDS::Edge( exp.Current() );
+      facesNearEdge.Clear();
+      PShapeIteratorPtr faceIt = SMESH_MesherHelper::GetAncestors( edge, mesh, TopAbs_FACE );
+      while ( const TopoDS_Shape* face = faceIt->next() )
+        if ( facesOfEdgeContainer.Contains( *face ))
+          if ( facesNearEdge.Add( *face ) && facesNearEdge.Extent() > 1 )
+            break;
+      if ( facesNearEdge.Extent() == 1 )
+        return edge;
+    }
+
+  return TopoDS_Edge();
+}
+
+
+namespace { // Definition of event listeners
 
   SMESH_subMeshEventListener* GetSrcSubMeshListener();
 
@@ -1733,8 +2079,8 @@ namespace {
 
   struct HypModifWaiter: SMESH_subMeshEventListener
   {
-    HypModifWaiter():SMESH_subMeshEventListener(0){} // won't be deleted by submesh
-
+    HypModifWaiter():SMESH_subMeshEventListener(false,// won't be deleted by submesh
+                                                "StdMeshers_ProjectionUtils::HypModifWaiter") {}
     void ProcessEvent(const int event, const int eventType, SMESH_subMesh* subMesh,
                       EventListenerData*, const SMESH_Hypothesis*)
     {
@@ -1744,9 +2090,7 @@ namespace {
         // delete current source listener
         subMesh->DeleteEventListener( GetSrcSubMeshListener() );
         // let algo set a new one
-        SMESH_Gen* gen = subMesh->GetFather()->GetGen();
-        if ( SMESH_Algo* algo = gen->GetAlgo( *subMesh->GetFather(),
-                                              subMesh->GetSubShape() ))
+        if ( SMESH_Algo* algo = subMesh->GetAlgo() )
           algo->SetEventListener( subMesh );
       }
     }
@@ -1768,7 +2112,8 @@ namespace {
   //================================================================================
 
   SMESH_subMeshEventListener* GetSrcSubMeshListener() {
-    static SMESH_subMeshEventListener srcListener(0); // won't be deleted by submesh
+    static SMESH_subMeshEventListener srcListener(false, // won't be deleted by submesh
+                                                  "StdMeshers_ProjectionUtils::SrcSubMeshListener");
     return &srcListener;
   }
 }
@@ -1787,7 +2132,7 @@ void StdMeshers_ProjectionUtils::SetEventListener(SMESH_subMesh* subMesh,
                                                   SMESH_Mesh*    srcMesh)
 {
   // Set listener that resets an event listener on source submesh when
-  // "ProjectionSource*D" hypothesis is modified
+  // "ProjectionSource*D" hypothesis is modified since source shape can be changed
   subMesh->SetEventListener( GetHypModifWaiter(),0,subMesh);
 
   // Set an event listener to submesh of the source shape
@@ -1802,18 +2147,21 @@ void StdMeshers_ProjectionUtils::SetEventListener(SMESH_subMesh* subMesh,
       if ( srcShapeSM->GetSubMeshDS() &&
            srcShapeSM->GetSubMeshDS()->IsComplexSubmesh() )
       {  // source shape is a group
-        TopExp_Explorer it(srcShapeSM->GetSubShape(), // explore the group into subshapes...
+        TopExp_Explorer it(srcShapeSM->GetSubShape(), // explore the group into sub-shapes...
                            subMesh->GetSubShape().ShapeType()); // ...of target shape type
         for (; it.More(); it.Next())
         {
           SMESH_subMesh* srcSM = srcMesh->GetSubMesh( it.Current() );
-          SMESH_subMeshEventListenerData* data =
-            srcSM->GetEventListenerData(GetSrcSubMeshListener());
-          if ( data )
-            data->mySubMeshes.push_back( subMesh );
-          else
-            data = SMESH_subMeshEventListenerData::MakeData( subMesh );
-          subMesh->SetEventListener ( GetSrcSubMeshListener(), data, srcSM );
+          if ( srcSM != subMesh )
+          {
+            SMESH_subMeshEventListenerData* data =
+              srcSM->GetEventListenerData(GetSrcSubMeshListener());
+            if ( data )
+              data->mySubMeshes.push_back( subMesh );
+            else
+              data = SMESH_subMeshEventListenerData::MakeData( subMesh );
+            subMesh->SetEventListener ( GetSrcSubMeshListener(), data, srcSM );
+          }
         }
       }
       else
index 6ca881c88960146cc8cd805d4f6d39ff2c1e1be9..685536a4dca7305eb2513b32d8682966c2dcf6cc 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : idl implementation based on 'SMESH' unit's calsses
 // File      : StdMeshers_ProjectionUtils.hxx
 // Created   : Thu Oct 26 15:37:24 2006
@@ -44,6 +45,29 @@ class SMESH_Hypothesis;
 class SMESH_subMesh;
 class TopTools_IndexedDataMapOfShapeListOfShape;
 
+/*!
+ * \brief Struct used instead of a sole TopTools_DataMapOfShapeShape to avoid
+ *        problems with bidirectional bindings
+ */
+struct StdMeshers_ShapeShapeBiDirectionMap
+{
+  TopTools_DataMapOfShapeShape _map1to2, _map2to1;
+
+  // convension: s1 - target, s2 - source
+  bool Bind( const TopoDS_Shape& s1, const TopoDS_Shape& s2 )
+  { _map1to2.Bind( s1, s2 ); return _map2to1.Bind( s2, s1 ); }
+  bool IsBound( const TopoDS_Shape& s, const bool isShape2=false ) const 
+  { return (isShape2 ? _map2to1 : _map1to2).IsBound( s ); }
+  bool IsEmpty() const { return _map1to2.IsEmpty(); }
+  int Extent() const { return _map1to2.Extent(); }
+  void Clear() { _map1to2.Clear(); _map2to1.Clear(); }
+  const TopoDS_Shape& operator()( const TopoDS_Shape& s, const bool isShape2=false ) const
+  { // if we get a Standard_NoSuchObject here, it means that the calling code
+    // passes incorrect isShape2
+    return (isShape2 ? _map2to1 : _map1to2)( s );
+  }
+};
+
 /*!
  * \brief Class encapsulating methods common to Projection algorithms
  */
@@ -51,12 +75,12 @@ class StdMeshers_ProjectionUtils
 {
  public:
 
-  typedef TopTools_DataMapOfShapeShape                         TShapeShapeMap;
+  typedef StdMeshers_ShapeShapeBiDirectionMap                  TShapeShapeMap;
   typedef TopTools_IndexedDataMapOfShapeListOfShape            TAncestorMap;
   typedef std::map<const SMDS_MeshNode*, const SMDS_MeshNode*> TNodeNodeMap;
 
   /*!
-   * \brief Looks for association of all subshapes of two shapes
+   * \brief Looks for association of all sub-shapes of two shapes
     * \param theShape1 - shape 1
     * \param theMesh1 - mesh built on shape 1
     * \param theShape2 - shape 2
@@ -81,10 +105,10 @@ class StdMeshers_ProjectionUtils
     * \param edges2 - out list of edges of face 2
     * \retval int - nb of edges in an outer wire in a success case, else zero
    */
-  static int FindFaceAssociation(const TopoDS_Face&    face1,
-                                 TopoDS_Vertex         VV1[2],
-                                 const TopoDS_Face&    face2,
-                                 TopoDS_Vertex         VV2[2],
+  static int FindFaceAssociation(const TopoDS_Face&         face1,
+                                 TopoDS_Vertex              VV1[2],
+                                 const TopoDS_Face&         face2,
+                                 TopoDS_Vertex              VV2[2],
                                  std::list< TopoDS_Edge > & edges1,
                                  std::list< TopoDS_Edge > & edges2);
 
@@ -95,25 +119,19 @@ class StdMeshers_ProjectionUtils
     * \param theTargetShape - the shape theHyp assigned to
    */
   static void InitVertexAssociation( const SMESH_Hypothesis* theHyp,
-                                     TShapeShapeMap &        theAssociationMap,
-                                     const TopoDS_Shape&     theTargetShape);
+                                     TShapeShapeMap &        theAssociationMap);
 
   /*!
    * \brief Inserts association theShape1 <-> theShape2 to TShapeShapeMap
-    * \param theShape1 - shape 1
-    * \param theShape2 - shape 2
+    * \param theShape1 - target shape
+    * \param theShape2 - source shape
     * \param theAssociationMap - association map 
     * \param theBidirectional - if false, inserts theShape1 -> theShape2 association
     * \retval bool - true if there was no association for these shapes before
    */
-  static bool InsertAssociation( const TopoDS_Shape& theShape1,
-                                 const TopoDS_Shape& theShape2,
-                                 TShapeShapeMap &    theAssociationMap,
-                                 const bool          theBidirectional=true);
-
-  static bool IsSubShape( const TopoDS_Shape& shape, SMESH_Mesh* aMesh );
-
-  static bool IsSubShape( const TopoDS_Shape& shape, const TopoDS_Shape& mainShape );
+  static bool InsertAssociation( const TopoDS_Shape& theShape1, // target
+                                 const TopoDS_Shape& theShape2, // source
+                                 TShapeShapeMap &    theAssociationMap);
 
   /*!
    * \brief Finds an edge by its vertices in a main shape of the mesh
@@ -151,7 +169,7 @@ class StdMeshers_ProjectionUtils
     * \param mesh1 - mesh containing elements on the first face
     * \param face2 - the second face
     * \param mesh2 - mesh containing elements on the second face
-    * \param assocMap - map associating subshapes of the faces
+    * \param assocMap - map associating sub-shapes of the faces
     * \param nodeIn2OutMap - map containing found matching nodes
     * \retval bool - is a success
    */
@@ -162,17 +180,10 @@ class StdMeshers_ProjectionUtils
                                         const TShapeShapeMap & assocMap,
                                         TNodeNodeMap &         nodeIn2OutMap);
   /*!
-   * \brief Check if the first and last vertices of an edge are the same
-    * \param anEdge - the edge to check
-    * \retval bool - true if same
-   */
-  static bool IsClosedEdge( const TopoDS_Edge& anEdge );
-
-  /*!
-   * \brief Return any subshape of a face belonging to the outer wire
+   * \brief Return any sub-shape of a face belonging to the outer wire
     * \param face - the face
-    * \param type - type of subshape to return
-    * \retval TopoDS_Shape - the found subshape
+    * \param type - type of sub-shape to return
+    * \retval TopoDS_Shape - the found sub-shape
    */
   static TopoDS_Shape OuterShape( const TopoDS_Face& face,
                                   TopAbs_ShapeEnum   type);
@@ -186,9 +197,9 @@ class StdMeshers_ProjectionUtils
   static bool MakeComputed(SMESH_subMesh * sm, const int iterationNb = 0);
 
   /*!
-   * \brief Count nb of subshapes
+   * \brief Count nb of sub-shapes
     * \param shape - the shape
-    * \param type - the type of subshapes to count
+    * \param type - the type of sub-shapes to count
     * \param ignoreSame - if true, use map not to count same shapes, esle use explorer
     * \retval int - the calculated number
    */
@@ -206,6 +217,11 @@ class StdMeshers_ProjectionUtils
                                TopoDS_Shape   srcShape,
                                SMESH_Mesh*    srcMesh);
 
+  /*!
+   * \brief Return a boundary EDGE of edgeContainer
+   */
+  static TopoDS_Edge GetBoundaryEdge(const TopoDS_Shape& edgeContainer,
+                                     const SMESH_Mesh&   mesh);
 };
 
 #endif
index 4fd7c5d8dc9c5fd0192e4b16a1f3ed5653b9173b..778b57c0e605d36495fe5dd7b72b1b9f3ff2921a 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 // File      : StdMeshers_Projection_1D.cxx
 // Module    : SMESH
@@ -67,7 +68,7 @@ StdMeshers_Projection_1D::StdMeshers_Projection_1D(int hypId, int studyId, SMESH
   :SMESH_1D_Algo(hypId, studyId, gen)
 {
   _name = "Projection_1D";
-  _shapeType = (1 << TopAbs_EDGE);     // 1 bit per shape type
+  _shapeType = (1 << TopAbs_EDGE);      // 1 bit per shape type
 
   _compatibleHypothesis.push_back("ProjectionSource1D");
   _sourceHypo = 0;
@@ -128,25 +129,25 @@ bool StdMeshers_Projection_1D::CheckHypothesis(SMESH_Mesh&
     if ( _sourceHypo->HasVertexAssociation() )
     {
       // source and target vertices
-      if ( !TAssocTool::IsSubShape( _sourceHypo->GetSourceVertex(), srcMesh ) ||
-           !TAssocTool::IsSubShape( _sourceHypo->GetTargetVertex(), tgtMesh ) ||
-           !TAssocTool::IsSubShape( _sourceHypo->GetSourceVertex(),
-                                    _sourceHypo->GetSourceEdge() ))
+      if ( !SMESH_MesherHelper::IsSubShape( _sourceHypo->GetSourceVertex(), srcMesh ) ||
+           !SMESH_MesherHelper::IsSubShape( _sourceHypo->GetTargetVertex(), tgtMesh ) ||
+           !SMESH_MesherHelper::IsSubShape( _sourceHypo->GetSourceVertex(),
+                                            _sourceHypo->GetSourceEdge() ))
       {
         aStatus = HYP_BAD_PARAMETER;
-        SCRUTE((TAssocTool::IsSubShape( _sourceHypo->GetSourceVertex(), srcMesh )));
-        SCRUTE((TAssocTool::IsSubShape( _sourceHypo->GetTargetVertex(), tgtMesh )));
-        SCRUTE((TAssocTool::IsSubShape( _sourceHypo->GetSourceVertex(),
-                                        _sourceHypo->GetSourceEdge() )));
+        SCRUTE((SMESH_MesherHelper::IsSubShape( _sourceHypo->GetSourceVertex(), srcMesh )));
+        SCRUTE((SMESH_MesherHelper::IsSubShape( _sourceHypo->GetTargetVertex(), tgtMesh )));
+        SCRUTE((SMESH_MesherHelper::IsSubShape( _sourceHypo->GetSourceVertex(),
+                                                _sourceHypo->GetSourceEdge() )));
       }
       // PAL16202
-      else 
+      else
       {
-        bool isSub = TAssocTool::IsSubShape( _sourceHypo->GetTargetVertex(), aShape );
+        bool isSub = SMESH_MesherHelper::IsSubShape( _sourceHypo->GetTargetVertex(), aShape );
         if ( !_sourceHypo->IsCompoundSource() ) {
           if ( !isSub ) {
             aStatus = HYP_BAD_PARAMETER;
-            SCRUTE((TAssocTool::IsSubShape( _sourceHypo->GetTargetVertex(), aShape)));
+            SCRUTE((SMESH_MesherHelper::IsSubShape( _sourceHypo->GetTargetVertex(), aShape)));
           }
         }
         else if ( isSub ) {
@@ -159,7 +160,7 @@ bool StdMeshers_Projection_1D::CheckHypothesis(SMESH_Mesh&
           {
             const TopoDS_Shape& ancestor = ancestIt.Value();
             if ( ancestor.ShapeType() == TopAbs_EDGE &&
-                 TAssocTool::IsSubShape( ancestor, _sourceHypo->GetSourceEdge() ))
+                 SMESH_MesherHelper::IsSubShape( ancestor, _sourceHypo->GetSourceEdge() ))
             {
               if ( sharingEdge.IsNull() || ancestor.IsSame( sharingEdge ))
                 sharingEdge = ancestor;
@@ -175,11 +176,11 @@ bool StdMeshers_Projection_1D::CheckHypothesis(SMESH_Mesh&
       }
     }
     // check source edge
-    if ( !TAssocTool::IsSubShape( _sourceHypo->GetSourceEdge(), srcMesh ) ||
+    if ( !SMESH_MesherHelper::IsSubShape( _sourceHypo->GetSourceEdge(), srcMesh ) ||
          ( srcMesh == tgtMesh && aShape == _sourceHypo->GetSourceEdge() ))
     {
       aStatus = HYP_BAD_PARAMETER;
-      SCRUTE((TAssocTool::IsSubShape( _sourceHypo->GetSourceEdge(), srcMesh )));
+      SCRUTE((SMESH_MesherHelper::IsSubShape( _sourceHypo->GetSourceEdge(), srcMesh )));
       SCRUTE((srcMesh == tgtMesh));
       SCRUTE(( aShape == _sourceHypo->GetSourceEdge() ));
     }
@@ -209,14 +210,14 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   SMESHDS_Mesh * meshDS = theMesh.GetMeshDS();
 
   // ---------------------------
-  // Make subshapes association
+  // Make sub-shapes association
   // ---------------------------
 
   TopoDS_Edge srcEdge, tgtEdge = TopoDS::Edge( theShape.Oriented(TopAbs_FORWARD));
   TopoDS_Shape srcShape = _sourceHypo->GetSourceEdge().Oriented(TopAbs_FORWARD);
 
   TAssocTool::TShapeShapeMap shape2ShapeMap;
-  TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap, tgtEdge );
+  TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap );
   if ( !TAssocTool::FindSubShapeAssociation( tgtEdge, tgtMesh, srcShape, srcMesh,
                                              shape2ShapeMap) ||
        !shape2ShapeMap.IsBound( tgtEdge ))
@@ -372,6 +373,97 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   return true;
 }
 
+
+//=======================================================================
+//function : Evaluate
+//purpose  : 
+//=======================================================================
+
+bool StdMeshers_Projection_1D::Evaluate(SMESH_Mesh& theMesh,
+                                        const TopoDS_Shape& theShape,
+                                        MapShapeNbElems& aResMap)
+{
+  if ( !_sourceHypo )
+    return false;
+
+  SMESH_Mesh * srcMesh = _sourceHypo->GetSourceMesh(); 
+  SMESH_Mesh * tgtMesh = & theMesh;
+  if ( !srcMesh )
+    srcMesh = tgtMesh;
+
+  //SMESHDS_Mesh * meshDS = theMesh.GetMeshDS();
+
+  // ---------------------------
+  // Make sub-shapes association
+  // ---------------------------
+
+  TopoDS_Edge srcEdge, tgtEdge = TopoDS::Edge( theShape.Oriented(TopAbs_FORWARD));
+  TopoDS_Shape srcShape = _sourceHypo->GetSourceEdge().Oriented(TopAbs_FORWARD);
+
+  TAssocTool::TShapeShapeMap shape2ShapeMap;
+  TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap );
+  if ( !TAssocTool::FindSubShapeAssociation( tgtEdge, tgtMesh, srcShape, srcMesh,
+                                             shape2ShapeMap) ||
+       !shape2ShapeMap.IsBound( tgtEdge ))
+    return error("Vertices association failed" );
+
+  srcEdge = TopoDS::Edge( shape2ShapeMap( tgtEdge ).Oriented(TopAbs_FORWARD));
+//   cout << " srcEdge #" << srcMesh->GetMeshDS()->ShapeToIndex( srcEdge )
+//        << " tgtEdge #" << tgtMesh->GetMeshDS()->ShapeToIndex( tgtEdge ) << endl;
+
+  TopoDS_Vertex tgtV[2], srcV[2];
+  TopExp::Vertices( tgtEdge, tgtV[0], tgtV[1] );
+  TopExp::Vertices( srcEdge, srcV[0], srcV[1] );
+
+  // ----------------------------------------------
+  // Assure that mesh on a source edge is computed
+  // ----------------------------------------------
+
+  SMESH_subMesh* srcSubMesh = srcMesh->GetSubMesh( srcEdge );
+  //SMESH_subMesh* tgtSubMesh = tgtMesh->GetSubMesh( tgtEdge );
+
+  if ( tgtMesh == srcMesh ) {
+    if ( !TAssocTool::MakeComputed( srcSubMesh ))
+      return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
+  }
+  else {
+    if ( !srcSubMesh->IsMeshComputed() )
+      return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
+  }
+  // -----------------------------------------------
+  // Find out nodes distribution on the source edge
+  // -----------------------------------------------
+
+  //double srcLength = EdgeLength( srcEdge );
+  //double tgtLength = EdgeLength( tgtEdge );
+  
+  vector< double > params; // sorted parameters of nodes on the source edge
+  if ( !SMESH_Algo::GetNodeParamOnEdge( srcMesh->GetMeshDS(), srcEdge, params ))
+    return error(COMPERR_BAD_INPUT_MESH,"Bad node parameters on the source edge");
+
+  int nbNodes = params.size();
+
+  std::vector<int> aVec(SMDSEntity_Last);
+  for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aVec[i] = 0;
+
+  aVec[SMDSEntity_Node] = nbNodes;
+
+  bool quadratic = false;
+  SMDS_ElemIteratorPtr elemIt = srcSubMesh->GetSubMeshDS()->GetElements();
+  if ( elemIt->more() )
+    quadratic = elemIt->next()->IsQuadratic();
+  if(quadratic)
+    aVec[SMDSEntity_Quad_Edge] = (nbNodes-1)/2;
+  else
+    aVec[SMDSEntity_Edge] = nbNodes - 1;
+
+  SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
+  aResMap.insert(std::make_pair(sm,aVec));
+
+  return true;
+}
+
+
 //=============================================================================
 /*!
  * \brief Sets a default event listener to submesh of the source edge
index 52f76e17043fda139be494ea44746949207a28ef..5ef640170fdda85077800be5b474ed9c3641bb56 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_Projection_1D.hxx
 //  Module : SMESH
@@ -46,6 +47,9 @@ public:
 
   virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
 
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
+
   /*!
    * \brief Sets a default event listener to submesh of the source edge
    *  \param whenSetToSubMesh - submesh where algo is set
diff --git a/src/StdMeshers/StdMeshers_Projection_1D2D.cxx b/src/StdMeshers/StdMeshers_Projection_1D2D.cxx
new file mode 100644 (file)
index 0000000..efe6bf0
--- /dev/null
@@ -0,0 +1,264 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+// File      : StdMeshers_Projection_1D2D.cxx
+// Module    : SMESH
+// Author    : Edward AGAPOV (eap)
+//
+#include "StdMeshers_Projection_1D2D.hxx"
+
+#include "SMESH_Gen.hxx"
+#include "SMESH_MesherHelper.hxx"
+#include "SMESH_subMeshEventListener.hxx"
+#include "StdMeshers_FaceSide.hxx"
+#include "StdMeshers_ProjectionSource2D.hxx"
+#include "StdMeshers_ProjectionUtils.hxx"
+
+#include <TopoDS.hxx>
+#include <TopExp_Explorer.hxx>
+
+using namespace std;
+
+namespace
+{
+  // --------------------------------------------------------------------------------
+  /*!
+   * \brief an event listener updating submehses of EDGEs according to
+   *        events on the target FACE submesh
+   */
+  struct EventProparatorToEdges : public SMESH_subMeshEventListener
+  {
+    EventProparatorToEdges(): SMESH_subMeshEventListener(/*isDeletable=*/false,
+                                                         "Projection_1D2D::EventProparatorToEdges")
+    {}
+    static EventProparatorToEdges* Instance() { static EventProparatorToEdges E; return &E; }
+
+    static void Set(SMESH_subMesh* faceSubMesh)
+    {
+      SMESH_subMeshEventListenerData* edgeSubMeshes =
+        new SMESH_subMeshEventListenerData(/*isDeletable=*/true);
+      SMESH_Mesh* mesh = faceSubMesh->GetFather();
+      TopExp_Explorer eExp( faceSubMesh->GetSubShape(), TopAbs_EDGE );
+      for ( ; eExp.More(); eExp.Next() )
+        edgeSubMeshes->mySubMeshes.push_back( mesh->GetSubMesh( eExp.Current() ));
+
+      // set a listener
+      faceSubMesh->SetEventListener( Instance(), edgeSubMeshes, faceSubMesh );
+    }
+  };
+  // --------------------------------------------------------------------------------
+  /*!
+   * \brief Structure used to temporary remove EventProparatorToEdges from faceSubMesh
+   *  in order to prevent propagation of CLEAN event from FACE to EDGEs during 
+   *  StdMeshers_Projection_1D2D::Compute(). The CLEAN event is emmited by Pattern mapper
+   * and causes removal of faces generated on adjacent FACEs.
+   */
+  struct UnsetterOfEventProparatorToEdges
+  {
+    SMESH_subMesh* _faceSubMesh;
+    UnsetterOfEventProparatorToEdges( SMESH_subMesh* faceSubMesh ):_faceSubMesh(faceSubMesh)
+    {
+      faceSubMesh->DeleteEventListener( EventProparatorToEdges::Instance() );
+    }
+    ~UnsetterOfEventProparatorToEdges()
+    {
+      EventProparatorToEdges::Set(_faceSubMesh);
+    }
+  };
+}
+
+//=======================================================================
+//function : StdMeshers_Projection_1D2D
+//purpose  : 
+//=======================================================================
+
+StdMeshers_Projection_1D2D::StdMeshers_Projection_1D2D(int hypId, int studyId, SMESH_Gen* gen)
+  :StdMeshers_Projection_2D(hypId, studyId, gen)
+{
+  _name = "Projection_1D2D";
+  _requireDiscreteBoundary = false;
+  _supportSubmeshes = true;
+}
+
+//=======================================================================
+//function : Compute
+//purpose  : 
+//=======================================================================
+
+bool StdMeshers_Projection_1D2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theShape)
+{
+  UnsetterOfEventProparatorToEdges eventBarrier( theMesh.GetSubMesh( theShape ));
+
+  if ( !StdMeshers_Projection_2D::Compute(theMesh, theShape))
+    return false;
+
+  SMESHDS_Mesh * meshDS = theMesh.GetMeshDS();
+
+  SMESHDS_SubMesh * faceSubMesh = meshDS->MeshElements( theShape );
+  if ( !faceSubMesh || faceSubMesh->NbElements() == 0 ) return false;
+  _quadraticMesh = faceSubMesh->GetElements()->next()->IsQuadratic();
+
+  SMESH_MesherHelper helper( theMesh );
+  helper.SetSubShape( theShape );
+
+  TopoDS_Face F = TopoDS::Face( theShape );
+  TError err;
+  TSideVector wires = StdMeshers_FaceSide::GetFaceWires( F, theMesh,
+                                                         /*ignoreMediumNodes=*/false, err);
+  if ( err && !err->IsOK() )
+    return error( err );
+
+  for ( size_t iWire = 0; iWire < wires.size(); ++iWire )
+  {
+    vector<const SMDS_MeshNode*> nodes = wires[ iWire ]->GetOrderedNodes();
+    if ( nodes.empty() )
+      return error("Wrong nodes on a wire");
+
+    // check that all nodes are shared by faces generated on F
+    for ( size_t i = 0; i < nodes.size(); ++i )
+    {
+      SMDS_ElemIteratorPtr fIt = nodes[i]->GetInverseElementIterator(SMDSAbs_Face);
+      bool faceFound = false;
+      while ( !faceFound && fIt->more() )
+        faceFound = ( helper.GetSubShapeID() == fIt->next()->getshapeId() );
+      if ( !faceFound )
+        return error("The existing 1D mesh mismatches the generated 2D mesh");
+    }
+
+    const bool checkExisting = ( wires[ iWire ]->NbSegments() || helper.HasSeam() );
+
+    if ( _quadraticMesh )
+    {
+      for ( size_t i = 2; i < nodes.size(); i += 2 )
+      {
+        if ( checkExisting && meshDS->FindEdge( nodes[i-2], nodes[i], nodes[i-1]))
+          continue;
+        SMDS_MeshElement* e = meshDS->AddEdge( nodes[i-2], nodes[i], nodes[i-1] );
+        meshDS->SetMeshElementOnShape( e, nodes[i-1]->getshapeId() );
+      }
+    }
+    else
+    {
+      int edgeID = meshDS->ShapeToIndex( wires[ iWire ]->Edge(0) );
+      for ( size_t i = 1; i < nodes.size(); ++i )
+      {
+        if ( checkExisting && meshDS->FindEdge( nodes[i-1], nodes[i]))
+          continue;
+        SMDS_MeshElement* e = meshDS->AddEdge( nodes[i-1], nodes[i] );
+        if ( nodes[i-1]->getshapeId() != edgeID &&
+             nodes[i  ]->getshapeId() != edgeID )
+        {
+          edgeID = helper.GetMediumPos( nodes[i-1], nodes[i] ).first;
+          if ( edgeID < 1 ) edgeID = helper.GetSubShapeID();
+        }
+        meshDS->SetMeshElementOnShape( e, edgeID );
+      }
+    }
+  }   
+
+  return true;
+}
+
+//=======================================================================
+//function : Evaluate
+//purpose  : 
+//=======================================================================
+
+bool StdMeshers_Projection_1D2D::Evaluate(SMESH_Mesh&         theMesh,
+                                          const TopoDS_Shape& theShape,
+                                          MapShapeNbElems&    aResMap)
+{
+  if ( !StdMeshers_Projection_2D::Evaluate(theMesh,theShape,aResMap))
+    return false;
+
+  TopoDS_Shape srcFace = _sourceHypo->GetSourceFace();
+  SMESH_Mesh * srcMesh = _sourceHypo->GetSourceMesh();
+  if ( !srcMesh ) srcMesh = & theMesh;
+  SMESH_subMesh* srcFaceSM = srcMesh->GetSubMesh( srcFace );
+
+  typedef StdMeshers_ProjectionUtils SPU;
+  SPU::TShapeShapeMap shape2ShapeMap;
+  SPU::InitVertexAssociation( _sourceHypo, shape2ShapeMap );
+  if ( !SPU::FindSubShapeAssociation( theShape, &theMesh, srcFace, srcMesh, shape2ShapeMap))
+    return error(COMPERR_BAD_SHAPE,"Topology of source and target faces seems different" );
+
+  MapShapeNbElems srcResMap;
+  if ( !srcFaceSM->IsMeshComputed() )
+    _gen->Evaluate( *srcMesh, srcFace, srcResMap);
+
+  SMESH_subMeshIteratorPtr smIt = srcFaceSM->getDependsOnIterator(/*includeSelf=*/false,
+                                                                  /*complexShapeFirst=*/true);
+  while ( smIt->more() )
+  {
+    SMESH_subMesh* srcSM = smIt->next();
+    TopAbs_ShapeEnum shapeType = srcSM->GetSubShape().ShapeType();
+    if ( shapeType == TopAbs_EDGE )
+    {
+      std::vector<int> aVec;
+      SMESHDS_SubMesh* srcSubMeshDS = srcSM->GetSubMeshDS();
+      if ( srcSubMeshDS && srcSubMeshDS->NbElements() )
+      {
+        aVec.resize(SMDSEntity_Last, 0);
+        SMDS_ElemIteratorPtr eIt = srcSubMeshDS->GetElements();
+        _quadraticMesh = ( eIt->more() && eIt->next()->IsQuadratic() );
+
+        aVec[SMDSEntity_Node] = srcSubMeshDS->NbNodes();
+        aVec[_quadraticMesh ? SMDSEntity_Quad_Edge : SMDSEntity_Edge] = srcSubMeshDS->NbElements();
+      }
+      else
+      {
+        if ( srcResMap.empty() )
+          if ( !_gen->Evaluate( *srcMesh, srcSM->GetSubShape(), srcResMap ))
+            return error(COMPERR_BAD_INPUT_MESH,"Source mesh not evaluatable");
+        aVec = srcResMap[ srcSM ];
+        if ( aVec.empty() )
+          return error(COMPERR_BAD_INPUT_MESH,"Source mesh is wrongly evaluated");
+      }
+      TopoDS_Shape tgtEdge = shape2ShapeMap( srcSM->GetSubShape(), /*isSrc=*/true  );
+      SMESH_subMesh* tgtSM = theMesh.GetSubMesh( tgtEdge );
+      aResMap.insert(std::make_pair(tgtSM,aVec));
+    }
+    if ( shapeType == TopAbs_VERTEX ) break;
+  }
+
+  return true;
+}
+
+//=======================================================================
+//function : SetEventListener
+//purpose  : Sets a default event listener to submesh of the source face.
+//           faceSubMesh - submesh where algo is set
+// After being set, event listener is notified on each event of a submesh.
+// This method is called when a submesh gets HYP_OK algo_state.
+// Arranges that CLEAN event is translated from source submesh to
+// the faceSubMesh submesh.
+//=======================================================================
+
+void StdMeshers_Projection_1D2D::SetEventListener(SMESH_subMesh* faceSubMesh)
+{
+  // set a listener of events on a source submesh
+  StdMeshers_Projection_2D::SetEventListener(faceSubMesh);
+
+  // set a listener to the target FACE submesh in order to update submehses
+  // of EDGEs according to events on the target FACE submesh
+  EventProparatorToEdges::Set( faceSubMesh );
+}
+
diff --git a/src/StdMeshers/StdMeshers_Projection_1D2D.hxx b/src/StdMeshers/StdMeshers_Projection_1D2D.hxx
new file mode 100644 (file)
index 0000000..9e7715c
--- /dev/null
@@ -0,0 +1,52 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+//  File   : StdMeshers_Projection_1D2D.hxx
+//  Module : SMESH
+//
+#ifndef _SMESH_Projection_1D2D_HXX_
+#define _SMESH_Projection_1D2D_HXX_
+
+#include "StdMeshers_Projection_2D.hxx"
+
+class STDMESHERS_EXPORT StdMeshers_Projection_1D2D: public StdMeshers_Projection_2D
+{
+public:
+  StdMeshers_Projection_1D2D(int hypId, int studyId, SMESH_Gen* gen);
+
+  virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
+
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
+  /*!
+   * \brief Sets a default event listener to submesh of the source face
+   *  \param whenSetToSubMesh - submesh where algo is set
+   *
+   * After being set, event listener is notified on each event of a submesh.
+   * This method is called when a submesh gets HYP_OK algo_state.
+   * Arranges that CLEAN event is translated from source submesh to
+   * the whenSetToSubMesh submesh.
+   */
+  virtual void SetEventListener(SMESH_subMesh* whenSetToSubMesh);
+};
+
+#endif
index ed6027268ec1ecb5cd87f85e5e3301b788ef7eb0..b4734fa0c6c531b40b0c82d3f3a94c75c1338cfd 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 // File      : StdMeshers_Projection_2D.cxx
 // Module    : SMESH
 
 #include "StdMeshers_ProjectionSource2D.hxx"
 #include "StdMeshers_ProjectionUtils.hxx"
+#include "StdMeshers_FaceSide.hxx"
 
+#include "SMDS_EdgePosition.hxx"
+#include "SMDS_FacePosition.hxx"
 #include "SMESHDS_Hypothesis.hxx"
 #include "SMESHDS_SubMesh.hxx"
 #include "SMESH_Block.hxx"
+#include "SMESH_Comment.hxx"
 #include "SMESH_Gen.hxx"
 #include "SMESH_Mesh.hxx"
-#include "SMESH_MeshEditor.hxx"
+#include "SMESH_MesherHelper.hxx"
 #include "SMESH_Pattern.hxx"
 #include "SMESH_subMesh.hxx"
 #include "SMESH_subMeshEventListener.hxx"
-#include "SMESH_Comment.hxx"
-#include "SMDS_EdgePosition.hxx"
 
 #include "utilities.h"
 
@@ -50,6 +53,8 @@
 #include <TopExp_Explorer.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopoDS.hxx>
+#include <gp_Ax2.hxx>
+#include <gp_Ax3.hxx>
 
 
 using namespace std;
@@ -67,7 +72,7 @@ StdMeshers_Projection_2D::StdMeshers_Projection_2D(int hypId, int studyId, SMESH
   :SMESH_2D_Algo(hypId, studyId, gen)
 {
   _name = "Projection_2D";
-  _shapeType = (1 << TopAbs_FACE);     // 1 bit per shape type
+  _shapeType = (1 << TopAbs_FACE);      // 1 bit per shape type
 
   _compatibleHypothesis.push_back("ProjectionSource2D");
   _sourceHypo = 0;
@@ -130,40 +135,40 @@ bool StdMeshers_Projection_2D::CheckHypothesis(SMESH_Mesh&
       TopoDS_Shape edge = TAssocTool::GetEdgeByVertices
         ( srcMesh, _sourceHypo->GetSourceVertex(1), _sourceHypo->GetSourceVertex(2) );
       if ( edge.IsNull() ||
-           !TAssocTool::IsSubShape( edge, srcMesh ) ||
-           !TAssocTool::IsSubShape( edge, _sourceHypo->GetSourceFace() ))
+           !SMESH_MesherHelper::IsSubShape( edge, srcMesh ) ||
+           !SMESH_MesherHelper::IsSubShape( edge, _sourceHypo->GetSourceFace() ))
       {
         theStatus = HYP_BAD_PARAMETER;
         SCRUTE((edge.IsNull()));
-        SCRUTE((TAssocTool::IsSubShape( edge, srcMesh )));
-        SCRUTE((TAssocTool::IsSubShape( edge, _sourceHypo->GetSourceFace() )));
+        SCRUTE((SMESH_MesherHelper::IsSubShape( edge, srcMesh )));
+        SCRUTE((SMESH_MesherHelper::IsSubShape( edge, _sourceHypo->GetSourceFace() )));
       }
       else
       {
         // target vertices
         edge = TAssocTool::GetEdgeByVertices
           ( tgtMesh, _sourceHypo->GetTargetVertex(1), _sourceHypo->GetTargetVertex(2) );
-        if ( edge.IsNull() || !TAssocTool::IsSubShape( edge, tgtMesh ))
+        if ( edge.IsNull() || !SMESH_MesherHelper::IsSubShape( edge, tgtMesh ))
         {
           theStatus = HYP_BAD_PARAMETER;
           SCRUTE((edge.IsNull()));
-          SCRUTE((TAssocTool::IsSubShape( edge, tgtMesh )));
+          SCRUTE((SMESH_MesherHelper::IsSubShape( edge, tgtMesh )));
         }
         // PAL16203
         else if ( !_sourceHypo->IsCompoundSource() &&
-                  !TAssocTool::IsSubShape( edge, theShape ))
+                  !SMESH_MesherHelper::IsSubShape( edge, theShape ))
         {
           theStatus = HYP_BAD_PARAMETER;
-          SCRUTE((TAssocTool::IsSubShape( edge, theShape )));
+          SCRUTE((SMESH_MesherHelper::IsSubShape( edge, theShape )));
         }
       }
     }
     // check a source face
-    if ( !TAssocTool::IsSubShape( _sourceHypo->GetSourceFace(), srcMesh ) ||
+    if ( !SMESH_MesherHelper::IsSubShape( _sourceHypo->GetSourceFace(), srcMesh ) ||
          ( srcMesh == tgtMesh && theShape == _sourceHypo->GetSourceFace() ))
     {
       theStatus = HYP_BAD_PARAMETER;
-      SCRUTE((TAssocTool::IsSubShape( _sourceHypo->GetSourceFace(), srcMesh )));
+      SCRUTE((SMESH_MesherHelper::IsSubShape( _sourceHypo->GetSourceFace(), srcMesh )));
       SCRUTE((srcMesh == tgtMesh));
       SCRUTE(( theShape == _sourceHypo->GetSourceFace() ));
     }
@@ -177,22 +182,29 @@ bool StdMeshers_Projection_2D::CheckHypothesis(SMESH_Mesh&
 
 namespace {
 
-
   //================================================================================
   /*!
    * \brief define if a node is new or old
-    * \param node - node to check
-    * \retval bool - true if the node existed before Compute() is called
+   * \param node - node to check
+   * \retval bool - true if the node existed before Compute() is called
    */
   //================================================================================
 
-  bool isOldNode( const SMDS_MeshNode* node )
+  bool isOldNode( const SMDS_MeshNode* node/*, const bool is1DComputed*/ )
   {
     // old nodes are shared by edges and new ones are shared
     // only by faces created by mapper
-    SMDS_ElemIteratorPtr invEdge = node->GetInverseElementIterator(SMDSAbs_Edge);
-    bool isOld = invEdge->more();
-    return isOld;
+    //if ( is1DComputed )
+    {
+      bool isOld = node->NbInverseElements(SMDSAbs_Edge) > 0;
+      return isOld;
+    }
+    // else
+    // {
+    //   SMDS_ElemIteratorPtr invFace = node->GetInverseElementIterator(SMDSAbs_Face);
+    //   bool isNew = invFace->more();
+    //   return !isNew;
+    // }
   }
 
   //================================================================================
@@ -211,7 +223,7 @@ namespace {
     void Release() { sm = 0; } // mesh will not be removed
     static void Clean( SMESH_subMesh* sm, bool withSub=true )
     {
-      if ( !sm ) return;
+      if ( !sm || !sm->GetSubMeshDS() ) return;
       // PAL16567, 18920. Remove face nodes as well
 //       switch ( sm->GetSubShape().ShapeType() ) {
 //       case TopAbs_VERTEX:
@@ -339,7 +351,7 @@ namespace {
           RETURN_BAD_RESULT("Bad node position type: node " << node->GetID() <<
                             " pos type " << node->GetPosition()->GetTypeOfPosition());
         const SMDS_EdgePosition* pos =
-          static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+          static_cast<const SMDS_EdgePosition*>(node->GetPosition());
         u2nodes.insert( make_pair( pos->GetUParameter(), node ));
         seamNodes.insert( node );
       }
@@ -354,8 +366,406 @@ namespace {
 
   } // bool getBoundaryNodes()
 
+  //================================================================================
+  /*!
+   * \brief Preform projection in case if tgtFace.IsPartner( srcFace ) and in case
+   * if projection by transformation is possible
+   */
+  //================================================================================
+
+  bool projectPartner(const TopoDS_Face&                tgtFace,
+                      const TopoDS_Face&                srcFace,
+                      SMESH_Mesh *                      tgtMesh,
+                      SMESH_Mesh *                      srcMesh,
+                      const TAssocTool::TShapeShapeMap& shape2ShapeMap)
+  {
+    MESSAGE("projectPartner");
+    const double tol = 1.e-7*srcMesh->GetMeshDS()->getMaxDim();
+
+    gp_Trsf trsf; // transformation to get location of target nodes from source ones
+    if ( tgtFace.IsPartner( srcFace ))
+    {
+      gp_Trsf srcTrsf = srcFace.Location();
+      gp_Trsf tgtTrsf = tgtFace.Location();
+      trsf = srcTrsf.Inverted() * tgtTrsf;
+    }
+    else
+    {
+      // Try to find the transformation
+
+      // make any local coord systems of src and tgt faces
+      vector<gp_Pnt> srcPP, tgtPP; // 3 points on face boundaries to make axes of CS
+      SMESH_subMesh * srcSM = srcMesh->GetSubMesh( srcFace );
+      SMESH_subMeshIteratorPtr smIt = srcSM->getDependsOnIterator(/*includeSelf=*/false,false);
+      srcSM = smIt->next(); // sm of a vertex
+      while ( smIt->more() && srcPP.size() < 3 )
+      {
+        srcSM = smIt->next();
+        SMESHDS_SubMesh* srcSmds = srcSM->GetSubMeshDS();
+        if ( !srcSmds ) continue;
+        SMDS_NodeIteratorPtr nIt = srcSmds->GetNodes();
+        while ( nIt->more() )
+        {
+          SMESH_TNodeXYZ p ( nIt->next());
+          bool pOK = false;
+          switch ( srcPP.size() )
+          {
+          case 0: pOK = true; break;
+
+          case 1: pOK = ( srcPP[0].SquareDistance( p ) > 10*tol ); break;
+            
+          case 2:
+            {
+              gp_Vec p0p1( srcPP[0], srcPP[1] ), p0p( srcPP[0], p );
+              // pOK = !p0p1.IsParallel( p0p, tol );
+              pOK = !p0p1.IsParallel( p0p, 3.14/20 ); // angle min 18 degrees
+              break;
+            }
+          }
+          if ( !pOK )
+            continue;
+
+          // find corresponding point on target shape
+          pOK = false;
+          gp_Pnt tgtP;
+          const TopoDS_Shape& tgtShape = shape2ShapeMap( srcSM->GetSubShape(), /*isSrc=*/true );
+          if ( tgtShape.ShapeType() == TopAbs_VERTEX )
+          {
+            tgtP = BRep_Tool::Pnt( TopoDS::Vertex( tgtShape ));
+            pOK = true;
+            //cout << "V - nS " << p._node->GetID() << " - nT " << SMESH_Algo::VertexNode(TopoDS::Vertex( tgtShape),tgtMesh->GetMeshDS())->GetID() << endl;
+          }
+          else if ( tgtPP.size() > 0 )
+          {
+            if ( SMESHDS_SubMesh* tgtSmds = tgtMesh->GetMeshDS()->MeshElements( tgtShape ))
+            {
+              double srcDist = srcPP[0].Distance( p );
+              double eTol = BRep_Tool::Tolerance( TopoDS::Edge( tgtShape ));
+              if (eTol < tol) eTol = tol;
+              SMDS_NodeIteratorPtr nItT = tgtSmds->GetNodes();
+              while ( nItT->more() && !pOK )
+              {
+                const SMDS_MeshNode* n = nItT->next();
+                tgtP = SMESH_TNodeXYZ( n );
+                pOK = ( fabs( srcDist - tgtPP[0].Distance( tgtP )) < 2*eTol );
+                //cout << "E - nS " << p._node->GetID() << " - nT " << n->GetID()<< " OK - " << pOK<< " " << fabs( srcDist - tgtPP[0].Distance( tgtP ))<< " tol " << eTol<< endl;
+              }
+            }
+          }
+          if ( !pOK )
+            continue;
+
+          srcPP.push_back( p );
+          tgtPP.push_back( tgtP );
+        }
+      }
+      if ( srcPP.size() != 3 )
+        return false;
+
+      // make transformation
+      gp_Trsf fromTgtCS, toSrcCS; // from/to global CS
+      gp_Ax2 srcCS( srcPP[0], gp_Vec( srcPP[0], srcPP[1] ), gp_Vec( srcPP[0], srcPP[2]));
+      gp_Ax2 tgtCS( tgtPP[0], gp_Vec( tgtPP[0], tgtPP[1] ), gp_Vec( tgtPP[0], tgtPP[2]));
+      toSrcCS  .SetTransformation( gp_Ax3( srcCS ));
+      fromTgtCS.SetTransformation( gp_Ax3( tgtCS ));
+      fromTgtCS.Invert();
+
+      trsf = fromTgtCS * toSrcCS;
+    }
+
+    // Fill map of src to tgt nodes with nodes on edges
+
+    map<const SMDS_MeshNode* , const SMDS_MeshNode*> src2tgtNodes;
+    map<const SMDS_MeshNode* , const SMDS_MeshNode*>::iterator srcN_tgtN;
+
+    for ( TopExp_Explorer srcEdge( srcFace, TopAbs_EDGE); srcEdge.More(); srcEdge.Next() )
+    {
+      const TopoDS_Shape& tgtEdge = shape2ShapeMap( srcEdge.Current(), /*isSrc=*/true );
+
+      map< double, const SMDS_MeshNode* > srcNodes, tgtNodes;
+      if ( !SMESH_Algo::GetSortedNodesOnEdge( srcMesh->GetMeshDS(),
+                                              TopoDS::Edge( srcEdge.Current() ),
+                                              /*ignoreMediumNodes = */true,
+                                              srcNodes )
+           ||
+           !SMESH_Algo::GetSortedNodesOnEdge( tgtMesh->GetMeshDS(),
+                                              TopoDS::Edge( tgtEdge ),
+                                              /*ignoreMediumNodes = */true,
+                                              tgtNodes )
+           ||
+           srcNodes.size() != tgtNodes.size())
+        return false;
+
+      if ( !tgtEdge.IsPartner( srcEdge.Current() ))
+      {
+        // check that transformation is OK by three nodes
+        gp_Pnt p0S = SMESH_TNodeXYZ( (srcNodes.begin())  ->second);
+        gp_Pnt p1S = SMESH_TNodeXYZ( (srcNodes.rbegin()) ->second);
+        gp_Pnt p2S = SMESH_TNodeXYZ( (++srcNodes.begin())->second);
+
+        gp_Pnt p0T = SMESH_TNodeXYZ( (tgtNodes.begin())  ->second);
+        gp_Pnt p1T = SMESH_TNodeXYZ( (tgtNodes.rbegin()) ->second);
+        gp_Pnt p2T = SMESH_TNodeXYZ( (++tgtNodes.begin())->second);
+
+        // transform source points, they must coincide with target ones
+        if ( p0T.SquareDistance( p0S.Transformed( trsf )) > tol ||
+             p1T.SquareDistance( p1S.Transformed( trsf )) > tol ||
+             p2T.SquareDistance( p2S.Transformed( trsf )) > tol )
+        {
+          //cout << "KO trsf, 3 dist: "
+          //<< p0T.SquareDistance( p0S.Transformed( trsf ))<< ", "
+          //<< p1T.SquareDistance( p1S.Transformed( trsf ))<< ", "
+          //<< p2T.SquareDistance( p2S.Transformed( trsf ))<< ", "<<endl;
+          return false;
+        }
+      }
+
+      map< double, const SMDS_MeshNode* >::iterator u_tn = tgtNodes.begin();
+      map< double, const SMDS_MeshNode* >::iterator u_sn = srcNodes.begin();
+      for ( ; u_tn != tgtNodes.end(); ++u_tn, ++u_sn)
+        src2tgtNodes.insert( make_pair( u_sn->second, u_tn->second ));
+    }
+
+    // Make new faces
+
+    // prepare the helper to adding quadratic elements if necessary
+    SMESH_MesherHelper helper( *tgtMesh );
+    helper.SetSubShape( tgtFace );
+    helper.IsQuadraticSubMesh( tgtFace );
+    helper.SetElementsOnShape( true );
+
+    SMESH_MesherHelper srcHelper( *srcMesh );
+    srcHelper.SetSubShape( srcFace );
+
+    const SMDS_MeshNode* nullNode = 0;
+
+    // indices of nodes to create properly oriented faces
+    int tri1 = 1, tri2 = 2, quad1 = 1, quad3 = 3;
+    if ( trsf.Form() != gp_Identity )
+      std::swap( tri1, tri2 ), std::swap( quad1, quad3 );
+
+    SMESHDS_SubMesh* srcSubDS = srcMesh->GetMeshDS()->MeshElements( srcFace );
+    SMDS_ElemIteratorPtr elemIt = srcSubDS->GetElements();
+    vector< const SMDS_MeshNode* > tgtNodes;
+    while ( elemIt->more() ) // loop on all mesh faces on srcFace
+    {
+      const SMDS_MeshElement* elem = elemIt->next();
+      const int nbN = elem->NbCornerNodes(); 
+      tgtNodes.resize( nbN );
+      for ( int i = 0; i < nbN; ++i ) // loop on nodes of the source element
+      {
+        const SMDS_MeshNode* srcNode = elem->GetNode(i);
+        srcN_tgtN = src2tgtNodes.insert( make_pair( srcNode, nullNode )).first;
+        if ( srcN_tgtN->second == nullNode )
+        {
+          // create a new node
+          gp_Pnt tgtP = gp_Pnt(srcNode->X(),srcNode->Y(),srcNode->Z()).Transformed( trsf );
+          SMDS_MeshNode* n = helper.AddNode( tgtP.X(), tgtP.Y(), tgtP.Z() );
+          srcN_tgtN->second = n;
+
+          gp_Pnt2d srcUV = srcHelper.GetNodeUV( srcFace, srcNode,
+                                                elem->GetNode( helper.WrapIndex(i+1,nbN)));
+          n->SetPosition( new SMDS_FacePosition( srcUV.X(), srcUV.Y() ));
+        }
+        tgtNodes[i] = srcN_tgtN->second;
+      }
+      // create a new face
+      switch ( nbN )
+      {
+      case 3: helper.AddFace(tgtNodes[0], tgtNodes[tri1], tgtNodes[tri2]); break;
+      case 4: helper.AddFace(tgtNodes[0], tgtNodes[quad1], tgtNodes[2], tgtNodes[quad3]); break;
+      }
+    }
+    return true;
+
+  } //   bool projectPartner()
+
+  //================================================================================
+  /*!
+   * \brief Preform projection in case if the faces are similar in 2D space
+   */
+  //================================================================================
+
+  bool projectBy2DSimilarity(const TopoDS_Face&                tgtFace,
+                             const TopoDS_Face&                srcFace,
+                             SMESH_Mesh *                      tgtMesh,
+                             SMESH_Mesh *                      srcMesh,
+                             const TAssocTool::TShapeShapeMap& shape2ShapeMap,
+                             const bool                        is1DComputed)
+  {
+    // 1) Preparation
+
+    // get ordered src EDGEs
+    TError err;
+    TSideVector srcWires =
+      StdMeshers_FaceSide::GetFaceWires( srcFace, *srcMesh,/*ignoreMediumNodes = */false, err);
+    if ( err && !err->IsOK() )
+      return false;
+
+    // make corresponding sequence of tgt EDGEs
+    TSideVector tgtWires( srcWires.size() );
+    for ( unsigned iW = 0; iW < srcWires.size(); ++iW )
+    {
+      list< TopoDS_Edge > tgtEdges;
+      StdMeshers_FaceSidePtr srcWire = srcWires[iW];
+      TopTools_IndexedMapOfShape edgeMap; // to detect seam edges
+      for ( int iE = 0; iE < srcWire->NbEdges(); ++iE )
+      {
+        tgtEdges.push_back( TopoDS::Edge( shape2ShapeMap( srcWire->Edge( iE ), /*isSrc=*/true)));
+        // reverse a seam edge encountered for the second time
+        const int oldExtent = edgeMap.Extent();
+        edgeMap.Add( tgtEdges.back() );
+        if ( oldExtent == edgeMap.Extent() )
+          tgtEdges.back().Reverse();
+      }
+      tgtWires[ iW ].reset( new StdMeshers_FaceSide( tgtFace, tgtEdges, tgtMesh,
+                                                     /*theIsForward = */ true,
+                                                     /*theIgnoreMediumNodes = */false));
+      if ( is1DComputed &&
+           srcWires[iW]->GetUVPtStruct().size() !=
+           tgtWires[iW]->GetUVPtStruct().size())
+        return false;
+    }
+
+    // 2) Find transformation
+
+    gp_Trsf2d trsf;
+    {
+      // get 2 pairs of corresponding UVs
+      gp_Pnt2d srcP0 = srcWires[0]->Value2d(0.0);
+      gp_Pnt2d srcP1 = srcWires[0]->Value2d(0.333);
+      gp_Pnt2d tgtP0 = tgtWires[0]->Value2d(0.0);
+      gp_Pnt2d tgtP1 = tgtWires[0]->Value2d(0.333);
+
+      // make transformation
+      gp_Trsf2d fromTgtCS, toSrcCS; // from/to global CS
+      gp_Ax2d srcCS( srcP0, gp_Vec2d( srcP0, srcP1 ));
+      gp_Ax2d tgtCS( tgtP0, gp_Vec2d( tgtP0, tgtP1 ));
+      toSrcCS  .SetTransformation( srcCS );
+      fromTgtCS.SetTransformation( tgtCS );
+      fromTgtCS.Invert();
+
+      trsf = fromTgtCS * toSrcCS;
+
+      // check transformation
+      const double tol = 1e-5 * gp_Vec2d( srcP0, srcP1 ).Magnitude();
+      for ( double u = 0.12; u < 1.; u += 0.1 )
+      {
+        gp_Pnt2d srcUV = srcWires[0]->Value2d( u );
+        gp_Pnt2d tgtUV = tgtWires[0]->Value2d( u );
+        gp_Pnt2d tgtUV2 = srcUV.Transformed( trsf );
+        if ( tgtUV.Distance( tgtUV2 ) > tol )
+          return false;
+      }
+    }
+
+    // 3) Projection
+
+    typedef map<const SMDS_MeshNode* , const SMDS_MeshNode*, TIDCompare> TN2NMap;
+    TN2NMap src2tgtNodes;
+    TN2NMap::iterator srcN_tgtN;
+
+    // fill src2tgtNodes in with nodes on EDGEs
+    for ( unsigned iW = 0; iW < srcWires.size(); ++iW )
+      if ( is1DComputed )
+      {
+        const vector<UVPtStruct>& srcUVs = srcWires[iW]->GetUVPtStruct();
+        const vector<UVPtStruct>& tgtUVs = tgtWires[iW]->GetUVPtStruct();
+        for ( unsigned i = 0; i < srcUVs.size(); ++i )
+          src2tgtNodes.insert( make_pair( srcUVs[i].node, tgtUVs[i].node ));
+      }
+      else
+      {
+        for ( int iE = 0; iE < srcWires[iW]->NbEdges(); ++iE )
+        {
+          TopoDS_Vertex srcV = srcWires[iW]->FirstVertex(iE);
+          TopoDS_Vertex tgtV = tgtWires[iW]->FirstVertex(iE);
+          const SMDS_MeshNode* srcNode = SMESH_Algo::VertexNode( srcV, srcMesh->GetMeshDS() );
+          const SMDS_MeshNode* tgtNode = SMESH_Algo::VertexNode( tgtV, tgtMesh->GetMeshDS() );
+          if ( tgtNode && srcNode )
+            src2tgtNodes.insert( make_pair( srcNode, tgtNode ));
+        }
+      }
+
+    // make elements
+
+    SMESHDS_SubMesh* srcSubDS = srcMesh->GetMeshDS()->MeshElements( srcFace );
+
+    SMESH_MesherHelper helper( *tgtMesh );
+    helper.SetSubShape( tgtFace );
+    if ( is1DComputed )
+      helper.IsQuadraticSubMesh( tgtFace );
+    else
+      helper.SetIsQuadratic( srcSubDS->GetElements()->next()->IsQuadratic() );
+    helper.SetElementsOnShape( true );
+    Handle(Geom_Surface) tgtSurface = BRep_Tool::Surface( tgtFace );
+    SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS();
+
+    SMESH_MesherHelper srcHelper( *srcMesh );
+    srcHelper.SetSubShape( srcFace );
+
+    const SMDS_MeshNode* nullNode = 0;
+
+    SMDS_ElemIteratorPtr elemIt = srcSubDS->GetElements();
+    vector< const SMDS_MeshNode* > tgtNodes;
+    bool uvOK;
+    while ( elemIt->more() ) // loop on all mesh faces on srcFace
+    {
+      const SMDS_MeshElement* elem = elemIt->next();
+      const int nbN = elem->NbCornerNodes(); 
+      tgtNodes.resize( nbN );
+      for ( int i = 0; i < nbN; ++i ) // loop on nodes of the source element
+      {
+        const SMDS_MeshNode* srcNode = elem->GetNode(i);
+        srcN_tgtN = src2tgtNodes.insert( make_pair( srcNode, nullNode )).first;
+        if ( srcN_tgtN->second == nullNode )
+        {
+          // create a new node
+          gp_Pnt2d srcUV = srcHelper.GetNodeUV( srcFace, srcNode,
+                                                elem->GetNode( helper.WrapIndex(i+1,nbN)), &uvOK);
+          gp_Pnt2d tgtUV = srcUV.Transformed( trsf );
+          gp_Pnt   tgtP  = tgtSurface->Value( tgtUV.X(), tgtUV.Y() );
+          SMDS_MeshNode* n = tgtMeshDS->AddNode( tgtP.X(), tgtP.Y(), tgtP.Z() );
+          switch ( srcNode->GetPosition()->GetTypeOfPosition() )
+          {
+          case SMDS_TOP_FACE: {
+            tgtMeshDS->SetNodeOnFace( n, helper.GetSubShapeID(), tgtUV.X(), tgtUV.Y() );
+            break;
+          }
+          case SMDS_TOP_EDGE: {
+            TopoDS_Shape srcEdge = srcHelper.GetSubShapeByNode( srcNode, srcHelper.GetMeshDS() );
+            TopoDS_Edge  tgtEdge = TopoDS::Edge( shape2ShapeMap( srcEdge, /*isSrc=*/true ));
+            tgtMeshDS->SetNodeOnEdge( n, TopoDS::Edge( tgtEdge ));
+            double U = srcHelper.GetNodeU( TopoDS::Edge( srcEdge ), srcNode );
+            helper.CheckNodeU( tgtEdge, n, U, Precision::PConfusion());
+            n->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition( U )));
+            break;
+          }
+          case SMDS_TOP_VERTEX: {
+            TopoDS_Shape srcV = srcHelper.GetSubShapeByNode( srcNode, srcHelper.GetMeshDS() );
+            TopoDS_Shape tgtV = shape2ShapeMap( srcV, /*isSrc=*/true );
+            tgtMeshDS->SetNodeOnVertex( n, TopoDS::Vertex( tgtV ));
+            break;
+          }
+          }
+          srcN_tgtN->second = n;
+        }
+        tgtNodes[i] = srcN_tgtN->second;
+      }
+      // create a new face (with reversed orientation)
+      switch ( nbN )
+      {
+      case 3: helper.AddFace(tgtNodes[0], tgtNodes[2], tgtNodes[1]); break;
+      case 4: helper.AddFace(tgtNodes[0], tgtNodes[3], tgtNodes[2], tgtNodes[1]); break;
+      }
+    }
+    return true;
+
+  } // bool projectBy2DSimilarity(...)
+
 } // namespace
 
+
 //=======================================================================
 //function : Compute
 //purpose  : 
@@ -363,6 +773,7 @@ namespace {
 
 bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theShape)
 {
+  MESSAGE("Projection_2D Compute");
   if ( !_sourceHypo )
     return false;
 
@@ -374,14 +785,14 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   SMESHDS_Mesh * meshDS = theMesh.GetMeshDS();
 
   // ---------------------------
-  // Make subshapes association
+  // Make sub-shapes association
   // ---------------------------
 
   TopoDS_Face tgtFace = TopoDS::Face( theShape.Oriented(TopAbs_FORWARD));
   TopoDS_Shape srcShape = _sourceHypo->GetSourceFace().Oriented(TopAbs_FORWARD);
 
   TAssocTool::TShapeShapeMap shape2ShapeMap;
-  TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap, tgtFace );
+  TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap );
   if ( !TAssocTool::FindSubShapeAssociation( tgtFace, tgtMesh, srcShape, srcMesh,
                                              shape2ShapeMap)  ||
        !shape2ShapeMap.IsBound( tgtFace ))
@@ -405,197 +816,274 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
       return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
   }
 
-  // --------------------
-  // Prepare to mapping 
-  // --------------------
-
-  SMESH_MesherHelper helper( theMesh );
-  helper.SetSubShape( tgtFace );
-
-  // Check if node projection to a face is needed
-  Bnd_B2d uvBox;
-  SMDS_ElemIteratorPtr faceIt = srcSubMesh->GetSubMeshDS()->GetElements();
-  for ( int nbN = 0; nbN < 3 && faceIt->more();  ) {
-    const SMDS_MeshElement* face = faceIt->next();
-    SMDS_ElemIteratorPtr nodeIt = face->nodesIterator();
-    while ( nodeIt->more() ) {
-      const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-      if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ) {
-        nbN++;
-        uvBox.Add( helper.GetNodeUV( srcFace, node ));
-      }
-    }
-  }
-  const bool toProjectNodes = ( uvBox.IsVoid() || uvBox.SquareExtent() < DBL_MIN );
-
-  // Load pattern from the source face
-  SMESH_Pattern mapper;
-  mapper.Load( srcMesh, srcFace, toProjectNodes );
-  if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK )
-    return error(COMPERR_BAD_INPUT_MESH,"Can't load mesh pattern from the source face");
-
-  // Find the first target vertex corresponding to first vertex of the <mapper>
-  // and <theReverse> flag needed to call mapper.Apply()
-
-  TopoDS_Vertex srcV1 = TopoDS::Vertex( mapper.GetSubShape( 1 ));
-  if ( srcV1.IsNull() )
-    RETURN_BAD_RESULT("Mesh is not bound to the face");
-  if ( !shape2ShapeMap.IsBound( srcV1 ))
-    RETURN_BAD_RESULT("Not associated vertices, srcV1 " << srcV1.TShape().operator->() );
-  TopoDS_Vertex tgtV1 = TopoDS::Vertex( shape2ShapeMap( srcV1 ));
-
-  if ( !TAssocTool::IsSubShape( srcV1, srcFace ))
-    RETURN_BAD_RESULT("Wrong srcV1 " << srcV1.TShape().operator->());
-  if ( !TAssocTool::IsSubShape( tgtV1, tgtFace ))
-    RETURN_BAD_RESULT("Wrong tgtV1 " << tgtV1.TShape().operator->());
-
-  // try to find out orientation by order of edges
-  bool reverse = false;
-  list< TopoDS_Edge > tgtEdges, srcEdges;
-  list< int > nbEdgesInWires;
-  SMESH_Block::GetOrderedEdges( tgtFace, tgtV1, tgtEdges, nbEdgesInWires);
-  SMESH_Block::GetOrderedEdges( srcFace, srcV1, srcEdges, nbEdgesInWires);
-  if ( nbEdgesInWires.front() > 1 ) // possible to find out
+  // ===========
+  // Projection
+  // ===========
+
+  // find out if EDGEs are meshed or not
+  bool is1DComputed = false;
+  SMESH_subMeshIteratorPtr smIt = tgtSubMesh->getDependsOnIterator(/*includeSelf=*/false,
+                                                                   /*complexShapeFirst=*/true);
+  while ( smIt->more() && !is1DComputed )
   {
-    TopoDS_Edge srcE1 = srcEdges.front(), tgtE1 = tgtEdges.front();
-    TopoDS_Shape srcE1bis = shape2ShapeMap( tgtE1 );
-    reverse = ( ! srcE1.IsSame( srcE1bis ));
+    SMESH_subMesh* sm = smIt->next();
+    if ( sm->GetSubShape().ShapeType() == TopAbs_EDGE )
+      is1DComputed = sm->IsMeshComputed();
   }
-  else if ( nbEdgesInWires.front() == 1 )
+
+  bool done = false;
+
+  if ( !done )
   {
-    // TODO::Compare orientation of curves in a sole edge
-    //RETURN_BAD_RESULT("Not implemented case");
+    // try to project from the same face with different location
+    done = projectPartner( tgtFace, srcFace, tgtMesh, srcMesh, shape2ShapeMap );
   }
-  else
+  if ( !done )
   {
-    RETURN_BAD_RESULT("Bad result from SMESH_Block::GetOrderedEdges()");
+    // projection in case if the faces are similar in 2D space
+    done = projectBy2DSimilarity( tgtFace, srcFace, tgtMesh, srcMesh, shape2ShapeMap, is1DComputed);
   }
 
-  // --------------------
-  // Perform 2D mapping 
-  // --------------------
-
-  // Compute mesh on a target face
+  if ( !done )
+  {
+    // --------------------
+    // Prepare to mapping 
+    // --------------------
+
+    SMESH_MesherHelper helper( theMesh );
+    helper.SetSubShape( tgtFace );
+
+    // Check if node projection to a face is needed
+    Bnd_B2d uvBox;
+    SMDS_ElemIteratorPtr faceIt = srcSubMesh->GetSubMeshDS()->GetElements();
+    int nbFaceNodes = 0;
+    for ( ; nbFaceNodes < 3 && faceIt->more();  ) {
+      const SMDS_MeshElement* face = faceIt->next();
+      SMDS_ElemIteratorPtr nodeIt = face->nodesIterator();
+      while ( nodeIt->more() ) {
+        const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+        if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ) {
+          nbFaceNodes++;
+          uvBox.Add( helper.GetNodeUV( srcFace, node ));
+        }
+      }
+    }
+    const bool toProjectNodes =
+      ( nbFaceNodes > 0 && ( uvBox.IsVoid() || uvBox.SquareExtent() < DBL_MIN ));
+
+    // Load pattern from the source face
+    SMESH_Pattern mapper;
+    mapper.Load( srcMesh, srcFace, toProjectNodes );
+    if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK )
+      return error(COMPERR_BAD_INPUT_MESH,"Can't load mesh pattern from the source face");
+
+    // Find the first target vertex corresponding to first vertex of the <mapper>
+    // and <theReverse> flag needed to call mapper.Apply()
+
+    TopoDS_Vertex srcV1 = TopoDS::Vertex( mapper.GetSubShape( 1 ));
+    if ( srcV1.IsNull() )
+      RETURN_BAD_RESULT("Mesh is not bound to the face");
+    if ( !shape2ShapeMap.IsBound( srcV1, /*isSrc=*/true ))
+      RETURN_BAD_RESULT("Not associated vertices, srcV1 " << srcV1.TShape().operator->() );
+    TopoDS_Vertex tgtV1 = TopoDS::Vertex( shape2ShapeMap( srcV1, /*isSrc=*/true ));
+
+    if ( !SMESH_MesherHelper::IsSubShape( srcV1, srcFace ))
+      RETURN_BAD_RESULT("Wrong srcV1 " << srcV1.TShape().operator->());
+    if ( !SMESH_MesherHelper::IsSubShape( tgtV1, tgtFace ))
+      RETURN_BAD_RESULT("Wrong tgtV1 " << tgtV1.TShape().operator->());
+
+    // try to find out orientation by order of edges
+    bool reverse = false;
+    list< TopoDS_Edge > tgtEdges, srcEdges;
+    list< int > nbEdgesInWires;
+    SMESH_Block::GetOrderedEdges( tgtFace, tgtV1, tgtEdges, nbEdgesInWires);
+    SMESH_Block::GetOrderedEdges( srcFace, srcV1, srcEdges, nbEdgesInWires);
+    if ( nbEdgesInWires.front() > 1 ) // possible to find out
+    {
+      TopoDS_Edge srcE1 = srcEdges.front(), tgtE1 = tgtEdges.front();
+      TopoDS_Shape srcE1bis = shape2ShapeMap( tgtE1 );
+      reverse = ( ! srcE1.IsSame( srcE1bis ));
+    }
+    else if ( nbEdgesInWires.front() == 1 )
+    {
+      // TODO::Compare orientation of curves in a sole edge
+      //RETURN_BAD_RESULT("Not implemented case");
+    }
+    else
+    {
+      RETURN_BAD_RESULT("Bad result from SMESH_Block::GetOrderedEdges()");
+    }
 
-  mapper.Apply( tgtFace, tgtV1, reverse );
-  if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK )
-    return error("Can't apply source mesh pattern to the face");
+    // --------------------
+    // Perform 2D mapping 
+    // --------------------
 
-  // Create the mesh
+    // Compute mesh on a target face
 
-  const bool toCreatePolygons = false, toCreatePolyedrs = false;
-  mapper.MakeMesh( tgtMesh, toCreatePolygons, toCreatePolyedrs );
-  if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK )
-    return error("Can't make mesh by source mesh pattern");
+    mapper.Apply( tgtFace, tgtV1, reverse );
+    if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK )
+      return error("Can't apply source mesh pattern to the face");
 
-  // it will remove mesh built by pattern mapper on edges and vertices
-  // in failure case
-  MeshCleaner cleaner( tgtSubMesh );
+    // Create the mesh
 
-  // -------------------------------------------------------------------------
-  // mapper doesn't take care of nodes already existing on edges and vertices,
-  // so we must merge nodes created by it with existing ones 
-  // -------------------------------------------------------------------------
+    const bool toCreatePolygons = false, toCreatePolyedrs = false;
+    mapper.MakeMesh( tgtMesh, toCreatePolygons, toCreatePolyedrs );
+    if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK )
+      return error("Can't make mesh by source mesh pattern");
 
-  SMESH_MeshEditor editor( tgtMesh );
-  SMESH_MeshEditor::TListOfListOfNodes groupsOfNodes;
+    // it will remove mesh built by pattern mapper on edges and vertices
+    // in failure case
+    MeshCleaner cleaner( tgtSubMesh );
 
-  // Make groups of nodes to merge
+    // -------------------------------------------------------------------------
+    // mapper doesn't take care of nodes already existing on edges and vertices,
+    // so we must merge nodes created by it with existing ones 
+    // -------------------------------------------------------------------------
 
-  // loop on edge and vertex submeshes of a target face
-  SMESH_subMeshIteratorPtr smIt = tgtSubMesh->getDependsOnIterator(false,false);
-  while ( smIt->more() )
-  {
-    SMESH_subMesh*     sm = smIt->next();
-    SMESHDS_SubMesh* smDS = sm->GetSubMeshDS();
+    SMESH_MeshEditor::TListOfListOfNodes groupsOfNodes;
 
-    // Sort new and old nodes of a submesh separately
+    // Make groups of nodes to merge
 
-    bool isSeam = helper.IsRealSeam( sm->GetId() );
+    // loop on edge and vertex submeshes of a target face
+    smIt = tgtSubMesh->getDependsOnIterator(/*includeSelf=*/false,/*complexShapeFirst=*/false);
+    while ( smIt->more() )
+    {
+      SMESH_subMesh*     sm = smIt->next();
+      SMESHDS_SubMesh* smDS = sm->GetSubMeshDS();
+      if ( !smDS || smDS->NbNodes() == 0 )
+        continue;
+      //if ( !is1DComputed && sm->GetSubShape().ShapeType() == TopAbs_EDGE )
+      //break;
 
-    enum { NEW_NODES = 0, OLD_NODES };
-    map< double, const SMDS_MeshNode* > u2nodesMaps[2], u2nodesOnSeam;
-    map< double, const SMDS_MeshNode* >::iterator u_oldNode, u_newNode, u_newOnSeam, newEnd;
-    set< const SMDS_MeshNode* > seamNodes;
+      // Sort new and old nodes of a submesh separately
 
-    // mapper puts on a seam edge nodes from 2 edges
-    if ( isSeam && ! getBoundaryNodes ( sm, tgtFace, u2nodesOnSeam, seamNodes ))
-      RETURN_BAD_RESULT("getBoundaryNodes() failed");
+      bool isSeam = helper.IsRealSeam( sm->GetId() );
 
-    SMDS_NodeIteratorPtr nIt = smDS->GetNodes();
-    while ( nIt->more() )
-    {
-      const SMDS_MeshNode* node = nIt->next();
-      bool isOld = isOldNode( node );
+      enum { NEW_NODES = 0, OLD_NODES };
+      map< double, const SMDS_MeshNode* > u2nodesMaps[2], u2nodesOnSeam;
+      map< double, const SMDS_MeshNode* >::iterator u_oldNode, u_newNode, u_newOnSeam, newEnd;
+      set< const SMDS_MeshNode* > seamNodes;
 
-      if ( !isOld && isSeam ) { // new node on a seam edge
-        if ( seamNodes.find( node ) != seamNodes.end())
-          continue; // node is already in the map
-      }
+      // mapper puts on a seam edge nodes from 2 edges
+      if ( isSeam && ! getBoundaryNodes ( sm, tgtFace, u2nodesOnSeam, seamNodes ))
+        RETURN_BAD_RESULT("getBoundaryNodes() failed");
 
-      // sort nodes on edges by their position
-      map< double, const SMDS_MeshNode* > & pos2nodes = u2nodesMaps[isOld ? OLD_NODES : NEW_NODES];
-      switch ( node->GetPosition()->GetTypeOfPosition() )
+      SMDS_NodeIteratorPtr nIt = smDS->GetNodes();
+      while ( nIt->more() )
       {
-      case  SMDS_TOP_VERTEX: {
-        pos2nodes.insert( make_pair( 0, node ));
-        break;
-      }
-      case  SMDS_TOP_EDGE:   {
-        const SMDS_EdgePosition* pos =
-          static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
-        pos2nodes.insert( make_pair( pos->GetUParameter(), node ));
-        break;
+        const SMDS_MeshNode* node = nIt->next();
+        bool isOld = isOldNode( node );
+
+        if ( !isOld && isSeam ) { // new node on a seam edge
+          if ( seamNodes.count( node ) )
+            continue; // node is already in the map
+        }
+
+        // sort nodes on edges by their position
+        map< double, const SMDS_MeshNode* > & pos2nodes = u2nodesMaps[isOld ? OLD_NODES : NEW_NODES];
+        switch ( node->GetPosition()->GetTypeOfPosition() )
+        {
+        case  SMDS_TOP_VERTEX: {
+          if ( !is1DComputed && !pos2nodes.empty() )
+            u2nodesMaps[isOld ? NEW_NODES : OLD_NODES].insert( make_pair( 0, node ));
+          else
+            pos2nodes.insert( make_pair( 0, node ));
+          break;
+        }
+        case  SMDS_TOP_EDGE:   {
+          const SMDS_EdgePosition* pos =
+            static_cast<const SMDS_EdgePosition*>(node->GetPosition());
+          pos2nodes.insert( make_pair( pos->GetUParameter(), node ));
+          break;
+        }
+        default:
+          RETURN_BAD_RESULT("Wrong node position type: "<<
+                            node->GetPosition()->GetTypeOfPosition());
+        }
       }
-      default:
-        RETURN_BAD_RESULT("Wrong node position type: "<<
-                          node->GetPosition()->GetTypeOfPosition());
+      const bool mergeNewToOld =
+        ( u2nodesMaps[ NEW_NODES ].size() == u2nodesMaps[ OLD_NODES ].size() );
+      const bool mergeSeamToNew =
+        ( u2nodesMaps[ NEW_NODES ].size() == u2nodesOnSeam.size() );
+
+      if ( !mergeNewToOld )
+        if ( u2nodesMaps[ NEW_NODES ].size() > 0 &&
+             u2nodesMaps[ OLD_NODES ].size() > 0 )
+        {
+          u_oldNode = u2nodesMaps[ OLD_NODES ].begin(); 
+          newEnd    = u2nodesMaps[ OLD_NODES ].end();
+          for ( ; u_oldNode != newEnd; ++u_oldNode )
+            _badInputElements.push_back( u_oldNode->second );
+          return error( COMPERR_BAD_INPUT_MESH,
+                        SMESH_Comment( "Existing mesh mismatches the projected 2D mesh on " )
+                        << ( sm->GetSubShape().ShapeType() == TopAbs_EDGE ? "edge" : "vertex" )
+                        << " #" << sm->GetId() );
+        }
+      if ( isSeam && !mergeSeamToNew ) {
+        //RETURN_BAD_RESULT
+        MESSAGE("Different nb of old and seam nodes " <<
+                u2nodesMaps[ OLD_NODES ].size() << " != " << u2nodesOnSeam.size());
       }
+      // Make groups of nodes to merge
+      u_oldNode = u2nodesMaps[ OLD_NODES ].begin(); 
+      u_newNode = u2nodesMaps[ NEW_NODES ].begin();
+      newEnd    = u2nodesMaps[ NEW_NODES ].end();
+      u_newOnSeam = u2nodesOnSeam.begin();
+      if ( mergeNewToOld )
+        for ( ; u_newNode != newEnd; ++u_newNode, ++u_oldNode )
+        {
+          groupsOfNodes.push_back( list< const SMDS_MeshNode* >() );
+          groupsOfNodes.back().push_back( u_oldNode->second );
+          groupsOfNodes.back().push_back( u_newNode->second );
+          if ( mergeSeamToNew )
+            groupsOfNodes.back().push_back( (u_newOnSeam++)->second );
+        }
+      else if ( mergeSeamToNew )
+        for ( ; u_newNode != newEnd; ++u_newNode, ++u_newOnSeam )
+        {
+          groupsOfNodes.push_back( list< const SMDS_MeshNode* >() );
+          groupsOfNodes.back().push_back( u_newNode->second );
+          groupsOfNodes.back().push_back( u_newOnSeam->second );
+        }
     }
-    if ( u2nodesMaps[ NEW_NODES ].size() != u2nodesMaps[ OLD_NODES ].size() )
+
+    // Merge
+
+    SMESH_MeshEditor editor( tgtMesh );
+    int nbFaceBeforeMerge = tgtSubMesh->GetSubMeshDS()->NbElements();
+    editor.MergeNodes( groupsOfNodes );
+    int nbFaceAtferMerge = tgtSubMesh->GetSubMeshDS()->NbElements();
+    if ( nbFaceBeforeMerge != nbFaceAtferMerge )
+      return error(COMPERR_BAD_INPUT_MESH, "Probably invalid node parameters on geom faces");
+
+    // ----------------------------------------------------------------
+    // The mapper can't create quadratic elements, so convert if needed
+    // ----------------------------------------------------------------
+
+    faceIt         = srcSubMesh->GetSubMeshDS()->GetElements();
+    bool srcIsQuad = faceIt->next()->IsQuadratic();
+    faceIt         = tgtSubMesh->GetSubMeshDS()->GetElements();
+    bool tgtIsQuad = faceIt->next()->IsQuadratic();
+    if ( srcIsQuad && !tgtIsQuad )
     {
-      if ( u2nodesMaps[ NEW_NODES ].size() == 0         &&
-           sm->GetSubShape().ShapeType() == TopAbs_EDGE &&
-           helper.IsDegenShape( sm->GetId() )             )
-        // NPAL15894 (tt88bis.py) - project mesh built by NETGEN_1d_2D that
-        // does not make segments/nodes on degenerated edges
-        continue;
+      TIDSortedElemSet tgtFaces;
+      faceIt = tgtSubMesh->GetSubMeshDS()->GetElements();
+      while ( faceIt->more() )
+        tgtFaces.insert( tgtFaces.end(), faceIt->next() );
 
-      RETURN_BAD_RESULT("Different nb of old and new nodes on shape #"<< sm->GetId() <<" "<<
-                        u2nodesMaps[ OLD_NODES ].size() << " != " <<
-                        u2nodesMaps[ NEW_NODES ].size());
+      editor.ConvertToQuadratic(/*theForce3d=*/false, tgtFaces);
     }
-    if ( isSeam && u2nodesMaps[ OLD_NODES ].size() != u2nodesOnSeam.size() ) {
-      RETURN_BAD_RESULT("Different nb of old and seam nodes " <<
-                        u2nodesMaps[ OLD_NODES ].size() << " != " << u2nodesOnSeam.size());
-    }
-    // Make groups of nodes to merge
-    u_oldNode = u2nodesMaps[ OLD_NODES ].begin(); 
-    u_newNode = u2nodesMaps[ NEW_NODES ].begin();
-    newEnd    = u2nodesMaps[ NEW_NODES ].end();
-    u_newOnSeam = u2nodesOnSeam.begin();
-    for ( ; u_newNode != newEnd; ++u_newNode, ++u_oldNode ) {
-      groupsOfNodes.push_back( list< const SMDS_MeshNode* >() );
-      groupsOfNodes.back().push_back( u_oldNode->second );
-      groupsOfNodes.back().push_back( u_newNode->second );
-      if ( isSeam )
-        groupsOfNodes.back().push_back( (u_newOnSeam++)->second );
-    }
-  }
 
-  // Merge
+    cleaner.Release(); // not to remove mesh
+
+  } // end of projection using Pattern mapping
 
-  int nbFaceBeforeMerge = tgtSubMesh->GetSubMeshDS()->NbElements();
-  editor.MergeNodes( groupsOfNodes );
-  int nbFaceAtferMerge = tgtSubMesh->GetSubMeshDS()->NbElements();
-  if ( nbFaceBeforeMerge != nbFaceAtferMerge )
-    return error(COMPERR_BAD_INPUT_MESH, "Probably invalid node parameters on geom faces");
 
   // ---------------------------
   // Check elements orientation
   // ---------------------------
 
-  TopoDS_Face face = tgtFace;
+  TopoDS_Face face = TopoDS::Face( theShape );
   if ( !theMesh.IsMainShape( tgtFace ))
   {
     // find the main shape
@@ -627,6 +1115,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   // Fix orientation
   if ( SMESH_Algo::IsReversedSubMesh( face, meshDS ))
   {
+    SMESH_MeshEditor editor( tgtMesh );
     SMDS_ElemIteratorPtr eIt = meshDS->MeshElements( face )->GetElements();
     while ( eIt->more() ) {
       const SMDS_MeshElement* e = eIt->next();
@@ -635,11 +1124,77 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
     }
   }
 
-  cleaner.Release(); // do not remove mesh
+  return true;
+}
+
+
+//=======================================================================
+//function : Evaluate
+//purpose  : 
+//=======================================================================
+
+bool StdMeshers_Projection_2D::Evaluate(SMESH_Mesh&         theMesh,
+                                        const TopoDS_Shape& theShape,
+                                        MapShapeNbElems&    aResMap)
+{
+  if ( !_sourceHypo )
+    return false;
+
+  SMESH_Mesh * srcMesh = _sourceHypo->GetSourceMesh();
+  SMESH_Mesh * tgtMesh = & theMesh;
+  if ( !srcMesh )
+    srcMesh = tgtMesh;
+
+  // ---------------------------
+  // Make sub-shapes association
+  // ---------------------------
+
+  TopoDS_Face tgtFace = TopoDS::Face( theShape.Oriented(TopAbs_FORWARD));
+  TopoDS_Shape srcShape = _sourceHypo->GetSourceFace().Oriented(TopAbs_FORWARD);
+
+  TAssocTool::TShapeShapeMap shape2ShapeMap;
+  TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap );
+  if ( !TAssocTool::FindSubShapeAssociation( tgtFace, tgtMesh, srcShape, srcMesh,
+                                             shape2ShapeMap)  ||
+       !shape2ShapeMap.IsBound( tgtFace ))
+    return error(COMPERR_BAD_SHAPE,"Topology of source and target faces seems different" );
+
+  TopoDS_Face srcFace = TopoDS::Face( shape2ShapeMap( tgtFace ).Oriented(TopAbs_FORWARD));
+
+  // -------------------------------------------------------
+  // Assure that mesh on a source Face is computed/evaluated
+  // -------------------------------------------------------
+
+  std::vector<int> aVec;
+
+  SMESH_subMesh* srcSubMesh = srcMesh->GetSubMesh( srcFace );
+  if ( srcSubMesh->IsMeshComputed() )
+  {
+    aVec.resize( SMDSEntity_Last, 0 );
+    aVec[SMDSEntity_Node] = srcSubMesh->GetSubMeshDS()->NbNodes();
+
+    SMDS_ElemIteratorPtr elemIt = srcSubMesh->GetSubMeshDS()->GetElements();
+    while ( elemIt->more() )
+      aVec[ elemIt->next()->GetEntityType() ]++;
+  }
+  else
+  {
+    MapShapeNbElems  tmpResMap;
+    MapShapeNbElems& srcResMap = (srcMesh == tgtMesh) ? aResMap : tmpResMap;
+    if ( !_gen->Evaluate( *srcMesh, srcShape, srcResMap ))
+      return error(COMPERR_BAD_INPUT_MESH,"Source mesh not evaluatable");
+    aVec = srcResMap[ srcSubMesh ];
+    if ( aVec.empty() )
+      return error(COMPERR_BAD_INPUT_MESH,"Source mesh is wrongly evaluated");
+  }
+
+  SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
+  aResMap.insert(std::make_pair(sm,aVec));
 
   return true;
 }
 
+
 //=============================================================================
 /*!
  * \brief Sets a default event listener to submesh of the source face
index 006db83448d5da5e6a95a278bd097ffa6eda0231..3d1bd1808e7b76336a3c2bc85760cf29e9839af2 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_Projection_2D.hxx
 //  Module : SMESH
@@ -44,6 +45,9 @@ public:
 
   virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
 
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
+
   /*!
    * \brief Sets a default event listener to submesh of the source face
    *  \param whenSetToSubMesh - submesh where algo is set
index 7d657ac4e07b501bd503198b81ff6505c319524c..76c29c82215f3cc96ac1a6784801c970ff30fbcc 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 // File      : StdMeshers_Projection_3D.cxx
 // Module    : SMESH
 
 #include "StdMeshers_ProjectionUtils.hxx"
 
+#include "SMDS_PolyhedralVolumeOfNodes.hxx"
+#include "SMDS_VolumeTool.hxx"
 #include "SMESHDS_Hypothesis.hxx"
 #include "SMESHDS_SubMesh.hxx"
 #include "SMESH_Block.hxx"
+#include "SMESH_Comment.hxx"
 #include "SMESH_Gen.hxx"
 #include "SMESH_Mesh.hxx"
-#include "SMESH_MeshEditor.hxx"
+#include "SMESH_MesherHelper.hxx"
 #include "SMESH_Pattern.hxx"
 #include "SMESH_subMesh.hxx"
 #include "SMESH_subMeshEventListener.hxx"
-#include "SMESH_MesherHelper.hxx"
-#include "SMESH_Comment.hxx"
-#include "SMDS_VolumeTool.hxx"
-#include "SMDS_PolyhedralVolumeOfNodes.hxx"
 
 #include "utilities.h"
 
@@ -69,7 +69,7 @@ StdMeshers_Projection_3D::StdMeshers_Projection_3D(int hypId, int studyId, SMESH
   :SMESH_3D_Algo(hypId, studyId, gen)
 {
   _name = "Projection_3D";
-  _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);      // 1 bit per shape type
+  _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);  // 1 bit per shape type
 
   _compatibleHypothesis.push_back("ProjectionSource3D");
   _sourceHypo = 0;
@@ -142,12 +142,12 @@ bool StdMeshers_Projection_3D::CheckHypothesis(SMESH_Mesh&
       TopoDS_Shape edge = TAssocTool::GetEdgeByVertices
         ( srcMesh, _sourceHypo->GetSourceVertex(1), _sourceHypo->GetSourceVertex(2) );
       if ( edge.IsNull() ||
-           !TAssocTool::IsSubShape( edge, srcMesh ) ||
-           !TAssocTool::IsSubShape( edge, _sourceHypo->GetSource3DShape() ))
+           !SMESH_MesherHelper::IsSubShape( edge, srcMesh ) ||
+           !SMESH_MesherHelper::IsSubShape( edge, _sourceHypo->GetSource3DShape() ))
       {
         SCRUTE((edge.IsNull()));
-        SCRUTE((TAssocTool::IsSubShape( edge, srcMesh )));
-        SCRUTE((TAssocTool::IsSubShape( edge, _sourceHypo->GetSource3DShape() )));
+        SCRUTE((SMESH_MesherHelper::IsSubShape( edge, srcMesh )));
+        SCRUTE((SMESH_MesherHelper::IsSubShape( edge, _sourceHypo->GetSource3DShape() )));
         aStatus = SMESH_Hypothesis::HYP_BAD_PARAMETER;
       }
       else
@@ -156,21 +156,21 @@ bool StdMeshers_Projection_3D::CheckHypothesis(SMESH_Mesh&
         edge = TAssocTool::GetEdgeByVertices
           ( tgtMesh, _sourceHypo->GetTargetVertex(1), _sourceHypo->GetTargetVertex(2) );
         if ( edge.IsNull() ||
-             !TAssocTool::IsSubShape( edge, tgtMesh ) ||
-             !TAssocTool::IsSubShape( edge, aShape ))
+             !SMESH_MesherHelper::IsSubShape( edge, tgtMesh ) ||
+             !SMESH_MesherHelper::IsSubShape( edge, aShape ))
         {
           SCRUTE((edge.IsNull()));
-          SCRUTE((TAssocTool::IsSubShape( edge, tgtMesh )));
-          SCRUTE((TAssocTool::IsSubShape( edge, aShape )));
+          SCRUTE((SMESH_MesherHelper::IsSubShape( edge, tgtMesh )));
+          SCRUTE((SMESH_MesherHelper::IsSubShape( edge, aShape )));
           aStatus = SMESH_Hypothesis::HYP_BAD_PARAMETER;
         }
       }
     }
     // check a source shape
-    if ( !TAssocTool::IsSubShape( _sourceHypo->GetSource3DShape(), srcMesh ) ||
+    if ( !SMESH_MesherHelper::IsSubShape( _sourceHypo->GetSource3DShape(), srcMesh ) ||
          ( srcMesh == tgtMesh && aShape == _sourceHypo->GetSource3DShape()))
     {
-      SCRUTE((TAssocTool::IsSubShape( _sourceHypo->GetSource3DShape(), srcMesh)));
+      SCRUTE((SMESH_MesherHelper::IsSubShape( _sourceHypo->GetSource3DShape(), srcMesh)));
       SCRUTE((srcMesh == tgtMesh));
       SCRUTE((aShape == _sourceHypo->GetSource3DShape()));
       aStatus = SMESH_Hypothesis::HYP_BAD_PARAMETER;
@@ -264,12 +264,12 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS
     TopExp::Vertices( TopoDS::Edge( exp.Current() ), tgtV000, tgtV100 );
 
     if ( !shape2ShapeMap.IsBound( tgtV000 ) || !shape2ShapeMap.IsBound( tgtV100 ))
-      return error("Association of subshapes failed" );
+      return error("Association of sub-shapes failed" );
     srcV000 = TopoDS::Vertex( shape2ShapeMap( tgtV000 ));
     srcV100 = TopoDS::Vertex( shape2ShapeMap( tgtV100 ));
-    if ( !TAssocTool::IsSubShape( srcV000, srcShell ) ||
-         !TAssocTool::IsSubShape( srcV100, srcShell ))
-      return error("Incorrect association of subshapes" );
+    if ( !SMESH_MesherHelper::IsSubShape( srcV000, srcShell ) ||
+         !SMESH_MesherHelper::IsSubShape( srcV100, srcShell ))
+      return error("Incorrect association of sub-shapes" );
   }
 
   // Load 2 SMESH_Block's with src and tgt shells
@@ -277,20 +277,20 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS
   SMESH_Block srcBlock, tgtBlock;
   TopTools_IndexedMapOfOrientedShape scrShapes, tgtShapes;
   if ( !tgtBlock.LoadBlockShapes( tgtShell, tgtV000, tgtV100, tgtShapes ))
-    return error(COMPERR_BAD_SHAPE, "Can't detect block subshapes. Not a block?");
+    return error(COMPERR_BAD_SHAPE, "Can't detect block sub-shapes. Not a block?");
 
   if ( !srcBlock.LoadBlockShapes( srcShell, srcV000, srcV100, scrShapes ))
-    return error(COMPERR_BAD_SHAPE, "Can't detect block subshapes. Not a block?");
+    return error(COMPERR_BAD_SHAPE, "Can't detect block sub-shapes. Not a block?");
 
   // Find matching nodes of src and tgt shells
 
   TNodeNodeMap src2tgtNodeMap;
   for ( int fId = SMESH_Block::ID_FirstF; fId < SMESH_Block::ID_Shell; ++fId )
   {
-    // Corresponding subshapes
+    // Corresponding sub-shapes
     TopoDS_Face srcFace = TopoDS::Face( scrShapes( fId ));
     TopoDS_Face tgtFace = TopoDS::Face( tgtShapes( fId ));
-    if ( _sourceHypo->HasVertexAssociation() ) { // associate face subshapes
+    if ( _sourceHypo->HasVertexAssociation() ) { // associate face sub-shapes
       shape2ShapeMap.Clear();
       vector< int > edgeIdVec;
       SMESH_Block::GetFaceEdgesIDs( fId, edgeIdVec );
@@ -309,9 +309,9 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS
     TNodeNodeMap faceMatchingNodes;
     if ( ! TAssocTool::FindMatchingNodesOnFaces( srcFace, srcMesh, tgtFace, tgtMesh, 
                                                  shape2ShapeMap, faceMatchingNodes ))
-    return error(COMPERR_BAD_INPUT_MESH,SMESH_Comment("Mesh on faces #")
-                 << srcMeshDS->ShapeToIndex( srcFace ) << " and "
-                 << tgtMeshDS->ShapeToIndex( tgtFace ) << " seems different" );
+      return error(COMPERR_BAD_INPUT_MESH,SMESH_Comment("Mesh on faces #")
+                   << srcMeshDS->ShapeToIndex( srcFace ) << " and "
+                   << tgtMeshDS->ShapeToIndex( tgtFace ) << " seems different" );
 
     // put found matching nodes of 2 faces to the global map
     src2tgtNodeMap.insert( faceMatchingNodes.begin(), faceMatchingNodes.end() );
@@ -407,11 +407,13 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS
                                  nodes[6],
                                  nodes[7], id, force3d); break;
     default: // polyhedron
-      const SMDS_PolyhedralVolumeOfNodes * poly =
-        dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>( srcVol );
+      const SMDS_VtkVolume * poly =
+        dynamic_cast<const SMDS_VtkVolume*>( srcVol );
       if ( !poly )
         RETURN_BAD_RESULT("Unexpected volume type");
-      tgtVol = tgtMeshDS->AddPolyhedralVolume( nodes, poly->GetQuanities() );
+      if ( !poly->IsPoly())
+        RETURN_BAD_RESULT("Unexpected volume type");
+      tgtVol = tgtMeshDS->AddPolyhedralVolume( nodes, poly->GetQuantities() );
     }
     if ( tgtVol ) {
       tgtMeshDS->SetMeshElementOnShape( tgtVol, helper.GetSubShapeID() );
@@ -421,6 +423,104 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS
   return true;
 }
 
+
+//=======================================================================
+//function : Evaluate
+//purpose  : 
+//=======================================================================
+
+bool StdMeshers_Projection_3D::Evaluate(SMESH_Mesh& aMesh,
+                                        const TopoDS_Shape& aShape,
+                                        MapShapeNbElems& aResMap)
+{
+  if ( !_sourceHypo )
+    return false;
+
+  SMESH_Mesh * srcMesh = _sourceHypo->GetSourceMesh();
+  SMESH_Mesh * tgtMesh = & aMesh;
+  if ( !srcMesh )
+    srcMesh = tgtMesh;
+
+  // get shell from shape3D
+  TopoDS_Shell srcShell, tgtShell;
+  TopExp_Explorer exp( _sourceHypo->GetSource3DShape(), TopAbs_SHELL );
+  int nbShell;
+  for ( nbShell = 0; exp.More(); exp.Next(), ++nbShell )
+    srcShell = TopoDS::Shell( exp.Current() );
+  if ( nbShell != 1 )
+    return error(COMPERR_BAD_SHAPE,
+                 SMESH_Comment("Source shape must have 1 shell but not ") << nbShell);
+
+  exp.Init( aShape, TopAbs_SHELL );
+  for ( nbShell = 0; exp.More(); exp.Next(), ++nbShell )
+    tgtShell = TopoDS::Shell( exp.Current() );
+  if ( nbShell != 1 )
+    return error(COMPERR_BAD_SHAPE,
+                 SMESH_Comment("Target shape must have 1 shell but not ") << nbShell);
+
+  // Check that shapes are blocks
+  if ( TAssocTool::Count( tgtShell, TopAbs_FACE , 1 ) != 6 ||
+       TAssocTool::Count( tgtShell, TopAbs_EDGE , 1 ) != 12 ||
+       TAssocTool::Count( tgtShell, TopAbs_WIRE , 1 ) != 6 )
+    return error(COMPERR_BAD_SHAPE, "Target shape is not a block");
+  if ( TAssocTool::Count( srcShell, TopAbs_FACE , 1 ) != 6 ||
+       TAssocTool::Count( srcShell, TopAbs_EDGE , 1 ) != 12 ||
+       TAssocTool::Count( srcShell, TopAbs_WIRE , 1 ) != 6 )
+    return error(COMPERR_BAD_SHAPE, "Source shape is not a block");
+
+  // Assure that mesh on a source shape is computed
+
+  SMESH_subMesh* srcSubMesh = srcMesh->GetSubMesh( _sourceHypo->GetSource3DShape() );
+
+  if ( !srcSubMesh->IsMeshComputed() )
+    return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
+
+
+  std::vector<int> aVec(SMDSEntity_Last);
+  for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aVec[i] = 0;
+
+  aVec[SMDSEntity_Node] = srcSubMesh->GetSubMeshDS()->NbNodes();
+
+  //bool quadratic = false;
+  SMDS_ElemIteratorPtr elemIt = srcSubMesh->GetSubMeshDS()->GetElements();
+  while ( elemIt->more() ) {
+    const SMDS_MeshElement* E  = elemIt->next();
+    if( E->NbNodes()==4 ) {
+      aVec[SMDSEntity_Tetra]++;
+    }
+    else if( E->NbNodes()==5 ) {
+      aVec[SMDSEntity_Pyramid]++;
+    }
+    else if( E->NbNodes()==6 ) {
+      aVec[SMDSEntity_Penta]++;
+    }
+    else if( E->NbNodes()==8 ) {
+      aVec[SMDSEntity_Hexa]++;
+    }
+    else if( E->NbNodes()==10 && E->IsQuadratic() ) {
+      aVec[SMDSEntity_Quad_Tetra]++;
+    }
+    else if( E->NbNodes()==13 && E->IsQuadratic() ) {
+      aVec[SMDSEntity_Quad_Pyramid]++;
+    }
+    else if( E->NbNodes()==15 && E->IsQuadratic() ) {
+      aVec[SMDSEntity_Quad_Penta]++;
+    }
+    else if( E->NbNodes()==20 && E->IsQuadratic() ) {
+      aVec[SMDSEntity_Quad_Hexa]++;
+    }
+    else {
+      aVec[SMDSEntity_Polyhedra]++;
+    }
+  }
+
+  SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+  aResMap.insert(std::make_pair(sm,aVec));
+
+  return true;
+}
+
+
 //=============================================================================
 /*!
  * \brief Sets a default event listener to submesh of the source shape
index 7f4200ef42d87ae6f8a0d4db2dc6d4915e423274..03e8c4838a8382c48d4ea757e55fcb330be85b85 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_Projection_3D.hxx
 //  Module : SMESH
@@ -44,6 +45,9 @@ public:
 
   virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
 
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
+
   /*!
    * \brief Sets a default event listener to submesh of the source shape
    *  \param whenSetToSubMesh - submesh where algo is set
index c6b9b015fb50193491cfb8dd7525e74b8cfe26f4..0550c86a7940ba5ea333f27b6bdf3ba2bfe1be76 100644 (file)
@@ -1,34 +1,36 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_Propagation.cxx
 //  Module : SMESH
-
+//
 #include "StdMeshers_Propagation.hxx"
 
 #include "utilities.h"
 
 #include "SMDS_SetIterator.hxx"
 #include "SMESH_Algo.hxx"
+#include "SMESH_Gen.hxx"
 #include "SMESH_HypoFilter.hxx"
 #include "SMESH_Mesh.hxx"
 #include "SMESH_subMesh.hxx"
@@ -39,7 +41,7 @@
 #include <TopoDS.hxx>
 
 #define DBGMSG(txt) \
-//  cout << txt << endl;
+  //  cout << txt << endl;
 
 using namespace std;
 
@@ -266,7 +268,7 @@ namespace {
       for (; itA.More(); itA.Next())
       {
         // there are objects of different type among the ancestors of edge
-        if ( itA.Value().ShapeType() != TopAbs_WIRE || !checkedShapes.Add( itA.Value() ))
+        if ( itA.Value().ShapeType() != TopAbs_WIRE /*|| !checkedShapes.Add( itA.Value() )*/)
           continue;
 
         // Get ordered edges and find index of anE in a sequence
@@ -288,8 +290,7 @@ namespace {
           continue; // too few edges
         }
         else if ( edges.size() == 4 ) {
-          int oppIndex = edgeIndex + 2;
-          if ( oppIndex > 3 ) oppIndex -= 4;
+          int oppIndex = ( edgeIndex + 2 ) % 4;
           anOppE = edges[ oppIndex ];
         }
         else {
@@ -346,6 +347,10 @@ namespace {
             oppSM->ComputeStateEngine( SMESH_subMesh::CLEAN );
             oppData->SetState( IN_CHAIN );
             DBGMSG( "set IN_CHAIN on " << oppSM->GetId() );
+            if ( oppSM->GetAlgoState() != SMESH_subMesh::HYP_OK )
+              // make oppSM check algo state
+              if ( SMESH_Algo* algo = mesh->GetGen()->GetAlgo( *mesh, anOppE ))
+                oppSM->AlgoStateEngine(SMESH_subMesh::ADD_FATHER_ALGO,algo);
           }
           else {
             oppData->SetState( LAST_IN_CHAIN );
@@ -444,7 +449,8 @@ namespace {
   //================================================================================
 
   PropagationMgr::PropagationMgr()
-    : SMESH_subMeshEventListener( false ) // won't be deleted by submesh
+    : SMESH_subMeshEventListener( false, // won't be deleted by submesh
+                                  "StdMeshers_Propagation::PropagationMgr")
   {}
   //================================================================================
   /*!
@@ -454,6 +460,7 @@ namespace {
 
   void PropagationMgr::Set(SMESH_subMesh * submesh)
   {
+    if ( findData( submesh )) return;
     DBGMSG( "PropagationMgr::Set() on  " << submesh->GetId() );
     EventListenerData* data = new PropagationMgrData();
     submesh->SetEventListener( getListener(), data, submesh );
index b02f9aebe03b39961ca1069c0296e63e113d53fe..5a72d72a51798648d6509c2980d0d251946543db 100644 (file)
@@ -1,28 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_Propagation.hxx
 //  Module : SMESH
-
+//
 #ifndef _SMESH_PROPAGATION_HXX_
 #define _SMESH_PROPAGATION_HXX_
 
index 620bad81c2fd9e75f69f66ffc1613ae3b0351f0b..5764cc6eac0520dda5a7f2a24ae226c59a627b0d 100644 (file)
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  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 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.
 //
-//  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
 //
-//  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.com
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-//  SMESH SMESH : implementaion of SMESH idl descriptions
+
 // File      : StdMeshers_QuadToTriaAdaptor.cxx
 // Module    : SMESH
 // Created   : Wen May 07 16:37:07 2008
 // Author    : Sergey KUUL (skl)
-//
+
 #include "StdMeshers_QuadToTriaAdaptor.hxx"
 
-//#include <TColgp_HArray1OfPnt.hxx>
-//#include <TColgp_HArray1OfVec.hxx>
+#include "SMDS_SetIterator.hxx"
+
+#include "SMESH_Algo.hxx"
+#include "SMESH_MesherHelper.hxx"
+
+#include <IntAna_IntConicQuad.hxx>
+#include <IntAna_Quadric.hxx>
+#include <TColgp_HArray1OfPnt.hxx>
+#include <TColgp_HArray1OfVec.hxx>
+#include <TColgp_HSequenceOfPnt.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopoDS.hxx>
-#include <SMESH_Algo.hxx>
-#include <TColgp_HSequenceOfPnt.hxx>
-#include <TColStd_MapOfInteger.hxx>
-#include <TColStd_HSequenceOfInteger.hxx>
-#include <IntAna_Quadric.hxx>
-#include <IntAna_IntConicQuad.hxx>
 #include <gp_Lin.hxx>
 #include <gp_Pln.hxx>
-#include <SMDS_FaceOfNodes.hxx>
 
-#include <NCollection_Array1.hxx>
-typedef NCollection_Array1<TColStd_SequenceOfInteger> StdMeshers_Array1OfSequenceOfInteger;
+#include <numeric>
+#include <limits>
 
+using namespace std;
 
-//=======================================================================
-//function : StdMeshers_QuadToTriaAdaptor
-//purpose  : 
-//=======================================================================
+enum EQuadNature { NOT_QUAD, QUAD, DEGEN_QUAD, PYRAM_APEX = 4, TRIA_APEX = 0 };
 
-StdMeshers_QuadToTriaAdaptor::StdMeshers_QuadToTriaAdaptor()
+// std-like iterator used to get coordinates of nodes of mesh element
+typedef SMDS_StdIterator< SMESH_TNodeXYZ, SMDS_ElemIteratorPtr > TXyzIterator;
+
+namespace
 {
+  //================================================================================
+  /*!
+   * \brief Return true if two nodes of triangles are equal
+   */
+  //================================================================================
+
+  bool EqualTriangles(const SMDS_MeshElement* F1,const SMDS_MeshElement* F2)
+  {
+    return
+      ( F1->GetNode(1)==F2->GetNode(2) && F1->GetNode(2)==F2->GetNode(1) ) ||
+      ( F1->GetNode(1)==F2->GetNode(1) && F1->GetNode(2)==F2->GetNode(2) );
+  }
+  //================================================================================
+  /*!
+   * \brief Return true if two adjacent pyramids are too close one to another
+   * so that a tetrahedron to built between them would have too poor quality
+   */
+  //================================================================================
+
+  bool TooCloseAdjacent( const SMDS_MeshElement* PrmI,
+                         const SMDS_MeshElement* PrmJ,
+                         const bool              hasShape)
+  {
+    const SMDS_MeshNode* nApexI = PrmI->GetNode(4);
+    const SMDS_MeshNode* nApexJ = PrmJ->GetNode(4);
+    if ( nApexI == nApexJ ||
+         nApexI->getshapeId() != nApexJ->getshapeId() )
+      return false;
+
+    // Find two common base nodes and their indices within PrmI and PrmJ
+    const SMDS_MeshNode* baseNodes[2] = { 0,0 };
+    int baseNodesIndI[2], baseNodesIndJ[2];
+    for ( int i = 0; i < 4 ; ++i )
+    {
+      int j = PrmJ->GetNodeIndex( PrmI->GetNode(i));
+      if ( j >= 0 )
+      {
+        int ind = baseNodes[0] ? 1:0;
+        if ( baseNodes[ ind ])
+          return false; // pyramids with a common base face
+        baseNodes    [ ind ] = PrmI->GetNode(i);
+        baseNodesIndI[ ind ] = i;
+        baseNodesIndJ[ ind ] = j;
+      }
+    }
+    if ( !baseNodes[1] ) return false; // not adjacent
+
+    // Get normals of triangles sharing baseNodes
+    gp_XYZ apexI = SMESH_TNodeXYZ( nApexI );
+    gp_XYZ apexJ = SMESH_TNodeXYZ( nApexJ );
+    gp_XYZ base1 = SMESH_TNodeXYZ( baseNodes[0]);
+    gp_XYZ base2 = SMESH_TNodeXYZ( baseNodes[1]);
+    gp_Vec baseVec( base1, base2 );
+    gp_Vec baI( base1, apexI );
+    gp_Vec baJ( base1, apexJ );
+    gp_Vec nI = baseVec.Crossed( baI );
+    gp_Vec nJ = baseVec.Crossed( baJ );
+
+    // Check angle between normals
+    double angle = nI.Angle( nJ );
+    bool tooClose = ( angle < 15. * M_PI / 180. );
+
+    // Check if pyramids collide
+    if ( !tooClose && baI * baJ > 0 )
+    {
+      // find out if nI points outside of PrmI or inside
+      int dInd = baseNodesIndI[1] - baseNodesIndI[0];
+      bool isOutI = ( abs(dInd)==1 ) ? dInd < 0 : dInd > 0;
+
+      // find out sign of projection of nJ to baI
+      double proj = baI * nJ;
+
+      tooClose = isOutI ? proj > 0 : proj < 0;
+    }
+
+    // Check if PrmI and PrmJ are in same domain
+    if ( tooClose && !hasShape )
+    {
+      // check order of baseNodes within pyramids, it must be opposite
+      int dInd;
+      dInd = baseNodesIndI[1] - baseNodesIndI[0];
+      bool isOutI = ( abs(dInd)==1 ) ? dInd < 0 : dInd > 0;
+      dInd = baseNodesIndJ[1] - baseNodesIndJ[0];
+      bool isOutJ = ( abs(dInd)==1 ) ? dInd < 0 : dInd > 0;
+      if ( isOutJ == isOutI )
+        return false; // other domain
+
+      // direct both normals outside pyramid
+      ( isOutI ? nJ : nI ).Reverse();
+
+      // check absence of a face separating domains between pyramids
+      TIDSortedElemSet emptySet, avoidSet;
+      int i1, i2;
+      while ( const SMDS_MeshElement* f =
+              SMESH_MeshEditor::FindFaceInSet( baseNodes[0], baseNodes[1],
+                                               emptySet, avoidSet, &i1, &i2 ))
+      {
+        avoidSet.insert( f );
+
+        // face node other than baseNodes
+        int otherNodeInd = 0;
+        while ( otherNodeInd == i1 || otherNodeInd == i2 ) otherNodeInd++;
+        const SMDS_MeshNode* otherFaceNode = f->GetNode( otherNodeInd );
+
+        if ( otherFaceNode == nApexI || otherFaceNode == nApexJ )
+          continue; // f is a temporary triangle
+
+        // check if f is a base face of either of pyramids
+        if ( f->NbCornerNodes() == 4 &&
+             ( PrmI->GetNodeIndex( otherFaceNode ) >= 0 ||
+               PrmJ->GetNodeIndex( otherFaceNode ) >= 0 ))
+          continue; // f is a base quadrangle
+
+        // check projections of face direction (baOFN) to triange normals (nI and nJ)
+        gp_Vec baOFN( base1, SMESH_TNodeXYZ( otherFaceNode ));
+        if ( nI * baOFN > 0 && nJ * baOFN > 0 )
+        {
+          tooClose = false; // f is between pyramids
+          break;
+        }
+      }
+    }
+
+    return tooClose;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Move medium nodes of merged quadratic pyramids
+   */
+  //================================================================================
+
+  void UpdateQuadraticPyramids(const set<const SMDS_MeshNode*>& commonApex,
+                               SMESHDS_Mesh*                    meshDS)
+  {
+    typedef SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > TStdElemIterator;
+    TStdElemIterator itEnd;
+
+    // shift of node index to get medium nodes between the 4 base nodes and the apex
+    const int base2MediumShift = 9;
+
+    set<const SMDS_MeshNode*>::const_iterator nIt = commonApex.begin();
+    for ( ; nIt != commonApex.end(); ++nIt )
+    {
+      SMESH_TNodeXYZ apex( *nIt );
+
+      vector< const SMDS_MeshElement* > pyrams // pyramids sharing the apex node
+        ( TStdElemIterator( apex._node->GetInverseElementIterator( SMDSAbs_Volume )), itEnd );
+
+      // Select medium nodes to keep and medium nodes to remove
+
+      typedef map < const SMDS_MeshNode*, const SMDS_MeshNode*, TIDCompare > TN2NMap;
+      TN2NMap base2medium; // to keep
+      vector< const SMDS_MeshNode* > nodesToRemove;
+
+      for ( unsigned i = 0; i < pyrams.size(); ++i )
+        for ( int baseIndex = 0; baseIndex < PYRAM_APEX; ++baseIndex )
+        {
+          SMESH_TNodeXYZ         base = pyrams[i]->GetNode( baseIndex );
+          const SMDS_MeshNode* medium = pyrams[i]->GetNode( baseIndex + base2MediumShift );
+          TN2NMap::iterator b2m = base2medium.insert( make_pair( base._node, medium )).first;
+          if ( b2m->second != medium )
+          {
+            nodesToRemove.push_back( medium );
+          }
+          else
+          {
+            // move the kept medium node
+            gp_XYZ newXYZ = 0.5 * ( apex + base );
+            meshDS->MoveNode( medium, newXYZ.X(), newXYZ.Y(), newXYZ.Z() );
+          }
+        }
+
+      // Within pyramids, replace nodes to remove by nodes to keep  
+
+      for ( unsigned i = 0; i < pyrams.size(); ++i )
+      {
+        vector< const SMDS_MeshNode* > nodes( pyrams[i]->begin_nodes(),
+                                              pyrams[i]->end_nodes() );
+        for ( int baseIndex = 0; baseIndex < PYRAM_APEX; ++baseIndex )
+        {
+          const SMDS_MeshNode* base = pyrams[i]->GetNode( baseIndex );
+          nodes[ baseIndex + base2MediumShift ] = base2medium[ base ];
+        }
+        meshDS->ChangeElementNodes( pyrams[i], &nodes[0], nodes.size());
+      }
+
+      // Remove the replaced nodes
+
+      if ( !nodesToRemove.empty() )
+      {
+        SMESHDS_SubMesh * sm = meshDS->MeshElements( nodesToRemove[0]->getshapeId() );
+        for ( unsigned i = 0; i < nodesToRemove.size(); ++i )
+          meshDS->RemoveFreeNode( nodesToRemove[i], sm, /*fromGroups=*/false);
+      }
+    }
+  }
+
 }
 
+//================================================================================
+/*!
+ * \brief Merge the two pyramids (i.e. fuse their apex) and others already merged with them
+ */
+//================================================================================
+
+void StdMeshers_QuadToTriaAdaptor::MergePiramids( const SMDS_MeshElement*     PrmI,
+                                                  const SMDS_MeshElement*     PrmJ,
+                                                  set<const SMDS_MeshNode*> & nodesToMove)
+{
+  const SMDS_MeshNode* Nrem = PrmJ->GetNode(4); // node to remove
+  //int nbJ = Nrem->NbInverseElements( SMDSAbs_Volume );
+  SMESH_TNodeXYZ Pj( Nrem );
+
+  // an apex node to make common to all merged pyramids
+  SMDS_MeshNode* CommonNode = const_cast<SMDS_MeshNode*>(PrmI->GetNode(4));
+  if ( CommonNode == Nrem ) return; // already merged
+  //int nbI = CommonNode->NbInverseElements( SMDSAbs_Volume );
+  SMESH_TNodeXYZ Pi( CommonNode );
+  gp_XYZ Pnew = /*( nbI*Pi + nbJ*Pj ) / (nbI+nbJ);*/ 0.5 * ( Pi + Pj );
+  CommonNode->setXYZ( Pnew.X(), Pnew.Y(), Pnew.Z() );
+
+  nodesToMove.insert( CommonNode );
+  nodesToMove.erase ( Nrem );
+
+  typedef SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > TStdElemIterator;
+  TStdElemIterator itEnd;
+
+  // find and remove coincided faces of merged pyramids
+  vector< const SMDS_MeshElement* > inverseElems
+    // copy inverse elements to avoid iteration on changing container 
+    ( TStdElemIterator( CommonNode->GetInverseElementIterator(SMDSAbs_Face)), itEnd);
+  for ( unsigned i = 0; i < inverseElems.size(); ++i )
+  {
+    const SMDS_MeshElement* FI = inverseElems[i];
+    const SMDS_MeshElement* FJEqual = 0;
+    SMDS_ElemIteratorPtr triItJ = Nrem->GetInverseElementIterator(SMDSAbs_Face);
+    while ( !FJEqual && triItJ->more() )
+    {
+      const SMDS_MeshElement* FJ = triItJ->next();
+      if ( EqualTriangles( FJ, FI ))
+        FJEqual = FJ;
+    }
+    if ( FJEqual )
+    {
+      removeTmpElement( FI );
+      removeTmpElement( FJEqual );
+      myRemovedTrias.insert( FI );
+      myRemovedTrias.insert( FJEqual );
+    }
+  }
+
+  // set the common apex node to pyramids and triangles merged with J
+  inverseElems.assign( TStdElemIterator( Nrem->GetInverseElementIterator()), itEnd );
+  for ( unsigned i = 0; i < inverseElems.size(); ++i )
+  {
+    const SMDS_MeshElement* elem = inverseElems[i];
+    vector< const SMDS_MeshNode* > nodes( elem->begin_nodes(), elem->end_nodes() );
+    nodes[ elem->GetType() == SMDSAbs_Volume ? PYRAM_APEX : TRIA_APEX ] = CommonNode;
+    GetMeshDS()->ChangeElementNodes( elem, &nodes[0], nodes.size());
+  }
+  ASSERT( Nrem->NbInverseElements() == 0 );
+  GetMeshDS()->RemoveFreeNode( Nrem,
+                               GetMeshDS()->MeshElements( Nrem->getshapeId()),
+                               /*fromGroups=*/false);
+}
+
+//================================================================================
+/*!
+ * \brief Merges adjacent pyramids
+ */
+//================================================================================
+
+void StdMeshers_QuadToTriaAdaptor::MergeAdjacent(const SMDS_MeshElement*    PrmI,
+                                                 set<const SMDS_MeshNode*>& nodesToMove)
+{
+  TIDSortedElemSet adjacentPyrams;
+  bool mergedPyrams = false;
+  for(int k=0; k<4; k++) // loop on 4 base nodes of PrmI
+  {
+    const SMDS_MeshNode* n = PrmI->GetNode(k);
+    SMDS_ElemIteratorPtr vIt = n->GetInverseElementIterator( SMDSAbs_Volume );
+    while ( vIt->more() )
+    {
+      const SMDS_MeshElement* PrmJ = vIt->next();
+      if ( PrmJ->NbCornerNodes() != 5 || !adjacentPyrams.insert( PrmJ ).second  )
+        continue;
+      if ( PrmI != PrmJ && TooCloseAdjacent( PrmI, PrmJ, GetMesh()->HasShapeToMesh() ))
+      {
+        MergePiramids( PrmI, PrmJ, nodesToMove );
+        mergedPyrams = true;
+        // container of inverse elements can change
+        vIt = n->GetInverseElementIterator( SMDSAbs_Volume );
+      }
+    }
+  }
+  if ( mergedPyrams )
+  {
+    TIDSortedElemSet::iterator prm;
+    for (prm = adjacentPyrams.begin(); prm != adjacentPyrams.end(); ++prm)
+      MergeAdjacent( *prm, nodesToMove );
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Constructor
+ */
+//================================================================================
+
+StdMeshers_QuadToTriaAdaptor::StdMeshers_QuadToTriaAdaptor():
+  myElemSearcher(0)
+{
+}
 
 //================================================================================
 /*!
@@ -62,39 +373,47 @@ StdMeshers_QuadToTriaAdaptor::StdMeshers_QuadToTriaAdaptor()
 //================================================================================
 
 StdMeshers_QuadToTriaAdaptor::~StdMeshers_QuadToTriaAdaptor()
-{}
-
+{
+  // temporary faces are deleted by ~SMESH_ProxyMesh()
+  if ( myElemSearcher ) delete myElemSearcher;
+  myElemSearcher=0;
+}
 
 //=======================================================================
 //function : FindBestPoint
-//purpose  : Auxilare for Compute()
+//purpose  : Return a point P laying on the line (PC,V) so that triangle
+//           (P, P1, P2) to be equilateral as much as possible
 //           V - normal to (P1,P2,PC)
 //=======================================================================
+
 static gp_Pnt FindBestPoint(const gp_Pnt& P1, const gp_Pnt& P2,
                             const gp_Pnt& PC, const gp_Vec& V)
 {
-  double a = P1.Distance(P2);
-  double b = P1.Distance(PC);
-  double c = P2.Distance(PC);
+  gp_Pnt Pbest = PC;
+  const double a = P1.Distance(P2);
+  const double b = P1.Distance(PC);
+  const double c = P2.Distance(PC);
   if( a < (b+c)/2 )
-    return PC;
-  else {
-    // find shift along V in order to a became equal to (b+c)/2
-    double shift = sqrt( a*a + (b*b-c*c)*(b*b-c*c)/16/a/a - (b*b+c*c)/2 );
-    gp_Dir aDir(V);
-    gp_Pnt Pbest( PC.X() + aDir.X()*shift,  PC.Y() + aDir.Y()*shift,
-                  PC.Z() + aDir.Z()*shift );
     return Pbest;
+  else {
+    // find shift along V in order a to became equal to (b+c)/2
+    const double Vsize = V.Magnitude();
+    if ( fabs( Vsize ) > std::numeric_limits<double>::min() )
+    {
+      const double shift = sqrt( a*a + (b*b-c*c)*(b*b-c*c)/16/a/a - (b*b+c*c)/2 );
+      Pbest.ChangeCoord() += shift * V.XYZ() / Vsize;
+    }
   }
+  return Pbest;
 }
 
-
 //=======================================================================
 //function : HasIntersection3
 //purpose  : Auxilare for HasIntersection()
 //           find intersection point between triangle (P1,P2,P3)
 //           and segment [PC,P]
 //=======================================================================
+
 static bool HasIntersection3(const gp_Pnt& P, const gp_Pnt& PC, gp_Pnt& Pint,
                              const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& P3)
 {
@@ -113,7 +432,7 @@ static bool HasIntersection3(const gp_Pnt& P, const gp_Pnt& PC, gp_Pnt& Pint,
       return false;
     if( IAICQ.NbPoints() == 1 ) {
       gp_Pnt PIn = IAICQ.Point(1);
-      double preci = 1.e-6;
+      const double preci = 1.e-10 * P.Distance(PC);
       // check if this point is internal for segment [PC,P]
       bool IsExternal =
         ( (PC.X()-PIn.X())*(P.X()-PIn.X()) > preci ) ||
@@ -126,32 +445,34 @@ static bool HasIntersection3(const gp_Pnt& P, const gp_Pnt& PC, gp_Pnt& Pint,
       gp_Vec V1(PIn,P1);
       gp_Vec V2(PIn,P2);
       gp_Vec V3(PIn,P3);
-      if( V1.Magnitude()<preci || V2.Magnitude()<preci ||
+      if( V1.Magnitude()<preci ||
+          V2.Magnitude()<preci ||
           V3.Magnitude()<preci ) {
         Pint = PIn;
         return true;
       }
+      const double angularTol = 1e-6;
       gp_Vec VC1 = V1.Crossed(V2);
       gp_Vec VC2 = V2.Crossed(V3);
       gp_Vec VC3 = V3.Crossed(V1);
-      if(VC1.Magnitude()<preci) {
-        if(VC2.IsOpposite(VC3,preci)) {
+      if(VC1.Magnitude()<gp::Resolution()) {
+        if(VC2.IsOpposite(VC3,angularTol)) {
           return false;
         }
       }
-      else if(VC2.Magnitude()<preci) {
-        if(VC1.IsOpposite(VC3,preci)) {
+      else if(VC2.Magnitude()<gp::Resolution()) {
+        if(VC1.IsOpposite(VC3,angularTol)) {
           return false;
         }
       }
-      else if(VC3.Magnitude()<preci) {
-        if(VC1.IsOpposite(VC2,preci)) {
+      else if(VC3.Magnitude()<gp::Resolution()) {
+        if(VC1.IsOpposite(VC2,angularTol)) {
           return false;
         }
       }
       else {
-        if( VC1.IsOpposite(VC2,preci) || VC1.IsOpposite(VC3,preci) ||
-            VC2.IsOpposite(VC3,preci) ) {
+        if( VC1.IsOpposite(VC2,angularTol) || VC1.IsOpposite(VC3,angularTol) ||
+            VC2.IsOpposite(VC3,angularTol) ) {
           return false;
         }
       }
@@ -163,11 +484,11 @@ static bool HasIntersection3(const gp_Pnt& P, const gp_Pnt& PC, gp_Pnt& Pint,
   return false;
 }
 
-
 //=======================================================================
 //function : HasIntersection
 //purpose  : Auxilare for CheckIntersection()
 //=======================================================================
+
 static bool HasIntersection(const gp_Pnt& P, const gp_Pnt& PC, gp_Pnt& Pint,
                             Handle(TColgp_HSequenceOfPnt)& aContour)
 {
@@ -196,152 +517,96 @@ static bool HasIntersection(const gp_Pnt& P, const gp_Pnt& PC, gp_Pnt& Pint,
   return false;
 }
 
+//================================================================================
+/*!
+ * \brief Checks if a line segment (P,PC) intersects any mesh face.
+ *  \param P - first segment end
+ *  \param PC - second segment end (it is a gravity center of quadrangle)
+ *  \param Pint - (out) intersection point
+ *  \param aMesh - mesh
+ *  \param aShape - shape to check faces on
+ *  \param NotCheckedFace - mesh face not to check
+ *  \retval bool - true if there is an intersection
+ */
+//================================================================================
 
-//=======================================================================
-//function : CheckIntersection
-//purpose  : Auxilare for Compute()
-//           NotCheckedFace - for optimization
-//=======================================================================
-bool StdMeshers_QuadToTriaAdaptor::CheckIntersection
-                       (const gp_Pnt& P, const gp_Pnt& PC,
-                        gp_Pnt& Pint, SMESH_Mesh& aMesh,
-                        const TopoDS_Shape& aShape,
-                        const TopoDS_Shape& NotCheckedFace)
+bool StdMeshers_QuadToTriaAdaptor::CheckIntersection (const gp_Pnt&       P,
+                                                      const gp_Pnt&       PC,
+                                                      gp_Pnt&             Pint,
+                                                      SMESH_Mesh&         aMesh,
+                                                      const TopoDS_Shape& aShape,
+                                                      const SMDS_MeshElement* NotCheckedFace)
 {
-  SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
+  if ( !myElemSearcher )
+    myElemSearcher = SMESH_MeshEditor(&aMesh).GetElementSearcher();
+  SMESH_ElementSearcher* searcher = const_cast<SMESH_ElementSearcher*>(myElemSearcher);
+
+  //SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
   //cout<<"    CheckIntersection: meshDS->NbFaces() = "<<meshDS->NbFaces()<<endl;
   bool res = false;
-  double dist = RealLast();
+  double dist = RealLast(); // find intersection closest to the segment
   gp_Pnt Pres;
-  for (TopExp_Explorer exp(aShape,TopAbs_FACE);exp.More();exp.Next()) {
-    const TopoDS_Shape& aShapeFace = exp.Current();
-    if(aShapeFace==NotCheckedFace)
-      continue;
-    const SMESHDS_SubMesh * aSubMeshDSFace = meshDS->MeshElements(aShapeFace);
-    if ( aSubMeshDSFace ) {
-      SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements();
-      while ( iteratorElem->more() ) { // loop on elements on a face
-        const SMDS_MeshElement* face = iteratorElem->next();
-        Handle(TColgp_HSequenceOfPnt) aContour = new TColgp_HSequenceOfPnt;
-        SMDS_ElemIteratorPtr nodeIt = face->nodesIterator();
-        if( !face->IsQuadratic() ) {
-          while ( nodeIt->more() ) {
-            const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-            aContour->Append(gp_Pnt(node->X(), node->Y(), node->Z()));
-          }
-        }
-        else {
-          int nn = 0;
-          while ( nodeIt->more() ) {
-            nn++;
-            const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-            aContour->Append(gp_Pnt(node->X(), node->Y(), node->Z()));
-            if(nn==face->NbNodes()/2) break;
-          }
-        }
-        if( HasIntersection(P, PC, Pres, aContour) ) {
-          res = true;
-          double tmp = PC.Distance(Pres);
-          if(tmp<dist) {
-            Pint = Pres;
-            dist = tmp;
-          }
-        }
+
+  gp_Ax1 line( P, gp_Vec(P,PC));
+  vector< const SMDS_MeshElement* > suspectElems;
+  searcher->GetElementsNearLine( line, SMDSAbs_Face, suspectElems);
+  
+  for ( int i = 0; i < suspectElems.size(); ++i )
+  {
+    const SMDS_MeshElement* face = suspectElems[i];
+    if ( face == NotCheckedFace ) continue;
+    Handle(TColgp_HSequenceOfPnt) aContour = new TColgp_HSequenceOfPnt;
+    for ( int i = 0; i < face->NbCornerNodes(); ++i ) 
+      aContour->Append( SMESH_TNodeXYZ( face->GetNode(i) ));
+    if( HasIntersection(P, PC, Pres, aContour) ) {
+      res = true;
+      double tmp = PC.Distance(Pres);
+      if(tmp<dist) {
+        Pint = Pres;
+        dist = tmp;
       }
     }
   }
   return res;
 }
 
+//================================================================================
+/*!
+ * \brief Prepare data for the given face
+ *  \param PN - coordinates of face nodes
+ *  \param VN - cross products of vectors (PC-PN(i)) ^ (PC-PN(i+1))
+ *  \param FNodes - face nodes
+ *  \param PC - gravity center of nodes
+ *  \param VNorm - face normal (sum of VN)
+ *  \param volumes - two volumes sharing the given face, the first is in VNorm direction
+ *  \retval int - 0 if given face is not quad,
+ *                1 if given face is quad,
+ *                2 if given face is degenerate quad (two nodes are coincided)
+ */
+//================================================================================
 
-//=======================================================================
-//function : CompareTrias
-//purpose  : Auxilare for Compute()
-//=======================================================================
-static bool CompareTrias(const SMDS_MeshElement* F1,const SMDS_MeshElement* F2)
-{
-  SMDS_ElemIteratorPtr nIt = F1->nodesIterator();
-  const SMDS_MeshNode* Ns1[3];
-  int k = 0;
-  while( nIt->more() ) {
-    Ns1[k] = static_cast<const SMDS_MeshNode*>( nIt->next() );
-    k++;
-  }
-  nIt = F2->nodesIterator();
-  const SMDS_MeshNode* Ns2[3];
-  k = 0;
-  while( nIt->more() ) {
-    Ns2[k] = static_cast<const SMDS_MeshNode*>( nIt->next() );
-    k++;
-  }
-  if( ( Ns1[1]==Ns2[1] && Ns1[2]==Ns2[2] ) ||
-      ( Ns1[1]==Ns2[2] && Ns1[2]==Ns2[1] ) )
-    return true;
-  return false;
-}
-
-
-//=======================================================================
-//function : IsDegenarate
-//purpose  : Auxilare for Preparation()
-//=======================================================================
-static int IsDegenarate(const Handle(TColgp_HArray1OfPnt)& PN)
+int StdMeshers_QuadToTriaAdaptor::Preparation(const SMDS_MeshElement*       face,
+                                              Handle(TColgp_HArray1OfPnt)&  PN,
+                                              Handle(TColgp_HArray1OfVec)&  VN,
+                                              vector<const SMDS_MeshNode*>& FNodes,
+                                              gp_Pnt&                       PC,
+                                              gp_Vec&                       VNorm,
+                                              const SMDS_MeshElement**      volumes)
 {
-  int i = 1;
-  for(; i<4; i++) {
-    int j = i+1;
-    for(; j<=4; j++) {
-      if( PN->Value(i).Distance(PN->Value(j)) < 1.e-6 )
-        return j;
-    }
+  if( face->NbCornerNodes() != 4 )
+  {
+    return NOT_QUAD;
   }
-  return 0;
-}
-
 
-//=======================================================================
-//function : Preparation
-//purpose  : Auxilare for Compute()
-//         : Return 0 if given face is not quad,
-//                  1 if given face is quad,
-//                  2 if given face is degenerate quad (two nodes are coincided)
-//=======================================================================
-int StdMeshers_QuadToTriaAdaptor::Preparation(const SMDS_MeshElement* face,
-                                              Handle(TColgp_HArray1OfPnt) PN,
-                                              Handle(TColgp_HArray1OfVec) VN,
-                                              std::vector<const SMDS_MeshNode*>& FNodes,
-                                              gp_Pnt& PC, gp_Vec& VNorm)
-{
   int i = 0;
-  double xc=0., yc=0., zc=0.;
-  SMDS_ElemIteratorPtr nodeIt = face->nodesIterator();
-  if( !face->IsQuadratic() ) {
-    if( face->NbNodes() != 4 )
-      return 0;
-    while ( nodeIt->more() ) {
-      i++;
-      const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-      FNodes[i-1] = node;
-      PN->SetValue( i, gp_Pnt(node->X(), node->Y(), node->Z()) );
-      xc += node->X();
-      yc += node->Y();
-      zc += node->Z();
-    }
-  }
-  else {
-    if( face->NbNodes() != 8)
-      return 0;
-    while ( nodeIt->more() ) {
-      i++;
-      const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-      FNodes[i-1] = node;
-      PN->SetValue( i, gp_Pnt(node->X(), node->Y(), node->Z()) );
-      xc += node->X();
-      yc += node->Y();
-      zc += node->Z();
-      if(i==4) break;
-    }
+  gp_XYZ xyzC(0., 0., 0.);
+  for ( i = 0; i < 4; ++i )
+  {
+    gp_XYZ p = SMESH_TNodeXYZ( FNodes[i] = face->GetNode(i) );
+    PN->SetValue( i+1, p );
+    xyzC += p;
   }
+  PC = xyzC/4;
 
   int nbp = 4;
 
@@ -362,7 +627,7 @@ int StdMeshers_QuadToTriaAdaptor::Preparation(const SMDS_MeshElement* face,
     hasdeg = true;
     gp_Pnt Pdeg = PN->Value(i);
 
-    std::list< const SMDS_MeshNode* >::iterator itdg = myDegNodes.begin();
+    list< const SMDS_MeshNode* >::iterator itdg = myDegNodes.begin();
     const SMDS_MeshNode* DegNode = 0;
     for(; itdg!=myDegNodes.end(); itdg++) {
       const SMDS_MeshNode* N = (*itdg);
@@ -385,24 +650,15 @@ int StdMeshers_QuadToTriaAdaptor::Preparation(const SMDS_MeshElement* face,
       FNodes[i-1] = FNodes[i];
     }
     nbp = 3;
-    //PC = gp_Pnt( PN->Value(1).X() + PN.Value
   }
 
-  PC = gp_Pnt(xc/4., yc/4., zc/4.);
-  //cout<<"  PC("<<PC.X()<<","<<PC.Y()<<","<<PC.Z()<<")"<<endl;
-
-  //PN->SetValue(5,PN->Value(1));
   PN->SetValue(nbp+1,PN->Value(1));
-  //FNodes[4] = FNodes[0];
   FNodes[nbp] = FNodes[0];
   // find normal direction
-  //gp_Vec V1(PC,PN->Value(4));
   gp_Vec V1(PC,PN->Value(nbp));
   gp_Vec V2(PC,PN->Value(1));
   VNorm = V1.Crossed(V2);
-  //VN->SetValue(4,VNorm);
   VN->SetValue(nbp,VNorm);
-  //for(i=1; i<4; i++) {
   for(i=1; i<nbp; i++) {
     V1 = gp_Vec(PC,PN->Value(i));
     V2 = gp_Vec(PC,PN->Value(i+1));
@@ -410,9 +666,37 @@ int StdMeshers_QuadToTriaAdaptor::Preparation(const SMDS_MeshElement* face,
     VN->SetValue(i,Vtmp);
     VNorm += Vtmp;
   }
+
+  // find volumes sharing the face
+  if ( volumes )
+  {
+    volumes[0] = volumes[1] = 0;
+    SMDS_ElemIteratorPtr vIt = FNodes[0]->GetInverseElementIterator( SMDSAbs_Volume );
+    while ( vIt->more() )
+    {
+      const SMDS_MeshElement* vol = vIt->next();
+      bool volSharesAllNodes = true;
+      for ( int i = 1; i < face->NbNodes() && volSharesAllNodes; ++i )
+        volSharesAllNodes = ( vol->GetNodeIndex( FNodes[i] ) >= 0 );
+      if ( volSharesAllNodes )
+        volumes[ volumes[0] ? 1 : 0 ] = vol;
+      // we could additionally check that vol has all FNodes in its one face using SMDS_VolumeTool
+    }
+    // define volume position relating to the face normal
+    if ( volumes[0] )
+    {
+      // get volume gc
+      SMDS_ElemIteratorPtr nodeIt = volumes[0]->nodesIterator();
+      gp_XYZ volGC(0,0,0);
+      volGC = accumulate( TXyzIterator(nodeIt), TXyzIterator(), volGC ) / volumes[0]->NbNodes();
+
+      if ( VNorm * gp_Vec( PC, volGC ) < 0 )
+        swap( volumes[0], volumes[1] );
+    }
+  }
+
   //cout<<"  VNorm("<<VNorm.X()<<","<<VNorm.Y()<<","<<VNorm.Z()<<")"<<endl;
-  if(hasdeg) return 2;
-  return 1;
+  return hasdeg ? DEGEN_QUAD : QUAD;
 }
 
 
@@ -421,164 +705,240 @@ int StdMeshers_QuadToTriaAdaptor::Preparation(const SMDS_MeshElement* face,
 //purpose  : 
 //=======================================================================
 
-bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape)
+bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh&         aMesh,
+                                           const TopoDS_Shape& aShape,
+                                           SMESH_ProxyMesh*    aProxyMesh)
 {
-  myResMap.clear();
-  myMapFPyram.clear();
+  SMESH_ProxyMesh::setMesh( aMesh );
 
-  SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
+  if ( aShape.ShapeType() != TopAbs_SOLID &&
+       aShape.ShapeType() != TopAbs_SHELL )
+    return false;
+
+  myShape = aShape;
 
-  for (TopExp_Explorer exp(aShape,TopAbs_FACE);exp.More();exp.Next()) {
+  vector<const SMDS_MeshElement*> myPyramids;
+
+  SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
+  SMESH_MesherHelper helper(aMesh);
+  helper.IsQuadraticSubMesh(aShape);
+  helper.SetElementsOnShape( true );
+
+  if ( myElemSearcher ) delete myElemSearcher;
+  if ( aProxyMesh )
+    myElemSearcher = SMESH_MeshEditor(&aMesh).GetElementSearcher( aProxyMesh->GetFaces(aShape));
+  else
+    myElemSearcher = SMESH_MeshEditor(&aMesh).GetElementSearcher();
+
+  const SMESHDS_SubMesh * aSubMeshDSFace;
+  Handle(TColgp_HArray1OfPnt) PN = new TColgp_HArray1OfPnt(1,5);
+  Handle(TColgp_HArray1OfVec) VN = new TColgp_HArray1OfVec(1,4);
+  vector<const SMDS_MeshNode*> FNodes(5);
+  gp_Pnt PC;
+  gp_Vec VNorm;
+
+  for (TopExp_Explorer exp(aShape,TopAbs_FACE);exp.More();exp.Next())
+  {
     const TopoDS_Shape& aShapeFace = exp.Current();
-    const SMESHDS_SubMesh * aSubMeshDSFace = meshDS->MeshElements( aShapeFace );
-    if ( aSubMeshDSFace ) {
-      bool isRev = SMESH_Algo::IsReversedSubMesh( TopoDS::Face(aShapeFace), meshDS );
+    if ( aProxyMesh )
+      aSubMeshDSFace = aProxyMesh->GetSubMesh( aShapeFace );
+    else
+      aSubMeshDSFace = meshDS->MeshElements( aShapeFace );
+
+    vector<const SMDS_MeshElement*> trias, quads;
+    bool hasNewTrias = false;
+
+    if ( aSubMeshDSFace )
+    {
+      bool isRev = false;
+      if ( helper.NbAncestors( aShapeFace, aMesh, aShape.ShapeType() ) > 1 )
+        isRev = SMESH_Algo::IsReversedSubMesh( TopoDS::Face(aShapeFace), meshDS );
 
       SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements();
-      while ( iteratorElem->more() ) { // loop on elements on a face
+      while ( iteratorElem->more() ) // loop on elements on a geometrical face
+      {
         const SMDS_MeshElement* face = iteratorElem->next();
-        //cout<<endl<<"================= face->GetID() = "<<face->GetID()<<endl;
-        // preparation step using face info
-        Handle(TColgp_HArray1OfPnt) PN = new TColgp_HArray1OfPnt(1,5);
-        Handle(TColgp_HArray1OfVec) VN = new TColgp_HArray1OfVec(1,4);
-        std::vector<const SMDS_MeshNode*> FNodes(5);
-        gp_Pnt PC;
-        gp_Vec VNorm;
-        int stat =  Preparation(face, PN, VN, FNodes, PC, VNorm);
-        if(stat==0)
-          continue;
+        // preparation step to get face info
+        int stat = Preparation(face, PN, VN, FNodes, PC, VNorm);
+        switch ( stat )
+        {
+        case NOT_QUAD:
 
-        if(stat==2) {
-          // degenerate face
-          // add triangles to result map
-          std::list<const SMDS_FaceOfNodes*> aList;
-          SMDS_FaceOfNodes* NewFace;
-          if(!isRev)
-            NewFace = new SMDS_FaceOfNodes( FNodes[0], FNodes[1], FNodes[2] );
-          else
-            NewFace = new SMDS_FaceOfNodes( FNodes[0], FNodes[2], FNodes[1] );
-          aList.push_back(NewFace);
-          myResMap.insert(make_pair(face,aList));
-          continue;
-        }
+          trias.push_back( face );
+          break;
 
-        if(!isRev) VNorm.Reverse();
-        double xc = 0., yc = 0., zc = 0.;
-        int i = 1;
-        for(; i<=4; i++) {
-          gp_Pnt Pbest;
-          if(!isRev)
-            Pbest = FindBestPoint(PN->Value(i), PN->Value(i+1), PC, VN->Value(i).Reversed());
-          else
-            Pbest = FindBestPoint(PN->Value(i), PN->Value(i+1), PC, VN->Value(i));
-          xc += Pbest.X();
-          yc += Pbest.Y();
-          zc += Pbest.Z();
-        }
-        gp_Pnt PCbest(xc/4., yc/4., zc/4.);
-
-        // check PCbest
-        double height = PCbest.Distance(PC);
-        if(height<1.e-6) {
-          // create new PCbest using a bit shift along VNorm
-          PCbest = gp_Pnt( PC.X() + VNorm.X()*0.001,
-                           PC.Y() + VNorm.Y()*0.001,
-                           PC.Z() + VNorm.Z()*0.001);
-        }
-        else {
-          // check possible intersection with other faces
-          gp_Pnt Pint;
-          bool check = CheckIntersection(PCbest, PC, Pint, aMesh, aShape, aShapeFace);
-          if(check) {
-            //cout<<"--PC("<<PC.X()<<","<<PC.Y()<<","<<PC.Z()<<")"<<endl;
-            //cout<<"  PCbest("<<PCbest.X()<<","<<PCbest.Y()<<","<<PCbest.Z()<<")"<<endl;
-            double dist = PC.Distance(Pint)/3.;
-            gp_Dir aDir(gp_Vec(PC,PCbest));
-            PCbest = gp_Pnt( PC.X() + aDir.X()*dist,
-                             PC.Y() + aDir.Y()*dist,
-                             PC.Z() + aDir.Z()*dist );
+        case DEGEN_QUAD:
+          {
+            // degenerate face
+            // add triangles to result map
+            SMDS_MeshFace* NewFace;
+            if(!isRev)
+              NewFace = meshDS->AddFace( FNodes[0], FNodes[1], FNodes[2] );
+            else
+              NewFace = meshDS->AddFace( FNodes[0], FNodes[2], FNodes[1] );
+            storeTmpElement( NewFace );
+            trias.push_back ( NewFace );
+            quads.push_back( face );
+            hasNewTrias = true;
+            break;
           }
-          else {
-            gp_Vec VB(PC,PCbest);
-            gp_Pnt PCbestTmp(PC.X()+VB.X()*3, PC.X()+VB.X()*3, PC.X()+VB.X()*3);
-            bool check = CheckIntersection(PCbestTmp, PC, Pint, aMesh, aShape, aShapeFace);
-            if(check) {
-              double dist = PC.Distance(Pint)/3.;
-              if(dist<height) {
+
+        case QUAD:
+          {
+            if(!isRev) VNorm.Reverse();
+            double xc = 0., yc = 0., zc = 0.;
+            int i = 1;
+            for(; i<=4; i++) {
+              gp_Pnt Pbest;
+              if(!isRev)
+                Pbest = FindBestPoint(PN->Value(i), PN->Value(i+1), PC, VN->Value(i).Reversed());
+              else
+                Pbest = FindBestPoint(PN->Value(i), PN->Value(i+1), PC, VN->Value(i));
+              xc += Pbest.X();
+              yc += Pbest.Y();
+              zc += Pbest.Z();
+            }
+            gp_Pnt PCbest(xc/4., yc/4., zc/4.);
+
+            // check PCbest
+            double height = PCbest.Distance(PC);
+            if(height<1.e-6) {
+              // create new PCbest using a bit shift along VNorm
+              PCbest = PC.XYZ() + VNorm.XYZ() * 0.001;
+            }
+            else {
+              // check possible intersection with other faces
+              gp_Pnt Pint;
+              bool check = CheckIntersection(PCbest, PC, Pint, aMesh, aShape, face);
+              if(check) {
+                //cout<<"--PC("<<PC.X()<<","<<PC.Y()<<","<<PC.Z()<<")"<<endl;
+                //cout<<"  PCbest("<<PCbest.X()<<","<<PCbest.Y()<<","<<PCbest.Z()<<")"<<endl;
+                double dist = PC.Distance(Pint)/3.;
                 gp_Dir aDir(gp_Vec(PC,PCbest));
-                PCbest = gp_Pnt( PC.X() + aDir.X()*dist,
-                                 PC.Y() + aDir.Y()*dist,
-                                 PC.Z() + aDir.Z()*dist );
+                PCbest = PC.XYZ() + aDir.XYZ() * dist;
+              }
+              else {
+                gp_Vec VB(PC,PCbest);
+                gp_Pnt PCbestTmp = PC.XYZ() + VB.XYZ() * 3.0;
+                check = CheckIntersection(PCbestTmp, PC, Pint, aMesh, aShape, face);
+                if(check) {
+                  double dist = PC.Distance(Pint)/3.;
+                  if(dist<height) {
+                    gp_Dir aDir(gp_Vec(PC,PCbest));
+                    PCbest = PC.XYZ() + aDir.XYZ() * dist;
+                  }
+                }
               }
             }
-          }
-        }
-        // create node for PCbest
-        SMDS_MeshNode* NewNode = meshDS->AddNode( PCbest.X(), PCbest.Y(), PCbest.Z() );
-        // add triangles to result map
-        std::list<const SMDS_FaceOfNodes*> aList;
-        for(i=0; i<4; i++) {
-          SMDS_FaceOfNodes* NewFace = new SMDS_FaceOfNodes( NewNode, FNodes[i], FNodes[i+1] );
-          aList.push_back(NewFace);
+            // create node for PCbest
+            SMDS_MeshNode* NewNode = helper.AddNode( PCbest.X(), PCbest.Y(), PCbest.Z() );
+
+            // add triangles to result map
+            for(i=0; i<4; i++)
+            {
+              trias.push_back ( meshDS->AddFace( NewNode, FNodes[i], FNodes[i+1] ));
+              storeTmpElement( trias.back() );
+            }
+            // create a pyramid
+            if ( isRev ) swap( FNodes[1], FNodes[3]);
+            SMDS_MeshVolume* aPyram =
+              helper.AddVolume( FNodes[0], FNodes[1], FNodes[2], FNodes[3], NewNode );
+            myPyramids.push_back(aPyram);
+
+            quads.push_back( face );
+            hasNewTrias = true;
+            break;
+
+          } // case QUAD:
+
+        } // switch ( stat )
+      } // end loop on elements on a face submesh
+
+      bool sourceSubMeshIsProxy = false;
+      if ( aProxyMesh )
+      {
+        // move proxy sub-mesh from other proxy mesh to this
+        sourceSubMeshIsProxy = takeProxySubMesh( aShapeFace, aProxyMesh );
+        // move also tmp elements added in mesh
+        takeTmpElemsInMesh( aProxyMesh );
+      }
+      if ( hasNewTrias )
+      {
+        SMESH_ProxyMesh::SubMesh* prxSubMesh = getProxySubMesh( aShapeFace );
+        prxSubMesh->ChangeElements( trias.begin(), trias.end() );
+
+        // delete tmp quadrangles removed from aProxyMesh
+        if ( sourceSubMeshIsProxy )
+        {
+          for ( unsigned i = 0; i < quads.size(); ++i )
+            removeTmpElement( quads[i] );
+
+          delete myElemSearcher;
+          myElemSearcher =
+            SMESH_MeshEditor(&aMesh).GetElementSearcher( aProxyMesh->GetFaces(aShape));
         }
-        myResMap.insert(make_pair(face,aList));
-        // create pyramid
-        SMDS_MeshVolume* aPyram =
-          meshDS->AddVolume( FNodes[0], FNodes[1], FNodes[2], FNodes[3], NewNode );
-        myMapFPyram.insert(make_pair(face,aPyram));
-      } // end loop on elements on a face
+      }
     }
   } // end for(TopExp_Explorer exp(aShape,TopAbs_FACE);exp.More();exp.Next()) {
 
-  return Compute2ndPart(aMesh);
+  return Compute2ndPart(aMesh, myPyramids);
 }
 
-
-//=======================================================================
-//function : Compute
-//purpose  : 
-//=======================================================================
+//================================================================================
+/*!
+ * \brief Computes pyramids in mesh with no shape
+ */
+//================================================================================
 
 bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh)
 {
-  myResMap.clear();
-  myMapFPyram.clear();
+  SMESH_ProxyMesh::setMesh( aMesh );
+  SMESH_ProxyMesh::_allowedTypes.push_back( SMDSEntity_Triangle );
+  SMESH_ProxyMesh::_allowedTypes.push_back( SMDSEntity_Quad_Triangle );
+  if ( aMesh.NbQuadrangles() < 1 )
+    return false;
 
-  SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
+  vector<const SMDS_MeshElement*> myPyramids;
+  SMESH_MesherHelper helper(aMesh);
+  helper.IsQuadraticSubMesh(aMesh.GetShapeToMesh());
+  helper.SetElementsOnShape( true );
 
-  SMDS_FaceIteratorPtr itFace = meshDS->facesIterator();
+  if ( !myElemSearcher )
+    myElemSearcher = SMESH_MeshEditor(&aMesh).GetElementSearcher();
+  SMESH_ElementSearcher* searcher = const_cast<SMESH_ElementSearcher*>(myElemSearcher);
 
-  while(itFace->more()) {
-    const SMDS_MeshElement* face = itFace->next();
+  SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
+  SMESH_ProxyMesh::SubMesh* prxSubMesh = getProxySubMesh();
+
+  SMDS_FaceIteratorPtr fIt = meshDS->facesIterator(/*idInceasingOrder=*/true);
+  while( fIt->more()) 
+  {
+    const SMDS_MeshElement* face = fIt->next();
     if ( !face ) continue;
-    //cout<<endl<<"================= face->GetID() = "<<face->GetID()<<endl;
-    // preparation step using face info
+    // retrieve needed information about a face
     Handle(TColgp_HArray1OfPnt) PN = new TColgp_HArray1OfPnt(1,5);
     Handle(TColgp_HArray1OfVec) VN = new TColgp_HArray1OfVec(1,4);
-    std::vector<const SMDS_MeshNode*> FNodes(5);
+    vector<const SMDS_MeshNode*> FNodes(5);
     gp_Pnt PC;
     gp_Vec VNorm;
-
-    int stat =  Preparation(face, PN, VN, FNodes, PC, VNorm);
-    if(stat==0)
+    const SMDS_MeshElement* volumes[2];
+    int what = Preparation(face, PN, VN, FNodes, PC, VNorm, volumes);
+    if ( what == NOT_QUAD )
       continue;
+    if ( volumes[0] && volumes[1] )
+      continue; // face is shared by two volumes - no space for a pyramid
 
-    if(stat==2) {
+    if ( what == DEGEN_QUAD )
+    {
       // degenerate face
-      // add triangles to result map
-      std::list<const SMDS_FaceOfNodes*> aList;
-      SMDS_FaceOfNodes* NewFace;
-      // check orientation
+      // add a triangle to the proxy mesh
+      SMDS_MeshFace* NewFace;
 
-      double tmp = PN->Value(1).Distance(PN->Value(2)) +
-        PN->Value(2).Distance(PN->Value(3));
-      gp_Dir tmpDir(VNorm);
-      gp_Pnt Ptmp1( PC.X() + tmpDir.X()*tmp*1.e6,
-                    PC.Y() + tmpDir.Y()*tmp*1.e6,
-                    PC.Z() + tmpDir.Z()*tmp*1.e6 );
-      gp_Pnt Ptmp2( PC.X() + tmpDir.Reversed().X()*tmp*1.e6,
-                    PC.Y() + tmpDir.Reversed().Y()*tmp*1.e6,
-                    PC.Z() + tmpDir.Reversed().Z()*tmp*1.e6 );
+      // check orientation
+      double tmp = PN->Value(1).Distance(PN->Value(2)) + PN->Value(2).Distance(PN->Value(3));
+      // far points in VNorm direction
+      gp_Pnt Ptmp1 = PC.XYZ() + VNorm.XYZ() * tmp * 1.e6;
+      gp_Pnt Ptmp2 = PC.XYZ() - VNorm.XYZ() * tmp * 1.e6;
       // check intersection for Ptmp1 and Ptmp2
       bool IsRev = false;
       bool IsOK1 = false;
@@ -586,29 +946,19 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh)
       double dist1 = RealLast();
       double dist2 = RealLast();
       gp_Pnt Pres1,Pres2;
-      SMDS_FaceIteratorPtr itf = meshDS->facesIterator();
-      while(itf->more()) {
-        const SMDS_MeshElement* F = itf->next();
+
+      gp_Ax1 line( PC, VNorm );
+      vector< const SMDS_MeshElement* > suspectElems;
+      searcher->GetElementsNearLine( line, SMDSAbs_Face, suspectElems);
+
+      for ( int iF = 0; iF < suspectElems.size(); ++iF ) {
+        const SMDS_MeshElement* F = suspectElems[iF];
         if(F==face) continue;
         Handle(TColgp_HSequenceOfPnt) aContour = new TColgp_HSequenceOfPnt;
-        SMDS_ElemIteratorPtr nodeIt = F->nodesIterator();
-        if( !F->IsQuadratic() ) {
-          while ( nodeIt->more() ) {
-            const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-            aContour->Append(gp_Pnt(node->X(), node->Y(), node->Z()));
-          }
-        }
-        else {
-          int nn = 0;
-          while ( nodeIt->more() ) {
-            nn++;
-            const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-            aContour->Append(gp_Pnt(node->X(), node->Y(), node->Z()));
-            if(nn==face->NbNodes()/2) break;
-          }
-        }
+        for ( int i = 0; i < 4; ++i )
+          aContour->Append( SMESH_TNodeXYZ( F->GetNode(i) ));
         gp_Pnt PPP;
-        if( HasIntersection(Ptmp1, PC, PPP, aContour) ) {
+        if( !volumes[0] && HasIntersection(Ptmp1, PC, PPP, aContour) ) {
           IsOK1 = true;
           double tmp = PC.Distance(PPP);
           if(tmp<dist1) {
@@ -616,7 +966,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh)
             dist1 = tmp;
           }
         }
-        if( HasIntersection(Ptmp2, PC, PPP, aContour) ) {
+        if( !volumes[1] && HasIntersection(Ptmp2, PC, PPP, aContour) ) {
           IsOK2 = true;
           double tmp = PC.Distance(PPP);
           if(tmp<dist2) {
@@ -634,8 +984,8 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh)
         IsRev = true;
       }
       else { // IsOK1 && IsOK2
-        double tmp1 = PC.Distance(Pres1)/3.;
-        double tmp2 = PC.Distance(Pres2)/3.;
+        double tmp1 = PC.Distance(Pres1);
+        double tmp2 = PC.Distance(Pres2);
         if(tmp1<tmp2) {
           // using existed direction
         }
@@ -645,518 +995,295 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh)
         }
       }
       if(!IsRev)
-        NewFace = new SMDS_FaceOfNodes( FNodes[0], FNodes[1], FNodes[2] );
+        NewFace = meshDS->AddFace( FNodes[0], FNodes[1], FNodes[2] );
       else
-        NewFace = new SMDS_FaceOfNodes( FNodes[0], FNodes[2], FNodes[1] );
-      aList.push_back(NewFace);
-      myResMap.insert(make_pair(face,aList));
+        NewFace = meshDS->AddFace( FNodes[0], FNodes[2], FNodes[1] );
+      storeTmpElement( NewFace );
+      prxSubMesh->AddElement( NewFace );
       continue;
     }
-    
-    double xc = 0., yc = 0., zc = 0.;
+
+    // Case of non-degenerated quadrangle 
+
+    // Find pyramid peak
+
+    gp_XYZ PCbest(0., 0., 0.); // pyramid peak
     int i = 1;
     for(; i<=4; i++) {
       gp_Pnt Pbest = FindBestPoint(PN->Value(i), PN->Value(i+1), PC, VN->Value(i));
-      xc += Pbest.X();
-      yc += Pbest.Y();
-      zc += Pbest.Z();
+      PCbest += Pbest.XYZ();
     }
-    gp_Pnt PCbest(xc/4., yc/4., zc/4.);
-    double height = PCbest.Distance(PC);
-    if(height<1.e-6) {
+    PCbest /= 4;
+
+    double height = PC.Distance(PCbest); // pyramid height to precise
+    if ( height < 1.e-6 ) {
       // create new PCbest using a bit shift along VNorm
-      PCbest = gp_Pnt( PC.X() + VNorm.X()*0.001,
-                       PC.Y() + VNorm.Y()*0.001,
-                       PC.Z() + VNorm.Z()*0.001);
-      height = PCbest.Distance(PC);
+      PCbest = PC.XYZ() + VNorm.XYZ() * 0.001;
+      height = PC.Distance(PCbest);
+      if ( height < std::numeric_limits<double>::min() )
+        return false; // batterfly element
     }
-    //cout<<"  PCbest("<<PCbest.X()<<","<<PCbest.Y()<<","<<PCbest.Z()<<")"<<endl;
-
-    gp_Vec V1(PC,PCbest);
-    double tmp = PN->Value(1).Distance(PN->Value(3)) +
-      PN->Value(2).Distance(PN->Value(4));
-    gp_Dir tmpDir(V1);
-    gp_Pnt Ptmp1( PC.X() + tmpDir.X()*tmp*1.e6,
-                  PC.Y() + tmpDir.Y()*tmp*1.e6,
-                  PC.Z() + tmpDir.Z()*tmp*1.e6 );
-    gp_Pnt Ptmp2( PC.X() + tmpDir.Reversed().X()*tmp*1.e6,
-                  PC.Y() + tmpDir.Reversed().Y()*tmp*1.e6,
-                  PC.Z() + tmpDir.Reversed().Z()*tmp*1.e6 );
-    // check intersection for Ptmp1 and Ptmp2
-    bool IsRev = false;
-    bool IsOK1 = false;
-    bool IsOK2 = false;
-    double dist1 = RealLast();
-    double dist2 = RealLast();
-    gp_Pnt Pres1,Pres2;
-    SMDS_FaceIteratorPtr itf = meshDS->facesIterator();
-    while(itf->more()) {
-      const SMDS_MeshElement* F = itf->next();
+
+    // Restrict pyramid height by intersection with other faces
+    gp_Vec tmpDir(PC,PCbest); tmpDir.Normalize();
+    double tmp = PN->Value(1).Distance(PN->Value(3)) + PN->Value(2).Distance(PN->Value(4));
+    // far points: in (PC, PCbest) direction and vice-versa
+    gp_Pnt farPnt[2] = { PC.XYZ() + tmpDir.XYZ() * tmp * 1.e6,
+                         PC.XYZ() - tmpDir.XYZ() * tmp * 1.e6 };
+    // check intersection for farPnt1 and farPnt2
+    bool   intersected[2] = { false, false };
+    double dist       [2] = { RealLast(), RealLast() };
+    gp_Pnt intPnt[2];
+
+    gp_Ax1 line( PC, tmpDir );
+    vector< const SMDS_MeshElement* > suspectElems;
+    searcher->GetElementsNearLine( line, SMDSAbs_Face, suspectElems);
+
+    for ( int iF = 0; iF < suspectElems.size(); ++iF )
+    {
+      const SMDS_MeshElement* F = suspectElems[iF];
       if(F==face) continue;
       Handle(TColgp_HSequenceOfPnt) aContour = new TColgp_HSequenceOfPnt;
-      SMDS_ElemIteratorPtr nodeIt = F->nodesIterator();
-      if( !F->IsQuadratic() ) {
-        while ( nodeIt->more() ) {
-          const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-          aContour->Append(gp_Pnt(node->X(), node->Y(), node->Z()));
-        }
-      }
-      else {
-        int nn = 0;
-        while ( nodeIt->more() ) {
-          nn++;
-          const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-          aContour->Append(gp_Pnt(node->X(), node->Y(), node->Z()));
-          if(nn==face->NbNodes()/2) break;
-        }
-      }
-      gp_Pnt PPP;
-      if( HasIntersection(Ptmp1, PC, PPP, aContour) ) {
-        IsOK1 = true;
-        double tmp = PC.Distance(PPP);
-        if(tmp<dist1) {
-          Pres1 = PPP;
-          dist1 = tmp;
-        }
-      }
-      if( HasIntersection(Ptmp2, PC, PPP, aContour) ) {
-        IsOK2 = true;
-        double tmp = PC.Distance(PPP);
-        if(tmp<dist2) {
-          Pres2 = PPP;
-          dist2 = tmp;
+      int nbN = F->NbNodes() / ( F->IsQuadratic() ? 2 : 1 );
+      for ( i = 0; i < nbN; ++i )
+        aContour->Append( SMESH_TNodeXYZ( F->GetNode(i) ));
+      gp_Pnt intP;
+      for ( int isRev = 0; isRev < 2; ++isRev )
+      {
+        if( !volumes[isRev] && HasIntersection(farPnt[isRev], PC, intP, aContour) ) {
+          intersected[isRev] = true;
+          double d = PC.Distance( intP );
+          if( d < dist[isRev] )
+          {
+            intPnt[isRev] = intP;
+            dist  [isRev] = d;
+          }
         }
       }
     }
 
-    if( IsOK1 && !IsOK2 ) {
-      // using existed direction
-      double tmp = PC.Distance(Pres1)/3.;
-      if( height > tmp ) {
-        height = tmp;
-        PCbest = gp_Pnt( PC.X() + tmpDir.X()*height,
-                         PC.Y() + tmpDir.Y()*height,
-                         PC.Z() + tmpDir.Z()*height );
-      }
-    }
-    else if( !IsOK1 && IsOK2 ) {
-      // using opposite direction
-      IsRev = true;
-      double tmp = PC.Distance(Pres2)/3.;
-      if( height > tmp ) height = tmp;
-      PCbest = gp_Pnt( PC.X() + tmpDir.Reversed().X()*height,
-                       PC.Y() + tmpDir.Reversed().Y()*height,
-                       PC.Z() + tmpDir.Reversed().Z()*height );
-    }
-    else { // IsOK1 && IsOK2
-      double tmp1 = PC.Distance(Pres1)/3.;
-      double tmp2 = PC.Distance(Pres2)/3.;
-      if(tmp1<tmp2) {
-        // using existed direction
-        if( height > tmp1 ) {
-          height = tmp1;
-          PCbest = gp_Pnt( PC.X() + tmpDir.X()*height,
-                           PC.Y() + tmpDir.Y()*height,
-                           PC.Z() + tmpDir.Z()*height );
-        }
-      }
-      else {
-        // using opposite direction
-        IsRev = true;
-        if( height > tmp2 ) height = tmp2;
-        PCbest = gp_Pnt( PC.X() + tmpDir.Reversed().X()*height,
-                         PC.Y() + tmpDir.Reversed().Y()*height,
-                         PC.Z() + tmpDir.Reversed().Z()*height );
-      }
-    }
+    // Create one or two pyramids
+
+    for ( int isRev = 0; isRev < 2; ++isRev )
+    {
+      if( !intersected[isRev] ) continue;
+      double pyramidH = Min( height, PC.Distance(intPnt[isRev])/3.);
+      PCbest = PC.XYZ() + tmpDir.XYZ() * (isRev ? -pyramidH : pyramidH);
 
-    // create node for PCbest
-    SMDS_MeshNode* NewNode = meshDS->AddNode( PCbest.X(), PCbest.Y(), PCbest.Z() );
-    // add triangles to result map
-    std::list<const SMDS_FaceOfNodes*> aList;
-    for(i=0; i<4; i++) {
-      SMDS_FaceOfNodes* NewFace;
-      if(IsRev)
-        NewFace = new SMDS_FaceOfNodes( NewNode, FNodes[i], FNodes[i+1] );
+      // create node for PCbest
+      SMDS_MeshNode* NewNode = helper.AddNode( PCbest.X(), PCbest.Y(), PCbest.Z() );
+
+      // add triangles to result map
+      for(i=0; i<4; i++) {
+        SMDS_MeshFace* NewFace;
+        if(isRev)
+          NewFace = meshDS->AddFace( NewNode, FNodes[i], FNodes[i+1] );
+        else
+          NewFace = meshDS->AddFace( NewNode, FNodes[i+1], FNodes[i] );
+        storeTmpElement( NewFace );
+        prxSubMesh->AddElement( NewFace );
+      }
+      // create a pyramid
+      SMDS_MeshVolume* aPyram;
+      if(isRev)
+        aPyram = helper.AddVolume( FNodes[0], FNodes[1], FNodes[2], FNodes[3], NewNode );
       else
-        NewFace = new SMDS_FaceOfNodes( NewNode, FNodes[i+1], FNodes[i] );
-      aList.push_back(NewFace);
+        aPyram = helper.AddVolume( FNodes[0], FNodes[3], FNodes[2], FNodes[1], NewNode );
+      myPyramids.push_back(aPyram);
     }
-    myResMap.insert(make_pair(face,aList));
-    // create pyramid
-    SMDS_MeshVolume* aPyram;
-    if(IsRev)
-     aPyram = meshDS->AddVolume( FNodes[0], FNodes[1], FNodes[2], FNodes[3], NewNode );
-    else
-     aPyram = meshDS->AddVolume( FNodes[0], FNodes[3], FNodes[2], FNodes[1], NewNode );
-    myMapFPyram.insert(make_pair(face,aPyram));
-  } // end loop on elements on a face
+  } // end loop on all faces
 
-  return Compute2ndPart(aMesh);
+  return Compute2ndPart(aMesh, myPyramids);
 }
 
+//================================================================================
+/*!
+ * \brief Update created pyramids and faces to avoid their intersection
+ */
+//================================================================================
 
-//=======================================================================
-//function : Compute2ndPart
-//purpose  : 
-//=======================================================================
-
-bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh)
+bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh&                            aMesh,
+                                                  const vector<const SMDS_MeshElement*>& myPyramids)
 {
+  if(myPyramids.empty())
+    return true;
+
   SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
+  int i, j, k, myShapeID = myPyramids[0]->GetNode(4)->getshapeId();
 
-  // check intersections between created pyramids
-  int NbPyram = myMapFPyram.size();
-  //cout<<"NbPyram = "<<NbPyram<<endl;
-  if(NbPyram==0)
-    return true;
+  if ( myElemSearcher ) delete myElemSearcher;
+  myElemSearcher = SMESH_MeshEditor(&aMesh).GetElementSearcher();
+  SMESH_ElementSearcher* searcher = const_cast<SMESH_ElementSearcher*>(myElemSearcher);
 
-  std::vector< const SMDS_MeshElement* > Pyrams(NbPyram);
-  std::vector< const SMDS_MeshElement* > Faces(NbPyram);
-  std::map< const SMDS_MeshElement*,
-    const SMDS_MeshElement* >::iterator itp = myMapFPyram.begin();
-  int i = 0;
-  for(; itp!=myMapFPyram.end(); itp++, i++) {
-    Faces[i] = (*itp).first;
-    Pyrams[i] = (*itp).second;
-  }
-  StdMeshers_Array1OfSequenceOfInteger MergesInfo(0,NbPyram-1);
-  for(i=0; i<NbPyram; i++) {
-    TColStd_SequenceOfInteger aMerges;
-    aMerges.Append(i);
-    MergesInfo.SetValue(i,aMerges);
+  set<const SMDS_MeshNode*> nodesToMove;
+
+  // check adjacent pyramids
+
+  for ( i = 0; i <  myPyramids.size(); ++i )
+  {
+    const SMDS_MeshElement* PrmI = myPyramids[i];
+    MergeAdjacent( PrmI, nodesToMove );
   }
-  for(i=0; i<NbPyram-1; i++) {
-    const SMDS_MeshElement* Prm1 = Pyrams[i];
-    SMDS_ElemIteratorPtr nIt = Prm1->nodesIterator();
-    std::vector<gp_Pnt> Ps1(5);
-    const SMDS_MeshNode* Ns1[5];
-    int k = 0;
-    while( nIt->more() ) {
-      const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nIt->next() );
-      Ns1[k] = node;
-      Ps1[k] = gp_Pnt(node->X(), node->Y(), node->Z());
-      k++;
-    }
-    bool NeedMove = false;
-    for(int j=i+1; j<NbPyram; j++) {
-      //cout<<"  i="<<i<<" j="<<j<<endl;
-      const TColStd_SequenceOfInteger& aMergesI = MergesInfo.Value(i);
-      int nbI = aMergesI.Length();
-      const TColStd_SequenceOfInteger& aMergesJ = MergesInfo.Value(j);
-      int nbJ = aMergesJ.Length();
-
-      int k = 2;
-      bool NeedCont = false;
-      for(; k<=nbI; k++) {
-        if(aMergesI.Value(k)==j) {
-          NeedCont = true;
-          break;
-        }
-      }
-      if(NeedCont) continue;
-
-      const SMDS_MeshElement* Prm2 = Pyrams[j];
-      nIt = Prm2->nodesIterator();
-      std::vector<gp_Pnt> Ps2(5);
-      const SMDS_MeshNode* Ns2[5];
-      k = 0;
-      while( nIt->more() ) {
-        const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nIt->next() );
-        Ns2[k] = node;
-        Ps2[k] = gp_Pnt(node->X(), node->Y(), node->Z());
-        k++;
+
+  // iterate on all pyramids
+  for ( i = 0; i <  myPyramids.size(); ++i )
+  {
+    const SMDS_MeshElement* PrmI = myPyramids[i];
+
+    // compare PrmI with all the rest pyramids
+
+    // collect adjacent pyramids and nodes coordinates of PrmI
+    set<const SMDS_MeshElement*> checkedPyrams;
+    vector<gp_Pnt> PsI(5);
+    for(k=0; k<5; k++) // loop on 4 base nodes of PrmI
+    {
+      const SMDS_MeshNode* n = PrmI->GetNode(k);
+      PsI[k] = SMESH_TNodeXYZ( n );
+      SMDS_ElemIteratorPtr vIt = n->GetInverseElementIterator( SMDSAbs_Volume );
+      while ( vIt->more() )
+      {
+        const SMDS_MeshElement* PrmJ = vIt->next();
+        if ( SMESH_Algo::GetCommonNodes( PrmI, PrmJ ).size() > 1 )
+          checkedPyrams.insert( PrmJ );
       }
+    }
 
-      bool hasInt = false;
-      gp_Pnt Pint;
-      for(k=0; k<4; k++) {
-        gp_Vec Vtmp(Ps1[k],Ps1[4]);
-        gp_Pnt Pshift( Ps1[k].X() + Vtmp.X()*0.01,
-                       Ps1[k].Y() + Vtmp.Y()*0.01,
-                       Ps1[k].Z() + Vtmp.Z()*0.01 );
-        int m=0;
-        for(; m<3; m++) {
-          if( HasIntersection3( Pshift, Ps1[4], Pint, Ps2[m], Ps2[m+1], Ps2[4]) ) {
-            hasInt = true;
-            break;
-          }
-        }
-        if( HasIntersection3( Pshift, Ps1[4], Pint, Ps2[3], Ps2[0], Ps2[4]) ) {
-          hasInt = true;
+    // check intersection with distant pyramids
+    for(k=0; k<4; k++) // loop on 4 base nodes of PrmI
+    {
+      gp_Vec Vtmp(PsI[k],PsI[4]);
+      gp_Ax1 line( PsI[k], Vtmp );
+      vector< const SMDS_MeshElement* > suspectPyrams;
+      searcher->GetElementsNearLine( line, SMDSAbs_Volume, suspectPyrams);
+
+      for ( j = 0; j < suspectPyrams.size(); ++j )
+      {
+        const SMDS_MeshElement* PrmJ = suspectPyrams[j];
+        if ( PrmJ == PrmI || PrmJ->NbCornerNodes() != 5 )
+          continue;
+        if ( myShapeID != PrmJ->GetNode(4)->getshapeId())
+          continue; // pyramid from other SOLID
+        if ( PrmI->GetNode(4) == PrmJ->GetNode(4) )
+          continue; // pyramids PrmI and PrmJ already merged
+        if ( !checkedPyrams.insert( PrmJ ).second )
+          continue; // already checked
+
+        TXyzIterator xyzIt( PrmJ->nodesIterator() );
+        vector<gp_Pnt> PsJ( xyzIt, TXyzIterator() );
+
+        gp_Pnt Pint;
+        bool hasInt=false;
+        for(k=0; k<4 && !hasInt; k++) {
+          gp_Vec Vtmp(PsI[k],PsI[4]);
+          gp_Pnt Pshift = PsI[k].XYZ() + Vtmp.XYZ() * 0.01; // base node moved a bit to apex
+          hasInt = 
+          ( HasIntersection3( Pshift, PsI[4], Pint, PsJ[0], PsJ[1], PsJ[4]) ||
+            HasIntersection3( Pshift, PsI[4], Pint, PsJ[1], PsJ[2], PsJ[4]) ||
+            HasIntersection3( Pshift, PsI[4], Pint, PsJ[2], PsJ[3], PsJ[4]) ||
+            HasIntersection3( Pshift, PsI[4], Pint, PsJ[3], PsJ[0], PsJ[4]) );
         }
-        if(hasInt) break;
-      }
-      if(!hasInt) {
-        for(k=0; k<4; k++) {
-          gp_Vec Vtmp(Ps2[k],Ps2[4]);
-          gp_Pnt Pshift( Ps2[k].X() + Vtmp.X()*0.01,
-                         Ps2[k].Y() + Vtmp.Y()*0.01,
-                         Ps2[k].Z() + Vtmp.Z()*0.01 );
-          int m=0;
-          for(; m<3; m++) {
-            if( HasIntersection3( Pshift, Ps2[4], Pint, Ps1[m], Ps1[m+1], Ps1[4]) ) {
-              hasInt = true;
-              break;
-            }
-          }
-          if( HasIntersection3( Pshift, Ps2[4], Pint, Ps1[3], Ps1[0], Ps1[4]) ) {
-            hasInt = true;
-          }
-          if(hasInt) break;
+        for(k=0; k<4 && !hasInt; k++) {
+          gp_Vec Vtmp(PsJ[k],PsJ[4]);
+          gp_Pnt Pshift = PsJ[k].XYZ() + Vtmp.XYZ() * 0.01;
+          hasInt = 
+            ( HasIntersection3( Pshift, PsJ[4], Pint, PsI[0], PsI[1], PsI[4]) ||
+              HasIntersection3( Pshift, PsJ[4], Pint, PsI[1], PsI[2], PsI[4]) ||
+              HasIntersection3( Pshift, PsJ[4], Pint, PsI[2], PsI[3], PsI[4]) ||
+              HasIntersection3( Pshift, PsJ[4], Pint, PsI[3], PsI[0], PsI[4]) );
         }
-      }
 
-      if(hasInt) {
-        //cout<<"    has intersec for i="<<i<<" j="<<j<<endl;
-        // check if MeshFaces have 2 common node
-        int nbc = 0;
-        for(k=0; k<4; k++) {
-          for(int m=0; m<4; m++) {
-            if( Ns1[k]==Ns2[m] ) nbc++;
-          }
-        }
-        //cout<<"      nbc = "<<nbc<<endl;
-        if(nbc>0) {
-          // create common node
-          SMDS_MeshNode* CommonNode = const_cast<SMDS_MeshNode*>(Ns1[4]);
-          CommonNode->setXYZ( ( nbI*Ps1[4].X() + nbJ*Ps2[4].X() ) / (nbI+nbJ),
-                              ( nbI*Ps1[4].Y() + nbJ*Ps2[4].Y() ) / (nbI+nbJ),
-                              ( nbI*Ps1[4].Z() + nbJ*Ps2[4].Z() ) / (nbI+nbJ) );
-          NeedMove = true;
-          //cout<<"       CommonNode: "<<CommonNode;
-          const SMDS_MeshNode* Nrem = Ns2[4];
-          Ns2[4] = CommonNode;
-          meshDS->ChangeElementNodes(Prm2, Ns2, 5);
-          // update pyramids for J
-          for(k=2; k<=nbJ; k++) {
-            const SMDS_MeshElement* tmpPrm = Pyrams[aMergesJ.Value(k)];
-            SMDS_ElemIteratorPtr tmpIt = tmpPrm->nodesIterator();
-            const SMDS_MeshNode* Ns[5];
-            int m = 0;
-            while( tmpIt->more() ) {
-              Ns[m] = static_cast<const SMDS_MeshNode*>( tmpIt->next() );
-              m++;
-            }
-            Ns[4] = CommonNode;
-            meshDS->ChangeElementNodes(tmpPrm, Ns, 5);
-          }
+        if ( hasInt )
+        {
+          // count common nodes of base faces of two pyramids
+          int nbc = 0;
+          for (k=0; k<4; k++)
+            nbc += int ( PrmI->GetNodeIndex( PrmJ->GetNode(k) ) >= 0 );
 
-          // update MergesInfo
-          for(k=1; k<=nbI; k++) {
-            int num = aMergesI.Value(k);
-            const TColStd_SequenceOfInteger& aSeq = MergesInfo.Value(num);
-            TColStd_SequenceOfInteger tmpSeq;
-            int m = 1;
-            for(; m<=aSeq.Length(); m++) {
-              tmpSeq.Append(aSeq.Value(m));
-            }
-            for(m=1; m<=nbJ; m++) {
-              tmpSeq.Append(aMergesJ.Value(m));
-            }
-            MergesInfo.SetValue(num,tmpSeq);
-          }
-          for(k=1; k<=nbJ; k++) {
-            int num = aMergesJ.Value(k);
-            const TColStd_SequenceOfInteger& aSeq = MergesInfo.Value(num);
-            TColStd_SequenceOfInteger tmpSeq;
-            int m = 1;
-            for(; m<=aSeq.Length(); m++) {
-              tmpSeq.Append(aSeq.Value(m));
-            }
-            for(m=1; m<=nbI; m++) {
-              tmpSeq.Append(aMergesI.Value(m));
-            }
-            MergesInfo.SetValue(num,tmpSeq);
-          }
+          if ( nbc == 4 )
+            continue; // pyrams have a common base face
 
-          // update triangles for aMergesJ
-          for(k=1; k<=nbJ; k++) {
-            std::list< std::list< const SMDS_MeshNode* > > aFNodes;
-            std::list< const SMDS_MeshElement* > aFFaces;
-            int num = aMergesJ.Value(k);
-            std::map< const SMDS_MeshElement*,
-              std::list<const SMDS_FaceOfNodes*> >::iterator itrm = myResMap.find(Faces[num]);
-            std::list<const SMDS_FaceOfNodes*> trias = (*itrm).second;
-            std::list<const SMDS_FaceOfNodes*>::iterator itt = trias.begin();
-            for(; itt!=trias.end(); itt++) {
-              int nn = -1;
-              SMDS_ElemIteratorPtr nodeIt = (*itt)->nodesIterator();
-              const SMDS_MeshNode* NF[3];
-              while ( nodeIt->more() ) {
-                nn++;
-                NF[nn] = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-              }
-              NF[0] = CommonNode;
-              SMDS_FaceOfNodes* Ftria = const_cast< SMDS_FaceOfNodes*>( (*itt) );
-              Ftria->ChangeNodes(NF, 3);
-            }
+          if(nbc>0)
+          {
+            // Merge the two pyramids and others already merged with them
+            MergePiramids( PrmI, PrmJ, nodesToMove );
           }
+          else { // nbc==0
 
-          // check and remove coincided faces
-          TColStd_SequenceOfInteger IdRemovedTrias;
-          int i1 = 1;
-          for(; i1<=nbI; i1++) {
-            int numI = aMergesI.Value(i1);
-            std::map< const SMDS_MeshElement*,
-              std::list<const SMDS_FaceOfNodes*> >::iterator itrmI = myResMap.find(Faces[numI]);
-            std::list<const SMDS_FaceOfNodes*> triasI = (*itrmI).second;
-            std::list<const SMDS_FaceOfNodes*>::iterator ittI = triasI.begin();
-            int nbfI = triasI.size();
-            std::vector<const SMDS_FaceOfNodes*> FsI(nbfI);
-            k = 0;
-            for(; ittI!=triasI.end(); ittI++) {
-              FsI[k]  = (*ittI);
-              k++;
+            // decrease height of pyramids
+            gp_XYZ PCi(0,0,0), PCj(0,0,0);
+            for(k=0; k<4; k++) {
+              PCi += PsI[k].XYZ();
+              PCj += PsJ[k].XYZ();
             }
-            int i2 = 0;
-            for(; i2<nbfI; i2++) {
-              const SMDS_FaceOfNodes* FI = FsI[i2];
-              if(FI==0) continue;
-              int j1 = 1;
-              for(; j1<=nbJ; j1++) {
-                int numJ = aMergesJ.Value(j1);
-                std::map< const SMDS_MeshElement*,
-                  std::list<const SMDS_FaceOfNodes*> >::iterator itrmJ = myResMap.find(Faces[numJ]);
-                std::list<const SMDS_FaceOfNodes*> triasJ = (*itrmJ).second;
-                std::list<const SMDS_FaceOfNodes*>::iterator ittJ = triasJ.begin();
-                int nbfJ = triasJ.size();
-                std::vector<const SMDS_FaceOfNodes*> FsJ(nbfJ);
-                k = 0;
-                for(; ittJ!=triasJ.end(); ittJ++) {
-                  FsJ[k]  = (*ittJ);
-                  k++;
-                }
-                int j2 = 0;
-                for(; j2<nbfJ; j2++) {
-                  const SMDS_FaceOfNodes* FJ = FsJ[j2];
-                  // compare triangles
-                  if( CompareTrias(FI,FJ) ) {
-                    IdRemovedTrias.Append( FI->GetID() );
-                    IdRemovedTrias.Append( FJ->GetID() );
-                    FsI[i2] = 0;
-                    FsJ[j2] = 0;
-                    std::list<const SMDS_FaceOfNodes*> new_triasI;
-                    for(k=0; k<nbfI; k++) {
-                      if( FsI[k]==0 ) continue;
-                      new_triasI.push_back( FsI[k] );
-                    }
-                    (*itrmI).second = new_triasI;
-                    triasI = new_triasI;
-                    std::list<const SMDS_FaceOfNodes*> new_triasJ;
-                    for(k=0; k<nbfJ; k++) {
-                      if( FsJ[k]==0 ) continue;
-                      new_triasJ.push_back( FsJ[k] );
-                    }
-                    (*itrmJ).second = new_triasJ;
-                    triasJ = new_triasJ;
-                    // remove faces
-                    delete FI;
-                    delete FJ;
-                    // close for j2 and j1
-                    j1 = nbJ;
-                    break;
-                  }
-                } // j2
-              } // j1
-            } // i2
-          } // i1
-          // removing node
-          meshDS->RemoveNode(Nrem);
-        }
-        else { // nbc==0
-          //cout<<"decrease height of pyramids"<<endl;
-          // decrease height of pyramids
-          double xc1 = 0., yc1 = 0., zc1 = 0.;
-          double xc2 = 0., yc2 = 0., zc2 = 0.;
-          for(k=0; k<4; k++) {
-            xc1 += Ps1[k].X();
-            yc1 += Ps1[k].Y();
-            zc1 += Ps1[k].Z();
-            xc2 += Ps2[k].X();
-            yc2 += Ps2[k].Y();
-            zc2 += Ps2[k].Z();
+            PCi /= 4; PCj /= 4; 
+            gp_Vec VN1(PCi,PsI[4]);
+            gp_Vec VN2(PCj,PsJ[4]);
+            gp_Vec VI1(PCi,Pint);
+            gp_Vec VI2(PCj,Pint);
+            double ang1 = fabs(VN1.Angle(VI1));
+            double ang2 = fabs(VN2.Angle(VI2));
+            double coef1 = 0.5 - (( ang1 < M_PI/3. ) ? cos(ang1)*0.25 : 0 );
+            double coef2 = 0.5 - (( ang2 < M_PI/3. ) ? cos(ang2)*0.25 : 0 ); // cos(ang2) ?
+//             double coef2 = 0.5;
+//             if(ang2<PI/3)
+//               coef2 -= cos(ang1)*0.25;
+
+            VN1.Scale(coef1);
+            VN2.Scale(coef2);
+            SMDS_MeshNode* aNode1 = const_cast<SMDS_MeshNode*>(PrmI->GetNode(4));
+            aNode1->setXYZ( PCi.X()+VN1.X(), PCi.Y()+VN1.Y(), PCi.Z()+VN1.Z() );
+            SMDS_MeshNode* aNode2 = const_cast<SMDS_MeshNode*>(PrmJ->GetNode(4));
+            aNode2->setXYZ( PCj.X()+VN2.X(), PCj.Y()+VN2.Y(), PCj.Z()+VN2.Z() );
+            nodesToMove.insert( aNode1 );
+            nodesToMove.insert( aNode2 );
           }
-          gp_Pnt PC1(xc1/4.,yc1/4.,zc1/4.);
-          gp_Pnt PC2(xc2/4.,yc2/4.,zc2/4.);
-          gp_Vec VN1(PC1,Ps1[4]);
-          gp_Vec VI1(PC1,Pint);
-          gp_Vec VN2(PC2,Ps2[4]);
-          gp_Vec VI2(PC2,Pint);
-          double ang1 = fabs(VN1.Angle(VI1));
-          double ang2 = fabs(VN2.Angle(VI2));
-          double h1,h2;
-          if(ang1>PI/3.)
-            h1 = VI1.Magnitude()/2;
-          else
-            h1 = VI1.Magnitude()*cos(ang1);
-          if(ang2>PI/3.)
-            h2 = VI2.Magnitude()/2;
+          // fix intersections that could appear after apex movement
+          MergeAdjacent( PrmI, nodesToMove );
+          MergeAdjacent( PrmJ, nodesToMove );
+
+        } // end if(hasInt)
+      } // loop on suspectPyrams
+    }  // loop on 4 base nodes of PrmI
+
+  } // loop on all pyramids
+
+  if( !nodesToMove.empty() && !meshDS->IsEmbeddedMode() )
+  {
+    set<const SMDS_MeshNode*>::iterator n = nodesToMove.begin();
+    for ( ; n != nodesToMove.end(); ++n )
+      meshDS->MoveNode( *n, (*n)->X(), (*n)->Y(), (*n)->Z() );
+  }
+
+  // move medium nodes of merged quadratic pyramids
+  if ( myPyramids[0]->IsQuadratic() )
+    UpdateQuadraticPyramids( nodesToMove, GetMeshDS() );
+
+  // erase removed triangles from the proxy mesh
+  if ( !myRemovedTrias.empty() )
+  {
+    for ( int i = 0; i <= meshDS->MaxShapeIndex(); ++i )
+      if ( SMESH_ProxyMesh::SubMesh* sm = findProxySubMesh(i))
+      {
+        vector<const SMDS_MeshElement *> faces;
+        faces.reserve( sm->NbElements() );
+        SMDS_ElemIteratorPtr fIt = sm->GetElements();
+        while ( fIt->more() )
+        {
+          const SMDS_MeshElement* tria = fIt->next();
+          set<const SMDS_MeshElement*>::iterator rmTria = myRemovedTrias.find( tria );
+          if ( rmTria != myRemovedTrias.end() )
+            myRemovedTrias.erase( rmTria );
           else
-            h2 = VI2.Magnitude()*cos(ang2);
-          double coef1 = 0.5;
-          if(ang1<PI/3)
-            coef1 -= cos(ang1)*0.25;
-          double coef2 = 0.5;
-          if(ang2<PI/3)
-            coef2 -= cos(ang1)*0.25;
-
-          SMDS_MeshNode* aNode1 = const_cast<SMDS_MeshNode*>(Ns1[4]);
-          VN1.Scale(coef1);
-          aNode1->setXYZ( PC1.X()+VN1.X(), PC1.Y()+VN1.Y(), PC1.Z()+VN1.Z() );
-          SMDS_MeshNode* aNode2 = const_cast<SMDS_MeshNode*>(Ns2[4]);
-          VN2.Scale(coef2);
-          aNode2->setXYZ( PC2.X()+VN2.X(), PC2.Y()+VN2.Y(), PC2.Z()+VN2.Z() );
-          NeedMove = true;
+            faces.push_back( tria );
         }
-      } // end if(hasInt)
-      else {
-        //cout<<"    no intersec for i="<<i<<" j="<<j<<endl;
+        sm->ChangeElements( faces.begin(), faces.end() );
       }
-
-    }
-    if( NeedMove && !meshDS->IsEmbeddedMode() ) {
-      meshDS->MoveNode( Ns1[4], Ns1[4]->X(), Ns1[4]->Y(), Ns1[4]->Z() );
-    }
   }
 
-  return true;
-}
+  myDegNodes.clear();
 
+  delete myElemSearcher;
+  myElemSearcher=0;
 
-//================================================================================
-/*!
- * \brief Return list of created triangles for given face
- */
-//================================================================================
-std::list<const SMDS_FaceOfNodes*> StdMeshers_QuadToTriaAdaptor::GetTriangles
-                                                   (const SMDS_MeshElement* aFace)
-{
-  std::list<const SMDS_FaceOfNodes*> aRes;
-  std::map< const SMDS_MeshElement*,
-    std::list<const SMDS_FaceOfNodes*> >::iterator it = myResMap.find(aFace);
-  if( it != myResMap.end() ) {
-    aRes = (*it).second;
-  }
-  return aRes;
+  return true;
 }
-
-
-//================================================================================
-/*!
- * \brief Remove all create auxilary faces
- */
-//================================================================================
-//void StdMeshers_QuadToTriaAdaptor::RemoveFaces(SMESH_Mesh& aMesh)
-//{
-//  SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
-//  std::map< const SMDS_MeshElement*,
-//    std::list<const SMDS_MeshElement*> >::iterator it = myResMap.begin();
-//  for(; it != myResMap.end(); it++ ) {
-//    std::list<const SMDS_MeshElement*> aFaces = (*it).second;
-//    std::list<const SMDS_MeshElement*>::iterator itf = aFaces.begin();
-//    for(; itf!=aFaces.end(); itf++ ) {
-//      meshDS->RemoveElement( (*itf) );
-//    }
-//  }
-//}
index af818549f264005607c7621b80d2eff1d107b3dd..87063ee3f416098685fdbc8d39b81872dc158ed4 100644 (file)
@@ -1,76 +1,97 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  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 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.
 //
-//  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
 //
-//  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.com
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-//  SMESH SMESH : implementaion of SMESH idl descriptions
+
 //  File   : StdMeshers_QuadToTriaAdaptor.hxx
 //  Module : SMESH
 //
 #ifndef _SMESH_QuadToTriaAdaptor_HXX_
 #define _SMESH_QuadToTriaAdaptor_HXX_
 
-#include <SMESH_Mesh.hxx>
-#include <SMESH_StdMeshers.hxx>
-#include <SMDS_FaceOfNodes.hxx>
-#include <TColgp_HArray1OfPnt.hxx>
-#include <TColgp_HArray1OfVec.hxx>
+#include "SMESH_StdMeshers.hxx"
+
+#include "SMESH_ProxyMesh.hxx"
+
+class SMESH_Mesh;
+class SMESH_ElementSearcher;
+class SMDS_MeshElement;
+class SMDS_MeshNode;
+class SMDS_MeshFace;
+class Handle_TColgp_HArray1OfPnt;
+class Handle_TColgp_HArray1OfVec;
+class gp_Pnt;
+class gp_Vec;
 
-#include <map>
+
+#include <set>
 #include <list>
 #include <vector>
 
-class STDMESHERS_EXPORT StdMeshers_QuadToTriaAdaptor
+#include <TopoDS_Shape.hxx>
+
+/*!
+ * \brief "Transforms" quadrilateral faces into triangular ones by creation of pyramids
+ */
+class STDMESHERS_EXPORT StdMeshers_QuadToTriaAdaptor : public SMESH_ProxyMesh
 {
 public:
-
   StdMeshers_QuadToTriaAdaptor();
 
   ~StdMeshers_QuadToTriaAdaptor();
 
-  bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
+  bool Compute(SMESH_Mesh&         aMesh,
+               const TopoDS_Shape& aShape,
+               SMESH_ProxyMesh*    aProxyMesh=0);
 
   bool Compute(SMESH_Mesh& aMesh);
 
-  std::list<const SMDS_FaceOfNodes*> GetTriangles(const SMDS_MeshElement* aFace);
+  const TopoDS_Shape& GetShape() const { return myShape; }
 
 protected:
 
-  //bool CheckDegenerate(const SMDS_MeshElement* aFace);
-
   int Preparation(const SMDS_MeshElement* face,
-                  Handle(TColgp_HArray1OfPnt) PN,
-                  Handle(TColgp_HArray1OfVec) VN,
+                  Handle_TColgp_HArray1OfPnt& PN,
+                  Handle_TColgp_HArray1OfVec& VN,
                   std::vector<const SMDS_MeshNode*>& FNodes,
-                  gp_Pnt& PC, gp_Vec& VNorm);
+                  gp_Pnt& PC, gp_Vec& VNorm,
+                  const SMDS_MeshElement** volumes=0);
 
   bool CheckIntersection(const gp_Pnt& P, const gp_Pnt& PC,
                          gp_Pnt& Pint, SMESH_Mesh& aMesh,
                          const TopoDS_Shape& aShape,
-                         const TopoDS_Shape& NotCheckedFace);
+                         const SMDS_MeshElement* NotCheckedFace);
 
-  bool Compute2ndPart(SMESH_Mesh& aMesh);
+  bool Compute2ndPart(SMESH_Mesh&                                 aMesh,
+                      const std::vector<const SMDS_MeshElement*>& pyramids);
 
-  std::map< const SMDS_MeshElement*, std::list<const SMDS_FaceOfNodes*> > myResMap;
-  std::map< const SMDS_MeshElement*, const SMDS_MeshElement* > myMapFPyram;
-  std::list< const SMDS_MeshNode* > myDegNodes;
 
+  void MergePiramids( const SMDS_MeshElement*          PrmI,
+                      const SMDS_MeshElement*          PrmJ,
+                      std::set<const SMDS_MeshNode*> & nodesToMove);
+
+  void MergeAdjacent(const SMDS_MeshElement*         PrmI,
+                     std::set<const SMDS_MeshNode*>& nodesToMove);
+
+
+  TopoDS_Shape                      myShape;
+  std::set<const SMDS_MeshElement*> myRemovedTrias;
+  std::list< const SMDS_MeshNode* > myDegNodes;
+  const SMESH_ElementSearcher*      myElemSearcher;
 };
 
 #endif
diff --git a/src/StdMeshers/StdMeshers_QuadrangleParams.cxx b/src/StdMeshers/StdMeshers_QuadrangleParams.cxx
new file mode 100644 (file)
index 0000000..13a7f48
--- /dev/null
@@ -0,0 +1,175 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+//  File   : StdMeshers_QuadrangleParams.cxx
+//  Author : Sergey KUUL, OCC
+//  Module : SMESH
+
+#include "StdMeshers_QuadrangleParams.hxx"
+
+#include "SMESH_Algo.hxx"
+#include "SMESH_Mesh.hxx"
+
+#include <BRep_Tool.hxx>
+#include <GCPnts_AbscissaPoint.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <Geom_Curve.hxx>
+#include <TopExp.hxx>
+#include <TopLoc_Location.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+
+using namespace std;
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+StdMeshers_QuadrangleParams::StdMeshers_QuadrangleParams(int hypId, int studyId,
+                                                         SMESH_Gen * gen)
+  : SMESH_Hypothesis(hypId, studyId, gen)
+{
+  _name = "QuadrangleParams";
+  _param_algo_dim = 2;
+  _triaVertexID = -1;
+  _quadType = QUAD_STANDARD;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+StdMeshers_QuadrangleParams::~StdMeshers_QuadrangleParams()
+{
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+void StdMeshers_QuadrangleParams::SetTriaVertex (int id)
+{
+  if (id != _triaVertexID) {
+    _triaVertexID = id;
+    NotifySubMeshesHypothesisModification();
+  }
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+void StdMeshers_QuadrangleParams::SetQuadType (StdMeshers_QuadType type)
+{
+  if (type != _quadType) {
+    _quadType = type;
+    NotifySubMeshesHypothesisModification();
+  }
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+ostream & StdMeshers_QuadrangleParams::SaveTo(ostream & save)
+{
+  if (_objEntry.size() == 0)
+    save << _triaVertexID << " UNDEFINED " << int(_quadType);
+  else
+    save << _triaVertexID << " " << _objEntry << " " << int(_quadType);
+  return save;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+istream & StdMeshers_QuadrangleParams::LoadFrom(istream & load)
+{
+  bool isOK = true;
+  isOK = (load >> _triaVertexID);
+  if (!isOK)
+    load.clear(ios::badbit | load.rdstate());
+
+  isOK = (load >> _objEntry);
+  if (!isOK)
+    load.clear(ios::badbit | load.rdstate());
+
+  int type;
+  isOK = (load >> type);
+  if (isOK)
+    _quadType = StdMeshers_QuadType(type);
+
+  return load;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+ostream & operator <<(ostream & save, StdMeshers_QuadrangleParams & hyp)
+{
+  return hyp.SaveTo( save );
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+istream & operator >>(istream & load, StdMeshers_QuadrangleParams & hyp)
+{
+  return hyp.LoadFrom( load );
+}
+
+//================================================================================
+/*!
+ * \brief Redifined method
+ * \param theMesh - the built mesh
+ * \param theShape - the geometry of interest
+ * \retval bool - true if parameter values have been successfully defined
+ */
+//================================================================================
+bool StdMeshers_QuadrangleParams::SetParametersByMesh(const SMESH_Mesh* theMesh,
+                                                      const TopoDS_Shape& theShape)
+{
+  if ( !theMesh || theShape.IsNull() )
+    return false;
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Initialize my parameter values by default parameters.
+ *  \retval bool - true if parameter values have been successfully defined
+ */
+//================================================================================
+bool StdMeshers_QuadrangleParams::SetParametersByDefaults(const TDefaults&  dflts,
+                                                          const SMESH_Mesh* /*mesh*/)
+{
+  return true;
+}
diff --git a/src/StdMeshers/StdMeshers_QuadrangleParams.hxx b/src/StdMeshers/StdMeshers_QuadrangleParams.hxx
new file mode 100644 (file)
index 0000000..6bf9c2a
--- /dev/null
@@ -0,0 +1,86 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+//  File   : StdMeshers_QuadrangleParams.hxx
+//  Author : Sergey KUUL, OCC
+//  Module : SMESH
+
+#ifndef _SMESH_QUADRANGLEPARAMS_HXX_
+#define _SMESH_QUADRANGLEPARAMS_HXX_
+
+#include "SMESH_StdMeshers.hxx"
+
+#include "SMESH_Hypothesis.hxx"
+#include "Utils_SALOME_Exception.hxx"
+
+enum StdMeshers_QuadType
+  {
+    QUAD_STANDARD,
+    QUAD_TRIANGLE_PREF,
+    QUAD_QUADRANGLE_PREF,
+    QUAD_QUADRANGLE_PREF_REVERSED,
+    QUAD_REDUCED,
+    QUAD_NB_TYPES
+  };
+
+class STDMESHERS_EXPORT StdMeshers_QuadrangleParams:
+  public SMESH_Hypothesis
+{
+public:
+  StdMeshers_QuadrangleParams(int hypId, int studyId, SMESH_Gen* gen);
+  virtual ~StdMeshers_QuadrangleParams();
+
+  void SetTriaVertex (int id);
+  int GetTriaVertex() const { return _triaVertexID; }
+
+  void SetObjectEntry (const char* entry) { _objEntry = entry; }
+  const char* GetObjectEntry() { return _objEntry.c_str(); }
+
+  void SetQuadType (StdMeshers_QuadType type);
+  StdMeshers_QuadType GetQuadType() const { return _quadType; }
+
+  virtual std::ostream & SaveTo(std::ostream & save);
+  virtual std::istream & LoadFrom(std::istream & load);
+  friend std::ostream& operator << (std::ostream & save,
+                                    StdMeshers_QuadrangleParams & hyp);
+  friend std::istream& operator >> (std::istream & load,
+                                    StdMeshers_QuadrangleParams & hyp);
+
+  /*!
+   * \brief Initialize start and end length by the mesh built on the geometry
+    * \param theMesh - the built mesh
+    * \param theShape - the geometry of interest
+    * \retval bool - true if parameter values have been successfully defined
+   */
+  virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh,
+                                   const TopoDS_Shape& theShape);
+
+  /*!
+   * \brief Initialize my parameter values by default parameters.
+   *  \retval bool - true if parameter values have been successfully defined
+   */
+  virtual bool SetParametersByDefaults(const TDefaults& dflts,
+                                       const SMESH_Mesh* theMesh=0);
+
+protected:
+  int                 _triaVertexID;
+  std::string         _objEntry;
+  StdMeshers_QuadType _quadType;
+};
+
+#endif
index cf3986e38a0070ece022db2a77fbec41a2d4de2b..8ecb551a58d38a42f15b09e3c117810008651fdb 100644 (file)
@@ -1,28 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH StdMeshers_QuadranglePreference : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_QuadranglePreference.cxx
 //  Module : SMESH
-
+//
 #include "StdMeshers_QuadranglePreference.hxx"
 #include "utilities.h"
 
@@ -40,7 +41,7 @@ StdMeshers_QuadranglePreference::StdMeshers_QuadranglePreference(int         hyp
      :SMESH_Hypothesis(hypId, studyId, gen)
 {
   _name = "QuadranglePreference";
-  _param_algo_dim = -2; // auxiliary used by StdMeshers_Quadrangle_2D
+  _param_algo_dim = -2; // auxiliary used by NETGEN 2D
 }
 
 //=============================================================================
@@ -75,27 +76,6 @@ istream & StdMeshers_QuadranglePreference::LoadFrom(istream & load)
   return load;
 }
 
-//=============================================================================
-/*!
- *  
- */
-//=============================================================================
-
-ostream & operator <<(ostream & save, StdMeshers_QuadranglePreference & hyp)
-{
-  return hyp.SaveTo( save );
-}
-
-//=============================================================================
-/*!
- *  
- */
-//=============================================================================
-
-istream & operator >>(istream & load, StdMeshers_QuadranglePreference & hyp)
-{
-  return hyp.LoadFrom( load );
-}
 //================================================================================
 /*!
  * \brief Initialize my parameter values by the mesh built on the geometry
index ec641d15a81e97c7307a2ed258f3af7486aaea15..184072509f0793238e1449370e0a454bcc51728c 100644 (file)
@@ -1,28 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH StdMeshers : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_QuadranglePreference.hxx
 //  Module : SMESH
-
+//
 #ifndef _StdMeshers_QuadranglePreference_HXX_
 #define _StdMeshers_QuadranglePreference_HXX_
 
@@ -45,8 +46,6 @@ class STDMESHERS_EXPORT StdMeshers_QuadranglePreference:public SMESH_Hypothesis
   
   virtual std::ostream & SaveTo(std::ostream & save);
   virtual std::istream & LoadFrom(std::istream & load);
-  friend std::ostream & operator <<(std::ostream & save, StdMeshers_QuadranglePreference & hyp);
-  friend std::istream & operator >>(std::istream & load, StdMeshers_QuadranglePreference & hyp);
 
   /*!
    * \brief Initialize my parameter values by the mesh built on the geometry
index 3a137b109cf2947d97a4c2c0d1b81fdb7d1010c7..3842b4733f56d8d937d25444bfb7de67257cb272 100644 (file)
@@ -1,35 +1,35 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-//  SMESH SMESH : implementaion of SMESH idl descriptions
+
 //  File   : StdMeshers_Quadrangle_2D.cxx
-//           Moved here from SMESH_Quadrangle_2D.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//  $Header$
-//
+
 #include "StdMeshers_Quadrangle_2D.hxx"
 
 #include "StdMeshers_FaceSide.hxx"
 
+#include "StdMeshers_QuadrangleParams.hxx"
+
 #include "SMESH_Gen.hxx"
 #include "SMESH_Mesh.hxx"
 #include "SMESH_subMesh.hxx"
 #include "SMDS_EdgePosition.hxx"
 #include "SMDS_FacePosition.hxx"
 
-#include <BRepTools.hxx>
-#include <BRepTools_WireExplorer.hxx>
 #include <BRep_Tool.hxx>
 #include <Geom_Surface.hxx>
 #include <NCollection_DefineArray2.hxx>
 #include <Precision.hxx>
 #include <TColStd_SequenceOfReal.hxx>
+#include <TColStd_SequenceOfInteger.hxx>
 #include <TColgp_SequenceOfXY.hxx>
 #include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
 #include <TopoDS.hxx>
 
 #include "utilities.h"
@@ -75,15 +77,17 @@ typedef SMESH_Comment TComm;
  */
 //=============================================================================
 
-StdMeshers_Quadrangle_2D::StdMeshers_Quadrangle_2D (int hypId, int studyId, SMESH_Gen* gen)
+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 = (1 << TopAbs_FACE);
+  _compatibleHypothesis.push_back("QuadrangleParams");
   _compatibleHypothesis.push_back("QuadranglePreference");
   _compatibleHypothesis.push_back("TrianglePreference");
-  myTool = 0;
+  myHelper = 0;
 }
 
 //=============================================================================
@@ -111,25 +115,75 @@ bool StdMeshers_Quadrangle_2D::CheckHypothesis
   bool isOk = true;
   aStatus = SMESH_Hypothesis::HYP_OK;
 
-
-  const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape, false);
-  const SMESHDS_Hypothesis *theHyp = 0;
-  
-  if(hyps.size() > 0){
-    theHyp = *hyps.begin();
-    if(strcmp("QuadranglePreference", theHyp->GetName()) == 0) {
-      myQuadranglePreference= true;
-      myTrianglePreference= false; 
+  const list <const SMESHDS_Hypothesis * >& hyps =
+    GetUsedHypothesis(aMesh, aShape, false);
+  const SMESHDS_Hypothesis * aHyp = 0;
+
+  myTriaVertexID = -1;
+  myQuadType = QUAD_STANDARD;
+  myQuadranglePreference = false;
+  myTrianglePreference = false;
+
+  bool isFirstParams = true;
+
+  // First assigned hypothesis (if any) is processed now
+  if (hyps.size() > 0) {
+    aHyp = hyps.front();
+    if (strcmp("QuadrangleParams", aHyp->GetName()) == 0) {
+      const StdMeshers_QuadrangleParams* aHyp1 = 
+        (const StdMeshers_QuadrangleParams*)aHyp;
+      myTriaVertexID = aHyp1->GetTriaVertex();
+      myQuadType = aHyp1->GetQuadType();
+      if (myQuadType == QUAD_QUADRANGLE_PREF ||
+          myQuadType == QUAD_QUADRANGLE_PREF_REVERSED)
+        myQuadranglePreference = true;
+      else if (myQuadType == QUAD_TRIANGLE_PREF)
+        myTrianglePreference = true;
+    }
+    else if (strcmp("QuadranglePreference", aHyp->GetName()) == 0) {
+      isFirstParams = false;
+      myQuadranglePreference = true;
+    }
+    else if (strcmp("TrianglePreference", aHyp->GetName()) == 0){
+      isFirstParams = false;
+      myTrianglePreference = true; 
     }
-    else if(strcmp("TrianglePreference", theHyp->GetName()) == 0){
-      myQuadranglePreference= false;
-      myTrianglePreference= true; 
+    else {
+      isFirstParams = false;
     }
   }
-  else {
-    myQuadranglePreference = false;
-    myTrianglePreference = false;
+
+  // Second(last) assigned hypothesis (if any) is processed now
+  if (hyps.size() > 1) {
+    aHyp = hyps.back();
+    if (isFirstParams) {
+      if (strcmp("QuadranglePreference", aHyp->GetName()) == 0) {
+        myQuadranglePreference = true;
+        myTrianglePreference = false; 
+        myQuadType = QUAD_STANDARD;
+      }
+      else if (strcmp("TrianglePreference", aHyp->GetName()) == 0){
+        myQuadranglePreference = false;
+        myTrianglePreference = true; 
+        myQuadType = QUAD_STANDARD;
+      }
+    }
+    else {
+      const StdMeshers_QuadrangleParams* aHyp2 = 
+        (const StdMeshers_QuadrangleParams*)aHyp;
+      myTriaVertexID = aHyp2->GetTriaVertex();
+
+      if (!myQuadranglePreference && !myTrianglePreference) { // priority of hypos
+        myQuadType = aHyp2->GetQuadType();
+        if (myQuadType == QUAD_QUADRANGLE_PREF ||
+            myQuadType == QUAD_QUADRANGLE_PREF_REVERSED)
+          myQuadranglePreference = true;
+        else if (myQuadType == QUAD_TRIANGLE_PREF)
+          myTrianglePreference = true;
+      }
+    }
   }
+
   return isOk;
 }
 
@@ -148,17 +202,18 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
   SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
   aMesh.GetSubMesh(aShape);
 
-  SMESH_MesherHelper helper(aMesh);
-  myTool = &helper;
+  SMESH_MesherHelper helper (aMesh);
+  myHelper = &helper;
 
-  _quadraticMesh = myTool->IsQuadraticSubMesh(aShape);
+  _quadraticMesh = myHelper->IsQuadraticSubMesh(aShape);
+  myNeedSmooth = false;
 
-  FaceQuadStruct *quad = CheckNbEdges( aMesh, aShape );
-  std::auto_ptr<FaceQuadStruct> quadDeleter( quad ); // to delete quad at exit from Compute()
+  FaceQuadStruct *quad = CheckNbEdges(aMesh, aShape);
+  std::auto_ptr<FaceQuadStruct> quadDeleter (quad); // to delete quad at exit from Compute()
   if (!quad)
     return false;
 
-  if(myQuadranglePreference) {
+  if (myQuadranglePreference) {
     int n1 = quad->side[0]->NbPoints();
     int n2 = quad->side[1]->NbPoints();
     int n3 = quad->side[2]->NbPoints();
@@ -166,9 +221,28 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
     int nfull = n1+n2+n3+n4;
     int ntmp = nfull/2;
     ntmp = ntmp*2;
-    if( nfull==ntmp && ( (n1!=n3) || (n2!=n4) ) ) {
+    if (nfull == ntmp && ((n1 != n3) || (n2 != n4))) {
       // special path for using only quandrangle faces
       bool ok = ComputeQuadPref(aMesh, aShape, quad);
+      if ( ok && myNeedSmooth )
+        Smooth( quad ); 
+      return ok;
+    }
+  }
+  else if (myQuadType == QUAD_REDUCED) {
+    int n1 = quad->side[0]->NbPoints();
+    int n2 = quad->side[1]->NbPoints();
+    int n3 = quad->side[2]->NbPoints();
+    int n4 = quad->side[3]->NbPoints();
+    int n13 = n1 - n3;
+    int n24 = n2 - n4;
+    int n13tmp = n13/2; n13tmp = n13tmp*2;
+    int n24tmp = n24/2; n24tmp = n24tmp*2;
+    if ((n1 == n3 && n2 != n4 && n24tmp == n24) ||
+        (n2 == n4 && n1 != n3 && n13tmp == n13)) {
+      bool ok = ComputeReduced(aMesh, aShape, quad);
+      if ( ok && myNeedSmooth )
+        Smooth( quad ); 
       return ok;
     }
   }
@@ -193,7 +267,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
   Handle(Geom_Surface) S = BRep_Tool::Surface(F);
 
   // internal mesh nodes
-  int i, j, geomFaceID = meshDS->ShapeToIndex( F );
+  int i, j, geomFaceID = meshDS->ShapeToIndex(F);
   for (i = 1; i < nbhoriz - 1; i++) {
     for (j = 1; j < nbvertic - 1; j++) {
       int ij = j * nbhoriz + i;
@@ -237,18 +311,20 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
       b = quad->uv_grid[j * nbhoriz + i + 1].node;
       c = quad->uv_grid[(j + 1) * nbhoriz + i + 1].node;
       d = quad->uv_grid[(j + 1) * nbhoriz + i].node;
-      SMDS_MeshFace* face = myTool->AddFace(a, b, c, d);
-      meshDS->SetMeshElementOnShape(face, geomFaceID);
+      SMDS_MeshFace* face = myHelper->AddFace(a, b, c, d);
+      if (face) {
+        meshDS->SetMeshElementOnShape(face, geomFaceID);
+      }
     }
   }
 
-  const vector<UVPtStruct>& uv_e0 = quad->side[0]->GetUVPtStruct(true,0 );
+  const vector<UVPtStruct>& uv_e0 = quad->side[0]->GetUVPtStruct(true,0);
   const vector<UVPtStruct>& uv_e1 = quad->side[1]->GetUVPtStruct(false,1);
-  const vector<UVPtStruct>& uv_e2 = quad->side[2]->GetUVPtStruct(true,1 );
+  const vector<UVPtStruct>& uv_e2 = quad->side[2]->GetUVPtStruct(true,1);
   const vector<UVPtStruct>& uv_e3 = quad->side[3]->GetUVPtStruct(false,0);
 
-  if ( uv_e0.empty() || uv_e1.empty() || uv_e2.empty() || uv_e3.empty() )
-    return error( COMPERR_BAD_INPUT_MESH );
+  if (uv_e0.empty() || uv_e1.empty() || uv_e2.empty() || uv_e3.empty())
+    return error(COMPERR_BAD_INPUT_MESH);
 
   double eps = Precision::Confusion();
 
@@ -312,9 +388,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
       }
 
       if (near == g) { // make triangle
-        //SMDS_MeshFace* face = meshDS->AddFace(a, b, c);
-        SMDS_MeshFace* face = myTool->AddFace(a, b, c);
-        meshDS->SetMeshElementOnShape(face, geomFaceID);
+        SMDS_MeshFace* face = myHelper->AddFace(a, b, c);
+        if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
       }
       else { // make quadrangle
         if (near - 1 < ilow)
@@ -323,9 +398,9 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
           d = quad->uv_grid[nbhoriz + near - 1].node;
         //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
         
-        if(!myTrianglePreference){
-          SMDS_MeshFace* face = myTool->AddFace(a, b, c, d);
-          meshDS->SetMeshElementOnShape(face, geomFaceID);
+        if (!myTrianglePreference){
+          SMDS_MeshFace* face = myHelper->AddFace(a, b, c, d);
+          if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
         }
         else {
           SplitQuad(meshDS, geomFaceID, a, b, c, d);
@@ -339,9 +414,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
               d = uv_e3[1].node;
             else
               d = quad->uv_grid[nbhoriz + k - 1].node;
-            //SMDS_MeshFace* face = meshDS->AddFace(a, c, d);
-            SMDS_MeshFace* face = myTool->AddFace(a, c, d);
-            meshDS->SetMeshElementOnShape(face, geomFaceID);
+            SMDS_MeshFace* face = myHelper->AddFace(a, c, d);
+            if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
           }
         }
         g = near;
@@ -402,9 +476,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
         }
 
         if (near == g) { // make triangle
-          //SMDS_MeshFace* face = meshDS->AddFace(a, b, c);
-          SMDS_MeshFace* face = myTool->AddFace(a, b, c);
-          meshDS->SetMeshElementOnShape(face, geomFaceID);
+          SMDS_MeshFace* face = myHelper->AddFace(a, b, c);
+          if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
         }
         else { // make quadrangle
           if (near + 1 > iup)
@@ -412,9 +485,9 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
           else
             d = quad->uv_grid[nbhoriz*(nbvertic - 2) + near + 1].node;
           //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
-          if(!myTrianglePreference){
-            SMDS_MeshFace* face = myTool->AddFace(a, b, c, d);
-            meshDS->SetMeshElementOnShape(face, geomFaceID);
+          if (!myTrianglePreference){
+            SMDS_MeshFace* face = myHelper->AddFace(a, b, c, d);
+            if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
           }
           else {
             SplitQuad(meshDS, geomFaceID, a, b, c, d);
@@ -427,9 +500,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
                 d = uv_e1[nbright - 2].node;
               else
                 d = quad->uv_grid[nbhoriz*(nbvertic - 2) + k + 1].node;
-              //SMDS_MeshFace* face = meshDS->AddFace(a, c, d);
-              SMDS_MeshFace* face = myTool->AddFace(a, c, d);
-              meshDS->SetMeshElementOnShape(face, geomFaceID);
+              SMDS_MeshFace* face = myHelper->AddFace(a, c, d);
+              if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
             }
           }
           g = near;
@@ -476,9 +548,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
       }
 
       if (near == g) { // make triangle
-        //SMDS_MeshFace* face = meshDS->AddFace(a, b, c);
-        SMDS_MeshFace* face = myTool->AddFace(a, b, c);
-        meshDS->SetMeshElementOnShape(face, geomFaceID);
+        SMDS_MeshFace* face = myHelper->AddFace(a, b, c);
+        if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
       }
       else { // make quadrangle
         if (near - 1 < jlow)
@@ -487,9 +558,9 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
           d = quad->uv_grid[nbhoriz*near - 2].node;
         //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
 
-        if(!myTrianglePreference){
-          SMDS_MeshFace* face = myTool->AddFace(a, b, c, d);
-          meshDS->SetMeshElementOnShape(face, geomFaceID);
+        if (!myTrianglePreference){
+          SMDS_MeshFace* face = myHelper->AddFace(a, b, c, d);
+          if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
         }
         else {
           SplitQuad(meshDS, geomFaceID, a, b, c, d);
@@ -502,9 +573,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
               d = uv_e0[nbdown - 2].node;
             else
               d = quad->uv_grid[nbhoriz*k - 2].node;
-            //SMDS_MeshFace* face = meshDS->AddFace(a, c, d);
-            SMDS_MeshFace* face = myTool->AddFace(a, c, d);
-            meshDS->SetMeshElementOnShape(face, geomFaceID);
+            SMDS_MeshFace* face = myHelper->AddFace(a, c, d);
+            if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
           }
         }
         g = near;
@@ -548,9 +618,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
         }
 
         if (near == g) { // make triangle
-          //SMDS_MeshFace* face = meshDS->AddFace(a, b, c);
-          SMDS_MeshFace* face = myTool->AddFace(a, b, c);
-          meshDS->SetMeshElementOnShape(face, geomFaceID);
+          SMDS_MeshFace* face = myHelper->AddFace(a, b, c);
+          if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
         }
         else { // make quadrangle
           if (near + 1 > jup)
@@ -558,9 +627,9 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
           else
             d = quad->uv_grid[nbhoriz*(near + 1) + 1].node;
           //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
-          if(!myTrianglePreference){
-            SMDS_MeshFace* face = myTool->AddFace(a, b, c, d);
-            meshDS->SetMeshElementOnShape(face, geomFaceID);
+          if (!myTrianglePreference){
+            SMDS_MeshFace* face = myHelper->AddFace(a, b, c, d);
+            if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
           }
           else {
             SplitQuad(meshDS, geomFaceID, a, b, c, d);
@@ -573,9 +642,8 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
                 d = uv_e2[1].node;
               else
                 d = quad->uv_grid[nbhoriz*(k + 1) + 1].node;
-              //SMDS_MeshFace* face = meshDS->AddFace(a, c, d);
-              SMDS_MeshFace* face = myTool->AddFace(a, c, d);
-              meshDS->SetMeshElementOnShape(face, geomFaceID);
+              SMDS_MeshFace* face = myHelper->AddFace(a, c, d);
+              if (face) meshDS->SetMeshElementOnShape(face, geomFaceID);
             }
           }
           g = near;
@@ -584,10 +652,129 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
     }
   }
 
+  if ( myNeedSmooth )
+    Smooth( quad );
+
   bool isOk = true;
   return isOk;
 }
 
+
+//=============================================================================
+/*!
+ *  Evaluate
+ */
+//=============================================================================
+
+bool StdMeshers_Quadrangle_2D::Evaluate(SMESH_Mesh& aMesh,
+                                        const TopoDS_Shape& aShape,
+                                        MapShapeNbElems& aResMap)
+
+{
+  aMesh.GetSubMesh(aShape);
+
+  std::vector<int> aNbNodes(4);
+  bool IsQuadratic = false;
+  if (!CheckNbEdgesForEvaluate(aMesh, aShape, aResMap, aNbNodes, IsQuadratic)) {
+    std::vector<int> aResVec(SMDSEntity_Last);
+    for (int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
+    SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+    aResMap.insert(std::make_pair(sm,aResVec));
+    SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+    smError.reset(new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
+    return false;
+  }
+
+  if (myQuadranglePreference) {
+    int n1 = aNbNodes[0];
+    int n2 = aNbNodes[1];
+    int n3 = aNbNodes[2];
+    int n4 = aNbNodes[3];
+    int nfull = n1+n2+n3+n4;
+    int ntmp = nfull/2;
+    ntmp = ntmp*2;
+    if (nfull==ntmp && ((n1!=n3) || (n2!=n4))) {
+      // special path for using only quandrangle faces
+      return EvaluateQuadPref(aMesh, aShape, aNbNodes, aResMap, IsQuadratic);
+      //return true;
+    }
+  }
+
+  int nbdown  = aNbNodes[0];
+  int nbup    = aNbNodes[2];
+
+  int nbright = aNbNodes[1];
+  int nbleft  = aNbNodes[3];
+
+  int nbhoriz  = Min(nbdown, nbup);
+  int nbvertic = Min(nbright, nbleft);
+
+  int dh = Max(nbdown, nbup) - nbhoriz;
+  int dv = Max(nbright, nbleft) - nbvertic;
+
+  //int kdh = 0;
+  //if (dh>0) kdh = 1;
+  //int kdv = 0;
+  //if (dv>0) kdv = 1;
+
+  int nbNodes = (nbhoriz-2)*(nbvertic-2);
+  //int nbFaces3 = dh + dv + kdh*(nbvertic-1)*2 + kdv*(nbhoriz-1)*2;
+  int nbFaces3 = dh + dv;
+  //if (kdh==1 && kdv==1) nbFaces3 -= 2;
+  //if (dh>0 && dv>0) nbFaces3 -= 2;
+  //int nbFaces4 = (nbhoriz-1-kdh)*(nbvertic-1-kdv);
+  int nbFaces4 = (nbhoriz-1)*(nbvertic-1);
+
+  std::vector<int> aVec(SMDSEntity_Last);
+  for (int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aVec[i] = 0;
+  if (IsQuadratic) {
+    aVec[SMDSEntity_Quad_Triangle] = nbFaces3;
+    aVec[SMDSEntity_Quad_Quadrangle] = nbFaces4;
+    int nbbndedges = nbdown + nbup + nbright + nbleft -4;
+    int nbintedges = (nbFaces4*4 + nbFaces3*3 - nbbndedges) / 2;
+    aVec[SMDSEntity_Node] = nbNodes + nbintedges;
+    if (aNbNodes.size()==5) {
+      aVec[SMDSEntity_Quad_Triangle] = nbFaces3 + aNbNodes[3] -1;
+      aVec[SMDSEntity_Quad_Quadrangle] = nbFaces4 - aNbNodes[3] +1;
+    }
+  }
+  else {
+    aVec[SMDSEntity_Node] = nbNodes;
+    aVec[SMDSEntity_Triangle] = nbFaces3;
+    aVec[SMDSEntity_Quadrangle] = nbFaces4;
+    if (aNbNodes.size()==5) {
+      aVec[SMDSEntity_Triangle] = nbFaces3 + aNbNodes[3] - 1;
+      aVec[SMDSEntity_Quadrangle] = nbFaces4 - aNbNodes[3] + 1;
+    }
+  }
+  SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+  aResMap.insert(std::make_pair(sm,aVec));
+
+  return true;
+}
+
+
+//================================================================================
+/*!
+ * \brief Return true if only two given edges meat at their common vertex
+ */
+//================================================================================
+
+static bool twoEdgesMeatAtVertex(const TopoDS_Edge& e1,
+                                 const TopoDS_Edge& e2,
+                                 SMESH_Mesh &       mesh)
+{
+  TopoDS_Vertex v;
+  if (!TopExp::CommonVertex(e1, e2, v))
+    return false;
+  TopTools_ListIteratorOfListOfShape ancestIt(mesh.GetAncestors(v));
+  for (; ancestIt.More() ; ancestIt.Next())
+    if (ancestIt.Value().ShapeType() == TopAbs_EDGE)
+      if (!e1.IsSame(ancestIt.Value()) && !e2.IsSame(ancestIt.Value()))
+        return false;
+  return true;
+}
+
 //=============================================================================
 /*!
  *  
@@ -598,7 +785,8 @@ FaceQuadStruct* StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh &         aMes
                                                        const TopoDS_Shape & aShape)
   //throw(SALOME_Exception)
 {
-  const TopoDS_Face & F = TopoDS::Face(aShape);
+  TopoDS_Face F = TopoDS::Face(aShape);
+  if ( F.Orientation() >= TopAbs_INTERNAL ) F.Orientation( TopAbs_FORWARD );
   const bool ignoreMediumNodes = _quadraticMesh;
 
   // verify 1 wire only, with 4 edges
@@ -613,50 +801,157 @@ FaceQuadStruct* StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh &         aMes
   FaceQuadStruct* quad = new FaceQuadStruct;
   quad->uv_grid = 0;
   quad->side.reserve(nbEdgesInWire.front());
+  quad->face = F;
 
   int nbSides = 0;
   list< TopoDS_Edge >::iterator edgeIt = edges.begin();
-  if ( nbEdgesInWire.front() == 4 ) { // exactly 4 edges
-    for ( ; edgeIt != edges.end(); ++edgeIt, nbSides++ )
-      quad->side.push_back( new StdMeshers_FaceSide(F, *edgeIt, &aMesh,
+  if (nbEdgesInWire.front() == 3) // exactly 3 edges
+  {
+    SMESH_Comment comment;
+    SMESHDS_Mesh* meshDS = aMesh.GetMeshDS();
+    if (myTriaVertexID == -1)
+    {
+      comment << "No Base vertex parameter provided for a trilateral geometrical face";
+    }
+    else
+    {
+      TopoDS_Vertex V = TopoDS::Vertex(meshDS->IndexToShape(myTriaVertexID));
+      if (!V.IsNull()) {
+        TopoDS_Edge E1,E2,E3;
+        for (; edgeIt != edges.end(); ++edgeIt) {
+          TopoDS_Edge E =  *edgeIt;
+          TopoDS_Vertex VF, VL;
+          TopExp::Vertices(E, VF, VL, true);
+          if (VF.IsSame(V))
+            E1 = E;
+          else if (VL.IsSame(V))
+            E3 = E;
+          else
+            E2 = E;
+        }
+        if (!E1.IsNull() && !E2.IsNull() && !E3.IsNull())
+        {
+          quad->side.push_back(new StdMeshers_FaceSide(F, E1, &aMesh, true, ignoreMediumNodes));
+          quad->side.push_back(new StdMeshers_FaceSide(F, E2, &aMesh, true, ignoreMediumNodes));
+          quad->side.push_back(new StdMeshers_FaceSide(F, E3, &aMesh, false,ignoreMediumNodes));
+          const vector<UVPtStruct>& UVPSleft  = quad->side[0]->GetUVPtStruct(true,0);
+          /*  vector<UVPtStruct>& UVPStop   = */quad->side[1]->GetUVPtStruct(false,1);
+          /*  vector<UVPtStruct>& UVPSright = */quad->side[2]->GetUVPtStruct(true,1);
+          const SMDS_MeshNode* aNode = UVPSleft[0].node;
+          gp_Pnt2d aPnt2d(UVPSleft[0].u, UVPSleft[0].v);
+          quad->side.push_back(new StdMeshers_FaceSide(aNode, aPnt2d, quad->side[1]));
+          return quad;
+        }
+      }
+      comment << "Invalid Base vertex parameter: " << myTriaVertexID << " is not among [";
+      TopTools_MapOfShape vMap;
+      for (TopExp_Explorer v(aShape, TopAbs_VERTEX); v.More(); v.Next())
+        if (vMap.Add(v.Current()))
+          comment << meshDS->ShapeToIndex(v.Current()) << (vMap.Extent()==3 ? "]" : ", ");
+    }
+    error(comment);
+    delete quad;
+    return quad = 0;
+  }
+  else if (nbEdgesInWire.front() == 4) // exactly 4 edges
+  {
+    for (; edgeIt != edges.end(); ++edgeIt, nbSides++)
+      quad->side.push_back(new StdMeshers_FaceSide(F, *edgeIt, &aMesh,
                                                     nbSides<TOP_SIDE, ignoreMediumNodes));
   }
-  else if ( nbEdgesInWire.front() > 4 ) { // more than 4 edges - try to unite some
+  else if (nbEdgesInWire.front() > 4) // more than 4 edges - try to unite some
+  {
     list< TopoDS_Edge > sideEdges;
-    while ( !edges.empty()) {
+    vector< int > degenSides;
+    while (!edges.empty()) {
       sideEdges.clear();
-      sideEdges.splice( sideEdges.end(), edges, edges.begin()); // edges.front() -> sideEdges.end()
+      sideEdges.splice(sideEdges.end(), edges, edges.begin()); // edges.front() -> sideEdges.end()
       bool sameSide = true;
-      while ( !edges.empty() && sameSide ) {
-        sameSide = SMESH_Algo::IsContinuous( sideEdges.back(), edges.front() );
-        if ( sameSide )
-          sideEdges.splice( sideEdges.end(), edges, edges.begin());
+      while (!edges.empty() && sameSide) {
+        sameSide = SMESH_Algo::IsContinuous(sideEdges.back(), edges.front());
+        if (sameSide)
+          sideEdges.splice(sideEdges.end(), edges, edges.begin());
       }
-      if ( nbSides == 0 ) { // go backward from the first edge
+      if (nbSides == 0) { // go backward from the first edge
         sameSide = true;
-        while ( !edges.empty() && sameSide ) {
-          sameSide = SMESH_Algo::IsContinuous( sideEdges.front(), edges.back() );
-          if ( sameSide )
-            sideEdges.splice( sideEdges.begin(), edges, --edges.end());
+        while (!edges.empty() && sameSide) {
+          sameSide = SMESH_Algo::IsContinuous(sideEdges.front(), edges.back());
+          if (sameSide)
+            sideEdges.splice(sideEdges.begin(), edges, --edges.end());
         }
       }
-      quad->side.push_back( new StdMeshers_FaceSide(F, sideEdges, &aMesh,
+      if ( sideEdges.size() == 1 && BRep_Tool::Degenerated( sideEdges.front() ))
+        degenSides.push_back( nbSides );
+
+      quad->side.push_back(new StdMeshers_FaceSide(F, sideEdges, &aMesh,
                                                     nbSides<TOP_SIDE, ignoreMediumNodes));
       ++nbSides;
     }
+    if ( !degenSides.empty() && nbSides - degenSides.size() == 4 )
+    {
+      myNeedSmooth = true;
+      for ( unsigned i = TOP_SIDE; i < quad->side.size(); ++i )
+        quad->side[i]->Reverse();
+
+      for ( int i = degenSides.size()-1; i > -1; --i )
+      {
+        StdMeshers_FaceSide* degenSide = quad->side[ degenSides[ i ]];
+        delete degenSide;
+        quad->side.erase( quad->side.begin() + degenSides[ i ] );
+      }
+      for ( unsigned i = TOP_SIDE; i < quad->side.size(); ++i )
+        quad->side[i]->Reverse();
+
+      nbSides -= degenSides.size();
+    }
+    // issue 20222. Try to unite only edges shared by two same faces
+    if (nbSides < 4) {
+      // delete found sides
+      { FaceQuadStruct cleaner(*quad); }
+      quad->side.clear();
+      quad->side.reserve(nbEdgesInWire.front());
+      nbSides = 0;
+
+      SMESH_Block::GetOrderedEdges (F, V, edges, nbEdgesInWire);
+      while (!edges.empty()) {
+        sideEdges.clear();
+        sideEdges.splice(sideEdges.end(), edges, edges.begin());
+        bool sameSide = true;
+        while (!edges.empty() && sameSide) {
+          sameSide =
+            SMESH_Algo::IsContinuous(sideEdges.back(), edges.front()) &&
+            twoEdgesMeatAtVertex(sideEdges.back(), edges.front(), aMesh);
+          if (sameSide)
+            sideEdges.splice(sideEdges.end(), edges, edges.begin());
+        }
+        if (nbSides == 0) { // go backward from the first edge
+          sameSide = true;
+          while (!edges.empty() && sameSide) {
+            sameSide =
+              SMESH_Algo::IsContinuous(sideEdges.front(), edges.back()) &&
+              twoEdgesMeatAtVertex(sideEdges.front(), edges.back(), aMesh);
+            if (sameSide)
+              sideEdges.splice(sideEdges.begin(), edges, --edges.end());
+          }
+        }
+        quad->side.push_back(new StdMeshers_FaceSide(F, sideEdges, &aMesh,
+                                                      nbSides<TOP_SIDE, ignoreMediumNodes));
+        ++nbSides;
+      }
+    }
   }
   if (nbSides != 4) {
 #ifdef _DEBUG_
-    MESSAGE ( "StdMeshers_Quadrangle_2D. Edge IDs of " << nbSides << " sides:\n" );
-    for ( int i = 0; i < nbSides; ++i ) {
-      MESSAGE ( " ( " );
-      for ( int e = 0; e < quad->side[i]->NbEdges(); ++e )
-        MESSAGE ( myTool->GetMeshDS()->ShapeToIndex( quad->side[i]->Edge( e )) << " " );
-      MESSAGE ( ")\n" );
+    MESSAGE ("StdMeshers_Quadrangle_2D. Edge IDs of " << nbSides << " sides:\n");
+    for (int i = 0; i < nbSides; ++i) {
+      MESSAGE (" (");
+      for (int e = 0; e < quad->side[i]->NbEdges(); ++e)
+        MESSAGE (myHelper->GetMeshDS()->ShapeToIndex(quad->side[i]->Edge(e)) << " ");
+      MESSAGE (")\n");
     }
     //cout << endl;
 #endif
-    if ( !nbSides )
+    if (!nbSides)
       nbSides = nbEdgesInWire.front();
     error(COMPERR_BAD_SHAPE, TComm("Face must have 4 sides but not ") << nbSides);
     delete quad;
@@ -666,6 +961,193 @@ FaceQuadStruct* StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh &         aMes
   return quad;
 }
 
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+bool StdMeshers_Quadrangle_2D::CheckNbEdgesForEvaluate(SMESH_Mesh& aMesh,
+                                                       const TopoDS_Shape & aShape,
+                                                       MapShapeNbElems& aResMap,
+                                                       std::vector<int>& aNbNodes,
+                                                       bool& IsQuadratic)
+
+{
+  const TopoDS_Face & F = TopoDS::Face(aShape);
+
+  // verify 1 wire only, with 4 edges
+  TopoDS_Vertex V;
+  list< TopoDS_Edge > edges;
+  list< int > nbEdgesInWire;
+  int nbWire = SMESH_Block::GetOrderedEdges (F, V, edges, nbEdgesInWire);
+  if (nbWire != 1) {
+    return false;
+  }
+
+  aNbNodes.resize(4);
+
+  int nbSides = 0;
+  list< TopoDS_Edge >::iterator edgeIt = edges.begin();
+  SMESH_subMesh * sm = aMesh.GetSubMesh(*edgeIt);
+  MapShapeNbElemsItr anIt = aResMap.find(sm);
+  if (anIt==aResMap.end()) {
+    return false;
+  }
+  std::vector<int> aVec = (*anIt).second;
+  IsQuadratic = (aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge]);
+  if (nbEdgesInWire.front() == 3) { // exactly 3 edges
+    if (myTriaVertexID>0) {
+      SMESHDS_Mesh* meshDS = aMesh.GetMeshDS();
+      TopoDS_Vertex V = TopoDS::Vertex(meshDS->IndexToShape(myTriaVertexID));
+      if (!V.IsNull()) {
+        TopoDS_Edge E1,E2,E3;
+        for (; edgeIt != edges.end(); ++edgeIt) {
+          TopoDS_Edge E =  TopoDS::Edge(*edgeIt);
+          TopoDS_Vertex VF, VL;
+          TopExp::Vertices(E, VF, VL, true);
+          if (VF.IsSame(V))
+            E1 = E;
+          else if (VL.IsSame(V))
+            E3 = E;
+          else
+            E2 = E;
+        }
+        SMESH_subMesh * sm = aMesh.GetSubMesh(E1);
+        MapShapeNbElemsItr anIt = aResMap.find(sm);
+        if (anIt==aResMap.end()) return false;
+        std::vector<int> aVec = (*anIt).second;
+        if (IsQuadratic)
+          aNbNodes[0] = (aVec[SMDSEntity_Node]-1)/2 + 2;
+        else
+          aNbNodes[0] = aVec[SMDSEntity_Node] + 2;
+        sm = aMesh.GetSubMesh(E2);
+        anIt = aResMap.find(sm);
+        if (anIt==aResMap.end()) return false;
+        aVec = (*anIt).second;
+        if (IsQuadratic)
+          aNbNodes[1] = (aVec[SMDSEntity_Node]-1)/2 + 2;
+        else
+          aNbNodes[1] = aVec[SMDSEntity_Node] + 2;
+        sm = aMesh.GetSubMesh(E3);
+        anIt = aResMap.find(sm);
+        if (anIt==aResMap.end()) return false;
+        aVec = (*anIt).second;
+        if (IsQuadratic)
+          aNbNodes[2] = (aVec[SMDSEntity_Node]-1)/2 + 2;
+        else
+          aNbNodes[2] = aVec[SMDSEntity_Node] + 2;
+        aNbNodes[3] = aNbNodes[1];
+        aNbNodes.resize(5);
+        nbSides = 4;
+      }
+    }
+  }
+  if (nbEdgesInWire.front() == 4) { // exactly 4 edges
+    for (; edgeIt != edges.end(); edgeIt++) {
+      SMESH_subMesh * sm = aMesh.GetSubMesh(*edgeIt);
+      MapShapeNbElemsItr anIt = aResMap.find(sm);
+      if (anIt==aResMap.end()) {
+        return false;
+      }
+      std::vector<int> aVec = (*anIt).second;
+      if (IsQuadratic)
+        aNbNodes[nbSides] = (aVec[SMDSEntity_Node]-1)/2 + 2;
+      else
+        aNbNodes[nbSides] = aVec[SMDSEntity_Node] + 2;
+      nbSides++;
+    }
+  }
+  else if (nbEdgesInWire.front() > 4) { // more than 4 edges - try to unite some
+    list< TopoDS_Edge > sideEdges;
+    while (!edges.empty()) {
+      sideEdges.clear();
+      sideEdges.splice(sideEdges.end(), edges, edges.begin()); // edges.front() -> sideEdges.end()
+      bool sameSide = true;
+      while (!edges.empty() && sameSide) {
+        sameSide = SMESH_Algo::IsContinuous(sideEdges.back(), edges.front());
+        if (sameSide)
+          sideEdges.splice(sideEdges.end(), edges, edges.begin());
+      }
+      if (nbSides == 0) { // go backward from the first edge
+        sameSide = true;
+        while (!edges.empty() && sameSide) {
+          sameSide = SMESH_Algo::IsContinuous(sideEdges.front(), edges.back());
+          if (sameSide)
+            sideEdges.splice(sideEdges.begin(), edges, --edges.end());
+        }
+      }
+      list<TopoDS_Edge>::iterator ite = sideEdges.begin();
+      aNbNodes[nbSides] = 1;
+      for (; ite!=sideEdges.end(); ite++) {
+        SMESH_subMesh * sm = aMesh.GetSubMesh(*ite);
+        MapShapeNbElemsItr anIt = aResMap.find(sm);
+        if (anIt==aResMap.end()) {
+          return false;
+        }
+        std::vector<int> aVec = (*anIt).second;
+        if (IsQuadratic)
+          aNbNodes[nbSides] += (aVec[SMDSEntity_Node]-1)/2 + 1;
+        else
+          aNbNodes[nbSides] += aVec[SMDSEntity_Node] + 1;
+      }
+      ++nbSides;
+    }
+    // issue 20222. Try to unite only edges shared by two same faces
+    if (nbSides < 4) {
+      nbSides = 0;
+      SMESH_Block::GetOrderedEdges (F, V, edges, nbEdgesInWire);
+      while (!edges.empty()) {
+        sideEdges.clear();
+        sideEdges.splice(sideEdges.end(), edges, edges.begin());
+        bool sameSide = true;
+        while (!edges.empty() && sameSide) {
+          sameSide =
+            SMESH_Algo::IsContinuous(sideEdges.back(), edges.front()) &&
+            twoEdgesMeatAtVertex(sideEdges.back(), edges.front(), aMesh);
+          if (sameSide)
+            sideEdges.splice(sideEdges.end(), edges, edges.begin());
+        }
+        if (nbSides == 0) { // go backward from the first edge
+          sameSide = true;
+          while (!edges.empty() && sameSide) {
+            sameSide =
+              SMESH_Algo::IsContinuous(sideEdges.front(), edges.back()) &&
+              twoEdgesMeatAtVertex(sideEdges.front(), edges.back(), aMesh);
+            if (sameSide)
+              sideEdges.splice(sideEdges.begin(), edges, --edges.end());
+          }
+        }
+        list<TopoDS_Edge>::iterator ite = sideEdges.begin();
+        aNbNodes[nbSides] = 1;
+        for (; ite!=sideEdges.end(); ite++) {
+          SMESH_subMesh * sm = aMesh.GetSubMesh(*ite);
+          MapShapeNbElemsItr anIt = aResMap.find(sm);
+          if (anIt==aResMap.end()) {
+            return false;
+          }
+          std::vector<int> aVec = (*anIt).second;
+          if (IsQuadratic)
+            aNbNodes[nbSides] += (aVec[SMDSEntity_Node]-1)/2 + 1;
+          else
+            aNbNodes[nbSides] += aVec[SMDSEntity_Node] + 1;
+        }
+        ++nbSides;
+      }
+    }
+  }
+  if (nbSides != 4) {
+    if (!nbSides)
+      nbSides = nbEdgesInWire.front();
+    error(COMPERR_BAD_SHAPE, TComm("Face must have 4 sides but not ") << nbSides);
+    return false;
+  }
+
+  return true;
+}
+
+
 //=============================================================================
 /*!
  *  CheckAnd2Dcompute
@@ -681,13 +1163,12 @@ FaceQuadStruct *StdMeshers_Quadrangle_2D::CheckAnd2Dcompute
 
   FaceQuadStruct *quad = CheckNbEdges(aMesh, aShape);
 
-  if(!quad) return 0;
+  if (!quad) return 0;
 
   // set normalized grid on unit square in parametric domain
   bool stat = SetNormalizedGrid(aMesh, aShape, quad);
-  if(!stat) {
-    if(!quad)
-      delete quad;
+  if (!stat) {
+    if (quad) delete quad;
     quad = 0;
   }
 
@@ -711,13 +1192,21 @@ faceQuadStruct::~faceQuadStruct()
 namespace {
   inline const vector<UVPtStruct>& GetUVPtStructIn(FaceQuadStruct* quad, int i, int nbSeg)
   {
-    bool   isXConst   = ( i == BOTTOM_SIDE || i == TOP_SIDE );
-    double constValue = ( i == BOTTOM_SIDE || i == LEFT_SIDE ) ? 0 : 1;
+    bool   isXConst   = (i == BOTTOM_SIDE || i == TOP_SIDE);
+    double constValue = (i == BOTTOM_SIDE || i == LEFT_SIDE) ? 0 : 1;
     return
       quad->isEdgeOut[i] ?
       quad->side[i]->SimulateUVPtStruct(nbSeg,isXConst,constValue) :
       quad->side[i]->GetUVPtStruct(isXConst,constValue);
   }
+  inline gp_UV CalcUV(double x, double y,
+                      const gp_UV& a0,const gp_UV& a1,const gp_UV& a2,const gp_UV& a3,
+                      const gp_UV& p0,const gp_UV& p1,const gp_UV& p2,const gp_UV& p3)
+  {
+    return
+      ((1 - y) * p0 + x * p1 + y * p2 + (1 - x) * p3 ) -
+      ((1 - x) * (1 - y) * a0 + x * (1 - y) * a1 + x * y * a2 + (1 - x) * y * a3);
+  }
 }
 
 //=============================================================================
@@ -730,10 +1219,10 @@ bool StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh,
                                                   const TopoDS_Shape& aShape,
                                                   FaceQuadStruct* & quad) //throw (SALOME_Exception)
 {
-  // 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é
+  // 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é
 
 //  MESSAGE("StdMeshers_Quadrangle_2D::SetNormalizedGrid");
 //  const TopoDS_Face& F = TopoDS::Face(aShape);
@@ -764,14 +1253,17 @@ bool StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh,
 
   UVPtStruct *uv_grid = quad->uv_grid = new UVPtStruct[nbvertic * nbhoriz];
 
-  const vector<UVPtStruct>& uv_e0 = GetUVPtStructIn( quad, 0, nbhoriz - 1 );
-  const vector<UVPtStruct>& uv_e1 = GetUVPtStructIn( quad, 1, nbvertic - 1 );
-  const vector<UVPtStruct>& uv_e2 = GetUVPtStructIn( quad, 2, nbhoriz - 1 );
-  const vector<UVPtStruct>& uv_e3 = GetUVPtStructIn( quad, 3, nbvertic - 1 );
+  const vector<UVPtStruct>& uv_e0 = GetUVPtStructIn(quad, 0, nbhoriz - 1);
+  const vector<UVPtStruct>& uv_e1 = GetUVPtStructIn(quad, 1, nbvertic - 1);
+  const vector<UVPtStruct>& uv_e2 = GetUVPtStructIn(quad, 2, nbhoriz - 1);
+  const vector<UVPtStruct>& uv_e3 = GetUVPtStructIn(quad, 3, nbvertic - 1);
 
-  if ( uv_e0.empty() || uv_e1.empty() || uv_e2.empty() || uv_e3.empty() )
-    //return error( "Can't find nodes on sides");
-    return error( COMPERR_BAD_INPUT_MESH );
+  if (uv_e0.empty() || uv_e1.empty() || uv_e2.empty() || uv_e3.empty())
+    //return error("Can't find nodes on sides");
+    return error(COMPERR_BAD_INPUT_MESH);
+
+  if ( myNeedSmooth )
+    UpdateDegenUV( quad );
 
   // nodes Id on "in" edges
   if (! quad->isEdgeOut[0]) {
@@ -804,17 +1296,15 @@ bool StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh,
   }
 
   // normalized 2d values on grid
-  for (int i = 0; i < nbhoriz; i++)
-  {
-    for (int j = 0; j < nbvertic; j++)
-    {
+  for (int i = 0; i < nbhoriz; i++) {
+    for (int j = 0; j < nbvertic; j++) {
       int ij = j * nbhoriz + 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
+      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
+      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);
@@ -826,15 +1316,13 @@ bool StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh,
   }
 
   // 4 --- projection on 2d domain (u,v)
-  gp_UV a0( uv_e0.front().u, uv_e0.front().v );
-  gp_UV a1( uv_e0.back().u,  uv_e0.back().v );
-  gp_UV a2( uv_e2.back().u,  uv_e2.back().v );
-  gp_UV a3( uv_e2.front().u, uv_e2.front().v );
+  gp_UV a0(uv_e0.front().u, uv_e0.front().v);
+  gp_UV a1(uv_e0.back().u,  uv_e0.back().v);
+  gp_UV a2(uv_e2.back().u,  uv_e2.back().v);
+  gp_UV a3(uv_e2.front().u, uv_e2.front().v);
 
-  for (int i = 0; i < nbhoriz; i++)
-  {
-    for (int j = 0; j < nbvertic; j++)
-    {
+  for (int i = 0; i < nbhoriz; i++) {
+    for (int j = 0; j < nbvertic; j++) {
       int ij = j * nbhoriz + i;
       double x = uv_grid[ij].x;
       double y = uv_grid[ij].y;
@@ -849,8 +1337,7 @@ bool StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh,
       gp_UV p2 = quad->side[2]->Value2d(param_2).XY();
       gp_UV p3 = quad->side[3]->Value2d(param_3).XY();
 
-      gp_UV uv = (1 - y) * p0 + x * p1 + y * p2 + (1 - x) * p3;
-      uv -= (1 - x) * (1 - y) * a0 + x * (1 - y) * a1 + x * y * a2 + (1 - x) * y * a3;
+      gp_UV uv = CalcUV(x,y, a0,a1,a2,a3, p0,p1,p2,p3);
 
       uv_grid[ij].u = uv.X();
       uv_grid[ij].v = uv.Y();
@@ -867,11 +1354,11 @@ bool StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh,
 static void ShiftQuad(FaceQuadStruct* quad, const int num, bool)
 {
   StdMeshers_FaceSide* side[4] = { quad->side[0], quad->side[1], quad->side[2], quad->side[3] };
-  for (int i = BOTTOM_SIDE; i < NB_SIDES; ++i ) {
-    int id = ( i + num ) % NB_SIDES;
-    bool wasForward = ( i < TOP_SIDE );
-    bool newForward = ( id < TOP_SIDE );
-    if ( wasForward != newForward )
+  for (int i = BOTTOM_SIDE; i < NB_SIDES; ++i) {
+    int id = (i + num) % NB_SIDES;
+    bool wasForward = (i < TOP_SIDE);
+    bool newForward = (id < TOP_SIDE);
+    if (wasForward != newForward)
       side[ i ]->Reverse();
     quad->side[ id ] = side[ i ];
   }
@@ -887,9 +1374,9 @@ static gp_UV CalcUV(double x0, double x1, double y0, double y1,
                     const gp_UV& a0, const gp_UV& a1,
                     const gp_UV& a2, const gp_UV& a3)
 {
-  const vector<UVPtStruct>& uv_eb = quad->side[0]->GetUVPtStruct(true,0 );
+  const vector<UVPtStruct>& uv_eb = quad->side[0]->GetUVPtStruct(true,0);
   const vector<UVPtStruct>& uv_er = quad->side[1]->GetUVPtStruct(false,1);
-  const vector<UVPtStruct>& uv_et = quad->side[2]->GetUVPtStruct(true,1 );
+  const vector<UVPtStruct>& uv_et = quad->side[2]->GetUVPtStruct(true,1);
   const vector<UVPtStruct>& uv_el = quad->side[3]->GetUVPtStruct(false,0);
 
   double x = (x0 + y0 * (x1 - x0)) / (1 - (y1 - y0) * (x1 - x0));
@@ -905,9 +1392,7 @@ static gp_UV CalcUV(double x0, double x1, double y0, double y1,
   gp_UV p2 = quad->side[TOP_SIDE   ]->Value2d(param_t).XY();
   gp_UV p3 = quad->side[LEFT_SIDE  ]->Value2d(param_l).XY();
 
-  gp_UV uv = p0 * (1 - y) + p1 * x + p2 * y + p3 * (1 - x);
-
-  uv -= (1 - x) * (1 - y) * a0 + x * (1 - y) * a1 + x * y * a2 + (1 - x) * y * a3;
+  gp_UV uv = CalcUV(x,y, a0,a1,a2,a3, p0,p1,p2,p3);
 
   return uv;
 }
@@ -922,27 +1407,12 @@ static gp_UV CalcUV2(double x, double y,
                      const gp_UV& a0, const gp_UV& a1,
                      const gp_UV& a2, const gp_UV& a3)
 {
-  const vector<UVPtStruct>& uv_eb = quad->side[0]->GetUVPtStruct(true,0 );
-  const vector<UVPtStruct>& uv_er = quad->side[1]->GetUVPtStruct(false,1);
-  const vector<UVPtStruct>& uv_et = quad->side[2]->GetUVPtStruct(true,1 );
-  const vector<UVPtStruct>& uv_el = quad->side[3]->GetUVPtStruct(false,0);
+  gp_UV p0 = quad->side[BOTTOM_SIDE]->Value2d(x).XY();
+  gp_UV p1 = quad->side[RIGHT_SIDE ]->Value2d(y).XY();
+  gp_UV p2 = quad->side[TOP_SIDE   ]->Value2d(x).XY();
+  gp_UV p3 = quad->side[LEFT_SIDE  ]->Value2d(y).XY();
 
-  //double x = (x0 + y0 * (x1 - x0)) / (1 - (y1 - y0) * (x1 - x0));
-  //double y = y0 + x * (y1 - y0);
-
-  double param_b = uv_eb[0].normParam + x * (uv_eb.back().normParam - uv_eb[0].normParam);
-  double param_t = uv_et[0].normParam + x * (uv_et.back().normParam - uv_et[0].normParam);
-  double param_r = uv_er[0].normParam + y * (uv_er.back().normParam - uv_er[0].normParam);
-  double param_l = uv_el[0].normParam + y * (uv_el.back().normParam - uv_el[0].normParam);
-
-  gp_UV p0 = quad->side[BOTTOM_SIDE]->Value2d(param_b).XY();
-  gp_UV p1 = quad->side[RIGHT_SIDE ]->Value2d(param_r).XY();
-  gp_UV p2 = quad->side[TOP_SIDE   ]->Value2d(param_t).XY();
-  gp_UV p3 = quad->side[LEFT_SIDE  ]->Value2d(param_l).XY();
-
-  gp_UV uv = p0 * (1 - y) + p1 * x + p2 * y + p3 * (1 - x);
-
-  uv -= (1 - x) * (1 - y) * a0 + x * (1 - y) * a1 + x * y * a2 + (1 - x) * y * a3;
+  gp_UV uv = CalcUV(x,y, a0,a1,a2,a3, p0,p1,p2,p3);
 
   return uv;
 }
@@ -962,20 +1432,14 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh &        aMesh,
   // of meshing after implementation new variant
   // for bug 0016220 from Mantis.
   bool OldVersion = false;
+  if (myQuadType == QUAD_QUADRANGLE_PREF_REVERSED)
+    OldVersion = true;
 
   SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
   const TopoDS_Face& F = TopoDS::Face(aShape);
   Handle(Geom_Surface) S = BRep_Tool::Surface(F);
-//  const TopoDS_Wire& W = BRepTools::OuterWire(F);
   bool WisF = true;
-//   if(W.Orientation()==TopAbs_FORWARD) 
-//     WisF = true;
-  //if(WisF) cout<<"W is FORWARD"<<endl;
-  //else cout<<"W is REVERSED"<<endl;
-//   bool FisF = (F.Orientation()==TopAbs_FORWARD);
-//   if(!FisF) WisF = !WisF;
-//  WisF = FisF;
-  int i,j,geomFaceID = meshDS->ShapeToIndex( F );
+  int i,j,geomFaceID = meshDS->ShapeToIndex(F);
 
   int nb = quad->side[0]->NbPoints();
   int nr = quad->side[1]->NbPoints();
@@ -984,8 +1448,8 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh &        aMesh,
   int dh = abs(nb-nt);
   int dv = abs(nr-nl);
 
-  if( dh>=dv ) {
-    if( nt>nb ) {
+  if (dh>=dv) {
+    if (nt>nb) {
       // it is a base case => not shift quad but me be replacement is need
       ShiftQuad(quad,0,WisF);
     }
@@ -995,7 +1459,7 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh &        aMesh,
     }
   }
   else {
-    if( nr>nl ) {
+    if (nr>nl) {
       // we have to shift quad on 1
       ShiftQuad(quad,1,WisF);
     }
@@ -1044,7 +1508,7 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh &        aMesh,
   //      0------------0
   //       0  bottom  1
 
-  if(dh>dv) {
+  if (dh>dv) {
     addv = (dh-dv)/2;
     nbv = nbv + addv;
   }
@@ -1053,79 +1517,84 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh &        aMesh,
     nbh = nbh + addh;
   }
 
-  const vector<UVPtStruct>& uv_eb = quad->side[0]->GetUVPtStruct(true,0 );
+  const vector<UVPtStruct>& uv_eb = quad->side[0]->GetUVPtStruct(true,0);
   const vector<UVPtStruct>& uv_er = quad->side[1]->GetUVPtStruct(false,1);
-  const vector<UVPtStruct>& uv_et = quad->side[2]->GetUVPtStruct(true,1 );
+  const vector<UVPtStruct>& uv_et = quad->side[2]->GetUVPtStruct(true,1);
   const vector<UVPtStruct>& uv_el = quad->side[3]->GetUVPtStruct(false,0);
 
+  if (uv_eb.size() != nb || uv_er.size() != nr || uv_et.size() != nt || uv_el.size() != nl)
+    return error(COMPERR_BAD_INPUT_MESH);
+
+  if ( myNeedSmooth )
+    UpdateDegenUV( quad );
+
   // arrays for normalized params
   //cout<<"Dump B:"<<endl;
   TColStd_SequenceOfReal npb, npr, npt, npl;
-  for(i=0; i<nb; i++) {
+  for (i=0; i<nb; i++) {
     npb.Append(uv_eb[i].normParam);
     //cout<<"i="<<i<<" par="<<uv_eb[i].normParam<<" npar="<<uv_eb[i].normParam;
     //const SMDS_MeshNode* N = uv_eb[i].node;
     //cout<<" node("<<N->X()<<","<<N->Y()<<","<<N->Z()<<")"<<endl;
   }
-  for(i=0; i<nr; i++) {
+  for (i=0; i<nr; i++) {
     npr.Append(uv_er[i].normParam);
   }
-  for(i=0; i<nt; i++) {
+  for (i=0; i<nt; i++) {
     npt.Append(uv_et[i].normParam);
   }
-  for(i=0; i<nl; i++) {
+  for (i=0; i<nl; i++) {
     npl.Append(uv_el[i].normParam);
   }
 
   int dl,dr;
-  if(OldVersion) {
+  if (OldVersion) {
     // add some params to right and left after the first param
     // insert to right
     dr = nbv - nr;
     double dpr = (npr.Value(2) - npr.Value(1))/(dr+1);
-    for(i=1; i<=dr; i++) {
+    for (i=1; i<=dr; i++) {
       npr.InsertAfter(1,npr.Value(2)-dpr);
     }
     // insert to left
     dl = nbv - nl;
     dpr = (npl.Value(2) - npl.Value(1))/(dl+1);
-    for(i=1; i<=dl; i++) {
+    for (i=1; i<=dl; i++) {
       npl.InsertAfter(1,npl.Value(2)-dpr);
     }
   }
   //cout<<"npb:";
-  //for(i=1; i<=npb.Length(); i++) {
+  //for (i=1; i<=npb.Length(); i++) {
   //  cout<<" "<<npb.Value(i);
   //}
   //cout<<endl;
   
-  gp_XY a0( uv_eb.front().u, uv_eb.front().v );
-  gp_XY a1( uv_eb.back().u,  uv_eb.back().v );
-  gp_XY a2( uv_et.back().u,  uv_et.back().v );
-  gp_XY a3( uv_et.front().u, uv_et.front().v );
+  gp_XY a0(uv_eb.front().u, uv_eb.front().v);
+  gp_XY a1(uv_eb.back().u,  uv_eb.back().v);
+  gp_XY a2(uv_et.back().u,  uv_et.back().v);
+  gp_XY a3(uv_et.front().u, uv_et.front().v);
   //cout<<" a0("<<a0.X()<<","<<a0.Y()<<")"<<" a1("<<a1.X()<<","<<a1.Y()<<")"
   //    <<" a2("<<a2.X()<<","<<a2.Y()<<")"<<" a3("<<a3.X()<<","<<a3.Y()<<")"<<endl;
 
   int nnn = Min(nr,nl);
   // auxilary sequence of XY for creation nodes
   // in the bottom part of central domain
-  // it's length must be == nbv-nnn-1
-  TColgp_SequenceOfXY UVL;
-  TColgp_SequenceOfXY UVR;
+  // Length of UVL and UVR must be == nbv-nnn
+  TColgp_SequenceOfXY UVL, UVR, UVT;
 
-  if(OldVersion) {
+  if (OldVersion) {
     // step1: create faces for left domain
     StdMeshers_Array2OfNode NodesL(1,dl+1,1,nl);
     // add left nodes
-    for(j=1; j<=nl; j++)
+    for (j=1; j<=nl; j++)
       NodesL.SetValue(1,j,uv_el[j-1].node);
-    if(dl>0) {
+    if (dl>0) {
       // add top nodes
-      for(i=1; i<=dl; i++) 
+      for (i=1; i<=dl; i++) 
         NodesL.SetValue(i+1,nl,uv_et[i].node);
       // create and add needed nodes
       TColgp_SequenceOfXY UVtmp;
-      for(i=1; i<=dl; i++) {
+      for (i=1; i<=dl; i++) {
         double x0 = npt.Value(i+1);
         double x1 = x0;
         // diagonal node
@@ -1136,9 +1605,9 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh &        aMesh,
         SMDS_MeshNode * N = meshDS->AddNode(P.X(), P.Y(), P.Z());
         meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
         NodesL.SetValue(i+1,1,N);
-        if(UVL.Length()<nbv-nnn-1) UVL.Append(UV);
+        if (UVL.Length()<nbv-nnn) UVL.Append(UV);
         // internal nodes
-        for(j=2; j<nl; j++) {
+        for (j=2; j<nl; j++) {
           double y0 = npl.Value(dl+j);
           double y1 = npr.Value(dl+j);
           gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3);
@@ -1146,57 +1615,57 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh &        aMesh,
           SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z());
           meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
           NodesL.SetValue(i+1,j,N);
-          if( i==dl ) UVtmp.Append(UV);
+          if (i==dl) UVtmp.Append(UV);
         }
       }
-      for(i=1; i<=UVtmp.Length() && UVL.Length()<nbv-nnn-1; i++) {
+      for (i=1; i<=UVtmp.Length() && UVL.Length()<nbv-nnn; i++) {
         UVL.Append(UVtmp.Value(i));
       }
       //cout<<"Dump NodesL:"<<endl;
-      //for(i=1; i<=dl+1; i++) {
+      //for (i=1; i<=dl+1; i++) {
       //  cout<<"i="<<i;
-      //  for(j=1; j<=nl; j++) {
+      //  for (j=1; j<=nl; j++) {
       //    cout<<" ("<<NodesL.Value(i,j)->X()<<","<<NodesL.Value(i,j)->Y()<<","<<NodesL.Value(i,j)->Z()<<")";
       //  }
       //  cout<<endl;
       //}
       // create faces
-      for(i=1; i<=dl; i++) {
-        for(j=1; j<nl; j++) {
-          if(WisF) {
+      for (i=1; i<=dl; i++) {
+        for (j=1; j<nl; j++) {
+          if (WisF) {
             SMDS_MeshFace* F =
-              myTool->AddFace(NodesL.Value(i,j), NodesL.Value(i+1,j),
+              myHelper->AddFace(NodesL.Value(i,j), NodesL.Value(i+1,j),
                               NodesL.Value(i+1,j+1), NodesL.Value(i,j+1));
-            meshDS->SetMeshElementOnShape(F, geomFaceID);
+            if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
           }
           else {
             SMDS_MeshFace* F =
-              myTool->AddFace(NodesL.Value(i,j), NodesL.Value(i,j+1),
+              myHelper->AddFace(NodesL.Value(i,j), NodesL.Value(i,j+1),
                               NodesL.Value(i+1,j+1), NodesL.Value(i+1,j));
-            meshDS->SetMeshElementOnShape(F, geomFaceID);
+            if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
           }
         }
       }
     }
     else {
       // fill UVL using c2d
-      for(i=1; i<npl.Length() && UVL.Length()<nbv-nnn-1; i++) {
-        UVL.Append( gp_UV ( uv_el[i].u, uv_el[i].v ));
+      for (i=1; i<npl.Length() && UVL.Length()<nbv-nnn; i++) {
+        UVL.Append(gp_UV (uv_el[i].u, uv_el[i].v));
       }
     }
     
     // step2: create faces for right domain
     StdMeshers_Array2OfNode NodesR(1,dr+1,1,nr);
     // add right nodes
-    for(j=1; j<=nr; j++) 
+    for (j=1; j<=nr; j++) 
       NodesR.SetValue(1,j,uv_er[nr-j].node);
-    if(dr>0) {
+    if (dr>0) {
       // add top nodes
-      for(i=1; i<=dr; i++) 
+      for (i=1; i<=dr; i++) 
         NodesR.SetValue(i+1,1,uv_et[nt-1-i].node);
       // create and add needed nodes
       TColgp_SequenceOfXY UVtmp;
-      for(i=1; i<=dr; i++) {
+      for (i=1; i<=dr; i++) {
         double x0 = npt.Value(nt-i);
         double x1 = x0;
         // diagonal node
@@ -1207,9 +1676,9 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh &        aMesh,
         SMDS_MeshNode * N = meshDS->AddNode(P.X(), P.Y(), P.Z());
         meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
         NodesR.SetValue(i+1,nr,N);
-        if(UVR.Length()<nbv-nnn-1) UVR.Append(UV);
+        if (UVR.Length()<nbv-nnn) UVR.Append(UV);
         // internal nodes
-        for(j=2; j<nr; j++) {
+        for (j=2; j<nr; j++) {
           double y0 = npl.Value(nbv-j+1);
           double y1 = npr.Value(nbv-j+1);
           gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3);
@@ -1217,62 +1686,62 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh &        aMesh,
           SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z());
           meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
           NodesR.SetValue(i+1,j,N);
-          if( i==dr ) UVtmp.Prepend(UV);
+          if (i==dr) UVtmp.Prepend(UV);
         }
       }
-      for(i=1; i<=UVtmp.Length() && UVR.Length()<nbv-nnn-1; i++) {
+      for (i=1; i<=UVtmp.Length() && UVR.Length()<nbv-nnn; i++) {
         UVR.Append(UVtmp.Value(i));
       }
       // create faces
-      for(i=1; i<=dr; i++) {
-        for(j=1; j<nr; j++) {
-          if(WisF) {
+      for (i=1; i<=dr; i++) {
+        for (j=1; j<nr; j++) {
+          if (WisF) {
             SMDS_MeshFace* F =
-              myTool->AddFace(NodesR.Value(i,j), NodesR.Value(i+1,j),
+              myHelper->AddFace(NodesR.Value(i,j), NodesR.Value(i+1,j),
                               NodesR.Value(i+1,j+1), NodesR.Value(i,j+1));
-            meshDS->SetMeshElementOnShape(F, geomFaceID);
+            if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
           }
           else {
             SMDS_MeshFace* F =
-              myTool->AddFace(NodesR.Value(i,j), NodesR.Value(i,j+1),
+              myHelper->AddFace(NodesR.Value(i,j), NodesR.Value(i,j+1),
                               NodesR.Value(i+1,j+1), NodesR.Value(i+1,j));
-            meshDS->SetMeshElementOnShape(F, geomFaceID);
+            if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
           }
         }
       }
     }
     else {
       // fill UVR using c2d
-      for(i=1; i<npr.Length() && UVR.Length()<nbv-nnn-1; i++) {
-        UVR.Append( gp_UV( uv_er[i].u, uv_er[i].v ));
+      for (i=1; i<npr.Length() && UVR.Length()<nbv-nnn; i++) {
+        UVR.Append(gp_UV(uv_er[i].u, uv_er[i].v));
       }
     }
     
     // step3: create faces for central domain
     StdMeshers_Array2OfNode NodesC(1,nb,1,nbv);
-    // add first string using NodesL
-    for(i=1; i<=dl+1; i++)
+    // add first line using NodesL
+    for (i=1; i<=dl+1; i++)
       NodesC.SetValue(1,i,NodesL(i,1));
-    for(i=2; i<=nl; i++)
+    for (i=2; i<=nl; i++)
       NodesC.SetValue(1,dl+i,NodesL(dl+1,i));
-    // add last string using NodesR
-    for(i=1; i<=dr+1; i++)
+    // add last line using NodesR
+    for (i=1; i<=dr+1; i++)
       NodesC.SetValue(nb,i,NodesR(i,nr));
-    for(i=1; i<nr; i++)
+    for (i=1; i<nr; i++)
       NodesC.SetValue(nb,dr+i+1,NodesR(dr+1,nr-i));
     // add top nodes (last columns)
-    for(i=dl+2; i<nbh-dr; i++) 
+    for (i=dl+2; i<nbh-dr; i++) 
       NodesC.SetValue(i-dl,nbv,uv_et[i-1].node);
     // add bottom nodes (first columns)
-    for(i=2; i<nb; i++)
+    for (i=2; i<nb; i++)
       NodesC.SetValue(i,1,uv_eb[i-1].node);
     
     // create and add needed nodes
     // add linear layers
-    for(i=2; i<nb; i++) {
+    for (i=2; i<nb; i++) {
       double x0 = npt.Value(dl+i);
       double x1 = x0;
-      for(j=1; j<nnn; j++) {
+      for (j=1; j<nnn; j++) {
         double y0 = npl.Value(nbv-nnn+j);
         double y1 = npr.Value(nbv-nnn+j);
         gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3);
@@ -1280,41 +1749,48 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh &        aMesh,
         SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z());
         meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
         NodesC.SetValue(i,nbv-nnn+j,N);
+        if ( j==1 )
+          UVT.Append( UV );
       }
     }
     // add diagonal layers
     //cout<<"UVL.Length()="<<UVL.Length()<<" UVR.Length()="<<UVR.Length()<<endl;
     //cout<<"Dump UVL:"<<endl;
-    //for(i=1; i<=UVL.Length(); i++) {
+    //for (i=1; i<=UVL.Length(); i++) {
     //  cout<<" ("<<UVL.Value(i).X()<<","<<UVL.Value(i).Y()<<")";
     //}
     //cout<<endl;
-    for(i=1; i<nbv-nnn; i++) {
-      double du = UVR.Value(i).X() - UVL.Value(i).X();
-      double dv = UVR.Value(i).Y() - UVL.Value(i).Y();
-      for(j=2; j<nb; j++) {
-        double u = UVL.Value(i).X() + du*npb.Value(j);
-        double v = UVL.Value(i).Y() + dv*npb.Value(j);
-        gp_Pnt P = S->Value(u,v);
+    gp_UV A2 = UVR.Value(nbv-nnn);
+    gp_UV A3 = UVL.Value(nbv-nnn);
+    for (i=1; i<nbv-nnn; i++) {
+      gp_UV p1 = UVR.Value(i);
+      gp_UV p3 = UVL.Value(i);
+      double y = i / double(nbv-nnn);
+      for (j=2; j<nb; j++) {
+        double x = npb.Value(j);
+        gp_UV p0( uv_eb[j-1].u, uv_eb[j-1].v );
+        gp_UV p2 = UVT.Value( j-1 );
+        gp_UV UV = CalcUV(x, y, a0, a1, A2, A3, p0,p1,p2,p3 );
+        gp_Pnt P = S->Value(UV.X(),UV.Y());
         SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z());
-        meshDS->SetNodeOnFace(N, geomFaceID, u, v);
+        meshDS->SetNodeOnFace(N, geomFaceID, UV.X(),UV.Y());
         NodesC.SetValue(j,i+1,N);
       }
     }
     // create faces
-    for(i=1; i<nb; i++) {
-      for(j=1; j<nbv; j++) {
-        if(WisF) {
+    for (i=1; i<nb; i++) {
+      for (j=1; j<nbv; j++) {
+        if (WisF) {
           SMDS_MeshFace* F =
-            myTool->AddFace(NodesC.Value(i,j), NodesC.Value(i+1,j),
+            myHelper->AddFace(NodesC.Value(i,j), NodesC.Value(i+1,j),
                             NodesC.Value(i+1,j+1), NodesC.Value(i,j+1));
-          meshDS->SetMeshElementOnShape(F, geomFaceID);
+          if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
         }
         else {
           SMDS_MeshFace* F =
-            myTool->AddFace(NodesC.Value(i,j), NodesC.Value(i,j+1),
+            myHelper->AddFace(NodesC.Value(i,j), NodesC.Value(i,j+1),
                             NodesC.Value(i+1,j+1), NodesC.Value(i+1,j));
-          meshDS->SetMeshElementOnShape(F, geomFaceID);
+          if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
         }
       }
     }
@@ -1324,58 +1800,55 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh &        aMesh,
     // step1: create faces for bottom rectangle domain
     StdMeshers_Array2OfNode NodesBRD(1,nb,1,nnn-1);
     // fill UVL and UVR using c2d
-    for(j=0; j<nb; j++) {
+    for (j=0; j<nb; j++) {
       NodesBRD.SetValue(j+1,1,uv_eb[j].node);
     }
-    for(i=1; i<nnn-1; i++) {
+    for (i=1; i<nnn-1; i++) {
       NodesBRD.SetValue(1,i+1,uv_el[i].node);
       NodesBRD.SetValue(nb,i+1,uv_er[i].node);
-      double du = uv_er[i].u - uv_el[i].u;
-      double dv = uv_er[i].v - uv_el[i].v;
-      for(j=2; j<nb; j++) {
-        double u = uv_el[i].u + du*npb.Value(j);
-        double v = uv_el[i].v + dv*npb.Value(j);
-        gp_Pnt P = S->Value(u,v);
+      for (j=2; j<nb; j++) {
+        double x = npb.Value(j);
+        double y = (1-x) * npl.Value(i+1) + x * npr.Value(i+1);
+        gp_UV UV = CalcUV2(x, y, quad, a0, a1, a2, a3);
+        gp_Pnt P = S->Value(UV.X(),UV.Y());
         SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z());
-        meshDS->SetNodeOnFace(N, geomFaceID, u, v);
+        meshDS->SetNodeOnFace(N, geomFaceID, UV.X(),UV.Y());
         NodesBRD.SetValue(j,i+1,N);
-
       }
     }
-    for(j=1; j<nnn-1; j++) {
-      for(i=1; i<nb; i++) {
-        if(WisF) {
+    for (j=1; j<nnn-1; j++) {
+      for (i=1; i<nb; i++) {
+        if (WisF) {
           SMDS_MeshFace* F =
-            myTool->AddFace(NodesBRD.Value(i,j), NodesBRD.Value(i+1,j),
+            myHelper->AddFace(NodesBRD.Value(i,j), NodesBRD.Value(i+1,j),
                             NodesBRD.Value(i+1,j+1), NodesBRD.Value(i,j+1));
-          meshDS->SetMeshElementOnShape(F, geomFaceID);
+          if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
         }
         else {
           SMDS_MeshFace* F =
-            myTool->AddFace(NodesBRD.Value(i,j), NodesBRD.Value(i,j+1),
+            myHelper->AddFace(NodesBRD.Value(i,j), NodesBRD.Value(i,j+1),
                             NodesBRD.Value(i+1,j+1), NodesBRD.Value(i+1,j));
-          meshDS->SetMeshElementOnShape(F, geomFaceID);
+          if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
         }
       }
     }
-
     int drl = abs(nr-nl);
     // create faces for region C
     StdMeshers_Array2OfNode NodesC(1,nb,1,drl+1+addv);
     // add nodes from previous region
-    for(j=1; j<=nb; j++) {
+    for (j=1; j<=nb; j++) {
       NodesC.SetValue(j,1,NodesBRD.Value(j,nnn-1));
     }
-    if( (drl+addv) > 0 ) {
+    if ((drl+addv) > 0) {
       int n1,n2;
-      if(nr>nl) {
+      if (nr>nl) {
         n1 = 1;
         n2 = drl + 1;
         TColgp_SequenceOfXY UVtmp;
         double drparam = npr.Value(nr) - npr.Value(nnn-1);
         double dlparam = npl.Value(nnn) - npl.Value(nnn-1);
         double y0,y1;
-        for(i=1; i<=drl; i++) {
+        for (i=1; i<=drl; i++) {
           // add existed nodes from right edge
           NodesC.SetValue(nb,i+1,uv_er[nnn+i-2].node);
           //double dtparam = npt.Value(i+1);
@@ -1383,7 +1856,7 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh &        aMesh,
           double dpar = (y1 - npr.Value(nnn-1))/drparam;
           y0 = npl.Value(nnn-1) + dpar*dlparam; // param on left edge
           double dy = y1 - y0;
-          for(j=1; j<nb; j++) {
+          for (j=1; j<nb; j++) {
             double x = npt.Value(i+1) + npb.Value(j)*(1-npt.Value(i+1));
             double y = y0 + dy*x;
             gp_UV UV = CalcUV2(x, y, quad, a0, a1, a2, a3);
@@ -1395,13 +1868,13 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh &        aMesh,
         }
         double dy0 = (1-y0)/(addv+1);
         double dy1 = (1-y1)/(addv+1);
-        for(i=1; i<=addv; i++) {
+        for (i=1; i<=addv; i++) {
           double yy0 = y0 + dy0*i;
           double yy1 = y1 + dy1*i;
           double dyy = yy1 - yy0;
-          for(j=1; j<=nb; j++) {
+          for (j=1; j<=nb; j++) {
             double x = npt.Value(i+1+drl) + 
-              npb.Value(j) * ( npt.Value(nt-i) - npt.Value(i+1+drl) );
+              npb.Value(j) * (npt.Value(nt-i) - npt.Value(i+1+drl));
             double y = yy0 + dyy*x;
             gp_UV UV = CalcUV2(x, y, quad, a0, a1, a2, a3);
             gp_Pnt P = S->Value(UV.X(),UV.Y());
@@ -1419,14 +1892,14 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh &        aMesh,
         double drparam = npr.Value(nnn) - npr.Value(nnn-1);
         double y0 = npl.Value(nnn-1);
         double y1 = npr.Value(nnn-1);
-        for(i=1; i<=drl; i++) {
+        for (i=1; i<=drl; i++) {
           // add existed nodes from right edge
           NodesC.SetValue(1,i+1,uv_el[nnn+i-2].node);
           y0 = npl.Value(nnn+i-1); // param on left edge
           double dpar = (y0 - npl.Value(nnn-1))/dlparam;
           y1 = npr.Value(nnn-1) + dpar*drparam; // param on right edge
           double dy = y1 - y0;
-          for(j=2; j<=nb; j++) {
+          for (j=2; j<=nb; j++) {
             double x = npb.Value(j)*npt.Value(nt-i);
             double y = y0 + dy*x;
             gp_UV UV = CalcUV2(x, y, quad, a0, a1, a2, a3);
@@ -1438,13 +1911,13 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh &        aMesh,
         }
         double dy0 = (1-y0)/(addv+1);
         double dy1 = (1-y1)/(addv+1);
-        for(i=1; i<=addv; i++) {
+        for (i=1; i<=addv; i++) {
           double yy0 = y0 + dy0*i;
           double yy1 = y1 + dy1*i;
           double dyy = yy1 - yy0;
-          for(j=1; j<=nb; j++) {
+          for (j=1; j<=nb; j++) {
             double x = npt.Value(i+1) + 
-              npb.Value(j) * ( npt.Value(nt-i-drl) - npt.Value(i+1) );
+              npb.Value(j) * (npt.Value(nt-i-drl) - npt.Value(i+1));
             double y = yy0 + dyy*x;
             gp_UV UV = CalcUV2(x, y, quad, a0, a1, a2, a3);
             gp_Pnt P = S->Value(UV.X(),UV.Y());
@@ -1455,55 +1928,55 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh &        aMesh,
         }
       }
       // create faces
-      for(j=1; j<=drl+addv; j++) {
-        for(i=1; i<nb; i++) {
-          if(WisF) {
+      for (j=1; j<=drl+addv; j++) {
+        for (i=1; i<nb; i++) {
+          if (WisF) {
             SMDS_MeshFace* F =
-              myTool->AddFace(NodesC.Value(i,j), NodesC.Value(i+1,j),
+              myHelper->AddFace(NodesC.Value(i,j), NodesC.Value(i+1,j),
                               NodesC.Value(i+1,j+1), NodesC.Value(i,j+1));
-            meshDS->SetMeshElementOnShape(F, geomFaceID);
+            if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
           }
           else {
             SMDS_MeshFace* F =
-              myTool->AddFace(NodesC.Value(i,j), NodesC.Value(i,j+1),
+              myHelper->AddFace(NodesC.Value(i,j), NodesC.Value(i,j+1),
                               NodesC.Value(i+1,j+1), NodesC.Value(i+1,j));
-            meshDS->SetMeshElementOnShape(F, geomFaceID);
+            if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
           }
         }
       } // end nr<nl
 
       StdMeshers_Array2OfNode NodesLast(1,nt,1,2);
-      for(i=1; i<=nt; i++) {
+      for (i=1; i<=nt; i++) {
         NodesLast.SetValue(i,2,uv_et[i-1].node);
       }
       int nnn=0;
-      for(i=n1; i<drl+addv+1; i++) {
+      for (i=n1; i<drl+addv+1; i++) {
         nnn++;
         NodesLast.SetValue(nnn,1,NodesC.Value(1,i));
       }
-      for(i=1; i<=nb; i++) {
+      for (i=1; i<=nb; i++) {
         nnn++;
         NodesLast.SetValue(nnn,1,NodesC.Value(i,drl+addv+1));
       }
-      for(i=drl+addv; i>=n2; i--) {
+      for (i=drl+addv; i>=n2; i--) {
         nnn++;
         NodesLast.SetValue(nnn,1,NodesC.Value(nb,i));
       }
-      for(i=1; i<nt; i++) {
-        if(WisF) {
+      for (i=1; i<nt; i++) {
+        if (WisF) {
           SMDS_MeshFace* F =
-            myTool->AddFace(NodesLast.Value(i,1), NodesLast.Value(i+1,1),
+            myHelper->AddFace(NodesLast.Value(i,1), NodesLast.Value(i+1,1),
                             NodesLast.Value(i+1,2), NodesLast.Value(i,2));
-          meshDS->SetMeshElementOnShape(F, geomFaceID);
+          if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
         }
         else {
           SMDS_MeshFace* F =
-            myTool->AddFace(NodesLast.Value(i,1), NodesLast.Value(i,2),
+            myHelper->AddFace(NodesLast.Value(i,1), NodesLast.Value(i,2),
                             NodesLast.Value(i+1,2), NodesLast.Value(i+1,2));
-          meshDS->SetMeshElementOnShape(F, geomFaceID);
+          if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
         }
       }
-    } // if( (drl+addv) > 0 )
+    } // if ((drl+addv) > 0)
 
   } // end new version implementation
 
@@ -1511,34 +1984,1470 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh &        aMesh,
   return isOk;
 }
 
-//=============================================================================
-/*! Split quadrangle in to 2 triangles by smallest diagonal
- *   
+
+//=======================================================================
+/*!
+ * Evaluate only quandrangle faces
  */
-//=============================================================================
-void StdMeshers_Quadrangle_2D::SplitQuad(SMESHDS_Mesh *theMeshDS,
-                                    int theFaceID,
-                                    const SMDS_MeshNode* theNode1,
-                                    const SMDS_MeshNode* theNode2,
-                                    const SMDS_MeshNode* theNode3,
-                                    const SMDS_MeshNode* theNode4)
+//=======================================================================
+
+bool StdMeshers_Quadrangle_2D::EvaluateQuadPref(SMESH_Mesh &        aMesh,
+                                                const TopoDS_Shape& aShape,
+                                                std::vector<int>& aNbNodes,
+                                                MapShapeNbElems& aResMap,
+                                                bool IsQuadratic)
 {
-  gp_Pnt a(theNode1->X(),theNode1->Y(),theNode1->Z());
-  gp_Pnt b(theNode2->X(),theNode2->Y(),theNode2->Z());
-  gp_Pnt c(theNode3->X(),theNode3->Y(),theNode3->Z());
-  gp_Pnt d(theNode4->X(),theNode4->Y(),theNode4->Z());
-  SMDS_MeshFace* face;
-  if(a.Distance(c) > b.Distance(d)){
-    face = myTool->AddFace(theNode2, theNode4 , theNode1);
-    theMeshDS->SetMeshElementOnShape(face, theFaceID );
-    face = myTool->AddFace(theNode2, theNode3, theNode4);
-    theMeshDS->SetMeshElementOnShape(face, theFaceID );
+  // Auxilary key in order to keep old variant
+  // of meshing after implementation new variant
+  // for bug 0016220 from Mantis.
+  bool OldVersion = false;
+  if (myQuadType == QUAD_QUADRANGLE_PREF_REVERSED)
+    OldVersion = true;
+
+  const TopoDS_Face& F = TopoDS::Face(aShape);
+  Handle(Geom_Surface) S = BRep_Tool::Surface(F);
+
+  int nb = aNbNodes[0];
+  int nr = aNbNodes[1];
+  int nt = aNbNodes[2];
+  int nl = aNbNodes[3];
+  int dh = abs(nb-nt);
+  int dv = abs(nr-nl);
 
+  if (dh>=dv) {
+    if (nt>nb) {
+      // it is a base case => not shift 
+    }
+    else {
+      // we have to shift on 2
+      nb = aNbNodes[2];
+      nr = aNbNodes[3];
+      nt = aNbNodes[0];
+      nl = aNbNodes[1];
+    }
   }
-  else{
-    face = myTool->AddFace(theNode1, theNode2 ,theNode3);
-    theMeshDS->SetMeshElementOnShape(face, theFaceID );
-    face = myTool->AddFace(theNode1, theNode3, theNode4);
-    theMeshDS->SetMeshElementOnShape(face, theFaceID );
+  else {
+    if (nr>nl) {
+      // we have to shift quad on 1
+      nb = aNbNodes[3];
+      nr = aNbNodes[0];
+      nt = aNbNodes[1];
+      nl = aNbNodes[2];
+    }
+    else {
+      // we have to shift quad on 3
+      nb = aNbNodes[1];
+      nr = aNbNodes[2];
+      nt = aNbNodes[3];
+      nl = aNbNodes[0];
+    }
+  }
+
+  dh = abs(nb-nt);
+  dv = abs(nr-nl);
+  int nbh  = Max(nb,nt);
+  int nbv = Max(nr,nl);
+  int addh = 0;
+  int addv = 0;
+
+  if (dh>dv) {
+    addv = (dh-dv)/2;
+    nbv = nbv + addv;
+  }
+  else { // dv>=dh
+    addh = (dv-dh)/2;
+    nbh = nbh + addh;
+  }
+
+  int dl,dr;
+  if (OldVersion) {
+    // add some params to right and left after the first param
+    // insert to right
+    dr = nbv - nr;
+    // insert to left
+    dl = nbv - nl;
+  }
+  
+  int nnn = Min(nr,nl);
+
+  int nbNodes = 0;
+  int nbFaces = 0;
+  if (OldVersion) {
+    // step1: create faces for left domain
+    if (dl>0) {
+      nbNodes += dl*(nl-1);
+      nbFaces += dl*(nl-1);
+    }
+    // step2: create faces for right domain
+    if (dr>0) {
+      nbNodes += dr*(nr-1);
+      nbFaces += dr*(nr-1);
+    }
+    // step3: create faces for central domain
+    nbNodes += (nb-2)*(nnn-1) + (nbv-nnn-1)*(nb-2);
+    nbFaces += (nb-1)*(nbv-1);
+  }
+  else { // New version (!OldVersion)
+    nbNodes += (nnn-2)*(nb-2);
+    nbFaces += (nnn-2)*(nb-1);
+    int drl = abs(nr-nl);
+    nbNodes += drl*(nb-1) + addv*nb;
+    nbFaces += (drl+addv)*(nb-1) + (nt-1);
+  } // end new version implementation
+
+  std::vector<int> aVec(SMDSEntity_Last);
+  for (int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aVec[i] = 0;
+  if (IsQuadratic) {
+    aVec[SMDSEntity_Quad_Quadrangle] = nbFaces;
+    aVec[SMDSEntity_Node] = nbNodes + nbFaces*4;
+    if (aNbNodes.size()==5) {
+      aVec[SMDSEntity_Quad_Triangle] = aNbNodes[3] - 1;
+      aVec[SMDSEntity_Quad_Quadrangle] = nbFaces - aNbNodes[3] + 1;
+    }
+  }
+  else {
+    aVec[SMDSEntity_Node] = nbNodes;
+    aVec[SMDSEntity_Quadrangle] = nbFaces;
+    if (aNbNodes.size()==5) {
+      aVec[SMDSEntity_Triangle] = aNbNodes[3] - 1;
+      aVec[SMDSEntity_Quadrangle] = nbFaces - aNbNodes[3] + 1;
+    }
+  }
+  SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+  aResMap.insert(std::make_pair(sm,aVec));
+
+  return true;
+}
+
+
+//=============================================================================
+/*! Split quadrangle in to 2 triangles by smallest diagonal
+ *   
+ */
+//=============================================================================
+void StdMeshers_Quadrangle_2D::SplitQuad(SMESHDS_Mesh *theMeshDS,
+                                         int theFaceID,
+                                         const SMDS_MeshNode* theNode1,
+                                         const SMDS_MeshNode* theNode2,
+                                         const SMDS_MeshNode* theNode3,
+                                         const SMDS_MeshNode* theNode4)
+{
+  gp_Pnt a(theNode1->X(),theNode1->Y(),theNode1->Z());
+  gp_Pnt b(theNode2->X(),theNode2->Y(),theNode2->Z());
+  gp_Pnt c(theNode3->X(),theNode3->Y(),theNode3->Z());
+  gp_Pnt d(theNode4->X(),theNode4->Y(),theNode4->Z());
+  SMDS_MeshFace* face;
+  if (a.Distance(c) > b.Distance(d)){
+    face = myHelper->AddFace(theNode2, theNode4 , theNode1);
+    if (face) theMeshDS->SetMeshElementOnShape(face, theFaceID);
+    face = myHelper->AddFace(theNode2, theNode3, theNode4);
+    if (face) theMeshDS->SetMeshElementOnShape(face, theFaceID);
+
+  }
+  else{
+    face = myHelper->AddFace(theNode1, theNode2 ,theNode3);
+    if (face) theMeshDS->SetMeshElementOnShape(face, theFaceID);
+    face = myHelper->AddFace(theNode1, theNode3, theNode4);
+    if (face) theMeshDS->SetMeshElementOnShape(face, theFaceID);
+  }
+}
+
+namespace
+{
+  enum uvPos { UV_A0, UV_A1, UV_A2, UV_A3, UV_B, UV_R, UV_T, UV_L, UV_SIZE };
+
+  inline  SMDS_MeshNode* makeNode( UVPtStruct &         uvPt,
+                                   const double         y,
+                                   FaceQuadStruct*      quad,
+                                   const gp_UV*         UVs,
+                                   SMESH_MesherHelper*  helper,
+                                   Handle(Geom_Surface) S)
+  {
+    const vector<UVPtStruct>& uv_eb = quad->side[BOTTOM_SIDE]->GetUVPtStruct();
+    const vector<UVPtStruct>& uv_et = quad->side[TOP_SIDE   ]->GetUVPtStruct();
+    double rBot = ( uv_eb.size() - 1 ) * uvPt.normParam;
+    double rTop = ( uv_et.size() - 1 ) * uvPt.normParam;
+    int iBot = int( rBot );
+    int iTop = int( rTop );
+    double xBot = uv_eb[ iBot ].normParam + ( rBot - iBot ) * ( uv_eb[ iBot+1 ].normParam - uv_eb[ iBot ].normParam );
+    double xTop = uv_et[ iTop ].normParam + ( rTop - iTop ) * ( uv_et[ iTop+1 ].normParam - uv_et[ iTop ].normParam );
+    double x = xBot + y * ( xTop - xBot );
+    
+    gp_UV uv = CalcUV(/*x,y=*/x, y,
+                      /*a0,...=*/UVs[UV_A0], UVs[UV_A1], UVs[UV_A2], UVs[UV_A3],
+                      /*p0=*/quad->side[BOTTOM_SIDE]->Value2d( x ).XY(),
+                      /*p1=*/UVs[ UV_R ],
+                      /*p2=*/quad->side[TOP_SIDE   ]->Value2d( x ).XY(),
+                      /*p3=*/UVs[ UV_L ]);
+    gp_Pnt P = S->Value( uv.X(), uv.Y() );
+    uvPt.u = uv.X();
+    uvPt.v = uv.Y();
+    return helper->AddNode(P.X(), P.Y(), P.Z(), 0, uv.X(), uv.Y() );
+  }
+
+  void reduce42( const vector<UVPtStruct>& curr_base,
+                 vector<UVPtStruct>&       next_base,
+                 const int                 j,
+                 int &                     next_base_len,
+                 FaceQuadStruct*           quad,
+                 gp_UV*                    UVs,
+                 const double              y,
+                 SMESH_MesherHelper*       helper,
+                 Handle(Geom_Surface)&     S)
+  {
+    // add one "HH": nodes a,b,c,d,e and faces 1,2,3,4,5,6
+    //
+    //  .-----a-----b i + 1
+    //  |\ 5  | 6  /|
+    //  | \   |   / |
+    //  |  c--d--e  |
+    //  |1 |2 |3 |4 |
+    //  |  |  |  |  |
+    //  .--.--.--.--. i
+    //
+    //  j     j+2   j+4
+
+    // a (i + 1, j + 2)
+    const SMDS_MeshNode*& Na = next_base[ ++next_base_len ].node;
+    if ( !Na )
+      Na = makeNode( next_base[ next_base_len ], y, quad, UVs, helper, S );
+
+    // b (i + 1, j + 4)
+    const SMDS_MeshNode*& Nb = next_base[ ++next_base_len ].node;
+    if ( !Nb )
+      Nb = makeNode( next_base[ next_base_len ], y, quad, UVs, helper, S );
+
+    // c
+    double u = (curr_base[j + 2].u + next_base[next_base_len - 2].u) / 2.0;
+    double v = (curr_base[j + 2].v + next_base[next_base_len - 2].v) / 2.0;
+    gp_Pnt P = S->Value(u,v);
+    SMDS_MeshNode* Nc = helper->AddNode(P.X(), P.Y(), P.Z(), 0, u, v);
+
+    // d
+    u = (curr_base[j + 2].u + next_base[next_base_len - 1].u) / 2.0;
+    v = (curr_base[j + 2].v + next_base[next_base_len - 1].v) / 2.0;
+    P = S->Value(u,v);
+    SMDS_MeshNode* Nd = helper->AddNode(P.X(), P.Y(), P.Z(), 0, u, v);
+
+    // e
+    u = (curr_base[j + 2].u + next_base[next_base_len].u) / 2.0;
+    v = (curr_base[j + 2].v + next_base[next_base_len].v) / 2.0;
+    P = S->Value(u,v);
+    SMDS_MeshNode* Ne = helper->AddNode(P.X(), P.Y(), P.Z(), 0, u, v);
+
+    // Faces
+    helper->AddFace(curr_base[j + 0].node,
+                    curr_base[j + 1].node, Nc,
+                    next_base[next_base_len - 2].node);
+
+    helper->AddFace(curr_base[j + 1].node,
+                    curr_base[j + 2].node, Nd, Nc);
+
+    helper->AddFace(curr_base[j + 2].node,
+                    curr_base[j + 3].node, Ne, Nd);
+
+    helper->AddFace(curr_base[j + 3].node,
+                    curr_base[j + 4].node, Nb, Ne);
+
+    helper->AddFace(Nc, Nd, Na, next_base[next_base_len - 2].node);
+
+    helper->AddFace(Nd, Ne, Nb, Na);
+  }
+
+  void reduce31( const vector<UVPtStruct>& curr_base,
+                 vector<UVPtStruct>&       next_base,
+                 const int                 j,
+                 int &                     next_base_len,
+                 FaceQuadStruct*           quad,
+                 gp_UV*                    UVs,
+                 const double              y,
+                 SMESH_MesherHelper*       helper,
+                 Handle(Geom_Surface)&     S)
+  {
+    // add one "H": nodes b,c,e and faces 1,2,4,5
+    //
+    //  .---------b i + 1
+    //  |\   5   /|
+    //  | \     / |
+    //  |  c---e  |
+    //  |1 |2  |4 |
+    //  |  |   |  |
+    //  .--.---.--. i
+    //
+    //  j j+1 j+2 j+3
+
+    // b (i + 1, j + 3)
+    const SMDS_MeshNode*& Nb = next_base[ ++next_base_len ].node;
+    if ( !Nb )
+      Nb = makeNode( next_base[ next_base_len ], y, quad, UVs, helper, S );
+
+    // c and e
+    double u1 = (curr_base[ j   ].u + next_base[ next_base_len-1 ].u ) / 2.0;
+    double u2 = (curr_base[ j+3 ].u + next_base[ next_base_len   ].u ) / 2.0;
+    double u3 = (u2 - u1) / 3.0;
+    //
+    double v1 = (curr_base[ j   ].v + next_base[ next_base_len-1 ].v ) / 2.0;
+    double v2 = (curr_base[ j+3 ].v + next_base[ next_base_len   ].v ) / 2.0;
+    double v3 = (v2 - v1) / 3.0;
+    // c
+    double u = u1 + u3;
+    double v = v1 + v3;
+    gp_Pnt P = S->Value(u,v);
+    SMDS_MeshNode* Nc = helper->AddNode( P.X(), P.Y(), P.Z(), 0, u, v );
+    // e
+    u = u1 + u3 + u3;
+    v = v1 + v3 + v3;
+    P = S->Value(u,v);
+    SMDS_MeshNode* Ne = helper->AddNode( P.X(), P.Y(), P.Z(), 0, u, v );
+
+    // Faces
+    // 1
+    helper->AddFace( curr_base[ j + 0 ].node,
+                     curr_base[ j + 1 ].node,
+                     Nc,
+                     next_base[ next_base_len - 1 ].node);
+    // 2
+    helper->AddFace( curr_base[ j + 1 ].node,
+                     curr_base[ j + 2 ].node, Ne, Nc);
+    // 4
+    helper->AddFace( curr_base[ j + 2 ].node,
+                     curr_base[ j + 3 ].node, Nb, Ne);
+    // 5
+    helper->AddFace(Nc, Ne, Nb,
+                    next_base[ next_base_len - 1 ].node);
+  }
+
+  typedef void (* PReduceFunction) ( const vector<UVPtStruct>& curr_base,
+                                     vector<UVPtStruct>&       next_base,
+                                     const int                 j,
+                                     int &                     next_base_len,
+                                     FaceQuadStruct*           quad,
+                                     gp_UV*                    UVs,
+                                     const double              y,
+                                     SMESH_MesherHelper*       helper,
+                                     Handle(Geom_Surface)&     S);
+
+} // namespace
+
+//=======================================================================
+/*!
+ *  Implementation of Reduced algorithm (meshing with quadrangles only)
+ */
+//=======================================================================
+bool StdMeshers_Quadrangle_2D::ComputeReduced (SMESH_Mesh &        aMesh,
+                                               const TopoDS_Shape& aShape,
+                                               FaceQuadStruct*     quad)
+{
+  SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
+  const TopoDS_Face& F = TopoDS::Face(aShape);
+  Handle(Geom_Surface) S = BRep_Tool::Surface(F);
+  int i,j,geomFaceID = meshDS->ShapeToIndex(F);
+
+  int nb = quad->side[0]->NbPoints();
+  int nr = quad->side[1]->NbPoints();
+  int nt = quad->side[2]->NbPoints();
+  int nl = quad->side[3]->NbPoints();
+
+  //  Simple Reduce 10->8->6->4 (3 steps)     Multiple Reduce 10->4 (1 step)
+  //
+  //  .-----.-----.-----.-----.               .-----.-----.-----.-----.
+  //  |    / \    |    / \    |               |    / \    |    / \    |
+  //  |   /    .--.--.    \   |               |    / \    |    / \    |
+  //  |   /   /   |   \   \   |               |   /  .----.----.  \   |
+  //  .---.---.---.---.---.---.               |   / / \   |   / \ \   |
+  //  |   /  / \  |  / \  \   |               |   / / \   |   / \ \   |
+  //  |  /  /   .-.-.   \  \  |               |  / /  .---.---.  \ \  |
+  //  |  /  /  /  |  \  \  \  |               |  / / / \  |  / \ \ \  |
+  //  .--.--.--.--.--.--.--.--.               |  / / /  \ | /  \ \ \  |
+  //  |  / /  / \ | / \  \ \  |               | / / /   .-.-.   \ \ \ |
+  //  | / /  /  .-.-.  \  \ \ |               | / / /  /  |  \  \ \ \ |
+  //  | / / /  /  |  \  \ \ \ |               | / / /  /  |  \  \ \ \ |
+  //  .-.-.-.--.--.--.--.-.-.-.               .-.-.-.--.--.--.--.-.-.-.
+
+  bool MultipleReduce = false;
+  {
+    int nb1 = nb;
+    int nr1 = nr;
+    int nt1 = nt;
+
+    if (nr == nl) {
+      if (nb < nt) {
+        nt1 = nb;
+        nb1 = nt;
+      }
+    }
+    else if (nb == nt) {
+      nr1 = nb; // and == nt
+      if (nl < nr) {
+        nt1 = nl;
+        nb1 = nr;
+      }
+      else {
+        nt1 = nr;
+        nb1 = nl;
+      }
+    }
+    else {
+      return false;
+    }
+
+    // number of rows and columns
+    int nrows = nr1 - 1;
+    int ncol_top = nt1 - 1;
+    int ncol_bot = nb1 - 1;
+    // number of rows needed to reduce ncol_bot to ncol_top using simple 3->1 "tree" (see below)
+    int nrows_tree31 = int( log( (double)(ncol_bot / ncol_top) ) / log((double) 3 )); // = log x base 3
+    if ( nrows < nrows_tree31 )
+      MultipleReduce = true;
+  }
+
+  if (MultipleReduce) { // == ComputeQuadPref QUAD_QUADRANGLE_PREF_REVERSED
+    //==================================================
+    int dh = abs(nb-nt);
+    int dv = abs(nr-nl);
+
+    if (dh >= dv) {
+      if (nt > nb) {
+        // it is a base case => not shift quad but may be replacement is need
+        ShiftQuad(quad,0,true);
+      }
+      else {
+        // we have to shift quad on 2
+        ShiftQuad(quad,2,true);
+      }
+    }
+    else {
+      if (nr > nl) {
+        // we have to shift quad on 1
+        ShiftQuad(quad,1,true);
+      }
+      else {
+        // we have to shift quad on 3
+        ShiftQuad(quad,3,true);
+      }
+    }
+
+    nb = quad->side[0]->NbPoints();
+    nr = quad->side[1]->NbPoints();
+    nt = quad->side[2]->NbPoints();
+    nl = quad->side[3]->NbPoints();
+    dh = abs(nb-nt);
+    dv = abs(nr-nl);
+    int nbh = Max(nb,nt);
+    int nbv = Max(nr,nl);
+    int addh = 0;
+    int addv = 0;
+
+    if (dh>dv) {
+      addv = (dh-dv)/2;
+      nbv = nbv + addv;
+    }
+    else { // dv>=dh
+      addh = (dv-dh)/2;
+      nbh = nbh + addh;
+    }
+
+    const vector<UVPtStruct>& uv_eb = quad->side[0]->GetUVPtStruct(true,0);
+    const vector<UVPtStruct>& uv_er = quad->side[1]->GetUVPtStruct(false,1);
+    const vector<UVPtStruct>& uv_et = quad->side[2]->GetUVPtStruct(true,1);
+    const vector<UVPtStruct>& uv_el = quad->side[3]->GetUVPtStruct(false,0);
+
+    if (uv_eb.size() != nb || uv_er.size() != nr || uv_et.size() != nt || uv_el.size() != nl)
+      return error(COMPERR_BAD_INPUT_MESH);
+
+    if ( myNeedSmooth )
+      UpdateDegenUV( quad );
+
+    // arrays for normalized params
+    TColStd_SequenceOfReal npb, npr, npt, npl;
+    for (j = 0; j < nb; j++) {
+      npb.Append(uv_eb[j].normParam);
+    }
+    for (i = 0; i < nr; i++) {
+      npr.Append(uv_er[i].normParam);
+    }
+    for (j = 0; j < nt; j++) {
+      npt.Append(uv_et[j].normParam);
+    }
+    for (i = 0; i < nl; i++) {
+      npl.Append(uv_el[i].normParam);
+    }
+
+    int dl,dr;
+    // orientation of face and 3 main domain for future faces
+    //       0   top    1
+    //      1------------1
+    //       |   |  |   |
+    //       |   |  |   |
+    //       | L |  | R |
+    //  left |   |  |   | rigth
+    //       |  /    \  |
+    //       | /  C   \ |
+    //       |/        \|
+    //      0------------0
+    //       0  bottom  1
+
+    // add some params to right and left after the first param
+    // insert to right
+    dr = nbv - nr;
+    double dpr = (npr.Value(2) - npr.Value(1))/(dr+1);
+    for (i=1; i<=dr; i++) {
+      npr.InsertAfter(1,npr.Value(2)-dpr);
+    }
+    // insert to left
+    dl = nbv - nl;
+    dpr = (npl.Value(2) - npl.Value(1))/(dl+1);
+    for (i=1; i<=dl; i++) {
+      npl.InsertAfter(1,npl.Value(2)-dpr);
+    }
+  
+    gp_XY a0 (uv_eb.front().u, uv_eb.front().v);
+    gp_XY a1 (uv_eb.back().u,  uv_eb.back().v);
+    gp_XY a2 (uv_et.back().u,  uv_et.back().v);
+    gp_XY a3 (uv_et.front().u, uv_et.front().v);
+
+    int nnn = Min(nr,nl);
+    // auxilary sequence of XY for creation of nodes
+    // in the bottom part of central domain
+    // it's length must be == nbv-nnn-1
+    TColgp_SequenceOfXY UVL;
+    TColgp_SequenceOfXY UVR;
+    //==================================================
+
+    // step1: create faces for left domain
+    StdMeshers_Array2OfNode NodesL(1,dl+1,1,nl);
+    // add left nodes
+    for (j=1; j<=nl; j++)
+      NodesL.SetValue(1,j,uv_el[j-1].node);
+    if (dl>0) {
+      // add top nodes
+      for (i=1; i<=dl; i++) 
+        NodesL.SetValue(i+1,nl,uv_et[i].node);
+      // create and add needed nodes
+      TColgp_SequenceOfXY UVtmp;
+      for (i=1; i<=dl; i++) {
+        double x0 = npt.Value(i+1);
+        double x1 = x0;
+        // diagonal node
+        double y0 = npl.Value(i+1);
+        double y1 = npr.Value(i+1);
+        gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3);
+        gp_Pnt P = S->Value(UV.X(),UV.Y());
+        SMDS_MeshNode * N = meshDS->AddNode(P.X(), P.Y(), P.Z());
+        meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
+        NodesL.SetValue(i+1,1,N);
+        if (UVL.Length()<nbv-nnn-1) UVL.Append(UV);
+        // internal nodes
+        for (j=2; j<nl; j++) {
+          double y0 = npl.Value(dl+j);
+          double y1 = npr.Value(dl+j);
+          gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3);
+          gp_Pnt P = S->Value(UV.X(),UV.Y());
+          SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z());
+          meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
+          NodesL.SetValue(i+1,j,N);
+          if (i==dl) UVtmp.Append(UV);
+        }
+      }
+      for (i=1; i<=UVtmp.Length() && UVL.Length()<nbv-nnn-1; i++) {
+        UVL.Append(UVtmp.Value(i));
+      }
+      // create faces
+      for (i=1; i<=dl; i++) {
+        for (j=1; j<nl; j++) {
+            SMDS_MeshFace* F =
+              myHelper->AddFace(NodesL.Value(i,j), NodesL.Value(i+1,j),
+                                NodesL.Value(i+1,j+1), NodesL.Value(i,j+1));
+            if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
+        }
+      }
+    }
+    else {
+      // fill UVL using c2d
+      for (i=1; i<npl.Length() && UVL.Length()<nbv-nnn-1; i++) {
+        UVL.Append(gp_UV (uv_el[i].u, uv_el[i].v));
+      }
+    }
+    
+    // step2: create faces for right domain
+    StdMeshers_Array2OfNode NodesR(1,dr+1,1,nr);
+    // add right nodes
+    for (j=1; j<=nr; j++) 
+      NodesR.SetValue(1,j,uv_er[nr-j].node);
+    if (dr>0) {
+      // add top nodes
+      for (i=1; i<=dr; i++) 
+        NodesR.SetValue(i+1,1,uv_et[nt-1-i].node);
+      // create and add needed nodes
+      TColgp_SequenceOfXY UVtmp;
+      for (i=1; i<=dr; i++) {
+        double x0 = npt.Value(nt-i);
+        double x1 = x0;
+        // diagonal node
+        double y0 = npl.Value(i+1);
+        double y1 = npr.Value(i+1);
+        gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3);
+        gp_Pnt P = S->Value(UV.X(),UV.Y());
+        SMDS_MeshNode * N = meshDS->AddNode(P.X(), P.Y(), P.Z());
+        meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
+        NodesR.SetValue(i+1,nr,N);
+        if (UVR.Length()<nbv-nnn-1) UVR.Append(UV);
+        // internal nodes
+        for (j=2; j<nr; j++) {
+          double y0 = npl.Value(nbv-j+1);
+          double y1 = npr.Value(nbv-j+1);
+          gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3);
+          gp_Pnt P = S->Value(UV.X(),UV.Y());
+          SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z());
+          meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
+          NodesR.SetValue(i+1,j,N);
+          if (i==dr) UVtmp.Prepend(UV);
+        }
+      }
+      for (i=1; i<=UVtmp.Length() && UVR.Length()<nbv-nnn-1; i++) {
+        UVR.Append(UVtmp.Value(i));
+      }
+      // create faces
+      for (i=1; i<=dr; i++) {
+        for (j=1; j<nr; j++) {
+            SMDS_MeshFace* F =
+              myHelper->AddFace(NodesR.Value(i,j), NodesR.Value(i+1,j),
+                                NodesR.Value(i+1,j+1), NodesR.Value(i,j+1));
+            if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
+        }
+      }
+    }
+    else {
+      // fill UVR using c2d
+      for (i=1; i<npr.Length() && UVR.Length()<nbv-nnn-1; i++) {
+        UVR.Append(gp_UV(uv_er[i].u, uv_er[i].v));
+      }
+    }
+    
+    // step3: create faces for central domain
+    StdMeshers_Array2OfNode NodesC(1,nb,1,nbv);
+    // add first line using NodesL
+    for (i=1; i<=dl+1; i++)
+      NodesC.SetValue(1,i,NodesL(i,1));
+    for (i=2; i<=nl; i++)
+      NodesC.SetValue(1,dl+i,NodesL(dl+1,i));
+    // add last line using NodesR
+    for (i=1; i<=dr+1; i++)
+      NodesC.SetValue(nb,i,NodesR(i,nr));
+    for (i=1; i<nr; i++)
+      NodesC.SetValue(nb,dr+i+1,NodesR(dr+1,nr-i));
+    // add top nodes (last columns)
+    for (i=dl+2; i<nbh-dr; i++) 
+      NodesC.SetValue(i-dl,nbv,uv_et[i-1].node);
+    // add bottom nodes (first columns)
+    for (i=2; i<nb; i++)
+      NodesC.SetValue(i,1,uv_eb[i-1].node);
+    
+    // create and add needed nodes
+    // add linear layers
+    for (i=2; i<nb; i++) {
+      double x0 = npt.Value(dl+i);
+      double x1 = x0;
+      for (j=1; j<nnn; j++) {
+        double y0 = npl.Value(nbv-nnn+j);
+        double y1 = npr.Value(nbv-nnn+j);
+        gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3);
+        gp_Pnt P = S->Value(UV.X(),UV.Y());
+        SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z());
+        meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
+        NodesC.SetValue(i,nbv-nnn+j,N);
+      }
+    }
+    // add diagonal layers
+    for (i=1; i<nbv-nnn; i++) {
+      double du = UVR.Value(i).X() - UVL.Value(i).X();
+      double dv = UVR.Value(i).Y() - UVL.Value(i).Y();
+      for (j=2; j<nb; j++) {
+        double u = UVL.Value(i).X() + du*npb.Value(j);
+        double v = UVL.Value(i).Y() + dv*npb.Value(j);
+        gp_Pnt P = S->Value(u,v);
+        SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z());
+        meshDS->SetNodeOnFace(N, geomFaceID, u, v);
+        NodesC.SetValue(j,i+1,N);
+      }
+    }
+    // create faces
+    for (i=1; i<nb; i++) {
+      for (j=1; j<nbv; j++) {
+          SMDS_MeshFace* F =
+            myHelper->AddFace(NodesC.Value(i,j), NodesC.Value(i+1,j),
+                            NodesC.Value(i+1,j+1), NodesC.Value(i,j+1));
+          if (F) meshDS->SetMeshElementOnShape(F, geomFaceID);
+      }
+    }
+    // TODO ???
+  } // end Multiple Reduce implementation
+  else { // Simple Reduce (!MultipleReduce)
+    //=========================================================
+    if (nr == nl) {
+      if (nt < nb) {
+        // it is a base case => not shift quad
+        //ShiftQuad(quad,0,true);
+      }
+      else {
+        // we have to shift quad on 2
+        ShiftQuad(quad,2,true);
+      }
+    }
+    else {
+      if (nl > nr) {
+        // we have to shift quad on 1
+        ShiftQuad(quad,1,true);
+      }
+      else {
+        // we have to shift quad on 3
+        ShiftQuad(quad,3,true);
+      }
+    }
+
+    nb = quad->side[0]->NbPoints();
+    nr = quad->side[1]->NbPoints();
+    nt = quad->side[2]->NbPoints();
+    nl = quad->side[3]->NbPoints();
+
+    // number of rows and columns
+    int nrows = nr - 1; // and also == nl - 1
+    int ncol_top = nt - 1;
+    int ncol_bot = nb - 1;
+    int npair_top = ncol_top / 2;
+    // maximum number of bottom elements for "linear" simple reduce 4->2
+    int max_lin42 = ncol_top + npair_top * 2 * nrows;
+    // maximum number of bottom elements for "linear" simple reduce 3->1
+    int max_lin31 = ncol_top + ncol_top * 2 * nrows;
+    // maximum number of bottom elements for "tree" simple reduce 4->2
+    int max_tree42 = 0;
+    // number of rows needed to reduce ncol_bot to ncol_top using simple 4->2 "tree"
+    int nrows_tree42 = int( log( (double)(ncol_bot / ncol_top) )/log((double)2)  ); // needed to avoid overflow at pow(2) while computing max_tree42
+    if (nrows_tree42 < nrows) {
+      max_tree42 = npair_top * pow(2.0, nrows + 1);
+      if ( ncol_top > npair_top * 2 ) {
+        int delta = ncol_bot - max_tree42;
+        for (int irow = 1; irow < nrows; irow++) {
+          int nfour = delta / 4;
+          delta -= nfour * 2;
+        }
+        if (delta <= (ncol_top - npair_top * 2))
+          max_tree42 = ncol_bot;
+      }
+    }
+    // maximum number of bottom elements for "tree" simple reduce 3->1
+    //int max_tree31 = ncol_top * pow(3.0, nrows);
+    bool is_lin_31 = false;
+    bool is_lin_42 = false;
+    bool is_tree_31 = false;
+    bool is_tree_42 = false;
+    int max_lin = max_lin42;
+    if (ncol_bot > max_lin42) {
+      if (ncol_bot <= max_lin31) {
+        is_lin_31 = true;
+        max_lin = max_lin31;
+      }
+    }
+    else {
+      // if ncol_bot is a 3*n or not 2*n
+      if ((ncol_bot/3)*3 == ncol_bot || (ncol_bot/2)*2 != ncol_bot) {
+        is_lin_31 = true;
+        max_lin = max_lin31;
+      }
+      else {
+        is_lin_42 = true;
+      }
+    }
+    if (ncol_bot > max_lin) { // not "linear"
+      is_tree_31 = (ncol_bot > max_tree42);
+      if (ncol_bot <= max_tree42) {
+        if ((ncol_bot/3)*3 == ncol_bot || (ncol_bot/2)*2 != ncol_bot) {
+          is_tree_31 = true;
+        }
+        else {
+          is_tree_42 = true;
+        }
+      }
+    }
+
+    const vector<UVPtStruct>& uv_eb = quad->side[0]->GetUVPtStruct(true,0);
+    const vector<UVPtStruct>& uv_er = quad->side[1]->GetUVPtStruct(false,1);
+    const vector<UVPtStruct>& uv_et = quad->side[2]->GetUVPtStruct(true,1);
+    const vector<UVPtStruct>& uv_el = quad->side[3]->GetUVPtStruct(false,0);
+
+    if (uv_eb.size() != nb || uv_er.size() != nr || uv_et.size() != nt || uv_el.size() != nl)
+      return error(COMPERR_BAD_INPUT_MESH);
+
+    myHelper->SetElementsOnShape( true );
+
+    gp_UV uv[ UV_SIZE ];
+    uv[ UV_A0 ].SetCoord( uv_eb.front().u, uv_eb.front().v);
+    uv[ UV_A1 ].SetCoord( uv_eb.back().u,  uv_eb.back().v );
+    uv[ UV_A2 ].SetCoord( uv_et.back().u,  uv_et.back().v );
+    uv[ UV_A3 ].SetCoord( uv_et.front().u, uv_et.front().v);
+
+    vector<UVPtStruct> curr_base = uv_eb, next_base;
+
+    UVPtStruct nullUVPtStruct; nullUVPtStruct.node = 0;
+
+    int curr_base_len = nb;
+    int next_base_len = 0;
+
+    if ( true )
+    { // ------------------------------------------------------------------
+      // New algorithm implemented by request of IPAL22856
+      // "2D quadrangle mesher of reduced type works wrong"
+      // http://bugtracker.opencascade.com/show_bug.cgi?id=22856
+
+      // the algorithm is following: all reduces are centred in horizontal
+      // direction and are distributed among all rows
+
+      if (ncol_bot > max_tree42) {
+        is_lin_31 = true;
+      }
+      else {
+        if ((ncol_top/3)*3 == ncol_top ) {
+          is_lin_31 = true;
+        }
+        else {
+          is_lin_42 = true;
+        }
+      }
+
+      const int col_top_size  = is_lin_42 ? 2 : 1;
+      const int col_base_size = is_lin_42 ? 4 : 3;
+
+      // Compute nb of "columns" (like in "linear" simple reducing) in all rows
+
+      vector<int> nb_col_by_row;
+
+      int delta_all = nb - nt;
+      int delta_one_col = nrows * 2;
+      int nb_col = delta_all / delta_one_col;
+      int remainder = delta_all - nb_col * delta_one_col;
+      if (remainder > 0) {
+        nb_col++;
+      }
+      if ( nb_col * col_top_size >= nt ) // == "tree" reducing situation
+      {
+        // top row is full (all elements reduced), add "columns" one by one
+        // in rows below until all bottom elements are reduced
+        nb_col = ( nt - 1 ) / col_top_size;
+        nb_col_by_row.resize( nrows, nb_col );
+        int nbrows_not_full = nrows - 1;
+        int cur_top_size = nt - 1;
+        remainder = delta_all - nb_col * delta_one_col;
+        while ( remainder > 0 )
+        {
+          delta_one_col = nbrows_not_full * 2;
+          int nb_col_add = remainder / delta_one_col;
+          cur_top_size += 2 * nb_col_by_row[ nbrows_not_full ];
+          int nb_col_free = cur_top_size / col_top_size - nb_col_by_row[ nbrows_not_full-1 ];
+          if ( nb_col_add > nb_col_free )
+            nb_col_add = nb_col_free;
+          for ( int irow = 0; irow < nbrows_not_full; ++irow )
+            nb_col_by_row[ irow ] += nb_col_add;
+          nbrows_not_full --;
+          remainder -=  nb_col_add * delta_one_col;
+        }
+      }
+      else // == "linear" reducing situation
+      {
+        nb_col_by_row.resize( nrows, nb_col );
+        if (remainder > 0)
+          for ( int irow = remainder / 2; irow < nrows; ++irow )
+            nb_col_by_row[ irow ]--;
+      }
+
+      // Make elements
+
+      PReduceFunction reduceFunction = & ( is_lin_42 ? reduce42 : reduce31 );
+
+      const int reduce_grp_size = is_lin_42 ? 4 : 3;
+
+      for (i = 1; i < nr; i++) // layer by layer
+      {
+        nb_col = nb_col_by_row[ i-1 ];
+        int nb_next = curr_base_len - nb_col * 2;
+        if (nb_next < nt) nb_next = nt;
+
+        const double y = uv_el[ i ].normParam;
+
+        if ( i + 1 == nr ) // top
+        {
+          next_base = uv_et;
+        }
+        else
+        {
+          next_base.clear();
+          next_base.resize( nb_next, nullUVPtStruct );
+          next_base.front() = uv_el[i];
+          next_base.back()  = uv_er[i];
+
+          // compute normalized param u
+          double du = 1. / ( nb_next - 1 );
+          next_base[0].normParam = 0.;
+          for ( j = 1; j < nb_next; ++j )
+            next_base[j].normParam = next_base[j-1].normParam + du;
+        }
+        uv[ UV_L ].SetCoord( next_base.front().u, next_base.front().v );
+        uv[ UV_R ].SetCoord( next_base.back().u,  next_base.back().v );
+
+        int free_left = ( curr_base_len - 1 - nb_col * col_base_size ) / 2;
+        int free_middle = curr_base_len - 1 - nb_col * col_base_size - 2 * free_left;
+
+        // not reduced left elements
+        for (j = 0; j < free_left; j++)
+        {
+          // f (i + 1, j + 1)
+          const SMDS_MeshNode*& Nf = next_base[++next_base_len].node;
+          if ( !Nf )
+            Nf = makeNode( next_base[ next_base_len ], y, quad, uv, myHelper, S );
+
+          myHelper->AddFace(curr_base[ j ].node,
+                            curr_base[ j+1 ].node,
+                            Nf,
+                            next_base[ next_base_len-1 ].node);
+        }
+
+        for (int icol = 1; icol <= nb_col; icol++)
+        {
+          // add "H"
+          reduceFunction( curr_base, next_base, j, next_base_len, quad, uv, y, myHelper, S );
+
+          j += reduce_grp_size;
+
+          // elements in the middle of "columns" added for symmetry
+          if ( free_middle > 0 && ( nb_col % 2 == 0 ) && icol == nb_col / 2 )
+          {
+            for (int imiddle = 1; imiddle <= free_middle; imiddle++) {
+              // f (i + 1, j + imiddle)
+              const SMDS_MeshNode*& Nf = next_base[++next_base_len].node;
+              if ( !Nf )
+                Nf = makeNode( next_base[ next_base_len ], y, quad, uv, myHelper, S );
+
+              myHelper->AddFace(curr_base[ j-1+imiddle ].node,
+                                curr_base[ j  +imiddle ].node,
+                                Nf,
+                                next_base[ next_base_len-1 ].node);
+            }
+            j += free_middle;
+          }
+        }
+
+        // not reduced right elements
+        for (; j < curr_base_len-1; j++) {
+          // f (i + 1, j + 1)
+          const SMDS_MeshNode*& Nf = next_base[++next_base_len].node;
+          if ( !Nf )
+            Nf = makeNode( next_base[ next_base_len ], y, quad, uv, myHelper, S );
+
+          myHelper->AddFace(curr_base[ j ].node,
+                            curr_base[ j+1 ].node,
+                            Nf,
+                            next_base[ next_base_len-1 ].node);
+        }
+
+        curr_base_len = next_base_len + 1;
+        next_base_len = 0;
+        curr_base.swap( next_base );
+      }
+
+    }
+    else if ( is_tree_42 || is_tree_31 )
+    {
+      // "tree" simple reduce "42": 2->4->8->16->32->...
+      //
+      //  .-------------------------------.-------------------------------. nr
+      //  |    \                          |                          /    |
+      //  |         \     .---------------.---------------.     /         |
+      //  |               |               |               |               |
+      //  .---------------.---------------.---------------.---------------.
+      //  | \             |             / | \             |             / |
+      //  |     \ .-------.-------. /     |     \ .-------.-------. /     |
+      //  |       |       |       |       |       |       |       |       |
+      //  .-------.-------.-------.-------.-------.-------.-------.-------. i
+      //  |\      |      /|\      |      /|\      |      /|\      |      /|
+      //  |  \.---.---./  |  \.---.---./  |  \.---.---./  |  \.---.---./  |
+      //  |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
+      //  .---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.
+      //  |\  |  /|\  |  /|\  |  /|\  |  /|\  |  /|\  |  /|\  |  /|\  |  /|
+      //  | .-.-. | .-.-. | .-.-. | .-.-. | .-.-. | .-.-. | .-.-. | .-.-. |
+      //  | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+      //  .-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. 1
+      //  1                               j                               nb
+
+      // "tree" simple reduce "31": 1->3->9->27->...
+      //
+      //  .-----------------------------------------------------. nr
+      //  |        \                                   /        |
+      //  |                 .-----------------.                 |
+      //  |                 |                 |                 |
+      //  .-----------------.-----------------.-----------------.
+      //  |   \         /   |   \         /   |   \         /   |
+      //  |     .-----.     |     .-----.     |     .-----.     | i
+      //  |     |     |     |     |     |     |     |     |     |
+      //  .-----.-----.-----.-----.-----.-----.-----.-----.-----.
+      //  |\   /|\   /|\   /|\   /|\   /|\   /|\   /|\   /|\   /|
+      //  | .-. | .-. | .-. | .-. | .-. | .-. | .-. | .-. | .-. |
+      //  | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+      //  .-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. 1
+      //  1                          j                          nb
+
+      PReduceFunction reduceFunction = & ( is_tree_42 ? reduce42 : reduce31 );
+
+      const int reduce_grp_size = is_tree_42 ? 4 : 3;
+
+      for (i = 1; i < nr; i++) // layer by layer
+      {
+        // to stop reducing, if number of nodes reaches nt
+        int delta = curr_base_len - nt;
+
+        // to calculate normalized parameter, we must know number of points in next layer
+        int nb_reduce_groups = (curr_base_len - 1) / reduce_grp_size;
+        int nb_next = nb_reduce_groups * (reduce_grp_size-2) + (curr_base_len - nb_reduce_groups*reduce_grp_size);
+        if (nb_next < nt) nb_next = nt;
+
+        const double y = uv_el[ i ].normParam;
+
+        if ( i + 1 == nr ) // top
+        {
+          next_base = uv_et;
+        }
+        else
+        {
+          next_base.clear();
+          next_base.resize( nb_next, nullUVPtStruct );
+          next_base.front() = uv_el[i];
+          next_base.back()  = uv_er[i];
+
+          // compute normalized param u
+          double du = 1. / ( nb_next - 1 );
+          next_base[0].normParam = 0.;
+          for ( j = 1; j < nb_next; ++j )
+            next_base[j].normParam = next_base[j-1].normParam + du;
+        }
+        uv[ UV_L ].SetCoord( next_base.front().u, next_base.front().v );
+        uv[ UV_R ].SetCoord( next_base.back().u,  next_base.back().v );
+
+        for (j = 0; j+reduce_grp_size < curr_base_len && delta > 0; j+=reduce_grp_size, delta-=2)
+        {
+          reduceFunction( curr_base, next_base, j, next_base_len, quad, uv, y, myHelper, S );
+        }
+
+        // not reduced side elements (if any)
+        for (; j < curr_base_len-1; j++)
+        {
+          // f (i + 1, j + 1)
+          const SMDS_MeshNode*& Nf = next_base[++next_base_len].node;
+          if ( !Nf )
+            Nf = makeNode( next_base[ next_base_len ], y, quad, uv, myHelper, S );
+          
+          myHelper->AddFace(curr_base[ j ].node,
+                            curr_base[ j+1 ].node,
+                            Nf,
+                            next_base[ next_base_len-1 ].node);
+        }
+        curr_base_len = next_base_len + 1;
+        next_base_len = 0;
+        curr_base.swap( next_base );
+      }
+    } // end "tree" simple reduce
+
+    else if ( is_lin_42 || is_lin_31 ) {
+      // "linear" simple reduce "31": 2->6->10->14
+      //
+      //  .-----------------------------.-----------------------------. nr
+      //  |     \                 /     |     \                 /     |
+      //  |         .---------.         |         .---------.         |
+      //  |         |         |         |         |         |         |
+      //  .---------.---------.---------.---------.---------.---------.
+      //  |        / \       / \        |        / \       / \        |
+      //  |       /   .-----.   \       |       /   .-----.   \       | i
+      //  |      /    |     |    \      |      /    |     |    \      |
+      //  .-----.-----.-----.-----.-----.-----.-----.-----.-----.-----.
+      //  |    /     / \   / \     \    |    /     / \   / \     \    |
+      //  |   /     /   .-.   \     \   |   /     /   .-.   \     \   |
+      //  |  /     /   /   \   \     \  |  /     /   /   \   \     \  |
+      //  .--.----.---.-----.---.-----.-.--.----.---.-----.---.-----.-. 1
+      //  1                             j                             nb
+
+      // "linear" simple reduce "42": 4->8->12->16
+      //
+      //  .---------------.---------------.---------------.---------------. nr
+      //  | \             |             / | \             |             / |
+      //  |     \ .-------.-------. /     |     \ .-------.-------. /     |
+      //  |       |       |       |       |       |       |       |       |
+      //  .-------.-------.-------.-------.-------.-------.-------.-------.
+      //  |      / \      |      / \      |      / \      |      / \      |
+      //  |     /   \.----.----./   \     |     /   \.----.----./   \     | i
+      //  |     /    |    |    |    \     |     /    |    |    |    \     |
+      //  .-----.----.----.----.----.-----.-----.----.----.----.----.-----.
+      //  |     /   / \   |  /  \   \     |     /   / \   |  /  \   \     |
+      //  |    /   /    .-.-.    \   \    |    /   /    .-.-.    \   \    |
+      //  |   /   /    /  |  \    \   \   |   /   /    /  |  \    \   \   |
+      //  .---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---. 1
+      //  1                               j                               nb
+
+      // nt = 5, nb = 7, nr = 4
+      //int delta_all = 2;
+      //int delta_one_col = 6;
+      //int nb_col = 0;
+      //int remainder = 2;
+      //if (remainder > 0) nb_col++;
+      //nb_col = 1;
+      //int free_left = 1;
+      //free_left += 2;
+      //int free_middle = 4;
+
+      int delta_all = nb - nt;
+      int delta_one_col = (nr - 1) * 2;
+      int nb_col = delta_all / delta_one_col;
+      int remainder = delta_all - nb_col * delta_one_col;
+      if (remainder > 0) {
+        nb_col++;
+      }
+      const int col_top_size = is_lin_42 ? 2 : 1;
+      int free_left = ((nt - 1) - nb_col * col_top_size) / 2;
+      free_left += nr - 2;
+      int free_middle = (nr - 2) * 2;
+      if (remainder > 0 && nb_col == 1) {
+        int nb_rows_short_col = remainder / 2;
+        int nb_rows_thrown = (nr - 1) - nb_rows_short_col;
+        free_left -= nb_rows_thrown;
+      }
+
+      // nt = 5, nb = 17, nr = 4
+      //int delta_all = 12;
+      //int delta_one_col = 6;
+      //int nb_col = 2;
+      //int remainder = 0;
+      //int free_left = 2;
+      //int free_middle = 4;
+
+      PReduceFunction reduceFunction = & ( is_lin_42 ? reduce42 : reduce31 );
+
+      const int reduce_grp_size = is_lin_42 ? 4 : 3;
+
+      for (i = 1; i < nr; i++, free_middle -= 2, free_left -= 1) // layer by layer
+      {
+        // to calculate normalized parameter, we must know number of points in next layer
+        int nb_next = curr_base_len - nb_col * 2;
+        if (remainder > 0 && i > remainder / 2)
+          // take into account short "column"
+          nb_next += 2;
+        if (nb_next < nt) nb_next = nt;
+
+        const double y = uv_el[ i ].normParam;
+
+        if ( i + 1 == nr ) // top
+        {
+          next_base = uv_et;
+        }
+        else
+        {
+          next_base.clear();
+          next_base.resize( nb_next, nullUVPtStruct );
+          next_base.front() = uv_el[i];
+          next_base.back()  = uv_er[i];
+
+          // compute normalized param u
+          double du = 1. / ( nb_next - 1 );
+          next_base[0].normParam = 0.;
+          for ( j = 1; j < nb_next; ++j )
+            next_base[j].normParam = next_base[j-1].normParam + du;
+        }
+        uv[ UV_L ].SetCoord( next_base.front().u, next_base.front().v );
+        uv[ UV_R ].SetCoord( next_base.back().u,  next_base.back().v );
+
+        // not reduced left elements
+        for (j = 0; j < free_left; j++)
+        {
+          // f (i + 1, j + 1)
+          const SMDS_MeshNode*& Nf = next_base[++next_base_len].node;
+          if ( !Nf )
+            Nf = makeNode( next_base[ next_base_len ], y, quad, uv, myHelper, S );
+
+          myHelper->AddFace(curr_base[ j ].node,
+                            curr_base[ j+1 ].node,
+                            Nf,
+                            next_base[ next_base_len-1 ].node);
+        }
+
+        for (int icol = 1; icol <= nb_col; icol++) {
+
+          if (remainder > 0 && icol == nb_col && i > remainder / 2)
+            // stop short "column"
+            break;
+
+          // add "H"
+          reduceFunction( curr_base, next_base, j, next_base_len, quad, uv, y, myHelper, S );
+
+          j += reduce_grp_size;
+
+          // not reduced middle elements
+          if (icol < nb_col) {
+            if (remainder > 0 && icol == nb_col - 1 && i > remainder / 2)
+              // pass middle elements before stopped short "column"
+              break;
+
+            int free_add = free_middle;
+            if (remainder > 0 && icol == nb_col - 1)
+              // next "column" is short
+              free_add -= (nr - 1) - (remainder / 2);
+
+            for (int imiddle = 1; imiddle <= free_add; imiddle++) {
+              // f (i + 1, j + imiddle)
+              const SMDS_MeshNode*& Nf = next_base[++next_base_len].node;
+              if ( !Nf )
+                Nf = makeNode( next_base[ next_base_len ], y, quad, uv, myHelper, S );
+
+              myHelper->AddFace(curr_base[ j-1+imiddle ].node,
+                                curr_base[ j  +imiddle ].node,
+                                Nf,
+                                next_base[ next_base_len-1 ].node);
+            }
+            j += free_add;
+          }
+        }
+
+        // not reduced right elements
+        for (; j < curr_base_len-1; j++) {
+          // f (i + 1, j + 1)
+          const SMDS_MeshNode*& Nf = next_base[++next_base_len].node;
+          if ( !Nf )
+            Nf = makeNode( next_base[ next_base_len ], y, quad, uv, myHelper, S );
+
+          myHelper->AddFace(curr_base[ j ].node,
+                            curr_base[ j+1 ].node,
+                            Nf,
+                            next_base[ next_base_len-1 ].node);
+        }
+
+        curr_base_len = next_base_len + 1;
+        next_base_len = 0;
+        curr_base.swap( next_base );
+      }
+
+    } // end "linear" simple reduce
+
+    else {
+      return false;
+    }
+  } // end Simple Reduce implementation
+
+  bool isOk = true;
+  return isOk;
+}
+
+//================================================================================
+namespace // data for smoothing
+{
+  struct TSmoothNode;
+  // --------------------------------------------------------------------------------
+  /*!
+   * \brief Structure used to check validity of node position after smoothing.
+   *        It holds two nodes connected to a smoothed node and belonging to
+   *        one mesh face
+   */
+  struct TTriangle
+  {
+    TSmoothNode* _n1;
+    TSmoothNode* _n2;
+    TTriangle( TSmoothNode* n1=0, TSmoothNode* n2=0 ): _n1(n1), _n2(n2) {}
+
+    inline bool IsForward( gp_UV uv ) const;
+  };
+  // --------------------------------------------------------------------------------
+  /*!
+   * \brief Data of a smoothed node
+   */
+  struct TSmoothNode
+  {
+    gp_XY _uv;
+    vector< TTriangle > _triangles; // if empty, then node is not movable
+  };
+  // --------------------------------------------------------------------------------
+  inline bool TTriangle::IsForward( gp_UV uv ) const
+  {
+    gp_Vec2d v1( uv, _n1->_uv ), v2( uv, _n2->_uv );
+    double d = v1 ^ v2;
+    return d > 1e-100;
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Set UV of nodes on degenerated VERTEXes in the middle of degenerated EDGE
+ *
+ * WARNING: this method must be called AFTER retrieving UVPtStruct's from quad
+ */
+//================================================================================
+
+void StdMeshers_Quadrangle_2D::UpdateDegenUV(FaceQuadStruct* quad)
+{
+  for ( unsigned i = 0; i < quad->side.size(); ++i )
+  {
+    StdMeshers_FaceSide* side = quad->side[i];
+    const vector<UVPtStruct>& uvVec = side->GetUVPtStruct();
+
+    // find which end of the side is on degenerated shape
+    int degenInd = -1;
+    if ( myHelper->IsDegenShape( uvVec[0].node->getshapeId() ))
+      degenInd = 0;
+    else if ( myHelper->IsDegenShape( uvVec.back().node->getshapeId() ))
+      degenInd = uvVec.size() - 1;
+    else
+      continue;
+
+    // find another side sharing the degenerated shape
+    bool isPrev = ( degenInd == 0 );
+    if ( i >= TOP_SIDE )
+      isPrev = !isPrev;
+    int i2 = ( isPrev ? ( i + 3 ) : ( i + 1 )) % 4;
+    StdMeshers_FaceSide* side2 = quad->side[ i2 ];
+    const vector<UVPtStruct>& uvVec2 = side2->GetUVPtStruct();
+    int degenInd2 = -1;
+    if ( uvVec[ degenInd ].node == uvVec2[0].node )
+      degenInd2 = 0;
+    else if ( uvVec[ degenInd ].node == uvVec2.back().node )
+      degenInd2 = uvVec2.size() - 1;
+    else
+      throw SALOME_Exception( LOCALIZED( "Logical error" ));
+
+    // move UV in the middle
+    uvPtStruct& uv1 = const_cast<uvPtStruct&>( uvVec [ degenInd  ]);
+    uvPtStruct& uv2 = const_cast<uvPtStruct&>( uvVec2[ degenInd2 ]);
+    uv1.u = uv2.u = 0.5 * ( uv1.u + uv2.u );
+    uv1.v = uv2.v = 0.5 * ( uv1.v + uv2.v );
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Perform smoothing of 2D elements on a FACE with ignored degenerated EDGE
+ */
+//================================================================================
+
+void StdMeshers_Quadrangle_2D::Smooth (FaceQuadStruct* quad)
+{
+  if ( !myNeedSmooth ) return;
+
+  // Get nodes to smooth
+
+  typedef map< const SMDS_MeshNode*, TSmoothNode, TIDCompare > TNo2SmooNoMap;
+  TNo2SmooNoMap smooNoMap;
+
+  const TopoDS_Face& geomFace = TopoDS::Face( myHelper->GetSubShape() );
+  SMESHDS_Mesh* meshDS = myHelper->GetMeshDS();
+  SMESHDS_SubMesh* fSubMesh = meshDS->MeshElements( geomFace );
+  SMDS_NodeIteratorPtr nIt = fSubMesh->GetNodes();
+  while ( nIt->more() ) // loop on nodes bound to a FACE
+  {
+    const SMDS_MeshNode* node = nIt->next();
+    TSmoothNode & sNode = smooNoMap[ node ];
+    sNode._uv = myHelper->GetNodeUV( geomFace, node );
+
+    // set sNode._triangles
+    SMDS_ElemIteratorPtr fIt = node->GetInverseElementIterator( SMDSAbs_Face );
+    while ( fIt->more() )
+    {
+      const SMDS_MeshElement* face = fIt->next();
+      const int nbN = face->NbCornerNodes();
+      const int nInd = face->GetNodeIndex( node );
+      const int prevInd = myHelper->WrapIndex( nInd - 1, nbN );
+      const int nextInd = myHelper->WrapIndex( nInd + 1, nbN );
+      const SMDS_MeshNode* prevNode = face->GetNode( prevInd );
+      const SMDS_MeshNode* nextNode = face->GetNode( nextInd );
+      sNode._triangles.push_back( TTriangle( & smooNoMap[ prevNode ],
+                                             & smooNoMap[ nextNode ]));
+    }
+  }
+  // set _uv of smooth nodes on FACE boundary
+  for ( unsigned i = 0; i < quad->side.size(); ++i )
+  {
+    const vector<UVPtStruct>& uvVec = quad->side[i]->GetUVPtStruct();
+    for ( unsigned j = 0; j < uvVec.size(); ++j )
+    {
+      TSmoothNode & sNode = smooNoMap[ uvVec[j].node ];
+      sNode._uv.SetCoord( uvVec[j].u, uvVec[j].v );
+    }
+  }
+
+  // define refernce orientation in 2D
+  TNo2SmooNoMap::iterator n2sn = smooNoMap.begin();
+  for ( ; n2sn != smooNoMap.end(); ++n2sn )
+    if ( !n2sn->second._triangles.empty() )
+      break;
+  if ( n2sn == smooNoMap.end() ) return;
+  const TSmoothNode & sampleNode = n2sn->second;
+  const bool refForward = ( sampleNode._triangles[0].IsForward( sampleNode._uv ));
+
+  // Smoothing
+
+  for ( int iLoop = 0; iLoop < 5; ++iLoop )
+  {
+    for ( n2sn = smooNoMap.begin(); n2sn != smooNoMap.end(); ++n2sn )
+    {
+      TSmoothNode& sNode = n2sn->second;
+      if ( sNode._triangles.empty() )
+        continue; // not movable node
+
+      // compute a new UV
+      gp_XY newUV (0,0);
+      for ( unsigned i = 0; i < sNode._triangles.size(); ++i )
+        newUV += sNode._triangles[i]._n1->_uv;
+      newUV /= sNode._triangles.size();
+
+      // check validity of the newUV
+      bool isValid = true;
+      for ( unsigned i = 0; i < sNode._triangles.size() && isValid; ++i )
+        isValid = ( sNode._triangles[i].IsForward( newUV ) == refForward );
+
+      if ( isValid )
+        sNode._uv = newUV;
+    }
+  }
+
+  // Set new XYZ to the smoothed nodes
+
+  Handle(Geom_Surface) surface = BRep_Tool::Surface( geomFace );
+
+  for ( n2sn = smooNoMap.begin(); n2sn != smooNoMap.end(); ++n2sn )
+  {
+    TSmoothNode& sNode = n2sn->second;
+    if ( sNode._triangles.empty() )
+      continue; // not movable node
+
+    SMDS_MeshNode* node = const_cast< SMDS_MeshNode*>( n2sn->first );
+    gp_Pnt xyz = surface->Value( sNode._uv.X(), sNode._uv.Y() );
+    meshDS->MoveNode( node, xyz.X(), xyz.Y(), xyz.Z() );
+
+    // store the new UV
+    node->SetPosition( SMDS_PositionPtr( new SMDS_FacePosition( sNode._uv.X(), sNode._uv.Y() )));
+  }
+
+  // Move medium nodes in quadratic mesh
+  if ( _quadraticMesh )
+  {
+    const TLinkNodeMap& links = myHelper->GetTLinkNodeMap();
+    TLinkNodeMap::const_iterator linkIt = links.begin();
+    for ( ; linkIt != links.end(); ++linkIt )
+    {
+      const SMESH_TLink& link = linkIt->first;
+      SMDS_MeshNode*     node = const_cast< SMDS_MeshNode*>( linkIt->second );
+
+      if ( node->getshapeId() != myHelper->GetSubShapeID() )
+        continue; // medium node is on EDGE or VERTEX
+
+      gp_XY uv1 = myHelper->GetNodeUV( geomFace, link.node1(), node );
+      gp_XY uv2 = myHelper->GetNodeUV( geomFace, link.node2(), node );
+
+      gp_XY uv  = myHelper->GetMiddleUV( surface, uv1, uv2 );
+      node->SetPosition( SMDS_PositionPtr( new SMDS_FacePosition( uv.X(), uv.Y() )));
+      
+      gp_Pnt xyz = surface->Value( uv.X(), uv.Y() );
+      meshDS->MoveNode( node, xyz.X(), xyz.Y(), xyz.Z() );
+    }
   }
 }
index 18c1daeca8183eac0a60275544a92622b1d96c3e..3f9202e86dbe883584ec0db8a95bfdd6b2d7c1db 100644 (file)
@@ -1,39 +1,41 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-//  SMESH SMESH : implementaion of SMESH idl descriptions
 //  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_StdMeshers.hxx"
 
+#include "StdMeshers_QuadrangleParams.hxx"
+
 #include "SMESH_2D_Algo.hxx"
 #include "Utils_SALOME_Exception.hxx"
 
+#include <TopoDS_Face.hxx>
+
 class SMESH_Mesh;
 class SMESH_MesherHelper;
 class StdMeshers_FaceSide;
@@ -49,6 +51,7 @@ typedef struct faceQuadStruct
   std::vector< StdMeshers_FaceSide*> side;
   bool isEdgeOut[4]; // true, if an edge has more nodes, than the opposite
   UVPtStruct* uv_grid;
+  TopoDS_Face face;
   ~faceQuadStruct();
 } FaceQuadStruct;
 
@@ -63,20 +66,29 @@ public:
                                SMESH_Hypothesis::Hypothesis_Status& aStatus);
 
   virtual bool Compute(SMESH_Mesh& aMesh,
-                      const TopoDS_Shape& aShape);
+                       const TopoDS_Shape& aShape);
+
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
 
   FaceQuadStruct* CheckAnd2Dcompute(SMESH_Mesh& aMesh,
-                                   const TopoDS_Shape& aShape,
+                                    const TopoDS_Shape& aShape,
                                     const bool CreateQuadratic);
 
-protected:
-
   FaceQuadStruct* CheckNbEdges(SMESH_Mesh& aMesh,
                                const TopoDS_Shape& aShape);
 
+protected:
+
+  bool CheckNbEdgesForEvaluate(SMESH_Mesh& aMesh,
+                               const TopoDS_Shape & aShape,
+                               MapShapeNbElems& aResMap,
+                               std::vector<int>& aNbNodes,
+                               bool& IsQuadratic);
+
   bool SetNormalizedGrid(SMESH_Mesh& aMesh,
-                        const TopoDS_Shape& aShape,
-                        FaceQuadStruct*& quad);
+                         const TopoDS_Shape& aShape,
+                         FaceQuadStruct*& quad);
   
   void SplitQuad(SMESHDS_Mesh *theMeshDS,
                  const int theFaceID,
@@ -85,34 +97,40 @@ protected:
                  const SMDS_MeshNode* theNode3,
                  const SMDS_MeshNode* theNode4);
 
-  /**
-   * Special function for creation only quandrangle faces
-   */
   bool ComputeQuadPref(SMESH_Mesh& aMesh,
-                       
                        const TopoDS_Shape& aShape,
                        FaceQuadStruct* quad);
 
-  UVPtStruct* LoadEdgePoints2(SMESH_Mesh& aMesh,
-                             const TopoDS_Face& F, const TopoDS_Edge& E,
-                              bool IsReverse);
+  bool EvaluateQuadPref(SMESH_Mesh& aMesh,
+                        const TopoDS_Shape& aShape,
+                        std::vector<int>& aNbNodes,
+                        MapShapeNbElems& aResMap,
+                        bool IsQuadratic);
+
+  bool ComputeReduced (SMESH_Mesh& aMesh,
+                       const TopoDS_Shape& aShape,
+                       FaceQuadStruct* quad);
+
+  void UpdateDegenUV(FaceQuadStruct* quad);
 
-  UVPtStruct* LoadEdgePoints(SMESH_Mesh& aMesh,
-                            const TopoDS_Face& F, const TopoDS_Edge& E,
-                            double first, double last);
+  void Smooth (FaceQuadStruct* quad);
 
-  UVPtStruct* MakeEdgePoints(SMESH_Mesh& aMesh,
-                            const TopoDS_Face& F, const TopoDS_Edge& E,
-                            double first, double last, int nb_segm);
 
   // true if QuadranglePreference hypothesis is assigned that forces
   // construction of quadrangles if the number of nodes on opposite edges
-  // is not the same in the case where the global number of nodes on edges is even
+  // is not the same in the case where the global number of nodes on edges
+  // is even
   bool myQuadranglePreference;
 
   bool myTrianglePreference;
 
-  SMESH_MesherHelper* myTool; // tool for working with quadratic elements
+  int myTriaVertexID;
+
+  StdMeshers_QuadType myQuadType;
+
+  SMESH_MesherHelper* myHelper; // tool for working with quadratic elements
+
+  bool myNeedSmooth;
 };
 
 #endif
index 4764356f25d99ba7fb22d9cf97f876d0369f4912..b58504b1f2817ca06e6866394f799d575a90135b 100644 (file)
@@ -1,28 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH StdMeshers_QuadraticMesh : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_QuadraticMesh.cxx
 //  Module : SMESH
-
+//
 #include "StdMeshers_QuadraticMesh.hxx"
 #include "utilities.h"
 
index 9972469c0a3f08bb18eee894ae329f141f8991e3..7d870408b3ef9b318909a4ab021201c45c10ab28 100644 (file)
@@ -1,28 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH StdMeshers : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_QuadraticMesh.hxx
 //  Module : SMESH
-
+//
 #ifndef _StdMeshers_QuadraticMesh_HXX_
 #define _StdMeshers_QuadraticMesh_HXX_
 
index b19f79aee8fc1fe57d993476923fab030db343c7..6ae4ac7873760e900178b83489e59f021251ef4c 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 // File      : StdMeshers_RadialPrism_3D.cxx
 // Module    : SMESH
@@ -37,7 +38,6 @@
 #include "SMESHDS_SubMesh.hxx"
 #include "SMESH_Gen.hxx"
 #include "SMESH_Mesh.hxx"
-#include "SMESH_MeshEditor.hxx"
 #include "SMESH_MesherHelper.hxx"
 #include "SMESH_subMesh.hxx"
 
 #include <BRepAdaptor_Curve.hxx>
 #include <BRepBuilderAPI_MakeEdge.hxx>
 #include <BRepTools.hxx>
+#include <BRep_Tool.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopoDS.hxx>
 #include <TopoDS_Shell.hxx>
 #include <TopoDS_Solid.hxx>
+#include <TopTools_MapOfShape.hxx>
 #include <gp.hxx>
 #include <gp_Pnt.hxx>
 
@@ -70,7 +72,7 @@ StdMeshers_RadialPrism_3D::StdMeshers_RadialPrism_3D(int hypId, int studyId, SME
   :SMESH_3D_Algo(hypId, studyId, gen)
 {
   _name = "RadialPrism_3D";
-  _shapeType = (1 << TopAbs_SOLID);    // 1 bit per shape type
+  _shapeType = (1 << TopAbs_SOLID);     // 1 bit per shape type
 
   _compatibleHypothesis.push_back("LayerDistribution");
   _compatibleHypothesis.push_back("NumberOfLayers");
@@ -170,12 +172,12 @@ bool StdMeshers_RadialPrism_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& a
     return error(COMPERR_BAD_SHAPE, SMESH_Comment("Must be 2 shells but not ")<<nbShells);
 
   // ----------------------------------
-  // Associate subshapes of the shells
+  // Associate sub-shapes of the shells
   // ----------------------------------
 
   TAssocTool::TShapeShapeMap shape2ShapeMap;
-  if ( !TAssocTool::FindSubShapeAssociation( outerShell, &aMesh,
-                                             innerShell, &aMesh,
+  if ( !TAssocTool::FindSubShapeAssociation( innerShell, &aMesh,
+                                             outerShell, &aMesh,
                                              shape2ShapeMap) )
     return error(COMPERR_BAD_SHAPE,"Topology of inner and outer shells seems different" );
 
@@ -188,14 +190,14 @@ bool StdMeshers_RadialPrism_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& a
 
   for ( exp.Init( outerShell, TopAbs_FACE ); exp.More(); exp.Next() )
   {
-    // Corresponding subshapes
+    // Corresponding sub-shapes
     TopoDS_Face outFace = TopoDS::Face( exp.Current() );
     TopoDS_Face inFace;
-    if ( !shape2ShapeMap.IsBound( outFace )) {
+    if ( !shape2ShapeMap.IsBound( outFace, /*isOut=*/true )) {
       return error(SMESH_Comment("Corresponding inner face not found for face #" )
                    << meshDS->ShapeToIndex( outFace ));
     } else {
-      inFace = TopoDS::Face( shape2ShapeMap( outFace ));
+      inFace = TopoDS::Face( shape2ShapeMap( outFace, /*isOut=*/true ));
     }
 
     // Find matching nodes of in and out faces
@@ -387,3 +389,171 @@ bool StdMeshers_RadialPrism_3D::computeLayerPositions(const gp_Pnt& pIn,
   }
   RETURN_BAD_RESULT("Bad hypothesis");
 }
+
+
+//=======================================================================
+//function : Evaluate
+//purpose  : 
+//=======================================================================
+
+bool StdMeshers_RadialPrism_3D::Evaluate(SMESH_Mesh& aMesh,
+                                         const TopoDS_Shape& aShape,
+                                         MapShapeNbElems& aResMap)
+{
+  // get 2 shells
+  TopoDS_Solid solid = TopoDS::Solid( aShape );
+  TopoDS_Shell outerShell = BRepTools::OuterShell( solid );
+  TopoDS_Shape innerShell;
+  int nbShells = 0;
+  for ( TopoDS_Iterator It (solid); It.More(); It.Next(), ++nbShells )
+    if ( !outerShell.IsSame( It.Value() ))
+      innerShell = It.Value();
+  if ( nbShells != 2 ) {
+    std::vector<int> aResVec(SMDSEntity_Last);
+    for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
+    SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+    aResMap.insert(std::make_pair(sm,aResVec));
+    SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+    smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
+    return false;
+  }
+
+  // Associate sub-shapes of the shells
+  TAssocTool::TShapeShapeMap shape2ShapeMap;
+  if ( !TAssocTool::FindSubShapeAssociation( outerShell, &aMesh,
+                                             innerShell, &aMesh,
+                                             shape2ShapeMap) ) {
+    std::vector<int> aResVec(SMDSEntity_Last);
+    for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
+    SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+    aResMap.insert(std::make_pair(sm,aResVec));
+    SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+    smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
+    return false;
+  }
+
+  // get info for outer shell
+  int nb0d_Out=0, nb2d_3_Out=0, nb2d_4_Out=0;
+  //TopTools_SequenceOfShape FacesOut;
+  for (TopExp_Explorer exp(outerShell, TopAbs_FACE); exp.More(); exp.Next()) {
+    //FacesOut.Append(exp.Current());
+    SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current());
+    MapShapeNbElemsItr anIt = aResMap.find(aSubMesh);
+    std::vector<int> aVec = (*anIt).second;
+    nb0d_Out += aVec[SMDSEntity_Node];
+    nb2d_3_Out += Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]);
+    nb2d_4_Out += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]);
+  }
+  int nb1d_Out = 0;
+  TopTools_MapOfShape tmpMap;
+  for (TopExp_Explorer exp(outerShell, TopAbs_EDGE); exp.More(); exp.Next()) {
+    if( tmpMap.Contains( exp.Current() ) )
+      continue;
+    tmpMap.Add( exp.Current() );
+    SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current());
+    MapShapeNbElemsItr anIt = aResMap.find(aSubMesh);
+    std::vector<int> aVec = (*anIt).second;
+    nb0d_Out += aVec[SMDSEntity_Node];
+    nb1d_Out += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]);
+  }
+  tmpMap.Clear();
+  for (TopExp_Explorer exp(outerShell, TopAbs_VERTEX); exp.More(); exp.Next()) {
+    if( tmpMap.Contains( exp.Current() ) )
+      continue;
+    tmpMap.Add( exp.Current() );
+    nb0d_Out++;
+  }
+
+  // get info for inner shell
+  int nb0d_In=0, nb2d_3_In=0, nb2d_4_In=0;
+  //TopTools_SequenceOfShape FacesIn;
+  for (TopExp_Explorer exp(innerShell, TopAbs_FACE); exp.More(); exp.Next()) {
+    //FacesIn.Append(exp.Current());
+    SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current());
+    MapShapeNbElemsItr anIt = aResMap.find(aSubMesh);
+    std::vector<int> aVec = (*anIt).second;
+    nb0d_In += aVec[SMDSEntity_Node];
+    nb2d_3_In += Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]);
+    nb2d_4_In += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]);
+  }
+  int nb1d_In = 0;
+  tmpMap.Clear();
+  bool IsQuadratic = false;
+  bool IsFirst = true;
+  for (TopExp_Explorer exp(innerShell, TopAbs_EDGE); exp.More(); exp.Next()) {
+    if( tmpMap.Contains( exp.Current() ) )
+      continue;
+    tmpMap.Add( exp.Current() );
+    SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current());
+    MapShapeNbElemsItr anIt = aResMap.find(aSubMesh);
+    std::vector<int> aVec = (*anIt).second;
+    nb0d_In += aVec[SMDSEntity_Node];
+    nb1d_In += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]);
+    if(IsFirst) {
+      IsQuadratic = (aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge]);
+      IsFirst = false;
+    }
+  }
+  tmpMap.Clear();
+  for (TopExp_Explorer exp(innerShell, TopAbs_VERTEX); exp.More(); exp.Next()) {
+    if( tmpMap.Contains( exp.Current() ) )
+      continue;
+    tmpMap.Add( exp.Current() );
+    nb0d_In++;
+  }
+
+  bool IsOK = (nb0d_Out==nb0d_In) && (nb1d_Out==nb1d_In) && 
+              (nb2d_3_Out==nb2d_3_In) && (nb2d_4_Out==nb2d_4_In);
+  if(!IsOK) {
+    std::vector<int> aResVec(SMDSEntity_Last);
+    for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
+    SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+    aResMap.insert(std::make_pair(sm,aResVec));
+    SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+    smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
+    return false;
+  }
+
+  int nbLayers = 0;
+  if( myNbLayerHypo ) {
+    nbLayers = myNbLayerHypo->GetNumberOfLayers();
+  }
+  if ( myDistributionHypo ) {
+    if ( !myDistributionHypo->GetLayerDistribution() ) {
+      std::vector<int> aResVec(SMDSEntity_Last);
+      for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
+      SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+      aResMap.insert(std::make_pair(sm,aResVec));
+      SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+      smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
+      return false;
+    }
+    TopExp_Explorer exp(outerShell, TopAbs_VERTEX);
+    TopoDS_Vertex Vout = TopoDS::Vertex(exp.Current());
+    TopoDS_Vertex Vin = TopoDS::Vertex( shape2ShapeMap(Vout) );
+    if ( myLayerPositions.empty() ) {
+      gp_Pnt pIn = BRep_Tool::Pnt(Vin);
+      gp_Pnt pOut = BRep_Tool::Pnt(Vout);
+      computeLayerPositions( pIn, pOut );
+    }
+    nbLayers = myLayerPositions.size() + 1;
+  }
+
+  std::vector<int> aResVec(SMDSEntity_Last);
+  for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
+  if(IsQuadratic) {
+    aResVec[SMDSEntity_Quad_Penta] = nb2d_3_Out * nbLayers;
+    aResVec[SMDSEntity_Quad_Hexa] = nb2d_4_Out * nbLayers;
+    int nb1d = ( nb2d_3_Out*3 + nb2d_4_Out*4 ) / 2;
+    aResVec[SMDSEntity_Node] = nb0d_Out * ( 2*nbLayers - 1 ) - nb1d * nbLayers;
+  }
+  else {
+    aResVec[SMDSEntity_Node] = nb0d_Out * ( nbLayers - 1 );
+    aResVec[SMDSEntity_Penta] = nb2d_3_Out * nbLayers;
+    aResVec[SMDSEntity_Hexa] = nb2d_4_Out * nbLayers;
+  }
+  SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+  aResMap.insert(std::make_pair(sm,aResVec));
+
+  return true;
+}
index d0c78352216509e4d7d2a5a8c50d9e0e2b834bc9..11959d46f8ec37819a60fa1124409469c0c3209f 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_RadialPrism_3D.hxx
 //  Module : SMESH
@@ -51,6 +52,9 @@ public:
 
   virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
 
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
+
 protected:
 
   typedef std::vector<const SMDS_MeshNode* >            TNodeColumn;
diff --git a/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx b/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx
new file mode 100644 (file)
index 0000000..d93c64e
--- /dev/null
@@ -0,0 +1,1285 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+// File      : StdMeshers_RadialQuadrangle_1D2D.cxx
+// Module    : SMESH
+// Created   : Fri Oct 20 11:37:07 2006
+// Author    : Edward AGAPOV (eap)
+
+#include "StdMeshers_RadialQuadrangle_1D2D.hxx"
+
+#include "StdMeshers_NumberOfLayers.hxx"
+#include "StdMeshers_LayerDistribution.hxx"
+#include "StdMeshers_Regular_1D.hxx"
+#include "StdMeshers_NumberOfSegments.hxx"
+
+#include "SMDS_MeshNode.hxx"
+#include "SMESHDS_SubMesh.hxx"
+#include "SMESH_Gen.hxx"
+#include "SMESH_HypoFilter.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_MesherHelper.hxx"
+#include "SMESH_subMesh.hxx"
+#include "SMESH_subMeshEventListener.hxx"
+
+#include "utilities.h"
+
+#include <BRepAdaptor_Curve.hxx>
+#include <BRepBuilderAPI_MakeEdge.hxx>
+#include <BRep_Tool.hxx>
+#include <GeomAPI_ProjectPointOnSurf.hxx>
+#include <Geom_Circle.hxx>
+#include <Geom_Line.hxx>
+#include <Geom_TrimmedCurve.hxx>
+#include <TColgp_SequenceOfPnt.hxx>
+#include <TColgp_SequenceOfPnt2d.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopoDS.hxx>
+
+
+using namespace std;
+
+#define RETURN_BAD_RESULT(msg) { MESSAGE(")-: Error: " << msg); return false; }
+#define gpXYZ(n) gp_XYZ(n->X(),n->Y(),n->Z())
+
+
+//=======================================================================
+//function : StdMeshers_RadialQuadrangle_1D2D
+//purpose  : 
+//=======================================================================
+
+StdMeshers_RadialQuadrangle_1D2D::StdMeshers_RadialQuadrangle_1D2D(int hypId,
+                                                                   int studyId,
+                                                                   SMESH_Gen* gen)
+  :SMESH_2D_Algo(hypId, studyId, gen)
+{
+  _name = "RadialQuadrangle_1D2D";
+  _shapeType = (1 << TopAbs_FACE);        // 1 bit per shape type
+
+  _compatibleHypothesis.push_back("LayerDistribution2D");
+  _compatibleHypothesis.push_back("NumberOfLayers2D");
+  myNbLayerHypo = 0;
+  myDistributionHypo = 0;
+  _requireDiscreteBoundary = false;
+  _supportSubmeshes = true;
+}
+
+
+//================================================================================
+/*!
+ * \brief Destructor
+ */
+//================================================================================
+
+StdMeshers_RadialQuadrangle_1D2D::~StdMeshers_RadialQuadrangle_1D2D()
+{}
+
+
+//=======================================================================
+//function : CheckHypothesis
+//purpose  : 
+//=======================================================================
+
+bool StdMeshers_RadialQuadrangle_1D2D::CheckHypothesis
+                           (SMESH_Mesh&                          aMesh,
+                            const TopoDS_Shape&                  aShape,
+                            SMESH_Hypothesis::Hypothesis_Status& aStatus)
+{
+  // check aShape 
+  myNbLayerHypo = 0;
+  myDistributionHypo = 0;
+
+  list <const SMESHDS_Hypothesis * >::const_iterator itl;
+
+  const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
+  if ( hyps.size() == 0 ) {
+    aStatus = SMESH_Hypothesis::HYP_OK;
+    return true;  // can work with no hypothesis
+  }
+
+  if ( hyps.size() > 1 ) {
+    aStatus = SMESH_Hypothesis::HYP_ALREADY_EXIST;
+    return false;
+  }
+
+  const SMESHDS_Hypothesis *theHyp = hyps.front();
+
+  string hypName = theHyp->GetName();
+
+  if (hypName == "NumberOfLayers2D") {
+    myNbLayerHypo = static_cast<const StdMeshers_NumberOfLayers *>(theHyp);
+    aStatus = SMESH_Hypothesis::HYP_OK;
+    return true;
+  }
+  if (hypName == "LayerDistribution2D") {
+    myDistributionHypo = static_cast<const StdMeshers_LayerDistribution *>(theHyp);
+    aStatus = SMESH_Hypothesis::HYP_OK;
+    return true;
+  }
+  aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
+  return true;
+}
+
+namespace
+{
+  // ------------------------------------------------------------------------------
+  /*!
+   * \brief Listener used to mark edges meshed by StdMeshers_RadialQuadrangle_1D2D
+   */
+  class TEdgeMarker : public SMESH_subMeshEventListener
+  {
+    TEdgeMarker(): SMESH_subMeshEventListener(/*isDeletable=*/false,
+                                              "StdMeshers_RadialQuadrangle_1D2D::TEdgeMarker") {}
+  public:
+    //!<  Return static listener
+    static SMESH_subMeshEventListener* getListener()
+    {
+      static TEdgeMarker theEdgeMarker;
+      return &theEdgeMarker;
+    }
+    //! Clear face sumbesh if something happens on edges
+    void ProcessEvent(const int          event,
+                      const int          eventType,
+                      SMESH_subMesh*     edgeSubMesh,
+                      EventListenerData* data,
+                      const SMESH_Hypothesis*  /*hyp*/)
+    {
+      if ( data && !data->mySubMeshes.empty() && eventType == SMESH_subMesh::ALGO_EVENT)
+      {
+        ASSERT( data->mySubMeshes.front() != edgeSubMesh );
+        SMESH_subMesh* faceSubMesh = data->mySubMeshes.front();
+        faceSubMesh->ComputeStateEngine( SMESH_subMesh::CLEAN );
+      }
+    }
+  };
+
+  // ------------------------------------------------------------------------------
+  /*!
+   * \brief Mark an edge as computed by StdMeshers_RadialQuadrangle_1D2D
+   */
+  void markEdgeAsComputedByMe(const TopoDS_Edge& edge, SMESH_subMesh* faceSubMesh)
+  {
+    if ( SMESH_subMesh* edgeSM = faceSubMesh->GetFather()->GetSubMeshContaining( edge ))
+    {
+      if ( !edgeSM->GetEventListenerData( TEdgeMarker::getListener() ))
+        faceSubMesh->SetEventListener( TEdgeMarker::getListener(),
+                                       SMESH_subMeshEventListenerData::MakeData(faceSubMesh),
+                                       edgeSM);
+    }
+  }
+  // ------------------------------------------------------------------------------
+  /*!
+   * \brief Return true if a radial edge was meshed with StdMeshers_RadialQuadrangle_1D2D with
+   * the same radial distribution
+   */
+//   bool isEdgeCompatiballyMeshed(const TopoDS_Edge& edge, SMESH_subMesh* faceSubMesh)
+//   {
+//     if ( SMESH_subMesh* edgeSM = faceSubMesh->GetFather()->GetSubMeshContaining( edge ))
+//     {
+//       if ( SMESH_subMeshEventListenerData* otherFaceData =
+//            edgeSM->GetEventListenerData( TEdgeMarker::getListener() ))
+//       {
+//         // compare hypothesis aplied to two disk faces sharing radial edges
+//         SMESH_Mesh& mesh = *faceSubMesh->GetFather();
+//         SMESH_Algo* radialQuadAlgo = mesh.GetGen()->GetAlgo(mesh, faceSubMesh->GetSubShape() );
+//         SMESH_subMesh* otherFaceSubMesh = otherFaceData->mySubMeshes.front();
+//         list <const SMESHDS_Hypothesis *> hyps1 =
+//           radialQuadAlgo->GetUsedHypothesis( mesh, faceSubMesh->GetSubShape());
+//         list <const SMESHDS_Hypothesis *> hyps2 =
+//           radialQuadAlgo->GetUsedHypothesis( mesh, otherFaceSubMesh->GetSubShape());
+//         if( hyps1.empty() && hyps2.empty() )
+//           return true; // defaul hyps
+//         if ( hyps1.size() != hyps2.size() )
+//           return false;
+//         return *hyps1.front() == *hyps2.front();
+//       }
+//     }
+//     return false;
+//   }
+
+  //================================================================================
+  /*!
+   * \brief Return base curve of the edge and extremum parameters
+   */
+  //================================================================================
+
+  Handle(Geom_Curve) getCurve(const TopoDS_Edge& edge, double* f=0, double* l=0)
+  {
+    Handle(Geom_Curve) C;
+    if ( !edge.IsNull() )
+    {
+      double first = 0., last = 0.;
+      C = BRep_Tool::Curve(edge, first, last);
+      if ( !C.IsNull() )
+      {
+        Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(C);
+        while( !tc.IsNull() ) {
+          C = tc->BasisCurve();
+          tc = Handle(Geom_TrimmedCurve)::DownCast(C);
+        }
+        if ( f ) *f = first;
+        if ( l ) *l = last;
+      }
+    }
+    return C;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Return edges of the face
+   *  \retval int - nb of edges
+   */
+  //================================================================================
+
+  int analyseFace(const TopoDS_Shape& face,
+                  TopoDS_Edge&        CircEdge,
+                  TopoDS_Edge&        LinEdge1,
+                  TopoDS_Edge&        LinEdge2)
+  {
+    CircEdge.Nullify(); LinEdge1.Nullify(); LinEdge2.Nullify();
+    int nbe = 0;
+
+    for ( TopExp_Explorer exp( face, TopAbs_EDGE ); exp.More(); exp.Next(), ++nbe )
+    {
+      const TopoDS_Edge& E = TopoDS::Edge( exp.Current() );
+      double f,l;
+      Handle(Geom_Curve) C = getCurve(E,&f,&l);
+      if ( !C.IsNull() )
+      {
+        if ( C->IsKind( STANDARD_TYPE(Geom_Circle)))
+        {
+          if ( CircEdge.IsNull() )
+            CircEdge = E;
+          else
+            return 0;
+        }
+        else if ( LinEdge1.IsNull() )
+          LinEdge1 = E;
+        else
+          LinEdge2 = E;
+      }
+    }
+    return nbe;
+  }
+
+//================================================================================
+//================================================================================
+/*!
+ * \brief Class computing layers distribution using data of
+ *        StdMeshers_LayerDistribution hypothesis
+ */
+//================================================================================
+//================================================================================
+
+class TNodeDistributor: public StdMeshers_Regular_1D
+{
+  list <const SMESHDS_Hypothesis *> myUsedHyps;
+public:
+  // -----------------------------------------------------------------------------
+  static TNodeDistributor* GetDistributor(SMESH_Mesh& aMesh)
+  {
+    const int myID = -1000;
+    map < int, SMESH_1D_Algo * > & algoMap = aMesh.GetGen()->_map1D_Algo;
+    map < int, SMESH_1D_Algo * >::iterator id_algo = algoMap.find( myID );
+    if ( id_algo == algoMap.end() )
+      return new TNodeDistributor( myID, 0, aMesh.GetGen() );
+    return static_cast< TNodeDistributor* >( id_algo->second );
+  }
+  // -----------------------------------------------------------------------------
+  //! Computes distribution of nodes on a straight line ending at pIn and pOut
+  bool Compute( vector< double > &      positions,
+                gp_Pnt                  pIn,
+                gp_Pnt                  pOut,
+                SMESH_Mesh&             aMesh,
+                const SMESH_Hypothesis* hyp1d)
+  {
+    if ( !hyp1d ) return error( "Invalid LayerDistribution hypothesis");
+
+    double len = pIn.Distance( pOut );
+    if ( len <= DBL_MIN ) return error("Too close points of inner and outer shells");
+
+    myUsedHyps.clear();
+    myUsedHyps.push_back( hyp1d );
+
+    TopoDS_Edge edge = BRepBuilderAPI_MakeEdge( pIn, pOut );
+    SMESH_Hypothesis::Hypothesis_Status aStatus;
+    if ( !StdMeshers_Regular_1D::CheckHypothesis( aMesh, edge, aStatus ))
+      return error( "StdMeshers_Regular_1D::CheckHypothesis() failed "
+                    "with LayerDistribution hypothesis");
+
+    BRepAdaptor_Curve C3D(edge);
+    double f = C3D.FirstParameter(), l = C3D.LastParameter();
+    list< double > params;
+    if ( !StdMeshers_Regular_1D::computeInternalParameters( aMesh, C3D, len, f, l, params, false ))
+      return error("StdMeshers_Regular_1D failed to compute layers distribution");
+
+    positions.clear();
+    positions.reserve( params.size() );
+    for (list<double>::iterator itU = params.begin(); itU != params.end(); itU++)
+      positions.push_back( *itU / len );
+    return true;
+  }
+  // -----------------------------------------------------------------------------
+  //! Make mesh on an adge using assigned 1d hyp or defaut nb of segments
+  bool ComputeCircularEdge(SMESH_Mesh&         aMesh,
+                           const TopoDS_Edge& anEdge)
+  {
+    _gen->Compute( aMesh, anEdge);
+    SMESH_subMesh *sm = aMesh.GetSubMesh(anEdge);
+    if ( sm->GetComputeState() != SMESH_subMesh::COMPUTE_OK)
+    {
+      // find any 1d hyp assigned (there can be a hyp w/o algo)
+      myUsedHyps = SMESH_Algo::GetUsedHypothesis(aMesh, anEdge, /*ignoreAux=*/true);
+      Hypothesis_Status aStatus;
+      if ( !StdMeshers_Regular_1D::CheckHypothesis( aMesh, anEdge, aStatus ))
+      {
+        // no valid 1d hyp assigned, use default nb of segments
+        _hypType                    = NB_SEGMENTS;
+        _ivalue[ DISTR_TYPE_IND ]   = StdMeshers_NumberOfSegments::DT_Regular;
+        _ivalue[ NB_SEGMENTS_IND  ] = _gen->GetDefaultNbSegments();
+      }
+      return StdMeshers_Regular_1D::Compute( aMesh, anEdge );
+    }
+    return true;
+  }
+  // -----------------------------------------------------------------------------
+  //! Make mesh on an adge using assigned 1d hyp or defaut nb of segments
+  bool EvaluateCircularEdge(SMESH_Mesh&        aMesh,
+                            const TopoDS_Edge& anEdge,
+                            MapShapeNbElems&   aResMap)
+  {
+    _gen->Evaluate( aMesh, anEdge, aResMap );
+    if ( aResMap.count( aMesh.GetSubMesh( anEdge )))
+      return true;
+
+    // find any 1d hyp assigned
+    myUsedHyps = SMESH_Algo::GetUsedHypothesis(aMesh, anEdge, /*ignoreAux=*/true);
+    Hypothesis_Status aStatus;
+    if ( !StdMeshers_Regular_1D::CheckHypothesis( aMesh, anEdge, aStatus ))
+    {
+      // no valid 1d hyp assigned, use default nb of segments
+      _hypType                    = NB_SEGMENTS;
+      _ivalue[ DISTR_TYPE_IND ]   = StdMeshers_NumberOfSegments::DT_Regular;
+      _ivalue[ NB_SEGMENTS_IND  ] = _gen->GetDefaultNbSegments();
+    }
+    return StdMeshers_Regular_1D::Evaluate( aMesh, anEdge, aResMap );
+  }
+protected:
+  // -----------------------------------------------------------------------------
+  TNodeDistributor( int hypId, int studyId, SMESH_Gen* gen)
+    : StdMeshers_Regular_1D( hypId, studyId, gen)
+  {
+  }
+  // -----------------------------------------------------------------------------
+  virtual const list <const SMESHDS_Hypothesis *> &
+    GetUsedHypothesis(SMESH_Mesh &, const TopoDS_Shape &, const bool)
+  {
+    return myUsedHyps;
+  }
+  // -----------------------------------------------------------------------------
+};
+}
+
+//=======================================================================
+/*!
+ * \brief Allow algo to do something after persistent restoration
+ * \param subMesh - restored submesh
+ *
+ * call markEdgeAsComputedByMe()
+ */
+//=======================================================================
+
+void StdMeshers_RadialQuadrangle_1D2D::SubmeshRestored(SMESH_subMesh* faceSubMesh)
+{
+  if ( !faceSubMesh->IsEmpty() )
+  {
+    TopoDS_Edge CircEdge, LinEdge1, LinEdge2;
+    analyseFace( faceSubMesh->GetSubShape(), CircEdge, LinEdge1, LinEdge2 );
+    if ( !CircEdge.IsNull() ) markEdgeAsComputedByMe( CircEdge, faceSubMesh );
+    if ( !LinEdge1.IsNull() ) markEdgeAsComputedByMe( LinEdge1, faceSubMesh );
+    if ( !LinEdge2.IsNull() ) markEdgeAsComputedByMe( LinEdge2, faceSubMesh );
+  }
+}
+
+//=======================================================================
+//function : Compute
+//purpose  : 
+//=======================================================================
+
+bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh&         aMesh,
+                                               const TopoDS_Shape& aShape)
+{
+  SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
+
+  myHelper = new SMESH_MesherHelper( aMesh );
+  myHelper->IsQuadraticSubMesh( aShape );
+  // to delete helper at exit from Compute()
+  auto_ptr<SMESH_MesherHelper> helperDeleter( myHelper );
+
+  TNodeDistributor* algo1d = TNodeDistributor::GetDistributor(aMesh);
+
+  TopoDS_Edge CircEdge, LinEdge1, LinEdge2;
+  int nbe = analyseFace( aShape, CircEdge, LinEdge1, LinEdge2 );
+  Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast( getCurve( CircEdge ));
+  if( nbe>3 || nbe < 1 || aCirc.IsNull() )
+    return error("The face must be a full circle or a part of circle (i.e. the number of edges is less or equal to 3 and one of them is a circle curve)");
+  
+  gp_Pnt P0, P1;
+  // points for rotation
+  TColgp_SequenceOfPnt Points;
+  // angles for rotation
+  TColStd_SequenceOfReal Angles;
+  // Nodes1 and Nodes2 - nodes along radiuses
+  // CNodes - nodes on circle edge
+  vector< const SMDS_MeshNode* > Nodes1, Nodes2, CNodes;
+  SMDS_MeshNode * NC;
+  // parameters edge nodes on face
+  TColgp_SequenceOfPnt2d Pnts2d1;
+  gp_Pnt2d PC;
+
+  int faceID = meshDS->ShapeToIndex(aShape);
+  TopoDS_Face F = TopoDS::Face(aShape);
+  Handle(Geom_Surface) S = BRep_Tool::Surface(F);
+
+
+  if(nbe==1)
+  {
+    if (!algo1d->ComputeCircularEdge( aMesh, CircEdge ))
+      return error( algo1d->GetComputeError() );
+    map< double, const SMDS_MeshNode* > theNodes;
+    if ( !GetSortedNodesOnEdge(aMesh.GetMeshDS(),CircEdge,true,theNodes))
+      return error("Circular edge is incorrectly meshed");
+
+    CNodes.clear();
+    map< double, const SMDS_MeshNode* >::iterator itn = theNodes.begin();
+    const SMDS_MeshNode* NF = (*itn).second;
+    CNodes.push_back( (*itn).second );
+    double fang = (*itn).first;
+    if ( itn != theNodes.end() ) {
+      itn++;
+      for(; itn != theNodes.end(); itn++ ) {
+        CNodes.push_back( (*itn).second );
+        double ang = (*itn).first - fang;
+        if( ang>M_PI ) ang = ang - 2.*M_PI;
+        if( ang<-M_PI ) ang = ang + 2.*M_PI;
+        Angles.Append( ang ); 
+      }
+    }
+    P1 = gp_Pnt( NF->X(), NF->Y(), NF->Z() );
+    P0 = aCirc->Location();
+
+    if ( !computeLayerPositions(P0,P1))
+      return false;
+
+    TopoDS_Vertex V1 = myHelper->IthVertex(0, CircEdge );
+    gp_Pnt2d p2dV = BRep_Tool::Parameters( V1, TopoDS::Face(aShape) );
+
+    NC = meshDS->AddNode(P0.X(), P0.Y(), P0.Z());
+    GeomAPI_ProjectPointOnSurf PPS(P0,S);
+    double U0,V0;
+    PPS.Parameters(1,U0,V0);
+    meshDS->SetNodeOnFace(NC, faceID, U0, V0);
+    PC = gp_Pnt2d(U0,V0);
+
+    gp_Vec aVec(P0,P1);
+    gp_Vec2d aVec2d(PC,p2dV);
+    Nodes1.resize( myLayerPositions.size()+1 );
+    Nodes2.resize( myLayerPositions.size()+1 );
+    int i = 0;
+    for(; i<myLayerPositions.size(); i++) {
+      gp_Pnt P( P0.X() + aVec.X()*myLayerPositions[i],
+                P0.Y() + aVec.Y()*myLayerPositions[i],
+                P0.Z() + aVec.Z()*myLayerPositions[i] );
+      Points.Append(P);
+      SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z());
+      Nodes1[i] = node;
+      Nodes2[i] = node;
+      double U = PC.X() + aVec2d.X()*myLayerPositions[i];
+      double V = PC.Y() + aVec2d.Y()*myLayerPositions[i];
+      meshDS->SetNodeOnFace( node, faceID, U, V );
+      Pnts2d1.Append(gp_Pnt2d(U,V));
+    }
+    Nodes1[Nodes1.size()-1] = NF;
+    Nodes2[Nodes1.size()-1] = NF;
+  }
+  else if(nbe==2 && LinEdge1.Orientation() != TopAbs_INTERNAL )
+  {
+    // one curve must be a half of circle and other curve must be
+    // a segment of line
+    double fp, lp;
+    Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast( getCurve( CircEdge, &fp, &lp ));
+    if( fabs(fabs(lp-fp)-M_PI) > Precision::Confusion() ) {
+      // not half of circle
+      return error(COMPERR_BAD_SHAPE);
+    }
+    Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast( getCurve( LinEdge1 ));
+    if( aLine.IsNull() ) {
+      // other curve not line
+      return error(COMPERR_BAD_SHAPE);
+    }
+
+    if ( !algo1d->ComputeCircularEdge( aMesh, CircEdge ))
+      return error( algo1d->GetComputeError() );
+    map< double, const SMDS_MeshNode* > theNodes;
+    if ( !GetSortedNodesOnEdge(aMesh.GetMeshDS(),CircEdge,true,theNodes) )
+      return error("Circular edge is incorrectly meshed");
+
+    map< double, const SMDS_MeshNode* >::iterator itn = theNodes.begin();
+    CNodes.clear();
+    CNodes.push_back( itn->second );
+    double fang = (*itn).first;
+    itn++;
+    for(; itn != theNodes.end(); itn++ ) {
+      CNodes.push_back( (*itn).second );
+      double ang = (*itn).first - fang;
+      if( ang>M_PI ) ang = ang - 2.*M_PI;
+      if( ang<-M_PI ) ang = ang + 2.*M_PI;
+      Angles.Append( ang );
+    }
+    const SMDS_MeshNode* NF = theNodes.begin()->second;
+    const SMDS_MeshNode* NL = theNodes.rbegin()->second;
+    P1 = gp_Pnt( NF->X(), NF->Y(), NF->Z() );
+    gp_Pnt P2( NL->X(), NL->Y(), NL->Z() );
+    P0 = aCirc->Location();
+
+    bool linEdgeComputed;
+    if ( !computeLayerPositions(P0,P1,LinEdge1,&linEdgeComputed))
+      return false;
+
+    if ( linEdgeComputed )
+    {
+      if (!GetSortedNodesOnEdge(aMesh.GetMeshDS(),LinEdge1,true,theNodes))
+        return error("Invalid mesh on a straight edge");
+
+      Nodes1.resize( myLayerPositions.size()+1 );
+      Nodes2.resize( myLayerPositions.size()+1 );
+      vector< const SMDS_MeshNode* > *pNodes1 = &Nodes1, *pNodes2 = &Nodes2;
+      bool nodesFromP0ToP1 = ( theNodes.rbegin()->second == NF );
+      if ( !nodesFromP0ToP1 ) std::swap( pNodes1, pNodes2 );
+
+      map< double, const SMDS_MeshNode* >::reverse_iterator ritn = theNodes.rbegin();
+      itn = theNodes.begin();
+      for ( int i = Nodes1.size()-1; i > -1; ++itn, ++ritn, --i )
+      {
+        (*pNodes1)[i] = ritn->second;
+        (*pNodes2)[i] =  itn->second;
+        Points.Prepend( gpXYZ( Nodes1[i]));
+        Pnts2d1.Prepend( myHelper->GetNodeUV( F, Nodes1[i]));
+      }
+      NC = const_cast<SMDS_MeshNode*>( itn->second );
+      Points.Remove( Nodes1.size() );
+    }
+    else
+    {
+      gp_Vec aVec(P0,P1);
+      int edgeID = meshDS->ShapeToIndex(LinEdge1);
+      // check orientation
+      Handle(Geom_Curve) Crv = BRep_Tool::Curve(LinEdge1,fp,lp);
+      gp_Pnt Ptmp;
+      Crv->D0(fp,Ptmp);
+      bool ori = true;
+      if( P1.Distance(Ptmp) > Precision::Confusion() )
+        ori = false;
+      // get UV points for edge
+      gp_Pnt2d PF,PL;
+      BRep_Tool::UVPoints( LinEdge1, TopoDS::Face(aShape), PF, PL );
+      PC = gp_Pnt2d( (PF.X()+PL.X())/2, (PF.Y()+PL.Y())/2 );
+      gp_Vec2d V2d;
+      if(ori) V2d = gp_Vec2d(PC,PF);
+      else V2d = gp_Vec2d(PC,PL);
+      // add nodes on edge
+      double cp = (fp+lp)/2;
+      double dp2 = (lp-fp)/2;
+      NC = meshDS->AddNode(P0.X(), P0.Y(), P0.Z());
+      meshDS->SetNodeOnEdge(NC, edgeID, cp);
+      Nodes1.resize( myLayerPositions.size()+1 );
+      Nodes2.resize( myLayerPositions.size()+1 );
+      int i = 0;
+      for(; i<myLayerPositions.size(); i++) {
+        gp_Pnt P( P0.X() + aVec.X()*myLayerPositions[i],
+                  P0.Y() + aVec.Y()*myLayerPositions[i],
+                  P0.Z() + aVec.Z()*myLayerPositions[i] );
+        Points.Append(P);
+        SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z());
+        Nodes1[i] = node;
+        double param;
+        if(ori)
+          param = fp + dp2*(1-myLayerPositions[i]);
+        else
+          param = cp + dp2*myLayerPositions[i];
+        meshDS->SetNodeOnEdge(node, edgeID, param);
+        P = gp_Pnt( P0.X() - aVec.X()*myLayerPositions[i],
+                    P0.Y() - aVec.Y()*myLayerPositions[i],
+                    P0.Z() - aVec.Z()*myLayerPositions[i] );
+        node = meshDS->AddNode(P.X(), P.Y(), P.Z());
+        Nodes2[i] = node;
+        if(!ori)
+          param = fp + dp2*(1-myLayerPositions[i]);
+        else
+          param = cp + dp2*myLayerPositions[i];
+        meshDS->SetNodeOnEdge(node, edgeID, param);
+        // parameters on face
+        gp_Pnt2d P2d( PC.X() + V2d.X()*myLayerPositions[i],
+                      PC.Y() + V2d.Y()*myLayerPositions[i] );
+        Pnts2d1.Append(P2d);
+      }
+      Nodes1[ myLayerPositions.size() ] = NF;
+      Nodes2[ myLayerPositions.size() ] = NL;
+      // create 1D elements on edge
+      vector< const SMDS_MeshNode* > tmpNodes;
+      tmpNodes.resize(2*Nodes1.size()+1);
+      for(i=0; i<Nodes2.size(); i++)
+        tmpNodes[Nodes2.size()-i-1] = Nodes2[i];
+      tmpNodes[Nodes2.size()] = NC;
+      for(i=0; i<Nodes1.size(); i++)
+        tmpNodes[Nodes2.size()+1+i] = Nodes1[i];
+      for(i=1; i<tmpNodes.size(); i++) {
+        SMDS_MeshEdge* ME = myHelper->AddEdge( tmpNodes[i-1], tmpNodes[i] );
+        if(ME) meshDS->SetMeshElementOnShape(ME, edgeID);
+      }
+      markEdgeAsComputedByMe( LinEdge1, aMesh.GetSubMesh( F ));
+    }
+  }
+  else // nbe==3 or ( nbe==2 && linEdge is INTERNAL )
+  {
+    if (nbe==2 && LinEdge1.Orientation() == TopAbs_INTERNAL )
+      LinEdge2 = LinEdge1;
+
+    // one curve must be a part of circle and other curves must be
+    // segments of line
+    double fp, lp;
+    Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast( getCurve( CircEdge ));
+    Handle(Geom_Line)  aLine1 = Handle(Geom_Line)::DownCast( getCurve( LinEdge1 ));
+    Handle(Geom_Line)  aLine2 = Handle(Geom_Line)::DownCast( getCurve( LinEdge2 ));
+    if( aCirc.IsNull() || aLine1.IsNull() || aLine2.IsNull() )
+      return error(COMPERR_BAD_SHAPE);
+
+    if ( !algo1d->ComputeCircularEdge( aMesh, CircEdge ))
+      return error( algo1d->GetComputeError() );
+    map< double, const SMDS_MeshNode* > theNodes;
+    if ( !GetSortedNodesOnEdge(aMesh.GetMeshDS(),CircEdge,true,theNodes))
+      return error("Circular edge is incorrectly meshed");
+
+    const SMDS_MeshNode* NF = theNodes.begin()->second;
+    const SMDS_MeshNode* NL = theNodes.rbegin()->second;
+    CNodes.clear();
+    CNodes.push_back( NF );
+    map< double, const SMDS_MeshNode* >::iterator itn = theNodes.begin();
+    double fang = (*itn).first;
+    itn++;
+    for(; itn != theNodes.end(); itn++ ) {
+      CNodes.push_back( (*itn).second );
+      double ang = (*itn).first - fang;
+      if( ang>M_PI ) ang = ang - 2.*M_PI;
+      if( ang<-M_PI ) ang = ang + 2.*M_PI;
+      Angles.Append( ang );
+    }
+    P1 = gp_Pnt( NF->X(), NF->Y(), NF->Z() );
+    gp_Pnt P2( NL->X(), NL->Y(), NL->Z() );
+    P0 = aCirc->Location();
+
+    // make P1 belong to LinEdge1
+    TopoDS_Vertex V1 = myHelper->IthVertex( 0, LinEdge1 );
+    TopoDS_Vertex V2 = myHelper->IthVertex( 1, LinEdge1 );
+    gp_Pnt PE1 = BRep_Tool::Pnt(V1);
+    gp_Pnt PE2 = BRep_Tool::Pnt(V2);
+    if( ( P1.Distance(PE1) > Precision::Confusion() ) &&
+        ( P1.Distance(PE2) > Precision::Confusion() ) )
+      std::swap( LinEdge1, LinEdge2 );
+
+    bool linEdge1Computed, linEdge2Computed;
+    if ( !computeLayerPositions(P0,P1,LinEdge1,&linEdge1Computed))
+      return false;
+
+    Nodes1.resize( myLayerPositions.size()+1 );
+    Nodes2.resize( myLayerPositions.size()+1 );
+
+    // check that both linear edges have same hypotheses
+    if ( !computeLayerPositions(P0,P2,LinEdge2, &linEdge2Computed))
+         return false;
+    if ( Nodes1.size() != myLayerPositions.size()+1 )
+      return error("Different hypotheses apply to radial edges");
+
+    // find the central vertex
+    TopoDS_Vertex VC = V2;
+    if( ( P1.Distance(PE1) > Precision::Confusion() ) &&
+        ( P2.Distance(PE1) > Precision::Confusion() ) )
+      VC = V1;
+    int vertID = meshDS->ShapeToIndex(VC);
+
+    // LinEdge1
+    if ( linEdge1Computed )
+    {
+      if (!GetSortedNodesOnEdge(aMesh.GetMeshDS(),LinEdge1,true,theNodes))
+        return error("Invalid mesh on a straight edge");
+
+      bool nodesFromP0ToP1 = ( theNodes.rbegin()->second == NF );
+      NC = const_cast<SMDS_MeshNode*>
+        ( nodesFromP0ToP1 ? theNodes.begin()->second : theNodes.rbegin()->second );
+      int i = 0, ir = Nodes1.size()-1;
+      int * pi = nodesFromP0ToP1 ? &i : &ir;
+      itn = theNodes.begin();
+      if ( nodesFromP0ToP1 ) ++itn;
+      for ( ; i < Nodes1.size(); ++i, --ir, ++itn )
+      {
+        Nodes1[*pi] = itn->second;
+      }
+      for ( i = 0; i < Nodes1.size()-1; ++i )
+      {
+        Points.Append( gpXYZ( Nodes1[i]));
+        Pnts2d1.Append( myHelper->GetNodeUV( F, Nodes1[i]));
+      }
+    }
+    else
+    {
+      int edgeID = meshDS->ShapeToIndex(LinEdge1);
+      gp_Vec aVec(P0,P1);
+      // check orientation
+      Handle(Geom_Curve) Crv = BRep_Tool::Curve(LinEdge1,fp,lp);
+      gp_Pnt Ptmp = Crv->Value(fp);
+      bool ori = false;
+      if( P1.Distance(Ptmp) > Precision::Confusion() )
+        ori = true;
+      // get UV points for edge
+      gp_Pnt2d PF,PL;
+      BRep_Tool::UVPoints( LinEdge1, TopoDS::Face(aShape), PF, PL );
+      gp_Vec2d V2d;
+      if(ori) {
+        V2d = gp_Vec2d(PF,PL);
+        PC = PF;
+      }
+      else {
+        V2d = gp_Vec2d(PL,PF);
+        PC = PL;
+      }
+      NC = const_cast<SMDS_MeshNode*>( VertexNode( VC, meshDS ));
+      if ( !NC )
+      {
+        NC = meshDS->AddNode(P0.X(), P0.Y(), P0.Z());
+        meshDS->SetNodeOnVertex(NC, vertID);
+      }
+      double dp = lp-fp;
+      int i = 0;
+      for(; i<myLayerPositions.size(); i++) {
+        gp_Pnt P( P0.X() + aVec.X()*myLayerPositions[i],
+                  P0.Y() + aVec.Y()*myLayerPositions[i],
+                  P0.Z() + aVec.Z()*myLayerPositions[i] );
+        Points.Append(P);
+        SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z());
+        Nodes1[i] = node;
+        double param;
+        if(!ori)
+          param = fp + dp*(1-myLayerPositions[i]);
+        else
+          param = fp + dp*myLayerPositions[i];
+        meshDS->SetNodeOnEdge(node, edgeID, param);
+        // parameters on face
+        gp_Pnt2d P2d( PC.X() + V2d.X()*myLayerPositions[i],
+                      PC.Y() + V2d.Y()*myLayerPositions[i] );
+        Pnts2d1.Append(P2d);
+      }
+      Nodes1[ myLayerPositions.size() ] = NF;
+      // create 1D elements on edge
+      SMDS_MeshEdge* ME = myHelper->AddEdge( NC, Nodes1[0] );
+      if(ME) meshDS->SetMeshElementOnShape(ME, edgeID);
+      for(i=1; i<Nodes1.size(); i++) {
+        ME = myHelper->AddEdge( Nodes1[i-1], Nodes1[i] );
+        if(ME) meshDS->SetMeshElementOnShape(ME, edgeID);
+      }
+      if (nbe==2 && LinEdge1.Orientation() == TopAbs_INTERNAL )
+        Nodes2 = Nodes1;
+    }
+    markEdgeAsComputedByMe( LinEdge1, aMesh.GetSubMesh( F ));
+
+    // LinEdge2
+    if ( linEdge2Computed )
+    {
+      if (!GetSortedNodesOnEdge(aMesh.GetMeshDS(),LinEdge2,true,theNodes))
+        return error("Invalid mesh on a straight edge");
+
+      bool nodesFromP0ToP2 = ( theNodes.rbegin()->second == NL );
+      int i = 0, ir = Nodes1.size()-1;
+      int * pi = nodesFromP0ToP2 ? &i : &ir;
+      itn = theNodes.begin();
+      if ( nodesFromP0ToP2 ) ++itn;
+      for ( ; i < Nodes2.size(); ++i, --ir, ++itn )
+        Nodes2[*pi] = itn->second;
+    }
+    else
+    {
+      int edgeID = meshDS->ShapeToIndex(LinEdge2);
+      gp_Vec aVec = gp_Vec(P0,P2);
+      // check orientation
+      Handle(Geom_Curve) Crv = BRep_Tool::Curve(LinEdge2,fp,lp);
+      gp_Pnt Ptmp = Crv->Value(fp);
+      bool ori = false;
+      if( P2.Distance(Ptmp) > Precision::Confusion() )
+        ori = true;
+      // get UV points for edge
+      gp_Pnt2d PF,PL;
+      BRep_Tool::UVPoints( LinEdge2, TopoDS::Face(aShape), PF, PL );
+      gp_Vec2d V2d;
+      if(ori) {
+        V2d = gp_Vec2d(PF,PL);
+        PC = PF;
+      }
+      else {
+        V2d = gp_Vec2d(PL,PF);
+        PC = PL;
+      }
+      double dp = lp-fp;
+      for(int i=0; i<myLayerPositions.size(); i++) {
+        gp_Pnt P( P0.X() + aVec.X()*myLayerPositions[i],
+                  P0.Y() + aVec.Y()*myLayerPositions[i],
+                  P0.Z() + aVec.Z()*myLayerPositions[i] );
+        SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z());
+        Nodes2[i] = node;
+        double param;
+        if(!ori)
+          param = fp + dp*(1-myLayerPositions[i]);
+        else
+          param = fp + dp*myLayerPositions[i];
+        meshDS->SetNodeOnEdge(node, edgeID, param);
+        // parameters on face
+        gp_Pnt2d P2d( PC.X() + V2d.X()*myLayerPositions[i],
+                      PC.Y() + V2d.Y()*myLayerPositions[i] );
+      }
+      Nodes2[ myLayerPositions.size() ] = NL;
+      // create 1D elements on edge
+      SMDS_MeshEdge* ME = myHelper->AddEdge( NC, Nodes2[0] );
+      if(ME) meshDS->SetMeshElementOnShape(ME, edgeID);
+      for(int i=1; i<Nodes2.size(); i++) {
+        ME = myHelper->AddEdge( Nodes2[i-1], Nodes2[i] );
+        if(ME) meshDS->SetMeshElementOnShape(ME, edgeID);
+      }
+    }
+    markEdgeAsComputedByMe( LinEdge2, aMesh.GetSubMesh( F ));
+  }
+  markEdgeAsComputedByMe( CircEdge, aMesh.GetSubMesh( F ));
+
+  // orientation
+  bool IsForward = ( CircEdge.Orientation()==TopAbs_FORWARD );
+
+  // create nodes and mesh elements on face
+  // find axis of rotation
+  gp_Pnt P2 = gp_Pnt( CNodes[1]->X(), CNodes[1]->Y(), CNodes[1]->Z() );
+  gp_Vec Vec1(P0,P1);
+  gp_Vec Vec2(P0,P2);
+  gp_Vec Axis = Vec1.Crossed(Vec2);
+  // create elements
+  int i = 1;
+  //cout<<"Angles.Length() = "<<Angles.Length()<<"   Points.Length() = "<<Points.Length()<<endl;
+  //cout<<"Nodes1.size() = "<<Nodes1.size()<<"   Pnts2d1.Length() = "<<Pnts2d1.Length()<<endl;
+  for(; i<Angles.Length(); i++) {
+    vector< const SMDS_MeshNode* > tmpNodes;
+    tmpNodes.reserve(Nodes1.size());
+    gp_Trsf aTrsf;
+    gp_Ax1 theAxis(P0,gp_Dir(Axis));
+    aTrsf.SetRotation( theAxis, Angles.Value(i) );
+    gp_Trsf2d aTrsf2d;
+    aTrsf2d.SetRotation( PC, Angles.Value(i) );
+    // create nodes
+    int j = 1;
+    for(; j<=Points.Length(); j++) {
+      double cx,cy,cz;
+      Points.Value(j).Coord( cx, cy, cz );
+      aTrsf.Transforms( cx, cy, cz );
+      SMDS_MeshNode* node = myHelper->AddNode( cx, cy, cz );
+      // find parameters on face
+      Pnts2d1.Value(j).Coord( cx, cy );
+      aTrsf2d.Transforms( cx, cy );
+      // set node on face
+      meshDS->SetNodeOnFace( node, faceID, cx, cy );
+      tmpNodes[j-1] = node;
+    }
+    // create faces
+    tmpNodes[Points.Length()] = CNodes[i];
+    // quad
+    for(j=0; j<Nodes1.size()-1; j++) {
+      SMDS_MeshFace* MF;
+      if(IsForward)
+        MF = myHelper->AddFace( tmpNodes[j], Nodes1[j],
+                                Nodes1[j+1], tmpNodes[j+1] );
+      else
+        MF = myHelper->AddFace( tmpNodes[j], tmpNodes[j+1],
+                                Nodes1[j+1], Nodes1[j] );
+      if(MF) meshDS->SetMeshElementOnShape(MF, faceID);
+    }
+    // tria
+    SMDS_MeshFace* MF;
+    if(IsForward)
+      MF = myHelper->AddFace( NC, Nodes1[0], tmpNodes[0] );
+    else
+      MF = myHelper->AddFace( NC, tmpNodes[0], Nodes1[0] );
+    if(MF) meshDS->SetMeshElementOnShape(MF, faceID);
+    for(j=0; j<Nodes1.size(); j++) {
+      Nodes1[j] = tmpNodes[j];
+    }
+  }
+  // create last faces
+  // quad
+  for(i=0; i<Nodes1.size()-1; i++) {
+    SMDS_MeshFace* MF;
+    if(IsForward)
+      MF = myHelper->AddFace( Nodes2[i], Nodes1[i],
+                              Nodes1[i+1], Nodes2[i+1] );
+    else
+      MF = myHelper->AddFace( Nodes2[i],  Nodes2[i+1],
+                              Nodes1[i+1], Nodes1[i] );
+    if(MF) meshDS->SetMeshElementOnShape(MF, faceID);
+  }
+  // tria
+  SMDS_MeshFace* MF;
+  if(IsForward)
+    MF = myHelper->AddFace( NC, Nodes1[0], Nodes2[0] );
+  else
+    MF = myHelper->AddFace( NC, Nodes2[0], Nodes1[0] );
+  if(MF) meshDS->SetMeshElementOnShape(MF, faceID);
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Compute positions of nodes on the radial edge
+  * \retval bool - is a success
+ */
+//================================================================================
+
+bool StdMeshers_RadialQuadrangle_1D2D::computeLayerPositions(const gp_Pnt&      p1,
+                                                             const gp_Pnt&      p2,
+                                                             const TopoDS_Edge& linEdge,
+                                                             bool*              linEdgeComputed)
+{
+  // First, try to compute positions of layers
+
+  myLayerPositions.clear();
+
+  SMESH_Mesh * mesh = myHelper->GetMesh();
+
+  const SMESH_Hypothesis* hyp1D = myDistributionHypo ? myDistributionHypo->GetLayerDistribution() : 0;
+  int                  nbLayers = myNbLayerHypo ? myNbLayerHypo->GetNumberOfLayers() : 0;
+
+  if ( !hyp1D && !nbLayers )
+  {
+    // No own algo hypotheses assigned, so first try to find any 1D hypothesis.
+    // We need some edge
+    TopoDS_Shape edge = linEdge;
+    if ( edge.IsNull() && !myHelper->GetSubShape().IsNull())
+      for ( TopExp_Explorer e(myHelper->GetSubShape(), TopAbs_EDGE); e.More(); e.Next())
+        edge = e.Current();
+    if ( !edge.IsNull() )
+    {
+      // find a hyp usable by TNodeDistributor
+      SMESH_HypoFilter hypKind;
+      TNodeDistributor::GetDistributor(*mesh)->InitCompatibleHypoFilter(hypKind,/*ignoreAux=*/1);
+      hyp1D = mesh->GetHypothesis( edge, hypKind, /*fromAncestors=*/true);
+    }
+  }
+  if ( hyp1D ) // try to compute with hyp1D
+  {
+    if ( !TNodeDistributor::GetDistributor(*mesh)->Compute( myLayerPositions,p1,p2,*mesh,hyp1D )) {
+      if ( myDistributionHypo ) { // bad hyp assigned 
+        return error( TNodeDistributor::GetDistributor(*mesh)->GetComputeError() );
+      }
+      else {
+        // bad hyp found, its Ok, lets try with default nb of segnents
+      }
+    }
+  }
+  
+  if ( myLayerPositions.empty() ) // try to use nb of layers
+  {
+    if ( !nbLayers )
+      nbLayers = _gen->GetDefaultNbSegments();
+
+    if ( nbLayers )
+    {
+      myLayerPositions.resize( nbLayers - 1 );
+      for ( int z = 1; z < nbLayers; ++z )
+        myLayerPositions[ z - 1 ] = double( z )/ double( nbLayers );
+    }
+  }
+
+  // Second, check presence of a mesh built by other algo on linEdge
+  // and mesh conformity to my hypothesis
+
+  bool meshComputed = (!linEdge.IsNull() && !mesh->GetSubMesh(linEdge)->IsEmpty() );
+  if ( linEdgeComputed ) *linEdgeComputed = meshComputed;
+
+  if ( meshComputed )
+  {
+    vector< double > nodeParams;
+    GetNodeParamOnEdge( mesh->GetMeshDS(), linEdge, nodeParams );
+
+    // nb of present nodes must be different in cases of 1 and 2 straight edges
+
+    TopoDS_Vertex VV[2];
+    TopExp::Vertices( linEdge, VV[0], VV[1]);
+    const gp_Pnt* points[] = { &p1, &p2 };
+    gp_Pnt       vPoints[] = { BRep_Tool::Pnt(VV[0]), BRep_Tool::Pnt(VV[1]) };
+    const double     tol[] = { BRep_Tool::Tolerance(VV[0]), BRep_Tool::Tolerance(VV[1]) };
+    bool pointsAreOnVertices = true;
+    for ( int iP = 0; iP < 2 && pointsAreOnVertices; ++iP )
+      pointsAreOnVertices = ( points[iP]->Distance( vPoints[0] ) < tol[0] ||
+                              points[iP]->Distance( vPoints[1] ) < tol[1] );
+
+    int nbNodes = nodeParams.size() - 2; // 2 straight edges
+    if ( !pointsAreOnVertices )
+      nbNodes = ( nodeParams.size() - 3 ) / 2; // 1 straight edge
+
+    if ( myLayerPositions.empty() )
+    {
+      myLayerPositions.resize( nbNodes );
+    }
+    else if ( myDistributionHypo || myNbLayerHypo )
+    {
+      // linEdge is computed by other algo. Check if there is a meshed face
+      // using nodes on linEdge
+      bool nodesAreUsed = false;
+      TopTools_ListIteratorOfListOfShape ancestIt = mesh->GetAncestors( linEdge );
+      for ( ; ancestIt.More() && !nodesAreUsed; ancestIt.Next() )
+        if ( ancestIt.Value().ShapeType() == TopAbs_FACE )
+          nodesAreUsed = (!mesh->GetSubMesh( ancestIt.Value() )->IsEmpty());
+      if ( !nodesAreUsed ) {
+        // rebuild them
+        mesh->GetSubMesh( linEdge )->ComputeStateEngine( SMESH_subMesh::CLEAN );
+        if ( linEdgeComputed ) *linEdgeComputed = false;
+      }
+      else {
+        
+        if ( myLayerPositions.size() != nbNodes )
+          return error("Radial edge is meshed by other algorithm");
+      }
+    }
+  }
+
+  return !myLayerPositions.empty();
+}
+
+
+//=======================================================================
+//function : Evaluate
+//purpose  : 
+//=======================================================================
+
+bool StdMeshers_RadialQuadrangle_1D2D::Evaluate(SMESH_Mesh& aMesh,
+                                                const TopoDS_Shape& aShape,
+                                                MapShapeNbElems& aResMap)
+{
+  if( aShape.ShapeType() != TopAbs_FACE ) {
+    return false;
+  }
+  SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
+  if( aResMap.count(sm) )
+    return false;
+
+  vector<int>& aResVec =
+    aResMap.insert( make_pair(sm, vector<int>(SMDSEntity_Last,0))).first->second;
+
+  myHelper = new SMESH_MesherHelper( aMesh );
+  myHelper->SetSubShape( aShape );
+  auto_ptr<SMESH_MesherHelper> helperDeleter( myHelper );
+
+  TNodeDistributor* algo1d = TNodeDistributor::GetDistributor(aMesh);
+
+  TopoDS_Edge CircEdge, LinEdge1, LinEdge2;
+  int nbe = analyseFace( aShape, CircEdge, LinEdge1, LinEdge2 );
+  if( nbe>3 || nbe < 1 || CircEdge.IsNull() )
+    return false;
+
+  Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast( getCurve( CircEdge ));
+  if( aCirc.IsNull() )
+    return error(COMPERR_BAD_SHAPE);
+
+  gp_Pnt P0 = aCirc->Location();
+  gp_Pnt P1 = aCirc->Value(0.);
+  computeLayerPositions( P0, P1, LinEdge1 );
+
+  int nb0d=0, nb2d_tria=0, nb2d_quad=0;
+  bool isQuadratic = false, ok = true;
+  if(nbe==1)
+  {
+    // C1 must be a circle
+    ok = algo1d->EvaluateCircularEdge( aMesh, CircEdge, aResMap );
+    if(ok) {
+      const vector<int>& aVec = aResMap[aMesh.GetSubMesh(CircEdge)];
+      isQuadratic = aVec[SMDSEntity_Quad_Edge]>aVec[SMDSEntity_Edge];
+      if(isQuadratic) {
+        // main nodes
+        nb0d = (aVec[SMDSEntity_Node]+1) * myLayerPositions.size();
+        // radial medium nodes
+        nb0d += (aVec[SMDSEntity_Node]+1) * (myLayerPositions.size()+1);
+        // other medium nodes
+        nb0d += (aVec[SMDSEntity_Node]+1) * myLayerPositions.size();
+      }
+      else {
+        nb0d = (aVec[SMDSEntity_Node]+1) * myLayerPositions.size();
+      }
+      nb2d_tria = aVec[SMDSEntity_Node] + 1;
+      nb2d_quad = nb0d;
+    }
+  }
+  else if(nbe==2 && LinEdge1.Orientation() != TopAbs_INTERNAL)
+  {
+    // one curve must be a half of circle and other curve must be
+    // a segment of line
+    double fp, lp;
+    Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast( getCurve( CircEdge, &fp, &lp ));
+    if( fabs(fabs(lp-fp)-M_PI) > Precision::Confusion() ) {
+      // not half of circle
+      return error(COMPERR_BAD_SHAPE);
+    }
+    Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast( getCurve( LinEdge1 ));
+    if( aLine.IsNull() ) {
+      // other curve not line
+      return error(COMPERR_BAD_SHAPE);
+    }
+    ok = !aResMap.count( aMesh.GetSubMesh(LinEdge1) );
+    if ( !ok ) {
+      const vector<int>& aVec = aResMap[ aMesh.GetSubMesh(LinEdge1) ];
+      ok = ( aVec[SMDSEntity_Node] == myLayerPositions.size() );
+    }
+    if(ok) {
+      ok = algo1d->EvaluateCircularEdge( aMesh, CircEdge, aResMap );
+    }
+    if(ok) {
+      const vector<int>& aVec = aResMap[ aMesh.GetSubMesh(CircEdge) ];
+      isQuadratic = aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge];
+      if(isQuadratic) {
+        // main nodes
+        nb0d = aVec[SMDSEntity_Node] * myLayerPositions.size();
+        // radial medium nodes
+        nb0d += aVec[SMDSEntity_Node] * (myLayerPositions.size()+1);
+        // other medium nodes
+        nb0d += (aVec[SMDSEntity_Node]+1) * myLayerPositions.size();
+      }
+      else {
+        nb0d = aVec[SMDSEntity_Node] * myLayerPositions.size();
+      }
+      nb2d_tria = aVec[SMDSEntity_Node] + 1;
+      nb2d_quad = nb2d_tria * myLayerPositions.size();
+      // add evaluation for edges
+      vector<int> aResVec(SMDSEntity_Last,0);
+      if(isQuadratic) {
+        aResVec[SMDSEntity_Node] = 4*myLayerPositions.size() + 3;
+        aResVec[SMDSEntity_Quad_Edge] = 2*myLayerPositions.size() + 2;
+      }
+      else {
+        aResVec[SMDSEntity_Node] = 2*myLayerPositions.size() + 1;
+        aResVec[SMDSEntity_Edge] = 2*myLayerPositions.size() + 2;
+      }
+      aResMap[ aMesh.GetSubMesh(LinEdge1) ] = aResVec;
+    }
+  }
+  else  // nbe==3 or ( nbe==2 && linEdge is INTERNAL )
+  {
+    if (nbe==2 && LinEdge1.Orientation() == TopAbs_INTERNAL )
+      LinEdge2 = LinEdge1;
+
+    // one curve must be a part of circle and other curves must be
+    // segments of line
+    Handle(Geom_Line)  aLine1 = Handle(Geom_Line)::DownCast( getCurve( LinEdge1 ));
+    Handle(Geom_Line)  aLine2 = Handle(Geom_Line)::DownCast( getCurve( LinEdge2 ));
+    if( aLine1.IsNull() || aLine2.IsNull() ) {
+      // other curve not line
+      return error(COMPERR_BAD_SHAPE);
+    }
+    int nbLayers = myLayerPositions.size();
+    computeLayerPositions( P0, P1, LinEdge2 );
+    if ( nbLayers != myLayerPositions.size() )
+      return error("Different hypotheses apply to radial edges");
+      
+    bool ok = !aResMap.count( aMesh.GetSubMesh(LinEdge1));
+    if ( !ok ) {
+      if ( myDistributionHypo || myNbLayerHypo )
+        ok = true; // override other 1d hyps
+      else {
+        const vector<int>& aVec = aResMap[ aMesh.GetSubMesh(LinEdge1) ];
+        ok = ( aVec[SMDSEntity_Node] == myLayerPositions.size() );
+      }
+    }
+    if( ok && aResMap.count( aMesh.GetSubMesh(LinEdge2) )) {
+      if ( myDistributionHypo || myNbLayerHypo )
+        ok = true; // override other 1d hyps
+      else {
+        const vector<int>& aVec = aResMap[ aMesh.GetSubMesh(LinEdge2) ];
+        ok = ( aVec[SMDSEntity_Node] == myLayerPositions.size() );
+      }
+    }
+    if(ok) {
+      ok = algo1d->EvaluateCircularEdge( aMesh, CircEdge, aResMap );
+    }
+    if(ok) {
+      const vector<int>& aVec = aResMap[ aMesh.GetSubMesh(CircEdge) ];
+      isQuadratic = aVec[SMDSEntity_Quad_Edge]>aVec[SMDSEntity_Edge];
+      if(isQuadratic) {
+        // main nodes
+        nb0d = aVec[SMDSEntity_Node] * myLayerPositions.size();
+        // radial medium nodes
+        nb0d += aVec[SMDSEntity_Node] * (myLayerPositions.size()+1);
+        // other medium nodes
+        nb0d += (aVec[SMDSEntity_Node]+1) * myLayerPositions.size();
+      }
+      else {
+        nb0d = aVec[SMDSEntity_Node] * myLayerPositions.size();
+      }
+      nb2d_tria = aVec[SMDSEntity_Node] + 1;
+      nb2d_quad = nb2d_tria * myLayerPositions.size();
+      // add evaluation for edges
+      vector<int> aResVec(SMDSEntity_Last, 0);
+      if(isQuadratic) {
+        aResVec[SMDSEntity_Node] = 2*myLayerPositions.size() + 1;
+        aResVec[SMDSEntity_Quad_Edge] = myLayerPositions.size() + 1;
+      }
+      else {
+        aResVec[SMDSEntity_Node] = myLayerPositions.size();
+        aResVec[SMDSEntity_Edge] = myLayerPositions.size() + 1;
+      }
+      sm = aMesh.GetSubMesh(LinEdge1);
+      aResMap[sm] = aResVec;
+      sm = aMesh.GetSubMesh(LinEdge2);
+      aResMap[sm] = aResVec;
+    }
+  }
+
+  if(nb0d>0) {
+    aResVec[0] = nb0d;
+    if(isQuadratic) {
+      aResVec[SMDSEntity_Quad_Triangle] = nb2d_tria;
+      aResVec[SMDSEntity_Quad_Quadrangle] = nb2d_quad;
+    }
+    else {
+      aResVec[SMDSEntity_Triangle] = nb2d_tria;
+      aResVec[SMDSEntity_Quadrangle] = nb2d_quad;
+    }
+    return true;
+  }
+
+  // invalid case
+  sm = aMesh.GetSubMesh(aShape);
+  SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+  smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,
+                                        "Submesh can not be evaluated",this));
+  return false;
+
+}
diff --git a/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.hxx b/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.hxx
new file mode 100644 (file)
index 0000000..b68ebe9
--- /dev/null
@@ -0,0 +1,76 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+//  File   : StdMeshers_RadialQuadrangle_1D2D.hxx
+//  Module : SMESH
+//
+#ifndef _SMESH_RadialQuadrangle_1D2D_HXX_
+#define _SMESH_RadialQuadrangle_1D2D_HXX_
+
+#include "SMESH_StdMeshers.hxx"
+
+#include "SMESH_2D_Algo.hxx"
+
+#include <TopoDS_Edge.hxx>
+
+#include <vector>
+
+class StdMeshers_NumberOfLayers;
+class StdMeshers_LayerDistribution;
+class SMESH_MesherHelper;
+class gp_Pnt;
+
+class STDMESHERS_EXPORT StdMeshers_RadialQuadrangle_1D2D: public SMESH_2D_Algo
+{
+public:
+  StdMeshers_RadialQuadrangle_1D2D(int hypId, int studyId, SMESH_Gen* gen);
+  virtual ~StdMeshers_RadialQuadrangle_1D2D();
+
+  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);
+
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
+  /*!
+   * \brief Allow algo to do something after persistent restoration
+    * \param subMesh - restored submesh
+   *
+   * This method is called only if a submesh has HYP_OK algo_state.
+   */
+  virtual void SubmeshRestored(SMESH_subMesh* subMesh);
+  
+protected:
+
+  bool computeLayerPositions(const gp_Pnt&      p1,
+                             const gp_Pnt&      p2,
+                             const TopoDS_Edge& linEdge=TopoDS_Edge(),
+                             bool*              linEdgeComputed = 0);
+
+
+  const StdMeshers_NumberOfLayers*    myNbLayerHypo;
+  const StdMeshers_LayerDistribution* myDistributionHypo;
+  SMESH_MesherHelper*                 myHelper;
+  std::vector< double >               myLayerPositions;
+};
+
+#endif
index ee4aa86e78a1e992e97c3c2a599a9ef13b4105d3..8d900955d284778f5dadb9fddb78416b11f5311e 100644 (file)
@@ -1,30 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-//  SMESH SMESH : implementaion of SMESH idl descriptions
+
 //  File   : StdMeshers_Regular_1D.cxx
 //           Moved here from SMESH_Regular_1D.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-
+//
 #include "StdMeshers_Regular_1D.hxx"
 #include "StdMeshers_Distribution.hxx"
 
 #include <TopExp_Explorer.hxx>
 #include <TopoDS.hxx>
 #include <TopoDS_Edge.hxx>
+#include <TopoDS_Vertex.hxx>
 
 #include <string>
+#include <limits>
 
 using namespace std;
 
@@ -73,22 +75,24 @@ using namespace std;
 //=============================================================================
 
 StdMeshers_Regular_1D::StdMeshers_Regular_1D(int hypId, int studyId,
-       SMESH_Gen * gen):SMESH_1D_Algo(hypId, studyId, gen)
+        SMESH_Gen * gen):SMESH_1D_Algo(hypId, studyId, gen)
 {
-       MESSAGE("StdMeshers_Regular_1D::StdMeshers_Regular_1D");
-       _name = "Regular_1D";
-       _shapeType = (1 << TopAbs_EDGE);
-
-       _compatibleHypothesis.push_back("LocalLength");
-       _compatibleHypothesis.push_back("MaxLength");
-       _compatibleHypothesis.push_back("NumberOfSegments");
-       _compatibleHypothesis.push_back("StartEndLength");
-       _compatibleHypothesis.push_back("Deflection1D");
-       _compatibleHypothesis.push_back("Arithmetic1D");
-       _compatibleHypothesis.push_back("AutomaticLength");
-
-       _compatibleHypothesis.push_back("QuadraticMesh"); // auxiliary !!!
-       _compatibleHypothesis.push_back("Propagation"); // auxiliary !!!
+        MESSAGE("StdMeshers_Regular_1D::StdMeshers_Regular_1D");
+        _name = "Regular_1D";
+        _shapeType = (1 << TopAbs_EDGE);
+        _fpHyp = 0;
+
+        _compatibleHypothesis.push_back("LocalLength");
+        _compatibleHypothesis.push_back("MaxLength");
+        _compatibleHypothesis.push_back("NumberOfSegments");
+        _compatibleHypothesis.push_back("StartEndLength");
+        _compatibleHypothesis.push_back("Deflection1D");
+        _compatibleHypothesis.push_back("Arithmetic1D");
+        _compatibleHypothesis.push_back("FixedPoints1D");
+        _compatibleHypothesis.push_back("AutomaticLength");
+
+        _compatibleHypothesis.push_back("QuadraticMesh"); // auxiliary !!!
+        _compatibleHypothesis.push_back("Propagation"); // auxiliary !!!
 }
 
 //=============================================================================
@@ -115,9 +119,8 @@ bool StdMeshers_Regular_1D::CheckHypothesis
   _hypType = NONE;
   _quadraticMesh = false;
 
-  const bool ignoreAuxiliaryHyps = false;
   const list <const SMESHDS_Hypothesis * > & hyps =
-    GetUsedHypothesis(aMesh, aShape, ignoreAuxiliaryHyps);
+    GetUsedHypothesis(aMesh, aShape, /*ignoreAuxiliaryHyps=*/false);
 
   // find non-auxiliary hypothesis
   const SMESHDS_Hypothesis *theHyp = 0;
@@ -180,12 +183,15 @@ bool StdMeshers_Regular_1D::CheckHypothesis
     {
     case StdMeshers_NumberOfSegments::DT_Scale:
       _value[ SCALE_FACTOR_IND ] = hyp->GetScaleFactor();
+      _revEdgesIDs = hyp->GetReversedEdges();
       break;
     case StdMeshers_NumberOfSegments::DT_TabFunc:
       _vvalue[ TAB_FUNC_IND ] = hyp->GetTableFunction();
+      _revEdgesIDs = hyp->GetReversedEdges();
       break;
     case StdMeshers_NumberOfSegments::DT_ExprFunc:
       _svalue[ EXPR_FUNC_IND ] = hyp->GetExpressionFunction();
+      _revEdgesIDs = hyp->GetReversedEdges();
       break;
     case StdMeshers_NumberOfSegments::DT_Regular:
       break;
@@ -209,6 +215,19 @@ bool StdMeshers_Regular_1D::CheckHypothesis
     _value[ END_LENGTH_IND ] = hyp->GetLength( false );
     ASSERT( _value[ BEG_LENGTH_IND ] > 0 && _value[ END_LENGTH_IND ] > 0 );
     _hypType = ARITHMETIC_1D;
+
+    _revEdgesIDs = hyp->GetReversedEdges();
+
+    aStatus = SMESH_Hypothesis::HYP_OK;
+  }
+
+  else if (hypName == "FixedPoints1D") {
+    _fpHyp = dynamic_cast <const StdMeshers_FixedPoints1D*>(theHyp);
+    ASSERT(_fpHyp);
+    _hypType = FIXED_POINTS_1D;
+
+    _revEdgesIDs = _fpHyp->GetReversedEdges();
+
     aStatus = SMESH_Hypothesis::HYP_OK;
   }
 
@@ -221,6 +240,9 @@ bool StdMeshers_Regular_1D::CheckHypothesis
     _value[ END_LENGTH_IND ] = hyp->GetLength( false );
     ASSERT( _value[ BEG_LENGTH_IND ] > 0 && _value[ END_LENGTH_IND ] > 0 );
     _hypType = BEG_END_LENGTH;
+
+    _revEdgesIDs = hyp->GetReversedEdges();
+
     aStatus = SMESH_Hypothesis::HYP_OK;
   }
 
@@ -303,6 +325,8 @@ static bool computeParamByFunc(Adaptor3d_Curve& C3d, double first, double last,
       return false;
     prevU = U;
   }
+  if ( theReverse )
+    theParams.reverse();
   return true;
 }
 
@@ -352,10 +376,14 @@ static void compensateError(double a1, double an,
     }
 
     double q  = dUn / ( nPar - 1 );
-    if ( !adjustNeighbors2an ) {
-      for ( itU = theParams.rbegin(), i = 1; i < nPar; itU++, i++ ) {
+    if ( !adjustNeighbors2an )
+    {
+      q = dUn / ( Utgt - Un ); // (signed) factor of segment length change
+      for ( itU = theParams.rbegin(), i = 1; i < nPar; i++ ) {
+        double prevU = *itU;
         (*itU) += dUn;
-        dUn -= q;
+        ++itU;
+        dUn = q * (*itU - prevU) * (prevU-U1)/(Un-U1);
       }
     }
     else {
@@ -602,7 +630,7 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh &     theMesh,
           bool computed = sm->IsMeshComputed();
           if (!computed) {
             if (sm->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE) {
-              sm->ComputeStateEngine(SMESH_subMesh::COMPUTE);
+              _gen->Compute( theMesh, _mainEdge, /*anUpward=*/true);
               computed = sm->IsMeshComputed();
             }
           }
@@ -659,6 +687,14 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh &     theMesh,
               theParams.push_back( param );
             }
           }
+          const double lenFactor = theLength/(l-f);
+          list<double>::iterator u = theParams.begin(), uEnd = theParams.end();
+          for ( ; u != uEnd; ++u )
+          {
+            GCPnts_AbscissaPoint Discret( theC3d, ((*u)-f) * lenFactor, f );
+            if ( Discret.IsDone() )
+              *u = Discret.Parameter();
+          }
           return true;
         }
         break;
@@ -706,6 +742,9 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh &     theMesh,
     double a1 = _value[ BEG_LENGTH_IND ];
     double an = _value[ END_LENGTH_IND ];
     double q  = ( theLength - a1 ) / ( theLength - an );
+    if ( q < theLength/1e6 || 1.01*theLength < a1 + an)
+      return error ( SMESH_Comment("Invalid segment lengths (")<<a1<<" and "<<an<<") "<<
+                     "for an edge of length "<<theLength);
 
     double U1 = theReverse ? l : f;
     double Un = theReverse ? f : l;
@@ -734,9 +773,12 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh &     theMesh,
 
     double a1 = _value[ BEG_LENGTH_IND ];
     double an = _value[ END_LENGTH_IND ];
+    if ( 1.01*theLength < a1 + an)
+      return error ( SMESH_Comment("Invalid segment lengths (")<<a1<<" and "<<an<<") "<<
+                     "for an edge of length "<<theLength);
 
     double  q = ( an - a1 ) / ( 2 *theLength/( a1 + an ) - 1 );
-    int     n = int( 1 + ( an - a1 ) / q );
+    int n = int(fabs(q) > numeric_limits<double>::min() ? ( 1+( an-a1 )/q ) : ( 1+theLength/a1 ));
 
     double U1 = theReverse ? l : f;
     double Un = theReverse ? f : l;
@@ -764,6 +806,107 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh &     theMesh,
     return true;
   }
 
+  case FIXED_POINTS_1D: {
+    const std::vector<double>& aPnts = _fpHyp->GetPoints();
+    const std::vector<int>& nbsegs = _fpHyp->GetNbSegments();
+    int i = 0;
+    TColStd_SequenceOfReal Params;
+    for(; i<aPnts.size(); i++) {
+      if( aPnts[i]<0.0001 || aPnts[i]>0.9999 ) continue;
+      int j=1;
+      bool IsExist = false;
+      for(; j<=Params.Length(); j++) {
+        if( fabs(aPnts[i]-Params.Value(j)) < 1e-4 ) {
+          IsExist = true;
+          break;
+        }
+        if( aPnts[i]<Params.Value(j) ) break;
+      }
+      if(!IsExist) Params.InsertBefore(j,aPnts[i]);
+    }
+    double par2, par1, lp;
+    par1 = f;
+    lp = l;
+    double sign = 1.0;
+    if(theReverse) {
+      par1 = l;
+      lp = f;
+      sign = -1.0;
+    }
+    double eltSize, segmentSize = 0.;
+    double currAbscissa = 0;
+    for(i=0; i<Params.Length(); i++) {
+      int nbseg = ( i > nbsegs.size()-1 ) ? nbsegs[0] : nbsegs[i];
+      segmentSize = Params.Value(i+1)*theLength - currAbscissa;
+      currAbscissa += segmentSize;
+      GCPnts_AbscissaPoint APnt(theC3d, sign*segmentSize, par1);
+      if( !APnt.IsDone() )
+        return error( "GCPnts_AbscissaPoint failed");
+      par2 = APnt.Parameter();
+      eltSize = segmentSize/nbseg;
+      GCPnts_UniformAbscissa Discret(theC3d, eltSize, par1, par2);
+      if(theReverse)
+        Discret.Initialize(theC3d, eltSize, par2, par1);
+      else
+        Discret.Initialize(theC3d, eltSize, par1, par2);
+      if ( !Discret.IsDone() )
+        return error( "GCPnts_UniformAbscissa failed");
+      int NbPoints = Discret.NbPoints();
+      list<double> tmpParams;
+      for(int i=2; i<NbPoints; i++) {
+        double param = Discret.Parameter(i);
+        tmpParams.push_back( param );
+      }
+      if (theReverse) {
+        compensateError( eltSize, eltSize, par2, par1, segmentSize, theC3d, tmpParams );
+        tmpParams.reverse();
+      }
+      else {
+        compensateError( eltSize, eltSize, par1, par2, segmentSize, theC3d, tmpParams );
+      }
+      list<double>::iterator itP = tmpParams.begin();
+      for(; itP != tmpParams.end(); itP++) {
+        theParams.push_back( *(itP) );
+      }
+      theParams.push_back( par2 );
+
+      par1 = par2;
+    }
+    // add for last
+    int nbseg = ( nbsegs.size() > Params.Length() ) ? nbsegs[Params.Length()] : nbsegs[0];
+    segmentSize = theLength - currAbscissa;
+    eltSize = segmentSize/nbseg;
+    GCPnts_UniformAbscissa Discret;
+    if(theReverse)
+      Discret.Initialize(theC3d, eltSize, par1, lp);
+    else
+      Discret.Initialize(theC3d, eltSize, lp, par1);
+    if ( !Discret.IsDone() )
+      return error( "GCPnts_UniformAbscissa failed");
+    int NbPoints = Discret.NbPoints();
+    list<double> tmpParams;
+    for(int i=2; i<NbPoints; i++) {
+      double param = Discret.Parameter(i);
+      tmpParams.push_back( param );
+    }
+    if (theReverse) {
+      compensateError( eltSize, eltSize, lp, par1, segmentSize, theC3d, tmpParams );
+      tmpParams.reverse();
+    }
+    else {
+      compensateError( eltSize, eltSize, par1, lp, segmentSize, theC3d, tmpParams );
+    }
+    list<double>::iterator itP = tmpParams.begin();
+    for(; itP != tmpParams.end(); itP++) {
+      theParams.push_back( *(itP) );
+    }
+
+    if (theReverse) {
+      theParams.reverse(); // NPAL18025
+    }
+    return true;
+  }
+
   case DEFLECTION: {
 
     GCPnts_UniformDeflection Discret(theC3d, _value[ DEFLECTION_IND ], f, l, true);
@@ -815,12 +958,43 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t
   if (!idFirst || !idLast)
     return error( COMPERR_BAD_INPUT_MESH, "No node on vertex");
 
+  // remove elements created by e.g. patern mapping (PAL21999)
+  // CLEAN event is incorrectly ptopagated seemingly due to Propagation hyp
+  // so TEMPORARY solution is to clean the submesh manually
+  //theMesh.GetSubMesh(theShape)->ComputeStateEngine( SMESH_subMesh::CLEAN );
+  if (SMESHDS_SubMesh * subMeshDS = meshDS->MeshElements(theShape))
+  {
+    SMDS_ElemIteratorPtr ite = subMeshDS->GetElements();
+    while (ite->more())
+      meshDS->RemoveFreeElement(ite->next(), subMeshDS);
+    SMDS_NodeIteratorPtr itn = subMeshDS->GetNodes();
+    while (itn->more()) {
+      const SMDS_MeshNode * node = itn->next();
+      if ( node->NbInverseElements() == 0 )
+        meshDS->RemoveFreeNode(node, subMeshDS);
+      else
+        meshDS->RemoveNode(node);
+    }
+  }
+
   if (!Curve.IsNull())
   {
     list< double > params;
     bool reversed = false;
-    if ( !_mainEdge.IsNull() )
+    if ( theMesh.GetShapeToMesh().ShapeType() >= TopAbs_WIRE ) {
+      // if the shape to mesh is WIRE or EDGE
+      reversed = ( EE.Orientation() == TopAbs_REVERSED );
+    }
+    if ( !_mainEdge.IsNull() ) {
+      // take into account reversing the edge the hypothesis is propagated from
       reversed = ( _mainEdge.Orientation() == TopAbs_REVERSED );
+      int mainID = meshDS->ShapeToIndex(_mainEdge);
+      if ( std::find( _revEdgesIDs.begin(), _revEdgesIDs.end(), mainID) != _revEdgesIDs.end())
+        reversed = !reversed;
+    }
+    // take into account this edge reversing
+    if ( std::find( _revEdgesIDs.begin(), _revEdgesIDs.end(), shapeID) != _revEdgesIDs.end())
+      reversed = !reversed;
 
     BRepAdaptor_Curve C3d( E );
     double length = EdgeLength( E );
@@ -845,7 +1019,6 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t
       parLast = f;
     }
     */
-
     for (list<double>::iterator itU = params.begin(); itU != params.end(); itU++) {
       double param = *itU;
       gp_Pnt P = Curve->Value(param);
@@ -930,6 +1103,81 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t
   return true;
 }
 
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+bool StdMeshers_Regular_1D::Evaluate(SMESH_Mesh & theMesh,
+                                     const TopoDS_Shape & theShape,
+                                     MapShapeNbElems& aResMap)
+{
+  if ( _hypType == NONE )
+    return false;
+
+  //SMESHDS_Mesh * meshDS = theMesh.GetMeshDS();
+
+  const TopoDS_Edge & EE = TopoDS::Edge(theShape);
+  TopoDS_Edge E = TopoDS::Edge(EE.Oriented(TopAbs_FORWARD));
+  //  int shapeID = meshDS->ShapeToIndex( E );
+
+  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
+
+  ASSERT(!VFirst.IsNull());
+  ASSERT(!VLast.IsNull());
+
+  std::vector<int> aVec(SMDSEntity_Last,0);
+
+  if (!Curve.IsNull()) {
+    list< double > params;
+
+    BRepAdaptor_Curve C3d( E );
+    double length = EdgeLength( E );
+    if ( ! computeInternalParameters( theMesh, C3d, length, f, l, params, false, true )) {
+      SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
+      aResMap.insert(std::make_pair(sm,aVec));
+      SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+      smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
+      return false;
+    }
+    redistributeNearVertices( theMesh, C3d, length, params, VFirst, VLast );
+
+    if(_quadraticMesh) {
+      aVec[SMDSEntity_Node] = 2*params.size() + 1;
+      aVec[SMDSEntity_Quad_Edge] = params.size() + 1;
+    }
+    else {
+      aVec[SMDSEntity_Node] = params.size();
+      aVec[SMDSEntity_Edge] = params.size() + 1;
+    }
+    
+  }
+  else {
+    //MESSAGE("************* Degenerated edge! *****************");
+    // Edge is a degenerated Edge : We put n = 5 points on the edge.
+    if(_quadraticMesh) {
+      aVec[SMDSEntity_Node] = 11;
+      aVec[SMDSEntity_Quad_Edge] = 6;
+    }
+    else {
+      aVec[SMDSEntity_Node] = 5;
+      aVec[SMDSEntity_Edge] = 6;
+    }
+  }
+
+  SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
+  aResMap.insert(std::make_pair(sm,aVec));
+
+  return true;
+}
+
+
 //=============================================================================
 /*!
  *  See comments in SMESH_Algo.cxx
@@ -946,10 +1194,9 @@ StdMeshers_Regular_1D::GetUsedHypothesis(SMESH_Mesh &         aMesh,
 
   SMESH_HypoFilter auxiliaryFilter, compatibleFilter;
   auxiliaryFilter.Init( SMESH_HypoFilter::IsAuxiliary() );
-  const bool ignoreAux = true;
-  InitCompatibleHypoFilter( compatibleFilter, ignoreAux );
+  InitCompatibleHypoFilter( compatibleFilter, /*ignoreAux=*/true );
 
-  // get non-auxiliary assigned to aShape
+  // get non-auxiliary assigned directly to aShape
   int nbHyp = aMesh.GetHypotheses( aShape, compatibleFilter, _usedHypList, false );
 
   if (nbHyp == 0 && aShape.ShapeType() == TopAbs_EDGE)
index 7df8e45338f84c17f8445379e69fd81c428640a6..aed1064abee96b9c69bc7a08751e79813b668de9 100644 (file)
@@ -1,30 +1,31 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_Regular_1D.hxx
 //           Moved here from SMESH_Regular_1D.hxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-
+//
 #ifndef _SMESH_REGULAR_1D_HXX_
 #define _SMESH_REGULAR_1D_HXX_
 
@@ -32,6 +33,8 @@
 
 #include "SMESH_1D_Algo.hxx"
 
+#include "StdMeshers_FixedPoints1D.hxx"
+
 class Adaptor3d_Curve;
 class TopoDS_Vertex;
 class StdMeshers_SegmentLengthAroundVertex;
@@ -47,7 +50,10 @@ public:
                                SMESH_Hypothesis::Hypothesis_Status& aStatus);
 
   virtual bool Compute(SMESH_Mesh& aMesh,
-                      const TopoDS_Shape& aShape);
+                       const TopoDS_Shape& aShape);
+
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
 
   virtual const std::list <const SMESHDS_Hypothesis *> &
     GetUsedHypothesis(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, const bool=true);
@@ -94,7 +100,7 @@ protected:
   StdMeshers_SegmentLengthAroundVertex* getVertexHyp(SMESH_Mesh &          theMesh,
                                                      const TopoDS_Vertex & theV);
 
-  enum HypothesisType { LOCAL_LENGTH, MAX_LENGTH, NB_SEGMENTS, BEG_END_LENGTH, DEFLECTION, ARITHMETIC_1D, NONE };
+  enum HypothesisType { LOCAL_LENGTH, MAX_LENGTH, NB_SEGMENTS, BEG_END_LENGTH, DEFLECTION, ARITHMETIC_1D, FIXED_POINTS_1D, NONE };
 
   enum ValueIndex {
     SCALE_FACTOR_IND = 0,
@@ -120,10 +126,13 @@ protected:
 
   HypothesisType _hypType;
 
+  const StdMeshers_FixedPoints1D* _fpHyp;
+
   double _value[2];
   int    _ivalue[3];
   std::vector<double> _vvalue[1];
   std::string         _svalue[1];
+  std::vector<int>    _revEdgesIDs;
 
   // a source of propagated hypothesis, is set by CheckHypothesis()
   // always called before Compute()
index 60ba2518d71baede09a713eb761a42ed686c6643..1a6f14e18bbf124919084fc3e64d2a949bc42e7d 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 // File      : StdMeshers_SegmentAroundVertex_0D.cxx
 // Module    : SMESH
@@ -38,7 +39,7 @@ StdMeshers_SegmentAroundVertex_0D::StdMeshers_SegmentAroundVertex_0D
 {
   _name = "SegmentAroundVertex_0D";
   // it is assigned to vertices but influence a state of EDGE submeshes 
-  _shapeType = (1 << TopAbs_VERTEX);   // 1 bit per shape type
+  _shapeType = (1 << TopAbs_VERTEX);    // 1 bit per shape type
 
   _compatibleHypothesis.push_back("SegmentLengthAroundVertex");
 }
@@ -92,3 +93,18 @@ bool StdMeshers_SegmentAroundVertex_0D::Compute(SMESH_Mesh&, const TopoDS_Shape&
   // StdMeshers_SegmentLengthAroundVertex hypothesis
   return true;
 }
+
+
+//=======================================================================
+//function : Evaluate
+//purpose  : 
+//=======================================================================
+
+bool StdMeshers_SegmentAroundVertex_0D::Evaluate(SMESH_Mesh&,
+                                                 const TopoDS_Shape&,
+                                                 MapShapeNbElems&)
+{
+  // This algorithm exists in order just to enable assignation of
+  // StdMeshers_SegmentLengthAroundVertex hypothesis
+  return false;
+}
index 4054a715d5c31c84909b0c7a7cf7086a521909f4..abb8ce2c665336f31b92bbdfba8eca2ef07c0e11 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_SegmentAroundVertex_0D.hxx
 //  Module : SMESH
@@ -46,6 +47,8 @@ public:
 
   virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
   
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
 };
 
 #endif
index f5540a88c8f977a13927b7ebd70196200056ddf0..27f280f43234a1b44379716abe5a3b914dc7ff6f 100644 (file)
@@ -1,28 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_SegmentLengthAroundVertex.cxx
 //  Module : SMESH
-
+//
 #include "StdMeshers_SegmentLengthAroundVertex.hxx"
 
 #include "SMESH_Mesh.hxx"
@@ -30,7 +31,6 @@
 #include "SMDS_MeshNode.hxx"
 #include "SMESHDS_Mesh.hxx"
 #include "SMESHDS_SubMesh.hxx"
-#include "SMESH_MeshEditor.hxx"
 #include "SMESH_MesherHelper.hxx"
 
 #include "utilities.h"
index c7c54bbf688a07d36b9fec0d88ac5a0229cdb093..ed196455a2fce4326ef6052b9a67de274ecf6935 100644 (file)
@@ -1,29 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_SegmentLengthAroundVertex.hxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-
+//
 #ifndef _SMESH_SegmentLengthAroundVertex_HXX_
 #define _SMESH_SegmentLengthAroundVertex_HXX_
 
index 0beb6349a1e83a5b0f06c6275fbbf7ffe17d643c..46cee3f22951040ca01495526c13daa4b0dfa70f 100644 (file)
@@ -1,28 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH StdMeshers_StartEndLength : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_StartEndLength.cxx
 //  Module : SMESH
-
+//
 #include "StdMeshers_StartEndLength.hxx"
 
 #include "SMESH_Algo.hxx"
@@ -105,9 +106,33 @@ double StdMeshers_StartEndLength::GetLength(bool isStartLength) const
  */
 //=============================================================================
 
+void StdMeshers_StartEndLength::SetReversedEdges( std::vector<int>& ids )
+{
+  if ( ids != _edgeIDs ) {
+    _edgeIDs = ids;
+
+    NotifySubMeshesHypothesisModification();
+  }
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
 ostream & StdMeshers_StartEndLength::SaveTo(ostream & save)
 {
-  save << _begLength << " " <<_endLength;
+  int listSize = _edgeIDs.size();
+  save << _begLength << " " << _endLength << " " << listSize;
+
+  if ( listSize > 0 ) {
+    for ( int i = 0; i < listSize; i++) {
+      save << " " << _edgeIDs[i];
+    }
+    save << " " << _objEntry;
+  }
+
   return save;
 }
 
@@ -120,12 +145,25 @@ ostream & StdMeshers_StartEndLength::SaveTo(ostream & save)
 istream & StdMeshers_StartEndLength::LoadFrom(istream & load)
 {
   bool isOK = true;
+  int intVal;
   isOK = (load >> _begLength);
   if (!isOK)
     load.clear(ios::badbit | load.rdstate());
   isOK = (load >> _endLength);
+
   if (!isOK)
     load.clear(ios::badbit | load.rdstate());
+  
+  isOK = (load >> intVal);
+  if (isOK && intVal > 0) {
+    _edgeIDs.reserve( intVal );
+    for (int i = 0; i < _edgeIDs.capacity() && isOK; i++) {
+      isOK = (load >> intVal);
+      if ( isOK ) _edgeIDs.push_back( intVal );
+    }
+    isOK = (load >> _objEntry);
+  }
+
   return load;
 }
 
@@ -178,7 +216,7 @@ bool StdMeshers_StartEndLength::SetParametersByMesh(const SMESH_Mesh*   theMesh,
   {
     const TopoDS_Edge& edge = TopoDS::Edge( edgeMap( i ));
     Handle(Geom_Curve) C = BRep_Tool::Curve(edge, L, UMin, UMax);
-    GeomAdaptor_Curve AdaptCurve(C);
+    GeomAdaptor_Curve AdaptCurve(C, UMin, UMax);
 
     vector< double > params;
     SMESHDS_Mesh* aMeshDS = const_cast< SMESH_Mesh* >( theMesh )->GetMeshDS();
@@ -207,6 +245,6 @@ bool StdMeshers_StartEndLength::SetParametersByMesh(const SMESH_Mesh*   theMesh,
 bool StdMeshers_StartEndLength::SetParametersByDefaults(const TDefaults&  dflts,
                                                         const SMESH_Mesh* /*theMesh*/)
 {
-  return bool(_begLength = _endLength = dflts._elemLength );
+  return (_begLength = _endLength = dflts._elemLength );
 }
 
index 00f228771fee69fa82d1f726a0888b2ed6bcfcbb..dc8781a7fea12f1f49db0c8cdc55b043ec93bae7 100644 (file)
@@ -1,28 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH StdMeshers : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_StartEndLength.hxx
 //  Module : SMESH
-
+//
 #ifndef _STDMESHERS_STARTENDLENGTH_HXX_
 #define _STDMESHERS_STARTENDLENGTH_HXX_
 
@@ -31,6 +32,8 @@
 #include "SMESH_Hypothesis.hxx"
 #include "Utils_SALOME_Exception.hxx"
 
+#include <vector>
+
 class STDMESHERS_EXPORT StdMeshers_StartEndLength:public SMESH_Hypothesis
 {
  public:
@@ -40,6 +43,14 @@ class STDMESHERS_EXPORT StdMeshers_StartEndLength:public SMESH_Hypothesis
   void SetLength(double length, bool isStartLength) throw(SALOME_Exception);
 
   double GetLength(bool isStartLength) const;
+
+  void SetReversedEdges( std::vector<int>& ids);
+
+  const std::vector<int>& GetReversedEdges() const { return _edgeIDs; }
+
+  void SetObjectEntry( const char* entry ) { _objEntry = entry; }
+
+  const char* GetObjectEntry() { return _objEntry.c_str(); }
   
   virtual std::ostream & SaveTo(std::ostream & save);
   virtual std::istream & LoadFrom(std::istream & load);
@@ -63,6 +74,8 @@ class STDMESHERS_EXPORT StdMeshers_StartEndLength:public SMESH_Hypothesis
 
 protected:
   double _begLength, _endLength;
+  std::vector<int>   _edgeIDs;
+  std::string        _objEntry;
 };
 
 #endif
diff --git a/src/StdMeshers/StdMeshers_TrianglePreference.cxx b/src/StdMeshers/StdMeshers_TrianglePreference.cxx
deleted file mode 100644 (file)
index 331cd0d..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-//  SMESH StdMeshers_TrianglePreference 
-//  File   : StdMeshers_TrianglePreference.cxx
-//  Module : SMESH
-
-#include "StdMeshers_TrianglePreference.hxx"
-#include "utilities.h"
-
-using namespace std;
-
-//=============================================================================
-/*!
- *  
- */
-//=============================================================================
-
-StdMeshers_TrianglePreference::StdMeshers_TrianglePreference(int         hypId,
-                                                                 int         studyId,
-                                                                 SMESH_Gen * gen)
-     :SMESH_Hypothesis(hypId, studyId, gen)
-{
-  _name = "TrianglePreference";
-  _param_algo_dim = -2; // auxiliary used by StdMeshers_Quadrangle_2D
-}
-
-//=============================================================================
-/*!
- *  
- */
-//=============================================================================
-
-StdMeshers_TrianglePreference::~StdMeshers_TrianglePreference()
-{
-}
-
-//=============================================================================
-/*!
- *  
- */
-//=============================================================================
-
-ostream & StdMeshers_TrianglePreference::SaveTo(ostream & save)
-{
-  return save;
-}
-
-//=============================================================================
-/*!
- *  
- */
-//=============================================================================
-
-istream & StdMeshers_TrianglePreference::LoadFrom(istream & load)
-{
-  return load;
-}
-
-//=============================================================================
-/*!
- *  
- */
-//=============================================================================
-
-ostream & operator <<(ostream & save, StdMeshers_TrianglePreference & hyp)
-{
-  return hyp.SaveTo( save );
-}
-
-//=============================================================================
-/*!
- *  
- */
-//=============================================================================
-
-istream & operator >>(istream & load, StdMeshers_TrianglePreference & hyp)
-{
-  return hyp.LoadFrom( load );
-}
-//================================================================================
-/*!
- * \brief Initialize my parameter values by the mesh built on the geometry
- * \param theMesh - the built mesh
- * \param theShape - the geometry of interest
- * \retval bool - true if parameter values have been successfully defined
- *
- * Just return false as this hypothesis does not have parameters values
- */
-//================================================================================
-
-bool StdMeshers_TrianglePreference::SetParametersByMesh(const SMESH_Mesh* /*theMesh*/,
-                                                          const TopoDS_Shape& /*theShape*/)
-{
-  return false;
-}
-
-//================================================================================
-/*!
- * \brief Initialize my parameter values by default parameters.
- *  \retval bool - true if parameter values have been successfully defined
- */
-//================================================================================
-
-bool StdMeshers_TrianglePreference::SetParametersByDefaults(const TDefaults&  /*dflts*/,
-                                                            const SMESH_Mesh* /*theMesh*/)
-{
-  return false;
-}
-
diff --git a/src/StdMeshers/StdMeshers_TrianglePreference.hxx b/src/StdMeshers/StdMeshers_TrianglePreference.hxx
deleted file mode 100644 (file)
index 34ec364..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-//  SMESH StdMeshers : implementaion of SMESH idl descriptions
-//  File   : StdMeshers_TrianglePreference.hxx
-//  Module : SMESH
-
-#ifndef _StdMeshers_TrianglePreference_HXX_
-#define _StdMeshers_TrianglePreference_HXX_
-
-#include "SMESH_StdMeshers.hxx"
-
-#include "SMESH_Hypothesis.hxx"
-#include "Utils_SALOME_Exception.hxx"
-
-/*!
- * \brief Hypothesis for StdMeshers_Quadrangle_2D, forcing construction
- *        of triangles in the in a refinement area if the number of nodes 
- *        on opposite edges is not the same. See Issue 16186.
- */
-class STDMESHERS_EXPORT StdMeshers_TrianglePreference:public SMESH_Hypothesis
-{
- public:
-  StdMeshers_TrianglePreference(int hypId, int studyId, SMESH_Gen * gen);
-  virtual ~ StdMeshers_TrianglePreference();
-  
-  virtual std::ostream & SaveTo(std::ostream & save);
-  virtual std::istream & LoadFrom(std::istream & load);
-  friend std::ostream & operator <<(std::ostream & save, StdMeshers_TrianglePreference & hyp);
-  friend std::istream & operator >>(std::istream & load, StdMeshers_TrianglePreference & hyp);
-
-  /*!
-   * \brief Initialize my parameter values by the mesh built on the geometry
-    * \param theMesh - the built mesh
-    * \param theShape - the geometry of interest
-    * \retval bool - true if parameter values have been successfully defined
-    *
-    * Just return false as this hypothesis does not have parameters values
-   */
-  virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape);
-
-  /*!
-   * \brief Initialize my parameter values by default parameters.
-   *  \retval bool - true if parameter values have been successfully defined
-   */
-  virtual bool SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh=0);
-
-};
-
-#endif
index e44345af42877cd5efe6020977b870fce7c3eb14..e93dfffaf27147c07cb12fb95288b53555ad4933 100644 (file)
@@ -1,24 +1,22 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  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 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.
 //
-//  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
 //
-//  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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 // File      : StdMeshers_UseExisting_1D2D.cxx
 // Module    : SMESH
@@ -60,10 +58,27 @@ bool StdMeshers_UseExisting_1D::CheckHypothesis(SMESH_Mesh& ,
 
 bool StdMeshers_UseExisting_1D::Compute(SMESH_Mesh&, const TopoDS_Shape&)
 {
-  // This algorithm exists to allow mesh generation by mesh edition functions in TUI mode
+  // This algorithm exists to allow mesh generation by mesh
+  // edition functions in TUI mode
   return true;
 }
 
+
+//=======================================================================
+//function : Evaluate
+//purpose  : 
+//=======================================================================
+
+bool StdMeshers_UseExisting_1D::Evaluate(SMESH_Mesh&,
+                                         const TopoDS_Shape&,
+                                         MapShapeNbElems&)
+{
+  // This algorithm exists to allow mesh generation by mesh
+  // edition functions in TUI mode
+  return false;
+}
+
+
 //=======================================================================
 //function : StdMeshers_UseExisting_2D
 //purpose  : 
@@ -97,6 +112,22 @@ bool StdMeshers_UseExisting_2D::CheckHypothesis(SMESH_Mesh& ,
 
 bool StdMeshers_UseExisting_2D::Compute(SMESH_Mesh&, const TopoDS_Shape&)
 {
-  // This algorithm exists to allow mesh generation by mesh edition functions in TUI mode
+  // This algorithm exists to allow mesh generation by mesh edition
+  // functions in TUI mode
   return true;
 }
+
+
+//=======================================================================
+//function : Evaluate
+//purpose  : 
+//=======================================================================
+
+bool StdMeshers_UseExisting_2D::Evaluate(SMESH_Mesh&,
+                                         const TopoDS_Shape&,
+                                         MapShapeNbElems&)
+{
+  // This algorithm exists to allow mesh generation by mesh edition
+  // functions in TUI mode
+  return false;
+}
index 6d5a5e495be4610b43b02a89868181fb03855530..23c64b5b9191c12f7bbd3c7c426c5648168455a3 100644 (file)
@@ -1,24 +1,22 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  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 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.
 //
-//  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
 //
-//  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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_UseExisting_1D2D.hxx
 //  Module : SMESH
@@ -46,6 +44,8 @@ public:
 
   virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
   
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
 };
 
 class STDMESHERS_EXPORT StdMeshers_UseExisting_1D: public SMESH_1D_Algo
@@ -59,6 +59,8 @@ public:
 
   virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
   
+  virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+                        MapShapeNbElems& aResMap);
 };
 
 #endif
diff --git a/src/StdMeshers/StdMeshers_ViscousLayers.cxx b/src/StdMeshers/StdMeshers_ViscousLayers.cxx
new file mode 100644 (file)
index 0000000..ddae235
--- /dev/null
@@ -0,0 +1,4483 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+// File      : StdMeshers_ViscousLayers.cxx
+// Created   : Wed Dec  1 15:15:34 2010
+// Author    : Edward AGAPOV (eap)
+
+#include "StdMeshers_ViscousLayers.hxx"
+
+#include "SMDS_EdgePosition.hxx"
+#include "SMDS_FaceOfNodes.hxx"
+#include "SMDS_FacePosition.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_SetIterator.hxx"
+#include "SMESHDS_Group.hxx"
+#include "SMESHDS_Hypothesis.hxx"
+#include "SMESH_Algo.hxx"
+#include "SMESH_ComputeError.hxx"
+#include "SMESH_ControlsDef.hxx"
+#include "SMESH_Gen.hxx"
+#include "SMESH_Group.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_MesherHelper.hxx"
+#include "SMESH_ProxyMesh.hxx"
+#include "SMESH_subMesh.hxx"
+#include "SMESH_subMeshEventListener.hxx"
+
+#include "utilities.h"
+
+#include <BRepAdaptor_Curve2d.hxx>
+#include <BRep_Tool.hxx>
+#include <Bnd_B2d.hxx>
+#include <Bnd_B3d.hxx>
+#include <ElCLib.hxx>
+#include <GCPnts_AbscissaPoint.hxx>
+#include <Geom2d_Circle.hxx>
+#include <Geom2d_Line.hxx>
+#include <Geom2d_TrimmedCurve.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <Geom_Circle.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom_Line.hxx>
+#include <Geom_TrimmedCurve.hxx>
+#include <Precision.hxx>
+#include <Standard_ErrorHandler.hxx>
+#include <TColStd_Array1OfReal.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <gp_Ax1.hxx>
+#include <gp_Vec.hxx>
+#include <gp_XY.hxx>
+
+#include <list>
+#include <string>
+#include <cmath>
+#include <limits>
+
+//#define __myDEBUG
+
+using namespace std;
+
+//================================================================================
+namespace VISCOUS
+{
+  typedef int TGeomID;
+
+  enum UIndex { U_TGT = 1, U_SRC, LEN_TGT };
+
+  /*!
+   * \brief SMESH_ProxyMesh computed by _ViscousBuilder for a SOLID.
+   * It is stored in a SMESH_subMesh of the SOLID as SMESH_subMeshEventListenerData
+   */
+  struct _MeshOfSolid : public SMESH_ProxyMesh,
+                        public SMESH_subMeshEventListenerData
+  {
+    bool _n2nMapComputed;
+
+    _MeshOfSolid( SMESH_Mesh* mesh)
+      :SMESH_subMeshEventListenerData( /*isDeletable=*/true),_n2nMapComputed(false)
+    {
+      SMESH_ProxyMesh::setMesh( *mesh );
+    }
+
+    // returns submesh for a geom face
+    SMESH_ProxyMesh::SubMesh* getFaceSubM(const TopoDS_Face& F, bool create=false)
+    {
+      TGeomID i = SMESH_ProxyMesh::shapeIndex(F);
+      return create ? SMESH_ProxyMesh::getProxySubMesh(i) : findProxySubMesh(i);
+    }
+    void setNode2Node(const SMDS_MeshNode*                 srcNode,
+                      const SMDS_MeshNode*                 proxyNode,
+                      const SMESH_ProxyMesh::SubMesh* subMesh)
+    {
+      SMESH_ProxyMesh::setNode2Node( srcNode,proxyNode,subMesh);
+    }
+  };
+  //--------------------------------------------------------------------------------
+  /*!
+   * \brief Listener of events of 3D sub-meshes computed with viscous layers.
+   * It is used to clear an inferior dim sub-meshes modified by viscous layers
+   */
+  class _SrinkShapeListener : SMESH_subMeshEventListener
+  {
+    _SrinkShapeListener()
+      : SMESH_subMeshEventListener(/*isDeletable=*/false,
+                                   "StdMeshers_ViscousLayers::_SrinkShapeListener") {}
+    static SMESH_subMeshEventListener* Get() { static _SrinkShapeListener l; return &l; }
+  public:
+    virtual void ProcessEvent(const int                       event,
+                              const int                       eventType,
+                              SMESH_subMesh*                  solidSM,
+                              SMESH_subMeshEventListenerData* data,
+                              const SMESH_Hypothesis*         hyp)
+    {
+      if ( SMESH_subMesh::COMPUTE_EVENT == eventType && solidSM->IsEmpty() && data )
+      {
+        SMESH_subMeshEventListener::ProcessEvent(event,eventType,solidSM,data,hyp);
+      }
+    }
+    static void ToClearSubMeshWithSolid( SMESH_subMesh*      sm,
+                                         const TopoDS_Shape& solid)
+    {
+      SMESH_subMesh* solidSM = sm->GetFather()->GetSubMesh( solid );
+      SMESH_subMeshEventListenerData* data = solidSM->GetEventListenerData( Get());
+      if ( data )
+      {
+        if ( find( data->mySubMeshes.begin(), data->mySubMeshes.end(), sm ) ==
+             data->mySubMeshes.end())
+          data->mySubMeshes.push_back( sm );
+      }
+      else
+      {
+        data = SMESH_subMeshEventListenerData::MakeData( /*dependent=*/sm );
+        sm->SetEventListener( Get(), data, /*whereToListenTo=*/solidSM );
+      }
+    }
+  };
+  //--------------------------------------------------------------------------------
+  /*!
+   * \brief Listener of events of 3D sub-meshes computed with viscous layers.
+   * It is used to store data computed by _ViscousBuilder for a sub-mesh and to
+   * delete the data as soon as it has been used
+   */
+  class _ViscousListener : SMESH_subMeshEventListener
+  {
+    _ViscousListener():
+      SMESH_subMeshEventListener(/*isDeletable=*/false,
+                                 "StdMeshers_ViscousLayers::_ViscousListener") {}
+    static SMESH_subMeshEventListener* Get() { static _ViscousListener l; return &l; }
+  public:
+    virtual void ProcessEvent(const int                       event,
+                              const int                       eventType,
+                              SMESH_subMesh*                  subMesh,
+                              SMESH_subMeshEventListenerData* data,
+                              const SMESH_Hypothesis*         hyp)
+    {
+      if ( SMESH_subMesh::COMPUTE_EVENT == eventType )
+      {
+        // delete SMESH_ProxyMesh containing temporary faces
+        subMesh->DeleteEventListener( this );
+      }
+    }
+    // Finds or creates proxy mesh of the solid
+    static _MeshOfSolid* GetSolidMesh(SMESH_Mesh*         mesh,
+                                      const TopoDS_Shape& solid,
+                                      bool                toCreate=false)
+    {
+      if ( !mesh ) return 0;
+      SMESH_subMesh* sm = mesh->GetSubMesh(solid);
+      _MeshOfSolid* data = (_MeshOfSolid*) sm->GetEventListenerData( Get() );
+      if ( !data && toCreate )
+      {
+        data = new _MeshOfSolid(mesh);
+        data->mySubMeshes.push_back( sm ); // to find SOLID by _MeshOfSolid
+        sm->SetEventListener( Get(), data, sm );
+      }
+      return data;
+    }
+    // Removes proxy mesh of the solid
+    static void RemoveSolidMesh(SMESH_Mesh* mesh, const TopoDS_Shape& solid)
+    {
+      mesh->GetSubMesh(solid)->DeleteEventListener( _ViscousListener::Get() );
+    }
+  };
+  
+  //--------------------------------------------------------------------------------
+  /*!
+   * \brief Simplex (triangle or tetrahedron) based on 1 (tria) or 2 (tet) nodes of
+   * _LayerEdge and 2 nodes of the mesh surface beening smoothed.
+   * The class is used to check validity of face or volumes around a smoothed node;
+   * it stores only 2 nodes as the other nodes are stored by _LayerEdge.
+   */
+  struct _Simplex
+  {
+    const SMDS_MeshNode *_nPrev, *_nNext; // nodes on a smoothed mesh surface
+    _Simplex(const SMDS_MeshNode* nPrev=0, const SMDS_MeshNode* nNext=0)
+      : _nPrev(nPrev), _nNext(nNext) {}
+    bool IsForward(const SMDS_MeshNode* nSrc, const gp_XYZ* pntTgt) const
+    {
+      const double M[3][3] =
+        {{ _nNext->X() - nSrc->X(), _nNext->Y() - nSrc->Y(), _nNext->Z() - nSrc->Z() },
+         { pntTgt->X() - nSrc->X(), pntTgt->Y() - nSrc->Y(), pntTgt->Z() - nSrc->Z() },
+         { _nPrev->X() - nSrc->X(), _nPrev->Y() - nSrc->Y(), _nPrev->Z() - nSrc->Z() }};
+      double determinant = ( + M[0][0]*M[1][1]*M[2][2]
+                             + M[0][1]*M[1][2]*M[2][0]
+                             + M[0][2]*M[1][0]*M[2][1]
+                             - M[0][0]*M[1][2]*M[2][1]
+                             - M[0][1]*M[1][0]*M[2][2]
+                             - M[0][2]*M[1][1]*M[2][0]);
+      return determinant > 1e-100;
+    }
+    bool IsForward(const gp_XY&         tgtUV,
+                   const SMDS_MeshNode* smoothedNode,
+                   const TopoDS_Face&   face,
+                   SMESH_MesherHelper&  helper,
+                   const double         refSign) const
+    {
+      gp_XY prevUV = helper.GetNodeUV( face, _nPrev, smoothedNode );
+      gp_XY nextUV = helper.GetNodeUV( face, _nNext, smoothedNode );
+      gp_Vec2d v1( tgtUV, prevUV ), v2( tgtUV, nextUV );
+      double d = v1 ^ v2;
+      return d*refSign > 1e-100;
+    }
+    bool IsNeighbour(const _Simplex& other) const
+    {
+      return _nPrev == other._nNext || _nNext == other._nPrev;
+    }
+  };
+  //--------------------------------------------------------------------------------
+  /*!
+   * Structure used to take into account surface curvature while smoothing
+   */
+  struct _Curvature
+  {
+    double _r; // radius
+    double _k; // factor to correct node smoothed position
+  public:
+    static _Curvature* New( double avgNormProj, double avgDist )
+    {
+      _Curvature* c = 0;
+      if ( fabs( avgNormProj / avgDist ) > 1./200 )
+      {
+        c = new _Curvature;
+        c->_r = avgDist * avgDist / avgNormProj;
+        c->_k = avgDist * avgDist / c->_r / c->_r;
+        c->_k *= ( c->_r < 0 ? 1/1.1 : 1.1 ); // not to be too restrictive
+      }
+      return c;
+    }
+    double lenDelta(double len) const { return _k * ( _r + len ); }
+  };
+  struct _LayerEdge;
+  //--------------------------------------------------------------------------------
+  /*!
+   * Structure used to smooth a _LayerEdge (master) based on an EDGE.
+   */
+  struct _2NearEdges
+  {
+    // target nodes of 2 neighbour _LayerEdge's based on the same EDGE
+    const SMDS_MeshNode* _nodes[2];
+    // vectors from source nodes of 2 _LayerEdge's to the source node of master _LayerEdge
+    //gp_XYZ               _vec[2];
+    double               _wgt[2]; // weights of _nodes
+    _LayerEdge*          _edges[2];
+
+     // normal to plane passing through _LayerEdge._normal and tangent of EDGE
+    gp_XYZ*              _plnNorm;
+
+    _2NearEdges() { _nodes[0]=_nodes[1]=0; _plnNorm = 0; }
+    void reverse() {
+      std::swap( _nodes[0], _nodes[1] );
+      std::swap( _wgt[0], _wgt[1] );
+    }
+  };
+  //--------------------------------------------------------------------------------
+  /*!
+   * \brief Edge normal to surface, connecting a node on solid surface (_nodes[0])
+   * and a node of the most internal layer (_nodes.back())
+   */
+  struct _LayerEdge
+  {
+    vector< const SMDS_MeshNode*> _nodes;
+
+    gp_XYZ              _normal; // to solid surface
+    vector<gp_XYZ>      _pos; // points computed during inflation
+    double              _len; // length achived with the last step
+    double              _cosin; // of angle (_normal ^ surface)
+    double              _lenFactor; // to compute _len taking _cosin into account
+
+    // face or edge w/o layer along or near which _LayerEdge is inflated
+    TopoDS_Shape        _sWOL;
+    // simplices connected to the source node (_nodes[0]);
+    // used for smoothing and quality check of _LayerEdge's based on the FACE
+    vector<_Simplex>    _simplices;
+    // data for smoothing of _LayerEdge's based on the EDGE
+    _2NearEdges*        _2neibors;
+
+    _Curvature*         _curvature;
+    // TODO:: detele _Curvature, _plnNorm
+
+    void SetNewLength( double len, SMESH_MesherHelper& helper );
+    bool SetNewLength2d( Handle(Geom_Surface)& surface,
+                         const TopoDS_Face&    F,
+                         SMESH_MesherHelper&   helper );
+    void SetDataByNeighbors( const SMDS_MeshNode* n1,
+                             const SMDS_MeshNode* n2,
+                             SMESH_MesherHelper&  helper);
+    void InvalidateStep( int curStep );
+    bool Smooth(int& badNb);
+    bool SmoothOnEdge(Handle(Geom_Surface)& surface,
+                      const TopoDS_Face&    F,
+                      SMESH_MesherHelper&   helper);
+    bool FindIntersection( SMESH_ElementSearcher&   searcher,
+                           double &                 distance,
+                           const double&            epsilon,
+                           const SMDS_MeshElement** face = 0);
+    bool SegTriaInter( const gp_Ax1&        lastSegment,
+                       const SMDS_MeshNode* n0,
+                       const SMDS_MeshNode* n1,
+                       const SMDS_MeshNode* n2,
+                       double&              dist,
+                       const double&        epsilon) const;
+    gp_Ax1 LastSegment(double& segLen) const;
+    bool IsOnEdge() const { return _2neibors; }
+    void Copy( _LayerEdge& other, SMESH_MesherHelper& helper );
+    void SetCosin( double cosin );
+  };
+  struct _LayerEdgeCmp
+  {
+    bool operator () (const _LayerEdge* e1, const _LayerEdge* e2) const
+    {
+      const bool cmpNodes = ( e1 && e2 && e1->_nodes.size() && e2->_nodes.size() );
+      return cmpNodes ? ( e1->_nodes[0]->GetID() < e2->_nodes[0]->GetID()) : ( e1 < e2 );
+    }
+  };
+  //--------------------------------------------------------------------------------
+
+  typedef map< const SMDS_MeshNode*, _LayerEdge*, TIDCompare > TNode2Edge;
+  
+  //--------------------------------------------------------------------------------
+  /*!
+   * \brief Data of a SOLID
+   */
+  struct _SolidData
+  {
+    TopoDS_Shape                    _solid;
+    const StdMeshers_ViscousLayers* _hyp;
+    _MeshOfSolid*                   _proxyMesh;
+    set<TGeomID>                    _reversedFaceIds;
+
+    double                          _stepSize, _stepSizeCoeff;
+    const SMDS_MeshNode*            _stepSizeNodes[2];
+
+    TNode2Edge                      _n2eMap;
+    // edges of _n2eMap. We keep same data in two containers because
+    // iteration over the map is 5 time longer than over the vector
+    vector< _LayerEdge* >           _edges;
+
+    // key: an id of shape (EDGE or VERTEX) shared by a FACE with
+    // layers and a FACE w/o layers
+    // value: the shape (FACE or EDGE) to shrink mesh on.
+    // _LayerEdge's basing on nodes on key shape are inflated along the value shape
+    map< TGeomID, TopoDS_Shape >     _shrinkShape2Shape;
+
+    // FACE's WOL, srink on which is forbiden due to algo on the adjacent SOLID
+    set< TGeomID >                   _noShrinkFaces;
+
+    // <EDGE to smooth on> to <it's curve>
+    map< TGeomID,Handle(Geom_Curve)> _edge2curve;
+
+    // end indices in _edges of _LayerEdge on one shape to smooth
+    vector< int >                    _endEdgeToSmooth;
+
+    double                           _epsilon; // precision for SegTriaInter()
+
+    int                              _index; // for debug
+
+    _SolidData(const TopoDS_Shape&             s=TopoDS_Shape(),
+               const StdMeshers_ViscousLayers* h=0,
+               _MeshOfSolid*                   m=0) :_solid(s), _hyp(h), _proxyMesh(m) {}
+    ~_SolidData();
+
+    Handle(Geom_Curve) CurveForSmooth( const TopoDS_Edge&    E,
+                                       const int             iFrom,
+                                       const int             iTo,
+                                       Handle(Geom_Surface)& surface,
+                                       const TopoDS_Face&    F,
+                                       SMESH_MesherHelper&   helper);
+  };
+  //--------------------------------------------------------------------------------
+  /*!
+   * \brief Data of node on a shrinked FACE
+   */
+  struct _SmoothNode
+  {
+    const SMDS_MeshNode*         _node;
+    //vector<const SMDS_MeshNode*> _nodesAround;
+    vector<_Simplex>             _simplices; // for quality check
+
+    bool Smooth(int&                  badNb,
+                Handle(Geom_Surface)& surface,
+                SMESH_MesherHelper&   helper,
+                const double          refSign,
+                bool                  isCentroidal,
+                bool                  set3D);
+  };
+  //--------------------------------------------------------------------------------
+  /*!
+   * \brief Builder of viscous layers
+   */
+  class _ViscousBuilder
+  {
+  public:
+    _ViscousBuilder();
+    // does it's job
+    SMESH_ComputeErrorPtr Compute(SMESH_Mesh&         mesh,
+                                  const TopoDS_Shape& shape);
+
+    // restore event listeners used to clear an inferior dim sub-mesh modified by viscous layers
+    void RestoreListeners();
+
+    // computes SMESH_ProxyMesh::SubMesh::_n2n;
+    bool MakeN2NMap( _MeshOfSolid* pm );
+
+  private:
+
+    bool findSolidsWithLayers();
+    bool findFacesWithLayers();
+    bool makeLayer(_SolidData& data);
+    bool setEdgeData(_LayerEdge& edge, const set<TGeomID>& subIds,
+                     SMESH_MesherHelper& helper, _SolidData& data);
+    bool findNeiborsOnEdge(const _LayerEdge*     edge,
+                           const SMDS_MeshNode*& n1,
+                           const SMDS_MeshNode*& n2,
+                           _SolidData&           data);
+    void getSimplices( const SMDS_MeshNode* node, vector<_Simplex>& simplices,
+                       const set<TGeomID>& ingnoreShapes,
+                       const _SolidData*   dataToCheckOri = 0,
+                       const bool          toSort = false);
+    bool sortEdges( _SolidData&                    data,
+                    vector< vector<_LayerEdge*> >& edgesByGeom);
+    void limitStepSize( _SolidData&             data,
+                        const SMDS_MeshElement* face,
+                        const double            cosin);
+    void limitStepSize( _SolidData& data, const double minSize);
+    bool inflate(_SolidData& data);
+    bool smoothAndCheck(_SolidData& data, const int nbSteps, double & distToIntersection);
+    bool smoothAnalyticEdge( _SolidData&           data,
+                             const int             iFrom,
+                             const int             iTo,
+                             Handle(Geom_Surface)& surface,
+                             const TopoDS_Face&    F,
+                             SMESH_MesherHelper&   helper);
+    bool updateNormals( _SolidData& data, SMESH_MesherHelper& helper );
+    bool refine(_SolidData& data);
+    bool shrink();
+    bool prepareEdgeToShrink( _LayerEdge& edge, const TopoDS_Face& F,
+                              SMESH_MesherHelper& helper,
+                              const SMESHDS_SubMesh* faceSubMesh );
+    void fixBadFaces(const TopoDS_Face& F, SMESH_MesherHelper& helper);
+    bool addBoundaryElements();
+
+    bool error( const string& text, int solidID=-1 );
+    SMESHDS_Mesh* getMeshDS() { return _mesh->GetMeshDS(); }
+
+    // debug
+    void makeGroupOfLE();
+
+    SMESH_Mesh*           _mesh;
+    SMESH_ComputeErrorPtr _error;
+
+    vector< _SolidData >  _sdVec;
+    set<TGeomID>          _ignoreShapeIds;
+    int                   _tmpFaceID;
+  };
+  //--------------------------------------------------------------------------------
+  /*!
+   * \brief Shrinker of nodes on the EDGE
+   */
+  class _Shrinker1D
+  {
+    vector<double>                _initU;
+    vector<double>                _normPar;
+    vector<const SMDS_MeshNode*>  _nodes;
+    const _LayerEdge*             _edges[2];
+    bool                          _done;
+  public:
+    void AddEdge( const _LayerEdge* e, SMESH_MesherHelper& helper );
+    void Compute(bool set3D, SMESH_MesherHelper& helper);
+    void RestoreParams();
+    void SwapSrcTgtNodes(SMESHDS_Mesh* mesh);
+  };
+  //--------------------------------------------------------------------------------
+  /*!
+   * \brief Class of temporary mesh face.
+   * We can't use SMDS_FaceOfNodes since it's impossible to set it's ID which is
+   * needed because SMESH_ElementSearcher internaly uses set of elements sorted by ID
+   */
+  struct TmpMeshFace : public SMDS_MeshElement
+  {
+    vector<const SMDS_MeshNode* > _nn;
+    TmpMeshFace( const vector<const SMDS_MeshNode*>& nodes, int id):
+      SMDS_MeshElement(id), _nn(nodes) {}
+    virtual const SMDS_MeshNode* GetNode(const int ind) const { return _nn[ind]; }
+    virtual SMDSAbs_ElementType  GetType() const              { return SMDSAbs_Face; }
+    virtual vtkIdType GetVtkType() const                      { return -1; }
+    virtual SMDSAbs_EntityType   GetEntityType() const        { return SMDSEntity_Last; }
+    virtual SMDSAbs_GeometryType GetGeomType() const          { return SMDSGeom_TRIANGLE; }
+virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const
+    { return SMDS_ElemIteratorPtr( new SMDS_NodeVectorElemIterator( _nn.begin(), _nn.end()));}
+  };
+  //--------------------------------------------------------------------------------
+  /*!
+   * \brief Class of temporary mesh face storing _LayerEdge it's based on
+   */
+  struct TmpMeshFaceOnEdge : public TmpMeshFace
+  {
+    _LayerEdge *_le1, *_le2;
+    TmpMeshFaceOnEdge( _LayerEdge* le1, _LayerEdge* le2, int ID ):
+      TmpMeshFace( vector<const SMDS_MeshNode*>(4), ID ), _le1(le1), _le2(le2)
+    {
+      _nn[0]=_le1->_nodes[0];
+      _nn[1]=_le1->_nodes.back();
+      _nn[2]=_le2->_nodes.back();
+      _nn[3]=_le2->_nodes[0];
+    }
+  };
+} // namespace VISCOUS
+
+//================================================================================
+// StdMeshers_ViscousLayers hypothesis
+//
+StdMeshers_ViscousLayers::StdMeshers_ViscousLayers(int hypId, int studyId, SMESH_Gen* gen)
+  :SMESH_Hypothesis(hypId, studyId, gen),
+   _nbLayers(1), _thickness(1), _stretchFactor(1)
+{
+  _name = StdMeshers_ViscousLayers::GetHypType();
+  _param_algo_dim = -3; // auxiliary hyp used by 3D algos
+} // --------------------------------------------------------------------------------
+void StdMeshers_ViscousLayers::SetIgnoreFaces(const std::vector<int>& faceIds)
+{
+  if ( faceIds != _ignoreFaceIds )
+    _ignoreFaceIds = faceIds, NotifySubMeshesHypothesisModification();
+} // --------------------------------------------------------------------------------
+void StdMeshers_ViscousLayers::SetTotalThickness(double thickness)
+{
+  if ( thickness != _thickness )
+    _thickness = thickness, NotifySubMeshesHypothesisModification();
+} // --------------------------------------------------------------------------------
+void StdMeshers_ViscousLayers::SetNumberLayers(int nb)
+{
+  if ( _nbLayers != nb )
+    _nbLayers = nb, NotifySubMeshesHypothesisModification();
+} // --------------------------------------------------------------------------------
+void StdMeshers_ViscousLayers::SetStretchFactor(double factor)
+{
+  if ( _stretchFactor != factor )
+    _stretchFactor = factor, NotifySubMeshesHypothesisModification();
+} // --------------------------------------------------------------------------------
+SMESH_ProxyMesh::Ptr
+StdMeshers_ViscousLayers::Compute(SMESH_Mesh&         theMesh,
+                                  const TopoDS_Shape& theShape,
+                                  const bool          toMakeN2NMap) const
+{
+  using namespace VISCOUS;
+  _ViscousBuilder bulder;
+  SMESH_ComputeErrorPtr err = bulder.Compute( theMesh, theShape );
+  if ( err && !err->IsOK() )
+    return SMESH_ProxyMesh::Ptr();
+
+  vector<SMESH_ProxyMesh::Ptr> components;
+  TopExp_Explorer exp( theShape, TopAbs_SOLID );
+  for ( ; exp.More(); exp.Next() )
+  {
+    if ( _MeshOfSolid* pm =
+         _ViscousListener::GetSolidMesh( &theMesh, exp.Current(), /*toCreate=*/false))
+    {
+      if ( toMakeN2NMap && !pm->_n2nMapComputed )
+        if ( !bulder.MakeN2NMap( pm ))
+          return SMESH_ProxyMesh::Ptr();
+      components.push_back( SMESH_ProxyMesh::Ptr( pm ));
+      pm->myIsDeletable = false; // it will de deleted by boost::shared_ptr
+    }
+    _ViscousListener::RemoveSolidMesh ( &theMesh, exp.Current() );
+  }
+  switch ( components.size() )
+  {
+  case 0: break;
+
+  case 1: return components[0];
+
+  default: return SMESH_ProxyMesh::Ptr( new SMESH_ProxyMesh( components ));
+  }
+  return SMESH_ProxyMesh::Ptr();
+} // --------------------------------------------------------------------------------
+std::ostream & StdMeshers_ViscousLayers::SaveTo(std::ostream & save)
+{
+  save << " " << _nbLayers
+       << " " << _thickness
+       << " " << _stretchFactor
+       << " " << _ignoreFaceIds.size();
+  for ( unsigned i = 0; i < _ignoreFaceIds.size(); ++i )
+    save << " " << _ignoreFaceIds[i];
+  return save;
+} // --------------------------------------------------------------------------------
+std::istream & StdMeshers_ViscousLayers::LoadFrom(std::istream & load)
+{
+  int nbFaces, faceID;
+  load >> _nbLayers >> _thickness >> _stretchFactor >> nbFaces;
+  while ( _ignoreFaceIds.size() < nbFaces && load >> faceID )
+    _ignoreFaceIds.push_back( faceID );
+  return load;
+} // --------------------------------------------------------------------------------
+bool StdMeshers_ViscousLayers::SetParametersByMesh(const SMESH_Mesh*   theMesh,
+                                                   const TopoDS_Shape& theShape)
+{
+  // TODO
+  return false;
+}
+// END StdMeshers_ViscousLayers hypothesis
+//================================================================================
+
+namespace
+{
+  gp_XYZ getEdgeDir( const TopoDS_Edge& E, const TopoDS_Vertex& fromV )
+  {
+    gp_Vec dir;
+    double f,l;
+    Handle(Geom_Curve) c = BRep_Tool::Curve( E, f, l );
+    gp_Pnt p = BRep_Tool::Pnt( fromV );
+    double distF = p.SquareDistance( c->Value( f ));
+    double distL = p.SquareDistance( c->Value( l ));
+    c->D1(( distF < distL ? f : l), p, dir );
+    if ( distL < distF ) dir.Reverse();
+    return dir.XYZ();
+  }
+  //--------------------------------------------------------------------------------
+  gp_XYZ getEdgeDir( const TopoDS_Edge& E, const SMDS_MeshNode* atNode,
+                     SMESH_MesherHelper& helper)
+  {
+    gp_Vec dir;
+    double f,l; gp_Pnt p;
+    Handle(Geom_Curve) c = BRep_Tool::Curve( E, f, l );
+    double u = helper.GetNodeU( E, atNode );
+    c->D1( u, p, dir );
+    return dir.XYZ();
+  }
+  //--------------------------------------------------------------------------------
+  gp_XYZ getFaceDir( const TopoDS_Face& F, const TopoDS_Edge& fromE,
+                     const SMDS_MeshNode* node, SMESH_MesherHelper& helper, bool& ok)
+  {
+    gp_XY uv = helper.GetNodeUV( F, node, 0, &ok );
+    Handle(Geom_Surface) surface = BRep_Tool::Surface( F );
+    gp_Pnt p; gp_Vec du, dv, norm;
+    surface->D1( uv.X(),uv.Y(), p, du,dv );
+    norm = du ^ dv;
+
+    double f,l;
+    Handle(Geom_Curve) c = BRep_Tool::Curve( fromE, f, l );
+    double u = helper.GetNodeU( fromE, node, 0, &ok );
+    c->D1( u, p, du );
+    TopAbs_Orientation o = helper.GetSubShapeOri( F.Oriented(TopAbs_FORWARD), fromE);
+    if ( o == TopAbs_REVERSED )
+      du.Reverse();
+
+    gp_Vec dir = norm ^ du;
+
+    if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX &&
+         helper.IsClosedEdge( fromE ))
+    {
+      if ( fabs(u-f) < fabs(u-l )) c->D1( l, p, dv );
+      else                         c->D1( f, p, dv );
+      if ( o == TopAbs_REVERSED )
+        dv.Reverse();
+      gp_Vec dir2 = norm ^ dv;
+      dir = dir.Normalized() + dir2.Normalized();
+    }
+    return dir.XYZ();
+  }
+  //--------------------------------------------------------------------------------
+  gp_XYZ getFaceDir( const TopoDS_Face& F, const TopoDS_Vertex& fromV,
+                     const SMDS_MeshNode* node, SMESH_MesherHelper& helper,
+                     bool& ok, double* cosin=0)
+  {
+    double f,l; TopLoc_Location loc;
+    vector< TopoDS_Edge > edges; // sharing a vertex
+    PShapeIteratorPtr eIt = helper.GetAncestors( fromV, *helper.GetMesh(), TopAbs_EDGE);
+    while ( eIt->more())
+    {
+      const TopoDS_Edge* e = static_cast<const TopoDS_Edge*>( eIt->next() );
+      if ( helper.IsSubShape( *e, F ) && !BRep_Tool::Curve( *e, loc,f,l).IsNull() )
+        edges.push_back( *e );
+    }
+    gp_XYZ dir(0,0,0);
+    if ( !( ok = ( edges.size() > 0 ))) return dir;
+    // get average dir of edges going fromV
+    gp_Vec edgeDir;
+    for ( unsigned i = 0; i < edges.size(); ++i )
+    {
+      edgeDir = getEdgeDir( edges[i], fromV );
+      double size2 = edgeDir.SquareMagnitude();
+      if ( size2 > numeric_limits<double>::min() )
+        edgeDir /= sqrt( size2 );
+      else
+        ok = false;
+      dir += edgeDir.XYZ();
+    }
+    gp_XYZ fromEdgeDir = getFaceDir( F, edges[0], node, helper, ok );
+    if ( edges.size() == 1 || dir.SquareModulus() < 1e-10)
+      dir = fromEdgeDir;
+    else if ( dir * fromEdgeDir < 0 )
+      dir *= -1;
+    if ( ok )
+    {
+      //dir /= edges.size();
+      if ( cosin ) {
+        double angle = edgeDir.Angle( dir );
+        *cosin = cos( angle );
+      }
+    }
+    return dir;
+  }
+  //================================================================================
+  /*!
+   * \brief Returns true if a FACE is bound by a concave EDGE
+   */
+  //================================================================================
+
+  bool isConcave( const TopoDS_Face& F, SMESH_MesherHelper& helper )
+  {
+    gp_Vec2d drv1, drv2;
+    gp_Pnt2d p;
+    TopExp_Explorer eExp( F.Oriented( TopAbs_FORWARD ), TopAbs_EDGE );
+    for ( ; eExp.More(); eExp.Next() )
+    {
+      const TopoDS_Edge& E = TopoDS::Edge( eExp.Current() );
+      if ( BRep_Tool::Degenerated( E )) continue;
+      // check if 2D curve is concave
+      BRepAdaptor_Curve2d curve( E, F );
+      const int nbIntervals = curve.NbIntervals( GeomAbs_C2 );
+      TColStd_Array1OfReal intervals(1, nbIntervals + 1 );
+      curve.Intervals( intervals, GeomAbs_C2 );
+      bool isConvex = true;
+      for ( int i = 1; i <= nbIntervals && isConvex; ++i )
+      {
+        double u1 = intervals( i );
+        double u2 = intervals( i+1 );
+        curve.D2( 0.5*( u1+u2 ), p, drv1, drv2 );
+        double cross = drv2 ^ drv1;
+        if ( E.Orientation() == TopAbs_REVERSED )
+          cross = -cross;
+        isConvex = ( cross < 1e-9 );
+      }
+      // check if concavity is strong enough to care about it
+      //const double maxAngle = 5 * Standard_PI180;
+      if ( !isConvex )
+      {
+        //cout << "Concave FACE " << helper.GetMeshDS()->ShapeToIndex( F ) << endl;
+        return true;
+        // map< double, const SMDS_MeshNode* > u2nodes;
+        // if ( !SMESH_Algo::GetSortedNodesOnEdge( helper.GetMeshDS(), E,
+        //                                         /*ignoreMedium=*/true, u2nodes))
+        //   continue;
+        // map< double, const SMDS_MeshNode* >::iterator u2n = u2nodes.begin();
+        // gp_Pnt2d uvPrev = helper.GetNodeUV( F, u2n->second );
+        // double    uPrev = u2n->first;
+        // for ( ++u2n; u2n != u2nodes.end(); ++u2n )
+        // {
+        //   gp_Pnt2d uv = helper.GetNodeUV( F, u2n->second );
+        //   gp_Vec2d segmentDir( uvPrev, uv );
+        //   curve.D1( uPrev, p, drv1 );
+        //   try {
+        //     if ( fabs( segmentDir.Angle( drv1 )) > maxAngle )
+        //       return true;
+        //   }
+        //   catch ( ... ) {}
+        //   uvPrev = uv;
+        //   uPrev = u2n->first;
+        // }
+      }
+    }
+    return false;
+  }
+  //--------------------------------------------------------------------------------
+  // DEBUG. Dump intermediate node positions into a python script
+#ifdef __myDEBUG
+  ofstream* py;
+  struct PyDump {
+    PyDump() {
+      const char* fname = "/tmp/viscous.py";
+      cout << "execfile('"<<fname<<"')"<<endl;
+      py = new ofstream(fname);
+      *py << "from smesh import *" << endl
+          << "meshSO = GetCurrentStudy().FindObjectID('0:1:2:3')" << endl
+          << "mesh = Mesh( meshSO.GetObject() )"<<endl;
+    }
+    void Finish() {
+      if (py)
+        *py << "mesh.MakeGroup('Viscous Prisms',VOLUME,FT_ElemGeomType,'=',Geom_PENTA)"<<endl;
+      delete py; py=0;
+    }
+    ~PyDump() { Finish(); }
+  };
+#define dumpFunction(f) { _dumpFunction(f, __LINE__);}
+#define dumpMove(n)     { _dumpMove(n, __LINE__);}
+#define dumpCmd(txt)    { _dumpCmd(txt, __LINE__);}
+  void _dumpFunction(const string& fun, int ln)
+  { if (py) *py<< "def "<<fun<<"(): # "<< ln <<endl; cout<<fun<<"()"<<endl;}
+  void _dumpMove(const SMDS_MeshNode* n, int ln)
+  { if (py) *py<< "  mesh.MoveNode( "<<n->GetID()<< ", "<< n->X()
+               << ", "<<n->Y()<<", "<< n->Z()<< ")\t\t # "<< ln <<endl; }
+  void _dumpCmd(const string& txt, int ln)
+  { if (py) *py<< "  "<<txt<<" # "<< ln <<endl; }
+  void dumpFunctionEnd()
+  { if (py) *py<< "  return"<< endl; }
+  void dumpChangeNodes( const SMDS_MeshElement* f )
+  { if (py) { *py<< "  mesh.ChangeElemNodes( " << f->GetID()<<", [";
+      for ( int i=1; i < f->NbNodes(); ++i ) *py << f->GetNode(i-1)->GetID()<<", ";
+      *py << f->GetNode( f->NbNodes()-1 )->GetID() << " ])"<< endl; }}
+#else
+  struct PyDump { void Finish() {} };
+#define dumpFunction(f) f
+#define dumpMove(n)
+#define dumpCmd(txt)
+#define dumpFunctionEnd()
+#define dumpChangeNodes(f)
+#endif
+}
+
+using namespace VISCOUS;
+
+//================================================================================
+/*!
+ * \brief Constructor of _ViscousBuilder
+ */
+//================================================================================
+
+_ViscousBuilder::_ViscousBuilder()
+{
+  _error = SMESH_ComputeError::New(COMPERR_OK);
+  _tmpFaceID = 0;
+}
+
+//================================================================================
+/*!
+ * \brief Stores error description and returns false
+ */
+//================================================================================
+
+bool _ViscousBuilder::error(const string& text, int solidId )
+{
+  _error->myName    = COMPERR_ALGO_FAILED;
+  _error->myComment = string("Viscous layers builder: ") + text;
+  if ( _mesh )
+  {
+    SMESH_subMesh* sm = _mesh->GetSubMeshContaining( solidId );
+    if ( !sm && !_sdVec.empty() )
+      sm = _mesh->GetSubMeshContaining( _sdVec[0]._index );
+    if ( sm && sm->GetSubShape().ShapeType() == TopAbs_SOLID )
+    {
+      SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+      if ( smError && smError->myAlgo )
+        _error->myAlgo = smError->myAlgo;
+      smError = _error;
+    }
+  }
+  makeGroupOfLE(); // debug
+
+  return false;
+}
+
+//================================================================================
+/*!
+ * \brief At study restoration, restore event listeners used to clear an inferior
+ *  dim sub-mesh modified by viscous layers
+ */
+//================================================================================
+
+void _ViscousBuilder::RestoreListeners()
+{
+  // TODO
+}
+
+//================================================================================
+/*!
+ * \brief computes SMESH_ProxyMesh::SubMesh::_n2n
+ */
+//================================================================================
+
+bool _ViscousBuilder::MakeN2NMap( _MeshOfSolid* pm )
+{
+  SMESH_subMesh* solidSM = pm->mySubMeshes.front();
+  TopExp_Explorer fExp( solidSM->GetSubShape(), TopAbs_FACE );
+  for ( ; fExp.More(); fExp.Next() )
+  {
+    SMESHDS_SubMesh* srcSmDS = pm->GetMeshDS()->MeshElements( fExp.Current() );
+    const SMESH_ProxyMesh::SubMesh* prxSmDS = pm->GetProxySubMesh( fExp.Current() );
+
+    if ( !srcSmDS || !prxSmDS || !srcSmDS->NbElements() || !prxSmDS->NbElements() )
+      continue;
+    if ( srcSmDS->GetElements()->next() == prxSmDS->GetElements()->next())
+      continue;
+
+    if ( srcSmDS->NbElements() != prxSmDS->NbElements() )
+      return error( "Different nb elements in a source and a proxy sub-mesh", solidSM->GetId());
+
+    SMDS_ElemIteratorPtr srcIt = srcSmDS->GetElements();
+    SMDS_ElemIteratorPtr prxIt = prxSmDS->GetElements();
+    while( prxIt->more() )
+    {
+      const SMDS_MeshElement* fSrc = srcIt->next();
+      const SMDS_MeshElement* fPrx = prxIt->next();
+      if ( fSrc->NbNodes() != fPrx->NbNodes())
+        return error( "Different elements in a source and a proxy sub-mesh", solidSM->GetId());
+      for ( int i = 0 ; i < fPrx->NbNodes(); ++i )
+        pm->setNode2Node( fSrc->GetNode(i), fPrx->GetNode(i), prxSmDS );
+    }
+  }
+  pm->_n2nMapComputed = true;
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Does its job
+ */
+//================================================================================
+
+SMESH_ComputeErrorPtr _ViscousBuilder::Compute(SMESH_Mesh&         theMesh,
+                                               const TopoDS_Shape& theShape)
+{
+  // TODO: set priority of solids during Gen::Compute()
+
+  _mesh = & theMesh;
+
+  // check if proxy mesh already computed
+  TopExp_Explorer exp( theShape, TopAbs_SOLID );
+  if ( !exp.More() )
+    return error("No SOLID's in theShape"), _error;
+
+  if ( _ViscousListener::GetSolidMesh( _mesh, exp.Current(), /*toCreate=*/false))
+    return SMESH_ComputeErrorPtr(); // everything already computed
+
+  PyDump debugDump;
+
+  // TODO: ignore already computed SOLIDs 
+  if ( !findSolidsWithLayers())
+    return _error;
+
+  if ( !findFacesWithLayers() )
+    return _error;
+
+  for ( unsigned i = 0; i < _sdVec.size(); ++i )
+  {
+    if ( ! makeLayer(_sdVec[i]) )
+      return _error;
+    
+    if ( ! inflate(_sdVec[i]) )
+      return _error;
+
+    if ( ! refine(_sdVec[i]) )
+      return _error;
+  }
+  if ( !shrink() )
+    return _error;
+
+  addBoundaryElements();
+
+  makeGroupOfLE(); // debug
+  debugDump.Finish();
+
+  return _error;
+}
+
+//================================================================================
+/*!
+ * \brief Finds SOLIDs to compute using viscous layers. Fills _sdVec
+ */
+//================================================================================
+
+bool _ViscousBuilder::findSolidsWithLayers()
+{
+  // get all solids
+  TopTools_IndexedMapOfShape allSolids;
+  TopExp::MapShapes( _mesh->GetShapeToMesh(), TopAbs_SOLID, allSolids );
+  _sdVec.reserve( allSolids.Extent());
+
+  SMESH_Gen* gen = _mesh->GetGen();
+  for ( int i = 1; i <= allSolids.Extent(); ++i )
+  {
+    // find StdMeshers_ViscousLayers hyp assigned to the i-th solid
+    SMESH_Algo* algo = gen->GetAlgo( *_mesh, allSolids(i) );
+    if ( !algo ) continue;
+    // TODO: check if algo is hidden
+    const list <const SMESHDS_Hypothesis *> & allHyps =
+      algo->GetUsedHypothesis(*_mesh, allSolids(i), /*ignoreAuxiliary=*/false);
+    list< const SMESHDS_Hypothesis *>::const_iterator hyp = allHyps.begin();
+    const StdMeshers_ViscousLayers* viscHyp = 0;
+    for ( ; hyp != allHyps.end() && !viscHyp; ++hyp )
+      viscHyp = dynamic_cast<const StdMeshers_ViscousLayers*>( *hyp );
+    if ( viscHyp )
+    {
+      _MeshOfSolid* proxyMesh = _ViscousListener::GetSolidMesh( _mesh,
+                                                                allSolids(i),
+                                                                /*toCreate=*/true);
+      _sdVec.push_back( _SolidData( allSolids(i), viscHyp, proxyMesh ));
+      _sdVec.back()._index = getMeshDS()->ShapeToIndex( allSolids(i));
+    }
+  }
+  if ( _sdVec.empty() )
+    return error
+      ( SMESH_Comment(StdMeshers_ViscousLayers::GetHypType()) << " hypothesis not found",0);
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief 
+ */
+//================================================================================
+
+bool _ViscousBuilder::findFacesWithLayers()
+{
+  // collect all faces to ignore defined by hyp
+  vector<TopoDS_Shape> ignoreFaces;
+  for ( unsigned i = 0; i < _sdVec.size(); ++i )
+  {
+    vector<TGeomID> ids = _sdVec[i]._hyp->GetIgnoreFaces();
+    for ( unsigned i = 0; i < ids.size(); ++i )
+    {
+      const TopoDS_Shape& s = getMeshDS()->IndexToShape( ids[i] );
+      if ( !s.IsNull() && s.ShapeType() == TopAbs_FACE )
+      {
+        _ignoreShapeIds.insert( ids[i] );
+        ignoreFaces.push_back( s );
+      }
+    }
+  }
+
+  // ignore internal faces
+  SMESH_MesherHelper helper( *_mesh );
+  TopExp_Explorer exp;
+  for ( unsigned i = 0; i < _sdVec.size(); ++i )
+  {
+    exp.Init( _sdVec[i]._solid.Oriented( TopAbs_FORWARD ), TopAbs_FACE );
+    for ( ; exp.More(); exp.Next() )
+    {
+      TGeomID faceInd = getMeshDS()->ShapeToIndex( exp.Current() );
+      if ( helper.NbAncestors( exp.Current(), *_mesh, TopAbs_SOLID ) > 1 )
+      {     
+        _ignoreShapeIds.insert( faceInd );
+        ignoreFaces.push_back( exp.Current() );
+        if ( SMESH_Algo::IsReversedSubMesh( TopoDS::Face( exp.Current() ), getMeshDS()))
+          _sdVec[i]._reversedFaceIds.insert( faceInd );
+      }
+    }
+  }
+
+  // Find faces to shrink mesh on (solution 2 in issue 0020832);
+  TopTools_IndexedMapOfShape shapes;
+  for ( unsigned i = 0; i < _sdVec.size(); ++i )
+  {
+    shapes.Clear();
+    TopExp::MapShapes(_sdVec[i]._solid, TopAbs_EDGE, shapes);
+    for ( int iE = 1; iE <= shapes.Extent(); ++iE )
+    {
+      const TopoDS_Shape& edge = shapes(iE);
+      // find 2 faces sharing an edge
+      TopoDS_Shape FF[2];
+      PShapeIteratorPtr fIt = helper.GetAncestors(edge, *_mesh, TopAbs_FACE);
+      while ( fIt->more())
+      {
+        const TopoDS_Shape* f = fIt->next();
+        if ( helper.IsSubShape( *f, _sdVec[i]._solid))
+          FF[ int( !FF[0].IsNull()) ] = *f;
+      }
+      if( FF[1].IsNull() ) continue; // seam edge can be shared by 1 FACE only
+      // check presence of layers on them
+      int ignore[2];
+      for ( int j = 0; j < 2; ++j )
+        ignore[j] = _ignoreShapeIds.count ( getMeshDS()->ShapeToIndex( FF[j] ));
+      if ( ignore[0] == ignore[1] ) continue; // nothing interesting
+      TopoDS_Shape fWOL = FF[ ignore[0] ? 0 : 1 ];
+      // add edge to maps
+      TGeomID edgeInd = getMeshDS()->ShapeToIndex( edge );
+      _sdVec[i]._shrinkShape2Shape.insert( make_pair( edgeInd, fWOL ));
+    }
+  }
+  // Exclude from _shrinkShape2Shape FACE's that can't be shrinked since
+  // the algo of the SOLID sharing the FACE does not support it
+  set< string > notSupportAlgos; notSupportAlgos.insert("Hexa_3D");
+  for ( unsigned i = 0; i < _sdVec.size(); ++i )
+  {
+    TopTools_MapOfShape noShrinkVertices;
+    map< TGeomID, TopoDS_Shape >::iterator e2f = _sdVec[i]._shrinkShape2Shape.begin();
+    for ( ; e2f != _sdVec[i]._shrinkShape2Shape.end(); ++e2f )
+    {
+      const TopoDS_Shape& fWOL = e2f->second;
+      TGeomID           edgeID = e2f->first;
+      bool notShrinkFace = false;
+      PShapeIteratorPtr soIt = helper.GetAncestors(fWOL, *_mesh, TopAbs_SOLID);
+      while ( soIt->more())
+      {
+        const TopoDS_Shape* solid = soIt->next();
+        if ( _sdVec[i]._solid.IsSame( *solid )) continue;
+        SMESH_Algo* algo = _mesh->GetGen()->GetAlgo( *_mesh, *solid );
+        if ( !algo || !notSupportAlgos.count( algo->GetName() )) continue;
+        notShrinkFace = true;
+        for ( unsigned j = 0; j < _sdVec.size(); ++j )
+        {
+          if ( _sdVec[j]._solid.IsSame( *solid ) )
+            if ( _sdVec[j]._shrinkShape2Shape.count( edgeID ))
+              notShrinkFace = false;
+        }
+      }
+      if ( notShrinkFace )
+      {
+        _sdVec[i]._noShrinkFaces.insert( getMeshDS()->ShapeToIndex( fWOL ));
+        for ( TopExp_Explorer vExp( fWOL, TopAbs_VERTEX ); vExp.More(); vExp.Next() )
+          noShrinkVertices.Add( vExp.Current() );
+      }
+    }
+    // erase from _shrinkShape2Shape all srink EDGE's of a SOLID connected
+    // to the found not shrinked fWOL's
+    e2f = _sdVec[i]._shrinkShape2Shape.begin();
+    for ( ; e2f != _sdVec[i]._shrinkShape2Shape.end(); )
+    {
+      TGeomID edgeID = e2f->first;
+      TopoDS_Vertex VV[2];
+      TopExp::Vertices( TopoDS::Edge( getMeshDS()->IndexToShape( edgeID )),VV[0],VV[1]);
+      if ( noShrinkVertices.Contains( VV[0] ) || noShrinkVertices.Contains( VV[1] ))
+      {
+        _sdVec[i]._noShrinkFaces.insert( getMeshDS()->ShapeToIndex( e2f->second ));
+        _sdVec[i]._shrinkShape2Shape.erase( e2f++ );
+      }
+      else
+      {
+        e2f++;
+      }
+    }
+  }
+      
+  // Find the SHAPE along which to inflate _LayerEdge based on VERTEX
+
+  for ( unsigned i = 0; i < _sdVec.size(); ++i )
+  {
+    shapes.Clear();
+    TopExp::MapShapes(_sdVec[i]._solid, TopAbs_VERTEX, shapes);
+    for ( int iV = 1; iV <= shapes.Extent(); ++iV )
+    {
+      const TopoDS_Shape& vertex = shapes(iV);
+      // find faces WOL sharing the vertex
+      vector< TopoDS_Shape > facesWOL;
+      int totalNbFaces = 0;
+      PShapeIteratorPtr fIt = helper.GetAncestors(vertex, *_mesh, TopAbs_FACE);
+      while ( fIt->more())
+      {
+        const TopoDS_Shape* f = fIt->next();
+        const int         fID = getMeshDS()->ShapeToIndex( *f );
+        if ( helper.IsSubShape( *f, _sdVec[i]._solid ) )
+        {
+          totalNbFaces++;
+          if ( _ignoreShapeIds.count ( fID ) && ! _sdVec[i]._noShrinkFaces.count( fID ))
+            facesWOL.push_back( *f );
+        }
+      }
+      if ( facesWOL.size() == totalNbFaces || facesWOL.empty() )
+        continue; // no layers at this vertex or no WOL
+      TGeomID vInd = getMeshDS()->ShapeToIndex( vertex );
+      switch ( facesWOL.size() )
+      {
+      case 1:
+        {
+          helper.SetSubShape( facesWOL[0] );
+          if ( helper.IsRealSeam( vInd )) // inflate along a seam edge?
+          {
+            TopoDS_Shape seamEdge;
+            PShapeIteratorPtr eIt = helper.GetAncestors(vertex, *_mesh, TopAbs_EDGE);
+            while ( eIt->more() && seamEdge.IsNull() )
+            {
+              const TopoDS_Shape* e = eIt->next();
+              if ( helper.IsRealSeam( *e ) )
+                seamEdge = *e;
+            }
+            if ( !seamEdge.IsNull() )
+            {
+              _sdVec[i]._shrinkShape2Shape.insert( make_pair( vInd, seamEdge ));
+              break;
+            }
+          }
+          _sdVec[i]._shrinkShape2Shape.insert( make_pair( vInd, facesWOL[0] ));
+          break;
+        }
+      case 2:
+        {
+          // find an edge shared by 2 faces
+          PShapeIteratorPtr eIt = helper.GetAncestors(vertex, *_mesh, TopAbs_EDGE);
+          while ( eIt->more())
+          {
+            const TopoDS_Shape* e = eIt->next();
+            if ( helper.IsSubShape( *e, facesWOL[0]) &&
+                 helper.IsSubShape( *e, facesWOL[1]))
+            {
+              _sdVec[i]._shrinkShape2Shape.insert( make_pair( vInd, *e )); break;
+            }
+          }
+          break;
+        }
+      default:
+        return error("Not yet supported case", _sdVec[i]._index);
+      }
+    }
+  }
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Create the inner surface of the viscous layer and prepare data for infation
+ */
+//================================================================================
+
+bool _ViscousBuilder::makeLayer(_SolidData& data)
+{
+  // get all sub-shapes to make layers on
+  set<TGeomID> subIds, faceIds;
+  subIds = data._noShrinkFaces;
+  TopExp_Explorer exp( data._solid, TopAbs_FACE );
+  for ( ; exp.More(); exp.Next() )
+    if ( ! _ignoreShapeIds.count( getMeshDS()->ShapeToIndex( exp.Current() )))
+    {
+      SMESH_subMesh* fSubM = _mesh->GetSubMesh( exp.Current() );
+      faceIds.insert( fSubM->GetId() );
+      SMESH_subMeshIteratorPtr subIt =
+        fSubM->getDependsOnIterator(/*includeSelf=*/true, /*complexShapeFirst=*/false);
+      while ( subIt->more() )
+        subIds.insert( subIt->next()->GetId() );
+    }
+
+  // make a map to find new nodes on sub-shapes shared with other SOLID
+  map< TGeomID, TNode2Edge* > s2neMap;
+  map< TGeomID, TNode2Edge* >::iterator s2ne;
+  map< TGeomID, TopoDS_Shape >::iterator s2s = data._shrinkShape2Shape.begin();
+  for (; s2s != data._shrinkShape2Shape.end(); ++s2s )
+  {
+    TGeomID shapeInd = s2s->first;
+    for ( unsigned i = 0; i < _sdVec.size(); ++i )
+    {
+      if ( _sdVec[i]._index == data._index ) continue;
+      map< TGeomID, TopoDS_Shape >::iterator s2s2 = _sdVec[i]._shrinkShape2Shape.find( shapeInd );
+      if ( s2s2 != _sdVec[i]._shrinkShape2Shape.end() &&
+           *s2s == *s2s2 && !_sdVec[i]._n2eMap.empty() )
+      {
+        s2neMap.insert( make_pair( shapeInd, &_sdVec[i]._n2eMap ));
+        break;
+      }
+    }
+  }
+
+  // Create temporary faces and _LayerEdge's
+
+  dumpFunction(SMESH_Comment("makeLayers_")<<data._index); 
+
+  data._stepSize = Precision::Infinite();
+  data._stepSizeNodes[0] = 0;
+
+  SMESH_MesherHelper helper( *_mesh );
+  helper.SetSubShape( data._solid );
+  helper.SetElementsOnShape(true);
+
+  vector< const SMDS_MeshNode*> newNodes; // of a mesh face
+  TNode2Edge::iterator n2e2;
+
+  // collect _LayerEdge's of shapes they are based on
+  const int nbShapes = getMeshDS()->MaxShapeIndex();
+  vector< vector<_LayerEdge*> > edgesByGeom( nbShapes+1 );
+
+  for ( set<TGeomID>::iterator id = faceIds.begin(); id != faceIds.end(); ++id )
+  {
+    SMESHDS_SubMesh* smDS = getMeshDS()->MeshElements( *id );
+    if ( !smDS ) return error(SMESH_Comment("Not meshed face ") << *id, data._index );
+
+    const TopoDS_Face& F = TopoDS::Face( getMeshDS()->IndexToShape( *id ));
+    SMESH_ProxyMesh::SubMesh* proxySub =
+      data._proxyMesh->getFaceSubM( F, /*create=*/true);
+
+    SMDS_ElemIteratorPtr eIt = smDS->GetElements();
+    while ( eIt->more() )
+    {
+      const SMDS_MeshElement* face = eIt->next();
+      newNodes.resize( face->NbCornerNodes() );
+      double faceMaxCosin = -1;
+      for ( int i = 0 ; i < face->NbCornerNodes(); ++i )
+      {
+        const SMDS_MeshNode* n = face->GetNode(i);
+        TNode2Edge::iterator n2e = data._n2eMap.insert( make_pair( n, (_LayerEdge*)0 )).first;
+        if ( !(*n2e).second )
+        {
+          // add a _LayerEdge
+          _LayerEdge* edge = new _LayerEdge();
+          n2e->second = edge;
+          edge->_nodes.push_back( n );
+          const int shapeID = n->getshapeId();
+          edgesByGeom[ shapeID ].push_back( edge );
+
+          // set edge data or find already refined _LayerEdge and get data from it
+          if ( n->GetPosition()->GetTypeOfPosition() != SMDS_TOP_FACE &&
+               ( s2ne = s2neMap.find( shapeID )) != s2neMap.end() &&
+               ( n2e2 = (*s2ne).second->find( n )) != s2ne->second->end())
+          {
+            _LayerEdge* foundEdge = (*n2e2).second;
+            edge->Copy( *foundEdge, helper );
+            // location of the last node is modified but we can restore
+            // it by node position on _sWOL stored by the node
+            const_cast< SMDS_MeshNode* >
+              ( edge->_nodes.back() )->setXYZ( n->X(), n->Y(), n->Z() );
+          }
+          else
+          {
+            edge->_nodes.push_back( helper.AddNode( n->X(), n->Y(), n->Z() ));
+            if ( !setEdgeData( *edge, subIds, helper, data ))
+              return false;
+          }
+          dumpMove(edge->_nodes.back());
+          if ( edge->_cosin > 0.01 )
+          {
+            if ( edge->_cosin > faceMaxCosin )
+              faceMaxCosin = edge->_cosin;
+          }
+        }
+        newNodes[ i ] = n2e->second->_nodes.back();
+      }
+      // create a temporary face
+      const SMDS_MeshElement* newFace = new TmpMeshFace( newNodes, --_tmpFaceID );
+      proxySub->AddElement( newFace );
+
+      // compute inflation step size by min size of element on a convex surface
+      if ( faceMaxCosin > 0.1 )
+        limitStepSize( data, face, faceMaxCosin );
+    } // loop on 2D elements on a FACE
+  } // loop on FACEs of a SOLID
+
+  data._epsilon = 1e-7;
+  if ( data._stepSize < 1. )
+    data._epsilon *= data._stepSize;
+
+  // Put _LayerEdge's into a vector
+
+  if ( !sortEdges( data, edgesByGeom ))
+    return false;
+
+  // Set target nodes into _Simplex and _2NearEdges
+  TNode2Edge::iterator n2e;
+  for ( unsigned i = 0; i < data._edges.size(); ++i )
+  {
+    if ( data._edges[i]->IsOnEdge())
+      for ( int j = 0; j < 2; ++j )
+      {
+        if ( data._edges[i]->_nodes.back()->NbInverseElements(SMDSAbs_Volume) > 0 )
+          break; // _LayerEdge is shared by two _SolidData's
+        const SMDS_MeshNode* & n = data._edges[i]->_2neibors->_nodes[j];
+        if (( n2e = data._n2eMap.find( n )) == data._n2eMap.end() )
+          return error("_LayerEdge not found by src node", data._index);
+        n = (*n2e).second->_nodes.back();
+        data._edges[i]->_2neibors->_edges[j] = n2e->second;
+      }
+    else
+      for ( unsigned j = 0; j < data._edges[i]->_simplices.size(); ++j )
+      {
+        _Simplex& s = data._edges[i]->_simplices[j];
+        s._nNext = data._n2eMap[ s._nNext ]->_nodes.back();
+        s._nPrev = data._n2eMap[ s._nPrev ]->_nodes.back();
+      }
+  }
+
+  dumpFunctionEnd();
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Compute inflation step size by min size of element on a convex surface
+ */
+//================================================================================
+
+void _ViscousBuilder::limitStepSize( _SolidData&             data,
+                                     const SMDS_MeshElement* face,
+                                     const double            cosin)
+{
+  int iN = 0;
+  double minSize = 10 * data._stepSize;
+  const int nbNodes = face->NbCornerNodes();
+  for ( int i = 0; i < nbNodes; ++i )
+  {
+    const SMDS_MeshNode* nextN = face->GetNode( SMESH_MesherHelper::WrapIndex( i+1, nbNodes ));
+    const SMDS_MeshNode* curN = face->GetNode( i );
+    if ( nextN->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ||
+         curN->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE )
+    {
+      double dist = SMESH_TNodeXYZ( face->GetNode(i)).Distance( nextN );
+      if ( dist < minSize )
+        minSize = dist, iN = i;
+    }
+  }
+  double newStep = 0.8 * minSize / cosin;
+  if ( newStep < data._stepSize )
+  {
+    data._stepSize = newStep;
+    data._stepSizeCoeff = 0.8 / cosin;
+    data._stepSizeNodes[0] = face->GetNode( iN );
+    data._stepSizeNodes[1] = face->GetNode( SMESH_MesherHelper::WrapIndex( iN+1, nbNodes ));
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Compute inflation step size by min size of element on a convex surface
+ */
+//================================================================================
+
+void _ViscousBuilder::limitStepSize( _SolidData& data, const double minSize)
+{
+  if ( minSize < data._stepSize )
+  {
+    data._stepSize = minSize;
+    if ( data._stepSizeNodes[0] )
+    {
+      double dist =
+        SMESH_TNodeXYZ(data._stepSizeNodes[0]).Distance(data._stepSizeNodes[1]);
+      data._stepSizeCoeff = data._stepSize / dist;
+    }
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Separate shapes (and _LayerEdge's on them) to smooth from the rest ones
+ */
+//================================================================================
+
+bool _ViscousBuilder::sortEdges( _SolidData&                    data,
+                                 vector< vector<_LayerEdge*> >& edgesByGeom)
+{
+  // Find shapes needing smoothing; such a shape has _LayerEdge._normal on it's
+  // boundry inclined at a sharp angle to the shape
+
+  list< TGeomID > shapesToSmooth;
+  
+  SMESH_MesherHelper helper( *_mesh );
+  bool ok = true;
+
+  for ( unsigned iS = 0; iS < edgesByGeom.size(); ++iS )
+  {
+    vector<_LayerEdge*>& eS = edgesByGeom[iS];
+    if ( eS.empty() ) continue;
+    TopoDS_Shape S = getMeshDS()->IndexToShape( iS );
+    bool needSmooth = false;
+    switch ( S.ShapeType() )
+    {
+    case TopAbs_EDGE: {
+
+      bool isShrinkEdge = !eS[0]->_sWOL.IsNull();
+      for ( TopoDS_Iterator vIt( S ); vIt.More() && !needSmooth; vIt.Next() )
+      {
+        TGeomID iV = getMeshDS()->ShapeToIndex( vIt.Value() );
+        vector<_LayerEdge*>& eV = edgesByGeom[ iV ];
+        if ( eV.empty() ) continue;
+        double cosin = eV[0]->_cosin;
+        bool badCosin =
+          ( !eV[0]->_sWOL.IsNull() && ( eV[0]->_sWOL.ShapeType() == TopAbs_EDGE || !isShrinkEdge));
+        if ( badCosin )
+        {
+          gp_Vec dir1, dir2;
+          if ( eV[0]->_sWOL.ShapeType() == TopAbs_EDGE )
+            dir1 = getEdgeDir( TopoDS::Edge( eV[0]->_sWOL ), TopoDS::Vertex( vIt.Value() ));
+          else
+            dir1 = getFaceDir( TopoDS::Face( eV[0]->_sWOL ), TopoDS::Vertex( vIt.Value() ),
+                               eV[0]->_nodes[0], helper, ok);
+          dir2 = getEdgeDir( TopoDS::Edge( S ), TopoDS::Vertex( vIt.Value() ));
+          double angle = dir1.Angle( dir2 );
+          cosin = cos( angle );
+        }
+        needSmooth = ( cosin > 0.1 );
+      }
+      break;
+    }
+    case TopAbs_FACE: {
+
+      for ( TopExp_Explorer eExp( S, TopAbs_EDGE ); eExp.More() && !needSmooth; eExp.Next() )
+      {
+        TGeomID iE = getMeshDS()->ShapeToIndex( eExp.Current() );
+        vector<_LayerEdge*>& eE = edgesByGeom[ iE ];
+        if ( eE.empty() ) continue;
+        if ( eE[0]->_sWOL.IsNull() )
+        {
+          for ( unsigned i = 0; i < eE.size() && !needSmooth; ++i )
+            needSmooth = ( eE[i]->_cosin > 0.1 );
+        }
+        else
+        {
+          const TopoDS_Face& F1 = TopoDS::Face( S );
+          const TopoDS_Face& F2 = TopoDS::Face( eE[0]->_sWOL );
+          const TopoDS_Edge& E  = TopoDS::Edge( eExp.Current() );
+          for ( unsigned i = 0; i < eE.size() && !needSmooth; ++i )
+          {
+            gp_Vec dir1 = getFaceDir( F1, E, eE[i]->_nodes[0], helper, ok );
+            gp_Vec dir2 = getFaceDir( F2, E, eE[i]->_nodes[0], helper, ok );
+            double angle = dir1.Angle( dir2 );
+            double cosin = cos( angle );
+            needSmooth = ( cosin > 0.1 );
+          }
+        }
+      }
+      break;
+    }
+    case TopAbs_VERTEX:
+      continue;
+    default:;
+    }
+    if ( needSmooth )
+    {
+      if ( S.ShapeType() == TopAbs_EDGE ) shapesToSmooth.push_front( iS );
+      else                                shapesToSmooth.push_back ( iS );
+    }
+
+  } // loop on edgesByGeom
+
+  data._edges.reserve( data._n2eMap.size() );
+  data._endEdgeToSmooth.clear();
+
+  // first we put _LayerEdge's on shapes to smooth
+  list< TGeomID >::iterator gIt = shapesToSmooth.begin();
+  for ( ; gIt != shapesToSmooth.end(); ++gIt )
+  {
+    vector<_LayerEdge*>& eVec = edgesByGeom[ *gIt ];
+    if ( eVec.empty() ) continue;
+    data._edges.insert( data._edges.end(), eVec.begin(), eVec.end() );
+    data._endEdgeToSmooth.push_back( data._edges.size() );
+    eVec.clear();
+  }
+
+  // then the rest _LayerEdge's
+  for ( unsigned iS = 0; iS < edgesByGeom.size(); ++iS )
+  {
+    vector<_LayerEdge*>& eVec = edgesByGeom[iS];
+    data._edges.insert( data._edges.end(), eVec.begin(), eVec.end() );
+    eVec.clear();
+  }
+
+  return ok;
+}
+
+//================================================================================
+/*!
+ * \brief Set data of _LayerEdge needed for smoothing
+ *  \param subIds - ids of sub-shapes of a SOLID to take into account faces from
+ */
+//================================================================================
+
+bool _ViscousBuilder::setEdgeData(_LayerEdge&         edge,
+                                  const set<TGeomID>& subIds,
+                                  SMESH_MesherHelper& helper,
+                                  _SolidData&         data)
+{
+  SMESH_MeshEditor editor(_mesh);
+
+  const SMDS_MeshNode* node = edge._nodes[0]; // source node
+  SMDS_TypeOfPosition posType = node->GetPosition()->GetTypeOfPosition();
+
+  edge._len = 0;
+  edge._2neibors = 0;
+  edge._curvature = 0;
+
+  // --------------------------
+  // Compute _normal and _cosin
+  // --------------------------
+
+  edge._cosin = 0;
+  edge._normal.SetCoord(0,0,0);
+
+  int totalNbFaces = 0;
+  gp_Pnt p;
+  gp_Vec du, dv, geomNorm;
+  bool normOK = true;
+
+  TGeomID shapeInd = node->getshapeId();
+  map< TGeomID, TopoDS_Shape >::const_iterator s2s = data._shrinkShape2Shape.find( shapeInd );
+  bool onShrinkShape ( s2s != data._shrinkShape2Shape.end() );
+  TopoDS_Shape vertEdge;
+
+  if ( onShrinkShape ) // one of faces the node is on has no layers
+  {
+    vertEdge = getMeshDS()->IndexToShape( s2s->first ); // vertex or edge
+    if ( s2s->second.ShapeType() == TopAbs_EDGE )
+    {
+      // inflate from VERTEX along EDGE
+      edge._normal = getEdgeDir( TopoDS::Edge( s2s->second ), TopoDS::Vertex( vertEdge ));
+    }
+    else if ( vertEdge.ShapeType() == TopAbs_VERTEX )
+    {
+      // inflate from VERTEX along FACE
+      edge._normal = getFaceDir( TopoDS::Face( s2s->second ), TopoDS::Vertex( vertEdge ),
+                                 node, helper, normOK, &edge._cosin);
+    }
+    else
+    {
+      // inflate from EDGE along FACE
+      edge._normal = getFaceDir( TopoDS::Face( s2s->second ), TopoDS::Edge( vertEdge ),
+                                 node, helper, normOK);
+    }
+  }
+  else // layers are on all faces of SOLID the node is on
+  {
+    // find indices of geom faces the node lies on
+    set<TGeomID> faceIds;
+    if  ( posType == SMDS_TOP_FACE )
+    {
+      faceIds.insert( node->getshapeId() );
+    }
+    else
+    {
+      SMDS_ElemIteratorPtr fIt = node->GetInverseElementIterator(SMDSAbs_Face);
+      while ( fIt->more() )
+        faceIds.insert( editor.FindShape(fIt->next()));
+    }
+
+    set<TGeomID>::iterator id = faceIds.begin();
+    TopoDS_Face F;
+    for ( ; id != faceIds.end(); ++id )
+    {
+      const TopoDS_Shape& s = getMeshDS()->IndexToShape( *id );
+      if ( s.IsNull() || s.ShapeType() != TopAbs_FACE || !subIds.count( *id ))
+        continue;
+      totalNbFaces++;
+      //nbLayerFaces += subIds.count( *id );
+      F = TopoDS::Face( s );
+
+      gp_XY uv = helper.GetNodeUV( F, node, 0, &normOK );
+      Handle(Geom_Surface) surface = BRep_Tool::Surface( F );
+      surface->D1( uv.X(),uv.Y(), p, du,dv );
+      geomNorm = du ^ dv;
+      double size2 = geomNorm.SquareMagnitude();
+      if ( size2 > numeric_limits<double>::min() )
+        geomNorm /= sqrt( size2 );
+      else
+        normOK = false;
+      if ( helper.GetSubShapeOri( data._solid, F ) != TopAbs_REVERSED )
+        geomNorm.Reverse();
+      edge._normal += geomNorm.XYZ();
+    }
+    if ( totalNbFaces == 0 )
+      return error(SMESH_Comment("Can't get normal to node ") << node->GetID(), data._index);
+
+    edge._normal /= totalNbFaces;
+
+    switch ( posType )
+    {
+    case SMDS_TOP_FACE:
+      edge._cosin = 0; break;
+
+    case SMDS_TOP_EDGE: {
+      TopoDS_Edge E = TopoDS::Edge( helper.GetSubShapeByNode( node, getMeshDS()));
+      gp_Vec inFaceDir = getFaceDir( F, E, node, helper, normOK);
+      double angle = inFaceDir.Angle( edge._normal ); // [0,PI]
+      edge._cosin = cos( angle );
+      //cout << "Cosin on EDGE " << edge._cosin << " node " << node->GetID() << endl;
+      break;
+    }
+    case SMDS_TOP_VERTEX: {
+      TopoDS_Vertex V = TopoDS::Vertex( helper.GetSubShapeByNode( node, getMeshDS()));
+      gp_Vec inFaceDir = getFaceDir( F, V, node, helper, normOK);
+      double angle = inFaceDir.Angle( edge._normal ); // [0,PI]
+      edge._cosin = cos( angle );
+      //cout << "Cosin on VERTEX " << edge._cosin << " node " << node->GetID() << endl;
+      break;
+    }
+    default:
+      return error(SMESH_Comment("Invalid shape position of node ")<<node, data._index);
+    }
+  }
+
+  double normSize = edge._normal.SquareModulus();
+  if ( normSize < numeric_limits<double>::min() )
+    return error(SMESH_Comment("Bad normal at node ")<< node->GetID(), data._index );
+
+  edge._normal /= sqrt( normSize );
+
+  // TODO: if ( !normOK ) then get normal by mesh faces
+
+  // Set the rest data
+  // --------------------
+  if ( onShrinkShape )
+  {
+    edge._sWOL = (*s2s).second;
+
+    SMDS_MeshNode* tgtNode = const_cast<SMDS_MeshNode*>( edge._nodes.back() );
+    if ( SMESHDS_SubMesh* sm = getMeshDS()->MeshElements( data._solid ))
+      sm->RemoveNode( tgtNode , /*isNodeDeleted=*/false );
+
+    // set initial position which is parameters on _sWOL in this case
+    if ( edge._sWOL.ShapeType() == TopAbs_EDGE )
+    {
+      double u = helper.GetNodeU( TopoDS::Edge( edge._sWOL ), node, 0, &normOK );
+      edge._pos.push_back( gp_XYZ( u, 0, 0));
+      getMeshDS()->SetNodeOnEdge( tgtNode, TopoDS::Edge( edge._sWOL ), u );
+    }
+    else // TopAbs_FACE
+    {
+      gp_XY uv = helper.GetNodeUV( TopoDS::Face( edge._sWOL ), node, 0, &normOK );
+      edge._pos.push_back( gp_XYZ( uv.X(), uv.Y(), 0));
+      getMeshDS()->SetNodeOnFace( tgtNode, TopoDS::Face( edge._sWOL ), uv.X(), uv.Y() );
+    }
+  }
+  else
+  {
+    edge._pos.push_back( SMESH_TNodeXYZ( node ));
+
+    if ( posType == SMDS_TOP_FACE )
+    {
+      getSimplices( node, edge._simplices, _ignoreShapeIds, &data );
+      double avgNormProj = 0, avgLen = 0;
+      for ( unsigned i = 0; i < edge._simplices.size(); ++i )
+      {
+        gp_XYZ vec = edge._pos.back() - SMESH_TNodeXYZ( edge._simplices[i]._nPrev );
+        avgNormProj += edge._normal * vec;
+        avgLen += vec.Modulus();
+      }
+      avgNormProj /= edge._simplices.size();
+      avgLen /= edge._simplices.size();
+      edge._curvature = _Curvature::New( avgNormProj, avgLen );
+    }
+  }
+
+  // Set neighbour nodes for a _LayerEdge based on EDGE
+
+  if ( posType == SMDS_TOP_EDGE /*||
+       ( onShrinkShape && posType == SMDS_TOP_VERTEX && fabs( edge._cosin ) < 1e-10 )*/)
+  {
+    edge._2neibors = new _2NearEdges;
+    // target node instead of source ones will be set later
+    if ( ! findNeiborsOnEdge( &edge,
+                              edge._2neibors->_nodes[0],
+                              edge._2neibors->_nodes[1],
+                              data))
+      return false;
+    edge.SetDataByNeighbors( edge._2neibors->_nodes[0],
+                             edge._2neibors->_nodes[1],
+                             helper);
+  }
+
+  edge.SetCosin( edge._cosin ); // to update edge._lenFactor
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Find 2 neigbor nodes of a node on EDGE
+ */
+//================================================================================
+
+bool _ViscousBuilder::findNeiborsOnEdge(const _LayerEdge*     edge,
+                                        const SMDS_MeshNode*& n1,
+                                        const SMDS_MeshNode*& n2,
+                                        _SolidData&           data)
+{
+  const SMDS_MeshNode* node = edge->_nodes[0];
+  const int shapeInd = node->getshapeId();
+  SMESHDS_SubMesh* edgeSM = 0;
+  if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_EDGE )
+  {
+    
+    edgeSM = getMeshDS()->MeshElements( shapeInd );
+    if ( !edgeSM || edgeSM->NbElements() == 0 )
+      return error(SMESH_Comment("Not meshed EDGE ") << shapeInd, data._index);
+  }
+  int iN = 0;
+  n2 = 0;
+  SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator(SMDSAbs_Edge);
+  while ( eIt->more() && !n2 )
+  {
+    const SMDS_MeshElement* e = eIt->next();
+    const SMDS_MeshNode*   nNeibor = e->GetNode( 0 );
+    if ( nNeibor == node ) nNeibor = e->GetNode( 1 );
+    if ( edgeSM )
+    {
+      if (!edgeSM->Contains(e)) continue;
+    }
+    else
+    {
+      TopoDS_Shape s = SMESH_MesherHelper::GetSubShapeByNode(nNeibor, getMeshDS() );
+      if ( !SMESH_MesherHelper::IsSubShape( s, edge->_sWOL )) continue;
+    }
+    ( iN++ ? n2 : n1 ) = nNeibor;
+  }
+  if ( !n2 )
+    return error(SMESH_Comment("Wrongly meshed EDGE ") << shapeInd, data._index);
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Set _curvature and _2neibors->_plnNorm by 2 neigbor nodes residing the same EDGE
+ */
+//================================================================================
+
+void _LayerEdge::SetDataByNeighbors( const SMDS_MeshNode* n1,
+                                     const SMDS_MeshNode* n2,
+                                     SMESH_MesherHelper&  helper)
+{
+  if ( _nodes[0]->GetPosition()->GetTypeOfPosition() != SMDS_TOP_EDGE )
+    return;
+
+  gp_XYZ pos = SMESH_TNodeXYZ( _nodes[0] );
+  gp_XYZ vec1 = pos - SMESH_TNodeXYZ( n1 );
+  gp_XYZ vec2 = pos - SMESH_TNodeXYZ( n2 );
+
+  // Set _curvature
+
+  double sumLen = vec1.Modulus() + vec2.Modulus();
+  _2neibors->_wgt[0] = 1 - vec1.Modulus() / sumLen;
+  _2neibors->_wgt[1] = 1 - vec2.Modulus() / sumLen;
+  double avgNormProj = 0.5 * ( _normal * vec1 + _normal * vec2 );
+  double avgLen = 0.5 * ( vec1.Modulus() + vec2.Modulus() );
+  if ( _curvature ) delete _curvature;
+  _curvature = _Curvature::New( avgNormProj, avgLen );
+#ifdef __myDEBUG
+//     if ( _curvature )
+//       cout << _nodes[0]->GetID()
+//            << " CURV r,k: " << _curvature->_r<<","<<_curvature->_k
+//            << " proj = "<<avgNormProj<< " len = " << avgLen << "| lenDelta(0) = "
+//            << _curvature->lenDelta(0) << endl;
+#endif
+
+  // Set _plnNorm
+
+  if ( _sWOL.IsNull() )
+  {
+    TopoDS_Shape S = helper.GetSubShapeByNode( _nodes[0], helper.GetMeshDS() );
+    gp_XYZ dirE = getEdgeDir( TopoDS::Edge( S ), _nodes[0], helper );
+    gp_XYZ plnNorm = dirE ^ _normal;
+    double proj0 = plnNorm * vec1;
+    double proj1 = plnNorm * vec2;
+    if ( fabs( proj0 ) > 1e-10 || fabs( proj1 ) > 1e-10 )
+    {
+      if ( _2neibors->_plnNorm ) delete _2neibors->_plnNorm;
+      _2neibors->_plnNorm = new gp_XYZ( plnNorm.Normalized() );
+    }
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Copy data from a _LayerEdge of other SOLID and based on the same node;
+ * this and other _LayerEdge's are inflated along a FACE or an EDGE
+ */
+//================================================================================
+
+void _LayerEdge::Copy( _LayerEdge& other, SMESH_MesherHelper& helper )
+{
+  _nodes     = other._nodes;
+  _normal    = other._normal;
+  _len       = 0;
+  _lenFactor = other._lenFactor;
+  _cosin     = other._cosin;
+  _sWOL      = other._sWOL;
+  _2neibors  = other._2neibors;
+  _curvature = 0; std::swap( _curvature, other._curvature );
+  _2neibors  = 0; std::swap( _2neibors,  other._2neibors );
+
+  if ( _sWOL.ShapeType() == TopAbs_EDGE )
+  {
+    double u = helper.GetNodeU( TopoDS::Edge( _sWOL ), _nodes[0] );
+    _pos.push_back( gp_XYZ( u, 0, 0));
+  }
+  else // TopAbs_FACE
+  {
+    gp_XY uv = helper.GetNodeUV( TopoDS::Face( _sWOL ), _nodes[0]);
+    _pos.push_back( gp_XYZ( uv.X(), uv.Y(), 0));
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Set _cosin and _lenFactor
+ */
+//================================================================================
+
+void _LayerEdge::SetCosin( double cosin )
+{
+  _cosin = cosin;
+  _lenFactor = ( _cosin > 0.1 ) ?  1./sqrt(1-_cosin*_cosin) : 1.0;
+}
+
+//================================================================================
+/*!
+ * \brief Fills a vector<_Simplex > 
+ */
+//================================================================================
+
+void _ViscousBuilder::getSimplices( const SMDS_MeshNode* node,
+                                    vector<_Simplex>&    simplices,
+                                    const set<TGeomID>&  ingnoreShapes,
+                                    const _SolidData*    dataToCheckOri,
+                                    const bool           toSort)
+{
+  SMDS_ElemIteratorPtr fIt = node->GetInverseElementIterator(SMDSAbs_Face);
+  while ( fIt->more() )
+  {
+    const SMDS_MeshElement* f = fIt->next();
+    const TGeomID shapeInd = f->getshapeId();
+    if ( ingnoreShapes.count( shapeInd )) continue;
+    const int nbNodes = f->NbCornerNodes();
+    int srcInd = f->GetNodeIndex( node );
+    const SMDS_MeshNode* nPrev = f->GetNode( SMESH_MesherHelper::WrapIndex( srcInd-1, nbNodes ));
+    const SMDS_MeshNode* nNext = f->GetNode( SMESH_MesherHelper::WrapIndex( srcInd+1, nbNodes ));
+    if ( dataToCheckOri && dataToCheckOri->_reversedFaceIds.count( shapeInd ))
+      std::swap( nPrev, nNext );
+    simplices.push_back( _Simplex( nPrev, nNext ));
+  }
+
+  if ( toSort )
+  {
+    vector<_Simplex> sortedSimplices( simplices.size() );
+    sortedSimplices[0] = simplices[0];
+    int nbFound = 0;
+    for ( size_t i = 1; i < simplices.size(); ++i )
+    {
+      for ( size_t j = 1; j < simplices.size(); ++j )
+        if ( sortedSimplices[i-1]._nNext == simplices[j]._nPrev )
+        {
+          sortedSimplices[i] = simplices[j];
+          nbFound++;
+          break;
+        }
+    }
+    if ( nbFound == simplices.size() - 1 )
+      simplices.swap( sortedSimplices );
+  }
+}
+
+//================================================================================
+/*!
+ * \brief DEBUG. Create groups contating temorary data of _LayerEdge's
+ */
+//================================================================================
+
+void _ViscousBuilder::makeGroupOfLE()
+{
+#ifdef _DEBUG_
+  for ( unsigned i = 0 ; i < _sdVec.size(); ++i )
+  {
+    if ( _sdVec[i]._edges.empty() ) continue;
+//     string name = SMESH_Comment("_LayerEdge's_") << i;
+//     int id;
+//     SMESH_Group* g = _mesh->AddGroup(SMDSAbs_Edge, name.c_str(), id );
+//     SMESHDS_Group* gDS = (SMESHDS_Group*)g->GetGroupDS();
+//     SMESHDS_Mesh* mDS = _mesh->GetMeshDS();
+
+    dumpFunction( SMESH_Comment("make_LayerEdge_") << i );
+    for ( unsigned j = 0 ; j < _sdVec[i]._edges.size(); ++j )
+    {
+      _LayerEdge* le = _sdVec[i]._edges[j];
+      for ( unsigned iN = 1; iN < le->_nodes.size(); ++iN )
+        dumpCmd(SMESH_Comment("mesh.AddEdge([ ") <<le->_nodes[iN-1]->GetID()
+                << ", " << le->_nodes[iN]->GetID() <<"])");
+      //gDS->SMDSGroup().Add( mDS->AddEdge( le->_nodes[iN-1], le->_nodes[iN]));
+    }
+    dumpFunctionEnd();
+
+    dumpFunction( SMESH_Comment("makeNormals") << i );
+    for ( unsigned j = 0 ; j < _sdVec[i]._edges.size(); ++j )
+    {
+      _LayerEdge& edge = *_sdVec[i]._edges[j];
+      SMESH_TNodeXYZ nXYZ( edge._nodes[0] );
+      nXYZ += edge._normal * _sdVec[i]._stepSize;
+      dumpCmd(SMESH_Comment("mesh.AddEdge([ ") <<edge._nodes[0]->GetID()
+              << ", mesh.AddNode( " << nXYZ.X()<<","<< nXYZ.Y()<<","<< nXYZ.Z()<<")])");
+    }
+    dumpFunctionEnd();
+
+//     name = SMESH_Comment("tmp_faces ") << i;
+//     g = _mesh->AddGroup(SMDSAbs_Face, name.c_str(), id );
+//     gDS = (SMESHDS_Group*)g->GetGroupDS();
+//     SMESH_MeshEditor editor( _mesh );
+    dumpFunction( SMESH_Comment("makeTmpFaces_") << i );
+    TopExp_Explorer fExp( _sdVec[i]._solid, TopAbs_FACE );
+    for ( ; fExp.More(); fExp.Next() )
+    {
+      if (const SMESHDS_SubMesh* sm = _sdVec[i]._proxyMesh->GetProxySubMesh( fExp.Current()))
+      {
+        SMDS_ElemIteratorPtr fIt = sm->GetElements();
+        while ( fIt->more())
+        {
+          const SMDS_MeshElement* e = fIt->next();
+          SMESH_Comment cmd("mesh.AddFace([");
+          for ( int j=0; j < e->NbCornerNodes(); ++j )
+            cmd << e->GetNode(j)->GetID() << (j+1<e->NbCornerNodes() ? ",": "])");
+          dumpCmd( cmd );
+          //vector<const SMDS_MeshNode*> nodes( e->begin_nodes(), e->end_nodes() );
+          //gDS->SMDSGroup().Add( editor.AddElement( nodes, e->GetType(), e->IsPoly()));
+        }
+      }
+    }
+    dumpFunctionEnd();
+  }
+#endif
+}
+
+//================================================================================
+/*!
+ * \brief Increase length of _LayerEdge's to reach the required thickness of layers
+ */
+//================================================================================
+
+bool _ViscousBuilder::inflate(_SolidData& data)
+{
+  SMESH_MesherHelper helper( *_mesh );
+
+  // Limit inflation step size by geometry size found by itersecting
+  // normals of _LayerEdge's with mesh faces
+  double geomSize = Precision::Infinite(), intersecDist;
+  SMESH_MeshEditor editor( _mesh );
+  auto_ptr<SMESH_ElementSearcher> searcher
+    ( editor.GetElementSearcher( data._proxyMesh->GetFaces( data._solid )) );
+  for ( unsigned i = 0; i < data._edges.size(); ++i )
+  {
+    if ( data._edges[i]->IsOnEdge() ) continue;
+    data._edges[i]->FindIntersection( *searcher, intersecDist, data._epsilon );
+    if ( geomSize > intersecDist )
+      geomSize = intersecDist;
+  }
+  if ( data._stepSize > 0.3 * geomSize )
+    limitStepSize( data, 0.3 * geomSize );
+
+  const double tgtThick = data._hyp->GetTotalThickness();
+  if ( data._stepSize > tgtThick )
+    limitStepSize( data, tgtThick );
+
+  if ( data._stepSize < 1. )
+    data._epsilon = data._stepSize * 1e-7;
+
+#ifdef __myDEBUG
+  cout << "-- geomSize = " << geomSize << ", stepSize = " << data._stepSize << endl;
+#endif
+
+  double avgThick = 0, curThick = 0, distToIntersection = Precision::Infinite();
+  int nbSteps = 0, nbRepeats = 0;
+  while ( 1.01 * avgThick < tgtThick )
+  {
+    // new target length
+    curThick += data._stepSize;
+    if ( curThick > tgtThick )
+    {
+      curThick = tgtThick + ( tgtThick-avgThick ) * nbRepeats;
+      nbRepeats++;
+    }
+
+    // Elongate _LayerEdge's
+    dumpFunction(SMESH_Comment("inflate")<<data._index<<"_step"<<nbSteps); // debug
+    for ( unsigned i = 0; i < data._edges.size(); ++i )
+    {
+      data._edges[i]->SetNewLength( curThick, helper );
+    }
+    dumpFunctionEnd();
+
+    if ( !nbSteps )
+      if ( !updateNormals( data, helper ) )
+        return false;
+
+    // Improve and check quality
+    if ( !smoothAndCheck( data, nbSteps, distToIntersection ))
+    {
+      if ( nbSteps > 0 )
+      {
+        dumpFunction(SMESH_Comment("invalidate")<<data._index<<"_step"<<nbSteps); // debug
+        for ( unsigned i = 0; i < data._edges.size(); ++i )
+        {
+          data._edges[i]->InvalidateStep( nbSteps+1 );
+        }
+        dumpFunctionEnd();
+      }
+      break; // no more inflating possible
+    }
+    nbSteps++;
+
+    // Evaluate achieved thickness
+    avgThick = 0;
+    for ( unsigned i = 0; i < data._edges.size(); ++i )
+      avgThick += data._edges[i]->_len;
+    avgThick /= data._edges.size();
+#ifdef __myDEBUG
+    cout << "-- Thickness " << avgThick << " reached" << endl;
+#endif
+
+    if ( distToIntersection < avgThick*1.5 )
+    {
+#ifdef __myDEBUG
+      cout << "-- Stop inflation since distToIntersection( "<<distToIntersection<<" ) < avgThick( "
+           << avgThick << " ) * 1.5" << endl;
+#endif
+      break;
+    }
+    // new step size
+    limitStepSize( data, 0.25 * distToIntersection );
+    if ( data._stepSizeNodes[0] )
+      data._stepSize = data._stepSizeCoeff *
+        SMESH_TNodeXYZ(data._stepSizeNodes[0]).Distance(data._stepSizeNodes[1]);
+  }
+
+  if (nbSteps == 0 )
+    return error("failed at the very first inflation step", data._index);
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Improve quality of layer inner surface and check intersection
+ */
+//================================================================================
+
+bool _ViscousBuilder::smoothAndCheck(_SolidData& data,
+                                     const int   nbSteps,
+                                     double &    distToIntersection)
+{
+  if ( data._endEdgeToSmooth.empty() )
+    return true; // no shapes needing smoothing
+
+  bool moved, improved;
+
+  SMESH_MesherHelper helper(*_mesh);
+  Handle(Geom_Surface) surface;
+  TopoDS_Face F;
+
+  int iBeg, iEnd = 0;
+  for ( unsigned iS = 0; iS < data._endEdgeToSmooth.size(); ++iS )
+  {
+    iBeg = iEnd;
+    iEnd = data._endEdgeToSmooth[ iS ];
+
+    if ( !data._edges[ iBeg ]->_sWOL.IsNull() &&
+         data._edges[ iBeg ]->_sWOL.ShapeType() == TopAbs_FACE )
+    {
+      if ( !F.IsSame( data._edges[ iBeg ]->_sWOL )) {
+        F = TopoDS::Face( data._edges[ iBeg ]->_sWOL );
+        helper.SetSubShape( F );
+        surface = BRep_Tool::Surface( F );
+      }
+    }
+    else
+    {
+      F.Nullify(); surface.Nullify();
+    }
+    TGeomID sInd = data._edges[ iBeg ]->_nodes[0]->getshapeId();
+
+    if ( data._edges[ iBeg ]->IsOnEdge() )
+    { 
+      dumpFunction(SMESH_Comment("smooth")<<data._index << "_Ed"<<sInd <<"_InfStep"<<nbSteps);
+
+      // try a simple solution on an analytic EDGE
+      if ( !smoothAnalyticEdge( data, iBeg, iEnd, surface, F, helper ))
+      {
+        // smooth on EDGE's
+        int step = 0;
+        do {
+          moved = false;
+          for ( int i = iBeg; i < iEnd; ++i )
+          {
+            moved |= data._edges[i]->SmoothOnEdge(surface, F, helper);
+          }
+          dumpCmd( SMESH_Comment("# end step ")<<step);
+        }
+        while ( moved && step++ < 5 );
+        //cout << " NB STEPS: " << step << endl;
+      }
+      dumpFunctionEnd();
+    }
+    else
+    {
+      // smooth on FACE's
+      int step = 0, badNb = 0; moved = true;
+      while (( ++step <= 5 && moved ) || improved )
+      {
+        dumpFunction(SMESH_Comment("smooth")<<data._index<<"_Fa"<<sInd
+                     <<"_InfStep"<<nbSteps<<"_"<<step); // debug
+        int oldBadNb = badNb;
+        badNb = 0;
+        moved = false;
+        for ( int i = iBeg; i < iEnd; ++i )
+          moved |= data._edges[i]->Smooth(badNb);
+        improved = ( badNb < oldBadNb );
+
+        dumpFunctionEnd();
+      }
+      if ( badNb > 0 )
+      {
+#ifdef __myDEBUG
+        for ( int i = iBeg; i < iEnd; ++i )
+        {
+          _LayerEdge* edge = data._edges[i];
+          SMESH_TNodeXYZ tgtXYZ( edge->_nodes.back() );
+          for ( unsigned j = 0; j < edge->_simplices.size(); ++j )
+            if ( !edge->_simplices[j].IsForward( edge->_nodes[0], &tgtXYZ ))
+            {
+              cout << "Bad simplex ( " << edge->_nodes[0]->GetID()<< " "<< tgtXYZ._node->GetID()
+                   << " "<< edge->_simplices[j]._nPrev->GetID()
+                   << " "<< edge->_simplices[j]._nNext->GetID() << " )" << endl;
+              return false;
+            }
+        }
+#endif
+        return false;
+      }
+    }
+  } // loop on shapes to smooth
+
+  // Check if the last segments of _LayerEdge intersects 2D elements;
+  // checked elements are either temporary faces or faces on surfaces w/o the layers
+
+  SMESH_MeshEditor editor( _mesh );
+  auto_ptr<SMESH_ElementSearcher> searcher
+    ( editor.GetElementSearcher( data._proxyMesh->GetFaces( data._solid )) );
+
+  distToIntersection = Precision::Infinite();
+  double dist;
+  const SMDS_MeshElement* intFace = 0;
+#ifdef __myDEBUG
+  const SMDS_MeshElement* closestFace = 0;
+  int iLE = 0;
+#endif
+  for ( unsigned i = 0; i < data._edges.size(); ++i )
+  {
+    if ( data._edges[i]->FindIntersection( *searcher, dist, data._epsilon, &intFace ))
+      return false;
+    if ( distToIntersection > dist )
+    {
+      distToIntersection = dist;
+#ifdef __myDEBUG
+      iLE = i;
+      closestFace = intFace;
+#endif
+    }
+  }
+#ifdef __myDEBUG
+  if ( closestFace )
+  {
+    SMDS_MeshElement::iterator nIt = closestFace->begin_nodes();
+    cout << "Shortest distance: _LayerEdge nodes: tgt " << data._edges[iLE]->_nodes.back()->GetID()
+         << " src " << data._edges[iLE]->_nodes[0]->GetID()<< ", intersection with face ("
+         << (*nIt++)->GetID()<<" "<< (*nIt++)->GetID()<<" "<< (*nIt++)->GetID()
+         << ") distance = " << distToIntersection<< endl;
+  }
+#endif
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Return a curve of the EDGE to be used for smoothing and arrange
+ *        _LayerEdge's to be in a consequent order
+ */
+//================================================================================
+
+Handle(Geom_Curve) _SolidData::CurveForSmooth( const TopoDS_Edge&    E,
+                                               const int             iFrom,
+                                               const int             iTo,
+                                               Handle(Geom_Surface)& surface,
+                                               const TopoDS_Face&    F,
+                                               SMESH_MesherHelper&   helper)
+{
+  TGeomID eIndex = helper.GetMeshDS()->ShapeToIndex( E );
+
+  map< TGeomID, Handle(Geom_Curve)>::iterator i2curve = _edge2curve.find( eIndex );
+
+  if ( i2curve == _edge2curve.end() )
+  {
+    // sort _LayerEdge's by position on the EDGE
+    {
+      map< double, _LayerEdge* > u2edge;
+      for ( int i = iFrom; i < iTo; ++i )
+        u2edge.insert( make_pair( helper.GetNodeU( E, _edges[i]->_nodes[0] ), _edges[i] ));
+
+      ASSERT( u2edge.size() == iTo - iFrom );
+      map< double, _LayerEdge* >::iterator u2e = u2edge.begin();
+      for ( int i = iFrom; i < iTo; ++i, ++u2e )
+        _edges[i] = u2e->second;
+
+      // set _2neibors according to the new order
+      for ( int i = iFrom; i < iTo-1; ++i )
+        if ( _edges[i]->_2neibors->_nodes[1] != _edges[i+1]->_nodes.back() )
+          _edges[i]->_2neibors->reverse();
+      if ( u2edge.size() > 1 &&
+           _edges[iTo-1]->_2neibors->_nodes[0] != _edges[iTo-2]->_nodes.back() )
+        _edges[iTo-1]->_2neibors->reverse();
+    }
+
+    SMESHDS_SubMesh* smDS = helper.GetMeshDS()->MeshElements( eIndex );
+
+    TopLoc_Location loc; double f,l;
+
+    Handle(Geom_Line)   line;
+    Handle(Geom_Circle) circle;
+    bool isLine, isCirc;
+    if ( F.IsNull() ) // 3D case
+    {
+      // check if the EDGE is a line
+      Handle(Geom_Curve) curve = BRep_Tool::Curve( E, loc, f, l);
+      if ( curve->IsKind( STANDARD_TYPE( Geom_TrimmedCurve )))
+        curve = Handle(Geom_TrimmedCurve)::DownCast( curve )->BasisCurve();
+
+      line   = Handle(Geom_Line)::DownCast( curve );
+      circle = Handle(Geom_Circle)::DownCast( curve );
+      isLine = (!line.IsNull());
+      isCirc = (!circle.IsNull());
+
+      if ( !isLine && !isCirc ) // Check if the EDGE is close to a line
+      {
+        Bnd_B3d bndBox;
+        SMDS_NodeIteratorPtr nIt = smDS->GetNodes();
+        while ( nIt->more() )
+          bndBox.Add( SMESH_TNodeXYZ( nIt->next() ));
+        gp_XYZ size = bndBox.CornerMax() - bndBox.CornerMin();
+
+        SMESH_TNodeXYZ p0( _edges[iFrom]->_2neibors->_nodes[0] );
+        SMESH_TNodeXYZ p1( _edges[iFrom]->_2neibors->_nodes[1] );
+        const double lineTol = 1e-2 * ( p0 - p1 ).Modulus();
+        for ( int i = 0; i < 3 && !isLine; ++i )
+          isLine = ( size.Coord( i+1 ) <= lineTol );
+      }
+      if ( !isLine && !isCirc && iTo-iFrom > 2) // Check if the EDGE is close to a circle
+      {
+        // TODO
+      }
+    }
+    else // 2D case
+    {
+      // check if the EDGE is a line
+      Handle(Geom2d_Curve) curve = BRep_Tool::CurveOnSurface( E, F, f, l);
+      if ( curve->IsKind( STANDARD_TYPE( Geom2d_TrimmedCurve )))
+        curve = Handle(Geom2d_TrimmedCurve)::DownCast( curve )->BasisCurve();
+
+      Handle(Geom2d_Line)   line2d   = Handle(Geom2d_Line)::DownCast( curve );
+      Handle(Geom2d_Circle) circle2d = Handle(Geom2d_Circle)::DownCast( curve );
+      isLine = (!line2d.IsNull());
+      isCirc = (!circle2d.IsNull());
+
+      if ( !isLine && !isCirc) // Check if the EDGE is close to a line
+      {
+        Bnd_B2d bndBox;
+        SMDS_NodeIteratorPtr nIt = smDS->GetNodes();
+        while ( nIt->more() )
+          bndBox.Add( helper.GetNodeUV( F, nIt->next() ));
+        gp_XY size = bndBox.CornerMax() - bndBox.CornerMin();
+
+        const double lineTol = 1e-2 * sqrt( bndBox.SquareExtent() );
+        for ( int i = 0; i < 2 && !isLine; ++i )
+          isLine = ( size.Coord( i+1 ) <= lineTol );
+      }
+      if ( !isLine && !isCirc && iTo-iFrom > 2) // Check if the EDGE is close to a circle
+      {
+        // TODO
+      }
+      if ( isLine )
+      {
+        line = new Geom_Line( gp::OX() ); // only type does matter
+      }
+      else if ( isCirc )
+      {
+        gp_Pnt2d p = circle2d->Location();
+        gp_Ax2 ax( gp_Pnt( p.X(), p.Y(), 0), gp::DX());
+        circle = new Geom_Circle( ax, 1.); // only center position does matter
+      }
+    }
+
+    Handle(Geom_Curve)& res = _edge2curve[ eIndex ];
+    if ( isLine )
+      res = line;
+    else if ( isCirc )
+      res = circle;
+
+    return res;
+  }
+  return i2curve->second;
+}
+
+//================================================================================
+/*!
+ * \brief smooth _LayerEdge's on a staight EDGE or circular EDGE
+ */
+//================================================================================
+
+bool _ViscousBuilder::smoothAnalyticEdge( _SolidData&           data,
+                                          const int             iFrom,
+                                          const int             iTo,
+                                          Handle(Geom_Surface)& surface,
+                                          const TopoDS_Face&    F,
+                                          SMESH_MesherHelper&   helper)
+{
+  TopoDS_Shape S = helper.GetSubShapeByNode( data._edges[ iFrom ]->_nodes[0],
+                                             helper.GetMeshDS());
+  TopoDS_Edge E = TopoDS::Edge( S );
+
+  Handle(Geom_Curve) curve = data.CurveForSmooth( E, iFrom, iTo, surface, F, helper );
+  if ( curve.IsNull() ) return false;
+
+  // compute a relative length of segments
+  vector< double > len( iTo-iFrom+1 );
+  {
+    double curLen, prevLen = len[0] = 1.0;
+    for ( int i = iFrom; i < iTo; ++i )
+    {
+      curLen = prevLen * data._edges[i]->_2neibors->_wgt[0] / data._edges[i]->_2neibors->_wgt[1];
+      len[i-iFrom+1] = len[i-iFrom] + curLen;
+      prevLen = curLen;
+    }
+  }
+
+  if ( curve->IsKind( STANDARD_TYPE( Geom_Line )))
+  {
+    if ( F.IsNull() ) // 3D
+    {
+      SMESH_TNodeXYZ p0( data._edges[iFrom]->_2neibors->_nodes[0]);
+      SMESH_TNodeXYZ p1( data._edges[iTo-1]->_2neibors->_nodes[1]);
+      for ( int i = iFrom; i < iTo; ++i )
+      {
+        double r = len[i-iFrom] / len.back();
+        gp_XYZ newPos = p0 * ( 1. - r ) + p1 * r;
+        data._edges[i]->_pos.back() = newPos;
+        SMDS_MeshNode* tgtNode = const_cast<SMDS_MeshNode*>( data._edges[i]->_nodes.back() );
+        tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() );
+        dumpMove( tgtNode );
+      }
+    }
+    else
+    {
+      gp_XY uv0 = helper.GetNodeUV( F, data._edges[iFrom]->_2neibors->_nodes[0]);
+      gp_XY uv1 = helper.GetNodeUV( F, data._edges[iTo-1]->_2neibors->_nodes[1]);
+      if ( data._edges[iFrom]->_2neibors->_nodes[0] ==
+           data._edges[iTo-1]->_2neibors->_nodes[1] ) // closed edge
+      {
+        int iPeriodic = helper.GetPeriodicIndex();
+        if ( iPeriodic == 1 || iPeriodic == 2 )
+        {
+          uv1.SetCoord( iPeriodic, helper.GetOtherParam( uv1.Coord( iPeriodic )));
+          if ( uv0.Coord( iPeriodic ) > uv1.Coord( iPeriodic ))
+            std::swap( uv0, uv1 );
+        }
+      }
+      const gp_XY rangeUV = uv1 - uv0;
+      for ( int i = iFrom; i < iTo; ++i )
+      {
+        double r = len[i-iFrom] / len.back();
+        gp_XY newUV = uv0 + r * rangeUV;
+        data._edges[i]->_pos.back().SetCoord( newUV.X(), newUV.Y(), 0 );
+
+        gp_Pnt newPos = surface->Value( newUV.X(), newUV.Y() );
+        SMDS_MeshNode* tgtNode = const_cast<SMDS_MeshNode*>( data._edges[i]->_nodes.back() );
+        tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() );
+        dumpMove( tgtNode );
+
+        SMDS_FacePosition* pos = static_cast<SMDS_FacePosition*>( tgtNode->GetPosition() );
+        pos->SetUParameter( newUV.X() );
+        pos->SetVParameter( newUV.Y() );
+      }
+    }
+    return true;
+  }
+
+  if ( curve->IsKind( STANDARD_TYPE( Geom_Circle )))
+  {
+    Handle(Geom_Circle) circle = Handle(Geom_Circle)::DownCast( curve );
+    gp_Pnt center3D = circle->Location();
+
+    if ( F.IsNull() ) // 3D
+    {
+      return false; // TODO ???
+    }
+    else // 2D
+    {
+      const gp_XY center( center3D.X(), center3D.Y() );
+      
+      gp_XY uv0 = helper.GetNodeUV( F, data._edges[iFrom]->_2neibors->_nodes[0]);
+      gp_XY uvM = helper.GetNodeUV( F, data._edges[iFrom]->_nodes.back());
+      gp_XY uv1 = helper.GetNodeUV( F, data._edges[iTo-1]->_2neibors->_nodes[1]);
+      gp_Vec2d vec0( center, uv0 );
+      gp_Vec2d vecM( center, uvM);
+      gp_Vec2d vec1( center, uv1 );
+      double uLast = vec0.Angle( vec1 ); // -PI - +PI
+      double uMidl = vec0.Angle( vecM );
+      if ( uLast < 0 ) uLast += 2.*M_PI; // 0.0 - 2*PI
+      if ( uMidl < 0 ) uMidl += 2.*M_PI;
+      const bool sense = ( uMidl < uLast );
+      const double radius = 0.5 * ( vec0.Magnitude() + vec1.Magnitude() );
+
+      gp_Ax2d axis( center, vec0 );
+      gp_Circ2d circ ( axis, radius, sense );
+      for ( int i = iFrom; i < iTo; ++i )
+      {
+        double    newU = uLast * len[i-iFrom] / len.back();
+        gp_Pnt2d newUV = ElCLib::Value( newU, circ );
+        data._edges[i]->_pos.back().SetCoord( newUV.X(), newUV.Y(), 0 );
+
+        gp_Pnt newPos = surface->Value( newUV.X(), newUV.Y() );
+        SMDS_MeshNode* tgtNode = const_cast<SMDS_MeshNode*>( data._edges[i]->_nodes.back() );
+        tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() );
+        dumpMove( tgtNode );
+
+        SMDS_FacePosition* pos = static_cast<SMDS_FacePosition*>( tgtNode->GetPosition() );
+        pos->SetUParameter( newUV.X() );
+        pos->SetVParameter( newUV.Y() );
+      }
+    }
+    return true;
+  }
+
+  return false;
+}
+
+//================================================================================
+/*!
+ * \brief Modify normals of _LayerEdge's on EDGE's to avoid intersection with
+ * _LayerEdge's on neighbor EDGE's
+ */
+//================================================================================
+
+bool _ViscousBuilder::updateNormals( _SolidData&         data,
+                                     SMESH_MesherHelper& helper )
+{
+  // make temporary quadrangles got by extrusion of
+  // mesh edges along _LayerEdge._normal's
+
+  vector< const SMDS_MeshElement* > tmpFaces;
+  {
+    set< SMESH_TLink > extrudedLinks; // contains target nodes
+    vector< const SMDS_MeshNode*> nodes(4); // of a tmp mesh face
+
+    dumpFunction(SMESH_Comment("makeTmpFacesOnEdges")<<data._index);
+    for ( unsigned i = 0; i < data._edges.size(); ++i )
+    {
+      _LayerEdge* edge = data._edges[i];
+      if ( !edge->IsOnEdge() || !edge->_sWOL.IsNull() ) continue;
+      const SMDS_MeshNode* tgt1 = edge->_nodes.back();
+      for ( int j = 0; j < 2; ++j ) // loop on _2NearEdges
+      {
+        const SMDS_MeshNode* tgt2 = edge->_2neibors->_nodes[j];
+        pair< set< SMESH_TLink >::iterator, bool > link_isnew =
+          extrudedLinks.insert( SMESH_TLink( tgt1, tgt2 ));
+        if ( !link_isnew.second )
+        {
+          extrudedLinks.erase( link_isnew.first );
+          continue; // already extruded and will no more encounter
+        }
+        // look for a _LayerEdge containg tgt2
+//         _LayerEdge* neiborEdge = 0;
+//         unsigned di = 0; // check _edges[i+di] and _edges[i-di]
+//         while ( !neiborEdge && ++di <= data._edges.size() )
+//         {
+//           if ( i+di < data._edges.size() && data._edges[i+di]->_nodes.back() == tgt2 )
+//             neiborEdge = data._edges[i+di];
+//           else if ( di <= i && data._edges[i-di]->_nodes.back() == tgt2 )
+//             neiborEdge = data._edges[i-di];
+//         }
+//         if ( !neiborEdge )
+//           return error("updateNormals(): neighbor _LayerEdge not found", data._index);
+        _LayerEdge* neiborEdge = edge->_2neibors->_edges[j];
+
+        TmpMeshFaceOnEdge* f = new TmpMeshFaceOnEdge( edge, neiborEdge, --_tmpFaceID );
+        tmpFaces.push_back( f );
+
+        dumpCmd(SMESH_Comment("mesh.AddFace([ ")
+                <<f->_nn[0]->GetID()<<", "<<f->_nn[1]->GetID()<<", "
+                <<f->_nn[2]->GetID()<<", "<<f->_nn[3]->GetID()<<" ])");
+      }
+    }
+    dumpFunctionEnd();
+  }
+  // Check if _LayerEdge's based on EDGE's intersects tmpFaces.
+  // Perform two loops on _LayerEdge on EDGE's:
+  // 1) to find and fix intersection
+  // 2) to check that no new intersection appears as result of 1)
+
+  SMESH_MeshEditor editor( _mesh );
+  SMDS_ElemIteratorPtr fIt( new SMDS_ElementVectorIterator( tmpFaces.begin(),
+                                                            tmpFaces.end()));
+  auto_ptr<SMESH_ElementSearcher> searcher ( editor.GetElementSearcher( fIt ));
+
+  // 1) Find intersections
+  double dist;
+  const SMDS_MeshElement* face;
+  typedef map< _LayerEdge*, set< _LayerEdge*, _LayerEdgeCmp >, _LayerEdgeCmp > TLEdge2LEdgeSet;
+  TLEdge2LEdgeSet edge2CloseEdge;
+
+  const double eps = data._epsilon * data._epsilon;
+  for ( unsigned i = 0; i < data._edges.size(); ++i )
+  {
+    _LayerEdge* edge = data._edges[i];
+    if ( !edge->IsOnEdge() || !edge->_sWOL.IsNull() ) continue;
+    if ( edge->FindIntersection( *searcher, dist, eps, &face ))
+    {
+      const TmpMeshFaceOnEdge* f = (const TmpMeshFaceOnEdge*) face;
+      set< _LayerEdge*, _LayerEdgeCmp > & ee = edge2CloseEdge[ edge ];
+      ee.insert( f->_le1 );
+      ee.insert( f->_le2 );
+      if ( f->_le1->IsOnEdge() && f->_le1->_sWOL.IsNull() ) 
+        edge2CloseEdge[ f->_le1 ].insert( edge );
+      if ( f->_le2->IsOnEdge() && f->_le2->_sWOL.IsNull() ) 
+        edge2CloseEdge[ f->_le2 ].insert( edge );
+    }
+  }
+
+  // Set _LayerEdge._normal
+
+  if ( !edge2CloseEdge.empty() )
+  {
+    dumpFunction(SMESH_Comment("updateNormals")<<data._index);
+
+    TLEdge2LEdgeSet::iterator e2ee = edge2CloseEdge.begin();
+    for ( ; e2ee != edge2CloseEdge.end(); ++e2ee )
+    {
+      _LayerEdge* edge1       = e2ee->first;
+      _LayerEdge* edge2       = 0;
+      set< _LayerEdge*, _LayerEdgeCmp >& ee  = e2ee->second;
+
+      // find EDGEs the edges reside
+      TopoDS_Edge E1, E2;
+      TopoDS_Shape S = helper.GetSubShapeByNode( edge1->_nodes[0], getMeshDS() );
+      if ( S.ShapeType() != TopAbs_EDGE )
+        continue; // TODO: find EDGE by VERTEX
+      E1 = TopoDS::Edge( S );
+      set< _LayerEdge*, _LayerEdgeCmp >::iterator eIt = ee.begin();
+      while ( E2.IsNull() && eIt != ee.end())
+      {
+        _LayerEdge* e2 = *eIt++;
+        TopoDS_Shape S = helper.GetSubShapeByNode( e2->_nodes[0], getMeshDS() );
+        if ( S.ShapeType() == TopAbs_EDGE )
+          E2 = TopoDS::Edge( S ), edge2 = e2;
+      }
+      if ( E2.IsNull() ) continue; // TODO: find EDGE by VERTEX
+
+      // find 3 FACEs sharing 2 EDGEs
+
+      TopoDS_Face FF1[2], FF2[2];
+      PShapeIteratorPtr fIt = helper.GetAncestors(E1, *_mesh, TopAbs_FACE);
+      while ( fIt->more() && FF1[1].IsNull())
+      {
+        const TopoDS_Face *F = (const TopoDS_Face*) fIt->next();
+        if ( helper.IsSubShape( *F, data._solid))
+          FF1[ FF1[0].IsNull() ? 0 : 1 ] = *F;
+      }
+      fIt = helper.GetAncestors(E2, *_mesh, TopAbs_FACE);
+      while ( fIt->more() && FF2[1].IsNull())
+      {
+        const TopoDS_Face *F = (const TopoDS_Face*) fIt->next();
+        if ( helper.IsSubShape( *F, data._solid))
+          FF2[ FF2[0].IsNull() ? 0 : 1 ] = *F;
+      }
+      // exclude a FACE common to E1 and E2 (put it at [1] in FF* )
+      if ( FF1[0].IsSame( FF2[0]) || FF1[0].IsSame( FF2[1]))
+        std::swap( FF1[0], FF1[1] );
+      if ( FF2[0].IsSame( FF1[0]) )
+        std::swap( FF2[0], FF2[1] );
+      if ( FF1[0].IsNull() || FF2[0].IsNull() )
+        continue;
+
+//       // get a new normal for edge1
+      bool ok;
+      gp_Vec dir1 = edge1->_normal, dir2 = edge2->_normal;
+      if ( edge1->_cosin < 0 )
+        dir1 = getFaceDir( FF1[0], E1, edge1->_nodes[0], helper, ok ).Normalized();
+      if ( edge2->_cosin < 0 )
+        dir2 = getFaceDir( FF2[0], E2, edge2->_nodes[0], helper, ok ).Normalized();
+      //      gp_Vec dir1 = getFaceDir( FF1[0], E1, edge1->_nodes[0], helper, ok );
+//       gp_Vec dir2 = getFaceDir( FF2[0], E2, edge2->_nodes[0], helper, ok2 );
+//       double wgt1 = ( edge1->_cosin + 1 ) / ( edge1->_cosin + edge2->_cosin + 2 );
+//       double wgt2 = ( edge2->_cosin + 1 ) / ( edge1->_cosin + edge2->_cosin + 2 );
+//       gp_Vec newNorm = wgt1 * dir1 + wgt2 * dir2;
+//       newNorm.Normalize();
+
+      double wgt1 = ( edge1->_cosin + 1 ) / ( edge1->_cosin + edge2->_cosin + 2 );
+      double wgt2 = ( edge2->_cosin + 1 ) / ( edge1->_cosin + edge2->_cosin + 2 );
+      gp_Vec newNorm = wgt1 * dir1 + wgt2 * dir2;
+      newNorm.Normalize();
+
+      edge1->_normal = newNorm.XYZ();
+
+      // update data of edge1 depending on _normal
+      const SMDS_MeshNode *n1, *n2;
+      n1 = edge1->_2neibors->_edges[0]->_nodes[0];
+      n2 = edge1->_2neibors->_edges[1]->_nodes[0];
+      //if ( !findNeiborsOnEdge( edge1, n1, n2, data ))
+      //continue;
+      edge1->SetDataByNeighbors( n1, n2, helper );
+      gp_Vec dirInFace;
+      if ( edge1->_cosin < 0 )
+        dirInFace = dir1;
+      else
+        getFaceDir( FF1[0], E1, edge1->_nodes[0], helper, ok );
+      double angle = dir1.Angle( edge1->_normal ); // [0,PI]
+      edge1->SetCosin( cos( angle ));
+
+      // limit data._stepSize
+      if ( edge1->_cosin > 0.1 )
+      {
+        SMDS_ElemIteratorPtr fIt = edge1->_nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
+        while ( fIt->more() )
+          limitStepSize( data, fIt->next(), edge1->_cosin );
+      }
+      // set new XYZ of target node
+      edge1->InvalidateStep( 1 );
+      edge1->_len = 0;
+      edge1->SetNewLength( data._stepSize, helper );
+    }
+
+    // Update normals and other dependent data of not intersecting _LayerEdge's
+    // neighboring the intersecting ones
+
+    for ( e2ee = edge2CloseEdge.begin(); e2ee != edge2CloseEdge.end(); ++e2ee )
+    {
+      _LayerEdge* edge1 = e2ee->first;
+      if ( !edge1->_2neibors )
+        continue;
+      for ( int j = 0; j < 2; ++j ) // loop on 2 neighbors
+      {
+        _LayerEdge* neighbor = edge1->_2neibors->_edges[j];
+        if ( edge2CloseEdge.count ( neighbor ))
+          continue; // j-th neighbor is also intersected
+        _LayerEdge* prevEdge = edge1;
+        const int nbSteps = 6;
+        for ( int step = nbSteps; step; --step ) // step from edge1 in j-th direction
+        {
+          if ( !neighbor->_2neibors )
+            break; // neighbor is on VERTEX
+          int iNext = 0;
+          _LayerEdge* nextEdge = neighbor->_2neibors->_edges[iNext];
+          if ( nextEdge == prevEdge )
+            nextEdge = neighbor->_2neibors->_edges[ ++iNext ];
+//           const double&  wgtPrev = neighbor->_2neibors->_wgt[1-iNext];
+//           const double&  wgtNext = neighbor->_2neibors->_wgt[iNext];
+          double r = double(step-1)/nbSteps;
+          if ( !nextEdge->_2neibors )
+            r = 0.5;
+
+          gp_XYZ newNorm = prevEdge->_normal * r + nextEdge->_normal * (1-r);
+          newNorm.Normalize();
+
+          neighbor->_normal = newNorm;
+          neighbor->SetCosin( prevEdge->_cosin * r + nextEdge->_cosin * (1-r) );
+          neighbor->SetDataByNeighbors( prevEdge->_nodes[0], nextEdge->_nodes[0], helper );
+
+          neighbor->InvalidateStep( 1 );
+          neighbor->_len = 0;
+          neighbor->SetNewLength( data._stepSize, helper );
+
+          // goto the next neighbor
+          prevEdge = neighbor;
+          neighbor = nextEdge;
+        }
+      }
+    }
+    dumpFunctionEnd();
+  }
+  // 2) Check absence of intersections
+  // TODO?
+
+  for ( unsigned i = 0 ; i < tmpFaces.size(); ++i )
+    delete tmpFaces[i];
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Looks for intersection of it's last segment with faces
+ *  \param distance - returns shortest distance from the last node to intersection
+ */
+//================================================================================
+
+bool _LayerEdge::FindIntersection( SMESH_ElementSearcher&   searcher,
+                                   double &                 distance,
+                                   const double&            epsilon,
+                                   const SMDS_MeshElement** face)
+{
+  vector< const SMDS_MeshElement* > suspectFaces;
+  double segLen;
+  gp_Ax1 lastSegment = LastSegment(segLen);
+  searcher.GetElementsNearLine( lastSegment, SMDSAbs_Face, suspectFaces );
+
+  bool segmentIntersected = false;
+  distance = Precision::Infinite();
+  int iFace = -1; // intersected face
+  for ( unsigned j = 0 ; j < suspectFaces.size() && !segmentIntersected; ++j )
+  {
+    const SMDS_MeshElement* face = suspectFaces[j];
+    if ( face->GetNodeIndex( _nodes.back() ) >= 0 ||
+         face->GetNodeIndex( _nodes[0]     ) >= 0 )
+      continue; // face sharing _LayerEdge node
+    const int nbNodes = face->NbCornerNodes();
+    bool intFound = false;
+    double dist;
+    SMDS_MeshElement::iterator nIt = face->begin_nodes();
+    if ( nbNodes == 3 )
+    {
+      intFound = SegTriaInter( lastSegment, *nIt++, *nIt++, *nIt++, dist, epsilon );
+    }
+    else
+    {
+      const SMDS_MeshNode* tria[3];
+      tria[0] = *nIt++;
+      tria[1] = *nIt++;;
+      for ( int n2 = 2; n2 < nbNodes && !intFound; ++n2 )
+      {
+        tria[2] = *nIt++;
+        intFound = SegTriaInter(lastSegment, tria[0], tria[1], tria[2], dist, epsilon );
+        tria[1] = tria[2];
+      }
+    }
+    if ( intFound )
+    {
+      if ( dist < segLen*(1.01))
+        segmentIntersected = true;
+      if ( distance > dist )
+        distance = dist, iFace = j;
+    }
+  }
+  if ( iFace != -1 && face ) *face = suspectFaces[iFace];
+//   if ( distance && iFace > -1 )
+//   {
+//     // distance is used to limit size of inflation step which depends on
+//     // whether the intersected face bears viscous layers or not
+//     bool faceHasVL = suspectFaces[iFace]->GetID() < 1;
+//     if ( faceHasVL )
+//       *distance /= 2;
+//   }
+  if ( segmentIntersected )
+  {
+#ifdef __myDEBUG
+    SMDS_MeshElement::iterator nIt = suspectFaces[iFace]->begin_nodes();
+    gp_XYZ intP( lastSegment.Location().XYZ() + lastSegment.Direction().XYZ() * distance );
+    cout << "nodes: tgt " << _nodes.back()->GetID() << " src " << _nodes[0]->GetID()
+         << ", intersection with face ("
+         << (*nIt++)->GetID()<<" "<< (*nIt++)->GetID()<<" "<< (*nIt++)->GetID()
+         << ") at point (" << intP.X() << ", " << intP.Y() << ", " << intP.Z()
+         << ") distance = " << distance - segLen<< endl;
+#endif
+  }
+
+  distance -= segLen;
+
+  return segmentIntersected;
+}
+
+//================================================================================
+/*!
+ * \brief Returns size and direction of the last segment
+ */
+//================================================================================
+
+gp_Ax1 _LayerEdge::LastSegment(double& segLen) const
+{
+  // find two non-coincident positions
+  gp_XYZ orig = _pos.back();
+  gp_XYZ dir;
+  int iPrev = _pos.size() - 2;
+  while ( iPrev >= 0 )
+  {
+    dir = orig - _pos[iPrev];
+    if ( dir.SquareModulus() > 1e-100 )
+      break;
+    else
+      iPrev--;
+  }
+
+  // make gp_Ax1
+  gp_Ax1 segDir;
+  if ( iPrev < 0 )
+  {
+    segDir.SetLocation( SMESH_TNodeXYZ( _nodes[0] ));
+    segDir.SetDirection( _normal );
+    segLen = 0;
+  }
+  else
+  {
+    gp_Pnt pPrev = _pos[ iPrev ];
+    if ( !_sWOL.IsNull() )
+    {
+      TopLoc_Location loc;
+      if ( _sWOL.ShapeType() == TopAbs_EDGE )
+      {
+        double f,l;
+        Handle(Geom_Curve) curve = BRep_Tool::Curve( TopoDS::Edge( _sWOL ), loc, f,l);
+        pPrev = curve->Value( pPrev.X() ).Transformed( loc );
+      }
+      else
+      {
+        Handle(Geom_Surface) surface = BRep_Tool::Surface( TopoDS::Face(_sWOL), loc );
+        pPrev = surface->Value( pPrev.X(), pPrev.Y() ).Transformed( loc );
+      }
+      dir = SMESH_TNodeXYZ( _nodes.back() ) - pPrev.XYZ();
+    }
+    segDir.SetLocation( pPrev );
+    segDir.SetDirection( dir );
+    segLen = dir.Modulus();
+  }
+
+  return segDir;
+}
+
+//================================================================================
+/*!
+ * \brief Test intersection of the last segment with a given triangle
+ *   using Moller-Trumbore algorithm
+ * Intersection is detected if distance to intersection is less than _LayerEdge._len
+ */
+//================================================================================
+
+bool _LayerEdge::SegTriaInter( const gp_Ax1&        lastSegment,
+                               const SMDS_MeshNode* n0,
+                               const SMDS_MeshNode* n1,
+                               const SMDS_MeshNode* n2,
+                               double&              t,
+                               const double&        EPSILON) const
+{
+  //const double EPSILON = 1e-6;
+
+  gp_XYZ orig = lastSegment.Location().XYZ();
+  gp_XYZ dir  = lastSegment.Direction().XYZ();
+
+  SMESH_TNodeXYZ vert0( n0 );
+  SMESH_TNodeXYZ vert1( n1 );
+  SMESH_TNodeXYZ vert2( n2 );
+
+  /* calculate distance from vert0 to ray origin */
+  gp_XYZ tvec = orig - vert0;
+
+  if ( tvec * dir > EPSILON )
+    // intersected face is at back side of the temporary face this _LayerEdge belongs to
+    return false;
+
+  gp_XYZ edge1 = vert1 - vert0;
+  gp_XYZ edge2 = vert2 - vert0;
+
+  /* begin calculating determinant - also used to calculate U parameter */
+  gp_XYZ pvec = dir ^ edge2;
+
+  /* if determinant is near zero, ray lies in plane of triangle */
+  double det = edge1 * pvec;
+
+  if (det > -EPSILON && det < EPSILON)
+    return 0;
+  double inv_det = 1.0 / det;
+
+  /* calculate U parameter and test bounds */
+  double u = ( tvec * pvec ) * inv_det;
+  if (u < 0.0 || u > 1.0)
+    return 0;
+
+  /* prepare to test V parameter */
+  gp_XYZ qvec = tvec ^ edge1;
+
+  /* calculate V parameter and test bounds */
+  double v = (dir * qvec) * inv_det;
+  if ( v < 0.0 || u + v > 1.0 )
+    return 0;
+
+  /* calculate t, ray intersects triangle */
+  t = (edge2 * qvec) * inv_det;
+
+  //   if (det < EPSILON)
+  //     return false;
+
+  //   /* calculate distance from vert0 to ray origin */
+  //   gp_XYZ tvec = orig - vert0;
+
+  //   /* calculate U parameter and test bounds */
+  //   double u = tvec * pvec;
+  //   if (u < 0.0 || u > det)
+//     return 0;
+
+//   /* prepare to test V parameter */
+//   gp_XYZ qvec = tvec ^ edge1;
+
+//   /* calculate V parameter and test bounds */
+//   double v = dir * qvec;
+//   if (v < 0.0 || u + v > det)
+//     return 0;
+
+//   /* calculate t, scale parameters, ray intersects triangle */
+//   double t = edge2 * qvec;
+//   double inv_det = 1.0 / det;
+//   t *= inv_det;
+//   //u *= inv_det;
+//   //v *= inv_det;
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Perform smooth of _LayerEdge's based on EDGE's
+ *  \retval bool - true if node has been moved
+ */
+//================================================================================
+
+bool _LayerEdge::SmoothOnEdge(Handle(Geom_Surface)& surface,
+                              const TopoDS_Face&    F,
+                              SMESH_MesherHelper&   helper)
+{
+  ASSERT( IsOnEdge() );
+
+  SMDS_MeshNode* tgtNode = const_cast<SMDS_MeshNode*>( _nodes.back() );
+  SMESH_TNodeXYZ oldPos( tgtNode );
+  double dist01, distNewOld;
+  
+  SMESH_TNodeXYZ p0( _2neibors->_nodes[0]);
+  SMESH_TNodeXYZ p1( _2neibors->_nodes[1]);
+  dist01 = p0.Distance( _2neibors->_nodes[1] );
+
+  gp_Pnt newPos = p0 * _2neibors->_wgt[0] + p1 * _2neibors->_wgt[1];
+  double lenDelta = 0;
+  if ( _curvature )
+  {
+    lenDelta = _curvature->lenDelta( _len );
+    newPos.ChangeCoord() += _normal * lenDelta;
+  }
+
+  distNewOld = newPos.Distance( oldPos );
+
+  if ( F.IsNull() )
+  {
+    if ( _2neibors->_plnNorm )
+    {
+      // put newPos on the plane defined by source node and _plnNorm
+      gp_XYZ new2src = SMESH_TNodeXYZ( _nodes[0] ) - newPos.XYZ();
+      double new2srcProj = (*_2neibors->_plnNorm) * new2src;
+      newPos.ChangeCoord() += (*_2neibors->_plnNorm) * new2srcProj;
+    }
+    tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() );
+    _pos.back() = newPos.XYZ();
+  }
+  else
+  {
+    tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() );
+    gp_XY uv( Precision::Infinite(), 0 );
+    helper.CheckNodeUV( F, tgtNode, uv, 1e-10, /*force=*/true );
+    _pos.back().SetCoord( uv.X(), uv.Y(), 0 );
+
+    newPos = surface->Value( uv.X(), uv.Y() );
+    tgtNode->setXYZ( newPos.X(), newPos.Y(), newPos.Z() );
+  }
+
+  if ( _curvature && lenDelta < 0 )
+  {
+    gp_Pnt prevPos( _pos[ _pos.size()-2 ]);
+    _len -= prevPos.Distance( oldPos );
+    _len += prevPos.Distance( newPos );
+  }
+  bool moved = distNewOld > dist01/50;
+  //if ( moved )
+  dumpMove( tgtNode ); // debug
+
+  return moved;
+}
+
+//================================================================================
+/*!
+ * \brief Perform laplacian smooth in 3D of nodes inflated from FACE
+ *  \retval bool - true if _tgtNode has been moved
+ */
+//================================================================================
+
+bool _LayerEdge::Smooth(int& badNb)
+{
+  if ( _simplices.size() < 2 )
+    return false; // _LayerEdge inflated along EDGE or FACE
+
+  // compute new position for the last _pos
+  gp_XYZ newPos (0,0,0);
+  for ( unsigned i = 0; i < _simplices.size(); ++i )
+    newPos += SMESH_TNodeXYZ( _simplices[i]._nPrev );
+  newPos /= _simplices.size();
+
+  if ( _curvature )
+    newPos += _normal * _curvature->lenDelta( _len );
+
+  gp_Pnt prevPos( _pos[ _pos.size()-2 ]);
+//   if ( _cosin < -0.1)
+//   {
+//     // Avoid decreasing length of edge on concave surface
+//     //gp_Vec oldMove( _pos[ _pos.size()-2 ], _pos.back() );
+//     gp_Vec newMove( prevPos, newPos );
+//     newPos = _pos.back() + newMove.XYZ();
+//   }
+//   else if ( _cosin > 0.3 )
+//   {
+//     // Avoid increasing length of edge too much
+
+//   }
+  // count quality metrics (orientation) of tetras around _tgtNode
+  int nbOkBefore = 0;
+  SMESH_TNodeXYZ tgtXYZ( _nodes.back() );
+  for ( unsigned i = 0; i < _simplices.size(); ++i )
+    nbOkBefore += _simplices[i].IsForward( _nodes[0], &tgtXYZ );
+
+  int nbOkAfter = 0;
+  for ( unsigned i = 0; i < _simplices.size(); ++i )
+    nbOkAfter += _simplices[i].IsForward( _nodes[0], &newPos );
+
+  if ( nbOkAfter < nbOkBefore )
+    return false;
+
+  SMDS_MeshNode* n = const_cast< SMDS_MeshNode* >( _nodes.back() );
+
+  _len -= prevPos.Distance(SMESH_TNodeXYZ( n ));
+  _len += prevPos.Distance(newPos);
+
+  n->setXYZ( newPos.X(), newPos.Y(), newPos.Z());
+  _pos.back() = newPos;
+
+  badNb += _simplices.size() - nbOkAfter;
+
+  dumpMove( n );
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Add a new segment to _LayerEdge during inflation
+ */
+//================================================================================
+
+void _LayerEdge::SetNewLength( double len, SMESH_MesherHelper& helper )
+{
+  if ( _len - len > -1e-6 )
+  {
+    _pos.push_back( _pos.back() );
+    return;
+  }
+
+  SMDS_MeshNode* n = const_cast< SMDS_MeshNode*>( _nodes.back() );
+  SMESH_TNodeXYZ oldXYZ( n );
+  gp_XYZ nXYZ = oldXYZ + _normal * ( len - _len ) * _lenFactor;
+  n->setXYZ( nXYZ.X(), nXYZ.Y(), nXYZ.Z() );
+
+  _pos.push_back( nXYZ );
+  _len = len;
+  if ( !_sWOL.IsNull() )
+  {
+    double distXYZ[4];
+    if ( _sWOL.ShapeType() == TopAbs_EDGE )
+    {
+      double u = Precision::Infinite(); // to force projection w/o distance check
+      helper.CheckNodeU( TopoDS::Edge( _sWOL ), n, u, 1e-10, /*force=*/true, distXYZ );
+      _pos.back().SetCoord( u, 0, 0 );
+      SMDS_EdgePosition* pos = static_cast<SMDS_EdgePosition*>( n->GetPosition() );
+      pos->SetUParameter( u );
+    }
+    else //  TopAbs_FACE
+    {
+      gp_XY uv( Precision::Infinite(), 0 );
+      helper.CheckNodeUV( TopoDS::Face( _sWOL ), n, uv, 1e-10, /*force=*/true, distXYZ );
+      _pos.back().SetCoord( uv.X(), uv.Y(), 0 );
+      SMDS_FacePosition* pos = static_cast<SMDS_FacePosition*>( n->GetPosition() );
+      pos->SetUParameter( uv.X() );
+      pos->SetVParameter( uv.Y() );
+    }
+    n->setXYZ( distXYZ[1], distXYZ[2], distXYZ[3]);
+  }
+  dumpMove( n ); //debug
+}
+
+//================================================================================
+/*!
+ * \brief Remove last inflation step
+ */
+//================================================================================
+
+void _LayerEdge::InvalidateStep( int curStep )
+{
+  if ( _pos.size() > curStep )
+  {
+    _pos.resize( curStep );
+    gp_Pnt nXYZ = _pos.back();
+    SMDS_MeshNode* n = const_cast< SMDS_MeshNode*>( _nodes.back() );
+    if ( !_sWOL.IsNull() )
+    {
+      TopLoc_Location loc;
+      if ( _sWOL.ShapeType() == TopAbs_EDGE )
+      {
+        SMDS_EdgePosition* pos = static_cast<SMDS_EdgePosition*>( n->GetPosition() );
+        pos->SetUParameter( nXYZ.X() );
+        double f,l;
+        Handle(Geom_Curve) curve = BRep_Tool::Curve( TopoDS::Edge( _sWOL ), loc, f,l);
+        nXYZ = curve->Value( nXYZ.X() ).Transformed( loc );
+      }
+      else
+      {
+        SMDS_FacePosition* pos = static_cast<SMDS_FacePosition*>( n->GetPosition() );
+        pos->SetUParameter( nXYZ.X() );
+        pos->SetVParameter( nXYZ.Y() );
+        Handle(Geom_Surface) surface = BRep_Tool::Surface( TopoDS::Face(_sWOL), loc );
+        nXYZ = surface->Value( nXYZ.X(), nXYZ.Y() ).Transformed( loc );
+      }
+    }
+    n->setXYZ( nXYZ.X(), nXYZ.Y(), nXYZ.Z() );
+    dumpMove( n );
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Create layers of prisms
+ */
+//================================================================================
+
+bool _ViscousBuilder::refine(_SolidData& data)
+{
+  SMESH_MesherHelper helper( *_mesh );
+  helper.SetSubShape( data._solid );
+  helper.SetElementsOnShape(false);
+
+  Handle(Geom_Curve) curve;
+  Handle(Geom_Surface) surface;
+  TopoDS_Edge geomEdge;
+  TopoDS_Face geomFace;
+  TopLoc_Location loc;
+  double f,l, u/*, distXYZ[4]*/;
+  gp_XY uv;
+  bool isOnEdge;
+
+  for ( unsigned i = 0; i < data._edges.size(); ++i )
+  {
+    _LayerEdge& edge = *data._edges[i];
+
+    // get accumulated length of segments
+    vector< double > segLen( edge._pos.size() );
+    segLen[0] = 0.0;
+    for ( unsigned j = 1; j < edge._pos.size(); ++j )
+      segLen[j] = segLen[j-1] + (edge._pos[j-1] - edge._pos[j] ).Modulus();
+
+    // allocate memory for new nodes if it is not yet refined
+    const SMDS_MeshNode* tgtNode = edge._nodes.back();
+    if ( edge._nodes.size() == 2 )
+    {
+      edge._nodes.resize( data._hyp->GetNumberLayers() + 1, 0 );
+      edge._nodes[1] = 0;
+      edge._nodes.back() = tgtNode;
+    }
+    if ( !edge._sWOL.IsNull() )
+    {
+      isOnEdge = ( edge._sWOL.ShapeType() == TopAbs_EDGE );
+      // restore position of the last node
+//       gp_Pnt p;
+      if ( isOnEdge )
+      {
+        geomEdge = TopoDS::Edge( edge._sWOL );
+        curve = BRep_Tool::Curve( geomEdge, loc, f,l);
+//         double u = helper.GetNodeU( tgtNode );
+//         p = curve->Value( u );
+      }
+      else
+      {
+        geomFace = TopoDS::Face( edge._sWOL );
+        surface = BRep_Tool::Surface( geomFace, loc );
+//         gp_XY uv = helper.GetNodeUV( tgtNode );
+//         p = surface->Value( uv.X(), uv.Y() );
+      }
+//       p.Transform( loc );
+//       const_cast< SMDS_MeshNode* >( tgtNode )->setXYZ( p.X(), p.Y(), p.Z() );
+    }
+    // calculate height of the first layer
+    double h0;
+    const double T = segLen.back(); //data._hyp.GetTotalThickness();
+    const double f = data._hyp->GetStretchFactor();
+    const int    N = data._hyp->GetNumberLayers();
+    const double fPowN = pow( f, N );
+    if ( fPowN - 1 <= numeric_limits<double>::min() )
+      h0 = T / N;
+    else
+      h0 = T * ( f - 1 )/( fPowN - 1 );
+
+    const double zeroLen = std::numeric_limits<double>::min();
+
+    // create intermediate nodes
+    double hSum = 0, hi = h0/f;
+    unsigned iSeg = 1;
+    for ( unsigned iStep = 1; iStep < edge._nodes.size(); ++iStep )
+    {
+      // compute an intermediate position
+      hi *= f;
+      hSum += hi;
+      while ( hSum > segLen[iSeg] && iSeg < segLen.size()-1)
+        ++iSeg;
+      int iPrevSeg = iSeg-1;
+      while ( fabs( segLen[iPrevSeg] - segLen[iSeg]) <= zeroLen && iPrevSeg > 0 )
+        --iPrevSeg;
+      double r = ( segLen[iSeg] - hSum ) / ( segLen[iSeg] - segLen[iPrevSeg] );
+      gp_Pnt pos = r * edge._pos[iPrevSeg] + (1-r) * edge._pos[iSeg];
+
+      SMDS_MeshNode*& node = const_cast< SMDS_MeshNode*& >(edge._nodes[ iStep ]);
+      if ( !edge._sWOL.IsNull() )
+      {
+        // compute XYZ by parameters <pos>
+        if ( isOnEdge )
+        {
+          u = pos.X();
+          pos = curve->Value( u ).Transformed(loc);
+        }
+        else
+        {
+          uv.SetCoord( pos.X(), pos.Y() );
+          pos = surface->Value( pos.X(), pos.Y() ).Transformed(loc);
+        }
+      }
+      // create or update the node
+      if ( !node )
+      {
+        node = helper.AddNode( pos.X(), pos.Y(), pos.Z());
+        if ( !edge._sWOL.IsNull() )
+        {
+          if ( isOnEdge )
+            getMeshDS()->SetNodeOnEdge( node, geomEdge, u );
+          else
+            getMeshDS()->SetNodeOnFace( node, geomFace, uv.X(), uv.Y() );
+        }
+        else
+        {
+          getMeshDS()->SetNodeInVolume( node, helper.GetSubShapeID() );
+        }
+      }
+      else
+      {
+        if ( !edge._sWOL.IsNull() )
+        {
+          // make average pos from new and current parameters
+          if ( isOnEdge )
+          {
+            u = 0.5 * ( u + helper.GetNodeU( geomEdge, node ));
+            pos = curve->Value( u ).Transformed(loc);
+          }
+          else
+          {
+            uv = 0.5 * ( uv + helper.GetNodeUV( geomFace, node ));
+            pos = surface->Value( uv.X(), uv.Y()).Transformed(loc);
+          }
+        }
+        node->setXYZ( pos.X(), pos.Y(), pos.Z() );
+      }
+    }
+  }
+
+  // TODO: make quadratic prisms and polyhedrons(?)
+
+  helper.SetElementsOnShape(true);
+
+  TopExp_Explorer exp( data._solid, TopAbs_FACE );
+  for ( ; exp.More(); exp.Next() )
+  {
+    if ( _ignoreShapeIds.count( getMeshDS()->ShapeToIndex( exp.Current() )))
+      continue;
+    SMESHDS_SubMesh* fSubM = getMeshDS()->MeshElements( exp.Current() );
+    SMDS_ElemIteratorPtr fIt = fSubM->GetElements();
+    vector< vector<const SMDS_MeshNode*>* > nnVec;
+    while ( fIt->more() )
+    {
+      const SMDS_MeshElement* face = fIt->next();
+      int nbNodes = face->NbCornerNodes();
+      nnVec.resize( nbNodes );
+      SMDS_ElemIteratorPtr nIt = face->nodesIterator();
+      for ( int iN = 0; iN < nbNodes; ++iN )
+      {
+        const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nIt->next() );
+        nnVec[ iN ] = & data._n2eMap[ n ]->_nodes;
+      }
+
+      int nbZ = nnVec[0]->size();
+      switch ( nbNodes )
+      {
+      case 3:
+        for ( int iZ = 1; iZ < nbZ; ++iZ )
+          helper.AddVolume( (*nnVec[0])[iZ-1], (*nnVec[1])[iZ-1], (*nnVec[2])[iZ-1],
+                            (*nnVec[0])[iZ],   (*nnVec[1])[iZ],   (*nnVec[2])[iZ]);
+        break;
+      case 4:
+        for ( int iZ = 1; iZ < nbZ; ++iZ )
+          helper.AddVolume( (*nnVec[0])[iZ-1], (*nnVec[1])[iZ-1],
+                            (*nnVec[2])[iZ-1], (*nnVec[3])[iZ-1],
+                            (*nnVec[0])[iZ],   (*nnVec[1])[iZ],
+                            (*nnVec[2])[iZ],   (*nnVec[3])[iZ]);
+        break;
+      default:
+        return error("Not supported type of element", data._index);
+      }
+    }
+  }
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Shrink 2D mesh on faces to let space for inflated layers
+ */
+//================================================================================
+
+bool _ViscousBuilder::shrink()
+{
+  // make map of (ids of FACEs to shrink mesh on) to (_SolidData containing _LayerEdge's
+  // inflated along FACE or EDGE)
+  map< TGeomID, _SolidData* > f2sdMap;
+  for ( unsigned i = 0 ; i < _sdVec.size(); ++i )
+  {
+    _SolidData& data = _sdVec[i];
+    TopTools_MapOfShape FFMap;
+    map< TGeomID, TopoDS_Shape >::iterator s2s = data._shrinkShape2Shape.begin();
+    for (; s2s != data._shrinkShape2Shape.end(); ++s2s )
+      if ( s2s->second.ShapeType() == TopAbs_FACE )
+      {
+        f2sdMap.insert( make_pair( getMeshDS()->ShapeToIndex( s2s->second ), &data ));
+
+        if ( FFMap.Add( (*s2s).second ))
+          // Put mesh faces on the shrinked FACE to the proxy sub-mesh to avoid
+          // usage of mesh faces made in addBoundaryElements() by the 3D algo or
+          // by StdMeshers_QuadToTriaAdaptor
+          if ( SMESHDS_SubMesh* smDS = getMeshDS()->MeshElements( s2s->second ))
+          {
+            SMESH_ProxyMesh::SubMesh* proxySub =
+              data._proxyMesh->getFaceSubM( TopoDS::Face( s2s->second ), /*create=*/true);
+            SMDS_ElemIteratorPtr fIt = smDS->GetElements();
+            while ( fIt->more() )
+              proxySub->AddElement( fIt->next() );
+            // as a result 3D algo will use elements from proxySub and not from smDS
+          }
+      }
+  }
+
+  SMESH_MesherHelper helper( *_mesh );
+  helper.ToFixNodeParameters( true );
+
+  // EDGE's to shrink
+  map< int, _Shrinker1D > e2shrMap;
+
+  // loop on FACES to srink mesh on
+  map< TGeomID, _SolidData* >::iterator f2sd = f2sdMap.begin();
+  for ( ; f2sd != f2sdMap.end(); ++f2sd )
+  {
+    _SolidData&     data = *f2sd->second;
+    TNode2Edge&   n2eMap = data._n2eMap;
+    const TopoDS_Face& F = TopoDS::Face( getMeshDS()->IndexToShape( f2sd->first ));
+
+    Handle(Geom_Surface) surface = BRep_Tool::Surface(F);
+
+    SMESH_subMesh*     sm = _mesh->GetSubMesh( F );
+    SMESHDS_SubMesh* smDS = sm->GetSubMeshDS();
+
+    helper.SetSubShape(F);
+
+    // ===========================
+    // Prepare data for shrinking
+    // ===========================
+
+    // Collect nodes to smooth, as src nodes are not yet replaced by tgt ones
+    // and thus all nodes on a FACE connected to 2d elements are to be smoothed
+    vector < const SMDS_MeshNode* > smoothNodes;
+    {
+      SMDS_NodeIteratorPtr nIt = smDS->GetNodes();
+      while ( nIt->more() )
+      {
+        const SMDS_MeshNode* n = nIt->next();
+        if ( n->NbInverseElements( SMDSAbs_Face ) > 0 )
+          smoothNodes.push_back( n );
+      }
+    }
+    // Find out face orientation
+    double refSign = 1;
+    const set<TGeomID> ignoreShapes;
+    bool isOkUV;
+    if ( !smoothNodes.empty() )
+    {
+      vector<_Simplex> simplices;
+      getSimplices( smoothNodes[0], simplices, ignoreShapes );
+      helper.GetNodeUV( F, simplices[0]._nPrev, 0, &isOkUV ); // fix UV of silpmex nodes
+      helper.GetNodeUV( F, simplices[0]._nNext, 0, &isOkUV );
+      gp_XY uv = helper.GetNodeUV( F, smoothNodes[0], 0, &isOkUV );
+      if ( !simplices[0].IsForward(uv, smoothNodes[0], F, helper,refSign) )
+        refSign = -1;
+    }
+
+    // Find _LayerEdge's inflated along F
+    vector< _LayerEdge* > lEdges;
+    {
+      SMESH_subMeshIteratorPtr subIt =
+        sm->getDependsOnIterator(/*includeSelf=*/false, /*complexShapeFirst=*/false);
+      while ( subIt->more() )
+      {
+        SMESH_subMesh* sub = subIt->next();
+        SMESHDS_SubMesh* subDS = sub->GetSubMeshDS();
+        if ( subDS->NbNodes() == 0 || !n2eMap.count( subDS->GetNodes()->next() ))
+          continue;
+        SMDS_NodeIteratorPtr nIt = subDS->GetNodes();
+        while ( nIt->more() )
+        {
+          _LayerEdge* edge = n2eMap[ nIt->next() ];
+          lEdges.push_back( edge );
+          prepareEdgeToShrink( *edge, F, helper, smDS );
+        }
+      }
+    }
+
+    // Replace source nodes by target nodes in mesh faces to shrink
+    const SMDS_MeshNode* nodes[20];
+    for ( unsigned i = 0; i < lEdges.size(); ++i )
+    {
+      _LayerEdge& edge = *lEdges[i];
+      const SMDS_MeshNode* srcNode = edge._nodes[0];
+      const SMDS_MeshNode* tgtNode = edge._nodes.back();
+      SMDS_ElemIteratorPtr fIt = srcNode->GetInverseElementIterator(SMDSAbs_Face);
+      while ( fIt->more() )
+      {
+        const SMDS_MeshElement* f = fIt->next();
+        if ( !smDS->Contains( f ))
+          continue;
+        SMDS_ElemIteratorPtr nIt = f->nodesIterator();
+        for ( int iN = 0; iN < f->NbNodes(); ++iN )
+        {
+          const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nIt->next() );
+          nodes[iN] = ( n == srcNode ? tgtNode : n );
+        }
+        helper.GetMeshDS()->ChangeElementNodes( f, nodes, f->NbNodes() );
+      }
+    }
+
+    // find out if a FACE is concave
+    const bool isConcaveFace = isConcave( F, helper );
+
+    // Create _SmoothNode's on face F
+    vector< _SmoothNode > nodesToSmooth( smoothNodes.size() );
+    {
+      dumpFunction(SMESH_Comment("beforeShrinkFace")<<f2sd->first); // debug
+      for ( unsigned i = 0; i < smoothNodes.size(); ++i )
+      {
+        const SMDS_MeshNode* n = smoothNodes[i];
+        nodesToSmooth[ i ]._node = n;
+        // src nodes must be replaced by tgt nodes to have tgt nodes in _simplices
+        getSimplices( n, nodesToSmooth[ i ]._simplices, ignoreShapes, NULL, isConcaveFace );
+        // fix up incorrect uv of nodes on the FACE
+        helper.GetNodeUV( F, n, 0, &isOkUV);
+        dumpMove( n );
+      }
+      dumpFunctionEnd();
+    }
+    //if ( nodesToSmooth.empty() ) continue;
+
+    // Find EDGE's to shrink
+    set< _Shrinker1D* > eShri1D;
+    {
+      for ( unsigned i = 0; i < lEdges.size(); ++i )
+      {
+        _LayerEdge* edge = lEdges[i];
+        if ( edge->_sWOL.ShapeType() == TopAbs_EDGE )
+        {
+          TGeomID edgeIndex = getMeshDS()->ShapeToIndex( edge->_sWOL );
+          _Shrinker1D& srinker = e2shrMap[ edgeIndex ];
+          eShri1D.insert( & srinker );
+          srinker.AddEdge( edge, helper );
+          // restore params of nodes on EGDE if the EDGE has been already
+          // srinked while srinking another FACE
+          srinker.RestoreParams();
+        }
+      }
+    }
+
+    // ==================
+    // Perform shrinking
+    // ==================
+
+    bool shrinked = true;
+    int badNb, shriStep=0, smooStep=0;
+    while ( shrinked )
+    {
+      // Move boundary nodes (actually just set new UV)
+      // -----------------------------------------------
+      dumpFunction(SMESH_Comment("moveBoundaryOnF")<<f2sd->first<<"_st"<<shriStep++ ); // debug
+      shrinked = false;
+      for ( unsigned i = 0; i < lEdges.size(); ++i )
+      {
+        shrinked |= lEdges[i]->SetNewLength2d( surface,F,helper );
+      }
+      dumpFunctionEnd();
+
+      // Move nodes on EDGE's
+      set< _Shrinker1D* >::iterator shr = eShri1D.begin();
+      for ( ; shr != eShri1D.end(); ++shr )
+        (*shr)->Compute( /*set3D=*/false, helper );
+
+      // Smoothing in 2D
+      // -----------------
+      int nbNoImpSteps = 0;
+      bool moved = true;
+      badNb = 1;
+      while (( nbNoImpSteps < 5 && badNb > 0) && moved)
+      {
+        dumpFunction(SMESH_Comment("shrinkFace")<<f2sd->first<<"_st"<<++smooStep); // debug
+
+        int oldBadNb = badNb;
+        badNb = 0;
+        moved = false;
+        for ( unsigned i = 0; i < nodesToSmooth.size(); ++i )
+        {
+          moved |= nodesToSmooth[i].Smooth( badNb,surface,helper,refSign,
+                                            /*isCentroidal=*/isConcaveFace,/*set3D=*/false );
+        }
+        if ( badNb < oldBadNb )
+          nbNoImpSteps = 0;
+        else
+          nbNoImpSteps++;
+
+        dumpFunctionEnd();
+      }
+      if ( badNb > 0 )
+        return error(SMESH_Comment("Can't shrink 2D mesh on face ") << f2sd->first );
+    }
+    // No wrongly shaped faces remain; final smooth. Set node XYZ.
+    // First, find out a needed quality of smoothing (high for quadrangles only)
+    bool highQuality;
+    {
+      const bool hasTria = _mesh->NbTriangles(), hasQuad = _mesh->NbQuadrangles();
+      if ( hasTria != hasQuad )
+      {
+        highQuality = hasQuad;
+      }
+      else
+      {
+        set<int> nbNodesSet;
+        SMDS_ElemIteratorPtr fIt = smDS->GetElements();
+        while ( fIt->more() && nbNodesSet.size() < 2 )
+          nbNodesSet.insert( fIt->next()->NbCornerNodes() );
+        highQuality = ( *nbNodesSet.begin() == 4 );
+      }
+    }
+    if ( !highQuality && isConcaveFace )
+      fixBadFaces( F, helper ); // fix narrow faces by swaping diagonals
+    for ( int st = highQuality ? 10 : 3; st; --st )
+    {
+      dumpFunction(SMESH_Comment("shrinkFace")<<f2sd->first<<"_st"<<++smooStep); // debug
+      for ( unsigned i = 0; i < nodesToSmooth.size(); ++i )
+        nodesToSmooth[i].Smooth( badNb,surface,helper,refSign,
+                                 /*isCentroidal=*/isConcaveFace,/*set3D=*/st==1 );
+      dumpFunctionEnd();
+    }
+    // Set an event listener to clear FACE sub-mesh together with SOLID sub-mesh
+    _SrinkShapeListener::ToClearSubMeshWithSolid( sm, data._solid );
+
+  } // loop on FACES to srink mesh on
+
+
+  // Replace source nodes by target nodes in shrinked mesh edges
+
+  map< int, _Shrinker1D >::iterator e2shr = e2shrMap.begin();
+  for ( ; e2shr != e2shrMap.end(); ++e2shr )
+    e2shr->second.SwapSrcTgtNodes( getMeshDS() );
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Computes 2d shrink direction and finds nodes limiting shrinking
+ */
+//================================================================================
+
+bool _ViscousBuilder::prepareEdgeToShrink( _LayerEdge&            edge,
+                                           const TopoDS_Face&     F,
+                                           SMESH_MesherHelper&    helper,
+                                           const SMESHDS_SubMesh* faceSubMesh)
+{
+  const SMDS_MeshNode* srcNode = edge._nodes[0];
+  const SMDS_MeshNode* tgtNode = edge._nodes.back();
+
+  edge._pos.clear();
+
+  if ( edge._sWOL.ShapeType() == TopAbs_FACE )
+  {
+    gp_XY srcUV = helper.GetNodeUV( F, srcNode );
+    gp_XY tgtUV = helper.GetNodeUV( F, tgtNode );
+    gp_Vec2d uvDir( srcUV, tgtUV );
+    double uvLen = uvDir.Magnitude();
+    uvDir /= uvLen;
+    edge._normal.SetCoord( uvDir.X(),uvDir.Y(), 0);
+
+    // IMPORTANT to have src nodes NOT yet REPLACED by tgt nodes in shrinked faces
+    vector<const SMDS_MeshElement*> faces;
+    multimap< double, const SMDS_MeshNode* > proj2node;
+    SMDS_ElemIteratorPtr fIt = srcNode->GetInverseElementIterator(SMDSAbs_Face);
+    while ( fIt->more() )
+    {
+      const SMDS_MeshElement* f = fIt->next();
+      if ( faceSubMesh->Contains( f ))
+        faces.push_back( f );
+    }
+    for ( unsigned i = 0; i < faces.size(); ++i )
+    {
+      const int nbNodes = faces[i]->NbCornerNodes();
+      for ( int j = 0; j < nbNodes; ++j )
+      {
+        const SMDS_MeshNode* n = faces[i]->GetNode(j);
+        if ( n == srcNode ) continue;
+        if ( n->GetPosition()->GetTypeOfPosition() != SMDS_TOP_FACE &&
+             ( faces.size() > 1 || nbNodes > 3 ))
+          continue;
+        gp_Pnt2d uv = helper.GetNodeUV( F, n );
+        gp_Vec2d uvDirN( srcUV, uv );
+        double proj = uvDirN * uvDir;
+        proj2node.insert( make_pair( proj, n ));
+      }
+    }
+
+    multimap< double, const SMDS_MeshNode* >::iterator p2n = proj2node.begin(), p2nEnd;
+    const double minProj = p2n->first;
+    const double projThreshold = 1.1 * uvLen;
+    if ( minProj > projThreshold )
+    {
+      // tgtNode is located so that it does not make faces with wrong orientation
+      return true;
+    }
+    edge._pos.resize(1);
+    edge._pos[0].SetCoord( tgtUV.X(), tgtUV.Y(), 0 );
+
+    // store most risky nodes in _simplices
+    p2nEnd = proj2node.lower_bound( projThreshold );
+    int nbSimpl = ( std::distance( p2n, p2nEnd ) + 1) / 2;
+    edge._simplices.resize( nbSimpl );
+    for ( int i = 0; i < nbSimpl; ++i )
+    {
+      edge._simplices[i]._nPrev = p2n->second;
+      if ( ++p2n != p2nEnd )
+        edge._simplices[i]._nNext = p2n->second;
+    }
+    // set UV of source node to target node
+    SMDS_FacePosition* pos = static_cast<SMDS_FacePosition*>( tgtNode->GetPosition() );
+    pos->SetUParameter( srcUV.X() );
+    pos->SetVParameter( srcUV.Y() );
+  }
+  else // _sWOL is TopAbs_EDGE
+  {
+    TopoDS_Edge E = TopoDS::Edge( edge._sWOL);
+    SMESHDS_SubMesh* edgeSM = getMeshDS()->MeshElements( E );
+    if ( !edgeSM || edgeSM->NbElements() == 0 )
+      return error(SMESH_Comment("Not meshed EDGE ") << getMeshDS()->ShapeToIndex( E ));
+
+    const SMDS_MeshNode* n2 = 0;
+    SMDS_ElemIteratorPtr eIt = srcNode->GetInverseElementIterator(SMDSAbs_Edge);
+    while ( eIt->more() && !n2 )
+    {
+      const SMDS_MeshElement* e = eIt->next();
+      if ( !edgeSM->Contains(e)) continue;
+      n2 = e->GetNode( 0 );
+      if ( n2 == srcNode ) n2 = e->GetNode( 1 );
+    }
+    if ( !n2 )
+      return error(SMESH_Comment("Wrongly meshed EDGE ") << getMeshDS()->ShapeToIndex( E ));
+
+    double uSrc = helper.GetNodeU( E, srcNode, n2 );
+    double uTgt = helper.GetNodeU( E, tgtNode, srcNode );
+    double u2   = helper.GetNodeU( E, n2,      srcNode );
+
+    if ( fabs( uSrc-uTgt ) < 0.99 * fabs( uSrc-u2 ))
+    {
+      // tgtNode is located so that it does not make faces with wrong orientation
+      return true;
+    }
+    edge._pos.resize(1);
+    edge._pos[0].SetCoord( U_TGT, uTgt );
+    edge._pos[0].SetCoord( U_SRC, uSrc );
+    edge._pos[0].SetCoord( LEN_TGT, fabs( uSrc-uTgt ));
+
+    edge._simplices.resize( 1 );
+    edge._simplices[0]._nPrev = n2;
+
+    // set UV of source node to target node
+    SMDS_EdgePosition* pos = static_cast<SMDS_EdgePosition*>( tgtNode->GetPosition() );
+    pos->SetUParameter( uSrc );
+  }
+  return true;
+
+  //================================================================================
+  /*!
+   * \brief Compute positions (UV) to set to a node on edge moved during shrinking
+   */
+  //================================================================================
+  
+  // Compute UV to follow during shrinking
+
+//   const SMDS_MeshNode* srcNode = edge._nodes[0];
+//   const SMDS_MeshNode* tgtNode = edge._nodes.back();
+
+//   gp_XY srcUV = helper.GetNodeUV( F, srcNode );
+//   gp_XY tgtUV = helper.GetNodeUV( F, tgtNode );
+//   gp_Vec2d uvDir( srcUV, tgtUV );
+//   double uvLen = uvDir.Magnitude();
+//   uvDir /= uvLen;
+
+//   // Select shrinking step such that not to make faces with wrong orientation.
+//   // IMPORTANT to have src nodes NOT yet REPLACED by tgt nodes in shrinked faces
+//   const double minStepSize = uvLen / 20;
+//   double stepSize = uvLen;
+//   SMDS_ElemIteratorPtr fIt = srcNode->GetInverseElementIterator(SMDSAbs_Face);
+//   while ( fIt->more() )
+//   {
+//     const SMDS_MeshElement* f = fIt->next();
+//     if ( !faceSubMesh->Contains( f )) continue;
+//     const int nbNodes = f->NbCornerNodes();
+//     for ( int i = 0; i < nbNodes; ++i )
+//     {
+//       const SMDS_MeshNode* n = f->GetNode(i);
+//       if ( n->GetPosition()->GetTypeOfPosition() != SMDS_TOP_FACE || n == srcNode)
+//         continue;
+//       gp_XY uv = helper.GetNodeUV( F, n );
+//       gp_Vec2d uvDirN( srcUV, uv );
+//       double proj = uvDirN * uvDir;
+//       if ( proj < stepSize && proj > minStepSize )
+//         stepSize = proj;
+//     }
+//   }
+//   stepSize *= 0.8;
+
+//   const int nbSteps = ceil( uvLen / stepSize );
+//   gp_XYZ srcUV0( srcUV.X(), srcUV.Y(), 0 );
+//   gp_XYZ tgtUV0( tgtUV.X(), tgtUV.Y(), 0 );
+//   edge._pos.resize( nbSteps );
+//   edge._pos[0] = tgtUV0;
+//   for ( int i = 1; i < nbSteps; ++i )
+//   {
+//     double r = i / double( nbSteps );
+//     edge._pos[i] = (1-r) * tgtUV0 + r * srcUV0;
+//   }
+//   return true;
+}
+
+//================================================================================
+/*!
+ * \brief Try to fix triangles with high aspect ratio by swaping diagonals
+ */
+//================================================================================
+
+void _ViscousBuilder::fixBadFaces(const TopoDS_Face& F, SMESH_MesherHelper& helper)
+{
+  SMESH::Controls::AspectRatio qualifier;
+  SMESH::Controls::TSequenceOfXYZ points(3), points1(3), points2(3);
+  const double maxAspectRatio = 4.;
+
+  // find bad triangles
+
+  vector< const SMDS_MeshElement* > badTrias;
+  vector< double >                  badAspects;
+  SMESHDS_SubMesh* sm = helper.GetMeshDS()->MeshElements( F );
+  SMDS_ElemIteratorPtr fIt = sm->GetElements();
+  while ( fIt->more() )
+  {
+    const SMDS_MeshElement * f = fIt->next();
+    if ( f->NbCornerNodes() != 3 ) continue;
+    for ( int iP = 0; iP < 3; ++iP ) points(iP+1) = SMESH_TNodeXYZ( f->GetNode(iP));
+    double aspect = qualifier.GetValue( points );
+    if ( aspect > maxAspectRatio )
+    {
+      badTrias.push_back( f );
+      badAspects.push_back( aspect );
+    }
+  }
+  if ( badTrias.empty() )
+    return;
+
+  // find couples of faces to swap diagonal
+
+  typedef pair < const SMDS_MeshElement* , const SMDS_MeshElement* > T2Trias;
+  vector< T2Trias > triaCouples; 
+
+  TIDSortedElemSet involvedFaces, emptySet;
+  for ( size_t iTia = 0; iTia < badTrias.size(); ++iTia )
+  {
+    T2Trias trias    [3];
+    double  aspRatio [3];
+    int i1, i2, i3;
+
+    involvedFaces.insert( badTrias[iTia] );
+    for ( int iP = 0; iP < 3; ++iP )
+      points(iP+1) = SMESH_TNodeXYZ( badTrias[iTia]->GetNode(iP));
+
+    // find triangles adjacent to badTrias[iTia] with better aspect ratio after diag-swaping
+    int bestCouple = -1;
+    for ( int iSide = 0; iSide < 3; ++iSide )
+    {
+      const SMDS_MeshNode* n1 = badTrias[iTia]->GetNode( iSide );
+      const SMDS_MeshNode* n2 = badTrias[iTia]->GetNode(( iSide+1 ) % 3 );
+      trias [iSide].first  = badTrias[iTia];
+      trias [iSide].second = SMESH_MeshEditor::FindFaceInSet( n1, n2, emptySet, involvedFaces,
+                                                              & i1, & i2 );
+      if ( ! trias[iSide].second || trias[iSide].second->NbCornerNodes() != 3 )
+        continue;
+
+      // aspect ratio of an adjacent tria
+      for ( int iP = 0; iP < 3; ++iP )
+        points2(iP+1) = SMESH_TNodeXYZ( trias[iSide].second->GetNode(iP));
+      double aspectInit = qualifier.GetValue( points2 );
+
+      // arrange nodes as after diag-swaping
+      if ( helper.WrapIndex( i1+1, 3 ) == i2 )
+        i3 = helper.WrapIndex( i1-1, 3 );
+      else
+        i3 = helper.WrapIndex( i1+1, 3 );
+      points1 = points;
+      points1( 1+ iSide ) = points2( 1+ i3 );
+      points2( 1+ i2    ) = points1( 1+ ( iSide+2 ) % 3 );
+
+      // aspect ratio after diag-swaping
+      aspRatio[ iSide ] = qualifier.GetValue( points1 ) + qualifier.GetValue( points2 );
+      if ( aspRatio[ iSide ] > aspectInit + badAspects[ iTia ] )
+        continue;
+
+      if ( bestCouple < 0 || aspRatio[ bestCouple ] > aspRatio[ iSide ] )
+        bestCouple = iSide;
+    }
+
+    if ( bestCouple >= 0 )
+    {
+      triaCouples.push_back( trias[bestCouple] );
+      involvedFaces.insert ( trias[bestCouple].second );
+    }
+    else
+    {
+      involvedFaces.erase( badTrias[iTia] );
+    }
+  }
+  if ( triaCouples.empty() )
+    return;
+
+  // swap diagonals
+
+  SMESH_MeshEditor editor( helper.GetMesh() );
+  dumpFunction(SMESH_Comment("beforeSwapDiagonals_F")<<helper.GetSubShapeID());
+  for ( size_t i = 0; i < triaCouples.size(); ++i )
+  {
+    dumpChangeNodes( triaCouples[i].first );
+    dumpChangeNodes( triaCouples[i].second );
+    editor.InverseDiag( triaCouples[i].first, triaCouples[i].second );
+  }
+  dumpFunctionEnd();
+
+  // just for debug dump resulting triangles
+  dumpFunction(SMESH_Comment("swapDiagonals_F")<<helper.GetSubShapeID());
+  for ( size_t i = 0; i < triaCouples.size(); ++i )
+  {
+    dumpChangeNodes( triaCouples[i].first );
+    dumpChangeNodes( triaCouples[i].second );
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Move target node to it's final position on the FACE during shrinking
+ */
+//================================================================================
+
+bool _LayerEdge::SetNewLength2d( Handle(Geom_Surface)& surface,
+                                 const TopoDS_Face&    F,
+                                 SMESH_MesherHelper&   helper )
+{
+  if ( _pos.empty() )
+    return false; // already at the target position
+
+  SMDS_MeshNode* tgtNode = const_cast< SMDS_MeshNode*& >( _nodes.back() );
+
+  if ( _sWOL.ShapeType() == TopAbs_FACE )
+  {
+    gp_XY    curUV = helper.GetNodeUV( F, tgtNode );
+    gp_Pnt2d tgtUV( _pos[0].X(), _pos[0].Y());
+    gp_Vec2d uvDir( _normal.X(), _normal.Y() );
+    const double uvLen = tgtUV.Distance( curUV );
+
+    // Select shrinking step such that not to make faces with wrong orientation.
+    const double kSafe = 0.8;
+    const double minStepSize = uvLen / 10;
+    double stepSize = uvLen;
+    for ( unsigned i = 0; i < _simplices.size(); ++i )
+    {
+      const SMDS_MeshNode* nn[2] = { _simplices[i]._nPrev, _simplices[i]._nNext };
+      for ( int j = 0; j < 2; ++j )
+        if ( const SMDS_MeshNode* n = nn[j] )
+        {
+          gp_XY uv = helper.GetNodeUV( F, n );
+          gp_Vec2d uvDirN( curUV, uv );
+          double proj = uvDirN * uvDir * kSafe;
+          if ( proj < stepSize && proj > minStepSize )
+            stepSize = proj;
+        }
+    }
+
+    gp_Pnt2d newUV;
+    if ( stepSize == uvLen )
+    {
+      newUV = tgtUV;
+      _pos.clear();
+    }
+    else
+    {
+      newUV = curUV + uvDir.XY() * stepSize;
+    }
+
+    SMDS_FacePosition* pos = static_cast<SMDS_FacePosition*>( tgtNode->GetPosition() );
+    pos->SetUParameter( newUV.X() );
+    pos->SetVParameter( newUV.Y() );
+
+#ifdef __myDEBUG
+    gp_Pnt p = surface->Value( newUV.X(), newUV.Y() );
+    tgtNode->setXYZ( p.X(), p.Y(), p.Z() );
+    dumpMove( tgtNode );
+#endif
+  }
+  else // _sWOL is TopAbs_EDGE
+  {
+    TopoDS_Edge E = TopoDS::Edge( _sWOL );
+    const SMDS_MeshNode* n2 = _simplices[0]._nPrev;
+
+    const double u2 = helper.GetNodeU( E, n2, tgtNode );
+    const double uSrc   = _pos[0].Coord( U_SRC );
+    const double lenTgt = _pos[0].Coord( LEN_TGT );
+
+    double newU = _pos[0].Coord( U_TGT );
+    if ( lenTgt < 0.99 * fabs( uSrc-u2 ))
+    {
+      _pos.clear();
+    }
+    else
+    {
+      newU = 0.1 * uSrc + 0.9 * u2;
+    }
+    SMDS_EdgePosition* pos = static_cast<SMDS_EdgePosition*>( tgtNode->GetPosition() );
+    pos->SetUParameter( newU );
+#ifdef __myDEBUG
+    gp_XY newUV = helper.GetNodeUV( F, tgtNode, _nodes[0]);
+    gp_Pnt p = surface->Value( newUV.X(), newUV.Y() );
+    tgtNode->setXYZ( p.X(), p.Y(), p.Z() );
+    dumpMove( tgtNode );
+#endif
+  }
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Perform smooth on the FACE
+ *  \retval bool - true if the node has been moved
+ */
+//================================================================================
+
+bool _SmoothNode::Smooth(int&                  badNb,
+                         Handle(Geom_Surface)& surface,
+                         SMESH_MesherHelper&   helper,
+                         const double          refSign,
+                         bool                  isCentroidal,
+                         bool                  set3D)
+{
+  const TopoDS_Face& face = TopoDS::Face( helper.GetSubShape() );
+
+  // get uv of surrounding nodes
+  vector<gp_XY> uv( _simplices.size() );
+  for ( size_t i = 0; i < _simplices.size(); ++i )
+    uv[i] = helper.GetNodeUV( face, _simplices[i]._nPrev, _node );
+
+  // compute new UV for the node
+  gp_XY newPos (0,0);
+  if ( isCentroidal && _simplices.size() > 3 )
+  {
+    // average centers of diagonals wieghted with their reciprocal lengths
+    if ( _simplices.size() == 4 )
+    {
+      double w1 = 1. / ( uv[2]-uv[0] ).SquareModulus();
+      double w2 = 1. / ( uv[3]-uv[1] ).SquareModulus();
+      newPos = ( w1 * ( uv[2]+uv[0] ) + w2 * ( uv[3]+uv[1] )) / ( w1+w2 ) / 2;
+    }
+    else
+    {
+      double sumWeight = 0;
+      int nb = _simplices.size() == 4 ? 2 : _simplices.size();
+      for ( int i = 0; i < nb; ++i )
+      {
+        int iFrom = i + 2;
+        int iTo   = i + _simplices.size() - 1;
+        for ( int j = iFrom; j < iTo; ++j )
+        {
+          int i2 = SMESH_MesherHelper::WrapIndex( j, _simplices.size() );
+          double w = 1. / ( uv[i]-uv[i2] ).SquareModulus();
+          sumWeight += w;
+          newPos += w * ( uv[i]+uv[i2] );
+        }
+      }
+      newPos /= 2 * sumWeight;
+    }
+  }
+  else
+  {
+    // Laplacian smooth
+    isCentroidal = false;
+    for ( size_t i = 0; i < _simplices.size(); ++i )
+      newPos += uv[i];
+    newPos /= _simplices.size();
+  }
+
+  // count quality metrics (orientation) of triangles around the node
+  int nbOkBefore = 0;
+  gp_XY tgtUV = helper.GetNodeUV( face, _node );
+  for ( unsigned i = 0; i < _simplices.size(); ++i )
+    nbOkBefore += _simplices[i].IsForward( tgtUV, _node, face, helper, refSign );
+
+  int nbOkAfter = 0;
+  for ( unsigned i = 0; i < _simplices.size(); ++i )
+    nbOkAfter += _simplices[i].IsForward( newPos, _node, face, helper, refSign );
+
+  if ( nbOkAfter < nbOkBefore )
+  {
+    // if ( isCentroidal )
+    //   return Smooth( badNb, surface, helper, refSign, !isCentroidal, set3D );
+    badNb += _simplices.size() - nbOkBefore;
+    return false;
+  }
+
+  SMDS_FacePosition* pos = static_cast<SMDS_FacePosition*>( _node->GetPosition() );
+  pos->SetUParameter( newPos.X() );
+  pos->SetVParameter( newPos.Y() );
+
+#ifdef __myDEBUG
+  set3D = true;
+#endif
+  if ( set3D )
+  {
+    gp_Pnt p = surface->Value( newPos.X(), newPos.Y() );
+    const_cast< SMDS_MeshNode* >( _node )->setXYZ( p.X(), p.Y(), p.Z() );
+    dumpMove( _node );
+  }
+
+  badNb += _simplices.size() - nbOkAfter;
+  return ( (tgtUV-newPos).SquareModulus() > 1e-10 );
+}
+
+//================================================================================
+/*!
+ * \brief Delete _SolidData
+ */
+//================================================================================
+
+_SolidData::~_SolidData()
+{
+  for ( unsigned i = 0; i < _edges.size(); ++i )
+  {
+    if ( _edges[i] && _edges[i]->_2neibors )
+      delete _edges[i]->_2neibors;
+    delete _edges[i];
+  }
+  _edges.clear();
+}
+//================================================================================
+/*!
+ * \brief Add a _LayerEdge inflated along the EDGE
+ */
+//================================================================================
+
+void _Shrinker1D::AddEdge( const _LayerEdge* e, SMESH_MesherHelper& helper )
+{
+  // init
+  if ( _nodes.empty() )
+  {
+    _edges[0] = _edges[1] = 0;
+    _done = false;
+  }
+  // check _LayerEdge
+  if ( e == _edges[0] || e == _edges[1] )
+    return;
+  if ( e->_sWOL.IsNull() || e->_sWOL.ShapeType() != TopAbs_EDGE )
+    throw SALOME_Exception(LOCALIZED("Wrong _LayerEdge is added"));
+  if ( _edges[0] && _edges[0]->_sWOL != e->_sWOL )
+    throw SALOME_Exception(LOCALIZED("Wrong _LayerEdge is added"));
+
+  // store _LayerEdge
+  const TopoDS_Edge& E = TopoDS::Edge( e->_sWOL );
+  double f,l;
+  BRep_Tool::Range( E, f,l );
+  double u = helper.GetNodeU( E, e->_nodes[0], e->_nodes.back());
+  _edges[ u < 0.5*(f+l) ? 0 : 1 ] = e;
+
+  // Update _nodes
+
+  const SMDS_MeshNode* tgtNode0 = _edges[0] ? _edges[0]->_nodes.back() : 0;
+  const SMDS_MeshNode* tgtNode1 = _edges[1] ? _edges[1]->_nodes.back() : 0;
+
+  if ( _nodes.empty() )
+  {
+    SMESHDS_SubMesh * eSubMesh = helper.GetMeshDS()->MeshElements( E );
+    if ( !eSubMesh || eSubMesh->NbNodes() < 1 )
+      return;
+    TopLoc_Location loc;
+    Handle(Geom_Curve) C = BRep_Tool::Curve(E, loc, f,l);
+    GeomAdaptor_Curve aCurve(C, f,l);
+    const double totLen = GCPnts_AbscissaPoint::Length(aCurve, f, l);
+
+    int nbExpectNodes = eSubMesh->NbNodes() - e->_nodes.size();
+    _initU  .reserve( nbExpectNodes );
+    _normPar.reserve( nbExpectNodes );
+    _nodes  .reserve( nbExpectNodes );
+    SMDS_NodeIteratorPtr nIt = eSubMesh->GetNodes();
+    while ( nIt->more() )
+    {
+      const SMDS_MeshNode* node = nIt->next();
+      if ( node->NbInverseElements(SMDSAbs_Edge) == 0 ||
+           node == tgtNode0 || node == tgtNode1 )
+        continue; // refinement nodes
+      _nodes.push_back( node );
+      _initU.push_back( helper.GetNodeU( E, node ));
+      double len = GCPnts_AbscissaPoint::Length(aCurve, f, _initU.back());
+      _normPar.push_back(  len / totLen );
+    }
+  }
+  else
+  {
+    // remove target node of the _LayerEdge from _nodes
+    int nbFound = 0;
+    for ( unsigned i = 0; i < _nodes.size(); ++i )
+      if ( !_nodes[i] || _nodes[i] == tgtNode0 || _nodes[i] == tgtNode1 )
+        _nodes[i] = 0, nbFound++;
+    if ( nbFound == _nodes.size() )
+      _nodes.clear();
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Move nodes on EDGE from ends where _LayerEdge's are inflated
+ */
+//================================================================================
+
+void _Shrinker1D::Compute(bool set3D, SMESH_MesherHelper& helper)
+{
+  if ( _done || _nodes.empty())
+    return;
+  const _LayerEdge* e = _edges[0];
+  if ( !e ) e = _edges[1];
+  if ( !e ) return;
+
+  _done =  (( !_edges[0] || _edges[0]->_pos.empty() ) &&
+            ( !_edges[1] || _edges[1]->_pos.empty() ));
+
+  const TopoDS_Edge& E = TopoDS::Edge( e->_sWOL );
+  double f,l;
+  if ( set3D || _done )
+  {
+    Handle(Geom_Curve) C = BRep_Tool::Curve(E, f,l);
+    GeomAdaptor_Curve aCurve(C, f,l);
+
+    if ( _edges[0] )
+      f = helper.GetNodeU( E, _edges[0]->_nodes.back(), _nodes[0] );
+    if ( _edges[1] )
+      l = helper.GetNodeU( E, _edges[1]->_nodes.back(), _nodes.back() );
+    double totLen = GCPnts_AbscissaPoint::Length( aCurve, f, l );
+
+    for ( unsigned i = 0; i < _nodes.size(); ++i )
+    {
+      if ( !_nodes[i] ) continue;
+      double len = totLen * _normPar[i];
+      GCPnts_AbscissaPoint discret( aCurve, len, f );
+      if ( !discret.IsDone() )
+        return throw SALOME_Exception(LOCALIZED("GCPnts_AbscissaPoint failed"));
+      double u = discret.Parameter();
+      SMDS_EdgePosition* pos = static_cast<SMDS_EdgePosition*>( _nodes[i]->GetPosition() );
+      pos->SetUParameter( u );
+      gp_Pnt p = C->Value( u );
+      const_cast< SMDS_MeshNode*>( _nodes[i] )->setXYZ( p.X(), p.Y(), p.Z() );
+    }
+  }
+  else
+  {
+    BRep_Tool::Range( E, f,l );
+    if ( _edges[0] )
+      f = helper.GetNodeU( E, _edges[0]->_nodes.back(), _nodes[0] );
+    if ( _edges[1] )
+      l = helper.GetNodeU( E, _edges[1]->_nodes.back(), _nodes.back() );
+    
+    for ( unsigned i = 0; i < _nodes.size(); ++i )
+    {
+      if ( !_nodes[i] ) continue;
+      double u = f * ( 1-_normPar[i] ) + l * _normPar[i];
+      SMDS_EdgePosition* pos = static_cast<SMDS_EdgePosition*>( _nodes[i]->GetPosition() );
+      pos->SetUParameter( u );
+    }
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Restore initial parameters of nodes on EDGE
+ */
+//================================================================================
+
+void _Shrinker1D::RestoreParams()
+{
+  if ( _done )
+    for ( unsigned i = 0; i < _nodes.size(); ++i )
+    {
+      if ( !_nodes[i] ) continue;
+      SMDS_EdgePosition* pos = static_cast<SMDS_EdgePosition*>( _nodes[i]->GetPosition() );
+      pos->SetUParameter( _initU[i] );
+    }
+  _done = false;
+}
+
+//================================================================================
+/*!
+ * \brief Replace source nodes by target nodes in shrinked mesh edges
+ */
+//================================================================================
+
+void _Shrinker1D::SwapSrcTgtNodes( SMESHDS_Mesh* mesh )
+{
+  const SMDS_MeshNode* nodes[3];
+  for ( int i = 0; i < 2; ++i )
+  {
+    if ( !_edges[i] ) continue;
+
+    SMESHDS_SubMesh * eSubMesh = mesh->MeshElements( _edges[i]->_sWOL );
+    if ( !eSubMesh ) return;
+    const SMDS_MeshNode* srcNode = _edges[i]->_nodes[0];
+    const SMDS_MeshNode* tgtNode = _edges[i]->_nodes.back();
+    SMDS_ElemIteratorPtr eIt = srcNode->GetInverseElementIterator(SMDSAbs_Edge);
+    while ( eIt->more() )
+    {
+      const SMDS_MeshElement* e = eIt->next();
+      if ( !eSubMesh->Contains( e ))
+          continue;
+      SMDS_ElemIteratorPtr nIt = e->nodesIterator();
+      for ( int iN = 0; iN < e->NbNodes(); ++iN )
+      {
+        const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nIt->next() );
+        nodes[iN] = ( n == srcNode ? tgtNode : n );
+      }
+      mesh->ChangeElementNodes( e, nodes, e->NbNodes() );
+    }
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Creates 2D and 1D elements on boundaries of new prisms
+ */
+//================================================================================
+
+bool _ViscousBuilder::addBoundaryElements()
+{
+  SMESH_MesherHelper helper( *_mesh );
+
+  for ( unsigned i = 0; i < _sdVec.size(); ++i )
+  {
+    _SolidData& data = _sdVec[i];
+    TopTools_IndexedMapOfShape geomEdges;
+    TopExp::MapShapes( data._solid, TopAbs_EDGE, geomEdges );
+    for ( int iE = 1; iE <= geomEdges.Extent(); ++iE )
+    {
+      const TopoDS_Edge& E = TopoDS::Edge( geomEdges(iE));
+
+      // Get _LayerEdge's based on E
+
+      map< double, const SMDS_MeshNode* > u2nodes;
+      if ( !SMESH_Algo::GetSortedNodesOnEdge( getMeshDS(), E, /*ignoreMedium=*/false, u2nodes))
+        continue;
+
+      vector< _LayerEdge* > ledges; ledges.reserve( u2nodes.size() );
+      TNode2Edge & n2eMap = data._n2eMap;
+      map< double, const SMDS_MeshNode* >::iterator u2n = u2nodes.begin();
+      {
+        //check if 2D elements are needed on E
+        TNode2Edge::iterator n2e = n2eMap.find( u2n->second );
+        if ( n2e == n2eMap.end() ) continue; // no layers on vertex
+        ledges.push_back( n2e->second );
+        u2n++;
+        if (( n2e = n2eMap.find( u2n->second )) == n2eMap.end() )
+          continue; // no layers on E
+        ledges.push_back( n2eMap[ u2n->second ]);
+
+        const SMDS_MeshNode* tgtN0 = ledges[0]->_nodes.back();
+        const SMDS_MeshNode* tgtN1 = ledges[1]->_nodes.back();
+        int nbSharedPyram = 0;
+        SMDS_ElemIteratorPtr vIt = tgtN0->GetInverseElementIterator(SMDSAbs_Volume);
+        while ( vIt->more() )
+        {
+          const SMDS_MeshElement* v = vIt->next();
+          nbSharedPyram += int( v->GetNodeIndex( tgtN1 ) >= 0 );
+        }
+        if ( nbSharedPyram > 1 )
+          continue; // not free border of the pyramid
+
+        if ( getMeshDS()->FindFace( ledges[0]->_nodes[0], ledges[0]->_nodes[1],
+                                    ledges[1]->_nodes[0], ledges[1]->_nodes[1]))
+          continue; // faces already created
+      }
+      for ( ++u2n; u2n != u2nodes.end(); ++u2n )
+        ledges.push_back( n2eMap[ u2n->second ]);
+
+      // Find out orientation and type of face to create
+
+      bool reverse = false, isOnFace;
+      
+      map< TGeomID, TopoDS_Shape >::iterator e2f =
+        data._shrinkShape2Shape.find( getMeshDS()->ShapeToIndex( E ));
+      TopoDS_Shape F;
+      if (( isOnFace = ( e2f != data._shrinkShape2Shape.end() )))
+      {
+        F = e2f->second.Oriented( TopAbs_FORWARD );
+        reverse = ( helper.GetSubShapeOri( F, E ) == TopAbs_REVERSED );
+        if ( helper.GetSubShapeOri( data._solid, F ) == TopAbs_REVERSED )
+          reverse = !reverse;
+      }
+      else
+      {
+        // find FACE with layers sharing E
+        PShapeIteratorPtr fIt = helper.GetAncestors( E, *_mesh, TopAbs_FACE );
+        while ( fIt->more() && F.IsNull() )
+        {
+          const TopoDS_Shape* pF = fIt->next();
+          if ( helper.IsSubShape( *pF, data._solid) &&
+               !_ignoreShapeIds.count( e2f->first ))
+            F = *pF;
+        }
+      }
+      // Find the sub-mesh to add new faces
+      SMESHDS_SubMesh* sm = 0;
+      if ( isOnFace )
+        sm = getMeshDS()->MeshElements( F );
+      else
+        sm = data._proxyMesh->getFaceSubM( TopoDS::Face(F), /*create=*/true );
+      if ( !sm )
+        return error("error in addBoundaryElements()", data._index);
+
+      // Make faces
+      const int dj1 = reverse ? 0 : 1;
+      const int dj2 = reverse ? 1 : 0;
+      for ( unsigned j = 1; j < ledges.size(); ++j )
+      {
+        vector< const SMDS_MeshNode*>&  nn1 = ledges[j-dj1]->_nodes;
+        vector< const SMDS_MeshNode*>&  nn2 = ledges[j-dj2]->_nodes;
+        if ( isOnFace )
+          for ( unsigned z = 1; z < nn1.size(); ++z )
+            sm->AddElement( getMeshDS()->AddFace( nn1[z-1], nn2[z-1], nn2[z], nn1[z] ));
+        else
+          for ( unsigned z = 1; z < nn1.size(); ++z )
+            sm->AddElement( new SMDS_FaceOfNodes( nn1[z-1], nn2[z-1], nn2[z], nn1[z]));
+      }
+    }
+  }
+
+  return true;
+}
diff --git a/src/StdMeshers/StdMeshers_ViscousLayers.hxx b/src/StdMeshers/StdMeshers_ViscousLayers.hxx
new file mode 100644 (file)
index 0000000..42c1871
--- /dev/null
@@ -0,0 +1,94 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+// File      : StdMeshers_ViscousLayers.hxx
+// Created   : Wed Dec  1 15:15:34 2010
+// Author    : Edward AGAPOV (eap)
+
+#ifndef __StdMeshers_ViscousLayers_HXX__
+#define __StdMeshers_ViscousLayers_HXX__
+
+#include "SMESH_StdMeshers.hxx"
+
+#include "SMESH_Hypothesis.hxx"
+#include "SMESH_ProxyMesh.hxx"
+
+#include <vector>
+
+/*!
+ * \brief Hypothesis defining parameters of viscous layers
+ */
+class STDMESHERS_EXPORT StdMeshers_ViscousLayers : public SMESH_Hypothesis
+{
+public:
+  StdMeshers_ViscousLayers(int hypId, int studyId, SMESH_Gen* gen);
+
+  // Set faces to exclude from treatment
+  void SetIgnoreFaces(const std::vector<int>& faceIds);
+  std::vector<int> GetIgnoreFaces() const { return _ignoreFaceIds; }
+
+  // Set total thickness of layers of prisms
+  void SetTotalThickness(double thickness);
+  double GetTotalThickness() const { return _thickness; }
+
+  // Set number of layers of prisms
+  void SetNumberLayers(int nb);
+  int GetNumberLayers() const { return _nbLayers; }
+
+  // Set factor (>1.0) of growth of layer thickness towards inside of mesh
+  void SetStretchFactor(double factor);
+  double GetStretchFactor() const { return _stretchFactor; }
+
+  // Computes temporary 2D mesh to be used by 3D algorithm.
+  // Return SMESH_ProxyMesh for each SOLID in theShape
+  SMESH_ProxyMesh::Ptr Compute(SMESH_Mesh&         theMesh,
+                               const TopoDS_Shape& theShape,
+                               const bool          toMakeN2NMap=false) const;
+
+  virtual std::ostream & SaveTo(std::ostream & save);
+  virtual std::istream & LoadFrom(std::istream & load);
+
+  /*!
+   * \brief Initialize my parameter values by the mesh built on the geometry
+    * \param theMesh - the built mesh
+    * \param theShape - the geometry of interest
+    * \retval bool - true if parameter values have been successfully defined
+    *
+    * Just return false as this hypothesis does not have parameters values
+   */
+  virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape);
+
+  /*!
+   * \brief Initialize my parameter values by default parameters.
+   *  \retval bool - true if parameter values have been successfully defined
+   */
+  virtual bool SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh=0)
+  { return false; }
+
+  static const char* GetHypType() { return "ViscousLayers"; }
+
+ private:
+
+  std::vector<int> _ignoreFaceIds;
+  int              _nbLayers;
+  double           _thickness;
+  double           _stretchFactor;
+};
+
+#endif
index 38425ec0c078b36fa6e36d6cf46fd06c4a6f7fdc..3f7a1d8fff9db9dffc30092c248f8f1081685cd8 100644 (file)
@@ -1,30 +1,26 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
 #
-#  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-#
-#  SMESH StdMeshersGUI : GUI for StdMeshers plugin
 #  File   : Makefile.in
 #  Author : Julia DOROVSKIKH
 #  Modified by : Alexander BORODIN (OCN) - autotools usage
 #  Module : SMESH
-#
+
 include $(top_srcdir)/adm_local/unix/make_common_starter.am
 
 # header files 
@@ -35,10 +31,15 @@ salomeinclude_HEADERS = \
        StdMeshersGUI_DistrTable.h \
        StdMeshersGUI_NbSegmentsCreator.h \
        StdMeshersGUI_ObjectReferenceParamWdg.h \
-       StdMeshersGUI_LayerDistributionParamWdg.h
+       StdMeshersGUI_QuadrangleParamWdg.h \
+       StdMeshersGUI_LayerDistributionParamWdg.h \
+       StdMeshersGUI_FixedPointsParamWdg.h \
+       StdMeshersGUI_SubShapeSelectorWdg.h \
+       StdMeshersGUI_CartesianParamCreator.h
 
 # Libraries targets
 lib_LTLIBRARIES = libStdMeshersGUI.la
+
 dist_libStdMeshersGUI_la_SOURCES = \
        StdMeshersGUI.cxx \
        StdMeshersGUI_StdHypothesisCreator.cxx \
@@ -46,7 +47,11 @@ dist_libStdMeshersGUI_la_SOURCES = \
        StdMeshersGUI_DistrTable.cxx \
        StdMeshersGUI_NbSegmentsCreator.cxx \
        StdMeshersGUI_ObjectReferenceParamWdg.cxx \
-       StdMeshersGUI_LayerDistributionParamWdg.cxx
+       StdMeshersGUI_QuadrangleParamWdg.cxx \
+       StdMeshersGUI_LayerDistributionParamWdg.cxx \
+       StdMeshersGUI_FixedPointsParamWdg.cxx \
+       StdMeshersGUI_SubShapeSelectorWdg.cxx \
+       StdMeshersGUI_CartesianParamCreator.cxx
 
 MOC_FILES = \
        StdMeshersGUI_StdHypothesisCreator_moc.cxx \
@@ -54,7 +59,11 @@ MOC_FILES = \
        StdMeshersGUI_DistrTable_moc.cxx \
        StdMeshersGUI_NbSegmentsCreator_moc.cxx \
        StdMeshersGUI_ObjectReferenceParamWdg_moc.cxx \
-       StdMeshersGUI_LayerDistributionParamWdg_moc.cxx
+       StdMeshersGUI_QuadrangleParamWdg_moc.cxx \
+       StdMeshersGUI_LayerDistributionParamWdg_moc.cxx \
+       StdMeshersGUI_FixedPointsParamWdg_moc.cxx \
+       StdMeshersGUI_SubShapeSelectorWdg_moc.cxx \
+       StdMeshersGUI_CartesianParamCreator_moc.cxx
 
 nodist_libStdMeshersGUI_la_SOURCES= \
        $(MOC_FILES)
@@ -74,6 +83,7 @@ libStdMeshersGUI_la_CPPFLAGS = \
        $(CORBA_CXXFLAGS) \
        $(CORBA_INCLUDES) \
        -I$(srcdir)/../SMESH \
+       -I$(srcdir)/../SMESHUtils \
        -I$(srcdir)/../SMESH_I \
        -I$(srcdir)/../SMESHDS \
        -I$(srcdir)/../SMDS \
@@ -82,9 +92,7 @@ libStdMeshersGUI_la_CPPFLAGS = \
        -I$(srcdir)/../StdMeshers \
        -I$(srcdir)/../OBJECT \
        -I$(srcdir)/../SMESHFiltersSelection \
-       -I$(top_builddir)/idl \
-       -I$(top_builddir)/salome_adm/unix
-
+       -I$(top_builddir)/idl
 
 libStdMeshersGUI_la_LDFLAGS  = \
        ../../idl/libSalomeIDLSMESH.la \
@@ -98,4 +106,5 @@ libStdMeshersGUI_la_LDFLAGS  = \
 # resources files
 nodist_salomeres_DATA= \
        StdMeshers_images.qm \
-       StdMeshers_msg_en.qm
+       StdMeshers_msg_en.qm \
+       StdMeshers_msg_fr.qm
index 76ce2a2a2a5f4e5f28bd0bfb89ca59e922f31b33..946bd61a6ba95c9395207bf9d041df908c196680 100755 (executable)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : SMESH_StdMeshersGUI.hxx
 // Author : Alexander BORODIN, Open CASCADE S.A.S.
 //
@@ -26,7 +27,7 @@
 #define SMESH_STDMESHERSGUI_HXX
 
 #ifdef WNT
- #if defined STDMESHERSGUI_EXPORTS
+ #if defined STDMESHERSGUI_EXPORTS || defined StdMeshersGUI_EXPORTS
   #define STDMESHERSGUI_EXPORT __declspec( dllexport )
  #else
   #define STDMESHERSGUI_EXPORT __declspec( dllimport )
index f3e400e82fcf223b2b55cd2772fa1997ccf1ddeb..8b86c5d27b49d2bc552d05dbad93b7076f2d00f0 100644 (file)
@@ -1,30 +1,32 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : StdMeshersGUI.cxx
 // Author : Alexander SOLOVYOV, Open CASCADE S.A.S.
 // SMESH includes
 //
 #include "StdMeshersGUI_StdHypothesisCreator.h"
 #include "StdMeshersGUI_NbSegmentsCreator.h"
+#include "StdMeshersGUI_CartesianParamCreator.h"
 
 //=============================================================================
 /*! GetHypothesisCreator
@@ -38,6 +40,8 @@ extern "C"
   {
     if( aHypType=="NumberOfSegments" )
       return new StdMeshersGUI_NbSegmentsCreator();
+    else if ( aHypType=="CartesianParameters3D" )
+      return new StdMeshersGUI_CartesianParamCreator( aHypType );
     else
       return new StdMeshersGUI_StdHypothesisCreator( aHypType );
   }
diff --git a/src/StdMeshersGUI/StdMeshersGUI_CartesianParamCreator.cxx b/src/StdMeshersGUI/StdMeshersGUI_CartesianParamCreator.cxx
new file mode 100644 (file)
index 0000000..48eec0e
--- /dev/null
@@ -0,0 +1,698 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+// File   : StdMeshersGUI_CartesianParamCreator.cxx
+// Author : Open CASCADE S.A.S.
+
+// SMESH includes
+#include "StdMeshersGUI_CartesianParamCreator.h"
+
+#include <SMESHGUI.h>
+#include <SMESHGUI_Utils.h>
+#include <SMESHGUI_HypothesesUtils.h>
+#include <SMESHGUI_SpinBox.h>
+
+// IDL includes
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+// SALOME GUI includes
+#include <SalomeApp_Tools.h>
+#include <SalomeApp_IntSpinBox.h>
+#include <QtxComboBox.h>
+
+// Qt includes
+#include <QAbstractItemModel>
+#include <QApplication>
+#include <QButtonGroup>
+#include <QGridLayout>
+#include <QGroupBox>
+#include <QHBoxLayout>
+#include <QLabel>
+#include <QLineEdit>
+#include <QListWidget>
+#include <QModelIndex>
+#include <QRadioButton>
+#include <QString>
+#include <QStyleOptionViewItem>
+#include <QTreeWidget>
+#include <QTreeWidgetItem>
+#include <QVBoxLayout>
+#include <QPushButton>
+#include <QTabWidget>
+
+#define SPACING 6
+#define MARGIN  11
+
+namespace StdMeshersGUI
+{
+  enum { COORD_BUT = 0, SPACING_BUT };
+
+  //================================================================================
+  /*!
+   * \brief get spacing definition from a tree item
+   */
+  //================================================================================
+
+  void getFromItem(QTreeWidgetItem * item, double& t0, double& t1, QString& fun )
+  {
+    if ( item )
+    {
+      t0 = item->text( 0 ).split(' ')[0].toDouble();
+      t1 = item->data( 0, Qt::UserRole ).toDouble();
+      fun = item->text( 1 );
+    }
+  }
+
+  //================================================================================
+  /*!
+   * \brief set spacing definition to a tree item
+   */
+  //================================================================================
+
+  QTreeWidgetItem* setToItem(double t0, double t1, const QString& fun, QTreeWidgetItem * item)
+  {
+    if ( !item ) item = new QTreeWidgetItem;
+    item->setText( 0, QString( "%1 - %2" ).arg( t0 ).arg( t1 ));
+    item->setData( 0, Qt::UserRole, t1 );
+    item->setText( 1, fun );
+    item->setFlags( item->flags() | Qt::ItemIsEditable );
+    return item;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Retrieves coordinate value from a list item
+   */
+  //================================================================================
+
+  double coordFromItem( QListWidgetItem * item )
+  {
+    return item ? item->data( Qt::UserRole ).toDouble() : 0;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Sets coordinate value to a list item
+   */
+  //================================================================================
+
+  QListWidgetItem* coordToItem( double coord, QListWidgetItem * item )
+  {
+    if ( !item ) item = new QListWidgetItem;
+    item->setText( QString::number( coord ));
+    item->setData( Qt::UserRole, coord );
+    item->setFlags( item->flags() | Qt::ItemIsEditable );
+    return item;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Constructor
+   * \param theParent - Parent widget for this tab
+   * 
+   * Makes tab's look and feel
+   */
+  //================================================================================
+
+  GridAxisTab::GridAxisTab( QWidget* theParent,const int axisIndex ):
+    QFrame( theParent ), myAxisIndex( axisIndex )
+  {
+    // 1) Grid definition mode
+    myModeGroup = new QButtonGroup( this );
+    QGroupBox* modeBox = new QGroupBox( tr( "GRID_DEF_MODE" ), this );
+    QHBoxLayout* modeLay = new QHBoxLayout( modeBox );
+    modeLay->setMargin( MARGIN );
+    modeLay->setSpacing( SPACING );
+
+    QRadioButton* coordModeBtn = new QRadioButton( tr( "SMESH_COORDINATES" ), modeBox );
+    QRadioButton* spacModeBtn  = new QRadioButton( tr( "SPACING" ), modeBox );
+
+    modeLay->addWidget( coordModeBtn );
+    modeLay->addWidget( spacModeBtn );
+    myModeGroup->addButton( coordModeBtn, COORD_BUT );
+    myModeGroup->addButton( spacModeBtn,  SPACING_BUT );
+
+    // 2) Buttons + Step
+    myInsertBtn = new QPushButton( tr("INSERT"), this);
+    myDeleteBtn = new QPushButton( tr("SMESH_BUT_DELETE"), this);
+
+    myStepLabel = new QLabel( tr("COORD_STEP"));
+    myStepSpin  = new SMESHGUI_SpinBox( this );
+    myStepSpin->setAcceptNames( false ); // No Notebook variables allowed
+    myStepSpin->RangeStepAndValidator();
+    myStepSpin->SetStep( 1. );
+    myStepSpin->SetValue( myStep = 1. );
+
+    // 3) Coodrinates/Spacing group
+    QFrame* csFrame = new QFrame( this );
+    QVBoxLayout* scLay = new QVBoxLayout( csFrame );
+    scLay->setMargin( 0 );
+    scLay->setSpacing( SPACING );
+
+    // 3.1) Spacing
+    mySpacingTreeWdg = new QTreeWidget( csFrame );
+    mySpacingTreeWdg->setColumnCount(2);
+    mySpacingTreeWdg->setHeaderLabels( QStringList() << tr( "SMESH_RANGE" ) << QString( "f(t)" ));
+    mySpacingTreeWdg->setColumnWidth( 1, 40 );
+    mySpacingTreeWdg->setColumnWidth( 2, 30 );
+    mySpacingTreeWdg->setItemDelegate( new LineDelegate( mySpacingTreeWdg ));
+    scLay->addWidget( mySpacingTreeWdg );
+
+    // 3.2) Coordinates
+    myCoordList = new QListWidget( csFrame );
+    myCoordList->setItemDelegate( new LineDelegate( myCoordList ));
+    scLay->addWidget( myCoordList );
+
+    // layouting
+
+    QGridLayout* axisTabLayout = new QGridLayout( this );
+    axisTabLayout->setMargin( MARGIN );
+    axisTabLayout->setSpacing( SPACING );
+
+    axisTabLayout->addWidget( modeBox    , 0, 0, 1, 3 );
+    axisTabLayout->addWidget( myInsertBtn  , 1, 0, 1, 2 );
+    axisTabLayout->addWidget( myDeleteBtn  , 2, 0, 1, 2 );
+    axisTabLayout->addWidget( myStepLabel, 3, 0 );
+    axisTabLayout->addWidget( myStepSpin , 3, 1 );
+    axisTabLayout->addWidget( csFrame    , 1, 2, 4, 1 );
+
+    axisTabLayout->setRowStretch( 4, 1 );
+
+    // signals
+    connect( myInsertBtn,      SIGNAL( clicked() ),             SLOT( onInsert() ));
+    connect( myDeleteBtn,      SIGNAL( clicked() ),             SLOT( onDelete() ));
+    connect( myModeGroup,      SIGNAL( buttonClicked ( int )),  SLOT( onMode(int)));
+    connect( mySpacingTreeWdg, SIGNAL( itemSelectionChanged()), SLOT( updateButtons() ));
+    connect( myCoordList,      SIGNAL( itemSelectionChanged()), SLOT( updateButtons() ));
+    connect( myStepSpin,       SIGNAL( valueChanged(double)),   SLOT( onStepChange() ));
+  }
+
+  void GridAxisTab::onInsert()
+  {
+    if ( isGridBySpacing() )
+    {
+      QTreeWidgetItem * item = mySpacingTreeWdg->currentItem();
+      if ( !item ) item = mySpacingTreeWdg->topLevelItem( 0 );
+      int i = mySpacingTreeWdg->indexOfTopLevelItem( item );
+
+      double t0, t1; QString fun;
+      getFromItem( item, t0, t1, fun );
+      double t = 0.5 * ( t0 + t1 );
+      setToItem( t0, t, fun, item );
+
+      item = setToItem( t, t1, fun );
+      if ( i == mySpacingTreeWdg->topLevelItemCount()-1 )
+        mySpacingTreeWdg->addTopLevelItem( item );
+      else
+        mySpacingTreeWdg->insertTopLevelItem( i+1, item );
+      mySpacingTreeWdg->setCurrentItem( item );
+    }
+    else
+    {
+      if ( myCoordList->count() == 0 )
+      {
+        myCoordList->addItem( coordToItem( 0 ));
+      }
+      else
+      {
+        double coord = coordFromItem( myCoordList->currentItem() ) + myStep;
+        int i = myCoordList->currentRow();
+        while ( i > 0 && coordFromItem( myCoordList->item( i-1 )) > coord )
+          --i;
+        while ( i < myCoordList->count() && coordFromItem( myCoordList->item( i )) < coord )
+          ++i;
+        const double tol = 1e-6;
+        const bool isSame = 
+          ( i < myCoordList->count() && coordFromItem( myCoordList->item( i )) - coord < tol ) ||
+          ( i > 0 && coord - coordFromItem( myCoordList->item( i-1 )) < tol );
+        if ( !isSame )
+          myCoordList->insertItem( i, coordToItem( coord ));
+        else if ( myStep < 0 )
+          --i;
+        myCoordList->setCurrentRow( i );
+      }
+    }
+    updateButtons();
+  }
+
+  void GridAxisTab::onDelete()
+  {
+    if ( isGridBySpacing() )
+    {
+      QList<QTreeWidgetItem *> selItems = mySpacingTreeWdg->selectedItems();
+      QTreeWidgetItem * item;
+      foreach ( item, selItems )
+      {
+        int i = mySpacingTreeWdg->indexOfTopLevelItem( item );
+        if ( i == 0 ) continue; 
+        QTreeWidgetItem* prevItem = mySpacingTreeWdg->topLevelItem( i-1 );
+
+        double t0, t1, t2; QString fun;
+        getFromItem( item, t1, t2, fun );
+        getFromItem( prevItem, t0, t1, fun );
+        delete item;
+
+        setToItem( t0, t2, fun, prevItem );
+      }
+    }
+    else
+    {
+      if ( myCoordList->count() > 2 )
+        if ( QListWidgetItem * item = myCoordList->currentItem() )
+          delete item;
+    }
+    updateButtons();
+  }
+
+  void GridAxisTab::onMode(int isSpacing)
+  {
+    mySpacingTreeWdg->setShown( isSpacing );
+    myCoordList->setShown( !isSpacing );
+    myStepSpin->setShown( !isSpacing );
+    myStepLabel->setShown( !isSpacing );
+    if ( isSpacing )
+    {
+      if ( mySpacingTreeWdg->topLevelItemCount() == 0 )
+      {
+        QString spacing( "1" );
+        if ( myCoordList->count() > 1 )
+        {
+          double c1 = coordFromItem( myCoordList->item( 1 ));
+          double c0 = coordFromItem( myCoordList->item( 0 ));
+          spacing = QString::number( c1 - c0 );
+        }
+        mySpacingTreeWdg->addTopLevelItem( setToItem( 0., 1., spacing ) );
+      }
+      //myCoordList->clear();
+    }
+    else
+    {
+      //mySpacingTreeWdg->clear();
+      if ( myCoordList->count() == 0 )
+        myCoordList->addItem( coordToItem( 0 ));
+    }
+    updateButtons();
+  }
+
+  void GridAxisTab::onStepChange()
+  {
+    if ( fabs( myStepSpin->GetValue() ) < 1e-100 )
+    {
+      double delta = myStepSpin->singleStep() * ( myStep > myStepSpin->GetValue() ? -1 : +1 );
+      myStepSpin->SetValue( myStepSpin->GetValue() + delta );
+    }
+    myStep = myStepSpin->GetValue();
+  }
+
+  void GridAxisTab::updateButtons()
+  {
+    bool insertEnable = false, deleteEnable = false;
+    if ( isGridBySpacing() )
+    {
+      insertEnable = true;
+      const int nbSelected = mySpacingTreeWdg->selectedItems().count();
+      if ( nbSelected > 0 )
+      {
+        // we delete a current range by uniting it with the previous
+        int i = mySpacingTreeWdg->indexOfTopLevelItem(  mySpacingTreeWdg->currentItem() );
+        deleteEnable = ( i > 0 );
+      }
+    }
+    else
+    {
+      const int nbSelected = myCoordList->selectedItems().count();
+      insertEnable = ( nbSelected || myCoordList->count() < 2 );
+      deleteEnable = ( nbSelected && myCoordList->count() > 2 );
+    }
+    myInsertBtn->setEnabled( insertEnable );
+    myDeleteBtn->setEnabled( deleteEnable );
+  }
+
+  void GridAxisTab::setCoordinates( SMESH::double_array_var coords )
+  {
+    myCoordList->clear();
+    for ( size_t i = 0; i < coords->length(); ++i )
+      myCoordList->addItem( coordToItem( coords[i] ));
+
+    myModeGroup->button( COORD_BUT )->setChecked( true );
+    onMode( COORD_BUT );
+  }
+
+  void GridAxisTab::setSpacing( SMESH::string_array_var funs, SMESH::double_array_var points )
+  {
+    mySpacingTreeWdg->clear();
+    if ( funs->length() == points->length() - 1 )
+    {
+      for ( size_t i = 1; i < points->length(); ++i )
+        mySpacingTreeWdg->addTopLevelItem
+          ( setToItem( points[i-1], points[i], (const char*) funs[i-1] ));
+    }
+    myModeGroup->button( SPACING_BUT )->setChecked( true );
+    onMode( SPACING_BUT );
+  }
+
+  bool GridAxisTab::isGridBySpacing() const
+  {
+    return ( myModeGroup->checkedId() == SPACING_BUT );
+  }
+
+  SMESH::double_array* GridAxisTab::getCoordinates()
+  {
+    SMESH::double_array_var coords = new SMESH::double_array;
+    coords->length( myCoordList->count() );
+    for ( size_t i = 0; i < coords->length(); ++i )
+      coords[i] = coordFromItem( myCoordList->item( i ) );
+
+    return coords._retn();
+  }
+
+  void GridAxisTab::getSpacing(SMESH::string_array_out funs,
+                               SMESH::double_array_out points) const
+  {
+    funs =  new SMESH::string_array();
+    points = new SMESH::double_array();
+    funs->length( mySpacingTreeWdg->topLevelItemCount() );
+    points->length( mySpacingTreeWdg->topLevelItemCount() + 1 );
+    double t0, t1; QString fun;
+    for ( size_t i = 0; i < funs->length(); ++i )
+    {
+      QTreeWidgetItem* item = mySpacingTreeWdg->topLevelItem( i );
+      getFromItem( item, t0, t1, fun );
+      points[i] = t0;
+      funs[i] = fun.toLatin1().constData();
+    }
+    points[ points->length()-1 ] = 1.0;
+  }
+
+
+  bool GridAxisTab::checkParams(QString& msg, SMESH::SMESH_Hypothesis_var& hyp) const
+  {
+    if ( isGridBySpacing() )
+    {
+      if ( mySpacingTreeWdg->topLevelItemCount() == 0 )
+        return false; // how could it be?
+      StdMeshers::StdMeshers_CartesianParameters3D_var h =
+        StdMeshers::StdMeshers_CartesianParameters3D::_narrow( hyp );
+      SMESH::string_array_var funs;
+      SMESH::double_array_var points;
+      getSpacing( funs.out(), points.out() );
+      try {
+        const char* axisName[3] = { "X", "Y", "Z" };
+        SMESH::double_array_var coords =
+          h->ComputeCoordinates(0.,1., funs, points, axisName[ myAxisIndex ]);
+      }
+      catch ( const SALOME::SALOME_Exception& ex ) {
+        msg = (const char*) ex.details.text;
+        return false;
+      }
+    }
+    else
+    {
+      return myCoordList->count() > 1;
+    }
+    return true;
+  }
+
+  LineDelegate::LineDelegate( QWidget* parent ):
+    QItemDelegate( parent ),
+    mySpacingTreeWdg( qobject_cast<QTreeWidget*>( parent )),
+    myCoordList( qobject_cast<QListWidget*>( parent ))
+  {
+  }
+
+  QWidget* LineDelegate::createEditor( QWidget*                    parent,
+                                       const QStyleOptionViewItem& opt,
+                                       const QModelIndex&          index) const
+  {
+    QWidget* w = 0;
+    if ( mySpacingTreeWdg )
+    {
+      if ( index.column() == 0 &&
+           index.row() != mySpacingTreeWdg->topLevelItemCount()-1 )
+      {
+        SMESHGUI_SpinBox* sb = new SMESHGUI_SpinBox( parent );
+        sb->setAcceptNames( false ); // No Notebook variables allowed
+        sb->setFrame( false );
+        w = sb;
+      }
+      if ( index.column() == 1 ) {
+        w = new QLineEdit( parent );
+      }
+    }
+    else
+    {
+      SMESHGUI_SpinBox* sb = new SMESHGUI_SpinBox( parent );
+      sb->setAcceptNames( false ); // No Notebook variables allowed
+      sb->setFrame( false );
+      const double tol = 1e-5;
+      double from = index.row() ? coordFromItem( myCoordList->item( index.row()-1 ))+tol : -1e+6;
+      double to = index.row() == myCoordList->count()-1 ? 1e+6 : coordFromItem( myCoordList->item( index.row()+1 ))-tol;
+      sb->RangeStepAndValidator( from, to, 0.01 );
+      w = sb;
+    }
+    return w;
+  }
+
+  void LineDelegate::setEditorData ( QWidget * editor, const QModelIndex & index ) const
+  {
+    if ( mySpacingTreeWdg && index.column() == 0 )
+    {
+      double t0, t1, t2=1.0; QString fun;
+      QTreeWidgetItem* item = mySpacingTreeWdg->topLevelItem( index.row() );
+      getFromItem( item, t0, t1, fun );
+      if ( index.row() != mySpacingTreeWdg->topLevelItemCount()-1 )
+      {
+        item = mySpacingTreeWdg->topLevelItem( index.row()+1 );
+        getFromItem( item, t1, t2, fun );
+      }
+      const double tol = 1e-3;
+      SMESHGUI_SpinBox* sb = qobject_cast<SMESHGUI_SpinBox*>( editor );
+      sb->RangeStepAndValidator( t0 + tol, t2 - tol, 0.01 );
+      sb->SetValue( t1 );
+    }
+    else
+    {
+      QItemDelegate::setEditorData( editor, index );
+    }
+  }
+  void LineDelegate::setModelData( QWidget*            editor,
+                                   QAbstractItemModel* model,
+                                   const QModelIndex&  index ) const
+  {
+    if ( mySpacingTreeWdg )
+    {
+      if ( index.column() == 0 )
+      {
+        if ( index.row() != mySpacingTreeWdg->topLevelItemCount()-1 )
+        {
+          SMESHGUI_SpinBox* sb = qobject_cast<SMESHGUI_SpinBox*>( editor );
+          double t0, t1, t = sb->GetValue(); QString fun;
+
+          QTreeWidgetItem* item = mySpacingTreeWdg->topLevelItem( index.row() );
+          getFromItem( item, t0, t1, fun );
+          setToItem( t0, t, fun, item );
+
+          item = mySpacingTreeWdg->topLevelItem( index.row() + 1 );
+          getFromItem( item, t0, t1, fun );
+          setToItem( t, t1, fun, item );
+        }
+      }
+      else if ( !qobject_cast<QLineEdit*>(editor)->text().trimmed().isEmpty() )
+      {
+        QItemDelegate::setModelData( editor, model, index );
+      }
+    }
+    else
+    {
+      SMESHGUI_SpinBox* sb = qobject_cast<SMESHGUI_SpinBox*>( editor );
+      coordToItem( sb->GetValue(), myCoordList->item( index.row() ));
+    }
+  }
+
+} // namespace StdMeshersGUI
+
+
+StdMeshersGUI_CartesianParamCreator::StdMeshersGUI_CartesianParamCreator(const QString& aHypType)
+  : StdMeshersGUI_StdHypothesisCreator( aHypType ),
+    myThreshold( 0 )
+{
+  myAxisTabs[0] = 0;
+  myAxisTabs[1] = 0;
+  myAxisTabs[2] = 0;
+}
+
+StdMeshersGUI_CartesianParamCreator::~StdMeshersGUI_CartesianParamCreator()
+{
+  if ( myAxisTabs[0] ) delete myAxisTabs[0];
+  if ( myAxisTabs[1] ) delete myAxisTabs[1];
+  if ( myAxisTabs[2] ) delete myAxisTabs[2];
+  myAxisTabs[0] = 0;
+  myAxisTabs[1] = 0;
+  myAxisTabs[2] = 0;
+}
+
+bool StdMeshersGUI_CartesianParamCreator::checkParams( QString& msg ) const
+{
+  if( !SMESHGUI_GenericHypothesisCreator::checkParams( msg ) )
+    return false;
+
+  if ( myName && myName->text().trimmed().isEmpty() )
+  {
+    msg = tr("SMESH_WRN_EMPTY_NAME");
+    return false;
+  }
+  if ( ! myThreshold->isValid( msg, true ))
+    return false;
+
+  SMESH::SMESH_Hypothesis_var hyp = hypothesis();
+  if ( !myAxisTabs[0]->checkParams( msg, hyp )) return false;
+  if ( !myAxisTabs[1]->checkParams( msg, hyp )) return false;
+  if ( !myAxisTabs[2]->checkParams( msg, hyp )) return false;
+
+  return true;
+}
+
+QFrame* StdMeshersGUI_CartesianParamCreator::buildFrame()
+{
+  QFrame* fr = new QFrame();
+  //fr->setMinimumWidth(460);
+
+  QVBoxLayout* lay = new QVBoxLayout( fr );
+  lay->setMargin( 0 );
+  lay->setSpacing( SPACING );
+
+  QGroupBox* GroupC1 = new QGroupBox( tr( "SMESH_ARGUMENTS" ), fr );
+  lay->addWidget( GroupC1 );
+
+  StdMeshers::StdMeshers_NumberOfSegments_var h =
+    StdMeshers::StdMeshers_NumberOfSegments::_narrow( hypothesis() );
+
+  QGridLayout* argGroupLayout = new QGridLayout( GroupC1 );
+  argGroupLayout->setSpacing( SPACING );
+  argGroupLayout->setMargin( MARGIN );
+  argGroupLayout->setColumnStretch( 0, 0 );
+  argGroupLayout->setColumnStretch( 1, 1 );
+
+  int row = 0;
+  // 0)  name
+  myName = 0;
+  if( isCreation() )
+  {
+    myName = new QLineEdit( GroupC1 );
+    argGroupLayout->addWidget( new QLabel( tr( "SMESH_NAME" ), GroupC1 ), row, 0 );
+    argGroupLayout->addWidget( myName, row, 1 );
+    row++;
+  }
+
+  // 1)  threshold
+  argGroupLayout->addWidget( new QLabel( tr( "THRESHOLD" ), GroupC1 ), row, 0 );
+  myThreshold = new SMESHGUI_SpinBox( GroupC1 );
+  myThreshold->setAcceptNames( false ); // No Notebook variables allowed
+  myThreshold->RangeStepAndValidator( 1.1, 1e+10, 1., "length_precision" );
+  argGroupLayout->addWidget( myThreshold, row, 1 );
+  row++;
+  
+  // 2)  Grid definition
+  QTabWidget* tabWdg = new QTabWidget( fr );
+  myAxisTabs[ 0 ] = new StdMeshersGUI::GridAxisTab( tabWdg, 0 );
+  myAxisTabs[ 1 ] = new StdMeshersGUI::GridAxisTab( tabWdg, 1 );
+  myAxisTabs[ 2 ] = new StdMeshersGUI::GridAxisTab( tabWdg, 2 );
+  tabWdg->addTab( myAxisTabs[ 0 ], tr( "AXIS_X" ) );
+  tabWdg->addTab( myAxisTabs[ 1 ], tr( "AXIS_Y" ) );
+  tabWdg->addTab( myAxisTabs[ 2 ], tr( "AXIS_Z" ) );
+  argGroupLayout->addWidget( tabWdg, row, 0, 1, 2 );
+
+  return fr;
+}
+
+void StdMeshersGUI_CartesianParamCreator::retrieveParams() const
+{
+  StdMeshers::StdMeshers_CartesianParameters3D_var h =
+    StdMeshers::StdMeshers_CartesianParameters3D::_narrow( initParamsHypothesis() );
+
+  if( myName )
+    myName->setText( hypName() );
+
+  QString varName = getVariableName( "SetSizeThreshold" );
+  if ( varName.isEmpty() )
+    myThreshold->setValue( h->GetSizeThreshold() );
+  else
+    myThreshold->setText( varName );
+
+  for ( int ax = 0; ax < 3; ++ax )
+  {
+    if ( h->IsGridBySpacing( ax ))
+    {
+      SMESH::string_array_var funs;
+      SMESH::double_array_var intPoints;
+      h->GetGridSpacing( funs.out(), intPoints.out(), ax );
+      myAxisTabs[ax]->setSpacing( funs, intPoints );
+    }
+    else
+    {
+      SMESH::double_array_var coords = h->GetGrid( ax );
+      myAxisTabs[ax]->setCoordinates( coords );
+    }
+  }
+  if ( dlg() )
+    dlg()->setMinimumSize( dlg()->minimumSizeHint().width(), dlg()->minimumSizeHint().height() );
+}
+
+QString StdMeshersGUI_CartesianParamCreator::storeParams() const
+{
+  StdMeshers::StdMeshers_CartesianParameters3D_var h =
+    StdMeshers::StdMeshers_CartesianParameters3D::_narrow( hypothesis() );
+
+  try
+  {
+    if( isCreation() )
+      SMESH::SetName( SMESH::FindSObject( h ), myName->text().toLatin1().constData() );
+
+    h->SetVarParameter( myThreshold->text().toLatin1().constData(), "SetSizeThreshold" );
+    h->SetSizeThreshold( myThreshold->text().toDouble() );
+
+    for ( int ax = 0; ax < 3; ++ax )
+    {
+      if ( myAxisTabs[ax]->isGridBySpacing())
+      {
+        SMESH::double_array_var intPoints;
+        SMESH::string_array_var funs;
+        myAxisTabs[ax]->getSpacing( funs.out(), intPoints.out() );
+        h->SetGridSpacing( funs, intPoints, ax );
+      }
+      else
+      {
+        SMESH::double_array_var coords = myAxisTabs[ax]->getCoordinates();
+        h->SetGrid( coords, ax );
+      }
+    }
+  }
+  catch(const SALOME::SALOME_Exception& ex)
+  {
+    SalomeApp_Tools::QtCatchCorbaException(ex);
+  }
+  return "";
+}
+
+QString StdMeshersGUI_CartesianParamCreator::helpPage() const
+{
+  return "cartesian_algo_page.html#cartesian_hyp_anchor";
+}
diff --git a/src/StdMeshersGUI/StdMeshersGUI_CartesianParamCreator.h b/src/StdMeshersGUI/StdMeshersGUI_CartesianParamCreator.h
new file mode 100644 (file)
index 0000000..d8cddb6
--- /dev/null
@@ -0,0 +1,142 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+// File   : StdMeshersGUI_CartesianParamCreator.h
+// Author : Open CASCADE S.A.S.
+//
+#ifndef STDMESHERSGUI_CartesianParamCreator_H
+#define STDMESHERSGUI_CartesianParamCreator_H
+
+// SMESH includes
+#include "SMESH_StdMeshersGUI.hxx"
+
+#include "StdMeshersGUI_StdHypothesisCreator.h"
+
+// IDL includes
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_Hypothesis)
+
+#include <QFrame>
+#include <QItemDelegate>
+
+class SMESHGUI_SpinBox;
+class QLineEdit;
+class QButtonGroup;
+class QTreeWidgetItem;
+class QString;
+class QWidget;
+class QTreeWidget;
+class QListWidget;
+class QStyleOptionViewItem;
+class QModelIndex;
+class QAbstractItemModel;
+class QListWidgetItem;
+
+namespace StdMeshersGUI
+{
+  void getFromItem(QTreeWidgetItem * item, double& t0, double& t1, QString& fun );
+  QTreeWidgetItem* setToItem (double  t0, double  t1, const QString& fun, QTreeWidgetItem* item=0);
+
+  double coordFromItem( QListWidgetItem * );
+  QListWidgetItem* coordToItem( double coord, QListWidgetItem * item=0);
+
+  /*!
+   * \brief Widget defining the grid in one direction
+   */
+  class GridAxisTab : public QFrame
+  {
+    Q_OBJECT
+  public:
+    GridAxisTab( QWidget* parent, const int axisIndex );
+    ~GridAxisTab() {}
+
+    void setCoordinates( SMESH::double_array_var coords );
+    void setSpacing( SMESH::string_array_var funs, SMESH::double_array_var points );
+
+    bool checkParams(QString& msg, SMESH::SMESH_Hypothesis_var& hyp) const;
+    bool isGridBySpacing() const;
+    SMESH::double_array* getCoordinates();
+    void getSpacing(SMESH::string_array_out funs, SMESH::double_array_out points) const;
+
+  private slots:
+    void onInsert();
+    void onDelete();
+    void onMode(int);
+    void onStepChange();
+    void updateButtons();
+
+  private:
+
+    int               myAxisIndex;
+    QButtonGroup*     myModeGroup;
+    QTreeWidget*      mySpacingTreeWdg;
+    QListWidget*      myCoordList;
+    QPushButton*      myInsertBtn;
+    QPushButton*      myDeleteBtn;
+    SMESHGUI_SpinBox* myStepSpin;
+    QLabel*           myStepLabel;
+    double            myStep;
+  };
+  /*
+   * \brief : Custom item delegate
+   */
+  class LineDelegate : public QItemDelegate
+  {
+    Q_OBJECT
+  public:
+    LineDelegate( QWidget* parent );
+    ~LineDelegate() {}
+
+    QWidget* createEditor( QWidget*, const QStyleOptionViewItem&, const QModelIndex& ) const;
+    void setEditorData ( QWidget * editor, const QModelIndex & index ) const;
+    void setModelData( QWidget* editor, QAbstractItemModel* model, const QModelIndex& index ) const;
+
+  private:
+    QTreeWidget* mySpacingTreeWdg;
+    QListWidget* myCoordList;
+  };
+}
+
+class STDMESHERSGUI_EXPORT StdMeshersGUI_CartesianParamCreator : public StdMeshersGUI_StdHypothesisCreator
+{
+  Q_OBJECT
+
+public:
+  StdMeshersGUI_CartesianParamCreator( const QString& aHypType );
+  virtual ~StdMeshersGUI_CartesianParamCreator();
+
+  virtual bool    checkParams( QString& ) const;
+  virtual QString helpPage() const;
+
+protected:
+  virtual QFrame*  buildFrame();
+  virtual void     retrieveParams() const;
+  virtual QString  storeParams() const;
+
+private:
+  QLineEdit*                  myName;
+  SMESHGUI_SpinBox*           myThreshold;
+  StdMeshersGUI::GridAxisTab* myAxisTabs[3];
+};
+
+#endif // STDMESHERSGUI_CartesianParamCreator_H
index ead8d1c3d72d7dea4eed6032a2de6896501cfebe..4d9bd5111198fd8409b3ddc75145a0e6016ebc55 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : StdMeshersGUI_DistrPreview.cxx
 // Author : Open CASCADE S.A.S.
 // SMESH includes
 #ifdef WIN32
 # include <algorithm>
 #endif
+#include <math.h>
+#include <limits>
+
+#include <Basics_Utils.hxx>
 
 StdMeshersGUI_DistrPreview::StdMeshersGUI_DistrPreview( QWidget* p, StdMeshers::StdMeshers_NumberOfSegments_ptr h )
 : QwtPlot( p ),
@@ -60,6 +65,7 @@ StdMeshersGUI_DistrPreview::StdMeshersGUI_DistrPreview( QWidget* p, StdMeshers::
   myIsDone( true ),
   myNbSeg( 1 )
 {
+  Kernel_Utils::Localizer loc;
   myHypo = StdMeshers::StdMeshers_NumberOfSegments::_duplicate( h );
   myVars.ChangeValue( 1 ) = new Expr_NamedUnknown( "t" );
   myDensity = new QwtPlotCurve( QString() );
@@ -72,7 +78,7 @@ StdMeshersGUI_DistrPreview::StdMeshersGUI_DistrPreview( QWidget* p, StdMeshers::
   QwtText mt = myMsg->label();
   mt.setBackgroundPen( QPen( Qt::red, 1 ) );
   QFont f = mt.font();
-  f.setPointSize( 14 ); f.setBold( true );
+  f.setPointSize( 14 ); //f.setBold( true );
   mt.setFont( f );
   myMsg->setLabel( mt );
   myDensity->setPen( QPen( Qt::red, 1 ) );
@@ -88,6 +94,17 @@ StdMeshersGUI_DistrPreview::StdMeshersGUI_DistrPreview( QWidget* p, StdMeshers::
   }
   insertLegend( l, QwtPlot::BottomLegend );
 
+  enableAxis(QwtPlot::yLeft, false);
+  enableAxis(QwtPlot::yRight, true);
+  
+  QFont axisFont;
+  axisFont.setPointSize( 8 );
+  setAxisFont(QwtPlot::yRight, axisFont); 
+  setAxisFont(QwtPlot::xBottom, axisFont); 
+  
+  myDensity->setYAxis(QwtPlot::yRight);
+  myDistr->setYAxis(QwtPlot::yRight);
+  myMsg->setYAxis(QwtPlot::yRight);
   myDensity->setTitle( tr( "SMESH_DENSITY_FUNC" ) );
   myDistr->setTitle( tr( "SMESH_DISTR" ) );
   
@@ -200,6 +217,7 @@ bool StdMeshersGUI_DistrPreview::createTable( SMESH::double_array& func )
 
 void StdMeshersGUI_DistrPreview::update()
 {
+  Kernel_Utils::Localizer loc;
   SMESH::double_array graph, distr;
   if( isTableFunc() )
   {
@@ -218,13 +236,13 @@ void StdMeshersGUI_DistrPreview::update()
     {
       SMESH::double_array* arr = 0;
       if( isTableFunc() )
-       arr = h->BuildDistributionTab( myTableFunc, myNbSeg, ( int )myConv );
+        arr = h->BuildDistributionTab( myTableFunc, myNbSeg, ( int )myConv );
       else
-       arr = h->BuildDistributionExpr( myFunction.toLatin1().data(), myNbSeg, ( int )myConv );
+        arr = h->BuildDistributionExpr( myFunction.toLatin1().data(), myNbSeg, ( int )myConv );
       if( arr )
       {
-       distr = *arr;
-       delete arr;
+        distr = *arr;
+        delete arr;
       }
     }
   }
@@ -257,6 +275,15 @@ void StdMeshersGUI_DistrPreview::update()
       showError();
       return;
     }
+#ifdef WIN32
+    if ( std::fabs(y[i]) >= HUGE_VAL)
+      y[i] = HUGE_VAL/100.;
+#else
+    if ( isinf(y[i]))
+      y[i] = std::numeric_limits<double>::max()/100.;
+#endif
+//     if ( y[i] > 1e3 )
+//       y[i] = 1e3;
     if( i==0 || y[i]<min_y )
       min_y = y[i];
     if( i==0 || y[i]>max_y )
@@ -333,7 +360,7 @@ bool isCorrectArg( const Handle( Expr_GeneralExpression )& expr )
     if( !name.IsNull() )
     {
       if( name->GetName()!="t" )
-       res = false;
+        res = false;
     }
     else
       res = isCorrectArg( sub );
@@ -343,6 +370,7 @@ bool isCorrectArg( const Handle( Expr_GeneralExpression )& expr )
 
 bool StdMeshersGUI_DistrPreview::init( const QString& str )
 {
+  Kernel_Utils::Localizer loc;
   bool parsed_ok = true;
   try {
 #ifdef NO_CAS_CATCH
@@ -416,15 +444,15 @@ bool StdMeshersGUI_DistrPreview::convert( double& v ) const
 #ifdef NO_CAS_CATCH
         OCC_CATCH_SIGNALS;
 #endif
-       // in StdMeshers_NumberOfSegments.cc
-       // const double PRECISION = 1e-7;
-       //
-       if(v < -7) v = -7.0;
-       v = pow( 10.0, v );
+        // in StdMeshers_NumberOfSegments.cc
+        // const double PRECISION = 1e-7;
+        //
+        if(v < -7) v = -7.0;
+        v = pow( 10.0, v );
       } catch(Standard_Failure) {
-       Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-       v = 0.0;
-       ok = false;
+        Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+        v = 0.0;
+        ok = false;
       }
     }
     break;
index 87a9eb86e217ebc66b667f01a27b0041092974c5..8abcc3e26996cb3604688d94c8bfe695949fbab3 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : StdMeshersGUI_DistrPreview.h
 // Author : Open CASCADE S.A.S.
 //
index cc718ed66e768476f1256dad751ce6d8fe4cecfc..dbd9a4d8b6ecd4f11779992ff8bd67e37bad797b 100644 (file)
@@ -1,34 +1,37 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : StdMeshersGUI_DistrTable.cxx
 // Author : Open CASCADE S.A.S.
 // SMESH includes
 //
 #include "StdMeshersGUI_DistrTable.h"
 
+#include <SMESHGUI_SpinBox.h>
+
 // Qt incldues
 #include <QItemDelegate>
 #include <QTableWidget>
-#include <QDoubleSpinBox>
+#include <QHeaderView>
 #include <QPushButton>
 #include <QVBoxLayout>
 #include <QHBoxLayout>
@@ -84,14 +87,14 @@ public:
   ~SpinBoxDelegate();
 
   QWidget* createEditor( QWidget*,
-                        const QStyleOptionViewItem&,
-                        const QModelIndex& ) const;
+                         const QStyleOptionViewItem&,
+                         const QModelIndex& ) const;
   void     setEditorData( QWidget*, const QModelIndex&) const;
   void     setModelData( QWidget*, QAbstractItemModel*, 
-                        const QModelIndex& ) const;
+                         const QModelIndex& ) const;
   void     updateEditorGeometry( QWidget*,
-                                const QStyleOptionViewItem&, 
-                                const QModelIndex& ) const;
+                                 const QStyleOptionViewItem&, 
+                                 const QModelIndex& ) const;
 
 private:
   StdMeshersGUI_DistrTableFrame::Table* myTable;
@@ -109,7 +112,7 @@ private:
   struct EditorData
   { 
     int r, c;
-    QDoubleSpinBox* sb;
+    SMESHGUI_SpinBox* sb;
     EditorData() { reset(); }
     void reset() { r = -1; c = -1; sb = 0; }
   };
@@ -138,7 +141,7 @@ public:
   void          addRow();
   void          deleteRow();
 
-  void          setEditor( int, int, QDoubleSpinBox* );
+  void          setEditor( int, int, SMESHGUI_SpinBox* );
 
 protected:
   void          closeEditor( QWidget*, QAbstractItemDelegate::EndEditHint );
@@ -173,21 +176,25 @@ StdMeshersGUI_DistrTableFrame::SpinBoxDelegate::
 QWidget* 
 StdMeshersGUI_DistrTableFrame::SpinBoxDelegate::
 createEditor( QWidget* parent,
-             const QStyleOptionViewItem& /*option*/,
-             const QModelIndex& index ) const
+              const QStyleOptionViewItem& /*option*/,
+              const QModelIndex& index ) const
 {
-  QDoubleSpinBox* sb = new QDoubleSpinBox( parent );
+  SMESHGUI_SpinBox* sb = new SMESHGUI_SpinBox( parent );
+  
+  sb->setAcceptNames(false); // No Notebook variables allowed
+  double aMin = index.column() == StdMeshersGUI_DistrTableFrame::ArgColumn ? 
+                  myTable->argMinimum( index.row() ) : 
+                  myTable->funcMinimum( index.row() );
+  double aMax = index.column() == StdMeshersGUI_DistrTableFrame::ArgColumn ? 
+                  myTable->argMaximum( index.row() ) : 
+                  myTable->funcMaximum( index.row() );
+  double aStep = index.column() == StdMeshersGUI_DistrTableFrame::ArgColumn ? 
+                     myTable->argStep( index.row() ) : 
+                     myTable->funcStep( index.row() );
+  sb->RangeStepAndValidator( aMin, aMax, aStep, "parametric_precision" );
   sb->setFrame(false);
-  sb->setMinimum( index.column() == StdMeshersGUI_DistrTableFrame::ArgColumn ? 
-                 myTable->argMinimum( index.row() ) : 
-                 myTable->funcMinimum( index.row() ) );
-  sb->setMaximum( index.column() == StdMeshersGUI_DistrTableFrame::ArgColumn ? 
-                 myTable->argMaximum( index.row() ) : 
-                 myTable->funcMaximum( index.row() ) );
-  sb->setSingleStep( index.column() == StdMeshersGUI_DistrTableFrame::ArgColumn ? 
-                    myTable->argStep( index.row() ) : 
-                    myTable->funcStep( index.row() ) );
-  myTable->setEditor( index.row(), index.column(), sb );
+
+  myTable->setEditor( index.row(), index.column(), sb );  
   return sb;
 }
 
@@ -196,7 +203,7 @@ StdMeshersGUI_DistrTableFrame::SpinBoxDelegate::
 setEditorData( QWidget* editor, const QModelIndex& index ) const
 {
   QString value = index.model()->data(index, Qt::DisplayRole).toString();
-  QDoubleSpinBox* sb = static_cast<QDoubleSpinBox*>(editor);
+  SMESHGUI_SpinBox* sb = static_cast<SMESHGUI_SpinBox*>(editor);
 
   bool bOk = false;
   double v = value.toDouble( &bOk );
@@ -208,17 +215,17 @@ setEditorData( QWidget* editor, const QModelIndex& index ) const
 void
 StdMeshersGUI_DistrTableFrame::SpinBoxDelegate::
 setModelData( QWidget* editor, QAbstractItemModel* model, 
-             const QModelIndex& index ) const
+              const QModelIndex& index ) const
 {
-  QDoubleSpinBox* sb = static_cast<QDoubleSpinBox*>(editor);
+  SMESHGUI_SpinBox* sb = static_cast<SMESHGUI_SpinBox*>(editor);
   model->setData( index, QString::number( sb->value() ), Qt::DisplayRole );
 }
 
 void 
 StdMeshersGUI_DistrTableFrame::SpinBoxDelegate::
 updateEditorGeometry( QWidget* editor,
-                     const QStyleOptionViewItem& option, 
-                     const QModelIndex& /*index*/ ) const
+                      const QStyleOptionViewItem& option, 
+                      const QModelIndex& /*index*/ ) const
 {
   editor->setGeometry( option.rect );
 }
@@ -238,6 +245,8 @@ Table( QWidget* parent, int rows )
   QStringList labs;
   labs << "t" << "f(t)";
   setHorizontalHeaderLabels( labs );
+  this->horizontalHeader()->setStretchLastSection(true);
+  this->horizontalHeader()->setDefaultSectionSize(60);
 
   while( rows-- )
     addRow();
@@ -247,7 +256,7 @@ Table( QWidget* parent, int rows )
 
 void
 StdMeshersGUI_DistrTableFrame::Table::
-setEditor( int r, int c, QDoubleSpinBox* sb )
+setEditor( int r, int c, SMESHGUI_SpinBox* sb )
 {
   myEditorData.r  = r;
   myEditorData.c  = c;
@@ -405,15 +414,15 @@ sizeHint() const
 {
   if( cachedSizeHint().isValid() )
     return cachedSizeHint();
-
-  QSize sh = QTableWidget::sizeHint();
-  if( sh.width() < 400 )
-    sh.setWidth( 400 );
-  if( sh.height() < 200 )
-    sh.setHeight( 200 );
-
-  setCachedSizeHint( sh );
-  return sh;
+  return QTableWidget::sizeHint();
+//   QSize sh = QTableWidget::sizeHint();
+//   if( sh.width() < 400 )
+//     sh.setWidth( 400 );
+//   if( sh.height() < 200 )
+//     sh.setHeight( 200 );
+// 
+//   setCachedSizeHint( sh );
+//   return sh;
 }
 
 void
@@ -501,38 +510,32 @@ StdMeshersGUI_DistrTableFrame::
 StdMeshersGUI_DistrTableFrame( QWidget* parent )
   : QWidget( parent )
 {
-  QVBoxLayout* main = new QVBoxLayout( this );
+  QGridLayout* main = new QGridLayout( this );
   main->setMargin( 0 );
   main->setSpacing( 0 );
 
   // ---
   myTable = new Table( this );
   connect( myTable, SIGNAL( valueChanged( int, int ) ), this, SIGNAL( valueChanged( int, int ) ) );
-  
-  // ---
-  QWidget* aButFrame = new QWidget( this );
-  QHBoxLayout* butLay = new QHBoxLayout( aButFrame );
-  butLay->setContentsMargins( 0, SPACING, 0, SPACING );
-  butLay->setSpacing( SPACING );
 
-  myButtons[ InsertRowBtn ] = new QPushButton( tr( "SMESH_INSERT_ROW" ), aButFrame );
-  myButtons[ RemoveRowBtn ] = new QPushButton( tr( "SMESH_REMOVE_ROW" ), aButFrame );
+  myButtons[ InsertRowBtn ] = new QPushButton( tr( "SMESH_INSERT_ROW" ), this );
+  myButtons[ RemoveRowBtn ] = new QPushButton( tr( "SMESH_REMOVE_ROW" ), this );
 
-  butLay->addWidget( myButtons[ InsertRowBtn ] );
-  butLay->addWidget( myButtons[ RemoveRowBtn ] );
-  butLay->addStretch();
 
   // ---
-  main->addWidget( myTable );
-  main->addWidget( aButFrame );
+  main->addWidget( myTable , 0, 0, 1, 3);
+  main->addWidget( myButtons[ InsertRowBtn ] , 1, 0);
+  main->addWidget( myButtons[ RemoveRowBtn ] , 1, 1);
+  main->setColumnStretch(2, 1);
+  main->setSpacing( SPACING );
   
   // ---
   connect( myButtons[ InsertRowBtn ], SIGNAL( clicked() ), this, SLOT( onInsert() ) );
   connect( myButtons[ RemoveRowBtn ], SIGNAL( clicked() ), this, SLOT( onRemove() ) );
   connect( myTable, SIGNAL( currentCellChanged( int, int, int, int ) ),
-          this,    SIGNAL( currentChanged( int, int ) ) );
+           this,    SIGNAL( currentChanged( int, int ) ) );
   connect( myTable, SIGNAL( cellChanged( int, int ) ),
-          this,    SIGNAL( valueChanged( int, int ) ) );
+           this,    SIGNAL( valueChanged( int, int ) ) );
 }
 
 StdMeshersGUI_DistrTableFrame::
index 11a4ab33332b25dfdf94b09fa2ad65078fc8ee7b..9ba227c3aabdfc36e183b371d9349324950e694c 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : StdMeshersGUI_DistrTable.h
 // Author : Open CASCADE S.A.S.
 //
diff --git a/src/StdMeshersGUI/StdMeshersGUI_FixedPointsParamWdg.cxx b/src/StdMeshersGUI/StdMeshersGUI_FixedPointsParamWdg.cxx
new file mode 100644 (file)
index 0000000..13b575e
--- /dev/null
@@ -0,0 +1,394 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+// File   : StdMeshersGUI_FixedPointsParamWdg.cxx
+// Author : Open CASCADE S.A.S.
+// SMESH includes
+//
+#include "StdMeshersGUI_FixedPointsParamWdg.h"
+
+#include <SMESHGUI_SpinBox.h>
+
+#include <SalomeApp_IntSpinBox.h>
+
+// Qt includes
+#include <QPushButton>
+#include <QIntValidator>
+#include <QGridLayout>
+#include <QListWidget>
+#include <QListWidgetItem>
+#include <QItemDelegate>
+#include <QTreeWidget>
+#include <QTreeWidgetItem>
+#include <QCheckBox>
+#include <QLineEdit>
+#include <QItemDelegate>
+#include <QKeyEvent>
+
+#define SPACING 6
+#define MARGIN 0
+#define SAME_TEXT "-/-"
+
+#define TOLERANCE 1e-7
+#define EQUAL_DBL(a,b) (fabs(a-b)<TOLERANCE)
+#define LT_DBL(a,b) ((a<b)&&!EQUAL_DBL(a,b))
+#define GT_DBL(a,b) ((a>b)&&!EQUAL_DBL(a,b))
+
+/*
+ * class : Tree Widget Item Delegate
+ * purpose  : Custom item delegate
+ */
+
+class StdMeshersGUI_FixedPointsParamWdg::LineDelegate : public QItemDelegate
+{
+public:
+  LineDelegate( QTreeWidget* );
+  ~LineDelegate() {}
+
+  QWidget*     createEditor( QWidget*, const QStyleOptionViewItem&, const QModelIndex& ) const;
+  void         setModelData( QWidget* editor, QAbstractItemModel* model, const QModelIndex& index ) const;
+
+private:
+  QTreeWidget* myTreeWidget;
+};
+
+StdMeshersGUI_FixedPointsParamWdg::LineDelegate::LineDelegate( QTreeWidget* parent )
+  : QItemDelegate( parent ),
+    myTreeWidget( parent )
+{
+}
+
+QWidget* StdMeshersGUI_FixedPointsParamWdg::LineDelegate::createEditor( QWidget* parent,
+                                                                        const QStyleOptionViewItem& option,
+                                                                        const QModelIndex& index ) const
+{
+  QWidget* w = 0;
+  if ( (index.column() == 1 ) ) {
+    SalomeApp_IntSpinBox* sb = new SalomeApp_IntSpinBox( parent );
+    sb->setAcceptNames( false ); // No Notebook variables allowed
+    sb->setFrame( false );
+    sb->setRange( 1, 999);
+    w = sb;
+  }
+
+  return w;
+}
+
+void StdMeshersGUI_FixedPointsParamWdg::LineDelegate::setModelData( QWidget* editor, 
+                                                                    QAbstractItemModel* model, 
+                                                                    const QModelIndex& index ) const
+{
+  model->setData( index, qobject_cast<SalomeApp_IntSpinBox*>( editor )->value(), Qt::EditRole );
+  model->setData( index, qobject_cast<SalomeApp_IntSpinBox*>( editor )->value(), Qt::UserRole );
+}
+
+//================================================================================
+/*!
+ *  Constructor
+ */
+//================================================================================
+
+StdMeshersGUI_FixedPointsParamWdg
+::StdMeshersGUI_FixedPointsParamWdg( QWidget * parent ): 
+  QWidget( parent )
+{
+  QGridLayout* edgesLayout = new QGridLayout( this );
+  edgesLayout->setMargin( MARGIN );
+  edgesLayout->setSpacing( SPACING );
+  
+  myListWidget   = new QListWidget( this );
+  myTreeWidget   = new QTreeWidget( this );
+  mySpinBox      = new SMESHGUI_SpinBox( this );
+  myAddButton    = new QPushButton( tr( "SMESH_BUT_ADD" ),    this );
+  myRemoveButton = new QPushButton( tr( "SMESH_BUT_REMOVE" ), this );      
+  mySameValues   = new QCheckBox( tr("SMESH_SAME_NB_SEGMENTS"), this);
+
+  myListWidget->setSelectionMode( QListWidget::ExtendedSelection );
+
+  myTreeWidget->setColumnCount(2);
+  myTreeWidget->setHeaderLabels( QStringList() << tr( "SMESH_RANGE" ) << tr( "SMESH_NB_SEGMENTS" ) );
+  myTreeWidget->setColumnWidth( 1, 40 );
+  myTreeWidget->setColumnWidth( 2, 30 );
+  myTreeWidget->setItemDelegate( new LineDelegate( myTreeWidget ) );
+
+  edgesLayout->addWidget(myListWidget,   0, 0, 4, 1);
+  edgesLayout->addWidget(mySpinBox,      0, 1);
+  edgesLayout->addWidget(myAddButton,    1, 1);
+  edgesLayout->addWidget(myRemoveButton, 2, 1);
+  edgesLayout->addWidget(myTreeWidget,   0, 2, 4, 1);
+  edgesLayout->addWidget(mySameValues,   4, 0, 1, 3);
+  edgesLayout->setRowStretch( 3, 5 );
+  edgesLayout->setColumnStretch(0, 1);
+  edgesLayout->setColumnStretch(1, 0);
+  edgesLayout->setColumnStretch(2, 2);
+
+  myListWidget->setMinimumWidth( 80 );
+  myTreeWidget->setMinimumWidth( 200 );
+
+  mySpinBox->setAcceptNames( false ); // No Notebook variables allowed
+  mySpinBox->RangeStepAndValidator( 0., 1., .1, "parametric_precision" );
+  myListWidget->setMinimumWidth( 70 );
+
+  connect( myAddButton,    SIGNAL( clicked() ),              SLOT( onAdd() ) );
+  connect( myRemoveButton, SIGNAL( clicked() ),              SLOT( onRemove() ) );
+  connect( mySameValues,   SIGNAL( stateChanged( int ) ),    SLOT( onCheckBoxChanged() ) );
+  connect( mySpinBox,      SIGNAL( valueChanged( double ) ), SLOT( updateState() ) );
+  connect( myListWidget,   SIGNAL( itemSelectionChanged() ), SLOT( updateState() ) );
+  myListWidget->installEventFilter( this );
+
+  clear();
+}
+
+//================================================================================
+/*!
+ *  Destructor
+ */
+//================================================================================
+
+StdMeshersGUI_FixedPointsParamWdg::~StdMeshersGUI_FixedPointsParamWdg()
+{
+}
+
+//================================================================================
+/*!
+ *  Event filter
+ */
+//================================================================================
+bool StdMeshersGUI_FixedPointsParamWdg::eventFilter( QObject* o, QEvent* e )
+{
+  if ( o == myListWidget && e->type() == QEvent::KeyPress ) {
+    QKeyEvent* ke = (QKeyEvent*)e;
+    if ( ke->key() == Qt::Key_Delete )
+      removePoints();
+  }
+  return QWidget::eventFilter( o, e );
+}
+
+//================================================================================
+/*!
+ *  Clear widget
+ */
+//================================================================================
+void StdMeshersGUI_FixedPointsParamWdg::clear()
+{
+  myTreeWidget->clear();
+  myListWidget->clear();
+  myTreeWidget->addTopLevelItem( newTreeItem( 0, 1 ) );
+  mySpinBox->setValue( 0. );
+  onCheckBoxChanged();
+  updateState();
+}
+
+//=================================================================================
+// function : onAdd()
+// purpose  : Called when Add Button Clicked
+//=================================================================================
+void StdMeshersGUI_FixedPointsParamWdg::onAdd()
+{
+  addPoint( mySpinBox->value() );
+}
+         
+//=================================================================================
+// function : onRemove()
+// purpose  : Called when Remove Button Clicked
+//=================================================================================
+void StdMeshersGUI_FixedPointsParamWdg::onRemove()
+{
+  removePoints();
+}
+
+//=================================================================================
+// function : newTreeItem()
+// purpose  : Called to create TreeItem
+//=================================================================================
+
+QTreeWidgetItem* StdMeshersGUI_FixedPointsParamWdg::newTreeItem( double v1, double v2 )
+{
+  QTreeWidgetItem* anItem = new QTreeWidgetItem();
+  anItem->setText( 0, treeItemText( v1, v2 ) );
+  anItem->setText( 1, QString::number( 1 ) );
+  anItem->setData( 1, Qt::UserRole, 1 );
+  return anItem;
+}
+
+//=================================================================================
+// function : newListItem()
+// purpose  : Called to create ListItem
+//=================================================================================
+
+QListWidgetItem* StdMeshersGUI_FixedPointsParamWdg::newListItem( double v )
+{
+  QListWidgetItem* anItem = new QListWidgetItem( QString::number( v ) );
+  anItem->setData( Qt::UserRole, v );
+  return anItem;
+}
+
+//=================================================================================
+// function : itemText()
+// purpose  : Called to convert Values to Text
+//=================================================================================
+
+QString StdMeshersGUI_FixedPointsParamWdg::treeItemText( double v1, double v2 )
+{
+  return QString( "%1 - %2" ).arg( v1 ).arg( v2 );
+}
+
+//=================================================================================
+// function : addPoint()
+// purpose  : Called to Add new Point
+//=================================================================================
+void StdMeshersGUI_FixedPointsParamWdg::addPoint( double v)
+{
+  if ( GT_DBL(v, 0.0) && LT_DBL(v, 1.0)) {
+    bool toInsert = true;
+    int idx = myTreeWidget->topLevelItemCount()-1;
+    for ( int i = 0 ; i < myListWidget->count(); i++ ) {
+      double lv = point( i );
+      if ( EQUAL_DBL(lv, v) ) { toInsert = false; break; }
+      else if ( GT_DBL(lv, v) ) {
+        idx = i; break;
+      }
+    }
+    if ( toInsert ) {
+      double v1 = idx == 0 ? 0 : point( idx-1 );
+      double v2 = idx == myTreeWidget->topLevelItemCount()-1 ? 1 : point( idx );
+      myTreeWidget->insertTopLevelItem( idx, newTreeItem( v1, v ) );
+      myTreeWidget->topLevelItem( idx+1 )->setText( 0, treeItemText( v, v2 ) );
+      myListWidget->insertItem( idx, newListItem( v ) );
+      onCheckBoxChanged();
+    }
+  }
+  updateState();
+}
+
+//=================================================================================
+// function : removePoints()
+// purpose  : Called to remove selected points
+//=================================================================================
+void StdMeshersGUI_FixedPointsParamWdg::removePoints()
+{
+  QList<QListWidgetItem*> selItems = myListWidget->selectedItems();
+  QListWidgetItem* item;
+  foreach ( item, selItems ) {
+    int idx = myListWidget->row( item );
+    delete myTreeWidget->topLevelItem( idx );
+    delete item;
+    myTreeWidget->topLevelItem( idx )->setText( 0, treeItemText( idx == 0 ? 0 : point( idx-1 ),
+                                                                 idx > myListWidget->count()-1 ? 1 : point( idx ) ) );
+  }
+  onCheckBoxChanged();
+  updateState();
+}
+
+double StdMeshersGUI_FixedPointsParamWdg::point( int idx ) const
+{
+  return idx >= 0 && idx < myListWidget->count() ? myListWidget->item( idx )->data( Qt::UserRole ).toDouble() : 0.;
+}
+
+void StdMeshersGUI_FixedPointsParamWdg::setNbSegments( int idx, int val )
+{
+  if ( idx >= 0 && idx < myTreeWidget->topLevelItemCount() ) {
+    myTreeWidget->topLevelItem( idx )->setData( 1, Qt::UserRole, val );
+    myTreeWidget->topLevelItem( idx )->setText( 1, idx > 0 && mySameValues->isChecked() ? QString( SAME_TEXT ) : QString::number( val ) );
+  }
+}
+
+int StdMeshersGUI_FixedPointsParamWdg::nbSegments( int idx ) const
+{
+  return idx >= 0 && idx < myTreeWidget->topLevelItemCount() ? myTreeWidget->topLevelItem( idx )->data( 1, Qt::UserRole ).toInt() : 1;
+}
+
+//=================================================================================
+// function : onCheckBoxChanged()
+// purpose  : Called when Check Box Clicked
+//=================================================================================
+void StdMeshersGUI_FixedPointsParamWdg::onCheckBoxChanged()
+{
+  for ( int i = 0; i < myTreeWidget->topLevelItemCount(); i++ ) {
+    QTreeWidgetItem* anItem = myTreeWidget->topLevelItem(i);
+    setNbSegments( i, nbSegments( i ) );
+    anItem->setFlags( mySameValues->isChecked() && i > 0 ? anItem->flags() & ~Qt::ItemIsEditable : anItem->flags() | Qt::ItemIsEditable );
+  }
+}
+
+//=================================================================================
+// function : updateState()
+// purpose  : Update widgets state
+//=================================================================================
+void StdMeshersGUI_FixedPointsParamWdg::updateState()
+{
+  double v = mySpinBox->value();
+  myAddButton->setEnabled( GT_DBL(v, 0.0) && LT_DBL(v, 1.0) );
+  myRemoveButton->setEnabled( myListWidget->selectedItems().count() > 0 );
+}
+
+//=================================================================================
+// function : GetListOfPoints
+// purpose  : Called to get the list of Edges IDs
+//=================================================================================
+SMESH::double_array_var StdMeshersGUI_FixedPointsParamWdg::GetListOfPoints()
+{
+  SMESH::double_array_var anArray = new SMESH::double_array;
+  int size = myListWidget->count();
+  anArray->length( size );
+  for (int i = 0; i < size; i++) {
+    anArray[i] = point(i);
+  }
+  return anArray;
+}
+
+//=================================================================================
+// function : SetListOfPoints
+// purpose  : Called to set the list of Points
+//=================================================================================
+void StdMeshersGUI_FixedPointsParamWdg::SetListOfPoints( SMESH::double_array_var thePoints)
+{
+  clear();
+  for ( int i = 0; i < thePoints->length(); i++ ) {
+    addPoint( thePoints[ i ] );
+  }
+}
+
+//=================================================================================
+// function : GetListOfSegments
+// purpose  : Called to get the list Number of Segments
+//=================================================================================
+SMESH::long_array_var StdMeshersGUI_FixedPointsParamWdg::GetListOfSegments()
+{
+  SMESH::long_array_var anArray = new SMESH::long_array;
+  int size = mySameValues->isChecked() ? 1 : myTreeWidget->topLevelItemCount();
+  anArray->length( size );
+  for (int i = 0; i < size; i++) {
+    anArray[i] = nbSegments( i );
+  }
+  return anArray;
+}
+
+//=================================================================================
+// function : SetListOfPoints
+// purpose  : Called to set the list of Points
+//=================================================================================
+void StdMeshersGUI_FixedPointsParamWdg::SetListOfSegments( SMESH::long_array_var theSegments)
+{
+  if ( myListWidget->count() > 0 && theSegments->length() == 1)
+    mySameValues->setChecked(true);
+  for ( int i = 0; i < theSegments->length(); i++ ) {
+    setNbSegments( i, theSegments[i] );
+  }
+}
diff --git a/src/StdMeshersGUI/StdMeshersGUI_FixedPointsParamWdg.h b/src/StdMeshersGUI/StdMeshersGUI_FixedPointsParamWdg.h
new file mode 100644 (file)
index 0000000..312b00a
--- /dev/null
@@ -0,0 +1,92 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+// File   : StdMeshersGUI_FixedPointsParamWdg.h
+// Author : Open CASCADE S.A.S. (dmv)
+//
+#ifndef STDMESHERSGUI_FIXEDPOINTSPARAMWGD_H
+#define STDMESHERSGUI_FIXEDPOINTSPARAMWGD_H
+
+// SMESH includes
+#include <SMESHGUI.h>
+#include "SMESH_StdMeshersGUI.hxx"
+
+// Qt includes
+#include <QWidget>
+#include <QStringList>
+
+class SMESHGUI;
+class SMESHGUI_SpinBox;
+class QPushButton;
+class QLineEdit;
+class QCheckBox;
+class QListWidget;
+class QListWidgetItem;
+class QTreeWidget;
+class QTreeWidgetItem;
+
+class STDMESHERSGUI_EXPORT StdMeshersGUI_FixedPointsParamWdg : public QWidget
+{
+  Q_OBJECT
+
+    class LineDelegate;
+
+public:
+  StdMeshersGUI_FixedPointsParamWdg( QWidget* parent = 0 );
+  ~StdMeshersGUI_FixedPointsParamWdg();
+
+  bool                           eventFilter( QObject*, QEvent* );
+
+  SMESH::double_array_var        GetListOfPoints();
+  void                           SetListOfPoints( SMESH::double_array_var );
+
+  SMESH::long_array_var          GetListOfSegments();
+  void                           SetListOfSegments( SMESH::long_array_var );
+
+  QString                        GetValue() const { return myParamValue; }
+
+private slots:
+  void                           onAdd(); 
+  void                           onRemove(); 
+  void                           onCheckBoxChanged();
+  void                           updateState();
+
+private:
+  void                           clear();
+  void                           addPoint( double ); 
+  void                           removePoints(); 
+  double                         point( int ) const;
+  void                           setNbSegments( int, int );
+  int                            nbSegments( int ) const;
+
+  static QTreeWidgetItem*        newTreeItem( double v1, double v2 );
+  static QListWidgetItem*        newListItem( double v1 );
+  static QString                 treeItemText( double v1, double v2 );
+
+private:
+  QListWidget*                   myListWidget;
+  QTreeWidget*                   myTreeWidget;
+  SMESHGUI_SpinBox*              mySpinBox;
+  QPushButton*                   myAddButton;
+  QPushButton*                   myRemoveButton;
+  QCheckBox*                     mySameValues;
+  QString                        myParamValue;
+};
+
+#endif // STDMESHERSGUI_FIXEDPOINTSPARAMWGD_H
index ffdc4a7f151ff310022a74d0bef3f16f75891390..ee46af5b11a5adfc286d2f14e6d9ff17aa50130d 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : StdMeshersGUI_LayerDistributionParamWdg.cxx
 // Author : Open CASCADE S.A.S.
 // SMESH includes
@@ -50,7 +51,7 @@
 
 StdMeshersGUI_LayerDistributionParamWdg
 ::StdMeshersGUI_LayerDistributionParamWdg(SMESH::SMESH_Hypothesis_ptr hyp,
-                                         const QString& theName,
+                                          const QString& theName,
                                           QDialog* dlg): 
   QWidget(), myName(theName), myDlg( dlg )
 {
@@ -198,19 +199,26 @@ void StdMeshersGUI_LayerDistributionParamWdg::onEdit()
     return;
 
   CORBA::String_var hypType = myHyp->GetName();
-  SMESHGUI_GenericHypothesisCreator*
-    editor = SMESH::GetHypothesisCreator( hypType.in() );
+  // BUG 0020378
+  SMESHGUI_GenericHypothesisCreator* editor = SMESH::GetHypothesisCreator(hypType.in());
   if ( !editor ) return;
 
-  if ( myDlg ) myDlg->hide();
+  if ( myDlg )
+    myDlg->hide();
 
   try {
     QWidget* parent = this;
-    if ( myDlg ) parent = myDlg->parentWidget();
-    editor->edit( myHyp, myName, parent );
+    if ( myDlg )
+      parent = myDlg->parentWidget();
+    editor->edit( myHyp, myName, parent, this, SLOT( onEdited( int ) ) );
   }
-  catch(...) {
+  catch(...)
+  {
   }
+}
 
-  if ( myDlg ) myDlg->show();
+void StdMeshersGUI_LayerDistributionParamWdg::onEdited( int result )
+{
+  if ( myDlg )
+    myDlg->show();
 }
index b04f2a60533ef0eccb0127884949b0cc210c73d2..41224a41258d3056687f96a3aef8f7216438dc1e 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : StdMeshersGUI_LayerDistributionParamWdg.h
 // Author : Open CASCADE S.A.S.
 //
@@ -51,7 +52,7 @@ class STDMESHERSGUI_EXPORT StdMeshersGUI_LayerDistributionParamWdg : public QWid
 
 public:
   StdMeshersGUI_LayerDistributionParamWdg(SMESH::SMESH_Hypothesis_ptr,
-                                         const QString&,
+                                          const QString&,
                                           QDialog*);
   ~StdMeshersGUI_LayerDistributionParamWdg();
 
@@ -65,6 +66,7 @@ private slots:
   void onCreate(); 
   void onEdit(); 
   void onHypTypePopup( QAction* );
+  void onEdited(int);
 
 private:
   void init();
index 9e8e0bda842b80b5672c123d7dacee87a15723ca..f4e65c3f659a75fbb46f3e879cb08c76e2b50cde 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : StdMeshersGUI_NbSegmentsCreator.cxx
 // Author : Open CASCADE S.A.S.
 // SMESH includes
@@ -26,6 +27,7 @@
 #include "StdMeshersGUI_NbSegmentsCreator.h"
 #include "StdMeshersGUI_DistrTable.h"
 #include "StdMeshersGUI_DistrPreview.h"
+#include "StdMeshersGUI_SubShapeSelectorWdg.h"
 
 #include <SMESHGUI.h>
 #include <SMESHGUI_Utils.h>
@@ -96,17 +98,17 @@ bool StdMeshersGUI_NbSegmentsCreator::checkParams( QString& msg ) const
 QFrame* StdMeshersGUI_NbSegmentsCreator::buildFrame()
 {
   QFrame* fr = new QFrame();
+  fr->setMinimumWidth(460);
 
   QVBoxLayout* lay = new QVBoxLayout( fr );
   lay->setMargin( 0 );
-  lay->setSpacing( 0 );
+  lay->setSpacing( SPACING );
 
   QGroupBox* GroupC1 = new QGroupBox( tr( "SMESH_ARGUMENTS" ), fr );
   lay->addWidget( GroupC1 );
 
   StdMeshers::StdMeshers_NumberOfSegments_var h =
     StdMeshers::StdMeshers_NumberOfSegments::_narrow( hypothesis() );
-  myPreview = new StdMeshersGUI_DistrPreview( GroupC1, h.in() );
 
   myGroupLayout = new QGridLayout( GroupC1 );
   myGroupLayout->setSpacing( SPACING );
@@ -125,6 +127,7 @@ QFrame* StdMeshersGUI_NbSegmentsCreator::buildFrame()
     row++;
   }
 
+
   // 1)  number of segments
   myGroupLayout->addWidget( new QLabel( tr( "SMESH_NB_SEGMENTS_PARAM" ), GroupC1 ), row, 0 );
   myNbSeg = new SalomeApp_IntSpinBox( GroupC1 );
@@ -133,6 +136,7 @@ QFrame* StdMeshersGUI_NbSegmentsCreator::buildFrame()
   myGroupLayout->addWidget( myNbSeg, row, 1 );
   row++;
 
+  
   // 2)  type of distribution
   myGroupLayout->addWidget( new QLabel( tr( "SMESH_DISTR_TYPE" ), GroupC1 ), row, 0 );
   myDistr = new QtxComboBox( GroupC1 );
@@ -145,32 +149,43 @@ QFrame* StdMeshersGUI_NbSegmentsCreator::buildFrame()
   myGroupLayout->addWidget( myDistr, row, 1 );
   row++;
 
+  
   // 3)  scale
   myGroupLayout->addWidget( myLScale = new QLabel( tr( "SMESH_NB_SEGMENTS_SCALE_PARAM" ), GroupC1 ), row, 0 );
   myScale = new SMESHGUI_SpinBox( GroupC1 );
-  myScale->RangeStepAndValidator( 1E-5, 1E+5, 0.1, 6 );
+  myScale->RangeStepAndValidator( 1E-5, 1E+5, 0.1, "parametric_precision" );
   myGroupLayout->addWidget( myScale, row, 1 );
   row++;
 
-  myInfo = new QLabel( tr( "SMESH_FUNC_DOMAIN" ), GroupC1 );
-  myGroupLayout->addWidget( myInfo, row, 0, 1, 2 );
-  row++;
   
-  // 4)  table
-  myGroupLayout->addWidget( myLTable = new QLabel( tr( "SMESH_TAB_FUNC" ), GroupC1 ), row, 0 );
-  myTable = new StdMeshersGUI_DistrTableFrame( GroupC1 );
-  myGroupLayout->addWidget( myTable, row, 1 );
+  // 4) Distribution definition
+  QGridLayout* myDistLayout = new QGridLayout(GroupC1);
+  myGroupLayout->addLayout( myDistLayout, row, 0, 1, 2 );
   myGroupLayout->setRowStretch( row, 1 );
-  myTableRow = row;
-  row++;
+  row ++;
 
-  // 5)  expression
-  myGroupLayout->addWidget( myLExpr = new QLabel( tr( "SMESH_EXPR_FUNC" ), GroupC1 ), row, 0 );
+       // a)  expression
+  QHBoxLayout* myExprLayout = new QHBoxLayout(GroupC1);
+  myExprLayout->addWidget( myLExpr = new QLabel( "f(t)=", GroupC1 ), 0);
   myExpr = new QLineEdit( GroupC1 );
-  myGroupLayout->addWidget( myExpr, row, 1 );
-  row++;
+  myExprLayout->addWidget( myExpr,1);
+  myDistLayout->addLayout(myExprLayout,1 ,0);
+  myDistLayout->setRowStretch(2, 1);
 
-  // 6)  conversion (radiogroup)
+       // b)  warning
+  myInfo = new QLabel( tr( "SMESH_FUNC_DOMAIN" ), GroupC1 );
+  myDistLayout->addWidget( myInfo, 0, 0, 1, 2);
+  
+       // c)  table
+  myTable = new StdMeshersGUI_DistrTableFrame( GroupC1 );
+  myDistLayout->addWidget( myTable, 1, 0, 2, 1 );
+
+       // d) preview
+  myPreview = new StdMeshersGUI_DistrPreview( GroupC1, h.in() );  
+  myPreview->setMinimumHeight(220);
+  myDistLayout->addWidget( myPreview, 1, 1, 2, 1 );
+  
+  // 5)  conversion (radiogroup)
   myConvBox = new QGroupBox( tr( "SMESH_CONV_MODE" ), GroupC1 );
   myConv = new QButtonGroup( GroupC1 );
 
@@ -189,17 +204,30 @@ QFrame* StdMeshersGUI_NbSegmentsCreator::buildFrame()
   myGroupLayout->addWidget( myConvBox, row, 0, 1, 2 );
   row++;
 
-  // 7) distribution preview
-  myGroupLayout->addWidget( myPreview, row, 0, 1, 2 );
-  myGroupLayout->setRowStretch( row, 1 );
-  myPreviewRow = row;
-  row++;
 
+  // 6) reverse edge parameters
+  myReversedEdgesBox = new QGroupBox(tr( "SMESH_REVERSED_EDGES" ), fr);
+  QHBoxLayout* edgeLay = new QHBoxLayout( myReversedEdgesBox );
+
+  myDirectionWidget = new StdMeshersGUI_SubShapeSelectorWdg( myReversedEdgesBox );
+  QString aGeomEntry = getShapeEntry();
+  QString aMainEntry = getMainShapeEntry();
+  if ( aGeomEntry == "" )
+    aGeomEntry = h->GetObjectEntry();
+  myDirectionWidget->SetGeomShapeEntry( aGeomEntry );
+  myDirectionWidget->SetMainShapeEntry( aMainEntry );
+  myDirectionWidget->SetListOfIDs( h->GetReversedEdges() );
+  edgeLay->addWidget( myDirectionWidget );
+
+  lay->addWidget( myReversedEdgesBox );
+  lay->setStretchFactor( GroupC1, 2);
+  lay->setStretchFactor( myReversedEdgesBox, 1);
+  
   connect( myNbSeg, SIGNAL( valueChanged( const QString& ) ), this, SLOT( onValueChanged() ) );
   connect( myDistr, SIGNAL( activated( int ) ), this, SLOT( onValueChanged() ) );
   connect( myTable, SIGNAL( valueChanged( int, int ) ), this, SLOT( onValueChanged() ) );
   connect( myExpr,  SIGNAL( textChanged( const QString& ) ), this, SLOT( onValueChanged() ) );
-  connect( myConv,  SIGNAL( cuttonClicked( int ) ), this, SLOT( onValueChanged() ) );
+  connect( myConv,  SIGNAL( buttonClicked( int ) ), this, SLOT( onValueChanged() ) );
 
   return fr;
 }
@@ -271,10 +299,12 @@ QString StdMeshersGUI_NbSegmentsCreator::storeParams() const
     break;
   }
   if ( hasConv )
+  {
     if ( data.myConv )
       valStr += "; " + tr("SMESH_CUT_NEG_MODE");
     else
       valStr += "; " + tr("SMESH_EXP_MODE");
+  }
 
   return valStr;
 }
@@ -287,17 +317,17 @@ bool StdMeshersGUI_NbSegmentsCreator::readParamsFromHypo( NbSegmentsHypothesisDa
   h_data.myName = hypName();
 
   h_data.myNbSeg = (int) h->GetNumberOfSegments();
-  
-  SMESH::ListOfParameters_var aParameters = h->GetLastParameters();
 
-  h_data.myNbSegVarName  = (aParameters->length() > 0) ? QString(aParameters[0].in()) : QString("");
+  CORBA::String_var aVaribaleName = h->GetVarParameter( "SetNumberOfSegments" );
+  h_data.myNbSegVarName = aVaribaleName.in();
 
   int distr = (int) h->GetDistrType();
   h_data.myDistrType = distr;
   h_data.myScale = distr==1 ? h->GetScaleFactor() : 1.0;
   
-  if(distr==1){
-    h_data.myScaleVarName  = (aParameters->length() > 1) ? QString(aParameters[1].in()) : QString("");
+  if(distr==1) {
+    aVaribaleName = h->GetVarParameter( "SetScaleFactor" );
+    h_data.myScaleVarName = aVaribaleName.in();
   }
   else 
     h_data.myScaleVarName = QString("");
@@ -334,20 +364,23 @@ bool StdMeshersGUI_NbSegmentsCreator::storeParamsToHypo( const NbSegmentsHypothe
     if( isCreation() )
       SMESH::SetName( SMESH::FindSObject( h ), h_data.myName.toLatin1().data() );
 
-    QStringList aVariablesList;
-    aVariablesList.append(h_data.myNbSegVarName);
-
+    h->SetVarParameter( h_data.myNbSegVarName.toLatin1().constData(), "SetNumberOfSegments" );
     h->SetNumberOfSegments( h_data.myNbSeg );
     int distr = h_data.myDistrType;
     h->SetDistrType( distr );
     
     if( distr==1 ) {
+      h->SetVarParameter( h_data.myScaleVarName.toLatin1().constData(), "SetScaleFactor" );
       h->SetScaleFactor( h_data.myScale );
-      aVariablesList.append(h_data.myScaleVarName);
     }
     if( distr==2 || distr==3 )
       h->SetConversionMode( h_data.myConv );
 
+    if( distr==1 || distr==2 || distr==3 ) {
+      h->SetReversedEdges( myDirectionWidget->GetListOfIDs() );
+      h->SetObjectEntry( myDirectionWidget->GetMainShapeEntry() );
+    }
+
     if( distr==2 )
       h->SetTableFunction( h_data.myTable );
 
@@ -356,8 +389,6 @@ bool StdMeshersGUI_NbSegmentsCreator::storeParamsToHypo( const NbSegmentsHypothe
     //setting of function must follow after setConversionMode, because otherwise
     //the function will be checked with old conversion mode, so that it may occurs
     //unexpected errors for user
-
-    h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList));
   }
   catch(const SALOME::SALOME_Exception& ex)
   {
@@ -400,23 +431,17 @@ void StdMeshersGUI_NbSegmentsCreator::onValueChanged()
 
   myScale->setShown( distr==1 );
   myLScale->setShown( distr==1 );
+  myReversedEdgesBox->setShown( !distr==0 );
+  myDirectionWidget->showPreview( !distr==0 );
 
   bool isFunc = distr==2 || distr==3;
   myPreview->setShown( isFunc );
-  myGroupLayout->setRowStretch( myPreviewRow, isFunc ? 1 : 0 );
-
   myConvBox->setShown( isFunc );
-
-  if( distr==2 )
-    myTable->show();
-  else
-    myTable->hide();
-  myLTable->setShown( distr==2 );
-  myGroupLayout->setRowStretch( myTableRow, distr==2 ? 1 : 0 );
-
+  
+  myTable->setShown( distr==2 );
   myExpr->setShown( distr==3 );
   myLExpr->setShown( distr==3 );
-  myInfo->setShown( isFunc );
+  myInfo->setShown( distr==3);
 
   //change of preview
   int nbSeg = myNbSeg->value();
@@ -434,8 +459,11 @@ void StdMeshersGUI_NbSegmentsCreator::onValueChanged()
 
   if ( (QtxComboBox*)sender() == myDistr && dlg() ) {
     QApplication::instance()->processEvents();
+    myGroupLayout->invalidate();
+    dlg()->layout()->invalidate();
     dlg()->updateGeometry();
-    dlg()->setMinimumSize( dlg()->minimumSizeHint().width(), dlg()->minimumSizeHint().height() );
+    dlg()->setMinimumSize( dlg()->minimumSizeHint() );
     dlg()->resize( dlg()->minimumSize() );
+    QApplication::instance()->processEvents();
   }
 }
index ba7c7bff85d840f0b10d33e1d9586a6251d5b530..66456e0ca44d30f3b311a47eedeeb9727848a06c 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : StdMeshersGUI_NbSegmentsCreator.h
 // Author : Open CASCADE S.A.S.
 //
@@ -44,6 +45,7 @@ class QButtonGroup;
 class QGroupBox;
 class QGridLayout;
 class QRadioButton;
+class StdMeshersGUI_SubShapeSelectorWdg;
 
 typedef struct
 {
@@ -90,7 +92,10 @@ private:
   QLabel          *myLScale, *myLTable, *myLExpr, *myInfo;
   QGridLayout*     myGroupLayout;
   int              myTableRow, myPreviewRow;
-  QRadioButton*    myCutNeg;
+  //QRadioButton*    myCutNeg;
+  QGroupBox*       myReversedEdgesBox;
+
+  StdMeshersGUI_SubShapeSelectorWdg*    myDirectionWidget;
 };
 
 #endif // STDMESHERSGUI_NBSEGMENTSCREATOR_H
index 37a3ce7eedde8a1706a4ceb00c44cb352aa508f8..1efeb01621c3959b987576933abbdd42feea899b 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : StdMeshersGUI_ObjectReferenceParamWdg.cxx
 // Author : Open CASCADE S.A.S.
 // SMESH includes
 #include <LightApp_SelectionMgr.h>
 #include <SVTK_ViewWindow.h>
 #include <SALOME_ListIO.hxx>
+#include <SALOME_ListIteratorOfListIO.hxx>
 
 // SALOME KERNEL incldues
 #include <SALOMEDSClient_SObject.hxx>
+#include <SALOMEDSClient_Study.hxx>
 
 // Qt includes
 #include <QPushButton>
 //================================================================================
 
 StdMeshersGUI_ObjectReferenceParamWdg::StdMeshersGUI_ObjectReferenceParamWdg
-( SUIT_SelectionFilter* f, QWidget* parent)
-  : QWidget( parent )
+( SUIT_SelectionFilter* f, QWidget* parent, bool multiSelection, bool stretch )
+  : QWidget( parent ), myMultiSelection( multiSelection )
 {
   myFilter = f;
+  myStretchActivated = stretch;
   init();
 }
 
@@ -68,8 +72,8 @@ StdMeshersGUI_ObjectReferenceParamWdg::StdMeshersGUI_ObjectReferenceParamWdg
 //================================================================================
 
 StdMeshersGUI_ObjectReferenceParamWdg::StdMeshersGUI_ObjectReferenceParamWdg
-( MeshObjectType objType, QWidget* parent )
-  : QWidget( parent )
+( MeshObjectType objType, QWidget* parent, bool multiSelection )
+  : QWidget( parent ), myMultiSelection( multiSelection )
 {
   myFilter = new SMESH_TypeFilter( objType );
   init();
@@ -83,7 +87,10 @@ StdMeshersGUI_ObjectReferenceParamWdg::StdMeshersGUI_ObjectReferenceParamWdg
 StdMeshersGUI_ObjectReferenceParamWdg::~StdMeshersGUI_ObjectReferenceParamWdg()
 {
   if ( myFilter )
+  {
+    mySelectionMgr->removeFilter( myFilter );
     delete myFilter;
+  }
 }
 
 
@@ -104,6 +111,8 @@ void StdMeshersGUI_ObjectReferenceParamWdg::init()
   mySelectionMgr = SMESH::GetSelectionMgr( mySMESHGUI );
   mySelectionActivated = false;
   myParamValue = "";
+  myEmptyText = "";
+  myEmptyStyleSheet ="";
 
   SUIT_ResourceMgr* mgr = SMESH::GetResourceMgr( mySMESHGUI );
   QPixmap iconSlct ( mgr->loadPixmap("SMESH", tr("ICON_SELECT")));
@@ -114,10 +123,13 @@ void StdMeshersGUI_ObjectReferenceParamWdg::init()
 
   myObjNameLineEdit = new QLineEdit(this);
   myObjNameLineEdit->setReadOnly(true);
+  myObjNameLineEdit->setStyleSheet(myEmptyStyleSheet);
 
   aHBox->addWidget( mySelButton );
   aHBox->addWidget( myObjNameLineEdit );
-  aHBox->addStretch();
+  if (myStretchActivated){
+    aHBox->addStretch();
+  }
 
   connect( mySelButton, SIGNAL(clicked()), SLOT(activateSelection()));
 }
@@ -141,6 +153,7 @@ void StdMeshersGUI_ObjectReferenceParamWdg::activateSelection()
     connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone()));
   }
   emit selectionActivated();
+  onSelectionDone();
 
   mySelButton->setChecked( mySelectionActivated );
 }
@@ -183,8 +196,9 @@ void StdMeshersGUI_ObjectReferenceParamWdg::AvoidSimultaneousSelection
 
 void StdMeshersGUI_ObjectReferenceParamWdg::SetObject(CORBA::Object_ptr obj)
 {
-  myObject = CORBA::Object::_nil();
-  myObjNameLineEdit->setText( "" );
+  myObjects.clear();
+  myObjNameLineEdit->setText( myEmptyText );
+  myObjNameLineEdit->setStyleSheet(myEmptyStyleSheet);
   myParamValue = "";
 
   _PTR(SObject) sobj;
@@ -192,10 +206,52 @@ void StdMeshersGUI_ObjectReferenceParamWdg::SetObject(CORBA::Object_ptr obj)
     sobj = SMESH::FindSObject (obj);
   if ( sobj ) {
     std::string name = sobj->GetName();
-    myObjNameLineEdit->setText( name.c_str() );
-    myObject = CORBA::Object::_duplicate( obj );
+    myObjNameLineEdit->setText( QString( name.c_str() ).trimmed() );
+    myObjNameLineEdit->setStyleSheet("");
+    myObjects.push_back( CORBA::Object::_duplicate( obj ));
     myParamValue = sobj->GetID().c_str();
+    emit contentModified();
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Initialize selected objects
+ * \param objects - entries of objects
+ */
+//================================================================================
+
+void StdMeshersGUI_ObjectReferenceParamWdg::SetObjects(SMESH::string_array_var& objects)
+{
+  myObjects.clear();
+  myObjNameLineEdit->setText( myEmptyText );
+  myObjNameLineEdit->setStyleSheet(myEmptyStyleSheet);
+  myParamValue = "";
+  bool selChanged = false;
+  
+  for ( unsigned i = 0; i < objects->length(); ++i )
+  {
+    _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
+    _PTR(SObject) aSObj = aStudy->FindObjectID(objects[i].in());
+    CORBA::Object_var anObj = SMESH::SObjectToObject(aSObj,aStudy);
+    if ( !CORBA::is_nil( anObj )) {
+      std::string name = aSObj->GetName();
+      QString text = myObjNameLineEdit->text();
+      if ( text != myEmptyText )
+        text += " ";
+      else
+        text = "";
+      text += QString( name.c_str() ).trimmed();
+      myObjNameLineEdit->setText( text );
+      myObjNameLineEdit->setStyleSheet("");
+      myObjects.push_back( anObj );
+      myParamValue += " ";
+      myParamValue += objects[i];
+      selChanged = true;
+    }
   }
+  if (selChanged)
+    emit contentModified();
 }
 
 //================================================================================
@@ -211,7 +267,34 @@ void StdMeshersGUI_ObjectReferenceParamWdg::onSelectionDone()
     SALOME_ListIO aList;
     mySelectionMgr->selectedObjects(aList);
     if (aList.Extent() == 1)
+    {
       obj = SMESH::IObjectToObject( aList.First() );
-    SetObject( obj.in() );
+      SetObject( obj.in() );
+    }
+    else if (myMultiSelection)
+    {
+      SMESH::string_array_var objIds = new SMESH::string_array;
+      objIds->length( aList.Extent());
+      SALOME_ListIteratorOfListIO io( aList );
+      int i = 0;
+      for ( ; io.More(); io.Next(), ++i )
+      {
+        Handle(SALOME_InteractiveObject) anIO = io.Value();
+        if ( anIO->hasEntry() )
+          objIds[i] = anIO->getEntry();
+        else
+          i--;
+      }
+      objIds->length(i);
+      SetObjects( objIds );
+    }
   }
 }
+
+void StdMeshersGUI_ObjectReferenceParamWdg::SetDefaultText(QString defaultText, QString styleSheet)
+{
+  myEmptyText = defaultText;
+  myEmptyStyleSheet = styleSheet;
+  myObjNameLineEdit->setText( myEmptyText );
+  myObjNameLineEdit->setStyleSheet( myEmptyStyleSheet);
+}
index 62e5096af2c7795bd899266db1d04a175191ee27..26448cf22df51c49fd48c7133ff0ecb2c6b43663 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : StdMeshersGUI_ObjectReferenceParamWdg.h
 // Author : Open CASCADE S.A.S.
 //
@@ -36,6 +37,9 @@
 // CORBA includes
 #include <CORBA.h>
 
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+
 class SUIT_SelectionFilter;
 class SMESHGUI;
 class LightApp_SelectionMgr;
@@ -51,24 +55,34 @@ class STDMESHERSGUI_EXPORT StdMeshersGUI_ObjectReferenceParamWdg : public QWidge
 
 public:
   StdMeshersGUI_ObjectReferenceParamWdg( SUIT_SelectionFilter* filter, 
-                                         QWidget*              parent);
+                                         QWidget*              parent,
+                                         bool                  multiSelection=false,
+                                         bool                  stretch=true);
   StdMeshersGUI_ObjectReferenceParamWdg( MeshObjectType objType,
-                                         QWidget*       parent);
+                                         QWidget*       parent,
+                                         bool           multiSelection=false);
   ~StdMeshersGUI_ObjectReferenceParamWdg();
 
   void SetObject(CORBA::Object_ptr obj);
 
+  void SetObjects(SMESH::string_array_var& objEntries);
+
   template<class TInterface> 
-    typename TInterface::_var_type GetObject() const {
-    if ( IsObjectSelected() ) return TInterface::_narrow(myObject);
+    typename TInterface::_var_type GetObject(unsigned i=0) const {
+    if ( IsObjectSelected(i) ) return TInterface::_narrow(myObjects[i]);
     return TInterface::_nil();
   }
 
+  int NbObjects() const { return myObjects.size(); }
+
   QString GetValue() const { return myParamValue; }
 
-  bool IsObjectSelected() const { return !CORBA::is_nil(myObject); }
+  bool IsObjectSelected(unsigned i=0) const
+  { return i < myObjects.size() && !CORBA::is_nil(myObjects[i]); }
 
   void AvoidSimultaneousSelection( StdMeshersGUI_ObjectReferenceParamWdg* other);
+  
+  void SetDefaultText(QString defaultText="", QString styleSheet="");
 
 public slots:
   /*!
@@ -88,6 +102,7 @@ signals:
     * one is activated
    */
   void selectionActivated();
+  void contentModified();
   
 private slots:
   void onSelectionDone(); 
@@ -96,9 +111,13 @@ private:
   void init();
   
 private:
- CORBA::Object_var      myObject;
+
+  bool                                myMultiSelection;
+  std::vector<CORBA::Object_var>      myObjects;
+
  SUIT_SelectionFilter*  myFilter;
  bool                   mySelectionActivated;
+ bool                   myStretchActivated;
 
  SMESHGUI*              mySMESHGUI;
  LightApp_SelectionMgr* mySelectionMgr;
@@ -106,6 +125,8 @@ private:
  QLineEdit*             myObjNameLineEdit;
  QPushButton*           mySelButton;
  QString                myParamValue;
+ QString                myEmptyText;
+ QString                myEmptyStyleSheet;
 };
 
 #endif // STDMESHERSGUI_OBJECTREFERENCEPARAMWDG_H
diff --git a/src/StdMeshersGUI/StdMeshersGUI_QuadrangleParamWdg.cxx b/src/StdMeshersGUI/StdMeshersGUI_QuadrangleParamWdg.cxx
new file mode 100644 (file)
index 0000000..cb95187
--- /dev/null
@@ -0,0 +1,100 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+//  File   : StdMeshersGUI_QuadrangleParamWdg.cxx
+//  Author : Open CASCADE S.A.S. (jfa)
+//  SMESH includes
+
+#include "StdMeshersGUI_QuadrangleParamWdg.h"
+
+#include "SMESHGUI.h"
+
+#include "SUIT_ResourceMgr.h"
+
+// Qt includes
+#include <QButtonGroup>
+#include <QRadioButton>
+#include <QLabel>
+#include <QGridLayout>
+
+// IDL includes
+#include <SALOMEconfig.h>
+#include CORBA_CLIENT_HEADER(SMESH_BasicHypothesis)
+
+#define SPACING 6
+#define MARGIN 0
+
+//================================================================================
+// function : Constructor
+// purpose  :
+//================================================================================
+StdMeshersGUI_QuadrangleParamWdg::StdMeshersGUI_QuadrangleParamWdg (QWidget * parent)
+  : QWidget(parent),
+    myType(0)
+{
+  myType = new QButtonGroup (this);
+
+  QGridLayout* typeLay = new QGridLayout( this );
+
+  typeLay->setMargin(MARGIN);
+  typeLay->setSpacing(SPACING);
+
+  QString aTypeKey ("SMESH_QUAD_TYPE_%1");
+  QString aPictKey ("ICON_StdMeshers_Quadrangle_Params_%1");
+
+  int itype = 0;
+  for (; itype < int(StdMeshers::QUAD_NB_TYPES); itype++) {
+    QRadioButton* rbi = new QRadioButton (tr(aTypeKey.arg(itype).toLatin1()), this);
+    QPixmap pmi (SMESHGUI::resourceMgr()->loadPixmap("SMESH", tr(aPictKey.arg(itype).toLatin1())));
+    QLabel* pli = new QLabel (this);
+    pli->setPixmap(pmi);
+    typeLay->addWidget(rbi, itype, 0, 1, 1);
+    typeLay->addWidget(pli, itype, 1, 1, 1);
+    myType->addButton(rbi, itype);
+  }
+  myType->button(0)->setChecked(true);
+
+  setLayout(typeLay);
+  setMinimumWidth(300);
+}
+
+//================================================================================
+// function : Destructor
+// purpose  :
+//================================================================================
+StdMeshersGUI_QuadrangleParamWdg::~StdMeshersGUI_QuadrangleParamWdg()
+{
+}
+
+//=================================================================================
+// function : SetType
+// purpose  :
+//=================================================================================
+void StdMeshersGUI_QuadrangleParamWdg::SetType (int theType)
+{
+  myType->button(theType)->setChecked(true);
+}
+
+//=================================================================================
+// function : GetType
+// purpose  :
+//=================================================================================
+int StdMeshersGUI_QuadrangleParamWdg::GetType()
+{
+  return myType->checkedId();
+}
diff --git a/src/StdMeshersGUI/StdMeshersGUI_QuadrangleParamWdg.h b/src/StdMeshersGUI/StdMeshersGUI_QuadrangleParamWdg.h
new file mode 100644 (file)
index 0000000..b58445b
--- /dev/null
@@ -0,0 +1,49 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+//  File   : StdMeshersGUI_QuadrangleParamWdg.h
+//  Author : Open CASCADE S.A.S. (jfa)
+
+#ifndef STDMESHERSGUI_QUADRANGLEPARAMWDG_H
+#define STDMESHERSGUI_QUADRANGLEPARAMWDG_H
+
+// SMESH includes
+#include "SMESH_StdMeshersGUI.hxx"
+
+// Qt includes
+#include <QWidget>
+
+class QButtonGroup;
+
+class STDMESHERSGUI_EXPORT StdMeshersGUI_QuadrangleParamWdg : public QWidget
+{
+  Q_OBJECT
+
+public:
+  StdMeshersGUI_QuadrangleParamWdg (QWidget* parent = 0);
+  ~StdMeshersGUI_QuadrangleParamWdg();
+
+  void SetType (int theType);
+  int  GetType ();
+
+private:
+  // Quadranle preference, Triangle preference, Reduced
+  QButtonGroup* myType;
+};
+
+#endif // STDMESHERSGUI_QUADRANGLEPARAMWDG_H
index 56e31b5a6deae6b463b7a12a4269b2d57110474e..6e902a7f191bd60f3c68720b8551ac783712e822 100644 (file)
@@ -1,38 +1,45 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
-//
-// File   : StdMeshersGUI_StdHypothesisCreator.cxx
-// Author : Alexander SOLOVYOV, Open CASCADE S.A.S.
-// SMESH includes
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+//  File   : StdMeshersGUI_StdHypothesisCreator.cxx
+//  Author : Alexander SOLOVYOV, Open CASCADE S.A.S.
+//  SMESH includes
+
 #include "StdMeshersGUI_StdHypothesisCreator.h"
 
 #include <SMESHGUI.h>
 #include <SMESHGUI_SpinBox.h>
 #include <SMESHGUI_HypothesesUtils.h>
 #include <SMESHGUI_Utils.h>
+#include <SMESHGUI_GEOMGenUtils.h>
+
 #include <SMESH_TypeFilter.hxx>
 #include <SMESH_NumberFilter.hxx>
-#include <StdMeshersGUI_ObjectReferenceParamWdg.h>
-#include <StdMeshersGUI_LayerDistributionParamWdg.h>
+
+#include "StdMeshersGUI_FixedPointsParamWdg.h"
+#include "StdMeshersGUI_LayerDistributionParamWdg.h"
+#include "StdMeshersGUI_ObjectReferenceParamWdg.h"
+#include "StdMeshersGUI_QuadrangleParamWdg.h"
+#include "StdMeshersGUI_SubShapeSelectorWdg.h"
+
 #include <SALOMEDSClient_Study.hxx>
 
 // SALOME GUI includes
@@ -42,6 +49,7 @@
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
 #include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_Group)
 
 // Qt includes
 #include <QHBoxLayout>
@@ -184,10 +192,10 @@ namespace {
    */
   //================================================================================
 
-  class TDoubleSliderWith2Lables: public QWidget
+  class TDoubleSliderWith2Labels: public QWidget
   {
   public:
-    TDoubleSliderWith2Lables( const QString& leftLabel, const QString& rightLabel,
+    TDoubleSliderWith2Labels( const QString& leftLabel, const QString& rightLabel,
                               const double   initValue, const double   bottom,
                               const double   top      , const double   precision,
                               QWidget *      parent=0 , const char *   name=0 )
@@ -196,11 +204,11 @@ namespace {
       setObjectName(name);
 
       QHBoxLayout* aHBoxL = new QHBoxLayout(this);
-      
+
       if ( !leftLabel.isEmpty() ) {
-       QLabel* aLeftLabel = new QLabel( this );
-       aLeftLabel->setText( leftLabel );
-       aHBoxL->addWidget( aLeftLabel );
+        QLabel* aLeftLabel = new QLabel( this );
+        aLeftLabel->setText( leftLabel );
+        aHBoxL->addWidget( aLeftLabel );
       }
 
       _slider = new QSlider( Qt::Horizontal, this );
@@ -209,9 +217,9 @@ namespace {
       aHBoxL->addWidget( _slider );
 
       if ( !rightLabel.isEmpty() ) {
-       QLabel* aRightLabel = new QLabel( this );
-       aRightLabel->setText( rightLabel );
-       aHBoxL->addWidget( aRightLabel );
+        QLabel* aRightLabel = new QLabel( this );
+        aRightLabel->setText( rightLabel );
+        aHBoxL->addWidget( aRightLabel );
       }
 
       setLayout( aHBoxL );
@@ -255,11 +263,30 @@ namespace {
     return SMESH::SMESH_Mesh::_nil();
   }
   //================================================================================
+  /*!
+   * \brief Retrieve SMESH_Mesh held by widget
+   */
+  //================================================================================
+
+  inline SMESH::ListOfGroups_var groupsFromWdg(const QWidget* wdg)
+  {
+    SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
+    const StdMeshersGUI_ObjectReferenceParamWdg * objRefWdg =
+      dynamic_cast<const StdMeshersGUI_ObjectReferenceParamWdg*>( wdg );
+    if ( objRefWdg )
+    {
+      groups->length( objRefWdg->NbObjects() );
+      for ( unsigned i = 0; i < groups->length(); ++i )
+        groups[i] = objRefWdg->GetObject< SMESH::SMESH_GroupBase >(i);
+    }
+    return groups;
+  }
+  //================================================================================
   /*!
    * \brief creates a filter for selection of shapes of given dimension
     * \param dim - dimension
-    * \param subShapeType - required type of subshapes, number of which must be \a nbSubShapes
-    * \param nbSubShapes - number of subshapes of given type
+    * \param subShapeType - required type of sub-shapes, number of which must be \a nbSubShapes
+    * \param nbSubShapes - number of sub-shapes of given type
     * \param closed - required closeness flag of a shape
     * \retval SUIT_SelectionFilter* - created filter
    */
@@ -311,6 +338,16 @@ namespace {
     w->SetObject( object.in() );
     return w;
   }
+  QWidget* newObjRefParamWdg( SUIT_SelectionFilter*    filter,
+                              SMESH::string_array_var& objEntries)
+  {
+    StdMeshersGUI_ObjectReferenceParamWdg* w =
+      new StdMeshersGUI_ObjectReferenceParamWdg( filter, 0, /*multiSel=*/true);
+    //RNV: Firstly, activate selection, then set objects
+    w->activateSelection();
+    w->SetObjects( objEntries );
+    return w;
+  }
 
   //================================================================================
   /*!
@@ -355,7 +392,8 @@ bool StdMeshersGUI_StdHypothesisCreator::checkParams( QString& msg ) const
     ok = ( w->IsObjectSelected() );
     if ( !ok ) w->SetObject( CORBA::Object::_nil() );
     int nbAssocVert = ( hypType() == "ProjectionSource1D" ? 1 : 2 );
-    for ( int i = 0; ok && i < nbAssocVert; i += 2)
+    int nbNonEmptyAssoc = 0;
+    for ( int i = 0; ok && i < nbAssocVert*2; i += 2)
     {
       QString srcV, tgtV;
       StdMeshersGUI_ObjectReferenceParamWdg* w1 =
@@ -370,18 +408,43 @@ bool StdMeshersGUI_StdHypothesisCreator::checkParams( QString& msg ) const
         w1->SetObject( CORBA::Object::_nil() );
         w2->SetObject( CORBA::Object::_nil() );
       }
+      nbNonEmptyAssoc += !srcV.isEmpty();
+    }
+    if ( ok && nbNonEmptyAssoc == 1 && nbAssocVert == 2 )
+    {
+      // only one pair of VERTEXes is given for a FACE,
+      // then the FACE must have only one VERTEX
+      GEOM::GEOM_Object_var face = w->GetObject< GEOM::GEOM_Object >();
+
+      GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen();
+      _PTR(Study)         aStudy = SMESH::GetActiveStudyDocument();
+      GEOM::GEOM_IShapesOperations_var shapeOp;
+      if ( !geomGen->_is_nil() && aStudy )
+        shapeOp = geomGen->GetIShapesOperations( aStudy->StudyId() );
+      if ( !shapeOp->_is_nil() )
+      {
+        GEOM::ListOfLong_var vertices =
+          shapeOp->GetAllSubShapesIDs (face, GEOM::VERTEX, /*isSorted=*/false);
+        ok = ( vertices->length() == 1 );
+      }
     }
-
     // Uninstall filters of StdMeshersGUI_ObjectReferenceParamWdg
     if ( ok )
       deactivateObjRefParamWdg( customWidgets() );
   }
-  else if ( hypType() == "LayerDistribution" )
+  else if ( hypType().startsWith("ImportSource" ))
+  {
+    StdMeshersGUI_ObjectReferenceParamWdg* w =
+      widget< StdMeshersGUI_ObjectReferenceParamWdg >( 0 );
+    ok = ( w->IsObjectSelected() );
+  }
+  else if ( hypType() == "LayerDistribution" || hypType() == "LayerDistribution2D" )
   {
     StdMeshersGUI_LayerDistributionParamWdg* w = 
       widget< StdMeshersGUI_LayerDistributionParamWdg >( 0 );
     ok = ( w && w->IsOk() );
   }
+
   return ok;
 }
 
@@ -403,25 +466,26 @@ QString StdMeshersGUI_StdHypothesisCreator::storeParams() const
   }
 
   QString valueStr = stdParamValues( params );
-  QStringList aVariablesList = getVariablesFromDlg();
+  //QStringList aVariablesList = getVariablesFromDlg();
 
   if( res && !params.isEmpty() )
   {
     if( hypType()=="LocalLength" )
     {
       StdMeshers::StdMeshers_LocalLength_var h =
-       StdMeshers::StdMeshers_LocalLength::_narrow( hypothesis() );
+        StdMeshers::StdMeshers_LocalLength::_narrow( hypothesis() );
 
+      h->SetVarParameter( params[0].text(), "SetLength" );
       h->SetLength( params[0].myValue.toDouble() );
-      h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList));
+      h->SetVarParameter( params[1].text(), "SetPrecision" );
       h->SetPrecision( params[1].myValue.toDouble() );
-      h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList));
     }
     else if( hypType()=="MaxLength" )
     {
       StdMeshers::StdMeshers_MaxLength_var h =
-       StdMeshers::StdMeshers_MaxLength::_narrow( hypothesis() );
+        StdMeshers::StdMeshers_MaxLength::_narrow( hypothesis() );
 
+      h->SetVarParameter( params[0].text(), "SetLength" );
       h->SetLength( params[0].myValue.toDouble() );
       h->SetUsePreestimatedLength( widget< QCheckBox >( 1 )->isChecked() );
       if ( !h->HavePreestimatedLength() && !h->_is_equivalent( initParamsHypothesis() )) {
@@ -433,83 +497,133 @@ QString StdMeshersGUI_StdHypothesisCreator::storeParams() const
     else if( hypType()=="SegmentLengthAroundVertex" )
     {
       StdMeshers::StdMeshers_SegmentLengthAroundVertex_var h =
-       StdMeshers::StdMeshers_SegmentLengthAroundVertex::_narrow( hypothesis() );
+        StdMeshers::StdMeshers_SegmentLengthAroundVertex::_narrow( hypothesis() );
 
+      h->SetVarParameter( params[0].text(), "SetLength" );
       h->SetLength( params[0].myValue.toDouble() );
-      h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList));
     }
     else if( hypType()=="Arithmetic1D" )
     {
       StdMeshers::StdMeshers_Arithmetic1D_var h =
-       StdMeshers::StdMeshers_Arithmetic1D::_narrow( hypothesis() );
+        StdMeshers::StdMeshers_Arithmetic1D::_narrow( hypothesis() );
+
+      StdMeshersGUI_SubShapeSelectorWdg* w = 
+        widget< StdMeshersGUI_SubShapeSelectorWdg >( 2 );
+
+      h->SetVarParameter( params[0].text(), "SetStartLength" );
+      h->SetStartLength( params[0].myValue.toDouble() );
+      h->SetVarParameter( params[1].text(), "SetEndLength" );
+      h->SetEndLength( params[1].myValue.toDouble() );
+      if (w) {
+        h->SetReversedEdges( w->GetListOfIDs() );
+        h->SetObjectEntry( w->GetMainShapeEntry() );
+      }
+    }
+    else if( hypType()=="FixedPoints1D" )
+    {
+      StdMeshers::StdMeshers_FixedPoints1D_var h =
+        StdMeshers::StdMeshers_FixedPoints1D::_narrow( hypothesis() );
+
+      StdMeshersGUI_FixedPointsParamWdg* w1 = 
+        widget< StdMeshersGUI_FixedPointsParamWdg >( 0 );
 
-      h->SetLength( params[0].myValue.toDouble(), true );
-      h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList));
-      h->SetLength( params[1].myValue.toDouble(), false );
-      h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList));
+      StdMeshersGUI_SubShapeSelectorWdg* w2 = 
+        widget< StdMeshersGUI_SubShapeSelectorWdg >( 1 );
+
+      if (w1) {
+        h->SetPoints( w1->GetListOfPoints() );
+        h->SetNbSegments( w1->GetListOfSegments() );
+      }
+      if (w2) {
+        h->SetReversedEdges( w2->GetListOfIDs() );
+        h->SetObjectEntry( w2->GetMainShapeEntry() );
+      }
     }
     else if( hypType()=="MaxElementArea" )
     {
       StdMeshers::StdMeshers_MaxElementArea_var h =
-       StdMeshers::StdMeshers_MaxElementArea::_narrow( hypothesis() );
-      h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList));
+        StdMeshers::StdMeshers_MaxElementArea::_narrow( hypothesis() );
+      h->SetVarParameter( params[0].text(), "SetMaxElementArea" );
       h->SetMaxElementArea( params[0].myValue.toDouble() );
     }
     else if( hypType()=="MaxElementVolume" )
     {
       StdMeshers::StdMeshers_MaxElementVolume_var h =
-       StdMeshers::StdMeshers_MaxElementVolume::_narrow( hypothesis() );
+        StdMeshers::StdMeshers_MaxElementVolume::_narrow( hypothesis() );
 
+      h->SetVarParameter( params[0].text(), "SetMaxElementVolume" );
       h->SetMaxElementVolume( params[0].myValue.toDouble() );
-      h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList));
     }
     else if( hypType()=="StartEndLength" )
     {
       StdMeshers::StdMeshers_StartEndLength_var h =
-       StdMeshers::StdMeshers_StartEndLength::_narrow( hypothesis() );
-
-      h->SetLength( params[0].myValue.toDouble(), true );
-      h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList));
-      h->SetLength( params[1].myValue.toDouble(), false );
-      h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList));
+        StdMeshers::StdMeshers_StartEndLength::_narrow( hypothesis() );
+
+      StdMeshersGUI_SubShapeSelectorWdg* w = 
+        widget< StdMeshersGUI_SubShapeSelectorWdg >( 2 );
+
+      h->SetVarParameter( params[0].text(), "SetStartLength" );
+      h->SetStartLength( params[0].myValue.toDouble() );
+      h->SetVarParameter( params[1].text(), "SetEndLength" );
+      h->SetEndLength( params[1].myValue.toDouble() );
+      if (w) {
+        h->SetReversedEdges( w->GetListOfIDs() );
+        h->SetObjectEntry( w->GetMainShapeEntry() );
+      }
     }
     else if( hypType()=="Deflection1D" )
     {
       StdMeshers::StdMeshers_Deflection1D_var h =
-       StdMeshers::StdMeshers_Deflection1D::_narrow( hypothesis() );
-      h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList));
+        StdMeshers::StdMeshers_Deflection1D::_narrow( hypothesis() );
+      h->SetVarParameter( params[0].text(), "SetDeflection" );
       h->SetDeflection( params[0].myValue.toDouble() );
     }
     else if( hypType()=="AutomaticLength" )
     {
       StdMeshers::StdMeshers_AutomaticLength_var h =
-       StdMeshers::StdMeshers_AutomaticLength::_narrow( hypothesis() );
+        StdMeshers::StdMeshers_AutomaticLength::_narrow( hypothesis() );
 
+      h->SetVarParameter( params[0].text(), "SetFineness" );
       h->SetFineness( params[0].myValue.toDouble() );
     }
     else if( hypType()=="NumberOfLayers" )
     {
       StdMeshers::StdMeshers_NumberOfLayers_var h =
-       StdMeshers::StdMeshers_NumberOfLayers::_narrow( hypothesis() );
+        StdMeshers::StdMeshers_NumberOfLayers::_narrow( hypothesis() );
 
+      h->SetVarParameter( params[0].text(), "SetNumberOfLayers" );
       h->SetNumberOfLayers( params[0].myValue.toInt() );
-      h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList));
     }
     else if( hypType()=="LayerDistribution" )
     {
       StdMeshers::StdMeshers_LayerDistribution_var h =
-       StdMeshers::StdMeshers_LayerDistribution::_narrow( hypothesis() );
+        StdMeshers::StdMeshers_LayerDistribution::_narrow( hypothesis() );
+      StdMeshersGUI_LayerDistributionParamWdg* w = 
+        widget< StdMeshersGUI_LayerDistributionParamWdg >( 0 );
+      
+      h->SetLayerDistribution( w->GetHypothesis() );
+    }
+    else if( hypType()=="NumberOfLayers2D" )
+    {
+      StdMeshers::StdMeshers_NumberOfLayers2D_var h =
+        StdMeshers::StdMeshers_NumberOfLayers2D::_narrow( hypothesis() );
+
+      h->SetVarParameter( params[0].text(), "SetNumberOfLayers" );
+      h->SetNumberOfLayers( params[0].myValue.toInt() );
+    }
+    else if( hypType()=="LayerDistribution2D" )
+    {
+      StdMeshers::StdMeshers_LayerDistribution2D_var h =
+        StdMeshers::StdMeshers_LayerDistribution2D::_narrow( hypothesis() );
       StdMeshersGUI_LayerDistributionParamWdg* w = 
         widget< StdMeshersGUI_LayerDistributionParamWdg >( 0 );
       
       h->SetLayerDistribution( w->GetHypothesis() );
-      h->SetParameters(w->GetHypothesis()->GetParameters());
-      w->GetHypothesis()->ClearParameters();
     }
     else if( hypType()=="ProjectionSource1D" )
     {
       StdMeshers::StdMeshers_ProjectionSource1D_var h =
-       StdMeshers::StdMeshers_ProjectionSource1D::_narrow( hypothesis() );
+        StdMeshers::StdMeshers_ProjectionSource1D::_narrow( hypothesis() );
 
       h->SetSourceEdge       ( geomFromWdg ( getWidgetForParam( 0 )));
       h->SetSourceMesh       ( meshFromWdg ( getWidgetForParam( 1 )));
@@ -519,7 +633,7 @@ QString StdMeshersGUI_StdHypothesisCreator::storeParams() const
     else if( hypType()=="ProjectionSource2D" )
     {
       StdMeshers::StdMeshers_ProjectionSource2D_var h =
-       StdMeshers::StdMeshers_ProjectionSource2D::_narrow( hypothesis() );
+        StdMeshers::StdMeshers_ProjectionSource2D::_narrow( hypothesis() );
 
       h->SetSourceFace       ( geomFromWdg ( getWidgetForParam( 0 )));
       h->SetSourceMesh       ( meshFromWdg ( getWidgetForParam( 1 )));
@@ -531,7 +645,7 @@ QString StdMeshersGUI_StdHypothesisCreator::storeParams() const
     else if( hypType()=="ProjectionSource3D" )
     {
       StdMeshers::StdMeshers_ProjectionSource3D_var h =
-       StdMeshers::StdMeshers_ProjectionSource3D::_narrow( hypothesis() );
+        StdMeshers::StdMeshers_ProjectionSource3D::_narrow( hypothesis() );
 
       h->SetSource3DShape    ( geomFromWdg ( getWidgetForParam( 0 )));
       h->SetSourceMesh       ( meshFromWdg ( getWidgetForParam( 1 )));
@@ -540,6 +654,63 @@ QString StdMeshersGUI_StdHypothesisCreator::storeParams() const
                                geomFromWdg ( getWidgetForParam( 3 )), // tgt1
                                geomFromWdg ( getWidgetForParam( 5 ))); // tgt2
     }
+    else if( hypType()=="ImportSource1D" )
+    {
+      StdMeshers::StdMeshers_ImportSource1D_var h =
+        StdMeshers::StdMeshers_ImportSource1D::_narrow( hypothesis() );
+
+      SMESH::ListOfGroups_var groups = groupsFromWdg( getWidgetForParam( 0 ));
+      h->SetSourceEdges( groups.in() );
+      QCheckBox* toCopyMesh   = widget< QCheckBox >( 1 );
+      QCheckBox* toCopyGroups = widget< QCheckBox >( 2 );
+      h->SetCopySourceMesh( toCopyMesh->isChecked(), toCopyGroups->isChecked());
+    }
+    else if( hypType()=="ImportSource2D" )
+    {
+      StdMeshers::StdMeshers_ImportSource2D_var h =
+        StdMeshers::StdMeshers_ImportSource2D::_narrow( hypothesis() );
+
+      SMESH::ListOfGroups_var groups = groupsFromWdg( getWidgetForParam( 0 ));
+      h->SetSourceFaces( groups.in() );
+      QCheckBox* toCopyMesh   = widget< QCheckBox >( 1 );
+      QCheckBox* toCopyGroups = widget< QCheckBox >( 2 );
+      h->SetCopySourceMesh( toCopyMesh->isChecked(), toCopyGroups->isChecked());
+    }
+    else if( hypType()=="ViscousLayers" )
+    {
+      StdMeshers::StdMeshers_ViscousLayers_var h =
+        StdMeshers::StdMeshers_ViscousLayers::_narrow( hypothesis() );
+
+      h->SetVarParameter( params[0].text(), "SetTotalThickness" );
+      h->SetTotalThickness( params[0].myValue.toDouble() );
+      h->SetVarParameter( params[1].text(), "SetNumberLayers" );
+      h->SetNumberLayers  ( params[1].myValue.toInt() );
+      h->SetVarParameter( params[2].text(), "SetStretchFactor" );
+      h->SetStretchFactor ( params[2].myValue.toDouble() );
+
+      if ( StdMeshersGUI_SubShapeSelectorWdg* idsWg = 
+           widget< StdMeshersGUI_SubShapeSelectorWdg >( 3 ))
+      {
+        h->SetIgnoreFaces( idsWg->GetListOfIDs() );
+      }
+    }
+    else if( hypType()=="QuadrangleParams" )
+    {
+      StdMeshers::StdMeshers_QuadrangleParams_var h =
+        StdMeshers::StdMeshers_QuadrangleParams::_narrow( hypothesis() );
+      StdMeshersGUI_SubShapeSelectorWdg* w1 =
+        widget< StdMeshersGUI_SubShapeSelectorWdg >( 0 );
+      StdMeshersGUI_QuadrangleParamWdg* w2 =
+        widget< StdMeshersGUI_QuadrangleParamWdg >( 1 );
+      if (w1 && w2) {
+        if (w1->GetListSize() > 0) {
+          h->SetTriaVertex(w1->GetListOfIDs()[0]); // getlist must be called once
+          const char * entry = w1->GetMainShapeEntry();
+          h->SetObjectEntry(entry);
+        }
+        h->SetQuadType(StdMeshers::QuadType(w2->GetType()));
+      }
+    }
   }
   return valueStr;
 }
@@ -547,15 +718,15 @@ QString StdMeshersGUI_StdHypothesisCreator::storeParams() const
 //================================================================================
 /*!
  * \brief Return parameter values as SMESHGUI_GenericHypothesisCreator::StdParam
 * \param p - list of parameters
 * \retval bool - success flag
 *
 * Is called from SMESHGUI_GenericHypothesisCreator::buildStdFrame().
 * Parameters will be shown using "standard" controls:
 *   Int by QtxIntSpinBox
 *   Double by SMESHGUI_SpinBox
 *   String by QLineEdit
 * getCustomWidget() allows to redefine control for a parameter
+ * \param p - list of parameters
+ * \retval bool - success flag
+ *
+ * Is called from SMESHGUI_GenericHypothesisCreator::buildStdFrame().
+ * Parameters will be shown using "standard" controls:
+ *   Int by QtxIntSpinBox
+ *   Double by SMESHGUI_SpinBox
+ *   String by QLineEdit
+ * getCustomWidget() allows to redefine control for a parameter
  */
 //================================================================================
 
@@ -574,7 +745,7 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
     p.append( item );
     customWidgets()->append(0);
   }
-  
+
   SMESH::SMESH_Hypothesis_var hyp = initParamsHypothesis();
   SMESH::ListOfParameters_var aParameters = hyp->GetLastParameters();
 
@@ -582,17 +753,16 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
   {
     StdMeshers::StdMeshers_LocalLength_var h =
       StdMeshers::StdMeshers_LocalLength::_narrow( hyp );
-    
+
     item.myName = tr("SMESH_LOCAL_LENGTH_PARAM");
-    if(!initVariableName(aParameters,item,0))
+    if(!initVariableName( hyp, item, "SetLength"))
       item.myValue = h->GetLength();
     p.append( item );     
-    
+
     item.myName = tr("SMESH_LOCAL_LENGTH_PRECISION");
-    if(!initVariableName(aParameters,item,1))
+    if(!initVariableName( hyp, item, "SetPrecision"))
       item.myValue = h->GetPrecision(); 
     p.append( item );
-    
   }
   else if( hypType()=="MaxLength" )
   {
@@ -610,7 +780,8 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
     }
 
     item.myName = tr("SMESH_LOCAL_LENGTH_PARAM");
-    item.myValue = h->GetLength();
+    if(!initVariableName( hyp, item, "SetLength"))
+      item.myValue = h->GetLength();
     p.append( item );
     customWidgets()->append(0);
 
@@ -633,7 +804,7 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
       StdMeshers::StdMeshers_SegmentLengthAroundVertex::_narrow( hyp );
 
     item.myName = tr("SMESH_LOCAL_LENGTH_PARAM");
-    if(!initVariableName(aParameters,item,0))
+    if(!initVariableName( hyp, item, "SetLength"))
       item.myValue = h->GetLength();
     
     p.append( item );
@@ -644,22 +815,78 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
       StdMeshers::StdMeshers_Arithmetic1D::_narrow( hyp );
 
     item.myName = tr( "SMESH_START_LENGTH_PARAM" );
-    if(!initVariableName(aParameters,item,0))
+    if(!initVariableName( hyp, item, "SetStartLength" ))
       item.myValue = h->GetLength( true );
     p.append( item );
 
+    customWidgets()->append (0);
+
     item.myName = tr( "SMESH_END_LENGTH_PARAM" );
-    if(!initVariableName(aParameters,item,1))
+    if(!initVariableName( hyp, item, "SetEndLength" ))
       item.myValue = h->GetLength( false );
     p.append( item );
+
+    customWidgets()->append (0);
+
+    item.myName = tr( "SMESH_REVERSED_EDGES" );
+    p.append( item );
+
+    StdMeshersGUI_SubShapeSelectorWdg* aDirectionWidget =
+      new StdMeshersGUI_SubShapeSelectorWdg();
+    QString aGeomEntry = SMESHGUI_GenericHypothesisCreator::getShapeEntry();
+    QString aMainEntry = SMESHGUI_GenericHypothesisCreator::getMainShapeEntry();
+    if ( aGeomEntry == "" )
+      aGeomEntry = h->GetObjectEntry();
+
+    aDirectionWidget->SetGeomShapeEntry( aGeomEntry );
+    aDirectionWidget->SetMainShapeEntry( aMainEntry );
+    aDirectionWidget->SetListOfIDs( h->GetReversedEdges() );
+    aDirectionWidget->showPreview( true );
+    customWidgets()->append ( aDirectionWidget );
   }
+
+
+  else if( hypType()=="FixedPoints1D" )
+  {
+    StdMeshers::StdMeshers_FixedPoints1D_var h =
+      StdMeshers::StdMeshers_FixedPoints1D::_narrow( hyp );
+
+    item.myName = tr( "SMESH_FIXED_POINTS" );
+    p.append( item );
+
+    StdMeshersGUI_FixedPointsParamWdg* aFixedPointsWidget =
+      new StdMeshersGUI_FixedPointsParamWdg();
+
+    if ( !isCreation() ) {
+      aFixedPointsWidget->SetListOfPoints( h->GetPoints() );
+      aFixedPointsWidget->SetListOfSegments( h->GetNbSegments() );
+    }
+    customWidgets()->append( aFixedPointsWidget );
+
+    item.myName = tr( "SMESH_REVERSED_EDGES" );
+    p.append( item );
+
+    StdMeshersGUI_SubShapeSelectorWdg* aDirectionWidget =
+      new StdMeshersGUI_SubShapeSelectorWdg();
+    QString anEntry = SMESHGUI_GenericHypothesisCreator::getShapeEntry();
+    QString aMainEntry = SMESHGUI_GenericHypothesisCreator::getMainShapeEntry();
+    if ( anEntry == "" )
+      anEntry = h->GetObjectEntry();
+    aDirectionWidget->SetGeomShapeEntry( anEntry );
+    aDirectionWidget->SetMainShapeEntry( aMainEntry );
+    aDirectionWidget->SetListOfIDs( h->GetReversedEdges() );
+    aDirectionWidget->showPreview( true );
+    customWidgets()->append ( aDirectionWidget );
+  }
+
+
   else if( hypType()=="MaxElementArea" )
   {
     StdMeshers::StdMeshers_MaxElementArea_var h =
       StdMeshers::StdMeshers_MaxElementArea::_narrow( hyp );
 
     item.myName = tr( "SMESH_MAX_ELEMENT_AREA_PARAM" );
-    if(!initVariableName(aParameters,item,0))
+    if(!initVariableName( hyp, item, "SetMaxElementArea" ))
       item.myValue = h->GetMaxElementArea();
     p.append( item );
     
@@ -670,7 +897,7 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
       StdMeshers::StdMeshers_MaxElementVolume::_narrow( hyp );
 
     item.myName = tr( "SMESH_MAX_ELEMENT_VOLUME_PARAM" );
-    if(!initVariableName(aParameters,item,0))
+    if(!initVariableName( hyp, item, "SetMaxElementVolume" ))
       item.myValue = h->GetMaxElementVolume();
     p.append( item );
   }
@@ -681,15 +908,31 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
 
     item.myName = tr( "SMESH_START_LENGTH_PARAM" );
 
-    if(!initVariableName(aParameters,item,0)) 
+    if(!initVariableName( hyp, item, "SetStartLength" )) 
       item.myValue = h->GetLength( true );
     p.append( item );
+    customWidgets()->append(0);
 
     item.myName = tr( "SMESH_END_LENGTH_PARAM" );
-    if(!initVariableName(aParameters,item,1)) 
+    if(!initVariableName( hyp, item, "SetEndLength" )) 
       item.myValue = h->GetLength( false );
     p.append( item );
-    
+    customWidgets()->append(0);
+
+    item.myName = tr( "SMESH_REVERSED_EDGES" );
+    p.append( item );
+
+    StdMeshersGUI_SubShapeSelectorWdg* aDirectionWidget =
+      new StdMeshersGUI_SubShapeSelectorWdg();
+    QString anEntry = SMESHGUI_GenericHypothesisCreator::getShapeEntry();
+    QString aMainEntry = SMESHGUI_GenericHypothesisCreator::getMainShapeEntry();
+    if ( anEntry == "" )
+      anEntry = h->GetObjectEntry();
+    aDirectionWidget->SetGeomShapeEntry( anEntry );
+    aDirectionWidget->SetMainShapeEntry( aMainEntry );
+    aDirectionWidget->SetListOfIDs( h->GetReversedEdges() );
+    aDirectionWidget->showPreview( true );
+    customWidgets()->append ( aDirectionWidget );
   }
   else if( hypType()=="Deflection1D" )
   {
@@ -697,7 +940,7 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
       StdMeshers::StdMeshers_Deflection1D::_narrow( hyp );
     
     item.myName = tr( "SMESH_DEFLECTION1D_PARAM" );
-    if(!initVariableName(aParameters,item,0)) 
+    if(!initVariableName( hyp, item, "SetDeflection" )) 
       item.myValue = h->GetDeflection();
     p.append( item );
   }
@@ -709,8 +952,10 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
     item.myName = tr( "SMESH_FINENESS_PARAM" );
     //item.myValue = h->GetFineness();
     p.append( item );
-    customWidgets()->append
-      ( new TDoubleSliderWith2Lables( "0 ", " 1", h->GetFineness(), 0, 1, 0.01, 0 ));
+    SMESHGUI_SpinBox* _autoLengthSpinBox = new SMESHGUI_SpinBox(dlg());
+    _autoLengthSpinBox->RangeStepAndValidator(0, 1, 0.01, "length_precision");
+    _autoLengthSpinBox->SetValue(h->GetFineness());
+    customWidgets()->append( _autoLengthSpinBox);
   }
   else if( hypType()=="NumberOfLayers" )
   {
@@ -718,25 +963,37 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
       StdMeshers::StdMeshers_NumberOfLayers::_narrow( hyp );
 
     item.myName = tr( "SMESH_NUMBER_OF_LAYERS" );
-    if(!initVariableName(aParameters,item,0))     
+    if(!initVariableName( hyp, item, "SetNumberOfLayers" ))     
       item.myValue = (int) h->GetNumberOfLayers();
     p.append( item );
   }
   else if( hypType()=="LayerDistribution" )
-    {
-      StdMeshers::StdMeshers_LayerDistribution_var h =
+  {
+    StdMeshers::StdMeshers_LayerDistribution_var h =
       StdMeshers::StdMeshers_LayerDistribution::_narrow( hyp );
-
+    
     item.myName = tr( "SMESH_LAYERS_DISTRIBUTION" ); p.append( item );
+    initVariableName( hyp, item, "SetLayerDistribution" );
+    customWidgets()->append
+      ( new StdMeshersGUI_LayerDistributionParamWdg( h->GetLayerDistribution(), hypName(), dlg()));
+  }
+  else if( hypType()=="NumberOfLayers2D" )
+  {
+    StdMeshers::StdMeshers_NumberOfLayers2D_var h =
+      StdMeshers::StdMeshers_NumberOfLayers2D::_narrow( hyp );
     
-    //Set into not published hypo last variables
-    QStringList aLastVarsList;
-    for(int i = 0;i<aParameters->length();i++) 
-      aLastVarsList.append(QString(aParameters[i].in()));
+    item.myName = tr( "SMESH_NUMBER_OF_LAYERS" );
+    if(!initVariableName( hyp, item, "SetNumberOfLayers" ))     
+      item.myValue = (int) h->GetNumberOfLayers();
+    p.append( item );
+  }
+  else if( hypType()=="LayerDistribution2D" )
+  {
+    StdMeshers::StdMeshers_LayerDistribution2D_var h =
+      StdMeshers::StdMeshers_LayerDistribution2D::_narrow( hyp );
 
-    if(!aLastVarsList.isEmpty())
-      h->GetLayerDistribution()->SetLastParameters(SMESHGUI::JoinObjectParameters(aLastVarsList));
-    
+    item.myName = tr( "SMESH_LAYERS_DISTRIBUTION" ); p.append( item );
+    initVariableName( hyp, item, "SetLayerDistribution" );
     customWidgets()->append
       ( new StdMeshersGUI_LayerDistributionParamWdg( h->GetLayerDistribution(), hypName(), dlg()));
   }
@@ -806,6 +1063,135 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
     customWidgets()->append( newObjRefParamWdg( filterForShapeOfDim( 0 ),
                                                h->GetTargetVertex( 2 )));
   }
+  else if( hypType()=="ImportSource1D" )
+  {
+    StdMeshers::StdMeshers_ImportSource1D_var h =
+      StdMeshers::StdMeshers_ImportSource1D::_narrow( hyp );
+
+    SMESH::string_array_var groupEntries = h->GetSourceEdges();
+    CORBA::Boolean toCopyMesh, toCopyGroups;
+    h->GetCopySourceMesh(toCopyMesh, toCopyGroups);
+
+    item.myName = tr( "SMESH_SOURCE_EDGES" ); p.append( item );
+    customWidgets()->append( newObjRefParamWdg( new SMESH_TypeFilter( GROUP_EDGE ), 
+                                                groupEntries));
+
+    item.myName = tr( "SMESH_COPY_MESH" ); p.append( item );
+    QCheckBox* aQCheckBox = new QCheckBox(dlg());
+    aQCheckBox->setChecked( toCopyMesh );
+    connect( aQCheckBox, SIGNAL(  stateChanged(int) ), this, SLOT( onValueChanged() ));
+    customWidgets()->append( aQCheckBox );
+
+    item.myName = tr( "SMESH_TO_COPY_GROUPS" ); p.append( item );
+    aQCheckBox = new QCheckBox(dlg());
+    aQCheckBox->setChecked( toCopyGroups );
+    aQCheckBox->setEnabled( toCopyMesh );
+    customWidgets()->append( aQCheckBox );
+  }
+  else if( hypType()=="ImportSource2D" )
+  {
+    StdMeshers::StdMeshers_ImportSource2D_var h =
+      StdMeshers::StdMeshers_ImportSource2D::_narrow( hyp );
+
+    SMESH::string_array_var groupEntries = h->GetSourceFaces();
+    CORBA::Boolean toCopyMesh, toCopyGroups;
+    h->GetCopySourceMesh(toCopyMesh, toCopyGroups);
+
+    item.myName = tr( "SMESH_SOURCE_FACES" ); p.append( item );
+    customWidgets()->append( newObjRefParamWdg( new SMESH_TypeFilter( GROUP_FACE ), 
+                                                groupEntries));
+
+    item.myName = tr( "SMESH_COPY_MESH" ); p.append( item );
+    QCheckBox* aQCheckBox = new QCheckBox(dlg());
+    aQCheckBox->setChecked( toCopyMesh );
+    connect( aQCheckBox, SIGNAL(  stateChanged(int) ), this, SLOT( onValueChanged() ));
+    customWidgets()->append( aQCheckBox );
+
+    item.myName = tr( "SMESH_COPY_GROUPS" ); p.append( item );
+    aQCheckBox = new QCheckBox(dlg());
+    aQCheckBox->setChecked( toCopyGroups );
+    aQCheckBox->setEnabled( toCopyMesh );
+    customWidgets()->append( aQCheckBox );
+  }
+  else if( hypType()=="ViscousLayers" )
+  {
+    StdMeshers::StdMeshers_ViscousLayers_var h =
+      StdMeshers::StdMeshers_ViscousLayers::_narrow( hyp );
+
+    item.myName = tr( "SMESH_TOTAL_THICKNESS" );
+    if(!initVariableName( hyp, item, "SetTotalThickness" ))
+      item.myValue = h->GetTotalThickness();
+    p.append( item );
+    customWidgets()->append (0);
+
+    item.myName = tr( "SMESH_NUMBER_OF_LAYERS" );
+    if(!initVariableName( hyp, item, "SetNumberLayers" ))
+      item.myValue = h->GetNumberLayers();
+    p.append( item );
+    customWidgets()->append (0);
+
+    item.myName = tr( "SMESH_STRETCH_FACTOR" );
+    if(!initVariableName( hyp, item, "SetStretchFactor" ))
+      item.myValue = h->GetStretchFactor();
+    p.append( item );
+    customWidgets()->append (0);
+
+    QString aMainEntry = SMESHGUI_GenericHypothesisCreator::getMainShapeEntry();
+    if ( !aMainEntry.isEmpty() )
+    {
+      item.myName = tr( "SMESH_FACES_WO_LAYERS" );
+      p.append( item );
+
+      StdMeshersGUI_SubShapeSelectorWdg* idsWg =
+        new StdMeshersGUI_SubShapeSelectorWdg(0,TopAbs_FACE);
+
+      idsWg->SetGeomShapeEntry( aMainEntry );
+      idsWg->SetMainShapeEntry( aMainEntry );
+      idsWg->SetListOfIDs( h->GetIgnoreFaces() );
+      idsWg->showPreview( true );
+      customWidgets()->append ( idsWg );
+    }
+  }
+  else if (hypType() == "QuadrangleParams")
+  {
+    StdMeshers::StdMeshers_QuadrangleParams_var h =
+      StdMeshers::StdMeshers_QuadrangleParams::_narrow(hyp);
+
+    item.myName = tr("SMESH_BASE_VERTEX");
+    p.append(item);
+
+    StdMeshersGUI_SubShapeSelectorWdg* aDirectionWidget =
+      new StdMeshersGUI_SubShapeSelectorWdg(0, TopAbs_VERTEX);
+    aDirectionWidget->SetMaxSize(1);
+    QString anEntry = SMESHGUI_GenericHypothesisCreator::getShapeEntry();
+    QString aMainEntry = SMESHGUI_GenericHypothesisCreator::getMainShapeEntry();
+    if (anEntry == "")
+      anEntry = h->GetObjectEntry();
+    aDirectionWidget->SetGeomShapeEntry(anEntry);
+    aDirectionWidget->SetMainShapeEntry(aMainEntry);
+    if (!isCreation()) {
+      SMESH::long_array_var aVec = new SMESH::long_array;
+      int vertID = h->GetTriaVertex();
+      if (vertID > 0) {
+        aVec->length(1);
+        aVec[0] = vertID;
+        aDirectionWidget->SetListOfIDs(aVec);
+      }
+    }
+    aDirectionWidget->showPreview(true);
+
+    item.myName = tr("SMESH_QUAD_TYPE");
+    p.append(item);
+
+    StdMeshersGUI_QuadrangleParamWdg* aTypeWidget =
+      new StdMeshersGUI_QuadrangleParamWdg();
+    if (!isCreation()) {
+      aTypeWidget->SetType(int(h->GetQuadType()));
+    }
+
+    customWidgets()->append(aDirectionWidget);
+    customWidgets()->append(aTypeWidget);
+  }
   else
     res = false;
   return res;
@@ -814,50 +1200,66 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
 //================================================================================
 /*!
  * \brief tune "standard" control
 * \param w - control widget
 * \param int - parameter index
 \param w - control widget
 \param int - parameter index
  */
 //================================================================================
 
 void StdMeshersGUI_StdHypothesisCreator::attuneStdWidget (QWidget* w, const int) const
 {
   SMESHGUI_SpinBox* sb = w->inherits( "SMESHGUI_SpinBox" ) ? ( SMESHGUI_SpinBox* )w : 0;
-  if( hypType()=="LocalLength" &&  sb )
-  {
-    if (sb->objectName() == tr("SMESH_LOCAL_LENGTH_PARAM"))
-      sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, 6 );
-    else if (sb->objectName() == tr("SMESH_LOCAL_LENGTH_PRECISION"))
-      sb->RangeStepAndValidator( 0.0, 1.0, 0.05, 7 );
-  }
-  else if( hypType()=="Arithmetic1D" && sb )
-  {
-    sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, 6 );
-  }
-  else if( hypType()=="MaxLength" && sb )
-  {
-    sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, 6 );
-    sb->setEnabled( !widget< QCheckBox >( 1 )->isChecked() );
-  }
-  else if( hypType()=="MaxElementArea" && sb )
-  {
-    sb->RangeStepAndValidator( VALUE_SMALL_2, VALUE_MAX_2, 1.0, 6 );
-  }
-  else if( hypType()=="MaxElementVolume" && sb )
+  if ( sb )
   {
-    sb->RangeStepAndValidator( VALUE_SMALL_3, VALUE_MAX_3, 1.0, 6 );
-  }
-  else if( hypType()=="StartEndLength" && sb )
-  {
-    sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, 6 );
-  }
-  else if( hypType()=="Deflection1D" && sb )
-  {
-    sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, 6 );
-  }
-  else if ( sb ) // default validator for possible ancestors
-  {
-    sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, 6 );
+    if( hypType()=="LocalLength" )
+    {
+      if (sb->objectName() == tr("SMESH_LOCAL_LENGTH_PARAM"))
+        sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, "length_precision" );
+      else if (sb->objectName() == tr("SMESH_LOCAL_LENGTH_PRECISION"))
+        sb->RangeStepAndValidator( 0.0, 1.0, 0.05, "len_tol_precision" );
+    }
+    else if( hypType()=="Arithmetic1D" )
+    {
+      sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, "parametric_precision" );
+    }
+    else if( hypType()=="MaxLength" )
+    {
+      sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, "length_precision" );
+      sb->setEnabled( !widget< QCheckBox >( 1 )->isChecked() );
+    }
+    else if( hypType()=="MaxElementArea" )
+    {
+      sb->RangeStepAndValidator( VALUE_SMALL_2, VALUE_MAX_2, 1.0, "area_precision" );
+    }
+    else if( hypType()=="MaxElementVolume" )
+    {
+      sb->RangeStepAndValidator( VALUE_SMALL_3, VALUE_MAX_3, 1.0, "vol_precision" );
+    }
+    else if( hypType()=="StartEndLength" )
+    {
+      sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, "length_precision" );
+    }
+    else if( hypType()=="Deflection1D" )
+    {
+      sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, "parametric_precision" );
+    }
+    else if( hypType()=="ViscousLayers" )
+    {
+      if (sb->objectName() == tr("SMESH_STRETCH_FACTOR"))
+        sb->RangeStepAndValidator( 1.0, VALUE_MAX, 0.1, "parametric_precision" );
+      else
+        sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, "length_precision" );
+    }
+    else // default validator for possible ancestors
+    {
+      sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, "length_precision" );
+    }
   }
+//   else if ( QtxIntSpinBox* ib = w->inherits( "QtxIntSpinBox" ) ? ( QtxIntSpinBox* )w : 0)
+//   {
+//     if( hypType()=="ViscousLayers" )
+//     {
+//     }
+//   }
 }
 
 //================================================================================
@@ -918,14 +1320,22 @@ QString StdMeshersGUI_StdHypothesisCreator::hypTypeName( const QString& t ) cons
     types.insert( "StartEndLength", "START_END_LENGTH" );
     types.insert( "Deflection1D", "DEFLECTION1D" );
     types.insert( "Arithmetic1D", "ARITHMETIC_1D" );
+    types.insert( "FixedPoints1D", "FIXED_POINTS_1D" );
     types.insert( "AutomaticLength", "AUTOMATIC_LENGTH" );
     types.insert( "ProjectionSource1D", "PROJECTION_SOURCE_1D" );
     types.insert( "ProjectionSource2D", "PROJECTION_SOURCE_2D" );
     types.insert( "ProjectionSource3D", "PROJECTION_SOURCE_3D" );
+    types.insert( "ImportSource1D", "IMPORT_SOURCE_1D" );
+    types.insert( "ImportSource2D", "IMPORT_SOURCE_2D" );
     types.insert( "NumberOfLayers", "NUMBER_OF_LAYERS" );
     types.insert( "LayerDistribution", "LAYER_DISTRIBUTION" );
+    types.insert( "NumberOfLayers2D", "NUMBER_OF_LAYERS_2D" );
+    types.insert( "LayerDistribution2D", "LAYER_DISTRIBUTION" );
     types.insert( "SegmentLengthAroundVertex", "SEGMENT_LENGTH_AROUND_VERTEX" );
     types.insert( "MaxLength", "MAX_LENGTH" );
+    types.insert( "ViscousLayers", "VISCOUS_LAYERS" );
+    types.insert( "QuadrangleParams", "QUADRANGLE_PARAMS" );
+    types.insert( "CartesianParameters3D", "CARTESIAN_PARAMS" );
   }
 
   QString res;
@@ -971,9 +1381,9 @@ bool StdMeshersGUI_StdHypothesisCreator::getParamFromCustomWidget( StdParam & pa
                                                                    QWidget*   widget) const
 {
   if ( hypType()=="AutomaticLength" ) {
-    TDoubleSliderWith2Lables* w = dynamic_cast<TDoubleSliderWith2Lables*>( widget );
+    SMESHGUI_SpinBox* w = dynamic_cast<SMESHGUI_SpinBox*>( widget );
     if ( w ) {
-      param.myValue = w->value();
+      param.myValue = w->GetValue();
       return true;
     }
   }
@@ -998,6 +1408,33 @@ bool StdMeshersGUI_StdHypothesisCreator::getParamFromCustomWidget( StdParam & pa
     param.myValue = w->GetValue();
     return true;
   }
+  if ( widget->inherits( "StdMeshersGUI_SubShapeSelectorWdg" ))
+  {
+    const StdMeshersGUI_SubShapeSelectorWdg * w =
+      static_cast<const StdMeshersGUI_SubShapeSelectorWdg*>( widget );
+    param.myValue = w->GetValue();
+    return true;
+  }
+  if ( widget->inherits( "StdMeshersGUI_QuadrangleParamWdg" ))
+  {
+    //const StdMeshersGUI_QuadrangleParamWdg * w =
+    //  static_cast<const StdMeshersGUI_QuadrangleParamWdg*>( widget );
+    param.myValue = "QuadType";
+    return true;
+  }
+  if ( widget->inherits( "StdMeshersGUI_FixedPointsParamWdg" ))
+  {
+    const StdMeshersGUI_FixedPointsParamWdg * w =
+      static_cast<const StdMeshersGUI_FixedPointsParamWdg*>( widget );
+    param.myValue = w->GetValue();
+    return true;
+  }
+  if ( widget->inherits( "QCheckBox" ))
+  {
+    //const QCheckBox * w = static_cast<const QCheckBox*>( widget );
+    //param.myValue = w->isChecked();
+    return true;
+  }
   return false;
 }
 
@@ -1009,7 +1446,8 @@ bool StdMeshersGUI_StdHypothesisCreator::getParamFromCustomWidget( StdParam & pa
 
 void StdMeshersGUI_StdHypothesisCreator::onReject()
 {
-  if ( hypType().startsWith("ProjectionSource" ))
+  if ( hypType().startsWith("ProjectionSource" ) ||
+       hypType().startsWith("ImportSource" ))
   {
     // Uninstall filters of StdMeshersGUI_ObjectReferenceParamWdg
     deactivateObjRefParamWdg( customWidgets() );
@@ -1018,13 +1456,14 @@ void StdMeshersGUI_StdHypothesisCreator::onReject()
 
 //================================================================================
 /*!
- * \brief 
+ * \brief Update widgets dependent on paramWidget
  */
 //================================================================================
 
 void StdMeshersGUI_StdHypothesisCreator::valueChanged( QWidget* paramWidget)
 {
-  if ( hypType() == "MaxLength" && paramWidget == getWidgetForParam(1) ) {
+  if ( hypType() == "MaxLength" && paramWidget == getWidgetForParam(1) )
+  {
     getWidgetForParam(0)->setEnabled( !widget< QCheckBox >( 1 )->isChecked() );
     if ( !getWidgetForParam(0)->isEnabled() ) {
       StdMeshers::StdMeshers_MaxLength_var h =
@@ -1032,6 +1471,20 @@ void StdMeshersGUI_StdHypothesisCreator::valueChanged( QWidget* paramWidget)
       widget< QtxDoubleSpinBox >( 0 )->setValue( h->GetPreestimatedLength() );
     }
   }
+  else if ( hypType().startsWith("ImportSource") && paramWidget == getWidgetForParam(1) )
+  {
+    QCheckBox* toCopyMesh   = (QCheckBox*) paramWidget;
+    QCheckBox* toCopyGroups = widget< QCheckBox >( 2 );
+    if ( !toCopyMesh->isChecked() )
+    {
+      toCopyGroups->setChecked( false );
+      toCopyGroups->setEnabled( false );
+    }
+    else
+    {
+      toCopyGroups->setEnabled( true );
+    }
+  }
 }
 
 //================================================================================
@@ -1040,13 +1493,13 @@ void StdMeshersGUI_StdHypothesisCreator::valueChanged( QWidget* paramWidget)
  */
 //================================================================================
 
-bool StdMeshersGUI_StdHypothesisCreator::initVariableName(SMESH::ListOfParameters_var theParameters
-                                                          StdParam &theParams, 
-                                                          int order) const
+bool StdMeshersGUI_StdHypothesisCreator::initVariableName(SMESH::SMESH_Hypothesis_var theHyp
+                                                          StdParam &                  theParams, 
+                                                          const char*                 theMethod) const
 {
-  QString aVaribaleName = (theParameters->length() > order) ? QString(theParameters[order].in()) : QString("");
+  QString aVaribaleName = getVariableName( theMethod );
   theParams.isVariable = !aVaribaleName.isEmpty();
-  if(theParams.isVariable) 
+  if (theParams.isVariable)
     theParams.myValue = aVaribaleName;
 
   return theParams.isVariable;
index 0973c5c03325e349cf6036f3f56acb353ca21d9b..c08e255e73003dc5aa4e4fa62cb78fa1e50af5d6 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // File   : StdMeshersGUI_StdHypothesisCreator.h
 // Author : Alexander SOLOVYOV, Open CASCADE S.A.S.
 //
@@ -59,7 +60,7 @@ protected:
   virtual QWidget* getWidgetForParam( int paramIndex ) const;
   virtual ListOfWidgets* customWidgets() const;
   virtual void     onReject();
-  virtual bool     initVariableName(SMESH::ListOfParameters_var theParameters, StdParam& theParams, int order) const;
+  bool             initVariableName(SMESH::SMESH_Hypothesis_var theHyp, StdParam& theParams, const char* theMethod) const;
 
   virtual void     valueChanged( QWidget* );
 
diff --git a/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.cxx b/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.cxx
new file mode 100644 (file)
index 0000000..8c22408
--- /dev/null
@@ -0,0 +1,610 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+// File   : StdMeshersGUI_SubShapeSelectorWdg.cxx
+// Author : Open CASCADE S.A.S. (dmv)
+// SMESH includes
+//
+#include "StdMeshersGUI_SubShapeSelectorWdg.h"
+
+// SMESH Includes
+#include "SMESH_Type.h"
+#include "SMESHGUI_MeshUtils.h"
+#include "SMESH_Actor.h"
+#include "SMESH_PreviewActorsCollection.h"
+#include "SMESH_ActorUtils.h"
+#include "SMESHGUI_GroupUtils.h"
+#include "SMESH_Gen_i.hxx"
+#include "SMESHGUI_GEOMGenUtils.h"
+#include "SMESH_LogicalFilter.hxx"
+
+// SVTK Includes
+#include <SVTK_ViewWindow.h>
+#include <SVTK_ViewModel.h>
+#include <SVTK_ViewWindow.h>
+#include <SVTK_Selector.h>
+
+// SALOME GUI includes
+#include <SALOME_ListIO.hxx>
+#include <LightApp_SelectionMgr.h>
+#include <SALOME_ListIteratorOfListIO.hxx>
+
+// SUIT Includes
+#include <SUIT_ResourceMgr.h>
+
+// GEOM Includes
+#include <GEOMBase.h>
+#include <GEOM_TypeFilter.h>
+#include <GEOM_CompoundFilter.h>
+
+// Qt includes
+#include <QPushButton>
+#include <QGridLayout>
+#include <QListWidget>
+#include <QCheckBox>
+#include <QLineEdit>
+
+// OCCT includes
+#include <TColStd_MapOfInteger.hxx>
+#include <TColStd_IndexedMapOfInteger.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <StdSelect_TypeOfEdge.hxx>
+
+// SALOME KERNEL includes
+#include <SALOMEDS_SObject.hxx>
+
+
+#define SPACING 6
+#define MARGIN 0
+
+//================================================================================
+/*!
+ *  Constructor
+ */
+//================================================================================
+
+StdMeshersGUI_SubShapeSelectorWdg
+::StdMeshersGUI_SubShapeSelectorWdg( QWidget * parent, TopAbs_ShapeEnum aSubShType ): 
+  QWidget( parent ),
+  myPreviewActor( 0 ),
+  myMaxSize( -1 )
+{
+  QPixmap image0( SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap( "SMESH", tr( "ICON_SELECT" ) ) );
+
+  QGridLayout* edgesLayout = new QGridLayout( this );
+  edgesLayout->setMargin( MARGIN );
+  edgesLayout->setSpacing( SPACING );
+  
+  myListWidget   = new QListWidget( this );
+  myAddButton    = new QPushButton( tr( "SMESH_BUT_ADD" ),    this );
+  myRemoveButton = new QPushButton( tr( "SMESH_BUT_REMOVE" ), this );      
+  myInfoLabel    = new QLabel( this );
+  myPrevButton   = new QPushButton( "<<", this );
+  myNextButton   = new QPushButton( ">>", this );
+  myListWidget->setSelectionMode( QListWidget::ExtendedSelection );
+
+  edgesLayout->addWidget(myListWidget,   0, 0, 3, 3);
+  edgesLayout->addWidget(myAddButton,    0, 3);
+  edgesLayout->addWidget(myRemoveButton, 1, 3);
+  edgesLayout->addWidget(myInfoLabel,    3, 0, 1, 3);
+  edgesLayout->addWidget(myPrevButton,   4, 0);
+  edgesLayout->addWidget(myNextButton,   4, 2);
+
+  edgesLayout->setRowStretch(2, 5);
+  edgesLayout->setColumnStretch(1, 5);
+
+  myListWidget->setMinimumWidth(300);
+  myInfoLabel->setMinimumWidth(300);
+  myInfoLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
+  myInfoLabel->setAlignment(Qt::AlignCenter);
+
+  mySubShType = aSubShType;
+
+  init();
+}
+
+//================================================================================
+/*!
+ *  Destructor
+ */
+//================================================================================
+
+StdMeshersGUI_SubShapeSelectorWdg::~StdMeshersGUI_SubShapeSelectorWdg()
+{
+  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) {
+    if ( myPreviewActor ) {
+      myPreviewActor->RemoveFromRender( myRenderer );
+      aViewWindow->Repaint();
+
+      delete myPreviewActor;
+      myPreviewActor = 0;
+    }
+  }
+  myEntry = "";
+  myParamValue = "";
+  myMainShape.Nullify();
+
+  if ( mySelectionMgr && myFilter )
+    mySelectionMgr->removeFilter( myFilter );
+  delete myFilter; myFilter=0;
+
+  SUIT_SelectionFilter* filter;
+  foreach( filter, myGeomFilters )
+    delete filter;
+}
+
+//================================================================================
+/*!
+ *  Create a layout, initialize fields
+ */
+//================================================================================
+
+void StdMeshersGUI_SubShapeSelectorWdg::init()
+{
+  myParamValue = "";
+  myIsNotCorrected = true; // to dont call the GetCorrectedValue method twice
+  myListOfIDs.clear();
+  mySelectedIDs.clear();
+
+  myAddButton->setEnabled( false );
+  myRemoveButton->setEnabled( false );
+
+  mySMESHGUI     = SMESHGUI::GetSMESHGUI();
+  mySelectionMgr = SMESH::GetSelectionMgr( mySMESHGUI );
+  mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
+
+  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+    aViewWindow->SetSelectionMode( ActorSelection );
+
+  myFilter=0;
+  //setFilter();
+
+  connect( myAddButton,    SIGNAL(clicked()), SLOT(onAdd()));
+  connect( myRemoveButton, SIGNAL(clicked()), SLOT(onRemove()));
+  connect( myPrevButton,   SIGNAL(clicked()), SLOT(onPrevious()));
+  connect( myNextButton,   SIGNAL(clicked()), SLOT(onNext()));
+  
+  connect( mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
+  connect( myListWidget,   SIGNAL(itemSelectionChanged()),    this, SLOT(onListSelectionChanged()));
+
+  updateState();
+}
+
+//================================================================================
+/*!
+ * \brief Install filters to select sub-shapes of mySubShType or their groups
+ */
+//================================================================================
+
+void StdMeshersGUI_SubShapeSelectorWdg::setFilter()
+{
+  SalomeApp_Study* study = mySMESHGUI->activeStudy();
+  GEOM_TypeFilter* typeFilter = new GEOM_TypeFilter(study, mySubShType, /*isShapeType=*/true );
+  GEOM_CompoundFilter* gpoupFilter = new GEOM_CompoundFilter(study);
+  gpoupFilter->addSubType( mySubShType );
+  myGeomFilters.append( typeFilter );
+  myGeomFilters.append( gpoupFilter );
+  myFilter = new SMESH_LogicalFilter( myGeomFilters, SMESH_LogicalFilter::LO_OR );
+  mySelectionMgr->installFilter( myFilter );
+}
+
+//================================================================================
+/*!
+ *  Create a layout, initialize fields
+ */
+//================================================================================
+
+void StdMeshersGUI_SubShapeSelectorWdg::showPreview( bool visible)
+{
+  if ( !myPreviewActor )
+    return;
+
+  if ( myIsShown != visible ) {
+    myPreviewActor->SetShown( visible );
+    
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->Repaint();
+
+    myIsShown = visible;
+  }
+}
+
+//=================================================================================
+// function : SelectionIntoArgument()
+// purpose  : Called when selection as changed or other case
+//=================================================================================
+void StdMeshersGUI_SubShapeSelectorWdg::SelectionIntoArgument()
+{
+  if ( !myPreviewActor )
+    return;
+
+  mySelectedIDs.clear();
+
+  // get selected mesh
+  SALOME_ListIO aList;
+  mySelectionMgr->selectedObjects( aList );
+  int nbSel = aList.Extent();
+
+  if (nbSel > 0) {
+    SALOME_ListIteratorOfListIO anIt (aList);
+    
+    for ( ; anIt.More(); anIt.Next()) { // Loop on selected objects
+      Handle(SALOME_InteractiveObject) IO = anIt.Value();
+      
+      GEOM::GEOM_Object_var aGeomObj = GetGeomObjectByEntry( IO->getEntry() );  
+      if ( !CORBA::is_nil( aGeomObj ) ) { // Selected Object From Study
+        GEOM::GEOM_Object_ptr aGeomFatherObj = aGeomObj->GetMainShape();
+        QString aFatherEntry = "";
+        QString aMainFatherEntry = "";
+        TopoDS_Shape shape;
+        if ( !CORBA::is_nil( aGeomFatherObj ) ) {
+          // Get Main Shape
+          GEOM::GEOM_Object_var aGeomMain = GetGeomObjectByEntry( myEntry );
+          if ( !CORBA::is_nil( aGeomMain ) && aGeomMain->GetType() == 37 ) {  // Main Shape is a Group
+            GEOM::GEOM_Object_ptr aMainFatherObj = aGeomMain->GetMainShape();
+            if ( !CORBA::is_nil( aMainFatherObj ) )
+              aMainFatherEntry = aMainFatherObj->GetStudyEntry();
+          }
+          aFatherEntry = aGeomFatherObj->GetStudyEntry();
+        }
+        
+        if ( aFatherEntry != "" && ( aFatherEntry == myEntry || aFatherEntry == aMainFatherEntry ) )
+        {
+          if ( aGeomObj->GetType() == 37 /*GEOM_GROUP*/ ) { // Selected Group that belongs the main object
+            GEOMBase::GetShape(aGeomObj, shape); 
+            if ( !shape.IsNull() ) {
+              TopExp_Explorer exp( shape, mySubShType );
+              for ( ; exp.More(); exp.Next() ) {
+                int index = myPreviewActor->GetIndexByShape( exp.Current() );
+                if ( index ) {
+                  mySelectedIDs.append( index );
+                  myPreviewActor->HighlightID( index );
+                }
+              }
+            }
+          } else if ( aGeomObj->GetType() == 28 /*GEOM_SUBSHAPE*/  ) {
+            GEOMBase::GetShape(aGeomObj, shape); 
+            if ( !shape.IsNull() && shape.ShapeType() == mySubShType ) {
+              int index = myPreviewActor->GetIndexByShape( shape );
+              if ( index ) {
+                mySelectedIDs.append( index );
+                myPreviewActor->HighlightID( index );
+              }
+            }
+          }
+        }
+      } else { // Selected Actor from Actor Collection
+        QString anEntry = IO->getEntry();
+        QString str = "_";
+        int index = anEntry.lastIndexOf( str );
+        anEntry.remove(0, index+1);
+        int ind = anEntry.toInt();
+        if ( ind )
+          mySelectedIDs.append( ind );
+      }
+    }
+  }
+  // update add button
+  myAddButton->setEnabled( ( myListWidget->count() < myMaxSize || myMaxSize == -1 ) && mySelectedIDs.size() > 0 && ( mySelectedIDs.size() <= myMaxSize || myMaxSize == -1 ) );
+
+  //Connect Selected Ids in viewer and dialog's Ids list
+  bool signalsBlocked = myListWidget->blockSignals( true );
+  myListWidget->clearSelection();
+  if ( mySelectedIDs.size() > 0 ) {
+    for (int i = 0; i < mySelectedIDs.size(); i++) {
+      QString anID = QString(" %1").arg( mySelectedIDs.at(i) );
+      QList<QListWidgetItem*> anItems = myListWidget->findItems ( anID, Qt::MatchExactly );
+      QListWidgetItem* item;
+      foreach(item, anItems)
+        item->setSelected(true);
+    }
+  }
+  myListWidget->blockSignals( signalsBlocked );
+}
+
+//=================================================================================
+// function : onAdd()
+// purpose  : Called when Add Button Clicked
+//=================================================================================
+void StdMeshersGUI_SubShapeSelectorWdg::onAdd()
+{
+  if ( mySelectedIDs.size() < 1 )
+    return;
+
+  myListWidget->blockSignals( true );
+  for (int i = 0; i < mySelectedIDs.size() && (myMaxSize == -1 || myListOfIDs.size() < myMaxSize); i++) {
+    if ( myListOfIDs.indexOf( mySelectedIDs.at(i) ) == -1 ) {
+      QString anID = QString(" %1").arg( mySelectedIDs.at(i) );
+
+      QListWidgetItem* anItem = new QListWidgetItem( anID, myListWidget );
+      anItem->setSelected(true);
+      
+      myListOfIDs.append( mySelectedIDs.at(i) );
+    }
+  }
+  onListSelectionChanged();
+  myListWidget->blockSignals( false );
+  myAddButton->setEnabled( myMaxSize == -1 || myListOfIDs.size() < myMaxSize );
+}
+         
+//=================================================================================
+// function : onRemove()
+// purpose  : Called when Remove Button Clicked
+//=================================================================================
+void StdMeshersGUI_SubShapeSelectorWdg::onRemove()
+{
+  if ( myListWidget->count() < 1 )
+    return;
+
+  myListWidget->blockSignals( true );
+  QList<QListWidgetItem*> selItems = myListWidget->selectedItems();
+  QListWidgetItem* item;
+  foreach(item, selItems) {
+    QString idStr = item->text();
+    int id = idStr.toInt();
+
+    int index = myListOfIDs.indexOf( id );
+    myListOfIDs.removeAt( index );
+    delete item;
+  }
+
+  onListSelectionChanged();
+  myListWidget->blockSignals( false );
+  
+  myAddButton->setEnabled( true );
+}
+
+void StdMeshersGUI_SubShapeSelectorWdg::onPrevious()
+{
+  if ( myPreviewActor ) {
+    myPreviewActor->previous();
+    myListWidget->clearSelection();
+    updateButtons();
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->Repaint();
+  }
+}
+
+void StdMeshersGUI_SubShapeSelectorWdg::onNext()
+{
+  if ( myPreviewActor ) {
+    myPreviewActor->next();
+    myListWidget->clearSelection();
+    updateButtons();
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->Repaint();
+  }
+}
+
+//=================================================================================
+// function : onListSelectionChanged()
+// purpose  : Called when selection in element list is changed
+//=================================================================================
+void StdMeshersGUI_SubShapeSelectorWdg::onListSelectionChanged()
+{
+  if ( !myPreviewActor )
+    return;
+
+  mySelectionMgr->clearSelected();
+  TColStd_MapOfInteger aIndexes;
+  QList<QListWidgetItem*> selItems = myListWidget->selectedItems();
+  QListWidgetItem* anItem;
+  foreach(anItem, selItems)
+    myPreviewActor->HighlightID( anItem->text().toInt() );
+
+  // update remove button
+  myRemoveButton->setEnabled( selItems.size() > 0 );
+}
+
+//=================================================================================
+// function : setGeomShape
+// purpose  : Called to set geometry whose sub-shapes are selected
+//================================================================================
+void StdMeshersGUI_SubShapeSelectorWdg::SetGeomShapeEntry( const QString& theEntry )
+{
+  if ( theEntry != "") {
+    myParamValue = theEntry;
+    myEntry = theEntry;
+    myGeomShape = GetTopoDSByEntry( theEntry );
+    updateState();
+    myIsNotCorrected = true;
+  }
+}
+
+//=================================================================================
+// function : updateState
+// purpose  : update Widget state
+//=================================================================================
+void StdMeshersGUI_SubShapeSelectorWdg::updateState()
+{
+  bool state = false;
+  if ( !myGeomShape.IsNull() )
+    state = true;
+  myInfoLabel->setVisible( false );
+  myPrevButton->setVisible( false );
+  myNextButton->setVisible( false );
+  
+  myListWidget->setEnabled( state );
+  myAddButton->setEnabled( mySelectedIDs.size() > 0 );
+  
+  if (state) {
+    myPreviewActor = new SMESH_PreviewActorsCollection();
+    myPreviewActor->SetSelector( mySelector );
+    myPreviewActor->Init( myGeomShape, mySubShType, myEntry );
+    myPreviewActor->SetShown( false );
+    myIsShown = false;
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) {
+      myRenderer = aViewWindow->getRenderer();
+      myPreviewActor->AddToRender( myRenderer );
+      aViewWindow->Repaint();
+    }
+    updateButtons();
+  }
+}
+
+//=================================================================================
+// function : GetGeomObjectByEntry
+// purpose  : Called to get GeomObject
+//=================================================================================
+GEOM::GEOM_Object_var StdMeshersGUI_SubShapeSelectorWdg::GetGeomObjectByEntry( const QString& theEntry )
+{
+  GEOM::GEOM_Object_var aGeomObj;
+  SALOMEDS::Study_var aStudy = SMESHGUI::GetSMESHGen()->GetCurrentStudy();
+  if (aStudy != 0) {
+    SALOMEDS::SObject_var aSObj = aStudy->FindObjectID( theEntry.toLatin1().data() );
+    SALOMEDS::GenericAttribute_var anAttr;
+
+    if (!aSObj->_is_nil() && aSObj->FindAttribute(anAttr, "AttributeIOR")) {
+      SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
+      CORBA::String_var aVal = anIOR->Value();
+      CORBA::Object_var obj = aStudy->ConvertIORToObject(aVal);
+      aGeomObj = GEOM::GEOM_Object::_narrow(obj);
+    }
+  }
+  return aGeomObj;
+}
+
+//=================================================================================
+// function : setObjectByEntry
+// purpose  : Called to get GeomObject
+//=================================================================================
+TopoDS_Shape StdMeshersGUI_SubShapeSelectorWdg::GetTopoDSByEntry( const QString& theEntry )
+{
+  TopoDS_Shape shape;
+  GEOM::GEOM_Object_var aGeomObj = GetGeomObjectByEntry( theEntry );
+  GEOMBase::GetShape(aGeomObj, shape);
+  return shape;
+}
+
+//=================================================================================
+// function : GetListOfIds
+// purpose  : Called to get the list of SubShapes IDs
+//=================================================================================
+SMESH::long_array_var StdMeshersGUI_SubShapeSelectorWdg::GetListOfIDs()
+{
+  SMESH::long_array_var anArray = new SMESH::long_array;
+
+  if ( myMainEntry != "" && myIsNotCorrected )
+    myListOfIDs = GetCorrectedListOfIDs( true );
+
+  int size = myListOfIDs.size();
+  anArray->length( size );
+  if ( size ) {
+    for (int i = 0; i < size; i++) {
+        anArray[i] = myListOfIDs.at(i);
+    }
+  }
+  return anArray;
+}
+
+//=================================================================================
+// function : SetListOfIds
+// purpose  : Called to set the list of SubShapes IDs
+//=================================================================================
+void StdMeshersGUI_SubShapeSelectorWdg::SetListOfIDs( SMESH::long_array_var theIds)
+{
+  mySelectedIDs.clear();
+  myListOfIDs.clear();
+  int size = theIds->length();
+  for ( int i = 0; i < size; i++ )
+    mySelectedIDs.append( theIds[ i ] );
+
+  mySelectedIDs = GetCorrectedListOfIDs( false );
+  onAdd();
+}
+
+//=================================================================================
+// function : SetMainShapeEntry
+// purpose  : Called to set the Entry of main shape of the mesh
+//=================================================================================
+void StdMeshersGUI_SubShapeSelectorWdg::SetMainShapeEntry( const QString& theEntry )
+{
+  myMainEntry = theEntry;
+  myMainShape = GetTopoDSByEntry( theEntry );
+  myIsNotCorrected = true;
+}
+
+//=================================================================================
+// function : GetMainShapeEntry
+// purpose  : Called to get the Main Object Entry
+//=================================================================================
+const char* StdMeshersGUI_SubShapeSelectorWdg::GetMainShapeEntry()
+{
+  if ( myMainEntry == "")
+    return myEntry.toLatin1().data();
+
+  return myMainEntry.toLatin1().data();
+}
+
+//=================================================================================
+// function : GetCorrectedListOfIds
+// purpose  : Called to convert the list of IDs from sub-shape IDs to main shape IDs
+//=================================================================================
+QList<int> StdMeshersGUI_SubShapeSelectorWdg::GetCorrectedListOfIDs( bool fromSubshapeToMainshape )
+{
+  if ( ( myMainShape.IsNull() || myGeomShape.IsNull() ) &&  fromSubshapeToMainshape )
+    return myListOfIDs;
+  else   if ( ( myMainShape.IsNull() || myGeomShape.IsNull() ) &&  !fromSubshapeToMainshape )
+    return mySelectedIDs;
+
+  QList<int> aList;
+  TopTools_IndexedMapOfShape   aGeomMap;
+  TopTools_IndexedMapOfShape   aMainMap;
+  TopExp::MapShapes(myGeomShape, aGeomMap);
+  TopExp::MapShapes(myMainShape, aMainMap);
+
+  if ( fromSubshapeToMainshape ) { // convert indexes from sub-shape to mainshape
+    int size = myListOfIDs.size();
+    for (int i = 0; i < size; i++) {
+      TopoDS_Shape aSubShape = aGeomMap.FindKey( myListOfIDs.at(i) );
+      int index = aMainMap.FindIndex( aSubShape );
+      aList.append( index );
+    }
+    myIsNotCorrected = false;
+  } else { // convert indexes from main shape to sub-shape
+    int size = mySelectedIDs.size();
+    for (int i = 0; i < size; i++) {
+      TopoDS_Shape aSubShape = aMainMap.FindKey( mySelectedIDs.at(i) );
+      int index = aGeomMap.FindIndex( aSubShape );
+      aList.append( index );
+    }
+  }
+
+  return aList;
+}
+
+void StdMeshersGUI_SubShapeSelectorWdg::updateButtons()
+{
+  if ( myPreviewActor ) {
+    int total = myPreviewActor->count();
+    int chunk = myPreviewActor->currentChunk();
+    int chunkSize = myPreviewActor->chunkSize();
+    int imin = chunk*chunkSize+1;
+    int imax = std::min((chunk+1)*chunkSize, total);
+    bool vis = imax > 0 && total > chunkSize;
+    myInfoLabel->setVisible( vis );
+    myPrevButton->setVisible( vis );
+    myNextButton->setVisible( vis );
+    myInfoLabel->setText( tr( "X_FROM_Y_ITEMS_SHOWN" ).arg(imin).arg(imax).arg(total) );
+    myPrevButton->setEnabled( myPreviewActor->hasPrevious() );
+    myNextButton->setEnabled( myPreviewActor->hasNext() );
+  }
+}
diff --git a/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.h b/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.h
new file mode 100644 (file)
index 0000000..6d3cbbe
--- /dev/null
@@ -0,0 +1,136 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+// File   : StdMeshersGUI_SubShapeSelectorWdg.h
+// Author : Open CASCADE S.A.S. (dmv)
+//
+#ifndef STDMESHERSGUI_SUBSHAPESELECTORWDG_H
+#define STDMESHERSGUI_SUBSHAPESELECTORWDG_H
+
+// SMESH includes
+#include <SMESHGUI.h>
+#include "SMESH_StdMeshersGUI.hxx"
+#include "SMESH_SMESHGUI.hxx"
+
+// Qt includes
+#include <QWidget>
+#include <QStringList>
+#include <TopoDS_Shape.hxx>
+
+#include <SMESHGUI_VTKUtils.h>
+
+class SMESHGUI;
+class LightApp_SelectionMgr;
+class SVTK_Selector;
+class QPushButton;
+class QLabel;
+class QLineEdit;
+class QCheckBox;
+class QListWidget;
+class SMESH_Actor;
+class SMESH_PreviewActorsCollection;
+class vtkRenderer;
+class SUIT_SelectionFilter;
+
+class STDMESHERSGUI_EXPORT StdMeshersGUI_SubShapeSelectorWdg : public QWidget
+{
+  Q_OBJECT
+
+public:
+  StdMeshersGUI_SubShapeSelectorWdg( QWidget* parent = 0,
+                                     TopAbs_ShapeEnum aSubShType = TopAbs_EDGE );
+  ~StdMeshersGUI_SubShapeSelectorWdg();
+
+  SMESH::long_array_var          GetListOfIDs();
+  void                           SetListOfIDs( SMESH::long_array_var );
+
+  void                           SetGeomShapeEntry( const QString& theEntry );
+  const char*                    GetGeomShapeEntry() { return myEntry.toLatin1().data();}
+
+  void                           SetMainShapeEntry( const QString& theEntry );
+  const char*                    GetMainShapeEntry();
+
+  TopoDS_Shape                   GetGeomShape() { return myGeomShape; }
+  TopoDS_Shape                   GetMainShape() { return myMainShape; }
+
+  QList<int>                     GetCorrectedListOfIDs( bool fromSubshapeToMainshape = true );
+
+  static GEOM::GEOM_Object_var   GetGeomObjectByEntry( const QString& );
+  static TopoDS_Shape            GetTopoDSByEntry( const QString& );
+
+  QString                        GetValue() const { return myParamValue; }
+
+  void                           showPreview ( bool );
+
+  int                            GetListSize() { return myListOfIDs.size(); }
+
+  void SetMaxSize(int aMaxSize) { myMaxSize = aMaxSize; }
+  //void SetSubShType(TopAbs_ShapeEnum aSubShType) { mySubShType = aSubShType; }
+
+private:
+  void                           updateState();
+  void                           setFilter();
+  void                           updateButtons();
+
+private slots:
+  void                           onAdd(); 
+  void                           onRemove(); 
+  void                           onPrevious(); 
+  void                           onNext(); 
+  void                           SelectionIntoArgument();
+  void                           onListSelectionChanged();
+
+private:
+  void                           init();
+
+private:
+  SMESHGUI*                      mySMESHGUI;
+  LightApp_SelectionMgr*         mySelectionMgr;          /* User shape selection */
+  SVTK_Selector*                 mySelector;
+  SMESH::SMESH_Mesh_var          myMesh;
+  TopoDS_Shape                   myGeomShape; // shape whose sub-shapes are selected
+  TopoDS_Shape                   myMainShape; // main shape of the mesh
+  QString                        myEntry;
+  QString                        myMainEntry;
+  vtkRenderer*                   myRenderer;
+  
+  QListWidget*                   myListWidget;
+  QPushButton*                   myAddButton;
+  QPushButton*                   myRemoveButton;
+  QLabel*                        myInfoLabel;
+  QPushButton*                   myPrevButton;
+  QPushButton*                   myNextButton;
+  QList<int>                     mySelectedIDs;
+  QList<int>                     myListOfIDs;
+  
+  QString                        myParamValue;
+  bool                           myIsShown;
+  bool                           myIsNotCorrected;
+
+  // for manage possible size of myListOfIDs
+  int                            myMaxSize;
+  // for manage type of selected subshape
+  TopAbs_ShapeEnum               mySubShType;
+  
+  SMESH_PreviewActorsCollection* myPreviewActor;
+  QList<SUIT_SelectionFilter*>   myGeomFilters;
+  SUIT_SelectionFilter*          myFilter;
+};
+
+#endif // STDMESHERSGUI_SUBSHAPESELECTORWDG_H
index 132661aa001d8f24eae0f788981ee4ad287d3b41..aaf16607c11a5eae684e9f32c22a4933111ee626 100644 (file)
@@ -1,34 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE TS>
-<!--
-  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-
-  Copyright (C) 2003-2007  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.com
-
--->
-<TS version="1.1" >
+<TS version="2.0" language="en_US">
     <context>
         <name>@default</name>
         <message>
             <source>ICON_DLG_ARITHMETIC_1D</source>
             <translation>mesh_hypo_length.png</translation>
         </message>
+        <message>
+            <source>ICON_DLG_FIXED_POINTS_1D</source>
+            <translation>mesh_hypo_length.png</translation>
+        </message>
         <message>
             <source>ICON_DLG_AUTOMATIC_LENGTH</source>
             <translation>mesh_hypo_length.png</translation>
             <source>ICON_DLG_MAX_LENGTH</source>
             <translation>mesh_hypo_length.png</translation>
         </message>
+        <message>
+            <source>ICON_DLG_CARTESIAN_PARAMS</source>
+            <translation>mesh_hypo_length.png</translation>
+        </message>
+        <message>
+            <source>ICON_DLG_VISCOUS_LAYERS</source>
+            <translation>mesh_hypo_viscous_layers.png</translation>
+        </message>
         <message>
             <source>ICON_DLG_MAX_ELEMENT_AREA</source>
             <translation>mesh_hypo_area.png</translation>
             <source>ICON_DLG_NUMBER_OF_LAYERS</source>
             <translation>mesh_hypo_layer_distribution.png</translation>
         </message>
+       <message>
+            <source>ICON_DLG_NUMBER_OF_LAYERS_2D</source>
+            <translation>mesh_hypo_layer_distribution.png</translation>
+        </message>
         <message>
             <source>ICON_DLG_PROJECTION_SOURCE_1D</source>
             <translation>mesh_hypo_source_edge.png</translation>
             <source>ICON_DLG_PROJECTION_SOURCE_3D</source>
             <translation>mesh_hypo_source_3d.png</translation>
         </message>
+        <message>
+            <source>ICON_DLG_QUADRANGLE_PARAMS</source>
+            <translation>mesh_hypo_length.png</translation>
+        </message>
+        <message>
+            <source>ICON_DLG_IMPORT_SOURCE_1D</source>
+            <translation>mesh_hypo_source_edge.png</translation>
+        </message>
+        <message>
+            <source>ICON_DLG_IMPORT_SOURCE_2D</source>
+            <translation>mesh_hypo_source_face.png</translation>
+        </message>
         <message>
             <source>ICON_DLG_SEGMENT_LENGTH_AROUND_VERTEX</source>
             <translation>mesh_hypo_length.png</translation>
             <source>ICON_SMESH_TREE_ALGO_CompositeSegment_1D</source>
             <translation>mesh_tree_algo_regular.png</translation>
         </message>
+       <message>
+            <source>ICON_SMESH_TREE_ALGO_UseExisting_2D</source>
+            <translation>mesh_tree_algo_existing_2D.png</translation>
+        </message>
+       <message>
+            <source>ICON_SMESH_TREE_ALGO_UseExisting_1D</source>
+            <translation>mesh_tree_algo_regular.png</translation>
+        </message>
         <message>
             <source>ICON_SMESH_TREE_ALGO_Hexa_3D</source>
             <translation>mesh_tree_algo_hexa.png</translation>
             <source>ICON_SMESH_TREE_ALGO_Quadrangle_2D</source>
             <translation>mesh_tree_algo_quad.png</translation>
         </message>
+       <message>
+            <source>ICON_SMESH_TREE_ALGO_RadialQuadrangle_1D2D</source>
+            <translation>mesh_tree_algo_radial_quadrangle_1D2D.png</translation>
+        </message>
+       <message>
+            <source>ICON_SMESH_TREE_ALGO_Prism_3D</source>
+            <translation>mesh_tree_algo_prism.png</translation>
+        </message>
         <message>
             <source>ICON_SMESH_TREE_ALGO_RadialPrism_3D</source>
             <translation>mesh_tree_algo_radial_prism.png</translation>
         </message>
         <message>
             <source>ICON_SMESH_TREE_ALGO_SegmentAroundVertex_0D</source>
-            <translation>mesh_tree_algo_regular.png</translation>
+            <translation>mesh_tree_algo_0D.png</translation>
         </message>
         <message>
             <source>ICON_SMESH_TREE_HYPO_Arithmetic1D</source>
             <source>ICON_SMESH_TREE_HYPO_NumberOfSegments</source>
             <translation>mesh_tree_hypo_segment.png</translation>
         </message>
+        <message>
+            <source>ICON_SMESH_TREE_HYPO_ViscousLayers</source>
+            <translation>mesh_tree_hypo_viscous_layers.png</translation>
+        </message>
         <message>
             <source>ICON_SMESH_TREE_HYPO_ProjectionSource1D</source>
             <translation>mesh_tree_hypo_source_edge.png</translation>
             <translation>mesh_tree_hypo_length.png</translation>
         </message>
     </context>
+    <context>
+        <name>StdMeshersGUI_QuadrangleParamWdg</name>
+        <message>
+            <source>ICON_StdMeshers_Quadrangle_Params_0</source>
+            <translation>mesh_quadrangle_standard.png</translation>
+        </message>
+        <message>
+            <source>ICON_StdMeshers_Quadrangle_Params_1</source>
+            <translation>mesh_quadrangle_triapref.png</translation>
+        </message>
+        <message>
+            <source>ICON_StdMeshers_Quadrangle_Params_2</source>
+            <translation>mesh_quadrangle_quadpref.png</translation>
+        </message>
+        <message>
+            <source>ICON_StdMeshers_Quadrangle_Params_3</source>
+            <translation>mesh_quadrangle_quadpref_reversed.png</translation>
+        </message>
+        <message>
+            <source>ICON_StdMeshers_Quadrangle_Params_4</source>
+            <translation>mesh_quadrangle_reduced.png</translation>
+        </message>
+    </context>
 </TS>
index f11a5d675a1c0f3ceaa2f725fa9877772daf0798..df97c12a15c0becd9c74fb20818deaeec6d66a18 100644 (file)
+<?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE TS>
-<!--
-  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-
-  Copyright (C) 2003-2007  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.com
-
--->
-<TS version="1.1" >
-    <context>
-        <name>@default</name>
-        <message>
-            <source>SMESH_ARITHMETIC_1D_HYPOTHESIS</source>
-            <translation>Arithmetic 1D</translation>
-        </message>
-        <message>
-            <source>SMESH_ARITHMETIC_1D_PARAM</source>
-            <translation>Arithmetic Reason</translation>
-        </message>
-        <message>
-            <source>SMESH_ARITHMETIC_1D_TITLE</source>
-            <translation>Hypothesis Construction</translation>
-        </message>
-        <message>
-            <source>SMESH_AUTOMATIC_LENGTH_HYPOTHESIS</source>
-            <translation>Automatic Length</translation>
-        </message>
-        <message>
-            <source>SMESH_AUTOMATIC_LENGTH_TITLE</source>
-            <translation>Hypothesis Construction</translation>
-        </message>
-        <message>
-            <source>SMESH_CONV_MODE</source>
-            <translation>Conversion mode </translation>
-        </message>
-        <message>
-            <source>SMESH_CUT_NEG_MODE</source>
-            <translation>Cut negative</translation>
-        </message>
-        <message>
-            <source>SMESH_DEFLECTION1D_HYPOTHESIS</source>
-            <translation>Deflection 1D</translation>
-        </message>
-        <message>
-            <source>SMESH_DEFLECTION1D_PARAM</source>
-            <translation>Deflection</translation>
-        </message>
-        <message>
-            <source>SMESH_DEFLECTION1D_TITLE</source>
-            <translation>Hypothesis Construction</translation>
-        </message>
-        <message>
-            <source>SMESH_DENSITY_FUNC</source>
-            <translation>Density function</translation>
-        </message>
-        <message>
-            <source>SMESH_DISTR</source>
-            <translation>Distribution</translation>
-        </message>
-        <message>
-            <source>SMESH_DISTR_EXPR</source>
-            <translation>Distribution with analitic density</translation>
-        </message>
-        <message>
-            <source>SMESH_DISTR_REGULAR</source>
-            <translation>Equidistant distribution</translation>
-        </message>
-        <message>
-            <source>SMESH_DISTR_SCALE</source>
-            <translation>Scale distribution</translation>
-        </message>
-        <message>
-            <source>SMESH_DISTR_TAB</source>
-            <translation>Distribution with table density</translation>
-        </message>
-        <message>
-            <source>SMESH_DISTR_TYPE</source>
-            <translation>Type of distribution</translation>
-        </message>
-        <message>
-            <source>SMESH_END_LENGTH_PARAM</source>
-            <translation>End Length</translation>
-        </message>
-        <message>
-            <source>SMESH_EXPR_FUNC</source>
-            <translation>Density function f(t) = </translation>
-        </message>
-        <message>
-            <source>SMESH_EXP_MODE</source>
-            <translation>Exponent</translation>
-        </message>
-        <message>
-            <source>SMESH_FINENESS_PARAM</source>
-            <translation>Fineness</translation>
-        </message>
-        <message>
-            <source>SMESH_FUNC_DOMAIN</source>
-            <translation>Warning: function must be defined on segment [0..1]</translation>
-        </message>
-        <message>
-            <source>SMESH_INSERT_ROW</source>
-            <translation>Insert row</translation>
-        </message>
-        <message>
-            <source>SMESH_INVALID_FUNCTION</source>
-            <translation>Function is invalid</translation>
-        </message>
-        <message>
-            <source>SMESH_LAYERS_DISTRIBUTION</source>
-            <translation>1D Hypothesis</translation>
-        </message>
-        <message>
-            <source>SMESH_LAYER_DISTRIBUTION_HYPOTHESIS</source>
-            <translation>Distribution of Layers</translation>
-        </message>
-        <message>
-            <source>SMESH_LAYER_DISTRIBUTION_TITLE</source>
-            <translation>Hypothesis Construction</translation>
-        </message>
-        <message>
-            <source>SMESH_LOCAL_LENGTH_HYPOTHESIS</source>
-            <translation>Average Length</translation>
-        </message>
-        <message>
-            <source>SMESH_LOCAL_LENGTH_PARAM</source>
-            <translation>Length</translation>
-        </message>
-        <message>
-            <source>SMESH_LOCAL_LENGTH_PRECISION</source>
-            <translation>Precision</translation>
-        </message>
-        <message>
-            <source>SMESH_LOCAL_LENGTH_TITLE</source>
-            <translation>Hypothesis Construction</translation>
-        </message>
-        <message>
-            <source>SMESH_MAX_LENGTH_HYPOTHESIS</source>
-            <translation>Max Length</translation>
-        </message>
-        <message>
-            <source>SMESH_USE_PREESTIMATED_LENGTH</source>
-            <translation>Use preestimated length</translation>
-        </message>
-        <message>
-            <source>SMESH_MAX_LENGTH_TITLE</source>
-            <translation>Hypothesis Construction</translation>
-        </message>
-        <message>
-            <source>SMESH_MAX_ELEMENT_AREA_HYPOTHESIS</source>
-            <translation>Max. Element Area</translation>
-        </message>
-        <message>
-            <source>SMESH_MAX_ELEMENT_AREA_PARAM</source>
-            <translation>Max. Area</translation>
-        </message>
-        <message>
-            <source>SMESH_MAX_ELEMENT_AREA_TITLE</source>
-            <translation>Hypothesis Construction</translation>
-        </message>
-        <message>
-            <source>SMESH_MAX_ELEMENT_VOLUME_HYPOTHESIS</source>
-            <translation>Max. Element Volume</translation>
-        </message>
-        <message>
-            <source>SMESH_MAX_ELEMENT_VOLUME_PARAM</source>
-            <translation>Max. Volume</translation>
-        </message>
-        <message>
-            <source>SMESH_MAX_ELEMENT_VOLUME_TITLE</source>
-            <translation>Hypothesis Construction</translation>
-        </message>
-        <message>
-            <source>SMESH_NB_SEGMENTS_HYPOTHESIS</source>
-            <translation>Number of Segments</translation>
-        </message>
-        <message>
-            <source>SMESH_NB_SEGMENTS_PARAM</source>
-            <translation>Number of Segments</translation>
-        </message>
-        <message>
-            <source>SMESH_NB_SEGMENTS_SCALE_PARAM</source>
-            <translation>Scale Factor</translation>
-        </message>
-        <message>
-            <source>SMESH_NB_SEGMENTS_TITLE</source>
-            <translation>Hypothesis Construction</translation>
-        </message>
-        <message>
-            <source>SMESH_NO_CONV</source>
-            <translation>No conversion</translation>
-        </message>
-        <message>
-            <source>SMESH_NUMBER_OF_LAYERS</source>
-            <translation>Number of Layers</translation>
-        </message>
-        <message>
-            <source>SMESH_NUMBER_OF_LAYERS_HYPOTHESIS</source>
-            <translation>Radial Prism Parameter</translation>
-        </message>
-        <message>
-            <source>SMESH_NUMBER_OF_LAYERS_TITLE</source>
-            <translation>Hypothesis Construction</translation>
-        </message>
-        <message>
-            <source>SMESH_PROJECTION_SOURCE_1D_HYPOTHESIS</source>
-            <translation>Projection Source 1D</translation>
-        </message>
-        <message>
-            <source>SMESH_PROJECTION_SOURCE_1D_TITLE</source>
-            <translation>Hypothesis Construction</translation>
-        </message>
-        <message>
-            <source>SMESH_PROJECTION_SOURCE_2D_HYPOTHESIS</source>
-            <translation>Projection Source 2D</translation>
-        </message>
-        <message>
-            <source>SMESH_PROJECTION_SOURCE_2D_TITLE</source>
-            <translation>Hypothesis Construction</translation>
-        </message>
-        <message>
-            <source>SMESH_PROJECTION_SOURCE_3D_HYPOTHESIS</source>
-            <translation>Projection Source 3D</translation>
-        </message>
-        <message>
-            <source>SMESH_PROJECTION_SOURCE_3D_TITLE</source>
-            <translation>Hypothesis Construction</translation>
-        </message>
-        <message>
-            <source>SMESH_REMOVE_ROW</source>
-            <translation>Remove row</translation>
-        </message>
-        <message>
-            <source>SMESH_SEGMENT_LENGTH_AROUND_VERTEX_HYPOTHESIS</source>
-            <translation>Segment Length Around Vertex</translation>
-        </message>
-        <message>
-            <source>SMESH_SEGMENT_LENGTH_AROUND_VERTEX_PARAM</source>
-            <translation>Length</translation>
-        </message>
-        <message>
-            <source>SMESH_SEGMENT_LENGTH_AROUND_VERTEX_TITLE</source>
-            <translation>Hypothesis Construction</translation>
-        </message>
-        <message>
-            <source>SMESH_SOURCE_3DSHAPE</source>
-            <translation>3D shape</translation>
-        </message>
-        <message>
-            <source>SMESH_SOURCE_EDGE</source>
-            <translation>Edge</translation>
-        </message>
-        <message>
-            <source>SMESH_SOURCE_FACE</source>
-            <translation>Face</translation>
-        </message>
-        <message>
-            <source>SMESH_SOURCE_MESH</source>
-            <translation>Mesh</translation>
-        </message>
-        <message>
-            <source>SMESH_SOURCE_VERTEX</source>
-            <translation>Source Vertex</translation>
-        </message>
-        <message>
-            <source>SMESH_SOURCE_VERTEX1</source>
-            <translation>Source Vertex 1</translation>
-        </message>
-        <message>
-            <source>SMESH_SOURCE_VERTEX2</source>
-            <translation>Source Vertex 2</translation>
-        </message>
-        <message>
-            <source>SMESH_START_END_LENGTH_HYPOTHESIS</source>
-            <translation>Start and End local Length</translation>
-        </message>
-        <message>
-            <source>SMESH_START_END_LENGTH_TITLE</source>
-            <translation>Hypothesis Construction</translation>
-        </message>
-        <message>
-            <source>SMESH_START_LENGTH_PARAM</source>
-            <translation>Start Length</translation>
-        </message>
-        <message>
-            <source>SMESH_TAB_FUNC</source>
-            <translation>Table function</translation>
-        </message>
-        <message>
-            <source>SMESH_TARGET_VERTEX</source>
-            <translation>Target Vertex</translation>
-        </message>
-        <message>
-            <source>SMESH_TARGET_VERTEX1</source>
-            <translation>Target Vertex 1</translation>
-        </message>
-        <message>
-            <source>SMESH_TARGET_VERTEX2</source>
-            <translation>Target Vertex 2</translation>
-        </message>
-    </context>
-    <context>
-        <name>StdMeshersGUI_LayerDistributionParamWdg</name>
-        <message>
-            <source>CHANGE_TYPE</source>
-            <translation>Change Type</translation>
-        </message>
-        <message>
-            <source>CREATE</source>
-            <translation>Create</translation>
-        </message>
-        <message>
-            <source>EDIT</source>
-            <translation>Edit</translation>
-        </message>
-    </context>
+<TS version="2.0" language="en_US">
+<context>
+    <name>@default</name>
+    <message>
+        <source>SMESH_ARITHMETIC_1D_HYPOTHESIS</source>
+        <translation>Arithmetic 1D</translation>
+    </message>
+    <message>
+        <source>SMESH_ARITHMETIC_1D_PARAM</source>
+        <translation>Arithmetic Reason</translation>
+    </message>
+    <message>
+        <source>SMESH_ARITHMETIC_1D_TITLE</source>
+        <translation>Hypothesis Construction</translation>
+    </message>
+    <message>
+        <source>SMESH_AUTOMATIC_LENGTH_HYPOTHESIS</source>
+        <translation>Automatic Length</translation>
+    </message>
+    <message>
+        <source>SMESH_AUTOMATIC_LENGTH_TITLE</source>
+        <translation>Hypothesis Construction</translation>
+    </message>
+    <message>
+        <source>SMESH_CONV_MODE</source>
+        <translation>Conversion mode </translation>
+    </message>
+    <message>
+        <source>SMESH_CUT_NEG_MODE</source>
+        <translation>Cut negative</translation>
+    </message>
+    <message>
+        <source>SMESH_DEFLECTION1D_HYPOTHESIS</source>
+        <translation>Deflection 1D</translation>
+    </message>
+    <message>
+        <source>SMESH_DEFLECTION1D_PARAM</source>
+        <translation>Deflection</translation>
+    </message>
+    <message>
+        <source>SMESH_DEFLECTION1D_TITLE</source>
+        <translation>Hypothesis Construction</translation>
+    </message>
+    <message>
+        <source>SMESH_DENSITY_FUNC</source>
+        <translation>Density function</translation>
+    </message>
+    <message>
+        <source>SMESH_DISTR</source>
+        <translation>Distribution</translation>
+    </message>
+    <message>
+        <source>SMESH_DISTR_EXPR</source>
+        <translation>Distribution with analitic density</translation>
+    </message>
+    <message>
+        <source>SMESH_DISTR_REGULAR</source>
+        <translation>Equidistant distribution</translation>
+    </message>
+    <message>
+        <source>SMESH_DISTR_SCALE</source>
+        <translation>Scale distribution</translation>
+    </message>
+    <message>
+        <source>SMESH_DISTR_TAB</source>
+        <translation>Distribution with table density</translation>
+    </message>
+    <message>
+        <source>SMESH_DISTR_TYPE</source>
+        <translation>Type of distribution</translation>
+    </message>
+    <message>
+        <source>SMESH_END_LENGTH_PARAM</source>
+        <translation>End Length</translation>
+    </message>
+    <message>
+        <source>SMESH_EXPR_FUNC</source>
+        <translation>Density function</translation>
+    </message>
+    <message>
+        <source>SMESH_EXP_MODE</source>
+        <translation>Exponent</translation>
+    </message>
+    <message>
+        <source>SMESH_FINENESS_PARAM</source>
+        <translation>Fineness</translation>
+    </message>
+    <message>
+        <source>SMESH_FUNC_DOMAIN</source>
+        <translation>Warning: function must be defined on segment [0..1]</translation>
+    </message>
+    <message>
+        <source>SMESH_INSERT_ROW</source>
+        <translation>Insert row</translation>
+    </message>
+    <message>
+        <source>SMESH_INVALID_FUNCTION</source>
+        <translation>Function is invalid</translation>
+    </message>
+    <message>
+        <source>SMESH_LAYERS_DISTRIBUTION</source>
+        <translation>1D Hypothesis</translation>
+    </message>
+    <message>
+        <source>SMESH_LAYER_DISTRIBUTION_HYPOTHESIS</source>
+        <translation>Distribution of Layers</translation>
+    </message>
+    <message>
+        <source>SMESH_LAYER_DISTRIBUTION_TITLE</source>
+        <translation>Hypothesis Construction</translation>
+    </message>
+    <message>
+        <source>SMESH_LOCAL_LENGTH_HYPOTHESIS</source>
+        <translation>Local Length</translation>
+    </message>
+    <message>
+        <source>SMESH_LOCAL_LENGTH_PARAM</source>
+        <translation>Length</translation>
+    </message>
+    <message>
+        <source>SMESH_LOCAL_LENGTH_PRECISION</source>
+        <translation>Precision</translation>
+    </message>
+    <message>
+        <source>SMESH_LOCAL_LENGTH_TITLE</source>
+        <translation>Hypothesis Construction</translation>
+    </message>
+    <message>
+        <source>SMESH_FIXED_POINTS_1D_HYPOTHESIS</source>
+        <translation>Fixed points 1D</translation>
+    </message>
+    <message>
+        <source>SMESH_FIXED_POINTS_1D_TITLE</source>
+        <translation>Hypothesis Construction</translation>
+    </message>
+    <message>
+        <source>SMESH_MAX_LENGTH_HYPOTHESIS</source>
+        <translation>Max Length</translation>
+    </message>
+    <message>
+        <source>SMESH_CARTESIAN_PARAMS_HYPOTHESIS</source>
+        <translation>Body Fitting Parameters</translation>
+    </message>
+    <message>
+        <source>SMESH_USE_PREESTIMATED_LENGTH</source>
+        <translation>Use preestimated length</translation>
+    </message>
+    <message>
+        <source>SMESH_VISCOUS_LAYERS_HYPOTHESIS</source>
+        <translation>Viscous Layers</translation>
+    </message>
+    <message>
+        <source>SMESH_VISCOUS_LAYERS_TITLE</source>
+        <translation>Hypothesis Construction</translation>
+    </message>
+    <message>
+        <source>SMESH_TOTAL_THICKNESS</source>
+        <translation>Total thickness</translation>
+    </message>
+    <message>
+        <source>SMESH_STRETCH_FACTOR</source>
+        <translation>Stretch factor</translation>
+    </message>
+    <message>
+        <source>SMESH_FACES_WO_LAYERS</source>
+        <translation>Faces without layers
+(inlets and oulets)</translation>
+    </message>
+    <message>
+        <source>SMESH_MAX_LENGTH_TITLE</source>
+        <translation>Hypothesis Construction</translation>
+    </message>
+    <message>
+        <source>SMESH_CARTESIAN_PARAMS_TITLE</source>
+        <translation>Hypothesis Construction</translation>
+    </message>
+    <message>
+        <source>SMESH_MAX_ELEMENT_AREA_HYPOTHESIS</source>
+        <translation>Max. Element Area</translation>
+    </message>
+    <message>
+        <source>SMESH_MAX_ELEMENT_AREA_PARAM</source>
+        <translation>Max. Area</translation>
+    </message>
+    <message>
+        <source>SMESH_MAX_ELEMENT_AREA_TITLE</source>
+        <translation>Hypothesis Construction</translation>
+    </message>
+    <message>
+        <source>SMESH_MAX_ELEMENT_VOLUME_HYPOTHESIS</source>
+        <translation>Max. Element Volume</translation>
+    </message>
+    <message>
+        <source>SMESH_MAX_ELEMENT_VOLUME_PARAM</source>
+        <translation>Max. Volume</translation>
+    </message>
+    <message>
+        <source>SMESH_MAX_ELEMENT_VOLUME_TITLE</source>
+        <translation>Hypothesis Construction</translation>
+    </message>
+    <message>
+        <source>SMESH_NB_SEGMENTS_HYPOTHESIS</source>
+        <translation>Number of Segments</translation>
+    </message>
+    <message>
+        <source>SMESH_NB_SEGMENTS_PARAM</source>
+        <translation>Number of Segments</translation>
+    </message>
+    <message>
+        <source>SMESH_NB_SEGMENTS_SCALE_PARAM</source>
+        <translation>Scale Factor</translation>
+    </message>
+    <message>
+        <source>SMESH_NB_SEGMENTS_TITLE</source>
+        <translation>Hypothesis Construction</translation>
+    </message>
+    <message>
+        <source>SMESH_NO_CONV</source>
+        <translation>No conversion</translation>
+    </message>
+    <message>
+        <source>SMESH_NUMBER_OF_LAYERS</source>
+        <translation>Number of layers</translation>
+    </message>
+    <message>
+        <source>SMESH_NUMBER_OF_LAYERS_HYPOTHESIS</source>
+        <translation>Radial Prism Parameter</translation>
+    </message>
+    <message>
+        <source>SMESH_NUMBER_OF_LAYERS_2D_HYPOTHESIS</source>
+        <translation>Radial Quadrangle Parameter</translation>
+    </message>
+    <message>
+        <source>SMESH_NUMBER_OF_LAYERS_TITLE</source>
+        <translation>Hypothesis Construction</translation>
+    </message>
+    <message>
+        <source>SMESH_NUMBER_OF_LAYERS_2D_TITLE</source>
+        <translation>Hypothesis Construction</translation>
+    </message>
+    <message>
+        <source>SMESH_PROJECTION_SOURCE_1D_HYPOTHESIS</source>
+        <translation>Projection Source 1D</translation>
+    </message>
+    <message>
+        <source>SMESH_PROJECTION_SOURCE_1D_TITLE</source>
+        <translation>Hypothesis Construction</translation>
+    </message>
+    <message>
+        <source>SMESH_PROJECTION_SOURCE_2D_HYPOTHESIS</source>
+        <translation>Projection Source 2D</translation>
+    </message>
+    <message>
+        <source>SMESH_PROJECTION_SOURCE_2D_TITLE</source>
+        <translation>Hypothesis Construction</translation>
+    </message>
+    <message>
+        <source>SMESH_PROJECTION_SOURCE_3D_HYPOTHESIS</source>
+        <translation>Projection Source 3D</translation>
+    </message>
+    <message>
+        <source>SMESH_PROJECTION_SOURCE_3D_TITLE</source>
+        <translation>Hypothesis Construction</translation>
+    </message>
+    <message>
+        <source>SMESH_IMPORT_SOURCE_1D_HYPOTHESIS</source>
+        <translation>Source edges</translation>
+    </message>
+    <message>
+        <source>SMESH_IMPORT_SOURCE_1D_TITLE</source>
+        <translation>Hypothesis Construction</translation>
+    </message>
+    <message>
+        <source>SMESH_IMPORT_SOURCE_2D_HYPOTHESIS</source>
+        <translation>Source faces</translation>
+    </message>
+    <message>
+        <source>SMESH_IMPORT_SOURCE_2D_TITLE</source>
+        <translation>Hypothesis Construction</translation>
+    </message>
+    <message>
+        <source>SMESH_REMOVE_ROW</source>
+        <translation>Remove row</translation>
+    </message>
+    <message>
+        <source>SMESH_REVERSED_EDGES</source>
+        <translation>Reversed Edges</translation>
+    </message>
+    <message>
+        <source>SMESH_FIXED_POINTS</source>
+        <translation>Fixed Points</translation>
+    </message>
+    <message>
+        <source>SMESH_RANGE</source>
+        <translation>Range</translation>
+    </message>
+    <message>
+        <source>SMESH_NB_SEGMENTS</source>
+        <translation>Nb. Segments</translation>
+    </message>
+    <message>
+        <source>SMESH_SAME_NB_SEGMENTS</source>
+        <translation>Same Nb. Segments for All Intervals</translation>
+    </message>
+    <message>
+        <source>SMESH_BASE_VERTEX</source>
+        <translation>Base vertex</translation>
+    </message>
+    <message>
+        <source>SMESH_SEGMENT_LENGTH_AROUND_VERTEX_HYPOTHESIS</source>
+        <translation>Segment Length Around Vertex</translation>
+    </message>
+    <message>
+        <source>SMESH_SEGMENT_LENGTH_AROUND_VERTEX_PARAM</source>
+        <translation>Length</translation>
+    </message>
+    <message>
+        <source>SMESH_SEGMENT_LENGTH_AROUND_VERTEX_TITLE</source>
+        <translation>Hypothesis Construction</translation>
+    </message>
+    <message>
+        <source>SMESH_SOURCE_3DSHAPE</source>
+        <translation>Source 3D shape</translation>
+    </message>
+    <message>
+        <source>SMESH_SOURCE_EDGE</source>
+        <translation>Source Edge</translation>
+    </message>
+    <message>
+        <source>SMESH_SOURCE_EDGES</source>
+        <translation>Groups of Edges</translation>
+    </message>
+    <message>
+        <source>SMESH_SOURCE_FACE</source>
+        <translation>Source Face</translation>
+    </message>
+    <message>
+        <source>SMESH_SOURCE_FACES</source>
+        <translation>Groups of Faces</translation>
+    </message>
+    <message>
+        <source>SMESH_SOURCE_MESH</source>
+        <translation>Source Mesh</translation>
+    </message>
+    <message>
+        <source>SMESH_COPY_MESH</source>
+        <translation>To copy mesh</translation>
+    </message>
+    <message>
+        <source>SMESH_TO_COPY_GROUPS</source>
+        <translation>To copy groups</translation>
+    </message>
+    <message>
+        <source>SMESH_SOURCE_VERTEX</source>
+        <translation>Source Vertex</translation>
+    </message>
+    <message>
+        <source>SMESH_SOURCE_VERTEX1</source>
+        <translation>Source Vertex 1</translation>
+    </message>
+    <message>
+        <source>SMESH_SOURCE_VERTEX2</source>
+        <translation>Source Vertex 2</translation>
+    </message>
+    <message>
+        <source>SMESH_START_END_LENGTH_HYPOTHESIS</source>
+        <translation>Start and End local Length</translation>
+    </message>
+    <message>
+        <source>SMESH_START_END_LENGTH_TITLE</source>
+        <translation>Hypothesis Construction</translation>
+    </message>
+    <message>
+        <source>SMESH_START_LENGTH_PARAM</source>
+        <translation>Start Length</translation>
+    </message>
+    <message>
+        <source>SMESH_TAB_FUNC</source>
+        <translation>Table function</translation>
+    </message>
+    <message>
+        <source>SMESH_TARGET_VERTEX</source>
+        <translation>Target Vertex</translation>
+    </message>
+    <message>
+        <source>SMESH_TARGET_VERTEX1</source>
+        <translation>Target Vertex 1</translation>
+    </message>
+    <message>
+        <source>SMESH_TARGET_VERTEX2</source>
+        <translation>Target Vertex 2</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRANGLE_PARAMS_HYPOTHESIS</source>
+        <translation>Quadrangle parameters</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRANGLE_PARAMS_TITLE</source>
+        <translation>Hypothesis Construction</translation>
+    </message>
+    <message>
+        <source>SMESH_QUAD_TYPE</source>
+        <translation>Type</translation>
+    </message>
+</context>
+<context>
+    <name>StdMeshersGUI_QuadrangleParamWdg</name>
+    <message>
+        <source>SMESH_QUAD_TYPE_0</source>
+        <translation>Standard</translation>
+    </message>
+    <message>
+        <source>SMESH_QUAD_TYPE_1</source>
+        <translation>Triangle preference</translation>
+    </message>
+    <message>
+        <source>SMESH_QUAD_TYPE_2</source>
+        <translation>Quadrangle preference</translation>
+    </message>
+    <message>
+        <source>SMESH_QUAD_TYPE_3</source>
+        <translation>Quadrangle preference (reversed)</translation>
+    </message>
+    <message>
+        <source>SMESH_QUAD_TYPE_4</source>
+        <translation>Reduced</translation>
+    </message>
+</context>
+<context>
+    <name>StdMeshersGUI_LayerDistributionParamWdg</name>
+    <message>
+        <source>CHANGE_TYPE</source>
+        <translation>Change Type</translation>
+    </message>
+    <message>
+        <source>CREATE</source>
+        <translation>Create</translation>
+    </message>
+    <message>
+        <source>EDIT</source>
+        <translation>Edit</translation>
+    </message>
+</context>
+<context>
+    <name>StdMeshersGUI_CartesianParamCreator</name>
+    <message>
+        <source>THRESHOLD</source>
+        <translation>Threshold</translation>
+    </message>
+    <message>
+        <source>AXIS_X</source>
+        <translation>Axis X</translation>
+    </message>
+    <message>
+        <source>AXIS_Y</source>
+        <translation>Axis Y</translation>
+    </message>
+    <message>
+        <source>AXIS_Z</source>
+        <translation>Axis Z</translation>
+    </message>
+</context>
+<context>
+    <name>StdMeshersGUI::GridAxisTab</name>
+    <message>
+        <source>GRID_DEF_MODE</source>
+        <translation>Definition mode</translation>
+    </message>
+    <message>
+        <source>SPACING</source>
+        <translation>Spacing</translation>
+    </message>
+    <message>
+        <source>INSERT</source>
+        <translation>Insert</translation>
+    </message>
+    <message>
+        <source>COORD_STEP</source>
+        <translation>Step</translation>
+    </message>
+</context>
 </TS>
diff --git a/src/StdMeshersGUI/StdMeshers_msg_fr.ts b/src/StdMeshersGUI/StdMeshers_msg_fr.ts
new file mode 100755 (executable)
index 0000000..836a9fb
--- /dev/null
@@ -0,0 +1,484 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="fr_FR">
+<context>
+    <name>@default</name>
+    <message>
+        <source>SMESH_ARITHMETIC_1D_HYPOTHESIS</source>
+        <translation>Arithmétique 1D</translation>
+    </message>
+    <message>
+        <source>SMESH_ARITHMETIC_1D_PARAM</source>
+        <translation>Raison arithmétique</translation>
+    </message>
+    <message>
+        <source>SMESH_ARITHMETIC_1D_TITLE</source>
+        <translation>Construction de l&apos;hypothèse</translation>
+    </message>
+    <message>
+        <source>SMESH_AUTOMATIC_LENGTH_HYPOTHESIS</source>
+        <translation>Longueur automatique</translation>
+    </message>
+    <message>
+        <source>SMESH_AUTOMATIC_LENGTH_TITLE</source>
+        <translation>Construction de l&apos;hypothèse</translation>
+    </message>
+    <message>
+        <source>SMESH_CONV_MODE</source>
+        <translation>Mode de conversion</translation>
+    </message>
+    <message>
+        <source>SMESH_CUT_NEG_MODE</source>
+        <translation>Section négative</translation>
+    </message>
+    <message>
+        <source>SMESH_DEFLECTION1D_HYPOTHESIS</source>
+        <translation>Déflection 1D</translation>
+    </message>
+    <message>
+        <source>SMESH_DEFLECTION1D_PARAM</source>
+        <translation>Déflection</translation>
+    </message>
+    <message>
+        <source>SMESH_DEFLECTION1D_TITLE</source>
+        <translation>Construction de l&apos;hypothèse</translation>
+    </message>
+    <message>
+        <source>SMESH_DENSITY_FUNC</source>
+        <translation>Fonction de densité </translation>
+    </message>
+    <message>
+        <source>SMESH_DISTR</source>
+        <translation>Distribution</translation>
+    </message>
+    <message>
+        <source>SMESH_DISTR_EXPR</source>
+        <translation>Distribution de densité analytique</translation>
+    </message>
+    <message>
+        <source>SMESH_DISTR_REGULAR</source>
+        <translation>Distribution Ã©quidistante</translation>
+    </message>
+    <message>
+        <source>SMESH_DISTR_SCALE</source>
+        <translation>Progression géométrique</translation>
+    </message>
+    <message>
+        <source>SMESH_DISTR_TAB</source>
+        <translation>Table de densités</translation>
+    </message>
+    <message>
+        <source>SMESH_DISTR_TYPE</source>
+        <translation>Type de distribution</translation>
+    </message>
+    <message>
+        <source>SMESH_END_LENGTH_PARAM</source>
+        <translation>Longueur finale</translation>
+    </message>
+    <message>
+        <source>SMESH_EXPR_FUNC</source>
+        <translation>Expression de la densité</translation>
+    </message>
+    <message>
+        <source>SMESH_EXP_MODE</source>
+        <translation>Exposant</translation>
+    </message>
+    <message>
+        <source>SMESH_FINENESS_PARAM</source>
+        <translation>Finesse</translation>
+    </message>
+    <message>
+        <source>SMESH_FUNC_DOMAIN</source>
+        <translation>Avertissement: La fonction doit Ãªtre définie sur le segment [0..1]</translation>
+    </message>
+    <message>
+        <source>SMESH_INSERT_ROW</source>
+        <translation>Insérer une ligne</translation>
+    </message>
+    <message>
+        <source>SMESH_INVALID_FUNCTION</source>
+        <translation>La fonction n&apos;est pas valide</translation>
+    </message>
+    <message>
+        <source>SMESH_LAYERS_DISTRIBUTION</source>
+        <translation>Hypothèse 1D </translation>
+    </message>
+    <message>
+        <source>SMESH_LAYER_DISTRIBUTION_HYPOTHESIS</source>
+        <translation>Distribution des couches</translation>
+    </message>
+    <message>
+        <source>SMESH_LAYER_DISTRIBUTION_TITLE</source>
+        <translation>Construction de l&apos;hypothèse</translation>
+    </message>
+    <message>
+        <source>SMESH_LOCAL_LENGTH_HYPOTHESIS</source>
+        <translation>Longueur moyenne</translation>
+    </message>
+    <message>
+        <source>SMESH_LOCAL_LENGTH_PARAM</source>
+        <translation>Longueur</translation>
+    </message>
+    <message>
+        <source>SMESH_LOCAL_LENGTH_PRECISION</source>
+        <translation>Précision</translation>
+    </message>
+    <message>
+        <source>SMESH_LOCAL_LENGTH_TITLE</source>
+        <translation>Construction de l&apos;hypothèse</translation>
+    </message>
+    <message>
+        <source>SMESH_FIXED_POINTS_1D_HYPOTHESIS</source>
+        <translation>Points fixes 1D</translation>
+    </message>
+    <message>
+        <source>SMESH_FIXED_POINTS_1D_TITLE</source>
+        <translation>Construction de l&apos;hypothèse</translation>
+    </message>
+    <message>
+        <source>SMESH_MAX_LENGTH_HYPOTHESIS</source>
+        <translation>Longueur maximale</translation>
+    </message>
+    <message>
+        <source>SMESH_CARTESIAN_PARAMS_HYPOTHESIS</source>
+        <translation>Paramètres de Body Fitting</translation>
+    </message>
+    <message>
+        <source>SMESH_USE_PREESTIMATED_LENGTH</source>
+        <translation>Utiliser la longueur pré-estimée</translation>
+    </message>
+    <message>
+        <source>SMESH_VISCOUS_LAYERS_HYPOTHESIS</source>
+        <translation>Couches limites</translation>
+    </message>
+    <message>
+        <source>SMESH_VISCOUS_LAYERS_TITLE</source>
+        <translation>Construction de l&apos;hypothèse</translation>
+    </message>
+    <message>
+        <source>SMESH_TOTAL_THICKNESS</source>
+        <translation>Epaisseur totale</translation>
+    </message>
+    <message>
+        <source>SMESH_STRETCH_FACTOR</source>
+        <translation>Facteur d&apos;échelle</translation>
+    </message>
+    <message>
+        <source>SMESH_FACES_WO_LAYERS</source>
+        <translation>Faces sans couche limite
+(entrées et sorties)</translation>
+    </message>
+    <message>
+        <source>SMESH_MAX_LENGTH_TITLE</source>
+        <translation>Construction de l&apos;hypothèse</translation>
+    </message>
+    <message>
+        <source>SMESH_CARTESIAN_PARAMS_TITLE</source>
+        <translation>Construction de l&apos;hypothèse</translation>
+    </message>
+    <message>
+        <source>SMESH_MAX_ELEMENT_AREA_HYPOTHESIS</source>
+        <translation>Aire maximale d&apos;une maille</translation>
+    </message>
+    <message>
+        <source>SMESH_MAX_ELEMENT_AREA_PARAM</source>
+        <translation>Aire maximale</translation>
+    </message>
+    <message>
+        <source>SMESH_MAX_ELEMENT_AREA_TITLE</source>
+        <translation>Construction de l&apos;hypothèse</translation>
+    </message>
+    <message>
+        <source>SMESH_MAX_ELEMENT_VOLUME_HYPOTHESIS</source>
+        <translation>Volume maximal d&apos;une maille</translation>
+    </message>
+    <message>
+        <source>SMESH_MAX_ELEMENT_VOLUME_PARAM</source>
+        <translation>Volume maximal</translation>
+    </message>
+    <message>
+        <source>SMESH_MAX_ELEMENT_VOLUME_TITLE</source>
+        <translation>Construction de l&apos;hypothèse</translation>
+    </message>
+    <message>
+        <source>SMESH_NB_SEGMENTS_HYPOTHESIS</source>
+        <translation>Nombre de segments</translation>
+    </message>
+    <message>
+        <source>SMESH_NB_SEGMENTS_PARAM</source>
+        <translation>Nombre de segments</translation>
+    </message>
+    <message>
+        <source>SMESH_NB_SEGMENTS_SCALE_PARAM</source>
+        <translation>Facteur d&apos;échelle</translation>
+    </message>
+    <message>
+        <source>SMESH_NB_SEGMENTS_TITLE</source>
+        <translation>Construction de l&apos;hypothèse</translation>
+    </message>
+    <message>
+        <source>SMESH_NO_CONV</source>
+        <translation>Sans conversion</translation>
+    </message>
+    <message>
+        <source>SMESH_NUMBER_OF_LAYERS</source>
+        <translation>Nombre de couches</translation>
+    </message>
+    <message>
+        <source>SMESH_NUMBER_OF_LAYERS_HYPOTHESIS</source>
+        <translation>Paramètre des prismes radiaux</translation>
+    </message>
+    <message>
+        <source>SMESH_NUMBER_OF_LAYERS_2D_HYPOTHESIS</source>
+        <translation>Paramètre des quadrangles radiaux</translation>
+    </message>
+    <message>
+        <source>SMESH_NUMBER_OF_LAYERS_TITLE</source>
+        <translation>Construction de l&apos;hypothèse</translation>
+    </message>
+    <message>
+        <source>SMESH_NUMBER_OF_LAYERS_2D_TITLE</source>
+        <translation>Construction de l&apos;hypothèse</translation>
+    </message>
+    <message>
+        <source>SMESH_PROJECTION_SOURCE_1D_HYPOTHESIS</source>
+        <translation>Source pour le projection 1D</translation>
+    </message>
+    <message>
+        <source>SMESH_PROJECTION_SOURCE_1D_TITLE</source>
+        <translation>Construction de l&apos;hypothèse</translation>
+    </message>
+    <message>
+        <source>SMESH_PROJECTION_SOURCE_2D_HYPOTHESIS</source>
+        <translation>Source pour la projection 2D</translation>
+    </message>
+    <message>
+        <source>SMESH_PROJECTION_SOURCE_2D_TITLE</source>
+        <translation>Construction de l&apos;hypothèse</translation>
+    </message>
+    <message>
+        <source>SMESH_PROJECTION_SOURCE_3D_HYPOTHESIS</source>
+        <translation>Source pour la projection 3D</translation>
+    </message>
+    <message>
+        <source>SMESH_PROJECTION_SOURCE_3D_TITLE</source>
+        <translation>Construction de l&apos;hypothèse</translation>
+    </message>
+    <message>
+        <source>SMESH_IMPORT_SOURCE_1D_HYPOTHESIS</source>
+        <translation>Arêtes source</translation>
+    </message>
+    <message>
+        <source>SMESH_IMPORT_SOURCE_1D_TITLE</source>
+        <translation>Construction de l&apos;hypothèse</translation>
+    </message>
+    <message>
+        <source>SMESH_IMPORT_SOURCE_2D_HYPOTHESIS</source>
+        <translation>Faces sources</translation>
+    </message>
+    <message>
+        <source>SMESH_IMPORT_SOURCE_2D_TITLE</source>
+        <translation>Construction de l&apos;hypothèse</translation>
+    </message>
+    <message>
+        <source>SMESH_REMOVE_ROW</source>
+        <translation>Supprimer une ligne</translation>
+    </message>
+    <message>
+        <source>SMESH_REVERSED_EDGES</source>
+        <translation>Arêtes inversées</translation>
+    </message>
+    <message>
+        <source>SMESH_FIXED_POINTS</source>
+        <translation>Points fixés</translation>
+    </message>
+    <message>
+        <source>SMESH_RANGE</source>
+        <translation>Intervalle</translation>
+    </message>
+    <message>
+        <source>SMESH_NB_SEGMENTS</source>
+        <translation>Nb. segments</translation>
+    </message>
+    <message>
+        <source>SMESH_SAME_NB_SEGMENTS</source>
+        <translation>Le même Nb. segments dans chaque intervalle</translation>
+    </message>
+    <message>
+        <source>SMESH_BASE_VERTEX</source>
+        <translation>Point de base</translation>
+    </message>
+    <message>
+        <source>SMESH_SEGMENT_LENGTH_AROUND_VERTEX_HYPOTHESIS</source>
+        <translation>Longueur des segments autour d&apos;un point</translation>
+    </message>
+    <message>
+        <source>SMESH_SEGMENT_LENGTH_AROUND_VERTEX_PARAM</source>
+        <translation>Longueur</translation>
+    </message>
+    <message>
+        <source>SMESH_SEGMENT_LENGTH_AROUND_VERTEX_TITLE</source>
+        <translation>Construction de l&apos;hypothèse</translation>
+    </message>
+    <message>
+        <source>SMESH_SOURCE_3DSHAPE</source>
+        <translation>Objet 3D</translation>
+    </message>
+    <message>
+        <source>SMESH_SOURCE_EDGE</source>
+        <translation>Arête</translation>
+    </message>
+    <message>
+        <source>SMESH_SOURCE_EDGES</source>
+        <translation>Groupes d&apos;arêtes</translation>
+    </message>
+    <message>
+        <source>SMESH_SOURCE_FACE</source>
+        <translation>Face</translation>
+    </message>
+    <message>
+        <source>SMESH_SOURCE_FACES</source>
+        <translation>Groupes de faces</translation>
+    </message>
+    <message>
+        <source>SMESH_SOURCE_MESH</source>
+        <translation>Maillage</translation>
+    </message>
+    <message>
+        <source>SMESH_COPY_MESH</source>
+        <translation>Copier le maillage</translation>
+    </message>
+    <message>
+        <source>SMESH_TO_COPY_GROUPS</source>
+        <translation>Copier les groupes</translation>
+    </message>
+    <message>
+        <source>SMESH_SOURCE_VERTEX</source>
+        <translation>Point source</translation>
+    </message>
+    <message>
+        <source>SMESH_SOURCE_VERTEX1</source>
+        <translation>Point source 1</translation>
+    </message>
+    <message>
+        <source>SMESH_SOURCE_VERTEX2</source>
+        <translation>Point source 2</translation>
+    </message>
+    <message>
+        <source>SMESH_START_END_LENGTH_HYPOTHESIS</source>
+        <translation>Start and end local Length</translation>
+    </message>
+    <message>
+        <source>SMESH_START_END_LENGTH_TITLE</source>
+        <translation>Construction de l&apos;hypothèse</translation>
+    </message>
+    <message>
+        <source>SMESH_START_LENGTH_PARAM</source>
+        <translation>Longueur initiale</translation>
+    </message>
+    <message>
+        <source>SMESH_TAB_FUNC</source>
+        <translation>Table de valeurs de la fonction</translation>
+    </message>
+    <message>
+        <source>SMESH_TARGET_VERTEX</source>
+        <translation>Point cible</translation>
+    </message>
+    <message>
+        <source>SMESH_TARGET_VERTEX1</source>
+        <translation>Point cible 1</translation>
+    </message>
+    <message>
+        <source>SMESH_TARGET_VERTEX2</source>
+        <translation>Point cible 2</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRANGLE_PARAMS_HYPOTHESIS</source>
+        <translation>Paramètres pour le maillage quadrangulaire</translation>
+    </message>
+    <message>
+        <source>SMESH_QUADRANGLE_PARAMS_TITLE</source>
+        <translation>Construction de l&apos;hypothèse</translation>
+    </message>
+    <message>
+        <source>SMESH_QUAD_TYPE</source>
+        <translation>Type</translation>
+    </message>
+</context>
+<context>
+    <name>StdMeshersGUI_QuadrangleParamWdg</name>
+    <message>
+        <source>SMESH_QUAD_TYPE_0</source>
+        <translation>Standard</translation>
+    </message>
+    <message>
+        <source>SMESH_QUAD_TYPE_1</source>
+        <translation>Triangles privilégiés</translation>
+    </message>
+    <message>
+        <source>SMESH_QUAD_TYPE_2</source>
+        <translation>Quadrangles privilégiés</translation>
+    </message>
+    <message>
+        <source>SMESH_QUAD_TYPE_3</source>
+        <translation>Quadrangles privilégiés (inversé)</translation>
+    </message>
+    <message>
+        <source>SMESH_QUAD_TYPE_4</source>
+        <translation>Réduction</translation>
+    </message>
+</context>
+<context>
+    <name>StdMeshersGUI_LayerDistributionParamWdg</name>
+    <message>
+        <source>CHANGE_TYPE</source>
+        <translation>Changer le type</translation>
+    </message>
+    <message>
+        <source>CREATE</source>
+        <translation>Créer</translation>
+    </message>
+    <message>
+        <source>EDIT</source>
+        <translation>Editer</translation>
+    </message>
+</context>
+<context>
+    <name>StdMeshersGUI_CartesianParamCreator</name>
+    <message>
+        <source>THRESHOLD</source>
+        <translation>Seuil</translation>
+    </message>
+    <message>
+        <source>AXIS_X</source>
+        <translation>Axe X</translation>
+    </message>
+    <message>
+        <source>AXIS_Y</source>
+        <translation>Axe Y</translation>
+    </message>
+    <message>
+        <source>AXIS_Z</source>
+        <translation>Axe Z</translation>
+    </message>
+</context>
+<context>
+    <name>StdMeshersGUI::GridAxisTab</name>
+    <message>
+        <source>GRID_DEF_MODE</source>
+        <translation>Mode de définition</translation>
+    </message>
+    <message>
+        <source>SPACING</source>
+        <translation>Espacement</translation>
+    </message>
+    <message>
+        <source>INSERT</source>
+        <translation>Insérer</translation>
+    </message>
+    <message>
+        <source>COORD_STEP</source>
+        <translation>Pas</translation>
+    </message>
+</context>
+</TS>
index 526d71fc580129b29587b6694d470da136bf37fb..4bc901d2dfa6750e7358f1c3c6a5d9e8f6ab0f44 100644 (file)
@@ -1,30 +1,28 @@
-#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 #
-#  Copyright (C) 2003-2007  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 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.
 #
-#  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
 #
-#  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.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
+
 #  SMESH StdMeshers_I : idl implementation based on 'StdMeshersPlugin' unit's classes
 #  File   : Makefile.in
 #  Author : Julia DOROVSKIKH
 #  Modified by : Alexander BORODIN (OCN) - autotools usage
 #  Module : SMESH
-
+#
 include $(top_srcdir)/adm_local/unix/make_common_starter.am
 
 # header files 
@@ -32,6 +30,7 @@ salomeinclude_HEADERS = \
        StdMeshers_LocalLength_i.hxx \
        StdMeshers_StartEndLength_i.hxx \
        StdMeshers_Arithmetic1D_i.hxx \
+       StdMeshers_FixedPoints1D_i.hxx \
        StdMeshers_NumberOfSegments_i.hxx \
        StdMeshers_Deflection1D_i.hxx \
        StdMeshers_Propagation_i.hxx \
@@ -47,6 +46,7 @@ salomeinclude_HEADERS = \
        StdMeshers_QuadranglePreference_i.hxx \
        StdMeshers_QuadraticMesh_i.hxx \
        StdMeshers_NumberOfLayers_i.hxx \
+       StdMeshers_NumberOfLayers2D_i.hxx \
        StdMeshers_Prism_3D_i.hxx \
        StdMeshers_ProjectionSource1D_i.hxx \
        StdMeshers_ProjectionSource2D_i.hxx \
@@ -54,13 +54,22 @@ salomeinclude_HEADERS = \
        StdMeshers_Projection_1D_2D_3D_i.hxx \
        StdMeshers_ObjRefUlils.hxx \
        StdMeshers_LayerDistribution_i.hxx \
+       StdMeshers_LayerDistribution2D_i.hxx \
        StdMeshers_CompositeSegment_1D_i.hxx \
        StdMeshers_SegmentAroundVertex_0D_i.hxx \
        StdMeshers_SegmentLengthAroundVertex_i.hxx \
        StdMeshers_UseExisting_1D2D_i.hxx \
-       StdMeshers_TrianglePreference_i.hxx \
        StdMeshers_MaxLength_i.hxx \
-       SMESH_StdMeshers_I.hxx
+       StdMeshers_QuadrangleParams_i.hxx \
+       StdMeshers_RadialQuadrangle_1D2D_i.hxx \
+       SMESH_StdMeshers_I.hxx \
+       StdMeshers_ImportSource1D_i.hxx \
+       StdMeshers_ImportSource2D_i.hxx \
+       StdMeshers_Import_1D_i.hxx \
+       StdMeshers_Import_1D2D_i.hxx \
+       StdMeshers_ViscousLayers_i.hxx \
+       StdMeshers_CartesianParameters3D_i.hxx \
+       StdMeshers_Cartesian_3D_i.hxx
 
 # Libraries targets
 lib_LTLIBRARIES = libStdMeshersEngine.la
@@ -70,6 +79,7 @@ dist_libStdMeshersEngine_la_SOURCES = \
         StdMeshers_LocalLength_i.cxx \
        StdMeshers_StartEndLength_i.cxx \
        StdMeshers_Arithmetic1D_i.cxx \
+       StdMeshers_FixedPoints1D_i.cxx \
        StdMeshers_NumberOfSegments_i.cxx \
        StdMeshers_Deflection1D_i.cxx \
         StdMeshers_Propagation_i.cxx \
@@ -85,6 +95,7 @@ dist_libStdMeshersEngine_la_SOURCES = \
        StdMeshers_QuadranglePreference_i.cxx \
        StdMeshers_QuadraticMesh_i.cxx \
        StdMeshers_NumberOfLayers_i.cxx \
+       StdMeshers_NumberOfLayers2D_i.cxx \
        StdMeshers_Prism_3D_i.cxx \
        StdMeshers_ProjectionSource1D_i.cxx \
        StdMeshers_ProjectionSource2D_i.cxx \
@@ -92,12 +103,21 @@ dist_libStdMeshersEngine_la_SOURCES = \
        StdMeshers_Projection_1D_2D_3D_i.cxx \
        StdMeshers_ObjRefUlils.cxx \
        StdMeshers_LayerDistribution_i.cxx \
+       StdMeshers_LayerDistribution2D_i.cxx \
        StdMeshers_CompositeSegment_1D_i.cxx \
        StdMeshers_SegmentAroundVertex_0D_i.cxx \
        StdMeshers_SegmentLengthAroundVertex_i.cxx \
        StdMeshers_UseExisting_1D2D_i.cxx \
-       StdMeshers_TrianglePreference_i.cxx \
-       StdMeshers_MaxLength_i.cxx
+       StdMeshers_MaxLength_i.cxx \
+       StdMeshers_QuadrangleParams_i.cxx \
+       StdMeshers_RadialQuadrangle_1D2D_i.cxx \
+       StdMeshers_ImportSource1D_i.cxx \
+       StdMeshers_ImportSource2D_i.cxx \
+       StdMeshers_Import_1D_i.cxx \
+       StdMeshers_Import_1D2D_i.cxx \
+       StdMeshers_ViscousLayers_i.cxx \
+       StdMeshers_CartesianParameters3D_i.cxx \
+       StdMeshers_Cartesian_3D_i.cxx
 
 # additionnal information to compil and link file
 libStdMeshersEngine_la_CPPFLAGS = \
@@ -107,19 +127,19 @@ libStdMeshersEngine_la_CPPFLAGS = \
        $(GEOM_CXXFLAGS) \
        $(MED_CXXFLAGS) \
        $(BOOST_CPPFLAGS) \
+        $(VTK_INCLUDES) \
        $(CORBA_CXXFLAGS) \
        $(CORBA_INCLUDES) \
        -I$(srcdir)/../SMESHImpl \
        -I$(srcdir)/../MEFISTO2 \
        -I$(srcdir)/../SMESH \
+       -I$(srcdir)/../SMESHUtils \
        -I$(srcdir)/../SMESH_I \
        -I$(srcdir)/../SMESHDS \
        -I$(srcdir)/../SMDS \
        -I$(srcdir)/../Controls \
        -I$(srcdir)/../StdMeshers \
-       -I$(top_builddir)/idl \
-       -I$(top_builddir)/salome_adm/unix
-
+       -I$(top_builddir)/idl
 
 libStdMeshersEngine_la_LDFLAGS  = \
        ../../idl/libSalomeIDLSMESH.la \
index 70a1bda4409ee7da11b7a2c5623e5a1573049cc0..6352b073489fcdc927346f81a977358b2c94b805 100755 (executable)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  File   : SMESH_StdMeshers_I.hxx
 //  Author : Alexander BORODIN
 //  Module : SMESH
@@ -28,7 +29,7 @@
 #define _SMESH_StdMeshers_I_HXX_
 
 #ifdef WNT
- #if defined STDMESHERS_I_EXPORTS
+ #if defined STDMESHERS_I_EXPORTS || defined StdMeshersEngine_EXPORTS
   #define STDMESHERS_I_EXPORT __declspec( dllexport )
  #else
   #define STDMESHERS_I_EXPORT __declspec( dllimport )
index 20a0b29096165e87b4dea53f01df673c66ddd9e3..8d57e1e9a8fb2aa8a219417e6ef16462fa9e58fa 100644 (file)
@@ -1,29 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_Arithmetic1D_i.cxx
 //  Author : Damien COQUERET, OCC
 //  Module : SMESH
-//  $Header$
 //
 #include "StdMeshers_Arithmetic1D_i.hxx"
 #include "SMESH_Gen_i.hxx"
@@ -46,15 +46,15 @@ using namespace std;
 //=============================================================================
 
 StdMeshers_Arithmetic1D_i::StdMeshers_Arithmetic1D_i( PortableServer::POA_ptr thePOA,
-                                                   int                     theStudyId,
-                                                   ::SMESH_Gen*            theGenImpl )
+                                                    int                     theStudyId,
+                                                    ::SMESH_Gen*            theGenImpl )
      : SALOME::GenericObj_i( thePOA ), 
        SMESH_Hypothesis_i( thePOA )
 {
   MESSAGE( "StdMeshers_Arithmetic1D_i::StdMeshers_Arithmetic1D_i" );
   myBaseImpl = new ::StdMeshers_Arithmetic1D( theGenImpl->GetANewId(),
-                                            theStudyId,
-                                            theGenImpl );
+                                             theStudyId,
+                                             theGenImpl );
 }
 
 //=============================================================================
@@ -79,7 +79,7 @@ StdMeshers_Arithmetic1D_i::~StdMeshers_Arithmetic1D_i()
 //=============================================================================
 
 void StdMeshers_Arithmetic1D_i::SetLength(CORBA::Double theLength,
-                                         CORBA::Boolean theIsStart )
+                                          CORBA::Boolean theIsStart )
      throw ( SALOME::SALOME_Exception )
 {
   MESSAGE( "StdMeshers_StartEndLength_i::SetLength" );
@@ -89,12 +89,37 @@ void StdMeshers_Arithmetic1D_i::SetLength(CORBA::Double theLength,
   }
   catch ( SALOME_Exception& S_ex ) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
-                                 SALOME::BAD_PARAM );
+                                  SALOME::BAD_PARAM );
   }
 
   // Update Python script
-  SMESH::TPythonDump() << _this() << ".SetLength( "
-                       << theLength << ", " << theIsStart << " )";
+  SMESH::TPythonDump()
+    << _this() << ( theIsStart ? ".SetStartLength( " : ".SetEndLength( " )
+    << SMESH::TVar(theLength) << " )";
+}
+
+//=============================================================================
+/*!
+ * Sets <start segment length> parameter value
+ */
+//=============================================================================
+
+void StdMeshers_Arithmetic1D_i::SetStartLength( CORBA::Double length)
+  throw (SALOME::SALOME_Exception)
+{
+  SetLength( length, true );
+}
+
+//=============================================================================
+/*!
+ * Sets <end segment length> parameter value
+ */
+//=============================================================================
+
+void StdMeshers_Arithmetic1D_i::SetEndLength( CORBA::Double length)
+  throw (SALOME::SALOME_Exception)
+{
+  SetLength( length, false );
 }
 
 //=============================================================================
@@ -107,11 +132,105 @@ void StdMeshers_Arithmetic1D_i::SetLength(CORBA::Double theLength,
 
 CORBA::Double StdMeshers_Arithmetic1D_i::GetLength( CORBA::Boolean theIsStart)
 {
-  MESSAGE( "StdMeshers_StartEndLength_i::GetLength" );
+  MESSAGE( "StdMeshers_Arithmetic1D_i::GetLength" );
   ASSERT( myBaseImpl );
   return this->GetImpl()->GetLength( theIsStart );
 }
 
+//=============================================================================
+/*!
+ *  StdMeshers_Arithmetic1D_i::SetReversedEdges
+ *
+ *  Set edges to reverse
+ */
+//=============================================================================
+
+void StdMeshers_Arithmetic1D_i::SetReversedEdges( const SMESH::long_array& theIds )
+{
+  ASSERT( myBaseImpl );
+  try {
+    std::vector<int> ids( theIds.length() );
+    CORBA::Long iEnd = theIds.length();
+    for ( CORBA::Long i = 0; i < iEnd; i++ )
+      ids[ i ] = theIds[ i ];
+
+    this->GetImpl()->SetReversedEdges( ids );
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
+                                  SALOME::BAD_PARAM );
+  }
+
+  // Update Python script
+  SMESH::TPythonDump() << _this() << ".SetReversedEdges( " << theIds << " )";
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_Arithmetic1D_i::SetObjectEntry
+ *
+ *  Set the Entry for the Main Object
+ */
+//=============================================================================
+
+void StdMeshers_Arithmetic1D_i::SetObjectEntry( const char* theEntry )
+{
+  ASSERT( myBaseImpl );
+  string entry(theEntry); // actually needed as theEntry is spoiled by moment of dumping
+  try {
+    this->GetImpl()->SetObjectEntry( entry.c_str() );
+    // Update Python script
+    SMESH::TPythonDump() << _this() << ".SetObjectEntry( \"" << entry.c_str() << "\" )";
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),SALOME::BAD_PARAM );
+  }
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_Arithmetic1D_i::GetObjectEntry
+ *
+ *  Set the Entry for the Main Object
+ */
+//=============================================================================
+
+char* StdMeshers_Arithmetic1D_i::GetObjectEntry()
+{
+  MESSAGE( "StdMeshers_Arithmetic1D_i::SetObjectEntry" );
+  ASSERT( myBaseImpl );
+  const char* entry;
+  try {
+    entry = this->GetImpl()->GetObjectEntry();
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
+                                  SALOME::BAD_PARAM );
+  }
+  return CORBA::string_dup( entry );
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_Arithmetic1D_i::GetReversedEdges
+ *
+ *  Get reversed edges
+ */
+//=============================================================================
+
+SMESH::long_array* StdMeshers_Arithmetic1D_i::GetReversedEdges()
+{
+  MESSAGE( "StdMeshers_StartEndLength_i::GetReversedEdges" );
+  ASSERT( myBaseImpl );
+  SMESH::long_array_var anArray = new SMESH::long_array;
+  std::vector<int> ids = this->GetImpl()->GetReversedEdges();
+  anArray->length( ids.size() );
+  for ( CORBA::Long i = 0; i < ids.size(); i++)
+    anArray [ i ] = ids [ i ];
+
+  return anArray._retn();
+}
+
 //=============================================================================
 /*!
  *  StdMeshers_Arithmetic1D_i::GetImpl
@@ -140,3 +259,14 @@ CORBA::Boolean StdMeshers_Arithmetic1D_i::IsDimSupported( SMESH::Dimension type
   return type == SMESH::DIM_1D;
 }
 
+//================================================================================
+/*!
+ * \brief Return method name corresponding to index of variable parameter
+ */
+//================================================================================
+
+std::string StdMeshers_Arithmetic1D_i::getMethodOfParameter(const int paramIndex,
+                                                            int       nbVars) const
+{
+  return paramIndex == 0 ? "SetStartLength" : "SetEndLength";
+}
index 3d8ec8642c095d4e9f25fb578f0dd97bc6ad52c7..6dfeb10fd3764770a187aca67231429fcc46bd37 100644 (file)
@@ -1,29 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_Arithmetic1D_i.hxx
 //  Author : Damien COQUERET, OCC
 //  Module : SMESH
-//  $Header$
 //
 #ifndef _SMESH_ARITHMETIC1D_I_HXX_
 #define _SMESH_ARITHMETIC1D_I_HXX_
@@ -47,21 +47,44 @@ public:
   // Constructor
   StdMeshers_Arithmetic1D_i( PortableServer::POA_ptr thePOA,
                             int                     theStudyId,
-                           ::SMESH_Gen*            theGenImpl );
+                             ::SMESH_Gen*            theGenImpl );
   // Destructor
   virtual ~StdMeshers_Arithmetic1D_i();
 
   // Set length
+  // * OBSOLETE *. Avoid such a way of interface design
   void SetLength( CORBA::Double theLength, CORBA::Boolean theIsStart )
     throw ( SALOME::SALOME_Exception );
+
+  // Sets <start segment length> parameter value
+  void SetStartLength( CORBA::Double length) throw (SALOME::SALOME_Exception);
+
+  // Sets <end segment length> parameter value
+  void SetEndLength( CORBA::Double length) throw (SALOME::SALOME_Exception);
+
   // Get length
   CORBA::Double GetLength(CORBA::Boolean theIsStart);
 
+  //Set Reversed Edges
+  void SetReversedEdges( const SMESH::long_array& theIDs);
+
+  //Get Reversed Edges
+  SMESH::long_array*  GetReversedEdges();
+  
+  //Set the Entry of the Object
+  void SetObjectEntry( const char* theEntry);
+
+  //Get Object Entry
+  char* GetObjectEntry();
+
   // Get implementation
   ::StdMeshers_Arithmetic1D* GetImpl();
-  
+
   // Verify whether hypothesis supports given entity type 
   CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+
+ protected:
+  virtual std::string getMethodOfParameter(const int paramIndex, int nbVars) const;
 };
 
 #endif
index 2085f1f5269fe9c71b90d149d82c03be7a4f7db6..9d8f15e6551c9fa820f2b86c77146e6555754b72 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes
 //  File   : StdMeshers_AutomaticLength_i.cxx
 //  Author : Edward AGAPOV
@@ -87,7 +88,7 @@ void StdMeshers_AutomaticLength_i::SetFineness( CORBA::Double theFineness )
   }
   catch ( SALOME_Exception& S_ex ) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
-                                 SALOME::BAD_PARAM );
+                                  SALOME::BAD_PARAM );
   }
   // Update Python script
   SMESH::TPythonDump() << _this() << ".SetFineness( " << theFineness << " )";
index 7bb85cf4575cd98e053ec04526dfe719f7c6243f..c3492bf38bf7baaa27cc61176f0cb23a9fa7bccf 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_AutomaticLength_i.hxx
 //  Author : Edward AGAPOV
diff --git a/src/StdMeshers_I/StdMeshers_CartesianParameters3D_i.cxx b/src/StdMeshers_I/StdMeshers_CartesianParameters3D_i.cxx
new file mode 100644 (file)
index 0000000..d8b0724
--- /dev/null
@@ -0,0 +1,293 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+//  File   : StdMeshers_CartesianParameters3D_i.cxx
+//  Module : SMESH
+//
+#include "StdMeshers_CartesianParameters3D_i.hxx"
+
+#include "StdMeshers_CartesianParameters3D.hxx"
+#include "SMESH_Gen_i.hxx"
+#include "SMESH_Gen.hxx"
+#include "SMESH_PythonDump.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+#define _vec2array( v, a,conversion )           \
+  {                                             \
+    a->length( v.size() );                      \
+    for ( size_t i = 0; i < v.size(); ++i )     \
+      a[i] = conversion( v[i] );                \
+  }
+#define _array2vec(a,v,conversion)              \
+  {                                             \
+    v.resize( a.length() );                     \
+    for ( size_t i = 0; i < v.size(); ++i )     \
+      v[i] = conversion ( a[i] );               \
+  }
+namespace
+{
+  const char* _string2chars(const std::string& s ) { return s.c_str(); }
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_CartesianParameters3D_i::StdMeshers_CartesianParameters3D_i
+ *
+ *  Constructor
+ */
+//=============================================================================
+
+StdMeshers_CartesianParameters3D_i::
+StdMeshers_CartesianParameters3D_i( PortableServer::POA_ptr thePOA,
+                                    int                     theStudyId,
+                                    ::SMESH_Gen*            theGenImpl )
+  : SALOME::GenericObj_i( thePOA ), 
+    SMESH_Hypothesis_i( thePOA )
+{
+  MESSAGE( "StdMeshers_CartesianParameters3D_i::StdMeshers_CartesianParameters3D_i" );
+  myBaseImpl = new ::StdMeshers_CartesianParameters3D( theGenImpl->GetANewId(),
+                                                       theStudyId,
+                                                       theGenImpl );
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_CartesianParameters3D_i::~StdMeshers_CartesianParameters3D_i
+ *
+ *  Destructor
+ */
+//=============================================================================
+
+StdMeshers_CartesianParameters3D_i::~StdMeshers_CartesianParameters3D_i()
+{
+  MESSAGE( "StdMeshers_CartesianParameters3D_i::~StdMeshers_CartesianParameters3D_i" );
+}
+
+//=============================================================================
+/*!
+ * SetGrid
+ */
+//=============================================================================
+
+void StdMeshers_CartesianParameters3D_i::SetGrid(const SMESH::double_array& coords,
+                                                 CORBA::Short               axis)
+  throw (SALOME::SALOME_Exception)
+{
+  std::vector<double> coordVec;//, yCoords, zCoords;
+  _array2vec( coords, coordVec, );
+
+  ASSERT( myBaseImpl );
+  try {
+    this->GetImpl()->SetGrid( coordVec, axis );
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM );
+  }
+
+  // Update Python script
+  SMESH::TPythonDump() << _this() << ".SetGrid( " << coords << ", " << axis << " )";
+}
+
+//=============================================================================
+/*!
+ *  GetGrid
+ */
+//=============================================================================
+
+SMESH::double_array* StdMeshers_CartesianParameters3D_i::GetGrid(CORBA::Short axis)
+  throw (SALOME::SALOME_Exception)
+{
+  std::vector<double> coordVec;
+  ASSERT( myBaseImpl );
+  try {
+    this->GetImpl()->GetGrid(coordVec, axis);
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM );
+  }
+
+  SMESH::double_array_var coords = new SMESH::double_array();
+  _vec2array( coordVec, coords, );
+
+  return coords._retn();
+}
+
+//=============================================================================
+/*!
+ *  SetSizeThreshold
+ */
+//=============================================================================
+
+void StdMeshers_CartesianParameters3D_i::SetSizeThreshold(CORBA::Double threshold)
+  throw (SALOME::SALOME_Exception)
+{
+  ASSERT( myBaseImpl );
+  try {
+    this->GetImpl()->SetSizeThreshold(threshold);
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM );
+  }
+
+  // Update Python script
+  SMESH::TPythonDump() << _this() << ".SetSizeThreshold( " << SMESH::TVar(threshold) << " )";
+}
+
+//=============================================================================
+/*!
+ *  GetSizeThreshold
+ */
+//=============================================================================
+
+CORBA::Double StdMeshers_CartesianParameters3D_i::GetSizeThreshold()
+{
+  return this->GetImpl()->GetSizeThreshold();
+}
+
+//=======================================================================
+//function : SetGridSpacing
+//\brief Set grid spacing along the three axes
+// \param spaceFunctions - functions defining spacing values at given point on axis
+// \param internalPoints - points dividing a grid into parts along each direction
+// Parameter t of spaceFunction f(t) is a position [0,1] withing bounding box of
+// the shape to mesh or withing an interval defined by internal points
+//=======================================================================
+
+void StdMeshers_CartesianParameters3D_i::SetGridSpacing(const SMESH::string_array& spaceFunctions,
+                                                        const SMESH::double_array& internalPoints,
+                                                        CORBA::Short               axis)
+  throw (SALOME::SALOME_Exception)
+{
+  vector<string> funVec;
+  vector<double> pointVec;
+  _array2vec( spaceFunctions, funVec, (const char*) );
+  _array2vec( internalPoints, pointVec, );
+
+  ASSERT( myBaseImpl );
+  try {
+    this->GetImpl()->SetGridSpacing( funVec, pointVec, axis );
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM );
+  }
+
+  // Update Python script
+  SMESH::TPythonDump() << _this() << ".SetGridSpacing( "
+                       << spaceFunctions << ", "
+                       << internalPoints << ", "
+                       << axis << " )";
+}
+
+//=======================================================================
+//function : GetGridSpacing
+//=======================================================================
+
+void StdMeshers_CartesianParameters3D_i::GetGridSpacing(SMESH::string_array_out xSpaceFunctions,
+                                                        SMESH::double_array_out xInternalPoints,
+                                                        CORBA::Short            axis)
+  throw (SALOME::SALOME_Exception)
+{
+  ASSERT( myBaseImpl );
+  try {
+    vector<string> funVec;
+    vector<double> pointVec;
+    this->GetImpl()->GetGridSpacing( funVec, pointVec, axis );
+
+    xSpaceFunctions = new SMESH::string_array();
+    xInternalPoints = new SMESH::double_array();
+
+    _vec2array( funVec, xSpaceFunctions, _string2chars );
+    _vec2array( pointVec, xInternalPoints, );
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM );
+  }
+}
+
+//=======================================================================
+//function : IsGridBySpacing
+//purpose  : Return true if the grid is defined by spacing functions and 
+//           not by node coordinates
+//=======================================================================
+
+CORBA::Boolean StdMeshers_CartesianParameters3D_i::IsGridBySpacing(CORBA::Short axis)
+{
+  return this->GetImpl()->IsGridBySpacing(axis);
+}
+
+//=======================================================================
+//function : ComputeCoordinates
+//purpose  : Computes node coordinates by spacing functions
+//=======================================================================
+
+SMESH::double_array*
+StdMeshers_CartesianParameters3D_i::ComputeCoordinates(CORBA::Double              x0,
+                                                       CORBA::Double              x1,
+                                                       const SMESH::string_array& spaceFuns,
+                                                       const SMESH::double_array& points,
+                                                       const char*                axisName )
+    throw (SALOME::SALOME_Exception)
+{
+  vector<string> xFuns;
+  vector<double> xPoints, coords;
+  _array2vec( spaceFuns, xFuns, (const char*) );
+  _array2vec( points, xPoints, );
+  
+  try {
+    this->GetImpl()->ComputeCoordinates( x0, x1, xFuns, xPoints, coords, axisName );
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM );
+  }
+  SMESH::double_array_var res = new SMESH::double_array;
+  _vec2array( coords, res,  );
+
+  return res._retn();
+}
+
+//=============================================================================
+/*!
+ *  Get implementation
+ */
+//=============================================================================
+
+::StdMeshers_CartesianParameters3D* StdMeshers_CartesianParameters3D_i::GetImpl()
+{
+  MESSAGE( "StdMeshers_CartesianParameters3D_i::GetImpl" );
+  return ( ::StdMeshers_CartesianParameters3D* )myBaseImpl;
+}
+
+//================================================================================
+/*!
+ * \brief Verify whether hypothesis supports given entity type 
+  * \param type - dimension (see SMESH::Dimension enumeration)
+  * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise
+ * 
+ * Verify whether hypothesis supports given entity type (see SMESH::Dimension enumeration)
+ */
+//================================================================================  
+
+CORBA::Boolean StdMeshers_CartesianParameters3D_i::IsDimSupported( SMESH::Dimension type )
+{
+  return type == SMESH::DIM_3D;
+}
diff --git a/src/StdMeshers_I/StdMeshers_CartesianParameters3D_i.hxx b/src/StdMeshers_I/StdMeshers_CartesianParameters3D_i.hxx
new file mode 100644 (file)
index 0000000..e09422d
--- /dev/null
@@ -0,0 +1,116 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+//  File   : StdMeshers_CartesianParameters3D_i.hxx
+//  Module : SMESH
+//
+#ifndef _SMESH_CartesianParameters3D_I_HXX_
+#define _SMESH_CartesianParameters3D_I_HXX_
+
+#include "SMESH_StdMeshers_I.hxx"
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_Hypothesis_i.hxx"
+
+class SMESH_Gen;
+class StdMeshers_CartesianParameters3D;
+
+// ======================================================
+// "CartesianParameters3D" hypothesis
+// ======================================================
+
+class STDMESHERS_I_EXPORT StdMeshers_CartesianParameters3D_i:
+  public virtual POA_StdMeshers::StdMeshers_CartesianParameters3D,
+  public virtual SMESH_Hypothesis_i
+{
+ public:
+  // Constructor
+  StdMeshers_CartesianParameters3D_i( PortableServer::POA_ptr thePOA,
+                                      int                     theStudyId,
+                                      ::SMESH_Gen*            theGenImpl );
+  // Destructor
+  virtual ~StdMeshers_CartesianParameters3D_i();
+
+  /*!
+   * Set size threshold. A polyhedral cell got by cutting an initial
+   * hexahedron by geometry boundary is considered small and is removed if
+   * it's size is \athreshold times less than the size of the initial hexahedron. 
+   * threshold must be > 1.0
+   */
+  void SetSizeThreshold(CORBA::Double threshold) throw (SALOME::SALOME_Exception);
+  CORBA::Double GetSizeThreshold();
+
+  /*!
+   * \brief Set node coordinates along an axis (counterd from zero)
+   */
+  void SetGrid(const SMESH::double_array& coords,
+               CORBA::Short               axis) throw (SALOME::SALOME_Exception);
+  SMESH::double_array* GetGrid(CORBA::Short axis) throw (SALOME::SALOME_Exception);
+
+  /*!
+   * \brief Set grid spacing along an axis
+   *  \param spaceFunctions - functions defining spacing value at given point on axis
+   *  \param internalPoints - points dividing a grid into parts along each direction
+   *  \param axis - index of an axis counterd from zero, i.e. 0==X, 1==Y, 2==Z
+   *
+   * Parameter t of spaceFunction f(t) is a position [0,1] withing bounding box of
+   * the shape to mesh or withing an interval defined by internal points
+   */
+  void SetGridSpacing(const SMESH::string_array& spaceFunctions,
+                      const SMESH::double_array& internalPoints,
+                      CORBA::Short               axis) throw (SALOME::SALOME_Exception);
+
+  void GetGridSpacing(SMESH::string_array_out xSpaceFunctions,
+                      SMESH::double_array_out xInternalPoints,
+                      CORBA::Short            axis) throw (SALOME::SALOME_Exception);
+
+  /*!
+   * \brief Return true if the grid is defined by spacing functions and 
+   *        not by node coordinates
+   */
+  CORBA::Boolean IsGridBySpacing(CORBA::Short axis);
+
+  /*!
+   * \brief Computes node coordinates by spacing functions
+   *  \param x0 - lower coordinate
+   *  \param x1 - upper coordinate
+   *  \param spaceFuns - space functions
+   *  \param points - internal points
+   *  \param coords - the computed coordinates
+   */
+  SMESH::double_array* ComputeCoordinates(CORBA::Double              x0,
+                                          CORBA::Double              x1,
+                                          const SMESH::string_array& spaceFuns,
+                                          const SMESH::double_array& points,
+                                          const char*                axisName )
+    throw (SALOME::SALOME_Exception);
+
+  // Get implementation
+  ::StdMeshers_CartesianParameters3D* GetImpl();
+
+  // Verify whether hypothesis supports given entity type 
+  CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+};
+
+#endif
+
diff --git a/src/StdMeshers_I/StdMeshers_Cartesian_3D_i.cxx b/src/StdMeshers_I/StdMeshers_Cartesian_3D_i.cxx
new file mode 100644 (file)
index 0000000..445495f
--- /dev/null
@@ -0,0 +1,79 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+//  File   : StdMeshers_Cartesian_3D_i.cxx
+//  Module : SMESH
+//
+#include "StdMeshers_Cartesian_3D_i.hxx"
+#include "StdMeshers_Cartesian_3D.hxx"
+#include "SMESH_Gen.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+//=============================================================================
+/*!
+ *  StdMeshers_Cartesian_3D_i::StdMeshers_Cartesian_3D_i
+ *
+ *  Constructor
+ */
+//=============================================================================
+
+StdMeshers_Cartesian_3D_i::StdMeshers_Cartesian_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( "StdMeshers_Cartesian_3D_i::StdMeshers_Cartesian_3D_i" );
+  myBaseImpl = new ::StdMeshers_Cartesian_3D( theGenImpl->GetANewId(),
+                                              theStudyId,
+                                              theGenImpl );
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_Cartesian_3D_i::~StdMeshers_Cartesian_3D_i
+ *
+ *  Destructor
+ */
+//=============================================================================
+
+StdMeshers_Cartesian_3D_i::~StdMeshers_Cartesian_3D_i()
+{
+  MESSAGE( "StdMeshers_Cartesian_3D_i::~StdMeshers_Cartesian_3D_i" );
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_Cartesian_3D_i::GetImpl
+ *
+ *  Get implementation
+ */
+//=============================================================================
+
+::StdMeshers_Cartesian_3D* StdMeshers_Cartesian_3D_i::GetImpl()
+{
+  MESSAGE( "StdMeshers_Cartesian_3D_i::GetImpl" );
+  return ( ::StdMeshers_Cartesian_3D* )myBaseImpl;
+}
diff --git a/src/StdMeshers_I/StdMeshers_Cartesian_3D_i.hxx b/src/StdMeshers_I/StdMeshers_Cartesian_3D_i.hxx
new file mode 100644 (file)
index 0000000..7b2d72a
--- /dev/null
@@ -0,0 +1,58 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+//  File   : StdMeshers_Cartesian_3D_i.hxx
+//  Module : SMESH
+//
+#ifndef _SMESH_Cartesian_3D_I_HXX_
+#define _SMESH_Cartesian_3D_I_HXX_
+
+#include "SMESH_StdMeshers_I.hxx"
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_3D_Algo_i.hxx"
+
+class SMESH_Gen;
+class StdMeshers_Cartesian_3D;
+
+// ======================================================
+// Cartesianedron 3d algorithm
+// ======================================================
+class STDMESHERS_I_EXPORT StdMeshers_Cartesian_3D_i:
+  public virtual POA_StdMeshers::StdMeshers_Cartesian_3D,
+  public virtual SMESH_3D_Algo_i
+{
+public:
+  // Constructor
+  StdMeshers_Cartesian_3D_i( PortableServer::POA_ptr thePOA,
+                             int                     theStudyId,
+                             ::SMESH_Gen*            theGenImpl );
+
+  // Destructor
+  virtual ~StdMeshers_Cartesian_3D_i();
+
+  // Get implementation
+  ::StdMeshers_Cartesian_3D* GetImpl();
+};
+
+#endif
index c9d1d76930697399c917632e20d2bc2f696d1e96..5dc09cbc533a09f839cc3667a36078e91e1ec5c9 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_CompositeSegment_1D_i.cxx
 //  Module : SMESH
index d8ffd9b9f95e0ed3d9493cd84e0d560dc2243f78..4f40a2d7a6cc2f3968e36d59754cf274cf0e1c2e 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_CompositeSegment_1D_i.hxx
 //  Module : SMESH
index 2386c6aa7c981ad1e624e0583026259d988796ef..93b208b7ae1868ce3145a3b56b6434b9b514cdfa 100644 (file)
@@ -1,30 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_Deflection1D_i.cxx
 //           Moved here from SMESH_LocalLength_i.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//  $Header$
 //
 #include "StdMeshers_Deflection1D_i.hxx"
 #include "SMESH_Gen_i.hxx"
@@ -47,15 +47,15 @@ using namespace std;
 //=============================================================================
 
 StdMeshers_Deflection1D_i::StdMeshers_Deflection1D_i( PortableServer::POA_ptr thePOA,
-                                         int                     theStudyId,
-                                         ::SMESH_Gen*            theGenImpl )
+                                          int                     theStudyId,
+                                          ::SMESH_Gen*            theGenImpl )
      : SALOME::GenericObj_i( thePOA ), 
        SMESH_Hypothesis_i( thePOA )
 {
   MESSAGE( "StdMeshers_Deflection1D_i::StdMeshers_Deflection1D_i" );
   myBaseImpl = new ::StdMeshers_Deflection1D( theGenImpl->GetANewId(),
-                                       theStudyId,
-                                       theGenImpl );
+                                        theStudyId,
+                                        theGenImpl );
 }
 
 //=============================================================================
@@ -89,11 +89,11 @@ void StdMeshers_Deflection1D_i::SetDeflection( CORBA::Double theValue )
   }
   catch ( SALOME_Exception& S_ex ) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
-                                 SALOME::BAD_PARAM );
+                                  SALOME::BAD_PARAM );
   }
 
   // Update Python script
-  SMESH::TPythonDump() << _this() << ".SetDeflection( " << theValue << " )";
+  SMESH::TPythonDump() << _this() << ".SetDeflection( " << SMESH::TVar(theValue) << " )";
 }
 
 //=============================================================================
@@ -139,3 +139,14 @@ CORBA::Boolean StdMeshers_Deflection1D_i::IsDimSupported( SMESH::Dimension type
   return type == SMESH::DIM_1D;
 }
 
+//================================================================================
+/*!
+ * \brief Return method name corresponding to index of variable parameter
+ */
+//================================================================================
+
+std::string StdMeshers_Deflection1D_i::getMethodOfParameter(const int paramIndex,
+                                                            int       /*nbVars*/) const
+{
+  return "SetDeflection";
+}
index 8fd89d4cd3dce15f31eecfe2f2ca00ccaf5b9bfe..f4e9a9b267a18ee9d2436def3129121af2f49054 100644 (file)
@@ -1,30 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_Deflection1D_i.hxx
 //           Moved here from SMESH_LocalLength_i.hxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//  $Header$
 //
 #ifndef _SMESH_Deflection1D_I_HXX_
 #define _SMESH_Deflection1D_I_HXX_
@@ -65,7 +65,9 @@ public:
   
   // Verify whether hypothesis supports given entity type 
   CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+
+ protected:
+  virtual std::string getMethodOfParameter(const int paramIndex, int nbVars) const;
 };
 
 #endif
-
diff --git a/src/StdMeshers_I/StdMeshers_FixedPoints1D_i.cxx b/src/StdMeshers_I/StdMeshers_FixedPoints1D_i.cxx
new file mode 100644 (file)
index 0000000..1d39c8e
--- /dev/null
@@ -0,0 +1,288 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//  File   : StdMeshers_FixedPoints1D_i.cxx
+//  Author : Damien COQUERET, OCC
+//  Module : SMESH
+//  $Header$
+//
+#include "StdMeshers_FixedPoints1D_i.hxx"
+#include "SMESH_Gen_i.hxx"
+#include "SMESH_Gen.hxx"
+#include "SMESH_PythonDump.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+#include <TCollection_AsciiString.hxx>
+
+using namespace std;
+
+//=============================================================================
+/*!
+ *  StdMeshers_FixedPoints1D_i::StdMeshers_FixedPoints1D_i
+ *
+ *  Constructor
+ */
+//=============================================================================
+
+StdMeshers_FixedPoints1D_i::StdMeshers_FixedPoints1D_i( PortableServer::POA_ptr thePOA,
+                                                        int                     theStudyId,
+                                                        ::SMESH_Gen*            theGenImpl )
+     : SALOME::GenericObj_i( thePOA ), 
+       SMESH_Hypothesis_i( thePOA )
+{
+  MESSAGE( "StdMeshers_FixedPoints1D_i::StdMeshers_FixedPoints1D_i" );
+  myBaseImpl = new ::StdMeshers_FixedPoints1D(theGenImpl->GetANewId(),
+                                              theStudyId,
+                                              theGenImpl);
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_FixedPoints1D_i::~StdMeshers_FixedPoints1D_i
+ *
+ *  Destructor
+ */
+//=============================================================================
+
+StdMeshers_FixedPoints1D_i::~StdMeshers_FixedPoints1D_i()
+{
+  MESSAGE( "StdMeshers_FixedPoints1D_i::~StdMeshers_FixedPoints1D_i" );
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_FixedPoints1D_i::SetNbSegments
+ */
+//=============================================================================
+
+void StdMeshers_FixedPoints1D_i::SetNbSegments(const SMESH::long_array& listNbSeg) 
+     throw ( SALOME::SALOME_Exception )
+{
+  MESSAGE( "StdMeshers_FixedPoints1D_i::SetNbSegments" );
+  ASSERT( myBaseImpl );
+  try {
+    std::vector<int> nbsegs( listNbSeg.length() );
+    CORBA::Long iEnd = listNbSeg.length();
+    for ( CORBA::Long i = 0; i < iEnd; i++ )
+      nbsegs[ i ] = listNbSeg[ i ];
+    this->GetImpl()->SetNbSegments( nbsegs );
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
+                                  SALOME::BAD_PARAM );
+  }
+
+  // Update Python script
+  SMESH::TPythonDump() << _this() << ".SetNbSegments( " << listNbSeg << " )";
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_FixedPoints1D_i::SetPoints
+ */
+//=============================================================================
+
+void StdMeshers_FixedPoints1D_i::SetPoints(const SMESH::double_array& listParams) 
+     throw ( SALOME::SALOME_Exception )
+{
+  MESSAGE( "StdMeshers_FixedPoints1D_i::SetPoints" );
+  ASSERT( myBaseImpl );
+  try {
+    std::vector<double> params( listParams.length() );
+    CORBA::Long iEnd = listParams.length();
+    for ( CORBA::Long i = 0; i < iEnd; i++ )
+      params[ i ] = listParams[ i ];
+    this->GetImpl()->SetPoints( params );
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
+                                  SALOME::BAD_PARAM );
+  }
+
+  // Update Python script
+  SMESH::TPythonDump() << _this() << ".SetPoints( " << listParams << " )";
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_FixedPoints1D_i::GetPoints
+ *
+ *  Get list of point's parameters
+ */
+//=============================================================================
+
+SMESH::double_array* StdMeshers_FixedPoints1D_i::GetPoints()
+{
+  MESSAGE( "StdMeshers_FixedPoints1D_i::GetPoints" );
+  ASSERT( myBaseImpl );
+  SMESH::double_array_var anArray = new SMESH::double_array;
+  std::vector<double> params = this->GetImpl()->GetPoints();
+  anArray->length( params.size() );
+  for ( CORBA::Long i = 0; i < params.size(); i++)
+    anArray [ i ] = params [ i ];
+
+  return anArray._retn();
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_FixedPoints1D_i::GetNbSegments
+ *
+ *  Get list of point's parameters
+ */
+//=============================================================================
+
+SMESH::long_array* StdMeshers_FixedPoints1D_i::GetNbSegments()
+{
+  MESSAGE( "StdMeshers_FixedPoints1D_i::GetNbSegments" );
+  ASSERT( myBaseImpl );
+  SMESH::long_array_var anArray = new SMESH::long_array;
+  std::vector<int> nbsegs = this->GetImpl()->GetNbSegments();
+  anArray->length( nbsegs.size() );
+  for ( CORBA::Long i = 0; i < nbsegs.size(); i++)
+    anArray [ i ] = nbsegs [ i ];
+
+  return anArray._retn();
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_FixedPoints1D_i::SetReversedEdges
+ *
+ *  Set edges to reverse
+ */
+//=============================================================================
+
+void StdMeshers_FixedPoints1D_i::SetReversedEdges( const SMESH::long_array& theIds )
+{
+  ASSERT( myBaseImpl );
+  try {
+    std::vector<int> ids( theIds.length() );
+    CORBA::Long iEnd = theIds.length();
+    for ( CORBA::Long i = 0; i < iEnd; i++ )
+      ids[ i ] = theIds[ i ];
+
+    this->GetImpl()->SetReversedEdges( ids );
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
+                                  SALOME::BAD_PARAM );
+  }
+
+  // Update Python script
+  SMESH::TPythonDump() << _this() << ".SetReversedEdges( " << theIds << " )";
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_FixedPoints1D_i::SetObjectEntry
+ *
+ *  Set the Entry for the Main Object
+ */
+//=============================================================================
+
+void StdMeshers_FixedPoints1D_i::SetObjectEntry( const char* theEntry )
+{
+  ASSERT( myBaseImpl );
+  string entry(theEntry); // actually needed as theEntry is spoiled by moment of dumping
+  try {
+    this->GetImpl()->SetObjectEntry( entry.c_str() );
+    // Update Python script
+    SMESH::TPythonDump() << _this() << ".SetObjectEntry( \"" << entry.c_str() << "\" )";
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),SALOME::BAD_PARAM );
+  }
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_FixedPoints1D_i::GetObjectEntry
+ *
+ *  Set the Entry for the Main Object
+ */
+//=============================================================================
+
+char* StdMeshers_FixedPoints1D_i::GetObjectEntry()
+{
+  MESSAGE( "StdMeshers_FixedPoints1D_i::SetObjectEntry" );
+  ASSERT( myBaseImpl );
+  const char* entry;
+  try {
+    entry = this->GetImpl()->GetObjectEntry();
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
+                                  SALOME::BAD_PARAM );
+  }
+  return CORBA::string_dup( entry );
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_FixedPoints1D_i::GetReversedEdges
+ *
+ *  Get reversed edges
+ */
+//=============================================================================
+
+SMESH::long_array* StdMeshers_FixedPoints1D_i::GetReversedEdges()
+{
+  MESSAGE( "StdMeshers_FixedPoints1D_i::GetReversedEdges" );
+  ASSERT( myBaseImpl );
+  SMESH::long_array_var anArray = new SMESH::long_array;
+  std::vector<int> ids = this->GetImpl()->GetReversedEdges();
+  anArray->length( ids.size() );
+  for ( CORBA::Long i = 0; i < ids.size(); i++)
+    anArray [ i ] = ids [ i ];
+
+  return anArray._retn();
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_FixedPoints1D_i::GetImpl
+ *
+ *  Get implementation
+ */
+//=============================================================================
+
+::StdMeshers_FixedPoints1D* StdMeshers_FixedPoints1D_i::GetImpl()
+{
+  MESSAGE( "StdMeshers_FixedPoints1D_i::GetImpl" );
+  return ( ::StdMeshers_FixedPoints1D* )myBaseImpl;
+}
+
+//================================================================================
+/*!
+ * \brief Verify whether hypothesis supports given entity type 
+  * \param type - dimension (see SMESH::Dimension enumeration)
+  * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise
+ * 
+ * Verify whether hypothesis supports given entity type (see SMESH::Dimension enumeration)
+ */
+//================================================================================  
+CORBA::Boolean StdMeshers_FixedPoints1D_i::IsDimSupported( SMESH::Dimension type )
+{
+  return type == SMESH::DIM_1D;
+}
+
diff --git a/src/StdMeshers_I/StdMeshers_FixedPoints1D_i.hxx b/src/StdMeshers_I/StdMeshers_FixedPoints1D_i.hxx
new file mode 100644 (file)
index 0000000..ee43e5c
--- /dev/null
@@ -0,0 +1,85 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//  File   : StdMeshers_FixedPoints1D_i.hxx
+//  Author : Damien COQUERET, OCC
+//  Module : SMESH
+//
+#ifndef _SMESH_FIXEDPOINTS1D_I_HXX_
+#define _SMESH_FIXEDPOINTS1D_I_HXX_
+
+#include "SMESH_StdMeshers_I.hxx"
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_Hypothesis_i.hxx"
+#include "StdMeshers_FixedPoints1D.hxx"
+
+// ======================================================
+// Fixed points 1D hypothesis
+// ======================================================
+class STDMESHERS_I_EXPORT StdMeshers_FixedPoints1D_i:
+  public virtual POA_StdMeshers::StdMeshers_FixedPoints1D,
+  public virtual SMESH_Hypothesis_i
+{
+public:
+  // Constructor
+  StdMeshers_FixedPoints1D_i( PortableServer::POA_ptr thePOA,
+                              int                     theStudyId,
+                              ::SMESH_Gen*            theGenImpl );
+  // Destructor
+  virtual ~StdMeshers_FixedPoints1D_i();
+
+  // Sets some points on edge using parameter on curve from 0 to 1
+  // (additionally it is neecessary to check orientation of edges and
+  // create list of reversed edges if it is needed) and sets numbers
+  // of segments between given points (default values are equals 1)
+  void SetPoints(const SMESH::double_array& listParams) 
+    throw ( SALOME::SALOME_Exception );
+  void SetNbSegments(const SMESH::long_array& listNbSeg) 
+    throw ( SALOME::SALOME_Exception );
+
+  // Returns list of point's parameters
+  SMESH::double_array* GetPoints();
+  
+  // Returns list of numbers of segments
+  SMESH::long_array* GetNbSegments();
+    
+  //Set Reversed Edges
+  void SetReversedEdges( const SMESH::long_array& theIDs);
+
+  //Get Reversed Edges
+  SMESH::long_array*  GetReversedEdges();
+  
+  //Set the Entry of the Object
+  void SetObjectEntry( const char* theEntry);
+
+  //Get Object Entry
+  char* GetObjectEntry();
+
+  // Get implementation
+  ::StdMeshers_FixedPoints1D* GetImpl();
+
+  // Verify whether hypothesis supports given entity type 
+  CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+};
+
+#endif
index cac9b45e2f9fd7b6a0bf4bbf4e91ef125075ed30..d75efe8e89825a60679de8aadb968beee219e902 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_Hexa_3D_i.cxx
 //           Moved here from SMESH_Hexa_3D_i.cxx
@@ -43,8 +44,8 @@ using namespace std;
 //=============================================================================
 
 StdMeshers_Hexa_3D_i::StdMeshers_Hexa_3D_i( PortableServer::POA_ptr thePOA,
-                                 int                     theStudyId,
-                                 ::SMESH_Gen*            theGenImpl )
+                                  int                     theStudyId,
+                                  ::SMESH_Gen*            theGenImpl )
      : SALOME::GenericObj_i( thePOA ), 
        SMESH_Hypothesis_i( thePOA ), 
        SMESH_Algo_i( thePOA ),
@@ -52,8 +53,8 @@ StdMeshers_Hexa_3D_i::StdMeshers_Hexa_3D_i( PortableServer::POA_ptr thePOA,
 {
   MESSAGE( "StdMeshers_Hexa_3D_i::StdMeshers_Hexa_3D_i" );
   myBaseImpl = new ::StdMeshers_Hexa_3D( theGenImpl->GetANewId(),
-                                   theStudyId,
-                                   theGenImpl );
+                                    theStudyId,
+                                    theGenImpl );
 }
 
 //=============================================================================
index 9c07aed6f7888980fafe51612bc247b513bffb96..6316fea71d9146b8c2152a77e3af1f908d621011 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_Hexa_3D_i.hxx
 //           Moved here from SMESH_Hexa_3D_i.hxx
@@ -50,7 +51,7 @@ public:
   // Constructor
   StdMeshers_Hexa_3D_i( PortableServer::POA_ptr thePOA,
                    int                     theStudyId,
-                  ::SMESH_Gen*            theGenImpl );
+                   ::SMESH_Gen*            theGenImpl );
 
   // Destructor
   virtual ~StdMeshers_Hexa_3D_i();
diff --git a/src/StdMeshers_I/StdMeshers_ImportSource1D_i.cxx b/src/StdMeshers_I/StdMeshers_ImportSource1D_i.cxx
new file mode 100644 (file)
index 0000000..e2ad321
--- /dev/null
@@ -0,0 +1,280 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//  File   : StdMeshers_ImportSource1D_i.cxx
+//  Module : SMESH
+//
+#include "StdMeshers_ImportSource1D_i.hxx"
+
+#include "SMESH_Gen.hxx"
+#include "SMESH_Gen_i.hxx"
+#include "SMESH_Group_i.hxx"
+#include "SMESH_PythonDump.hxx"
+#include "StdMeshers_ObjRefUlils.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+#include <TCollection_AsciiString.hxx>
+
+#include CORBA_SERVER_HEADER(SMESH_Group)
+
+using namespace std;
+
+//=============================================================================
+/*!
+ *  StdMeshers_ImportSource1D_i::StdMeshers_ImportSource1D_i
+ *
+ *  Constructor
+ */
+//=============================================================================
+
+StdMeshers_ImportSource1D_i::StdMeshers_ImportSource1D_i( PortableServer::POA_ptr thePOA,
+                                                          int                     theStudyId,
+                                                          ::SMESH_Gen*            theGenImpl )
+  : SALOME::GenericObj_i( thePOA ), 
+    SMESH_Hypothesis_i( thePOA )
+{
+  MESSAGE( "StdMeshers_ImportSource1D_i::StdMeshers_ImportSource1D_i" );
+  myBaseImpl = new ::StdMeshers_ImportSource1D( theGenImpl->GetANewId(),
+                                                theStudyId,
+                                                theGenImpl );
+  _groupEntries = new SMESH::string_array();
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_ImportSource1D_i::~StdMeshers_ImportSource1D_i
+ *
+ *  Destructor
+ */
+//=============================================================================
+
+StdMeshers_ImportSource1D_i::~StdMeshers_ImportSource1D_i()
+{
+  MESSAGE( "StdMeshers_ImportSource1D_i::~StdMeshers_ImportSource1D_i" );
+}
+
+//=============================================================================
+/*!
+ *  SetSourceEdges
+ */
+//=============================================================================
+
+void StdMeshers_ImportSource1D_i::SetSourceEdges(const SMESH::ListOfGroups& groups)
+{
+  MESSAGE( "StdMeshers_ImportSource1D_i::SetSourceEdges" );
+  ASSERT( myBaseImpl );
+  try
+  {
+    std::vector<SMESH_Group*> smesh_groups;
+    std::vector<string> entries;
+    SALOMEDS::Study_var study = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy();
+    for ( int i = 0; i < groups.length(); ++i )
+      if ( SMESH_GroupBase_i* gp_i = SMESH::DownCast<SMESH_GroupBase_i*>( groups[i] ))
+      {
+        if ( gp_i->GetType() != SMESH::EDGE )
+          THROW_SALOME_CORBA_EXCEPTION("Wrong group type", SALOME::BAD_PARAM);
+        smesh_groups.push_back( gp_i->GetSmeshGroup() );
+
+        SALOMEDS::SObject_var so = SMESH_Gen_i::GetSMESHGen()->ObjectToSObject(study, groups[i]);
+        if ( !so->_is_nil())
+        {
+          CORBA::String_var entry = so->GetID();
+          entries.push_back( entry.in() );
+        }
+      }
+    this->GetImpl()->SetGroups( smesh_groups );
+
+    _groupEntries = new SMESH::string_array;
+    _groupEntries->length( entries.size ());
+    for ( int i = 0; i < entries.size(); ++i )
+      _groupEntries[i] = entries[i].c_str();
+  }
+  catch ( SALOME_Exception& S_ex )
+  {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM );
+  }
+
+  // Update Python script
+  SMESH::TPythonDump() << _this() << ".SetSourceEdges( " << groups << " )";
+}
+
+//=============================================================================
+/*!
+ * Return entries of groups
+ */
+//=============================================================================
+
+SMESH::string_array*  StdMeshers_ImportSource1D_i::GetSourceEdges()
+{
+  MESSAGE( "StdMeshers_ImportSource1D_i::GetImportSource" );
+  SMESH::string_array_var res = new SMESH::string_array( _groupEntries );
+  return res._retn();
+}
+
+//================================================================================
+/*!
+ * \brief Set to copy mesh and groups
+ */
+//================================================================================
+
+void StdMeshers_ImportSource1D_i::SetCopySourceMesh(CORBA::Boolean toCopyMesh,
+                                                    CORBA::Boolean toCopyGroups)
+{
+  GetImpl()->SetCopySourceMesh(toCopyMesh,toCopyGroups);
+  SMESH::TPythonDump() << _this() << ".SetCopySourceMesh( "
+                       << toCopyMesh << ", " << toCopyGroups << " )";
+}
+
+//================================================================================
+/*!
+ * \brief Return "to copy mesh and groups"
+ */
+//================================================================================
+
+void StdMeshers_ImportSource1D_i::GetCopySourceMesh(CORBA::Boolean& toCopyMesh,
+                                                    CORBA::Boolean& toCopyGroups)
+{
+  GetImpl()->GetCopySourceMesh(toCopyMesh,toCopyGroups);
+}
+
+//================================================================================
+/*!
+ * \brief Write parameters in a string
+  * \retval char* - resulting string
+ */
+//================================================================================
+
+char* StdMeshers_ImportSource1D_i::SaveTo()
+{
+  std::ostringstream os;
+  os << " " << _groupEntries->length();
+
+  SALOMEDS::Study_var study = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy();
+  for ( int i = 0; i < _groupEntries->length(); ++i )
+  {
+    // entry
+    os << " " << _groupEntries[i];
+
+    // id
+    SALOMEDS::SObject_var groupSO = study->FindObjectID( _groupEntries[i] );
+    CORBA::Object_var groupObj;
+    if ( !groupSO->_is_nil() )
+      groupObj = groupSO->GetObject();
+    StdMeshers_ObjRefUlils::SaveToStream( groupObj, os );
+  }
+
+  myBaseImpl->SaveTo( os );
+
+  return CORBA::string_dup( os.str().c_str() );
+}
+
+//================================================================================
+/*!
+ * \brief Retrieve parameters from the string
+  * \param theStream - the input string
+ */
+//================================================================================
+
+void StdMeshers_ImportSource1D_i::LoadFrom( const char* theStream )
+{
+  std::istringstream is( theStream );
+
+  int nbGroups;
+  is >> nbGroups;
+
+  _groupEntries = new SMESH::string_array;
+  _groupEntries->length( nbGroups );
+  std::string id, entry;
+  for ( int i = 0; i < _groupEntries->length(); ++i )
+  {
+    if ( is >> entry )
+      _groupEntries[i] = entry.c_str();
+    else
+    {
+      _groupEntries->length( i );
+      is.clear(ios::badbit | is.rdstate());
+      break;
+    }
+    if ( is >> id )
+      _groupIDs.push_back( id );
+    else
+    {
+      is.clear(ios::badbit | is.rdstate());
+      break;
+    }
+  }
+
+  myBaseImpl->LoadFrom( is );
+}
+
+//================================================================================
+/*!
+ * \brief Retrieve groups by their ids loaded by LoadFrom()
+ * This is possible only when all meshes are fully loaded
+ */
+//================================================================================
+
+void StdMeshers_ImportSource1D_i::UpdateAsMeshesRestored()
+{
+  std::vector<SMESH_Group*> smesh_groups;
+  for ( unsigned i = 0; i < _groupIDs.size(); ++i )
+  {
+    std::istringstream is( _groupIDs[i].c_str() );
+    SMESH::SMESH_GroupBase_var group =
+      StdMeshers_ObjRefUlils::LoadObjectFromStream<SMESH::SMESH_GroupBase>( is );
+    if ( SMESH_GroupBase_i* gp_i = SMESH::DownCast<SMESH_GroupBase_i*>( group ))
+      smesh_groups.push_back( gp_i->GetSmeshGroup() );
+  }
+  GetImpl()->RestoreGroups(smesh_groups);
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_ImportSource1D_i::GetImpl
+ *
+ *  Get implementation
+ */
+//=============================================================================
+
+::StdMeshers_ImportSource1D* StdMeshers_ImportSource1D_i::GetImpl()
+{
+  MESSAGE( "StdMeshers_ImportSource1D_i::GetImpl" );
+  return ( ::StdMeshers_ImportSource1D* )myBaseImpl;
+}
+
+//================================================================================
+/*!
+ * \brief Verify whether hypothesis supports given entity type 
+  * \param type - dimension (see SMESH::Dimension enumeration)
+  * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise
+ * 
+ * Verify whether hypothesis supports given entity type (see SMESH::Dimension enumeration)
+ */
+//================================================================================  
+CORBA::Boolean StdMeshers_ImportSource1D_i::IsDimSupported( SMESH::Dimension type )
+{
+  return type == SMESH::DIM_1D;
+}
+
diff --git a/src/StdMeshers_I/StdMeshers_ImportSource1D_i.hxx b/src/StdMeshers_I/StdMeshers_ImportSource1D_i.hxx
new file mode 100644 (file)
index 0000000..1c3fafa
--- /dev/null
@@ -0,0 +1,74 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//  File   : StdMeshers_ImportSource1D_i.hxx
+//  Module : SMESH
+//
+#ifndef _SMESH_ImportSource1D_I_HXX_
+#define _SMESH_ImportSource1D_I_HXX_
+
+#include "SMESH_StdMeshers_I.hxx"
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_Hypothesis_i.hxx"
+#include "StdMeshers_ImportSource.hxx"
+
+class SMESH_Gen;
+
+class STDMESHERS_I_EXPORT StdMeshers_ImportSource1D_i:
+  public virtual POA_StdMeshers::StdMeshers_ImportSource1D,
+  public virtual SMESH_Hypothesis_i
+{
+ public:
+  // Constructor
+  StdMeshers_ImportSource1D_i( PortableServer::POA_ptr thePOA,
+                               int                     theStudyId,
+                               ::SMESH_Gen*            theGenImpl );
+  // Destructor
+  virtual ~StdMeshers_ImportSource1D_i();
+
+  void SetSourceEdges(const ::SMESH::ListOfGroups& groups);
+  SMESH::string_array* GetSourceEdges();
+  void SetCopySourceMesh(::CORBA::Boolean toCopyMesh, ::CORBA::Boolean toCopyGroups);
+  void GetCopySourceMesh(::CORBA::Boolean& toCopyMesh, ::CORBA::Boolean& toCopyGroups);
+
+  // Get implementation
+  ::StdMeshers_ImportSource1D* GetImpl();
+
+  // Verify whether hypothesis supports given entity type 
+  CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+
+  // Redefined Persistence
+  virtual char* SaveTo();
+  virtual void  LoadFrom( const char* theStream );
+  virtual void  UpdateAsMeshesRestored();
+
+ private:
+  SMESH::string_array_var _groupEntries;
+  std::vector< std::string > _groupIDs;
+};
+
+#endif
+
diff --git a/src/StdMeshers_I/StdMeshers_ImportSource2D_i.cxx b/src/StdMeshers_I/StdMeshers_ImportSource2D_i.cxx
new file mode 100644 (file)
index 0000000..35f9d3f
--- /dev/null
@@ -0,0 +1,280 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//  File   : StdMeshers_ImportSource2D_i.cxx
+//  Module : SMESH
+//
+#include "StdMeshers_ImportSource2D_i.hxx"
+
+#include "SMESH_Gen.hxx"
+#include "SMESH_Gen_i.hxx"
+#include "SMESH_Group_i.hxx"
+#include "SMESH_PythonDump.hxx"
+#include "StdMeshers_ObjRefUlils.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+#include <TCollection_AsciiString.hxx>
+
+#include CORBA_SERVER_HEADER(SMESH_Group)
+
+using namespace std;
+
+//=============================================================================
+/*!
+ *  StdMeshers_ImportSource2D_i::StdMeshers_ImportSource2D_i
+ *
+ *  Constructor
+ */
+//=============================================================================
+
+StdMeshers_ImportSource2D_i::StdMeshers_ImportSource2D_i( PortableServer::POA_ptr thePOA,
+                                                          int                     theStudyId,
+                                                          ::SMESH_Gen*            theGenImpl )
+  : SALOME::GenericObj_i( thePOA ), 
+    SMESH_Hypothesis_i( thePOA )
+{
+  MESSAGE( "StdMeshers_ImportSource2D_i::StdMeshers_ImportSource2D_i" );
+  myBaseImpl = new ::StdMeshers_ImportSource2D( theGenImpl->GetANewId(),
+                                                theStudyId,
+                                                theGenImpl );
+  _groupEntries = new SMESH::string_array();
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_ImportSource2D_i::~StdMeshers_ImportSource2D_i
+ *
+ *  Destructor
+ */
+//=============================================================================
+
+StdMeshers_ImportSource2D_i::~StdMeshers_ImportSource2D_i()
+{
+  MESSAGE( "StdMeshers_ImportSource2D_i::~StdMeshers_ImportSource2D_i" );
+}
+
+//=============================================================================
+/*!
+ *  SetSourceFaces
+ */
+//=============================================================================
+
+void StdMeshers_ImportSource2D_i::SetSourceFaces(const SMESH::ListOfGroups& groups)
+{
+  MESSAGE( "StdMeshers_ImportSource2D_i::SetSourceFaces" );
+  ASSERT( myBaseImpl );
+  try
+  {
+    std::vector<SMESH_Group*> smesh_groups;
+    std::vector<string> entries;
+    SALOMEDS::Study_var study = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy();
+    for ( int i = 0; i < groups.length(); ++i )
+      if ( SMESH_GroupBase_i* gp_i = SMESH::DownCast<SMESH_GroupBase_i*>( groups[i] ))
+      {
+        if ( gp_i->GetType() != SMESH::FACE )
+          THROW_SALOME_CORBA_EXCEPTION("Wrong group type", SALOME::BAD_PARAM);
+        smesh_groups.push_back( gp_i->GetSmeshGroup() );
+
+        SALOMEDS::SObject_var so = SMESH_Gen_i::GetSMESHGen()->ObjectToSObject(study, groups[i]);
+        if ( !so->_is_nil())
+        {
+          CORBA::String_var entry = so->GetID();
+          entries.push_back( entry.in() );
+        }
+      }
+    this->GetImpl()->SetGroups( smesh_groups );
+
+    _groupEntries = new SMESH::string_array;
+    _groupEntries->length( entries.size ());
+    for ( int i = 0; i < entries.size(); ++i )
+      _groupEntries[i] = entries[i].c_str();
+  }
+  catch ( SALOME_Exception& S_ex )
+  {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM );
+  }
+
+  // Update Python script
+  SMESH::TPythonDump() << _this() << ".SetSourceFaces( " << groups << " )";
+}
+
+//=============================================================================
+/*!
+ * Return entries of groups
+ */
+//=============================================================================
+
+SMESH::string_array*  StdMeshers_ImportSource2D_i::GetSourceFaces()
+{
+  MESSAGE( "StdMeshers_ImportSource2D_i::GetImportSource" );
+  SMESH::string_array_var res = new SMESH::string_array( _groupEntries );
+  return res._retn();
+}
+
+//================================================================================
+/*!
+ * \brief Set to copy mesh and groups
+ */
+//================================================================================
+
+void StdMeshers_ImportSource2D_i::SetCopySourceMesh(CORBA::Boolean toCopyMesh,
+                                                    CORBA::Boolean toCopyGroups)
+{
+  GetImpl()->SetCopySourceMesh(toCopyMesh,toCopyGroups);
+  SMESH::TPythonDump() << _this() << ".SetCopySourceMesh( "
+                       << toCopyMesh << ", " << toCopyGroups << " )";
+}
+
+//================================================================================
+/*!
+ * \brief Return "to copy mesh and groups"
+ */
+//================================================================================
+
+void StdMeshers_ImportSource2D_i::GetCopySourceMesh(CORBA::Boolean& toCopyMesh,
+                                                    CORBA::Boolean& toCopyGroups)
+{
+  GetImpl()->GetCopySourceMesh(toCopyMesh,toCopyGroups);
+}
+
+//================================================================================
+/*!
+ * \brief Write parameters in a string
+  * \retval char* - resulting string
+ */
+//================================================================================
+
+char* StdMeshers_ImportSource2D_i::SaveTo()
+{
+  std::ostringstream os;
+  os << " " << _groupEntries->length();
+
+  SALOMEDS::Study_var study = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy();
+  for ( int i = 0; i < _groupEntries->length(); ++i )
+  {
+    // entry
+    os << " " << _groupEntries[i];
+
+    // id
+    SALOMEDS::SObject_var groupSO = study->FindObjectID( _groupEntries[i] );
+    CORBA::Object_var groupObj;
+    if ( !groupSO->_is_nil() )
+      groupObj = groupSO->GetObject();
+    StdMeshers_ObjRefUlils::SaveToStream( groupObj, os );
+  }
+
+  myBaseImpl->SaveTo( os );
+
+  return CORBA::string_dup( os.str().c_str() );
+}
+
+//================================================================================
+/*!
+ * \brief Retrieve parameters from the string
+  * \param theStream - the input string
+ */
+//================================================================================
+
+void StdMeshers_ImportSource2D_i::LoadFrom( const char* theStream )
+{
+  std::istringstream is( theStream );
+
+  int nbGroups;
+  is >> nbGroups;
+
+  _groupEntries = new SMESH::string_array;
+  _groupEntries->length( nbGroups );
+  std::string id, entry;
+  for ( int i = 0; i < _groupEntries->length(); ++i )
+  {
+    if ( is >> entry )
+      _groupEntries[i] = entry.c_str();
+    else
+    {
+      _groupEntries->length( i );
+      is.clear(ios::badbit | is.rdstate());
+      break;
+    }
+    if ( is >> id )
+      _groupIDs.push_back( id );
+    else
+    {
+      is.clear(ios::badbit | is.rdstate());
+      break;
+    }
+  }
+
+  myBaseImpl->LoadFrom( is );
+}
+
+//================================================================================
+/*!
+ * \brief Retrieve groups by their ids loaded by LoadFrom()
+ * This is possible only when all meshes are fully loaded
+ */
+//================================================================================
+
+void StdMeshers_ImportSource2D_i::UpdateAsMeshesRestored()
+{
+  std::vector<SMESH_Group*> smesh_groups;
+  for ( unsigned i = 0; i < _groupIDs.size(); ++i )
+  {
+    std::istringstream is( _groupIDs[i].c_str() );
+    SMESH::SMESH_GroupBase_var group =
+      StdMeshers_ObjRefUlils::LoadObjectFromStream<SMESH::SMESH_GroupBase>( is );
+    if ( SMESH_GroupBase_i* gp_i = SMESH::DownCast<SMESH_GroupBase_i*>( group ))
+      smesh_groups.push_back( gp_i->GetSmeshGroup() );
+  }
+  GetImpl()->RestoreGroups(smesh_groups);
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_ImportSource2D_i::GetImpl
+ *
+ *  Get implementation
+ */
+//=============================================================================
+
+::StdMeshers_ImportSource2D* StdMeshers_ImportSource2D_i::GetImpl()
+{
+  MESSAGE( "StdMeshers_ImportSource2D_i::GetImpl" );
+  return ( ::StdMeshers_ImportSource2D* )myBaseImpl;
+}
+
+//================================================================================
+/*!
+ * \brief Verify whether hypothesis supports given entity type 
+  * \param type - dimension (see SMESH::Dimension enumeration)
+  * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise
+ * 
+ * Verify whether hypothesis supports given entity type (see SMESH::Dimension enumeration)
+ */
+//================================================================================  
+CORBA::Boolean StdMeshers_ImportSource2D_i::IsDimSupported( SMESH::Dimension type )
+{
+  return type == SMESH::DIM_2D;
+}
+
diff --git a/src/StdMeshers_I/StdMeshers_ImportSource2D_i.hxx b/src/StdMeshers_I/StdMeshers_ImportSource2D_i.hxx
new file mode 100644 (file)
index 0000000..eea15ba
--- /dev/null
@@ -0,0 +1,74 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//  File   : StdMeshers_ImportSource2D_i.hxx
+//  Module : SMESH
+//
+#ifndef _SMESH_ImportSource2D_I_HXX_
+#define _SMESH_ImportSource2D_I_HXX_
+
+#include "SMESH_StdMeshers_I.hxx"
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_Hypothesis_i.hxx"
+#include "StdMeshers_ImportSource.hxx"
+
+class SMESH_Gen;
+
+class STDMESHERS_I_EXPORT StdMeshers_ImportSource2D_i:
+  public virtual POA_StdMeshers::StdMeshers_ImportSource2D,
+  public virtual SMESH_Hypothesis_i
+{
+ public:
+  // Constructor
+  StdMeshers_ImportSource2D_i( PortableServer::POA_ptr thePOA,
+                               int                     theStudyId,
+                               ::SMESH_Gen*            theGenImpl );
+  // Destructor
+  virtual ~StdMeshers_ImportSource2D_i();
+
+  void SetSourceFaces(const ::SMESH::ListOfGroups& groups);
+  SMESH::string_array*  GetSourceFaces();
+  void SetCopySourceMesh(::CORBA::Boolean toCopyMesh, ::CORBA::Boolean toCopyGroups);
+  void GetCopySourceMesh(::CORBA::Boolean& toCopyMesh, ::CORBA::Boolean& toCopyGroups);
+
+  // Get implementation
+  ::StdMeshers_ImportSource2D* GetImpl();
+
+  // Verify whether hypothesis supports given entity type 
+  CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+
+  // Redefined Persistence
+  virtual char* SaveTo();
+  virtual void  LoadFrom( const char* theStream );
+  virtual void  UpdateAsMeshesRestored();
+
+ private:
+  SMESH::string_array_var _groupEntries;
+  std::vector< std::string > _groupIDs;
+};
+
+#endif
+
diff --git a/src/StdMeshers_I/StdMeshers_Import_1D2D_i.cxx b/src/StdMeshers_I/StdMeshers_Import_1D2D_i.cxx
new file mode 100644 (file)
index 0000000..104b777
--- /dev/null
@@ -0,0 +1,67 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//  File   : StdMeshers_Import_1D2D_i.cxx
+//  Module : SMESH
+//
+#include "StdMeshers_Import_1D2D_i.hxx"
+#include "SMESH_Gen.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+using namespace std;
+
+
+//=============================================================================
+/*!
+ *  StdMeshers_Import_1D2D_i::StdMeshers_Import_1D2D_i
+ */
+//=============================================================================
+
+StdMeshers_Import_1D2D_i::StdMeshers_Import_1D2D_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( "StdMeshers_Import_1D2D_i::StdMeshers_Import_1D2D_i" );
+  myBaseImpl = new ::StdMeshers_Import_1D2D(theGenImpl->GetANewId(),
+                                            theStudyId,
+                                            theGenImpl );
+}
+
+//-----------------------------------------------------------------------------
+
+StdMeshers_Import_1D2D_i::~StdMeshers_Import_1D2D_i()
+{
+  MESSAGE( "StdMeshers_Import_1D2D_i::~StdMeshers_Import_1D2D_i" );
+}
+
+//-----------------------------------------------------------------------------
+
+::StdMeshers_Import_1D2D* StdMeshers_Import_1D2D_i::GetImpl()
+{
+  MESSAGE( "StdMeshers_Import_1D2D_i::GetImpl" );
+  return ( ::StdMeshers_Import_1D2D* )myBaseImpl;
+}
+
diff --git a/src/StdMeshers_I/StdMeshers_Import_1D2D_i.hxx b/src/StdMeshers_I/StdMeshers_Import_1D2D_i.hxx
new file mode 100644 (file)
index 0000000..150f5aa
--- /dev/null
@@ -0,0 +1,53 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//  File   : StdMeshers_Import_1D2D_i.hxx
+//  Module : SMESH
+//
+#ifndef _SMESH_Import_1D2D_I_HXX_
+#define _SMESH_Import_1D2D_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_2D_Algo_i.hxx"
+#include "StdMeshers_Import_1D2D.hxx"
+
+class SMESH_Gen;
+
+class StdMeshers_Import_1D2D_i:
+  public virtual POA_StdMeshers::StdMeshers_Import_1D2D,
+  public virtual SMESH_2D_Algo_i
+{
+public:
+  // Constructor
+  StdMeshers_Import_1D2D_i( PortableServer::POA_ptr thePOA,
+                            int                     theStudyId,
+                            ::SMESH_Gen*            theGenImpl );
+
+  // Destructor
+  virtual ~StdMeshers_Import_1D2D_i();
+
+  // Get implementation
+  ::StdMeshers_Import_1D2D* GetImpl();
+};
+
+
+#endif
diff --git a/src/StdMeshers_I/StdMeshers_Import_1D_i.cxx b/src/StdMeshers_I/StdMeshers_Import_1D_i.cxx
new file mode 100644 (file)
index 0000000..2a73e4e
--- /dev/null
@@ -0,0 +1,85 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//  File   : StdMeshers_Import_1D_i.cxx
+//           Moved here from SMESH_Import_1D_i.cxx
+//  Author : Paul RASCLE, EDF
+//  Module : SMESH
+//
+#include "StdMeshers_Import_1D_i.hxx"
+#include "SMESH_Gen.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+using namespace std;
+
+//=============================================================================
+/*!
+ *  StdMeshers_Import_1D_i::StdMeshers_Import_1D_i
+ *
+ *  Constructor
+ */
+//=============================================================================
+
+StdMeshers_Import_1D_i::StdMeshers_Import_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_Import_1D_i::StdMeshers_Import_1D_i" );
+  myBaseImpl = new ::StdMeshers_Import_1D( theGenImpl->GetANewId(),
+                                           theStudyId,
+                                           theGenImpl );
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_Import_1D_i::~StdMeshers_Import_1D_i
+ *
+ *  Destructor
+ */
+//=============================================================================
+
+StdMeshers_Import_1D_i::~StdMeshers_Import_1D_i()
+{
+  MESSAGE( "StdMeshers_Import_1D_i::~StdMeshers_Import_1D_i" );
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_Import_1D_i::GetImpl
+ *
+ *  Get implementation
+ */
+//=============================================================================
+
+::StdMeshers_Import_1D* StdMeshers_Import_1D_i::GetImpl()
+{
+  MESSAGE( "StdMeshers_Import_1D_i::GetImpl" );
+  return ( ::StdMeshers_Import_1D* )myBaseImpl;
+}
+
diff --git a/src/StdMeshers_I/StdMeshers_Import_1D_i.hxx b/src/StdMeshers_I/StdMeshers_Import_1D_i.hxx
new file mode 100644 (file)
index 0000000..eec55f2
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//  File   : StdMeshers_Import_1D_i.hxx
+//  Module : SMESH
+//
+#ifndef _SMESH_Import_1D_I_HXX_
+#define _SMESH_Import_1D_I_HXX_
+
+#include "SMESH_StdMeshers_I.hxx"
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_1D_Algo_i.hxx"
+#include "StdMeshers_Import_1D.hxx"
+
+class STDMESHERS_I_EXPORT StdMeshers_Import_1D_i:
+  public virtual POA_StdMeshers::StdMeshers_Import_1D,
+  public virtual SMESH_1D_Algo_i
+{
+ public:
+  // Constructor
+  StdMeshers_Import_1D_i( PortableServer::POA_ptr thePOA,
+                          int                     theStudyId,
+                          ::SMESH_Gen*            theGenImpl );
+  // Destructor
+  virtual ~StdMeshers_Import_1D_i();
+
+  // Get implementation
+  ::StdMeshers_Import_1D* GetImpl();
+};
+
+#endif
diff --git a/src/StdMeshers_I/StdMeshers_LayerDistribution2D_i.cxx b/src/StdMeshers_I/StdMeshers_LayerDistribution2D_i.cxx
new file mode 100644 (file)
index 0000000..5fd33f4
--- /dev/null
@@ -0,0 +1,90 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes
+//  File   : StdMeshers_LayerDistribution2D_i.cxx
+//  Author : Edward AGAPOV
+//  Module : SMESH
+//
+#include "StdMeshers_LayerDistribution2D_i.hxx"
+
+#include "utilities.h"
+
+//=============================================================================
+/*!
+ *  StdMeshers_LayerDistribution2D_i::StdMeshers_LayerDistribution2D_i
+ *
+ *  Constructor
+ */
+//=============================================================================
+
+StdMeshers_LayerDistribution2D_i::StdMeshers_LayerDistribution2D_i
+                                          (PortableServer::POA_ptr thePOA,
+                                           int                     theStudyId,
+                                           ::SMESH_Gen*            theGenImpl )
+: StdMeshers_LayerDistribution_i(thePOA,theStudyId,theGenImpl),
+  SMESH_Hypothesis_i( thePOA )
+{
+  MESSAGE( "StdMeshers_LayerDistribution2D_i::StdMeshers_LayerDistribution2D_i" );
+  myBaseImpl = new ::StdMeshers_LayerDistribution2D(theGenImpl->GetANewId(),
+                                                    theStudyId,
+                                                    theGenImpl);
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_LayerDistribution2D_i::~StdMeshers_LayerDistribution2D_i
+ *
+ *  Destructor
+ */
+//=============================================================================
+
+StdMeshers_LayerDistribution2D_i::~StdMeshers_LayerDistribution2D_i()
+{
+  MESSAGE("StdMeshers_LayerDistribution2D_i::~StdMeshers_LayerDistribution2D_i");
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_LayerDistribution2D_i::GetImpl
+ *
+ *  Get implementation
+ */
+//=============================================================================
+
+::StdMeshers_LayerDistribution2D* StdMeshers_LayerDistribution2D_i::GetImpl()
+{
+  return ( ::StdMeshers_LayerDistribution2D* )myBaseImpl;
+}
+
+//================================================================================
+/*!
+ * \brief Verify whether hypothesis supports given entity type 
+  * \param type - dimension (see SMESH::Dimension enumeration)
+  * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise
+ * 
+ * Verify whether hypothesis supports given entity type (see SMESH::Dimension enumeration)
+ */
+//================================================================================  
+CORBA::Boolean StdMeshers_LayerDistribution2D_i::IsDimSupported( SMESH::Dimension type )
+{
+  return type == SMESH::DIM_2D;
+}
+
+
diff --git a/src/StdMeshers_I/StdMeshers_LayerDistribution2D_i.hxx b/src/StdMeshers_I/StdMeshers_LayerDistribution2D_i.hxx
new file mode 100644 (file)
index 0000000..25acd65
--- /dev/null
@@ -0,0 +1,61 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//  File   : StdMeshers_LayerDistribution2D_i.hxx
+//  Author : Edward AGAPOV
+//  Module : SMESH
+//
+#ifndef _SMESH_LayerDistribution2D_I_HXX_
+#define _SMESH_LayerDistribution2D_I_HXX_
+
+#include "StdMeshers_LayerDistribution_i.hxx"
+#include "StdMeshers_LayerDistribution2D.hxx"
+
+
+// =========================================================
+/*!
+ * This hypothesis is used by "Radial quadrangle" algorithm.
+ * It specifies 1D hypothesis defining distribution of segments
+ * between the internal and the external surfaces.
+ */
+// =========================================================
+
+class StdMeshers_LayerDistribution2D_i:
+  public virtual POA_StdMeshers::StdMeshers_LayerDistribution2D,
+  public virtual StdMeshers_LayerDistribution_i
+{
+public:
+  // Constructor
+  StdMeshers_LayerDistribution2D_i(PortableServer::POA_ptr thePOA,
+                                   int                     theStudyId,
+                                   ::SMESH_Gen*            theGenImpl );
+  // Destructor
+  virtual ~StdMeshers_LayerDistribution2D_i();
+
+  // Get implementation
+  ::StdMeshers_LayerDistribution2D* GetImpl();
+  
+  // Verify whether hypothesis supports given entity type 
+  CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+
+};
+
+#endif
+
index 53707613c5bdeacf2986f64d5a8fd783ced70c0b..e162f22aa32c593f1e684866a137b9f53e1354f6 100644 (file)
@@ -1,29 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes
 //  File   : StdMeshers_LayerDistribution_i.cxx
 //  Author : Edward AGAPOV
 //  Module : SMESH
-//  $Header$
 //
 #include "StdMeshers_LayerDistribution_i.hxx"
 #include "SMESH_Gen_i.hxx"
@@ -168,9 +168,9 @@ char* StdMeshers_LayerDistribution_i::SaveTo()
   else {
     os << hyp1D->GetName() << " "
        << hyp1D->GetLibName() << " "
-       << hyp1D_i->SaveTo();
+       << hyp1D_i->SaveTo() << " ";
   }
-  //myBaseImpl->SaveTo( os );
+  os << SMESH_Hypothesis_i::SaveTo();  // to have a mark of storage version ("VARS...")
 
   return CORBA::string_dup( os.str().c_str() );
 }
@@ -200,11 +200,14 @@ void StdMeshers_LayerDistribution_i::LoadFrom( const char* theStream )
         gen->CreateHypothesis( typeName.c_str(), libName.c_str() );
       SMESH_Hypothesis_i* hyp1D_i = SMESH::DownCast< SMESH_Hypothesis_i*>( hyp1D );
       if ( hyp1D_i ) {
-        hyp1D_i->LoadFrom( & theStream[ is.tellg() ]);
+        hyp1D_i->LoadFrom( & theStream[ (streamoff) is.tellg()+1 ]);
         this->GetImpl()->SetLayerDistribution( hyp1D_i->GetImpl() );
         myHyp = hyp1D;
         // as hyp1D is not published, its ID changes
         //SMESH::TPythonDump() << _this() << ".SetLayerDistribution( " << hyp1D << " )";
+
+        // restore a mark of storage version ("VARS...")
+        SMESH_Hypothesis_i::LoadFrom( & theStream[ (streamoff)is.tellg()+1 ]);
       }
     }
     catch (...) {
@@ -213,3 +216,14 @@ void StdMeshers_LayerDistribution_i::LoadFrom( const char* theStream )
   }
 }
 
+//================================================================================
+/*!
+ * \brief Restore myMethod2VarParams by parameters stored in an old study
+ */
+//================================================================================
+
+void StdMeshers_LayerDistribution_i::setOldParameters (const char* theParameters)
+{
+  if ( SMESH_Hypothesis_i* hyp1D_i = SMESH::DownCast< SMESH_Hypothesis_i*>( myHyp ))
+    hyp1D_i->setOldParameters( theParameters );
+}
index f08a9d7efa5e869653508ea502379dcb468a9421..78bf71d5a046e7b380e8e9175514801a162c367e 100644 (file)
@@ -1,29 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_LayerDistribution_i.hxx
 //  Author : Edward AGAPOV
 //  Module : SMESH
-//  $Header$
 //
 #ifndef _SMESH_LayerDistribution_I_HXX_
 #define _SMESH_LayerDistribution_I_HXX_
@@ -79,9 +79,12 @@ public:
   virtual char* SaveTo();
   virtual void  LoadFrom( const char* theStream );
 
+protected:
+  // restore myMethod2VarParams by parameters stored in an old study
+  virtual void setOldParameters (const char* theParameters);
+  
 private:
   SMESH::SMESH_Hypothesis_var myHyp;
 };
 
 #endif
-
index 0d78830d6ec6e82d589d9c739880dc1efe20db40..324a9b064768119c7ea04e516aba5e1900b520e9 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_LengthFromEdges_i.cxx
 //           Moved here from SMESH_LengthFromEdges_i.cxx
@@ -43,15 +44,15 @@ using namespace std;
 //=============================================================================
 
 StdMeshers_LengthFromEdges_i::StdMeshers_LengthFromEdges_i( PortableServer::POA_ptr thePOA,
-                                                 int                     theStudyId,
-                                                 ::SMESH_Gen*            theGenImpl )
+                                                  int                     theStudyId,
+                                                  ::SMESH_Gen*            theGenImpl )
      : SALOME::GenericObj_i( thePOA ), 
        SMESH_Hypothesis_i( thePOA )
 {
   MESSAGE( "StdMeshers_LengthFromEdges_i::StdMeshers_LengthFromEdges_i" );
   myBaseImpl = new ::StdMeshers_LengthFromEdges( theGenImpl->GetANewId(),
-                                           theStudyId,
-                                           theGenImpl );
+                                            theStudyId,
+                                            theGenImpl );
 }
 
 //=============================================================================
@@ -85,7 +86,7 @@ void StdMeshers_LengthFromEdges_i::SetMode( CORBA::Long theMode )
   }
   catch ( SALOME_Exception& S_ex ) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
-                                 SALOME::BAD_PARAM );
+                                  SALOME::BAD_PARAM );
   }
 }
 
index 77ebc48adbb5097c10d4c1446101a83564c2dda3..38f50d3dfc48e9a1f9a13ccf4202d230655d2329 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_LengthFromEdges_i.hxx
 //           Moved here from SMESH_LengthFromEdges_i.hxx
index fdc8c1c2755ebaf07becb73ba3fb4bcdbf98fbbe..5d6ec1b51d8aefd701717cff30e5a7b23b60b613 100644 (file)
@@ -1,30 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_LocalLength_i.cxx
 //           Moved here from SMESH_LocalLength_i.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//  $Header$
 //
 #include "StdMeshers_LocalLength_i.hxx"
 #include "SMESH_Gen_i.hxx"
@@ -88,11 +88,11 @@ void StdMeshers_LocalLength_i::SetLength( CORBA::Double theLength )
   }
   catch ( SALOME_Exception& S_ex ) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
-                                 SALOME::BAD_PARAM );
+                                  SALOME::BAD_PARAM );
   }
 
   // Update Python script
-  SMESH::TPythonDump() << _this() << ".SetLength( " << theLength << " )";
+  SMESH::TPythonDump() << _this() << ".SetLength( " << SMESH::TVar(theLength) << " )";
 }
 
 //=============================================================================
@@ -112,11 +112,11 @@ void StdMeshers_LocalLength_i::SetPrecision( CORBA::Double thePrecision )
   }
   catch ( SALOME_Exception& S_ex ) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
-                                 SALOME::BAD_PARAM );
+                                  SALOME::BAD_PARAM );
   }
 
   // Update Python script
-  SMESH::TPythonDump() << _this() << ".SetPrecision( " << thePrecision << " )";
+  SMESH::TPythonDump() << _this() << ".SetPrecision( " << SMESH::TVar(thePrecision) << " )";
 }
 
 //=============================================================================
@@ -173,3 +173,9 @@ CORBA::Boolean StdMeshers_LocalLength_i::IsDimSupported( SMESH::Dimension type )
 {
   return type == SMESH::DIM_1D;
 }
+
+std::string StdMeshers_LocalLength_i::getMethodOfParameter(const int paramIndex,
+                                                           int       /*nbVars*/) const
+{
+  return paramIndex == 0 ? "SetLength" : "SetPrecision";
+}
index e31b08ece54eaa9ad81ccba5f7a0381e63a1dac3..dd2b239e12043245ae83ea2dabe6316c905b4644 100644 (file)
@@ -1,30 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  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_
@@ -71,6 +71,9 @@ public:
   
   // Verify whether hypothesis supports given entity type 
   CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+
+ protected:
+  virtual std::string getMethodOfParameter(const int paramIndex, int nbVars) const;
 };
 
 #endif
index 4731e8888d64f6be713d564fec9009ea71661be7..5eb244e8936b7984f104ce2da4ed94c25e8c93ad 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_MEFISTO_2D_i.cxx
 //           Moved here from SMESH_MEFISTO_2D_i.cxx
@@ -43,8 +44,8 @@ using namespace std;
 //=============================================================================
 
 StdMeshers_MEFISTO_2D_i::StdMeshers_MEFISTO_2D_i( PortableServer::POA_ptr thePOA,
-                                       int                     theStudyId,
-                                       ::SMESH_Gen*            theGenImpl )
+                                        int                     theStudyId,
+                                        ::SMESH_Gen*            theGenImpl )
      : SALOME::GenericObj_i( thePOA ), 
        SMESH_Hypothesis_i( thePOA ), 
        SMESH_Algo_i( thePOA ),
@@ -52,8 +53,8 @@ StdMeshers_MEFISTO_2D_i::StdMeshers_MEFISTO_2D_i( PortableServer::POA_ptr thePOA
 {
   MESSAGE( "StdMeshers_MEFISTO_2D_i::StdMeshers_MEFISTO_2D_i" );
   myBaseImpl = new ::StdMeshers_MEFISTO_2D( theGenImpl->GetANewId(),
-                                      theStudyId,
-                                      theGenImpl );
+                                       theStudyId,
+                                       theGenImpl );
 }
 
 //=============================================================================
index f368c76c5ffb210ddc523a94d4c20439e9a5b53e..3700c7cea15d243cdb5a0f58853f6ae1a32254f3 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_MEFISTO_2D_i.hxx
 //           Moved here from SMESH_MEFISTO_2D_i.hxx
@@ -50,7 +51,7 @@ public:
   // Constructor
   StdMeshers_MEFISTO_2D_i( PortableServer::POA_ptr thePOA,
                       int                     theStudyId,
-                     ::SMESH_Gen*            theGenImpl );
+                      ::SMESH_Gen*            theGenImpl );
 
   // Destructor
   virtual ~StdMeshers_MEFISTO_2D_i();
index 8a81691353054fa03476dad2b32732d3f753229b..7af8090bc73acd4843d80223a36d1e0bae2c9465 100644 (file)
@@ -1,30 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_MaxElementArea_i.cxx
 //           Moved here from SMESH_MaxElementArea_i.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//  $Header$
 //
 #include "StdMeshers_MaxElementArea_i.hxx"
 #include "SMESH_Gen_i.hxx"
@@ -47,15 +47,15 @@ using namespace std;
 //=============================================================================
 
 StdMeshers_MaxElementArea_i::StdMeshers_MaxElementArea_i( PortableServer::POA_ptr thePOA,
-                                               int                     theStudyId,
-                                               ::SMESH_Gen*            theGenImpl )
+                                                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 );
+                                           theStudyId,
+                                           theGenImpl );
 }
 
 //=============================================================================
@@ -89,11 +89,11 @@ void StdMeshers_MaxElementArea_i::SetMaxElementArea( CORBA::Double theArea )
   }
   catch (SALOME_Exception& S_ex) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
-                                 SALOME::BAD_PARAM );
+                                  SALOME::BAD_PARAM );
   }
 
   // Update Python script
-  SMESH::TPythonDump() << _this() << ".SetMaxElementArea( " << theArea << " )";
+  SMESH::TPythonDump() << _this() << ".SetMaxElementArea( " << SMESH::TVar(theArea) << " )";
 }
 
 //=============================================================================
@@ -139,3 +139,14 @@ CORBA::Boolean StdMeshers_MaxElementArea_i::IsDimSupported( SMESH::Dimension typ
   return type == SMESH::DIM_2D;
 }
 
+//================================================================================
+/*!
+ * \brief Return method name corresponding to index of variable parameter
+ */
+//================================================================================
+
+std::string StdMeshers_MaxElementArea_i::getMethodOfParameter(const int paramIndex,
+                                                              int       /*nbVars*/) const
+{
+  return "SetMaxElementArea";
+}
index 199c4bb4b2428939f4c82b75ce90ca4e0aca40a9..51e6033b9afbd252ec23c8bfb4c255b0ad587062 100644 (file)
@@ -1,30 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_MaxElementArea_i.hxx
 //           Moved here from SMESH_MaxElementArea_i.hxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//  $Header$
 //
 #ifndef _SMESH_MAXELEMENTAREA_I_HXX_
 #define _SMESH_MAXELEMENTAREA_I_HXX_
@@ -48,7 +48,7 @@ public:
   // Constructor
   StdMeshers_MaxElementArea_i( PortableServer::POA_ptr thePOA,
                           int                     theStudyId,
-                         ::SMESH_Gen*            theGenImpl );
+                          ::SMESH_Gen*            theGenImpl );
   // Destructor
   virtual ~StdMeshers_MaxElementArea_i();
 
@@ -63,6 +63,9 @@ public:
   
   // Verify whether hypothesis supports given entity type 
   CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+
+ protected:
+  virtual std::string getMethodOfParameter(const int paramIndex, int nbVars) const;
 };
 
 #endif
index 7ee1eefdca44f39ce868e76c61800ee06410b13c..a9e8b657dcfd32f3d2623065d6d5a386ac0a50f0 100644 (file)
@@ -1,30 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_MaxElementVolume_i.cxx
 //           Moved here from SMESH_MaxElementVolume_i.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//  $Header$
 //
 #include "StdMeshers_MaxElementVolume_i.hxx"
 #include "SMESH_Gen_i.hxx"
@@ -47,15 +47,15 @@ using namespace std;
 //=============================================================================
 
 StdMeshers_MaxElementVolume_i::StdMeshers_MaxElementVolume_i( PortableServer::POA_ptr thePOA,
-                                                   int                     theStudyId,
-                                                   ::SMESH_Gen*            theGenImpl )
+                                                    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 );
+                                             theStudyId,
+                                             theGenImpl );
 }
 
 //=============================================================================
@@ -89,11 +89,11 @@ void StdMeshers_MaxElementVolume_i::SetMaxElementVolume( CORBA::Double theVolume
   }
   catch (SALOME_Exception& S_ex) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
-                                 SALOME::BAD_PARAM );
+                                  SALOME::BAD_PARAM );
   }
 
   // Update Python script
-  SMESH::TPythonDump() << _this() << ".SetMaxElementVolume( " << theVolume << " )";
+  SMESH::TPythonDump() << _this() << ".SetMaxElementVolume( " << SMESH::TVar(theVolume) << " )";
 }
 
 //=============================================================================
@@ -139,3 +139,13 @@ CORBA::Boolean StdMeshers_MaxElementVolume_i::IsDimSupported( SMESH::Dimension t
   return type == SMESH::DIM_3D;
 }
 
+//================================================================================
+/*!
+ * \brief Return method name corresponding to index of variable parameter
+ */
+//================================================================================
+
+std::string StdMeshers_MaxElementVolume_i::getMethodOfParameter(const int, int) const
+{
+  return "SetMaxElementVolume";
+}
index a01df54448f3413b39c5d47e065f9078a7da1f42..829097c4d2edb5b066b7fdfdb14383a4f10e51c8 100644 (file)
@@ -1,30 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_MaxElementVolume_i.hxx
 //           Moved here from SMESH_MaxElementVolume_i.hxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//  $Header$
 //
 #ifndef _SMESH_MAXELEMENTVOLUME_I_HXX_
 #define _SMESH_MAXELEMENTVOLUME_I_HXX_
@@ -63,6 +63,9 @@ public:
   
   // Verify whether hypothesis supports given entity type 
   CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+
+ protected:
+  virtual std::string getMethodOfParameter(const int paramIndex, int nbVars) const;
 };
 
 #endif
index bbed6c448ac82f49f3542fccfaa426c7e0c494a5..5ce5b34f9ea796be669249fbe66707f3a4834b81 100644 (file)
@@ -1,27 +1,26 @@
-//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
 //
-//  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.com
 //
+
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_MaxLength_i.cxx
 //  Module : SMESH
-
+//
 #include "StdMeshers_MaxLength_i.hxx"
 #include "SMESH_Gen_i.hxx"
 #include "SMESH_Gen.hxx"
@@ -81,11 +80,11 @@ void StdMeshers_MaxLength_i::SetLength( CORBA::Double theLength )
   }
   catch ( SALOME_Exception& S_ex ) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
-                                 SALOME::BAD_PARAM );
+                                  SALOME::BAD_PARAM );
   }
 
   // Update Python script
-  SMESH::TPythonDump() << _this() << ".SetLength( " << theLength << " )";
+  SMESH::TPythonDump() << _this() << ".SetLength( " << SMESH::TVar(theLength) << " )";
 }
 
 //=============================================================================
@@ -102,7 +101,7 @@ void StdMeshers_MaxLength_i::SetUsePreestimatedLength( CORBA::Boolean toUse )
   }
   catch ( SALOME_Exception& S_ex ) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
-                                 SALOME::BAD_PARAM );
+                                  SALOME::BAD_PARAM );
   }
 
   // this is an internal kitchen call - no Python dump
@@ -123,7 +122,7 @@ void StdMeshers_MaxLength_i::SetPreestimatedLength( CORBA::Double theLength )
   }
   catch ( SALOME_Exception& S_ex ) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
-                                 SALOME::BAD_PARAM );
+                                  SALOME::BAD_PARAM );
   }
   // this is an internal kitchen call - no Python dump
   // Update Python script
@@ -202,3 +201,14 @@ CORBA::Boolean StdMeshers_MaxLength_i::IsDimSupported( SMESH::Dimension type )
 {
   return type == SMESH::DIM_1D;
 }
+
+//================================================================================
+/*!
+ * \brief Return method name corresponding to index of variable parameter
+ */
+//================================================================================
+
+std::string StdMeshers_MaxLength_i::getMethodOfParameter(const int, int) const
+{
+  return "SetLength";
+}
index 715da7a239b368586733d0faa8dd061399c6c13c..f088f7895d71b6ed681d38e402aca4db492d05ed 100644 (file)
@@ -1,27 +1,26 @@
-//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
 //
-//  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.com
 //
+
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_MaxLength_i.hxx
 //  Module : SMESH
-
+//
 #ifndef _SMESH_MaxLength_I_HXX_
 #define _SMESH_MaxLength_I_HXX_
 
@@ -78,6 +77,9 @@ public:
   
   // Verify whether hypothesis supports given entity type 
   CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+
+ protected:
+  virtual std::string getMethodOfParameter(const int paramIndex, int nbVars) const;
 };
 
 #endif
index 59f13b891b2742827ab627ccc0dd0568cb69b9fb..78831a397345d180aa12260ee6ed0738479a5f83 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH StdMeshers_I : idl implementation based on 'SMESH' unit's classes
 //  File   : StdMeshers_NotConformAllowed_i.cxx
 //  Author : Paul RASCLE, EDF
index be9f764c26bfffb7114e5df2301ae0f252640250..862baae579ae4aae3e5bad7f3d64cdfeaf520dde 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH StdMeshers_I : idl implementation based on 'SMESH' unit's classes
 //  File   : StdMeshers_NotConformAllowed_i.hxx
 //  Author : Paul RASCLE, EDF
diff --git a/src/StdMeshers_I/StdMeshers_NumberOfLayers2D_i.cxx b/src/StdMeshers_I/StdMeshers_NumberOfLayers2D_i.cxx
new file mode 100644 (file)
index 0000000..e4e5a1e
--- /dev/null
@@ -0,0 +1,88 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes
+//  File   : StdMeshers_NumberOfLayers2D_i.cxx
+//  Author : Edward AGAPOV
+//  Module : SMESH
+//
+#include "StdMeshers_NumberOfLayers2D_i.hxx"
+
+#include "utilities.h"
+
+//=============================================================================
+/*!
+ *  StdMeshers_NumberOfLayers2D_i::StdMeshers_NumberOfLayers2D_i
+ *
+ *  Constructor
+ */
+//=============================================================================
+
+StdMeshers_NumberOfLayers2D_i::StdMeshers_NumberOfLayers2D_i
+                                           (PortableServer::POA_ptr thePOA,
+                                            int                     theStudyId,
+                                            ::SMESH_Gen*            theGenImpl)
+: StdMeshers_NumberOfLayers_i(thePOA,theStudyId,theGenImpl),
+  SMESH_Hypothesis_i( thePOA )
+{
+  MESSAGE("StdMeshers_NumberOfLayers2D_i::StdMeshers_NumberOfLayers2D_i");
+  myBaseImpl = new ::StdMeshers_NumberOfLayers2D(theGenImpl->GetANewId(),
+                                                 theStudyId,
+                                                 theGenImpl);
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_NumberOfLayers2D_i::~StdMeshers_NumberOfLayers2D_i
+ *
+ *  Destructor
+ */
+//=============================================================================
+
+StdMeshers_NumberOfLayers2D_i::~StdMeshers_NumberOfLayers2D_i()
+{
+  MESSAGE( "StdMeshers_NumberOfLayers2D_i::~StdMeshers_NumberOfLayers2D_i" );
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_NumberOfLayers2D_i::GetImpl
+ *
+ *  Get implementation
+ */
+//=============================================================================
+
+::StdMeshers_NumberOfLayers2D* StdMeshers_NumberOfLayers2D_i::GetImpl()
+{
+  return ( ::StdMeshers_NumberOfLayers2D* )myBaseImpl;
+}
+
+//================================================================================
+/*!
+ * \brief Verify whether hypothesis supports given entity type 
+  * \param type - dimension (see SMESH::Dimension enumeration)
+  * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise
+ * 
+ * Verify whether hypothesis supports given entity type (see SMESH::Dimension enumeration)
+ */
+//================================================================================  
+CORBA::Boolean StdMeshers_NumberOfLayers2D_i::IsDimSupported( SMESH::Dimension type )
+{
+  return type == SMESH::DIM_2D;
+}
diff --git a/src/StdMeshers_I/StdMeshers_NumberOfLayers2D_i.hxx b/src/StdMeshers_I/StdMeshers_NumberOfLayers2D_i.hxx
new file mode 100644 (file)
index 0000000..ae68459
--- /dev/null
@@ -0,0 +1,58 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//  File   : StdMeshers_NumberOfLayers2D_i.hxx
+//  Author : Edward AGAPOV
+//  Module : SMESH
+//
+#ifndef _SMESH_NumberOfLayers2D_I_HXX_
+#define _SMESH_NumberOfLayers2D_I_HXX_
+
+#include "StdMeshers_NumberOfLayers2D.hxx"
+#include "StdMeshers_NumberOfLayers_i.hxx"
+
+// =========================================================
+/*!
+ * This hypothesis is used by "Radial quadrangle" algorithm.
+ * It specifies number of segments between the internal 
+ * and the external surfaces.
+ */
+// =========================================================
+
+class StdMeshers_NumberOfLayers2D_i:
+  public virtual POA_StdMeshers::StdMeshers_NumberOfLayers2D,
+  public virtual StdMeshers_NumberOfLayers_i
+{
+public:
+  // Constructor
+  StdMeshers_NumberOfLayers2D_i( PortableServer::POA_ptr thePOA,
+                                 int                     theStudyId,
+                                 ::SMESH_Gen*            theGenImpl );
+  // Destructor
+  virtual ~StdMeshers_NumberOfLayers2D_i();
+
+  // Get implementation
+  ::StdMeshers_NumberOfLayers2D* GetImpl();
+  
+  // Verify whether hypothesis supports given entity type 
+  CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+};
+
+#endif
index 9779cfbdb0ac7bf80afca6c8d74587f3af4634e8..8c12ab72780927793819747922ab5b9bba451679 100644 (file)
@@ -1,29 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes
 //  File   : StdMeshers_NumberOfLayers_i.cxx
 //  Author : Edward AGAPOV
 //  Module : SMESH
-//  $Header$
 //
 #include "StdMeshers_NumberOfLayers_i.hxx"
 #include "SMESH_Gen_i.hxx"
@@ -89,7 +89,7 @@ void StdMeshers_NumberOfLayers_i::SetNumberOfLayers(CORBA::Long numberOfLayers)
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM );
   }
   // Update Python script
-  SMESH::TPythonDump() << _this() << ".SetNumberOfLayers( " << numberOfLayers << " )";
+  SMESH::TPythonDump() << _this() << ".SetNumberOfLayers( " << SMESH::TVar(numberOfLayers) << " )";
 }
 
 //=============================================================================
@@ -133,3 +133,13 @@ CORBA::Boolean StdMeshers_NumberOfLayers_i::IsDimSupported( SMESH::Dimension typ
   return type == SMESH::DIM_3D;
 }
 
+//================================================================================
+/*!
+ * \brief Return method name corresponding to index of variable parameter
+ */
+//================================================================================
+
+std::string StdMeshers_NumberOfLayers_i::getMethodOfParameter(const int, int) const
+{
+  return "SetNumberOfLayers";
+}
index 3d926b03b066d19673c137a5d96cc3c9c1edf95a..cf8b1bcb2c882ebb2448d9a52907f450d073e83a 100644 (file)
@@ -1,29 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_NumberOfLayers_i.hxx
 //  Author : Edward AGAPOV
 //  Module : SMESH
-//  $Header$
 //
 #ifndef _SMESH_NumberOfLayers_I_HXX_
 #define _SMESH_NumberOfLayers_I_HXX_
@@ -68,7 +68,9 @@ public:
   
   // Verify whether hypothesis supports given entity type 
   CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+
+ protected:
+  virtual std::string getMethodOfParameter(const int paramIndex, int nbVars) const;
 };
 
 #endif
-
index 7b2d215a5f5fcdee169c1322aaafd62d777c114d..d0195c9a769a20943bb8116f70ba70d8b1ea1af3 100644 (file)
@@ -1,30 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_NumberOfSegments_i.cxx
 //           Moved here from SMESH_NumberOfSegments_i.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//  $Header$
 //
 #include "StdMeshers_NumberOfSegments_i.hxx"
 #include "SMESH_Gen_i.hxx"
@@ -46,15 +46,15 @@ using namespace std;
 //=============================================================================
 
 StdMeshers_NumberOfSegments_i::StdMeshers_NumberOfSegments_i( PortableServer::POA_ptr thePOA,
-                                                   int                     theStudyId,
-                                                   ::SMESH_Gen*            theGenImpl )
+                                                    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 );
+                                             theStudyId,
+                                             theGenImpl );
 }
 
 //=============================================================================
@@ -78,8 +78,8 @@ StdMeshers_NumberOfSegments_i::~StdMeshers_NumberOfSegments_i()
  */
 //=============================================================================
 SMESH::double_array* StdMeshers_NumberOfSegments_i::BuildDistributionExpr( const char* func, 
-                                                                          CORBA::Long nbSeg, 
-                                                                          CORBA::Long conv )
+                                                                           CORBA::Long nbSeg, 
+                                                                           CORBA::Long conv )
   throw ( SALOME::SALOME_Exception )
 {
   ASSERT( myBaseImpl );
@@ -99,8 +99,8 @@ SMESH::double_array* StdMeshers_NumberOfSegments_i::BuildDistributionExpr( const
 }
 
 SMESH::double_array* StdMeshers_NumberOfSegments_i::BuildDistributionTab( const SMESH::double_array& func,
-                                                                         CORBA::Long nbSeg, 
-                                                                         CORBA::Long conv )
+                                                                          CORBA::Long nbSeg, 
+                                                                          CORBA::Long conv )
   throw ( SALOME::SALOME_Exception )
 {
   ASSERT( myBaseImpl );
@@ -141,11 +141,11 @@ void StdMeshers_NumberOfSegments_i::SetNumberOfSegments( CORBA::Long theSegments
   }
   catch (SALOME_Exception& S_ex) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
-                                 SALOME::BAD_PARAM );
+                                  SALOME::BAD_PARAM );
   }
 
   // Update Python script
-  SMESH::TPythonDump() << _this() << ".SetNumberOfSegments( " << theSegmentsNumber << " )";
+  SMESH::TPythonDump() << _this() << ".SetNumberOfSegments( " << SMESH::TVar(theSegmentsNumber) << " )";
 }
 
 //=============================================================================
@@ -162,6 +162,101 @@ CORBA::Long StdMeshers_NumberOfSegments_i::GetNumberOfSegments()
   return this->GetImpl()->GetNumberOfSegments();
 }
 
+//=============================================================================
+/*!
+ *  StdMeshers_NumberOfSegments_i::SetReversedEdges
+ *
+ *  Set edges to reverse
+ */
+//=============================================================================
+
+void StdMeshers_NumberOfSegments_i::SetReversedEdges( const SMESH::long_array& theIds )
+{
+  ASSERT( myBaseImpl );
+  try {
+    std::vector<int> ids( theIds.length() );
+    CORBA::Long iEnd = theIds.length();
+    for ( CORBA::Long i = 0; i < iEnd; i++ )
+      ids[ i ] = theIds[ i ];
+
+    this->GetImpl()->SetReversedEdges( ids );
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
+                                  SALOME::BAD_PARAM );
+  }
+
+  // Update Python script
+  SMESH::TPythonDump() << _this() << ".SetReversedEdges( " << theIds << " )";
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_NumberOfSegments_i::SetObjectEntry
+ *
+ *  Set the Entry for the Main Object
+ */
+//=============================================================================
+
+void StdMeshers_NumberOfSegments_i::SetObjectEntry( const char* theEntry )
+{
+  ASSERT( myBaseImpl );
+  string entry(theEntry); // actually needed as theEntry is spoiled by moment of dumping
+  try {
+    this->GetImpl()->SetObjectEntry( entry.c_str() );
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
+                                  SALOME::BAD_PARAM );
+  }
+  // Update Python script
+  SMESH::TPythonDump() << _this() << ".SetObjectEntry( \"" << entry.c_str() << "\" )";
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_NumberOfSegments_i::GetObjectEntry
+ *
+ *  Set the Entry for the Main Object
+ */
+//=============================================================================
+
+char* StdMeshers_NumberOfSegments_i::GetObjectEntry()
+{
+  ASSERT( myBaseImpl );
+
+  const char* entry;
+  try {
+    entry = this->GetImpl()->GetObjectEntry();
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
+                                  SALOME::BAD_PARAM );
+  }
+  return CORBA::string_dup( entry );
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_NumberOfSegments_i::GetReversedEdges
+ *
+ *  Get reversed edges
+ */
+//=============================================================================
+
+SMESH::long_array* StdMeshers_NumberOfSegments_i::GetReversedEdges()
+{
+  MESSAGE( "StdMeshers_NumberOfSegments_i::GetReversedEdges" );
+  ASSERT( myBaseImpl );
+  SMESH::long_array_var anArray = new SMESH::long_array;
+  std::vector<int> ids = this->GetImpl()->GetReversedEdges();
+  anArray->length( ids.size() );
+  for ( CORBA::Long i = 0; i < ids.size(); i++)
+    anArray [ i ] = ids [ i ];
+
+  return anArray._retn();
+}
+
 //=============================================================================
 /*!
  */
@@ -179,7 +274,7 @@ void StdMeshers_NumberOfSegments_i::SetDistrType(CORBA::Long typ)
   }
   catch ( SALOME_Exception& S_ex ) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
-                                 SALOME::BAD_PARAM );
+                                  SALOME::BAD_PARAM );
   }
 }
 
@@ -209,11 +304,11 @@ void StdMeshers_NumberOfSegments_i::SetScaleFactor( CORBA::Double theScaleFactor
   try {
     this->GetImpl()->SetScaleFactor( theScaleFactor );
     // Update Python script
-    SMESH::TPythonDump() << _this() << ".SetScaleFactor( " << theScaleFactor << " )";
+    SMESH::TPythonDump() << _this() << ".SetScaleFactor( " << SMESH::TVar(theScaleFactor) << " )";
   }
   catch ( SALOME_Exception& S_ex ) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
-                                 SALOME::BAD_PARAM );
+                                  SALOME::BAD_PARAM );
   }
 }
 
@@ -235,7 +330,7 @@ CORBA::Double StdMeshers_NumberOfSegments_i::GetScaleFactor()
   }
   catch ( SALOME_Exception& S_ex ) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
-                                 SALOME::BAD_PARAM );
+                                  SALOME::BAD_PARAM );
   }
   return scale;
 }
@@ -259,7 +354,7 @@ void StdMeshers_NumberOfSegments_i::SetTableFunction(const SMESH::double_array&
   }
   catch ( SALOME_Exception& S_ex ) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
-                                 SALOME::BAD_PARAM );
+                                  SALOME::BAD_PARAM );
   }
 }
 
@@ -278,7 +373,7 @@ SMESH::double_array* StdMeshers_NumberOfSegments_i::GetTableFunction()
   }
   catch ( SALOME_Exception& S_ex ) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
-                                 SALOME::BAD_PARAM );
+                                  SALOME::BAD_PARAM );
   }
   SMESH::double_array_var aRes = new SMESH::double_array();
   aRes->length(tbl->size());
@@ -303,7 +398,7 @@ void StdMeshers_NumberOfSegments_i::SetExpressionFunction(const char* expr)
   }
   catch ( SALOME_Exception& S_ex ) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
-                                 SALOME::BAD_PARAM );
+                                  SALOME::BAD_PARAM );
   }
 }
 
@@ -322,7 +417,7 @@ char* StdMeshers_NumberOfSegments_i::GetExpressionFunction()
   }
   catch ( SALOME_Exception& S_ex ) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
-                                 SALOME::BAD_PARAM );
+                                  SALOME::BAD_PARAM );
   }
   return CORBA::string_dup(expr);
 }
@@ -343,7 +438,7 @@ void StdMeshers_NumberOfSegments_i::SetConversionMode(CORBA::Long conv )
   }
   catch ( SALOME_Exception& S_ex ) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
-                                 SALOME::BAD_PARAM );
+                                  SALOME::BAD_PARAM );
   }
 }
 
@@ -362,7 +457,7 @@ CORBA::Long StdMeshers_NumberOfSegments_i::ConversionMode()
   }
   catch ( SALOME_Exception& S_ex ) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
-                                 SALOME::BAD_PARAM );
+                                  SALOME::BAD_PARAM );
   }
   return conv;
 }
@@ -394,3 +489,13 @@ CORBA::Boolean StdMeshers_NumberOfSegments_i::IsDimSupported( SMESH::Dimension t
   return type == SMESH::DIM_1D;
 }
 
+//================================================================================
+/*!
+ * \brief Return method name corresponding to index of variable parameter
+ */
+//================================================================================
+
+std::string StdMeshers_NumberOfSegments_i::getMethodOfParameter(const int paramIndex, int ) const
+{
+  return paramIndex == 0 ? "SetNumberOfSegments" : "SetScaleFactor";
+}
index 208a59b0b0d404b33311688e77b04b749ac61961..3745a736ce8ecf75f18deaff920313f99da7a1c1 100644 (file)
@@ -1,30 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_NumberOfSegments_i.hxx
 //           Moved here from SMESH_NumberOfSegments_i.hxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//  $Header$
 //
 #ifndef _SMESH_NUMBEROFSEGMENTS_I_HXX_
 #define _SMESH_NUMBEROFSEGMENTS_I_HXX_
@@ -49,7 +49,7 @@ public:
   // Constructor
   StdMeshers_NumberOfSegments_i( PortableServer::POA_ptr thePOA,
                             int                     theStudyId,
-                           ::SMESH_Gen*            theGenImpl );
+                            ::SMESH_Gen*            theGenImpl );
   // Destructor
   virtual ~StdMeshers_NumberOfSegments_i();
 
@@ -104,6 +104,21 @@ public:
   
   // Verify whether hypothesis supports given entity type 
   CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+
+  //Set Reversed Edges
+  void SetReversedEdges( const SMESH::long_array& theIDs);
+
+  //Get Reversed Edges
+  SMESH::long_array*  GetReversedEdges();
+
+  //Set Object Entry
+  void SetObjectEntry( const char* entry);
+
+  //Get Object Entry
+  char* GetObjectEntry();
+
+ protected:
+  virtual std::string getMethodOfParameter(const int paramIndex, int nbVars) const;
 };
 
 #endif
index 53330557b72f55d0af148e60b5e69a4b2c0aa637..910d0aaa870d886314d0a6cd276ee3d0405a7ff7 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 // File      : StdMeshers_ObjRefUlils.cxx
 // Created   : Wed Oct 18 15:38:22 2006
 
 using namespace std;
 
+//=======================================================================
+//function : GeomObjectToEntry
+//purpose  : Return study entry of GEOM Object
+//=======================================================================
+
+std::string StdMeshers_ObjRefUlils::GeomObjectToEntry(GEOM::GEOM_Object_ptr&  theGeomObject)
+{
+  if ( CORBA::is_nil( theGeomObject ))
+    return "NULL_OBJECT";
+
+  CORBA::String_var entry = theGeomObject->GetStudyEntry();
+  return entry.in();
+}
+
+//=======================================================================
+//function : EntryOrShapeToGeomObject
+//purpose  :  Return GEOM Object by its sytudy entry or TopoDS_Shape
+//=======================================================================
+
+GEOM::GEOM_Object_ptr
+StdMeshers_ObjRefUlils::EntryOrShapeToGeomObject (const std::string&  theEntry,
+                                                  const TopoDS_Shape& theShape)
+{
+  GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_nil();
+
+  // try by entry
+  if (SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen()) {
+    SALOMEDS::Study_var study = gen->GetCurrentStudy();
+    if ( ! theEntry.empty() && ! study->_is_nil() ) {
+      SALOMEDS::SObject_var sobj= study->FindObjectID( theEntry.c_str() );
+      CORBA::Object_var obj = gen->SObjectToObject( sobj );
+      geom = GEOM::GEOM_Object::_narrow( obj );
+    }
+  }
+  // try by TopoDS_Shape
+  if ( geom->_is_nil() )
+    geom = ShapeToGeomObject( theShape );
+
+  return geom._retn();
+}
+
 //================================================================================
   /*!
    * \brief Store the shape in the stream
@@ -103,3 +145,17 @@ void StdMeshers_ObjRefUlils::SaveToStream( CORBA::Object_ptr obj,
   if ( ! ok )
     stream << " NULL_OBJECT ";
 }
+
+//=======================================================================
+//function : SaveToStream
+//purpose  : Store the study entry of object in the stream
+//=======================================================================
+
+void StdMeshers_ObjRefUlils::SaveToStream( const std::string& studyEntry,
+                                           std::ostream &     stream)
+{
+  if ( studyEntry.find_first_not_of( ' ' ) == std::string::npos )
+    stream << " NULL_OBJECT ";
+  else
+    stream << " " << studyEntry;
+}
index 4556810cfe75cd43982a5149db512e0a775dd61d..2f13689c1da73f726b350658b136010df6eaadb8 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 // File      : StdMeshers_ObjRefUlils.hxx
 // Created   : Wed Oct 18 15:15:27 2006
@@ -64,6 +65,18 @@ public:
        return TopoDS_Shape();
   }
 
+  /*!
+   * \brief Return study entry of GEOM Object
+   */
+  static std::string GeomObjectToEntry(GEOM::GEOM_Object_ptr&  theGeomObject);
+
+  /*!
+   * \brief Return GEOM Object by its study entry or TopoDS_Shape
+   */
+  static GEOM::GEOM_Object_ptr EntryOrShapeToGeomObject (const std::string&  theEntry,
+                                                         const TopoDS_Shape& theShape);
+
+
   /*!
    * \brief Store the shape in the stream
     * \param theShape - shape to store
@@ -76,14 +89,14 @@ public:
     * \param stream - the stream
     * \retval TopoDS_Shape - resulting shape
    */
-  static TopoDS_Shape LoadFromStream( std::istream & stream);
+  static TopoDS_Shape LoadFromStream( std::istream & stream );
 
   /*!
    * \brief Store the CORBA object in the stream
     * \param obj - object to store
     * \param stream - the stream
    */
-  static void SaveToStream( CORBA::Object_ptr obj, std::ostream & stream);
+  static void SaveToStream( CORBA::Object_ptr obj, std::ostream & stream );
 
   /*!
    * \brief Retrieve a CORBA object from the stream 
@@ -106,6 +119,14 @@ public:
     }
     return TInterface::_nil();
   }
+
+  /*!
+   * \brief Store the study entry of object in the stream
+    * \param studyEntry - the study entry
+    * \param stream - the stream
+   */
+  static void SaveToStream( const std::string& studyEntry, std::ostream & stream);
+
 };
 
 #endif
index f6e2a3f70189b98a9f7fd3ad17c66376374d6609..4daffc4a4fbd135e551ba25a9a70e3d9357372e4 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_Prism_3D_i.cxx
 //           Moved here from SMESH_Prism_3D_i.cxx
@@ -41,8 +42,8 @@ using namespace std;
 //=============================================================================
 
 StdMeshers_Prism_3D_i::StdMeshers_Prism_3D_i( PortableServer::POA_ptr thePOA,
-                                 int                     theStudyId,
-                                 ::SMESH_Gen*            theGenImpl )
+                                  int                     theStudyId,
+                                  ::SMESH_Gen*            theGenImpl )
      : SALOME::GenericObj_i( thePOA ), 
        SMESH_Hypothesis_i( thePOA ), 
        SMESH_Algo_i( thePOA ),
@@ -75,8 +76,8 @@ StdMeshers_Prism_3D_i::~StdMeshers_Prism_3D_i()
 //=============================================================================
 
 StdMeshers_RadialPrism_3D_i::StdMeshers_RadialPrism_3D_i( PortableServer::POA_ptr thePOA,
-                                 int                     theStudyId,
-                                 ::SMESH_Gen*            theGenImpl )
+                                  int                     theStudyId,
+                                  ::SMESH_Gen*            theGenImpl )
      : SALOME::GenericObj_i( thePOA ), 
        SMESH_Hypothesis_i( thePOA ), 
        SMESH_Algo_i( thePOA ),
@@ -84,8 +85,8 @@ StdMeshers_RadialPrism_3D_i::StdMeshers_RadialPrism_3D_i( PortableServer::POA_pt
 {
   MESSAGE( "StdMeshers_RadialPrism_3D_i::StdMeshers_RadialPrism_3D_i" );
   myBaseImpl = new ::StdMeshers_RadialPrism_3D( theGenImpl->GetANewId(),
-                                   theStudyId,
-                                   theGenImpl );
+                                    theStudyId,
+                                    theGenImpl );
 }
 //-----------------------------------------------------------------------------
 
index fc09a08db0a115f915eb1b40624e2115ce03324e..c7d179c098cc3907af7cbce2e1851b21c4e89c9b 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_Prism_3D_i.hxx
 //           Moved here from SMESH_Prism_3D_i.hxx
index 62d7d7af7503fee9276ee86019a8011033486c14..092e9b45122fc9836c2f071bf0fb06f21217b80b 100644 (file)
@@ -1,29 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes
 //  File   : StdMeshers_ProjectionSource1D_i.cxx
 //  Author : Edward AGAPOV
 //  Module : SMESH
-//  $Header$
 //
 #include "StdMeshers_ProjectionSource1D_i.hxx"
 
@@ -83,6 +83,8 @@ void StdMeshers_ProjectionSource1D_i::SetSourceEdge(GEOM::GEOM_Object_ptr edge)
   ASSERT( myBaseImpl );
   try {
     this->GetImpl()->SetSourceEdge( StdMeshers_ObjRefUlils::GeomObjectToShape( edge ));
+    CORBA::String_var entry = edge->GetStudyEntry();
+    myShapeEntries[ SRC_EDGE ] = entry.in();
   }
   catch ( SALOME_Exception& S_ex ) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM );
@@ -107,6 +109,9 @@ void StdMeshers_ProjectionSource1D_i::SetVertexAssociation(GEOM::GEOM_Object_ptr
     TopoDS_Shape v1 = StdMeshers_ObjRefUlils::GeomObjectToShape( sourceVertex );
     TopoDS_Shape v2 = StdMeshers_ObjRefUlils::GeomObjectToShape( targetVertex );
     this->GetImpl()->SetVertexAssociation( v1, v2 );
+
+    myShapeEntries[ SRC_VERTEX ] = StdMeshers_ObjRefUlils::GeomObjectToEntry( sourceVertex );
+    myShapeEntries[ TGT_VERTEX ] = StdMeshers_ObjRefUlils::GeomObjectToEntry( targetVertex );
   }
   catch ( SALOME_Exception& S_ex ) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM );
@@ -171,7 +176,9 @@ SMESH::SMESH_Mesh_ptr StdMeshers_ProjectionSource1D_i::GetSourceMesh()
 GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource1D_i::GetSourceEdge()
 {
   ASSERT( myBaseImpl );
-  return StdMeshers_ObjRefUlils::ShapeToGeomObject( this->GetImpl()->GetSourceEdge() );
+  return StdMeshers_ObjRefUlils::EntryOrShapeToGeomObject
+    ( myShapeEntries[ SRC_EDGE ],
+      this->GetImpl()->GetSourceEdge() );
 }
 
 //=============================================================================
@@ -184,7 +191,9 @@ GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource1D_i::GetSourceEdge()
 GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource1D_i::GetSourceVertex()
 {
   ASSERT( myBaseImpl );
-  return StdMeshers_ObjRefUlils::ShapeToGeomObject( this->GetImpl()->GetSourceVertex() );
+  return StdMeshers_ObjRefUlils::EntryOrShapeToGeomObject
+    ( myShapeEntries[ SRC_VERTEX ],
+      this->GetImpl()->GetSourceVertex() );
 }
 
 //=============================================================================
@@ -197,7 +206,9 @@ GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource1D_i::GetSourceVertex()
 GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource1D_i::GetTargetVertex()
 {
   ASSERT( myBaseImpl );
-  return StdMeshers_ObjRefUlils::ShapeToGeomObject( this->GetImpl()->GetTargetVertex() );
+  return StdMeshers_ObjRefUlils::EntryOrShapeToGeomObject
+    ( myShapeEntries[ TGT_VERTEX ],
+      this->GetImpl()->GetTargetVertex() );
 }
 
 //=============================================================================
@@ -239,12 +250,8 @@ char* StdMeshers_ProjectionSource1D_i::SaveTo()
   ASSERT( myBaseImpl );
   std::ostringstream os;
 
-  TopoDS_Shape s1, s2, s3;
-  GetImpl()->GetStoreParams( s1, s2, s3 );
-
-  StdMeshers_ObjRefUlils::SaveToStream( s1, os );
-  StdMeshers_ObjRefUlils::SaveToStream( s2, os );
-  StdMeshers_ObjRefUlils::SaveToStream( s3, os );
+  for ( int i = 0; i < NB_SHAPES; ++i )
+    StdMeshers_ObjRefUlils::SaveToStream( myShapeEntries[ i ], os );
   StdMeshers_ObjRefUlils::SaveToStream( GetSourceMesh(), os );
 
   myBaseImpl->SaveTo( os );
@@ -264,9 +271,9 @@ void StdMeshers_ProjectionSource1D_i::LoadFrom( const char* theStream )
   ASSERT( myBaseImpl );
   std::istringstream is( theStream );
 
-  TopoDS_Shape s1 = StdMeshers_ObjRefUlils::LoadFromStream( is );
-  TopoDS_Shape s2 = StdMeshers_ObjRefUlils::LoadFromStream( is );
-  TopoDS_Shape s3 = StdMeshers_ObjRefUlils::LoadFromStream( is );
+  TopoDS_Shape shapes[ NB_SHAPES ];
+  for ( int i = 0; i < NB_SHAPES; ++i )
+    shapes[ i ] = StdMeshers_ObjRefUlils::LoadFromStream( is );
   SMESH::SMESH_Mesh_var mesh = 
     StdMeshers_ObjRefUlils::LoadObjectFromStream< SMESH::SMESH_Mesh >( is );
 
@@ -280,8 +287,15 @@ void StdMeshers_ProjectionSource1D_i::LoadFrom( const char* theStream )
   }
 
   myCorbaMesh = SMESH::SMESH_Mesh::_duplicate( mesh );
-  GetImpl()->RestoreParams( s1, s2, s3, meshImpl );
+  GetImpl()->SetSourceMesh       ( meshImpl );
+  GetImpl()->SetSourceEdge       ( shapes[ SRC_EDGE ] );
+  GetImpl()->SetVertexAssociation( shapes[ SRC_VERTEX ],
+                                   shapes[ TGT_VERTEX ]);
 
   myBaseImpl->LoadFrom( is );
+
+  std::istringstream str( theStream );
+  for ( int i = 0; i < NB_SHAPES; ++i )
+    str >> myShapeEntries[ i ];
 }
 
index f73d75762aa7bbf2bd50b66249a50cc722cfb6bf..7326d3730697ea0b36b7e67e8453ecee8c3ea669 100644 (file)
@@ -1,29 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_ProjectionSource1D_i.hxx
 //  Author : Edward AGAPOV
 //  Module : SMESH
-//  $Header$
 //
 #ifndef _SMESH_ProjectionSource1D_I_HXX_
 #define _SMESH_ProjectionSource1D_I_HXX_
@@ -111,6 +111,11 @@ public:
   virtual void  LoadFrom( const char* theStream );
 
 private:
+  // keep entries because the same shape can be published several times with
+  // different names and in this case a correct name can't be restored by a TopoDS_Shape
+  // kept by ::StdMeshers_ProjectionSource1D
+  enum { SRC_EDGE=0, SRC_VERTEX, TGT_VERTEX, NB_SHAPES };
+  std::string           myShapeEntries[NB_SHAPES];
   SMESH::SMESH_Mesh_var myCorbaMesh;
 };
 
index 6186a7b04639312e809c330f18bfa99a60a9bd60..2c14db45975dbf8c4ae7cccb03c01b599157b3e3 100644 (file)
@@ -1,29 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes
 //  File   : StdMeshers_ProjectionSource2D_i.cxx
 //  Author : Edward AGAPOV
 //  Module : SMESH
-//  $Header$
 //
 #include "StdMeshers_ProjectionSource2D_i.hxx"
 
@@ -83,6 +83,8 @@ void StdMeshers_ProjectionSource2D_i::SetSourceFace(GEOM::GEOM_Object_ptr face)
   ASSERT( myBaseImpl );
   try {
     this->GetImpl()->SetSourceFace( StdMeshers_ObjRefUlils::GeomObjectToShape( face ));
+    CORBA::String_var entry = face->GetStudyEntry();
+    myShapeEntries[ SRC_FACE ] = entry.in();
   }
   catch ( SALOME_Exception& S_ex ) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM );
@@ -158,6 +160,11 @@ void StdMeshers_ProjectionSource2D_i::SetVertexAssociation(GEOM::GEOM_Object_ptr
     TopoDS_Shape v3 = StdMeshers_ObjRefUlils::GeomObjectToShape( targetVertex1 );
     TopoDS_Shape v4 = StdMeshers_ObjRefUlils::GeomObjectToShape( targetVertex2 );
     this->GetImpl()->SetVertexAssociation( v1, v2, v3, v4 );
+
+    myShapeEntries[ SRC_VERTEX1 ] = StdMeshers_ObjRefUlils::GeomObjectToEntry( sourceVertex1 );
+    myShapeEntries[ SRC_VERTEX2 ] = StdMeshers_ObjRefUlils::GeomObjectToEntry( sourceVertex2 );
+    myShapeEntries[ TGT_VERTEX1 ] = StdMeshers_ObjRefUlils::GeomObjectToEntry( targetVertex1 );
+    myShapeEntries[ TGT_VERTEX2 ] = StdMeshers_ObjRefUlils::GeomObjectToEntry( targetVertex2 );
   }
   catch ( SALOME_Exception& S_ex ) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM );
@@ -179,7 +186,9 @@ void StdMeshers_ProjectionSource2D_i::SetVertexAssociation(GEOM::GEOM_Object_ptr
 GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource2D_i::GetSourceFace()
 {
   ASSERT( myBaseImpl );
-  return StdMeshers_ObjRefUlils::ShapeToGeomObject( this->GetImpl()->GetSourceFace() );
+  return StdMeshers_ObjRefUlils::EntryOrShapeToGeomObject
+    ( myShapeEntries[ SRC_FACE ],
+      this->GetImpl()->GetSourceFace() );
 }
 
 //=============================================================================
@@ -192,7 +201,9 @@ GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource2D_i::GetSourceFace()
 GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource2D_i::GetSourceVertex(CORBA::Long i)
 {
   ASSERT( myBaseImpl );
-  return StdMeshers_ObjRefUlils::ShapeToGeomObject( this->GetImpl()->GetSourceVertex((int) i ));
+  return StdMeshers_ObjRefUlils::EntryOrShapeToGeomObject
+    ( myShapeEntries[ i == 1 ? SRC_VERTEX1 : SRC_VERTEX2 ],
+      this->GetImpl()->GetSourceVertex((int) i ));
 }
 
 //=============================================================================
@@ -205,7 +216,9 @@ GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource2D_i::GetSourceVertex(CORBA::Lo
 GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource2D_i::GetTargetVertex(CORBA::Long i)
 {
   ASSERT( myBaseImpl );
-  return StdMeshers_ObjRefUlils::ShapeToGeomObject( this->GetImpl()->GetTargetVertex( (int)i ));
+  return StdMeshers_ObjRefUlils::EntryOrShapeToGeomObject
+    ( myShapeEntries[ i == 1 ? TGT_VERTEX1 : TGT_VERTEX2 ],
+      this->GetImpl()->GetTargetVertex( (int)i ));
 }
 
 //=============================================================================
@@ -247,14 +260,8 @@ char* StdMeshers_ProjectionSource2D_i::SaveTo()
   ASSERT( myBaseImpl );
   std::ostringstream os;
 
-  TopoDS_Shape s1, s2, s3, s4, s5;
-  GetImpl()->GetStoreParams( s1, s2, s3, s4, s5 );
-
-  StdMeshers_ObjRefUlils::SaveToStream( s1, os );
-  StdMeshers_ObjRefUlils::SaveToStream( s2, os );
-  StdMeshers_ObjRefUlils::SaveToStream( s3, os );
-  StdMeshers_ObjRefUlils::SaveToStream( s4, os );
-  StdMeshers_ObjRefUlils::SaveToStream( s5, os );
+  for ( int i = 0; i < NB_SHAPES; ++i )
+    StdMeshers_ObjRefUlils::SaveToStream( myShapeEntries[ i ], os );
   StdMeshers_ObjRefUlils::SaveToStream( GetSourceMesh(), os );
 
   myBaseImpl->SaveTo( os );
@@ -274,11 +281,9 @@ void StdMeshers_ProjectionSource2D_i::LoadFrom( const char* theStream )
   ASSERT( myBaseImpl );
   std::istringstream is( theStream );
 
-  TopoDS_Shape s1 = StdMeshers_ObjRefUlils::LoadFromStream( is );
-  TopoDS_Shape s2 = StdMeshers_ObjRefUlils::LoadFromStream( is );
-  TopoDS_Shape s3 = StdMeshers_ObjRefUlils::LoadFromStream( is );
-  TopoDS_Shape s4 = StdMeshers_ObjRefUlils::LoadFromStream( is );
-  TopoDS_Shape s5 = StdMeshers_ObjRefUlils::LoadFromStream( is );
+  TopoDS_Shape shapes[ NB_SHAPES ];
+  for ( int i = 0; i < NB_SHAPES; ++i )
+    shapes[ i ] = StdMeshers_ObjRefUlils::LoadFromStream( is );
   SMESH::SMESH_Mesh_var mesh = 
     StdMeshers_ObjRefUlils::LoadObjectFromStream< SMESH::SMESH_Mesh >( is );
 
@@ -292,8 +297,17 @@ void StdMeshers_ProjectionSource2D_i::LoadFrom( const char* theStream )
   }
 
   myCorbaMesh = SMESH::SMESH_Mesh::_duplicate( mesh );
-  GetImpl()->RestoreParams( s1, s2, s3, s4, s5, meshImpl );
 
+  GetImpl()->SetSourceMesh       ( meshImpl );
+  GetImpl()->SetSourceFace       ( shapes[ SRC_FACE ] );
+  GetImpl()->SetVertexAssociation( shapes[ SRC_VERTEX1 ],
+                                   shapes[ SRC_VERTEX2 ],
+                                   shapes[ TGT_VERTEX1 ],
+                                   shapes[ TGT_VERTEX2 ]);
   myBaseImpl->LoadFrom( is );
+
+  std::istringstream str( theStream );
+  for ( int i = 0; i < NB_SHAPES; ++i )
+    str >> myShapeEntries[ i ];
 }
 
index 4aa63c7a5901817eeef6478b68be9a4903c1327e..454744439045a34a74f08ba23f13b1ecb1ae57bb 100644 (file)
@@ -1,29 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_ProjectionSource2D_i.hxx
 //  Author : Edward AGAPOV
 //  Module : SMESH
-//  $Header$
 //
 #ifndef _SMESH_ProjectionSource2D_I_HXX_
 #define _SMESH_ProjectionSource2D_I_HXX_
@@ -93,6 +93,7 @@ public:
   /*!
    * Returns the <i>-th source vertex associated with the <i>-th target vertex.
    * Result may be nil if association not set.
+   * Valid indices are 1 and 2
    */
   GEOM::GEOM_Object_ptr GetSourceVertex(CORBA::Long i);
 
@@ -114,8 +115,12 @@ public:
   virtual void  LoadFrom( const char* theStream );
 
 private:
+  // keep entries because the same shape can be published several times with
+  // different names and in this case a correct name can't be restored by a TopoDS_Shape
+  // kept by ::StdMeshers_ProjectionSource2D
+  enum { SRC_FACE=0, SRC_VERTEX1, SRC_VERTEX2, TGT_VERTEX1, TGT_VERTEX2, NB_SHAPES };
+  std::string           myShapeEntries[NB_SHAPES];
   SMESH::SMESH_Mesh_var myCorbaMesh;
 };
 
 #endif
-
index 5ee44b3fc4e1077c6ba22d91ce5678f50c960d30..ea2a2b31fe84da7a5812d3354f48a4c7c935fb55 100644 (file)
@@ -1,29 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes
 //  File   : StdMeshers_ProjectionSource3D_i.cxx
 //  Author : Edward AGAPOV
 //  Module : SMESH
-//  $Header$
 //
 #include "StdMeshers_ProjectionSource3D_i.hxx"
 
@@ -83,6 +83,9 @@ void StdMeshers_ProjectionSource3D_i::SetSource3DShape(GEOM::GEOM_Object_ptr sha
   ASSERT( myBaseImpl );
   try {
     this->GetImpl()->SetSource3DShape( StdMeshers_ObjRefUlils::GeomObjectToShape( shape ));
+
+    CORBA::String_var entry = shape->GetStudyEntry();
+    myShapeEntries[ SRC_SHAPE3D ] = entry.in();
   }
   catch ( SALOME_Exception& S_ex ) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM );
@@ -158,6 +161,11 @@ void StdMeshers_ProjectionSource3D_i::SetVertexAssociation(GEOM::GEOM_Object_ptr
     TopoDS_Shape v3 = StdMeshers_ObjRefUlils::GeomObjectToShape( targetVertex1 );
     TopoDS_Shape v4 = StdMeshers_ObjRefUlils::GeomObjectToShape( targetVertex2 );
     this->GetImpl()->SetVertexAssociation( v1, v2, v3, v4 );
+
+    myShapeEntries[ SRC_VERTEX1 ] = StdMeshers_ObjRefUlils::GeomObjectToEntry( sourceVertex1 );
+    myShapeEntries[ SRC_VERTEX2 ] = StdMeshers_ObjRefUlils::GeomObjectToEntry( sourceVertex2 );
+    myShapeEntries[ TGT_VERTEX1 ] = StdMeshers_ObjRefUlils::GeomObjectToEntry( targetVertex1 );
+    myShapeEntries[ TGT_VERTEX2 ] = StdMeshers_ObjRefUlils::GeomObjectToEntry( targetVertex2 );
   }
   catch ( SALOME_Exception& S_ex ) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM );
@@ -179,7 +187,9 @@ void StdMeshers_ProjectionSource3D_i::SetVertexAssociation(GEOM::GEOM_Object_ptr
 GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource3D_i::GetSource3DShape()
 {
   ASSERT( myBaseImpl );
-  return StdMeshers_ObjRefUlils::ShapeToGeomObject( this->GetImpl()->GetSource3DShape() );
+  return StdMeshers_ObjRefUlils::EntryOrShapeToGeomObject
+    ( myShapeEntries[ SRC_SHAPE3D ],
+      this->GetImpl()->GetSource3DShape() );
 }
 
 //=============================================================================
@@ -192,7 +202,9 @@ GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource3D_i::GetSource3DShape()
 GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource3D_i::GetSourceVertex(CORBA::Long i)
 {
   ASSERT( myBaseImpl );
-  return StdMeshers_ObjRefUlils::ShapeToGeomObject( this->GetImpl()->GetSourceVertex((int) i ));
+  return StdMeshers_ObjRefUlils::EntryOrShapeToGeomObject
+    ( myShapeEntries[ i == 1 ? SRC_VERTEX1 : SRC_VERTEX2 ],
+      this->GetImpl()->GetSourceVertex((int) i ));
 }
 
 //=============================================================================
@@ -205,7 +217,9 @@ GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource3D_i::GetSourceVertex(CORBA::Lo
 GEOM::GEOM_Object_ptr StdMeshers_ProjectionSource3D_i::GetTargetVertex(CORBA::Long i)
 {
   ASSERT( myBaseImpl );
-  return StdMeshers_ObjRefUlils::ShapeToGeomObject( this->GetImpl()->GetTargetVertex( (int)i ));
+  return StdMeshers_ObjRefUlils::EntryOrShapeToGeomObject
+    ( myShapeEntries[ i == 1 ? TGT_VERTEX1 : TGT_VERTEX2 ],
+      this->GetImpl()->GetTargetVertex( (int)i ));
 }
 
 //=============================================================================
@@ -247,14 +261,8 @@ char* StdMeshers_ProjectionSource3D_i::SaveTo()
   ASSERT( myBaseImpl );
   std::ostringstream os;
 
-  TopoDS_Shape s1, s2, s3, s4, s5;
-  GetImpl()->GetStoreParams( s1, s2, s3, s4, s5 );
-
-  StdMeshers_ObjRefUlils::SaveToStream( s1, os );
-  StdMeshers_ObjRefUlils::SaveToStream( s2, os );
-  StdMeshers_ObjRefUlils::SaveToStream( s3, os );
-  StdMeshers_ObjRefUlils::SaveToStream( s4, os );
-  StdMeshers_ObjRefUlils::SaveToStream( s5, os );
+  for ( int i = 0; i < NB_SHAPES; ++i )
+    StdMeshers_ObjRefUlils::SaveToStream( myShapeEntries[ i ], os );
   StdMeshers_ObjRefUlils::SaveToStream( GetSourceMesh(), os );
 
   myBaseImpl->SaveTo( os );
@@ -274,11 +282,9 @@ void StdMeshers_ProjectionSource3D_i::LoadFrom( const char* theStream )
   ASSERT( myBaseImpl );
   std::istringstream is( theStream );
 
-  TopoDS_Shape s1 = StdMeshers_ObjRefUlils::LoadFromStream( is );
-  TopoDS_Shape s2 = StdMeshers_ObjRefUlils::LoadFromStream( is );
-  TopoDS_Shape s3 = StdMeshers_ObjRefUlils::LoadFromStream( is );
-  TopoDS_Shape s4 = StdMeshers_ObjRefUlils::LoadFromStream( is );
-  TopoDS_Shape s5 = StdMeshers_ObjRefUlils::LoadFromStream( is );
+  TopoDS_Shape shapes[ NB_SHAPES ];
+  for ( int i = 0; i < NB_SHAPES; ++i )
+    shapes[ i ] = StdMeshers_ObjRefUlils::LoadFromStream( is );
   SMESH::SMESH_Mesh_var mesh =
     StdMeshers_ObjRefUlils::LoadObjectFromStream< SMESH::SMESH_Mesh >( is );
 
@@ -292,7 +298,18 @@ void StdMeshers_ProjectionSource3D_i::LoadFrom( const char* theStream )
   }
 
   myCorbaMesh = SMESH::SMESH_Mesh::_duplicate( mesh );
-  GetImpl()->RestoreParams( s1, s2, s3, s4, s5, meshImpl );
+
+  GetImpl()->SetSourceMesh       ( meshImpl );
+  GetImpl()->SetSource3DShape    ( shapes[ SRC_SHAPE3D ] );
+  GetImpl()->SetVertexAssociation( shapes[ SRC_VERTEX1 ],
+                                   shapes[ SRC_VERTEX2 ],
+                                   shapes[ TGT_VERTEX1 ],
+                                   shapes[ TGT_VERTEX2 ]);
+
   myBaseImpl->LoadFrom( is );
+
+  std::istringstream str( theStream );
+  for ( int i = 0; i < NB_SHAPES; ++i )
+    str >> myShapeEntries[ i ];
 }
 
index d8eff8b7f8ce6d2caaff375d80f8b2b0a489c252..f09340130bc556e15bc41a7ed573862d87f3c424 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_ProjectionSource3D_i.hxx
 //  Author : Edward AGAPOV
@@ -93,6 +94,7 @@ public:
   /*!
    * Returns the <i>-th source vertex associated with the <i>-th target vertex.
    * Result may be nil if association not set.
+   * Valid indices are 1 and 2
    */
   GEOM::GEOM_Object_ptr GetSourceVertex(CORBA::Long i);
 
@@ -114,6 +116,11 @@ public:
   virtual void  LoadFrom( const char* theStream );
 
 private:
+  // keep entries because the same shape can be published several times with
+  // different names and in this case a correct name can't be restored by a TopoDS_Shape
+  // kept by ::StdMeshers_ProjectionSource3D
+  enum { SRC_SHAPE3D=0, SRC_VERTEX1, SRC_VERTEX2, TGT_VERTEX1, TGT_VERTEX2, NB_SHAPES };
+  std::string           myShapeEntries[NB_SHAPES];
   SMESH::SMESH_Mesh_var myCorbaMesh;
 };
 
index 185bdd6ad0240e87160d8943769db260606a1b6b..ed4063315c5136125f1570d7d1f64165041050b1 100644 (file)
@@ -1,30 +1,26 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
-//  File   : StdMeshers_Projection_3D_i.cxx
-//           Moved here from SMESH_Projection_3D_i.cxx
-//  Author : Paul RASCLE, EDF
+//  File   : StdMeshers_Projection_1D_2D_3D_i.cxx
 //  Module : SMESH
-//  $Header$
 //
 #include "StdMeshers_Projection_1D_2D_3D_i.hxx"
 
@@ -53,8 +49,8 @@ StdMeshers_Projection_3D_i::StdMeshers_Projection_3D_i( PortableServer::POA_ptr
 {
   MESSAGE( "StdMeshers_Projection_3D_i::StdMeshers_Projection_3D_i" );
   myBaseImpl = new ::StdMeshers_Projection_3D( theGenImpl->GetANewId(),
-                                   theStudyId,
-                                   theGenImpl );
+                                    theStudyId,
+                                    theGenImpl );
 }
 //-----------------------------------------------------------------------------
 
@@ -87,8 +83,8 @@ StdMeshers_Projection_2D_i::StdMeshers_Projection_2D_i( PortableServer::POA_ptr
 {
   MESSAGE( "StdMeshers_Projection_2D_i::StdMeshers_Projection_2D_i" );
   myBaseImpl = new ::StdMeshers_Projection_2D( theGenImpl->GetANewId(),
-                                   theStudyId,
-                                   theGenImpl );
+                                    theStudyId,
+                                    theGenImpl );
 }
 //-----------------------------------------------------------------------------
 
@@ -105,6 +101,40 @@ StdMeshers_Projection_2D_i::~StdMeshers_Projection_2D_i()
 }
 
 
+//=============================================================================
+/*!
+ *  StdMeshers_Projection_1D2D_i::StdMeshers_Projection_1D2D_i
+ */
+//=============================================================================
+
+StdMeshers_Projection_1D2D_i::StdMeshers_Projection_1D2D_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( "StdMeshers_Projection_1D2D_i::StdMeshers_Projection_1D2D_i" );
+  myBaseImpl = new ::StdMeshers_Projection_1D2D( theGenImpl->GetANewId(),
+                                                 theStudyId,
+                                                 theGenImpl );
+}
+//-----------------------------------------------------------------------------
+
+StdMeshers_Projection_1D2D_i::~StdMeshers_Projection_1D2D_i()
+{
+  MESSAGE( "StdMeshers_Projection_1D2D_i::~StdMeshers_Projection_1D2D_i" );
+}
+//-----------------------------------------------------------------------------
+
+::StdMeshers_Projection_1D2D* StdMeshers_Projection_1D2D_i::GetImpl()
+{
+  MESSAGE( "StdMeshers_Projection_1D2D_i::GetImpl" );
+  return ( ::StdMeshers_Projection_1D2D* )myBaseImpl;
+}
+
+
 //=============================================================================
 /*!
  *  StdMeshers_Projection_1D_i::StdMeshers_Projection_1D_i
@@ -121,8 +151,8 @@ StdMeshers_Projection_1D_i::StdMeshers_Projection_1D_i( PortableServer::POA_ptr
 {
   MESSAGE( "StdMeshers_Projection_1D_i::StdMeshers_Projection_1D_i" );
   myBaseImpl = new ::StdMeshers_Projection_1D( theGenImpl->GetANewId(),
-                                   theStudyId,
-                                   theGenImpl );
+                                    theStudyId,
+                                    theGenImpl );
 }
 //-----------------------------------------------------------------------------
 
index 7fdba6588fcff1fca1e08490765abf924e8a3b66..fb17dd60977e63f4af4f76b32c93f0cc9b9112f6 100644 (file)
@@ -1,33 +1,29 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
-//  File   : StdMeshers_Hexa_3D_i.hxx
-//           Moved here from SMESH_Hexa_3D_i.hxx
-//  Author : Paul RASCLE, EDF
+//  File   : StdMeshers_Projection_1D_2D_3D_i.hxx
 //  Module : SMESH
-//  $Header$
 //
-#ifndef _SMESH_Projection_3D_I_HXX_
-#define _SMESH_Projection_3D_I_HXX_
+#ifndef _SMESH_Projection_1D2D3D_I_HXX_
+#define _SMESH_Projection_1D2D3D_I_HXX_
 
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
@@ -36,6 +32,7 @@
 #include "SMESH_2D_Algo_i.hxx"
 #include "SMESH_3D_Algo_i.hxx"
 #include "StdMeshers_Projection_1D.hxx"
+#include "StdMeshers_Projection_1D2D.hxx"
 #include "StdMeshers_Projection_2D.hxx"
 #include "StdMeshers_Projection_3D.hxx"
 
@@ -63,7 +60,7 @@ public:
 };
 
 // ======================================================
-// Projection 3D algorithm
+// Projection 2D algorithm
 // ======================================================
 
 class StdMeshers_Projection_2D_i:
@@ -84,7 +81,28 @@ public:
 };
 
 // ======================================================
-// Projection 3D algorithm
+// Projection 1D-2D algorithm
+// ======================================================
+
+class StdMeshers_Projection_1D2D_i:
+  public virtual POA_StdMeshers::StdMeshers_Projection_1D2D,
+  public virtual SMESH_2D_Algo_i
+{
+public:
+  // Constructor
+  StdMeshers_Projection_1D2D_i( PortableServer::POA_ptr thePOA,
+                                int                     theStudyId,
+                                ::SMESH_Gen*            theGenImpl );
+
+  // Destructor
+  virtual ~StdMeshers_Projection_1D2D_i();
+
+  // Get implementation
+  ::StdMeshers_Projection_1D2D* GetImpl();
+};
+
+// ======================================================
+// Projection 1D algorithm
 // ======================================================
 
 class StdMeshers_Projection_1D_i:
index 707e41600cc1a5664bcdc65a97787979330843aa..a288d1c3bef8d4346764055436c58a475986bb6e 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_Propagation_i.cxx
 //  Module : SMESH
index 77f8631758f64bcbe69d8e30a07759f2521d866d..a79465a3ec18a8f703e34bb8ca5f5f9c58497de0 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_Propagation_i.hxx
 //  Module : SMESH
diff --git a/src/StdMeshers_I/StdMeshers_QuadrangleParams_i.cxx b/src/StdMeshers_I/StdMeshers_QuadrangleParams_i.cxx
new file mode 100644 (file)
index 0000000..4d72e8d
--- /dev/null
@@ -0,0 +1,245 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+//  File   : StdMeshers_QuadrangleParams_i.cxx
+//  Author : Sergey KUUL, OCC
+//  Module : SMESH
+
+#include "StdMeshers_QuadrangleParams_i.hxx"
+#include "SMESH_Gen_i.hxx"
+#include "SMESH_Gen.hxx"
+#include "SMESH_PythonDump.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+#include <TCollection_AsciiString.hxx>
+
+using namespace std;
+
+//=============================================================================
+/*!
+ *  StdMeshers_QuadrangleParams_i::StdMeshers_QuadrangleParams_i
+ *
+ *  Constructor
+ */
+//=============================================================================
+
+StdMeshers_QuadrangleParams_i::StdMeshers_QuadrangleParams_i
+                                          (PortableServer::POA_ptr thePOA,
+                                           int                     theStudyId,
+                                           ::SMESH_Gen*            theGenImpl )
+     : SALOME::GenericObj_i( thePOA ), 
+       SMESH_Hypothesis_i( thePOA )
+{
+  MESSAGE( "StdMeshers_QuadrangleParams_i::StdMeshers_QuadrangleParams_i" );
+  myBaseImpl = new ::StdMeshers_QuadrangleParams(theGenImpl->GetANewId(),
+                                                 theStudyId,
+                                                 theGenImpl);
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_QuadrangleParams_i::~StdMeshers_QuadrangleParams_i
+ *
+ *  Destructor
+ */
+//=============================================================================
+
+StdMeshers_QuadrangleParams_i::~StdMeshers_QuadrangleParams_i()
+{
+  MESSAGE( "StdMeshers_QuadrangleParams_i::~StdMeshers_QuadrangleParams_i" );
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_QuadrangleParams_i::SetTriaVertex
+ *
+ *  Set base vertex for triangles
+ */
+//=============================================================================
+
+void StdMeshers_QuadrangleParams_i::SetTriaVertex(CORBA::Long vertID)
+{
+  MESSAGE( "StdMeshers_QuadrangleParams_i::SetTriaVertex" );
+  ASSERT( myBaseImpl );
+  try {
+    this->GetImpl()->SetTriaVertex( vertID );
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
+                                  SALOME::BAD_PARAM );
+  }
+
+  // Update Python script
+  SMESH::TPythonDump() << _this() << ".SetTriaVertex( "
+      << vertID << " )";
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_QuadrangleParams_i::GetTriaVertex
+ *
+ *  Get base vertex for triangles
+ */
+//=============================================================================
+
+CORBA::Long StdMeshers_QuadrangleParams_i::GetTriaVertex()
+{
+  MESSAGE( "StdMeshers_QuadrangleParams_i::GetTriaVertex" );
+  ASSERT( myBaseImpl );
+  return this->GetImpl()->GetTriaVertex();
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_QuadrangleParams_i::SetObjectEntry
+ *
+ *  Set the Entry for the Main Object
+ */
+//=============================================================================
+
+void StdMeshers_QuadrangleParams_i::SetObjectEntry( const char* entry )
+{
+  MESSAGE( "StdMeshers_QuadrangleParams_i::SetObjectEntry" );
+  ASSERT( myBaseImpl );
+
+  try {
+    this->GetImpl()->SetObjectEntry( entry );
+    // Update Python script
+    //    SMESH::TPythonDump() << _this() << ".SetObjectEntry( '" << entry << "' )";
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
+                                  SALOME::BAD_PARAM );
+  }
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_QuadrangleParams_i::GetObjectEntry
+ *
+ *  Set the Entry for the Main Object
+ */
+//=============================================================================
+
+char* StdMeshers_QuadrangleParams_i::GetObjectEntry()
+{
+  MESSAGE( "StdMeshers_QuadrangleParams_i::SetObjectEntry" );
+  ASSERT( myBaseImpl );
+  const char* entry;
+  try {
+    entry = this->GetImpl()->GetObjectEntry();
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
+                                  SALOME::BAD_PARAM );
+  }
+  return CORBA::string_dup( entry );
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_QuadrangleParams_i::SetQuadType
+ *
+ *  Set the type of quadrangulation
+ */
+//=============================================================================
+void StdMeshers_QuadrangleParams_i::SetQuadType(StdMeshers::QuadType type)
+{
+  //static char* quadTypes[5] = {"StdMeshers.QUAD_STANDARD",
+  //                             "StdMeshers.QUAD_TRIANGLE_PREF",
+  //                             "StdMeshers.QUAD_QUADRANGLE_PREF",
+  //                             "StdMeshers.QUAD_QUADRANGLE_PREF_REVERSED",
+  //                             "StdMeshers.QUAD_REDUCED"};
+
+  MESSAGE("StdMeshers_QuadrangleParams_i::SetQuadType");
+  ASSERT(myBaseImpl);
+
+  if (int(type) >= int(StdMeshers::QUAD_NB_TYPES)) {
+    THROW_SALOME_CORBA_EXCEPTION("Bad type of quadrangulation", SALOME::BAD_PARAM);
+  }
+
+  try {
+    this->GetImpl()->SetQuadType(StdMeshers_QuadType(int(type)));
+  }
+  catch (SALOME_Exception& S_ex) {
+    THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+  }
+
+  // Update Python script
+  const char* quadType;
+  switch (type) {
+  case StdMeshers::QUAD_STANDARD:
+    quadType = "StdMeshers.QUAD_STANDARD"; break;
+  case StdMeshers::QUAD_TRIANGLE_PREF:
+    quadType = "StdMeshers.QUAD_TRIANGLE_PREF"; break;
+  case StdMeshers::QUAD_QUADRANGLE_PREF:
+    quadType = "StdMeshers.QUAD_QUADRANGLE_PREF"; break;
+  case StdMeshers::QUAD_QUADRANGLE_PREF_REVERSED:
+    quadType = "StdMeshers.QUAD_QUADRANGLE_PREF_REVERSED"; break;
+  case StdMeshers::QUAD_REDUCED:
+    quadType = "StdMeshers.QUAD_REDUCED"; break;
+  default:
+    quadType = "UNKNOWN";
+  }
+  SMESH::TPythonDump() << _this() << ".SetQuadType( " << quadType << " )";
+  //SMESH::TPythonDump() << _this() << ".SetQuadType( " << quadTypes[int(type)] << " )";
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_QuadrangleParams_i::GetQuadType
+ *
+ *  Get the type of quadrangulation
+ */
+//=============================================================================
+StdMeshers::QuadType StdMeshers_QuadrangleParams_i::GetQuadType()
+{
+  MESSAGE("StdMeshers_QuadrangleParams_i::GetQuadType");
+  ASSERT(myBaseImpl);
+  return StdMeshers::QuadType(int(this->GetImpl()->GetQuadType()));
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_QuadrangleParams_i::GetImpl
+ *
+ *  Get implementation
+ */
+//=============================================================================
+
+::StdMeshers_QuadrangleParams* StdMeshers_QuadrangleParams_i::GetImpl()
+{
+  MESSAGE( "StdMeshers_QuadrangleParams_i::GetImpl" );
+  return ( ::StdMeshers_QuadrangleParams* )myBaseImpl;
+}
+
+//================================================================================
+/*!
+ * \brief Verify whether hypothesis supports given entity type 
+  * \param type - dimension (see SMESH::Dimension enumeration)
+  * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise
+ * 
+ * Verify whether hypothesis supports given entity type (see SMESH::Dimension enumeration)
+ */
+//================================================================================  
+CORBA::Boolean StdMeshers_QuadrangleParams_i::IsDimSupported( SMESH::Dimension type )
+{
+  return type == SMESH::DIM_2D;
+}
diff --git a/src/StdMeshers_I/StdMeshers_QuadrangleParams_i.hxx b/src/StdMeshers_I/StdMeshers_QuadrangleParams_i.hxx
new file mode 100644 (file)
index 0000000..7558ea3
--- /dev/null
@@ -0,0 +1,82 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+//  File   : StdMeshers_QuadrangleParams_i.hxx
+//  Author : Sergey KUUL, OCC
+//  Module : SMESH
+//  $Header$
+
+#ifndef _SMESH_QUADRANGLEPARAMS_I_HXX_
+#define _SMESH_QUADRANGLEPARAMS_I_HXX_
+
+#include "SMESH_StdMeshers_I.hxx"
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_Hypothesis_i.hxx"
+#include "StdMeshers_QuadrangleParams.hxx"
+
+// ======================================================
+// QuadrangleParams hypothesis
+// ======================================================
+class STDMESHERS_I_EXPORT StdMeshers_QuadrangleParams_i:
+  public virtual POA_StdMeshers::StdMeshers_QuadrangleParams,
+  public virtual SMESH_Hypothesis_i
+{
+public:
+  // Constructor
+  StdMeshers_QuadrangleParams_i (PortableServer::POA_ptr thePOA,
+                                 int                     theStudyId,
+                                 ::SMESH_Gen*            theGenImpl);
+  // Destructor
+  virtual ~StdMeshers_QuadrangleParams_i();
+
+  // Set length
+  //void SetLength( CORBA::Double theLength, CORBA::Boolean theIsStart )
+  //  throw ( SALOME::SALOME_Exception );
+
+  // Get length
+  //CORBA::Double GetLength(CORBA::Boolean theIsStart);
+
+  // Set base vertex for triangles
+  void SetTriaVertex (CORBA::Long vertID);
+
+  // Get base vertex for triangles
+  CORBA::Long GetTriaVertex();
+  
+  // Set the Entry of the Object
+  void SetObjectEntry (const char* theEntry);
+
+  // Get Object Entry
+  char* GetObjectEntry();
+
+  // Set the type of quadrangulation
+  void SetQuadType (StdMeshers::QuadType type);
+
+  // Get the type of quadrangulation
+  StdMeshers::QuadType GetQuadType();
+
+  // Get implementation
+  ::StdMeshers_QuadrangleParams* GetImpl();
+  
+  // Verify whether hypothesis supports given entity type 
+  CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+};
+
+#endif
index c199fcebd492d175a1d81e79d59c5761eed88a17..57a053d9826651b818ed8d95fdfc5861789b01d0 100644 (file)
@@ -1,30 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_QuadranglePreference_i.cxx
 //           Moved here from SMESH_LocalLength_i.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//  $Header$
 //
 #include "StdMeshers_QuadranglePreference_i.hxx"
 #include "SMESH_Gen_i.hxx"
index fc63462a951d4e99f98cad90fe1dcead218b4777..b0d2bc712a8239d3e97335d2123ab7cd424d8ac5 100644 (file)
@@ -1,30 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_QuadranglePreference_i.hxx
 //           Moved here from SMESH_LocalLength_i.hxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//  $Header$
 //
 #ifndef _SMESH_QuadranglePreference_I_HXX_
 #define _SMESH_QuadranglePreference_I_HXX_
index 7b0ce1e63a99c666b15306447ac080bd07358dd6..24d44ac6a30113b59d2c36df92d0111c249b54c6 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_Quadrangle_2D_i.cxx
 //           Moved here from SMESH_Quadrangle_2D_i.cxx
@@ -43,8 +44,8 @@ using namespace std;
 //=============================================================================
 
 StdMeshers_Quadrangle_2D_i::StdMeshers_Quadrangle_2D_i( PortableServer::POA_ptr thePOA,
-                                             int                     theStudyId,
-                                             ::SMESH_Gen*            theGenImpl )
+                                              int                     theStudyId,
+                                              ::SMESH_Gen*            theGenImpl )
      : SALOME::GenericObj_i( thePOA ), 
        SMESH_Hypothesis_i( thePOA ), 
        SMESH_Algo_i( thePOA ),
@@ -52,8 +53,8 @@ StdMeshers_Quadrangle_2D_i::StdMeshers_Quadrangle_2D_i( PortableServer::POA_ptr
 {
   MESSAGE( "StdMeshers_Quadrangle_2D_i::StdMeshers_Quadrangle_2D_i" );
   myBaseImpl = new ::StdMeshers_Quadrangle_2D( theGenImpl->GetANewId(),
-                                         theStudyId,
-                                         theGenImpl );
+                                          theStudyId,
+                                          theGenImpl );
 }
 
 //=============================================================================
index abe6ce46abf5a33d7ec0915f636b9122e8ea5f8e..2dfcce71d05ba583a49ac9cf230c157626bda5eb 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_Quadrangle_2D_i.hxx
 //           Moved here from SMESH_Quadrangle_2D_i.hxx
@@ -50,7 +51,7 @@ public:
   // Constructor
   StdMeshers_Quadrangle_2D_i( PortableServer::POA_ptr thePOA,
                          int                     theStudyId,
-                        ::SMESH_Gen*            theGenImpl );
+                         ::SMESH_Gen*            theGenImpl );
 
   // Destructor
   virtual ~StdMeshers_Quadrangle_2D_i();
index 46052eb94af26be2c82a67f69a130cb8f0617238..71553993fe0d9c8afd62962d59bca84202d54cf1 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_QuadraticMesh_i.cxx
 //           Moved here from SMESH_LocalLength_i.cxx
index ecd7baaa349ee5e5a26721abbc55cc01869cae64..522f696441379996981385dc13cda73dbf0d9f57 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_QuadraticMesh_i.hxx
 //           Moved here from SMESH_LocalLength_i.hxx
diff --git a/src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.cxx b/src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.cxx
new file mode 100644 (file)
index 0000000..202faa2
--- /dev/null
@@ -0,0 +1,68 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//  File   : StdMeshers_RadialQuadrangle_1D2D_i.cxx
+//  Module : SMESH
+//
+#include "StdMeshers_RadialQuadrangle_1D2D_i.hxx"
+#include "SMESH_Gen.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+using namespace std;
+
+
+//=============================================================================
+/*!
+ *  StdMeshers_RadialQuadrangle_1D2D_i::StdMeshers_RadialQuadrangle_1D2D_i
+ */
+//=============================================================================
+
+StdMeshers_RadialQuadrangle_1D2D_i::StdMeshers_RadialQuadrangle_1D2D_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( "StdMeshers_RadialQuadrangle_1D2D_i::StdMeshers_RadialQuadrangle_1D2D_i" );
+  myBaseImpl = new ::StdMeshers_RadialQuadrangle_1D2D(theGenImpl->GetANewId(),
+                                                      theStudyId,
+                                                      theGenImpl );
+}
+
+//-----------------------------------------------------------------------------
+
+StdMeshers_RadialQuadrangle_1D2D_i::~StdMeshers_RadialQuadrangle_1D2D_i()
+{
+  MESSAGE( "StdMeshers_RadialQuadrangle_1D2D_i::~StdMeshers_RadialQuadrangle_1D2D_i" );
+}
+
+//-----------------------------------------------------------------------------
+
+::StdMeshers_RadialQuadrangle_1D2D* StdMeshers_RadialQuadrangle_1D2D_i::GetImpl()
+{
+  MESSAGE( "StdMeshers_RadialQuadrangle_1D2D_i::GetImpl" );
+  return ( ::StdMeshers_RadialQuadrangle_1D2D* )myBaseImpl;
+}
+
diff --git a/src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.hxx b/src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.hxx
new file mode 100644 (file)
index 0000000..ae5b731
--- /dev/null
@@ -0,0 +1,53 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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.com
+//
+
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//  File   : StdMeshers_RadialQuadrangle_1D2D_i.hxx
+//  Module : SMESH
+//
+#ifndef _SMESH_RadialQuadrangle_1D2D_I_HXX_
+#define _SMESH_RadialQuadrangle_1D2D_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_2D_Algo_i.hxx"
+#include "StdMeshers_RadialQuadrangle_1D2D.hxx"
+
+class SMESH_Gen;
+
+class StdMeshers_RadialQuadrangle_1D2D_i:
+  public virtual POA_StdMeshers::StdMeshers_RadialQuadrangle_1D2D,
+  public virtual SMESH_2D_Algo_i
+{
+public:
+  // Constructor
+  StdMeshers_RadialQuadrangle_1D2D_i( PortableServer::POA_ptr thePOA,
+                                      int                     theStudyId,
+                                      ::SMESH_Gen*            theGenImpl );
+
+  // Destructor
+  virtual ~StdMeshers_RadialQuadrangle_1D2D_i();
+
+  // Get implementation
+  ::StdMeshers_RadialQuadrangle_1D2D* GetImpl();
+};
+
+
+#endif
index 1ac655bda80f6d1662f49f8ae98d73626d8e7e7e..a9b8cd8ac337b9e7baa414551ddf05a53ab0e119 100644 (file)
@@ -1,30 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_Regular_1D_i.cxx
 //           Moved here from SMESH_Regular_1D_i.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//  $Header$
 //
 #include "StdMeshers_Regular_1D_i.hxx"
 #include "SMESH_Gen.hxx"
index 2c3e89ba12516ac8f8c8c523b09a65eef94a380e..ea299fc98241b75782aa6fc94d9700b5b1e173fa 100644 (file)
@@ -1,30 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_Regular_1D_i.hxx
 //           Moved here from SMESH_Regular_1D_i.hxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//  $Header$
 //
 #ifndef _SMESH_REGULAR_1D_I_HXX_
 #define _SMESH_REGULAR_1D_I_HXX_
@@ -48,7 +48,7 @@ public:
   // Constructor
   StdMeshers_Regular_1D_i( PortableServer::POA_ptr thePOA,
                       int                     theStudyId,
-                     ::SMESH_Gen*            theGenImpl );
+                      ::SMESH_Gen*            theGenImpl );
   // Destructor
   virtual ~StdMeshers_Regular_1D_i();
  
index fb81f9e9f00533856a45a0db2b0a43f985e9381f..0836c36e4fb1ef997ceb96d5c60c2d921770912f 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_Projection_3D_i.cxx
 //           Moved here from SMESH_Projection_3D_i.cxx
index 526bfca8fcb33ed021ebb525eaa34ab46609f2ea..64d559097db11f30627eec859e54a63b9833fb8e 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_SegmentAroundVertex_0D.hxx
 //  Module : SMESH
index 9ee69e626fef2e48f9469869152beae14384b062..7eba3661cafad3c2ff8110cae63b685554d880ed 100644 (file)
@@ -1,28 +1,28 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_SegmentLengthAroundVertex_i.cxx
 //  Module : SMESH
-//  $Header$
 //
 #include "StdMeshers_SegmentLengthAroundVertex_i.hxx"
 #include "SMESH_Gen.hxx"
@@ -90,7 +90,7 @@ void StdMeshers_SegmentLengthAroundVertex_i::SetLength( CORBA::Double theLength
   }
 
   // Update Python script
-  SMESH::TPythonDump() << _this() << ".SetLength( " << theLength << " )";
+  SMESH::TPythonDump() << _this() << ".SetLength( " << SMESH::TVar(theLength) << " )";
 }
 
 //=============================================================================
@@ -137,3 +137,13 @@ CORBA::Boolean StdMeshers_SegmentLengthAroundVertex_i::IsDimSupported( SMESH::Di
   return type == SMESH::DIM_1D;
 }
 
+//================================================================================
+/*!
+ * \brief Return method name corresponding to index of variable parameter
+ */
+//================================================================================
+
+std::string StdMeshers_SegmentLengthAroundVertex_i::getMethodOfParameter(const int, int ) const
+{
+  return "SetLength";
+}
index 2add0396a7dd1a7e6f4ca7cfe6601acce33c49d6..220a7e733e405c6b805cca39f4262537e450ffea 100644 (file)
@@ -1,28 +1,28 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_SegmentLengthAroundVertex_i.hxx
 //  Module : SMESH
-//  $Header$
 //
 #ifndef _SMESH_SegmentLengthAroundVertex_I_HXX_
 #define _SMESH_SegmentLengthAroundVertex_I_HXX_
@@ -63,6 +63,9 @@ public:
   
   // Verify whether hypothesis supports given entity type 
   CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+
+ protected:
+  virtual std::string getMethodOfParameter(const int paramIndex, int nbVars) const;
 };
 
 #endif
index 1154b63f2a2408046536a8f9fe8ebf123daa40e2..61b855a1dc111eda34f1fcf60c4d8de41862ff74 100644 (file)
@@ -1,30 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_StartEndLength_i.cxx
 //           Moved here from SMESH_LocalLength_i.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//  $Header$
 //
 #include "StdMeshers_StartEndLength_i.hxx"
 #include "SMESH_Gen_i.hxx"
@@ -90,12 +90,37 @@ void StdMeshers_StartEndLength_i::SetLength(CORBA::Double theLength,
   }
   catch ( SALOME_Exception& S_ex ) {
     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
-                                 SALOME::BAD_PARAM );
+                                  SALOME::BAD_PARAM );
   }
 
   // Update Python script
-  SMESH::TPythonDump() << _this() << ".SetLength( "
-                       << theLength << ", " << theIsStart << " )";
+  SMESH::TPythonDump() <<
+    _this() << ( theIsStart ? ".SetStartLength( " : ".SetEndLength( " ) <<
+    SMESH::TVar(theLength) << " )";
+}
+
+//=============================================================================
+/*!
+ * Sets <start segment length> parameter value
+ */
+//=============================================================================
+
+void StdMeshers_StartEndLength_i::SetStartLength( CORBA::Double length)
+  throw (SALOME::SALOME_Exception)
+{
+  SetLength( length, true );
+}
+
+//=============================================================================
+/*!
+ * Sets <end segment length> parameter value
+ */
+//=============================================================================
+
+void StdMeshers_StartEndLength_i::SetEndLength( CORBA::Double length)
+  throw (SALOME::SALOME_Exception)
+{
+  SetLength( length, false );
 }
 
 //=============================================================================
@@ -113,6 +138,97 @@ CORBA::Double StdMeshers_StartEndLength_i::GetLength( CORBA::Boolean theIsStart)
   return this->GetImpl()->GetLength( theIsStart );
 }
 
+//=============================================================================
+/*!
+ *  StdMeshers_StartEndLength_i::SetReversedEdges
+ *
+ *  Set edges to reverse
+ */
+//=============================================================================
+
+void StdMeshers_StartEndLength_i::SetReversedEdges( const SMESH::long_array& theIds )
+{
+  ASSERT( myBaseImpl );
+  try {
+    std::vector<int> ids( theIds.length() );
+    CORBA::Long iEnd = theIds.length();
+    for ( CORBA::Long i = 0; i < iEnd; i++ )
+      ids[ i ] = theIds[ i ];
+
+    this->GetImpl()->SetReversedEdges( ids );
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
+                                  SALOME::BAD_PARAM );
+  }
+
+  // Update Python script
+  SMESH::TPythonDump() << _this() << ".SetReversedEdges( " << theIds << " )";
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_StartEndLength_i::SetObjectEntry
+ *
+ *  Set the Entry for the Main Object
+ */
+//=============================================================================
+
+void StdMeshers_StartEndLength_i::SetObjectEntry( const char* theEntry )
+{
+  ASSERT( myBaseImpl );
+  string entry(theEntry); // actually needed as theEntry is spoiled by moment of dumping
+  try {
+    this->GetImpl()->SetObjectEntry( entry.c_str() );
+    // Update Python script
+    SMESH::TPythonDump() << _this() << ".SetObjectEntry( '" << entry.c_str() << "' )";
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),SALOME::BAD_PARAM );
+  }
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_StartEndLength_i::GetObjectEntry
+ *
+ *  Set the Entry for the Main Object
+ */
+//=============================================================================
+
+char* StdMeshers_StartEndLength_i::GetObjectEntry()
+{
+  ASSERT( myBaseImpl );
+  const char* entry;
+  try {
+    entry = this->GetImpl()->GetObjectEntry();
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM );
+  }
+  return CORBA::string_dup( entry );
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_StartEndLength_i::GetReversedEdges
+ *
+ *  Get reversed edges
+ */
+//=============================================================================
+
+SMESH::long_array* StdMeshers_StartEndLength_i::GetReversedEdges()
+{
+  ASSERT( myBaseImpl );
+  SMESH::long_array_var anArray = new SMESH::long_array;
+  std::vector<int> ids = this->GetImpl()->GetReversedEdges();
+  anArray->length( ids.size() );
+  for ( CORBA::Long i = 0; i < ids.size(); i++)
+    anArray [ i ] = ids [ i ];
+
+  return anArray._retn();
+}
+
 //=============================================================================
 /*!
  *  StdMeshers_StartEndLength_i::GetImpl
@@ -141,3 +257,14 @@ CORBA::Boolean StdMeshers_StartEndLength_i::IsDimSupported( SMESH::Dimension typ
   return type == SMESH::DIM_1D;
 }
 
+//================================================================================
+/*!
+ * \brief Return method name corresponding to index of variable parameter
+ */
+//================================================================================
+
+std::string StdMeshers_StartEndLength_i::getMethodOfParameter(const int paramIndex,
+                                                              int       /*nbVars*/) const
+{
+  return paramIndex == 0 ? "SetStartLength" : "SetEndLength";
+}
index d7a4c4bcd17795ca00ea63ab43db06376dc4bba9..7eeb70e17ea1c1e16c6b65c222af87d9967e147d 100644 (file)
@@ -1,30 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_StartEndLength_i.hxx
 //           Moved here from SMESH_LocalLength_i.hxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//  $Header$
 //
 #ifndef _SMESH_StartEndLength_I_HXX_
 #define _SMESH_StartEndLength_I_HXX_
@@ -55,8 +55,16 @@ public:
   virtual ~StdMeshers_StartEndLength_i();
 
   // Set length
+  // * OBSOLETE *. Avoid such a way of interface design
   void SetLength( CORBA::Double theLength, CORBA::Boolean theIsStart )
     throw ( SALOME::SALOME_Exception );
+
+  // Sets <start segment length> parameter value
+  void SetStartLength( CORBA::Double length) throw (SALOME::SALOME_Exception);
+
+  // Sets <end segment length> parameter value
+  void SetEndLength( CORBA::Double length) throw (SALOME::SALOME_Exception);
+
   // Get length
   CORBA::Double GetLength(CORBA::Boolean theIsStart);
 
@@ -65,7 +73,21 @@ public:
   
   // Verify whether hypothesis supports given entity type 
   CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+
+  //Set Reversed Edges
+  void SetReversedEdges( const SMESH::long_array& theIDs);
+
+  //Get Reversed Edges
+  SMESH::long_array*  GetReversedEdges();
+
+  //Set Object Entry
+  void SetObjectEntry( const char* entry);
+
+  //Get Object Entry
+  char* GetObjectEntry();
+
+ protected:
+  virtual std::string getMethodOfParameter(const int paramIndex, int nbVars) const;
 };
 
 #endif
-
diff --git a/src/StdMeshers_I/StdMeshers_TrianglePreference_i.cxx b/src/StdMeshers_I/StdMeshers_TrianglePreference_i.cxx
deleted file mode 100644 (file)
index 330216d..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-//  File   : StdMeshers_TrianglePreference_i.cxx
-//  Author : 
-//  Module : SMESH
-//
-#include "StdMeshers_TrianglePreference_i.hxx"
-#include "SMESH_Gen_i.hxx"
-#include "SMESH_Gen.hxx"
-
-#include "Utils_CorbaException.hxx"
-#include "utilities.h"
-
-#include <TCollection_AsciiString.hxx>
-
-using namespace std;
-
-//=============================================================================
-/*!
- *  StdMeshers_TrianglePreference_i::StdMeshers_TrianglePreference_i
- *
- *  Constructor
- */
-//=============================================================================
-
-StdMeshers_TrianglePreference_i::StdMeshers_TrianglePreference_i
-( PortableServer::POA_ptr thePOA,
-  int                     theStudyId,
-  ::SMESH_Gen*            theGenImpl ): SALOME::GenericObj_i( thePOA ), 
-                                        SMESH_Hypothesis_i( thePOA )
-{
-  myBaseImpl = new ::StdMeshers_TrianglePreference( theGenImpl->GetANewId(),
-                                                    theStudyId,
-                                                    theGenImpl );
-}
-
-//=============================================================================
-/*!
- *  StdMeshers_TrianglePreference_i::~StdMeshers_TrianglePreference_i
- *
- *  Destructor
- */
-//=============================================================================
-
-StdMeshers_TrianglePreference_i::~StdMeshers_TrianglePreference_i()
-{
-}
-
-//=============================================================================
-/*!
- *  StdMeshers_TrianglePreference_i::GetImpl
- *
- *  Get implementation
- */
-//=============================================================================
-
-::StdMeshers_TrianglePreference* StdMeshers_TrianglePreference_i::GetImpl()
-{
-  return ( ::StdMeshers_TrianglePreference* )myBaseImpl;
-}
-
-//================================================================================
-/*!
- * \brief Verify whether hypothesis supports given entity type 
-  * \param type - dimension (see SMESH::Dimension enumeration)
-  * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise
- * 
- * Verify whether hypothesis supports given entity type (see SMESH::Dimension enumeration)
- */
-//================================================================================  
-
-CORBA::Boolean StdMeshers_TrianglePreference_i::IsDimSupported( SMESH::Dimension type )
-{
-  return type == SMESH::DIM_2D;
-}
-
diff --git a/src/StdMeshers_I/StdMeshers_TrianglePreference_i.hxx b/src/StdMeshers_I/StdMeshers_TrianglePreference_i.hxx
deleted file mode 100644 (file)
index ce48263..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  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.com
-//
-//  File   : StdMeshers_TrianglePreference_i.hxx
-//  Author : 
-//  Module : SMESH
-//
-#ifndef _SMESH_TrianglePreference_I_HXX_
-#define _SMESH_TrianglePreference_I_HXX_
-
-#include "SMESH_StdMeshers_I.hxx"
-
-#include <SALOMEconfig.h>
-#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
-
-#include "SMESH_Hypothesis_i.hxx"
-#include "StdMeshers_TrianglePreference.hxx"
-
-class SMESH_Gen;
-
-class STDMESHERS_I_EXPORT StdMeshers_TrianglePreference_i:
-  public virtual POA_StdMeshers::StdMeshers_TrianglePreference,
-  public virtual SMESH_Hypothesis_i
-{
-public:
-  // Constructor
-  StdMeshers_TrianglePreference_i( PortableServer::POA_ptr thePOA,
-                                     int                     theStudyId,
-                                     ::SMESH_Gen*            theGenImpl );
-  // Destructor
-  virtual ~StdMeshers_TrianglePreference_i();
-
-  // Get implementation
-  ::StdMeshers_TrianglePreference* GetImpl();
-  
-  // Verify whether hypothesis supports given entity type 
-  CORBA::Boolean IsDimSupported( SMESH::Dimension type );
-};
-
-#endif //_SMESH_TrianglePreference_I_HXX_
index 63814d21806b9c89c5baaa7cff1b35330afcebd9..1ca4f2038f882d2df28df59abd93d4c04307c17f 100644 (file)
@@ -1,24 +1,22 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  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 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.
 //
-//  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
 //
-//  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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_Projection_3D_i.cxx
 //           Moved here from SMESH_Projection_3D_i.cxx
index 32035e3c1bfe403b64c2130b23453af8079cc499..77f019fbfc9b6ca2c33b9de3e15b123ee9eb4a23 100644 (file)
@@ -1,24 +1,22 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  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 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.
 //
-//  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
 //
-//  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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : StdMeshers_UseExisting_1D2D.hxx
 //  Module : SMESH
diff --git a/src/StdMeshers_I/StdMeshers_ViscousLayers_i.cxx b/src/StdMeshers_I/StdMeshers_ViscousLayers_i.cxx
new file mode 100644 (file)
index 0000000..55ca30d
--- /dev/null
@@ -0,0 +1,231 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//  File   : StdMeshers_ViscousLayers_i.cxx
+//  Module : SMESH
+//
+#include "StdMeshers_ViscousLayers_i.hxx"
+
+#include "SMESH_Gen.hxx"
+#include "SMESH_Gen_i.hxx"
+#include "SMESH_PythonDump.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+#include <TCollection_AsciiString.hxx>
+
+#include CORBA_SERVER_HEADER(SMESH_Group)
+
+using namespace std;
+
+//=============================================================================
+/*!
+ *  StdMeshers_ViscousLayers_i::StdMeshers_ViscousLayers_i
+ *
+ *  Constructor
+ */
+//=============================================================================
+
+StdMeshers_ViscousLayers_i::StdMeshers_ViscousLayers_i( PortableServer::POA_ptr thePOA,
+                                                        int                     theStudyId,
+                                                        ::SMESH_Gen*            theGenImpl )
+  : SALOME::GenericObj_i( thePOA ), 
+    SMESH_Hypothesis_i( thePOA )
+{
+  MESSAGE( "StdMeshers_ViscousLayers_i::StdMeshers_ViscousLayers_i" );
+  myBaseImpl = new ::StdMeshers_ViscousLayers( theGenImpl->GetANewId(),
+                                               theStudyId,
+                                               theGenImpl );
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_ViscousLayers_i::~StdMeshers_ViscousLayers_i
+ *
+ *  Destructor
+ */
+//=============================================================================
+
+StdMeshers_ViscousLayers_i::~StdMeshers_ViscousLayers_i()
+{
+  MESSAGE( "StdMeshers_ViscousLayers_i::~StdMeshers_ViscousLayers_i" );
+}
+
+//================================================================================
+/*!
+ * \brief 
+ */
+//================================================================================
+
+void StdMeshers_ViscousLayers_i::SetIgnoreFaces(const ::SMESH::long_array& faceIDs)
+throw ( SALOME::SALOME_Exception )
+{
+  vector<int> ids( faceIDs.length() );
+  for ( unsigned i = 0; i < ids.size(); ++i )
+    if (( ids[i] = faceIDs[i] ) < 1 )
+      THROW_SALOME_CORBA_EXCEPTION( "Invalid face id", SALOME::BAD_PARAM );
+  GetImpl()->SetIgnoreFaces( ids );
+  SMESH::TPythonDump() << _this() << ".SetIgnoreFaces( " << faceIDs << " )";
+}
+
+//================================================================================
+/*!
+ * \brief 
+ */
+//================================================================================
+
+SMESH::long_array* StdMeshers_ViscousLayers_i::GetIgnoreFaces()
+{
+  vector<int> idsVec = GetImpl()->GetIgnoreFaces();
+  SMESH::long_array_var ids = new SMESH::long_array;
+  ids->length( idsVec.size() );
+  for ( unsigned i = 0; i < idsVec.size(); ++i )
+    ids[i] = idsVec[i];
+  return ids._retn();
+}
+
+//================================================================================
+/*!
+ * \brief 
+ */
+//================================================================================
+
+void StdMeshers_ViscousLayers_i::SetTotalThickness(::CORBA::Double thickness)
+throw ( SALOME::SALOME_Exception )
+{
+  if ( thickness < 1e-100 )
+    THROW_SALOME_CORBA_EXCEPTION( "Invalid thickness", SALOME::BAD_PARAM );
+  GetImpl()->SetTotalThickness(thickness);
+  SMESH::TPythonDump() << _this() << ".SetTotalThickness( " << SMESH::TVar(thickness) << " )";
+}
+
+//================================================================================
+/*!
+ * \brief 
+ */
+//================================================================================
+
+::CORBA::Double StdMeshers_ViscousLayers_i::GetTotalThickness()
+{
+  return GetImpl()->GetTotalThickness();
+}
+
+//================================================================================
+/*!
+ * \brief 
+ *  \param nb - 
+ */
+//================================================================================
+
+void StdMeshers_ViscousLayers_i::SetNumberLayers(::CORBA::Short nb)
+throw ( SALOME::SALOME_Exception )
+{
+  if ( nb < 1 )
+    THROW_SALOME_CORBA_EXCEPTION( "Invalid number of layers", SALOME::BAD_PARAM );
+  GetImpl()->SetNumberLayers( nb );
+  SMESH::TPythonDump() << _this() << ".SetNumberLayers( " << SMESH::TVar(nb) << " )";
+}
+
+//================================================================================
+/*!
+ * \brief 
+ */
+//================================================================================
+
+::CORBA::Short StdMeshers_ViscousLayers_i::GetNumberLayers()
+{
+  return CORBA::Short( GetImpl()->GetNumberLayers() );
+}
+
+//================================================================================
+/*!
+ * \brief 
+ *  \param factor - 
+ */
+//================================================================================
+
+void StdMeshers_ViscousLayers_i::SetStretchFactor(::CORBA::Double factor)
+throw ( SALOME::SALOME_Exception )
+{
+  if ( factor < 1 )
+    THROW_SALOME_CORBA_EXCEPTION( "Invalid stretch factor, it must be >= 1.0", SALOME::BAD_PARAM );
+  GetImpl()->SetStretchFactor(factor);
+  SMESH::TPythonDump() << _this() << ".SetStretchFactor( " << SMESH::TVar(factor) << " )";
+}
+
+//================================================================================
+/*!
+ * \brief 
+ * 
+ */
+//================================================================================
+
+::CORBA::Double StdMeshers_ViscousLayers_i::GetStretchFactor()
+{
+  return GetImpl()->GetStretchFactor();
+}
+
+//=============================================================================
+/*!
+ *  Get implementation
+ */
+//=============================================================================
+
+::StdMeshers_ViscousLayers* StdMeshers_ViscousLayers_i::GetImpl()
+{
+  MESSAGE( "StdMeshers_ViscousLayers_i::GetImpl" );
+  return ( ::StdMeshers_ViscousLayers* )myBaseImpl;
+}
+
+//================================================================================
+/*!
+ * \brief Verify whether hypothesis supports given entity type 
+  * \param type - dimension (see SMESH::Dimension enumeration)
+  * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise
+ * 
+ * Verify whether hypothesis supports given entity type (see SMESH::Dimension enumeration)
+ */
+//================================================================================  
+CORBA::Boolean StdMeshers_ViscousLayers_i::IsDimSupported( SMESH::Dimension type )
+{
+  return type == SMESH::DIM_3D;
+}
+
+//================================================================================
+/*!
+ * \brief Return method name corresponding to index of variable parameter
+ */
+//================================================================================
+
+std::string StdMeshers_ViscousLayers_i::getMethodOfParameter(const int paramIndex, int ) const
+{
+  // order of methods was defined by StdMeshersGUI_StdHypothesisCreator::storeParams()
+  switch ( paramIndex )
+  {
+  case 0: return "SetTotalThickness";
+  case 1: return "SetNumberLayers";
+  case 2: return "SetStretchFactor";
+  }
+  return "";
+}
diff --git a/src/StdMeshers_I/StdMeshers_ViscousLayers_i.hxx b/src/StdMeshers_I/StdMeshers_ViscousLayers_i.hxx
new file mode 100644 (file)
index 0000000..e4d5d6e
--- /dev/null
@@ -0,0 +1,74 @@
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  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.com
+//
+
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//  File   : StdMeshers_ViscousLayers_i.hxx
+//  Module : SMESH
+//
+#ifndef _SMESH_ViscousLayers_I_HXX_
+#define _SMESH_ViscousLayers_I_HXX_
+
+#include "SMESH_StdMeshers_I.hxx"
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_Hypothesis_i.hxx"
+#include "StdMeshers_ViscousLayers.hxx"
+
+class SMESH_Gen;
+
+class STDMESHERS_I_EXPORT StdMeshers_ViscousLayers_i:
+  public virtual POA_StdMeshers::StdMeshers_ViscousLayers,
+  public virtual SMESH_Hypothesis_i
+{
+ public:
+  // Constructor
+  StdMeshers_ViscousLayers_i( PortableServer::POA_ptr thePOA,
+                              int                     theStudyId,
+                              ::SMESH_Gen*            theGenImpl );
+  // Destructor
+  virtual ~StdMeshers_ViscousLayers_i();
+
+  void SetIgnoreFaces(const ::SMESH::long_array& faceIDs) throw ( SALOME::SALOME_Exception );
+  SMESH::long_array* GetIgnoreFaces();
+
+  void SetTotalThickness(::CORBA::Double thickness) throw ( SALOME::SALOME_Exception );
+  ::CORBA::Double GetTotalThickness();
+
+  void SetNumberLayers(::CORBA::Short nb) throw ( SALOME::SALOME_Exception );
+  ::CORBA::Short GetNumberLayers();
+
+  void SetStretchFactor(::CORBA::Double factor) throw ( SALOME::SALOME_Exception );
+  ::CORBA::Double GetStretchFactor();
+
+  // Get implementation
+  ::StdMeshers_ViscousLayers* GetImpl();
+
+  // Verify whether hypothesis supports given entity type 
+  CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+
+ protected:
+  virtual std::string getMethodOfParameter(const int paramIndex, int nbVars) const;
+};
+
+#endif
index 8d73b56d8d5a75a1ff7700af1af4498c4e368134..20104d9c8755a58f82e984fff2825fbaef6731c5 100644 (file)
@@ -1,29 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  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 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.
+// 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
+// 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.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 //  SMESH StdMeshers : implementaion of SMESH idl descriptions
 //  File   : StdMeshers_i.cxx
 //  Author : Julia DOROVSKIKH
 //  Module : SMESH
-
+//
 #include "SMESH_StdMeshers_I.hxx"
 
 #include "SMESH_Gen_i.hxx"
 #include "StdMeshers_AutomaticLength_i.hxx"
 #include "StdMeshers_StartEndLength_i.hxx"
 #include "StdMeshers_Arithmetic1D_i.hxx"
+#include "StdMeshers_FixedPoints1D_i.hxx"
 #include "StdMeshers_NumberOfSegments_i.hxx"
 #include "StdMeshers_Deflection1D_i.hxx"
 #include "StdMeshers_Propagation_i.hxx"
 #include "StdMeshers_LengthFromEdges_i.hxx"
 #include "StdMeshers_QuadranglePreference_i.hxx"
-#include "StdMeshers_TrianglePreference_i.hxx"
+//#include "StdMeshers_TrianglePreference_i.hxx"
 #include "StdMeshers_QuadraticMesh_i.hxx"
 #include "StdMeshers_MaxElementArea_i.hxx"
 #include "StdMeshers_MaxElementVolume_i.hxx"
 #include "StdMeshers_ProjectionSource1D_i.hxx"
 #include "StdMeshers_NumberOfLayers_i.hxx"
 #include "StdMeshers_LayerDistribution_i.hxx"
+#include "StdMeshers_NumberOfLayers2D_i.hxx"
+#include "StdMeshers_LayerDistribution2D_i.hxx"
 #include "StdMeshers_SegmentLengthAroundVertex_i.hxx"
 #include "StdMeshers_MaxLength_i.hxx"
+#include "StdMeshers_QuadrangleParams_i.hxx"
+#include "StdMeshers_ImportSource1D_i.hxx"
+#include "StdMeshers_ImportSource2D_i.hxx"
+#include "StdMeshers_Cartesian_3D_i.hxx"
 
 #include "StdMeshers_Regular_1D_i.hxx"
 #include "StdMeshers_MEFISTO_2D_i.hxx"
 #include "StdMeshers_SegmentAroundVertex_0D_i.hxx"
 #include "StdMeshers_CompositeSegment_1D_i.hxx"
 #include "StdMeshers_UseExisting_1D2D_i.hxx"
-
+#include "StdMeshers_RadialQuadrangle_1D2D_i.hxx"
+#include "StdMeshers_Import_1D_i.hxx"
+#include "StdMeshers_Import_1D2D_i.hxx"
+#include "StdMeshers_ViscousLayers_i.hxx"
+#include "StdMeshers_CartesianParameters3D_i.hxx"
 
 template <class T> class StdHypothesisCreator_i:public HypothesisCreator_i<T>
 {
+public:
   // as we have 'module StdMeshers' in SMESH_BasicHypothesis.idl
   virtual std::string GetModuleName() { return "StdMeshers"; }
 };
 
+//=============================================================================
+/*!
+ * \brief Creates StdMeshers_QuadrangleParams_i instead of
+ * StdMeshers_TrianglePreference_i and StdMeshers_QuadranglePreference_i
+ */
+//=============================================================================
+
+template <StdMeshers::QuadType TYPE>
+class QuadrangleParamsCreator : public StdHypothesisCreator_i<StdMeshers_QuadrangleParams_i>
+{
+public:
+  virtual SMESH_Hypothesis_i* Create (PortableServer::POA_ptr thePOA,
+                                      int                     theStudyId,
+                                      ::SMESH_Gen*            theGenImpl)
+  {
+    StdMeshers_QuadrangleParams_i* h =
+      new StdMeshers_QuadrangleParams_i( thePOA, theStudyId, theGenImpl);
+    h->SetQuadType( TYPE );
+    return h;
+  }
+};
+
 //=============================================================================
 /*!
  *
@@ -105,14 +140,19 @@ STDMESHERS_I_EXPORT
       aCreator = new StdHypothesisCreator_i<StdMeshers_StartEndLength_i>;
     else if (strcmp(aHypName, "Deflection1D") == 0)
       aCreator = new StdHypothesisCreator_i<StdMeshers_Deflection1D_i>;
+    else if (strcmp(aHypName, "FixedPoints1D") == 0)
+      aCreator = new StdHypothesisCreator_i<StdMeshers_FixedPoints1D_i>;
     else if (strcmp(aHypName, "Arithmetic1D") == 0)
       aCreator = new StdHypothesisCreator_i<StdMeshers_Arithmetic1D_i>;
     else if (strcmp(aHypName, "AutomaticLength") == 0)
       aCreator = new StdHypothesisCreator_i<StdMeshers_AutomaticLength_i>;
     else if (strcmp(aHypName, "QuadranglePreference") == 0)
+      // do not convert to StdMeshers_QuadrangleParams_i as it is used by NETGEN 2D
       aCreator = new StdHypothesisCreator_i<StdMeshers_QuadranglePreference_i>;
+      //aCreator = new QuadrangleParamsCreator< StdMeshers::QUAD_QUADRANGLE_PREF >();
     else if (strcmp(aHypName, "TrianglePreference") == 0)
-      aCreator = new StdHypothesisCreator_i<StdMeshers_TrianglePreference_i>;
+      //aCreator = new StdHypothesisCreator_i<StdMeshers_TrianglePreference_i>;
+      aCreator = new QuadrangleParamsCreator< StdMeshers::QUAD_TRIANGLE_PREF >();
     else if (strcmp(aHypName, "QuadraticMesh") == 0)
       aCreator = new StdHypothesisCreator_i<StdMeshers_QuadraticMesh_i>;
     else if (strcmp(aHypName, "ProjectionSource3D") == 0)
@@ -125,8 +165,22 @@ STDMESHERS_I_EXPORT
       aCreator = new StdHypothesisCreator_i<StdMeshers_NumberOfLayers_i>;
     else if (strcmp(aHypName, "LayerDistribution") == 0)
       aCreator = new StdHypothesisCreator_i<StdMeshers_LayerDistribution_i>;
+    else if (strcmp(aHypName, "NumberOfLayers2D") == 0)
+      aCreator = new StdHypothesisCreator_i<StdMeshers_NumberOfLayers2D_i>;
+    else if (strcmp(aHypName, "LayerDistribution2D") == 0)
+      aCreator = new StdHypothesisCreator_i<StdMeshers_LayerDistribution2D_i>;
     else if (strcmp(aHypName, "SegmentLengthAroundVertex") == 0)
       aCreator = new StdHypothesisCreator_i<StdMeshers_SegmentLengthAroundVertex_i>;
+    else if (strcmp(aHypName, "QuadrangleParams") == 0)
+      aCreator = new StdHypothesisCreator_i<StdMeshers_QuadrangleParams_i>;
+    else if (strcmp(aHypName, "ImportSource1D") == 0)
+      aCreator = new StdHypothesisCreator_i<StdMeshers_ImportSource1D_i>;
+    else if (strcmp(aHypName, "ImportSource2D") == 0)
+      aCreator = new StdHypothesisCreator_i<StdMeshers_ImportSource2D_i>;
+    else if (strcmp(aHypName, "ViscousLayers") == 0)
+      aCreator = new StdHypothesisCreator_i<StdMeshers_ViscousLayers_i>;
+    else if (strcmp(aHypName, "CartesianParameters3D") == 0)
+      aCreator = new StdHypothesisCreator_i<StdMeshers_CartesianParameters3D_i>;
 
     // Algorithms
     else if (strcmp(aHypName, "Regular_1D") == 0)
@@ -139,6 +193,8 @@ STDMESHERS_I_EXPORT
       aCreator = new StdHypothesisCreator_i<StdMeshers_Hexa_3D_i>;
     else if (strcmp(aHypName, "Projection_1D") == 0)
       aCreator = new StdHypothesisCreator_i<StdMeshers_Projection_1D_i>;
+    else if (strcmp(aHypName, "Projection_1D2D") == 0)
+      aCreator = new StdHypothesisCreator_i<StdMeshers_Projection_1D2D_i>;
     else if (strcmp(aHypName, "Projection_2D") == 0)
       aCreator = new StdHypothesisCreator_i<StdMeshers_Projection_2D_i>;
     else if (strcmp(aHypName, "Projection_3D") == 0)
@@ -155,6 +211,14 @@ STDMESHERS_I_EXPORT
       aCreator = new StdHypothesisCreator_i<StdMeshers_UseExisting_1D_i>;
     else if (strcmp(aHypName, "UseExisting_2D") == 0)
       aCreator = new StdHypothesisCreator_i<StdMeshers_UseExisting_2D_i>;
+    else if (strcmp(aHypName, "RadialQuadrangle_1D2D") == 0)
+      aCreator = new StdHypothesisCreator_i<StdMeshers_RadialQuadrangle_1D2D_i>;
+    else if (strcmp(aHypName, "Import_1D") == 0)
+      aCreator = new StdHypothesisCreator_i<StdMeshers_Import_1D_i>;
+    else if (strcmp(aHypName, "Import_1D2D") == 0)
+      aCreator = new StdHypothesisCreator_i<StdMeshers_Import_1D2D_i>;
+    else if (strcmp(aHypName, "Cartesian_3D") == 0)
+      aCreator = new StdHypothesisCreator_i<StdMeshers_Cartesian_3D_i>;
     else ;
 
     return aCreator;
diff --git a/src/Tools/Makefile.am b/src/Tools/Makefile.am
new file mode 100644 (file)
index 0000000..cae255b
--- /dev/null
@@ -0,0 +1,31 @@
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# 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.com
+#
+
+#  File   : Makefile.in
+#  Author : Patrick GOLDBRONN (CEA)
+#  Modified by : Alexander BORODIN (OCN) - autotools usage
+#  Module : SMESH
+#  $Header$
+#
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+SUBDIRS = MeshCut padder
+
+salomeplugins_PYTHON = \
+       smesh_plugins.py
diff --git a/src/Tools/MeshCut/AUTHORS b/src/Tools/MeshCut/AUTHORS
new file mode 100644 (file)
index 0000000..28f414d
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright (C) 2006-2012  EDF R&D
+//
+// 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.com
+//
+// Authors: Jean Claude LALEUF, Jean Francois HERY, XMESHLAB project, EDF R&D
diff --git a/src/Tools/MeshCut/Makefile.am b/src/Tools/MeshCut/Makefile.am
new file mode 100644 (file)
index 0000000..d09c3bb
--- /dev/null
@@ -0,0 +1,59 @@
+# Copyright (C) 2007-2012  EDF R&D
+#
+# 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.com
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+
+bin_PROGRAMS = MeshCut
+
+MeshCut_SOURCES = \
+  MeshCut_Globals.hxx \
+  MeshCut_Carre.hxx \
+  MeshCut_Carre.cxx \
+  MeshCut_Cube.hxx \
+  MeshCut_Cube.cxx \
+  MeshCut_Maillage.hxx \
+  MeshCut_Maillage.cxx \
+  MeshCut_Fonctions.hxx \
+  MeshCut_Fonctions.cxx \
+  MeshCut_Utils.hxx \
+  MeshCut_Utils.cxx \
+  MeshCut_Cas.hxx \
+  MeshCut_Cas.cxx \
+  MeshCut_DC.cxx
+
+MeshCut_CPPFLAGS =  $(MED3_INCLUDES)
+
+MeshCut_LDFLAGS =  $(MED3_LIBS) $(HDF5_LIBS)
+
+salomeplugins_PYTHON = \
+       meshcut_plugin.py
+
+UIPY_FILES =  MeshCutDialog.py
+
+if SMESH_ENABLE_GUI
+  nodist_salomescript_SCRIPTS = $(UIPY_FILES)
+endif
+
+CLEANFILES = $(UIPY_FILES)
+
+EXTRA_DIST += $(UIPY_FILES:%.py=%.ui)
+
+%.py : %.ui
+       $(PYUIC) $< -o $@
diff --git a/src/Tools/MeshCut/MeshCutDialog.ui b/src/Tools/MeshCut/MeshCutDialog.ui
new file mode 100644 (file)
index 0000000..a7f29b4
--- /dev/null
@@ -0,0 +1,273 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>416</width>
+    <height>431</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>cut a mesh by a plane</string>
+  </property>
+  <property name="sizeGripEnabled">
+   <bool>false</bool>
+  </property>
+  <layout class="QGridLayout" name="gridLayout_5">
+   <item row="0" column="0">
+    <layout class="QGridLayout" name="gridLayout_4">
+     <item row="0" column="0">
+      <widget class="QPushButton" name="pb_origMeshFile">
+       <property name="text">
+        <string>original mesh file</string>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="1">
+      <widget class="QLineEdit" name="le_origMeshFile"/>
+     </item>
+     <item row="3" column="0" colspan="2">
+      <layout class="QGridLayout" name="gridLayout_3">
+       <item row="0" column="0">
+        <widget class="QLabel" name="label">
+         <property name="text">
+          <string>output mesh name</string>
+         </property>
+        </widget>
+       </item>
+       <item row="0" column="1">
+        <widget class="QLineEdit" name="le_outMeshName">
+         <property name="text">
+          <string>meshCut</string>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="0">
+        <widget class="QLabel" name="label_2">
+         <property name="text">
+          <string>name of group above cut</string>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="1">
+        <widget class="QLineEdit" name="le_groupAbove">
+         <property name="text">
+          <string>above</string>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="0">
+        <widget class="QLabel" name="label_3">
+         <property name="text">
+          <string>name of group below cut</string>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="1">
+        <widget class="QLineEdit" name="le_groupBelow">
+         <property name="text">
+          <string>below</string>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </item>
+     <item row="4" column="0" colspan="2">
+      <widget class="QGroupBox" name="groupBox">
+       <property name="title">
+        <string>cut plane</string>
+       </property>
+       <layout class="QGridLayout" name="gridLayout_2">
+        <item row="0" column="0">
+         <layout class="QGridLayout" name="gridLayout">
+          <item row="0" column="0">
+           <widget class="QLabel" name="label_4">
+            <property name="text">
+             <string>normal vector</string>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="1">
+           <widget class="QLabel" name="label_5">
+            <property name="text">
+             <string>vertex in plane</string>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="0">
+           <widget class="QDoubleSpinBox" name="dsb_normX">
+            <property name="minimum">
+             <double>-999999999.000000000000000</double>
+            </property>
+            <property name="maximum">
+             <double>999999999.000000000000000</double>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="0">
+           <widget class="QDoubleSpinBox" name="dsb_normY">
+            <property name="minimum">
+             <double>-999999999.000000000000000</double>
+            </property>
+            <property name="maximum">
+             <double>999999999.000000000000000</double>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="1">
+           <widget class="QDoubleSpinBox" name="dsb_vertY">
+            <property name="minimum">
+             <double>-999999999.000000000000000</double>
+            </property>
+            <property name="maximum">
+             <double>999999999.000000000000000</double>
+            </property>
+           </widget>
+          </item>
+          <item row="3" column="0">
+           <widget class="QDoubleSpinBox" name="dsb_normZ">
+            <property name="minimum">
+             <double>-999999999.000000000000000</double>
+            </property>
+            <property name="maximum">
+             <double>999999999.000000000000000</double>
+            </property>
+            <property name="value">
+             <double>1.000000000000000</double>
+            </property>
+           </widget>
+          </item>
+          <item row="3" column="1">
+           <widget class="QDoubleSpinBox" name="dsb_vertZ">
+            <property name="minimum">
+             <double>-999999999.000000000000000</double>
+            </property>
+            <property name="maximum">
+             <double>999999999.000000000000000</double>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="1">
+           <widget class="QDoubleSpinBox" name="dsb_vertX">
+            <property name="minimum">
+             <double>-999999999.000000000000000</double>
+            </property>
+            <property name="maximum">
+             <double>999999999.000000000000000</double>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </item>
+       </layout>
+      </widget>
+     </item>
+     <item row="5" column="0" colspan="2">
+      <widget class="QSplitter" name="splitter">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <widget class="QLabel" name="label_6">
+        <property name="text">
+         <string>Tolerance 0 &lt; T &lt;= 1</string>
+        </property>
+       </widget>
+       <widget class="QDoubleSpinBox" name="dsb_tolerance">
+        <property name="maximum">
+         <double>1.000000000000000</double>
+        </property>
+        <property name="singleStep">
+         <double>0.010000000000000</double>
+        </property>
+        <property name="value">
+         <double>0.010000000000000</double>
+        </property>
+       </widget>
+      </widget>
+     </item>
+     <item row="6" column="0" colspan="2">
+      <spacer name="verticalSpacer">
+       <property name="orientation">
+        <enum>Qt::Vertical</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>396</width>
+         <height>90</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item row="7" column="0" colspan="2">
+      <widget class="QSplitter" name="splitter_2">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <widget class="QPushButton" name="pb_help">
+        <property name="text">
+         <string>Help</string>
+        </property>
+       </widget>
+       <widget class="QDialogButtonBox" name="pb_okCancel">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="standardButtons">
+         <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+        </property>
+       </widget>
+      </widget>
+     </item>
+     <item row="1" column="1">
+      <widget class="QLineEdit" name="le_cutMeshFile"/>
+     </item>
+     <item row="1" column="0">
+      <widget class="QPushButton" name="pb_cutMeshFile">
+       <property name="text">
+        <string>cut mesh file</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>pb_okCancel</sender>
+   <signal>accepted()</signal>
+   <receiver>Dialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>pb_okCancel</sender>
+   <signal>rejected()</signal>
+   <receiver>Dialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/src/Tools/MeshCut/MeshCut_Carre.cxx b/src/Tools/MeshCut/MeshCut_Carre.cxx
new file mode 100644 (file)
index 0000000..181a6e5
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright (C) 2006-2012  EDF R&D
+//
+// 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.com
+//
+
+#include "MeshCut_Carre.hxx"
+
+#include <iostream>
+
+using namespace MESHCUT;
+using namespace std;
+
+Carre::Carre(float _x0, float _x1, float _y0, float _y1)
+{
+  x0 = _x0;
+  x1 = _x1;
+  y0 = _y0;
+  y1 = _y1;
+}
+
+bool Carre::disjoint(Carre* c2)
+{
+  return (x0 > c2->x1 || x1 < c2->x0 || y0 > c2->y1 || y1 < c2->y0);
+}
+
+bool Carre::contientNoeud(int ngnoeud, Maillage *MAILLAGE)
+{
+  float x = *(MAILLAGE->XX + ngnoeud - 1);
+  float y = *(MAILLAGE->YY + ngnoeud - 1);
+  return (x >= x0 && x <= x1 && y >= y0 && y <= y1);
+}
+
+void Carre::affichage()
+{
+  cout << "x0=" << x0 << " ";
+  cout << "x1=" << x1 << " ";
+  cout << "y0=" << y0 << " ";
+  cout << "y1=" << y1 << " ";
+}
+
diff --git a/src/Tools/MeshCut/MeshCut_Carre.hxx b/src/Tools/MeshCut/MeshCut_Carre.hxx
new file mode 100644 (file)
index 0000000..9f6f303
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright (C) 2006-2012  EDF R&D
+//
+// 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.com
+//
+
+#ifndef __MESHCUT_CARRE_HXX__
+#define __MESHCUT_CARRE_HXX__
+
+#include "MeshCut_Maillage.hxx"
+
+namespace MESHCUT
+  {
+    class Carre
+    {
+    public:
+      float x0, x1, y0, y1;
+    public:
+      Carre(float _x0, float _x1, float _y0, float _y1);
+      bool disjoint(Carre* c2);
+      bool contientNoeud(int ngnoeud, Maillage *MAILLAGE);
+      void affichage();
+    };
+  }
+
+#endif
diff --git a/src/Tools/MeshCut/MeshCut_Cas.cxx b/src/Tools/MeshCut/MeshCut_Cas.cxx
new file mode 100644 (file)
index 0000000..16c8455
--- /dev/null
@@ -0,0 +1,945 @@
+// Copyright (C) 2006-2012  EDF R&D
+//
+// 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.com
+//
+
+#include "MeshCut_Cas.hxx"
+
+#include "MeshCut_Globals.hxx"
+
+using namespace MESHCUT;
+using namespace std;
+
+/*!
+ * Le cas 1 traduit le fait que deux des sommets du T4 initial sont dans le plan de coupe.
+ * Le point d'intersection franc trouvé est sur l'arête opposée Ã  ces deux points du T4.
+
+ * Le T4 initial produit deux nouveaux T4.
+ */
+void MESHCUT::cas1(int VN[6], int it4)
+{
+  cutTetras.push_back(it4);
+  //  cout << "Cas 1 - it4=" << it4 << ", VN = " << VN[0] << " " << VN[1] << " " << VN[2] << " " << VN[3] << " " << VN[4]
+  //      << " " << VN[5] << " " << endl;
+
+  // Numéros des noeuds du TETRA4
+  int ng0 = MAILLAGE1->CNX[TETRA4][4 * it4 + 0];
+  int ng1 = MAILLAGE1->CNX[TETRA4][4 * it4 + 1];
+  int ng2 = MAILLAGE1->CNX[TETRA4][4 * it4 + 2];
+  int ng3 = MAILLAGE1->CNX[TETRA4][4 * it4 + 3];
+
+  int i1, i2;
+
+  if (VN[0] != -1)
+    {
+      // Le sommet de T4new1 servant Ã  la détermination du groupe est le noeud 1 du T4 d'origine
+
+      // cout << "cas 1/0" << endl;
+      newCNX[TETRA4].push_back(VN[0]);
+      newCNX[TETRA4].push_back(ng1);
+      newCNX[TETRA4].push_back(ng2);
+      newCNX[TETRA4].push_back(ng3);
+      cptNouvellesMailles[TETRA4]++;
+      i1 = cptNouvellesMailles[TETRA4] - 1;
+
+      newCNX[TETRA4].push_back(ng0);
+      newCNX[TETRA4].push_back(VN[0]);
+      newCNX[TETRA4].push_back(ng2);
+      newCNX[TETRA4].push_back(ng3);
+      cptNouvellesMailles[TETRA4]++;
+      i2 = cptNouvellesMailles[TETRA4] - 1;
+
+      if (POSN[ng1 - 1] == 1)
+        {
+          GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i1);
+          GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i2);
+        }
+      else
+        {
+          GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i2);
+          GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i1);
+        }
+    }
+
+  else if (VN[1] != -1)
+    {
+      // Le sommet de T4new1 servant Ã  la détermination du groupe est le noeud 0 du T4 d'origine
+
+      // cout << "cas 1/1" << endl;
+      newCNX[TETRA4].push_back(ng0);
+      newCNX[TETRA4].push_back(ng1);
+      newCNX[TETRA4].push_back(VN[1]);
+      newCNX[TETRA4].push_back(ng3);
+      cptNouvellesMailles[TETRA4]++;
+      i1 = cptNouvellesMailles[TETRA4] - 1;
+
+      newCNX[TETRA4].push_back(ng1);
+      newCNX[TETRA4].push_back(ng2);
+      newCNX[TETRA4].push_back(VN[1]);
+      newCNX[TETRA4].push_back(ng3);
+      cptNouvellesMailles[TETRA4]++;
+      i2 = cptNouvellesMailles[TETRA4] - 1;
+
+      if (POSN[ng0 - 1] == 1)
+        {
+          GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i1);
+          GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i2);
+        }
+      else
+        {
+          GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i2);
+          GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i1);
+        }
+    }
+
+  else if (VN[2] != -1)
+    {
+      // Le sommet de T4new1 servant Ã  la détermination du groupe est le noeud 0 du T4 d'origine
+
+      // cout << "cas 1/2" << endl;
+      newCNX[TETRA4].push_back(ng0);
+      newCNX[TETRA4].push_back(ng1);
+      newCNX[TETRA4].push_back(ng2);
+      newCNX[TETRA4].push_back(VN[2]);
+      cptNouvellesMailles[TETRA4]++;
+      i1 = cptNouvellesMailles[TETRA4] - 1;
+
+      newCNX[TETRA4].push_back(ng1);
+      newCNX[TETRA4].push_back(ng2);
+      newCNX[TETRA4].push_back(VN[2]);
+      newCNX[TETRA4].push_back(ng3);
+      cptNouvellesMailles[TETRA4]++;
+      i2 = cptNouvellesMailles[TETRA4] - 1;
+
+      if (POSN[ng0 - 1] == 1)
+        {
+          GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i1);
+          GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i2);
+        }
+      else
+        {
+          GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i2);
+          GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i1);
+        }
+    }
+
+  else if (VN[3] != -1)
+    {
+      // Le sommet de T4new1 servant Ã  la détermination du groupe est le noeud 1 du T4 d'origine
+
+      // cout << "cas 1/3" << endl;
+      newCNX[TETRA4].push_back(ng0);
+      newCNX[TETRA4].push_back(ng1);
+      newCNX[TETRA4].push_back(VN[3]);
+      newCNX[TETRA4].push_back(ng3);
+      cptNouvellesMailles[TETRA4]++;
+      i1 = cptNouvellesMailles[TETRA4] - 1;
+
+      newCNX[TETRA4].push_back(ng0);
+      newCNX[TETRA4].push_back(VN[3]);
+      newCNX[TETRA4].push_back(ng2);
+      newCNX[TETRA4].push_back(ng3);
+      cptNouvellesMailles[TETRA4]++;
+      i2 = cptNouvellesMailles[TETRA4] - 1;
+
+      if (POSN[ng1 - 1] == 1)
+        {
+          GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i1);
+          GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i2);
+        }
+      else
+        {
+          GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i2);
+          GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i1);
+        }
+    }
+
+  else if (VN[4] != -1)
+    {
+      // Le sommet de T4new1 servant Ã  la détermination du groupe est le noeud 1 du T4 d'origine
+
+      // cout << "cas 1/4" << endl;
+      newCNX[TETRA4].push_back(ng0);
+      newCNX[TETRA4].push_back(ng1);
+      newCNX[TETRA4].push_back(ng2);
+      newCNX[TETRA4].push_back(VN[4]);
+      cptNouvellesMailles[TETRA4]++;
+      i1 = cptNouvellesMailles[TETRA4] - 1;
+
+      newCNX[TETRA4].push_back(ng0);
+      newCNX[TETRA4].push_back(VN[4]);
+      newCNX[TETRA4].push_back(ng2);
+      newCNX[TETRA4].push_back(ng3);
+      cptNouvellesMailles[TETRA4]++;
+      i2 = cptNouvellesMailles[TETRA4] - 1;
+
+      if (POSN[ng1 - 1] == 1)
+        {
+          GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i1);
+          GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i2);
+        }
+      else
+        {
+          GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i2);
+          GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i1);
+        }
+    }
+
+  else if (VN[5] != -1)
+    {
+      // Le sommet de T4new1 servant Ã  la détermination du groupe est le noeud 3 du T4 d'origine
+
+      // cout << "cas 1/5" << endl;
+      newCNX[TETRA4].push_back(ng0);
+      newCNX[TETRA4].push_back(ng1);
+      newCNX[TETRA4].push_back(VN[5]);
+      newCNX[TETRA4].push_back(ng3);
+      cptNouvellesMailles[TETRA4]++;
+      i1 = cptNouvellesMailles[TETRA4] - 1;
+
+      newCNX[TETRA4].push_back(ng0);
+      newCNX[TETRA4].push_back(ng1);
+      newCNX[TETRA4].push_back(ng2);
+      newCNX[TETRA4].push_back(VN[5]);
+      cptNouvellesMailles[TETRA4]++;
+      i2 = cptNouvellesMailles[TETRA4] - 1;
+
+      if (POSN[ng3 - 1] == 1)
+        {
+          GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i1);
+          GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i2);
+        }
+      else
+        {
+          GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i2);
+          GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i1);
+        }
+    }
+
+  else
+    ERREUR(" Intersections configuration not taken into account (case cptPI=1) ");
+
+  //int nl1 = MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i1;
+  //int nl2 = MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + i2;
+  // cout << "La maille TETRA4 " << it4 << " produit les mailles TETRA4-" << nl1 << " et TETRA4-" << nl2 << endl;
+
+}
+
+/*!  Deux points d'intersection
+ *  Le cas 2 traduit le fait qu'un des sommets du T4 est dans le plan de coupe.
+ *  Ce sommet est celui des quatre qui n'appartient Ã  aucune des deux arêtes sur lesquelles
+ *  un point d'intersection non -1 a Ã©té calculé.
+ *
+ *  Le T4 initial produit un nouveau T4 et un Ã©lément PYRAM5.
+ *
+ */
+void MESHCUT::cas2(int VN[6], int it4)
+{
+  cutTetras.push_back(it4);
+  //  cout << "Cas 2 - it4=" << it4 << ", VN = " << VN[0] << " " << VN[1] << " " << VN[2] << " " << VN[3] << " " << VN[4]
+  //      << " " << VN[5] << " " << endl;
+
+  // Numéros des noeuds du TETRA4
+  int ng0 = MAILLAGE1->CNX[TETRA4][4 * it4 + 0];
+  int ng1 = MAILLAGE1->CNX[TETRA4][4 * it4 + 1];
+  int ng2 = MAILLAGE1->CNX[TETRA4][4 * it4 + 2];
+  int ng3 = MAILLAGE1->CNX[TETRA4][4 * it4 + 3];
+
+  if (VN[0] != -1 && VN[1] != -1)
+    {
+      // Le sommet du nouveau T4 est le noeud 0 du T4 d'origine
+
+      // cout << "cas 2.01" << endl;
+      newCNX[TETRA4].push_back(VN[0]);
+      newCNX[TETRA4].push_back(ng3);
+      newCNX[TETRA4].push_back(VN[1]);
+      newCNX[TETRA4].push_back(ng0);
+      cptNouvellesMailles[TETRA4]++;
+
+      newCNX[PYRAM5].push_back(VN[0]);
+      newCNX[PYRAM5].push_back(ng1);
+      newCNX[PYRAM5].push_back(ng2);
+      newCNX[PYRAM5].push_back(VN[1]);
+      newCNX[PYRAM5].push_back(ng3);
+      cptNouvellesMailles[PYRAM5]++;
+
+      if (POSN[ng0 - 1] == 1)
+        {
+          GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMmoins[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1);
+        }
+      else
+        {
+          GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMplus[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1);
+        }
+    }
+  else if (VN[0] != -1 && VN[2] != -1)
+    {
+      // Le sommet du nouveau T4 est le noeud 0 du T4 d'origine
+
+      // cout << "cas 2.02" << endl;
+      newCNX[TETRA4].push_back(VN[0]);
+      newCNX[TETRA4].push_back(VN[2]);
+      newCNX[TETRA4].push_back(ng2);
+      newCNX[TETRA4].push_back(ng0);
+      cptNouvellesMailles[TETRA4]++;
+
+      newCNX[PYRAM5].push_back(VN[0]);
+      newCNX[PYRAM5].push_back(VN[2]);
+      newCNX[PYRAM5].push_back(ng3);
+      newCNX[PYRAM5].push_back(ng1);
+      newCNX[PYRAM5].push_back(ng2);
+      cptNouvellesMailles[PYRAM5]++;
+
+      if (POSN[ng0 - 1] == 1)
+        {
+          GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMmoins[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1);
+        }
+      else
+        {
+          GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMplus[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1);
+        }
+    }
+  else if (VN[0] != -1 && VN[3] != -1)
+    {
+      // Le sommet du nouveau T4 est le noeud 1 du T4 d'origine
+
+      // cout << "cas 2.03" << endl;
+      newCNX[TETRA4].push_back(VN[0]);
+      newCNX[TETRA4].push_back(VN[3]);
+      newCNX[TETRA4].push_back(ng3);
+      newCNX[TETRA4].push_back(ng1);
+      cptNouvellesMailles[TETRA4]++;
+
+      newCNX[PYRAM5].push_back(VN[0]);
+      newCNX[PYRAM5].push_back(VN[3]);
+      newCNX[PYRAM5].push_back(ng2);
+      newCNX[PYRAM5].push_back(ng0);
+      newCNX[PYRAM5].push_back(ng3);
+      cptNouvellesMailles[PYRAM5]++;
+
+      if (POSN[ng1 - 1] == 1)
+        {
+          GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMmoins[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1);
+        }
+      else
+        {
+          GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMplus[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1);
+        }
+    }
+  else if (VN[0] != -1 && VN[4] != -1)
+    {
+      // Le sommet du nouveau T4 est le noeud 1 du T4 d'origine
+
+      // cout << "cas 2.04" << endl;
+      newCNX[TETRA4].push_back(VN[0]);
+      newCNX[TETRA4].push_back(ng2);
+      newCNX[TETRA4].push_back(VN[4]);
+      newCNX[TETRA4].push_back(ng1);
+      cptNouvellesMailles[TETRA4]++;
+
+      newCNX[PYRAM5].push_back(ng0);
+      newCNX[PYRAM5].push_back(ng3);
+      newCNX[PYRAM5].push_back(VN[4]);
+      newCNX[PYRAM5].push_back(VN[0]);
+      newCNX[PYRAM5].push_back(ng2);
+      cptNouvellesMailles[PYRAM5]++;
+
+      if (POSN[ng1 - 1] == 1)
+        {
+          GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMmoins[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1);
+        }
+      else
+        {
+          GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMplus[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1);
+        }
+    }
+
+  else if (VN[0] != -1 && VN[5] != -1)
+    ERREUR("Case 2/05 forbidden");
+
+  else if (VN[1] != -1 && VN[2] != -1)
+    {
+      // Le sommet du nouveau T4 est le noeud 0 du T4 d'origine
+
+      // cout << "cas 2.12" << endl;
+      newCNX[TETRA4].push_back(ng1);
+      newCNX[TETRA4].push_back(VN[2]);
+      newCNX[TETRA4].push_back(VN[1]);
+      newCNX[TETRA4].push_back(ng0);
+      cptNouvellesMailles[TETRA4]++;
+
+      newCNX[PYRAM5].push_back(ng2);
+      newCNX[PYRAM5].push_back(ng3);
+      newCNX[PYRAM5].push_back(VN[2]);
+      newCNX[PYRAM5].push_back(VN[1]);
+      newCNX[PYRAM5].push_back(ng1);
+      cptNouvellesMailles[PYRAM5]++;
+
+      if (POSN[ng0 - 1] == 1)
+        {
+          GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMmoins[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1);
+        }
+      else
+        {
+          GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMplus[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1);
+        }
+    }
+  else if (VN[1] != -1 && VN[3] != -1)
+    {
+      // Le sommet du nouveau T4 est le noeud 2 du T4 d'origine
+
+      // cout << "cas 2.13" << endl;
+      newCNX[TETRA4].push_back(VN[1]);
+      newCNX[TETRA4].push_back(ng3);
+      newCNX[TETRA4].push_back(VN[3]);
+      newCNX[TETRA4].push_back(ng2);
+      cptNouvellesMailles[TETRA4]++;
+
+      newCNX[PYRAM5].push_back(ng0);
+      newCNX[PYRAM5].push_back(ng1);
+      newCNX[PYRAM5].push_back(VN[3]);
+      newCNX[PYRAM5].push_back(VN[1]);
+      newCNX[PYRAM5].push_back(ng3);
+      cptNouvellesMailles[PYRAM5]++;
+
+      if (POSN[ng2 - 1] == 1)
+        {
+          GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMmoins[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1);
+        }
+      else
+        {
+          GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMplus[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1);
+        }
+    }
+
+  else if (VN[1] != -1 && VN[4] != -1)
+    ERREUR("Case 2/14 excluded");
+
+  else if (VN[1] != -1 && VN[5] != -1)
+    {
+      // Le sommet du nouveau T4 est le noeud 2 du T4 d'origine
+
+      // cout << "cas 2.15" << endl;
+      newCNX[TETRA4].push_back(ng1);
+      newCNX[TETRA4].push_back(ng2);
+      newCNX[TETRA4].push_back(VN[1]);
+      newCNX[TETRA4].push_back(VN[5]);
+      cptNouvellesMailles[TETRA4]++;
+
+      newCNX[PYRAM5].push_back(VN[1]);
+      newCNX[PYRAM5].push_back(VN[5]);
+      newCNX[PYRAM5].push_back(ng3);
+      newCNX[PYRAM5].push_back(ng0);
+      newCNX[PYRAM5].push_back(ng1);
+      cptNouvellesMailles[PYRAM5]++;
+
+      if (POSN[ng2 - 1] == 1)
+        {
+          GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMmoins[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1);
+        }
+      else
+        {
+          GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMplus[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1);
+        }
+    }
+
+  else if (VN[2] != -1 && VN[3] != -1)
+    ERREUR("Case 2/23 excluded");
+
+  else if (VN[2] != -1 && VN[4] != -1)
+    {
+      // Le sommet du nouveau T4 est le noeud 3 du T4 d'origine
+
+      // cout << "cas 2.24" << endl;
+      newCNX[TETRA4].push_back(VN[2]);
+      newCNX[TETRA4].push_back(VN[4]);
+      newCNX[TETRA4].push_back(ng2);
+      newCNX[TETRA4].push_back(ng3);
+      cptNouvellesMailles[TETRA4]++;
+
+      newCNX[PYRAM5].push_back(ng0);
+      newCNX[PYRAM5].push_back(VN[2]);
+      newCNX[PYRAM5].push_back(VN[4]);
+      newCNX[PYRAM5].push_back(ng1);
+      newCNX[PYRAM5].push_back(ng2);
+      cptNouvellesMailles[PYRAM5]++;
+
+      if (POSN[ng3 - 1] == 1)
+        {
+          GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMmoins[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1);
+        }
+      else
+        {
+          GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMplus[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1);
+        }
+    }
+
+  else if (VN[2] != -1 && VN[5] != -1)
+    {
+      // Le sommet du nouveau T4 est le noeud 3 du T4 d'origine
+
+      // cout << "cas 2.25" << endl;
+      newCNX[TETRA4].push_back(ng1);
+      newCNX[TETRA4].push_back(VN[5]);
+      newCNX[TETRA4].push_back(VN[2]);
+      newCNX[TETRA4].push_back(ng3);
+      cptNouvellesMailles[TETRA4]++;
+
+      newCNX[PYRAM5].push_back(ng0);
+      newCNX[PYRAM5].push_back(ng2);
+      newCNX[PYRAM5].push_back(VN[5]);
+      newCNX[PYRAM5].push_back(VN[2]);
+      newCNX[PYRAM5].push_back(ng1);
+      cptNouvellesMailles[PYRAM5]++;
+
+      if (POSN[ng3 - 1] == 1)
+        {
+          GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMmoins[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1);
+        }
+      else
+        {
+          GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMplus[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1);
+        }
+    }
+
+  else if (VN[3] != -1 && VN[4] != -1)
+    {
+      // Le sommet du nouveau T4 est le noeud 1 du T4 d'origine
+
+      // cout << "cas 2.34" << endl;
+      newCNX[TETRA4].push_back(ng0);
+      newCNX[TETRA4].push_back(VN[3]);
+      newCNX[TETRA4].push_back(VN[4]);
+      newCNX[TETRA4].push_back(ng1);
+      cptNouvellesMailles[TETRA4]++;
+
+      newCNX[PYRAM5].push_back(VN[3]);
+      newCNX[PYRAM5].push_back(VN[4]);
+      newCNX[PYRAM5].push_back(ng3);
+      newCNX[PYRAM5].push_back(ng2);
+      newCNX[PYRAM5].push_back(ng0);
+      cptNouvellesMailles[PYRAM5]++;
+
+      if (POSN[ng1 - 1] == 1)
+        {
+          GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMmoins[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1);
+        }
+      else
+        {
+          GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMplus[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1);
+        }
+    }
+
+  else if (VN[3] != -1 && VN[5] != -1)
+    {
+      // Le sommet du nouveau T4 est le noeud 2 du T4 d'origine
+
+      // cout << "cas 2.35" << endl;
+      newCNX[TETRA4].push_back(VN[3]);
+      newCNX[TETRA4].push_back(VN[5]);
+      newCNX[TETRA4].push_back(ng2);
+      newCNX[TETRA4].push_back(ng0);
+      cptNouvellesMailles[TETRA4]++;
+
+      newCNX[PYRAM5].push_back(VN[3]);
+      newCNX[PYRAM5].push_back(ng1);
+      newCNX[PYRAM5].push_back(ng3);
+      newCNX[PYRAM5].push_back(VN[5]);
+      newCNX[PYRAM5].push_back(ng0);
+      cptNouvellesMailles[PYRAM5]++;
+
+      if (POSN[ng2 - 1] == 1)
+        {
+          GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMmoins[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1);
+        }
+      else
+        {
+          GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMplus[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1);
+        }
+    }
+
+  else if (VN[4] != -1 && VN[5] != -1)
+    {
+      // Le sommet du nouveau T4 est le noeud 3 du T4 d'origine
+
+      // cout << "cas 2.35" << endl;
+      newCNX[TETRA4].push_back(ng0);
+      newCNX[TETRA4].push_back(VN[4]);
+      newCNX[TETRA4].push_back(VN[5]);
+      newCNX[TETRA4].push_back(ng3);
+      cptNouvellesMailles[TETRA4]++;
+
+      newCNX[PYRAM5].push_back(ng1);
+      newCNX[PYRAM5].push_back(VN[4]);
+      newCNX[PYRAM5].push_back(VN[5]);
+      newCNX[PYRAM5].push_back(ng2);
+      newCNX[PYRAM5].push_back(ng0);
+      cptNouvellesMailles[PYRAM5]++;
+
+      if (POSN[ng3 - 1] == 1)
+        {
+          GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMmoins[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1);
+        }
+      else
+        {
+          GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMplus[PYRAM5].push_back(MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1);
+        }
+    }
+
+  else
+    ERREUR(" Intersections configuration not taken into account (case cptPI=2) ");
+
+  // int ngT4 = MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1;
+  // int ngP5 = MAILLAGE1->EFFECTIFS_TYPES[PYRAM5] + cptNouvellesMailles[PYRAM5] - 1;
+  // cout << "La maille TETRA4 " << it4 << " produit les mailles TETRA4-" << ngT4 << " et PYRAM5-" << ngP5 << endl;
+
+}
+
+/*! Trois points d'intersection
+ *  ATTENTION: pour les PENTA6 on adopte la convention d'orientation SALOME :
+ *
+ *  N1 N2 N3 N4 N5 N6
+ *
+ *  où N1 N2 N3 sont les sommets du haut et N4 N5 N6 les sommets du bas
+ *  (selon l'orientation donnée par le sens des triangles)
+ */
+void MESHCUT::cas3(int VN[6], int it4)
+{
+  cutTetras.push_back(it4);
+  // cout << "Cas 3 - it4="<<it4<<", VN = " << VN[0] << " " << VN[1] << " " << VN[2] << " " << VN[3] << " " << VN[4] << " " << VN[5] << " " << endl;
+
+  // Numéros des noeuds du TETRA4
+  int ng0 = MAILLAGE1->CNX[TETRA4][4 * it4 + 0];
+  int ng1 = MAILLAGE1->CNX[TETRA4][4 * it4 + 1];
+  int ng2 = MAILLAGE1->CNX[TETRA4][4 * it4 + 2];
+  int ng3 = MAILLAGE1->CNX[TETRA4][4 * it4 + 3];
+
+  if (VN[0] != -1 && VN[1] != -1 && VN[2] != -1)
+    {
+
+      // Le sommet du nouveau T4 est le noeud 0 du T4 d'origine
+
+      newCNX[TETRA4].push_back(ng0);
+      newCNX[TETRA4].push_back(VN[0]);
+      newCNX[TETRA4].push_back(VN[1]);
+      newCNX[TETRA4].push_back(VN[2]);
+      cptNouvellesMailles[TETRA4]++;
+
+      newCNX[PENTA6].push_back(ng1);
+      newCNX[PENTA6].push_back(ng3);
+      newCNX[PENTA6].push_back(ng2);
+      newCNX[PENTA6].push_back(VN[0]);
+      newCNX[PENTA6].push_back(VN[2]);
+      newCNX[PENTA6].push_back(VN[1]);
+      cptNouvellesMailles[PENTA6]++;
+
+      if (POSN[ng0 - 1] == 1)
+        {
+          GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMmoins[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + cptNouvellesMailles[PENTA6] - 1);
+        }
+      else
+        {
+          GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMplus[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + cptNouvellesMailles[PENTA6] - 1);
+        }
+    }
+
+  else if (VN[0] != -1 && VN[3] != -1 && VN[4] != -1)
+    {
+      // Le sommet du nouveau T4 est le noeud 1 du T4 d'origine
+
+      //cout << "cas 3.2 (noeud sommet 1)" << endl;
+      newCNX[TETRA4].push_back(VN[0]);
+      newCNX[TETRA4].push_back(ng1);
+      newCNX[TETRA4].push_back(VN[3]);
+      newCNX[TETRA4].push_back(VN[4]);
+      cptNouvellesMailles[TETRA4]++;
+
+      newCNX[PENTA6].push_back(ng0);
+      newCNX[PENTA6].push_back(ng2);
+      newCNX[PENTA6].push_back(ng3);
+      newCNX[PENTA6].push_back(VN[0]);
+      newCNX[PENTA6].push_back(VN[3]);
+      newCNX[PENTA6].push_back(VN[4]);
+      cptNouvellesMailles[PENTA6]++;
+
+      if (POSN[ng1 - 1] == 1)
+        {
+          GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMmoins[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + cptNouvellesMailles[PENTA6] - 1);
+        }
+      else
+        {
+          GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMplus[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + cptNouvellesMailles[PENTA6] - 1);
+        }
+    }
+  else if (VN[1] != -1 && VN[3] != -1 && VN[5] != -1)
+    {
+      // Le sommet du nouveau T4 est le noeud 2 du T4 d'origine
+
+      //cout << "cas 3.3 (noeud sommet 2)" << endl;
+
+      newCNX[TETRA4].push_back(VN[1]);
+      newCNX[TETRA4].push_back(VN[3]);
+      newCNX[TETRA4].push_back(ng2);
+      newCNX[TETRA4].push_back(VN[5]);
+      cptNouvellesMailles[TETRA4]++;
+
+      newCNX[PENTA6].push_back(ng0);
+      newCNX[PENTA6].push_back(ng3);
+      newCNX[PENTA6].push_back(ng1);
+      newCNX[PENTA6].push_back(VN[1]);
+      newCNX[PENTA6].push_back(VN[5]);
+      newCNX[PENTA6].push_back(VN[3]);
+      cptNouvellesMailles[PENTA6]++;
+
+      if (POSN[ng2 - 1] == 1)
+        {
+          GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMmoins[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + cptNouvellesMailles[PENTA6] - 1);
+        }
+      else
+        {
+          GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMplus[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + cptNouvellesMailles[PENTA6] - 1);
+        }
+    }
+  else if (VN[2] != -1 && VN[4] != -1 && VN[5] != -1)
+    {
+      // Le sommet du nouveau T4 est le noeud 3 du T4 d'origine
+
+      newCNX[TETRA4].push_back(VN[2]);
+      newCNX[TETRA4].push_back(VN[4]);
+      newCNX[TETRA4].push_back(VN[5]);
+      newCNX[TETRA4].push_back(ng3);
+      cptNouvellesMailles[TETRA4]++;
+
+      newCNX[PENTA6].push_back(ng0);
+      newCNX[PENTA6].push_back(ng1);
+      newCNX[PENTA6].push_back(ng2);
+      newCNX[PENTA6].push_back(VN[2]);
+      newCNX[PENTA6].push_back(VN[4]);
+      newCNX[PENTA6].push_back(VN[5]);
+      cptNouvellesMailles[PENTA6]++;
+
+      if (POSN[ng3 - 1] == 1)
+        {
+          GMplus[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMmoins[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + cptNouvellesMailles[PENTA6] - 1);
+        }
+      else
+        {
+          GMmoins[TETRA4].push_back(MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1);
+          GMplus[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + cptNouvellesMailles[PENTA6] - 1);
+        }
+    }
+  else
+    {
+      //      cout << "Cas 3 - it4=" << it4 << ", VN = " << VN[0] << " " << VN[1] << " " << VN[2] << " " << VN[3] << " "
+      //          << VN[4] << " " << VN[5] << " " << endl;
+      //
+      //      int n0 = *(MAILLAGE1->CNX[TETRA4] + it4 * 4 + 0);
+      //      float x0 = MAILLAGE1->XX[n0 - 1];
+      //      float y0 = MAILLAGE1->YY[n0 - 1];
+      //      float z0 = MAILLAGE1->ZZ[n0 - 1];
+      //
+      //      int n1 = *(MAILLAGE1->CNX[TETRA4] + it4 * 4 + 1);
+      //      float x1 = MAILLAGE1->XX[n1 - 1];
+      //      float y1 = MAILLAGE1->YY[n1 - 1];
+      //      float z1 = MAILLAGE1->ZZ[n1 - 1];
+      //
+      //      int n2 = *(MAILLAGE1->CNX[TETRA4] + it4 * 4 + 2);
+      //      float x2 = MAILLAGE1->XX[n2 - 1];
+      //      float y2 = MAILLAGE1->YY[n2 - 1];
+      //      float z2 = MAILLAGE1->ZZ[n2 - 1];
+      //
+      //      int n3 = *(MAILLAGE1->CNX[TETRA4] + it4 * 4 + 3);
+      //      float x3 = MAILLAGE1->XX[n3 - 1];
+      //      float y3 = MAILLAGE1->YY[n3 - 1];
+      //      float z3 = MAILLAGE1->ZZ[n3 - 1];
+      //
+      //      cout << x0 << " " << y0 << " " << z0 << " " << endl;
+      //      cout << x1 << " " << y1 << " " << z1 << " " << endl;
+      //      cout << x2 << " " << y2 << " " << z2 << " " << endl;
+      //      cout << x3 << " " << y3 << " " << z3 << " " << endl;
+
+      ERREUR(" Intersections configuration not taken into account (case cptPI=3) ");
+    }
+
+  // int ngT4 = MAILLAGE1->EFFECTIFS_TYPES[TETRA4] + cptNouvellesMailles[TETRA4] - 1;
+  // int ngP6 = MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + cptNouvellesMailles[PENTA6] - 1;
+  // cout << "La maille TETRA4 " << it4 << " produit les mailles TETRA4-" << ngT4 << " et PENTA6-" << ngP6 << endl;
+}
+
+/*! Quatre points d'intersection
+ *
+ *  ATTENTION: pour les PENTA6 on adopte la convention d'orientation SALOME
+ *
+ *  N1 N2 N3 N4 N5 N6
+ *
+ *  où N1 N2 N3 sont les sommets du haut et N4 N5 N6 les sommets du bas
+ *  (selon l'orientation donnée par le sens des triangles)
+ */
+void MESHCUT::cas4(int VN[6], int it4)
+{
+  cutTetras.push_back(it4);
+  //  cout << "Cas 4 - it4=" << it4 << ", VN = " << VN[0] << " " << VN[1] << " " << VN[2] << " " << VN[3] << " " << VN[4]
+  //      << " " << VN[5] << " " << endl;
+
+  // Numéros des noeuds du TETRA4
+  int ng0 = MAILLAGE1->CNX[TETRA4][4 * it4 + 0];
+  int ng1 = MAILLAGE1->CNX[TETRA4][4 * it4 + 1];
+  int ng2 = MAILLAGE1->CNX[TETRA4][4 * it4 + 2];
+  int ng3 = MAILLAGE1->CNX[TETRA4][4 * it4 + 3];
+
+  int i1, i2; // Numéros locaux dans le type des mailles créées
+
+  if (VN[0] == -1 && VN[5] == -1)
+    {
+      // Les deux arêtes opposées sont [0,1] et [2,3]
+
+      newCNX[PENTA6].push_back(ng0);
+      newCNX[PENTA6].push_back(VN[1]);
+      newCNX[PENTA6].push_back(VN[2]);
+      newCNX[PENTA6].push_back(ng1);
+      newCNX[PENTA6].push_back(VN[3]);
+      newCNX[PENTA6].push_back(VN[4]);
+      cptNouvellesMailles[PENTA6]++;
+      i1 = cptNouvellesMailles[PENTA6] - 1;
+
+      newCNX[PENTA6].push_back(ng3);
+      newCNX[PENTA6].push_back(VN[4]);
+      newCNX[PENTA6].push_back(VN[2]);
+      newCNX[PENTA6].push_back(ng2);
+      newCNX[PENTA6].push_back(VN[3]);
+      newCNX[PENTA6].push_back(VN[1]);
+      cptNouvellesMailles[PENTA6]++;
+      i2 = cptNouvellesMailles[PENTA6] - 1;
+
+      if (POSN[ng0 - 1] == 1)
+        {
+          GMplus[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + i1);
+          GMmoins[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + i2);
+        }
+      else
+        {
+          GMplus[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + i2);
+          GMmoins[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + i1);
+        }
+
+    } // if ( VN[0]==-1 && VN[5]==-1 )
+
+  else if (VN[1] == -1 && VN[4] == -1)
+    {
+      // Les deux arêtes opposées sont [0,2] et [1,3]
+
+      newCNX[PENTA6].push_back(ng2);
+      newCNX[PENTA6].push_back(VN[3]);
+      newCNX[PENTA6].push_back(VN[5]);
+      newCNX[PENTA6].push_back(ng0);
+      newCNX[PENTA6].push_back(VN[0]);
+      newCNX[PENTA6].push_back(VN[2]);
+      cptNouvellesMailles[PENTA6]++;
+      i1 = cptNouvellesMailles[PENTA6] - 1;
+
+      newCNX[PENTA6].push_back(ng1);
+      newCNX[PENTA6].push_back(VN[3]);
+      newCNX[PENTA6].push_back(VN[0]);
+      newCNX[PENTA6].push_back(ng3);
+      newCNX[PENTA6].push_back(VN[5]);
+      newCNX[PENTA6].push_back(VN[2]);
+      cptNouvellesMailles[PENTA6]++;
+      i2 = cptNouvellesMailles[PENTA6] - 1;
+
+      if (POSN[ng0 - 1] == 1)
+        {
+          GMplus[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + i1);
+          GMmoins[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + i2);
+        }
+      else
+        {
+          GMplus[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + i2);
+          GMmoins[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + i1);
+        }
+    }
+
+  else if (VN[2] == -1 && VN[3] == -1)
+    {
+      // Les deux arêtes opposées sont [0,3] et [1,2]
+
+      newCNX[PENTA6].push_back(ng0);
+      newCNX[PENTA6].push_back(VN[0]);
+      newCNX[PENTA6].push_back(VN[1]);
+      newCNX[PENTA6].push_back(ng3);
+      newCNX[PENTA6].push_back(VN[4]);
+      newCNX[PENTA6].push_back(VN[5]);
+      cptNouvellesMailles[PENTA6]++;
+      i1 = cptNouvellesMailles[PENTA6] - 1;
+
+      newCNX[PENTA6].push_back(ng2);
+      newCNX[PENTA6].push_back(VN[5]);
+      newCNX[PENTA6].push_back(VN[1]);
+      newCNX[PENTA6].push_back(ng1);
+      newCNX[PENTA6].push_back(VN[4]);
+      newCNX[PENTA6].push_back(VN[0]);
+      cptNouvellesMailles[PENTA6]++;
+      i2 = cptNouvellesMailles[PENTA6] - 1;
+
+      if (POSN[ng0 - 1] == 1)
+        {
+          GMplus[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + i1);
+          GMmoins[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + i2);
+        }
+      else
+        {
+          GMplus[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + i2);
+          GMmoins[PENTA6].push_back(MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + i1);
+        }
+    }
+  else
+    ERREUR(" Intersection configuration not taken into account (case cptPI=4) ");
+
+  // int nl1 = MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + i1;
+  // int nl2 = MAILLAGE1->EFFECTIFS_TYPES[PENTA6] + i2;
+  // cout << "La maille TETRA4 " << it4 << " produit les mailles PENTA6-" << nl1 << " et PENTA6-" << nl2 << endl;
+}
diff --git a/src/Tools/MeshCut/MeshCut_Cas.hxx b/src/Tools/MeshCut/MeshCut_Cas.hxx
new file mode 100644 (file)
index 0000000..0840280
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright (C) 2006-2012  EDF R&D
+//
+// 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.com
+//
+
+#ifndef __MESHCUT_CAS_HXX__
+#define __MESHCUT_CAS_HXX__
+
+namespace MESHCUT
+  {
+    void cas1(int VN[6], int it4);
+    void cas2(int VN[6], int it4);
+    void cas3(int VN[6], int it4);
+    void cas4(int VN[6], int it4);
+  }
+
+#endif
diff --git a/src/Tools/MeshCut/MeshCut_Cube.cxx b/src/Tools/MeshCut/MeshCut_Cube.cxx
new file mode 100644 (file)
index 0000000..62ef846
--- /dev/null
@@ -0,0 +1,58 @@
+// Copyright (C) 2006-2012  EDF R&D
+//
+// 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.com
+//
+
+#include "MeshCut_Cube.hxx"
+
+#include <iostream>
+
+using namespace MESHCUT;
+using namespace std;
+
+Cube::Cube(float _x0, float _x1, float _y0, float _y1, float _z0, float _z1)
+{
+  x0 = _x0;
+  x1 = _x1;
+  y0 = _y0;
+  y1 = _y1;
+  z0 = _z0;
+  z1 = _z1;
+}
+
+bool Cube::disjoint(Cube* c2)
+{
+  return (x0 > c2->x1 || x1 < c2->x0 || y0 > c2->y1 || y1 < c2->y0 || z0 > c2->z1 || z1 < c2->z0);
+}
+
+bool Cube::contientNoeud(int ngnoeud, Maillage *MAILLAGE)
+{
+  float x = *(MAILLAGE->XX + ngnoeud - 1);
+  float y = *(MAILLAGE->YY + ngnoeud - 1);
+  float z = *(MAILLAGE->ZZ + ngnoeud - 1);
+  return (x >= x0 && x <= x1 && y >= y0 && y <= y1 && z >= z0 && z <= z1);
+}
+
+void Cube::affichage()
+{
+  cout << "x0=" << x0 << " ";
+  cout << "x1=" << x1 << " ";
+  cout << "y0=" << y0 << " ";
+  cout << "y1=" << y1 << " ";
+  cout << "z0=" << z0 << " ";
+  cout << "z1=" << z1 << " ";
+}
diff --git a/src/Tools/MeshCut/MeshCut_Cube.hxx b/src/Tools/MeshCut/MeshCut_Cube.hxx
new file mode 100644 (file)
index 0000000..03068d9
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright (C) 2006-2012  EDF R&D
+//
+// 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.com
+//
+
+#ifndef __MESHCUT_CUBE_HXX__
+#define __MESHCUT_CUBE_HXX__
+
+#include "MeshCut_Maillage.hxx"
+
+namespace MESHCUT
+  {
+    class Cube
+    {
+    public:
+      float x0, x1, y0, y1, z0, z1;
+    public:
+      Cube(float _x0, float _x1, float _y0, float _y1, float _z0, float _z1);
+      bool disjoint(Cube* c2);
+      bool contientNoeud(int ngnoeud, Maillage *MAILLAGE);
+      void affichage();
+    };
+  }
+
+#endif
diff --git a/src/Tools/MeshCut/MeshCut_DC.cxx b/src/Tools/MeshCut/MeshCut_DC.cxx
new file mode 100644 (file)
index 0000000..36bcae4
--- /dev/null
@@ -0,0 +1,1124 @@
+// Copyright (C) 2006-2012  EDF R&D
+//
+// 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.com
+//
+
+// Classes et fonctions XMeshLab
+
+#include "MeshCut_Utils.hxx"
+#include "MeshCut_Maillage.hxx"
+
+#include "MeshCut_Carre.hxx"
+#include "MeshCut_Cube.hxx"
+
+#include "MeshCut_Fonctions.hxx"
+#include "MeshCut_Cas.hxx"
+
+#include "MeshCut_Globals.hxx"
+
+#include <iostream>
+#include <cmath>
+#include <cstdlib>
+#include <cstring>
+
+using namespace MESHCUT;
+using namespace std;
+
+// ==================================  DECLARATION DES VARIABLES GLOBALES  ==================================================
+
+std::map<std::string, int> MESHCUT::intersections;
+
+int MESHCUT::indexNouvellesMailles, MESHCUT::indexNouveauxNoeuds, MESHCUT::offsetMailles;
+std::string MESHCUT::str_id_GMplus, MESHCUT::str_id_GMmoins;
+Maillage *MESHCUT::MAILLAGE1, *MESHCUT::MAILLAGE2;
+
+std::vector<float> MESHCUT::newXX, MESHCUT::newYY, MESHCUT::newZZ;
+std::map<TYPE_MAILLE, std::vector<int> > MESHCUT::newCNX;
+std::map<TYPE_MAILLE, int> MESHCUT::cptNouvellesMailles;
+std::map<TYPE_MAILLE, std::vector<int> > MESHCUT::GMplus, MESHCUT::GMmoins;
+std::vector<int> MESHCUT::cutTetras;
+
+float *MESHCUT::DNP;
+int *MESHCUT::POSN;
+
+std::string MESHCUT::str_id_maillagenew;
+
+float MESHCUT::normale[3], MESHCUT::pointPlan[3];
+float MESHCUT::d;
+float MESHCUT::epsilon;
+
+bool MESHCUT::debug;
+int MESHCUT::Naretes;
+
+// ==================================   PROGRAMME PRINCIPAL  ==================================================
+
+int main(int argc, char *argv[])
+{
+
+  debug = false;
+  string ficMEDin;
+  string ficMEDout;
+  float xNormal;
+  float yNormal;
+  float zNormal;
+  float xm;
+  float ym;
+  float zm;
+  float tolerance;
+  try
+    {
+      if (argc != 13)
+        throw std::exception();
+      char *ficMEDin0 = argv[1];
+      ficMEDin = (string) ficMEDin0;
+      char *ficMEDout0 = argv[2];
+      ficMEDout = (string) ficMEDout0;
+      char *id_maillagenew = argv[3];
+      str_id_maillagenew = (string) id_maillagenew;
+
+      // Groupes créés
+      char *id_GMplus = argv[4];
+      str_id_GMplus = (string) id_GMplus;
+      char *id_GMmoins = argv[5];
+      str_id_GMmoins = (string) id_GMmoins;
+
+      // Vecteur normal au plan de coupe
+      char *charxn = argv[6];
+      xNormal = char2float(charxn);
+      char *charyn = argv[7];
+      yNormal = char2float(charyn);
+      char *charzn = argv[8];
+      zNormal = char2float(charzn);
+
+      // Point du plan de coupe
+      char *charxm = argv[9];
+      xm = char2float(charxm);
+      char *charym = argv[10];
+      ym = char2float(charym);
+      char *charzm = argv[11];
+      zm = char2float(charzm);
+
+      // Tolérance :  epsilon = tolérance * longueur arête moyenne - où epsilon est la tolérance absolue (distance)
+      char *chtolerance = argv[12];
+      tolerance = char2float(chtolerance);
+    }
+  catch (...)
+    {
+      cout << endl;
+      cout << "                 Cut a tetrahedron mesh by a plane" << endl;
+      cout << "                 ---------------------------------" << endl;
+      cout << "Syntax:" << endl << endl;
+      cout << argv[0] << " input.med output.med resuMeshName aboveGroup belowGroup nx ny nz px py pz T " << endl;
+      cout << endl << "where:" << endl;
+      cout << "  input.med    = name of the original mesh file in med format" << endl;
+      cout << "  output.med   = name of the result mesh file in med format" << endl;
+      cout << "  resuMeshName = name of the result mesh" << endl;
+      cout << "  aboveGroup   = name of the group of volumes above the cut plane" << endl;
+      cout << "  belowGroups  = name of the group of volumes below the cut plane" << endl;
+      cout << "  nx ny nz     = vector normal to the cut plane" << endl;
+      cout << "  px py pz     = a point of the cut plane" << endl;
+      cout << "  T            = 0 < T < 1 : vertices of a tetrahedron are considered as belonging" << endl;
+      cout << "                 the cut plane if their distance to the plane is inferior to L*T" << endl;
+      cout << "                 where L is the mean edge size of the tetrahedron" << endl;
+      ERREUR("--> check arguments!");
+    }
+
+  cout << "Cut by a plane :" << endl;
+  cout << "  source mesh: " << ficMEDin << endl;
+  cout << "  result mesh:  " << ficMEDout << endl;
+  cout << "  mesh name:  " << str_id_maillagenew << endl;
+  cout << "  group above plane:  " << str_id_GMplus << endl;
+  cout << "  group below plane: " << str_id_GMmoins << endl;
+  cout << "  vector normal to the cut plane: xn=" << xNormal << " yn=" << yNormal << " zn=" << zNormal << endl;
+  cout << "  point in the cut plane: xm=" << xm << " ym=" << ym << " zm=" << zm << endl;
+  cout << "  tolerance: " << tolerance << endl;
+  cout << endl;
+
+  if (tolerance <= 0.0)
+    ERREUR("Tolerance must not be negative or null");
+
+  // Il faut normer la normale
+  float normeNormal = sqrt(xNormal * xNormal + yNormal * yNormal + zNormal * zNormal);
+  if (normeNormal == 0.0)
+    ERREUR("null normal vector");
+  normale[0] = xNormal / normeNormal;
+  normale[1] = yNormal / normeNormal;
+  normale[2] = zNormal / normeNormal;
+
+  pointPlan[0] = xm;
+  pointPlan[1] = ym;
+  pointPlan[2] = zm;
+
+  // Calcul du coefficient d de l'équation du plan  xn x + yn y + zn n + d = 0
+  d = -normale[0] * xm - normale[1] * ym - normale[2] * zm;
+
+  intersections.clear();
+
+  // Initialisation des compteurs de nouvelles mailles
+  for (int itm = (int) POI1; itm <= (int) HEXA20; itm++)
+    {
+      TYPE_MAILLE tm = (TYPE_MAILLE) itm;
+      cptNouvellesMailles[tm] = 0;
+    }
+
+  int V[6];
+  int S[4]; // Signature du T4 courant
+  //int NG[4]; // Num. globaux des sommets
+
+  // Acquisition maillage initial
+  //cout << chrono() << " - Acquisition du maillage initial" << endl;
+  MAILLAGE1 = new Maillage((string) "TEMP");
+  MAILLAGE1->inputMED(ficMEDin);
+  cout << chrono() << " - End of mesh read" << endl;
+  indexNouveauxNoeuds = MAILLAGE1->nombreNoeudsMaillage;
+
+  // Le maillage ne contient aucun TETRA4 : on rend le maillage initial sans modification
+  if (!MAILLAGE1->EFFECTIFS_TYPES[TETRA4])
+    {
+      cout << "WARNING: mesh does not contain tetra4 elements, it will not be modified" << endl;
+      MAILLAGE1->ID = str_id_maillagenew;
+      MAILLAGE1->outputMED(ficMEDout);
+      cout << chrono() << " - Finished!" << endl << endl;
+      exit(0);
+    }
+  // A partir de cet instant le maillage contient forcément des TETRA4
+
+
+  // Chargement des distances noeud-plan DNP
+  DNP = (float*) malloc(sizeof(float) * MAILLAGE1->nombreNoeudsMaillage);
+  for (int k = 0; k < MAILLAGE1->nombreNoeudsMaillage; k++)
+    DNP[k] = distanceNoeudPlan(k + 1);
+  cout << chrono() << " - End of computation of distances between nodes and plane" << endl;
+
+  // Longueur d'arête moyenne des T4 intersectant le plan de coupe
+  float LONGUEURS = 0.0;
+  int cptLONGUEURS = 0;
+  for (int it4 = 0; it4 < MAILLAGE1->EFFECTIFS_TYPES[TETRA4]; it4++)
+    {
+      bool plus = false;
+      bool moins = false;
+      int *offset = MAILLAGE1->CNX[TETRA4] + 4 * it4;
+      for (int is = 0; is < 4; is++)
+        {
+          int ng = *(offset + is);
+          if (DNP[ng - 1] > 0.0)
+            plus = true;
+          else if (DNP[ng - 1] < 0.0)
+            moins = true;
+        }
+      if (plus && moins)
+        {
+          // Ce tetra est Ã  cheval sur le plan de coupe: on calcule ses longueurs d'arêtes
+          LONGUEURS += longueurSegment(*(offset + 0), *(offset + 1));
+          cptLONGUEURS++;
+          LONGUEURS += longueurSegment(*(offset + 0), *(offset + 2));
+          cptLONGUEURS++;
+          LONGUEURS += longueurSegment(*(offset + 0), *(offset + 3));
+          cptLONGUEURS++;
+          LONGUEURS += longueurSegment(*(offset + 1), *(offset + 2));
+          cptLONGUEURS++;
+          LONGUEURS += longueurSegment(*(offset + 1), *(offset + 3));
+          cptLONGUEURS++;
+          LONGUEURS += longueurSegment(*(offset + 2), *(offset + 3));
+          cptLONGUEURS++;
+        }
+    }
+
+  // Aucun TETRA4 intercepté par le plan de coupe : on rend MAILLAGE1
+  if (cptLONGUEURS == 0)
+    {
+      cout
+          << "WARNING: the cut plane does not cut any tetra4 element, initial mesh will not be modified"
+          << endl;
+      MAILLAGE1->ID = str_id_maillagenew;
+      MAILLAGE1->outputMED(ficMEDout);
+      cout << chrono() << " - Finished!" << endl << endl;
+      exit(0);
+    }
+  // A partir de cet instant le maillage contient forcément des TETRA4 intersectant le plan de coupe
+
+
+  float longueurMoyenne = LONGUEURS / cptLONGUEURS;
+  epsilon = tolerance * longueurMoyenne;
+
+  int nT4coupe = cptLONGUEURS / 6;
+  cout << chrono() << " - End of computation of mean length of tetra4 edges near the cut plane" << endl;
+
+  cout << "Number of tetra4 to be cut = " << nT4coupe << endl;
+  cout << "Mean length = " << longueurMoyenne << endl;
+  cout << "Tolerance = " << tolerance << endl;
+  cout << "Epsilon = " << epsilon << endl;
+
+  // Détermination des positions de noeuds par rapport au plan de coupe - POSN
+  POSN = (int*) malloc(sizeof(int) * MAILLAGE1->nombreNoeudsMaillage);
+  for (int k = 0; k < MAILLAGE1->nombreNoeudsMaillage; k++)
+    {
+      if (DNP[k] > epsilon)
+        POSN[k] = 1;
+      else if (DNP[k] < -epsilon)
+        POSN[k] = -1;
+      else
+        POSN[k] = 0;
+    }
+  cout << chrono() << " - End of nodes qualification above or below the cut plane" << endl;
+  cout << "Start of iteration on tetra4" << endl;
+
+  for (int it4 = 0; it4 < MAILLAGE1->EFFECTIFS_TYPES[TETRA4]; it4++)
+    {
+
+      for (int is = 0; is < 4; is++)
+        {
+          int ng = *(MAILLAGE1->CNX[TETRA4] + 4 * it4 + is);
+          //NG[is] = ng;
+          S[is] = *(POSN + ng - 1);
+        }
+
+      // -------------------------------------------------------------------
+
+      if (S[0] == -1 && S[1] == -1 && S[2] == -1 && S[3] == -1)
+        GMmoins[TETRA4].push_back(it4);
+
+      else if (S[0] == -1 && S[1] == -1 && S[2] == -1 && S[3] == 0)
+        GMmoins[TETRA4].push_back(it4);
+
+      else if (S[0] == -1 && S[1] == -1 && S[2] == -1 && S[3] == 1)
+        { // Cas 3 - Arêtes 2 4 5
+          V[0] = -1;
+          V[1] = -1;
+          V[2] = intersectionSegmentPlan(it4, 2);
+          V[3] = -1;
+          V[4] = intersectionSegmentPlan(it4, 4);
+          V[5] = intersectionSegmentPlan(it4, 5);
+          cas3(V, it4);
+        }
+
+      // -------------------------------------------------------------------
+
+      else if (S[0] == -1 && S[1] == -1 && S[2] == 0 && S[3] == -1)
+        GMmoins[TETRA4].push_back(it4);
+
+      else if (S[0] == -1 && S[1] == -1 && S[2] == 0 && S[3] == 0)
+        GMmoins[TETRA4].push_back(it4);
+
+      else if (S[0] == -1 && S[1] == -1 && S[2] == 0 && S[3] == 1)
+        { // Cas 2, arêtes 2 4
+          V[0] = -1;
+          V[1] = -1;
+          V[2] = intersectionSegmentPlan(it4, 2);
+          V[3] = -1;
+          V[4] = intersectionSegmentPlan(it4, 4);
+          V[5] = -1;
+          cas2(V, it4);
+        }
+
+      // -------------------------------------------------------------------
+
+      else if (S[0] == -1 && S[1] == -1 && S[2] == 1 && S[3] == -1)
+        { // Cas 3, arêtes 1 3 5
+          V[0] = -1;
+          V[1] = intersectionSegmentPlan(it4, 1);
+          V[2] = -1;
+          V[3] = intersectionSegmentPlan(it4, 3);
+          V[4] = -1;
+          V[5] = intersectionSegmentPlan(it4, 5);
+          cas3(V, it4);
+        }
+
+      else if (S[0] == -1 && S[1] == -1 && S[2] == 1 && S[3] == 0)
+        { // Cas 2, arêtes 1 3
+          V[0] = -1;
+          V[1] = intersectionSegmentPlan(it4, 1);
+          V[2] = -1;
+          V[3] = intersectionSegmentPlan(it4, 3);
+          V[4] = -1;
+          V[5] = -1;
+          cas2(V, it4);
+        }
+
+      else if (S[0] == -1 && S[1] == -1 && S[2] == 1 && S[3] == 1)
+        { // Cas 4, arêtes 1 2 3 4
+          V[0] = -1;
+          V[1] = intersectionSegmentPlan(it4, 1);
+          V[2] = intersectionSegmentPlan(it4, 2);
+          V[3] = intersectionSegmentPlan(it4, 3);
+          V[4] = intersectionSegmentPlan(it4, 4);
+          V[5] = -1;
+          cas4(V, it4);
+        }
+
+      // -------------------------------------------------------------------
+
+      else if (S[0] == -1 && S[1] == 0 && S[2] == -1 && S[3] == -1)
+        GMmoins[TETRA4].push_back(it4);
+
+      else if (S[0] == -1 && S[1] == 0 && S[2] == -1 && S[3] == 0)
+        GMmoins[TETRA4].push_back(it4);
+
+      else if (S[0] == -1 && S[1] == 0 && S[2] == -1 && S[3] == 1)
+        { // Cas 2, arêtes 2 5
+          V[0] = -1;
+          V[1] = -1;
+          V[2] = intersectionSegmentPlan(it4, 2);
+          V[3] = -1;
+          V[4] = -1;
+          V[5] = intersectionSegmentPlan(it4, 5);
+          cas2(V, it4);
+        }
+
+      // -------------------------------------------------------------------
+
+      else if (S[0] == -1 && S[1] == 0 && S[2] == 0 && S[3] == -1)
+        GMmoins[TETRA4].push_back(it4);
+
+      else if (S[0] == -1 && S[1] == 0 && S[2] == 0 && S[3] == 0)
+        GMmoins[TETRA4].push_back(it4);
+
+      else if (S[0] == -1 && S[1] == 0 && S[2] == 0 && S[3] == 1)
+        { // Cas 1, arête 2
+          V[0] = -1;
+          V[1] = -1;
+          V[2] = intersectionSegmentPlan(it4, 2);
+          V[3] = -1;
+          V[4] = -1;
+          V[5] = -1;
+          cas1(V, it4);
+        }
+
+      // -------------------------------------------------------------------
+
+      else if (S[0] == -1 && S[1] == 0 && S[2] == 1 && S[3] == -1)
+        { // Cas 2, arêtes 1 5
+          V[0] = -1;
+          V[1] = intersectionSegmentPlan(it4, 1);
+          V[2] = -1;
+          V[3] = -1;
+          V[4] = -1;
+          V[5] = intersectionSegmentPlan(it4, 5);
+          cas2(V, it4);
+        }
+
+      else if (S[0] == -1 && S[1] == 0 && S[2] == 1 && S[3] == 0)
+        { // Cas 1, arête 1
+          V[0] = -1;
+          V[1] = intersectionSegmentPlan(it4, 1);
+          V[2] = -1;
+          V[3] = -1;
+          V[4] = -1;
+          V[5] = -1;
+          cas1(V, it4);
+        }
+
+      else if (S[0] == -1 && S[1] == 0 && S[2] == 1 && S[3] == 1)
+        { // Cas 2, arêtes 1 2
+          V[0] = -1;
+          V[1] = intersectionSegmentPlan(it4, 1);
+          V[2] = intersectionSegmentPlan(it4, 2);
+          V[3] = -1;
+          V[4] = -1;
+          V[5] = -1;
+          cas2(V, it4);
+        }
+
+      // -------------------------------------------------------------------
+
+      else if (S[0] == -1 && S[1] == 1 && S[2] == -1 && S[3] == -1)
+        { // Cas 3, arêtes 0 3 4
+          V[0] = intersectionSegmentPlan(it4, 0);
+          V[1] = -1;
+          V[2] = -1;
+          V[3] = intersectionSegmentPlan(it4, 3);
+          V[4] = intersectionSegmentPlan(it4, 4);
+          V[5] = -1;
+          cas3(V, it4);
+        }
+
+      else if (S[0] == -1 && S[1] == 1 && S[2] == -1 && S[3] == 0)
+        { // Cas 2, arêtes 0 3
+          V[0] = intersectionSegmentPlan(it4, 0);
+          V[1] = -1;
+          V[2] = -1;
+          V[3] = intersectionSegmentPlan(it4, 3);
+          V[4] = -1;
+          V[5] = -1;
+          cas2(V, it4);
+        }
+
+      else if (S[0] == -1 && S[1] == 1 && S[2] == -1 && S[3] == 1)
+        { // Cas 4, arêtes 0 2 3 5
+          V[0] = intersectionSegmentPlan(it4, 0);
+          V[1] = -1;
+          V[2] = intersectionSegmentPlan(it4, 2);
+          V[3] = intersectionSegmentPlan(it4, 3);
+          V[4] = -1;
+          V[5] = intersectionSegmentPlan(it4, 5);
+          cas4(V, it4);
+        }
+
+      // -------------------------------------------------------------------
+
+      else if (S[0] == -1 && S[1] == 1 && S[2] == 0 && S[3] == -1)
+        { // Cas 2, arêtes 0 4
+          V[0] = intersectionSegmentPlan(it4, 0);
+          V[1] = -1;
+          V[2] = -1;
+          V[3] = -1;
+          V[4] = intersectionSegmentPlan(it4, 4);
+          V[5] = -1;
+          cas2(V, it4);
+        }
+
+      else if (S[0] == -1 && S[1] == 1 && S[2] == 0 && S[3] == 0)
+        { // Cas 1, arête 0
+          V[0] = intersectionSegmentPlan(it4, 0);
+          V[1] = -1;
+          V[2] = -1;
+          V[3] = -1;
+          V[4] = -1;
+          V[5] = -1;
+          cas1(V, it4);
+        }
+
+      else if (S[0] == -1 && S[1] == 1 && S[2] == 0 && S[3] == 1)
+        { // Cas 2, arêtes 0 2
+          V[0] = intersectionSegmentPlan(it4, 0);
+          V[1] = -1;
+          V[2] = intersectionSegmentPlan(it4, 2);
+          V[3] = -1;
+          V[4] = -1;
+          V[5] = -1;
+          cas2(V, it4);
+        }
+
+      // -------------------------------------------------------------------
+
+      else if (S[0] == -1 && S[1] == 1 && S[2] == 1 && S[3] == -1)
+        { // Cas 4, arêtes 0 1 4 5
+          V[0] = intersectionSegmentPlan(it4, 0);
+          V[1] = intersectionSegmentPlan(it4, 1);
+          V[2] = -1;
+          V[3] = -1;
+          V[4] = intersectionSegmentPlan(it4, 4);
+          V[5] = intersectionSegmentPlan(it4, 5);
+          cas4(V, it4);
+        }
+
+      else if (S[0] == -1 && S[1] == 1 && S[2] == 1 && S[3] == 0)
+        { // Cas 2, arêtes 0 1
+          V[0] = intersectionSegmentPlan(it4, 0);
+          V[1] = intersectionSegmentPlan(it4, 1);
+          V[2] = -1;
+          V[3] = -1;
+          V[4] = -1;
+          V[5] = -1;
+          cas2(V, it4);
+        }
+
+      else if (S[0] == -1 && S[1] == 1 && S[2] == 1 && S[3] == 1)
+        { // Cas 3, arêtes 0 1 2
+          V[0] = intersectionSegmentPlan(it4, 0);
+          V[1] = intersectionSegmentPlan(it4, 1);
+          V[2] = intersectionSegmentPlan(it4, 2);
+          V[3] = -1;
+          V[4] = -1;
+          V[5] = -1;
+          cas3(V, it4);
+        }
+
+      // -------------------------------------------------------------------
+
+      else if (S[0] == 0 && S[1] == -1 && S[2] == -1 && S[3] == -1)
+        GMmoins[TETRA4].push_back(it4);
+
+      else if (S[0] == 0 && S[1] == -1 && S[2] == -1 && S[3] == 0)
+        GMmoins[TETRA4].push_back(it4);
+
+      else if (S[0] == 0 && S[1] == -1 && S[2] == -1 && S[3] == 1)
+        { // Cas 2, arêtes 4 5
+          V[0] = -1;
+          V[1] = -1;
+          V[2] = -1;
+          V[3] = -1;
+          V[4] = intersectionSegmentPlan(it4, 4);
+          V[5] = intersectionSegmentPlan(it4, 5);
+          cas2(V, it4);
+        }
+
+      // -------------------------------------------------------------------
+
+      else if (S[0] == 0 && S[1] == -1 && S[2] == 0 && S[3] == -1)
+        GMmoins[TETRA4].push_back(it4);
+
+      else if (S[0] == 0 && S[1] == -1 && S[2] == 0 && S[3] == 0)
+        GMmoins[TETRA4].push_back(it4);
+
+      else if (S[0] == 0 && S[1] == -1 && S[2] == 0 && S[3] == 1)
+        { // Cas 1, arête 4
+          V[0] = -1;
+          V[1] = -1;
+          V[2] = -1;
+          V[3] = -1;
+          V[4] = intersectionSegmentPlan(it4, 4);
+          V[5] = -1;
+          cas1(V, it4);
+        }
+
+      // -------------------------------------------------------------------
+
+      else if (S[0] == 0 && S[1] == -1 && S[2] == 1 && S[3] == -1)
+        { // Cas 2, arêtes 3 5
+          V[0] = -1;
+          V[1] = -1;
+          V[2] = -1;
+          V[3] = intersectionSegmentPlan(it4, 3);
+          V[4] = -1;
+          V[5] = intersectionSegmentPlan(it4, 5);
+          cas2(V, it4);
+        }
+
+      else if (S[0] == 0 && S[1] == -1 && S[2] == 1 && S[3] == 0)
+        { // Cas 1, arête 3
+          V[0] = -1;
+          V[1] = -1;
+          V[2] = -1;
+          V[3] = intersectionSegmentPlan(it4, 3);
+          V[4] = -1;
+          V[5] = -1;
+          cas1(V, it4);
+        }
+
+      else if (S[0] == 0 && S[1] == -1 && S[2] == 1 && S[3] == 1)
+        { // Cas 2, arêtes 3 4
+          V[0] = -1;
+          V[1] = -1;
+          V[2] = -1;
+          V[3] = intersectionSegmentPlan(it4, 3);
+          V[4] = intersectionSegmentPlan(it4, 4);
+          V[5] = -1;
+          cas2(V, it4);
+        }
+
+      // -------------------------------------------------------------------
+
+      else if (S[0] == 0 && S[1] == 0 && S[2] == -1 && S[3] == -1)
+        GMmoins[TETRA4].push_back(it4);
+
+      else if (S[0] == 0 && S[1] == 0 && S[2] == -1 && S[3] == 0)
+        GMmoins[TETRA4].push_back(it4);
+
+      else if (S[0] == 0 && S[1] == 0 && S[2] == -1 && S[3] == 1)
+        { // Cas 1, arête 5
+          V[0] = -1;
+          V[1] = -1;
+          V[2] = -1;
+          V[3] = -1;
+          V[4] = -1;
+          V[5] = intersectionSegmentPlan(it4, 5);
+          cas1(V, it4);
+        }
+
+      // -------------------------------------------------------------------
+
+      else if (S[0] == 0 && S[1] == 0 && S[2] == 0 && S[3] == -1)
+        GMmoins[TETRA4].push_back(it4);
+
+      else if (S[0] == 0 && S[1] == 0 && S[2] == 0 && S[3] == 0)
+        {
+          cout << "WARNING: TETRA4 number " << it4
+              << " entirely in the tolerance zone near the cut plane" << endl;
+          cout << " --> affected to group " << str_id_GMmoins << endl;
+          GMmoins[TETRA4].push_back(it4);
+        }
+
+      else if (S[0] == 0 && S[1] == 0 && S[2] == 0 && S[3] == 1)
+        GMplus[TETRA4].push_back(it4);
+
+      // -------------------------------------------------------------------
+
+      else if (S[0] == 0 && S[1] == 0 && S[2] == 1 && S[3] == -1)
+        { // Cas 1, arête 5
+          V[0] = -1;
+          V[1] = -1;
+          V[2] = -1;
+          V[3] = -1;
+          V[4] = -1;
+          V[5] = intersectionSegmentPlan(it4, 5);
+          cas1(V, it4);
+        }
+
+      else if (S[0] == 0 && S[1] == 0 && S[2] == 1 && S[3] == 0)
+        GMplus[TETRA4].push_back(it4);
+
+      else if (S[0] == 0 && S[1] == 0 && S[2] == 1 && S[3] == 1)
+        GMplus[TETRA4].push_back(it4);
+
+      // -------------------------------------------------------------------
+
+      else if (S[0] == 0 && S[1] == 1 && S[2] == -1 && S[3] == -1)
+        { // Cas 2, arêtes 3 4
+          V[0] = -1;
+          V[1] = -1;
+          V[2] = -1;
+          V[3] = intersectionSegmentPlan(it4, 3);
+          V[4] = intersectionSegmentPlan(it4, 4);
+          V[5] = -1;
+          cas2(V, it4);
+        }
+
+      else if (S[0] == 0 && S[1] == 1 && S[2] == -1 && S[3] == 0)
+        { // Cas 1, arête 3
+          V[0] = -1;
+          V[1] = -1;
+          V[2] = -1;
+          V[3] = intersectionSegmentPlan(it4, 3);
+          V[4] = -1;
+          V[5] = -1;
+          cas1(V, it4);
+        }
+
+      else if (S[0] == 0 && S[1] == 1 && S[2] == -1 && S[3] == 1)
+        { // Cas 2, arêtes 3 5
+          V[0] = -1;
+          V[1] = -1;
+          V[2] = -1;
+          V[3] = intersectionSegmentPlan(it4, 3);
+          V[4] = -1;
+          V[5] = intersectionSegmentPlan(it4, 5);
+          cas2(V, it4);
+        }
+
+      // -------------------------------------------------------------------
+
+      else if (S[0] == 0 && S[1] == 1 && S[2] == 0 && S[3] == -1)
+        { // Cas 1, arête 4
+          V[0] = -1;
+          V[1] = -1;
+          V[2] = -1;
+          V[3] = -1;
+          V[4] = intersectionSegmentPlan(it4, 4);
+          V[5] = -1;
+          cas1(V, it4);
+        }
+
+      else if (S[0] == 0 && S[1] == 1 && S[2] == 0 && S[3] == 0)
+        GMplus[TETRA4].push_back(it4);
+
+      else if (S[0] == 0 && S[1] == 1 && S[2] == 0 && S[3] == 1)
+        GMplus[TETRA4].push_back(it4);
+
+      // -------------------------------------------------------------------
+
+      else if (S[0] == 0 && S[1] == 1 && S[2] == 1 && S[3] == -1)
+        { // Cas 2, arêtes 4 5
+          V[0] = -1;
+          V[1] = -1;
+          V[2] = -1;
+          V[3] = -1;
+          V[4] = intersectionSegmentPlan(it4, 4);
+          V[5] = intersectionSegmentPlan(it4, 5);
+          cas2(V, it4);
+        }
+
+      else if (S[0] == 0 && S[1] == 1 && S[2] == 1 && S[3] == 0)
+        GMplus[TETRA4].push_back(it4);
+
+      else if (S[0] == 0 && S[1] == 1 && S[2] == 1 && S[3] == 1)
+        GMplus[TETRA4].push_back(it4);
+
+      // -------------------------------------------------------------------
+
+      else if (S[0] == 1 && S[1] == -1 && S[2] == -1 && S[3] == -1)
+        { // Cas 3, arêtes 0 1 2
+          V[0] = intersectionSegmentPlan(it4, 0);
+          V[1] = intersectionSegmentPlan(it4, 1);
+          V[2] = intersectionSegmentPlan(it4, 2);
+          V[3] = -1;
+          V[4] = -1;
+          V[5] = -1;
+          cas3(V, it4);
+        }
+
+      else if (S[0] == 1 && S[1] == -1 && S[2] == -1 && S[3] == 0)
+        { // Cas 2, arêtes 0 1
+          V[0] = intersectionSegmentPlan(it4, 0);
+          V[1] = intersectionSegmentPlan(it4, 1);
+          V[2] = -1;
+          V[3] = -1;
+          V[4] = -1;
+          V[5] = -1;
+          cas2(V, it4);
+        }
+
+      else if (S[0] == 1 && S[1] == -1 && S[2] == -1 && S[3] == 1)
+        { // Cas 4, arêtes 0 1 4 5
+          V[0] = intersectionSegmentPlan(it4, 0);
+          V[1] = intersectionSegmentPlan(it4, 1);
+          V[2] = -1;
+          V[3] = -1;
+          V[4] = intersectionSegmentPlan(it4, 4);
+          V[5] = intersectionSegmentPlan(it4, 5);
+          cas4(V, it4);
+        }
+
+      // -------------------------------------------------------------------
+
+      else if (S[0] == 1 && S[1] == -1 && S[2] == 0 && S[3] == -1)
+        { // Cas 2, arêtes 0 2
+          V[0] = intersectionSegmentPlan(it4, 0);
+          V[1] = -1;
+          V[2] = intersectionSegmentPlan(it4, 2);
+          V[3] = -1;
+          V[4] = -1;
+          V[5] = -1;
+          cas2(V, it4);
+        }
+
+      else if (S[0] == 1 && S[1] == -1 && S[2] == 0 && S[3] == 0)
+        { // Cas 1, arête 0
+          V[0] = intersectionSegmentPlan(it4, 0);
+          V[1] = -1;
+          V[2] = -1;
+          V[3] = -1;
+          V[4] = -1;
+          V[5] = -1;
+          cas1(V, it4);
+        }
+
+      else if (S[0] == 1 && S[1] == -1 && S[2] == 0 && S[3] == 1)
+        { // Cas 2, arêtes 0 4
+          V[0] = intersectionSegmentPlan(it4, 0);
+          V[1] = -1;
+          V[2] = -1;
+          V[3] = -1;
+          V[4] = intersectionSegmentPlan(it4, 4);
+          V[5] = -1;
+          cas2(V, it4);
+        }
+
+      // -------------------------------------------------------------------
+
+      else if (S[0] == 1 && S[1] == -1 && S[2] == 1 && S[3] == -1)
+        { // Cas 4, arêtes 0 2 3 5
+          V[0] = intersectionSegmentPlan(it4, 0);
+          V[1] = -1;
+          V[2] = intersectionSegmentPlan(it4, 2);
+          V[3] = intersectionSegmentPlan(it4, 3);
+          V[4] = -1;
+          V[5] = intersectionSegmentPlan(it4, 5);
+          cas4(V, it4);
+        }
+
+      else if (S[0] == 1 && S[1] == -1 && S[2] == 1 && S[3] == 0)
+        { // Cas 2, arêtes 0 3
+          V[0] = intersectionSegmentPlan(it4, 0);
+          V[1] = -1;
+          V[2] = -1;
+          V[3] = intersectionSegmentPlan(it4, 3);
+          V[4] = -1;
+          V[5] = -1;
+          cas2(V, it4);
+        }
+
+      else if (S[0] == 1 && S[1] == -1 && S[2] == 1 && S[3] == 1)
+        { // Cas 3, arêtes 0 3 4
+          V[0] = intersectionSegmentPlan(it4, 0);
+          V[1] = -1;
+          V[2] = -1;
+          V[3] = intersectionSegmentPlan(it4, 3);
+          V[4] = intersectionSegmentPlan(it4, 4);
+          V[5] = -1;
+          cas3(V, it4);
+        }
+
+      // -------------------------------------------------------------------
+
+      else if (S[0] == 1 && S[1] == 0 && S[2] == -1 && S[3] == -1)
+        { // Cas 2, arêtes 1 2
+          V[0] = -1;
+          V[1] = intersectionSegmentPlan(it4, 1);
+          V[2] = intersectionSegmentPlan(it4, 2);
+          V[3] = -1;
+          V[4] = -1;
+          V[5] = -1;
+          cas2(V, it4);
+        }
+
+      else if (S[0] == 1 && S[1] == 0 && S[2] == -1 && S[3] == 0)
+        { // Cas 1, arête 1
+          V[0] = -1;
+          V[1] = intersectionSegmentPlan(it4, 1);
+          V[2] = -1;
+          V[3] = -1;
+          V[4] = -1;
+          V[5] = -1;
+          cas1(V, it4);
+        }
+
+      else if (S[0] == 1 && S[1] == 0 && S[2] == -1 && S[3] == 1)
+        { // Cas 2, arêtes 1 5
+          V[0] = -1;
+          V[1] = intersectionSegmentPlan(it4, 1);
+          V[2] = -1;
+          V[3] = -1;
+          V[4] = -1;
+          V[5] = intersectionSegmentPlan(it4, 5);
+          cas2(V, it4);
+        }
+
+      // -------------------------------------------------------------------
+
+      else if (S[0] == 1 && S[1] == 0 && S[2] == 0 && S[3] == -1)
+        { // Cas 1, arête 2
+          V[0] = -1;
+          V[1] = -1;
+          V[2] = intersectionSegmentPlan(it4, 2);
+          V[3] = -1;
+          V[4] = -1;
+          V[5] = -1;
+          cas1(V, it4);
+        }
+
+      else if (S[0] == 1 && S[1] == 0 && S[2] == 0 && S[3] == 0)
+        GMplus[TETRA4].push_back(it4);
+
+      else if (S[0] == 1 && S[1] == 0 && S[2] == 0 && S[3] == 1)
+        GMplus[TETRA4].push_back(it4);
+
+      // -------------------------------------------------------------------
+
+      else if (S[0] == 1 && S[1] == 0 && S[2] == 1 && S[3] == -1)
+        { // Cas 2, arêtes 2 5
+          V[0] = -1;
+          V[1] = -1;
+          V[2] = intersectionSegmentPlan(it4, 2);
+          V[3] = -1;
+          V[4] = -1;
+          V[5] = intersectionSegmentPlan(it4, 5);
+          cas2(V, it4);
+        }
+
+      else if (S[0] == 1 && S[1] == 0 && S[2] == 1 && S[3] == 0)
+        GMplus[TETRA4].push_back(it4);
+
+      else if (S[0] == 1 && S[1] == 0 && S[2] == 1 && S[3] == 1)
+        GMplus[TETRA4].push_back(it4);
+
+      // -------------------------------------------------------------------
+
+      else if (S[0] == 1 && S[1] == 1 && S[2] == -1 && S[3] == -1)
+        { // Cas 4, arêtes 1 2 3 4
+          V[0] = -1;
+          V[1] = intersectionSegmentPlan(it4, 1);
+          V[2] = intersectionSegmentPlan(it4, 2);
+          V[3] = intersectionSegmentPlan(it4, 3);
+          V[4] = intersectionSegmentPlan(it4, 4);
+          V[5] = -1;
+          cas4(V, it4);
+        }
+
+      else if (S[0] == 1 && S[1] == 1 && S[2] == -1 && S[3] == 0)
+        { // Cas 2, arêtes 1 3
+          V[0] = -1;
+          V[1] = intersectionSegmentPlan(it4, 1);
+          V[2] = -1;
+          V[3] = intersectionSegmentPlan(it4, 3);
+          V[4] = -1;
+          V[5] = -1;
+          cas2(V, it4);
+        }
+
+      else if (S[0] == 1 && S[1] == 1 && S[2] == -1 && S[3] == 1)
+        { // Cas 3, arêtes 1 3 5
+          V[0] = -1;
+          V[1] = intersectionSegmentPlan(it4, 1);
+          V[2] = -1;
+          V[3] = intersectionSegmentPlan(it4, 3);
+          V[4] = -1;
+          V[5] = intersectionSegmentPlan(it4, 5);
+          cas3(V, it4);
+        }
+
+      // -------------------------------------------------------------------
+
+      else if (S[0] == 1 && S[1] == 1 && S[2] == 0 && S[3] == -1)
+        { // Cas 2, arêtes 2 4
+          V[0] = -1;
+          V[1] = -1;
+          V[2] = intersectionSegmentPlan(it4, 2);
+          V[3] = -1;
+          V[4] = intersectionSegmentPlan(it4, 4);
+          V[5] = -1;
+          cas2(V, it4);
+        }
+
+      else if (S[0] == 1 && S[1] == 1 && S[2] == 0 && S[3] == 0)
+        GMplus[TETRA4].push_back(it4);
+
+      else if (S[0] == 1 && S[1] == 1 && S[2] == 0 && S[3] == 1)
+        GMplus[TETRA4].push_back(it4);
+
+      // -------------------------------------------------------------------
+
+      else if (S[0] == 1 && S[1] == 1 && S[2] == 1 && S[3] == -1)
+        { // Cas 3, arêtes 2 4 5
+          V[0] = -1;
+          V[1] = -1;
+          V[2] = intersectionSegmentPlan(it4, 2);
+          V[3] = -1;
+          V[4] = intersectionSegmentPlan(it4, 4);
+          V[5] = intersectionSegmentPlan(it4, 5);
+          cas3(V, it4);
+        }
+
+      else if (S[0] == 1 && S[1] == 1 && S[2] == 1 && S[3] == 0)
+        GMplus[TETRA4].push_back(it4);
+
+      else if (S[0] == 1 && S[1] == 1 && S[2] == 1 && S[3] == 1)
+        GMplus[TETRA4].push_back(it4);
+
+      else
+        ERREUR("Case not taken into account");
+
+    }
+  cout << chrono() << " - End of iteration on tetra4" << endl;
+
+  // cout << "indexNouveauxNoeuds = " << indexNouveauxNoeuds << endl;
+  newXX.resize(indexNouveauxNoeuds - MAILLAGE1->nombreNoeudsMaillage);
+  newYY.resize(indexNouveauxNoeuds - MAILLAGE1->nombreNoeudsMaillage);
+  newZZ.resize(indexNouveauxNoeuds - MAILLAGE1->nombreNoeudsMaillage);
+
+  if (cptNouvellesMailles[TETRA4])
+    newCNX[TETRA4].resize(4 * cptNouvellesMailles[TETRA4]);
+  if (cptNouvellesMailles[PYRAM5])
+    newCNX[PYRAM5].resize(5 * cptNouvellesMailles[PYRAM5]);
+  if (cptNouvellesMailles[PENTA6])
+    newCNX[PENTA6].resize(6 * cptNouvellesMailles[PENTA6]);
+
+  // =========================================================================================
+  //                          2. Constitution du maillage final
+  // =========================================================================================
+
+  cout << chrono() << " - Constitution of final mesh" << endl;
+
+  MAILLAGE2 = new Maillage(str_id_maillagenew);
+  MAILLAGE2->dimensionMaillage = MAILLAGE1->dimensionMaillage;
+  MAILLAGE2->dimensionEspace = MAILLAGE1->dimensionEspace;
+  strcpy(MAILLAGE2->axisname, MAILLAGE1->axisname);
+  strcpy(MAILLAGE2->unitname, MAILLAGE1->unitname);
+  MAILLAGE2->nombreNoeudsMaillage = indexNouveauxNoeuds;
+  MAILLAGE2->nombreMaillesMaillage = MAILLAGE1->nombreMaillesMaillage + cptNouvellesMailles[TETRA4]
+      + cptNouvellesMailles[PYRAM5] + cptNouvellesMailles[PENTA6];
+
+  // ---------- Coordonnées
+  // Optimisation de la mémoire au détriment du temps
+
+  // Héritage des coordonnées MAILLAGE1
+  MAILLAGE2->XX = (float*) malloc(sizeof(float) * MAILLAGE2->nombreNoeudsMaillage);
+  for (int i = 0; i < MAILLAGE1->nombreNoeudsMaillage; i++)
+    *(MAILLAGE2->XX + i) = *(MAILLAGE1->XX + i);
+  free(MAILLAGE1->XX);
+  MAILLAGE2->YY = (float*) malloc(sizeof(float) * MAILLAGE2->nombreNoeudsMaillage);
+  for (int i = 0; i < MAILLAGE1->nombreNoeudsMaillage; i++)
+    *(MAILLAGE2->YY + i) = *(MAILLAGE1->YY + i);
+  free(MAILLAGE1->YY);
+  MAILLAGE2->ZZ = (float*) malloc(sizeof(float) * MAILLAGE2->nombreNoeudsMaillage);
+  for (int i = 0; i < MAILLAGE1->nombreNoeudsMaillage; i++)
+    *(MAILLAGE2->ZZ + i) = *(MAILLAGE1->ZZ + i);
+  free(MAILLAGE1->ZZ);
+
+  // Coordonnées des noeuds créés
+  for (int i = 0; i < MAILLAGE2->nombreNoeudsMaillage - MAILLAGE1->nombreNoeudsMaillage; i++)
+    {
+      *(MAILLAGE2->XX + MAILLAGE1->nombreNoeudsMaillage + i) = newXX[i];
+      *(MAILLAGE2->YY + MAILLAGE1->nombreNoeudsMaillage + i) = newYY[i];
+      *(MAILLAGE2->ZZ + MAILLAGE1->nombreNoeudsMaillage + i) = newZZ[i];
+      // cout << "Nouveaux noeuds, indice " << i << " : " << newXX[i] << " " << newYY[i] << " " << newZZ[i] << " " << endl;
+    }
+
+  // Legacy mailles maillage 1 (volumes seulement)
+  for (int itm = (int) TETRA4; itm <= (int) HEXA20; itm++)
+    {
+      TYPE_MAILLE tm = (TYPE_MAILLE) itm;
+      if (tm != TETRA4 && tm != PYRAM5 && tm != PENTA6)
+        {
+          // Pour les types autres que TETRA4 PYRAM5 PENTA6 on fait seulement pointer CNX2 vers CNX1
+          if (MAILLAGE1->EFFECTIFS_TYPES[tm])
+            MAILLAGE2->CNX[tm] = MAILLAGE1->CNX[tm];
+          MAILLAGE2->EFFECTIFS_TYPES[tm] = MAILLAGE1->EFFECTIFS_TYPES[tm];
+        }
+      else
+        {
+          // Pour les types TETRA4 PYRAM5 PENTA6 on recopie CNX1 et on ajoute Ã  la suite les newCNX
+          // cout << "Legacy " << tm << " effectif " << MAILLAGE1->EFFECTIFS_TYPES[tm] << endl;
+          int tailleType = Nnoeuds(tm);
+
+          MAILLAGE2->CNX[tm] = (int*) malloc(sizeof(int) * tailleType * (MAILLAGE1->EFFECTIFS_TYPES[tm]
+              + cptNouvellesMailles[tm]));
+          for (int i = 0; i < MAILLAGE1->EFFECTIFS_TYPES[tm]; i++)
+            for (int j = 0; j < tailleType; j++)
+              *(MAILLAGE2->CNX[tm] + tailleType * i + j) = *(MAILLAGE1->CNX[tm] + tailleType * i + j);
+
+          for (int i = 0; i < cptNouvellesMailles[tm]; i++)
+            for (int j = 0; j < tailleType; j++)
+              *(MAILLAGE2->CNX[tm] + tailleType * (MAILLAGE1->EFFECTIFS_TYPES[tm] + i) + j) = newCNX[tm][i * tailleType
+                  + j];
+
+          MAILLAGE2->EFFECTIFS_TYPES[tm] = MAILLAGE1->EFFECTIFS_TYPES[tm] + cptNouvellesMailles[tm];
+        }
+    }
+
+  // Restit CNX
+
+  //   cout << "Maillage 2 - CNX TETRA4 : " << endl;
+  //  ;
+  //  for (int i = 0; i < MAILLAGE2->EFFECTIFS_TYPES[TETRA4]; i++)
+  //    {
+  //      cout << "Maille " << i << " : ";
+  //      for (int j = 0; j < 4; j++)
+  //        cout << MAILLAGE2->CNX[TETRA4][i * 4 + j] << " ";
+  //      cout << endl;
+  //    }
+  //  cout << endl;
+  //  cout << "Maillage 2 - CNX PENTA6 : " << endl;
+  //  ;
+  //  for (int i = 0; i < MAILLAGE2->EFFECTIFS_TYPES[PENTA6]; i++)
+  //    {
+  //      cout << "Maille " << i << " : ";
+  //      for (int j = 0; j < 6; j++)
+  //        cout << MAILLAGE2->CNX[PENTA6][i * 6 + j] << " ";
+  //      cout << endl;
+  //    }
+  //  cout << endl;
+
+  // Groupes de mailles
+  // MAILLAGE2->GM = MAILLAGE1->GM;
+  MAILLAGE2->GN.clear();
+  MAILLAGE2->GM.clear();
+  MAILLAGE2->GM[str_id_GMplus] = GMplus;
+  MAILLAGE2->GM[str_id_GMmoins] = GMmoins;
+
+  // MAILLAGE2->GN = MAILLAGE1->GN;
+
+  MAILLAGE2->eliminationMailles(TETRA4, cutTetras);
+
+  cout << chrono() << " - MED file writing" << endl;
+
+  MAILLAGE2->outputMED(ficMEDout);
+  cout << chrono() << " - Finished!" << endl << endl;
+
+  return 0;
+
+}
diff --git a/src/Tools/MeshCut/MeshCut_Fonctions.cxx b/src/Tools/MeshCut/MeshCut_Fonctions.cxx
new file mode 100644 (file)
index 0000000..28ca3dc
--- /dev/null
@@ -0,0 +1,188 @@
+// Copyright (C) 2006-2012  EDF R&D
+//
+// 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.com
+//
+
+#include "MeshCut_Fonctions.hxx"
+#include "MeshCut_Globals.hxx"
+
+#include <iostream>
+#include <cmath>
+
+using namespace MESHCUT;
+using namespace std;
+
+//=================================================================================================
+//                                    intersectionSegmentPlan
+//=================================================================================================
+
+float MESHCUT::longueurSegment(int ngA, int ngB)
+{
+  float A[3], B[3];
+  A[0] = MAILLAGE1->XX[ngA - 1];
+  A[1] = MAILLAGE1->YY[ngA - 1];
+  A[2] = MAILLAGE1->ZZ[ngA - 1];
+  B[0] = MAILLAGE1->XX[ngB - 1];
+  B[1] = MAILLAGE1->YY[ngB - 1];
+  B[2] = MAILLAGE1->ZZ[ngB - 1];
+  float dx = B[0] - A[0];
+  float dy = B[1] - A[1];
+  float dz = B[2] - A[2];
+  return sqrt(dx * dx + dy * dy + dz * dz);
+}
+
+float MESHCUT::distanceNoeudPlan(float point[3])
+{
+  return normale[0] * point[0] + normale[1] * point[1] + normale[2] * point[2] + d;
+}
+
+float MESHCUT::distanceNoeudPlan(int ng)
+{
+  float A[3];
+  A[0] = MAILLAGE1->XX[ng - 1];
+  A[1] = MAILLAGE1->YY[ng - 1];
+  A[2] = MAILLAGE1->ZZ[ng - 1];
+  return distanceNoeudPlan(A);
+}
+
+int MESHCUT::positionNoeudPlan(int indiceNoeud)
+{
+  if (distanceNoeudPlan(indiceNoeud + 1) > epsilon)
+    return 1;
+  else if (distanceNoeudPlan(indiceNoeud + 1) < -epsilon)
+    return -1;
+  else
+    return 0;
+}
+
+/*!
+ * Equation paramétrique de la droite AB:    OP = OA + lambda AB
+ *
+ * Fonction caractéristique du plan : PI(X,Y,Z) = nx X + ny Y + nz Z + d
+ *
+ * Pour un point P de la droite: PI(OP) = PI(OA) + lambda n.AB     avec n=(nx,ny,nz),
+ * L'intersection AB/plan est donnée par le point P tel que PI(OP)=0.
+ *
+ * Il lui correspond la coordonnée   lambda = - PI(OA) / n.AB.
+ *
+ * Cette intersection est dans le segment si lambda est dans [0,1]
+ */
+int MESHCUT::intersectionSegmentPlan(int it4, int na)
+{
+
+  int ngA, ngB; // Numéros des noeuds extrémités AB
+  float lambda, ps; //, ab; // ab = longueur AB
+  float A[3], B[3];
+
+  // Détermination des ng des extrémités de l'arête passée en argument na
+  int * offset = MAILLAGE1->CNX[TETRA4] + 4 * it4;
+  if (na == 0)
+    {
+      ngA = *(offset + 0);
+      ngB = *(offset + 1);
+    }
+  else if (na == 1)
+    {
+      ngA = *(offset + 0);
+      ngB = *(offset + 2);
+    }
+  else if (na == 2)
+    {
+      ngA = *(offset + 0);
+      ngB = *(offset + 3);
+    }
+  else if (na == 3)
+    {
+      ngA = *(offset + 1);
+      ngB = *(offset + 2);
+    }
+  else if (na == 4)
+    {
+      ngA = *(offset + 1);
+      ngB = *(offset + 3);
+    }
+  else if (na == 5)
+    {
+      ngA = *(offset + 2);
+      ngB = *(offset + 3);
+    }
+  else
+    ERREUR("Edge number superior to 6");
+
+  string cle1 = int2string(ngA) + (string) "_" + int2string(ngB);
+  string cle2 = int2string(ngB) + (string) "_" + int2string(ngA);
+
+  if (intersections[cle1])
+    return intersections[cle1];
+
+  else
+    {
+
+      A[0] = MAILLAGE1->XX[ngA - 1];
+      A[1] = MAILLAGE1->YY[ngA - 1];
+      A[2] = MAILLAGE1->ZZ[ngA - 1];
+      B[0] = MAILLAGE1->XX[ngB - 1];
+      B[1] = MAILLAGE1->YY[ngB - 1];
+      B[2] = MAILLAGE1->ZZ[ngB - 1];
+
+      //      // Longueur AB
+      //      float lx = B[0] - A[0], ly = B[1] - A[1], lz = B[2] - A[2];
+      //      ab = sqrt(lx * lx + ly * ly + lz * lz);
+      //      // La longueur maximale théorique est 2 epsilon
+      //      if (ab < 2 * epsilon * 0.9)
+      //        ERREUR("Arête de longueur inférieure au minimum théorique 2 epsilon");
+
+      // Calcul du produit scalaire AB.n
+      ps = 0.0;
+      for (int k = 0; k < 3; k++)
+        ps += (B[k] - A[k]) * normale[k];
+      // ps = ps / ab ;
+
+      if (debug)
+        {
+          cout << "Routine ISP : arête " << na << " -  ngA=" << ngA << " ngB=" << ngB << endl;
+          cout << "A : " << A[0] << ' ' << A[1] << ' ' << A[2] << endl;
+          cout << "B : " << B[0] << ' ' << B[1] << ' ' << B[2] << endl;
+          cout << "N : " << normale[0] << ' ' << normale[1] << ' ' << normale[2] << endl;
+        }
+
+      if (fabs(ps) == 0.0)
+        ERREUR("Error on null scalar product");
+
+      // PS non nul: l'intersection AB/plan existe
+
+      lambda = -distanceNoeudPlan(A) / ps;
+
+      float inter[3];
+      for (int k = 0; k < 3; k++)
+        inter[k] = A[k] + lambda * (B[k] - A[k]);
+      newXX.push_back(inter[0]);
+      newYY.push_back(inter[1]);
+      newZZ.push_back(inter[2]);
+      indexNouveauxNoeuds++;
+      intersections[cle1] = indexNouveauxNoeuds;
+      intersections[cle2] = indexNouveauxNoeuds;
+
+      //      cout << "création noeud " << indexNouveauxNoeuds << " : " << inter[0] << " " << inter[1] << " " << inter[2]
+      //          << endl;
+      if (debug)
+        cout << " sortie nouveau noeud, lambda = " << lambda << " , noeud = " << indexNouveauxNoeuds << endl;
+      return indexNouveauxNoeuds;
+
+    }
+}
+
diff --git a/src/Tools/MeshCut/MeshCut_Fonctions.hxx b/src/Tools/MeshCut/MeshCut_Fonctions.hxx
new file mode 100644 (file)
index 0000000..cee002f
--- /dev/null
@@ -0,0 +1,36 @@
+// Copyright (C) 2006-2012  EDF R&D
+//
+// 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.com
+//
+
+#ifndef __MESHCUT_FONCTION_HXX__
+#define __MESHCUT_FONCTION_HXX__
+
+namespace MESHCUT
+  {
+    float longueurSegment(int ngA, int ngB);
+
+    float distanceNoeudPlan(float point[3]);
+
+    float distanceNoeudPlan(int ng);
+
+    int positionNoeudPlan(int indiceNoeud);
+
+    int intersectionSegmentPlan(int it4, int na);
+  }
+
+#endif
diff --git a/src/Tools/MeshCut/MeshCut_Globals.hxx b/src/Tools/MeshCut/MeshCut_Globals.hxx
new file mode 100644 (file)
index 0000000..fc1f831
--- /dev/null
@@ -0,0 +1,62 @@
+// Copyright (C) 2006-2012  EDF R&D
+//
+// 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.com
+//
+
+#ifndef __MESHCUT_GLOBALS_HXX__
+#define __MESHCUT_GLOBALS_HXX__
+
+#include "MeshCut_Maillage.hxx"
+
+#include <map>
+#include <string>
+#include <vector>
+
+namespace MESHCUT
+  {
+    /*! Table des points d'intersection calculés.
+     *  Si on a calculé une intersection entre le plan et un segment reliant N1 et N2
+     *  de numéros globaux n1 et n2, on stocke dans ce tableau, sous les libellés "n1_n2" et "n2_n1",
+     *  le numéro global du point d'intersection (noeud créé).
+     *  On Ã©vite ainsi de calculer deux fois l'intersection d'une même arête de T4 avec le plan
+     */
+    extern std::map<std::string, int> intersections;
+
+    extern int indexNouvellesMailles, indexNouveauxNoeuds, offsetMailles;
+    extern std::string str_id_GMplus, str_id_GMmoins;
+    extern Maillage *MAILLAGE1, *MAILLAGE2;
+
+    extern std::vector<float> newXX, newYY, newZZ;
+    extern std::map<TYPE_MAILLE, std::vector<int> > newCNX;
+    extern std::map<TYPE_MAILLE, int> cptNouvellesMailles;
+    extern std::map<TYPE_MAILLE, std::vector<int> > GMplus, GMmoins;
+    extern std::vector<int> cutTetras;
+
+    extern float *DNP; //!< Distance Noeud Plan
+    extern int *POSN; //!<  Version -1/0/+1 du précédent, selon epsilon
+
+    extern std::string str_id_maillagenew;
+
+    extern float normale[3], pointPlan[3]; //!<  Définition du plan de coupe
+    extern float d; //!<  coefficient constant de l'équation du plan de coupe
+    extern float epsilon; //!<  distance en dessous de laquelle un point est considéré comme appartenant au plan de coupe
+
+    extern bool debug;
+    extern int Naretes;
+  }
+
+#endif
diff --git a/src/Tools/MeshCut/MeshCut_Maillage.cxx b/src/Tools/MeshCut/MeshCut_Maillage.cxx
new file mode 100644 (file)
index 0000000..0ae4437
--- /dev/null
@@ -0,0 +1,1789 @@
+// Copyright (C) 2006-2012  EDF R&D
+//
+// 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.com
+//
+
+#include "MeshCut_Maillage.hxx"
+#include "MeshCut_Cube.hxx"
+
+#include <iostream>
+#include <sstream>
+#include <list>
+#include <algorithm>
+#include <cmath>
+#include <cstring>
+
+using namespace MESHCUT;
+using namespace std;
+
+Maillage::Maillage(std::string _ID)
+{
+  ID = _ID;
+  nombreNoeudsMaillage = 0;
+  nombreMaillesMaillage = 0;
+  //nPOI1=0; nSEG2=0; nSEG3=0; nTRIA3=0; nTRIA6=0; nQUAD4=0; nQUAD8=0; nTETRA4=0; nTETRA10=0; nPYRAM5=0; nPYRAM13=0; nPENTA6=0; nPENTA15=0; nHEXA8=0; nHEXA20=0;
+  GM.clear();
+  GN.clear();
+  for (int itm = (int) POI1; itm <= (int) HEXA20; itm++)
+    EFFECTIFS_TYPES[(TYPE_MAILLE) itm] = 0;
+}
+
+Maillage::~Maillage()
+{
+}
+
+void Maillage::creationGMtype(TYPE_MAILLE tm, std::string nomGMtype)
+{
+  //cout << "Creation GM type, groupe " << nomGMtype << endl;
+  for (int nl = 0; nl < EFFECTIFS_TYPES[tm]; nl++)
+    GM[nomGMtype][tm].push_back(nl);
+  GM[nomGMtype][tm].resize(EFFECTIFS_TYPES[tm]);
+  sort(GM[nomGMtype][tm].begin(), GM[nomGMtype][tm].end());
+}
+
+void Maillage::afficheMailles(TYPE_MAILLE tm)
+{
+  cout << "Affichage des mailles du type " << TM2string(tm) << " (effectif " << EFFECTIFS_TYPES[tm] << "): " << endl;
+  if (EFFECTIFS_TYPES[tm])
+    {
+      // Boucle sur les connectivités d'un type tm
+      int nnoeuds = Nnoeuds(tm);
+      for (int i = 0; i < EFFECTIFS_TYPES[tm]; i++)
+        {
+          cout << "\tMaille " << i << " :" << endl;
+          //Boucle sur les noeuds de la maille de numéro local i dans le type tm
+          int * offset = CNX[tm] + nnoeuds * i;
+          for (int j = 0; j < nnoeuds; j++)
+            {
+              int ngnoeud = *(offset + j);
+              //cout << "\t\t" << X[ngnoeud-1] << " " << Y[ngnoeud-1] << " " << Z[ngnoeud-1] << endl;
+              cout << "\t" << ngnoeud << "\t" << *(XX + ngnoeud - 1) << " " << *(YY + ngnoeud - 1) << " " << *(ZZ + ngnoeud - 1) << endl;
+            }
+        }
+      cout << endl;
+    }
+}
+
+void Maillage::listeMaillesType(TYPE_MAILLE tm)
+{
+  cout << "La fonction \"Restitution des mailles par type\" est obsolète " << endl;
+
+  //  cout << "Restitution des mailles du type " << TM2string(tm) << " (effectif " << EFFECTIFS_TYPES[tm] << "): " << endl;
+  //  if (EFFECTIFS_TYPES[tm])
+  //    for (int i = 0; i < IDS_MAILLES[tm].size(); i++)
+  //      cout << IDS_MAILLES[tm][i] << " ";
+  //  cout << endl;
+}
+
+void Maillage::listeMaillesTousTypes()
+{
+  for (int itm = (int) POI1; itm <= (int) HEXA20; itm++)
+    {
+      TYPE_MAILLE tm = (TYPE_MAILLE) itm;
+      listeMaillesType(tm);
+    }
+}
+
+void Maillage::listeMaillesParGM()
+{
+  cout << "Liste des mailles par GM : " << endl;
+  for (map<string, map<TYPE_MAILLE, vector<int> > >::iterator I = GM.begin(); I != GM.end(); I++)
+    listeMaillesGM(I->first);
+}
+
+void Maillage::listeMaillesGM(std::string nomGM)
+{
+  cout << "Liste des mailles du groupe " << nomGM << " : " << endl;
+  for (int itm = (int) POI1; itm <= (int) HEXA20; itm++)
+    {
+      TYPE_MAILLE tm = (TYPE_MAILLE) itm;
+      if (GM[nomGM][tm].size())
+        {
+          cout << "\t" << TM2string(tm) << " : ";
+          for (unsigned int j = 0; j < GM[nomGM][tm].size(); j++)
+            cout << GM[nomGM][tm][j] << " ";
+          cout << endl;
+        }
+    }
+}
+
+//void Maillage::listeMaillesGMordonne(std::string nomGM)
+//{
+//  cout << "Liste ordonnée des mailles du groupe " << nomGM << " (" << GM[nomGM].size() << " mailles) : ";
+//  sort(GM[nomGM].begin(), GM[nomGM].end());
+//  for (int j = 0; j < GM[nomGM].size(); j++)
+//    cout << GM[nomGM][j] << " ";
+//  cout << endl;
+//}
+
+void Maillage::listeNoeuds()
+{
+  cout << "Liste des noeuds du maillage : " << endl;
+  for (int i = 0; i < nombreNoeudsMaillage; i++)
+    cout << "\t" << *(XX + i) << " " << *(YY + i) << " " << *(ZZ + i) << endl;
+  cout << endl;
+}
+
+void Maillage::listeNoeudsGN(std::string nomGN)
+{
+  cout << "Liste brute des noeuds du groupe " << nomGN << " (" << GN[nomGN].size() << " noeuds) : ";
+  for (unsigned int j = 0; j < GN[nomGN].size(); j++)
+    cout << GN[nomGN][j] << " ";
+  cout << endl;
+}
+
+void Maillage::listeNoeudsGNordonne(std::string nomGN)
+{
+  cout << "Liste ordonnée des noeuds du groupe " << nomGN << " (" << GN[nomGN].size() << " noeuds) : ";
+  sort(GN[nomGN].begin(), GN[nomGN].end());
+  for (unsigned int j = 0; j < GN[nomGN].size(); j++)
+    cout << GN[nomGN][j] << " ";
+  cout << endl;
+}
+
+std::vector<float> Maillage::G(int i, TYPE_MAILLE tm)
+{
+  vector<float> G;
+  float x = 0.0;
+  float y = 0.0;
+  float z = 0.0;
+  int nn = NnoeudsGeom(tm);
+  for (int j = 0; j < nn; j++)
+    {
+      int ng = CNX[tm][nn * i + j];
+      x += XX[ng - 1];
+      y += YY[ng - 1];
+      z += ZZ[ng - 1];
+    }
+  G.push_back(x / nn);
+  G.push_back(y / nn);
+  G.push_back(z / nn);
+  G.resize(3);
+  return G;
+}
+
+float Maillage::distanceNoeudMaille(int ngnoeud, int imaille, TYPE_MAILLE tm)
+{
+  float x, y, z;
+  float x0 = XX[ngnoeud - 1];
+  float y0 = YY[ngnoeud - 1];
+  float z0 = ZZ[ngnoeud - 1];
+  int nn = NnoeudsGeom(tm);
+  float d1 = 1000000000000.0;
+  float d;
+  for (int j = 0; j < nn; j++)
+    {
+      int ng = CNX[tm][nn * imaille + j]; // Noeud courant dans la maille
+      x = XX[ng - 1];
+      y = YY[ng - 1];
+      z = ZZ[ng - 1];
+      d = sqrt((x - x0) * (x - x0) + (y - y0) * (y - y0) + (z - z0) * (z - z0));
+      if (d < d1)
+        d1 = d;
+    }
+  return d1;
+}
+
+/*!
+ *  Retourne le ng du noeud le plus proche de ngnoeud dans la maille imaille du type tm
+ */
+int Maillage::noeudVoisin(int ngnoeud, int imaille, TYPE_MAILLE tm)
+{
+  float x, y, z;
+  int ngv;
+  float x0 = XX[ngnoeud - 1];
+  float y0 = YY[ngnoeud - 1];
+  float z0 = ZZ[ngnoeud - 1];
+  int nn = NnoeudsGeom(tm);
+  float d1 = 1000000000000.0;
+  float d;
+  for (int j = 0; j < nn; j++)
+    {
+      int ng = CNX[tm][nn * imaille + j]; // Noeud courant dans la maille
+      x = XX[ng - 1];
+      y = YY[ng - 1];
+      z = ZZ[ng - 1];
+      d = sqrt((x - x0) * (x - x0) + (y - y0) * (y - y0) + (z - z0) * (z - z0));
+      if (d < d1)
+        {
+          d1 = d;
+          ngv = ng;
+        }
+    }
+  return ngv;
+}
+
+float Maillage::distanceNoeudNoeud(int ng1, int ng2)
+{
+  float x1, x2, y1, y2, z1, z2;
+  x1 = XX[ng1 - 1];
+  y1 = YY[ng1 - 1];
+  z1 = ZZ[ng1 - 1];
+  x2 = XX[ng2 - 1];
+  y2 = YY[ng2 - 1];
+  z2 = ZZ[ng2 - 1];
+  return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2));
+}
+
+//void Maillage::encombrements()
+//{
+//  float ex = 0.0;
+//  float ey = 0.0;
+//  float ez = 0.0;
+//
+//  for (int itm = (int) SEG2; itm <= (int) HEXA20; itm++)
+//    {
+//      TYPE_MAILLE tm = (TYPE_MAILLE) itm;
+//      if (MAILLAGE->EFFECTIFS_TYPES[tm])
+//        {
+//          int nnoeuds = Nnoeuds(tm);
+//          for (int i = 0; i < CON[tm].size() / nnoeuds; i++)
+//            {
+//              //Boucle sur les noeuds de la maille de numéro local i dans le type tm
+//              for (int j = 0; j < nnoeuds; j++)
+//                {
+//                  //..... CON[tm][nnoeuds*i+j];
+//                }
+//            }
+//        }
+//    }
+//  // Boucle sur les connectivités d'un type tm
+//}
+
+void Maillage::inputMED(std::string fichierMED)
+{
+  //cout << endl << "Début procédure inputMED, fichier "<< fichierMED << endl;
+
+  //  int i, j, k, ichamp, igauss, ipt, ival;
+  int j;
+  //  med_err ret = 0; // Code retour
+  med_idt fid; // Descripteur de fichier MED
+  char maa[MED_NAME_SIZE + 1]; // nom du maillage de longueur maxi MED_NAME_SIZE
+  med_int spacedim;
+  med_int mdim; // Dimension du maillage
+  med_mesh_type type;
+  char desc[MED_COMMENT_SIZE + 1]; // Description du maillage
+
+  // Profils
+  //  med_int nprofils;
+  //  int iprofil;
+  //  char nomprofil[MED_NAME_SIZE + 1] = "";
+  //  med_int nvalprofil, nvalprofil2;
+  //  med_int *pflval;
+
+  // Champs
+  //  med_int nChamps, nCompChamp, nval;
+  //  char *compChamp, *unitChamp, *nomChamp;
+  //char nomChamp [ MED_NAME_SIZE+1 ] = "";
+  //  med_field_type typeChamp;
+  //  med_int nGauss, ngpdt, numdt, numo;
+  med_int nPasTemps;
+  //  char locname[MED_NAME_SIZE + 1] = "";
+  //  med_geometry_type type_geo;
+  //  med_int ngauss;
+  char dtunit[MED_SNAME_SIZE + 1] = "";
+  //  med_float dt = 0.0;
+  //  med_bool local;
+  //  med_int nbrefmaa;
+
+  med_sorting_type sortingtype;
+  med_axis_type axistype;
+
+  // Initialisations
+  FAMILLES.clear();
+  FAM_TYPES.clear();
+  FAMILLES_NOEUDS.clear();
+  GROUPES_MAILLES.clear();
+  GROUPES_NOEUDS.clear();
+  RESIDU.clear(); // Sera initialisé Ã  1 par la routine acquisitionTYPE_inputMED
+  tailleFAMILLES.clear();
+  tailleGROUPES.clear();
+
+  // Ouverture du fichier MED en lecture seule
+  fid = MEDfileOpen(string2char(fichierMED), MED_ACC_RDONLY);
+  if (fid < 0)
+    {
+      ERREUR("Error file open\n");
+    }
+  //cout << chrono() << " --- inputMED: MEDfileOpen: ouverture du maillage en lecture seule, OK" << endl;
+
+  // Lecture des infos concernant le premier maillage
+  if (MEDmeshInfo(fid, 1, maa, &spacedim, &mdim, &type, desc, dtunit, &sortingtype, &nPasTemps, &axistype, axisname,
+                  unitname) < 0)
+    ERREUR("Error while reading mesh informations ");
+  //cout << chrono() << " --- inputMED: MEDmeshInfo: OK" << endl;
+
+//  cerr << "maa=" << maa << endl;
+//  cerr << "spacedim=" << spacedim << endl;
+//  cerr << "mdim=" << mdim << endl;
+//  cerr << "type=" << type << endl;
+//  cerr << "desc=" << desc << endl;
+//  cerr << "dtunit=" << dtunit << endl;
+//  cerr << "sortingtype=" << sortingtype << endl;
+//  cerr << "nPasTemps=" << nPasTemps << endl;
+//  cerr << "axistype=" << axistype << endl;
+//  cerr << "axisname=" << axisname << endl;
+//  cerr << "unitname=" << unitname << endl;
+
+  dimensionMaillage = mdim;
+  dimensionEspace = spacedim;
+
+  ID = (string) maa;
+
+  //  nGauss = MEDnGauss(fid);
+  //  if (debug > 0)
+  //    cout << "Nombre d'éléments portant des points de Gauss: " << (int) nGauss << endl;
+  //  map<string, int> REFGAUSS;
+  //  map<string, int>::iterator iterGAUSS;
+  //  for (igauss = 1; igauss <= nGauss; igauss++)
+  //    {
+  //      if (MEDgaussInfo(fid, igauss, locname, &type_geo, &ngauss) < 0)
+  //        ERREUR("Erreur MEDgaussInfo");
+  //      if (debug == 2)
+  //        {
+  //          cout << endl << "  Retour MEDgaussInfo, localisation gauss n°" << igauss << " : " << endl;
+  //          cout << "    locname  = " << locname << endl;
+  //          cout << "    type_geo = " << type_geo << endl;
+  //          cout << "    ngauss   = " << ngauss << endl;
+  //          cout << endl;
+  //        }
+  //      REFGAUSS[(string) locname] = (int) ngauss;
+  //    }
+  //
+  //  if (debug == 2)
+  //    {
+  //      cout << endl << "Restitution de la table REFGAUSS:" << endl;
+  //      for (iterGAUSS = REFGAUSS.begin(); iterGAUSS != REFGAUSS.end(); iterGAUSS++)
+  //        {
+  //          cout << iterGAUSS->first << " : " << iterGAUSS->second << endl;
+  //        }
+  //    }
+  //
+  //  nprofils = MEDnProfil(fid);
+  //  if (debug)
+  //    cout << endl << endl << "Nombre de profils: " << nprofils << endl;
+  //  for (iprofil = 1; iprofil <= nprofils; iprofil++)
+  //    {
+  //      if (MEDprofilInfo(fid, iprofil, nomprofil, &nvalprofil) < 0)
+  //        ERREUR("ERREUR MEDprofilInfo");
+  //      nvalprofil2 = MEDnValProfil(fid, nomprofil);
+  //      if (debug == 2)
+  //        {
+  //          cout << "Profil " << iprofil << " : " << endl;
+  //          cout << "    Nom profil : " << nomprofil << endl;
+  //          cout << "    Nombre de valeurs profil (par MEDprofilInfo) : " << nvalprofil << endl;
+  //          cout << "    Nombre de valeurs profil (par MEDnValProfil) : " << nvalprofil2 << endl;
+  //        }
+  //      if (nvalprofil != nvalprofil2)
+  //        ERREUR("Discordance nvalprofil (entre MEDprofilInfo et MEDnValProfil)");
+  //      pflval = (med_int*) malloc(sizeof(med_int) * nvalprofil);
+  //      if (MEDprofilLire(fid, pflval, nomprofil) < 0)
+  //        ERREUR("ERREUR MEDprofilLire");
+  //      //cout << "    Affichage des 100 premières valeurs:" << endl;
+  //      //for (ival=0;ival<min(100,nvalprofil);ival++) cout << " " << *(pflval+ival) ;
+  //      free(pflval);
+  //    }
+  //
+  //  nChamps = MEDnChamp(fid, 0);
+  //  cout << "Nombre de champs : " << (int) nChamps << endl;
+  //
+  //  if (nChamps > 0)
+  //    {
+  //
+  //      for (ichamp = 1; ichamp <= nChamps; ichamp++)
+  //        {
+  //          //for (ichamp=4; ichamp<=4; ichamp++ ) {
+  //          cout << endl << endl;
+  //          cout << endl << endl << " ====================================================================" << endl;
+  //          cout << endl << endl << "                             CHAMP " << ichamp << endl;
+  //          cout << endl << endl << " ====================================================================" << endl;
+  //          cout << endl << endl;
+  //
+  //          nCompChamp = MEDnChamp(fid, ichamp);
+  //          if (nCompChamp < 0)
+  //            ERREUR("Erreur Ncomposantes champ");
+  //          cout << "Nombre de composantes du champ " << ichamp << " : " << (int) nCompChamp << endl;
+  //
+  //          nomChamp = (char*) malloc(MED_NAME_SIZE + 1);
+  //          compChamp = (char*) malloc(nCompChamp * MED_SNAME_SIZE + 1);
+  //          unitChamp = (char*) malloc(nCompChamp * MED_SNAME_SIZE + 1);
+  //
+  //          if (MEDchampInfo(fid, ichamp, nomChamp, &typeChamp, compChamp, unitChamp, nCompChamp) < 0)
+  //            ERREUR("Erreur MEDchampInfo");
+  //
+  //          cout << "Infos sur le champ " << ichamp << " : " << endl;
+  //          cout << "  Nom:  " << (string) nomChamp << endl;
+  //          cout << "  Type:  " << typeChamp << endl;
+  //          cout << "  Noms des composantes:  " << (string) compChamp << endl;
+  //          cout << "  Unités des composantes:  " << (string) unitChamp << endl;
+  //
+  //          infoChamps((string) "NOEUDS", MED_NODE, MED_NONE, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
+  //          infoChamps((string) "POI1", MED_CELL, MED_POINT1, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
+  //          infoChamps((string) "SEG2", MED_CELL, MED_SEG2, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
+  //          infoChamps((string) "SEG3", MED_CELL, MED_SEG3, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
+  //          infoChamps((string) "TRIA3", MED_CELL, MED_TRIA3, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
+  //          infoChamps((string) "TRIA6", MED_CELL, MED_TRIA6, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
+  //          infoChamps((string) "QUAD4", MED_CELL, MED_QUAD4, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
+  //          infoChamps((string) "QUAD8", MED_CELL, MED_QUAD8, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
+  //          infoChamps((string) "TETRA4", MED_CELL, MED_TETRA4, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
+  //          infoChamps((string) "TETRA10", MED_CELL, MED_TETRA10, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
+  //          infoChamps((string) "PYRAM5", MED_CELL, MED_PYRA5, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
+  //          infoChamps((string) "PYRAM13", MED_CELL, MED_PYRA13, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
+  //          infoChamps((string) "PENTA6", MED_CELL, MED_PENTA6, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
+  //          infoChamps((string) "PENTA15", MED_CELL, MED_PENTA15, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
+  //          infoChamps((string) "HEXA8", MED_CELL, MED_HEXA8, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
+  //          infoChamps((string) "HEXA20", MED_CELL, MED_HEXA20, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
+  //
+  //        }
+  //
+  //      cout << endl << "Rappel des codes de géométries: " << endl;
+  //      cout << " TETRA4 = " << MED_TETRA4 << endl;
+  //      cout << " PENTA6 = " << MED_PENTA6 << endl;
+  //      cout << " HEXA8 = " << MED_HEXA8 << endl;
+  //
+  //    }
+  //  else
+  //    cout << "Pas de champs dans ce maillage" << endl;
+
+  // ##################################################################################################
+  // ##################################################################################################
+  //
+  //                  A C Q U I S I T I O N     D E S     F A M I L L E S
+  //
+  // ##################################################################################################
+  // ##################################################################################################
+
+
+  med_int nFamilles;
+  char nomGroupeChar[MED_LNAME_SIZE + 1];
+  if ((nFamilles = MEDnFamily(fid, maa)) < 0)
+    ERREUR("ERROR MEDnFamily");
+
+  // Initialisation des tailles:   tailleFAMILLES  et  tailleGROUPES
+
+  //   for (int i = 0; i < nFamilles; i++)
+  //    {
+  //      char nomfam[MED_NAME_SIZE + 1];
+  //      char *attdes, *gro;
+  //      med_int numfam, *attide, *attval, natt, ngro;
+  //
+  //      if ((ngro = MEDnFamilyGroup(fid, maa, i + 1)) < 0)
+  //        ERREUR("ERREUR MEDnFamilyGroup");
+  //      if ((natt = MEDnFamily23Attribute(fid, maa, i + 1)) < 0)
+  //        ERREUR("ERREUR MEDnFamily23Attribute");
+  //
+  //      attide = (med_int *) malloc(sizeof(med_int) * natt);
+  //      attval = (med_int *) malloc(sizeof(med_int) * natt);
+  //      attdes = (char *) malloc(MED_COMMENT_SIZE * natt + 1);
+  //      gro = (char *) malloc(MED_LNAME_SIZE * ngro + 1);
+  //
+  //      if (MEDfamilyInfo(fid, maa, (med_int)(i + 1), nomfam, &numfam, attide, attval, attdes, &natt, gro, &ngro) < 0)
+  //        ERREUR("ERREUR MEDfamilyInfo");
+  //
+  //      free(attide);
+  //      free(attval);
+  //      free(attdes);
+  //      free(gro);
+  //    }
+
+  for (int i = 0; i < nFamilles; i++)
+    {
+      char nomfam[MED_NAME_SIZE + 1];
+      char *attdes, *gro;
+      med_int numfam, *attide, *attval, natt, ngro;
+
+      if ((ngro = MEDnFamilyGroup(fid, maa, i + 1)) < 0)
+        ERREUR("ERROR MEDnFamilyGroup");
+      if ((natt = MEDnFamily23Attribute(fid, maa, i + 1)) < 0)
+        ERREUR("ERROR MEDnFamily23Attribute");
+
+      attide = (med_int *) malloc(sizeof(med_int) * natt);
+      attval = (med_int *) malloc(sizeof(med_int) * natt);
+      attdes = (char *) malloc(MED_COMMENT_SIZE * natt + 1);
+      gro = (char *) malloc(MED_LNAME_SIZE * ngro + 1);
+
+      if (MEDfamilyInfo(fid, maa, (med_int) (i + 1), nomfam, &numfam, gro) < 0)
+        ERREUR("ERROR MEDfamilyInfo");
+
+      for (int ig = 1; ig <= ngro; ig++)
+        {
+          for (j = 0; j < MED_LNAME_SIZE; j++)
+            nomGroupeChar[j] = gro[(ig - 1) * MED_LNAME_SIZE + j];
+          nomGroupeChar[MED_LNAME_SIZE] = '\0';
+          //cout << "Groupe lu : " << (string)nomGroupeChar << endl;
+          tailleGROUPES[strip((string) nomGroupeChar)]++;
+          if (numfam > 0)
+            GROUPES_NOEUDS[strip((string) nomGroupeChar)].push_back((int) numfam);
+          else if (numfam < 0)
+            GROUPES_MAILLES[strip((string) nomGroupeChar)].push_back((int) numfam);
+        }
+
+      free(attide);
+      free(attval);
+      free(attdes);
+      free(gro);
+    }
+
+  // ##################################################################################################
+  // ##################################################################################################
+  //
+  //                  A C Q U I S I T I O N     D E S     N O E U D S
+  //
+  // ##################################################################################################
+  // ##################################################################################################
+
+  //  class Noeud *n;
+  //  list<Noeud*> listeNoeuds;
+  //  float x, y, z, rx, ry, rz, tx, ty, tz;
+  string line, IDnoeud;
+  float x0, x1, y0, y1, z0, z1;
+
+  vector<int> RESIDU_NOEUDS; // Table de vérité du résidu des noeuds
+
+  ostringstream OSCOORD;
+
+  med_int nnoe = 0; // Nbre de noeuds
+  med_float *coo1; // Table des coordonnées
+  //  char nomcoo[mdim * MED_SNAME_SIZE + 1]; // Table des noms des coordonnées
+  //  char unicoo[mdim * MED_SNAME_SIZE + 1]; // Table des unités des coordonnées
+  char *nomnoe;
+
+  med_int *numnoe;
+  med_int *nufano;
+  //  med_grid_type rep;
+  //  med_bool inonoe, inunoe;
+  //  med_int profil[2] = { 2, 3 };
+  med_bool coordinatechangement;
+  med_bool geotransformation;
+
+  // Combien de noeuds a lire ?
+  nnoe = MEDmeshnEntity(fid, maa, MED_NO_DT, MED_NO_IT, MED_NODE, MED_NO_GEOTYPE, MED_COORDINATE, MED_NO_CMODE,
+                        &coordinatechangement, &geotransformation);
+
+  if (nnoe < 0)
+    ERREUR("Error while reading number of nodes");
+
+  nombreNoeudsMaillage = nnoe;
+
+  // Lecture des familles des noeuds
+  med_int *famNoeuds = (med_int*) malloc(sizeof(med_int) * nnoe);
+  if (nnoe > 0)
+    {
+      if (MEDmeshEntityFamilyNumberRd(fid, maa, MED_NO_DT, MED_NO_IT, MED_NODE, MED_NONE, famNoeuds) < 0)
+        ERREUR("Error while reading family node number (MEDmeshEntityFamilyNumberRd)");
+    }
+
+  /* Allocations memoires */
+  if (nnoe > 0)
+    {
+      // table des coordonnees - profil : (dimension * nombre de noeuds )
+      coo1 = (med_float*) calloc(nnoe * mdim, sizeof(med_float));
+      // table des 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_SNAME_SIZE+1)
+      nomnoe = (char*) malloc(MED_SNAME_SIZE * nnoe + 1);
+    }
+
+  // Lecture des composantes des coordonnees des noeuds
+  if (nnoe > 0)
+    if (MEDmeshNodeCoordinateRd(fid, maa, MED_NO_DT, MED_NO_IT, MED_FULL_INTERLACE, coo1) < 0)
+      ERREUR("Error while reading nodes coordinates");
+
+  //   // Les noeuds ont-ils un nom? un numéro?
+  //  if (nnoe > 0)
+  //    {
+  //      if (MEDnomLire(fid, maa, nomnoe, nnoe, MED_NODE, (med_geometry_type) 0) < 0)
+  //        inonoe = MED_FALSE;
+  //      else
+  //        inonoe = MED_TRUE;
+  //      if (MEDnumLire(fid, maa, numnoe, nnoe, MED_NODE, (med_geometry_type) 0) < 0)
+  //        inunoe = MED_FALSE;
+  //      else
+  //        inunoe = MED_TRUE;
+  //    }
+  //
+  //  if (inonoe)
+  //    cout << "WARNING input MED : les noms des noeuds sont ignorés" << endl;
+  //  if (inunoe)
+  //    cout << "WARNING input MED : les numéros des noeuds sont ignorés" << endl;
+  //
+  //  if (inonoe)
+  //    {
+  //      char str[MED_SNAME_SIZE + 1];
+  //      for (int inoeud = 0; inoeud < nnoe; inoeud++)
+  //        {
+  //          strncpy(str, nomnoe + inoeud * MED_SNAME_SIZE, MED_SNAME_SIZE);
+  //          str[MED_SNAME_SIZE] = '\0';
+  //          IDS_NOEUDS.push_back((string) str);
+  //        }
+  //    }
+  //  else if (inunoe)
+  //    {
+  //      for (int inoeud = 0; inoeud < nnoe; inoeud++)
+  //        {
+  //          int numnoeud = *(numnoe + inoeud);
+  //          IDS_NOEUDS.push_back((string) "N" + int2string(numnoeud));
+  //        }
+  //    }
+  //  else
+  //    for (int inoeud = 0; inoeud < nnoe; inoeud++)
+  //      IDS_NOEUDS.push_back((string) "N" + int2string(inoeud + 1));
+  //  IDS_NOEUDS.resize(nnoe);
+
+  /* ====================================================================== */
+  /*               BOUCLE SUR LES NOEUDS LUS DANS LE FICHIER MED            */
+  /* ====================================================================== */
+
+  //  X.resize(nnoe);
+  //  Y.resize(nnoe);
+  //  Z.resize(nnoe);
+
+  // Initialisation de l'enveloppe
+  x0 = coo1[0];
+  x1 = coo1[0];
+  y0 = coo1[1];
+  y1 = coo1[1];
+  if (mdim == 3)
+    {
+      z0 = coo1[2];
+      z1 = coo1[2];
+    }
+  else
+    {
+      z0 = 0.0;
+      z1 = 0.0;
+    }
+
+  // Allocation mémoire pour les coordonnées XX YY ZZ
+  XX = (float*) malloc(sizeof(float) * nombreNoeudsMaillage);
+  if (mdim > 1)
+    YY = (float*) malloc(sizeof(float) * nombreNoeudsMaillage);
+  if (mdim > 2)
+    ZZ = (float*) malloc(sizeof(float) * nombreNoeudsMaillage);
+
+  for (int i = 0; i < nnoe; i++)
+    {
+
+      // Chargement des coordonnées X, Y et Z
+      // Calcul de l'enveloppe du maillage
+
+      FAMILLES_NOEUDS[*(famNoeuds + i)].push_back(i + 1); // ATTENTION! Les num. de noeuds commencent Ã  1
+      tailleFAMILLES[*(famNoeuds + i)]++;
+
+      // IDnoeud = "N"+int2string(i+1);
+
+      float * XXi = XX + i;
+      float * YYi = YY + i;
+      float * ZZi = ZZ + i;
+
+      if (mdim == 3)
+        {
+          *XXi = (float) coo1[3 * i];
+          *YYi = (float) coo1[3 * i + 1];
+          *ZZi = (float) coo1[3 * i + 2];
+          if (*XXi < x0)
+            x0 = *XXi;
+          else if (*XXi > x1)
+            x1 = *XXi;
+          if (*YYi < y0)
+            y0 = *YYi;
+          else if (*YYi > y1)
+            y1 = *YYi;
+          if (*ZZi < z0)
+            z0 = *ZZi;
+          else if (*ZZi > z1)
+            z1 = *ZZi;
+        }
+      else if (mdim == 2)
+        {
+          *XXi = (float) coo1[2 * i];
+          *YYi = (float) coo1[2 * i + 1];
+          if (*XXi < x0)
+            x0 = *XXi;
+          else if (*XXi > x1)
+            x1 = *XXi;
+          if (*YYi < y0)
+            y0 = *YYi;
+          else if (*YYi > y1)
+            y1 = *YYi;
+        }
+      else if (mdim == 1)
+        {
+          *XXi = (float) coo1[1 * i];
+          if (*XXi < x0)
+            x0 = *XXi;
+          else if (*XXi > x1)
+            x1 = *XXi;
+        }
+
+      // Chargement des numéros de noeuds
+      //      if (inunoe)
+      //        NUM_NOEUDS.push_back(*(numnoe + i));
+      //      else
+      //        NUM_NOEUDS.push_back(i + 1);
+
+    } // boucle sur les noeuds
+
+  //  NUM_NOEUDS.resize(nnoe);
+
+  // Enveloppe du maillage
+  enveloppeMaillage = new Cube(x0, x1, y0, y1, z0, z1);
+
+  // Libération mémoire
+  if (nnoe > 0)
+    {
+      free(coo1);
+      free(nomnoe);
+      free(numnoe);
+      free(nufano);
+    }
+
+  // ##################################################################################################
+  // ##################################################################################################
+  //
+  //                  A C Q U I S I T I O N     D E S     M A I L L E S
+  //
+  // ##################################################################################################
+  // ##################################################################################################
+
+  for (int itm = (int) POI1; itm <= (int) HEXA20; itm++)
+    {
+      TYPE_MAILLE tm = (TYPE_MAILLE) itm;
+      EFFECTIFS_TYPES[tm] = MEDmeshnEntity(fid, maa, MED_NO_DT, MED_NO_IT, MED_CELL, InstanceMGE(tm), MED_CONNECTIVITY,
+                                           MED_NODAL, &coordinatechangement, &geotransformation);
+      if (EFFECTIFS_TYPES[tm])
+        acquisitionTYPE_inputMED(tm, EFFECTIFS_TYPES[tm], fid, maa, mdim);
+    }
+
+  // Resize des vecteurs des maps FAMILLES et FAM_TYPES
+  map<int, vector<int> >::iterator IF;
+  for (IF = FAMILLES.begin(); IF != FAMILLES.end(); IF++)
+    {
+      IF->second.resize(tailleFAMILLES[IF->first]);
+      FAM_TYPES[IF->first].resize(tailleFAMILLES[IF->first]);
+    }
+
+  for (int itm = (int) POI1; itm <= (int) HEXA20; itm++)
+    nombreMaillesMaillage += EFFECTIFS_TYPES[(TYPE_MAILLE) itm];
+
+  // ##################################################################################################
+  // ##################################################################################################
+  //
+  //          A C Q U I S I T I O N     D E S     G R O U P E S
+  //          D E    M A I L L E S    E T    D E    N O E U D S
+  //
+  // ##################################################################################################
+  // ##################################################################################################
+
+  // =============================================================================================
+  //                 Chargement des groupes dans GM et GN
+  // =============================================================================================
+
+  string nomGM;
+  vector<int> vfam;
+  map<string, vector<int> >::iterator iterGRO;
+
+  int cptGM = 0;
+  for (iterGRO = GROUPES_MAILLES.begin(); iterGRO != GROUPES_MAILLES.end(); iterGRO++)
+    {
+      nomGM = iterGRO->first;
+      vfam = iterGRO->second;
+      cptGM++;
+      map<TYPE_MAILLE, int> effectifGroupeType;
+      for (unsigned int i = 0; i < vfam.size(); i++)
+        {
+          int numf = vfam[i];
+          // Parcours simultané des vecteurs FAMILLES[numf] et FAM_TYPES[numfam] pour obtention du num local
+          // et du type des mailles de la famille numf
+          for (unsigned int imaille = 0; imaille < FAMILLES[numf].size(); imaille++)
+            {
+              TYPE_MAILLE tm = FAM_TYPES[numf][imaille];
+              int nl = FAMILLES[numf][imaille];
+              GM[nomGM][tm].push_back(nl);
+              effectifGroupeType[tm]++;
+            }
+        }
+
+      // Resize d'un GM
+      for (map<TYPE_MAILLE, vector<int> >::iterator I = GM[nomGM].begin(); I != GM[nomGM].end(); I++)
+        {
+          TYPE_MAILLE tm = I->first;
+          GM[nomGM][tm].resize(effectifGroupeType[tm]);
+          sort(GM[nomGM][tm].begin(), GM[nomGM][tm].end());
+        }
+    }
+
+  int cptGN = 0;
+  for (iterGRO = GROUPES_NOEUDS.begin(); iterGRO != GROUPES_NOEUDS.end(); iterGRO++)
+    {
+      nomGM = iterGRO->first;
+      vfam = iterGRO->second;
+      cptGN++;
+      int cptNoeudsGN = 0;
+      for (unsigned int i = 0; i < vfam.size(); i++)
+        {
+          int numf = vfam[i];
+          // Parcours vecteurs FAMILLES_NOEUDS[numf]
+          for (unsigned int inoeud = 0; inoeud < FAMILLES_NOEUDS[numf].size(); inoeud++)
+            {
+              GN[nomGM].push_back(FAMILLES_NOEUDS[numf][inoeud]);
+              cptNoeudsGN++;
+            }
+        }
+      GN[nomGM].resize(cptNoeudsGN);
+      sort(GN[nomGM].begin(), GN[nomGM].end());
+    }
+
+  MEDfileClose(fid);
+  //  cout << "Fin procédure inputMED" << endl << endl;
+}
+
+void Maillage::acquisitionTYPE_inputMED(TYPE_MAILLE TYPE, int nTYPE, med_idt fid, char maa[MED_NAME_SIZE + 1],
+                                        med_int mdim)
+{
+
+  //  int taille, numeromaille, numeroFamille;
+  int numeroFamille;
+  string line, IDmaille, IDnoeud, typeMaille;
+  //  char str[MED_SNAME_SIZE + 1]; // Conteneur pour un nom de maille
+  //  bool rejetMaille;
+  med_int tTYPE = (med_int) Nnoeuds(TYPE);
+  char *nomTYPE = (char*) malloc(MED_SNAME_SIZE * nTYPE + 1);
+  med_int *numTYPE = (med_int*) malloc(sizeof(med_int) * nTYPE);
+  med_int *famTYPE = (med_int*) malloc(sizeof(med_int) * nTYPE);
+
+  //med_int *conTYPE = (med_int*) malloc(sizeof(med_int)*tTYPE*nTYPE);
+  CNX[TYPE] = (int*) malloc(sizeof(int) * tTYPE * nTYPE);
+
+  med_bool inomTYPE, inumTYPE, ifamTYPE;
+  med_geometry_type typeBanaliseMED = InstanceMGE(TYPE);
+
+  if (MEDmeshElementRd(fid, maa, MED_NO_DT, MED_NO_IT, MED_CELL, typeBanaliseMED, MED_NODAL, MED_FULL_INTERLACE,
+                       CNX[TYPE], &inomTYPE, nomTYPE, &inumTYPE, numTYPE, &ifamTYPE, famTYPE) < 0)
+    ERREUR("Error while reading elements");
+
+  // Conversion HL
+  conversionCNX(CNX[TYPE], TYPE, nTYPE);
+
+  //  CON[TYPE].resize(tTYPE * nTYPE);
+  //  for (int i = 0; i < tTYPE * nTYPE; i++)
+  //    CON[TYPE][i] = (int) *(conTYPE + i);
+  //  CNX[TYPE] = (int*) malloc(sizeof(int) * tTYPE * nTYPE);
+  //  for (int i = 0; i < tTYPE * nTYPE; i++)
+  //    *(CNX[TYPE] + i) = (int) *(conTYPE + i);
+
+  for (int i = 0; i < nTYPE; i++)
+    {
+      numeroFamille = (int) *(famTYPE + i);
+      FAMILLES[numeroFamille].push_back(i);
+      tailleFAMILLES[numeroFamille]++;
+      FAM_TYPES[numeroFamille].push_back(TYPE);
+
+      // Chargement des numéros de mailles
+      //      if (inumTYPE)
+      //        NUM_MAILLES[TYPE].push_back(*(numTYPE + i));
+      //      else
+      //        NUM_MAILLES[TYPE].push_back(NGLOBAL(TYPE, i));
+
+    }
+  //  NUM_MAILLES[TYPE].resize(nTYPE);
+
+  //   if (inomTYPE)
+  //    {
+  //      char str[MED_SNAME_SIZE + 1];
+  //      for (int imaille = 0; imaille < nTYPE; imaille++)
+  //        {
+  //          strncpy(str, nomTYPE + imaille * MED_SNAME_SIZE, MED_SNAME_SIZE);
+  //          str[MED_SNAME_SIZE] = '\0';
+  //          IDS_MAILLES[TYPE].push_back((string) str);
+  //        }
+  //    }
+  //  else if (inumTYPE)
+  //    {
+  //      for (int imaille = 0; imaille < nTYPE; imaille++)
+  //        {
+  //          int nummaille = *(numTYPE + imaille);
+  //          IDS_MAILLES[TYPE].push_back((string) "M" + int2string(nummaille));
+  //        }
+  //    }
+  //  else
+  //    {
+  //      for (int imaille = 0; imaille < nTYPE; imaille++)
+  //        {
+  //          IDS_MAILLES[TYPE].push_back((string) "M" + int2string(imaille + 1));
+  //        }
+  //    }
+  //  IDS_MAILLES[TYPE].resize(nTYPE);
+}
+
+void Maillage::outputMED(std::string fichierMED)
+{
+  // int i, j, k;
+  int nTYPE, tTYPE;
+  string line, s, stype, nomnoeud;
+  //  med_err ret = 0; // Code retour
+  //  int ig, jg;
+  //  cout << endl << endl << "Début procédure outputMED, fichier " << fichierMED << endl;
+
+  // Sortie sur erreur en cas de maillage sans noeuds
+  if (nombreNoeudsMaillage <= 0)
+    {
+      ERREUR("This mesh does not contain any node\n"); /* cout << "Maillage sans noeuds" << endl; */
+    }
+
+  // ########################################################################
+  //    Ouverture du fichier MED et création du maillage
+  // ########################################################################
+
+  // Ouverture du fichier MED en création
+  med_idt fid = MEDfileOpen(string2char(fichierMED), MED_ACC_CREAT);
+  if (fid < 0)
+    {
+      ERREUR("Error MEDfileOpen\n");
+      cout << "Error MEDfileOpen" << endl;
+    }
+
+  // Création du maillage
+  char maa[MED_NAME_SIZE + 1]; // Nom du maillage de longueur maxi MED_NAME_SIZE
+  strcpy(maa, string2char(ID));
+
+  med_int mdim; // Dimension du maillage
+  if (dimensionMaillage == 0)
+    {
+      mdim = 3;
+      cout << "ATTENTION, dimension 3 attribuée par défaut!" << endl;
+    }
+  else
+    mdim = dimensionMaillage;
+  med_int spacedim = 3;
+  if (dimensionEspace)
+    spacedim = dimensionEspace;
+
+  //med_int profil[2] = { 2, 3 };
+  char desc[MED_COMMENT_SIZE + 1]; // Description du maillage
+  strcpy(desc, string2char(ID));
+  med_mesh_type type = MED_UNSTRUCTURED_MESH;
+//  cerr << "maa=" << maa << endl;
+//  cerr << "spacedim=" << spacedim << endl;
+//  cerr << "mdim=" << mdim << endl;
+//  cerr << "type=" << type << endl;
+//  cerr << "axisname=" << axisname << endl;
+//  cerr << "unitname=" << unitname << endl;
+  if (MEDmeshCr(fid, maa, spacedim, mdim, type, desc, "s", MED_SORT_DTIT, MED_CARTESIAN, axisname, unitname) < 0)
+    {
+      ERREUR("Error MEDmeshCr");
+      cout << "Error MEDmeshCr" << endl;
+    }
+
+  // =============================  CREATION FAMILLE ZERO
+  char nomfam[MED_NAME_SIZE + 1];
+  med_int numfam;
+  //  char attdes[MED_COMMENT_SIZE + 1];
+  //  med_int natt, attide, attval;
+  int ngro;
+  //  char gro[MED_LNAME_SIZE + 1];
+
+  strcpy(nomfam, "FAMILLE_0");
+  numfam = 0;
+  if (MEDfamilyCr(fid, maa, nomfam, numfam, 0, MED_NO_GROUP) < 0)
+    ERREUR("Error MEDfamilyCr (create family 0)");
+
+  // ########################################################################
+  //          GROUPES DE NOEUDS
+  // ########################################################################
+
+  int nGroupesNoeuds = GN.size();
+
+  vector<vector<int> > ETIQUETTES_N;
+  ETIQUETTES_N.resize(nombreNoeudsMaillage);
+  vector<unsigned int> INDEX_N;
+  INDEX_N.resize(GN.size());
+  vector<string> NOMSFAM;
+  vector<vector<int> > ETIQFAM;
+  int cptNOMFAM = 0;
+  map<string, int> NUMFAMETIQ; //  clé = Ã©tiquette  -  valeur = numéros de familles
+
+
+  if (nGroupesNoeuds)
+    {
+
+      // Pérennisation d'un ordre sur les GM dans le vecteur NOMS_GROUPES_MAILLES
+      vector<string> NOMS_GROUPES_NOEUDS;
+      for (map<string, vector<int> >::iterator ITGN = GN.begin(); ITGN != GN.end(); ITGN++)
+        {
+          string nomGN = ITGN->first;
+          NOMS_GROUPES_NOEUDS.push_back(nomGN);
+        }
+      NOMS_GROUPES_NOEUDS.resize(GN.size());
+
+      // Tri des vecteurs de noeuds de GN
+      for (unsigned int ig = 0; ig < NOMS_GROUPES_NOEUDS.size(); ig++)
+        sort(GN[NOMS_GROUPES_NOEUDS[ig]].begin(), GN[NOMS_GROUPES_NOEUDS[ig]].end());
+
+      // Construction des Ã©tiquettes (familles)
+
+      // Initialisation des index de groupes
+      for (unsigned int ig = 0; ig < NOMS_GROUPES_NOEUDS.size(); ig++)
+        INDEX_N[ig] = 0;
+
+      for (int k = 1; k <= nombreNoeudsMaillage; k++)
+        { // k: num. global de noeud
+          int tailleEtiquette = 0;
+          string etiq = (string) "";
+          // Boucle sur les groupes
+          for (unsigned int ig = 0; ig < NOMS_GROUPES_NOEUDS.size(); ig++)
+            {
+              if (INDEX_N[ig] < GN[NOMS_GROUPES_NOEUDS[ig]].size())
+                {
+                  string nomgroupe = NOMS_GROUPES_NOEUDS[ig];
+                  if (k == GN[nomgroupe][INDEX_N[ig]])
+                    {
+                      // Attention: l'indice 0 dans le vecteur ETIQUETTES correspond
+                      // Ã  l'élément (noeud ou maille) de num. global 1
+                      // Par ailleurs, le numéro de groupe dans l'étiquette commence Ã  0
+                      ETIQUETTES_N[k - 1].push_back(ig);
+                      tailleEtiquette++;
+                      etiq += int2string(ig);
+                      INDEX_N[ig]++;
+                    }
+                }
+            }
+          ETIQUETTES_N[k - 1].resize(tailleEtiquette);
+          // Stockage de l'étiquette dans NOMSFAM ETIQFAM, si pas déjà stockée
+          //          bool trouve = false;
+          //          for (int i = 0; i < NOMSFAM.size(); i++)
+          //            if (NOMSFAM[i] == ((string) "ETIQUETTE_" + etiq))
+          //              {
+          //                trouve = true;
+          //                break;
+          //              }
+          if (!NUMFAMETIQ[etiq] && etiq != (string) "")
+            {
+              NOMSFAM.push_back((string) "ETIQN_" + etiq);
+              ETIQFAM.push_back(ETIQUETTES_N[k - 1]);
+              NUMFAMETIQ[etiq] = cptNOMFAM + 1; // Famille de noeuds, num>0
+              cptNOMFAM++;
+            }
+        }
+
+      NOMSFAM.resize(cptNOMFAM);
+      ETIQFAM.resize(cptNOMFAM);
+
+      // Création des familles de noeuds
+      for (unsigned int ifam = 0; ifam < NOMSFAM.size(); ifam++)
+        {
+          strcpy(nomfam, string2char(NOMSFAM[ifam]));
+          // Numéro de famille: ifam+1 (positif pour les noeuds + non nul)
+          numfam = ifam + 1;
+          ngro = ETIQFAM[ifam].size();
+
+          // Noms des groupes de la famille: variable nomsGN
+          char *gro = new char[ngro * MED_LNAME_SIZE + 1];
+          int cptGN = 0;
+          for (unsigned int ign = 0; ign < ETIQFAM[ifam].size(); ign++)
+            {
+              string nomGNcourant = NOMS_GROUPES_NOEUDS[ETIQFAM[ifam][ign]];
+              // ATTENTION! Il faut mettre Ã  la fin de chaque segment un \0 qui est ensuite Ã©crasé
+              // par le premier caractère du champ suivant dans le strcat !!!!
+              if (ign == 0)
+                {
+                  // Premier groupe
+                  strcpy(gro, string2char(nomGNcourant));
+                  for (int jg = nomGNcourant.size(); jg < MED_LNAME_SIZE; jg++)
+                    gro[jg] = ' ';
+                  gro[MED_LNAME_SIZE] = '\0';
+                }
+              else
+                {
+                  strcat(gro, string2char(nomGNcourant));
+                  for (int jg = nomGNcourant.size(); jg < MED_LNAME_SIZE; jg++)
+                    gro[cptGN * MED_LNAME_SIZE + jg] = ' ';
+                  gro[(cptGN + 1) * MED_LNAME_SIZE] = '\0';
+                }
+              cptGN++;
+            }
+
+          // Création de la famille
+          if (MEDfamilyCr(fid, maa, nomfam, numfam, 0, MED_NO_GROUP) < 0)
+            ERREUR("Error MEDfamilyCr");
+         delete gro;
+       }
+
+    }
+
+  // ########################################################################
+  //          NOEUDS
+  // ########################################################################
+
+  //  float x, y, z;
+
+  med_int nnoe = nombreNoeudsMaillage; // Nombre de noeuds
+  med_float *coo; // Table des coordonnées
+
+  // Noms des coordonnées (variable nomcoo)
+  char* nomcoo = new char[mdim * MED_SNAME_SIZE + 1];
+  string strX = (string) "X";
+  while (strX.size() < MED_SNAME_SIZE)
+    strX += (string) " ";
+  string strY = (string) "Y";
+  while (strY.size() < MED_SNAME_SIZE)
+    strY += (string) " ";
+  string strZ = (string) "Z";
+  while (strZ.size() < MED_SNAME_SIZE)
+    strZ += (string) " ";
+  if (mdim == 3)
+    strcpy(nomcoo, string2char(strX + strY + strZ));
+  else if (mdim == 2)
+    strcpy(nomcoo, string2char(strX + strY));
+  else
+    strcpy(nomcoo, string2char(strX));
+  nomcoo[mdim * MED_SNAME_SIZE] = '\0';
+
+  // Unités des coordonnées (variable unicoo)
+  char* unicoo = new char[mdim * MED_SNAME_SIZE + 1];
+  string strmesure = (string) "SI";
+  while (strmesure.size() < MED_SNAME_SIZE)
+    strmesure += (string) " ";
+  if (mdim == 3)
+    strcpy(unicoo, string2char(strmesure + strmesure + strmesure));
+  else if (mdim == 2)
+    strcpy(unicoo, string2char(strmesure + strmesure));
+  else
+    strcpy(unicoo, string2char(strmesure));
+  unicoo[mdim * MED_SNAME_SIZE] = '\0';
+
+  // Tables des noms, numeros, numeros de familles des noeuds
+  //    autant d'elements que de noeuds - les noms ont pout longueur MED_SNAME_SIZE
+  char *nomnoe;
+  med_int *numnoe = NULL;
+  med_int *nufano;
+  med_bool inonoe = MED_FALSE;
+  med_bool inunoe = MED_FALSE;
+
+  // Allocations memoire
+  if (nnoe > 0)
+    {
+      // table des coordonnees - profil : (dimension * nombre de noeuds )
+      coo = (med_float*) calloc(nnoe * mdim, sizeof(med_float));
+
+      // table des 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_SNAME_SIZE+1)
+      nomnoe = (char*) ""; // ATTENTION!
+
+      //      nomnoe = (char*) malloc(MED_SNAME_SIZE * nnoe + 1);
+      //      for (int inoeud = 0; inoeud < IDS_NOEUDS.size(); inoeud++)
+      //        {
+      //          string nomNoeud = IDS_NOEUDS[inoeud];
+      //          if (inoeud == 0)
+      //            {
+      //              // Premier groupe
+      //              strcpy(nomnoe, string2char(nomNoeud));
+      //              for (int jg = nomNoeud.size(); jg < MED_SNAME_SIZE; jg++)
+      //                nomnoe[jg] = ' ';
+      //              nomnoe[MED_SNAME_SIZE] = '\0';
+      //            }
+      //          else
+      //            {
+      //              strcat(nomnoe, string2char(nomNoeud));
+      //              for (int jg = nomNoeud.size(); jg < MED_SNAME_SIZE; jg++)
+      //                nomnoe[inoeud * MED_SNAME_SIZE + jg] = ' ';
+      //              nomnoe[(inoeud + 1) * MED_SNAME_SIZE] = '\0';
+      //            }
+      //        }
+    }
+
+  // Chargement des coordonnées, numéros de familles et numéros de noeuds
+  if (dimensionMaillage == 3)
+    {
+      int i3 = 0;
+      for (int i = 0; i < nnoe; i++)
+        {
+          //          coo[i3] = X[i];
+          //          coo[i3 + 1] = Y[i];
+          //          coo[i3 + 2] = Z[i];
+          //          i3 = i3 + 3;
+          coo[i3] = *(XX + i);
+          coo[i3 + 1] = *(YY + i);
+          coo[i3 + 2] = *(ZZ + i);
+          i3 = i3 + 3;
+
+          // Numéros de familles  -  Le num. global de noeud est i+1
+          if (nGroupesNoeuds)
+            {
+              vector<int> v = ETIQUETTES_N[i];
+              string sv = (string) "";
+              for (unsigned int j = 0; j < v.size(); j++)
+                sv += int2string(v[j]); // Etiquette du noeud au format string
+              // cout << "Noeud " << i + 1 << " : sv=" << sv << endl;
+              *(nufano + i) = (med_int) NUMFAMETIQ[sv];
+            }
+          else
+            *(nufano + i) = (med_int) 0;
+
+          // Numéros de noeuds
+          // *(numnoe + i) = (med_int) NUM_NOEUDS[i];
+        }
+    }
+  else /* dimension 2 */
+    {
+      int i2 = 0;
+      for (int i = 0; i < nnoe; i++)
+        {
+          coo[i2] = *(XX + i);
+          coo[i2 + 1] = *(YY + i);
+          i2 = i2 + 2;
+          // Numéros de familles  -  Le num. global de noeud est i+1
+          if (nGroupesNoeuds)
+            {
+              vector<int> v = ETIQUETTES_N[i];
+              string sv = (string) "";
+              for (unsigned int j = 0; j < v.size(); j++)
+                sv += int2string(v[j]); // Etiquette du noeud au format string
+              // cout << "Noeud " << i + 1 << " : sv=" << sv << endl;
+              *(nufano + i) = (med_int) NUMFAMETIQ[sv];
+            }
+          else
+            *(nufano + i) = (med_int) 0;
+          // Numéros de noeuds
+          // *(numnoe + i) = (med_int) NUM_NOEUDS[i];
+        }
+    }
+
+  //   // Restitution coo
+  //  int i3 = 0;
+  //  for (int i = 0; i < nnoe; i++)
+  //    {
+  //      cout << "Noeud " << i << " : " << coo[i3] << " " << coo[i3 + 1] << " " << coo[i3 + 2] << endl;
+  //      i3 = i3 + 3;
+  //    }
+
+  if (MEDmeshNodeWr(fid, maa, MED_NO_DT, MED_NO_IT, MED_UNDEF_DT, MED_FULL_INTERLACE, nnoe, coo, inonoe, nomnoe,
+                    inunoe, numnoe, MED_TRUE, nufano) < 0)
+    {
+      ERREUR("Error MEDmeshNodeWr");
+      cout << "Error MEDmeshNodeWr" << endl;
+    }
+
+  // ########################################################################
+  //          GROUPES DE MAILLES
+  // ########################################################################
+
+  int nGroupesMailles = GM.size();
+
+  map<TYPE_MAILLE, vector<vector<int> > > ETIQUETTES_M; // [ tm => [ nl => [ig1, ig2, ... ] ] ]
+  // INDEX_M :
+  //  Clé :       tm
+  //  Valeur :    vect. des compteurs par indice de GM dans NOMS_GROUPES_MAILLES
+  map<TYPE_MAILLE, vector<unsigned int> > INDEX_M;
+  NOMSFAM.clear();
+  ETIQFAM.clear();
+  NUMFAMETIQ.clear(); //  clé = Ã©tiquette  -  valeur = numéros de familles
+  cptNOMFAM = 0;
+
+  if (nGroupesMailles)
+    {
+
+      // Pérennisation d'un ordre sur les GM dans le vecteur NOMS_GROUPES_MAILLES
+      vector<string> NOMS_GROUPES_MAILLES;
+      for (map<string, map<TYPE_MAILLE, vector<int> > >::iterator ITGM = GM.begin(); ITGM != GM.end(); ITGM++)
+        {
+          string nomGM = ITGM->first;
+          NOMS_GROUPES_MAILLES.push_back(nomGM);
+        }
+      NOMS_GROUPES_MAILLES.resize(GM.size());
+      // Tri des vecteurs d'entiers de GM
+      for (unsigned int ig = 0; ig < NOMS_GROUPES_MAILLES.size(); ig++)
+        {
+          string nomGM = NOMS_GROUPES_MAILLES[ig];
+          for (map<TYPE_MAILLE, vector<int> >::iterator I = GM[nomGM].begin(); I != GM[nomGM].end(); I++)
+            {
+              TYPE_MAILLE tm = I->first;
+              sort(GM[nomGM][tm].begin(), GM[nomGM][tm].end());
+            }
+        }
+
+      // Construction des Ã©tiquettes (familles)
+
+      // Initialisation 0 des index de groupes, et resize ETIQUETTES_M[tm]
+      for (int itm = (int) POI1; itm <= (int) HEXA20; itm++)
+        {
+          TYPE_MAILLE tm = (TYPE_MAILLE) itm;
+          if (EFFECTIFS_TYPES[tm])
+            {
+              for (unsigned int ig = 0; ig < NOMS_GROUPES_MAILLES.size(); ig++)
+                INDEX_M[tm].push_back(0);
+              ETIQUETTES_M[tm].resize(EFFECTIFS_TYPES[tm]);
+            }
+        }
+
+      for (int itm = (int) POI1; itm <= (int) HEXA20; itm++)
+        {
+          TYPE_MAILLE tm = (TYPE_MAILLE) itm;
+          int efftm = EFFECTIFS_TYPES[tm];
+          // cout << endl << "*************** coucou ***************" << endl;
+          // cout << "*************** Type " << TM2string(tm) << " effectif = " << efftm << endl;
+          if (efftm)
+            {
+              // cout << "Traitement du type " << TM2string(tm) << endl;
+              for (int nl = 0; nl < efftm; nl++)
+                {
+                  // nl = num. local de la maille dans son type
+                  // cout << "\tMaille " << TM2string(tm) << " n° " << nl << endl;
+
+                  int tailleEtiquette = 0;
+                  string etiq = (string) "";
+                  // Boucle sur les groupes
+                  for (unsigned int ig = 0; ig < NOMS_GROUPES_MAILLES.size(); ig++)
+                    {
+                      string nomGM = NOMS_GROUPES_MAILLES[ig];
+                      // cout << "\t\t" << "Groupe " << nomGM << endl;
+
+                      if (INDEX_M[tm][ig] < GM[nomGM][tm].size())
+                        {
+                          if (nl == GM[nomGM][tm][INDEX_M[tm][ig]])
+                            {
+                              // Attention: l'indice 0 dans le vecteur ETIQUETTES correspond
+                              // Ã  l'élément (noeud ou maille) de num. global 1
+                              // Par ailleurs, le numéro de groupe dans l'étiquette commence Ã  0
+                              // cout << "\t\t\t" << "La maille est dans le groupe " << nomGM << endl;
+                              ETIQUETTES_M[tm][nl].push_back(ig);
+                              tailleEtiquette++;
+                              etiq += int2string(ig);
+                              INDEX_M[tm][ig]++;
+                              // cout << "\t\t\t  OK" << endl;
+                            }
+                        }
+                    }
+
+                  ETIQUETTES_M[tm][nl].resize(tailleEtiquette);
+                  // Stockage de l'étiquette dans NOMSFAM ETIQFAM, si pas déjà stockée
+                  //                  bool trouve = false;
+                  //                  for (int i = 0; i < NOMSFAM.size(); i++)
+                  //                    if (NOMSFAM[i] == ((string) "ETIQUETTE_" + etiq))
+                  //                      {
+                  //                        trouve = true;
+                  //                        break;
+                  //                      }
+
+                  if (!NUMFAMETIQ[etiq] && etiq != (string) "")
+                    {
+                      NOMSFAM.push_back((string) "ETIQM_" + etiq);
+                      ETIQFAM.push_back(ETIQUETTES_M[tm][nl]);
+                      NUMFAMETIQ[etiq] = -cptNOMFAM - 1; // Famille de mailles, num<0
+                      cptNOMFAM++;
+                    }
+
+                }
+
+            } // if (efftm)
+        }
+
+      NOMSFAM.resize(cptNOMFAM);
+      ETIQFAM.resize(cptNOMFAM);
+
+      // Création des familles de mailles
+      for (unsigned int ifam = 0; ifam < NOMSFAM.size(); ifam++)
+        {
+          strcpy(nomfam, string2char(NOMSFAM[ifam]));
+          // Numéro de famille: -ifam-1 (négatif pour les mailles, et non nul)
+          numfam = -ifam - 1;
+          ngro = ETIQFAM[ifam].size();
+
+          // Noms des groupes de la famille
+          char* gro = new char[ngro * MED_LNAME_SIZE + 1];
+          int cptGM = 0;
+          for (unsigned int ign = 0; ign < ETIQFAM[ifam].size(); ign++)
+            {
+              string nomGMcourant = NOMS_GROUPES_MAILLES[ETIQFAM[ifam][ign]];
+              // ATTENTION! Il faut mettre Ã  la fin de chaque segment un \0 qui est ensuite Ã©crasé
+              // par le premier caractère du champ suivant dans le strcat !!!!
+              if (ign == 0)
+                {
+                  // Premier groupe
+                  strcpy(gro, string2char(nomGMcourant));
+                  for (int jg = nomGMcourant.size(); jg < MED_LNAME_SIZE; jg++)
+                    gro[jg] = ' ';
+                  gro[MED_LNAME_SIZE] = '\0';
+                }
+              else
+                {
+                  strcat(gro, string2char(nomGMcourant));
+                  for (int jg = nomGMcourant.size(); jg < MED_LNAME_SIZE; jg++)
+                    gro[cptGM * MED_LNAME_SIZE + jg] = ' ';
+                  gro[(cptGM + 1) * MED_LNAME_SIZE] = '\0';
+                }
+              cptGM++;
+            }
+
+          // Création de la famille
+          if (MEDfamilyCr(fid, maa, nomfam, numfam, 1, gro) < 0)
+            ERREUR("Error MEDfamilyCr");
+
+         delete gro;
+        }
+    }
+
+  // ########################################################################
+  //                                MAILLES
+  // ########################################################################
+  //               Appel de la routine ecritureTypeNew
+
+  med_bool inomTYPE = MED_FALSE;
+  med_bool inumTYPE = MED_FALSE;
+
+  med_geometry_type MGE;
+
+  for (int itm = (int) POI1; itm <= (int) HEXA20; itm++)
+    {
+      TYPE_MAILLE tm = (TYPE_MAILLE) itm;
+      if (EFFECTIFS_TYPES[tm])
+        {
+          nTYPE = EFFECTIFS_TYPES[tm];
+          tTYPE = Nnoeuds(tm);
+          MGE = InstanceMGE(tm);
+          stype = TM2string(tm);
+
+          // Noms des mailles
+          //          char *nomTYPE = (char*) malloc(MED_SNAME_SIZE * nTYPE + 1);
+          //          strcpy(nomTYPE, ""); // ATTENTION!
+
+          char *nomTYPE = (char*)""; // Attention! Ne pas faire strcpy !
+
+          //           for (int imaille = 0; imaille < IDS_MAILLES[tm].size(); imaille++)
+          //            {
+          //              string nomMaille = IDS_MAILLES[tm][imaille];
+          //              if (imaille == 0)
+          //                {
+          //                  // Premier groupe
+          //                  strcpy(nomTYPE, string2char(nomMaille));
+          //                  for (int jg = nomMaille.size(); jg < MED_SNAME_SIZE; jg++)
+          //                    nomTYPE[jg] = ' ';
+          //                  nomTYPE[MED_SNAME_SIZE] = '\0';
+          //                }
+          //              else
+          //                {
+          //                  strcat(nomTYPE, string2char(nomMaille));
+          //                  for (int jg = nomMaille.size(); jg < MED_SNAME_SIZE; jg++)
+          //                    nomTYPE[imaille * MED_SNAME_SIZE + jg] = ' ';
+          //                  nomTYPE[(imaille + 1) * MED_SNAME_SIZE] = '\0';
+          //                }
+          //            }
+
+          med_int *numTYPE = NULL; //  (med_int*) malloc(sizeof(med_int)*nTYPE);
+
+          med_int *famTYPE = (med_int*) malloc(sizeof(med_int) * nTYPE);
+
+          //          med_int *conTYPE = (med_int*) malloc(sizeof(med_int) * tTYPE * nTYPE);
+          //          for (int i = 0; i < nTYPE * tTYPE; i++)
+          //            *(conTYPE + i) = (med_int) CON[tm][i];
+
+          // Chargement famTYPE
+          if (nGroupesMailles)
+            {
+              // Boucle sur les mailles du type (indice = num. local)
+              for (int nl = 0; nl < nTYPE; nl++)
+                {
+                  // Construction de l'étiquette de la maille au format string
+                  vector<int> v = ETIQUETTES_M[tm][nl];
+                  string sv = (string) "";
+                  for (unsigned int j = 0; j < v.size(); j++)
+                    sv += int2string(v[j]);
+                  // Accès au num. de la famille
+                  *(famTYPE + nl) = (med_int) NUMFAMETIQ[sv];
+                } // Boucle sur les mailles du type
+            } // if (nGroupesMailles)
+          else
+            for (int nl = 0; nl < nTYPE; nl++)
+              *(famTYPE + nl) = (med_int) 0;
+
+          // Formatage MED des CNX
+          conversionCNX(CNX[tm], tm, nTYPE);
+
+          // Chargement numTYPE
+          //for (int nl=0; nl<nTYPE; nl++)    *(numTYPE+nl) = (med_int) ( NUM_MAILLES[tm][nl] );
+//          cerr << "maa=" << maa << endl;
+//          cerr << "MGE=" << MGE << endl;
+//          cerr << "nTYPE=" << nTYPE << endl;
+//          cerr << "inomTYPE=" << inomTYPE << endl;
+//          //cerr << "nomTYPE=" << nomTYPE << endl;
+//          cerr << "inumTYPE=" << inumTYPE << endl;
+//          this->afficheMailles(tm);
+          if (MEDmeshElementWr(fid, maa, MED_NO_DT, MED_NO_IT, MED_UNDEF_DT, MED_CELL, MGE, MED_NODAL,
+                               MED_FULL_INTERLACE, nTYPE, CNX[tm], inomTYPE, nomTYPE, inumTYPE, numTYPE, MED_FALSE,
+                               famTYPE) < 0)
+            {
+              ERREUR("Error MEDmeshElementWr");
+              cout << "Error MEDmeshElementWr, type " << stype << endl;
+            }
+          if (MEDmeshEntityFamilyNumberWr(fid, maa, MED_NO_DT, MED_NO_IT,
+                                          MED_CELL, MGE, nTYPE, famTYPE) < 0)
+            {
+              ERREUR("Error MEDmeshEntityFamilyNumberWr");
+              cout << "Error MEDmeshEntityFamilyNumberWr, type " << stype << endl;
+            }
+
+          // free(nomTYPE);
+          // free(numTYPE);
+          free(famTYPE);
+          // free(conTYPE);
+
+        } // Effectif non vide
+    }
+
+  // ########################################################################
+  //                            Fermeture du fichier MED
+  // ########################################################################
+
+  if (MEDfileClose(fid) < 0)
+    {
+      ERREUR("Error on close MED file\n");
+      cout << "Error on close MED file" << endl;
+    }
+
+  delete unicoo;
+  delete nomcoo;
+
+  // cout << endl << endl << "Fin procédure outputMED" << endl;
+} // outputMED
+
+
+int Maillage::NGLOBAL(TYPE_MAILLE typeMaille, int nlocal)
+{
+  // Attention, les num. globaux commencent Ã  1, les num. locaux Ã  0
+  int cpt = 1 + nlocal;
+  for (int itm = (int) POI1; itm < (int) typeMaille; itm++)
+    { // Attention! inférieur strict!
+      TYPE_MAILLE tm = (TYPE_MAILLE) itm;
+      cpt += EFFECTIFS_TYPES[tm];
+    }
+  return cpt;
+}
+
+TYPE_MAILLE Maillage::TYPE(int nglobal)
+{
+  // Attention, les num. globaux commencent Ã  1, les num. locaux Ã  0
+  TYPE_MAILLE resultat;
+  int cpt = 0;
+  for (int itm = (int) POI1; itm <= (int) HEXA20; itm++)
+    {
+      TYPE_MAILLE tm = (TYPE_MAILLE) itm;
+      cpt += EFFECTIFS_TYPES[tm];
+      if (nglobal <= cpt)
+        {
+          resultat = tm;
+          break;
+        }
+    }
+  return resultat;
+}
+
+int Maillage::NLOCAL(int nglobal, TYPE_MAILLE tm)
+{
+  // Attention, les num. globaux commencent Ã  1, les num. locaux Ã  0
+  int nPOI1 = EFFECTIFS_TYPES[POI1];
+  int nSEG2 = EFFECTIFS_TYPES[SEG2];
+  int nSEG3 = EFFECTIFS_TYPES[SEG3];
+  int nTRIA3 = EFFECTIFS_TYPES[TRIA3];
+  int nTRIA6 = EFFECTIFS_TYPES[TRIA6];
+  int nQUAD4 = EFFECTIFS_TYPES[QUAD4];
+  int nQUAD8 = EFFECTIFS_TYPES[QUAD8];
+  int nTETRA4 = EFFECTIFS_TYPES[TETRA4];
+  int nTETRA10 = EFFECTIFS_TYPES[TETRA10];
+  int nPYRAM5 = EFFECTIFS_TYPES[PYRAM5];
+  int nPYRAM13 = EFFECTIFS_TYPES[PYRAM13];
+  int nPENTA6 = EFFECTIFS_TYPES[PENTA6];
+  int nPENTA15 = EFFECTIFS_TYPES[PENTA15];
+  int nHEXA8 = EFFECTIFS_TYPES[HEXA8];
+  int nHEXA20 = EFFECTIFS_TYPES[HEXA20];
+
+  if (nglobal <= nPOI1)
+    {
+      return nglobal - 1;
+    }
+  else if (nglobal <= nPOI1 + nSEG2)
+    {
+      return nglobal - nPOI1 - 1;
+    }
+  else if (nglobal <= nPOI1 + nSEG2 + nSEG3)
+    {
+      return nglobal - nPOI1 - nSEG2 - 1;
+    }
+  else if (nglobal <= nPOI1 + nSEG2 + nSEG3 + nTRIA3)
+    {
+      return nglobal - nPOI1 - nSEG2 - nSEG3 - 1;
+    }
+  else if (nglobal <= nPOI1 + nSEG2 + nSEG3 + nTRIA3 + nTRIA6)
+    {
+      return nglobal - nPOI1 - nSEG2 - nSEG3 - nTRIA3 - 1;
+    }
+  else if (nglobal <= nPOI1 + nSEG2 + nSEG3 + nTRIA3 + nTRIA6 + nQUAD4)
+    {
+      return nglobal - nPOI1 - nSEG2 - nSEG3 - nTRIA3 - nTRIA6 - 1;
+    }
+  else if (nglobal <= nPOI1 + nSEG2 + nSEG3 + nTRIA3 + nTRIA6 + nQUAD4 + nQUAD8)
+    {
+      return nglobal - nPOI1 - nSEG2 - nSEG3 - nTRIA3 - nTRIA6 - nQUAD4 - 1;
+    }
+  else if (nglobal <= nPOI1 + nSEG2 + nSEG3 + nTRIA3 + nTRIA6 + nQUAD4 + nQUAD8 + nTETRA4)
+    {
+      return nglobal - nPOI1 - nSEG2 - nSEG3 - nTRIA3 - nTRIA6 - nQUAD4 - nQUAD8 - 1;
+    }
+  else if (nglobal <= nPOI1 + nSEG2 + nSEG3 + nTRIA3 + nTRIA6 + nQUAD4 + nQUAD8 + nTETRA4 + nTETRA10)
+    {
+      return nglobal - nPOI1 - nSEG2 - nSEG3 - nTRIA3 - nTRIA6 - nQUAD4 - nQUAD8 - nTETRA4 - 1;
+    }
+  else if (nglobal <= nPOI1 + nSEG2 + nSEG3 + nTRIA3 + nTRIA6 + nQUAD4 + nQUAD8 + nTETRA4 + nTETRA10 + nPYRAM5)
+    {
+      return nglobal - nPOI1 - nSEG2 - nSEG3 - nTRIA3 - nTRIA6 - nQUAD4 - nQUAD8 - nTETRA4 - nTETRA10 - 1;
+    }
+  else if (nglobal <= nPOI1 + nSEG2 + nSEG3 + nTRIA3 + nTRIA6 + nQUAD4 + nQUAD8 + nTETRA4 + nTETRA10 + nPYRAM5
+      + nPYRAM13)
+    {
+      return nglobal - nPOI1 - nSEG2 - nSEG3 - nTRIA3 - nTRIA6 - nQUAD4 - nQUAD8 - nTETRA4 - nTETRA10 - nPYRAM5 - 1;
+    }
+  else if (nglobal <= nPOI1 + nSEG2 + nSEG3 + nTRIA3 + nTRIA6 + nQUAD4 + nQUAD8 + nTETRA4 + nTETRA10 + nPYRAM5
+      + nPYRAM13 + nPENTA6)
+    {
+      return nglobal - nPOI1 - nSEG2 - nSEG3 - nTRIA3 - nTRIA6 - nQUAD4 - nQUAD8 - nTETRA4 - nTETRA10 - nPYRAM5
+          - nPYRAM13 - 1;
+    }
+  else if (nglobal <= nPOI1 + nSEG2 + nSEG3 + nTRIA3 + nTRIA6 + nQUAD4 + nQUAD8 + nTETRA4 + nTETRA10 + nPYRAM5
+      + nPYRAM13 + nPENTA6 + nPENTA15)
+    {
+      return nglobal - nPOI1 - nSEG2 - nSEG3 - nTRIA3 - nTRIA6 - nQUAD4 - nQUAD8 - nTETRA4 - nTETRA10 - nPYRAM5
+          - nPYRAM13 - nPENTA6 - 1;
+    }
+  else if (nglobal <= nPOI1 + nSEG2 + nSEG3 + nTRIA3 + nTRIA6 + nQUAD4 + nQUAD8 + nTETRA4 + nTETRA10 + nPYRAM5
+      + nPYRAM13 + nPENTA6 + nPENTA15 + nHEXA8)
+    {
+      return nglobal - nPOI1 - nSEG2 - nSEG3 - nTRIA3 - nTRIA6 - nQUAD4 - nQUAD8 - nTETRA4 - nTETRA10 - nPYRAM5
+          - nPYRAM13 - nPENTA6 - nPENTA15 - 1;
+    }
+  else if (nglobal <= nPOI1 + nSEG2 + nSEG3 + nTRIA3 + nTRIA6 + nQUAD4 + nQUAD8 + nTETRA4 + nTETRA10 + nPYRAM5
+      + nPYRAM13 + nPENTA6 + nPENTA15 + nHEXA8 + nHEXA20)
+    {
+      return nglobal - nPOI1 - nSEG2 - nSEG3 - nTRIA3 - nTRIA6 - nQUAD4 - nQUAD8 - nTETRA4 - nTETRA10 - nPYRAM5
+          - nPYRAM13 - nPENTA6 - nPENTA15 - nHEXA8 - 1;
+    }
+  else
+    ERREUR("method NLOCAL: unknown type");
+  return 0;
+}
+
+/*!
+ *  Suppression de mailles dans un type :
+ *
+ *  - Contraction de la connectivité concernée
+ *  - Réécriture des GM avec les nouveaux numéros locaux des Ã©léments du type concerné
+ *  - Mise Ã  jour nombreMaillesMaillage
+ *
+ *  Les noeuds ne sont pas affectés.
+ */
+void Maillage::eliminationMailles(TYPE_MAILLE tm, vector<int> listeMaillesSuppr)
+{
+  map<int, int> TABLE_NL; // Table des num. locaux dans le type tm
+
+  cout << "Method eliminationMailles, listeMaillesSuppr.size()=" << listeMaillesSuppr.size() << endl;
+
+  // ************* Modification de la connectivité du type concerné
+
+  int* CNX2;
+  int nNoeudsType = Nnoeuds(tm);
+  int tailleCNX2 = nNoeudsType * (EFFECTIFS_TYPES[tm] - listeMaillesSuppr.size());
+  CNX2 = (int*) malloc(sizeof(int) * tailleCNX2);
+  // Recopie sélective des connectivités
+  int isuppr = 0; // indice dans listeMaillesSuppr
+  int ih2 = 0; // nouveau numéro local ( remarque: ih2 = ih1 - isuppr )
+  for (int ih1 = 0; ih1 < EFFECTIFS_TYPES[tm]; ih1++)
+    {
+      if (listeMaillesSuppr[isuppr] != ih1)
+        {
+          for (int jh1 = 0; jh1 < nNoeudsType; jh1++)
+            *(CNX2 + nNoeudsType * ih2 + jh1) = *(CNX[tm] + nNoeudsType * ih1 + jh1);
+          ih2++;
+        }
+      else
+        isuppr++;
+    }
+  free(CNX[tm]);
+  CNX[tm] = CNX2;
+
+  // ************* Construction de la table de correspondance des NL dans le type concerné
+  unsigned int offset = 0;
+  for (int i = 0; i < EFFECTIFS_TYPES[tm]; i++)
+    {
+      if (offset < listeMaillesSuppr.size())
+        {
+          if (i < listeMaillesSuppr[offset])
+            TABLE_NL[i] = i - offset;
+          else if (i == listeMaillesSuppr[offset])
+            {
+              TABLE_NL[i] = -1; // Element Ã  supprimer
+              offset++;
+            }
+        }
+      else
+        TABLE_NL[i] = i - offset;
+    }
+
+  // Contrôle
+  if (offset != listeMaillesSuppr.size())
+    {
+      ERREUR("Incoherent offset, method eliminationMailles");
+      exit(0);
+    }
+
+  // ************* Mise Ã  jour du type concerné dans les GM
+  for (map<string, map<TYPE_MAILLE, vector<int> > >::iterator I = GM.begin(); I != GM.end(); I++)
+    {
+      string nomGM = I->first;
+
+      if (GM[nomGM][tm].size())
+        {
+          //cout << "GM[" << nomGM <<"][" << tm << "].size()=" << GM[nomGM][tm].size() << endl;
+          vector<int> mailles = GM[nomGM][tm];
+          vector<int> mailles2; //mailles2.resize(mailles.size()-listeMaillesSuppr.size());
+          unsigned int cptMailles = 0;
+          for (unsigned int i = 0; i < mailles.size(); i++)
+            {
+              int nl2 = TABLE_NL[mailles[i]];
+              if (nl2 != -1)
+                {
+                  mailles2.push_back(nl2);
+                  cptMailles++;
+                }
+            }
+
+          GM[nomGM][tm].clear();
+          mailles2.resize(cptMailles);
+          GM[nomGM][tm] = mailles2;
+
+        }
+    }
+
+  // ************* Mise Ã  jour des effectifs
+
+  EFFECTIFS_TYPES[tm] = EFFECTIFS_TYPES[tm] - listeMaillesSuppr.size();
+  nombreMaillesMaillage = nombreMaillesMaillage - listeMaillesSuppr.size();
+
+  TABLE_NL.clear();
+}
+
diff --git a/src/Tools/MeshCut/MeshCut_Maillage.hxx b/src/Tools/MeshCut/MeshCut_Maillage.hxx
new file mode 100644 (file)
index 0000000..06dbc5c
--- /dev/null
@@ -0,0 +1,165 @@
+// Copyright (C) 2006-2012  EDF R&D
+//
+// 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.com
+//
+
+#ifndef __MESHCUT_MAILLAGE_HXX__
+#define __MESHCUT_MAILLAGE_HXX__
+
+#include "MeshCut_Utils.hxx"
+
+#include <string>
+#include <vector>
+#include <map>
+
+namespace MESHCUT
+  {
+    class Maillage
+    {
+    public:
+      // Toutes ces variables doivent Ãªtre placées au niveau du principal pour Ãªtre connues de toutes les fonctions
+
+      // Vecteurs des familles d'éléments
+      std::map<int, std::vector<int> > FAMILLES;
+      std::map<int, std::vector<TYPE_MAILLE> > FAM_TYPES;
+
+      // Vecteurs des familles de noeuds
+      std::map<int, std::vector<int> > FAMILLES_NOEUDS;
+
+      // Description des groupes (par familles)
+      std::map<std::string, std::vector<int> > GROUPES_MAILLES;
+      std::map<std::string, std::vector<int> > GROUPES_NOEUDS;
+
+      // Commun noeuds et mailles
+      std::map<int, int> tailleFAMILLES; // la clé est un num. de famille
+      std::map<std::string, int> tailleGROUPES; // Tailles des vecteurs GROUPES_MAILLES et GROUPES_NOEUDS - la clé est un nom de groupe (de noeuds ou de mailles)
+
+      // Résidus mailles
+      std::map<TYPE_MAILLE, std::vector<int> > RESIDU;
+
+    public:
+      std::string ID;
+      int nombreNoeudsMaillage; // ****** MED-OBLIGATOIRE ******
+      int nombreMaillesMaillage; // ****** MED-OBLIGATOIRE ******
+
+      class Cube *enveloppeMaillage;
+
+      int dimensionMaillage; // ****** MED-OBLIGATOIRE ******
+      int dimensionEspace; // ****** MED-OBLIGATOIRE ******
+
+      char axisname[3*MED_SNAME_SIZE+1]; // ****** MED-OBLIGATOIRE ******
+      char unitname[3*MED_SNAME_SIZE+1]; // ****** MED-OBLIGATOIRE ******
+
+      float *XX;
+      float *YY;
+      float *ZZ; // ****** MED-OBLIGATOIRE ******
+
+      // Effectifs des Ã©léments par type
+      std::map<TYPE_MAILLE, int> EFFECTIFS_TYPES; // ****** MED-OBLIGATOIRE ******
+
+      // Connectivités des types
+      // Le numéro global du j-ième noeud de la maille de numéro global i est stocké Ã  l'adresse
+      //           CNX[tm]+t*(i-1)+(j-1)
+      // (t = taille du type, i.e. nombre de noeuds de l'élément)
+      std::map<TYPE_MAILLE, int*> CNX; // ****** MED-OBLIGATOIRE ******
+
+      // Enveloppes cubiques
+      std::map<TYPE_MAILLE, float*> EC;
+
+      // Description des groupes
+      std::map<std::string, std::map<TYPE_MAILLE, std::vector<int> > > GM;
+      std::map<std::string, std::vector<int> > GN;
+
+      //  std::vector<std::string> IDS_NOEUDS; // Indice = num. global - 1
+      //  std::map<TYPE_MAILLE, std::vector<std::string> > IDS_MAILLES; // Indice = num local de maille dans le type
+      //
+      //  std::vector<int> NUM_NOEUDS; // Indice = num. global - 1
+      //  std::map<TYPE_MAILLE, std::vector<int> > NUM_MAILLES; // Indice = num local de maille dans le type
+
+      Maillage(std::string _ID);
+      virtual ~Maillage();
+
+      void creationGMtype(TYPE_MAILLE tm, std::string nomGMtype);
+      void afficheMailles(TYPE_MAILLE tm);
+      void listeMaillesType(TYPE_MAILLE tm);
+      void listeMaillesTousTypes();
+      void listeMaillesParGM();
+      void listeMaillesGM(std::string nomGM);
+      // void listeMaillesGMordonne(std::string nomGM);
+      void listeNoeuds();
+      void listeNoeudsGN(std::string nomGN);
+      void listeNoeudsGNordonne(std::string nomGN);
+      std::vector<float> G(int i, TYPE_MAILLE tm);
+      float distanceNoeudMaille(int ngnoeud, int imaille, TYPE_MAILLE tm);
+      int noeudVoisin(int ngnoeud, int imaille, TYPE_MAILLE tm);
+      float distanceNoeudNoeud(int ng1, int ng2);
+      //  void encombrements()
+
+      void inputMED(std::string fichierMED);
+      void outputMED(std::string fichierMED);
+      void outputMEDold(std::string fichierMED);
+
+      void inputHL(std::string fichierHL /*, std::string ficDICnoeuds, std::string ficDICmailles, bool DICO */);
+      void outputHL(std::string fichierHL);
+
+      void outputVRML(std::string ficVRML, float rNoeuds, char *renduAretes, char *renduFaces, float transparence);
+      // std::string vrmlType(TYPE_MAILLE tm, char *renduAretes, char *renduFaces, float transparence);
+      // void Maillage::creationGMtype(TYPE_MAILLE tm, std::vector<int> CON_TYPE);
+      int NGLOBAL(TYPE_MAILLE typeMaille, int nlocal);
+      int NLOCAL(int nglobal, TYPE_MAILLE tm);
+      TYPE_MAILLE TYPE(int nglobal);
+      void eliminationMailles(TYPE_MAILLE typeMaille, std::vector<int> listeMaillesSuppr);
+
+      // acquisitionTYPE_inputMED appelée par inputMED
+      void
+          acquisitionTYPE_inputMED(TYPE_MAILLE TYPE, int nTYPE, med_idt fid, char maa[MED_NAME_SIZE + 1], med_int mdim);
+
+      // void infoChamps(std::string type, med_entity_type MEM, med_geometry_type MGE, med_idt fid, char *maa,
+      //                 char *nomChamp, med_field_type typeChamp, med_int nCompChamp, std::map<std::string, int> REFGAUSS);
+
+      bool NoeudDansHEXA8(int n, int n0, int n1, int n2, int n3, int n4, int n5, int n6, int n7, float epsilon);
+      bool NoeudDansPENTA6(int n, int n0, int n1, int n2, int n3, int n4, int n5, float epsilon);
+      bool NoeudDansPYRAM5(int n, int n0, int n1, int n2, int n3, int n4, float epsilon);
+      bool NoeudDansTETRA4(int n, int n1, int n2, int n3, int n4, float epsilon);
+      bool NoeudDansQUAD4(int n, int n1, int n2, int n3, int n4, float epsilon);
+      bool NoeudDansTRIA3(int n, int n1, int n2, int n3, float epsilon);
+      double volumeTETRA(int n1, int n2, int n3, int n4);
+      double aireTRIA(int n1, int n2, int n3);
+      double DET3(int n1, int n2, int n3);
+      double DET2(int n1, int n2);
+      void * chargeEnveloppesCubiques(TYPE_MAILLE tm);
+      void * chargeEnveloppesCarrees(TYPE_MAILLE tm);
+      bool noeudDeMaille(int ngnoeud, int i, TYPE_MAILLE tm);
+      bool NoeudDansMaille3D(int n, int i, TYPE_MAILLE tm, float epsilon);
+      bool NoeudDansMaille2D(int n, int i, TYPE_MAILLE tm, float epsilon);
+      bool NoeudDansEnveloppeMaille2D(int n, int i, TYPE_MAILLE tm, float epsilon);
+      bool NoeudDansEnveloppeMaille3D(int n, int i, TYPE_MAILLE tm, float epsilon);
+      void * afficheEnveloppesCubiques(TYPE_MAILLE tm);
+      void * afficheEnveloppesCarrees(TYPE_MAILLE tm);
+
+      std::vector<int> noeudsGeomCommuns(int i1, TYPE_MAILLE tm1, int i2, TYPE_MAILLE tm2);
+      void creationGMresidu();
+
+      float longueurMoyenne();
+      // void Maillage::infoChamps2(std::string type, med_entity_type MEM, med_geometry_type MGE, med_idt fid,
+      //                            char *maa, char *nomChamp, med_field_type typeChamp, med_int nCompChamp, map<string,
+      //                            int> REFGAUSS);
+
+    };
+  }
+
+#endif
diff --git a/src/Tools/MeshCut/MeshCut_Utils.cxx b/src/Tools/MeshCut/MeshCut_Utils.cxx
new file mode 100644 (file)
index 0000000..e7cf9e0
--- /dev/null
@@ -0,0 +1,1104 @@
+// Copyright (C) 2006-2012  EDF R&D
+//
+// 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.com
+//
+
+#include "MeshCut_Utils.hxx"
+
+#include <iostream>
+#include <string>
+#include <sstream>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+
+using namespace std;
+using namespace MESHCUT;
+
+//string pathUsers = (string) "/var/www/XMeshLab/users/";
+
+bool MESHCUT::estUnTypeMaille(std::string S)
+{
+  if (S == (string) "POI1" || S == (string) "SEG2" || S == (string) "SEG3" || S == (string) "TRIA3" || S
+      == (string) "TRIA6" || S == (string) "QUAD4" || S == (string) "QUAD8" || S == (string) "QUAD9" || S
+      == (string) "TETRA4" || S == (string) "TETRA10" || S == (string) "PYRAM5" || S == (string) "PYRAM13" || S
+      == (string) "PENTA6" || S == (string) "PENTA15" || S == (string) "HEXA8" || S == (string) "HEXA20" || S
+      == (string) "HEXA27")
+    return true;
+  else
+    return false;
+}
+
+void MESHCUT::ERREUR(const char* msg)
+{
+  cout << endl << "====== ERROR ====== " << msg << endl << endl;
+  exit(-1);
+}
+
+char* MESHCUT::string2char(std::string str)
+{
+  // créer le buffer pour copier la chaîne
+  size_t size = str.size() + 1;
+  char* buffer = new char[size];
+  // copier la chaîne
+  strncpy(buffer, str.c_str(), size);
+
+  // libérer la mémoire
+  //delete [] buffer;
+
+  return buffer;
+}
+
+std::string MESHCUT::int2string(int k)
+{
+  std::stringstream oss;
+  oss << k;
+  return oss.str(); //  oss.seekp (ios_base::beg);
+}
+
+float MESHCUT::char2float(const char* ch)
+{
+  return atof(ch);
+}
+
+std::string MESHCUT::float2string(float f)
+{
+  stringstream buf;
+  buf << fixed << f;
+  string s = buf.str();
+  return s;
+}
+
+bool MESHCUT::appartient(std::string e, std::string tableau[], int taille)
+{
+  for (int i = 0; i < taille; i++)
+    if (tableau[i] == e)
+      return true;
+  return false;
+}
+
+float MESHCUT::arrondi(float x)
+{
+  if (x > 0 && x < 1.0e-5)
+    return 0;
+  else if (x < 0 && x > -1.0e-5)
+    return 0;
+  else
+    return x;
+}
+
+int MESHCUT::numNoeudPointe(std::string b1, std::string b2, std::string b3)
+{
+  if (b1 == "1" && b2 == "1" && b3 == "2")
+    return 2;
+  else if (b1 == "1" && b2 == "2" && b3 == "1")
+    return 1;
+  else if (b1 == "1" && b2 == "2" && b3 == "2")
+    return 2;
+  else if (b1 == "2" && b2 == "1" && b3 == "1")
+    return 3;
+  else if (b1 == "2" && b2 == "1" && b3 == "2")
+    return 3;
+  else if (b1 == "2" && b2 == "2" && b3 == "1")
+    return 1;
+  else
+    return -1;
+}
+
+std::string MESHCUT::strip(std::string S)
+{
+  if (S.empty())
+    return S;
+  int startIndex = S.find_first_not_of(" ");
+  int endIndex = S.find_last_not_of(" ");
+  return S.substr(startIndex, (endIndex - startIndex + 1));
+}
+
+std::string MESHCUT::entierSur10_g(int i)
+{
+  if (i > 999999999)
+    ERREUR("trying to write a number superior to 999999999 on more than 10 chars");
+  if (i < 10)
+    return int2string(i) + (string) "         ";
+  else if (i < 100)
+    return int2string(i) + (string) "        ";
+  else if (i < 1000)
+    return int2string(i) + (string) "       ";
+  else if (i < 10000)
+    return int2string(i) + (string) "      ";
+  else if (i < 100000)
+    return int2string(i) + (string) "     ";
+  else if (i < 1000000)
+    return int2string(i) + (string) "    ";
+  else if (i < 10000000)
+    return int2string(i) + (string) "   ";
+  else if (i < 100000000)
+    return int2string(i) + (string) "  ";
+  else if (i < 1000000000)
+    return int2string(i) + (string) " ";
+  else
+    return int2string(i);
+}
+
+std::string MESHCUT::entierSur10_d(int i)
+{
+  if (i > 999999999)
+    ERREUR("trying to write a number superior to 999999999 on more than 10 chars");
+  if (i < 10)
+    return (string) "         " + int2string(i);
+  else if (i < 100)
+    return (string) "        " + int2string(i);
+  else if (i < 1000)
+    return (string) "       " + int2string(i);
+  else if (i < 10000)
+    return (string) "      " + int2string(i);
+  else if (i < 100000)
+    return (string) "     " + int2string(i);
+  else if (i < 1000000)
+    return (string) "    " + int2string(i);
+  else if (i < 10000000)
+    return (string) "   " + int2string(i);
+  else if (i < 100000000)
+    return (string) "  " + int2string(i);
+  else if (i < 1000000000)
+    return (string) " " + int2string(i);
+  else
+    return int2string(i);
+}
+
+std::string MESHCUT::typeEnsight(std::string type)
+{
+  if (type == (string) "POI1")
+    return (string) "point";
+  else if (type == (string) "SEG2")
+    return (string) "bar2";
+  else if (type == (string) "SEG3")
+    return (string) "bar2";// ATTENTION, triche!
+  else if (type == (string) "TRIA3")
+    return (string) "tria3";
+  else if (type == (string) "TRIA6")
+    return (string) "tria3";// ATTENTION, triche!
+  else if (type == (string) "QUAD4")
+    return (string) "quad4";
+  else if (type == (string) "QUAD8")
+    return (string) "quad4"; // ATTENTION, triche!
+  else if (type == (string) "QUAD9")
+    ERREUR("Type QUAD9 not supported by Ensight");
+  else if (type == (string) "TETRA4")
+    return (string) "tetra4";
+  else if (type == (string) "TETRA10")
+    return (string) "tetra4"; // ATTENTION, triche!
+  else if (type == (string) "PYRAM5")
+    return (string) "pyramid5";
+  else if (type == (string) "PYRAM13")
+    return (string) "pyramid5"; // ATTENTION, triche!
+  else if (type == (string) "PENTA6")
+    return (string) "penta6";
+  else if (type == (string) "PENTA15")
+    return (string) "penta6"; // ATTENTION, triche!
+  else if (type == (string) "HEXA8")
+    return (string) "hexa8";
+  else if (type == (string) "HEXA20")
+    return (string) "hexa8"; // ATTENTION, triche!
+  else if (type == (string) "HEXA27")
+    ERREUR("Type HEXA27 not supported by Ensight");
+  else
+    ERREUR("Type of element not accepted (method \"typeEnsight\"");
+  return (string) "";
+}
+
+int MESHCUT::Nnoeuds(TYPE_MAILLE type)
+{
+  switch (type)
+  {
+    case POI1:
+      {
+        return 1;
+        break;
+      }
+    case SEG2:
+      {
+        return 2;
+        break;
+      }
+    case SEG3:
+      {
+        return 3;
+        break;
+      }
+    case TRIA3:
+      {
+        return 3;
+        break;
+      }
+    case TRIA6:
+      {
+        return 6;
+        break;
+      }
+    case QUAD4:
+      {
+        return 4;
+        break;
+      }
+    case QUAD8:
+      {
+        return 8;
+        break;
+      }
+      //case QUAD9:                   { return 9; break; }
+    case TETRA4:
+      {
+        return 4;
+        break;
+      }
+    case TETRA10:
+      {
+        return 10;
+        break;
+      }
+    case PYRAM5:
+      {
+        return 5;
+        break;
+      }
+    case PYRAM13:
+      {
+        return 13;
+        break;
+      }
+    case PENTA6:
+      {
+        return 6;
+        break;
+      }
+    case PENTA15:
+      {
+        return 15;
+        break;
+      }
+    case HEXA8:
+      {
+        return 8;
+        break;
+      }
+    case HEXA20:
+      {
+        return 20;
+        break;
+      }
+      //case HEXA27:                      { return 27;    break; }
+    default:
+      ERREUR("Type of elem not accepted (method Nnoeuds)");
+  }
+  return 0;
+}
+
+int MESHCUT::NnoeudsGeom(TYPE_MAILLE type)
+{
+  switch (type)
+  {
+    case POI1:
+      {
+        return 1;
+        break;
+      }
+    case SEG2:
+      {
+        return 2;
+        break;
+      }
+    case SEG3:
+      {
+        return 2;
+        break;
+      }
+    case TRIA3:
+      {
+        return 3;
+        break;
+      }
+    case TRIA6:
+      {
+        return 3;
+        break;
+      }
+    case QUAD4:
+      {
+        return 4;
+        break;
+      }
+    case QUAD8:
+      {
+        return 4;
+        break;
+      }
+      //case QUAD9:                   { return 9; break; }
+    case TETRA4:
+      {
+        return 4;
+        break;
+      }
+    case TETRA10:
+      {
+        return 4;
+        break;
+      }
+    case PYRAM5:
+      {
+        return 5;
+        break;
+      }
+    case PYRAM13:
+      {
+        return 5;
+        break;
+      }
+    case PENTA6:
+      {
+        return 6;
+        break;
+      }
+    case PENTA15:
+      {
+        return 6;
+        break;
+      }
+    case HEXA8:
+      {
+        return 8;
+        break;
+      }
+    case HEXA20:
+      {
+        return 8;
+        break;
+      }
+      //case HEXA27:                      { return 27;    break; }
+    default:
+      ERREUR("Type of elem not accepted (method NnoeudsGeom)");
+  }
+  return 0;
+}
+
+int MESHCUT::codeGMSH(std::string type)
+{
+  if (type == (string) "POI1")
+    ERREUR("POI1 not taken into account by GMSH");
+  else if (type == (string) "SEG2")
+    return 1;
+  else if (type == (string) "SEG3")
+    return 8;
+  else if (type == (string) "TRIA3")
+    return 2;
+  else if (type == (string) "TRIA6")
+    return 9;
+  else if (type == (string) "QUAD4")
+    return 3;
+  else if (type == (string) "QUAD8")
+    return 16;
+  else if (type == (string) "QUAD9")
+    return 10;
+  else if (type == (string) "TETRA4")
+    return 4;
+  else if (type == (string) "TETRA10")
+    return 11;
+  else if (type == (string) "PYRAM5")
+    return 7;
+  else if (type == (string) "PENTA6")
+    return 6;
+  else if (type == (string) "PENTA15")
+    return 18;
+  else if (type == (string) "HEXA8")
+    return 5;
+  else if (type == (string) "HEXA20")
+    return 17;
+  else if (type == (string) "HEXA27")
+    return 12;
+  else
+    ERREUR("Type of elem not accepted (method codeGMSH)");
+  return 0;
+}
+
+std::string MESHCUT::floatEnsight(float x)
+{
+  char buf[12];
+  string s;
+  if (x < 0.0)
+    sprintf(buf, "%1.5E", x);
+  else
+    sprintf(buf, " %1.5E", x);
+  s = (string) buf;
+  s.erase(10, 1);
+  return s;
+}
+
+bool MESHCUT::typeComplexe(std::string type)
+{
+  if (type == (string) "SEG3")
+    return true;
+  else if (type == (string) "TRIA6")
+    return true;
+  else if (type == (string) "QUAD8")
+    return true;
+  else if (type == (string) "QUAD9")
+    return true;
+  else if (type == (string) "TETRA10")
+    return true;
+  else if (type == (string) "PYRAM13")
+    return true;
+  else if (type == (string) "PENTA15")
+    return true;
+  else if (type == (string) "HEXA20")
+    return true;
+  else if (type == (string) "HEXA27")
+    return true;
+  else
+    return false;
+}
+
+std::string MESHCUT::ASTER8(std::string s)
+{
+  if (s.size() == 0)
+    return (s + (string) "        ");
+  else if (s.size() == 1)
+    return (s + (string) "       ");
+  else if (s.size() == 2)
+    return (s + (string) "      ");
+  else if (s.size() == 3)
+    return (s + (string) "     ");
+  else if (s.size() == 4)
+    return (s + (string) "    ");
+  else if (s.size() == 5)
+    return (s + (string) "   ");
+  else if (s.size() == 6)
+    return (s + (string) "  ");
+  else if (s.size() == 7)
+    return (s + (string) " ");
+  else if (s.size() == 8)
+    return (s);
+  else
+    ERREUR("More than 8 char for an ASTER string");
+  return (s);
+}
+
+/*!
+ *  Distance Ã  laquelle doit se tenir l'observateur sur un axe
+ *  pour voir sous 90° un objet centré de dimensions a et b selon les deux autres axes.
+ *  Si on ne tient pas compte de la dimension de l'objet selon l'axe choisi,
+ *  la formule d_obs=max(a,b)/2 donne la cote
+ *  qui permet de voir l'objet plat dans un angle de 90°.
+ *  A cela il faut ajouter la dimension de l'objet selon l'axe d'observation = c.
+ *
+ *  @param a dimensions de l'objet selon un des axes normal Ã  l'axe d'observation
+ *  @param b dimensions de l'objet selon l'autre axe normal Ã  l'axe d'observation
+ *  @param c est la dimension de l'objet selon l'axe d'observation
+ */
+float MESHCUT::dObservateur(float a, float b, float c)
+{
+  return (max(a, b) / 2.0 + c);
+}
+
+int MESHCUT::copieFichier(std::string source, std::string cible)
+{
+  FILE *fsource, *fcible;
+  char buffer[512];
+  int NbLu;
+  if ((fsource = fopen(string2char(source), "rb")) == NULL)
+    return -1;
+  if ((fcible = fopen(string2char(cible), "wb")) == NULL)
+    {
+      fclose(fsource);
+      return -2;
+    }
+  while ((NbLu = fread(buffer, 1, 512, fsource)) != 0)
+    fwrite(buffer, 1, NbLu, fcible);
+  fclose(fcible);
+  fclose(fsource);
+  return 0;
+}
+
+med_geometry_type MESHCUT::InstanceMGE(TYPE_MAILLE TYPE)
+{
+  med_geometry_type typeBanaliseMED;
+
+  switch (TYPE)
+  {
+    case POI1:
+      typeBanaliseMED = MED_POINT1;
+      break; // Attention, piège !
+    case SEG2:
+      typeBanaliseMED = MED_SEG2;
+      break;
+    case SEG3:
+      typeBanaliseMED = MED_SEG3;
+      break;
+    case TRIA3:
+      typeBanaliseMED = MED_TRIA3;
+      break;
+    case TRIA6:
+      typeBanaliseMED = MED_TRIA6;
+      break;
+    case QUAD4:
+      typeBanaliseMED = MED_QUAD4;
+      break;
+    case QUAD8:
+      typeBanaliseMED = MED_QUAD8;
+      break;
+    case TETRA4:
+      typeBanaliseMED = MED_TETRA4;
+      break;
+    case TETRA10:
+      typeBanaliseMED = MED_TETRA10;
+      break;
+    case PYRAM5:
+      typeBanaliseMED = MED_PYRA5;
+      break; // Attention, piège !
+    case PYRAM13:
+      typeBanaliseMED = MED_PYRA13;
+      break; // Attention, piège !
+    case PENTA6:
+      typeBanaliseMED = MED_PENTA6;
+      break;
+    case PENTA15:
+      typeBanaliseMED = MED_PENTA15;
+      break;
+    case HEXA8:
+      typeBanaliseMED = MED_HEXA8;
+      break;
+    case HEXA20:
+      typeBanaliseMED = MED_HEXA20;
+      break;
+    default:
+      ERREUR("Method InstanceMGE, unknown type ");
+  }
+  return typeBanaliseMED;
+}
+
+int MESHCUT::chrono()
+{
+  return clock() / CLOCKS_PER_SEC;
+}
+
+TYPE_MAILLE MESHCUT::typeMaille(std::string type)
+{
+  if (type == (string) "POI1")
+    return POI1;
+  else if (type == (string) "SEG2")
+    return SEG2;
+  else if (type == (string) "SEG3")
+    return SEG3;
+  else if (type == (string) "TRIA3")
+    return TRIA3;
+  else if (type == (string) "TRIA6")
+    return TRIA6;
+  else if (type == (string) "QUAD4")
+    return QUAD4;
+  else if (type == (string) "QUAD8")
+    return QUAD8;
+  else if (type == (string) "TETRA4")
+    return TETRA4;
+  else if (type == (string) "TETRA10")
+    return TETRA10;
+  else if (type == (string) "PYRAM5")
+    return PYRAM5;
+  else if (type == (string) "PYRAM13")
+    return PYRAM13;
+  else if (type == (string) "PENTA6")
+    return PENTA6;
+  else if (type == (string) "PENTA15")
+    return PENTA15;
+  else if (type == (string) "HEXA8")
+    return HEXA8;
+  else if (type == (string) "HEXA20")
+    return HEXA20;
+  else
+    ERREUR("ERROR method typeMaille, unknown type");
+  return POI1;
+}
+
+std::string MESHCUT::MGE2string(med_geometry_type MGE)
+{
+  if (MGE == MED_NONE)
+    return (string) "NOEUD";
+  else if (MGE == MED_POINT1)
+    return (string) "POI1";
+  else if (MGE == MED_SEG2)
+    return (string) "SEG2";
+  else if (MGE == MED_SEG3)
+    return (string) "SEG3";
+  else if (MGE == MED_TRIA3)
+    return (string) "TRIA3";
+  else if (MGE == MED_TRIA6)
+    return (string) "TRIA6";
+  else if (MGE == MED_QUAD4)
+    return (string) "QUAD4";
+  else if (MGE == MED_QUAD8)
+    return (string) "QUAD8";
+  else if (MGE == MED_TETRA4)
+    return (string) "TETRA4";
+  else if (MGE == MED_TETRA10)
+    return (string) "TETRA10";
+  else if (MGE == MED_PYRA5)
+    return (string) "PYRAM5";
+  else if (MGE == MED_PYRA13)
+    return (string) "PYRAM13";
+  else if (MGE == MED_PENTA6)
+    return (string) "PENTA6";
+  else if (MGE == MED_PENTA15)
+    return (string) "PENTA15";
+  else if (MGE == MED_HEXA8)
+    return (string) "HEXA8";
+  else if (MGE == MED_HEXA20)
+    return (string) "HEXA20";
+  else
+    ERREUR("ERROR method MGE2string, unknown type");
+  return (string) "NOEUD";
+}
+
+std::string MESHCUT::TM2string(TYPE_MAILLE MGE)
+{
+  if (MGE == POI1)
+    return (string) "POI1";
+  else if (MGE == SEG2)
+    return (string) "SEG2";
+  else if (MGE == SEG3)
+    return (string) "SEG3";
+  else if (MGE == TRIA3)
+    return (string) "TRIA3";
+  else if (MGE == TRIA6)
+    return (string) "TRIA6";
+  else if (MGE == QUAD4)
+    return (string) "QUAD4";
+  else if (MGE == QUAD8)
+    return (string) "QUAD8";
+  else if (MGE == TETRA4)
+    return (string) "TETRA4";
+  else if (MGE == TETRA10)
+    return (string) "TETRA10";
+  else if (MGE == PYRAM5)
+    return (string) "PYRAM5";
+  else if (MGE == PYRAM13)
+    return (string) "PYRAM13";
+  else if (MGE == PENTA6)
+    return (string) "PENTA6";
+  else if (MGE == PENTA15)
+    return (string) "PENTA15";
+  else if (MGE == HEXA8)
+    return (string) "HEXA8";
+  else if (MGE == HEXA20)
+    return (string) "HEXA20";
+  else
+    ERREUR("ERROR method TM2string, unknown type");
+  return (string) "POI1";
+}
+
+TYPE_MAILLE MESHCUT::string2TM(std::string stm)
+{
+  if (stm == (string) "POI1")
+    return POI1;
+  else if (stm == (string) "SEG2")
+    return SEG2;
+  else if (stm == (string) "SEG3")
+    return SEG3;
+  else if (stm == (string) "TRIA3")
+    return TRIA3;
+  else if (stm == (string) "TRIA6")
+    return TRIA6;
+  else if (stm == (string) "QUAD4")
+    return QUAD4;
+  else if (stm == (string) "QUAD8")
+    return QUAD8;
+  else if (stm == (string) "TETRA4")
+    return TETRA4;
+  else if (stm == (string) "TETRA10")
+    return TETRA10;
+  else if (stm == (string) "PYRAM5")
+    return PYRAM5;
+  else if (stm == (string) "PYRAM13")
+    return PYRAM13;
+  else if (stm == (string) "PENTA6")
+    return PENTA6;
+  else if (stm == (string) "PENTA15")
+    return PENTA15;
+  else if (stm == (string) "HEXA8")
+    return HEXA8;
+  else if (stm == (string) "HEXA20")
+    return HEXA20;
+  else
+    ERREUR("ERROR method string2TM, unknown type");
+  return POI1;
+}
+
+std::string MESHCUT::coordIndex_ILS(TYPE_MAILLE tm)
+{
+  if (tm == SEG2)
+    return (string) " 0,1 ";
+  else if (tm == SEG3)
+    return (string) " 0,1 "; // Idem SEG2
+  else if (tm == TRIA3)
+    return (string) " 0,1,2,0 ";
+  else if (tm == TRIA6)
+    return (string) " 0,1,2,0 ";
+  else if (tm == QUAD4)
+    return (string) " 0,1,2,3,0 ";
+  else if (tm == QUAD8)
+    return (string) " 0,1,2,3,0 ";
+  else if (tm == TETRA4)
+    return (string) " 0,1,2,0,-1, 0,3,-1, 1,3,-1, 2,3,-1 ";
+  else if (tm == TETRA10)
+    return (string) " 0,1,2,0,-1, 0,3,-1, 1,3,-1, 2,3,-1 ";
+  else if (tm == PYRAM5)
+    return (string) " 0,1,2,3,0,-1, 0,4,-1, 1,4,-1, 2,4,-1, 3,4,-1 ";
+  else if (tm == PYRAM13)
+    return (string) " 0,1,2,3,0,-1, 0,4,-1, 1,4,-1, 2,4,-1, 3,4,-1 ";
+  else if (tm == PENTA6)
+    return (string) " 0,1,2,0,-1, 3,4,5,3,-1, 0,3,-1, 1,4,-1, 2,5,-1 ";
+  else if (tm == PENTA15)
+    return (string) " 0,1,2,0,-1, 3,4,5,3,-1, 0,3,-1, 1,4,-1, 2,5,-1 ";
+  else if (tm == HEXA8)
+    return (string) " 0,1,2,3,0,-1, 4,5,6,7,4,-1, 0,4,-1, 1,5,-1, 2,6,-1, 3,7,-1 ";
+  else if (tm == HEXA20)
+    return (string) " 0,1,2,3,0,-1, 4,5,6,7,4,-1, 0,4,-1, 1,5,-1, 2,6,-1, 3,7,-1 ";
+  else
+    return (string) "";
+}
+
+std::string MESHCUT::coordIndex_IFS(TYPE_MAILLE tm)
+{
+  if (tm == SEG2)
+    return (string) "  ";
+  else if (tm == SEG3)
+    return (string) "  "; // Idem SEG2
+  else if (tm == TRIA3)
+    return (string) " 0,1,2,0,-1, 0,2,1,0,-1 ";
+  else if (tm == TRIA6)
+    return (string) " 0,1,2,0,-1, 0,2,1,0,-1 ";
+  else if (tm == QUAD4)
+    return (string) " 0,1,2,3,0,-1, 0,3,2,1,0,-1 ";
+  else if (tm == QUAD8)
+    return (string) " 0,1,2,3,0,-1, 0,3,2,1,0,-1 ";
+  else if (tm == TETRA4)
+    return (string) " 0,1,2,0,-1, 0,2,1,0,-1, 0,3,1,0,-1, 0,1,3,0,-1, 1,3,2,1,-1, 1,2,3,1,-1, 0,2,3,0,-1, 0,3,2,0,-1 ";
+  else if (tm == TETRA10)
+    return (string) " 0,1,2,0,-1, 0,2,1,0,-1, 0,3,1,0,-1, 0,1,3,0,-1, 1,3,2,1,-1, 1,2,3,1,-1, 0,2,3,0,-1, 0,3,2,0,-1 ";
+  else if (tm == PYRAM5)
+    return (string) " 0,1,2,3,0,-1, 0,3,2,1,0,-1, 0,1,4,0,-1, 0,4,1,0,-1, 1,2,4,1,-1, 1,4,2,1,-1, 2,4,3,2,-1, 2,3,4,2,-1, 3,4,0,3,-1, 3,0,4,3,-1 ";
+  else if (tm == PYRAM13)
+    return (string) " 0,1,2,3,0,-1, 0,3,2,1,0,-1, 0,1,4,0,-1, 0,4,1,0,-1, 1,2,4,1,-1, 1,4,2,1,-1, 2,4,3,2,-1, 2,3,4,2,-1, 3,4,0,3,-1, 3,0,4,3,-1 ";
+  else if (tm == PENTA6)
+    return (string) " 0,1,2,0,-1, 0,2,1,0,-1, 3,4,5,3,-1, 3,5,4,3,-1, 0,1,4,3,0,-1, 0,3,4,1,0,-1, 1,4,5,2,1,-1, 1,2,5,4,1,-1, 0,3,5,2,0,-1, 0,2,5,3,0,-1 ";
+  else if (tm == PENTA15)
+    return (string) " 0,1,2,0,-1, 0,2,1,0,-1, 3,4,5,3,-1, 3,5,4,3,-1, 0,1,4,3,0,-1, 0,3,4,1,0,-1, 1,4,5,2,1,-1, 1,2,5,4,1,-1, 0,3,5,2,0,-1, 0,2,5,3,0,-1 ";
+  else if (tm == HEXA8)
+    return (string) " 0,1,2,3,0,-1, 0,3,2,1,0,-1, 1,5,6,2,1,-1, 1,2,6,5,1,-1, 5,4,7,6,5,-1, 5,6,7,4,5,-1, 4,0,3,7,4,-1, 4,7,3,0,4,-1, 0,4,5,1,0,-1, 0,1,5,4,0,-1, 3,7,6,2,3,-1, 3,2,6,7,3,-1 ";
+  else if (tm == HEXA20)
+    return (string) " 0,1,2,3,0,-1, 0,3,2,1,0,-1, 1,5,6,2,1,-1, 1,2,6,5,1,-1, 5,4,7,6,5,-1, 5,6,7,4,5,-1, 4,0,3,7,4,-1, 4,7,3,0,4,-1, 0,4,5,1,0,-1, 0,1,5,4,0,-1, 3,7,6,2,3,-1, 3,2,6,7,3,-1 ";
+  else
+    return (string) "";
+}
+
+std::string MESHCUT::SIGNE(double x)
+{
+  if (x < 0)
+    return "-";
+  else if (x > 0)
+    return "+";
+  else
+    return "0";
+}
+
+void MESHCUT::champType(std::string type, med_entity_type MEM, med_geometry_type MGE, med_idt fid, med_idt fidout,
+                        char *maa, char *nomChamp, char *nomChampMoy, med_field_type typeChamp, char *compChamp,
+                        char *unitChamp, med_int nCompChamp, std::map<std::string, int> REFGAUSS, int ichamp)
+{
+
+  bool debug = true;
+  int ipt, nmailles, ngauss, imaille, igauss, icomp;
+  //  int ival, ngpdt;
+  med_int nval, numdt, numo, nPasTemps;
+  char dtunit[MED_SNAME_SIZE + 1] = "";
+  char locname[MED_NAME_SIZE + 1] = "";
+  char nomprofil[MED_NAME_SIZE + 1] = "";
+  med_float dt = 0.0;
+  med_float *valr = NULL;
+  med_float *valr2 = NULL;
+  med_bool local;
+  //  med_int nbrefmaa;
+  med_field_type fieldType;
+
+  if (MEDfieldInfo(fid, ichamp, nomChamp, maa, &local, &fieldType, compChamp, unitChamp, dtunit, &nPasTemps) < 0)
+    ERREUR("Error MEDfieldInfo");
+  cout << type << " : " << (int) nPasTemps << " timestep  " << endl;
+
+  for (ipt = 1; ipt <= nPasTemps; ipt++)
+    {
+      //for (ipt=1; ipt<=min(nPasTemps,1); ipt++) {
+      if (debug)
+        cout << endl;
+      if (debug)
+        cout << "************************************************************" << endl;
+      if (debug)
+        cout << "                    FIELD " << ichamp << endl;
+      if (debug)
+        cout << "          " << nomChamp << endl;
+      if (debug)
+        cout << "          " << type << "   ---   Timestep " << ipt << endl;
+      if (debug)
+        cout << "************************************************************" << endl;
+      if (debug)
+        cout << endl;
+
+      if (MEDfieldComputingStepInfo(fid, nomChamp, ipt, &numdt, &numo, &dt) < 0)
+        {
+          cout << endl;
+          cout << endl << "####################################################################" << endl;
+          cout << "                   ERROR MEDpasdetempsInfo                         " << endl;
+          cout << endl << "####################################################################" << endl;
+          cout << "                  Field: " << (string) nomChamp << endl;
+          cout << "                  Geometrie: " << MGE2string(MGE) << endl;
+          cout << "                  Timestep " << ipt << " ignored" << endl;
+
+          continue;
+        }
+
+      med_int profilesize, nintegrationpoint;
+      nval = MEDfieldnValueWithProfile(fid, nomChamp, numdt, numo, MEM, MGE, ipt, MED_COMPACT_PFLMODE, nomprofil,
+                                       &profilesize, locname, &nintegrationpoint);
+      if (debug)
+        cout << "     Number of values in this timestep: " << (int) nval << endl;
+
+      if (typeChamp == MED_FLOAT64)
+        valr = (med_float*) calloc(nCompChamp * nval, sizeof(med_float));
+      else
+        ERREUR("Type of field not taken into account");
+
+      if (MEDfieldValueWithProfileRd(fid, maa, numdt, numo, MEM, MGE, MED_COMPACT_PFLMODE, nomprofil,
+                                     MED_FULL_INTERLACE, MED_ALL_CONSTITUENT, (unsigned char*) valr) < 0)
+        {
+          cout << endl;
+          cout << endl << "####################################################################" << endl;
+          cout << "                         ERROR MEDchampLire                        " << endl;
+          cout << endl << "####################################################################" << endl;
+          cout << endl;
+          cout << "   Field: " << (string) nomChamp << endl;
+          cout << "   Geometry: " << MGE2string(MGE) << endl;
+          cout << "   Timestep " << ipt << " ignored" << endl;
+          cout << endl << endl;
+          continue;
+        }
+
+      if (debug)
+        cout << "       profile  = " << (string) nomprofil << endl;
+      // Localisation du champ aux points de Gauss
+      if (debug)
+        cout << "       locname = " << (string) locname << endl;
+
+      if (REFGAUSS[(string) locname])
+        {
+          ngauss = REFGAUSS[(string) locname];
+          if (debug)
+            cout << "       " << ngauss << " Gauss points by element)" << endl;
+        }
+      else
+        ngauss = 1;
+
+      nmailles = nval / ngauss;
+      if (debug)
+        cout << "      Nbre de mailles: " << nmailles << endl;
+
+      if (debug)
+        {
+          cout << endl << "       Liste des valeurs du champ brut aux 3 premiers Ã©léments:" << endl;
+          for (imaille = 0; imaille < min(nmailles, 3); imaille++)
+            {
+              cout << "         Maille " << imaille << endl;
+              for (igauss = 0; igauss < ngauss; igauss++)
+                {
+                  cout << "             PG " << igauss << " : ";
+                  for (icomp = 0; icomp < nCompChamp; icomp++)
+                    cout << " " << *(valr + imaille * ngauss * nCompChamp + igauss * nCompChamp + icomp);
+                  cout << endl;
+                }
+              cout << endl;
+            }
+          cout << endl;
+        }
+
+      if (ngauss > 1)
+        {
+
+          valr2 = (med_float*) calloc(nCompChamp * nmailles, sizeof(med_float));
+
+          if (debug)
+            cout << endl << "       Moyenne sur les PG des mailles" << endl;
+          for (imaille = 0; imaille < nmailles; imaille++)
+            {
+              for (icomp = 0; icomp < nCompChamp; icomp++)
+                {
+                  float valCompMaille = 0.0;
+                  for (igauss = 0; igauss < ngauss; igauss++)
+                    valCompMaille += *(valr + imaille * ngauss * nCompChamp + igauss * nCompChamp + icomp);
+                  *(valr2 + imaille * nCompChamp + icomp) = valCompMaille / ngauss;
+
+                }
+            }
+
+          //cout << endl << "Nom champ moy = " <<  (string)nomChampMoy << endl;
+          //cout << endl << "Type champ = " <<  typeChamp << endl;
+          //cout << endl << "Comp champ = " <<  (string)compChamp << endl;
+          //cout << endl << "Unit champ = " <<  (string)unitChamp << endl;
+          //cout << endl << "N comp champ = " <<  nCompChamp << endl;
+
+          if (MEDfieldValueWithProfileWr(fidout, nomChampMoy, numdt, numo, dt, MEM, MGE, MED_COMPACT_PFLMODE,
+                                         nomprofil, MED_NO_LOCALIZATION, MED_FULL_INTERLACE, MED_ALL_CONSTITUENT,
+                                         (med_int) nmailles, (unsigned char*) valr2) < 0)
+            {
+              cout << endl;
+              cout << endl << "********************************************************************" << endl;
+              cout << "********************                         ***********************" << endl;
+              cout << "********************   ERROR MEDchampEcr     ***********************" << endl;
+              cout << "********************                         ***********************" << endl;
+              cout << "********************************************************************" << endl;
+              cout << endl;
+              cout << "   Champ: " << (string) nomChampMoy << endl;
+              cout << "   Géométrie: " << MGE2string(MGE) << endl;
+              cout << "   Pas de temps " << ipt << " ignoré" << endl;
+              cout << endl << endl;
+              continue;
+            }
+
+          if (debug)
+            cout << "    Writing mean values in new field: OK " << endl;
+
+          // Restitution du champ moyenné
+          if (debug)
+            {
+              cout << endl << "       Liste des valeurs du champ moyenné aux 3 premiers Ã©léments:" << endl;
+              for (imaille = 0; imaille < min(nmailles, 3); imaille++)
+                {
+                  cout << "         Maille " << imaille << endl;
+                  for (icomp = 0; icomp < nCompChamp; icomp++)
+                    cout << " " << *(valr2 + imaille * nCompChamp + icomp);
+                  cout << endl;
+                }
+              cout << endl;
+            }
+
+        }
+
+      free(valr);
+      free(valr2);
+
+    } // boucle sur les pas de temps
+
+  cout << endl;
+}
+
+std::string MESHCUT::nomMaille(TYPE_MAILLE tm, int nl)
+{
+  return (TM2string(tm) + (string) "_" + int2string(nl));
+}
+
+bool MESHCUT::appartientVN(int n, std::vector<int> V)
+{
+  bool app = false;
+  for (unsigned int i = 0; i < V.size(); i++)
+    if (n == V[i])
+      {
+        app = true;
+        break;
+      }
+  return app;
+}
+
+float MESHCUT::distance2(float x1, float y1, float z1, float x2, float y2, float z2)
+{
+  return (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) + (z2 - z1) * (z2 - z1);
+}
+
+/*!
+ *  Conversion HL-MED d'une table de connectivités
+ */
+void MESHCUT::conversionCNX(int *CNXtm, TYPE_MAILLE tm, int N)
+{
+
+  int n = Nnoeuds(tm);
+
+  if (tm == TETRA4)
+    {
+      for (int i = 0; i < N; i++)
+        {
+          int i1 = CNXtm[i * n + 1];
+          int i2 = CNXtm[i * n + 2];
+          CNXtm[i * n + 1] = i2;
+          CNXtm[i * n + 2] = i1;
+        }
+    }
+  else if (tm == PYRAM5)
+    {
+      for (int i = 0; i < N; i++)
+        {
+          int i1 = CNXtm[i * n + 1];
+          int i3 = CNXtm[i * n + 3];
+          CNXtm[i * n + 1] = i3;
+          CNXtm[i * n + 3] = i1;
+        }
+    }
+  else if (tm == PENTA6)
+    {
+      for (int i = 0; i < N; i++)
+        {
+          int i0 = CNXtm[i * n + 0];
+          int i1 = CNXtm[i * n + 1];
+          int i2 = CNXtm[i * n + 2];
+          int i3 = CNXtm[i * n + 3];
+          int i4 = CNXtm[i * n + 4];
+          int i5 = CNXtm[i * n + 5];
+          CNXtm[i * n + 0] = i3;
+          CNXtm[i * n + 1] = i4;
+          CNXtm[i * n + 2] = i5;
+          CNXtm[i * n + 3] = i0;
+          CNXtm[i * n + 4] = i1;
+          CNXtm[i * n + 5] = i2;
+        }
+    }
+
+  else if (tm == HEXA8)
+    {
+      for (int i = 0; i < N; i++)
+        {
+          int i0 = CNXtm[i * n + 0];
+          int i1 = CNXtm[i * n + 1];
+          int i2 = CNXtm[i * n + 2];
+          int i3 = CNXtm[i * n + 3];
+          int i4 = CNXtm[i * n + 4];
+          int i5 = CNXtm[i * n + 5];
+          int i6 = CNXtm[i * n + 6];
+          int i7 = CNXtm[i * n + 7];
+          CNXtm[i * n + 0] = i4;
+          CNXtm[i * n + 1] = i5;
+          CNXtm[i * n + 2] = i6;
+          CNXtm[i * n + 3] = i7;
+          CNXtm[i * n + 4] = i0;
+          CNXtm[i * n + 5] = i1;
+          CNXtm[i * n + 6] = i2;
+          CNXtm[i * n + 7] = i3;
+        }
+    }
+}
+
diff --git a/src/Tools/MeshCut/MeshCut_Utils.hxx b/src/Tools/MeshCut/MeshCut_Utils.hxx
new file mode 100644 (file)
index 0000000..36eb22d
--- /dev/null
@@ -0,0 +1,81 @@
+// Copyright (C) 2006-2012  EDF R&D
+//
+// 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.com
+//
+
+#ifndef __MESHCUT_UTILS_HXX__
+#define __MESHCUT_UTILS_HXX__
+
+extern "C"
+  {
+#include <med.h>
+  }
+
+#include <string>
+#include <vector>
+#include <map>
+
+namespace MESHCUT
+  {
+
+    enum TYPE_MAILLE
+    {
+      POI1, SEG2, SEG3, TRIA3, TRIA6, QUAD4, QUAD8, TETRA4, TETRA10, PYRAM5, PYRAM13, PENTA6, PENTA15, HEXA8, HEXA20
+    };
+
+    bool estUnTypeMaille(std::string S);
+    void ERREUR(const char* msg);
+    char* string2char(std::string str);
+    std::string int2string(int k);
+    float char2float(const char* ch);
+    std::string float2string(float f);
+    bool appartient(std::string e, std::string tableau[], int taille);
+    float arrondi(float x);
+    int numNoeudPointe(std::string b1, std::string b2, std::string b3);
+    std::string strip(std::string S);
+    std::string entierSur10_g(int i);
+    std::string entierSur10_d(int i);
+    std::string typeEnsight(std::string type);
+    int Nnoeuds(TYPE_MAILLE type);
+    int NnoeudsGeom(TYPE_MAILLE type);
+    int codeGMSH(std::string type);
+    std::string floatEnsight(float x);
+    bool typeComplexe(std::string type);
+    std::string ASTER8(std::string s);
+    float dObservateur(float a, float b, float c);
+
+    int copieFichier(std::string source, std::string cible);
+    med_geometry_type InstanceMGE(TYPE_MAILLE TYPE);
+    int chrono();
+    TYPE_MAILLE typeMaille(std::string type);
+    std::string MGE2string(med_geometry_type MGE);
+    std::string TM2string(TYPE_MAILLE MGE);
+    TYPE_MAILLE string2TM(std::string stm);
+    std::string coordIndex_ILS(TYPE_MAILLE tm);
+    std::string coordIndex_IFS(TYPE_MAILLE tm);
+    std::string SIGNE(double x);
+    void champType(std::string type, med_entity_type MEM, med_geometry_type MGE, med_idt fid, med_idt fidout,
+                   char *maa, char *nomChamp, char *nomChampMoy, med_field_type typeChamp, char *compChamp,
+                   char *unitChamp, med_int nCompChamp, std::map<std::string, int> REFGAUSS, int ichamp);
+    std::string nomMaille(TYPE_MAILLE tm, int nl);
+    bool appartientVN(int n, std::vector<int> V);
+    float distance2(float x1, float y1, float z1, float x2, float y2, float z2);
+    void conversionCNX(int *CNXtm, TYPE_MAILLE tm, int N);
+
+  }
+
+#endif
diff --git a/src/Tools/MeshCut/README b/src/Tools/MeshCut/README
new file mode 100644 (file)
index 0000000..599806b
--- /dev/null
@@ -0,0 +1,26 @@
+
+
+                 Cut a tetrahedron mesh by a plane
+                 ---------------------------------
+                 
+MeshCut allows to cut a mesh constituted of linear tetrahedrons by a plane.
+The tetrahedrons intersected by the plane are cut and replaced by elements of various types,
+(tetrahedron, pyramid, pentahedron).
+
+MeshCut is a standalone program, reading and producing med files.                
+                 
+Syntax:
+
+MeshCut input.med output.med resuMeshName aboveGroup belowGroup nx ny nz px py pz T
+
+where:
+  input.med    = name of the original mesh file in med format
+  output.med   = name of the result mesh file in med format
+  resuMeshName = name of the result mesh
+  aboveGroup   = name of the group of volumes above the cut plane
+  belowGroups  = name of the group of volumes below the cut plane
+  nx ny nz     = vector normal to the cut plane
+  px py pz     = a point of the cut plane
+  T            = 0 < T < 1 : vertices of a tetrahedron are considered as belonging to
+                 the cut plane if their distance to the plane is inferior to L*T
+                 where L is the mean edge size of the tetrahedron
diff --git a/src/Tools/MeshCut/meshcut_plugin.py b/src/Tools/MeshCut/meshcut_plugin.py
new file mode 100644 (file)
index 0000000..eaab608
--- /dev/null
@@ -0,0 +1,140 @@
+# Copyright (C) 2006-2012  EDF R&D
+#
+# 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.com
+#
+
+# if you already have plugins defined in a salome_plugins.py file, add this file at the end.
+# if not, copy this file as ${HOME}/Plugins/smesh_plugins.py or ${APPLI}/Plugins/smesh_plugins.py
+
+def MeshCut(context):
+  # get context study, studyId, salomeGui
+  study = context.study
+  studyId = context.studyId
+  sg = context.sg
+  
+  import os
+  import subprocess
+  import tempfile
+  from PyQt4 import QtCore
+  from PyQt4 import QtGui
+  from PyQt4.QtGui import QFileDialog
+  from PyQt4.QtGui import QMessageBox
+  from MeshCutDialog import Ui_Dialog
+  
+  class CutDialog(QtGui.QDialog):
+    
+    def __init__(self):
+      QtGui.QDialog.__init__(self)
+      # Set up the user interface from Designer.
+      self.ui = Ui_Dialog()
+      self.ui.setupUi(self)
+      # Connect up the buttons.
+      self.connect(self.ui.pb_origMeshFile, QtCore.SIGNAL("clicked()"),
+                   self.setInputFile)
+      self.connect(self.ui.pb_cutMeshFile, QtCore.SIGNAL("clicked()"),
+                   self.setOutputFile)
+      self.connect(self.ui.pb_help, QtCore.SIGNAL("clicked()"),
+                   self.helpMessage)
+      pass
+    
+    def setInputFile(self):
+      fd = QFileDialog(self, "select an existing Med file", self.ui.le_origMeshFile.text(), "MED-Files (*.med);;All Files (*)")
+      if fd.exec_():
+        infile = fd.selectedFiles()[0]
+        self.ui.le_origMeshFile.setText(infile)
+        insplit = os.path.splitext(infile.toLocal8Bit().data())
+        outfile = insplit[0] + '_cut' + insplit[1]
+        self.ui.le_cutMeshFile.setText(outfile)
+      pass
+    
+    def setOutputFile(self):
+      fd = QFileDialog(self, "select an output Med file", self.ui.le_cutMeshFile.text(), "MED-Files (*.med);;All Files (*)")
+      if fd.exec_():
+        self.ui.le_cutMeshFile.setText(fd.selectedFiles()[0])
+      pass
+    
+    def helpMessage(self):
+      QMessageBox.about(None, "About MeshCut",
+      """
+      Cut a tetrahedron mesh by a plane
+      ---------------------------------
+                 
+MeshCut allows to cut a mesh constituted of linear
+tetrahedrons by a plane. The tetrahedrons intersected
+by the plane are cut and replaced by elements of
+various types (tetrahedron, pyramid, pentahedron).
+
+MeshCut is a standalone program, reading and
+producing med files. The cutting plane is defined
+by a vector normal to the plane and a vertex
+belonging to the plane.
+
+Vertices of a tetrahedron are considered as belonging to
+the cut plane if their distance to the plane is inferior
+to L*T where L is the mean edge size of the tetrahedron
+and T the tolerance.
+      """)
+      pass
+    pass
+  
+  
+                     
+  window = CutDialog()
+  window.ui.dsb_tolerance.setValue(0.01)
+  retry = True
+  while(retry):
+    retry = False
+    window.exec_()
+    result = window.result()
+    if result:
+      # dialog accepted
+      args = ['MeshCut']
+      args += [window.ui.le_origMeshFile.text().toLocal8Bit().data()]
+      args += [window.ui.le_cutMeshFile.text().toLocal8Bit().data()]
+      args += [window.ui.le_outMeshName.text().toLocal8Bit().data()]
+      args += [window.ui.le_groupAbove.text().toLocal8Bit().data()]
+      args += [window.ui.le_groupBelow.text().toLocal8Bit().data()]
+      args += [str(window.ui.dsb_normX.value())]
+      args += [str(window.ui.dsb_normY.value())]
+      args += [str(window.ui.dsb_normZ.value())]
+      args += [str(window.ui.dsb_vertX.value())]
+      args += [str(window.ui.dsb_vertY.value())]
+      args += [str(window.ui.dsb_vertZ.value())]
+      args += [str(window.ui.dsb_tolerance.value())]
+      f= tempfile.NamedTemporaryFile(delete=False)
+      fname = f.name
+      p = subprocess.Popen(args, stdout=f, stderr=f)
+      err = p.wait()
+      f.close()
+      if err==0:
+        os.remove(fname)
+      else:
+        f = open(fname, 'r')
+        m = f.read()
+        msgBox = QMessageBox()
+        msgBox.setText("Parameters are not OK")
+        msgBox.setInformativeText("Do you want to retry ?")
+        msgBox.setDetailedText(m)
+        msgBox.setStandardButtons(QMessageBox.Retry | QMessageBox.Cancel)
+        msgBox.setDefaultButton(QMessageBox.Retry)
+        ret = msgBox.exec_()
+        if ret == QMessageBox.Retry:
+          retry = True
+        pass
+      pass
+    pass
+  pass
diff --git a/src/Tools/padder/Makefile.am b/src/Tools/padder/Makefile.am
new file mode 100644 (file)
index 0000000..e771536
--- /dev/null
@@ -0,0 +1,22 @@
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D
+#
+# 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.com
+#
+
+SUBDIRS = meshjob spadderpy unittests resources doc
+
+EXTRA_DIST = README.txt
diff --git a/src/Tools/padder/README.txt b/src/Tools/padder/README.txt
new file mode 100644 (file)
index 0000000..2ecebb3
--- /dev/null
@@ -0,0 +1,38 @@
+
+
+PADDER overview
+---------------
+
+PADDER is an algorithm that creates a set of particules called a "discrete mesh".
+The particules are characterized by a location in space and a weight that can be considered
+as the radius of a sphere whose center is the location of the particule.
+
+Discrete meshes are typically used to modelize civil components in rapid dynamic
+computation problems (seisms, chocs). These components consists in concrete parts
+embedding steal bares for reinforcement. These parts are input to the algorithm
+as standard finite elements meshes. The cells of theses meshes drive the location
+and sizing of particules.
+
+In the med representation, a discrete mesh is described as MED_BALL elements.
+A MED_BALL element is defined by a location and a radius. 
+
+PADDER plugin
+-------------
+
+This directory provides SMESH with a SALOME plugin that can be used to define
+and then run a PADDER execution. The inputs are the FE meshes that describe
+the concrete parts and steal bares parts. The output is a discrete mesh
+containing MED_BALL elements.
+
+A graphical interface is used to drive the user for data input and computation
+supervision (the algorithm may last more than an hour long), and finally the publication
+of the resulting mesh (when succeed) in the SALOME study.
+
+Technically speaking, the PADDER plugin consists in:
+
+* a SALOME component MESHJOB that do the computation job (wrapper to the padder executable program)
+* a graphical interface composed of two dialog windows
+* a configuration mechanism (data file and read function), to define
+  the computation resource (a SALOME resource + the software configuration of the padder executable
+  program on this resource)
+* an integration file (salomeplugin.py)
diff --git a/src/Tools/padder/doc/Makefile.am b/src/Tools/padder/doc/Makefile.am
new file mode 100755 (executable)
index 0000000..ec45f74
--- /dev/null
@@ -0,0 +1,39 @@
+# Copyright (C) 2011-2012  CEA/DEN, EDF R&D
+#
+# 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.com
+#
+
+#  Author : Guillaume Boulant (EDF/R&D)
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+EXTRA_DIST += images input
+
+#
+# The simplest way to extend the documentation of SMESH with the
+# documentation for PADDER is to add path to the padder documentation
+# in the SMESH gui documentation (see the doxyfile).
+#
+
+# For test purpose, we let the user generate a local dosygen
+# documentation including only the local pages  
+#
+test_docs: doxyfile 
+       echo "===========================================" ; \
+       echo "Generating PADDER documentation" ;             \
+       echo "===========================================" ; \
+       $(DOXYGEN) doxyfile ;
diff --git a/src/Tools/padder/doc/doxyfile.in b/src/Tools/padder/doc/doxyfile.in
new file mode 100755 (executable)
index 0000000..7ce741c
--- /dev/null
@@ -0,0 +1,77 @@
+# Copyright (C) 2007-2012  CEA/DEN, EDF R&D
+#
+# Copyright (C) 2003-2007  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.com
+#
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME      = "SALOME Mesh User's Guide"
+OUTPUT_DIRECTORY  = .
+CREATE_SUBDIRS   = NO
+OUTPUT_LANGUAGE   = English
+TAB_SIZE          = 5
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET             = NO
+WARNINGS          = YES
+
+#---------------------------------------------------------------------------
+#Input related options
+#---------------------------------------------------------------------------
+INPUT             = @srcdir@/input               
+FILE_PATTERNS     = *.doc
+EXCLUDE           = 
+IMAGE_PATH        = @srcdir@/images
+EXAMPLE_PATH      = @top_srcdir@/src/SMESH_SWIG
+
+#---------------------------------------------------------------------------
+#HTML related options
+#---------------------------------------------------------------------------
+GENERATE_HTML     = YES
+HTML_OUTPUT       = .
+HTML_HEADER       = @top_builddir@/doc/salome/gui/SMESH/static/header.html
+HTML_FOOTER       = @top_srcdir@/doc/salome/gui/SMESH/static/footer.html
+HTML_STYLESHEET   = @top_srcdir@/doc/salome/gui/SMESH/static/doxygen.css
+TOC_EXPAND        = YES
+DISABLE_INDEX     = NO
+GENERATE_TREEVIEW = YES
+TREEVIEW_WIDTH    = 300
+
+#---------------------------------------------------------------------------
+#SORT related options
+#---------------------------------------------------------------------------
+SORT_GROUP_NAMES = NO
+
+
+#---------------------------------------------------------------------------
+#LaTeX related option
+#---------------------------------------------------------------------------
+GENERATE_LATEX    = NO
+EXTRA_PACKAGES    = amsmath
+
+#---------------------------------------------------------------------------
+#RTF related options
+#---------------------------------------------------------------------------
+GENERATE_RTF      = NO
+
+SEARCHENGINE      = YES
diff --git a/src/Tools/padder/doc/images/SMESH_spadder_end.png b/src/Tools/padder/doc/images/SMESH_spadder_end.png
new file mode 100644 (file)
index 0000000..12e2b7c
Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_end.png differ
diff --git a/src/Tools/padder/doc/images/SMESH_spadder_inputdialog_concrete.png b/src/Tools/padder/doc/images/SMESH_spadder_inputdialog_concrete.png
new file mode 100644 (file)
index 0000000..ed0a8a7
Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_inputdialog_concrete.png differ
diff --git a/src/Tools/padder/doc/images/SMESH_spadder_inputdialog_start.png b/src/Tools/padder/doc/images/SMESH_spadder_inputdialog_start.png
new file mode 100644 (file)
index 0000000..8725d71
Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_inputdialog_start.png differ
diff --git a/src/Tools/padder/doc/images/SMESH_spadder_inputdialog_steelbar.png b/src/Tools/padder/doc/images/SMESH_spadder_inputdialog_steelbar.png
new file mode 100644 (file)
index 0000000..8e692dc
Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_inputdialog_steelbar.png differ
diff --git a/src/Tools/padder/doc/images/SMESH_spadder_menu.png b/src/Tools/padder/doc/images/SMESH_spadder_menu.png
new file mode 100644 (file)
index 0000000..e891406
Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_menu.png differ
diff --git a/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_finished.png b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_finished.png
new file mode 100644 (file)
index 0000000..e29cf56
Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_finished.png differ
diff --git a/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_ready.png b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_ready.png
new file mode 100644 (file)
index 0000000..f86790b
Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_ready.png differ
diff --git a/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_running.png b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_running.png
new file mode 100644 (file)
index 0000000..b3c9ef1
Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_compute_running.png differ
diff --git a/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_published.png b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_published.png
new file mode 100644 (file)
index 0000000..19e1ae7
Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_published.png differ
diff --git a/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_start.png b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_start.png
new file mode 100644 (file)
index 0000000..45ba1a0
Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_plugindialog_start.png differ
diff --git a/src/Tools/padder/doc/images/SMESH_spadder_start.png b/src/Tools/padder/doc/images/SMESH_spadder_start.png
new file mode 100644 (file)
index 0000000..160da9d
Binary files /dev/null and b/src/Tools/padder/doc/images/SMESH_spadder_start.png differ
diff --git a/src/Tools/padder/doc/input/padder_userguide.doc b/src/Tools/padder/doc/input/padder_userguide.doc
new file mode 100644 (file)
index 0000000..d92f85e
--- /dev/null
@@ -0,0 +1,139 @@
+/*!
+
+\page padder_userguide_page Use the padder SMESH Plugin
+
+-# \ref S1_PADDER
+-# \ref S2_PADDER
+-# \ref S3_PADDER
+
+\section S1_PADDER The PADDER Algorithm
+
+PADDER is an algorithm that creates a set of particules called a "discrete mesh".
+The particules are characterized by a location in space and a weight that can be considered
+as the radius of a sphere whose center is the location of the particule.
+
+Discrete meshes are typically used to modelize civil components in rapid dynamic
+computation problems (seisms, chocs). These components consists in concrete parts
+embedding steal bares for reinforcement. These parts are input to the algorithm
+as standard finite elements meshes. The cells of theses meshes drive the location
+and sizing of particules.
+
+In the med representation, a discrete mesh is described as MED_BALL elements.
+A MED_BALL element is defined by a location and a radius.
+
+\section S2_PADDER The PADDER SALOME plugin
+
+The PADDER algoritm is integrated in the module SMESH as a SALOME
+plugin. This section illustrates how to use this plugin to create a
+discrete mesh.
+
+In this example, we suppose that two standard meshes (Finite Elements
+Meshes) have been created and publish in the study to modelize the
+concrete part (here with the name "concrete") and the steal bars part
+(here with the name "ferrail"):
+
+\image html SMESH_spadder_start.png
+
+The PADDER plugin can be invoked from the SMESH plugins menu, as
+illustrated on the figure below:
+
+\image html SMESH_spadder_menu.png
+
+When you clic on the "PADDER mesher" item, the graphical interface of
+the PADDER plugin appears:
+
+\image html SMESH_spadder_plugindialog_start.png
+
+This interface invites you to specify input data by pressing the button
+"Input". This command opens the Input dialog box to specify the list
+of meshes and the type of the selected meshes (to be choosen between
+"concrete" or "steelbar" using the combobox on the right side of the
+input line):
+
+\image html SMESH_spadder_inputdialog_start.png
+
+In the figure below, the mesh with name "concrete" has been selected
+in the study and added in the list of input file as a "concrete
+mesh". You have to input the mesh in the dialog using the rounded
+arrow icon, then specify a group name (the name of the group of
+MED_BALL created for this mesh in the resulting mesh), and finnaly
+clic on the "Add" icon:
+
+\image html SMESH_spadder_inputdialog_concrete.png
+
+Then, the mesh with name "ferrail" is selected and added to the list
+as a "steelbar mesh":
+
+\image html SMESH_spadder_inputdialog_steelbar.png
+
+The input dialog box can be validated toreturn to the main plugin
+interface. The "Compute" button is now enable, indicating that the
+problem is ready to be computed:
+
+\image html SMESH_spadder_plugindialog_compute_ready.png
+
+The command "Compute" start the job. The progression can be requested
+using the command "Refresh". In the figure below, the job is still
+running:
+
+\image html SMESH_spadder_plugindialog_compute_running.png
+
+Finally, the job is finished and the result is ready to be published
+in the SALOME study:
+
+\image html SMESH_spadder_plugindialog_compute_finished.png
+
+Clic on the command "Publish" to explicitly import the resulting med
+file in SMESH and published the resulting mesh in the SALOME study:
+
+\image html SMESH_spadder_plugindialog_published.png
+
+Note that this mesh contains one group for each of the input mesh. A
+group with the name specified in the input dialog has been defined for
+the set of MED_BALL created from the corresponding input mesh:
+
+\image html SMESH_spadder_end.png
+
+\section S3_PADDER Configuring the plugin
+
+The configuration of the plugin consists in specifying the location of
+the padder executable program for each of the SALOME resource (at
+least for the localhost resource). This specification is done in the
+file padder.cfg, located in the plugin installation folder
+(i.e. <SMESH_ROOT_DIR>/plugins):
+
+\code
+# This section specify the configurations to be used respectively for
+# the local execution and the remote execution. The value for 'local'
+# and 'remote' keys must be the name of a configuration section in
+# this file. The default key must specify a value between "local" or
+# "remote" to indicate the user preference. 
+[resources]
+local   = localhost
+remote  = nepal
+
+[preferences]
+defaultres = local
+
+# The following sections defines the available configurations.
+# The name of the section can be choosen arbitrary. But the value of
+# the resname key MUST be the name of a SALOME resource defined in the
+# catalog of resources (CatalogResources.xml).
+
+# For each section:
+# - resname : the name of the SALOME resource to be used in this configuration
+# - binpath : the path to the padder executable program on this resource
+# - envpath : the path to the environment file on this resource
+[localhost]
+resname = localhost
+binpath = /home/.programs/salome/workspace/V6_4_BR/SMESH/install/share/salome/resources/smesh/padderexe/padder.exe
+envpath = /home/.programs/salome/workspace/V6_4_BR/SMESH/install/share/salome/resources/smesh/padderexe/envPadder.sh
+
+[nepal]
+resname = nepal@nepal
+binpath = /usr/local/bin/padder.exe
+envpath = /usr/local/share/envPadder.sh
+\endcode
+
+*/
+
diff --git a/src/Tools/padder/meshjob/Makefile.am b/src/Tools/padder/meshjob/Makefile.am
new file mode 100644 (file)
index 0000000..b1a47b9
--- /dev/null
@@ -0,0 +1,20 @@
+# Copyright (C) 2011-2012  CEA/DEN, EDF R&D
+#
+# 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.com
+#
+
+SUBDIRS = idl impl
diff --git a/src/Tools/padder/meshjob/idl/MESHJOB.idl b/src/Tools/padder/meshjob/idl/MESHJOB.idl
new file mode 100644 (file)
index 0000000..a5559cd
--- /dev/null
@@ -0,0 +1,126 @@
+// Copyright (C) 2011-2012  CEA/DEN, EDF R&D
+//
+// 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.com
+//
+// Authors : Guillaume Boulant (EDF) - 31/01/2011
+
+#ifndef _MESHJOB_IDL_
+#define _MESHJOB_IDL_
+
+#include "SALOME_Exception.idl"
+#include "SALOME_Component.idl"
+
+//
+// This interface is used for mesh job submission from within the
+// SALOME plugin for PADDER.
+//
+module MESHJOB
+{
+
+  //
+  // Structure to transmit the parameters requiered for the job to run
+  // the executable program on the target resource. See configure
+  // service.
+  //
+  struct ConfigParameter {
+    string resname; // The name of the SALOME resource to be used
+    string binpath; // The path of the executable program on this resource
+    string envpath; // The path of the environment file on this resource
+  };
+
+  //
+  // This set of specification defines the data structure used to
+  // initialize a job on a specific resource, then supervise the job
+  // and finally retrieve the result data.
+  //
+
+  // This defines the set of temporary folders used by the jobmanager
+  // when executing a job (may depends on the job).
+  struct MeshJobPaths
+  {
+    string local_inputdir;
+    string local_resultdir;
+    string remote_workdir;
+  };
+
+  // This defines the possible types for a job parameter
+  enum FileType {MED_CONCRETE, MED_STEELBAR};
+
+  // This defines a single parameter for the job initialization (a med file)
+  struct MeshJobParameter
+  {
+    string file_name;
+    FileType file_type;
+    string group_name;
+  };
+  
+  // This defines a set of parameters for the job initialization
+  typedef sequence<MESHJOB::MeshJobParameter> MeshJobParameterList;
+
+  // This defines the result data of a job 
+  struct MeshJobResults
+  {
+    string results_dirname;
+    string outputmesh_filename;
+    string status;
+  };
+
+  // This defines the possible states of a job
+  enum MeshJobState {CREATED, IN_PROCESS, QUEUED, RUNNING, PAUSED, FINISHED, ERROR};
+
+  //
+  // This interface defines the computation services of the component
+  //
+
+  interface MeshJobManager: Engines::EngineComponent
+  {
+
+     /*! Add a resource configuration, identified by the string
+         configId and characterized by the parameters in
+         configParameter */
+    boolean configure(in string configId, in MESHJOB::ConfigParameter configParameter)
+      raises (SALOME::SALOME_Exception);
+
+    /*! Initialize a smesh computation job and return the job identifier */
+    long    initialize(in MESHJOB::MeshJobParameterList meshJobParameterList, in string configId)
+      raises (SALOME::SALOME_Exception);
+
+    /*! Submit the job execution and return true if submission is OK */
+    boolean start(in long jobId)
+      raises (SALOME::SALOME_Exception);
+
+    /*! Request the launch manager for the state of the specified job */
+    string getState(in long jobId)
+      raises (SALOME::SALOME_Exception);
+
+    /*! Request the launch manager for downloading the results */
+    MeshJobResults finalize(in long jobid)
+      raises (SALOME::SALOME_Exception);
+
+    /*! Clean all data associated to this job and remove the job from the launch manager */
+    boolean clean(in long jobId)
+      raises (SALOME::SALOME_Exception);
+
+    /*! Returns the set of temporary folders used by the job instance */
+    MeshJobPaths getPaths(in long jobId)
+      raises (SALOME::SALOME_Exception);
+
+  };
+
+};
+
+#endif // _MESHJOB_IDL_
diff --git a/src/Tools/padder/meshjob/idl/Makefile.am b/src/Tools/padder/meshjob/idl/Makefile.am
new file mode 100644 (file)
index 0000000..15bb1a8
--- /dev/null
@@ -0,0 +1,95 @@
+# Copyright (C) 2011-2012  CEA/DEN, EDF R&D
+#
+# 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.com
+#
+
+# This Makefile is responsible of generating the client and server
+# implementation of IDL interfaces for both C++ and python usage.
+# The building process of the C++ files is in charge of each source
+# package and then is not manage here.
+#
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+BUILT_SOURCES = MESHJOBSK.cc
+IDL_FILES = MESHJOB.idl
+
+# For test purpose, we add a little component:
+BUILT_SOURCES += SPADDERPluginTestSK.cc
+IDL_FILES += SPADDERPluginTest.idl
+
+IDL_FILES_PY=$(IDL_FILES:%.idl=%_idl.py)
+
+salomeidl_DATA = $(IDL_FILES) 
+
+lib_LTLIBRARIES = libSalomeIDLSPADDER.la
+libSalomeIDLSPADDER_la_SOURCES      =
+nodist_libSalomeIDLSPADDER_la_SOURCES = $(BUILT_SOURCES)
+nodist_salomeinclude_HEADERS= $(IDL_FILES:%idl=%hh)
+
+OMNIORB_CXXFLAGS=@OMNIORB_CXXFLAGS@ @OMNIORB_INCLUDES@
+OMNIORB_LIBS=@OMNIORB_LIBS@
+
+libSalomeIDLSPADDER_la_CXXFLAGS = \
+       $(KERNEL_CXXFLAGS) \
+       $(OMNIORB_CXXFLAGS) \
+       -I.
+
+libSalomeIDLSPADDER_la_LIBADD     = \
+       $(KERNEL_LDFLAGS) -lSalomeIDLKernel \
+       $(OMNIORB_LIBS)
+
+
+# These variables defines the building process of CORBA files
+IDLCXXFLAGS = \
+        -bcxx -I. \
+       @OMNIORB_IDLCXXFLAGS@ \
+        -I$(KERNEL_ROOT_DIR)/idl/salome
+
+IDLPYFLAGS  = \
+       -I. \
+       @OMNIORB_IDLPYFLAGS@ \
+        -I$(KERNEL_ROOT_DIR)/idl/salome
+
+##########################################################
+SUFFIXES = .idl .hh SK.cc
+
+%SK.cc %.hh : %.idl
+       $(OMNIORB_IDL) $(IDLCXXFLAGS) $<
+
+%_idl.py : %.idl
+       $(OMNIORB_IDL) $(IDLPYFLAGS)  $<
+
+CLEANFILES = *.hh *SK.cc *.py *.hxx *.cxx
+
+EXTRA_DIST += $(IDL_FILES)
+
+install-data-local: $(IDL_FILES)
+       $(INSTALL) -d  $(DESTDIR)$(salomepythondir)
+       ls $^ | while read file; do \
+       $(OMNIORB_IDL) $(IDLPYFLAGS) -C$(DESTDIR)$(salomepythondir) $$file ; \
+       done
+
+# we want to remove only staff generated for IDL files and nothing more
+uninstall-local:
+       @for modulen in MESHJOB SPADDERPluginTest  ; do \
+         test -d $(DESTDIR)$(salomepythondir)/$${modulen} && echo "Removing $(DESTDIR)$(salomepythondir)/$${modulen}" && rm -rf $(DESTDIR)$(salomepythondir)/$${modulen} ; \
+         test -d $(DESTDIR)$(salomepythondir)/$${modulen}__POA && echo "Removing $(DESTDIR)$(salomepythondir)/$${modulen}__POA" && rm -rf $(DESTDIR)$(salomepythondir)/$${modulen}__POA ; \
+       done ; \
+       for filen in $(IDL_FILES_PY) ; do \
+         echo "Removing $(DESTDIR)$(salomepythondir)/$${filen}" && rm -f $(DESTDIR)$(salomepythondir)/$${filen}* ; \
+       done
+
diff --git a/src/Tools/padder/meshjob/idl/SPADDERPluginTest.idl b/src/Tools/padder/meshjob/idl/SPADDERPluginTest.idl
new file mode 100644 (file)
index 0000000..e0beec0
--- /dev/null
@@ -0,0 +1,46 @@
+// Copyright (C) 2011-2012  CEA/DEN, EDF R&D
+//
+// 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.com
+//
+// Authors : Guillaume Boulant (EDF) - 31/01/2011
+
+#ifndef _SPADDERPLUGINTEST_IDL_
+#define _SPADDERPLUGINTEST_IDL_
+
+#include "SALOME_Exception.idl"
+#include "SALOME_Component.idl"
+
+module SPADDERPluginTest {
+
+  //
+  // ========================================================================
+  // Thi module defines an interface provided for testing the usage
+  // of SPADDERPlugin components and underlying classes from within a
+  // C++ unit test running in a SALOME container (easy to run from a
+  // python client)..
+  // ========================================================================
+  //
+
+  interface SPADDERPluginTester: Engines::EngineComponent
+  {
+    void demo(in double a,in double b,out double c) raises (SALOME::SALOME_Exception);
+    boolean testkernel() raises (SALOME::SALOME_Exception);
+    boolean testsmesh(in long studyId) raises (SALOME::SALOME_Exception);
+  };
+};
+
+#endif // _SPADDERPLUGINTEST_IDL_
diff --git a/src/Tools/padder/meshjob/impl/Makefile.am b/src/Tools/padder/meshjob/impl/Makefile.am
new file mode 100644 (file)
index 0000000..31a6dbb
--- /dev/null
@@ -0,0 +1,89 @@
+# Copyright (C) 2011-2012  CEA/DEN, EDF R&D
+#
+# 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.com
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+AM_CFLAGS=$(SALOME_INCLUDES) -fexceptions
+
+lib_LTLIBRARIES= libMeshJobManagerEngine.la
+
+salomeinclude_HEADERS= \
+       MeshJobManager_i.hxx
+
+
+# =============================================================
+# Definition of MeshJobManagerEngine construction
+# =============================================================
+libMeshJobManagerEngine_la_SOURCES  = \
+       MeshJobManager_i.cxx
+
+LIBXML_LIBS=@LIBXML_LIBS@
+KERNEL_CXXFLAGS=@KERNEL_CXXFLAGS@
+
+libMeshJobManagerEngine_la_CXXFLAGS = \
+       -I$(top_builddir)/src/Tools/padder/meshjob/idl $(KERNEL_CXXFLAGS) \
+       @CORBA_CXXFLAGS@ @CORBA_INCLUDES@ @LIBXML_INCLUDES@
+
+libMeshJobManagerEngine_la_FFLAGS = -fexceptions
+libMeshJobManagerEngine_la_LDFLAGS   = \
+       $(top_builddir)/src/Tools/padder/meshjob/idl/libSalomeIDLSPADDER.la \
+       @KERNEL_LDFLAGS@ -lSalomeContainer -lSalomeKernelHelpers -lSalomeLifeCycleCORBA \
+       @LIBXML_LIBS@
+
+# =============================================================
+# Definition of the SPADDERPluginTester engine construction
+# =============================================================
+lib_LTLIBRARIES += libSPADDERPluginTesterEngine.la
+
+libSPADDERPluginTesterEngine_la_SOURCES  = \
+       SPADDERPluginTester_i.hxx \
+        SPADDERPluginTester_i.cxx
+
+nodist_libSPADDERPluginTesterEngine_la_SOURCES =
+
+libSPADDERPluginTesterEngine_la_CXXFLAGS = \
+       -I$(top_builddir)/src/Tools/padder/meshjob/idl $(KERNEL_CXXFLAGS) \
+       @CORBA_CXXFLAGS@ @CORBA_INCLUDES@ @LIBXML_INCLUDES@
+
+libSPADDERPluginTesterEngine_la_FFLAGS = -fexceptions
+libSPADDERPluginTesterEngine_la_LIBADD = \
+       $(top_builddir)/src/Tools/padder/meshjob/idl/libSalomeIDLSPADDER.la \
+       @KERNEL_LDFLAGS@ -lSalomeContainer -lSalomeKernelHelpers \
+       @LIBXML_LIBS@
+
+
+# For testing SMESH
+#
+libSPADDERPluginTesterEngine_la_CXXFLAGS += \
+       @GEOM_CXXFLAGS@ @MED_CXXFLAGS@ \
+       -I$(top_builddir)/idl \
+       -I$(top_srcdir)/src/SMESH \
+       -I$(top_srcdir)/src/SMESH_I \
+       -I$(top_srcdir)/src/SMESHDS \
+       -I$(top_srcdir)/src/SMDS \
+       -I$(top_srcdir)/src/SMESHUtils \
+       $(VTK_INCLUDES) $(CAS_CPPFLAGS) $(BOOST_CPPFLAGS)
+
+libSPADDERPluginTesterEngine_la_LIBADD += \
+       $(top_builddir)/src/SMESH/libSMESHimpl.la \
+       $(top_builddir)/src/SMESH_I/libSMESHEngine.la \
+       $(top_builddir)/src/SMESHDS/libSMESHDS.la \
+       $(top_builddir)/src/SMDS/libSMDS.la \
+       $(top_builddir)/src/SMESHUtils/libSMESHUtils.la
+
diff --git a/src/Tools/padder/meshjob/impl/MeshJobManager_i.cxx b/src/Tools/padder/meshjob/impl/MeshJobManager_i.cxx
new file mode 100644 (file)
index 0000000..72520fb
--- /dev/null
@@ -0,0 +1,631 @@
+// Copyright (C) 2011-2012  EDF R&D
+//
+// 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.com
+//
+// Authors : Guillaume Boulant (EDF) - 01/03/2011
+
+#ifdef WIN32
+#include <winsock2.h>
+#include <windows.h> 
+#else
+#include <sys/time.h>
+#endif
+
+#include "MeshJobManager_i.hxx"
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SALOME_Exception)
+
+
+#include "Basics_Utils.hxx"         // For standard logging
+#undef LOG
+#include "SALOME_KernelServices.hxx"   // For CORBA logging
+#undef LOG
+
+#define LOG STDLOG
+
+//
+// ====================================================================
+// General purpose helper functions (to put elsewhere at least)
+// ====================================================================
+//
+
+/*!
+ * This function must be used to associate a datetime tag to a job
+ */
+
+#ifndef WIN32
+static long timetag() {
+  timeval tv;
+  gettimeofday(&tv,0);
+  long tag = tv.tv_usec + tv.tv_sec*1000000;
+  return tag;
+}
+#endif
+
+/*!
+ * This function returns true if the string text starts with the string
+ * token.
+ */
+static bool myStartsWith(const std::string& text,const std::string& token){     
+  if(text.length() < token.length())
+    return false;
+  return (text.compare(0, token.length(), token) == 0);
+}
+
+//
+// ====================================================================
+// Constructor/Destructor
+// ====================================================================
+//
+MeshJobManager_i::MeshJobManager_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)
+{
+  LOG("Activating MESHJOB::MeshJobManager object");
+  _thisObj = this ;
+  _id = _poa->activate_object(_thisObj);
+
+  _salomeLauncher   = KERNEL::getSalomeLauncher();
+  if(CORBA::is_nil(_salomeLauncher)){
+    LOG("The SALOME launcher can't be reached ==> STOP");
+    throw KERNEL::createSalomeException("SALOME launcher can't be reached");
+  }
+
+  _resourcesManager = KERNEL::getResourcesManager();
+  if(CORBA::is_nil(_resourcesManager)){
+    LOG("The SALOME resource manager can't be reached ==> STOP");
+    throw KERNEL::createSalomeException("The SALOME resource manager can't be reached");
+  }
+}
+
+MeshJobManager_i::~MeshJobManager_i() {
+  LOG("MeshJobManager_i::~MeshJobManager_i()");
+}
+
+//
+// ====================================================================
+// Helper functions to deals with the local and remote file systems
+// ====================================================================
+//
+#include <fstream>     // to get the file streams
+#ifdef WNT             
+#include <stdlib.h>    // to get _splitpath
+#include <direct.h>    // to get _mkdir
+#else
+#include <unistd.h>    // to get basename
+#include <sys/stat.h>  // to get mkdir
+#include <sys/types.h> // to get mkdir options
+#endif
+
+#include <stdlib.h>    // to get system and getenv
+
+static std::string OUTPUTFILE("output.med");
+static std::string DATAFILE("data.txt");
+static std::string SCRIPTFILE("padder.sh");
+static std::string SEPARATOR(" ");
+
+static std::string USER(getenv("USER"));
+static std::string LOCAL_INPUTDIR("/tmp/spadder.local.inputdir."+USER);
+static std::string LOCAL_RESULTDIR("/tmp/spadder.local.resultdir."+USER);
+static std::string REMOTE_WORKDIR("/tmp/spadder.remote.workdir."+USER);
+
+/*!
+ * This function creates the padder text input file containing the
+ * input data (list of filenames and groupnames) and returns the path
+ * of the created file. This function is the one that knows the format
+ * of the padder input file. If the input file format changes, then
+ * this function (and only this one) should be updated.
+ */
+const char * MeshJobManager_i::_writeDataFile(std::vector<MESHJOB::MeshJobParameter> listConcreteMesh,
+                                              std::vector<MESHJOB::MeshJobParameter> listSteelBarMesh) {
+#ifdef WIN32
+  _mkdir(LOCAL_INPUTDIR.c_str());
+#else
+  mkdir(LOCAL_INPUTDIR.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
+#endif
+
+  // Make it static so that it's allocated once (constant name)
+  static std::string * dataFilename = new std::string(LOCAL_INPUTDIR+"/"+DATAFILE);
+  std::ofstream dataFile(dataFilename->c_str());
+  
+  // We first specify the concrete mesh data (filename and groupname)
+  std::string line;
+#ifdef WIN32
+  char fname[ _MAX_FNAME ];
+  _splitpath( listConcreteMesh[0].file_name, NULL, NULL, fname, NULL );
+  char* bname = &fname[0];
+#else
+  char* bname = basename(listConcreteMesh[0].file_name);
+#endif
+  line = std::string(bname) + " " + std::string(listConcreteMesh[0].group_name);
+  dataFile << line.c_str() << std::endl;
+  // Note that we use here the basename because the files are supposed
+  // to be copied in the REMOTE_WORKDIR for execution.
+  
+  // The, we can specify the steelbar mesh data, starting by the
+  // number of meshes
+  int nbSteelBarMesh=listSteelBarMesh.size();
+  line = std::string("nbSteelbarMesh") + SEPARATOR + ToString(nbSteelBarMesh);
+  dataFile << line.c_str() << std::endl;
+  for (int i=0; i<nbSteelBarMesh; i++) {
+#ifdef WIN32
+        char fname[ _MAX_FNAME ];
+        _splitpath( listSteelBarMesh[i].file_name, NULL, NULL, fname, NULL );
+        char* bname = &fname[0];
+#else
+        char* bname = basename(listSteelBarMesh[i].file_name);
+#endif
+    line = std::string(bname) + " " + std::string(listSteelBarMesh[i].group_name);
+    dataFile << line.c_str() << std::endl;
+  }
+  
+  // Finally, we conclude with the name of the output file
+  line = OUTPUTFILE;
+  dataFile << line.c_str() << std::endl;
+  dataFile.close();
+  return dataFilename->c_str();  
+}
+
+/*!
+ * This function creates a shell script that runs padder whith the
+ * specified data file, and returns the path of the created script
+ * file. The config id is used to retrieve the path to the binary file
+ * and other required files.
+ */
+const char* MeshJobManager_i::_writeScriptFile(const char * dataFileName, const char * configId) {
+#ifdef WIN32
+  _mkdir(LOCAL_INPUTDIR.c_str());
+#else
+  mkdir(LOCAL_INPUTDIR.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
+#endif
+
+  // Make it static so that it's allocated once (constant name)
+  static std::string * scriptFilename = new std::string(LOCAL_INPUTDIR+"/"+SCRIPTFILE);
+
+  char * binpath = _configMap[configId].binpath;
+  char * envpath = _configMap[configId].envpath;
+
+#ifdef WIN32
+        char fname[ _MAX_FNAME ];
+        _splitpath( dataFileName, NULL, NULL, fname, NULL );
+        const char* bname = &fname[0];
+#else
+        const char* bname = basename(dataFileName);
+#endif
+
+
+  std::ofstream script(scriptFilename->c_str());
+  script << "#!/bin/sh"                                   << std::endl;
+  script << "here=$(dirname $0)"                          << std::endl;
+  script << ". " << envpath                               << std::endl;
+  script << binpath << " $here/" << bname                 << std::endl;
+  // Note that we use the basename of the datafile because all data
+  // files are supposed to have been copied in the REMOTE_WORKDIR.
+  script.close();
+  return scriptFilename->c_str();
+}
+
+//
+// ====================================================================
+// Functions to initialize and supervise the mesh computation job
+// ====================================================================
+//
+bool MeshJobManager_i::configure(const char *configId,
+                                 const MESHJOB::ConfigParameter & configParameter)
+{
+  beginService("MeshJobManager_i::configure");
+  
+  _configMap[configId] = configParameter;
+
+  LOG("Adding configuration for " << configId);
+  LOG("- binpath = " << _configMap[configId].binpath);
+  LOG("- envpath = " << _configMap[configId].envpath);
+
+  endService("MeshJobManager_i::configure");
+  return true;
+}
+
+long MeshJobManager_i::JOBID_UNDEFINED = -1;
+
+/*! Initialize a smesh computation job and return the job identifier */
+CORBA::Long MeshJobManager_i::initialize(const MESHJOB::MeshJobParameterList & meshJobParameterList,
+                                         const char * configId)
+{
+  beginService("MeshJobManager_i::initialize");
+  std::cerr << "##################################### initialize" << std::endl;
+  std::cerr << "#####################################" << std::endl;
+
+  //
+  // We first analyse the CORBA sequence to store data in C++ vectors
+  //
+  std::vector<MESHJOB::MeshJobParameter> listConcreteMesh;
+  std::vector<MESHJOB::MeshJobParameter> listSteelBarMesh;
+  for(CORBA::ULong i=0; i<meshJobParameterList.length(); i++) {
+    MESHJOB::MeshJobParameter currentMesh = meshJobParameterList[i];
+    switch ( currentMesh.file_type ) {
+    case MESHJOB::MED_CONCRETE:
+      listConcreteMesh.push_back(currentMesh);
+      break;
+    case MESHJOB::MED_STEELBAR:
+      listSteelBarMesh.push_back(currentMesh);
+      break;
+    default:
+      LOG("The type of the file is not recognized");
+      return JOBID_UNDEFINED;
+    }
+  }
+  
+  if ( listConcreteMesh.size() != 1 ) {
+    // Not consistent with the specification
+    LOG("You specify more than one concrete mesh");
+    return JOBID_UNDEFINED;
+  }
+  
+  LOG("Nb. concrete mesh = " << listConcreteMesh.size());
+  LOG("Nb. steelbar mesh = " << listSteelBarMesh.size());
+
+  // We initiate here a datetime to tag the files and folder
+  // associated to this job.
+#ifdef WIN32
+  DWORD jobDatetimeTag = timeGetTime();
+#else
+  long jobDatetimeTag = timetag();
+#endif
+  // And a MESHJOB::MeshJobPaths structure to hold the directories
+  // where to find data
+  MESHJOB::MeshJobPaths * jobPaths = new MESHJOB::MeshJobPaths();
+  jobPaths->local_inputdir  = LOCAL_INPUTDIR.c_str();
+  jobPaths->local_resultdir = (LOCAL_RESULTDIR + "." + ToString(jobDatetimeTag)).c_str();
+  jobPaths->remote_workdir  = (REMOTE_WORKDIR + "." + ToString(jobDatetimeTag)).c_str();  
+
+  //
+  // Then, we have to create the padder input data file. This input
+  // data is a text file containing the list of file names and group
+  // names.
+  //
+  const char * dataFilename = this->_writeDataFile(listConcreteMesh, listSteelBarMesh);
+  LOG("dataFilename = " << dataFilename);
+  const char * scriptFilename = this->_writeScriptFile(dataFilename, configId);
+  LOG("scriptFilename = " << scriptFilename);
+
+  //
+  // Then, the following instructions consists in preparing the job
+  // parameters to request the SALOME launcher for creating a new
+  // job.
+  //
+  Engines::JobParameters_var jobParameters = new Engines::JobParameters;
+  jobParameters->job_type = CORBA::string_dup("command");
+  // CAUTION: the job_file must be a single filename specifying a
+  // self-consistent script to be executed without any argument on the
+  // remote host.
+  jobParameters->job_file = CORBA::string_dup(scriptFilename);
+
+  //
+  // Specification of the working spaces:
+  //
+  // - local_directory: can be used to specify where to find the input
+  //   files on the local resource. It's optionnal if you specify the
+  //   absolute path name of input files.
+  //
+  // - result_directory: must be used to specify where to download the
+  //   output files on the local resources
+  //
+  // - work_directory: must be used to specify the remote directory
+  //   where to put all the stuff to run the job. Note that the job
+  //   will be executed from within this directory, i.e. a change
+  //   directory toward this working directory is done by the batch
+  //   system before running the specified job script.
+  //
+  jobParameters->local_directory  = CORBA::string_dup("");
+  jobParameters->result_directory = CORBA::string_dup(jobPaths->local_resultdir);
+  jobParameters->work_directory   = CORBA::string_dup(jobPaths->remote_workdir);
+
+  // We specify the input files that are required to execute the
+  // job_file. If basenames are specified, then the files are supposed
+  // to be located in local_directory.
+  int nbFiles = listSteelBarMesh.size()+2;
+  // The number of input file is: 
+  //   (nb. of steelbar meshfile)
+  // + (1 concrete meshfile)
+  // + (1 padder input file)
+  // = nb steelbar meshfile + 2
+  jobParameters->in_files.length(nbFiles);
+  jobParameters->in_files[0] = CORBA::string_dup(listConcreteMesh[0].file_name);
+  for (int i=0; i<listSteelBarMesh.size(); i++) {
+    jobParameters->in_files[1+i] = CORBA::string_dup(listSteelBarMesh[i].file_name);
+  }
+  jobParameters->in_files[1+listSteelBarMesh.size()] = CORBA::string_dup(dataFilename);
+  // Note that all these input files will be copied in the
+  // REMOTE_WORKDIR on the remote host
+  
+  // Then, we have to specify the existance of an output
+  // filenames. The path is supposed to be a path on the remote
+  // resource, i.e. where the job is executed.
+  jobParameters->out_files.length(1);
+  std::string outputfile_name = std::string(jobPaths->remote_workdir)+"/"+OUTPUTFILE;
+  jobParameters->out_files[0] = CORBA::string_dup(outputfile_name.c_str());
+
+  // CAUTION: the maximum duration has to be set with a format like "hh:mm"
+  jobParameters->maximum_duration = CORBA::string_dup("01:00");
+  jobParameters->queue = CORBA::string_dup("");
+
+  // Setting resource and additionnal properties (if needed)
+  // The resource parameters can be initiated from scratch, for
+  // example by specifying the values in hard coding:
+  // >>>
+  //jobParameters->resource_required.name = CORBA::string_dup("localhost");
+  //jobParameters->resource_required.hostname = CORBA::string_dup("localhost");
+  //jobParameters->resource_required.mem_mb = 1024 * 10;
+  //jobParameters->resource_required.nb_proc = 1;
+  // <<<
+  // But it's better to initiate these parameters from a resource
+  // definition known by the resource manager. This ensures that the
+  // resource will be available:
+  //const char * resourceName = "localhost";
+  //const char * resourceName = "boulant@claui2p1";
+  //const char * resourceName = "nepal@nepal";
+  const char * resourceName = _configMap[configId].resname;
+  Engines::ResourceDefinition * resourceDefinition = _resourcesManager->GetResourceDefinition(resourceName);
+  // CAUTION: This resource should have been defined in the
+  // CatalogResource.xml associated to the SALOME application.
+  //
+  // Then, the values can be used to initiate the resource parameters
+  // of the job:
+  jobParameters->resource_required.name     = CORBA::string_dup(resourceDefinition->name.in());
+  // CAUTION: the additionnal two following parameters MUST be
+  // specified explicitly, because they are not provided by the
+  // resource definition:
+  jobParameters->resource_required.mem_mb   = resourceDefinition->mem_mb;
+  jobParameters->resource_required.nb_proc  = resourceDefinition->nb_proc_per_node;
+  // CAUTION: the parameter mem_mb specifies the maximum memory value
+  // that could be allocated for executing the job. This takes into
+  // account not only the data that could be loaded by the batch
+  // process but also the linked dynamic library.
+  //
+  // A possible problem, for exemple in the case where you use the ssh
+  // emulation of a batch system, is to get an error message as below
+  // when libBatch try to run the ssh command:
+  //
+  // ## /usr/bin/ssh: error while loading shared libraries: libcrypto.so.0.9.8: failed
+  // ## to map segment from shared object: Cannot allocate memory
+  //
+  // In this exemple, the mem_mb was set to 1MB, value that is not
+  // sufficient to load the dynamic libraries linked to the ssh
+  // executable (libcrypto.so in the error message).
+  //
+  // So, even in the case of a simple test shell script, you should
+  // set this value at least to a standard threshold as 500MB
+
+  int jobId = JOBID_UNDEFINED;
+  try {
+    std::cerr << "#####################################" << std::endl;
+    std::cerr << "#####################################" << std::endl;
+    std::cerr << "jobUndef = " << JOBID_UNDEFINED << std::endl;
+    jobId = _salomeLauncher->createJob(jobParameters);
+    std::cerr << "#####################################" << std::endl;
+    std::cerr << "#####################################" << std::endl;
+    std::cerr << "#####################################" << std::endl;
+    std::cerr << "jobId = " << jobId << std::endl;
+    // We register the datetime tag of this job
+    _jobDateTimeMap[jobId]=jobDatetimeTag;
+    _jobPathsMap[jobId] = jobPaths;
+  }
+  catch (const SALOME::SALOME_Exception & ex) {
+    LOG("SALOME Exception in createJob !" <<ex.details.text.in());
+    //LOG(ex.details.text.in());
+    return JOBID_UNDEFINED;
+  }
+  catch (const CORBA::SystemException& ex) {
+    LOG("Receive SALOME System Exception: "<<ex);
+    LOG("Check SALOME servers...");
+    return JOBID_UNDEFINED;
+  }
+  
+  endService("MeshJobManager_i::initialize");
+  return jobId;
+}
+
+/*! Submit the job execution and return true if submission is OK */
+bool MeshJobManager_i::start(CORBA::Long jobId) {
+  beginService("MeshJobManager_i::start");
+
+  try {
+    _salomeLauncher->launchJob(jobId);
+  }
+  catch (const SALOME::SALOME_Exception & ex) {
+    LOG("SALOME Exception in launchjob !" <<ex.details.text.in());
+    //LOG(ex.details.text.in());
+    return false;
+  }
+  catch (const CORBA::SystemException& ex) {
+    LOG("Receive SALOME System Exception: "<<ex);
+    LOG("Check SALOME servers...");
+    return false;
+  }
+
+  endService("MeshJobManager_i::initialize");
+  return true;
+}
+
+/*! Request the launch manager for the state of the specified job */
+char* MeshJobManager_i::getState(CORBA::Long jobId) {
+  beginService("MeshJobManager_i::getState");
+
+  std::string state;
+  try
+  {
+    state = _salomeLauncher->getJobState(jobId);
+  }
+  catch (const SALOME::SALOME_Exception & ex)
+  {
+    LOG("SALOME Exception in getJobState !");
+    state = ex.details.text;
+  }
+  catch (const CORBA::SystemException& ex)
+  {
+    LOG("Receive SALOME System Exception: " << ex);
+    state="SALOME System Exception - see logs";
+  }
+  LOG("jobId="<<ToString(jobId)<<" state="<<state);
+  endService("MeshJobManager_i::getState");
+  return CORBA::string_dup(state.c_str());
+}
+
+MESHJOB::MeshJobPaths * MeshJobManager_i::getPaths(CORBA::Long jobId) {
+
+  MESHJOB::MeshJobPaths * jobPaths = _jobPathsMap[jobId];
+  if ( jobPaths == NULL ) {
+    LOG("You request the working paths for an undefined job (jobId="<<ToString(jobId)<<")");
+    return NULL; // Maybe raise an exception?
+  }
+  return jobPaths;
+}
+
+
+MESHJOB::MeshJobResults * MeshJobManager_i::finalize(CORBA::Long jobId) {
+  beginService("MeshJobManager_i::getResults");
+  MESHJOB::MeshJobResults * result = new MESHJOB::MeshJobResults();
+
+  MESHJOB::MeshJobPaths * jobPaths = this->getPaths(jobId);
+  std::string local_resultdir(jobPaths->local_resultdir);
+  result->results_dirname = local_resultdir.c_str();  
+  try
+  {
+    _salomeLauncher->getJobResults(jobId, local_resultdir.c_str());
+    // __BUG__: to prevent from a bug of the MED driver (SALOME
+    // 5.1.5), we change the basename of the output file to force the
+    // complete reloading of data by the med driver.
+    long jobDatetimeTag = _jobDateTimeMap[jobId];
+    std::string outputFileName = "output"+ToString(jobDatetimeTag)+".med";
+    rename((local_resultdir+"/"+OUTPUTFILE).c_str(), (local_resultdir+"/"+outputFileName).c_str());
+
+    result->outputmesh_filename = outputFileName.c_str();
+    result->status = "OK";
+ }
+  catch (const SALOME::SALOME_Exception & ex)
+  {
+    LOG("SALOME Exception in getResults !");
+    result->status = "SALOME Exception in getResults !";
+  }
+  catch (const CORBA::SystemException& ex)
+  {
+    LOG("Receive CORBA System Exception: " << ex);
+    result->status = "Receive CORBA System Exception: see log";
+  }
+  endService("MeshJobManager_i::getResults");
+  return result;
+}
+
+
+/*! Clean all data associated to this job and remove the job from the launch manager */
+bool MeshJobManager_i::clean(CORBA::Long jobId) {
+  beginService("MeshJobManager_i::clean");
+  
+  // __GBO__ WORK IN PROGRESS: we just clean the temporary local
+  // directories. The remote working directories are tag with the
+  // execution datetime and the we prevent the task from conflict
+  // with files of another task.
+  MESHJOB::MeshJobPaths * jobPaths = this->getPaths(jobId);
+  if ( jobPaths == NULL ) return false;
+
+  // WARN: !!!!!
+  // For safety reason (and prevent from bug that could erase the
+  // filesystem), we cancel the operation in the case where the
+  // directories to delete are not in the /tmp folder.
+  std::string shell_command("rm -rf ");
+  std::string inputdir(jobPaths->local_inputdir);
+  std::string resultdir(jobPaths->local_resultdir);
+  if ( !myStartsWith(inputdir,"/tmp/") )  {
+    LOG("WRN: The directory "<<inputdir<<" is not in /tmp. NO DELETE is done");
+  } else {
+    shell_command+=inputdir+" ";
+  }
+  if ( !myStartsWith(resultdir,"/tmp/"))  {
+    LOG("WRN: The directory "<<resultdir<<" is not in /tmp. NO DELETE is done");
+  } else {
+    shell_command+=resultdir;
+  }
+
+  LOG("DBG: clean shell command = "<<shell_command);
+
+  bool cleanOk = false;
+  int error = system(shell_command.c_str());
+  if (error == 0) cleanOk = true;
+
+  endService("MeshJobManager_i::clean");
+  return cleanOk;
+}
+
+
+std::vector<std::string> * MeshJobManager_i::_getResourceNames() {
+
+  //
+  // These part is just to control the available resources
+  //
+  Engines::ResourceParameters params;
+  KERNEL::getLifeCycleCORBA()->preSet(params);
+
+  Engines::ResourceList * resourceList = _resourcesManager->GetFittingResources(params);
+  Engines::ResourceDefinition * resourceDefinition = NULL;
+  LOG("### resource list:");
+  std::vector<std::string>* resourceNames = new std::vector<std::string>();
+  if (resourceList) {
+    for (int i = 0; i < resourceList->length(); i++) {
+      const char* aResourceName = (*resourceList)[i];
+      resourceNames->push_back(std::string(aResourceName));
+      LOG("resource["<<i<<"] = "<<aResourceName);
+      resourceDefinition = _resourcesManager->GetResourceDefinition(aResourceName);
+      LOG("protocol["<<i<<"] = "<<resourceDefinition->protocol);
+    }
+  }
+
+  // Note: a ResourceDefinition is used to create a batch configuration
+  // in the Launcher. This operation is done at Launcher startup from
+  // the configuration file CatalogResources.xml provided by the
+  // SALOME application.
+  // In the code instructions, you just have to choose a resource
+  // configuration by its name and then define the ResourceParameters
+  // that specify additionnal properties for a specific job submission
+  // (use the attribute resource_required of the JobParameters).
+
+  return resourceNames;
+}
+
+
+//
+// ==========================================================================
+// Factory services
+// ==========================================================================
+//
+extern "C"
+{
+  PortableServer::ObjectId * MeshJobManagerEngine_factory( CORBA::ORB_ptr orb,
+                                                           PortableServer::POA_ptr poa,
+                                                           PortableServer::ObjectId * contId,
+                                                           const char *instanceName,
+                                                           const char *interfaceName)
+  {
+    LOG("PortableServer::ObjectId * MeshJobManagerEngine_factory()");
+    MeshJobManager_i * myEngine = new MeshJobManager_i(orb, poa, contId, instanceName, interfaceName);
+    return myEngine->getId() ;
+  }
+}
diff --git a/src/Tools/padder/meshjob/impl/MeshJobManager_i.hxx b/src/Tools/padder/meshjob/impl/MeshJobManager_i.hxx
new file mode 100644 (file)
index 0000000..283a92d
--- /dev/null
@@ -0,0 +1,81 @@
+// Copyright (C) 2011-2012  EDF R&D
+//
+// 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.com
+//
+// Authors : Guillaume Boulant (EDF) - 01/03/2011
+
+#ifndef _MESHJOBMANAGER_HXX_
+#define _MESHJOBMANAGER_HXX_
+
+// include the stubs generating from MESHJOB.idl
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(MESHJOB)
+#include CORBA_SERVER_HEADER(SALOME_Component)
+#include "SALOME_Component_i.hxx"
+
+#include "SALOME_Launcher.hxx"
+#include <vector>
+#include <string>
+#include <map>
+
+class MeshJobManager_i: public virtual POA_MESHJOB::MeshJobManager,
+                        public Engines_Component_i
+{
+public:
+  MeshJobManager_i(CORBA::ORB_ptr orb, PortableServer::POA_ptr poa,
+                   PortableServer::ObjectId * contId,
+                   const char *instanceName, const char *interfaceName);
+  ~MeshJobManager_i();
+
+  bool           configure  (const char *configId,
+                            const MESHJOB::ConfigParameter & configParameter);
+  CORBA::Long    initialize (const MESHJOB::MeshJobParameterList & meshJobParameterList,
+                            const char *configId);
+  bool           start      (CORBA::Long jobId);
+  char*          getState   (CORBA::Long jobId);
+  MESHJOB::MeshJobResults * finalize(CORBA::Long jobId);
+  MESHJOB::MeshJobPaths *   getPaths(CORBA::Long jobId);
+  bool           clean      (CORBA::Long jobId);
+
+  static long JOBID_UNDEFINED;
+
+private:
+  Engines::SalomeLauncher_var   _salomeLauncher;
+  Engines::ResourcesManager_var _resourcesManager;
+  
+  // This maps the config identifier to the config parameters. A
+  // config is a resource with additionnal data specifying the
+  // location of the binary program to be executed by the task
+  std::map<std::string, MESHJOB::ConfigParameter> _configMap;
+
+  // This maps a job identifier to its associated datetime tag. When
+  // a job is created during the initialize function, a datetime tag
+  // is associated to this job and can be used to characterized files
+  // and directories associated to this job.
+  std::map<long, long> _jobDateTimeMap;
+  std::map<long, MESHJOB::MeshJobPaths*> _jobPathsMap;
+
+  const char* _writeDataFile   (std::vector<MESHJOB::MeshJobParameter> listConcreteMesh,
+                                std::vector<MESHJOB::MeshJobParameter> listSteelBarMesh);
+  const char* _writeScriptFile (const char * dataFileName, const char * configId);
+
+  std::vector<std::string> * _getResourceNames();
+
+};
+
+#endif
+
diff --git a/src/Tools/padder/meshjob/impl/SPADDERPluginTester_i.cxx b/src/Tools/padder/meshjob/impl/SPADDERPluginTester_i.cxx
new file mode 100644 (file)
index 0000000..805eb4f
--- /dev/null
@@ -0,0 +1,157 @@
+// Copyright (C) 2011-2012  CEA/DEN, EDF R&D
+//
+// 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.com
+//
+// Authors : Guillaume Boulant (EDF) - 01/03/2011
+
+#include "SPADDERPluginTester_i.hxx"
+
+#include <SALOME_NamingService.hxx>
+#include <Utils_SALOME_Exception.hxx>
+
+// For standard logging
+#include "Basics_Utils.hxx"
+
+//
+// ==========================================================================
+// Implementation of the SPADDER component interface
+// ==========================================================================
+//
+using namespace std;
+
+/*!
+ * Constructor for component "SPADDER" instance
+ */
+SPADDERPluginTester_i::SPADDERPluginTester_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)
+{
+  LOG("Activating SPADDERPluginTester_i::SPADDERPluginTester object");
+  _thisObj = this ;
+  _id = _poa->activate_object(_thisObj);
+}
+
+//! Destructor for component "SPADDER" instance
+SPADDERPluginTester_i::~SPADDERPluginTester_i()
+{
+  std::cerr << "SPADDERPluginTester destruction" << std::endl;
+}
+
+/*!
+ * This test is just to check the component SPADDER.
+ */
+void SPADDERPluginTester_i::demo(CORBA::Double a,CORBA::Double b,CORBA::Double& c)
+{
+  beginService("SPADDERPluginTester_i::demo");
+  try {
+    //BODY
+    
+    std::cerr << "a: " << a << std::endl;
+    std::cerr << "b: " << b << std::endl;
+    c=a+b;
+    std::cerr << "c: " << c << std::endl;
+    
+  }
+  catch ( const SALOME_Exception & ex) {
+    SALOME::ExceptionStruct es;
+    es.text=CORBA::string_dup(ex.what());
+    es.type=SALOME::INTERNAL_ERROR;
+    throw SALOME::SALOME_Exception(es);
+  }
+  catch ( const SALOME::SALOME_Exception & ex) {
+    throw;
+  }
+  catch (...) {
+    std::cerr << "unknown exception" << std::endl;
+    SALOME::ExceptionStruct es;
+    es.text=CORBA::string_dup(" unknown exception");
+    es.type=SALOME::INTERNAL_ERROR;
+    throw SALOME::SALOME_Exception(es);
+  }
+  endService("SPADDERPluginTester_i::demo");
+}
+
+#ifdef LOG
+#undef LOG
+#endif
+
+#include <SALOME_KernelServices.hxx>
+#include "SALOME_Launcher.hxx"
+bool SPADDERPluginTester_i::testkernel()
+{
+  beginService("SPADDERPluginTester_i::testplugin");
+
+  Engines::SalomeLauncher_ptr salomeLauncher = KERNEL::getSalomeLauncher();
+
+  endService("SPADDERPluginTester_i::testplugin");
+  return true;
+}
+
+
+#include <SMESH_Gen_i.hxx>
+#include <SMESH_Gen.hxx>
+#include <SALOMEconfig.h>
+#include CORBA_CLIENT_HEADER(SALOMEDS)
+
+#include <utilities.h>
+
+/*!
+ * This test checks the constructor of the basic classes of the SMESH
+ * plugin for PADDER.
+ */
+bool SPADDERPluginTester_i::testsmesh(CORBA::Long studyId)
+{
+  beginService("SPADDERPluginTester_i::testsmesh");
+
+  // Resolve the SMESH engine and the SALOME study
+  // _WARN_ The SMESH engine should have been loaded first
+  SMESH_Gen_i* smeshGen_i = SMESH_Gen_i::GetSMESHGen();
+  CORBA::Object_var anObject = smeshGen_i->GetNS()->Resolve("/myStudyManager");
+  SALOMEDS::StudyManager_var aStudyMgr = SALOMEDS::StudyManager::_narrow(anObject);
+  SALOMEDS::Study_var myStudy = aStudyMgr->GetStudyByID(studyId);
+
+  //
+  // _MEM_ CAUTION: SMESH_Gen define a data structure for local usage
+  // while SMESH_Gen_i is the implementation of the SMESH_Gen IDL
+  // interface.
+  //
+
+  endService("SPADDERPluginTester_i::testsmesh");
+  return true;
+}
+
+//
+// ==========================================================================
+// Factory services
+// ==========================================================================
+//
+extern "C"
+{
+  PortableServer::ObjectId * SPADDERPluginTesterEngine_factory( CORBA::ORB_ptr orb,
+                                                                PortableServer::POA_ptr poa,
+                                                                PortableServer::ObjectId * contId,
+                                                                const char *instanceName,
+                                                                const char *interfaceName)
+  {
+    MESSAGE("PortableServer::ObjectId * SPADDERPluginTesterEngine_factory()");
+    SPADDERPluginTester_i * myEngine = new SPADDERPluginTester_i(orb, poa, contId, instanceName, interfaceName);
+    return myEngine->getId() ;
+  }
+}
diff --git a/src/Tools/padder/meshjob/impl/SPADDERPluginTester_i.hxx b/src/Tools/padder/meshjob/impl/SPADDERPluginTester_i.hxx
new file mode 100644 (file)
index 0000000..26a7416
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright (C) 2011-2012  CEA/DEN, EDF R&D
+//
+// 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.com
+//
+// Authors : Guillaume Boulant (EDF) - 01/03/2011
+
+#ifndef _SPADDER_PLUGINTESTER_HXX_
+#define _SPADDER_PLUGINTESTER_HXX_
+
+// include the stubs generating from SPADDERPluginTest.idl
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SPADDERPluginTest)
+#include <SALOME_Component.hh>
+#include "SALOME_Component_i.hxx"
+
+class SPADDERPluginTester_i:
+  public virtual POA_SPADDERPluginTest::SPADDERPluginTester,
+  public Engines_Component_i
+{
+public:
+  SPADDERPluginTester_i(CORBA::ORB_ptr orb, PortableServer::POA_ptr poa,
+                       PortableServer::ObjectId * contId,
+                       const char *instanceName, const char *interfaceName);
+  virtual ~SPADDERPluginTester_i();
+  
+  void demo(CORBA::Double a,CORBA::Double b,CORBA::Double& c);
+  bool testkernel();
+  bool testsmesh(CORBA::Long studyId);
+
+};
+
+#endif
+
diff --git a/src/Tools/padder/meshjob/impl/testhelper.hxx b/src/Tools/padder/meshjob/impl/testhelper.hxx
new file mode 100644 (file)
index 0000000..adc7fdf
--- /dev/null
@@ -0,0 +1,66 @@
+// Copyright (C) 2011-2012  CEA/DEN, EDF R&D
+//
+// 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.com
+//
+// Authors : Guillaume Boulant (EDF) - 01/03/2011
+
+#ifndef __TESTHELPER_HXX__
+#define __TESTHELPER_HXX__
+
+// >>>
+// WARN: this file is DEPRECATED and/or should be used for test
+// purpose only. The PADDER configuration is now read in a
+// configuration file (padder.cfg).
+// <<<
+
+#include <stdlib.h> // Standard C include (for getenv)
+#include <unistd.h>
+#include <string>
+
+/*!
+ * This function returns the module SMESH installation root directory
+ * as a string.
+ */
+static std::string SMESH_ROOT_DIR() {
+  static std::string * smesh_root_dir;
+  if ( smesh_root_dir == NULL ) {
+    char * SMESH_ROOT_DIR = getenv("SMESH_ROOT_DIR");
+    if ( SMESH_ROOT_DIR == NULL ) {
+      smesh_root_dir = new std::string("<path_undefined>");
+    }
+    else {
+      smesh_root_dir = new std::string(SMESH_ROOT_DIR);
+    }
+  }
+  return *smesh_root_dir;
+}
+
+/*! Relative path of the directory containing data and exe for tests */
+static std::string PADDEREXE_RPATH("/share/salome/resources/smesh/padderexe");
+/*! Absolute path of the directory containing data and exe for tests */
+static std::string PADDEREXE_APATH(SMESH_ROOT_DIR()+PADDEREXE_RPATH);
+/*! Absolute path of the exe shell script for tests */
+static std::string PADDEREXE_SCRIPT_FILENAME(PADDEREXE_APATH+"/padder.sh");
+
+
+static int testssh_using_system() {
+  const char * cmd = "/usr/bin/ssh claui2p1 -l boulant 'cd /tmp && ./runCommand_padder_Mon_Feb_28_14_28_36_2011.sh'";
+  int result = system(cmd);
+  return result;
+}
+
+#endif // __TESTHELPER_HXX__
diff --git a/src/Tools/padder/resources/Makefile.am b/src/Tools/padder/resources/Makefile.am
new file mode 100644 (file)
index 0000000..207faad
--- /dev/null
@@ -0,0 +1,25 @@
+# Copyright (C) 2011-2012  CEA/DEN, EDF R&D
+#
+# 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.com
+#
+
+SUBDIRS = appligen padderexe
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+mysalomeresdir=$(salomeresdir)
+dist_mysalomeres_DATA = SPADDERCatalog.xml
diff --git a/src/Tools/padder/resources/SPADDERCatalog.xml b/src/Tools/padder/resources/SPADDERCatalog.xml
new file mode 100644 (file)
index 0000000..4e4cafe
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version='1.0' encoding='us-ascii' ?>
+
+<!-- XML component catalog -->
+
+<begin-catalog>
+    <path-prefix-list></path-prefix-list>
+    <type-list></type-list>
+    <component-list>
+        <component>
+            <component-name>MeshJobManager</component-name>
+        </component>
+        <component>
+            <component-name>SPADDERPluginTester</component-name>
+        </component>
+    </component-list>
+</begin-catalog>
diff --git a/src/Tools/padder/resources/appligen/CatalogResources.xml b/src/Tools/padder/resources/appligen/CatalogResources.xml
new file mode 100644 (file)
index 0000000..4900b5f
--- /dev/null
@@ -0,0 +1,21 @@
+<!DOCTYPE ResourcesCatalog>
+<resources>
+
+   <!-- Generic configuration that should works on every workstation -->
+   <machine name="localhost" hostname="localhost"
+            protocol="ssh" batch="ssh_batch"
+            memInMB="500" CPUFreqMHz="0" nbOfNodes="1" nbOfProcPerNode="1"/>
+
+   <!-- Specific configuration that only works on my workstation (needs ssh authentification) -->
+   <machine name="boulant@claui2p1" 
+            hostname="claui2p1" userName="boulant"
+            protocol="ssh" batch="ssh_batch"
+            memInMB="500" CPUFreqMHz="0" nbOfNodes="1" nbOfProcPerNode="1"/>
+
+   <!-- Specific configuration that only works for nepal team (needs ssh authentification) -->
+   <machine name="nepal@nepal" 
+            hostname="nepal" userName="nepal"
+            protocol="ssh" batch="ssh_batch"
+            memInMB="500" CPUFreqMHz="0" nbOfNodes="1" nbOfProcPerNode="1"/>
+
+</resources>
diff --git a/src/Tools/padder/resources/appligen/Makefile.am b/src/Tools/padder/resources/appligen/Makefile.am
new file mode 100644 (file)
index 0000000..c22ab65
--- /dev/null
@@ -0,0 +1,40 @@
+# Copyright (C) 2011-2012  CEA/DEN, EDF R&D
+#
+# 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.com
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+appligendir = $(salomeresdir)/appligen
+
+dist_appligen_DATA=            \
+       appli-splashscreen.jpg \
+       SalomeApp.xml          \
+       CatalogResources.xml
+
+nodist_appligen_DATA=          \
+       envappli.sh            \
+       config_appli.xml
+
+nodist_appligen_SCRIPTS= \
+       appligen.sh
+
+envappli.sh:
+       $(srcdir)/genenv.sh envappli.sh
+
+EXTRA_DIST += README.txt genenv.sh
+CLEANFILES  = envappli.sh
diff --git a/src/Tools/padder/resources/appligen/README.txt b/src/Tools/padder/resources/appligen/README.txt
new file mode 100644 (file)
index 0000000..6fb376c
--- /dev/null
@@ -0,0 +1,24 @@
+This package defines a build procedure that creates a
+set of files ready to use to generate a SALOME application
+embedding this module.
+
+The files are created in the directory:
+
+  <installdir>/share/salome/resources/<module_name>/appligen
+
+Where <installdir> is the installation directory of the module.
+
+To generate a SALOME application, just change directory to go
+where you want to install the SALOME application and type the
+following command in a standard shell (the SALOME environment
+is not required, all paths are "hard" coded in the script):
+
+  $ <installdir>/share/salome/resources/<module_name>/appligen/appligen.sh 
+
+This script generates an application in a directory ./appli.
+Then type the following command to run a SALOME application
+embedding your module:
+
+  $ ./appli/runAppli -k
+
+
diff --git a/src/Tools/padder/resources/appligen/SalomeApp.xml b/src/Tools/padder/resources/appligen/SalomeApp.xml
new file mode 100644 (file)
index 0000000..87ca362
--- /dev/null
@@ -0,0 +1,40 @@
+<document>
+  <section name="launch">
+    <!-- SALOME launching parameters -->
+    <parameter name="gui"        value="yes"/>
+    <parameter name="splash"     value="yes"/>
+    <parameter name="file"       value="no"/>
+    <parameter name="key"        value="no"/>
+    <parameter name="interp"     value="no"/>
+    <parameter name="logger"     value="no"/>
+    <parameter name="xterm"      value="no"/>
+    <parameter name="portkill"   value="no"/>
+    <parameter name="killall"    value="no"/>
+    <parameter name="noexcepthandler"  value="no"/>
+    <parameter name="modules"    value="KERNEL,MED,GUI,GEOM,SMESH,JOBMANAGER,VISU,YACS"/>
+    <parameter name="pyModules"  value=""/>
+    <parameter name="embedded"   value="SalomeAppEngine,study,cppContainer,registry,moduleCatalog"/>
+    <parameter name="standalone" value="pyContainer"/>
+  </section>
+  <section name="SMESH">
+    <parameter name="plugins" value="NETGENPlugin,GHS3DPlugin,BLSURFPlugin"/>
+  </section>
+  <section name="splash" >
+    <!-- Splash screen settings. This only works when using a SALOME application, -->
+    <!-- where the file appli-splashscreen.jpg has been copy into. -->
+    <parameter name="image"             value="${SMESH_ROOT_DIR}/share/salome/resources/smesh/appligen/appli-splashscreen.jpg" />
+    <parameter name="constant_info"     value="%A [ %V ]" />
+    <parameter name="text_colors"       value="#eeeeff|#555555" />
+    <parameter name="hide_on_click"     value="no" />
+    <parameter name="show_progress"     value="yes" />
+    <parameter name="show_message"      value="yes" />
+    <parameter name="show_percents"     value="yes" />
+    <parameter name="margin"            value="40" />
+    <parameter name="progress_width"    value="20" />
+    <parameter name="progress_flags"    value="bottom,left_to_right" />
+    <parameter name="opacity"           value="0.70" />
+    <parameter name="font"              value="Tahoma,12,normal" />
+    <parameter name="alignment"         value="top,left" />
+    <parameter name="progress_colors"   value="#3b3e5d|#d14949|v" />
+  </section>
+</document>
diff --git a/src/Tools/padder/resources/appligen/appli-splashscreen.jpg b/src/Tools/padder/resources/appligen/appli-splashscreen.jpg
new file mode 100644 (file)
index 0000000..45377b1
Binary files /dev/null and b/src/Tools/padder/resources/appligen/appli-splashscreen.jpg differ
diff --git a/src/Tools/padder/resources/appligen/appligen.sh.in b/src/Tools/padder/resources/appligen/appligen.sh.in
new file mode 100755 (executable)
index 0000000..a27a3eb
--- /dev/null
@@ -0,0 +1,50 @@
+#!/bin/sh
+# Copyright (C) 2011-2012  CEA/DEN, EDF R&D
+#
+# 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.com
+#
+
+# 
+# This script installs or updates a SALOME application for testing the
+# PADDER plugin for SMESH. The application is installed in the
+# directory ./appli. The configuration file is supposed to be adapted
+# to your own environment (see config_appli.xml).
+#
+# To run this script, you should have first configure your
+# shell with the SALOME environment, i.e. source the files
+# prerequis.sh and envSalome.sh (or equivalent) that fit
+# your configuration. You can alternatively customize the env.sh file
+# to fit your SALOME environment and let the script do the job (see
+# source below).
+#
+# (gboulant - 3/2/2011)
+#
+
+here=$(dirname $0)
+
+#
+# Run the appli_gen.py
+#
+APPLIDIR="./appli"
+@KERNEL_ROOT_DIR@/bin/salome/appli_gen.py --prefix=$APPLIDIR --config=$here/config_appli.xml
+
+#
+# Copy customized configuration files in the application
+#
+cp $here/SalomeApp.xml $APPLIDIR/.
+cp $here/CatalogResources.xml $APPLIDIR/.
+cp @prefix@/plugins/envPlugins.sh $APPLIDIR/env.d/.
diff --git a/src/Tools/padder/resources/appligen/config_appli.xml.in b/src/Tools/padder/resources/appligen/config_appli.xml.in
new file mode 100644 (file)
index 0000000..2f77f06
--- /dev/null
@@ -0,0 +1,15 @@
+<application>
+<!-- The path should be the absolute path of installation of the file envappli.sh -->
+<prerequisites path="@prefix@/share/salome/resources/@MODULE_NAME@/appligen/envappli.sh"/>
+
+<modules>
+  <module name="KERNEL" path="@KERNEL_ROOT_DIR@"/>
+  <module name="MED" path="@MED_ROOT_DIR@"/>
+  <module name="GUI" path="@GUI_ROOT_DIR@"/>
+  <module name="GEOM" path="@GEOM_ROOT_DIR@"/>
+  <module name="SMESH" path="@prefix@"/>
+  <module name="BLSURFPLUGIN" gui="no" path="@BLSURFPLUGIN_ROOT_DIR@"/>
+  <module name="GHS3DPLUGIN" gui="no" path="@GHS3DPLUGIN_ROOT_DIR@"/>
+  <module name="NETGENPLUGIN" gui="no" path="@NETGENPLUGIN_ROOT_DIR@"/>
+</modules>
+</application>
diff --git a/src/Tools/padder/resources/appligen/genenv.sh b/src/Tools/padder/resources/appligen/genenv.sh
new file mode 100755 (executable)
index 0000000..c4d5dc5
--- /dev/null
@@ -0,0 +1,60 @@
+#!/bin/bash
+
+# Copyright (C) 2011-2012  CEA/DEN, EDF R&D
+#
+# 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.com
+#
+
+# This script creates a source file that defines a SALOME shell
+# environment. We assume here that the SALOME environment has been
+# previously set, so that the env command get all environment
+# variables required for building and executing SALOME. We talk
+# about third party software programs and libraries. The environment
+# variables defining SALOME module are exluded (i.e. *_ROOT_DIR)
+# because they are automatically set when generating a SALOME application..
+#
+# The argument is the filepath to be created.
+#
+
+if [ $# == 1 ]; then
+    ENVAPPLI_SH=$1
+else
+    ENVAPPLI_SH=envappli.sh
+fi
+
+function header {
+    echo "#"
+    echo "# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
+    echo "# THIS FILE IS GENERATED from the shell environment used to build the SALOME module."
+    echo "# IT SHOULD NOT BE EDITED, it is generated for the need of the SALOME application   "
+    echo "# that embeds the module (for test purposes).                                       "
+    echo "# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
+    echo "#"
+}
+header > $ENVAPPLI_SH
+env | grep -v -e PWD -e SalomeAppConfig -e _ROOT_DIR | while read f; do
+    key=$(echo $f | cut -d"=" -f1)
+    value=$(echo $f | cut -d"=" -f2-)
+
+    # if the key is a path (LD_LIBRARY_PATH, PATH and PYTHONPATH) then
+    # we must extends the variable.
+    if [ $key == "LD_LIBRARY_PATH" -o $key == "PATH" -o $key == "PYTHONPATH" ]; then
+        echo export $key=\"$value:\$$key\"
+    else
+        echo export $key=\"$value\"
+    fi
+done >> $ENVAPPLI_SH
diff --git a/src/Tools/padder/resources/padderexe/Makefile.am b/src/Tools/padder/resources/padderexe/Makefile.am
new file mode 100644 (file)
index 0000000..1388ede
--- /dev/null
@@ -0,0 +1,42 @@
+# Copyright (C) 2011-2012  CEA/DEN, EDF R&D
+#
+# 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.com
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+mysalomeresdir=$(salomeresdir)/padderexe
+
+version=med3
+notinstall_version=med2
+
+# We install the padder.exe program and the files required for testing
+# the execution from within the installation directory
+dist_mysalomeres_SCRIPTS =    \
+       $(version)/padder.exe \
+       padder.sh
+
+nodist_mysalomeres_SCRIPTS =         \
+       envPadder.sh
+
+dist_mysalomeres_DATA =         \
+       $(version)/data.txt     \
+       $(version)/concrete.med \
+       $(version)/ferraill.med
+
+NOT_USED_FILES = buildparticules.py particules.png
+EXTRA_DIST += $(notinstall_version) $(NOT_USED_FILES)
diff --git a/src/Tools/padder/resources/padderexe/buildparticules.py b/src/Tools/padder/resources/padderexe/buildparticules.py
new file mode 100755 (executable)
index 0000000..04035f1
--- /dev/null
@@ -0,0 +1,42 @@
+#!/usr/bin/env python
+# Copyright (C) 2011-2012  CEA/DEN, EDF R&D
+#
+# 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.com
+#
+
+import geompy
+import salome
+salome.salome_init()
+theStudy = salome.myStudy
+geompy.init_geom(theStudy)
+
+filename="/home/gboulant/development/projets/salome/SPADDER/spadder/resources/padderexe/REF_spheres.dat.xyz"
+file=open(filename,'rb')
+
+import csv
+datalines = csv.reader(file, delimiter=' ')
+i=0
+for row in datalines:
+    x=float(row[0])
+    y=float(row[1])
+    z=float(row[2])
+    rayon=float(row[3])/2.
+
+    centre = geompy.MakeVertex(x, y, z)
+    particule = geompy.MakeSpherePntR(centre, rayon)
+    geompy.addToStudy( particule, 'p'+str(i) )
+    i+=1
diff --git a/src/Tools/padder/resources/padderexe/envPadder.sh.in b/src/Tools/padder/resources/padderexe/envPadder.sh.in
new file mode 100644 (file)
index 0000000..90848a9
--- /dev/null
@@ -0,0 +1,27 @@
+#!/bin/sh
+# Copyright (C) 2011-2012  CEA/DEN, EDF R&D
+#
+# 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.com
+#
+
+# This script defines the shell extension required for executing the
+# padder executable program on the localhost (for test purposes)
+
+MED_ROOT="@MED3HOME@"
+HDF_ROOT="@HDF5HOME@"
+CGAL_ROOT="@CGALHOME@"
+export LD_LIBRARY_PATH="$MED_ROOT/lib:$HDF_ROOT/lib:$CGAL_ROOT/lib:$LD_LIBRARY_PATH"
diff --git a/src/Tools/padder/resources/padderexe/med2/REF_FinalEDMesh.med b/src/Tools/padder/resources/padderexe/med2/REF_FinalEDMesh.med
new file mode 100644 (file)
index 0000000..0072943
Binary files /dev/null and b/src/Tools/padder/resources/padderexe/med2/REF_FinalEDMesh.med differ
diff --git a/src/Tools/padder/resources/padderexe/med2/REF_spheres.dat.xyz b/src/Tools/padder/resources/padderexe/med2/REF_spheres.dat.xyz
new file mode 100644 (file)
index 0000000..d511c38
--- /dev/null
@@ -0,0 +1,4097 @@
+0.00782971 0.00837862 0.188345 0.00802045 1 0
+0.0154087 0.00912149 0.0068625 0.00705037 1 0
+0.00853443 0.191571 0.191485 0.00877202 1 0
+0.00831246 0.192152 0.00532739 0.00567024 1 0
+0.392373 0.0103119 0.19108 0.00782777 1 0
+0.382012 0.00642122 0.00627707 0.00662885 1 0
+0.393074 0.19203 0.194472 0.00590232 1 0
+0.387096 0.187644 0.0151337 0.0125061 1 0
+0.0107355 0.00843302 0.0669608 0.00880526 1 0
+0.0130229 0.0100937 0.135407 0.0113355 1 0
+0.0066941 0.0661207 0.191646 0.00802792 1 0
+0.0103253 0.133553 0.192494 0.00822172 1 0
+0.0101874 0.193228 0.0665758 0.00716313 1 0
+0.0128864 0.189676 0.134999 0.0115899 1 0
+0.00969349 0.0657247 0.00859538 0.00955034 1 0
+0.00859049 0.132642 0.00899122 0.00969975 1 0
+0.385203 0.00809838 0.0668407 0.00880575 1 0
+0.386131 0.0107039 0.135508 0.0115306 1 0
+0.393588 0.0665381 0.191132 0.00775488 1 0
+0.386598 0.134808 0.191052 0.0102175 1 0
+0.389949 0.190842 0.0653571 0.00998665 1 0
+0.389353 0.192011 0.133631 0.00881068 1 0
+0.392783 0.067271 0.00660849 0.00698802 1 0
+0.388304 0.134196 0.0104575 0.0117876 1 0
+0.078446 0.0111886 0.00562685 0.00698503 1 0
+0.15933 0.010178 0.0071953 0.00782222 1 0
+0.239408 0.0117814 0.00838242 0.00902724 1 0
+0.319266 0.0104094 0.0109799 0.0115214 1 0
+0.0801022 0.00839366 0.191955 0.009342 1 0
+0.158855 0.0101758 0.190771 0.00985613 1 0
+0.240059 0.008372 0.19268 0.00811281 1 0
+0.319477 0.00952385 0.189827 0.0109663 1 0
+0.080239 0.184554 0.0107232 0.0118692 1 0
+0.158896 0.189543 0.0104515 0.0111914 1 0
+0.239206 0.192295 0.0114336 0.00824166 1 0
+0.321165 0.189065 0.0198378 0.011684 1 0
+0.0784293 0.189358 0.189415 0.0114984 1 0
+0.158102 0.183775 0.186583 0.0140474 1 0
+0.240505 0.191585 0.192095 0.00878636 1 0
+0.320737 0.187137 0.173616 0.0136636 1 0
+0.0102439 0.0601788 0.110611 0.011165 1 0
+0.00632993 0.0606389 0.0501703 0.00699327 1 0
+0.00886816 0.118481 0.073089 0.00961398 1 0
+0.0084637 0.130613 0.129338 0.0092135 1 0
+0.390636 0.0614183 0.111012 0.010272 1 0
+0.391413 0.0615332 0.0505572 0.0092585 1 0
+0.392479 0.119396 0.0733079 0.00827305 1 0
+0.389389 0.131268 0.129331 0.0113393 1 0
+0.274388 0.0076649 0.0575634 0.00842627 1 0
+0.134941 0.00959236 0.0653354 0.0105187 1 0
+0.0651853 0.00803465 0.0661969 0.00886309 1 0
+0.110295 0.00934566 0.133492 0.010401 1 0
+0.185332 0.0137269 0.132579 0.0147265 1 0
+0.331786 0.0104332 0.0984378 0.0115849 1 0
+0.207876 0.0106516 0.0633744 0.0116242 1 0
+0.261527 0.00924836 0.126979 0.0103371 1 0
+0.274177 0.19319 0.0574857 0.00758089 1 0
+0.135692 0.189732 0.0648955 0.0112128 1 0
+0.0663 0.187677 0.0661222 0.0131058 1 0
+0.109855 0.18853 0.132715 0.0125194 1 0
+0.185773 0.18914 0.131535 0.0118814 1 0
+0.332133 0.189017 0.0978282 0.0121498 1 0
+0.207852 0.192331 0.0632991 0.00864703 1 0
+0.261572 0.192711 0.126344 0.00840316 1 0
+0.0697814 0.106226 0.00960134 0.0108828 1 0
+0.131623 0.0598217 0.0086532 0.00941678 1 0
+0.266788 0.0652192 0.0102618 0.0112281 1 0
+0.340609 0.0648565 0.00796636 0.00886868 1 0
+0.291252 0.132331 0.011155 0.0121409 1 0
+0.215098 0.131697 0.0133923 0.0143177 1 0
+0.19535 0.0639082 0.0075357 0.00848584 1 0
+0.141228 0.128178 0.0122679 0.0132652 1 0
+0.0684398 0.10719 0.184859 0.0147587 1 0
+0.131467 0.0598993 0.189562 0.0112022 1 0
+0.267697 0.0654378 0.191161 0.00979633 1 0
+0.340927 0.0652784 0.190301 0.0106229 1 0
+0.291838 0.133337 0.1901 0.0109407 1 0
+0.216095 0.132971 0.190766 0.0102258 1 0
+0.194717 0.0641122 0.187867 0.0130967 1 0
+0.141036 0.129092 0.188982 0.0120216 1 0
+0.0669682 0.0665113 0.0941136 0.0147587 1 0
+0.0833322 0.143862 0.12175 0.0147587 1 0
+0.189807 0.104641 0.118969 0.0147587 1 0
+0.344502 0.0601456 0.0998379 0.0141213 1 0
+0.274144 0.081421 0.098988 0.0147587 1 0
+0.329187 0.144678 0.0830052 0.0143816 1 0
+0.243586 0.146288 0.0866495 0.0147193 1 0
+0.132914 0.0731836 0.103217 0.0147587 1 0
+0.0428272 0.119038 0.052029 0.0119519 1 0
+0.261979 0.150932 0.146194 0.0117141 1 0
+0.102115 0.140291 0.0526524 0.0147587 1 0
+0.0340305 0.101951 0.155062 0.0129279 1 0
+0.357144 0.101091 0.153465 0.0134399 1 0
+0.187456 0.162108 0.0494275 0.0113731 1 0
+0.232702 0.0552718 0.0430421 0.0140424 1 0
+0.171625 0.0519527 0.049372 0.0140307 1 0
+0.369195 0.0892426 0.0427442 0.0106064 1 0
+0.282643 0.107185 0.149494 0.0143329 1 0
+0.301665 0.113049 0.0909966 0.0106702 1 0
+0.310165 0.138814 0.141503 0.0130046 1 0
+0.343165 0.122885 0.118235 0.0109302 1 0
+0.315644 0.0912562 0.126227 0.0126514 1 0
+0.324143 0.117021 0.176733 0.0108517 1 0
+0.241903 0.0991953 0.191196 0.00904411 1 0
+0.205529 0.0985492 0.193468 0.00687593 1 0
+0.231275 0.0648555 0.192248 0.00804733 1 0
+0.192501 0.0845542 0.159484 0.0113254 1 0
+0.203006 0.118545 0.159484 0.0112056 1 0
+0.228532 0.0851619 0.159484 0.0128027 1 0
+0.0076378 0.159507 0.0697794 0.00794379 1 0
+0.00797419 0.124577 0.101219 0.00825663 1 0
+0.00724401 0.165552 0.0978756 0.0074128 1 0
+0.0416661 0.137341 0.125342 0.0105815 1 0
+0.0416661 0.131346 0.0975119 0.0124504 1 0
+0.0416661 0.171931 0.0942084 0.0143232 1 0
+0.0327151 0.00826481 0.0665097 0.00864515 1 0
+0.0663095 0.0332556 0.0799531 0.00903774 1 0
+0.0334841 0.0332556 0.0803902 0.0122868 1 0
+0.0573668 0.0559547 0.065866 0.00791185 1 0
+0.0567081 0.0226991 0.0517055 0.00704303 1 0
+0.0238827 0.0226991 0.0521425 0.00900202 1 0
+0.342522 0.0625798 0.149919 0.0125448 1 0
+0.350823 0.0806185 0.126652 0.00858079 1 0
+0.348843 0.0830528 0.176733 0.00764718 1 0
+0.363749 0.071594 0.15777 0.00763325 1 0
+0.357428 0.051121 0.130956 0.008721 1 0
+0.355448 0.0535553 0.181037 0.00667593 1 0
+0.0681372 0.08677 0.147057 0.0141747 1 0
+0.0504993 0.0842312 0.124588 0.00972722 1 0
+0.0516683 0.10449 0.177531 0.00716934 1 0
+0.0399296 0.0726263 0.156605 0.00748802 1 0
+0.0563985 0.0549064 0.12613 0.00891438 1 0
+0.0575674 0.0751651 0.179073 0.00997186 1 0
+0.0329075 0.194096 0.0663952 0.00629114 1 0
+0.054239 0.159519 0.0589108 0.0106545 1 0
+0.0214136 0.159519 0.0593479 0.0115942 1 0
+0.0444173 0.141073 0.0412066 0.00615021 1 0
+0.0558291 0.181554 0.0480883 0.00684724 1 0
+0.0230037 0.181554 0.0485254 0.00865493 1 0
+0.305829 0.166343 0.00930025 0.00968747 1 0
+0.310165 0.138814 0.0415026 0.0115073 1 0
+0.294382 0.156927 0.0589093 0.0106354 1 0
+0.275359 0.151063 0.0174067 0.007417 1 0
+0.289788 0.184588 0.0174067 0.00953043 1 0
+0.00594911 0.0607854 0.0803628 0.0061939 1 0
+0.00479756 0.0897179 0.0617091 0.00502066 1 0
+0.00616272 0.0895967 0.0918222 0.00633686 1 0
+0.0334841 0.0926703 0.0836937 0.0109375 1 0
+0.0334841 0.0638087 0.072279 0.0100164 1 0
+0.0334841 0.0638137 0.10221 0.0086386 1 0
+0.38987 0.00500221 0.0329115 0.0052469 1 0
+0.393944 0.0306307 0.0587043 0.00630491 1 0
+0.381303 0.0482723 0.0447202 0.00584722 1 0
+0.381303 0.0177192 0.0528313 0.0073099 1 0
+0.100494 0.0834848 0.190271 0.00999289 1 0
+0.136589 0.094439 0.188634 0.0116715 1 0
+0.10535 0.11814 0.185976 0.0143114 1 0
+0.137312 0.100876 0.151609 0.013982 1 0
+0.132467 0.0667472 0.151609 0.0122049 1 0
+0.10111 0.0901062 0.151609 0.0133919 1 0
+0.196804 0.00564298 0.0979846 0.00597401 1 0
+0.234676 0.00734643 0.0952439 0.0075486 1 0
+0.223513 0.00751701 0.129666 0.00783969 1 0
+0.267589 0.0407105 0.112875 0.0108776 1 0
+0.241081 0.0407105 0.0814703 0.0138234 1 0
+0.230019 0.0407105 0.115571 0.0123786 1 0
+0.395052 0.090127 0.0918997 0.00512988 1 0
+0.394346 0.124977 0.101082 0.00594888 1 0
+0.394125 0.0960045 0.119809 0.00606523 1 0
+0.372251 0.0954827 0.114386 0.0118067 1 0
+0.372251 0.0894874 0.0865558 0.0106283 1 0
+0.372251 0.0606309 0.105072 0.00706064 1 0
+0.240956 0.194533 0.060616 0.00571904 1 0
+0.225802 0.173144 0.0753011 0.00853777 1 0
+0.258741 0.173144 0.0722814 0.00850498 1 0
+0.251581 0.157732 0.0607315 0.00735967 1 0
+0.233797 0.184588 0.049383 0.00834547 1 0
+0.266736 0.184588 0.0463634 0.00513679 1 0
+0.00936532 0.0328331 0.190733 0.00954134 1 0
+0.03956 0.0329435 0.190241 0.00993531 1 0
+0.0229144 0.0549841 0.179073 0.00828957 1 0
+0.223628 0.194435 0.129147 0.00587496 1 0
+0.25231 0.173144 0.106706 0.00865879 1 0
+0.214741 0.173144 0.109401 0.011377 1 0
+0.230868 0.156087 0.11999 0.00925117 1 0
+0.239592 0.182943 0.140046 0.00761219 1 0
+0.202023 0.182943 0.142742 0.00643796 1 0
+0.360114 0.190042 0.16695 0.0101415 1 0
+0.324593 0.172339 0.141503 0.0102159 1 0
+0.364593 0.172339 0.108169 0.0128744 1 0
+0.344574 0.149581 0.121034 0.010329 1 0
+0.37998 0.177242 0.146199 0.00823187 1 0
+0.0750501 0.153331 0.00691301 0.00725809 1 0
+0.0857105 0.12366 0.0263262 0.00879905 1 0
+0.0740611 0.1517 0.0415182 0.00806666 1 0
+0.0576568 0.135069 0.0151921 0.008488 1 0
+0.0630037 0.181554 0.0151921 0.00733111 1 0
+0.100334 0.00507726 0.0657085 0.00540601 1 0
+0.101348 0.0332556 0.0799218 0.0124732 1 0
+0.0888629 0.0482426 0.0678241 0.00969621 1 0
+0.0882042 0.0149869 0.0536635 0.00741779 1 0
+0.123242 0.0149869 0.0536322 0.00573819 1 0
+0.366088 0.00696468 0.116037 0.00721858 1 0
+0.366109 0.00552948 0.0824399 0.00579393 1 0
+0.338439 0.0300728 0.0991444 0.00767144 1 0
+0.372251 0.0300728 0.116586 0.0110535 1 0
+0.372251 0.0300728 0.0832523 0.0110382 1 0
+0.203006 0.118545 0.0594845 0.0120352 1 0
+0.211255 0.0799562 0.0810055 0.0125263 1 0
+0.224453 0.0938606 0.021521 0.0112369 1 0
+0.202163 0.0536123 0.046207 0.00768668 1 0
+0.180716 0.0782967 0.0841705 0.0111456 1 0
+0.193914 0.0922011 0.024686 0.0130531 1 0
+0.394528 0.0305532 0.122124 0.00575726 1 0
+0.385177 0.0516063 0.13619 0.00782689 1 0
+0.385177 0.0210482 0.147704 0.0073708 1 0
+0.0751502 0.105187 0.107932 0.0104693 1 0
+0.0763192 0.125446 0.160875 0.010952 1 0
+0.108123 0.108523 0.112484 0.0110378 1 0
+0.0999413 0.0698475 0.0986656 0.00836315 1 0
+0.165758 0.116605 0.159484 0.0121527 1 0
+0.160914 0.0824757 0.159484 0.013619 1 0
+0.161361 0.0889121 0.111093 0.00836142 1 0
+0.294009 0.0323892 0.189614 0.01061 1 0
+0.304296 0.0653391 0.191657 0.00865693 1 0
+0.330471 0.0324018 0.19251 0.00785154 1 0
+0.302412 0.0509357 0.177837 0.0115737 1 0
+0.26577 0.0512702 0.177837 0.00661967 1 0
+0.187851 0.15232 0.125561 0.0120432 1 0
+0.216697 0.125464 0.102809 0.00941345 1 0
+0.215521 0.154198 0.0680385 0.00864791 1 0
+0.188632 0.133375 0.0841982 0.0112806 1 0
+0.186676 0.181054 0.0907904 0.0113755 1 0
+0.257158 0.00634884 0.0286278 0.00661142 1 0
+0.24115 0.00797505 0.0605706 0.00822542 1 0
+0.223999 0.00751144 0.0314485 0.00773857 1 0
+0.22036 0.0276359 0.0534973 0.00800536 1 0
+0.253299 0.0276359 0.0504777 0.00881505 1 0
+0.0994942 0.063411 0.0470568 0.014322 1 0
+0.132467 0.0667472 0.0516087 0.0130026 1 0
+0.121836 0.0515788 0.072376 0.00981294 1 0
+0.121389 0.0451423 0.0207672 0.00695694 1 0
+0.199897 0.192878 0.195143 0.00502548 1 0
+0.213141 0.191335 0.165953 0.0089279 1 0
+0.17265 0.189447 0.165926 0.0108864 1 0
+0.2707 0.0735521 0.049494 0.0125585 1 0
+0.28673 0.0582431 0.0706498 0.00967816 1 0
+0.283286 0.0503742 0.0211558 0.00766029 1 0
+0.266009 0.0451685 0.0426768 0.00870186 1 0
+0.253423 0.0683464 0.071015 0.0092965 1 0
+0.249979 0.0604775 0.021521 0.0070212 1 0
+0.227566 0.166162 0.00927722 0.00964504 1 0
+0.23789 0.150813 0.0174067 0.0083311 1 0
+0.249788 0.184588 0.0174067 0.00630637 1 0
+0.20183 0.147279 0.0247137 0.00805173 1 0
+0.21747 0.0316523 0.190068 0.010193 1 0
+0.229739 0.0506625 0.177837 0.0108254 1 0
+0.186798 0.0522662 0.181595 0.00590615 1 0
+0.231976 0.0930308 0.108978 0.011216 1 0
+0.245174 0.106935 0.049494 0.00991656 1 0
+0.258865 0.113855 0.0928188 0.00909479 1 0
+0.229895 0.139369 0.0433248 0.0114901 1 0
+0.309323 0.0707833 0.099413 0.00918863 1 0
+0.30326 0.0407105 0.0987195 0.0125128 1 0
+0.269214 0.0591391 0.127331 0.00909719 1 0
+0.304393 0.0485014 0.127756 0.0125593 1 0
+0.298329 0.0184286 0.127063 0.0120348 1 0
+0.342522 0.0625798 0.049919 0.0125044 1 0
+0.353554 0.047792 0.069417 0.00851466 1 0
+0.351574 0.0502263 0.019498 0.00671085 1 0
+0.365901 0.0623405 0.0408701 0.00679192 1 0
+0.356848 0.0746941 0.0712911 0.0085842 1 0
+0.354868 0.0771284 0.0213721 0.00710973 1 0
+0.393665 0.0612623 0.0805882 0.00656835 1 0
+0.372251 0.0606259 0.0751412 0.00928767 1 0
+0.00800775 0.00481281 0.0330032 0.00501284 1 0
+0.00493794 0.0302994 0.058471 0.0051964 1 0
+0.0238827 0.0532522 0.0440314 0.0064865 1 0
+0.388819 0.00982632 0.167372 0.0110774 1 0
+0.359782 0.0103331 0.167339 0.0105166 1 0
+0.360202 0.00555297 0.194979 0.00521289 1 0
+0.307343 0.0732175 0.149494 0.0100654 1 0
+0.297242 0.00716979 0.112559 0.0074196 1 0
+0.262658 0.0184286 0.141219 0.00586963 1 0
+0.252783 0.14861 0.116422 0.00781161 1 0
+0.261506 0.175466 0.136478 0.00659803 1 0
+0.240065 0.158409 0.149762 0.00585704 1 0
+0.280059 0.00504557 0.194484 0.00529663 1 0
+0.291028 0.0109082 0.163718 0.0111851 1 0
+0.250706 0.00816308 0.163779 0.0085333 1 0
+0.251026 0.191692 0.163287 0.00868018 1 0
+0.0742247 0.0530447 0.190726 0.00951869 1 0
+0.105992 0.0295004 0.189733 0.0105254 1 0
+0.121557 0.0494515 0.179666 0.00632887 1 0
+0.0902001 0.0728104 0.179666 0.0112387 1 0
+0.0400163 0.189738 0.166964 0.0104471 1 0
+0.0416661 0.171931 0.127542 0.0126428 1 0
+0.0611786 0.149062 0.142927 0.00777122 1 0
+0.0195125 0.177131 0.148718 0.00844259 1 0
+0.280463 0.194149 0.194111 0.00609663 1 0
+0.30581 0.166488 0.193747 0.00663919 1 0
+0.265709 0.166873 0.191652 0.00860795 1 0
+0.276561 0.141941 0.173097 0.00797356 1 0
+0.118638 0.186606 0.187079 0.0130349 1 0
+0.149567 0.165601 0.18603 0.0143514 1 0
+0.110778 0.164928 0.189958 0.0102913 1 0
+0.112521 0.136216 0.160875 0.0123521 1 0
+0.168005 0.0965757 0.192944 0.00723432 1 0
+0.178652 0.13081 0.193931 0.00640298 1 0
+0.332251 0.0300728 0.149919 0.0103012 1 0
+0.325711 0.00860382 0.149657 0.00892666 1 0
+0.0548977 0.0927747 0.0730713 0.00893812 1 0
+0.0214136 0.118934 0.0626514 0.00597593 1 0
+0.0214136 0.0900721 0.0512367 0.00900762 1 0
+0.321909 0.0476054 0.0710748 0.0096664 1 0
+0.319929 0.0500397 0.0211558 0.00827911 1 0
+0.267936 0.00808185 0.0922081 0.00836643 1 0
+0.27402 0.0407105 0.0784506 0.0113994 1 0
+0.370562 0.0994924 0.193807 0.00632978 1 0
+0.378572 0.117212 0.176733 0.00887554 1 0
+0.378572 0.0838791 0.176733 0.00900273 1 0
+0.0170152 0.0815337 0.132684 0.00868612 1 0
+0.0229144 0.0522088 0.134226 0.00857542 1 0
+0.00714838 0.192871 0.0328516 0.00736289 1 0
+0.0329743 0.189293 0.0327432 0.0108652 1 0
+0.0230037 0.181554 0.0151921 0.00829238 1 0
+0.280033 0.194371 0.00546809 0.00575251 1 0
+0.265391 0.166364 0.00786568 0.00811157 1 0
+0.336844 0.102412 0.0914216 0.0109427 1 0
+0.364593 0.137749 0.10597 0.0106918 1 0
+0.378572 0.115956 0.1412 0.00720476 1 0
+0.160389 0.00646817 0.0988948 0.0067168 1 0
+0.17157 0.00638728 0.0645314 0.00668162 1 0
+0.189822 0.0259764 0.0566623 0.00813572 1 0
+0.17876 0.0259764 0.0907627 0.0123462 1 0
+0.153676 0.0259764 0.057551 0.00815413 1 0
+0.147479 0.00853593 0.0323513 0.00887264 1 0
+0.183736 0.00755407 0.0314761 0.0077984 1 0
+0.378572 0.0811038 0.131886 0.00909792 1 0
+0.00591154 0.132048 0.1648 0.00629393 1 0
+0.0195125 0.142541 0.146519 0.0071908 1 0
+0.0195125 0.143797 0.182052 0.00712555 1 0
+0.0365277 0.128106 0.159583 0.00666505 1 0
+0.0170152 0.116386 0.141999 0.00646397 1 0
+0.0170152 0.117642 0.177531 0.00806451 1 0
+0.370844 0.0324118 0.191016 0.00912187 1 0
+0.134768 0.188691 0.166564 0.0115827 1 0
+0.148015 0.19024 0.132253 0.0100692 1 0
+0.134614 0.171931 0.126952 0.0146729 1 0
+0.097124 0.171931 0.127505 0.00794981 1 0
+0.392841 0.0977101 0.0250466 0.00727379 1 0
+0.394032 0.126426 0.0363921 0.00628753 1 0
+0.384597 0.104036 0.058009 0.00656267 1 0
+0.384597 0.0751744 0.0465943 0.00530318 1 0
+0.384597 0.111288 0.0213721 0.00858782 1 0
+0.390129 0.167151 0.0101153 0.0100334 1 0
+0.360693 0.166517 0.0106686 0.0108482 1 0
+0.361679 0.190338 0.013115 0.00979974 1 0
+0.364593 0.139006 0.0415026 0.0137119 1 0
+0.325829 0.188443 0.149303 0.0118787 1 0
+0.366315 0.193143 0.115659 0.00709951 1 0
+0.330781 0.172339 0.0907281 0.00719079 1 0
+0.393701 0.16717 0.194106 0.00622614 1 0
+0.389212 0.189767 0.166773 0.0104671 1 0
+0.37998 0.143909 0.179532 0.00763044 1 0
+0.119432 0.00577778 0.0058474 0.00598998 1 0
+0.107374 0.00697596 0.0325843 0.00717186 1 0
+0.0953788 0.0149869 0.0207672 0.00746824 1 0
+0.392788 0.0332226 0.193286 0.00688538 1 0
+0.385177 0.0543815 0.181037 0.00675563 1 0
+0.13657 0.124252 0.12036 0.0141879 1 0
+0.227045 0.070749 0.137322 0.0133981 1 0
+0.165758 0.116605 0.0594845 0.010786 1 0
+0.137312 0.100876 0.0516087 0.0146835 1 0
+0.117515 0.106738 0.0779349 0.0111866 1 0
+0.145961 0.122466 0.0858107 0.0144476 1 0
+0.121912 0.13443 0.0263262 0.00836417 1 0
+0.303644 0.0655245 0.00637762 0.0067013 1 0
+0.307343 0.0732175 0.049494 0.0112366 1 0
+0.0898928 0.0528545 0.0188092 0.0112597 1 0
+0.100339 0.0835407 0.00719202 0.00745889 1 0
+0.0681372 0.08677 0.0470568 0.0128114 1 0
+0.0845416 0.103401 0.073383 0.011455 1 0
+0.117068 0.100301 0.0263262 0.0125396 1 0
+0.227947 0.166669 0.192156 0.00820954 1 0
+0.239091 0.141691 0.173097 0.00912766 1 0
+0.217177 0.149168 0.176665 0.00718058 1 0
+0.359991 0.00561588 0.00622086 0.00588961 1 0
+0.330111 0.0325816 0.00548694 0.00583707 1 0
+0.370436 0.0326136 0.00785919 0.00799892 1 0
+0.187721 0.166242 0.0085089 0.00875112 1 0
+0.17892 0.13031 0.0061861 0.00650468 1 0
+0.150608 0.164404 0.0088986 0.00927567 1 0
+0.164583 0.145339 0.0247137 0.0094048 1 0
+0.163348 0.0622665 0.195283 0.0049871 1 0
+0.184104 0.0723527 0.14108 0.0098866 1 0
+0.155211 0.0501878 0.181595 0.00782231 1 0
+0.0323044 0.00983341 0.0328972 0.00998101 1 0
+0.286387 0.145483 0.0848274 0.0107116 1 0
+0.295583 0.147805 0.114599 0.0115574 1 0
+0.268062 0.116176 0.122591 0.0106126 1 0
+0.286606 0.0175326 0.0501124 0.00575424 1 0
+0.393607 0.159806 0.0697236 0.00670458 1 0
+0.392433 0.165936 0.0977602 0.00773155 1 0
+0.364593 0.131754 0.0781394 0.00950111 1 0
+0.364593 0.172339 0.0748359 0.0114168 1 0
+0.370471 0.0987242 0.00887783 0.00900479 1 0
+0.334864 0.104846 0.0415026 0.0144509 1 0
+0.349191 0.11696 0.0628747 0.00991734 1 0
+0.391274 0.191165 0.0995132 0.00895533 1 0
+0.394266 0.165746 0.131262 0.0061074 1 0
+0.212893 0.00607632 0.166473 0.00634648 1 0
+0.225089 0.0184286 0.143914 0.0112197 1 0
+0.0100767 0.166711 0.0104198 0.0102409 1 0
+0.0401862 0.166512 0.0109898 0.0111838 1 0
+0.0402255 0.193994 0.00591644 0.00621158 1 0
+0.0230037 0.148221 0.0151921 0.00783265 1 0
+0.381303 0.0510526 0.019498 0.00780039 1 0
+0.384597 0.0779546 0.0213721 0.00716514 1 0
+0.00795073 0.100327 0.191944 0.00820322 1 0
+0.00729948 0.0984007 0.164901 0.00747012 1 0
+0.0170152 0.0843089 0.177531 0.00831272 1 0
+0.309658 0.0175326 0.0211558 0.00733963 1 0
+0.144786 0.1512 0.0510399 0.0110181 1 0
+0.0398287 0.0100308 0.167135 0.0102105 1 0
+0.0956244 0.00846175 0.166819 0.00882322 1 0
+0.0553841 0.00785993 0.133774 0.00819954 1 0
+0.0783722 0.0216507 0.145704 0.0102551 1 0
+0.0229144 0.0216507 0.14574 0.00846962 1 0
+0.122004 0.0558879 0.131275 0.00867966 1 0
+0.0125628 0.192161 0.168294 0.00802027 1 0
+0.37998 0.142652 0.143999 0.00692701 1 0
+0.234711 0.192608 0.0948239 0.00758701 1 0
+0.267805 0.192014 0.0920019 0.00827455 1 0
+0.141191 0.0409633 0.0454532 0.00814838 1 0
+0.303395 0.00577704 0.0780608 0.00607367 1 0
+0.315845 0.0175326 0.0703813 0.00924845 1 0
+0.00557333 0.165517 0.131393 0.00595387 1 0
+0.134321 0.0365918 0.0844737 0.0102843 1 0
+0.15227 0.0625682 0.0762948 0.00870398 1 0
+0.00610125 0.1259 0.0362767 0.00640747 1 0
+0.0214136 0.126186 0.0260145 0.00861099 1 0
+0.203979 0.135263 0.13615 0.00946628 1 0
+0.0541656 0.130645 0.182052 0.00832584 1 0
+0.0586813 0.122907 0.138406 0.00909749 1 0
+0.0733752 0.190249 0.0328107 0.0100889 1 0
+0.0838829 0.170146 0.0592225 0.00889822 1 0
+0.253452 0.132342 0.00666335 0.00698182 1 0
+0.267364 0.139619 0.0433248 0.0124672 1 0
+0.122838 0.00676448 0.099532 0.00706562 1 0
+0.088942 0.0332556 0.113687 0.0111015 1 0
+0.121915 0.0365918 0.118239 0.010264 1 0
+0.120406 0.00711212 0.193704 0.00641037 1 0
+0.135269 0.00862405 0.166962 0.00889347 1 0
+0.111005 0.0192961 0.146296 0.00582169 1 0
+0.297338 0.00779496 0.0287033 0.00808652 1 0
+0.325794 0.00845973 0.0487937 0.00864908 1 0
+0.187851 0.0523203 0.125561 0.0131926 1 0
+0.182148 0.0200324 0.147672 0.00640389 1 0
+0.10101 0.193895 0.065773 0.00643011 1 0
+0.0885172 0.194105 0.0997932 0.00613151 1 0
+0.123113 0.194109 0.099166 0.00619423 1 0
+0.0744915 0.171931 0.0937713 0.0101514 1 0
+0.10953 0.171931 0.09374 0.0118815 1 0
+0.13666 0.0941074 0.00611892 0.00642099 1 0
+0.156667 0.0902607 0.024686 0.0119912 1 0
+0.303258 0.19412 0.0778613 0.00617833 1 0
+0.297043 0.193387 0.112406 0.00685793 1 0
+0.29511 0.172339 0.104884 0.0122603 1 0
+0.301542 0.172339 0.0704592 0.00991179 1 0
+0.145949 0.0298672 0.194806 0.00545143 1 0
+0.169201 0.0200324 0.181595 0.00717934 1 0
+0.0346919 0.119789 0.0059911 0.0062676 1 0
+0.0560667 0.113033 0.0260145 0.00745023 1 0
+0.39462 0.0641305 0.0251582 0.00571618 1 0
+0.358552 0.127788 0.156265 0.00671995 1 0
+0.22384 0.19136 0.0315576 0.00886931 1 0
+0.197737 0.181054 0.05669 0.00568653 1 0
+0.31648 0.0993063 0.190149 0.010111 1 0
+0.196881 0.194663 0.0976769 0.00566597 1 0
+0.0927236 0.142077 0.0872012 0.00896175 1 0
+0.325551 0.143717 0.179532 0.0103648 1 0
+0.293068 0.0329148 0.00869786 0.00893395 1 0
+0.145887 0.0300695 0.00590849 0.0061642 1 0
+0.163592 0.0622743 0.00591676 0.00618727 1 0
+0.177744 0.0321437 0.00757873 0.00778291 1 0
+0.18341 0.0582102 0.024686 0.00701536 1 0
+0.151823 0.0561318 0.024686 0.00798044 1 0
+0.148058 0.190384 0.0324284 0.00993649 1 0
+0.171705 0.193063 0.0644836 0.0072308 1 0
+0.183703 0.191741 0.0316221 0.00850022 1 0
+0.161592 0.181054 0.0575787 0.00827033 1 0
+0.0334841 0.0332556 0.113723 0.0127761 1 0
+0.177315 0.0318544 0.193179 0.00702079 1 0
+0.00742114 0.00649798 0.100794 0.00672344 1 0
+0.0327225 0.00713169 0.100056 0.00728828 1 0
+0.00670312 0.0301976 0.122088 0.00698302 1 0
+0.360594 0.166754 0.190849 0.00932946 1 0
+0.360458 0.194671 0.1947 0.00561391 1 0
+0.187984 0.166822 0.189677 0.0105794 1 0
+0.0890311 0.0525517 0.126723 0.0104433 1 0
+0.279526 0.0994358 0.191957 0.00838132 1 0
+0.2707 0.0735521 0.149494 0.0128078 1 0
+0.395059 0.132156 0.164748 0.00532758 1 0
+0.0630797 0.13145 0.0868896 0.010546 1 0
+0.297324 0.192975 0.0285702 0.00731488 1 0
+0.256988 0.193627 0.0285966 0.00663241 1 0
+0.159405 0.0365918 0.117685 0.0118586 1 0
+0.148494 0.0192961 0.145743 0.0110561 1 0
+0.155658 0.0566242 0.133204 0.0102794 1 0
+0.347491 0.0177192 0.0687235 0.00944119 1 0
+0.253944 0.133117 0.19163 0.00868888 1 0
+0.160668 0.192288 0.0983666 0.00794803 1 0
+0.162767 0.15232 0.0923495 0.011823 1 0
+0.118921 0.170146 0.0591912 0.00871951 1 0
+0.393862 0.0306371 0.0888131 0.00630879 1 0
+0.0342825 0.0868882 0.194405 0.00582405 1 0
+0.0724711 0.129665 0.0523407 0.00787313 1 0
+0.0114266 0.193846 0.10058 0.00631329 1 0
+0.00798199 0.0330447 0.00607383 0.00636767 1 0
+0.0238827 0.0560324 0.0188092 0.00805161 1 0
+0.225893 0.127786 0.132581 0.011245 1 0
+0.0878774 0.00698675 0.0995188 0.00723216 1 0
+0.359861 0.0100027 0.0325919 0.0101839 1 0
+0.00634885 0.0635272 0.15549 0.00666141 1 0
+0.198913 0.0523203 0.0914608 0.0110048 1 0
+0.316316 0.0979592 0.0127506 0.0129877 1 0
+0.279109 0.0990261 0.00597457 0.00631869 1 0
+0.282643 0.107185 0.049494 0.0141105 1 0
+0.0948512 0.190047 0.166682 0.0103369 1 0
+0.0557363 0.192315 0.133729 0.0080218 1 0
+0.345858 0.133694 0.191225 0.00911709 1 0
+0.291379 0.188532 0.163401 0.0117574 1 0
+0.147955 0.00690015 0.132871 0.00722402 1 0
+0.392977 0.0637462 0.155599 0.00734253 1 0
+0.205744 0.0981554 0.00574847 0.0060839 1 0
+0.213949 0.0598698 0.021521 0.00722832 1 0
+0.119829 0.194369 0.00555227 0.00581835 1 0
+0.110214 0.164362 0.00948955 0.00975918 1 0
+0.241564 0.0986453 0.00619258 0.0064188 1 0
+0.231155 0.0649184 0.00722361 0.00752111 1 0
+0.072516 0.00571679 0.032973 0.00607668 1 0
+0.0398795 0.0325987 0.0100453 0.0102223 1 0
+0.0749134 0.0529824 0.0074804 0.00770916 1 0
+0.034637 0.0863996 0.00611601 0.00636006 1 0
+0.0585358 0.0762134 0.0188092 0.00941862 1 0
+0.0452963 0.0822181 0.0448237 0.00939987 1 0
+0.0328906 0.192731 0.1 0.0074275 1 0
+0.00681689 0.00655054 0.166864 0.00687372 1 0
+0.00498748 0.0997191 0.00470913 0.00492065 1 0
+0.00722114 0.0969544 0.024775 0.00732295 1 0
+0.0214136 0.0928524 0.0260145 0.0106683 1 0
+0.00611892 0.0301864 0.0885671 0.00629176 1 0
+0.00549623 0.0956741 0.119829 0.00569037 1 0
+0.0334841 0.0986656 0.111524 0.0123951 1 0
+0.0742482 0.153988 0.191585 0.0087894 1 0
+0.346052 0.132703 0.0081435 0.00845818 1 0
+0.172624 0.00676555 0.166485 0.00710748 1 0
+0.105188 0.117628 0.00615975 0.0064399 1 0
+0.10855 0.190097 0.0325934 0.0101185 1 0
+0.168432 0.096057 0.00759595 0.00777318 1 0
+0.10551 0.0300778 0.00791612 0.00819381 1 0
+0.253178 0.0328009 0.00693181 0.00723025 1 0
+0.217325 0.0321298 0.00770683 0.00796454 1 0
+0.199642 0.193449 0.00648802 0.00669564 1 0
+0.19968 0.0060719 0.193867 0.00628404 1 0
+0.245174 0.106935 0.149494 0.0121355 1 0
+0.360308 0.190453 0.0326889 0.00972258 1 0
+0.326158 0.191821 0.0485561 0.00837765 1 0
+0.366278 0.195066 0.0822926 0.0051992 1 0
+0.392933 0.100219 0.00558497 0.00577655 1 0
+0.0342897 0.120289 0.194417 0.00586501 1 0
+0.0109856 0.167283 0.18869 0.0111292 1 0
+0.0394183 0.167057 0.191843 0.00833159 1 0
+0.390892 0.190956 0.0327244 0.0093067 1 0
+0.253763 0.0323933 0.190427 0.00989013 1 0
+0.279981 0.00552827 0.00540814 0.00558839 1 0
+0.390994 0.0986796 0.165026 0.00917001 1 0
+0.199351 0.00925291 0.00631537 0.00641028 1 0
+0.339858 0.0978656 0.116162 0.0143915 1 0
+0.291051 0.0839952 0.134791 0.0143838 1 0
+0.0230061 0.123341 0.115559 0.014715 1 0
+0.0519932 0.0216838 0.0700086 0.0118849 1 0
+0.0659504 0.0385772 0.0588947 0.0126856 1 0
+0.0384246 0.0355656 0.0575836 0.0111628 1 0
+0.0413681 0.0154344 0.0520067 0.00993293 1 0
+0.355919 0.0796688 0.144359 0.00987007 1 0
+0.353269 0.0664527 0.133592 0.00738205 1 0
+0.352004 0.0664607 0.170429 0.0103816 1 0
+0.359379 0.058104 0.157686 0.00654738 1 0
+0.0439492 0.0842267 0.143609 0.0103898 1 0
+0.0555715 0.0700535 0.136294 0.00934517 1 0
+0.0493466 0.0863296 0.163824 0.0106386 1 0
+0.0534492 0.0726907 0.152056 0.00677646 1 0
+0.0386384 0.178144 0.0651692 0.0144339 1 0
+0.0476738 0.170827 0.0475964 0.00663684 1 0
+0.0327376 0.19314 0.0513751 0.00696728 1 0
+0.308907 0.158592 0.0460618 0.0088282 1 0
+0.0166338 0.0802439 0.0709789 0.0135577 1 0
+0.0185188 0.0796215 0.097997 0.0135333 1 0
+0.017346 0.0603505 0.0840744 0.0102698 1 0
+0.385086 0.0340574 0.0498343 0.00972602 1 0
+0.388393 0.106695 0.102392 0.0116154 1 0
+0.38536 0.0845969 0.101285 0.00968738 1 0
+0.387865 0.0846269 0.118425 0.00763409 1 0
+0.387009 0.093955 0.0898924 0.00514799 1 0
+0.241671 0.181504 0.0670229 0.0112165 1 0
+0.226608 0.172233 0.0583028 0.00850386 1 0
+0.255964 0.172978 0.0541895 0.00979963 1 0
+0.249612 0.189723 0.0511142 0.00837173 1 0
+0.022717 0.0142507 0.190427 0.00962286 1 0
+0.0407331 0.0149915 0.192019 0.00699943 1 0
+0.235776 0.18609 0.115207 0.0139961 1 0
+0.248867 0.166126 0.126089 0.0122412 1 0
+0.22212 0.171399 0.131059 0.0115699 1 0
+0.229005 0.186785 0.133425 0.0054521 1 0
+0.0851153 0.146493 0.022762 0.0143185 1 0
+0.0669041 0.130177 0.0330515 0.0122099 1 0
+0.063305 0.151289 0.0168905 0.00877187 1 0
+0.0815405 0.0205122 0.0716063 0.012504 1 0
+0.0780966 0.038364 0.0727091 0.00571037 1 0
+0.0957399 0.0321352 0.0575695 0.010599 1 0
+0.105371 0.0143381 0.0549332 0.0098079 1 0
+0.353367 0.0167339 0.0905831 0.0132159 1 0
+0.385155 0.0166265 0.0999075 0.0139561 1 0
+0.210662 0.0770846 0.015566 0.0112815 1 0
+0.389953 0.0388172 0.108549 0.0102772 1 0
+0.374346 0.0517042 0.120709 0.011067 1 0
+0.370621 0.037495 0.137735 0.0114201 1 0
+0.390558 0.0348163 0.13853 0.00953474 1 0
+0.0614848 0.104058 0.127071 0.013075 1 0
+0.0841309 0.110185 0.141854 0.0146546 1 0
+0.313814 0.0452291 0.190212 0.00980316 1 0
+0.292761 0.0517713 0.19146 0.00875362 1 0
+0.21056 0.154445 0.121274 0.0111641 1 0
+0.206882 0.165797 0.0859801 0.014397 1 0
+0.185081 0.158987 0.101408 0.0131654 1 0
+0.240847 0.0199757 0.0656529 0.0122568 1 0
+0.106587 0.047547 0.0623922 0.00885443 1 0
+0.103367 0.0560932 0.0794102 0.0104592 1 0
+0.116016 0.0593138 0.0591628 0.00656649 1 0
+0.117395 0.0483294 0.048068 0.00910673 1 0
+0.191796 0.19261 0.178099 0.00739796 1 0
+0.190262 0.1898 0.155824 0.010507 1 0
+0.202655 0.189878 0.185887 0.00756968 1 0
+0.284667 0.0527579 0.0492684 0.0124918 1 0
+0.267685 0.0562034 0.0643551 0.0104832 1 0
+0.252363 0.0623362 0.0534503 0.00929825 1 0
+0.217215 0.109656 0.118837 0.0131045 1 0
+0.320736 0.0555155 0.0908827 0.0116948 1 0
+0.292623 0.0664634 0.113613 0.013154 1 0
+0.288493 0.0359165 0.11613 0.0108148 1 0
+0.306189 0.0324051 0.116388 0.00722874 1 0
+0.361999 0.0517455 0.0533655 0.0100488 1 0
+0.35477 0.0616834 0.0642386 0.00636022 1 0
+0.353108 0.0627607 0.0302231 0.00985696 1 0
+0.357697 0.0745456 0.0429063 0.00805419 1 0
+0.388473 0.0786088 0.0762144 0.0115309 1 0
+0.371176 0.0763511 0.0756446 0.00648226 1 0
+0.384953 0.0606811 0.0905716 0.0106986 1 0
+0.0133713 0.0395707 0.0482004 0.0112632 1 0
+0.377054 0.00985857 0.185869 0.00990833 1 0
+0.358234 0.00751157 0.184997 0.00687113 1 0
+0.322977 0.0666139 0.132647 0.0138483 1 0
+0.290648 0.0596014 0.144794 0.0119843 1 0
+0.318269 0.0522183 0.156885 0.0147333 1 0
+0.298642 0.0225801 0.107366 0.00809767 1 0
+0.275372 0.0400522 0.134644 0.0122502 1 0
+0.277295 0.0139269 0.111945 0.0142065 1 0
+0.243332 0.158549 0.107592 0.00849985 1 0
+0.242569 0.143772 0.132518 0.0118557 1 0
+0.250115 0.170904 0.148051 0.0102692 1 0
+0.270953 0.0113225 0.178894 0.0113339 1 0
+0.29312 0.0104373 0.185275 0.010733 1 0
+0.231865 0.191675 0.150453 0.0083346 1 0
+0.0363854 0.187793 0.145368 0.0117962 1 0
+0.037714 0.16799 0.147599 0.00817705 1 0
+0.286593 0.17804 0.189411 0.0105941 1 0
+0.293143 0.15599 0.186423 0.0120585 1 0
+0.264356 0.185135 0.187138 0.0121549 1 0
+0.164858 0.117047 0.185871 0.0144117 1 0
+0.177516 0.0986111 0.17122 0.0123366 1 0
+0.184805 0.120304 0.171268 0.0105479 1 0
+0.311233 0.0306946 0.142974 0.0118427 1 0
+0.304212 0.0102483 0.147532 0.0102694 1 0
+0.318374 0.0131916 0.133019 0.00952195 1 0
+0.0386367 0.0873516 0.0632239 0.0108306 1 0
+0.0346314 0.0785248 0.0759995 0.005206 1 0
+0.0129629 0.103031 0.0634684 0.0107145 1 0
+0.337932 0.040181 0.0586026 0.0119534 1 0
+0.32304 0.0510643 0.0458029 0.0104974 1 0
+0.250929 0.00828934 0.0790767 0.00830518 1 0
+0.279563 0.033216 0.0976184 0.0099148 1 0
+0.259255 0.0237673 0.0795199 0.0110999 1 0
+0.387591 0.0867004 0.191347 0.00868954 1 0
+0.380134 0.100613 0.182544 0.00878057 1 0
+0.363045 0.0756534 0.186215 0.0109639 1 0
+0.391256 0.0917194 0.178525 0.00601633 1 0
+0.0314241 0.0759766 0.119374 0.0117015 1 0
+0.029587 0.0691096 0.140595 0.0106787 1 0
+0.0388408 0.0552642 0.118268 0.0103264 1 0
+0.0157146 0.193858 0.0469593 0.00617142 1 0
+0.277481 0.181533 0.00721478 0.00724873 1 0
+0.271742 0.191377 0.0181054 0.00864813 1 0
+0.357203 0.0992801 0.0980791 0.010705 1 0
+0.346708 0.113725 0.102435 0.00767388 1 0
+0.363235 0.116484 0.111255 0.0112617 1 0
+0.36471 0.092865 0.133798 0.00918174 1 0
+0.179094 0.00946046 0.0850337 0.0094677 1 0
+0.199891 0.0155986 0.0842305 0.0120848 1 0
+0.172 0.021775 0.0668766 0.0128311 1 0
+0.161145 0.0142864 0.0849849 0.00957009 1 0
+0.16531 0.0124429 0.0443094 0.0124479 1 0
+0.0225446 0.0474814 0.0663094 0.0105236 1 0
+0.0363874 0.056185 0.0541821 0.00983428 1 0
+0.365501 0.08116 0.123471 0.00644773 1 0
+0.385763 0.0960578 0.128605 0.00781636 1 0
+0.0139599 0.147592 0.164164 0.0119845 1 0
+0.0193222 0.126877 0.155769 0.0110009 1 0
+0.0212865 0.132071 0.173446 0.00752773 1 0
+0.00730761 0.117082 0.165563 0.00740949 1 0
+0.355834 0.0185177 0.191414 0.00859597 1 0
+0.348607 0.0383027 0.189035 0.0111529 1 0
+0.132639 0.191841 0.11779 0.00827679 1 0
+0.131246 0.18865 0.14727 0.0116651 1 0
+0.116957 0.175433 0.141497 0.00846987 1 0
+0.393127 0.106986 0.048055 0.0069068 1 0
+0.386686 0.0899624 0.0516342 0.00902786 1 0
+0.394727 0.112683 0.030698 0.00538644 1 0
+0.387084 0.104472 0.0346597 0.00655158 1 0
+0.345148 0.184789 0.0466062 0.0120454 1 0
+0.356736 0.19091 0.0990343 0.0093597 1 0
+0.127682 0.00939457 0.0200367 0.00940051 1 0
+0.132097 0.0106245 0.0400132 0.0108593 1 0
+0.114843 0.0126578 0.0419875 0.00632081 1 0
+0.116248 0.014684 0.0122303 0.00542048 1 0
+0.170733 0.133505 0.170743 0.00875461 1 0
+0.218872 0.06169 0.160269 0.0125913 1 0
+0.246232 0.0513181 0.190082 0.0100493 1 0
+0.143967 0.127614 0.0582512 0.0136594 1 0
+0.301316 0.0589064 0.0296002 0.0140002 1 0
+0.305269 0.053935 0.0508793 0.00820659 1 0
+0.306264 0.0475953 0.00980291 0.00981875 1 0
+0.0837573 0.0439635 0.0525451 0.00697184 1 0
+0.0834765 0.0514769 0.0414608 0.00642183 1 0
+0.076722 0.0672725 0.0328524 0.0127936 1 0
+0.0658256 0.110332 0.0584587 0.013466 1 0
+0.0942477 0.102218 0.0133943 0.0136546 1 0
+0.225715 0.148708 0.162646 0.00924061 1 0
+0.221432 0.176832 0.188792 0.00785824 1 0
+0.348751 0.0206444 0.0108774 0.0108922 1 0
+0.354084 0.00754641 0.0149245 0.00773943 1 0
+0.16887 0.150891 0.0104275 0.0104412 1 0
+0.184389 0.138255 0.0194275 0.0122844 1 0
+0.170477 0.0770973 0.185021 0.0141745 1 0
+0.179787 0.0643972 0.161671 0.0126068 1 0
+0.178077 0.0813081 0.167517 0.00536716 1 0
+0.171908 0.0530528 0.187151 0.0100066 1 0
+0.0215599 0.00758453 0.0470124 0.00758974 1 0
+0.295725 0.0372936 0.0668884 0.013429 1 0
+0.257832 0.038671 0.0651608 0.00964449 1 0
+0.375459 0.123248 0.09362 0.0112366 1 0
+0.378156 0.157402 0.0583142 0.0146607 1 0
+0.361717 0.112088 0.0437565 0.0134527 1 0
+0.354214 0.0947525 0.0274061 0.0115302 1 0
+0.343699 0.127706 0.046363 0.0105342 1 0
+0.375771 0.093816 0.0209501 0.0109917 1 0
+0.387431 0.179191 0.116619 0.012603 1 0
+0.38242 0.153218 0.1108 0.0133994 1 0
+0.378499 0.187674 0.094636 0.0118575 1 0
+0.231756 0.00691231 0.151275 0.00691899 1 0
+0.241288 0.00968751 0.13274 0.0100394 1 0
+0.224111 0.0114066 0.159899 0.00626691 1 0
+0.0229603 0.185685 0.00743012 0.00747811 1 0
+0.037411 0.185073 0.00917614 0.00771211 1 0
+0.0152978 0.169501 0.00788204 0.0080064 1 0
+0.365584 0.0584976 0.015229 0.0101092 1 0
+0.377674 0.064919 0.0295789 0.00972316 1 0
+0.371345 0.0763962 0.0124227 0.00890194 1 0
+0.00607016 0.113737 0.183234 0.00610793 1 0
+0.0177482 0.106556 0.166576 0.00753866 1 0
+0.0173924 0.101126 0.188401 0.0116203 1 0
+0.320855 0.0376444 0.0116917 0.00734364 1 0
+0.165208 0.137354 0.0720785 0.0134923 1 0
+0.144079 0.135267 0.0312902 0.014367 1 0
+0.165475 0.13543 0.0466744 0.011986 1 0
+0.0745623 0.00883203 0.149173 0.00893237 1 0
+0.0535073 0.0116626 0.173585 0.00612253 1 0
+0.130865 0.0425638 0.145565 0.0127738 1 0
+0.0174239 0.190396 0.172379 0.00967554 1 0
+0.0419233 0.185353 0.185353 0.0108033 1 0
+0.36587 0.143274 0.129383 0.0133985 1 0
+0.38734 0.15923 0.145213 0.0112514 1 0
+0.250941 0.192171 0.0787188 0.00784625 1 0
+0.240426 0.178773 0.0903638 0.0123165 1 0
+0.26236 0.182441 0.0879309 0.0100541 1 0
+0.115378 0.0852737 0.0465421 0.0127064 1 0
+0.135265 0.0258461 0.0546071 0.0104916 1 0
+0.289878 0.0375387 0.0857934 0.00636108 1 0
+0.294878 0.0501245 0.0832888 0.00741146 1 0
+0.296897 0.0125443 0.0631942 0.0116219 1 0
+0.0319177 0.15258 0.137429 0.0111748 1 0
+0.0461303 0.13768 0.146997 0.011531 1 0
+0.0124959 0.159635 0.144886 0.0107932 1 0
+0.121417 0.0316553 0.0691049 0.0103816 1 0
+0.142505 0.0474971 0.0650048 0.0125079 1 0
+0.136531 0.0567854 0.0846523 0.0100307 1 0
+0.00947917 0.146002 0.0490215 0.00949669 1 0
+0.0189339 0.126393 0.0464796 0.0120048 1 0
+0.0138137 0.140396 0.0740045 0.0136698 1 0
+0.211644 0.133981 0.118885 0.00946723 1 0
+0.203399 0.154344 0.1416 0.0103861 1 0
+0.37496 0.0650114 0.17113 0.0110079 1 0
+0.368208 0.0574165 0.187213 0.00801593 1 0
+0.0599565 0.140497 0.16553 0.0117625 1 0
+0.0649543 0.135088 0.147747 0.00748528 1 0
+0.0507607 0.119256 0.166314 0.0113964 1 0
+0.0611788 0.126711 0.156142 0.00496128 1 0
+0.071849 0.165862 0.0484098 0.00783746 1 0
+0.232227 0.15496 0.0381257 0.0051099 1 0
+0.26539 0.153878 0.0308856 0.00655751 1 0
+0.254226 0.148364 0.010579 0.00954279 1 0
+0.0872335 0.0210381 0.0948407 0.0114235 1 0
+0.105355 0.0511996 0.109046 0.0136553 1 0
+0.116522 0.0454841 0.0897557 0.00935573 1 0
+0.1186 0.0229352 0.0978742 0.0144792 1 0
+0.114751 0.0094733 0.178 0.00947644 1 0
+0.124719 0.0129115 0.190021 0.00698671 1 0
+0.307064 0.0130512 0.042066 0.0118309 1 0
+0.31323 0.00918472 0.0581303 0.00580519 1 0
+0.211591 0.0479259 0.138481 0.0141896 1 0
+0.192181 0.0566818 0.146392 0.00852602 1 0
+0.106678 0.190419 0.0861648 0.00958831 1 0
+0.0908359 0.178847 0.108707 0.0130443 1 0
+0.111001 0.188553 0.106954 0.00940378 1 0
+0.0909946 0.179291 0.086244 0.00942362 1 0
+0.134588 0.0840325 0.0312592 0.0118727 1 0
+0.12406 0.109313 0.00937685 0.00950764 1 0
+0.152886 0.0799858 0.0459999 0.0119702 1 0
+0.162111 0.101123 0.0443798 0.0111489 1 0
+0.367244 0.0678647 0.0600582 0.00817559 1 0
+0.379698 0.0622769 0.0475206 0.00852458 1 0
+0.382411 0.0656188 0.0628647 0.00741194 1 0
+0.00530947 0.148284 0.152208 0.00533782 1 0
+0.288341 0.189851 0.092671 0.0101512 1 0
+0.309853 0.189503 0.10137 0.0106376 1 0
+0.302921 0.179146 0.0872126 0.00822421 1 0
+0.296218 0.186488 0.0765203 0.00637589 1 0
+0.12987 0.0269885 0.191541 0.00851021 1 0
+0.155532 0.0360994 0.188404 0.00782845 1 0
+0.0410591 0.123946 0.0199892 0.0120594 1 0
+0.0498383 0.139312 0.0286472 0.00764205 1 0
+0.031696 0.141924 0.030251 0.01066 1 0
+0.0422405 0.140611 0.0091657 0.00922523 1 0
+0.322469 0.0178805 0.146835 0.00563141 1 0
+0.353699 0.0281999 0.149582 0.011231 1 0
+0.393307 0.0473753 0.0129008 0.0067172 1 0
+0.39101 0.0521887 0.0335625 0.00922384 1 0
+0.387535 0.0310431 0.0114009 0.00871386 1 0
+0.352823 0.136375 0.117279 0.00568851 1 0
+0.371019 0.129497 0.146528 0.00919033 1 0
+0.23975 0.193302 0.0389499 0.00670009 1 0
+0.21322 0.183876 0.0473552 0.012344 1 0
+0.290996 0.0840484 0.162816 0.0136415 1 0
+0.325332 0.0739599 0.153491 0.00837755 1 0
+0.216003 0.193165 0.107949 0.00683835 1 0
+0.208824 0.186868 0.0957084 0.0088923 1 0
+0.0847779 0.120989 0.0918488 0.0140475 1 0
+0.345015 0.130383 0.172191 0.0143434 1 0
+0.312653 0.0320914 0.00504478 0.00513512 1 0
+0.160375 0.0435024 0.012158 0.0121629 1 0
+0.167644 0.0655224 0.0186183 0.0113927 1 0
+0.153084 0.0234026 0.0132979 0.00819621 1 0
+0.165403 0.190889 0.0441825 0.00911561 1 0
+0.180966 0.183623 0.0569599 0.011283 1 0
+0.0703895 0.0374811 0.129595 0.0136996 1 0
+0.0388652 0.0422696 0.134182 0.0102187 1 0
+0.392038 0.0743685 0.0348702 0.00826804 1 0
+0.196846 0.143226 0.0628502 0.0136246 1 0
+0.013777 0.012867 0.0881742 0.0129082 1 0
+0.0326336 0.0202219 0.096746 0.00864434 1 0
+0.0196705 0.0323884 0.0967388 0.00913384 1 0
+0.0212244 0.0499256 0.104219 0.00999515 1 0
+0.0168423 0.0335269 0.131134 0.0113103 1 0
+0.36748 0.185207 0.190326 0.00919273 1 0
+0.352104 0.181131 0.189058 0.00676397 1 0
+0.356398 0.190294 0.182063 0.00553682 1 0
+0.189141 0.142776 0.181993 0.0147268 1 0
+0.209487 0.139272 0.155345 0.0109017 1 0
+0.0562426 0.155027 0.00555774 0.005627 1 0
+0.107317 0.0430345 0.132072 0.0108538 1 0
+0.296461 0.0860378 0.187312 0.0126963 1 0
+0.277728 0.103706 0.177365 0.0141811 1 0
+0.299084 0.0636102 0.162844 0.00833912 1 0
+0.385162 0.120121 0.157934 0.0112558 1 0
+0.37038 0.132965 0.168166 0.0108392 1 0
+0.385632 0.140025 0.158284 0.00865763 1 0
+0.0482981 0.19129 0.0831739 0.00916622 1 0
+0.0612524 0.15544 0.0821634 0.0139729 1 0
+0.0367202 0.15469 0.0757918 0.0113843 1 0
+0.161624 0.0198379 0.103776 0.0100296 1 0
+0.15685 0.0402778 0.0923543 0.0138665 1 0
+0.15098 0.0378477 0.137264 0.00949224 1 0
+0.149986 0.0504614 0.149848 0.0083531 1 0
+0.169736 0.0424577 0.135879 0.00987065 1 0
+0.345062 0.0342228 0.0782216 0.00975469 1 0
+0.33098 0.0194967 0.0588677 0.00986929 1 0
+0.327716 0.0304708 0.0735557 0.00859503 1 0
+0.246079 0.154124 0.191715 0.00829122 1 0
+0.257018 0.141833 0.182154 0.0109571 1 0
+0.0909553 0.0358688 0.131503 0.00701734 1 0
+0.0721281 0.060405 0.134812 0.00987482 1 0
+0.129253 0.179824 0.102862 0.0112379 1 0
+0.164382 0.176216 0.10136 0.0137664 1 0
+0.140089 0.149112 0.0760627 0.0145271 1 0
+0.140634 0.172744 0.0614462 0.013265 1 0
+0.180291 0.151694 0.0809075 0.00911506 1 0
+0.386181 0.0416112 0.0904011 0.00841162 1 0
+0.0516717 0.0525541 0.184848 0.0140982 1 0
+0.0722764 0.0624285 0.179007 0.00948518 1 0
+0.0348474 0.0734227 0.181379 0.0129312 1 0
+0.0506055 0.100507 0.0440875 0.00965794 1 0
+0.0706543 0.0913602 0.0671509 0.00795337 1 0
+0.0816734 0.117759 0.0433435 0.00965938 1 0
+0.0483573 0.188757 0.112117 0.0111442 1 0
+0.00970976 0.0470906 0.0128571 0.00973229 1 0
+0.0123456 0.0550317 0.0325287 0.00990198 1 0
+0.00980577 0.0280851 0.0111555 0.00741917 1 0
+0.2282 0.155122 0.0560451 0.00882879 1 0
+0.213943 0.16944 0.0663647 0.00676659 1 0
+0.232681 0.136413 0.112038 0.0120468 1 0
+0.243686 0.114589 0.120711 0.0138871 1 0
+0.0564921 0.0924674 0.105065 0.0122932 1 0
+0.0498239 0.190957 0.0181107 0.00905355 1 0
+0.238506 0.150955 0.00679354 0.00687541 1 0
+0.106056 0.00804251 0.0861211 0.0080478 1 0
+0.0994817 0.0132035 0.11266 0.0115751 1 0
+0.142361 0.143467 0.102546 0.0126466 1 0
+0.346896 0.0103949 0.0502715 0.0104187 1 0
+0.337578 0.00615697 0.0647539 0.00632648 1 0
+0.365415 0.0149719 0.0720151 0.008988 1 0
+0.0131234 0.045257 0.15088 0.0119557 1 0
+0.0127507 0.0623101 0.141517 0.00750223 1 0
+0.304444 0.185815 0.0513571 0.0136452 1 0
+0.281936 0.176296 0.0604795 0.0124403 1 0
+0.179508 0.0471838 0.102471 0.0118902 1 0
+0.178001 0.0538737 0.0770514 0.0144384 1 0
+0.187521 0.0410831 0.0886018 0.00525026 1 0
+0.174998 0.0847604 0.0147851 0.00955679 1 0
+0.290064 0.084341 0.0344495 0.0142315 1 0
+0.290002 0.0844431 0.0611749 0.0124942 1 0
+0.376134 0.0463674 0.191537 0.00625324 1 0
+0.0513784 0.191572 0.152027 0.00853012 1 0
+0.0678098 0.176773 0.12328 0.0142848 1 0
+0.344998 0.153703 0.184615 0.0120791 1 0
+0.362316 0.140492 0.185516 0.00972086 1 0
+0.18804 0.169771 0.146387 0.0119031 1 0
+0.308172 0.180009 0.1575 0.00797814 1 0
+0.308458 0.182891 0.125762 0.0146732 1 0
+0.323046 0.0647415 0.0612375 0.0101253 1 0
+0.314683 0.0935818 0.0994618 0.0142316 1 0
+0.30898 0.0979252 0.0495522 0.0135253 1 0
+0.347456 0.0862242 0.0563558 0.0124924 1 0
+0.139757 0.0240381 0.124471 0.0124244 1 0
+0.119083 0.0265038 0.135206 0.00967716 1 0
+0.131047 0.00950555 0.13885 0.00995462 1 0
+0.390467 0.0463886 0.154038 0.00872832 1 0
+0.379006 0.0613228 0.150385 0.0104481 1 0
+0.382075 0.0448445 0.00657943 0.00658226 1 0
+0.22257 0.14715 0.140927 0.0101008 1 0
+0.283228 0.192355 0.18211 0.00772919 1 0
+0.251721 0.184881 0.157569 0.00671726 1 0
+0.272656 0.0531788 0.149365 0.0076595 1 0
+0.209222 0.0940953 0.0136833 0.00589358 1 0
+0.199062 0.0655167 0.031442 0.0115316 1 0
+0.193577 0.0745342 0.0173387 0.00608358 1 0
+0.132108 0.179284 0.00894548 0.0089664 1 0
+0.139169 0.152455 0.0124863 0.0115774 1 0
+0.226438 0.0840168 0.00791548 0.00792328 1 0
+0.231146 0.0678308 0.0205716 0.0117466 1 0
+0.242263 0.0852114 0.0147031 0.00970349 1 0
+0.151372 0.0795723 0.192909 0.00712179 1 0
+0.0541621 0.009468 0.0191585 0.00949259 1 0
+0.0663788 0.0137363 0.0309331 0.00688294 1 0
+0.0387704 0.0148417 0.0112337 0.00865432 1 0
+0.353335 0.0998197 0.0757791 0.0119344 1 0
+0.362165 0.119893 0.187596 0.010984 1 0
+0.0728923 0.0772205 0.190884 0.00967805 1 0
+0.288715 0.00701357 0.0926238 0.00701559 1 0
+0.0506495 0.0549668 0.0138225 0.0138284 1 0
+0.0708841 0.0519034 0.0203875 0.00783806 1 0
+0.0365921 0.0763735 0.0199077 0.0125531 1 0
+0.365386 0.0868869 0.0713017 0.00630041 1 0
+0.054346 0.0732162 0.0601268 0.0105279 1 0
+0.05443 0.0886831 0.0309235 0.00844493 1 0
+0.057257 0.0690964 0.0416356 0.00863903 1 0
+0.364393 0.0328048 0.0626499 0.0111804 1 0
+0.262206 0.12561 0.144205 0.0136869 1 0
+0.0690483 0.193069 0.111205 0.00699695 1 0
+0.0517508 0.17195 0.111857 0.00600386 1 0
+0.0317408 0.00808948 0.183343 0.00727501 1 0
+0.0448126 0.132295 0.0726416 0.012636 1 0
+0.0105125 0.0861309 0.00983185 0.0100961 1 0
+0.0124964 0.104975 0.0414812 0.0109114 1 0
+0.00883058 0.0853637 0.0392147 0.00906131 1 0
+0.0142786 0.1082 0.011511 0.0115812 1 0
+0.0377934 0.0960012 0.182614 0.00987213 1 0
+0.0166288 0.068417 0.167964 0.0102407 1 0
+0.306593 0.0605586 0.0743283 0.0106548 1 0
+0.0219073 0.0146401 0.00836378 0.00841415 1 0
+0.00810007 0.0434991 0.0724525 0.00811193 1 0
+0.0221052 0.0452536 0.0887114 0.00622461 1 0
+0.0164182 0.0888751 0.117519 0.0081728 1 0
+0.0358909 0.0913123 0.129594 0.00726122 1 0
+0.0149256 0.101493 0.132387 0.0113841 1 0
+0.0064834 0.0180904 0.106134 0.00649126 1 0
+0.327023 0.0779322 0.11252 0.00959491 1 0
+0.0792518 0.136865 0.0706925 0.0129743 1 0
+0.0720758 0.152592 0.0579455 0.00850425 1 0
+0.0861308 0.159992 0.0801141 0.0114014 1 0
+0.103346 0.171842 0.0714987 0.0112036 1 0
+0.3503 0.125144 0.0244213 0.0125217 1 0
+0.154271 0.00658848 0.154326 0.00659142 1 0
+0.145609 0.0129631 0.162101 0.00672077 1 0
+0.105485 0.124246 0.0203198 0.0118756 1 0
+0.385248 0.0794694 0.158897 0.0105453 1 0
+0.372667 0.0773341 0.146586 0.0071862 1 0
+0.343365 0.0431501 0.146365 0.00722527 1 0
+0.063767 0.142112 0.0487261 0.00773984 1 0
+0.0938688 0.184927 0.0594656 0.00894189 1 0
+0.152705 0.0619648 0.0546286 0.00801086 1 0
+0.39375 0.146995 0.0492081 0.00626239 1 0
+0.383045 0.130686 0.0581556 0.0124989 1 0
+0.167215 0.0563811 0.117252 0.00942078 1 0
+0.171844 0.0640991 0.131713 0.0076115 1 0
+0.152281 0.0794524 0.0082892 0.00831509 1 0
+0.175193 0.0796253 0.0358228 0.0120995 1 0
+0.140635 0.090329 0.0145581 0.00697231 1 0
+0.286716 0.16251 0.0756719 0.00862372 1 0
+0.248275 0.0833534 0.144199 0.0122316 1 0
+0.126338 0.0206836 0.00730592 0.00730955 1 0
+0.0404216 0.100268 0.0163574 0.0119049 1 0
+0.0378094 0.0911662 0.0329799 0.00722532 1 0
+0.235829 0.0443444 0.0110074 0.0110097 1 0
+0.248735 0.0314925 0.0141296 0.00612448 1 0
+0.208742 0.178494 0.0101585 0.0101662 1 0
+0.196251 0.189903 0.0181036 0.0101298 1 0
+0.0887479 0.0103276 0.0365731 0.0103767 1 0
+0.0975155 0.00563253 0.0489598 0.0056578 1 0
+0.0158431 0.106378 0.0939756 0.0136557 1 0
+0.0502105 0.113761 0.109082 0.0102676 1 0
+0.0436462 0.104431 0.0946859 0.00809977 1 0
+0.202061 0.187687 0.0791138 0.00904632 1 0
+0.201503 0.0132524 0.0433349 0.0106019 1 0
+0.191637 0.0115332 0.178539 0.0115424 1 0
+0.204607 0.0138582 0.167907 0.00543025 1 0
+0.194779 0.0189619 0.192232 0.00777998 1 0
+0.168729 0.189848 0.0818483 0.010209 1 0
+0.129854 0.190782 0.0210644 0.00923197 1 0
+0.26258 0.110366 0.161066 0.00904576 1 0
+0.262803 0.106419 0.146864 0.00569588 1 0
+0.36782 0.188057 0.0582292 0.0121309 1 0
+0.363468 0.18552 0.0857521 0.00573485 1 0
+0.355917 0.173687 0.0582736 0.00732894 1 0
+0.14095 0.00809392 0.111729 0.00810161 1 0
+0.139403 0.0520251 0.158761 0.00557152 1 0
+0.391256 0.0859491 0.00909444 0.00878231 1 0
+0.388958 0.10046 0.0129862 0.00578511 1 0
+0.229216 0.108846 0.136684 0.00841708 1 0
+0.252786 0.0911588 0.168619 0.0137994 1 0
+0.0620011 0.109176 0.0885769 0.0118184 1 0
+0.341706 0.111231 0.188779 0.0112243 1 0
+0.035336 0.135001 0.185697 0.0113418 1 0
+0.0334853 0.114705 0.182273 0.00932439 1 0
+0.0245974 0.185509 0.191853 0.00818761 1 0
+0.204741 0.0577915 0.0675464 0.0142103 1 0
+0.206424 0.179996 0.192712 0.00729287 1 0
+0.370418 0.00789946 0.0151283 0.00793645 1 0
+0.297334 0.10541 0.0705256 0.0116052 1 0
+0.289761 0.133647 0.0548894 0.0134367 1 0
+0.26159 0.111988 0.191384 0.00862492 1 0
+0.378576 0.0868718 0.00681008 0.00500929 1 0
+0.0298629 0.0738766 0.05118 0.00925954 1 0
+0.197723 0.039046 0.0100464 0.01024 1 0
+0.273033 0.0212788 0.192444 0.00756068 1 0
+0.271806 0.0218552 0.0091431 0.00915288 1 0
+0.282277 0.0111852 0.0121297 0.00665603 1 0
+0.0912619 0.1637 0.00873324 0.00896896 1 0
+0.187463 0.109838 0.010696 0.0107031 1 0
+0.211959 0.150836 0.0463463 0.0100119 1 0
+0.276616 0.00726373 0.0208333 0.00726634 1 0
+0.269059 0.00801338 0.0365432 0.00799643 1 0
+0.350892 0.112417 0.0889808 0.00647615 1 0
+0.382318 0.104857 0.167515 0.00698831 1 0
+0.391578 0.112555 0.1718 0.00579373 1 0
+0.0383565 0.118252 0.13661 0.0118309 1 0
+0.347168 0.106342 0.0103183 0.0103355 1 0
+0.0531425 0.147131 0.189814 0.0101934 1 0
+0.0600396 0.165464 0.190941 0.00934447 1 0
+0.154216 0.190864 0.116273 0.00922074 1 0
+0.179424 0.193204 0.0949906 0.00683883 1 0
+0.212951 0.124659 0.145298 0.00716684 1 0
+0.204603 0.0185068 0.00721977 0.0072496 1 0
+0.188898 0.0204287 0.0133955 0.00869768 1 0
+0.390733 0.0440608 0.0726776 0.00928055 1 0
+0.375987 0.0444276 0.0718798 0.00765274 1 0
+0.369288 0.114453 0.0681617 0.0110147 1 0
+0.0346381 0.104006 0.194264 0.0058219 1 0
+0.276533 0.149359 0.0667189 0.0102655 1 0
+0.215694 0.192892 0.0133808 0.00725409 1 0
+0.240383 0.0400749 0.0586261 0.00904036 1 0
+0.0898222 0.0384868 0.00728664 0.00748467 1 0
+0.0845856 0.0737115 0.0110843 0.0113386 1 0
+0.315825 0.189883 0.0295578 0.0104679 1 0
+0.37166 0.193887 0.0984797 0.00613497 1 0
+0.0122528 0.0828442 0.152275 0.0115181 1 0
+0.0158326 0.0667114 0.152824 0.00501628 1 0
+0.227332 0.0458339 0.193588 0.00644537 1 0
+0.0277894 0.19127 0.0808528 0.00878933 1 0
+0.392151 0.0865789 0.141861 0.00786235 1 0
+0.168763 0.151455 0.190798 0.0092146 1 0
+0.204381 0.00966975 0.0216306 0.00967165 1 0
+0.0243094 0.150481 0.0968196 0.013393 1 0
+0.0336358 0.0203736 0.0661439 0.00692063 1 0
+0.361559 0.0637907 0.145559 0.00702253 1 0
+0.0619236 0.074084 0.16276 0.00694743 1 0
+0.0382627 0.160366 0.0558773 0.00562937 1 0
+0.0275376 0.0718734 0.0836242 0.00512013 1 0
+0.228784 0.0149795 0.112927 0.0135174 1 0
+0.395161 0.0898583 0.106136 0.00496068 1 0
+0.25985 0.18758 0.0639603 0.00819434 1 0
+0.0299818 0.0347722 0.183721 0.0061519 1 0
+0.21549 0.186948 0.122246 0.00749354 1 0
+0.361217 0.177099 0.150076 0.0109281 1 0
+0.067308 0.149657 0.0302269 0.00524767 1 0
+0.0991941 0.0200913 0.0677805 0.00556428 1 0
+0.367458 0.0270138 0.0999109 0.00656395 1 0
+0.382911 0.0385284 0.126089 0.00554315 1 0
+0.15259 0.102064 0.170509 0.0103504 1 0
+0.204226 0.159285 0.105587 0.00643247 1 0
+0.106211 0.0611613 0.0650592 0.00502375 1 0
+0.200173 0.191619 0.170332 0.00501194 1 0
+0.271079 0.0587953 0.0365451 0.00707767 1 0
+0.311446 0.0565969 0.10969 0.0084572 1 0
+0.375804 0.0736045 0.0865151 0.00564715 1 0
+0.374788 0.00974941 0.169654 0.00494595 1 0
+0.307617 0.0594108 0.141521 0.0052979 1 0
+0.282294 0.0255418 0.127101 0.00550773 1 0
+0.270122 0.0111254 0.154309 0.0114169 1 0
+0.278578 0.161938 0.192902 0.00495567 1 0
+0.185316 0.109793 0.154663 0.00911126 1 0
+0.293049 0.024156 0.145083 0.00759668 1 0
+0.0265287 0.096412 0.0693108 0.00547116 1 0
+0.241683 0.0191683 0.0860944 0.0082177 1 0
+0.368118 0.0918938 0.184249 0.00616362 1 0
+0.0420928 0.0663928 0.129828 0.00604567 1 0
+0.272006 0.172145 0.0138445 0.00574495 1 0
+0.358694 0.104248 0.124013 0.00698951 1 0
+0.172924 0.0295833 0.0470859 0.00846439 1 0
+0.0390121 0.0491533 0.0682909 0.00614668 1 0
+0.375885 0.0784083 0.117374 0.00590407 1 0
+0.129273 0.172145 0.145903 0.00501788 1 0
+0.391118 0.093988 0.0385701 0.00534297 1 0
+0.105125 0.00750422 0.0121776 0.0078184 1 0
+0.245577 0.0643043 0.163627 0.0144505 1 0
+0.133484 0.113119 0.0700113 0.00774841 1 0
+0.292684 0.0677731 0.0443244 0.00523317 1 0
+0.0766266 0.0592614 0.0541753 0.00998487 1 0
+0.0920868 0.096747 0.0403876 0.0139767 1 0
+0.355631 0.0369208 0.00910917 0.00678582 1 0
+0.187383 0.152005 0.00844206 0.00556809 1 0
+0.18167 0.0620785 0.179408 0.00537936 1 0
+0.0159403 0.00601645 0.0343362 0.00609946 1 0
+0.273759 0.040202 0.0598429 0.00721707 1 0
+0.383771 0.152815 0.084718 0.0127205 1 0
+0.365547 0.1106 0.0219998 0.00868864 1 0
+0.382057 0.169898 0.0993032 0.0068623 1 0
+0.381343 0.0643481 0.0134882 0.00679037 1 0
+0.0639149 0.00754483 0.168317 0.00764772 1 0
+0.0255336 0.192066 0.158187 0.00553389 1 0
+0.373082 0.165629 0.128448 0.0101101 1 0
+0.252547 0.191844 0.100086 0.00835748 1 0
+0.0965972 0.0845669 0.0638608 0.0128504 1 0
+0.14744 0.0175978 0.0433787 0.00617132 1 0
+0.284139 0.0201847 0.081076 0.0116354 1 0
+0.0265165 0.16914 0.138529 0.00627887 1 0
+0.137475 0.0306754 0.0699326 0.00572817 1 0
+0.0227494 0.144802 0.0482607 0.00688008 1 0
+0.379247 0.0677962 0.188607 0.00720059 1 0
+0.261495 0.142099 0.0245236 0.00738447 1 0
+0.106169 0.0378184 0.09608 0.00499535 1 0
+0.310725 0.0197461 0.0571708 0.00509167 1 0
+0.19151 0.0413327 0.142497 0.00732389 1 0
+0.139872 0.105686 0.0266184 0.0108939 1 0
+0.373959 0.0564584 0.0614421 0.00513291 1 0
+0.146353 0.0271243 0.18695 0.00509141 1 0
+0.0298808 0.136673 0.014959 0.0056102 1 0
+0.340704 0.0146383 0.141235 0.00932259 1 0
+0.366728 0.120761 0.130942 0.00918468 1 0
+0.221367 0.186752 0.102372 0.00531139 1 0
+0.0996498 0.0980634 0.092229 0.0132821 1 0
+0.170107 0.0277319 0.0112926 0.00509826 1 0
+0.168886 0.177023 0.0442298 0.0074665 1 0
+0.0497445 0.0241692 0.132148 0.0109974 1 0
+0.389449 0.0608805 0.0214952 0.00511992 1 0
+0.188863 0.129071 0.0421877 0.012663 1 0
+0.168 0.0388015 0.189779 0.00500258 1 0
+0.0361613 0.0111184 0.0808431 0.0100163 1 0
+0.0330297 0.027338 0.131563 0.00602515 1 0
+0.380836 0.174758 0.191983 0.00805852 1 0
+0.191985 0.140342 0.160274 0.0073124 1 0
+0.0475619 0.155101 0.0135935 0.00636649 1 0
+0.089078 0.0771357 0.130195 0.0143848 1 0
+0.386624 0.131859 0.169841 0.00552843 1 0
+0.163404 0.0272597 0.139457 0.00697779 1 0
+0.317549 0.0334651 0.0588785 0.00950924 1 0
+0.251437 0.157781 0.182183 0.00593932 1 0
+0.0862738 0.0444398 0.144012 0.00885247 1 0
+0.144082 0.165439 0.105567 0.0095987 1 0
+0.162451 0.163006 0.0706732 0.0123462 1 0
+0.377191 0.0348654 0.0993471 0.00595367 1 0
+0.0292483 0.0558257 0.19181 0.00845751 1 0
+0.0731428 0.104323 0.0409557 0.00643389 1 0
+0.0198718 0.17265 0.11226 0.0139851 1 0
+0.236318 0.163423 0.0677451 0.00765444 1 0
+0.229331 0.119425 0.108368 0.00565285 1 0
+0.0618705 0.108585 0.148216 0.00855224 1 0
+0.0472707 0.190341 0.0339418 0.00579053 1 0
+0.252217 0.157224 0.00623357 0.00624238 1 0
+0.0962091 0.0159385 0.081255 0.00563935 1 0
+0.00817874 0.0253714 0.146558 0.0083663 1 0
+0.291538 0.171609 0.0445923 0.00670552 1 0
+0.192874 0.0346911 0.0760032 0.00985719 1 0
+0.186361 0.103634 0.0473216 0.0134073 1 0
+0.0741433 0.188066 0.14553 0.0114578 1 0
+0.337023 0.158487 0.194499 0.00550687 1 0
+0.314179 0.0840405 0.072824 0.014068 1 0
+0.133116 0.0246177 0.141414 0.00578305 1 0
+0.394011 0.0446063 0.149989 0.00599448 1 0
+0.37493 0.0385825 0.0159213 0.0066536 1 0
+0.22654 0.143138 0.126695 0.00520927 1 0
+0.268222 0.192866 0.175692 0.00715241 1 0
+0.283563 0.0645575 0.16196 0.00723602 1 0
+0.212596 0.0829564 0.0372903 0.0113053 1 0
+0.123976 0.161412 0.0117908 0.00607324 1 0
+0.162715 0.0962505 0.18281 0.00660952 1 0
+0.0501585 0.00739969 0.0403256 0.00761423 1 0
+0.338479 0.102953 0.0632961 0.00772136 1 0
+0.210651 0.0578669 0.112459 0.0136824 1 0
+0.0662949 0.0647975 0.151469 0.0083119 1 0
+0.289129 0.0209543 0.0975938 0.00563666 1 0
+0.031921 0.0468844 0.0111795 0.00631896 1 0
+0.374995 0.0812476 0.0630345 0.00757385 1 0
+0.240684 0.182445 0.153056 0.00545292 1 0
+0.052213 0.0903392 0.0549818 0.00533031 1 0
+0.371036 0.0137309 0.0852819 0.00547397 1 0
+0.286823 0.129083 0.131978 0.0140184 1 0
+0.063446 0.182761 0.102616 0.0076676 1 0
+0.020394 0.00826111 0.173178 0.00829914 1 0
+0.0312729 0.139892 0.0824798 0.00574432 1 0
+0.00863994 0.083511 0.0249144 0.00519484 1 0
+0.0488243 0.0851716 0.190139 0.00732035 1 0
+0.021921 0.0320327 0.0063651 0.00619372 1 0
+0.0320102 0.0409486 0.0967865 0.0058844 1 0
+0.319167 0.0835592 0.143631 0.00670174 1 0
+0.0782541 0.146147 0.0872911 0.00606958 1 0
+0.225196 0.0554171 0.125535 0.00602916 1 0
+0.128068 0.159785 0.0950072 0.0103182 1 0
+0.335086 0.144369 0.0208107 0.0122591 1 0
+0.309413 0.0449647 0.0811385 0.00659358 1 0
+0.139213 0.00758794 0.153068 0.00558374 1 0
+0.112588 0.0974011 0.00905504 0.00553724 1 0
+0.354749 0.0447492 0.15183 0.00550329 1 0
+0.0586951 0.146078 0.0365589 0.00602574 1 0
+0.250268 0.0762195 0.0341256 0.0131473 1 0
+0.0961069 0.193018 0.0469953 0.00699127 1 0
+0.144597 0.0535251 0.0484729 0.00521266 1 0
+0.383755 0.143112 0.0443475 0.00609051 1 0
+0.177372 0.0558999 0.142282 0.0068624 1 0
+0.149436 0.0717535 0.0217132 0.00809978 1 0
+0.0869359 0.175095 0.0724519 0.00555306 1 0
+0.279529 0.172596 0.089291 0.00978439 1 0
+0.250355 0.0597187 0.137615 0.0123911 1 0
+0.119589 0.0328563 0.0105656 0.00746041 1 0
+0.133067 0.163118 0.0460139 0.006435 1 0
+0.230063 0.025654 0.00788834 0.00633899 1 0
+0.0355784 0.114217 0.101586 0.00617914 1 0
+0.217434 0.184185 0.0825201 0.00708441 1 0
+0.335162 0.0848649 0.0984859 0.0080474 1 0
+0.113069 0.114581 0.144575 0.0147412 1 0
+0.174078 0.166055 0.0859442 0.00708755 1 0
+0.274922 0.125237 0.164978 0.0106713 1 0
+0.346199 0.184401 0.0697786 0.0111541 1 0
+0.142237 0.0228484 0.102594 0.00962491 1 0
+0.14345 0.0678292 0.0349685 0.00696443 1 0
+0.394852 0.0819298 0.0230254 0.00518911 1 0
+0.232323 0.0944074 0.142046 0.0072955 1 0
+0.044562 0.116355 0.0848029 0.00741468 1 0
+0.353889 0.109415 0.17346 0.00846082 1 0
+0.0355702 0.125228 0.171647 0.00577467 1 0
+0.0219492 0.169303 0.194138 0.00592133 1 0
+0.189144 0.0431386 0.0602557 0.00839812 1 0
+0.210267 0.167803 0.187758 0.00653748 1 0
+0.371833 0.0125051 0.0272674 0.00523647 1 0
+0.235904 0.0268693 0.129898 0.00839309 1 0
+0.00800912 0.0936409 0.106956 0.00614546 1 0
+0.152239 0.0664404 0.148093 0.00787896 1 0
+0.0727944 0.116542 0.0759453 0.00635603 1 0
+0.256759 0.110831 0.177046 0.00796748 1 0
+0.0171044 0.142267 0.0374209 0.00560163 1 0
+0.388409 0.15406 0.161688 0.00604898 1 0
+0.212628 0.0445981 0.0184521 0.00840461 1 0
+0.287804 0.0212483 0.00898011 0.00524894 1 0
+0.103648 0.142195 0.00915061 0.00918398 1 0
+0.0249615 0.0944006 0.00999414 0.00581314 1 0
+0.17413 0.101717 0.0223372 0.0090261 1 0
+0.221216 0.134036 0.0650604 0.0125142 1 0
+0.204726 0.070397 0.144764 0.0101323 1 0
+0.283783 0.00667192 0.0360334 0.00686949 1 0
+0.307041 0.163873 0.140303 0.00930808 1 0
+0.372003 0.107226 0.0994053 0.00614495 1 0
+0.0436736 0.10863 0.12283 0.00579659 1 0
+0.34477 0.108323 0.0249005 0.00519196 1 0
+0.0377104 0.15348 0.184693 0.00731607 1 0
+0.121077 0.183774 0.11724 0.0057677 1 0
+0.185975 0.191251 0.0741351 0.00816562 1 0
+0.229029 0.132523 0.15296 0.00991017 1 0
+0.190654 0.0233533 0.00723081 0.00727075 1 0
+0.36508 0.126326 0.0566512 0.0060488 1 0
+0.118158 0.188182 0.158422 0.00502799 1 0
+0.0271665 0.103701 0.1749 0.00535086 1 0
+0.279837 0.149124 0.0515643 0.00524692 1 0
+0.207288 0.192364 0.0321903 0.00772377 1 0
+0.23098 0.0647793 0.0732639 0.0135387 1 0
+0.214176 0.0155511 0.163247 0.00500672 1 0
+0.0209887 0.072175 0.0348169 0.00943272 1 0
+0.0305213 0.134868 0.138194 0.00660834 1 0
+0.0777922 0.0430145 0.0142222 0.0049973 1 0
+0.250382 0.186598 0.0369264 0.00617653 1 0
+0.369015 0.0664313 0.1323 0.00841746 1 0
+0.163825 0.0656479 0.0972373 0.0128942 1 0
+0.0139643 0.101756 0.151244 0.00749925 1 0
+0.105723 0.0334557 0.118016 0.00623026 1 0
+0.0242189 0.0717604 0.155129 0.00504056 1 0
+0.244405 0.0437342 0.178231 0.00539913 1 0
+0.0868532 0.0275435 0.013115 0.00530271 1 0
+0.238417 0.118837 0.138676 0.00530997 1 0
+0.248809 0.0411882 0.0203365 0.00538804 1 0
+0.271743 0.164873 0.0723046 0.00690452 1 0
+0.259549 0.0164941 0.0393869 0.00505907 1 0
+0.0336293 0.184633 0.106557 0.00512952 1 0
+0.0961337 0.069566 0.0259228 0.00794518 1 0
+0.261421 0.0946635 0.0449094 0.0109537 1 0
+0.16721 0.147574 0.178979 0.0079243 1 0
+0.162571 0.0175805 0.15751 0.00737101 1 0
+0.0681521 0.156908 0.15673 0.00858295 1 0
+0.371311 0.188827 0.17645 0.0056506 1 0
+0.382051 0.0326958 0.0660182 0.00679611 1 0
+0.370883 0.097932 0.0722141 0.00607098 1 0
+0.189375 0.0100781 0.0223039 0.00496697 1 0
+0.293977 0.128725 0.155733 0.0107931 1 0
+0.294931 0.106278 0.116439 0.0147434 1 0
+0.319684 0.118009 0.126407 0.0144058 1 0
+0.333114 0.100453 0.142545 0.0129627 1 0
+0.233056 0.0821008 0.185284 0.0135691 1 0
+0.222491 0.107745 0.186574 0.0136897 1 0
+0.205985 0.0856081 0.180974 0.0140664 1 0
+0.209378 0.0980333 0.160304 0.0102888 1 0
+0.0183493 0.171206 0.088728 0.00963997 1 0
+0.0138642 0.130553 0.0946587 0.0092099 1 0
+0.00880729 0.14103 0.109349 0.00910086 1 0
+0.0455904 0.15159 0.109242 0.0112735 1 0
+0.0248175 0.0292809 0.0651985 0.00564902 1 0
+0.051736 0.0417432 0.0745267 0.00867866 1 0
+0.34206 0.0568584 0.130516 0.00768926 1 0
+0.351697 0.0751907 0.157835 0.00494477 1 0
+0.0670896 0.0864491 0.169068 0.00786377 1 0
+0.0512748 0.0963263 0.151133 0.0056313 1 0
+0.0507137 0.0645705 0.163841 0.00779486 1 0
+0.0223355 0.190893 0.0607357 0.00673162 1 0
+0.0467381 0.191243 0.0507055 0.00669401 1 0
+0.299576 0.14876 0.0144156 0.008239 1 0
+0.323826 0.152206 0.0430153 0.00768271 1 0
+0.00617829 0.0719664 0.0851172 0.00587751 1 0
+0.00679986 0.0963776 0.0785689 0.00696181 1 0
+0.0420936 0.072806 0.0881394 0.0101486 1 0
+0.392841 0.0130103 0.0241736 0.00733186 1 0
+0.392432 0.0186516 0.0607261 0.00636687 1 0
+0.374975 0.0243043 0.043706 0.00560077 1 0
+0.0871383 0.0936887 0.187415 0.0112409 1 0
+0.142323 0.107156 0.187424 0.0100812 1 0
+0.145518 0.0811453 0.142775 0.0091413 1 0
+0.215674 0.0140729 0.108765 0.0140781 1 0
+0.222644 0.016739 0.0890476 0.011201 1 0
+0.249043 0.0290925 0.103992 0.0127402 1 0
+0.393134 0.1016 0.0826434 0.00716053 1 0
+0.366581 0.0771724 0.102847 0.0105666 1 0
+0.22542 0.187068 0.0617098 0.00676333 1 0
+0.245887 0.16773 0.0766569 0.00611283 1 0
+0.0157395 0.037729 0.189653 0.0105725 1 0
+0.0536306 0.0208592 0.191866 0.00717096 1 0
+0.214248 0.187878 0.137434 0.00777375 1 0
+0.231408 0.167212 0.109112 0.00631698 1 0
+0.370209 0.186792 0.131924 0.0115277 1 0
+0.348265 0.188219 0.175274 0.00525853 1 0
+0.357703 0.16075 0.122765 0.00699528 1 0
+0.348719 0.169077 0.156321 0.00518334 1 0
+0.0777636 0.163008 0.0142156 0.00567678 1 0
+0.0703331 0.140071 0.0105286 0.00591555 1 0
+0.107597 0.0123506 0.0706847 0.00622383 1 0
+0.0858999 0.00550219 0.062506 0.00576121 1 0
+0.369151 0.00818008 0.0940423 0.00506689 1 0
+0.380448 0.0115654 0.123048 0.0101947 1 0
+0.361218 0.00529068 0.0991335 0.00545717 1 0
+0.21127 0.107896 0.037595 0.0136718 1 0
+0.19285 0.098723 0.0741582 0.0146363 1 0
+0.208754 0.0675954 0.0481468 0.00789315 1 0
+0.190332 0.0714759 0.0516261 0.0112526 1 0
+0.386695 0.0279839 0.124866 0.0057263 1 0
+0.391511 0.0471853 0.123585 0.00691367 1 0
+0.362912 0.0409177 0.12372 0.00493753 1 0
+0.0819763 0.098613 0.165435 0.0117008 1 0
+0.0732932 0.088342 0.117281 0.00888556 1 0
+0.0762444 0.12042 0.121165 0.00973858 1 0
+0.109151 0.0843392 0.112748 0.0131693 1 0
+0.157145 0.101235 0.154726 0.00609758 1 0
+0.156414 0.0947529 0.141875 0.00831439 1 0
+0.141156 0.0819152 0.157509 0.0062447 1 0
+0.311691 0.0225125 0.189756 0.0105256 1 0
+0.277398 0.0425153 0.191083 0.00918601 1 0
+0.31954 0.0655847 0.185438 0.0122109 1 0
+0.199689 0.169705 0.103668 0.00509297 1 0
+0.202364 0.140992 0.101095 0.011787 1 0
+0.222034 0.150856 0.0986253 0.010356 1 0
+0.195383 0.149282 0.0816558 0.00618624 1 0
+0.234882 0.00824154 0.0210247 0.00850376 1 0
+0.227894 0.00967124 0.0485354 0.00981243 1 0
+0.119952 0.0603646 0.0313592 0.0116434 1 0
+0.0929176 0.0649489 0.0678022 0.00749513 1 0
+0.119362 0.0624182 0.0864577 0.00812881 1 0
+0.103313 0.0438392 0.0487169 0.00568792 1 0
+0.189872 0.191278 0.190833 0.00620737 1 0
+0.218556 0.191504 0.183794 0.0088616 1 0
+0.256878 0.0572496 0.0376613 0.00725023 1 0
+0.272126 0.0751648 0.0726282 0.0106756 1 0
+0.251638 0.0481765 0.0465315 0.00647808 1 0
+0.226605 0.183384 0.0126504 0.0076126 1 0
+0.22612 0.155581 0.0104955 0.00612659 1 0
+0.225868 0.00918519 0.182376 0.00962794 1 0
+0.217444 0.0456945 0.187116 0.00535896 1 0
+0.216067 0.126527 0.0469773 0.00773177 1 0
+0.225386 0.109266 0.0975421 0.00970786 1 0
+0.243769 0.106338 0.0993678 0.00899614 1 0
+0.227952 0.126064 0.0859668 0.0108525 1 0
+0.316443 0.042169 0.113368 0.00724812 1 0
+0.326654 0.0517949 0.108777 0.00751662 1 0
+0.301954 0.0583803 0.0999651 0.00524896 1 0
+0.29274 0.0347683 0.132402 0.0060409 1 0
+0.343566 0.0597269 0.018211 0.005781 1 0
+0.352622 0.0502169 0.0402065 0.00618205 1 0
+0.369643 0.0714826 0.0475044 0.00510766 1 0
+0.394229 0.0737736 0.0944807 0.0059695 1 0
+0.394376 0.0620919 0.0670473 0.00591046 1 0
+0.394948 0.0939468 0.076593 0.00516962 1 0
+0.367544 0.0646222 0.0903772 0.00715182 1 0
+0.00818188 0.0126094 0.0228858 0.00838371 1 0
+0.0147844 0.0120618 0.0580327 0.00618432 1 0
+0.31466 0.0730897 0.166658 0.00859344 1 0
+0.319997 0.0525574 0.119828 0.00540728 1 0
+0.300218 0.0662144 0.131142 0.0059512 1 0
+0.282304 0.0498985 0.104559 0.00836055 1 0
+0.251758 0.18354 0.132704 0.00661005 1 0
+0.256939 0.160326 0.111173 0.00568273 1 0
+0.247454 0.15754 0.141038 0.00505592 1 0
+0.236481 0.165237 0.140116 0.00649243 1 0
+0.249384 0.00719792 0.180125 0.00758229 1 0
+0.285711 0.0124466 0.191211 0.0059783 1 0
+0.21456 0.186543 0.153079 0.00793122 1 0
+0.226593 0.180792 0.150642 0.00562627 1 0
+0.083875 0.0293033 0.189486 0.0110144 1 0
+0.0897915 0.0688272 0.191879 0.00823789 1 0
+0.106315 0.053566 0.188127 0.0119741 1 0
+0.111229 0.0439213 0.176073 0.00592557 1 0
+0.0550361 0.190197 0.174822 0.00669825 1 0
+0.0652126 0.164537 0.14202 0.00824646 1 0
+0.267189 0.18792 0.191085 0.00915243 1 0
+0.301131 0.171959 0.186846 0.00580245 1 0
+0.275044 0.14871 0.191894 0.00855422 1 0
+0.0975724 0.182156 0.191598 0.00897754 1 0
+0.117908 0.145176 0.184706 0.0136715 1 0
+0.10357 0.157952 0.149551 0.01374 1 0
+0.202562 0.121477 0.182416 0.0104515 1 0
+0.186167 0.0940157 0.190579 0.00955469 1 0
+0.185097 0.109625 0.185197 0.00700597 1 0
+0.193167 0.106857 0.167044 0.00584006 1 0
+0.325806 0.0498837 0.176862 0.00674515 1 0
+0.327219 0.0434707 0.135695 0.009877 1 0
+0.306853 0.00505278 0.129738 0.00514724 1 0
+0.284301 0.00970246 0.141233 0.00973076 1 0
+0.279911 0.024517 0.14259 0.00577992 1 0
+0.0139161 0.0761074 0.0511881 0.00684258 1 0
+0.0193503 0.0978804 0.0773104 0.00537681 1 0
+0.0312895 0.104381 0.0594031 0.008106 1 0
+0.338556 0.0576895 0.071032 0.00952752 1 0
+0.345385 0.0400912 0.0418604 0.00637311 1 0
+0.259771 0.012368 0.0639415 0.00821059 1 0
+0.234281 0.00979121 0.078925 0.00571495 1 0
+0.261934 0.0151467 0.0961373 0.00781128 1 0
+0.259949 0.0384556 0.0902831 0.00712307 1 0
+0.391538 0.0733979 0.181127 0.00823926 1 0
+0.386642 0.103587 0.194456 0.0057173 1 0
+0.353589 0.0933042 0.189377 0.00930854 1 0
+0.368799 0.0965009 0.17087 0.00800324 1 0
+0.0172555 0.065784 0.127555 0.00757448 1 0
+0.0482225 0.0691234 0.119297 0.00644119 1 0
+0.0294276 0.0847632 0.137985 0.00519188 1 0
+0.0442468 0.0580953 0.140519 0.00765787 1 0
+0.0114241 0.186249 0.0561499 0.0059827 1 0
+0.262791 0.180463 0.0104332 0.00712933 1 0
+0.294967 0.180725 0.00756748 0.00765309 1 0
+0.285215 0.168706 0.0109914 0.00819881 1 0
+0.381007 0.113507 0.121441 0.00943741 1 0
+0.356667 0.0880347 0.110332 0.00593489 1 0
+0.351332 0.127097 0.103414 0.00650858 1 0
+0.361994 0.107448 0.135957 0.00580829 1 0
+0.155172 0.0084073 0.0683292 0.00890522 1 0
+0.188438 0.012146 0.0976326 0.00587874 1 0
+0.188594 0.00995718 0.0690544 0.00765734 1 0
+0.164749 0.0103023 0.0215641 0.0106028 1 0
+0.148297 0.0125693 0.0549953 0.00651599 1 0
+0.181856 0.00865314 0.0566887 0.00648529 1 0
+0.18013 0.0188051 0.0511475 0.00512225 1 0
+0.0135713 0.0284825 0.0616517 0.00617028 1 0
+0.0168143 0.0550432 0.0534702 0.00544081 1 0
+0.0409675 0.0512215 0.0813284 0.00719788 1 0
+0.0315788 0.0446527 0.0458322 0.00519363 1 0
+0.385172 0.0707297 0.121669 0.00688846 1 0
+0.374496 0.103002 0.129779 0.00547061 1 0
+0.36727 0.0697245 0.118015 0.00634524 1 0
+0.00772959 0.129551 0.178176 0.00705005 1 0
+0.00816046 0.138058 0.150509 0.00565004 1 0
+0.0289621 0.137907 0.164141 0.00587197 1 0
+0.0308662 0.118011 0.16402 0.00573116 1 0
+0.369926 0.0178553 0.192356 0.00551679 1 0
+0.340425 0.0223486 0.192848 0.00726053 1 0
+0.11975 0.194485 0.158475 0.00575396 1 0
+0.123894 0.160886 0.143244 0.00774069 1 0
+0.38433 0.118675 0.0362219 0.00799993 1 0
+0.383284 0.102965 0.0460323 0.00553318 1 0
+0.375325 0.156401 0.0123866 0.00920127 1 0
+0.357718 0.185092 0.00968631 0.00792417 1 0
+0.347141 0.186821 0.121368 0.0135055 1 0
+0.326057 0.18231 0.153424 0.00539424 1 0
+0.350309 0.194901 0.11039 0.0056395 1 0
+0.346212 0.166812 0.115758 0.00776566 1 0
+0.386697 0.192126 0.181588 0.00799521 1 0
+0.391156 0.161996 0.18664 0.00904983 1 0
+0.390692 0.174385 0.154308 0.00550439 1 0
+0.0981993 0.0080985 0.00848544 0.00689311 1 0
+0.130053 0.00832591 0.00885153 0.00577159 1 0
+0.394383 0.0239477 0.190847 0.00572692 1 0
+0.134318 0.12667 0.172249 0.0140221 1 0
+0.120571 0.140802 0.136533 0.0136934 1 0
+0.153977 0.137668 0.159255 0.0119829 1 0
+0.238908 0.0637111 0.182828 0.00588483 1 0
+0.217927 0.0660372 0.181256 0.00886203 1 0
+0.213215 0.0882626 0.14329 0.00970245 1 0
+0.23219 0.049967 0.161982 0.00523379 1 0
+0.150521 0.116093 0.0410209 0.0080791 1 0
+0.171537 0.113958 0.0821499 0.0127537 1 0
+0.14791 0.109908 0.0683858 0.00711928 1 0
+0.119181 0.11991 0.0577099 0.0123017 1 0
+0.280074 0.0657231 0.0256561 0.00865399 1 0
+0.315154 0.0634001 0.0129531 0.00810922 1 0
+0.284546 0.0676017 0.0591255 0.00532716 1 0
+0.287665 0.0444101 0.0328449 0.00617395 1 0
+0.103511 0.0542246 0.0293572 0.00602015 1 0
+0.0695044 0.04998 0.0409961 0.00763791 1 0
+0.0777995 0.108209 0.0272184 0.0085827 1 0
+0.105089 0.0831391 0.0281576 0.00846905 1 0
+0.085815 0.0790746 0.0487101 0.00653949 1 0
+0.0968583 0.116976 0.0358279 0.00730169 1 0
+0.23678 0.180027 0.189891 0.00785738 1 0
+0.227769 0.143544 0.185132 0.00749987 1 0
+0.374033 0.01768 0.00744475 0.0059995 1 0
+0.339686 0.00677261 0.00975196 0.00758317 1 0
+0.345282 0.0433209 0.00911013 0.00944693 1 0
+0.172435 0.170777 0.00790899 0.0071469 1 0
+0.164953 0.130355 0.0128714 0.00969678 1 0
+0.158948 0.0614367 0.187529 0.00543337 1 0
+0.189978 0.0716632 0.177366 0.00746771 1 0
+0.178238 0.0797084 0.15281 0.00515117 1 0
+0.165762 0.0528525 0.170612 0.00763925 1 0
+0.0212608 0.0094604 0.0249075 0.00532478 1 0
+0.0403634 0.0072238 0.0517658 0.00747519 1 0
+0.272598 0.106078 0.104539 0.0105631 1 0
+0.287075 0.128572 0.101641 0.0131448 1 0
+0.267112 0.132629 0.0860788 0.01249 1 0
+0.268691 0.137384 0.115787 0.0116689 1 0
+0.27002 0.0257179 0.0636094 0.00820884 1 0
+0.273264 0.0592573 0.0810021 0.00733734 1 0
+0.28318 0.0354773 0.0531312 0.00527753 1 0
+0.389817 0.174931 0.080054 0.0106338 1 0
+0.384445 0.132558 0.0788915 0.00836827 1 0
+0.378701 0.139814 0.0972384 0.00602715 1 0
+0.368813 0.141861 0.0898128 0.00650638 1 0
+0.375492 0.110279 0.0315041 0.00507147 1 0
+0.357443 0.0867631 0.00909228 0.00870971 1 0
+0.375897 0.17125 0.088069 0.00602091 1 0
+0.393984 0.161636 0.116134 0.00619005 1 0
+0.373611 0.161616 0.0966576 0.00525879 1 0
+0.238039 0.00638372 0.171919 0.00666163 1 0
+0.216858 0.00703131 0.152268 0.00513398 1 0
+0.248589 0.00675868 0.148564 0.00687499 1 0
+0.250447 0.0211514 0.146636 0.00776452 1 0
+0.0113154 0.182689 0.00817339 0.00538843 1 0
+0.0238939 0.157768 0.00645951 0.00671657 1 0
+0.0526952 0.185282 0.00720097 0.00766273 1 0
+0.352161 0.0664096 0.0153645 0.00547242 1 0
+0.366475 0.0528956 0.0311387 0.00678152 1 0
+0.365266 0.0710618 0.0239861 0.00520902 1 0
+0.00559995 0.0871335 0.18492 0.00598431 1 0
+0.0112576 0.123259 0.187933 0.00508419 1 0
+0.00679544 0.114603 0.150888 0.00721419 1 0
+0.331843 0.0232473 0.0106033 0.00564219 1 0
+0.332571 0.0501213 0.0120277 0.00731454 1 0
+0.163805 0.12126 0.0301393 0.0098536 1 0
+0.183228 0.124309 0.0663082 0.00949033 1 0
+0.16112 0.149977 0.0571642 0.00646968 1 0
+0.0363436 0.00966209 0.145313 0.0101949 1 0
+0.0688378 0.00717589 0.182349 0.00732408 1 0
+0.0901335 0.00996526 0.15139 0.00727241 1 0
+0.0971279 0.0886962 0.172203 0.0076308 1 0
+0.123389 0.0696746 0.17629 0.0142557 1 0
+0.124882 0.0519842 0.162996 0.00792356 1 0
+0.0127854 0.18895 0.187874 0.0060405 1 0
+0.0175302 0.185317 0.159172 0.0049817 1 0
+0.0525532 0.194899 0.185444 0.00556042 1 0
+0.293887 0.136954 0.174997 0.0101556 1 0
+0.292423 0.15219 0.135484 0.0100152 1 0
+0.282663 0.14629 0.152378 0.0103683 1 0
+0.38584 0.172299 0.134702 0.0055863 1 0
+0.382557 0.152871 0.130059 0.00586379 1 0
+0.357948 0.153628 0.110573 0.00712653 1 0
+0.370099 0.157471 0.142381 0.00630911 1 0
+0.231197 0.192268 0.0787137 0.0079133 1 0
+0.255548 0.165874 0.0866424 0.00790485 1 0
+0.104601 0.0696791 0.0710747 0.0055276 1 0
+0.121347 0.0793999 0.0725771 0.0138937 1 0
+0.107036 0.102437 0.0568728 0.00899351 1 0
+0.283468 0.0231189 0.0642061 0.005501 1 0
+0.302915 0.0162019 0.0810346 0.00755809 1 0
+0.0142963 0.174362 0.133416 0.00796007 1 0
+0.0146243 0.145628 0.132304 0.00815538 1 0
+0.0505912 0.153131 0.131263 0.00849822 1 0
+0.0272526 0.160361 0.151105 0.00523692 1 0
+0.13311 0.0181588 0.0707926 0.00755563 1 0
+0.127461 0.0404578 0.0564505 0.00617569 1 0
+0.151748 0.0383447 0.0530821 0.00513729 1 0
+0.00679267 0.169096 0.0536077 0.00703579 1 0
+0.00651555 0.128824 0.0595809 0.00620981 1 0
+0.199676 0.173535 0.126518 0.0114282 1 0
+0.355852 0.0615542 0.189935 0.00529508 1 0
+0.363794 0.0772269 0.169744 0.00559938 1 0
+0.0653017 0.125566 0.174107 0.00626643 1 0
+0.0706548 0.124027 0.145934 0.00508993 1 0
+0.0437616 0.136513 0.163371 0.00505446 1 0
+0.0403833 0.118787 0.153449 0.00513884 1 0
+0.0668814 0.177731 0.0527361 0.00573733 1 0
+0.0839827 0.158633 0.0492808 0.00631288 1 0
+0.244283 0.130233 0.0206647 0.0134639 1 0
+0.248042 0.142193 0.0542112 0.00985963 1 0
+0.127496 0.0235248 0.0806035 0.00495716 1 0
+0.112549 0.0236483 0.117163 0.00574903 1 0
+0.102698 0.0328561 0.104551 0.00541704 1 0
+0.121179 0.0419633 0.103427 0.00550955 1 0
+0.0949815 0.00750083 0.183421 0.00782525 1 0
+0.134652 0.00614998 0.184862 0.00637881 1 0
+0.116839 0.0088601 0.154427 0.00920183 1 0
+0.31655 0.00700799 0.0248976 0.00751269 1 0
+0.290853 0.00645499 0.0473027 0.00643783 1 0
+0.198169 0.0451707 0.154014 0.00652276 1 0
+0.202753 0.0641795 0.129688 0.00629429 1 0
+0.231726 0.0501635 0.148392 0.00836477 1 0
+0.0806751 0.186693 0.0947945 0.00588621 1 0
+0.0980923 0.193862 0.114456 0.00659301 1 0
+0.0927057 0.166659 0.0945026 0.00576554 1 0
+0.131037 0.0979195 0.0154893 0.00529982 1 0
+0.119759 0.0958302 0.0614018 0.00604038 1 0
+0.117254 0.105551 0.0450691 0.00692544 1 0
+0.180049 0.0968475 0.0963658 0.0110648 1 0
+0.147055 0.0681246 0.0888777 0.00600637 1 0
+0.165325 0.0730319 0.0647813 0.0116055 1 0
+0.356389 0.0605846 0.0771528 0.00670138 1 0
+0.0090253 0.146891 0.178321 0.00943242 1 0
+0.00766876 0.177799 0.147082 0.00803472 1 0
+0.284654 0.182165 0.0777849 0.00603437 1 0
+0.317912 0.188593 0.0821801 0.010196 1 0
+0.31526 0.170622 0.0967369 0.00954165 1 0
+0.157011 0.0204114 0.191012 0.00814343 1 0
+0.0246857 0.126178 0.0110075 0.00674863 1 0
+0.0583965 0.11981 0.0136165 0.00686965 1 0
+0.0423734 0.131397 0.0355498 0.00524297 1 0
+0.359164 0.0155869 0.1297 0.0124649 1 0
+0.346991 0.00989893 0.149958 0.00993081 1 0
+0.335926 0.0173156 0.11971 0.0128885 1 0
+0.351904 0.0330754 0.118387 0.00959278 1 0
+0.394389 0.0194257 0.0160663 0.00555908 1 0
+0.379919 0.129378 0.133306 0.00674795 1 0
+0.343983 0.13786 0.10791 0.00727759 1 0
+0.353387 0.128435 0.141138 0.00927701 1 0
+0.360604 0.139797 0.147167 0.0054718 1 0
+0.210437 0.166175 0.0492754 0.00567761 1 0
+0.333137 0.0762092 0.17059 0.0105529 1 0
+0.304235 0.104976 0.172225 0.0128493 1 0
+0.335688 0.0988857 0.167769 0.0124404 1 0
+0.202789 0.187561 0.113687 0.00783417 1 0
+0.216769 0.19414 0.0854304 0.0061718 1 0
+0.226591 0.167311 0.0969075 0.00680436 1 0
+0.0790982 0.1003 0.091185 0.00741713 1 0
+0.0916304 0.108721 0.10674 0.00642763 1 0
+0.124019 0.099056 0.0987964 0.0119762 1 0
+0.099967 0.113614 0.0782024 0.00766243 1 0
+0.322068 0.132654 0.161504 0.0110719 1 0
+0.328964 0.137853 0.116072 0.00981602 1 0
+0.347629 0.119456 0.153756 0.00724557 1 0
+0.343041 0.14108 0.150765 0.00968606 1 0
+0.308067 0.0305676 0.014255 0.00749486 1 0
+0.288222 0.0486479 0.00726165 0.00755659 1 0
+0.322953 0.0477624 0.00519321 0.00532254 1 0
+0.163145 0.0244185 0.00512858 0.00531505 1 0
+0.143503 0.0521922 0.0141325 0.00602348 1 0
+0.176407 0.0560466 0.00779385 0.00804853 1 0
+0.171945 0.0484305 0.027348 0.00827547 1 0
+0.170499 0.19428 0.0274052 0.00537 1 0
+0.156708 0.193111 0.0620835 0.0071917 1 0
+0.185673 0.194117 0.0511677 0.00612124 1 0
+0.0331075 0.0116814 0.124277 0.0112441 1 0
+0.0663881 0.017704 0.134001 0.00695376 1 0
+0.0509858 0.0401183 0.121398 0.00752897 1 0
+0.0536159 0.0388033 0.139584 0.00586791 1 0
+0.377357 0.0513898 0.0351915 0.00492737 1 0
+0.379201 0.0777361 0.037615 0.00548177 1 0
+0.205056 0.128243 0.0246036 0.0112558 1 0
+0.194766 0.119397 0.0757122 0.00618427 1 0
+0.181175 0.145115 0.0499636 0.00675236 1 0
+0.148696 0.0473235 0.193751 0.00638771 1 0
+0.1805 0.0491506 0.19158 0.00866147 1 0
+0.0218087 0.0143186 0.108466 0.00836723 1 0
+0.0478675 0.0219623 0.0896958 0.00823181 1 0
+0.0512223 0.0421287 0.0966569 0.0133643 1 0
+0.0207695 0.021881 0.119874 0.00535858 1 0
+0.0215509 0.0467649 0.120322 0.00641871 1 0
+0.0360928 0.0484112 0.104878 0.00496479 1 0
+0.0326386 0.0525415 0.145065 0.00598976 1 0
+0.381427 0.190418 0.194281 0.00586092 1 0
+0.373734 0.16649 0.18837 0.00498055 1 0
+0.205452 0.154565 0.177984 0.00579418 1 0
+0.194448 0.131231 0.149231 0.00721404 1 0
+0.0229852 0.137984 0.00566485 0.00616599 1 0
+0.0607551 0.169837 0.00924403 0.00965325 1 0
+0.0609532 0.142705 0.00515321 0.00524266 1 0
+0.0845293 0.0785676 0.161161 0.00895357 1 0
+0.0760292 0.0631132 0.116189 0.00934452 1 0
+0.109096 0.0662653 0.125401 0.0088934 1 0
+0.0992344 0.0589427 0.143979 0.0105978 1 0
+0.273636 0.0785978 0.180015 0.0113957 1 0
+0.31771 0.0863584 0.178826 0.00966627 1 0
+0.29521 0.110289 0.191138 0.00918946 1 0
+0.381769 0.130907 0.179692 0.00549505 1 0
+0.384951 0.132232 0.147066 0.00501827 1 0
+0.368263 0.120297 0.157834 0.00564419 1 0
+0.372344 0.141301 0.154623 0.00518439 1 0
+0.015366 0.18067 0.0718755 0.00991698 1 0
+0.0571934 0.17713 0.0784465 0.00840477 1 0
+0.0608721 0.163181 0.103517 0.00874349 1 0
+0.0402299 0.146705 0.0580912 0.00834893 1 0
+0.254209 0.193453 0.0136025 0.00692331 1 0
+0.293146 0.193828 0.00583723 0.00565197 1 0
+0.273439 0.190697 0.0328814 0.00943147 1 0
+0.148158 0.0224957 0.0751162 0.0086904 1 0
+0.169855 0.0328631 0.104474 0.00539417 1 0
+0.161211 0.0397703 0.0704683 0.00845554 1 0
+0.14024 0.0469873 0.122983 0.010578 1 0
+0.336735 0.0202872 0.0803728 0.00662079 1 0
+0.331173 0.0418264 0.0836408 0.00698085 1 0
+0.248925 0.170773 0.189235 0.0074251 1 0
+0.262339 0.153703 0.191569 0.00510053 1 0
+0.228363 0.152946 0.194167 0.00555304 1 0
+0.253545 0.153824 0.172184 0.00501869 1 0
+0.085673 0.0219495 0.128863 0.00810289 1 0
+0.0787165 0.0476022 0.114194 0.00652346 1 0
+0.0980547 0.0314382 0.144821 0.00871123 1 0
+0.0709612 0.0486933 0.147475 0.00741279 1 0
+0.146003 0.180965 0.107392 0.00615155 1 0
+0.151935 0.175908 0.116585 0.00590186 1 0
+0.131311 0.156841 0.111757 0.006995 1 0
+0.156763 0.164613 0.0522469 0.00700493 1 0
+0.166162 0.131633 0.0940256 0.00920817 1 0
+0.169708 0.159475 0.0531444 0.00695105 1 0
+0.391928 0.014103 0.0938668 0.00815456 1 0
+0.391359 0.0211293 0.117583 0.00530946 1 0
+0.375048 0.0429505 0.106888 0.00530811 1 0
+0.0461391 0.0699646 0.193821 0.00627914 1 0
+0.0622147 0.0345418 0.191454 0.00898645 1 0
+0.0593306 0.0684257 0.192418 0.00508167 1 0
+0.0397629 0.0590945 0.170099 0.00595525 1 0
+0.0661161 0.112209 0.0346864 0.00584907 1 0
+0.0797103 0.0967227 0.0580186 0.00598094 1 0
+0.0568741 0.114675 0.041708 0.00601682 1 0
+0.0822935 0.121589 0.0590197 0.00649001 1 0
+0.0084868 0.184703 0.0965632 0.0086322 1 0
+0.00581197 0.179899 0.124047 0.00594827 1 0
+0.0193344 0.15123 0.117751 0.00813427 1 0
+0.0373418 0.165335 0.111805 0.00496009 1 0
+0.0069464 0.0203693 0.00957193 0.00729029 1 0
+0.0114912 0.0644476 0.0186047 0.00692857 1 0
+0.23016 0.15093 0.070759 0.00659564 1 0
+0.239476 0.169123 0.048159 0.00817471 1 0
+0.216925 0.162977 0.0570597 0.00494897 1 0
+0.256492 0.108796 0.106756 0.00592031 1 0
+0.239834 0.122034 0.101258 0.0072955 1 0
+0.250444 0.134166 0.118395 0.00695265 1 0
+0.0669046 0.0202201 0.0606514 0.00578 1 0
+0.0667976 0.109972 0.163301 0.00737749 1 0
+0.0647391 0.0862293 0.128114 0.00507807 1 0
+0.0730489 0.126344 0.135373 0.0059837 1 0
+0.0487948 0.104113 0.14207 0.00657197 1 0
+0.028089 0.193995 0.0135611 0.00631276 1 0
+0.0674378 0.193956 0.0187955 0.00627478 1 0
+0.0560479 0.192898 0.040999 0.00736616 1 0
+0.262174 0.14737 0.00768132 0.00782649 1 0
+0.110871 0.0181432 0.0802059 0.00539194 1 0
+0.0877005 0.00667963 0.0836161 0.00686255 1 0
+0.104632 0.00847264 0.10825 0.00872388 1 0
+0.0824788 0.0353326 0.0842433 0.00699519 1 0
+0.14732 0.10401 0.105935 0.0128921 1 0
+0.131004 0.0929942 0.120441 0.0115619 1 0
+0.124891 0.124973 0.0770648 0.00850322 1 0
+0.367253 0.00909377 0.0543428 0.00926423 1 0
+0.341448 0.00752611 0.0337154 0.00700713 1 0
+0.353185 0.00671947 0.0658624 0.00679685 1 0
+0.360068 0.0192233 0.0458931 0.00610856 1 0
+0.00526509 0.0409069 0.136276 0.00535184 1 0
+0.00810634 0.0521513 0.169336 0.00845315 1 0
+0.00898223 0.0516547 0.135279 0.00540738 1 0
+0.0272917 0.0344396 0.154164 0.00617013 1 0
+0.28683 0.192156 0.0542309 0.00529478 1 0
+0.306074 0.167622 0.0566469 0.00537123 1 0
+0.19755 0.0334298 0.0932068 0.00801512 1 0
+0.189077 0.0691788 0.103897 0.0121385 1 0
+0.191992 0.113584 0.0278815 0.0086521 1 0
+0.162067 0.106234 0.0287016 0.00534139 1 0
+0.179901 0.11 0.0638109 0.00541145 1 0
+0.17278 0.0881559 0.0541978 0.00830241 1 0
+0.288755 0.0755487 0.0109192 0.0110888 1 0
+0.308569 0.0795913 0.0189497 0.01037 1 0
+0.296556 0.0983438 0.0125803 0.0125357 1 0
+0.383772 0.0259801 0.193385 0.00537695 1 0
+0.386942 0.0526887 0.193606 0.00647137 1 0
+0.365199 0.047121 0.19492 0.0052279 1 0
+0.0519969 0.181546 0.139662 0.00596041 1 0
+0.073405 0.189449 0.169333 0.0107301 1 0
+0.0877081 0.173817 0.141113 0.00870525 1 0
+0.341047 0.169722 0.193253 0.00654535 1 0
+0.330376 0.150117 0.192594 0.00496002 1 0
+0.114133 0.161206 0.130073 0.00865552 1 0
+0.303032 0.188236 0.140302 0.0117671 1 0
+0.315833 0.195507 0.114557 0.00504126 1 0
+0.284501 0.189967 0.127885 0.0104032 1 0
+0.312477 0.161431 0.113936 0.0101568 1 0
+0.327634 0.0793802 0.0481969 0.0100093 1 0
+0.324448 0.0752109 0.0906867 0.0083484 1 0
+0.31356 0.104172 0.0805245 0.00749451 1 0
+0.327746 0.101416 0.0747659 0.00806205 1 0
+0.121771 0.0134248 0.122837 0.00852373 1 0
+0.159631 0.0150029 0.128638 0.00980085 1 0
+0.392511 0.0522317 0.169404 0.00783913 1 0
+0.395162 0.0501463 0.134408 0.00498903 1 0
+0.272107 0.170806 0.116229 0.013434 1 0
+0.281281 0.155885 0.101404 0.0095132 1 0
+0.266574 0.153585 0.107595 0.00660862 1 0
+0.264709 0.153674 0.119585 0.00552586 1 0
+0.38681 0.0562555 0.00638283 0.00528748 1 0
+0.365455 0.0437473 0.0107899 0.00529517 1 0
+0.210022 0.123308 0.12934 0.00556125 1 0
+0.250494 0.193287 0.180336 0.00706519 1 0
+0.258499 0.192009 0.147804 0.00855534 1 0
+0.281498 0.0581577 0.178437 0.0105608 1 0
+0.303242 0.0692587 0.176297 0.00683264 1 0
+0.279185 0.0677835 0.134067 0.00571929 1 0
+0.283695 0.0478234 0.161373 0.00950883 1 0
+0.201343 0.0885042 0.00865546 0.00499766 1 0
+0.217247 0.0657974 0.0338116 0.00681007 1 0
+0.184647 0.0707221 0.0238142 0.00558769 1 0
+0.109721 0.184804 0.00937792 0.00961705 1 0
+0.329991 0.0107204 0.0287114 0.0058961 1 0
+0.324986 0.00709674 0.065553 0.00544047 1 0
+0.320655 0.0241156 0.0465631 0.00626207 1 0
+0.246404 0.0691349 0.00781767 0.00828671 1 0
+0.222941 0.103933 0.0111598 0.011335 1 0
+0.216109 0.0696221 0.00799544 0.00826141 1 0
+0.157528 0.0899447 0.191168 0.00507421 1 0
+0.155537 0.100229 0.191591 0.00540953 1 0
+0.177525 0.0943671 0.150699 0.00861897 1 0
+0.0348592 0.00813347 0.015002 0.00828149 1 0
+0.0512365 0.0192255 0.0153088 0.00517423 1 0
+0.342655 0.0798171 0.0361204 0.00926937 1 0
+0.3391 0.0812289 0.0784261 0.0116296 1 0
+0.338672 0.111785 0.0750774 0.00700406 1 0
+0.330466 0.129438 0.187166 0.00655636 1 0
+0.361513 0.120336 0.171651 0.00498052 1 0
+0.205291 0.0302313 0.114125 0.0145174 1 0
+0.20977 0.0267413 0.0944394 0.00597039 1 0
+0.205971 0.0681862 0.0953955 0.00680038 1 0
+0.233346 0.0592739 0.0989024 0.0127908 1 0
+0.0729556 0.0741033 0.169157 0.00580497 1 0
+0.0687666 0.0753065 0.130455 0.00601045 1 0
+0.0846709 0.0567052 0.156714 0.00887761 1 0
+0.0667951 0.0521266 0.1623 0.00836534 1 0
+0.29608 0.0149178 0.0917873 0.00524784 1 0
+0.283962 0.0466343 0.0910075 0.00567696 1 0
+0.0622957 0.0349496 0.0106501 0.0110784 1 0
+0.0495625 0.0756888 0.00622606 0.00642553 1 0
+0.386469 0.0770333 0.0583167 0.00552774 1 0
+0.387526 0.0946109 0.0661314 0.00621954 1 0
+0.362512 0.0757967 0.0849561 0.00624904 1 0
+0.241755 0.185676 0.178927 0.00544206 1 0
+0.234978 0.173823 0.150145 0.00528781 1 0
+0.0631754 0.100075 0.0342654 0.00630015 1 0
+0.0490861 0.10025 0.0597905 0.00612054 1 0
+0.0448321 0.0676857 0.0483798 0.00556852 1 0
+0.357979 0.0272896 0.0764568 0.00501178 1 0
+0.278958 0.131248 0.150856 0.00519829 1 0
+0.280979 0.110705 0.130202 0.00534803 1 0
+0.302751 0.12933 0.116301 0.00833201 1 0
+0.27393 0.140098 0.141054 0.00521546 1 0
+0.0373405 0.191358 0.126653 0.00727957 1 0
+0.0677841 0.191625 0.0901428 0.00869273 1 0
+0.0844209 0.191969 0.124443 0.00855905 1 0
+0.0775465 0.162201 0.109099 0.0082593 1 0
+0.0207555 0.0053754 0.188771 0.00547368 1 0
+0.0455209 0.00928189 0.181845 0.00561126 1 0
+0.0245158 0.167059 0.0749526 0.00601204 1 0
+0.0568859 0.143012 0.0981434 0.00673649 1 0
+0.0311157 0.142002 0.0668341 0.00512793 1 0
+0.00911201 0.111889 0.0105822 0.00952419 1 0
+0.0289019 0.0987202 0.0405127 0.00667252 1 0
+0.0153248 0.0709797 0.185047 0.00708259 1 0
+0.0468106 0.0975161 0.194603 0.00576613 1 0
+0.0330428 0.088288 0.168913 0.00655303 1 0
+0.0319882 0.0658179 0.164622 0.00569154 1 0
+0.327932 0.0661663 0.0347492 0.00884639 1 0
+0.325235 0.0611186 0.0757851 0.00502571 1 0
+0.301791 0.0719827 0.0647257 0.00502249 1 0
+0.140444 0.0208043 0.00857616 0.00554489 1 0
+0.13206 0.0531746 0.0191259 0.00650001 1 0
+0.0227459 0.0405526 0.0137735 0.00512675 1 0
+0.0139517 0.0311413 0.0791735 0.00739728 1 0
+0.00812655 0.0462816 0.0920372 0.00831147 1 0
+0.0100434 0.0603263 0.0679059 0.00747143 1 0
+0.0330852 0.0595645 0.0875891 0.00587617 1 0
+0.01453 0.0759006 0.120222 0.00521403 1 0
+0.0151535 0.103402 0.114357 0.0067483 1 0
+0.0287214 0.0951057 0.139099 0.00523436 1 0
+0.0133948 0.0273098 0.111089 0.00733124 1 0
+0.00839056 0.0392552 0.105564 0.00674924 1 0
+0.0335484 0.0517292 0.0957753 0.00505228 1 0
+0.321536 0.0865347 0.161924 0.00723207 1 0
+0.336144 0.0797876 0.125265 0.00618701 1 0
+0.306447 0.0747709 0.124501 0.0063047 1 0
+0.338491 0.0802498 0.140048 0.00809261 1 0
+0.0724714 0.172504 0.0723751 0.00867382 1 0
+0.077077 0.155879 0.0945479 0.00612652 1 0
+0.0603146 0.142855 0.064314 0.00788684 1 0
+0.0873398 0.153674 0.0624092 0.00743584 1 0
+0.0837064 0.168728 0.18948 0.00889523 1 0
+0.0796081 0.136161 0.182522 0.013425 1 0
+0.0984236 0.143756 0.174245 0.00848882 1 0
+0.090862 0.139998 0.157997 0.00982194 1 0
+0.120833 0.0169722 0.0755527 0.00566548 1 0
+0.0890771 0.0475762 0.0844198 0.00691428 1 0
+0.111386 0.0351207 0.0575203 0.0053293 1 0
+0.220659 0.0305815 0.129607 0.00729992 1 0
+0.20806 0.0804905 0.123909 0.0118058 1 0
+0.238003 0.061297 0.120152 0.00905688 1 0
+0.233536 0.0524825 0.134068 0.00625855 1 0
+0.246734 0.133539 0.040288 0.00658618 1 0
+0.261156 0.116553 0.0379597 0.0120144 1 0
+0.253954 0.128533 0.0491202 0.00587193 1 0
+0.0659653 0.0123689 0.0890542 0.0122615 1 0
+0.0753169 0.0123982 0.113778 0.0125732 1 0
+0.0701547 0.0311356 0.0969636 0.00853032 1 0
+0.124168 0.167553 0.0768115 0.00984731 1 0
+0.154698 0.126665 0.106738 0.00861596 1 0
+0.114986 0.142254 0.0860121 0.0133329 1 0
+0.346007 0.153192 0.00795461 0.00800824 1 0
+0.318942 0.148861 0.0113152 0.0115475 1 0
+0.318348 0.0348712 0.0863439 0.00785672 1 0
+0.303844 0.0561051 0.0899067 0.0052354 1 0
+0.313022 0.0358319 0.074224 0.00541661 1 0
+0.152268 0.0076484 0.173852 0.00786869 1 0
+0.13011 0.0144056 0.154271 0.00585279 1 0
+0.165082 0.0119672 0.144377 0.00713006 1 0
+0.0871026 0.125344 0.0093217 0.0096307 1 0
+0.122601 0.0934845 0.0107429 0.00534686 1 0
+0.390935 0.0680353 0.16854 0.00545651 1 0
+0.391784 0.0660705 0.137733 0.0081494 1 0
+0.368876 0.0851037 0.157602 0.00681751 1 0
+0.3435 0.0532953 0.184997 0.0059137 1 0
+0.0678451 0.116635 0.0213229 0.00572971 1 0
+0.0831903 0.134643 0.0428236 0.0073013 1 0
+0.315142 0.019002 0.154585 0.00509271 1 0
+0.318834 0.0287574 0.124498 0.0082297 1 0
+0.331325 0.0384706 0.118156 0.00881685 1 0
+0.257485 0.0774816 0.0149607 0.00737033 1 0
+0.243986 0.105343 0.0208968 0.0114293 1 0
+0.250893 0.0810976 0.056506 0.00976706 1 0
+0.241362 0.071397 0.0497077 0.00543699 1 0
+0.0951764 0.190812 0.0352198 0.005069 1 0
+0.105909 0.1918 0.0552695 0.0055431 1 0
+0.0838705 0.19237 0.0559887 0.00778471 1 0
+0.0909871 0.168167 0.046449 0.00585127 1 0
+0.138129 0.0547823 0.0314965 0.00737256 1 0
+0.133008 0.0625234 0.0701167 0.00598886 1 0
+0.131467 0.0487513 0.0499509 0.0050972 1 0
+0.392729 0.17308 0.0543232 0.00762244 1 0
+0.390069 0.140352 0.0309828 0.00894587 1 0
+0.392483 0.144524 0.0675016 0.00668198 1 0
+0.365541 0.139541 0.0628607 0.00767386 1 0
+0.181917 0.072989 0.122854 0.00848093 1 0
+0.151607 0.0618207 0.010758 0.00684657 1 0
+0.170956 0.0743141 0.00515087 0.00535107 1 0
+0.151276 0.100927 0.0089466 0.00913301 1 0
+0.159422 0.0740842 0.0305408 0.00543141 1 0
+0.115667 0.180416 0.0794904 0.0058022 1 0
+0.0994465 0.155809 0.0923839 0.00718233 1 0
+0.0999845 0.154006 0.0694851 0.00705776 1 0
+0.273075 0.179113 0.0764238 0.0060175 1 0
+0.273414 0.182999 0.100381 0.00660443 1 0
+0.294461 0.167567 0.0871492 0.00611654 1 0
+0.267046 0.169424 0.0821706 0.00493232 1 0
+0.263157 0.0743531 0.166745 0.00603747 1 0
+0.236311 0.0883744 0.127816 0.00866709 1 0
+0.262038 0.0760561 0.129225 0.00937597 1 0
+0.260806 0.0583165 0.152129 0.00554879 1 0
+0.127913 0.0401208 0.0105813 0.0108419 1 0
+0.139949 0.188361 0.0447094 0.00963688 1 0
+0.156756 0.175254 0.0466356 0.00502514 1 0
+0.0182403 0.0775134 0.0207589 0.00585374 1 0
+0.049628 0.0861852 0.0125484 0.00534557 1 0
+0.0386586 0.104817 0.0341019 0.00649825 1 0
+0.0504136 0.0672162 0.0286269 0.00617965 1 0
+0.241949 0.0263184 0.0058993 0.00573091 1 0
+0.252068 0.0556234 0.00921361 0.00637274 1 0
+0.22369 0.0526726 0.0183509 0.0052916 1 0
+0.232494 0.0511763 0.0241064 0.00533218 1 0
+0.19112 0.181137 0.00602503 0.00537962 1 0
+0.202486 0.159753 0.0127104 0.00927223 1 0
+0.0752446 0.00953644 0.0199405 0.00785062 1 0
+0.0762035 0.00765303 0.0478329 0.00785765 1 0
+0.0933209 0.00532339 0.0221773 0.00561959 1 0
+0.103481 0.0147954 0.0398048 0.00544491 1 0
+0.0277912 0.120626 0.096511 0.00511143 1 0
+0.0426447 0.126149 0.114312 0.00516252 1 0
+0.196674 0.18675 0.102437 0.0049966 1 0
+0.211756 0.1794 0.0726919 0.00523377 1 0
+0.223498 0.175543 0.0884482 0.00502362 1 0
+0.200843 0.175993 0.0680288 0.00711302 1 0
+0.342708 0.0784478 0.109096 0.0064675 1 0
+0.301046 0.0851749 0.11395 0.00736852 1 0
+0.326322 0.112953 0.104599 0.00894385 1 0
+0.33831 0.112264 0.129564 0.00533993 1 0
+0.146632 0.119854 0.155857 0.00758345 1 0
+0.113839 0.124127 0.123163 0.00871534 1 0
+0.147431 0.104285 0.128928 0.0101026 1 0
+0.130699 0.107509 0.132492 0.00730589 1 0
+0.110278 0.121507 0.179754 0.0116856 1 0
+0.0956274 0.122005 0.158534 0.00879957 1 0
+0.119865 0.0920174 0.138423 0.00961322 1 0
+0.219451 0.0418365 0.0510078 0.00644042 1 0
+0.173338 0.00866538 0.177793 0.00550045 1 0
+0.211117 0.00543773 0.18246 0.00561183 1 0
+0.187216 0.00837054 0.155071 0.00872445 1 0
+0.1664 0.17484 0.0827415 0.00501124 1 0
+0.177999 0.143392 0.0931468 0.00585077 1 0
+0.109717 0.192946 0.0137512 0.00724742 1 0
+0.14143 0.184762 0.0195865 0.00684492 1 0
+0.122259 0.190175 0.0476535 0.0102463 1 0
+0.0667361 0.169401 0.0599992 0.00531496 1 0
+0.082868 0.146826 0.0508342 0.00564837 1 0
+0.0552552 0.154891 0.0433447 0.00561681 1 0
+0.310689 0.151778 0.181469 0.00665367 1 0
+0.330094 0.152012 0.136954 0.0113277 1 0
+0.345349 0.156333 0.145413 0.00664196 1 0
+0.251394 0.126454 0.166924 0.0114056 1 0
+0.267385 0.108622 0.136848 0.00553662 1 0
+0.263938 0.13864 0.160479 0.00723252 1 0
+0.360484 0.188651 0.0759512 0.00497759 1 0
+0.331221 0.188418 0.0363829 0.00560804 1 0
+0.331933 0.192602 0.0717644 0.00779763 1 0
+0.347752 0.165414 0.0682079 0.00796147 1 0
+0.136251 0.00928 0.0920064 0.00859638 1 0
+0.129956 0.0161276 0.112292 0.00509584 1 0
+0.152579 0.0159942 0.115424 0.00520984 1 0
+0.136703 0.036157 0.110096 0.00662378 1 0
+0.100961 0.00493377 0.154156 0.00544695 1 0
+0.13546 0.0669218 0.0237618 0.0068288 1 0
+0.142736 0.0815677 0.0644031 0.00910591 1 0
+0.155592 0.0620349 0.0396216 0.00727139 1 0
+0.23071 0.0941707 0.0424577 0.0106171 1 0
+0.231904 0.080267 0.0565854 0.00924055 1 0
+0.136849 0.055555 0.169806 0.00630133 1 0
+0.13647 0.0580592 0.135486 0.00654245 1 0
+0.150866 0.0539106 0.165846 0.00803573 1 0
+0.394575 0.07269 0.0171423 0.0055546 1 0
+0.39486 0.110574 0.0118853 0.00550496 1 0
+0.387951 0.0869387 0.0294716 0.00538716 1 0
+0.254035 0.0737726 0.183436 0.00907811 1 0
+0.227242 0.108008 0.16302 0.0103512 1 0
+0.22171 0.101723 0.147955 0.0068841 1 0
+0.246732 0.0983579 0.13288 0.00662683 1 0
+0.0335488 0.109202 0.0863888 0.00581296 1 0
+0.0513091 0.0948092 0.0875527 0.00611939 1 0
+0.05679 0.122306 0.0980262 0.00517686 1 0
+0.052778 0.114593 0.0733525 0.00678807 1 0
+0.377528 0.112721 0.191255 0.00636142 1 0
+0.323421 0.118747 0.192828 0.00747939 1 0
+0.0202821 0.127857 0.185543 0.00532221 1 0
+0.0456882 0.121297 0.189231 0.00619298 1 0
+0.0278125 0.163137 0.185644 0.00614243 1 0
+0.0407269 0.184969 0.19302 0.00713734 1 0
+0.202317 0.0380069 0.0635513 0.0061186 1 0
+0.196048 0.0690914 0.0860807 0.00683945 1 0
+0.214552 0.0556608 0.0504908 0.00558046 1 0
+0.187018 0.0565114 0.0598651 0.00514824 1 0
+0.192447 0.179866 0.191769 0.00552928 1 0
+0.382976 0.00933654 0.00800821 0.00624409 1 0
+0.379462 0.00880123 0.0393308 0.00900867 1 0
+0.228739 0.0357554 0.140074 0.00689897 1 0
+0.253924 0.0245816 0.129793 0.00977247 1 0
+0.254756 0.0552683 0.117164 0.0089968 1 0
+0.244956 0.0366762 0.141704 0.00942559 1 0
+0.284401 0.126071 0.0301732 0.0129644 1 0
+0.280462 0.111896 0.0848258 0.0114435 1 0
+0.294088 0.127276 0.0774395 0.0103921 1 0
+0.280271 0.135028 0.0733615 0.0059669 1 0
+0.00563921 0.0823402 0.11215 0.00596405 1 0
+0.00684844 0.11187 0.11031 0.0057838 1 0
+0.0379734 0.0850477 0.0989356 0.00668566 1 0
+0.148048 0.0673697 0.16165 0.00634128 1 0
+0.16632 0.0802059 0.13652 0.0100819 1 0
+0.153832 0.0715793 0.136283 0.00509827 1 0
+0.164782 0.0570918 0.149821 0.00786055 1 0
+0.0708317 0.0947185 0.0813214 0.00661075 1 0
+0.0669437 0.121838 0.0984773 0.00499761 1 0
+0.0644455 0.124797 0.0716368 0.00615064 1 0
+0.090339 0.120408 0.0696529 0.00689617 1 0
+0.262019 0.0920942 0.188904 0.00850721 1 0
+0.266705 0.121891 0.180648 0.00733623 1 0
+0.243492 0.119364 0.185346 0.00985739 1 0
+0.265228 0.0970171 0.153937 0.00631729 1 0
+0.386732 0.186006 0.0490056 0.0075897 1 0
+0.391645 0.153252 0.0174181 0.00874731 1 0
+0.0164142 0.169571 0.0469836 0.00510672 1 0
+0.0162801 0.146559 0.0269116 0.00578039 1 0
+0.0336765 0.137425 0.0465965 0.00640884 1 0
+0.0352034 0.153494 0.042736 0.00671905 1 0
+0.393189 0.145792 0.170589 0.00703241 1 0
+0.393971 0.175462 0.142844 0.00637997 1 0
+0.393145 0.142807 0.143542 0.006247 1 0
+0.378366 0.151838 0.156955 0.00527381 1 0
+0.381775 0.0767982 0.00497851 0.00506417 1 0
+0.384389 0.110274 0.00625307 0.00656743 1 0
+0.0501918 0.0651677 0.0751153 0.00698474 1 0
+0.0522839 0.0587165 0.0514569 0.00649157 1 0
+0.217106 0.0220904 0.0114196 0.00546845 1 0
+0.20051 0.0538623 0.0172405 0.0068967 1 0
+0.222733 0.0473342 0.0279354 0.00572104 1 0
+0.261327 0.0222179 0.186737 0.00551997 1 0
+0.300809 0.0175195 0.00825984 0.0083 1 0
+0.278985 0.0387736 0.00632486 0.00651096 1 0
+0.0868131 0.14207 0.00723754 0.00730909 1 0
+0.111635 0.139991 0.0197633 0.00503765 1 0
+0.103829 0.139937 0.0308627 0.00710114 1 0
+0.0486418 0.113671 0.00631207 0.00680382 1 0
+0.0276864 0.110959 0.0271024 0.00789287 1 0
+0.189698 0.0844834 0.00680689 0.00718779 1 0
+0.165699 0.11211 0.0107286 0.00868968 1 0
+0.213054 0.136856 0.0377959 0.00641269 1 0
+0.205379 0.128465 0.0764922 0.00779672 1 0
+0.210352 0.14347 0.0803363 0.00847115 1 0
+0.19583 0.147316 0.0427877 0.00687583 1 0
+0.203294 0.0652706 0.173102 0.00790694 1 0
+0.195976 0.0856479 0.140561 0.00794527 1 0
+0.198447 0.0571985 0.161029 0.00740396 1 0
+0.271409 0.00778163 0.00978963 0.0049704 1 0
+0.294126 0.00627609 0.01453 0.00645502 1 0
+0.28841 0.183894 0.158858 0.00510762 1 0
+0.269919 0.183373 0.131083 0.00614539 1 0
+0.29785 0.164485 0.122122 0.00688027 1 0
+0.377503 0.106226 0.0875702 0.00694416 1 0
+0.386703 0.127112 0.110159 0.00913205 1 0
+0.357162 0.124419 0.0912405 0.00725182 1 0
+0.0095061 0.116134 0.0277109 0.0070637 1 0
+0.00773396 0.0931842 0.051083 0.0050224 1 0
+0.00649546 0.115939 0.0538062 0.00667849 1 0
+0.0282208 0.110772 0.0450519 0.00622384 1 0
+0.394226 0.100204 0.186616 0.00590458 1 0
+0.390406 0.111207 0.183462 0.0060037 1 0
+0.371822 0.111796 0.16477 0.00589004 1 0
+0.320528 0.0880744 0.0322957 0.00945677 1 0
+0.298506 0.108633 0.0320131 0.00953935 1 0
+0.27853 0.09926 0.0699264 0.00818781 1 0
+0.31458 0.122673 0.0613605 0.0144611 1 0
+0.0293974 0.107606 0.126394 0.00543034 1 0
+0.0588922 0.124193 0.121338 0.00801985 1 0
+0.0424652 0.102032 0.131962 0.00553475 1 0
+0.364571 0.122046 0.00864333 0.0089966 1 0
+0.327554 0.121654 0.0148372 0.0124066 1 0
+0.333016 0.124314 0.0330948 0.00683507 1 0
+0.105421 0.0127092 0.192345 0.00790702 1 0
+0.137771 0.0134939 0.193549 0.00659779 1 0
+0.122142 0.0399081 0.190873 0.00657837 1 0
+0.0360628 0.14824 0.195135 0.00498531 1 0
+0.0487747 0.130945 0.194461 0.00520711 1 0
+0.0114236 0.190122 0.0171162 0.00624084 1 0
+0.00719424 0.185625 0.043441 0.00751635 1 0
+0.150284 0.191552 0.11361 0.00847748 1 0
+0.113937 0.170589 0.114578 0.00946019 1 0
+0.157242 0.195396 0.0739888 0.004951 1 0
+0.187169 0.191199 0.104521 0.0057037 1 0
+0.191458 0.179219 0.0751372 0.00509441 1 0
+0.179449 0.177476 0.0741934 0.00707689 1 0
+0.220758 0.131729 0.172635 0.0110727 1 0
+0.235641 0.14715 0.150809 0.00628522 1 0
+0.174845 0.0173726 0.00679136 0.00715132 1 0
+0.389 0.0262074 0.0765676 0.00740518 1 0
+0.385725 0.0576259 0.0716836 0.00494275 1 0
+0.369562 0.0489367 0.0886258 0.00875958 1 0
+0.389473 0.125925 0.0240515 0.00707116 1 0
+0.384935 0.114117 0.0640126 0.00517591 1 0
+0.358025 0.129177 0.065102 0.00532288 1 0
+0.380652 0.114116 0.0493804 0.00640348 1 0
+0.0925978 0.185847 0.176284 0.00817487 1 0
+0.103581 0.173693 0.138901 0.00526595 1 0
+0.169338 0.185191 0.144271 0.0124284 1 0
+0.190417 0.142733 0.141853 0.00703344 1 0
+0.0145455 0.0827114 0.192269 0.00671582 1 0
+0.0201515 0.118411 0.19059 0.00538755 1 0
+0.0447295 0.10804 0.190066 0.00589401 1 0
+0.372658 0.186009 0.0342008 0.00586944 1 0
+0.341111 0.193211 0.0297643 0.00725038 1 0
+0.291381 0.145337 0.0695375 0.00537388 1 0
+0.262009 0.149087 0.0586692 0.0063418 1 0
+0.272672 0.157725 0.0471531 0.00678475 1 0
+0.177522 0.191702 0.0151077 0.00871947 1 0
+0.195951 0.192488 0.042442 0.0075691 1 0
+0.223972 0.0441119 0.066088 0.00943428 1 0
+0.216549 0.0621694 0.0881533 0.00736065 1 0
+0.248009 0.0605968 0.0849173 0.00751538 1 0
+0.222064 0.056697 0.058959 0.005155 1 0
+0.204322 0.00865878 0.149084 0.00905007 1 0
+0.0179466 0.0646345 0.0477057 0.00580657 1 0
+0.0279603 0.0870887 0.0391257 0.00507917 1 0
+0.0583118 0.138382 0.13237 0.0075169 1 0
+0.0310013 0.14362 0.151161 0.00524737 1 0
+0.0781885 0.0332649 0.0108671 0.00532103 1 0
+0.0690375 0.0649554 0.0147177 0.00651158 1 0
+0.104554 0.0463637 0.00797568 0.00810448 1 0
+0.291221 0.19255 0.0657017 0.00699412 1 0
+0.314641 0.193615 0.0665849 0.00653856 1 0
+0.322512 0.174957 0.0655721 0.0117791 1 0
+0.246221 0.191961 0.0279806 0.00505252 1 0
+0.26026 0.192866 0.0414315 0.0063595 1 0
+0.226439 0.194878 0.0503368 0.0053088 1 0
+0.381734 0.0627377 0.129848 0.00505232 1 0
+0.359458 0.0626474 0.123117 0.00536539 1 0
+0.368474 0.0544648 0.140028 0.00583783 1 0
+0.371952 0.186986 0.0786659 0.00541608 1 0
+0.373149 0.188049 0.110842 0.00521248 1 0
+0.348782 0.174456 0.0904933 0.0109357 1 0
+0.370339 0.0202183 0.145735 0.00762078 1 0
+0.353047 0.036823 0.134046 0.00654898 1 0
+0.173665 0.0688826 0.112392 0.00546214 1 0
+0.00601937 0.0813715 0.168923 0.00635341 1 0
+0.00602729 0.0869847 0.136085 0.00609493 1 0
+0.0184638 0.0953948 0.160977 0.0049687 1 0
+0.0871605 0.0551548 0.11149 0.00512355 1 0
+0.121243 0.0613418 0.116861 0.00674977 1 0
+0.0104101 0.0605892 0.180056 0.00544866 1 0
+0.0264487 0.0799943 0.162158 0.00601263 1 0
+0.0255322 0.0594446 0.155259 0.00734574 1 0
+0.236368 0.0362734 0.192409 0.00762552 1 0
+0.220529 0.0553839 0.190136 0.00524858 1 0
+0.251545 0.0452632 0.169149 0.00625398 1 0
+0.258667 0.0495091 0.076911 0.0063627 1 0
+0.0844778 0.0171772 0.0142944 0.00539746 1 0
+0.104986 0.0472937 0.020959 0.00496815 1 0
+0.234017 0.123122 0.165273 0.00636487 1 0
+0.215883 0.114482 0.137351 0.00607392 1 0
+0.255968 0.107054 0.134688 0.00618773 1 0
+0.242199 0.129011 0.143615 0.00661564 1 0
+0.254621 0.0204878 0.0150463 0.0063895 1 0
+0.260334 0.046401 0.00768789 0.00812479 1 0
+0.247893 0.0462226 0.0316245 0.00700558 1 0
+0.221421 0.134262 0.0282345 0.00655456 1 0
+0.180824 0.0228593 0.187996 0.00638733 1 0
+0.213041 0.0133159 0.19237 0.00780685 1 0
+0.194998 0.0338827 0.189502 0.0106018 1 0
+0.272619 0.189084 0.0698362 0.00594189 1 0
+0.302616 0.154225 0.0769161 0.00934855 1 0
+0.264127 0.154008 0.0797161 0.00829343 1 0
+0.269698 0.168629 0.0506287 0.0050404 1 0
+0.254899 0.0132178 0.0246547 0.00566253 1 0
+0.262937 0.0114562 0.0492763 0.00654525 1 0
+0.0232101 0.185494 0.094236 0.00642635 1 0
+0.0189702 0.190582 0.104327 0.00564361 1 0
+0.394705 0.0831134 0.171396 0.0056949 1 0
+0.384951 0.0759243 0.143572 0.00518763 1 0
+0.391195 0.109337 0.137347 0.00919292 1 0
+0.377732 0.0936121 0.147022 0.00939294 1 0
+0.0611988 0.0576605 0.0342762 0.00552004 1 0
+0.132409 0.152308 0.0376554 0.00724506 1 0
+0.257384 0.0913827 0.0213397 0.00792487 1 0
+0.273538 0.105342 0.0198757 0.0126039 1 0
+0.249536 0.115752 0.00706078 0.00712634 1 0
+0.273484 0.0906132 0.0559532 0.00589563 1 0
+0.00905115 0.0140949 0.160302 0.00928439 1 0
+0.195107 0.12811 0.194695 0.00562069 1 0
+0.170111 0.136759 0.187004 0.00585134 1 0
+0.17994 0.131085 0.156562 0.00832547 1 0
+0.164357 0.0123431 0.173025 0.00531164 1 0
+0.17351 0.0145689 0.152659 0.00496858 1 0
+0.0701793 0.171675 0.188997 0.00495742 1 0
+0.0748005 0.143099 0.15452 0.00690164 1 0
+0.374541 0.189631 0.155372 0.00811457 1 0
+0.380585 0.0188822 0.0672238 0.00714736 1 0
+0.382836 0.0435632 0.061077 0.00516762 1 0
+0.364107 0.0429161 0.0770429 0.00538829 1 0
+0.37229 0.041059 0.0512871 0.00493193 1 0
+0.355692 0.0860349 0.0875009 0.00631317 1 0
+0.349618 0.116454 0.0780361 0.00525851 1 0
+0.364768 0.0981785 0.0596607 0.00789483 1 0
+0.179002 0.0116066 0.0194827 0.00589101 1 0
+0.216723 0.0137037 0.0181508 0.00529219 1 0
+0.198619 0.00990967 0.0413414 0.0101715 1 0
+0.186634 0.0338454 0.044727 0.00608557 1 0
+0.4 0.03 0.03 0.01 2 0
+0 0.03 0.03 0.01 2 0
+0.4 0.03 0.17 0.01 2 0
+0 0.03 0.17 0.01 2 0
+0.4 0.17 0.03 0.01 2 0
+0 0.17 0.03 0.01 2 0
+0.4 0.17 0.17 0.01 2 0
+0 0.17 0.17 0.01 2 0
+0.02 0.03 0.03 0.01 2 0
+0.04 0.03 0.03 0.01 2 0
+0.06 0.03 0.03 0.01 2 0
+0.08 0.03 0.03 0.01 2 0
+0.1 0.03 0.03 0.01 2 0
+0.12 0.03 0.03 0.01 2 0
+0.14 0.03 0.03 0.01 2 0
+0.16 0.03 0.03 0.01 2 0
+0.18 0.03 0.03 0.01 2 0
+0.2 0.03 0.03 0.01 2 0
+0.22 0.03 0.03 0.01 2 0
+0.24 0.03 0.03 0.01 2 0
+0.26 0.03 0.03 0.01 2 0
+0.28 0.03 0.03 0.01 2 0
+0.3 0.03 0.03 0.01 2 0
+0.32 0.03 0.03 0.01 2 0
+0.34 0.03 0.03 0.01 2 0
+0.36 0.03 0.03 0.01 2 0
+0.38 0.03 0.03 0.01 2 0
+0.02 0.03 0.17 0.01 2 0
+0.04 0.03 0.17 0.01 2 0
+0.06 0.03 0.17 0.01 2 0
+0.08 0.03 0.17 0.01 2 0
+0.1 0.03 0.17 0.01 2 0
+0.12 0.03 0.17 0.01 2 0
+0.14 0.03 0.17 0.01 2 0
+0.16 0.03 0.17 0.01 2 0
+0.18 0.03 0.17 0.01 2 0
+0.2 0.03 0.17 0.01 2 0
+0.22 0.03 0.17 0.01 2 0
+0.24 0.03 0.17 0.01 2 0
+0.26 0.03 0.17 0.01 2 0
+0.28 0.03 0.17 0.01 2 0
+0.3 0.03 0.17 0.01 2 0
+0.32 0.03 0.17 0.01 2 0
+0.34 0.03 0.17 0.01 2 0
+0.36 0.03 0.17 0.01 2 0
+0.38 0.03 0.17 0.01 2 0
+0.02 0.17 0.03 0.01 2 0
+0.04 0.17 0.03 0.01 2 0
+0.06 0.17 0.03 0.01 2 0
+0.08 0.17 0.03 0.01 2 0
+0.1 0.17 0.03 0.01 2 0
+0.12 0.17 0.03 0.01 2 0
+0.14 0.17 0.03 0.01 2 0
+0.16 0.17 0.03 0.01 2 0
+0.18 0.17 0.03 0.01 2 0
+0.2 0.17 0.03 0.01 2 0
+0.22 0.17 0.03 0.01 2 0
+0.24 0.17 0.03 0.01 2 0
+0.26 0.17 0.03 0.01 2 0
+0.28 0.17 0.03 0.01 2 0
+0.3 0.17 0.03 0.01 2 0
+0.32 0.17 0.03 0.01 2 0
+0.34 0.17 0.03 0.01 2 0
+0.36 0.17 0.03 0.01 2 0
+0.38 0.17 0.03 0.01 2 0
+0.02 0.17 0.17 0.01 2 0
+0.04 0.17 0.17 0.01 2 0
+0.06 0.17 0.17 0.01 2 0
+0.08 0.17 0.17 0.01 2 0
+0.1 0.17 0.17 0.01 2 0
+0.12 0.17 0.17 0.01 2 0
+0.14 0.17 0.17 0.01 2 0
+0.16 0.17 0.17 0.01 2 0
+0.18 0.17 0.17 0.01 2 0
+0.2 0.17 0.17 0.01 2 0
+0.22 0.17 0.17 0.01 2 0
+0.24 0.17 0.17 0.01 2 0
+0.26 0.17 0.17 0.01 2 0
+0.28 0.17 0.17 0.01 2 0
+0.3 0.17 0.17 0.01 2 0
+0.32 0.17 0.17 0.01 2 0
+0.34 0.17 0.17 0.01 2 0
+0.36 0.17 0.17 0.01 2 0
+0.38 0.17 0.17 0.01 2 0
+0.347522 0.0798775 0.189345 0.00542525 1 0
+0.0978862 0.0443223 0.157324 0.00881265 1 0
+0.392662 0.0990343 0.149296 0.00665244 1 0
+0.27 0.186275 0.156019 0.00669684 1 0
+0.356951 0.162534 0.138065 0.00842663 1 0
+0.282853 0.0239922 0.154694 0.00641626 1 0
+0.03 0.152792 0.169299 0.005642 1 0
+0.102813 0.149965 0.130103 0.0072981 1 0
+0.246362 0.124006 0.0878291 0.00776572 1 0
+0.134712 0.0782273 0.00486166 0.00518048 1 0
+0.145202 0.0420336 0.160607 0.00612731 1 0
+0.1331 0.191055 0.13096 0.00492461 1 0
+0.178568 0.0439534 0.0151785 0.00628492 1 0
+0.0369389 0.0587979 0.0362255 0.00831987 1 0
+0.324462 0.104118 0.060766 0.00656953 1 0
+0.242014 0.156239 0.0521801 0.00555918 1 0
+0.347445 0.0793337 0.0940084 0.00614759 1 0
+0.176037 0.0328676 0.119084 0.00524276 1 0
+0.203878 0.107329 0.173163 0.00650472 1 0
+0.275532 0.0453966 0.0313616 0.00608947 1 0
+0.26178 0.155021 0.0948649 0.00706965 1 0
+0.39 0.158236 0.172488 0.00563869 1 0
+0.105644 0.0790286 0.176016 0.00580547 1 0
+0.20005 0.0366356 0.0493124 0.0083647 1 0
+0.0185075 0.160973 0.130327 0.00501499 1 0
+0.300174 0.155686 0.0955826 0.00747518 1 0
+0.113642 0.0321054 0.151243 0.00816062 1 0
+0.0507885 0.15975 0.145708 0.00739224 1 0
+0.271194 0.0350138 0.151904 0.00620918 1 0
+0.201468 0.195442 0.130678 0.00505288 1 0
+0.188726 0.172934 0.0671716 0.0054132 1 0
+0.370376 0.156378 0.178879 0.00812185 1 0
+0.212651 0.051505 0.0344394 0.00698105 1 0
+0.0728915 0.0702816 0.0670054 0.00733578 1 0
+0.27 0.0222001 0.0413285 0.00700511 1 0
+0.209838 0.078913 0.158632 0.00692605 1 0
+0.0313396 0.169454 0.0453461 0.00637858 1 0
+0.380556 0.0338425 0.153157 0.00728474 1 0
+0.327886 0.154734 0.118663 0.00729678 1 0
+0.35 0.157495 0.0225033 0.00747683 1 0
+0.0649327 0.050875 0.110639 0.00808269 1 0
+0.152733 0.0857879 0.179473 0.00634748 1 0
+0.288763 0.147693 0.0341985 0.0094579 1 0
+0.11 0.0433635 0.0307431 0.00670737 1 0
+0.361312 0.0139639 0.152203 0.00512422 1 0
+0.220006 0.095739 0.171783 0.00552227 1 0
+0.339671 0.181996 0.18433 0.00656595 1 0
+0.267395 0.194784 0.109548 0.00565878 1 0
+0.308662 0.0124479 0.173343 0.00896394 1 0
+0.253811 0.0926573 0.109213 0.0106235 1 0
+0.392837 0.123744 0.178331 0.00689455 1 0
+0.220257 0.0991966 0.0646123 0.0143061 1 0
+0.149942 0.0119581 0.0950768 0.00568721 1 0
+0.021108 0.192638 0.0225377 0.00513947 1 0
+0.202093 0.121861 0.111158 0.00779051 1 0
+0.364844 0.0434614 0.0223083 0.00624303 1 0
+0.0816671 0.141038 0.0995708 0.00766147 1 0
+0.356446 0.160479 0.0471579 0.00994152 1 0
+0.0450777 0.18198 0.0420726 0.0054801 1 0
+0.359875 0.0893131 0.177108 0.00504329 1 0
+0.0983642 0.130066 0.170333 0.00574947 1 0
+0.0337275 0.0454853 0.184088 0.00520309 1 0
+0.260472 0.183642 0.0225082 0.00557063 1 0
+0.320423 0.153275 0.0290202 0.00675951 1 0
+0.142201 0.152845 0.144419 0.0122891 1 0
+0.236239 0.12794 0.17545 0.00511185 1 0
+0.253457 0.0513097 0.0973065 0.00889881 1 0
+0.292661 0.0883479 0.0835194 0.0103442 1 0
+0.29 0.019008 0.0211345 0.00730379 1 0
+0.206797 0.109716 0.0158543 0.00644442 1 0
+0.00485992 0.157468 0.0570503 0.00495699 1 0
+0.151719 0.0532074 0.109485 0.00820095 1 0
+0.207828 0.170978 0.14269 0.00686123 1 0
+0.207725 0.0420149 0.179824 0.00733632 1 0
+0.270731 0.14459 0.099749 0.0060311 1 0
+0.184316 0.122176 0.187476 0.00577481 1 0
+0.140387 0.0445274 0.0230222 0.00612092 1 0
+0.160369 0.1527 0.0415237 0.00674556 1 0
+0.300792 0.147145 0.15994 0.00929333 1 0
+0.0525256 0.0915602 0.179181 0.00589334 1 0
+0.129693 0.175565 0.0426627 0.00688964 1 0
+0.299318 0.0291523 0.0845295 0.00620838 1 0
+0.00962742 0.0170789 0.119014 0.00614714 1 0
+0.26608 0.0134887 0.0245473 0.0055224 1 0
+0.359626 0.145645 0.018462 0.00831556 1 0
+0.264127 0.048321 0.0226428 0.00742254 1 0
+0.296538 0.081742 0.100029 0.00744197 1 0
+0.345111 0.0473617 0.172251 0.00823776 1 0
+0.0868119 0.108331 0.0569456 0.00585534 1 0
+0.174245 0.131957 0.0322579 0.00524247 1 0
+0.12388 0.118941 0.0234175 0.00751806 1 0
+0.334458 0.0902555 0.188535 0.0100815 1 0
+0.195442 0.0683869 0.120811 0.00520101 1 0
+0.33765 0.0317681 0.0132248 0.00499725 1 0
+0.0139264 0.0661681 0.057607 0.00498931 1 0
+0.366444 0.176412 0.0907763 0.00508473 1 0
+0.251406 0.18165 0.175613 0.00552709 1 0
+0.0480855 0.0204338 0.179939 0.00598943 1 0
+0.342488 0.0409397 0.10765 0.00671023 1 0
+0.172764 0.118587 0.043688 0.00660758 1 0
+0.33 0.0380642 0.179743 0.0061229 1 0
+0.177923 0.116745 0.0232329 0.00649864 1 0
+0.0434834 0.147828 0.0215313 0.0051462 1 0
+0.130758 0.0473001 0.0975034 0.00695327 1 0
+0.272865 0.0192001 0.132966 0.00589323 1 0
+0.265019 0.150946 0.168352 0.00741564 1 0
+0.24418 0.0141703 0.0369479 0.00778553 1 0
+0.336748 0.170515 0.077577 0.0071526 1 0
+0.184562 0.178649 0.112849 0.00958207 1 0
+0.362317 0.110098 0.0861787 0.00522559 1 0
+0.157402 0.116345 0.119616 0.00810692 1 0
+0.208746 0.0329015 0.0825929 0.00742124 1 0
+0.0497274 0.0591842 0.0861661 0.00559058 1 0
+0.01 0.0185565 0.177554 0.00697095 1 0
+0.0728359 0.0892859 0.0249654 0.00991388 1 0
+0.00664008 0.149212 0.0165518 0.00717416 1 0
+0.214491 0.0193724 0.180289 0.00578476 1 0
+0.277068 0.191227 0.0809189 0.00619127 1 0
+0.0424533 0.104161 0.0716172 0.00799191 1 0
+0.31 0.0402308 0.0232237 0.00582996 1 0
+0.27754 0.184929 0.172891 0.00540447 1 0
+0.252694 0.158786 0.0735484 0.00554851 1 0
+0.3085 0.0988447 0.149485 0.0110854 1 0
+0.146358 0.0654075 0.176887 0.00852953 1 0
+0.15028 0.0850435 0.124902 0.0097613 1 0
+0.331544 0.04829 0.19056 0.00819168 1 0
+0.351251 0.101156 0.135048 0.00589803 1 0
+0.186782 0.165407 0.083592 0.00584857 1 0
+0.325097 0.166509 0.185233 0.00643767 1 0
+0.0918322 0.180427 0.0413606 0.00745013 1 0
+0.160433 0.0312632 0.152793 0.00725904 1 0
+0.17575 0.0105614 0.189975 0.00706232 1 0
+0.11 0.0178155 0.165291 0.00645094 1 0
+0.209597 0.178443 0.177733 0.00493965 1 0
+0.0474925 0.152649 0.157478 0.00674388 1 0
+0.0970484 0.187071 0.0748803 0.00561971 1 0
+0.127766 0.16398 0.184554 0.00756034 1 0
+0.138599 0.0762437 0.189021 0.00663846 1 0
+0.091639 0.0976758 0.118241 0.00951811 1 0
+0.37809 0.0472335 0.165234 0.0079822 1 0
+0.09 0.155653 0.166236 0.0078889 1 0
+0.222052 0.0741071 0.101548 0.00603959 1 0
+0.360558 0.156651 0.0895007 0.0104342 1 0
+0.0209121 0.156322 0.178298 0.00574117 1 0
+0.275085 0.0433949 0.176447 0.00565728 1 0
+0.132939 0.151075 0.159076 0.00513916 1 0
+0.338449 0.0869435 0.0180735 0.00838531 1 0
+0.255873 0.0180861 0.178487 0.00519845 1 0
+0.19 0.178801 0.0412054 0.0074073 1 0
+0.24197 0.150359 0.0663884 0.00600992 1 0
+0.366987 0.0483655 0.151525 0.00651083 1 0
+0.258204 0.0950625 0.0787748 0.0143746 1 0
+0.313156 0.0696813 0.0855558 0.00515003 1 0
+0.0224121 0.161022 0.017894 0.00526373 1 0
+0.378217 0.181987 0.0709204 0.0053618 1 0
+0.336389 0.151644 0.165116 0.00933514 1 0
+0.265528 0.039234 0.181998 0.00611775 1 0
+0.0774819 0.181246 0.0528093 0.0054311 1 0
+0.366662 0.0219018 0.158378 0.00565348 1 0
+0.159721 0.0359766 0.0451912 0.00632694 1 0
+0.153264 0.142666 0.0149768 0.00576333 1 0
+0.267688 0.0789297 0.0281816 0.00545798 1 0
+0.359133 0.041135 0.10209 0.00997302 1 0
+0.27 0.156557 0.179664 0.00615902 1 0
+0.157162 0.0928317 0.0624114 0.00930508 1 0
+0.24382 0.0682745 0.191382 0.00498369 1 0
+0.030824 0.119874 0.0824092 0.00589828 1 0
+0.0607368 0.0719771 0.121373 0.006561 1 0
+0.182555 0.0870453 0.131754 0.00758449 1 0
+0.249288 0.171861 0.00902276 0.00894261 1 0
+0.128277 0.140272 0.0478176 0.00904013 1 0
+0.39 0.0408851 0.179636 0.00764493 1 0
+0.344839 0.0246951 0.0561511 0.00517938 1 0
+0.374681 0.124486 0.022 0.00793192 1 0
+0.172293 0.0940976 0.0800211 0.00723459 1 0
+0.189986 0.15199 0.152309 0.0069387 1 0
+0.0808306 0.0847432 0.0775252 0.00801434 1 0
+0.35 0.0244296 0.180218 0.00534406 1 0
+0.29128 0.068629 0.089716 0.00854914 1 0
+0.370536 0.00948985 0.15318 0.00517375 1 0
+0.138975 0.029358 0.0148715 0.0051768 1 0
+0.229972 0.163942 0.156787 0.0076274 1 0
+0.0458068 0.0745883 0.105977 0.00800304 1 0
+0.387971 0.13337 0.0972578 0.005263 1 0
+0.267418 0.123144 0.103298 0.00717081 1 0
+0.289479 0.116327 0.166929 0.00597564 1 0
+0.0076274 0.0163704 0.0386944 0.00763753 1 0
+0.168509 0.182954 0.0239459 0.006639 1 0
+0.15 0.176936 0.0391289 0.00521332 1 0
+0.37 0.158822 0.0381978 0.00639058 1 0
+0.393535 0.192952 0.0828301 0.0070797 1 0
+0.220561 0.152147 0.0267704 0.0081512 1 0
+0.0723325 0.16431 0.182063 0.00538414 1 0
+0.334911 0.0744686 0.0606515 0.00522857 1 0
+0.235834 0.026813 0.0458702 0.00671452 1 0
+0.195435 0.0170165 0.162842 0.00551265 1 0
+0.269892 0.0607274 0.109486 0.00883171 1 0
+0.343501 0.0709899 0.0209709 0.0057976 1 0
+0.222355 0.0915619 0.123518 0.00627954 1 0
+0.14512 0.0672658 0.124313 0.00713699 1 0
+0.0789361 0.0122478 0.165528 0.00833777 1 0
+0.303859 0.120825 0.105216 0.00568384 1 0
+0.0668885 0.187978 0.0470427 0.0057157 1 0
+0.0474666 0.176518 0.156891 0.00643413 1 0
+0.0546208 0.00894538 0.0542628 0.00499468 1 0
+0.163881 0.165255 0.0156245 0.00562792 1 0
+0.264941 0.0352942 0.0524973 0.00526542 1 0
+0.0682807 0.131748 0.126804 0.00521273 1 0
+0.31 0.0414694 0.0383149 0.00734023 1 0
+0.293551 0.0411853 0.146535 0.00674033 1 0
+0.259371 0.101169 0.0300947 0.00535567 1 0
+0.0236936 0.19498 0.117863 0.00556218 1 0
+0.194553 0.0960323 0.00662746 0.00534121 1 0
+0.144031 0.00765253 0.0145084 0.00790903 1 0
+0.387286 0.0283025 0.183463 0.00540204 1 0
+0.190849 0.085665 0.042132 0.0058276 1 0
+0.337163 0.0493615 0.0297166 0.00957028 1 0
+0.0702921 0.0508055 0.0761078 0.00887061 1 0
+0.363204 0.079317 0.031058 0.00585507 1 0
+0.0239026 0.0171388 0.0732999 0.00558563 1 0
+0.31 0.171377 0.0410328 0.00495384 1 0
+0.242897 0.0431399 0.157876 0.00764433 1 0
+0.0232279 0.0625859 0.0569853 0.00499752 1 0
+0.308419 0.154837 0.0283139 0.00536722 1 0
+0.351596 0.0296902 0.0490809 0.00580207 1 0
+0.00724216 0.107479 0.173821 0.0052565 1 0
+0.320234 0.110807 0.157754 0.00760032 1 0
+0.10993 0.17569 0.0450187 0.00888243 1 0
+0.0556015 0.0166924 0.153296 0.0118053 1 0
+0.255539 0.0102831 0.109715 0.00796557 1 0
+0.146502 0.158052 0.0927089 0.00542645 1 0
+0.105747 0.0703886 0.184545 0.00523508 1 0
+0.32732 0.123906 0.044966 0.00633809 1 0
+0.167621 0.160837 0.179697 0.00536462 1 0
+0.156603 0.15324 0.169971 0.00710102 1 0
+0.308484 0.164311 0.181512 0.00539052 1 0
+0.0635922 0.181646 0.183508 0.00623565 1 0
+0.0488876 0.155546 0.17358 0.00734124 1 0
+0.05 0.161337 0.0228354 0.00504587 1 0
+0.333482 0.115593 0.0639115 0.00588445 1 0
+0.311958 0.0137062 0.111868 0.00852586 1 0
+0.07 0.0223539 0.18273 0.00591058 1 0
+0.00719179 0.070529 0.0416848 0.00606667 1 0
+0.101032 0.0195252 0.155612 0.00685467 1 0
+0.0254764 0.0434224 0.0366104 0.00593267 1 0
+0.0697503 0.14859 0.103677 0.00703194 1 0
+0.0853097 0.164886 0.121862 0.00635816 1 0
+0.261932 0.182529 0.103209 0.0052298 1 0
+0.287308 0.151721 0.168501 0.00726717 1 0
+0.0169782 0.15904 0.0805994 0.0050559 1 0
+0.14364 0.0674591 0.13787 0.0055179 1 0
+0.231317 0.120206 0.0514386 0.00936835 1 0
+0.0573314 0.122786 0.19436 0.00603971 1 0
+0.0281059 0.0184631 0.021398 0.00499663 1 0
+0.263591 0.0639061 0.174787 0.00656042 1 0
+0.0581201 0.184798 0.163389 0.00631669 1 0
+0.179217 0.044415 0.158281 0.00766895 1 0
+0.0731051 0.0881463 0.180648 0.00529527 1 0
+0.09 0.0359271 0.0194755 0.0049713 1 0
+0.23 0.157473 0.178684 0.0080108 1 0
+0.341498 0.194203 0.0117522 0.00650448 1 0
+0.391166 0.10602 0.0685237 0.0059928 1 0
+0.358029 0.0186959 0.108716 0.00560939 1 0
+0.329772 0.17071 0.121833 0.00909976 1 0
+0.335608 0.0574737 0.173582 0.0057023 1 0
+0.331246 0.159417 0.103862 0.0085865 1 0
+0.0563992 0.0102386 0.185024 0.00576244 1 0
+0.213145 0.0479381 0.170198 0.00519868 1 0
+0.0938822 0.161259 0.0546349 0.00524396 1 0
+0.264021 0.027745 0.0944503 0.00506959 1 0
+0.140928 0.0777212 0.176066 0.00495326 1 0
+0.161296 0.115551 0.0985767 0.00666958 1 0
+0.280353 0.130673 0.178957 0.00528118 1 0
+0.156516 0.136071 0.178792 0.00753372 1 0
+0.251158 0.0395676 0.121355 0.00764725 1 0
+0.326188 0.034959 0.0461858 0.00591718 1 0
+0.217008 0.055159 0.00923339 0.0062824 1 0
+0.24511 0.0178481 0.0217576 0.00554719 1 0
+0.192659 0.033758 0.130776 0.00667871 1 0
+0.134313 0.00674791 0.123773 0.00571604 1 0
+0.25894 0.00798155 0.142322 0.00527416 1 0
+0.0989189 0.138211 0.188624 0.00693057 1 0
+0.188807 0.154195 0.0314249 0.00814928 1 0
+0.0465999 0.0158036 0.0306726 0.00566998 1 0
+0.21 0.178166 0.16205 0.00516225 1 0
+0.103462 0.0747507 0.162656 0.00566988 1 0
+0.232491 0.186303 0.165265 0.00743411 1 0
+0.0948224 0.0458309 0.0355574 0.00719834 1 0
+0.137066 0.0453262 0.182442 0.00595659 1 0
+0.0606057 0.0509872 0.139644 0.00577137 1 0
+0.118997 0.0803134 0.0169132 0.00963772 1 0
+0.0648667 0.150087 0.129484 0.00620631 1 0
+0.13 0.168638 0.0183636 0.00540324 1 0
+0.328037 0.00816448 0.0789749 0.00836521 1 0
+0.261785 0.0674796 0.0860459 0.00765607 1 0
+0.265839 0.12281 0.0595413 0.0109387 1 0
+0.125226 0.108533 0.114202 0.00615113 1 0
+0.215342 0.155261 0.153166 0.0062645 1 0
+0.189995 0.0465725 0.0353405 0.00970266 1 0
+0.0885535 0.0561785 0.184883 0.00626981 1 0
+0.121939 0.169556 0.15395 0.00617321 1 0
+0.11 0.174743 0.0199283 0.00496436 1 0
+0.331276 0.142067 0.0574075 0.0114335 1 0
+0.0469555 0.0789318 0.0751397 0.00502226 1 0
+0.20313 0.095668 0.132944 0.0065325 1 0
+0.0264725 0.182658 0.163376 0.00525103 1 0
+0.0549236 0.0830398 0.0891248 0.0062925 1 0
+0.309388 0.0495779 0.0630322 0.00534495 1 0
+0.234442 0.182998 0.0358474 0.00529841 1 0
+0.206371 0.159944 0.0584285 0.00581264 1 0
+0.306901 0.125028 0.0251801 0.010106 1 0
+0.101812 0.0251804 0.129384 0.00802216 1 0
+0.369995 0.173609 0.181455 0.00562445 1 0
+0.349316 0.114621 0.138382 0.00538571 1 0
+0.330089 0.129989 0.143439 0.00887266 1 0
+0.115997 0.191979 0.0698904 0.00832214 1 0
+0.177899 0.0857562 0.112367 0.00852281 1 0
+0.072263 0.030518 0.111296 0.00596901 1 0
+0.352759 0.136596 0.0576396 0.00644424 1 0
+0.230748 0.0966892 0.17339 0.00538032 1 0
+0.0458287 0.0433015 0.158147 0.00874561 1 0
+0.0980732 0.171347 0.0552498 0.00569654 1 0
+0.305693 0.155839 0.127417 0.00593698 1 0
+0.335309 0.126327 0.0706772 0.00693509 1 0
+0.314188 0.143696 0.103088 0.0107034 1 0
+0.142819 0.173227 0.0858479 0.0112391 1 0
+0.31 0.0348089 0.180252 0.00510729 1 0
+0.15 0.0436508 0.0331577 0.00721381 1 0
+0.19796 0.0280548 0.148822 0.00873619 1 0
+0.287608 0.0440149 0.181191 0.00508972 1 0
+0.234242 0.0276053 0.0936894 0.00535566 1 0
+0.200447 0.0930969 0.0415927 0.00509391 1 0
+0.33 0.0395939 0.0215398 0.00504401 1 0
+0.108655 0.0741489 0.140021 0.00772278 1 0
+0.23 0.0336803 0.155098 0.00832 1 0
+0.05 0.0465513 0.0365519 0.0095876 1 0
+0.102633 0.158261 0.0806719 0.00520046 1 0
+0.30296 0.116641 0.142802 0.00871556 1 0
+0.146636 0.0086573 0.0811116 0.00646753 1 0
+0.248061 0.150212 0.159558 0.00759468 1 0
+0.0511742 0.126609 0.00468162 0.00493993 1 0
+0.160765 0.14026 0.105735 0.00630499 1 0
+0.203703 0.132457 0.169937 0.00620977 1 0
+0.287417 0.086656 0.114549 0.00635341 1 0
+0.0993595 0.191428 0.098834 0.00507766 1 0
+0.313624 0.145026 0.121706 0.00796975 1 0
+0.122538 0.15124 0.154183 0.00635657 1 0
+0.0604078 0.0152021 0.123458 0.00542286 1 0
+0.0223381 0.125728 0.135981 0.00585759 1 0
+0.315672 0.149159 0.0607302 0.00602484 1 0
+0.3332 0.164513 0.0123964 0.00965288 1 0
+0.37582 0.172889 0.0147571 0.00606757 1 0
+0.052553 0.0588091 0.110053 0.00604681 1 0
+0.140355 0.0965998 0.0802462 0.0122419 1 0
+0.0973348 0.00627142 0.0760289 0.00540746 1 0
+0.279178 0.0296219 0.185108 0.00513539 1 0
+0.00445371 0.0476518 0.120346 0.00494855 1 0
+0.0644919 0.191953 0.00716455 0.00588954 1 0
+0.0869399 0.0810823 0.10593 0.0102924 1 0
+0.340655 0.171237 0.140926 0.00589336 1 0
+0.237862 0.110315 0.0055321 0.00579299 1 0
+0.320733 0.173027 0.0827873 0.00563505 1 0
+0.144934 0.0258788 0.0882664 0.00526551 1 0
+0.101809 0.0163963 0.176675 0.00526074 1 0
+0.107666 0.0199858 0.0178321 0.00611792 1 0
+0.0498234 0.0372418 0.0210861 0.00511295 1 0
+0.110865 0.0949012 0.0684746 0.0052638 1 0
+0.38057 0.176806 0.0552643 0.00512958 1 0
+0.197033 0.114059 0.138863 0.0084076 1 0
+0.249194 0.109915 0.166191 0.00529529 1 0
+0.0862794 0.154898 0.17898 0.00540933 1 0
+0.27033 0.12531 0.0158457 0.00713187 1 0
+0.32917 0.0623616 0.0191554 0.00725251 1 0
+0.0834931 0.060607 0.0794537 0.00790831 1 0
+0.00791223 0.0940613 0.176638 0.00505783 1 0
+0.0787373 0.191473 0.104354 0.00497613 1 0
+0.354648 0.0809409 0.165555 0.00512381 1 0
+0.195343 0.0213989 0.0684254 0.00535459 1 0
+0.202165 0.116979 0.091119 0.011077 1 0
+0.183385 0.12038 0.10588 0.0066955 1 0
+0.100627 0.181147 0.150607 0.00892321 1 0
+0.184063 0.182109 0.0222756 0.00492635 1 0
+0.269945 0.0508076 0.0970386 0.00613515 1 0
+0.223061 0.0442632 0.164099 0.00573653 1 0
+0.379559 0.149125 0.1674 0.00558254 1 0
+0.166691 0.0981379 0.126571 0.0102523 1 0
+0.146453 0.178477 0.0102732 0.00546206 1 0
+0.250081 0.139208 0.105752 0.00666326 1 0
+0.0828624 0.049343 0.0991538 0.00917406 1 0
+0.114047 0.157075 0.0674288 0.00748147 1 0
+0.325864 0.0379841 0.102682 0.00760018 1 0
+0.0865448 0.0333339 0.154956 0.00674158 1 0
+0.179765 0.0194648 0.159028 0.00521305 1 0
+0.158754 0.0550893 0.0664386 0.00526478 1 0
+0.268519 0.0975019 0.126336 0.00843922 1 0
+0.0780719 0.0491939 0.0311838 0.00541201 1 0
+0.333234 0.187204 0.0596276 0.00554904 1 0
+0.209764 0.108087 0.146589 0.0067205 1 0
+0.184083 0.128664 0.130131 0.0123429 1 0
+0.286562 0.0698164 0.19439 0.0059234 1 0
+0.03 0.167223 0.158687 0.00535208 1 0
+0.0905275 0.0637841 0.115981 0.00517076 1 0
+0.0903216 0.0828469 0.0253702 0.00656234 1 0
+0.21 0.181115 0.0256308 0.00557701 1 0
+0.392997 0.123522 0.0881469 0.00713771 1 0
+0.27 0.177572 0.0390839 0.00548721 1 0
+0.341463 0.070823 0.130651 0.00521516 1 0
+0.0368654 0.0432709 0.0217789 0.00592252 1 0
+0.19 0.0188588 0.0323655 0.00515657 1 0
+0.11 0.0373125 0.019389 0.00609366 1 0
+0.102 0.0568128 0.166768 0.00737801 1 0
+0.37 0.16207 0.157379 0.0079496 1 0
+0.372113 0.105287 0.140051 0.00531965 1 0
+0.00599721 0.0650202 0.0947234 0.00597836 1 0
+0.24746 0.0529289 0.0668096 0.00629904 1 0
+0.0104065 0.136024 0.0294409 0.00654423 1 0
+0.231698 0.130363 0.18604 0.00628433 1 0
+0.29 0.0290446 0.044384 0.00754462 1 0
+0.028435 0.130973 0.0597217 0.00492464 1 0
+0.367429 0.109044 0.174486 0.00512261 1 0
+0.262766 0.0628471 0.0261988 0.00537886 1 0
+0.258736 0.100411 0.00488452 0.00494719 1 0
+0.321904 0.12017 0.085994 0.0113597 1 0
+0.262991 0.0494983 0.190873 0.00682598 1 0
+0.03 0.0189616 0.177748 0.00507591 1 0
+0.0587581 0.0997631 0.159554 0.00614663 1 0
+0.0638137 0.00656929 0.0414673 0.00611381 1 0
+0.11821 0.026267 0.0533042 0.00661779 1 0
+0.33 0.0415766 0.169184 0.005005 1 0
+0.345193 0.112954 0.163829 0.00498868 1 0
+0.392254 0.0472032 0.0473154 0.0054577 1 0
+0.0286494 0.11133 0.0760248 0.0049874 1 0
+0.27 0.0365696 0.0170355 0.00686145 1 0
+0.13948 0.0741076 0.165953 0.00537703 1 0
+0.152228 0.180271 0.0220904 0.00511481 1 0
+0.11 0.159652 0.175278 0.0053276 1 0
+0.130342 0.0749803 0.127891 0.00794283 1 0
+0.37 0.0455926 0.178018 0.007069 1 0
+0.174904 0.15232 0.159484 0.0097671 1 0
+0.258567 0.142183 0.0704392 0.00773136 1 0
+0.221933 0.0370084 0.0950801 0.00995903 1 0
+0.273527 0.0201031 0.0938819 0.00499655 1 0
+0.374264 0.12754 0.119256 0.00628468 1 0
+0.118483 0.012984 0.0645129 0.00630568 1 0
+0.241122 0.0152128 0.15513 0.00617623 1 0
+0.0291186 0.0337872 0.0429776 0.00617698 1 0
+0.333775 0.066065 0.0826432 0.00498637 1 0
+0.37 0.181074 0.0233665 0.00632907 1 0
+0.223202 0.18819 0.0923402 0.00498807 1 0
+0.346015 0.0269364 0.134661 0.00559914 1 0
+0.07 0.0416623 0.178629 0.00762019 1 0
+0.280236 0.0510122 0.119443 0.00670719 1 0
+0.261681 0.0470373 0.126408 0.005187 1 0
+0.307872 0.125585 0.172237 0.00807778 1 0
+0.37691 0.0493025 0.0547169 0.00512084 1 0
+0.199809 0.142591 0.11782 0.00520728 1 0
+0.290256 0.175235 0.122551 0.00533184 1 0
+0.359318 0.162337 0.0625626 0.00527138 1 0
+0.266254 0.130207 0.0276945 0.00581197 1 0
+0.216126 0.102205 0.136049 0.00568307 1 0
+0.305954 0.165733 0.085845 0.00559505 1 0
+0.194504 0.103429 0.179534 0.00548175 1 0
+0.0595778 0.17011 0.0454706 0.00547673 1 0
+0.120786 0.149805 0.0197906 0.00838019 1 0
+0.226249 0.0744244 0.115243 0.00828741 1 0
+0.229092 0.0811134 0.0322316 0.0060468 1 0
+0.0234179 0.155289 0.0264939 0.00512035 1 0
+0.0953025 0.0401542 0.182022 0.00642255 1 0
+0.24542 0.121912 0.0445354 0.0058618 1 0
+0.250948 0.153357 0.027401 0.00830815 1 0
+0.14512 0.0114577 0.184325 0.00537055 1 0
+0.229495 0.0740694 0.0408994 0.00512964 1 0
+0.245814 0.0900784 0.0454943 0.00532297 1 0
+0.3414 0.125404 0.0907135 0.00854917 1 0
+0.0809721 0.133603 0.142928 0.00715165 1 0
+0.01 0.0400683 0.175232 0.00512425 1 0
+0.175861 0.00960354 0.101807 0.0076149 1 0
+0.110409 0.0662879 0.0110968 0.00780684 1 0
+0.068644 0.126408 0.0158185 0.00551588 1 0
+0.341462 0.0416071 0.0919578 0.00625069 1 0
+0.237534 0.0419936 0.0999316 0.00501946 1 0
+0.0621255 0.0923219 0.0886774 0.0050362 1 0
+0.219184 0.0495255 0.0811933 0.00731089 1 0
+0.387963 0.0545049 0.0624941 0.00501702 1 0
+0.139508 0.0367064 0.0988393 0.00498963 1 0
+0.11 0.0189772 0.0326292 0.00511339 1 0
+0.266344 0.0950372 0.139461 0.00509116 1 0
+0.307471 0.185989 0.0714464 0.00500287 1 0
+0.181953 0.0950166 0.00545282 0.0055711 1 0
+0.118734 0.0115042 0.0312841 0.00512618 1 0
+0.15 0.160336 0.0231105 0.00551957 1 0
+0.22619 0.0202691 0.0185718 0.00623608 1 0
+0.276323 0.0724613 0.123032 0.00660369 1 0
+0.220569 0.076601 0.172806 0.00492155 1 0
+0.100232 0.131322 0.143208 0.00639902 1 0
+0.394782 0.0236983 0.13031 0.00492271 1 0
+0.382281 0.0185517 0.0169469 0.00592855 1 0
+0.22683 0.0322293 0.0166972 0.00511889 1 0
+0.0489981 0.170903 0.18261 0.0055178 1 0
+0.349467 0.075473 0.0104567 0.00518068 1 0
+0.139219 0.109415 0.0104712 0.00569116 1 0
+0.240757 0.104913 0.175124 0.00559638 1 0
+0.0937754 0.0174482 0.140284 0.00660599 1 0
+0.218027 0.187273 0.070854 0.00499785 1 0
+0.246405 0.0970869 0.0365274 0.00607323 1 0
+0.287901 0.18408 0.0332955 0.00647807 1 0
+0.376126 0.100972 0.0352068 0.00496434 1 0
+0.209984 0.155755 0.164863 0.00661049 1 0
+0.0273352 0.180617 0.179068 0.00577195 1 0
+0.175007 0.0219339 0.0183149 0.00505085 1 0
+0.0228989 0.0946957 0.170487 0.00554807 1 0
+0.0314103 0.0460342 0.165143 0.00751195 1 0
+0.370248 0.0450066 0.0410144 0.00626097 1 0
+0.27816 0.0123399 0.0452198 0.00530145 1 0
+0.39 0.176178 0.18115 0.00620133 1 0
+0.256466 0.186298 0.11359 0.00675823 1 0
+0.357651 0.140973 0.158994 0.00677486 1 0
+0.33 0.176801 0.161228 0.00494019 1 0
+0.28369 0.16306 0.0484567 0.00552614 1 0
+0.209807 0.0179606 0.135153 0.00640212 1 0
+0.374754 0.113029 0.0121099 0.00503982 1 0
+0.0743218 0.0220835 0.0127212 0.00599074 1 0
+0.18094 0.170539 0.128215 0.00762202 1 0
+0.09 0.0187735 0.176421 0.00634823 1 0
+0.05 0.181269 0.0284853 0.00514207 1 0
+0.382123 0.104338 0.155546 0.00499356 1 0
+0.32331 0.0201479 0.0853821 0.0060223 1 0
+0.21477 0.166049 0.0164699 0.00503424 1 0
+0.360868 0.0609557 0.111799 0.00616562 1 0
+0.18085 0.0321406 0.14269 0.00675333 1 0
+0.376028 0.1525 0.195405 0.00500279 1 0
+0.23225 0.024593 0.184328 0.00716327 1 0
+0.101793 0.10075 0.0728653 0.00600643 1 0
+0.12091 0.179599 0.0179687 0.00541848 1 0
+0.0640294 0.159891 0.0402461 0.00494685 1 0
+0.154054 0.185061 0.159621 0.00923332 1 0
+0.132175 0.0181216 0.17936 0.0067317 1 0
+0.23 0.180445 0.0248208 0.00535967 1 0
+0.11 0.15442 0.0350109 0.00917913 1 0
+0.156521 0.0697386 0.118669 0.00582222 1 0
+0.309131 0.137733 0.184422 0.00778363 1 0
+0.366573 0.021133 0.181724 0.00603386 1 0
+0.358072 0.127979 0.121924 0.005249 1 0
+0.12069 0.108055 0.166835 0.00967485 1 0
+0.35182 0.095704 0.174893 0.00547524 1 0
+0.27 0.167186 0.0407491 0.00494861 1 0
+0.13 0.0433101 0.031196 0.00669101 1 0
+0.0081316 0.173136 0.0422839 0.00506157 1 0
+0.122184 0.140332 0.0098268 0.00543885 1 0
+0.0236819 0.0581298 0.119657 0.0051633 1 0
+0.07 0.0351198 0.155468 0.00836856 1 0
+0.10544 0.111304 0.04461 0.00622339 1 0
+0.31127 0.0701473 0.114328 0.0058661 1 0
+0.354215 0.0480357 0.0842499 0.00633501 1 0
+0.0804859 0.0484113 0.171363 0.0068126 1 0
+0.172237 0.115855 0.106807 0.00537165 1 0
+0.0455084 0.160394 0.0412336 0.00577368 1 0
+0.202462 0.0695508 0.160314 0.00511081 1 0
+0.127363 0.189716 0.0842867 0.00989146 1 0
+0.0967372 0.10246 0.175354 0.00649448 1 0
+0.29834 0.054986 0.0621569 0.00507099 1 0
+0.339449 0.0122872 0.0219697 0.00582351 1 0
+0.339266 0.172422 0.0589719 0.00640596 1 0
+0.33 0.0206983 0.181778 0.00636567 1 0
+0.266732 0.100053 0.0608677 0.00607784 1 0
+0.380859 0.0514983 0.1034 0.00560041 1 0
+0.335886 0.0528022 0.0844396 0.00499071 1 0
+0.35 0.0212422 0.0391845 0.00539966 1 0
+0.381987 0.173518 0.0456676 0.00511331 1 0
+0.271273 0.161918 0.0586698 0.00555117 1 0
+0.0925863 0.183631 0.132173 0.00543901 1 0
+0.258335 0.12838 0.125804 0.00532049 1 0
+0.332545 0.139745 0.1934 0.00566671 1 0
+0.269576 0.0853788 0.0088008 0.00833053 1 0
+0.230941 0.017388 0.16918 0.00554991 1 0
+0.339962 0.0828962 0.156992 0.00606685 1 0
+0.289594 0.099299 0.0979231 0.0057516 1 0
+0.140955 0.193737 0.0954806 0.00640935 1 0
+0.118922 0.195137 0.118187 0.00530406 1 0
+0.0591231 0.0998853 0.0219789 0.00663882 1 0
+0.319005 0.15718 0.158883 0.00699831 1 0
+0.127877 0.155594 0.057736 0.00769139 1 0
+0.318294 0.16287 0.129378 0.0064074 1 0
+0.36565 0.0218976 0.0162911 0.00645217 1 0
+0.00566143 0.076938 0.179819 0.00541591 1 0
+0.293948 0.0438732 0.017724 0.00529041 1 0
+0.0624557 0.0779759 0.0326174 0.00502421 1 0
+0.376266 0.00748401 0.0779648 0.00547678 1 0
+0.0682995 0.172801 0.154954 0.00740985 1 0
+0.0594805 0.127945 0.0586856 0.00525666 1 0
+0.347452 0.0663356 0.119742 0.0069306 1 0
+0.184045 0.0231649 0.0428077 0.00507048 1 0
+0.316409 0.118177 0.0351041 0.0052505 1 0
+0.351999 0.141379 0.092419 0.00731385 1 0
+0.09 0.0212043 0.159808 0.00506732 1 0
+0.0585221 0.017857 0.0399701 0.00578099 1 0
+0.155197 0.00481838 0.142725 0.00492107 1 0
+0.30678 0.0953303 0.0300757 0.00624598 1 0
+0.393444 0.136023 0.0439173 0.00510526 1 0
+0.125353 0.0507762 0.110233 0.00638261 1 0
+0.351042 0.145311 0.0675031 0.00682948 1 0
+0.254195 0.0381235 0.0413503 0.00511698 1 0
+0.01 0.180899 0.0322408 0.00495998 1 0
+0.0483639 0.0473283 0.0625009 0.00500291 1 0
+0.194708 0.0966212 0.170253 0.00499734 1 0
+0.187264 0.183601 0.170186 0.00542055 1 0
+0.222129 0.115037 0.148178 0.00643828 1 0
+0.0430709 0.0295178 0.149118 0.0066055 1 0
+0.128507 0.0100832 0.0801202 0.00561299 1 0
+0.233596 0.122146 0.0371903 0.00519093 1 0
+0.0971237 0.130173 0.0772085 0.00719146 1 0
+0.00891847 0.0214366 0.052843 0.00603167 1 0
+0.333253 0.0299159 0.0869719 0.00556045 1 0
+0.139007 0.146844 0.179856 0.00804221 1 0
+0.0889269 0.120896 0.17275 0.0069551 1 0
+0.076424 0.0383375 0.0433011 0.00610034 1 0
+0.115177 0.0947907 0.177942 0.00848365 1 0
+0.0519639 0.0337147 0.182047 0.00495052 1 0
+0.280811 0.147314 0.124882 0.00644796 1 0
+0.175351 0.0993935 0.0629356 0.00616285 1 0
+0.232532 0.140507 0.00982939 0.00553772 1 0
+0.3443 0.0707592 0.0655399 0.00521791 1 0
+0.148259 0.169095 0.147212 0.005276 1 0
+0.0806145 0.0696028 0.148441 0.00697314 1 0
+0.377057 0.0938253 0.0614691 0.00526754 1 0
+0.176727 0.163044 0.0167244 0.00534095 1 0
+0.3747 0.183974 0.167391 0.00517088 1 0
+0.116467 0.129337 0.00737408 0.00584774 1 0
+0.265312 0.0469076 0.162889 0.00895888 1 0
+0.210312 0.136884 0.0516481 0.0050044 1 0
+0.382313 0.188611 0.0781563 0.00508364 1 0
+0.256426 0.156039 0.0443755 0.00729046 1 0
+0.110251 0.153492 0.110863 0.00841988 1 0
+0.153164 0.18907 0.0510826 0.00505197 1 0
+0.135832 0.105832 0.171815 0.00641906 1 0
+0.215764 0.0305541 0.0723022 0.00525438 1 0
+0.310033 0.142274 0.171375 0.00606043 1 0
+0.15 0.164059 0.0410785 0.00606329 1 0
+0.372926 0.0870483 0.194764 0.00526985 1 0
+0.277151 0.166751 0.184336 0.00497332 1 0
+0.233981 0.116093 0.174304 0.00507903 1 0
+0.170618 0.0208526 0.19461 0.00533624 1 0
+0.31 0.176127 0.0200096 0.00540617 1 0
+0.101048 0.0762601 0.0845436 0.00718604 1 0
+0.0542891 0.0249088 0.109028 0.00805957 1 0
+0.124952 0.117632 0.0917484 0.00791336 1 0
+0.347463 0.0241088 0.106902 0.00563985 1 0
+0.0329361 0.150373 0.120633 0.00579599 1 0
+0.0245338 0.0119199 0.158341 0.00647275 1 0
+0.172233 0.146717 0.0576079 0.00512017 1 0
+0.0883143 0.156751 0.100443 0.00659294 1 0
+0.214205 0.160449 0.179897 0.00492494 1 0
+0.135415 0.0877608 0.169698 0.00815181 1 0
+0.170844 0.0282051 0.128725 0.00611538 1 0
+0.153428 0.110489 0.144807 0.00597814 1 0
+0.193851 0.0220132 0.0994787 0.00552583 1 0
+0.323255 0.167198 0.0474381 0.00795909 1 0
+0.179707 0.164925 0.0747548 0.005482 1 0
+0.0511664 0.13624 0.0541774 0.00719237 1 0
+0.338068 0.176277 0.153188 0.00581013 1 0
+0.364839 0.0856002 0.0571979 0.00492247 1 0
+0.245009 0.190734 0.148366 0.00500709 1 0
+0.208114 0.0832033 0.0596652 0.00637513 1 0
+0.295831 0.116129 0.0184326 0.0056183 1 0
+0.34496 0.165245 0.132476 0.00507771 1 0
+0.0531677 0.18774 0.096376 0.00534642 1 0
+0.382862 0.132041 0.0397941 0.00514877 1 0
+0.322868 0.132797 0.0297669 0.00680391 1 0
+0.345811 0.139817 0.0350729 0.00615701 1 0
+0.0995122 0.174468 0.0147702 0.00587915 1 0
+0.24042 0.0930751 0.0560819 0.0061489 1 0
+0.35639 0.0526969 0.14479 0.00524043 1 0
+0.288497 0.168296 0.150794 0.0110711 1 0
+0.337262 0.163029 0.0517847 0.00558953 1 0
+0.261944 0.0256295 0.116649 0.00566127 1 0
+0.251957 0.095516 0.0101884 0.0049549 1 0
+0.0698836 0.0221234 0.0433974 0.00682977 1 0
+0.0137647 0.149326 0.195047 0.00556836 1 0
+0.250432 0.074121 0.109003 0.00821935 1 0
+0.179564 0.047218 0.171751 0.006094 1 0
+0.0331699 0.0224626 0.0413483 0.00523962 1 0
+0.329789 0.137961 0.0388322 0.00571604 1 0
+0.249914 0.140583 0.151655 0.00499878 1 0
+0.319055 0.0264271 0.106152 0.0062552 1 0
+0.0386856 0.0573807 0.156485 0.00602484 1 0
+0.35 0.177304 0.0190771 0.00651221 1 0
+0.255732 0.0438077 0.179543 0.00496818 1 0
+0.23 0.01902 0.0359562 0.00600114 1 0
+0.29 0.0182661 0.035311 0.00630612 1 0
+0.190535 0.0462154 0.167995 0.00554567 1 0
+0.226768 0.173457 0.0439585 0.00508207 1 0
+0.195773 0.086384 0.0930442 0.00811178 1 0
+0.25161 0.0879304 0.126099 0.0067339 1 0
+0.244441 0.0160123 0.172747 0.00493063 1 0
+0.043296 0.151548 0.0918601 0.00625959 1 0
+0.307593 0.0272495 0.0769788 0.0051061 1 0
+0.00725937 0.181249 0.160883 0.00619715 1 0
+0.175231 0.00533157 0.147991 0.00552298 1 0
+0.0631338 0.0584774 0.0477833 0.00496594 1 0
+0.0472304 0.0284223 0.0444217 0.00620969 1 0
+0.0937202 0.0200306 0.00855072 0.00585216 1 0
+0.00876345 0.191816 0.153383 0.00684825 1 0
+0.317627 0.0683682 0.0252238 0.00535805 1 0
+0.0717525 0.130556 0.107098 0.00817232 1 0
+0.146068 0.0287704 0.0437635 0.00509176 1 0
+0.274603 0.0963645 0.03542 0.00537813 1 0
+0.190315 0.0552909 0.0503652 0.00498143 1 0
+0.34227 0.0424943 0.128558 0.00680922 1 0
+0.224546 0.0717756 0.0894152 0.0052022 1 0
+0.16485 0.144163 0.116683 0.00601526 1 0
+0.31 0.0264071 0.159299 0.00508062 1 0
+0.337475 0.0525507 0.117738 0.00655369 1 0
+0.223739 0.0170824 0.0614024 0.00560669 1 0
+0.299231 0.0440644 0.161454 0.00647538 1 0
+0.0335832 0.0789404 0.0370472 0.00503675 1 0
+0.167133 0.07712 0.119504 0.00701539 1 0
+0.222646 0.152381 0.0815839 0.00666112 1 0
+0.256102 0.122997 0.109313 0.00494815 1 0
+0.217144 0.136513 0.0915481 0.0051836 1 0
+0.248134 0.0112451 0.0967474 0.00654313 1 0
+0.13 0.024322 0.0192746 0.00572495 1 0
+0.269567 0.00820065 0.0760283 0.00789579 1 0
+0.221619 0.0680395 0.0552225 0.00679536 1 0
+0.33895 0.13243 0.132953 0.00507055 1 0
+0.119456 0.0226494 0.183848 0.00514542 1 0
+0.31 0.16474 0.156743 0.00495294 1 0
+0.333612 0.104095 0.0213189 0.0057855 1 0
+0.157879 0.174185 0.130036 0.00890416 1 0
+0.300888 0.122424 0.0414241 0.00732578 1 0
+0.365243 0.103443 0.182958 0.00526612 1 0
+0.052821 0.0599626 0.150999 0.00601089 1 0
+0.389875 0.0408276 0.0233581 0.00608927 1 0
+0.00600313 0.18337 0.178389 0.00501887 1 0
+0.34897 0.111007 0.128003 0.00550693 1 0
+0.294398 0.161156 0.0182559 0.00573325 1 0
+0.181712 0.0226184 0.108846 0.00628206 1 0
+0.232003 0.0810735 0.0908776 0.00680589 1 0
+0.192502 0.0130733 0.0573592 0.00506112 1 0
+0.0286125 0.0500802 0.0806136 0.00523027 1 0
+0.0493994 0.121428 0.149163 0.00518747 1 0
+0.08476 0.158288 0.0380256 0.00497445 1 0
+0.0951523 0.159668 0.111227 0.0065057 1 0
+0.112207 0.191503 0.168551 0.00718012 1 0
+0.114836 0.191245 0.149378 0.00508199 1 0
+0.0904455 0.160321 0.133842 0.00686734 1 0
+0.118465 0.0969585 0.152407 0.00528396 1 0
+0.325616 0.136625 0.131179 0.00570646 1 0
+0.170373 0.171284 0.0552724 0.00506681 1 0
+0.279831 0.0253967 0.0541884 0.00539711 1 0
+0.204186 0.100462 0.0951556 0.00604524 1 0
+0.241027 0.140553 0.188586 0.00632563 1 0
+0.01 0.0305452 0.158786 0.00503532 1 0
+0.154831 0.106833 0.0213084 0.00502078 1 0
+0.356808 0.00512252 0.0769753 0.00500051 1 0
+0.148342 0.0586842 0.18959 0.0057163 1 0
+0.171288 0.0323468 0.182402 0.00533673 1 0
+0.277129 0.149936 0.137827 0.00562111 1 0
+0.172076 0.136966 0.111224 0.00555198 1 0
+0.285579 0.118203 0.066372 0.00625782 1 0
+0.0164121 0.194575 0.0894871 0.00544476 1 0
+0.375279 0.142649 0.0228584 0.00808403 1 0
+0.15 0.0391444 0.176967 0.00523655 1 0
+0.154845 0.0844059 0.0919995 0.00855174 1 0
+0.114847 0.0530955 0.17119 0.00507901 1 0
+0.161215 0.0463565 0.158803 0.00658422 1 0
+0.244294 0.0749789 0.127429 0.00693151 1 0
+0.201621 0.169863 0.056274 0.00539321 1 0
+0.115581 0.0706966 0.056733 0.00508092 1 0
+0.106464 0.112311 0.0671209 0.00524916 1 0
+0.291234 0.0553339 0.0958209 0.00526472 1 0
+0.316176 0.00764799 0.0855426 0.0052024 1 0
+0.275018 0.050031 0.0102281 0.0060469 1 0
+0.150034 0.0206415 0.178561 0.0061308 1 0
+0.263767 0.191992 0.0760477 0.00525599 1 0
+0.130293 0.116906 0.0351914 0.00604257 1 0
+0.186688 0.0872507 0.0579731 0.0061373 1 0
+0.230104 0.106871 0.03155 0.00613509 1 0
+0.173996 0.0709171 0.0506331 0.00512285 1 0
+0.0207845 0.0177262 0.0390978 0.0052981 1 0
+0.0211481 0.0258574 0.0156478 0.00498216 1 0
+0.332627 0.115789 0.15882 0.00579958 1 0
+0.263268 0.157899 0.0664981 0.00551224 1 0
+0.337952 0.0433085 0.15956 0.006886 1 0
+0.34815 0.131308 0.0763117 0.00704923 1 0
+0.115767 0.0923186 0.0853965 0.00514234 1 0
+0.39 0.0189152 0.0358037 0.00601733 1 0
+0.136347 0.131356 0.149812 0.00898847 1 0
+0.34661 0.147226 0.136929 0.00586783 1 0
+0.295703 0.0581534 0.0112684 0.00518624 1 0
+0.0870268 0.00678368 0.0133139 0.00534889 1 0
+0.047278 0.0610762 0.0980137 0.0060369 1 0
+0.178609 0.136398 0.0584243 0.0056634 1 0
+0.202349 0.1576 0.189478 0.00649183 1 0
+0.270943 0.132336 0.191526 0.00832911 1 0
+0.110306 0.122519 0.0741579 0.00656935 1 0
+0.114864 0.0526981 0.143973 0.00623323 1 0
+0.293011 0.0684381 0.183414 0.00565701 1 0
+0.274135 0.0932081 0.160943 0.00563774 1 0
+0.303815 0.140585 0.0694233 0.00626015 1 0
+0.302754 0.191723 0.0147281 0.00550898 1 0
+0.127051 0.00535971 0.111888 0.0055462 1 0
+0.16405 0.0356627 0.0568418 0.00542532 1 0
+0.216114 0.15051 0.19106 0.00731595 1 0
+0.0585163 0.0784101 0.193673 0.00501427 1 0
+0.164093 0.159871 0.117253 0.00903389 1 0
+0.171427 0.150318 0.145285 0.00498805 1 0
+0.01 0.178751 0.0212145 0.00593001 1 0
+0.126596 0.135693 0.0659915 0.00700331 1 0
+0.142394 0.0700104 0.010219 0.00549211 1 0
+0.28283 0.0597229 0.012684 0.00496416 1 0
+0.346125 0.065843 0.0811333 0.00549911 1 0
+0.0192994 0.155884 0.0432481 0.00504566 1 0
+0.0620351 0.177468 0.141743 0.00507261 1 0
+0.395852 0.0603702 0.179532 0.00498008 1 0
+0.196962 0.184654 0.0324529 0.0051657 1 0
+0.279714 0.0566011 0.19426 0.005438 1 0
+0.33 0.0204775 0.0218146 0.00605239 1 0
+0.166458 0.103195 0.147391 0.00591854 1 0
+0.0617074 0.043718 0.0241343 0.00501687 1 0
+0.193501 0.0107412 0.111082 0.00846357 1 0
+0.196351 0.0464952 0.106671 0.00548262 1 0
+0.075906 0.0671244 0.160934 0.00537679 1 0
+0.309361 0.00933187 0.0990245 0.0052889 1 0
+0.0627181 0.0634413 0.168156 0.00501112 1 0
+0.046994 0.112873 0.0364355 0.00532616 1 0
+0.183407 0.0707565 0.00836969 0.00530652 1 0
+0.232014 0.188669 0.181532 0.00507663 1 0
+0.0555723 0.144624 0.121058 0.00569052 1 0
+0.0343206 0.0954366 0.0503161 0.0050001 1 0
+0.0290338 0.173999 0.187396 0.00492787 1 0
+0.309574 0.0839854 0.160007 0.00514783 1 0
+0.0969705 0.169712 0.184873 0.00518084 1 0
+0.0658485 0.150003 0.179707 0.0062944 1 0
+0.108433 0.119435 0.163223 0.00507743 1 0
+0.206247 0.0766513 0.105902 0.0066949 1 0
+0.0864436 0.0643843 0.103629 0.00657068 1 0
+0.182244 0.133136 0.104595 0.00617659 1 0
+0.0471952 0.00624242 0.0945309 0.00649479 1 0
+0.0527607 0.0109981 0.11591 0.00611499 1 0
+0.10993 0.119343 0.0931493 0.0072709 1 0
+0.103207 0.0969803 0.129359 0.00654085 1 0
+0.170271 0.0187429 0.167282 0.00512471 1 0
+0.164726 0.0409384 0.179983 0.00554499 1 0
+0.326465 0.0283705 0.135593 0.00524226 1 0
+0.140623 0.0711734 0.0772951 0.00581126 1 0
+0.0850976 0.191205 0.0768463 0.00685597 1 0
+0.09 0.183533 0.0269557 0.00709967 1 0
+0.375296 0.139669 0.0715155 0.00536797 1 0
+0.156343 0.119418 0.0174718 0.00496351 1 0
+0.201745 0.155548 0.03555 0.00549744 1 0
+0.283227 0.187762 0.109832 0.00782879 1 0
+0.0651253 0.0846026 0.00611225 0.00671016 1 0
+0.165103 0.164994 0.0433823 0.00517184 1 0
+0.230469 0.142552 0.0262646 0.00565048 1 0
+0.0644654 0.0126289 0.0524089 0.00567865 1 0
+0.193453 0.160545 0.0700145 0.00542249 1 0
+0.169417 0.181557 0.0684874 0.00516442 1 0
+0.334088 0.127733 0.102483 0.00550088 1 0
+0.0956108 0.121131 0.123297 0.00975789 1 0
+0.123709 0.127416 0.188492 0.00539229 1 0
+0.0979571 0.108096 0.156332 0.00547353 1 0
+0.251707 0.016391 0.19019 0.00624543 1 0
+0.0661633 0.179022 0.041344 0.00492435 1 0
+0.355416 0.193746 0.0841065 0.00589224 1 0
+0.347893 0.18288 0.0297822 0.00510758 1 0
+0.136844 0.0199226 0.083017 0.00534729 1 0
+0.39235 0.147579 0.183273 0.00580378 1 0
+0.01 0.0411491 0.0267012 0.00533574 1 0
+0.0588663 0.13177 0.102265 0.00539944 1 0
+0.0978903 0.11469 0.0541935 0.00643746 1 0
+0.308283 0.122379 0.18741 0.00743573 1 0
+0.381485 0.00477065 0.0532761 0.0053672 1 0
+0.274681 0.123917 0.0450574 0.00494249 1 0
+0.274508 0.141622 0.0266256 0.00580575 1 0
+0.170151 0.0674314 0.143951 0.00518518 1 0
+0.158682 0.0638484 0.15911 0.0051452 1 0
+0.378616 0.181401 0.180389 0.00548654 1 0
+0.0459767 0.150753 0.0466611 0.00506987 1 0
+0.0454381 0.151814 0.0341858 0.00532984 1 0
+0.188361 0.0534292 0.0140177 0.00568027 1 0
+0.217714 0.125165 0.0343887 0.00503698 1 0
+0.110836 0.126499 0.0383373 0.00694862 1 0
+0.096231 0.130024 0.0342919 0.0058512 1 0
+0.201951 0.139456 0.0361176 0.00511319 1 0
+0.191894 0.0976474 0.14744 0.00647568 1 0
+0.35 0.171579 0.181703 0.00547433 1 0
+0.30885 0.0795745 0.0344666 0.00514951 1 0
+0.296265 0.116872 0.0586386 0.00494227 1 0
+0.314284 0.103333 0.0673027 0.00555231 1 0
+0.092611 0.0159843 0.19321 0.0053434 1 0
+0.13 0.0210197 0.163043 0.00513412 1 0
+0.027443 0.148809 0.189908 0.00511117 1 0
+0.121856 0.159182 0.118894 0.00508099 1 0
+0.156883 0.181267 0.0743892 0.0062106 1 0
+0.363206 0.0564425 0.0982633 0.00501058 1 0
+0.00889184 0.161165 0.0418842 0.00670472 1 0
+0.39 0.156352 0.032948 0.00717421 1 0
+0.196193 0.191986 0.0554252 0.00542604 1 0
+0.212932 0.0369344 0.0594619 0.00530686 1 0
+0.246057 0.0820164 0.0902824 0.00684233 1 0
+0.262212 0.194978 0.0528194 0.005386 1 0
+0.349212 0.161169 0.102484 0.00696689 1 0
+0.0212278 0.053785 0.165676 0.00526682 1 0
+0.25 0.0222123 0.160308 0.00595556 1 0
+0.13 0.0338003 0.0415081 0.00571234 1 0
+0.251398 0.0134418 0.052878 0.00555353 1 0
+0.283035 0.0380155 0.017362 0.00527007 1 0
+0.256399 0.00663239 0.0405731 0.00536133 1 0
+0.277872 0.0151422 0.0301644 0.00501034 1 0
+0.29 0.0331873 0.156387 0.00535195 1 0
+0.310051 0.159968 0.0644506 0.00626058 1 0
+0.23 0.0400195 0.0252136 0.00494321 1 0
+0.00597915 0.192857 0.113782 0.00614966 1 0
+0.26478 0.0856209 0.0621084 0.0058759 1 0
+0.170888 0.0249568 0.149919 0.00528423 1 0
+0.0862489 0.178614 0.156334 0.00675943 1 0
+0.0765856 0.148868 0.166939 0.00690831 1 0
+0.0769549 0.152726 0.14279 0.00842565 1 0
+0.374428 0.101105 0.0515387 0.00506034 1 0
+0.208821 0.0315649 0.0177298 0.00519243 1 0
+0.213451 0.0158765 0.0324657 0.00576198 1 0
+0.2004 0.0441061 0.0243762 0.00519107 1 0
+0.21 0.0282458 0.0431743 0.00602494 1 0
+0.258037 0.0375442 0.0171449 0.00503405 1 0
+0.13 0.0397069 0.163478 0.00538679 1 0
+0.341736 0.0212705 0.157989 0.00494933 1 0
+0.33 0.0107095 0.169753 0.00926678 1 0
+0.39 0.0244424 0.159316 0.00565326 1 0
+0.123273 0.184883 0.0328546 0.00550323 1 0
+0.0582003 0.154851 0.0294708 0.00526422 1 0
+0.0687158 0.163556 0.0197289 0.0049326 1 0
+0.343047 0.152234 0.0418529 0.00666205 1 0
+0.260138 0.181753 0.0392608 0.00496383 1 0
+0.323838 0.181046 0.0401489 0.00548408 1 0
+0.39 0.17758 0.03934 0.00564262 1 0
+0.0114031 0.169948 0.157271 0.00536005 1 0
+0.105449 0.182977 0.175277 0.00503166 1 0
+0.181274 0.184416 0.182946 0.0067919 1 0
+0.17 0.174714 0.158959 0.00562471 1 0
+0.243437 0.155565 0.17436 0.0054662 1 0
+0.198594 0.177974 0.183018 0.00533083 1 0
+0.357939 0.155902 0.154586 0.00588195 1 0
+0.0678736 0.0194877 0.193962 0.00587428 1 0
+0.261094 0.031613 0.143196 0.00641111 1 0
+0.0544616 0.0115973 0.103615 0.00631154 1 0
+0.300243 0.18462 0.180876 0.00679718 1 0
+0.381482 0.00919082 0.15216 0.00582408 1 0
+0.3597 0.172902 0.127903 0.00513018 1 0
+0.27607 0.152288 0.115059 0.00497727 1 0
+0.33 0.165643 0.156947 0.00701088 1 0
+0.168644 0.0373118 0.1599 0.00517157 1 0
+0.110805 0.0247741 0.0426208 0.00646617 1 0
+0.277394 0.0310717 0.04549 0.00527087 1 0
+0.370097 0.00686026 0.142097 0.00622595 1 0
+0.10914 0.070801 0.0234014 0.00536059 1 0
+0.062817 0.0164829 0.177108 0.00493717 1 0
+0.340361 0.121672 0.136124 0.00623336 1 0
+0.177069 0.166193 0.116547 0.00541707 1 0
+0.0717111 0.0222557 0.159741 0.00529445 1 0
+0.173048 0.126401 0.105637 0.00526965 1 0
+0.370588 0.141092 0.00823424 0.00735295 1 0
+0.311732 0.112762 0.10386 0.00566651 1 0
+0.224861 0.0108757 0.0111513 0.00580825 1 0
+0.282403 0.0378644 0.150256 0.00501103 1 0
+0.183624 0.0128695 0.0433923 0.00525007 1 0
+0.342352 0.149326 0.0994858 0.00704412 1 0
+0.23 0.164717 0.0399481 0.00506231 1 0
+0.342001 0.179746 0.00588706 0.0062753 1 0
+0.198251 0.0879786 0.0521409 0.00683441 1 0
+0.0955366 0.15961 0.122925 0.00519878 1 0
+0.00593014 0.161319 0.084341 0.00603019 1 0
+0.18029 0.154792 0.145996 0.00496599 1 0
+0.0281417 0.143236 0.173569 0.0049881 1 0
+0.352748 0.152499 0.0343066 0.00563147 1 0
+0.260024 0.10054 0.0972566 0.00498755 1 0
+0.159265 0.0614676 0.177132 0.00496797 1 0
+0.273013 0.066809 0.168266 0.00526 1 0
+0.0961053 0.158912 0.0425576 0.00541757 1 0
+0.38805 0.112274 0.0864649 0.00526447 1 0
+0.264119 0.0605599 0.0966643 0.00523095 1 0
+0.329591 0.159137 0.176464 0.00586786 1 0
+0.0730028 0.0412287 0.106009 0.00531919 1 0
+0.264012 0.178833 0.14807 0.00573042 1 0
+0.263282 0.135521 0.013621 0.00547357 1 0
+0.0967876 0.145384 0.10407 0.00751144 1 0
+0.230225 0.160641 0.0228926 0.00528607 1 0
+0.325794 0.0266551 0.0951936 0.00597996 1 0
+0.149199 0.0800426 0.0786346 0.00659869 1 0
+0.238664 0.165512 0.184353 0.00509723 1 0
+0.21 0.0406293 0.1602 0.00757887 1 0
+0.187799 0.0417546 0.177593 0.00538602 1 0
+0.0331917 0.0228511 0.156774 0.0065044 1 0
+0.216288 0.0735893 0.0648644 0.00554062 1 0
+0.19795 0.00662434 0.163804 0.00522254 1 0
+0.332126 0.00415627 0.0198734 0.0051572 1 0
+0.205507 0.0201568 0.158537 0.00588187 1 0
+0.170897 0.173902 0.120927 0.00523435 1 0
+0.248516 0.014429 0.120122 0.005256 1 0
+0.0361242 0.15799 0.157262 0.00581867 1 0
+0.138548 0.147702 0.123506 0.00907352 1 0
+0.149799 0.0372451 0.151687 0.00499184 1 0
+0.177965 0.159118 0.180328 0.00514079 1 0
+0.392538 0.0189895 0.180817 0.00561277 1 0
+0.382243 0.101195 0.0750976 0.00609491 1 0
+0.0836357 0.0219441 0.00512935 0.00496743 1 0
+0.33 0.161926 0.0377196 0.00499244 1 0
+0.336211 0.177032 0.132754 0.00506622 1 0
+0.0532224 0.134385 0.114407 0.0055477 1 0
+0.276116 0.156167 0.163396 0.0058125 1 0
+0.0348003 0.115308 0.0677341 0.00607577 1 0
+0.0440233 0.146143 0.166868 0.00519442 1 0
+0.120917 0.0561351 0.0994865 0.00526409 1 0
+0.256449 0.107859 0.061902 0.00687425 1 0
+0.171845 0.0215487 0.117558 0.00692348 1 0
+0.255654 0.161876 0.0169731 0.00532026 1 0
+0.144031 0.154944 0.170114 0.00558662 1 0
+0.145005 0.0179794 0.0223569 0.00509841 1 0
+0.128038 0.0977233 0.174511 0.00514635 1 0
+0.201338 0.0257893 0.133051 0.00532102 1 0
+0.166681 0.100641 0.0706421 0.00550443 1 0
+0.12131 0.166423 0.0453309 0.00579703 1 0
+0.0658001 0.154509 0.11645 0.00642682 1 0
+0.0572581 0.165887 0.155183 0.0056194 1 0
+0.187662 0.191443 0.00509992 0.00542144 1 0
+0.0944134 0.0383697 0.0973631 0.0068424 1 0
+0.318418 0.111156 0.144915 0.00537137 1 0
+0.286851 0.123289 0.175289 0.00521646 1 0
+0.161594 0.113297 0.134391 0.00755107 1 0
+0.18948 0.156254 0.0181854 0.00526632 1 0
+0.177931 0.155843 0.0650242 0.00562178 1 0
+0.100584 0.0462843 0.173604 0.00525411 1 0
+0.169914 0.139955 0.1501 0.00653871 1 0
+0.263616 0.116388 0.0769037 0.00648812 1 0
+0.31668 0.128179 0.105431 0.00518582 1 0
+0.100492 0.0735251 0.0144766 0.00492659 1 0
+0.132923 0.17577 0.18249 0.00547233 1 0
+0.34078 0.0083426 0.186336 0.00818907 1 0
+0.29936 0.142034 0.0951274 0.00620868 1 0
+0.269367 0.0277092 0.18182 0.00525473 1 0
+0.325954 0.0773823 0.00821037 0.00871461 1 0
+0.385832 0.013629 0.080827 0.0053703 1 0
+0.271175 0.194405 0.138624 0.00629957 1 0
+0.176297 0.1553 0.0249634 0.00597416 1 0
+0.367395 0.155817 0.0259312 0.00650447 1 0
+0.242305 0.045509 0.129572 0.00581364 1 0
+0.170596 0.167333 0.189563 0.00681678 1 0
+0.143312 0.0364464 0.184318 0.0050612 1 0
+0.0838401 0.0723796 0.0732097 0.00542222 1 0
+0.164174 0.164756 0.146673 0.00878473 1 0
+0.343979 0.0134402 0.16495 0.00576487 1 0
+0.296169 0.0723779 0.0760541 0.00519839 1 0
+0.343016 0.131144 0.0620836 0.00527033 1 0
+0.176588 0.144532 0.0358948 0.0059744 1 0
+0.257508 0.0394345 0.133334 0.00567279 1 0
+0.0289996 0.142579 0.113386 0.00555155 1 0
+0.11092 0.182559 0.0602423 0.00608611 1 0
+0.0607705 0.0760141 0.076644 0.00607164 1 0
+0.16066 0.0425497 0.147777 0.00509363 1 0
+0.0715801 0.0833763 0.104049 0.00535127 1 0
+0.15 0.170787 0.157919 0.00570278 1 0
+0.327064 0.164185 0.0820805 0.00526258 1 0
+0.317055 0.15458 0.171205 0.00574498 1 0
+0.347806 0.153938 0.0778674 0.00703853 1 0
+0.293947 0.171232 0.133718 0.00556929 1 0
+0.156684 0.149419 0.111223 0.00512589 1 0
+0.252732 0.131396 0.0968162 0.00549874 1 0
+0.01425 0.0215658 0.0708055 0.00532287 1 0
+0.0763223 0.156665 0.176082 0.00511058 1 0
+0.124446 0.127437 0.039473 0.00674084 1 0
+0.359546 0.118236 0.0804413 0.00511047 1 0
+0.0887918 0.0346958 0.0417275 0.00539093 1 0
+0.177854 0.108789 0.142292 0.00537027 1 0
+0.0968535 0.0707884 0.111793 0.00515489 1 0
+0.302334 0.145584 0.0277289 0.00572278 1 0
+0.3148 0.0091965 0.159974 0.00610153 1 0
+0.0650404 0.077735 0.111273 0.00583579 1 0
+0.35 0.157852 0.167876 0.00587751 1 0
+0.0687925 0.0473 0.0986019 0.00505409 1 0
+0.351393 0.00584318 0.10956 0.00633544 1 0
+0.250902 0.0661362 0.0970678 0.00614813 1 0
+0.199256 0.151144 0.160893 0.00572317 1 0
+0.081642 0.174244 0.0457985 0.00526858 1 0
+0.21976 0.170596 0.149192 0.00673337 1 0
+0.310973 0.131476 0.0090823 0.00770685 1 0
+0.171225 0.0350769 0.148616 0.00492495 1 0
+0.0422254 0.0146582 0.108313 0.00714824 1 0
+0.25391 0.150461 0.103458 0.00533219 1 0
+0.328306 0.142198 0.15002 0.00511059 1 0
+0.382755 0.00781137 0.0192031 0.00505643 1 0
+0.127577 0.145161 0.167248 0.0062849 1 0
+0.0600214 0.130019 0.0487371 0.0049201 1 0
+0.110918 0.0619143 0.156475 0.00676531 1 0
+0.293273 0.158535 0.00771861 0.00518306 1 0
+0.1195 0.145898 0.0623842 0.0059389 1 0
+0.109317 0.0465481 0.165315 0.00531158 1 0
+0.315361 0.10605 0.0312039 0.007184 1 0
+0.0817801 0.153306 0.155881 0.00553843 1 0
+0.0487354 0.0470424 0.0517937 0.005316 1 0
+0.37 0.0372783 0.160129 0.0058242 1 0
+0.0778138 0.0743938 0.0561003 0.00531565 1 0
+0.346521 0.143338 0.049699 0.00569743 1 0
+0.307383 0.11418 0.156362 0.00575875 1 0
+0.277046 0.158534 0.144477 0.00524865 1 0
+0.13 0.0361391 0.180559 0.00578534 1 0
+0.206529 0.0269038 0.0694898 0.00506644 1 0
+0.358316 0.0430172 0.177113 0.00492916 1 0
+0.00654987 0.0696918 0.0295163 0.00614741 1 0
+0.0899527 0.0570072 0.172679 0.00604206 1 0
+0.202863 0.180004 0.154309 0.00552596 1 0
+0.148523 0.177151 0.140333 0.00532119 1 0
+0.13307 0.0630071 0.121302 0.00599325 1 0
+0.0780002 0.0448977 0.160222 0.00513026 1 0
+0.238688 0.0248954 0.150031 0.0050339 1 0
+0.33353 0.0754906 0.0249002 0.00582627 1 0
+0.256402 0.0357335 0.152655 0.00492271 1 0
+0.234174 0.0957673 0.0900119 0.00807268 1 0
+0.192198 0.127593 0.100147 0.00505887 1 0
+0.00825974 0.126987 0.0225671 0.00501073 1 0
+0.13 0.174395 0.159837 0.00492019 1 0
+0.367878 0.149816 0.162361 0.00544743 1 0
+0.274419 0.0773807 0.019342 0.00563982 1 0
+0.262616 0.0135154 0.193305 0.00545901 1 0
+0.306531 0.148053 0.0546813 0.00499252 1 0
+0.0517323 0.176959 0.0189973 0.00510163 1 0
+0.237788 0.0894483 0.0749374 0.00714378 1 0
+0.0893069 0.189382 0.152218 0.00516745 1 0
+0.0323866 0.126165 0.0357112 0.00522841 1 0
+0.314882 0.0714174 0.0349756 0.00500877 1 0
+0.33603 0.1587 0.0660504 0.00571842 1 0
+0.108816 0.151105 0.169317 0.00516 1 0
+0.364708 0.051628 0.167371 0.00626463 1 0
+0.100349 0.108523 0.130208 0.0053807 1 0
+0.170666 0.0892365 0.068069 0.0057705 1 0
+0.0999165 0.142379 0.0745268 0.00561466 1 0
+0.0597816 0.185221 0.027062 0.0055033 1 0
+0.238633 0.179517 0.0175771 0.005709 1 0
+0.107246 0.085266 0.131911 0.00559302 1 0
+0.0861326 0.0451846 0.187098 0.00520339 1 0
+0.0637139 0.192531 0.157391 0.00495527 1 0
+0.267139 0.069563 0.0327794 0.00499077 1 0
+0.0864614 0.191535 0.0401115 0.0049512 1 0
+0.0237336 0.120119 0.0736767 0.00535296 1 0
+0.211425 0.00508826 0.0340575 0.00523903 1 0
+0.0575627 0.0483748 0.151254 0.00577812 1 0
+0.243244 0.0831797 0.102024 0.00528776 1 0
+0.261577 0.0796649 0.114792 0.00550874 1 0
+0.103909 0.0607845 0.0205837 0.00494194 1 0
+0.227431 0.195448 0.0180965 0.00494513 1 0
+0.29699 0.120724 0.180025 0.00600489 1 0
+0.122431 0.0146929 0.166487 0.00531487 1 0
+0.356335 0.0460945 0.0299408 0.00548702 1 0
+0.25 0.165995 0.040633 0.0051361 1 0
+0.245868 0.116582 0.0693421 0.00872676 1 0
+0.215962 0.117685 0.0750916 0.0073751 1 0
+0.0934349 0.0583919 0.0966913 0.00495829 1 0
+0.359399 0.151389 0.059909 0.00510121 1 0
+0.259602 0.143109 0.0989046 0.00502089 1 0
+0.0356892 0.0457494 0.032632 0.00527195 1 0
+0.180834 0.0330256 0.1308 0.0051692 1 0
+0.0631825 0.193286 0.183238 0.00541475 1 0
+0.343546 0.167816 0.0445428 0.00512738 1 0
+0.239506 0.0748118 0.116467 0.00503154 1 0
+0.365153 0.133028 0.0180349 0.0054654 1 0
+0.214868 0.00513958 0.006055 0.00538041 1 0
+0.0779447 0.00933514 0.133271 0.00725011 1 0
+0.37 0.171148 0.0439746 0.00681272 1 0
+0.106816 0.139283 0.119261 0.00843925 1 0
+0.394734 0.0786798 0.128928 0.00549414 1 0
+0.096486 0.153221 0.187963 0.00829006 1 0
+0.17 0.156997 0.0352682 0.00551604 1 0
+0.0556346 0.033688 0.15095 0.0053515 1 0
+0.226596 0.0350846 0.043546 0.00590146 1 0
+0.0777909 0.165915 0.148506 0.00597243 1 0
+0.340627 0.165863 0.150643 0.00521091 1 0
+0.393511 0.111386 0.0591638 0.00504775 1 0
+0.324017 0.170214 0.108676 0.00527019 1 0
+0.278548 0.116772 0.191291 0.00493263 1 0
+0.208638 0.131575 0.0885691 0.00509302 1 0
+0.24394 0.127435 0.0543049 0.00545812 1 0
+0.233082 0.0215367 0.159692 0.00502445 1 0
+0.0802463 0.0952664 0.128303 0.00587113 1 0
+0.35373 0.142419 0.0794802 0.00578166 1 0
+0.332804 0.119654 0.0538804 0.00495888 1 0
+0.14254 0.0523675 0.0987686 0.00593462 1 0
+0.238221 0.0238557 0.0159596 0.005277 1 0
+0.276343 0.155965 0.0355368 0.00552434 1 0
+0.389898 0.166025 0.0423102 0.00628806 1 0
+0.20734 0.0934415 0.107873 0.00881958 1 0
+0.113326 0.0465527 0.155473 0.00531565 1 0
+0.287784 0.152427 0.0201663 0.0053834 1 0
+0.19 0.174441 0.0195105 0.00515748 1 0
+0.0933412 0.0662663 0.0868433 0.0056423 1 0
+0.0535527 0.170707 0.140558 0.00502638 1 0
+0.056345 0.0447936 0.167543 0.00543527 1 0
+0.319714 0.173203 0.0138602 0.00532904 1 0
+0.318993 0.159075 0.14688 0.00515332 1 0
+0.132172 0.073621 0.0140572 0.00541312 1 0
+0.186738 0.0355362 0.152613 0.00527402 1 0
+0.354687 0.148664 0.144741 0.00546032 1 0
+0.143956 0.0873215 0.111676 0.00507434 1 0
+0.33 0.0263341 0.0406133 0.00503598 1 0
+0.239281 0.184703 0.0268573 0.00494154 1 0
+0.317241 0.121443 0.147915 0.0054086 1 0
+0.0155774 0.155562 0.0334974 0.00539621 1 0
+0.0467048 0.164738 0.157204 0.0051868 1 0
+0.0907433 0.128642 0.136023 0.00580039 1 0
+0.226558 0.0050429 0.0680593 0.00546214 1 0
+0.160818 0.101567 0.0900302 0.00542622 1 0
+0.0578329 0.0527018 0.0826996 0.00535188 1 0
+0.190631 0.0849595 0.120363 0.00498892 1 0
+0.0855674 0.0739422 0.0906115 0.00557382 1 0
+0.079236 0.0838242 0.173243 0.00524543 1 0
+0.317096 0.134697 0.0196558 0.00492943 1 0
+0.22179 0.164076 0.0472665 0.005254 1 0
+0.035521 0.024448 0.141908 0.00500036 1 0
+0.121423 0.153796 0.0454467 0.00630561 1 0
+0.243375 0.157456 0.0401662 0.0056814 1 0
+0.216065 0.156221 0.0151389 0.00496757 1 0
+0.288644 0.161478 0.0391054 0.00517417 1 0
+0.305165 0.129215 0.093237 0.00602047 1 0
+0.326572 0.0931579 0.0556699 0.0057005 1 0
+0.142905 0.188128 0.00832213 0.00500349 1 0
+0.303122 0.183253 0.0234914 0.0050918 1 0
+0.0513195 0.131298 0.0421085 0.00585023 1 0
+0.137058 0.141451 0.159999 0.00536984 1 0
+0.257599 0.0941042 0.134262 0.00512517 1 0
+0.19656 0.0472216 0.181399 0.0050835 1 0
+0.133371 0.0855867 0.135726 0.00558747 1 0
+0.297211 0.148201 0.0460843 0.00513294 1 0
+0.27 0.18092 0.166627 0.00518641 1 0
+0.117472 0.0642168 0.142115 0.00572231 1 0
+0.37979 0.152412 0.0390155 0.0053394 1 0
+0.21 0.0393582 0.0384033 0.00606831 1 0
+0.227068 0.0301736 0.0720983 0.00605722 1 0
+0.341191 0.0251477 0.0454776 0.00610949 1 0
+0.364764 0.147722 0.152537 0.00496601 1 0
+0.331248 0.0630576 0.114729 0.00602514 1 0
+0.187503 0.160421 0.160779 0.00526709 1 0
+0.0607547 0.036431 0.111339 0.00504444 1 0
+0.0249341 0.140233 0.059008 0.00500066 1 0
+0.277753 0.0891442 0.0799665 0.00500209 1 0
+0.241637 0.138237 0.158558 0.00502118 1 0
+0.107164 0.192643 0.156784 0.00567281 1 0
+0.121535 0.112179 0.124726 0.00558203 1 0
+0.12679 0.109329 0.188589 0.00564646 1 0
+0.192212 0.116073 0.195068 0.00500692 1 0
+0.176887 0.14295 0.103954 0.00502218 1 0
+0.200576 0.118743 0.0119407 0.00519626 1 0
+0.179161 0.124561 0.0950849 0.00562769 1 0
+0.101414 0.125129 0.0662452 0.00561635 1 0
+0.252938 0.0644826 0.194418 0.00534798 1 0
+0.241464 0.0230279 0.194617 0.00567851 1 0
+0.14585 0.154364 0.0333299 0.0049201 1 0
+0.13 0.162097 0.15985 0.00629393 1 0
+0.374508 0.0444107 0.028399 0.00521957 1 0
+0.163322 0.111215 0.109167 0.00495191 1 0
+0.325752 0.186974 0.117146 0.00507565 1 0
+0.235053 0.112389 0.0399197 0.0050449 1 0
+0.310614 0.134246 0.0798435 0.00715402 1 0
+0.337052 0.175091 0.108946 0.00633609 1 0
+0.258904 0.122522 0.0117143 0.00533354 1 0
+0.119023 0.128715 0.105223 0.0094116 1 0
+0.0621116 0.0146283 0.00623177 0.00653622 1 0
+0.0110308 0.159897 0.123493 0.00517159 1 0
+0.106056 0.161993 0.0567978 0.00669773 1 0
+0.319037 0.128427 0.186393 0.00494375 1 0
+0.0707372 0.138259 0.1358 0.00492486 1 0
+0.0951466 0.0410084 0.194366 0.00577235 1 0
+0.215184 0.0511051 0.0949013 0.00567067 1 0
+0.152345 0.15892 0.128689 0.00738893 1 0
+0.116686 0.0767524 0.0309955 0.00507058 1 0
+0.208835 0.142381 0.170932 0.00500633 1 0
+0.0834147 0.087441 0.0911852 0.00614729 1 0
+0.113349 0.0109536 0.0221073 0.00516509 1 0
+0.00816041 0.155564 0.108356 0.00548171 1 0
+0.0962057 0.0661762 0.15883 0.0061964 1 0
+0.327568 0.116904 0.148792 0.00548791 1 0
+0.164068 0.082941 0.0800338 0.00662652 1 0
+0.244047 0.0375086 0.0431852 0.00521327 1 0
+0.141397 0.176393 0.154309 0.00518206 1 0
+0.178245 0.168578 0.0633801 0.00529997 1 0
+0.160227 0.051309 0.0342094 0.00494937 1 0
+0.170286 0.124796 0.116129 0.00569779 1 0
+0.203984 0.106266 0.184599 0.0049814 1 0
+0.325401 0.161488 0.0918087 0.00496851 1 0
+0.306247 0.00665273 0.089148 0.00540779 1 0
+0.316238 0.015265 0.0931219 0.0055432 1 0
+0.240079 0.145881 0.0296839 0.00507972 1 0
+0.32467 0.132036 0.0980336 0.00576958 1 0
+0.157623 0.132844 0.122606 0.00866231 1 0
+0.169955 0.15008 0.108074 0.00561139 1 0
+0.194824 0.187497 0.0649106 0.00515682 1 0
+0.239326 0.0150519 0.181313 0.00509233 1 0
+0.318191 0.159187 0.0564939 0.00514918 1 0
+0.0792881 0.016866 0.180201 0.00517011 1 0
+0.260323 0.0685592 0.11658 0.00542457 1 0
+0.239286 0.106852 0.0810619 0.00706377 1 0
+0.334289 0.0982624 0.0122789 0.00499393 1 0
+0.226025 0.118987 0.0279885 0.00713664 1 0
+0.344845 0.189664 0.0855549 0.00553181 1 0
+0.253551 0.0766101 0.0827654 0.00506928 1 0
+0.345822 0.188583 0.154599 0.00880407 1 0
+0.0827703 0.0235384 0.0445821 0.00618839 1 0
+0.333985 0.040954 0.0412785 0.00507434 1 0
+0.278721 0.0594964 0.0952742 0.00546562 1 0
+0.019205 0.0449667 0.0239296 0.00500779 1 0
+0.149741 0.117969 0.0247541 0.00497227 1 0
+0.148458 0.0655767 0.112763 0.00500424 1 0
+0.185581 0.113329 0.0951075 0.00636539 1 0
+0.314931 0.172481 0.184316 0.00538804 1 0
+0.151307 0.191604 0.0841679 0.00742714 1 0
+0.215391 0.0778268 0.0526149 0.00509487 1 0
+0.116938 0.0537562 0.0111887 0.00632439 1 0
+0.123704 0.145119 0.105583 0.0063281 1 0
+0.349979 0.189299 0.0221952 0.00504719 1 0
+0.373207 0.0786809 0.0262685 0.00511944 1 0
+0.119987 0.0826799 0.127211 0.00497848 1 0
+0.119432 0.0344412 0.044668 0.00533614 1 0
+0.125114 0.0259125 0.148706 0.00512049 1 0
+0.0491786 0.102561 0.165362 0.00540046 1 0
+0.187451 0.00754914 0.195216 0.00498253 1 0
+0.0993061 0.0379254 0.016514 0.00499695 1 0
+0.134012 0.118456 0.140878 0.00687643 1 0
+0.274864 0.191863 0.165327 0.00519948 1 0
+0.338764 0.184065 0.0196136 0.00661261 1 0
+0.30909 0.155887 0.1521 0.00508481 1 0
+0.281038 0.179616 0.0434301 0.00495262 1 0
+0.284824 0.0573723 0.0853284 0.00514923 1 0
+0.152 0.0776878 0.110776 0.0062575 1 0
+0.352751 0.0402944 0.0504634 0.00495409 1 0
+0.06202 0.039623 0.0415275 0.00515143 1 0
+0.253638 0.0493509 0.152362 0.00593247 1 0
+0.17658 0.177998 0.016944 0.00513947 1 0
+0.315916 0.152921 0.0712626 0.00516184 1 0
+0.222567 0.157874 0.0384202 0.00498412 1 0
+0.178055 0.0404681 0.180863 0.00497207 1 0
+0.0640356 0.136959 0.117493 0.00598804 1 0
+0.269722 0.170038 0.152649 0.00571176 1 0
+0.252802 0.16212 0.0986709 0.00499185 1 0
+0.209844 0.0545797 0.177965 0.00554082 1 0
+0.13029 0.0507768 0.0401549 0.00497506 1 0
+0.366953 0.146216 0.0774128 0.00517086 1 0
+0.371563 0.0342949 0.0441009 0.00496373 1 0
+0.27 0.178611 0.0224494 0.00494871 1 0
+0.26675 0.138843 0.061017 0.00518781 1 0
+0.114366 0.178677 0.155083 0.0057361 1 0
+0.221864 0.0366978 0.0793678 0.00501016 1 0
+0.207612 0.0444648 0.193214 0.00627639 1 0
+0.271776 0.149236 0.0896579 0.00512745 1 0
+0.121741 0.14519 0.0354793 0.00576319 1 0
+0.262546 0.0115259 0.0141798 0.00560513 1 0
+0.300685 0.155898 0.0352115 0.00504962 1 0
+0.174803 0.111176 0.0338426 0.00552079 1 0
+0.104673 0.128424 0.132813 0.00527037 1 0
+0.315444 0.160233 0.189164 0.00572812 1 0
+0.251209 0.129378 0.074338 0.00601193 1 0
+0.190451 0.192302 0.115137 0.00546215 1 0
+0.249307 0.185526 0.00612246 0.00502701 1 0
+0.203934 0.0225659 0.18315 0.0051549 1 0
+0.302241 0.100337 0.134276 0.00542858 1 0
+0.347415 0.0902788 0.136673 0.00554412 1 0
+0.0795558 0.105547 0.122701 0.00494732 1 0
+0.301311 0.0235448 0.154751 0.00513585 1 0
+0.114762 0.0984224 0.124566 0.00605229 1 0
+0.0258172 0.13008 0.0854701 0.00587416 1 0
+0.192188 0.0787302 0.129962 0.00526632 1 0
+0.24031 0.16392 0.0162384 0.00504816 1 0
+0.173767 0.182968 0.0343716 0.00503739 1 0
+0.187492 0.121202 0.145904 0.00543631 1 0
+0.121307 0.0911066 0.163532 0.00760362 1 0
+0.306121 0.039887 0.0508405 0.00586732 1 0
+0.0313969 0.187535 0.116287 0.00526618 1 0
+0.205244 0.0530181 0.00474848 0.00533448 1 0
+0.318555 0.0988328 0.162645 0.00544252 1 0
+0.384049 0.150213 0.18977 0.00506271 1 0
+0.35882 0.0705367 0.0071012 0.00591425 1 0
+0.374241 0.107337 0.150027 0.0050843 1 0
+0.0585332 0.133693 0.194195 0.00493436 1 0
+0.0855199 0.118215 0.184505 0.0055736 1 0
+0.158235 0.138137 0.19419 0.00609273 1 0
+0.122416 0.07642 0.139554 0.0062318 1 0
+0.00479918 0.192651 0.081544 0.00545332 1 0
+0.27634 0.123768 0.072765 0.00597458 1 0
+0.0486482 0.0469649 0.145052 0.00514093 1 0
+0.19 0.0254881 0.159743 0.00501905 1 0
+0.37864 0.120691 0.00630193 0.00533048 1 0
+0.25 0.162741 0.161173 0.0051858 1 0
+0.0566476 0.069124 0.110854 0.00507997 1 0
+0.0116925 0.0406675 0.11733 0.0050623 1 0
+0.315558 0.141102 0.0689741 0.00550287 1 0
+0.180223 0.0123022 0.113459 0.00511602 1 0
+0.273171 0.138287 0.0113356 0.00504578 1 0
+0.26461 0.0518817 0.0868252 0.00543732 1 0
+0.229094 0.159702 0.0881235 0.00508333 1 0
+0.26882 0.0938501 0.113402 0.00500452 1 0
+0.349178 0.0540905 0.119842 0.00543585 1 0
+0.0760557 0.0196645 0.0539054 0.00560242 1 0
+0.242801 0.116421 0.034328 0.00532604 1 0
+0.313923 0.155856 0.0894238 0.00559722 1 0
+0.195836 0.105589 0.190249 0.00495681 1 0
+0.0559161 0.179048 0.149599 0.00500992 1 0
+0.252497 0.141266 0.0333844 0.00527091 1 0
+0.0868643 0.111262 0.116764 0.0049587 1 0
+0.350233 0.0345982 0.092011 0.00497733 1 0
+0.09 0.0412077 0.171813 0.00512945 1 0
+0.155742 0.155361 0.0307641 0.00526499 1 0
+0.15503 0.153165 0.0171135 0.00496063 1 0
+0.275704 0.0855324 0.120332 0.0067578 1 0
+0.102093 0.142054 0.139593 0.00507751 1 0
+0.239529 0.0907062 0.0290642 0.00558211 1 0
+0.206284 0.164971 0.15529 0.00676775 1 0
+0.033003 0.0442111 0.152608 0.00525452 1 0
+0.0275063 0.0428424 0.176527 0.0049388 1 0
+0.35862 0.149303 0.170872 0.00662706 1 0
+0.07 0.0215284 0.0227742 0.00496596 1 0
+0.115516 0.132417 0.0702031 0.00529467 1 0
+0.366673 0.153534 0.191388 0.00523087 1 0
+0.0213304 0.141411 0.194224 0.00541128 1 0
+0.106137 0.148663 0.0220844 0.00548936 1 0
+0.295259 0.0650414 0.0597985 0.0057072 1 0
+0.116732 0.150019 0.00547719 0.0057373 1 0
+0.298718 0.00847115 0.0998693 0.00542173 1 0
+0.103477 0.0980706 0.184761 0.00544981 1 0
+0.380526 0.154388 0.0254918 0.00504119 1 0
+0.270214 0.0877797 0.0223453 0.00543992 1 0
+0.314709 0.146188 0.157199 0.00492299 1 0
+0.0183423 0.184847 0.028443 0.00502048 1 0
+0.0872812 0.109532 0.177678 0.00554028 1 0
+0.104323 0.10894 0.166694 0.00671663 1 0
+0.310986 0.115453 0.0435155 0.0051215 1 0
+0.261494 0.0451588 0.14497 0.00564139 1 0
+0.214052 0.0206624 0.0755293 0.00529037 1 0
+0.106893 0.081013 0.0946225 0.00539707 1 0
+0.298594 0.155871 0.148747 0.00506892 1 0
+0.2684 0.0265539 0.125613 0.00542403 1 0
+0.271924 0.155568 0.128731 0.00627654 1 0
+0.190981 0.0881231 0.1063 0.00609074 1 0
+0.317668 0.162075 0.0759067 0.00525105 1 0
+0.161501 0.138712 0.135025 0.00560976 1 0
+0.275306 0.11263 0.0685627 0.0056332 1 0
+0.224296 0.141754 0.0863415 0.00509894 1 0
+0.162671 0.187559 0.127827 0.00547326 1 0
+0.215382 0.0994359 0.0865149 0.00813389 1 0
+0.175097 0.141131 0.121027 0.00551912 1 0
+0.142482 0.0456714 0.17182 0.00515071 1 0
+0.0871426 0.193219 0.0885682 0.00521211 1 0
+0.1382 0.120316 0.0420877 0.00498942 1 0
+0.182786 0.0783669 0.0664189 0.0067264 1 0
+0.139911 0.136595 0.136115 0.00610351 1 0
+0.153271 0.127392 0.136792 0.00714609 1 0
+0.134296 0.0259236 0.153496 0.00523579 1 0
+0.177675 0.144073 0.138335 0.00625251 1 0
+0.307612 0.0216726 0.0937214 0.00521856 1 0
+0.23 0.179957 0.176114 0.0053792 1 0
+0.190162 0.128682 0.112774 0.00604757 1 0
+0.0763513 0.183133 0.0817355 0.00601091 1 0
+0.202471 0.162916 0.0429757 0.0049886 1 0
+0.059156 0.0903555 0.0147954 0.00529511 1 0
+0.0774759 0.0907105 0.00848086 0.0064719 1 0
+0.104679 0.12904 0.107042 0.00505079 1 0
+0.156928 0.0667936 0.168618 0.00496171 1 0
+0.109435 0.114802 0.0340654 0.00526307 1 0
+0.202898 0.0988148 0.144118 0.00507812 1 0
+0.247038 0.0932036 0.0948382 0.00527664 1 0
+0.25441 0.0812233 0.0986122 0.00498023 1 0
+0.207974 0.0236615 0.0530072 0.00501154 1 0
+0.216544 0.0188464 0.0440366 0.0054604 1 0
+0.347109 0.15848 0.157316 0.00508872 1 0
+0.275296 0.175117 0.141214 0.00660876 1 0
+0.00496755 0.1067 0.119988 0.00513157 1 0
+0.297911 0.040944 0.040722 0.00499771 1 0
+0.159434 0.0956141 0.0793437 0.00573121 1 0
+0.283499 0.191069 0.14746 0.0062051 1 0
+0.0369525 0.147064 0.159164 0.00530303 1 0
+0.22607 0.161718 0.14422 0.00523933 1 0
+0.108679 0.0368119 0.0413441 0.00582451 1 0
+0.160892 0.158663 0.1593 0.00561418 1 0
+0.117058 0.136609 0.0401125 0.0050545 1 0
+0.307358 0.147503 0.0894396 0.00502678 1 0
+0.245616 0.147308 0.0379248 0.0049501 1 0
+0.392621 0.0111457 0.151269 0.00552043 1 0
+0.236105 0.110368 0.0613037 0.00536382 1 0
+0.245302 0.0805854 0.0785322 0.0050188 1 0
+0.0652638 0.0836976 0.083807 0.00535354 1 0
+0.32297 0.0769884 0.0234433 0.00493859 1 0
+0.0138609 0.156448 0.0232398 0.0050417 1 0
+0.360794 0.0355947 0.0448732 0.00591051 1 0
+0.178974 0.0989185 0.137006 0.00588317 1 0
+0.175662 0.152784 0.0430227 0.00496919 1 0
+0.0770389 0.0916468 0.0998569 0.00500567 1 0
+0.130172 0.156197 0.173118 0.0064809 1 0
+0.357743 0.0473451 0.116656 0.00592238 1 0
+0.195747 0.0966667 0.101135 0.00497218 1 0
+0.00530248 0.149842 0.121771 0.00585836 1 0
+0.306338 0.116316 0.00953368 0.00781098 1 0
+0.244299 0.0236894 0.182913 0.00500193 1 0
+0.215106 0.0280928 0.153081 0.00542675 1 0
+0.361435 0.15433 0.070999 0.00655125 1 0
+0.0932397 0.190976 0.141447 0.00640936 1 0
+0.153466 0.0468423 0.0457411 0.00518046 1 0
+0.191824 0.0385899 0.160921 0.00493513 1 0
+0.115354 0.154888 0.0550774 0.00509607 1 0
+0.0862296 0.163467 0.155967 0.00555456 1 0
+0.328104 0.185124 0.128874 0.00534291 1 0
+0.34386 0.153777 0.0544861 0.00600231 1 0
+0.162034 0.132633 0.144444 0.00561354 1 0
+0.360377 0.177149 0.0473056 0.00500698 1 0
+0.236277 0.19483 0.0243622 0.00525474 1 0
+0.118413 0.11688 0.0402421 0.0054435 1 0
+0.305835 0.155644 0.170986 0.00552785 1 0
+0.129544 0.141282 0.114632 0.00510482 1 0
+0.376786 0.018156 0.156706 0.00527047 1 0
+0.147745 0.185436 0.146696 0.00515421 1 0
+0.272266 0.15953 0.0903589 0.00520212 1 0
+0.22723 0.104227 0.0822697 0.00533343 1 0
+0.385255 0.175893 0.0649707 0.00515363 1 0
+0.23857 0.129915 0.0724236 0.00678225 1 0
+0.0351287 0.115887 0.0370834 0.00515281 1 0
+0.23379 0.0768889 0.102961 0.00529133 1 0
+0.311395 0.182793 0.00742186 0.00531421 1 0
+0.35 0.0342712 0.0193649 0.00502089 1 0
+0.163462 0.0941723 0.0980868 0.00582487 1 0
+0.220885 0.0883698 0.0979634 0.0050954 1 0
+0.381986 0.112109 0.0779516 0.00518927 1 0
+0.349757 0.149435 0.160687 0.00492043 1 0
+0.163168 0.149353 0.150924 0.00505876 1 0
+0.320919 0.180746 0.109715 0.00575719 1 0
+0.335675 0.0176508 0.0384298 0.00556491 1 0
+0.126986 0.115883 0.105086 0.00569101 1 0
+0.325076 0.0168704 0.0376704 0.0050906 1 0
+0.145427 0.117636 0.136501 0.00537628 1 0
+0.236591 0.177699 0.00704534 0.00517186 1 0
+0.149068 0.155496 0.116311 0.00586574 1 0
+0.155506 0.124715 0.148408 0.00498151 1 0
+0.170478 0.112538 0.118343 0.00557105 1 0
+0.25196 0.095997 0.0590623 0.00538771 1 0
+0.363179 0.151149 0.00658791 0.00524601 1 0
+0.333096 0.138546 0.101435 0.0054084 1 0
+0.0678159 0.156327 0.170413 0.0051171 1 0
+0.110907 0.0718823 0.0908004 0.00528436 1 0
+0.0145692 0.194365 0.0779644 0.0050922 1 0
+0.0956187 0.0132816 0.129183 0.00509384 1 0
+0.165112 0.161259 0.132262 0.00607402 1 0
+0.209558 0.0908923 0.0945273 0.00494699 1 0
+0.251909 0.00908388 0.014914 0.00533323 1 0
+0.261593 0.118391 0.0209312 0.00511847 1 0
+0.196188 0.0813525 0.0631632 0.00502461 1 0
+0.0258493 0.18743 0.124911 0.00498865 1 0
+0.360149 0.042735 0.161188 0.00548699 1 0
+0.35 0.0403613 0.161944 0.004963 1 0
+0.309527 0.124847 0.154487 0.00528182 1 0
+0.244683 0.101301 0.0655127 0.0055659 1 0
+0.325279 0.155186 0.066466 0.00559949 1 0
+0.226617 0.195266 0.00806071 0.00512528 1 0
+0.169953 0.0999186 0.108535 0.00504286 1 0
+0.137916 0.186472 0.184189 0.0064584 1 0
+0.0972162 0.134765 0.110854 0.00509749 1 0
+0.303273 0.0299333 0.0454584 0.00580123 1 0
+0.279745 0.0864832 0.0184272 0.0049462 1 0
+0.116074 0.0774425 0.154193 0.00638064 1 0
+0.248656 0.176256 0.0414543 0.00524495 1 0
+0.11719 0.0834206 0.0961585 0.00528837 1 0
+0.229539 0.118874 0.0684492 0.00511033 1 0
+0.173123 0.195374 0.111901 0.00501602 1 0
+0.136327 0.0396209 0.195201 0.0051349 1 0
+0.158862 0.147049 0.127001 0.00625819 1 0
+0.0991766 0.0235319 0.0445431 0.00538577 1 0
+0.201657 0.0487937 0.17149 0.00500199 1 0
+0.312662 0.0232805 0.0848822 0.00508772 1 0
+0.35945 0.135313 0.00927028 0.00523795 1 0
+0.104058 0.068495 0.17199 0.00518088 1 0
+0.037409 0.146655 0.174523 0.00493557 1 0
+0.148805 0.153965 0.160534 0.0051623 1 0
+0.328463 0.160841 0.0579076 0.00514102 1 0
+0.0221549 0.157353 0.194761 0.00500206 1 0
+0.322146 0.13593 0.192839 0.00542503 1 0
+0.286297 0.149768 0.00908993 0.00610423 1 0
+0.280655 0.166453 0.133761 0.00601319 1 0
+0.169994 0.185952 0.11743 0.00584323 1 0
+0.132045 0.045301 0.172359 0.00530653 1 0
+0.0777551 0.161616 0.131273 0.00552788 1 0
+0.199873 0.172401 0.0460262 0.00510947 1 0
+0.272171 0.0594096 0.160745 0.00532387 1 0
+0.165046 0.00600323 0.109875 0.00521884 1 0
+0.142337 0.0812874 0.0878795 0.00498215 1 0
+0.0924792 0.0732765 0.150215 0.00557322 1 0
+0.056255 0.16237 0.117474 0.00507203 1 0
+0.175249 0.16002 0.136546 0.00500027 1 0
+0.155973 0.175395 0.149447 0.00493138 1 0
+0.118544 0.152403 0.165247 0.00546414 1 0
+0.343404 0.159514 0.0899321 0.00495426 1 0
+0.128004 0.141325 0.154959 0.0049926 1 0
+0.244713 0.0307325 0.155689 0.00508441 1 0
+0.181902 0.141143 0.112709 0.00522801 1 0
+0.307729 0.138997 0.0192935 0.00507574 1 0
+0.331633 0.0900834 0.00664554 0.00528612 1 0
+0.216766 0.0824641 0.108869 0.00568365 1 0
+0.211694 0.10536 0.101931 0.00519168 1 0
+0.179299 0.0286834 0.154585 0.00503082 1 0
+0.00631072 0.147677 0.0345265 0.00543485 1 0
+0.332261 0.0910282 0.0655754 0.00591895 1 0
+0.326055 0.0639492 0.104676 0.00532498 1 0
+0.104297 0.0712327 0.152123 0.0049905 1 0
+0.337664 0.118813 0.146655 0.00500696 1 0
+0.16796 0.0880324 0.0899783 0.00520396 1 0
+0.151126 0.144095 0.117993 0.0051249 1 0
+0.167151 0.122918 0.127015 0.00578551 1 0
+0.347149 0.181876 0.140827 0.00657185 1 0
+0.353949 0.191197 0.140731 0.00496706 1 0
+0.28435 0.189917 0.0435792 0.00586862 1 0
+0.222213 0.0143369 0.0721368 0.00557794 1 0
+0.279042 0.0945755 0.11326 0.00519755 1 0
+0.210267 0.0545971 0.188648 0.00515023 1 0
+0.317678 0.147377 0.193662 0.00621996 1 0
+0.250707 0.128303 0.0628843 0.00550307 1 0
+0.0200183 0.12112 0.083305 0.00501581 1 0
+0.177239 0.118432 0.146594 0.00520612 1 0
+0.111327 0.0824235 0.166339 0.00591941 1 0
+0.155479 0.146328 0.186009 0.0050508 1 0
+0.0919961 0.140076 0.142581 0.00563671 1 0
+0.269316 0.144037 0.131719 0.00560771 1 0
+0.150699 0.139069 0.133101 0.00536768 1 0
+0.209042 0.108432 0.0794174 0.00496219 1 0
+0.216699 0.112429 0.0861932 0.00492981 1 0
+0.101038 0.133943 0.0973033 0.00644403 1 0
+0.0966487 0.120678 0.107036 0.00523101 1 0
+0.202327 0.02737 0.0603728 0.0049831 1 0
+0.193253 0.0784818 0.0730075 0.00564155 1 0
+0.0868005 0.12796 0.110006 0.00531148 1 0
+0.238097 0.139762 0.0654122 0.00531521 1 0
+0.154478 0.00735788 0.109484 0.00544259 1 0
+0.103283 0.128144 0.0876139 0.0050692 1 0
+0.270558 0.16535 0.0986312 0.00505513 1 0
+0.157723 0.105315 0.0744188 0.00528203 1 0
+0.169762 0.151644 0.135452 0.00507249 1 0
+0.125053 0.149402 0.11914 0.00521138 1 0
+0.268898 0.165729 0.134488 0.00578782 1 0
+0.170716 0.13527 0.138964 0.00498681 1 0
+0.171308 0.127188 0.14667 0.00536928 1 0
+0.277086 0.157709 0.00506657 0.00534523 1 0
+0.1712 0.00837622 0.119438 0.00530001 1 0
+0.355425 0.144238 0.00571681 0.00517774 1 0
+0.166652 0.083414 0.0995339 0.00524142 1 0
+0.119505 0.139675 0.114664 0.00506236 1 0
+0.204039 0.110165 0.106515 0.00494264 1 0
+0.39225 0.188542 0.150983 0.00565893 1 0
+0.148649 0.136782 0.143078 0.00506248 1 0
+0.22953 0.112953 0.0768692 0.0051831 1 0
+0.0694713 0.0871968 0.0941546 0.00546271 1 0
+0.259241 0.149048 0.128677 0.00604828 1 0
+0.170321 0.17059 0.134922 0.00493746 1 0
+0.275538 0.146728 0.00487594 0.00536114 1 0
+0.169881 0.149538 0.125133 0.00519197 1 0
+0.159116 0.151902 0.139595 0.00532538 1 0
+0.165307 0.125014 0.137586 0.00514797 1 0
+0.187238 0.105113 0.140191 0.00492454 1 0
+0.0980079 0.195089 0.151294 0.00527918 1 0
+0.0896188 0.149924 0.139441 0.00497002 1 0
+0.109522 0.139505 0.105479 0.0049669 1 0
+0.168901 0.107365 0.101898 0.00498716 1 0
+0.0467424 0.143688 0.176425 0.00504098 1 0
+0.258472 0.137915 0.130327 0.00523309 1 0
+0.264116 0.173093 0.0996929 0.00507272 1 0
+0.175687 0.0787602 0.0994242 0.00492242 1 0
+0.190441 0.0686624 0.0757399 0.00493151 1 0
diff --git a/src/Tools/padder/resources/padderexe/med2/concrete.med b/src/Tools/padder/resources/padderexe/med2/concrete.med
new file mode 100644 (file)
index 0000000..3b39b27
Binary files /dev/null and b/src/Tools/padder/resources/padderexe/med2/concrete.med differ
diff --git a/src/Tools/padder/resources/padderexe/med2/data.txt b/src/Tools/padder/resources/padderexe/med2/data.txt
new file mode 100644 (file)
index 0000000..f7a6b44
--- /dev/null
@@ -0,0 +1,5 @@
+concrete.med concrete
+nbSteelFiles 2
+ferrtran.med ferrtran
+ferraill.med ferraill
+output.med
diff --git a/src/Tools/padder/resources/padderexe/med2/ferraill.med b/src/Tools/padder/resources/padderexe/med2/ferraill.med
new file mode 100644 (file)
index 0000000..79cda88
Binary files /dev/null and b/src/Tools/padder/resources/padderexe/med2/ferraill.med differ
diff --git a/src/Tools/padder/resources/padderexe/med2/ferrtran.med b/src/Tools/padder/resources/padderexe/med2/ferrtran.med
new file mode 100644 (file)
index 0000000..0a86670
Binary files /dev/null and b/src/Tools/padder/resources/padderexe/med2/ferrtran.med differ
diff --git a/src/Tools/padder/resources/padderexe/med2/padder.exe b/src/Tools/padder/resources/padderexe/med2/padder.exe
new file mode 100755 (executable)
index 0000000..8591550
Binary files /dev/null and b/src/Tools/padder/resources/padderexe/med2/padder.exe differ
diff --git a/src/Tools/padder/resources/padderexe/med3/concrete.med b/src/Tools/padder/resources/padderexe/med3/concrete.med
new file mode 100644 (file)
index 0000000..3b39b27
Binary files /dev/null and b/src/Tools/padder/resources/padderexe/med3/concrete.med differ
diff --git a/src/Tools/padder/resources/padderexe/med3/data.txt b/src/Tools/padder/resources/padderexe/med3/data.txt
new file mode 100644 (file)
index 0000000..04cabc7
--- /dev/null
@@ -0,0 +1,4 @@
+concrete.med concrete
+nbSteelbarMesh= 1
+ferraill.med ferraill
+FinalEDMesh.med
diff --git a/src/Tools/padder/resources/padderexe/med3/ferraill.med b/src/Tools/padder/resources/padderexe/med3/ferraill.med
new file mode 100644 (file)
index 0000000..79cda88
Binary files /dev/null and b/src/Tools/padder/resources/padderexe/med3/ferraill.med differ
diff --git a/src/Tools/padder/resources/padderexe/med3/padder.exe b/src/Tools/padder/resources/padderexe/med3/padder.exe
new file mode 100755 (executable)
index 0000000..3eca741
Binary files /dev/null and b/src/Tools/padder/resources/padderexe/med3/padder.exe differ
diff --git a/src/Tools/padder/resources/padderexe/padder.sh b/src/Tools/padder/resources/padderexe/padder.sh
new file mode 100755 (executable)
index 0000000..d68b561
--- /dev/null
@@ -0,0 +1,34 @@
+#!/bin/sh
+# Copyright (C) 2011-2012  CEA/DEN, EDF R&D
+#
+# 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.com
+#
+
+# This script emulates the launcher script that will be generated by
+# the padder SALOME component and give as the "job file" to the SALOME
+# launcher to execute the padder job.
+# The script is supposed to be executed where the data are located.
+
+here=$(dirname $0)
+
+# >>> This part should be written by the component
+binpath=$here/padder.exe
+envpath=$here/envPadder.sh
+# <<<
+
+. $envpath
+$binpath $here/data.txt
diff --git a/src/Tools/padder/resources/padderexe/particules.png b/src/Tools/padder/resources/padderexe/particules.png
new file mode 100644 (file)
index 0000000..a1b97ec
Binary files /dev/null and b/src/Tools/padder/resources/padderexe/particules.png differ
diff --git a/src/Tools/padder/spadderpy/Makefile.am b/src/Tools/padder/spadderpy/Makefile.am
new file mode 100644 (file)
index 0000000..c28a874
--- /dev/null
@@ -0,0 +1,36 @@
+# Copyright (C) 2011-2012  EDF R&D
+#
+# 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.com
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+SUBDIRS = 
+
+if SMESH_ENABLE_GUI
+SUBDIRS += gui plugin
+endif
+
+DIST_SUBDIRS = gui plugin
+
+spadderpydir=$(smeshpypkgdir)/spadder
+spadderpy_PYTHON = \
+       __init__.py \
+       configreader.py
+
+salomeplugins_DATA = \
+       padder.cfg
diff --git a/src/Tools/padder/spadderpy/__init__.py b/src/Tools/padder/spadderpy/__init__.py
new file mode 100644 (file)
index 0000000..911cf5b
--- /dev/null
@@ -0,0 +1,93 @@
+# Copyright (C) 2011-2012  EDF R&D
+#
+# 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.com
+#
+# Author(s): Guillaume Boulant (23/03/2011)
+#
+
+# TODO: put all this stuff in the unitests package
+
+import os
+def getRootDir():
+    '''
+    This returns the root directory where the module SPADDER is
+    installed. All test files are looked up from this location.
+    '''
+    return os.environ['SMESH_ROOT_DIR']
+
+def getTestDataDir():
+    '''
+    This function gives the absolute path to the directory containing
+    the data files for test (realistic med files).
+    '''
+    datadir=os.path.join(getRootDir(),"share/salome/resources/smesh/padderexe")
+    return datadir
+
+import MESHJOB # to get the enum constant values
+from MESHJOB import MeshJobParameter, MeshJobParameterList
+
+DEFAULT_CONCRETE_FILENAME=os.path.join(getTestDataDir(),'concrete.med')
+DEFAULT_STEELBAR_LISTFILENAME=[
+    os.path.join(getTestDataDir(),'ferraill.med')
+    ]
+
+def getMeshJobParameterList(concrete_filename=DEFAULT_CONCRETE_FILENAME,
+                            steelbar_listfilename=DEFAULT_STEELBAR_LISTFILENAME):
+    '''
+    This helper function creates a complete set of parameters (a
+    MeshJobParameterList) for a simple test case, i.e. a case with a
+    concrete filename and a single steelbar filename.
+    '''
+    # Note that a CORBA sequence (MeshJobParameterList) is mapped on a
+    # simple list in python
+    meshJobParameterList = []
+    # We can add some parameters
+    param = MeshJobParameter(
+        file_name  = concrete_filename,
+        file_type  = MESHJOB.MED_CONCRETE,
+        group_name = "concrete")
+    meshJobParameterList.append(param)
+
+    for steelbar_filename in steelbar_listfilename:
+        param = MeshJobParameter(
+            file_name  = steelbar_filename,
+            file_type  = MESHJOB.MED_STEELBAR,
+            group_name = "steelbar")
+        meshJobParameterList.append(param)
+
+    return meshJobParameterList
+
+
+def getSpadderCatalogFilename():
+    filename=os.path.join(getRootDir(),"share/salome/resources/smesh/SPADDERCatalog.xml")
+    return filename
+
+def loadSpadderCatalog():
+    import salome
+    salome.salome_init()
+    obj = salome.naming_service.Resolve('Kernel/ModulCatalog')
+    import SALOME_ModuleCatalog
+    catalog = obj._narrow(SALOME_ModuleCatalog.ModuleCatalog)
+    if not catalog:
+        raise RuntimeError, "Can't accesss module catalog"
+
+    filename = getSpadderCatalogFilename()
+    catalog.ImportXmlCatalogFile(filename)
+
+    from salome.kernel import services
+    print "The list of SALOME components is now:" 
+    print services.getComponentList()
diff --git a/src/Tools/padder/spadderpy/configreader.py b/src/Tools/padder/spadderpy/configreader.py
new file mode 100644 (file)
index 0000000..ceacf54
--- /dev/null
@@ -0,0 +1,140 @@
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2011-2012  EDF R&D
+#
+# 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.com
+#
+# Author(s): Guillaume Boulant (23/03/2011)
+#
+
+import sys, os
+import ConfigParser
+from MESHJOB import ConfigParameter
+from salome.kernel.uiexception import AdminException, UiException
+
+from salome_pluginsmanager import PLUGIN_PATH_PATTERN
+CONFIG_RELPATH  = os.path.join(PLUGIN_PATH_PATTERN,'smesh')
+CONFIG_FILENAME = "padder.cfg"
+TYPE_LOCAL   = 'local'
+TYPE_REMOTE  = 'remote'
+TYPES=[TYPE_LOCAL, TYPE_REMOTE]
+
+class ConfigReader:
+    def __init__(self):
+        # The first step is to look for the config file. This file
+        # is supposed to be located in the same directory than the
+        # padder plugin. Then, we have to scan the directories
+        # specified in the SALOME plugins path.
+        self.__configFilename = None
+        try:
+            smeshpath=os.environ["SMESH_ROOT_DIR"]
+        except KeyError, ex:
+            raise AdminException("You should define the variable SMESH_ROOT_DIR")
+
+        pluginspath = os.path.join(smeshpath,CONFIG_RELPATH)
+        filename    = os.path.join(pluginspath,CONFIG_FILENAME)
+        if os.path.exists(filename):
+            self.__configFilename = filename
+        else:
+            msg = "The configuration file %s can't be found in the SMESH plugins path %s"
+            raise AdminException(msg%(CONFIG_FILENAME,pluginspath))
+
+        print "The configuration file is : %s"%self.__configFilename
+        self.__configparser = ConfigParser.RawConfigParser()
+        try:
+            self.__configparser.read(self.__configFilename)
+        except ConfigParser.ParsingError, ex:
+            raise AdminException(ex.message)
+
+    def getLocalConfig(self):
+        return self.__getConfig(TYPE_LOCAL)
+    
+    def getRemoteConfig(self):
+        return self.__getConfig(TYPE_REMOTE)
+
+    def getDefaultConfig(self):
+        defaultType = self.__getDefaultType()
+        return self.__getConfig(defaultType)
+        
+    def __getConfig(self, type=TYPE_LOCAL):
+        configName = self.__configparser.get('resources', type)
+        resname = self.__configparser.get(configName, 'resname')
+        binpath = self.__configparser.get(configName, 'binpath')
+        envpath = self.__configparser.get(configName, 'envpath')
+        config = ConfigParameter(resname, binpath, envpath)
+        config.resname = resname
+        return config
+
+    def __getDefaultType(self):
+        '''This returns the default type read in the config file ([resources], default)'''
+        defaultType = self.__configparser.get('preferences', 'defaultres')
+        if defaultType not in TYPES:
+            return TYPE_LOCAL
+        return defaultType
+
+
+def printConfig(config):
+    print "PADDER CONFIGURATION:"
+    print "\tconfig.resname = %s"%config.resname
+    print "\tconfig.binpath = %s"%config.binpath
+    print "\tconfig.envpath = %s"%config.envpath
+    
+
+#
+# =========================================================================
+# Test runner
+# =========================================================================
+#
+def TEST_getDefaultConfig():
+    try:
+        configReader = ConfigReader()
+        defaultConfig = configReader.getDefaultConfig()
+        print defaultConfig.resname
+        print defaultConfig.binpath
+        print defaultConfig.envpath
+    except Exception, ex:
+        sys.stderr.write('ERROR: %s\n' % str(ex))
+        return False
+    
+    return True
+
+def TEST_getDefaultConfig_withError():
+    global CONFIG_FILENAME
+    CONFIG_FILENAME = "toto.cfg"
+    try:
+        configReader = ConfigReader()
+        defaultConfig = configReader.getDefaultConfig()
+    except UiException, err:
+        print 'ERROR: %s' % str(err)
+        return True
+    
+    return False
+
+
+from salome.kernel import unittester
+moduleName = "configreader"
+
+def testsuite():
+    unittester.run(moduleName, "TEST_getDefaultConfig")
+    unittester.run(moduleName, "TEST_getDefaultConfig_withError")
+    
+if __name__ == "__main__":
+    #import os, sys
+    #pluginspath=os.environ["SALOME_PLUGINS_PATH"]
+    #for path in pluginspath.split(":"):
+    #    sys.path.insert(0,path)
+    
+    testsuite()
diff --git a/src/Tools/padder/spadderpy/gui/Makefile.am b/src/Tools/padder/spadderpy/gui/Makefile.am
new file mode 100644 (file)
index 0000000..02d4ffd
--- /dev/null
@@ -0,0 +1,60 @@
+# Copyright (C) 2011-2012  EDF R&D
+#
+# 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.com
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+#
+# Files that compose the spadder graphical interface used by the
+# plugin. They are installed in the spadder python package, under the
+# sub-package plugins.
+#
+spadderpydir=$(smeshpypkgdir)/spadder/gui
+dist_spadderpy_PYTHON = \
+       __init__.py \
+       plugindialog.py \
+       inputdialog.py \
+       inputdata.py
+
+PYUIC_FILES = \
+       plugindialog_ui.py \
+       inputframe_ui.py
+
+nodist_spadderpy_PYTHON = $(PYUIC_FILES)
+CLEANFILES = $(PYUIC_FILES)
+
+dist_spadderpy_DATA= \
+       parameters.png \
+       input.png \
+       select.png \
+       compute.png \
+       refresh.png \
+       publish.png \
+       clear.png \
+       addinput.png \
+       deleteinput.png \
+       concrete.png \
+       steelbar.png
+
+%_ui.py:%.ui
+       $(PYUIC) -x $< -o $@
+
+%_rc.py:%.qrc
+       $(PYRCC) $< -o $@
+
+EXTRA_DIST += $(PYUIC_FILES:%_ui.py=%.ui)
diff --git a/src/Tools/padder/spadderpy/gui/__init__.py b/src/Tools/padder/spadderpy/gui/__init__.py
new file mode 100644 (file)
index 0000000..4bde9bc
--- /dev/null
@@ -0,0 +1,20 @@
+#  Copyright (C) 2011-2012 EDF R&D
+#
+#  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.com
+#
+# Author(s): Guillaume Boulant (23/03/2011)
+#
diff --git a/src/Tools/padder/spadderpy/gui/addinput.png b/src/Tools/padder/spadderpy/gui/addinput.png
new file mode 100644 (file)
index 0000000..408b6b4
Binary files /dev/null and b/src/Tools/padder/spadderpy/gui/addinput.png differ
diff --git a/src/Tools/padder/spadderpy/gui/clear.png b/src/Tools/padder/spadderpy/gui/clear.png
new file mode 100644 (file)
index 0000000..642001b
Binary files /dev/null and b/src/Tools/padder/spadderpy/gui/clear.png differ
diff --git a/src/Tools/padder/spadderpy/gui/compute.png b/src/Tools/padder/spadderpy/gui/compute.png
new file mode 100644 (file)
index 0000000..37c77a5
Binary files /dev/null and b/src/Tools/padder/spadderpy/gui/compute.png differ
diff --git a/src/Tools/padder/spadderpy/gui/concrete.png b/src/Tools/padder/spadderpy/gui/concrete.png
new file mode 100644 (file)
index 0000000..33af046
Binary files /dev/null and b/src/Tools/padder/spadderpy/gui/concrete.png differ
diff --git a/src/Tools/padder/spadderpy/gui/deleteinput.png b/src/Tools/padder/spadderpy/gui/deleteinput.png
new file mode 100644 (file)
index 0000000..86c3e36
Binary files /dev/null and b/src/Tools/padder/spadderpy/gui/deleteinput.png differ
diff --git a/src/Tools/padder/spadderpy/gui/input.png b/src/Tools/padder/spadderpy/gui/input.png
new file mode 100644 (file)
index 0000000..a8a67db
Binary files /dev/null and b/src/Tools/padder/spadderpy/gui/input.png differ
diff --git a/src/Tools/padder/spadderpy/gui/inputdata.py b/src/Tools/padder/spadderpy/gui/inputdata.py
new file mode 100644 (file)
index 0000000..2aa54e6
--- /dev/null
@@ -0,0 +1,77 @@
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2011-2012  EDF R&D
+#
+# 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.com
+#
+# Author : Guillaume Boulant (EDF)
+#
+
+from salome.kernel.enumerate import Enumerate
+from salome.kernel.datamodeler import DataModeler, TypeString, TypeInteger
+
+# __MEM__: Note that this module does not depend on the SPADDER
+# component on purpose (we could have use a derived structure of
+# SPADDER_ORB.MeshJobParameter). This choice is made to ease the test
+# and development of the gui part of the plugin. If this data
+# structure becomes too important, we could make another arrangement
+# and use directly a SPADDER_ORB.MeshJobParameter.
+
+class InputData(DataModeler):
+    MESHTYPES=Enumerate([
+        'CONCRETE',
+        'STEELBAR'
+        ])
+
+    def __init__(self):
+        DataModeler.__init__(self)
+        self.addAttribute(
+            name  = "meshObject",
+            void  = True
+            )
+        self.addAttribute(
+            name  = "meshName",
+            type  = TypeString,
+            range = None
+            )
+        self.addAttribute(
+            name  = "meshType",
+            type  = TypeInteger,
+            range = self.MESHTYPES.listvalues()
+            )
+        self.addAttribute(
+            name  = "groupName",
+            type  = TypeString,
+            range = None
+            )
+
+#
+# ==============================================================================
+# Basic use cases and unit tests
+# ==============================================================================
+#
+def TEST_getName():
+    testdata = InputData()
+    testdata.meshName   = "myMesh"
+    testdata.meshObject = None
+    testdata.meshType   = InputData.MESHTYPES.CONCRETE
+    if testdata.meshName != "myMesh" :
+        return False
+    return True
+
+if __name__ == "__main__":
+    from salome.kernel.unittester import run
+    run("inputdata","TEST_getName")
diff --git a/src/Tools/padder/spadderpy/gui/inputdialog.py b/src/Tools/padder/spadderpy/gui/inputdialog.py
new file mode 100644 (file)
index 0000000..c9d8ae6
--- /dev/null
@@ -0,0 +1,376 @@
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2011-2012  EDF R&D
+#
+# 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.com
+#
+# Author : Guillaume Boulant (EDF)
+#
+
+import os
+
+import salome
+from salome.kernel import studyedit
+from salome.gui.genericdialog import GenericDialog
+from salome.gui import helper as guihelper
+from salome.smesh.smeshstudytools import SMeshStudyTools
+
+from omniORB import CORBA
+
+from PyQt4.QtCore import QObject, SIGNAL, SLOT
+from PyQt4.QtGui import QIcon, QStandardItemModel, QStandardItem, QMessageBox
+
+from inputframe_ui import Ui_InputFrame
+from inputdata import InputData
+
+DEBUG_MODE=True
+GROUPNAME_MAXLENGTH=8
+
+class InputDialog(GenericDialog):
+
+    TBL_HEADER_LABEL=["Input Mesh", "Output group name"]
+
+    def __init__(self, parent=None, name="InputDialog", modal=0):
+        """
+        This initializes a dialog windows to define the input data of
+        the plugin function. The input data consist in a list of
+        meshes characterizes each by a name, a pointer to the smesh
+        servant object, a type and a group name (see data model in the
+        inputdata.py).
+        """
+        GenericDialog.__init__(self, parent, name, modal)
+        # Set up the user interface from Designer.
+        self.__ui = Ui_InputFrame()
+        # BE CAREFULL HERE, the ui form is NOT drawn in the global
+        # dialog (already containing some generic widgets) but in the
+        # center panel created in the GenericDialog as a void
+        # container for the form. The InputFrame form is supposed
+        # here to create only the widgets to be placed in the center
+        # panel. Then, the setupUi function of this form draws itself
+        # in the specified panel, i.e. the panel returned by
+        # self.getPanel().
+        self.__ui.setupUi(self.getPanel())
+
+        self.setWindowTitle("Specification of input files")
+
+        # The icon are supposed to be located in the plugin folder,
+        # i.e. in the same folder than this python module file
+        iconfolder=os.path.dirname(os.path.abspath(__file__))
+        icon = QIcon()
+        icon.addFile(os.path.join(iconfolder,"select.png"))
+        self.__ui.btnSmeshObject.setIcon(icon)
+        icon = QIcon()
+        icon.addFile(os.path.join(iconfolder,"addinput.png"))
+        self.__ui.btnAddInput.setIcon(icon)
+        icon = QIcon()
+        icon.addFile(os.path.join(iconfolder,"deleteinput.png"))
+        self.__ui.btnDeleteInput.setIcon(icon)
+
+        # We specify here the items in the combo box (even if already
+        # defined in the designer) so that we can be sure of the item
+        # indexation.
+        self.MESHTYPE_ICONS = {}
+        meshTypeIndex = InputData.MESHTYPES.CONCRETE
+        self.__ui.cmbMeshType.setItemText(meshTypeIndex, "Béton")
+        icon = QIcon()
+        icon.addFile(os.path.join(iconfolder,"concrete.png"))
+        self.__ui.cmbMeshType.setItemIcon(meshTypeIndex, icon)
+        self.MESHTYPE_ICONS[meshTypeIndex] = icon
+
+        meshTypeIndex = InputData.MESHTYPES.STEELBAR
+        self.__ui.cmbMeshType.setItemText(meshTypeIndex, "Acier")
+        icon = QIcon()
+        icon.addFile(os.path.join(iconfolder,"steelbar.png"))
+        self.__ui.cmbMeshType.setItemIcon(meshTypeIndex, icon)
+        self.MESHTYPE_ICONS[meshTypeIndex] = icon
+        
+        # The click on btnSmeshObject (signal clicked() emitted by the
+        # button btnSmeshObject) is connected to the slot
+        # onSelectSmeshObject, etc ...
+        self.connect(self.__ui.btnSmeshObject, SIGNAL('clicked()'), self.onSelectSmeshObject )
+        self.connect(self.__ui.btnAddInput,    SIGNAL('clicked()'), self.onAddInput )
+        self.connect(self.__ui.btnDeleteInput, SIGNAL('clicked()'), self.onDeleteInput )
+
+        # Set up the model of the Qt table list
+        self.__inputModel = QStandardItemModel(0,2)
+        self.__inputModel.setHorizontalHeaderLabels(InputDialog.TBL_HEADER_LABEL)
+        self.__ui.tblListInput.setModel(self.__inputModel)
+        self.__ui.tblListInput.verticalHeader().hide()
+        self.__ui.tblListInput.horizontalHeader().setStretchLastSection(True)
+        # Note that the type is not display explicitly in the Qt table
+        # because it is specified using an icon on the text of the
+        # name item. 
+
+        # Note that PADDER does not support group name longer than 8
+        # characters. We apply then this limit in the gui field.
+        self.__ui.txtGroupName.setMaxLength(GROUPNAME_MAXLENGTH)
+
+        self.clear()
+
+        self.smeshStudyTool = SMeshStudyTools()
+
+    def clear(self):
+        """
+        This function clears the data gui area and associated values.
+        """
+        self.__ui.txtSmeshObject.setText("")
+        self.__ui.txtGroupName.setText("")
+        self.__inputModel.clear()
+        self.__inputModel.setHorizontalHeaderLabels(InputDialog.TBL_HEADER_LABEL)
+        if not DEBUG_MODE:
+            self.__ui.txtSmeshObject.setEnabled(False)
+            self.__ui.btnAddInput.setEnabled(False)
+        self.__selectedMesh = None
+        self.__dictInputData = {}
+        self.__nbConcreteMesh = 0
+        self.__nbSteelbarMesh = 0
+
+    def accept(self):
+        """
+        This function is the slot connected to the button OK
+        """
+        # The dialog is raised in a non modal mode to get
+        # interactivity with the parents windows. Then we have to emit
+        # a signal to warn the parent observer that the dialog has
+        # been validated so that it can process the event
+        GenericDialog.accept(self)
+        if self.wasOk():
+            self.emit(SIGNAL('inputValidated()'))
+
+    def onSelectSmeshObject(self):
+        '''
+        This function is the slot connected on the mesh selection
+        button. It memorizes the selected mesh and put its name in the
+        text field of the dialog box.
+        '''
+        mySObject, myEntry = guihelper.getSObjectSelected()
+        if CORBA.is_nil(mySObject):
+            self.__ui.txtSmeshObject.setText("You must choose a mesh")
+            self.__ui.txtGroupName.setText("")
+            self.__ui.txtSmeshObject.setEnabled(False)
+            self.__ui.btnAddInput.setEnabled(False)
+            self.__selectedMesh = None
+            return
+
+        self.smeshStudyTool.updateStudy(studyedit.getActiveStudyId())
+        self.__selectedMesh = self.smeshStudyTool.getMeshObjectFromSObject(mySObject)
+        if CORBA.is_nil(self.__selectedMesh):
+            self.__ui.txtSmeshObject.setText("The selected object is not a mesh")
+            self.__ui.txtGroupName.setText("")
+            self.__ui.txtSmeshObject.setEnabled(False)
+            self.__ui.btnAddInput.setEnabled(False)
+            self.__selectedMesh = None
+            return
+        myName = mySObject.GetName()
+        self.__ui.txtSmeshObject.setText(myName)
+        self.__ui.txtSmeshObject.setEnabled(True)
+        self.__ui.btnAddInput.setEnabled(True)
+
+        # We can suggest a default group name from the mesh name
+        self.__ui.txtGroupName.setText(myName)
+
+    def onAddInput(self):
+        """
+        This function is the slot connected to the Add button. It
+        creates a new entry in the list of input data, or updates this
+        entry if it already exists.
+        """
+        meshName   = str(self.__ui.txtSmeshObject.text().trimmed())
+        meshObject = self.__selectedMesh
+        meshType   = self.__ui.cmbMeshType.currentIndex()
+        groupName  = str(self.__ui.txtGroupName.text().trimmed())
+
+        self.__addInputInGui(meshName, meshObject, meshType, groupName)
+        self.__addInputInMap(meshName, meshObject, meshType, groupName)
+
+    def __addInputInGui(self, meshName, meshObject, meshType, groupName):
+        """
+        This function adds an entry with the specified data int the
+        GUI table (for data visualization purpose).
+        """
+        # The mesh name is used as the key index in the model. We have
+        # to check first if this item already exists in the list.
+        tblItems = self.__inputModel.findItems(meshName)
+        row = self.__inputModel.rowCount()
+        if not tblItems:
+            tblItems = []
+            tblItems.append(QStandardItem()) # input mesh name
+            tblItems.append(QStandardItem()) # output group name
+        else:
+            row = tblItems[0].index().row()
+            tblItems.append(self.__inputModel.item(row,1))
+
+        tblItems[0].setText(meshName)
+        tblItems[0].setIcon(self.MESHTYPE_ICONS[meshType])
+        tblItems[1].setText(groupName)
+        self.__inputModel.setItem(row,0,tblItems[0])
+        self.__inputModel.setItem(row,1,tblItems[1])
+        self.__ui.tblListInput.setCurrentIndex(tblItems[0].index())
+
+    def __addInputInMap(self, meshName, meshObject, meshType, groupName):
+        """
+        This function adds an entry with the specified data in the
+        internal map (for data management purpose).
+        """
+        # if the entry already exists, we remove it to replace by a
+        # new one
+        if self.__dictInputData.has_key(meshName):
+            self.__delInputFromMap(meshName)
+        
+        inputData = InputData()
+        inputData.meshName   = meshName
+        inputData.meshObject = meshObject
+        inputData.meshType   = meshType
+        inputData.groupName  = groupName
+        # The key of the map is the mesh name
+        self.__dictInputData[meshName] = inputData
+        if inputData.meshType == InputData.MESHTYPES.CONCRETE:
+            self.__nbConcreteMesh += 1
+        else:
+            self.__nbSteelbarMesh += 1
+
+        print inputData
+        print "meshType = ",inputData.meshType
+        print "nb concrete mesh ",self.__nbConcreteMesh
+        print "nb steelbar mesh ",self.__nbSteelbarMesh
+            
+
+    def onDeleteInput(self):
+        """
+        This function is the slot connected to the Delete button. It
+        remove from the data list the entry selected in the Qt table.
+        """
+        selectedIdx = self.__ui.tblListInput.selectedIndexes()
+        if selectedIdx:
+            row  = selectedIdx[0].row()
+            tblItem  = self.__inputModel.item(row,0)
+            meshName = str(tblItem.text())
+            self.__inputModel.takeRow(row)
+            # Don't forget to remove this entry from the mesh object
+            # internal dictionnary
+            self.__delInputFromMap(meshName)
+
+    def __delInputFromMap(self, meshName):
+        """
+        This function removes the specified entry from the internal
+        map (for data management purpose) 
+        """
+        inputData = self.__dictInputData.pop(meshName)
+        if inputData.meshType == InputData.MESHTYPES.CONCRETE:
+            self.__nbConcreteMesh -= 1
+        else:
+            self.__nbSteelbarMesh -= 1
+
+        print inputData
+        print "nb concrete mesh ",self.__nbConcreteMesh
+        print "nb steelbar mesh ",self.__nbSteelbarMesh
+
+
+    def setData(self, listInputData=[]):
+        """
+        This function fills the dialog widgets with values provided by
+        the specified data list.
+        """
+        self.clear()
+        for inputData in listInputData:
+
+            meshName   = inputData.meshName
+            meshObject = inputData.meshObject
+            meshType   = inputData.meshType
+            groupName  = inputData.groupName
+            
+            self.__addInputInGui(meshName, meshObject, meshType, groupName)
+            self.__addInputInMap(meshName, meshObject, meshType, groupName)
+
+            if not DEBUG_MODE:
+                self.onSelectSmeshObject()
+
+    def getData(self):
+        """
+        This function returns a list of InputData that corresponds to
+        the data in the dialog widgets of the current dialog.
+        """
+        # Note that the values() function returns a copy of the list
+        # of values.
+        return self.__dictInputData.values()
+        
+    def checkData(self):
+        """
+        This function checks if the data are valid, from the dialog
+        window point of view.
+        """
+        if self.__nbConcreteMesh < 1:
+            self.checkDataMessage = "You must define at least one CONCRETE mesh"
+            return False        
+        if self.__nbConcreteMesh > 1:
+            self.checkDataMessage  = "You define multiple CONCRETE meshes."
+            self.checkDataMessage += "You should verify first that your version of PADDER support this configuration."
+            # just warn the user, but don't block
+            QMessageBox.information(self, "Info", self.checkDataMessage)
+            return True
+        if self.__nbSteelbarMesh < 1:
+            self.checkDataMessage = "You must define at least one STEELBAR mesh"
+            return False
+        return True
+
+
+# ==============================================================================
+# Basic use case
+# ==============================================================================
+#
+def TEST_InputDialog():
+    import sys
+    from PyQt4.QtCore import QObject, SIGNAL, SLOT
+    from PyQt4.QtGui import QApplication
+    app = QApplication(sys.argv)
+    QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
+
+    dlg=InputDialog()
+    dlg.displayAndWait()
+    if dlg.wasOk():
+        print "OK has been pressed"
+
+def TEST_InputDialog_setData():
+    import sys
+    from PyQt4.QtCore import QObject, SIGNAL, SLOT
+    from PyQt4.QtGui import QApplication
+    app = QApplication(sys.argv)
+    QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
+
+    dlg=InputDialog()
+
+    from inputdata import InputData
+    inputData = InputData()
+    inputData.meshName   = "myMesh"
+    inputData.meshObject = None
+    inputData.meshType   = InputData.MESHTYPES.CONCRETE
+    inputData.groupName  = "myGroup"
+    listInputData = []
+    listInputData.append(inputData)
+    
+    dlg.setData2(listInputData)
+    
+    dlg.displayAndWait()
+    if dlg.wasOk():
+        print "OK has been pressed"
+        outputListInputData = dlg.getData2()
+        print outputListInputData
+
+
+if __name__ == "__main__":
+    #TEST_InputDialog()
+    TEST_InputDialog_setData()
+
diff --git a/src/Tools/padder/spadderpy/gui/inputframe.ui b/src/Tools/padder/spadderpy/gui/inputframe.ui
new file mode 100644 (file)
index 0000000..9f98eb9
--- /dev/null
@@ -0,0 +1,204 @@
+<ui version="4.0" >
+ <class>InputFrame</class>
+ <widget class="QDialog" name="InputFrame" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>509</width>
+    <height>307</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>Input parameters</string>
+  </property>
+  <layout class="QHBoxLayout" >
+   <property name="margin" >
+    <number>9</number>
+   </property>
+   <property name="spacing" >
+    <number>6</number>
+   </property>
+   <item>
+    <layout class="QVBoxLayout" >
+     <property name="margin" >
+      <number>0</number>
+     </property>
+     <property name="spacing" >
+      <number>6</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="lblSmeshObject" >
+       <property name="text" >
+        <string>Input MESH / Output group name / Type :</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <layout class="QHBoxLayout" >
+       <property name="margin" >
+        <number>0</number>
+       </property>
+       <property name="spacing" >
+        <number>6</number>
+       </property>
+       <item>
+        <layout class="QVBoxLayout" >
+         <property name="margin" >
+          <number>0</number>
+         </property>
+         <property name="spacing" >
+          <number>6</number>
+         </property>
+         <item>
+          <layout class="QHBoxLayout" >
+           <property name="margin" >
+            <number>0</number>
+           </property>
+           <property name="spacing" >
+            <number>6</number>
+           </property>
+           <item>
+            <layout class="QHBoxLayout" >
+             <property name="margin" >
+              <number>0</number>
+             </property>
+             <property name="spacing" >
+              <number>6</number>
+             </property>
+             <item>
+              <widget class="QPushButton" name="btnSmeshObject" >
+               <property name="sizePolicy" >
+                <sizepolicy>
+                 <hsizetype>0</hsizetype>
+                 <vsizetype>0</vsizetype>
+                 <horstretch>0</horstretch>
+                 <verstretch>0</verstretch>
+                </sizepolicy>
+               </property>
+               <property name="maximumSize" >
+                <size>
+                 <width>31</width>
+                 <height>16777215</height>
+                </size>
+               </property>
+               <property name="text" >
+                <string/>
+               </property>
+               <property name="icon" >
+                <iconset>select.png</iconset>
+               </property>
+              </widget>
+             </item>
+             <item>
+              <widget class="QLineEdit" name="txtSmeshObject" >
+               <property name="toolTip" >
+                <string comment="Select the input mesh in the object browser" />
+               </property>
+              </widget>
+             </item>
+            </layout>
+           </item>
+           <item>
+            <widget class="Line" name="line" >
+             <property name="orientation" >
+              <enum>Qt::Vertical</enum>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <widget class="QLineEdit" name="txtGroupName" >
+             <property name="toolTip" >
+              <string comment="Specify the name of the associated group in the output mesh" />
+             </property>
+            </widget>
+           </item>
+           <item>
+            <widget class="Line" name="line_2" >
+             <property name="orientation" >
+              <enum>Qt::Vertical</enum>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <widget class="QComboBox" name="cmbMeshType" >
+             <property name="toolTip" >
+              <string comment="Select the type of the mesh" />
+             </property>
+             <item>
+              <property name="text" >
+               <string>Béton</string>
+              </property>
+              <property name="icon" >
+               <iconset>concrete.png</iconset>
+              </property>
+             </item>
+             <item>
+              <property name="text" >
+               <string>Acier</string>
+              </property>
+              <property name="icon" >
+               <iconset>steelbar.png</iconset>
+              </property>
+             </item>
+            </widget>
+           </item>
+          </layout>
+         </item>
+         <item>
+          <widget class="QTableView" name="tblListInput" />
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QVBoxLayout" >
+         <property name="margin" >
+          <number>0</number>
+         </property>
+         <property name="spacing" >
+          <number>6</number>
+         </property>
+         <item>
+          <widget class="QPushButton" name="btnAddInput" >
+           <property name="text" >
+            <string/>
+           </property>
+           <property name="icon" >
+            <iconset>addinput.png</iconset>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QPushButton" name="btnDeleteInput" >
+           <property name="text" >
+            <string/>
+           </property>
+           <property name="icon" >
+            <iconset>deleteinput.png</iconset>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <spacer>
+           <property name="orientation" >
+            <enum>Qt::Vertical</enum>
+           </property>
+           <property name="sizeHint" >
+            <size>
+             <width>20</width>
+             <height>40</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+        </layout>
+       </item>
+      </layout>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/Tools/padder/spadderpy/gui/parameters.png b/src/Tools/padder/spadderpy/gui/parameters.png
new file mode 100644 (file)
index 0000000..a8a67db
Binary files /dev/null and b/src/Tools/padder/spadderpy/gui/parameters.png differ
diff --git a/src/Tools/padder/spadderpy/gui/plugindialog.py b/src/Tools/padder/spadderpy/gui/plugindialog.py
new file mode 100644 (file)
index 0000000..2cf4c15
--- /dev/null
@@ -0,0 +1,403 @@
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2011-2012  EDF R&D
+#
+# 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.com
+#
+# Author : Guillaume Boulant (EDF)
+#
+
+from PyQt4.QtGui import QDialog, QIcon
+from PyQt4.QtCore import QObject, SIGNAL, SLOT, Qt
+
+from plugindialog_ui import Ui_PluginDialog
+from inputdialog import InputDialog
+from inputdata import InputData
+# __GBO__: uncomment this line and comment the previous one to use the
+# demo input dialog instead of the real one.
+#from demoinputdialog import InputDialog
+
+import os
+import salome
+from salome.kernel import studyedit
+from salome.kernel.uiexception import AdminException
+
+from omniORB import CORBA
+import SMESH
+import smesh
+import MESHJOB
+
+gui_states = ["CAN_SELECT", "CAN_COMPUTE", "CAN_REFRESH", "CAN_PUBLISH"]
+
+run_states = ["CREATED", "IN_PROCESS", "QUEUED", "RUNNING", "PAUSED"];
+end_states = ["FINISHED", "ERROR"]
+all_states = run_states+end_states;
+
+# The SALOME launcher resource is specified by its name as defined in
+# the file CatalogResources.xml (see root directory of the
+# application). We could have a check box in the dialog to specify
+# wether we want a local execution or a remote one.
+resource_name = "localhost"
+from salome.smesh.spadder.configreader import ConfigReader
+
+
+class PluginDialog(QDialog):
+
+    def __init__(self,parent = None,name = None,modal = 0,fl = 0):
+        QDialog.__init__(self,parent)
+        # Set up the user interface from Designer.
+        self.__ui = Ui_PluginDialog()
+        self.__ui.setupUi(self)
+
+        # The default display strategy is to use a separate dialog box
+        # to select the input data.
+        self.viewInputFrame(False)
+
+        # The icon are supposed to be located in the plugin folder,
+        # i.e. in the same folder than this python module file
+        iconfolder=os.path.dirname(os.path.abspath(__file__))
+        icon = QIcon()
+        icon.addFile(os.path.join(iconfolder,"input.png"))
+        self.__ui.btnInput.setIcon(icon)
+        icon = QIcon()
+        icon.addFile(os.path.join(iconfolder,"compute.png"))
+        self.__ui.btnCompute.setIcon(icon)
+        icon = QIcon()
+        icon.addFile(os.path.join(iconfolder,"refresh.png"))
+        self.__ui.btnRefresh.setIcon(icon)
+        icon = QIcon()
+        icon.addFile(os.path.join(iconfolder,"publish.png"))
+        self.__ui.btnPublish.setIcon(icon)
+        icon = QIcon()
+        icon.addFile(os.path.join(iconfolder,"clear.png"))
+        self.__ui.btnClear.setIcon(icon)
+
+        # Then, we can connect the slot to there associated button event
+        self.connect(self.__ui.btnInput,       SIGNAL('clicked()'), self.onInput )
+        self.connect(self.__ui.btnCompute,     SIGNAL('clicked()'), self.onCompute )
+        self.connect(self.__ui.btnRefresh,     SIGNAL('clicked()'), self.onRefresh )
+        self.connect(self.__ui.btnPublish,     SIGNAL('clicked()'), self.onPublish )
+        self.connect(self.__ui.btnClear,       SIGNAL('clicked()'), self.onClear )
+
+        self.clear()
+
+        self.setupJobManager()
+        
+
+    def setupJobManager(self):
+        '''
+        This function configures the jobmanager by transmiting the
+        parameters required for a local execution and a remote
+        execution. The choice between "local" and "remote" is done at
+        the initialize step, by specifing the name of the resource to
+        be used.
+        '''
+        # We first 
+        
+        configReader = ConfigReader()
+        config = configReader.getLocalConfig()
+        configId = config.resname
+        self.__getJobManager().configure(configId, config)
+        # Note that the resname parameter is used as the key identifier of
+        # the configuration in the job manager. As is, there can be then
+        # only one configuration for each machine defined in the resources
+        # catalog (no need to have further, I thing)
+        config = configReader.getRemoteConfig()
+        configId = config.resname
+        self.__getJobManager().configure(configId, config)
+
+        # We specify the default configuration identifier as the
+        # resource name of the default configuration
+        self.__configId = configReader.getDefaultConfig().resname
+
+
+    def viewInputFrame(self, view=True):
+        # By default, the top input frame is visible and the input
+        # button is not visible.
+        if view is False:
+            self.__ui.frameInput.setVisible(False)
+            self.__ui.btnInput.setVisible(True)
+            # We create the input dialog that will be displayed when
+            # button input is pressed:
+            self.__inputDialog = InputDialog(self)
+            # The window is kept on the top to ease the selection of
+            # items in the object browser:
+            self.__inputDialog.setWindowFlags(
+                self.__inputDialog.windowFlags() | Qt.WindowStaysOnTopHint)
+            # The signal inputValidated emited from inputDialog is
+            # connected to the slot function onProcessInput:
+            self.connect(self.__inputDialog, SIGNAL('inputValidated()'), self.onProcessInput)
+            
+        else:
+            self.__ui.frameInput.setVisible(True)
+            self.__ui.btnInput.setVisible(False)
+            # This case is NOT IMPLEMENTED YET (not really). It could
+            # be used to draw the input frame directly in the frame
+            # frameInput of this dialog box.
+
+    def getInputFrame(self):
+        return self.__ui.frameInput
+        
+    def __setGuiState(self,states=["CAN_SELECT"]):
+        if "CAN_SELECT" in states:
+            self.__ui.btnInput.setEnabled(True)
+        else:
+            self.__ui.btnInput.setEnabled(False)
+            
+        if "CAN_COMPUTE" in states:
+            self.__ui.btnCompute.setEnabled(True)
+        else:
+            self.__ui.btnCompute.setEnabled(False)
+
+        if "CAN_REFRESH" in states:
+            self.__ui.btnRefresh.setEnabled(True)
+        else:
+            self.__ui.btnRefresh.setEnabled(False)
+
+        if "CAN_PUBLISH" in states:
+            self.__ui.btnPublish.setEnabled(True)
+        else:
+            self.__ui.btnPublish.setEnabled(False)
+
+    def __getJobManager(self):
+        """
+        This function requests a pointer to the MeshJobManager
+        servant. Note that the component is loaded on first demand,
+        and then the reference is recycled.
+        """
+        if self.__dict__.has_key("__jobManager") and self.__jobManager is not None:
+            return self.__jobManager
+
+        # WARN: we first have to update the SALOME components catalog
+        # with the SPADDER components (because they are not defined in
+        # the SMESH catalog, and then they are not in the default
+        # catalog)
+        from salome.smesh import spadder
+        spadder.loadSpadderCatalog()
+        # Then we can load the MeshJobManager component
+        component=salome.lcc.FindOrLoadComponent("FactoryServer","MeshJobManager")
+        if component is None:
+            msg="ERR: the SALOME component MeshJobManager can't be reached"
+            self.__log(msg)
+            raise AdminException(msg)
+
+        self.__jobManager = component
+        return self.__jobManager
+
+    def __log(self, message):
+        """
+        This function prints the specified message in the log area
+        """ 
+        self.__ui.txtLog.append(message)
+
+    def __exportMesh(self, meshName, meshObject):
+        '''
+        This function exports the specified mesh object to a med
+        file whose name (basepath) is built from the specified mesh
+        name. This returns the filename.
+        '''
+        filename=str("/tmp/padder_inputfile_"+meshName+".med")
+        meshObject.ExportToMEDX( filename, 0, SMESH.MED_V2_2, 1 )
+        return filename
+
+    def clear(self):
+        """
+        This function clears the log area and the states of the buttons
+        """
+        self.__listInputData = []
+        self.__ui.txtLog.clear()
+        self.__setGuiState(["CAN_SELECT"])
+        self.__isRunning = False
+        self.__ui.lblStatusBar.setText("Ready")
+
+    def update(self):
+        '''
+        This function can be used to programmatically force the
+        refresh of the dialog box, the job state in particular.
+        '''
+        if self.__isRunning:
+            self.onRefresh()
+
+    def onInput(self):
+        '''
+        This function is the slot connected to the Input button
+        (signal clicked()). It opens the dialog window to input
+        data. The dialog is opened in a window modal mode so that the
+        SALOME study objects can be selected. In conterpart, this
+        class must listen to signals emitted by the child dialog
+        windows to process the validation event (see the slot
+        onProcessInput which is connected to this event).
+        '''
+        self.__inputDialog.setData(self.__listInputData)
+        self.__inputDialog.open()
+
+    def onProcessInput(self):
+        """
+        This function is the slot connected to the signal
+        inputValidated(), emit by the input dialog window when it's
+        validated, i.e. OK is pressed and data are valid.
+        """
+        # The processing simply consists in requesting the input data
+        # from the dialog window.
+        self.__listInputData = self.__inputDialog.getData()
+        self.__ui.lblStatusBar.setText("Input data OK")
+        self.__log("INF: Press \"Compute\" to start the job")
+        self.__setGuiState(["CAN_SELECT", "CAN_COMPUTE"])
+        
+    def onCompute(self):
+        '''
+        This function is the slot connected to the Compute button. It
+        initializes a mesh computation job and start it using the
+        SALOME launcher.  
+        '''
+        # We first have to create the list of parameters for the
+        # initialize function. For that, we have to create the files
+        # from the mesh objects:
+        meshJobParameterList=[]
+        concreteIndex=0
+        for inputData in self.__listInputData:
+            # For each input data, we have to create a
+            # MeshJobParameter and add it to the list.
+            filename  = self.__exportMesh(inputData.meshName, inputData.meshObject)
+            if inputData.meshType == InputData.MESHTYPES.CONCRETE:
+                filetype = MESHJOB.MED_CONCRETE
+            else:
+                filetype = MESHJOB.MED_STEELBAR
+
+            parameter = MESHJOB.MeshJobParameter(
+                file_name  = filename,
+                file_type  = filetype,
+                group_name = inputData.groupName)
+            meshJobParameterList.append(parameter)
+
+        jobManager = self.__getJobManager()
+        self.__jobid = jobManager.initialize(meshJobParameterList, self.__configId)
+        if self.__jobid < 0:
+            self.__log("ERR: the job can't be initialized")
+            return
+        self.__log("INF: the job has been initialized with jobid = "+str(self.__jobid))
+        
+        startOk = jobManager.start(self.__jobid)
+        if not startOk:
+            self.__log("ERR: the job with jobid = "+str(self.__jobid)+" can't be started")
+            return
+        self.__log("INF: the job "+str(self.__jobid)+" has been started")
+        self.__ui.lblStatusBar.setText("Submission OK")
+        self.__setGuiState(["CAN_REFRESH"])
+        self.__isRunning = True
+
+    def onRefresh(self):
+        """
+        This function is the slot connected on the Refresh button. It
+        requests the mesh job manager to get the state of the job and
+        display it in the log area.
+        """
+        jobManager = self.__getJobManager()
+        state = jobManager.getState(self.__jobid)
+        self.__log("INF: job state = "+str(state))
+        self.__ui.lblStatusBar.setText("")
+        if state in run_states:
+            return
+
+        self.__isRunning = False
+        if state == "FINISHED":
+            self.__setGuiState(["CAN_PUBLISH"])
+        else:
+            self.__setGuiState(["CAN_SELECT"])
+
+
+    def onPublish(self):
+        """
+        This function is the slot connected on the Publish button. It
+        requests the mesh job manager to download the results data
+        from the computation resource host and load the med file in
+        the SALOME study. 
+        """
+        jobManager = self.__getJobManager()
+        state = jobManager.getState(self.__jobid)
+        if state in run_states:
+            self.__log("WRN: jobid = "+str(self.__jobid)+" is not finished (state="+str(state)+")")
+            return
+
+        if state not in end_states:
+            self.__log("ERR: jobid = "+str(self.__jobid)+" ended abnormally with state="+str(state))
+            return
+
+        meshJobResults = jobManager.finalize(self.__jobid)
+        if state == "ERROR":
+            self.__log("ERR: jobid = "+str(self.__jobid)+" ended with error: "+meshJobResults.status)
+            return
+
+        logsdirname = os.path.join(meshJobResults.results_dirname, "logs")
+        self.__log("INF:  jobid="+str(self.__jobid)+" ended normally   : "+meshJobResults.status)
+        self.__log("INF:  jobid="+str(self.__jobid)+" see log files in : "+logsdirname)
+
+        medfilename = os.path.join(meshJobResults.results_dirname,
+                                   meshJobResults.outputmesh_filename)
+
+        smesh.SetCurrentStudy(studyedit.getActiveStudy())
+        ([outputMesh], status) = smesh.CreateMeshesFromMED(medfilename)
+
+        # By convention, the name of the output mesh in the study is
+        # build from a constant string 'padder' and the session jobid
+        meshname = 'padder_'+str(self.__jobid)
+        smesh.SetName(outputMesh.GetMesh(), meshname)
+        if salome.sg.hasDesktop():
+            salome.sg.updateObjBrowser(0)
+
+        self.__ui.lblStatusBar.setText("Publication OK")
+        self.__setGuiState(["CAN_SELECT"])
+
+    def onClear(self):
+        """
+        This function is the slot connected on the Clear button. It
+        erases data in the dialog box and cancel the current job if
+        one is running.
+        """
+        self.clear()
+        
+
+
+__dialog=None
+def getDialog():
+    """
+    This function returns a singleton instance of the plugin dialog. 
+    """
+    global __dialog
+    if __dialog is None:
+        __dialog = PluginDialog()
+    return __dialog
+
+#
+# ==============================================================================
+# Basic use cases and unit test functions
+# ==============================================================================
+#
+def TEST_PluginDialog():
+    import sys
+    from PyQt4.QtGui import QApplication
+    from PyQt4.QtCore import QObject, SIGNAL, SLOT
+    app = QApplication(sys.argv)
+    QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
+
+    dlg=PluginDialog()
+    dlg.exec_()
+
+if __name__ == "__main__":
+    TEST_PluginDialog()
+
+        
+
diff --git a/src/Tools/padder/spadderpy/gui/plugindialog.ui b/src/Tools/padder/spadderpy/gui/plugindialog.ui
new file mode 100644 (file)
index 0000000..c6af08f
--- /dev/null
@@ -0,0 +1,168 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PluginDialog</class>
+ <widget class="QDialog" name="PluginDialog">
+  <property name="enabled">
+   <bool>true</bool>
+  </property>
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>649</width>
+    <height>367</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Create a mesh with PADDER</string>
+  </property>
+  <layout class="QHBoxLayout">
+   <property name="spacing">
+    <number>6</number>
+   </property>
+   <property name="margin">
+    <number>9</number>
+   </property>
+   <item>
+    <layout class="QVBoxLayout">
+     <property name="spacing">
+      <number>6</number>
+     </property>
+     <property name="margin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QFrame" name="frameInput">
+       <property name="frameShadow">
+        <enum>QFrame::Raised</enum>
+       </property>
+       <property name="lineWidth">
+        <number>1</number>
+       </property>
+       <property name="midLineWidth">
+        <number>0</number>
+       </property>
+       <layout class="QHBoxLayout">
+        <property name="spacing">
+         <number>6</number>
+        </property>
+        <property name="margin">
+         <number>9</number>
+        </property>
+       </layout>
+      </widget>
+     </item>
+     <item>
+      <layout class="QHBoxLayout">
+       <property name="spacing">
+        <number>6</number>
+       </property>
+       <property name="margin">
+        <number>0</number>
+       </property>
+       <item>
+        <widget class="QTextEdit" name="txtLog"/>
+       </item>
+       <item>
+        <layout class="QVBoxLayout">
+         <property name="spacing">
+          <number>6</number>
+         </property>
+         <property name="margin">
+          <number>0</number>
+         </property>
+         <item>
+          <widget class="QPushButton" name="btnInput">
+           <property name="text">
+            <string>Input</string>
+           </property>
+           <property name="icon">
+            <iconset>
+             <normaloff>parameters.png</normaloff>parameters.png</iconset>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QPushButton" name="btnCompute">
+           <property name="text">
+            <string>Compute</string>
+           </property>
+           <property name="icon">
+            <iconset>
+             <normaloff>compute.png</normaloff>compute.png</iconset>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QPushButton" name="btnRefresh">
+           <property name="text">
+            <string>Refresh</string>
+           </property>
+           <property name="icon">
+            <iconset>
+             <normaloff>refresh.png</normaloff>refresh.png</iconset>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QPushButton" name="btnPublish">
+           <property name="text">
+            <string>Publish</string>
+           </property>
+           <property name="icon">
+            <iconset>
+             <normaloff>publish.png</normaloff>publish.png</iconset>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <spacer>
+           <property name="orientation">
+            <enum>Qt::Vertical</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>75</width>
+             <height>101</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item>
+          <widget class="QPushButton" name="btnClear">
+           <property name="text">
+            <string>Clear</string>
+           </property>
+           <property name="icon">
+            <iconset>
+             <normaloff>clear.png</normaloff>clear.png</iconset>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+      </layout>
+     </item>
+     <item>
+      <widget class="QLabel" name="lblStatusBar">
+       <property name="enabled">
+        <bool>true</bool>
+       </property>
+       <property name="frameShape">
+        <enum>QFrame::StyledPanel</enum>
+       </property>
+       <property name="frameShadow">
+        <enum>QFrame::Sunken</enum>
+       </property>
+       <property name="text">
+        <string/>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/Tools/padder/spadderpy/gui/publish.png b/src/Tools/padder/spadderpy/gui/publish.png
new file mode 100644 (file)
index 0000000..bfe8802
Binary files /dev/null and b/src/Tools/padder/spadderpy/gui/publish.png differ
diff --git a/src/Tools/padder/spadderpy/gui/refresh.png b/src/Tools/padder/spadderpy/gui/refresh.png
new file mode 100644 (file)
index 0000000..2683e98
Binary files /dev/null and b/src/Tools/padder/spadderpy/gui/refresh.png differ
diff --git a/src/Tools/padder/spadderpy/gui/select.png b/src/Tools/padder/spadderpy/gui/select.png
new file mode 100644 (file)
index 0000000..8eea6a9
Binary files /dev/null and b/src/Tools/padder/spadderpy/gui/select.png differ
diff --git a/src/Tools/padder/spadderpy/gui/steelbar.png b/src/Tools/padder/spadderpy/gui/steelbar.png
new file mode 100644 (file)
index 0000000..ce27fe3
Binary files /dev/null and b/src/Tools/padder/spadderpy/gui/steelbar.png differ
diff --git a/src/Tools/padder/spadderpy/padder.cfg.in b/src/Tools/padder/spadderpy/padder.cfg.in
new file mode 100644 (file)
index 0000000..4962a33
--- /dev/null
@@ -0,0 +1,35 @@
+# This section specify the configurations to be used respectively for
+# the local execution and the remote execution. The value for 'local'
+# and 'remote' keys must be the name of a configuration section in
+# this file. The default key must specify a value between "local" or
+# "remote" to indicate the user preference. 
+[resources]
+local   = localhost
+remote  = nepal
+
+[preferences]
+defaultres = local
+
+# The following sections defines the available configurations.
+# The name of the section can be choosen arbitrary. But the value of
+# the resname key MUST be the name of a SALOME resource defined in the
+# catalog of resources (CatalogResources.xml).
+
+# For each section:
+# - resname : the name of the SALOME resource to be used in this configuration
+# - binpath : the path to the padder executable program on this resource
+# - envpath : the path to the environment file on this resource
+[localhost]
+resname = localhost
+binpath = @PADDERHOME@/padder.exe
+envpath = @PADDERHOME@/padder.env
+
+[venus]
+resname = gboulant@venus
+binpath = /usr/local/bin/padder.exe
+envpath = /usr/local/share/envPadder.sh
+
+[nepal]
+resname = nepal@nepal
+binpath = /usr/local/bin/padder.exe
+envpath = /usr/local/share/envPadder.sh
diff --git a/src/Tools/padder/spadderpy/plugin/Makefile.am b/src/Tools/padder/spadderpy/plugin/Makefile.am
new file mode 100644 (file)
index 0000000..e05fd63
--- /dev/null
@@ -0,0 +1,33 @@
+# Copyright (C) 2011-2012  EDF R&D
+#
+# 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.com
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+#
+# Files that strictly concern the SALOME plugins registration and
+# configuration. They are installed in a dedicated folder named
+# plugins and created in the root installation directory.
+#
+salomeplugins_PYTHON = \
+       spadderPlugin.py
+
+#salomeplugins_DATA = \
+#      envPlugins.sh
+
+
diff --git a/src/Tools/padder/spadderpy/plugin/envPlugins.sh.in b/src/Tools/padder/spadderpy/plugin/envPlugins.sh.in
new file mode 100644 (file)
index 0000000..aa7c39a
--- /dev/null
@@ -0,0 +1,22 @@
+# Copyright (C) 2011-2012  EDF R&D
+#
+# 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.com
+#
+
+SPADDER_PLUGINS_PATH=@prefix@/plugins
+export SALOME_PLUGINS_PATH=$SALOME_PLUGINS_PATH:$SPADDER_PLUGINS_PATH
+
diff --git a/src/Tools/padder/spadderpy/plugin/spadderPlugin.py b/src/Tools/padder/spadderpy/plugin/spadderPlugin.py
new file mode 100644 (file)
index 0000000..67f7826
--- /dev/null
@@ -0,0 +1,36 @@
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2011-2012  EDF R&D
+#
+# 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.com
+#
+# Author : Guillaume Boulant (EDF) 
+#
+
+def runSpadderPlugin(context):
+    from salome.smesh.spadder.gui import plugindialog
+    from salome.kernel.uiexception import UiException
+    try:
+        dialog=plugindialog.getDialog()
+    except UiException, err:
+        from PyQt4.QtGui import QMessageBox
+        QMessageBox.critical(None,"An error occurs during PADDER configuration",
+                             err.getUIMessage())
+        return
+    
+    dialog.update()    
+    dialog.show()
+
diff --git a/src/Tools/padder/unittests/Makefile.am b/src/Tools/padder/unittests/Makefile.am
new file mode 100644 (file)
index 0000000..42fad27
--- /dev/null
@@ -0,0 +1,31 @@
+# Copyright (C) 2011-2012  EDF R&D
+#
+# 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.com
+#
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+spadderpydir=$(smeshpypkgdir)/spadder/unittests
+
+spadderpy_PYTHON =                     \
+       __init__.py                    \
+       usecase_meshJobManager.py      \
+       usecase_spadderPluginTester.py
+
+spadderbindir=$(bindir)/spadder
+spadderbin_SCRIPTS = \
+       autotest.sh
diff --git a/src/Tools/padder/unittests/__init__.py b/src/Tools/padder/unittests/__init__.py
new file mode 100644 (file)
index 0000000..faa0a86
--- /dev/null
@@ -0,0 +1,18 @@
+# Copyright (C) 2011-2012  CEA/DEN, EDF R&D
+#
+# 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.com
+#
diff --git a/src/Tools/padder/unittests/autotest.sh.in b/src/Tools/padder/unittests/autotest.sh.in
new file mode 100644 (file)
index 0000000..7ff1ece
--- /dev/null
@@ -0,0 +1,61 @@
+#!/bin/bash
+# Copyright (C) 2010-2012  EDF R&D
+#
+# 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.com
+#
+# Author : Guillaume Boulant (EDF) 
+#
+
+
+# This script should be executed in a SALOME shell session,
+# for example the shell obtained from the command runSession
+# provided by the SALOME application.
+
+# This list contains the filenames where test suites are to be
+# executed. The path are defined relative to the PYTHON installation
+# directory of the SALOME module.
+listfiles="\
+    configreader.py \
+    unittests/usecase_meshJobManager.py \
+    gui/inputdata.py"
+
+INSTALL_DIR=@prefix@
+PYTHON_DIR=$INSTALL_DIR/lib/python@PYTHON_VERSION@/site-packages/salome
+PYTHONPATH=$PYTHON_DIR:$PYTHONPATH
+export PYTHONPATH
+
+stderr=2
+while getopts 'ql' OPTION
+do
+    case $OPTION in
+       q) stderr=1 ;;
+       l) for f in $listfiles; do echo $f; done; exit 0;;
+       ?) printf "Usage: %s: [-q] [-l]\n" $(basename $0) >&2; exit 2;;
+    esac
+done
+shift $(($OPTIND - 1))
+
+here=$(pwd)
+package_path="salome/smesh/spadder"
+cd $PYTHON_DIR
+for file in $listfiles; do
+    # Uncomment this line (and comment the next one) to display
+    # the start line of a test and not only the result:
+    python $package_path/$file 2>&$stderr | grep '^\[TEST'
+    #python $package_path/$file $filter | grep '^\[TEST' | grep -v 'test in progress'
+done
+cd $here
diff --git a/src/Tools/padder/unittests/usecase_meshJobManager.py b/src/Tools/padder/unittests/usecase_meshJobManager.py
new file mode 100644 (file)
index 0000000..09a8c09
--- /dev/null
@@ -0,0 +1,102 @@
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2011-2012  EDF R&D
+#
+# 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.com
+#
+# Author(s): Guillaume Boulant (23/03/2011)
+#
+
+# This script illustrates the standard use case of the component
+# MeshJobManager from within a SALOME script.
+
+
+#
+# Preparing the configuration parameters
+#
+import os
+from salome.smesh.spadder.configreader import ConfigReader, printConfig
+
+configReader = ConfigReader()
+defaultConfig = configReader.getDefaultConfig()
+printConfig(defaultConfig)
+
+from salome.smesh import spadder
+file_concrete=os.path.join(spadder.getTestDataDir(),"concrete.med")
+file_steelbar=os.path.join(spadder.getTestDataDir(),"ferraill.med")
+
+import salome
+import MESHJOB
+
+#
+# Setup the configuration in the component. When first have to load
+# the catalog of SPADDER components, then load the component
+# MeshJobManager, and finally configure this component.
+#
+spadder.loadSpadderCatalog()
+
+salome.salome_init()
+component = salome.lcc.FindOrLoadComponent("FactoryServer","MeshJobManager")
+config = MESHJOB.ConfigParameter(resname=defaultConfig.resname,
+                                 binpath=defaultConfig.binpath,
+                                 envpath=defaultConfig.envpath)
+component.configure("localhost",config)
+
+#
+# Prepare the job parameters and initialize the job
+#
+meshJobParameterList = []
+param = MESHJOB.MeshJobParameter(file_name=file_concrete,
+                                 file_type=MESHJOB.MED_CONCRETE,
+                                 group_name="concrete")
+meshJobParameterList.append(param)
+
+param = MESHJOB.MeshJobParameter(file_name=file_steelbar,
+                                 file_type=MESHJOB.MED_STEELBAR,
+                                 group_name="steelbar")
+meshJobParameterList.append(param)
+jobid = component.initialize(meshJobParameterList, "localhost")
+
+#
+# Start the execution of the job identified by its job id.
+#
+ok=component.start(jobid)
+
+#
+# This part illustrates how you can follow the execution of the job.
+#
+run_states = ["CREATED", "IN_PROCESS", "QUEUED", "RUNNING", "PAUSED"];
+end_states = ["FINISHED", "ERROR"]
+all_states = run_states+end_states;
+
+ended  = False
+nbiter = 0
+import time
+while not ended:
+    state = component.getState(jobid)
+    print "MeshJobManager ["+str(nbiter)+"] : state = "+str(state)
+    if state not in run_states:
+        ended=True
+    time.sleep(0.5)
+    nbiter+=1
+        
+if state not in end_states:
+    print "ERR: jobid = "+str(jobid)+" ended abnormally with state="+str(state)
+else:
+    print "OK:  jobid = "+str(jobid)+" ended with state="+str(state)
+    meshJobResults = component.finalize(jobid)
+    print meshJobResults
+    print "You will find the results files in the directory:\n%s"%meshJobResults.results_dirname
diff --git a/src/Tools/padder/unittests/usecase_spadderPluginTester.py b/src/Tools/padder/unittests/usecase_spadderPluginTester.py
new file mode 100644 (file)
index 0000000..164cf8a
--- /dev/null
@@ -0,0 +1,51 @@
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2011-2012  EDF R&D
+#
+# 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.com
+#
+# Author(s): Guillaume Boulant (23/03/2011)
+#
+
+# This script illustrates the standard use case of the component
+# SPADDERPluginTester from within a SALOME script. This component is
+# dedicated to test purpose only
+
+import salome
+import SPADDERPluginTest
+
+# We first have to update the SALOME components list by loading the
+# SPADDER catalog (load on demand only) 
+from salome.smesh import spadder
+spadder.loadSpadderCatalog()
+
+# Basic test
+print "Basic tests"
+c=salome.lcc.FindOrLoadComponent("FactoryServer","SPADDERPluginTester")
+z=c.demo(2.,3.)
+
+# Test of usage of KERNEL services from the test component
+print "Test of usage of KERNEL services from the test component"
+c.testkernel()
+
+# Test of usage of SMESH engine from the test component
+# WARN: the SMESH engine must be loaded first
+print "Test of usage of SMESH engine from the test component"
+import SMESH
+salome.lcc.FindOrLoadComponent("FactoryServer","SMESH")
+c.testsmesh(salome.myStudyId)
+
+print "Test completed : OK"
diff --git a/src/Tools/smesh_plugins.py b/src/Tools/smesh_plugins.py
new file mode 100644 (file)
index 0000000..612e0fa
--- /dev/null
@@ -0,0 +1,33 @@
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2011-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# 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.com
+#
+# Author : Guillaume Boulant (EDF) 
+#
+import salome_pluginsmanager
+
+from spadderPlugin import runSpadderPlugin
+from meshcut_plugin import MeshCut
+
+salome_pluginsmanager.AddFunction('PADDER mesher',
+                                  'Create a mesh with PADDER',
+                                  runSpadderPlugin)
+
+salome_pluginsmanager.AddFunction('MeshCut',
+                                  'Cut a tetrahedron mesh by a plane',
+                                  MeshCut)